2 * COMEDI driver for the ADLINK PCI-72xx series boards.
4 * COMEDI - Linux Control and Measurement Device Interface
5 * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 Description: 24/48/96-Channel Opto-22 Compatible Digital I/O Boards
25 Devices: (ADLink) PCI-7224 [adl_pci7224] - 24 channels
26 (ADLink) PCI-7248 [adl_pci7248] - 48 channels
27 (ADLink) PCI-7296 [adl_pci7296] - 96 channels
28 Author: Jon Grierson <jd@renko.co.uk>
29 Updated: Mon, 14 Apr 2008 15:05:56 +0100
32 This driver only attaches using the PCI PnP auto config support
33 in the comedi core. The module parameter 'comedi_autoconfig'
34 must be 1 (default) to enable this feature. The COMEDI_DEVCONFIG
35 ioctl, used by the comedi_config utility, is not supported by
38 These boards also have an 8254 programmable timer/counter chip.
39 This chip is not currently supported by this driver.
41 Interrupt support for these boards is also not currently supported.
43 Configuration Options: not applicable
46 #include "../comedidev.h"
51 * PCI Device ID's supported by this driver
53 #define PCI_DEVICE_ID_PCI7224 0x7224
54 #define PCI_DEVICE_ID_PCI7248 0x7248
55 #define PCI_DEVICE_ID_PCI7296 0x7296
57 struct adl_pci7296_boardinfo {
59 unsigned short device;
63 static const struct adl_pci7296_boardinfo adl_pci7296_boards[] = {
65 .name = "adl_pci7224",
66 .device = PCI_DEVICE_ID_PCI7224,
69 .name = "adl_pci7248",
70 .device = PCI_DEVICE_ID_PCI7248,
73 .name = "adl_pci7296",
74 .device = PCI_DEVICE_ID_PCI7296,
79 static const void *adl_pci7296_find_boardinfo(struct comedi_device *dev,
80 struct pci_dev *pcidev)
82 const struct adl_pci7296_boardinfo *board;
85 for (i = 0; i < ARRAY_SIZE(adl_pci7296_boards); i++) {
86 board = &adl_pci7296_boards[i];
87 if (pcidev->device == board->device)
93 static int adl_pci7296_attach_pci(struct comedi_device *dev,
94 struct pci_dev *pcidev)
96 const struct adl_pci7296_boardinfo *board;
97 struct comedi_subdevice *s;
101 comedi_set_hw_dev(dev, &pcidev->dev);
103 board = adl_pci7296_find_boardinfo(dev, pcidev);
106 dev->board_ptr = board;
107 dev->board_name = board->name;
109 ret = comedi_pci_enable(pcidev, dev->board_name);
112 dev->iobase = pci_resource_start(pcidev, 2);
115 * One, two, or four subdevices are setup by this driver depending
116 * on the number of channels provided by the board. Each subdevice
117 * has 24 channels supported by the 8255 module.
119 ret = comedi_alloc_subdevices(dev, board->nsubdevs);
123 for (i = 0; i < board->nsubdevs; i++) {
124 s = dev->subdevices + i;
125 ret = subdev_8255_init(dev, s, NULL, dev->iobase + (i * 4));
130 dev_info(dev->class_dev, "%s attached (%d digital i/o channels)\n",
131 dev->board_name, board->nsubdevs * 24);
136 static int adl_pci7296_attach(struct comedi_device *dev,
137 struct comedi_devconfig *it)
139 dev_warn(dev->class_dev,
140 "This driver does not support attach using comedi_config\n");
145 static void adl_pci7296_detach(struct comedi_device *dev)
147 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
148 const struct adl_pci7296_boardinfo *board = comedi_board(dev);
149 struct comedi_subdevice *s;
152 if (dev->subdevices) {
153 for (i = 0; i < board->nsubdevs; i++) {
154 s = dev->subdevices + i;
155 subdev_8255_cleanup(dev, s);
160 comedi_pci_disable(pcidev);
164 static struct comedi_driver adl_pci7296_driver = {
165 .driver_name = "adl_pci7296",
166 .module = THIS_MODULE,
167 .attach = adl_pci7296_attach,
168 .attach_pci = adl_pci7296_attach_pci,
169 .detach = adl_pci7296_detach,
172 static int __devinit adl_pci7296_pci_probe(struct pci_dev *dev,
173 const struct pci_device_id *ent)
175 return comedi_pci_auto_config(dev, &adl_pci7296_driver);
178 static void __devexit adl_pci7296_pci_remove(struct pci_dev *dev)
180 comedi_pci_auto_unconfig(dev);
183 static DEFINE_PCI_DEVICE_TABLE(adl_pci7296_pci_table) = {
184 { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7224) },
185 { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7248) },
186 { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7296) },
189 MODULE_DEVICE_TABLE(pci, adl_pci7296_pci_table);
191 static struct pci_driver adl_pci7296_pci_driver = {
192 .name = "adl_pci7296",
193 .id_table = adl_pci7296_pci_table,
194 .probe = adl_pci7296_pci_probe,
195 .remove = __devexit_p(adl_pci7296_pci_remove),
197 module_comedi_pci_driver(adl_pci7296_driver, adl_pci7296_pci_driver);
199 MODULE_DESCRIPTION("ADLINK PCI-72xx Opto-22 Compatible Digital I/O Boards");
200 MODULE_AUTHOR("Comedi http://www.comedi.org");
201 MODULE_LICENSE("GPL");