2 comedi/drivers/cb_pcidio.c
3 A Comedi driver for PCI-DIO24H & PCI-DIO48H of ComputerBoards (currently MeasurementComputing)
5 COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 2000 David A. Schleef <ds@schleef.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 Description: ComputerBoards' DIO boards with PCI interface
26 Devices: [Measurement Computing] PCI-DIO24 (cb_pcidio), PCI-DIO24H, PCI-DIO48H
27 Author: Yoshiya Matsuzaka
28 Updated: Mon, 29 Oct 2007 15:40:47 +0000
31 This driver has been modified from skel.c of comedi-0.7.70.
33 Configuration Options:
34 [0] - PCI bus of device (optional)
35 [1] - PCI slot of device (optional)
36 If bus/slot is not specified, the first available PCI device will
39 Passing a zero for an option is the same as leaving it unspecified.
42 /*------------------------------ HEADER FILES ---------------------------------*/
43 #include "../comedidev.h"
46 /*-------------------------- MACROS and DATATYPES -----------------------------*/
47 #define PCI_VENDOR_ID_CB 0x1307
50 * Board descriptions for two imaginary boards. Describing the
51 * boards in this way is optional, and completely driver-dependent.
52 * Some drivers use arrays such as this, other do not.
55 const char *name; /* name of the board */
57 int n_8255; /* number of 8255 chips on board */
59 /* indices of base address regions */
60 int pcicontroler_badrindex;
61 int dioregs_badrindex;
64 static const struct pcidio_board pcidio_boards[] = {
69 .pcicontroler_badrindex = 1,
70 .dioregs_badrindex = 2,
76 .pcicontroler_badrindex = 1,
77 .dioregs_badrindex = 2,
83 .pcicontroler_badrindex = 0,
84 .dioregs_badrindex = 1,
89 * Useful for shorthand access to the particular board structure
91 #define thisboard ((const struct pcidio_board *)dev->board_ptr)
93 static struct pci_dev *pcidio_find_pci_dev(struct comedi_device *dev,
94 struct comedi_devconfig *it)
96 struct pci_dev *pcidev = NULL;
97 int bus = it->options[0];
98 int slot = it->options[1];
101 for_each_pci_dev(pcidev) {
103 if (bus != pcidev->bus->number ||
104 slot != PCI_SLOT(pcidev->devfn))
107 if (pcidev->vendor != PCI_VENDOR_ID_CB)
109 for (i = 0; i < ARRAY_SIZE(pcidio_boards); i++) {
110 if (pcidio_boards[i].dev_id != pcidev->device)
113 dev->board_ptr = pcidio_boards + i;
117 dev_err(dev->class_dev,
118 "No supported board found! (req. bus %d, slot %d)\n",
123 static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
125 struct pci_dev *pcidev;
129 pcidev = pcidio_find_pci_dev(dev, it);
132 comedi_set_hw_dev(dev, &pcidev->dev);
135 * Initialize dev->board_name. Note that we can use the "thisboard"
136 * macro now, since we just initialized it in the last line.
138 dev->board_name = thisboard->name;
140 if (comedi_pci_enable(pcidev, thisboard->name))
143 dev->iobase = pci_resource_start(pcidev, thisboard->dioregs_badrindex);
145 ret = comedi_alloc_subdevices(dev, thisboard->n_8255);
149 for (i = 0; i < thisboard->n_8255; i++) {
150 subdev_8255_init(dev, dev->subdevices + i,
151 NULL, dev->iobase + i * 4);
152 dev_dbg(dev->class_dev, "subdev %d: base = 0x%lx\n", i,
153 dev->iobase + i * 4);
159 static void pcidio_detach(struct comedi_device *dev)
161 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
165 comedi_pci_disable(pcidev);
168 if (dev->subdevices) {
170 for (i = 0; i < thisboard->n_8255; i++)
171 subdev_8255_cleanup(dev, dev->subdevices + i);
175 static struct comedi_driver cb_pcidio_driver = {
176 .driver_name = "cb_pcidio",
177 .module = THIS_MODULE,
178 .attach = pcidio_attach,
179 .detach = pcidio_detach,
182 static int __devinit cb_pcidio_pci_probe(struct pci_dev *dev,
183 const struct pci_device_id *ent)
185 return comedi_pci_auto_config(dev, &cb_pcidio_driver);
188 static void __devexit cb_pcidio_pci_remove(struct pci_dev *dev)
190 comedi_pci_auto_unconfig(dev);
193 static DEFINE_PCI_DEVICE_TABLE(cb_pcidio_pci_table) = {
194 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0028) },
195 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0014) },
196 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000b) },
199 MODULE_DEVICE_TABLE(pci, cb_pcidio_pci_table);
201 static struct pci_driver cb_pcidio_pci_driver = {
203 .id_table = cb_pcidio_pci_table,
204 .probe = cb_pcidio_pci_probe,
205 .remove = __devexit_p(cb_pcidio_pci_remove),
207 module_comedi_pci_driver(cb_pcidio_driver, cb_pcidio_pci_driver);
209 MODULE_AUTHOR("Comedi http://www.comedi.org");
210 MODULE_DESCRIPTION("Comedi low-level driver");
211 MODULE_LICENSE("GPL");