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;
469 /* analog output insn for pcidas-1000 and 1200 series */
470 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev,
471 struct comedi_subdevice *s,
472 struct comedi_insn *insn,
475 struct cb_pcidas_private *devpriv = dev->private;
476 unsigned int chan = CR_CHAN(insn->chanspec);
477 unsigned int range = CR_RANGE(insn->chanspec);
480 /* set channel and range */
481 spin_lock_irqsave(&dev->spinlock, flags);
482 devpriv->ao_control_bits &= (~DAC_MODE_UPDATE_BOTH &
483 ~DAC_RANGE_MASK(chan));
484 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range));
485 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
486 spin_unlock_irqrestore(&dev->spinlock, flags);
488 /* remember value for readback */
489 devpriv->ao_value[chan] = data[0];
492 outw(data[0], devpriv->ao_registers + DAC_DATA_REG(chan));
497 /* analog output insn for pcidas-1602 series */
498 static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev,
499 struct comedi_subdevice *s,
500 struct comedi_insn *insn, unsigned int *data)
502 struct cb_pcidas_private *devpriv = dev->private;
503 unsigned int chan = CR_CHAN(insn->chanspec);
504 unsigned int range = CR_RANGE(insn->chanspec);
508 outw(0, devpriv->ao_registers + DACFIFOCLR);
510 /* set channel and range */
511 spin_lock_irqsave(&dev->spinlock, flags);
512 devpriv->ao_control_bits &= (~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) &
513 ~DAC_RANGE_MASK(chan) & ~DAC_PACER_MASK);
514 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range) |
515 DAC_CHAN_EN(chan) | DAC_START);
516 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
517 spin_unlock_irqrestore(&dev->spinlock, flags);
519 /* remember value for readback */
520 devpriv->ao_value[chan] = data[0];
523 outw(data[0], devpriv->ao_registers + DACDATA);
528 static int cb_pcidas_ao_readback_insn(struct comedi_device *dev,
529 struct comedi_subdevice *s,
530 struct comedi_insn *insn,
533 struct cb_pcidas_private *devpriv = dev->private;
535 data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
540 static int wait_for_nvram_ready(unsigned long s5933_base_addr)
542 static const int timeout = 1000;
545 for (i = 0; i < timeout; i++) {
546 if ((inb(s5933_base_addr +
547 AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
555 static int nvram_read(struct comedi_device *dev, unsigned int address,
558 struct cb_pcidas_private *devpriv = dev->private;
559 unsigned long iobase = devpriv->s5933_config;
561 if (wait_for_nvram_ready(iobase) < 0)
564 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
565 iobase + AMCC_OP_REG_MCSR_NVCMD);
566 outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
567 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
568 iobase + AMCC_OP_REG_MCSR_NVCMD);
569 outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
570 outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
572 if (wait_for_nvram_ready(iobase) < 0)
575 *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
580 static int eeprom_read_insn(struct comedi_device *dev,
581 struct comedi_subdevice *s,
582 struct comedi_insn *insn, unsigned int *data)
587 retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
591 data[0] = nvram_data;
596 static void write_calibration_bitstream(struct comedi_device *dev,
597 unsigned int register_bits,
598 unsigned int bitstream,
599 unsigned int bitstream_length)
601 struct cb_pcidas_private *devpriv = dev->private;
602 static const int write_delay = 1;
605 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
607 register_bits |= SERIAL_DATA_IN_BIT;
609 register_bits &= ~SERIAL_DATA_IN_BIT;
611 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
615 static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
618 struct cb_pcidas_private *devpriv = dev->private;
619 static const int num_caldac_channels = 8;
620 static const int bitstream_length = 11;
621 unsigned int bitstream = ((address & 0x7) << 8) | value;
622 static const int caldac_8800_udelay = 1;
624 if (address >= num_caldac_channels) {
625 comedi_error(dev, "illegal caldac channel");
629 if (value == devpriv->caldac_value[address])
632 devpriv->caldac_value[address] = value;
634 write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
637 udelay(caldac_8800_udelay);
638 outw(cal_enable_bits(dev) | SELECT_8800_BIT,
639 devpriv->control_status + CALIBRATION_REG);
640 udelay(caldac_8800_udelay);
641 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
646 static int caldac_write_insn(struct comedi_device *dev,
647 struct comedi_subdevice *s,
648 struct comedi_insn *insn, unsigned int *data)
650 const unsigned int channel = CR_CHAN(insn->chanspec);
652 return caldac_8800_write(dev, channel, data[0]);
655 static int caldac_read_insn(struct comedi_device *dev,
656 struct comedi_subdevice *s,
657 struct comedi_insn *insn, unsigned int *data)
659 struct cb_pcidas_private *devpriv = dev->private;
661 data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)];
666 /* 1602/16 pregain offset */
667 static void dac08_write(struct comedi_device *dev, unsigned int value)
669 struct cb_pcidas_private *devpriv = dev->private;
670 unsigned long cal_reg;
672 if (devpriv->dac08_value != value) {
673 devpriv->dac08_value = value;
675 cal_reg = devpriv->control_status + CALIBRATION_REG;
678 value |= cal_enable_bits(dev);
680 /* latch the new value into the caldac */
681 outw(value, cal_reg);
683 outw(value | SELECT_DAC08_BIT, cal_reg);
685 outw(value, cal_reg);
690 static int dac08_write_insn(struct comedi_device *dev,
691 struct comedi_subdevice *s,
692 struct comedi_insn *insn, unsigned int *data)
696 for (i = 0; i < insn->n; i++)
697 dac08_write(dev, data[i]);
702 static int dac08_read_insn(struct comedi_device *dev,
703 struct comedi_subdevice *s, struct comedi_insn *insn,
706 struct cb_pcidas_private *devpriv = dev->private;
708 data[0] = devpriv->dac08_value;
713 static int trimpot_7376_write(struct comedi_device *dev, uint8_t value)
715 struct cb_pcidas_private *devpriv = dev->private;
716 static const int bitstream_length = 7;
717 unsigned int bitstream = value & 0x7f;
718 unsigned int register_bits;
719 static const int ad7376_udelay = 1;
721 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
722 udelay(ad7376_udelay);
723 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
725 write_calibration_bitstream(dev, register_bits, bitstream,
728 udelay(ad7376_udelay);
729 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
736 * ch 1 : adc postgain offset */
737 static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
740 struct cb_pcidas_private *devpriv = dev->private;
741 static const int bitstream_length = 10;
742 unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
743 unsigned int register_bits;
744 static const int ad8402_udelay = 1;
746 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
747 udelay(ad8402_udelay);
748 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
750 write_calibration_bitstream(dev, register_bits, bitstream,
753 udelay(ad8402_udelay);
754 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
759 static int cb_pcidas_trimpot_write(struct comedi_device *dev,
760 unsigned int channel, unsigned int value)
762 const struct cb_pcidas_board *thisboard = comedi_board(dev);
763 struct cb_pcidas_private *devpriv = dev->private;
765 if (devpriv->trimpot_value[channel] == value)
768 devpriv->trimpot_value[channel] = value;
769 switch (thisboard->trimpot) {
771 trimpot_7376_write(dev, value);
774 trimpot_8402_write(dev, channel, value);
777 comedi_error(dev, "driver bug?");
785 static int trimpot_write_insn(struct comedi_device *dev,
786 struct comedi_subdevice *s,
787 struct comedi_insn *insn, unsigned int *data)
789 unsigned int channel = CR_CHAN(insn->chanspec);
791 return cb_pcidas_trimpot_write(dev, channel, data[0]);
794 static int trimpot_read_insn(struct comedi_device *dev,
795 struct comedi_subdevice *s,
796 struct comedi_insn *insn, unsigned int *data)
798 struct cb_pcidas_private *devpriv = dev->private;
799 unsigned int channel = CR_CHAN(insn->chanspec);
801 data[0] = devpriv->trimpot_value[channel];
806 static int cb_pcidas_ai_check_chanlist(struct comedi_device *dev,
807 struct comedi_subdevice *s,
808 struct comedi_cmd *cmd)
810 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
811 unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
814 for (i = 1; i < cmd->chanlist_len; i++) {
815 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
816 unsigned int range = CR_RANGE(cmd->chanlist[i]);
818 if (chan != (chan0 + i) % s->n_chan) {
819 dev_dbg(dev->class_dev,
820 "entries in chanlist must be consecutive channels, counting upwards\n");
824 if (range != range0) {
825 dev_dbg(dev->class_dev,
826 "entries in chanlist must all have the same gain\n");
833 static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
834 struct comedi_subdevice *s,
835 struct comedi_cmd *cmd)
837 const struct cb_pcidas_board *thisboard = comedi_board(dev);
838 struct cb_pcidas_private *devpriv = dev->private;
842 /* Step 1 : check if triggers are trivially valid */
844 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
845 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
846 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
847 err |= cfc_check_trigger_src(&cmd->convert_src,
848 TRIG_TIMER | TRIG_NOW | TRIG_EXT);
849 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
850 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
855 /* Step 2a : make sure trigger sources are unique */
857 err |= cfc_check_trigger_is_unique(cmd->start_src);
858 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
859 err |= cfc_check_trigger_is_unique(cmd->convert_src);
860 err |= cfc_check_trigger_is_unique(cmd->stop_src);
862 /* Step 2b : and mutually compatible */
864 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
866 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
868 if (cmd->start_src == TRIG_EXT &&
869 (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))
875 /* Step 3: check if arguments are trivially valid */
877 switch (cmd->start_src) {
879 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
882 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
884 & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
885 cmd->start_arg &= ~(CR_FLAGS_MASK &
886 ~(CR_EDGE | CR_INVERT));
889 if (!thisboard->is_1602 && (cmd->start_arg & CR_INVERT)) {
890 cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
896 if (cmd->scan_begin_src == TRIG_TIMER)
897 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
898 thisboard->ai_speed * cmd->chanlist_len);
900 if (cmd->convert_src == TRIG_TIMER)
901 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
902 thisboard->ai_speed);
904 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
906 if (cmd->stop_src == TRIG_NONE)
907 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
912 /* step 4: fix up any arguments */
914 if (cmd->scan_begin_src == TRIG_TIMER) {
915 arg = cmd->scan_begin_arg;
916 i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
920 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
922 if (cmd->convert_src == TRIG_TIMER) {
923 arg = cmd->convert_arg;
924 i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
928 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
934 /* Step 5: check channel list if it exists */
935 if (cmd->chanlist && cmd->chanlist_len > 0)
936 err |= cb_pcidas_ai_check_chanlist(dev, s, cmd);
944 static void cb_pcidas_ai_load_counters(struct comedi_device *dev)
946 struct cb_pcidas_private *devpriv = dev->private;
947 unsigned long timer_base = devpriv->pacer_counter_dio + ADC8254;
949 i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
950 i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
952 i8254_write(timer_base, 0, 1, devpriv->divisor1);
953 i8254_write(timer_base, 0, 2, devpriv->divisor2);
956 static int cb_pcidas_ai_cmd(struct comedi_device *dev,
957 struct comedi_subdevice *s)
959 const struct cb_pcidas_board *thisboard = comedi_board(dev);
960 struct cb_pcidas_private *devpriv = dev->private;
961 struct comedi_async *async = s->async;
962 struct comedi_cmd *cmd = &async->cmd;
966 /* make sure CAL_EN_BIT is disabled */
967 outw(0, devpriv->control_status + CALIBRATION_REG);
968 /* initialize before settings pacer source and count values */
969 outw(0, devpriv->control_status + TRIG_CONTSTAT);
971 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
973 /* set mux limits, gain and pacer source */
974 bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
975 END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
976 GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
977 /* set unipolar/bipolar */
978 if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
980 /* set singleended/differential */
981 if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
983 /* set pacer source */
984 if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
985 bits |= PACER_EXT_RISE;
988 outw(bits, devpriv->control_status + ADCMUX_CONT);
991 if (cmd->scan_begin_src == TRIG_TIMER || cmd->convert_src == TRIG_TIMER)
992 cb_pcidas_ai_load_counters(dev);
994 /* set number of conversions */
995 if (cmd->stop_src == TRIG_COUNT)
996 devpriv->count = cmd->chanlist_len * cmd->stop_arg;
997 /* enable interrupts */
998 spin_lock_irqsave(&dev->spinlock, flags);
999 devpriv->adc_fifo_bits |= INTE;
1000 devpriv->adc_fifo_bits &= ~INT_MASK;
1001 if (cmd->flags & TRIG_WAKE_EOS) {
1002 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) {
1003 /* interrupt end of burst */
1004 devpriv->adc_fifo_bits |= INT_EOS;
1006 /* interrupt fifo not empty */
1007 devpriv->adc_fifo_bits |= INT_FNE;
1010 /* interrupt fifo half full */
1011 devpriv->adc_fifo_bits |= INT_FHF;
1014 /* enable (and clear) interrupts */
1015 outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
1016 devpriv->control_status + INT_ADCFIFO);
1017 spin_unlock_irqrestore(&dev->spinlock, flags);
1019 /* set start trigger and burst mode */
1021 if (cmd->start_src == TRIG_NOW) {
1023 } else { /* TRIG_EXT */
1024 bits |= EXT_TRIGGER | TGEN | XTRCL;
1025 if (thisboard->is_1602) {
1026 if (cmd->start_arg & CR_INVERT)
1028 if (cmd->start_arg & CR_EDGE)
1032 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1034 outw(bits, devpriv->control_status + TRIG_CONTSTAT);
1039 static int cb_pcidas_ao_check_chanlist(struct comedi_device *dev,
1040 struct comedi_subdevice *s,
1041 struct comedi_cmd *cmd)
1043 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
1045 if (cmd->chanlist_len > 1) {
1046 unsigned int chan1 = CR_CHAN(cmd->chanlist[1]);
1048 if (chan0 != 0 || chan1 != 1) {
1049 dev_dbg(dev->class_dev,
1050 "channels must be ordered channel 0, channel 1 in chanlist\n");
1058 static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
1059 struct comedi_subdevice *s,
1060 struct comedi_cmd *cmd)
1062 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1063 struct cb_pcidas_private *devpriv = dev->private;
1067 /* Step 1 : check if triggers are trivially valid */
1069 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT);
1070 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
1071 TRIG_TIMER | TRIG_EXT);
1072 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
1073 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1074 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1079 /* Step 2a : make sure trigger sources are unique */
1081 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
1082 err |= cfc_check_trigger_is_unique(cmd->stop_src);
1084 /* Step 2b : and mutually compatible */
1089 /* Step 3: check if arguments are trivially valid */
1091 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1093 if (cmd->scan_begin_src == TRIG_TIMER)
1094 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1095 thisboard->ao_scan_speed);
1097 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1099 if (cmd->stop_src == TRIG_NONE)
1100 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1105 /* step 4: fix up any arguments */
1107 if (cmd->scan_begin_src == TRIG_TIMER) {
1108 arg = cmd->scan_begin_arg;
1109 i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
1110 &devpriv->ao_divisor1,
1111 &devpriv->ao_divisor2,
1113 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
1119 /* Step 5: check channel list if it exists */
1120 if (cmd->chanlist && cmd->chanlist_len > 0)
1121 err |= cb_pcidas_ao_check_chanlist(dev, s, cmd);
1129 /* cancel analog input command */
1130 static int cb_pcidas_cancel(struct comedi_device *dev,
1131 struct comedi_subdevice *s)
1133 struct cb_pcidas_private *devpriv = dev->private;
1134 unsigned long flags;
1136 spin_lock_irqsave(&dev->spinlock, flags);
1137 /* disable interrupts */
1138 devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
1139 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1140 spin_unlock_irqrestore(&dev->spinlock, flags);
1142 /* disable start trigger source and burst mode */
1143 outw(0, devpriv->control_status + TRIG_CONTSTAT);
1144 /* software pacer source */
1145 outw(0, devpriv->control_status + ADCMUX_CONT);
1150 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1151 struct comedi_subdevice *s,
1152 unsigned int trig_num)
1154 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1155 struct cb_pcidas_private *devpriv = dev->private;
1156 unsigned int num_bytes, num_points = thisboard->fifo_size;
1157 struct comedi_async *async = s->async;
1158 struct comedi_cmd *cmd = &s->async->cmd;
1159 unsigned long flags;
1161 if (trig_num != cmd->start_arg)
1165 if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
1166 num_points = devpriv->ao_count;
1168 num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1169 num_points * sizeof(short));
1170 num_points = num_bytes / sizeof(short);
1172 if (cmd->stop_src == TRIG_COUNT)
1173 devpriv->ao_count -= num_points;
1174 /* write data to board's fifo */
1175 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
1177 /* enable dac half-full and empty interrupts */
1178 spin_lock_irqsave(&dev->spinlock, flags);
1179 devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
1181 /* enable and clear interrupts */
1182 outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
1183 devpriv->control_status + INT_ADCFIFO);
1186 devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1187 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1189 spin_unlock_irqrestore(&dev->spinlock, flags);
1191 async->inttrig = NULL;
1196 static void cb_pcidas_ao_load_counters(struct comedi_device *dev)
1198 struct cb_pcidas_private *devpriv = dev->private;
1199 unsigned long timer_base = devpriv->pacer_counter_dio + DAC8254;
1201 i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
1202 i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
1204 i8254_write(timer_base, 0, 1, devpriv->ao_divisor1);
1205 i8254_write(timer_base, 0, 2, devpriv->ao_divisor2);
1208 static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1209 struct comedi_subdevice *s)
1211 struct cb_pcidas_private *devpriv = dev->private;
1212 struct comedi_async *async = s->async;
1213 struct comedi_cmd *cmd = &async->cmd;
1215 unsigned long flags;
1217 /* set channel limits, gain */
1218 spin_lock_irqsave(&dev->spinlock, flags);
1219 for (i = 0; i < cmd->chanlist_len; i++) {
1220 /* enable channel */
1221 devpriv->ao_control_bits |=
1222 DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
1224 devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
1229 /* disable analog out before settings pacer source and count values */
1230 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1231 spin_unlock_irqrestore(&dev->spinlock, flags);
1234 outw(0, devpriv->ao_registers + DACFIFOCLR);
1237 if (cmd->scan_begin_src == TRIG_TIMER)
1238 cb_pcidas_ao_load_counters(dev);
1240 /* set number of conversions */
1241 if (cmd->stop_src == TRIG_COUNT)
1242 devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
1243 /* set pacer source */
1244 spin_lock_irqsave(&dev->spinlock, flags);
1245 switch (cmd->scan_begin_src) {
1247 devpriv->ao_control_bits |= DAC_PACER_INT;
1250 devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1253 spin_unlock_irqrestore(&dev->spinlock, flags);
1254 comedi_error(dev, "error setting dac pacer source");
1258 spin_unlock_irqrestore(&dev->spinlock, flags);
1260 async->inttrig = cb_pcidas_ao_inttrig;
1265 /* cancel analog output command */
1266 static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1267 struct comedi_subdevice *s)
1269 struct cb_pcidas_private *devpriv = dev->private;
1270 unsigned long flags;
1272 spin_lock_irqsave(&dev->spinlock, flags);
1273 /* disable interrupts */
1274 devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
1275 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1277 /* disable output */
1278 devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1279 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1280 spin_unlock_irqrestore(&dev->spinlock, flags);
1285 static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
1287 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1288 struct cb_pcidas_private *devpriv = dev->private;
1289 struct comedi_subdevice *s = dev->write_subdev;
1290 struct comedi_async *async = s->async;
1291 struct comedi_cmd *cmd = &async->cmd;
1292 unsigned int half_fifo = thisboard->fifo_size / 2;
1293 unsigned int num_points;
1294 unsigned long flags;
1296 if (status & DAEMI) {
1297 /* clear dac empty interrupt latch */
1298 spin_lock_irqsave(&dev->spinlock, flags);
1299 outw(devpriv->adc_fifo_bits | DAEMI,
1300 devpriv->control_status + INT_ADCFIFO);
1301 spin_unlock_irqrestore(&dev->spinlock, flags);
1302 if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
1303 if (cmd->stop_src == TRIG_NONE ||
1304 (cmd->stop_src == TRIG_COUNT
1305 && devpriv->ao_count)) {
1306 comedi_error(dev, "dac fifo underflow");
1307 async->events |= COMEDI_CB_ERROR;
1309 async->events |= COMEDI_CB_EOA;
1311 } else if (status & DAHFI) {
1312 unsigned int num_bytes;
1314 /* figure out how many points we are writing to fifo */
1315 num_points = half_fifo;
1316 if (cmd->stop_src == TRIG_COUNT &&
1317 devpriv->ao_count < num_points)
1318 num_points = devpriv->ao_count;
1320 cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1321 num_points * sizeof(short));
1322 num_points = num_bytes / sizeof(short);
1324 if (cmd->stop_src == TRIG_COUNT)
1325 devpriv->ao_count -= num_points;
1326 /* write data to board's fifo */
1327 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
1329 /* clear half-full interrupt latch */
1330 spin_lock_irqsave(&dev->spinlock, flags);
1331 outw(devpriv->adc_fifo_bits | DAHFI,
1332 devpriv->control_status + INT_ADCFIFO);
1333 spin_unlock_irqrestore(&dev->spinlock, flags);
1336 cfc_handle_events(dev, s);
1339 static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1341 struct comedi_device *dev = (struct comedi_device *)d;
1342 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1343 struct cb_pcidas_private *devpriv = dev->private;
1344 struct comedi_subdevice *s = dev->read_subdev;
1345 struct comedi_async *async;
1346 struct comedi_cmd *cmd;
1347 int status, s5933_status;
1348 int half_fifo = thisboard->fifo_size / 2;
1349 unsigned int num_samples, i;
1350 static const int timeout = 10000;
1351 unsigned long flags;
1359 s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1361 if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
1364 /* make sure mailbox 4 is empty */
1365 inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1366 /* clear interrupt on amcc s5933 */
1367 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1368 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1370 status = inw(devpriv->control_status + INT_ADCFIFO);
1372 /* check for analog output interrupt */
1373 if (status & (DAHFI | DAEMI))
1374 handle_ao_interrupt(dev, status);
1375 /* check for analog input interrupts */
1376 /* if fifo half-full */
1377 if (status & ADHFI) {
1379 num_samples = half_fifo;
1380 if (cmd->stop_src == TRIG_COUNT &&
1381 num_samples > devpriv->count) {
1382 num_samples = devpriv->count;
1384 insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
1386 cfc_write_array_to_buffer(s, devpriv->ai_buffer,
1387 num_samples * sizeof(short));
1388 devpriv->count -= num_samples;
1389 if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
1390 async->events |= COMEDI_CB_EOA;
1391 /* clear half-full interrupt latch */
1392 spin_lock_irqsave(&dev->spinlock, flags);
1393 outw(devpriv->adc_fifo_bits | INT,
1394 devpriv->control_status + INT_ADCFIFO);
1395 spin_unlock_irqrestore(&dev->spinlock, flags);
1396 /* else if fifo not empty */
1397 } else if (status & (ADNEI | EOBI)) {
1398 for (i = 0; i < timeout; i++) {
1399 /* break if fifo is empty */
1400 if ((ADNE & inw(devpriv->control_status +
1403 cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
1404 if (cmd->stop_src == TRIG_COUNT &&
1405 --devpriv->count == 0) {
1406 /* end of acquisition */
1407 async->events |= COMEDI_CB_EOA;
1411 /* clear not-empty interrupt latch */
1412 spin_lock_irqsave(&dev->spinlock, flags);
1413 outw(devpriv->adc_fifo_bits | INT,
1414 devpriv->control_status + INT_ADCFIFO);
1415 spin_unlock_irqrestore(&dev->spinlock, flags);
1416 } else if (status & EOAI) {
1418 "bug! encountered end of acquisition interrupt?");
1419 /* clear EOA interrupt latch */
1420 spin_lock_irqsave(&dev->spinlock, flags);
1421 outw(devpriv->adc_fifo_bits | EOAI,
1422 devpriv->control_status + INT_ADCFIFO);
1423 spin_unlock_irqrestore(&dev->spinlock, flags);
1425 /* check for fifo overflow */
1426 if (status & LADFUL) {
1427 comedi_error(dev, "fifo overflow");
1428 /* clear overflow interrupt latch */
1429 spin_lock_irqsave(&dev->spinlock, flags);
1430 outw(devpriv->adc_fifo_bits | LADFUL,
1431 devpriv->control_status + INT_ADCFIFO);
1432 spin_unlock_irqrestore(&dev->spinlock, flags);
1433 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1436 cfc_handle_events(dev, s);
1441 static int cb_pcidas_auto_attach(struct comedi_device *dev,
1442 unsigned long context)
1444 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1445 const struct cb_pcidas_board *thisboard = NULL;
1446 struct cb_pcidas_private *devpriv;
1447 struct comedi_subdevice *s;
1451 if (context < ARRAY_SIZE(cb_pcidas_boards))
1452 thisboard = &cb_pcidas_boards[context];
1455 dev->board_ptr = thisboard;
1456 dev->board_name = thisboard->name;
1458 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1462 ret = comedi_pci_enable(dev);
1466 devpriv->s5933_config = pci_resource_start(pcidev, 0);
1467 devpriv->control_status = pci_resource_start(pcidev, 1);
1468 devpriv->adc_fifo = pci_resource_start(pcidev, 2);
1469 devpriv->pacer_counter_dio = pci_resource_start(pcidev, 3);
1470 if (thisboard->ao_nchan)
1471 devpriv->ao_registers = pci_resource_start(pcidev, 4);
1473 /* disable and clear interrupts on amcc s5933 */
1474 outl(INTCSR_INBOX_INTR_STATUS,
1475 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1477 if (request_irq(pcidev->irq, cb_pcidas_interrupt,
1478 IRQF_SHARED, dev->driver->driver_name, dev)) {
1479 dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
1483 dev->irq = pcidev->irq;
1485 ret = comedi_alloc_subdevices(dev, 7);
1489 s = &dev->subdevices[0];
1490 /* analog input subdevice */
1491 dev->read_subdev = s;
1492 s->type = COMEDI_SUBD_AI;
1493 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
1494 /* WARNING: Number of inputs in differential mode is ignored */
1495 s->n_chan = thisboard->ai_nchan;
1496 s->len_chanlist = thisboard->ai_nchan;
1497 s->maxdata = (1 << thisboard->ai_bits) - 1;
1498 s->range_table = thisboard->ranges;
1499 s->insn_read = cb_pcidas_ai_rinsn;
1500 s->insn_config = ai_config_insn;
1501 s->do_cmd = cb_pcidas_ai_cmd;
1502 s->do_cmdtest = cb_pcidas_ai_cmdtest;
1503 s->cancel = cb_pcidas_cancel;
1505 /* analog output subdevice */
1506 s = &dev->subdevices[1];
1507 if (thisboard->ao_nchan) {
1508 s->type = COMEDI_SUBD_AO;
1509 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1510 s->n_chan = thisboard->ao_nchan;
1512 * analog out resolution is the same as
1513 * analog input resolution, so use ai_bits
1515 s->maxdata = (1 << thisboard->ai_bits) - 1;
1516 s->range_table = &cb_pcidas_ao_ranges;
1517 s->insn_read = cb_pcidas_ao_readback_insn;
1518 if (thisboard->has_ao_fifo) {
1519 dev->write_subdev = s;
1520 s->subdev_flags |= SDF_CMD_WRITE;
1521 s->insn_write = cb_pcidas_ao_fifo_winsn;
1522 s->do_cmdtest = cb_pcidas_ao_cmdtest;
1523 s->do_cmd = cb_pcidas_ao_cmd;
1524 s->cancel = cb_pcidas_ao_cancel;
1526 s->insn_write = cb_pcidas_ao_nofifo_winsn;
1529 s->type = COMEDI_SUBD_UNUSED;
1533 s = &dev->subdevices[2];
1534 ret = subdev_8255_init(dev, s, NULL,
1535 devpriv->pacer_counter_dio + DIO_8255);
1539 /* serial EEPROM, */
1540 s = &dev->subdevices[3];
1541 s->type = COMEDI_SUBD_MEMORY;
1542 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
1545 s->insn_read = eeprom_read_insn;
1548 s = &dev->subdevices[4];
1549 s->type = COMEDI_SUBD_CALIB;
1550 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1551 s->n_chan = NUM_CHANNELS_8800;
1553 s->insn_read = caldac_read_insn;
1554 s->insn_write = caldac_write_insn;
1555 for (i = 0; i < s->n_chan; i++)
1556 caldac_8800_write(dev, i, s->maxdata / 2);
1558 /* trim potentiometer */
1559 s = &dev->subdevices[5];
1560 s->type = COMEDI_SUBD_CALIB;
1561 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1562 if (thisboard->trimpot == AD7376) {
1563 s->n_chan = NUM_CHANNELS_7376;
1566 s->n_chan = NUM_CHANNELS_8402;
1569 s->insn_read = trimpot_read_insn;
1570 s->insn_write = trimpot_write_insn;
1571 for (i = 0; i < s->n_chan; i++)
1572 cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
1575 s = &dev->subdevices[6];
1576 if (thisboard->has_dac08) {
1577 s->type = COMEDI_SUBD_CALIB;
1578 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1579 s->n_chan = NUM_CHANNELS_DAC08;
1580 s->insn_read = dac08_read_insn;
1581 s->insn_write = dac08_write_insn;
1583 dac08_write(dev, s->maxdata / 2);
1585 s->type = COMEDI_SUBD_UNUSED;
1587 /* make sure mailbox 4 is empty */
1588 inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1589 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1590 devpriv->s5933_intcsr_bits =
1591 INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1592 INTCSR_INBOX_FULL_INT;
1593 /* clear and enable interrupt on amcc s5933 */
1594 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1595 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1600 static void cb_pcidas_detach(struct comedi_device *dev)
1602 struct cb_pcidas_private *devpriv = dev->private;
1605 if (devpriv->s5933_config) {
1606 outl(INTCSR_INBOX_INTR_STATUS,
1607 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1611 free_irq(dev->irq, dev);
1612 comedi_pci_disable(dev);
1615 static struct comedi_driver cb_pcidas_driver = {
1616 .driver_name = "cb_pcidas",
1617 .module = THIS_MODULE,
1618 .auto_attach = cb_pcidas_auto_attach,
1619 .detach = cb_pcidas_detach,
1622 static int cb_pcidas_pci_probe(struct pci_dev *dev,
1623 const struct pci_device_id *id)
1625 return comedi_pci_auto_config(dev, &cb_pcidas_driver,
1629 static const struct pci_device_id cb_pcidas_pci_table[] = {
1630 { PCI_VDEVICE(CB, 0x0001), BOARD_PCIDAS1602_16 },
1631 { PCI_VDEVICE(CB, 0x000f), BOARD_PCIDAS1200 },
1632 { PCI_VDEVICE(CB, 0x0010), BOARD_PCIDAS1602_12 },
1633 { PCI_VDEVICE(CB, 0x0019), BOARD_PCIDAS1200_JR },
1634 { PCI_VDEVICE(CB, 0x001c), BOARD_PCIDAS1602_16_JR },
1635 { PCI_VDEVICE(CB, 0x004c), BOARD_PCIDAS1000 },
1636 { PCI_VDEVICE(CB, 0x001a), BOARD_PCIDAS1001 },
1637 { PCI_VDEVICE(CB, 0x001b), BOARD_PCIDAS1002 },
1640 MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
1642 static struct pci_driver cb_pcidas_pci_driver = {
1643 .name = "cb_pcidas",
1644 .id_table = cb_pcidas_pci_table,
1645 .probe = cb_pcidas_pci_probe,
1646 .remove = comedi_pci_auto_unconfig,
1648 module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver);
1650 MODULE_AUTHOR("Comedi http://www.comedi.org");
1651 MODULE_DESCRIPTION("Comedi low-level driver");
1652 MODULE_LICENSE("GPL");