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