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