Version:  2.0.40 2.2.26 2.4.37 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 4.1

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

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