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 "../comedidev.h"
107 #include <linux/ioport.h>
111 #include "comedi_fc.h"
114 #define DAS1800_SIZE 16 /* uses 16 io addresses */
115 #define FIFO_SIZE 1024 /* 1024 sample fifo */
116 #define TIMER_BASE 200 /* 5 Mhz master clock */
117 #define UNIPOLAR 0x4 /* bit that determines whether input range is uni/bipolar */
118 #define DMA_BUF_SIZE 0x1ff00 /* size in bytes of dma buffers */
120 /* Registers for the das1800 */
121 #define DAS1800_FIFO 0x0
122 #define DAS1800_QRAM 0x0
123 #define DAS1800_DAC 0x0
124 #define DAS1800_SELECT 0x2
127 #define DAC(a) (0x2 + a)
128 #define DAS1800_DIGITAL 0x3
129 #define DAS1800_CONTROL_A 0x4
136 #define DAS1800_CONTROL_B 0x5
140 #define DMA_CH5_CH6 0x5
141 #define DMA_CH6_CH7 0x6
142 #define DMA_CH7_CH5 0x7
143 #define DMA_ENABLED 0x3 /* mask used to determine if dma is enabled */
152 #define DAS1800_CONTROL_C 0X6
160 #define DAS1800_STATUS 0x7
161 /* bits that prevent interrupt status bits (and CVEN) from being cleared on write */
162 #define CLEAR_INTR_MASK (CVEN_MASK | 0x1f)
169 #define CVEN_MASK 0x40 /* masks CVEN on write */
171 #define DAS1800_BURST_LENGTH 0x8
172 #define DAS1800_BURST_RATE 0x9
173 #define DAS1800_QRAM_ADDRESS 0xa
174 #define DAS1800_COUNTER 0xc
176 #define IOBASE2 0x400 /* offset of additional ioports used on 'ao' cards */
179 das1701st, das1701st_da, das1702st, das1702st_da, das1702hr,
181 das1701ao, das1702ao, das1801st, das1801st_da, das1802st, das1802st_da,
182 das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao
185 static int das1800_attach(struct comedi_device *dev,
186 struct comedi_devconfig *it);
187 static int das1800_detach(struct comedi_device *dev);
188 static int das1800_probe(struct comedi_device *dev);
189 static int das1800_cancel(struct comedi_device *dev,
190 struct comedi_subdevice *s);
191 static irqreturn_t das1800_interrupt(int irq, void *d);
192 static int das1800_ai_poll(struct comedi_device *dev,
193 struct comedi_subdevice *s);
194 static void das1800_ai_handler(struct comedi_device *dev);
195 static void das1800_handle_dma(struct comedi_device *dev,
196 struct comedi_subdevice *s, unsigned int status);
197 static void das1800_flush_dma(struct comedi_device *dev,
198 struct comedi_subdevice *s);
199 static void das1800_flush_dma_channel(struct comedi_device *dev,
200 struct comedi_subdevice *s,
201 unsigned int channel, uint16_t * buffer);
202 static void das1800_handle_fifo_half_full(struct comedi_device *dev,
203 struct comedi_subdevice *s);
204 static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
205 struct comedi_subdevice *s);
206 static int das1800_ai_do_cmdtest(struct comedi_device *dev,
207 struct comedi_subdevice *s,
208 struct comedi_cmd *cmd);
209 static int das1800_ai_do_cmd(struct comedi_device *dev,
210 struct comedi_subdevice *s);
211 static int das1800_ai_rinsn(struct comedi_device *dev,
212 struct comedi_subdevice *s,
213 struct comedi_insn *insn, unsigned int *data);
214 static int das1800_ao_winsn(struct comedi_device *dev,
215 struct comedi_subdevice *s,
216 struct comedi_insn *insn, unsigned int *data);
217 static int das1800_di_rbits(struct comedi_device *dev,
218 struct comedi_subdevice *s,
219 struct comedi_insn *insn, unsigned int *data);
220 static int das1800_do_wbits(struct comedi_device *dev,
221 struct comedi_subdevice *s,
222 struct comedi_insn *insn, unsigned int *data);
224 static int das1800_set_frequency(struct comedi_device *dev);
225 static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode);
226 static unsigned int suggest_transfer_size(struct comedi_cmd *cmd);
228 /* analog input ranges */
229 static const struct comedi_lrange range_ai_das1801 = {
243 static const struct comedi_lrange range_ai_das1802 = {
257 struct das1800_board {
259 int ai_speed; /* max conversion period in nanoseconds */
260 int resolution; /* bits of ai resolution */
261 int qram_len; /* length of card's channel / gain queue */
262 int common; /* supports AREF_COMMON flag */
263 int do_n_chan; /* number of digital output channels */
264 int ao_ability; /* 0 == no analog out, 1 == basic analog out, 2 == waveform analog out */
265 int ao_n_chan; /* number of analog out channels */
266 const struct comedi_lrange *range_ai; /* available input ranges */
269 /* Warning: the maximum conversion speeds listed below are
270 * not always achievable depending on board setup (see
273 static const struct das1800_board das1800_boards[] = {
275 .name = "das-1701st",
283 .range_ai = &range_ai_das1801,
286 .name = "das-1701st-da",
294 .range_ai = &range_ai_das1801,
297 .name = "das-1702st",
305 .range_ai = &range_ai_das1802,
308 .name = "das-1702st-da",
316 .range_ai = &range_ai_das1802,
319 .name = "das-1702hr",
327 .range_ai = &range_ai_das1802,
330 .name = "das-1702hr-da",
338 .range_ai = &range_ai_das1802,
341 .name = "das-1701ao",
349 .range_ai = &range_ai_das1801,
352 .name = "das-1702ao",
360 .range_ai = &range_ai_das1802,
363 .name = "das-1801st",
371 .range_ai = &range_ai_das1801,
374 .name = "das-1801st-da",
382 .range_ai = &range_ai_das1801,
385 .name = "das-1802st",
393 .range_ai = &range_ai_das1802,
396 .name = "das-1802st-da",
404 .range_ai = &range_ai_das1802,
407 .name = "das-1802hr",
415 .range_ai = &range_ai_das1802,
418 .name = "das-1802hr-da",
426 .range_ai = &range_ai_das1802,
429 .name = "das-1801hc",
437 .range_ai = &range_ai_das1801,
440 .name = "das-1802hc",
448 .range_ai = &range_ai_das1802,
451 .name = "das-1801ao",
459 .range_ai = &range_ai_das1801,
462 .name = "das-1802ao",
470 .range_ai = &range_ai_das1802,
475 * Useful for shorthand access to the particular board structure
477 #define thisboard ((const struct das1800_board *)dev->board_ptr)
479 struct das1800_private {
480 volatile unsigned int count; /* number of data points left to be taken */
481 unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */
482 unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */
483 int do_bits; /* digital output bits */
484 int irq_dma_bits; /* bits for control register b */
485 /* dma bits for control register b, stored so that dma can be
486 * turned on and off */
488 unsigned int dma0; /* dma channels used */
490 volatile unsigned int dma_current; /* dma channel currently in use */
491 uint16_t *ai_buf0; /* pointers to dma buffers */
493 uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */
494 unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */
495 unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */
496 short ao_update_bits; /* remembers the last write to the 'update' dac */
499 #define devpriv ((struct das1800_private *)dev->private)
501 /* analog out range for boards with basic analog out */
502 static const struct comedi_lrange range_ao_1 = {
509 /* analog out range for 'ao' boards */
511 static const struct comedi_lrange range_ao_2 = {
520 static struct comedi_driver driver_das1800 = {
521 .driver_name = "das1800",
522 .module = THIS_MODULE,
523 .attach = das1800_attach,
524 .detach = das1800_detach,
525 .num_names = ARRAY_SIZE(das1800_boards),
526 .board_name = &das1800_boards[0].name,
527 .offset = sizeof(struct das1800_board),
531 * A convenient macro that defines init_module() and cleanup_module(),
534 COMEDI_INITCLEANUP(driver_das1800);
536 static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
541 /* need an irq to do dma */
542 if (dev->irq && dma0) {
543 /* encode dma0 and dma1 into 2 digit hexadecimal for switch */
544 switch ((dma0 & 0x7) | (dma1 << 4)) {
545 case 0x5: /* dma0 == 5 */
546 devpriv->dma_bits |= DMA_CH5;
548 case 0x6: /* dma0 == 6 */
549 devpriv->dma_bits |= DMA_CH6;
551 case 0x7: /* dma0 == 7 */
552 devpriv->dma_bits |= DMA_CH7;
554 case 0x65: /* dma0 == 5, dma1 == 6 */
555 devpriv->dma_bits |= DMA_CH5_CH6;
557 case 0x76: /* dma0 == 6, dma1 == 7 */
558 devpriv->dma_bits |= DMA_CH6_CH7;
560 case 0x57: /* dma0 == 7, dma1 == 5 */
561 devpriv->dma_bits |= DMA_CH7_CH5;
564 printk(" only supports dma channels 5 through 7\n"
565 " Dual dma only allows the following combinations:\n"
566 " dma 5,6 / 6,7 / or 7,5\n");
570 if (request_dma(dma0, driver_das1800.driver_name)) {
571 printk(" failed to allocate dma channel %i\n", dma0);
574 devpriv->dma0 = dma0;
575 devpriv->dma_current = dma0;
577 if (request_dma(dma1, driver_das1800.driver_name)) {
578 printk(" failed to allocate dma channel %i\n",
582 devpriv->dma1 = dma1;
584 devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
585 if (devpriv->ai_buf0 == NULL)
587 devpriv->dma_current_buf = devpriv->ai_buf0;
590 kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
591 if (devpriv->ai_buf1 == NULL)
594 flags = claim_dma_lock();
595 disable_dma(devpriv->dma0);
596 set_dma_mode(devpriv->dma0, DMA_MODE_READ);
598 disable_dma(devpriv->dma1);
599 set_dma_mode(devpriv->dma1, DMA_MODE_READ);
601 release_dma_lock(flags);
606 static int das1800_attach(struct comedi_device *dev,
607 struct comedi_devconfig *it)
609 struct comedi_subdevice *s;
610 unsigned long iobase = it->options[0];
611 unsigned int irq = it->options[1];
612 unsigned int dma0 = it->options[2];
613 unsigned int dma1 = it->options[3];
614 unsigned long iobase2;
618 /* allocate and initialize dev->private */
619 if (alloc_private(dev, sizeof(struct das1800_private)) < 0)
622 printk("comedi%d: %s: io 0x%lx", dev->minor, driver_das1800.driver_name,
625 printk(", irq %u", irq);
627 printk(", dma %u", dma0);
629 printk(" and %u", dma1);
635 printk(" io base address required\n");
639 /* check if io addresses are available */
640 if (!request_region(iobase, DAS1800_SIZE, driver_das1800.driver_name)) {
642 (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
643 iobase, iobase + DAS1800_SIZE - 1);
646 dev->iobase = iobase;
648 board = das1800_probe(dev);
650 printk(" unable to determine board type\n");
654 dev->board_ptr = das1800_boards + board;
655 dev->board_name = thisboard->name;
657 /* if it is an 'ao' board with fancy analog out then we need extra io ports */
658 if (thisboard->ao_ability == 2) {
659 iobase2 = iobase + IOBASE2;
660 if (!request_region(iobase2, DAS1800_SIZE,
661 driver_das1800.driver_name)) {
663 (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
664 iobase2, iobase2 + DAS1800_SIZE - 1);
667 devpriv->iobase2 = iobase2;
672 if (request_irq(irq, das1800_interrupt, 0,
673 driver_das1800.driver_name, dev)) {
674 printk(" unable to allocate irq %u\n", irq);
680 /* set bits that tell card which irq to use */
685 devpriv->irq_dma_bits |= 0x8;
688 devpriv->irq_dma_bits |= 0x10;
691 devpriv->irq_dma_bits |= 0x18;
694 devpriv->irq_dma_bits |= 0x28;
697 devpriv->irq_dma_bits |= 0x30;
700 devpriv->irq_dma_bits |= 0x38;
703 printk(" irq out of range\n");
708 retval = das1800_init_dma(dev, dma0, dma1);
712 if (devpriv->ai_buf0 == NULL) {
714 kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL);
715 if (devpriv->ai_buf0 == NULL)
719 if (alloc_subdevices(dev, 4) < 0)
722 /* analog input subdevice */
723 s = dev->subdevices + 0;
724 dev->read_subdev = s;
725 s->type = COMEDI_SUBD_AI;
726 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ;
727 if (thisboard->common)
728 s->subdev_flags |= SDF_COMMON;
729 s->n_chan = thisboard->qram_len;
730 s->len_chanlist = thisboard->qram_len;
731 s->maxdata = (1 << thisboard->resolution) - 1;
732 s->range_table = thisboard->range_ai;
733 s->do_cmd = das1800_ai_do_cmd;
734 s->do_cmdtest = das1800_ai_do_cmdtest;
735 s->insn_read = das1800_ai_rinsn;
736 s->poll = das1800_ai_poll;
737 s->cancel = das1800_cancel;
740 s = dev->subdevices + 1;
741 if (thisboard->ao_ability == 1) {
742 s->type = COMEDI_SUBD_AO;
743 s->subdev_flags = SDF_WRITABLE;
744 s->n_chan = thisboard->ao_n_chan;
745 s->maxdata = (1 << thisboard->resolution) - 1;
746 s->range_table = &range_ao_1;
747 s->insn_write = das1800_ao_winsn;
749 s->type = COMEDI_SUBD_UNUSED;
753 s = dev->subdevices + 2;
754 s->type = COMEDI_SUBD_DI;
755 s->subdev_flags = SDF_READABLE;
758 s->range_table = &range_digital;
759 s->insn_bits = das1800_di_rbits;
762 s = dev->subdevices + 3;
763 s->type = COMEDI_SUBD_DO;
764 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
765 s->n_chan = thisboard->do_n_chan;
767 s->range_table = &range_digital;
768 s->insn_bits = das1800_do_wbits;
770 das1800_cancel(dev, dev->read_subdev);
772 /* initialize digital out channels */
773 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
775 /* initialize analog out channels */
776 if (thisboard->ao_ability == 1) {
777 /* select 'update' dac channel for baseAddress + 0x0 */
778 outb(DAC(thisboard->ao_n_chan - 1),
779 dev->iobase + DAS1800_SELECT);
780 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
786 static int das1800_detach(struct comedi_device *dev)
788 /* only free stuff if it has been allocated by _attach */
790 release_region(dev->iobase, DAS1800_SIZE);
792 free_irq(dev->irq, dev);
794 if (devpriv->iobase2)
795 release_region(devpriv->iobase2, DAS1800_SIZE);
797 free_dma(devpriv->dma0);
799 free_dma(devpriv->dma1);
800 if (devpriv->ai_buf0)
801 kfree(devpriv->ai_buf0);
802 if (devpriv->ai_buf1)
803 kfree(devpriv->ai_buf1);
806 printk("comedi%d: %s: remove\n", dev->minor,
807 driver_das1800.driver_name);
812 /* probes and checks das-1800 series board type
814 static int das1800_probe(struct comedi_device *dev)
819 id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */
820 board = ((struct das1800_board *)dev->board_ptr) - das1800_boards;
824 if (board == das1801st_da || board == das1802st_da ||
825 board == das1701st_da || board == das1702st_da) {
826 printk(" Board model: %s\n",
827 das1800_boards[board].name);
831 (" Board model (probed, not recommended): das-1800st-da series\n");
835 if (board == das1802hr_da || board == das1702hr_da) {
836 printk(" Board model: %s\n",
837 das1800_boards[board].name);
841 (" Board model (probed, not recommended): das-1802hr-da\n");
845 if (board == das1801ao || board == das1802ao ||
846 board == das1701ao || board == das1702ao) {
847 printk(" Board model: %s\n",
848 das1800_boards[board].name);
852 (" Board model (probed, not recommended): das-1800ao series\n");
856 if (board == das1802hr || board == das1702hr) {
857 printk(" Board model: %s\n",
858 das1800_boards[board].name);
861 printk(" Board model (probed, not recommended): das-1802hr\n");
865 if (board == das1801st || board == das1802st ||
866 board == das1701st || board == das1702st) {
867 printk(" Board model: %s\n",
868 das1800_boards[board].name);
872 (" Board model (probed, not recommended): das-1800st series\n");
876 if (board == das1801hc || board == das1802hc) {
877 printk(" Board model: %s\n",
878 das1800_boards[board].name);
882 (" Board model (probed, not recommended): das-1800hc series\n");
887 (" Board model: probe returned 0x%x (unknown, please report)\n",
895 static int das1800_ai_poll(struct comedi_device *dev,
896 struct comedi_subdevice *s)
900 /* prevent race with interrupt handler */
901 spin_lock_irqsave(&dev->spinlock, flags);
902 das1800_ai_handler(dev);
903 spin_unlock_irqrestore(&dev->spinlock, flags);
905 return s->async->buf_write_count - s->async->buf_read_count;
908 static irqreturn_t das1800_interrupt(int irq, void *d)
910 struct comedi_device *dev = d;
913 if (dev->attached == 0) {
914 comedi_error(dev, "premature interrupt");
918 /* Prevent race with das1800_ai_poll() on multi processor systems.
919 * Also protects indirect addressing in das1800_ai_handler */
920 spin_lock(&dev->spinlock);
921 status = inb(dev->iobase + DAS1800_STATUS);
923 /* if interrupt was not caused by das-1800 */
924 if (!(status & INT)) {
925 spin_unlock(&dev->spinlock);
928 /* clear the interrupt status bit INT */
929 outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
930 /* handle interrupt */
931 das1800_ai_handler(dev);
933 spin_unlock(&dev->spinlock);
937 /* the guts of the interrupt handler, that is shared with das1800_ai_poll */
938 static void das1800_ai_handler(struct comedi_device *dev)
940 struct comedi_subdevice *s = dev->subdevices + 0; /* analog input subdevice */
941 struct comedi_async *async = s->async;
942 struct comedi_cmd *cmd = &async->cmd;
943 unsigned int status = inb(dev->iobase + DAS1800_STATUS);
946 /* select adc for base address + 0 */
947 outb(ADC, dev->iobase + DAS1800_SELECT);
948 /* dma buffer full */
949 if (devpriv->irq_dma_bits & DMA_ENABLED) {
950 /* look for data from dma transfer even if dma terminal count hasn't happened yet */
951 das1800_handle_dma(dev, s, status);
952 } else if (status & FHF) { /* if fifo half full */
953 das1800_handle_fifo_half_full(dev, s);
954 } else if (status & FNE) { /* if fifo not empty */
955 das1800_handle_fifo_not_empty(dev, s);
958 async->events |= COMEDI_CB_BLOCK;
959 /* if the card's fifo has overflowed */
961 /* clear OVF interrupt bit */
962 outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
963 comedi_error(dev, "DAS1800 FIFO overflow");
964 das1800_cancel(dev, s);
965 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
966 comedi_event(dev, s);
969 /* stop taking data if appropriate */
970 /* stop_src TRIG_EXT */
971 if (status & CT0TC) {
972 /* clear CT0TC interrupt bit */
973 outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
974 /* make sure we get all remaining data from board before quitting */
975 if (devpriv->irq_dma_bits & DMA_ENABLED)
976 das1800_flush_dma(dev, s);
978 das1800_handle_fifo_not_empty(dev, s);
979 das1800_cancel(dev, s); /* disable hardware conversions */
980 async->events |= COMEDI_CB_EOA;
981 } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { /* stop_src TRIG_COUNT */
982 das1800_cancel(dev, s); /* disable hardware conversions */
983 async->events |= COMEDI_CB_EOA;
986 comedi_event(dev, s);
991 static void das1800_handle_dma(struct comedi_device *dev,
992 struct comedi_subdevice *s, unsigned int status)
995 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
997 flags = claim_dma_lock();
998 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
999 devpriv->dma_current_buf);
1000 /* re-enable dma channel */
1001 set_dma_addr(devpriv->dma_current,
1002 virt_to_bus(devpriv->dma_current_buf));
1003 set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size);
1004 enable_dma(devpriv->dma_current);
1005 release_dma_lock(flags);
1007 if (status & DMATC) {
1008 /* clear DMATC interrupt bit */
1009 outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
1010 /* switch dma channels for next time, if appropriate */
1012 /* read data from the other channel next time */
1013 if (devpriv->dma_current == devpriv->dma0) {
1014 devpriv->dma_current = devpriv->dma1;
1015 devpriv->dma_current_buf = devpriv->ai_buf1;
1017 devpriv->dma_current = devpriv->dma0;
1018 devpriv->dma_current_buf = devpriv->ai_buf0;
1026 static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev,
1029 sample += 1 << (thisboard->resolution - 1);
1033 static void munge_data(struct comedi_device *dev, uint16_t * array,
1034 unsigned int num_elements)
1039 /* see if card is using a unipolar or bipolar range so we can munge data correctly */
1040 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
1042 /* convert to unsigned type if we are in a bipolar mode */
1044 for (i = 0; i < num_elements; i++) {
1045 array[i] = munge_bipolar_sample(dev, array[i]);
1050 /* Utility function used by das1800_flush_dma() and das1800_handle_dma().
1051 * Assumes dma lock is held */
1052 static void das1800_flush_dma_channel(struct comedi_device *dev,
1053 struct comedi_subdevice *s,
1054 unsigned int channel, uint16_t * buffer)
1056 unsigned int num_bytes, num_samples;
1057 struct comedi_cmd *cmd = &s->async->cmd;
1059 disable_dma(channel);
1061 /* clear flip-flop to make sure 2-byte registers
1062 * get set correctly */
1063 clear_dma_ff(channel);
1065 /* figure out how many points to read */
1066 num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel);
1067 num_samples = num_bytes / sizeof(short);
1069 /* if we only need some of the points */
1070 if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples)
1071 num_samples = devpriv->count;
1073 munge_data(dev, buffer, num_samples);
1074 cfc_write_array_to_buffer(s, buffer, num_bytes);
1075 if (s->async->cmd.stop_src == TRIG_COUNT)
1076 devpriv->count -= num_samples;
1081 /* flushes remaining data from board when external trigger has stopped aquisition
1082 * and we are using dma transfers */
1083 static void das1800_flush_dma(struct comedi_device *dev,
1084 struct comedi_subdevice *s)
1086 unsigned long flags;
1087 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
1089 flags = claim_dma_lock();
1090 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
1091 devpriv->dma_current_buf);
1094 /* switch to other channel and flush it */
1095 if (devpriv->dma_current == devpriv->dma0) {
1096 devpriv->dma_current = devpriv->dma1;
1097 devpriv->dma_current_buf = devpriv->ai_buf1;
1099 devpriv->dma_current = devpriv->dma0;
1100 devpriv->dma_current_buf = devpriv->ai_buf0;
1102 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
1103 devpriv->dma_current_buf);
1106 release_dma_lock(flags);
1108 /* get any remaining samples in fifo */
1109 das1800_handle_fifo_not_empty(dev, s);
1114 static void das1800_handle_fifo_half_full(struct comedi_device *dev,
1115 struct comedi_subdevice *s)
1117 int numPoints = 0; /* number of points to read */
1118 struct comedi_cmd *cmd = &s->async->cmd;
1120 numPoints = FIFO_SIZE / 2;
1121 /* if we only need some of the points */
1122 if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints)
1123 numPoints = devpriv->count;
1124 insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints);
1125 munge_data(dev, devpriv->ai_buf0, numPoints);
1126 cfc_write_array_to_buffer(s, devpriv->ai_buf0,
1127 numPoints * sizeof(devpriv->ai_buf0[0]));
1128 if (cmd->stop_src == TRIG_COUNT)
1129 devpriv->count -= numPoints;
1133 static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
1134 struct comedi_subdevice *s)
1138 struct comedi_cmd *cmd = &s->async->cmd;
1140 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
1142 while (inb(dev->iobase + DAS1800_STATUS) & FNE) {
1143 if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
1145 dpnt = inw(dev->iobase + DAS1800_FIFO);
1146 /* convert to unsigned type if we are in a bipolar mode */
1148 dpnt = munge_bipolar_sample(dev, dpnt);
1149 cfc_write_to_buffer(s, dpnt);
1150 if (cmd->stop_src == TRIG_COUNT)
1157 static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1159 outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */
1160 outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */
1161 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */
1163 disable_dma(devpriv->dma0);
1165 disable_dma(devpriv->dma1);
1169 /* test analog input cmd */
1170 static int das1800_ai_do_cmdtest(struct comedi_device *dev,
1171 struct comedi_subdevice *s,
1172 struct comedi_cmd *cmd)
1176 unsigned int tmp_arg;
1180 /* step 1: make sure trigger sources are trivially valid */
1182 tmp = cmd->start_src;
1183 cmd->start_src &= TRIG_NOW | TRIG_EXT;
1184 if (!cmd->start_src || tmp != cmd->start_src)
1187 tmp = cmd->scan_begin_src;
1188 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
1189 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1192 tmp = cmd->convert_src;
1193 cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
1194 if (!cmd->convert_src || tmp != cmd->convert_src)
1197 tmp = cmd->scan_end_src;
1198 cmd->scan_end_src &= TRIG_COUNT;
1199 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1202 tmp = cmd->stop_src;
1203 cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
1204 if (!cmd->stop_src || tmp != cmd->stop_src)
1210 /* step 2: make sure trigger sources are unique and mutually compatible */
1212 /* uniqueness check */
1213 if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
1215 if (cmd->scan_begin_src != TRIG_FOLLOW &&
1216 cmd->scan_begin_src != TRIG_TIMER &&
1217 cmd->scan_begin_src != TRIG_EXT)
1219 if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
1221 if (cmd->stop_src != TRIG_COUNT &&
1222 cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
1224 /* compatibility check */
1225 if (cmd->scan_begin_src != TRIG_FOLLOW &&
1226 cmd->convert_src != TRIG_TIMER)
1232 /* step 3: make sure arguments are trivially compatible */
1234 if (cmd->start_arg != 0) {
1238 if (cmd->convert_src == TRIG_TIMER) {
1239 if (cmd->convert_arg < thisboard->ai_speed) {
1240 cmd->convert_arg = thisboard->ai_speed;
1244 if (!cmd->chanlist_len) {
1245 cmd->chanlist_len = 1;
1248 if (cmd->scan_end_arg != cmd->chanlist_len) {
1249 cmd->scan_end_arg = cmd->chanlist_len;
1253 switch (cmd->stop_src) {
1255 if (!cmd->stop_arg) {
1261 if (cmd->stop_arg != 0) {
1273 /* step 4: fix up any arguments */
1275 if (cmd->convert_src == TRIG_TIMER) {
1276 /* if we are not in burst mode */
1277 if (cmd->scan_begin_src == TRIG_FOLLOW) {
1278 tmp_arg = cmd->convert_arg;
1279 /* calculate counter values that give desired timing */
1280 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1281 &(devpriv->divisor1),
1282 &(devpriv->divisor2),
1283 &(cmd->convert_arg),
1285 flags & TRIG_ROUND_MASK);
1286 if (tmp_arg != cmd->convert_arg)
1289 /* if we are in burst mode */
1291 /* check that convert_arg is compatible */
1292 tmp_arg = cmd->convert_arg;
1294 burst_convert_arg(cmd->convert_arg,
1295 cmd->flags & TRIG_ROUND_MASK);
1296 if (tmp_arg != cmd->convert_arg)
1299 if (cmd->scan_begin_src == TRIG_TIMER) {
1300 /* if scans are timed faster than conversion rate allows */
1301 if (cmd->convert_arg * cmd->chanlist_len >
1302 cmd->scan_begin_arg) {
1303 cmd->scan_begin_arg =
1308 tmp_arg = cmd->scan_begin_arg;
1309 /* calculate counter values that give desired timing */
1310 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1320 if (tmp_arg != cmd->scan_begin_arg)
1329 /* make sure user is not trying to mix unipolar and bipolar ranges */
1330 if (cmd->chanlist) {
1331 unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR;
1332 for (i = 1; i < cmd->chanlist_len; i++) {
1333 if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) {
1335 "unipolar and bipolar ranges cannot be mixed in the chanlist");
1348 /* analog input cmd interface */
1350 /* first, some utility functions used in the main ai_do_cmd() */
1352 /* returns appropriate bits for control register a, depending on command */
1353 static int control_a_bits(struct comedi_cmd cmd)
1357 control_a = FFEN; /* enable fifo */
1358 if (cmd.stop_src == TRIG_EXT) {
1361 switch (cmd.start_src) {
1363 control_a |= TGEN | CGSL;
1375 /* returns appropriate bits for control register c, depending on command */
1376 static int control_c_bits(struct comedi_cmd cmd)
1381 /* set clock source to internal or external, select analog reference,
1382 * select unipolar / bipolar
1384 aref = CR_AREF(cmd.chanlist[0]);
1385 control_c = UQEN; /* enable upper qram addresses */
1386 if (aref != AREF_DIFF)
1388 if (aref == AREF_COMMON)
1390 /* if a unipolar range was selected */
1391 if (CR_RANGE(cmd.chanlist[0]) & UNIPOLAR)
1393 switch (cmd.scan_begin_src) {
1394 case TRIG_FOLLOW: /* not in burst mode */
1395 switch (cmd.convert_src) {
1397 /* trig on cascaded counters */
1401 /* trig on falling edge of external trigger */
1409 /* burst mode with internal pacer clock */
1410 control_c |= BMDE | IPCLK;
1413 /* burst mode with external trigger */
1414 control_c |= BMDE | XPCLK;
1423 /* sets up counters */
1424 static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd)
1426 /* setup cascaded counters for conversion/scan frequency */
1427 switch (cmd.scan_begin_src) {
1428 case TRIG_FOLLOW: /* not in burst mode */
1429 if (cmd.convert_src == TRIG_TIMER) {
1430 /* set conversion frequency */
1431 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1432 &(devpriv->divisor1),
1433 &(devpriv->divisor2),
1436 flags & TRIG_ROUND_MASK);
1437 if (das1800_set_frequency(dev) < 0) {
1442 case TRIG_TIMER: /* in burst mode */
1443 /* set scan frequency */
1444 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
1445 &(devpriv->divisor2),
1446 &(cmd.scan_begin_arg),
1447 cmd.flags & TRIG_ROUND_MASK);
1448 if (das1800_set_frequency(dev) < 0) {
1456 /* setup counter 0 for 'about triggering' */
1457 if (cmd.stop_src == TRIG_EXT) {
1458 /* load counter 0 in mode 0 */
1459 i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0);
1466 static void setup_dma(struct comedi_device *dev, struct comedi_cmd cmd)
1468 unsigned long lock_flags;
1469 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
1471 if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
1474 /* determine a reasonable dma transfer size */
1475 devpriv->dma_transfer_size = suggest_transfer_size(&cmd);
1476 lock_flags = claim_dma_lock();
1477 disable_dma(devpriv->dma0);
1478 /* clear flip-flop to make sure 2-byte registers for
1479 * count and address get set correctly */
1480 clear_dma_ff(devpriv->dma0);
1481 set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0));
1482 /* set appropriate size of transfer */
1483 set_dma_count(devpriv->dma0, devpriv->dma_transfer_size);
1484 devpriv->dma_current = devpriv->dma0;
1485 devpriv->dma_current_buf = devpriv->ai_buf0;
1486 enable_dma(devpriv->dma0);
1487 /* set up dual dma if appropriate */
1489 disable_dma(devpriv->dma1);
1490 /* clear flip-flop to make sure 2-byte registers for
1491 * count and address get set correctly */
1492 clear_dma_ff(devpriv->dma1);
1493 set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1));
1494 /* set appropriate size of transfer */
1495 set_dma_count(devpriv->dma1, devpriv->dma_transfer_size);
1496 enable_dma(devpriv->dma1);
1498 release_dma_lock(lock_flags);
1503 /* programs channel/gain list into card */
1504 static void program_chanlist(struct comedi_device *dev, struct comedi_cmd cmd)
1506 int i, n, chan_range;
1507 unsigned long irq_flags;
1508 const int range_mask = 0x3; /* masks unipolar/bipolar bit off range */
1509 const int range_bitshift = 8;
1511 n = cmd.chanlist_len;
1512 /* spinlock protects indirect addressing */
1513 spin_lock_irqsave(&dev->spinlock, irq_flags);
1514 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
1515 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */
1516 /* make channel / gain list */
1517 for (i = 0; i < n; i++) {
1520 chanlist[i]) | ((CR_RANGE(cmd.chanlist[i]) &
1521 range_mask) << range_bitshift);
1522 outw(chan_range, dev->iobase + DAS1800_QRAM);
1524 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
1525 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1530 /* analog input do_cmd */
1531 static int das1800_ai_do_cmd(struct comedi_device *dev,
1532 struct comedi_subdevice *s)
1535 int control_a, control_c;
1536 struct comedi_async *async = s->async;
1537 struct comedi_cmd cmd = async->cmd;
1541 "no irq assigned for das-1800, cannot do hardware conversions");
1545 /* disable dma on TRIG_WAKE_EOS, or TRIG_RT
1546 * (because dma in handler is unsafe at hard real-time priority) */
1547 if (cmd.flags & (TRIG_WAKE_EOS | TRIG_RT)) {
1548 devpriv->irq_dma_bits &= ~DMA_ENABLED;
1550 devpriv->irq_dma_bits |= devpriv->dma_bits;
1552 /* interrupt on end of conversion for TRIG_WAKE_EOS */
1553 if (cmd.flags & TRIG_WAKE_EOS) {
1554 /* interrupt fifo not empty */
1555 devpriv->irq_dma_bits &= ~FIMD;
1557 /* interrupt fifo half full */
1558 devpriv->irq_dma_bits |= FIMD;
1560 /* determine how many conversions we need */
1561 if (cmd.stop_src == TRIG_COUNT) {
1562 devpriv->count = cmd.stop_arg * cmd.chanlist_len;
1565 das1800_cancel(dev, s);
1567 /* determine proper bits for control registers */
1568 control_a = control_a_bits(cmd);
1569 control_c = control_c_bits(cmd);
1571 /* setup card and start */
1572 program_chanlist(dev, cmd);
1573 ret = setup_counters(dev, cmd);
1575 comedi_error(dev, "Error setting up counters");
1578 setup_dma(dev, cmd);
1579 outb(control_c, dev->iobase + DAS1800_CONTROL_C);
1580 /* set conversion rate and length for burst mode */
1581 if (control_c & BMDE) {
1582 /* program conversion period with number of microseconds minus 1 */
1583 outb(cmd.convert_arg / 1000 - 1,
1584 dev->iobase + DAS1800_BURST_RATE);
1585 outb(cmd.chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
1587 outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); /* enable irq/dma */
1588 outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */
1589 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
1594 /* read analog input */
1595 static int das1800_ai_rinsn(struct comedi_device *dev,
1596 struct comedi_subdevice *s,
1597 struct comedi_insn *insn, unsigned int *data)
1600 int chan, range, aref, chan_range;
1604 unsigned long irq_flags;
1606 /* set up analog reference and unipolar / bipolar mode */
1607 aref = CR_AREF(insn->chanspec);
1609 if (aref != AREF_DIFF)
1611 if (aref == AREF_COMMON)
1613 /* if a unipolar range was selected */
1614 if (CR_RANGE(insn->chanspec) & UNIPOLAR)
1617 outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */
1618 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
1619 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */
1620 outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
1622 chan = CR_CHAN(insn->chanspec);
1623 /* mask of unipolar/bipolar bit from range */
1624 range = CR_RANGE(insn->chanspec) & 0x3;
1625 chan_range = chan | (range << 8);
1626 spin_lock_irqsave(&dev->spinlock, irq_flags);
1627 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
1628 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */
1629 outw(chan_range, dev->iobase + DAS1800_QRAM);
1630 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
1631 outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */
1633 for (n = 0; n < insn->n; n++) {
1634 /* trigger conversion */
1635 outb(0, dev->iobase + DAS1800_FIFO);
1636 for (i = 0; i < timeout; i++) {
1637 if (inb(dev->iobase + DAS1800_STATUS) & FNE)
1641 comedi_error(dev, "timeout");
1644 dpnt = inw(dev->iobase + DAS1800_FIFO);
1645 /* shift data to offset binary for bipolar ranges */
1646 if ((conv_flags & UB) == 0)
1647 dpnt += 1 << (thisboard->resolution - 1);
1650 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1655 /* writes to an analog output channel */
1656 static int das1800_ao_winsn(struct comedi_device *dev,
1657 struct comedi_subdevice *s,
1658 struct comedi_insn *insn, unsigned int *data)
1660 int chan = CR_CHAN(insn->chanspec);
1661 /* int range = CR_RANGE(insn->chanspec); */
1662 int update_chan = thisboard->ao_n_chan - 1;
1664 unsigned long irq_flags;
1666 /* card expects two's complement data */
1667 output = data[0] - (1 << (thisboard->resolution - 1));
1668 /* if the write is to the 'update' channel, we need to remember its value */
1669 if (chan == update_chan)
1670 devpriv->ao_update_bits = output;
1671 /* write to channel */
1672 spin_lock_irqsave(&dev->spinlock, irq_flags);
1673 outb(DAC(chan), dev->iobase + DAS1800_SELECT); /* select dac channel for baseAddress + 0x0 */
1674 outw(output, dev->iobase + DAS1800_DAC);
1675 /* now we need to write to 'update' channel to update all dac channels */
1676 if (chan != update_chan) {
1677 outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); /* select 'update' channel for baseAddress + 0x0 */
1678 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
1680 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1685 /* reads from digital input channels */
1686 static int das1800_di_rbits(struct comedi_device *dev,
1687 struct comedi_subdevice *s,
1688 struct comedi_insn *insn, unsigned int *data)
1691 data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf;
1697 /* writes to digital output channels */
1698 static int das1800_do_wbits(struct comedi_device *dev,
1699 struct comedi_subdevice *s,
1700 struct comedi_insn *insn, unsigned int *data)
1704 /* only set bits that have been masked */
1705 data[0] &= (1 << s->n_chan) - 1;
1706 wbits = devpriv->do_bits;
1708 wbits |= data[0] & data[1];
1709 devpriv->do_bits = wbits;
1711 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
1713 data[1] = devpriv->do_bits;
1718 /* loads counters with divisor1, divisor2 from private structure */
1719 static int das1800_set_frequency(struct comedi_device *dev)
1723 /* counter 1, mode 2 */
1724 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1,
1727 /* counter 2, mode 2 */
1728 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2,
1737 /* converts requested conversion timing to timing compatible with
1738 * hardware, used only when card is in 'burst mode'
1740 static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode)
1742 unsigned int micro_sec;
1744 /* in burst mode, the maximum conversion time is 64 microseconds */
1745 if (convert_arg > 64000)
1746 convert_arg = 64000;
1748 /* the conversion time must be an integral number of microseconds */
1749 switch (round_mode) {
1750 case TRIG_ROUND_NEAREST:
1752 micro_sec = (convert_arg + 500) / 1000;
1754 case TRIG_ROUND_DOWN:
1755 micro_sec = convert_arg / 1000;
1758 micro_sec = (convert_arg - 1) / 1000 + 1;
1762 /* return number of nanoseconds */
1763 return micro_sec * 1000;
1766 /* utility function that suggests a dma transfer size based on the conversion period 'ns' */
1767 static unsigned int suggest_transfer_size(struct comedi_cmd *cmd)
1769 unsigned int size = DMA_BUF_SIZE;
1770 static const int sample_size = 2; /* size in bytes of one sample from board */
1771 unsigned int fill_time = 300000000; /* target time in nanoseconds for filling dma buffer */
1772 unsigned int max_size; /* maximum size we will allow for a transfer */
1774 /* make dma buffer fill in 0.3 seconds for timed modes */
1775 switch (cmd->scan_begin_src) {
1776 case TRIG_FOLLOW: /* not in burst mode */
1777 if (cmd->convert_src == TRIG_TIMER)
1778 size = (fill_time / cmd->convert_arg) * sample_size;
1781 size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) *
1785 size = DMA_BUF_SIZE;
1789 /* set a minimum and maximum size allowed */
1790 max_size = DMA_BUF_SIZE;
1791 /* if we are taking limited number of conversions, limit transfer size to that */
1792 if (cmd->stop_src == TRIG_COUNT &&
1793 cmd->stop_arg * cmd->chanlist_len * sample_size < max_size)
1794 max_size = cmd->stop_arg * cmd->chanlist_len * sample_size;
1796 if (size > max_size)
1798 if (size < sample_size)