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,
432 struct das1800_private {
433 volatile unsigned int count; /* number of data points left to be taken */
434 unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */
435 unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */
436 int do_bits; /* digital output bits */
437 int irq_dma_bits; /* bits for control register b */
438 /* dma bits for control register b, stored so that dma can be
439 * turned on and off */
441 unsigned int dma0; /* dma channels used */
443 volatile unsigned int dma_current; /* dma channel currently in use */
444 uint16_t *ai_buf0; /* pointers to dma buffers */
446 uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */
447 unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */
448 unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */
449 short ao_update_bits; /* remembers the last write to the 'update' dac */
452 /* analog out range for 'ao' boards */
454 static const struct comedi_lrange range_ao_2 = {
463 static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev,
466 const struct das1800_board *thisboard = comedi_board(dev);
468 sample += 1 << (thisboard->resolution - 1);
472 static void munge_data(struct comedi_device *dev, uint16_t * array,
473 unsigned int num_elements)
478 /* see if card is using a unipolar or bipolar range so we can munge data correctly */
479 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
481 /* convert to unsigned type if we are in a bipolar mode */
483 for (i = 0; i < num_elements; i++)
484 array[i] = munge_bipolar_sample(dev, array[i]);
488 static void das1800_handle_fifo_half_full(struct comedi_device *dev,
489 struct comedi_subdevice *s)
491 struct das1800_private *devpriv = dev->private;
492 int numPoints = 0; /* number of points to read */
493 struct comedi_cmd *cmd = &s->async->cmd;
495 numPoints = FIFO_SIZE / 2;
496 /* if we only need some of the points */
497 if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints)
498 numPoints = devpriv->count;
499 insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints);
500 munge_data(dev, devpriv->ai_buf0, numPoints);
501 cfc_write_array_to_buffer(s, devpriv->ai_buf0,
502 numPoints * sizeof(devpriv->ai_buf0[0]));
503 if (cmd->stop_src == TRIG_COUNT)
504 devpriv->count -= numPoints;
508 static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
509 struct comedi_subdevice *s)
511 struct das1800_private *devpriv = dev->private;
514 struct comedi_cmd *cmd = &s->async->cmd;
516 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
518 while (inb(dev->iobase + DAS1800_STATUS) & FNE) {
519 if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
521 dpnt = inw(dev->iobase + DAS1800_FIFO);
522 /* convert to unsigned type if we are in a bipolar mode */
525 dpnt = munge_bipolar_sample(dev, dpnt);
526 cfc_write_to_buffer(s, dpnt);
527 if (cmd->stop_src == TRIG_COUNT)
534 /* Utility function used by das1800_flush_dma() and das1800_handle_dma().
535 * Assumes dma lock is held */
536 static void das1800_flush_dma_channel(struct comedi_device *dev,
537 struct comedi_subdevice *s,
538 unsigned int channel, uint16_t *buffer)
540 struct das1800_private *devpriv = dev->private;
541 unsigned int num_bytes, num_samples;
542 struct comedi_cmd *cmd = &s->async->cmd;
544 disable_dma(channel);
546 /* clear flip-flop to make sure 2-byte registers
547 * get set correctly */
548 clear_dma_ff(channel);
550 /* figure out how many points to read */
551 num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel);
552 num_samples = num_bytes / sizeof(short);
554 /* if we only need some of the points */
555 if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples)
556 num_samples = devpriv->count;
558 munge_data(dev, buffer, num_samples);
559 cfc_write_array_to_buffer(s, buffer, num_bytes);
560 if (s->async->cmd.stop_src == TRIG_COUNT)
561 devpriv->count -= num_samples;
566 /* flushes remaining data from board when external trigger has stopped acquisition
567 * and we are using dma transfers */
568 static void das1800_flush_dma(struct comedi_device *dev,
569 struct comedi_subdevice *s)
571 struct das1800_private *devpriv = dev->private;
573 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
575 flags = claim_dma_lock();
576 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
577 devpriv->dma_current_buf);
580 /* switch to other channel and flush it */
581 if (devpriv->dma_current == devpriv->dma0) {
582 devpriv->dma_current = devpriv->dma1;
583 devpriv->dma_current_buf = devpriv->ai_buf1;
585 devpriv->dma_current = devpriv->dma0;
586 devpriv->dma_current_buf = devpriv->ai_buf0;
588 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
589 devpriv->dma_current_buf);
592 release_dma_lock(flags);
594 /* get any remaining samples in fifo */
595 das1800_handle_fifo_not_empty(dev, s);
600 static void das1800_handle_dma(struct comedi_device *dev,
601 struct comedi_subdevice *s, unsigned int status)
603 struct das1800_private *devpriv = dev->private;
605 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
607 flags = claim_dma_lock();
608 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
609 devpriv->dma_current_buf);
610 /* re-enable dma channel */
611 set_dma_addr(devpriv->dma_current,
612 virt_to_bus(devpriv->dma_current_buf));
613 set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size);
614 enable_dma(devpriv->dma_current);
615 release_dma_lock(flags);
617 if (status & DMATC) {
618 /* clear DMATC interrupt bit */
619 outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
620 /* switch dma channels for next time, if appropriate */
622 /* read data from the other channel next time */
623 if (devpriv->dma_current == devpriv->dma0) {
624 devpriv->dma_current = devpriv->dma1;
625 devpriv->dma_current_buf = devpriv->ai_buf1;
627 devpriv->dma_current = devpriv->dma0;
628 devpriv->dma_current_buf = devpriv->ai_buf0;
636 static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
638 struct das1800_private *devpriv = dev->private;
640 outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */
641 outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */
642 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */
644 disable_dma(devpriv->dma0);
646 disable_dma(devpriv->dma1);
650 /* the guts of the interrupt handler, that is shared with das1800_ai_poll */
651 static void das1800_ai_handler(struct comedi_device *dev)
653 struct das1800_private *devpriv = dev->private;
654 struct comedi_subdevice *s = &dev->subdevices[0];
655 struct comedi_async *async = s->async;
656 struct comedi_cmd *cmd = &async->cmd;
657 unsigned int status = inb(dev->iobase + DAS1800_STATUS);
660 /* select adc for base address + 0 */
661 outb(ADC, dev->iobase + DAS1800_SELECT);
662 /* dma buffer full */
663 if (devpriv->irq_dma_bits & DMA_ENABLED) {
664 /* look for data from dma transfer even if dma terminal count hasn't happened yet */
665 das1800_handle_dma(dev, s, status);
666 } else if (status & FHF) { /* if fifo half full */
667 das1800_handle_fifo_half_full(dev, s);
668 } else if (status & FNE) { /* if fifo not empty */
669 das1800_handle_fifo_not_empty(dev, s);
672 async->events |= COMEDI_CB_BLOCK;
673 /* if the card's fifo has overflowed */
675 /* clear OVF interrupt bit */
676 outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
677 comedi_error(dev, "DAS1800 FIFO overflow");
678 das1800_cancel(dev, s);
679 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
680 comedi_event(dev, s);
683 /* stop taking data if appropriate */
684 /* stop_src TRIG_EXT */
685 if (status & CT0TC) {
686 /* clear CT0TC interrupt bit */
687 outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
688 /* make sure we get all remaining data from board before quitting */
689 if (devpriv->irq_dma_bits & DMA_ENABLED)
690 das1800_flush_dma(dev, s);
692 das1800_handle_fifo_not_empty(dev, s);
693 das1800_cancel(dev, s); /* disable hardware conversions */
694 async->events |= COMEDI_CB_EOA;
695 } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { /* stop_src TRIG_COUNT */
696 das1800_cancel(dev, s); /* disable hardware conversions */
697 async->events |= COMEDI_CB_EOA;
700 comedi_event(dev, s);
705 static int das1800_ai_poll(struct comedi_device *dev,
706 struct comedi_subdevice *s)
710 /* prevent race with interrupt handler */
711 spin_lock_irqsave(&dev->spinlock, flags);
712 das1800_ai_handler(dev);
713 spin_unlock_irqrestore(&dev->spinlock, flags);
715 return s->async->buf_write_count - s->async->buf_read_count;
718 static irqreturn_t das1800_interrupt(int irq, void *d)
720 struct comedi_device *dev = d;
723 if (!dev->attached) {
724 comedi_error(dev, "premature interrupt");
728 /* Prevent race with das1800_ai_poll() on multi processor systems.
729 * Also protects indirect addressing in das1800_ai_handler */
730 spin_lock(&dev->spinlock);
731 status = inb(dev->iobase + DAS1800_STATUS);
733 /* if interrupt was not caused by das-1800 */
734 if (!(status & INT)) {
735 spin_unlock(&dev->spinlock);
738 /* clear the interrupt status bit INT */
739 outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
740 /* handle interrupt */
741 das1800_ai_handler(dev);
743 spin_unlock(&dev->spinlock);
747 /* converts requested conversion timing to timing compatible with
748 * hardware, used only when card is in 'burst mode'
750 static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode)
752 unsigned int micro_sec;
754 /* in burst mode, the maximum conversion time is 64 microseconds */
755 if (convert_arg > 64000)
758 /* the conversion time must be an integral number of microseconds */
759 switch (round_mode) {
760 case TRIG_ROUND_NEAREST:
762 micro_sec = (convert_arg + 500) / 1000;
764 case TRIG_ROUND_DOWN:
765 micro_sec = convert_arg / 1000;
768 micro_sec = (convert_arg - 1) / 1000 + 1;
772 /* return number of nanoseconds */
773 return micro_sec * 1000;
776 /* test analog input cmd */
777 static int das1800_ai_do_cmdtest(struct comedi_device *dev,
778 struct comedi_subdevice *s,
779 struct comedi_cmd *cmd)
781 const struct das1800_board *thisboard = comedi_board(dev);
782 struct das1800_private *devpriv = dev->private;
784 unsigned int tmp_arg;
788 /* Step 1 : check if triggers are trivially valid */
790 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
791 err |= cfc_check_trigger_src(&cmd->scan_begin_src,
792 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
793 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
794 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
795 err |= cfc_check_trigger_src(&cmd->stop_src,
796 TRIG_COUNT | TRIG_EXT | TRIG_NONE);
801 /* Step 2a : make sure trigger sources are unique */
803 err |= cfc_check_trigger_is_unique(cmd->start_src);
804 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
805 err |= cfc_check_trigger_is_unique(cmd->convert_src);
806 err |= cfc_check_trigger_is_unique(cmd->stop_src);
808 /* Step 2b : and mutually compatible */
810 if (cmd->scan_begin_src != TRIG_FOLLOW &&
811 cmd->convert_src != TRIG_TIMER)
817 /* Step 3: check if arguments are trivially valid */
819 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
821 if (cmd->convert_src == TRIG_TIMER)
822 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
823 thisboard->ai_speed);
825 err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
826 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
828 switch (cmd->stop_src) {
830 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
833 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
842 /* step 4: fix up any arguments */
844 if (cmd->convert_src == TRIG_TIMER) {
845 /* if we are not in burst mode */
846 if (cmd->scan_begin_src == TRIG_FOLLOW) {
847 tmp_arg = cmd->convert_arg;
848 /* calculate counter values that give desired timing */
849 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
850 &(devpriv->divisor1),
851 &(devpriv->divisor2),
854 flags & TRIG_ROUND_MASK);
855 if (tmp_arg != cmd->convert_arg)
858 /* if we are in burst mode */
860 /* check that convert_arg is compatible */
861 tmp_arg = cmd->convert_arg;
863 burst_convert_arg(cmd->convert_arg,
864 cmd->flags & TRIG_ROUND_MASK);
865 if (tmp_arg != cmd->convert_arg)
868 if (cmd->scan_begin_src == TRIG_TIMER) {
869 /* if scans are timed faster than conversion rate allows */
870 if (cmd->convert_arg * cmd->chanlist_len >
871 cmd->scan_begin_arg) {
872 cmd->scan_begin_arg =
877 tmp_arg = cmd->scan_begin_arg;
878 /* calculate counter values that give desired timing */
879 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
889 if (tmp_arg != cmd->scan_begin_arg)
898 /* make sure user is not trying to mix unipolar and bipolar ranges */
900 unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR;
901 for (i = 1; i < cmd->chanlist_len; i++) {
902 if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) {
904 "unipolar and bipolar ranges cannot be mixed in the chanlist");
917 /* returns appropriate bits for control register a, depending on command */
918 static int control_a_bits(const struct comedi_cmd *cmd)
922 control_a = FFEN; /* enable fifo */
923 if (cmd->stop_src == TRIG_EXT)
925 switch (cmd->start_src) {
927 control_a |= TGEN | CGSL;
939 /* returns appropriate bits for control register c, depending on command */
940 static int control_c_bits(const struct comedi_cmd *cmd)
945 /* set clock source to internal or external, select analog reference,
946 * select unipolar / bipolar
948 aref = CR_AREF(cmd->chanlist[0]);
949 control_c = UQEN; /* enable upper qram addresses */
950 if (aref != AREF_DIFF)
952 if (aref == AREF_COMMON)
954 /* if a unipolar range was selected */
955 if (CR_RANGE(cmd->chanlist[0]) & UNIPOLAR)
957 switch (cmd->scan_begin_src) {
958 case TRIG_FOLLOW: /* not in burst mode */
959 switch (cmd->convert_src) {
961 /* trig on cascaded counters */
965 /* trig on falling edge of external trigger */
973 /* burst mode with internal pacer clock */
974 control_c |= BMDE | IPCLK;
977 /* burst mode with external trigger */
978 control_c |= BMDE | XPCLK;
987 /* loads counters with divisor1, divisor2 from private structure */
988 static int das1800_set_frequency(struct comedi_device *dev)
990 struct das1800_private *devpriv = dev->private;
993 /* counter 1, mode 2 */
994 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1,
997 /* counter 2, mode 2 */
998 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2,
1007 /* sets up counters */
1008 static int setup_counters(struct comedi_device *dev,
1009 const struct comedi_cmd *cmd)
1011 struct das1800_private *devpriv = dev->private;
1012 unsigned int period;
1014 /* setup cascaded counters for conversion/scan frequency */
1015 switch (cmd->scan_begin_src) {
1016 case TRIG_FOLLOW: /* not in burst mode */
1017 if (cmd->convert_src == TRIG_TIMER) {
1018 /* set conversion frequency */
1019 period = cmd->convert_arg;
1020 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1026 if (das1800_set_frequency(dev) < 0)
1030 case TRIG_TIMER: /* in burst mode */
1031 /* set scan frequency */
1032 period = cmd->scan_begin_arg;
1033 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &devpriv->divisor1,
1034 &devpriv->divisor2, &period,
1035 cmd->flags & TRIG_ROUND_MASK);
1036 if (das1800_set_frequency(dev) < 0)
1043 /* setup counter 0 for 'about triggering' */
1044 if (cmd->stop_src == TRIG_EXT) {
1045 /* load counter 0 in mode 0 */
1046 i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0);
1052 /* utility function that suggests a dma transfer size based on the conversion period 'ns' */
1053 static unsigned int suggest_transfer_size(const struct comedi_cmd *cmd)
1055 unsigned int size = DMA_BUF_SIZE;
1056 static const int sample_size = 2; /* size in bytes of one sample from board */
1057 unsigned int fill_time = 300000000; /* target time in nanoseconds for filling dma buffer */
1058 unsigned int max_size; /* maximum size we will allow for a transfer */
1060 /* make dma buffer fill in 0.3 seconds for timed modes */
1061 switch (cmd->scan_begin_src) {
1062 case TRIG_FOLLOW: /* not in burst mode */
1063 if (cmd->convert_src == TRIG_TIMER)
1064 size = (fill_time / cmd->convert_arg) * sample_size;
1067 size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) *
1071 size = DMA_BUF_SIZE;
1075 /* set a minimum and maximum size allowed */
1076 max_size = DMA_BUF_SIZE;
1077 /* if we are taking limited number of conversions, limit transfer size to that */
1078 if (cmd->stop_src == TRIG_COUNT &&
1079 cmd->stop_arg * cmd->chanlist_len * sample_size < max_size)
1080 max_size = cmd->stop_arg * cmd->chanlist_len * sample_size;
1082 if (size > max_size)
1084 if (size < sample_size)
1091 static void setup_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
1093 struct das1800_private *devpriv = dev->private;
1094 unsigned long lock_flags;
1095 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
1097 if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
1100 /* determine a reasonable dma transfer size */
1101 devpriv->dma_transfer_size = suggest_transfer_size(cmd);
1102 lock_flags = claim_dma_lock();
1103 disable_dma(devpriv->dma0);
1104 /* clear flip-flop to make sure 2-byte registers for
1105 * count and address get set correctly */
1106 clear_dma_ff(devpriv->dma0);
1107 set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0));
1108 /* set appropriate size of transfer */
1109 set_dma_count(devpriv->dma0, devpriv->dma_transfer_size);
1110 devpriv->dma_current = devpriv->dma0;
1111 devpriv->dma_current_buf = devpriv->ai_buf0;
1112 enable_dma(devpriv->dma0);
1113 /* set up dual dma if appropriate */
1115 disable_dma(devpriv->dma1);
1116 /* clear flip-flop to make sure 2-byte registers for
1117 * count and address get set correctly */
1118 clear_dma_ff(devpriv->dma1);
1119 set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1));
1120 /* set appropriate size of transfer */
1121 set_dma_count(devpriv->dma1, devpriv->dma_transfer_size);
1122 enable_dma(devpriv->dma1);
1124 release_dma_lock(lock_flags);
1129 /* programs channel/gain list into card */
1130 static void program_chanlist(struct comedi_device *dev,
1131 const struct comedi_cmd *cmd)
1133 int i, n, chan_range;
1134 unsigned long irq_flags;
1135 const int range_mask = 0x3; /* masks unipolar/bipolar bit off range */
1136 const int range_bitshift = 8;
1138 n = cmd->chanlist_len;
1139 /* spinlock protects indirect addressing */
1140 spin_lock_irqsave(&dev->spinlock, irq_flags);
1141 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
1142 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */
1143 /* make channel / gain list */
1144 for (i = 0; i < n; i++) {
1146 CR_CHAN(cmd->chanlist[i]) |
1147 ((CR_RANGE(cmd->chanlist[i]) & range_mask) <<
1149 outw(chan_range, dev->iobase + DAS1800_QRAM);
1151 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
1152 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1157 /* analog input do_cmd */
1158 static int das1800_ai_do_cmd(struct comedi_device *dev,
1159 struct comedi_subdevice *s)
1161 struct das1800_private *devpriv = dev->private;
1163 int control_a, control_c;
1164 struct comedi_async *async = s->async;
1165 const struct comedi_cmd *cmd = &async->cmd;
1169 "no irq assigned for das-1800, cannot do hardware conversions");
1173 /* disable dma on TRIG_WAKE_EOS, or TRIG_RT
1174 * (because dma in handler is unsafe at hard real-time priority) */
1175 if (cmd->flags & (TRIG_WAKE_EOS | TRIG_RT))
1176 devpriv->irq_dma_bits &= ~DMA_ENABLED;
1178 devpriv->irq_dma_bits |= devpriv->dma_bits;
1179 /* interrupt on end of conversion for TRIG_WAKE_EOS */
1180 if (cmd->flags & TRIG_WAKE_EOS) {
1181 /* interrupt fifo not empty */
1182 devpriv->irq_dma_bits &= ~FIMD;
1184 /* interrupt fifo half full */
1185 devpriv->irq_dma_bits |= FIMD;
1187 /* determine how many conversions we need */
1188 if (cmd->stop_src == TRIG_COUNT)
1189 devpriv->count = cmd->stop_arg * cmd->chanlist_len;
1191 das1800_cancel(dev, s);
1193 /* determine proper bits for control registers */
1194 control_a = control_a_bits(cmd);
1195 control_c = control_c_bits(cmd);
1197 /* setup card and start */
1198 program_chanlist(dev, cmd);
1199 ret = setup_counters(dev, cmd);
1201 comedi_error(dev, "Error setting up counters");
1204 setup_dma(dev, cmd);
1205 outb(control_c, dev->iobase + DAS1800_CONTROL_C);
1206 /* set conversion rate and length for burst mode */
1207 if (control_c & BMDE) {
1208 /* program conversion period with number of microseconds minus 1 */
1209 outb(cmd->convert_arg / 1000 - 1,
1210 dev->iobase + DAS1800_BURST_RATE);
1211 outb(cmd->chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
1213 outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); /* enable irq/dma */
1214 outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */
1215 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
1220 /* read analog input */
1221 static int das1800_ai_rinsn(struct comedi_device *dev,
1222 struct comedi_subdevice *s,
1223 struct comedi_insn *insn, unsigned int *data)
1225 const struct das1800_board *thisboard = comedi_board(dev);
1227 int chan, range, aref, chan_range;
1231 unsigned long irq_flags;
1233 /* set up analog reference and unipolar / bipolar mode */
1234 aref = CR_AREF(insn->chanspec);
1236 if (aref != AREF_DIFF)
1238 if (aref == AREF_COMMON)
1240 /* if a unipolar range was selected */
1241 if (CR_RANGE(insn->chanspec) & UNIPOLAR)
1244 outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */
1245 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
1246 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */
1247 outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
1249 chan = CR_CHAN(insn->chanspec);
1250 /* mask of unipolar/bipolar bit from range */
1251 range = CR_RANGE(insn->chanspec) & 0x3;
1252 chan_range = chan | (range << 8);
1253 spin_lock_irqsave(&dev->spinlock, irq_flags);
1254 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
1255 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */
1256 outw(chan_range, dev->iobase + DAS1800_QRAM);
1257 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
1258 outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */
1260 for (n = 0; n < insn->n; n++) {
1261 /* trigger conversion */
1262 outb(0, dev->iobase + DAS1800_FIFO);
1263 for (i = 0; i < timeout; i++) {
1264 if (inb(dev->iobase + DAS1800_STATUS) & FNE)
1268 comedi_error(dev, "timeout");
1272 dpnt = inw(dev->iobase + DAS1800_FIFO);
1273 /* shift data to offset binary for bipolar ranges */
1274 if ((conv_flags & UB) == 0)
1275 dpnt += 1 << (thisboard->resolution - 1);
1279 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1284 /* writes to an analog output channel */
1285 static int das1800_ao_winsn(struct comedi_device *dev,
1286 struct comedi_subdevice *s,
1287 struct comedi_insn *insn, unsigned int *data)
1289 const struct das1800_board *thisboard = comedi_board(dev);
1290 struct das1800_private *devpriv = dev->private;
1291 int chan = CR_CHAN(insn->chanspec);
1292 /* int range = CR_RANGE(insn->chanspec); */
1293 int update_chan = thisboard->ao_n_chan - 1;
1295 unsigned long irq_flags;
1297 /* card expects two's complement data */
1298 output = data[0] - (1 << (thisboard->resolution - 1));
1299 /* if the write is to the 'update' channel, we need to remember its value */
1300 if (chan == update_chan)
1301 devpriv->ao_update_bits = output;
1302 /* write to channel */
1303 spin_lock_irqsave(&dev->spinlock, irq_flags);
1304 outb(DAC(chan), dev->iobase + DAS1800_SELECT); /* select dac channel for baseAddress + 0x0 */
1305 outw(output, dev->iobase + DAS1800_DAC);
1306 /* now we need to write to 'update' channel to update all dac channels */
1307 if (chan != update_chan) {
1308 outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); /* select 'update' channel for baseAddress + 0x0 */
1309 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
1311 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1316 /* reads from digital input channels */
1317 static int das1800_di_rbits(struct comedi_device *dev,
1318 struct comedi_subdevice *s,
1319 struct comedi_insn *insn, unsigned int *data)
1322 data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf;
1328 /* writes to digital output channels */
1329 static int das1800_do_wbits(struct comedi_device *dev,
1330 struct comedi_subdevice *s,
1331 struct comedi_insn *insn, unsigned int *data)
1333 struct das1800_private *devpriv = dev->private;
1336 /* only set bits that have been masked */
1337 data[0] &= (1 << s->n_chan) - 1;
1338 wbits = devpriv->do_bits;
1340 wbits |= data[0] & data[1];
1341 devpriv->do_bits = wbits;
1343 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
1345 data[1] = devpriv->do_bits;
1350 static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
1353 struct das1800_private *devpriv = dev->private;
1354 unsigned long flags;
1356 /* need an irq to do dma */
1357 if (dev->irq && dma0) {
1358 /* encode dma0 and dma1 into 2 digit hexadecimal for switch */
1359 switch ((dma0 & 0x7) | (dma1 << 4)) {
1360 case 0x5: /* dma0 == 5 */
1361 devpriv->dma_bits |= DMA_CH5;
1363 case 0x6: /* dma0 == 6 */
1364 devpriv->dma_bits |= DMA_CH6;
1366 case 0x7: /* dma0 == 7 */
1367 devpriv->dma_bits |= DMA_CH7;
1369 case 0x65: /* dma0 == 5, dma1 == 6 */
1370 devpriv->dma_bits |= DMA_CH5_CH6;
1372 case 0x76: /* dma0 == 6, dma1 == 7 */
1373 devpriv->dma_bits |= DMA_CH6_CH7;
1375 case 0x57: /* dma0 == 7, dma1 == 5 */
1376 devpriv->dma_bits |= DMA_CH7_CH5;
1379 dev_err(dev->class_dev,
1380 "only supports dma channels 5 through 7\n");
1381 dev_err(dev->class_dev,
1382 "Dual dma only allows the following combinations:\n");
1383 dev_err(dev->class_dev,
1384 "dma 5,6 / 6,7 / or 7,5\n");
1388 if (request_dma(dma0, dev->driver->driver_name)) {
1389 dev_err(dev->class_dev,
1390 "failed to allocate dma channel %i\n", dma0);
1393 devpriv->dma0 = dma0;
1394 devpriv->dma_current = dma0;
1396 if (request_dma(dma1, dev->driver->driver_name)) {
1397 dev_err(dev->class_dev,
1398 "failed to allocate dma channel %i\n",
1402 devpriv->dma1 = dma1;
1404 devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
1405 if (devpriv->ai_buf0 == NULL)
1407 devpriv->dma_current_buf = devpriv->ai_buf0;
1410 kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
1411 if (devpriv->ai_buf1 == NULL)
1414 flags = claim_dma_lock();
1415 disable_dma(devpriv->dma0);
1416 set_dma_mode(devpriv->dma0, DMA_MODE_READ);
1418 disable_dma(devpriv->dma1);
1419 set_dma_mode(devpriv->dma1, DMA_MODE_READ);
1421 release_dma_lock(flags);
1426 static int das1800_probe(struct comedi_device *dev)
1431 id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */
1432 board = ((struct das1800_board *)dev->board_ptr) - das1800_boards;
1436 if (board == das1801st_da || board == das1802st_da ||
1437 board == das1701st_da || board == das1702st_da) {
1438 dev_dbg(dev->class_dev, "Board model: %s\n",
1439 das1800_boards[board].name);
1443 (" Board model (probed, not recommended): das-1800st-da series\n");
1447 if (board == das1802hr_da || board == das1702hr_da) {
1448 dev_dbg(dev->class_dev, "Board model: %s\n",
1449 das1800_boards[board].name);
1453 (" Board model (probed, not recommended): das-1802hr-da\n");
1457 if (board == das1801ao || board == das1802ao ||
1458 board == das1701ao || board == das1702ao) {
1459 dev_dbg(dev->class_dev, "Board model: %s\n",
1460 das1800_boards[board].name);
1464 (" Board model (probed, not recommended): das-1800ao series\n");
1468 if (board == das1802hr || board == das1702hr) {
1469 dev_dbg(dev->class_dev, "Board model: %s\n",
1470 das1800_boards[board].name);
1474 (" Board model (probed, not recommended): das-1802hr\n");
1478 if (board == das1801st || board == das1802st ||
1479 board == das1701st || board == das1702st) {
1480 dev_dbg(dev->class_dev, "Board model: %s\n",
1481 das1800_boards[board].name);
1485 (" Board model (probed, not recommended): das-1800st series\n");
1489 if (board == das1801hc || board == das1802hc) {
1490 dev_dbg(dev->class_dev, "Board model: %s\n",
1491 das1800_boards[board].name);
1495 (" Board model (probed, not recommended): das-1800hc series\n");
1500 (" Board model: probe returned 0x%x (unknown, please report)\n",
1508 static int das1800_attach(struct comedi_device *dev,
1509 struct comedi_devconfig *it)
1511 const struct das1800_board *thisboard = comedi_board(dev);
1512 struct das1800_private *devpriv;
1513 struct comedi_subdevice *s;
1514 unsigned int irq = it->options[1];
1515 unsigned int dma0 = it->options[2];
1516 unsigned int dma1 = it->options[3];
1520 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
1523 dev->private = devpriv;
1525 ret = comedi_request_region(dev, it->options[0], DAS1800_SIZE);
1529 board = das1800_probe(dev);
1531 dev_err(dev->class_dev, "unable to determine board type\n");
1535 dev->board_ptr = das1800_boards + board;
1536 thisboard = comedi_board(dev);
1537 dev->board_name = thisboard->name;
1539 /* if it is an 'ao' board with fancy analog out then we need extra io ports */
1540 if (thisboard->ao_ability == 2) {
1541 unsigned long iobase2 = dev->iobase + IOBASE2;
1543 ret = __comedi_request_region(dev, iobase2, DAS1800_SIZE);
1546 devpriv->iobase2 = iobase2;
1551 if (request_irq(irq, das1800_interrupt, 0,
1552 dev->driver->driver_name, dev)) {
1553 dev_dbg(dev->class_dev, "unable to allocate irq %u\n",
1560 /* set bits that tell card which irq to use */
1565 devpriv->irq_dma_bits |= 0x8;
1568 devpriv->irq_dma_bits |= 0x10;
1571 devpriv->irq_dma_bits |= 0x18;
1574 devpriv->irq_dma_bits |= 0x28;
1577 devpriv->irq_dma_bits |= 0x30;
1580 devpriv->irq_dma_bits |= 0x38;
1583 dev_err(dev->class_dev, "irq out of range\n");
1588 ret = das1800_init_dma(dev, dma0, dma1);
1592 if (devpriv->ai_buf0 == NULL) {
1594 kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL);
1595 if (devpriv->ai_buf0 == NULL)
1599 ret = comedi_alloc_subdevices(dev, 4);
1603 /* analog input subdevice */
1604 s = &dev->subdevices[0];
1605 dev->read_subdev = s;
1606 s->type = COMEDI_SUBD_AI;
1607 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ;
1608 if (thisboard->common)
1609 s->subdev_flags |= SDF_COMMON;
1610 s->n_chan = thisboard->qram_len;
1611 s->len_chanlist = thisboard->qram_len;
1612 s->maxdata = (1 << thisboard->resolution) - 1;
1613 s->range_table = thisboard->range_ai;
1614 s->do_cmd = das1800_ai_do_cmd;
1615 s->do_cmdtest = das1800_ai_do_cmdtest;
1616 s->insn_read = das1800_ai_rinsn;
1617 s->poll = das1800_ai_poll;
1618 s->cancel = das1800_cancel;
1621 s = &dev->subdevices[1];
1622 if (thisboard->ao_ability == 1) {
1623 s->type = COMEDI_SUBD_AO;
1624 s->subdev_flags = SDF_WRITABLE;
1625 s->n_chan = thisboard->ao_n_chan;
1626 s->maxdata = (1 << thisboard->resolution) - 1;
1627 s->range_table = &range_bipolar10;
1628 s->insn_write = das1800_ao_winsn;
1630 s->type = COMEDI_SUBD_UNUSED;
1634 s = &dev->subdevices[2];
1635 s->type = COMEDI_SUBD_DI;
1636 s->subdev_flags = SDF_READABLE;
1639 s->range_table = &range_digital;
1640 s->insn_bits = das1800_di_rbits;
1643 s = &dev->subdevices[3];
1644 s->type = COMEDI_SUBD_DO;
1645 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1646 s->n_chan = thisboard->do_n_chan;
1648 s->range_table = &range_digital;
1649 s->insn_bits = das1800_do_wbits;
1651 das1800_cancel(dev, dev->read_subdev);
1653 /* initialize digital out channels */
1654 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
1656 /* initialize analog out channels */
1657 if (thisboard->ao_ability == 1) {
1658 /* select 'update' dac channel for baseAddress + 0x0 */
1659 outb(DAC(thisboard->ao_n_chan - 1),
1660 dev->iobase + DAS1800_SELECT);
1661 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
1667 static void das1800_detach(struct comedi_device *dev)
1669 struct das1800_private *devpriv = dev->private;
1673 free_dma(devpriv->dma0);
1675 free_dma(devpriv->dma1);
1676 kfree(devpriv->ai_buf0);
1677 kfree(devpriv->ai_buf1);
1678 if (devpriv->iobase2)
1679 release_region(devpriv->iobase2, DAS1800_SIZE);
1681 comedi_legacy_detach(dev);
1684 static struct comedi_driver das1800_driver = {
1685 .driver_name = "das1800",
1686 .module = THIS_MODULE,
1687 .attach = das1800_attach,
1688 .detach = das1800_detach,
1689 .num_names = ARRAY_SIZE(das1800_boards),
1690 .board_name = &das1800_boards[0].name,
1691 .offset = sizeof(struct das1800_board),
1693 module_comedi_driver(das1800_driver);
1695 MODULE_AUTHOR("Comedi http://www.comedi.org");
1696 MODULE_DESCRIPTION("Comedi low-level driver");
1697 MODULE_LICENSE("GPL");