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 INT_ADCFIFO 0 /* INTERRUPT / ADC FIFO register */
80 #define INT_EOS 0x1 /* int end of scan */
81 #define INT_FHF 0x2 /* int fifo half full */
82 #define INT_FNE 0x3 /* int fifo not empty */
83 #define INT_MASK 0x3 /* mask of int select bits */
84 #define INTE 0x4 /* int enable */
85 #define DAHFIE 0x8 /* dac half full int enable */
86 #define EOAIE 0x10 /* end of acq. int enable */
87 #define DAHFI 0x20 /* dac half full status / clear */
88 #define EOAI 0x40 /* end of acq. int status / clear */
89 #define INT 0x80 /* int status / clear */
90 #define EOBI 0x200 /* end of burst int status */
91 #define ADHFI 0x400 /* half-full int status */
92 #define ADNEI 0x800 /* fifo not empty int status (latch) */
93 #define ADNE 0x1000 /* fifo not empty status (realtime) */
94 #define DAEMIE 0x1000 /* dac empty int enable */
95 #define LADFUL 0x2000 /* fifo overflow / clear */
96 #define DAEMI 0x4000 /* dac fifo empty int status / clear */
98 #define ADCMUX_CONT 2 /* ADC CHANNEL MUX AND CONTROL reg */
99 #define BEGIN_SCAN(x) ((x) & 0xf)
100 #define END_SCAN(x) (((x) & 0xf) << 4)
101 #define GAIN_BITS(x) (((x) & 0x3) << 8)
102 #define UNIP 0x800 /* Analog front-end unipolar mode */
103 #define SE 0x400 /* Inputs in single-ended mode */
104 #define PACER_MASK 0x3000 /* pacer source bits */
105 #define PACER_INT 0x1000 /* int. pacer */
106 #define PACER_EXT_FALL 0x2000 /* ext. falling edge */
107 #define PACER_EXT_RISE 0x3000 /* ext. rising edge */
108 #define EOC 0x4000 /* adc not busy */
110 #define TRIG_CONTSTAT 4 /* TRIGGER CONTROL/STATUS register */
111 #define SW_TRIGGER 0x1 /* software start trigger */
112 #define EXT_TRIGGER 0x2 /* ext. start trigger */
113 #define ANALOG_TRIGGER 0x3 /* ext. analog trigger */
114 #define TRIGGER_MASK 0x3 /* start trigger mask */
115 #define TGPOL 0x04 /* invert trigger (1602 only) */
116 #define TGSEL 0x08 /* edge/level trigerred (1602 only) */
117 #define TGEN 0x10 /* enable external start trigger */
118 #define BURSTE 0x20 /* burst mode enable */
119 #define XTRCL 0x80 /* clear external trigger */
121 #define CALIBRATION_REG 6 /* CALIBRATION register */
122 #define SELECT_8800_BIT 0x100 /* select 8800 caldac */
123 #define SELECT_TRIMPOT_BIT 0x200 /* select ad7376 trim pot */
124 #define SELECT_DAC08_BIT 0x400 /* select dac08 caldac */
125 #define CAL_SRC_BITS(x) (((x) & 0x7) << 11)
126 #define CAL_EN_BIT 0x4000 /* calibration source enable */
127 #define SERIAL_DATA_IN_BIT 0x8000 /* serial data bit going to caldac */
129 #define DAC_CSR 0x8 /* dac control and status register */
130 #define DACEN 0x02 /* dac enable */
131 #define DAC_MODE_UPDATE_BOTH 0x80 /* update both dacs */
133 #define DAC_RANGE(c, r) (((r) & 0x3) << (8 + 2 * ((c) & 0x1)))
134 #define DAC_RANGE_MASK(c) DAC_RANGE((c), 0x3)
136 /* bits for 1602 series only */
137 #define DAC_EMPTY 0x1 /* fifo empty, read, write clear */
138 #define DAC_START 0x4 /* start/arm fifo operations */
139 #define DAC_PACER_MASK 0x18 /* bits that set pacer source */
140 #define DAC_PACER_INT 0x8 /* int. pacing */
141 #define DAC_PACER_EXT_FALL 0x10 /* ext. pacing, falling edge */
142 #define DAC_PACER_EXT_RISE 0x18 /* ext. pacing, rising edge */
144 #define DAC_CHAN_EN(c) BIT(5 + ((c) & 0x1))
147 * PCI BAR2 Register map (devpriv->pcibar2)
149 #define PCIDAS_AI_DATA_REG 0x00
150 #define PCIDAS_AI_FIFO_CLR_REG 0x02
153 * PCI BAR3 Register map (dev->iobase)
155 #define PCIDAS_AI_8254_BASE 0x00
156 #define PCIDAS_8255_BASE 0x04
157 #define PCIDAS_AO_8254_BASE 0x08
160 * PCI BAR4 Register map (devpriv->pcibar4)
162 #define PCIDAS_AO_DATA_REG(x) (0x00 + ((x) * 2))
163 #define PCIDAS_AO_FIFO_REG 0x00
164 #define PCIDAS_AO_FIFO_CLR_REG 0x02
166 /* analog input ranges for most boards */
167 static const struct comedi_lrange cb_pcidas_ranges
= {
180 /* pci-das1001 input ranges */
181 static const struct comedi_lrange cb_pcidas_alt_ranges
= {
194 /* analog output ranges */
195 static const struct comedi_lrange cb_pcidas_ao_ranges
= {
209 enum cb_pcidas_boardid
{
214 BOARD_PCIDAS1602_16_JR
,
220 struct cb_pcidas_board
{
222 int ai_speed
; /* fastest conversion period in ns */
223 int ao_scan_speed
; /* analog output scan speed for 1602 series */
224 int fifo_size
; /* number of samples fifo can hold */
225 enum trimpot_model trimpot
;
226 unsigned int is_16bit
; /* ai/ao is 1=16-bit; 0=12-bit */
227 unsigned int use_alt_range
:1; /* use alternate ai range table */
228 unsigned int has_ao
:1; /* has 2 analog output channels */
229 unsigned int has_ao_fifo
:1; /* analog output has fifo */
230 unsigned int has_dac08
:1;
231 unsigned int is_1602
:1;
234 static const struct cb_pcidas_board cb_pcidas_boards
[] = {
235 [BOARD_PCIDAS1602_16
] = {
236 .name
= "pci-das1602/16",
238 .ao_scan_speed
= 10000,
247 [BOARD_PCIDAS1200
] = {
248 .name
= "pci-das1200",
254 [BOARD_PCIDAS1602_12
] = {
255 .name
= "pci-das1602/12",
257 .ao_scan_speed
= 4000,
264 [BOARD_PCIDAS1200_JR
] = {
265 .name
= "pci-das1200/jr",
270 [BOARD_PCIDAS1602_16_JR
] = {
271 .name
= "pci-das1602/16/jr",
279 [BOARD_PCIDAS1000
] = {
280 .name
= "pci-das1000",
285 [BOARD_PCIDAS1001
] = {
286 .name
= "pci-das1001",
293 [BOARD_PCIDAS1002
] = {
294 .name
= "pci-das1002",
302 struct cb_pcidas_private
{
303 struct comedi_8254
*ao_pacer
;
305 unsigned long s5933_config
;
306 unsigned long pcibar1
;
307 unsigned long pcibar2
;
308 unsigned long pcibar4
;
309 /* bits to write to registers */
310 unsigned int adc_fifo_bits
;
311 unsigned int s5933_intcsr_bits
;
312 unsigned int ao_control_bits
;
314 unsigned short ai_buffer
[AI_BUFFER_SIZE
];
315 unsigned short ao_buffer
[AO_BUFFER_SIZE
];
316 unsigned int calibration_source
;
319 static inline unsigned int cal_enable_bits(struct comedi_device
*dev
)
321 struct cb_pcidas_private
*devpriv
= dev
->private;
323 return CAL_EN_BIT
| CAL_SRC_BITS(devpriv
->calibration_source
);
326 static int cb_pcidas_ai_eoc(struct comedi_device
*dev
,
327 struct comedi_subdevice
*s
,
328 struct comedi_insn
*insn
,
329 unsigned long context
)
331 struct cb_pcidas_private
*devpriv
= dev
->private;
334 status
= inw(devpriv
->pcibar1
+ ADCMUX_CONT
);
340 static int cb_pcidas_ai_rinsn(struct comedi_device
*dev
,
341 struct comedi_subdevice
*s
,
342 struct comedi_insn
*insn
, unsigned int *data
)
344 struct cb_pcidas_private
*devpriv
= dev
->private;
345 unsigned int chan
= CR_CHAN(insn
->chanspec
);
346 unsigned int range
= CR_RANGE(insn
->chanspec
);
347 unsigned int aref
= CR_AREF(insn
->chanspec
);
352 /* enable calibration input if appropriate */
353 if (insn
->chanspec
& CR_ALT_SOURCE
) {
354 outw(cal_enable_bits(dev
),
355 devpriv
->pcibar1
+ CALIBRATION_REG
);
358 outw(0, devpriv
->pcibar1
+ CALIBRATION_REG
);
361 /* set mux limits and gain */
362 bits
= BEGIN_SCAN(chan
) | END_SCAN(chan
) | GAIN_BITS(range
);
363 /* set unipolar/bipolar */
364 if (comedi_range_is_unipolar(s
, range
))
366 /* set single-ended/differential */
367 if (aref
!= AREF_DIFF
)
369 outw(bits
, devpriv
->pcibar1
+ ADCMUX_CONT
);
372 outw(0, devpriv
->pcibar2
+ PCIDAS_AI_FIFO_CLR_REG
);
374 /* convert n samples */
375 for (n
= 0; n
< insn
->n
; n
++) {
376 /* trigger conversion */
377 outw(0, devpriv
->pcibar2
+ PCIDAS_AI_DATA_REG
);
379 /* wait for conversion to end */
380 ret
= comedi_timeout(dev
, s
, insn
, cb_pcidas_ai_eoc
, 0);
385 data
[n
] = inw(devpriv
->pcibar2
+ PCIDAS_AI_DATA_REG
);
388 /* return the number of samples read/written */
392 static int ai_config_insn(struct comedi_device
*dev
, struct comedi_subdevice
*s
,
393 struct comedi_insn
*insn
, unsigned int *data
)
395 struct cb_pcidas_private
*devpriv
= dev
->private;
397 unsigned int source
= data
[1];
400 case INSN_CONFIG_ALT_SOURCE
:
402 dev_err(dev
->class_dev
,
403 "invalid calibration source: %i\n",
407 devpriv
->calibration_source
= source
;
415 /* analog output insn for pcidas-1000 and 1200 series */
416 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device
*dev
,
417 struct comedi_subdevice
*s
,
418 struct comedi_insn
*insn
,
421 struct cb_pcidas_private
*devpriv
= dev
->private;
422 unsigned int chan
= CR_CHAN(insn
->chanspec
);
423 unsigned int range
= CR_RANGE(insn
->chanspec
);
426 /* set channel and range */
427 spin_lock_irqsave(&dev
->spinlock
, flags
);
428 devpriv
->ao_control_bits
&= (~DAC_MODE_UPDATE_BOTH
&
429 ~DAC_RANGE_MASK(chan
));
430 devpriv
->ao_control_bits
|= (DACEN
| DAC_RANGE(chan
, range
));
431 outw(devpriv
->ao_control_bits
, devpriv
->pcibar1
+ DAC_CSR
);
432 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
434 /* remember value for readback */
435 s
->readback
[chan
] = data
[0];
438 outw(data
[0], devpriv
->pcibar4
+ PCIDAS_AO_DATA_REG(chan
));
443 /* analog output insn for pcidas-1602 series */
444 static int cb_pcidas_ao_fifo_winsn(struct comedi_device
*dev
,
445 struct comedi_subdevice
*s
,
446 struct comedi_insn
*insn
, unsigned int *data
)
448 struct cb_pcidas_private
*devpriv
= dev
->private;
449 unsigned int chan
= CR_CHAN(insn
->chanspec
);
450 unsigned int range
= CR_RANGE(insn
->chanspec
);
454 outw(0, devpriv
->pcibar4
+ PCIDAS_AO_FIFO_CLR_REG
);
456 /* set channel and range */
457 spin_lock_irqsave(&dev
->spinlock
, flags
);
458 devpriv
->ao_control_bits
&= (~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) &
459 ~DAC_RANGE_MASK(chan
) & ~DAC_PACER_MASK
);
460 devpriv
->ao_control_bits
|= (DACEN
| DAC_RANGE(chan
, range
) |
461 DAC_CHAN_EN(chan
) | DAC_START
);
462 outw(devpriv
->ao_control_bits
, devpriv
->pcibar1
+ DAC_CSR
);
463 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
465 /* remember value for readback */
466 s
->readback
[chan
] = data
[0];
469 outw(data
[0], devpriv
->pcibar4
+ PCIDAS_AO_FIFO_REG
);
474 static int wait_for_nvram_ready(unsigned long s5933_base_addr
)
476 static const int timeout
= 1000;
479 for (i
= 0; i
< timeout
; i
++) {
480 if ((inb(s5933_base_addr
+
481 AMCC_OP_REG_MCSR_NVCMD
) & MCSR_NV_BUSY
)
489 static int nvram_read(struct comedi_device
*dev
, unsigned int address
,
492 struct cb_pcidas_private
*devpriv
= dev
->private;
493 unsigned long iobase
= devpriv
->s5933_config
;
495 if (wait_for_nvram_ready(iobase
) < 0)
498 outb(MCSR_NV_ENABLE
| MCSR_NV_LOAD_LOW_ADDR
,
499 iobase
+ AMCC_OP_REG_MCSR_NVCMD
);
500 outb(address
& 0xff, iobase
+ AMCC_OP_REG_MCSR_NVDATA
);
501 outb(MCSR_NV_ENABLE
| MCSR_NV_LOAD_HIGH_ADDR
,
502 iobase
+ AMCC_OP_REG_MCSR_NVCMD
);
503 outb((address
>> 8) & 0xff, iobase
+ AMCC_OP_REG_MCSR_NVDATA
);
504 outb(MCSR_NV_ENABLE
| MCSR_NV_READ
, iobase
+ AMCC_OP_REG_MCSR_NVCMD
);
506 if (wait_for_nvram_ready(iobase
) < 0)
509 *data
= inb(iobase
+ AMCC_OP_REG_MCSR_NVDATA
);
514 static int eeprom_read_insn(struct comedi_device
*dev
,
515 struct comedi_subdevice
*s
,
516 struct comedi_insn
*insn
, unsigned int *data
)
521 retval
= nvram_read(dev
, CR_CHAN(insn
->chanspec
), &nvram_data
);
525 data
[0] = nvram_data
;
530 static void write_calibration_bitstream(struct comedi_device
*dev
,
531 unsigned int register_bits
,
532 unsigned int bitstream
,
533 unsigned int bitstream_length
)
535 struct cb_pcidas_private
*devpriv
= dev
->private;
536 static const int write_delay
= 1;
539 for (bit
= 1 << (bitstream_length
- 1); bit
; bit
>>= 1) {
541 register_bits
|= SERIAL_DATA_IN_BIT
;
543 register_bits
&= ~SERIAL_DATA_IN_BIT
;
545 outw(register_bits
, devpriv
->pcibar1
+ CALIBRATION_REG
);
549 static void caldac_8800_write(struct comedi_device
*dev
,
550 unsigned int chan
, uint8_t val
)
552 struct cb_pcidas_private
*devpriv
= dev
->private;
553 static const int bitstream_length
= 11;
554 unsigned int bitstream
= ((chan
& 0x7) << 8) | val
;
555 static const int caldac_8800_udelay
= 1;
557 write_calibration_bitstream(dev
, cal_enable_bits(dev
), bitstream
,
560 udelay(caldac_8800_udelay
);
561 outw(cal_enable_bits(dev
) | SELECT_8800_BIT
,
562 devpriv
->pcibar1
+ CALIBRATION_REG
);
563 udelay(caldac_8800_udelay
);
564 outw(cal_enable_bits(dev
), devpriv
->pcibar1
+ CALIBRATION_REG
);
567 static int cb_pcidas_caldac_insn_write(struct comedi_device
*dev
,
568 struct comedi_subdevice
*s
,
569 struct comedi_insn
*insn
,
572 unsigned int chan
= CR_CHAN(insn
->chanspec
);
575 unsigned int val
= data
[insn
->n
- 1];
577 if (s
->readback
[chan
] != val
) {
578 caldac_8800_write(dev
, chan
, val
);
579 s
->readback
[chan
] = val
;
586 /* 1602/16 pregain offset */
587 static void dac08_write(struct comedi_device
*dev
, unsigned int value
)
589 struct cb_pcidas_private
*devpriv
= dev
->private;
592 value
|= cal_enable_bits(dev
);
594 /* latch the new value into the caldac */
595 outw(value
, devpriv
->pcibar1
+ CALIBRATION_REG
);
597 outw(value
| SELECT_DAC08_BIT
,
598 devpriv
->pcibar1
+ CALIBRATION_REG
);
600 outw(value
, devpriv
->pcibar1
+ CALIBRATION_REG
);
604 static int cb_pcidas_dac08_insn_write(struct comedi_device
*dev
,
605 struct comedi_subdevice
*s
,
606 struct comedi_insn
*insn
,
609 unsigned int chan
= CR_CHAN(insn
->chanspec
);
612 unsigned int val
= data
[insn
->n
- 1];
614 if (s
->readback
[chan
] != val
) {
615 dac08_write(dev
, val
);
616 s
->readback
[chan
] = val
;
623 static int trimpot_7376_write(struct comedi_device
*dev
, uint8_t value
)
625 struct cb_pcidas_private
*devpriv
= dev
->private;
626 static const int bitstream_length
= 7;
627 unsigned int bitstream
= value
& 0x7f;
628 unsigned int register_bits
;
629 static const int ad7376_udelay
= 1;
631 register_bits
= cal_enable_bits(dev
) | SELECT_TRIMPOT_BIT
;
632 udelay(ad7376_udelay
);
633 outw(register_bits
, devpriv
->pcibar1
+ CALIBRATION_REG
);
635 write_calibration_bitstream(dev
, register_bits
, bitstream
,
638 udelay(ad7376_udelay
);
639 outw(cal_enable_bits(dev
), devpriv
->pcibar1
+ CALIBRATION_REG
);
646 * ch 1 : adc postgain offset */
647 static int trimpot_8402_write(struct comedi_device
*dev
, unsigned int channel
,
650 struct cb_pcidas_private
*devpriv
= dev
->private;
651 static const int bitstream_length
= 10;
652 unsigned int bitstream
= ((channel
& 0x3) << 8) | (value
& 0xff);
653 unsigned int register_bits
;
654 static const int ad8402_udelay
= 1;
656 register_bits
= cal_enable_bits(dev
) | SELECT_TRIMPOT_BIT
;
657 udelay(ad8402_udelay
);
658 outw(register_bits
, devpriv
->pcibar1
+ CALIBRATION_REG
);
660 write_calibration_bitstream(dev
, register_bits
, bitstream
,
663 udelay(ad8402_udelay
);
664 outw(cal_enable_bits(dev
), devpriv
->pcibar1
+ CALIBRATION_REG
);
669 static void cb_pcidas_trimpot_write(struct comedi_device
*dev
,
670 unsigned int chan
, unsigned int val
)
672 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
674 switch (board
->trimpot
) {
676 trimpot_7376_write(dev
, val
);
679 trimpot_8402_write(dev
, chan
, val
);
682 dev_err(dev
->class_dev
, "driver bug?\n");
687 static int cb_pcidas_trimpot_insn_write(struct comedi_device
*dev
,
688 struct comedi_subdevice
*s
,
689 struct comedi_insn
*insn
,
692 unsigned int chan
= CR_CHAN(insn
->chanspec
);
695 unsigned int val
= data
[insn
->n
- 1];
697 if (s
->readback
[chan
] != val
) {
698 cb_pcidas_trimpot_write(dev
, chan
, val
);
699 s
->readback
[chan
] = val
;
706 static int cb_pcidas_ai_check_chanlist(struct comedi_device
*dev
,
707 struct comedi_subdevice
*s
,
708 struct comedi_cmd
*cmd
)
710 unsigned int chan0
= CR_CHAN(cmd
->chanlist
[0]);
711 unsigned int range0
= CR_RANGE(cmd
->chanlist
[0]);
714 for (i
= 1; i
< cmd
->chanlist_len
; i
++) {
715 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
716 unsigned int range
= CR_RANGE(cmd
->chanlist
[i
]);
718 if (chan
!= (chan0
+ i
) % s
->n_chan
) {
719 dev_dbg(dev
->class_dev
,
720 "entries in chanlist must be consecutive channels, counting upwards\n");
724 if (range
!= range0
) {
725 dev_dbg(dev
->class_dev
,
726 "entries in chanlist must all have the same gain\n");
733 static int cb_pcidas_ai_cmdtest(struct comedi_device
*dev
,
734 struct comedi_subdevice
*s
,
735 struct comedi_cmd
*cmd
)
737 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
741 /* Step 1 : check if triggers are trivially valid */
743 err
|= comedi_check_trigger_src(&cmd
->start_src
, TRIG_NOW
| TRIG_EXT
);
744 err
|= comedi_check_trigger_src(&cmd
->scan_begin_src
,
745 TRIG_FOLLOW
| TRIG_TIMER
| TRIG_EXT
);
746 err
|= comedi_check_trigger_src(&cmd
->convert_src
,
747 TRIG_TIMER
| TRIG_NOW
| TRIG_EXT
);
748 err
|= comedi_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
749 err
|= comedi_check_trigger_src(&cmd
->stop_src
, TRIG_COUNT
| TRIG_NONE
);
754 /* Step 2a : make sure trigger sources are unique */
756 err
|= comedi_check_trigger_is_unique(cmd
->start_src
);
757 err
|= comedi_check_trigger_is_unique(cmd
->scan_begin_src
);
758 err
|= comedi_check_trigger_is_unique(cmd
->convert_src
);
759 err
|= comedi_check_trigger_is_unique(cmd
->stop_src
);
761 /* Step 2b : and mutually compatible */
763 if (cmd
->scan_begin_src
== TRIG_FOLLOW
&& cmd
->convert_src
== TRIG_NOW
)
765 if (cmd
->scan_begin_src
!= TRIG_FOLLOW
&& cmd
->convert_src
!= TRIG_NOW
)
767 if (cmd
->start_src
== TRIG_EXT
&&
768 (cmd
->convert_src
== TRIG_EXT
|| cmd
->scan_begin_src
== TRIG_EXT
))
774 /* Step 3: check if arguments are trivially valid */
776 switch (cmd
->start_src
) {
778 err
|= comedi_check_trigger_arg_is(&cmd
->start_arg
, 0);
781 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
783 & (CR_FLAGS_MASK
& ~(CR_EDGE
| CR_INVERT
))) != 0) {
784 cmd
->start_arg
&= ~(CR_FLAGS_MASK
&
785 ~(CR_EDGE
| CR_INVERT
));
788 if (!board
->is_1602
&& (cmd
->start_arg
& CR_INVERT
)) {
789 cmd
->start_arg
&= (CR_FLAGS_MASK
& ~CR_INVERT
);
795 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
796 err
|= comedi_check_trigger_arg_min(&cmd
->scan_begin_arg
,
801 if (cmd
->convert_src
== TRIG_TIMER
) {
802 err
|= comedi_check_trigger_arg_min(&cmd
->convert_arg
,
806 err
|= comedi_check_trigger_arg_is(&cmd
->scan_end_arg
,
809 if (cmd
->stop_src
== TRIG_COUNT
)
810 err
|= comedi_check_trigger_arg_min(&cmd
->stop_arg
, 1);
812 err
|= comedi_check_trigger_arg_is(&cmd
->stop_arg
, 0);
817 /* step 4: fix up any arguments */
819 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
820 arg
= cmd
->scan_begin_arg
;
821 comedi_8254_cascade_ns_to_timer(dev
->pacer
, &arg
, cmd
->flags
);
822 err
|= comedi_check_trigger_arg_is(&cmd
->scan_begin_arg
, arg
);
824 if (cmd
->convert_src
== TRIG_TIMER
) {
825 arg
= cmd
->convert_arg
;
826 comedi_8254_cascade_ns_to_timer(dev
->pacer
, &arg
, cmd
->flags
);
827 err
|= comedi_check_trigger_arg_is(&cmd
->convert_arg
, arg
);
833 /* Step 5: check channel list if it exists */
834 if (cmd
->chanlist
&& cmd
->chanlist_len
> 0)
835 err
|= cb_pcidas_ai_check_chanlist(dev
, s
, cmd
);
843 static int cb_pcidas_ai_cmd(struct comedi_device
*dev
,
844 struct comedi_subdevice
*s
)
846 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
847 struct cb_pcidas_private
*devpriv
= dev
->private;
848 struct comedi_async
*async
= s
->async
;
849 struct comedi_cmd
*cmd
= &async
->cmd
;
850 unsigned int range0
= CR_RANGE(cmd
->chanlist
[0]);
854 /* make sure CAL_EN_BIT is disabled */
855 outw(0, devpriv
->pcibar1
+ CALIBRATION_REG
);
856 /* initialize before settings pacer source and count values */
857 outw(0, devpriv
->pcibar1
+ TRIG_CONTSTAT
);
859 outw(0, devpriv
->pcibar2
+ PCIDAS_AI_FIFO_CLR_REG
);
861 /* set mux limits, gain and pacer source */
862 bits
= BEGIN_SCAN(CR_CHAN(cmd
->chanlist
[0])) |
863 END_SCAN(CR_CHAN(cmd
->chanlist
[cmd
->chanlist_len
- 1])) |
865 /* set unipolar/bipolar */
866 if (comedi_range_is_unipolar(s
, range0
))
868 /* set singleended/differential */
869 if (CR_AREF(cmd
->chanlist
[0]) != AREF_DIFF
)
871 /* set pacer source */
872 if (cmd
->convert_src
== TRIG_EXT
|| cmd
->scan_begin_src
== TRIG_EXT
)
873 bits
|= PACER_EXT_RISE
;
876 outw(bits
, devpriv
->pcibar1
+ ADCMUX_CONT
);
879 if (cmd
->scan_begin_src
== TRIG_TIMER
||
880 cmd
->convert_src
== TRIG_TIMER
) {
881 comedi_8254_update_divisors(dev
->pacer
);
882 comedi_8254_pacer_enable(dev
->pacer
, 1, 2, true);
885 /* enable interrupts */
886 spin_lock_irqsave(&dev
->spinlock
, flags
);
887 devpriv
->adc_fifo_bits
|= INTE
;
888 devpriv
->adc_fifo_bits
&= ~INT_MASK
;
889 if (cmd
->flags
& CMDF_WAKE_EOS
) {
890 if (cmd
->convert_src
== TRIG_NOW
&& cmd
->chanlist_len
> 1) {
891 /* interrupt end of burst */
892 devpriv
->adc_fifo_bits
|= INT_EOS
;
894 /* interrupt fifo not empty */
895 devpriv
->adc_fifo_bits
|= INT_FNE
;
898 /* interrupt fifo half full */
899 devpriv
->adc_fifo_bits
|= INT_FHF
;
902 /* enable (and clear) interrupts */
903 outw(devpriv
->adc_fifo_bits
| EOAI
| INT
| LADFUL
,
904 devpriv
->pcibar1
+ INT_ADCFIFO
);
905 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
907 /* set start trigger and burst mode */
909 if (cmd
->start_src
== TRIG_NOW
) {
911 } else { /* TRIG_EXT */
912 bits
|= EXT_TRIGGER
| TGEN
| XTRCL
;
913 if (board
->is_1602
) {
914 if (cmd
->start_arg
& CR_INVERT
)
916 if (cmd
->start_arg
& CR_EDGE
)
920 if (cmd
->convert_src
== TRIG_NOW
&& cmd
->chanlist_len
> 1)
922 outw(bits
, devpriv
->pcibar1
+ TRIG_CONTSTAT
);
927 static int cb_pcidas_ao_check_chanlist(struct comedi_device
*dev
,
928 struct comedi_subdevice
*s
,
929 struct comedi_cmd
*cmd
)
931 unsigned int chan0
= CR_CHAN(cmd
->chanlist
[0]);
933 if (cmd
->chanlist_len
> 1) {
934 unsigned int chan1
= CR_CHAN(cmd
->chanlist
[1]);
936 if (chan0
!= 0 || chan1
!= 1) {
937 dev_dbg(dev
->class_dev
,
938 "channels must be ordered channel 0, channel 1 in chanlist\n");
946 static int cb_pcidas_ao_cmdtest(struct comedi_device
*dev
,
947 struct comedi_subdevice
*s
,
948 struct comedi_cmd
*cmd
)
950 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
951 struct cb_pcidas_private
*devpriv
= dev
->private;
954 /* Step 1 : check if triggers are trivially valid */
956 err
|= comedi_check_trigger_src(&cmd
->start_src
, TRIG_INT
);
957 err
|= comedi_check_trigger_src(&cmd
->scan_begin_src
,
958 TRIG_TIMER
| TRIG_EXT
);
959 err
|= comedi_check_trigger_src(&cmd
->convert_src
, TRIG_NOW
);
960 err
|= comedi_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
961 err
|= comedi_check_trigger_src(&cmd
->stop_src
, TRIG_COUNT
| TRIG_NONE
);
966 /* Step 2a : make sure trigger sources are unique */
968 err
|= comedi_check_trigger_is_unique(cmd
->scan_begin_src
);
969 err
|= comedi_check_trigger_is_unique(cmd
->stop_src
);
971 /* Step 2b : and mutually compatible */
976 /* Step 3: check if arguments are trivially valid */
978 err
|= comedi_check_trigger_arg_is(&cmd
->start_arg
, 0);
980 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
981 err
|= comedi_check_trigger_arg_min(&cmd
->scan_begin_arg
,
982 board
->ao_scan_speed
);
985 err
|= comedi_check_trigger_arg_is(&cmd
->scan_end_arg
,
988 if (cmd
->stop_src
== TRIG_COUNT
)
989 err
|= comedi_check_trigger_arg_min(&cmd
->stop_arg
, 1);
991 err
|= comedi_check_trigger_arg_is(&cmd
->stop_arg
, 0);
996 /* step 4: fix up any arguments */
998 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
999 unsigned int arg
= cmd
->scan_begin_arg
;
1001 comedi_8254_cascade_ns_to_timer(devpriv
->ao_pacer
,
1003 err
|= comedi_check_trigger_arg_is(&cmd
->scan_begin_arg
, arg
);
1009 /* Step 5: check channel list if it exists */
1010 if (cmd
->chanlist
&& cmd
->chanlist_len
> 0)
1011 err
|= cb_pcidas_ao_check_chanlist(dev
, s
, cmd
);
1019 /* cancel analog input command */
1020 static int cb_pcidas_cancel(struct comedi_device
*dev
,
1021 struct comedi_subdevice
*s
)
1023 struct cb_pcidas_private
*devpriv
= dev
->private;
1024 unsigned long flags
;
1026 spin_lock_irqsave(&dev
->spinlock
, flags
);
1027 /* disable interrupts */
1028 devpriv
->adc_fifo_bits
&= ~INTE
& ~EOAIE
;
1029 outw(devpriv
->adc_fifo_bits
, devpriv
->pcibar1
+ INT_ADCFIFO
);
1030 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1032 /* disable start trigger source and burst mode */
1033 outw(0, devpriv
->pcibar1
+ TRIG_CONTSTAT
);
1034 /* software pacer source */
1035 outw(0, devpriv
->pcibar1
+ ADCMUX_CONT
);
1040 static void cb_pcidas_ao_load_fifo(struct comedi_device
*dev
,
1041 struct comedi_subdevice
*s
,
1042 unsigned int nsamples
)
1044 struct cb_pcidas_private
*devpriv
= dev
->private;
1045 unsigned int nbytes
;
1047 nsamples
= comedi_nsamples_left(s
, nsamples
);
1048 nbytes
= comedi_buf_read_samples(s
, devpriv
->ao_buffer
, nsamples
);
1050 nsamples
= comedi_bytes_to_samples(s
, nbytes
);
1051 outsw(devpriv
->pcibar4
+ PCIDAS_AO_FIFO_REG
,
1052 devpriv
->ao_buffer
, nsamples
);
1055 static int cb_pcidas_ao_inttrig(struct comedi_device
*dev
,
1056 struct comedi_subdevice
*s
,
1057 unsigned int trig_num
)
1059 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
1060 struct cb_pcidas_private
*devpriv
= dev
->private;
1061 struct comedi_async
*async
= s
->async
;
1062 struct comedi_cmd
*cmd
= &async
->cmd
;
1063 unsigned long flags
;
1065 if (trig_num
!= cmd
->start_arg
)
1068 cb_pcidas_ao_load_fifo(dev
, s
, board
->fifo_size
);
1070 /* enable dac half-full and empty interrupts */
1071 spin_lock_irqsave(&dev
->spinlock
, flags
);
1072 devpriv
->adc_fifo_bits
|= DAEMIE
| DAHFIE
;
1074 /* enable and clear interrupts */
1075 outw(devpriv
->adc_fifo_bits
| DAEMI
| DAHFI
,
1076 devpriv
->pcibar1
+ INT_ADCFIFO
);
1079 devpriv
->ao_control_bits
|= DAC_START
| DACEN
| DAC_EMPTY
;
1080 outw(devpriv
->ao_control_bits
, devpriv
->pcibar1
+ DAC_CSR
);
1082 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1084 async
->inttrig
= NULL
;
1089 static int cb_pcidas_ao_cmd(struct comedi_device
*dev
,
1090 struct comedi_subdevice
*s
)
1092 struct cb_pcidas_private
*devpriv
= dev
->private;
1093 struct comedi_async
*async
= s
->async
;
1094 struct comedi_cmd
*cmd
= &async
->cmd
;
1096 unsigned long flags
;
1098 /* set channel limits, gain */
1099 spin_lock_irqsave(&dev
->spinlock
, flags
);
1100 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
1101 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
1102 unsigned int range
= CR_RANGE(cmd
->chanlist
[i
]);
1104 /* enable channel */
1105 devpriv
->ao_control_bits
|= DAC_CHAN_EN(chan
);
1107 devpriv
->ao_control_bits
|= DAC_RANGE(chan
, range
);
1110 /* disable analog out before settings pacer source and count values */
1111 outw(devpriv
->ao_control_bits
, devpriv
->pcibar1
+ DAC_CSR
);
1112 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1115 outw(0, devpriv
->pcibar4
+ PCIDAS_AO_FIFO_CLR_REG
);
1118 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
1119 comedi_8254_update_divisors(devpriv
->ao_pacer
);
1120 comedi_8254_pacer_enable(devpriv
->ao_pacer
, 1, 2, true);
1123 /* set pacer source */
1124 spin_lock_irqsave(&dev
->spinlock
, flags
);
1125 switch (cmd
->scan_begin_src
) {
1127 devpriv
->ao_control_bits
|= DAC_PACER_INT
;
1130 devpriv
->ao_control_bits
|= DAC_PACER_EXT_RISE
;
1133 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1134 dev_err(dev
->class_dev
, "error setting dac pacer source\n");
1137 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1139 async
->inttrig
= cb_pcidas_ao_inttrig
;
1144 /* cancel analog output command */
1145 static int cb_pcidas_ao_cancel(struct comedi_device
*dev
,
1146 struct comedi_subdevice
*s
)
1148 struct cb_pcidas_private
*devpriv
= dev
->private;
1149 unsigned long flags
;
1151 spin_lock_irqsave(&dev
->spinlock
, flags
);
1152 /* disable interrupts */
1153 devpriv
->adc_fifo_bits
&= ~DAHFIE
& ~DAEMIE
;
1154 outw(devpriv
->adc_fifo_bits
, devpriv
->pcibar1
+ INT_ADCFIFO
);
1156 /* disable output */
1157 devpriv
->ao_control_bits
&= ~DACEN
& ~DAC_PACER_MASK
;
1158 outw(devpriv
->ao_control_bits
, devpriv
->pcibar1
+ DAC_CSR
);
1159 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1164 static void handle_ao_interrupt(struct comedi_device
*dev
, unsigned int status
)
1166 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
1167 struct cb_pcidas_private
*devpriv
= dev
->private;
1168 struct comedi_subdevice
*s
= dev
->write_subdev
;
1169 struct comedi_async
*async
= s
->async
;
1170 struct comedi_cmd
*cmd
= &async
->cmd
;
1171 unsigned long flags
;
1173 if (status
& DAEMI
) {
1174 /* clear dac empty interrupt latch */
1175 spin_lock_irqsave(&dev
->spinlock
, flags
);
1176 outw(devpriv
->adc_fifo_bits
| DAEMI
,
1177 devpriv
->pcibar1
+ INT_ADCFIFO
);
1178 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1179 if (inw(devpriv
->pcibar4
+ DAC_CSR
) & DAC_EMPTY
) {
1180 if (cmd
->stop_src
== TRIG_COUNT
&&
1181 async
->scans_done
>= cmd
->stop_arg
) {
1182 async
->events
|= COMEDI_CB_EOA
;
1184 dev_err(dev
->class_dev
, "dac fifo underflow\n");
1185 async
->events
|= COMEDI_CB_ERROR
;
1188 } else if (status
& DAHFI
) {
1189 cb_pcidas_ao_load_fifo(dev
, s
, board
->fifo_size
/ 2);
1191 /* clear half-full interrupt latch */
1192 spin_lock_irqsave(&dev
->spinlock
, flags
);
1193 outw(devpriv
->adc_fifo_bits
| DAHFI
,
1194 devpriv
->pcibar1
+ INT_ADCFIFO
);
1195 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1198 comedi_handle_events(dev
, s
);
1201 static irqreturn_t
cb_pcidas_interrupt(int irq
, void *d
)
1203 struct comedi_device
*dev
= d
;
1204 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
1205 struct cb_pcidas_private
*devpriv
= dev
->private;
1206 struct comedi_subdevice
*s
= dev
->read_subdev
;
1207 struct comedi_async
*async
;
1208 struct comedi_cmd
*cmd
;
1209 int status
, s5933_status
;
1210 int half_fifo
= board
->fifo_size
/ 2;
1211 unsigned int num_samples
, i
;
1212 static const int timeout
= 10000;
1213 unsigned long flags
;
1221 s5933_status
= inl(devpriv
->s5933_config
+ AMCC_OP_REG_INTCSR
);
1223 if ((INTCSR_INTR_ASSERTED
& s5933_status
) == 0)
1226 /* make sure mailbox 4 is empty */
1227 inl_p(devpriv
->s5933_config
+ AMCC_OP_REG_IMB4
);
1228 /* clear interrupt on amcc s5933 */
1229 outl(devpriv
->s5933_intcsr_bits
| INTCSR_INBOX_INTR_STATUS
,
1230 devpriv
->s5933_config
+ AMCC_OP_REG_INTCSR
);
1232 status
= inw(devpriv
->pcibar1
+ INT_ADCFIFO
);
1234 /* check for analog output interrupt */
1235 if (status
& (DAHFI
| DAEMI
))
1236 handle_ao_interrupt(dev
, status
);
1237 /* check for analog input interrupts */
1238 /* if fifo half-full */
1239 if (status
& ADHFI
) {
1241 num_samples
= comedi_nsamples_left(s
, half_fifo
);
1242 insw(devpriv
->pcibar2
+ PCIDAS_AI_DATA_REG
,
1243 devpriv
->ai_buffer
, num_samples
);
1244 comedi_buf_write_samples(s
, devpriv
->ai_buffer
, num_samples
);
1246 if (cmd
->stop_src
== TRIG_COUNT
&&
1247 async
->scans_done
>= cmd
->stop_arg
)
1248 async
->events
|= COMEDI_CB_EOA
;
1250 /* clear half-full interrupt latch */
1251 spin_lock_irqsave(&dev
->spinlock
, flags
);
1252 outw(devpriv
->adc_fifo_bits
| INT
,
1253 devpriv
->pcibar1
+ INT_ADCFIFO
);
1254 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1255 /* else if fifo not empty */
1256 } else if (status
& (ADNEI
| EOBI
)) {
1257 for (i
= 0; i
< timeout
; i
++) {
1260 /* break if fifo is empty */
1261 if ((ADNE
& inw(devpriv
->pcibar1
+
1264 val
= inw(devpriv
->pcibar2
+ PCIDAS_AI_DATA_REG
);
1265 comedi_buf_write_samples(s
, &val
, 1);
1267 if (cmd
->stop_src
== TRIG_COUNT
&&
1268 async
->scans_done
>= cmd
->stop_arg
) {
1269 async
->events
|= COMEDI_CB_EOA
;
1273 /* clear not-empty interrupt latch */
1274 spin_lock_irqsave(&dev
->spinlock
, flags
);
1275 outw(devpriv
->adc_fifo_bits
| INT
,
1276 devpriv
->pcibar1
+ INT_ADCFIFO
);
1277 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1278 } else if (status
& EOAI
) {
1279 dev_err(dev
->class_dev
,
1280 "bug! encountered end of acquisition interrupt?\n");
1281 /* clear EOA interrupt latch */
1282 spin_lock_irqsave(&dev
->spinlock
, flags
);
1283 outw(devpriv
->adc_fifo_bits
| EOAI
,
1284 devpriv
->pcibar1
+ INT_ADCFIFO
);
1285 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1287 /* check for fifo overflow */
1288 if (status
& LADFUL
) {
1289 dev_err(dev
->class_dev
, "fifo overflow\n");
1290 /* clear overflow interrupt latch */
1291 spin_lock_irqsave(&dev
->spinlock
, flags
);
1292 outw(devpriv
->adc_fifo_bits
| LADFUL
,
1293 devpriv
->pcibar1
+ INT_ADCFIFO
);
1294 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1295 async
->events
|= COMEDI_CB_ERROR
;
1298 comedi_handle_events(dev
, s
);
1303 static int cb_pcidas_auto_attach(struct comedi_device
*dev
,
1304 unsigned long context
)
1306 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
1307 const struct cb_pcidas_board
*board
= NULL
;
1308 struct cb_pcidas_private
*devpriv
;
1309 struct comedi_subdevice
*s
;
1313 if (context
< ARRAY_SIZE(cb_pcidas_boards
))
1314 board
= &cb_pcidas_boards
[context
];
1317 dev
->board_ptr
= board
;
1318 dev
->board_name
= board
->name
;
1320 devpriv
= comedi_alloc_devpriv(dev
, sizeof(*devpriv
));
1324 ret
= comedi_pci_enable(dev
);
1328 devpriv
->s5933_config
= pci_resource_start(pcidev
, 0);
1329 devpriv
->pcibar1
= pci_resource_start(pcidev
, 1);
1330 devpriv
->pcibar2
= pci_resource_start(pcidev
, 2);
1331 dev
->iobase
= pci_resource_start(pcidev
, 3);
1333 devpriv
->pcibar4
= pci_resource_start(pcidev
, 4);
1335 /* disable and clear interrupts on amcc s5933 */
1336 outl(INTCSR_INBOX_INTR_STATUS
,
1337 devpriv
->s5933_config
+ AMCC_OP_REG_INTCSR
);
1339 ret
= request_irq(pcidev
->irq
, cb_pcidas_interrupt
, IRQF_SHARED
,
1340 dev
->board_name
, dev
);
1342 dev_dbg(dev
->class_dev
, "unable to allocate irq %d\n",
1346 dev
->irq
= pcidev
->irq
;
1348 dev
->pacer
= comedi_8254_init(dev
->iobase
+ PCIDAS_AI_8254_BASE
,
1349 I8254_OSC_BASE_10MHZ
, I8254_IO8
, 0);
1353 devpriv
->ao_pacer
= comedi_8254_init(dev
->iobase
+ PCIDAS_AO_8254_BASE
,
1354 I8254_OSC_BASE_10MHZ
,
1356 if (!devpriv
->ao_pacer
)
1359 ret
= comedi_alloc_subdevices(dev
, 7);
1363 s
= &dev
->subdevices
[0];
1364 /* analog input subdevice */
1365 dev
->read_subdev
= s
;
1366 s
->type
= COMEDI_SUBD_AI
;
1367 s
->subdev_flags
= SDF_READABLE
| SDF_GROUND
| SDF_DIFF
| SDF_CMD_READ
;
1368 /* WARNING: Number of inputs in differential mode is ignored */
1370 s
->len_chanlist
= s
->n_chan
;
1371 s
->maxdata
= board
->is_16bit
? 0xffff : 0x0fff;
1372 s
->range_table
= board
->use_alt_range
? &cb_pcidas_alt_ranges
1373 : &cb_pcidas_ranges
;
1374 s
->insn_read
= cb_pcidas_ai_rinsn
;
1375 s
->insn_config
= ai_config_insn
;
1376 s
->do_cmd
= cb_pcidas_ai_cmd
;
1377 s
->do_cmdtest
= cb_pcidas_ai_cmdtest
;
1378 s
->cancel
= cb_pcidas_cancel
;
1380 /* analog output subdevice */
1381 s
= &dev
->subdevices
[1];
1382 if (board
->has_ao
) {
1383 s
->type
= COMEDI_SUBD_AO
;
1384 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
| SDF_GROUND
;
1386 s
->maxdata
= board
->is_16bit
? 0xffff : 0x0fff;
1387 s
->range_table
= &cb_pcidas_ao_ranges
;
1388 /* default to no fifo (*insn_write) */
1389 s
->insn_write
= cb_pcidas_ao_nofifo_winsn
;
1391 ret
= comedi_alloc_subdev_readback(s
);
1395 if (board
->has_ao_fifo
) {
1396 dev
->write_subdev
= s
;
1397 s
->subdev_flags
|= SDF_CMD_WRITE
;
1398 /* use fifo (*insn_write) instead */
1399 s
->insn_write
= cb_pcidas_ao_fifo_winsn
;
1400 s
->do_cmdtest
= cb_pcidas_ao_cmdtest
;
1401 s
->do_cmd
= cb_pcidas_ao_cmd
;
1402 s
->cancel
= cb_pcidas_ao_cancel
;
1405 s
->type
= COMEDI_SUBD_UNUSED
;
1409 s
= &dev
->subdevices
[2];
1410 ret
= subdev_8255_init(dev
, s
, NULL
, PCIDAS_8255_BASE
);
1414 /* serial EEPROM, */
1415 s
= &dev
->subdevices
[3];
1416 s
->type
= COMEDI_SUBD_MEMORY
;
1417 s
->subdev_flags
= SDF_READABLE
| SDF_INTERNAL
;
1420 s
->insn_read
= eeprom_read_insn
;
1423 s
= &dev
->subdevices
[4];
1424 s
->type
= COMEDI_SUBD_CALIB
;
1425 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
| SDF_INTERNAL
;
1428 s
->insn_write
= cb_pcidas_caldac_insn_write
;
1430 ret
= comedi_alloc_subdev_readback(s
);
1434 for (i
= 0; i
< s
->n_chan
; i
++) {
1435 caldac_8800_write(dev
, i
, s
->maxdata
/ 2);
1436 s
->readback
[i
] = s
->maxdata
/ 2;
1439 /* trim potentiometer */
1440 s
= &dev
->subdevices
[5];
1441 s
->type
= COMEDI_SUBD_CALIB
;
1442 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
| SDF_INTERNAL
;
1443 if (board
->trimpot
== AD7376
) {
1450 s
->insn_write
= cb_pcidas_trimpot_insn_write
;
1452 ret
= comedi_alloc_subdev_readback(s
);
1456 for (i
= 0; i
< s
->n_chan
; i
++) {
1457 cb_pcidas_trimpot_write(dev
, i
, s
->maxdata
/ 2);
1458 s
->readback
[i
] = s
->maxdata
/ 2;
1462 s
= &dev
->subdevices
[6];
1463 if (board
->has_dac08
) {
1464 s
->type
= COMEDI_SUBD_CALIB
;
1465 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
| SDF_INTERNAL
;
1468 s
->insn_write
= cb_pcidas_dac08_insn_write
;
1470 ret
= comedi_alloc_subdev_readback(s
);
1474 for (i
= 0; i
< s
->n_chan
; i
++) {
1475 dac08_write(dev
, s
->maxdata
/ 2);
1476 s
->readback
[i
] = s
->maxdata
/ 2;
1479 s
->type
= COMEDI_SUBD_UNUSED
;
1482 /* make sure mailbox 4 is empty */
1483 inl(devpriv
->s5933_config
+ AMCC_OP_REG_IMB4
);
1484 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1485 devpriv
->s5933_intcsr_bits
=
1486 INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1487 INTCSR_INBOX_FULL_INT
;
1488 /* clear and enable interrupt on amcc s5933 */
1489 outl(devpriv
->s5933_intcsr_bits
| INTCSR_INBOX_INTR_STATUS
,
1490 devpriv
->s5933_config
+ AMCC_OP_REG_INTCSR
);
1495 static void cb_pcidas_detach(struct comedi_device
*dev
)
1497 struct cb_pcidas_private
*devpriv
= dev
->private;
1500 if (devpriv
->s5933_config
)
1501 outl(INTCSR_INBOX_INTR_STATUS
,
1502 devpriv
->s5933_config
+ AMCC_OP_REG_INTCSR
);
1503 kfree(devpriv
->ao_pacer
);
1505 comedi_pci_detach(dev
);
1508 static struct comedi_driver cb_pcidas_driver
= {
1509 .driver_name
= "cb_pcidas",
1510 .module
= THIS_MODULE
,
1511 .auto_attach
= cb_pcidas_auto_attach
,
1512 .detach
= cb_pcidas_detach
,
1515 static int cb_pcidas_pci_probe(struct pci_dev
*dev
,
1516 const struct pci_device_id
*id
)
1518 return comedi_pci_auto_config(dev
, &cb_pcidas_driver
,
1522 static const struct pci_device_id cb_pcidas_pci_table
[] = {
1523 { PCI_VDEVICE(CB
, 0x0001), BOARD_PCIDAS1602_16
},
1524 { PCI_VDEVICE(CB
, 0x000f), BOARD_PCIDAS1200
},
1525 { PCI_VDEVICE(CB
, 0x0010), BOARD_PCIDAS1602_12
},
1526 { PCI_VDEVICE(CB
, 0x0019), BOARD_PCIDAS1200_JR
},
1527 { PCI_VDEVICE(CB
, 0x001c), BOARD_PCIDAS1602_16_JR
},
1528 { PCI_VDEVICE(CB
, 0x004c), BOARD_PCIDAS1000
},
1529 { PCI_VDEVICE(CB
, 0x001a), BOARD_PCIDAS1001
},
1530 { PCI_VDEVICE(CB
, 0x001b), BOARD_PCIDAS1002
},
1533 MODULE_DEVICE_TABLE(pci
, cb_pcidas_pci_table
);
1535 static struct pci_driver cb_pcidas_pci_driver
= {
1536 .name
= "cb_pcidas",
1537 .id_table
= cb_pcidas_pci_table
,
1538 .probe
= cb_pcidas_pci_probe
,
1539 .remove
= comedi_pci_auto_unconfig
,
1541 module_comedi_pci_driver(cb_pcidas_driver
, cb_pcidas_pci_driver
);
1543 MODULE_AUTHOR("Comedi http://www.comedi.org");
1544 MODULE_DESCRIPTION("Comedi low-level driver");
1545 MODULE_LICENSE("GPL");