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 ADCMUX_CONT 2 /* ADC CHANNEL MUX AND CONTROL reg */
101 #define BEGIN_SCAN(x) ((x) & 0xf)
102 #define END_SCAN(x) (((x) & 0xf) << 4)
103 #define GAIN_BITS(x) (((x) & 0x3) << 8)
104 #define UNIP 0x800 /* Analog front-end unipolar mode */
105 #define SE 0x400 /* Inputs in single-ended mode */
106 #define PACER_MASK 0x3000 /* pacer source bits */
107 #define PACER_INT 0x1000 /* int. pacer */
108 #define PACER_EXT_FALL 0x2000 /* ext. falling edge */
109 #define PACER_EXT_RISE 0x3000 /* ext. rising edge */
110 #define EOC 0x4000 /* adc not busy */
112 #define TRIG_CONTSTAT 4 /* TRIGGER CONTROL/STATUS register */
113 #define SW_TRIGGER 0x1 /* software start trigger */
114 #define EXT_TRIGGER 0x2 /* ext. start trigger */
115 #define ANALOG_TRIGGER 0x3 /* ext. analog trigger */
116 #define TRIGGER_MASK 0x3 /* start trigger mask */
117 #define TGPOL 0x04 /* invert trigger (1602 only) */
118 #define TGSEL 0x08 /* edge/level trigerred (1602 only) */
119 #define TGEN 0x10 /* enable external start trigger */
120 #define BURSTE 0x20 /* burst mode enable */
121 #define XTRCL 0x80 /* clear external trigger */
123 #define CALIBRATION_REG 6 /* CALIBRATION register */
124 #define SELECT_8800_BIT 0x100 /* select 8800 caldac */
125 #define SELECT_TRIMPOT_BIT 0x200 /* select ad7376 trim pot */
126 #define SELECT_DAC08_BIT 0x400 /* select dac08 caldac */
127 #define CAL_SRC_BITS(x) (((x) & 0x7) << 11)
128 #define CAL_EN_BIT 0x4000 /* calibration source enable */
129 #define SERIAL_DATA_IN_BIT 0x8000 /* serial data bit going to caldac */
131 #define DAC_CSR 0x8 /* dac control and status register */
132 #define DACEN 0x02 /* dac enable */
133 #define DAC_MODE_UPDATE_BOTH 0x80 /* update both dacs */
135 #define DAC_RANGE(c, r) (((r) & 0x3) << (8 + 2 * ((c) & 0x1)))
136 #define DAC_RANGE_MASK(c) DAC_RANGE((c), 0x3)
138 /* bits for 1602 series only */
139 #define DAC_EMPTY 0x1 /* fifo empty, read, write clear */
140 #define DAC_START 0x4 /* start/arm fifo operations */
141 #define DAC_PACER_MASK 0x18 /* bits that set pacer source */
142 #define DAC_PACER_INT 0x8 /* int. pacing */
143 #define DAC_PACER_EXT_FALL 0x10 /* ext. pacing, falling edge */
144 #define DAC_PACER_EXT_RISE 0x18 /* ext. pacing, rising edge */
146 #define DAC_CHAN_EN(c) BIT(5 + ((c) & 0x1))
149 * PCI BAR2 Register map (devpriv->pcibar2)
151 #define PCIDAS_AI_DATA_REG 0x00
152 #define PCIDAS_AI_FIFO_CLR_REG 0x02
155 * PCI BAR3 Register map (dev->iobase)
157 #define PCIDAS_AI_8254_BASE 0x00
158 #define PCIDAS_8255_BASE 0x04
159 #define PCIDAS_AO_8254_BASE 0x08
162 * PCI BAR4 Register map (devpriv->pcibar4)
164 #define PCIDAS_AO_DATA_REG(x) (0x00 + ((x) * 2))
165 #define PCIDAS_AO_FIFO_REG 0x00
166 #define PCIDAS_AO_FIFO_CLR_REG 0x02
168 /* analog input ranges for most boards */
169 static const struct comedi_lrange cb_pcidas_ranges
= {
182 /* pci-das1001 input ranges */
183 static const struct comedi_lrange cb_pcidas_alt_ranges
= {
196 /* analog output ranges */
197 static const struct comedi_lrange cb_pcidas_ao_ranges
= {
211 enum cb_pcidas_boardid
{
216 BOARD_PCIDAS1602_16_JR
,
222 struct cb_pcidas_board
{
224 int ai_speed
; /* fastest conversion period in ns */
225 int ao_scan_speed
; /* analog output scan speed for 1602 series */
226 int fifo_size
; /* number of samples fifo can hold */
227 enum trimpot_model trimpot
;
228 unsigned int is_16bit
; /* ai/ao is 1=16-bit; 0=12-bit */
229 unsigned int use_alt_range
:1; /* use alternate ai range table */
230 unsigned int has_ao
:1; /* has 2 analog output channels */
231 unsigned int has_ao_fifo
:1; /* analog output has fifo */
232 unsigned int has_dac08
:1;
233 unsigned int is_1602
:1;
236 static const struct cb_pcidas_board cb_pcidas_boards
[] = {
237 [BOARD_PCIDAS1602_16
] = {
238 .name
= "pci-das1602/16",
240 .ao_scan_speed
= 10000,
249 [BOARD_PCIDAS1200
] = {
250 .name
= "pci-das1200",
256 [BOARD_PCIDAS1602_12
] = {
257 .name
= "pci-das1602/12",
259 .ao_scan_speed
= 4000,
266 [BOARD_PCIDAS1200_JR
] = {
267 .name
= "pci-das1200/jr",
272 [BOARD_PCIDAS1602_16_JR
] = {
273 .name
= "pci-das1602/16/jr",
281 [BOARD_PCIDAS1000
] = {
282 .name
= "pci-das1000",
287 [BOARD_PCIDAS1001
] = {
288 .name
= "pci-das1001",
295 [BOARD_PCIDAS1002
] = {
296 .name
= "pci-das1002",
304 struct cb_pcidas_private
{
305 struct comedi_8254
*ao_pacer
;
307 unsigned long s5933_config
;
308 unsigned long pcibar1
;
309 unsigned long pcibar2
;
310 unsigned long pcibar4
;
311 /* bits to write to registers */
313 unsigned int s5933_intcsr_bits
;
314 unsigned int ao_control_bits
;
316 unsigned short ai_buffer
[AI_BUFFER_SIZE
];
317 unsigned short ao_buffer
[AO_BUFFER_SIZE
];
318 unsigned int calibration_source
;
321 static inline unsigned int cal_enable_bits(struct comedi_device
*dev
)
323 struct cb_pcidas_private
*devpriv
= dev
->private;
325 return CAL_EN_BIT
| CAL_SRC_BITS(devpriv
->calibration_source
);
328 static int cb_pcidas_ai_eoc(struct comedi_device
*dev
,
329 struct comedi_subdevice
*s
,
330 struct comedi_insn
*insn
,
331 unsigned long context
)
333 struct cb_pcidas_private
*devpriv
= dev
->private;
336 status
= inw(devpriv
->pcibar1
+ ADCMUX_CONT
);
342 static int cb_pcidas_ai_rinsn(struct comedi_device
*dev
,
343 struct comedi_subdevice
*s
,
344 struct comedi_insn
*insn
, unsigned int *data
)
346 struct cb_pcidas_private
*devpriv
= dev
->private;
347 unsigned int chan
= CR_CHAN(insn
->chanspec
);
348 unsigned int range
= CR_RANGE(insn
->chanspec
);
349 unsigned int aref
= CR_AREF(insn
->chanspec
);
354 /* enable calibration input if appropriate */
355 if (insn
->chanspec
& CR_ALT_SOURCE
) {
356 outw(cal_enable_bits(dev
),
357 devpriv
->pcibar1
+ CALIBRATION_REG
);
360 outw(0, devpriv
->pcibar1
+ CALIBRATION_REG
);
363 /* set mux limits and gain */
364 bits
= BEGIN_SCAN(chan
) | END_SCAN(chan
) | GAIN_BITS(range
);
365 /* set unipolar/bipolar */
366 if (comedi_range_is_unipolar(s
, range
))
368 /* set single-ended/differential */
369 if (aref
!= AREF_DIFF
)
371 outw(bits
, devpriv
->pcibar1
+ ADCMUX_CONT
);
374 outw(0, devpriv
->pcibar2
+ PCIDAS_AI_FIFO_CLR_REG
);
376 /* convert n samples */
377 for (n
= 0; n
< insn
->n
; n
++) {
378 /* trigger conversion */
379 outw(0, devpriv
->pcibar2
+ PCIDAS_AI_DATA_REG
);
381 /* wait for conversion to end */
382 ret
= comedi_timeout(dev
, s
, insn
, cb_pcidas_ai_eoc
, 0);
387 data
[n
] = inw(devpriv
->pcibar2
+ PCIDAS_AI_DATA_REG
);
390 /* return the number of samples read/written */
394 static int ai_config_insn(struct comedi_device
*dev
, struct comedi_subdevice
*s
,
395 struct comedi_insn
*insn
, unsigned int *data
)
397 struct cb_pcidas_private
*devpriv
= dev
->private;
399 unsigned int source
= data
[1];
402 case INSN_CONFIG_ALT_SOURCE
:
404 dev_err(dev
->class_dev
,
405 "invalid calibration source: %i\n",
409 devpriv
->calibration_source
= source
;
417 /* analog output insn for pcidas-1000 and 1200 series */
418 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device
*dev
,
419 struct comedi_subdevice
*s
,
420 struct comedi_insn
*insn
,
423 struct cb_pcidas_private
*devpriv
= dev
->private;
424 unsigned int chan
= CR_CHAN(insn
->chanspec
);
425 unsigned int range
= CR_RANGE(insn
->chanspec
);
428 /* set channel and range */
429 spin_lock_irqsave(&dev
->spinlock
, flags
);
430 devpriv
->ao_control_bits
&= (~DAC_MODE_UPDATE_BOTH
&
431 ~DAC_RANGE_MASK(chan
));
432 devpriv
->ao_control_bits
|= (DACEN
| DAC_RANGE(chan
, range
));
433 outw(devpriv
->ao_control_bits
, devpriv
->pcibar1
+ DAC_CSR
);
434 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
436 /* remember value for readback */
437 s
->readback
[chan
] = data
[0];
440 outw(data
[0], devpriv
->pcibar4
+ PCIDAS_AO_DATA_REG(chan
));
445 /* analog output insn for pcidas-1602 series */
446 static int cb_pcidas_ao_fifo_winsn(struct comedi_device
*dev
,
447 struct comedi_subdevice
*s
,
448 struct comedi_insn
*insn
, unsigned int *data
)
450 struct cb_pcidas_private
*devpriv
= dev
->private;
451 unsigned int chan
= CR_CHAN(insn
->chanspec
);
452 unsigned int range
= CR_RANGE(insn
->chanspec
);
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_control_bits
&= (~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) &
461 ~DAC_RANGE_MASK(chan
) & ~DAC_PACER_MASK
);
462 devpriv
->ao_control_bits
|= (DACEN
| DAC_RANGE(chan
, range
) |
463 DAC_CHAN_EN(chan
) | DAC_START
);
464 outw(devpriv
->ao_control_bits
, devpriv
->pcibar1
+ DAC_CSR
);
465 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
467 /* remember value for readback */
468 s
->readback
[chan
] = data
[0];
471 outw(data
[0], devpriv
->pcibar4
+ PCIDAS_AO_FIFO_REG
);
476 static int wait_for_nvram_ready(unsigned long s5933_base_addr
)
478 static const int timeout
= 1000;
481 for (i
= 0; i
< timeout
; i
++) {
482 if ((inb(s5933_base_addr
+
483 AMCC_OP_REG_MCSR_NVCMD
) & MCSR_NV_BUSY
)
491 static int nvram_read(struct comedi_device
*dev
, unsigned int address
,
494 struct cb_pcidas_private
*devpriv
= dev
->private;
495 unsigned long iobase
= devpriv
->s5933_config
;
497 if (wait_for_nvram_ready(iobase
) < 0)
500 outb(MCSR_NV_ENABLE
| MCSR_NV_LOAD_LOW_ADDR
,
501 iobase
+ AMCC_OP_REG_MCSR_NVCMD
);
502 outb(address
& 0xff, iobase
+ AMCC_OP_REG_MCSR_NVDATA
);
503 outb(MCSR_NV_ENABLE
| MCSR_NV_LOAD_HIGH_ADDR
,
504 iobase
+ AMCC_OP_REG_MCSR_NVCMD
);
505 outb((address
>> 8) & 0xff, iobase
+ AMCC_OP_REG_MCSR_NVDATA
);
506 outb(MCSR_NV_ENABLE
| MCSR_NV_READ
, iobase
+ AMCC_OP_REG_MCSR_NVCMD
);
508 if (wait_for_nvram_ready(iobase
) < 0)
511 *data
= inb(iobase
+ AMCC_OP_REG_MCSR_NVDATA
);
516 static int eeprom_read_insn(struct comedi_device
*dev
,
517 struct comedi_subdevice
*s
,
518 struct comedi_insn
*insn
, unsigned int *data
)
523 retval
= nvram_read(dev
, CR_CHAN(insn
->chanspec
), &nvram_data
);
527 data
[0] = nvram_data
;
532 static void write_calibration_bitstream(struct comedi_device
*dev
,
533 unsigned int register_bits
,
534 unsigned int bitstream
,
535 unsigned int bitstream_length
)
537 struct cb_pcidas_private
*devpriv
= dev
->private;
538 static const int write_delay
= 1;
541 for (bit
= 1 << (bitstream_length
- 1); bit
; bit
>>= 1) {
543 register_bits
|= SERIAL_DATA_IN_BIT
;
545 register_bits
&= ~SERIAL_DATA_IN_BIT
;
547 outw(register_bits
, devpriv
->pcibar1
+ CALIBRATION_REG
);
551 static void caldac_8800_write(struct comedi_device
*dev
,
552 unsigned int chan
, uint8_t val
)
554 struct cb_pcidas_private
*devpriv
= dev
->private;
555 static const int bitstream_length
= 11;
556 unsigned int bitstream
= ((chan
& 0x7) << 8) | val
;
557 static const int caldac_8800_udelay
= 1;
559 write_calibration_bitstream(dev
, cal_enable_bits(dev
), bitstream
,
562 udelay(caldac_8800_udelay
);
563 outw(cal_enable_bits(dev
) | SELECT_8800_BIT
,
564 devpriv
->pcibar1
+ CALIBRATION_REG
);
565 udelay(caldac_8800_udelay
);
566 outw(cal_enable_bits(dev
), devpriv
->pcibar1
+ CALIBRATION_REG
);
569 static int cb_pcidas_caldac_insn_write(struct comedi_device
*dev
,
570 struct comedi_subdevice
*s
,
571 struct comedi_insn
*insn
,
574 unsigned int chan
= CR_CHAN(insn
->chanspec
);
577 unsigned int val
= data
[insn
->n
- 1];
579 if (s
->readback
[chan
] != val
) {
580 caldac_8800_write(dev
, chan
, val
);
581 s
->readback
[chan
] = val
;
588 /* 1602/16 pregain offset */
589 static void dac08_write(struct comedi_device
*dev
, unsigned int value
)
591 struct cb_pcidas_private
*devpriv
= dev
->private;
594 value
|= cal_enable_bits(dev
);
596 /* latch the new value into the caldac */
597 outw(value
, devpriv
->pcibar1
+ CALIBRATION_REG
);
599 outw(value
| SELECT_DAC08_BIT
,
600 devpriv
->pcibar1
+ CALIBRATION_REG
);
602 outw(value
, devpriv
->pcibar1
+ CALIBRATION_REG
);
606 static int cb_pcidas_dac08_insn_write(struct comedi_device
*dev
,
607 struct comedi_subdevice
*s
,
608 struct comedi_insn
*insn
,
611 unsigned int chan
= CR_CHAN(insn
->chanspec
);
614 unsigned int val
= data
[insn
->n
- 1];
616 if (s
->readback
[chan
] != val
) {
617 dac08_write(dev
, val
);
618 s
->readback
[chan
] = val
;
625 static int trimpot_7376_write(struct comedi_device
*dev
, uint8_t value
)
627 struct cb_pcidas_private
*devpriv
= dev
->private;
628 static const int bitstream_length
= 7;
629 unsigned int bitstream
= value
& 0x7f;
630 unsigned int register_bits
;
631 static const int ad7376_udelay
= 1;
633 register_bits
= cal_enable_bits(dev
) | SELECT_TRIMPOT_BIT
;
634 udelay(ad7376_udelay
);
635 outw(register_bits
, devpriv
->pcibar1
+ CALIBRATION_REG
);
637 write_calibration_bitstream(dev
, register_bits
, bitstream
,
640 udelay(ad7376_udelay
);
641 outw(cal_enable_bits(dev
), devpriv
->pcibar1
+ CALIBRATION_REG
);
648 * ch 1 : adc postgain offset */
649 static int trimpot_8402_write(struct comedi_device
*dev
, unsigned int channel
,
652 struct cb_pcidas_private
*devpriv
= dev
->private;
653 static const int bitstream_length
= 10;
654 unsigned int bitstream
= ((channel
& 0x3) << 8) | (value
& 0xff);
655 unsigned int register_bits
;
656 static const int ad8402_udelay
= 1;
658 register_bits
= cal_enable_bits(dev
) | SELECT_TRIMPOT_BIT
;
659 udelay(ad8402_udelay
);
660 outw(register_bits
, devpriv
->pcibar1
+ CALIBRATION_REG
);
662 write_calibration_bitstream(dev
, register_bits
, bitstream
,
665 udelay(ad8402_udelay
);
666 outw(cal_enable_bits(dev
), devpriv
->pcibar1
+ CALIBRATION_REG
);
671 static void cb_pcidas_trimpot_write(struct comedi_device
*dev
,
672 unsigned int chan
, unsigned int val
)
674 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
676 switch (board
->trimpot
) {
678 trimpot_7376_write(dev
, val
);
681 trimpot_8402_write(dev
, chan
, val
);
684 dev_err(dev
->class_dev
, "driver bug?\n");
689 static int cb_pcidas_trimpot_insn_write(struct comedi_device
*dev
,
690 struct comedi_subdevice
*s
,
691 struct comedi_insn
*insn
,
694 unsigned int chan
= CR_CHAN(insn
->chanspec
);
697 unsigned int val
= data
[insn
->n
- 1];
699 if (s
->readback
[chan
] != val
) {
700 cb_pcidas_trimpot_write(dev
, chan
, val
);
701 s
->readback
[chan
] = val
;
708 static int cb_pcidas_ai_check_chanlist(struct comedi_device
*dev
,
709 struct comedi_subdevice
*s
,
710 struct comedi_cmd
*cmd
)
712 unsigned int chan0
= CR_CHAN(cmd
->chanlist
[0]);
713 unsigned int range0
= CR_RANGE(cmd
->chanlist
[0]);
716 for (i
= 1; i
< cmd
->chanlist_len
; i
++) {
717 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
718 unsigned int range
= CR_RANGE(cmd
->chanlist
[i
]);
720 if (chan
!= (chan0
+ i
) % s
->n_chan
) {
721 dev_dbg(dev
->class_dev
,
722 "entries in chanlist must be consecutive channels, counting upwards\n");
726 if (range
!= range0
) {
727 dev_dbg(dev
->class_dev
,
728 "entries in chanlist must all have the same gain\n");
735 static int cb_pcidas_ai_cmdtest(struct comedi_device
*dev
,
736 struct comedi_subdevice
*s
,
737 struct comedi_cmd
*cmd
)
739 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
743 /* Step 1 : check if triggers are trivially valid */
745 err
|= comedi_check_trigger_src(&cmd
->start_src
, TRIG_NOW
| TRIG_EXT
);
746 err
|= comedi_check_trigger_src(&cmd
->scan_begin_src
,
747 TRIG_FOLLOW
| TRIG_TIMER
| TRIG_EXT
);
748 err
|= comedi_check_trigger_src(&cmd
->convert_src
,
749 TRIG_TIMER
| TRIG_NOW
| TRIG_EXT
);
750 err
|= comedi_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
751 err
|= comedi_check_trigger_src(&cmd
->stop_src
, TRIG_COUNT
| TRIG_NONE
);
756 /* Step 2a : make sure trigger sources are unique */
758 err
|= comedi_check_trigger_is_unique(cmd
->start_src
);
759 err
|= comedi_check_trigger_is_unique(cmd
->scan_begin_src
);
760 err
|= comedi_check_trigger_is_unique(cmd
->convert_src
);
761 err
|= comedi_check_trigger_is_unique(cmd
->stop_src
);
763 /* Step 2b : and mutually compatible */
765 if (cmd
->scan_begin_src
== TRIG_FOLLOW
&& cmd
->convert_src
== TRIG_NOW
)
767 if (cmd
->scan_begin_src
!= TRIG_FOLLOW
&& cmd
->convert_src
!= TRIG_NOW
)
769 if (cmd
->start_src
== TRIG_EXT
&&
770 (cmd
->convert_src
== TRIG_EXT
|| cmd
->scan_begin_src
== TRIG_EXT
))
776 /* Step 3: check if arguments are trivially valid */
778 switch (cmd
->start_src
) {
780 err
|= comedi_check_trigger_arg_is(&cmd
->start_arg
, 0);
783 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
785 & (CR_FLAGS_MASK
& ~(CR_EDGE
| CR_INVERT
))) != 0) {
786 cmd
->start_arg
&= ~(CR_FLAGS_MASK
&
787 ~(CR_EDGE
| CR_INVERT
));
790 if (!board
->is_1602
&& (cmd
->start_arg
& CR_INVERT
)) {
791 cmd
->start_arg
&= (CR_FLAGS_MASK
& ~CR_INVERT
);
797 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
798 err
|= comedi_check_trigger_arg_min(&cmd
->scan_begin_arg
,
803 if (cmd
->convert_src
== TRIG_TIMER
) {
804 err
|= comedi_check_trigger_arg_min(&cmd
->convert_arg
,
808 err
|= comedi_check_trigger_arg_is(&cmd
->scan_end_arg
,
811 if (cmd
->stop_src
== TRIG_COUNT
)
812 err
|= comedi_check_trigger_arg_min(&cmd
->stop_arg
, 1);
814 err
|= comedi_check_trigger_arg_is(&cmd
->stop_arg
, 0);
819 /* step 4: fix up any arguments */
821 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
822 arg
= cmd
->scan_begin_arg
;
823 comedi_8254_cascade_ns_to_timer(dev
->pacer
, &arg
, cmd
->flags
);
824 err
|= comedi_check_trigger_arg_is(&cmd
->scan_begin_arg
, arg
);
826 if (cmd
->convert_src
== TRIG_TIMER
) {
827 arg
= cmd
->convert_arg
;
828 comedi_8254_cascade_ns_to_timer(dev
->pacer
, &arg
, cmd
->flags
);
829 err
|= comedi_check_trigger_arg_is(&cmd
->convert_arg
, arg
);
835 /* Step 5: check channel list if it exists */
836 if (cmd
->chanlist
&& cmd
->chanlist_len
> 0)
837 err
|= cb_pcidas_ai_check_chanlist(dev
, s
, cmd
);
845 static int cb_pcidas_ai_cmd(struct comedi_device
*dev
,
846 struct comedi_subdevice
*s
)
848 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
849 struct cb_pcidas_private
*devpriv
= dev
->private;
850 struct comedi_async
*async
= s
->async
;
851 struct comedi_cmd
*cmd
= &async
->cmd
;
852 unsigned int range0
= CR_RANGE(cmd
->chanlist
[0]);
856 /* make sure CAL_EN_BIT is disabled */
857 outw(0, devpriv
->pcibar1
+ CALIBRATION_REG
);
858 /* initialize before settings pacer source and count values */
859 outw(0, devpriv
->pcibar1
+ TRIG_CONTSTAT
);
861 outw(0, devpriv
->pcibar2
+ PCIDAS_AI_FIFO_CLR_REG
);
863 /* set mux limits, gain and pacer source */
864 bits
= BEGIN_SCAN(CR_CHAN(cmd
->chanlist
[0])) |
865 END_SCAN(CR_CHAN(cmd
->chanlist
[cmd
->chanlist_len
- 1])) |
867 /* set unipolar/bipolar */
868 if (comedi_range_is_unipolar(s
, range0
))
870 /* set singleended/differential */
871 if (CR_AREF(cmd
->chanlist
[0]) != AREF_DIFF
)
873 /* set pacer source */
874 if (cmd
->convert_src
== TRIG_EXT
|| cmd
->scan_begin_src
== TRIG_EXT
)
875 bits
|= PACER_EXT_RISE
;
878 outw(bits
, devpriv
->pcibar1
+ ADCMUX_CONT
);
881 if (cmd
->scan_begin_src
== TRIG_TIMER
||
882 cmd
->convert_src
== TRIG_TIMER
) {
883 comedi_8254_update_divisors(dev
->pacer
);
884 comedi_8254_pacer_enable(dev
->pacer
, 1, 2, true);
887 /* enable interrupts */
888 spin_lock_irqsave(&dev
->spinlock
, flags
);
889 devpriv
->ctrl
|= PCIDAS_CTRL_INTE
;
890 devpriv
->ctrl
&= ~PCIDAS_CTRL_INT_MASK
;
891 if (cmd
->flags
& CMDF_WAKE_EOS
) {
892 if (cmd
->convert_src
== TRIG_NOW
&& cmd
->chanlist_len
> 1) {
893 /* interrupt end of burst */
894 devpriv
->ctrl
|= PCIDAS_CTRL_INT_EOS
;
896 /* interrupt fifo not empty */
897 devpriv
->ctrl
|= PCIDAS_CTRL_INT_FNE
;
900 /* interrupt fifo half full */
901 devpriv
->ctrl
|= PCIDAS_CTRL_INT_FHF
;
904 /* enable (and clear) interrupts */
906 PCIDAS_CTRL_EOAI
| PCIDAS_CTRL_INT_CLR
| PCIDAS_CTRL_LADFUL
,
907 devpriv
->pcibar1
+ PCIDAS_CTRL_REG
);
908 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
910 /* set start trigger and burst mode */
912 if (cmd
->start_src
== TRIG_NOW
) {
914 } else { /* TRIG_EXT */
915 bits
|= EXT_TRIGGER
| TGEN
| XTRCL
;
916 if (board
->is_1602
) {
917 if (cmd
->start_arg
& CR_INVERT
)
919 if (cmd
->start_arg
& CR_EDGE
)
923 if (cmd
->convert_src
== TRIG_NOW
&& cmd
->chanlist_len
> 1)
925 outw(bits
, devpriv
->pcibar1
+ TRIG_CONTSTAT
);
930 static int cb_pcidas_ao_check_chanlist(struct comedi_device
*dev
,
931 struct comedi_subdevice
*s
,
932 struct comedi_cmd
*cmd
)
934 unsigned int chan0
= CR_CHAN(cmd
->chanlist
[0]);
936 if (cmd
->chanlist_len
> 1) {
937 unsigned int chan1
= CR_CHAN(cmd
->chanlist
[1]);
939 if (chan0
!= 0 || chan1
!= 1) {
940 dev_dbg(dev
->class_dev
,
941 "channels must be ordered channel 0, channel 1 in chanlist\n");
949 static int cb_pcidas_ao_cmdtest(struct comedi_device
*dev
,
950 struct comedi_subdevice
*s
,
951 struct comedi_cmd
*cmd
)
953 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
954 struct cb_pcidas_private
*devpriv
= dev
->private;
957 /* Step 1 : check if triggers are trivially valid */
959 err
|= comedi_check_trigger_src(&cmd
->start_src
, TRIG_INT
);
960 err
|= comedi_check_trigger_src(&cmd
->scan_begin_src
,
961 TRIG_TIMER
| TRIG_EXT
);
962 err
|= comedi_check_trigger_src(&cmd
->convert_src
, TRIG_NOW
);
963 err
|= comedi_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
964 err
|= comedi_check_trigger_src(&cmd
->stop_src
, TRIG_COUNT
| TRIG_NONE
);
969 /* Step 2a : make sure trigger sources are unique */
971 err
|= comedi_check_trigger_is_unique(cmd
->scan_begin_src
);
972 err
|= comedi_check_trigger_is_unique(cmd
->stop_src
);
974 /* Step 2b : and mutually compatible */
979 /* Step 3: check if arguments are trivially valid */
981 err
|= comedi_check_trigger_arg_is(&cmd
->start_arg
, 0);
983 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
984 err
|= comedi_check_trigger_arg_min(&cmd
->scan_begin_arg
,
985 board
->ao_scan_speed
);
988 err
|= comedi_check_trigger_arg_is(&cmd
->scan_end_arg
,
991 if (cmd
->stop_src
== TRIG_COUNT
)
992 err
|= comedi_check_trigger_arg_min(&cmd
->stop_arg
, 1);
994 err
|= comedi_check_trigger_arg_is(&cmd
->stop_arg
, 0);
999 /* step 4: fix up any arguments */
1001 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
1002 unsigned int arg
= cmd
->scan_begin_arg
;
1004 comedi_8254_cascade_ns_to_timer(devpriv
->ao_pacer
,
1006 err
|= comedi_check_trigger_arg_is(&cmd
->scan_begin_arg
, arg
);
1012 /* Step 5: check channel list if it exists */
1013 if (cmd
->chanlist
&& cmd
->chanlist_len
> 0)
1014 err
|= cb_pcidas_ao_check_chanlist(dev
, s
, cmd
);
1022 /* cancel analog input command */
1023 static int cb_pcidas_cancel(struct comedi_device
*dev
,
1024 struct comedi_subdevice
*s
)
1026 struct cb_pcidas_private
*devpriv
= dev
->private;
1027 unsigned long flags
;
1029 spin_lock_irqsave(&dev
->spinlock
, flags
);
1030 /* disable interrupts */
1031 devpriv
->ctrl
&= ~(PCIDAS_CTRL_INTE
| PCIDAS_CTRL_EOAIE
);
1032 outw(devpriv
->ctrl
, devpriv
->pcibar1
+ PCIDAS_CTRL_REG
);
1033 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1035 /* disable start trigger source and burst mode */
1036 outw(0, devpriv
->pcibar1
+ TRIG_CONTSTAT
);
1037 /* software pacer source */
1038 outw(0, devpriv
->pcibar1
+ ADCMUX_CONT
);
1043 static void cb_pcidas_ao_load_fifo(struct comedi_device
*dev
,
1044 struct comedi_subdevice
*s
,
1045 unsigned int nsamples
)
1047 struct cb_pcidas_private
*devpriv
= dev
->private;
1048 unsigned int nbytes
;
1050 nsamples
= comedi_nsamples_left(s
, nsamples
);
1051 nbytes
= comedi_buf_read_samples(s
, devpriv
->ao_buffer
, nsamples
);
1053 nsamples
= comedi_bytes_to_samples(s
, nbytes
);
1054 outsw(devpriv
->pcibar4
+ PCIDAS_AO_FIFO_REG
,
1055 devpriv
->ao_buffer
, nsamples
);
1058 static int cb_pcidas_ao_inttrig(struct comedi_device
*dev
,
1059 struct comedi_subdevice
*s
,
1060 unsigned int trig_num
)
1062 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
1063 struct cb_pcidas_private
*devpriv
= dev
->private;
1064 struct comedi_async
*async
= s
->async
;
1065 struct comedi_cmd
*cmd
= &async
->cmd
;
1066 unsigned long flags
;
1068 if (trig_num
!= cmd
->start_arg
)
1071 cb_pcidas_ao_load_fifo(dev
, s
, board
->fifo_size
);
1073 /* enable dac half-full and empty interrupts */
1074 spin_lock_irqsave(&dev
->spinlock
, flags
);
1075 devpriv
->ctrl
|= PCIDAS_CTRL_DAEMIE
| PCIDAS_CTRL_DAHFIE
;
1077 /* enable and clear interrupts */
1078 outw(devpriv
->ctrl
| PCIDAS_CTRL_DAEMI
| PCIDAS_CTRL_DAHFI
,
1079 devpriv
->pcibar1
+ PCIDAS_CTRL_REG
);
1082 devpriv
->ao_control_bits
|= DAC_START
| DACEN
| DAC_EMPTY
;
1083 outw(devpriv
->ao_control_bits
, devpriv
->pcibar1
+ DAC_CSR
);
1085 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1087 async
->inttrig
= NULL
;
1092 static int cb_pcidas_ao_cmd(struct comedi_device
*dev
,
1093 struct comedi_subdevice
*s
)
1095 struct cb_pcidas_private
*devpriv
= dev
->private;
1096 struct comedi_async
*async
= s
->async
;
1097 struct comedi_cmd
*cmd
= &async
->cmd
;
1099 unsigned long flags
;
1101 /* set channel limits, gain */
1102 spin_lock_irqsave(&dev
->spinlock
, flags
);
1103 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
1104 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
1105 unsigned int range
= CR_RANGE(cmd
->chanlist
[i
]);
1107 /* enable channel */
1108 devpriv
->ao_control_bits
|= DAC_CHAN_EN(chan
);
1110 devpriv
->ao_control_bits
|= DAC_RANGE(chan
, range
);
1113 /* disable analog out before settings pacer source and count values */
1114 outw(devpriv
->ao_control_bits
, devpriv
->pcibar1
+ DAC_CSR
);
1115 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1118 outw(0, devpriv
->pcibar4
+ PCIDAS_AO_FIFO_CLR_REG
);
1121 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
1122 comedi_8254_update_divisors(devpriv
->ao_pacer
);
1123 comedi_8254_pacer_enable(devpriv
->ao_pacer
, 1, 2, true);
1126 /* set pacer source */
1127 spin_lock_irqsave(&dev
->spinlock
, flags
);
1128 switch (cmd
->scan_begin_src
) {
1130 devpriv
->ao_control_bits
|= DAC_PACER_INT
;
1133 devpriv
->ao_control_bits
|= DAC_PACER_EXT_RISE
;
1136 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1137 dev_err(dev
->class_dev
, "error setting dac pacer source\n");
1140 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1142 async
->inttrig
= cb_pcidas_ao_inttrig
;
1147 /* cancel analog output command */
1148 static int cb_pcidas_ao_cancel(struct comedi_device
*dev
,
1149 struct comedi_subdevice
*s
)
1151 struct cb_pcidas_private
*devpriv
= dev
->private;
1152 unsigned long flags
;
1154 spin_lock_irqsave(&dev
->spinlock
, flags
);
1155 /* disable interrupts */
1156 devpriv
->ctrl
&= ~(PCIDAS_CTRL_DAHFIE
| PCIDAS_CTRL_DAEMIE
);
1157 outw(devpriv
->ctrl
, devpriv
->pcibar1
+ PCIDAS_CTRL_REG
);
1159 /* disable output */
1160 devpriv
->ao_control_bits
&= ~DACEN
& ~DAC_PACER_MASK
;
1161 outw(devpriv
->ao_control_bits
, devpriv
->pcibar1
+ DAC_CSR
);
1162 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1167 static void handle_ao_interrupt(struct comedi_device
*dev
, unsigned int status
)
1169 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
1170 struct cb_pcidas_private
*devpriv
= dev
->private;
1171 struct comedi_subdevice
*s
= dev
->write_subdev
;
1172 struct comedi_async
*async
= s
->async
;
1173 struct comedi_cmd
*cmd
= &async
->cmd
;
1174 unsigned long flags
;
1176 if (status
& PCIDAS_CTRL_DAEMI
) {
1177 /* clear dac empty interrupt latch */
1178 spin_lock_irqsave(&dev
->spinlock
, flags
);
1179 outw(devpriv
->ctrl
| PCIDAS_CTRL_DAEMI
,
1180 devpriv
->pcibar1
+ PCIDAS_CTRL_REG
);
1181 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1182 if (inw(devpriv
->pcibar4
+ DAC_CSR
) & DAC_EMPTY
) {
1183 if (cmd
->stop_src
== TRIG_COUNT
&&
1184 async
->scans_done
>= cmd
->stop_arg
) {
1185 async
->events
|= COMEDI_CB_EOA
;
1187 dev_err(dev
->class_dev
, "dac fifo underflow\n");
1188 async
->events
|= COMEDI_CB_ERROR
;
1191 } else if (status
& PCIDAS_CTRL_DAHFI
) {
1192 cb_pcidas_ao_load_fifo(dev
, s
, board
->fifo_size
/ 2);
1194 /* clear half-full interrupt latch */
1195 spin_lock_irqsave(&dev
->spinlock
, flags
);
1196 outw(devpriv
->ctrl
| PCIDAS_CTRL_DAHFI
,
1197 devpriv
->pcibar1
+ PCIDAS_CTRL_REG
);
1198 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1201 comedi_handle_events(dev
, s
);
1204 static irqreturn_t
cb_pcidas_interrupt(int irq
, void *d
)
1206 struct comedi_device
*dev
= d
;
1207 const struct cb_pcidas_board
*board
= dev
->board_ptr
;
1208 struct cb_pcidas_private
*devpriv
= dev
->private;
1209 struct comedi_subdevice
*s
= dev
->read_subdev
;
1210 struct comedi_async
*async
;
1211 struct comedi_cmd
*cmd
;
1212 int status
, s5933_status
;
1213 int half_fifo
= board
->fifo_size
/ 2;
1214 unsigned int num_samples
, i
;
1215 static const int timeout
= 10000;
1216 unsigned long flags
;
1224 s5933_status
= inl(devpriv
->s5933_config
+ AMCC_OP_REG_INTCSR
);
1226 if ((INTCSR_INTR_ASSERTED
& s5933_status
) == 0)
1229 /* make sure mailbox 4 is empty */
1230 inl_p(devpriv
->s5933_config
+ AMCC_OP_REG_IMB4
);
1231 /* clear interrupt on amcc s5933 */
1232 outl(devpriv
->s5933_intcsr_bits
| INTCSR_INBOX_INTR_STATUS
,
1233 devpriv
->s5933_config
+ AMCC_OP_REG_INTCSR
);
1235 status
= inw(devpriv
->pcibar1
+ PCIDAS_CTRL_REG
);
1237 /* check for analog output interrupt */
1238 if (status
& (PCIDAS_CTRL_DAHFI
| PCIDAS_CTRL_DAEMI
))
1239 handle_ao_interrupt(dev
, status
);
1240 /* check for analog input interrupts */
1241 /* if fifo half-full */
1242 if (status
& PCIDAS_CTRL_ADHFI
) {
1244 num_samples
= comedi_nsamples_left(s
, half_fifo
);
1245 insw(devpriv
->pcibar2
+ PCIDAS_AI_DATA_REG
,
1246 devpriv
->ai_buffer
, num_samples
);
1247 comedi_buf_write_samples(s
, devpriv
->ai_buffer
, num_samples
);
1249 if (cmd
->stop_src
== TRIG_COUNT
&&
1250 async
->scans_done
>= cmd
->stop_arg
)
1251 async
->events
|= COMEDI_CB_EOA
;
1253 /* clear half-full interrupt latch */
1254 spin_lock_irqsave(&dev
->spinlock
, flags
);
1255 outw(devpriv
->ctrl
| PCIDAS_CTRL_INT_CLR
,
1256 devpriv
->pcibar1
+ PCIDAS_CTRL_REG
);
1257 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1258 /* else if fifo not empty */
1259 } else if (status
& (PCIDAS_CTRL_ADNEI
| PCIDAS_CTRL_EOBI
)) {
1260 for (i
= 0; i
< timeout
; i
++) {
1263 /* break if fifo is empty */
1264 if ((inw(devpriv
->pcibar1
+ PCIDAS_CTRL_REG
) &
1265 PCIDAS_CTRL_ADNE
) == 0)
1267 val
= inw(devpriv
->pcibar2
+ PCIDAS_AI_DATA_REG
);
1268 comedi_buf_write_samples(s
, &val
, 1);
1270 if (cmd
->stop_src
== TRIG_COUNT
&&
1271 async
->scans_done
>= cmd
->stop_arg
) {
1272 async
->events
|= COMEDI_CB_EOA
;
1276 /* clear not-empty interrupt latch */
1277 spin_lock_irqsave(&dev
->spinlock
, flags
);
1278 outw(devpriv
->ctrl
| PCIDAS_CTRL_INT_CLR
,
1279 devpriv
->pcibar1
+ PCIDAS_CTRL_REG
);
1280 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1281 } else if (status
& PCIDAS_CTRL_EOAI
) {
1282 dev_err(dev
->class_dev
,
1283 "bug! encountered end of acquisition interrupt?\n");
1284 /* clear EOA interrupt latch */
1285 spin_lock_irqsave(&dev
->spinlock
, flags
);
1286 outw(devpriv
->ctrl
| PCIDAS_CTRL_EOAI
,
1287 devpriv
->pcibar1
+ PCIDAS_CTRL_REG
);
1288 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1290 /* check for fifo overflow */
1291 if (status
& PCIDAS_CTRL_LADFUL
) {
1292 dev_err(dev
->class_dev
, "fifo overflow\n");
1293 /* clear overflow interrupt latch */
1294 spin_lock_irqsave(&dev
->spinlock
, flags
);
1295 outw(devpriv
->ctrl
| PCIDAS_CTRL_LADFUL
,
1296 devpriv
->pcibar1
+ PCIDAS_CTRL_REG
);
1297 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1298 async
->events
|= COMEDI_CB_ERROR
;
1301 comedi_handle_events(dev
, s
);
1306 static int cb_pcidas_auto_attach(struct comedi_device
*dev
,
1307 unsigned long context
)
1309 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
1310 const struct cb_pcidas_board
*board
= NULL
;
1311 struct cb_pcidas_private
*devpriv
;
1312 struct comedi_subdevice
*s
;
1316 if (context
< ARRAY_SIZE(cb_pcidas_boards
))
1317 board
= &cb_pcidas_boards
[context
];
1320 dev
->board_ptr
= board
;
1321 dev
->board_name
= board
->name
;
1323 devpriv
= comedi_alloc_devpriv(dev
, sizeof(*devpriv
));
1327 ret
= comedi_pci_enable(dev
);
1331 devpriv
->s5933_config
= pci_resource_start(pcidev
, 0);
1332 devpriv
->pcibar1
= pci_resource_start(pcidev
, 1);
1333 devpriv
->pcibar2
= pci_resource_start(pcidev
, 2);
1334 dev
->iobase
= pci_resource_start(pcidev
, 3);
1336 devpriv
->pcibar4
= pci_resource_start(pcidev
, 4);
1338 /* disable and clear interrupts on amcc s5933 */
1339 outl(INTCSR_INBOX_INTR_STATUS
,
1340 devpriv
->s5933_config
+ AMCC_OP_REG_INTCSR
);
1342 ret
= request_irq(pcidev
->irq
, cb_pcidas_interrupt
, IRQF_SHARED
,
1343 dev
->board_name
, dev
);
1345 dev_dbg(dev
->class_dev
, "unable to allocate irq %d\n",
1349 dev
->irq
= pcidev
->irq
;
1351 dev
->pacer
= comedi_8254_init(dev
->iobase
+ PCIDAS_AI_8254_BASE
,
1352 I8254_OSC_BASE_10MHZ
, I8254_IO8
, 0);
1356 devpriv
->ao_pacer
= comedi_8254_init(dev
->iobase
+ PCIDAS_AO_8254_BASE
,
1357 I8254_OSC_BASE_10MHZ
,
1359 if (!devpriv
->ao_pacer
)
1362 ret
= comedi_alloc_subdevices(dev
, 7);
1366 s
= &dev
->subdevices
[0];
1367 /* analog input subdevice */
1368 dev
->read_subdev
= s
;
1369 s
->type
= COMEDI_SUBD_AI
;
1370 s
->subdev_flags
= SDF_READABLE
| SDF_GROUND
| SDF_DIFF
| SDF_CMD_READ
;
1371 /* WARNING: Number of inputs in differential mode is ignored */
1373 s
->len_chanlist
= s
->n_chan
;
1374 s
->maxdata
= board
->is_16bit
? 0xffff : 0x0fff;
1375 s
->range_table
= board
->use_alt_range
? &cb_pcidas_alt_ranges
1376 : &cb_pcidas_ranges
;
1377 s
->insn_read
= cb_pcidas_ai_rinsn
;
1378 s
->insn_config
= ai_config_insn
;
1379 s
->do_cmd
= cb_pcidas_ai_cmd
;
1380 s
->do_cmdtest
= cb_pcidas_ai_cmdtest
;
1381 s
->cancel
= cb_pcidas_cancel
;
1383 /* analog output subdevice */
1384 s
= &dev
->subdevices
[1];
1385 if (board
->has_ao
) {
1386 s
->type
= COMEDI_SUBD_AO
;
1387 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
| SDF_GROUND
;
1389 s
->maxdata
= board
->is_16bit
? 0xffff : 0x0fff;
1390 s
->range_table
= &cb_pcidas_ao_ranges
;
1391 /* default to no fifo (*insn_write) */
1392 s
->insn_write
= cb_pcidas_ao_nofifo_winsn
;
1394 ret
= comedi_alloc_subdev_readback(s
);
1398 if (board
->has_ao_fifo
) {
1399 dev
->write_subdev
= s
;
1400 s
->subdev_flags
|= SDF_CMD_WRITE
;
1401 /* use fifo (*insn_write) instead */
1402 s
->insn_write
= cb_pcidas_ao_fifo_winsn
;
1403 s
->do_cmdtest
= cb_pcidas_ao_cmdtest
;
1404 s
->do_cmd
= cb_pcidas_ao_cmd
;
1405 s
->cancel
= cb_pcidas_ao_cancel
;
1408 s
->type
= COMEDI_SUBD_UNUSED
;
1412 s
= &dev
->subdevices
[2];
1413 ret
= subdev_8255_init(dev
, s
, NULL
, PCIDAS_8255_BASE
);
1417 /* serial EEPROM, */
1418 s
= &dev
->subdevices
[3];
1419 s
->type
= COMEDI_SUBD_MEMORY
;
1420 s
->subdev_flags
= SDF_READABLE
| SDF_INTERNAL
;
1423 s
->insn_read
= eeprom_read_insn
;
1426 s
= &dev
->subdevices
[4];
1427 s
->type
= COMEDI_SUBD_CALIB
;
1428 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
| SDF_INTERNAL
;
1431 s
->insn_write
= cb_pcidas_caldac_insn_write
;
1433 ret
= comedi_alloc_subdev_readback(s
);
1437 for (i
= 0; i
< s
->n_chan
; i
++) {
1438 caldac_8800_write(dev
, i
, s
->maxdata
/ 2);
1439 s
->readback
[i
] = s
->maxdata
/ 2;
1442 /* trim potentiometer */
1443 s
= &dev
->subdevices
[5];
1444 s
->type
= COMEDI_SUBD_CALIB
;
1445 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
| SDF_INTERNAL
;
1446 if (board
->trimpot
== AD7376
) {
1453 s
->insn_write
= cb_pcidas_trimpot_insn_write
;
1455 ret
= comedi_alloc_subdev_readback(s
);
1459 for (i
= 0; i
< s
->n_chan
; i
++) {
1460 cb_pcidas_trimpot_write(dev
, i
, s
->maxdata
/ 2);
1461 s
->readback
[i
] = s
->maxdata
/ 2;
1465 s
= &dev
->subdevices
[6];
1466 if (board
->has_dac08
) {
1467 s
->type
= COMEDI_SUBD_CALIB
;
1468 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
| SDF_INTERNAL
;
1471 s
->insn_write
= cb_pcidas_dac08_insn_write
;
1473 ret
= comedi_alloc_subdev_readback(s
);
1477 for (i
= 0; i
< s
->n_chan
; i
++) {
1478 dac08_write(dev
, s
->maxdata
/ 2);
1479 s
->readback
[i
] = s
->maxdata
/ 2;
1482 s
->type
= COMEDI_SUBD_UNUSED
;
1485 /* make sure mailbox 4 is empty */
1486 inl(devpriv
->s5933_config
+ AMCC_OP_REG_IMB4
);
1487 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1488 devpriv
->s5933_intcsr_bits
=
1489 INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1490 INTCSR_INBOX_FULL_INT
;
1491 /* clear and enable interrupt on amcc s5933 */
1492 outl(devpriv
->s5933_intcsr_bits
| INTCSR_INBOX_INTR_STATUS
,
1493 devpriv
->s5933_config
+ AMCC_OP_REG_INTCSR
);
1498 static void cb_pcidas_detach(struct comedi_device
*dev
)
1500 struct cb_pcidas_private
*devpriv
= dev
->private;
1503 if (devpriv
->s5933_config
)
1504 outl(INTCSR_INBOX_INTR_STATUS
,
1505 devpriv
->s5933_config
+ AMCC_OP_REG_INTCSR
);
1506 kfree(devpriv
->ao_pacer
);
1508 comedi_pci_detach(dev
);
1511 static struct comedi_driver cb_pcidas_driver
= {
1512 .driver_name
= "cb_pcidas",
1513 .module
= THIS_MODULE
,
1514 .auto_attach
= cb_pcidas_auto_attach
,
1515 .detach
= cb_pcidas_detach
,
1518 static int cb_pcidas_pci_probe(struct pci_dev
*dev
,
1519 const struct pci_device_id
*id
)
1521 return comedi_pci_auto_config(dev
, &cb_pcidas_driver
,
1525 static const struct pci_device_id cb_pcidas_pci_table
[] = {
1526 { PCI_VDEVICE(CB
, 0x0001), BOARD_PCIDAS1602_16
},
1527 { PCI_VDEVICE(CB
, 0x000f), BOARD_PCIDAS1200
},
1528 { PCI_VDEVICE(CB
, 0x0010), BOARD_PCIDAS1602_12
},
1529 { PCI_VDEVICE(CB
, 0x0019), BOARD_PCIDAS1200_JR
},
1530 { PCI_VDEVICE(CB
, 0x001c), BOARD_PCIDAS1602_16_JR
},
1531 { PCI_VDEVICE(CB
, 0x004c), BOARD_PCIDAS1000
},
1532 { PCI_VDEVICE(CB
, 0x001a), BOARD_PCIDAS1001
},
1533 { PCI_VDEVICE(CB
, 0x001b), BOARD_PCIDAS1002
},
1536 MODULE_DEVICE_TABLE(pci
, cb_pcidas_pci_table
);
1538 static struct pci_driver cb_pcidas_pci_driver
= {
1539 .name
= "cb_pcidas",
1540 .id_table
= cb_pcidas_pci_table
,
1541 .probe
= cb_pcidas_pci_probe
,
1542 .remove
= comedi_pci_auto_unconfig
,
1544 module_comedi_pci_driver(cb_pcidas_driver
, cb_pcidas_pci_driver
);
1546 MODULE_AUTHOR("Comedi http://www.comedi.org");
1547 MODULE_DESCRIPTION("Comedi low-level driver");
1548 MODULE_LICENSE("GPL");