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 #define devpriv ((struct das1800_private *)dev->private)
459 /* analog out range for boards with basic analog out */
460 static const struct comedi_lrange range_ao_1 = {
467 /* analog out range for 'ao' boards */
469 static const struct comedi_lrange range_ao_2 = {
478 static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev,
481 sample += 1 << (thisboard->resolution - 1);
485 static void munge_data(struct comedi_device *dev, uint16_t * array,
486 unsigned int num_elements)
491 /* see if card is using a unipolar or bipolar range so we can munge data correctly */
492 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
494 /* convert to unsigned type if we are in a bipolar mode */
496 for (i = 0; i < num_elements; i++)
497 array[i] = munge_bipolar_sample(dev, array[i]);
501 static void das1800_handle_fifo_half_full(struct comedi_device *dev,
502 struct comedi_subdevice *s)
504 int numPoints = 0; /* number of points to read */
505 struct comedi_cmd *cmd = &s->async->cmd;
507 numPoints = FIFO_SIZE / 2;
508 /* if we only need some of the points */
509 if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints)
510 numPoints = devpriv->count;
511 insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints);
512 munge_data(dev, devpriv->ai_buf0, numPoints);
513 cfc_write_array_to_buffer(s, devpriv->ai_buf0,
514 numPoints * sizeof(devpriv->ai_buf0[0]));
515 if (cmd->stop_src == TRIG_COUNT)
516 devpriv->count -= numPoints;
520 static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
521 struct comedi_subdevice *s)
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 unsigned int num_bytes, num_samples;
552 struct comedi_cmd *cmd = &s->async->cmd;
554 disable_dma(channel);
556 /* clear flip-flop to make sure 2-byte registers
557 * get set correctly */
558 clear_dma_ff(channel);
560 /* figure out how many points to read */
561 num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel);
562 num_samples = num_bytes / sizeof(short);
564 /* if we only need some of the points */
565 if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples)
566 num_samples = devpriv->count;
568 munge_data(dev, buffer, num_samples);
569 cfc_write_array_to_buffer(s, buffer, num_bytes);
570 if (s->async->cmd.stop_src == TRIG_COUNT)
571 devpriv->count -= num_samples;
576 /* flushes remaining data from board when external trigger has stopped acquisition
577 * and we are using dma transfers */
578 static void das1800_flush_dma(struct comedi_device *dev,
579 struct comedi_subdevice *s)
582 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
584 flags = claim_dma_lock();
585 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
586 devpriv->dma_current_buf);
589 /* switch to other channel and flush it */
590 if (devpriv->dma_current == devpriv->dma0) {
591 devpriv->dma_current = devpriv->dma1;
592 devpriv->dma_current_buf = devpriv->ai_buf1;
594 devpriv->dma_current = devpriv->dma0;
595 devpriv->dma_current_buf = devpriv->ai_buf0;
597 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
598 devpriv->dma_current_buf);
601 release_dma_lock(flags);
603 /* get any remaining samples in fifo */
604 das1800_handle_fifo_not_empty(dev, s);
609 static void das1800_handle_dma(struct comedi_device *dev,
610 struct comedi_subdevice *s, unsigned int status)
613 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
615 flags = claim_dma_lock();
616 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
617 devpriv->dma_current_buf);
618 /* re-enable dma channel */
619 set_dma_addr(devpriv->dma_current,
620 virt_to_bus(devpriv->dma_current_buf));
621 set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size);
622 enable_dma(devpriv->dma_current);
623 release_dma_lock(flags);
625 if (status & DMATC) {
626 /* clear DMATC interrupt bit */
627 outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
628 /* switch dma channels for next time, if appropriate */
630 /* read data from the other channel next time */
631 if (devpriv->dma_current == devpriv->dma0) {
632 devpriv->dma_current = devpriv->dma1;
633 devpriv->dma_current_buf = devpriv->ai_buf1;
635 devpriv->dma_current = devpriv->dma0;
636 devpriv->dma_current_buf = devpriv->ai_buf0;
644 static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
646 outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */
647 outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */
648 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */
650 disable_dma(devpriv->dma0);
652 disable_dma(devpriv->dma1);
656 /* the guts of the interrupt handler, that is shared with das1800_ai_poll */
657 static void das1800_ai_handler(struct comedi_device *dev)
659 struct comedi_subdevice *s = &dev->subdevices[0];
660 struct comedi_async *async = s->async;
661 struct comedi_cmd *cmd = &async->cmd;
662 unsigned int status = inb(dev->iobase + DAS1800_STATUS);
665 /* select adc for base address + 0 */
666 outb(ADC, dev->iobase + DAS1800_SELECT);
667 /* dma buffer full */
668 if (devpriv->irq_dma_bits & DMA_ENABLED) {
669 /* look for data from dma transfer even if dma terminal count hasn't happened yet */
670 das1800_handle_dma(dev, s, status);
671 } else if (status & FHF) { /* if fifo half full */
672 das1800_handle_fifo_half_full(dev, s);
673 } else if (status & FNE) { /* if fifo not empty */
674 das1800_handle_fifo_not_empty(dev, s);
677 async->events |= COMEDI_CB_BLOCK;
678 /* if the card's fifo has overflowed */
680 /* clear OVF interrupt bit */
681 outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
682 comedi_error(dev, "DAS1800 FIFO overflow");
683 das1800_cancel(dev, s);
684 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
685 comedi_event(dev, s);
688 /* stop taking data if appropriate */
689 /* stop_src TRIG_EXT */
690 if (status & CT0TC) {
691 /* clear CT0TC interrupt bit */
692 outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
693 /* make sure we get all remaining data from board before quitting */
694 if (devpriv->irq_dma_bits & DMA_ENABLED)
695 das1800_flush_dma(dev, s);
697 das1800_handle_fifo_not_empty(dev, s);
698 das1800_cancel(dev, s); /* disable hardware conversions */
699 async->events |= COMEDI_CB_EOA;
700 } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { /* stop_src TRIG_COUNT */
701 das1800_cancel(dev, s); /* disable hardware conversions */
702 async->events |= COMEDI_CB_EOA;
705 comedi_event(dev, s);
710 static int das1800_ai_poll(struct comedi_device *dev,
711 struct comedi_subdevice *s)
715 /* prevent race with interrupt handler */
716 spin_lock_irqsave(&dev->spinlock, flags);
717 das1800_ai_handler(dev);
718 spin_unlock_irqrestore(&dev->spinlock, flags);
720 return s->async->buf_write_count - s->async->buf_read_count;
723 static irqreturn_t das1800_interrupt(int irq, void *d)
725 struct comedi_device *dev = d;
728 if (dev->attached == 0) {
729 comedi_error(dev, "premature interrupt");
733 /* Prevent race with das1800_ai_poll() on multi processor systems.
734 * Also protects indirect addressing in das1800_ai_handler */
735 spin_lock(&dev->spinlock);
736 status = inb(dev->iobase + DAS1800_STATUS);
738 /* if interrupt was not caused by das-1800 */
739 if (!(status & INT)) {
740 spin_unlock(&dev->spinlock);
743 /* clear the interrupt status bit INT */
744 outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
745 /* handle interrupt */
746 das1800_ai_handler(dev);
748 spin_unlock(&dev->spinlock);
752 /* converts requested conversion timing to timing compatible with
753 * hardware, used only when card is in 'burst mode'
755 static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode)
757 unsigned int micro_sec;
759 /* in burst mode, the maximum conversion time is 64 microseconds */
760 if (convert_arg > 64000)
763 /* the conversion time must be an integral number of microseconds */
764 switch (round_mode) {
765 case TRIG_ROUND_NEAREST:
767 micro_sec = (convert_arg + 500) / 1000;
769 case TRIG_ROUND_DOWN:
770 micro_sec = convert_arg / 1000;
773 micro_sec = (convert_arg - 1) / 1000 + 1;
777 /* return number of nanoseconds */
778 return micro_sec * 1000;
781 /* test analog input cmd */
782 static int das1800_ai_do_cmdtest(struct comedi_device *dev,
783 struct comedi_subdevice *s,
784 struct comedi_cmd *cmd)
787 unsigned int tmp_arg;
791 /* Step 1 : check if triggers are trivially valid */
793 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
794 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
795 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
796 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
797 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
798 err |= cfc_check_trigger_src(&cmd->stop_src,
799 TRIG_COUNT | TRIG_EXT | TRIG_NONE);
804 /* Step 2a : make sure trigger sources are unique */
806 err |= cfc_check_trigger_is_unique(cmd->start_src);
807 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
808 err |= cfc_check_trigger_is_unique(cmd->convert_src);
809 err |= cfc_check_trigger_is_unique(cmd->stop_src);
811 /* Step 2b : and mutually compatible */
813 if (cmd->scan_begin_src != TRIG_FOLLOW &&
814 cmd->convert_src != TRIG_TIMER)
820 /* step 3: make sure arguments are trivially compatible */
822 if (cmd->start_arg != 0) {
826 if (cmd->convert_src == TRIG_TIMER) {
827 if (cmd->convert_arg < thisboard->ai_speed) {
828 cmd->convert_arg = thisboard->ai_speed;
832 if (!cmd->chanlist_len) {
833 cmd->chanlist_len = 1;
836 if (cmd->scan_end_arg != cmd->chanlist_len) {
837 cmd->scan_end_arg = cmd->chanlist_len;
841 switch (cmd->stop_src) {
843 if (!cmd->stop_arg) {
849 if (cmd->stop_arg != 0) {
861 /* step 4: fix up any arguments */
863 if (cmd->convert_src == TRIG_TIMER) {
864 /* if we are not in burst mode */
865 if (cmd->scan_begin_src == TRIG_FOLLOW) {
866 tmp_arg = cmd->convert_arg;
867 /* calculate counter values that give desired timing */
868 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
869 &(devpriv->divisor1),
870 &(devpriv->divisor2),
873 flags & TRIG_ROUND_MASK);
874 if (tmp_arg != cmd->convert_arg)
877 /* if we are in burst mode */
879 /* check that convert_arg is compatible */
880 tmp_arg = cmd->convert_arg;
882 burst_convert_arg(cmd->convert_arg,
883 cmd->flags & TRIG_ROUND_MASK);
884 if (tmp_arg != cmd->convert_arg)
887 if (cmd->scan_begin_src == TRIG_TIMER) {
888 /* if scans are timed faster than conversion rate allows */
889 if (cmd->convert_arg * cmd->chanlist_len >
890 cmd->scan_begin_arg) {
891 cmd->scan_begin_arg =
896 tmp_arg = cmd->scan_begin_arg;
897 /* calculate counter values that give desired timing */
898 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
908 if (tmp_arg != cmd->scan_begin_arg)
917 /* make sure user is not trying to mix unipolar and bipolar ranges */
919 unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR;
920 for (i = 1; i < cmd->chanlist_len; i++) {
921 if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) {
923 "unipolar and bipolar ranges cannot be mixed in the chanlist");
936 /* returns appropriate bits for control register a, depending on command */
937 static int control_a_bits(const struct comedi_cmd *cmd)
941 control_a = FFEN; /* enable fifo */
942 if (cmd->stop_src == TRIG_EXT)
944 switch (cmd->start_src) {
946 control_a |= TGEN | CGSL;
958 /* returns appropriate bits for control register c, depending on command */
959 static int control_c_bits(const struct comedi_cmd *cmd)
964 /* set clock source to internal or external, select analog reference,
965 * select unipolar / bipolar
967 aref = CR_AREF(cmd->chanlist[0]);
968 control_c = UQEN; /* enable upper qram addresses */
969 if (aref != AREF_DIFF)
971 if (aref == AREF_COMMON)
973 /* if a unipolar range was selected */
974 if (CR_RANGE(cmd->chanlist[0]) & UNIPOLAR)
976 switch (cmd->scan_begin_src) {
977 case TRIG_FOLLOW: /* not in burst mode */
978 switch (cmd->convert_src) {
980 /* trig on cascaded counters */
984 /* trig on falling edge of external trigger */
992 /* burst mode with internal pacer clock */
993 control_c |= BMDE | IPCLK;
996 /* burst mode with external trigger */
997 control_c |= BMDE | XPCLK;
1006 /* loads counters with divisor1, divisor2 from private structure */
1007 static int das1800_set_frequency(struct comedi_device *dev)
1011 /* counter 1, mode 2 */
1012 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1,
1015 /* counter 2, mode 2 */
1016 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2,
1025 /* sets up counters */
1026 static int setup_counters(struct comedi_device *dev,
1027 const struct comedi_cmd *cmd)
1029 unsigned int period;
1031 /* setup cascaded counters for conversion/scan frequency */
1032 switch (cmd->scan_begin_src) {
1033 case TRIG_FOLLOW: /* not in burst mode */
1034 if (cmd->convert_src == TRIG_TIMER) {
1035 /* set conversion frequency */
1036 period = cmd->convert_arg;
1037 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1043 if (das1800_set_frequency(dev) < 0)
1047 case TRIG_TIMER: /* in burst mode */
1048 /* set scan frequency */
1049 period = cmd->scan_begin_arg;
1050 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &devpriv->divisor1,
1051 &devpriv->divisor2, &period,
1052 cmd->flags & TRIG_ROUND_MASK);
1053 if (das1800_set_frequency(dev) < 0)
1060 /* setup counter 0 for 'about triggering' */
1061 if (cmd->stop_src == TRIG_EXT) {
1062 /* load counter 0 in mode 0 */
1063 i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0);
1069 /* utility function that suggests a dma transfer size based on the conversion period 'ns' */
1070 static unsigned int suggest_transfer_size(const struct comedi_cmd *cmd)
1072 unsigned int size = DMA_BUF_SIZE;
1073 static const int sample_size = 2; /* size in bytes of one sample from board */
1074 unsigned int fill_time = 300000000; /* target time in nanoseconds for filling dma buffer */
1075 unsigned int max_size; /* maximum size we will allow for a transfer */
1077 /* make dma buffer fill in 0.3 seconds for timed modes */
1078 switch (cmd->scan_begin_src) {
1079 case TRIG_FOLLOW: /* not in burst mode */
1080 if (cmd->convert_src == TRIG_TIMER)
1081 size = (fill_time / cmd->convert_arg) * sample_size;
1084 size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) *
1088 size = DMA_BUF_SIZE;
1092 /* set a minimum and maximum size allowed */
1093 max_size = DMA_BUF_SIZE;
1094 /* if we are taking limited number of conversions, limit transfer size to that */
1095 if (cmd->stop_src == TRIG_COUNT &&
1096 cmd->stop_arg * cmd->chanlist_len * sample_size < max_size)
1097 max_size = cmd->stop_arg * cmd->chanlist_len * sample_size;
1099 if (size > max_size)
1101 if (size < sample_size)
1108 static void setup_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
1110 unsigned long lock_flags;
1111 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
1113 if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
1116 /* determine a reasonable dma transfer size */
1117 devpriv->dma_transfer_size = suggest_transfer_size(cmd);
1118 lock_flags = claim_dma_lock();
1119 disable_dma(devpriv->dma0);
1120 /* clear flip-flop to make sure 2-byte registers for
1121 * count and address get set correctly */
1122 clear_dma_ff(devpriv->dma0);
1123 set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0));
1124 /* set appropriate size of transfer */
1125 set_dma_count(devpriv->dma0, devpriv->dma_transfer_size);
1126 devpriv->dma_current = devpriv->dma0;
1127 devpriv->dma_current_buf = devpriv->ai_buf0;
1128 enable_dma(devpriv->dma0);
1129 /* set up dual dma if appropriate */
1131 disable_dma(devpriv->dma1);
1132 /* clear flip-flop to make sure 2-byte registers for
1133 * count and address get set correctly */
1134 clear_dma_ff(devpriv->dma1);
1135 set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1));
1136 /* set appropriate size of transfer */
1137 set_dma_count(devpriv->dma1, devpriv->dma_transfer_size);
1138 enable_dma(devpriv->dma1);
1140 release_dma_lock(lock_flags);
1145 /* programs channel/gain list into card */
1146 static void program_chanlist(struct comedi_device *dev,
1147 const struct comedi_cmd *cmd)
1149 int i, n, chan_range;
1150 unsigned long irq_flags;
1151 const int range_mask = 0x3; /* masks unipolar/bipolar bit off range */
1152 const int range_bitshift = 8;
1154 n = cmd->chanlist_len;
1155 /* spinlock protects indirect addressing */
1156 spin_lock_irqsave(&dev->spinlock, irq_flags);
1157 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
1158 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */
1159 /* make channel / gain list */
1160 for (i = 0; i < n; i++) {
1162 CR_CHAN(cmd->chanlist[i]) |
1163 ((CR_RANGE(cmd->chanlist[i]) & range_mask) <<
1165 outw(chan_range, dev->iobase + DAS1800_QRAM);
1167 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
1168 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1173 /* analog input do_cmd */
1174 static int das1800_ai_do_cmd(struct comedi_device *dev,
1175 struct comedi_subdevice *s)
1178 int control_a, control_c;
1179 struct comedi_async *async = s->async;
1180 const struct comedi_cmd *cmd = &async->cmd;
1184 "no irq assigned for das-1800, cannot do hardware conversions");
1188 /* disable dma on TRIG_WAKE_EOS, or TRIG_RT
1189 * (because dma in handler is unsafe at hard real-time priority) */
1190 if (cmd->flags & (TRIG_WAKE_EOS | TRIG_RT))
1191 devpriv->irq_dma_bits &= ~DMA_ENABLED;
1193 devpriv->irq_dma_bits |= devpriv->dma_bits;
1194 /* interrupt on end of conversion for TRIG_WAKE_EOS */
1195 if (cmd->flags & TRIG_WAKE_EOS) {
1196 /* interrupt fifo not empty */
1197 devpriv->irq_dma_bits &= ~FIMD;
1199 /* interrupt fifo half full */
1200 devpriv->irq_dma_bits |= FIMD;
1202 /* determine how many conversions we need */
1203 if (cmd->stop_src == TRIG_COUNT)
1204 devpriv->count = cmd->stop_arg * cmd->chanlist_len;
1206 das1800_cancel(dev, s);
1208 /* determine proper bits for control registers */
1209 control_a = control_a_bits(cmd);
1210 control_c = control_c_bits(cmd);
1212 /* setup card and start */
1213 program_chanlist(dev, cmd);
1214 ret = setup_counters(dev, cmd);
1216 comedi_error(dev, "Error setting up counters");
1219 setup_dma(dev, cmd);
1220 outb(control_c, dev->iobase + DAS1800_CONTROL_C);
1221 /* set conversion rate and length for burst mode */
1222 if (control_c & BMDE) {
1223 /* program conversion period with number of microseconds minus 1 */
1224 outb(cmd->convert_arg / 1000 - 1,
1225 dev->iobase + DAS1800_BURST_RATE);
1226 outb(cmd->chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
1228 outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); /* enable irq/dma */
1229 outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */
1230 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
1235 /* read analog input */
1236 static int das1800_ai_rinsn(struct comedi_device *dev,
1237 struct comedi_subdevice *s,
1238 struct comedi_insn *insn, unsigned int *data)
1241 int chan, range, aref, chan_range;
1245 unsigned long irq_flags;
1247 /* set up analog reference and unipolar / bipolar mode */
1248 aref = CR_AREF(insn->chanspec);
1250 if (aref != AREF_DIFF)
1252 if (aref == AREF_COMMON)
1254 /* if a unipolar range was selected */
1255 if (CR_RANGE(insn->chanspec) & UNIPOLAR)
1258 outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */
1259 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
1260 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */
1261 outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
1263 chan = CR_CHAN(insn->chanspec);
1264 /* mask of unipolar/bipolar bit from range */
1265 range = CR_RANGE(insn->chanspec) & 0x3;
1266 chan_range = chan | (range << 8);
1267 spin_lock_irqsave(&dev->spinlock, irq_flags);
1268 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
1269 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */
1270 outw(chan_range, dev->iobase + DAS1800_QRAM);
1271 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
1272 outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */
1274 for (n = 0; n < insn->n; n++) {
1275 /* trigger conversion */
1276 outb(0, dev->iobase + DAS1800_FIFO);
1277 for (i = 0; i < timeout; i++) {
1278 if (inb(dev->iobase + DAS1800_STATUS) & FNE)
1282 comedi_error(dev, "timeout");
1286 dpnt = inw(dev->iobase + DAS1800_FIFO);
1287 /* shift data to offset binary for bipolar ranges */
1288 if ((conv_flags & UB) == 0)
1289 dpnt += 1 << (thisboard->resolution - 1);
1293 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1298 /* writes to an analog output channel */
1299 static int das1800_ao_winsn(struct comedi_device *dev,
1300 struct comedi_subdevice *s,
1301 struct comedi_insn *insn, unsigned int *data)
1303 int chan = CR_CHAN(insn->chanspec);
1304 /* int range = CR_RANGE(insn->chanspec); */
1305 int update_chan = thisboard->ao_n_chan - 1;
1307 unsigned long irq_flags;
1309 /* card expects two's complement data */
1310 output = data[0] - (1 << (thisboard->resolution - 1));
1311 /* if the write is to the 'update' channel, we need to remember its value */
1312 if (chan == update_chan)
1313 devpriv->ao_update_bits = output;
1314 /* write to channel */
1315 spin_lock_irqsave(&dev->spinlock, irq_flags);
1316 outb(DAC(chan), dev->iobase + DAS1800_SELECT); /* select dac channel for baseAddress + 0x0 */
1317 outw(output, dev->iobase + DAS1800_DAC);
1318 /* now we need to write to 'update' channel to update all dac channels */
1319 if (chan != update_chan) {
1320 outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); /* select 'update' channel for baseAddress + 0x0 */
1321 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
1323 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1328 /* reads from digital input channels */
1329 static int das1800_di_rbits(struct comedi_device *dev,
1330 struct comedi_subdevice *s,
1331 struct comedi_insn *insn, unsigned int *data)
1334 data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf;
1340 /* writes to digital output channels */
1341 static int das1800_do_wbits(struct comedi_device *dev,
1342 struct comedi_subdevice *s,
1343 struct comedi_insn *insn, unsigned int *data)
1347 /* only set bits that have been masked */
1348 data[0] &= (1 << s->n_chan) - 1;
1349 wbits = devpriv->do_bits;
1351 wbits |= data[0] & data[1];
1352 devpriv->do_bits = wbits;
1354 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
1356 data[1] = devpriv->do_bits;
1361 static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
1364 unsigned long flags;
1366 /* need an irq to do dma */
1367 if (dev->irq && dma0) {
1368 /* encode dma0 and dma1 into 2 digit hexadecimal for switch */
1369 switch ((dma0 & 0x7) | (dma1 << 4)) {
1370 case 0x5: /* dma0 == 5 */
1371 devpriv->dma_bits |= DMA_CH5;
1373 case 0x6: /* dma0 == 6 */
1374 devpriv->dma_bits |= DMA_CH6;
1376 case 0x7: /* dma0 == 7 */
1377 devpriv->dma_bits |= DMA_CH7;
1379 case 0x65: /* dma0 == 5, dma1 == 6 */
1380 devpriv->dma_bits |= DMA_CH5_CH6;
1382 case 0x76: /* dma0 == 6, dma1 == 7 */
1383 devpriv->dma_bits |= DMA_CH6_CH7;
1385 case 0x57: /* dma0 == 7, dma1 == 5 */
1386 devpriv->dma_bits |= DMA_CH7_CH5;
1389 dev_err(dev->class_dev,
1390 "only supports dma channels 5 through 7\n");
1391 dev_err(dev->class_dev,
1392 "Dual dma only allows the following combinations:\n");
1393 dev_err(dev->class_dev,
1394 "dma 5,6 / 6,7 / or 7,5\n");
1398 if (request_dma(dma0, dev->driver->driver_name)) {
1399 dev_err(dev->class_dev,
1400 "failed to allocate dma channel %i\n", dma0);
1403 devpriv->dma0 = dma0;
1404 devpriv->dma_current = dma0;
1406 if (request_dma(dma1, dev->driver->driver_name)) {
1407 dev_err(dev->class_dev,
1408 "failed to allocate dma channel %i\n",
1412 devpriv->dma1 = dma1;
1414 devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
1415 if (devpriv->ai_buf0 == NULL)
1417 devpriv->dma_current_buf = devpriv->ai_buf0;
1420 kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
1421 if (devpriv->ai_buf1 == NULL)
1424 flags = claim_dma_lock();
1425 disable_dma(devpriv->dma0);
1426 set_dma_mode(devpriv->dma0, DMA_MODE_READ);
1428 disable_dma(devpriv->dma1);
1429 set_dma_mode(devpriv->dma1, DMA_MODE_READ);
1431 release_dma_lock(flags);
1436 static int das1800_probe(struct comedi_device *dev)
1441 id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */
1442 board = ((struct das1800_board *)dev->board_ptr) - das1800_boards;
1446 if (board == das1801st_da || board == das1802st_da ||
1447 board == das1701st_da || board == das1702st_da) {
1448 dev_dbg(dev->class_dev, "Board model: %s\n",
1449 das1800_boards[board].name);
1453 (" Board model (probed, not recommended): das-1800st-da series\n");
1457 if (board == das1802hr_da || board == das1702hr_da) {
1458 dev_dbg(dev->class_dev, "Board model: %s\n",
1459 das1800_boards[board].name);
1463 (" Board model (probed, not recommended): das-1802hr-da\n");
1467 if (board == das1801ao || board == das1802ao ||
1468 board == das1701ao || board == das1702ao) {
1469 dev_dbg(dev->class_dev, "Board model: %s\n",
1470 das1800_boards[board].name);
1474 (" Board model (probed, not recommended): das-1800ao series\n");
1478 if (board == das1802hr || board == das1702hr) {
1479 dev_dbg(dev->class_dev, "Board model: %s\n",
1480 das1800_boards[board].name);
1484 (" Board model (probed, not recommended): das-1802hr\n");
1488 if (board == das1801st || board == das1802st ||
1489 board == das1701st || board == das1702st) {
1490 dev_dbg(dev->class_dev, "Board model: %s\n",
1491 das1800_boards[board].name);
1495 (" Board model (probed, not recommended): das-1800st series\n");
1499 if (board == das1801hc || board == das1802hc) {
1500 dev_dbg(dev->class_dev, "Board model: %s\n",
1501 das1800_boards[board].name);
1505 (" Board model (probed, not recommended): das-1800hc series\n");
1510 (" Board model: probe returned 0x%x (unknown, please report)\n",
1518 static int das1800_attach(struct comedi_device *dev,
1519 struct comedi_devconfig *it)
1521 struct comedi_subdevice *s;
1522 unsigned long iobase = it->options[0];
1523 unsigned int irq = it->options[1];
1524 unsigned int dma0 = it->options[2];
1525 unsigned int dma1 = it->options[3];
1526 unsigned long iobase2;
1530 /* allocate and initialize dev->private */
1531 if (alloc_private(dev, sizeof(struct das1800_private)) < 0)
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)
1703 release_region(dev->iobase, DAS1800_SIZE);
1705 free_irq(dev->irq, dev);
1707 if (devpriv->iobase2)
1708 release_region(devpriv->iobase2, DAS1800_SIZE);
1710 free_dma(devpriv->dma0);
1712 free_dma(devpriv->dma1);
1713 kfree(devpriv->ai_buf0);
1714 kfree(devpriv->ai_buf1);
1718 static struct comedi_driver das1800_driver = {
1719 .driver_name = "das1800",
1720 .module = THIS_MODULE,
1721 .attach = das1800_attach,
1722 .detach = das1800_detach,
1723 .num_names = ARRAY_SIZE(das1800_boards),
1724 .board_name = &das1800_boards[0].name,
1725 .offset = sizeof(struct das1800_board),
1727 module_comedi_driver(das1800_driver);
1729 MODULE_AUTHOR("Comedi http://www.comedi.org");
1730 MODULE_DESCRIPTION("Comedi low-level driver");
1731 MODULE_LICENSE("GPL");