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 ao_registers;
346 /* divisors of master clock for analog input pacing */
347 unsigned int divisor1;
348 unsigned int divisor2;
349 /* number of analog input samples remaining */
351 /* bits to write to registers */
352 unsigned int adc_fifo_bits;
353 unsigned int s5933_intcsr_bits;
354 unsigned int ao_control_bits;
356 unsigned short ai_buffer[AI_BUFFER_SIZE];
357 unsigned short ao_buffer[AO_BUFFER_SIZE];
358 /* divisors of master clock for analog output pacing */
359 unsigned int ao_divisor1;
360 unsigned int ao_divisor2;
361 /* number of analog output samples remaining */
362 unsigned int ao_count;
363 unsigned int caldac_value[NUM_CHANNELS_8800];
364 unsigned int trimpot_value[NUM_CHANNELS_8402];
365 unsigned int dac08_value;
366 unsigned int calibration_source;
369 static inline unsigned int cal_enable_bits(struct comedi_device *dev)
371 struct cb_pcidas_private *devpriv = dev->private;
373 return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source);
376 static int cb_pcidas_ai_eoc(struct comedi_device *dev,
377 struct comedi_subdevice *s,
378 struct comedi_insn *insn,
379 unsigned long context)
381 struct cb_pcidas_private *devpriv = dev->private;
384 status = inw(devpriv->control_status + ADCMUX_CONT);
390 static int cb_pcidas_ai_rinsn(struct comedi_device *dev,
391 struct comedi_subdevice *s,
392 struct comedi_insn *insn, unsigned int *data)
394 struct cb_pcidas_private *devpriv = dev->private;
395 unsigned int chan = CR_CHAN(insn->chanspec);
396 unsigned int range = CR_RANGE(insn->chanspec);
397 unsigned int aref = CR_AREF(insn->chanspec);
402 /* enable calibration input if appropriate */
403 if (insn->chanspec & CR_ALT_SOURCE) {
404 outw(cal_enable_bits(dev),
405 devpriv->control_status + CALIBRATION_REG);
408 outw(0, devpriv->control_status + CALIBRATION_REG);
411 /* set mux limits and gain */
412 bits = BEGIN_SCAN(chan) | END_SCAN(chan) | GAIN_BITS(range);
413 /* set unipolar/bipolar */
414 if (range & IS_UNIPOLAR)
416 /* set single-ended/differential */
417 if (aref != AREF_DIFF)
419 outw(bits, devpriv->control_status + ADCMUX_CONT);
422 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
424 /* convert n samples */
425 for (n = 0; n < insn->n; n++) {
426 /* trigger conversion */
427 outw(0, devpriv->adc_fifo + ADCDATA);
429 /* wait for conversion to end */
430 ret = comedi_timeout(dev, s, insn, cb_pcidas_ai_eoc, 0);
435 data[n] = inw(devpriv->adc_fifo + ADCDATA);
438 /* return the number of samples read/written */
442 static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
443 struct comedi_insn *insn, unsigned int *data)
445 struct cb_pcidas_private *devpriv = dev->private;
447 unsigned int source = data[1];
450 case INSN_CONFIG_ALT_SOURCE:
452 dev_err(dev->class_dev,
453 "invalid calibration source: %i\n",
457 devpriv->calibration_source = source;
465 /* analog output insn for pcidas-1000 and 1200 series */
466 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev,
467 struct comedi_subdevice *s,
468 struct comedi_insn *insn,
471 struct cb_pcidas_private *devpriv = dev->private;
472 unsigned int chan = CR_CHAN(insn->chanspec);
473 unsigned int range = CR_RANGE(insn->chanspec);
476 /* set channel and range */
477 spin_lock_irqsave(&dev->spinlock, flags);
478 devpriv->ao_control_bits &= (~DAC_MODE_UPDATE_BOTH &
479 ~DAC_RANGE_MASK(chan));
480 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range));
481 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
482 spin_unlock_irqrestore(&dev->spinlock, flags);
484 /* remember value for readback */
485 s->readback[chan] = data[0];
488 outw(data[0], devpriv->ao_registers + DAC_DATA_REG(chan));
493 /* analog output insn for pcidas-1602 series */
494 static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev,
495 struct comedi_subdevice *s,
496 struct comedi_insn *insn, unsigned int *data)
498 struct cb_pcidas_private *devpriv = dev->private;
499 unsigned int chan = CR_CHAN(insn->chanspec);
500 unsigned int range = CR_RANGE(insn->chanspec);
504 outw(0, devpriv->ao_registers + DACFIFOCLR);
506 /* set channel and range */
507 spin_lock_irqsave(&dev->spinlock, flags);
508 devpriv->ao_control_bits &= (~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) &
509 ~DAC_RANGE_MASK(chan) & ~DAC_PACER_MASK);
510 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range) |
511 DAC_CHAN_EN(chan) | DAC_START);
512 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
513 spin_unlock_irqrestore(&dev->spinlock, flags);
515 /* remember value for readback */
516 s->readback[chan] = data[0];
519 outw(data[0], devpriv->ao_registers + DACDATA);
524 static int wait_for_nvram_ready(unsigned long s5933_base_addr)
526 static const int timeout = 1000;
529 for (i = 0; i < timeout; i++) {
530 if ((inb(s5933_base_addr +
531 AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
539 static int nvram_read(struct comedi_device *dev, unsigned int address,
542 struct cb_pcidas_private *devpriv = dev->private;
543 unsigned long iobase = devpriv->s5933_config;
545 if (wait_for_nvram_ready(iobase) < 0)
548 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
549 iobase + AMCC_OP_REG_MCSR_NVCMD);
550 outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
551 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
552 iobase + AMCC_OP_REG_MCSR_NVCMD);
553 outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
554 outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
556 if (wait_for_nvram_ready(iobase) < 0)
559 *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
564 static int eeprom_read_insn(struct comedi_device *dev,
565 struct comedi_subdevice *s,
566 struct comedi_insn *insn, unsigned int *data)
571 retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
575 data[0] = nvram_data;
580 static void write_calibration_bitstream(struct comedi_device *dev,
581 unsigned int register_bits,
582 unsigned int bitstream,
583 unsigned int bitstream_length)
585 struct cb_pcidas_private *devpriv = dev->private;
586 static const int write_delay = 1;
589 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
591 register_bits |= SERIAL_DATA_IN_BIT;
593 register_bits &= ~SERIAL_DATA_IN_BIT;
595 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
599 static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
602 struct cb_pcidas_private *devpriv = dev->private;
603 static const int num_caldac_channels = 8;
604 static const int bitstream_length = 11;
605 unsigned int bitstream = ((address & 0x7) << 8) | value;
606 static const int caldac_8800_udelay = 1;
608 if (address >= num_caldac_channels) {
609 dev_err(dev->class_dev, "illegal caldac channel\n");
613 if (value == devpriv->caldac_value[address])
616 devpriv->caldac_value[address] = value;
618 write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
621 udelay(caldac_8800_udelay);
622 outw(cal_enable_bits(dev) | SELECT_8800_BIT,
623 devpriv->control_status + CALIBRATION_REG);
624 udelay(caldac_8800_udelay);
625 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
630 static int caldac_write_insn(struct comedi_device *dev,
631 struct comedi_subdevice *s,
632 struct comedi_insn *insn, unsigned int *data)
634 const unsigned int channel = CR_CHAN(insn->chanspec);
636 return caldac_8800_write(dev, channel, data[0]);
639 static int caldac_read_insn(struct comedi_device *dev,
640 struct comedi_subdevice *s,
641 struct comedi_insn *insn, unsigned int *data)
643 struct cb_pcidas_private *devpriv = dev->private;
645 data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)];
650 /* 1602/16 pregain offset */
651 static void dac08_write(struct comedi_device *dev, unsigned int value)
653 struct cb_pcidas_private *devpriv = dev->private;
654 unsigned long cal_reg;
656 if (devpriv->dac08_value != value) {
657 devpriv->dac08_value = value;
659 cal_reg = devpriv->control_status + CALIBRATION_REG;
662 value |= cal_enable_bits(dev);
664 /* latch the new value into the caldac */
665 outw(value, cal_reg);
667 outw(value | SELECT_DAC08_BIT, cal_reg);
669 outw(value, cal_reg);
674 static int dac08_write_insn(struct comedi_device *dev,
675 struct comedi_subdevice *s,
676 struct comedi_insn *insn, unsigned int *data)
680 for (i = 0; i < insn->n; i++)
681 dac08_write(dev, data[i]);
686 static int dac08_read_insn(struct comedi_device *dev,
687 struct comedi_subdevice *s, struct comedi_insn *insn,
690 struct cb_pcidas_private *devpriv = dev->private;
692 data[0] = devpriv->dac08_value;
697 static int trimpot_7376_write(struct comedi_device *dev, uint8_t value)
699 struct cb_pcidas_private *devpriv = dev->private;
700 static const int bitstream_length = 7;
701 unsigned int bitstream = value & 0x7f;
702 unsigned int register_bits;
703 static const int ad7376_udelay = 1;
705 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
706 udelay(ad7376_udelay);
707 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
709 write_calibration_bitstream(dev, register_bits, bitstream,
712 udelay(ad7376_udelay);
713 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
720 * ch 1 : adc postgain offset */
721 static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
724 struct cb_pcidas_private *devpriv = dev->private;
725 static const int bitstream_length = 10;
726 unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
727 unsigned int register_bits;
728 static const int ad8402_udelay = 1;
730 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
731 udelay(ad8402_udelay);
732 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
734 write_calibration_bitstream(dev, register_bits, bitstream,
737 udelay(ad8402_udelay);
738 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
743 static int cb_pcidas_trimpot_write(struct comedi_device *dev,
744 unsigned int channel, unsigned int value)
746 const struct cb_pcidas_board *thisboard = dev->board_ptr;
747 struct cb_pcidas_private *devpriv = dev->private;
749 if (devpriv->trimpot_value[channel] == value)
752 devpriv->trimpot_value[channel] = value;
753 switch (thisboard->trimpot) {
755 trimpot_7376_write(dev, value);
758 trimpot_8402_write(dev, channel, value);
761 dev_err(dev->class_dev, "driver bug?\n");
768 static int trimpot_write_insn(struct comedi_device *dev,
769 struct comedi_subdevice *s,
770 struct comedi_insn *insn, unsigned int *data)
772 unsigned int channel = CR_CHAN(insn->chanspec);
774 return cb_pcidas_trimpot_write(dev, channel, data[0]);
777 static int trimpot_read_insn(struct comedi_device *dev,
778 struct comedi_subdevice *s,
779 struct comedi_insn *insn, unsigned int *data)
781 struct cb_pcidas_private *devpriv = dev->private;
782 unsigned int channel = CR_CHAN(insn->chanspec);
784 data[0] = devpriv->trimpot_value[channel];
789 static int cb_pcidas_ai_check_chanlist(struct comedi_device *dev,
790 struct comedi_subdevice *s,
791 struct comedi_cmd *cmd)
793 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
794 unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
797 for (i = 1; i < cmd->chanlist_len; i++) {
798 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
799 unsigned int range = CR_RANGE(cmd->chanlist[i]);
801 if (chan != (chan0 + i) % s->n_chan) {
802 dev_dbg(dev->class_dev,
803 "entries in chanlist must be consecutive channels, counting upwards\n");
807 if (range != range0) {
808 dev_dbg(dev->class_dev,
809 "entries in chanlist must all have the same gain\n");
816 static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
817 struct comedi_subdevice *s,
818 struct comedi_cmd *cmd)
820 const struct cb_pcidas_board *thisboard = dev->board_ptr;
821 struct cb_pcidas_private *devpriv = dev->private;
825 /* Step 1 : check if triggers are trivially valid */
827 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
828 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
829 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
830 err |= cfc_check_trigger_src(&cmd->convert_src,
831 TRIG_TIMER | TRIG_NOW | TRIG_EXT);
832 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
833 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
838 /* Step 2a : make sure trigger sources are unique */
840 err |= cfc_check_trigger_is_unique(cmd->start_src);
841 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
842 err |= cfc_check_trigger_is_unique(cmd->convert_src);
843 err |= cfc_check_trigger_is_unique(cmd->stop_src);
845 /* Step 2b : and mutually compatible */
847 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
849 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
851 if (cmd->start_src == TRIG_EXT &&
852 (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))
858 /* Step 3: check if arguments are trivially valid */
860 switch (cmd->start_src) {
862 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
865 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
867 & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
868 cmd->start_arg &= ~(CR_FLAGS_MASK &
869 ~(CR_EDGE | CR_INVERT));
872 if (!thisboard->is_1602 && (cmd->start_arg & CR_INVERT)) {
873 cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
879 if (cmd->scan_begin_src == TRIG_TIMER)
880 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
881 thisboard->ai_speed * cmd->chanlist_len);
883 if (cmd->convert_src == TRIG_TIMER)
884 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
885 thisboard->ai_speed);
887 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
889 if (cmd->stop_src == TRIG_COUNT)
890 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
892 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
897 /* step 4: fix up any arguments */
899 if (cmd->scan_begin_src == TRIG_TIMER) {
900 arg = cmd->scan_begin_arg;
901 i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
905 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
907 if (cmd->convert_src == TRIG_TIMER) {
908 arg = cmd->convert_arg;
909 i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
913 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
919 /* Step 5: check channel list if it exists */
920 if (cmd->chanlist && cmd->chanlist_len > 0)
921 err |= cb_pcidas_ai_check_chanlist(dev, s, cmd);
929 static void cb_pcidas_ai_load_counters(struct comedi_device *dev)
931 struct cb_pcidas_private *devpriv = dev->private;
932 unsigned long timer_base = dev->iobase + ADC8254;
934 i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
935 i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
937 i8254_write(timer_base, 0, 1, devpriv->divisor1);
938 i8254_write(timer_base, 0, 2, devpriv->divisor2);
941 static int cb_pcidas_ai_cmd(struct comedi_device *dev,
942 struct comedi_subdevice *s)
944 const struct cb_pcidas_board *thisboard = dev->board_ptr;
945 struct cb_pcidas_private *devpriv = dev->private;
946 struct comedi_async *async = s->async;
947 struct comedi_cmd *cmd = &async->cmd;
951 /* make sure CAL_EN_BIT is disabled */
952 outw(0, devpriv->control_status + CALIBRATION_REG);
953 /* initialize before settings pacer source and count values */
954 outw(0, devpriv->control_status + TRIG_CONTSTAT);
956 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
958 /* set mux limits, gain and pacer source */
959 bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
960 END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
961 GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
962 /* set unipolar/bipolar */
963 if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
965 /* set singleended/differential */
966 if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
968 /* set pacer source */
969 if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
970 bits |= PACER_EXT_RISE;
973 outw(bits, devpriv->control_status + ADCMUX_CONT);
976 if (cmd->scan_begin_src == TRIG_TIMER || cmd->convert_src == TRIG_TIMER)
977 cb_pcidas_ai_load_counters(dev);
979 /* set number of conversions */
980 if (cmd->stop_src == TRIG_COUNT)
981 devpriv->count = cmd->chanlist_len * cmd->stop_arg;
982 /* enable interrupts */
983 spin_lock_irqsave(&dev->spinlock, flags);
984 devpriv->adc_fifo_bits |= INTE;
985 devpriv->adc_fifo_bits &= ~INT_MASK;
986 if (cmd->flags & CMDF_WAKE_EOS) {
987 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) {
988 /* interrupt end of burst */
989 devpriv->adc_fifo_bits |= INT_EOS;
991 /* interrupt fifo not empty */
992 devpriv->adc_fifo_bits |= INT_FNE;
995 /* interrupt fifo half full */
996 devpriv->adc_fifo_bits |= INT_FHF;
999 /* enable (and clear) interrupts */
1000 outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
1001 devpriv->control_status + INT_ADCFIFO);
1002 spin_unlock_irqrestore(&dev->spinlock, flags);
1004 /* set start trigger and burst mode */
1006 if (cmd->start_src == TRIG_NOW) {
1008 } else { /* TRIG_EXT */
1009 bits |= EXT_TRIGGER | TGEN | XTRCL;
1010 if (thisboard->is_1602) {
1011 if (cmd->start_arg & CR_INVERT)
1013 if (cmd->start_arg & CR_EDGE)
1017 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1019 outw(bits, devpriv->control_status + TRIG_CONTSTAT);
1024 static int cb_pcidas_ao_check_chanlist(struct comedi_device *dev,
1025 struct comedi_subdevice *s,
1026 struct comedi_cmd *cmd)
1028 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
1030 if (cmd->chanlist_len > 1) {
1031 unsigned int chan1 = CR_CHAN(cmd->chanlist[1]);
1033 if (chan0 != 0 || chan1 != 1) {
1034 dev_dbg(dev->class_dev,
1035 "channels must be ordered channel 0, channel 1 in chanlist\n");
1043 static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
1044 struct comedi_subdevice *s,
1045 struct comedi_cmd *cmd)
1047 const struct cb_pcidas_board *thisboard = dev->board_ptr;
1048 struct cb_pcidas_private *devpriv = dev->private;
1052 /* Step 1 : check if triggers are trivially valid */
1054 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT);
1055 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
1056 TRIG_TIMER | TRIG_EXT);
1057 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
1058 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1059 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1064 /* Step 2a : make sure trigger sources are unique */
1066 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
1067 err |= cfc_check_trigger_is_unique(cmd->stop_src);
1069 /* Step 2b : and mutually compatible */
1074 /* Step 3: check if arguments are trivially valid */
1076 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1078 if (cmd->scan_begin_src == TRIG_TIMER)
1079 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1080 thisboard->ao_scan_speed);
1082 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1084 if (cmd->stop_src == TRIG_COUNT)
1085 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
1086 else /* TRIG_NONE */
1087 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1092 /* step 4: fix up any arguments */
1094 if (cmd->scan_begin_src == TRIG_TIMER) {
1095 arg = cmd->scan_begin_arg;
1096 i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
1097 &devpriv->ao_divisor1,
1098 &devpriv->ao_divisor2,
1100 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
1106 /* Step 5: check channel list if it exists */
1107 if (cmd->chanlist && cmd->chanlist_len > 0)
1108 err |= cb_pcidas_ao_check_chanlist(dev, s, cmd);
1116 /* cancel analog input command */
1117 static int cb_pcidas_cancel(struct comedi_device *dev,
1118 struct comedi_subdevice *s)
1120 struct cb_pcidas_private *devpriv = dev->private;
1121 unsigned long flags;
1123 spin_lock_irqsave(&dev->spinlock, flags);
1124 /* disable interrupts */
1125 devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
1126 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1127 spin_unlock_irqrestore(&dev->spinlock, flags);
1129 /* disable start trigger source and burst mode */
1130 outw(0, devpriv->control_status + TRIG_CONTSTAT);
1131 /* software pacer source */
1132 outw(0, devpriv->control_status + ADCMUX_CONT);
1137 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1138 struct comedi_subdevice *s,
1139 unsigned int trig_num)
1141 const struct cb_pcidas_board *thisboard = dev->board_ptr;
1142 struct cb_pcidas_private *devpriv = dev->private;
1143 unsigned int num_bytes, num_points = thisboard->fifo_size;
1144 struct comedi_async *async = s->async;
1145 struct comedi_cmd *cmd = &s->async->cmd;
1146 unsigned long flags;
1148 if (trig_num != cmd->start_arg)
1152 if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
1153 num_points = devpriv->ao_count;
1155 num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1156 num_points * sizeof(short));
1157 num_points = num_bytes / sizeof(short);
1159 if (cmd->stop_src == TRIG_COUNT)
1160 devpriv->ao_count -= num_points;
1161 /* write data to board's fifo */
1162 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
1164 /* enable dac half-full and empty interrupts */
1165 spin_lock_irqsave(&dev->spinlock, flags);
1166 devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
1168 /* enable and clear interrupts */
1169 outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
1170 devpriv->control_status + INT_ADCFIFO);
1173 devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1174 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1176 spin_unlock_irqrestore(&dev->spinlock, flags);
1178 async->inttrig = NULL;
1183 static void cb_pcidas_ao_load_counters(struct comedi_device *dev)
1185 struct cb_pcidas_private *devpriv = dev->private;
1186 unsigned long timer_base = dev->iobase + DAC8254;
1188 i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
1189 i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
1191 i8254_write(timer_base, 0, 1, devpriv->ao_divisor1);
1192 i8254_write(timer_base, 0, 2, devpriv->ao_divisor2);
1195 static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1196 struct comedi_subdevice *s)
1198 struct cb_pcidas_private *devpriv = dev->private;
1199 struct comedi_async *async = s->async;
1200 struct comedi_cmd *cmd = &async->cmd;
1202 unsigned long flags;
1204 /* set channel limits, gain */
1205 spin_lock_irqsave(&dev->spinlock, flags);
1206 for (i = 0; i < cmd->chanlist_len; i++) {
1207 /* enable channel */
1208 devpriv->ao_control_bits |=
1209 DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
1211 devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
1216 /* disable analog out before settings pacer source and count values */
1217 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1218 spin_unlock_irqrestore(&dev->spinlock, flags);
1221 outw(0, devpriv->ao_registers + DACFIFOCLR);
1224 if (cmd->scan_begin_src == TRIG_TIMER)
1225 cb_pcidas_ao_load_counters(dev);
1227 /* set number of conversions */
1228 if (cmd->stop_src == TRIG_COUNT)
1229 devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
1230 /* set pacer source */
1231 spin_lock_irqsave(&dev->spinlock, flags);
1232 switch (cmd->scan_begin_src) {
1234 devpriv->ao_control_bits |= DAC_PACER_INT;
1237 devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1240 spin_unlock_irqrestore(&dev->spinlock, flags);
1241 dev_err(dev->class_dev, "error setting dac pacer source\n");
1244 spin_unlock_irqrestore(&dev->spinlock, flags);
1246 async->inttrig = cb_pcidas_ao_inttrig;
1251 /* cancel analog output command */
1252 static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1253 struct comedi_subdevice *s)
1255 struct cb_pcidas_private *devpriv = dev->private;
1256 unsigned long flags;
1258 spin_lock_irqsave(&dev->spinlock, flags);
1259 /* disable interrupts */
1260 devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
1261 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1263 /* disable output */
1264 devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1265 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1266 spin_unlock_irqrestore(&dev->spinlock, flags);
1271 static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
1273 const struct cb_pcidas_board *thisboard = dev->board_ptr;
1274 struct cb_pcidas_private *devpriv = dev->private;
1275 struct comedi_subdevice *s = dev->write_subdev;
1276 struct comedi_async *async = s->async;
1277 struct comedi_cmd *cmd = &async->cmd;
1278 unsigned int half_fifo = thisboard->fifo_size / 2;
1279 unsigned int num_points;
1280 unsigned long flags;
1282 if (status & DAEMI) {
1283 /* clear dac empty interrupt latch */
1284 spin_lock_irqsave(&dev->spinlock, flags);
1285 outw(devpriv->adc_fifo_bits | DAEMI,
1286 devpriv->control_status + INT_ADCFIFO);
1287 spin_unlock_irqrestore(&dev->spinlock, flags);
1288 if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
1289 if (cmd->stop_src == TRIG_NONE ||
1290 (cmd->stop_src == TRIG_COUNT
1291 && devpriv->ao_count)) {
1292 dev_err(dev->class_dev, "dac fifo underflow\n");
1293 async->events |= COMEDI_CB_ERROR;
1295 async->events |= COMEDI_CB_EOA;
1297 } else if (status & DAHFI) {
1298 unsigned int num_bytes;
1300 /* figure out how many points we are writing to fifo */
1301 num_points = half_fifo;
1302 if (cmd->stop_src == TRIG_COUNT &&
1303 devpriv->ao_count < num_points)
1304 num_points = devpriv->ao_count;
1306 cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1307 num_points * sizeof(short));
1308 num_points = num_bytes / sizeof(short);
1310 if (cmd->stop_src == TRIG_COUNT)
1311 devpriv->ao_count -= num_points;
1312 /* write data to board's fifo */
1313 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
1315 /* clear half-full interrupt latch */
1316 spin_lock_irqsave(&dev->spinlock, flags);
1317 outw(devpriv->adc_fifo_bits | DAHFI,
1318 devpriv->control_status + INT_ADCFIFO);
1319 spin_unlock_irqrestore(&dev->spinlock, flags);
1322 cfc_handle_events(dev, s);
1325 static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1327 struct comedi_device *dev = (struct comedi_device *)d;
1328 const struct cb_pcidas_board *thisboard = dev->board_ptr;
1329 struct cb_pcidas_private *devpriv = dev->private;
1330 struct comedi_subdevice *s = dev->read_subdev;
1331 struct comedi_async *async;
1332 struct comedi_cmd *cmd;
1333 int status, s5933_status;
1334 int half_fifo = thisboard->fifo_size / 2;
1335 unsigned int num_samples, i;
1336 static const int timeout = 10000;
1337 unsigned long flags;
1345 s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1347 if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
1350 /* make sure mailbox 4 is empty */
1351 inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1352 /* clear interrupt on amcc s5933 */
1353 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1354 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1356 status = inw(devpriv->control_status + INT_ADCFIFO);
1358 /* check for analog output interrupt */
1359 if (status & (DAHFI | DAEMI))
1360 handle_ao_interrupt(dev, status);
1361 /* check for analog input interrupts */
1362 /* if fifo half-full */
1363 if (status & ADHFI) {
1365 num_samples = half_fifo;
1366 if (cmd->stop_src == TRIG_COUNT &&
1367 num_samples > devpriv->count) {
1368 num_samples = devpriv->count;
1370 insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
1372 cfc_write_array_to_buffer(s, devpriv->ai_buffer,
1373 num_samples * sizeof(short));
1374 devpriv->count -= num_samples;
1375 if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
1376 async->events |= COMEDI_CB_EOA;
1377 /* clear half-full interrupt latch */
1378 spin_lock_irqsave(&dev->spinlock, flags);
1379 outw(devpriv->adc_fifo_bits | INT,
1380 devpriv->control_status + INT_ADCFIFO);
1381 spin_unlock_irqrestore(&dev->spinlock, flags);
1382 /* else if fifo not empty */
1383 } else if (status & (ADNEI | EOBI)) {
1384 for (i = 0; i < timeout; i++) {
1385 /* break if fifo is empty */
1386 if ((ADNE & inw(devpriv->control_status +
1389 cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
1390 if (cmd->stop_src == TRIG_COUNT &&
1391 --devpriv->count == 0) {
1392 /* end of acquisition */
1393 async->events |= COMEDI_CB_EOA;
1397 /* clear not-empty interrupt latch */
1398 spin_lock_irqsave(&dev->spinlock, flags);
1399 outw(devpriv->adc_fifo_bits | INT,
1400 devpriv->control_status + INT_ADCFIFO);
1401 spin_unlock_irqrestore(&dev->spinlock, flags);
1402 } else if (status & EOAI) {
1403 dev_err(dev->class_dev,
1404 "bug! encountered end of acquisition interrupt?\n");
1405 /* clear EOA interrupt latch */
1406 spin_lock_irqsave(&dev->spinlock, flags);
1407 outw(devpriv->adc_fifo_bits | EOAI,
1408 devpriv->control_status + INT_ADCFIFO);
1409 spin_unlock_irqrestore(&dev->spinlock, flags);
1411 /* check for fifo overflow */
1412 if (status & LADFUL) {
1413 dev_err(dev->class_dev, "fifo overflow\n");
1414 /* clear overflow interrupt latch */
1415 spin_lock_irqsave(&dev->spinlock, flags);
1416 outw(devpriv->adc_fifo_bits | LADFUL,
1417 devpriv->control_status + INT_ADCFIFO);
1418 spin_unlock_irqrestore(&dev->spinlock, flags);
1419 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1422 cfc_handle_events(dev, s);
1427 static int cb_pcidas_auto_attach(struct comedi_device *dev,
1428 unsigned long context)
1430 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1431 const struct cb_pcidas_board *thisboard = NULL;
1432 struct cb_pcidas_private *devpriv;
1433 struct comedi_subdevice *s;
1437 if (context < ARRAY_SIZE(cb_pcidas_boards))
1438 thisboard = &cb_pcidas_boards[context];
1441 dev->board_ptr = thisboard;
1442 dev->board_name = thisboard->name;
1444 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1448 ret = comedi_pci_enable(dev);
1452 devpriv->s5933_config = pci_resource_start(pcidev, 0);
1453 devpriv->control_status = pci_resource_start(pcidev, 1);
1454 devpriv->adc_fifo = pci_resource_start(pcidev, 2);
1455 dev->iobase = pci_resource_start(pcidev, 3);
1456 if (thisboard->ao_nchan)
1457 devpriv->ao_registers = pci_resource_start(pcidev, 4);
1459 /* disable and clear interrupts on amcc s5933 */
1460 outl(INTCSR_INBOX_INTR_STATUS,
1461 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1463 ret = request_irq(pcidev->irq, cb_pcidas_interrupt, IRQF_SHARED,
1464 dev->board_name, dev);
1466 dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
1470 dev->irq = pcidev->irq;
1472 ret = comedi_alloc_subdevices(dev, 7);
1476 s = &dev->subdevices[0];
1477 /* analog input subdevice */
1478 dev->read_subdev = s;
1479 s->type = COMEDI_SUBD_AI;
1480 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
1481 /* WARNING: Number of inputs in differential mode is ignored */
1482 s->n_chan = thisboard->ai_nchan;
1483 s->len_chanlist = thisboard->ai_nchan;
1484 s->maxdata = (1 << thisboard->ai_bits) - 1;
1485 s->range_table = thisboard->ranges;
1486 s->insn_read = cb_pcidas_ai_rinsn;
1487 s->insn_config = ai_config_insn;
1488 s->do_cmd = cb_pcidas_ai_cmd;
1489 s->do_cmdtest = cb_pcidas_ai_cmdtest;
1490 s->cancel = cb_pcidas_cancel;
1492 /* analog output subdevice */
1493 s = &dev->subdevices[1];
1494 if (thisboard->ao_nchan) {
1495 s->type = COMEDI_SUBD_AO;
1496 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1497 s->n_chan = thisboard->ao_nchan;
1499 * analog out resolution is the same as
1500 * analog input resolution, so use ai_bits
1502 s->maxdata = (1 << thisboard->ai_bits) - 1;
1503 s->range_table = &cb_pcidas_ao_ranges;
1504 /* default to no fifo (*insn_write) */
1505 s->insn_write = cb_pcidas_ao_nofifo_winsn;
1506 s->insn_read = comedi_readback_insn_read;
1508 ret = comedi_alloc_subdev_readback(s);
1512 if (thisboard->has_ao_fifo) {
1513 dev->write_subdev = s;
1514 s->subdev_flags |= SDF_CMD_WRITE;
1515 /* use fifo (*insn_write) instead */
1516 s->insn_write = cb_pcidas_ao_fifo_winsn;
1517 s->do_cmdtest = cb_pcidas_ao_cmdtest;
1518 s->do_cmd = cb_pcidas_ao_cmd;
1519 s->cancel = cb_pcidas_ao_cancel;
1522 s->type = COMEDI_SUBD_UNUSED;
1526 s = &dev->subdevices[2];
1527 ret = subdev_8255_init(dev, s, NULL, DIO_8255);
1531 /* serial EEPROM, */
1532 s = &dev->subdevices[3];
1533 s->type = COMEDI_SUBD_MEMORY;
1534 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
1537 s->insn_read = eeprom_read_insn;
1540 s = &dev->subdevices[4];
1541 s->type = COMEDI_SUBD_CALIB;
1542 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1543 s->n_chan = NUM_CHANNELS_8800;
1545 s->insn_read = caldac_read_insn;
1546 s->insn_write = caldac_write_insn;
1547 for (i = 0; i < s->n_chan; i++)
1548 caldac_8800_write(dev, i, s->maxdata / 2);
1550 /* trim potentiometer */
1551 s = &dev->subdevices[5];
1552 s->type = COMEDI_SUBD_CALIB;
1553 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1554 if (thisboard->trimpot == AD7376) {
1555 s->n_chan = NUM_CHANNELS_7376;
1558 s->n_chan = NUM_CHANNELS_8402;
1561 s->insn_read = trimpot_read_insn;
1562 s->insn_write = trimpot_write_insn;
1563 for (i = 0; i < s->n_chan; i++)
1564 cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
1567 s = &dev->subdevices[6];
1568 if (thisboard->has_dac08) {
1569 s->type = COMEDI_SUBD_CALIB;
1570 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1571 s->n_chan = NUM_CHANNELS_DAC08;
1572 s->insn_read = dac08_read_insn;
1573 s->insn_write = dac08_write_insn;
1575 dac08_write(dev, s->maxdata / 2);
1577 s->type = COMEDI_SUBD_UNUSED;
1579 /* make sure mailbox 4 is empty */
1580 inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1581 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1582 devpriv->s5933_intcsr_bits =
1583 INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1584 INTCSR_INBOX_FULL_INT;
1585 /* clear and enable interrupt on amcc s5933 */
1586 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1587 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1592 static void cb_pcidas_detach(struct comedi_device *dev)
1594 struct cb_pcidas_private *devpriv = dev->private;
1596 if (devpriv && devpriv->s5933_config) {
1597 outl(INTCSR_INBOX_INTR_STATUS,
1598 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1600 comedi_pci_detach(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 const struct pci_device_id 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");