2 comedi/drivers/cb_pcidas.c
4 Developed by Ivan Martinez and Frank Mori Hess, with valuable help from
5 David Schleef and the rest of the Comedi developers comunity.
7 Copyright (C) 2001-2003 Ivan Martinez <imr@oersted.dtu.dk>
8 Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
10 COMEDI - Linux Control and Measurement Device Interface
11 Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 ************************************************************************
31 Description: MeasurementComputing PCI-DAS series
32 with the AMCC S5933 PCI controller
33 Author: Ivan Martinez <imr@oersted.dtu.dk>,
34 Frank Mori Hess <fmhess@users.sourceforge.net>
36 Devices: [Measurement Computing] PCI-DAS1602/16 (cb_pcidas),
37 PCI-DAS1602/16jr, PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr,
38 PCI-DAS1000, PCI-DAS1001, PCI_DAS1002
41 There are many reports of the driver being used with most of the
42 supported cards. Despite no detailed log is maintained, it can
43 be said that the driver is quite tested and stable.
45 The boards may be autocalibrated using the comedi_calibrate
48 Configuration options: not applicable, uses PCI auto config
50 For commands, the scanned channels must be consecutive
51 (i.e. 4-5-6-7, 2-3-4,...), and must all have the same
55 For start_src == TRIG_EXT, the A/D EXTERNAL TRIGGER IN (pin 45) is used.
56 For 1602 series, the start_arg is interpreted as follows:
57 start_arg == 0 => gated trigger (level high)
58 start_arg == CR_INVERT => gated trigger (level low)
59 start_arg == CR_EDGE => Rising edge
60 start_arg == CR_EDGE | CR_INVERT => Falling edge
61 For the other boards the trigger will be done on rising edge
67 analog triggering on 1602 series
70 #include <linux/pci.h>
71 #include <linux/delay.h>
72 #include <linux/interrupt.h>
74 #include "../comedidev.h"
78 #include "amcc_s5933.h"
79 #include "comedi_fc.h"
81 #define TIMER_BASE 100 /* 10MHz master clock */
82 #define AI_BUFFER_SIZE 1024 /* max ai fifo size */
83 #define AO_BUFFER_SIZE 1024 /* max ao fifo size */
84 #define NUM_CHANNELS_8800 8
85 #define NUM_CHANNELS_7376 1
86 #define NUM_CHANNELS_8402 2
87 #define NUM_CHANNELS_DAC08 1
89 /* Control/Status registers */
90 #define INT_ADCFIFO 0 /* INTERRUPT / ADC FIFO register */
91 #define INT_EOS 0x1 /* int end of scan */
92 #define INT_FHF 0x2 /* int fifo half full */
93 #define INT_FNE 0x3 /* int fifo not empty */
94 #define INT_MASK 0x3 /* mask of int select bits */
95 #define INTE 0x4 /* int enable */
96 #define DAHFIE 0x8 /* dac half full int enable */
97 #define EOAIE 0x10 /* end of acq. int enable */
98 #define DAHFI 0x20 /* dac half full status / clear */
99 #define EOAI 0x40 /* end of acq. int status / clear */
100 #define INT 0x80 /* int status / clear */
101 #define EOBI 0x200 /* end of burst int status */
102 #define ADHFI 0x400 /* half-full int status */
103 #define ADNEI 0x800 /* fifo not empty int status (latch) */
104 #define ADNE 0x1000 /* fifo not empty status (realtime) */
105 #define DAEMIE 0x1000 /* dac empty int enable */
106 #define LADFUL 0x2000 /* fifo overflow / clear */
107 #define DAEMI 0x4000 /* dac fifo empty int status / clear */
109 #define ADCMUX_CONT 2 /* ADC CHANNEL MUX AND CONTROL reg */
110 #define BEGIN_SCAN(x) ((x) & 0xf)
111 #define END_SCAN(x) (((x) & 0xf) << 4)
112 #define GAIN_BITS(x) (((x) & 0x3) << 8)
113 #define UNIP 0x800 /* Analog front-end unipolar mode */
114 #define SE 0x400 /* Inputs in single-ended mode */
115 #define PACER_MASK 0x3000 /* pacer source bits */
116 #define PACER_INT 0x1000 /* int. pacer */
117 #define PACER_EXT_FALL 0x2000 /* ext. falling edge */
118 #define PACER_EXT_RISE 0x3000 /* ext. rising edge */
119 #define EOC 0x4000 /* adc not busy */
121 #define TRIG_CONTSTAT 4 /* TRIGGER CONTROL/STATUS register */
122 #define SW_TRIGGER 0x1 /* software start trigger */
123 #define EXT_TRIGGER 0x2 /* ext. start trigger */
124 #define ANALOG_TRIGGER 0x3 /* ext. analog trigger */
125 #define TRIGGER_MASK 0x3 /* start trigger mask */
126 #define TGPOL 0x04 /* invert trigger (1602 only) */
127 #define TGSEL 0x08 /* edge/level trigerred (1602 only) */
128 #define TGEN 0x10 /* enable external start trigger */
129 #define BURSTE 0x20 /* burst mode enable */
130 #define XTRCL 0x80 /* clear external trigger */
132 #define CALIBRATION_REG 6 /* CALIBRATION register */
133 #define SELECT_8800_BIT 0x100 /* select 8800 caldac */
134 #define SELECT_TRIMPOT_BIT 0x200 /* select ad7376 trim pot */
135 #define SELECT_DAC08_BIT 0x400 /* select dac08 caldac */
136 #define CAL_SRC_BITS(x) (((x) & 0x7) << 11)
137 #define CAL_EN_BIT 0x4000 /* calibration source enable */
138 #define SERIAL_DATA_IN_BIT 0x8000 /* serial data bit going to caldac */
140 #define DAC_CSR 0x8 /* dac control and status register */
141 #define DACEN 0x02 /* dac enable */
142 #define DAC_MODE_UPDATE_BOTH 0x80 /* update both dacs */
144 static inline unsigned int DAC_RANGE(unsigned int channel, unsigned int range)
146 return (range & 0x3) << (8 + 2 * (channel & 0x1));
149 static inline unsigned int DAC_RANGE_MASK(unsigned int channel)
151 return 0x3 << (8 + 2 * (channel & 0x1));
154 /* bits for 1602 series only */
155 #define DAC_EMPTY 0x1 /* fifo empty, read, write clear */
156 #define DAC_START 0x4 /* start/arm fifo operations */
157 #define DAC_PACER_MASK 0x18 /* bits that set pacer source */
158 #define DAC_PACER_INT 0x8 /* int. pacing */
159 #define DAC_PACER_EXT_FALL 0x10 /* ext. pacing, falling edge */
160 #define DAC_PACER_EXT_RISE 0x18 /* ext. pacing, rising edge */
162 static inline unsigned int DAC_CHAN_EN(unsigned int channel)
164 return 1 << (5 + (channel & 0x1)); /* enable channel 0 or 1 */
167 /* analog input fifo */
168 #define ADCDATA 0 /* ADC DATA register */
169 #define ADCFIFOCLR 2 /* ADC FIFO CLEAR */
171 /* pacer, counter, dio registers */
176 /* analog output registers for 100x, 1200 series */
177 static inline unsigned int DAC_DATA_REG(unsigned int channel)
179 return 2 * (channel & 0x1);
182 /* analog output registers for 1602 series*/
183 #define DACDATA 0 /* DAC DATA register */
184 #define DACFIFOCLR 2 /* DAC FIFO CLEAR */
186 #define IS_UNIPOLAR 0x4 /* unipolar range mask */
188 /* analog input ranges for most boards */
189 static const struct comedi_lrange cb_pcidas_ranges = {
203 /* pci-das1001 input ranges */
204 static const struct comedi_lrange cb_pcidas_alt_ranges = {
218 /* analog output ranges */
219 static const struct comedi_lrange cb_pcidas_ao_ranges = {
234 struct cb_pcidas_board {
236 unsigned short device_id;
237 int ai_nchan; /* Inputs in single-ended mode */
238 int ai_bits; /* analog input resolution */
239 int ai_speed; /* fastest conversion period in ns */
240 int ao_nchan; /* number of analog out channels */
241 int has_ao_fifo; /* analog output has fifo */
242 int ao_scan_speed; /* analog output scan speed for 1602 series */
243 int fifo_size; /* number of samples fifo can hold */
244 const struct comedi_lrange *ranges;
245 enum trimpot_model trimpot;
246 unsigned has_dac08:1;
250 static const struct cb_pcidas_board cb_pcidas_boards[] = {
252 .name = "pci-das1602/16",
259 .ao_scan_speed = 10000,
261 .ranges = &cb_pcidas_ranges,
266 .name = "pci-das1200",
273 .ranges = &cb_pcidas_ranges,
276 .name = "pci-das1602/12",
283 .ao_scan_speed = 4000,
285 .ranges = &cb_pcidas_ranges,
289 .name = "pci-das1200/jr",
295 .ranges = &cb_pcidas_ranges,
298 .name = "pci-das1602/16/jr",
304 .ranges = &cb_pcidas_ranges,
309 .name = "pci-das1000",
315 .ranges = &cb_pcidas_ranges,
318 .name = "pci-das1001",
325 .ranges = &cb_pcidas_alt_ranges,
328 .name = "pci-das1002",
335 .ranges = &cb_pcidas_ranges,
340 struct cb_pcidas_private {
342 unsigned long s5933_config;
343 unsigned long control_status;
344 unsigned long adc_fifo;
345 unsigned long pacer_counter_dio;
346 unsigned long ao_registers;
347 /* divisors of master clock for analog input pacing */
348 unsigned int divisor1;
349 unsigned int divisor2;
350 /* number of analog input samples remaining */
352 /* bits to write to registers */
353 unsigned int adc_fifo_bits;
354 unsigned int s5933_intcsr_bits;
355 unsigned int ao_control_bits;
357 short ai_buffer[AI_BUFFER_SIZE];
358 short ao_buffer[AO_BUFFER_SIZE];
359 /* divisors of master clock for analog output pacing */
360 unsigned int ao_divisor1;
361 unsigned int ao_divisor2;
362 /* number of analog output samples remaining */
363 unsigned int ao_count;
364 /* cached values for readback */
366 unsigned int caldac_value[NUM_CHANNELS_8800];
367 unsigned int trimpot_value[NUM_CHANNELS_8402];
368 unsigned int dac08_value;
369 unsigned int calibration_source;
372 static inline unsigned int cal_enable_bits(struct comedi_device *dev)
374 struct cb_pcidas_private *devpriv = dev->private;
376 return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source);
379 static int cb_pcidas_ai_rinsn(struct comedi_device *dev,
380 struct comedi_subdevice *s,
381 struct comedi_insn *insn, unsigned int *data)
383 struct cb_pcidas_private *devpriv = dev->private;
384 unsigned int chan = CR_CHAN(insn->chanspec);
385 unsigned int range = CR_RANGE(insn->chanspec);
386 unsigned int aref = CR_AREF(insn->chanspec);
390 /* enable calibration input if appropriate */
391 if (insn->chanspec & CR_ALT_SOURCE) {
392 outw(cal_enable_bits(dev),
393 devpriv->control_status + CALIBRATION_REG);
396 outw(0, devpriv->control_status + CALIBRATION_REG);
399 /* set mux limits and gain */
400 bits = BEGIN_SCAN(chan) | END_SCAN(chan) | GAIN_BITS(range);
401 /* set unipolar/bipolar */
402 if (range & IS_UNIPOLAR)
404 /* set single-ended/differential */
405 if (aref != AREF_DIFF)
407 outw(bits, devpriv->control_status + ADCMUX_CONT);
410 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
412 /* convert n samples */
413 for (n = 0; n < insn->n; n++) {
414 /* trigger conversion */
415 outw(0, devpriv->adc_fifo + ADCDATA);
417 /* wait for conversion to end */
418 /* return -ETIMEDOUT if there is a timeout */
419 for (i = 0; i < 10000; i++) {
420 if (inw(devpriv->control_status + ADCMUX_CONT) & EOC)
427 data[n] = inw(devpriv->adc_fifo + ADCDATA);
430 /* return the number of samples read/written */
434 static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
435 struct comedi_insn *insn, unsigned int *data)
437 struct cb_pcidas_private *devpriv = dev->private;
439 unsigned int source = data[1];
442 case INSN_CONFIG_ALT_SOURCE:
444 dev_err(dev->class_dev,
445 "invalid calibration source: %i\n",
449 devpriv->calibration_source = source;
458 /* analog output insn for pcidas-1000 and 1200 series */
459 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev,
460 struct comedi_subdevice *s,
461 struct comedi_insn *insn,
464 struct cb_pcidas_private *devpriv = dev->private;
465 unsigned int chan = CR_CHAN(insn->chanspec);
466 unsigned int range = CR_RANGE(insn->chanspec);
469 /* set channel and range */
470 spin_lock_irqsave(&dev->spinlock, flags);
471 devpriv->ao_control_bits &= (~DAC_MODE_UPDATE_BOTH &
472 ~DAC_RANGE_MASK(chan));
473 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range));
474 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
475 spin_unlock_irqrestore(&dev->spinlock, flags);
477 /* remember value for readback */
478 devpriv->ao_value[chan] = data[0];
481 outw(data[0], devpriv->ao_registers + DAC_DATA_REG(chan));
486 /* analog output insn for pcidas-1602 series */
487 static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev,
488 struct comedi_subdevice *s,
489 struct comedi_insn *insn, unsigned int *data)
491 struct cb_pcidas_private *devpriv = dev->private;
492 unsigned int chan = CR_CHAN(insn->chanspec);
493 unsigned int range = CR_RANGE(insn->chanspec);
497 outw(0, devpriv->ao_registers + DACFIFOCLR);
499 /* set channel and range */
500 spin_lock_irqsave(&dev->spinlock, flags);
501 devpriv->ao_control_bits &= (~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) &
502 ~DAC_RANGE_MASK(chan) & ~DAC_PACER_MASK);
503 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range) |
504 DAC_CHAN_EN(chan) | DAC_START);
505 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
506 spin_unlock_irqrestore(&dev->spinlock, flags);
508 /* remember value for readback */
509 devpriv->ao_value[chan] = data[0];
512 outw(data[0], devpriv->ao_registers + DACDATA);
517 static int cb_pcidas_ao_readback_insn(struct comedi_device *dev,
518 struct comedi_subdevice *s,
519 struct comedi_insn *insn,
522 struct cb_pcidas_private *devpriv = dev->private;
524 data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
529 static int wait_for_nvram_ready(unsigned long s5933_base_addr)
531 static const int timeout = 1000;
534 for (i = 0; i < timeout; i++) {
535 if ((inb(s5933_base_addr +
536 AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
544 static int nvram_read(struct comedi_device *dev, unsigned int address,
547 struct cb_pcidas_private *devpriv = dev->private;
548 unsigned long iobase = devpriv->s5933_config;
550 if (wait_for_nvram_ready(iobase) < 0)
553 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
554 iobase + AMCC_OP_REG_MCSR_NVCMD);
555 outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
556 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
557 iobase + AMCC_OP_REG_MCSR_NVCMD);
558 outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
559 outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
561 if (wait_for_nvram_ready(iobase) < 0)
564 *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
569 static int eeprom_read_insn(struct comedi_device *dev,
570 struct comedi_subdevice *s,
571 struct comedi_insn *insn, unsigned int *data)
576 retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
580 data[0] = nvram_data;
585 static void write_calibration_bitstream(struct comedi_device *dev,
586 unsigned int register_bits,
587 unsigned int bitstream,
588 unsigned int bitstream_length)
590 struct cb_pcidas_private *devpriv = dev->private;
591 static const int write_delay = 1;
594 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
596 register_bits |= SERIAL_DATA_IN_BIT;
598 register_bits &= ~SERIAL_DATA_IN_BIT;
600 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
604 static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
607 struct cb_pcidas_private *devpriv = dev->private;
608 static const int num_caldac_channels = 8;
609 static const int bitstream_length = 11;
610 unsigned int bitstream = ((address & 0x7) << 8) | value;
611 static const int caldac_8800_udelay = 1;
613 if (address >= num_caldac_channels) {
614 comedi_error(dev, "illegal caldac channel");
618 if (value == devpriv->caldac_value[address])
621 devpriv->caldac_value[address] = value;
623 write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
626 udelay(caldac_8800_udelay);
627 outw(cal_enable_bits(dev) | SELECT_8800_BIT,
628 devpriv->control_status + CALIBRATION_REG);
629 udelay(caldac_8800_udelay);
630 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
635 static int caldac_write_insn(struct comedi_device *dev,
636 struct comedi_subdevice *s,
637 struct comedi_insn *insn, unsigned int *data)
639 const unsigned int channel = CR_CHAN(insn->chanspec);
641 return caldac_8800_write(dev, channel, data[0]);
644 static int caldac_read_insn(struct comedi_device *dev,
645 struct comedi_subdevice *s,
646 struct comedi_insn *insn, unsigned int *data)
648 struct cb_pcidas_private *devpriv = dev->private;
650 data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)];
655 /* 1602/16 pregain offset */
656 static void dac08_write(struct comedi_device *dev, unsigned int value)
658 struct cb_pcidas_private *devpriv = dev->private;
659 unsigned long cal_reg;
661 if (devpriv->dac08_value != value) {
662 devpriv->dac08_value = value;
664 cal_reg = devpriv->control_status + CALIBRATION_REG;
667 value |= cal_enable_bits(dev);
669 /* latch the new value into the caldac */
670 outw(value, cal_reg);
672 outw(value | SELECT_DAC08_BIT, cal_reg);
674 outw(value, cal_reg);
679 static int dac08_write_insn(struct comedi_device *dev,
680 struct comedi_subdevice *s,
681 struct comedi_insn *insn, unsigned int *data)
685 for (i = 0; i < insn->n; i++)
686 dac08_write(dev, data[i]);
691 static int dac08_read_insn(struct comedi_device *dev,
692 struct comedi_subdevice *s, struct comedi_insn *insn,
695 struct cb_pcidas_private *devpriv = dev->private;
697 data[0] = devpriv->dac08_value;
702 static int trimpot_7376_write(struct comedi_device *dev, uint8_t value)
704 struct cb_pcidas_private *devpriv = dev->private;
705 static const int bitstream_length = 7;
706 unsigned int bitstream = value & 0x7f;
707 unsigned int register_bits;
708 static const int ad7376_udelay = 1;
710 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
711 udelay(ad7376_udelay);
712 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
714 write_calibration_bitstream(dev, register_bits, bitstream,
717 udelay(ad7376_udelay);
718 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
725 * ch 1 : adc postgain offset */
726 static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
729 struct cb_pcidas_private *devpriv = dev->private;
730 static const int bitstream_length = 10;
731 unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
732 unsigned int register_bits;
733 static const int ad8402_udelay = 1;
735 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
736 udelay(ad8402_udelay);
737 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
739 write_calibration_bitstream(dev, register_bits, bitstream,
742 udelay(ad8402_udelay);
743 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
748 static int cb_pcidas_trimpot_write(struct comedi_device *dev,
749 unsigned int channel, unsigned int value)
751 const struct cb_pcidas_board *thisboard = comedi_board(dev);
752 struct cb_pcidas_private *devpriv = dev->private;
754 if (devpriv->trimpot_value[channel] == value)
757 devpriv->trimpot_value[channel] = value;
758 switch (thisboard->trimpot) {
760 trimpot_7376_write(dev, value);
763 trimpot_8402_write(dev, channel, value);
766 comedi_error(dev, "driver bug?");
774 static int trimpot_write_insn(struct comedi_device *dev,
775 struct comedi_subdevice *s,
776 struct comedi_insn *insn, unsigned int *data)
778 unsigned int channel = CR_CHAN(insn->chanspec);
780 return cb_pcidas_trimpot_write(dev, channel, data[0]);
783 static int trimpot_read_insn(struct comedi_device *dev,
784 struct comedi_subdevice *s,
785 struct comedi_insn *insn, unsigned int *data)
787 struct cb_pcidas_private *devpriv = dev->private;
788 unsigned int channel = CR_CHAN(insn->chanspec);
790 data[0] = devpriv->trimpot_value[channel];
795 static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
796 struct comedi_subdevice *s,
797 struct comedi_cmd *cmd)
799 const struct cb_pcidas_board *thisboard = comedi_board(dev);
800 struct cb_pcidas_private *devpriv = dev->private;
803 int i, gain, start_chan;
805 /* Step 1 : check if triggers are trivially valid */
807 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
808 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
809 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
810 err |= cfc_check_trigger_src(&cmd->convert_src,
811 TRIG_TIMER | TRIG_NOW | TRIG_EXT);
812 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
813 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
818 /* Step 2a : make sure trigger sources are unique */
820 err |= cfc_check_trigger_is_unique(cmd->start_src);
821 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
822 err |= cfc_check_trigger_is_unique(cmd->convert_src);
823 err |= cfc_check_trigger_is_unique(cmd->stop_src);
825 /* Step 2b : and mutually compatible */
827 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
829 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
831 if (cmd->start_src == TRIG_EXT &&
832 (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))
838 /* step 3: arguments are trivially compatible */
840 switch (cmd->start_src) {
842 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
844 & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
845 cmd->start_arg &= ~(CR_FLAGS_MASK &
846 ~(CR_EDGE | CR_INVERT));
849 if (!thisboard->is_1602 && (cmd->start_arg & CR_INVERT)) {
850 cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
855 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
859 if (cmd->scan_begin_src == TRIG_TIMER)
860 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
861 thisboard->ai_speed * cmd->chanlist_len);
863 if (cmd->convert_src == TRIG_TIMER)
864 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
865 thisboard->ai_speed);
867 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
869 if (cmd->stop_src == TRIG_NONE)
870 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
875 /* step 4: fix up any arguments */
877 if (cmd->scan_begin_src == TRIG_TIMER) {
878 tmp = cmd->scan_begin_arg;
879 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
880 &(devpriv->divisor1),
881 &(devpriv->divisor2),
882 &(cmd->scan_begin_arg),
883 cmd->flags & TRIG_ROUND_MASK);
884 if (tmp != cmd->scan_begin_arg)
887 if (cmd->convert_src == TRIG_TIMER) {
888 tmp = cmd->convert_arg;
889 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
890 &(devpriv->divisor1),
891 &(devpriv->divisor2),
893 cmd->flags & TRIG_ROUND_MASK);
894 if (tmp != cmd->convert_arg)
901 /* check channel/gain list against card's limitations */
903 gain = CR_RANGE(cmd->chanlist[0]);
904 start_chan = CR_CHAN(cmd->chanlist[0]);
905 for (i = 1; i < cmd->chanlist_len; i++) {
906 if (CR_CHAN(cmd->chanlist[i]) !=
907 (start_chan + i) % s->n_chan) {
909 "entries in chanlist must be consecutive channels, counting upwards\n");
912 if (CR_RANGE(cmd->chanlist[i]) != gain) {
914 "entries in chanlist must all have the same gain\n");
926 static void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns,
929 struct cb_pcidas_private *devpriv = dev->private;
931 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
932 &(devpriv->divisor2), ns,
933 rounding_flags & TRIG_ROUND_MASK);
935 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
936 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1,
937 devpriv->divisor1, 2);
938 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2,
939 devpriv->divisor2, 2);
942 static int cb_pcidas_ai_cmd(struct comedi_device *dev,
943 struct comedi_subdevice *s)
945 const struct cb_pcidas_board *thisboard = comedi_board(dev);
946 struct cb_pcidas_private *devpriv = dev->private;
947 struct comedi_async *async = s->async;
948 struct comedi_cmd *cmd = &async->cmd;
952 /* make sure CAL_EN_BIT is disabled */
953 outw(0, devpriv->control_status + CALIBRATION_REG);
954 /* initialize before settings pacer source and count values */
955 outw(0, devpriv->control_status + TRIG_CONTSTAT);
957 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
959 /* set mux limits, gain and pacer source */
960 bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
961 END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
962 GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
963 /* set unipolar/bipolar */
964 if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
966 /* set singleended/differential */
967 if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
969 /* set pacer source */
970 if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
971 bits |= PACER_EXT_RISE;
974 outw(bits, devpriv->control_status + ADCMUX_CONT);
977 if (cmd->convert_src == TRIG_TIMER)
978 cb_pcidas_load_counters(dev, &cmd->convert_arg,
979 cmd->flags & TRIG_ROUND_MASK);
980 else if (cmd->scan_begin_src == TRIG_TIMER)
981 cb_pcidas_load_counters(dev, &cmd->scan_begin_arg,
982 cmd->flags & TRIG_ROUND_MASK);
984 /* set number of conversions */
985 if (cmd->stop_src == TRIG_COUNT)
986 devpriv->count = cmd->chanlist_len * cmd->stop_arg;
987 /* enable interrupts */
988 spin_lock_irqsave(&dev->spinlock, flags);
989 devpriv->adc_fifo_bits |= INTE;
990 devpriv->adc_fifo_bits &= ~INT_MASK;
991 if (cmd->flags & TRIG_WAKE_EOS) {
992 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) {
993 /* interrupt end of burst */
994 devpriv->adc_fifo_bits |= INT_EOS;
996 /* interrupt fifo not empty */
997 devpriv->adc_fifo_bits |= INT_FNE;
1000 /* interrupt fifo half full */
1001 devpriv->adc_fifo_bits |= INT_FHF;
1004 /* enable (and clear) interrupts */
1005 outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
1006 devpriv->control_status + INT_ADCFIFO);
1007 spin_unlock_irqrestore(&dev->spinlock, flags);
1009 /* set start trigger and burst mode */
1011 if (cmd->start_src == TRIG_NOW)
1013 else if (cmd->start_src == TRIG_EXT) {
1014 bits |= EXT_TRIGGER | TGEN | XTRCL;
1015 if (thisboard->is_1602) {
1016 if (cmd->start_arg & CR_INVERT)
1018 if (cmd->start_arg & CR_EDGE)
1022 comedi_error(dev, "bug!");
1025 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1027 outw(bits, devpriv->control_status + TRIG_CONTSTAT);
1032 static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
1033 struct comedi_subdevice *s,
1034 struct comedi_cmd *cmd)
1036 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1037 struct cb_pcidas_private *devpriv = dev->private;
1041 /* Step 1 : check if triggers are trivially valid */
1043 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT);
1044 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
1045 TRIG_TIMER | TRIG_EXT);
1046 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
1047 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1048 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1053 /* Step 2a : make sure trigger sources are unique */
1055 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
1056 err |= cfc_check_trigger_is_unique(cmd->stop_src);
1058 /* Step 2b : and mutually compatible */
1063 /* Step 3: check if arguments are trivially valid */
1065 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1067 if (cmd->scan_begin_src == TRIG_TIMER)
1068 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1069 thisboard->ao_scan_speed);
1071 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1073 if (cmd->stop_src == TRIG_NONE)
1074 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1079 /* step 4: fix up any arguments */
1081 if (cmd->scan_begin_src == TRIG_TIMER) {
1082 tmp = cmd->scan_begin_arg;
1083 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1084 &(devpriv->ao_divisor1),
1085 &(devpriv->ao_divisor2),
1086 &(cmd->scan_begin_arg),
1087 cmd->flags & TRIG_ROUND_MASK);
1088 if (tmp != cmd->scan_begin_arg)
1095 /* check channel/gain list against card's limitations */
1096 if (cmd->chanlist && cmd->chanlist_len > 1) {
1097 if (CR_CHAN(cmd->chanlist[0]) != 0 ||
1098 CR_CHAN(cmd->chanlist[1]) != 1) {
1100 "channels must be ordered channel 0, channel 1 in chanlist\n");
1111 /* cancel analog input command */
1112 static int cb_pcidas_cancel(struct comedi_device *dev,
1113 struct comedi_subdevice *s)
1115 struct cb_pcidas_private *devpriv = dev->private;
1116 unsigned long flags;
1118 spin_lock_irqsave(&dev->spinlock, flags);
1119 /* disable interrupts */
1120 devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
1121 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1122 spin_unlock_irqrestore(&dev->spinlock, flags);
1124 /* disable start trigger source and burst mode */
1125 outw(0, devpriv->control_status + TRIG_CONTSTAT);
1126 /* software pacer source */
1127 outw(0, devpriv->control_status + ADCMUX_CONT);
1132 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1133 struct comedi_subdevice *s,
1134 unsigned int trig_num)
1136 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1137 struct cb_pcidas_private *devpriv = dev->private;
1138 unsigned int num_bytes, num_points = thisboard->fifo_size;
1139 struct comedi_async *async = s->async;
1140 struct comedi_cmd *cmd = &s->async->cmd;
1141 unsigned long flags;
1147 if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
1148 num_points = devpriv->ao_count;
1150 num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1151 num_points * sizeof(short));
1152 num_points = num_bytes / sizeof(short);
1154 if (cmd->stop_src == TRIG_COUNT)
1155 devpriv->ao_count -= num_points;
1156 /* write data to board's fifo */
1157 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
1159 /* enable dac half-full and empty interrupts */
1160 spin_lock_irqsave(&dev->spinlock, flags);
1161 devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
1163 /* enable and clear interrupts */
1164 outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
1165 devpriv->control_status + INT_ADCFIFO);
1168 devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1169 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1171 spin_unlock_irqrestore(&dev->spinlock, flags);
1173 async->inttrig = NULL;
1178 static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1179 struct comedi_subdevice *s)
1181 struct cb_pcidas_private *devpriv = dev->private;
1182 struct comedi_async *async = s->async;
1183 struct comedi_cmd *cmd = &async->cmd;
1185 unsigned long flags;
1187 /* set channel limits, gain */
1188 spin_lock_irqsave(&dev->spinlock, flags);
1189 for (i = 0; i < cmd->chanlist_len; i++) {
1190 /* enable channel */
1191 devpriv->ao_control_bits |=
1192 DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
1194 devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
1199 /* disable analog out before settings pacer source and count values */
1200 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1201 spin_unlock_irqrestore(&dev->spinlock, flags);
1204 outw(0, devpriv->ao_registers + DACFIFOCLR);
1207 if (cmd->scan_begin_src == TRIG_TIMER) {
1208 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1209 &(devpriv->ao_divisor1),
1210 &(devpriv->ao_divisor2),
1211 &(cmd->scan_begin_arg),
1214 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1215 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1,
1216 devpriv->ao_divisor1, 2);
1217 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2,
1218 devpriv->ao_divisor2, 2);
1220 /* set number of conversions */
1221 if (cmd->stop_src == TRIG_COUNT)
1222 devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
1223 /* set pacer source */
1224 spin_lock_irqsave(&dev->spinlock, flags);
1225 switch (cmd->scan_begin_src) {
1227 devpriv->ao_control_bits |= DAC_PACER_INT;
1230 devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1233 spin_unlock_irqrestore(&dev->spinlock, flags);
1234 comedi_error(dev, "error setting dac pacer source");
1238 spin_unlock_irqrestore(&dev->spinlock, flags);
1240 async->inttrig = cb_pcidas_ao_inttrig;
1245 /* cancel analog output command */
1246 static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1247 struct comedi_subdevice *s)
1249 struct cb_pcidas_private *devpriv = dev->private;
1250 unsigned long flags;
1252 spin_lock_irqsave(&dev->spinlock, flags);
1253 /* disable interrupts */
1254 devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
1255 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1257 /* disable output */
1258 devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1259 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1260 spin_unlock_irqrestore(&dev->spinlock, flags);
1265 static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
1267 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1268 struct cb_pcidas_private *devpriv = dev->private;
1269 struct comedi_subdevice *s = dev->write_subdev;
1270 struct comedi_async *async = s->async;
1271 struct comedi_cmd *cmd = &async->cmd;
1272 unsigned int half_fifo = thisboard->fifo_size / 2;
1273 unsigned int num_points;
1274 unsigned long flags;
1278 if (status & DAEMI) {
1279 /* clear dac empty interrupt latch */
1280 spin_lock_irqsave(&dev->spinlock, flags);
1281 outw(devpriv->adc_fifo_bits | DAEMI,
1282 devpriv->control_status + INT_ADCFIFO);
1283 spin_unlock_irqrestore(&dev->spinlock, flags);
1284 if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
1285 if (cmd->stop_src == TRIG_NONE ||
1286 (cmd->stop_src == TRIG_COUNT
1287 && devpriv->ao_count)) {
1288 comedi_error(dev, "dac fifo underflow");
1289 cb_pcidas_ao_cancel(dev, s);
1290 async->events |= COMEDI_CB_ERROR;
1292 async->events |= COMEDI_CB_EOA;
1294 } else if (status & DAHFI) {
1295 unsigned int num_bytes;
1297 /* figure out how many points we are writing to fifo */
1298 num_points = half_fifo;
1299 if (cmd->stop_src == TRIG_COUNT &&
1300 devpriv->ao_count < num_points)
1301 num_points = devpriv->ao_count;
1303 cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1304 num_points * sizeof(short));
1305 num_points = num_bytes / sizeof(short);
1307 if (async->cmd.stop_src == TRIG_COUNT)
1308 devpriv->ao_count -= num_points;
1309 /* write data to board's fifo */
1310 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
1312 /* clear half-full interrupt latch */
1313 spin_lock_irqsave(&dev->spinlock, flags);
1314 outw(devpriv->adc_fifo_bits | DAHFI,
1315 devpriv->control_status + INT_ADCFIFO);
1316 spin_unlock_irqrestore(&dev->spinlock, flags);
1319 comedi_event(dev, s);
1322 static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1324 struct comedi_device *dev = (struct comedi_device *)d;
1325 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1326 struct cb_pcidas_private *devpriv = dev->private;
1327 struct comedi_subdevice *s = dev->read_subdev;
1328 struct comedi_async *async;
1329 int status, s5933_status;
1330 int half_fifo = thisboard->fifo_size / 2;
1331 unsigned int num_samples, i;
1332 static const int timeout = 10000;
1333 unsigned long flags;
1335 if (dev->attached == 0)
1341 s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1343 if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
1346 /* make sure mailbox 4 is empty */
1347 inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1348 /* clear interrupt on amcc s5933 */
1349 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1350 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1352 status = inw(devpriv->control_status + INT_ADCFIFO);
1354 /* check for analog output interrupt */
1355 if (status & (DAHFI | DAEMI))
1356 handle_ao_interrupt(dev, status);
1357 /* check for analog input interrupts */
1358 /* if fifo half-full */
1359 if (status & ADHFI) {
1361 num_samples = half_fifo;
1362 if (async->cmd.stop_src == TRIG_COUNT &&
1363 num_samples > devpriv->count) {
1364 num_samples = devpriv->count;
1366 insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
1368 cfc_write_array_to_buffer(s, devpriv->ai_buffer,
1369 num_samples * sizeof(short));
1370 devpriv->count -= num_samples;
1371 if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) {
1372 async->events |= COMEDI_CB_EOA;
1373 cb_pcidas_cancel(dev, s);
1375 /* clear half-full interrupt latch */
1376 spin_lock_irqsave(&dev->spinlock, flags);
1377 outw(devpriv->adc_fifo_bits | INT,
1378 devpriv->control_status + INT_ADCFIFO);
1379 spin_unlock_irqrestore(&dev->spinlock, flags);
1380 /* else if fifo not empty */
1381 } else if (status & (ADNEI | EOBI)) {
1382 for (i = 0; i < timeout; i++) {
1383 /* break if fifo is empty */
1384 if ((ADNE & inw(devpriv->control_status +
1387 cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
1388 if (async->cmd.stop_src == TRIG_COUNT &&
1389 --devpriv->count == 0) {
1390 /* end of acquisition */
1391 cb_pcidas_cancel(dev, s);
1392 async->events |= COMEDI_CB_EOA;
1396 /* clear not-empty interrupt latch */
1397 spin_lock_irqsave(&dev->spinlock, flags);
1398 outw(devpriv->adc_fifo_bits | INT,
1399 devpriv->control_status + INT_ADCFIFO);
1400 spin_unlock_irqrestore(&dev->spinlock, flags);
1401 } else if (status & EOAI) {
1403 "bug! encountered end of acquisition interrupt?");
1404 /* clear EOA interrupt latch */
1405 spin_lock_irqsave(&dev->spinlock, flags);
1406 outw(devpriv->adc_fifo_bits | EOAI,
1407 devpriv->control_status + INT_ADCFIFO);
1408 spin_unlock_irqrestore(&dev->spinlock, flags);
1410 /* check for fifo overflow */
1411 if (status & LADFUL) {
1412 comedi_error(dev, "fifo overflow");
1413 /* clear overflow interrupt latch */
1414 spin_lock_irqsave(&dev->spinlock, flags);
1415 outw(devpriv->adc_fifo_bits | LADFUL,
1416 devpriv->control_status + INT_ADCFIFO);
1417 spin_unlock_irqrestore(&dev->spinlock, flags);
1418 cb_pcidas_cancel(dev, s);
1419 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1422 comedi_event(dev, s);
1427 static const void *cb_pcidas_find_boardinfo(struct comedi_device *dev,
1428 struct pci_dev *pcidev)
1430 const struct cb_pcidas_board *thisboard;
1433 for (i = 0; i < ARRAY_SIZE(cb_pcidas_boards); i++) {
1434 thisboard = &cb_pcidas_boards[i];
1435 if (thisboard->device_id == pcidev->device)
1441 static int cb_pcidas_auto_attach(struct comedi_device *dev,
1442 unsigned long context_unused)
1444 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1445 const struct cb_pcidas_board *thisboard;
1446 struct cb_pcidas_private *devpriv;
1447 struct comedi_subdevice *s;
1451 thisboard = cb_pcidas_find_boardinfo(dev, pcidev);
1454 dev->board_ptr = thisboard;
1455 dev->board_name = thisboard->name;
1457 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1460 dev->private = devpriv;
1462 ret = comedi_pci_enable(pcidev, dev->board_name);
1466 devpriv->s5933_config = pci_resource_start(pcidev, 0);
1467 devpriv->control_status = pci_resource_start(pcidev, 1);
1468 devpriv->adc_fifo = pci_resource_start(pcidev, 2);
1469 devpriv->pacer_counter_dio = pci_resource_start(pcidev, 3);
1470 if (thisboard->ao_nchan)
1471 devpriv->ao_registers = pci_resource_start(pcidev, 4);
1473 /* disable and clear interrupts on amcc s5933 */
1474 outl(INTCSR_INBOX_INTR_STATUS,
1475 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1477 if (request_irq(pcidev->irq, cb_pcidas_interrupt,
1478 IRQF_SHARED, dev->driver->driver_name, dev)) {
1479 dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
1483 dev->irq = pcidev->irq;
1485 ret = comedi_alloc_subdevices(dev, 7);
1489 s = &dev->subdevices[0];
1490 /* analog input subdevice */
1491 dev->read_subdev = s;
1492 s->type = COMEDI_SUBD_AI;
1493 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
1494 /* WARNING: Number of inputs in differential mode is ignored */
1495 s->n_chan = thisboard->ai_nchan;
1496 s->len_chanlist = thisboard->ai_nchan;
1497 s->maxdata = (1 << thisboard->ai_bits) - 1;
1498 s->range_table = thisboard->ranges;
1499 s->insn_read = cb_pcidas_ai_rinsn;
1500 s->insn_config = ai_config_insn;
1501 s->do_cmd = cb_pcidas_ai_cmd;
1502 s->do_cmdtest = cb_pcidas_ai_cmdtest;
1503 s->cancel = cb_pcidas_cancel;
1505 /* analog output subdevice */
1506 s = &dev->subdevices[1];
1507 if (thisboard->ao_nchan) {
1508 s->type = COMEDI_SUBD_AO;
1509 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1510 s->n_chan = thisboard->ao_nchan;
1512 * analog out resolution is the same as
1513 * analog input resolution, so use ai_bits
1515 s->maxdata = (1 << thisboard->ai_bits) - 1;
1516 s->range_table = &cb_pcidas_ao_ranges;
1517 s->insn_read = cb_pcidas_ao_readback_insn;
1518 if (thisboard->has_ao_fifo) {
1519 dev->write_subdev = s;
1520 s->subdev_flags |= SDF_CMD_WRITE;
1521 s->insn_write = cb_pcidas_ao_fifo_winsn;
1522 s->do_cmdtest = cb_pcidas_ao_cmdtest;
1523 s->do_cmd = cb_pcidas_ao_cmd;
1524 s->cancel = cb_pcidas_ao_cancel;
1526 s->insn_write = cb_pcidas_ao_nofifo_winsn;
1529 s->type = COMEDI_SUBD_UNUSED;
1533 s = &dev->subdevices[2];
1534 ret = subdev_8255_init(dev, s, NULL,
1535 devpriv->pacer_counter_dio + DIO_8255);
1539 /* serial EEPROM, */
1540 s = &dev->subdevices[3];
1541 s->type = COMEDI_SUBD_MEMORY;
1542 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
1545 s->insn_read = eeprom_read_insn;
1548 s = &dev->subdevices[4];
1549 s->type = COMEDI_SUBD_CALIB;
1550 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1551 s->n_chan = NUM_CHANNELS_8800;
1553 s->insn_read = caldac_read_insn;
1554 s->insn_write = caldac_write_insn;
1555 for (i = 0; i < s->n_chan; i++)
1556 caldac_8800_write(dev, i, s->maxdata / 2);
1558 /* trim potentiometer */
1559 s = &dev->subdevices[5];
1560 s->type = COMEDI_SUBD_CALIB;
1561 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1562 if (thisboard->trimpot == AD7376) {
1563 s->n_chan = NUM_CHANNELS_7376;
1566 s->n_chan = NUM_CHANNELS_8402;
1569 s->insn_read = trimpot_read_insn;
1570 s->insn_write = trimpot_write_insn;
1571 for (i = 0; i < s->n_chan; i++)
1572 cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
1575 s = &dev->subdevices[6];
1576 if (thisboard->has_dac08) {
1577 s->type = COMEDI_SUBD_CALIB;
1578 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1579 s->n_chan = NUM_CHANNELS_DAC08;
1580 s->insn_read = dac08_read_insn;
1581 s->insn_write = dac08_write_insn;
1583 dac08_write(dev, s->maxdata / 2);
1585 s->type = COMEDI_SUBD_UNUSED;
1587 /* make sure mailbox 4 is empty */
1588 inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1589 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1590 devpriv->s5933_intcsr_bits =
1591 INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1592 INTCSR_INBOX_FULL_INT;
1593 /* clear and enable interrupt on amcc s5933 */
1594 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1595 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1597 dev_info(dev->class_dev, "%s: %s attached\n",
1598 dev->driver->driver_name, dev->board_name);
1603 static void cb_pcidas_detach(struct comedi_device *dev)
1605 struct cb_pcidas_private *devpriv = dev->private;
1606 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1609 if (devpriv->s5933_config) {
1610 outl(INTCSR_INBOX_INTR_STATUS,
1611 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1615 free_irq(dev->irq, dev);
1616 if (dev->subdevices)
1617 subdev_8255_cleanup(dev, &dev->subdevices[2]);
1619 if (devpriv->s5933_config)
1620 comedi_pci_disable(pcidev);
1624 static struct comedi_driver cb_pcidas_driver = {
1625 .driver_name = "cb_pcidas",
1626 .module = THIS_MODULE,
1627 .auto_attach = cb_pcidas_auto_attach,
1628 .detach = cb_pcidas_detach,
1631 static int cb_pcidas_pci_probe(struct pci_dev *dev,
1632 const struct pci_device_id *ent)
1634 return comedi_pci_auto_config(dev, &cb_pcidas_driver);
1637 static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = {
1638 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0001) },
1639 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000f) },
1640 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0010) },
1641 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0019) },
1642 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001c) },
1643 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x004c) },
1644 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001a) },
1645 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001b) },
1648 MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
1650 static struct pci_driver cb_pcidas_pci_driver = {
1651 .name = "cb_pcidas",
1652 .id_table = cb_pcidas_pci_table,
1653 .probe = cb_pcidas_pci_probe,
1654 .remove = comedi_pci_auto_unconfig,
1656 module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver);
1658 MODULE_AUTHOR("Comedi http://www.comedi.org");
1659 MODULE_DESCRIPTION("Comedi low-level driver");
1660 MODULE_LICENSE("GPL");