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 = {
196 /* pci-das1001 input ranges */
197 static const struct comedi_lrange cb_pcidas_alt_ranges = {
210 /* analog output ranges */
211 static const struct comedi_lrange cb_pcidas_ao_ranges = {
225 enum cb_pcidas_boardid {
230 BOARD_PCIDAS1602_16_JR,
236 struct cb_pcidas_board {
238 int ai_nchan; /* Inputs in single-ended mode */
239 int ai_bits; /* analog input resolution */
240 int ai_speed; /* fastest conversion period in ns */
241 int ao_nchan; /* number of analog out channels */
242 int has_ao_fifo; /* analog output has fifo */
243 int ao_scan_speed; /* analog output scan speed for 1602 series */
244 int fifo_size; /* number of samples fifo can hold */
245 const struct comedi_lrange *ranges;
246 enum trimpot_model trimpot;
247 unsigned has_dac08:1;
251 static const struct cb_pcidas_board cb_pcidas_boards[] = {
252 [BOARD_PCIDAS1602_16] = {
253 .name = "pci-das1602/16",
259 .ao_scan_speed = 10000,
261 .ranges = &cb_pcidas_ranges,
266 [BOARD_PCIDAS1200] = {
267 .name = "pci-das1200",
273 .ranges = &cb_pcidas_ranges,
276 [BOARD_PCIDAS1602_12] = {
277 .name = "pci-das1602/12",
283 .ao_scan_speed = 4000,
285 .ranges = &cb_pcidas_ranges,
289 [BOARD_PCIDAS1200_JR] = {
290 .name = "pci-das1200/jr",
295 .ranges = &cb_pcidas_ranges,
298 [BOARD_PCIDAS1602_16_JR] = {
299 .name = "pci-das1602/16/jr",
304 .ranges = &cb_pcidas_ranges,
309 [BOARD_PCIDAS1000] = {
310 .name = "pci-das1000",
315 .ranges = &cb_pcidas_ranges,
318 [BOARD_PCIDAS1001] = {
319 .name = "pci-das1001",
325 .ranges = &cb_pcidas_alt_ranges,
328 [BOARD_PCIDAS1002] = {
329 .name = "pci-das1002",
335 .ranges = &cb_pcidas_ranges,
340 struct cb_pcidas_private {
342 unsigned long s5933_config;
343 unsigned long control_status;
344 unsigned long adc_fifo;
345 unsigned long pacer_counter_dio;
346 unsigned long ao_registers;
347 /* divisors of master clock for analog input pacing */
348 unsigned int divisor1;
349 unsigned int divisor2;
350 /* number of analog input samples remaining */
352 /* bits to write to registers */
353 unsigned int adc_fifo_bits;
354 unsigned int s5933_intcsr_bits;
355 unsigned int ao_control_bits;
357 unsigned short ai_buffer[AI_BUFFER_SIZE];
358 unsigned short ao_buffer[AO_BUFFER_SIZE];
359 /* divisors of master clock for analog output pacing */
360 unsigned int ao_divisor1;
361 unsigned int ao_divisor2;
362 /* number of analog output samples remaining */
363 unsigned int ao_count;
364 /* cached values for readback */
365 unsigned short ao_value[2];
366 unsigned int caldac_value[NUM_CHANNELS_8800];
367 unsigned int trimpot_value[NUM_CHANNELS_8402];
368 unsigned int dac08_value;
369 unsigned int calibration_source;
372 static inline unsigned int cal_enable_bits(struct comedi_device *dev)
374 struct cb_pcidas_private *devpriv = dev->private;
376 return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source);
379 static int cb_pcidas_ai_eoc(struct comedi_device *dev,
380 struct comedi_subdevice *s,
381 struct comedi_insn *insn,
382 unsigned long context)
384 struct cb_pcidas_private *devpriv = dev->private;
387 status = inw(devpriv->control_status + ADCMUX_CONT);
393 static int cb_pcidas_ai_rinsn(struct comedi_device *dev,
394 struct comedi_subdevice *s,
395 struct comedi_insn *insn, unsigned int *data)
397 struct cb_pcidas_private *devpriv = dev->private;
398 unsigned int chan = CR_CHAN(insn->chanspec);
399 unsigned int range = CR_RANGE(insn->chanspec);
400 unsigned int aref = CR_AREF(insn->chanspec);
405 /* enable calibration input if appropriate */
406 if (insn->chanspec & CR_ALT_SOURCE) {
407 outw(cal_enable_bits(dev),
408 devpriv->control_status + CALIBRATION_REG);
411 outw(0, devpriv->control_status + CALIBRATION_REG);
414 /* set mux limits and gain */
415 bits = BEGIN_SCAN(chan) | END_SCAN(chan) | GAIN_BITS(range);
416 /* set unipolar/bipolar */
417 if (range & IS_UNIPOLAR)
419 /* set single-ended/differential */
420 if (aref != AREF_DIFF)
422 outw(bits, devpriv->control_status + ADCMUX_CONT);
425 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
427 /* convert n samples */
428 for (n = 0; n < insn->n; n++) {
429 /* trigger conversion */
430 outw(0, devpriv->adc_fifo + ADCDATA);
432 /* wait for conversion to end */
433 ret = comedi_timeout(dev, s, insn, cb_pcidas_ai_eoc, 0);
438 data[n] = inw(devpriv->adc_fifo + ADCDATA);
441 /* return the number of samples read/written */
445 static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
446 struct comedi_insn *insn, unsigned int *data)
448 struct cb_pcidas_private *devpriv = dev->private;
450 unsigned int source = data[1];
453 case INSN_CONFIG_ALT_SOURCE:
455 dev_err(dev->class_dev,
456 "invalid calibration source: %i\n",
460 devpriv->calibration_source = source;
468 /* analog output insn for pcidas-1000 and 1200 series */
469 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev,
470 struct comedi_subdevice *s,
471 struct comedi_insn *insn,
474 struct cb_pcidas_private *devpriv = dev->private;
475 unsigned int chan = CR_CHAN(insn->chanspec);
476 unsigned int range = CR_RANGE(insn->chanspec);
479 /* set channel and range */
480 spin_lock_irqsave(&dev->spinlock, flags);
481 devpriv->ao_control_bits &= (~DAC_MODE_UPDATE_BOTH &
482 ~DAC_RANGE_MASK(chan));
483 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range));
484 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
485 spin_unlock_irqrestore(&dev->spinlock, flags);
487 /* remember value for readback */
488 devpriv->ao_value[chan] = data[0];
491 outw(data[0], devpriv->ao_registers + DAC_DATA_REG(chan));
496 /* analog output insn for pcidas-1602 series */
497 static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev,
498 struct comedi_subdevice *s,
499 struct comedi_insn *insn, unsigned int *data)
501 struct cb_pcidas_private *devpriv = dev->private;
502 unsigned int chan = CR_CHAN(insn->chanspec);
503 unsigned int range = CR_RANGE(insn->chanspec);
507 outw(0, devpriv->ao_registers + DACFIFOCLR);
509 /* set channel and range */
510 spin_lock_irqsave(&dev->spinlock, flags);
511 devpriv->ao_control_bits &= (~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) &
512 ~DAC_RANGE_MASK(chan) & ~DAC_PACER_MASK);
513 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range) |
514 DAC_CHAN_EN(chan) | DAC_START);
515 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
516 spin_unlock_irqrestore(&dev->spinlock, flags);
518 /* remember value for readback */
519 devpriv->ao_value[chan] = data[0];
522 outw(data[0], devpriv->ao_registers + DACDATA);
527 static int cb_pcidas_ao_readback_insn(struct comedi_device *dev,
528 struct comedi_subdevice *s,
529 struct comedi_insn *insn,
532 struct cb_pcidas_private *devpriv = dev->private;
534 data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
539 static int wait_for_nvram_ready(unsigned long s5933_base_addr)
541 static const int timeout = 1000;
544 for (i = 0; i < timeout; i++) {
545 if ((inb(s5933_base_addr +
546 AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
554 static int nvram_read(struct comedi_device *dev, unsigned int address,
557 struct cb_pcidas_private *devpriv = dev->private;
558 unsigned long iobase = devpriv->s5933_config;
560 if (wait_for_nvram_ready(iobase) < 0)
563 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
564 iobase + AMCC_OP_REG_MCSR_NVCMD);
565 outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
566 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
567 iobase + AMCC_OP_REG_MCSR_NVCMD);
568 outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
569 outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
571 if (wait_for_nvram_ready(iobase) < 0)
574 *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
579 static int eeprom_read_insn(struct comedi_device *dev,
580 struct comedi_subdevice *s,
581 struct comedi_insn *insn, unsigned int *data)
586 retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
590 data[0] = nvram_data;
595 static void write_calibration_bitstream(struct comedi_device *dev,
596 unsigned int register_bits,
597 unsigned int bitstream,
598 unsigned int bitstream_length)
600 struct cb_pcidas_private *devpriv = dev->private;
601 static const int write_delay = 1;
604 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
606 register_bits |= SERIAL_DATA_IN_BIT;
608 register_bits &= ~SERIAL_DATA_IN_BIT;
610 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
614 static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
617 struct cb_pcidas_private *devpriv = dev->private;
618 static const int num_caldac_channels = 8;
619 static const int bitstream_length = 11;
620 unsigned int bitstream = ((address & 0x7) << 8) | value;
621 static const int caldac_8800_udelay = 1;
623 if (address >= num_caldac_channels) {
624 dev_err(dev->class_dev, "illegal caldac channel\n");
628 if (value == devpriv->caldac_value[address])
631 devpriv->caldac_value[address] = value;
633 write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
636 udelay(caldac_8800_udelay);
637 outw(cal_enable_bits(dev) | SELECT_8800_BIT,
638 devpriv->control_status + CALIBRATION_REG);
639 udelay(caldac_8800_udelay);
640 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
645 static int caldac_write_insn(struct comedi_device *dev,
646 struct comedi_subdevice *s,
647 struct comedi_insn *insn, unsigned int *data)
649 const unsigned int channel = CR_CHAN(insn->chanspec);
651 return caldac_8800_write(dev, channel, data[0]);
654 static int caldac_read_insn(struct comedi_device *dev,
655 struct comedi_subdevice *s,
656 struct comedi_insn *insn, unsigned int *data)
658 struct cb_pcidas_private *devpriv = dev->private;
660 data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)];
665 /* 1602/16 pregain offset */
666 static void dac08_write(struct comedi_device *dev, unsigned int value)
668 struct cb_pcidas_private *devpriv = dev->private;
669 unsigned long cal_reg;
671 if (devpriv->dac08_value != value) {
672 devpriv->dac08_value = value;
674 cal_reg = devpriv->control_status + CALIBRATION_REG;
677 value |= cal_enable_bits(dev);
679 /* latch the new value into the caldac */
680 outw(value, cal_reg);
682 outw(value | SELECT_DAC08_BIT, cal_reg);
684 outw(value, cal_reg);
689 static int dac08_write_insn(struct comedi_device *dev,
690 struct comedi_subdevice *s,
691 struct comedi_insn *insn, unsigned int *data)
695 for (i = 0; i < insn->n; i++)
696 dac08_write(dev, data[i]);
701 static int dac08_read_insn(struct comedi_device *dev,
702 struct comedi_subdevice *s, struct comedi_insn *insn,
705 struct cb_pcidas_private *devpriv = dev->private;
707 data[0] = devpriv->dac08_value;
712 static int trimpot_7376_write(struct comedi_device *dev, uint8_t value)
714 struct cb_pcidas_private *devpriv = dev->private;
715 static const int bitstream_length = 7;
716 unsigned int bitstream = value & 0x7f;
717 unsigned int register_bits;
718 static const int ad7376_udelay = 1;
720 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
721 udelay(ad7376_udelay);
722 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
724 write_calibration_bitstream(dev, register_bits, bitstream,
727 udelay(ad7376_udelay);
728 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
735 * ch 1 : adc postgain offset */
736 static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
739 struct cb_pcidas_private *devpriv = dev->private;
740 static const int bitstream_length = 10;
741 unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
742 unsigned int register_bits;
743 static const int ad8402_udelay = 1;
745 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
746 udelay(ad8402_udelay);
747 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
749 write_calibration_bitstream(dev, register_bits, bitstream,
752 udelay(ad8402_udelay);
753 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
758 static int cb_pcidas_trimpot_write(struct comedi_device *dev,
759 unsigned int channel, unsigned int value)
761 const struct cb_pcidas_board *thisboard = comedi_board(dev);
762 struct cb_pcidas_private *devpriv = dev->private;
764 if (devpriv->trimpot_value[channel] == value)
767 devpriv->trimpot_value[channel] = value;
768 switch (thisboard->trimpot) {
770 trimpot_7376_write(dev, value);
773 trimpot_8402_write(dev, channel, value);
776 dev_err(dev->class_dev, "driver bug?\n");
783 static int trimpot_write_insn(struct comedi_device *dev,
784 struct comedi_subdevice *s,
785 struct comedi_insn *insn, unsigned int *data)
787 unsigned int channel = CR_CHAN(insn->chanspec);
789 return cb_pcidas_trimpot_write(dev, channel, data[0]);
792 static int trimpot_read_insn(struct comedi_device *dev,
793 struct comedi_subdevice *s,
794 struct comedi_insn *insn, unsigned int *data)
796 struct cb_pcidas_private *devpriv = dev->private;
797 unsigned int channel = CR_CHAN(insn->chanspec);
799 data[0] = devpriv->trimpot_value[channel];
804 static int cb_pcidas_ai_check_chanlist(struct comedi_device *dev,
805 struct comedi_subdevice *s,
806 struct comedi_cmd *cmd)
808 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
809 unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
812 for (i = 1; i < cmd->chanlist_len; i++) {
813 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
814 unsigned int range = CR_RANGE(cmd->chanlist[i]);
816 if (chan != (chan0 + i) % s->n_chan) {
817 dev_dbg(dev->class_dev,
818 "entries in chanlist must be consecutive channels, counting upwards\n");
822 if (range != range0) {
823 dev_dbg(dev->class_dev,
824 "entries in chanlist must all have the same gain\n");
831 static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
832 struct comedi_subdevice *s,
833 struct comedi_cmd *cmd)
835 const struct cb_pcidas_board *thisboard = comedi_board(dev);
836 struct cb_pcidas_private *devpriv = dev->private;
840 /* Step 1 : check if triggers are trivially valid */
842 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
843 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
844 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
845 err |= cfc_check_trigger_src(&cmd->convert_src,
846 TRIG_TIMER | TRIG_NOW | TRIG_EXT);
847 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
848 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
853 /* Step 2a : make sure trigger sources are unique */
855 err |= cfc_check_trigger_is_unique(cmd->start_src);
856 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
857 err |= cfc_check_trigger_is_unique(cmd->convert_src);
858 err |= cfc_check_trigger_is_unique(cmd->stop_src);
860 /* Step 2b : and mutually compatible */
862 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
864 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
866 if (cmd->start_src == TRIG_EXT &&
867 (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))
873 /* Step 3: check if arguments are trivially valid */
875 switch (cmd->start_src) {
877 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
880 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
882 & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
883 cmd->start_arg &= ~(CR_FLAGS_MASK &
884 ~(CR_EDGE | CR_INVERT));
887 if (!thisboard->is_1602 && (cmd->start_arg & CR_INVERT)) {
888 cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
894 if (cmd->scan_begin_src == TRIG_TIMER)
895 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
896 thisboard->ai_speed * cmd->chanlist_len);
898 if (cmd->convert_src == TRIG_TIMER)
899 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
900 thisboard->ai_speed);
902 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
904 if (cmd->stop_src == TRIG_NONE)
905 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
910 /* step 4: fix up any arguments */
912 if (cmd->scan_begin_src == TRIG_TIMER) {
913 arg = cmd->scan_begin_arg;
914 i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
918 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
920 if (cmd->convert_src == TRIG_TIMER) {
921 arg = cmd->convert_arg;
922 i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
926 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
932 /* Step 5: check channel list if it exists */
933 if (cmd->chanlist && cmd->chanlist_len > 0)
934 err |= cb_pcidas_ai_check_chanlist(dev, s, cmd);
942 static void cb_pcidas_ai_load_counters(struct comedi_device *dev)
944 struct cb_pcidas_private *devpriv = dev->private;
945 unsigned long timer_base = devpriv->pacer_counter_dio + ADC8254;
947 i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
948 i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
950 i8254_write(timer_base, 0, 1, devpriv->divisor1);
951 i8254_write(timer_base, 0, 2, devpriv->divisor2);
954 static int cb_pcidas_ai_cmd(struct comedi_device *dev,
955 struct comedi_subdevice *s)
957 const struct cb_pcidas_board *thisboard = comedi_board(dev);
958 struct cb_pcidas_private *devpriv = dev->private;
959 struct comedi_async *async = s->async;
960 struct comedi_cmd *cmd = &async->cmd;
964 /* make sure CAL_EN_BIT is disabled */
965 outw(0, devpriv->control_status + CALIBRATION_REG);
966 /* initialize before settings pacer source and count values */
967 outw(0, devpriv->control_status + TRIG_CONTSTAT);
969 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
971 /* set mux limits, gain and pacer source */
972 bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
973 END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
974 GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
975 /* set unipolar/bipolar */
976 if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
978 /* set singleended/differential */
979 if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
981 /* set pacer source */
982 if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
983 bits |= PACER_EXT_RISE;
986 outw(bits, devpriv->control_status + ADCMUX_CONT);
989 if (cmd->scan_begin_src == TRIG_TIMER || cmd->convert_src == TRIG_TIMER)
990 cb_pcidas_ai_load_counters(dev);
992 /* set number of conversions */
993 if (cmd->stop_src == TRIG_COUNT)
994 devpriv->count = cmd->chanlist_len * cmd->stop_arg;
995 /* enable interrupts */
996 spin_lock_irqsave(&dev->spinlock, flags);
997 devpriv->adc_fifo_bits |= INTE;
998 devpriv->adc_fifo_bits &= ~INT_MASK;
999 if (cmd->flags & TRIG_WAKE_EOS) {
1000 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) {
1001 /* interrupt end of burst */
1002 devpriv->adc_fifo_bits |= INT_EOS;
1004 /* interrupt fifo not empty */
1005 devpriv->adc_fifo_bits |= INT_FNE;
1008 /* interrupt fifo half full */
1009 devpriv->adc_fifo_bits |= INT_FHF;
1012 /* enable (and clear) interrupts */
1013 outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
1014 devpriv->control_status + INT_ADCFIFO);
1015 spin_unlock_irqrestore(&dev->spinlock, flags);
1017 /* set start trigger and burst mode */
1019 if (cmd->start_src == TRIG_NOW) {
1021 } else { /* TRIG_EXT */
1022 bits |= EXT_TRIGGER | TGEN | XTRCL;
1023 if (thisboard->is_1602) {
1024 if (cmd->start_arg & CR_INVERT)
1026 if (cmd->start_arg & CR_EDGE)
1030 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1032 outw(bits, devpriv->control_status + TRIG_CONTSTAT);
1037 static int cb_pcidas_ao_check_chanlist(struct comedi_device *dev,
1038 struct comedi_subdevice *s,
1039 struct comedi_cmd *cmd)
1041 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
1043 if (cmd->chanlist_len > 1) {
1044 unsigned int chan1 = CR_CHAN(cmd->chanlist[1]);
1046 if (chan0 != 0 || chan1 != 1) {
1047 dev_dbg(dev->class_dev,
1048 "channels must be ordered channel 0, channel 1 in chanlist\n");
1056 static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
1057 struct comedi_subdevice *s,
1058 struct comedi_cmd *cmd)
1060 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1061 struct cb_pcidas_private *devpriv = dev->private;
1065 /* Step 1 : check if triggers are trivially valid */
1067 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT);
1068 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
1069 TRIG_TIMER | TRIG_EXT);
1070 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
1071 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1072 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1077 /* Step 2a : make sure trigger sources are unique */
1079 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
1080 err |= cfc_check_trigger_is_unique(cmd->stop_src);
1082 /* Step 2b : and mutually compatible */
1087 /* Step 3: check if arguments are trivially valid */
1089 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1091 if (cmd->scan_begin_src == TRIG_TIMER)
1092 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1093 thisboard->ao_scan_speed);
1095 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1097 if (cmd->stop_src == TRIG_NONE)
1098 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1103 /* step 4: fix up any arguments */
1105 if (cmd->scan_begin_src == TRIG_TIMER) {
1106 arg = cmd->scan_begin_arg;
1107 i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
1108 &devpriv->ao_divisor1,
1109 &devpriv->ao_divisor2,
1111 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
1117 /* Step 5: check channel list if it exists */
1118 if (cmd->chanlist && cmd->chanlist_len > 0)
1119 err |= cb_pcidas_ao_check_chanlist(dev, s, cmd);
1127 /* cancel analog input command */
1128 static int cb_pcidas_cancel(struct comedi_device *dev,
1129 struct comedi_subdevice *s)
1131 struct cb_pcidas_private *devpriv = dev->private;
1132 unsigned long flags;
1134 spin_lock_irqsave(&dev->spinlock, flags);
1135 /* disable interrupts */
1136 devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
1137 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1138 spin_unlock_irqrestore(&dev->spinlock, flags);
1140 /* disable start trigger source and burst mode */
1141 outw(0, devpriv->control_status + TRIG_CONTSTAT);
1142 /* software pacer source */
1143 outw(0, devpriv->control_status + ADCMUX_CONT);
1148 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1149 struct comedi_subdevice *s,
1150 unsigned int trig_num)
1152 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1153 struct cb_pcidas_private *devpriv = dev->private;
1154 unsigned int num_bytes, num_points = thisboard->fifo_size;
1155 struct comedi_async *async = s->async;
1156 struct comedi_cmd *cmd = &s->async->cmd;
1157 unsigned long flags;
1159 if (trig_num != cmd->start_arg)
1163 if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
1164 num_points = devpriv->ao_count;
1166 num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1167 num_points * sizeof(short));
1168 num_points = num_bytes / sizeof(short);
1170 if (cmd->stop_src == TRIG_COUNT)
1171 devpriv->ao_count -= num_points;
1172 /* write data to board's fifo */
1173 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
1175 /* enable dac half-full and empty interrupts */
1176 spin_lock_irqsave(&dev->spinlock, flags);
1177 devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
1179 /* enable and clear interrupts */
1180 outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
1181 devpriv->control_status + INT_ADCFIFO);
1184 devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1185 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1187 spin_unlock_irqrestore(&dev->spinlock, flags);
1189 async->inttrig = NULL;
1194 static void cb_pcidas_ao_load_counters(struct comedi_device *dev)
1196 struct cb_pcidas_private *devpriv = dev->private;
1197 unsigned long timer_base = devpriv->pacer_counter_dio + DAC8254;
1199 i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
1200 i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
1202 i8254_write(timer_base, 0, 1, devpriv->ao_divisor1);
1203 i8254_write(timer_base, 0, 2, devpriv->ao_divisor2);
1206 static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1207 struct comedi_subdevice *s)
1209 struct cb_pcidas_private *devpriv = dev->private;
1210 struct comedi_async *async = s->async;
1211 struct comedi_cmd *cmd = &async->cmd;
1213 unsigned long flags;
1215 /* set channel limits, gain */
1216 spin_lock_irqsave(&dev->spinlock, flags);
1217 for (i = 0; i < cmd->chanlist_len; i++) {
1218 /* enable channel */
1219 devpriv->ao_control_bits |=
1220 DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
1222 devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
1227 /* disable analog out before settings pacer source and count values */
1228 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1229 spin_unlock_irqrestore(&dev->spinlock, flags);
1232 outw(0, devpriv->ao_registers + DACFIFOCLR);
1235 if (cmd->scan_begin_src == TRIG_TIMER)
1236 cb_pcidas_ao_load_counters(dev);
1238 /* set number of conversions */
1239 if (cmd->stop_src == TRIG_COUNT)
1240 devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
1241 /* set pacer source */
1242 spin_lock_irqsave(&dev->spinlock, flags);
1243 switch (cmd->scan_begin_src) {
1245 devpriv->ao_control_bits |= DAC_PACER_INT;
1248 devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1251 spin_unlock_irqrestore(&dev->spinlock, flags);
1252 dev_err(dev->class_dev, "error setting dac pacer source\n");
1255 spin_unlock_irqrestore(&dev->spinlock, flags);
1257 async->inttrig = cb_pcidas_ao_inttrig;
1262 /* cancel analog output command */
1263 static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1264 struct comedi_subdevice *s)
1266 struct cb_pcidas_private *devpriv = dev->private;
1267 unsigned long flags;
1269 spin_lock_irqsave(&dev->spinlock, flags);
1270 /* disable interrupts */
1271 devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
1272 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1274 /* disable output */
1275 devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1276 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1277 spin_unlock_irqrestore(&dev->spinlock, flags);
1282 static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
1284 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1285 struct cb_pcidas_private *devpriv = dev->private;
1286 struct comedi_subdevice *s = dev->write_subdev;
1287 struct comedi_async *async = s->async;
1288 struct comedi_cmd *cmd = &async->cmd;
1289 unsigned int half_fifo = thisboard->fifo_size / 2;
1290 unsigned int num_points;
1291 unsigned long flags;
1293 if (status & DAEMI) {
1294 /* clear dac empty interrupt latch */
1295 spin_lock_irqsave(&dev->spinlock, flags);
1296 outw(devpriv->adc_fifo_bits | DAEMI,
1297 devpriv->control_status + INT_ADCFIFO);
1298 spin_unlock_irqrestore(&dev->spinlock, flags);
1299 if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
1300 if (cmd->stop_src == TRIG_NONE ||
1301 (cmd->stop_src == TRIG_COUNT
1302 && devpriv->ao_count)) {
1303 dev_err(dev->class_dev, "dac fifo underflow\n");
1304 async->events |= COMEDI_CB_ERROR;
1306 async->events |= COMEDI_CB_EOA;
1308 } else if (status & DAHFI) {
1309 unsigned int num_bytes;
1311 /* figure out how many points we are writing to fifo */
1312 num_points = half_fifo;
1313 if (cmd->stop_src == TRIG_COUNT &&
1314 devpriv->ao_count < num_points)
1315 num_points = devpriv->ao_count;
1317 cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1318 num_points * sizeof(short));
1319 num_points = num_bytes / sizeof(short);
1321 if (cmd->stop_src == TRIG_COUNT)
1322 devpriv->ao_count -= num_points;
1323 /* write data to board's fifo */
1324 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
1326 /* clear half-full interrupt latch */
1327 spin_lock_irqsave(&dev->spinlock, flags);
1328 outw(devpriv->adc_fifo_bits | DAHFI,
1329 devpriv->control_status + INT_ADCFIFO);
1330 spin_unlock_irqrestore(&dev->spinlock, flags);
1333 cfc_handle_events(dev, s);
1336 static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1338 struct comedi_device *dev = (struct comedi_device *)d;
1339 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1340 struct cb_pcidas_private *devpriv = dev->private;
1341 struct comedi_subdevice *s = dev->read_subdev;
1342 struct comedi_async *async;
1343 struct comedi_cmd *cmd;
1344 int status, s5933_status;
1345 int half_fifo = thisboard->fifo_size / 2;
1346 unsigned int num_samples, i;
1347 static const int timeout = 10000;
1348 unsigned long flags;
1356 s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1358 if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
1361 /* make sure mailbox 4 is empty */
1362 inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1363 /* clear interrupt on amcc s5933 */
1364 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1365 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1367 status = inw(devpriv->control_status + INT_ADCFIFO);
1369 /* check for analog output interrupt */
1370 if (status & (DAHFI | DAEMI))
1371 handle_ao_interrupt(dev, status);
1372 /* check for analog input interrupts */
1373 /* if fifo half-full */
1374 if (status & ADHFI) {
1376 num_samples = half_fifo;
1377 if (cmd->stop_src == TRIG_COUNT &&
1378 num_samples > devpriv->count) {
1379 num_samples = devpriv->count;
1381 insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
1383 cfc_write_array_to_buffer(s, devpriv->ai_buffer,
1384 num_samples * sizeof(short));
1385 devpriv->count -= num_samples;
1386 if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
1387 async->events |= COMEDI_CB_EOA;
1388 /* clear half-full interrupt latch */
1389 spin_lock_irqsave(&dev->spinlock, flags);
1390 outw(devpriv->adc_fifo_bits | INT,
1391 devpriv->control_status + INT_ADCFIFO);
1392 spin_unlock_irqrestore(&dev->spinlock, flags);
1393 /* else if fifo not empty */
1394 } else if (status & (ADNEI | EOBI)) {
1395 for (i = 0; i < timeout; i++) {
1396 /* break if fifo is empty */
1397 if ((ADNE & inw(devpriv->control_status +
1400 cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
1401 if (cmd->stop_src == TRIG_COUNT &&
1402 --devpriv->count == 0) {
1403 /* end of acquisition */
1404 async->events |= COMEDI_CB_EOA;
1408 /* clear not-empty interrupt latch */
1409 spin_lock_irqsave(&dev->spinlock, flags);
1410 outw(devpriv->adc_fifo_bits | INT,
1411 devpriv->control_status + INT_ADCFIFO);
1412 spin_unlock_irqrestore(&dev->spinlock, flags);
1413 } else if (status & EOAI) {
1414 dev_err(dev->class_dev,
1415 "bug! encountered end of acquisition interrupt?\n");
1416 /* clear EOA interrupt latch */
1417 spin_lock_irqsave(&dev->spinlock, flags);
1418 outw(devpriv->adc_fifo_bits | EOAI,
1419 devpriv->control_status + INT_ADCFIFO);
1420 spin_unlock_irqrestore(&dev->spinlock, flags);
1422 /* check for fifo overflow */
1423 if (status & LADFUL) {
1424 dev_err(dev->class_dev, "fifo overflow\n");
1425 /* clear overflow interrupt latch */
1426 spin_lock_irqsave(&dev->spinlock, flags);
1427 outw(devpriv->adc_fifo_bits | LADFUL,
1428 devpriv->control_status + INT_ADCFIFO);
1429 spin_unlock_irqrestore(&dev->spinlock, flags);
1430 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1433 cfc_handle_events(dev, s);
1438 static int cb_pcidas_auto_attach(struct comedi_device *dev,
1439 unsigned long context)
1441 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1442 const struct cb_pcidas_board *thisboard = NULL;
1443 struct cb_pcidas_private *devpriv;
1444 struct comedi_subdevice *s;
1448 if (context < ARRAY_SIZE(cb_pcidas_boards))
1449 thisboard = &cb_pcidas_boards[context];
1452 dev->board_ptr = thisboard;
1453 dev->board_name = thisboard->name;
1455 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1459 ret = comedi_pci_enable(dev);
1463 devpriv->s5933_config = pci_resource_start(pcidev, 0);
1464 devpriv->control_status = pci_resource_start(pcidev, 1);
1465 devpriv->adc_fifo = pci_resource_start(pcidev, 2);
1466 devpriv->pacer_counter_dio = pci_resource_start(pcidev, 3);
1467 if (thisboard->ao_nchan)
1468 devpriv->ao_registers = pci_resource_start(pcidev, 4);
1470 /* disable and clear interrupts on amcc s5933 */
1471 outl(INTCSR_INBOX_INTR_STATUS,
1472 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1474 ret = request_irq(pcidev->irq, cb_pcidas_interrupt, IRQF_SHARED,
1475 dev->board_name, dev);
1477 dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
1481 dev->irq = pcidev->irq;
1483 ret = comedi_alloc_subdevices(dev, 7);
1487 s = &dev->subdevices[0];
1488 /* analog input subdevice */
1489 dev->read_subdev = s;
1490 s->type = COMEDI_SUBD_AI;
1491 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
1492 /* WARNING: Number of inputs in differential mode is ignored */
1493 s->n_chan = thisboard->ai_nchan;
1494 s->len_chanlist = thisboard->ai_nchan;
1495 s->maxdata = (1 << thisboard->ai_bits) - 1;
1496 s->range_table = thisboard->ranges;
1497 s->insn_read = cb_pcidas_ai_rinsn;
1498 s->insn_config = ai_config_insn;
1499 s->do_cmd = cb_pcidas_ai_cmd;
1500 s->do_cmdtest = cb_pcidas_ai_cmdtest;
1501 s->cancel = cb_pcidas_cancel;
1503 /* analog output subdevice */
1504 s = &dev->subdevices[1];
1505 if (thisboard->ao_nchan) {
1506 s->type = COMEDI_SUBD_AO;
1507 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1508 s->n_chan = thisboard->ao_nchan;
1510 * analog out resolution is the same as
1511 * analog input resolution, so use ai_bits
1513 s->maxdata = (1 << thisboard->ai_bits) - 1;
1514 s->range_table = &cb_pcidas_ao_ranges;
1515 s->insn_read = cb_pcidas_ao_readback_insn;
1516 if (thisboard->has_ao_fifo) {
1517 dev->write_subdev = s;
1518 s->subdev_flags |= SDF_CMD_WRITE;
1519 s->insn_write = cb_pcidas_ao_fifo_winsn;
1520 s->do_cmdtest = cb_pcidas_ao_cmdtest;
1521 s->do_cmd = cb_pcidas_ao_cmd;
1522 s->cancel = cb_pcidas_ao_cancel;
1524 s->insn_write = cb_pcidas_ao_nofifo_winsn;
1527 s->type = COMEDI_SUBD_UNUSED;
1531 s = &dev->subdevices[2];
1532 ret = subdev_8255_init(dev, s, NULL,
1533 devpriv->pacer_counter_dio + DIO_8255);
1537 /* serial EEPROM, */
1538 s = &dev->subdevices[3];
1539 s->type = COMEDI_SUBD_MEMORY;
1540 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
1543 s->insn_read = eeprom_read_insn;
1546 s = &dev->subdevices[4];
1547 s->type = COMEDI_SUBD_CALIB;
1548 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1549 s->n_chan = NUM_CHANNELS_8800;
1551 s->insn_read = caldac_read_insn;
1552 s->insn_write = caldac_write_insn;
1553 for (i = 0; i < s->n_chan; i++)
1554 caldac_8800_write(dev, i, s->maxdata / 2);
1556 /* trim potentiometer */
1557 s = &dev->subdevices[5];
1558 s->type = COMEDI_SUBD_CALIB;
1559 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1560 if (thisboard->trimpot == AD7376) {
1561 s->n_chan = NUM_CHANNELS_7376;
1564 s->n_chan = NUM_CHANNELS_8402;
1567 s->insn_read = trimpot_read_insn;
1568 s->insn_write = trimpot_write_insn;
1569 for (i = 0; i < s->n_chan; i++)
1570 cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
1573 s = &dev->subdevices[6];
1574 if (thisboard->has_dac08) {
1575 s->type = COMEDI_SUBD_CALIB;
1576 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1577 s->n_chan = NUM_CHANNELS_DAC08;
1578 s->insn_read = dac08_read_insn;
1579 s->insn_write = dac08_write_insn;
1581 dac08_write(dev, s->maxdata / 2);
1583 s->type = COMEDI_SUBD_UNUSED;
1585 /* make sure mailbox 4 is empty */
1586 inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1587 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1588 devpriv->s5933_intcsr_bits =
1589 INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1590 INTCSR_INBOX_FULL_INT;
1591 /* clear and enable interrupt on amcc s5933 */
1592 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1593 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1598 static void cb_pcidas_detach(struct comedi_device *dev)
1600 struct cb_pcidas_private *devpriv = dev->private;
1603 if (devpriv->s5933_config) {
1604 outl(INTCSR_INBOX_INTR_STATUS,
1605 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1609 free_irq(dev->irq, dev);
1610 comedi_pci_disable(dev);
1613 static struct comedi_driver cb_pcidas_driver = {
1614 .driver_name = "cb_pcidas",
1615 .module = THIS_MODULE,
1616 .auto_attach = cb_pcidas_auto_attach,
1617 .detach = cb_pcidas_detach,
1620 static int cb_pcidas_pci_probe(struct pci_dev *dev,
1621 const struct pci_device_id *id)
1623 return comedi_pci_auto_config(dev, &cb_pcidas_driver,
1627 static const struct pci_device_id cb_pcidas_pci_table[] = {
1628 { PCI_VDEVICE(CB, 0x0001), BOARD_PCIDAS1602_16 },
1629 { PCI_VDEVICE(CB, 0x000f), BOARD_PCIDAS1200 },
1630 { PCI_VDEVICE(CB, 0x0010), BOARD_PCIDAS1602_12 },
1631 { PCI_VDEVICE(CB, 0x0019), BOARD_PCIDAS1200_JR },
1632 { PCI_VDEVICE(CB, 0x001c), BOARD_PCIDAS1602_16_JR },
1633 { PCI_VDEVICE(CB, 0x004c), BOARD_PCIDAS1000 },
1634 { PCI_VDEVICE(CB, 0x001a), BOARD_PCIDAS1001 },
1635 { PCI_VDEVICE(CB, 0x001b), BOARD_PCIDAS1002 },
1638 MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
1640 static struct pci_driver cb_pcidas_pci_driver = {
1641 .name = "cb_pcidas",
1642 .id_table = cb_pcidas_pci_table,
1643 .probe = cb_pcidas_pci_probe,
1644 .remove = comedi_pci_auto_unconfig,
1646 module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver);
1648 MODULE_AUTHOR("Comedi http://www.comedi.org");
1649 MODULE_DESCRIPTION("Comedi low-level driver");
1650 MODULE_LICENSE("GPL");