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 static inline unsigned int DAC_RANGE(unsigned int channel
, unsigned int range
)
135 return (range
& 0x3) << (8 + 2 * (channel
& 0x1));
138 static inline unsigned int DAC_RANGE_MASK(unsigned int channel
)
140 return 0x3 << (8 + 2 * (channel
& 0x1));
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 static inline unsigned int DAC_CHAN_EN(unsigned int channel
)
153 return 1 << (5 + (channel
& 0x1)); /* enable channel 0 or 1 */
156 /* analog input fifo */
157 #define ADCDATA 0 /* ADC DATA register */
158 #define ADCFIFOCLR 2 /* ADC FIFO CLEAR */
160 /* pacer, counter, dio registers */
165 /* analog output registers for 100x, 1200 series */
166 static inline unsigned int DAC_DATA_REG(unsigned int channel
)
168 return 2 * (channel
& 0x1);
171 /* analog output registers for 1602 series*/
172 #define DACDATA 0 /* DAC DATA register */
173 #define DACFIFOCLR 2 /* DAC FIFO CLEAR */
175 #define IS_UNIPOLAR 0x4 /* unipolar range mask */
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
= {
220 enum cb_pcidas_boardid
{
225 BOARD_PCIDAS1602_16_JR
,
231 struct cb_pcidas_board
{
233 int ai_speed
; /* fastest conversion period in ns */
234 int ao_scan_speed
; /* analog output scan speed for 1602 series */
235 int fifo_size
; /* number of samples fifo can hold */
236 enum trimpot_model trimpot
;
237 unsigned int is_16bit
; /* ai/ao is 1=16-bit; 0=12-bit */
238 unsigned int use_alt_range
:1; /* use alternate ai range table */
239 unsigned int has_ao
:1; /* has 2 analog output channels */
240 unsigned int has_ao_fifo
:1; /* analog output has fifo */
241 unsigned int has_dac08
:1;
242 unsigned int is_1602
:1;
245 static const struct cb_pcidas_board cb_pcidas_boards
[] = {
246 [BOARD_PCIDAS1602_16
] = {
247 .name
= "pci-das1602/16",
249 .ao_scan_speed
= 10000,
258 [BOARD_PCIDAS1200
] = {
259 .name
= "pci-das1200",
265 [BOARD_PCIDAS1602_12
] = {
266 .name
= "pci-das1602/12",
268 .ao_scan_speed
= 4000,
275 [BOARD_PCIDAS1200_JR
] = {
276 .name
= "pci-das1200/jr",
281 [BOARD_PCIDAS1602_16_JR
] = {
282 .name
= "pci-das1602/16/jr",
290 [BOARD_PCIDAS1000
] = {
291 .name
= "pci-das1000",
296 [BOARD_PCIDAS1001
] = {
297 .name
= "pci-das1001",
304 [BOARD_PCIDAS1002
] = {
305 .name
= "pci-das1002",
313 struct cb_pcidas_private
{
314 struct comedi_8254
*ao_pacer
;
316 unsigned long s5933_config
;
317 unsigned long pcibar1
;
318 unsigned long adc_fifo
;
319 unsigned long ao_registers
;
320 /* bits to write to registers */
321 unsigned int adc_fifo_bits
;
322 unsigned int s5933_intcsr_bits
;
323 unsigned int ao_control_bits
;
325 unsigned short ai_buffer
[AI_BUFFER_SIZE
];
326 unsigned short ao_buffer
[AO_BUFFER_SIZE
];
327 unsigned int calibration_source
;
330 static inline unsigned int cal_enable_bits(struct comedi_device
*dev
)
332 struct cb_pcidas_private
*devpriv
= dev
->private;
334 return CAL_EN_BIT
| CAL_SRC_BITS(devpriv
->calibration_source
);
337 static int cb_pcidas_ai_eoc(struct comedi_device
*dev
,
338 struct comedi_subdevice
*s
,
339 struct comedi_insn
*insn
,
340 unsigned long context
)
342 struct cb_pcidas_private
*devpriv
= dev
->private;
345 status
= inw(devpriv
->pcibar1
+ ADCMUX_CONT
);
351 static int cb_pcidas_ai_rinsn(struct comedi_device
*dev
,
352 struct comedi_subdevice
*s
,
353 struct comedi_insn
*insn
, unsigned int *data
)
355 struct cb_pcidas_private
*devpriv
= dev
->private;
356 unsigned int chan
= CR_CHAN(insn
->chanspec
);
357 unsigned int range
= CR_RANGE(insn
->chanspec
);
358 unsigned int aref
= CR_AREF(insn
->chanspec
);
363 /* enable calibration input if appropriate */
364 if (insn
->chanspec
& CR_ALT_SOURCE
) {
365 outw(cal_enable_bits(dev
),
366 devpriv
->pcibar1
+ CALIBRATION_REG
);
369 outw(0, devpriv
->pcibar1
+ CALIBRATION_REG
);
372 /* set mux limits and gain */
373 bits
= BEGIN_SCAN(chan
) | END_SCAN(chan
) | GAIN_BITS(range
);
374 /* set unipolar/bipolar */
375 if (range
& IS_UNIPOLAR
)
377 /* set single-ended/differential */
378 if (aref
!= AREF_DIFF
)
380 outw(bits
, devpriv
->pcibar1
+ ADCMUX_CONT
);
383 outw(0, devpriv
->adc_fifo
+ ADCFIFOCLR
);
385 /* convert n samples */
386 for (n
= 0; n
< insn
->n
; n
++) {
387 /* trigger conversion */
388 outw(0, devpriv
->adc_fifo
+ ADCDATA
);
390 /* wait for conversion to end */
391 ret
= comedi_timeout(dev
, s
, insn
, cb_pcidas_ai_eoc
, 0);
396 data
[n
] = inw(devpriv
->adc_fifo
+ ADCDATA
);
399 /* return the number of samples read/written */
403 static int ai_config_insn(struct comedi_device
*dev
, struct comedi_subdevice
*s
,
404 struct comedi_insn
*insn
, unsigned int *data
)
406 struct cb_pcidas_private
*devpriv
= dev
->private;
408 unsigned int source
= data
[1];
411 case INSN_CONFIG_ALT_SOURCE
:
413 dev_err(dev
->class_dev
,
414 "invalid calibration source: %i\n",
418 devpriv
->calibration_source
= source
;
426 /* analog output insn for pcidas-1000 and 1200 series */
427 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device
*dev
,
428 struct comedi_subdevice
*s
,
429 struct comedi_insn
*insn
,
432 struct cb_pcidas_private
*devpriv
= dev
->private;
433 unsigned int chan
= CR_CHAN(insn
->chanspec
);
434 unsigned int range
= CR_RANGE(insn
->chanspec
);
437 /* set channel and range */
438 spin_lock_irqsave(&dev
->spinlock
, flags
);
439 devpriv
->ao_control_bits
&= (~DAC_MODE_UPDATE_BOTH
&
440 ~DAC_RANGE_MASK(chan
));
441 devpriv
->ao_control_bits
|= (DACEN
| DAC_RANGE(chan
, range
));
442 outw(devpriv
->ao_control_bits
, devpriv
->pcibar1
+ DAC_CSR
);
443 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
445 /* remember value for readback */
446 s
->readback
[chan
] = data
[0];
449 outw(data
[0], devpriv
->ao_registers
+ DAC_DATA_REG(chan
));
454 /* analog output insn for pcidas-1602 series */
455 static int cb_pcidas_ao_fifo_winsn(struct comedi_device
*dev
,
456 struct comedi_subdevice
*s
,
457 struct comedi_insn
*insn
, unsigned int *data
)
459 struct cb_pcidas_private
*devpriv
= dev
->private;
460 unsigned int chan
= CR_CHAN(insn
->chanspec
);
461 unsigned int range
= CR_RANGE(insn
->chanspec
);
465 outw(0, devpriv
->ao_registers
+ DACFIFOCLR
);
467 /* set channel and range */
468 spin_lock_irqsave(&dev
->spinlock
, flags
);
469 devpriv
->ao_control_bits
&= (~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) &
470 ~DAC_RANGE_MASK(chan
) & ~DAC_PACER_MASK
);
471 devpriv
->ao_control_bits
|= (DACEN
| DAC_RANGE(chan
, range
) |
472 DAC_CHAN_EN(chan
) | DAC_START
);
473 outw(devpriv
->ao_control_bits
, devpriv
->pcibar1
+ DAC_CSR
);
474 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
476 /* remember value for readback */
477 s
->readback
[chan
] = data
[0];
480 outw(data
[0], devpriv
->ao_registers
+ DACDATA
);
485 static int wait_for_nvram_ready(unsigned long s5933_base_addr
)
487 static const int timeout
= 1000;
490 for (i
= 0; i
< timeout
; i
++) {
491 if ((inb(s5933_base_addr
+
492 AMCC_OP_REG_MCSR_NVCMD
) & MCSR_NV_BUSY
)
500 static int nvram_read(struct comedi_device
*dev
, unsigned int address
,
503 struct cb_pcidas_private
*devpriv
= dev
->private;
504 unsigned long iobase
= devpriv
->s5933_config
;
506 if (wait_for_nvram_ready(iobase
) < 0)
509 outb(MCSR_NV_ENABLE
| MCSR_NV_LOAD_LOW_ADDR
,
510 iobase
+ AMCC_OP_REG_MCSR_NVCMD
);
511 outb(address
& 0xff, iobase
+ AMCC_OP_REG_MCSR_NVDATA
);
512 outb(MCSR_NV_ENABLE
| MCSR_NV_LOAD_HIGH_ADDR
,
513 iobase
+ AMCC_OP_REG_MCSR_NVCMD
);
514 outb((address
>> 8) & 0xff, iobase
+ AMCC_OP_REG_MCSR_NVDATA
);
515 outb(MCSR_NV_ENABLE
| MCSR_NV_READ
, iobase
+ AMCC_OP_REG_MCSR_NVCMD
);
517 if (wait_for_nvram_ready(iobase
) < 0)
520 *data
= inb(iobase
+ AMCC_OP_REG_MCSR_NVDATA
);
525 static int eeprom_read_insn(struct comedi_device
*dev
,
526 struct comedi_subdevice
*s
,
527 struct comedi_insn
*insn
, unsigned int *data
)
532 retval
= nvram_read(dev
, CR_CHAN(insn
->chanspec
), &nvram_data
);
536 data
[0] = nvram_data
;
541 static void write_calibration_bitstream(struct comedi_device
*dev
,
542 unsigned int register_bits
,
543 unsigned int bitstream
,
544 unsigned int bitstream_length
)
546 struct cb_pcidas_private
*devpriv
= dev
->private;
547 static const int write_delay
= 1;
550 for (bit
= 1 << (bitstream_length
- 1); bit
; bit
>>= 1) {
552 register_bits
|= SERIAL_DATA_IN_BIT
;
554 register_bits
&= ~SERIAL_DATA_IN_BIT
;
556 outw(register_bits
, devpriv
->pcibar1
+ CALIBRATION_REG
);
560 static void caldac_8800_write(struct comedi_device
*dev
,
561 unsigned int chan
, uint8_t val
)
563 struct cb_pcidas_private
*devpriv
= dev
->private;
564 static const int bitstream_length
= 11;
565 unsigned int bitstream
= ((chan
& 0x7) << 8) | val
;
566 static const int caldac_8800_udelay
= 1;
568 write_calibration_bitstream(dev
, cal_enable_bits(dev
), bitstream
,
571 udelay(caldac_8800_udelay
);
572 outw(cal_enable_bits(dev
) | SELECT_8800_BIT
,
573 devpriv
->pcibar1
+ CALIBRATION_REG
);
574 udelay(caldac_8800_udelay
);
575 outw(cal_enable_bits(dev
), devpriv
->pcibar1
+ CALIBRATION_REG
);
578 static int cb_pcidas_caldac_insn_write(struct comedi_device
*dev
,
579 struct comedi_subdevice
*s
,
580 struct comedi_insn
*insn
,
583 unsigned int chan
= CR_CHAN(insn
->chanspec
);
586 unsigned int val
= data
[insn
->n
- 1];
588 if (s
->readback
[chan
] != val
) {
589 caldac_8800_write(dev
, chan
, val
);
590 s
->readback
[chan
] = val
;
597 /* 1602/16 pregain offset */
598 static void dac08_write(struct comedi_device
*dev
, unsigned int value
)
600 struct cb_pcidas_private
*devpriv
= dev
->private;
603 value
|= cal_enable_bits(dev
);
605 /* latch the new value into the caldac */
606 outw(value
, devpriv
->pcibar1
+ CALIBRATION_REG
);
608 outw(value
| SELECT_DAC08_BIT
,
609 devpriv
->pcibar1
+ CALIBRATION_REG
);
611 outw(value
, devpriv
->pcibar1
+ CALIBRATION_REG
);
615 static int cb_pcidas_dac08_insn_write(struct comedi_device
*dev
,
616 struct comedi_subdevice
*s
,
617 struct comedi_insn
*insn
,
620 unsigned int chan
= CR_CHAN(insn
->chanspec
);
623 unsigned int val
= data
[insn
->n
- 1];
625 if (s
->readback
[chan
] != val
) {
626 dac08_write(dev
, val
);
627 s
->readback
[chan
] = val
;
634 static int trimpot_7376_write(struct comedi_device
*dev
, uint8_t value
)
636 struct cb_pcidas_private
*devpriv
= dev
->private;
637 static const int bitstream_length
= 7;
638 unsigned int bitstream
= value
& 0x7f;
639 unsigned int register_bits
;
640 static const int ad7376_udelay
= 1;
642 register_bits
= cal_enable_bits(dev
) | SELECT_TRIMPOT_BIT
;
643 udelay(ad7376_udelay
);
644 outw(register_bits
, devpriv
->pcibar1
+ CALIBRATION_REG
);
646 write_calibration_bitstream(dev
, register_bits
, bitstream
,
649 udelay(ad7376_udelay
);
650 outw(cal_enable_bits(dev
), devpriv
->pcibar1
+ CALIBRATION_REG
);
657 * ch 1 : adc postgain offset */
658 static int trimpot_8402_write(struct comedi_device
*dev
, unsigned int channel
,
661 struct cb_pcidas_private
*devpriv
= dev
->private;
662 static const int bitstream_length
= 10;
663 unsigned int bitstream
= ((channel
& 0x3) << 8) | (value
& 0xff);
664 unsigned int register_bits
;
665 static const int ad8402_udelay
= 1;
667 register_bits
= cal_enable_bits(dev
) | SELECT_TRIMPOT_BIT
;
668 udelay(ad8402_udelay
);
669 outw(register_bits
, devpriv
->pcibar1
+ CALIBRATION_REG
);
671 write_calibration_bitstream(dev
, register_bits
, bitstream
,
674 udelay(ad8402_udelay
);
675 outw(cal_enable_bits(dev
), devpriv
->pcibar1
+ CALIBRATION_REG
);
680 static void cb_pcidas_trimpot_write(struct comedi_device
*dev
,
681 unsigned int chan
, unsigned int val
)
683 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
685 switch (board
->trimpot
) {
687 trimpot_7376_write(dev
, val
);
690 trimpot_8402_write(dev
, chan
, val
);
693 dev_err(dev
->class_dev
, "driver bug?\n");
698 static int cb_pcidas_trimpot_insn_write(struct comedi_device
*dev
,
699 struct comedi_subdevice
*s
,
700 struct comedi_insn
*insn
,
703 unsigned int chan
= CR_CHAN(insn
->chanspec
);
706 unsigned int val
= data
[insn
->n
- 1];
708 if (s
->readback
[chan
] != val
) {
709 cb_pcidas_trimpot_write(dev
, chan
, val
);
710 s
->readback
[chan
] = val
;
717 static int cb_pcidas_ai_check_chanlist(struct comedi_device
*dev
,
718 struct comedi_subdevice
*s
,
719 struct comedi_cmd
*cmd
)
721 unsigned int chan0
= CR_CHAN(cmd
->chanlist
[0]);
722 unsigned int range0
= CR_RANGE(cmd
->chanlist
[0]);
725 for (i
= 1; i
< cmd
->chanlist_len
; i
++) {
726 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
727 unsigned int range
= CR_RANGE(cmd
->chanlist
[i
]);
729 if (chan
!= (chan0
+ i
) % s
->n_chan
) {
730 dev_dbg(dev
->class_dev
,
731 "entries in chanlist must be consecutive channels, counting upwards\n");
735 if (range
!= range0
) {
736 dev_dbg(dev
->class_dev
,
737 "entries in chanlist must all have the same gain\n");
744 static int cb_pcidas_ai_cmdtest(struct comedi_device
*dev
,
745 struct comedi_subdevice
*s
,
746 struct comedi_cmd
*cmd
)
748 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
752 /* Step 1 : check if triggers are trivially valid */
754 err
|= comedi_check_trigger_src(&cmd
->start_src
, TRIG_NOW
| TRIG_EXT
);
755 err
|= comedi_check_trigger_src(&cmd
->scan_begin_src
,
756 TRIG_FOLLOW
| TRIG_TIMER
| TRIG_EXT
);
757 err
|= comedi_check_trigger_src(&cmd
->convert_src
,
758 TRIG_TIMER
| TRIG_NOW
| TRIG_EXT
);
759 err
|= comedi_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
760 err
|= comedi_check_trigger_src(&cmd
->stop_src
, TRIG_COUNT
| TRIG_NONE
);
765 /* Step 2a : make sure trigger sources are unique */
767 err
|= comedi_check_trigger_is_unique(cmd
->start_src
);
768 err
|= comedi_check_trigger_is_unique(cmd
->scan_begin_src
);
769 err
|= comedi_check_trigger_is_unique(cmd
->convert_src
);
770 err
|= comedi_check_trigger_is_unique(cmd
->stop_src
);
772 /* Step 2b : and mutually compatible */
774 if (cmd
->scan_begin_src
== TRIG_FOLLOW
&& cmd
->convert_src
== TRIG_NOW
)
776 if (cmd
->scan_begin_src
!= TRIG_FOLLOW
&& cmd
->convert_src
!= TRIG_NOW
)
778 if (cmd
->start_src
== TRIG_EXT
&&
779 (cmd
->convert_src
== TRIG_EXT
|| cmd
->scan_begin_src
== TRIG_EXT
))
785 /* Step 3: check if arguments are trivially valid */
787 switch (cmd
->start_src
) {
789 err
|= comedi_check_trigger_arg_is(&cmd
->start_arg
, 0);
792 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
794 & (CR_FLAGS_MASK
& ~(CR_EDGE
| CR_INVERT
))) != 0) {
795 cmd
->start_arg
&= ~(CR_FLAGS_MASK
&
796 ~(CR_EDGE
| CR_INVERT
));
799 if (!board
->is_1602
&& (cmd
->start_arg
& CR_INVERT
)) {
800 cmd
->start_arg
&= (CR_FLAGS_MASK
& ~CR_INVERT
);
806 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
807 err
|= comedi_check_trigger_arg_min(&cmd
->scan_begin_arg
,
812 if (cmd
->convert_src
== TRIG_TIMER
) {
813 err
|= comedi_check_trigger_arg_min(&cmd
->convert_arg
,
817 err
|= comedi_check_trigger_arg_is(&cmd
->scan_end_arg
,
820 if (cmd
->stop_src
== TRIG_COUNT
)
821 err
|= comedi_check_trigger_arg_min(&cmd
->stop_arg
, 1);
823 err
|= comedi_check_trigger_arg_is(&cmd
->stop_arg
, 0);
828 /* step 4: fix up any arguments */
830 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
831 arg
= cmd
->scan_begin_arg
;
832 comedi_8254_cascade_ns_to_timer(dev
->pacer
, &arg
, cmd
->flags
);
833 err
|= comedi_check_trigger_arg_is(&cmd
->scan_begin_arg
, arg
);
835 if (cmd
->convert_src
== TRIG_TIMER
) {
836 arg
= cmd
->convert_arg
;
837 comedi_8254_cascade_ns_to_timer(dev
->pacer
, &arg
, cmd
->flags
);
838 err
|= comedi_check_trigger_arg_is(&cmd
->convert_arg
, arg
);
844 /* Step 5: check channel list if it exists */
845 if (cmd
->chanlist
&& cmd
->chanlist_len
> 0)
846 err
|= cb_pcidas_ai_check_chanlist(dev
, s
, cmd
);
854 static int cb_pcidas_ai_cmd(struct comedi_device
*dev
,
855 struct comedi_subdevice
*s
)
857 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
858 struct cb_pcidas_private
*devpriv
= dev
->private;
859 struct comedi_async
*async
= s
->async
;
860 struct comedi_cmd
*cmd
= &async
->cmd
;
864 /* make sure CAL_EN_BIT is disabled */
865 outw(0, devpriv
->pcibar1
+ CALIBRATION_REG
);
866 /* initialize before settings pacer source and count values */
867 outw(0, devpriv
->pcibar1
+ TRIG_CONTSTAT
);
869 outw(0, devpriv
->adc_fifo
+ ADCFIFOCLR
);
871 /* set mux limits, gain and pacer source */
872 bits
= BEGIN_SCAN(CR_CHAN(cmd
->chanlist
[0])) |
873 END_SCAN(CR_CHAN(cmd
->chanlist
[cmd
->chanlist_len
- 1])) |
874 GAIN_BITS(CR_RANGE(cmd
->chanlist
[0]));
875 /* set unipolar/bipolar */
876 if (CR_RANGE(cmd
->chanlist
[0]) & IS_UNIPOLAR
)
878 /* set singleended/differential */
879 if (CR_AREF(cmd
->chanlist
[0]) != AREF_DIFF
)
881 /* set pacer source */
882 if (cmd
->convert_src
== TRIG_EXT
|| cmd
->scan_begin_src
== TRIG_EXT
)
883 bits
|= PACER_EXT_RISE
;
886 outw(bits
, devpriv
->pcibar1
+ ADCMUX_CONT
);
889 if (cmd
->scan_begin_src
== TRIG_TIMER
||
890 cmd
->convert_src
== TRIG_TIMER
) {
891 comedi_8254_update_divisors(dev
->pacer
);
892 comedi_8254_pacer_enable(dev
->pacer
, 1, 2, true);
895 /* enable interrupts */
896 spin_lock_irqsave(&dev
->spinlock
, flags
);
897 devpriv
->adc_fifo_bits
|= INTE
;
898 devpriv
->adc_fifo_bits
&= ~INT_MASK
;
899 if (cmd
->flags
& CMDF_WAKE_EOS
) {
900 if (cmd
->convert_src
== TRIG_NOW
&& cmd
->chanlist_len
> 1) {
901 /* interrupt end of burst */
902 devpriv
->adc_fifo_bits
|= INT_EOS
;
904 /* interrupt fifo not empty */
905 devpriv
->adc_fifo_bits
|= INT_FNE
;
908 /* interrupt fifo half full */
909 devpriv
->adc_fifo_bits
|= INT_FHF
;
912 /* enable (and clear) interrupts */
913 outw(devpriv
->adc_fifo_bits
| EOAI
| INT
| LADFUL
,
914 devpriv
->pcibar1
+ INT_ADCFIFO
);
915 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
917 /* set start trigger and burst mode */
919 if (cmd
->start_src
== TRIG_NOW
) {
921 } else { /* TRIG_EXT */
922 bits
|= EXT_TRIGGER
| TGEN
| XTRCL
;
923 if (board
->is_1602
) {
924 if (cmd
->start_arg
& CR_INVERT
)
926 if (cmd
->start_arg
& CR_EDGE
)
930 if (cmd
->convert_src
== TRIG_NOW
&& cmd
->chanlist_len
> 1)
932 outw(bits
, devpriv
->pcibar1
+ TRIG_CONTSTAT
);
937 static int cb_pcidas_ao_check_chanlist(struct comedi_device
*dev
,
938 struct comedi_subdevice
*s
,
939 struct comedi_cmd
*cmd
)
941 unsigned int chan0
= CR_CHAN(cmd
->chanlist
[0]);
943 if (cmd
->chanlist_len
> 1) {
944 unsigned int chan1
= CR_CHAN(cmd
->chanlist
[1]);
946 if (chan0
!= 0 || chan1
!= 1) {
947 dev_dbg(dev
->class_dev
,
948 "channels must be ordered channel 0, channel 1 in chanlist\n");
956 static int cb_pcidas_ao_cmdtest(struct comedi_device
*dev
,
957 struct comedi_subdevice
*s
,
958 struct comedi_cmd
*cmd
)
960 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
961 struct cb_pcidas_private
*devpriv
= dev
->private;
964 /* Step 1 : check if triggers are trivially valid */
966 err
|= comedi_check_trigger_src(&cmd
->start_src
, TRIG_INT
);
967 err
|= comedi_check_trigger_src(&cmd
->scan_begin_src
,
968 TRIG_TIMER
| TRIG_EXT
);
969 err
|= comedi_check_trigger_src(&cmd
->convert_src
, TRIG_NOW
);
970 err
|= comedi_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
971 err
|= comedi_check_trigger_src(&cmd
->stop_src
, TRIG_COUNT
| TRIG_NONE
);
976 /* Step 2a : make sure trigger sources are unique */
978 err
|= comedi_check_trigger_is_unique(cmd
->scan_begin_src
);
979 err
|= comedi_check_trigger_is_unique(cmd
->stop_src
);
981 /* Step 2b : and mutually compatible */
986 /* Step 3: check if arguments are trivially valid */
988 err
|= comedi_check_trigger_arg_is(&cmd
->start_arg
, 0);
990 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
991 err
|= comedi_check_trigger_arg_min(&cmd
->scan_begin_arg
,
992 board
->ao_scan_speed
);
995 err
|= comedi_check_trigger_arg_is(&cmd
->scan_end_arg
,
998 if (cmd
->stop_src
== TRIG_COUNT
)
999 err
|= comedi_check_trigger_arg_min(&cmd
->stop_arg
, 1);
1000 else /* TRIG_NONE */
1001 err
|= comedi_check_trigger_arg_is(&cmd
->stop_arg
, 0);
1006 /* step 4: fix up any arguments */
1008 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
1009 unsigned int arg
= cmd
->scan_begin_arg
;
1011 comedi_8254_cascade_ns_to_timer(devpriv
->ao_pacer
,
1013 err
|= comedi_check_trigger_arg_is(&cmd
->scan_begin_arg
, arg
);
1019 /* Step 5: check channel list if it exists */
1020 if (cmd
->chanlist
&& cmd
->chanlist_len
> 0)
1021 err
|= cb_pcidas_ao_check_chanlist(dev
, s
, cmd
);
1029 /* cancel analog input command */
1030 static int cb_pcidas_cancel(struct comedi_device
*dev
,
1031 struct comedi_subdevice
*s
)
1033 struct cb_pcidas_private
*devpriv
= dev
->private;
1034 unsigned long flags
;
1036 spin_lock_irqsave(&dev
->spinlock
, flags
);
1037 /* disable interrupts */
1038 devpriv
->adc_fifo_bits
&= ~INTE
& ~EOAIE
;
1039 outw(devpriv
->adc_fifo_bits
, devpriv
->pcibar1
+ INT_ADCFIFO
);
1040 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1042 /* disable start trigger source and burst mode */
1043 outw(0, devpriv
->pcibar1
+ TRIG_CONTSTAT
);
1044 /* software pacer source */
1045 outw(0, devpriv
->pcibar1
+ ADCMUX_CONT
);
1050 static void cb_pcidas_ao_load_fifo(struct comedi_device
*dev
,
1051 struct comedi_subdevice
*s
,
1052 unsigned int nsamples
)
1054 struct cb_pcidas_private
*devpriv
= dev
->private;
1055 unsigned int nbytes
;
1057 nsamples
= comedi_nsamples_left(s
, nsamples
);
1058 nbytes
= comedi_buf_read_samples(s
, devpriv
->ao_buffer
, nsamples
);
1060 nsamples
= comedi_bytes_to_samples(s
, nbytes
);
1061 outsw(devpriv
->ao_registers
+ DACDATA
, devpriv
->ao_buffer
, nsamples
);
1064 static int cb_pcidas_ao_inttrig(struct comedi_device
*dev
,
1065 struct comedi_subdevice
*s
,
1066 unsigned int trig_num
)
1068 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
1069 struct cb_pcidas_private
*devpriv
= dev
->private;
1070 struct comedi_async
*async
= s
->async
;
1071 struct comedi_cmd
*cmd
= &async
->cmd
;
1072 unsigned long flags
;
1074 if (trig_num
!= cmd
->start_arg
)
1077 cb_pcidas_ao_load_fifo(dev
, s
, board
->fifo_size
);
1079 /* enable dac half-full and empty interrupts */
1080 spin_lock_irqsave(&dev
->spinlock
, flags
);
1081 devpriv
->adc_fifo_bits
|= DAEMIE
| DAHFIE
;
1083 /* enable and clear interrupts */
1084 outw(devpriv
->adc_fifo_bits
| DAEMI
| DAHFI
,
1085 devpriv
->pcibar1
+ INT_ADCFIFO
);
1088 devpriv
->ao_control_bits
|= DAC_START
| DACEN
| DAC_EMPTY
;
1089 outw(devpriv
->ao_control_bits
, devpriv
->pcibar1
+ DAC_CSR
);
1091 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1093 async
->inttrig
= NULL
;
1098 static int cb_pcidas_ao_cmd(struct comedi_device
*dev
,
1099 struct comedi_subdevice
*s
)
1101 struct cb_pcidas_private
*devpriv
= dev
->private;
1102 struct comedi_async
*async
= s
->async
;
1103 struct comedi_cmd
*cmd
= &async
->cmd
;
1105 unsigned long flags
;
1107 /* set channel limits, gain */
1108 spin_lock_irqsave(&dev
->spinlock
, flags
);
1109 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
1110 /* enable channel */
1111 devpriv
->ao_control_bits
|=
1112 DAC_CHAN_EN(CR_CHAN(cmd
->chanlist
[i
]));
1114 devpriv
->ao_control_bits
|= DAC_RANGE(CR_CHAN(cmd
->chanlist
[i
]),
1119 /* disable analog out before settings pacer source and count values */
1120 outw(devpriv
->ao_control_bits
, devpriv
->pcibar1
+ DAC_CSR
);
1121 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1124 outw(0, devpriv
->ao_registers
+ DACFIFOCLR
);
1127 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
1128 comedi_8254_update_divisors(devpriv
->ao_pacer
);
1129 comedi_8254_pacer_enable(devpriv
->ao_pacer
, 1, 2, true);
1132 /* set pacer source */
1133 spin_lock_irqsave(&dev
->spinlock
, flags
);
1134 switch (cmd
->scan_begin_src
) {
1136 devpriv
->ao_control_bits
|= DAC_PACER_INT
;
1139 devpriv
->ao_control_bits
|= DAC_PACER_EXT_RISE
;
1142 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1143 dev_err(dev
->class_dev
, "error setting dac pacer source\n");
1146 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1148 async
->inttrig
= cb_pcidas_ao_inttrig
;
1153 /* cancel analog output command */
1154 static int cb_pcidas_ao_cancel(struct comedi_device
*dev
,
1155 struct comedi_subdevice
*s
)
1157 struct cb_pcidas_private
*devpriv
= dev
->private;
1158 unsigned long flags
;
1160 spin_lock_irqsave(&dev
->spinlock
, flags
);
1161 /* disable interrupts */
1162 devpriv
->adc_fifo_bits
&= ~DAHFIE
& ~DAEMIE
;
1163 outw(devpriv
->adc_fifo_bits
, devpriv
->pcibar1
+ INT_ADCFIFO
);
1165 /* disable output */
1166 devpriv
->ao_control_bits
&= ~DACEN
& ~DAC_PACER_MASK
;
1167 outw(devpriv
->ao_control_bits
, devpriv
->pcibar1
+ DAC_CSR
);
1168 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1173 static void handle_ao_interrupt(struct comedi_device
*dev
, unsigned int status
)
1175 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
1176 struct cb_pcidas_private
*devpriv
= dev
->private;
1177 struct comedi_subdevice
*s
= dev
->write_subdev
;
1178 struct comedi_async
*async
= s
->async
;
1179 struct comedi_cmd
*cmd
= &async
->cmd
;
1180 unsigned long flags
;
1182 if (status
& DAEMI
) {
1183 /* clear dac empty interrupt latch */
1184 spin_lock_irqsave(&dev
->spinlock
, flags
);
1185 outw(devpriv
->adc_fifo_bits
| DAEMI
,
1186 devpriv
->pcibar1
+ INT_ADCFIFO
);
1187 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1188 if (inw(devpriv
->ao_registers
+ DAC_CSR
) & DAC_EMPTY
) {
1189 if (cmd
->stop_src
== TRIG_COUNT
&&
1190 async
->scans_done
>= cmd
->stop_arg
) {
1191 async
->events
|= COMEDI_CB_EOA
;
1193 dev_err(dev
->class_dev
, "dac fifo underflow\n");
1194 async
->events
|= COMEDI_CB_ERROR
;
1197 } else if (status
& DAHFI
) {
1198 cb_pcidas_ao_load_fifo(dev
, s
, board
->fifo_size
/ 2);
1200 /* clear half-full interrupt latch */
1201 spin_lock_irqsave(&dev
->spinlock
, flags
);
1202 outw(devpriv
->adc_fifo_bits
| DAHFI
,
1203 devpriv
->pcibar1
+ INT_ADCFIFO
);
1204 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1207 comedi_handle_events(dev
, s
);
1210 static irqreturn_t
cb_pcidas_interrupt(int irq
, void *d
)
1212 struct comedi_device
*dev
= d
;
1213 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
1214 struct cb_pcidas_private
*devpriv
= dev
->private;
1215 struct comedi_subdevice
*s
= dev
->read_subdev
;
1216 struct comedi_async
*async
;
1217 struct comedi_cmd
*cmd
;
1218 int status
, s5933_status
;
1219 int half_fifo
= board
->fifo_size
/ 2;
1220 unsigned int num_samples
, i
;
1221 static const int timeout
= 10000;
1222 unsigned long flags
;
1230 s5933_status
= inl(devpriv
->s5933_config
+ AMCC_OP_REG_INTCSR
);
1232 if ((INTCSR_INTR_ASSERTED
& s5933_status
) == 0)
1235 /* make sure mailbox 4 is empty */
1236 inl_p(devpriv
->s5933_config
+ AMCC_OP_REG_IMB4
);
1237 /* clear interrupt on amcc s5933 */
1238 outl(devpriv
->s5933_intcsr_bits
| INTCSR_INBOX_INTR_STATUS
,
1239 devpriv
->s5933_config
+ AMCC_OP_REG_INTCSR
);
1241 status
= inw(devpriv
->pcibar1
+ INT_ADCFIFO
);
1243 /* check for analog output interrupt */
1244 if (status
& (DAHFI
| DAEMI
))
1245 handle_ao_interrupt(dev
, status
);
1246 /* check for analog input interrupts */
1247 /* if fifo half-full */
1248 if (status
& ADHFI
) {
1250 num_samples
= comedi_nsamples_left(s
, half_fifo
);
1251 insw(devpriv
->adc_fifo
+ ADCDATA
, devpriv
->ai_buffer
,
1253 comedi_buf_write_samples(s
, devpriv
->ai_buffer
, num_samples
);
1255 if (cmd
->stop_src
== TRIG_COUNT
&&
1256 async
->scans_done
>= cmd
->stop_arg
)
1257 async
->events
|= COMEDI_CB_EOA
;
1259 /* clear half-full interrupt latch */
1260 spin_lock_irqsave(&dev
->spinlock
, flags
);
1261 outw(devpriv
->adc_fifo_bits
| INT
,
1262 devpriv
->pcibar1
+ INT_ADCFIFO
);
1263 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1264 /* else if fifo not empty */
1265 } else if (status
& (ADNEI
| EOBI
)) {
1266 for (i
= 0; i
< timeout
; i
++) {
1269 /* break if fifo is empty */
1270 if ((ADNE
& inw(devpriv
->pcibar1
+
1273 val
= inw(devpriv
->adc_fifo
);
1274 comedi_buf_write_samples(s
, &val
, 1);
1276 if (cmd
->stop_src
== TRIG_COUNT
&&
1277 async
->scans_done
>= cmd
->stop_arg
) {
1278 async
->events
|= COMEDI_CB_EOA
;
1282 /* clear not-empty interrupt latch */
1283 spin_lock_irqsave(&dev
->spinlock
, flags
);
1284 outw(devpriv
->adc_fifo_bits
| INT
,
1285 devpriv
->pcibar1
+ INT_ADCFIFO
);
1286 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1287 } else if (status
& EOAI
) {
1288 dev_err(dev
->class_dev
,
1289 "bug! encountered end of acquisition interrupt?\n");
1290 /* clear EOA interrupt latch */
1291 spin_lock_irqsave(&dev
->spinlock
, flags
);
1292 outw(devpriv
->adc_fifo_bits
| EOAI
,
1293 devpriv
->pcibar1
+ INT_ADCFIFO
);
1294 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1296 /* check for fifo overflow */
1297 if (status
& LADFUL
) {
1298 dev_err(dev
->class_dev
, "fifo overflow\n");
1299 /* clear overflow interrupt latch */
1300 spin_lock_irqsave(&dev
->spinlock
, flags
);
1301 outw(devpriv
->adc_fifo_bits
| LADFUL
,
1302 devpriv
->pcibar1
+ INT_ADCFIFO
);
1303 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1304 async
->events
|= COMEDI_CB_ERROR
;
1307 comedi_handle_events(dev
, s
);
1312 static int cb_pcidas_auto_attach(struct comedi_device
*dev
,
1313 unsigned long context
)
1315 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
1316 const struct cb_pcidas_board
*board
= NULL
;
1317 struct cb_pcidas_private
*devpriv
;
1318 struct comedi_subdevice
*s
;
1322 if (context
< ARRAY_SIZE(cb_pcidas_boards
))
1323 board
= &cb_pcidas_boards
[context
];
1326 dev
->board_ptr
= board
;
1327 dev
->board_name
= board
->name
;
1329 devpriv
= comedi_alloc_devpriv(dev
, sizeof(*devpriv
));
1333 ret
= comedi_pci_enable(dev
);
1337 devpriv
->s5933_config
= pci_resource_start(pcidev
, 0);
1338 devpriv
->pcibar1
= pci_resource_start(pcidev
, 1);
1339 devpriv
->adc_fifo
= pci_resource_start(pcidev
, 2);
1340 dev
->iobase
= pci_resource_start(pcidev
, 3);
1342 devpriv
->ao_registers
= pci_resource_start(pcidev
, 4);
1344 /* disable and clear interrupts on amcc s5933 */
1345 outl(INTCSR_INBOX_INTR_STATUS
,
1346 devpriv
->s5933_config
+ AMCC_OP_REG_INTCSR
);
1348 ret
= request_irq(pcidev
->irq
, cb_pcidas_interrupt
, IRQF_SHARED
,
1349 dev
->board_name
, dev
);
1351 dev_dbg(dev
->class_dev
, "unable to allocate irq %d\n",
1355 dev
->irq
= pcidev
->irq
;
1357 dev
->pacer
= comedi_8254_init(dev
->iobase
+ ADC8254
,
1358 I8254_OSC_BASE_10MHZ
, I8254_IO8
, 0);
1362 devpriv
->ao_pacer
= comedi_8254_init(dev
->iobase
+ DAC8254
,
1363 I8254_OSC_BASE_10MHZ
,
1365 if (!devpriv
->ao_pacer
)
1368 ret
= comedi_alloc_subdevices(dev
, 7);
1372 s
= &dev
->subdevices
[0];
1373 /* analog input subdevice */
1374 dev
->read_subdev
= s
;
1375 s
->type
= COMEDI_SUBD_AI
;
1376 s
->subdev_flags
= SDF_READABLE
| SDF_GROUND
| SDF_DIFF
| SDF_CMD_READ
;
1377 /* WARNING: Number of inputs in differential mode is ignored */
1379 s
->len_chanlist
= s
->n_chan
;
1380 s
->maxdata
= board
->is_16bit
? 0xffff : 0x0fff;
1381 s
->range_table
= board
->use_alt_range
? &cb_pcidas_alt_ranges
1382 : &cb_pcidas_ranges
;
1383 s
->insn_read
= cb_pcidas_ai_rinsn
;
1384 s
->insn_config
= ai_config_insn
;
1385 s
->do_cmd
= cb_pcidas_ai_cmd
;
1386 s
->do_cmdtest
= cb_pcidas_ai_cmdtest
;
1387 s
->cancel
= cb_pcidas_cancel
;
1389 /* analog output subdevice */
1390 s
= &dev
->subdevices
[1];
1391 if (board
->has_ao
) {
1392 s
->type
= COMEDI_SUBD_AO
;
1393 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
| SDF_GROUND
;
1395 s
->maxdata
= board
->is_16bit
? 0xffff : 0x0fff;
1396 s
->range_table
= &cb_pcidas_ao_ranges
;
1397 /* default to no fifo (*insn_write) */
1398 s
->insn_write
= cb_pcidas_ao_nofifo_winsn
;
1400 ret
= comedi_alloc_subdev_readback(s
);
1404 if (board
->has_ao_fifo
) {
1405 dev
->write_subdev
= s
;
1406 s
->subdev_flags
|= SDF_CMD_WRITE
;
1407 /* use fifo (*insn_write) instead */
1408 s
->insn_write
= cb_pcidas_ao_fifo_winsn
;
1409 s
->do_cmdtest
= cb_pcidas_ao_cmdtest
;
1410 s
->do_cmd
= cb_pcidas_ao_cmd
;
1411 s
->cancel
= cb_pcidas_ao_cancel
;
1414 s
->type
= COMEDI_SUBD_UNUSED
;
1418 s
= &dev
->subdevices
[2];
1419 ret
= subdev_8255_init(dev
, s
, NULL
, DIO_8255
);
1423 /* serial EEPROM, */
1424 s
= &dev
->subdevices
[3];
1425 s
->type
= COMEDI_SUBD_MEMORY
;
1426 s
->subdev_flags
= SDF_READABLE
| SDF_INTERNAL
;
1429 s
->insn_read
= eeprom_read_insn
;
1432 s
= &dev
->subdevices
[4];
1433 s
->type
= COMEDI_SUBD_CALIB
;
1434 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
| SDF_INTERNAL
;
1437 s
->insn_write
= cb_pcidas_caldac_insn_write
;
1439 ret
= comedi_alloc_subdev_readback(s
);
1443 for (i
= 0; i
< s
->n_chan
; i
++) {
1444 caldac_8800_write(dev
, i
, s
->maxdata
/ 2);
1445 s
->readback
[i
] = s
->maxdata
/ 2;
1448 /* trim potentiometer */
1449 s
= &dev
->subdevices
[5];
1450 s
->type
= COMEDI_SUBD_CALIB
;
1451 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
| SDF_INTERNAL
;
1452 if (board
->trimpot
== AD7376
) {
1459 s
->insn_write
= cb_pcidas_trimpot_insn_write
;
1461 ret
= comedi_alloc_subdev_readback(s
);
1465 for (i
= 0; i
< s
->n_chan
; i
++) {
1466 cb_pcidas_trimpot_write(dev
, i
, s
->maxdata
/ 2);
1467 s
->readback
[i
] = s
->maxdata
/ 2;
1471 s
= &dev
->subdevices
[6];
1472 if (board
->has_dac08
) {
1473 s
->type
= COMEDI_SUBD_CALIB
;
1474 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
| SDF_INTERNAL
;
1477 s
->insn_write
= cb_pcidas_dac08_insn_write
;
1479 ret
= comedi_alloc_subdev_readback(s
);
1483 for (i
= 0; i
< s
->n_chan
; i
++) {
1484 dac08_write(dev
, s
->maxdata
/ 2);
1485 s
->readback
[i
] = s
->maxdata
/ 2;
1488 s
->type
= COMEDI_SUBD_UNUSED
;
1491 /* make sure mailbox 4 is empty */
1492 inl(devpriv
->s5933_config
+ AMCC_OP_REG_IMB4
);
1493 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1494 devpriv
->s5933_intcsr_bits
=
1495 INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1496 INTCSR_INBOX_FULL_INT
;
1497 /* clear and enable interrupt on amcc s5933 */
1498 outl(devpriv
->s5933_intcsr_bits
| INTCSR_INBOX_INTR_STATUS
,
1499 devpriv
->s5933_config
+ AMCC_OP_REG_INTCSR
);
1504 static void cb_pcidas_detach(struct comedi_device
*dev
)
1506 struct cb_pcidas_private
*devpriv
= dev
->private;
1509 if (devpriv
->s5933_config
)
1510 outl(INTCSR_INBOX_INTR_STATUS
,
1511 devpriv
->s5933_config
+ AMCC_OP_REG_INTCSR
);
1512 kfree(devpriv
->ao_pacer
);
1514 comedi_pci_detach(dev
);
1517 static struct comedi_driver cb_pcidas_driver
= {
1518 .driver_name
= "cb_pcidas",
1519 .module
= THIS_MODULE
,
1520 .auto_attach
= cb_pcidas_auto_attach
,
1521 .detach
= cb_pcidas_detach
,
1524 static int cb_pcidas_pci_probe(struct pci_dev
*dev
,
1525 const struct pci_device_id
*id
)
1527 return comedi_pci_auto_config(dev
, &cb_pcidas_driver
,
1531 static const struct pci_device_id cb_pcidas_pci_table
[] = {
1532 { PCI_VDEVICE(CB
, 0x0001), BOARD_PCIDAS1602_16
},
1533 { PCI_VDEVICE(CB
, 0x000f), BOARD_PCIDAS1200
},
1534 { PCI_VDEVICE(CB
, 0x0010), BOARD_PCIDAS1602_12
},
1535 { PCI_VDEVICE(CB
, 0x0019), BOARD_PCIDAS1200_JR
},
1536 { PCI_VDEVICE(CB
, 0x001c), BOARD_PCIDAS1602_16_JR
},
1537 { PCI_VDEVICE(CB
, 0x004c), BOARD_PCIDAS1000
},
1538 { PCI_VDEVICE(CB
, 0x001a), BOARD_PCIDAS1001
},
1539 { PCI_VDEVICE(CB
, 0x001b), BOARD_PCIDAS1002
},
1542 MODULE_DEVICE_TABLE(pci
, cb_pcidas_pci_table
);
1544 static struct pci_driver cb_pcidas_pci_driver
= {
1545 .name
= "cb_pcidas",
1546 .id_table
= cb_pcidas_pci_table
,
1547 .probe
= cb_pcidas_pci_probe
,
1548 .remove
= comedi_pci_auto_unconfig
,
1550 module_comedi_pci_driver(cb_pcidas_driver
, cb_pcidas_pci_driver
);
1552 MODULE_AUTHOR("Comedi http://www.comedi.org");
1553 MODULE_DESCRIPTION("Comedi low-level driver");
1554 MODULE_LICENSE("GPL");