2 * Comedi driver for Keithley DAS-1700/DAS-1800 series boards
3 * Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
5 * COMEDI - Linux Control and Measurement Device Interface
6 * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
21 * Description: Keithley Metrabyte DAS1800 (& compatibles)
22 * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
23 * Devices: [Keithley Metrabyte] DAS-1701ST (das-1701st),
24 * DAS-1701ST-DA (das-1701st-da), DAS-1701/AO (das-1701ao),
25 * DAS-1702ST (das-1702st), DAS-1702ST-DA (das-1702st-da),
26 * DAS-1702HR (das-1702hr), DAS-1702HR-DA (das-1702hr-da),
27 * DAS-1702/AO (das-1702ao), DAS-1801ST (das-1801st),
28 * DAS-1801ST-DA (das-1801st-da), DAS-1801HC (das-1801hc),
29 * DAS-1801AO (das-1801ao), DAS-1802ST (das-1802st),
30 * DAS-1802ST-DA (das-1802st-da), DAS-1802HR (das-1802hr),
31 * DAS-1802HR-DA (das-1802hr-da), DAS-1802HC (das-1802hc),
32 * DAS-1802AO (das-1802ao)
35 * Configuration options:
36 * [0] - I/O port base address
37 * [1] - IRQ (optional, required for analog input cmd support)
38 * [2] - DMA0 (optional, requires irq)
39 * [3] - DMA1 (optional, requires irq and dma0)
41 * analog input cmd triggers supported:
43 * start_src TRIG_NOW command starts immediately
44 * TRIG_EXT command starts on external pin TGIN
46 * scan_begin_src TRIG_FOLLOW paced/external scans start immediately
47 * TRIG_TIMER burst scans start periodically
48 * TRIG_EXT burst scans start on external pin XPCLK
50 * scan_end_src TRIG_COUNT scan ends after last channel
52 * convert_src TRIG_TIMER paced/burst conversions are timed
53 * TRIG_EXT conversions on external pin XPCLK
54 * (requires scan_begin_src == TRIG_FOLLOW)
56 * stop_src TRIG_COUNT command stops after stop_arg scans
57 * TRIG_EXT command stops on external pin TGIN
58 * TRIG_NONE command runs until canceled
60 * If TRIG_EXT is used for both the start_src and stop_src, the first TGIN
61 * trigger starts the command, and the second trigger will stop it. If only
62 * one is TRIG_EXT, the first trigger will either stop or start the command.
63 * The external pin TGIN is normally set for negative edge triggering. It
64 * can be set to positive edge with the CR_INVERT flag. If TRIG_EXT is used
65 * for both the start_src and stop_src they must have the same polarity.
67 * Minimum conversion speed is limited to 64 microseconds (convert_arg <= 64000)
68 * for 'burst' scans. This limitation does not apply for 'paced' scans. The
69 * maximum conversion speed is limited by the board (convert_arg >= ai_speed).
70 * Maximum conversion speeds are not always achievable depending on the
71 * board setup (see user manual).
74 * Only the DAS-1801ST has been tested by me.
75 * Unipolar and bipolar ranges cannot be mixed in the channel/gain list.
77 * The waveform analog output on the 'ao' cards is not supported.
78 * If you need it, send me (Frank Hess) an email.
81 #include <linux/module.h>
82 #include <linux/interrupt.h>
83 #include <linux/slab.h>
86 #include "../comedidev.h"
88 #include "comedi_isadma.h"
89 #include "comedi_8254.h"
92 #define DAS1800_SIZE 16 /* uses 16 io addresses */
93 #define FIFO_SIZE 1024 /* 1024 sample fifo */
94 #define DMA_BUF_SIZE 0x1ff00 /* size in bytes of dma buffers */
96 /* Registers for the das1800 */
97 #define DAS1800_FIFO 0x0
98 #define DAS1800_QRAM 0x0
99 #define DAS1800_DAC 0x0
100 #define DAS1800_SELECT 0x2
103 #define DAC(a) (0x2 + a)
104 #define DAS1800_DIGITAL 0x3
105 #define DAS1800_CONTROL_A 0x4
113 #define DAS1800_CONTROL_B 0x5
117 #define DMA_CH5_CH6 0x5
118 #define DMA_CH6_CH7 0x6
119 #define DMA_CH7_CH5 0x7
120 #define DMA_ENABLED 0x3
129 #define DAS1800_CONTROL_C 0X6
137 #define DAS1800_STATUS 0x7
145 #define CVEN_MASK 0x40
146 #define CLEAR_INTR_MASK (CVEN_MASK | 0x1f)
147 #define DAS1800_BURST_LENGTH 0x8
148 #define DAS1800_BURST_RATE 0x9
149 #define DAS1800_QRAM_ADDRESS 0xa
150 #define DAS1800_COUNTER 0xc
152 #define IOBASE2 0x400
154 static const struct comedi_lrange das1801_ai_range = {
156 BIP_RANGE(5), /* bipolar gain = 1 */
157 BIP_RANGE(1), /* bipolar gain = 10 */
158 BIP_RANGE(0.1), /* bipolar gain = 50 */
159 BIP_RANGE(0.02), /* bipolar gain = 250 */
160 UNI_RANGE(5), /* unipolar gain = 1 */
161 UNI_RANGE(1), /* unipolar gain = 10 */
162 UNI_RANGE(0.1), /* unipolar gain = 50 */
163 UNI_RANGE(0.02) /* unipolar gain = 250 */
167 static const struct comedi_lrange das1802_ai_range = {
169 BIP_RANGE(10), /* bipolar gain = 1 */
170 BIP_RANGE(5), /* bipolar gain = 2 */
171 BIP_RANGE(2.5), /* bipolar gain = 4 */
172 BIP_RANGE(1.25), /* bipolar gain = 8 */
173 UNI_RANGE(10), /* unipolar gain = 1 */
174 UNI_RANGE(5), /* unipolar gain = 2 */
175 UNI_RANGE(2.5), /* unipolar gain = 4 */
176 UNI_RANGE(1.25) /* unipolar gain = 8 */
181 * The waveform analog outputs on the 'ao' boards are not currently
182 * supported. They have a comedi_lrange of:
183 * { 2, { BIP_RANGE(10), BIP_RANGE(5) } }
186 enum das1800_boardid {
207 /* board probe id values (hi byte of the digital input register) */
208 #define DAS1800_ID_ST_DA 0x3
209 #define DAS1800_ID_HR_DA 0x4
210 #define DAS1800_ID_AO 0x5
211 #define DAS1800_ID_HR 0x6
212 #define DAS1800_ID_ST 0x7
213 #define DAS1800_ID_HC 0x8
215 struct das1800_board {
218 unsigned int ai_speed;
219 unsigned int is_01_series:1;
222 static const struct das1800_board das1800_boards[] = {
223 [BOARD_DAS1701ST] = {
224 .name = "das-1701st",
229 [BOARD_DAS1701ST_DA] = {
230 .name = "das-1701st-da",
231 .id = DAS1800_ID_ST_DA,
235 [BOARD_DAS1702ST] = {
236 .name = "das-1702st",
240 [BOARD_DAS1702ST_DA] = {
241 .name = "das-1702st-da",
242 .id = DAS1800_ID_ST_DA,
245 [BOARD_DAS1702HR] = {
246 .name = "das-1702hr",
250 [BOARD_DAS1702HR_DA] = {
251 .name = "das-1702hr-da",
252 .id = DAS1800_ID_HR_DA,
255 [BOARD_DAS1701AO] = {
256 .name = "das-1701ao",
261 [BOARD_DAS1702AO] = {
262 .name = "das-1702ao",
266 [BOARD_DAS1801ST] = {
267 .name = "das-1801st",
272 [BOARD_DAS1801ST_DA] = {
273 .name = "das-1801st-da",
274 .id = DAS1800_ID_ST_DA,
278 [BOARD_DAS1802ST] = {
279 .name = "das-1802st",
283 [BOARD_DAS1802ST_DA] = {
284 .name = "das-1802st-da",
285 .id = DAS1800_ID_ST_DA,
288 [BOARD_DAS1802HR] = {
289 .name = "das-1802hr",
293 [BOARD_DAS1802HR_DA] = {
294 .name = "das-1802hr-da",
295 .id = DAS1800_ID_HR_DA,
298 [BOARD_DAS1801HC] = {
299 .name = "das-1801hc",
304 [BOARD_DAS1802HC] = {
305 .name = "das-1802hc",
309 [BOARD_DAS1801AO] = {
310 .name = "das-1801ao",
315 [BOARD_DAS1802AO] = {
316 .name = "das-1802ao",
322 struct das1800_private {
323 struct comedi_isadma *dma;
326 unsigned short *fifo_buf;
327 unsigned long iobase2;
331 static void das1800_ai_munge(struct comedi_device *dev,
332 struct comedi_subdevice *s,
333 void *data, unsigned int num_bytes,
334 unsigned int start_chan_index)
336 struct das1800_private *devpriv = dev->private;
337 unsigned short *array = data;
338 unsigned int num_samples = comedi_bytes_to_samples(s, num_bytes);
341 if (devpriv->ai_is_unipolar)
344 for (i = 0; i < num_samples; i++)
345 array[i] = comedi_offset_munge(s, array[i]);
348 static void das1800_handle_fifo_half_full(struct comedi_device *dev,
349 struct comedi_subdevice *s)
351 struct das1800_private *devpriv = dev->private;
352 unsigned int nsamples = comedi_nsamples_left(s, FIFO_SIZE / 2);
354 insw(dev->iobase + DAS1800_FIFO, devpriv->fifo_buf, nsamples);
355 comedi_buf_write_samples(s, devpriv->fifo_buf, nsamples);
358 static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
359 struct comedi_subdevice *s)
361 struct comedi_cmd *cmd = &s->async->cmd;
364 while (inb(dev->iobase + DAS1800_STATUS) & FNE) {
365 dpnt = inw(dev->iobase + DAS1800_FIFO);
366 comedi_buf_write_samples(s, &dpnt, 1);
368 if (cmd->stop_src == TRIG_COUNT &&
369 s->async->scans_done >= cmd->stop_arg)
374 static void das1800_flush_dma_channel(struct comedi_device *dev,
375 struct comedi_subdevice *s,
376 struct comedi_isadma_desc *desc)
378 unsigned int residue = comedi_isadma_disable(desc->chan);
379 unsigned int nbytes = desc->size - residue;
380 unsigned int nsamples;
382 /* figure out how many points to read */
383 nsamples = comedi_bytes_to_samples(s, nbytes);
384 nsamples = comedi_nsamples_left(s, nsamples);
386 comedi_buf_write_samples(s, desc->virt_addr, nsamples);
389 static void das1800_flush_dma(struct comedi_device *dev,
390 struct comedi_subdevice *s)
392 struct das1800_private *devpriv = dev->private;
393 struct comedi_isadma *dma = devpriv->dma;
394 struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
395 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
397 das1800_flush_dma_channel(dev, s, desc);
400 /* switch to other channel and flush it */
401 dma->cur_dma = 1 - dma->cur_dma;
402 desc = &dma->desc[dma->cur_dma];
403 das1800_flush_dma_channel(dev, s, desc);
406 /* get any remaining samples in fifo */
407 das1800_handle_fifo_not_empty(dev, s);
410 static void das1800_handle_dma(struct comedi_device *dev,
411 struct comedi_subdevice *s, unsigned int status)
413 struct das1800_private *devpriv = dev->private;
414 struct comedi_isadma *dma = devpriv->dma;
415 struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
416 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
418 das1800_flush_dma_channel(dev, s, desc);
420 /* re-enable dma channel */
421 comedi_isadma_program(desc);
423 if (status & DMATC) {
424 /* clear DMATC interrupt bit */
425 outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
426 /* switch dma channels for next time, if appropriate */
428 dma->cur_dma = 1 - dma->cur_dma;
432 static int das1800_ai_cancel(struct comedi_device *dev,
433 struct comedi_subdevice *s)
435 struct das1800_private *devpriv = dev->private;
436 struct comedi_isadma *dma = devpriv->dma;
437 struct comedi_isadma_desc *desc;
440 /* disable and stop conversions */
441 outb(0x0, dev->iobase + DAS1800_STATUS);
442 outb(0x0, dev->iobase + DAS1800_CONTROL_B);
443 outb(0x0, dev->iobase + DAS1800_CONTROL_A);
446 for (i = 0; i < 2; i++) {
447 desc = &dma->desc[i];
449 comedi_isadma_disable(desc->chan);
456 static void das1800_ai_handler(struct comedi_device *dev)
458 struct das1800_private *devpriv = dev->private;
459 struct comedi_subdevice *s = dev->read_subdev;
460 struct comedi_async *async = s->async;
461 struct comedi_cmd *cmd = &async->cmd;
462 unsigned int status = inb(dev->iobase + DAS1800_STATUS);
464 /* select adc register (spinlock is already held) */
465 outb(ADC, dev->iobase + DAS1800_SELECT);
467 /* get samples with dma, fifo, or polled as necessary */
468 if (devpriv->irq_dma_bits & DMA_ENABLED)
469 das1800_handle_dma(dev, s, status);
470 else if (status & FHF)
471 das1800_handle_fifo_half_full(dev, s);
472 else if (status & FNE)
473 das1800_handle_fifo_not_empty(dev, s);
475 /* if the card's fifo has overflowed */
477 /* clear OVF interrupt bit */
478 outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
479 dev_err(dev->class_dev, "FIFO overflow\n");
480 async->events |= COMEDI_CB_ERROR;
481 comedi_handle_events(dev, s);
484 /* stop taking data if appropriate */
485 /* stop_src TRIG_EXT */
486 if (status & CT0TC) {
487 /* clear CT0TC interrupt bit */
488 outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
489 /* get all remaining samples before quitting */
490 if (devpriv->irq_dma_bits & DMA_ENABLED)
491 das1800_flush_dma(dev, s);
493 das1800_handle_fifo_not_empty(dev, s);
494 async->events |= COMEDI_CB_EOA;
495 } else if (cmd->stop_src == TRIG_COUNT &&
496 async->scans_done >= cmd->stop_arg) {
497 async->events |= COMEDI_CB_EOA;
500 comedi_handle_events(dev, s);
503 static int das1800_ai_poll(struct comedi_device *dev,
504 struct comedi_subdevice *s)
509 * Protects the indirect addressing selected by DAS1800_SELECT
510 * in das1800_ai_handler() also prevents race with das1800_interrupt().
512 spin_lock_irqsave(&dev->spinlock, flags);
514 das1800_ai_handler(dev);
516 spin_unlock_irqrestore(&dev->spinlock, flags);
518 return comedi_buf_n_bytes_ready(s);
521 static irqreturn_t das1800_interrupt(int irq, void *d)
523 struct comedi_device *dev = d;
526 if (!dev->attached) {
527 dev_err(dev->class_dev, "premature interrupt\n");
532 * Protects the indirect addressing selected by DAS1800_SELECT
533 * in das1800_ai_handler() also prevents race with das1800_ai_poll().
535 spin_lock(&dev->spinlock);
537 status = inb(dev->iobase + DAS1800_STATUS);
539 /* if interrupt was not caused by das-1800 */
540 if (!(status & INT)) {
541 spin_unlock(&dev->spinlock);
544 /* clear the interrupt status bit INT */
545 outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
546 /* handle interrupt */
547 das1800_ai_handler(dev);
549 spin_unlock(&dev->spinlock);
553 static int das1800_ai_fixup_paced_timing(struct comedi_device *dev,
554 struct comedi_cmd *cmd)
556 unsigned int arg = cmd->convert_arg;
560 * scan_begin_src is TRIG_FOLLOW
561 * convert_src is TRIG_TIMER
563 * The convert_arg sets the pacer sample acquisition time.
564 * The max acquisition speed is limited to the boards
565 * 'ai_speed' (this was already verified). The min speed is
566 * limited by the cascaded 8254 timer.
568 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
569 return comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
572 static int das1800_ai_fixup_burst_timing(struct comedi_device *dev,
573 struct comedi_cmd *cmd)
575 unsigned int arg = cmd->convert_arg;
580 * scan_begin_src is TRIG_TIMER or TRIG_EXT
581 * convert_src is TRIG_TIMER
583 * The convert_arg sets burst sample acquisition time.
584 * The max acquisition speed is limited to the boards
585 * 'ai_speed' (this was already verified). The min speed is
586 * limiited to 64 microseconds,
588 err |= comedi_check_trigger_arg_max(&arg, 64000);
590 /* round to microseconds then verify */
591 switch (cmd->flags & CMDF_ROUND_MASK) {
592 case CMDF_ROUND_NEAREST:
594 arg = DIV_ROUND_CLOSEST(arg, 1000);
596 case CMDF_ROUND_DOWN:
600 arg = DIV_ROUND_UP(arg, 1000);
603 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg * 1000);
606 * The pacer can be used to set the scan sample rate. The max scan
607 * speed is limited by the conversion speed and the number of channels
608 * to convert. The min speed is limited by the cascaded 8254 timer.
610 if (cmd->scan_begin_src == TRIG_TIMER) {
611 arg = cmd->convert_arg * cmd->chanlist_len;
612 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, arg);
614 arg = cmd->scan_begin_arg;
615 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
616 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
622 static int das1800_ai_check_chanlist(struct comedi_device *dev,
623 struct comedi_subdevice *s,
624 struct comedi_cmd *cmd)
626 unsigned int range = CR_RANGE(cmd->chanlist[0]);
627 bool unipolar0 = comedi_range_is_unipolar(s, range);
630 for (i = 1; i < cmd->chanlist_len; i++) {
631 range = CR_RANGE(cmd->chanlist[i]);
633 if (unipolar0 != comedi_range_is_unipolar(s, range)) {
634 dev_dbg(dev->class_dev,
635 "unipolar and bipolar ranges cannot be mixed in the chanlist\n");
643 static int das1800_ai_cmdtest(struct comedi_device *dev,
644 struct comedi_subdevice *s,
645 struct comedi_cmd *cmd)
647 const struct das1800_board *board = dev->board_ptr;
650 /* Step 1 : check if triggers are trivially valid */
652 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
653 err |= comedi_check_trigger_src(&cmd->scan_begin_src,
654 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
655 err |= comedi_check_trigger_src(&cmd->convert_src,
656 TRIG_TIMER | TRIG_EXT);
657 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
658 err |= comedi_check_trigger_src(&cmd->stop_src,
659 TRIG_COUNT | TRIG_EXT | TRIG_NONE);
664 /* Step 2a : make sure trigger sources are unique */
666 err |= comedi_check_trigger_is_unique(cmd->start_src);
667 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
668 err |= comedi_check_trigger_is_unique(cmd->convert_src);
669 err |= comedi_check_trigger_is_unique(cmd->stop_src);
671 /* Step 2b : and mutually compatible */
673 /* burst scans must use timed conversions */
674 if (cmd->scan_begin_src != TRIG_FOLLOW &&
675 cmd->convert_src != TRIG_TIMER)
678 /* the external pin TGIN must use the same polarity */
679 if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
680 err |= comedi_check_trigger_arg_is(&cmd->start_arg,
686 /* Step 3: check if arguments are trivially valid */
688 if (cmd->start_arg == TRIG_NOW)
689 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
691 if (cmd->convert_src == TRIG_TIMER) {
692 err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
696 err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
697 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
700 switch (cmd->stop_src) {
702 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
705 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
714 /* Step 4: fix up any arguments */
716 if (cmd->convert_src == TRIG_TIMER) {
717 if (cmd->scan_begin_src == TRIG_FOLLOW)
718 err |= das1800_ai_fixup_paced_timing(dev, cmd);
719 else /* TRIG_TIMER or TRIG_EXT */
720 err |= das1800_ai_fixup_burst_timing(dev, cmd);
726 /* Step 5: check channel list if it exists */
727 if (cmd->chanlist && cmd->chanlist_len > 0)
728 err |= das1800_ai_check_chanlist(dev, s, cmd);
736 static unsigned char das1800_ai_chanspec_bits(struct comedi_subdevice *s,
737 unsigned int chanspec)
739 unsigned int range = CR_RANGE(chanspec);
740 unsigned int aref = CR_AREF(chanspec);
744 if (aref != AREF_DIFF)
746 if (aref == AREF_COMMON)
748 if (comedi_range_is_unipolar(s, range))
754 static unsigned int das1800_ai_transfer_size(struct comedi_device *dev,
755 struct comedi_subdevice *s,
756 unsigned int maxbytes,
759 struct comedi_cmd *cmd = &s->async->cmd;
760 unsigned int max_samples = comedi_bytes_to_samples(s, maxbytes);
761 unsigned int samples;
763 samples = max_samples;
765 /* for timed modes, make dma buffer fill in 'ns' time */
766 switch (cmd->scan_begin_src) {
767 case TRIG_FOLLOW: /* not in burst mode */
768 if (cmd->convert_src == TRIG_TIMER)
769 samples = ns / cmd->convert_arg;
772 samples = ns / (cmd->scan_begin_arg * cmd->chanlist_len);
776 /* limit samples to what is remaining in the command */
777 samples = comedi_nsamples_left(s, samples);
779 if (samples > max_samples)
780 samples = max_samples;
784 return comedi_samples_to_bytes(s, samples);
787 static void das1800_ai_setup_dma(struct comedi_device *dev,
788 struct comedi_subdevice *s)
790 struct das1800_private *devpriv = dev->private;
791 struct comedi_isadma *dma = devpriv->dma;
792 struct comedi_isadma_desc *desc;
795 if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
799 desc = &dma->desc[0];
801 /* determine a dma transfer size to fill buffer in 0.3 sec */
802 bytes = das1800_ai_transfer_size(dev, s, desc->maxsize, 300000000);
805 comedi_isadma_program(desc);
807 /* set up dual dma if appropriate */
808 if (devpriv->irq_dma_bits & DMA_DUAL) {
809 desc = &dma->desc[1];
811 comedi_isadma_program(desc);
815 static void das1800_ai_set_chanlist(struct comedi_device *dev,
816 unsigned int *chanlist, unsigned int len)
821 /* protects the indirect addressing selected by DAS1800_SELECT */
822 spin_lock_irqsave(&dev->spinlock, flags);
824 /* select QRAM register and set start address */
825 outb(QRAM, dev->iobase + DAS1800_SELECT);
826 outb(len - 1, dev->iobase + DAS1800_QRAM_ADDRESS);
828 /* make channel / gain list */
829 for (i = 0; i < len; i++) {
830 unsigned int chan = CR_CHAN(chanlist[i]);
831 unsigned int range = CR_RANGE(chanlist[i]);
834 val = chan | ((range & 0x3) << 8);
835 outw(val, dev->iobase + DAS1800_QRAM);
838 /* finish write to QRAM */
839 outb(len - 1, dev->iobase + DAS1800_QRAM_ADDRESS);
841 spin_unlock_irqrestore(&dev->spinlock, flags);
844 static int das1800_ai_cmd(struct comedi_device *dev,
845 struct comedi_subdevice *s)
847 struct das1800_private *devpriv = dev->private;
848 int control_a, control_c;
849 struct comedi_async *async = s->async;
850 const struct comedi_cmd *cmd = &async->cmd;
851 unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
854 * Disable dma on CMDF_WAKE_EOS, or CMDF_PRIORITY (because dma in
855 * handler is unsafe at hard real-time priority).
857 if (cmd->flags & (CMDF_WAKE_EOS | CMDF_PRIORITY))
858 devpriv->irq_dma_bits &= ~DMA_ENABLED;
860 devpriv->irq_dma_bits |= devpriv->dma_bits;
861 /* interrupt on end of conversion for CMDF_WAKE_EOS */
862 if (cmd->flags & CMDF_WAKE_EOS) {
863 /* interrupt fifo not empty */
864 devpriv->irq_dma_bits &= ~FIMD;
866 /* interrupt fifo half full */
867 devpriv->irq_dma_bits |= FIMD;
870 das1800_ai_cancel(dev, s);
872 devpriv->ai_is_unipolar = comedi_range_is_unipolar(s, range0);
875 if (cmd->stop_src == TRIG_EXT)
877 if (cmd->start_src == TRIG_EXT)
878 control_a |= TGEN | CGSL;
881 if (control_a & (ATEN | TGEN)) {
882 if ((cmd->start_arg & CR_INVERT) || (cmd->stop_arg & CR_INVERT))
886 control_c = das1800_ai_chanspec_bits(s, cmd->chanlist[0]);
887 /* set clock source to internal or external */
888 if (cmd->scan_begin_src == TRIG_FOLLOW) {
889 /* not in burst mode */
890 if (cmd->convert_src == TRIG_TIMER) {
891 /* trig on cascaded counters */
893 } else { /* TRIG_EXT */
894 /* trig on falling edge of external trigger */
897 } else if (cmd->scan_begin_src == TRIG_TIMER) {
898 /* burst mode with internal pacer clock */
899 control_c |= BMDE | IPCLK;
900 } else { /* TRIG_EXT */
901 /* burst mode with external trigger */
902 control_c |= BMDE | XPCLK;
905 das1800_ai_set_chanlist(dev, cmd->chanlist, cmd->chanlist_len);
907 /* setup cascaded counters for conversion/scan frequency */
908 if ((cmd->scan_begin_src == TRIG_FOLLOW ||
909 cmd->scan_begin_src == TRIG_TIMER) &&
910 cmd->convert_src == TRIG_TIMER) {
911 comedi_8254_update_divisors(dev->pacer);
912 comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
915 /* setup counter 0 for 'about triggering' */
916 if (cmd->stop_src == TRIG_EXT)
917 comedi_8254_load(dev->pacer, 0, 1, I8254_MODE0 | I8254_BINARY);
919 das1800_ai_setup_dma(dev, s);
920 outb(control_c, dev->iobase + DAS1800_CONTROL_C);
921 /* set conversion rate and length for burst mode */
922 if (control_c & BMDE) {
923 outb(cmd->convert_arg / 1000 - 1, /* microseconds - 1 */
924 dev->iobase + DAS1800_BURST_RATE);
925 outb(cmd->chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
928 /* enable and start conversions */
929 outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B);
930 outb(control_a, dev->iobase + DAS1800_CONTROL_A);
931 outb(CVEN, dev->iobase + DAS1800_STATUS);
936 static int das1800_ai_eoc(struct comedi_device *dev,
937 struct comedi_subdevice *s,
938 struct comedi_insn *insn,
939 unsigned long context)
941 unsigned char status;
943 status = inb(dev->iobase + DAS1800_STATUS);
949 static int das1800_ai_insn_read(struct comedi_device *dev,
950 struct comedi_subdevice *s,
951 struct comedi_insn *insn,
954 unsigned int range = CR_RANGE(insn->chanspec);
955 bool is_unipolar = comedi_range_is_unipolar(s, range);
961 outb(das1800_ai_chanspec_bits(s, insn->chanspec),
962 dev->iobase + DAS1800_CONTROL_C); /* software pacer */
963 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
964 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */
965 outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
967 das1800_ai_set_chanlist(dev, &insn->chanspec, 1);
969 /* protects the indirect addressing selected by DAS1800_SELECT */
970 spin_lock_irqsave(&dev->spinlock, flags);
972 /* select ai fifo register */
973 outb(ADC, dev->iobase + DAS1800_SELECT);
975 for (n = 0; n < insn->n; n++) {
976 /* trigger conversion */
977 outb(0, dev->iobase + DAS1800_FIFO);
979 ret = comedi_timeout(dev, s, insn, das1800_ai_eoc, 0);
983 dpnt = inw(dev->iobase + DAS1800_FIFO);
985 dpnt = comedi_offset_munge(s, dpnt);
988 spin_unlock_irqrestore(&dev->spinlock, flags);
990 return ret ? ret : insn->n;
993 static int das1800_ao_insn_write(struct comedi_device *dev,
994 struct comedi_subdevice *s,
995 struct comedi_insn *insn,
998 unsigned int chan = CR_CHAN(insn->chanspec);
999 unsigned int update_chan = s->n_chan - 1;
1000 unsigned long flags;
1003 /* protects the indirect addressing selected by DAS1800_SELECT */
1004 spin_lock_irqsave(&dev->spinlock, flags);
1006 for (i = 0; i < insn->n; i++) {
1007 unsigned int val = data[i];
1009 s->readback[chan] = val;
1011 val = comedi_offset_munge(s, val);
1013 /* load this channel (and update if it's the last channel) */
1014 outb(DAC(chan), dev->iobase + DAS1800_SELECT);
1015 outw(val, dev->iobase + DAS1800_DAC);
1017 /* update all channels */
1018 if (chan != update_chan) {
1019 val = comedi_offset_munge(s, s->readback[update_chan]);
1021 outb(DAC(update_chan), dev->iobase + DAS1800_SELECT);
1022 outw(val, dev->iobase + DAS1800_DAC);
1025 spin_unlock_irqrestore(&dev->spinlock, flags);
1030 static int das1800_di_insn_bits(struct comedi_device *dev,
1031 struct comedi_subdevice *s,
1032 struct comedi_insn *insn,
1035 data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf;
1041 static int das1800_do_insn_bits(struct comedi_device *dev,
1042 struct comedi_subdevice *s,
1043 struct comedi_insn *insn,
1046 if (comedi_dio_update_state(s, data))
1047 outb(s->state, dev->iobase + DAS1800_DIGITAL);
1054 static void das1800_init_dma(struct comedi_device *dev,
1055 struct comedi_devconfig *it)
1057 struct das1800_private *devpriv = dev->private;
1058 unsigned int *dma_chan;
1061 * it->options[2] is DMA channel 0
1062 * it->options[3] is DMA channel 1
1064 * Encode the DMA channels into 2 digit hexadecimal for switch.
1066 dma_chan = &it->options[2];
1068 switch ((dma_chan[0] & 0x7) | (dma_chan[1] << 4)) {
1069 case 0x5: /* dma0 == 5 */
1070 devpriv->dma_bits = DMA_CH5;
1072 case 0x6: /* dma0 == 6 */
1073 devpriv->dma_bits = DMA_CH6;
1075 case 0x7: /* dma0 == 7 */
1076 devpriv->dma_bits = DMA_CH7;
1078 case 0x65: /* dma0 == 5, dma1 == 6 */
1079 devpriv->dma_bits = DMA_CH5_CH6;
1081 case 0x76: /* dma0 == 6, dma1 == 7 */
1082 devpriv->dma_bits = DMA_CH6_CH7;
1084 case 0x57: /* dma0 == 7, dma1 == 5 */
1085 devpriv->dma_bits = DMA_CH7_CH5;
1091 /* DMA can use 1 or 2 buffers, each with a separate channel */
1092 devpriv->dma = comedi_isadma_alloc(dev, dma_chan[1] ? 2 : 1,
1093 dma_chan[0], dma_chan[1],
1094 DMA_BUF_SIZE, COMEDI_ISADMA_READ);
1096 devpriv->dma_bits = 0;
1099 static void das1800_free_dma(struct comedi_device *dev)
1101 struct das1800_private *devpriv = dev->private;
1104 comedi_isadma_free(devpriv->dma);
1107 static int das1800_probe(struct comedi_device *dev)
1109 const struct das1800_board *board = dev->board_ptr;
1112 id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf;
1115 * The dev->board_ptr will be set by comedi_device_attach() if the
1116 * board name provided by the user matches a board->name in this
1117 * driver. If so, this function sanity checks the id to verify that
1118 * the board is correct.
1121 if (board->id == id)
1123 dev_err(dev->class_dev,
1124 "probed id does not match board id (0x%x != 0x%x)\n",
1130 * If the dev->board_ptr is not set, the user is trying to attach
1131 * an unspecified board to this driver. In this case the id is used
1132 * to 'probe' for the dev->board_ptr.
1135 case DAS1800_ID_ST_DA:
1136 /* das-1701st-da, das-1702st-da, das-1801st-da, das-1802st-da */
1137 board = &das1800_boards[BOARD_DAS1801ST_DA];
1139 case DAS1800_ID_HR_DA:
1140 /* das-1702hr-da, das-1802hr-da */
1141 board = &das1800_boards[BOARD_DAS1802HR_DA];
1144 /* das-1701ao, das-1702ao, das-1801ao, das-1802ao */
1145 board = &das1800_boards[BOARD_DAS1801AO];
1148 /* das-1702hr, das-1802hr */
1149 board = &das1800_boards[BOARD_DAS1802HR];
1152 /* das-1701st, das-1702st, das-1801st, das-1802st */
1153 board = &das1800_boards[BOARD_DAS1801ST];
1156 /* das-1801hc, das-1802hc */
1157 board = &das1800_boards[BOARD_DAS1801HC];
1160 dev_err(dev->class_dev, "invalid probe id 0x%x\n", id);
1163 dev->board_ptr = board;
1164 dev->board_name = board->name;
1165 dev_warn(dev->class_dev,
1166 "probed id 0x%0x: %s series (not recommended)\n",
1171 static int das1800_attach(struct comedi_device *dev,
1172 struct comedi_devconfig *it)
1174 const struct das1800_board *board;
1175 struct das1800_private *devpriv;
1176 struct comedi_subdevice *s;
1177 unsigned int irq = it->options[1];
1182 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1186 ret = comedi_request_region(dev, it->options[0], DAS1800_SIZE);
1190 ret = das1800_probe(dev);
1193 board = dev->board_ptr;
1195 is_16bit = board->id == DAS1800_ID_HR || board->id == DAS1800_ID_HR_DA;
1197 /* waveform 'ao' boards have additional io ports */
1198 if (board->id == DAS1800_ID_AO) {
1199 unsigned long iobase2 = dev->iobase + IOBASE2;
1201 ret = __comedi_request_region(dev, iobase2, DAS1800_SIZE);
1204 devpriv->iobase2 = iobase2;
1207 if (irq == 3 || irq == 5 || irq == 7 || irq == 10 || irq == 11 ||
1209 ret = request_irq(irq, das1800_interrupt, 0,
1210 dev->board_name, dev);
1216 devpriv->irq_dma_bits |= 0x8;
1219 devpriv->irq_dma_bits |= 0x10;
1222 devpriv->irq_dma_bits |= 0x18;
1225 devpriv->irq_dma_bits |= 0x28;
1228 devpriv->irq_dma_bits |= 0x30;
1231 devpriv->irq_dma_bits |= 0x38;
1237 /* an irq and one dma channel is required to use dma */
1238 if (dev->irq & it->options[2])
1239 das1800_init_dma(dev, it);
1241 devpriv->fifo_buf = kmalloc_array(FIFO_SIZE,
1242 sizeof(*devpriv->fifo_buf),
1244 if (!devpriv->fifo_buf)
1247 dev->pacer = comedi_8254_init(dev->iobase + DAS1800_COUNTER,
1248 I8254_OSC_BASE_5MHZ, I8254_IO8, 0);
1252 ret = comedi_alloc_subdevices(dev, 4);
1257 * Analog Input subdevice
1259 * The "hc" type boards have 64 analog input channels and a 64
1262 * All the other board types have 16 on-board channels. Each channel
1263 * can be expanded to 16 channels with the addition of an EXP-1800
1264 * expansion board for a total of 256 channels. The QRAM fifo on
1265 * these boards has 256 entries.
1267 * From the datasheets it's not clear what the comedi channel to
1268 * actual physical channel mapping is when EXP-1800 boards are used.
1270 s = &dev->subdevices[0];
1271 s->type = COMEDI_SUBD_AI;
1272 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND;
1273 if (board->id != DAS1800_ID_HC)
1274 s->subdev_flags |= SDF_COMMON;
1275 s->n_chan = (board->id == DAS1800_ID_HC) ? 64 : 256;
1276 s->maxdata = is_16bit ? 0xffff : 0x0fff;
1277 s->range_table = board->is_01_series ? &das1801_ai_range
1278 : &das1802_ai_range;
1279 s->insn_read = das1800_ai_insn_read;
1281 dev->read_subdev = s;
1282 s->subdev_flags |= SDF_CMD_READ;
1283 s->len_chanlist = s->n_chan;
1284 s->do_cmd = das1800_ai_cmd;
1285 s->do_cmdtest = das1800_ai_cmdtest;
1286 s->poll = das1800_ai_poll;
1287 s->cancel = das1800_ai_cancel;
1288 s->munge = das1800_ai_munge;
1291 /* Analog Output subdevice */
1292 s = &dev->subdevices[1];
1293 if (board->id == DAS1800_ID_ST_DA || board->id == DAS1800_ID_HR_DA) {
1294 s->type = COMEDI_SUBD_AO;
1295 s->subdev_flags = SDF_WRITABLE;
1296 s->n_chan = (board->id == DAS1800_ID_ST_DA) ? 4 : 2;
1297 s->maxdata = is_16bit ? 0xffff : 0x0fff;
1298 s->range_table = &range_bipolar10;
1299 s->insn_write = das1800_ao_insn_write;
1301 ret = comedi_alloc_subdev_readback(s);
1305 /* initialize all channels to 0V */
1306 for (i = 0; i < s->n_chan; i++) {
1307 /* spinlock is not necessary during the attach */
1308 outb(DAC(i), dev->iobase + DAS1800_SELECT);
1309 outw(0, dev->iobase + DAS1800_DAC);
1311 } else if (board->id == DAS1800_ID_AO) {
1313 * 'ao' boards have waveform analog outputs that are not
1314 * currently supported.
1316 s->type = COMEDI_SUBD_UNUSED;
1318 s->type = COMEDI_SUBD_UNUSED;
1321 /* Digital Input subdevice */
1322 s = &dev->subdevices[2];
1323 s->type = COMEDI_SUBD_DI;
1324 s->subdev_flags = SDF_READABLE;
1327 s->range_table = &range_digital;
1328 s->insn_bits = das1800_di_insn_bits;
1330 /* Digital Output subdevice */
1331 s = &dev->subdevices[3];
1332 s->type = COMEDI_SUBD_DO;
1333 s->subdev_flags = SDF_WRITABLE;
1334 s->n_chan = (board->id == DAS1800_ID_HC) ? 8 : 4;
1336 s->range_table = &range_digital;
1337 s->insn_bits = das1800_do_insn_bits;
1339 das1800_ai_cancel(dev, dev->read_subdev);
1341 /* initialize digital out channels */
1342 outb(0, dev->iobase + DAS1800_DIGITAL);
1347 static void das1800_detach(struct comedi_device *dev)
1349 struct das1800_private *devpriv = dev->private;
1351 das1800_free_dma(dev);
1353 kfree(devpriv->fifo_buf);
1354 if (devpriv->iobase2)
1355 release_region(devpriv->iobase2, DAS1800_SIZE);
1357 comedi_legacy_detach(dev);
1360 static struct comedi_driver das1800_driver = {
1361 .driver_name = "das1800",
1362 .module = THIS_MODULE,
1363 .attach = das1800_attach,
1364 .detach = das1800_detach,
1365 .num_names = ARRAY_SIZE(das1800_boards),
1366 .board_name = &das1800_boards[0].name,
1367 .offset = sizeof(struct das1800_board),
1369 module_comedi_driver(das1800_driver);
1371 MODULE_AUTHOR("Comedi http://www.comedi.org");
1372 MODULE_DESCRIPTION("Comedi driver for DAS1800 compatible ISA boards");
1373 MODULE_LICENSE("GPL");