Version:  2.0.40 2.2.26 2.4.37 3.0 3.1 3.2 3.3 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

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

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