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