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 "../comedidev.h"
105 #include <linux/ioport.h>
109 #include "comedi_fc.h"
112 #define DAS1800_SIZE 16 /* uses 16 io addresses */
113 #define FIFO_SIZE 1024 /* 1024 sample fifo */
114 #define TIMER_BASE 200 /* 5 Mhz master clock */
115 #define UNIPOLAR 0x4 /* bit that determines whether input range is uni/bipolar */
116 #define DMA_BUF_SIZE 0x1ff00 /* size in bytes of dma buffers */
118 /* Registers for the das1800 */
119 #define DAS1800_FIFO 0x0
120 #define DAS1800_QRAM 0x0
121 #define DAS1800_DAC 0x0
122 #define DAS1800_SELECT 0x2
125 #define DAC(a) (0x2 + a)
126 #define DAS1800_DIGITAL 0x3
127 #define DAS1800_CONTROL_A 0x4
134 #define DAS1800_CONTROL_B 0x5
138 #define DMA_CH5_CH6 0x5
139 #define DMA_CH6_CH7 0x6
140 #define DMA_CH7_CH5 0x7
141 #define DMA_ENABLED 0x3 /* mask used to determine if dma is enabled */
150 #define DAS1800_CONTROL_C 0X6
158 #define DAS1800_STATUS 0x7
159 /* bits that prevent interrupt status bits (and CVEN) from being cleared on write */
160 #define CLEAR_INTR_MASK (CVEN_MASK | 0x1f)
167 #define CVEN_MASK 0x40 /* masks CVEN on write */
169 #define DAS1800_BURST_LENGTH 0x8
170 #define DAS1800_BURST_RATE 0x9
171 #define DAS1800_QRAM_ADDRESS 0xa
172 #define DAS1800_COUNTER 0xc
174 #define IOBASE2 0x400 /* offset of additional ioports used on 'ao' cards */
177 das1701st, das1701st_da, das1702st, das1702st_da, das1702hr,
179 das1701ao, das1702ao, das1801st, das1801st_da, das1802st, das1802st_da,
180 das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao
183 static int das1800_attach(struct comedi_device * dev, struct comedi_devconfig * it);
184 static int das1800_detach(struct comedi_device * dev);
185 static int das1800_probe(struct comedi_device * dev);
186 static int das1800_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
187 static irqreturn_t das1800_interrupt(int irq, void *d);
188 static int das1800_ai_poll(struct comedi_device * dev, struct comedi_subdevice * s);
189 static void das1800_ai_handler(struct comedi_device * dev);
190 static void das1800_handle_dma(struct comedi_device * dev, struct comedi_subdevice * s,
191 unsigned int status);
192 static void das1800_flush_dma(struct comedi_device * dev, struct comedi_subdevice * s);
193 static void das1800_flush_dma_channel(struct comedi_device * dev, struct comedi_subdevice * s,
194 unsigned int channel, uint16_t * buffer);
195 static void das1800_handle_fifo_half_full(struct comedi_device * dev,
196 struct comedi_subdevice * s);
197 static void das1800_handle_fifo_not_empty(struct comedi_device * dev,
198 struct comedi_subdevice * s);
199 static int das1800_ai_do_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
200 struct comedi_cmd * cmd);
201 static int das1800_ai_do_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
202 static int das1800_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
203 struct comedi_insn * insn, unsigned int * data);
204 static int das1800_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
205 struct comedi_insn * insn, unsigned int * data);
206 static int das1800_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
207 struct comedi_insn * insn, unsigned int * data);
208 static int das1800_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
209 struct comedi_insn * insn, unsigned int * data);
211 static int das1800_set_frequency(struct comedi_device * dev);
212 static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode);
213 static unsigned int suggest_transfer_size(struct comedi_cmd * cmd);
215 /* analog input ranges */
216 static const struct comedi_lrange range_ai_das1801 = {
230 static const struct comedi_lrange range_ai_das1802 = {
244 struct das1800_board {
246 int ai_speed; /* max conversion period in nanoseconds */
247 int resolution; /* bits of ai resolution */
248 int qram_len; /* length of card's channel / gain queue */
249 int common; /* supports AREF_COMMON flag */
250 int do_n_chan; /* number of digital output channels */
251 int ao_ability; /* 0 == no analog out, 1 == basic analog out, 2 == waveform analog out */
252 int ao_n_chan; /* number of analog out channels */
253 const struct comedi_lrange *range_ai; /* available input ranges */
256 /* Warning: the maximum conversion speeds listed below are
257 * not always achievable depending on board setup (see
260 static const struct das1800_board das1800_boards[] = {
270 range_ai:&range_ai_das1801,
273 name: "das-1701st-da",
281 range_ai:&range_ai_das1801,
292 range_ai:&range_ai_das1802,
295 name: "das-1702st-da",
303 range_ai:&range_ai_das1802,
314 range_ai:&range_ai_das1802,
317 name: "das-1702hr-da",
325 range_ai:&range_ai_das1802,
336 range_ai:&range_ai_das1801,
347 range_ai:&range_ai_das1802,
358 range_ai:&range_ai_das1801,
361 name: "das-1801st-da",
369 range_ai:&range_ai_das1801,
380 range_ai:&range_ai_das1802,
383 name: "das-1802st-da",
391 range_ai:&range_ai_das1802,
402 range_ai:&range_ai_das1802,
405 name: "das-1802hr-da",
413 range_ai:&range_ai_das1802,
424 range_ai:&range_ai_das1801,
435 range_ai:&range_ai_das1802,
446 range_ai:&range_ai_das1801,
457 range_ai:&range_ai_das1802,
462 * Useful for shorthand access to the particular board structure
464 #define thisboard ((const struct das1800_board *)dev->board_ptr)
466 struct das1800_private {
467 volatile unsigned int count; /* number of data points left to be taken */
468 unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */
469 unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */
470 int do_bits; /* digital output bits */
471 int irq_dma_bits; /* bits for control register b */
472 /* dma bits for control register b, stored so that dma can be
473 * turned on and off */
475 unsigned int dma0; /* dma channels used */
477 volatile unsigned int dma_current; /* dma channel currently in use */
478 uint16_t *ai_buf0; /* pointers to dma buffers */
480 uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */
481 unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */
482 unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */
483 short ao_update_bits; /* remembers the last write to the 'update' dac */
486 #define devpriv ((struct das1800_private *)dev->private)
488 /* analog out range for boards with basic analog out */
489 static const struct comedi_lrange range_ao_1 = {
496 /* analog out range for 'ao' boards */
498 static const struct comedi_lrange range_ao_2 = {
507 static struct comedi_driver driver_das1800 = {
508 driver_name:"das1800",
510 attach:das1800_attach,
511 detach:das1800_detach,
512 num_names:sizeof(das1800_boards) / sizeof(struct das1800_board),
513 board_name:&das1800_boards[0].name,
514 offset:sizeof(struct das1800_board),
518 * A convenient macro that defines init_module() and cleanup_module(),
521 COMEDI_INITCLEANUP(driver_das1800);
523 static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
528 /* need an irq to do dma */
529 if (dev->irq && dma0) {
530 /* encode dma0 and dma1 into 2 digit hexadecimal for switch */
531 switch ((dma0 & 0x7) | (dma1 << 4)) {
532 case 0x5: /* dma0 == 5 */
533 devpriv->dma_bits |= DMA_CH5;
535 case 0x6: /* dma0 == 6 */
536 devpriv->dma_bits |= DMA_CH6;
538 case 0x7: /* dma0 == 7 */
539 devpriv->dma_bits |= DMA_CH7;
541 case 0x65: /* dma0 == 5, dma1 == 6 */
542 devpriv->dma_bits |= DMA_CH5_CH6;
544 case 0x76: /* dma0 == 6, dma1 == 7 */
545 devpriv->dma_bits |= DMA_CH6_CH7;
547 case 0x57: /* dma0 == 7, dma1 == 5 */
548 devpriv->dma_bits |= DMA_CH7_CH5;
551 printk(" only supports dma channels 5 through 7\n"
552 " Dual dma only allows the following combinations:\n"
553 " dma 5,6 / 6,7 / or 7,5\n");
557 if (request_dma(dma0, driver_das1800.driver_name)) {
558 printk(" failed to allocate dma channel %i\n", dma0);
561 devpriv->dma0 = dma0;
562 devpriv->dma_current = dma0;
564 if (request_dma(dma1, driver_das1800.driver_name)) {
565 printk(" failed to allocate dma channel %i\n",
569 devpriv->dma1 = dma1;
571 devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
572 if (devpriv->ai_buf0 == NULL)
574 devpriv->dma_current_buf = devpriv->ai_buf0;
577 kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
578 if (devpriv->ai_buf1 == NULL)
581 flags = claim_dma_lock();
582 disable_dma(devpriv->dma0);
583 set_dma_mode(devpriv->dma0, DMA_MODE_READ);
585 disable_dma(devpriv->dma1);
586 set_dma_mode(devpriv->dma1, DMA_MODE_READ);
588 release_dma_lock(flags);
593 static int das1800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
595 struct comedi_subdevice *s;
596 unsigned long iobase = it->options[0];
597 unsigned int irq = it->options[1];
598 unsigned int dma0 = it->options[2];
599 unsigned int dma1 = it->options[3];
600 unsigned long iobase2;
604 /* allocate and initialize dev->private */
605 if (alloc_private(dev, sizeof(struct das1800_private)) < 0)
608 printk("comedi%d: %s: io 0x%lx", dev->minor, driver_das1800.driver_name,
611 printk(", irq %u", irq);
613 printk(", dma %u", dma0);
615 printk(" and %u", dma1);
621 printk(" io base address required\n");
625 /* check if io addresses are available */
626 if (!request_region(iobase, DAS1800_SIZE, driver_das1800.driver_name)) {
627 printk(" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", iobase, iobase + DAS1800_SIZE - 1);
630 dev->iobase = iobase;
632 board = das1800_probe(dev);
634 printk(" unable to determine board type\n");
638 dev->board_ptr = das1800_boards + board;
639 dev->board_name = thisboard->name;
641 /* if it is an 'ao' board with fancy analog out then we need extra io ports */
642 if (thisboard->ao_ability == 2) {
643 iobase2 = iobase + IOBASE2;
644 if (!request_region(iobase2, DAS1800_SIZE,
645 driver_das1800.driver_name)) {
646 printk(" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", iobase2, iobase2 + DAS1800_SIZE - 1);
649 devpriv->iobase2 = iobase2;
654 if (comedi_request_irq(irq, das1800_interrupt, 0,
655 driver_das1800.driver_name, dev)) {
656 printk(" unable to allocate irq %u\n", irq);
662 /* set bits that tell card which irq to use */
667 devpriv->irq_dma_bits |= 0x8;
670 devpriv->irq_dma_bits |= 0x10;
673 devpriv->irq_dma_bits |= 0x18;
676 devpriv->irq_dma_bits |= 0x28;
679 devpriv->irq_dma_bits |= 0x30;
682 devpriv->irq_dma_bits |= 0x38;
685 printk(" irq out of range\n");
690 retval = das1800_init_dma(dev, dma0, dma1);
694 if (devpriv->ai_buf0 == NULL) {
696 kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL);
697 if (devpriv->ai_buf0 == NULL)
701 if (alloc_subdevices(dev, 4) < 0)
704 /* analog input subdevice */
705 s = dev->subdevices + 0;
706 dev->read_subdev = s;
707 s->type = COMEDI_SUBD_AI;
708 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ;
709 if (thisboard->common)
710 s->subdev_flags |= SDF_COMMON;
711 s->n_chan = thisboard->qram_len;
712 s->len_chanlist = thisboard->qram_len;
713 s->maxdata = (1 << thisboard->resolution) - 1;
714 s->range_table = thisboard->range_ai;
715 s->do_cmd = das1800_ai_do_cmd;
716 s->do_cmdtest = das1800_ai_do_cmdtest;
717 s->insn_read = das1800_ai_rinsn;
718 s->poll = das1800_ai_poll;
719 s->cancel = das1800_cancel;
722 s = dev->subdevices + 1;
723 if (thisboard->ao_ability == 1) {
724 s->type = COMEDI_SUBD_AO;
725 s->subdev_flags = SDF_WRITABLE;
726 s->n_chan = thisboard->ao_n_chan;
727 s->maxdata = (1 << thisboard->resolution) - 1;
728 s->range_table = &range_ao_1;
729 s->insn_write = das1800_ao_winsn;
731 s->type = COMEDI_SUBD_UNUSED;
735 s = dev->subdevices + 2;
736 s->type = COMEDI_SUBD_DI;
737 s->subdev_flags = SDF_READABLE;
740 s->range_table = &range_digital;
741 s->insn_bits = das1800_di_rbits;
744 s = dev->subdevices + 3;
745 s->type = COMEDI_SUBD_DO;
746 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
747 s->n_chan = thisboard->do_n_chan;
749 s->range_table = &range_digital;
750 s->insn_bits = das1800_do_wbits;
752 das1800_cancel(dev, dev->read_subdev);
754 /* initialize digital out channels */
755 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
757 /* initialize analog out channels */
758 if (thisboard->ao_ability == 1) {
759 /* select 'update' dac channel for baseAddress + 0x0 */
760 outb(DAC(thisboard->ao_n_chan - 1),
761 dev->iobase + DAS1800_SELECT);
762 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
768 static int das1800_detach(struct comedi_device *dev)
770 /* only free stuff if it has been allocated by _attach */
772 release_region(dev->iobase, DAS1800_SIZE);
774 comedi_free_irq(dev->irq, dev);
776 if (devpriv->iobase2)
777 release_region(devpriv->iobase2, DAS1800_SIZE);
779 free_dma(devpriv->dma0);
781 free_dma(devpriv->dma1);
782 if (devpriv->ai_buf0)
783 kfree(devpriv->ai_buf0);
784 if (devpriv->ai_buf1)
785 kfree(devpriv->ai_buf1);
788 printk("comedi%d: %s: remove\n", dev->minor,
789 driver_das1800.driver_name);
794 /* probes and checks das-1800 series board type
796 static int das1800_probe(struct comedi_device *dev)
801 id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */
802 board = ((struct das1800_board *) dev->board_ptr) - das1800_boards;
806 if (board == das1801st_da || board == das1802st_da ||
807 board == das1701st_da || board == das1702st_da) {
808 printk(" Board model: %s\n",
809 das1800_boards[board].name);
812 printk(" Board model (probed, not recommended): das-1800st-da series\n");
816 if (board == das1802hr_da || board == das1702hr_da) {
817 printk(" Board model: %s\n",
818 das1800_boards[board].name);
821 printk(" Board model (probed, not recommended): das-1802hr-da\n");
825 if (board == das1801ao || board == das1802ao ||
826 board == das1701ao || board == das1702ao) {
827 printk(" Board model: %s\n",
828 das1800_boards[board].name);
831 printk(" Board model (probed, not recommended): das-1800ao series\n");
835 if (board == das1802hr || board == das1702hr) {
836 printk(" Board model: %s\n",
837 das1800_boards[board].name);
840 printk(" Board model (probed, not recommended): das-1802hr\n");
844 if (board == das1801st || board == das1802st ||
845 board == das1701st || board == das1702st) {
846 printk(" Board model: %s\n",
847 das1800_boards[board].name);
850 printk(" Board model (probed, not recommended): das-1800st series\n");
854 if (board == das1801hc || board == das1802hc) {
855 printk(" Board model: %s\n",
856 das1800_boards[board].name);
859 printk(" Board model (probed, not recommended): das-1800hc series\n");
863 printk(" Board model: probe returned 0x%x (unknown, please report)\n", id);
870 static int das1800_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
874 /* prevent race with interrupt handler */
875 comedi_spin_lock_irqsave(&dev->spinlock, flags);
876 das1800_ai_handler(dev);
877 comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
879 return s->async->buf_write_count - s->async->buf_read_count;
882 static irqreturn_t das1800_interrupt(int irq, void *d)
884 struct comedi_device *dev = d;
887 if (dev->attached == 0) {
888 comedi_error(dev, "premature interrupt");
892 /* Prevent race with das1800_ai_poll() on multi processor systems.
893 * Also protects indirect addressing in das1800_ai_handler */
894 spin_lock(&dev->spinlock);
895 status = inb(dev->iobase + DAS1800_STATUS);
897 /* if interrupt was not caused by das-1800 */
898 if (!(status & INT)) {
899 spin_unlock(&dev->spinlock);
902 /* clear the interrupt status bit INT */
903 outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
904 /* handle interrupt */
905 das1800_ai_handler(dev);
907 spin_unlock(&dev->spinlock);
911 /* the guts of the interrupt handler, that is shared with das1800_ai_poll */
912 static void das1800_ai_handler(struct comedi_device *dev)
914 struct comedi_subdevice *s = dev->subdevices + 0; /* analog input subdevice */
915 struct comedi_async *async = s->async;
916 struct comedi_cmd *cmd = &async->cmd;
917 unsigned int status = inb(dev->iobase + DAS1800_STATUS);
920 /* select adc for base address + 0 */
921 outb(ADC, dev->iobase + DAS1800_SELECT);
922 /* dma buffer full */
923 if (devpriv->irq_dma_bits & DMA_ENABLED) {
924 /* look for data from dma transfer even if dma terminal count hasn't happened yet */
925 das1800_handle_dma(dev, s, status);
926 } else if (status & FHF) { /* if fifo half full */
927 das1800_handle_fifo_half_full(dev, s);
928 } else if (status & FNE) { /* if fifo not empty */
929 das1800_handle_fifo_not_empty(dev, s);
932 async->events |= COMEDI_CB_BLOCK;
933 /* if the card's fifo has overflowed */
935 /* clear OVF interrupt bit */
936 outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
937 comedi_error(dev, "DAS1800 FIFO overflow");
938 das1800_cancel(dev, s);
939 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
940 comedi_event(dev, s);
943 /* stop taking data if appropriate */
944 /* stop_src TRIG_EXT */
945 if (status & CT0TC) {
946 /* clear CT0TC interrupt bit */
947 outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
948 /* make sure we get all remaining data from board before quitting */
949 if (devpriv->irq_dma_bits & DMA_ENABLED)
950 das1800_flush_dma(dev, s);
952 das1800_handle_fifo_not_empty(dev, s);
953 das1800_cancel(dev, s); /* disable hardware conversions */
954 async->events |= COMEDI_CB_EOA;
955 } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { /* stop_src TRIG_COUNT */
956 das1800_cancel(dev, s); /* disable hardware conversions */
957 async->events |= COMEDI_CB_EOA;
960 comedi_event(dev, s);
965 static void das1800_handle_dma(struct comedi_device *dev, struct comedi_subdevice *s,
969 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
971 flags = claim_dma_lock();
972 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
973 devpriv->dma_current_buf);
974 /* re-enable dma channel */
975 set_dma_addr(devpriv->dma_current,
976 virt_to_bus(devpriv->dma_current_buf));
977 set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size);
978 enable_dma(devpriv->dma_current);
979 release_dma_lock(flags);
981 if (status & DMATC) {
982 /* clear DMATC interrupt bit */
983 outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
984 /* switch dma channels for next time, if appropriate */
986 /* read data from the other channel next time */
987 if (devpriv->dma_current == devpriv->dma0) {
988 devpriv->dma_current = devpriv->dma1;
989 devpriv->dma_current_buf = devpriv->ai_buf1;
991 devpriv->dma_current = devpriv->dma0;
992 devpriv->dma_current_buf = devpriv->ai_buf0;
1000 static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev,
1003 sample += 1 << (thisboard->resolution - 1);
1007 static void munge_data(struct comedi_device *dev, uint16_t *array,
1008 unsigned int num_elements)
1013 /* see if card is using a unipolar or bipolar range so we can munge data correctly */
1014 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
1016 /* convert to unsigned type if we are in a bipolar mode */
1018 for (i = 0; i < num_elements; i++) {
1019 array[i] = munge_bipolar_sample(dev, array[i]);
1024 /* Utility function used by das1800_flush_dma() and das1800_handle_dma().
1025 * Assumes dma lock is held */
1026 static void das1800_flush_dma_channel(struct comedi_device *dev, struct comedi_subdevice *s,
1027 unsigned int channel, uint16_t *buffer)
1029 unsigned int num_bytes, num_samples;
1030 struct comedi_cmd *cmd = &s->async->cmd;
1032 disable_dma(channel);
1034 /* clear flip-flop to make sure 2-byte registers
1035 * get set correctly */
1036 clear_dma_ff(channel);
1038 /* figure out how many points to read */
1039 num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel);
1040 num_samples = num_bytes / sizeof(short);
1042 /* if we only need some of the points */
1043 if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples)
1044 num_samples = devpriv->count;
1046 munge_data(dev, buffer, num_samples);
1047 cfc_write_array_to_buffer(s, buffer, num_bytes);
1048 if (s->async->cmd.stop_src == TRIG_COUNT)
1049 devpriv->count -= num_samples;
1054 /* flushes remaining data from board when external trigger has stopped aquisition
1055 * and we are using dma transfers */
1056 static void das1800_flush_dma(struct comedi_device *dev, struct comedi_subdevice *s)
1058 unsigned long flags;
1059 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
1061 flags = claim_dma_lock();
1062 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
1063 devpriv->dma_current_buf);
1066 /* switch to other channel and flush it */
1067 if (devpriv->dma_current == devpriv->dma0) {
1068 devpriv->dma_current = devpriv->dma1;
1069 devpriv->dma_current_buf = devpriv->ai_buf1;
1071 devpriv->dma_current = devpriv->dma0;
1072 devpriv->dma_current_buf = devpriv->ai_buf0;
1074 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
1075 devpriv->dma_current_buf);
1078 release_dma_lock(flags);
1080 /* get any remaining samples in fifo */
1081 das1800_handle_fifo_not_empty(dev, s);
1086 static void das1800_handle_fifo_half_full(struct comedi_device *dev,
1087 struct comedi_subdevice *s)
1089 int numPoints = 0; /* number of points to read */
1090 struct comedi_cmd *cmd = &s->async->cmd;
1092 numPoints = FIFO_SIZE / 2;
1093 /* if we only need some of the points */
1094 if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints)
1095 numPoints = devpriv->count;
1096 insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints);
1097 munge_data(dev, devpriv->ai_buf0, numPoints);
1098 cfc_write_array_to_buffer(s, devpriv->ai_buf0,
1099 numPoints * sizeof(devpriv->ai_buf0[0]));
1100 if (cmd->stop_src == TRIG_COUNT)
1101 devpriv->count -= numPoints;
1105 static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
1106 struct comedi_subdevice *s)
1110 struct comedi_cmd *cmd = &s->async->cmd;
1112 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
1114 while (inb(dev->iobase + DAS1800_STATUS) & FNE) {
1115 if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
1117 dpnt = inw(dev->iobase + DAS1800_FIFO);
1118 /* convert to unsigned type if we are in a bipolar mode */
1120 dpnt = munge_bipolar_sample(dev, dpnt);
1121 cfc_write_to_buffer(s, dpnt);
1122 if (cmd->stop_src == TRIG_COUNT)
1129 static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1131 outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */
1132 outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */
1133 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */
1135 disable_dma(devpriv->dma0);
1137 disable_dma(devpriv->dma1);
1141 /* test analog input cmd */
1142 static int das1800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
1143 struct comedi_cmd *cmd)
1147 unsigned int tmp_arg;
1151 /* step 1: make sure trigger sources are trivially valid */
1153 tmp = cmd->start_src;
1154 cmd->start_src &= TRIG_NOW | TRIG_EXT;
1155 if (!cmd->start_src || tmp != cmd->start_src)
1158 tmp = cmd->scan_begin_src;
1159 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
1160 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
1163 tmp = cmd->convert_src;
1164 cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
1165 if (!cmd->convert_src || tmp != cmd->convert_src)
1168 tmp = cmd->scan_end_src;
1169 cmd->scan_end_src &= TRIG_COUNT;
1170 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
1173 tmp = cmd->stop_src;
1174 cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
1175 if (!cmd->stop_src || tmp != cmd->stop_src)
1181 /* step 2: make sure trigger sources are unique and mutually compatible */
1183 /* uniqueness check */
1184 if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
1186 if (cmd->scan_begin_src != TRIG_FOLLOW &&
1187 cmd->scan_begin_src != TRIG_TIMER &&
1188 cmd->scan_begin_src != TRIG_EXT)
1190 if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
1192 if (cmd->stop_src != TRIG_COUNT &&
1193 cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
1195 /* compatibility check */
1196 if (cmd->scan_begin_src != TRIG_FOLLOW &&
1197 cmd->convert_src != TRIG_TIMER)
1203 /* step 3: make sure arguments are trivially compatible */
1205 if (cmd->start_arg != 0) {
1209 if (cmd->convert_src == TRIG_TIMER) {
1210 if (cmd->convert_arg < thisboard->ai_speed) {
1211 cmd->convert_arg = thisboard->ai_speed;
1215 if (!cmd->chanlist_len) {
1216 cmd->chanlist_len = 1;
1219 if (cmd->scan_end_arg != cmd->chanlist_len) {
1220 cmd->scan_end_arg = cmd->chanlist_len;
1224 switch (cmd->stop_src) {
1226 if (!cmd->stop_arg) {
1232 if (cmd->stop_arg != 0) {
1244 /* step 4: fix up any arguments */
1246 if (cmd->convert_src == TRIG_TIMER) {
1247 /* if we are not in burst mode */
1248 if (cmd->scan_begin_src == TRIG_FOLLOW) {
1249 tmp_arg = cmd->convert_arg;
1250 /* calculate counter values that give desired timing */
1251 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1252 &(devpriv->divisor1), &(devpriv->divisor2),
1253 &(cmd->convert_arg),
1254 cmd->flags & TRIG_ROUND_MASK);
1255 if (tmp_arg != cmd->convert_arg)
1258 /* if we are in burst mode */
1260 /* check that convert_arg is compatible */
1261 tmp_arg = cmd->convert_arg;
1263 burst_convert_arg(cmd->convert_arg,
1264 cmd->flags & TRIG_ROUND_MASK);
1265 if (tmp_arg != cmd->convert_arg)
1268 if (cmd->scan_begin_src == TRIG_TIMER) {
1269 /* if scans are timed faster than conversion rate allows */
1270 if (cmd->convert_arg * cmd->chanlist_len >
1271 cmd->scan_begin_arg) {
1272 cmd->scan_begin_arg =
1277 tmp_arg = cmd->scan_begin_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->scan_begin_arg),
1283 cmd->flags & TRIG_ROUND_MASK);
1284 if (tmp_arg != cmd->scan_begin_arg)
1293 /* make sure user is not trying to mix unipolar and bipolar ranges */
1294 if (cmd->chanlist) {
1295 unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR;
1296 for (i = 1; i < cmd->chanlist_len; i++) {
1297 if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) {
1299 "unipolar and bipolar ranges cannot be mixed in the chanlist");
1312 /* analog input cmd interface */
1314 /* first, some utility functions used in the main ai_do_cmd() */
1316 /* returns appropriate bits for control register a, depending on command */
1317 static int control_a_bits(struct comedi_cmd cmd)
1321 control_a = FFEN; /* enable fifo */
1322 if (cmd.stop_src == TRIG_EXT) {
1325 switch (cmd.start_src) {
1327 control_a |= TGEN | CGSL;
1339 /* returns appropriate bits for control register c, depending on command */
1340 static int control_c_bits(struct comedi_cmd cmd)
1345 /* set clock source to internal or external, select analog reference,
1346 * select unipolar / bipolar
1348 aref = CR_AREF(cmd.chanlist[0]);
1349 control_c = UQEN; /* enable upper qram addresses */
1350 if (aref != AREF_DIFF)
1352 if (aref == AREF_COMMON)
1354 /* if a unipolar range was selected */
1355 if (CR_RANGE(cmd.chanlist[0]) & UNIPOLAR)
1357 switch (cmd.scan_begin_src) {
1358 case TRIG_FOLLOW: /* not in burst mode */
1359 switch (cmd.convert_src) {
1361 /* trig on cascaded counters */
1365 /* trig on falling edge of external trigger */
1373 /* burst mode with internal pacer clock */
1374 control_c |= BMDE | IPCLK;
1377 /* burst mode with external trigger */
1378 control_c |= BMDE | XPCLK;
1387 /* sets up counters */
1388 static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd)
1390 /* setup cascaded counters for conversion/scan frequency */
1391 switch (cmd.scan_begin_src) {
1392 case TRIG_FOLLOW: /* not in burst mode */
1393 if (cmd.convert_src == TRIG_TIMER) {
1394 /* set conversion frequency */
1395 i8253_cascade_ns_to_timer_2div(TIMER_BASE,
1396 &(devpriv->divisor1), &(devpriv->divisor2),
1398 cmd.flags & TRIG_ROUND_MASK);
1399 if (das1800_set_frequency(dev) < 0) {
1404 case TRIG_TIMER: /* in burst mode */
1405 /* set scan frequency */
1406 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
1407 &(devpriv->divisor2), &(cmd.scan_begin_arg),
1408 cmd.flags & TRIG_ROUND_MASK);
1409 if (das1800_set_frequency(dev) < 0) {
1417 /* setup counter 0 for 'about triggering' */
1418 if (cmd.stop_src == TRIG_EXT) {
1419 /* load counter 0 in mode 0 */
1420 i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0);
1427 static void setup_dma(struct comedi_device *dev, struct comedi_cmd cmd)
1429 unsigned long lock_flags;
1430 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
1432 if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
1435 /* determine a reasonable dma transfer size */
1436 devpriv->dma_transfer_size = suggest_transfer_size(&cmd);
1437 lock_flags = claim_dma_lock();
1438 disable_dma(devpriv->dma0);
1439 /* clear flip-flop to make sure 2-byte registers for
1440 * count and address get set correctly */
1441 clear_dma_ff(devpriv->dma0);
1442 set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0));
1443 /* set appropriate size of transfer */
1444 set_dma_count(devpriv->dma0, devpriv->dma_transfer_size);
1445 devpriv->dma_current = devpriv->dma0;
1446 devpriv->dma_current_buf = devpriv->ai_buf0;
1447 enable_dma(devpriv->dma0);
1448 /* set up dual dma if appropriate */
1450 disable_dma(devpriv->dma1);
1451 /* clear flip-flop to make sure 2-byte registers for
1452 * count and address get set correctly */
1453 clear_dma_ff(devpriv->dma1);
1454 set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1));
1455 /* set appropriate size of transfer */
1456 set_dma_count(devpriv->dma1, devpriv->dma_transfer_size);
1457 enable_dma(devpriv->dma1);
1459 release_dma_lock(lock_flags);
1464 /* programs channel/gain list into card */
1465 static void program_chanlist(struct comedi_device *dev, struct comedi_cmd cmd)
1467 int i, n, chan_range;
1468 unsigned long irq_flags;
1469 const int range_mask = 0x3; /* masks unipolar/bipolar bit off range */
1470 const int range_bitshift = 8;
1472 n = cmd.chanlist_len;
1473 /* spinlock protects indirect addressing */
1474 comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
1475 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
1476 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */
1477 /* make channel / gain list */
1478 for (i = 0; i < n; i++) {
1480 CR_CHAN(cmd.chanlist[i]) | ((CR_RANGE(cmd.
1481 chanlist[i]) & range_mask) <<
1483 outw(chan_range, dev->iobase + DAS1800_QRAM);
1485 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
1486 comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1491 /* analog input do_cmd */
1492 static int das1800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1495 int control_a, control_c;
1496 struct comedi_async *async = s->async;
1497 struct comedi_cmd cmd = async->cmd;
1501 "no irq assigned for das-1800, cannot do hardware conversions");
1505 /* disable dma on TRIG_WAKE_EOS, or TRIG_RT
1506 * (because dma in handler is unsafe at hard real-time priority) */
1507 if (cmd.flags & (TRIG_WAKE_EOS | TRIG_RT)) {
1508 devpriv->irq_dma_bits &= ~DMA_ENABLED;
1510 devpriv->irq_dma_bits |= devpriv->dma_bits;
1512 /* interrupt on end of conversion for TRIG_WAKE_EOS */
1513 if (cmd.flags & TRIG_WAKE_EOS) {
1514 /* interrupt fifo not empty */
1515 devpriv->irq_dma_bits &= ~FIMD;
1517 /* interrupt fifo half full */
1518 devpriv->irq_dma_bits |= FIMD;
1520 /* determine how many conversions we need */
1521 if (cmd.stop_src == TRIG_COUNT) {
1522 devpriv->count = cmd.stop_arg * cmd.chanlist_len;
1525 das1800_cancel(dev, s);
1527 /* determine proper bits for control registers */
1528 control_a = control_a_bits(cmd);
1529 control_c = control_c_bits(cmd);
1531 /* setup card and start */
1532 program_chanlist(dev, cmd);
1533 ret = setup_counters(dev, cmd);
1535 comedi_error(dev, "Error setting up counters");
1538 setup_dma(dev, cmd);
1539 outb(control_c, dev->iobase + DAS1800_CONTROL_C);
1540 /* set conversion rate and length for burst mode */
1541 if (control_c & BMDE) {
1542 /* program conversion period with number of microseconds minus 1 */
1543 outb(cmd.convert_arg / 1000 - 1,
1544 dev->iobase + DAS1800_BURST_RATE);
1545 outb(cmd.chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
1547 outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); /* enable irq/dma */
1548 outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */
1549 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
1554 /* read analog input */
1555 static int das1800_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
1556 struct comedi_insn *insn, unsigned int *data)
1559 int chan, range, aref, chan_range;
1563 unsigned long irq_flags;
1565 /* set up analog reference and unipolar / bipolar mode */
1566 aref = CR_AREF(insn->chanspec);
1568 if (aref != AREF_DIFF)
1570 if (aref == AREF_COMMON)
1572 /* if a unipolar range was selected */
1573 if (CR_RANGE(insn->chanspec) & UNIPOLAR)
1576 outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */
1577 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
1578 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */
1579 outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
1581 chan = CR_CHAN(insn->chanspec);
1582 /* mask of unipolar/bipolar bit from range */
1583 range = CR_RANGE(insn->chanspec) & 0x3;
1584 chan_range = chan | (range << 8);
1585 comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
1586 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
1587 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */
1588 outw(chan_range, dev->iobase + DAS1800_QRAM);
1589 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
1590 outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */
1592 for (n = 0; n < insn->n; n++) {
1593 /* trigger conversion */
1594 outb(0, dev->iobase + DAS1800_FIFO);
1595 for (i = 0; i < timeout; i++) {
1596 if (inb(dev->iobase + DAS1800_STATUS) & FNE)
1600 comedi_error(dev, "timeout");
1603 dpnt = inw(dev->iobase + DAS1800_FIFO);
1604 /* shift data to offset binary for bipolar ranges */
1605 if ((conv_flags & UB) == 0)
1606 dpnt += 1 << (thisboard->resolution - 1);
1609 comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1614 /* writes to an analog output channel */
1615 static int das1800_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
1616 struct comedi_insn *insn, unsigned int *data)
1618 int chan = CR_CHAN(insn->chanspec);
1619 /* int range = CR_RANGE(insn->chanspec); */
1620 int update_chan = thisboard->ao_n_chan - 1;
1622 unsigned long irq_flags;
1624 /* card expects two's complement data */
1625 output = data[0] - (1 << (thisboard->resolution - 1));
1626 /* if the write is to the 'update' channel, we need to remember its value */
1627 if (chan == update_chan)
1628 devpriv->ao_update_bits = output;
1629 /* write to channel */
1630 comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
1631 outb(DAC(chan), dev->iobase + DAS1800_SELECT); /* select dac channel for baseAddress + 0x0 */
1632 outw(output, dev->iobase + DAS1800_DAC);
1633 /* now we need to write to 'update' channel to update all dac channels */
1634 if (chan != update_chan) {
1635 outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); /* select 'update' channel for baseAddress + 0x0 */
1636 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
1638 comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1643 /* reads from digital input channels */
1644 static int das1800_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
1645 struct comedi_insn *insn, unsigned int *data)
1648 data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf;
1654 /* writes to digital output channels */
1655 static int das1800_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
1656 struct comedi_insn *insn, unsigned int *data)
1660 /* only set bits that have been masked */
1661 data[0] &= (1 << s->n_chan) - 1;
1662 wbits = devpriv->do_bits;
1664 wbits |= data[0] & data[1];
1665 devpriv->do_bits = wbits;
1667 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
1669 data[1] = devpriv->do_bits;
1674 /* loads counters with divisor1, divisor2 from private structure */
1675 static int das1800_set_frequency(struct comedi_device *dev)
1679 /* counter 1, mode 2 */
1680 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1,
1683 /* counter 2, mode 2 */
1684 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2,
1693 /* converts requested conversion timing to timing compatible with
1694 * hardware, used only when card is in 'burst mode'
1696 static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode)
1698 unsigned int micro_sec;
1700 /* in burst mode, the maximum conversion time is 64 microseconds */
1701 if (convert_arg > 64000)
1702 convert_arg = 64000;
1704 /* the conversion time must be an integral number of microseconds */
1705 switch (round_mode) {
1706 case TRIG_ROUND_NEAREST:
1708 micro_sec = (convert_arg + 500) / 1000;
1710 case TRIG_ROUND_DOWN:
1711 micro_sec = convert_arg / 1000;
1714 micro_sec = (convert_arg - 1) / 1000 + 1;
1718 /* return number of nanoseconds */
1719 return micro_sec * 1000;
1722 /* utility function that suggests a dma transfer size based on the conversion period 'ns' */
1723 static unsigned int suggest_transfer_size(struct comedi_cmd *cmd)
1725 unsigned int size = DMA_BUF_SIZE;
1726 static const int sample_size = 2; /* size in bytes of one sample from board */
1727 unsigned int fill_time = 300000000; /* target time in nanoseconds for filling dma buffer */
1728 unsigned int max_size; /* maximum size we will allow for a transfer */
1730 /* make dma buffer fill in 0.3 seconds for timed modes */
1731 switch (cmd->scan_begin_src) {
1732 case TRIG_FOLLOW: /* not in burst mode */
1733 if (cmd->convert_src == TRIG_TIMER)
1734 size = (fill_time / cmd->convert_arg) * sample_size;
1737 size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) *
1741 size = DMA_BUF_SIZE;
1745 /* set a minimum and maximum size allowed */
1746 max_size = DMA_BUF_SIZE;
1747 /* if we are taking limited number of conversions, limit transfer size to that */
1748 if (cmd->stop_src == TRIG_COUNT &&
1749 cmd->stop_arg * cmd->chanlist_len * sample_size < max_size)
1750 max_size = cmd->stop_arg * cmd->chanlist_len * sample_size;
1752 if (size > max_size)
1754 if (size < sample_size)