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.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 ************************************************************************
31 Description: MeasurementComputing PCI-DAS series
32 with the AMCC S5933 PCI controller
33 Author: Ivan Martinez <imr@oersted.dtu.dk>,
34 Frank Mori Hess <fmhess@users.sourceforge.net>
36 Devices: [Measurement Computing] PCI-DAS1602/16 (cb_pcidas),
37 PCI-DAS1602/16jr, PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr,
38 PCI-DAS1000, PCI-DAS1001, PCI_DAS1002
41 There are many reports of the driver being used with most of the
42 supported cards. Despite no detailed log is maintained, it can
43 be said that the driver is quite tested and stable.
45 The boards may be autocalibrated using the comedi_calibrate
48 Configuration options: not applicable, uses PCI auto config
50 For commands, the scanned channels must be consecutive
51 (i.e. 4-5-6-7, 2-3-4,...), and must all have the same
55 For start_src == TRIG_EXT, the A/D EXTERNAL TRIGGER IN (pin 45) is used.
56 For 1602 series, the start_arg is interpreted as follows:
57 start_arg == 0 => gated trigger (level high)
58 start_arg == CR_INVERT => gated trigger (level low)
59 start_arg == CR_EDGE => Rising edge
60 start_arg == CR_EDGE | CR_INVERT => Falling edge
61 For the other boards the trigger will be done on rising edge
67 analog triggering on 1602 series
70 #include <linux/pci.h>
71 #include <linux/delay.h>
72 #include <linux/interrupt.h>
74 #include "../comedidev.h"
78 #include "amcc_s5933.h"
79 #include "comedi_fc.h"
81 #define TIMER_BASE 100 /* 10MHz master clock */
82 #define AI_BUFFER_SIZE 1024 /* max ai fifo size */
83 #define AO_BUFFER_SIZE 1024 /* max ao fifo size */
84 #define NUM_CHANNELS_8800 8
85 #define NUM_CHANNELS_7376 1
86 #define NUM_CHANNELS_8402 2
87 #define NUM_CHANNELS_DAC08 1
89 /* Control/Status registers */
90 #define INT_ADCFIFO 0 /* INTERRUPT / ADC FIFO register */
91 #define INT_EOS 0x1 /* int end of scan */
92 #define INT_FHF 0x2 /* int fifo half full */
93 #define INT_FNE 0x3 /* int fifo not empty */
94 #define INT_MASK 0x3 /* mask of int select bits */
95 #define INTE 0x4 /* int enable */
96 #define DAHFIE 0x8 /* dac half full int enable */
97 #define EOAIE 0x10 /* end of acq. int enable */
98 #define DAHFI 0x20 /* dac half full status / clear */
99 #define EOAI 0x40 /* end of acq. int status / clear */
100 #define INT 0x80 /* int status / clear */
101 #define EOBI 0x200 /* end of burst int status */
102 #define ADHFI 0x400 /* half-full int status */
103 #define ADNEI 0x800 /* fifo not empty int status (latch) */
104 #define ADNE 0x1000 /* fifo not empty status (realtime) */
105 #define DAEMIE 0x1000 /* dac empty int enable */
106 #define LADFUL 0x2000 /* fifo overflow / clear */
107 #define DAEMI 0x4000 /* dac fifo empty int status / clear */
109 #define ADCMUX_CONT 2 /* ADC CHANNEL MUX AND CONTROL reg */
110 #define BEGIN_SCAN(x) ((x) & 0xf)
111 #define END_SCAN(x) (((x) & 0xf) << 4)
112 #define GAIN_BITS(x) (((x) & 0x3) << 8)
113 #define UNIP 0x800 /* Analog front-end unipolar mode */
114 #define SE 0x400 /* Inputs in single-ended mode */
115 #define PACER_MASK 0x3000 /* pacer source bits */
116 #define PACER_INT 0x1000 /* int. pacer */
117 #define PACER_EXT_FALL 0x2000 /* ext. falling edge */
118 #define PACER_EXT_RISE 0x3000 /* ext. rising edge */
119 #define EOC 0x4000 /* adc not busy */
121 #define TRIG_CONTSTAT 4 /* TRIGGER CONTROL/STATUS register */
122 #define SW_TRIGGER 0x1 /* software start trigger */
123 #define EXT_TRIGGER 0x2 /* ext. start trigger */
124 #define ANALOG_TRIGGER 0x3 /* ext. analog trigger */
125 #define TRIGGER_MASK 0x3 /* start trigger mask */
126 #define TGPOL 0x04 /* invert trigger (1602 only) */
127 #define TGSEL 0x08 /* edge/level trigerred (1602 only) */
128 #define TGEN 0x10 /* enable external start trigger */
129 #define BURSTE 0x20 /* burst mode enable */
130 #define XTRCL 0x80 /* clear external trigger */
132 #define CALIBRATION_REG 6 /* CALIBRATION register */
133 #define SELECT_8800_BIT 0x100 /* select 8800 caldac */
134 #define SELECT_TRIMPOT_BIT 0x200 /* select ad7376 trim pot */
135 #define SELECT_DAC08_BIT 0x400 /* select dac08 caldac */
136 #define CAL_SRC_BITS(x) (((x) & 0x7) << 11)
137 #define CAL_EN_BIT 0x4000 /* calibration source enable */
138 #define SERIAL_DATA_IN_BIT 0x8000 /* serial data bit going to caldac */
140 #define DAC_CSR 0x8 /* dac control and status register */
141 #define DACEN 0x02 /* dac enable */
142 #define DAC_MODE_UPDATE_BOTH 0x80 /* update both dacs */
144 static inline unsigned int DAC_RANGE(unsigned int channel, unsigned int range)
146 return (range & 0x3) << (8 + 2 * (channel & 0x1));
149 static inline unsigned int DAC_RANGE_MASK(unsigned int channel)
151 return 0x3 << (8 + 2 * (channel & 0x1));
154 /* bits for 1602 series only */
155 #define DAC_EMPTY 0x1 /* fifo empty, read, write clear */
156 #define DAC_START 0x4 /* start/arm fifo operations */
157 #define DAC_PACER_MASK 0x18 /* bits that set pacer source */
158 #define DAC_PACER_INT 0x8 /* int. pacing */
159 #define DAC_PACER_EXT_FALL 0x10 /* ext. pacing, falling edge */
160 #define DAC_PACER_EXT_RISE 0x18 /* ext. pacing, rising edge */
162 static inline unsigned int DAC_CHAN_EN(unsigned int channel)
164 return 1 << (5 + (channel & 0x1)); /* enable channel 0 or 1 */
167 /* analog input fifo */
168 #define ADCDATA 0 /* ADC DATA register */
169 #define ADCFIFOCLR 2 /* ADC FIFO CLEAR */
171 /* pacer, counter, dio registers */
176 /* analog output registers for 100x, 1200 series */
177 static inline unsigned int DAC_DATA_REG(unsigned int channel)
179 return 2 * (channel & 0x1);
182 /* analog output registers for 1602 series*/
183 #define DACDATA 0 /* DAC DATA register */
184 #define DACFIFOCLR 2 /* DAC FIFO CLEAR */
186 #define IS_UNIPOLAR 0x4 /* unipolar range mask */
188 /* analog input ranges for most boards */
189 static const struct comedi_lrange cb_pcidas_ranges = {
203 /* pci-das1001 input ranges */
204 static const struct comedi_lrange cb_pcidas_alt_ranges = {
218 /* analog output ranges */
219 static const struct comedi_lrange cb_pcidas_ao_ranges = {
234 enum cb_pcidas_boardid {
239 BOARD_PCIDAS1602_16_JR,
245 struct cb_pcidas_board {
247 int ai_nchan; /* Inputs in single-ended mode */
248 int ai_bits; /* analog input resolution */
249 int ai_speed; /* fastest conversion period in ns */
250 int ao_nchan; /* number of analog out channels */
251 int has_ao_fifo; /* analog output has fifo */
252 int ao_scan_speed; /* analog output scan speed for 1602 series */
253 int fifo_size; /* number of samples fifo can hold */
254 const struct comedi_lrange *ranges;
255 enum trimpot_model trimpot;
256 unsigned has_dac08:1;
260 static const struct cb_pcidas_board cb_pcidas_boards[] = {
261 [BOARD_PCIDAS1602_16] = {
262 .name = "pci-das1602/16",
268 .ao_scan_speed = 10000,
270 .ranges = &cb_pcidas_ranges,
275 [BOARD_PCIDAS1200] = {
276 .name = "pci-das1200",
282 .ranges = &cb_pcidas_ranges,
285 [BOARD_PCIDAS1602_12] = {
286 .name = "pci-das1602/12",
292 .ao_scan_speed = 4000,
294 .ranges = &cb_pcidas_ranges,
298 [BOARD_PCIDAS1200_JR] = {
299 .name = "pci-das1200/jr",
304 .ranges = &cb_pcidas_ranges,
307 [BOARD_PCIDAS1602_16_JR] = {
308 .name = "pci-das1602/16/jr",
313 .ranges = &cb_pcidas_ranges,
318 [BOARD_PCIDAS1000] = {
319 .name = "pci-das1000",
324 .ranges = &cb_pcidas_ranges,
327 [BOARD_PCIDAS1001] = {
328 .name = "pci-das1001",
334 .ranges = &cb_pcidas_alt_ranges,
337 [BOARD_PCIDAS1002] = {
338 .name = "pci-das1002",
344 .ranges = &cb_pcidas_ranges,
349 struct cb_pcidas_private {
351 unsigned long s5933_config;
352 unsigned long control_status;
353 unsigned long adc_fifo;
354 unsigned long pacer_counter_dio;
355 unsigned long ao_registers;
356 /* divisors of master clock for analog input pacing */
357 unsigned int divisor1;
358 unsigned int divisor2;
359 /* number of analog input samples remaining */
361 /* bits to write to registers */
362 unsigned int adc_fifo_bits;
363 unsigned int s5933_intcsr_bits;
364 unsigned int ao_control_bits;
366 short ai_buffer[AI_BUFFER_SIZE];
367 short ao_buffer[AO_BUFFER_SIZE];
368 /* divisors of master clock for analog output pacing */
369 unsigned int ao_divisor1;
370 unsigned int ao_divisor2;
371 /* number of analog output samples remaining */
372 unsigned int ao_count;
373 /* cached values for readback */
375 unsigned int caldac_value[NUM_CHANNELS_8800];
376 unsigned int trimpot_value[NUM_CHANNELS_8402];
377 unsigned int dac08_value;
378 unsigned int calibration_source;
381 static inline unsigned int cal_enable_bits(struct comedi_device *dev)
383 struct cb_pcidas_private *devpriv = dev->private;
385 return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source);
388 static int cb_pcidas_ai_rinsn(struct comedi_device *dev,
389 struct comedi_subdevice *s,
390 struct comedi_insn *insn, unsigned int *data)
392 struct cb_pcidas_private *devpriv = dev->private;
393 unsigned int chan = CR_CHAN(insn->chanspec);
394 unsigned int range = CR_RANGE(insn->chanspec);
395 unsigned int aref = CR_AREF(insn->chanspec);
399 /* enable calibration input if appropriate */
400 if (insn->chanspec & CR_ALT_SOURCE) {
401 outw(cal_enable_bits(dev),
402 devpriv->control_status + CALIBRATION_REG);
405 outw(0, devpriv->control_status + CALIBRATION_REG);
408 /* set mux limits and gain */
409 bits = BEGIN_SCAN(chan) | END_SCAN(chan) | GAIN_BITS(range);
410 /* set unipolar/bipolar */
411 if (range & IS_UNIPOLAR)
413 /* set single-ended/differential */
414 if (aref != AREF_DIFF)
416 outw(bits, devpriv->control_status + ADCMUX_CONT);
419 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
421 /* convert n samples */
422 for (n = 0; n < insn->n; n++) {
423 /* trigger conversion */
424 outw(0, devpriv->adc_fifo + ADCDATA);
426 /* wait for conversion to end */
427 /* return -ETIMEDOUT if there is a timeout */
428 for (i = 0; i < 10000; i++) {
429 if (inw(devpriv->control_status + ADCMUX_CONT) & EOC)
436 data[n] = inw(devpriv->adc_fifo + ADCDATA);
439 /* return the number of samples read/written */
443 static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
444 struct comedi_insn *insn, unsigned int *data)
446 struct cb_pcidas_private *devpriv = dev->private;
448 unsigned int source = data[1];
451 case INSN_CONFIG_ALT_SOURCE:
453 dev_err(dev->class_dev,
454 "invalid calibration source: %i\n",
458 devpriv->calibration_source = source;
467 /* analog output insn for pcidas-1000 and 1200 series */
468 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev,
469 struct comedi_subdevice *s,
470 struct comedi_insn *insn,
473 struct cb_pcidas_private *devpriv = dev->private;
474 unsigned int chan = CR_CHAN(insn->chanspec);
475 unsigned int range = CR_RANGE(insn->chanspec);
478 /* set channel and range */
479 spin_lock_irqsave(&dev->spinlock, flags);
480 devpriv->ao_control_bits &= (~DAC_MODE_UPDATE_BOTH &
481 ~DAC_RANGE_MASK(chan));
482 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range));
483 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
484 spin_unlock_irqrestore(&dev->spinlock, flags);
486 /* remember value for readback */
487 devpriv->ao_value[chan] = data[0];
490 outw(data[0], devpriv->ao_registers + DAC_DATA_REG(chan));
495 /* analog output insn for pcidas-1602 series */
496 static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev,
497 struct comedi_subdevice *s,
498 struct comedi_insn *insn, unsigned int *data)
500 struct cb_pcidas_private *devpriv = dev->private;
501 unsigned int chan = CR_CHAN(insn->chanspec);
502 unsigned int range = CR_RANGE(insn->chanspec);
506 outw(0, devpriv->ao_registers + DACFIFOCLR);
508 /* set channel and range */
509 spin_lock_irqsave(&dev->spinlock, flags);
510 devpriv->ao_control_bits &= (~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) &
511 ~DAC_RANGE_MASK(chan) & ~DAC_PACER_MASK);
512 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range) |
513 DAC_CHAN_EN(chan) | DAC_START);
514 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
515 spin_unlock_irqrestore(&dev->spinlock, flags);
517 /* remember value for readback */
518 devpriv->ao_value[chan] = data[0];
521 outw(data[0], devpriv->ao_registers + DACDATA);
526 static int cb_pcidas_ao_readback_insn(struct comedi_device *dev,
527 struct comedi_subdevice *s,
528 struct comedi_insn *insn,
531 struct cb_pcidas_private *devpriv = dev->private;
533 data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
538 static int wait_for_nvram_ready(unsigned long s5933_base_addr)
540 static const int timeout = 1000;
543 for (i = 0; i < timeout; i++) {
544 if ((inb(s5933_base_addr +
545 AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
553 static int nvram_read(struct comedi_device *dev, unsigned int address,
556 struct cb_pcidas_private *devpriv = dev->private;
557 unsigned long iobase = devpriv->s5933_config;
559 if (wait_for_nvram_ready(iobase) < 0)
562 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
563 iobase + AMCC_OP_REG_MCSR_NVCMD);
564 outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
565 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
566 iobase + AMCC_OP_REG_MCSR_NVCMD);
567 outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
568 outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
570 if (wait_for_nvram_ready(iobase) < 0)
573 *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
578 static int eeprom_read_insn(struct comedi_device *dev,
579 struct comedi_subdevice *s,
580 struct comedi_insn *insn, unsigned int *data)
585 retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
589 data[0] = nvram_data;
594 static void write_calibration_bitstream(struct comedi_device *dev,
595 unsigned int register_bits,
596 unsigned int bitstream,
597 unsigned int bitstream_length)
599 struct cb_pcidas_private *devpriv = dev->private;
600 static const int write_delay = 1;
603 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
605 register_bits |= SERIAL_DATA_IN_BIT;
607 register_bits &= ~SERIAL_DATA_IN_BIT;
609 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
613 static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
616 struct cb_pcidas_private *devpriv = dev->private;
617 static const int num_caldac_channels = 8;
618 static const int bitstream_length = 11;
619 unsigned int bitstream = ((address & 0x7) << 8) | value;
620 static const int caldac_8800_udelay = 1;
622 if (address >= num_caldac_channels) {
623 comedi_error(dev, "illegal caldac channel");
627 if (value == devpriv->caldac_value[address])
630 devpriv->caldac_value[address] = value;
632 write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
635 udelay(caldac_8800_udelay);
636 outw(cal_enable_bits(dev) | SELECT_8800_BIT,
637 devpriv->control_status + CALIBRATION_REG);
638 udelay(caldac_8800_udelay);
639 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
644 static int caldac_write_insn(struct comedi_device *dev,
645 struct comedi_subdevice *s,
646 struct comedi_insn *insn, unsigned int *data)
648 const unsigned int channel = CR_CHAN(insn->chanspec);
650 return caldac_8800_write(dev, channel, data[0]);
653 static int caldac_read_insn(struct comedi_device *dev,
654 struct comedi_subdevice *s,
655 struct comedi_insn *insn, unsigned int *data)
657 struct cb_pcidas_private *devpriv = dev->private;
659 data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)];
664 /* 1602/16 pregain offset */
665 static void dac08_write(struct comedi_device *dev, unsigned int value)
667 struct cb_pcidas_private *devpriv = dev->private;
668 unsigned long cal_reg;
670 if (devpriv->dac08_value != value) {
671 devpriv->dac08_value = value;
673 cal_reg = devpriv->control_status + CALIBRATION_REG;
676 value |= cal_enable_bits(dev);
678 /* latch the new value into the caldac */
679 outw(value, cal_reg);
681 outw(value | SELECT_DAC08_BIT, cal_reg);
683 outw(value, cal_reg);
688 static int dac08_write_insn(struct comedi_device *dev,
689 struct comedi_subdevice *s,
690 struct comedi_insn *insn, unsigned int *data)
694 for (i = 0; i < insn->n; i++)
695 dac08_write(dev, data[i]);
700 static int dac08_read_insn(struct comedi_device *dev,
701 struct comedi_subdevice *s, struct comedi_insn *insn,
704 struct cb_pcidas_private *devpriv = dev->private;
706 data[0] = devpriv->dac08_value;
711 static int trimpot_7376_write(struct comedi_device *dev, uint8_t value)
713 struct cb_pcidas_private *devpriv = dev->private;
714 static const int bitstream_length = 7;
715 unsigned int bitstream = value & 0x7f;
716 unsigned int register_bits;
717 static const int ad7376_udelay = 1;
719 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
720 udelay(ad7376_udelay);
721 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
723 write_calibration_bitstream(dev, register_bits, bitstream,
726 udelay(ad7376_udelay);
727 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
734 * ch 1 : adc postgain offset */
735 static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
738 struct cb_pcidas_private *devpriv = dev->private;
739 static const int bitstream_length = 10;
740 unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
741 unsigned int register_bits;
742 static const int ad8402_udelay = 1;
744 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
745 udelay(ad8402_udelay);
746 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
748 write_calibration_bitstream(dev, register_bits, bitstream,
751 udelay(ad8402_udelay);
752 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
757 static int cb_pcidas_trimpot_write(struct comedi_device *dev,
758 unsigned int channel, unsigned int value)
760 const struct cb_pcidas_board *thisboard = comedi_board(dev);
761 struct cb_pcidas_private *devpriv = dev->private;
763 if (devpriv->trimpot_value[channel] == value)
766 devpriv->trimpot_value[channel] = value;
767 switch (thisboard->trimpot) {
769 trimpot_7376_write(dev, value);
772 trimpot_8402_write(dev, channel, value);
775 comedi_error(dev, "driver bug?");
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_cmdtest(struct comedi_device *dev,
805 struct comedi_subdevice *s,
806 struct comedi_cmd *cmd)
808 const struct cb_pcidas_board *thisboard = comedi_board(dev);
809 struct cb_pcidas_private *devpriv = dev->private;
812 int i, gain, start_chan;
814 /* Step 1 : check if triggers are trivially valid */
816 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
817 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
818 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
819 err |= cfc_check_trigger_src(&cmd->convert_src,
820 TRIG_TIMER | TRIG_NOW | TRIG_EXT);
821 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
822 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
827 /* Step 2a : make sure trigger sources are unique */
829 err |= cfc_check_trigger_is_unique(cmd->start_src);
830 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
831 err |= cfc_check_trigger_is_unique(cmd->convert_src);
832 err |= cfc_check_trigger_is_unique(cmd->stop_src);
834 /* Step 2b : and mutually compatible */
836 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
838 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
840 if (cmd->start_src == TRIG_EXT &&
841 (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))
847 /* step 3: arguments are trivially compatible */
849 switch (cmd->start_src) {
851 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
853 & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
854 cmd->start_arg &= ~(CR_FLAGS_MASK &
855 ~(CR_EDGE | CR_INVERT));
858 if (!thisboard->is_1602 && (cmd->start_arg & CR_INVERT)) {
859 cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
864 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
868 if (cmd->scan_begin_src == TRIG_TIMER)
869 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
870 thisboard->ai_speed * cmd->chanlist_len);
872 if (cmd->convert_src == TRIG_TIMER)
873 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
874 thisboard->ai_speed);
876 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
878 if (cmd->stop_src == TRIG_NONE)
879 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
884 /* step 4: fix up any arguments */
886 if (cmd->scan_begin_src == TRIG_TIMER) {
887 tmp = cmd->scan_begin_arg;
888 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
889 &(devpriv->divisor1),
890 &(devpriv->divisor2),
891 &(cmd->scan_begin_arg),
892 cmd->flags & TRIG_ROUND_MASK);
893 if (tmp != cmd->scan_begin_arg)
896 if (cmd->convert_src == TRIG_TIMER) {
897 tmp = cmd->convert_arg;
898 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
899 &(devpriv->divisor1),
900 &(devpriv->divisor2),
902 cmd->flags & TRIG_ROUND_MASK);
903 if (tmp != cmd->convert_arg)
910 /* check channel/gain list against card's limitations */
912 gain = CR_RANGE(cmd->chanlist[0]);
913 start_chan = CR_CHAN(cmd->chanlist[0]);
914 for (i = 1; i < cmd->chanlist_len; i++) {
915 if (CR_CHAN(cmd->chanlist[i]) !=
916 (start_chan + i) % s->n_chan) {
918 "entries in chanlist must be consecutive channels, counting upwards\n");
921 if (CR_RANGE(cmd->chanlist[i]) != gain) {
923 "entries in chanlist must all have the same gain\n");
935 static void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns,
938 struct cb_pcidas_private *devpriv = dev->private;
940 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
941 &(devpriv->divisor2), ns,
942 rounding_flags & TRIG_ROUND_MASK);
944 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
945 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1,
946 devpriv->divisor1, 2);
947 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2,
948 devpriv->divisor2, 2);
951 static int cb_pcidas_ai_cmd(struct comedi_device *dev,
952 struct comedi_subdevice *s)
954 const struct cb_pcidas_board *thisboard = comedi_board(dev);
955 struct cb_pcidas_private *devpriv = dev->private;
956 struct comedi_async *async = s->async;
957 struct comedi_cmd *cmd = &async->cmd;
961 /* make sure CAL_EN_BIT is disabled */
962 outw(0, devpriv->control_status + CALIBRATION_REG);
963 /* initialize before settings pacer source and count values */
964 outw(0, devpriv->control_status + TRIG_CONTSTAT);
966 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
968 /* set mux limits, gain and pacer source */
969 bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
970 END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
971 GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
972 /* set unipolar/bipolar */
973 if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
975 /* set singleended/differential */
976 if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
978 /* set pacer source */
979 if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
980 bits |= PACER_EXT_RISE;
983 outw(bits, devpriv->control_status + ADCMUX_CONT);
986 if (cmd->convert_src == TRIG_TIMER)
987 cb_pcidas_load_counters(dev, &cmd->convert_arg,
988 cmd->flags & TRIG_ROUND_MASK);
989 else if (cmd->scan_begin_src == TRIG_TIMER)
990 cb_pcidas_load_counters(dev, &cmd->scan_begin_arg,
991 cmd->flags & TRIG_ROUND_MASK);
993 /* set number of conversions */
994 if (cmd->stop_src == TRIG_COUNT)
995 devpriv->count = cmd->chanlist_len * cmd->stop_arg;
996 /* enable interrupts */
997 spin_lock_irqsave(&dev->spinlock, flags);
998 devpriv->adc_fifo_bits |= INTE;
999 devpriv->adc_fifo_bits &= ~INT_MASK;
1000 if (cmd->flags & TRIG_WAKE_EOS) {
1001 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) {
1002 /* interrupt end of burst */
1003 devpriv->adc_fifo_bits |= INT_EOS;
1005 /* interrupt fifo not empty */
1006 devpriv->adc_fifo_bits |= INT_FNE;
1009 /* interrupt fifo half full */
1010 devpriv->adc_fifo_bits |= INT_FHF;
1013 /* enable (and clear) interrupts */
1014 outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
1015 devpriv->control_status + INT_ADCFIFO);
1016 spin_unlock_irqrestore(&dev->spinlock, flags);
1018 /* set start trigger and burst mode */
1020 if (cmd->start_src == TRIG_NOW)
1022 else if (cmd->start_src == TRIG_EXT) {
1023 bits |= EXT_TRIGGER | TGEN | XTRCL;
1024 if (thisboard->is_1602) {
1025 if (cmd->start_arg & CR_INVERT)
1027 if (cmd->start_arg & CR_EDGE)
1031 comedi_error(dev, "bug!");
1034 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1036 outw(bits, devpriv->control_status + TRIG_CONTSTAT);
1041 static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
1042 struct comedi_subdevice *s,
1043 struct comedi_cmd *cmd)
1045 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1046 struct cb_pcidas_private *devpriv = dev->private;
1050 /* Step 1 : check if triggers are trivially valid */
1052 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT);
1053 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
1054 TRIG_TIMER | TRIG_EXT);
1055 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
1056 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1057 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1062 /* Step 2a : make sure trigger sources are unique */
1064 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
1065 err |= cfc_check_trigger_is_unique(cmd->stop_src);
1067 /* Step 2b : and mutually compatible */
1072 /* Step 3: check if arguments are trivially valid */
1074 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1076 if (cmd->scan_begin_src == TRIG_TIMER)
1077 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1078 thisboard->ao_scan_speed);
1080 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1082 if (cmd->stop_src == TRIG_NONE)
1083 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1088 /* step 4: fix up any arguments */
1090 if (cmd->scan_begin_src == TRIG_TIMER) {
1091 tmp = cmd->scan_begin_arg;
1092 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1093 &(devpriv->ao_divisor1),
1094 &(devpriv->ao_divisor2),
1095 &(cmd->scan_begin_arg),
1096 cmd->flags & TRIG_ROUND_MASK);
1097 if (tmp != cmd->scan_begin_arg)
1104 /* check channel/gain list against card's limitations */
1105 if (cmd->chanlist && cmd->chanlist_len > 1) {
1106 if (CR_CHAN(cmd->chanlist[0]) != 0 ||
1107 CR_CHAN(cmd->chanlist[1]) != 1) {
1109 "channels must be ordered channel 0, channel 1 in chanlist\n");
1120 /* cancel analog input command */
1121 static int cb_pcidas_cancel(struct comedi_device *dev,
1122 struct comedi_subdevice *s)
1124 struct cb_pcidas_private *devpriv = dev->private;
1125 unsigned long flags;
1127 spin_lock_irqsave(&dev->spinlock, flags);
1128 /* disable interrupts */
1129 devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
1130 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1131 spin_unlock_irqrestore(&dev->spinlock, flags);
1133 /* disable start trigger source and burst mode */
1134 outw(0, devpriv->control_status + TRIG_CONTSTAT);
1135 /* software pacer source */
1136 outw(0, devpriv->control_status + ADCMUX_CONT);
1141 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1142 struct comedi_subdevice *s,
1143 unsigned int trig_num)
1145 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1146 struct cb_pcidas_private *devpriv = dev->private;
1147 unsigned int num_bytes, num_points = thisboard->fifo_size;
1148 struct comedi_async *async = s->async;
1149 struct comedi_cmd *cmd = &s->async->cmd;
1150 unsigned long flags;
1156 if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
1157 num_points = devpriv->ao_count;
1159 num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1160 num_points * sizeof(short));
1161 num_points = num_bytes / sizeof(short);
1163 if (cmd->stop_src == TRIG_COUNT)
1164 devpriv->ao_count -= num_points;
1165 /* write data to board's fifo */
1166 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
1168 /* enable dac half-full and empty interrupts */
1169 spin_lock_irqsave(&dev->spinlock, flags);
1170 devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
1172 /* enable and clear interrupts */
1173 outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
1174 devpriv->control_status + INT_ADCFIFO);
1177 devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1178 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1180 spin_unlock_irqrestore(&dev->spinlock, flags);
1182 async->inttrig = NULL;
1187 static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1188 struct comedi_subdevice *s)
1190 struct cb_pcidas_private *devpriv = dev->private;
1191 struct comedi_async *async = s->async;
1192 struct comedi_cmd *cmd = &async->cmd;
1194 unsigned long flags;
1196 /* set channel limits, gain */
1197 spin_lock_irqsave(&dev->spinlock, flags);
1198 for (i = 0; i < cmd->chanlist_len; i++) {
1199 /* enable channel */
1200 devpriv->ao_control_bits |=
1201 DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
1203 devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
1208 /* disable analog out before settings pacer source and count values */
1209 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1210 spin_unlock_irqrestore(&dev->spinlock, flags);
1213 outw(0, devpriv->ao_registers + DACFIFOCLR);
1216 if (cmd->scan_begin_src == TRIG_TIMER) {
1217 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1218 &(devpriv->ao_divisor1),
1219 &(devpriv->ao_divisor2),
1220 &(cmd->scan_begin_arg),
1223 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1224 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1,
1225 devpriv->ao_divisor1, 2);
1226 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2,
1227 devpriv->ao_divisor2, 2);
1229 /* set number of conversions */
1230 if (cmd->stop_src == TRIG_COUNT)
1231 devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
1232 /* set pacer source */
1233 spin_lock_irqsave(&dev->spinlock, flags);
1234 switch (cmd->scan_begin_src) {
1236 devpriv->ao_control_bits |= DAC_PACER_INT;
1239 devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1242 spin_unlock_irqrestore(&dev->spinlock, flags);
1243 comedi_error(dev, "error setting dac pacer source");
1247 spin_unlock_irqrestore(&dev->spinlock, flags);
1249 async->inttrig = cb_pcidas_ao_inttrig;
1254 /* cancel analog output command */
1255 static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1256 struct comedi_subdevice *s)
1258 struct cb_pcidas_private *devpriv = dev->private;
1259 unsigned long flags;
1261 spin_lock_irqsave(&dev->spinlock, flags);
1262 /* disable interrupts */
1263 devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
1264 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1266 /* disable output */
1267 devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1268 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1269 spin_unlock_irqrestore(&dev->spinlock, flags);
1274 static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
1276 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1277 struct cb_pcidas_private *devpriv = dev->private;
1278 struct comedi_subdevice *s = dev->write_subdev;
1279 struct comedi_async *async = s->async;
1280 struct comedi_cmd *cmd = &async->cmd;
1281 unsigned int half_fifo = thisboard->fifo_size / 2;
1282 unsigned int num_points;
1283 unsigned long flags;
1287 if (status & DAEMI) {
1288 /* clear dac empty interrupt latch */
1289 spin_lock_irqsave(&dev->spinlock, flags);
1290 outw(devpriv->adc_fifo_bits | DAEMI,
1291 devpriv->control_status + INT_ADCFIFO);
1292 spin_unlock_irqrestore(&dev->spinlock, flags);
1293 if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
1294 if (cmd->stop_src == TRIG_NONE ||
1295 (cmd->stop_src == TRIG_COUNT
1296 && devpriv->ao_count)) {
1297 comedi_error(dev, "dac fifo underflow");
1298 cb_pcidas_ao_cancel(dev, s);
1299 async->events |= COMEDI_CB_ERROR;
1301 async->events |= COMEDI_CB_EOA;
1303 } else if (status & DAHFI) {
1304 unsigned int num_bytes;
1306 /* figure out how many points we are writing to fifo */
1307 num_points = half_fifo;
1308 if (cmd->stop_src == TRIG_COUNT &&
1309 devpriv->ao_count < num_points)
1310 num_points = devpriv->ao_count;
1312 cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1313 num_points * sizeof(short));
1314 num_points = num_bytes / sizeof(short);
1316 if (async->cmd.stop_src == TRIG_COUNT)
1317 devpriv->ao_count -= num_points;
1318 /* write data to board's fifo */
1319 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
1321 /* clear half-full interrupt latch */
1322 spin_lock_irqsave(&dev->spinlock, flags);
1323 outw(devpriv->adc_fifo_bits | DAHFI,
1324 devpriv->control_status + INT_ADCFIFO);
1325 spin_unlock_irqrestore(&dev->spinlock, flags);
1328 comedi_event(dev, s);
1331 static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1333 struct comedi_device *dev = (struct comedi_device *)d;
1334 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1335 struct cb_pcidas_private *devpriv = dev->private;
1336 struct comedi_subdevice *s = dev->read_subdev;
1337 struct comedi_async *async;
1338 int status, s5933_status;
1339 int half_fifo = thisboard->fifo_size / 2;
1340 unsigned int num_samples, i;
1341 static const int timeout = 10000;
1342 unsigned long flags;
1350 s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1352 if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
1355 /* make sure mailbox 4 is empty */
1356 inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1357 /* clear interrupt on amcc s5933 */
1358 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1359 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1361 status = inw(devpriv->control_status + INT_ADCFIFO);
1363 /* check for analog output interrupt */
1364 if (status & (DAHFI | DAEMI))
1365 handle_ao_interrupt(dev, status);
1366 /* check for analog input interrupts */
1367 /* if fifo half-full */
1368 if (status & ADHFI) {
1370 num_samples = half_fifo;
1371 if (async->cmd.stop_src == TRIG_COUNT &&
1372 num_samples > devpriv->count) {
1373 num_samples = devpriv->count;
1375 insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
1377 cfc_write_array_to_buffer(s, devpriv->ai_buffer,
1378 num_samples * sizeof(short));
1379 devpriv->count -= num_samples;
1380 if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) {
1381 async->events |= COMEDI_CB_EOA;
1382 cb_pcidas_cancel(dev, s);
1384 /* clear half-full interrupt latch */
1385 spin_lock_irqsave(&dev->spinlock, flags);
1386 outw(devpriv->adc_fifo_bits | INT,
1387 devpriv->control_status + INT_ADCFIFO);
1388 spin_unlock_irqrestore(&dev->spinlock, flags);
1389 /* else if fifo not empty */
1390 } else if (status & (ADNEI | EOBI)) {
1391 for (i = 0; i < timeout; i++) {
1392 /* break if fifo is empty */
1393 if ((ADNE & inw(devpriv->control_status +
1396 cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
1397 if (async->cmd.stop_src == TRIG_COUNT &&
1398 --devpriv->count == 0) {
1399 /* end of acquisition */
1400 cb_pcidas_cancel(dev, s);
1401 async->events |= COMEDI_CB_EOA;
1405 /* clear not-empty interrupt latch */
1406 spin_lock_irqsave(&dev->spinlock, flags);
1407 outw(devpriv->adc_fifo_bits | INT,
1408 devpriv->control_status + INT_ADCFIFO);
1409 spin_unlock_irqrestore(&dev->spinlock, flags);
1410 } else if (status & EOAI) {
1412 "bug! encountered end of acquisition interrupt?");
1413 /* clear EOA interrupt latch */
1414 spin_lock_irqsave(&dev->spinlock, flags);
1415 outw(devpriv->adc_fifo_bits | EOAI,
1416 devpriv->control_status + INT_ADCFIFO);
1417 spin_unlock_irqrestore(&dev->spinlock, flags);
1419 /* check for fifo overflow */
1420 if (status & LADFUL) {
1421 comedi_error(dev, "fifo overflow");
1422 /* clear overflow interrupt latch */
1423 spin_lock_irqsave(&dev->spinlock, flags);
1424 outw(devpriv->adc_fifo_bits | LADFUL,
1425 devpriv->control_status + INT_ADCFIFO);
1426 spin_unlock_irqrestore(&dev->spinlock, flags);
1427 cb_pcidas_cancel(dev, s);
1428 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1431 comedi_event(dev, s);
1436 static int cb_pcidas_auto_attach(struct comedi_device *dev,
1437 unsigned long context)
1439 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1440 const struct cb_pcidas_board *thisboard = NULL;
1441 struct cb_pcidas_private *devpriv;
1442 struct comedi_subdevice *s;
1446 if (context < ARRAY_SIZE(cb_pcidas_boards))
1447 thisboard = &cb_pcidas_boards[context];
1450 dev->board_ptr = thisboard;
1451 dev->board_name = thisboard->name;
1453 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1456 dev->private = devpriv;
1458 ret = comedi_pci_enable(dev);
1462 devpriv->s5933_config = pci_resource_start(pcidev, 0);
1463 devpriv->control_status = pci_resource_start(pcidev, 1);
1464 devpriv->adc_fifo = pci_resource_start(pcidev, 2);
1465 devpriv->pacer_counter_dio = pci_resource_start(pcidev, 3);
1466 if (thisboard->ao_nchan)
1467 devpriv->ao_registers = pci_resource_start(pcidev, 4);
1469 /* disable and clear interrupts on amcc s5933 */
1470 outl(INTCSR_INBOX_INTR_STATUS,
1471 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1473 if (request_irq(pcidev->irq, cb_pcidas_interrupt,
1474 IRQF_SHARED, dev->driver->driver_name, dev)) {
1475 dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
1479 dev->irq = pcidev->irq;
1481 ret = comedi_alloc_subdevices(dev, 7);
1485 s = &dev->subdevices[0];
1486 /* analog input subdevice */
1487 dev->read_subdev = s;
1488 s->type = COMEDI_SUBD_AI;
1489 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
1490 /* WARNING: Number of inputs in differential mode is ignored */
1491 s->n_chan = thisboard->ai_nchan;
1492 s->len_chanlist = thisboard->ai_nchan;
1493 s->maxdata = (1 << thisboard->ai_bits) - 1;
1494 s->range_table = thisboard->ranges;
1495 s->insn_read = cb_pcidas_ai_rinsn;
1496 s->insn_config = ai_config_insn;
1497 s->do_cmd = cb_pcidas_ai_cmd;
1498 s->do_cmdtest = cb_pcidas_ai_cmdtest;
1499 s->cancel = cb_pcidas_cancel;
1501 /* analog output subdevice */
1502 s = &dev->subdevices[1];
1503 if (thisboard->ao_nchan) {
1504 s->type = COMEDI_SUBD_AO;
1505 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1506 s->n_chan = thisboard->ao_nchan;
1508 * analog out resolution is the same as
1509 * analog input resolution, so use ai_bits
1511 s->maxdata = (1 << thisboard->ai_bits) - 1;
1512 s->range_table = &cb_pcidas_ao_ranges;
1513 s->insn_read = cb_pcidas_ao_readback_insn;
1514 if (thisboard->has_ao_fifo) {
1515 dev->write_subdev = s;
1516 s->subdev_flags |= SDF_CMD_WRITE;
1517 s->insn_write = cb_pcidas_ao_fifo_winsn;
1518 s->do_cmdtest = cb_pcidas_ao_cmdtest;
1519 s->do_cmd = cb_pcidas_ao_cmd;
1520 s->cancel = cb_pcidas_ao_cancel;
1522 s->insn_write = cb_pcidas_ao_nofifo_winsn;
1525 s->type = COMEDI_SUBD_UNUSED;
1529 s = &dev->subdevices[2];
1530 ret = subdev_8255_init(dev, s, NULL,
1531 devpriv->pacer_counter_dio + DIO_8255);
1535 /* serial EEPROM, */
1536 s = &dev->subdevices[3];
1537 s->type = COMEDI_SUBD_MEMORY;
1538 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
1541 s->insn_read = eeprom_read_insn;
1544 s = &dev->subdevices[4];
1545 s->type = COMEDI_SUBD_CALIB;
1546 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1547 s->n_chan = NUM_CHANNELS_8800;
1549 s->insn_read = caldac_read_insn;
1550 s->insn_write = caldac_write_insn;
1551 for (i = 0; i < s->n_chan; i++)
1552 caldac_8800_write(dev, i, s->maxdata / 2);
1554 /* trim potentiometer */
1555 s = &dev->subdevices[5];
1556 s->type = COMEDI_SUBD_CALIB;
1557 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1558 if (thisboard->trimpot == AD7376) {
1559 s->n_chan = NUM_CHANNELS_7376;
1562 s->n_chan = NUM_CHANNELS_8402;
1565 s->insn_read = trimpot_read_insn;
1566 s->insn_write = trimpot_write_insn;
1567 for (i = 0; i < s->n_chan; i++)
1568 cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
1571 s = &dev->subdevices[6];
1572 if (thisboard->has_dac08) {
1573 s->type = COMEDI_SUBD_CALIB;
1574 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1575 s->n_chan = NUM_CHANNELS_DAC08;
1576 s->insn_read = dac08_read_insn;
1577 s->insn_write = dac08_write_insn;
1579 dac08_write(dev, s->maxdata / 2);
1581 s->type = COMEDI_SUBD_UNUSED;
1583 /* make sure mailbox 4 is empty */
1584 inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1585 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1586 devpriv->s5933_intcsr_bits =
1587 INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1588 INTCSR_INBOX_FULL_INT;
1589 /* clear and enable interrupt on amcc s5933 */
1590 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1591 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1593 dev_info(dev->class_dev, "%s: %s attached\n",
1594 dev->driver->driver_name, dev->board_name);
1599 static void cb_pcidas_detach(struct comedi_device *dev)
1601 struct cb_pcidas_private *devpriv = dev->private;
1604 if (devpriv->s5933_config) {
1605 outl(INTCSR_INBOX_INTR_STATUS,
1606 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1610 free_irq(dev->irq, dev);
1611 comedi_spriv_free(dev, 2);
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 DEFINE_PCI_DEVICE_TABLE(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");