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