Version:  2.0.40 2.2.26 2.4.37 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 4.1

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 
 57 #include "../comedi_pci.h"
 58 
 59 /*
 60  * Register I/O map (32-bit access only)
 61  */
 62 #define PCI7X3X_DIO_REG         0x00
 63 #define PCI743X_DIO_REG         0x04
 64 
 65 enum apci1516_boardid {
 66         BOARD_PCI7230,
 67         BOARD_PCI7233,
 68         BOARD_PCI7234,
 69         BOARD_PCI7432,
 70         BOARD_PCI7433,
 71         BOARD_PCI7434,
 72 };
 73 
 74 struct adl_pci7x3x_boardinfo {
 75         const char *name;
 76         int nsubdevs;
 77         int di_nchan;
 78         int do_nchan;
 79 };
 80 
 81 static const struct adl_pci7x3x_boardinfo adl_pci7x3x_boards[] = {
 82         [BOARD_PCI7230] = {
 83                 .name           = "adl_pci7230",
 84                 .nsubdevs       = 2,
 85                 .di_nchan       = 16,
 86                 .do_nchan       = 16,
 87         },
 88         [BOARD_PCI7233] = {
 89                 .name           = "adl_pci7233",
 90                 .nsubdevs       = 1,
 91                 .di_nchan       = 32,
 92         },
 93         [BOARD_PCI7234] = {
 94                 .name           = "adl_pci7234",
 95                 .nsubdevs       = 1,
 96                 .do_nchan       = 32,
 97         },
 98         [BOARD_PCI7432] = {
 99                 .name           = "adl_pci7432",
100                 .nsubdevs       = 2,
101                 .di_nchan       = 32,
102                 .do_nchan       = 32,
103         },
104         [BOARD_PCI7433] = {
105                 .name           = "adl_pci7433",
106                 .nsubdevs       = 2,
107                 .di_nchan       = 64,
108         },
109         [BOARD_PCI7434] = {
110                 .name           = "adl_pci7434",
111                 .nsubdevs       = 2,
112                 .do_nchan       = 64,
113         }
114 };
115 
116 static int adl_pci7x3x_do_insn_bits(struct comedi_device *dev,
117                                     struct comedi_subdevice *s,
118                                     struct comedi_insn *insn,
119                                     unsigned int *data)
120 {
121         unsigned long reg = (unsigned long)s->private;
122 
123         if (comedi_dio_update_state(s, data))
124                 outl(s->state, dev->iobase + reg);
125 
126         data[1] = s->state;
127 
128         return insn->n;
129 }
130 
131 static int adl_pci7x3x_di_insn_bits(struct comedi_device *dev,
132                                     struct comedi_subdevice *s,
133                                     struct comedi_insn *insn,
134                                     unsigned int *data)
135 {
136         unsigned long reg = (unsigned long)s->private;
137 
138         data[1] = inl(dev->iobase + reg);
139 
140         return insn->n;
141 }
142 
143 static int adl_pci7x3x_auto_attach(struct comedi_device *dev,
144                                    unsigned long context)
145 {
146         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
147         const struct adl_pci7x3x_boardinfo *board = NULL;
148         struct comedi_subdevice *s;
149         int subdev;
150         int nchan;
151         int ret;
152 
153         if (context < ARRAY_SIZE(adl_pci7x3x_boards))
154                 board = &adl_pci7x3x_boards[context];
155         if (!board)
156                 return -ENODEV;
157         dev->board_ptr = board;
158         dev->board_name = board->name;
159 
160         ret = comedi_pci_enable(dev);
161         if (ret)
162                 return ret;
163         dev->iobase = pci_resource_start(pcidev, 2);
164 
165         ret = comedi_alloc_subdevices(dev, board->nsubdevs);
166         if (ret)
167                 return ret;
168 
169         subdev = 0;
170 
171         if (board->di_nchan) {
172                 nchan = min(board->di_nchan, 32);
173 
174                 s = &dev->subdevices[subdev];
175                 /* Isolated digital inputs 0 to 15/31 */
176                 s->type         = COMEDI_SUBD_DI;
177                 s->subdev_flags = SDF_READABLE;
178                 s->n_chan       = nchan;
179                 s->maxdata      = 1;
180                 s->insn_bits    = adl_pci7x3x_di_insn_bits;
181                 s->range_table  = &range_digital;
182 
183                 s->private      = (void *)PCI7X3X_DIO_REG;
184 
185                 subdev++;
186 
187                 nchan = board->di_nchan - nchan;
188                 if (nchan) {
189                         s = &dev->subdevices[subdev];
190                         /* Isolated digital inputs 32 to 63 */
191                         s->type         = COMEDI_SUBD_DI;
192                         s->subdev_flags = SDF_READABLE;
193                         s->n_chan       = nchan;
194                         s->maxdata      = 1;
195                         s->insn_bits    = adl_pci7x3x_di_insn_bits;
196                         s->range_table  = &range_digital;
197 
198                         s->private      = (void *)PCI743X_DIO_REG;
199 
200                         subdev++;
201                 }
202         }
203 
204         if (board->do_nchan) {
205                 nchan = min(board->do_nchan, 32);
206 
207                 s = &dev->subdevices[subdev];
208                 /* Isolated digital outputs 0 to 15/31 */
209                 s->type         = COMEDI_SUBD_DO;
210                 s->subdev_flags = SDF_WRITABLE;
211                 s->n_chan       = nchan;
212                 s->maxdata      = 1;
213                 s->insn_bits    = adl_pci7x3x_do_insn_bits;
214                 s->range_table  = &range_digital;
215 
216                 s->private      = (void *)PCI7X3X_DIO_REG;
217 
218                 subdev++;
219 
220                 nchan = board->do_nchan - nchan;
221                 if (nchan) {
222                         s = &dev->subdevices[subdev];
223                         /* Isolated digital outputs 32 to 63 */
224                         s->type         = COMEDI_SUBD_DO;
225                         s->subdev_flags = SDF_WRITABLE;
226                         s->n_chan       = nchan;
227                         s->maxdata      = 1;
228                         s->insn_bits    = adl_pci7x3x_do_insn_bits;
229                         s->range_table  = &range_digital;
230 
231                         s->private      = (void *)PCI743X_DIO_REG;
232 
233                         subdev++;
234                 }
235         }
236 
237         return 0;
238 }
239 
240 static struct comedi_driver adl_pci7x3x_driver = {
241         .driver_name    = "adl_pci7x3x",
242         .module         = THIS_MODULE,
243         .auto_attach    = adl_pci7x3x_auto_attach,
244         .detach         = comedi_pci_detach,
245 };
246 
247 static int adl_pci7x3x_pci_probe(struct pci_dev *dev,
248                                  const struct pci_device_id *id)
249 {
250         return comedi_pci_auto_config(dev, &adl_pci7x3x_driver,
251                                       id->driver_data);
252 }
253 
254 static const struct pci_device_id adl_pci7x3x_pci_table[] = {
255         { PCI_VDEVICE(ADLINK, 0x7230), BOARD_PCI7230 },
256         { PCI_VDEVICE(ADLINK, 0x7233), BOARD_PCI7233 },
257         { PCI_VDEVICE(ADLINK, 0x7234), BOARD_PCI7234 },
258         { PCI_VDEVICE(ADLINK, 0x7432), BOARD_PCI7432 },
259         { PCI_VDEVICE(ADLINK, 0x7433), BOARD_PCI7433 },
260         { PCI_VDEVICE(ADLINK, 0x7434), BOARD_PCI7434 },
261         { 0 }
262 };
263 MODULE_DEVICE_TABLE(pci, adl_pci7x3x_pci_table);
264 
265 static struct pci_driver adl_pci7x3x_pci_driver = {
266         .name           = "adl_pci7x3x",
267         .id_table       = adl_pci7x3x_pci_table,
268         .probe          = adl_pci7x3x_pci_probe,
269         .remove         = comedi_pci_auto_unconfig,
270 };
271 module_comedi_pci_driver(adl_pci7x3x_driver, adl_pci7x3x_pci_driver);
272 
273 MODULE_DESCRIPTION("ADLINK PCI-723x/743x Isolated Digital I/O boards");
274 MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
275 MODULE_LICENSE("GPL");
276 

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