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 kfree(devpriv->ai_buf0);
801 kfree(devpriv->ai_buf1);
804 printk("comedi%d: %s: remove\n", dev->minor,
805 driver_das1800.driver_name);
810 /* probes and checks das-1800 series board type
812 static int das1800_probe(struct comedi_device *dev)
817 id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */
818 board = ((struct das1800_board *)dev->board_ptr) - das1800_boards;
822 if (board == das1801st_da || board == das1802st_da ||
823 board == das1701st_da || board == das1702st_da) {
824 printk(" Board model: %s\n",
825 das1800_boards[board].name);
829 (" Board model (probed, not recommended): das-1800st-da series\n");
833 if (board == das1802hr_da || board == das1702hr_da) {
834 printk(" Board model: %s\n",
835 das1800_boards[board].name);
839 (" Board model (probed, not recommended): das-1802hr-da\n");
843 if (board == das1801ao || board == das1802ao ||
844 board == das1701ao || board == das1702ao) {
845 printk(" Board model: %s\n",
846 das1800_boards[board].name);
850 (" Board model (probed, not recommended): das-1800ao series\n");
854 if (board == das1802hr || board == das1702hr) {
855 printk(" Board model: %s\n",
856 das1800_boards[board].name);
859 printk(" Board model (probed, not recommended): das-1802hr\n");
863 if (board == das1801st || board == das1802st ||
864 board == das1701st || board == das1702st) {
865 printk(" Board model: %s\n",
866 das1800_boards[board].name);
870 (" Board model (probed, not recommended): das-1800st series\n");
874 if (board == das1801hc || board == das1802hc) {
875 printk(" Board model: %s\n",
876 das1800_boards[board].name);
880 (" Board model (probed, not recommended): das-1800hc series\n");
885 (" Board model: probe returned 0x%x (unknown, please report)\n",
893 static int das1800_ai_poll(struct comedi_device *dev,
894 struct comedi_subdevice *s)
898 /* prevent race with interrupt handler */
899 spin_lock_irqsave(&dev->spinlock, flags);
900 das1800_ai_handler(dev);
901 spin_unlock_irqrestore(&dev->spinlock, flags);
903 return s->async->buf_write_count - s->async->buf_read_count;
906 static irqreturn_t das1800_interrupt(int irq, void *d)
908 struct comedi_device *dev = d;
911 if (dev->attached == 0) {
912 comedi_error(dev, "premature interrupt");
916 /* Prevent race with das1800_ai_poll() on multi processor systems.
917 * Also protects indirect addressing in das1800_ai_handler */
918 spin_lock(&dev->spinlock);
919 status = inb(dev->iobase + DAS1800_STATUS);
921 /* if interrupt was not caused by das-1800 */
922 if (!(status & INT)) {
923 spin_unlock(&dev->spinlock);
926 /* clear the interrupt status bit INT */
927 outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
928 /* handle interrupt */
929 das1800_ai_handler(dev);
931 spin_unlock(&dev->spinlock);
935 /* the guts of the interrupt handler, that is shared with das1800_ai_poll */
936 static void das1800_ai_handler(struct comedi_device *dev)
938 struct comedi_subdevice *s = dev->subdevices + 0; /* analog input subdevice */
939 struct comedi_async *async = s->async;
940 struct comedi_cmd *cmd = &async->cmd;
941 unsigned int status = inb(dev->iobase + DAS1800_STATUS);
944 /* select adc for base address + 0 */
945 outb(ADC, dev->iobase + DAS1800_SELECT);
946 /* dma buffer full */
947 if (devpriv->irq_dma_bits & DMA_ENABLED) {
948 /* look for data from dma transfer even if dma terminal count hasn't happened yet */
949 das1800_handle_dma(dev, s, status);
950 } else if (status & FHF) { /* if fifo half full */
951 das1800_handle_fifo_half_full(dev, s);
952 } else if (status & FNE) { /* if fifo not empty */
953 das1800_handle_fifo_not_empty(dev, s);
956 async->events |= COMEDI_CB_BLOCK;
957 /* if the card's fifo has overflowed */
959 /* clear OVF interrupt bit */
960 outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
961 comedi_error(dev, "DAS1800 FIFO overflow");
962 das1800_cancel(dev, s);
963 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
964 comedi_event(dev, s);
967 /* stop taking data if appropriate */
968 /* stop_src TRIG_EXT */
969 if (status & CT0TC) {
970 /* clear CT0TC interrupt bit */
971 outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
972 /* make sure we get all remaining data from board before quitting */
973 if (devpriv->irq_dma_bits & DMA_ENABLED)
974 das1800_flush_dma(dev, s);
976 das1800_handle_fifo_not_empty(dev, s);
977 das1800_cancel(dev, s); /* disable hardware conversions */
978 async->events |= COMEDI_CB_EOA;
979 } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { /* stop_src TRIG_COUNT */
980 das1800_cancel(dev, s); /* disable hardware conversions */
981 async->events |= COMEDI_CB_EOA;
984 comedi_event(dev, s);
989 static void das1800_handle_dma(struct comedi_device *dev,
990 struct comedi_subdevice *s, unsigned int status)
993 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
995 flags = claim_dma_lock();
996 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
997 devpriv->dma_current_buf);
998 /* re-enable dma channel */
999 set_dma_addr(devpriv->dma_current,
1000 virt_to_bus(devpriv->dma_current_buf));
1001 set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size);
1002 enable_dma(devpriv->dma_current);
1003 release_dma_lock(flags);
1005 if (status & DMATC) {
1006 /* clear DMATC interrupt bit */
1007 outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
1008 /* switch dma channels for next time, if appropriate */
1010 /* read data from the other channel next time */
1011 if (devpriv->dma_current == devpriv->dma0) {
1012 devpriv->dma_current = devpriv->dma1;
1013 devpriv->dma_current_buf = devpriv->ai_buf1;
1015 devpriv->dma_current = devpriv->dma0;
1016 devpriv->dma_current_buf = devpriv->ai_buf0;
1024 static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev,
1027 sample += 1 << (thisboard->resolution - 1);
1031 static void munge_data(struct comedi_device *dev, uint16_t * array,
1032 unsigned int num_elements)
1037 /* see if card is using a unipolar or bipolar range so we can munge data correctly */
1038 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
1040 /* convert to unsigned type if we are in a bipolar mode */
1042 for (i = 0; i < num_elements; i++) {
1043 array[i] = munge_bipolar_sample(dev, array[i]);
1048 /* Utility function used by das1800_flush_dma() and das1800_handle_dma().
1049 * Assumes dma lock is held */
1050 static void das1800_flush_dma_channel(struct comedi_device *dev,
1051 struct comedi_subdevice *s,
1052 unsigned int channel, uint16_t * buffer)
1054 unsigned int num_bytes, num_samples;
1055 struct comedi_cmd *cmd = &s->async->cmd;
1057 disable_dma(channel);
1059 /* clear flip-flop to make sure 2-byte registers
1060 * get set correctly */
1061 clear_dma_ff(channel);
1063 /* figure out how many points to read */
1064 num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel);
1065 num_samples = num_bytes / sizeof(short);
1067 /* if we only need some of the points */
1068 if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples)
1069 num_samples = devpriv->count;
1071 munge_data(dev, buffer, num_samples);
1072 cfc_write_array_to_buffer(s, buffer, num_bytes);
1073 if (s->async->cmd.stop_src == TRIG_COUNT)
1074 devpriv->count -= num_samples;
1079 /* flushes remaining data from board when external trigger has stopped aquisition
1080 * and we are using dma transfers */
1081 static void das1800_flush_dma(struct comedi_device *dev,
1082 struct comedi_subdevice *s)
1084 unsigned long flags;
1085 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
1087 flags = claim_dma_lock();
1088 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
1089 devpriv->dma_current_buf);
1092 /* switch to other channel and flush it */
1093 if (devpriv->dma_current == devpriv->dma0) {
1094 devpriv->dma_current = devpriv->dma1;
1095 devpriv->dma_current_buf = devpriv->ai_buf1;
1097 devpriv->dma_current = devpriv->dma0;
1098 devpriv->dma_current_buf = devpriv->ai_buf0;
1100 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
1101 devpriv->dma_current_buf);
1104 release_dma_lock(flags);
1106 /* get any remaining samples in fifo */
1107 das1800_handle_fifo_not_empty(dev, s);
1112 static void das1800_handle_fifo_half_full(struct comedi_device *dev,
1113 struct comedi_subdevice *s)
1115 int numPoints = 0; /* number of points to read */
1116 struct comedi_cmd *cmd = &s->async->cmd;
1118 numPoints = FIFO_SIZE / 2;
1119 /* if we only need some of the points */
1120 if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints)
1121 numPoints = devpriv->count;
1122 insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints);
1123 munge_data(dev, devpriv->ai_buf0, numPoints);
1124 cfc_write_array_to_buffer(s, devpriv->ai_buf0,
1125 numPoints * sizeof(devpriv->ai_buf0[0]));
1126 if (cmd->stop_src == TRIG_COUNT)
1127 devpriv->count -= numPoints;
1131 static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
1132 struct comedi_subdevice *s)
1136 struct comedi_cmd *cmd = &s->async->cmd;
1138 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
1140 while (inb(dev->iobase + DAS1800_STATUS) & FNE) {
1141 if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
1143 dpnt = inw(dev->iobase + DAS1800_FIFO);
1144 /* convert to unsigned type if we are in a bipolar mode */
1146 dpnt = munge_bipolar_sample(dev, dpnt);
1147 cfc_write_to_buffer(s, dpnt);
1148 if (cmd->stop_src == TRIG_COUNT)
1155 static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1157 outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */
1158 outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */
1159 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */
1161 disable_dma(devpriv->dma0);
1163 disable_dma(devpriv->dma1);
1167 /* test analog input cmd */
1168 static int das1800_ai_do_cmdtest(struct comedi_device *dev,
1169 struct comedi_subdevice *s,
1170 struct comedi_cmd *cmd)
1174 unsigned int tmp_arg;
1178 /* step 1: make sure trigger sources are trivially valid */
1180 tmp = cmd->start_src;
1181 cmd->start_src &= TRIG_NOW | TRIG_EXT;
1182 if (!cmd->start_src || tmp != cmd->start_src)
1185 tmp = cmd->scan_begin_src;
1186 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
1187 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1190 tmp = cmd->convert_src;
1191 cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
1192 if (!cmd->convert_src || tmp != cmd->convert_src)
1195 tmp = cmd->scan_end_src;
1196 cmd->scan_end_src &= TRIG_COUNT;
1197 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1200 tmp = cmd->stop_src;
1201 cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
1202 if (!cmd->stop_src || tmp != cmd->stop_src)
1208 /* step 2: make sure trigger sources are unique and mutually compatible */
1210 /* uniqueness check */
1211 if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
1213 if (cmd->scan_begin_src != TRIG_FOLLOW &&
1214 cmd->scan_begin_src != TRIG_TIMER &&
1215 cmd->scan_begin_src != TRIG_EXT)
1217 if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
1219 if (cmd->stop_src != TRIG_COUNT &&
1220 cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
1222 /* compatibility check */
1223 if (cmd->scan_begin_src != TRIG_FOLLOW &&
1224 cmd->convert_src != TRIG_TIMER)
1230 /* step 3: make sure arguments are trivially compatible */
1232 if (cmd->start_arg != 0) {
1236 if (cmd->convert_src == TRIG_TIMER) {
1237 if (cmd->convert_arg < thisboard->ai_speed) {
1238 cmd->convert_arg = thisboard->ai_speed;
1242 if (!cmd->chanlist_len) {
1243 cmd->chanlist_len = 1;
1246 if (cmd->scan_end_arg != cmd->chanlist_len) {
1247 cmd->scan_end_arg = cmd->chanlist_len;
1251 switch (cmd->stop_src) {
1253 if (!cmd->stop_arg) {
1259 if (cmd->stop_arg != 0) {
1271 /* step 4: fix up any arguments */
1273 if (cmd->convert_src == TRIG_TIMER) {
1274 /* if we are not in burst mode */
1275 if (cmd->scan_begin_src == TRIG_FOLLOW) {
1276 tmp_arg = cmd->convert_arg;
1277 /* calculate counter values that give desired timing */
1278 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1279 &(devpriv->divisor1),
1280 &(devpriv->divisor2),
1281 &(cmd->convert_arg),
1283 flags & TRIG_ROUND_MASK);
1284 if (tmp_arg != cmd->convert_arg)
1287 /* if we are in burst mode */
1289 /* check that convert_arg is compatible */
1290 tmp_arg = cmd->convert_arg;
1292 burst_convert_arg(cmd->convert_arg,
1293 cmd->flags & TRIG_ROUND_MASK);
1294 if (tmp_arg != cmd->convert_arg)
1297 if (cmd->scan_begin_src == TRIG_TIMER) {
1298 /* if scans are timed faster than conversion rate allows */
1299 if (cmd->convert_arg * cmd->chanlist_len >
1300 cmd->scan_begin_arg) {
1301 cmd->scan_begin_arg =
1306 tmp_arg = cmd->scan_begin_arg;
1307 /* calculate counter values that give desired timing */
1308 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1318 if (tmp_arg != cmd->scan_begin_arg)
1327 /* make sure user is not trying to mix unipolar and bipolar ranges */
1328 if (cmd->chanlist) {
1329 unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR;
1330 for (i = 1; i < cmd->chanlist_len; i++) {
1331 if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) {
1333 "unipolar and bipolar ranges cannot be mixed in the chanlist");
1346 /* analog input cmd interface */
1348 /* first, some utility functions used in the main ai_do_cmd() */
1350 /* returns appropriate bits for control register a, depending on command */
1351 static int control_a_bits(struct comedi_cmd cmd)
1355 control_a = FFEN; /* enable fifo */
1356 if (cmd.stop_src == TRIG_EXT) {
1359 switch (cmd.start_src) {
1361 control_a |= TGEN | CGSL;
1373 /* returns appropriate bits for control register c, depending on command */
1374 static int control_c_bits(struct comedi_cmd cmd)
1379 /* set clock source to internal or external, select analog reference,
1380 * select unipolar / bipolar
1382 aref = CR_AREF(cmd.chanlist[0]);
1383 control_c = UQEN; /* enable upper qram addresses */
1384 if (aref != AREF_DIFF)
1386 if (aref == AREF_COMMON)
1388 /* if a unipolar range was selected */
1389 if (CR_RANGE(cmd.chanlist[0]) & UNIPOLAR)
1391 switch (cmd.scan_begin_src) {
1392 case TRIG_FOLLOW: /* not in burst mode */
1393 switch (cmd.convert_src) {
1395 /* trig on cascaded counters */
1399 /* trig on falling edge of external trigger */
1407 /* burst mode with internal pacer clock */
1408 control_c |= BMDE | IPCLK;
1411 /* burst mode with external trigger */
1412 control_c |= BMDE | XPCLK;
1421 /* sets up counters */
1422 static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd)
1424 /* setup cascaded counters for conversion/scan frequency */
1425 switch (cmd.scan_begin_src) {
1426 case TRIG_FOLLOW: /* not in burst mode */
1427 if (cmd.convert_src == TRIG_TIMER) {
1428 /* set conversion frequency */
1429 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1430 &(devpriv->divisor1),
1431 &(devpriv->divisor2),
1434 flags & TRIG_ROUND_MASK);
1435 if (das1800_set_frequency(dev) < 0) {
1440 case TRIG_TIMER: /* in burst mode */
1441 /* set scan frequency */
1442 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
1443 &(devpriv->divisor2),
1444 &(cmd.scan_begin_arg),
1445 cmd.flags & TRIG_ROUND_MASK);
1446 if (das1800_set_frequency(dev) < 0) {
1454 /* setup counter 0 for 'about triggering' */
1455 if (cmd.stop_src == TRIG_EXT) {
1456 /* load counter 0 in mode 0 */
1457 i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0);
1464 static void setup_dma(struct comedi_device *dev, struct comedi_cmd cmd)
1466 unsigned long lock_flags;
1467 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
1469 if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
1472 /* determine a reasonable dma transfer size */
1473 devpriv->dma_transfer_size = suggest_transfer_size(&cmd);
1474 lock_flags = claim_dma_lock();
1475 disable_dma(devpriv->dma0);
1476 /* clear flip-flop to make sure 2-byte registers for
1477 * count and address get set correctly */
1478 clear_dma_ff(devpriv->dma0);
1479 set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0));
1480 /* set appropriate size of transfer */
1481 set_dma_count(devpriv->dma0, devpriv->dma_transfer_size);
1482 devpriv->dma_current = devpriv->dma0;
1483 devpriv->dma_current_buf = devpriv->ai_buf0;
1484 enable_dma(devpriv->dma0);
1485 /* set up dual dma if appropriate */
1487 disable_dma(devpriv->dma1);
1488 /* clear flip-flop to make sure 2-byte registers for
1489 * count and address get set correctly */
1490 clear_dma_ff(devpriv->dma1);
1491 set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1));
1492 /* set appropriate size of transfer */
1493 set_dma_count(devpriv->dma1, devpriv->dma_transfer_size);
1494 enable_dma(devpriv->dma1);
1496 release_dma_lock(lock_flags);
1501 /* programs channel/gain list into card */
1502 static void program_chanlist(struct comedi_device *dev, struct comedi_cmd cmd)
1504 int i, n, chan_range;
1505 unsigned long irq_flags;
1506 const int range_mask = 0x3; /* masks unipolar/bipolar bit off range */
1507 const int range_bitshift = 8;
1509 n = cmd.chanlist_len;
1510 /* spinlock protects indirect addressing */
1511 spin_lock_irqsave(&dev->spinlock, irq_flags);
1512 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
1513 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */
1514 /* make channel / gain list */
1515 for (i = 0; i < n; i++) {
1518 chanlist[i]) | ((CR_RANGE(cmd.chanlist[i]) &
1519 range_mask) << range_bitshift);
1520 outw(chan_range, dev->iobase + DAS1800_QRAM);
1522 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
1523 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1528 /* analog input do_cmd */
1529 static int das1800_ai_do_cmd(struct comedi_device *dev,
1530 struct comedi_subdevice *s)
1533 int control_a, control_c;
1534 struct comedi_async *async = s->async;
1535 struct comedi_cmd cmd = async->cmd;
1539 "no irq assigned for das-1800, cannot do hardware conversions");
1543 /* disable dma on TRIG_WAKE_EOS, or TRIG_RT
1544 * (because dma in handler is unsafe at hard real-time priority) */
1545 if (cmd.flags & (TRIG_WAKE_EOS | TRIG_RT)) {
1546 devpriv->irq_dma_bits &= ~DMA_ENABLED;
1548 devpriv->irq_dma_bits |= devpriv->dma_bits;
1550 /* interrupt on end of conversion for TRIG_WAKE_EOS */
1551 if (cmd.flags & TRIG_WAKE_EOS) {
1552 /* interrupt fifo not empty */
1553 devpriv->irq_dma_bits &= ~FIMD;
1555 /* interrupt fifo half full */
1556 devpriv->irq_dma_bits |= FIMD;
1558 /* determine how many conversions we need */
1559 if (cmd.stop_src == TRIG_COUNT) {
1560 devpriv->count = cmd.stop_arg * cmd.chanlist_len;
1563 das1800_cancel(dev, s);
1565 /* determine proper bits for control registers */
1566 control_a = control_a_bits(cmd);
1567 control_c = control_c_bits(cmd);
1569 /* setup card and start */
1570 program_chanlist(dev, cmd);
1571 ret = setup_counters(dev, cmd);
1573 comedi_error(dev, "Error setting up counters");
1576 setup_dma(dev, cmd);
1577 outb(control_c, dev->iobase + DAS1800_CONTROL_C);
1578 /* set conversion rate and length for burst mode */
1579 if (control_c & BMDE) {
1580 /* program conversion period with number of microseconds minus 1 */
1581 outb(cmd.convert_arg / 1000 - 1,
1582 dev->iobase + DAS1800_BURST_RATE);
1583 outb(cmd.chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
1585 outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); /* enable irq/dma */
1586 outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */
1587 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
1592 /* read analog input */
1593 static int das1800_ai_rinsn(struct comedi_device *dev,
1594 struct comedi_subdevice *s,
1595 struct comedi_insn *insn, unsigned int *data)
1598 int chan, range, aref, chan_range;
1602 unsigned long irq_flags;
1604 /* set up analog reference and unipolar / bipolar mode */
1605 aref = CR_AREF(insn->chanspec);
1607 if (aref != AREF_DIFF)
1609 if (aref == AREF_COMMON)
1611 /* if a unipolar range was selected */
1612 if (CR_RANGE(insn->chanspec) & UNIPOLAR)
1615 outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */
1616 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
1617 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */
1618 outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
1620 chan = CR_CHAN(insn->chanspec);
1621 /* mask of unipolar/bipolar bit from range */
1622 range = CR_RANGE(insn->chanspec) & 0x3;
1623 chan_range = chan | (range << 8);
1624 spin_lock_irqsave(&dev->spinlock, irq_flags);
1625 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
1626 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */
1627 outw(chan_range, dev->iobase + DAS1800_QRAM);
1628 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
1629 outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */
1631 for (n = 0; n < insn->n; n++) {
1632 /* trigger conversion */
1633 outb(0, dev->iobase + DAS1800_FIFO);
1634 for (i = 0; i < timeout; i++) {
1635 if (inb(dev->iobase + DAS1800_STATUS) & FNE)
1639 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);
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)