staging: comedi: adv_pci_dio: remove 'main_pci_region' boardinfo
[deliverable/linux.git] / drivers / staging / comedi / drivers / adv_pci_dio.c
1 /*
2 * comedi/drivers/adv_pci_dio.c
3 *
4 * Author: Michal Dobes <dobes@tesnet.cz>
5 *
6 * Hardware driver for Advantech PCI DIO cards.
7 */
8
9 /*
10 * Driver: adv_pci_dio
11 * Description: Advantech PCI-1730, PCI-1733, PCI-1734, PCI-1735U,
12 * PCI-1736UP, PCI-1739U, PCI-1750, PCI-1751, PCI-1752,
13 * PCI-1753/E, PCI-1754, PCI-1756, PCI-1762
14 * Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733,
15 * PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U, PCI-1750,
16 * PCI-1751, PCI-1752, PCI-1753,
17 * PCI-1753+PCI-1753E, PCI-1754, PCI-1756,
18 * PCI-1762
19 * Author: Michal Dobes <dobes@tesnet.cz>
20 * Updated: Mon, 09 Jan 2012 12:40:46 +0000
21 * Status: untested
22 *
23 * Configuration Options: not applicable, uses PCI auto config
24 */
25
26 #include <linux/module.h>
27 #include <linux/delay.h>
28
29 #include "../comedi_pci.h"
30
31 #include "8255.h"
32 #include "comedi_8254.h"
33
34 /* hardware types of the cards */
35 enum hw_cards_id {
36 TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734, TYPE_PCI1735, TYPE_PCI1736,
37 TYPE_PCI1739,
38 TYPE_PCI1750,
39 TYPE_PCI1751,
40 TYPE_PCI1752,
41 TYPE_PCI1753, TYPE_PCI1753E,
42 TYPE_PCI1754, TYPE_PCI1756,
43 TYPE_PCI1762
44 };
45
46 /* which I/O instructions to use */
47 enum hw_io_access {
48 IO_8b, IO_16b
49 };
50
51 #define MAX_DI_SUBDEVS 2 /* max number of DI subdevices per card */
52 #define MAX_DO_SUBDEVS 2 /* max number of DO subdevices per card */
53 #define MAX_DIO_SUBDEVG 2 /* max number of DIO subdevices group per
54 * card */
55
56 /* Register offset definitions */
57 /* Advantech PCI-1730/3/4 */
58 #define PCI1730_IDI 0 /* R: Isolated digital input 0-15 */
59 #define PCI1730_IDO 0 /* W: Isolated digital output 0-15 */
60 #define PCI1730_DI 2 /* R: Digital input 0-15 */
61 #define PCI1730_DO 2 /* W: Digital output 0-15 */
62 #define PCI1733_IDI 0 /* R: Isolated digital input 0-31 */
63 #define PCI1730_3_INT_EN 0x08 /* R/W: enable/disable interrupts */
64 #define PCI1730_3_INT_RF 0x0c /* R/W: set falling/raising edge for
65 * interrupts */
66 #define PCI1730_3_INT_CLR 0x10 /* R/W: clear interrupts */
67 #define PCI1734_IDO 0 /* W: Isolated digital output 0-31 */
68 #define PCI173x_BOARDID 4 /* R: Board I/D switch for 1730/3/4 */
69
70 /* Advantech PCI-1735U */
71 #define PCI1735_DI 0 /* R: Digital input 0-31 */
72 #define PCI1735_DO 0 /* W: Digital output 0-31 */
73 #define PCI1735_C8254 4 /* R/W: 8254 counter */
74 #define PCI1735_BOARDID 8 /* R: Board I/D switch for 1735U */
75
76 /* Advantech PCI-1736UP */
77 #define PCI1736_IDI 0 /* R: Isolated digital input 0-15 */
78 #define PCI1736_IDO 0 /* W: Isolated digital output 0-15 */
79 #define PCI1736_3_INT_EN 0x08 /* R/W: enable/disable interrupts */
80 #define PCI1736_3_INT_RF 0x0c /* R/W: set falling/raising edge for
81 * interrupts */
82 #define PCI1736_3_INT_CLR 0x10 /* R/W: clear interrupts */
83 #define PCI1736_BOARDID 4 /* R: Board I/D switch for 1736UP */
84
85 /* Advantech PCI-1739U */
86 #define PCI1739_DIO 0 /* R/W: begin of 8255 registers block */
87 #define PCI1739_ICR 32 /* W: Interrupt control register */
88 #define PCI1739_ISR 32 /* R: Interrupt status register */
89 #define PCI1739_BOARDID 8 /* R: Board I/D switch for 1739U */
90
91 /* Advantech PCI-1750 */
92 #define PCI1750_IDI 0 /* R: Isolated digital input 0-15 */
93 #define PCI1750_IDO 0 /* W: Isolated digital output 0-15 */
94 #define PCI1750_ICR 32 /* W: Interrupt control register */
95 #define PCI1750_ISR 32 /* R: Interrupt status register */
96
97 /* Advantech PCI-1751/3/3E */
98 #define PCI1751_DIO 0 /* R/W: begin of 8255 registers block */
99 #define PCI1751_CNT 24 /* R/W: begin of 8254 registers block */
100 #define PCI1751_ICR 32 /* W: Interrupt control register */
101 #define PCI1751_ISR 32 /* R: Interrupt status register */
102 #define PCI1753_DIO 0 /* R/W: begin of 8255 registers block */
103 #define PCI1753_ICR0 16 /* R/W: Interrupt control register group 0 */
104 #define PCI1753_ICR1 17 /* R/W: Interrupt control register group 1 */
105 #define PCI1753_ICR2 18 /* R/W: Interrupt control register group 2 */
106 #define PCI1753_ICR3 19 /* R/W: Interrupt control register group 3 */
107 #define PCI1753E_DIO 32 /* R/W: begin of 8255 registers block */
108 #define PCI1753E_ICR0 48 /* R/W: Interrupt control register group 0 */
109 #define PCI1753E_ICR1 49 /* R/W: Interrupt control register group 1 */
110 #define PCI1753E_ICR2 50 /* R/W: Interrupt control register group 2 */
111 #define PCI1753E_ICR3 51 /* R/W: Interrupt control register group 3 */
112
113 /* Advantech PCI-1752/4/6 */
114 #define PCI1752_IDO 0 /* R/W: Digital output 0-31 */
115 #define PCI1752_IDO2 4 /* R/W: Digital output 32-63 */
116 #define PCI1754_IDI 0 /* R: Digital input 0-31 */
117 #define PCI1754_IDI2 4 /* R: Digital input 32-64 */
118 #define PCI1756_IDI 0 /* R: Digital input 0-31 */
119 #define PCI1756_IDO 4 /* R/W: Digital output 0-31 */
120 #define PCI1754_6_ICR0 0x08 /* R/W: Interrupt control register group 0 */
121 #define PCI1754_6_ICR1 0x0a /* R/W: Interrupt control register group 1 */
122 #define PCI1754_ICR2 0x0c /* R/W: Interrupt control register group 2 */
123 #define PCI1754_ICR3 0x0e /* R/W: Interrupt control register group 3 */
124 #define PCI1752_6_CFC 0x12 /* R/W: set/read channel freeze function */
125 #define PCI175x_BOARDID 0x10 /* R: Board I/D switch for 1752/4/6 */
126
127 /* Advantech PCI-1762 registers */
128 #define PCI1762_RO 0 /* R/W: Relays status/output */
129 #define PCI1762_IDI 2 /* R: Isolated input status */
130 #define PCI1762_BOARDID 4 /* R: Board I/D switch */
131 #define PCI1762_ICR 6 /* W: Interrupt control register */
132 #define PCI1762_ISR 6 /* R: Interrupt status register */
133
134 struct diosubd_data {
135 int chans; /* num of chans */
136 int addr; /* PCI address ofset */
137 int regs; /* number of registers to read or 8255
138 subdevices */
139 unsigned int specflags; /* addon subdevice flags */
140 };
141
142 struct dio_boardtype {
143 const char *name; /* board name */
144 enum hw_cards_id cardtype;
145 int nsubdevs;
146 struct diosubd_data sdi[MAX_DI_SUBDEVS]; /* DI chans */
147 struct diosubd_data sdo[MAX_DO_SUBDEVS]; /* DO chans */
148 struct diosubd_data sdio[MAX_DIO_SUBDEVG]; /* DIO 8255 chans */
149 struct diosubd_data boardid; /* card supports board ID switch */
150 unsigned long timer_regbase;
151 enum hw_io_access io_access;
152 };
153
154 static const struct dio_boardtype boardtypes[] = {
155 [TYPE_PCI1730] = {
156 .name = "pci1730",
157 .cardtype = TYPE_PCI1730,
158 .nsubdevs = 5,
159 .sdi[0] = { 16, PCI1730_DI, 2, 0, },
160 .sdi[1] = { 16, PCI1730_IDI, 2, 0, },
161 .sdo[0] = { 16, PCI1730_DO, 2, 0, },
162 .sdo[1] = { 16, PCI1730_IDO, 2, 0, },
163 .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, },
164 .io_access = IO_8b,
165 },
166 [TYPE_PCI1733] = {
167 .name = "pci1733",
168 .cardtype = TYPE_PCI1733,
169 .nsubdevs = 2,
170 .sdi[1] = { 32, PCI1733_IDI, 4, 0, },
171 .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, },
172 .io_access = IO_8b,
173 },
174 [TYPE_PCI1734] = {
175 .name = "pci1734",
176 .cardtype = TYPE_PCI1734,
177 .nsubdevs = 2,
178 .sdo[1] = { 32, PCI1734_IDO, 4, 0, },
179 .boardid = { 4, PCI173x_BOARDID, 1, SDF_INTERNAL, },
180 .io_access = IO_8b,
181 },
182 [TYPE_PCI1735] = {
183 .name = "pci1735",
184 .cardtype = TYPE_PCI1735,
185 .nsubdevs = 4,
186 .sdi[0] = { 32, PCI1735_DI, 4, 0, },
187 .sdo[0] = { 32, PCI1735_DO, 4, 0, },
188 .boardid = { 4, PCI1735_BOARDID, 1, SDF_INTERNAL, },
189 .timer_regbase = PCI1735_C8254,
190 .io_access = IO_8b,
191 },
192 [TYPE_PCI1736] = {
193 .name = "pci1736",
194 .cardtype = TYPE_PCI1736,
195 .nsubdevs = 3,
196 .sdi[1] = { 16, PCI1736_IDI, 2, 0, },
197 .sdo[1] = { 16, PCI1736_IDO, 2, 0, },
198 .boardid = { 4, PCI1736_BOARDID, 1, SDF_INTERNAL, },
199 .io_access = IO_8b,
200 },
201 [TYPE_PCI1739] = {
202 .name = "pci1739",
203 .cardtype = TYPE_PCI1739,
204 .nsubdevs = 2,
205 .sdio[0] = { 48, PCI1739_DIO, 2, 0, },
206 .io_access = IO_8b,
207 },
208 [TYPE_PCI1750] = {
209 .name = "pci1750",
210 .cardtype = TYPE_PCI1750,
211 .nsubdevs = 2,
212 .sdi[1] = { 16, PCI1750_IDI, 2, 0, },
213 .sdo[1] = { 16, PCI1750_IDO, 2, 0, },
214 .io_access = IO_8b,
215 },
216 [TYPE_PCI1751] = {
217 .name = "pci1751",
218 .cardtype = TYPE_PCI1751,
219 .nsubdevs = 3,
220 .sdio[0] = { 48, PCI1751_DIO, 2, 0, },
221 .timer_regbase = PCI1751_CNT,
222 .io_access = IO_8b,
223 },
224 [TYPE_PCI1752] = {
225 .name = "pci1752",
226 .cardtype = TYPE_PCI1752,
227 .nsubdevs = 3,
228 .sdo[0] = { 32, PCI1752_IDO, 2, 0, },
229 .sdo[1] = { 32, PCI1752_IDO2, 2, 0, },
230 .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, },
231 .io_access = IO_16b,
232 },
233 [TYPE_PCI1753] = {
234 .name = "pci1753",
235 .cardtype = TYPE_PCI1753,
236 .nsubdevs = 4,
237 .sdio[0] = { 96, PCI1753_DIO, 4, 0, },
238 .io_access = IO_8b,
239 },
240 [TYPE_PCI1753E] = {
241 .name = "pci1753e",
242 .cardtype = TYPE_PCI1753E,
243 .nsubdevs = 8,
244 .sdio[0] = { 96, PCI1753_DIO, 4, 0, },
245 .sdio[1] = { 96, PCI1753E_DIO, 4, 0, },
246 .io_access = IO_8b,
247 },
248 [TYPE_PCI1754] = {
249 .name = "pci1754",
250 .cardtype = TYPE_PCI1754,
251 .nsubdevs = 3,
252 .sdi[0] = { 32, PCI1754_IDI, 2, 0, },
253 .sdi[1] = { 32, PCI1754_IDI2, 2, 0, },
254 .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, },
255 .io_access = IO_16b,
256 },
257 [TYPE_PCI1756] = {
258 .name = "pci1756",
259 .cardtype = TYPE_PCI1756,
260 .nsubdevs = 3,
261 .sdi[1] = { 32, PCI1756_IDI, 2, 0, },
262 .sdo[1] = { 32, PCI1756_IDO, 2, 0, },
263 .boardid = { 4, PCI175x_BOARDID, 1, SDF_INTERNAL, },
264 .io_access = IO_16b,
265 },
266 [TYPE_PCI1762] = {
267 .name = "pci1762",
268 .cardtype = TYPE_PCI1762,
269 .nsubdevs = 3,
270 .sdi[1] = { 16, PCI1762_IDI, 1, 0, },
271 .sdo[1] = { 16, PCI1762_RO, 1, 0, },
272 .boardid = { 4, PCI1762_BOARDID, 1, SDF_INTERNAL, },
273 .io_access = IO_16b,
274 },
275 };
276
277 static int pci_dio_insn_bits_di_b(struct comedi_device *dev,
278 struct comedi_subdevice *s,
279 struct comedi_insn *insn, unsigned int *data)
280 {
281 const struct diosubd_data *d = (const struct diosubd_data *)s->private;
282 int i;
283
284 data[1] = 0;
285 for (i = 0; i < d->regs; i++)
286 data[1] |= inb(dev->iobase + d->addr + i) << (8 * i);
287
288 return insn->n;
289 }
290
291 static int pci_dio_insn_bits_di_w(struct comedi_device *dev,
292 struct comedi_subdevice *s,
293 struct comedi_insn *insn, unsigned int *data)
294 {
295 const struct diosubd_data *d = (const struct diosubd_data *)s->private;
296 int i;
297
298 data[1] = 0;
299 for (i = 0; i < d->regs; i++)
300 data[1] |= inw(dev->iobase + d->addr + 2 * i) << (16 * i);
301
302 return insn->n;
303 }
304
305 static int pci_dio_insn_bits_do_b(struct comedi_device *dev,
306 struct comedi_subdevice *s,
307 struct comedi_insn *insn,
308 unsigned int *data)
309 {
310 const struct diosubd_data *d = (const struct diosubd_data *)s->private;
311 int i;
312
313 if (comedi_dio_update_state(s, data)) {
314 for (i = 0; i < d->regs; i++)
315 outb((s->state >> (8 * i)) & 0xff,
316 dev->iobase + d->addr + i);
317 }
318
319 data[1] = s->state;
320
321 return insn->n;
322 }
323
324 static int pci_dio_insn_bits_do_w(struct comedi_device *dev,
325 struct comedi_subdevice *s,
326 struct comedi_insn *insn,
327 unsigned int *data)
328 {
329 const struct diosubd_data *d = (const struct diosubd_data *)s->private;
330 int i;
331
332 if (comedi_dio_update_state(s, data)) {
333 for (i = 0; i < d->regs; i++)
334 outw((s->state >> (16 * i)) & 0xffff,
335 dev->iobase + d->addr + 2 * i);
336 }
337
338 data[1] = s->state;
339
340 return insn->n;
341 }
342
343 static int pci_dio_reset(struct comedi_device *dev)
344 {
345 const struct dio_boardtype *board = dev->board_ptr;
346
347 switch (board->cardtype) {
348 case TYPE_PCI1730:
349 outb(0, dev->iobase + PCI1730_DO); /* clear outputs */
350 outb(0, dev->iobase + PCI1730_DO + 1);
351 outb(0, dev->iobase + PCI1730_IDO);
352 outb(0, dev->iobase + PCI1730_IDO + 1);
353 /* fallthrough */
354 case TYPE_PCI1733:
355 /* disable interrupts */
356 outb(0, dev->iobase + PCI1730_3_INT_EN);
357 /* clear interrupts */
358 outb(0x0f, dev->iobase + PCI1730_3_INT_CLR);
359 /* set rising edge trigger */
360 outb(0, dev->iobase + PCI1730_3_INT_RF);
361 break;
362 case TYPE_PCI1734:
363 outb(0, dev->iobase + PCI1734_IDO); /* clear outputs */
364 outb(0, dev->iobase + PCI1734_IDO + 1);
365 outb(0, dev->iobase + PCI1734_IDO + 2);
366 outb(0, dev->iobase + PCI1734_IDO + 3);
367 break;
368 case TYPE_PCI1735:
369 outb(0, dev->iobase + PCI1735_DO); /* clear outputs */
370 outb(0, dev->iobase + PCI1735_DO + 1);
371 outb(0, dev->iobase + PCI1735_DO + 2);
372 outb(0, dev->iobase + PCI1735_DO + 3);
373 break;
374
375 case TYPE_PCI1736:
376 outb(0, dev->iobase + PCI1736_IDO);
377 outb(0, dev->iobase + PCI1736_IDO + 1);
378 /* disable interrupts */
379 outb(0, dev->iobase + PCI1736_3_INT_EN);
380 /* clear interrupts */
381 outb(0x0f, dev->iobase + PCI1736_3_INT_CLR);
382 /* set rising edge trigger */
383 outb(0, dev->iobase + PCI1736_3_INT_RF);
384 break;
385
386 case TYPE_PCI1739:
387 /* disable & clear interrupts */
388 outb(0x88, dev->iobase + PCI1739_ICR);
389 break;
390
391 case TYPE_PCI1750:
392 case TYPE_PCI1751:
393 /* disable & clear interrupts */
394 outb(0x88, dev->iobase + PCI1750_ICR);
395 break;
396 case TYPE_PCI1752:
397 outw(0, dev->iobase + PCI1752_6_CFC); /* disable channel freeze
398 * function */
399 outw(0, dev->iobase + PCI1752_IDO); /* clear outputs */
400 outw(0, dev->iobase + PCI1752_IDO + 2);
401 outw(0, dev->iobase + PCI1752_IDO2);
402 outw(0, dev->iobase + PCI1752_IDO2 + 2);
403 break;
404 case TYPE_PCI1753E:
405 outb(0x88, dev->iobase + PCI1753E_ICR0); /* disable & clear
406 * interrupts */
407 outb(0x80, dev->iobase + PCI1753E_ICR1);
408 outb(0x80, dev->iobase + PCI1753E_ICR2);
409 outb(0x80, dev->iobase + PCI1753E_ICR3);
410 /* fallthrough */
411 case TYPE_PCI1753:
412 outb(0x88, dev->iobase + PCI1753_ICR0); /* disable & clear
413 * interrupts */
414 outb(0x80, dev->iobase + PCI1753_ICR1);
415 outb(0x80, dev->iobase + PCI1753_ICR2);
416 outb(0x80, dev->iobase + PCI1753_ICR3);
417 break;
418 case TYPE_PCI1754:
419 outw(0x08, dev->iobase + PCI1754_6_ICR0); /* disable and clear
420 * interrupts */
421 outw(0x08, dev->iobase + PCI1754_6_ICR1);
422 outw(0x08, dev->iobase + PCI1754_ICR2);
423 outw(0x08, dev->iobase + PCI1754_ICR3);
424 break;
425 case TYPE_PCI1756:
426 outw(0, dev->iobase + PCI1752_6_CFC); /* disable channel freeze
427 * function */
428 outw(0x08, dev->iobase + PCI1754_6_ICR0); /* disable and clear
429 * interrupts */
430 outw(0x08, dev->iobase + PCI1754_6_ICR1);
431 outw(0, dev->iobase + PCI1756_IDO); /* clear outputs */
432 outw(0, dev->iobase + PCI1756_IDO + 2);
433 break;
434 case TYPE_PCI1762:
435 outw(0x0101, dev->iobase + PCI1762_ICR); /* disable & clear
436 * interrupts */
437 break;
438 }
439
440 return 0;
441 }
442
443 static int pci_dio_add_di(struct comedi_device *dev,
444 struct comedi_subdevice *s,
445 const struct diosubd_data *d)
446 {
447 const struct dio_boardtype *board = dev->board_ptr;
448
449 s->type = COMEDI_SUBD_DI;
450 s->subdev_flags = SDF_READABLE | d->specflags;
451 if (d->chans > 16)
452 s->subdev_flags |= SDF_LSAMPL;
453 s->n_chan = d->chans;
454 s->maxdata = 1;
455 s->len_chanlist = d->chans;
456 s->range_table = &range_digital;
457 switch (board->io_access) {
458 case IO_8b:
459 s->insn_bits = pci_dio_insn_bits_di_b;
460 break;
461 case IO_16b:
462 s->insn_bits = pci_dio_insn_bits_di_w;
463 break;
464 }
465 s->private = (void *)d;
466
467 return 0;
468 }
469
470 static int pci_dio_add_do(struct comedi_device *dev,
471 struct comedi_subdevice *s,
472 const struct diosubd_data *d)
473 {
474 const struct dio_boardtype *board = dev->board_ptr;
475
476 s->type = COMEDI_SUBD_DO;
477 s->subdev_flags = SDF_WRITABLE;
478 if (d->chans > 16)
479 s->subdev_flags |= SDF_LSAMPL;
480 s->n_chan = d->chans;
481 s->maxdata = 1;
482 s->len_chanlist = d->chans;
483 s->range_table = &range_digital;
484 s->state = 0;
485 switch (board->io_access) {
486 case IO_8b:
487 s->insn_bits = pci_dio_insn_bits_do_b;
488 break;
489 case IO_16b:
490 s->insn_bits = pci_dio_insn_bits_do_w;
491 break;
492 }
493 s->private = (void *)d;
494
495 return 0;
496 }
497
498 static unsigned long pci_dio_override_cardtype(struct pci_dev *pcidev,
499 unsigned long cardtype)
500 {
501 /*
502 * Change cardtype from TYPE_PCI1753 to TYPE_PCI1753E if expansion
503 * board available. Need to enable PCI device and request the main
504 * registers PCI BAR temporarily to perform the test.
505 */
506 if (cardtype != TYPE_PCI1753)
507 return cardtype;
508 if (pci_enable_device(pcidev) < 0)
509 return cardtype;
510 if (pci_request_region(pcidev, 2, "adv_pci_dio") == 0) {
511 /*
512 * This test is based on Advantech's "advdaq" driver source
513 * (which declares its module licence as "GPL" although the
514 * driver source does not include a "COPYING" file).
515 */
516 unsigned long reg = pci_resource_start(pcidev, 2) + 53;
517
518 outb(0x05, reg);
519 if ((inb(reg) & 0x07) == 0x02) {
520 outb(0x02, reg);
521 if ((inb(reg) & 0x07) == 0x05)
522 cardtype = TYPE_PCI1753E;
523 }
524 pci_release_region(pcidev, 2);
525 }
526 pci_disable_device(pcidev);
527 return cardtype;
528 }
529
530 static int pci_dio_auto_attach(struct comedi_device *dev,
531 unsigned long context)
532 {
533 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
534 const struct dio_boardtype *board = NULL;
535 struct comedi_subdevice *s;
536 int ret, subdev, i, j;
537
538 if (context < ARRAY_SIZE(boardtypes))
539 board = &boardtypes[context];
540 if (!board)
541 return -ENODEV;
542 dev->board_ptr = board;
543 dev->board_name = board->name;
544
545 ret = comedi_pci_enable(dev);
546 if (ret)
547 return ret;
548 if (board->cardtype == TYPE_PCI1736)
549 dev->iobase = pci_resource_start(pcidev, 0);
550 else
551 dev->iobase = pci_resource_start(pcidev, 2);
552
553 ret = comedi_alloc_subdevices(dev, board->nsubdevs);
554 if (ret)
555 return ret;
556
557 subdev = 0;
558 for (i = 0; i < MAX_DI_SUBDEVS; i++)
559 if (board->sdi[i].chans) {
560 s = &dev->subdevices[subdev];
561 pci_dio_add_di(dev, s, &board->sdi[i]);
562 subdev++;
563 }
564
565 for (i = 0; i < MAX_DO_SUBDEVS; i++)
566 if (board->sdo[i].chans) {
567 s = &dev->subdevices[subdev];
568 pci_dio_add_do(dev, s, &board->sdo[i]);
569 subdev++;
570 }
571
572 for (i = 0; i < MAX_DIO_SUBDEVG; i++)
573 for (j = 0; j < board->sdio[i].regs; j++) {
574 s = &dev->subdevices[subdev];
575 ret = subdev_8255_init(dev, s, NULL,
576 board->sdio[i].addr +
577 j * I8255_SIZE);
578 if (ret)
579 return ret;
580 subdev++;
581 }
582
583 if (board->boardid.chans) {
584 s = &dev->subdevices[subdev];
585 s->type = COMEDI_SUBD_DI;
586 pci_dio_add_di(dev, s, &board->boardid);
587 subdev++;
588 }
589
590 if (board->timer_regbase) {
591 s = &dev->subdevices[subdev];
592
593 dev->pacer = comedi_8254_init(dev->iobase +
594 board->timer_regbase,
595 0, I8254_IO8, 0);
596 if (!dev->pacer)
597 return -ENOMEM;
598
599 comedi_8254_subdevice_init(s, dev->pacer);
600
601 subdev++;
602 }
603
604 pci_dio_reset(dev);
605
606 return 0;
607 }
608
609 static void pci_dio_detach(struct comedi_device *dev)
610 {
611 if (dev->iobase)
612 pci_dio_reset(dev);
613 comedi_pci_detach(dev);
614 }
615
616 static struct comedi_driver adv_pci_dio_driver = {
617 .driver_name = "adv_pci_dio",
618 .module = THIS_MODULE,
619 .auto_attach = pci_dio_auto_attach,
620 .detach = pci_dio_detach,
621 };
622
623 static int adv_pci_dio_pci_probe(struct pci_dev *dev,
624 const struct pci_device_id *id)
625 {
626 unsigned long cardtype;
627
628 cardtype = pci_dio_override_cardtype(dev, id->driver_data);
629 return comedi_pci_auto_config(dev, &adv_pci_dio_driver, cardtype);
630 }
631
632 static const struct pci_device_id adv_pci_dio_pci_table[] = {
633 { PCI_VDEVICE(ADVANTECH, 0x1730), TYPE_PCI1730 },
634 { PCI_VDEVICE(ADVANTECH, 0x1733), TYPE_PCI1733 },
635 { PCI_VDEVICE(ADVANTECH, 0x1734), TYPE_PCI1734 },
636 { PCI_VDEVICE(ADVANTECH, 0x1735), TYPE_PCI1735 },
637 { PCI_VDEVICE(ADVANTECH, 0x1736), TYPE_PCI1736 },
638 { PCI_VDEVICE(ADVANTECH, 0x1739), TYPE_PCI1739 },
639 { PCI_VDEVICE(ADVANTECH, 0x1750), TYPE_PCI1750 },
640 { PCI_VDEVICE(ADVANTECH, 0x1751), TYPE_PCI1751 },
641 { PCI_VDEVICE(ADVANTECH, 0x1752), TYPE_PCI1752 },
642 { PCI_VDEVICE(ADVANTECH, 0x1753), TYPE_PCI1753 },
643 { PCI_VDEVICE(ADVANTECH, 0x1754), TYPE_PCI1754 },
644 { PCI_VDEVICE(ADVANTECH, 0x1756), TYPE_PCI1756 },
645 { PCI_VDEVICE(ADVANTECH, 0x1762), TYPE_PCI1762 },
646 { 0 }
647 };
648 MODULE_DEVICE_TABLE(pci, adv_pci_dio_pci_table);
649
650 static struct pci_driver adv_pci_dio_pci_driver = {
651 .name = "adv_pci_dio",
652 .id_table = adv_pci_dio_pci_table,
653 .probe = adv_pci_dio_pci_probe,
654 .remove = comedi_pci_auto_unconfig,
655 };
656 module_comedi_pci_driver(adv_pci_dio_driver, adv_pci_dio_pci_driver);
657
658 MODULE_AUTHOR("Comedi http://www.comedi.org");
659 MODULE_DESCRIPTION("Comedi low-level driver");
660 MODULE_LICENSE("GPL");
This page took 0.043536 seconds and 5 git commands to generate.