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 TIMER_BASE 100 /* 10MHz master clock */
77 #define AI_BUFFER_SIZE 1024 /* max ai fifo size */
78 #define AO_BUFFER_SIZE 1024 /* max ao fifo size */
79 #define NUM_CHANNELS_8800 8
80 #define NUM_CHANNELS_7376 1
81 #define NUM_CHANNELS_8402 2
82 #define NUM_CHANNELS_DAC08 1
84 /* Control/Status registers */
85 #define INT_ADCFIFO 0 /* INTERRUPT / ADC FIFO register */
86 #define INT_EOS 0x1 /* int end of scan */
87 #define INT_FHF 0x2 /* int fifo half full */
88 #define INT_FNE 0x3 /* int fifo not empty */
89 #define INT_MASK 0x3 /* mask of int select bits */
90 #define INTE 0x4 /* int enable */
91 #define DAHFIE 0x8 /* dac half full int enable */
92 #define EOAIE 0x10 /* end of acq. int enable */
93 #define DAHFI 0x20 /* dac half full status / clear */
94 #define EOAI 0x40 /* end of acq. int status / clear */
95 #define INT 0x80 /* int status / clear */
96 #define EOBI 0x200 /* end of burst int status */
97 #define ADHFI 0x400 /* half-full int status */
98 #define ADNEI 0x800 /* fifo not empty int status (latch) */
99 #define ADNE 0x1000 /* fifo not empty status (realtime) */
100 #define DAEMIE 0x1000 /* dac empty int enable */
101 #define LADFUL 0x2000 /* fifo overflow / clear */
102 #define DAEMI 0x4000 /* dac fifo empty int status / clear */
104 #define ADCMUX_CONT 2 /* ADC CHANNEL MUX AND CONTROL reg */
105 #define BEGIN_SCAN(x) ((x) & 0xf)
106 #define END_SCAN(x) (((x) & 0xf) << 4)
107 #define GAIN_BITS(x) (((x) & 0x3) << 8)
108 #define UNIP 0x800 /* Analog front-end unipolar mode */
109 #define SE 0x400 /* Inputs in single-ended mode */
110 #define PACER_MASK 0x3000 /* pacer source bits */
111 #define PACER_INT 0x1000 /* int. pacer */
112 #define PACER_EXT_FALL 0x2000 /* ext. falling edge */
113 #define PACER_EXT_RISE 0x3000 /* ext. rising edge */
114 #define EOC 0x4000 /* adc not busy */
116 #define TRIG_CONTSTAT 4 /* TRIGGER CONTROL/STATUS register */
117 #define SW_TRIGGER 0x1 /* software start trigger */
118 #define EXT_TRIGGER 0x2 /* ext. start trigger */
119 #define ANALOG_TRIGGER 0x3 /* ext. analog trigger */
120 #define TRIGGER_MASK 0x3 /* start trigger mask */
121 #define TGPOL 0x04 /* invert trigger (1602 only) */
122 #define TGSEL 0x08 /* edge/level trigerred (1602 only) */
123 #define TGEN 0x10 /* enable external start trigger */
124 #define BURSTE 0x20 /* burst mode enable */
125 #define XTRCL 0x80 /* clear external trigger */
127 #define CALIBRATION_REG 6 /* CALIBRATION register */
128 #define SELECT_8800_BIT 0x100 /* select 8800 caldac */
129 #define SELECT_TRIMPOT_BIT 0x200 /* select ad7376 trim pot */
130 #define SELECT_DAC08_BIT 0x400 /* select dac08 caldac */
131 #define CAL_SRC_BITS(x) (((x) & 0x7) << 11)
132 #define CAL_EN_BIT 0x4000 /* calibration source enable */
133 #define SERIAL_DATA_IN_BIT 0x8000 /* serial data bit going to caldac */
135 #define DAC_CSR 0x8 /* dac control and status register */
136 #define DACEN 0x02 /* dac enable */
137 #define DAC_MODE_UPDATE_BOTH 0x80 /* update both dacs */
139 static inline unsigned int DAC_RANGE(unsigned int channel, unsigned int range)
141 return (range & 0x3) << (8 + 2 * (channel & 0x1));
144 static inline unsigned int DAC_RANGE_MASK(unsigned int channel)
146 return 0x3 << (8 + 2 * (channel & 0x1));
149 /* bits for 1602 series only */
150 #define DAC_EMPTY 0x1 /* fifo empty, read, write clear */
151 #define DAC_START 0x4 /* start/arm fifo operations */
152 #define DAC_PACER_MASK 0x18 /* bits that set pacer source */
153 #define DAC_PACER_INT 0x8 /* int. pacing */
154 #define DAC_PACER_EXT_FALL 0x10 /* ext. pacing, falling edge */
155 #define DAC_PACER_EXT_RISE 0x18 /* ext. pacing, rising edge */
157 static inline unsigned int DAC_CHAN_EN(unsigned int channel)
159 return 1 << (5 + (channel & 0x1)); /* enable channel 0 or 1 */
162 /* analog input fifo */
163 #define ADCDATA 0 /* ADC DATA register */
164 #define ADCFIFOCLR 2 /* ADC FIFO CLEAR */
166 /* pacer, counter, dio registers */
171 /* analog output registers for 100x, 1200 series */
172 static inline unsigned int DAC_DATA_REG(unsigned int channel)
174 return 2 * (channel & 0x1);
177 /* analog output registers for 1602 series*/
178 #define DACDATA 0 /* DAC DATA register */
179 #define DACFIFOCLR 2 /* DAC FIFO CLEAR */
181 #define IS_UNIPOLAR 0x4 /* unipolar range mask */
183 /* analog input ranges for most boards */
184 static const struct comedi_lrange cb_pcidas_ranges = {
198 /* pci-das1001 input ranges */
199 static const struct comedi_lrange cb_pcidas_alt_ranges = {
213 /* analog output ranges */
214 static const struct comedi_lrange cb_pcidas_ao_ranges = {
229 enum cb_pcidas_boardid {
234 BOARD_PCIDAS1602_16_JR,
240 struct cb_pcidas_board {
242 int ai_nchan; /* Inputs in single-ended mode */
243 int ai_bits; /* analog input resolution */
244 int ai_speed; /* fastest conversion period in ns */
245 int ao_nchan; /* number of analog out channels */
246 int has_ao_fifo; /* analog output has fifo */
247 int ao_scan_speed; /* analog output scan speed for 1602 series */
248 int fifo_size; /* number of samples fifo can hold */
249 const struct comedi_lrange *ranges;
250 enum trimpot_model trimpot;
251 unsigned has_dac08:1;
255 static const struct cb_pcidas_board cb_pcidas_boards[] = {
256 [BOARD_PCIDAS1602_16] = {
257 .name = "pci-das1602/16",
263 .ao_scan_speed = 10000,
265 .ranges = &cb_pcidas_ranges,
270 [BOARD_PCIDAS1200] = {
271 .name = "pci-das1200",
277 .ranges = &cb_pcidas_ranges,
280 [BOARD_PCIDAS1602_12] = {
281 .name = "pci-das1602/12",
287 .ao_scan_speed = 4000,
289 .ranges = &cb_pcidas_ranges,
293 [BOARD_PCIDAS1200_JR] = {
294 .name = "pci-das1200/jr",
299 .ranges = &cb_pcidas_ranges,
302 [BOARD_PCIDAS1602_16_JR] = {
303 .name = "pci-das1602/16/jr",
308 .ranges = &cb_pcidas_ranges,
313 [BOARD_PCIDAS1000] = {
314 .name = "pci-das1000",
319 .ranges = &cb_pcidas_ranges,
322 [BOARD_PCIDAS1001] = {
323 .name = "pci-das1001",
329 .ranges = &cb_pcidas_alt_ranges,
332 [BOARD_PCIDAS1002] = {
333 .name = "pci-das1002",
339 .ranges = &cb_pcidas_ranges,
344 struct cb_pcidas_private {
346 unsigned long s5933_config;
347 unsigned long control_status;
348 unsigned long adc_fifo;
349 unsigned long pacer_counter_dio;
350 unsigned long ao_registers;
351 /* divisors of master clock for analog input pacing */
352 unsigned int divisor1;
353 unsigned int divisor2;
354 /* number of analog input samples remaining */
356 /* bits to write to registers */
357 unsigned int adc_fifo_bits;
358 unsigned int s5933_intcsr_bits;
359 unsigned int ao_control_bits;
361 short ai_buffer[AI_BUFFER_SIZE];
362 short ao_buffer[AO_BUFFER_SIZE];
363 /* divisors of master clock for analog output pacing */
364 unsigned int ao_divisor1;
365 unsigned int ao_divisor2;
366 /* number of analog output samples remaining */
367 unsigned int ao_count;
368 /* cached values for readback */
370 unsigned int caldac_value[NUM_CHANNELS_8800];
371 unsigned int trimpot_value[NUM_CHANNELS_8402];
372 unsigned int dac08_value;
373 unsigned int calibration_source;
376 static inline unsigned int cal_enable_bits(struct comedi_device *dev)
378 struct cb_pcidas_private *devpriv = dev->private;
380 return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source);
383 static int cb_pcidas_ai_rinsn(struct comedi_device *dev,
384 struct comedi_subdevice *s,
385 struct comedi_insn *insn, unsigned int *data)
387 struct cb_pcidas_private *devpriv = dev->private;
388 unsigned int chan = CR_CHAN(insn->chanspec);
389 unsigned int range = CR_RANGE(insn->chanspec);
390 unsigned int aref = CR_AREF(insn->chanspec);
394 /* enable calibration input if appropriate */
395 if (insn->chanspec & CR_ALT_SOURCE) {
396 outw(cal_enable_bits(dev),
397 devpriv->control_status + CALIBRATION_REG);
400 outw(0, devpriv->control_status + CALIBRATION_REG);
403 /* set mux limits and gain */
404 bits = BEGIN_SCAN(chan) | END_SCAN(chan) | GAIN_BITS(range);
405 /* set unipolar/bipolar */
406 if (range & IS_UNIPOLAR)
408 /* set single-ended/differential */
409 if (aref != AREF_DIFF)
411 outw(bits, devpriv->control_status + ADCMUX_CONT);
414 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
416 /* convert n samples */
417 for (n = 0; n < insn->n; n++) {
418 /* trigger conversion */
419 outw(0, devpriv->adc_fifo + ADCDATA);
421 /* wait for conversion to end */
422 /* return -ETIMEDOUT if there is a timeout */
423 for (i = 0; i < 10000; i++) {
424 if (inw(devpriv->control_status + ADCMUX_CONT) & EOC)
431 data[n] = inw(devpriv->adc_fifo + ADCDATA);
434 /* return the number of samples read/written */
438 static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
439 struct comedi_insn *insn, unsigned int *data)
441 struct cb_pcidas_private *devpriv = dev->private;
443 unsigned int source = data[1];
446 case INSN_CONFIG_ALT_SOURCE:
448 dev_err(dev->class_dev,
449 "invalid calibration source: %i\n",
453 devpriv->calibration_source = source;
462 /* analog output insn for pcidas-1000 and 1200 series */
463 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev,
464 struct comedi_subdevice *s,
465 struct comedi_insn *insn,
468 struct cb_pcidas_private *devpriv = dev->private;
469 unsigned int chan = CR_CHAN(insn->chanspec);
470 unsigned int range = CR_RANGE(insn->chanspec);
473 /* set channel and range */
474 spin_lock_irqsave(&dev->spinlock, flags);
475 devpriv->ao_control_bits &= (~DAC_MODE_UPDATE_BOTH &
476 ~DAC_RANGE_MASK(chan));
477 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range));
478 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
479 spin_unlock_irqrestore(&dev->spinlock, flags);
481 /* remember value for readback */
482 devpriv->ao_value[chan] = data[0];
485 outw(data[0], devpriv->ao_registers + DAC_DATA_REG(chan));
490 /* analog output insn for pcidas-1602 series */
491 static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev,
492 struct comedi_subdevice *s,
493 struct comedi_insn *insn, unsigned int *data)
495 struct cb_pcidas_private *devpriv = dev->private;
496 unsigned int chan = CR_CHAN(insn->chanspec);
497 unsigned int range = CR_RANGE(insn->chanspec);
501 outw(0, devpriv->ao_registers + DACFIFOCLR);
503 /* set channel and range */
504 spin_lock_irqsave(&dev->spinlock, flags);
505 devpriv->ao_control_bits &= (~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) &
506 ~DAC_RANGE_MASK(chan) & ~DAC_PACER_MASK);
507 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range) |
508 DAC_CHAN_EN(chan) | DAC_START);
509 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
510 spin_unlock_irqrestore(&dev->spinlock, flags);
512 /* remember value for readback */
513 devpriv->ao_value[chan] = data[0];
516 outw(data[0], devpriv->ao_registers + DACDATA);
521 static int cb_pcidas_ao_readback_insn(struct comedi_device *dev,
522 struct comedi_subdevice *s,
523 struct comedi_insn *insn,
526 struct cb_pcidas_private *devpriv = dev->private;
528 data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
533 static int wait_for_nvram_ready(unsigned long s5933_base_addr)
535 static const int timeout = 1000;
538 for (i = 0; i < timeout; i++) {
539 if ((inb(s5933_base_addr +
540 AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
548 static int nvram_read(struct comedi_device *dev, unsigned int address,
551 struct cb_pcidas_private *devpriv = dev->private;
552 unsigned long iobase = devpriv->s5933_config;
554 if (wait_for_nvram_ready(iobase) < 0)
557 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
558 iobase + AMCC_OP_REG_MCSR_NVCMD);
559 outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
560 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
561 iobase + AMCC_OP_REG_MCSR_NVCMD);
562 outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
563 outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
565 if (wait_for_nvram_ready(iobase) < 0)
568 *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
573 static int eeprom_read_insn(struct comedi_device *dev,
574 struct comedi_subdevice *s,
575 struct comedi_insn *insn, unsigned int *data)
580 retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
584 data[0] = nvram_data;
589 static void write_calibration_bitstream(struct comedi_device *dev,
590 unsigned int register_bits,
591 unsigned int bitstream,
592 unsigned int bitstream_length)
594 struct cb_pcidas_private *devpriv = dev->private;
595 static const int write_delay = 1;
598 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
600 register_bits |= SERIAL_DATA_IN_BIT;
602 register_bits &= ~SERIAL_DATA_IN_BIT;
604 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
608 static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
611 struct cb_pcidas_private *devpriv = dev->private;
612 static const int num_caldac_channels = 8;
613 static const int bitstream_length = 11;
614 unsigned int bitstream = ((address & 0x7) << 8) | value;
615 static const int caldac_8800_udelay = 1;
617 if (address >= num_caldac_channels) {
618 comedi_error(dev, "illegal caldac channel");
622 if (value == devpriv->caldac_value[address])
625 devpriv->caldac_value[address] = value;
627 write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
630 udelay(caldac_8800_udelay);
631 outw(cal_enable_bits(dev) | SELECT_8800_BIT,
632 devpriv->control_status + CALIBRATION_REG);
633 udelay(caldac_8800_udelay);
634 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
639 static int caldac_write_insn(struct comedi_device *dev,
640 struct comedi_subdevice *s,
641 struct comedi_insn *insn, unsigned int *data)
643 const unsigned int channel = CR_CHAN(insn->chanspec);
645 return caldac_8800_write(dev, channel, data[0]);
648 static int caldac_read_insn(struct comedi_device *dev,
649 struct comedi_subdevice *s,
650 struct comedi_insn *insn, unsigned int *data)
652 struct cb_pcidas_private *devpriv = dev->private;
654 data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)];
659 /* 1602/16 pregain offset */
660 static void dac08_write(struct comedi_device *dev, unsigned int value)
662 struct cb_pcidas_private *devpriv = dev->private;
663 unsigned long cal_reg;
665 if (devpriv->dac08_value != value) {
666 devpriv->dac08_value = value;
668 cal_reg = devpriv->control_status + CALIBRATION_REG;
671 value |= cal_enable_bits(dev);
673 /* latch the new value into the caldac */
674 outw(value, cal_reg);
676 outw(value | SELECT_DAC08_BIT, cal_reg);
678 outw(value, cal_reg);
683 static int dac08_write_insn(struct comedi_device *dev,
684 struct comedi_subdevice *s,
685 struct comedi_insn *insn, unsigned int *data)
689 for (i = 0; i < insn->n; i++)
690 dac08_write(dev, data[i]);
695 static int dac08_read_insn(struct comedi_device *dev,
696 struct comedi_subdevice *s, struct comedi_insn *insn,
699 struct cb_pcidas_private *devpriv = dev->private;
701 data[0] = devpriv->dac08_value;
706 static int trimpot_7376_write(struct comedi_device *dev, uint8_t value)
708 struct cb_pcidas_private *devpriv = dev->private;
709 static const int bitstream_length = 7;
710 unsigned int bitstream = value & 0x7f;
711 unsigned int register_bits;
712 static const int ad7376_udelay = 1;
714 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
715 udelay(ad7376_udelay);
716 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
718 write_calibration_bitstream(dev, register_bits, bitstream,
721 udelay(ad7376_udelay);
722 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
729 * ch 1 : adc postgain offset */
730 static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
733 struct cb_pcidas_private *devpriv = dev->private;
734 static const int bitstream_length = 10;
735 unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
736 unsigned int register_bits;
737 static const int ad8402_udelay = 1;
739 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
740 udelay(ad8402_udelay);
741 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
743 write_calibration_bitstream(dev, register_bits, bitstream,
746 udelay(ad8402_udelay);
747 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
752 static int cb_pcidas_trimpot_write(struct comedi_device *dev,
753 unsigned int channel, unsigned int value)
755 const struct cb_pcidas_board *thisboard = comedi_board(dev);
756 struct cb_pcidas_private *devpriv = dev->private;
758 if (devpriv->trimpot_value[channel] == value)
761 devpriv->trimpot_value[channel] = value;
762 switch (thisboard->trimpot) {
764 trimpot_7376_write(dev, value);
767 trimpot_8402_write(dev, channel, value);
770 comedi_error(dev, "driver bug?");
778 static int trimpot_write_insn(struct comedi_device *dev,
779 struct comedi_subdevice *s,
780 struct comedi_insn *insn, unsigned int *data)
782 unsigned int channel = CR_CHAN(insn->chanspec);
784 return cb_pcidas_trimpot_write(dev, channel, data[0]);
787 static int trimpot_read_insn(struct comedi_device *dev,
788 struct comedi_subdevice *s,
789 struct comedi_insn *insn, unsigned int *data)
791 struct cb_pcidas_private *devpriv = dev->private;
792 unsigned int channel = CR_CHAN(insn->chanspec);
794 data[0] = devpriv->trimpot_value[channel];
799 static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
800 struct comedi_subdevice *s,
801 struct comedi_cmd *cmd)
803 const struct cb_pcidas_board *thisboard = comedi_board(dev);
804 struct cb_pcidas_private *devpriv = dev->private;
807 int i, gain, start_chan;
809 /* Step 1 : check if triggers are trivially valid */
811 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
812 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
813 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
814 err |= cfc_check_trigger_src(&cmd->convert_src,
815 TRIG_TIMER | TRIG_NOW | TRIG_EXT);
816 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
817 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
822 /* Step 2a : make sure trigger sources are unique */
824 err |= cfc_check_trigger_is_unique(cmd->start_src);
825 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
826 err |= cfc_check_trigger_is_unique(cmd->convert_src);
827 err |= cfc_check_trigger_is_unique(cmd->stop_src);
829 /* Step 2b : and mutually compatible */
831 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
833 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
835 if (cmd->start_src == TRIG_EXT &&
836 (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))
842 /* step 3: arguments are trivially compatible */
844 switch (cmd->start_src) {
846 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
848 & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
849 cmd->start_arg &= ~(CR_FLAGS_MASK &
850 ~(CR_EDGE | CR_INVERT));
853 if (!thisboard->is_1602 && (cmd->start_arg & CR_INVERT)) {
854 cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
859 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
863 if (cmd->scan_begin_src == TRIG_TIMER)
864 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
865 thisboard->ai_speed * cmd->chanlist_len);
867 if (cmd->convert_src == TRIG_TIMER)
868 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
869 thisboard->ai_speed);
871 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
873 if (cmd->stop_src == TRIG_NONE)
874 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
879 /* step 4: fix up any arguments */
881 if (cmd->scan_begin_src == TRIG_TIMER) {
882 tmp = cmd->scan_begin_arg;
883 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
884 &(devpriv->divisor1),
885 &(devpriv->divisor2),
886 &(cmd->scan_begin_arg),
887 cmd->flags & TRIG_ROUND_MASK);
888 if (tmp != cmd->scan_begin_arg)
891 if (cmd->convert_src == TRIG_TIMER) {
892 tmp = cmd->convert_arg;
893 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
894 &(devpriv->divisor1),
895 &(devpriv->divisor2),
897 cmd->flags & TRIG_ROUND_MASK);
898 if (tmp != cmd->convert_arg)
905 /* check channel/gain list against card's limitations */
907 gain = CR_RANGE(cmd->chanlist[0]);
908 start_chan = CR_CHAN(cmd->chanlist[0]);
909 for (i = 1; i < cmd->chanlist_len; i++) {
910 if (CR_CHAN(cmd->chanlist[i]) !=
911 (start_chan + i) % s->n_chan) {
913 "entries in chanlist must be consecutive channels, counting upwards\n");
916 if (CR_RANGE(cmd->chanlist[i]) != gain) {
918 "entries in chanlist must all have the same gain\n");
930 static void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns,
933 struct cb_pcidas_private *devpriv = dev->private;
935 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
936 &(devpriv->divisor2), ns,
937 rounding_flags & TRIG_ROUND_MASK);
939 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
940 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1,
941 devpriv->divisor1, 2);
942 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2,
943 devpriv->divisor2, 2);
946 static int cb_pcidas_ai_cmd(struct comedi_device *dev,
947 struct comedi_subdevice *s)
949 const struct cb_pcidas_board *thisboard = comedi_board(dev);
950 struct cb_pcidas_private *devpriv = dev->private;
951 struct comedi_async *async = s->async;
952 struct comedi_cmd *cmd = &async->cmd;
956 /* make sure CAL_EN_BIT is disabled */
957 outw(0, devpriv->control_status + CALIBRATION_REG);
958 /* initialize before settings pacer source and count values */
959 outw(0, devpriv->control_status + TRIG_CONTSTAT);
961 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
963 /* set mux limits, gain and pacer source */
964 bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
965 END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
966 GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
967 /* set unipolar/bipolar */
968 if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
970 /* set singleended/differential */
971 if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
973 /* set pacer source */
974 if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
975 bits |= PACER_EXT_RISE;
978 outw(bits, devpriv->control_status + ADCMUX_CONT);
981 if (cmd->convert_src == TRIG_TIMER)
982 cb_pcidas_load_counters(dev, &cmd->convert_arg,
983 cmd->flags & TRIG_ROUND_MASK);
984 else if (cmd->scan_begin_src == TRIG_TIMER)
985 cb_pcidas_load_counters(dev, &cmd->scan_begin_arg,
986 cmd->flags & TRIG_ROUND_MASK);
988 /* set number of conversions */
989 if (cmd->stop_src == TRIG_COUNT)
990 devpriv->count = cmd->chanlist_len * cmd->stop_arg;
991 /* enable interrupts */
992 spin_lock_irqsave(&dev->spinlock, flags);
993 devpriv->adc_fifo_bits |= INTE;
994 devpriv->adc_fifo_bits &= ~INT_MASK;
995 if (cmd->flags & TRIG_WAKE_EOS) {
996 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) {
997 /* interrupt end of burst */
998 devpriv->adc_fifo_bits |= INT_EOS;
1000 /* interrupt fifo not empty */
1001 devpriv->adc_fifo_bits |= INT_FNE;
1004 /* interrupt fifo half full */
1005 devpriv->adc_fifo_bits |= INT_FHF;
1008 /* enable (and clear) interrupts */
1009 outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
1010 devpriv->control_status + INT_ADCFIFO);
1011 spin_unlock_irqrestore(&dev->spinlock, flags);
1013 /* set start trigger and burst mode */
1015 if (cmd->start_src == TRIG_NOW)
1017 else if (cmd->start_src == TRIG_EXT) {
1018 bits |= EXT_TRIGGER | TGEN | XTRCL;
1019 if (thisboard->is_1602) {
1020 if (cmd->start_arg & CR_INVERT)
1022 if (cmd->start_arg & CR_EDGE)
1026 comedi_error(dev, "bug!");
1029 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1031 outw(bits, devpriv->control_status + TRIG_CONTSTAT);
1036 static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
1037 struct comedi_subdevice *s,
1038 struct comedi_cmd *cmd)
1040 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1041 struct cb_pcidas_private *devpriv = dev->private;
1045 /* Step 1 : check if triggers are trivially valid */
1047 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT);
1048 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
1049 TRIG_TIMER | TRIG_EXT);
1050 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
1051 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1052 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1057 /* Step 2a : make sure trigger sources are unique */
1059 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
1060 err |= cfc_check_trigger_is_unique(cmd->stop_src);
1062 /* Step 2b : and mutually compatible */
1067 /* Step 3: check if arguments are trivially valid */
1069 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1071 if (cmd->scan_begin_src == TRIG_TIMER)
1072 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1073 thisboard->ao_scan_speed);
1075 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1077 if (cmd->stop_src == TRIG_NONE)
1078 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1083 /* step 4: fix up any arguments */
1085 if (cmd->scan_begin_src == TRIG_TIMER) {
1086 tmp = cmd->scan_begin_arg;
1087 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1088 &(devpriv->ao_divisor1),
1089 &(devpriv->ao_divisor2),
1090 &(cmd->scan_begin_arg),
1091 cmd->flags & TRIG_ROUND_MASK);
1092 if (tmp != cmd->scan_begin_arg)
1099 /* check channel/gain list against card's limitations */
1100 if (cmd->chanlist && cmd->chanlist_len > 1) {
1101 if (CR_CHAN(cmd->chanlist[0]) != 0 ||
1102 CR_CHAN(cmd->chanlist[1]) != 1) {
1104 "channels must be ordered channel 0, channel 1 in chanlist\n");
1115 /* cancel analog input command */
1116 static int cb_pcidas_cancel(struct comedi_device *dev,
1117 struct comedi_subdevice *s)
1119 struct cb_pcidas_private *devpriv = dev->private;
1120 unsigned long flags;
1122 spin_lock_irqsave(&dev->spinlock, flags);
1123 /* disable interrupts */
1124 devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
1125 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1126 spin_unlock_irqrestore(&dev->spinlock, flags);
1128 /* disable start trigger source and burst mode */
1129 outw(0, devpriv->control_status + TRIG_CONTSTAT);
1130 /* software pacer source */
1131 outw(0, devpriv->control_status + ADCMUX_CONT);
1136 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1137 struct comedi_subdevice *s,
1138 unsigned int trig_num)
1140 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1141 struct cb_pcidas_private *devpriv = dev->private;
1142 unsigned int num_bytes, num_points = thisboard->fifo_size;
1143 struct comedi_async *async = s->async;
1144 struct comedi_cmd *cmd = &s->async->cmd;
1145 unsigned long flags;
1151 if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
1152 num_points = devpriv->ao_count;
1154 num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1155 num_points * sizeof(short));
1156 num_points = num_bytes / sizeof(short);
1158 if (cmd->stop_src == TRIG_COUNT)
1159 devpriv->ao_count -= num_points;
1160 /* write data to board's fifo */
1161 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
1163 /* enable dac half-full and empty interrupts */
1164 spin_lock_irqsave(&dev->spinlock, flags);
1165 devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
1167 /* enable and clear interrupts */
1168 outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
1169 devpriv->control_status + INT_ADCFIFO);
1172 devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1173 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1175 spin_unlock_irqrestore(&dev->spinlock, flags);
1177 async->inttrig = NULL;
1182 static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1183 struct comedi_subdevice *s)
1185 struct cb_pcidas_private *devpriv = dev->private;
1186 struct comedi_async *async = s->async;
1187 struct comedi_cmd *cmd = &async->cmd;
1189 unsigned long flags;
1191 /* set channel limits, gain */
1192 spin_lock_irqsave(&dev->spinlock, flags);
1193 for (i = 0; i < cmd->chanlist_len; i++) {
1194 /* enable channel */
1195 devpriv->ao_control_bits |=
1196 DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
1198 devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
1203 /* disable analog out before settings pacer source and count values */
1204 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1205 spin_unlock_irqrestore(&dev->spinlock, flags);
1208 outw(0, devpriv->ao_registers + DACFIFOCLR);
1211 if (cmd->scan_begin_src == TRIG_TIMER) {
1212 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1213 &(devpriv->ao_divisor1),
1214 &(devpriv->ao_divisor2),
1215 &(cmd->scan_begin_arg),
1218 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1219 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1,
1220 devpriv->ao_divisor1, 2);
1221 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2,
1222 devpriv->ao_divisor2, 2);
1224 /* set number of conversions */
1225 if (cmd->stop_src == TRIG_COUNT)
1226 devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
1227 /* set pacer source */
1228 spin_lock_irqsave(&dev->spinlock, flags);
1229 switch (cmd->scan_begin_src) {
1231 devpriv->ao_control_bits |= DAC_PACER_INT;
1234 devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1237 spin_unlock_irqrestore(&dev->spinlock, flags);
1238 comedi_error(dev, "error setting dac pacer source");
1242 spin_unlock_irqrestore(&dev->spinlock, flags);
1244 async->inttrig = cb_pcidas_ao_inttrig;
1249 /* cancel analog output command */
1250 static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1251 struct comedi_subdevice *s)
1253 struct cb_pcidas_private *devpriv = dev->private;
1254 unsigned long flags;
1256 spin_lock_irqsave(&dev->spinlock, flags);
1257 /* disable interrupts */
1258 devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
1259 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1261 /* disable output */
1262 devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1263 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1264 spin_unlock_irqrestore(&dev->spinlock, flags);
1269 static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
1271 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1272 struct cb_pcidas_private *devpriv = dev->private;
1273 struct comedi_subdevice *s = dev->write_subdev;
1274 struct comedi_async *async = s->async;
1275 struct comedi_cmd *cmd = &async->cmd;
1276 unsigned int half_fifo = thisboard->fifo_size / 2;
1277 unsigned int num_points;
1278 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 comedi_error(dev, "dac fifo underflow");
1293 cb_pcidas_ao_cancel(dev, s);
1294 async->events |= COMEDI_CB_ERROR;
1296 async->events |= COMEDI_CB_EOA;
1298 } else if (status & DAHFI) {
1299 unsigned int num_bytes;
1301 /* figure out how many points we are writing to fifo */
1302 num_points = half_fifo;
1303 if (cmd->stop_src == TRIG_COUNT &&
1304 devpriv->ao_count < num_points)
1305 num_points = devpriv->ao_count;
1307 cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1308 num_points * sizeof(short));
1309 num_points = num_bytes / sizeof(short);
1311 if (async->cmd.stop_src == TRIG_COUNT)
1312 devpriv->ao_count -= num_points;
1313 /* write data to board's fifo */
1314 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
1316 /* clear half-full interrupt latch */
1317 spin_lock_irqsave(&dev->spinlock, flags);
1318 outw(devpriv->adc_fifo_bits | DAHFI,
1319 devpriv->control_status + INT_ADCFIFO);
1320 spin_unlock_irqrestore(&dev->spinlock, flags);
1323 comedi_event(dev, s);
1326 static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1328 struct comedi_device *dev = (struct comedi_device *)d;
1329 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1330 struct cb_pcidas_private *devpriv = dev->private;
1331 struct comedi_subdevice *s = dev->read_subdev;
1332 struct comedi_async *async;
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 (async->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 (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) {
1376 async->events |= COMEDI_CB_EOA;
1377 cb_pcidas_cancel(dev, s);
1379 /* clear half-full interrupt latch */
1380 spin_lock_irqsave(&dev->spinlock, flags);
1381 outw(devpriv->adc_fifo_bits | INT,
1382 devpriv->control_status + INT_ADCFIFO);
1383 spin_unlock_irqrestore(&dev->spinlock, flags);
1384 /* else if fifo not empty */
1385 } else if (status & (ADNEI | EOBI)) {
1386 for (i = 0; i < timeout; i++) {
1387 /* break if fifo is empty */
1388 if ((ADNE & inw(devpriv->control_status +
1391 cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
1392 if (async->cmd.stop_src == TRIG_COUNT &&
1393 --devpriv->count == 0) {
1394 /* end of acquisition */
1395 cb_pcidas_cancel(dev, s);
1396 async->events |= COMEDI_CB_EOA;
1400 /* clear not-empty interrupt latch */
1401 spin_lock_irqsave(&dev->spinlock, flags);
1402 outw(devpriv->adc_fifo_bits | INT,
1403 devpriv->control_status + INT_ADCFIFO);
1404 spin_unlock_irqrestore(&dev->spinlock, flags);
1405 } else if (status & EOAI) {
1407 "bug! encountered end of acquisition interrupt?");
1408 /* clear EOA interrupt latch */
1409 spin_lock_irqsave(&dev->spinlock, flags);
1410 outw(devpriv->adc_fifo_bits | EOAI,
1411 devpriv->control_status + INT_ADCFIFO);
1412 spin_unlock_irqrestore(&dev->spinlock, flags);
1414 /* check for fifo overflow */
1415 if (status & LADFUL) {
1416 comedi_error(dev, "fifo overflow");
1417 /* clear overflow interrupt latch */
1418 spin_lock_irqsave(&dev->spinlock, flags);
1419 outw(devpriv->adc_fifo_bits | LADFUL,
1420 devpriv->control_status + INT_ADCFIFO);
1421 spin_unlock_irqrestore(&dev->spinlock, flags);
1422 cb_pcidas_cancel(dev, s);
1423 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1426 comedi_event(dev, s);
1431 static int cb_pcidas_auto_attach(struct comedi_device *dev,
1432 unsigned long context)
1434 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1435 const struct cb_pcidas_board *thisboard = NULL;
1436 struct cb_pcidas_private *devpriv;
1437 struct comedi_subdevice *s;
1441 if (context < ARRAY_SIZE(cb_pcidas_boards))
1442 thisboard = &cb_pcidas_boards[context];
1445 dev->board_ptr = thisboard;
1446 dev->board_name = thisboard->name;
1448 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1452 ret = comedi_pci_enable(dev);
1456 devpriv->s5933_config = pci_resource_start(pcidev, 0);
1457 devpriv->control_status = pci_resource_start(pcidev, 1);
1458 devpriv->adc_fifo = pci_resource_start(pcidev, 2);
1459 devpriv->pacer_counter_dio = pci_resource_start(pcidev, 3);
1460 if (thisboard->ao_nchan)
1461 devpriv->ao_registers = pci_resource_start(pcidev, 4);
1463 /* disable and clear interrupts on amcc s5933 */
1464 outl(INTCSR_INBOX_INTR_STATUS,
1465 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1467 if (request_irq(pcidev->irq, cb_pcidas_interrupt,
1468 IRQF_SHARED, dev->driver->driver_name, dev)) {
1469 dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
1473 dev->irq = pcidev->irq;
1475 ret = comedi_alloc_subdevices(dev, 7);
1479 s = &dev->subdevices[0];
1480 /* analog input subdevice */
1481 dev->read_subdev = s;
1482 s->type = COMEDI_SUBD_AI;
1483 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
1484 /* WARNING: Number of inputs in differential mode is ignored */
1485 s->n_chan = thisboard->ai_nchan;
1486 s->len_chanlist = thisboard->ai_nchan;
1487 s->maxdata = (1 << thisboard->ai_bits) - 1;
1488 s->range_table = thisboard->ranges;
1489 s->insn_read = cb_pcidas_ai_rinsn;
1490 s->insn_config = ai_config_insn;
1491 s->do_cmd = cb_pcidas_ai_cmd;
1492 s->do_cmdtest = cb_pcidas_ai_cmdtest;
1493 s->cancel = cb_pcidas_cancel;
1495 /* analog output subdevice */
1496 s = &dev->subdevices[1];
1497 if (thisboard->ao_nchan) {
1498 s->type = COMEDI_SUBD_AO;
1499 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1500 s->n_chan = thisboard->ao_nchan;
1502 * analog out resolution is the same as
1503 * analog input resolution, so use ai_bits
1505 s->maxdata = (1 << thisboard->ai_bits) - 1;
1506 s->range_table = &cb_pcidas_ao_ranges;
1507 s->insn_read = cb_pcidas_ao_readback_insn;
1508 if (thisboard->has_ao_fifo) {
1509 dev->write_subdev = s;
1510 s->subdev_flags |= SDF_CMD_WRITE;
1511 s->insn_write = cb_pcidas_ao_fifo_winsn;
1512 s->do_cmdtest = cb_pcidas_ao_cmdtest;
1513 s->do_cmd = cb_pcidas_ao_cmd;
1514 s->cancel = cb_pcidas_ao_cancel;
1516 s->insn_write = cb_pcidas_ao_nofifo_winsn;
1519 s->type = COMEDI_SUBD_UNUSED;
1523 s = &dev->subdevices[2];
1524 ret = subdev_8255_init(dev, s, NULL,
1525 devpriv->pacer_counter_dio + DIO_8255);
1529 /* serial EEPROM, */
1530 s = &dev->subdevices[3];
1531 s->type = COMEDI_SUBD_MEMORY;
1532 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
1535 s->insn_read = eeprom_read_insn;
1538 s = &dev->subdevices[4];
1539 s->type = COMEDI_SUBD_CALIB;
1540 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1541 s->n_chan = NUM_CHANNELS_8800;
1543 s->insn_read = caldac_read_insn;
1544 s->insn_write = caldac_write_insn;
1545 for (i = 0; i < s->n_chan; i++)
1546 caldac_8800_write(dev, i, s->maxdata / 2);
1548 /* trim potentiometer */
1549 s = &dev->subdevices[5];
1550 s->type = COMEDI_SUBD_CALIB;
1551 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1552 if (thisboard->trimpot == AD7376) {
1553 s->n_chan = NUM_CHANNELS_7376;
1556 s->n_chan = NUM_CHANNELS_8402;
1559 s->insn_read = trimpot_read_insn;
1560 s->insn_write = trimpot_write_insn;
1561 for (i = 0; i < s->n_chan; i++)
1562 cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
1565 s = &dev->subdevices[6];
1566 if (thisboard->has_dac08) {
1567 s->type = COMEDI_SUBD_CALIB;
1568 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1569 s->n_chan = NUM_CHANNELS_DAC08;
1570 s->insn_read = dac08_read_insn;
1571 s->insn_write = dac08_write_insn;
1573 dac08_write(dev, s->maxdata / 2);
1575 s->type = COMEDI_SUBD_UNUSED;
1577 /* make sure mailbox 4 is empty */
1578 inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1579 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1580 devpriv->s5933_intcsr_bits =
1581 INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1582 INTCSR_INBOX_FULL_INT;
1583 /* clear and enable interrupt on amcc s5933 */
1584 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1585 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1587 dev_info(dev->class_dev, "%s: %s attached\n",
1588 dev->driver->driver_name, dev->board_name);
1593 static void cb_pcidas_detach(struct comedi_device *dev)
1595 struct cb_pcidas_private *devpriv = dev->private;
1598 if (devpriv->s5933_config) {
1599 outl(INTCSR_INBOX_INTR_STATUS,
1600 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1604 free_irq(dev->irq, dev);
1605 comedi_pci_disable(dev);
1608 static struct comedi_driver cb_pcidas_driver = {
1609 .driver_name = "cb_pcidas",
1610 .module = THIS_MODULE,
1611 .auto_attach = cb_pcidas_auto_attach,
1612 .detach = cb_pcidas_detach,
1615 static int cb_pcidas_pci_probe(struct pci_dev *dev,
1616 const struct pci_device_id *id)
1618 return comedi_pci_auto_config(dev, &cb_pcidas_driver,
1622 static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = {
1623 { PCI_VDEVICE(CB, 0x0001), BOARD_PCIDAS1602_16 },
1624 { PCI_VDEVICE(CB, 0x000f), BOARD_PCIDAS1200 },
1625 { PCI_VDEVICE(CB, 0x0010), BOARD_PCIDAS1602_12 },
1626 { PCI_VDEVICE(CB, 0x0019), BOARD_PCIDAS1200_JR },
1627 { PCI_VDEVICE(CB, 0x001c), BOARD_PCIDAS1602_16_JR },
1628 { PCI_VDEVICE(CB, 0x004c), BOARD_PCIDAS1000 },
1629 { PCI_VDEVICE(CB, 0x001a), BOARD_PCIDAS1001 },
1630 { PCI_VDEVICE(CB, 0x001b), BOARD_PCIDAS1002 },
1633 MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
1635 static struct pci_driver cb_pcidas_pci_driver = {
1636 .name = "cb_pcidas",
1637 .id_table = cb_pcidas_pci_table,
1638 .probe = cb_pcidas_pci_probe,
1639 .remove = comedi_pci_auto_unconfig,
1641 module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver);
1643 MODULE_AUTHOR("Comedi http://www.comedi.org");
1644 MODULE_DESCRIPTION("Comedi low-level driver");
1645 MODULE_LICENSE("GPL");