]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/comedi/drivers/cb_pcidas.c
Merge tag 'late-omap' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[karo-tx-linux.git] / drivers / staging / comedi / drivers / cb_pcidas.c
1 /*
2     comedi/drivers/cb_pcidas.c
3
4     Developed by Ivan Martinez and Frank Mori Hess, with valuable help from
5     David Schleef and the rest of the Comedi developers comunity.
6
7     Copyright (C) 2001-2003 Ivan Martinez <imr@oersted.dtu.dk>
8     Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
9
10     COMEDI - Linux Control and Measurement Device Interface
11     Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
12
13     This program is free software; you can redistribute it and/or modify
14     it under the terms of the GNU General Public License as published by
15     the Free Software Foundation; either version 2 of the License, or
16     (at your option) any later version.
17
18     This program is distributed in the hope that it will be useful,
19     but WITHOUT ANY WARRANTY; without even the implied warranty of
20     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21     GNU General Public License for more details.
22
23     You should have received a copy of the GNU General Public License
24     along with this program; if not, write to the Free Software
25     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
27 ************************************************************************
28 */
29 /*
30 Driver: cb_pcidas
31 Description: MeasurementComputing PCI-DAS series
32   with the AMCC S5933 PCI controller
33 Author: Ivan Martinez <imr@oersted.dtu.dk>,
34   Frank Mori Hess <fmhess@users.sourceforge.net>
35 Updated: 2003-3-11
36 Devices: [Measurement Computing] PCI-DAS1602/16 (cb_pcidas),
37   PCI-DAS1602/16jr, PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr,
38   PCI-DAS1000, PCI-DAS1001, PCI_DAS1002
39
40 Status:
41   There are many reports of the driver being used with most of the
42   supported cards. Despite no detailed log is maintained, it can
43   be said that the driver is quite tested and stable.
44
45   The boards may be autocalibrated using the comedi_calibrate
46   utility.
47
48 Configuration options: not applicable, uses PCI auto config
49
50 For commands, the scanned channels must be consecutive
51 (i.e. 4-5-6-7, 2-3-4,...), and must all have the same
52 range and aref.
53
54 AI Triggering:
55    For start_src == TRIG_EXT, the A/D EXTERNAL TRIGGER IN (pin 45) is used.
56    For 1602 series, the start_arg is interpreted as follows:
57      start_arg == 0                   => gated trigger (level high)
58      start_arg == CR_INVERT           => gated trigger (level low)
59      start_arg == CR_EDGE             => Rising edge
60      start_arg == CR_EDGE | CR_INVERT => Falling edge
61    For the other boards the trigger will be done on rising edge
62 */
63 /*
64
65 TODO:
66
67 analog triggering on 1602 series
68 */
69
70 #include <linux/pci.h>
71 #include <linux/delay.h>
72 #include <linux/interrupt.h>
73
74 #include "../comedidev.h"
75
76 #include "8253.h"
77 #include "8255.h"
78 #include "amcc_s5933.h"
79 #include "comedi_fc.h"
80
81 #define TIMER_BASE              100     /* 10MHz master clock */
82 #define AI_BUFFER_SIZE          1024    /* max ai fifo size */
83 #define AO_BUFFER_SIZE          1024    /* max ao fifo size */
84 #define NUM_CHANNELS_8800       8
85 #define NUM_CHANNELS_7376       1
86 #define NUM_CHANNELS_8402       2
87 #define NUM_CHANNELS_DAC08      1
88
89 /* Control/Status registers */
90 #define INT_ADCFIFO             0       /* INTERRUPT / ADC FIFO register */
91 #define   INT_EOS               0x1     /* int end of scan */
92 #define   INT_FHF               0x2     /* int fifo half full */
93 #define   INT_FNE               0x3     /* int fifo not empty */
94 #define   INT_MASK              0x3     /* mask of int select bits */
95 #define   INTE                  0x4     /* int enable */
96 #define   DAHFIE                0x8     /* dac half full int enable */
97 #define   EOAIE                 0x10    /* end of acq. int enable */
98 #define   DAHFI                 0x20    /* dac half full status / clear */
99 #define   EOAI                  0x40    /* end of acq. int status / clear */
100 #define   INT                   0x80    /* int status / clear */
101 #define   EOBI                  0x200   /* end of burst int status */
102 #define   ADHFI                 0x400   /* half-full int status */
103 #define   ADNEI                 0x800   /* fifo not empty int status (latch) */
104 #define   ADNE                  0x1000  /* fifo not empty status (realtime) */
105 #define   DAEMIE                0x1000  /* dac empty int enable */
106 #define   LADFUL                0x2000  /* fifo overflow / clear */
107 #define   DAEMI                 0x4000  /* dac fifo empty int status / clear */
108
109 #define ADCMUX_CONT             2       /* ADC CHANNEL MUX AND CONTROL reg */
110 #define   BEGIN_SCAN(x)         ((x) & 0xf)
111 #define   END_SCAN(x)           (((x) & 0xf) << 4)
112 #define   GAIN_BITS(x)          (((x) & 0x3) << 8)
113 #define   UNIP                  0x800   /* Analog front-end unipolar mode */
114 #define   SE                    0x400   /* Inputs in single-ended mode */
115 #define   PACER_MASK            0x3000  /* pacer source bits */
116 #define   PACER_INT             0x1000  /* int. pacer */
117 #define   PACER_EXT_FALL        0x2000  /* ext. falling edge */
118 #define   PACER_EXT_RISE        0x3000  /* ext. rising edge */
119 #define   EOC                   0x4000  /* adc not busy */
120
121 #define TRIG_CONTSTAT            4      /* TRIGGER CONTROL/STATUS register */
122 #define   SW_TRIGGER            0x1     /* software start trigger */
123 #define   EXT_TRIGGER           0x2     /* ext. start trigger */
124 #define   ANALOG_TRIGGER        0x3     /* ext. analog trigger */
125 #define   TRIGGER_MASK          0x3     /* start trigger mask */
126 #define   TGPOL                 0x04    /* invert trigger (1602 only) */
127 #define   TGSEL                 0x08    /* edge/level trigerred (1602 only) */
128 #define   TGEN                  0x10    /* enable external start trigger */
129 #define   BURSTE                0x20    /* burst mode enable */
130 #define   XTRCL                 0x80    /* clear external trigger */
131
132 #define CALIBRATION_REG         6       /* CALIBRATION register */
133 #define   SELECT_8800_BIT       0x100   /* select 8800 caldac */
134 #define   SELECT_TRIMPOT_BIT    0x200   /* select ad7376 trim pot */
135 #define   SELECT_DAC08_BIT      0x400   /* select dac08 caldac */
136 #define   CAL_SRC_BITS(x)       (((x) & 0x7) << 11)
137 #define   CAL_EN_BIT            0x4000  /* calibration source enable */
138 #define   SERIAL_DATA_IN_BIT    0x8000  /* serial data bit going to caldac */
139
140 #define DAC_CSR                 0x8     /* dac control and status register */
141 #define   DACEN                 0x02    /* dac enable */
142 #define   DAC_MODE_UPDATE_BOTH  0x80    /* update both dacs */
143
144 static inline unsigned int DAC_RANGE(unsigned int channel, unsigned int range)
145 {
146         return (range & 0x3) << (8 + 2 * (channel & 0x1));
147 }
148
149 static inline unsigned int DAC_RANGE_MASK(unsigned int channel)
150 {
151         return 0x3 << (8 + 2 * (channel & 0x1));
152 };
153
154 /* bits for 1602 series only */
155 #define   DAC_EMPTY             0x1     /* fifo empty, read, write clear */
156 #define   DAC_START             0x4     /* start/arm fifo operations */
157 #define   DAC_PACER_MASK        0x18    /* bits that set pacer source */
158 #define   DAC_PACER_INT         0x8     /* int. pacing */
159 #define   DAC_PACER_EXT_FALL    0x10    /* ext. pacing, falling edge */
160 #define   DAC_PACER_EXT_RISE    0x18    /* ext. pacing, rising edge */
161
162 static inline unsigned int DAC_CHAN_EN(unsigned int channel)
163 {
164         return 1 << (5 + (channel & 0x1));      /*  enable channel 0 or 1 */
165 };
166
167 /* analog input fifo */
168 #define ADCDATA                 0       /* ADC DATA register */
169 #define ADCFIFOCLR              2       /* ADC FIFO CLEAR */
170
171 /* pacer, counter, dio registers */
172 #define ADC8254                 0
173 #define DIO_8255                4
174 #define DAC8254                 8
175
176 /* analog output registers for 100x, 1200 series */
177 static inline unsigned int DAC_DATA_REG(unsigned int channel)
178 {
179         return 2 * (channel & 0x1);
180 }
181
182 /* analog output registers for 1602 series*/
183 #define DACDATA                 0       /* DAC DATA register */
184 #define DACFIFOCLR              2       /* DAC FIFO CLEAR */
185
186 #define IS_UNIPOLAR             0x4     /* unipolar range mask */
187
188 /* analog input ranges for most boards */
189 static const struct comedi_lrange cb_pcidas_ranges = {
190         8,
191         {
192          BIP_RANGE(10),
193          BIP_RANGE(5),
194          BIP_RANGE(2.5),
195          BIP_RANGE(1.25),
196          UNI_RANGE(10),
197          UNI_RANGE(5),
198          UNI_RANGE(2.5),
199          UNI_RANGE(1.25)
200          }
201 };
202
203 /* pci-das1001 input ranges */
204 static const struct comedi_lrange cb_pcidas_alt_ranges = {
205         8,
206         {
207          BIP_RANGE(10),
208          BIP_RANGE(1),
209          BIP_RANGE(0.1),
210          BIP_RANGE(0.01),
211          UNI_RANGE(10),
212          UNI_RANGE(1),
213          UNI_RANGE(0.1),
214          UNI_RANGE(0.01)
215          }
216 };
217
218 /* analog output ranges */
219 static const struct comedi_lrange cb_pcidas_ao_ranges = {
220         4,
221         {
222          BIP_RANGE(5),
223          BIP_RANGE(10),
224          UNI_RANGE(5),
225          UNI_RANGE(10),
226          }
227 };
228
229 enum trimpot_model {
230         AD7376,
231         AD8402,
232 };
233
234 struct cb_pcidas_board {
235         const char *name;
236         unsigned short device_id;
237         int ai_nchan;           /*  Inputs in single-ended mode */
238         int ai_bits;            /*  analog input resolution */
239         int ai_speed;           /*  fastest conversion period in ns */
240         int ao_nchan;           /*  number of analog out channels */
241         int has_ao_fifo;        /*  analog output has fifo */
242         int ao_scan_speed;      /*  analog output scan speed for 1602 series */
243         int fifo_size;          /*  number of samples fifo can hold */
244         const struct comedi_lrange *ranges;
245         enum trimpot_model trimpot;
246         unsigned has_dac08:1;
247         unsigned is_1602:1;
248 };
249
250 static const struct cb_pcidas_board cb_pcidas_boards[] = {
251         {
252                 .name           = "pci-das1602/16",
253                 .device_id      = 0x1,
254                 .ai_nchan       = 16,
255                 .ai_bits        = 16,
256                 .ai_speed       = 5000,
257                 .ao_nchan       = 2,
258                 .has_ao_fifo    = 1,
259                 .ao_scan_speed  = 10000,
260                 .fifo_size      = 512,
261                 .ranges         = &cb_pcidas_ranges,
262                 .trimpot        = AD8402,
263                 .has_dac08      = 1,
264                 .is_1602        = 1,
265         }, {
266                 .name           = "pci-das1200",
267                 .device_id      = 0xF,
268                 .ai_nchan       = 16,
269                 .ai_bits        = 12,
270                 .ai_speed       = 3200,
271                 .ao_nchan       = 2,
272                 .fifo_size      = 1024,
273                 .ranges         = &cb_pcidas_ranges,
274                 .trimpot        = AD7376,
275         }, {
276                 .name           = "pci-das1602/12",
277                 .device_id      = 0x10,
278                 .ai_nchan       = 16,
279                 .ai_bits        = 12,
280                 .ai_speed       = 3200,
281                 .ao_nchan       = 2,
282                 .has_ao_fifo    = 1,
283                 .ao_scan_speed  = 4000,
284                 .fifo_size      = 1024,
285                 .ranges         = &cb_pcidas_ranges,
286                 .trimpot        = AD7376,
287                 .is_1602        = 1,
288         }, {
289                 .name           = "pci-das1200/jr",
290                 .device_id      = 0x19,
291                 .ai_nchan       = 16,
292                 .ai_bits        = 12,
293                 .ai_speed       = 3200,
294                 .fifo_size      = 1024,
295                 .ranges         = &cb_pcidas_ranges,
296                 .trimpot        = AD7376,
297         }, {
298                 .name           = "pci-das1602/16/jr",
299                 .device_id      = 0x1C,
300                 .ai_nchan       = 16,
301                 .ai_bits        = 16,
302                 .ai_speed       = 5000,
303                 .fifo_size      = 512,
304                 .ranges         = &cb_pcidas_ranges,
305                 .trimpot        = AD8402,
306                 .has_dac08      = 1,
307                 .is_1602        = 1,
308         }, {
309                 .name           = "pci-das1000",
310                 .device_id      = 0x4C,
311                 .ai_nchan       = 16,
312                 .ai_bits        = 12,
313                 .ai_speed       = 4000,
314                 .fifo_size      = 1024,
315                 .ranges         = &cb_pcidas_ranges,
316                 .trimpot        = AD7376,
317         }, {
318                 .name           = "pci-das1001",
319                 .device_id      = 0x1a,
320                 .ai_nchan       = 16,
321                 .ai_bits        = 12,
322                 .ai_speed       = 6800,
323                 .ao_nchan       = 2,
324                 .fifo_size      = 1024,
325                 .ranges         = &cb_pcidas_alt_ranges,
326                 .trimpot        = AD7376,
327         }, {
328                 .name           = "pci-das1002",
329                 .device_id      = 0x1b,
330                 .ai_nchan       = 16,
331                 .ai_bits        = 12,
332                 .ai_speed       = 6800,
333                 .ao_nchan       = 2,
334                 .fifo_size      = 1024,
335                 .ranges         = &cb_pcidas_ranges,
336                 .trimpot        = AD7376,
337         },
338 };
339
340 struct cb_pcidas_private {
341         /* base addresses */
342         unsigned long s5933_config;
343         unsigned long control_status;
344         unsigned long adc_fifo;
345         unsigned long pacer_counter_dio;
346         unsigned long ao_registers;
347         /* divisors of master clock for analog input pacing */
348         unsigned int divisor1;
349         unsigned int divisor2;
350         /* number of analog input samples remaining */
351         unsigned int count;
352         /* bits to write to registers */
353         unsigned int adc_fifo_bits;
354         unsigned int s5933_intcsr_bits;
355         unsigned int ao_control_bits;
356         /* fifo buffers */
357         short ai_buffer[AI_BUFFER_SIZE];
358         short ao_buffer[AO_BUFFER_SIZE];
359         /* divisors of master clock for analog output pacing */
360         unsigned int ao_divisor1;
361         unsigned int ao_divisor2;
362         /* number of analog output samples remaining */
363         unsigned int ao_count;
364         /* cached values for readback */
365         int ao_value[2];
366         unsigned int caldac_value[NUM_CHANNELS_8800];
367         unsigned int trimpot_value[NUM_CHANNELS_8402];
368         unsigned int dac08_value;
369         unsigned int calibration_source;
370 };
371
372 static inline unsigned int cal_enable_bits(struct comedi_device *dev)
373 {
374         struct cb_pcidas_private *devpriv = dev->private;
375
376         return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source);
377 }
378
379 static int cb_pcidas_ai_rinsn(struct comedi_device *dev,
380                               struct comedi_subdevice *s,
381                               struct comedi_insn *insn, unsigned int *data)
382 {
383         struct cb_pcidas_private *devpriv = dev->private;
384         unsigned int chan = CR_CHAN(insn->chanspec);
385         unsigned int range = CR_RANGE(insn->chanspec);
386         unsigned int aref = CR_AREF(insn->chanspec);
387         unsigned int bits;
388         int n, i;
389
390         /* enable calibration input if appropriate */
391         if (insn->chanspec & CR_ALT_SOURCE) {
392                 outw(cal_enable_bits(dev),
393                      devpriv->control_status + CALIBRATION_REG);
394                 chan = 0;
395         } else {
396                 outw(0, devpriv->control_status + CALIBRATION_REG);
397         }
398
399         /* set mux limits and gain */
400         bits = BEGIN_SCAN(chan) | END_SCAN(chan) | GAIN_BITS(range);
401         /* set unipolar/bipolar */
402         if (range & IS_UNIPOLAR)
403                 bits |= UNIP;
404         /* set single-ended/differential */
405         if (aref != AREF_DIFF)
406                 bits |= SE;
407         outw(bits, devpriv->control_status + ADCMUX_CONT);
408
409         /* clear fifo */
410         outw(0, devpriv->adc_fifo + ADCFIFOCLR);
411
412         /* convert n samples */
413         for (n = 0; n < insn->n; n++) {
414                 /* trigger conversion */
415                 outw(0, devpriv->adc_fifo + ADCDATA);
416
417                 /* wait for conversion to end */
418                 /* return -ETIMEDOUT if there is a timeout */
419                 for (i = 0; i < 10000; i++) {
420                         if (inw(devpriv->control_status + ADCMUX_CONT) & EOC)
421                                 break;
422                 }
423                 if (i == 10000)
424                         return -ETIMEDOUT;
425
426                 /* read data */
427                 data[n] = inw(devpriv->adc_fifo + ADCDATA);
428         }
429
430         /* return the number of samples read/written */
431         return n;
432 }
433
434 static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
435                           struct comedi_insn *insn, unsigned int *data)
436 {
437         struct cb_pcidas_private *devpriv = dev->private;
438         int id = data[0];
439         unsigned int source = data[1];
440
441         switch (id) {
442         case INSN_CONFIG_ALT_SOURCE:
443                 if (source >= 8) {
444                         dev_err(dev->class_dev,
445                                 "invalid calibration source: %i\n",
446                                 source);
447                         return -EINVAL;
448                 }
449                 devpriv->calibration_source = source;
450                 break;
451         default:
452                 return -EINVAL;
453                 break;
454         }
455         return insn->n;
456 }
457
458 /* analog output insn for pcidas-1000 and 1200 series */
459 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev,
460                                      struct comedi_subdevice *s,
461                                      struct comedi_insn *insn,
462                                      unsigned int *data)
463 {
464         struct cb_pcidas_private *devpriv = dev->private;
465         unsigned int chan = CR_CHAN(insn->chanspec);
466         unsigned int range = CR_RANGE(insn->chanspec);
467         unsigned long flags;
468
469         /* set channel and range */
470         spin_lock_irqsave(&dev->spinlock, flags);
471         devpriv->ao_control_bits &= (~DAC_MODE_UPDATE_BOTH &
472                                      ~DAC_RANGE_MASK(chan));
473         devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range));
474         outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
475         spin_unlock_irqrestore(&dev->spinlock, flags);
476
477         /* remember value for readback */
478         devpriv->ao_value[chan] = data[0];
479
480         /* send data */
481         outw(data[0], devpriv->ao_registers + DAC_DATA_REG(chan));
482
483         return insn->n;
484 }
485
486 /* analog output insn for pcidas-1602 series */
487 static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev,
488                                    struct comedi_subdevice *s,
489                                    struct comedi_insn *insn, unsigned int *data)
490 {
491         struct cb_pcidas_private *devpriv = dev->private;
492         unsigned int chan = CR_CHAN(insn->chanspec);
493         unsigned int range = CR_RANGE(insn->chanspec);
494         unsigned long flags;
495
496         /* clear dac fifo */
497         outw(0, devpriv->ao_registers + DACFIFOCLR);
498
499         /* set channel and range */
500         spin_lock_irqsave(&dev->spinlock, flags);
501         devpriv->ao_control_bits &= (~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) &
502                                      ~DAC_RANGE_MASK(chan) & ~DAC_PACER_MASK);
503         devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range) |
504                                      DAC_CHAN_EN(chan) | DAC_START);
505         outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
506         spin_unlock_irqrestore(&dev->spinlock, flags);
507
508         /* remember value for readback */
509         devpriv->ao_value[chan] = data[0];
510
511         /* send data */
512         outw(data[0], devpriv->ao_registers + DACDATA);
513
514         return insn->n;
515 }
516
517 static int cb_pcidas_ao_readback_insn(struct comedi_device *dev,
518                                       struct comedi_subdevice *s,
519                                       struct comedi_insn *insn,
520                                       unsigned int *data)
521 {
522         struct cb_pcidas_private *devpriv = dev->private;
523
524         data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
525
526         return 1;
527 }
528
529 static int wait_for_nvram_ready(unsigned long s5933_base_addr)
530 {
531         static const int timeout = 1000;
532         unsigned int i;
533
534         for (i = 0; i < timeout; i++) {
535                 if ((inb(s5933_base_addr +
536                          AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
537                     == 0)
538                         return 0;
539                 udelay(1);
540         }
541         return -1;
542 }
543
544 static int nvram_read(struct comedi_device *dev, unsigned int address,
545                         uint8_t *data)
546 {
547         struct cb_pcidas_private *devpriv = dev->private;
548         unsigned long iobase = devpriv->s5933_config;
549
550         if (wait_for_nvram_ready(iobase) < 0)
551                 return -ETIMEDOUT;
552
553         outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
554              iobase + AMCC_OP_REG_MCSR_NVCMD);
555         outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
556         outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
557              iobase + AMCC_OP_REG_MCSR_NVCMD);
558         outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
559         outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
560
561         if (wait_for_nvram_ready(iobase) < 0)
562                 return -ETIMEDOUT;
563
564         *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
565
566         return 0;
567 }
568
569 static int eeprom_read_insn(struct comedi_device *dev,
570                             struct comedi_subdevice *s,
571                             struct comedi_insn *insn, unsigned int *data)
572 {
573         uint8_t nvram_data;
574         int retval;
575
576         retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
577         if (retval < 0)
578                 return retval;
579
580         data[0] = nvram_data;
581
582         return 1;
583 }
584
585 static void write_calibration_bitstream(struct comedi_device *dev,
586                                         unsigned int register_bits,
587                                         unsigned int bitstream,
588                                         unsigned int bitstream_length)
589 {
590         struct cb_pcidas_private *devpriv = dev->private;
591         static const int write_delay = 1;
592         unsigned int bit;
593
594         for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
595                 if (bitstream & bit)
596                         register_bits |= SERIAL_DATA_IN_BIT;
597                 else
598                         register_bits &= ~SERIAL_DATA_IN_BIT;
599                 udelay(write_delay);
600                 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
601         }
602 }
603
604 static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
605                              uint8_t value)
606 {
607         struct cb_pcidas_private *devpriv = dev->private;
608         static const int num_caldac_channels = 8;
609         static const int bitstream_length = 11;
610         unsigned int bitstream = ((address & 0x7) << 8) | value;
611         static const int caldac_8800_udelay = 1;
612
613         if (address >= num_caldac_channels) {
614                 comedi_error(dev, "illegal caldac channel");
615                 return -1;
616         }
617
618         if (value == devpriv->caldac_value[address])
619                 return 1;
620
621         devpriv->caldac_value[address] = value;
622
623         write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
624                                     bitstream_length);
625
626         udelay(caldac_8800_udelay);
627         outw(cal_enable_bits(dev) | SELECT_8800_BIT,
628              devpriv->control_status + CALIBRATION_REG);
629         udelay(caldac_8800_udelay);
630         outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
631
632         return 1;
633 }
634
635 static int caldac_write_insn(struct comedi_device *dev,
636                              struct comedi_subdevice *s,
637                              struct comedi_insn *insn, unsigned int *data)
638 {
639         const unsigned int channel = CR_CHAN(insn->chanspec);
640
641         return caldac_8800_write(dev, channel, data[0]);
642 }
643
644 static int caldac_read_insn(struct comedi_device *dev,
645                             struct comedi_subdevice *s,
646                             struct comedi_insn *insn, unsigned int *data)
647 {
648         struct cb_pcidas_private *devpriv = dev->private;
649
650         data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)];
651
652         return 1;
653 }
654
655 /* 1602/16 pregain offset */
656 static void dac08_write(struct comedi_device *dev, unsigned int value)
657 {
658         struct cb_pcidas_private *devpriv = dev->private;
659         unsigned long cal_reg;
660
661         if (devpriv->dac08_value != value) {
662                 devpriv->dac08_value = value;
663
664                 cal_reg = devpriv->control_status + CALIBRATION_REG;
665
666                 value &= 0xff;
667                 value |= cal_enable_bits(dev);
668
669                 /* latch the new value into the caldac */
670                 outw(value, cal_reg);
671                 udelay(1);
672                 outw(value | SELECT_DAC08_BIT, cal_reg);
673                 udelay(1);
674                 outw(value, cal_reg);
675                 udelay(1);
676         }
677 }
678
679 static int dac08_write_insn(struct comedi_device *dev,
680                             struct comedi_subdevice *s,
681                             struct comedi_insn *insn, unsigned int *data)
682 {
683         int i;
684
685         for (i = 0; i < insn->n; i++)
686                 dac08_write(dev, data[i]);
687
688         return insn->n;
689 }
690
691 static int dac08_read_insn(struct comedi_device *dev,
692                            struct comedi_subdevice *s, struct comedi_insn *insn,
693                            unsigned int *data)
694 {
695         struct cb_pcidas_private *devpriv = dev->private;
696
697         data[0] = devpriv->dac08_value;
698
699         return 1;
700 }
701
702 static int trimpot_7376_write(struct comedi_device *dev, uint8_t value)
703 {
704         struct cb_pcidas_private *devpriv = dev->private;
705         static const int bitstream_length = 7;
706         unsigned int bitstream = value & 0x7f;
707         unsigned int register_bits;
708         static const int ad7376_udelay = 1;
709
710         register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
711         udelay(ad7376_udelay);
712         outw(register_bits, devpriv->control_status + CALIBRATION_REG);
713
714         write_calibration_bitstream(dev, register_bits, bitstream,
715                                     bitstream_length);
716
717         udelay(ad7376_udelay);
718         outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
719
720         return 0;
721 }
722
723 /* For 1602/16 only
724  * ch 0 : adc gain
725  * ch 1 : adc postgain offset */
726 static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
727                               uint8_t value)
728 {
729         struct cb_pcidas_private *devpriv = dev->private;
730         static const int bitstream_length = 10;
731         unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
732         unsigned int register_bits;
733         static const int ad8402_udelay = 1;
734
735         register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
736         udelay(ad8402_udelay);
737         outw(register_bits, devpriv->control_status + CALIBRATION_REG);
738
739         write_calibration_bitstream(dev, register_bits, bitstream,
740                                     bitstream_length);
741
742         udelay(ad8402_udelay);
743         outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
744
745         return 0;
746 }
747
748 static int cb_pcidas_trimpot_write(struct comedi_device *dev,
749                                    unsigned int channel, unsigned int value)
750 {
751         const struct cb_pcidas_board *thisboard = comedi_board(dev);
752         struct cb_pcidas_private *devpriv = dev->private;
753
754         if (devpriv->trimpot_value[channel] == value)
755                 return 1;
756
757         devpriv->trimpot_value[channel] = value;
758         switch (thisboard->trimpot) {
759         case AD7376:
760                 trimpot_7376_write(dev, value);
761                 break;
762         case AD8402:
763                 trimpot_8402_write(dev, channel, value);
764                 break;
765         default:
766                 comedi_error(dev, "driver bug?");
767                 return -1;
768                 break;
769         }
770
771         return 1;
772 }
773
774 static int trimpot_write_insn(struct comedi_device *dev,
775                               struct comedi_subdevice *s,
776                               struct comedi_insn *insn, unsigned int *data)
777 {
778         unsigned int channel = CR_CHAN(insn->chanspec);
779
780         return cb_pcidas_trimpot_write(dev, channel, data[0]);
781 }
782
783 static int trimpot_read_insn(struct comedi_device *dev,
784                              struct comedi_subdevice *s,
785                              struct comedi_insn *insn, unsigned int *data)
786 {
787         struct cb_pcidas_private *devpriv = dev->private;
788         unsigned int channel = CR_CHAN(insn->chanspec);
789
790         data[0] = devpriv->trimpot_value[channel];
791
792         return 1;
793 }
794
795 static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
796                                 struct comedi_subdevice *s,
797                                 struct comedi_cmd *cmd)
798 {
799         const struct cb_pcidas_board *thisboard = comedi_board(dev);
800         struct cb_pcidas_private *devpriv = dev->private;
801         int err = 0;
802         int tmp;
803         int i, gain, start_chan;
804
805         /* Step 1 : check if triggers are trivially valid */
806
807         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
808         err |= cfc_check_trigger_src(&cmd->scan_begin_src,
809                                         TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
810         err |= cfc_check_trigger_src(&cmd->convert_src,
811                                         TRIG_TIMER | TRIG_NOW | TRIG_EXT);
812         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
813         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
814
815         if (err)
816                 return 1;
817
818         /* Step 2a : make sure trigger sources are unique */
819
820         err |= cfc_check_trigger_is_unique(cmd->start_src);
821         err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
822         err |= cfc_check_trigger_is_unique(cmd->convert_src);
823         err |= cfc_check_trigger_is_unique(cmd->stop_src);
824
825         /* Step 2b : and mutually compatible */
826
827         if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
828                 err |= -EINVAL;
829         if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
830                 err |= -EINVAL;
831         if (cmd->start_src == TRIG_EXT &&
832             (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))
833                 err |= -EINVAL;
834
835         if (err)
836                 return 2;
837
838         /* step 3: arguments are trivially compatible */
839
840         switch (cmd->start_src) {
841         case TRIG_EXT:
842                 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
843                 if ((cmd->start_arg
844                      & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
845                         cmd->start_arg &= ~(CR_FLAGS_MASK &
846                                                 ~(CR_EDGE | CR_INVERT));
847                         err |= -EINVAL;
848                 }
849                 if (!thisboard->is_1602 && (cmd->start_arg & CR_INVERT)) {
850                         cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
851                         err |= -EINVAL;
852                 }
853                 break;
854         default:
855                 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
856                 break;
857         }
858
859         if (cmd->scan_begin_src == TRIG_TIMER)
860                 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
861                                 thisboard->ai_speed * cmd->chanlist_len);
862
863         if (cmd->convert_src == TRIG_TIMER)
864                 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
865                                                  thisboard->ai_speed);
866
867         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
868
869         if (cmd->stop_src == TRIG_NONE)
870                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
871
872         if (err)
873                 return 3;
874
875         /* step 4: fix up any arguments */
876
877         if (cmd->scan_begin_src == TRIG_TIMER) {
878                 tmp = cmd->scan_begin_arg;
879                 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
880                                                &(devpriv->divisor1),
881                                                &(devpriv->divisor2),
882                                                &(cmd->scan_begin_arg),
883                                                cmd->flags & TRIG_ROUND_MASK);
884                 if (tmp != cmd->scan_begin_arg)
885                         err++;
886         }
887         if (cmd->convert_src == TRIG_TIMER) {
888                 tmp = cmd->convert_arg;
889                 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
890                                                &(devpriv->divisor1),
891                                                &(devpriv->divisor2),
892                                                &(cmd->convert_arg),
893                                                cmd->flags & TRIG_ROUND_MASK);
894                 if (tmp != cmd->convert_arg)
895                         err++;
896         }
897
898         if (err)
899                 return 4;
900
901         /*  check channel/gain list against card's limitations */
902         if (cmd->chanlist) {
903                 gain = CR_RANGE(cmd->chanlist[0]);
904                 start_chan = CR_CHAN(cmd->chanlist[0]);
905                 for (i = 1; i < cmd->chanlist_len; i++) {
906                         if (CR_CHAN(cmd->chanlist[i]) !=
907                             (start_chan + i) % s->n_chan) {
908                                 comedi_error(dev,
909                                              "entries in chanlist must be consecutive channels, counting upwards\n");
910                                 err++;
911                         }
912                         if (CR_RANGE(cmd->chanlist[i]) != gain) {
913                                 comedi_error(dev,
914                                              "entries in chanlist must all have the same gain\n");
915                                 err++;
916                         }
917                 }
918         }
919
920         if (err)
921                 return 5;
922
923         return 0;
924 }
925
926 static void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns,
927                                     int rounding_flags)
928 {
929         struct cb_pcidas_private *devpriv = dev->private;
930
931         i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
932                                        &(devpriv->divisor2), ns,
933                                        rounding_flags & TRIG_ROUND_MASK);
934
935         /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
936         i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1,
937                    devpriv->divisor1, 2);
938         i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2,
939                    devpriv->divisor2, 2);
940 }
941
942 static int cb_pcidas_ai_cmd(struct comedi_device *dev,
943                             struct comedi_subdevice *s)
944 {
945         const struct cb_pcidas_board *thisboard = comedi_board(dev);
946         struct cb_pcidas_private *devpriv = dev->private;
947         struct comedi_async *async = s->async;
948         struct comedi_cmd *cmd = &async->cmd;
949         unsigned int bits;
950         unsigned long flags;
951
952         /*  make sure CAL_EN_BIT is disabled */
953         outw(0, devpriv->control_status + CALIBRATION_REG);
954         /*  initialize before settings pacer source and count values */
955         outw(0, devpriv->control_status + TRIG_CONTSTAT);
956         /*  clear fifo */
957         outw(0, devpriv->adc_fifo + ADCFIFOCLR);
958
959         /*  set mux limits, gain and pacer source */
960         bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
961             END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
962             GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
963         /*  set unipolar/bipolar */
964         if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
965                 bits |= UNIP;
966         /*  set singleended/differential */
967         if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
968                 bits |= SE;
969         /*  set pacer source */
970         if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
971                 bits |= PACER_EXT_RISE;
972         else
973                 bits |= PACER_INT;
974         outw(bits, devpriv->control_status + ADCMUX_CONT);
975
976         /*  load counters */
977         if (cmd->convert_src == TRIG_TIMER)
978                 cb_pcidas_load_counters(dev, &cmd->convert_arg,
979                                         cmd->flags & TRIG_ROUND_MASK);
980         else if (cmd->scan_begin_src == TRIG_TIMER)
981                 cb_pcidas_load_counters(dev, &cmd->scan_begin_arg,
982                                         cmd->flags & TRIG_ROUND_MASK);
983
984         /*  set number of conversions */
985         if (cmd->stop_src == TRIG_COUNT)
986                 devpriv->count = cmd->chanlist_len * cmd->stop_arg;
987         /*  enable interrupts */
988         spin_lock_irqsave(&dev->spinlock, flags);
989         devpriv->adc_fifo_bits |= INTE;
990         devpriv->adc_fifo_bits &= ~INT_MASK;
991         if (cmd->flags & TRIG_WAKE_EOS) {
992                 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) {
993                         /* interrupt end of burst */
994                         devpriv->adc_fifo_bits |= INT_EOS;
995                 } else {
996                         /* interrupt fifo not empty */
997                         devpriv->adc_fifo_bits |= INT_FNE;
998                 }
999         } else {
1000                 /* interrupt fifo half full */
1001                 devpriv->adc_fifo_bits |= INT_FHF;
1002         }
1003
1004         /*  enable (and clear) interrupts */
1005         outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
1006              devpriv->control_status + INT_ADCFIFO);
1007         spin_unlock_irqrestore(&dev->spinlock, flags);
1008
1009         /*  set start trigger and burst mode */
1010         bits = 0;
1011         if (cmd->start_src == TRIG_NOW)
1012                 bits |= SW_TRIGGER;
1013         else if (cmd->start_src == TRIG_EXT) {
1014                 bits |= EXT_TRIGGER | TGEN | XTRCL;
1015                 if (thisboard->is_1602) {
1016                         if (cmd->start_arg & CR_INVERT)
1017                                 bits |= TGPOL;
1018                         if (cmd->start_arg & CR_EDGE)
1019                                 bits |= TGSEL;
1020                 }
1021         } else {
1022                 comedi_error(dev, "bug!");
1023                 return -1;
1024         }
1025         if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1026                 bits |= BURSTE;
1027         outw(bits, devpriv->control_status + TRIG_CONTSTAT);
1028
1029         return 0;
1030 }
1031
1032 static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
1033                                 struct comedi_subdevice *s,
1034                                 struct comedi_cmd *cmd)
1035 {
1036         const struct cb_pcidas_board *thisboard = comedi_board(dev);
1037         struct cb_pcidas_private *devpriv = dev->private;
1038         int err = 0;
1039         int tmp;
1040
1041         /* Step 1 : check if triggers are trivially valid */
1042
1043         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT);
1044         err |= cfc_check_trigger_src(&cmd->scan_begin_src,
1045                                         TRIG_TIMER | TRIG_EXT);
1046         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
1047         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1048         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1049
1050         if (err)
1051                 return 1;
1052
1053         /* Step 2a : make sure trigger sources are unique */
1054
1055         err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
1056         err |= cfc_check_trigger_is_unique(cmd->stop_src);
1057
1058         /* Step 2b : and mutually compatible */
1059
1060         if (err)
1061                 return 2;
1062
1063         /* Step 3: check if arguments are trivially valid */
1064
1065         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1066
1067         if (cmd->scan_begin_src == TRIG_TIMER)
1068                 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1069                                                  thisboard->ao_scan_speed);
1070
1071         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1072
1073         if (cmd->stop_src == TRIG_NONE)
1074                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1075
1076         if (err)
1077                 return 3;
1078
1079         /* step 4: fix up any arguments */
1080
1081         if (cmd->scan_begin_src == TRIG_TIMER) {
1082                 tmp = cmd->scan_begin_arg;
1083                 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1084                                                &(devpriv->ao_divisor1),
1085                                                &(devpriv->ao_divisor2),
1086                                                &(cmd->scan_begin_arg),
1087                                                cmd->flags & TRIG_ROUND_MASK);
1088                 if (tmp != cmd->scan_begin_arg)
1089                         err++;
1090         }
1091
1092         if (err)
1093                 return 4;
1094
1095         /*  check channel/gain list against card's limitations */
1096         if (cmd->chanlist && cmd->chanlist_len > 1) {
1097                 if (CR_CHAN(cmd->chanlist[0]) != 0 ||
1098                     CR_CHAN(cmd->chanlist[1]) != 1) {
1099                         comedi_error(dev,
1100                                      "channels must be ordered channel 0, channel 1 in chanlist\n");
1101                         err++;
1102                 }
1103         }
1104
1105         if (err)
1106                 return 5;
1107
1108         return 0;
1109 }
1110
1111 /* cancel analog input command */
1112 static int cb_pcidas_cancel(struct comedi_device *dev,
1113                             struct comedi_subdevice *s)
1114 {
1115         struct cb_pcidas_private *devpriv = dev->private;
1116         unsigned long flags;
1117
1118         spin_lock_irqsave(&dev->spinlock, flags);
1119         /*  disable interrupts */
1120         devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
1121         outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1122         spin_unlock_irqrestore(&dev->spinlock, flags);
1123
1124         /*  disable start trigger source and burst mode */
1125         outw(0, devpriv->control_status + TRIG_CONTSTAT);
1126         /*  software pacer source */
1127         outw(0, devpriv->control_status + ADCMUX_CONT);
1128
1129         return 0;
1130 }
1131
1132 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1133                                 struct comedi_subdevice *s,
1134                                 unsigned int trig_num)
1135 {
1136         const struct cb_pcidas_board *thisboard = comedi_board(dev);
1137         struct cb_pcidas_private *devpriv = dev->private;
1138         unsigned int num_bytes, num_points = thisboard->fifo_size;
1139         struct comedi_async *async = s->async;
1140         struct comedi_cmd *cmd = &s->async->cmd;
1141         unsigned long flags;
1142
1143         if (trig_num != 0)
1144                 return -EINVAL;
1145
1146         /*  load up fifo */
1147         if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
1148                 num_points = devpriv->ao_count;
1149
1150         num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1151                                                num_points * sizeof(short));
1152         num_points = num_bytes / sizeof(short);
1153
1154         if (cmd->stop_src == TRIG_COUNT)
1155                 devpriv->ao_count -= num_points;
1156         /*  write data to board's fifo */
1157         outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
1158
1159         /*  enable dac half-full and empty interrupts */
1160         spin_lock_irqsave(&dev->spinlock, flags);
1161         devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
1162
1163         /*  enable and clear interrupts */
1164         outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
1165              devpriv->control_status + INT_ADCFIFO);
1166
1167         /*  start dac */
1168         devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1169         outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1170
1171         spin_unlock_irqrestore(&dev->spinlock, flags);
1172
1173         async->inttrig = NULL;
1174
1175         return 0;
1176 }
1177
1178 static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1179                             struct comedi_subdevice *s)
1180 {
1181         struct cb_pcidas_private *devpriv = dev->private;
1182         struct comedi_async *async = s->async;
1183         struct comedi_cmd *cmd = &async->cmd;
1184         unsigned int i;
1185         unsigned long flags;
1186
1187         /*  set channel limits, gain */
1188         spin_lock_irqsave(&dev->spinlock, flags);
1189         for (i = 0; i < cmd->chanlist_len; i++) {
1190                 /*  enable channel */
1191                 devpriv->ao_control_bits |=
1192                     DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
1193                 /*  set range */
1194                 devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
1195                                                       CR_RANGE(cmd->
1196                                                                chanlist[i]));
1197         }
1198
1199         /*  disable analog out before settings pacer source and count values */
1200         outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1201         spin_unlock_irqrestore(&dev->spinlock, flags);
1202
1203         /*  clear fifo */
1204         outw(0, devpriv->ao_registers + DACFIFOCLR);
1205
1206         /*  load counters */
1207         if (cmd->scan_begin_src == TRIG_TIMER) {
1208                 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1209                                                &(devpriv->ao_divisor1),
1210                                                &(devpriv->ao_divisor2),
1211                                                &(cmd->scan_begin_arg),
1212                                                cmd->flags);
1213
1214                 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1215                 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1,
1216                            devpriv->ao_divisor1, 2);
1217                 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2,
1218                            devpriv->ao_divisor2, 2);
1219         }
1220         /*  set number of conversions */
1221         if (cmd->stop_src == TRIG_COUNT)
1222                 devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
1223         /*  set pacer source */
1224         spin_lock_irqsave(&dev->spinlock, flags);
1225         switch (cmd->scan_begin_src) {
1226         case TRIG_TIMER:
1227                 devpriv->ao_control_bits |= DAC_PACER_INT;
1228                 break;
1229         case TRIG_EXT:
1230                 devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1231                 break;
1232         default:
1233                 spin_unlock_irqrestore(&dev->spinlock, flags);
1234                 comedi_error(dev, "error setting dac pacer source");
1235                 return -1;
1236                 break;
1237         }
1238         spin_unlock_irqrestore(&dev->spinlock, flags);
1239
1240         async->inttrig = cb_pcidas_ao_inttrig;
1241
1242         return 0;
1243 }
1244
1245 /* cancel analog output command */
1246 static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1247                                struct comedi_subdevice *s)
1248 {
1249         struct cb_pcidas_private *devpriv = dev->private;
1250         unsigned long flags;
1251
1252         spin_lock_irqsave(&dev->spinlock, flags);
1253         /*  disable interrupts */
1254         devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
1255         outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1256
1257         /*  disable output */
1258         devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1259         outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1260         spin_unlock_irqrestore(&dev->spinlock, flags);
1261
1262         return 0;
1263 }
1264
1265 static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
1266 {
1267         const struct cb_pcidas_board *thisboard = comedi_board(dev);
1268         struct cb_pcidas_private *devpriv = dev->private;
1269         struct comedi_subdevice *s = dev->write_subdev;
1270         struct comedi_async *async = s->async;
1271         struct comedi_cmd *cmd = &async->cmd;
1272         unsigned int half_fifo = thisboard->fifo_size / 2;
1273         unsigned int num_points;
1274         unsigned long flags;
1275
1276         async->events = 0;
1277
1278         if (status & DAEMI) {
1279                 /*  clear dac empty interrupt latch */
1280                 spin_lock_irqsave(&dev->spinlock, flags);
1281                 outw(devpriv->adc_fifo_bits | DAEMI,
1282                      devpriv->control_status + INT_ADCFIFO);
1283                 spin_unlock_irqrestore(&dev->spinlock, flags);
1284                 if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
1285                         if (cmd->stop_src == TRIG_NONE ||
1286                             (cmd->stop_src == TRIG_COUNT
1287                              && devpriv->ao_count)) {
1288                                 comedi_error(dev, "dac fifo underflow");
1289                                 cb_pcidas_ao_cancel(dev, s);
1290                                 async->events |= COMEDI_CB_ERROR;
1291                         }
1292                         async->events |= COMEDI_CB_EOA;
1293                 }
1294         } else if (status & DAHFI) {
1295                 unsigned int num_bytes;
1296
1297                 /*  figure out how many points we are writing to fifo */
1298                 num_points = half_fifo;
1299                 if (cmd->stop_src == TRIG_COUNT &&
1300                     devpriv->ao_count < num_points)
1301                         num_points = devpriv->ao_count;
1302                 num_bytes =
1303                     cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1304                                                num_points * sizeof(short));
1305                 num_points = num_bytes / sizeof(short);
1306
1307                 if (async->cmd.stop_src == TRIG_COUNT)
1308                         devpriv->ao_count -= num_points;
1309                 /*  write data to board's fifo */
1310                 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
1311                       num_points);
1312                 /*  clear half-full interrupt latch */
1313                 spin_lock_irqsave(&dev->spinlock, flags);
1314                 outw(devpriv->adc_fifo_bits | DAHFI,
1315                      devpriv->control_status + INT_ADCFIFO);
1316                 spin_unlock_irqrestore(&dev->spinlock, flags);
1317         }
1318
1319         comedi_event(dev, s);
1320 }
1321
1322 static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1323 {
1324         struct comedi_device *dev = (struct comedi_device *)d;
1325         const struct cb_pcidas_board *thisboard = comedi_board(dev);
1326         struct cb_pcidas_private *devpriv = dev->private;
1327         struct comedi_subdevice *s = dev->read_subdev;
1328         struct comedi_async *async;
1329         int status, s5933_status;
1330         int half_fifo = thisboard->fifo_size / 2;
1331         unsigned int num_samples, i;
1332         static const int timeout = 10000;
1333         unsigned long flags;
1334
1335         if (dev->attached == 0)
1336                 return IRQ_NONE;
1337
1338         async = s->async;
1339         async->events = 0;
1340
1341         s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1342
1343         if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
1344                 return IRQ_NONE;
1345
1346         /*  make sure mailbox 4 is empty */
1347         inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1348         /*  clear interrupt on amcc s5933 */
1349         outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1350              devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1351
1352         status = inw(devpriv->control_status + INT_ADCFIFO);
1353
1354         /*  check for analog output interrupt */
1355         if (status & (DAHFI | DAEMI))
1356                 handle_ao_interrupt(dev, status);
1357         /*  check for analog input interrupts */
1358         /*  if fifo half-full */
1359         if (status & ADHFI) {
1360                 /*  read data */
1361                 num_samples = half_fifo;
1362                 if (async->cmd.stop_src == TRIG_COUNT &&
1363                     num_samples > devpriv->count) {
1364                         num_samples = devpriv->count;
1365                 }
1366                 insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
1367                      num_samples);
1368                 cfc_write_array_to_buffer(s, devpriv->ai_buffer,
1369                                           num_samples * sizeof(short));
1370                 devpriv->count -= num_samples;
1371                 if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) {
1372                         async->events |= COMEDI_CB_EOA;
1373                         cb_pcidas_cancel(dev, s);
1374                 }
1375                 /*  clear half-full interrupt latch */
1376                 spin_lock_irqsave(&dev->spinlock, flags);
1377                 outw(devpriv->adc_fifo_bits | INT,
1378                      devpriv->control_status + INT_ADCFIFO);
1379                 spin_unlock_irqrestore(&dev->spinlock, flags);
1380                 /*  else if fifo not empty */
1381         } else if (status & (ADNEI | EOBI)) {
1382                 for (i = 0; i < timeout; i++) {
1383                         /*  break if fifo is empty */
1384                         if ((ADNE & inw(devpriv->control_status +
1385                                         INT_ADCFIFO)) == 0)
1386                                 break;
1387                         cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
1388                         if (async->cmd.stop_src == TRIG_COUNT &&
1389                             --devpriv->count == 0) {
1390                                 /* end of acquisition */
1391                                 cb_pcidas_cancel(dev, s);
1392                                 async->events |= COMEDI_CB_EOA;
1393                                 break;
1394                         }
1395                 }
1396                 /*  clear not-empty interrupt latch */
1397                 spin_lock_irqsave(&dev->spinlock, flags);
1398                 outw(devpriv->adc_fifo_bits | INT,
1399                      devpriv->control_status + INT_ADCFIFO);
1400                 spin_unlock_irqrestore(&dev->spinlock, flags);
1401         } else if (status & EOAI) {
1402                 comedi_error(dev,
1403                              "bug! encountered end of acquisition interrupt?");
1404                 /*  clear EOA interrupt latch */
1405                 spin_lock_irqsave(&dev->spinlock, flags);
1406                 outw(devpriv->adc_fifo_bits | EOAI,
1407                      devpriv->control_status + INT_ADCFIFO);
1408                 spin_unlock_irqrestore(&dev->spinlock, flags);
1409         }
1410         /* check for fifo overflow */
1411         if (status & LADFUL) {
1412                 comedi_error(dev, "fifo overflow");
1413                 /*  clear overflow interrupt latch */
1414                 spin_lock_irqsave(&dev->spinlock, flags);
1415                 outw(devpriv->adc_fifo_bits | LADFUL,
1416                      devpriv->control_status + INT_ADCFIFO);
1417                 spin_unlock_irqrestore(&dev->spinlock, flags);
1418                 cb_pcidas_cancel(dev, s);
1419                 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1420         }
1421
1422         comedi_event(dev, s);
1423
1424         return IRQ_HANDLED;
1425 }
1426
1427 static const void *cb_pcidas_find_boardinfo(struct comedi_device *dev,
1428                                             struct pci_dev *pcidev)
1429 {
1430         const struct cb_pcidas_board *thisboard;
1431         int i;
1432
1433         for (i = 0; i < ARRAY_SIZE(cb_pcidas_boards); i++) {
1434                 thisboard = &cb_pcidas_boards[i];
1435                 if (thisboard->device_id == pcidev->device)
1436                         return thisboard;
1437         }
1438         return NULL;
1439 }
1440
1441 static int cb_pcidas_auto_attach(struct comedi_device *dev,
1442                                            unsigned long context_unused)
1443 {
1444         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1445         const struct cb_pcidas_board *thisboard;
1446         struct cb_pcidas_private *devpriv;
1447         struct comedi_subdevice *s;
1448         int i;
1449         int ret;
1450
1451         thisboard = cb_pcidas_find_boardinfo(dev, pcidev);
1452         if (!thisboard)
1453                 return -ENODEV;
1454         dev->board_ptr  = thisboard;
1455         dev->board_name = thisboard->name;
1456
1457         devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1458         if (!devpriv)
1459                 return -ENOMEM;
1460         dev->private = devpriv;
1461
1462         ret = comedi_pci_enable(pcidev, dev->board_name);
1463         if (ret)
1464                 return ret;
1465
1466         devpriv->s5933_config = pci_resource_start(pcidev, 0);
1467         devpriv->control_status = pci_resource_start(pcidev, 1);
1468         devpriv->adc_fifo = pci_resource_start(pcidev, 2);
1469         devpriv->pacer_counter_dio = pci_resource_start(pcidev, 3);
1470         if (thisboard->ao_nchan)
1471                 devpriv->ao_registers = pci_resource_start(pcidev, 4);
1472
1473         /*  disable and clear interrupts on amcc s5933 */
1474         outl(INTCSR_INBOX_INTR_STATUS,
1475              devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1476
1477         if (request_irq(pcidev->irq, cb_pcidas_interrupt,
1478                         IRQF_SHARED, dev->driver->driver_name, dev)) {
1479                 dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
1480                         pcidev->irq);
1481                 return -EINVAL;
1482         }
1483         dev->irq = pcidev->irq;
1484
1485         ret = comedi_alloc_subdevices(dev, 7);
1486         if (ret)
1487                 return ret;
1488
1489         s = &dev->subdevices[0];
1490         /* analog input subdevice */
1491         dev->read_subdev = s;
1492         s->type = COMEDI_SUBD_AI;
1493         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
1494         /* WARNING: Number of inputs in differential mode is ignored */
1495         s->n_chan = thisboard->ai_nchan;
1496         s->len_chanlist = thisboard->ai_nchan;
1497         s->maxdata = (1 << thisboard->ai_bits) - 1;
1498         s->range_table = thisboard->ranges;
1499         s->insn_read = cb_pcidas_ai_rinsn;
1500         s->insn_config = ai_config_insn;
1501         s->do_cmd = cb_pcidas_ai_cmd;
1502         s->do_cmdtest = cb_pcidas_ai_cmdtest;
1503         s->cancel = cb_pcidas_cancel;
1504
1505         /* analog output subdevice */
1506         s = &dev->subdevices[1];
1507         if (thisboard->ao_nchan) {
1508                 s->type = COMEDI_SUBD_AO;
1509                 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1510                 s->n_chan = thisboard->ao_nchan;
1511                 /*
1512                  * analog out resolution is the same as
1513                  * analog input resolution, so use ai_bits
1514                  */
1515                 s->maxdata = (1 << thisboard->ai_bits) - 1;
1516                 s->range_table = &cb_pcidas_ao_ranges;
1517                 s->insn_read = cb_pcidas_ao_readback_insn;
1518                 if (thisboard->has_ao_fifo) {
1519                         dev->write_subdev = s;
1520                         s->subdev_flags |= SDF_CMD_WRITE;
1521                         s->insn_write = cb_pcidas_ao_fifo_winsn;
1522                         s->do_cmdtest = cb_pcidas_ao_cmdtest;
1523                         s->do_cmd = cb_pcidas_ao_cmd;
1524                         s->cancel = cb_pcidas_ao_cancel;
1525                 } else {
1526                         s->insn_write = cb_pcidas_ao_nofifo_winsn;
1527                 }
1528         } else {
1529                 s->type = COMEDI_SUBD_UNUSED;
1530         }
1531
1532         /* 8255 */
1533         s = &dev->subdevices[2];
1534         ret = subdev_8255_init(dev, s, NULL,
1535                                devpriv->pacer_counter_dio + DIO_8255);
1536         if (ret)
1537                 return ret;
1538
1539         /*  serial EEPROM, */
1540         s = &dev->subdevices[3];
1541         s->type = COMEDI_SUBD_MEMORY;
1542         s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
1543         s->n_chan = 256;
1544         s->maxdata = 0xff;
1545         s->insn_read = eeprom_read_insn;
1546
1547         /*  8800 caldac */
1548         s = &dev->subdevices[4];
1549         s->type = COMEDI_SUBD_CALIB;
1550         s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1551         s->n_chan = NUM_CHANNELS_8800;
1552         s->maxdata = 0xff;
1553         s->insn_read = caldac_read_insn;
1554         s->insn_write = caldac_write_insn;
1555         for (i = 0; i < s->n_chan; i++)
1556                 caldac_8800_write(dev, i, s->maxdata / 2);
1557
1558         /*  trim potentiometer */
1559         s = &dev->subdevices[5];
1560         s->type = COMEDI_SUBD_CALIB;
1561         s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1562         if (thisboard->trimpot == AD7376) {
1563                 s->n_chan = NUM_CHANNELS_7376;
1564                 s->maxdata = 0x7f;
1565         } else {
1566                 s->n_chan = NUM_CHANNELS_8402;
1567                 s->maxdata = 0xff;
1568         }
1569         s->insn_read = trimpot_read_insn;
1570         s->insn_write = trimpot_write_insn;
1571         for (i = 0; i < s->n_chan; i++)
1572                 cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
1573
1574         /*  dac08 caldac */
1575         s = &dev->subdevices[6];
1576         if (thisboard->has_dac08) {
1577                 s->type = COMEDI_SUBD_CALIB;
1578                 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1579                 s->n_chan = NUM_CHANNELS_DAC08;
1580                 s->insn_read = dac08_read_insn;
1581                 s->insn_write = dac08_write_insn;
1582                 s->maxdata = 0xff;
1583                 dac08_write(dev, s->maxdata / 2);
1584         } else
1585                 s->type = COMEDI_SUBD_UNUSED;
1586
1587         /*  make sure mailbox 4 is empty */
1588         inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1589         /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1590         devpriv->s5933_intcsr_bits =
1591             INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1592             INTCSR_INBOX_FULL_INT;
1593         /*  clear and enable interrupt on amcc s5933 */
1594         outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1595              devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1596
1597         dev_info(dev->class_dev, "%s: %s attached\n",
1598                 dev->driver->driver_name, dev->board_name);
1599
1600         return 0;
1601 }
1602
1603 static void cb_pcidas_detach(struct comedi_device *dev)
1604 {
1605         struct cb_pcidas_private *devpriv = dev->private;
1606         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1607
1608         if (devpriv) {
1609                 if (devpriv->s5933_config) {
1610                         outl(INTCSR_INBOX_INTR_STATUS,
1611                              devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1612                 }
1613         }
1614         if (dev->irq)
1615                 free_irq(dev->irq, dev);
1616         if (dev->subdevices)
1617                 subdev_8255_cleanup(dev, &dev->subdevices[2]);
1618         if (pcidev) {
1619                 if (devpriv->s5933_config)
1620                         comedi_pci_disable(pcidev);
1621         }
1622 }
1623
1624 static struct comedi_driver cb_pcidas_driver = {
1625         .driver_name    = "cb_pcidas",
1626         .module         = THIS_MODULE,
1627         .auto_attach    = cb_pcidas_auto_attach,
1628         .detach         = cb_pcidas_detach,
1629 };
1630
1631 static int cb_pcidas_pci_probe(struct pci_dev *dev,
1632                                          const struct pci_device_id *ent)
1633 {
1634         return comedi_pci_auto_config(dev, &cb_pcidas_driver);
1635 }
1636
1637 static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = {
1638         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0001) },
1639         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000f) },
1640         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0010) },
1641         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0019) },
1642         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001c) },
1643         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x004c) },
1644         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001a) },
1645         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001b) },
1646         { 0 }
1647 };
1648 MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
1649
1650 static struct pci_driver cb_pcidas_pci_driver = {
1651         .name           = "cb_pcidas",
1652         .id_table       = cb_pcidas_pci_table,
1653         .probe          = cb_pcidas_pci_probe,
1654         .remove         = comedi_pci_auto_unconfig,
1655 };
1656 module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver);
1657
1658 MODULE_AUTHOR("Comedi http://www.comedi.org");
1659 MODULE_DESCRIPTION("Comedi low-level driver");
1660 MODULE_LICENSE("GPL");