staging: comedi: adl_pci9111: cleanup pci9111_di_insn_bits()
[pandora-kernel.git] / drivers / staging / comedi / drivers / adl_pci9111.c
1 /*
2
3 comedi/drivers/adl_pci9111.c
4
5 Hardware driver for PCI9111 ADLink cards:
6
7 PCI-9111HR
8
9 Copyright (C) 2002-2005 Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26 /*
27 Driver: adl_pci9111
28 Description: Adlink PCI-9111HR
29 Author: Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr>
30 Devices: [ADLink] PCI-9111HR (adl_pci9111)
31 Status: experimental
32
33 Supports:
34
35         - ai_insn read
36         - ao_insn read/write
37         - di_insn read
38         - do_insn read/write
39         - ai_do_cmd mode with the following sources:
40
41         - start_src             TRIG_NOW
42         - scan_begin_src        TRIG_FOLLOW     TRIG_TIMER      TRIG_EXT
43         - convert_src                           TRIG_TIMER      TRIG_EXT
44         - scan_end_src          TRIG_COUNT
45         - stop_src              TRIG_COUNT      TRIG_NONE
46
47 The scanned channels must be consecutive and start from 0. They must
48 all have the same range and aref.
49
50 Configuration options:
51
52         [0] - PCI bus number (optional)
53         [1] - PCI slot number (optional)
54
55 If bus/slot is not specified, the first available PCI
56 device will be used.
57
58 */
59
60 /*
61 CHANGELOG:
62
63 2005/02/17 Extend AI streaming capabilities. Now, scan_begin_arg can be
64 a multiple of chanlist_len*convert_arg.
65 2002/02/19 Fixed the two's complement conversion in pci9111_(hr_)ai_get_data.
66 2002/02/18 Added external trigger support for analog input.
67
68 TODO:
69
70         - Really test implemented functionality.
71         - Add support for the PCI-9111DG with a probe routine to identify
72           the card type (perhaps with the help of the channel number readback
73           of the A/D Data register).
74         - Add external multiplexer support.
75
76 */
77
78 #include "../comedidev.h"
79
80 #include <linux/delay.h>
81 #include <linux/interrupt.h>
82
83 #include "8253.h"
84 #include "comedi_fc.h"
85
86 #define PCI9111_DRIVER_NAME     "adl_pci9111"
87 #define PCI9111_HR_DEVICE_ID    0x9111
88
89 /*  TODO: Add other pci9111 board id */
90
91 #define PCI9111_IO_RANGE        0x0100
92
93 #define PCI9111_FIFO_HALF_SIZE  512
94
95 #define PCI9111_AI_CHANNEL_NBR                  16
96
97 #define PCI9111_AI_RESOLUTION                   12
98 #define PCI9111_AI_RESOLUTION_MASK              0x0FFF
99 #define PCI9111_AI_RESOLUTION_2_CMP_BIT         0x0800
100
101 #define PCI9111_HR_AI_RESOLUTION                16
102 #define PCI9111_HR_AI_RESOLUTION_MASK           0xFFFF
103 #define PCI9111_HR_AI_RESOLUTION_2_CMP_BIT      0x8000
104
105 #define PCI9111_AI_ACQUISITION_PERIOD_MIN_NS    10000
106 #define PCI9111_AO_CHANNEL_NBR                  1
107 #define PCI9111_AO_RESOLUTION                   12
108 #define PCI9111_AO_RESOLUTION_MASK              0x0FFF
109 #define PCI9111_DI_CHANNEL_NBR                  16
110 #define PCI9111_DO_CHANNEL_NBR                  16
111 #define PCI9111_DO_MASK                         0xFFFF
112
113 #define PCI9111_RANGE_SETTING_DELAY             10
114 #define PCI9111_AI_INSTANT_READ_UDELAY_US       2
115 #define PCI9111_AI_INSTANT_READ_TIMEOUT         100
116
117 #define PCI9111_8254_CLOCK_PERIOD_NS            500
118
119 /* IO address map */
120
121 #define PCI9111_REGISTER_AD_FIFO_VALUE                  0x00 /* AD Data stored
122                                                                 in FIFO */
123 #define PCI9111_REGISTER_DA_OUTPUT                      0x00
124 #define PCI9111_DIO_REG                                 0x02
125 #define PCI9111_REGISTER_EXTENDED_IO_PORTS              0x04
126 #define PCI9111_REGISTER_AD_CHANNEL_CONTROL             0x06 /* Channel
127                                                                 selection */
128 #define PCI9111_REGISTER_AD_CHANNEL_READBACK            0x06
129 #define PCI9111_REGISTER_INPUT_SIGNAL_RANGE             0x08
130 #define PCI9111_REGISTER_RANGE_STATUS_READBACK          0x08
131 #define PCI9111_REGISTER_TRIGGER_MODE_CONTROL           0x0A
132 #define PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK     0x0A
133 #define PCI9111_REGISTER_SOFTWARE_TRIGGER               0x0E
134 #define PCI9111_REGISTER_INTERRUPT_CONTROL              0x0C
135 #define PCI9111_8254_BASE_REG                           0x40
136 #define PCI9111_REGISTER_INTERRUPT_CLEAR                0x48
137
138 #define PCI9111_TRIGGER_MASK                            0x0F
139 #define PCI9111_PTRG_OFF                                (0 << 3)
140 #define PCI9111_PTRG_ON                                 (1 << 3)
141 #define PCI9111_EITS_EXTERNAL                           (1 << 2)
142 #define PCI9111_EITS_INTERNAL                           (0 << 2)
143 #define PCI9111_TPST_SOFTWARE_TRIGGER                   (0 << 1)
144 #define PCI9111_TPST_TIMER_PACER                        (1 << 1)
145 #define PCI9111_ASCAN_ON                                (1 << 0)
146 #define PCI9111_ASCAN_OFF                               (0 << 0)
147
148 #define PCI9111_ISC0_SET_IRQ_ON_ENDING_OF_AD_CONVERSION (0 << 0)
149 #define PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL          (1 << 0)
150 #define PCI9111_ISC1_SET_IRQ_ON_TIMER_TICK              (0 << 1)
151 #define PCI9111_ISC1_SET_IRQ_ON_EXT_TRG                 (1 << 1)
152 #define PCI9111_FFEN_SET_FIFO_ENABLE                    (0 << 2)
153 #define PCI9111_FFEN_SET_FIFO_DISABLE                   (1 << 2)
154
155 #define PCI9111_CHANNEL_MASK                            0x0F
156
157 #define PCI9111_RANGE_MASK                              0x07
158 #define PCI9111_FIFO_EMPTY_MASK                         0x10
159 #define PCI9111_FIFO_HALF_FULL_MASK                     0x20
160 #define PCI9111_FIFO_FULL_MASK                          0x40
161 #define PCI9111_AD_BUSY_MASK                            0x80
162
163 /*
164  * Define inlined function
165  */
166
167 #define pci9111_trigger_and_autoscan_get() \
168         (inb(dev->iobase + PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK)&0x0F)
169
170 #define pci9111_trigger_and_autoscan_set(flags) \
171         outb(flags, dev->iobase + PCI9111_REGISTER_TRIGGER_MODE_CONTROL)
172
173 #define pci9111_interrupt_and_fifo_get() \
174         ((inb(dev->iobase + PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK) \
175                 >> 4) & 0x03)
176
177 #define pci9111_interrupt_and_fifo_set(flags) \
178         outb(flags, dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL)
179
180 #define pci9111_interrupt_clear() \
181         outb(0, dev->iobase + PCI9111_REGISTER_INTERRUPT_CLEAR)
182
183 #define pci9111_software_trigger() \
184         outb(0, dev->iobase + PCI9111_REGISTER_SOFTWARE_TRIGGER)
185
186 #define pci9111_fifo_reset() do { \
187         outb(PCI9111_FFEN_SET_FIFO_ENABLE, \
188                 dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL); \
189         outb(PCI9111_FFEN_SET_FIFO_DISABLE, \
190                 dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL); \
191         outb(PCI9111_FFEN_SET_FIFO_ENABLE, \
192                 dev->iobase + PCI9111_REGISTER_INTERRUPT_CONTROL); \
193         } while (0)
194
195 #define pci9111_is_fifo_full() \
196         ((inb(dev->iobase + PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
197                 PCI9111_FIFO_FULL_MASK) == 0)
198
199 #define pci9111_is_fifo_half_full() \
200         ((inb(dev->iobase + PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
201                 PCI9111_FIFO_HALF_FULL_MASK) == 0)
202
203 #define pci9111_is_fifo_empty() \
204         ((inb(dev->iobase + PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
205                 PCI9111_FIFO_EMPTY_MASK) == 0)
206
207 #define pci9111_ai_channel_set(channel) \
208         outb((channel)&PCI9111_CHANNEL_MASK, \
209                 dev->iobase + PCI9111_REGISTER_AD_CHANNEL_CONTROL)
210
211 #define pci9111_ai_channel_get() \
212         (inb(dev->iobase + PCI9111_REGISTER_AD_CHANNEL_READBACK) \
213                 &PCI9111_CHANNEL_MASK)
214
215 #define pci9111_ai_range_set(range) \
216         outb((range)&PCI9111_RANGE_MASK, \
217                 dev->iobase + PCI9111_REGISTER_INPUT_SIGNAL_RANGE)
218
219 #define pci9111_ai_range_get() \
220         (inb(dev->iobase + PCI9111_REGISTER_RANGE_STATUS_READBACK) \
221                 &PCI9111_RANGE_MASK)
222
223 #define pci9111_ai_get_data() \
224         (((inw(dev->iobase + PCI9111_REGISTER_AD_FIFO_VALUE)>>4) \
225                 &PCI9111_AI_RESOLUTION_MASK) \
226                         ^ PCI9111_AI_RESOLUTION_2_CMP_BIT)
227
228 #define pci9111_hr_ai_get_data() \
229         ((inw(dev->iobase + PCI9111_REGISTER_AD_FIFO_VALUE) \
230                 &PCI9111_HR_AI_RESOLUTION_MASK) \
231                         ^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT)
232
233 #define pci9111_ao_set_data(data) \
234         outw(data&PCI9111_AO_RESOLUTION_MASK, \
235                 dev->iobase + PCI9111_REGISTER_DA_OUTPUT)
236
237
238 static const struct comedi_lrange pci9111_hr_ai_range = {
239         5,
240         {
241          BIP_RANGE(10),
242          BIP_RANGE(5),
243          BIP_RANGE(2.5),
244          BIP_RANGE(1.25),
245          BIP_RANGE(0.625)
246          }
247 };
248
249 /*  */
250 /*  Board specification structure */
251 /*  */
252
253 struct pci9111_board {
254         const char *name;       /*  driver name */
255         int device_id;
256         int ai_channel_nbr;     /*  num of A/D chans */
257         int ao_channel_nbr;     /*  num of D/A chans */
258         int ai_resolution;      /*  resolution of A/D */
259         int ai_resolution_mask;
260         int ao_resolution;      /*  resolution of D/A */
261         int ao_resolution_mask;
262         const struct comedi_lrange *ai_range_list;      /*  rangelist for A/D */
263         const struct comedi_lrange *ao_range_list;      /*  rangelist for D/A */
264         unsigned int ai_acquisition_period_min_ns;
265 };
266
267 static const struct pci9111_board pci9111_boards[] = {
268         {
269          .name = "pci9111_hr",
270          .device_id = PCI9111_HR_DEVICE_ID,
271          .ai_channel_nbr = PCI9111_AI_CHANNEL_NBR,
272          .ao_channel_nbr = PCI9111_AO_CHANNEL_NBR,
273          .ai_resolution = PCI9111_HR_AI_RESOLUTION,
274          .ai_resolution_mask = PCI9111_HR_AI_RESOLUTION_MASK,
275          .ao_resolution = PCI9111_AO_RESOLUTION,
276          .ao_resolution_mask = PCI9111_AO_RESOLUTION_MASK,
277          .ai_range_list = &pci9111_hr_ai_range,
278          .ao_range_list = &range_bipolar10,
279          .ai_acquisition_period_min_ns = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS}
280 };
281
282 /*  Private data structure */
283
284 struct pci9111_private_data {
285         unsigned long io_range; /*  PCI6503 io range */
286
287         unsigned long lcr_io_base; /* Local configuration register base
288                                     * address */
289         unsigned long lcr_io_range;
290
291         int stop_counter;
292         int stop_is_none;
293
294         unsigned int scan_delay;
295         unsigned int chanlist_len;
296         unsigned int chunk_counter;
297         unsigned int chunk_num_samples;
298
299         int ao_readback;        /*  Last written analog output data */
300
301         unsigned int timer_divisor_1; /* Divisor values for the 8254 timer
302                                        * pacer */
303         unsigned int timer_divisor_2;
304
305         int is_valid;           /*  Is device valid */
306
307         short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE];
308 };
309
310 /*  ------------------------------------------------------------------ */
311 /*  PLX9050 SECTION */
312 /*  ------------------------------------------------------------------ */
313
314 #define PLX9050_REGISTER_INTERRUPT_CONTROL 0x4c
315
316 #define PLX9050_LINTI1_ENABLE           (1 << 0)
317 #define PLX9050_LINTI1_ACTIVE_HIGH      (1 << 1)
318 #define PLX9050_LINTI1_STATUS           (1 << 2)
319 #define PLX9050_LINTI2_ENABLE           (1 << 3)
320 #define PLX9050_LINTI2_ACTIVE_HIGH      (1 << 4)
321 #define PLX9050_LINTI2_STATUS           (1 << 5)
322 #define PLX9050_PCI_INTERRUPT_ENABLE    (1 << 6)
323 #define PLX9050_SOFTWARE_INTERRUPT      (1 << 7)
324
325 static void plx9050_interrupt_control(unsigned long io_base,
326                                       bool LINTi1_enable,
327                                       bool LINTi1_active_high,
328                                       bool LINTi2_enable,
329                                       bool LINTi2_active_high,
330                                       bool interrupt_enable)
331 {
332         int flags = 0;
333
334         if (LINTi1_enable)
335                 flags |= PLX9050_LINTI1_ENABLE;
336         if (LINTi1_active_high)
337                 flags |= PLX9050_LINTI1_ACTIVE_HIGH;
338         if (LINTi2_enable)
339                 flags |= PLX9050_LINTI2_ENABLE;
340         if (LINTi2_active_high)
341                 flags |= PLX9050_LINTI2_ACTIVE_HIGH;
342
343         if (interrupt_enable)
344                 flags |= PLX9050_PCI_INTERRUPT_ENABLE;
345
346         outb(flags, io_base + PLX9050_REGISTER_INTERRUPT_CONTROL);
347 }
348
349 /*  ------------------------------------------------------------------ */
350 /*  MISCELLANEOUS SECTION */
351 /*  ------------------------------------------------------------------ */
352
353 /*  8254 timer */
354
355 static void pci9111_timer_set(struct comedi_device *dev)
356 {
357         struct pci9111_private_data *dev_private = dev->private;
358         unsigned long timer_base = dev->iobase + PCI9111_8254_BASE_REG;
359
360         i8254_set_mode(timer_base, 1, 0, I8254_MODE0 | I8254_BINARY);
361         i8254_set_mode(timer_base, 1, 1, I8254_MODE2 | I8254_BINARY);
362         i8254_set_mode(timer_base, 1, 2, I8254_MODE2 | I8254_BINARY);
363
364         udelay(1);
365
366         i8254_write(timer_base, 1, 2, dev_private->timer_divisor_2);
367         i8254_write(timer_base, 1, 1, dev_private->timer_divisor_1);
368 }
369
370 enum pci9111_trigger_sources {
371         software,
372         timer_pacer,
373         external
374 };
375
376 static void pci9111_trigger_source_set(struct comedi_device *dev,
377                                        enum pci9111_trigger_sources source)
378 {
379         int flags;
380
381         flags = pci9111_trigger_and_autoscan_get() & 0x09;
382
383         switch (source) {
384         case software:
385                 flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_SOFTWARE_TRIGGER;
386                 break;
387
388         case timer_pacer:
389                 flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_TIMER_PACER;
390                 break;
391
392         case external:
393                 flags |= PCI9111_EITS_EXTERNAL;
394                 break;
395         }
396
397         pci9111_trigger_and_autoscan_set(flags);
398 }
399
400 static void pci9111_pretrigger_set(struct comedi_device *dev, bool pretrigger)
401 {
402         int flags;
403
404         flags = pci9111_trigger_and_autoscan_get() & 0x07;
405
406         if (pretrigger)
407                 flags |= PCI9111_PTRG_ON;
408
409         pci9111_trigger_and_autoscan_set(flags);
410 }
411
412 static void pci9111_autoscan_set(struct comedi_device *dev, bool autoscan)
413 {
414         int flags;
415
416         flags = pci9111_trigger_and_autoscan_get() & 0x0e;
417
418         if (autoscan)
419                 flags |= PCI9111_ASCAN_ON;
420
421         pci9111_trigger_and_autoscan_set(flags);
422 }
423
424 enum pci9111_ISC0_sources {
425         irq_on_eoc,
426         irq_on_fifo_half_full
427 };
428
429 enum pci9111_ISC1_sources {
430         irq_on_timer_tick,
431         irq_on_external_trigger
432 };
433
434 static void pci9111_interrupt_source_set(struct comedi_device *dev,
435                                          enum pci9111_ISC0_sources irq_0_source,
436                                          enum pci9111_ISC1_sources irq_1_source)
437 {
438         int flags;
439
440         flags = pci9111_interrupt_and_fifo_get() & 0x04;
441
442         if (irq_0_source == irq_on_fifo_half_full)
443                 flags |= PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL;
444
445         if (irq_1_source == irq_on_external_trigger)
446                 flags |= PCI9111_ISC1_SET_IRQ_ON_EXT_TRG;
447
448         pci9111_interrupt_and_fifo_set(flags);
449 }
450
451 /*  ------------------------------------------------------------------ */
452 /*  HARDWARE TRIGGERED ANALOG INPUT SECTION */
453 /*  ------------------------------------------------------------------ */
454
455 /*  Cancel analog input autoscan */
456
457 #undef AI_DO_CMD_DEBUG
458
459 static int pci9111_ai_cancel(struct comedi_device *dev,
460                              struct comedi_subdevice *s)
461 {
462         struct pci9111_private_data *dev_private = dev->private;
463
464         /*  Disable interrupts */
465
466         plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
467                                   true, false);
468
469         pci9111_trigger_source_set(dev, software);
470
471         pci9111_autoscan_set(dev, false);
472
473         pci9111_fifo_reset();
474
475 #ifdef AI_DO_CMD_DEBUG
476         printk(PCI9111_DRIVER_NAME ": ai_cancel\n");
477 #endif
478
479         return 0;
480 }
481
482 /*  Test analog input command */
483
484 #define pci9111_check_trigger_src(src, flags)   do {                    \
485                 tmp = src;                                              \
486                 src &= flags;                                           \
487                 if (!src || tmp != src)                                 \
488                         error++;                                        \
489         } while (false);
490
491 static int
492 pci9111_ai_do_cmd_test(struct comedi_device *dev,
493                        struct comedi_subdevice *s, struct comedi_cmd *cmd)
494 {
495         struct pci9111_private_data *dev_private = dev->private;
496         int tmp;
497         int error = 0;
498         int range, reference;
499         int i;
500         struct pci9111_board *board = (struct pci9111_board *)dev->board_ptr;
501
502         /*  Step 1 : check if trigger are trivialy valid */
503
504         pci9111_check_trigger_src(cmd->start_src, TRIG_NOW);
505         pci9111_check_trigger_src(cmd->scan_begin_src,
506                                   TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT);
507         pci9111_check_trigger_src(cmd->convert_src, TRIG_TIMER | TRIG_EXT);
508         pci9111_check_trigger_src(cmd->scan_end_src, TRIG_COUNT);
509         pci9111_check_trigger_src(cmd->stop_src, TRIG_COUNT | TRIG_NONE);
510
511         if (error)
512                 return 1;
513
514         /*  step 2 : make sure trigger sources are unique and mutually
515          *  compatible */
516
517         if (cmd->start_src != TRIG_NOW)
518                 error++;
519
520         if ((cmd->scan_begin_src != TRIG_TIMER) &&
521             (cmd->scan_begin_src != TRIG_FOLLOW) &&
522             (cmd->scan_begin_src != TRIG_EXT))
523                 error++;
524
525         if ((cmd->convert_src != TRIG_TIMER) && (cmd->convert_src != TRIG_EXT))
526                 error++;
527         if ((cmd->convert_src == TRIG_TIMER) &&
528             !((cmd->scan_begin_src == TRIG_TIMER) ||
529               (cmd->scan_begin_src == TRIG_FOLLOW)))
530                 error++;
531         if ((cmd->convert_src == TRIG_EXT) &&
532             !((cmd->scan_begin_src == TRIG_EXT) ||
533               (cmd->scan_begin_src == TRIG_FOLLOW)))
534                 error++;
535
536
537         if (cmd->scan_end_src != TRIG_COUNT)
538                 error++;
539         if ((cmd->stop_src != TRIG_COUNT) && (cmd->stop_src != TRIG_NONE))
540                 error++;
541
542         if (error)
543                 return 2;
544
545         /*  Step 3 : make sure arguments are trivialy compatible */
546
547         if (cmd->chanlist_len < 1) {
548                 cmd->chanlist_len = 1;
549                 error++;
550         }
551
552         if (cmd->chanlist_len > board->ai_channel_nbr) {
553                 cmd->chanlist_len = board->ai_channel_nbr;
554                 error++;
555         }
556
557         if ((cmd->start_src == TRIG_NOW) && (cmd->start_arg != 0)) {
558                 cmd->start_arg = 0;
559                 error++;
560         }
561
562         if ((cmd->convert_src == TRIG_TIMER) &&
563             (cmd->convert_arg < board->ai_acquisition_period_min_ns)) {
564                 cmd->convert_arg = board->ai_acquisition_period_min_ns;
565                 error++;
566         }
567         if ((cmd->convert_src == TRIG_EXT) && (cmd->convert_arg != 0)) {
568                 cmd->convert_arg = 0;
569                 error++;
570         }
571
572         if ((cmd->scan_begin_src == TRIG_TIMER) &&
573             (cmd->scan_begin_arg < board->ai_acquisition_period_min_ns)) {
574                 cmd->scan_begin_arg = board->ai_acquisition_period_min_ns;
575                 error++;
576         }
577         if ((cmd->scan_begin_src == TRIG_FOLLOW)
578             && (cmd->scan_begin_arg != 0)) {
579                 cmd->scan_begin_arg = 0;
580                 error++;
581         }
582         if ((cmd->scan_begin_src == TRIG_EXT) && (cmd->scan_begin_arg != 0)) {
583                 cmd->scan_begin_arg = 0;
584                 error++;
585         }
586
587         if ((cmd->scan_end_src == TRIG_COUNT) &&
588             (cmd->scan_end_arg != cmd->chanlist_len)) {
589                 cmd->scan_end_arg = cmd->chanlist_len;
590                 error++;
591         }
592
593         if ((cmd->stop_src == TRIG_COUNT) && (cmd->stop_arg < 1)) {
594                 cmd->stop_arg = 1;
595                 error++;
596         }
597         if ((cmd->stop_src == TRIG_NONE) && (cmd->stop_arg != 0)) {
598                 cmd->stop_arg = 0;
599                 error++;
600         }
601
602         if (error)
603                 return 3;
604
605         /*  Step 4 : fix up any arguments */
606
607         if (cmd->convert_src == TRIG_TIMER) {
608                 tmp = cmd->convert_arg;
609                 i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS,
610                                                &(dev_private->timer_divisor_1),
611                                                &(dev_private->timer_divisor_2),
612                                                &(cmd->convert_arg),
613                                                cmd->flags & TRIG_ROUND_MASK);
614                 if (tmp != cmd->convert_arg)
615                         error++;
616         }
617         /*  There's only one timer on this card, so the scan_begin timer must */
618         /*  be a multiple of chanlist_len*convert_arg */
619
620         if (cmd->scan_begin_src == TRIG_TIMER) {
621
622                 unsigned int scan_begin_min;
623                 unsigned int scan_begin_arg;
624                 unsigned int scan_factor;
625
626                 scan_begin_min = cmd->chanlist_len * cmd->convert_arg;
627
628                 if (cmd->scan_begin_arg != scan_begin_min) {
629                         if (scan_begin_min < cmd->scan_begin_arg) {
630                                 scan_factor =
631                                     cmd->scan_begin_arg / scan_begin_min;
632                                 scan_begin_arg = scan_factor * scan_begin_min;
633                                 if (cmd->scan_begin_arg != scan_begin_arg) {
634                                         cmd->scan_begin_arg = scan_begin_arg;
635                                         error++;
636                                 }
637                         } else {
638                                 cmd->scan_begin_arg = scan_begin_min;
639                                 error++;
640                         }
641                 }
642         }
643
644         if (error)
645                 return 4;
646
647         /*  Step 5 : check channel list */
648
649         if (cmd->chanlist) {
650
651                 range = CR_RANGE(cmd->chanlist[0]);
652                 reference = CR_AREF(cmd->chanlist[0]);
653
654                 if (cmd->chanlist_len > 1) {
655                         for (i = 0; i < cmd->chanlist_len; i++) {
656                                 if (CR_CHAN(cmd->chanlist[i]) != i) {
657                                         comedi_error(dev,
658                                                      "entries in chanlist must be consecutive "
659                                                      "channels,counting upwards from 0\n");
660                                         error++;
661                                 }
662                                 if (CR_RANGE(cmd->chanlist[i]) != range) {
663                                         comedi_error(dev,
664                                                      "entries in chanlist must all have the same gain\n");
665                                         error++;
666                                 }
667                                 if (CR_AREF(cmd->chanlist[i]) != reference) {
668                                         comedi_error(dev,
669                                                      "entries in chanlist must all have the same reference\n");
670                                         error++;
671                                 }
672                         }
673                 } else {
674                         if ((CR_CHAN(cmd->chanlist[0]) >
675                              (board->ai_channel_nbr - 1))
676                             || (CR_CHAN(cmd->chanlist[0]) < 0)) {
677                                 comedi_error(dev,
678                                              "channel number is out of limits\n");
679                                 error++;
680                         }
681                 }
682         }
683
684         if (error)
685                 return 5;
686
687         return 0;
688
689 }
690
691 /*  Analog input command */
692
693 static int pci9111_ai_do_cmd(struct comedi_device *dev,
694                              struct comedi_subdevice *s)
695 {
696         struct pci9111_private_data *dev_private = dev->private;
697         struct comedi_cmd *async_cmd = &s->async->cmd;
698
699         if (!dev->irq) {
700                 comedi_error(dev,
701                              "no irq assigned for PCI9111, cannot do hardware conversion");
702                 return -1;
703         }
704         /*  Set channel scan limit */
705         /*  PCI9111 allows only scanning from channel 0 to channel n */
706         /*  TODO: handle the case of an external multiplexer */
707
708         if (async_cmd->chanlist_len > 1) {
709                 pci9111_ai_channel_set((async_cmd->chanlist_len) - 1);
710                 pci9111_autoscan_set(dev, true);
711         } else {
712                 pci9111_ai_channel_set(CR_CHAN(async_cmd->chanlist[0]));
713                 pci9111_autoscan_set(dev, false);
714         }
715
716         /*  Set gain */
717         /*  This is the same gain on every channel */
718
719         pci9111_ai_range_set(CR_RANGE(async_cmd->chanlist[0]));
720
721         /* Set counter */
722
723         switch (async_cmd->stop_src) {
724         case TRIG_COUNT:
725                 dev_private->stop_counter =
726                     async_cmd->stop_arg * async_cmd->chanlist_len;
727                 dev_private->stop_is_none = 0;
728                 break;
729
730         case TRIG_NONE:
731                 dev_private->stop_counter = 0;
732                 dev_private->stop_is_none = 1;
733                 break;
734
735         default:
736                 comedi_error(dev, "Invalid stop trigger");
737                 return -1;
738         }
739
740         /*  Set timer pacer */
741
742         dev_private->scan_delay = 0;
743         switch (async_cmd->convert_src) {
744         case TRIG_TIMER:
745                 i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS,
746                                                &(dev_private->timer_divisor_1),
747                                                &(dev_private->timer_divisor_2),
748                                                &(async_cmd->convert_arg),
749                                                async_cmd->
750                                                flags & TRIG_ROUND_MASK);
751 #ifdef AI_DO_CMD_DEBUG
752                 printk(PCI9111_DRIVER_NAME ": divisors = %d, %d\n",
753                        dev_private->timer_divisor_1,
754                        dev_private->timer_divisor_2);
755 #endif
756
757                 pci9111_trigger_source_set(dev, software);
758                 pci9111_timer_set(dev);
759                 pci9111_fifo_reset();
760                 pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
761                                              irq_on_timer_tick);
762                 pci9111_trigger_source_set(dev, timer_pacer);
763                 plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
764                                           false, true, true);
765
766                 if (async_cmd->scan_begin_src == TRIG_TIMER) {
767                         dev_private->scan_delay =
768                                 (async_cmd->scan_begin_arg /
769                                  (async_cmd->convert_arg *
770                                   async_cmd->chanlist_len)) - 1;
771                 }
772
773                 break;
774
775         case TRIG_EXT:
776
777                 pci9111_trigger_source_set(dev, external);
778                 pci9111_fifo_reset();
779                 pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
780                                              irq_on_timer_tick);
781                 plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
782                                           false, true, true);
783
784                 break;
785
786         default:
787                 comedi_error(dev, "Invalid convert trigger");
788                 return -1;
789         }
790
791         dev_private->stop_counter *= (1 + dev_private->scan_delay);
792         dev_private->chanlist_len = async_cmd->chanlist_len;
793         dev_private->chunk_counter = 0;
794         dev_private->chunk_num_samples =
795             dev_private->chanlist_len * (1 + dev_private->scan_delay);
796
797 #ifdef AI_DO_CMD_DEBUG
798         printk(PCI9111_DRIVER_NAME ": start interruptions!\n");
799         printk(PCI9111_DRIVER_NAME ": trigger source = %2x\n",
800                pci9111_trigger_and_autoscan_get());
801         printk(PCI9111_DRIVER_NAME ": irq source     = %2x\n",
802                pci9111_interrupt_and_fifo_get());
803         printk(PCI9111_DRIVER_NAME ": ai_do_cmd\n");
804         printk(PCI9111_DRIVER_NAME ": stop counter   = %d\n",
805                dev_private->stop_counter);
806         printk(PCI9111_DRIVER_NAME ": scan delay     = %d\n",
807                dev_private->scan_delay);
808         printk(PCI9111_DRIVER_NAME ": chanlist_len   = %d\n",
809                dev_private->chanlist_len);
810         printk(PCI9111_DRIVER_NAME ": chunk num samples = %d\n",
811                dev_private->chunk_num_samples);
812 #endif
813
814         return 0;
815 }
816
817 static void pci9111_ai_munge(struct comedi_device *dev,
818                              struct comedi_subdevice *s, void *data,
819                              unsigned int num_bytes,
820                              unsigned int start_chan_index)
821 {
822         unsigned int i, num_samples = num_bytes / sizeof(short);
823         short *array = data;
824         int resolution =
825             ((struct pci9111_board *)dev->board_ptr)->ai_resolution;
826
827         for (i = 0; i < num_samples; i++) {
828                 if (resolution == PCI9111_HR_AI_RESOLUTION)
829                         array[i] =
830                             (array[i] & PCI9111_HR_AI_RESOLUTION_MASK) ^
831                             PCI9111_HR_AI_RESOLUTION_2_CMP_BIT;
832                 else
833                         array[i] =
834                             ((array[i] >> 4) & PCI9111_AI_RESOLUTION_MASK) ^
835                             PCI9111_AI_RESOLUTION_2_CMP_BIT;
836         }
837 }
838
839 /*  ------------------------------------------------------------------ */
840 /*  INTERRUPT SECTION */
841 /*  ------------------------------------------------------------------ */
842
843 #undef INTERRUPT_DEBUG
844
845 static irqreturn_t pci9111_interrupt(int irq, void *p_device)
846 {
847         struct comedi_device *dev = p_device;
848         struct pci9111_private_data *dev_private = dev->private;
849         struct comedi_subdevice *s = dev->read_subdev;
850         struct comedi_async *async;
851         unsigned long irq_flags;
852         unsigned char intcsr;
853
854         if (!dev->attached) {
855                 /*  Ignore interrupt before device fully attached. */
856                 /*  Might not even have allocated subdevices yet! */
857                 return IRQ_NONE;
858         }
859
860         async = s->async;
861
862         spin_lock_irqsave(&dev->spinlock, irq_flags);
863
864         /*  Check if we are source of interrupt */
865         intcsr = inb(dev_private->lcr_io_base +
866                      PLX9050_REGISTER_INTERRUPT_CONTROL);
867         if (!(((intcsr & PLX9050_PCI_INTERRUPT_ENABLE) != 0)
868               && (((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS))
869                    == (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS))
870                   || ((intcsr & (PLX9050_LINTI2_ENABLE | PLX9050_LINTI2_STATUS))
871                       == (PLX9050_LINTI2_ENABLE | PLX9050_LINTI2_STATUS))))) {
872                 /*  Not the source of the interrupt. */
873                 /*  (N.B. not using PLX9050_SOFTWARE_INTERRUPT) */
874                 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
875                 return IRQ_NONE;
876         }
877
878         if ((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) ==
879             (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) {
880                 /*  Interrupt comes from fifo_half-full signal */
881
882                 if (pci9111_is_fifo_full()) {
883                         spin_unlock_irqrestore(&dev->spinlock, irq_flags);
884                         comedi_error(dev, PCI9111_DRIVER_NAME " fifo overflow");
885                         pci9111_interrupt_clear();
886                         pci9111_ai_cancel(dev, s);
887                         async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
888                         comedi_event(dev, s);
889
890                         return IRQ_HANDLED;
891                 }
892
893                 if (pci9111_is_fifo_half_full()) {
894                         unsigned int num_samples;
895                         unsigned int bytes_written = 0;
896
897 #ifdef INTERRUPT_DEBUG
898                         printk(PCI9111_DRIVER_NAME ": fifo is half full\n");
899 #endif
900
901                         num_samples =
902                             PCI9111_FIFO_HALF_SIZE >
903                             dev_private->stop_counter
904                             && !dev_private->
905                             stop_is_none ? dev_private->stop_counter :
906                             PCI9111_FIFO_HALF_SIZE;
907                         insw(dev->iobase + PCI9111_REGISTER_AD_FIFO_VALUE,
908                              dev_private->ai_bounce_buffer, num_samples);
909
910                         if (dev_private->scan_delay < 1) {
911                                 bytes_written =
912                                     cfc_write_array_to_buffer(s,
913                                                               dev_private->
914                                                               ai_bounce_buffer,
915                                                               num_samples *
916                                                               sizeof(short));
917                         } else {
918                                 int position = 0;
919                                 int to_read;
920
921                                 while (position < num_samples) {
922                                         if (dev_private->chunk_counter <
923                                             dev_private->chanlist_len) {
924                                                 to_read =
925                                                     dev_private->chanlist_len -
926                                                     dev_private->chunk_counter;
927
928                                                 if (to_read >
929                                                     num_samples - position)
930                                                         to_read =
931                                                             num_samples -
932                                                             position;
933
934                                                 bytes_written +=
935                                                     cfc_write_array_to_buffer
936                                                     (s,
937                                                      dev_private->ai_bounce_buffer
938                                                      + position,
939                                                      to_read * sizeof(short));
940                                         } else {
941                                                 to_read =
942                                                     dev_private->chunk_num_samples
943                                                     -
944                                                     dev_private->chunk_counter;
945                                                 if (to_read >
946                                                     num_samples - position)
947                                                         to_read =
948                                                             num_samples -
949                                                             position;
950
951                                                 bytes_written +=
952                                                     sizeof(short) * to_read;
953                                         }
954
955                                         position += to_read;
956                                         dev_private->chunk_counter += to_read;
957
958                                         if (dev_private->chunk_counter >=
959                                             dev_private->chunk_num_samples)
960                                                 dev_private->chunk_counter = 0;
961                                 }
962                         }
963
964                         dev_private->stop_counter -=
965                             bytes_written / sizeof(short);
966                 }
967         }
968
969         if ((dev_private->stop_counter == 0) && (!dev_private->stop_is_none)) {
970                 async->events |= COMEDI_CB_EOA;
971                 pci9111_ai_cancel(dev, s);
972         }
973
974         /* Very important, otherwise another interrupt request will be inserted
975          * and will cause driver hangs on processing interrupt event. */
976
977         pci9111_interrupt_clear();
978
979         spin_unlock_irqrestore(&dev->spinlock, irq_flags);
980
981         comedi_event(dev, s);
982
983         return IRQ_HANDLED;
984 }
985
986 /*  ------------------------------------------------------------------ */
987 /*  INSTANT ANALOG INPUT OUTPUT SECTION */
988 /*  ------------------------------------------------------------------ */
989
990 /*  analog instant input */
991
992 #undef AI_INSN_DEBUG
993
994 static int pci9111_ai_insn_read(struct comedi_device *dev,
995                                 struct comedi_subdevice *s,
996                                 struct comedi_insn *insn, unsigned int *data)
997 {
998         int resolution =
999             ((struct pci9111_board *)dev->board_ptr)->ai_resolution;
1000
1001         int timeout, i;
1002
1003 #ifdef AI_INSN_DEBUG
1004         printk(PCI9111_DRIVER_NAME ": ai_insn set c/r/n = %2x/%2x/%2x\n",
1005                CR_CHAN((&insn->chanspec)[0]),
1006                CR_RANGE((&insn->chanspec)[0]), insn->n);
1007 #endif
1008
1009         pci9111_ai_channel_set(CR_CHAN((&insn->chanspec)[0]));
1010
1011         if ((pci9111_ai_range_get()) != CR_RANGE((&insn->chanspec)[0]))
1012                 pci9111_ai_range_set(CR_RANGE((&insn->chanspec)[0]));
1013
1014         pci9111_fifo_reset();
1015
1016         for (i = 0; i < insn->n; i++) {
1017                 pci9111_software_trigger();
1018
1019                 timeout = PCI9111_AI_INSTANT_READ_TIMEOUT;
1020
1021                 while (timeout--) {
1022                         if (!pci9111_is_fifo_empty())
1023                                 goto conversion_done;
1024                 }
1025
1026                 comedi_error(dev, "A/D read timeout");
1027                 data[i] = 0;
1028                 pci9111_fifo_reset();
1029                 return -ETIME;
1030
1031 conversion_done:
1032
1033                 if (resolution == PCI9111_HR_AI_RESOLUTION)
1034                         data[i] = pci9111_hr_ai_get_data();
1035                 else
1036                         data[i] = pci9111_ai_get_data();
1037         }
1038
1039 #ifdef AI_INSN_DEBUG
1040         printk(PCI9111_DRIVER_NAME ": ai_insn get c/r/t = %2x/%2x/%2x\n",
1041                pci9111_ai_channel_get(),
1042                pci9111_ai_range_get(), pci9111_trigger_and_autoscan_get());
1043 #endif
1044
1045         return i;
1046 }
1047
1048 /*  Analog instant output */
1049
1050 static int
1051 pci9111_ao_insn_write(struct comedi_device *dev,
1052                       struct comedi_subdevice *s, struct comedi_insn *insn,
1053                       unsigned int *data)
1054 {
1055         struct pci9111_private_data *dev_private = dev->private;
1056         int i;
1057
1058         for (i = 0; i < insn->n; i++) {
1059                 pci9111_ao_set_data(data[i]);
1060                 dev_private->ao_readback = data[i];
1061         }
1062
1063         return i;
1064 }
1065
1066 /*  Analog output readback */
1067
1068 static int pci9111_ao_insn_read(struct comedi_device *dev,
1069                                 struct comedi_subdevice *s,
1070                                 struct comedi_insn *insn, unsigned int *data)
1071 {
1072         struct pci9111_private_data *dev_private = dev->private;
1073         int i;
1074
1075         for (i = 0; i < insn->n; i++)
1076                 data[i] = dev_private->ao_readback & PCI9111_AO_RESOLUTION_MASK;
1077
1078         return i;
1079 }
1080
1081 static int pci9111_di_insn_bits(struct comedi_device *dev,
1082                                 struct comedi_subdevice *s,
1083                                 struct comedi_insn *insn,
1084                                 unsigned int *data)
1085 {
1086         data[1] = inw(dev->iobase + PCI9111_DIO_REG);
1087
1088         return insn->n;
1089 }
1090
1091 /*  Digital outputs */
1092
1093 static int pci9111_do_insn_bits(struct comedi_device *dev,
1094                                 struct comedi_subdevice *s,
1095                                 struct comedi_insn *insn, unsigned int *data)
1096 {
1097         unsigned int bits;
1098
1099         /*  Only set bits that have been masked */
1100         /*  data[0] = mask */
1101         /*  data[1] = bit state */
1102
1103         data[0] &= PCI9111_DO_MASK;
1104
1105         bits = s->state;
1106         bits &= ~data[0];
1107         bits |= data[0] & data[1];
1108         s->state = bits;
1109
1110         outw(bits, dev->iobase + PCI9111_DIO_REG);
1111
1112         data[1] = bits;
1113
1114         return insn->n;
1115 }
1116
1117 /*  ------------------------------------------------------------------ */
1118 /*  INITIALISATION SECTION */
1119 /*  ------------------------------------------------------------------ */
1120
1121 /*  Reset device */
1122
1123 static int pci9111_reset(struct comedi_device *dev)
1124 {
1125         struct pci9111_private_data *dev_private = dev->private;
1126
1127         /*  Set trigger source to software */
1128
1129         plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
1130                                   true, false);
1131
1132         pci9111_trigger_source_set(dev, software);
1133         pci9111_pretrigger_set(dev, false);
1134         pci9111_autoscan_set(dev, false);
1135
1136         /*  Reset 8254 chip */
1137
1138         dev_private->timer_divisor_1 = 0;
1139         dev_private->timer_divisor_2 = 0;
1140
1141         pci9111_timer_set(dev);
1142
1143         return 0;
1144 }
1145
1146 static struct pci_dev *pci9111_find_pci(struct comedi_device *dev,
1147                                         struct comedi_devconfig *it)
1148 {
1149         struct pci_dev *pcidev = NULL;
1150         int bus = it->options[0];
1151         int slot = it->options[1];
1152         int i;
1153
1154         for_each_pci_dev(pcidev) {
1155                 if (pcidev->vendor != PCI_VENDOR_ID_ADLINK)
1156                         continue;
1157                 for (i = 0; i < ARRAY_SIZE(pci9111_boards); i++) {
1158                         if (pcidev->device != pci9111_boards[i].device_id)
1159                                 continue;
1160                         if (bus || slot) {
1161                                 /* requested particular bus/slot */
1162                                 if (pcidev->bus->number != bus ||
1163                                     PCI_SLOT(pcidev->devfn) != slot)
1164                                         continue;
1165                         }
1166                         dev->board_ptr = pci9111_boards + i;
1167                         printk(KERN_ERR
1168                                 "comedi%d: found %s (b:s:f=%d:%d:%d), irq=%d\n",
1169                                 dev->minor, pci9111_boards[i].name,
1170                                 pcidev->bus->number, PCI_SLOT(pcidev->devfn),
1171                                 PCI_FUNC(pcidev->devfn), pcidev->irq);
1172                         return pcidev;
1173                 }
1174         }
1175         printk(KERN_ERR
1176                 "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
1177                 dev->minor, bus, slot);
1178         return NULL;
1179 }
1180
1181 static int pci9111_attach(struct comedi_device *dev,
1182                           struct comedi_devconfig *it)
1183 {
1184         struct pci9111_private_data *dev_private;
1185         struct pci_dev *pcidev;
1186         struct comedi_subdevice *s;
1187         unsigned long io_base, io_range, lcr_io_base, lcr_io_range;
1188         int ret;
1189         const struct pci9111_board *board;
1190
1191         ret = alloc_private(dev, sizeof(*dev_private));
1192         if (ret)
1193                 return ret;
1194         dev_private = dev->private;
1195
1196         /*  Probe the device to determine what device in the series it is. */
1197
1198         printk(KERN_ERR "comedi%d: " PCI9111_DRIVER_NAME " driver\n",
1199                                                                 dev->minor);
1200
1201         pcidev = pci9111_find_pci(dev, it);
1202         if (!pcidev)
1203                 return -EIO;
1204         comedi_set_hw_dev(dev, &pcidev->dev);
1205         board = (struct pci9111_board *)dev->board_ptr;
1206
1207         /*  TODO: Warn about non-tested boards. */
1208
1209         /*  Read local configuration register base address
1210          *  [PCI_BASE_ADDRESS #1]. */
1211
1212         lcr_io_base = pci_resource_start(pcidev, 1);
1213         lcr_io_range = pci_resource_len(pcidev, 1);
1214
1215         printk
1216             ("comedi%d: local configuration registers at address 0x%4lx [0x%4lx]\n",
1217              dev->minor, lcr_io_base, lcr_io_range);
1218
1219         /*  Enable PCI device and request regions */
1220         if (comedi_pci_enable(pcidev, PCI9111_DRIVER_NAME) < 0) {
1221                 printk
1222                     ("comedi%d: Failed to enable PCI device and request regions\n",
1223                      dev->minor);
1224                 return -EIO;
1225         }
1226         /*  Read PCI6308 register base address [PCI_BASE_ADDRESS #2]. */
1227
1228         io_base = pci_resource_start(pcidev, 2);
1229         io_range = pci_resource_len(pcidev, 2);
1230
1231         printk(KERN_ERR "comedi%d: 6503 registers at address 0x%4lx [0x%4lx]\n",
1232                dev->minor, io_base, io_range);
1233
1234         dev->iobase = io_base;
1235         dev->board_name = board->name;
1236         dev_private->io_range = io_range;
1237         dev_private->is_valid = 0;
1238         dev_private->lcr_io_base = lcr_io_base;
1239         dev_private->lcr_io_range = lcr_io_range;
1240
1241         pci9111_reset(dev);
1242
1243         /*  Irq setup */
1244
1245         dev->irq = 0;
1246         if (pcidev->irq > 0) {
1247                 dev->irq = pcidev->irq;
1248
1249                 if (request_irq(dev->irq, pci9111_interrupt,
1250                                 IRQF_SHARED, PCI9111_DRIVER_NAME, dev) != 0) {
1251                         printk(KERN_ERR
1252                                 "comedi%d: unable to allocate irq  %u\n",
1253                                         dev->minor, dev->irq);
1254                         return -EINVAL;
1255                 }
1256         }
1257
1258         /*  TODO: Add external multiplexer setup (according to option[2]). */
1259
1260         ret = comedi_alloc_subdevices(dev, 4);
1261         if (ret)
1262                 return ret;
1263
1264         s = &dev->subdevices[0];
1265         dev->read_subdev = s;
1266
1267         s->type = COMEDI_SUBD_AI;
1268         s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ;
1269
1270         /*  TODO: Add external multiplexer data */
1271         /*     if (devpriv->usemux) { s->n_chan = devpriv->usemux; } */
1272         /*     else { s->n_chan = this_board->n_aichan; } */
1273
1274         s->n_chan = board->ai_channel_nbr;
1275         s->maxdata = board->ai_resolution_mask;
1276         s->len_chanlist = board->ai_channel_nbr;
1277         s->range_table = board->ai_range_list;
1278         s->cancel = pci9111_ai_cancel;
1279         s->insn_read = pci9111_ai_insn_read;
1280         s->do_cmdtest = pci9111_ai_do_cmd_test;
1281         s->do_cmd = pci9111_ai_do_cmd;
1282         s->munge = pci9111_ai_munge;
1283
1284         s = &dev->subdevices[1];
1285         s->type = COMEDI_SUBD_AO;
1286         s->subdev_flags = SDF_WRITABLE | SDF_COMMON;
1287         s->n_chan = board->ao_channel_nbr;
1288         s->maxdata = board->ao_resolution_mask;
1289         s->len_chanlist = board->ao_channel_nbr;
1290         s->range_table = board->ao_range_list;
1291         s->insn_write = pci9111_ao_insn_write;
1292         s->insn_read = pci9111_ao_insn_read;
1293
1294         s = &dev->subdevices[2];
1295         s->type = COMEDI_SUBD_DI;
1296         s->subdev_flags = SDF_READABLE;
1297         s->n_chan = PCI9111_DI_CHANNEL_NBR;
1298         s->maxdata = 1;
1299         s->range_table = &range_digital;
1300         s->insn_bits = pci9111_di_insn_bits;
1301
1302         s = &dev->subdevices[3];
1303         s->type = COMEDI_SUBD_DO;
1304         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1305         s->n_chan = PCI9111_DO_CHANNEL_NBR;
1306         s->maxdata = 1;
1307         s->range_table = &range_digital;
1308         s->insn_bits = pci9111_do_insn_bits;
1309
1310         dev_private->is_valid = 1;
1311
1312         return 0;
1313 }
1314
1315 static void pci9111_detach(struct comedi_device *dev)
1316 {
1317         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1318         struct pci9111_private_data *dev_private = dev->private;
1319
1320         if (dev_private) {
1321                 if (dev_private->is_valid)
1322                         pci9111_reset(dev);
1323         }
1324         if (dev->irq != 0)
1325                 free_irq(dev->irq, dev);
1326         if (pcidev) {
1327                 if (dev->iobase)
1328                         comedi_pci_disable(pcidev);
1329                 pci_dev_put(pcidev);
1330         }
1331 }
1332
1333 static struct comedi_driver adl_pci9111_driver = {
1334         .driver_name    = "adl_pci9111",
1335         .module         = THIS_MODULE,
1336         .attach         = pci9111_attach,
1337         .detach         = pci9111_detach,
1338 };
1339
1340 static int __devinit pci9111_pci_probe(struct pci_dev *dev,
1341                                        const struct pci_device_id *ent)
1342 {
1343         return comedi_pci_auto_config(dev, &adl_pci9111_driver);
1344 }
1345
1346 static void __devexit pci9111_pci_remove(struct pci_dev *dev)
1347 {
1348         comedi_pci_auto_unconfig(dev);
1349 }
1350
1351 static DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = {
1352         { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID) },
1353         /* { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID) }, */
1354         { 0 }
1355 };
1356 MODULE_DEVICE_TABLE(pci, pci9111_pci_table);
1357
1358 static struct pci_driver adl_pci9111_pci_driver = {
1359         .name           = "adl_pci9111",
1360         .id_table       = pci9111_pci_table,
1361         .probe          = pci9111_pci_probe,
1362         .remove         = __devexit_p(pci9111_pci_remove),
1363 };
1364 module_comedi_pci_driver(adl_pci9111_driver, adl_pci9111_pci_driver);
1365
1366 MODULE_AUTHOR("Comedi http://www.comedi.org");
1367 MODULE_DESCRIPTION("Comedi low-level driver");
1368 MODULE_LICENSE("GPL");