2 * COMEDI driver for generic PCI based 8255 digital i/o boards
3 * Copyright (C) 2012 H Hartley Sweeten <hsweeten@visionengravers.com>
5 * Based on the tested adl_pci7296 driver written by:
6 * Jon Grierson <jd@renko.co.uk>
7 * and the experimental cb_pcidio driver written by:
10 * COMEDI - Linux Control and Measurement Device Interface
11 * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
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.
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.
26 Description: Generic PCI based 8255 Digital I/O boards
27 Devices: (ADLink) PCI-7224 [adl_pci-7224] - 24 channels
28 (ADLink) PCI-7248 [adl_pci-7248] - 48 channels
29 (ADLink) PCI-7296 [adl_pci-7296] - 96 channels
30 (Measurement Computing) PCI-DIO24 [cb_pci-dio24] - 24 channels
31 (Measurement Computing) PCI-DIO24H [cb_pci-dio24h] - 24 channels
32 (Measurement Computing) PCI-DIO48H [cb_pci-dio48h] - 48 channels
33 (Measurement Computing) PCI-DIO96H [cb_pci-dio96h] - 96 channels
34 (National Instruments) PCI-DIO-96 [ni_pci-dio-96] - 96 channels
35 (National Instruments) PCI-DIO-96B [ni_pci-dio-96b] - 96 channels
36 (National Instruments) PXI-6508 [ni_pxi-6508] - 96 channels
37 (National Instruments) PCI-6503 [ni_pci-6503] - 24 channels
38 (National Instruments) PCI-6503B [ni_pci-6503b] - 24 channels
39 (National Instruments) PCI-6503X [ni_pci-6503x] - 24 channels
40 (National Instruments) PXI-6503 [ni_pxi-6503] - 24 channels
41 Author: H Hartley Sweeten <hsweeten@visionengravers.com>
42 Updated: Wed, 12 Sep 2012 11:52:01 -0700
45 Some of these boards also have an 8254 programmable timer/counter
46 chip. This chip is not currently supported by this driver.
48 Interrupt support for these boards is also not currently supported.
50 Configuration Options: not applicable, uses PCI auto config
53 #include <linux/pci.h>
55 #include "../comedidev.h"
59 enum pci_8255_boardid
{
76 struct pci_8255_boardinfo
{
82 static const struct pci_8255_boardinfo pci_8255_boards
[] = {
83 [BOARD_ADLINK_PCI7224
] = {
84 .name
= "adl_pci-7224",
88 [BOARD_ADLINK_PCI7248
] = {
89 .name
= "adl_pci-7248",
93 [BOARD_ADLINK_PCI7296
] = {
94 .name
= "adl_pci-7296",
98 [BOARD_CB_PCIDIO24
] = {
99 .name
= "cb_pci-dio24",
103 [BOARD_CB_PCIDIO24H
] = {
104 .name
= "cb_pci-dio24h",
108 [BOARD_CB_PCIDIO48H
] = {
109 .name
= "cb_pci-dio48h",
113 [BOARD_CB_PCIDIO96H
] = {
114 .name
= "cb_pci-dio96h",
118 [BOARD_NI_PCIDIO96
] = {
119 .name
= "ni_pci-dio-96",
123 [BOARD_NI_PCIDIO96B
] = {
124 .name
= "ni_pci-dio-96b",
128 [BOARD_NI_PXI6508
] = {
129 .name
= "ni_pxi-6508",
133 [BOARD_NI_PCI6503
] = {
134 .name
= "ni_pci-6503",
138 [BOARD_NI_PCI6503B
] = {
139 .name
= "ni_pci-6503b",
143 [BOARD_NI_PCI6503X
] = {
144 .name
= "ni_pci-6503x",
148 [BOARD_NI_PXI_6503
] = {
149 .name
= "ni_pxi-6503",
155 struct pci_8255_private
{
156 void __iomem
*mmio_base
;
159 static int pci_8255_mmio(int dir
, int port
, int data
, unsigned long iobase
)
161 void __iomem
*mmio_base
= (void __iomem
*)iobase
;
164 writeb(data
, mmio_base
+ port
);
167 return readb(mmio_base
+ port
);
171 static int pci_8255_auto_attach(struct comedi_device
*dev
,
172 unsigned long context
)
174 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
175 const struct pci_8255_boardinfo
*board
= NULL
;
176 struct pci_8255_private
*devpriv
;
177 struct comedi_subdevice
*s
;
182 if (context
< ARRAY_SIZE(pci_8255_boards
))
183 board
= &pci_8255_boards
[context
];
186 dev
->board_ptr
= board
;
187 dev
->board_name
= board
->name
;
189 devpriv
= kzalloc(sizeof(*devpriv
), GFP_KERNEL
);
192 dev
->private = devpriv
;
194 ret
= comedi_pci_enable(dev
);
198 is_mmio
= (pci_resource_flags(pcidev
, board
->dio_badr
) &
199 IORESOURCE_MEM
) != 0;
201 devpriv
->mmio_base
= pci_ioremap_bar(pcidev
, board
->dio_badr
);
202 if (!devpriv
->mmio_base
)
205 dev
->iobase
= pci_resource_start(pcidev
, board
->dio_badr
);
209 * One, two, or four subdevices are setup by this driver depending
210 * on the number of channels provided by the board. Each subdevice
211 * has 24 channels supported by the 8255 module.
213 ret
= comedi_alloc_subdevices(dev
, board
->n_8255
);
217 for (i
= 0; i
< board
->n_8255
; i
++) {
218 unsigned long iobase
;
220 s
= &dev
->subdevices
[i
];
222 iobase
= (unsigned long)(devpriv
->mmio_base
+ (i
* 4));
223 ret
= subdev_8255_init(dev
, s
, pci_8255_mmio
, iobase
);
225 iobase
= dev
->iobase
+ (i
* 4);
226 ret
= subdev_8255_init(dev
, s
, NULL
, iobase
);
232 dev_info(dev
->class_dev
, "%s attached (%d digital i/o channels)\n",
233 dev
->board_name
, board
->n_8255
* 24);
238 static void pci_8255_detach(struct comedi_device
*dev
)
240 struct pci_8255_private
*devpriv
= dev
->private;
242 if (devpriv
&& devpriv
->mmio_base
)
243 iounmap(devpriv
->mmio_base
);
244 comedi_pci_disable(dev
);
247 static struct comedi_driver pci_8255_driver
= {
248 .driver_name
= "8255_pci",
249 .module
= THIS_MODULE
,
250 .auto_attach
= pci_8255_auto_attach
,
251 .detach
= pci_8255_detach
,
254 static int pci_8255_pci_probe(struct pci_dev
*dev
,
255 const struct pci_device_id
*id
)
257 return comedi_pci_auto_config(dev
, &pci_8255_driver
, id
->driver_data
);
260 static DEFINE_PCI_DEVICE_TABLE(pci_8255_pci_table
) = {
261 { PCI_VDEVICE(ADLINK
, 0x7224), BOARD_ADLINK_PCI7224
},
262 { PCI_VDEVICE(ADLINK
, 0x7248), BOARD_ADLINK_PCI7248
},
263 { PCI_VDEVICE(ADLINK
, 0x7296), BOARD_ADLINK_PCI7296
},
264 { PCI_VDEVICE(CB
, 0x0028), BOARD_CB_PCIDIO24
},
265 { PCI_VDEVICE(CB
, 0x0014), BOARD_CB_PCIDIO24H
},
266 { PCI_VDEVICE(CB
, 0x000b), BOARD_CB_PCIDIO48H
},
267 { PCI_VDEVICE(CB
, 0x0017), BOARD_CB_PCIDIO96H
},
268 { PCI_VDEVICE(NI
, 0x0160), BOARD_NI_PCIDIO96
},
269 { PCI_VDEVICE(NI
, 0x1630), BOARD_NI_PCIDIO96B
},
270 { PCI_VDEVICE(NI
, 0x13c0), BOARD_NI_PXI6508
},
271 { PCI_VDEVICE(NI
, 0x0400), BOARD_NI_PCI6503
},
272 { PCI_VDEVICE(NI
, 0x1250), BOARD_NI_PCI6503B
},
273 { PCI_VDEVICE(NI
, 0x17d0), BOARD_NI_PCI6503X
},
274 { PCI_VDEVICE(NI
, 0x1800), BOARD_NI_PXI_6503
},
277 MODULE_DEVICE_TABLE(pci
, pci_8255_pci_table
);
279 static struct pci_driver pci_8255_pci_driver
= {
281 .id_table
= pci_8255_pci_table
,
282 .probe
= pci_8255_pci_probe
,
283 .remove
= comedi_pci_auto_unconfig
,
285 module_comedi_pci_driver(pci_8255_driver
, pci_8255_pci_driver
);
287 MODULE_DESCRIPTION("COMEDI - Generic PCI based 8255 Digital I/O boards");
288 MODULE_AUTHOR("Comedi http://www.comedi.org");
289 MODULE_LICENSE("GPL");