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 with the AMCC S5933 PCI controller
32 Author: Ivan Martinez <imr@oersted.dtu.dk>,
33 Frank Mori Hess <fmhess@users.sourceforge.net>
35 Devices: [Measurement Computing] PCI-DAS1602/16 (cb_pcidas),
36 PCI-DAS1602/16jr, PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr,
37 PCI-DAS1000, PCI-DAS1001, PCI_DAS1002
40 There are many reports of the driver being used with most of the
41 supported cards. Despite no detailed log is maintained, it can
42 be said that the driver is quite tested and stable.
44 The boards may be autocalibrated using the comedi_calibrate
47 Configuration options:
48 [0] - PCI bus of device (optional)
49 [1] - PCI slot of device (optional)
50 If bus/slot is not specified, the first supported
51 PCI device found will be used.
53 For commands, the scanned channels must be consecutive
54 (i.e. 4-5-6-7, 2-3-4,...), and must all have the same
58 For start_src == TRIG_EXT, the A/D EXTERNAL TRIGGER IN (pin 45) is used.
59 For 1602 series, the start_arg is interpreted as follows:
60 start_arg == 0 => gated trigger (level high)
61 start_arg == CR_INVERT => gated trigger (level low)
62 start_arg == CR_EDGE => Rising edge
63 start_arg == CR_EDGE | CR_INVERT => Falling edge
64 For the other boards the trigger will be done on rising edge
70 analog triggering on 1602 series
73 #include "../comedidev.h"
74 #include <linux/delay.h>
75 #include <linux/interrupt.h>
79 #include "amcc_s5933.h"
80 #include "comedi_fc.h"
82 /* PCI vendor number of ComputerBoards/MeasurementComputing */
83 #define PCI_VENDOR_ID_CB 0x1307
84 #define TIMER_BASE 100 /* 10MHz master clock */
85 #define AI_BUFFER_SIZE 1024 /* maximum fifo size of any supported board */
86 #define AO_BUFFER_SIZE 1024 /* maximum fifo size of any supported board */
87 #define NUM_CHANNELS_8800 8
88 #define NUM_CHANNELS_7376 1
89 #define NUM_CHANNELS_8402 2
90 #define NUM_CHANNELS_DAC08 1
92 /* Control/Status registers */
93 #define INT_ADCFIFO 0 /* INTERRUPT / ADC FIFO register */
94 #define INT_EOS 0x1 /* interrupt end of scan */
95 #define INT_FHF 0x2 /* interrupt fifo half full */
96 #define INT_FNE 0x3 /* interrupt fifo not empty */
97 #define INT_MASK 0x3 /* mask of interrupt select bits */
98 #define INTE 0x4 /* interrupt enable */
99 #define DAHFIE 0x8 /* dac half full interrupt enable */
100 #define EOAIE 0x10 /* end of acquisition interrupt enable */
101 #define DAHFI 0x20 /* dac half full read status / write interrupt clear */
102 #define EOAI 0x40 /* read end of acq. interrupt status / write clear */
103 #define INT 0x80 /* read interrupt status / write clear */
104 #define EOBI 0x200 /* read end of burst interrupt status */
105 #define ADHFI 0x400 /* read half-full interrupt status */
106 #define ADNEI 0x800 /* read fifo not empty interrupt latch status */
107 #define ADNE 0x1000 /* read, fifo not empty (realtime, not latched) status */
108 #define DAEMIE 0x1000 /* write, dac empty interrupt enable */
109 #define LADFUL 0x2000 /* read fifo overflow / write clear */
110 #define DAEMI 0x4000 /* dac fifo empty interrupt status / write clear */
112 #define ADCMUX_CONT 2 /* ADC CHANNEL MUX AND CONTROL register */
113 #define BEGIN_SCAN(x) ((x) & 0xf)
114 #define END_SCAN(x) (((x) & 0xf) << 4)
115 #define GAIN_BITS(x) (((x) & 0x3) << 8)
116 #define UNIP 0x800 /* Analog front-end unipolar for range */
117 #define SE 0x400 /* Inputs in single-ended mode */
118 #define PACER_MASK 0x3000 /* pacer source bits */
119 #define PACER_INT 0x1000 /* internal pacer */
120 #define PACER_EXT_FALL 0x2000 /* external falling edge */
121 #define PACER_EXT_RISE 0x3000 /* external rising edge */
122 #define EOC 0x4000 /* adc not busy */
124 #define TRIG_CONTSTAT 4 /* TRIGGER CONTROL/STATUS register */
125 #define SW_TRIGGER 0x1 /* software start trigger */
126 #define EXT_TRIGGER 0x2 /* external start trigger */
127 #define ANALOG_TRIGGER 0x3 /* external analog trigger */
128 #define TRIGGER_MASK 0x3 /* mask of bits that determine start trigger */
129 #define TGPOL 0x04 /* invert the edge/level of the external trigger (1602 only) */
130 #define TGSEL 0x08 /* if set edge triggered, otherwise level trigerred (1602 only) */
131 #define TGEN 0x10 /* enable external start trigger */
132 #define BURSTE 0x20 /* burst mode enable */
133 #define XTRCL 0x80 /* clear external trigger */
135 #define CALIBRATION_REG 6 /* CALIBRATION register */
136 #define SELECT_8800_BIT 0x100 /* select 8800 caldac */
137 #define SELECT_TRIMPOT_BIT 0x200 /* select ad7376 trim pot */
138 #define SELECT_DAC08_BIT 0x400 /* select dac08 caldac */
139 #define CAL_SRC_BITS(x) (((x) & 0x7) << 11)
140 #define CAL_EN_BIT 0x4000 /* read calibration source instead of analog input channel 0 */
141 #define SERIAL_DATA_IN_BIT 0x8000 /* serial data stream going to 8800 and 7376 */
143 #define DAC_CSR 0x8 /* dac control and status register */
145 DACEN = 0x2, /* dac enable */
146 DAC_MODE_UPDATE_BOTH = 0x80, /* update both dacs when dac0 is written */
148 static inline unsigned int DAC_RANGE(unsigned int channel, unsigned int range)
150 return (range & 0x3) << (8 + 2 * (channel & 0x1));
153 static inline unsigned int DAC_RANGE_MASK(unsigned int channel)
155 return 0x3 << (8 + 2 * (channel & 0x1));
158 /* bits for 1602 series only */
159 enum dac_csr_bits_1602 {
160 DAC_EMPTY = 0x1, /* dac fifo empty, read, write clear */
161 DAC_START = 0x4, /* start/arm dac fifo operations */
162 DAC_PACER_MASK = 0x18, /* bits that set dac pacer source */
163 DAC_PACER_INT = 0x8, /* dac internal pacing */
164 DAC_PACER_EXT_FALL = 0x10, /* dac external pacing, falling edge */
165 DAC_PACER_EXT_RISE = 0x18, /* dac external pacing, rising edge */
167 static inline unsigned int DAC_CHAN_EN(unsigned int channel)
169 return 1 << (5 + (channel & 0x1)); /* enable channel 0 or 1 */
172 /* analog input fifo */
173 #define ADCDATA 0 /* ADC DATA register */
174 #define ADCFIFOCLR 2 /* ADC FIFO CLEAR */
176 /* pacer, counter, dio registers */
181 /* analog output registers for 100x, 1200 series */
182 static inline unsigned int DAC_DATA_REG(unsigned int channel)
184 return 2 * (channel & 0x1);
187 /* analog output registers for 1602 series*/
188 #define DACDATA 0 /* DAC DATA register */
189 #define DACFIFOCLR 2 /* DAC FIFO CLEAR */
191 /* bit in hexadecimal representation of range index that indicates unipolar input range */
192 #define IS_UNIPOLAR 0x4
193 /* analog input ranges for most boards */
194 static const struct comedi_lrange cb_pcidas_ranges = {
208 /* pci-das1001 input ranges */
209 static const struct comedi_lrange cb_pcidas_alt_ranges = {
223 /* analog output ranges */
224 static const struct comedi_lrange cb_pcidas_ao_ranges = {
239 struct cb_pcidas_board {
241 unsigned short device_id;
242 int ai_se_chans; /* 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 speed for 1602 series (for a scan, not conversion) */
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[] = {
257 .name = "pci-das1602/16",
264 .ao_scan_speed = 10000,
266 .ranges = &cb_pcidas_ranges,
271 .name = "pci-das1200",
278 .ranges = &cb_pcidas_ranges,
281 .name = "pci-das1602/12",
288 .ao_scan_speed = 4000,
290 .ranges = &cb_pcidas_ranges,
294 .name = "pci-das1200/jr",
300 .ranges = &cb_pcidas_ranges,
303 .name = "pci-das1602/16/jr",
309 .ranges = &cb_pcidas_ranges,
314 .name = "pci-das1000",
320 .ranges = &cb_pcidas_ranges,
323 .name = "pci-das1001",
330 .ranges = &cb_pcidas_alt_ranges,
333 .name = "pci-das1002",
340 .ranges = &cb_pcidas_ranges,
345 /* this structure is for data unique to this hardware driver. If
346 several hardware drivers keep similar information in this structure,
347 feel free to suggest moving the variable to the struct comedi_device struct. */
348 struct cb_pcidas_private {
349 /* would be useful for a PCI device */
350 struct pci_dev *pci_dev;
352 unsigned long s5933_config;
353 unsigned long control_status;
354 unsigned long adc_fifo;
355 unsigned long pacer_counter_dio;
356 unsigned long ao_registers;
357 /* divisors of master clock for analog input pacing */
358 unsigned int divisor1;
359 unsigned int divisor2;
360 volatile unsigned int count; /* number of analog input samples remaining */
361 volatile unsigned int adc_fifo_bits; /* bits to write to interrupt/adcfifo register */
362 volatile unsigned int s5933_intcsr_bits; /* bits to write to amcc s5933 interrupt control/status register */
363 volatile unsigned int ao_control_bits; /* bits to write to ao control and status register */
364 short ai_buffer[AI_BUFFER_SIZE];
365 short ao_buffer[AO_BUFFER_SIZE];
366 /* divisors of master clock for analog output pacing */
367 unsigned int ao_divisor1;
368 unsigned int ao_divisor2;
369 volatile unsigned int ao_count; /* number of analog output samples remaining */
370 int ao_value[2]; /* remember what the analog outputs are set to, to allow readback */
371 unsigned int caldac_value[NUM_CHANNELS_8800]; /* for readback of caldac */
372 unsigned int trimpot_value[NUM_CHANNELS_8402]; /* for readback of trimpot */
373 unsigned int dac08_value;
374 unsigned int calibration_source;
377 static inline unsigned int cal_enable_bits(struct comedi_device *dev)
379 struct cb_pcidas_private *devpriv = dev->private;
381 return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source);
385 * "instructions" read/write data in "one-shot" or "software-triggered"
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;
395 static const int timeout = 10000;
397 /* enable calibration input if appropriate */
398 if (insn->chanspec & CR_ALT_SOURCE) {
399 outw(cal_enable_bits(dev),
400 devpriv->control_status + CALIBRATION_REG);
403 outw(0, devpriv->control_status + CALIBRATION_REG);
404 channel = CR_CHAN(insn->chanspec);
406 /* set mux limits and gain */
407 bits = BEGIN_SCAN(channel) |
408 END_SCAN(channel) | GAIN_BITS(CR_RANGE(insn->chanspec));
409 /* set unipolar/bipolar */
410 if (CR_RANGE(insn->chanspec) & IS_UNIPOLAR)
412 /* set singleended/differential */
413 if (CR_AREF(insn->chanspec) != AREF_DIFF)
415 outw(bits, devpriv->control_status + ADCMUX_CONT);
418 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
420 /* convert n samples */
421 for (n = 0; n < insn->n; n++) {
422 /* trigger conversion */
423 outw(0, devpriv->adc_fifo + ADCDATA);
425 /* wait for conversion to end */
426 /* return -ETIMEDOUT if there is a timeout */
427 for (i = 0; i < timeout; i++) {
428 if (inw(devpriv->control_status + ADCMUX_CONT) & EOC)
435 data[n] = inw(devpriv->adc_fifo + ADCDATA);
438 /* return the number of samples read/written */
442 static int ai_config_calibration_source(struct comedi_device *dev,
445 struct cb_pcidas_private *devpriv = dev->private;
446 static const int num_calibration_sources = 8;
447 unsigned int source = data[1];
449 if (source >= num_calibration_sources) {
450 dev_err(dev->class_dev, "invalid calibration source: %i\n",
455 devpriv->calibration_source = source;
460 static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
461 struct comedi_insn *insn, unsigned int *data)
466 case INSN_CONFIG_ALT_SOURCE:
467 return ai_config_calibration_source(dev, data);
476 /* analog output insn for pcidas-1000 and 1200 series */
477 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev,
478 struct comedi_subdevice *s,
479 struct comedi_insn *insn,
482 struct cb_pcidas_private *devpriv = dev->private;
486 /* set channel and range */
487 channel = CR_CHAN(insn->chanspec);
488 spin_lock_irqsave(&dev->spinlock, flags);
489 devpriv->ao_control_bits &=
490 ~DAC_MODE_UPDATE_BOTH & ~DAC_RANGE_MASK(channel);
491 devpriv->ao_control_bits |=
492 DACEN | DAC_RANGE(channel, CR_RANGE(insn->chanspec));
493 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
494 spin_unlock_irqrestore(&dev->spinlock, flags);
496 /* remember value for readback */
497 devpriv->ao_value[channel] = data[0];
499 outw(data[0], devpriv->ao_registers + DAC_DATA_REG(channel));
504 /* analog output insn for pcidas-1602 series */
505 static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev,
506 struct comedi_subdevice *s,
507 struct comedi_insn *insn, unsigned int *data)
509 struct cb_pcidas_private *devpriv = dev->private;
514 outw(0, devpriv->ao_registers + DACFIFOCLR);
516 /* set channel and range */
517 channel = CR_CHAN(insn->chanspec);
518 spin_lock_irqsave(&dev->spinlock, flags);
519 devpriv->ao_control_bits &=
520 ~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) & ~DAC_RANGE_MASK(channel) &
522 devpriv->ao_control_bits |=
523 DACEN | DAC_RANGE(channel,
525 chanspec)) | DAC_CHAN_EN(channel) |
527 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
528 spin_unlock_irqrestore(&dev->spinlock, flags);
530 /* remember value for readback */
531 devpriv->ao_value[channel] = data[0];
533 outw(data[0], devpriv->ao_registers + DACDATA);
538 /* analog output readback insn */
539 /* XXX loses track of analog output value back after an analog ouput command is executed */
540 static int cb_pcidas_ao_readback_insn(struct comedi_device *dev,
541 struct comedi_subdevice *s,
542 struct comedi_insn *insn,
545 struct cb_pcidas_private *devpriv = dev->private;
547 data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
552 static int wait_for_nvram_ready(unsigned long s5933_base_addr)
554 static const int timeout = 1000;
557 for (i = 0; i < timeout; i++) {
558 if ((inb(s5933_base_addr +
559 AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
567 static int nvram_read(struct comedi_device *dev, unsigned int address,
570 struct cb_pcidas_private *devpriv = dev->private;
571 unsigned long iobase = devpriv->s5933_config;
573 if (wait_for_nvram_ready(iobase) < 0)
576 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
577 iobase + AMCC_OP_REG_MCSR_NVCMD);
578 outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
579 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
580 iobase + AMCC_OP_REG_MCSR_NVCMD);
581 outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
582 outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
584 if (wait_for_nvram_ready(iobase) < 0)
587 *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
592 static int eeprom_read_insn(struct comedi_device *dev,
593 struct comedi_subdevice *s,
594 struct comedi_insn *insn, unsigned int *data)
599 retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
603 data[0] = nvram_data;
608 static void write_calibration_bitstream(struct comedi_device *dev,
609 unsigned int register_bits,
610 unsigned int bitstream,
611 unsigned int bitstream_length)
613 struct cb_pcidas_private *devpriv = dev->private;
614 static const int write_delay = 1;
617 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
619 register_bits |= SERIAL_DATA_IN_BIT;
621 register_bits &= ~SERIAL_DATA_IN_BIT;
623 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
627 static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
630 struct cb_pcidas_private *devpriv = dev->private;
631 static const int num_caldac_channels = 8;
632 static const int bitstream_length = 11;
633 unsigned int bitstream = ((address & 0x7) << 8) | value;
634 static const int caldac_8800_udelay = 1;
636 if (address >= num_caldac_channels) {
637 comedi_error(dev, "illegal caldac channel");
641 if (value == devpriv->caldac_value[address])
644 devpriv->caldac_value[address] = value;
646 write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
649 udelay(caldac_8800_udelay);
650 outw(cal_enable_bits(dev) | SELECT_8800_BIT,
651 devpriv->control_status + CALIBRATION_REG);
652 udelay(caldac_8800_udelay);
653 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
658 static int caldac_write_insn(struct comedi_device *dev,
659 struct comedi_subdevice *s,
660 struct comedi_insn *insn, unsigned int *data)
662 const unsigned int channel = CR_CHAN(insn->chanspec);
664 return caldac_8800_write(dev, channel, data[0]);
667 static int caldac_read_insn(struct comedi_device *dev,
668 struct comedi_subdevice *s,
669 struct comedi_insn *insn, unsigned int *data)
671 struct cb_pcidas_private *devpriv = dev->private;
673 data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)];
678 /* 1602/16 pregain offset */
679 static int dac08_write(struct comedi_device *dev, unsigned int value)
681 struct cb_pcidas_private *devpriv = dev->private;
683 if (devpriv->dac08_value == value)
686 devpriv->dac08_value = value;
688 outw(cal_enable_bits(dev) | (value & 0xff),
689 devpriv->control_status + CALIBRATION_REG);
691 outw(cal_enable_bits(dev) | SELECT_DAC08_BIT | (value & 0xff),
692 devpriv->control_status + CALIBRATION_REG);
694 outw(cal_enable_bits(dev) | (value & 0xff),
695 devpriv->control_status + CALIBRATION_REG);
701 static int dac08_write_insn(struct comedi_device *dev,
702 struct comedi_subdevice *s,
703 struct comedi_insn *insn, unsigned int *data)
705 return dac08_write(dev, data[0]);
708 static int dac08_read_insn(struct comedi_device *dev,
709 struct comedi_subdevice *s, struct comedi_insn *insn,
712 struct cb_pcidas_private *devpriv = dev->private;
714 data[0] = devpriv->dac08_value;
719 static int trimpot_7376_write(struct comedi_device *dev, uint8_t value)
721 struct cb_pcidas_private *devpriv = dev->private;
722 static const int bitstream_length = 7;
723 unsigned int bitstream = value & 0x7f;
724 unsigned int register_bits;
725 static const int ad7376_udelay = 1;
727 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
728 udelay(ad7376_udelay);
729 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
731 write_calibration_bitstream(dev, register_bits, bitstream,
734 udelay(ad7376_udelay);
735 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
742 * ch 1 : adc postgain offset */
743 static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
746 struct cb_pcidas_private *devpriv = dev->private;
747 static const int bitstream_length = 10;
748 unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
749 unsigned int register_bits;
750 static const int ad8402_udelay = 1;
752 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
753 udelay(ad8402_udelay);
754 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
756 write_calibration_bitstream(dev, register_bits, bitstream,
759 udelay(ad8402_udelay);
760 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
765 static int cb_pcidas_trimpot_write(struct comedi_device *dev,
766 unsigned int channel, unsigned int value)
768 const struct cb_pcidas_board *thisboard = comedi_board(dev);
769 struct cb_pcidas_private *devpriv = dev->private;
771 if (devpriv->trimpot_value[channel] == value)
774 devpriv->trimpot_value[channel] = value;
775 switch (thisboard->trimpot) {
777 trimpot_7376_write(dev, value);
780 trimpot_8402_write(dev, channel, value);
783 comedi_error(dev, "driver bug?");
791 static int trimpot_write_insn(struct comedi_device *dev,
792 struct comedi_subdevice *s,
793 struct comedi_insn *insn, unsigned int *data)
795 unsigned int channel = CR_CHAN(insn->chanspec);
797 return cb_pcidas_trimpot_write(dev, channel, data[0]);
800 static int trimpot_read_insn(struct comedi_device *dev,
801 struct comedi_subdevice *s,
802 struct comedi_insn *insn, unsigned int *data)
804 struct cb_pcidas_private *devpriv = dev->private;
805 unsigned int channel = CR_CHAN(insn->chanspec);
807 data[0] = devpriv->trimpot_value[channel];
812 static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
813 struct comedi_subdevice *s,
814 struct comedi_cmd *cmd)
816 const struct cb_pcidas_board *thisboard = comedi_board(dev);
817 struct cb_pcidas_private *devpriv = dev->private;
820 int i, gain, start_chan;
822 /* cmdtest tests a particular command to see if it is valid.
823 * Using the cmdtest ioctl, a user can create a valid cmd
824 * and then have it executes by the cmd ioctl.
826 * cmdtest returns 1,2,3,4 or 0, depending on which tests
827 * the command passes. */
829 /* step 1: make sure trigger sources are trivially valid */
831 tmp = cmd->start_src;
832 cmd->start_src &= TRIG_NOW | TRIG_EXT;
833 if (!cmd->start_src || tmp != cmd->start_src)
836 tmp = cmd->scan_begin_src;
837 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
838 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
841 tmp = cmd->convert_src;
842 cmd->convert_src &= TRIG_TIMER | TRIG_NOW | TRIG_EXT;
843 if (!cmd->convert_src || tmp != cmd->convert_src)
846 tmp = cmd->scan_end_src;
847 cmd->scan_end_src &= TRIG_COUNT;
848 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
852 cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
853 if (!cmd->stop_src || tmp != cmd->stop_src)
859 /* step 2: make sure trigger sources are unique and mutually compatible */
861 if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
863 if (cmd->scan_begin_src != TRIG_FOLLOW &&
864 cmd->scan_begin_src != TRIG_TIMER &&
865 cmd->scan_begin_src != TRIG_EXT)
867 if (cmd->convert_src != TRIG_TIMER &&
868 cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
870 if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
873 /* make sure trigger sources are compatible with each other */
874 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
876 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
878 if (cmd->start_src == TRIG_EXT &&
879 (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))
885 /* step 3: make sure arguments are trivially compatible */
887 switch (cmd->start_src) {
889 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
891 & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
893 ~(CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
896 if (!thisboard->is_1602 && (cmd->start_arg & CR_INVERT)) {
897 cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
902 if (cmd->start_arg != 0) {
909 if (cmd->scan_begin_src == TRIG_TIMER) {
910 if (cmd->scan_begin_arg <
911 thisboard->ai_speed * cmd->chanlist_len) {
912 cmd->scan_begin_arg =
913 thisboard->ai_speed * cmd->chanlist_len;
917 if (cmd->convert_src == TRIG_TIMER) {
918 if (cmd->convert_arg < thisboard->ai_speed) {
919 cmd->convert_arg = thisboard->ai_speed;
924 if (cmd->scan_end_arg != cmd->chanlist_len) {
925 cmd->scan_end_arg = cmd->chanlist_len;
928 if (cmd->stop_src == TRIG_NONE) {
930 if (cmd->stop_arg != 0) {
939 /* step 4: fix up any arguments */
941 if (cmd->scan_begin_src == TRIG_TIMER) {
942 tmp = cmd->scan_begin_arg;
943 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
944 &(devpriv->divisor1),
945 &(devpriv->divisor2),
946 &(cmd->scan_begin_arg),
947 cmd->flags & TRIG_ROUND_MASK);
948 if (tmp != cmd->scan_begin_arg)
951 if (cmd->convert_src == TRIG_TIMER) {
952 tmp = cmd->convert_arg;
953 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
954 &(devpriv->divisor1),
955 &(devpriv->divisor2),
957 cmd->flags & TRIG_ROUND_MASK);
958 if (tmp != cmd->convert_arg)
965 /* check channel/gain list against card's limitations */
967 gain = CR_RANGE(cmd->chanlist[0]);
968 start_chan = CR_CHAN(cmd->chanlist[0]);
969 for (i = 1; i < cmd->chanlist_len; i++) {
970 if (CR_CHAN(cmd->chanlist[i]) !=
971 (start_chan + i) % s->n_chan) {
973 "entries in chanlist must be consecutive channels, counting upwards\n");
976 if (CR_RANGE(cmd->chanlist[i]) != gain) {
978 "entries in chanlist must all have the same gain\n");
990 static void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns,
993 struct cb_pcidas_private *devpriv = dev->private;
995 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
996 &(devpriv->divisor2), ns,
997 rounding_flags & TRIG_ROUND_MASK);
999 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1000 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1,
1001 devpriv->divisor1, 2);
1002 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2,
1003 devpriv->divisor2, 2);
1006 static int cb_pcidas_ai_cmd(struct comedi_device *dev,
1007 struct comedi_subdevice *s)
1009 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1010 struct cb_pcidas_private *devpriv = dev->private;
1011 struct comedi_async *async = s->async;
1012 struct comedi_cmd *cmd = &async->cmd;
1014 unsigned long flags;
1016 /* make sure CAL_EN_BIT is disabled */
1017 outw(0, devpriv->control_status + CALIBRATION_REG);
1018 /* initialize before settings pacer source and count values */
1019 outw(0, devpriv->control_status + TRIG_CONTSTAT);
1021 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
1023 /* set mux limits, gain and pacer source */
1024 bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
1025 END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
1026 GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
1027 /* set unipolar/bipolar */
1028 if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
1030 /* set singleended/differential */
1031 if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
1033 /* set pacer source */
1034 if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
1035 bits |= PACER_EXT_RISE;
1038 outw(bits, devpriv->control_status + ADCMUX_CONT);
1041 if (cmd->convert_src == TRIG_TIMER)
1042 cb_pcidas_load_counters(dev, &cmd->convert_arg,
1043 cmd->flags & TRIG_ROUND_MASK);
1044 else if (cmd->scan_begin_src == TRIG_TIMER)
1045 cb_pcidas_load_counters(dev, &cmd->scan_begin_arg,
1046 cmd->flags & TRIG_ROUND_MASK);
1048 /* set number of conversions */
1049 if (cmd->stop_src == TRIG_COUNT)
1050 devpriv->count = cmd->chanlist_len * cmd->stop_arg;
1051 /* enable interrupts */
1052 spin_lock_irqsave(&dev->spinlock, flags);
1053 devpriv->adc_fifo_bits |= INTE;
1054 devpriv->adc_fifo_bits &= ~INT_MASK;
1055 if (cmd->flags & TRIG_WAKE_EOS) {
1056 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1057 devpriv->adc_fifo_bits |= INT_EOS; /* interrupt end of burst */
1059 devpriv->adc_fifo_bits |= INT_FNE; /* interrupt fifo not empty */
1061 devpriv->adc_fifo_bits |= INT_FHF; /* interrupt fifo half full */
1064 /* enable (and clear) interrupts */
1065 outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
1066 devpriv->control_status + INT_ADCFIFO);
1067 spin_unlock_irqrestore(&dev->spinlock, flags);
1069 /* set start trigger and burst mode */
1071 if (cmd->start_src == TRIG_NOW)
1073 else if (cmd->start_src == TRIG_EXT) {
1074 bits |= EXT_TRIGGER | TGEN | XTRCL;
1075 if (thisboard->is_1602) {
1076 if (cmd->start_arg & CR_INVERT)
1078 if (cmd->start_arg & CR_EDGE)
1082 comedi_error(dev, "bug!");
1085 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1087 outw(bits, devpriv->control_status + TRIG_CONTSTAT);
1092 static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
1093 struct comedi_subdevice *s,
1094 struct comedi_cmd *cmd)
1096 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1097 struct cb_pcidas_private *devpriv = dev->private;
1101 /* cmdtest tests a particular command to see if it is valid.
1102 * Using the cmdtest ioctl, a user can create a valid cmd
1103 * and then have it executes by the cmd ioctl.
1105 * cmdtest returns 1,2,3,4 or 0, depending on which tests
1106 * the command passes. */
1108 /* step 1: make sure trigger sources are trivially valid */
1110 tmp = cmd->start_src;
1111 cmd->start_src &= TRIG_INT;
1112 if (!cmd->start_src || tmp != cmd->start_src)
1115 tmp = cmd->scan_begin_src;
1116 cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
1117 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1120 tmp = cmd->convert_src;
1121 cmd->convert_src &= TRIG_NOW;
1122 if (!cmd->convert_src || tmp != cmd->convert_src)
1125 tmp = cmd->scan_end_src;
1126 cmd->scan_end_src &= TRIG_COUNT;
1127 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1130 tmp = cmd->stop_src;
1131 cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1132 if (!cmd->stop_src || tmp != cmd->stop_src)
1138 /* step 2: make sure trigger sources are unique and mutually compatible */
1140 if (cmd->scan_begin_src != TRIG_TIMER &&
1141 cmd->scan_begin_src != TRIG_EXT)
1143 if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
1149 /* step 3: make sure arguments are trivially compatible */
1151 if (cmd->start_arg != 0) {
1156 if (cmd->scan_begin_src == TRIG_TIMER) {
1157 if (cmd->scan_begin_arg < thisboard->ao_scan_speed) {
1158 cmd->scan_begin_arg = thisboard->ao_scan_speed;
1163 if (cmd->scan_end_arg != cmd->chanlist_len) {
1164 cmd->scan_end_arg = cmd->chanlist_len;
1167 if (cmd->stop_src == TRIG_NONE) {
1169 if (cmd->stop_arg != 0) {
1178 /* step 4: fix up any arguments */
1180 if (cmd->scan_begin_src == TRIG_TIMER) {
1181 tmp = cmd->scan_begin_arg;
1182 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1183 &(devpriv->ao_divisor1),
1184 &(devpriv->ao_divisor2),
1185 &(cmd->scan_begin_arg),
1186 cmd->flags & TRIG_ROUND_MASK);
1187 if (tmp != cmd->scan_begin_arg)
1194 /* check channel/gain list against card's limitations */
1195 if (cmd->chanlist && cmd->chanlist_len > 1) {
1196 if (CR_CHAN(cmd->chanlist[0]) != 0 ||
1197 CR_CHAN(cmd->chanlist[1]) != 1) {
1199 "channels must be ordered channel 0, channel 1 in chanlist\n");
1210 /* cancel analog input command */
1211 static int cb_pcidas_cancel(struct comedi_device *dev,
1212 struct comedi_subdevice *s)
1214 struct cb_pcidas_private *devpriv = dev->private;
1215 unsigned long flags;
1217 spin_lock_irqsave(&dev->spinlock, flags);
1218 /* disable interrupts */
1219 devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
1220 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1221 spin_unlock_irqrestore(&dev->spinlock, flags);
1223 /* disable start trigger source and burst mode */
1224 outw(0, devpriv->control_status + TRIG_CONTSTAT);
1225 /* software pacer source */
1226 outw(0, devpriv->control_status + ADCMUX_CONT);
1231 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1232 struct comedi_subdevice *s,
1233 unsigned int trig_num)
1235 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1236 struct cb_pcidas_private *devpriv = dev->private;
1237 unsigned int num_bytes, num_points = thisboard->fifo_size;
1238 struct comedi_async *async = s->async;
1239 struct comedi_cmd *cmd = &s->async->cmd;
1240 unsigned long flags;
1246 if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
1247 num_points = devpriv->ao_count;
1249 num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1250 num_points * sizeof(short));
1251 num_points = num_bytes / sizeof(short);
1253 if (cmd->stop_src == TRIG_COUNT)
1254 devpriv->ao_count -= num_points;
1255 /* write data to board's fifo */
1256 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
1258 /* enable dac half-full and empty interrupts */
1259 spin_lock_irqsave(&dev->spinlock, flags);
1260 devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
1262 /* enable and clear interrupts */
1263 outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
1264 devpriv->control_status + INT_ADCFIFO);
1267 devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1268 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1270 spin_unlock_irqrestore(&dev->spinlock, flags);
1272 async->inttrig = NULL;
1277 static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1278 struct comedi_subdevice *s)
1280 struct cb_pcidas_private *devpriv = dev->private;
1281 struct comedi_async *async = s->async;
1282 struct comedi_cmd *cmd = &async->cmd;
1284 unsigned long flags;
1286 /* set channel limits, gain */
1287 spin_lock_irqsave(&dev->spinlock, flags);
1288 for (i = 0; i < cmd->chanlist_len; i++) {
1289 /* enable channel */
1290 devpriv->ao_control_bits |=
1291 DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
1293 devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
1298 /* disable analog out before settings pacer source and count values */
1299 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1300 spin_unlock_irqrestore(&dev->spinlock, flags);
1303 outw(0, devpriv->ao_registers + DACFIFOCLR);
1306 if (cmd->scan_begin_src == TRIG_TIMER) {
1307 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1308 &(devpriv->ao_divisor1),
1309 &(devpriv->ao_divisor2),
1310 &(cmd->scan_begin_arg),
1313 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1314 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1,
1315 devpriv->ao_divisor1, 2);
1316 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2,
1317 devpriv->ao_divisor2, 2);
1319 /* set number of conversions */
1320 if (cmd->stop_src == TRIG_COUNT)
1321 devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
1322 /* set pacer source */
1323 spin_lock_irqsave(&dev->spinlock, flags);
1324 switch (cmd->scan_begin_src) {
1326 devpriv->ao_control_bits |= DAC_PACER_INT;
1329 devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1332 spin_unlock_irqrestore(&dev->spinlock, flags);
1333 comedi_error(dev, "error setting dac pacer source");
1337 spin_unlock_irqrestore(&dev->spinlock, flags);
1339 async->inttrig = cb_pcidas_ao_inttrig;
1344 /* cancel analog output command */
1345 static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1346 struct comedi_subdevice *s)
1348 struct cb_pcidas_private *devpriv = dev->private;
1349 unsigned long flags;
1351 spin_lock_irqsave(&dev->spinlock, flags);
1352 /* disable interrupts */
1353 devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
1354 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1356 /* disable output */
1357 devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1358 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1359 spin_unlock_irqrestore(&dev->spinlock, flags);
1364 static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
1366 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1367 struct cb_pcidas_private *devpriv = dev->private;
1368 struct comedi_subdevice *s = dev->write_subdev;
1369 struct comedi_async *async = s->async;
1370 struct comedi_cmd *cmd = &async->cmd;
1371 unsigned int half_fifo = thisboard->fifo_size / 2;
1372 unsigned int num_points;
1373 unsigned long flags;
1377 if (status & DAEMI) {
1378 /* clear dac empty interrupt latch */
1379 spin_lock_irqsave(&dev->spinlock, flags);
1380 outw(devpriv->adc_fifo_bits | DAEMI,
1381 devpriv->control_status + INT_ADCFIFO);
1382 spin_unlock_irqrestore(&dev->spinlock, flags);
1383 if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
1384 if (cmd->stop_src == TRIG_NONE ||
1385 (cmd->stop_src == TRIG_COUNT
1386 && devpriv->ao_count)) {
1387 comedi_error(dev, "dac fifo underflow");
1388 cb_pcidas_ao_cancel(dev, s);
1389 async->events |= COMEDI_CB_ERROR;
1391 async->events |= COMEDI_CB_EOA;
1393 } else if (status & DAHFI) {
1394 unsigned int num_bytes;
1396 /* figure out how many points we are writing to fifo */
1397 num_points = half_fifo;
1398 if (cmd->stop_src == TRIG_COUNT &&
1399 devpriv->ao_count < num_points)
1400 num_points = devpriv->ao_count;
1402 cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1403 num_points * sizeof(short));
1404 num_points = num_bytes / sizeof(short);
1406 if (async->cmd.stop_src == TRIG_COUNT)
1407 devpriv->ao_count -= num_points;
1408 /* write data to board's fifo */
1409 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
1411 /* clear half-full interrupt latch */
1412 spin_lock_irqsave(&dev->spinlock, flags);
1413 outw(devpriv->adc_fifo_bits | DAHFI,
1414 devpriv->control_status + INT_ADCFIFO);
1415 spin_unlock_irqrestore(&dev->spinlock, flags);
1418 comedi_event(dev, s);
1421 static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1423 struct comedi_device *dev = (struct comedi_device *)d;
1424 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1425 struct cb_pcidas_private *devpriv = dev->private;
1426 struct comedi_subdevice *s = dev->read_subdev;
1427 struct comedi_async *async;
1428 int status, s5933_status;
1429 int half_fifo = thisboard->fifo_size / 2;
1430 unsigned int num_samples, i;
1431 static const int timeout = 10000;
1432 unsigned long flags;
1434 if (dev->attached == 0)
1440 s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1442 if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
1445 /* make sure mailbox 4 is empty */
1446 inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1447 /* clear interrupt on amcc s5933 */
1448 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1449 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1451 status = inw(devpriv->control_status + INT_ADCFIFO);
1453 /* check for analog output interrupt */
1454 if (status & (DAHFI | DAEMI))
1455 handle_ao_interrupt(dev, status);
1456 /* check for analog input interrupts */
1457 /* if fifo half-full */
1458 if (status & ADHFI) {
1460 num_samples = half_fifo;
1461 if (async->cmd.stop_src == TRIG_COUNT &&
1462 num_samples > devpriv->count) {
1463 num_samples = devpriv->count;
1465 insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
1467 cfc_write_array_to_buffer(s, devpriv->ai_buffer,
1468 num_samples * sizeof(short));
1469 devpriv->count -= num_samples;
1470 if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) {
1471 async->events |= COMEDI_CB_EOA;
1472 cb_pcidas_cancel(dev, s);
1474 /* clear half-full interrupt latch */
1475 spin_lock_irqsave(&dev->spinlock, flags);
1476 outw(devpriv->adc_fifo_bits | INT,
1477 devpriv->control_status + INT_ADCFIFO);
1478 spin_unlock_irqrestore(&dev->spinlock, flags);
1479 /* else if fifo not empty */
1480 } else if (status & (ADNEI | EOBI)) {
1481 for (i = 0; i < timeout; i++) {
1482 /* break if fifo is empty */
1483 if ((ADNE & inw(devpriv->control_status +
1486 cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
1487 if (async->cmd.stop_src == TRIG_COUNT && --devpriv->count == 0) { /* end of acquisition */
1488 cb_pcidas_cancel(dev, s);
1489 async->events |= COMEDI_CB_EOA;
1493 /* clear not-empty interrupt latch */
1494 spin_lock_irqsave(&dev->spinlock, flags);
1495 outw(devpriv->adc_fifo_bits | INT,
1496 devpriv->control_status + INT_ADCFIFO);
1497 spin_unlock_irqrestore(&dev->spinlock, flags);
1498 } else if (status & EOAI) {
1500 "bug! encountered end of acquisition interrupt?");
1501 /* clear EOA interrupt latch */
1502 spin_lock_irqsave(&dev->spinlock, flags);
1503 outw(devpriv->adc_fifo_bits | EOAI,
1504 devpriv->control_status + INT_ADCFIFO);
1505 spin_unlock_irqrestore(&dev->spinlock, flags);
1507 /* check for fifo overflow */
1508 if (status & LADFUL) {
1509 comedi_error(dev, "fifo overflow");
1510 /* clear overflow interrupt latch */
1511 spin_lock_irqsave(&dev->spinlock, flags);
1512 outw(devpriv->adc_fifo_bits | LADFUL,
1513 devpriv->control_status + INT_ADCFIFO);
1514 spin_unlock_irqrestore(&dev->spinlock, flags);
1515 cb_pcidas_cancel(dev, s);
1516 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1519 comedi_event(dev, s);
1524 static struct pci_dev *cb_pcidas_find_pci_device(struct comedi_device *dev,
1525 struct comedi_devconfig *it)
1527 const struct cb_pcidas_board *thisboard;
1528 struct pci_dev *pcidev = NULL;
1529 int bus = it->options[0];
1530 int slot = it->options[1];
1533 for_each_pci_dev(pcidev) {
1534 /* is it not a computer boards card? */
1535 if (pcidev->vendor != PCI_VENDOR_ID_CB)
1537 /* loop through cards supported by this driver */
1538 for (i = 0; i < ARRAY_SIZE(cb_pcidas_boards); i++) {
1539 thisboard = &cb_pcidas_boards[i];
1540 if (thisboard->device_id != pcidev->device)
1542 /* was a particular bus/slot requested? */
1544 /* are we on the wrong bus/slot? */
1545 if (pcidev->bus->number != bus ||
1546 PCI_SLOT(pcidev->devfn) != slot) {
1550 dev->board_ptr = thisboard;
1557 static int cb_pcidas_attach(struct comedi_device *dev,
1558 struct comedi_devconfig *it)
1560 const struct cb_pcidas_board *thisboard;
1561 struct cb_pcidas_private *devpriv;
1562 struct comedi_subdevice *s;
1566 if (alloc_private(dev, sizeof(struct cb_pcidas_private)) < 0)
1568 devpriv = dev->private;
1570 devpriv->pci_dev = cb_pcidas_find_pci_device(dev, it);
1571 if (!devpriv->pci_dev) {
1572 dev_err(dev->class_dev, "No supported card found\n");
1576 thisboard = comedi_board(dev);
1577 dev_dbg(dev->class_dev, "Found %s on bus %i, slot %i\n",
1578 thisboard->name, devpriv->pci_dev->bus->number,
1579 PCI_SLOT(devpriv->pci_dev->devfn));
1581 if (comedi_pci_enable(devpriv->pci_dev, "cb_pcidas")) {
1582 dev_err(dev->class_dev,
1583 "Failed to enable PCI device and request regions\n");
1587 devpriv->s5933_config = pci_resource_start(devpriv->pci_dev, 0);
1588 devpriv->control_status = pci_resource_start(devpriv->pci_dev, 1);
1589 devpriv->adc_fifo = pci_resource_start(devpriv->pci_dev, 2);
1590 devpriv->pacer_counter_dio = pci_resource_start(devpriv->pci_dev, 3);
1591 if (thisboard->ao_nchan)
1592 devpriv->ao_registers = pci_resource_start(devpriv->pci_dev, 4);
1594 /* disable and clear interrupts on amcc s5933 */
1595 outl(INTCSR_INBOX_INTR_STATUS,
1596 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1598 if (request_irq(devpriv->pci_dev->irq, cb_pcidas_interrupt,
1599 IRQF_SHARED, "cb_pcidas", dev)) {
1600 dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
1601 devpriv->pci_dev->irq);
1604 dev->irq = devpriv->pci_dev->irq;
1606 dev->board_name = thisboard->name;
1608 ret = comedi_alloc_subdevices(dev, 7);
1612 s = dev->subdevices + 0;
1613 /* analog input subdevice */
1614 dev->read_subdev = s;
1615 s->type = COMEDI_SUBD_AI;
1616 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
1617 /* WARNING: Number of inputs in differential mode is ignored */
1618 s->n_chan = thisboard->ai_se_chans;
1619 s->len_chanlist = thisboard->ai_se_chans;
1620 s->maxdata = (1 << thisboard->ai_bits) - 1;
1621 s->range_table = thisboard->ranges;
1622 s->insn_read = cb_pcidas_ai_rinsn;
1623 s->insn_config = ai_config_insn;
1624 s->do_cmd = cb_pcidas_ai_cmd;
1625 s->do_cmdtest = cb_pcidas_ai_cmdtest;
1626 s->cancel = cb_pcidas_cancel;
1628 /* analog output subdevice */
1629 s = dev->subdevices + 1;
1630 if (thisboard->ao_nchan) {
1631 s->type = COMEDI_SUBD_AO;
1632 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1633 s->n_chan = thisboard->ao_nchan;
1634 /* analog out resolution is the same as analog input resolution, so use ai_bits */
1635 s->maxdata = (1 << thisboard->ai_bits) - 1;
1636 s->range_table = &cb_pcidas_ao_ranges;
1637 s->insn_read = cb_pcidas_ao_readback_insn;
1638 if (thisboard->has_ao_fifo) {
1639 dev->write_subdev = s;
1640 s->subdev_flags |= SDF_CMD_WRITE;
1641 s->insn_write = cb_pcidas_ao_fifo_winsn;
1642 s->do_cmdtest = cb_pcidas_ao_cmdtest;
1643 s->do_cmd = cb_pcidas_ao_cmd;
1644 s->cancel = cb_pcidas_ao_cancel;
1646 s->insn_write = cb_pcidas_ao_nofifo_winsn;
1649 s->type = COMEDI_SUBD_UNUSED;
1653 s = dev->subdevices + 2;
1654 subdev_8255_init(dev, s, NULL, devpriv->pacer_counter_dio + DIO_8255);
1656 /* serial EEPROM, */
1657 s = dev->subdevices + 3;
1658 s->type = COMEDI_SUBD_MEMORY;
1659 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
1662 s->insn_read = eeprom_read_insn;
1665 s = dev->subdevices + 4;
1666 s->type = COMEDI_SUBD_CALIB;
1667 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1668 s->n_chan = NUM_CHANNELS_8800;
1670 s->insn_read = caldac_read_insn;
1671 s->insn_write = caldac_write_insn;
1672 for (i = 0; i < s->n_chan; i++)
1673 caldac_8800_write(dev, i, s->maxdata / 2);
1675 /* trim potentiometer */
1676 s = dev->subdevices + 5;
1677 s->type = COMEDI_SUBD_CALIB;
1678 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1679 if (thisboard->trimpot == AD7376) {
1680 s->n_chan = NUM_CHANNELS_7376;
1683 s->n_chan = NUM_CHANNELS_8402;
1686 s->insn_read = trimpot_read_insn;
1687 s->insn_write = trimpot_write_insn;
1688 for (i = 0; i < s->n_chan; i++)
1689 cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
1692 s = dev->subdevices + 6;
1693 if (thisboard->has_dac08) {
1694 s->type = COMEDI_SUBD_CALIB;
1695 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1696 s->n_chan = NUM_CHANNELS_DAC08;
1697 s->insn_read = dac08_read_insn;
1698 s->insn_write = dac08_write_insn;
1700 dac08_write(dev, s->maxdata / 2);
1702 s->type = COMEDI_SUBD_UNUSED;
1704 /* make sure mailbox 4 is empty */
1705 inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1706 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1707 devpriv->s5933_intcsr_bits =
1708 INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1709 INTCSR_INBOX_FULL_INT;
1710 /* clear and enable interrupt on amcc s5933 */
1711 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1712 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1717 static void cb_pcidas_detach(struct comedi_device *dev)
1719 struct cb_pcidas_private *devpriv = dev->private;
1722 if (devpriv->s5933_config) {
1723 outl(INTCSR_INBOX_INTR_STATUS,
1724 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1728 free_irq(dev->irq, dev);
1729 if (dev->subdevices)
1730 subdev_8255_cleanup(dev, dev->subdevices + 2);
1731 if (devpriv && devpriv->pci_dev) {
1732 if (devpriv->s5933_config)
1733 comedi_pci_disable(devpriv->pci_dev);
1734 pci_dev_put(devpriv->pci_dev);
1738 static struct comedi_driver cb_pcidas_driver = {
1739 .driver_name = "cb_pcidas",
1740 .module = THIS_MODULE,
1741 .attach = cb_pcidas_attach,
1742 .detach = cb_pcidas_detach,
1745 static int __devinit cb_pcidas_pci_probe(struct pci_dev *dev,
1746 const struct pci_device_id *ent)
1748 return comedi_pci_auto_config(dev, &cb_pcidas_driver);
1751 static void __devexit cb_pcidas_pci_remove(struct pci_dev *dev)
1753 comedi_pci_auto_unconfig(dev);
1756 static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = {
1757 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0001) },
1758 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000f) },
1759 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0010) },
1760 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0019) },
1761 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001c) },
1762 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x004c) },
1763 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001a) },
1764 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001b) },
1767 MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
1769 static struct pci_driver cb_pcidas_pci_driver = {
1770 .name = "cb_pcidas",
1771 .id_table = cb_pcidas_pci_table,
1772 .probe = cb_pcidas_pci_probe,
1773 .remove = __devexit_p(cb_pcidas_pci_remove)
1775 module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver);
1777 MODULE_AUTHOR("Comedi http://www.comedi.org");
1778 MODULE_DESCRIPTION("Comedi low-level driver");
1779 MODULE_LICENSE("GPL");