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:
49 [0] - PCI bus of device (optional)
50 [1] - PCI slot of device (optional)
51 If bus/slot is not specified, the first supported
52 PCI device found will be used.
54 For commands, the scanned channels must be consecutive
55 (i.e. 4-5-6-7, 2-3-4,...), and must all have the same
59 For start_src == TRIG_EXT, the A/D EXTERNAL TRIGGER IN (pin 45) is used.
60 For 1602 series, the start_arg is interpreted as follows:
61 start_arg == 0 => gated trigger (level high)
62 start_arg == CR_INVERT => gated trigger (level low)
63 start_arg == CR_EDGE => Rising edge
64 start_arg == CR_EDGE | CR_INVERT => Falling edge
65 For the other boards the trigger will be done on rising edge
71 analog triggering on 1602 series
74 #include "../comedidev.h"
75 #include <linux/delay.h>
76 #include <linux/interrupt.h>
80 #include "amcc_s5933.h"
81 #include "comedi_fc.h"
83 /* PCI vendor number of ComputerBoards/MeasurementComputing */
84 #define PCI_VENDOR_ID_CB 0x1307
86 #define TIMER_BASE 100 /* 10MHz master clock */
87 #define AI_BUFFER_SIZE 1024 /* max ai fifo size */
88 #define AO_BUFFER_SIZE 1024 /* max ao fifo size */
89 #define NUM_CHANNELS_8800 8
90 #define NUM_CHANNELS_7376 1
91 #define NUM_CHANNELS_8402 2
92 #define NUM_CHANNELS_DAC08 1
94 /* Control/Status registers */
95 #define INT_ADCFIFO 0 /* INTERRUPT / ADC FIFO register */
96 #define INT_EOS 0x1 /* int end of scan */
97 #define INT_FHF 0x2 /* int fifo half full */
98 #define INT_FNE 0x3 /* int fifo not empty */
99 #define INT_MASK 0x3 /* mask of int select bits */
100 #define INTE 0x4 /* int enable */
101 #define DAHFIE 0x8 /* dac half full int enable */
102 #define EOAIE 0x10 /* end of acq. int enable */
103 #define DAHFI 0x20 /* dac half full status / clear */
104 #define EOAI 0x40 /* end of acq. int status / clear */
105 #define INT 0x80 /* int status / clear */
106 #define EOBI 0x200 /* end of burst int status */
107 #define ADHFI 0x400 /* half-full int status */
108 #define ADNEI 0x800 /* fifo not empty int status (latch) */
109 #define ADNE 0x1000 /* fifo not empty status (realtime) */
110 #define DAEMIE 0x1000 /* dac empty int enable */
111 #define LADFUL 0x2000 /* fifo overflow / clear */
112 #define DAEMI 0x4000 /* dac fifo empty int status / clear */
114 #define ADCMUX_CONT 2 /* ADC CHANNEL MUX AND CONTROL reg */
115 #define BEGIN_SCAN(x) ((x) & 0xf)
116 #define END_SCAN(x) (((x) & 0xf) << 4)
117 #define GAIN_BITS(x) (((x) & 0x3) << 8)
118 #define UNIP 0x800 /* Analog front-end unipolar mode */
119 #define SE 0x400 /* Inputs in single-ended mode */
120 #define PACER_MASK 0x3000 /* pacer source bits */
121 #define PACER_INT 0x1000 /* int. pacer */
122 #define PACER_EXT_FALL 0x2000 /* ext. falling edge */
123 #define PACER_EXT_RISE 0x3000 /* ext. rising edge */
124 #define EOC 0x4000 /* adc not busy */
126 #define TRIG_CONTSTAT 4 /* TRIGGER CONTROL/STATUS register */
127 #define SW_TRIGGER 0x1 /* software start trigger */
128 #define EXT_TRIGGER 0x2 /* ext. start trigger */
129 #define ANALOG_TRIGGER 0x3 /* ext. analog trigger */
130 #define TRIGGER_MASK 0x3 /* start trigger mask */
131 #define TGPOL 0x04 /* invert trigger (1602 only) */
132 #define TGSEL 0x08 /* edge/level trigerred (1602 only) */
133 #define TGEN 0x10 /* enable external start trigger */
134 #define BURSTE 0x20 /* burst mode enable */
135 #define XTRCL 0x80 /* clear external trigger */
137 #define CALIBRATION_REG 6 /* CALIBRATION register */
138 #define SELECT_8800_BIT 0x100 /* select 8800 caldac */
139 #define SELECT_TRIMPOT_BIT 0x200 /* select ad7376 trim pot */
140 #define SELECT_DAC08_BIT 0x400 /* select dac08 caldac */
141 #define CAL_SRC_BITS(x) (((x) & 0x7) << 11)
142 #define CAL_EN_BIT 0x4000 /* calibration source enable */
143 #define SERIAL_DATA_IN_BIT 0x8000 /* serial data bit going to caldac */
145 #define DAC_CSR 0x8 /* dac control and status register */
146 #define DACEN 0x02 /* dac enable */
147 #define DAC_MODE_UPDATE_BOTH 0x80 /* update both dacs */
149 static inline unsigned int DAC_RANGE(unsigned int channel, unsigned int range)
151 return (range & 0x3) << (8 + 2 * (channel & 0x1));
154 static inline unsigned int DAC_RANGE_MASK(unsigned int channel)
156 return 0x3 << (8 + 2 * (channel & 0x1));
159 /* bits for 1602 series only */
160 #define DAC_EMPTY 0x1 /* fifo empty, read, write clear */
161 #define DAC_START 0x4 /* start/arm fifo operations */
162 #define DAC_PACER_MASK 0x18 /* bits that set pacer source */
163 #define DAC_PACER_INT 0x8 /* int. pacing */
164 #define DAC_PACER_EXT_FALL 0x10 /* ext. pacing, falling edge */
165 #define DAC_PACER_EXT_RISE 0x18 /* ext. 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 #define IS_UNIPOLAR 0x4 /* unipolar range mask */
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_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[] = {
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 struct cb_pcidas_private {
347 unsigned long s5933_config;
348 unsigned long control_status;
349 unsigned long adc_fifo;
350 unsigned long pacer_counter_dio;
351 unsigned long ao_registers;
352 /* divisors of master clock for analog input pacing */
353 unsigned int divisor1;
354 unsigned int divisor2;
355 /* number of analog input samples remaining */
357 /* bits to write to registers */
358 unsigned int adc_fifo_bits;
359 unsigned int s5933_intcsr_bits;
360 unsigned int ao_control_bits;
362 short ai_buffer[AI_BUFFER_SIZE];
363 short ao_buffer[AO_BUFFER_SIZE];
364 /* divisors of master clock for analog output pacing */
365 unsigned int ao_divisor1;
366 unsigned int ao_divisor2;
367 /* number of analog output samples remaining */
368 unsigned int ao_count;
369 /* cached values for readback */
371 unsigned int caldac_value[NUM_CHANNELS_8800];
372 unsigned int trimpot_value[NUM_CHANNELS_8402];
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);
384 static int cb_pcidas_ai_rinsn(struct comedi_device *dev,
385 struct comedi_subdevice *s,
386 struct comedi_insn *insn, unsigned int *data)
388 struct cb_pcidas_private *devpriv = dev->private;
389 unsigned int chan = CR_CHAN(insn->chanspec);
390 unsigned int range = CR_RANGE(insn->chanspec);
391 unsigned int aref = CR_AREF(insn->chanspec);
395 /* enable calibration input if appropriate */
396 if (insn->chanspec & CR_ALT_SOURCE) {
397 outw(cal_enable_bits(dev),
398 devpriv->control_status + CALIBRATION_REG);
401 outw(0, devpriv->control_status + CALIBRATION_REG);
404 /* set mux limits and gain */
405 bits = BEGIN_SCAN(chan) | END_SCAN(chan) | GAIN_BITS(range);
406 /* set unipolar/bipolar */
407 if (range & IS_UNIPOLAR)
409 /* set single-ended/differential */
410 if (aref != AREF_DIFF)
412 outw(bits, devpriv->control_status + ADCMUX_CONT);
415 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
417 /* convert n samples */
418 for (n = 0; n < insn->n; n++) {
419 /* trigger conversion */
420 outw(0, devpriv->adc_fifo + ADCDATA);
422 /* wait for conversion to end */
423 /* return -ETIMEDOUT if there is a timeout */
424 for (i = 0; i < 10000; i++) {
425 if (inw(devpriv->control_status + ADCMUX_CONT) & EOC)
432 data[n] = inw(devpriv->adc_fifo + ADCDATA);
435 /* return the number of samples read/written */
439 static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
440 struct comedi_insn *insn, unsigned int *data)
442 struct cb_pcidas_private *devpriv = dev->private;
444 unsigned int source = data[1];
447 case INSN_CONFIG_ALT_SOURCE:
449 dev_err(dev->class_dev,
450 "invalid calibration source: %i\n",
454 devpriv->calibration_source = source;
463 /* analog output insn for pcidas-1000 and 1200 series */
464 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev,
465 struct comedi_subdevice *s,
466 struct comedi_insn *insn,
469 struct cb_pcidas_private *devpriv = dev->private;
470 unsigned int chan = CR_CHAN(insn->chanspec);
471 unsigned int range = CR_RANGE(insn->chanspec);
474 /* set channel and range */
475 spin_lock_irqsave(&dev->spinlock, flags);
476 devpriv->ao_control_bits &= (~DAC_MODE_UPDATE_BOTH &
477 ~DAC_RANGE_MASK(chan));
478 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range));
479 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
480 spin_unlock_irqrestore(&dev->spinlock, flags);
482 /* remember value for readback */
483 devpriv->ao_value[chan] = data[0];
486 outw(data[0], devpriv->ao_registers + DAC_DATA_REG(chan));
491 /* analog output insn for pcidas-1602 series */
492 static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev,
493 struct comedi_subdevice *s,
494 struct comedi_insn *insn, unsigned int *data)
496 struct cb_pcidas_private *devpriv = dev->private;
497 unsigned int chan = CR_CHAN(insn->chanspec);
498 unsigned int range = CR_RANGE(insn->chanspec);
502 outw(0, devpriv->ao_registers + DACFIFOCLR);
504 /* set channel and range */
505 spin_lock_irqsave(&dev->spinlock, flags);
506 devpriv->ao_control_bits &= (~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) &
507 ~DAC_RANGE_MASK(chan) & ~DAC_PACER_MASK);
508 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range) |
509 DAC_CHAN_EN(chan) | DAC_START);
510 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
511 spin_unlock_irqrestore(&dev->spinlock, flags);
513 /* remember value for readback */
514 devpriv->ao_value[chan] = data[0];
517 outw(data[0], devpriv->ao_registers + DACDATA);
522 static int cb_pcidas_ao_readback_insn(struct comedi_device *dev,
523 struct comedi_subdevice *s,
524 struct comedi_insn *insn,
527 struct cb_pcidas_private *devpriv = dev->private;
529 data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
534 static int wait_for_nvram_ready(unsigned long s5933_base_addr)
536 static const int timeout = 1000;
539 for (i = 0; i < timeout; i++) {
540 if ((inb(s5933_base_addr +
541 AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
549 static int nvram_read(struct comedi_device *dev, unsigned int address,
552 struct cb_pcidas_private *devpriv = dev->private;
553 unsigned long iobase = devpriv->s5933_config;
555 if (wait_for_nvram_ready(iobase) < 0)
558 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
559 iobase + AMCC_OP_REG_MCSR_NVCMD);
560 outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
561 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
562 iobase + AMCC_OP_REG_MCSR_NVCMD);
563 outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
564 outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
566 if (wait_for_nvram_ready(iobase) < 0)
569 *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
574 static int eeprom_read_insn(struct comedi_device *dev,
575 struct comedi_subdevice *s,
576 struct comedi_insn *insn, unsigned int *data)
581 retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
585 data[0] = nvram_data;
590 static void write_calibration_bitstream(struct comedi_device *dev,
591 unsigned int register_bits,
592 unsigned int bitstream,
593 unsigned int bitstream_length)
595 struct cb_pcidas_private *devpriv = dev->private;
596 static const int write_delay = 1;
599 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
601 register_bits |= SERIAL_DATA_IN_BIT;
603 register_bits &= ~SERIAL_DATA_IN_BIT;
605 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
609 static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
612 struct cb_pcidas_private *devpriv = dev->private;
613 static const int num_caldac_channels = 8;
614 static const int bitstream_length = 11;
615 unsigned int bitstream = ((address & 0x7) << 8) | value;
616 static const int caldac_8800_udelay = 1;
618 if (address >= num_caldac_channels) {
619 comedi_error(dev, "illegal caldac channel");
623 if (value == devpriv->caldac_value[address])
626 devpriv->caldac_value[address] = value;
628 write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
631 udelay(caldac_8800_udelay);
632 outw(cal_enable_bits(dev) | SELECT_8800_BIT,
633 devpriv->control_status + CALIBRATION_REG);
634 udelay(caldac_8800_udelay);
635 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
640 static int caldac_write_insn(struct comedi_device *dev,
641 struct comedi_subdevice *s,
642 struct comedi_insn *insn, unsigned int *data)
644 const unsigned int channel = CR_CHAN(insn->chanspec);
646 return caldac_8800_write(dev, channel, data[0]);
649 static int caldac_read_insn(struct comedi_device *dev,
650 struct comedi_subdevice *s,
651 struct comedi_insn *insn, unsigned int *data)
653 struct cb_pcidas_private *devpriv = dev->private;
655 data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)];
660 /* 1602/16 pregain offset */
661 static void dac08_write(struct comedi_device *dev, unsigned int value)
663 struct cb_pcidas_private *devpriv = dev->private;
664 unsigned long cal_reg;
666 if (devpriv->dac08_value != value) {
667 devpriv->dac08_value = value;
669 cal_reg = devpriv->control_status + CALIBRATION_REG;
672 value |= cal_enable_bits(dev);
674 /* latch the new value into the caldac */
675 outw(value, cal_reg);
677 outw(value | SELECT_DAC08_BIT, cal_reg);
679 outw(value, cal_reg);
684 static int dac08_write_insn(struct comedi_device *dev,
685 struct comedi_subdevice *s,
686 struct comedi_insn *insn, unsigned int *data)
690 for (i = 0; i < insn->n; i++)
691 dac08_write(dev, data[i]);
696 static int dac08_read_insn(struct comedi_device *dev,
697 struct comedi_subdevice *s, struct comedi_insn *insn,
700 struct cb_pcidas_private *devpriv = dev->private;
702 data[0] = devpriv->dac08_value;
707 static int trimpot_7376_write(struct comedi_device *dev, uint8_t value)
709 struct cb_pcidas_private *devpriv = dev->private;
710 static const int bitstream_length = 7;
711 unsigned int bitstream = value & 0x7f;
712 unsigned int register_bits;
713 static const int ad7376_udelay = 1;
715 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
716 udelay(ad7376_udelay);
717 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
719 write_calibration_bitstream(dev, register_bits, bitstream,
722 udelay(ad7376_udelay);
723 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
730 * ch 1 : adc postgain offset */
731 static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
734 struct cb_pcidas_private *devpriv = dev->private;
735 static const int bitstream_length = 10;
736 unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
737 unsigned int register_bits;
738 static const int ad8402_udelay = 1;
740 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
741 udelay(ad8402_udelay);
742 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
744 write_calibration_bitstream(dev, register_bits, bitstream,
747 udelay(ad8402_udelay);
748 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
753 static int cb_pcidas_trimpot_write(struct comedi_device *dev,
754 unsigned int channel, unsigned int value)
756 const struct cb_pcidas_board *thisboard = comedi_board(dev);
757 struct cb_pcidas_private *devpriv = dev->private;
759 if (devpriv->trimpot_value[channel] == value)
762 devpriv->trimpot_value[channel] = value;
763 switch (thisboard->trimpot) {
765 trimpot_7376_write(dev, value);
768 trimpot_8402_write(dev, channel, value);
771 comedi_error(dev, "driver bug?");
779 static int trimpot_write_insn(struct comedi_device *dev,
780 struct comedi_subdevice *s,
781 struct comedi_insn *insn, unsigned int *data)
783 unsigned int channel = CR_CHAN(insn->chanspec);
785 return cb_pcidas_trimpot_write(dev, channel, data[0]);
788 static int trimpot_read_insn(struct comedi_device *dev,
789 struct comedi_subdevice *s,
790 struct comedi_insn *insn, unsigned int *data)
792 struct cb_pcidas_private *devpriv = dev->private;
793 unsigned int channel = CR_CHAN(insn->chanspec);
795 data[0] = devpriv->trimpot_value[channel];
800 static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
801 struct comedi_subdevice *s,
802 struct comedi_cmd *cmd)
804 const struct cb_pcidas_board *thisboard = comedi_board(dev);
805 struct cb_pcidas_private *devpriv = dev->private;
808 int i, gain, start_chan;
810 /* step 1: trigger sources are trivially valid */
812 tmp = cmd->start_src;
813 cmd->start_src &= TRIG_NOW | TRIG_EXT;
814 if (!cmd->start_src || tmp != cmd->start_src)
817 tmp = cmd->scan_begin_src;
818 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
819 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
822 tmp = cmd->convert_src;
823 cmd->convert_src &= TRIG_TIMER | TRIG_NOW | TRIG_EXT;
824 if (!cmd->convert_src || tmp != cmd->convert_src)
827 tmp = cmd->scan_end_src;
828 cmd->scan_end_src &= TRIG_COUNT;
829 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
833 cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
834 if (!cmd->stop_src || tmp != cmd->stop_src)
840 /* step 2: trigger sources are unique and mutually compatible */
842 if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
844 if (cmd->scan_begin_src != TRIG_FOLLOW &&
845 cmd->scan_begin_src != TRIG_TIMER &&
846 cmd->scan_begin_src != TRIG_EXT)
848 if (cmd->convert_src != TRIG_TIMER &&
849 cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
851 if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
854 /* make sure trigger sources are compatible with each other */
855 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
857 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
859 if (cmd->start_src == TRIG_EXT &&
860 (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))
866 /* step 3: arguments are trivially compatible */
868 switch (cmd->start_src) {
870 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
872 & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
874 ~(CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
877 if (!thisboard->is_1602 && (cmd->start_arg & CR_INVERT)) {
878 cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
883 if (cmd->start_arg != 0) {
890 if (cmd->scan_begin_src == TRIG_TIMER) {
891 if (cmd->scan_begin_arg <
892 thisboard->ai_speed * cmd->chanlist_len) {
893 cmd->scan_begin_arg =
894 thisboard->ai_speed * cmd->chanlist_len;
898 if (cmd->convert_src == TRIG_TIMER) {
899 if (cmd->convert_arg < thisboard->ai_speed) {
900 cmd->convert_arg = thisboard->ai_speed;
905 if (cmd->scan_end_arg != cmd->chanlist_len) {
906 cmd->scan_end_arg = cmd->chanlist_len;
909 if (cmd->stop_src == TRIG_NONE) {
911 if (cmd->stop_arg != 0) {
920 /* step 4: fix up any arguments */
922 if (cmd->scan_begin_src == TRIG_TIMER) {
923 tmp = cmd->scan_begin_arg;
924 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
925 &(devpriv->divisor1),
926 &(devpriv->divisor2),
927 &(cmd->scan_begin_arg),
928 cmd->flags & TRIG_ROUND_MASK);
929 if (tmp != cmd->scan_begin_arg)
932 if (cmd->convert_src == TRIG_TIMER) {
933 tmp = cmd->convert_arg;
934 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
935 &(devpriv->divisor1),
936 &(devpriv->divisor2),
938 cmd->flags & TRIG_ROUND_MASK);
939 if (tmp != cmd->convert_arg)
946 /* check channel/gain list against card's limitations */
948 gain = CR_RANGE(cmd->chanlist[0]);
949 start_chan = CR_CHAN(cmd->chanlist[0]);
950 for (i = 1; i < cmd->chanlist_len; i++) {
951 if (CR_CHAN(cmd->chanlist[i]) !=
952 (start_chan + i) % s->n_chan) {
954 "entries in chanlist must be consecutive channels, counting upwards\n");
957 if (CR_RANGE(cmd->chanlist[i]) != gain) {
959 "entries in chanlist must all have the same gain\n");
971 static void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns,
974 struct cb_pcidas_private *devpriv = dev->private;
976 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
977 &(devpriv->divisor2), ns,
978 rounding_flags & TRIG_ROUND_MASK);
980 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
981 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1,
982 devpriv->divisor1, 2);
983 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2,
984 devpriv->divisor2, 2);
987 static int cb_pcidas_ai_cmd(struct comedi_device *dev,
988 struct comedi_subdevice *s)
990 const struct cb_pcidas_board *thisboard = comedi_board(dev);
991 struct cb_pcidas_private *devpriv = dev->private;
992 struct comedi_async *async = s->async;
993 struct comedi_cmd *cmd = &async->cmd;
997 /* make sure CAL_EN_BIT is disabled */
998 outw(0, devpriv->control_status + CALIBRATION_REG);
999 /* initialize before settings pacer source and count values */
1000 outw(0, devpriv->control_status + TRIG_CONTSTAT);
1002 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
1004 /* set mux limits, gain and pacer source */
1005 bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
1006 END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
1007 GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
1008 /* set unipolar/bipolar */
1009 if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
1011 /* set singleended/differential */
1012 if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
1014 /* set pacer source */
1015 if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
1016 bits |= PACER_EXT_RISE;
1019 outw(bits, devpriv->control_status + ADCMUX_CONT);
1022 if (cmd->convert_src == TRIG_TIMER)
1023 cb_pcidas_load_counters(dev, &cmd->convert_arg,
1024 cmd->flags & TRIG_ROUND_MASK);
1025 else if (cmd->scan_begin_src == TRIG_TIMER)
1026 cb_pcidas_load_counters(dev, &cmd->scan_begin_arg,
1027 cmd->flags & TRIG_ROUND_MASK);
1029 /* set number of conversions */
1030 if (cmd->stop_src == TRIG_COUNT)
1031 devpriv->count = cmd->chanlist_len * cmd->stop_arg;
1032 /* enable interrupts */
1033 spin_lock_irqsave(&dev->spinlock, flags);
1034 devpriv->adc_fifo_bits |= INTE;
1035 devpriv->adc_fifo_bits &= ~INT_MASK;
1036 if (cmd->flags & TRIG_WAKE_EOS) {
1037 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) {
1038 /* interrupt end of burst */
1039 devpriv->adc_fifo_bits |= INT_EOS;
1041 /* interrupt fifo not empty */
1042 devpriv->adc_fifo_bits |= INT_FNE;
1045 /* interrupt fifo half full */
1046 devpriv->adc_fifo_bits |= INT_FHF;
1049 /* enable (and clear) interrupts */
1050 outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
1051 devpriv->control_status + INT_ADCFIFO);
1052 spin_unlock_irqrestore(&dev->spinlock, flags);
1054 /* set start trigger and burst mode */
1056 if (cmd->start_src == TRIG_NOW)
1058 else if (cmd->start_src == TRIG_EXT) {
1059 bits |= EXT_TRIGGER | TGEN | XTRCL;
1060 if (thisboard->is_1602) {
1061 if (cmd->start_arg & CR_INVERT)
1063 if (cmd->start_arg & CR_EDGE)
1067 comedi_error(dev, "bug!");
1070 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1072 outw(bits, devpriv->control_status + TRIG_CONTSTAT);
1077 static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
1078 struct comedi_subdevice *s,
1079 struct comedi_cmd *cmd)
1081 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1082 struct cb_pcidas_private *devpriv = dev->private;
1086 /* step 1: trigger sources are trivially valid */
1088 tmp = cmd->start_src;
1089 cmd->start_src &= TRIG_INT;
1090 if (!cmd->start_src || tmp != cmd->start_src)
1093 tmp = cmd->scan_begin_src;
1094 cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
1095 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1098 tmp = cmd->convert_src;
1099 cmd->convert_src &= TRIG_NOW;
1100 if (!cmd->convert_src || tmp != cmd->convert_src)
1103 tmp = cmd->scan_end_src;
1104 cmd->scan_end_src &= TRIG_COUNT;
1105 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1108 tmp = cmd->stop_src;
1109 cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1110 if (!cmd->stop_src || tmp != cmd->stop_src)
1116 /* step 2: trigger sources are unique and mutually compatible */
1118 if (cmd->scan_begin_src != TRIG_TIMER &&
1119 cmd->scan_begin_src != TRIG_EXT)
1121 if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
1127 /* step 3: arguments are trivially compatible */
1129 if (cmd->start_arg != 0) {
1134 if (cmd->scan_begin_src == TRIG_TIMER) {
1135 if (cmd->scan_begin_arg < thisboard->ao_scan_speed) {
1136 cmd->scan_begin_arg = thisboard->ao_scan_speed;
1141 if (cmd->scan_end_arg != cmd->chanlist_len) {
1142 cmd->scan_end_arg = cmd->chanlist_len;
1145 if (cmd->stop_src == TRIG_NONE) {
1147 if (cmd->stop_arg != 0) {
1156 /* step 4: fix up any arguments */
1158 if (cmd->scan_begin_src == TRIG_TIMER) {
1159 tmp = cmd->scan_begin_arg;
1160 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1161 &(devpriv->ao_divisor1),
1162 &(devpriv->ao_divisor2),
1163 &(cmd->scan_begin_arg),
1164 cmd->flags & TRIG_ROUND_MASK);
1165 if (tmp != cmd->scan_begin_arg)
1172 /* check channel/gain list against card's limitations */
1173 if (cmd->chanlist && cmd->chanlist_len > 1) {
1174 if (CR_CHAN(cmd->chanlist[0]) != 0 ||
1175 CR_CHAN(cmd->chanlist[1]) != 1) {
1177 "channels must be ordered channel 0, channel 1 in chanlist\n");
1188 /* cancel analog input command */
1189 static int cb_pcidas_cancel(struct comedi_device *dev,
1190 struct comedi_subdevice *s)
1192 struct cb_pcidas_private *devpriv = dev->private;
1193 unsigned long flags;
1195 spin_lock_irqsave(&dev->spinlock, flags);
1196 /* disable interrupts */
1197 devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
1198 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1199 spin_unlock_irqrestore(&dev->spinlock, flags);
1201 /* disable start trigger source and burst mode */
1202 outw(0, devpriv->control_status + TRIG_CONTSTAT);
1203 /* software pacer source */
1204 outw(0, devpriv->control_status + ADCMUX_CONT);
1209 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1210 struct comedi_subdevice *s,
1211 unsigned int trig_num)
1213 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1214 struct cb_pcidas_private *devpriv = dev->private;
1215 unsigned int num_bytes, num_points = thisboard->fifo_size;
1216 struct comedi_async *async = s->async;
1217 struct comedi_cmd *cmd = &s->async->cmd;
1218 unsigned long flags;
1224 if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
1225 num_points = devpriv->ao_count;
1227 num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1228 num_points * sizeof(short));
1229 num_points = num_bytes / sizeof(short);
1231 if (cmd->stop_src == TRIG_COUNT)
1232 devpriv->ao_count -= num_points;
1233 /* write data to board's fifo */
1234 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
1236 /* enable dac half-full and empty interrupts */
1237 spin_lock_irqsave(&dev->spinlock, flags);
1238 devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
1240 /* enable and clear interrupts */
1241 outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
1242 devpriv->control_status + INT_ADCFIFO);
1245 devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1246 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1248 spin_unlock_irqrestore(&dev->spinlock, flags);
1250 async->inttrig = NULL;
1255 static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1256 struct comedi_subdevice *s)
1258 struct cb_pcidas_private *devpriv = dev->private;
1259 struct comedi_async *async = s->async;
1260 struct comedi_cmd *cmd = &async->cmd;
1262 unsigned long flags;
1264 /* set channel limits, gain */
1265 spin_lock_irqsave(&dev->spinlock, flags);
1266 for (i = 0; i < cmd->chanlist_len; i++) {
1267 /* enable channel */
1268 devpriv->ao_control_bits |=
1269 DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
1271 devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
1276 /* disable analog out before settings pacer source and count values */
1277 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1278 spin_unlock_irqrestore(&dev->spinlock, flags);
1281 outw(0, devpriv->ao_registers + DACFIFOCLR);
1284 if (cmd->scan_begin_src == TRIG_TIMER) {
1285 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1286 &(devpriv->ao_divisor1),
1287 &(devpriv->ao_divisor2),
1288 &(cmd->scan_begin_arg),
1291 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1292 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1,
1293 devpriv->ao_divisor1, 2);
1294 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2,
1295 devpriv->ao_divisor2, 2);
1297 /* set number of conversions */
1298 if (cmd->stop_src == TRIG_COUNT)
1299 devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
1300 /* set pacer source */
1301 spin_lock_irqsave(&dev->spinlock, flags);
1302 switch (cmd->scan_begin_src) {
1304 devpriv->ao_control_bits |= DAC_PACER_INT;
1307 devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1310 spin_unlock_irqrestore(&dev->spinlock, flags);
1311 comedi_error(dev, "error setting dac pacer source");
1315 spin_unlock_irqrestore(&dev->spinlock, flags);
1317 async->inttrig = cb_pcidas_ao_inttrig;
1322 /* cancel analog output command */
1323 static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1324 struct comedi_subdevice *s)
1326 struct cb_pcidas_private *devpriv = dev->private;
1327 unsigned long flags;
1329 spin_lock_irqsave(&dev->spinlock, flags);
1330 /* disable interrupts */
1331 devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
1332 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1334 /* disable output */
1335 devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1336 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1337 spin_unlock_irqrestore(&dev->spinlock, flags);
1342 static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
1344 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1345 struct cb_pcidas_private *devpriv = dev->private;
1346 struct comedi_subdevice *s = dev->write_subdev;
1347 struct comedi_async *async = s->async;
1348 struct comedi_cmd *cmd = &async->cmd;
1349 unsigned int half_fifo = thisboard->fifo_size / 2;
1350 unsigned int num_points;
1351 unsigned long flags;
1355 if (status & DAEMI) {
1356 /* clear dac empty interrupt latch */
1357 spin_lock_irqsave(&dev->spinlock, flags);
1358 outw(devpriv->adc_fifo_bits | DAEMI,
1359 devpriv->control_status + INT_ADCFIFO);
1360 spin_unlock_irqrestore(&dev->spinlock, flags);
1361 if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
1362 if (cmd->stop_src == TRIG_NONE ||
1363 (cmd->stop_src == TRIG_COUNT
1364 && devpriv->ao_count)) {
1365 comedi_error(dev, "dac fifo underflow");
1366 cb_pcidas_ao_cancel(dev, s);
1367 async->events |= COMEDI_CB_ERROR;
1369 async->events |= COMEDI_CB_EOA;
1371 } else if (status & DAHFI) {
1372 unsigned int num_bytes;
1374 /* figure out how many points we are writing to fifo */
1375 num_points = half_fifo;
1376 if (cmd->stop_src == TRIG_COUNT &&
1377 devpriv->ao_count < num_points)
1378 num_points = devpriv->ao_count;
1380 cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1381 num_points * sizeof(short));
1382 num_points = num_bytes / sizeof(short);
1384 if (async->cmd.stop_src == TRIG_COUNT)
1385 devpriv->ao_count -= num_points;
1386 /* write data to board's fifo */
1387 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
1389 /* clear half-full interrupt latch */
1390 spin_lock_irqsave(&dev->spinlock, flags);
1391 outw(devpriv->adc_fifo_bits | DAHFI,
1392 devpriv->control_status + INT_ADCFIFO);
1393 spin_unlock_irqrestore(&dev->spinlock, flags);
1396 comedi_event(dev, s);
1399 static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1401 struct comedi_device *dev = (struct comedi_device *)d;
1402 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1403 struct cb_pcidas_private *devpriv = dev->private;
1404 struct comedi_subdevice *s = dev->read_subdev;
1405 struct comedi_async *async;
1406 int status, s5933_status;
1407 int half_fifo = thisboard->fifo_size / 2;
1408 unsigned int num_samples, i;
1409 static const int timeout = 10000;
1410 unsigned long flags;
1412 if (dev->attached == 0)
1418 s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1420 if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
1423 /* make sure mailbox 4 is empty */
1424 inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1425 /* clear interrupt on amcc s5933 */
1426 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1427 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1429 status = inw(devpriv->control_status + INT_ADCFIFO);
1431 /* check for analog output interrupt */
1432 if (status & (DAHFI | DAEMI))
1433 handle_ao_interrupt(dev, status);
1434 /* check for analog input interrupts */
1435 /* if fifo half-full */
1436 if (status & ADHFI) {
1438 num_samples = half_fifo;
1439 if (async->cmd.stop_src == TRIG_COUNT &&
1440 num_samples > devpriv->count) {
1441 num_samples = devpriv->count;
1443 insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
1445 cfc_write_array_to_buffer(s, devpriv->ai_buffer,
1446 num_samples * sizeof(short));
1447 devpriv->count -= num_samples;
1448 if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) {
1449 async->events |= COMEDI_CB_EOA;
1450 cb_pcidas_cancel(dev, s);
1452 /* clear half-full interrupt latch */
1453 spin_lock_irqsave(&dev->spinlock, flags);
1454 outw(devpriv->adc_fifo_bits | INT,
1455 devpriv->control_status + INT_ADCFIFO);
1456 spin_unlock_irqrestore(&dev->spinlock, flags);
1457 /* else if fifo not empty */
1458 } else if (status & (ADNEI | EOBI)) {
1459 for (i = 0; i < timeout; i++) {
1460 /* break if fifo is empty */
1461 if ((ADNE & inw(devpriv->control_status +
1464 cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
1465 if (async->cmd.stop_src == TRIG_COUNT &&
1466 --devpriv->count == 0) {
1467 /* end of acquisition */
1468 cb_pcidas_cancel(dev, s);
1469 async->events |= COMEDI_CB_EOA;
1473 /* clear not-empty interrupt latch */
1474 spin_lock_irqsave(&dev->spinlock, flags);
1475 outw(devpriv->adc_fifo_bits | INT,
1476 devpriv->control_status + INT_ADCFIFO);
1477 spin_unlock_irqrestore(&dev->spinlock, flags);
1478 } else if (status & EOAI) {
1480 "bug! encountered end of acquisition interrupt?");
1481 /* clear EOA interrupt latch */
1482 spin_lock_irqsave(&dev->spinlock, flags);
1483 outw(devpriv->adc_fifo_bits | EOAI,
1484 devpriv->control_status + INT_ADCFIFO);
1485 spin_unlock_irqrestore(&dev->spinlock, flags);
1487 /* check for fifo overflow */
1488 if (status & LADFUL) {
1489 comedi_error(dev, "fifo overflow");
1490 /* clear overflow interrupt latch */
1491 spin_lock_irqsave(&dev->spinlock, flags);
1492 outw(devpriv->adc_fifo_bits | LADFUL,
1493 devpriv->control_status + INT_ADCFIFO);
1494 spin_unlock_irqrestore(&dev->spinlock, flags);
1495 cb_pcidas_cancel(dev, s);
1496 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1499 comedi_event(dev, s);
1504 static struct pci_dev *cb_pcidas_find_pci_device(struct comedi_device *dev,
1505 struct comedi_devconfig *it)
1507 const struct cb_pcidas_board *thisboard;
1508 struct pci_dev *pcidev = NULL;
1509 int bus = it->options[0];
1510 int slot = it->options[1];
1513 for_each_pci_dev(pcidev) {
1514 /* is it not a computer boards card? */
1515 if (pcidev->vendor != PCI_VENDOR_ID_CB)
1517 /* loop through cards supported by this driver */
1518 for (i = 0; i < ARRAY_SIZE(cb_pcidas_boards); i++) {
1519 thisboard = &cb_pcidas_boards[i];
1520 if (thisboard->device_id != pcidev->device)
1522 /* was a particular bus/slot requested? */
1524 /* are we on the wrong bus/slot? */
1525 if (pcidev->bus->number != bus ||
1526 PCI_SLOT(pcidev->devfn) != slot) {
1530 dev_dbg(dev->class_dev,
1531 "Found %s on bus %i, slot %i\n",
1533 pcidev->bus->number, PCI_SLOT(pcidev->devfn));
1534 dev->board_ptr = thisboard;
1538 dev_err(dev->class_dev, "No supported card found\n");
1542 static int cb_pcidas_attach(struct comedi_device *dev,
1543 struct comedi_devconfig *it)
1545 const struct cb_pcidas_board *thisboard;
1546 struct cb_pcidas_private *devpriv;
1547 struct pci_dev *pcidev;
1548 struct comedi_subdevice *s;
1552 if (alloc_private(dev, sizeof(struct cb_pcidas_private)) < 0)
1554 devpriv = dev->private;
1556 pcidev = cb_pcidas_find_pci_device(dev, it);
1559 comedi_set_hw_dev(dev, &pcidev->dev);
1560 thisboard = comedi_board(dev);
1562 if (comedi_pci_enable(pcidev, dev->driver->driver_name)) {
1563 dev_err(dev->class_dev,
1564 "Failed to enable PCI device and request regions\n");
1568 devpriv->s5933_config = pci_resource_start(pcidev, 0);
1569 devpriv->control_status = pci_resource_start(pcidev, 1);
1570 devpriv->adc_fifo = pci_resource_start(pcidev, 2);
1571 devpriv->pacer_counter_dio = pci_resource_start(pcidev, 3);
1572 if (thisboard->ao_nchan)
1573 devpriv->ao_registers = pci_resource_start(pcidev, 4);
1575 /* disable and clear interrupts on amcc s5933 */
1576 outl(INTCSR_INBOX_INTR_STATUS,
1577 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1579 if (request_irq(pcidev->irq, cb_pcidas_interrupt,
1580 IRQF_SHARED, dev->driver->driver_name, dev)) {
1581 dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
1585 dev->irq = pcidev->irq;
1587 dev->board_name = thisboard->name;
1589 ret = comedi_alloc_subdevices(dev, 7);
1593 s = dev->subdevices + 0;
1594 /* analog input subdevice */
1595 dev->read_subdev = s;
1596 s->type = COMEDI_SUBD_AI;
1597 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
1598 /* WARNING: Number of inputs in differential mode is ignored */
1599 s->n_chan = thisboard->ai_nchan;
1600 s->len_chanlist = thisboard->ai_nchan;
1601 s->maxdata = (1 << thisboard->ai_bits) - 1;
1602 s->range_table = thisboard->ranges;
1603 s->insn_read = cb_pcidas_ai_rinsn;
1604 s->insn_config = ai_config_insn;
1605 s->do_cmd = cb_pcidas_ai_cmd;
1606 s->do_cmdtest = cb_pcidas_ai_cmdtest;
1607 s->cancel = cb_pcidas_cancel;
1609 /* analog output subdevice */
1610 s = dev->subdevices + 1;
1611 if (thisboard->ao_nchan) {
1612 s->type = COMEDI_SUBD_AO;
1613 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1614 s->n_chan = thisboard->ao_nchan;
1616 * analog out resolution is the same as
1617 * analog input resolution, so use ai_bits
1619 s->maxdata = (1 << thisboard->ai_bits) - 1;
1620 s->range_table = &cb_pcidas_ao_ranges;
1621 s->insn_read = cb_pcidas_ao_readback_insn;
1622 if (thisboard->has_ao_fifo) {
1623 dev->write_subdev = s;
1624 s->subdev_flags |= SDF_CMD_WRITE;
1625 s->insn_write = cb_pcidas_ao_fifo_winsn;
1626 s->do_cmdtest = cb_pcidas_ao_cmdtest;
1627 s->do_cmd = cb_pcidas_ao_cmd;
1628 s->cancel = cb_pcidas_ao_cancel;
1630 s->insn_write = cb_pcidas_ao_nofifo_winsn;
1633 s->type = COMEDI_SUBD_UNUSED;
1637 s = dev->subdevices + 2;
1638 ret = subdev_8255_init(dev, s, NULL,
1639 devpriv->pacer_counter_dio + DIO_8255);
1643 /* serial EEPROM, */
1644 s = dev->subdevices + 3;
1645 s->type = COMEDI_SUBD_MEMORY;
1646 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
1649 s->insn_read = eeprom_read_insn;
1652 s = dev->subdevices + 4;
1653 s->type = COMEDI_SUBD_CALIB;
1654 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1655 s->n_chan = NUM_CHANNELS_8800;
1657 s->insn_read = caldac_read_insn;
1658 s->insn_write = caldac_write_insn;
1659 for (i = 0; i < s->n_chan; i++)
1660 caldac_8800_write(dev, i, s->maxdata / 2);
1662 /* trim potentiometer */
1663 s = dev->subdevices + 5;
1664 s->type = COMEDI_SUBD_CALIB;
1665 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1666 if (thisboard->trimpot == AD7376) {
1667 s->n_chan = NUM_CHANNELS_7376;
1670 s->n_chan = NUM_CHANNELS_8402;
1673 s->insn_read = trimpot_read_insn;
1674 s->insn_write = trimpot_write_insn;
1675 for (i = 0; i < s->n_chan; i++)
1676 cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
1679 s = dev->subdevices + 6;
1680 if (thisboard->has_dac08) {
1681 s->type = COMEDI_SUBD_CALIB;
1682 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1683 s->n_chan = NUM_CHANNELS_DAC08;
1684 s->insn_read = dac08_read_insn;
1685 s->insn_write = dac08_write_insn;
1687 dac08_write(dev, s->maxdata / 2);
1689 s->type = COMEDI_SUBD_UNUSED;
1691 /* make sure mailbox 4 is empty */
1692 inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1693 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1694 devpriv->s5933_intcsr_bits =
1695 INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1696 INTCSR_INBOX_FULL_INT;
1697 /* clear and enable interrupt on amcc s5933 */
1698 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1699 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1704 static void cb_pcidas_detach(struct comedi_device *dev)
1706 struct cb_pcidas_private *devpriv = dev->private;
1707 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1710 if (devpriv->s5933_config) {
1711 outl(INTCSR_INBOX_INTR_STATUS,
1712 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1716 free_irq(dev->irq, dev);
1717 if (dev->subdevices)
1718 subdev_8255_cleanup(dev, dev->subdevices + 2);
1720 if (devpriv->s5933_config)
1721 comedi_pci_disable(pcidev);
1722 pci_dev_put(pcidev);
1726 static struct comedi_driver cb_pcidas_driver = {
1727 .driver_name = "cb_pcidas",
1728 .module = THIS_MODULE,
1729 .attach = cb_pcidas_attach,
1730 .detach = cb_pcidas_detach,
1733 static int __devinit cb_pcidas_pci_probe(struct pci_dev *dev,
1734 const struct pci_device_id *ent)
1736 return comedi_pci_auto_config(dev, &cb_pcidas_driver);
1739 static void __devexit cb_pcidas_pci_remove(struct pci_dev *dev)
1741 comedi_pci_auto_unconfig(dev);
1744 static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = {
1745 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0001) },
1746 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000f) },
1747 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0010) },
1748 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0019) },
1749 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001c) },
1750 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x004c) },
1751 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001a) },
1752 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001b) },
1755 MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
1757 static struct pci_driver cb_pcidas_pci_driver = {
1758 .name = "cb_pcidas",
1759 .id_table = cb_pcidas_pci_table,
1760 .probe = cb_pcidas_pci_probe,
1761 .remove = __devexit_p(cb_pcidas_pci_remove)
1763 module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver);
1765 MODULE_AUTHOR("Comedi http://www.comedi.org");
1766 MODULE_DESCRIPTION("Comedi low-level driver");
1767 MODULE_LICENSE("GPL");