3 * Developed by Ivan Martinez and Frank Mori Hess, with valuable help from
4 * David Schleef and the rest of the Comedi developers comunity.
6 * Copyright (C) 2001-2003 Ivan Martinez <imr@oersted.dtu.dk>
7 * Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
9 * COMEDI - Linux Control and Measurement Device Interface
10 * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
25 * Description: MeasurementComputing PCI-DAS series
26 * with the AMCC S5933 PCI controller
27 * Devices: [Measurement Computing] PCI-DAS1602/16 (cb_pcidas),
28 * PCI-DAS1602/16jr, PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr,
29 * PCI-DAS1000, PCI-DAS1001, PCI_DAS1002
30 * Author: Ivan Martinez <imr@oersted.dtu.dk>,
31 * Frank Mori Hess <fmhess@users.sourceforge.net>
35 * There are many reports of the driver being used with most of the
36 * supported cards. Despite no detailed log is maintained, it can
37 * be said that the driver is quite tested and stable.
39 * The boards may be autocalibrated using the comedi_calibrate
42 * Configuration options: not applicable, uses PCI auto config
44 * For commands, the scanned channels must be consecutive
45 * (i.e. 4-5-6-7, 2-3-4,...), and must all have the same
49 * For start_src == TRIG_EXT, the A/D EXTERNAL TRIGGER IN (pin 45) is used.
50 * For 1602 series, the start_arg is interpreted as follows:
51 * start_arg == 0 => gated trigger (level high)
52 * start_arg == CR_INVERT => gated trigger (level low)
53 * start_arg == CR_EDGE => Rising edge
54 * start_arg == CR_EDGE | CR_INVERT => Falling edge
55 * For the other boards the trigger will be done on rising edge
60 * analog triggering on 1602 series
63 #include <linux/module.h>
64 #include <linux/delay.h>
65 #include <linux/interrupt.h>
67 #include "../comedi_pci.h"
69 #include "comedi_8254.h"
71 #include "amcc_s5933.h"
73 #define AI_BUFFER_SIZE 1024 /* max ai fifo size */
74 #define AO_BUFFER_SIZE 1024 /* max ao fifo size */
77 * PCI BAR1 Register map (devpriv->pcibar1)
79 #define PCIDAS_CTRL_REG 0x00 /* INTERRUPT / ADC FIFO register */
80 #define PCIDAS_CTRL_INT(x) (((x) & 0x3) << 0)
81 #define PCIDAS_CTRL_INT_NONE PCIDAS_CTRL_INT(0) /* no int selected */
82 #define PCIDAS_CTRL_INT_EOS PCIDAS_CTRL_INT(1) /* int on end of scan */
83 #define PCIDAS_CTRL_INT_FHF PCIDAS_CTRL_INT(2) /* int on fifo half full */
84 #define PCIDAS_CTRL_INT_FNE PCIDAS_CTRL_INT(3) /* int on fifo not empty */
85 #define PCIDAS_CTRL_INT_MASK PCIDAS_CTRL_INT(3) /* mask of int select bits */
86 #define PCIDAS_CTRL_INTE BIT(2) /* int enable */
87 #define PCIDAS_CTRL_DAHFIE BIT(3) /* dac half full int enable */
88 #define PCIDAS_CTRL_EOAIE BIT(4) /* end of acq. int enable */
89 #define PCIDAS_CTRL_DAHFI BIT(5) /* dac half full status / clear */
90 #define PCIDAS_CTRL_EOAI BIT(6) /* end of acq. int status / clear */
91 #define PCIDAS_CTRL_INT_CLR BIT(7) /* int status / clear */
92 #define PCIDAS_CTRL_EOBI BIT(9) /* end of burst int status */
93 #define PCIDAS_CTRL_ADHFI BIT(10) /* half-full int status */
94 #define PCIDAS_CTRL_ADNEI BIT(11) /* fifo not empty int status (latch) */
95 #define PCIDAS_CTRL_ADNE BIT(12) /* fifo not empty status (realtime) */
96 #define PCIDAS_CTRL_DAEMIE BIT(12) /* dac empty int enable */
97 #define PCIDAS_CTRL_LADFUL BIT(13) /* fifo overflow / clear */
98 #define PCIDAS_CTRL_DAEMI BIT(14) /* dac fifo empty int status / clear */
100 #define PCIDAS_AI_REG 0x02 /* ADC CHANNEL MUX AND CONTROL reg */
101 #define PCIDAS_AI_FIRST(x) ((x) & 0xf)
102 #define PCIDAS_AI_LAST(x) (((x) & 0xf) << 4)
103 #define PCIDAS_AI_CHAN(x) (PCIDAS_AI_FIRST(x) | PCIDAS_AI_LAST(x))
104 #define PCIDAS_AI_GAIN(x) (((x) & 0x3) << 8)
105 #define PCIDAS_AI_SE BIT(10) /* Inputs in single-ended mode */
106 #define PCIDAS_AI_UNIP BIT(11) /* Analog front-end unipolar mode */
107 #define PCIDAS_AI_PACER(x) (((x) & 0x3) << 12)
108 #define PCIDAS_AI_PACER_SW PCIDAS_AI_PACER(0) /* software pacer */
109 #define PCIDAS_AI_PACER_INT PCIDAS_AI_PACER(1) /* int. pacer */
110 #define PCIDAS_AI_PACER_EXTN PCIDAS_AI_PACER(2) /* ext. falling edge */
111 #define PCIDAS_AI_PACER_EXTP PCIDAS_AI_PACER(3) /* ext. rising edge */
112 #define PCIDAS_AI_PACER_MASK PCIDAS_AI_PACER(3) /* pacer source bits */
113 #define PCIDAS_AI_EOC BIT(14) /* adc not busy */
115 #define PCIDAS_TRIG_REG 0x04 /* TRIGGER CONTROL/STATUS register */
116 #define PCIDAS_TRIG_SEL(x) (((x) & 0x3) << 0)
117 #define PCIDAS_TRIG_SEL_NONE PCIDAS_TRIG_SEL(0) /* no start trigger */
118 #define PCIDAS_TRIG_SEL_SW PCIDAS_TRIG_SEL(1) /* software start trigger */
119 #define PCIDAS_TRIG_SEL_EXT PCIDAS_TRIG_SEL(2) /* ext. start trigger */
120 #define PCIDAS_TRIG_SEL_ANALOG PCIDAS_TRIG_SEL(3) /* ext. analog trigger */
121 #define PCIDAS_TRIG_SEL_MASK PCIDAS_TRIG_SEL(3) /* start trigger mask */
122 #define PCIDAS_TRIG_POL BIT(2) /* invert trigger (1602 only) */
123 #define PCIDAS_TRIG_MODE BIT(3) /* edge/level trigerred (1602 only) */
124 #define PCIDAS_TRIG_EN BIT(4) /* enable external start trigger */
125 #define PCIDAS_TRIG_BURSTE BIT(5) /* burst mode enable */
126 #define PCIDAS_TRIG_CLR BIT(7) /* clear external trigger */
128 #define PCIDAS_CALIB_REG 0x06 /* CALIBRATION register */
129 #define PCIDAS_CALIB_8800_SEL BIT(8) /* select 8800 caldac */
130 #define PCIDAS_CALIB_TRIM_SEL BIT(9) /* select ad7376 trim pot */
131 #define PCIDAS_CALIB_DAC08_SEL BIT(10) /* select dac08 caldac */
132 #define PCIDAS_CALIB_SRC(x) (((x) & 0x7) << 11)
133 #define PCIDAS_CALIB_EN BIT(14) /* calibration source enable */
134 #define PCIDAS_CALIB_DATA BIT(15) /* serial data bit going to caldac */
136 #define DAC_CSR 0x8 /* dac control and status register */
137 #define DACEN 0x02 /* dac enable */
138 #define DAC_MODE_UPDATE_BOTH 0x80 /* update both dacs */
140 #define DAC_RANGE(c, r) (((r) & 0x3) << (8 + 2 * ((c) & 0x1)))
141 #define DAC_RANGE_MASK(c) DAC_RANGE((c), 0x3)
143 /* bits for 1602 series only */
144 #define DAC_EMPTY 0x1 /* fifo empty, read, write clear */
145 #define DAC_START 0x4 /* start/arm fifo operations */
146 #define DAC_PACER_MASK 0x18 /* bits that set pacer source */
147 #define DAC_PACER_INT 0x8 /* int. pacing */
148 #define DAC_PACER_EXT_FALL 0x10 /* ext. pacing, falling edge */
149 #define DAC_PACER_EXT_RISE 0x18 /* ext. pacing, rising edge */
151 #define DAC_CHAN_EN(c) BIT(5 + ((c) & 0x1))
154 * PCI BAR2 Register map (devpriv->pcibar2)
156 #define PCIDAS_AI_DATA_REG 0x00
157 #define PCIDAS_AI_FIFO_CLR_REG 0x02
160 * PCI BAR3 Register map (dev->iobase)
162 #define PCIDAS_AI_8254_BASE 0x00
163 #define PCIDAS_8255_BASE 0x04
164 #define PCIDAS_AO_8254_BASE 0x08
167 * PCI BAR4 Register map (devpriv->pcibar4)
169 #define PCIDAS_AO_DATA_REG(x) (0x00 + ((x) * 2))
170 #define PCIDAS_AO_FIFO_REG 0x00
171 #define PCIDAS_AO_FIFO_CLR_REG 0x02
173 /* analog input ranges for most boards */
174 static const struct comedi_lrange cb_pcidas_ranges = {
187 /* pci-das1001 input ranges */
188 static const struct comedi_lrange cb_pcidas_alt_ranges = {
201 /* analog output ranges */
202 static const struct comedi_lrange cb_pcidas_ao_ranges = {
216 enum cb_pcidas_boardid {
221 BOARD_PCIDAS1602_16_JR,
227 struct cb_pcidas_board {
229 int ai_speed; /* fastest conversion period in ns */
230 int ao_scan_speed; /* analog output scan speed for 1602 series */
231 int fifo_size; /* number of samples fifo can hold */
232 enum trimpot_model trimpot;
233 unsigned int is_16bit; /* ai/ao is 1=16-bit; 0=12-bit */
234 unsigned int use_alt_range:1; /* use alternate ai range table */
235 unsigned int has_ao:1; /* has 2 analog output channels */
236 unsigned int has_ao_fifo:1; /* analog output has fifo */
237 unsigned int has_dac08:1;
238 unsigned int is_1602:1;
241 static const struct cb_pcidas_board cb_pcidas_boards[] = {
242 [BOARD_PCIDAS1602_16] = {
243 .name = "pci-das1602/16",
245 .ao_scan_speed = 10000,
254 [BOARD_PCIDAS1200] = {
255 .name = "pci-das1200",
261 [BOARD_PCIDAS1602_12] = {
262 .name = "pci-das1602/12",
264 .ao_scan_speed = 4000,
271 [BOARD_PCIDAS1200_JR] = {
272 .name = "pci-das1200/jr",
277 [BOARD_PCIDAS1602_16_JR] = {
278 .name = "pci-das1602/16/jr",
286 [BOARD_PCIDAS1000] = {
287 .name = "pci-das1000",
292 [BOARD_PCIDAS1001] = {
293 .name = "pci-das1001",
300 [BOARD_PCIDAS1002] = {
301 .name = "pci-das1002",
309 struct cb_pcidas_private {
310 struct comedi_8254 *ao_pacer;
312 unsigned long s5933_config;
313 unsigned long pcibar1;
314 unsigned long pcibar2;
315 unsigned long pcibar4;
316 /* bits to write to registers */
318 unsigned int s5933_intcsr_bits;
319 unsigned int ao_control_bits;
321 unsigned short ai_buffer[AI_BUFFER_SIZE];
322 unsigned short ao_buffer[AO_BUFFER_SIZE];
323 unsigned int calibration_source;
326 static inline unsigned int cal_enable_bits(struct comedi_device *dev)
328 struct cb_pcidas_private *devpriv = dev->private;
330 return PCIDAS_CALIB_EN | PCIDAS_CALIB_SRC(devpriv->calibration_source);
333 static int cb_pcidas_ai_eoc(struct comedi_device *dev,
334 struct comedi_subdevice *s,
335 struct comedi_insn *insn,
336 unsigned long context)
338 struct cb_pcidas_private *devpriv = dev->private;
341 status = inw(devpriv->pcibar1 + PCIDAS_AI_REG);
342 if (status & PCIDAS_AI_EOC)
347 static int cb_pcidas_ai_rinsn(struct comedi_device *dev,
348 struct comedi_subdevice *s,
349 struct comedi_insn *insn, unsigned int *data)
351 struct cb_pcidas_private *devpriv = dev->private;
352 unsigned int chan = CR_CHAN(insn->chanspec);
353 unsigned int range = CR_RANGE(insn->chanspec);
354 unsigned int aref = CR_AREF(insn->chanspec);
359 /* enable calibration input if appropriate */
360 if (insn->chanspec & CR_ALT_SOURCE) {
361 outw(cal_enable_bits(dev),
362 devpriv->pcibar1 + PCIDAS_CALIB_REG);
365 outw(0, devpriv->pcibar1 + PCIDAS_CALIB_REG);
368 /* set mux limits and gain */
369 bits = PCIDAS_AI_CHAN(chan) | PCIDAS_AI_GAIN(range);
370 /* set unipolar/bipolar */
371 if (comedi_range_is_unipolar(s, range))
372 bits |= PCIDAS_AI_UNIP;
373 /* set single-ended/differential */
374 if (aref != AREF_DIFF)
375 bits |= PCIDAS_AI_SE;
376 outw(bits, devpriv->pcibar1 + PCIDAS_AI_REG);
379 outw(0, devpriv->pcibar2 + PCIDAS_AI_FIFO_CLR_REG);
381 /* convert n samples */
382 for (n = 0; n < insn->n; n++) {
383 /* trigger conversion */
384 outw(0, devpriv->pcibar2 + PCIDAS_AI_DATA_REG);
386 /* wait for conversion to end */
387 ret = comedi_timeout(dev, s, insn, cb_pcidas_ai_eoc, 0);
392 data[n] = inw(devpriv->pcibar2 + PCIDAS_AI_DATA_REG);
395 /* return the number of samples read/written */
399 static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
400 struct comedi_insn *insn, unsigned int *data)
402 struct cb_pcidas_private *devpriv = dev->private;
404 unsigned int source = data[1];
407 case INSN_CONFIG_ALT_SOURCE:
409 dev_err(dev->class_dev,
410 "invalid calibration source: %i\n",
414 devpriv->calibration_source = source;
422 /* analog output insn for pcidas-1000 and 1200 series */
423 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev,
424 struct comedi_subdevice *s,
425 struct comedi_insn *insn,
428 struct cb_pcidas_private *devpriv = dev->private;
429 unsigned int chan = CR_CHAN(insn->chanspec);
430 unsigned int range = CR_RANGE(insn->chanspec);
433 /* set channel and range */
434 spin_lock_irqsave(&dev->spinlock, flags);
435 devpriv->ao_control_bits &= (~DAC_MODE_UPDATE_BOTH &
436 ~DAC_RANGE_MASK(chan));
437 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range));
438 outw(devpriv->ao_control_bits, devpriv->pcibar1 + DAC_CSR);
439 spin_unlock_irqrestore(&dev->spinlock, flags);
441 /* remember value for readback */
442 s->readback[chan] = data[0];
445 outw(data[0], devpriv->pcibar4 + PCIDAS_AO_DATA_REG(chan));
450 /* analog output insn for pcidas-1602 series */
451 static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev,
452 struct comedi_subdevice *s,
453 struct comedi_insn *insn, unsigned int *data)
455 struct cb_pcidas_private *devpriv = dev->private;
456 unsigned int chan = CR_CHAN(insn->chanspec);
457 unsigned int range = CR_RANGE(insn->chanspec);
461 outw(0, devpriv->pcibar4 + PCIDAS_AO_FIFO_CLR_REG);
463 /* set channel and range */
464 spin_lock_irqsave(&dev->spinlock, flags);
465 devpriv->ao_control_bits &= (~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) &
466 ~DAC_RANGE_MASK(chan) & ~DAC_PACER_MASK);
467 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range) |
468 DAC_CHAN_EN(chan) | DAC_START);
469 outw(devpriv->ao_control_bits, devpriv->pcibar1 + DAC_CSR);
470 spin_unlock_irqrestore(&dev->spinlock, flags);
472 /* remember value for readback */
473 s->readback[chan] = data[0];
476 outw(data[0], devpriv->pcibar4 + PCIDAS_AO_FIFO_REG);
481 static int wait_for_nvram_ready(unsigned long s5933_base_addr)
483 static const int timeout = 1000;
486 for (i = 0; i < timeout; i++) {
487 if ((inb(s5933_base_addr +
488 AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
496 static int nvram_read(struct comedi_device *dev, unsigned int address,
499 struct cb_pcidas_private *devpriv = dev->private;
500 unsigned long iobase = devpriv->s5933_config;
502 if (wait_for_nvram_ready(iobase) < 0)
505 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
506 iobase + AMCC_OP_REG_MCSR_NVCMD);
507 outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
508 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
509 iobase + AMCC_OP_REG_MCSR_NVCMD);
510 outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
511 outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
513 if (wait_for_nvram_ready(iobase) < 0)
516 *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
521 static int eeprom_read_insn(struct comedi_device *dev,
522 struct comedi_subdevice *s,
523 struct comedi_insn *insn, unsigned int *data)
528 retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
532 data[0] = nvram_data;
537 static void write_calibration_bitstream(struct comedi_device *dev,
538 unsigned int register_bits,
539 unsigned int bitstream,
540 unsigned int bitstream_length)
542 struct cb_pcidas_private *devpriv = dev->private;
543 static const int write_delay = 1;
546 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
548 register_bits |= PCIDAS_CALIB_DATA;
550 register_bits &= ~PCIDAS_CALIB_DATA;
552 outw(register_bits, devpriv->pcibar1 + PCIDAS_CALIB_REG);
556 static void caldac_8800_write(struct comedi_device *dev,
557 unsigned int chan, uint8_t val)
559 struct cb_pcidas_private *devpriv = dev->private;
560 static const int bitstream_length = 11;
561 unsigned int bitstream = ((chan & 0x7) << 8) | val;
562 static const int caldac_8800_udelay = 1;
564 write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
567 udelay(caldac_8800_udelay);
568 outw(cal_enable_bits(dev) | PCIDAS_CALIB_8800_SEL,
569 devpriv->pcibar1 + PCIDAS_CALIB_REG);
570 udelay(caldac_8800_udelay);
571 outw(cal_enable_bits(dev), devpriv->pcibar1 + PCIDAS_CALIB_REG);
574 static int cb_pcidas_caldac_insn_write(struct comedi_device *dev,
575 struct comedi_subdevice *s,
576 struct comedi_insn *insn,
579 unsigned int chan = CR_CHAN(insn->chanspec);
582 unsigned int val = data[insn->n - 1];
584 if (s->readback[chan] != val) {
585 caldac_8800_write(dev, chan, val);
586 s->readback[chan] = val;
593 /* 1602/16 pregain offset */
594 static void dac08_write(struct comedi_device *dev, unsigned int value)
596 struct cb_pcidas_private *devpriv = dev->private;
599 value |= cal_enable_bits(dev);
601 /* latch the new value into the caldac */
602 outw(value, devpriv->pcibar1 + PCIDAS_CALIB_REG);
604 outw(value | PCIDAS_CALIB_DAC08_SEL,
605 devpriv->pcibar1 + PCIDAS_CALIB_REG);
607 outw(value, devpriv->pcibar1 + PCIDAS_CALIB_REG);
611 static int cb_pcidas_dac08_insn_write(struct comedi_device *dev,
612 struct comedi_subdevice *s,
613 struct comedi_insn *insn,
616 unsigned int chan = CR_CHAN(insn->chanspec);
619 unsigned int val = data[insn->n - 1];
621 if (s->readback[chan] != val) {
622 dac08_write(dev, val);
623 s->readback[chan] = val;
630 static int trimpot_7376_write(struct comedi_device *dev, uint8_t value)
632 struct cb_pcidas_private *devpriv = dev->private;
633 static const int bitstream_length = 7;
634 unsigned int bitstream = value & 0x7f;
635 unsigned int register_bits;
636 static const int ad7376_udelay = 1;
638 register_bits = cal_enable_bits(dev) | PCIDAS_CALIB_TRIM_SEL;
639 udelay(ad7376_udelay);
640 outw(register_bits, devpriv->pcibar1 + PCIDAS_CALIB_REG);
642 write_calibration_bitstream(dev, register_bits, bitstream,
645 udelay(ad7376_udelay);
646 outw(cal_enable_bits(dev), devpriv->pcibar1 + PCIDAS_CALIB_REG);
653 * ch 1 : adc postgain offset */
654 static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
657 struct cb_pcidas_private *devpriv = dev->private;
658 static const int bitstream_length = 10;
659 unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
660 unsigned int register_bits;
661 static const int ad8402_udelay = 1;
663 register_bits = cal_enable_bits(dev) | PCIDAS_CALIB_TRIM_SEL;
664 udelay(ad8402_udelay);
665 outw(register_bits, devpriv->pcibar1 + PCIDAS_CALIB_REG);
667 write_calibration_bitstream(dev, register_bits, bitstream,
670 udelay(ad8402_udelay);
671 outw(cal_enable_bits(dev), devpriv->pcibar1 + PCIDAS_CALIB_REG);
676 static void cb_pcidas_trimpot_write(struct comedi_device *dev,
677 unsigned int chan, unsigned int val)
679 const struct cb_pcidas_board *board = dev->board_ptr;
681 switch (board->trimpot) {
683 trimpot_7376_write(dev, val);
686 trimpot_8402_write(dev, chan, val);
689 dev_err(dev->class_dev, "driver bug?\n");
694 static int cb_pcidas_trimpot_insn_write(struct comedi_device *dev,
695 struct comedi_subdevice *s,
696 struct comedi_insn *insn,
699 unsigned int chan = CR_CHAN(insn->chanspec);
702 unsigned int val = data[insn->n - 1];
704 if (s->readback[chan] != val) {
705 cb_pcidas_trimpot_write(dev, chan, val);
706 s->readback[chan] = val;
713 static int cb_pcidas_ai_check_chanlist(struct comedi_device *dev,
714 struct comedi_subdevice *s,
715 struct comedi_cmd *cmd)
717 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
718 unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
721 for (i = 1; i < cmd->chanlist_len; i++) {
722 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
723 unsigned int range = CR_RANGE(cmd->chanlist[i]);
725 if (chan != (chan0 + i) % s->n_chan) {
726 dev_dbg(dev->class_dev,
727 "entries in chanlist must be consecutive channels, counting upwards\n");
731 if (range != range0) {
732 dev_dbg(dev->class_dev,
733 "entries in chanlist must all have the same gain\n");
740 static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
741 struct comedi_subdevice *s,
742 struct comedi_cmd *cmd)
744 const struct cb_pcidas_board *board = dev->board_ptr;
748 /* Step 1 : check if triggers are trivially valid */
750 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
751 err |= comedi_check_trigger_src(&cmd->scan_begin_src,
752 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
753 err |= comedi_check_trigger_src(&cmd->convert_src,
754 TRIG_TIMER | TRIG_NOW | TRIG_EXT);
755 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
756 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
761 /* Step 2a : make sure trigger sources are unique */
763 err |= comedi_check_trigger_is_unique(cmd->start_src);
764 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
765 err |= comedi_check_trigger_is_unique(cmd->convert_src);
766 err |= comedi_check_trigger_is_unique(cmd->stop_src);
768 /* Step 2b : and mutually compatible */
770 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
772 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
774 if (cmd->start_src == TRIG_EXT &&
775 (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))
781 /* Step 3: check if arguments are trivially valid */
783 switch (cmd->start_src) {
785 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
788 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
790 & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
791 cmd->start_arg &= ~(CR_FLAGS_MASK &
792 ~(CR_EDGE | CR_INVERT));
795 if (!board->is_1602 && (cmd->start_arg & CR_INVERT)) {
796 cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
802 if (cmd->scan_begin_src == TRIG_TIMER) {
803 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
808 if (cmd->convert_src == TRIG_TIMER) {
809 err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
813 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
816 if (cmd->stop_src == TRIG_COUNT)
817 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
819 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
824 /* step 4: fix up any arguments */
826 if (cmd->scan_begin_src == TRIG_TIMER) {
827 arg = cmd->scan_begin_arg;
828 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
829 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
831 if (cmd->convert_src == TRIG_TIMER) {
832 arg = cmd->convert_arg;
833 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
834 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
840 /* Step 5: check channel list if it exists */
841 if (cmd->chanlist && cmd->chanlist_len > 0)
842 err |= cb_pcidas_ai_check_chanlist(dev, s, cmd);
850 static int cb_pcidas_ai_cmd(struct comedi_device *dev,
851 struct comedi_subdevice *s)
853 const struct cb_pcidas_board *board = dev->board_ptr;
854 struct cb_pcidas_private *devpriv = dev->private;
855 struct comedi_async *async = s->async;
856 struct comedi_cmd *cmd = &async->cmd;
857 unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
861 /* make sure PCIDAS_CALIB_EN is disabled */
862 outw(0, devpriv->pcibar1 + PCIDAS_CALIB_REG);
863 /* initialize before settings pacer source and count values */
864 outw(PCIDAS_TRIG_SEL_NONE, devpriv->pcibar1 + PCIDAS_TRIG_REG);
866 outw(0, devpriv->pcibar2 + PCIDAS_AI_FIFO_CLR_REG);
868 /* set mux limits, gain and pacer source */
869 bits = PCIDAS_AI_FIRST(CR_CHAN(cmd->chanlist[0])) |
870 PCIDAS_AI_LAST(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
871 PCIDAS_AI_GAIN(range0);
872 /* set unipolar/bipolar */
873 if (comedi_range_is_unipolar(s, range0))
874 bits |= PCIDAS_AI_UNIP;
875 /* set singleended/differential */
876 if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
877 bits |= PCIDAS_AI_SE;
878 /* set pacer source */
879 if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
880 bits |= PCIDAS_AI_PACER_EXTP;
882 bits |= PCIDAS_AI_PACER_INT;
883 outw(bits, devpriv->pcibar1 + PCIDAS_AI_REG);
886 if (cmd->scan_begin_src == TRIG_TIMER ||
887 cmd->convert_src == TRIG_TIMER) {
888 comedi_8254_update_divisors(dev->pacer);
889 comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
892 /* enable interrupts */
893 spin_lock_irqsave(&dev->spinlock, flags);
894 devpriv->ctrl |= PCIDAS_CTRL_INTE;
895 devpriv->ctrl &= ~PCIDAS_CTRL_INT_MASK;
896 if (cmd->flags & CMDF_WAKE_EOS) {
897 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) {
898 /* interrupt end of burst */
899 devpriv->ctrl |= PCIDAS_CTRL_INT_EOS;
901 /* interrupt fifo not empty */
902 devpriv->ctrl |= PCIDAS_CTRL_INT_FNE;
905 /* interrupt fifo half full */
906 devpriv->ctrl |= PCIDAS_CTRL_INT_FHF;
909 /* enable (and clear) interrupts */
911 PCIDAS_CTRL_EOAI | PCIDAS_CTRL_INT_CLR | PCIDAS_CTRL_LADFUL,
912 devpriv->pcibar1 + PCIDAS_CTRL_REG);
913 spin_unlock_irqrestore(&dev->spinlock, flags);
915 /* set start trigger and burst mode */
917 if (cmd->start_src == TRIG_NOW) {
918 bits |= PCIDAS_TRIG_SEL_SW;
919 } else { /* TRIG_EXT */
920 bits |= PCIDAS_TRIG_SEL_EXT | PCIDAS_TRIG_EN | PCIDAS_TRIG_CLR;
921 if (board->is_1602) {
922 if (cmd->start_arg & CR_INVERT)
923 bits |= PCIDAS_TRIG_POL;
924 if (cmd->start_arg & CR_EDGE)
925 bits |= PCIDAS_TRIG_MODE;
928 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
929 bits |= PCIDAS_TRIG_BURSTE;
930 outw(bits, devpriv->pcibar1 + PCIDAS_TRIG_REG);
935 static int cb_pcidas_ao_check_chanlist(struct comedi_device *dev,
936 struct comedi_subdevice *s,
937 struct comedi_cmd *cmd)
939 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
941 if (cmd->chanlist_len > 1) {
942 unsigned int chan1 = CR_CHAN(cmd->chanlist[1]);
944 if (chan0 != 0 || chan1 != 1) {
945 dev_dbg(dev->class_dev,
946 "channels must be ordered channel 0, channel 1 in chanlist\n");
954 static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
955 struct comedi_subdevice *s,
956 struct comedi_cmd *cmd)
958 const struct cb_pcidas_board *board = dev->board_ptr;
959 struct cb_pcidas_private *devpriv = dev->private;
962 /* Step 1 : check if triggers are trivially valid */
964 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT);
965 err |= comedi_check_trigger_src(&cmd->scan_begin_src,
966 TRIG_TIMER | TRIG_EXT);
967 err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
968 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
969 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
974 /* Step 2a : make sure trigger sources are unique */
976 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
977 err |= comedi_check_trigger_is_unique(cmd->stop_src);
979 /* Step 2b : and mutually compatible */
984 /* Step 3: check if arguments are trivially valid */
986 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
988 if (cmd->scan_begin_src == TRIG_TIMER) {
989 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
990 board->ao_scan_speed);
993 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
996 if (cmd->stop_src == TRIG_COUNT)
997 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
999 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
1004 /* step 4: fix up any arguments */
1006 if (cmd->scan_begin_src == TRIG_TIMER) {
1007 unsigned int arg = cmd->scan_begin_arg;
1009 comedi_8254_cascade_ns_to_timer(devpriv->ao_pacer,
1011 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
1017 /* Step 5: check channel list if it exists */
1018 if (cmd->chanlist && cmd->chanlist_len > 0)
1019 err |= cb_pcidas_ao_check_chanlist(dev, s, cmd);
1027 /* cancel analog input command */
1028 static int cb_pcidas_cancel(struct comedi_device *dev,
1029 struct comedi_subdevice *s)
1031 struct cb_pcidas_private *devpriv = dev->private;
1032 unsigned long flags;
1034 spin_lock_irqsave(&dev->spinlock, flags);
1035 /* disable interrupts */
1036 devpriv->ctrl &= ~(PCIDAS_CTRL_INTE | PCIDAS_CTRL_EOAIE);
1037 outw(devpriv->ctrl, devpriv->pcibar1 + PCIDAS_CTRL_REG);
1038 spin_unlock_irqrestore(&dev->spinlock, flags);
1040 /* disable start trigger source and burst mode */
1041 outw(PCIDAS_TRIG_SEL_NONE, devpriv->pcibar1 + PCIDAS_TRIG_REG);
1042 outw(PCIDAS_AI_PACER_SW, devpriv->pcibar1 + PCIDAS_AI_REG);
1047 static void cb_pcidas_ao_load_fifo(struct comedi_device *dev,
1048 struct comedi_subdevice *s,
1049 unsigned int nsamples)
1051 struct cb_pcidas_private *devpriv = dev->private;
1052 unsigned int nbytes;
1054 nsamples = comedi_nsamples_left(s, nsamples);
1055 nbytes = comedi_buf_read_samples(s, devpriv->ao_buffer, nsamples);
1057 nsamples = comedi_bytes_to_samples(s, nbytes);
1058 outsw(devpriv->pcibar4 + PCIDAS_AO_FIFO_REG,
1059 devpriv->ao_buffer, nsamples);
1062 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1063 struct comedi_subdevice *s,
1064 unsigned int trig_num)
1066 const struct cb_pcidas_board *board = dev->board_ptr;
1067 struct cb_pcidas_private *devpriv = dev->private;
1068 struct comedi_async *async = s->async;
1069 struct comedi_cmd *cmd = &async->cmd;
1070 unsigned long flags;
1072 if (trig_num != cmd->start_arg)
1075 cb_pcidas_ao_load_fifo(dev, s, board->fifo_size);
1077 /* enable dac half-full and empty interrupts */
1078 spin_lock_irqsave(&dev->spinlock, flags);
1079 devpriv->ctrl |= PCIDAS_CTRL_DAEMIE | PCIDAS_CTRL_DAHFIE;
1081 /* enable and clear interrupts */
1082 outw(devpriv->ctrl | PCIDAS_CTRL_DAEMI | PCIDAS_CTRL_DAHFI,
1083 devpriv->pcibar1 + PCIDAS_CTRL_REG);
1086 devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1087 outw(devpriv->ao_control_bits, devpriv->pcibar1 + DAC_CSR);
1089 spin_unlock_irqrestore(&dev->spinlock, flags);
1091 async->inttrig = NULL;
1096 static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1097 struct comedi_subdevice *s)
1099 struct cb_pcidas_private *devpriv = dev->private;
1100 struct comedi_async *async = s->async;
1101 struct comedi_cmd *cmd = &async->cmd;
1103 unsigned long flags;
1105 /* set channel limits, gain */
1106 spin_lock_irqsave(&dev->spinlock, flags);
1107 for (i = 0; i < cmd->chanlist_len; i++) {
1108 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
1109 unsigned int range = CR_RANGE(cmd->chanlist[i]);
1111 /* enable channel */
1112 devpriv->ao_control_bits |= DAC_CHAN_EN(chan);
1114 devpriv->ao_control_bits |= DAC_RANGE(chan, range);
1117 /* disable analog out before settings pacer source and count values */
1118 outw(devpriv->ao_control_bits, devpriv->pcibar1 + DAC_CSR);
1119 spin_unlock_irqrestore(&dev->spinlock, flags);
1122 outw(0, devpriv->pcibar4 + PCIDAS_AO_FIFO_CLR_REG);
1125 if (cmd->scan_begin_src == TRIG_TIMER) {
1126 comedi_8254_update_divisors(devpriv->ao_pacer);
1127 comedi_8254_pacer_enable(devpriv->ao_pacer, 1, 2, true);
1130 /* set pacer source */
1131 spin_lock_irqsave(&dev->spinlock, flags);
1132 switch (cmd->scan_begin_src) {
1134 devpriv->ao_control_bits |= DAC_PACER_INT;
1137 devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1140 spin_unlock_irqrestore(&dev->spinlock, flags);
1141 dev_err(dev->class_dev, "error setting dac pacer source\n");
1144 spin_unlock_irqrestore(&dev->spinlock, flags);
1146 async->inttrig = cb_pcidas_ao_inttrig;
1151 /* cancel analog output command */
1152 static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1153 struct comedi_subdevice *s)
1155 struct cb_pcidas_private *devpriv = dev->private;
1156 unsigned long flags;
1158 spin_lock_irqsave(&dev->spinlock, flags);
1159 /* disable interrupts */
1160 devpriv->ctrl &= ~(PCIDAS_CTRL_DAHFIE | PCIDAS_CTRL_DAEMIE);
1161 outw(devpriv->ctrl, devpriv->pcibar1 + PCIDAS_CTRL_REG);
1163 /* disable output */
1164 devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1165 outw(devpriv->ao_control_bits, devpriv->pcibar1 + DAC_CSR);
1166 spin_unlock_irqrestore(&dev->spinlock, flags);
1171 static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
1173 const struct cb_pcidas_board *board = dev->board_ptr;
1174 struct cb_pcidas_private *devpriv = dev->private;
1175 struct comedi_subdevice *s = dev->write_subdev;
1176 struct comedi_async *async = s->async;
1177 struct comedi_cmd *cmd = &async->cmd;
1178 unsigned long flags;
1180 if (status & PCIDAS_CTRL_DAEMI) {
1181 /* clear dac empty interrupt latch */
1182 spin_lock_irqsave(&dev->spinlock, flags);
1183 outw(devpriv->ctrl | PCIDAS_CTRL_DAEMI,
1184 devpriv->pcibar1 + PCIDAS_CTRL_REG);
1185 spin_unlock_irqrestore(&dev->spinlock, flags);
1186 if (inw(devpriv->pcibar4 + DAC_CSR) & DAC_EMPTY) {
1187 if (cmd->stop_src == TRIG_COUNT &&
1188 async->scans_done >= cmd->stop_arg) {
1189 async->events |= COMEDI_CB_EOA;
1191 dev_err(dev->class_dev, "dac fifo underflow\n");
1192 async->events |= COMEDI_CB_ERROR;
1195 } else if (status & PCIDAS_CTRL_DAHFI) {
1196 cb_pcidas_ao_load_fifo(dev, s, board->fifo_size / 2);
1198 /* clear half-full interrupt latch */
1199 spin_lock_irqsave(&dev->spinlock, flags);
1200 outw(devpriv->ctrl | PCIDAS_CTRL_DAHFI,
1201 devpriv->pcibar1 + PCIDAS_CTRL_REG);
1202 spin_unlock_irqrestore(&dev->spinlock, flags);
1205 comedi_handle_events(dev, s);
1208 static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1210 struct comedi_device *dev = d;
1211 const struct cb_pcidas_board *board = dev->board_ptr;
1212 struct cb_pcidas_private *devpriv = dev->private;
1213 struct comedi_subdevice *s = dev->read_subdev;
1214 struct comedi_async *async;
1215 struct comedi_cmd *cmd;
1216 int status, s5933_status;
1217 int half_fifo = board->fifo_size / 2;
1218 unsigned int num_samples, i;
1219 static const int timeout = 10000;
1220 unsigned long flags;
1228 s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1230 if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
1233 /* make sure mailbox 4 is empty */
1234 inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1235 /* clear interrupt on amcc s5933 */
1236 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1237 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1239 status = inw(devpriv->pcibar1 + PCIDAS_CTRL_REG);
1241 /* check for analog output interrupt */
1242 if (status & (PCIDAS_CTRL_DAHFI | PCIDAS_CTRL_DAEMI))
1243 handle_ao_interrupt(dev, status);
1244 /* check for analog input interrupts */
1245 /* if fifo half-full */
1246 if (status & PCIDAS_CTRL_ADHFI) {
1248 num_samples = comedi_nsamples_left(s, half_fifo);
1249 insw(devpriv->pcibar2 + PCIDAS_AI_DATA_REG,
1250 devpriv->ai_buffer, num_samples);
1251 comedi_buf_write_samples(s, devpriv->ai_buffer, num_samples);
1253 if (cmd->stop_src == TRIG_COUNT &&
1254 async->scans_done >= cmd->stop_arg)
1255 async->events |= COMEDI_CB_EOA;
1257 /* clear half-full interrupt latch */
1258 spin_lock_irqsave(&dev->spinlock, flags);
1259 outw(devpriv->ctrl | PCIDAS_CTRL_INT_CLR,
1260 devpriv->pcibar1 + PCIDAS_CTRL_REG);
1261 spin_unlock_irqrestore(&dev->spinlock, flags);
1262 /* else if fifo not empty */
1263 } else if (status & (PCIDAS_CTRL_ADNEI | PCIDAS_CTRL_EOBI)) {
1264 for (i = 0; i < timeout; i++) {
1267 /* break if fifo is empty */
1268 if ((inw(devpriv->pcibar1 + PCIDAS_CTRL_REG) &
1269 PCIDAS_CTRL_ADNE) == 0)
1271 val = inw(devpriv->pcibar2 + PCIDAS_AI_DATA_REG);
1272 comedi_buf_write_samples(s, &val, 1);
1274 if (cmd->stop_src == TRIG_COUNT &&
1275 async->scans_done >= cmd->stop_arg) {
1276 async->events |= COMEDI_CB_EOA;
1280 /* clear not-empty interrupt latch */
1281 spin_lock_irqsave(&dev->spinlock, flags);
1282 outw(devpriv->ctrl | PCIDAS_CTRL_INT_CLR,
1283 devpriv->pcibar1 + PCIDAS_CTRL_REG);
1284 spin_unlock_irqrestore(&dev->spinlock, flags);
1285 } else if (status & PCIDAS_CTRL_EOAI) {
1286 dev_err(dev->class_dev,
1287 "bug! encountered end of acquisition interrupt?\n");
1288 /* clear EOA interrupt latch */
1289 spin_lock_irqsave(&dev->spinlock, flags);
1290 outw(devpriv->ctrl | PCIDAS_CTRL_EOAI,
1291 devpriv->pcibar1 + PCIDAS_CTRL_REG);
1292 spin_unlock_irqrestore(&dev->spinlock, flags);
1294 /* check for fifo overflow */
1295 if (status & PCIDAS_CTRL_LADFUL) {
1296 dev_err(dev->class_dev, "fifo overflow\n");
1297 /* clear overflow interrupt latch */
1298 spin_lock_irqsave(&dev->spinlock, flags);
1299 outw(devpriv->ctrl | PCIDAS_CTRL_LADFUL,
1300 devpriv->pcibar1 + PCIDAS_CTRL_REG);
1301 spin_unlock_irqrestore(&dev->spinlock, flags);
1302 async->events |= COMEDI_CB_ERROR;
1305 comedi_handle_events(dev, s);
1310 static int cb_pcidas_auto_attach(struct comedi_device *dev,
1311 unsigned long context)
1313 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1314 const struct cb_pcidas_board *board = NULL;
1315 struct cb_pcidas_private *devpriv;
1316 struct comedi_subdevice *s;
1320 if (context < ARRAY_SIZE(cb_pcidas_boards))
1321 board = &cb_pcidas_boards[context];
1324 dev->board_ptr = board;
1325 dev->board_name = board->name;
1327 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1331 ret = comedi_pci_enable(dev);
1335 devpriv->s5933_config = pci_resource_start(pcidev, 0);
1336 devpriv->pcibar1 = pci_resource_start(pcidev, 1);
1337 devpriv->pcibar2 = pci_resource_start(pcidev, 2);
1338 dev->iobase = pci_resource_start(pcidev, 3);
1340 devpriv->pcibar4 = pci_resource_start(pcidev, 4);
1342 /* disable and clear interrupts on amcc s5933 */
1343 outl(INTCSR_INBOX_INTR_STATUS,
1344 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1346 ret = request_irq(pcidev->irq, cb_pcidas_interrupt, IRQF_SHARED,
1347 dev->board_name, dev);
1349 dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
1353 dev->irq = pcidev->irq;
1355 dev->pacer = comedi_8254_init(dev->iobase + PCIDAS_AI_8254_BASE,
1356 I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
1360 devpriv->ao_pacer = comedi_8254_init(dev->iobase + PCIDAS_AO_8254_BASE,
1361 I8254_OSC_BASE_10MHZ,
1363 if (!devpriv->ao_pacer)
1366 ret = comedi_alloc_subdevices(dev, 7);
1370 s = &dev->subdevices[0];
1371 /* analog input subdevice */
1372 dev->read_subdev = s;
1373 s->type = COMEDI_SUBD_AI;
1374 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
1375 /* WARNING: Number of inputs in differential mode is ignored */
1377 s->len_chanlist = s->n_chan;
1378 s->maxdata = board->is_16bit ? 0xffff : 0x0fff;
1379 s->range_table = board->use_alt_range ? &cb_pcidas_alt_ranges
1380 : &cb_pcidas_ranges;
1381 s->insn_read = cb_pcidas_ai_rinsn;
1382 s->insn_config = ai_config_insn;
1383 s->do_cmd = cb_pcidas_ai_cmd;
1384 s->do_cmdtest = cb_pcidas_ai_cmdtest;
1385 s->cancel = cb_pcidas_cancel;
1387 /* analog output subdevice */
1388 s = &dev->subdevices[1];
1389 if (board->has_ao) {
1390 s->type = COMEDI_SUBD_AO;
1391 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1393 s->maxdata = board->is_16bit ? 0xffff : 0x0fff;
1394 s->range_table = &cb_pcidas_ao_ranges;
1395 /* default to no fifo (*insn_write) */
1396 s->insn_write = cb_pcidas_ao_nofifo_winsn;
1398 ret = comedi_alloc_subdev_readback(s);
1402 if (board->has_ao_fifo) {
1403 dev->write_subdev = s;
1404 s->subdev_flags |= SDF_CMD_WRITE;
1405 /* use fifo (*insn_write) instead */
1406 s->insn_write = cb_pcidas_ao_fifo_winsn;
1407 s->do_cmdtest = cb_pcidas_ao_cmdtest;
1408 s->do_cmd = cb_pcidas_ao_cmd;
1409 s->cancel = cb_pcidas_ao_cancel;
1412 s->type = COMEDI_SUBD_UNUSED;
1416 s = &dev->subdevices[2];
1417 ret = subdev_8255_init(dev, s, NULL, PCIDAS_8255_BASE);
1421 /* serial EEPROM, */
1422 s = &dev->subdevices[3];
1423 s->type = COMEDI_SUBD_MEMORY;
1424 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
1427 s->insn_read = eeprom_read_insn;
1430 s = &dev->subdevices[4];
1431 s->type = COMEDI_SUBD_CALIB;
1432 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1435 s->insn_write = cb_pcidas_caldac_insn_write;
1437 ret = comedi_alloc_subdev_readback(s);
1441 for (i = 0; i < s->n_chan; i++) {
1442 caldac_8800_write(dev, i, s->maxdata / 2);
1443 s->readback[i] = s->maxdata / 2;
1446 /* trim potentiometer */
1447 s = &dev->subdevices[5];
1448 s->type = COMEDI_SUBD_CALIB;
1449 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1450 if (board->trimpot == AD7376) {
1457 s->insn_write = cb_pcidas_trimpot_insn_write;
1459 ret = comedi_alloc_subdev_readback(s);
1463 for (i = 0; i < s->n_chan; i++) {
1464 cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
1465 s->readback[i] = s->maxdata / 2;
1469 s = &dev->subdevices[6];
1470 if (board->has_dac08) {
1471 s->type = COMEDI_SUBD_CALIB;
1472 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1475 s->insn_write = cb_pcidas_dac08_insn_write;
1477 ret = comedi_alloc_subdev_readback(s);
1481 for (i = 0; i < s->n_chan; i++) {
1482 dac08_write(dev, s->maxdata / 2);
1483 s->readback[i] = s->maxdata / 2;
1486 s->type = COMEDI_SUBD_UNUSED;
1489 /* make sure mailbox 4 is empty */
1490 inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1491 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1492 devpriv->s5933_intcsr_bits =
1493 INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1494 INTCSR_INBOX_FULL_INT;
1495 /* clear and enable interrupt on amcc s5933 */
1496 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1497 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1502 static void cb_pcidas_detach(struct comedi_device *dev)
1504 struct cb_pcidas_private *devpriv = dev->private;
1507 if (devpriv->s5933_config)
1508 outl(INTCSR_INBOX_INTR_STATUS,
1509 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1510 kfree(devpriv->ao_pacer);
1512 comedi_pci_detach(dev);
1515 static struct comedi_driver cb_pcidas_driver = {
1516 .driver_name = "cb_pcidas",
1517 .module = THIS_MODULE,
1518 .auto_attach = cb_pcidas_auto_attach,
1519 .detach = cb_pcidas_detach,
1522 static int cb_pcidas_pci_probe(struct pci_dev *dev,
1523 const struct pci_device_id *id)
1525 return comedi_pci_auto_config(dev, &cb_pcidas_driver,
1529 static const struct pci_device_id cb_pcidas_pci_table[] = {
1530 { PCI_VDEVICE(CB, 0x0001), BOARD_PCIDAS1602_16 },
1531 { PCI_VDEVICE(CB, 0x000f), BOARD_PCIDAS1200 },
1532 { PCI_VDEVICE(CB, 0x0010), BOARD_PCIDAS1602_12 },
1533 { PCI_VDEVICE(CB, 0x0019), BOARD_PCIDAS1200_JR },
1534 { PCI_VDEVICE(CB, 0x001c), BOARD_PCIDAS1602_16_JR },
1535 { PCI_VDEVICE(CB, 0x004c), BOARD_PCIDAS1000 },
1536 { PCI_VDEVICE(CB, 0x001a), BOARD_PCIDAS1001 },
1537 { PCI_VDEVICE(CB, 0x001b), BOARD_PCIDAS1002 },
1540 MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
1542 static struct pci_driver cb_pcidas_pci_driver = {
1543 .name = "cb_pcidas",
1544 .id_table = cb_pcidas_pci_table,
1545 .probe = cb_pcidas_pci_probe,
1546 .remove = comedi_pci_auto_unconfig,
1548 module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver);
1550 MODULE_AUTHOR("Comedi http://www.comedi.org");
1551 MODULE_DESCRIPTION("Comedi low-level driver");
1552 MODULE_LICENSE("GPL");