2 comedi/drivers/cb_pcidas.c
4 Developed by Ivan Martinez and Frank Mori Hess, with valuable help from
5 David Schleef and the rest of the Comedi developers comunity.
7 Copyright (C) 2001-2003 Ivan Martinez <imr@oersted.dtu.dk>
8 Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
10 COMEDI - Linux Control and Measurement Device Interface
11 Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
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.
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.
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>
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
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.
39 The boards may be autocalibrated using the comedi_calibrate
42 Configuration options: not applicable, uses PCI auto config
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
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
61 analog triggering on 1602 series
64 #include <linux/pci.h>
65 #include <linux/delay.h>
66 #include <linux/interrupt.h>
68 #include "../comedidev.h"
72 #include "amcc_s5933.h"
73 #include "comedi_fc.h"
75 #define TIMER_BASE 100 /* 10MHz master clock */
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
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 */
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 */
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 */
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 */
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 */
138 static inline unsigned int DAC_RANGE(unsigned int channel, unsigned int range)
140 return (range & 0x3) << (8 + 2 * (channel & 0x1));
143 static inline unsigned int DAC_RANGE_MASK(unsigned int channel)
145 return 0x3 << (8 + 2 * (channel & 0x1));
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 */
156 static inline unsigned int DAC_CHAN_EN(unsigned int channel)
158 return 1 << (5 + (channel & 0x1)); /* enable channel 0 or 1 */
161 /* analog input fifo */
162 #define ADCDATA 0 /* ADC DATA register */
163 #define ADCFIFOCLR 2 /* ADC FIFO CLEAR */
165 /* pacer, counter, dio registers */
170 /* analog output registers for 100x, 1200 series */
171 static inline unsigned int DAC_DATA_REG(unsigned int channel)
173 return 2 * (channel & 0x1);
176 /* analog output registers for 1602 series*/
177 #define DACDATA 0 /* DAC DATA register */
178 #define DACFIFOCLR 2 /* DAC FIFO CLEAR */
180 #define IS_UNIPOLAR 0x4 /* unipolar range mask */
182 /* analog input ranges for most boards */
183 static const struct comedi_lrange cb_pcidas_ranges = {
197 /* pci-das1001 input ranges */
198 static const struct comedi_lrange cb_pcidas_alt_ranges = {
212 /* analog output ranges */
213 static const struct comedi_lrange cb_pcidas_ao_ranges = {
228 enum cb_pcidas_boardid {
233 BOARD_PCIDAS1602_16_JR,
239 struct cb_pcidas_board {
241 int ai_nchan; /* Inputs in single-ended mode */
242 int ai_bits; /* analog input resolution */
243 int ai_speed; /* fastest conversion period in ns */
244 int ao_nchan; /* number of analog out channels */
245 int has_ao_fifo; /* analog output has fifo */
246 int ao_scan_speed; /* analog output scan speed for 1602 series */
247 int fifo_size; /* number of samples fifo can hold */
248 const struct comedi_lrange *ranges;
249 enum trimpot_model trimpot;
250 unsigned has_dac08:1;
254 static const struct cb_pcidas_board cb_pcidas_boards[] = {
255 [BOARD_PCIDAS1602_16] = {
256 .name = "pci-das1602/16",
262 .ao_scan_speed = 10000,
264 .ranges = &cb_pcidas_ranges,
269 [BOARD_PCIDAS1200] = {
270 .name = "pci-das1200",
276 .ranges = &cb_pcidas_ranges,
279 [BOARD_PCIDAS1602_12] = {
280 .name = "pci-das1602/12",
286 .ao_scan_speed = 4000,
288 .ranges = &cb_pcidas_ranges,
292 [BOARD_PCIDAS1200_JR] = {
293 .name = "pci-das1200/jr",
298 .ranges = &cb_pcidas_ranges,
301 [BOARD_PCIDAS1602_16_JR] = {
302 .name = "pci-das1602/16/jr",
307 .ranges = &cb_pcidas_ranges,
312 [BOARD_PCIDAS1000] = {
313 .name = "pci-das1000",
318 .ranges = &cb_pcidas_ranges,
321 [BOARD_PCIDAS1001] = {
322 .name = "pci-das1001",
328 .ranges = &cb_pcidas_alt_ranges,
331 [BOARD_PCIDAS1002] = {
332 .name = "pci-das1002",
338 .ranges = &cb_pcidas_ranges,
343 struct cb_pcidas_private {
345 unsigned long s5933_config;
346 unsigned long control_status;
347 unsigned long adc_fifo;
348 unsigned long pacer_counter_dio;
349 unsigned long ao_registers;
350 /* divisors of master clock for analog input pacing */
351 unsigned int divisor1;
352 unsigned int divisor2;
353 /* number of analog input samples remaining */
355 /* bits to write to registers */
356 unsigned int adc_fifo_bits;
357 unsigned int s5933_intcsr_bits;
358 unsigned int ao_control_bits;
360 short ai_buffer[AI_BUFFER_SIZE];
361 short ao_buffer[AO_BUFFER_SIZE];
362 /* divisors of master clock for analog output pacing */
363 unsigned int ao_divisor1;
364 unsigned int ao_divisor2;
365 /* number of analog output samples remaining */
366 unsigned int ao_count;
367 /* cached values for readback */
369 unsigned int caldac_value[NUM_CHANNELS_8800];
370 unsigned int trimpot_value[NUM_CHANNELS_8402];
371 unsigned int dac08_value;
372 unsigned int calibration_source;
375 static inline unsigned int cal_enable_bits(struct comedi_device *dev)
377 struct cb_pcidas_private *devpriv = dev->private;
379 return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source);
382 static int cb_pcidas_ai_rinsn(struct comedi_device *dev,
383 struct comedi_subdevice *s,
384 struct comedi_insn *insn, unsigned int *data)
386 struct cb_pcidas_private *devpriv = dev->private;
387 unsigned int chan = CR_CHAN(insn->chanspec);
388 unsigned int range = CR_RANGE(insn->chanspec);
389 unsigned int aref = CR_AREF(insn->chanspec);
393 /* enable calibration input if appropriate */
394 if (insn->chanspec & CR_ALT_SOURCE) {
395 outw(cal_enable_bits(dev),
396 devpriv->control_status + CALIBRATION_REG);
399 outw(0, devpriv->control_status + CALIBRATION_REG);
402 /* set mux limits and gain */
403 bits = BEGIN_SCAN(chan) | END_SCAN(chan) | GAIN_BITS(range);
404 /* set unipolar/bipolar */
405 if (range & IS_UNIPOLAR)
407 /* set single-ended/differential */
408 if (aref != AREF_DIFF)
410 outw(bits, devpriv->control_status + ADCMUX_CONT);
413 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
415 /* convert n samples */
416 for (n = 0; n < insn->n; n++) {
417 /* trigger conversion */
418 outw(0, devpriv->adc_fifo + ADCDATA);
420 /* wait for conversion to end */
421 /* return -ETIMEDOUT if there is a timeout */
422 for (i = 0; i < 10000; i++) {
423 if (inw(devpriv->control_status + ADCMUX_CONT) & EOC)
430 data[n] = inw(devpriv->adc_fifo + ADCDATA);
433 /* return the number of samples read/written */
437 static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
438 struct comedi_insn *insn, unsigned int *data)
440 struct cb_pcidas_private *devpriv = dev->private;
442 unsigned int source = data[1];
445 case INSN_CONFIG_ALT_SOURCE:
447 dev_err(dev->class_dev,
448 "invalid calibration source: %i\n",
452 devpriv->calibration_source = source;
461 /* analog output insn for pcidas-1000 and 1200 series */
462 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev,
463 struct comedi_subdevice *s,
464 struct comedi_insn *insn,
467 struct cb_pcidas_private *devpriv = dev->private;
468 unsigned int chan = CR_CHAN(insn->chanspec);
469 unsigned int range = CR_RANGE(insn->chanspec);
472 /* set channel and range */
473 spin_lock_irqsave(&dev->spinlock, flags);
474 devpriv->ao_control_bits &= (~DAC_MODE_UPDATE_BOTH &
475 ~DAC_RANGE_MASK(chan));
476 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range));
477 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
478 spin_unlock_irqrestore(&dev->spinlock, flags);
480 /* remember value for readback */
481 devpriv->ao_value[chan] = data[0];
484 outw(data[0], devpriv->ao_registers + DAC_DATA_REG(chan));
489 /* analog output insn for pcidas-1602 series */
490 static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev,
491 struct comedi_subdevice *s,
492 struct comedi_insn *insn, unsigned int *data)
494 struct cb_pcidas_private *devpriv = dev->private;
495 unsigned int chan = CR_CHAN(insn->chanspec);
496 unsigned int range = CR_RANGE(insn->chanspec);
500 outw(0, devpriv->ao_registers + DACFIFOCLR);
502 /* set channel and range */
503 spin_lock_irqsave(&dev->spinlock, flags);
504 devpriv->ao_control_bits &= (~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) &
505 ~DAC_RANGE_MASK(chan) & ~DAC_PACER_MASK);
506 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range) |
507 DAC_CHAN_EN(chan) | DAC_START);
508 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
509 spin_unlock_irqrestore(&dev->spinlock, flags);
511 /* remember value for readback */
512 devpriv->ao_value[chan] = data[0];
515 outw(data[0], devpriv->ao_registers + DACDATA);
520 static int cb_pcidas_ao_readback_insn(struct comedi_device *dev,
521 struct comedi_subdevice *s,
522 struct comedi_insn *insn,
525 struct cb_pcidas_private *devpriv = dev->private;
527 data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
532 static int wait_for_nvram_ready(unsigned long s5933_base_addr)
534 static const int timeout = 1000;
537 for (i = 0; i < timeout; i++) {
538 if ((inb(s5933_base_addr +
539 AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
547 static int nvram_read(struct comedi_device *dev, unsigned int address,
550 struct cb_pcidas_private *devpriv = dev->private;
551 unsigned long iobase = devpriv->s5933_config;
553 if (wait_for_nvram_ready(iobase) < 0)
556 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
557 iobase + AMCC_OP_REG_MCSR_NVCMD);
558 outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
559 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
560 iobase + AMCC_OP_REG_MCSR_NVCMD);
561 outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
562 outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
564 if (wait_for_nvram_ready(iobase) < 0)
567 *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
572 static int eeprom_read_insn(struct comedi_device *dev,
573 struct comedi_subdevice *s,
574 struct comedi_insn *insn, unsigned int *data)
579 retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
583 data[0] = nvram_data;
588 static void write_calibration_bitstream(struct comedi_device *dev,
589 unsigned int register_bits,
590 unsigned int bitstream,
591 unsigned int bitstream_length)
593 struct cb_pcidas_private *devpriv = dev->private;
594 static const int write_delay = 1;
597 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
599 register_bits |= SERIAL_DATA_IN_BIT;
601 register_bits &= ~SERIAL_DATA_IN_BIT;
603 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
607 static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
610 struct cb_pcidas_private *devpriv = dev->private;
611 static const int num_caldac_channels = 8;
612 static const int bitstream_length = 11;
613 unsigned int bitstream = ((address & 0x7) << 8) | value;
614 static const int caldac_8800_udelay = 1;
616 if (address >= num_caldac_channels) {
617 comedi_error(dev, "illegal caldac channel");
621 if (value == devpriv->caldac_value[address])
624 devpriv->caldac_value[address] = value;
626 write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
629 udelay(caldac_8800_udelay);
630 outw(cal_enable_bits(dev) | SELECT_8800_BIT,
631 devpriv->control_status + CALIBRATION_REG);
632 udelay(caldac_8800_udelay);
633 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
638 static int caldac_write_insn(struct comedi_device *dev,
639 struct comedi_subdevice *s,
640 struct comedi_insn *insn, unsigned int *data)
642 const unsigned int channel = CR_CHAN(insn->chanspec);
644 return caldac_8800_write(dev, channel, data[0]);
647 static int caldac_read_insn(struct comedi_device *dev,
648 struct comedi_subdevice *s,
649 struct comedi_insn *insn, unsigned int *data)
651 struct cb_pcidas_private *devpriv = dev->private;
653 data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)];
658 /* 1602/16 pregain offset */
659 static void dac08_write(struct comedi_device *dev, unsigned int value)
661 struct cb_pcidas_private *devpriv = dev->private;
662 unsigned long cal_reg;
664 if (devpriv->dac08_value != value) {
665 devpriv->dac08_value = value;
667 cal_reg = devpriv->control_status + CALIBRATION_REG;
670 value |= cal_enable_bits(dev);
672 /* latch the new value into the caldac */
673 outw(value, cal_reg);
675 outw(value | SELECT_DAC08_BIT, cal_reg);
677 outw(value, cal_reg);
682 static int dac08_write_insn(struct comedi_device *dev,
683 struct comedi_subdevice *s,
684 struct comedi_insn *insn, unsigned int *data)
688 for (i = 0; i < insn->n; i++)
689 dac08_write(dev, data[i]);
694 static int dac08_read_insn(struct comedi_device *dev,
695 struct comedi_subdevice *s, struct comedi_insn *insn,
698 struct cb_pcidas_private *devpriv = dev->private;
700 data[0] = devpriv->dac08_value;
705 static int trimpot_7376_write(struct comedi_device *dev, uint8_t value)
707 struct cb_pcidas_private *devpriv = dev->private;
708 static const int bitstream_length = 7;
709 unsigned int bitstream = value & 0x7f;
710 unsigned int register_bits;
711 static const int ad7376_udelay = 1;
713 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
714 udelay(ad7376_udelay);
715 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
717 write_calibration_bitstream(dev, register_bits, bitstream,
720 udelay(ad7376_udelay);
721 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
728 * ch 1 : adc postgain offset */
729 static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
732 struct cb_pcidas_private *devpriv = dev->private;
733 static const int bitstream_length = 10;
734 unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
735 unsigned int register_bits;
736 static const int ad8402_udelay = 1;
738 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
739 udelay(ad8402_udelay);
740 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
742 write_calibration_bitstream(dev, register_bits, bitstream,
745 udelay(ad8402_udelay);
746 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
751 static int cb_pcidas_trimpot_write(struct comedi_device *dev,
752 unsigned int channel, unsigned int value)
754 const struct cb_pcidas_board *thisboard = comedi_board(dev);
755 struct cb_pcidas_private *devpriv = dev->private;
757 if (devpriv->trimpot_value[channel] == value)
760 devpriv->trimpot_value[channel] = value;
761 switch (thisboard->trimpot) {
763 trimpot_7376_write(dev, value);
766 trimpot_8402_write(dev, channel, value);
769 comedi_error(dev, "driver bug?");
777 static int trimpot_write_insn(struct comedi_device *dev,
778 struct comedi_subdevice *s,
779 struct comedi_insn *insn, unsigned int *data)
781 unsigned int channel = CR_CHAN(insn->chanspec);
783 return cb_pcidas_trimpot_write(dev, channel, data[0]);
786 static int trimpot_read_insn(struct comedi_device *dev,
787 struct comedi_subdevice *s,
788 struct comedi_insn *insn, unsigned int *data)
790 struct cb_pcidas_private *devpriv = dev->private;
791 unsigned int channel = CR_CHAN(insn->chanspec);
793 data[0] = devpriv->trimpot_value[channel];
798 static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
799 struct comedi_subdevice *s,
800 struct comedi_cmd *cmd)
802 const struct cb_pcidas_board *thisboard = comedi_board(dev);
803 struct cb_pcidas_private *devpriv = dev->private;
806 int i, gain, start_chan;
808 /* Step 1 : check if triggers are trivially valid */
810 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
811 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
812 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
813 err |= cfc_check_trigger_src(&cmd->convert_src,
814 TRIG_TIMER | TRIG_NOW | TRIG_EXT);
815 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
816 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
821 /* Step 2a : make sure trigger sources are unique */
823 err |= cfc_check_trigger_is_unique(cmd->start_src);
824 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
825 err |= cfc_check_trigger_is_unique(cmd->convert_src);
826 err |= cfc_check_trigger_is_unique(cmd->stop_src);
828 /* Step 2b : and mutually compatible */
830 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
832 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
834 if (cmd->start_src == TRIG_EXT &&
835 (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))
841 /* step 3: arguments are trivially compatible */
843 switch (cmd->start_src) {
845 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
847 & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
848 cmd->start_arg &= ~(CR_FLAGS_MASK &
849 ~(CR_EDGE | CR_INVERT));
852 if (!thisboard->is_1602 && (cmd->start_arg & CR_INVERT)) {
853 cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
858 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
862 if (cmd->scan_begin_src == TRIG_TIMER)
863 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
864 thisboard->ai_speed * cmd->chanlist_len);
866 if (cmd->convert_src == TRIG_TIMER)
867 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
868 thisboard->ai_speed);
870 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
872 if (cmd->stop_src == TRIG_NONE)
873 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
878 /* step 4: fix up any arguments */
880 if (cmd->scan_begin_src == TRIG_TIMER) {
881 tmp = cmd->scan_begin_arg;
882 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
883 &(devpriv->divisor1),
884 &(devpriv->divisor2),
885 &(cmd->scan_begin_arg),
886 cmd->flags & TRIG_ROUND_MASK);
887 if (tmp != cmd->scan_begin_arg)
890 if (cmd->convert_src == TRIG_TIMER) {
891 tmp = cmd->convert_arg;
892 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
893 &(devpriv->divisor1),
894 &(devpriv->divisor2),
896 cmd->flags & TRIG_ROUND_MASK);
897 if (tmp != cmd->convert_arg)
904 /* check channel/gain list against card's limitations */
906 gain = CR_RANGE(cmd->chanlist[0]);
907 start_chan = CR_CHAN(cmd->chanlist[0]);
908 for (i = 1; i < cmd->chanlist_len; i++) {
909 if (CR_CHAN(cmd->chanlist[i]) !=
910 (start_chan + i) % s->n_chan) {
912 "entries in chanlist must be consecutive channels, counting upwards\n");
915 if (CR_RANGE(cmd->chanlist[i]) != gain) {
917 "entries in chanlist must all have the same gain\n");
929 static void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns,
932 struct cb_pcidas_private *devpriv = dev->private;
934 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
935 &(devpriv->divisor2), ns,
936 rounding_flags & TRIG_ROUND_MASK);
938 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
939 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1,
940 devpriv->divisor1, 2);
941 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2,
942 devpriv->divisor2, 2);
945 static int cb_pcidas_ai_cmd(struct comedi_device *dev,
946 struct comedi_subdevice *s)
948 const struct cb_pcidas_board *thisboard = comedi_board(dev);
949 struct cb_pcidas_private *devpriv = dev->private;
950 struct comedi_async *async = s->async;
951 struct comedi_cmd *cmd = &async->cmd;
955 /* make sure CAL_EN_BIT is disabled */
956 outw(0, devpriv->control_status + CALIBRATION_REG);
957 /* initialize before settings pacer source and count values */
958 outw(0, devpriv->control_status + TRIG_CONTSTAT);
960 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
962 /* set mux limits, gain and pacer source */
963 bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
964 END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
965 GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
966 /* set unipolar/bipolar */
967 if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
969 /* set singleended/differential */
970 if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
972 /* set pacer source */
973 if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
974 bits |= PACER_EXT_RISE;
977 outw(bits, devpriv->control_status + ADCMUX_CONT);
980 if (cmd->convert_src == TRIG_TIMER)
981 cb_pcidas_load_counters(dev, &cmd->convert_arg,
982 cmd->flags & TRIG_ROUND_MASK);
983 else if (cmd->scan_begin_src == TRIG_TIMER)
984 cb_pcidas_load_counters(dev, &cmd->scan_begin_arg,
985 cmd->flags & TRIG_ROUND_MASK);
987 /* set number of conversions */
988 if (cmd->stop_src == TRIG_COUNT)
989 devpriv->count = cmd->chanlist_len * cmd->stop_arg;
990 /* enable interrupts */
991 spin_lock_irqsave(&dev->spinlock, flags);
992 devpriv->adc_fifo_bits |= INTE;
993 devpriv->adc_fifo_bits &= ~INT_MASK;
994 if (cmd->flags & TRIG_WAKE_EOS) {
995 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) {
996 /* interrupt end of burst */
997 devpriv->adc_fifo_bits |= INT_EOS;
999 /* interrupt fifo not empty */
1000 devpriv->adc_fifo_bits |= INT_FNE;
1003 /* interrupt fifo half full */
1004 devpriv->adc_fifo_bits |= INT_FHF;
1007 /* enable (and clear) interrupts */
1008 outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
1009 devpriv->control_status + INT_ADCFIFO);
1010 spin_unlock_irqrestore(&dev->spinlock, flags);
1012 /* set start trigger and burst mode */
1014 if (cmd->start_src == TRIG_NOW)
1016 else if (cmd->start_src == TRIG_EXT) {
1017 bits |= EXT_TRIGGER | TGEN | XTRCL;
1018 if (thisboard->is_1602) {
1019 if (cmd->start_arg & CR_INVERT)
1021 if (cmd->start_arg & CR_EDGE)
1025 comedi_error(dev, "bug!");
1028 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1030 outw(bits, devpriv->control_status + TRIG_CONTSTAT);
1035 static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
1036 struct comedi_subdevice *s,
1037 struct comedi_cmd *cmd)
1039 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1040 struct cb_pcidas_private *devpriv = dev->private;
1044 /* Step 1 : check if triggers are trivially valid */
1046 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT);
1047 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
1048 TRIG_TIMER | TRIG_EXT);
1049 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
1050 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1051 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1056 /* Step 2a : make sure trigger sources are unique */
1058 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
1059 err |= cfc_check_trigger_is_unique(cmd->stop_src);
1061 /* Step 2b : and mutually compatible */
1066 /* Step 3: check if arguments are trivially valid */
1068 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1070 if (cmd->scan_begin_src == TRIG_TIMER)
1071 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1072 thisboard->ao_scan_speed);
1074 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1076 if (cmd->stop_src == TRIG_NONE)
1077 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1082 /* step 4: fix up any arguments */
1084 if (cmd->scan_begin_src == TRIG_TIMER) {
1085 tmp = cmd->scan_begin_arg;
1086 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1087 &(devpriv->ao_divisor1),
1088 &(devpriv->ao_divisor2),
1089 &(cmd->scan_begin_arg),
1090 cmd->flags & TRIG_ROUND_MASK);
1091 if (tmp != cmd->scan_begin_arg)
1098 /* check channel/gain list against card's limitations */
1099 if (cmd->chanlist && cmd->chanlist_len > 1) {
1100 if (CR_CHAN(cmd->chanlist[0]) != 0 ||
1101 CR_CHAN(cmd->chanlist[1]) != 1) {
1103 "channels must be ordered channel 0, channel 1 in chanlist\n");
1114 /* cancel analog input command */
1115 static int cb_pcidas_cancel(struct comedi_device *dev,
1116 struct comedi_subdevice *s)
1118 struct cb_pcidas_private *devpriv = dev->private;
1119 unsigned long flags;
1121 spin_lock_irqsave(&dev->spinlock, flags);
1122 /* disable interrupts */
1123 devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
1124 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1125 spin_unlock_irqrestore(&dev->spinlock, flags);
1127 /* disable start trigger source and burst mode */
1128 outw(0, devpriv->control_status + TRIG_CONTSTAT);
1129 /* software pacer source */
1130 outw(0, devpriv->control_status + ADCMUX_CONT);
1135 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1136 struct comedi_subdevice *s,
1137 unsigned int trig_num)
1139 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1140 struct cb_pcidas_private *devpriv = dev->private;
1141 unsigned int num_bytes, num_points = thisboard->fifo_size;
1142 struct comedi_async *async = s->async;
1143 struct comedi_cmd *cmd = &s->async->cmd;
1144 unsigned long flags;
1150 if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
1151 num_points = devpriv->ao_count;
1153 num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1154 num_points * sizeof(short));
1155 num_points = num_bytes / sizeof(short);
1157 if (cmd->stop_src == TRIG_COUNT)
1158 devpriv->ao_count -= num_points;
1159 /* write data to board's fifo */
1160 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
1162 /* enable dac half-full and empty interrupts */
1163 spin_lock_irqsave(&dev->spinlock, flags);
1164 devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
1166 /* enable and clear interrupts */
1167 outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
1168 devpriv->control_status + INT_ADCFIFO);
1171 devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1172 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1174 spin_unlock_irqrestore(&dev->spinlock, flags);
1176 async->inttrig = NULL;
1181 static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1182 struct comedi_subdevice *s)
1184 struct cb_pcidas_private *devpriv = dev->private;
1185 struct comedi_async *async = s->async;
1186 struct comedi_cmd *cmd = &async->cmd;
1188 unsigned long flags;
1190 /* set channel limits, gain */
1191 spin_lock_irqsave(&dev->spinlock, flags);
1192 for (i = 0; i < cmd->chanlist_len; i++) {
1193 /* enable channel */
1194 devpriv->ao_control_bits |=
1195 DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
1197 devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
1202 /* disable analog out before settings pacer source and count values */
1203 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1204 spin_unlock_irqrestore(&dev->spinlock, flags);
1207 outw(0, devpriv->ao_registers + DACFIFOCLR);
1210 if (cmd->scan_begin_src == TRIG_TIMER) {
1211 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1212 &(devpriv->ao_divisor1),
1213 &(devpriv->ao_divisor2),
1214 &(cmd->scan_begin_arg),
1217 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1218 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1,
1219 devpriv->ao_divisor1, 2);
1220 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2,
1221 devpriv->ao_divisor2, 2);
1223 /* set number of conversions */
1224 if (cmd->stop_src == TRIG_COUNT)
1225 devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
1226 /* set pacer source */
1227 spin_lock_irqsave(&dev->spinlock, flags);
1228 switch (cmd->scan_begin_src) {
1230 devpriv->ao_control_bits |= DAC_PACER_INT;
1233 devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1236 spin_unlock_irqrestore(&dev->spinlock, flags);
1237 comedi_error(dev, "error setting dac pacer source");
1241 spin_unlock_irqrestore(&dev->spinlock, flags);
1243 async->inttrig = cb_pcidas_ao_inttrig;
1248 /* cancel analog output command */
1249 static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1250 struct comedi_subdevice *s)
1252 struct cb_pcidas_private *devpriv = dev->private;
1253 unsigned long flags;
1255 spin_lock_irqsave(&dev->spinlock, flags);
1256 /* disable interrupts */
1257 devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
1258 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1260 /* disable output */
1261 devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1262 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1263 spin_unlock_irqrestore(&dev->spinlock, flags);
1268 static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
1270 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1271 struct cb_pcidas_private *devpriv = dev->private;
1272 struct comedi_subdevice *s = dev->write_subdev;
1273 struct comedi_async *async = s->async;
1274 struct comedi_cmd *cmd = &async->cmd;
1275 unsigned int half_fifo = thisboard->fifo_size / 2;
1276 unsigned int num_points;
1277 unsigned long flags;
1281 if (status & DAEMI) {
1282 /* clear dac empty interrupt latch */
1283 spin_lock_irqsave(&dev->spinlock, flags);
1284 outw(devpriv->adc_fifo_bits | DAEMI,
1285 devpriv->control_status + INT_ADCFIFO);
1286 spin_unlock_irqrestore(&dev->spinlock, flags);
1287 if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
1288 if (cmd->stop_src == TRIG_NONE ||
1289 (cmd->stop_src == TRIG_COUNT
1290 && devpriv->ao_count)) {
1291 comedi_error(dev, "dac fifo underflow");
1292 cb_pcidas_ao_cancel(dev, s);
1293 async->events |= COMEDI_CB_ERROR;
1295 async->events |= COMEDI_CB_EOA;
1297 } else if (status & DAHFI) {
1298 unsigned int num_bytes;
1300 /* figure out how many points we are writing to fifo */
1301 num_points = half_fifo;
1302 if (cmd->stop_src == TRIG_COUNT &&
1303 devpriv->ao_count < num_points)
1304 num_points = devpriv->ao_count;
1306 cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1307 num_points * sizeof(short));
1308 num_points = num_bytes / sizeof(short);
1310 if (async->cmd.stop_src == TRIG_COUNT)
1311 devpriv->ao_count -= num_points;
1312 /* write data to board's fifo */
1313 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
1315 /* clear half-full interrupt latch */
1316 spin_lock_irqsave(&dev->spinlock, flags);
1317 outw(devpriv->adc_fifo_bits | DAHFI,
1318 devpriv->control_status + INT_ADCFIFO);
1319 spin_unlock_irqrestore(&dev->spinlock, flags);
1322 comedi_event(dev, s);
1325 static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1327 struct comedi_device *dev = (struct comedi_device *)d;
1328 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1329 struct cb_pcidas_private *devpriv = dev->private;
1330 struct comedi_subdevice *s = dev->read_subdev;
1331 struct comedi_async *async;
1332 int status, s5933_status;
1333 int half_fifo = thisboard->fifo_size / 2;
1334 unsigned int num_samples, i;
1335 static const int timeout = 10000;
1336 unsigned long flags;
1344 s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1346 if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
1349 /* make sure mailbox 4 is empty */
1350 inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1351 /* clear interrupt on amcc s5933 */
1352 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1353 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1355 status = inw(devpriv->control_status + INT_ADCFIFO);
1357 /* check for analog output interrupt */
1358 if (status & (DAHFI | DAEMI))
1359 handle_ao_interrupt(dev, status);
1360 /* check for analog input interrupts */
1361 /* if fifo half-full */
1362 if (status & ADHFI) {
1364 num_samples = half_fifo;
1365 if (async->cmd.stop_src == TRIG_COUNT &&
1366 num_samples > devpriv->count) {
1367 num_samples = devpriv->count;
1369 insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
1371 cfc_write_array_to_buffer(s, devpriv->ai_buffer,
1372 num_samples * sizeof(short));
1373 devpriv->count -= num_samples;
1374 if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) {
1375 async->events |= COMEDI_CB_EOA;
1376 cb_pcidas_cancel(dev, s);
1378 /* clear half-full interrupt latch */
1379 spin_lock_irqsave(&dev->spinlock, flags);
1380 outw(devpriv->adc_fifo_bits | INT,
1381 devpriv->control_status + INT_ADCFIFO);
1382 spin_unlock_irqrestore(&dev->spinlock, flags);
1383 /* else if fifo not empty */
1384 } else if (status & (ADNEI | EOBI)) {
1385 for (i = 0; i < timeout; i++) {
1386 /* break if fifo is empty */
1387 if ((ADNE & inw(devpriv->control_status +
1390 cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
1391 if (async->cmd.stop_src == TRIG_COUNT &&
1392 --devpriv->count == 0) {
1393 /* end of acquisition */
1394 cb_pcidas_cancel(dev, s);
1395 async->events |= COMEDI_CB_EOA;
1399 /* clear not-empty interrupt latch */
1400 spin_lock_irqsave(&dev->spinlock, flags);
1401 outw(devpriv->adc_fifo_bits | INT,
1402 devpriv->control_status + INT_ADCFIFO);
1403 spin_unlock_irqrestore(&dev->spinlock, flags);
1404 } else if (status & EOAI) {
1406 "bug! encountered end of acquisition interrupt?");
1407 /* clear EOA interrupt latch */
1408 spin_lock_irqsave(&dev->spinlock, flags);
1409 outw(devpriv->adc_fifo_bits | EOAI,
1410 devpriv->control_status + INT_ADCFIFO);
1411 spin_unlock_irqrestore(&dev->spinlock, flags);
1413 /* check for fifo overflow */
1414 if (status & LADFUL) {
1415 comedi_error(dev, "fifo overflow");
1416 /* clear overflow interrupt latch */
1417 spin_lock_irqsave(&dev->spinlock, flags);
1418 outw(devpriv->adc_fifo_bits | LADFUL,
1419 devpriv->control_status + INT_ADCFIFO);
1420 spin_unlock_irqrestore(&dev->spinlock, flags);
1421 cb_pcidas_cancel(dev, s);
1422 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1425 comedi_event(dev, s);
1430 static int cb_pcidas_auto_attach(struct comedi_device *dev,
1431 unsigned long context)
1433 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1434 const struct cb_pcidas_board *thisboard = NULL;
1435 struct cb_pcidas_private *devpriv;
1436 struct comedi_subdevice *s;
1440 if (context < ARRAY_SIZE(cb_pcidas_boards))
1441 thisboard = &cb_pcidas_boards[context];
1444 dev->board_ptr = thisboard;
1445 dev->board_name = thisboard->name;
1447 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1450 dev->private = devpriv;
1452 ret = comedi_pci_enable(dev);
1456 devpriv->s5933_config = pci_resource_start(pcidev, 0);
1457 devpriv->control_status = pci_resource_start(pcidev, 1);
1458 devpriv->adc_fifo = pci_resource_start(pcidev, 2);
1459 devpriv->pacer_counter_dio = pci_resource_start(pcidev, 3);
1460 if (thisboard->ao_nchan)
1461 devpriv->ao_registers = pci_resource_start(pcidev, 4);
1463 /* disable and clear interrupts on amcc s5933 */
1464 outl(INTCSR_INBOX_INTR_STATUS,
1465 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1467 if (request_irq(pcidev->irq, cb_pcidas_interrupt,
1468 IRQF_SHARED, dev->driver->driver_name, dev)) {
1469 dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
1473 dev->irq = pcidev->irq;
1475 ret = comedi_alloc_subdevices(dev, 7);
1479 s = &dev->subdevices[0];
1480 /* analog input subdevice */
1481 dev->read_subdev = s;
1482 s->type = COMEDI_SUBD_AI;
1483 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
1484 /* WARNING: Number of inputs in differential mode is ignored */
1485 s->n_chan = thisboard->ai_nchan;
1486 s->len_chanlist = thisboard->ai_nchan;
1487 s->maxdata = (1 << thisboard->ai_bits) - 1;
1488 s->range_table = thisboard->ranges;
1489 s->insn_read = cb_pcidas_ai_rinsn;
1490 s->insn_config = ai_config_insn;
1491 s->do_cmd = cb_pcidas_ai_cmd;
1492 s->do_cmdtest = cb_pcidas_ai_cmdtest;
1493 s->cancel = cb_pcidas_cancel;
1495 /* analog output subdevice */
1496 s = &dev->subdevices[1];
1497 if (thisboard->ao_nchan) {
1498 s->type = COMEDI_SUBD_AO;
1499 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1500 s->n_chan = thisboard->ao_nchan;
1502 * analog out resolution is the same as
1503 * analog input resolution, so use ai_bits
1505 s->maxdata = (1 << thisboard->ai_bits) - 1;
1506 s->range_table = &cb_pcidas_ao_ranges;
1507 s->insn_read = cb_pcidas_ao_readback_insn;
1508 if (thisboard->has_ao_fifo) {
1509 dev->write_subdev = s;
1510 s->subdev_flags |= SDF_CMD_WRITE;
1511 s->insn_write = cb_pcidas_ao_fifo_winsn;
1512 s->do_cmdtest = cb_pcidas_ao_cmdtest;
1513 s->do_cmd = cb_pcidas_ao_cmd;
1514 s->cancel = cb_pcidas_ao_cancel;
1516 s->insn_write = cb_pcidas_ao_nofifo_winsn;
1519 s->type = COMEDI_SUBD_UNUSED;
1523 s = &dev->subdevices[2];
1524 ret = subdev_8255_init(dev, s, NULL,
1525 devpriv->pacer_counter_dio + DIO_8255);
1529 /* serial EEPROM, */
1530 s = &dev->subdevices[3];
1531 s->type = COMEDI_SUBD_MEMORY;
1532 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
1535 s->insn_read = eeprom_read_insn;
1538 s = &dev->subdevices[4];
1539 s->type = COMEDI_SUBD_CALIB;
1540 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1541 s->n_chan = NUM_CHANNELS_8800;
1543 s->insn_read = caldac_read_insn;
1544 s->insn_write = caldac_write_insn;
1545 for (i = 0; i < s->n_chan; i++)
1546 caldac_8800_write(dev, i, s->maxdata / 2);
1548 /* trim potentiometer */
1549 s = &dev->subdevices[5];
1550 s->type = COMEDI_SUBD_CALIB;
1551 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1552 if (thisboard->trimpot == AD7376) {
1553 s->n_chan = NUM_CHANNELS_7376;
1556 s->n_chan = NUM_CHANNELS_8402;
1559 s->insn_read = trimpot_read_insn;
1560 s->insn_write = trimpot_write_insn;
1561 for (i = 0; i < s->n_chan; i++)
1562 cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
1565 s = &dev->subdevices[6];
1566 if (thisboard->has_dac08) {
1567 s->type = COMEDI_SUBD_CALIB;
1568 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1569 s->n_chan = NUM_CHANNELS_DAC08;
1570 s->insn_read = dac08_read_insn;
1571 s->insn_write = dac08_write_insn;
1573 dac08_write(dev, s->maxdata / 2);
1575 s->type = COMEDI_SUBD_UNUSED;
1577 /* make sure mailbox 4 is empty */
1578 inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1579 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1580 devpriv->s5933_intcsr_bits =
1581 INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1582 INTCSR_INBOX_FULL_INT;
1583 /* clear and enable interrupt on amcc s5933 */
1584 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1585 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1587 dev_info(dev->class_dev, "%s: %s attached\n",
1588 dev->driver->driver_name, dev->board_name);
1593 static void cb_pcidas_detach(struct comedi_device *dev)
1595 struct cb_pcidas_private *devpriv = dev->private;
1598 if (devpriv->s5933_config) {
1599 outl(INTCSR_INBOX_INTR_STATUS,
1600 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1604 free_irq(dev->irq, dev);
1605 comedi_pci_disable(dev);
1608 static struct comedi_driver cb_pcidas_driver = {
1609 .driver_name = "cb_pcidas",
1610 .module = THIS_MODULE,
1611 .auto_attach = cb_pcidas_auto_attach,
1612 .detach = cb_pcidas_detach,
1615 static int cb_pcidas_pci_probe(struct pci_dev *dev,
1616 const struct pci_device_id *id)
1618 return comedi_pci_auto_config(dev, &cb_pcidas_driver,
1622 static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = {
1623 { PCI_VDEVICE(CB, 0x0001), BOARD_PCIDAS1602_16 },
1624 { PCI_VDEVICE(CB, 0x000f), BOARD_PCIDAS1200 },
1625 { PCI_VDEVICE(CB, 0x0010), BOARD_PCIDAS1602_12 },
1626 { PCI_VDEVICE(CB, 0x0019), BOARD_PCIDAS1200_JR },
1627 { PCI_VDEVICE(CB, 0x001c), BOARD_PCIDAS1602_16_JR },
1628 { PCI_VDEVICE(CB, 0x004c), BOARD_PCIDAS1000 },
1629 { PCI_VDEVICE(CB, 0x001a), BOARD_PCIDAS1001 },
1630 { PCI_VDEVICE(CB, 0x001b), BOARD_PCIDAS1002 },
1633 MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
1635 static struct pci_driver cb_pcidas_pci_driver = {
1636 .name = "cb_pcidas",
1637 .id_table = cb_pcidas_pci_table,
1638 .probe = cb_pcidas_pci_probe,
1639 .remove = comedi_pci_auto_unconfig,
1641 module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver);
1643 MODULE_AUTHOR("Comedi http://www.comedi.org");
1644 MODULE_DESCRIPTION("Comedi low-level driver");
1645 MODULE_LICENSE("GPL");