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