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.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 ************************************************************************
27 Description: Keithley Metrabyte DAS1800 (& compatibles)
28 Author: Frank Mori Hess <fmhess@users.sourceforge.net>
29 Devices: [Keithley Metrabyte] DAS-1701ST (das-1701st),
30 DAS-1701ST-DA (das-1701st-da), DAS-1701/AO (das-1701ao),
31 DAS-1702ST (das-1702st), DAS-1702ST-DA (das-1702st-da),
32 DAS-1702HR (das-1702hr), DAS-1702HR-DA (das-1702hr-da),
33 DAS-1702/AO (das-1702ao), DAS-1801ST (das-1801st),
34 DAS-1801ST-DA (das-1801st-da), DAS-1801HC (das-1801hc),
35 DAS-1801AO (das-1801ao), DAS-1802ST (das-1802st),
36 DAS-1802ST-DA (das-1802st-da), DAS-1802HR (das-1802hr),
37 DAS-1802HR-DA (das-1802hr-da), DAS-1802HC (das-1802hc),
38 DAS-1802AO (das-1802ao)
41 The waveform analog output on the 'ao' cards is not supported.
42 If you need it, send me (Frank Hess) an email.
44 Configuration options:
45 [0] - I/O port base address
46 [1] - IRQ (optional, required for timed or externally triggered conversions)
47 [2] - DMA0 (optional, requires irq)
48 [3] - DMA1 (optional, requires irq and dma0)
52 This driver supports the following Keithley boards:
75 [1] - irq (optional, required for timed or externally triggered conversions)
76 [2] - dma0 (optional, requires irq)
77 [3] - dma1 (optional, requires irq and dma0)
79 irq can be omitted, although the cmd interface will not work without it.
81 analog input cmd triggers supported:
82 start_src: TRIG_NOW | TRIG_EXT
83 scan_begin_src: TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT
84 scan_end_src: TRIG_COUNT
85 convert_src: TRIG_TIMER | TRIG_EXT (TRIG_EXT requires scan_begin_src == TRIG_FOLLOW)
86 stop_src: TRIG_COUNT | TRIG_EXT | TRIG_NONE
88 scan_begin_src triggers TRIG_TIMER and TRIG_EXT use the card's
89 'burst mode' which limits the valid conversion time to 64 microseconds
90 (convert_arg <= 64000). This limitation does not apply if scan_begin_src
94 Only the DAS-1801ST has been tested by me.
95 Unipolar and bipolar ranges cannot be mixed in the channel/gain list.
98 Make it automatically allocate irq and dma channels if they are not specified
99 Add support for analog out on 'ao' cards
100 read insn for analog out
103 #include <linux/interrupt.h>
104 #include <linux/slab.h>
105 #include <linux/io.h>
106 #include "../comedidev.h"
108 #include <linux/ioport.h>
112 #include "comedi_fc.h"
115 #define DAS1800_SIZE 16 /* uses 16 io addresses */
116 #define FIFO_SIZE 1024 /* 1024 sample fifo */
117 #define TIMER_BASE 200 /* 5 Mhz master clock */
118 #define UNIPOLAR 0x4 /* bit that determines whether input range is uni/bipolar */
119 #define DMA_BUF_SIZE 0x1ff00 /* size in bytes of dma buffers */
121 /* Registers for the das1800 */
122 #define DAS1800_FIFO 0x0
123 #define DAS1800_QRAM 0x0
124 #define DAS1800_DAC 0x0
125 #define DAS1800_SELECT 0x2
128 #define DAC(a) (0x2 + a)
129 #define DAS1800_DIGITAL 0x3
130 #define DAS1800_CONTROL_A 0x4
137 #define DAS1800_CONTROL_B 0x5
141 #define DMA_CH5_CH6 0x5
142 #define DMA_CH6_CH7 0x6
143 #define DMA_CH7_CH5 0x7
144 #define DMA_ENABLED 0x3 /* mask used to determine if dma is enabled */
153 #define DAS1800_CONTROL_C 0X6
161 #define DAS1800_STATUS 0x7
162 /* bits that prevent interrupt status bits (and CVEN) from being cleared on write */
163 #define CLEAR_INTR_MASK (CVEN_MASK | 0x1f)
170 #define CVEN_MASK 0x40 /* masks CVEN on write */
172 #define DAS1800_BURST_LENGTH 0x8
173 #define DAS1800_BURST_RATE 0x9
174 #define DAS1800_QRAM_ADDRESS 0xa
175 #define DAS1800_COUNTER 0xc
177 #define IOBASE2 0x400 /* offset of additional ioports used on 'ao' cards */
180 das1701st, das1701st_da, das1702st, das1702st_da, das1702hr,
182 das1701ao, das1702ao, das1801st, das1801st_da, das1802st, das1802st_da,
183 das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao
186 /* analog input ranges */
187 static const struct comedi_lrange range_ai_das1801 = {
201 static const struct comedi_lrange range_ai_das1802 = {
215 struct das1800_board {
217 int ai_speed; /* max conversion period in nanoseconds */
218 int resolution; /* bits of ai resolution */
219 int qram_len; /* length of card's channel / gain queue */
220 int common; /* supports AREF_COMMON flag */
221 int do_n_chan; /* number of digital output channels */
222 int ao_ability; /* 0 == no analog out, 1 == basic analog out, 2 == waveform analog out */
223 int ao_n_chan; /* number of analog out channels */
224 const struct comedi_lrange *range_ai; /* available input ranges */
227 /* Warning: the maximum conversion speeds listed below are
228 * not always achievable depending on board setup (see
231 static const struct das1800_board das1800_boards[] = {
233 .name = "das-1701st",
241 .range_ai = &range_ai_das1801,
244 .name = "das-1701st-da",
252 .range_ai = &range_ai_das1801,
255 .name = "das-1702st",
263 .range_ai = &range_ai_das1802,
266 .name = "das-1702st-da",
274 .range_ai = &range_ai_das1802,
277 .name = "das-1702hr",
285 .range_ai = &range_ai_das1802,
288 .name = "das-1702hr-da",
296 .range_ai = &range_ai_das1802,
299 .name = "das-1701ao",
307 .range_ai = &range_ai_das1801,
310 .name = "das-1702ao",
318 .range_ai = &range_ai_das1802,
321 .name = "das-1801st",
329 .range_ai = &range_ai_das1801,
332 .name = "das-1801st-da",
340 .range_ai = &range_ai_das1801,
343 .name = "das-1802st",
351 .range_ai = &range_ai_das1802,
354 .name = "das-1802st-da",
362 .range_ai = &range_ai_das1802,
365 .name = "das-1802hr",
373 .range_ai = &range_ai_das1802,
376 .name = "das-1802hr-da",
384 .range_ai = &range_ai_das1802,
387 .name = "das-1801hc",
395 .range_ai = &range_ai_das1801,
398 .name = "das-1802hc",
406 .range_ai = &range_ai_das1802,
409 .name = "das-1801ao",
417 .range_ai = &range_ai_das1801,
420 .name = "das-1802ao",
428 .range_ai = &range_ai_das1802,
433 * Useful for shorthand access to the particular board structure
435 #define thisboard ((const struct das1800_board *)dev->board_ptr)
437 struct das1800_private {
438 volatile unsigned int count; /* number of data points left to be taken */
439 unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */
440 unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */
441 int do_bits; /* digital output bits */
442 int irq_dma_bits; /* bits for control register b */
443 /* dma bits for control register b, stored so that dma can be
444 * turned on and off */
446 unsigned int dma0; /* dma channels used */
448 volatile unsigned int dma_current; /* dma channel currently in use */
449 uint16_t *ai_buf0; /* pointers to dma buffers */
451 uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */
452 unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */
453 unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */
454 short ao_update_bits; /* remembers the last write to the 'update' dac */
457 /* analog out range for boards with basic analog out */
458 static const struct comedi_lrange range_ao_1 = {
465 /* analog out range for 'ao' boards */
467 static const struct comedi_lrange range_ao_2 = {
476 static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev,
479 sample += 1 << (thisboard->resolution - 1);
483 static void munge_data(struct comedi_device *dev, uint16_t * array,
484 unsigned int num_elements)
489 /* see if card is using a unipolar or bipolar range so we can munge data correctly */
490 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
492 /* convert to unsigned type if we are in a bipolar mode */
494 for (i = 0; i < num_elements; i++)
495 array[i] = munge_bipolar_sample(dev, array[i]);
499 static void das1800_handle_fifo_half_full(struct comedi_device *dev,
500 struct comedi_subdevice *s)
502 struct das1800_private *devpriv = dev->private;
503 int numPoints = 0; /* number of points to read */
504 struct comedi_cmd *cmd = &s->async->cmd;
506 numPoints = FIFO_SIZE / 2;
507 /* if we only need some of the points */
508 if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints)
509 numPoints = devpriv->count;
510 insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints);
511 munge_data(dev, devpriv->ai_buf0, numPoints);
512 cfc_write_array_to_buffer(s, devpriv->ai_buf0,
513 numPoints * sizeof(devpriv->ai_buf0[0]));
514 if (cmd->stop_src == TRIG_COUNT)
515 devpriv->count -= numPoints;
519 static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
520 struct comedi_subdevice *s)
522 struct das1800_private *devpriv = dev->private;
525 struct comedi_cmd *cmd = &s->async->cmd;
527 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
529 while (inb(dev->iobase + DAS1800_STATUS) & FNE) {
530 if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
532 dpnt = inw(dev->iobase + DAS1800_FIFO);
533 /* convert to unsigned type if we are in a bipolar mode */
536 dpnt = munge_bipolar_sample(dev, dpnt);
537 cfc_write_to_buffer(s, dpnt);
538 if (cmd->stop_src == TRIG_COUNT)
545 /* Utility function used by das1800_flush_dma() and das1800_handle_dma().
546 * Assumes dma lock is held */
547 static void das1800_flush_dma_channel(struct comedi_device *dev,
548 struct comedi_subdevice *s,
549 unsigned int channel, uint16_t *buffer)
551 struct das1800_private *devpriv = dev->private;
552 unsigned int num_bytes, num_samples;
553 struct comedi_cmd *cmd = &s->async->cmd;
555 disable_dma(channel);
557 /* clear flip-flop to make sure 2-byte registers
558 * get set correctly */
559 clear_dma_ff(channel);
561 /* figure out how many points to read */
562 num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel);
563 num_samples = num_bytes / sizeof(short);
565 /* if we only need some of the points */
566 if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples)
567 num_samples = devpriv->count;
569 munge_data(dev, buffer, num_samples);
570 cfc_write_array_to_buffer(s, buffer, num_bytes);
571 if (s->async->cmd.stop_src == TRIG_COUNT)
572 devpriv->count -= num_samples;
577 /* flushes remaining data from board when external trigger has stopped acquisition
578 * and we are using dma transfers */
579 static void das1800_flush_dma(struct comedi_device *dev,
580 struct comedi_subdevice *s)
582 struct das1800_private *devpriv = dev->private;
584 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
586 flags = claim_dma_lock();
587 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
588 devpriv->dma_current_buf);
591 /* switch to other channel and flush it */
592 if (devpriv->dma_current == devpriv->dma0) {
593 devpriv->dma_current = devpriv->dma1;
594 devpriv->dma_current_buf = devpriv->ai_buf1;
596 devpriv->dma_current = devpriv->dma0;
597 devpriv->dma_current_buf = devpriv->ai_buf0;
599 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
600 devpriv->dma_current_buf);
603 release_dma_lock(flags);
605 /* get any remaining samples in fifo */
606 das1800_handle_fifo_not_empty(dev, s);
611 static void das1800_handle_dma(struct comedi_device *dev,
612 struct comedi_subdevice *s, unsigned int status)
614 struct das1800_private *devpriv = dev->private;
616 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
618 flags = claim_dma_lock();
619 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
620 devpriv->dma_current_buf);
621 /* re-enable dma channel */
622 set_dma_addr(devpriv->dma_current,
623 virt_to_bus(devpriv->dma_current_buf));
624 set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size);
625 enable_dma(devpriv->dma_current);
626 release_dma_lock(flags);
628 if (status & DMATC) {
629 /* clear DMATC interrupt bit */
630 outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
631 /* switch dma channels for next time, if appropriate */
633 /* read data from the other channel next time */
634 if (devpriv->dma_current == devpriv->dma0) {
635 devpriv->dma_current = devpriv->dma1;
636 devpriv->dma_current_buf = devpriv->ai_buf1;
638 devpriv->dma_current = devpriv->dma0;
639 devpriv->dma_current_buf = devpriv->ai_buf0;
647 static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
649 struct das1800_private *devpriv = dev->private;
651 outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */
652 outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */
653 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */
655 disable_dma(devpriv->dma0);
657 disable_dma(devpriv->dma1);
661 /* the guts of the interrupt handler, that is shared with das1800_ai_poll */
662 static void das1800_ai_handler(struct comedi_device *dev)
664 struct das1800_private *devpriv = dev->private;
665 struct comedi_subdevice *s = &dev->subdevices[0];
666 struct comedi_async *async = s->async;
667 struct comedi_cmd *cmd = &async->cmd;
668 unsigned int status = inb(dev->iobase + DAS1800_STATUS);
671 /* select adc for base address + 0 */
672 outb(ADC, dev->iobase + DAS1800_SELECT);
673 /* dma buffer full */
674 if (devpriv->irq_dma_bits & DMA_ENABLED) {
675 /* look for data from dma transfer even if dma terminal count hasn't happened yet */
676 das1800_handle_dma(dev, s, status);
677 } else if (status & FHF) { /* if fifo half full */
678 das1800_handle_fifo_half_full(dev, s);
679 } else if (status & FNE) { /* if fifo not empty */
680 das1800_handle_fifo_not_empty(dev, s);
683 async->events |= COMEDI_CB_BLOCK;
684 /* if the card's fifo has overflowed */
686 /* clear OVF interrupt bit */
687 outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
688 comedi_error(dev, "DAS1800 FIFO overflow");
689 das1800_cancel(dev, s);
690 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
691 comedi_event(dev, s);
694 /* stop taking data if appropriate */
695 /* stop_src TRIG_EXT */
696 if (status & CT0TC) {
697 /* clear CT0TC interrupt bit */
698 outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
699 /* make sure we get all remaining data from board before quitting */
700 if (devpriv->irq_dma_bits & DMA_ENABLED)
701 das1800_flush_dma(dev, s);
703 das1800_handle_fifo_not_empty(dev, s);
704 das1800_cancel(dev, s); /* disable hardware conversions */
705 async->events |= COMEDI_CB_EOA;
706 } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { /* stop_src TRIG_COUNT */
707 das1800_cancel(dev, s); /* disable hardware conversions */
708 async->events |= COMEDI_CB_EOA;
711 comedi_event(dev, s);
716 static int das1800_ai_poll(struct comedi_device *dev,
717 struct comedi_subdevice *s)
721 /* prevent race with interrupt handler */
722 spin_lock_irqsave(&dev->spinlock, flags);
723 das1800_ai_handler(dev);
724 spin_unlock_irqrestore(&dev->spinlock, flags);
726 return s->async->buf_write_count - s->async->buf_read_count;
729 static irqreturn_t das1800_interrupt(int irq, void *d)
731 struct comedi_device *dev = d;
734 if (dev->attached == 0) {
735 comedi_error(dev, "premature interrupt");
739 /* Prevent race with das1800_ai_poll() on multi processor systems.
740 * Also protects indirect addressing in das1800_ai_handler */
741 spin_lock(&dev->spinlock);
742 status = inb(dev->iobase + DAS1800_STATUS);
744 /* if interrupt was not caused by das-1800 */
745 if (!(status & INT)) {
746 spin_unlock(&dev->spinlock);
749 /* clear the interrupt status bit INT */
750 outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
751 /* handle interrupt */
752 das1800_ai_handler(dev);
754 spin_unlock(&dev->spinlock);
758 /* converts requested conversion timing to timing compatible with
759 * hardware, used only when card is in 'burst mode'
761 static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode)
763 unsigned int micro_sec;
765 /* in burst mode, the maximum conversion time is 64 microseconds */
766 if (convert_arg > 64000)
769 /* the conversion time must be an integral number of microseconds */
770 switch (round_mode) {
771 case TRIG_ROUND_NEAREST:
773 micro_sec = (convert_arg + 500) / 1000;
775 case TRIG_ROUND_DOWN:
776 micro_sec = convert_arg / 1000;
779 micro_sec = (convert_arg - 1) / 1000 + 1;
783 /* return number of nanoseconds */
784 return micro_sec * 1000;
787 /* test analog input cmd */
788 static int das1800_ai_do_cmdtest(struct comedi_device *dev,
789 struct comedi_subdevice *s,
790 struct comedi_cmd *cmd)
792 struct das1800_private *devpriv = dev->private;
794 unsigned int tmp_arg;
798 /* Step 1 : check if triggers are trivially valid */
800 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
801 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
802 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
803 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
804 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
805 err |= cfc_check_trigger_src(&cmd->stop_src,
806 TRIG_COUNT | TRIG_EXT | TRIG_NONE);
811 /* Step 2a : make sure trigger sources are unique */
813 err |= cfc_check_trigger_is_unique(cmd->start_src);
814 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
815 err |= cfc_check_trigger_is_unique(cmd->convert_src);
816 err |= cfc_check_trigger_is_unique(cmd->stop_src);
818 /* Step 2b : and mutually compatible */
820 if (cmd->scan_begin_src != TRIG_FOLLOW &&
821 cmd->convert_src != TRIG_TIMER)
827 /* Step 3: check if arguments are trivially valid */
829 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
831 if (cmd->convert_src == TRIG_TIMER)
832 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
833 thisboard->ai_speed);
835 err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
836 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
838 switch (cmd->stop_src) {
840 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
843 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
852 /* step 4: fix up any arguments */
854 if (cmd->convert_src == TRIG_TIMER) {
855 /* if we are not in burst mode */
856 if (cmd->scan_begin_src == TRIG_FOLLOW) {
857 tmp_arg = cmd->convert_arg;
858 /* calculate counter values that give desired timing */
859 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
860 &(devpriv->divisor1),
861 &(devpriv->divisor2),
864 flags & TRIG_ROUND_MASK);
865 if (tmp_arg != cmd->convert_arg)
868 /* if we are in burst mode */
870 /* check that convert_arg is compatible */
871 tmp_arg = cmd->convert_arg;
873 burst_convert_arg(cmd->convert_arg,
874 cmd->flags & TRIG_ROUND_MASK);
875 if (tmp_arg != cmd->convert_arg)
878 if (cmd->scan_begin_src == TRIG_TIMER) {
879 /* if scans are timed faster than conversion rate allows */
880 if (cmd->convert_arg * cmd->chanlist_len >
881 cmd->scan_begin_arg) {
882 cmd->scan_begin_arg =
887 tmp_arg = cmd->scan_begin_arg;
888 /* calculate counter values that give desired timing */
889 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
899 if (tmp_arg != cmd->scan_begin_arg)
908 /* make sure user is not trying to mix unipolar and bipolar ranges */
910 unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR;
911 for (i = 1; i < cmd->chanlist_len; i++) {
912 if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) {
914 "unipolar and bipolar ranges cannot be mixed in the chanlist");
927 /* returns appropriate bits for control register a, depending on command */
928 static int control_a_bits(const struct comedi_cmd *cmd)
932 control_a = FFEN; /* enable fifo */
933 if (cmd->stop_src == TRIG_EXT)
935 switch (cmd->start_src) {
937 control_a |= TGEN | CGSL;
949 /* returns appropriate bits for control register c, depending on command */
950 static int control_c_bits(const struct comedi_cmd *cmd)
955 /* set clock source to internal or external, select analog reference,
956 * select unipolar / bipolar
958 aref = CR_AREF(cmd->chanlist[0]);
959 control_c = UQEN; /* enable upper qram addresses */
960 if (aref != AREF_DIFF)
962 if (aref == AREF_COMMON)
964 /* if a unipolar range was selected */
965 if (CR_RANGE(cmd->chanlist[0]) & UNIPOLAR)
967 switch (cmd->scan_begin_src) {
968 case TRIG_FOLLOW: /* not in burst mode */
969 switch (cmd->convert_src) {
971 /* trig on cascaded counters */
975 /* trig on falling edge of external trigger */
983 /* burst mode with internal pacer clock */
984 control_c |= BMDE | IPCLK;
987 /* burst mode with external trigger */
988 control_c |= BMDE | XPCLK;
997 /* loads counters with divisor1, divisor2 from private structure */
998 static int das1800_set_frequency(struct comedi_device *dev)
1000 struct das1800_private *devpriv = dev->private;
1003 /* counter 1, mode 2 */
1004 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1,
1007 /* counter 2, mode 2 */
1008 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2,
1017 /* sets up counters */
1018 static int setup_counters(struct comedi_device *dev,
1019 const struct comedi_cmd *cmd)
1021 struct das1800_private *devpriv = dev->private;
1022 unsigned int period;
1024 /* setup cascaded counters for conversion/scan frequency */
1025 switch (cmd->scan_begin_src) {
1026 case TRIG_FOLLOW: /* not in burst mode */
1027 if (cmd->convert_src == TRIG_TIMER) {
1028 /* set conversion frequency */
1029 period = cmd->convert_arg;
1030 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1036 if (das1800_set_frequency(dev) < 0)
1040 case TRIG_TIMER: /* in burst mode */
1041 /* set scan frequency */
1042 period = cmd->scan_begin_arg;
1043 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &devpriv->divisor1,
1044 &devpriv->divisor2, &period,
1045 cmd->flags & TRIG_ROUND_MASK);
1046 if (das1800_set_frequency(dev) < 0)
1053 /* setup counter 0 for 'about triggering' */
1054 if (cmd->stop_src == TRIG_EXT) {
1055 /* load counter 0 in mode 0 */
1056 i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0);
1062 /* utility function that suggests a dma transfer size based on the conversion period 'ns' */
1063 static unsigned int suggest_transfer_size(const struct comedi_cmd *cmd)
1065 unsigned int size = DMA_BUF_SIZE;
1066 static const int sample_size = 2; /* size in bytes of one sample from board */
1067 unsigned int fill_time = 300000000; /* target time in nanoseconds for filling dma buffer */
1068 unsigned int max_size; /* maximum size we will allow for a transfer */
1070 /* make dma buffer fill in 0.3 seconds for timed modes */
1071 switch (cmd->scan_begin_src) {
1072 case TRIG_FOLLOW: /* not in burst mode */
1073 if (cmd->convert_src == TRIG_TIMER)
1074 size = (fill_time / cmd->convert_arg) * sample_size;
1077 size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) *
1081 size = DMA_BUF_SIZE;
1085 /* set a minimum and maximum size allowed */
1086 max_size = DMA_BUF_SIZE;
1087 /* if we are taking limited number of conversions, limit transfer size to that */
1088 if (cmd->stop_src == TRIG_COUNT &&
1089 cmd->stop_arg * cmd->chanlist_len * sample_size < max_size)
1090 max_size = cmd->stop_arg * cmd->chanlist_len * sample_size;
1092 if (size > max_size)
1094 if (size < sample_size)
1101 static void setup_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
1103 struct das1800_private *devpriv = dev->private;
1104 unsigned long lock_flags;
1105 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
1107 if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
1110 /* determine a reasonable dma transfer size */
1111 devpriv->dma_transfer_size = suggest_transfer_size(cmd);
1112 lock_flags = claim_dma_lock();
1113 disable_dma(devpriv->dma0);
1114 /* clear flip-flop to make sure 2-byte registers for
1115 * count and address get set correctly */
1116 clear_dma_ff(devpriv->dma0);
1117 set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0));
1118 /* set appropriate size of transfer */
1119 set_dma_count(devpriv->dma0, devpriv->dma_transfer_size);
1120 devpriv->dma_current = devpriv->dma0;
1121 devpriv->dma_current_buf = devpriv->ai_buf0;
1122 enable_dma(devpriv->dma0);
1123 /* set up dual dma if appropriate */
1125 disable_dma(devpriv->dma1);
1126 /* clear flip-flop to make sure 2-byte registers for
1127 * count and address get set correctly */
1128 clear_dma_ff(devpriv->dma1);
1129 set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1));
1130 /* set appropriate size of transfer */
1131 set_dma_count(devpriv->dma1, devpriv->dma_transfer_size);
1132 enable_dma(devpriv->dma1);
1134 release_dma_lock(lock_flags);
1139 /* programs channel/gain list into card */
1140 static void program_chanlist(struct comedi_device *dev,
1141 const struct comedi_cmd *cmd)
1143 int i, n, chan_range;
1144 unsigned long irq_flags;
1145 const int range_mask = 0x3; /* masks unipolar/bipolar bit off range */
1146 const int range_bitshift = 8;
1148 n = cmd->chanlist_len;
1149 /* spinlock protects indirect addressing */
1150 spin_lock_irqsave(&dev->spinlock, irq_flags);
1151 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
1152 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */
1153 /* make channel / gain list */
1154 for (i = 0; i < n; i++) {
1156 CR_CHAN(cmd->chanlist[i]) |
1157 ((CR_RANGE(cmd->chanlist[i]) & range_mask) <<
1159 outw(chan_range, dev->iobase + DAS1800_QRAM);
1161 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
1162 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1167 /* analog input do_cmd */
1168 static int das1800_ai_do_cmd(struct comedi_device *dev,
1169 struct comedi_subdevice *s)
1171 struct das1800_private *devpriv = dev->private;
1173 int control_a, control_c;
1174 struct comedi_async *async = s->async;
1175 const struct comedi_cmd *cmd = &async->cmd;
1179 "no irq assigned for das-1800, cannot do hardware conversions");
1183 /* disable dma on TRIG_WAKE_EOS, or TRIG_RT
1184 * (because dma in handler is unsafe at hard real-time priority) */
1185 if (cmd->flags & (TRIG_WAKE_EOS | TRIG_RT))
1186 devpriv->irq_dma_bits &= ~DMA_ENABLED;
1188 devpriv->irq_dma_bits |= devpriv->dma_bits;
1189 /* interrupt on end of conversion for TRIG_WAKE_EOS */
1190 if (cmd->flags & TRIG_WAKE_EOS) {
1191 /* interrupt fifo not empty */
1192 devpriv->irq_dma_bits &= ~FIMD;
1194 /* interrupt fifo half full */
1195 devpriv->irq_dma_bits |= FIMD;
1197 /* determine how many conversions we need */
1198 if (cmd->stop_src == TRIG_COUNT)
1199 devpriv->count = cmd->stop_arg * cmd->chanlist_len;
1201 das1800_cancel(dev, s);
1203 /* determine proper bits for control registers */
1204 control_a = control_a_bits(cmd);
1205 control_c = control_c_bits(cmd);
1207 /* setup card and start */
1208 program_chanlist(dev, cmd);
1209 ret = setup_counters(dev, cmd);
1211 comedi_error(dev, "Error setting up counters");
1214 setup_dma(dev, cmd);
1215 outb(control_c, dev->iobase + DAS1800_CONTROL_C);
1216 /* set conversion rate and length for burst mode */
1217 if (control_c & BMDE) {
1218 /* program conversion period with number of microseconds minus 1 */
1219 outb(cmd->convert_arg / 1000 - 1,
1220 dev->iobase + DAS1800_BURST_RATE);
1221 outb(cmd->chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
1223 outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); /* enable irq/dma */
1224 outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */
1225 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
1230 /* read analog input */
1231 static int das1800_ai_rinsn(struct comedi_device *dev,
1232 struct comedi_subdevice *s,
1233 struct comedi_insn *insn, unsigned int *data)
1236 int chan, range, aref, chan_range;
1240 unsigned long irq_flags;
1242 /* set up analog reference and unipolar / bipolar mode */
1243 aref = CR_AREF(insn->chanspec);
1245 if (aref != AREF_DIFF)
1247 if (aref == AREF_COMMON)
1249 /* if a unipolar range was selected */
1250 if (CR_RANGE(insn->chanspec) & UNIPOLAR)
1253 outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */
1254 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
1255 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */
1256 outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
1258 chan = CR_CHAN(insn->chanspec);
1259 /* mask of unipolar/bipolar bit from range */
1260 range = CR_RANGE(insn->chanspec) & 0x3;
1261 chan_range = chan | (range << 8);
1262 spin_lock_irqsave(&dev->spinlock, irq_flags);
1263 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
1264 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */
1265 outw(chan_range, dev->iobase + DAS1800_QRAM);
1266 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
1267 outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */
1269 for (n = 0; n < insn->n; n++) {
1270 /* trigger conversion */
1271 outb(0, dev->iobase + DAS1800_FIFO);
1272 for (i = 0; i < timeout; i++) {
1273 if (inb(dev->iobase + DAS1800_STATUS) & FNE)
1277 comedi_error(dev, "timeout");
1281 dpnt = inw(dev->iobase + DAS1800_FIFO);
1282 /* shift data to offset binary for bipolar ranges */
1283 if ((conv_flags & UB) == 0)
1284 dpnt += 1 << (thisboard->resolution - 1);
1288 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1293 /* writes to an analog output channel */
1294 static int das1800_ao_winsn(struct comedi_device *dev,
1295 struct comedi_subdevice *s,
1296 struct comedi_insn *insn, unsigned int *data)
1298 struct das1800_private *devpriv = dev->private;
1299 int chan = CR_CHAN(insn->chanspec);
1300 /* int range = CR_RANGE(insn->chanspec); */
1301 int update_chan = thisboard->ao_n_chan - 1;
1303 unsigned long irq_flags;
1305 /* card expects two's complement data */
1306 output = data[0] - (1 << (thisboard->resolution - 1));
1307 /* if the write is to the 'update' channel, we need to remember its value */
1308 if (chan == update_chan)
1309 devpriv->ao_update_bits = output;
1310 /* write to channel */
1311 spin_lock_irqsave(&dev->spinlock, irq_flags);
1312 outb(DAC(chan), dev->iobase + DAS1800_SELECT); /* select dac channel for baseAddress + 0x0 */
1313 outw(output, dev->iobase + DAS1800_DAC);
1314 /* now we need to write to 'update' channel to update all dac channels */
1315 if (chan != update_chan) {
1316 outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); /* select 'update' channel for baseAddress + 0x0 */
1317 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
1319 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1324 /* reads from digital input channels */
1325 static int das1800_di_rbits(struct comedi_device *dev,
1326 struct comedi_subdevice *s,
1327 struct comedi_insn *insn, unsigned int *data)
1330 data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf;
1336 /* writes to digital output channels */
1337 static int das1800_do_wbits(struct comedi_device *dev,
1338 struct comedi_subdevice *s,
1339 struct comedi_insn *insn, unsigned int *data)
1341 struct das1800_private *devpriv = dev->private;
1344 /* only set bits that have been masked */
1345 data[0] &= (1 << s->n_chan) - 1;
1346 wbits = devpriv->do_bits;
1348 wbits |= data[0] & data[1];
1349 devpriv->do_bits = wbits;
1351 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
1353 data[1] = devpriv->do_bits;
1358 static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
1361 struct das1800_private *devpriv = dev->private;
1362 unsigned long flags;
1364 /* need an irq to do dma */
1365 if (dev->irq && dma0) {
1366 /* encode dma0 and dma1 into 2 digit hexadecimal for switch */
1367 switch ((dma0 & 0x7) | (dma1 << 4)) {
1368 case 0x5: /* dma0 == 5 */
1369 devpriv->dma_bits |= DMA_CH5;
1371 case 0x6: /* dma0 == 6 */
1372 devpriv->dma_bits |= DMA_CH6;
1374 case 0x7: /* dma0 == 7 */
1375 devpriv->dma_bits |= DMA_CH7;
1377 case 0x65: /* dma0 == 5, dma1 == 6 */
1378 devpriv->dma_bits |= DMA_CH5_CH6;
1380 case 0x76: /* dma0 == 6, dma1 == 7 */
1381 devpriv->dma_bits |= DMA_CH6_CH7;
1383 case 0x57: /* dma0 == 7, dma1 == 5 */
1384 devpriv->dma_bits |= DMA_CH7_CH5;
1387 dev_err(dev->class_dev,
1388 "only supports dma channels 5 through 7\n");
1389 dev_err(dev->class_dev,
1390 "Dual dma only allows the following combinations:\n");
1391 dev_err(dev->class_dev,
1392 "dma 5,6 / 6,7 / or 7,5\n");
1396 if (request_dma(dma0, dev->driver->driver_name)) {
1397 dev_err(dev->class_dev,
1398 "failed to allocate dma channel %i\n", dma0);
1401 devpriv->dma0 = dma0;
1402 devpriv->dma_current = dma0;
1404 if (request_dma(dma1, dev->driver->driver_name)) {
1405 dev_err(dev->class_dev,
1406 "failed to allocate dma channel %i\n",
1410 devpriv->dma1 = dma1;
1412 devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
1413 if (devpriv->ai_buf0 == NULL)
1415 devpriv->dma_current_buf = devpriv->ai_buf0;
1418 kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
1419 if (devpriv->ai_buf1 == NULL)
1422 flags = claim_dma_lock();
1423 disable_dma(devpriv->dma0);
1424 set_dma_mode(devpriv->dma0, DMA_MODE_READ);
1426 disable_dma(devpriv->dma1);
1427 set_dma_mode(devpriv->dma1, DMA_MODE_READ);
1429 release_dma_lock(flags);
1434 static int das1800_probe(struct comedi_device *dev)
1439 id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */
1440 board = ((struct das1800_board *)dev->board_ptr) - das1800_boards;
1444 if (board == das1801st_da || board == das1802st_da ||
1445 board == das1701st_da || board == das1702st_da) {
1446 dev_dbg(dev->class_dev, "Board model: %s\n",
1447 das1800_boards[board].name);
1451 (" Board model (probed, not recommended): das-1800st-da series\n");
1455 if (board == das1802hr_da || board == das1702hr_da) {
1456 dev_dbg(dev->class_dev, "Board model: %s\n",
1457 das1800_boards[board].name);
1461 (" Board model (probed, not recommended): das-1802hr-da\n");
1465 if (board == das1801ao || board == das1802ao ||
1466 board == das1701ao || board == das1702ao) {
1467 dev_dbg(dev->class_dev, "Board model: %s\n",
1468 das1800_boards[board].name);
1472 (" Board model (probed, not recommended): das-1800ao series\n");
1476 if (board == das1802hr || board == das1702hr) {
1477 dev_dbg(dev->class_dev, "Board model: %s\n",
1478 das1800_boards[board].name);
1482 (" Board model (probed, not recommended): das-1802hr\n");
1486 if (board == das1801st || board == das1802st ||
1487 board == das1701st || board == das1702st) {
1488 dev_dbg(dev->class_dev, "Board model: %s\n",
1489 das1800_boards[board].name);
1493 (" Board model (probed, not recommended): das-1800st series\n");
1497 if (board == das1801hc || board == das1802hc) {
1498 dev_dbg(dev->class_dev, "Board model: %s\n",
1499 das1800_boards[board].name);
1503 (" Board model (probed, not recommended): das-1800hc series\n");
1508 (" Board model: probe returned 0x%x (unknown, please report)\n",
1516 static int das1800_attach(struct comedi_device *dev,
1517 struct comedi_devconfig *it)
1519 struct das1800_private *devpriv;
1520 struct comedi_subdevice *s;
1521 unsigned long iobase = it->options[0];
1522 unsigned int irq = it->options[1];
1523 unsigned int dma0 = it->options[2];
1524 unsigned int dma1 = it->options[3];
1525 unsigned long iobase2;
1529 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1532 dev->private = devpriv;
1534 printk(KERN_DEBUG "comedi%d: %s: io 0x%lx", dev->minor,
1535 dev->driver->driver_name, iobase);
1537 printk(KERN_CONT ", irq %u", irq);
1539 printk(KERN_CONT ", dma %u", dma0);
1541 printk(KERN_CONT " and %u", dma1);
1544 printk(KERN_CONT "\n");
1547 dev_err(dev->class_dev, "io base address required\n");
1551 /* check if io addresses are available */
1552 if (!request_region(iobase, DAS1800_SIZE, dev->driver->driver_name)) {
1554 (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
1555 iobase, iobase + DAS1800_SIZE - 1);
1558 dev->iobase = iobase;
1560 board = das1800_probe(dev);
1562 dev_err(dev->class_dev, "unable to determine board type\n");
1566 dev->board_ptr = das1800_boards + board;
1567 dev->board_name = thisboard->name;
1569 /* if it is an 'ao' board with fancy analog out then we need extra io ports */
1570 if (thisboard->ao_ability == 2) {
1571 iobase2 = iobase + IOBASE2;
1572 if (!request_region(iobase2, DAS1800_SIZE,
1573 dev->driver->driver_name)) {
1575 (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
1576 iobase2, iobase2 + DAS1800_SIZE - 1);
1579 devpriv->iobase2 = iobase2;
1584 if (request_irq(irq, das1800_interrupt, 0,
1585 dev->driver->driver_name, dev)) {
1586 dev_dbg(dev->class_dev, "unable to allocate irq %u\n",
1593 /* set bits that tell card which irq to use */
1598 devpriv->irq_dma_bits |= 0x8;
1601 devpriv->irq_dma_bits |= 0x10;
1604 devpriv->irq_dma_bits |= 0x18;
1607 devpriv->irq_dma_bits |= 0x28;
1610 devpriv->irq_dma_bits |= 0x30;
1613 devpriv->irq_dma_bits |= 0x38;
1616 dev_err(dev->class_dev, "irq out of range\n");
1621 retval = das1800_init_dma(dev, dma0, dma1);
1625 if (devpriv->ai_buf0 == NULL) {
1627 kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL);
1628 if (devpriv->ai_buf0 == NULL)
1632 retval = comedi_alloc_subdevices(dev, 4);
1636 /* analog input subdevice */
1637 s = &dev->subdevices[0];
1638 dev->read_subdev = s;
1639 s->type = COMEDI_SUBD_AI;
1640 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ;
1641 if (thisboard->common)
1642 s->subdev_flags |= SDF_COMMON;
1643 s->n_chan = thisboard->qram_len;
1644 s->len_chanlist = thisboard->qram_len;
1645 s->maxdata = (1 << thisboard->resolution) - 1;
1646 s->range_table = thisboard->range_ai;
1647 s->do_cmd = das1800_ai_do_cmd;
1648 s->do_cmdtest = das1800_ai_do_cmdtest;
1649 s->insn_read = das1800_ai_rinsn;
1650 s->poll = das1800_ai_poll;
1651 s->cancel = das1800_cancel;
1654 s = &dev->subdevices[1];
1655 if (thisboard->ao_ability == 1) {
1656 s->type = COMEDI_SUBD_AO;
1657 s->subdev_flags = SDF_WRITABLE;
1658 s->n_chan = thisboard->ao_n_chan;
1659 s->maxdata = (1 << thisboard->resolution) - 1;
1660 s->range_table = &range_ao_1;
1661 s->insn_write = das1800_ao_winsn;
1663 s->type = COMEDI_SUBD_UNUSED;
1667 s = &dev->subdevices[2];
1668 s->type = COMEDI_SUBD_DI;
1669 s->subdev_flags = SDF_READABLE;
1672 s->range_table = &range_digital;
1673 s->insn_bits = das1800_di_rbits;
1676 s = &dev->subdevices[3];
1677 s->type = COMEDI_SUBD_DO;
1678 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1679 s->n_chan = thisboard->do_n_chan;
1681 s->range_table = &range_digital;
1682 s->insn_bits = das1800_do_wbits;
1684 das1800_cancel(dev, dev->read_subdev);
1686 /* initialize digital out channels */
1687 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
1689 /* initialize analog out channels */
1690 if (thisboard->ao_ability == 1) {
1691 /* select 'update' dac channel for baseAddress + 0x0 */
1692 outb(DAC(thisboard->ao_n_chan - 1),
1693 dev->iobase + DAS1800_SELECT);
1694 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
1700 static void das1800_detach(struct comedi_device *dev)
1702 struct das1800_private *devpriv = dev->private;
1705 release_region(dev->iobase, DAS1800_SIZE);
1707 free_irq(dev->irq, dev);
1709 if (devpriv->iobase2)
1710 release_region(devpriv->iobase2, DAS1800_SIZE);
1712 free_dma(devpriv->dma0);
1714 free_dma(devpriv->dma1);
1715 kfree(devpriv->ai_buf0);
1716 kfree(devpriv->ai_buf1);
1720 static struct comedi_driver das1800_driver = {
1721 .driver_name = "das1800",
1722 .module = THIS_MODULE,
1723 .attach = das1800_attach,
1724 .detach = das1800_detach,
1725 .num_names = ARRAY_SIZE(das1800_boards),
1726 .board_name = &das1800_boards[0].name,
1727 .offset = sizeof(struct das1800_board),
1729 module_comedi_driver(das1800_driver);
1731 MODULE_AUTHOR("Comedi http://www.comedi.org");
1732 MODULE_DESCRIPTION("Comedi low-level driver");
1733 MODULE_LICENSE("GPL");