2 comedi/drivers/das1800.c
3 Driver for Keitley das1700/das1800 series boards
4 Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
6 COMEDI - Linux Control and Measurement Device Interface
7 Copyright (C) 2000 David A. Schleef <ds@schleef.org>
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 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 The waveform analog output on the 'ao' cards is not supported.
36 If you need it, send me (Frank Hess) an email.
38 Configuration options:
39 [0] - I/O port base address
40 [1] - IRQ (optional, required for timed or externally triggered conversions)
41 [2] - DMA0 (optional, requires irq)
42 [3] - DMA1 (optional, requires irq and dma0)
46 This driver supports the following Keithley boards:
69 [1] - irq (optional, required for timed or externally triggered conversions)
70 [2] - dma0 (optional, requires irq)
71 [3] - dma1 (optional, requires irq and dma0)
73 irq can be omitted, although the cmd interface will not work without it.
75 analog input cmd triggers supported:
76 start_src: TRIG_NOW | TRIG_EXT
77 scan_begin_src: TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT
78 scan_end_src: TRIG_COUNT
79 convert_src: TRIG_TIMER | TRIG_EXT (TRIG_EXT requires scan_begin_src == TRIG_FOLLOW)
80 stop_src: TRIG_COUNT | TRIG_EXT | TRIG_NONE
82 scan_begin_src triggers TRIG_TIMER and TRIG_EXT use the card's
83 'burst mode' which limits the valid conversion time to 64 microseconds
84 (convert_arg <= 64000). This limitation does not apply if scan_begin_src
88 Only the DAS-1801ST has been tested by me.
89 Unipolar and bipolar ranges cannot be mixed in the channel/gain list.
92 Make it automatically allocate irq and dma channels if they are not specified
93 Add support for analog out on 'ao' cards
94 read insn for analog out
97 #include <linux/module.h>
98 #include <linux/interrupt.h>
99 #include <linux/slab.h>
100 #include <linux/io.h>
101 #include "../comedidev.h"
106 #include "comedi_fc.h"
109 #define DAS1800_SIZE 16 /* uses 16 io addresses */
110 #define FIFO_SIZE 1024 /* 1024 sample fifo */
111 #define TIMER_BASE 200 /* 5 Mhz master clock */
112 #define UNIPOLAR 0x4 /* bit that determines whether input range is uni/bipolar */
113 #define DMA_BUF_SIZE 0x1ff00 /* size in bytes of dma buffers */
115 /* Registers for the das1800 */
116 #define DAS1800_FIFO 0x0
117 #define DAS1800_QRAM 0x0
118 #define DAS1800_DAC 0x0
119 #define DAS1800_SELECT 0x2
122 #define DAC(a) (0x2 + a)
123 #define DAS1800_DIGITAL 0x3
124 #define DAS1800_CONTROL_A 0x4
131 #define DAS1800_CONTROL_B 0x5
135 #define DMA_CH5_CH6 0x5
136 #define DMA_CH6_CH7 0x6
137 #define DMA_CH7_CH5 0x7
138 #define DMA_ENABLED 0x3 /* mask used to determine if dma is enabled */
147 #define DAS1800_CONTROL_C 0X6
155 #define DAS1800_STATUS 0x7
156 /* bits that prevent interrupt status bits (and CVEN) from being cleared on write */
157 #define CLEAR_INTR_MASK (CVEN_MASK | 0x1f)
164 #define CVEN_MASK 0x40 /* masks CVEN on write */
166 #define DAS1800_BURST_LENGTH 0x8
167 #define DAS1800_BURST_RATE 0x9
168 #define DAS1800_QRAM_ADDRESS 0xa
169 #define DAS1800_COUNTER 0xc
171 #define IOBASE2 0x400 /* offset of additional ioports used on 'ao' cards */
174 das1701st, das1701st_da, das1702st, das1702st_da, das1702hr,
176 das1701ao, das1702ao, das1801st, das1801st_da, das1802st, das1802st_da,
177 das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao
180 /* analog input ranges */
181 static const struct comedi_lrange range_ai_das1801 = {
195 static const struct comedi_lrange range_ai_das1802 = {
209 struct das1800_board {
211 int ai_speed; /* max conversion period in nanoseconds */
212 int resolution; /* bits of ai resolution */
213 int qram_len; /* length of card's channel / gain queue */
214 int common; /* supports AREF_COMMON flag */
215 int do_n_chan; /* number of digital output channels */
216 int ao_ability; /* 0 == no analog out, 1 == basic analog out, 2 == waveform analog out */
217 int ao_n_chan; /* number of analog out channels */
218 const struct comedi_lrange *range_ai; /* available input ranges */
221 /* Warning: the maximum conversion speeds listed below are
222 * not always achievable depending on board setup (see
225 static const struct das1800_board das1800_boards[] = {
227 .name = "das-1701st",
235 .range_ai = &range_ai_das1801,
238 .name = "das-1701st-da",
246 .range_ai = &range_ai_das1801,
249 .name = "das-1702st",
257 .range_ai = &range_ai_das1802,
260 .name = "das-1702st-da",
268 .range_ai = &range_ai_das1802,
271 .name = "das-1702hr",
279 .range_ai = &range_ai_das1802,
282 .name = "das-1702hr-da",
290 .range_ai = &range_ai_das1802,
293 .name = "das-1701ao",
301 .range_ai = &range_ai_das1801,
304 .name = "das-1702ao",
312 .range_ai = &range_ai_das1802,
315 .name = "das-1801st",
323 .range_ai = &range_ai_das1801,
326 .name = "das-1801st-da",
334 .range_ai = &range_ai_das1801,
337 .name = "das-1802st",
345 .range_ai = &range_ai_das1802,
348 .name = "das-1802st-da",
356 .range_ai = &range_ai_das1802,
359 .name = "das-1802hr",
367 .range_ai = &range_ai_das1802,
370 .name = "das-1802hr-da",
378 .range_ai = &range_ai_das1802,
381 .name = "das-1801hc",
389 .range_ai = &range_ai_das1801,
392 .name = "das-1802hc",
400 .range_ai = &range_ai_das1802,
403 .name = "das-1801ao",
411 .range_ai = &range_ai_das1801,
414 .name = "das-1802ao",
422 .range_ai = &range_ai_das1802,
426 struct das1800_private {
427 volatile unsigned int count; /* number of data points left to be taken */
428 unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */
429 unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */
430 int do_bits; /* digital output bits */
431 int irq_dma_bits; /* bits for control register b */
432 /* dma bits for control register b, stored so that dma can be
433 * turned on and off */
435 unsigned int dma0; /* dma channels used */
437 volatile unsigned int dma_current; /* dma channel currently in use */
438 uint16_t *ai_buf0; /* pointers to dma buffers */
440 uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */
441 unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */
442 unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */
443 short ao_update_bits; /* remembers the last write to the 'update' dac */
446 /* analog out range for 'ao' boards */
448 static const struct comedi_lrange range_ao_2 = {
457 static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev,
460 const struct das1800_board *thisboard = comedi_board(dev);
462 sample += 1 << (thisboard->resolution - 1);
466 static void munge_data(struct comedi_device *dev, uint16_t * array,
467 unsigned int num_elements)
472 /* see if card is using a unipolar or bipolar range so we can munge data correctly */
473 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
475 /* convert to unsigned type if we are in a bipolar mode */
477 for (i = 0; i < num_elements; i++)
478 array[i] = munge_bipolar_sample(dev, array[i]);
482 static void das1800_handle_fifo_half_full(struct comedi_device *dev,
483 struct comedi_subdevice *s)
485 struct das1800_private *devpriv = dev->private;
486 int numPoints = 0; /* number of points to read */
487 struct comedi_cmd *cmd = &s->async->cmd;
489 numPoints = FIFO_SIZE / 2;
490 /* if we only need some of the points */
491 if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints)
492 numPoints = devpriv->count;
493 insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints);
494 munge_data(dev, devpriv->ai_buf0, numPoints);
495 cfc_write_array_to_buffer(s, devpriv->ai_buf0,
496 numPoints * sizeof(devpriv->ai_buf0[0]));
497 if (cmd->stop_src == TRIG_COUNT)
498 devpriv->count -= numPoints;
502 static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
503 struct comedi_subdevice *s)
505 struct das1800_private *devpriv = dev->private;
508 struct comedi_cmd *cmd = &s->async->cmd;
510 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
512 while (inb(dev->iobase + DAS1800_STATUS) & FNE) {
513 if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
515 dpnt = inw(dev->iobase + DAS1800_FIFO);
516 /* convert to unsigned type if we are in a bipolar mode */
519 dpnt = munge_bipolar_sample(dev, dpnt);
520 cfc_write_to_buffer(s, dpnt);
521 if (cmd->stop_src == TRIG_COUNT)
528 /* Utility function used by das1800_flush_dma() and das1800_handle_dma().
529 * Assumes dma lock is held */
530 static void das1800_flush_dma_channel(struct comedi_device *dev,
531 struct comedi_subdevice *s,
532 unsigned int channel, uint16_t *buffer)
534 struct das1800_private *devpriv = dev->private;
535 unsigned int num_bytes, num_samples;
536 struct comedi_cmd *cmd = &s->async->cmd;
538 disable_dma(channel);
540 /* clear flip-flop to make sure 2-byte registers
541 * get set correctly */
542 clear_dma_ff(channel);
544 /* figure out how many points to read */
545 num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel);
546 num_samples = num_bytes / sizeof(short);
548 /* if we only need some of the points */
549 if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples)
550 num_samples = devpriv->count;
552 munge_data(dev, buffer, num_samples);
553 cfc_write_array_to_buffer(s, buffer, num_bytes);
554 if (s->async->cmd.stop_src == TRIG_COUNT)
555 devpriv->count -= num_samples;
560 /* flushes remaining data from board when external trigger has stopped acquisition
561 * and we are using dma transfers */
562 static void das1800_flush_dma(struct comedi_device *dev,
563 struct comedi_subdevice *s)
565 struct das1800_private *devpriv = dev->private;
567 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
569 flags = claim_dma_lock();
570 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
571 devpriv->dma_current_buf);
574 /* switch to other channel and flush it */
575 if (devpriv->dma_current == devpriv->dma0) {
576 devpriv->dma_current = devpriv->dma1;
577 devpriv->dma_current_buf = devpriv->ai_buf1;
579 devpriv->dma_current = devpriv->dma0;
580 devpriv->dma_current_buf = devpriv->ai_buf0;
582 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
583 devpriv->dma_current_buf);
586 release_dma_lock(flags);
588 /* get any remaining samples in fifo */
589 das1800_handle_fifo_not_empty(dev, s);
594 static void das1800_handle_dma(struct comedi_device *dev,
595 struct comedi_subdevice *s, unsigned int status)
597 struct das1800_private *devpriv = dev->private;
599 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
601 flags = claim_dma_lock();
602 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
603 devpriv->dma_current_buf);
604 /* re-enable dma channel */
605 set_dma_addr(devpriv->dma_current,
606 virt_to_bus(devpriv->dma_current_buf));
607 set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size);
608 enable_dma(devpriv->dma_current);
609 release_dma_lock(flags);
611 if (status & DMATC) {
612 /* clear DMATC interrupt bit */
613 outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
614 /* switch dma channels for next time, if appropriate */
616 /* read data from the other channel next time */
617 if (devpriv->dma_current == devpriv->dma0) {
618 devpriv->dma_current = devpriv->dma1;
619 devpriv->dma_current_buf = devpriv->ai_buf1;
621 devpriv->dma_current = devpriv->dma0;
622 devpriv->dma_current_buf = devpriv->ai_buf0;
630 static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
632 struct das1800_private *devpriv = dev->private;
634 outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */
635 outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */
636 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */
638 disable_dma(devpriv->dma0);
640 disable_dma(devpriv->dma1);
644 /* the guts of the interrupt handler, that is shared with das1800_ai_poll */
645 static void das1800_ai_handler(struct comedi_device *dev)
647 struct das1800_private *devpriv = dev->private;
648 struct comedi_subdevice *s = &dev->subdevices[0];
649 struct comedi_async *async = s->async;
650 struct comedi_cmd *cmd = &async->cmd;
651 unsigned int status = inb(dev->iobase + DAS1800_STATUS);
654 /* select adc for base address + 0 */
655 outb(ADC, dev->iobase + DAS1800_SELECT);
656 /* dma buffer full */
657 if (devpriv->irq_dma_bits & DMA_ENABLED) {
658 /* look for data from dma transfer even if dma terminal count hasn't happened yet */
659 das1800_handle_dma(dev, s, status);
660 } else if (status & FHF) { /* if fifo half full */
661 das1800_handle_fifo_half_full(dev, s);
662 } else if (status & FNE) { /* if fifo not empty */
663 das1800_handle_fifo_not_empty(dev, s);
666 async->events |= COMEDI_CB_BLOCK;
667 /* if the card's fifo has overflowed */
669 /* clear OVF interrupt bit */
670 outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
671 comedi_error(dev, "DAS1800 FIFO overflow");
672 das1800_cancel(dev, s);
673 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
674 comedi_event(dev, s);
677 /* stop taking data if appropriate */
678 /* stop_src TRIG_EXT */
679 if (status & CT0TC) {
680 /* clear CT0TC interrupt bit */
681 outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
682 /* make sure we get all remaining data from board before quitting */
683 if (devpriv->irq_dma_bits & DMA_ENABLED)
684 das1800_flush_dma(dev, s);
686 das1800_handle_fifo_not_empty(dev, s);
687 das1800_cancel(dev, s); /* disable hardware conversions */
688 async->events |= COMEDI_CB_EOA;
689 } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { /* stop_src TRIG_COUNT */
690 das1800_cancel(dev, s); /* disable hardware conversions */
691 async->events |= COMEDI_CB_EOA;
694 comedi_event(dev, s);
699 static int das1800_ai_poll(struct comedi_device *dev,
700 struct comedi_subdevice *s)
704 /* prevent race with interrupt handler */
705 spin_lock_irqsave(&dev->spinlock, flags);
706 das1800_ai_handler(dev);
707 spin_unlock_irqrestore(&dev->spinlock, flags);
709 return s->async->buf_write_count - s->async->buf_read_count;
712 static irqreturn_t das1800_interrupt(int irq, void *d)
714 struct comedi_device *dev = d;
717 if (!dev->attached) {
718 comedi_error(dev, "premature interrupt");
722 /* Prevent race with das1800_ai_poll() on multi processor systems.
723 * Also protects indirect addressing in das1800_ai_handler */
724 spin_lock(&dev->spinlock);
725 status = inb(dev->iobase + DAS1800_STATUS);
727 /* if interrupt was not caused by das-1800 */
728 if (!(status & INT)) {
729 spin_unlock(&dev->spinlock);
732 /* clear the interrupt status bit INT */
733 outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
734 /* handle interrupt */
735 das1800_ai_handler(dev);
737 spin_unlock(&dev->spinlock);
741 /* converts requested conversion timing to timing compatible with
742 * hardware, used only when card is in 'burst mode'
744 static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode)
746 unsigned int micro_sec;
748 /* in burst mode, the maximum conversion time is 64 microseconds */
749 if (convert_arg > 64000)
752 /* the conversion time must be an integral number of microseconds */
753 switch (round_mode) {
754 case TRIG_ROUND_NEAREST:
756 micro_sec = (convert_arg + 500) / 1000;
758 case TRIG_ROUND_DOWN:
759 micro_sec = convert_arg / 1000;
762 micro_sec = (convert_arg - 1) / 1000 + 1;
766 /* return number of nanoseconds */
767 return micro_sec * 1000;
770 /* test analog input cmd */
771 static int das1800_ai_do_cmdtest(struct comedi_device *dev,
772 struct comedi_subdevice *s,
773 struct comedi_cmd *cmd)
775 const struct das1800_board *thisboard = comedi_board(dev);
776 struct das1800_private *devpriv = dev->private;
778 unsigned int tmp_arg;
782 /* Step 1 : check if triggers are trivially valid */
784 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
785 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
786 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
787 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
788 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
789 err |= cfc_check_trigger_src(&cmd->stop_src,
790 TRIG_COUNT | TRIG_EXT | TRIG_NONE);
795 /* Step 2a : make sure trigger sources are unique */
797 err |= cfc_check_trigger_is_unique(cmd->start_src);
798 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
799 err |= cfc_check_trigger_is_unique(cmd->convert_src);
800 err |= cfc_check_trigger_is_unique(cmd->stop_src);
802 /* Step 2b : and mutually compatible */
804 if (cmd->scan_begin_src != TRIG_FOLLOW &&
805 cmd->convert_src != TRIG_TIMER)
811 /* Step 3: check if arguments are trivially valid */
813 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
815 if (cmd->convert_src == TRIG_TIMER)
816 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
817 thisboard->ai_speed);
819 err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
820 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
822 switch (cmd->stop_src) {
824 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
827 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
836 /* step 4: fix up any arguments */
838 if (cmd->convert_src == TRIG_TIMER) {
839 /* if we are not in burst mode */
840 if (cmd->scan_begin_src == TRIG_FOLLOW) {
841 tmp_arg = cmd->convert_arg;
842 /* calculate counter values that give desired timing */
843 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
844 &(devpriv->divisor1),
845 &(devpriv->divisor2),
848 flags & TRIG_ROUND_MASK);
849 if (tmp_arg != cmd->convert_arg)
852 /* if we are in burst mode */
854 /* check that convert_arg is compatible */
855 tmp_arg = cmd->convert_arg;
857 burst_convert_arg(cmd->convert_arg,
858 cmd->flags & TRIG_ROUND_MASK);
859 if (tmp_arg != cmd->convert_arg)
862 if (cmd->scan_begin_src == TRIG_TIMER) {
863 /* if scans are timed faster than conversion rate allows */
864 if (cmd->convert_arg * cmd->chanlist_len >
865 cmd->scan_begin_arg) {
866 cmd->scan_begin_arg =
871 tmp_arg = cmd->scan_begin_arg;
872 /* calculate counter values that give desired timing */
873 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
883 if (tmp_arg != cmd->scan_begin_arg)
892 /* make sure user is not trying to mix unipolar and bipolar ranges */
894 unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR;
895 for (i = 1; i < cmd->chanlist_len; i++) {
896 if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) {
898 "unipolar and bipolar ranges cannot be mixed in the chanlist");
911 /* returns appropriate bits for control register a, depending on command */
912 static int control_a_bits(const struct comedi_cmd *cmd)
916 control_a = FFEN; /* enable fifo */
917 if (cmd->stop_src == TRIG_EXT)
919 switch (cmd->start_src) {
921 control_a |= TGEN | CGSL;
933 /* returns appropriate bits for control register c, depending on command */
934 static int control_c_bits(const struct comedi_cmd *cmd)
939 /* set clock source to internal or external, select analog reference,
940 * select unipolar / bipolar
942 aref = CR_AREF(cmd->chanlist[0]);
943 control_c = UQEN; /* enable upper qram addresses */
944 if (aref != AREF_DIFF)
946 if (aref == AREF_COMMON)
948 /* if a unipolar range was selected */
949 if (CR_RANGE(cmd->chanlist[0]) & UNIPOLAR)
951 switch (cmd->scan_begin_src) {
952 case TRIG_FOLLOW: /* not in burst mode */
953 switch (cmd->convert_src) {
955 /* trig on cascaded counters */
959 /* trig on falling edge of external trigger */
967 /* burst mode with internal pacer clock */
968 control_c |= BMDE | IPCLK;
971 /* burst mode with external trigger */
972 control_c |= BMDE | XPCLK;
981 /* loads counters with divisor1, divisor2 from private structure */
982 static int das1800_set_frequency(struct comedi_device *dev)
984 struct das1800_private *devpriv = dev->private;
987 /* counter 1, mode 2 */
988 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1,
991 /* counter 2, mode 2 */
992 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2,
1001 /* sets up counters */
1002 static int setup_counters(struct comedi_device *dev,
1003 const struct comedi_cmd *cmd)
1005 struct das1800_private *devpriv = dev->private;
1006 unsigned int period;
1008 /* setup cascaded counters for conversion/scan frequency */
1009 switch (cmd->scan_begin_src) {
1010 case TRIG_FOLLOW: /* not in burst mode */
1011 if (cmd->convert_src == TRIG_TIMER) {
1012 /* set conversion frequency */
1013 period = cmd->convert_arg;
1014 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1020 if (das1800_set_frequency(dev) < 0)
1024 case TRIG_TIMER: /* in burst mode */
1025 /* set scan frequency */
1026 period = cmd->scan_begin_arg;
1027 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &devpriv->divisor1,
1028 &devpriv->divisor2, &period,
1029 cmd->flags & TRIG_ROUND_MASK);
1030 if (das1800_set_frequency(dev) < 0)
1037 /* setup counter 0 for 'about triggering' */
1038 if (cmd->stop_src == TRIG_EXT) {
1039 /* load counter 0 in mode 0 */
1040 i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0);
1046 /* utility function that suggests a dma transfer size based on the conversion period 'ns' */
1047 static unsigned int suggest_transfer_size(const struct comedi_cmd *cmd)
1049 unsigned int size = DMA_BUF_SIZE;
1050 static const int sample_size = 2; /* size in bytes of one sample from board */
1051 unsigned int fill_time = 300000000; /* target time in nanoseconds for filling dma buffer */
1052 unsigned int max_size; /* maximum size we will allow for a transfer */
1054 /* make dma buffer fill in 0.3 seconds for timed modes */
1055 switch (cmd->scan_begin_src) {
1056 case TRIG_FOLLOW: /* not in burst mode */
1057 if (cmd->convert_src == TRIG_TIMER)
1058 size = (fill_time / cmd->convert_arg) * sample_size;
1061 size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) *
1065 size = DMA_BUF_SIZE;
1069 /* set a minimum and maximum size allowed */
1070 max_size = DMA_BUF_SIZE;
1071 /* if we are taking limited number of conversions, limit transfer size to that */
1072 if (cmd->stop_src == TRIG_COUNT &&
1073 cmd->stop_arg * cmd->chanlist_len * sample_size < max_size)
1074 max_size = cmd->stop_arg * cmd->chanlist_len * sample_size;
1076 if (size > max_size)
1078 if (size < sample_size)
1085 static void setup_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
1087 struct das1800_private *devpriv = dev->private;
1088 unsigned long lock_flags;
1089 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
1091 if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
1094 /* determine a reasonable dma transfer size */
1095 devpriv->dma_transfer_size = suggest_transfer_size(cmd);
1096 lock_flags = claim_dma_lock();
1097 disable_dma(devpriv->dma0);
1098 /* clear flip-flop to make sure 2-byte registers for
1099 * count and address get set correctly */
1100 clear_dma_ff(devpriv->dma0);
1101 set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0));
1102 /* set appropriate size of transfer */
1103 set_dma_count(devpriv->dma0, devpriv->dma_transfer_size);
1104 devpriv->dma_current = devpriv->dma0;
1105 devpriv->dma_current_buf = devpriv->ai_buf0;
1106 enable_dma(devpriv->dma0);
1107 /* set up dual dma if appropriate */
1109 disable_dma(devpriv->dma1);
1110 /* clear flip-flop to make sure 2-byte registers for
1111 * count and address get set correctly */
1112 clear_dma_ff(devpriv->dma1);
1113 set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1));
1114 /* set appropriate size of transfer */
1115 set_dma_count(devpriv->dma1, devpriv->dma_transfer_size);
1116 enable_dma(devpriv->dma1);
1118 release_dma_lock(lock_flags);
1123 /* programs channel/gain list into card */
1124 static void program_chanlist(struct comedi_device *dev,
1125 const struct comedi_cmd *cmd)
1127 int i, n, chan_range;
1128 unsigned long irq_flags;
1129 const int range_mask = 0x3; /* masks unipolar/bipolar bit off range */
1130 const int range_bitshift = 8;
1132 n = cmd->chanlist_len;
1133 /* spinlock protects indirect addressing */
1134 spin_lock_irqsave(&dev->spinlock, irq_flags);
1135 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
1136 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */
1137 /* make channel / gain list */
1138 for (i = 0; i < n; i++) {
1140 CR_CHAN(cmd->chanlist[i]) |
1141 ((CR_RANGE(cmd->chanlist[i]) & range_mask) <<
1143 outw(chan_range, dev->iobase + DAS1800_QRAM);
1145 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
1146 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1151 /* analog input do_cmd */
1152 static int das1800_ai_do_cmd(struct comedi_device *dev,
1153 struct comedi_subdevice *s)
1155 struct das1800_private *devpriv = dev->private;
1157 int control_a, control_c;
1158 struct comedi_async *async = s->async;
1159 const struct comedi_cmd *cmd = &async->cmd;
1163 "no irq assigned for das-1800, cannot do hardware conversions");
1167 /* disable dma on TRIG_WAKE_EOS, or TRIG_RT
1168 * (because dma in handler is unsafe at hard real-time priority) */
1169 if (cmd->flags & (TRIG_WAKE_EOS | TRIG_RT))
1170 devpriv->irq_dma_bits &= ~DMA_ENABLED;
1172 devpriv->irq_dma_bits |= devpriv->dma_bits;
1173 /* interrupt on end of conversion for TRIG_WAKE_EOS */
1174 if (cmd->flags & TRIG_WAKE_EOS) {
1175 /* interrupt fifo not empty */
1176 devpriv->irq_dma_bits &= ~FIMD;
1178 /* interrupt fifo half full */
1179 devpriv->irq_dma_bits |= FIMD;
1181 /* determine how many conversions we need */
1182 if (cmd->stop_src == TRIG_COUNT)
1183 devpriv->count = cmd->stop_arg * cmd->chanlist_len;
1185 das1800_cancel(dev, s);
1187 /* determine proper bits for control registers */
1188 control_a = control_a_bits(cmd);
1189 control_c = control_c_bits(cmd);
1191 /* setup card and start */
1192 program_chanlist(dev, cmd);
1193 ret = setup_counters(dev, cmd);
1195 comedi_error(dev, "Error setting up counters");
1198 setup_dma(dev, cmd);
1199 outb(control_c, dev->iobase + DAS1800_CONTROL_C);
1200 /* set conversion rate and length for burst mode */
1201 if (control_c & BMDE) {
1202 /* program conversion period with number of microseconds minus 1 */
1203 outb(cmd->convert_arg / 1000 - 1,
1204 dev->iobase + DAS1800_BURST_RATE);
1205 outb(cmd->chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
1207 outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); /* enable irq/dma */
1208 outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */
1209 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
1214 /* read analog input */
1215 static int das1800_ai_rinsn(struct comedi_device *dev,
1216 struct comedi_subdevice *s,
1217 struct comedi_insn *insn, unsigned int *data)
1219 const struct das1800_board *thisboard = comedi_board(dev);
1221 int chan, range, aref, chan_range;
1225 unsigned long irq_flags;
1227 /* set up analog reference and unipolar / bipolar mode */
1228 aref = CR_AREF(insn->chanspec);
1230 if (aref != AREF_DIFF)
1232 if (aref == AREF_COMMON)
1234 /* if a unipolar range was selected */
1235 if (CR_RANGE(insn->chanspec) & UNIPOLAR)
1238 outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */
1239 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
1240 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */
1241 outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
1243 chan = CR_CHAN(insn->chanspec);
1244 /* mask of unipolar/bipolar bit from range */
1245 range = CR_RANGE(insn->chanspec) & 0x3;
1246 chan_range = chan | (range << 8);
1247 spin_lock_irqsave(&dev->spinlock, irq_flags);
1248 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
1249 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */
1250 outw(chan_range, dev->iobase + DAS1800_QRAM);
1251 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
1252 outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */
1254 for (n = 0; n < insn->n; n++) {
1255 /* trigger conversion */
1256 outb(0, dev->iobase + DAS1800_FIFO);
1257 for (i = 0; i < timeout; i++) {
1258 if (inb(dev->iobase + DAS1800_STATUS) & FNE)
1262 comedi_error(dev, "timeout");
1266 dpnt = inw(dev->iobase + DAS1800_FIFO);
1267 /* shift data to offset binary for bipolar ranges */
1268 if ((conv_flags & UB) == 0)
1269 dpnt += 1 << (thisboard->resolution - 1);
1273 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1278 /* writes to an analog output channel */
1279 static int das1800_ao_winsn(struct comedi_device *dev,
1280 struct comedi_subdevice *s,
1281 struct comedi_insn *insn, unsigned int *data)
1283 const struct das1800_board *thisboard = comedi_board(dev);
1284 struct das1800_private *devpriv = dev->private;
1285 int chan = CR_CHAN(insn->chanspec);
1286 /* int range = CR_RANGE(insn->chanspec); */
1287 int update_chan = thisboard->ao_n_chan - 1;
1289 unsigned long irq_flags;
1291 /* card expects two's complement data */
1292 output = data[0] - (1 << (thisboard->resolution - 1));
1293 /* if the write is to the 'update' channel, we need to remember its value */
1294 if (chan == update_chan)
1295 devpriv->ao_update_bits = output;
1296 /* write to channel */
1297 spin_lock_irqsave(&dev->spinlock, irq_flags);
1298 outb(DAC(chan), dev->iobase + DAS1800_SELECT); /* select dac channel for baseAddress + 0x0 */
1299 outw(output, dev->iobase + DAS1800_DAC);
1300 /* now we need to write to 'update' channel to update all dac channels */
1301 if (chan != update_chan) {
1302 outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); /* select 'update' channel for baseAddress + 0x0 */
1303 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
1305 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1310 /* reads from digital input channels */
1311 static int das1800_di_rbits(struct comedi_device *dev,
1312 struct comedi_subdevice *s,
1313 struct comedi_insn *insn, unsigned int *data)
1316 data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf;
1322 /* writes to digital output channels */
1323 static int das1800_do_wbits(struct comedi_device *dev,
1324 struct comedi_subdevice *s,
1325 struct comedi_insn *insn, unsigned int *data)
1327 struct das1800_private *devpriv = dev->private;
1330 /* only set bits that have been masked */
1331 data[0] &= (1 << s->n_chan) - 1;
1332 wbits = devpriv->do_bits;
1334 wbits |= data[0] & data[1];
1335 devpriv->do_bits = wbits;
1337 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
1339 data[1] = devpriv->do_bits;
1344 static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
1347 struct das1800_private *devpriv = dev->private;
1348 unsigned long flags;
1350 /* need an irq to do dma */
1351 if (dev->irq && dma0) {
1352 /* encode dma0 and dma1 into 2 digit hexadecimal for switch */
1353 switch ((dma0 & 0x7) | (dma1 << 4)) {
1354 case 0x5: /* dma0 == 5 */
1355 devpriv->dma_bits |= DMA_CH5;
1357 case 0x6: /* dma0 == 6 */
1358 devpriv->dma_bits |= DMA_CH6;
1360 case 0x7: /* dma0 == 7 */
1361 devpriv->dma_bits |= DMA_CH7;
1363 case 0x65: /* dma0 == 5, dma1 == 6 */
1364 devpriv->dma_bits |= DMA_CH5_CH6;
1366 case 0x76: /* dma0 == 6, dma1 == 7 */
1367 devpriv->dma_bits |= DMA_CH6_CH7;
1369 case 0x57: /* dma0 == 7, dma1 == 5 */
1370 devpriv->dma_bits |= DMA_CH7_CH5;
1373 dev_err(dev->class_dev,
1374 "only supports dma channels 5 through 7\n");
1375 dev_err(dev->class_dev,
1376 "Dual dma only allows the following combinations:\n");
1377 dev_err(dev->class_dev,
1378 "dma 5,6 / 6,7 / or 7,5\n");
1382 if (request_dma(dma0, dev->driver->driver_name)) {
1383 dev_err(dev->class_dev,
1384 "failed to allocate dma channel %i\n", dma0);
1387 devpriv->dma0 = dma0;
1388 devpriv->dma_current = dma0;
1390 if (request_dma(dma1, dev->driver->driver_name)) {
1391 dev_err(dev->class_dev,
1392 "failed to allocate dma channel %i\n",
1396 devpriv->dma1 = dma1;
1398 devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
1399 if (devpriv->ai_buf0 == NULL)
1401 devpriv->dma_current_buf = devpriv->ai_buf0;
1404 kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
1405 if (devpriv->ai_buf1 == NULL)
1408 flags = claim_dma_lock();
1409 disable_dma(devpriv->dma0);
1410 set_dma_mode(devpriv->dma0, DMA_MODE_READ);
1412 disable_dma(devpriv->dma1);
1413 set_dma_mode(devpriv->dma1, DMA_MODE_READ);
1415 release_dma_lock(flags);
1420 static int das1800_probe(struct comedi_device *dev)
1425 id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */
1426 board = ((struct das1800_board *)dev->board_ptr) - das1800_boards;
1430 if (board == das1801st_da || board == das1802st_da ||
1431 board == das1701st_da || board == das1702st_da) {
1432 dev_dbg(dev->class_dev, "Board model: %s\n",
1433 das1800_boards[board].name);
1437 (" Board model (probed, not recommended): das-1800st-da series\n");
1441 if (board == das1802hr_da || board == das1702hr_da) {
1442 dev_dbg(dev->class_dev, "Board model: %s\n",
1443 das1800_boards[board].name);
1447 (" Board model (probed, not recommended): das-1802hr-da\n");
1451 if (board == das1801ao || board == das1802ao ||
1452 board == das1701ao || board == das1702ao) {
1453 dev_dbg(dev->class_dev, "Board model: %s\n",
1454 das1800_boards[board].name);
1458 (" Board model (probed, not recommended): das-1800ao series\n");
1462 if (board == das1802hr || board == das1702hr) {
1463 dev_dbg(dev->class_dev, "Board model: %s\n",
1464 das1800_boards[board].name);
1468 (" Board model (probed, not recommended): das-1802hr\n");
1472 if (board == das1801st || board == das1802st ||
1473 board == das1701st || board == das1702st) {
1474 dev_dbg(dev->class_dev, "Board model: %s\n",
1475 das1800_boards[board].name);
1479 (" Board model (probed, not recommended): das-1800st series\n");
1483 if (board == das1801hc || board == das1802hc) {
1484 dev_dbg(dev->class_dev, "Board model: %s\n",
1485 das1800_boards[board].name);
1489 (" Board model (probed, not recommended): das-1800hc series\n");
1494 (" Board model: probe returned 0x%x (unknown, please report)\n",
1502 static int das1800_attach(struct comedi_device *dev,
1503 struct comedi_devconfig *it)
1505 const struct das1800_board *thisboard = comedi_board(dev);
1506 struct das1800_private *devpriv;
1507 struct comedi_subdevice *s;
1508 unsigned int irq = it->options[1];
1509 unsigned int dma0 = it->options[2];
1510 unsigned int dma1 = it->options[3];
1514 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1518 ret = comedi_request_region(dev, it->options[0], DAS1800_SIZE);
1522 board = das1800_probe(dev);
1524 dev_err(dev->class_dev, "unable to determine board type\n");
1528 dev->board_ptr = das1800_boards + board;
1529 thisboard = comedi_board(dev);
1530 dev->board_name = thisboard->name;
1532 /* if it is an 'ao' board with fancy analog out then we need extra io ports */
1533 if (thisboard->ao_ability == 2) {
1534 unsigned long iobase2 = dev->iobase + IOBASE2;
1536 ret = __comedi_request_region(dev, iobase2, DAS1800_SIZE);
1539 devpriv->iobase2 = iobase2;
1544 if (request_irq(irq, das1800_interrupt, 0,
1545 dev->driver->driver_name, dev)) {
1546 dev_dbg(dev->class_dev, "unable to allocate irq %u\n",
1553 /* set bits that tell card which irq to use */
1558 devpriv->irq_dma_bits |= 0x8;
1561 devpriv->irq_dma_bits |= 0x10;
1564 devpriv->irq_dma_bits |= 0x18;
1567 devpriv->irq_dma_bits |= 0x28;
1570 devpriv->irq_dma_bits |= 0x30;
1573 devpriv->irq_dma_bits |= 0x38;
1576 dev_err(dev->class_dev, "irq out of range\n");
1581 ret = das1800_init_dma(dev, dma0, dma1);
1585 if (devpriv->ai_buf0 == NULL) {
1587 kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL);
1588 if (devpriv->ai_buf0 == NULL)
1592 ret = comedi_alloc_subdevices(dev, 4);
1596 /* analog input subdevice */
1597 s = &dev->subdevices[0];
1598 dev->read_subdev = s;
1599 s->type = COMEDI_SUBD_AI;
1600 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ;
1601 if (thisboard->common)
1602 s->subdev_flags |= SDF_COMMON;
1603 s->n_chan = thisboard->qram_len;
1604 s->len_chanlist = thisboard->qram_len;
1605 s->maxdata = (1 << thisboard->resolution) - 1;
1606 s->range_table = thisboard->range_ai;
1607 s->do_cmd = das1800_ai_do_cmd;
1608 s->do_cmdtest = das1800_ai_do_cmdtest;
1609 s->insn_read = das1800_ai_rinsn;
1610 s->poll = das1800_ai_poll;
1611 s->cancel = das1800_cancel;
1614 s = &dev->subdevices[1];
1615 if (thisboard->ao_ability == 1) {
1616 s->type = COMEDI_SUBD_AO;
1617 s->subdev_flags = SDF_WRITABLE;
1618 s->n_chan = thisboard->ao_n_chan;
1619 s->maxdata = (1 << thisboard->resolution) - 1;
1620 s->range_table = &range_bipolar10;
1621 s->insn_write = das1800_ao_winsn;
1623 s->type = COMEDI_SUBD_UNUSED;
1627 s = &dev->subdevices[2];
1628 s->type = COMEDI_SUBD_DI;
1629 s->subdev_flags = SDF_READABLE;
1632 s->range_table = &range_digital;
1633 s->insn_bits = das1800_di_rbits;
1636 s = &dev->subdevices[3];
1637 s->type = COMEDI_SUBD_DO;
1638 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1639 s->n_chan = thisboard->do_n_chan;
1641 s->range_table = &range_digital;
1642 s->insn_bits = das1800_do_wbits;
1644 das1800_cancel(dev, dev->read_subdev);
1646 /* initialize digital out channels */
1647 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
1649 /* initialize analog out channels */
1650 if (thisboard->ao_ability == 1) {
1651 /* select 'update' dac channel for baseAddress + 0x0 */
1652 outb(DAC(thisboard->ao_n_chan - 1),
1653 dev->iobase + DAS1800_SELECT);
1654 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
1660 static void das1800_detach(struct comedi_device *dev)
1662 struct das1800_private *devpriv = dev->private;
1666 free_dma(devpriv->dma0);
1668 free_dma(devpriv->dma1);
1669 kfree(devpriv->ai_buf0);
1670 kfree(devpriv->ai_buf1);
1671 if (devpriv->iobase2)
1672 release_region(devpriv->iobase2, DAS1800_SIZE);
1674 comedi_legacy_detach(dev);
1677 static struct comedi_driver das1800_driver = {
1678 .driver_name = "das1800",
1679 .module = THIS_MODULE,
1680 .attach = das1800_attach,
1681 .detach = das1800_detach,
1682 .num_names = ARRAY_SIZE(das1800_boards),
1683 .board_name = &das1800_boards[0].name,
1684 .offset = sizeof(struct das1800_board),
1686 module_comedi_driver(das1800_driver);
1688 MODULE_AUTHOR("Comedi http://www.comedi.org");
1689 MODULE_DESCRIPTION("Comedi low-level driver");
1690 MODULE_LICENSE("GPL");