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/module.h>
65 #include <linux/pci.h>
66 #include <linux/delay.h>
67 #include <linux/interrupt.h>
69 #include "../comedidev.h"
73 #include "amcc_s5933.h"
74 #include "comedi_fc.h"
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 unsigned short ai_buffer[AI_BUFFER_SIZE];
361 unsigned 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 */
368 unsigned short ao_value[2];
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(I8254_OSC_BASE_10MHZ,
885 &cmd->scan_begin_arg, cmd->flags);
886 if (tmp != cmd->scan_begin_arg)
889 if (cmd->convert_src == TRIG_TIMER) {
890 tmp = cmd->convert_arg;
891 i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
894 &cmd->convert_arg, cmd->flags);
895 if (tmp != cmd->convert_arg)
902 /* check channel/gain list against card's limitations */
904 gain = CR_RANGE(cmd->chanlist[0]);
905 start_chan = CR_CHAN(cmd->chanlist[0]);
906 for (i = 1; i < cmd->chanlist_len; i++) {
907 if (CR_CHAN(cmd->chanlist[i]) !=
908 (start_chan + i) % s->n_chan) {
910 "entries in chanlist must be consecutive channels, counting upwards\n");
913 if (CR_RANGE(cmd->chanlist[i]) != gain) {
915 "entries in chanlist must all have the same gain\n");
927 static void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns,
930 struct cb_pcidas_private *devpriv = dev->private;
932 i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
933 &devpriv->divisor1, &devpriv->divisor2,
936 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
937 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1,
938 devpriv->divisor1, 2);
939 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2,
940 devpriv->divisor2, 2);
943 static int cb_pcidas_ai_cmd(struct comedi_device *dev,
944 struct comedi_subdevice *s)
946 const struct cb_pcidas_board *thisboard = comedi_board(dev);
947 struct cb_pcidas_private *devpriv = dev->private;
948 struct comedi_async *async = s->async;
949 struct comedi_cmd *cmd = &async->cmd;
953 /* make sure CAL_EN_BIT is disabled */
954 outw(0, devpriv->control_status + CALIBRATION_REG);
955 /* initialize before settings pacer source and count values */
956 outw(0, devpriv->control_status + TRIG_CONTSTAT);
958 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
960 /* set mux limits, gain and pacer source */
961 bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
962 END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
963 GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
964 /* set unipolar/bipolar */
965 if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
967 /* set singleended/differential */
968 if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
970 /* set pacer source */
971 if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
972 bits |= PACER_EXT_RISE;
975 outw(bits, devpriv->control_status + ADCMUX_CONT);
978 if (cmd->convert_src == TRIG_TIMER)
979 cb_pcidas_load_counters(dev, &cmd->convert_arg,
980 cmd->flags & TRIG_ROUND_MASK);
981 else if (cmd->scan_begin_src == TRIG_TIMER)
982 cb_pcidas_load_counters(dev, &cmd->scan_begin_arg,
983 cmd->flags & TRIG_ROUND_MASK);
985 /* set number of conversions */
986 if (cmd->stop_src == TRIG_COUNT)
987 devpriv->count = cmd->chanlist_len * cmd->stop_arg;
988 /* enable interrupts */
989 spin_lock_irqsave(&dev->spinlock, flags);
990 devpriv->adc_fifo_bits |= INTE;
991 devpriv->adc_fifo_bits &= ~INT_MASK;
992 if (cmd->flags & TRIG_WAKE_EOS) {
993 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) {
994 /* interrupt end of burst */
995 devpriv->adc_fifo_bits |= INT_EOS;
997 /* interrupt fifo not empty */
998 devpriv->adc_fifo_bits |= INT_FNE;
1001 /* interrupt fifo half full */
1002 devpriv->adc_fifo_bits |= INT_FHF;
1005 /* enable (and clear) interrupts */
1006 outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
1007 devpriv->control_status + INT_ADCFIFO);
1008 spin_unlock_irqrestore(&dev->spinlock, flags);
1010 /* set start trigger and burst mode */
1012 if (cmd->start_src == TRIG_NOW)
1014 else if (cmd->start_src == TRIG_EXT) {
1015 bits |= EXT_TRIGGER | TGEN | XTRCL;
1016 if (thisboard->is_1602) {
1017 if (cmd->start_arg & CR_INVERT)
1019 if (cmd->start_arg & CR_EDGE)
1023 comedi_error(dev, "bug!");
1026 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1028 outw(bits, devpriv->control_status + TRIG_CONTSTAT);
1033 static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
1034 struct comedi_subdevice *s,
1035 struct comedi_cmd *cmd)
1037 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1038 struct cb_pcidas_private *devpriv = dev->private;
1042 /* Step 1 : check if triggers are trivially valid */
1044 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT);
1045 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
1046 TRIG_TIMER | TRIG_EXT);
1047 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
1048 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1049 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1054 /* Step 2a : make sure trigger sources are unique */
1056 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
1057 err |= cfc_check_trigger_is_unique(cmd->stop_src);
1059 /* Step 2b : and mutually compatible */
1064 /* Step 3: check if arguments are trivially valid */
1066 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1068 if (cmd->scan_begin_src == TRIG_TIMER)
1069 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1070 thisboard->ao_scan_speed);
1072 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1074 if (cmd->stop_src == TRIG_NONE)
1075 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1080 /* step 4: fix up any arguments */
1082 if (cmd->scan_begin_src == TRIG_TIMER) {
1083 tmp = cmd->scan_begin_arg;
1084 i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
1085 &devpriv->ao_divisor1,
1086 &devpriv->ao_divisor2,
1087 &cmd->scan_begin_arg, cmd->flags);
1088 if (tmp != cmd->scan_begin_arg)
1095 /* check channel/gain list against card's limitations */
1096 if (cmd->chanlist && cmd->chanlist_len > 1) {
1097 if (CR_CHAN(cmd->chanlist[0]) != 0 ||
1098 CR_CHAN(cmd->chanlist[1]) != 1) {
1100 "channels must be ordered channel 0, channel 1 in chanlist\n");
1111 /* cancel analog input command */
1112 static int cb_pcidas_cancel(struct comedi_device *dev,
1113 struct comedi_subdevice *s)
1115 struct cb_pcidas_private *devpriv = dev->private;
1116 unsigned long flags;
1118 spin_lock_irqsave(&dev->spinlock, flags);
1119 /* disable interrupts */
1120 devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
1121 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1122 spin_unlock_irqrestore(&dev->spinlock, flags);
1124 /* disable start trigger source and burst mode */
1125 outw(0, devpriv->control_status + TRIG_CONTSTAT);
1126 /* software pacer source */
1127 outw(0, devpriv->control_status + ADCMUX_CONT);
1132 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1133 struct comedi_subdevice *s,
1134 unsigned int trig_num)
1136 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1137 struct cb_pcidas_private *devpriv = dev->private;
1138 unsigned int num_bytes, num_points = thisboard->fifo_size;
1139 struct comedi_async *async = s->async;
1140 struct comedi_cmd *cmd = &s->async->cmd;
1141 unsigned long flags;
1147 if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
1148 num_points = devpriv->ao_count;
1150 num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1151 num_points * sizeof(short));
1152 num_points = num_bytes / sizeof(short);
1154 if (cmd->stop_src == TRIG_COUNT)
1155 devpriv->ao_count -= num_points;
1156 /* write data to board's fifo */
1157 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
1159 /* enable dac half-full and empty interrupts */
1160 spin_lock_irqsave(&dev->spinlock, flags);
1161 devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
1163 /* enable and clear interrupts */
1164 outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
1165 devpriv->control_status + INT_ADCFIFO);
1168 devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1169 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1171 spin_unlock_irqrestore(&dev->spinlock, flags);
1173 async->inttrig = NULL;
1178 static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1179 struct comedi_subdevice *s)
1181 struct cb_pcidas_private *devpriv = dev->private;
1182 struct comedi_async *async = s->async;
1183 struct comedi_cmd *cmd = &async->cmd;
1185 unsigned long flags;
1187 /* set channel limits, gain */
1188 spin_lock_irqsave(&dev->spinlock, flags);
1189 for (i = 0; i < cmd->chanlist_len; i++) {
1190 /* enable channel */
1191 devpriv->ao_control_bits |=
1192 DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
1194 devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
1199 /* disable analog out before settings pacer source and count values */
1200 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1201 spin_unlock_irqrestore(&dev->spinlock, flags);
1204 outw(0, devpriv->ao_registers + DACFIFOCLR);
1207 if (cmd->scan_begin_src == TRIG_TIMER) {
1208 i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
1209 &devpriv->ao_divisor1,
1210 &devpriv->ao_divisor2,
1211 &cmd->scan_begin_arg, cmd->flags);
1213 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1214 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1,
1215 devpriv->ao_divisor1, 2);
1216 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2,
1217 devpriv->ao_divisor2, 2);
1219 /* set number of conversions */
1220 if (cmd->stop_src == TRIG_COUNT)
1221 devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
1222 /* set pacer source */
1223 spin_lock_irqsave(&dev->spinlock, flags);
1224 switch (cmd->scan_begin_src) {
1226 devpriv->ao_control_bits |= DAC_PACER_INT;
1229 devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1232 spin_unlock_irqrestore(&dev->spinlock, flags);
1233 comedi_error(dev, "error setting dac pacer source");
1237 spin_unlock_irqrestore(&dev->spinlock, flags);
1239 async->inttrig = cb_pcidas_ao_inttrig;
1244 /* cancel analog output command */
1245 static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1246 struct comedi_subdevice *s)
1248 struct cb_pcidas_private *devpriv = dev->private;
1249 unsigned long flags;
1251 spin_lock_irqsave(&dev->spinlock, flags);
1252 /* disable interrupts */
1253 devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
1254 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1256 /* disable output */
1257 devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1258 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1259 spin_unlock_irqrestore(&dev->spinlock, flags);
1264 static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
1266 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1267 struct cb_pcidas_private *devpriv = dev->private;
1268 struct comedi_subdevice *s = dev->write_subdev;
1269 struct comedi_async *async = s->async;
1270 struct comedi_cmd *cmd = &async->cmd;
1271 unsigned int half_fifo = thisboard->fifo_size / 2;
1272 unsigned int num_points;
1273 unsigned long flags;
1277 if (status & DAEMI) {
1278 /* clear dac empty interrupt latch */
1279 spin_lock_irqsave(&dev->spinlock, flags);
1280 outw(devpriv->adc_fifo_bits | DAEMI,
1281 devpriv->control_status + INT_ADCFIFO);
1282 spin_unlock_irqrestore(&dev->spinlock, flags);
1283 if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
1284 if (cmd->stop_src == TRIG_NONE ||
1285 (cmd->stop_src == TRIG_COUNT
1286 && devpriv->ao_count)) {
1287 comedi_error(dev, "dac fifo underflow");
1288 cb_pcidas_ao_cancel(dev, s);
1289 async->events |= COMEDI_CB_ERROR;
1291 async->events |= COMEDI_CB_EOA;
1293 } else if (status & DAHFI) {
1294 unsigned int num_bytes;
1296 /* figure out how many points we are writing to fifo */
1297 num_points = half_fifo;
1298 if (cmd->stop_src == TRIG_COUNT &&
1299 devpriv->ao_count < num_points)
1300 num_points = devpriv->ao_count;
1302 cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1303 num_points * sizeof(short));
1304 num_points = num_bytes / sizeof(short);
1306 if (async->cmd.stop_src == TRIG_COUNT)
1307 devpriv->ao_count -= num_points;
1308 /* write data to board's fifo */
1309 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
1311 /* clear half-full interrupt latch */
1312 spin_lock_irqsave(&dev->spinlock, flags);
1313 outw(devpriv->adc_fifo_bits | DAHFI,
1314 devpriv->control_status + INT_ADCFIFO);
1315 spin_unlock_irqrestore(&dev->spinlock, flags);
1318 comedi_event(dev, s);
1321 static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1323 struct comedi_device *dev = (struct comedi_device *)d;
1324 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1325 struct cb_pcidas_private *devpriv = dev->private;
1326 struct comedi_subdevice *s = dev->read_subdev;
1327 struct comedi_async *async;
1328 int status, s5933_status;
1329 int half_fifo = thisboard->fifo_size / 2;
1330 unsigned int num_samples, i;
1331 static const int timeout = 10000;
1332 unsigned long flags;
1340 s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1342 if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
1345 /* make sure mailbox 4 is empty */
1346 inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1347 /* clear interrupt on amcc s5933 */
1348 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1349 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1351 status = inw(devpriv->control_status + INT_ADCFIFO);
1353 /* check for analog output interrupt */
1354 if (status & (DAHFI | DAEMI))
1355 handle_ao_interrupt(dev, status);
1356 /* check for analog input interrupts */
1357 /* if fifo half-full */
1358 if (status & ADHFI) {
1360 num_samples = half_fifo;
1361 if (async->cmd.stop_src == TRIG_COUNT &&
1362 num_samples > devpriv->count) {
1363 num_samples = devpriv->count;
1365 insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
1367 cfc_write_array_to_buffer(s, devpriv->ai_buffer,
1368 num_samples * sizeof(short));
1369 devpriv->count -= num_samples;
1370 if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) {
1371 async->events |= COMEDI_CB_EOA;
1372 cb_pcidas_cancel(dev, s);
1374 /* clear half-full interrupt latch */
1375 spin_lock_irqsave(&dev->spinlock, flags);
1376 outw(devpriv->adc_fifo_bits | INT,
1377 devpriv->control_status + INT_ADCFIFO);
1378 spin_unlock_irqrestore(&dev->spinlock, flags);
1379 /* else if fifo not empty */
1380 } else if (status & (ADNEI | EOBI)) {
1381 for (i = 0; i < timeout; i++) {
1382 /* break if fifo is empty */
1383 if ((ADNE & inw(devpriv->control_status +
1386 cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
1387 if (async->cmd.stop_src == TRIG_COUNT &&
1388 --devpriv->count == 0) {
1389 /* end of acquisition */
1390 cb_pcidas_cancel(dev, s);
1391 async->events |= COMEDI_CB_EOA;
1395 /* clear not-empty interrupt latch */
1396 spin_lock_irqsave(&dev->spinlock, flags);
1397 outw(devpriv->adc_fifo_bits | INT,
1398 devpriv->control_status + INT_ADCFIFO);
1399 spin_unlock_irqrestore(&dev->spinlock, flags);
1400 } else if (status & EOAI) {
1402 "bug! encountered end of acquisition interrupt?");
1403 /* clear EOA interrupt latch */
1404 spin_lock_irqsave(&dev->spinlock, flags);
1405 outw(devpriv->adc_fifo_bits | EOAI,
1406 devpriv->control_status + INT_ADCFIFO);
1407 spin_unlock_irqrestore(&dev->spinlock, flags);
1409 /* check for fifo overflow */
1410 if (status & LADFUL) {
1411 comedi_error(dev, "fifo overflow");
1412 /* clear overflow interrupt latch */
1413 spin_lock_irqsave(&dev->spinlock, flags);
1414 outw(devpriv->adc_fifo_bits | LADFUL,
1415 devpriv->control_status + INT_ADCFIFO);
1416 spin_unlock_irqrestore(&dev->spinlock, flags);
1417 cb_pcidas_cancel(dev, s);
1418 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1421 comedi_event(dev, s);
1426 static int cb_pcidas_auto_attach(struct comedi_device *dev,
1427 unsigned long context)
1429 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1430 const struct cb_pcidas_board *thisboard = NULL;
1431 struct cb_pcidas_private *devpriv;
1432 struct comedi_subdevice *s;
1436 if (context < ARRAY_SIZE(cb_pcidas_boards))
1437 thisboard = &cb_pcidas_boards[context];
1440 dev->board_ptr = thisboard;
1441 dev->board_name = thisboard->name;
1443 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1447 ret = comedi_pci_enable(dev);
1451 devpriv->s5933_config = pci_resource_start(pcidev, 0);
1452 devpriv->control_status = pci_resource_start(pcidev, 1);
1453 devpriv->adc_fifo = pci_resource_start(pcidev, 2);
1454 devpriv->pacer_counter_dio = pci_resource_start(pcidev, 3);
1455 if (thisboard->ao_nchan)
1456 devpriv->ao_registers = pci_resource_start(pcidev, 4);
1458 /* disable and clear interrupts on amcc s5933 */
1459 outl(INTCSR_INBOX_INTR_STATUS,
1460 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1462 if (request_irq(pcidev->irq, cb_pcidas_interrupt,
1463 IRQF_SHARED, dev->driver->driver_name, dev)) {
1464 dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
1468 dev->irq = pcidev->irq;
1470 ret = comedi_alloc_subdevices(dev, 7);
1474 s = &dev->subdevices[0];
1475 /* analog input subdevice */
1476 dev->read_subdev = s;
1477 s->type = COMEDI_SUBD_AI;
1478 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
1479 /* WARNING: Number of inputs in differential mode is ignored */
1480 s->n_chan = thisboard->ai_nchan;
1481 s->len_chanlist = thisboard->ai_nchan;
1482 s->maxdata = (1 << thisboard->ai_bits) - 1;
1483 s->range_table = thisboard->ranges;
1484 s->insn_read = cb_pcidas_ai_rinsn;
1485 s->insn_config = ai_config_insn;
1486 s->do_cmd = cb_pcidas_ai_cmd;
1487 s->do_cmdtest = cb_pcidas_ai_cmdtest;
1488 s->cancel = cb_pcidas_cancel;
1490 /* analog output subdevice */
1491 s = &dev->subdevices[1];
1492 if (thisboard->ao_nchan) {
1493 s->type = COMEDI_SUBD_AO;
1494 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1495 s->n_chan = thisboard->ao_nchan;
1497 * analog out resolution is the same as
1498 * analog input resolution, so use ai_bits
1500 s->maxdata = (1 << thisboard->ai_bits) - 1;
1501 s->range_table = &cb_pcidas_ao_ranges;
1502 s->insn_read = cb_pcidas_ao_readback_insn;
1503 if (thisboard->has_ao_fifo) {
1504 dev->write_subdev = s;
1505 s->subdev_flags |= SDF_CMD_WRITE;
1506 s->insn_write = cb_pcidas_ao_fifo_winsn;
1507 s->do_cmdtest = cb_pcidas_ao_cmdtest;
1508 s->do_cmd = cb_pcidas_ao_cmd;
1509 s->cancel = cb_pcidas_ao_cancel;
1511 s->insn_write = cb_pcidas_ao_nofifo_winsn;
1514 s->type = COMEDI_SUBD_UNUSED;
1518 s = &dev->subdevices[2];
1519 ret = subdev_8255_init(dev, s, NULL,
1520 devpriv->pacer_counter_dio + DIO_8255);
1524 /* serial EEPROM, */
1525 s = &dev->subdevices[3];
1526 s->type = COMEDI_SUBD_MEMORY;
1527 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
1530 s->insn_read = eeprom_read_insn;
1533 s = &dev->subdevices[4];
1534 s->type = COMEDI_SUBD_CALIB;
1535 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1536 s->n_chan = NUM_CHANNELS_8800;
1538 s->insn_read = caldac_read_insn;
1539 s->insn_write = caldac_write_insn;
1540 for (i = 0; i < s->n_chan; i++)
1541 caldac_8800_write(dev, i, s->maxdata / 2);
1543 /* trim potentiometer */
1544 s = &dev->subdevices[5];
1545 s->type = COMEDI_SUBD_CALIB;
1546 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1547 if (thisboard->trimpot == AD7376) {
1548 s->n_chan = NUM_CHANNELS_7376;
1551 s->n_chan = NUM_CHANNELS_8402;
1554 s->insn_read = trimpot_read_insn;
1555 s->insn_write = trimpot_write_insn;
1556 for (i = 0; i < s->n_chan; i++)
1557 cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
1560 s = &dev->subdevices[6];
1561 if (thisboard->has_dac08) {
1562 s->type = COMEDI_SUBD_CALIB;
1563 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1564 s->n_chan = NUM_CHANNELS_DAC08;
1565 s->insn_read = dac08_read_insn;
1566 s->insn_write = dac08_write_insn;
1568 dac08_write(dev, s->maxdata / 2);
1570 s->type = COMEDI_SUBD_UNUSED;
1572 /* make sure mailbox 4 is empty */
1573 inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1574 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1575 devpriv->s5933_intcsr_bits =
1576 INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1577 INTCSR_INBOX_FULL_INT;
1578 /* clear and enable interrupt on amcc s5933 */
1579 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1580 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1582 dev_info(dev->class_dev, "%s: %s attached\n",
1583 dev->driver->driver_name, dev->board_name);
1588 static void cb_pcidas_detach(struct comedi_device *dev)
1590 struct cb_pcidas_private *devpriv = dev->private;
1593 if (devpriv->s5933_config) {
1594 outl(INTCSR_INBOX_INTR_STATUS,
1595 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1599 free_irq(dev->irq, dev);
1600 comedi_pci_disable(dev);
1603 static struct comedi_driver cb_pcidas_driver = {
1604 .driver_name = "cb_pcidas",
1605 .module = THIS_MODULE,
1606 .auto_attach = cb_pcidas_auto_attach,
1607 .detach = cb_pcidas_detach,
1610 static int cb_pcidas_pci_probe(struct pci_dev *dev,
1611 const struct pci_device_id *id)
1613 return comedi_pci_auto_config(dev, &cb_pcidas_driver,
1617 static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = {
1618 { PCI_VDEVICE(CB, 0x0001), BOARD_PCIDAS1602_16 },
1619 { PCI_VDEVICE(CB, 0x000f), BOARD_PCIDAS1200 },
1620 { PCI_VDEVICE(CB, 0x0010), BOARD_PCIDAS1602_12 },
1621 { PCI_VDEVICE(CB, 0x0019), BOARD_PCIDAS1200_JR },
1622 { PCI_VDEVICE(CB, 0x001c), BOARD_PCIDAS1602_16_JR },
1623 { PCI_VDEVICE(CB, 0x004c), BOARD_PCIDAS1000 },
1624 { PCI_VDEVICE(CB, 0x001a), BOARD_PCIDAS1001 },
1625 { PCI_VDEVICE(CB, 0x001b), BOARD_PCIDAS1002 },
1628 MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
1630 static struct pci_driver cb_pcidas_pci_driver = {
1631 .name = "cb_pcidas",
1632 .id_table = cb_pcidas_pci_table,
1633 .probe = cb_pcidas_pci_probe,
1634 .remove = comedi_pci_auto_unconfig,
1636 module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver);
1638 MODULE_AUTHOR("Comedi http://www.comedi.org");
1639 MODULE_DESCRIPTION("Comedi low-level driver");
1640 MODULE_LICENSE("GPL");