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_CTRL_AI_INT (PCIDAS_CTRL_EOAI | PCIDAS_CTRL_EOBI | \
101 PCIDAS_CTRL_ADHFI | PCIDAS_CTRL_ADNEI | \
103 #define PCIDAS_CTRL_AO_INT (PCIDAS_CTRL_DAHFI | PCIDAS_CTRL_DAEMI)
105 #define PCIDAS_AI_REG 0x02 /* ADC CHANNEL MUX AND CONTROL reg */
106 #define PCIDAS_AI_FIRST(x) ((x) & 0xf)
107 #define PCIDAS_AI_LAST(x) (((x) & 0xf) << 4)
108 #define PCIDAS_AI_CHAN(x) (PCIDAS_AI_FIRST(x) | PCIDAS_AI_LAST(x))
109 #define PCIDAS_AI_GAIN(x) (((x) & 0x3) << 8)
110 #define PCIDAS_AI_SE BIT(10) /* Inputs in single-ended mode */
111 #define PCIDAS_AI_UNIP BIT(11) /* Analog front-end unipolar mode */
112 #define PCIDAS_AI_PACER(x) (((x) & 0x3) << 12)
113 #define PCIDAS_AI_PACER_SW PCIDAS_AI_PACER(0) /* software pacer */
114 #define PCIDAS_AI_PACER_INT PCIDAS_AI_PACER(1) /* int. pacer */
115 #define PCIDAS_AI_PACER_EXTN PCIDAS_AI_PACER(2) /* ext. falling edge */
116 #define PCIDAS_AI_PACER_EXTP PCIDAS_AI_PACER(3) /* ext. rising edge */
117 #define PCIDAS_AI_PACER_MASK PCIDAS_AI_PACER(3) /* pacer source bits */
118 #define PCIDAS_AI_EOC BIT(14) /* adc not busy */
120 #define PCIDAS_TRIG_REG 0x04 /* TRIGGER CONTROL/STATUS register */
121 #define PCIDAS_TRIG_SEL(x) (((x) & 0x3) << 0)
122 #define PCIDAS_TRIG_SEL_NONE PCIDAS_TRIG_SEL(0) /* no start trigger */
123 #define PCIDAS_TRIG_SEL_SW PCIDAS_TRIG_SEL(1) /* software start trigger */
124 #define PCIDAS_TRIG_SEL_EXT PCIDAS_TRIG_SEL(2) /* ext. start trigger */
125 #define PCIDAS_TRIG_SEL_ANALOG PCIDAS_TRIG_SEL(3) /* ext. analog trigger */
126 #define PCIDAS_TRIG_SEL_MASK PCIDAS_TRIG_SEL(3) /* start trigger mask */
127 #define PCIDAS_TRIG_POL BIT(2) /* invert trigger (1602 only) */
128 #define PCIDAS_TRIG_MODE BIT(3) /* edge/level trigerred (1602 only) */
129 #define PCIDAS_TRIG_EN BIT(4) /* enable external start trigger */
130 #define PCIDAS_TRIG_BURSTE BIT(5) /* burst mode enable */
131 #define PCIDAS_TRIG_CLR BIT(7) /* clear external trigger */
133 #define PCIDAS_CALIB_REG 0x06 /* CALIBRATION register */
134 #define PCIDAS_CALIB_8800_SEL BIT(8) /* select 8800 caldac */
135 #define PCIDAS_CALIB_TRIM_SEL BIT(9) /* select ad7376 trim pot */
136 #define PCIDAS_CALIB_DAC08_SEL BIT(10) /* select dac08 caldac */
137 #define PCIDAS_CALIB_SRC(x) (((x) & 0x7) << 11)
138 #define PCIDAS_CALIB_EN BIT(14) /* calibration source enable */
139 #define PCIDAS_CALIB_DATA BIT(15) /* serial data bit going to caldac */
141 #define PCIDAS_AO_REG 0x08 /* dac control and status register */
142 #define PCIDAS_AO_EMPTY BIT(0) /* fifo empty, write clear (1602) */
143 #define PCIDAS_AO_DACEN BIT(1) /* dac enable */
144 #define PCIDAS_AO_START BIT(2) /* start/arm fifo (1602) */
145 #define PCIDAS_AO_PACER(x) (((x) & 0x3) << 3) /* (1602) */
146 #define PCIDAS_AO_PACER_SW PCIDAS_AO_PACER(0) /* software pacer */
147 #define PCIDAS_AO_PACER_INT PCIDAS_AO_PACER(1) /* int. pacer */
148 #define PCIDAS_AO_PACER_EXTN PCIDAS_AO_PACER(2) /* ext. falling edge */
149 #define PCIDAS_AO_PACER_EXTP PCIDAS_AO_PACER(3) /* ext. rising edge */
150 #define PCIDAS_AO_PACER_MASK PCIDAS_AO_PACER(3) /* pacer source bits */
151 #define PCIDAS_AO_CHAN_EN(c) BIT(5 + ((c) & 0x1))
152 #define PCIDAS_AO_CHAN_MASK (PCIDAS_AO_CHAN_EN(0) | PCIDAS_AO_CHAN_EN(1))
153 #define PCIDAS_AO_UPDATE_BOTH BIT(7) /* update both dacs */
154 #define PCIDAS_AO_RANGE(c, r) (((r) & 0x3) << (8 + 2 * ((c) & 0x1)))
155 #define PCIDAS_AO_RANGE_MASK(c) PCIDAS_AO_RANGE((c), 0x3)
158 * PCI BAR2 Register map (devpriv->pcibar2)
160 #define PCIDAS_AI_DATA_REG 0x00
161 #define PCIDAS_AI_FIFO_CLR_REG 0x02
164 * PCI BAR3 Register map (dev->iobase)
166 #define PCIDAS_AI_8254_BASE 0x00
167 #define PCIDAS_8255_BASE 0x04
168 #define PCIDAS_AO_8254_BASE 0x08
171 * PCI BAR4 Register map (devpriv->pcibar4)
173 #define PCIDAS_AO_DATA_REG(x) (0x00 + ((x) * 2))
174 #define PCIDAS_AO_FIFO_REG 0x00
175 #define PCIDAS_AO_FIFO_CLR_REG 0x02
177 /* analog input ranges for most boards */
178 static const struct comedi_lrange cb_pcidas_ranges = {
191 /* pci-das1001 input ranges */
192 static const struct comedi_lrange cb_pcidas_alt_ranges = {
205 /* analog output ranges */
206 static const struct comedi_lrange cb_pcidas_ao_ranges = {
215 enum cb_pcidas_boardid {
220 BOARD_PCIDAS1602_16_JR,
226 struct cb_pcidas_board {
228 int ai_speed; /* fastest conversion period in ns */
229 int ao_scan_speed; /* analog output scan speed for 1602 series */
230 int fifo_size; /* number of samples fifo can hold */
231 unsigned int is_16bit; /* ai/ao is 1=16-bit; 0=12-bit */
232 unsigned int use_alt_range:1; /* use alternate ai range table */
233 unsigned int has_ao:1; /* has 2 analog output channels */
234 unsigned int has_ao_fifo:1; /* analog output has fifo */
235 unsigned int has_ad8402:1; /* trimpot type 1=AD8402; 0=AD7376 */
236 unsigned int has_dac08:1;
237 unsigned int is_1602:1;
240 static const struct cb_pcidas_board cb_pcidas_boards[] = {
241 [BOARD_PCIDAS1602_16] = {
242 .name = "pci-das1602/16",
244 .ao_scan_speed = 10000,
253 [BOARD_PCIDAS1200] = {
254 .name = "pci-das1200",
259 [BOARD_PCIDAS1602_12] = {
260 .name = "pci-das1602/12",
262 .ao_scan_speed = 4000,
268 [BOARD_PCIDAS1200_JR] = {
269 .name = "pci-das1200/jr",
273 [BOARD_PCIDAS1602_16_JR] = {
274 .name = "pci-das1602/16/jr",
282 [BOARD_PCIDAS1000] = {
283 .name = "pci-das1000",
287 [BOARD_PCIDAS1001] = {
288 .name = "pci-das1001",
294 [BOARD_PCIDAS1002] = {
295 .name = "pci-das1002",
302 struct cb_pcidas_private {
303 struct comedi_8254 *ao_pacer;
305 unsigned long amcc; /* pcibar0 */
306 unsigned long pcibar1;
307 unsigned long pcibar2;
308 unsigned long pcibar4;
309 /* bits to write to registers */
311 unsigned int amcc_intcsr;
312 unsigned int ao_ctrl;
314 unsigned short ai_buffer[AI_BUFFER_SIZE];
315 unsigned short ao_buffer[AO_BUFFER_SIZE];
316 unsigned int calib_src;
319 static int cb_pcidas_ai_eoc(struct comedi_device *dev,
320 struct comedi_subdevice *s,
321 struct comedi_insn *insn,
322 unsigned long context)
324 struct cb_pcidas_private *devpriv = dev->private;
327 status = inw(devpriv->pcibar1 + PCIDAS_AI_REG);
328 if (status & PCIDAS_AI_EOC)
333 static int cb_pcidas_ai_insn_read(struct comedi_device *dev,
334 struct comedi_subdevice *s,
335 struct comedi_insn *insn,
338 struct cb_pcidas_private *devpriv = dev->private;
339 unsigned int chan = CR_CHAN(insn->chanspec);
340 unsigned int range = CR_RANGE(insn->chanspec);
341 unsigned int aref = CR_AREF(insn->chanspec);
346 /* enable calibration input if appropriate */
347 if (insn->chanspec & CR_ALT_SOURCE) {
348 outw(PCIDAS_CALIB_EN | PCIDAS_CALIB_SRC(devpriv->calib_src),
349 devpriv->pcibar1 + PCIDAS_CALIB_REG);
352 outw(0, devpriv->pcibar1 + PCIDAS_CALIB_REG);
355 /* set mux limits and gain */
356 bits = PCIDAS_AI_CHAN(chan) | PCIDAS_AI_GAIN(range);
357 /* set unipolar/bipolar */
358 if (comedi_range_is_unipolar(s, range))
359 bits |= PCIDAS_AI_UNIP;
360 /* set single-ended/differential */
361 if (aref != AREF_DIFF)
362 bits |= PCIDAS_AI_SE;
363 outw(bits, devpriv->pcibar1 + PCIDAS_AI_REG);
366 outw(0, devpriv->pcibar2 + PCIDAS_AI_FIFO_CLR_REG);
368 /* convert n samples */
369 for (n = 0; n < insn->n; n++) {
370 /* trigger conversion */
371 outw(0, devpriv->pcibar2 + PCIDAS_AI_DATA_REG);
373 /* wait for conversion to end */
374 ret = comedi_timeout(dev, s, insn, cb_pcidas_ai_eoc, 0);
379 data[n] = inw(devpriv->pcibar2 + PCIDAS_AI_DATA_REG);
382 /* return the number of samples read/written */
386 static int cb_pcidas_ai_insn_config(struct comedi_device *dev,
387 struct comedi_subdevice *s,
388 struct comedi_insn *insn,
391 struct cb_pcidas_private *devpriv = dev->private;
393 unsigned int source = data[1];
396 case INSN_CONFIG_ALT_SOURCE:
398 dev_err(dev->class_dev,
399 "invalid calibration source: %i\n",
403 devpriv->calib_src = source;
411 /* analog output insn for pcidas-1000 and 1200 series */
412 static int cb_pcidas_ao_nofifo_insn_write(struct comedi_device *dev,
413 struct comedi_subdevice *s,
414 struct comedi_insn *insn,
417 struct cb_pcidas_private *devpriv = dev->private;
418 unsigned int chan = CR_CHAN(insn->chanspec);
419 unsigned int range = CR_RANGE(insn->chanspec);
420 unsigned int val = s->readback[chan];
424 /* set channel and range */
425 spin_lock_irqsave(&dev->spinlock, flags);
426 devpriv->ao_ctrl &= ~(PCIDAS_AO_UPDATE_BOTH |
427 PCIDAS_AO_RANGE_MASK(chan));
428 devpriv->ao_ctrl |= PCIDAS_AO_DACEN | PCIDAS_AO_RANGE(chan, range);
429 outw(devpriv->ao_ctrl, devpriv->pcibar1 + PCIDAS_AO_REG);
430 spin_unlock_irqrestore(&dev->spinlock, flags);
432 for (i = 0; i < insn->n; i++) {
434 outw(val, devpriv->pcibar4 + PCIDAS_AO_DATA_REG(chan));
437 s->readback[chan] = val;
442 /* analog output insn for pcidas-1602 series */
443 static int cb_pcidas_ao_fifo_insn_write(struct comedi_device *dev,
444 struct comedi_subdevice *s,
445 struct comedi_insn *insn,
448 struct cb_pcidas_private *devpriv = dev->private;
449 unsigned int chan = CR_CHAN(insn->chanspec);
450 unsigned int range = CR_RANGE(insn->chanspec);
451 unsigned int val = s->readback[chan];
456 outw(0, devpriv->pcibar4 + PCIDAS_AO_FIFO_CLR_REG);
458 /* set channel and range */
459 spin_lock_irqsave(&dev->spinlock, flags);
460 devpriv->ao_ctrl &= ~(PCIDAS_AO_CHAN_MASK | PCIDAS_AO_RANGE_MASK(chan) |
461 PCIDAS_AO_PACER_MASK);
462 devpriv->ao_ctrl |= PCIDAS_AO_DACEN | PCIDAS_AO_RANGE(chan, range) |
463 PCIDAS_AO_CHAN_EN(chan) | PCIDAS_AO_START;
464 outw(devpriv->ao_ctrl, devpriv->pcibar1 + PCIDAS_AO_REG);
465 spin_unlock_irqrestore(&dev->spinlock, flags);
467 for (i = 0; i < insn->n; i++) {
469 outw(val, devpriv->pcibar4 + PCIDAS_AO_FIFO_REG);
472 s->readback[chan] = val;
477 static int cb_pcidas_eeprom_ready(struct comedi_device *dev,
478 struct comedi_subdevice *s,
479 struct comedi_insn *insn,
480 unsigned long context)
482 struct cb_pcidas_private *devpriv = dev->private;
485 status = inb(devpriv->amcc + AMCC_OP_REG_MCSR_NVCMD);
486 if ((status & MCSR_NV_BUSY) == 0)
491 static int cb_pcidas_eeprom_insn_read(struct comedi_device *dev,
492 struct comedi_subdevice *s,
493 struct comedi_insn *insn,
496 struct cb_pcidas_private *devpriv = dev->private;
497 unsigned int chan = CR_CHAN(insn->chanspec);
501 for (i = 0; i < insn->n; i++) {
502 /* make sure eeprom is ready */
503 ret = comedi_timeout(dev, s, insn, cb_pcidas_eeprom_ready, 0);
507 /* set address (chan) and read operation */
508 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
509 devpriv->amcc + AMCC_OP_REG_MCSR_NVCMD);
510 outb(chan & 0xff, devpriv->amcc + AMCC_OP_REG_MCSR_NVDATA);
511 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
512 devpriv->amcc + AMCC_OP_REG_MCSR_NVCMD);
513 outb((chan >> 8) & 0xff,
514 devpriv->amcc + AMCC_OP_REG_MCSR_NVDATA);
515 outb(MCSR_NV_ENABLE | MCSR_NV_READ,
516 devpriv->amcc + AMCC_OP_REG_MCSR_NVCMD);
518 /* wait for data to be returned */
519 ret = comedi_timeout(dev, s, insn, cb_pcidas_eeprom_ready, 0);
523 data[i] = inb(devpriv->amcc + AMCC_OP_REG_MCSR_NVDATA);
529 static void cb_pcidas_calib_write(struct comedi_device *dev,
530 unsigned int val, unsigned int len,
533 struct cb_pcidas_private *devpriv = dev->private;
534 unsigned int calib_bits;
537 calib_bits = PCIDAS_CALIB_EN | PCIDAS_CALIB_SRC(devpriv->calib_src);
540 calib_bits |= PCIDAS_CALIB_TRIM_SEL;
541 outw(calib_bits, devpriv->pcibar1 + PCIDAS_CALIB_REG);
544 /* write bitstream to calibration device */
545 for (bit = 1 << (len - 1); bit; bit >>= 1) {
547 calib_bits |= PCIDAS_CALIB_DATA;
549 calib_bits &= ~PCIDAS_CALIB_DATA;
551 outw(calib_bits, devpriv->pcibar1 + PCIDAS_CALIB_REG);
555 calib_bits = PCIDAS_CALIB_EN | PCIDAS_CALIB_SRC(devpriv->calib_src);
559 outw(calib_bits | PCIDAS_CALIB_8800_SEL,
560 devpriv->pcibar1 + PCIDAS_CALIB_REG);
564 /* latch value to trimpot/caldac */
565 outw(calib_bits, devpriv->pcibar1 + PCIDAS_CALIB_REG);
568 static int cb_pcidas_caldac_insn_write(struct comedi_device *dev,
569 struct comedi_subdevice *s,
570 struct comedi_insn *insn,
573 unsigned int chan = CR_CHAN(insn->chanspec);
576 unsigned int val = data[insn->n - 1];
578 if (s->readback[chan] != val) {
579 /* write 11-bit channel/value to caldac */
580 cb_pcidas_calib_write(dev, (chan << 8) | val, 11,
582 s->readback[chan] = val;
589 static void cb_pcidas_dac08_write(struct comedi_device *dev, unsigned int val)
591 struct cb_pcidas_private *devpriv = dev->private;
593 val |= PCIDAS_CALIB_EN | PCIDAS_CALIB_SRC(devpriv->calib_src);
595 /* latch the new value into the caldac */
596 outw(val, devpriv->pcibar1 + PCIDAS_CALIB_REG);
598 outw(val | PCIDAS_CALIB_DAC08_SEL,
599 devpriv->pcibar1 + PCIDAS_CALIB_REG);
601 outw(val, devpriv->pcibar1 + PCIDAS_CALIB_REG);
605 static int cb_pcidas_dac08_insn_write(struct comedi_device *dev,
606 struct comedi_subdevice *s,
607 struct comedi_insn *insn,
610 unsigned int chan = CR_CHAN(insn->chanspec);
613 unsigned int val = data[insn->n - 1];
615 if (s->readback[chan] != val) {
616 cb_pcidas_dac08_write(dev, val);
617 s->readback[chan] = val;
624 static void cb_pcidas_trimpot_write(struct comedi_device *dev,
625 unsigned int chan, unsigned int val)
627 const struct cb_pcidas_board *board = dev->board_ptr;
629 if (board->has_ad8402) {
630 /* write 10-bit channel/value to AD8402 trimpot */
631 cb_pcidas_calib_write(dev, (chan << 8) | val, 10, true);
633 /* write 7-bit value to AD7376 trimpot */
634 cb_pcidas_calib_write(dev, val, 7, true);
638 static int cb_pcidas_trimpot_insn_write(struct comedi_device *dev,
639 struct comedi_subdevice *s,
640 struct comedi_insn *insn,
643 unsigned int chan = CR_CHAN(insn->chanspec);
646 unsigned int val = data[insn->n - 1];
648 if (s->readback[chan] != val) {
649 cb_pcidas_trimpot_write(dev, chan, val);
650 s->readback[chan] = val;
657 static int cb_pcidas_ai_check_chanlist(struct comedi_device *dev,
658 struct comedi_subdevice *s,
659 struct comedi_cmd *cmd)
661 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
662 unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
665 for (i = 1; i < cmd->chanlist_len; i++) {
666 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
667 unsigned int range = CR_RANGE(cmd->chanlist[i]);
669 if (chan != (chan0 + i) % s->n_chan) {
670 dev_dbg(dev->class_dev,
671 "entries in chanlist must be consecutive channels, counting upwards\n");
675 if (range != range0) {
676 dev_dbg(dev->class_dev,
677 "entries in chanlist must all have the same gain\n");
684 static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
685 struct comedi_subdevice *s,
686 struct comedi_cmd *cmd)
688 const struct cb_pcidas_board *board = dev->board_ptr;
692 /* Step 1 : check if triggers are trivially valid */
694 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
695 err |= comedi_check_trigger_src(&cmd->scan_begin_src,
696 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
697 err |= comedi_check_trigger_src(&cmd->convert_src,
698 TRIG_TIMER | TRIG_NOW | TRIG_EXT);
699 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
700 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
705 /* Step 2a : make sure trigger sources are unique */
707 err |= comedi_check_trigger_is_unique(cmd->start_src);
708 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
709 err |= comedi_check_trigger_is_unique(cmd->convert_src);
710 err |= comedi_check_trigger_is_unique(cmd->stop_src);
712 /* Step 2b : and mutually compatible */
714 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
716 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
718 if (cmd->start_src == TRIG_EXT &&
719 (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))
725 /* Step 3: check if arguments are trivially valid */
727 switch (cmd->start_src) {
729 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
732 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
734 & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
735 cmd->start_arg &= ~(CR_FLAGS_MASK &
736 ~(CR_EDGE | CR_INVERT));
739 if (!board->is_1602 && (cmd->start_arg & CR_INVERT)) {
740 cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
746 if (cmd->scan_begin_src == TRIG_TIMER) {
747 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
752 if (cmd->convert_src == TRIG_TIMER) {
753 err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
757 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
760 if (cmd->stop_src == TRIG_COUNT)
761 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
763 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
768 /* step 4: fix up any arguments */
770 if (cmd->scan_begin_src == TRIG_TIMER) {
771 arg = cmd->scan_begin_arg;
772 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
773 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
775 if (cmd->convert_src == TRIG_TIMER) {
776 arg = cmd->convert_arg;
777 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
778 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
784 /* Step 5: check channel list if it exists */
785 if (cmd->chanlist && cmd->chanlist_len > 0)
786 err |= cb_pcidas_ai_check_chanlist(dev, s, cmd);
794 static int cb_pcidas_ai_cmd(struct comedi_device *dev,
795 struct comedi_subdevice *s)
797 const struct cb_pcidas_board *board = dev->board_ptr;
798 struct cb_pcidas_private *devpriv = dev->private;
799 struct comedi_async *async = s->async;
800 struct comedi_cmd *cmd = &async->cmd;
801 unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
805 /* make sure PCIDAS_CALIB_EN is disabled */
806 outw(0, devpriv->pcibar1 + PCIDAS_CALIB_REG);
807 /* initialize before settings pacer source and count values */
808 outw(PCIDAS_TRIG_SEL_NONE, devpriv->pcibar1 + PCIDAS_TRIG_REG);
810 outw(0, devpriv->pcibar2 + PCIDAS_AI_FIFO_CLR_REG);
812 /* set mux limits, gain and pacer source */
813 bits = PCIDAS_AI_FIRST(CR_CHAN(cmd->chanlist[0])) |
814 PCIDAS_AI_LAST(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
815 PCIDAS_AI_GAIN(range0);
816 /* set unipolar/bipolar */
817 if (comedi_range_is_unipolar(s, range0))
818 bits |= PCIDAS_AI_UNIP;
819 /* set singleended/differential */
820 if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
821 bits |= PCIDAS_AI_SE;
822 /* set pacer source */
823 if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
824 bits |= PCIDAS_AI_PACER_EXTP;
826 bits |= PCIDAS_AI_PACER_INT;
827 outw(bits, devpriv->pcibar1 + PCIDAS_AI_REG);
830 if (cmd->scan_begin_src == TRIG_TIMER ||
831 cmd->convert_src == TRIG_TIMER) {
832 comedi_8254_update_divisors(dev->pacer);
833 comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
836 /* enable interrupts */
837 spin_lock_irqsave(&dev->spinlock, flags);
838 devpriv->ctrl |= PCIDAS_CTRL_INTE;
839 devpriv->ctrl &= ~PCIDAS_CTRL_INT_MASK;
840 if (cmd->flags & CMDF_WAKE_EOS) {
841 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) {
842 /* interrupt end of burst */
843 devpriv->ctrl |= PCIDAS_CTRL_INT_EOS;
845 /* interrupt fifo not empty */
846 devpriv->ctrl |= PCIDAS_CTRL_INT_FNE;
849 /* interrupt fifo half full */
850 devpriv->ctrl |= PCIDAS_CTRL_INT_FHF;
853 /* enable (and clear) interrupts */
855 PCIDAS_CTRL_EOAI | PCIDAS_CTRL_INT_CLR | PCIDAS_CTRL_LADFUL,
856 devpriv->pcibar1 + PCIDAS_CTRL_REG);
857 spin_unlock_irqrestore(&dev->spinlock, flags);
859 /* set start trigger and burst mode */
861 if (cmd->start_src == TRIG_NOW) {
862 bits |= PCIDAS_TRIG_SEL_SW;
863 } else { /* TRIG_EXT */
864 bits |= PCIDAS_TRIG_SEL_EXT | PCIDAS_TRIG_EN | PCIDAS_TRIG_CLR;
865 if (board->is_1602) {
866 if (cmd->start_arg & CR_INVERT)
867 bits |= PCIDAS_TRIG_POL;
868 if (cmd->start_arg & CR_EDGE)
869 bits |= PCIDAS_TRIG_MODE;
872 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
873 bits |= PCIDAS_TRIG_BURSTE;
874 outw(bits, devpriv->pcibar1 + PCIDAS_TRIG_REG);
879 static int cb_pcidas_ao_check_chanlist(struct comedi_device *dev,
880 struct comedi_subdevice *s,
881 struct comedi_cmd *cmd)
883 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
885 if (cmd->chanlist_len > 1) {
886 unsigned int chan1 = CR_CHAN(cmd->chanlist[1]);
888 if (chan0 != 0 || chan1 != 1) {
889 dev_dbg(dev->class_dev,
890 "channels must be ordered channel 0, channel 1 in chanlist\n");
898 static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
899 struct comedi_subdevice *s,
900 struct comedi_cmd *cmd)
902 const struct cb_pcidas_board *board = dev->board_ptr;
903 struct cb_pcidas_private *devpriv = dev->private;
906 /* Step 1 : check if triggers are trivially valid */
908 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT);
909 err |= comedi_check_trigger_src(&cmd->scan_begin_src,
910 TRIG_TIMER | TRIG_EXT);
911 err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
912 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
913 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
918 /* Step 2a : make sure trigger sources are unique */
920 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
921 err |= comedi_check_trigger_is_unique(cmd->stop_src);
923 /* Step 2b : and mutually compatible */
928 /* Step 3: check if arguments are trivially valid */
930 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
932 if (cmd->scan_begin_src == TRIG_TIMER) {
933 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
934 board->ao_scan_speed);
937 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
940 if (cmd->stop_src == TRIG_COUNT)
941 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
943 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
948 /* step 4: fix up any arguments */
950 if (cmd->scan_begin_src == TRIG_TIMER) {
951 unsigned int arg = cmd->scan_begin_arg;
953 comedi_8254_cascade_ns_to_timer(devpriv->ao_pacer,
955 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
961 /* Step 5: check channel list if it exists */
962 if (cmd->chanlist && cmd->chanlist_len > 0)
963 err |= cb_pcidas_ao_check_chanlist(dev, s, cmd);
971 static int cb_pcidas_ai_cancel(struct comedi_device *dev,
972 struct comedi_subdevice *s)
974 struct cb_pcidas_private *devpriv = dev->private;
977 spin_lock_irqsave(&dev->spinlock, flags);
978 /* disable interrupts */
979 devpriv->ctrl &= ~(PCIDAS_CTRL_INTE | PCIDAS_CTRL_EOAIE);
980 outw(devpriv->ctrl, devpriv->pcibar1 + PCIDAS_CTRL_REG);
981 spin_unlock_irqrestore(&dev->spinlock, flags);
983 /* disable start trigger source and burst mode */
984 outw(PCIDAS_TRIG_SEL_NONE, devpriv->pcibar1 + PCIDAS_TRIG_REG);
985 outw(PCIDAS_AI_PACER_SW, devpriv->pcibar1 + PCIDAS_AI_REG);
990 static void cb_pcidas_ao_load_fifo(struct comedi_device *dev,
991 struct comedi_subdevice *s,
992 unsigned int nsamples)
994 struct cb_pcidas_private *devpriv = dev->private;
997 nsamples = comedi_nsamples_left(s, nsamples);
998 nbytes = comedi_buf_read_samples(s, devpriv->ao_buffer, nsamples);
1000 nsamples = comedi_bytes_to_samples(s, nbytes);
1001 outsw(devpriv->pcibar4 + PCIDAS_AO_FIFO_REG,
1002 devpriv->ao_buffer, nsamples);
1005 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1006 struct comedi_subdevice *s,
1007 unsigned int trig_num)
1009 const struct cb_pcidas_board *board = dev->board_ptr;
1010 struct cb_pcidas_private *devpriv = dev->private;
1011 struct comedi_async *async = s->async;
1012 struct comedi_cmd *cmd = &async->cmd;
1013 unsigned long flags;
1015 if (trig_num != cmd->start_arg)
1018 cb_pcidas_ao_load_fifo(dev, s, board->fifo_size);
1020 /* enable dac half-full and empty interrupts */
1021 spin_lock_irqsave(&dev->spinlock, flags);
1022 devpriv->ctrl |= PCIDAS_CTRL_DAEMIE | PCIDAS_CTRL_DAHFIE;
1024 /* enable and clear interrupts */
1025 outw(devpriv->ctrl | PCIDAS_CTRL_DAEMI | PCIDAS_CTRL_DAHFI,
1026 devpriv->pcibar1 + PCIDAS_CTRL_REG);
1029 devpriv->ao_ctrl |= PCIDAS_AO_START | PCIDAS_AO_DACEN | PCIDAS_AO_EMPTY;
1030 outw(devpriv->ao_ctrl, devpriv->pcibar1 + PCIDAS_AO_REG);
1032 spin_unlock_irqrestore(&dev->spinlock, flags);
1034 async->inttrig = NULL;
1039 static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1040 struct comedi_subdevice *s)
1042 struct cb_pcidas_private *devpriv = dev->private;
1043 struct comedi_async *async = s->async;
1044 struct comedi_cmd *cmd = &async->cmd;
1046 unsigned long flags;
1048 /* set channel limits, gain */
1049 spin_lock_irqsave(&dev->spinlock, flags);
1050 for (i = 0; i < cmd->chanlist_len; i++) {
1051 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
1052 unsigned int range = CR_RANGE(cmd->chanlist[i]);
1054 /* enable channel */
1055 devpriv->ao_ctrl |= PCIDAS_AO_CHAN_EN(chan);
1057 devpriv->ao_ctrl |= PCIDAS_AO_RANGE(chan, range);
1060 /* disable analog out before settings pacer source and count values */
1061 outw(devpriv->ao_ctrl, devpriv->pcibar1 + PCIDAS_AO_REG);
1062 spin_unlock_irqrestore(&dev->spinlock, flags);
1065 outw(0, devpriv->pcibar4 + PCIDAS_AO_FIFO_CLR_REG);
1068 if (cmd->scan_begin_src == TRIG_TIMER) {
1069 comedi_8254_update_divisors(devpriv->ao_pacer);
1070 comedi_8254_pacer_enable(devpriv->ao_pacer, 1, 2, true);
1073 /* set pacer source */
1074 spin_lock_irqsave(&dev->spinlock, flags);
1075 switch (cmd->scan_begin_src) {
1077 devpriv->ao_ctrl |= PCIDAS_AO_PACER_INT;
1080 devpriv->ao_ctrl |= PCIDAS_AO_PACER_EXTP;
1083 spin_unlock_irqrestore(&dev->spinlock, flags);
1084 dev_err(dev->class_dev, "error setting dac pacer source\n");
1087 spin_unlock_irqrestore(&dev->spinlock, flags);
1089 async->inttrig = cb_pcidas_ao_inttrig;
1094 static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1095 struct comedi_subdevice *s)
1097 struct cb_pcidas_private *devpriv = dev->private;
1098 unsigned long flags;
1100 spin_lock_irqsave(&dev->spinlock, flags);
1101 /* disable interrupts */
1102 devpriv->ctrl &= ~(PCIDAS_CTRL_DAHFIE | PCIDAS_CTRL_DAEMIE);
1103 outw(devpriv->ctrl, devpriv->pcibar1 + PCIDAS_CTRL_REG);
1105 /* disable output */
1106 devpriv->ao_ctrl &= ~(PCIDAS_AO_DACEN | PCIDAS_AO_PACER_MASK);
1107 outw(devpriv->ao_ctrl, devpriv->pcibar1 + PCIDAS_AO_REG);
1108 spin_unlock_irqrestore(&dev->spinlock, flags);
1113 static unsigned int cb_pcidas_ao_interrupt(struct comedi_device *dev,
1114 unsigned int status)
1116 const struct cb_pcidas_board *board = dev->board_ptr;
1117 struct cb_pcidas_private *devpriv = dev->private;
1118 struct comedi_subdevice *s = dev->write_subdev;
1119 struct comedi_async *async = s->async;
1120 struct comedi_cmd *cmd = &async->cmd;
1121 unsigned int irq_clr = 0;
1123 if (status & PCIDAS_CTRL_DAEMI) {
1124 irq_clr |= PCIDAS_CTRL_DAEMI;
1126 if (inw(devpriv->pcibar4 + PCIDAS_AO_REG) & PCIDAS_AO_EMPTY) {
1127 if (cmd->stop_src == TRIG_COUNT &&
1128 async->scans_done >= cmd->stop_arg) {
1129 async->events |= COMEDI_CB_EOA;
1131 dev_err(dev->class_dev, "dac fifo underflow\n");
1132 async->events |= COMEDI_CB_ERROR;
1135 } else if (status & PCIDAS_CTRL_DAHFI) {
1136 irq_clr |= PCIDAS_CTRL_DAHFI;
1138 cb_pcidas_ao_load_fifo(dev, s, board->fifo_size / 2);
1141 comedi_handle_events(dev, s);
1146 static unsigned int cb_pcidas_ai_interrupt(struct comedi_device *dev,
1147 unsigned int status)
1149 const struct cb_pcidas_board *board = dev->board_ptr;
1150 struct cb_pcidas_private *devpriv = dev->private;
1151 struct comedi_subdevice *s = dev->read_subdev;
1152 struct comedi_async *async = s->async;
1153 struct comedi_cmd *cmd = &async->cmd;
1154 unsigned int irq_clr = 0;
1156 if (status & PCIDAS_CTRL_ADHFI) {
1157 unsigned int num_samples;
1159 irq_clr |= PCIDAS_CTRL_INT_CLR;
1161 /* FIFO is half-full - read data */
1162 num_samples = comedi_nsamples_left(s, board->fifo_size / 2);
1163 insw(devpriv->pcibar2 + PCIDAS_AI_DATA_REG,
1164 devpriv->ai_buffer, num_samples);
1165 comedi_buf_write_samples(s, devpriv->ai_buffer, num_samples);
1167 if (cmd->stop_src == TRIG_COUNT &&
1168 async->scans_done >= cmd->stop_arg)
1169 async->events |= COMEDI_CB_EOA;
1170 } else if (status & (PCIDAS_CTRL_ADNEI | PCIDAS_CTRL_EOBI)) {
1173 irq_clr |= PCIDAS_CTRL_INT_CLR;
1175 /* FIFO is not empty - read data until empty or timeoout */
1176 for (i = 0; i < 10000; i++) {
1179 /* break if fifo is empty */
1180 if ((inw(devpriv->pcibar1 + PCIDAS_CTRL_REG) &
1181 PCIDAS_CTRL_ADNE) == 0)
1183 val = inw(devpriv->pcibar2 + PCIDAS_AI_DATA_REG);
1184 comedi_buf_write_samples(s, &val, 1);
1186 if (cmd->stop_src == TRIG_COUNT &&
1187 async->scans_done >= cmd->stop_arg) {
1188 async->events |= COMEDI_CB_EOA;
1192 } else if (status & PCIDAS_CTRL_EOAI) {
1193 irq_clr |= PCIDAS_CTRL_EOAI;
1195 dev_err(dev->class_dev,
1196 "bug! encountered end of acquisition interrupt?\n");
1199 /* check for fifo overflow */
1200 if (status & PCIDAS_CTRL_LADFUL) {
1201 irq_clr |= PCIDAS_CTRL_LADFUL;
1203 dev_err(dev->class_dev, "fifo overflow\n");
1204 async->events |= COMEDI_CB_ERROR;
1207 comedi_handle_events(dev, s);
1212 static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1214 struct comedi_device *dev = d;
1215 struct cb_pcidas_private *devpriv = dev->private;
1216 unsigned int irq_clr = 0;
1217 unsigned int amcc_status;
1218 unsigned int status;
1223 amcc_status = inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
1225 if ((INTCSR_INTR_ASSERTED & amcc_status) == 0)
1228 /* make sure mailbox 4 is empty */
1229 inl_p(devpriv->amcc + AMCC_OP_REG_IMB4);
1230 /* clear interrupt on amcc s5933 */
1231 outl(devpriv->amcc_intcsr | INTCSR_INBOX_INTR_STATUS,
1232 devpriv->amcc + AMCC_OP_REG_INTCSR);
1234 status = inw(devpriv->pcibar1 + PCIDAS_CTRL_REG);
1236 /* handle analog output interrupts */
1237 if (status & PCIDAS_CTRL_AO_INT)
1238 irq_clr |= cb_pcidas_ao_interrupt(dev, status);
1240 /* handle analog input interrupts */
1241 if (status & PCIDAS_CTRL_AI_INT)
1242 irq_clr |= cb_pcidas_ai_interrupt(dev, status);
1245 unsigned long flags;
1247 spin_lock_irqsave(&dev->spinlock, flags);
1248 outw(devpriv->ctrl | irq_clr,
1249 devpriv->pcibar1 + PCIDAS_CTRL_REG);
1250 spin_unlock_irqrestore(&dev->spinlock, flags);
1256 static int cb_pcidas_auto_attach(struct comedi_device *dev,
1257 unsigned long context)
1259 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1260 const struct cb_pcidas_board *board = NULL;
1261 struct cb_pcidas_private *devpriv;
1262 struct comedi_subdevice *s;
1266 if (context < ARRAY_SIZE(cb_pcidas_boards))
1267 board = &cb_pcidas_boards[context];
1270 dev->board_ptr = board;
1271 dev->board_name = board->name;
1273 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1277 ret = comedi_pci_enable(dev);
1281 devpriv->amcc = pci_resource_start(pcidev, 0);
1282 devpriv->pcibar1 = pci_resource_start(pcidev, 1);
1283 devpriv->pcibar2 = pci_resource_start(pcidev, 2);
1284 dev->iobase = pci_resource_start(pcidev, 3);
1286 devpriv->pcibar4 = pci_resource_start(pcidev, 4);
1288 /* disable and clear interrupts on amcc s5933 */
1289 outl(INTCSR_INBOX_INTR_STATUS,
1290 devpriv->amcc + AMCC_OP_REG_INTCSR);
1292 ret = request_irq(pcidev->irq, cb_pcidas_interrupt, IRQF_SHARED,
1293 dev->board_name, dev);
1295 dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
1299 dev->irq = pcidev->irq;
1301 dev->pacer = comedi_8254_init(dev->iobase + PCIDAS_AI_8254_BASE,
1302 I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
1306 devpriv->ao_pacer = comedi_8254_init(dev->iobase + PCIDAS_AO_8254_BASE,
1307 I8254_OSC_BASE_10MHZ,
1309 if (!devpriv->ao_pacer)
1312 ret = comedi_alloc_subdevices(dev, 7);
1316 /* Analog Input subdevice */
1317 s = &dev->subdevices[0];
1318 s->type = COMEDI_SUBD_AI;
1319 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
1321 s->maxdata = board->is_16bit ? 0xffff : 0x0fff;
1322 s->range_table = board->use_alt_range ? &cb_pcidas_alt_ranges
1323 : &cb_pcidas_ranges;
1324 s->insn_read = cb_pcidas_ai_insn_read;
1325 s->insn_config = cb_pcidas_ai_insn_config;
1327 dev->read_subdev = s;
1328 s->subdev_flags |= SDF_CMD_READ;
1329 s->len_chanlist = s->n_chan;
1330 s->do_cmd = cb_pcidas_ai_cmd;
1331 s->do_cmdtest = cb_pcidas_ai_cmdtest;
1332 s->cancel = cb_pcidas_ai_cancel;
1335 /* Analog Output subdevice */
1336 s = &dev->subdevices[1];
1337 if (board->has_ao) {
1338 s->type = COMEDI_SUBD_AO;
1339 s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
1341 s->maxdata = board->is_16bit ? 0xffff : 0x0fff;
1342 s->range_table = &cb_pcidas_ao_ranges;
1343 s->insn_write = (board->has_ao_fifo)
1344 ? cb_pcidas_ao_fifo_insn_write
1345 : cb_pcidas_ao_nofifo_insn_write;
1347 ret = comedi_alloc_subdev_readback(s);
1351 if (dev->irq && board->has_ao_fifo) {
1352 dev->write_subdev = s;
1353 s->subdev_flags |= SDF_CMD_WRITE;
1354 s->do_cmdtest = cb_pcidas_ao_cmdtest;
1355 s->do_cmd = cb_pcidas_ao_cmd;
1356 s->cancel = cb_pcidas_ao_cancel;
1359 s->type = COMEDI_SUBD_UNUSED;
1363 s = &dev->subdevices[2];
1364 ret = subdev_8255_init(dev, s, NULL, PCIDAS_8255_BASE);
1368 /* Memory subdevice - serial EEPROM */
1369 s = &dev->subdevices[3];
1370 s->type = COMEDI_SUBD_MEMORY;
1371 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
1374 s->insn_read = cb_pcidas_eeprom_insn_read;
1376 /* Calibration subdevice - 8800 caldac */
1377 s = &dev->subdevices[4];
1378 s->type = COMEDI_SUBD_CALIB;
1379 s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
1382 s->insn_write = cb_pcidas_caldac_insn_write;
1384 ret = comedi_alloc_subdev_readback(s);
1388 for (i = 0; i < s->n_chan; i++) {
1389 unsigned int val = s->maxdata / 2;
1391 /* write 11-bit channel/value to caldac */
1392 cb_pcidas_calib_write(dev, (i << 8) | val, 11, false);
1393 s->readback[i] = val;
1396 /* Calibration subdevice - trim potentiometer */
1397 s = &dev->subdevices[5];
1398 s->type = COMEDI_SUBD_CALIB;
1399 s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
1400 if (board->has_ad8402) {
1402 * pci-das1602/16 have an AD8402 trimpot:
1404 * chan 1 : adc postgain offset
1409 /* all other boards have an AD7376 trimpot */
1413 s->insn_write = cb_pcidas_trimpot_insn_write;
1415 ret = comedi_alloc_subdev_readback(s);
1419 for (i = 0; i < s->n_chan; i++) {
1420 cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
1421 s->readback[i] = s->maxdata / 2;
1424 /* Calibration subdevice - pci-das1602/16 pregain offset (dac08) */
1425 s = &dev->subdevices[6];
1426 if (board->has_dac08) {
1427 s->type = COMEDI_SUBD_CALIB;
1428 s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
1431 s->insn_write = cb_pcidas_dac08_insn_write;
1433 ret = comedi_alloc_subdev_readback(s);
1437 for (i = 0; i < s->n_chan; i++) {
1438 cb_pcidas_dac08_write(dev, s->maxdata / 2);
1439 s->readback[i] = s->maxdata / 2;
1442 s->type = COMEDI_SUBD_UNUSED;
1445 /* make sure mailbox 4 is empty */
1446 inl(devpriv->amcc + AMCC_OP_REG_IMB4);
1447 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1448 devpriv->amcc_intcsr = INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1449 INTCSR_INBOX_FULL_INT;
1450 /* clear and enable interrupt on amcc s5933 */
1451 outl(devpriv->amcc_intcsr | INTCSR_INBOX_INTR_STATUS,
1452 devpriv->amcc + AMCC_OP_REG_INTCSR);
1457 static void cb_pcidas_detach(struct comedi_device *dev)
1459 struct cb_pcidas_private *devpriv = dev->private;
1463 outl(INTCSR_INBOX_INTR_STATUS,
1464 devpriv->amcc + AMCC_OP_REG_INTCSR);
1465 kfree(devpriv->ao_pacer);
1467 comedi_pci_detach(dev);
1470 static struct comedi_driver cb_pcidas_driver = {
1471 .driver_name = "cb_pcidas",
1472 .module = THIS_MODULE,
1473 .auto_attach = cb_pcidas_auto_attach,
1474 .detach = cb_pcidas_detach,
1477 static int cb_pcidas_pci_probe(struct pci_dev *dev,
1478 const struct pci_device_id *id)
1480 return comedi_pci_auto_config(dev, &cb_pcidas_driver,
1484 static const struct pci_device_id cb_pcidas_pci_table[] = {
1485 { PCI_VDEVICE(CB, 0x0001), BOARD_PCIDAS1602_16 },
1486 { PCI_VDEVICE(CB, 0x000f), BOARD_PCIDAS1200 },
1487 { PCI_VDEVICE(CB, 0x0010), BOARD_PCIDAS1602_12 },
1488 { PCI_VDEVICE(CB, 0x0019), BOARD_PCIDAS1200_JR },
1489 { PCI_VDEVICE(CB, 0x001c), BOARD_PCIDAS1602_16_JR },
1490 { PCI_VDEVICE(CB, 0x004c), BOARD_PCIDAS1000 },
1491 { PCI_VDEVICE(CB, 0x001a), BOARD_PCIDAS1001 },
1492 { PCI_VDEVICE(CB, 0x001b), BOARD_PCIDAS1002 },
1495 MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
1497 static struct pci_driver cb_pcidas_pci_driver = {
1498 .name = "cb_pcidas",
1499 .id_table = cb_pcidas_pci_table,
1500 .probe = cb_pcidas_pci_probe,
1501 .remove = comedi_pci_auto_unconfig,
1503 module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver);
1505 MODULE_AUTHOR("Comedi http://www.comedi.org");
1506 MODULE_DESCRIPTION("Comedi driver for MeasurementComputing PCI-DAS series");
1507 MODULE_LICENSE("GPL");