Merge remote-tracking branch 'lsk/v3.10/topic/gator' into linux-linaro-lsk
[firefly-linux-kernel-4.4.55.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: not applicable, uses PCI auto config
51 */
52
53 /*
54 CHANGELOG:
55
56 2005/02/17 Extend AI streaming capabilities. Now, scan_begin_arg can be
57 a multiple of chanlist_len*convert_arg.
58 2002/02/19 Fixed the two's complement conversion in pci9111_(hr_)ai_get_data.
59 2002/02/18 Added external trigger support for analog input.
60
61 TODO:
62
63         - Really test implemented functionality.
64         - Add support for the PCI-9111DG with a probe routine to identify
65           the card type (perhaps with the help of the channel number readback
66           of the A/D Data register).
67         - Add external multiplexer support.
68
69 */
70
71 #include <linux/pci.h>
72 #include <linux/delay.h>
73 #include <linux/interrupt.h>
74
75 #include "../comedidev.h"
76
77 #include "8253.h"
78 #include "plx9052.h"
79 #include "comedi_fc.h"
80
81 #define PCI9111_DRIVER_NAME     "adl_pci9111"
82 #define PCI9111_HR_DEVICE_ID    0x9111
83
84 #define PCI9111_FIFO_HALF_SIZE  512
85
86 #define PCI9111_AI_ACQUISITION_PERIOD_MIN_NS    10000
87
88 #define PCI9111_RANGE_SETTING_DELAY             10
89 #define PCI9111_AI_INSTANT_READ_UDELAY_US       2
90 #define PCI9111_AI_INSTANT_READ_TIMEOUT         100
91
92 #define PCI9111_8254_CLOCK_PERIOD_NS            500
93
94 /*
95  * IO address map and bit defines
96  */
97 #define PCI9111_AI_FIFO_REG             0x00
98 #define PCI9111_AO_REG                  0x00
99 #define PCI9111_DIO_REG                 0x02
100 #define PCI9111_EDIO_REG                0x04
101 #define PCI9111_AI_CHANNEL_REG          0x06
102 #define PCI9111_AI_RANGE_STAT_REG       0x08
103 #define PCI9111_AI_STAT_AD_BUSY         (1 << 7)
104 #define PCI9111_AI_STAT_FF_FF           (1 << 6)
105 #define PCI9111_AI_STAT_FF_HF           (1 << 5)
106 #define PCI9111_AI_STAT_FF_EF           (1 << 4)
107 #define PCI9111_AI_RANGE_MASK           (7 << 0)
108 #define PCI9111_AI_TRIG_CTRL_REG        0x0a
109 #define PCI9111_AI_TRIG_CTRL_TRGEVENT   (1 << 5)
110 #define PCI9111_AI_TRIG_CTRL_POTRG      (1 << 4)
111 #define PCI9111_AI_TRIG_CTRL_PTRG       (1 << 3)
112 #define PCI9111_AI_TRIG_CTRL_ETIS       (1 << 2)
113 #define PCI9111_AI_TRIG_CTRL_TPST       (1 << 1)
114 #define PCI9111_AI_TRIG_CTRL_ASCAN      (1 << 0)
115 #define PCI9111_INT_CTRL_REG            0x0c
116 #define PCI9111_INT_CTRL_ISC2           (1 << 3)
117 #define PCI9111_INT_CTRL_FFEN           (1 << 2)
118 #define PCI9111_INT_CTRL_ISC1           (1 << 1)
119 #define PCI9111_INT_CTRL_ISC0           (1 << 0)
120 #define PCI9111_SOFT_TRIG_REG           0x0e
121 #define PCI9111_8254_BASE_REG           0x40
122 #define PCI9111_INT_CLR_REG             0x48
123
124 /* PLX 9052 Local Interrupt 1 enabled and active */
125 #define PCI9111_LI1_ACTIVE      (PLX9052_INTCSR_LI1ENAB |       \
126                                  PLX9052_INTCSR_LI1STAT)
127
128 /* PLX 9052 Local Interrupt 2 enabled and active */
129 #define PCI9111_LI2_ACTIVE      (PLX9052_INTCSR_LI2ENAB |       \
130                                  PLX9052_INTCSR_LI2STAT)
131
132 static const struct comedi_lrange pci9111_ai_range = {
133         5,
134         {
135                 BIP_RANGE(10),
136                 BIP_RANGE(5),
137                 BIP_RANGE(2.5),
138                 BIP_RANGE(1.25),
139                 BIP_RANGE(0.625)
140         }
141 };
142
143 struct pci9111_private_data {
144         unsigned long lcr_io_base;
145
146         int stop_counter;
147         int stop_is_none;
148
149         unsigned int scan_delay;
150         unsigned int chanlist_len;
151         unsigned int chunk_counter;
152         unsigned int chunk_num_samples;
153
154         int ao_readback;
155
156         unsigned int div1;
157         unsigned int div2;
158
159         short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE];
160 };
161
162 static void plx9050_interrupt_control(unsigned long io_base,
163                                       bool LINTi1_enable,
164                                       bool LINTi1_active_high,
165                                       bool LINTi2_enable,
166                                       bool LINTi2_active_high,
167                                       bool interrupt_enable)
168 {
169         int flags = 0;
170
171         if (LINTi1_enable)
172                 flags |= PLX9052_INTCSR_LI1ENAB;
173         if (LINTi1_active_high)
174                 flags |= PLX9052_INTCSR_LI1POL;
175         if (LINTi2_enable)
176                 flags |= PLX9052_INTCSR_LI2ENAB;
177         if (LINTi2_active_high)
178                 flags |= PLX9052_INTCSR_LI2POL;
179
180         if (interrupt_enable)
181                 flags |= PLX9052_INTCSR_PCIENAB;
182
183         outb(flags, io_base + PLX9052_INTCSR);
184 }
185
186 static void pci9111_timer_set(struct comedi_device *dev)
187 {
188         struct pci9111_private_data *dev_private = dev->private;
189         unsigned long timer_base = dev->iobase + PCI9111_8254_BASE_REG;
190
191         i8254_set_mode(timer_base, 1, 0, I8254_MODE0 | I8254_BINARY);
192         i8254_set_mode(timer_base, 1, 1, I8254_MODE2 | I8254_BINARY);
193         i8254_set_mode(timer_base, 1, 2, I8254_MODE2 | I8254_BINARY);
194
195         udelay(1);
196
197         i8254_write(timer_base, 1, 2, dev_private->div2);
198         i8254_write(timer_base, 1, 1, dev_private->div1);
199 }
200
201 enum pci9111_trigger_sources {
202         software,
203         timer_pacer,
204         external
205 };
206
207 static void pci9111_trigger_source_set(struct comedi_device *dev,
208                                        enum pci9111_trigger_sources source)
209 {
210         int flags;
211
212         /* Read the current trigger mode control bits */
213         flags = inb(dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
214         /* Mask off the EITS and TPST bits */
215         flags &= 0x9;
216
217         switch (source) {
218         case software:
219                 break;
220
221         case timer_pacer:
222                 flags |= PCI9111_AI_TRIG_CTRL_TPST;
223                 break;
224
225         case external:
226                 flags |= PCI9111_AI_TRIG_CTRL_ETIS;
227                 break;
228         }
229
230         outb(flags, dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
231 }
232
233 static void pci9111_pretrigger_set(struct comedi_device *dev, bool pretrigger)
234 {
235         int flags;
236
237         /* Read the current trigger mode control bits */
238         flags = inb(dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
239         /* Mask off the PTRG bit */
240         flags &= 0x7;
241
242         if (pretrigger)
243                 flags |= PCI9111_AI_TRIG_CTRL_PTRG;
244
245         outb(flags, dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
246 }
247
248 static void pci9111_autoscan_set(struct comedi_device *dev, bool autoscan)
249 {
250         int flags;
251
252         /* Read the current trigger mode control bits */
253         flags = inb(dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
254         /* Mask off the ASCAN bit */
255         flags &= 0xe;
256
257         if (autoscan)
258                 flags |= PCI9111_AI_TRIG_CTRL_ASCAN;
259
260         outb(flags, dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
261 }
262
263 enum pci9111_ISC0_sources {
264         irq_on_eoc,
265         irq_on_fifo_half_full
266 };
267
268 enum pci9111_ISC1_sources {
269         irq_on_timer_tick,
270         irq_on_external_trigger
271 };
272
273 static void pci9111_interrupt_source_set(struct comedi_device *dev,
274                                          enum pci9111_ISC0_sources irq_0_source,
275                                          enum pci9111_ISC1_sources irq_1_source)
276 {
277         int flags;
278
279         /* Read the current interrupt control bits */
280         flags = inb(dev->iobase + PCI9111_AI_TRIG_CTRL_REG);
281         /* Shift the bits so they are compatible with the write register */
282         flags >>= 4;
283         /* Mask off the ISCx bits */
284         flags &= 0xc0;
285
286         /* Now set the new ISCx bits */
287         if (irq_0_source == irq_on_fifo_half_full)
288                 flags |= PCI9111_INT_CTRL_ISC0;
289
290         if (irq_1_source == irq_on_external_trigger)
291                 flags |= PCI9111_INT_CTRL_ISC1;
292
293         outb(flags, dev->iobase + PCI9111_INT_CTRL_REG);
294 }
295
296 static void pci9111_fifo_reset(struct comedi_device *dev)
297 {
298         unsigned long int_ctrl_reg = dev->iobase + PCI9111_INT_CTRL_REG;
299
300         /* To reset the FIFO, set FFEN sequence as 0 -> 1 -> 0 */
301         outb(0, int_ctrl_reg);
302         outb(PCI9111_INT_CTRL_FFEN, int_ctrl_reg);
303         outb(0, int_ctrl_reg);
304 }
305
306 static int pci9111_ai_cancel(struct comedi_device *dev,
307                              struct comedi_subdevice *s)
308 {
309         struct pci9111_private_data *dev_private = dev->private;
310
311         /*  Disable interrupts */
312         plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
313                                   true, false);
314
315         pci9111_trigger_source_set(dev, software);
316
317         pci9111_autoscan_set(dev, false);
318
319         pci9111_fifo_reset(dev);
320
321         return 0;
322 }
323
324 static int pci9111_ai_do_cmd_test(struct comedi_device *dev,
325                                   struct comedi_subdevice *s,
326                                   struct comedi_cmd *cmd)
327 {
328         struct pci9111_private_data *dev_private = dev->private;
329         int tmp;
330         int error = 0;
331         int range, reference;
332         int i;
333
334         /* Step 1 : check if triggers are trivially valid */
335
336         error |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
337         error |= cfc_check_trigger_src(&cmd->scan_begin_src,
338                                         TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT);
339         error |= cfc_check_trigger_src(&cmd->convert_src,
340                                         TRIG_TIMER | TRIG_EXT);
341         error |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
342         error |= cfc_check_trigger_src(&cmd->stop_src,
343                                         TRIG_COUNT | TRIG_NONE);
344
345         if (error)
346                 return 1;
347
348         /* Step 2a : make sure trigger sources are unique */
349
350         error |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
351         error |= cfc_check_trigger_is_unique(cmd->convert_src);
352         error |= cfc_check_trigger_is_unique(cmd->stop_src);
353
354         /* Step 2b : and mutually compatible */
355
356         if ((cmd->convert_src == TRIG_TIMER) &&
357             !((cmd->scan_begin_src == TRIG_TIMER) ||
358               (cmd->scan_begin_src == TRIG_FOLLOW)))
359                 error |= -EINVAL;
360         if ((cmd->convert_src == TRIG_EXT) &&
361             !((cmd->scan_begin_src == TRIG_EXT) ||
362               (cmd->scan_begin_src == TRIG_FOLLOW)))
363                 error |= -EINVAL;
364
365         if (error)
366                 return 2;
367
368         /* Step 3: check if arguments are trivially valid */
369
370         error |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
371
372         if (cmd->convert_src == TRIG_TIMER)
373                 error |= cfc_check_trigger_arg_min(&cmd->convert_arg,
374                                         PCI9111_AI_ACQUISITION_PERIOD_MIN_NS);
375         else    /* TRIG_EXT */
376                 error |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
377
378         if (cmd->scan_begin_src == TRIG_TIMER)
379                 error |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
380                                         PCI9111_AI_ACQUISITION_PERIOD_MIN_NS);
381         else    /* TRIG_FOLLOW || TRIG_EXT */
382                 error |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
383
384         error |= cfc_check_trigger_arg_is(&cmd->scan_end_arg,
385                                           cmd->chanlist_len);
386
387         if (cmd->stop_src == TRIG_COUNT)
388                 error |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
389         else    /* TRIG_NONE */
390                 error |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
391
392         if (error)
393                 return 3;
394
395         /*  Step 4 : fix up any arguments */
396
397         if (cmd->convert_src == TRIG_TIMER) {
398                 tmp = cmd->convert_arg;
399                 i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS,
400                                                &dev_private->div1,
401                                                &dev_private->div2,
402                                                &cmd->convert_arg,
403                                                cmd->flags & TRIG_ROUND_MASK);
404                 if (tmp != cmd->convert_arg)
405                         error++;
406         }
407         /*  There's only one timer on this card, so the scan_begin timer must */
408         /*  be a multiple of chanlist_len*convert_arg */
409
410         if (cmd->scan_begin_src == TRIG_TIMER) {
411
412                 unsigned int scan_begin_min;
413                 unsigned int scan_begin_arg;
414                 unsigned int scan_factor;
415
416                 scan_begin_min = cmd->chanlist_len * cmd->convert_arg;
417
418                 if (cmd->scan_begin_arg != scan_begin_min) {
419                         if (scan_begin_min < cmd->scan_begin_arg) {
420                                 scan_factor =
421                                     cmd->scan_begin_arg / scan_begin_min;
422                                 scan_begin_arg = scan_factor * scan_begin_min;
423                                 if (cmd->scan_begin_arg != scan_begin_arg) {
424                                         cmd->scan_begin_arg = scan_begin_arg;
425                                         error++;
426                                 }
427                         } else {
428                                 cmd->scan_begin_arg = scan_begin_min;
429                                 error++;
430                         }
431                 }
432         }
433
434         if (error)
435                 return 4;
436
437         /*  Step 5 : check channel list */
438
439         if (cmd->chanlist) {
440
441                 range = CR_RANGE(cmd->chanlist[0]);
442                 reference = CR_AREF(cmd->chanlist[0]);
443
444                 if (cmd->chanlist_len > 1) {
445                         for (i = 0; i < cmd->chanlist_len; i++) {
446                                 if (CR_CHAN(cmd->chanlist[i]) != i) {
447                                         comedi_error(dev,
448                                                      "entries in chanlist must be consecutive "
449                                                      "channels,counting upwards from 0\n");
450                                         error++;
451                                 }
452                                 if (CR_RANGE(cmd->chanlist[i]) != range) {
453                                         comedi_error(dev,
454                                                      "entries in chanlist must all have the same gain\n");
455                                         error++;
456                                 }
457                                 if (CR_AREF(cmd->chanlist[i]) != reference) {
458                                         comedi_error(dev,
459                                                      "entries in chanlist must all have the same reference\n");
460                                         error++;
461                                 }
462                         }
463                 }
464         }
465
466         if (error)
467                 return 5;
468
469         return 0;
470
471 }
472
473 static int pci9111_ai_do_cmd(struct comedi_device *dev,
474                              struct comedi_subdevice *s)
475 {
476         struct pci9111_private_data *dev_private = dev->private;
477         struct comedi_cmd *async_cmd = &s->async->cmd;
478
479         if (!dev->irq) {
480                 comedi_error(dev,
481                              "no irq assigned for PCI9111, cannot do hardware conversion");
482                 return -1;
483         }
484         /*  Set channel scan limit */
485         /*  PCI9111 allows only scanning from channel 0 to channel n */
486         /*  TODO: handle the case of an external multiplexer */
487
488         if (async_cmd->chanlist_len > 1) {
489                 outb(async_cmd->chanlist_len - 1,
490                         dev->iobase + PCI9111_AI_CHANNEL_REG);
491                 pci9111_autoscan_set(dev, true);
492         } else {
493                 outb(CR_CHAN(async_cmd->chanlist[0]),
494                         dev->iobase + PCI9111_AI_CHANNEL_REG);
495                 pci9111_autoscan_set(dev, false);
496         }
497
498         /*  Set gain */
499         /*  This is the same gain on every channel */
500
501         outb(CR_RANGE(async_cmd->chanlist[0]) & PCI9111_AI_RANGE_MASK,
502                 dev->iobase + PCI9111_AI_RANGE_STAT_REG);
503
504         /* Set counter */
505
506         switch (async_cmd->stop_src) {
507         case TRIG_COUNT:
508                 dev_private->stop_counter =
509                     async_cmd->stop_arg * async_cmd->chanlist_len;
510                 dev_private->stop_is_none = 0;
511                 break;
512
513         case TRIG_NONE:
514                 dev_private->stop_counter = 0;
515                 dev_private->stop_is_none = 1;
516                 break;
517
518         default:
519                 comedi_error(dev, "Invalid stop trigger");
520                 return -1;
521         }
522
523         /*  Set timer pacer */
524
525         dev_private->scan_delay = 0;
526         switch (async_cmd->convert_src) {
527         case TRIG_TIMER:
528                 pci9111_trigger_source_set(dev, software);
529                 pci9111_timer_set(dev);
530                 pci9111_fifo_reset(dev);
531                 pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
532                                              irq_on_timer_tick);
533                 pci9111_trigger_source_set(dev, timer_pacer);
534                 plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
535                                           false, true, true);
536
537                 if (async_cmd->scan_begin_src == TRIG_TIMER) {
538                         dev_private->scan_delay =
539                                 (async_cmd->scan_begin_arg /
540                                  (async_cmd->convert_arg *
541                                   async_cmd->chanlist_len)) - 1;
542                 }
543
544                 break;
545
546         case TRIG_EXT:
547
548                 pci9111_trigger_source_set(dev, external);
549                 pci9111_fifo_reset(dev);
550                 pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
551                                              irq_on_timer_tick);
552                 plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
553                                           false, true, true);
554
555                 break;
556
557         default:
558                 comedi_error(dev, "Invalid convert trigger");
559                 return -1;
560         }
561
562         dev_private->stop_counter *= (1 + dev_private->scan_delay);
563         dev_private->chanlist_len = async_cmd->chanlist_len;
564         dev_private->chunk_counter = 0;
565         dev_private->chunk_num_samples =
566             dev_private->chanlist_len * (1 + dev_private->scan_delay);
567
568         return 0;
569 }
570
571 static void pci9111_ai_munge(struct comedi_device *dev,
572                              struct comedi_subdevice *s, void *data,
573                              unsigned int num_bytes,
574                              unsigned int start_chan_index)
575 {
576         short *array = data;
577         unsigned int maxdata = s->maxdata;
578         unsigned int invert = (maxdata + 1) >> 1;
579         unsigned int shift = (maxdata == 0xffff) ? 0 : 4;
580         unsigned int num_samples = num_bytes / sizeof(short);
581         unsigned int i;
582
583         for (i = 0; i < num_samples; i++)
584                 array[i] = ((array[i] >> shift) & maxdata) ^ invert;
585 }
586
587 static irqreturn_t pci9111_interrupt(int irq, void *p_device)
588 {
589         struct comedi_device *dev = p_device;
590         struct pci9111_private_data *dev_private = dev->private;
591         struct comedi_subdevice *s = dev->read_subdev;
592         struct comedi_async *async;
593         unsigned int status;
594         unsigned long irq_flags;
595         unsigned char intcsr;
596
597         if (!dev->attached) {
598                 /*  Ignore interrupt before device fully attached. */
599                 /*  Might not even have allocated subdevices yet! */
600                 return IRQ_NONE;
601         }
602
603         async = s->async;
604
605         spin_lock_irqsave(&dev->spinlock, irq_flags);
606
607         /*  Check if we are source of interrupt */
608         intcsr = inb(dev_private->lcr_io_base + PLX9052_INTCSR);
609         if (!(((intcsr & PLX9052_INTCSR_PCIENAB) != 0) &&
610               (((intcsr & PCI9111_LI1_ACTIVE) == PCI9111_LI1_ACTIVE) ||
611                ((intcsr & PCI9111_LI2_ACTIVE) == PCI9111_LI2_ACTIVE)))) {
612                 /*  Not the source of the interrupt. */
613                 /*  (N.B. not using PLX9052_INTCSR_SOFTINT) */
614                 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
615                 return IRQ_NONE;
616         }
617
618         if ((intcsr & PCI9111_LI1_ACTIVE) == PCI9111_LI1_ACTIVE) {
619                 /*  Interrupt comes from fifo_half-full signal */
620
621                 status = inb(dev->iobase + PCI9111_AI_RANGE_STAT_REG);
622
623                 /* '0' means FIFO is full, data may have been lost */
624                 if (!(status & PCI9111_AI_STAT_FF_FF)) {
625                         spin_unlock_irqrestore(&dev->spinlock, irq_flags);
626                         comedi_error(dev, PCI9111_DRIVER_NAME " fifo overflow");
627                         outb(0, dev->iobase + PCI9111_INT_CLR_REG);
628                         pci9111_ai_cancel(dev, s);
629                         async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
630                         comedi_event(dev, s);
631
632                         return IRQ_HANDLED;
633                 }
634
635                 /* '0' means FIFO is half-full */
636                 if (!(status & PCI9111_AI_STAT_FF_HF)) {
637                         unsigned int num_samples;
638                         unsigned int bytes_written = 0;
639
640                         num_samples =
641                             PCI9111_FIFO_HALF_SIZE >
642                             dev_private->stop_counter
643                             && !dev_private->
644                             stop_is_none ? dev_private->stop_counter :
645                             PCI9111_FIFO_HALF_SIZE;
646                         insw(dev->iobase + PCI9111_AI_FIFO_REG,
647                              dev_private->ai_bounce_buffer, num_samples);
648
649                         if (dev_private->scan_delay < 1) {
650                                 bytes_written =
651                                     cfc_write_array_to_buffer(s,
652                                                               dev_private->
653                                                               ai_bounce_buffer,
654                                                               num_samples *
655                                                               sizeof(short));
656                         } else {
657                                 int position = 0;
658                                 int to_read;
659
660                                 while (position < num_samples) {
661                                         if (dev_private->chunk_counter <
662                                             dev_private->chanlist_len) {
663                                                 to_read =
664                                                     dev_private->chanlist_len -
665                                                     dev_private->chunk_counter;
666
667                                                 if (to_read >
668                                                     num_samples - position)
669                                                         to_read =
670                                                             num_samples -
671                                                             position;
672
673                                                 bytes_written +=
674                                                     cfc_write_array_to_buffer
675                                                     (s,
676                                                      dev_private->ai_bounce_buffer
677                                                      + position,
678                                                      to_read * sizeof(short));
679                                         } else {
680                                                 to_read =
681                                                     dev_private->chunk_num_samples
682                                                     -
683                                                     dev_private->chunk_counter;
684                                                 if (to_read >
685                                                     num_samples - position)
686                                                         to_read =
687                                                             num_samples -
688                                                             position;
689
690                                                 bytes_written +=
691                                                     sizeof(short) * to_read;
692                                         }
693
694                                         position += to_read;
695                                         dev_private->chunk_counter += to_read;
696
697                                         if (dev_private->chunk_counter >=
698                                             dev_private->chunk_num_samples)
699                                                 dev_private->chunk_counter = 0;
700                                 }
701                         }
702
703                         dev_private->stop_counter -=
704                             bytes_written / sizeof(short);
705                 }
706         }
707
708         if ((dev_private->stop_counter == 0) && (!dev_private->stop_is_none)) {
709                 async->events |= COMEDI_CB_EOA;
710                 pci9111_ai_cancel(dev, s);
711         }
712
713         outb(0, dev->iobase + PCI9111_INT_CLR_REG);
714
715         spin_unlock_irqrestore(&dev->spinlock, irq_flags);
716
717         comedi_event(dev, s);
718
719         return IRQ_HANDLED;
720 }
721
722 static int pci9111_ai_insn_read(struct comedi_device *dev,
723                                 struct comedi_subdevice *s,
724                                 struct comedi_insn *insn, unsigned int *data)
725 {
726         unsigned int chan = CR_CHAN(insn->chanspec);
727         unsigned int range = CR_RANGE(insn->chanspec);
728         unsigned int maxdata = s->maxdata;
729         unsigned int invert = (maxdata + 1) >> 1;
730         unsigned int shift = (maxdata == 0xffff) ? 0 : 4;
731         unsigned int status;
732         int timeout;
733         int i;
734
735         outb(chan, dev->iobase + PCI9111_AI_CHANNEL_REG);
736
737         status = inb(dev->iobase + PCI9111_AI_RANGE_STAT_REG);
738         if ((status & PCI9111_AI_RANGE_MASK) != range) {
739                 outb(range & PCI9111_AI_RANGE_MASK,
740                         dev->iobase + PCI9111_AI_RANGE_STAT_REG);
741         }
742
743         pci9111_fifo_reset(dev);
744
745         for (i = 0; i < insn->n; i++) {
746                 /* Generate a software trigger */
747                 outb(0, dev->iobase + PCI9111_SOFT_TRIG_REG);
748
749                 timeout = PCI9111_AI_INSTANT_READ_TIMEOUT;
750
751                 while (timeout--) {
752                         status = inb(dev->iobase + PCI9111_AI_RANGE_STAT_REG);
753                         /* '1' means FIFO is not empty */
754                         if (status & PCI9111_AI_STAT_FF_EF)
755                                 goto conversion_done;
756                 }
757
758                 comedi_error(dev, "A/D read timeout");
759                 data[i] = 0;
760                 pci9111_fifo_reset(dev);
761                 return -ETIME;
762
763 conversion_done:
764
765                 data[i] = inw(dev->iobase + PCI9111_AI_FIFO_REG);
766                 data[i] = ((data[i] >> shift) & maxdata) ^ invert;
767         }
768
769         return i;
770 }
771
772 static int pci9111_ao_insn_write(struct comedi_device *dev,
773                                  struct comedi_subdevice *s,
774                                  struct comedi_insn *insn,
775                                  unsigned int *data)
776 {
777         struct pci9111_private_data *dev_private = dev->private;
778         unsigned int val = 0;
779         int i;
780
781         for (i = 0; i < insn->n; i++) {
782                 val = data[i];
783                 outw(val, dev->iobase + PCI9111_AO_REG);
784         }
785         dev_private->ao_readback = val;
786
787         return insn->n;
788 }
789
790 static int pci9111_ao_insn_read(struct comedi_device *dev,
791                                 struct comedi_subdevice *s,
792                                 struct comedi_insn *insn,
793                                 unsigned int *data)
794 {
795         struct pci9111_private_data *dev_private = dev->private;
796         int i;
797
798         for (i = 0; i < insn->n; i++)
799                 data[i] = dev_private->ao_readback;
800
801         return insn->n;
802 }
803
804 static int pci9111_di_insn_bits(struct comedi_device *dev,
805                                 struct comedi_subdevice *s,
806                                 struct comedi_insn *insn,
807                                 unsigned int *data)
808 {
809         data[1] = inw(dev->iobase + PCI9111_DIO_REG);
810
811         return insn->n;
812 }
813
814 static int pci9111_do_insn_bits(struct comedi_device *dev,
815                                 struct comedi_subdevice *s,
816                                 struct comedi_insn *insn,
817                                 unsigned int *data)
818 {
819         unsigned int mask = data[0];
820         unsigned int bits = data[1];
821
822         if (mask) {
823                 s->state &= ~mask;
824                 s->state |= (bits & mask);
825
826                 outw(s->state, dev->iobase + PCI9111_DIO_REG);
827         }
828
829         data[1] = s->state;
830
831         return insn->n;
832 }
833
834 static int pci9111_reset(struct comedi_device *dev)
835 {
836         struct pci9111_private_data *dev_private = dev->private;
837
838         /*  Set trigger source to software */
839         plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
840                                   true, false);
841
842         pci9111_trigger_source_set(dev, software);
843         pci9111_pretrigger_set(dev, false);
844         pci9111_autoscan_set(dev, false);
845
846         /* Reset 8254 chip */
847         dev_private->div1 = 0;
848         dev_private->div2 = 0;
849         pci9111_timer_set(dev);
850
851         return 0;
852 }
853
854 static int pci9111_auto_attach(struct comedi_device *dev,
855                                          unsigned long context_unused)
856 {
857         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
858         struct pci9111_private_data *dev_private;
859         struct comedi_subdevice *s;
860         int ret;
861
862         dev_private = kzalloc(sizeof(*dev_private), GFP_KERNEL);
863         if (!dev_private)
864                 return -ENOMEM;
865         dev->private = dev_private;
866
867         ret = comedi_pci_enable(dev);
868         if (ret)
869                 return ret;
870         dev_private->lcr_io_base = pci_resource_start(pcidev, 1);
871         dev->iobase = pci_resource_start(pcidev, 2);
872
873         pci9111_reset(dev);
874
875         if (pcidev->irq > 0) {
876                 ret = request_irq(pcidev->irq, pci9111_interrupt,
877                                   IRQF_SHARED, dev->board_name, dev);
878                 if (ret)
879                         return ret;
880                 dev->irq = pcidev->irq;
881         }
882
883         ret = comedi_alloc_subdevices(dev, 4);
884         if (ret)
885                 return ret;
886
887         s = &dev->subdevices[0];
888         dev->read_subdev = s;
889         s->type         = COMEDI_SUBD_AI;
890         s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ;
891         s->n_chan       = 16;
892         s->maxdata      = 0xffff;
893         s->len_chanlist = 16;
894         s->range_table  = &pci9111_ai_range;
895         s->cancel       = pci9111_ai_cancel;
896         s->insn_read    = pci9111_ai_insn_read;
897         s->do_cmdtest   = pci9111_ai_do_cmd_test;
898         s->do_cmd       = pci9111_ai_do_cmd;
899         s->munge        = pci9111_ai_munge;
900
901         s = &dev->subdevices[1];
902         s->type         = COMEDI_SUBD_AO;
903         s->subdev_flags = SDF_WRITABLE | SDF_COMMON;
904         s->n_chan       = 1;
905         s->maxdata      = 0x0fff;
906         s->len_chanlist = 1;
907         s->range_table  = &range_bipolar10;
908         s->insn_write   = pci9111_ao_insn_write;
909         s->insn_read    = pci9111_ao_insn_read;
910
911         s = &dev->subdevices[2];
912         s->type         = COMEDI_SUBD_DI;
913         s->subdev_flags = SDF_READABLE;
914         s->n_chan       = 16;
915         s->maxdata      = 1;
916         s->range_table  = &range_digital;
917         s->insn_bits    = pci9111_di_insn_bits;
918
919         s = &dev->subdevices[3];
920         s->type         = COMEDI_SUBD_DO;
921         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
922         s->n_chan       = 16;
923         s->maxdata      = 1;
924         s->range_table  = &range_digital;
925         s->insn_bits    = pci9111_do_insn_bits;
926
927         dev_info(dev->class_dev, "%s attached\n", dev->board_name);
928
929         return 0;
930 }
931
932 static void pci9111_detach(struct comedi_device *dev)
933 {
934         if (dev->iobase)
935                 pci9111_reset(dev);
936         if (dev->irq != 0)
937                 free_irq(dev->irq, dev);
938         comedi_pci_disable(dev);
939 }
940
941 static struct comedi_driver adl_pci9111_driver = {
942         .driver_name    = "adl_pci9111",
943         .module         = THIS_MODULE,
944         .auto_attach    = pci9111_auto_attach,
945         .detach         = pci9111_detach,
946 };
947
948 static int pci9111_pci_probe(struct pci_dev *dev,
949                              const struct pci_device_id *id)
950 {
951         return comedi_pci_auto_config(dev, &adl_pci9111_driver,
952                                       id->driver_data);
953 }
954
955 static DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = {
956         { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID) },
957         /* { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID) }, */
958         { 0 }
959 };
960 MODULE_DEVICE_TABLE(pci, pci9111_pci_table);
961
962 static struct pci_driver adl_pci9111_pci_driver = {
963         .name           = "adl_pci9111",
964         .id_table       = pci9111_pci_table,
965         .probe          = pci9111_pci_probe,
966         .remove         = comedi_pci_auto_unconfig,
967 };
968 module_comedi_pci_driver(adl_pci9111_driver, adl_pci9111_pci_driver);
969
970 MODULE_AUTHOR("Comedi http://www.comedi.org");
971 MODULE_DESCRIPTION("Comedi low-level driver");
972 MODULE_LICENSE("GPL");