Version:  2.0.40 2.2.26 2.4.37 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us