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 "../comedidev.h"
106 #include <linux/ioport.h>
110 #include "comedi_fc.h"
113 #define DAS1800_SIZE 16 /* uses 16 io addresses */
114 #define FIFO_SIZE 1024 /* 1024 sample fifo */
115 #define TIMER_BASE 200 /* 5 Mhz master clock */
116 #define UNIPOLAR 0x4 /* bit that determines whether input range is uni/bipolar */
117 #define DMA_BUF_SIZE 0x1ff00 /* size in bytes of dma buffers */
119 /* Registers for the das1800 */
120 #define DAS1800_FIFO 0x0
121 #define DAS1800_QRAM 0x0
122 #define DAS1800_DAC 0x0
123 #define DAS1800_SELECT 0x2
126 #define DAC(a) (0x2 + a)
127 #define DAS1800_DIGITAL 0x3
128 #define DAS1800_CONTROL_A 0x4
135 #define DAS1800_CONTROL_B 0x5
139 #define DMA_CH5_CH6 0x5
140 #define DMA_CH6_CH7 0x6
141 #define DMA_CH7_CH5 0x7
142 #define DMA_ENABLED 0x3 /* mask used to determine if dma is enabled */
151 #define DAS1800_CONTROL_C 0X6
159 #define DAS1800_STATUS 0x7
160 /* bits that prevent interrupt status bits (and CVEN) from being cleared on write */
161 #define CLEAR_INTR_MASK (CVEN_MASK | 0x1f)
168 #define CVEN_MASK 0x40 /* masks CVEN on write */
170 #define DAS1800_BURST_LENGTH 0x8
171 #define DAS1800_BURST_RATE 0x9
172 #define DAS1800_QRAM_ADDRESS 0xa
173 #define DAS1800_COUNTER 0xc
175 #define IOBASE2 0x400 /* offset of additional ioports used on 'ao' cards */
178 das1701st, das1701st_da, das1702st, das1702st_da, das1702hr,
180 das1701ao, das1702ao, das1801st, das1801st_da, das1802st, das1802st_da,
181 das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao
184 static int das1800_attach(struct comedi_device *dev,
185 struct comedi_devconfig *it);
186 static int das1800_detach(struct comedi_device *dev);
187 static int das1800_probe(struct comedi_device *dev);
188 static int das1800_cancel(struct comedi_device *dev,
189 struct comedi_subdevice *s);
190 static irqreturn_t das1800_interrupt(int irq, void *d);
191 static int das1800_ai_poll(struct comedi_device *dev,
192 struct comedi_subdevice *s);
193 static void das1800_ai_handler(struct comedi_device *dev);
194 static void das1800_handle_dma(struct comedi_device *dev,
195 struct comedi_subdevice *s, unsigned int status);
196 static void das1800_flush_dma(struct comedi_device *dev,
197 struct comedi_subdevice *s);
198 static void das1800_flush_dma_channel(struct comedi_device *dev,
199 struct comedi_subdevice *s,
200 unsigned int channel, uint16_t * buffer);
201 static void das1800_handle_fifo_half_full(struct comedi_device *dev,
202 struct comedi_subdevice *s);
203 static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
204 struct comedi_subdevice *s);
205 static int das1800_ai_do_cmdtest(struct comedi_device *dev,
206 struct comedi_subdevice *s,
207 struct comedi_cmd *cmd);
208 static int das1800_ai_do_cmd(struct comedi_device *dev,
209 struct comedi_subdevice *s);
210 static int das1800_ai_rinsn(struct comedi_device *dev,
211 struct comedi_subdevice *s,
212 struct comedi_insn *insn, unsigned int *data);
213 static int das1800_ao_winsn(struct comedi_device *dev,
214 struct comedi_subdevice *s,
215 struct comedi_insn *insn, unsigned int *data);
216 static int das1800_di_rbits(struct comedi_device *dev,
217 struct comedi_subdevice *s,
218 struct comedi_insn *insn, unsigned int *data);
219 static int das1800_do_wbits(struct comedi_device *dev,
220 struct comedi_subdevice *s,
221 struct comedi_insn *insn, unsigned int *data);
223 static int das1800_set_frequency(struct comedi_device *dev);
224 static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode);
225 static unsigned int suggest_transfer_size(struct comedi_cmd *cmd);
227 /* analog input ranges */
228 static const struct comedi_lrange range_ai_das1801 = {
242 static const struct comedi_lrange range_ai_das1802 = {
256 struct das1800_board {
258 int ai_speed; /* max conversion period in nanoseconds */
259 int resolution; /* bits of ai resolution */
260 int qram_len; /* length of card's channel / gain queue */
261 int common; /* supports AREF_COMMON flag */
262 int do_n_chan; /* number of digital output channels */
263 int ao_ability; /* 0 == no analog out, 1 == basic analog out, 2 == waveform analog out */
264 int ao_n_chan; /* number of analog out channels */
265 const struct comedi_lrange *range_ai; /* available input ranges */
268 /* Warning: the maximum conversion speeds listed below are
269 * not always achievable depending on board setup (see
272 static const struct das1800_board das1800_boards[] = {
274 .name = "das-1701st",
282 .range_ai = &range_ai_das1801,
285 .name = "das-1701st-da",
293 .range_ai = &range_ai_das1801,
296 .name = "das-1702st",
304 .range_ai = &range_ai_das1802,
307 .name = "das-1702st-da",
315 .range_ai = &range_ai_das1802,
318 .name = "das-1702hr",
326 .range_ai = &range_ai_das1802,
329 .name = "das-1702hr-da",
337 .range_ai = &range_ai_das1802,
340 .name = "das-1701ao",
348 .range_ai = &range_ai_das1801,
351 .name = "das-1702ao",
359 .range_ai = &range_ai_das1802,
362 .name = "das-1801st",
370 .range_ai = &range_ai_das1801,
373 .name = "das-1801st-da",
381 .range_ai = &range_ai_das1801,
384 .name = "das-1802st",
392 .range_ai = &range_ai_das1802,
395 .name = "das-1802st-da",
403 .range_ai = &range_ai_das1802,
406 .name = "das-1802hr",
414 .range_ai = &range_ai_das1802,
417 .name = "das-1802hr-da",
425 .range_ai = &range_ai_das1802,
428 .name = "das-1801hc",
436 .range_ai = &range_ai_das1801,
439 .name = "das-1802hc",
447 .range_ai = &range_ai_das1802,
450 .name = "das-1801ao",
458 .range_ai = &range_ai_das1801,
461 .name = "das-1802ao",
469 .range_ai = &range_ai_das1802,
474 * Useful for shorthand access to the particular board structure
476 #define thisboard ((const struct das1800_board *)dev->board_ptr)
478 struct das1800_private {
479 volatile unsigned int count; /* number of data points left to be taken */
480 unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */
481 unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */
482 int do_bits; /* digital output bits */
483 int irq_dma_bits; /* bits for control register b */
484 /* dma bits for control register b, stored so that dma can be
485 * turned on and off */
487 unsigned int dma0; /* dma channels used */
489 volatile unsigned int dma_current; /* dma channel currently in use */
490 uint16_t *ai_buf0; /* pointers to dma buffers */
492 uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */
493 unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */
494 unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */
495 short ao_update_bits; /* remembers the last write to the 'update' dac */
498 #define devpriv ((struct das1800_private *)dev->private)
500 /* analog out range for boards with basic analog out */
501 static const struct comedi_lrange range_ao_1 = {
508 /* analog out range for 'ao' boards */
510 static const struct comedi_lrange range_ao_2 = {
519 static struct comedi_driver driver_das1800 = {
520 .driver_name = "das1800",
521 .module = THIS_MODULE,
522 .attach = das1800_attach,
523 .detach = das1800_detach,
524 .num_names = ARRAY_SIZE(das1800_boards),
525 .board_name = &das1800_boards[0].name,
526 .offset = sizeof(struct das1800_board),
530 * A convenient macro that defines init_module() and cleanup_module(),
533 COMEDI_INITCLEANUP(driver_das1800);
535 static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
540 /* need an irq to do dma */
541 if (dev->irq && dma0) {
542 /* encode dma0 and dma1 into 2 digit hexadecimal for switch */
543 switch ((dma0 & 0x7) | (dma1 << 4)) {
544 case 0x5: /* dma0 == 5 */
545 devpriv->dma_bits |= DMA_CH5;
547 case 0x6: /* dma0 == 6 */
548 devpriv->dma_bits |= DMA_CH6;
550 case 0x7: /* dma0 == 7 */
551 devpriv->dma_bits |= DMA_CH7;
553 case 0x65: /* dma0 == 5, dma1 == 6 */
554 devpriv->dma_bits |= DMA_CH5_CH6;
556 case 0x76: /* dma0 == 6, dma1 == 7 */
557 devpriv->dma_bits |= DMA_CH6_CH7;
559 case 0x57: /* dma0 == 7, dma1 == 5 */
560 devpriv->dma_bits |= DMA_CH7_CH5;
563 printk(" only supports dma channels 5 through 7\n"
564 " Dual dma only allows the following combinations:\n"
565 " dma 5,6 / 6,7 / or 7,5\n");
569 if (request_dma(dma0, driver_das1800.driver_name)) {
570 printk(" failed to allocate dma channel %i\n", dma0);
573 devpriv->dma0 = dma0;
574 devpriv->dma_current = dma0;
576 if (request_dma(dma1, driver_das1800.driver_name)) {
577 printk(" failed to allocate dma channel %i\n",
581 devpriv->dma1 = dma1;
583 devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
584 if (devpriv->ai_buf0 == NULL)
586 devpriv->dma_current_buf = devpriv->ai_buf0;
589 kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
590 if (devpriv->ai_buf1 == NULL)
593 flags = claim_dma_lock();
594 disable_dma(devpriv->dma0);
595 set_dma_mode(devpriv->dma0, DMA_MODE_READ);
597 disable_dma(devpriv->dma1);
598 set_dma_mode(devpriv->dma1, DMA_MODE_READ);
600 release_dma_lock(flags);
605 static int das1800_attach(struct comedi_device *dev,
606 struct comedi_devconfig *it)
608 struct comedi_subdevice *s;
609 unsigned long iobase = it->options[0];
610 unsigned int irq = it->options[1];
611 unsigned int dma0 = it->options[2];
612 unsigned int dma1 = it->options[3];
613 unsigned long iobase2;
617 /* allocate and initialize dev->private */
618 if (alloc_private(dev, sizeof(struct das1800_private)) < 0)
621 printk("comedi%d: %s: io 0x%lx", dev->minor, driver_das1800.driver_name,
624 printk(", irq %u", irq);
626 printk(", dma %u", dma0);
628 printk(" and %u", dma1);
634 printk(" io base address required\n");
638 /* check if io addresses are available */
639 if (!request_region(iobase, DAS1800_SIZE, driver_das1800.driver_name)) {
641 (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
642 iobase, iobase + DAS1800_SIZE - 1);
645 dev->iobase = iobase;
647 board = das1800_probe(dev);
649 printk(" unable to determine board type\n");
653 dev->board_ptr = das1800_boards + board;
654 dev->board_name = thisboard->name;
656 /* if it is an 'ao' board with fancy analog out then we need extra io ports */
657 if (thisboard->ao_ability == 2) {
658 iobase2 = iobase + IOBASE2;
659 if (!request_region(iobase2, DAS1800_SIZE,
660 driver_das1800.driver_name)) {
662 (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
663 iobase2, iobase2 + DAS1800_SIZE - 1);
666 devpriv->iobase2 = iobase2;
671 if (request_irq(irq, das1800_interrupt, 0,
672 driver_das1800.driver_name, dev)) {
673 printk(" unable to allocate irq %u\n", irq);
679 /* set bits that tell card which irq to use */
684 devpriv->irq_dma_bits |= 0x8;
687 devpriv->irq_dma_bits |= 0x10;
690 devpriv->irq_dma_bits |= 0x18;
693 devpriv->irq_dma_bits |= 0x28;
696 devpriv->irq_dma_bits |= 0x30;
699 devpriv->irq_dma_bits |= 0x38;
702 printk(" irq out of range\n");
707 retval = das1800_init_dma(dev, dma0, dma1);
711 if (devpriv->ai_buf0 == NULL) {
713 kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL);
714 if (devpriv->ai_buf0 == NULL)
718 if (alloc_subdevices(dev, 4) < 0)
721 /* analog input subdevice */
722 s = dev->subdevices + 0;
723 dev->read_subdev = s;
724 s->type = COMEDI_SUBD_AI;
725 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ;
726 if (thisboard->common)
727 s->subdev_flags |= SDF_COMMON;
728 s->n_chan = thisboard->qram_len;
729 s->len_chanlist = thisboard->qram_len;
730 s->maxdata = (1 << thisboard->resolution) - 1;
731 s->range_table = thisboard->range_ai;
732 s->do_cmd = das1800_ai_do_cmd;
733 s->do_cmdtest = das1800_ai_do_cmdtest;
734 s->insn_read = das1800_ai_rinsn;
735 s->poll = das1800_ai_poll;
736 s->cancel = das1800_cancel;
739 s = dev->subdevices + 1;
740 if (thisboard->ao_ability == 1) {
741 s->type = COMEDI_SUBD_AO;
742 s->subdev_flags = SDF_WRITABLE;
743 s->n_chan = thisboard->ao_n_chan;
744 s->maxdata = (1 << thisboard->resolution) - 1;
745 s->range_table = &range_ao_1;
746 s->insn_write = das1800_ao_winsn;
748 s->type = COMEDI_SUBD_UNUSED;
752 s = dev->subdevices + 2;
753 s->type = COMEDI_SUBD_DI;
754 s->subdev_flags = SDF_READABLE;
757 s->range_table = &range_digital;
758 s->insn_bits = das1800_di_rbits;
761 s = dev->subdevices + 3;
762 s->type = COMEDI_SUBD_DO;
763 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
764 s->n_chan = thisboard->do_n_chan;
766 s->range_table = &range_digital;
767 s->insn_bits = das1800_do_wbits;
769 das1800_cancel(dev, dev->read_subdev);
771 /* initialize digital out channels */
772 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
774 /* initialize analog out channels */
775 if (thisboard->ao_ability == 1) {
776 /* select 'update' dac channel for baseAddress + 0x0 */
777 outb(DAC(thisboard->ao_n_chan - 1),
778 dev->iobase + DAS1800_SELECT);
779 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
785 static int das1800_detach(struct comedi_device *dev)
787 /* only free stuff if it has been allocated by _attach */
789 release_region(dev->iobase, DAS1800_SIZE);
791 free_irq(dev->irq, dev);
793 if (devpriv->iobase2)
794 release_region(devpriv->iobase2, DAS1800_SIZE);
796 free_dma(devpriv->dma0);
798 free_dma(devpriv->dma1);
799 if (devpriv->ai_buf0)
800 kfree(devpriv->ai_buf0);
801 if (devpriv->ai_buf1)
802 kfree(devpriv->ai_buf1);
805 printk("comedi%d: %s: remove\n", dev->minor,
806 driver_das1800.driver_name);
811 /* probes and checks das-1800 series board type
813 static int das1800_probe(struct comedi_device *dev)
818 id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */
819 board = ((struct das1800_board *)dev->board_ptr) - das1800_boards;
823 if (board == das1801st_da || board == das1802st_da ||
824 board == das1701st_da || board == das1702st_da) {
825 printk(" Board model: %s\n",
826 das1800_boards[board].name);
830 (" Board model (probed, not recommended): das-1800st-da series\n");
834 if (board == das1802hr_da || board == das1702hr_da) {
835 printk(" Board model: %s\n",
836 das1800_boards[board].name);
840 (" Board model (probed, not recommended): das-1802hr-da\n");
844 if (board == das1801ao || board == das1802ao ||
845 board == das1701ao || board == das1702ao) {
846 printk(" Board model: %s\n",
847 das1800_boards[board].name);
851 (" Board model (probed, not recommended): das-1800ao series\n");
855 if (board == das1802hr || board == das1702hr) {
856 printk(" Board model: %s\n",
857 das1800_boards[board].name);
860 printk(" Board model (probed, not recommended): das-1802hr\n");
864 if (board == das1801st || board == das1802st ||
865 board == das1701st || board == das1702st) {
866 printk(" Board model: %s\n",
867 das1800_boards[board].name);
871 (" Board model (probed, not recommended): das-1800st series\n");
875 if (board == das1801hc || board == das1802hc) {
876 printk(" Board model: %s\n",
877 das1800_boards[board].name);
881 (" Board model (probed, not recommended): das-1800hc series\n");
886 (" Board model: probe returned 0x%x (unknown, please report)\n",
894 static int das1800_ai_poll(struct comedi_device *dev,
895 struct comedi_subdevice *s)
899 /* prevent race with interrupt handler */
900 spin_lock_irqsave(&dev->spinlock, flags);
901 das1800_ai_handler(dev);
902 spin_unlock_irqrestore(&dev->spinlock, flags);
904 return s->async->buf_write_count - s->async->buf_read_count;
907 static irqreturn_t das1800_interrupt(int irq, void *d)
909 struct comedi_device *dev = d;
912 if (dev->attached == 0) {
913 comedi_error(dev, "premature interrupt");
917 /* Prevent race with das1800_ai_poll() on multi processor systems.
918 * Also protects indirect addressing in das1800_ai_handler */
919 spin_lock(&dev->spinlock);
920 status = inb(dev->iobase + DAS1800_STATUS);
922 /* if interrupt was not caused by das-1800 */
923 if (!(status & INT)) {
924 spin_unlock(&dev->spinlock);
927 /* clear the interrupt status bit INT */
928 outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
929 /* handle interrupt */
930 das1800_ai_handler(dev);
932 spin_unlock(&dev->spinlock);
936 /* the guts of the interrupt handler, that is shared with das1800_ai_poll */
937 static void das1800_ai_handler(struct comedi_device *dev)
939 struct comedi_subdevice *s = dev->subdevices + 0; /* analog input subdevice */
940 struct comedi_async *async = s->async;
941 struct comedi_cmd *cmd = &async->cmd;
942 unsigned int status = inb(dev->iobase + DAS1800_STATUS);
945 /* select adc for base address + 0 */
946 outb(ADC, dev->iobase + DAS1800_SELECT);
947 /* dma buffer full */
948 if (devpriv->irq_dma_bits & DMA_ENABLED) {
949 /* look for data from dma transfer even if dma terminal count hasn't happened yet */
950 das1800_handle_dma(dev, s, status);
951 } else if (status & FHF) { /* if fifo half full */
952 das1800_handle_fifo_half_full(dev, s);
953 } else if (status & FNE) { /* if fifo not empty */
954 das1800_handle_fifo_not_empty(dev, s);
957 async->events |= COMEDI_CB_BLOCK;
958 /* if the card's fifo has overflowed */
960 /* clear OVF interrupt bit */
961 outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
962 comedi_error(dev, "DAS1800 FIFO overflow");
963 das1800_cancel(dev, s);
964 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
965 comedi_event(dev, s);
968 /* stop taking data if appropriate */
969 /* stop_src TRIG_EXT */
970 if (status & CT0TC) {
971 /* clear CT0TC interrupt bit */
972 outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
973 /* make sure we get all remaining data from board before quitting */
974 if (devpriv->irq_dma_bits & DMA_ENABLED)
975 das1800_flush_dma(dev, s);
977 das1800_handle_fifo_not_empty(dev, s);
978 das1800_cancel(dev, s); /* disable hardware conversions */
979 async->events |= COMEDI_CB_EOA;
980 } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { /* stop_src TRIG_COUNT */
981 das1800_cancel(dev, s); /* disable hardware conversions */
982 async->events |= COMEDI_CB_EOA;
985 comedi_event(dev, s);
990 static void das1800_handle_dma(struct comedi_device *dev,
991 struct comedi_subdevice *s, unsigned int status)
994 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
996 flags = claim_dma_lock();
997 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
998 devpriv->dma_current_buf);
999 /* re-enable dma channel */
1000 set_dma_addr(devpriv->dma_current,
1001 virt_to_bus(devpriv->dma_current_buf));
1002 set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size);
1003 enable_dma(devpriv->dma_current);
1004 release_dma_lock(flags);
1006 if (status & DMATC) {
1007 /* clear DMATC interrupt bit */
1008 outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
1009 /* switch dma channels for next time, if appropriate */
1011 /* read data from the other channel next time */
1012 if (devpriv->dma_current == devpriv->dma0) {
1013 devpriv->dma_current = devpriv->dma1;
1014 devpriv->dma_current_buf = devpriv->ai_buf1;
1016 devpriv->dma_current = devpriv->dma0;
1017 devpriv->dma_current_buf = devpriv->ai_buf0;
1025 static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev,
1028 sample += 1 << (thisboard->resolution - 1);
1032 static void munge_data(struct comedi_device *dev, uint16_t * array,
1033 unsigned int num_elements)
1038 /* see if card is using a unipolar or bipolar range so we can munge data correctly */
1039 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
1041 /* convert to unsigned type if we are in a bipolar mode */
1043 for (i = 0; i < num_elements; i++) {
1044 array[i] = munge_bipolar_sample(dev, array[i]);
1049 /* Utility function used by das1800_flush_dma() and das1800_handle_dma().
1050 * Assumes dma lock is held */
1051 static void das1800_flush_dma_channel(struct comedi_device *dev,
1052 struct comedi_subdevice *s,
1053 unsigned int channel, uint16_t * buffer)
1055 unsigned int num_bytes, num_samples;
1056 struct comedi_cmd *cmd = &s->async->cmd;
1058 disable_dma(channel);
1060 /* clear flip-flop to make sure 2-byte registers
1061 * get set correctly */
1062 clear_dma_ff(channel);
1064 /* figure out how many points to read */
1065 num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel);
1066 num_samples = num_bytes / sizeof(short);
1068 /* if we only need some of the points */
1069 if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples)
1070 num_samples = devpriv->count;
1072 munge_data(dev, buffer, num_samples);
1073 cfc_write_array_to_buffer(s, buffer, num_bytes);
1074 if (s->async->cmd.stop_src == TRIG_COUNT)
1075 devpriv->count -= num_samples;
1080 /* flushes remaining data from board when external trigger has stopped aquisition
1081 * and we are using dma transfers */
1082 static void das1800_flush_dma(struct comedi_device *dev,
1083 struct comedi_subdevice *s)
1085 unsigned long flags;
1086 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
1088 flags = claim_dma_lock();
1089 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
1090 devpriv->dma_current_buf);
1093 /* switch to other channel and flush it */
1094 if (devpriv->dma_current == devpriv->dma0) {
1095 devpriv->dma_current = devpriv->dma1;
1096 devpriv->dma_current_buf = devpriv->ai_buf1;
1098 devpriv->dma_current = devpriv->dma0;
1099 devpriv->dma_current_buf = devpriv->ai_buf0;
1101 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
1102 devpriv->dma_current_buf);
1105 release_dma_lock(flags);
1107 /* get any remaining samples in fifo */
1108 das1800_handle_fifo_not_empty(dev, s);
1113 static void das1800_handle_fifo_half_full(struct comedi_device *dev,
1114 struct comedi_subdevice *s)
1116 int numPoints = 0; /* number of points to read */
1117 struct comedi_cmd *cmd = &s->async->cmd;
1119 numPoints = FIFO_SIZE / 2;
1120 /* if we only need some of the points */
1121 if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints)
1122 numPoints = devpriv->count;
1123 insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints);
1124 munge_data(dev, devpriv->ai_buf0, numPoints);
1125 cfc_write_array_to_buffer(s, devpriv->ai_buf0,
1126 numPoints * sizeof(devpriv->ai_buf0[0]));
1127 if (cmd->stop_src == TRIG_COUNT)
1128 devpriv->count -= numPoints;
1132 static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
1133 struct comedi_subdevice *s)
1137 struct comedi_cmd *cmd = &s->async->cmd;
1139 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
1141 while (inb(dev->iobase + DAS1800_STATUS) & FNE) {
1142 if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
1144 dpnt = inw(dev->iobase + DAS1800_FIFO);
1145 /* convert to unsigned type if we are in a bipolar mode */
1147 dpnt = munge_bipolar_sample(dev, dpnt);
1148 cfc_write_to_buffer(s, dpnt);
1149 if (cmd->stop_src == TRIG_COUNT)
1156 static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1158 outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */
1159 outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */
1160 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */
1162 disable_dma(devpriv->dma0);
1164 disable_dma(devpriv->dma1);
1168 /* test analog input cmd */
1169 static int das1800_ai_do_cmdtest(struct comedi_device *dev,
1170 struct comedi_subdevice *s,
1171 struct comedi_cmd *cmd)
1175 unsigned int tmp_arg;
1179 /* step 1: make sure trigger sources are trivially valid */
1181 tmp = cmd->start_src;
1182 cmd->start_src &= TRIG_NOW | TRIG_EXT;
1183 if (!cmd->start_src || tmp != cmd->start_src)
1186 tmp = cmd->scan_begin_src;
1187 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
1188 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1191 tmp = cmd->convert_src;
1192 cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
1193 if (!cmd->convert_src || tmp != cmd->convert_src)
1196 tmp = cmd->scan_end_src;
1197 cmd->scan_end_src &= TRIG_COUNT;
1198 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1201 tmp = cmd->stop_src;
1202 cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
1203 if (!cmd->stop_src || tmp != cmd->stop_src)
1209 /* step 2: make sure trigger sources are unique and mutually compatible */
1211 /* uniqueness check */
1212 if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
1214 if (cmd->scan_begin_src != TRIG_FOLLOW &&
1215 cmd->scan_begin_src != TRIG_TIMER &&
1216 cmd->scan_begin_src != TRIG_EXT)
1218 if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
1220 if (cmd->stop_src != TRIG_COUNT &&
1221 cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
1223 /* compatibility check */
1224 if (cmd->scan_begin_src != TRIG_FOLLOW &&
1225 cmd->convert_src != TRIG_TIMER)
1231 /* step 3: make sure arguments are trivially compatible */
1233 if (cmd->start_arg != 0) {
1237 if (cmd->convert_src == TRIG_TIMER) {
1238 if (cmd->convert_arg < thisboard->ai_speed) {
1239 cmd->convert_arg = thisboard->ai_speed;
1243 if (!cmd->chanlist_len) {
1244 cmd->chanlist_len = 1;
1247 if (cmd->scan_end_arg != cmd->chanlist_len) {
1248 cmd->scan_end_arg = cmd->chanlist_len;
1252 switch (cmd->stop_src) {
1254 if (!cmd->stop_arg) {
1260 if (cmd->stop_arg != 0) {
1272 /* step 4: fix up any arguments */
1274 if (cmd->convert_src == TRIG_TIMER) {
1275 /* if we are not in burst mode */
1276 if (cmd->scan_begin_src == TRIG_FOLLOW) {
1277 tmp_arg = cmd->convert_arg;
1278 /* calculate counter values that give desired timing */
1279 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1280 &(devpriv->divisor1),
1281 &(devpriv->divisor2),
1282 &(cmd->convert_arg),
1284 flags & TRIG_ROUND_MASK);
1285 if (tmp_arg != cmd->convert_arg)
1288 /* if we are in burst mode */
1290 /* check that convert_arg is compatible */
1291 tmp_arg = cmd->convert_arg;
1293 burst_convert_arg(cmd->convert_arg,
1294 cmd->flags & TRIG_ROUND_MASK);
1295 if (tmp_arg != cmd->convert_arg)
1298 if (cmd->scan_begin_src == TRIG_TIMER) {
1299 /* if scans are timed faster than conversion rate allows */
1300 if (cmd->convert_arg * cmd->chanlist_len >
1301 cmd->scan_begin_arg) {
1302 cmd->scan_begin_arg =
1307 tmp_arg = cmd->scan_begin_arg;
1308 /* calculate counter values that give desired timing */
1309 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1319 if (tmp_arg != cmd->scan_begin_arg)
1328 /* make sure user is not trying to mix unipolar and bipolar ranges */
1329 if (cmd->chanlist) {
1330 unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR;
1331 for (i = 1; i < cmd->chanlist_len; i++) {
1332 if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) {
1334 "unipolar and bipolar ranges cannot be mixed in the chanlist");
1347 /* analog input cmd interface */
1349 /* first, some utility functions used in the main ai_do_cmd() */
1351 /* returns appropriate bits for control register a, depending on command */
1352 static int control_a_bits(struct comedi_cmd cmd)
1356 control_a = FFEN; /* enable fifo */
1357 if (cmd.stop_src == TRIG_EXT) {
1360 switch (cmd.start_src) {
1362 control_a |= TGEN | CGSL;
1374 /* returns appropriate bits for control register c, depending on command */
1375 static int control_c_bits(struct comedi_cmd cmd)
1380 /* set clock source to internal or external, select analog reference,
1381 * select unipolar / bipolar
1383 aref = CR_AREF(cmd.chanlist[0]);
1384 control_c = UQEN; /* enable upper qram addresses */
1385 if (aref != AREF_DIFF)
1387 if (aref == AREF_COMMON)
1389 /* if a unipolar range was selected */
1390 if (CR_RANGE(cmd.chanlist[0]) & UNIPOLAR)
1392 switch (cmd.scan_begin_src) {
1393 case TRIG_FOLLOW: /* not in burst mode */
1394 switch (cmd.convert_src) {
1396 /* trig on cascaded counters */
1400 /* trig on falling edge of external trigger */
1408 /* burst mode with internal pacer clock */
1409 control_c |= BMDE | IPCLK;
1412 /* burst mode with external trigger */
1413 control_c |= BMDE | XPCLK;
1422 /* sets up counters */
1423 static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd)
1425 /* setup cascaded counters for conversion/scan frequency */
1426 switch (cmd.scan_begin_src) {
1427 case TRIG_FOLLOW: /* not in burst mode */
1428 if (cmd.convert_src == TRIG_TIMER) {
1429 /* set conversion frequency */
1430 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1431 &(devpriv->divisor1),
1432 &(devpriv->divisor2),
1435 flags & TRIG_ROUND_MASK);
1436 if (das1800_set_frequency(dev) < 0) {
1441 case TRIG_TIMER: /* in burst mode */
1442 /* set scan frequency */
1443 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
1444 &(devpriv->divisor2),
1445 &(cmd.scan_begin_arg),
1446 cmd.flags & TRIG_ROUND_MASK);
1447 if (das1800_set_frequency(dev) < 0) {
1455 /* setup counter 0 for 'about triggering' */
1456 if (cmd.stop_src == TRIG_EXT) {
1457 /* load counter 0 in mode 0 */
1458 i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0);
1465 static void setup_dma(struct comedi_device *dev, struct comedi_cmd cmd)
1467 unsigned long lock_flags;
1468 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
1470 if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
1473 /* determine a reasonable dma transfer size */
1474 devpriv->dma_transfer_size = suggest_transfer_size(&cmd);
1475 lock_flags = claim_dma_lock();
1476 disable_dma(devpriv->dma0);
1477 /* clear flip-flop to make sure 2-byte registers for
1478 * count and address get set correctly */
1479 clear_dma_ff(devpriv->dma0);
1480 set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0));
1481 /* set appropriate size of transfer */
1482 set_dma_count(devpriv->dma0, devpriv->dma_transfer_size);
1483 devpriv->dma_current = devpriv->dma0;
1484 devpriv->dma_current_buf = devpriv->ai_buf0;
1485 enable_dma(devpriv->dma0);
1486 /* set up dual dma if appropriate */
1488 disable_dma(devpriv->dma1);
1489 /* clear flip-flop to make sure 2-byte registers for
1490 * count and address get set correctly */
1491 clear_dma_ff(devpriv->dma1);
1492 set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1));
1493 /* set appropriate size of transfer */
1494 set_dma_count(devpriv->dma1, devpriv->dma_transfer_size);
1495 enable_dma(devpriv->dma1);
1497 release_dma_lock(lock_flags);
1502 /* programs channel/gain list into card */
1503 static void program_chanlist(struct comedi_device *dev, struct comedi_cmd cmd)
1505 int i, n, chan_range;
1506 unsigned long irq_flags;
1507 const int range_mask = 0x3; /* masks unipolar/bipolar bit off range */
1508 const int range_bitshift = 8;
1510 n = cmd.chanlist_len;
1511 /* spinlock protects indirect addressing */
1512 spin_lock_irqsave(&dev->spinlock, irq_flags);
1513 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
1514 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */
1515 /* make channel / gain list */
1516 for (i = 0; i < n; i++) {
1519 chanlist[i]) | ((CR_RANGE(cmd.chanlist[i]) &
1520 range_mask) << range_bitshift);
1521 outw(chan_range, dev->iobase + DAS1800_QRAM);
1523 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
1524 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1529 /* analog input do_cmd */
1530 static int das1800_ai_do_cmd(struct comedi_device *dev,
1531 struct comedi_subdevice *s)
1534 int control_a, control_c;
1535 struct comedi_async *async = s->async;
1536 struct comedi_cmd cmd = async->cmd;
1540 "no irq assigned for das-1800, cannot do hardware conversions");
1544 /* disable dma on TRIG_WAKE_EOS, or TRIG_RT
1545 * (because dma in handler is unsafe at hard real-time priority) */
1546 if (cmd.flags & (TRIG_WAKE_EOS | TRIG_RT)) {
1547 devpriv->irq_dma_bits &= ~DMA_ENABLED;
1549 devpriv->irq_dma_bits |= devpriv->dma_bits;
1551 /* interrupt on end of conversion for TRIG_WAKE_EOS */
1552 if (cmd.flags & TRIG_WAKE_EOS) {
1553 /* interrupt fifo not empty */
1554 devpriv->irq_dma_bits &= ~FIMD;
1556 /* interrupt fifo half full */
1557 devpriv->irq_dma_bits |= FIMD;
1559 /* determine how many conversions we need */
1560 if (cmd.stop_src == TRIG_COUNT) {
1561 devpriv->count = cmd.stop_arg * cmd.chanlist_len;
1564 das1800_cancel(dev, s);
1566 /* determine proper bits for control registers */
1567 control_a = control_a_bits(cmd);
1568 control_c = control_c_bits(cmd);
1570 /* setup card and start */
1571 program_chanlist(dev, cmd);
1572 ret = setup_counters(dev, cmd);
1574 comedi_error(dev, "Error setting up counters");
1577 setup_dma(dev, cmd);
1578 outb(control_c, dev->iobase + DAS1800_CONTROL_C);
1579 /* set conversion rate and length for burst mode */
1580 if (control_c & BMDE) {
1581 /* program conversion period with number of microseconds minus 1 */
1582 outb(cmd.convert_arg / 1000 - 1,
1583 dev->iobase + DAS1800_BURST_RATE);
1584 outb(cmd.chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
1586 outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); /* enable irq/dma */
1587 outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */
1588 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
1593 /* read analog input */
1594 static int das1800_ai_rinsn(struct comedi_device *dev,
1595 struct comedi_subdevice *s,
1596 struct comedi_insn *insn, unsigned int *data)
1599 int chan, range, aref, chan_range;
1603 unsigned long irq_flags;
1605 /* set up analog reference and unipolar / bipolar mode */
1606 aref = CR_AREF(insn->chanspec);
1608 if (aref != AREF_DIFF)
1610 if (aref == AREF_COMMON)
1612 /* if a unipolar range was selected */
1613 if (CR_RANGE(insn->chanspec) & UNIPOLAR)
1616 outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */
1617 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
1618 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */
1619 outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
1621 chan = CR_CHAN(insn->chanspec);
1622 /* mask of unipolar/bipolar bit from range */
1623 range = CR_RANGE(insn->chanspec) & 0x3;
1624 chan_range = chan | (range << 8);
1625 spin_lock_irqsave(&dev->spinlock, irq_flags);
1626 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
1627 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */
1628 outw(chan_range, dev->iobase + DAS1800_QRAM);
1629 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
1630 outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */
1632 for (n = 0; n < insn->n; n++) {
1633 /* trigger conversion */
1634 outb(0, dev->iobase + DAS1800_FIFO);
1635 for (i = 0; i < timeout; i++) {
1636 if (inb(dev->iobase + DAS1800_STATUS) & FNE)
1640 comedi_error(dev, "timeout");
1643 dpnt = inw(dev->iobase + DAS1800_FIFO);
1644 /* shift data to offset binary for bipolar ranges */
1645 if ((conv_flags & UB) == 0)
1646 dpnt += 1 << (thisboard->resolution - 1);
1649 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1654 /* writes to an analog output channel */
1655 static int das1800_ao_winsn(struct comedi_device *dev,
1656 struct comedi_subdevice *s,
1657 struct comedi_insn *insn, unsigned int *data)
1659 int chan = CR_CHAN(insn->chanspec);
1660 /* int range = CR_RANGE(insn->chanspec); */
1661 int update_chan = thisboard->ao_n_chan - 1;
1663 unsigned long irq_flags;
1665 /* card expects two's complement data */
1666 output = data[0] - (1 << (thisboard->resolution - 1));
1667 /* if the write is to the 'update' channel, we need to remember its value */
1668 if (chan == update_chan)
1669 devpriv->ao_update_bits = output;
1670 /* write to channel */
1671 spin_lock_irqsave(&dev->spinlock, irq_flags);
1672 outb(DAC(chan), dev->iobase + DAS1800_SELECT); /* select dac channel for baseAddress + 0x0 */
1673 outw(output, dev->iobase + DAS1800_DAC);
1674 /* now we need to write to 'update' channel to update all dac channels */
1675 if (chan != update_chan) {
1676 outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); /* select 'update' channel for baseAddress + 0x0 */
1677 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
1679 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1684 /* reads from digital input channels */
1685 static int das1800_di_rbits(struct comedi_device *dev,
1686 struct comedi_subdevice *s,
1687 struct comedi_insn *insn, unsigned int *data)
1690 data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf;
1696 /* writes to digital output channels */
1697 static int das1800_do_wbits(struct comedi_device *dev,
1698 struct comedi_subdevice *s,
1699 struct comedi_insn *insn, unsigned int *data)
1703 /* only set bits that have been masked */
1704 data[0] &= (1 << s->n_chan) - 1;
1705 wbits = devpriv->do_bits;
1707 wbits |= data[0] & data[1];
1708 devpriv->do_bits = wbits;
1710 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
1712 data[1] = devpriv->do_bits;
1717 /* loads counters with divisor1, divisor2 from private structure */
1718 static int das1800_set_frequency(struct comedi_device *dev)
1722 /* counter 1, mode 2 */
1723 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1,
1726 /* counter 2, mode 2 */
1727 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2,
1736 /* converts requested conversion timing to timing compatible with
1737 * hardware, used only when card is in 'burst mode'
1739 static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode)
1741 unsigned int micro_sec;
1743 /* in burst mode, the maximum conversion time is 64 microseconds */
1744 if (convert_arg > 64000)
1745 convert_arg = 64000;
1747 /* the conversion time must be an integral number of microseconds */
1748 switch (round_mode) {
1749 case TRIG_ROUND_NEAREST:
1751 micro_sec = (convert_arg + 500) / 1000;
1753 case TRIG_ROUND_DOWN:
1754 micro_sec = convert_arg / 1000;
1757 micro_sec = (convert_arg - 1) / 1000 + 1;
1761 /* return number of nanoseconds */
1762 return micro_sec * 1000;
1765 /* utility function that suggests a dma transfer size based on the conversion period 'ns' */
1766 static unsigned int suggest_transfer_size(struct comedi_cmd *cmd)
1768 unsigned int size = DMA_BUF_SIZE;
1769 static const int sample_size = 2; /* size in bytes of one sample from board */
1770 unsigned int fill_time = 300000000; /* target time in nanoseconds for filling dma buffer */
1771 unsigned int max_size; /* maximum size we will allow for a transfer */
1773 /* make dma buffer fill in 0.3 seconds for timed modes */
1774 switch (cmd->scan_begin_src) {
1775 case TRIG_FOLLOW: /* not in burst mode */
1776 if (cmd->convert_src == TRIG_TIMER)
1777 size = (fill_time / cmd->convert_arg) * sample_size;
1780 size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) *
1784 size = DMA_BUF_SIZE;
1788 /* set a minimum and maximum size allowed */
1789 max_size = DMA_BUF_SIZE;
1790 /* if we are taking limited number of conversions, limit transfer size to that */
1791 if (cmd->stop_src == TRIG_COUNT &&
1792 cmd->stop_arg * cmd->chanlist_len * sample_size < max_size)
1793 max_size = cmd->stop_arg * cmd->chanlist_len * sample_size;
1795 if (size > max_size)
1797 if (size < sample_size)