Version:  2.0.40 2.2.26 2.4.37 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0

Linux/drivers/staging/comedi/drivers/adl_pci7x3x.c

  1 /*
  2  * COMEDI driver for the ADLINK PCI-723x/743x series boards.
  3  * Copyright (C) 2012 H Hartley Sweeten <hsweeten@visionengravers.com>
  4  *
  5  * Based on the adl_pci7230 driver written by:
  6  *      David Fernandez <dfcastelao@gmail.com>
  7  * and the adl_pci7432 driver written by:
  8  *      Michel Lachaine <mike@mikelachaine.ca>
  9  *
 10  * COMEDI - Linux Control and Measurement Device Interface
 11  * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
 12  *
 13  * This program is free software; you can redistribute it and/or modify
 14  * it under the terms of the GNU General Public License as published by
 15  * the Free Software Foundation; either version 2 of the License, or
 16  * (at your option) any later version.
 17  *
 18  * This program is distributed in the hope that it will be useful,
 19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 21  * GNU General Public License for more details.
 22  */
 23 
 24 /*
 25  * Driver: adl_pci7x3x
 26  * Description: 32/64-Channel Isolated Digital I/O Boards
 27  * Devices: [ADLink] PCI-7230 (adl_pci7230), PCI-7233 (adl_pci7233),
 28  *   PCI-7234 (adl_pci7234), PCI-7432 (adl_pci7432), PCI-7433 (adl_pci7433),
 29  *   PCI-7434 (adl_pci7434)
 30  * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
 31  * Updated: Thu, 02 Aug 2012 14:27:46 -0700
 32  * Status: untested
 33  *
 34  * One or two subdevices are setup by this driver depending on
 35  * the number of digital inputs and/or outputs provided by the
 36  * board. Each subdevice has a maximum of 32 channels.
 37  *
 38  *      PCI-7230 - 2 subdevices: 0 - 16 input, 1 - 16 output
 39  *      PCI-7233 - 1 subdevice: 0 - 32 input
 40  *      PCI-7234 - 1 subdevice: 0 - 32 output
 41  *      PCI-7432 - 2 subdevices: 0 - 32 input, 1 - 32 output
 42  *      PCI-7433 - 2 subdevices: 0 - 32 input, 1 - 32 input
 43  *      PCI-7434 - 2 subdevices: 0 - 32 output, 1 - 32 output
 44  *
 45  * The PCI-7230, PCI-7432 and PCI-7433 boards also support external
 46  * interrupt signals on digital input channels 0 and 1. The PCI-7233
 47  * has dual-interrupt sources for change-of-state (COS) on any 16
 48  * digital input channels of LSB and for COS on any 16 digital input
 49  * lines of MSB. Interrupts are not currently supported by this
 50  * driver.
 51  *
 52  * Configuration Options: not applicable, uses comedi PCI auto config
 53  */
 54 
 55 #include <linux/module.h>
 56 #include <linux/pci.h>
 57 
 58 #include "../comedidev.h"
 59 
 60 /*
 61  * Register I/O map (32-bit access only)
 62  */
 63 #define PCI7X3X_DIO_REG         0x00
 64 #define PCI743X_DIO_REG         0x04
 65 
 66 enum apci1516_boardid {
 67         BOARD_PCI7230,
 68         BOARD_PCI7233,
 69         BOARD_PCI7234,
 70         BOARD_PCI7432,
 71         BOARD_PCI7433,
 72         BOARD_PCI7434,
 73 };
 74 
 75 struct adl_pci7x3x_boardinfo {
 76         const char *name;
 77         int nsubdevs;
 78         int di_nchan;
 79         int do_nchan;
 80 };
 81 
 82 static const struct adl_pci7x3x_boardinfo adl_pci7x3x_boards[] = {
 83         [BOARD_PCI7230] = {
 84                 .name           = "adl_pci7230",
 85                 .nsubdevs       = 2,
 86                 .di_nchan       = 16,
 87                 .do_nchan       = 16,
 88         },
 89         [BOARD_PCI7233] = {
 90                 .name           = "adl_pci7233",
 91                 .nsubdevs       = 1,
 92                 .di_nchan       = 32,
 93         },
 94         [BOARD_PCI7234] = {
 95                 .name           = "adl_pci7234",
 96                 .nsubdevs       = 1,
 97                 .do_nchan       = 32,
 98         },
 99         [BOARD_PCI7432] = {
100                 .name           = "adl_pci7432",
101                 .nsubdevs       = 2,
102                 .di_nchan       = 32,
103                 .do_nchan       = 32,
104         },
105         [BOARD_PCI7433] = {
106                 .name           = "adl_pci7433",
107                 .nsubdevs       = 2,
108                 .di_nchan       = 64,
109         },
110         [BOARD_PCI7434] = {
111                 .name           = "adl_pci7434",
112                 .nsubdevs       = 2,
113                 .do_nchan       = 64,
114         }
115 };
116 
117 static int adl_pci7x3x_do_insn_bits(struct comedi_device *dev,
118                                     struct comedi_subdevice *s,
119                                     struct comedi_insn *insn,
120                                     unsigned int *data)
121 {
122         unsigned long reg = (unsigned long)s->private;
123 
124         if (comedi_dio_update_state(s, data))
125                 outl(s->state, dev->iobase + reg);
126 
127         data[1] = s->state;
128 
129         return insn->n;
130 }
131 
132 static int adl_pci7x3x_di_insn_bits(struct comedi_device *dev,
133                                     struct comedi_subdevice *s,
134                                     struct comedi_insn *insn,
135                                     unsigned int *data)
136 {
137         unsigned long reg = (unsigned long)s->private;
138 
139         data[1] = inl(dev->iobase + reg);
140 
141         return insn->n;
142 }
143 
144 static int adl_pci7x3x_auto_attach(struct comedi_device *dev,
145                                    unsigned long context)
146 {
147         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
148         const struct adl_pci7x3x_boardinfo *board = NULL;
149         struct comedi_subdevice *s;
150         int subdev;
151         int nchan;
152         int ret;
153 
154         if (context < ARRAY_SIZE(adl_pci7x3x_boards))
155                 board = &adl_pci7x3x_boards[context];
156         if (!board)
157                 return -ENODEV;
158         dev->board_ptr = board;
159         dev->board_name = board->name;
160 
161         ret = comedi_pci_enable(dev);
162         if (ret)
163                 return ret;
164         dev->iobase = pci_resource_start(pcidev, 2);
165 
166         ret = comedi_alloc_subdevices(dev, board->nsubdevs);
167         if (ret)
168                 return ret;
169 
170         subdev = 0;
171 
172         if (board->di_nchan) {
173                 nchan = min(board->di_nchan, 32);
174 
175                 s = &dev->subdevices[subdev];
176                 /* Isolated digital inputs 0 to 15/31 */
177                 s->type         = COMEDI_SUBD_DI;
178                 s->subdev_flags = SDF_READABLE;
179                 s->n_chan       = nchan;
180                 s->maxdata      = 1;
181                 s->insn_bits    = adl_pci7x3x_di_insn_bits;
182                 s->range_table  = &range_digital;
183 
184                 s->private      = (void *)PCI7X3X_DIO_REG;
185 
186                 subdev++;
187 
188                 nchan = board->di_nchan - nchan;
189                 if (nchan) {
190                         s = &dev->subdevices[subdev];
191                         /* Isolated digital inputs 32 to 63 */
192                         s->type         = COMEDI_SUBD_DI;
193                         s->subdev_flags = SDF_READABLE;
194                         s->n_chan       = nchan;
195                         s->maxdata      = 1;
196                         s->insn_bits    = adl_pci7x3x_di_insn_bits;
197                         s->range_table  = &range_digital;
198 
199                         s->private      = (void *)PCI743X_DIO_REG;
200 
201                         subdev++;
202                 }
203         }
204 
205         if (board->do_nchan) {
206                 nchan = min(board->do_nchan, 32);
207 
208                 s = &dev->subdevices[subdev];
209                 /* Isolated digital outputs 0 to 15/31 */
210                 s->type         = COMEDI_SUBD_DO;
211                 s->subdev_flags = SDF_WRITABLE;
212                 s->n_chan       = nchan;
213                 s->maxdata      = 1;
214                 s->insn_bits    = adl_pci7x3x_do_insn_bits;
215                 s->range_table  = &range_digital;
216 
217                 s->private      = (void *)PCI7X3X_DIO_REG;
218 
219                 subdev++;
220 
221                 nchan = board->do_nchan - nchan;
222                 if (nchan) {
223                         s = &dev->subdevices[subdev];
224                         /* Isolated digital outputs 32 to 63 */
225                         s->type         = COMEDI_SUBD_DO;
226                         s->subdev_flags = SDF_WRITABLE;
227                         s->n_chan       = nchan;
228                         s->maxdata      = 1;
229                         s->insn_bits    = adl_pci7x3x_do_insn_bits;
230                         s->range_table  = &range_digital;
231 
232                         s->private      = (void *)PCI743X_DIO_REG;
233 
234                         subdev++;
235                 }
236         }
237 
238         return 0;
239 }
240 
241 static struct comedi_driver adl_pci7x3x_driver = {
242         .driver_name    = "adl_pci7x3x",
243         .module         = THIS_MODULE,
244         .auto_attach    = adl_pci7x3x_auto_attach,
245         .detach         = comedi_pci_detach,
246 };
247 
248 static int adl_pci7x3x_pci_probe(struct pci_dev *dev,
249                                  const struct pci_device_id *id)
250 {
251         return comedi_pci_auto_config(dev, &adl_pci7x3x_driver,
252                                       id->driver_data);
253 }
254 
255 static const struct pci_device_id adl_pci7x3x_pci_table[] = {
256         { PCI_VDEVICE(ADLINK, 0x7230), BOARD_PCI7230 },
257         { PCI_VDEVICE(ADLINK, 0x7233), BOARD_PCI7233 },
258         { PCI_VDEVICE(ADLINK, 0x7234), BOARD_PCI7234 },
259         { PCI_VDEVICE(ADLINK, 0x7432), BOARD_PCI7432 },
260         { PCI_VDEVICE(ADLINK, 0x7433), BOARD_PCI7433 },
261         { PCI_VDEVICE(ADLINK, 0x7434), BOARD_PCI7434 },
262         { 0 }
263 };
264 MODULE_DEVICE_TABLE(pci, adl_pci7x3x_pci_table);
265 
266 static struct pci_driver adl_pci7x3x_pci_driver = {
267         .name           = "adl_pci7x3x",
268         .id_table       = adl_pci7x3x_pci_table,
269         .probe          = adl_pci7x3x_pci_probe,
270         .remove         = comedi_pci_auto_unconfig,
271 };
272 module_comedi_pci_driver(adl_pci7x3x_driver, adl_pci7x3x_pci_driver);
273 
274 MODULE_DESCRIPTION("ADLINK PCI-723x/743x Isolated Digital I/O boards");
275 MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
276 MODULE_LICENSE("GPL");
277 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us