2 comedi/drivers/cb_pcidas.c
4 Developed by Ivan Martinez and Frank Mori Hess, with valuable help from
5 David Schleef and the rest of the Comedi developers comunity.
7 Copyright (C) 2001-2003 Ivan Martinez <imr@oersted.dtu.dk>
8 Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
10 COMEDI - Linux Control and Measurement Device Interface
11 Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 ************************************************************************
31 Description: MeasurementComputing PCI-DAS series with the AMCC S5933 PCI controller
32 Author: Ivan Martinez <imr@oersted.dtu.dk>,
33 Frank Mori Hess <fmhess@users.sourceforge.net>
35 Devices: [Measurement Computing] PCI-DAS1602/16 (cb_pcidas),
36 PCI-DAS1602/16jr, PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr,
37 PCI-DAS1000, PCI-DAS1001, PCI_DAS1002
40 There are many reports of the driver being used with most of the
41 supported cards. Despite no detailed log is maintained, it can
42 be said that the driver is quite tested and stable.
44 The boards may be autocalibrated using the comedi_calibrate
47 Configuration options:
48 [0] - PCI bus of device (optional)
49 [1] - PCI slot of device (optional)
50 If bus/slot is not specified, the first supported
51 PCI device found will be used.
53 For commands, the scanned channels must be consecutive
54 (i.e. 4-5-6-7, 2-3-4,...), and must all have the same
61 analog triggering on 1602 series
64 #include "../comedidev.h"
65 #include <linux/delay.h>
69 #include "amcc_s5933.h"
70 #include "comedi_pci.h"
71 #include "comedi_fc.h"
73 #undef CB_PCIDAS_DEBUG // disable debugging code
74 //#define CB_PCIDAS_DEBUG // enable debugging code
76 // PCI vendor number of ComputerBoards/MeasurementComputing
77 #define PCI_VENDOR_ID_CB 0x1307
78 #define TIMER_BASE 100 // 10MHz master clock
79 #define AI_BUFFER_SIZE 1024 // maximum fifo size of any supported board
80 #define AO_BUFFER_SIZE 1024 // maximum fifo size of any supported board
81 #define NUM_CHANNELS_8800 8
82 #define NUM_CHANNELS_7376 1
83 #define NUM_CHANNELS_8402 2
84 #define NUM_CHANNELS_DAC08 1
86 /* PCI-DAS base addresses */
88 // indices of base address regions
89 #define S5933_BADRINDEX 0
90 #define CONT_STAT_BADRINDEX 1
91 #define ADC_FIFO_BADRINDEX 2
92 #define PACER_BADRINDEX 3
93 #define AO_BADRINDEX 4
94 // sizes of io regions
95 #define CONT_STAT_SIZE 10
96 #define ADC_FIFO_SIZE 4
100 /* Control/Status registers */
101 #define INT_ADCFIFO 0 // INTERRUPT / ADC FIFO register
102 #define INT_EOS 0x1 // interrupt end of scan
103 #define INT_FHF 0x2 // interrupt fifo half full
104 #define INT_FNE 0x3 // interrupt fifo not empty
105 #define INT_MASK 0x3 // mask of interrupt select bits
106 #define INTE 0x4 // interrupt enable
107 #define DAHFIE 0x8 // dac half full interrupt enable
108 #define EOAIE 0x10 // end of aquisition interrupt enable
109 #define DAHFI 0x20 // dac half full read status / write interrupt clear
110 #define EOAI 0x40 // read end of acq. interrupt status / write clear
111 #define INT 0x80 // read interrupt status / write clear
112 #define EOBI 0x200 // read end of burst interrupt status
113 #define ADHFI 0x400 // read half-full interrupt status
114 #define ADNEI 0x800 // read fifo not empty interrupt latch status
115 #define ADNE 0x1000 // read, fifo not empty (realtime, not latched) status
116 #define DAEMIE 0x1000 // write, dac empty interrupt enable
117 #define LADFUL 0x2000 // read fifo overflow / write clear
118 #define DAEMI 0x4000 // dac fifo empty interrupt status / write clear
120 #define ADCMUX_CONT 2 // ADC CHANNEL MUX AND CONTROL register
121 #define BEGIN_SCAN(x) ((x) & 0xf)
122 #define END_SCAN(x) (((x) & 0xf) << 4)
123 #define GAIN_BITS(x) (((x) & 0x3) << 8)
124 #define UNIP 0x800 // Analog front-end unipolar for range
125 #define SE 0x400 // Inputs in single-ended mode
126 #define PACER_MASK 0x3000 // pacer source bits
127 #define PACER_INT 0x1000 // internal pacer
128 #define PACER_EXT_FALL 0x2000 // external falling edge
129 #define PACER_EXT_RISE 0x3000 // external rising edge
130 #define EOC 0x4000 // adc not busy
132 #define TRIG_CONTSTAT 4 // TRIGGER CONTROL/STATUS register
133 #define SW_TRIGGER 0x1 // software start trigger
134 #define EXT_TRIGGER 0x2 // external start trigger
135 #define ANALOG_TRIGGER 0x3 // external analog trigger
136 #define TRIGGER_MASK 0x3 // mask of bits that determine start trigger
137 #define TGEN 0x10 // enable external start trigger
138 #define BURSTE 0x20 // burst mode enable
139 #define XTRCL 0x80 // clear external trigger
141 #define CALIBRATION_REG 6 // CALIBRATION register
142 #define SELECT_8800_BIT 0x100 // select 8800 caldac
143 #define SELECT_TRIMPOT_BIT 0x200 // select ad7376 trim pot
144 #define SELECT_DAC08_BIT 0x400 // select dac08 caldac
145 #define CAL_SRC_BITS(x) (((x) & 0x7) << 11)
146 #define CAL_EN_BIT 0x4000 // read calibration source instead of analog input channel 0
147 #define SERIAL_DATA_IN_BIT 0x8000 // serial data stream going to 8800 and 7376
149 #define DAC_CSR 0x8 // dac control and status register
151 DACEN = 0x2, // dac enable
152 DAC_MODE_UPDATE_BOTH = 0x80, // update both dacs when dac0 is written
154 static inline unsigned int DAC_RANGE(unsigned int channel, unsigned int range)
156 return (range & 0x3) << (8 + 2 * (channel & 0x1));
158 static inline unsigned int DAC_RANGE_MASK(unsigned int channel)
160 return 0x3 << (8 + 2 * (channel & 0x1));
163 // bits for 1602 series only
164 enum dac_csr_bits_1602 {
165 DAC_EMPTY = 0x1, // dac fifo empty, read, write clear
166 DAC_START = 0x4, // start/arm dac fifo operations
167 DAC_PACER_MASK = 0x18, // bits that set dac pacer source
168 DAC_PACER_INT = 0x8, // dac internal pacing
169 DAC_PACER_EXT_FALL = 0x10, // dac external pacing, falling edge
170 DAC_PACER_EXT_RISE = 0x18, // dac external pacing, rising edge
172 static inline unsigned int DAC_CHAN_EN(unsigned int channel)
174 return 1 << (5 + (channel & 0x1)); // enable channel 0 or 1
177 /* analog input fifo */
178 #define ADCDATA 0 // ADC DATA register
179 #define ADCFIFOCLR 2 // ADC FIFO CLEAR
181 // pacer, counter, dio registers
186 // analog output registers for 100x, 1200 series
187 static inline unsigned int DAC_DATA_REG(unsigned int channel)
189 return 2 * (channel & 0x1);
192 /* analog output registers for 1602 series*/
193 #define DACDATA 0 // DAC DATA register
194 #define DACFIFOCLR 2 // DAC FIFO CLEAR
196 // bit in hexadecimal representation of range index that indicates unipolar input range
197 #define IS_UNIPOLAR 0x4
198 // analog input ranges for most boards
199 static const struct comedi_lrange cb_pcidas_ranges = {
213 // pci-das1001 input ranges
214 static const struct comedi_lrange cb_pcidas_alt_ranges = {
228 // analog output ranges
229 static const struct comedi_lrange cb_pcidas_ao_ranges = {
244 typedef struct cb_pcidas_board_struct {
246 unsigned short device_id;
247 int ai_se_chans; // Inputs in single-ended mode
248 int ai_diff_chans; // Inputs in differential mode
249 int ai_bits; // analog input resolution
250 int ai_speed; // fastest conversion period in ns
251 int ao_nchan; // number of analog out channels
252 int has_ao_fifo; // analog output has fifo
253 int ao_scan_speed; // analog output speed for 1602 series (for a scan, not conversion)
254 int fifo_size; // number of samples fifo can hold
255 const struct comedi_lrange *ranges;
256 enum trimpot_model trimpot;
257 unsigned has_dac08:1;
260 static const cb_pcidas_board cb_pcidas_boards[] = {
262 name: "pci-das1602/16",
272 ranges: &cb_pcidas_ranges,
286 ranges: &cb_pcidas_ranges,
291 name: "pci-das1602/12",
301 ranges: &cb_pcidas_ranges,
306 name: "pci-das1200/jr",
315 ranges: &cb_pcidas_ranges,
320 name: "pci-das1602/16/jr",
329 ranges: &cb_pcidas_ranges,
343 ranges: &cb_pcidas_ranges,
357 ranges: &cb_pcidas_alt_ranges,
371 ranges: &cb_pcidas_ranges,
377 // Number of boards in cb_pcidas_boards
378 #define N_BOARDS (sizeof(cb_pcidas_boards) / sizeof(cb_pcidas_board))
380 static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = {
381 {PCI_VENDOR_ID_CB, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
382 {PCI_VENDOR_ID_CB, 0x000f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
383 {PCI_VENDOR_ID_CB, 0x0010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
384 {PCI_VENDOR_ID_CB, 0x0019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
385 {PCI_VENDOR_ID_CB, 0x001c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
386 {PCI_VENDOR_ID_CB, 0x004c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
387 {PCI_VENDOR_ID_CB, 0x001a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
388 {PCI_VENDOR_ID_CB, 0x001b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
392 MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
395 * Useful for shorthand access to the particular board structure
397 #define thisboard ((const cb_pcidas_board *)dev->board_ptr)
399 /* this structure is for data unique to this hardware driver. If
400 several hardware drivers keep similar information in this structure,
401 feel free to suggest moving the variable to the struct comedi_device struct. */
403 /* would be useful for a PCI device */
404 struct pci_dev *pci_dev;
406 unsigned long s5933_config;
407 unsigned long control_status;
408 unsigned long adc_fifo;
409 unsigned long pacer_counter_dio;
410 unsigned long ao_registers;
411 // divisors of master clock for analog input pacing
412 unsigned int divisor1;
413 unsigned int divisor2;
414 volatile unsigned int count; // number of analog input samples remaining
415 volatile unsigned int adc_fifo_bits; // bits to write to interupt/adcfifo register
416 volatile unsigned int s5933_intcsr_bits; // bits to write to amcc s5933 interrupt control/status register
417 volatile unsigned int ao_control_bits; // bits to write to ao control and status register
418 short ai_buffer[AI_BUFFER_SIZE];
419 short ao_buffer[AO_BUFFER_SIZE];
420 // divisors of master clock for analog output pacing
421 unsigned int ao_divisor1;
422 unsigned int ao_divisor2;
423 volatile unsigned int ao_count; // number of analog output samples remaining
424 int ao_value[2]; // remember what the analog outputs are set to, to allow readback
425 unsigned int caldac_value[NUM_CHANNELS_8800]; // for readback of caldac
426 unsigned int trimpot_value[NUM_CHANNELS_8402]; // for readback of trimpot
427 unsigned int dac08_value;
428 unsigned int calibration_source;
432 * most drivers define the following macro to make it easy to
433 * access the private structure.
435 #define devpriv ((cb_pcidas_private *)dev->private)
438 * The struct comedi_driver structure tells the Comedi core module
439 * which functions to call to configure/deconfigure (attach/detach)
440 * the board, and also about the kernel module that contains
443 static int cb_pcidas_attach(struct comedi_device * dev, comedi_devconfig * it);
444 static int cb_pcidas_detach(struct comedi_device * dev);
445 static struct comedi_driver driver_cb_pcidas = {
446 driver_name:"cb_pcidas",
448 attach:cb_pcidas_attach,
449 detach:cb_pcidas_detach,
452 static int cb_pcidas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice * s,
453 comedi_insn * insn, unsigned int * data);
454 static int ai_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
455 comedi_insn * insn, unsigned int * data);
456 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
457 comedi_insn * insn, unsigned int * data);
458 static int cb_pcidas_ao_fifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
459 comedi_insn * insn, unsigned int * data);
460 static int cb_pcidas_ao_readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
461 comedi_insn * insn, unsigned int * data);
462 static int cb_pcidas_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
463 static int cb_pcidas_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
464 struct comedi_cmd * cmd);
465 static int cb_pcidas_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
466 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
467 struct comedi_subdevice *subdev,
468 unsigned int trig_num);
469 static int cb_pcidas_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
470 struct comedi_cmd * cmd);
471 static irqreturn_t cb_pcidas_interrupt(int irq, void *d PT_REGS_ARG);
472 static void handle_ao_interrupt(struct comedi_device * dev, unsigned int status);
473 static int cb_pcidas_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
474 static int cb_pcidas_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
475 static void cb_pcidas_load_counters(struct comedi_device * dev, unsigned int *ns,
477 static int eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
478 comedi_insn * insn, unsigned int * data);
479 static int caldac_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
480 comedi_insn * insn, unsigned int * data);
481 static int caldac_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
482 comedi_insn * insn, unsigned int * data);
483 static int trimpot_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
484 comedi_insn * insn, unsigned int * data);
485 static int cb_pcidas_trimpot_write(struct comedi_device * dev, unsigned int channel,
487 static int trimpot_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
488 comedi_insn * insn, unsigned int * data);
489 static int dac08_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
490 comedi_insn * insn, unsigned int * data);
491 static int dac08_write(struct comedi_device * dev, unsigned int value);
492 static int dac08_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
493 comedi_insn * insn, unsigned int * data);
494 static int caldac_8800_write(struct comedi_device * dev, unsigned int address,
496 static int trimpot_7376_write(struct comedi_device * dev, uint8_t value);
497 static int trimpot_8402_write(struct comedi_device * dev, unsigned int channel,
499 static int nvram_read(struct comedi_device * dev, unsigned int address,
502 static inline unsigned int cal_enable_bits(struct comedi_device * dev)
504 return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source);
508 * Attach is called by the Comedi core to configure the driver
509 * for a particular board.
511 static int cb_pcidas_attach(struct comedi_device * dev, comedi_devconfig * it)
513 struct comedi_subdevice *s;
514 struct pci_dev *pcidev;
518 printk("comedi%d: cb_pcidas: ", dev->minor);
521 * Allocate the private structure area.
523 if (alloc_private(dev, sizeof(cb_pcidas_private)) < 0)
527 * Probe the device to determine what device in the series it is.
531 for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
533 pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
534 // is it not a computer boards card?
535 if (pcidev->vendor != PCI_VENDOR_ID_CB)
537 // loop through cards supported by this driver
538 for (index = 0; index < N_BOARDS; index++) {
539 if (cb_pcidas_boards[index].device_id != pcidev->device)
541 // was a particular bus/slot requested?
542 if (it->options[0] || it->options[1]) {
543 // are we on the wrong bus/slot?
544 if (pcidev->bus->number != it->options[0] ||
545 PCI_SLOT(pcidev->devfn) !=
550 devpriv->pci_dev = pcidev;
551 dev->board_ptr = cb_pcidas_boards + index;
556 printk("No supported ComputerBoards/MeasurementComputing card found on "
557 "requested position\n");
562 printk("Found %s on bus %i, slot %i\n", cb_pcidas_boards[index].name,
563 pcidev->bus->number, PCI_SLOT(pcidev->devfn));
566 * Enable PCI device and reserve I/O ports.
568 if (comedi_pci_enable(pcidev, "cb_pcidas")) {
569 printk(" Failed to enable PCI device and request regions\n");
573 * Initialize devpriv->control_status and devpriv->adc_fifo to point to
574 * their base address.
576 devpriv->s5933_config =
577 pci_resource_start(devpriv->pci_dev, S5933_BADRINDEX);
578 devpriv->control_status =
579 pci_resource_start(devpriv->pci_dev, CONT_STAT_BADRINDEX);
581 pci_resource_start(devpriv->pci_dev, ADC_FIFO_BADRINDEX);
582 devpriv->pacer_counter_dio =
583 pci_resource_start(devpriv->pci_dev, PACER_BADRINDEX);
584 if (thisboard->ao_nchan) {
585 devpriv->ao_registers =
586 pci_resource_start(devpriv->pci_dev, AO_BADRINDEX);
588 // disable and clear interrupts on amcc s5933
589 outl(INTCSR_INBOX_INTR_STATUS,
590 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
593 if (comedi_request_irq(devpriv->pci_dev->irq, cb_pcidas_interrupt,
594 IRQF_SHARED, "cb_pcidas", dev)) {
595 printk(" unable to allocate irq %d\n", devpriv->pci_dev->irq);
598 dev->irq = devpriv->pci_dev->irq;
600 //Initialize dev->board_name
601 dev->board_name = thisboard->name;
604 * Allocate the subdevice structures.
606 if (alloc_subdevices(dev, 7) < 0)
609 s = dev->subdevices + 0;
610 /* analog input subdevice */
611 dev->read_subdev = s;
612 s->type = COMEDI_SUBD_AI;
613 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
614 /* WARNING: Number of inputs in differential mode is ignored */
615 s->n_chan = thisboard->ai_se_chans;
616 s->len_chanlist = thisboard->ai_se_chans;
617 s->maxdata = (1 << thisboard->ai_bits) - 1;
618 s->range_table = thisboard->ranges;
619 s->insn_read = cb_pcidas_ai_rinsn;
620 s->insn_config = ai_config_insn;
621 s->do_cmd = cb_pcidas_ai_cmd;
622 s->do_cmdtest = cb_pcidas_ai_cmdtest;
623 s->cancel = cb_pcidas_cancel;
625 /* analog output subdevice */
626 s = dev->subdevices + 1;
627 if (thisboard->ao_nchan) {
628 s->type = COMEDI_SUBD_AO;
629 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
630 s->n_chan = thisboard->ao_nchan;
631 // analog out resolution is the same as analog input resolution, so use ai_bits
632 s->maxdata = (1 << thisboard->ai_bits) - 1;
633 s->range_table = &cb_pcidas_ao_ranges;
634 s->insn_read = cb_pcidas_ao_readback_insn;
635 if (thisboard->has_ao_fifo) {
636 dev->write_subdev = s;
637 s->subdev_flags |= SDF_CMD_WRITE;
638 s->insn_write = cb_pcidas_ao_fifo_winsn;
639 s->do_cmdtest = cb_pcidas_ao_cmdtest;
640 s->do_cmd = cb_pcidas_ao_cmd;
641 s->cancel = cb_pcidas_ao_cancel;
643 s->insn_write = cb_pcidas_ao_nofifo_winsn;
646 s->type = COMEDI_SUBD_UNUSED;
650 s = dev->subdevices + 2;
651 subdev_8255_init(dev, s, NULL, devpriv->pacer_counter_dio + DIO_8255);
654 s = dev->subdevices + 3;
655 s->type = COMEDI_SUBD_MEMORY;
656 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
659 s->insn_read = eeprom_read_insn;
662 s = dev->subdevices + 4;
663 s->type = COMEDI_SUBD_CALIB;
664 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
665 s->n_chan = NUM_CHANNELS_8800;
667 s->insn_read = caldac_read_insn;
668 s->insn_write = caldac_write_insn;
669 for (i = 0; i < s->n_chan; i++)
670 caldac_8800_write(dev, i, s->maxdata / 2);
672 // trim potentiometer
673 s = dev->subdevices + 5;
674 s->type = COMEDI_SUBD_CALIB;
675 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
676 if (thisboard->trimpot == AD7376) {
677 s->n_chan = NUM_CHANNELS_7376;
680 s->n_chan = NUM_CHANNELS_8402;
683 s->insn_read = trimpot_read_insn;
684 s->insn_write = trimpot_write_insn;
685 for (i = 0; i < s->n_chan; i++)
686 cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
689 s = dev->subdevices + 6;
690 if (thisboard->has_dac08) {
691 s->type = COMEDI_SUBD_CALIB;
692 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
693 s->n_chan = NUM_CHANNELS_DAC08;
694 s->insn_read = dac08_read_insn;
695 s->insn_write = dac08_write_insn;
697 dac08_write(dev, s->maxdata / 2);
699 s->type = COMEDI_SUBD_UNUSED;
701 // make sure mailbox 4 is empty
702 inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
703 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
704 devpriv->s5933_intcsr_bits =
705 INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
706 INTCSR_INBOX_FULL_INT;
707 // clear and enable interrupt on amcc s5933
708 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
709 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
715 * cb_pcidas_detach is called to deconfigure a device. It should deallocate
717 * This function is also called when _attach() fails, so it should be
718 * careful not to release resources that were not necessarily
719 * allocated by _attach(). dev->private and dev->subdevices are
720 * deallocated automatically by the core.
722 static int cb_pcidas_detach(struct comedi_device * dev)
724 printk("comedi%d: cb_pcidas: remove\n", dev->minor);
727 if (devpriv->s5933_config) {
728 // disable and clear interrupts on amcc s5933
729 outl(INTCSR_INBOX_INTR_STATUS,
730 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
731 #ifdef CB_PCIDAS_DEBUG
732 rt_printk("detaching, incsr is 0x%x\n",
733 inl(devpriv->s5933_config +
734 AMCC_OP_REG_INTCSR));
739 comedi_free_irq(dev->irq, dev);
741 subdev_8255_cleanup(dev, dev->subdevices + 2);
742 if (devpriv && devpriv->pci_dev) {
743 if (devpriv->s5933_config) {
744 comedi_pci_disable(devpriv->pci_dev);
746 pci_dev_put(devpriv->pci_dev);
753 * "instructions" read/write data in "one-shot" or "software-triggered"
756 static int cb_pcidas_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
757 comedi_insn * insn, unsigned int * data)
761 static const int timeout = 10000;
763 // enable calibration input if appropriate
764 if (insn->chanspec & CR_ALT_SOURCE) {
765 outw(cal_enable_bits(dev),
766 devpriv->control_status + CALIBRATION_REG);
769 outw(0, devpriv->control_status + CALIBRATION_REG);
770 channel = CR_CHAN(insn->chanspec);
772 // set mux limits and gain
773 bits = BEGIN_SCAN(channel) |
774 END_SCAN(channel) | GAIN_BITS(CR_RANGE(insn->chanspec));
775 // set unipolar/bipolar
776 if (CR_RANGE(insn->chanspec) & IS_UNIPOLAR)
778 // set singleended/differential
779 if (CR_AREF(insn->chanspec) != AREF_DIFF)
781 outw(bits, devpriv->control_status + ADCMUX_CONT);
784 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
786 /* convert n samples */
787 for (n = 0; n < insn->n; n++) {
788 /* trigger conversion */
789 outw(0, devpriv->adc_fifo + ADCDATA);
791 /* wait for conversion to end */
792 /* return -ETIMEDOUT if there is a timeout */
793 for (i = 0; i < timeout; i++) {
794 if (inw(devpriv->control_status + ADCMUX_CONT) & EOC)
801 data[n] = inw(devpriv->adc_fifo + ADCDATA);
804 /* return the number of samples read/written */
808 static int ai_config_calibration_source(struct comedi_device * dev, unsigned int * data)
810 static const int num_calibration_sources = 8;
811 unsigned int source = data[1];
813 if (source >= num_calibration_sources) {
814 printk("invalid calibration source: %i\n", source);
818 devpriv->calibration_source = source;
823 static int ai_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
824 comedi_insn * insn, unsigned int * data)
829 case INSN_CONFIG_ALT_SOURCE:
830 return ai_config_calibration_source(dev, data);
839 // analog output insn for pcidas-1000 and 1200 series
840 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
841 comedi_insn * insn, unsigned int * data)
846 // set channel and range
847 channel = CR_CHAN(insn->chanspec);
848 comedi_spin_lock_irqsave(&dev->spinlock, flags);
849 devpriv->ao_control_bits &=
850 ~DAC_MODE_UPDATE_BOTH & ~DAC_RANGE_MASK(channel);
851 devpriv->ao_control_bits |=
852 DACEN | DAC_RANGE(channel, CR_RANGE(insn->chanspec));
853 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
854 comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
856 // remember value for readback
857 devpriv->ao_value[channel] = data[0];
859 outw(data[0], devpriv->ao_registers + DAC_DATA_REG(channel));
864 // analog output insn for pcidas-1602 series
865 static int cb_pcidas_ao_fifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
866 comedi_insn * insn, unsigned int * data)
872 outw(0, devpriv->ao_registers + DACFIFOCLR);
874 // set channel and range
875 channel = CR_CHAN(insn->chanspec);
876 comedi_spin_lock_irqsave(&dev->spinlock, flags);
877 devpriv->ao_control_bits &=
878 ~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) & ~DAC_RANGE_MASK(channel) &
880 devpriv->ao_control_bits |=
881 DACEN | DAC_RANGE(channel,
882 CR_RANGE(insn->chanspec)) | DAC_CHAN_EN(channel) | DAC_START;
883 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
884 comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
886 // remember value for readback
887 devpriv->ao_value[channel] = data[0];
889 outw(data[0], devpriv->ao_registers + DACDATA);
894 // analog output readback insn
895 // XXX loses track of analog output value back after an analog ouput command is executed
896 static int cb_pcidas_ao_readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
897 comedi_insn * insn, unsigned int * data)
899 data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
904 static int eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
905 comedi_insn * insn, unsigned int * data)
910 retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
914 data[0] = nvram_data;
919 static int caldac_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
920 comedi_insn * insn, unsigned int * data)
922 const unsigned int channel = CR_CHAN(insn->chanspec);
924 return caldac_8800_write(dev, channel, data[0]);
927 static int caldac_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
928 comedi_insn * insn, unsigned int * data)
930 data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)];
935 /* 1602/16 pregain offset */
936 static int dac08_write(struct comedi_device * dev, unsigned int value)
938 if (devpriv->dac08_value == value)
941 devpriv->dac08_value = value;
943 outw(cal_enable_bits(dev) | (value & 0xff),
944 devpriv->control_status + CALIBRATION_REG);
946 outw(cal_enable_bits(dev) | SELECT_DAC08_BIT | (value & 0xff),
947 devpriv->control_status + CALIBRATION_REG);
949 outw(cal_enable_bits(dev) | (value & 0xff),
950 devpriv->control_status + CALIBRATION_REG);
956 static int dac08_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
957 comedi_insn * insn, unsigned int * data)
959 return dac08_write(dev, data[0]);
962 static int dac08_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
963 comedi_insn * insn, unsigned int * data)
965 data[0] = devpriv->dac08_value;
970 static int cb_pcidas_trimpot_write(struct comedi_device * dev,
971 unsigned int channel, unsigned int value)
973 if (devpriv->trimpot_value[channel] == value)
976 devpriv->trimpot_value[channel] = value;
977 switch (thisboard->trimpot) {
979 trimpot_7376_write(dev, value);
982 trimpot_8402_write(dev, channel, value);
985 comedi_error(dev, "driver bug?");
993 static int trimpot_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
994 comedi_insn * insn, unsigned int * data)
996 unsigned int channel = CR_CHAN(insn->chanspec);
998 return cb_pcidas_trimpot_write(dev, channel, data[0]);
1001 static int trimpot_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
1002 comedi_insn * insn, unsigned int * data)
1004 unsigned int channel = CR_CHAN(insn->chanspec);
1006 data[0] = devpriv->trimpot_value[channel];
1011 static int cb_pcidas_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
1012 struct comedi_cmd * cmd)
1016 int i, gain, start_chan;
1018 /* cmdtest tests a particular command to see if it is valid.
1019 * Using the cmdtest ioctl, a user can create a valid cmd
1020 * and then have it executes by the cmd ioctl.
1022 * cmdtest returns 1,2,3,4 or 0, depending on which tests
1023 * the command passes. */
1025 /* step 1: make sure trigger sources are trivially valid */
1027 tmp = cmd->start_src;
1028 cmd->start_src &= TRIG_NOW | TRIG_EXT;
1029 if (!cmd->start_src || tmp != cmd->start_src)
1032 tmp = cmd->scan_begin_src;
1033 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
1034 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1037 tmp = cmd->convert_src;
1038 cmd->convert_src &= TRIG_TIMER | TRIG_NOW | TRIG_EXT;
1039 if (!cmd->convert_src || tmp != cmd->convert_src)
1042 tmp = cmd->scan_end_src;
1043 cmd->scan_end_src &= TRIG_COUNT;
1044 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1047 tmp = cmd->stop_src;
1048 cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1049 if (!cmd->stop_src || tmp != cmd->stop_src)
1055 /* step 2: make sure trigger sources are unique and mutually compatible */
1057 if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
1059 if (cmd->scan_begin_src != TRIG_FOLLOW &&
1060 cmd->scan_begin_src != TRIG_TIMER &&
1061 cmd->scan_begin_src != TRIG_EXT)
1063 if (cmd->convert_src != TRIG_TIMER &&
1064 cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
1066 if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
1069 // make sure trigger sources are compatible with each other
1070 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
1072 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
1074 if (cmd->start_src == TRIG_EXT &&
1075 (cmd->convert_src == TRIG_EXT
1076 || cmd->scan_begin_src == TRIG_EXT))
1082 /* step 3: make sure arguments are trivially compatible */
1084 if (cmd->start_arg != 0) {
1089 if (cmd->scan_begin_src == TRIG_TIMER) {
1090 if (cmd->scan_begin_arg <
1091 thisboard->ai_speed * cmd->chanlist_len) {
1092 cmd->scan_begin_arg =
1093 thisboard->ai_speed * cmd->chanlist_len;
1097 if (cmd->convert_src == TRIG_TIMER) {
1098 if (cmd->convert_arg < thisboard->ai_speed) {
1099 cmd->convert_arg = thisboard->ai_speed;
1104 if (cmd->scan_end_arg != cmd->chanlist_len) {
1105 cmd->scan_end_arg = cmd->chanlist_len;
1108 if (cmd->stop_src == TRIG_NONE) {
1110 if (cmd->stop_arg != 0) {
1119 /* step 4: fix up any arguments */
1121 if (cmd->scan_begin_src == TRIG_TIMER) {
1122 tmp = cmd->scan_begin_arg;
1123 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1124 &(devpriv->divisor1), &(devpriv->divisor2),
1125 &(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK);
1126 if (tmp != cmd->scan_begin_arg)
1129 if (cmd->convert_src == TRIG_TIMER) {
1130 tmp = cmd->convert_arg;
1131 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1132 &(devpriv->divisor1), &(devpriv->divisor2),
1133 &(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
1134 if (tmp != cmd->convert_arg)
1141 // check channel/gain list against card's limitations
1142 if (cmd->chanlist) {
1143 gain = CR_RANGE(cmd->chanlist[0]);
1144 start_chan = CR_CHAN(cmd->chanlist[0]);
1145 for (i = 1; i < cmd->chanlist_len; i++) {
1146 if (CR_CHAN(cmd->chanlist[i]) !=
1147 (start_chan + i) % s->n_chan) {
1149 "entries in chanlist must be consecutive channels, counting upwards\n");
1152 if (CR_RANGE(cmd->chanlist[i]) != gain) {
1154 "entries in chanlist must all have the same gain\n");
1166 static int cb_pcidas_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
1168 struct comedi_async *async = s->async;
1169 struct comedi_cmd *cmd = &async->cmd;
1171 unsigned long flags;
1173 // make sure CAL_EN_BIT is disabled
1174 outw(0, devpriv->control_status + CALIBRATION_REG);
1175 // initialize before settings pacer source and count values
1176 outw(0, devpriv->control_status + TRIG_CONTSTAT);
1178 outw(0, devpriv->adc_fifo + ADCFIFOCLR);
1180 // set mux limits, gain and pacer source
1181 bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
1182 END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
1183 GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
1184 // set unipolar/bipolar
1185 if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
1187 // set singleended/differential
1188 if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
1191 if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
1192 bits |= PACER_EXT_RISE;
1195 outw(bits, devpriv->control_status + ADCMUX_CONT);
1197 #ifdef CB_PCIDAS_DEBUG
1198 rt_printk("comedi: sent 0x%x to adcmux control\n", bits);
1202 if (cmd->convert_src == TRIG_TIMER)
1203 cb_pcidas_load_counters(dev, &cmd->convert_arg,
1204 cmd->flags & TRIG_ROUND_MASK);
1205 else if (cmd->scan_begin_src == TRIG_TIMER)
1206 cb_pcidas_load_counters(dev, &cmd->scan_begin_arg,
1207 cmd->flags & TRIG_ROUND_MASK);
1209 // set number of conversions
1210 if (cmd->stop_src == TRIG_COUNT) {
1211 devpriv->count = cmd->chanlist_len * cmd->stop_arg;
1213 // enable interrupts
1214 comedi_spin_lock_irqsave(&dev->spinlock, flags);
1215 devpriv->adc_fifo_bits |= INTE;
1216 devpriv->adc_fifo_bits &= ~INT_MASK;
1217 if (cmd->flags & TRIG_WAKE_EOS) {
1218 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1219 devpriv->adc_fifo_bits |= INT_EOS; // interrupt end of burst
1221 devpriv->adc_fifo_bits |= INT_FNE; // interrupt fifo not empty
1223 devpriv->adc_fifo_bits |= INT_FHF; //interrupt fifo half full
1225 #ifdef CB_PCIDAS_DEBUG
1226 rt_printk("comedi: adc_fifo_bits are 0x%x\n", devpriv->adc_fifo_bits);
1228 // enable (and clear) interrupts
1229 outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
1230 devpriv->control_status + INT_ADCFIFO);
1231 comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1233 // set start trigger and burst mode
1235 if (cmd->start_src == TRIG_NOW)
1237 else if (cmd->start_src == TRIG_EXT)
1238 bits |= EXT_TRIGGER | TGEN | XTRCL;
1240 comedi_error(dev, "bug!");
1243 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1245 outw(bits, devpriv->control_status + TRIG_CONTSTAT);
1246 #ifdef CB_PCIDAS_DEBUG
1247 rt_printk("comedi: sent 0x%x to trig control\n", bits);
1253 static int cb_pcidas_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
1254 struct comedi_cmd * cmd)
1259 /* cmdtest tests a particular command to see if it is valid.
1260 * Using the cmdtest ioctl, a user can create a valid cmd
1261 * and then have it executes by the cmd ioctl.
1263 * cmdtest returns 1,2,3,4 or 0, depending on which tests
1264 * the command passes. */
1266 /* step 1: make sure trigger sources are trivially valid */
1268 tmp = cmd->start_src;
1269 cmd->start_src &= TRIG_INT;
1270 if (!cmd->start_src || tmp != cmd->start_src)
1273 tmp = cmd->scan_begin_src;
1274 cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
1275 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1278 tmp = cmd->convert_src;
1279 cmd->convert_src &= TRIG_NOW;
1280 if (!cmd->convert_src || tmp != cmd->convert_src)
1283 tmp = cmd->scan_end_src;
1284 cmd->scan_end_src &= TRIG_COUNT;
1285 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1288 tmp = cmd->stop_src;
1289 cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
1290 if (!cmd->stop_src || tmp != cmd->stop_src)
1296 /* step 2: make sure trigger sources are unique and mutually compatible */
1298 if (cmd->scan_begin_src != TRIG_TIMER &&
1299 cmd->scan_begin_src != TRIG_EXT)
1301 if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
1307 /* step 3: make sure arguments are trivially compatible */
1309 if (cmd->start_arg != 0) {
1314 if (cmd->scan_begin_src == TRIG_TIMER) {
1315 if (cmd->scan_begin_arg < thisboard->ao_scan_speed) {
1316 cmd->scan_begin_arg = thisboard->ao_scan_speed;
1321 if (cmd->scan_end_arg != cmd->chanlist_len) {
1322 cmd->scan_end_arg = cmd->chanlist_len;
1325 if (cmd->stop_src == TRIG_NONE) {
1327 if (cmd->stop_arg != 0) {
1336 /* step 4: fix up any arguments */
1338 if (cmd->scan_begin_src == TRIG_TIMER) {
1339 tmp = cmd->scan_begin_arg;
1340 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1341 &(devpriv->ao_divisor1), &(devpriv->ao_divisor2),
1342 &(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK);
1343 if (tmp != cmd->scan_begin_arg)
1350 // check channel/gain list against card's limitations
1351 if (cmd->chanlist && cmd->chanlist_len > 1) {
1352 if (CR_CHAN(cmd->chanlist[0]) != 0 ||
1353 CR_CHAN(cmd->chanlist[1]) != 1) {
1355 "channels must be ordered channel 0, channel 1 in chanlist\n");
1366 static int cb_pcidas_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
1368 struct comedi_async *async = s->async;
1369 struct comedi_cmd *cmd = &async->cmd;
1371 unsigned long flags;
1373 // set channel limits, gain
1374 comedi_spin_lock_irqsave(&dev->spinlock, flags);
1375 for (i = 0; i < cmd->chanlist_len; i++) {
1377 devpriv->ao_control_bits |=
1378 DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
1380 devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
1381 CR_RANGE(cmd->chanlist[i]));
1384 // disable analog out before settings pacer source and count values
1385 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1386 comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1389 outw(0, devpriv->ao_registers + DACFIFOCLR);
1392 if (cmd->scan_begin_src == TRIG_TIMER) {
1393 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1394 &(devpriv->ao_divisor1), &(devpriv->ao_divisor2),
1395 &(cmd->scan_begin_arg), cmd->flags);
1397 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1398 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1,
1399 devpriv->ao_divisor1, 2);
1400 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2,
1401 devpriv->ao_divisor2, 2);
1403 // set number of conversions
1404 if (cmd->stop_src == TRIG_COUNT) {
1405 devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
1408 comedi_spin_lock_irqsave(&dev->spinlock, flags);
1409 switch (cmd->scan_begin_src) {
1411 devpriv->ao_control_bits |= DAC_PACER_INT;
1414 devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1417 comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1418 comedi_error(dev, "error setting dac pacer source");
1422 comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1424 async->inttrig = cb_pcidas_ao_inttrig;
1429 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1430 struct comedi_subdevice *s,
1431 unsigned int trig_num)
1433 unsigned int num_bytes, num_points = thisboard->fifo_size;
1434 struct comedi_async *async = s->async;
1435 struct comedi_cmd *cmd = &s->async->cmd;
1436 unsigned long flags;
1442 if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
1443 num_points = devpriv->ao_count;
1445 num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1446 num_points * sizeof(short));
1447 num_points = num_bytes / sizeof(short);
1449 if (cmd->stop_src == TRIG_COUNT) {
1450 devpriv->ao_count -= num_points;
1452 // write data to board's fifo
1453 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
1455 // enable dac half-full and empty interrupts
1456 comedi_spin_lock_irqsave(&dev->spinlock, flags);
1457 devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
1458 #ifdef CB_PCIDAS_DEBUG
1459 rt_printk("comedi: adc_fifo_bits are 0x%x\n", devpriv->adc_fifo_bits);
1461 // enable and clear interrupts
1462 outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
1463 devpriv->control_status + INT_ADCFIFO);
1466 devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1467 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1468 #ifdef CB_PCIDAS_DEBUG
1469 rt_printk("comedi: sent 0x%x to dac control\n",
1470 devpriv->ao_control_bits);
1472 comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1474 async->inttrig = NULL;
1479 static irqreturn_t cb_pcidas_interrupt(int irq, void *d PT_REGS_ARG)
1481 struct comedi_device *dev = (struct comedi_device *) d;
1482 struct comedi_subdevice *s = dev->read_subdev;
1483 struct comedi_async *async;
1484 int status, s5933_status;
1485 int half_fifo = thisboard->fifo_size / 2;
1486 unsigned int num_samples, i;
1487 static const int timeout = 10000;
1488 unsigned long flags;
1490 if (dev->attached == 0) {
1497 s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1498 #ifdef CB_PCIDAS_DEBUG
1499 rt_printk("intcsr 0x%x\n", s5933_status);
1500 rt_printk("mbef 0x%x\n", inl(devpriv->s5933_config + AMCC_OP_REG_MBEF));
1503 if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
1506 // make sure mailbox 4 is empty
1507 inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1508 // clear interrupt on amcc s5933
1509 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1510 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1512 status = inw(devpriv->control_status + INT_ADCFIFO);
1513 #ifdef CB_PCIDAS_DEBUG
1514 if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0) {
1515 comedi_error(dev, "spurious interrupt");
1519 // check for analog output interrupt
1520 if (status & (DAHFI | DAEMI)) {
1521 handle_ao_interrupt(dev, status);
1523 // check for analog input interrupts
1524 // if fifo half-full
1525 if (status & ADHFI) {
1527 num_samples = half_fifo;
1528 if (async->cmd.stop_src == TRIG_COUNT &&
1529 num_samples > devpriv->count) {
1530 num_samples = devpriv->count;
1532 insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
1534 cfc_write_array_to_buffer(s, devpriv->ai_buffer,
1535 num_samples * sizeof(short));
1536 devpriv->count -= num_samples;
1537 if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) {
1538 async->events |= COMEDI_CB_EOA;
1539 cb_pcidas_cancel(dev, s);
1541 // clear half-full interrupt latch
1542 comedi_spin_lock_irqsave(&dev->spinlock, flags);
1543 outw(devpriv->adc_fifo_bits | INT,
1544 devpriv->control_status + INT_ADCFIFO);
1545 comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1546 // else if fifo not empty
1547 } else if (status & (ADNEI | EOBI)) {
1548 for (i = 0; i < timeout; i++) {
1549 // break if fifo is empty
1550 if ((ADNE & inw(devpriv->control_status +
1553 cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
1554 if (async->cmd.stop_src == TRIG_COUNT && --devpriv->count == 0) { /* end of acquisition */
1555 cb_pcidas_cancel(dev, s);
1556 async->events |= COMEDI_CB_EOA;
1560 // clear not-empty interrupt latch
1561 comedi_spin_lock_irqsave(&dev->spinlock, flags);
1562 outw(devpriv->adc_fifo_bits | INT,
1563 devpriv->control_status + INT_ADCFIFO);
1564 comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1565 } else if (status & EOAI) {
1567 "bug! encountered end of aquisition interrupt?");
1568 // clear EOA interrupt latch
1569 comedi_spin_lock_irqsave(&dev->spinlock, flags);
1570 outw(devpriv->adc_fifo_bits | EOAI,
1571 devpriv->control_status + INT_ADCFIFO);
1572 comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1574 //check for fifo overflow
1575 if (status & LADFUL) {
1576 comedi_error(dev, "fifo overflow");
1577 // clear overflow interrupt latch
1578 comedi_spin_lock_irqsave(&dev->spinlock, flags);
1579 outw(devpriv->adc_fifo_bits | LADFUL,
1580 devpriv->control_status + INT_ADCFIFO);
1581 comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1582 cb_pcidas_cancel(dev, s);
1583 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1586 comedi_event(dev, s);
1591 static void handle_ao_interrupt(struct comedi_device * dev, unsigned int status)
1593 struct comedi_subdevice *s = dev->write_subdev;
1594 struct comedi_async *async = s->async;
1595 struct comedi_cmd *cmd = &async->cmd;
1596 unsigned int half_fifo = thisboard->fifo_size / 2;
1597 unsigned int num_points;
1602 if (status & DAEMI) {
1603 // clear dac empty interrupt latch
1604 comedi_spin_lock_irqsave(&dev->spinlock, flags);
1605 outw(devpriv->adc_fifo_bits | DAEMI,
1606 devpriv->control_status + INT_ADCFIFO);
1607 comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1608 if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
1609 if (cmd->stop_src == TRIG_NONE ||
1610 (cmd->stop_src == TRIG_COUNT
1611 && devpriv->ao_count)) {
1612 comedi_error(dev, "dac fifo underflow");
1613 cb_pcidas_ao_cancel(dev, s);
1614 async->events |= COMEDI_CB_ERROR;
1616 async->events |= COMEDI_CB_EOA;
1618 } else if (status & DAHFI) {
1619 unsigned int num_bytes;
1621 // figure out how many points we are writing to fifo
1622 num_points = half_fifo;
1623 if (cmd->stop_src == TRIG_COUNT &&
1624 devpriv->ao_count < num_points)
1625 num_points = devpriv->ao_count;
1627 cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1628 num_points * sizeof(short));
1629 num_points = num_bytes / sizeof(short);
1631 if (async->cmd.stop_src == TRIG_COUNT) {
1632 devpriv->ao_count -= num_points;
1634 // write data to board's fifo
1635 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
1637 // clear half-full interrupt latch
1638 comedi_spin_lock_irqsave(&dev->spinlock, flags);
1639 outw(devpriv->adc_fifo_bits | DAHFI,
1640 devpriv->control_status + INT_ADCFIFO);
1641 comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1644 comedi_event(dev, s);
1647 /* cancel analog input command */
1648 static int cb_pcidas_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
1650 unsigned long flags;
1652 comedi_spin_lock_irqsave(&dev->spinlock, flags);
1653 // disable interrupts
1654 devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
1655 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1656 comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1658 // disable start trigger source and burst mode
1659 outw(0, devpriv->control_status + TRIG_CONTSTAT);
1660 // software pacer source
1661 outw(0, devpriv->control_status + ADCMUX_CONT);
1666 /* cancel analog output command */
1667 static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1668 struct comedi_subdevice *s)
1670 unsigned long flags;
1672 comedi_spin_lock_irqsave(&dev->spinlock, flags);
1673 // disable interrupts
1674 devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
1675 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1678 devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1679 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1680 comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
1685 static void cb_pcidas_load_counters(struct comedi_device * dev, unsigned int *ns,
1688 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
1689 &(devpriv->divisor2), ns, rounding_flags & TRIG_ROUND_MASK);
1691 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1692 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1,
1693 devpriv->divisor1, 2);
1694 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2,
1695 devpriv->divisor2, 2);
1698 static void write_calibration_bitstream(struct comedi_device * dev,
1699 unsigned int register_bits, unsigned int bitstream,
1700 unsigned int bitstream_length)
1702 static const int write_delay = 1;
1705 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
1706 if (bitstream & bit)
1707 register_bits |= SERIAL_DATA_IN_BIT;
1709 register_bits &= ~SERIAL_DATA_IN_BIT;
1710 comedi_udelay(write_delay);
1711 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
1715 static int caldac_8800_write(struct comedi_device * dev, unsigned int address,
1718 static const int num_caldac_channels = 8;
1719 static const int bitstream_length = 11;
1720 unsigned int bitstream = ((address & 0x7) << 8) | value;
1721 static const int caldac_8800_comedi_udelay = 1;
1723 if (address >= num_caldac_channels) {
1724 comedi_error(dev, "illegal caldac channel");
1728 if (value == devpriv->caldac_value[address])
1731 devpriv->caldac_value[address] = value;
1733 write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
1736 comedi_udelay(caldac_8800_comedi_udelay);
1737 outw(cal_enable_bits(dev) | SELECT_8800_BIT,
1738 devpriv->control_status + CALIBRATION_REG);
1739 comedi_udelay(caldac_8800_comedi_udelay);
1740 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
1745 static int trimpot_7376_write(struct comedi_device * dev, uint8_t value)
1747 static const int bitstream_length = 7;
1748 unsigned int bitstream = value & 0x7f;
1749 unsigned int register_bits;
1750 static const int ad7376_comedi_udelay = 1;
1752 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
1753 comedi_udelay(ad7376_comedi_udelay);
1754 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
1756 write_calibration_bitstream(dev, register_bits, bitstream,
1759 comedi_udelay(ad7376_comedi_udelay);
1760 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
1767 * ch 1 : adc postgain offset */
1768 static int trimpot_8402_write(struct comedi_device * dev, unsigned int channel,
1771 static const int bitstream_length = 10;
1772 unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
1773 unsigned int register_bits;
1774 static const int ad8402_comedi_udelay = 1;
1776 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
1777 comedi_udelay(ad8402_comedi_udelay);
1778 outw(register_bits, devpriv->control_status + CALIBRATION_REG);
1780 write_calibration_bitstream(dev, register_bits, bitstream,
1783 comedi_udelay(ad8402_comedi_udelay);
1784 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
1789 static int wait_for_nvram_ready(unsigned long s5933_base_addr)
1791 static const int timeout = 1000;
1794 for (i = 0; i < timeout; i++) {
1795 if ((inb(s5933_base_addr +
1796 AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
1804 static int nvram_read(struct comedi_device * dev, unsigned int address, uint8_t * data)
1806 unsigned long iobase = devpriv->s5933_config;
1808 if (wait_for_nvram_ready(iobase) < 0)
1811 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
1812 iobase + AMCC_OP_REG_MCSR_NVCMD);
1813 outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
1814 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
1815 iobase + AMCC_OP_REG_MCSR_NVCMD);
1816 outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
1817 outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
1819 if (wait_for_nvram_ready(iobase) < 0)
1822 *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
1828 * A convenient macro that defines init_module() and cleanup_module(),
1831 COMEDI_PCI_INITCLEANUP(driver_cb_pcidas, cb_pcidas_pci_table);