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_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 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_insn(struct comedi_device *dev, struct comedi_subdevice *s,
443 struct comedi_insn *insn, unsigned int *data)
445 struct cb_pcidas_private *devpriv = dev->private;
447 unsigned int source = data[1];
450 case INSN_CONFIG_ALT_SOURCE:
452 dev_err(dev->class_dev,
453 "invalid calibration source: %i\n",
457 devpriv->calibration_source = source;
466 /* analog output insn for pcidas-1000 and 1200 series */
467 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev,
468 struct comedi_subdevice *s,
469 struct comedi_insn *insn,
472 struct cb_pcidas_private *devpriv = dev->private;
476 /* set channel and range */
477 channel = CR_CHAN(insn->chanspec);
478 spin_lock_irqsave(&dev->spinlock, flags);
479 devpriv->ao_control_bits &=
480 ~DAC_MODE_UPDATE_BOTH & ~DAC_RANGE_MASK(channel);
481 devpriv->ao_control_bits |=
482 DACEN | DAC_RANGE(channel, CR_RANGE(insn->chanspec));
483 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
484 spin_unlock_irqrestore(&dev->spinlock, flags);
486 /* remember value for readback */
487 devpriv->ao_value[channel] = data[0];
489 outw(data[0], devpriv->ao_registers + DAC_DATA_REG(channel));
494 /* analog output insn for pcidas-1602 series */
495 static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev,
496 struct comedi_subdevice *s,
497 struct comedi_insn *insn, unsigned int *data)
499 struct cb_pcidas_private *devpriv = dev->private;
504 outw(0, devpriv->ao_registers + DACFIFOCLR);
506 /* set channel and range */
507 channel = CR_CHAN(insn->chanspec);
508 spin_lock_irqsave(&dev->spinlock, flags);
509 devpriv->ao_control_bits &=
510 ~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) & ~DAC_RANGE_MASK(channel) &
512 devpriv->ao_control_bits |=
513 DACEN | DAC_RANGE(channel,
515 chanspec)) | DAC_CHAN_EN(channel) |
517 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
518 spin_unlock_irqrestore(&dev->spinlock, flags);
520 /* remember value for readback */
521 devpriv->ao_value[channel] = data[0];
523 outw(data[0], devpriv->ao_registers + DACDATA);
528 /* analog output readback insn */
529 /* XXX loses track of analog output value back after an analog ouput command is executed */
530 static int cb_pcidas_ao_readback_insn(struct comedi_device *dev,
531 struct comedi_subdevice *s,
532 struct comedi_insn *insn,
535 struct cb_pcidas_private *devpriv = dev->private;
537 data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
542 static int wait_for_nvram_ready(unsigned long s5933_base_addr)
544 static const int timeout = 1000;
547 for (i = 0; i < timeout; i++) {
548 if ((inb(s5933_base_addr +
549 AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
557 static int nvram_read(struct comedi_device *dev, unsigned int address,
560 struct cb_pcidas_private *devpriv = dev->private;
561 unsigned long iobase = devpriv->s5933_config;
563 if (wait_for_nvram_ready(iobase) < 0)
566 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
567 iobase + AMCC_OP_REG_MCSR_NVCMD);
568 outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
569 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
570 iobase + AMCC_OP_REG_MCSR_NVCMD);
571 outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
572 outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
574 if (wait_for_nvram_ready(iobase) < 0)
577 *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
582 static int eeprom_read_insn(struct comedi_device *dev,
583 struct comedi_subdevice *s,
584 struct comedi_insn *insn, unsigned int *data)
589 retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
593 data[0] = nvram_data;
598 static void write_calibration_bitstream(struct comedi_device *dev,
599 unsigned int register_bits,
600 unsigned int bitstream,
601 unsigned int bitstream_length)
603 struct cb_pcidas_private *devpriv = dev->private;
604 static const int write_delay = 1;
607 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
609 register_bits |= SERIAL_DATA_IN_BIT;
611 register_bits &= ~SERIAL_DATA_IN_BIT;
613 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
617 static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
620 struct cb_pcidas_private *devpriv = dev->private;
621 static const int num_caldac_channels = 8;
622 static const int bitstream_length = 11;
623 unsigned int bitstream = ((address & 0x7) << 8) | value;
624 static const int caldac_8800_udelay = 1;
626 if (address >= num_caldac_channels) {
627 comedi_error(dev, "illegal caldac channel");
631 if (value == devpriv->caldac_value[address])
634 devpriv->caldac_value[address] = value;
636 write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
639 udelay(caldac_8800_udelay);
640 outw(cal_enable_bits(dev) | SELECT_8800_BIT,
641 devpriv->control_status + CALIBRATION_REG);
642 udelay(caldac_8800_udelay);
643 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
648 static int caldac_write_insn(struct comedi_device *dev,
649 struct comedi_subdevice *s,
650 struct comedi_insn *insn, unsigned int *data)
652 const unsigned int channel = CR_CHAN(insn->chanspec);
654 return caldac_8800_write(dev, channel, data[0]);
657 static int caldac_read_insn(struct comedi_device *dev,
658 struct comedi_subdevice *s,
659 struct comedi_insn *insn, unsigned int *data)
661 struct cb_pcidas_private *devpriv = dev->private;
663 data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)];
668 /* 1602/16 pregain offset */
669 static int dac08_write(struct comedi_device *dev, unsigned int value)
671 struct cb_pcidas_private *devpriv = dev->private;
673 if (devpriv->dac08_value == value)
676 devpriv->dac08_value = value;
678 outw(cal_enable_bits(dev) | (value & 0xff),
679 devpriv->control_status + CALIBRATION_REG);
681 outw(cal_enable_bits(dev) | SELECT_DAC08_BIT | (value & 0xff),
682 devpriv->control_status + CALIBRATION_REG);
684 outw(cal_enable_bits(dev) | (value & 0xff),
685 devpriv->control_status + CALIBRATION_REG);
691 static int dac08_write_insn(struct comedi_device *dev,
692 struct comedi_subdevice *s,
693 struct comedi_insn *insn, unsigned int *data)
695 return dac08_write(dev, data[0]);
698 static int dac08_read_insn(struct comedi_device *dev,
699 struct comedi_subdevice *s, struct comedi_insn *insn,
702 struct cb_pcidas_private *devpriv = dev->private;
704 data[0] = devpriv->dac08_value;
709 static int trimpot_7376_write(struct comedi_device *dev, uint8_t value)
711 struct cb_pcidas_private *devpriv = dev->private;
712 static const int bitstream_length = 7;
713 unsigned int bitstream = value & 0x7f;
714 unsigned int register_bits;
715 static const int ad7376_udelay = 1;
717 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
718 udelay(ad7376_udelay);
719 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
721 write_calibration_bitstream(dev, register_bits, bitstream,
724 udelay(ad7376_udelay);
725 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
732 * ch 1 : adc postgain offset */
733 static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
736 struct cb_pcidas_private *devpriv = dev->private;
737 static const int bitstream_length = 10;
738 unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
739 unsigned int register_bits;
740 static const int ad8402_udelay = 1;
742 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
743 udelay(ad8402_udelay);
744 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
746 write_calibration_bitstream(dev, register_bits, bitstream,
749 udelay(ad8402_udelay);
750 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
755 static int cb_pcidas_trimpot_write(struct comedi_device *dev,
756 unsigned int channel, unsigned int value)
758 const struct cb_pcidas_board *thisboard = comedi_board(dev);
759 struct cb_pcidas_private *devpriv = dev->private;
761 if (devpriv->trimpot_value[channel] == value)
764 devpriv->trimpot_value[channel] = value;
765 switch (thisboard->trimpot) {
767 trimpot_7376_write(dev, value);
770 trimpot_8402_write(dev, channel, value);
773 comedi_error(dev, "driver bug?");
781 static int trimpot_write_insn(struct comedi_device *dev,
782 struct comedi_subdevice *s,
783 struct comedi_insn *insn, unsigned int *data)
785 unsigned int channel = CR_CHAN(insn->chanspec);
787 return cb_pcidas_trimpot_write(dev, channel, data[0]);
790 static int trimpot_read_insn(struct comedi_device *dev,
791 struct comedi_subdevice *s,
792 struct comedi_insn *insn, unsigned int *data)
794 struct cb_pcidas_private *devpriv = dev->private;
795 unsigned int channel = CR_CHAN(insn->chanspec);
797 data[0] = devpriv->trimpot_value[channel];
802 static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
803 struct comedi_subdevice *s,
804 struct comedi_cmd *cmd)
806 const struct cb_pcidas_board *thisboard = comedi_board(dev);
807 struct cb_pcidas_private *devpriv = dev->private;
810 int i, gain, start_chan;
812 /* step 1: trigger sources are trivially valid */
814 tmp = cmd->start_src;
815 cmd->start_src &= TRIG_NOW | TRIG_EXT;
816 if (!cmd->start_src || tmp != cmd->start_src)
819 tmp = cmd->scan_begin_src;
820 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
821 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
824 tmp = cmd->convert_src;
825 cmd->convert_src &= TRIG_TIMER | TRIG_NOW | TRIG_EXT;
826 if (!cmd->convert_src || tmp != cmd->convert_src)
829 tmp = cmd->scan_end_src;
830 cmd->scan_end_src &= TRIG_COUNT;
831 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
835 cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
836 if (!cmd->stop_src || tmp != cmd->stop_src)
842 /* step 2: trigger sources are unique and mutually compatible */
844 if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
846 if (cmd->scan_begin_src != TRIG_FOLLOW &&
847 cmd->scan_begin_src != TRIG_TIMER &&
848 cmd->scan_begin_src != TRIG_EXT)
850 if (cmd->convert_src != TRIG_TIMER &&
851 cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
853 if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
856 /* make sure trigger sources are compatible with each other */
857 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
859 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
861 if (cmd->start_src == TRIG_EXT &&
862 (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))
868 /* step 3: arguments are trivially compatible */
870 switch (cmd->start_src) {
872 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
874 & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
876 ~(CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
879 if (!thisboard->is_1602 && (cmd->start_arg & CR_INVERT)) {
880 cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
885 if (cmd->start_arg != 0) {
892 if (cmd->scan_begin_src == TRIG_TIMER) {
893 if (cmd->scan_begin_arg <
894 thisboard->ai_speed * cmd->chanlist_len) {
895 cmd->scan_begin_arg =
896 thisboard->ai_speed * cmd->chanlist_len;
900 if (cmd->convert_src == TRIG_TIMER) {
901 if (cmd->convert_arg < thisboard->ai_speed) {
902 cmd->convert_arg = thisboard->ai_speed;
907 if (cmd->scan_end_arg != cmd->chanlist_len) {
908 cmd->scan_end_arg = cmd->chanlist_len;
911 if (cmd->stop_src == TRIG_NONE) {
913 if (cmd->stop_arg != 0) {
922 /* step 4: fix up any arguments */
924 if (cmd->scan_begin_src == TRIG_TIMER) {
925 tmp = cmd->scan_begin_arg;
926 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
927 &(devpriv->divisor1),
928 &(devpriv->divisor2),
929 &(cmd->scan_begin_arg),
930 cmd->flags & TRIG_ROUND_MASK);
931 if (tmp != cmd->scan_begin_arg)
934 if (cmd->convert_src == TRIG_TIMER) {
935 tmp = cmd->convert_arg;
936 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
937 &(devpriv->divisor1),
938 &(devpriv->divisor2),
940 cmd->flags & TRIG_ROUND_MASK);
941 if (tmp != cmd->convert_arg)
948 /* check channel/gain list against card's limitations */
950 gain = CR_RANGE(cmd->chanlist[0]);
951 start_chan = CR_CHAN(cmd->chanlist[0]);
952 for (i = 1; i < cmd->chanlist_len; i++) {
953 if (CR_CHAN(cmd->chanlist[i]) !=
954 (start_chan + i) % s->n_chan) {
956 "entries in chanlist must be consecutive channels, counting upwards\n");
959 if (CR_RANGE(cmd->chanlist[i]) != gain) {
961 "entries in chanlist must all have the same gain\n");
973 static void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns,
976 struct cb_pcidas_private *devpriv = dev->private;
978 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
979 &(devpriv->divisor2), ns,
980 rounding_flags & TRIG_ROUND_MASK);
982 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
983 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1,
984 devpriv->divisor1, 2);
985 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2,
986 devpriv->divisor2, 2);
989 static int cb_pcidas_ai_cmd(struct comedi_device *dev,
990 struct comedi_subdevice *s)
992 const struct cb_pcidas_board *thisboard = comedi_board(dev);
993 struct cb_pcidas_private *devpriv = dev->private;
994 struct comedi_async *async = s->async;
995 struct comedi_cmd *cmd = &async->cmd;
999 /* make sure CAL_EN_BIT is disabled */
1000 outw(0, devpriv->control_status + CALIBRATION_REG);
1001 /* initialize before settings pacer source and count values */
1002 outw(0, devpriv->control_status + TRIG_CONTSTAT);
1004 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
1006 /* set mux limits, gain and pacer source */
1007 bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
1008 END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
1009 GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
1010 /* set unipolar/bipolar */
1011 if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
1013 /* set singleended/differential */
1014 if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
1016 /* set pacer source */
1017 if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
1018 bits |= PACER_EXT_RISE;
1021 outw(bits, devpriv->control_status + ADCMUX_CONT);
1024 if (cmd->convert_src == TRIG_TIMER)
1025 cb_pcidas_load_counters(dev, &cmd->convert_arg,
1026 cmd->flags & TRIG_ROUND_MASK);
1027 else if (cmd->scan_begin_src == TRIG_TIMER)
1028 cb_pcidas_load_counters(dev, &cmd->scan_begin_arg,
1029 cmd->flags & TRIG_ROUND_MASK);
1031 /* set number of conversions */
1032 if (cmd->stop_src == TRIG_COUNT)
1033 devpriv->count = cmd->chanlist_len * cmd->stop_arg;
1034 /* enable interrupts */
1035 spin_lock_irqsave(&dev->spinlock, flags);
1036 devpriv->adc_fifo_bits |= INTE;
1037 devpriv->adc_fifo_bits &= ~INT_MASK;
1038 if (cmd->flags & TRIG_WAKE_EOS) {
1039 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) {
1040 /* interrupt end of burst */
1041 devpriv->adc_fifo_bits |= INT_EOS;
1043 /* interrupt fifo not empty */
1044 devpriv->adc_fifo_bits |= INT_FNE;
1047 /* interrupt fifo half full */
1048 devpriv->adc_fifo_bits |= INT_FHF;
1051 /* enable (and clear) interrupts */
1052 outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
1053 devpriv->control_status + INT_ADCFIFO);
1054 spin_unlock_irqrestore(&dev->spinlock, flags);
1056 /* set start trigger and burst mode */
1058 if (cmd->start_src == TRIG_NOW)
1060 else if (cmd->start_src == TRIG_EXT) {
1061 bits |= EXT_TRIGGER | TGEN | XTRCL;
1062 if (thisboard->is_1602) {
1063 if (cmd->start_arg & CR_INVERT)
1065 if (cmd->start_arg & CR_EDGE)
1069 comedi_error(dev, "bug!");
1072 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1074 outw(bits, devpriv->control_status + TRIG_CONTSTAT);
1079 static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
1080 struct comedi_subdevice *s,
1081 struct comedi_cmd *cmd)
1083 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1084 struct cb_pcidas_private *devpriv = dev->private;
1088 /* step 1: trigger sources are trivially valid */
1090 tmp = cmd->start_src;
1091 cmd->start_src &= TRIG_INT;
1092 if (!cmd->start_src || tmp != cmd->start_src)
1095 tmp = cmd->scan_begin_src;
1096 cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
1097 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1100 tmp = cmd->convert_src;
1101 cmd->convert_src &= TRIG_NOW;
1102 if (!cmd->convert_src || tmp != cmd->convert_src)
1105 tmp = cmd->scan_end_src;
1106 cmd->scan_end_src &= TRIG_COUNT;
1107 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1110 tmp = cmd->stop_src;
1111 cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1112 if (!cmd->stop_src || tmp != cmd->stop_src)
1118 /* step 2: trigger sources are unique and mutually compatible */
1120 if (cmd->scan_begin_src != TRIG_TIMER &&
1121 cmd->scan_begin_src != TRIG_EXT)
1123 if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
1129 /* step 3: arguments are trivially compatible */
1131 if (cmd->start_arg != 0) {
1136 if (cmd->scan_begin_src == TRIG_TIMER) {
1137 if (cmd->scan_begin_arg < thisboard->ao_scan_speed) {
1138 cmd->scan_begin_arg = thisboard->ao_scan_speed;
1143 if (cmd->scan_end_arg != cmd->chanlist_len) {
1144 cmd->scan_end_arg = cmd->chanlist_len;
1147 if (cmd->stop_src == TRIG_NONE) {
1149 if (cmd->stop_arg != 0) {
1158 /* step 4: fix up any arguments */
1160 if (cmd->scan_begin_src == TRIG_TIMER) {
1161 tmp = cmd->scan_begin_arg;
1162 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1163 &(devpriv->ao_divisor1),
1164 &(devpriv->ao_divisor2),
1165 &(cmd->scan_begin_arg),
1166 cmd->flags & TRIG_ROUND_MASK);
1167 if (tmp != cmd->scan_begin_arg)
1174 /* check channel/gain list against card's limitations */
1175 if (cmd->chanlist && cmd->chanlist_len > 1) {
1176 if (CR_CHAN(cmd->chanlist[0]) != 0 ||
1177 CR_CHAN(cmd->chanlist[1]) != 1) {
1179 "channels must be ordered channel 0, channel 1 in chanlist\n");
1190 /* cancel analog input command */
1191 static int cb_pcidas_cancel(struct comedi_device *dev,
1192 struct comedi_subdevice *s)
1194 struct cb_pcidas_private *devpriv = dev->private;
1195 unsigned long flags;
1197 spin_lock_irqsave(&dev->spinlock, flags);
1198 /* disable interrupts */
1199 devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
1200 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1201 spin_unlock_irqrestore(&dev->spinlock, flags);
1203 /* disable start trigger source and burst mode */
1204 outw(0, devpriv->control_status + TRIG_CONTSTAT);
1205 /* software pacer source */
1206 outw(0, devpriv->control_status + ADCMUX_CONT);
1211 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1212 struct comedi_subdevice *s,
1213 unsigned int trig_num)
1215 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1216 struct cb_pcidas_private *devpriv = dev->private;
1217 unsigned int num_bytes, num_points = thisboard->fifo_size;
1218 struct comedi_async *async = s->async;
1219 struct comedi_cmd *cmd = &s->async->cmd;
1220 unsigned long flags;
1226 if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
1227 num_points = devpriv->ao_count;
1229 num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1230 num_points * sizeof(short));
1231 num_points = num_bytes / sizeof(short);
1233 if (cmd->stop_src == TRIG_COUNT)
1234 devpriv->ao_count -= num_points;
1235 /* write data to board's fifo */
1236 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
1238 /* enable dac half-full and empty interrupts */
1239 spin_lock_irqsave(&dev->spinlock, flags);
1240 devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
1242 /* enable and clear interrupts */
1243 outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
1244 devpriv->control_status + INT_ADCFIFO);
1247 devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1248 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1250 spin_unlock_irqrestore(&dev->spinlock, flags);
1252 async->inttrig = NULL;
1257 static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1258 struct comedi_subdevice *s)
1260 struct cb_pcidas_private *devpriv = dev->private;
1261 struct comedi_async *async = s->async;
1262 struct comedi_cmd *cmd = &async->cmd;
1264 unsigned long flags;
1266 /* set channel limits, gain */
1267 spin_lock_irqsave(&dev->spinlock, flags);
1268 for (i = 0; i < cmd->chanlist_len; i++) {
1269 /* enable channel */
1270 devpriv->ao_control_bits |=
1271 DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
1273 devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
1278 /* disable analog out before settings pacer source and count values */
1279 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1280 spin_unlock_irqrestore(&dev->spinlock, flags);
1283 outw(0, devpriv->ao_registers + DACFIFOCLR);
1286 if (cmd->scan_begin_src == TRIG_TIMER) {
1287 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1288 &(devpriv->ao_divisor1),
1289 &(devpriv->ao_divisor2),
1290 &(cmd->scan_begin_arg),
1293 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1294 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1,
1295 devpriv->ao_divisor1, 2);
1296 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2,
1297 devpriv->ao_divisor2, 2);
1299 /* set number of conversions */
1300 if (cmd->stop_src == TRIG_COUNT)
1301 devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
1302 /* set pacer source */
1303 spin_lock_irqsave(&dev->spinlock, flags);
1304 switch (cmd->scan_begin_src) {
1306 devpriv->ao_control_bits |= DAC_PACER_INT;
1309 devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1312 spin_unlock_irqrestore(&dev->spinlock, flags);
1313 comedi_error(dev, "error setting dac pacer source");
1317 spin_unlock_irqrestore(&dev->spinlock, flags);
1319 async->inttrig = cb_pcidas_ao_inttrig;
1324 /* cancel analog output command */
1325 static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1326 struct comedi_subdevice *s)
1328 struct cb_pcidas_private *devpriv = dev->private;
1329 unsigned long flags;
1331 spin_lock_irqsave(&dev->spinlock, flags);
1332 /* disable interrupts */
1333 devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
1334 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1336 /* disable output */
1337 devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1338 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1339 spin_unlock_irqrestore(&dev->spinlock, flags);
1344 static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
1346 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1347 struct cb_pcidas_private *devpriv = dev->private;
1348 struct comedi_subdevice *s = dev->write_subdev;
1349 struct comedi_async *async = s->async;
1350 struct comedi_cmd *cmd = &async->cmd;
1351 unsigned int half_fifo = thisboard->fifo_size / 2;
1352 unsigned int num_points;
1353 unsigned long flags;
1357 if (status & DAEMI) {
1358 /* clear dac empty interrupt latch */
1359 spin_lock_irqsave(&dev->spinlock, flags);
1360 outw(devpriv->adc_fifo_bits | DAEMI,
1361 devpriv->control_status + INT_ADCFIFO);
1362 spin_unlock_irqrestore(&dev->spinlock, flags);
1363 if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
1364 if (cmd->stop_src == TRIG_NONE ||
1365 (cmd->stop_src == TRIG_COUNT
1366 && devpriv->ao_count)) {
1367 comedi_error(dev, "dac fifo underflow");
1368 cb_pcidas_ao_cancel(dev, s);
1369 async->events |= COMEDI_CB_ERROR;
1371 async->events |= COMEDI_CB_EOA;
1373 } else if (status & DAHFI) {
1374 unsigned int num_bytes;
1376 /* figure out how many points we are writing to fifo */
1377 num_points = half_fifo;
1378 if (cmd->stop_src == TRIG_COUNT &&
1379 devpriv->ao_count < num_points)
1380 num_points = devpriv->ao_count;
1382 cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1383 num_points * sizeof(short));
1384 num_points = num_bytes / sizeof(short);
1386 if (async->cmd.stop_src == TRIG_COUNT)
1387 devpriv->ao_count -= num_points;
1388 /* write data to board's fifo */
1389 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
1391 /* clear half-full interrupt latch */
1392 spin_lock_irqsave(&dev->spinlock, flags);
1393 outw(devpriv->adc_fifo_bits | DAHFI,
1394 devpriv->control_status + INT_ADCFIFO);
1395 spin_unlock_irqrestore(&dev->spinlock, flags);
1398 comedi_event(dev, s);
1401 static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1403 struct comedi_device *dev = (struct comedi_device *)d;
1404 const struct cb_pcidas_board *thisboard = comedi_board(dev);
1405 struct cb_pcidas_private *devpriv = dev->private;
1406 struct comedi_subdevice *s = dev->read_subdev;
1407 struct comedi_async *async;
1408 int status, s5933_status;
1409 int half_fifo = thisboard->fifo_size / 2;
1410 unsigned int num_samples, i;
1411 static const int timeout = 10000;
1412 unsigned long flags;
1414 if (dev->attached == 0)
1420 s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1422 if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
1425 /* make sure mailbox 4 is empty */
1426 inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1427 /* clear interrupt on amcc s5933 */
1428 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1429 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1431 status = inw(devpriv->control_status + INT_ADCFIFO);
1433 /* check for analog output interrupt */
1434 if (status & (DAHFI | DAEMI))
1435 handle_ao_interrupt(dev, status);
1436 /* check for analog input interrupts */
1437 /* if fifo half-full */
1438 if (status & ADHFI) {
1440 num_samples = half_fifo;
1441 if (async->cmd.stop_src == TRIG_COUNT &&
1442 num_samples > devpriv->count) {
1443 num_samples = devpriv->count;
1445 insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
1447 cfc_write_array_to_buffer(s, devpriv->ai_buffer,
1448 num_samples * sizeof(short));
1449 devpriv->count -= num_samples;
1450 if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) {
1451 async->events |= COMEDI_CB_EOA;
1452 cb_pcidas_cancel(dev, s);
1454 /* clear half-full interrupt latch */
1455 spin_lock_irqsave(&dev->spinlock, flags);
1456 outw(devpriv->adc_fifo_bits | INT,
1457 devpriv->control_status + INT_ADCFIFO);
1458 spin_unlock_irqrestore(&dev->spinlock, flags);
1459 /* else if fifo not empty */
1460 } else if (status & (ADNEI | EOBI)) {
1461 for (i = 0; i < timeout; i++) {
1462 /* break if fifo is empty */
1463 if ((ADNE & inw(devpriv->control_status +
1466 cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
1467 if (async->cmd.stop_src == TRIG_COUNT &&
1468 --devpriv->count == 0) {
1469 /* end of acquisition */
1470 cb_pcidas_cancel(dev, s);
1471 async->events |= COMEDI_CB_EOA;
1475 /* clear not-empty interrupt latch */
1476 spin_lock_irqsave(&dev->spinlock, flags);
1477 outw(devpriv->adc_fifo_bits | INT,
1478 devpriv->control_status + INT_ADCFIFO);
1479 spin_unlock_irqrestore(&dev->spinlock, flags);
1480 } else if (status & EOAI) {
1482 "bug! encountered end of acquisition interrupt?");
1483 /* clear EOA interrupt latch */
1484 spin_lock_irqsave(&dev->spinlock, flags);
1485 outw(devpriv->adc_fifo_bits | EOAI,
1486 devpriv->control_status + INT_ADCFIFO);
1487 spin_unlock_irqrestore(&dev->spinlock, flags);
1489 /* check for fifo overflow */
1490 if (status & LADFUL) {
1491 comedi_error(dev, "fifo overflow");
1492 /* clear overflow interrupt latch */
1493 spin_lock_irqsave(&dev->spinlock, flags);
1494 outw(devpriv->adc_fifo_bits | LADFUL,
1495 devpriv->control_status + INT_ADCFIFO);
1496 spin_unlock_irqrestore(&dev->spinlock, flags);
1497 cb_pcidas_cancel(dev, s);
1498 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1501 comedi_event(dev, s);
1506 static struct pci_dev *cb_pcidas_find_pci_device(struct comedi_device *dev,
1507 struct comedi_devconfig *it)
1509 const struct cb_pcidas_board *thisboard;
1510 struct pci_dev *pcidev = NULL;
1511 int bus = it->options[0];
1512 int slot = it->options[1];
1515 for_each_pci_dev(pcidev) {
1516 /* is it not a computer boards card? */
1517 if (pcidev->vendor != PCI_VENDOR_ID_CB)
1519 /* loop through cards supported by this driver */
1520 for (i = 0; i < ARRAY_SIZE(cb_pcidas_boards); i++) {
1521 thisboard = &cb_pcidas_boards[i];
1522 if (thisboard->device_id != pcidev->device)
1524 /* was a particular bus/slot requested? */
1526 /* are we on the wrong bus/slot? */
1527 if (pcidev->bus->number != bus ||
1528 PCI_SLOT(pcidev->devfn) != slot) {
1532 dev_dbg(dev->class_dev,
1533 "Found %s on bus %i, slot %i\n",
1535 pcidev->bus->number, PCI_SLOT(pcidev->devfn));
1536 dev->board_ptr = thisboard;
1540 dev_err(dev->class_dev, "No supported card found\n");
1544 static int cb_pcidas_attach(struct comedi_device *dev,
1545 struct comedi_devconfig *it)
1547 const struct cb_pcidas_board *thisboard;
1548 struct cb_pcidas_private *devpriv;
1549 struct comedi_subdevice *s;
1553 if (alloc_private(dev, sizeof(struct cb_pcidas_private)) < 0)
1555 devpriv = dev->private;
1557 devpriv->pci_dev = cb_pcidas_find_pci_device(dev, it);
1558 if (!devpriv->pci_dev)
1560 thisboard = comedi_board(dev);
1562 if (comedi_pci_enable(devpriv->pci_dev, 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(devpriv->pci_dev, 0);
1569 devpriv->control_status = pci_resource_start(devpriv->pci_dev, 1);
1570 devpriv->adc_fifo = pci_resource_start(devpriv->pci_dev, 2);
1571 devpriv->pacer_counter_dio = pci_resource_start(devpriv->pci_dev, 3);
1572 if (thisboard->ao_nchan)
1573 devpriv->ao_registers = pci_resource_start(devpriv->pci_dev, 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(devpriv->pci_dev->irq, cb_pcidas_interrupt,
1580 IRQF_SHARED, dev->driver->driver_name, dev)) {
1581 dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
1582 devpriv->pci_dev->irq);
1585 dev->irq = devpriv->pci_dev->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;
1709 if (devpriv->s5933_config) {
1710 outl(INTCSR_INBOX_INTR_STATUS,
1711 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1715 free_irq(dev->irq, dev);
1716 if (dev->subdevices)
1717 subdev_8255_cleanup(dev, dev->subdevices + 2);
1718 if (devpriv && devpriv->pci_dev) {
1719 if (devpriv->s5933_config)
1720 comedi_pci_disable(devpriv->pci_dev);
1721 pci_dev_put(devpriv->pci_dev);
1725 static struct comedi_driver cb_pcidas_driver = {
1726 .driver_name = "cb_pcidas",
1727 .module = THIS_MODULE,
1728 .attach = cb_pcidas_attach,
1729 .detach = cb_pcidas_detach,
1732 static int __devinit cb_pcidas_pci_probe(struct pci_dev *dev,
1733 const struct pci_device_id *ent)
1735 return comedi_pci_auto_config(dev, &cb_pcidas_driver);
1738 static void __devexit cb_pcidas_pci_remove(struct pci_dev *dev)
1740 comedi_pci_auto_unconfig(dev);
1743 static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = {
1744 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0001) },
1745 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000f) },
1746 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0010) },
1747 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0019) },
1748 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001c) },
1749 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x004c) },
1750 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001a) },
1751 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001b) },
1754 MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
1756 static struct pci_driver cb_pcidas_pci_driver = {
1757 .name = "cb_pcidas",
1758 .id_table = cb_pcidas_pci_table,
1759 .probe = cb_pcidas_pci_probe,
1760 .remove = __devexit_p(cb_pcidas_pci_remove)
1762 module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver);
1764 MODULE_AUTHOR("Comedi http://www.comedi.org");
1765 MODULE_DESCRIPTION("Comedi low-level driver");
1766 MODULE_LICENSE("GPL");