5 COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 2000 David A. Schleef <ds@schleef.org>
7 Copyright (C) 2000 Chris R. Baugher <baugher@enteract.com>
8 Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 ************************************************************************
28 Description: DAS16 compatible boards
29 Author: Sam Moore, Warren Jasper, ds, Chris Baugher, Frank Hess, Roman Fietze
30 Devices: [Keithley Metrabyte] DAS-16 (das-16), DAS-16G (das-16g),
31 DAS-16F (das-16f), DAS-1201 (das-1201), DAS-1202 (das-1202),
32 DAS-1401 (das-1401), DAS-1402 (das-1402), DAS-1601 (das-1601),
34 [ComputerBoards] PC104-DAS16/JR (pc104-das16jr),
35 PC104-DAS16JR/16 (pc104-das16jr/16),
36 CIO-DAS16JR/16 (cio-das16jr/16),
37 CIO-DAS16/JR (cio-das16/jr), CIO-DAS1401/12 (cio-das1401/12),
38 CIO-DAS1402/12 (cio-das1402/12), CIO-DAS1402/16 (cio-das1402/16),
39 CIO-DAS1601/12 (cio-das1601/12), CIO-DAS1602/12 (cio-das1602/12),
40 CIO-DAS1602/16 (cio-das1602/16), CIO-DAS16/330 (cio-das16/330)
44 A rewrite of the das16 and das1600 drivers.
47 [1] - irq (does nothing, irq is not used anymore)
48 [2] - dma (optional, required for comedi_command support)
49 [3] - master clock speed in MHz (optional, 1 or 10, ignored if
50 board can probe clock, defaults to 1)
51 [4] - analog input range lowest voltage in microvolts (optional,
52 only useful if your board does not have software
54 [5] - analog input range highest voltage in microvolts (optional,
55 only useful if board does not have software programmable
57 [6] - analog output range lowest voltage in microvolts (optional)
58 [7] - analog output range highest voltage in microvolts (optional)
59 [8] - use timer mode for DMA. Timer mode is needed e.g. for
60 buggy DMA controllers in NS CS5530A (Geode Companion), and for
61 'jr' cards that lack a hardware fifo. This option is no
62 longer needed, since timer mode is _always_ used.
64 Passing a zero for an option is the same as leaving it unspecified.
69 Testing and debugging help provided by Daniel Koch.
73 4919.PDF (das1400, 1600)
75 4923.PDF (das1200, 1400, 1600)
77 Computer boards manuals also available from their website
78 www.measurementcomputing.com
82 #include <linux/pci.h>
83 #include <linux/slab.h>
84 #include <linux/interrupt.h>
86 #include "../comedidev.h"
90 #include "comedi_fc.h"
96 #define DEBUG_PRINT(format, args...) \
97 printk(KERN_DEBUG "das16: " format, ## args)
99 #define DEBUG_PRINT(format, args...)
102 #define DAS16_SIZE 20 /* number of ioports */
103 #define DAS16_DMA_SIZE 0xff00 /* size in bytes of allocated dma buffer */
111 0 a/d bits 0-3 start 12 bit
112 1 a/d bits 4-11 unused
119 8 status eoc uni/bip interrupt reset
120 9 dma, int, trig ctrl set dma, int
121 a pacer control unused
133 0 a/d bits 0-3 start 12 bit
134 1 a/d bits 4-11 unused
138 8 status eoc uni/bip interrupt reset
139 9 dma, int, trig ctrl set dma, int
140 a pacer control unused
141 b gain status gain control
151 0 a/d bits 0-7 start 16 bit
152 1 a/d bits 8-15 unused
156 8 status eoc uni/bip interrupt reset
157 9 dma, int, trig ctrl set dma, int
158 a pacer control unused
159 b gain status gain control
170 0 a/d bits 0-3 start 12 bit
171 1 a/d bits 4-11 unused
178 8 status eoc uni/bip interrupt reset
179 9 dma, int, trig ctrl set dma, int
180 a pacer control unused
181 b gain status gain control
184 404 unused conversion enable
185 405 unused burst enable
186 406 unused das1600 enable
191 /* size in bytes of a sample from board */
192 static const int sample_size = 2;
195 #define DAS16_AI_LSB 0
196 #define DAS16_AI_MSB 1
199 #define DAS16_AO_LSB(x) ((x) ? 6 : 4)
200 #define DAS16_AO_MSB(x) ((x) ? 7 : 5)
201 #define DAS16_STATUS 8
203 #define UNIPOLAR (1<<6)
204 #define DAS16_MUXBIT (1<<5)
205 #define DAS16_INT (1<<4)
206 #define DAS16_CONTROL 9
207 #define DAS16_INTE (1<<7)
208 #define DAS16_IRQ(x) (((x) & 0x7) << 4)
209 #define DMA_ENABLE (1<<2)
210 #define PACING_MASK 0x3
211 #define INT_PACER 0x03
212 #define EXT_PACER 0x02
213 #define DAS16_SOFT 0x00
214 #define DAS16_PACER 0x0A
215 #define DAS16_CTR0 (1<<1)
216 #define DAS16_TRIG0 (1<<0)
217 #define BURST_LEN_BITS(x) (((x) & 0xf) << 4)
218 #define DAS16_GAIN 0x0B
219 #define DAS16_CNTR0_DATA 0x0C
220 #define DAS16_CNTR1_DATA 0x0D
221 #define DAS16_CNTR2_DATA 0x0E
222 #define DAS16_CNTR_CONTROL 0x0F
223 #define DAS16_TERM_CNT 0x00
224 #define DAS16_ONE_SHOT 0x02
225 #define DAS16_RATE_GEN 0x04
226 #define DAS16_CNTR_LSB_MSB 0x30
227 #define DAS16_CNTR0 0x00
228 #define DAS16_CNTR1 0x40
229 #define DAS16_CNTR2 0x80
231 #define DAS1600_CONV 0x404
232 #define DAS1600_CONV_DISABLE 0x40
233 #define DAS1600_BURST 0x405
234 #define DAS1600_BURST_VAL 0x40
235 #define DAS1600_ENABLE 0x406
236 #define DAS1600_ENABLE_VAL 0x40
237 #define DAS1600_STATUS_B 0x407
238 #define DAS1600_BME 0x40
239 #define DAS1600_ME 0x20
240 #define DAS1600_CD 0x10
241 #define DAS1600_WS 0x02
242 #define DAS1600_CLK_10MHZ 0x01
244 static const struct comedi_lrange range_das1x01_bip = { 4, {
252 static const struct comedi_lrange range_das1x01_unip = { 4, {
260 static const struct comedi_lrange range_das1x02_bip = { 4, {
268 static const struct comedi_lrange range_das1x02_unip = { 4, {
276 static const struct comedi_lrange range_das16jr = { 9, {
277 /* also used by 16/330 */
290 static const struct comedi_lrange range_das16jr_16 = { 8, {
302 static const int das16jr_gainlist[] = { 8, 0, 1, 2, 3, 4, 5, 6, 7 };
303 static const int das16jr_16_gainlist[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
304 static const int das1600_gainlist[] = { 0, 1, 2, 3 };
313 static const int *const das16_gainlists[] = {
321 static const struct comedi_lrange *const das16_ai_uni_lranges[] = {
329 static const struct comedi_lrange *const das16_ai_bip_lranges[] = {
339 unsigned have_byte:1;
342 static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
343 struct comedi_insn *insn, unsigned int *data);
344 static int das16_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
345 struct comedi_insn *insn, unsigned int *data);
346 static int das16_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
347 struct comedi_insn *insn, unsigned int *data);
348 static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
349 struct comedi_insn *insn, unsigned int *data);
351 static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
352 struct comedi_cmd *cmd);
353 static int das16_cmd_exec(struct comedi_device *dev,
354 struct comedi_subdevice *s);
355 static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
356 static void das16_ai_munge(struct comedi_device *dev,
357 struct comedi_subdevice *s, void *array,
358 unsigned int num_bytes,
359 unsigned int start_chan_index);
361 static void das16_reset(struct comedi_device *dev);
362 static irqreturn_t das16_dma_interrupt(int irq, void *d);
363 static void das16_timer_interrupt(unsigned long arg);
364 static void das16_interrupt(struct comedi_device *dev);
366 static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
368 static int das1600_mode_detect(struct comedi_device *dev);
369 static unsigned int das16_suggest_transfer_size(struct comedi_device *dev,
370 struct comedi_cmd cmd);
372 static void reg_dump(struct comedi_device *dev);
377 unsigned int ai_nbits;
378 unsigned int ai_speed; /* max conversion speed in nanosec */
381 unsigned int ao_nbits;
385 unsigned int i8255_offset;
386 unsigned int i8254_offset;
392 static const struct das16_board das16_boards[] = {
395 .ai = das16_ai_rinsn,
398 .ai_pg = das16_pg_none,
399 .ao = das16_ao_winsn,
401 .di = das16_di_rbits,
402 .do_ = das16_do_wbits,
403 .i8255_offset = 0x10,
404 .i8254_offset = 0x0c,
410 .ai = das16_ai_rinsn,
413 .ai_pg = das16_pg_none,
414 .ao = das16_ao_winsn,
416 .di = das16_di_rbits,
417 .do_ = das16_do_wbits,
418 .i8255_offset = 0x10,
419 .i8254_offset = 0x0c,
425 .ai = das16_ai_rinsn,
428 .ai_pg = das16_pg_none,
429 .ao = das16_ao_winsn,
431 .di = das16_di_rbits,
432 .do_ = das16_do_wbits,
433 .i8255_offset = 0x10,
434 .i8254_offset = 0x0c,
439 .name = "cio-das16", /* cio-das16.pdf */
440 .ai = das16_ai_rinsn,
443 .ai_pg = das16_pg_none,
444 .ao = das16_ao_winsn,
446 .di = das16_di_rbits,
447 .do_ = das16_do_wbits,
448 .i8255_offset = 0x10,
449 .i8254_offset = 0x0c,
454 .name = "cio-das16/f", /* das16.pdf */
455 .ai = das16_ai_rinsn,
458 .ai_pg = das16_pg_none,
459 .ao = das16_ao_winsn,
461 .di = das16_di_rbits,
462 .do_ = das16_do_wbits,
463 .i8255_offset = 0x10,
464 .i8254_offset = 0x0c,
469 .name = "cio-das16/jr", /* cio-das16jr.pdf */
470 .ai = das16_ai_rinsn,
473 .ai_pg = das16_pg_16jr,
475 .di = das16_di_rbits,
476 .do_ = das16_do_wbits,
478 .i8254_offset = 0x0c,
483 .name = "pc104-das16jr", /* pc104-das16jr_xx.pdf */
484 .ai = das16_ai_rinsn,
487 .ai_pg = das16_pg_16jr,
489 .di = das16_di_rbits,
490 .do_ = das16_do_wbits,
492 .i8254_offset = 0x0c,
497 .name = "cio-das16jr/16", /* cio-das16jr_16.pdf */
498 .ai = das16_ai_rinsn,
501 .ai_pg = das16_pg_16jr_16,
503 .di = das16_di_rbits,
504 .do_ = das16_do_wbits,
506 .i8254_offset = 0x0c,
511 .name = "pc104-das16jr/16", /* pc104-das16jr_xx.pdf */
512 .ai = das16_ai_rinsn,
515 .ai_pg = das16_pg_16jr_16,
517 .di = das16_di_rbits,
518 .do_ = das16_do_wbits,
520 .i8254_offset = 0x0c,
525 .name = "das-1201", /* 4924.pdf (keithley user's manual) */
526 .ai = das16_ai_rinsn,
529 .ai_pg = das16_pg_none,
531 .di = das16_di_rbits,
532 .do_ = das16_do_wbits,
533 .i8255_offset = 0x400,
534 .i8254_offset = 0x0c,
539 .name = "das-1202", /* 4924.pdf (keithley user's manual) */
540 .ai = das16_ai_rinsn,
543 .ai_pg = das16_pg_none,
545 .di = das16_di_rbits,
546 .do_ = das16_do_wbits,
547 .i8255_offset = 0x400,
548 .i8254_offset = 0x0c,
553 /* 4919.pdf and 4922.pdf (keithley user's manual) */
555 .ai = das16_ai_rinsn,
558 .ai_pg = das16_pg_1601,
560 .di = das16_di_rbits,
561 .do_ = das16_do_wbits,
563 .i8254_offset = 0x0c,
565 .id = 0xc0 /* 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 */
568 /* 4919.pdf and 4922.pdf (keithley user's manual) */
570 .ai = das16_ai_rinsn,
573 .ai_pg = das16_pg_1602,
575 .di = das16_di_rbits,
576 .do_ = das16_do_wbits,
578 .i8254_offset = 0x0c,
580 .id = 0xc0 /* 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 */
583 .name = "das-1601", /* 4919.pdf */
584 .ai = das16_ai_rinsn,
587 .ai_pg = das16_pg_1601,
588 .ao = das16_ao_winsn,
590 .di = das16_di_rbits,
591 .do_ = das16_do_wbits,
592 .i8255_offset = 0x400,
593 .i8254_offset = 0x0c,
597 .name = "das-1602", /* 4919.pdf */
598 .ai = das16_ai_rinsn,
601 .ai_pg = das16_pg_1602,
602 .ao = das16_ao_winsn,
604 .di = das16_di_rbits,
605 .do_ = das16_do_wbits,
606 .i8255_offset = 0x400,
607 .i8254_offset = 0x0c,
611 .name = "cio-das1401/12", /* cio-das1400_series.pdf */
612 .ai = das16_ai_rinsn,
615 .ai_pg = das16_pg_1601,
617 .di = das16_di_rbits,
618 .do_ = das16_do_wbits,
620 .i8254_offset = 0x0c,
624 .name = "cio-das1402/12", /* cio-das1400_series.pdf */
625 .ai = das16_ai_rinsn,
628 .ai_pg = das16_pg_1602,
630 .di = das16_di_rbits,
631 .do_ = das16_do_wbits,
633 .i8254_offset = 0x0c,
637 .name = "cio-das1402/16", /* cio-das1400_series.pdf */
638 .ai = das16_ai_rinsn,
641 .ai_pg = das16_pg_1602,
643 .di = das16_di_rbits,
644 .do_ = das16_do_wbits,
646 .i8254_offset = 0x0c,
650 .name = "cio-das1601/12", /* cio-das160x-1x.pdf */
651 .ai = das16_ai_rinsn,
654 .ai_pg = das16_pg_1601,
655 .ao = das16_ao_winsn,
657 .di = das16_di_rbits,
658 .do_ = das16_do_wbits,
659 .i8255_offset = 0x400,
660 .i8254_offset = 0x0c,
664 .name = "cio-das1602/12", /* cio-das160x-1x.pdf */
665 .ai = das16_ai_rinsn,
668 .ai_pg = das16_pg_1602,
669 .ao = das16_ao_winsn,
671 .di = das16_di_rbits,
672 .do_ = das16_do_wbits,
673 .i8255_offset = 0x400,
674 .i8254_offset = 0x0c,
678 .name = "cio-das1602/16", /* cio-das160x-1x.pdf */
679 .ai = das16_ai_rinsn,
682 .ai_pg = das16_pg_1602,
683 .ao = das16_ao_winsn,
685 .di = das16_di_rbits,
686 .do_ = das16_do_wbits,
687 .i8255_offset = 0x400,
688 .i8254_offset = 0x0c,
692 .name = "cio-das16/330", /* ? */
693 .ai = das16_ai_rinsn,
696 .ai_pg = das16_pg_16jr,
698 .di = das16_di_rbits,
699 .do_ = das16_do_wbits,
701 .i8254_offset = 0x0c,
706 .name = "das16/330i", /* ? */
709 .name = "das16/jr/ctr5", /* ? */
712 /* cio-das16_m1_16.pdf, this board is a bit quirky, no dma */
713 .name = "cio-das16/m1/16",
718 static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it);
719 static int das16_detach(struct comedi_device *dev);
720 static struct comedi_driver driver_das16 = {
721 .driver_name = "das16",
722 .module = THIS_MODULE,
723 .attach = das16_attach,
724 .detach = das16_detach,
725 .board_name = &das16_boards[0].name,
726 .num_names = ARRAY_SIZE(das16_boards),
727 .offset = sizeof(das16_boards[0]),
730 #define DAS16_TIMEOUT 1000
732 /* Period for timer interrupt in jiffies. It's a function
733 * to deal with possibility of dynamic HZ patches */
734 static inline int timer_period(void)
739 struct das16_private_struct {
740 unsigned int ai_unipolar; /* unipolar flag */
741 unsigned int ai_singleended; /* single ended flag */
742 unsigned int clockbase; /* master clock speed in ns */
743 volatile unsigned int control_state; /* dma, interrupt and trigger control bits */
744 volatile unsigned long adc_byte_count; /* number of bytes remaining */
745 /* divisor dividing master clock to get conversion frequency */
746 unsigned int divisor1;
747 /* divisor dividing master clock to get conversion frequency */
748 unsigned int divisor2;
749 unsigned int dma_chan; /* dma channel */
750 uint16_t *dma_buffer[2];
751 dma_addr_t dma_buffer_addr[2];
752 unsigned int current_buffer;
753 volatile unsigned int dma_transfer_size; /* target number of bytes to transfer per dma shot */
755 * user-defined analog input and output ranges
756 * defined from config options
758 struct comedi_lrange *user_ai_range_table;
759 struct comedi_lrange *user_ao_range_table;
761 struct timer_list timer; /* for timed interrupt */
762 volatile short timer_running;
763 volatile short timer_mode; /* true if using timer mode */
765 #define devpriv ((struct das16_private_struct *)(dev->private))
766 #define thisboard ((struct das16_board *)(dev->board_ptr))
768 static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
769 struct comedi_cmd *cmd)
772 int gain, start_chan, i;
775 /* make sure triggers are valid */
776 tmp = cmd->start_src;
777 cmd->start_src &= TRIG_NOW;
778 if (!cmd->start_src || tmp != cmd->start_src)
781 tmp = cmd->scan_begin_src;
783 /* if board supports burst mode */
784 if (thisboard->size > 0x400)
785 mask |= TRIG_TIMER | TRIG_EXT;
786 cmd->scan_begin_src &= mask;
787 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
790 tmp = cmd->convert_src;
791 mask = TRIG_TIMER | TRIG_EXT;
792 /* if board supports burst mode */
793 if (thisboard->size > 0x400)
795 cmd->convert_src &= mask;
796 if (!cmd->convert_src || tmp != cmd->convert_src)
799 tmp = cmd->scan_end_src;
800 cmd->scan_end_src &= TRIG_COUNT;
801 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
805 cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
806 if (!cmd->stop_src || tmp != cmd->stop_src)
813 * step 2: make sure trigger sources are unique and
814 * mutually compatible
816 if (cmd->scan_begin_src != TRIG_TIMER &&
817 cmd->scan_begin_src != TRIG_EXT &&
818 cmd->scan_begin_src != TRIG_FOLLOW)
820 if (cmd->convert_src != TRIG_TIMER &&
821 cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
823 if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
826 /* make sure scan_begin_src and convert_src dont conflict */
827 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
829 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
835 /* step 3: make sure arguments are trivially compatible */
836 if (cmd->start_arg != 0) {
841 if (cmd->scan_begin_src == TRIG_FOLLOW) {
842 /* internal trigger */
843 if (cmd->scan_begin_arg != 0) {
844 cmd->scan_begin_arg = 0;
849 if (cmd->scan_end_arg != cmd->chanlist_len) {
850 cmd->scan_end_arg = cmd->chanlist_len;
853 /* check against maximum frequency */
854 if (cmd->scan_begin_src == TRIG_TIMER) {
855 if (cmd->scan_begin_arg <
856 thisboard->ai_speed * cmd->chanlist_len) {
857 cmd->scan_begin_arg =
858 thisboard->ai_speed * cmd->chanlist_len;
862 if (cmd->convert_src == TRIG_TIMER) {
863 if (cmd->convert_arg < thisboard->ai_speed) {
864 cmd->convert_arg = thisboard->ai_speed;
869 if (cmd->stop_src == TRIG_NONE) {
870 if (cmd->stop_arg != 0) {
878 /* step 4: fix up arguments */
879 if (cmd->scan_begin_src == TRIG_TIMER) {
880 unsigned int tmp = cmd->scan_begin_arg;
881 /* set divisors, correct timing arguments */
882 i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
883 &(devpriv->divisor1),
884 &(devpriv->divisor2),
885 &(cmd->scan_begin_arg),
886 cmd->flags & TRIG_ROUND_MASK);
887 err += (tmp != cmd->scan_begin_arg);
889 if (cmd->convert_src == TRIG_TIMER) {
890 unsigned int tmp = cmd->convert_arg;
891 /* set divisors, correct timing arguments */
892 i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
893 &(devpriv->divisor1),
894 &(devpriv->divisor2),
896 cmd->flags & TRIG_ROUND_MASK);
897 err += (tmp != cmd->convert_arg);
902 /* check channel/gain list against card's limitations */
904 gain = CR_RANGE(cmd->chanlist[0]);
905 start_chan = CR_CHAN(cmd->chanlist[0]);
906 for (i = 1; i < cmd->chanlist_len; i++) {
907 if (CR_CHAN(cmd->chanlist[i]) !=
908 (start_chan + i) % s->n_chan) {
910 "entries in chanlist must be "
911 "consecutive channels, "
912 "counting upwards\n");
915 if (CR_RANGE(cmd->chanlist[i]) != gain) {
917 "entries in chanlist must all "
918 "have the same gain\n");
929 static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
931 struct comedi_async *async = s->async;
932 struct comedi_cmd *cmd = &async->cmd;
937 if (devpriv->dma_chan == 0 || (dev->irq == 0
938 && devpriv->timer_mode == 0)) {
940 "irq (or use of 'timer mode') dma required to "
941 "execute comedi_cmd");
944 if (cmd->flags & TRIG_RT) {
945 comedi_error(dev, "isa dma transfers cannot be performed with "
946 "TRIG_RT, aborting");
950 devpriv->adc_byte_count =
951 cmd->stop_arg * cmd->chanlist_len * sizeof(uint16_t);
953 /* disable conversions for das1600 mode */
954 if (thisboard->size > 0x400)
955 outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV);
957 /* set scan limits */
958 byte = CR_CHAN(cmd->chanlist[0]);
959 byte |= CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]) << 4;
960 outb(byte, dev->iobase + DAS16_MUX);
962 /* set gain (this is also burst rate register but according to
963 * computer boards manual, burst rate does nothing, even on
965 if (thisboard->ai_pg != das16_pg_none) {
966 range = CR_RANGE(cmd->chanlist[0]);
967 outb((das16_gainlists[thisboard->ai_pg])[range],
968 dev->iobase + DAS16_GAIN);
971 /* set counter mode and counts */
973 das16_set_pacer(dev, cmd->convert_arg,
974 cmd->flags & TRIG_ROUND_MASK);
975 DEBUG_PRINT("pacer period: %d ns\n", cmd->convert_arg);
977 /* enable counters */
979 /* Enable burst mode if appropriate. */
980 if (thisboard->size > 0x400) {
981 if (cmd->convert_src == TRIG_NOW) {
982 outb(DAS1600_BURST_VAL, dev->iobase + DAS1600_BURST);
983 /* set burst length */
984 byte |= BURST_LEN_BITS(cmd->chanlist_len - 1);
986 outb(0, dev->iobase + DAS1600_BURST);
989 outb(byte, dev->iobase + DAS16_PACER);
991 /* set up dma transfer */
992 flags = claim_dma_lock();
993 disable_dma(devpriv->dma_chan);
994 /* clear flip-flop to make sure 2-byte registers for
995 * count and address get set correctly */
996 clear_dma_ff(devpriv->dma_chan);
997 devpriv->current_buffer = 0;
998 set_dma_addr(devpriv->dma_chan,
999 devpriv->dma_buffer_addr[devpriv->current_buffer]);
1000 /* set appropriate size of transfer */
1001 devpriv->dma_transfer_size = das16_suggest_transfer_size(dev, *cmd);
1002 set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
1003 enable_dma(devpriv->dma_chan);
1004 release_dma_lock(flags);
1006 /* set up interrupt */
1007 if (devpriv->timer_mode) {
1008 devpriv->timer_running = 1;
1009 devpriv->timer.expires = jiffies + timer_period();
1010 add_timer(&devpriv->timer);
1011 devpriv->control_state &= ~DAS16_INTE;
1013 /* clear interrupt bit */
1014 outb(0x00, dev->iobase + DAS16_STATUS);
1015 /* enable interrupts */
1016 devpriv->control_state |= DAS16_INTE;
1018 devpriv->control_state |= DMA_ENABLE;
1019 devpriv->control_state &= ~PACING_MASK;
1020 if (cmd->convert_src == TRIG_EXT)
1021 devpriv->control_state |= EXT_PACER;
1023 devpriv->control_state |= INT_PACER;
1024 outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
1026 /* Enable conversions if using das1600 mode */
1027 if (thisboard->size > 0x400)
1028 outb(0, dev->iobase + DAS1600_CONV);
1034 static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1036 unsigned long flags;
1038 spin_lock_irqsave(&dev->spinlock, flags);
1039 /* disable interrupts, dma and pacer clocked conversions */
1040 devpriv->control_state &= ~DAS16_INTE & ~PACING_MASK & ~DMA_ENABLE;
1041 outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
1042 if (devpriv->dma_chan)
1043 disable_dma(devpriv->dma_chan);
1045 /* disable SW timer */
1046 if (devpriv->timer_mode && devpriv->timer_running) {
1047 devpriv->timer_running = 0;
1048 del_timer(&devpriv->timer);
1051 /* disable burst mode */
1052 if (thisboard->size > 0x400)
1053 outb(0, dev->iobase + DAS1600_BURST);
1056 spin_unlock_irqrestore(&dev->spinlock, flags);
1061 static void das16_reset(struct comedi_device *dev)
1063 outb(0, dev->iobase + DAS16_STATUS);
1064 outb(0, dev->iobase + DAS16_CONTROL);
1065 outb(0, dev->iobase + DAS16_PACER);
1066 outb(0, dev->iobase + DAS16_CNTR_CONTROL);
1069 static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
1070 struct comedi_insn *insn, unsigned int *data)
1077 /* disable interrupts and pacing */
1078 devpriv->control_state &= ~DAS16_INTE & ~DMA_ENABLE & ~PACING_MASK;
1079 outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
1081 /* set multiplexer */
1082 chan = CR_CHAN(insn->chanspec);
1083 chan |= CR_CHAN(insn->chanspec) << 4;
1084 outb(chan, dev->iobase + DAS16_MUX);
1087 if (thisboard->ai_pg != das16_pg_none) {
1088 range = CR_RANGE(insn->chanspec);
1089 outb((das16_gainlists[thisboard->ai_pg])[range],
1090 dev->iobase + DAS16_GAIN);
1093 for (n = 0; n < insn->n; n++) {
1094 /* trigger conversion */
1095 outb_p(0, dev->iobase + DAS16_TRIG);
1097 for (i = 0; i < DAS16_TIMEOUT; i++) {
1098 if (!(inb(dev->iobase + DAS16_STATUS) & BUSY))
1101 if (i == DAS16_TIMEOUT) {
1102 printk("das16: timeout\n");
1105 msb = inb(dev->iobase + DAS16_AI_MSB);
1106 lsb = inb(dev->iobase + DAS16_AI_LSB);
1107 if (thisboard->ai_nbits == 12)
1108 data[n] = ((lsb >> 4) & 0xf) | (msb << 4);
1110 data[n] = lsb | (msb << 8);
1117 static int das16_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
1118 struct comedi_insn *insn, unsigned int *data)
1122 bits = inb(dev->iobase + DAS16_DIO) & 0xf;
1129 static int das16_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
1130 struct comedi_insn *insn, unsigned int *data)
1134 /* only set bits that have been masked */
1137 /* zero bits that have been masked */
1139 /* set masked bits */
1140 wbits |= data[0] & data[1];
1144 outb(s->state, dev->iobase + DAS16_DIO);
1149 static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
1150 struct comedi_insn *insn, unsigned int *data)
1156 chan = CR_CHAN(insn->chanspec);
1158 for (i = 0; i < insn->n; i++) {
1159 if (thisboard->ao_nbits == 12) {
1160 lsb = (data[i] << 4) & 0xff;
1161 msb = (data[i] >> 4) & 0xff;
1163 lsb = data[i] & 0xff;
1164 msb = (data[i] >> 8) & 0xff;
1166 outb(lsb, dev->iobase + DAS16_AO_LSB(chan));
1167 outb(msb, dev->iobase + DAS16_AO_MSB(chan));
1173 static irqreturn_t das16_dma_interrupt(int irq, void *d)
1176 struct comedi_device *dev = d;
1178 status = inb(dev->iobase + DAS16_STATUS);
1180 if ((status & DAS16_INT) == 0) {
1181 DEBUG_PRINT("spurious interrupt\n");
1185 /* clear interrupt */
1186 outb(0x00, dev->iobase + DAS16_STATUS);
1187 das16_interrupt(dev);
1191 static void das16_timer_interrupt(unsigned long arg)
1193 struct comedi_device *dev = (struct comedi_device *)arg;
1195 das16_interrupt(dev);
1197 if (devpriv->timer_running)
1198 mod_timer(&devpriv->timer, jiffies + timer_period());
1201 /* the pc104-das16jr (at least) has problems if the dma
1202 transfer is interrupted in the middle of transferring
1203 a 16 bit sample, so this function takes care to get
1204 an even transfer count after disabling dma
1207 static int disable_dma_on_even(struct comedi_device *dev)
1211 static const int disable_limit = 100;
1212 static const int enable_timeout = 100;
1213 disable_dma(devpriv->dma_chan);
1214 residue = get_dma_residue(devpriv->dma_chan);
1215 for (i = 0; i < disable_limit && (residue % 2); ++i) {
1217 enable_dma(devpriv->dma_chan);
1218 for (j = 0; j < enable_timeout; ++j) {
1221 new_residue = get_dma_residue(devpriv->dma_chan);
1222 if (new_residue != residue)
1225 disable_dma(devpriv->dma_chan);
1226 residue = get_dma_residue(devpriv->dma_chan);
1228 if (i == disable_limit) {
1229 comedi_error(dev, "failed to get an even dma transfer, "
1230 "could be trouble.");
1235 static void das16_interrupt(struct comedi_device *dev)
1237 unsigned long dma_flags, spin_flags;
1238 struct comedi_subdevice *s = dev->read_subdev;
1239 struct comedi_async *async;
1240 struct comedi_cmd *cmd;
1241 int num_bytes, residue;
1244 if (dev->attached == 0) {
1245 comedi_error(dev, "premature interrupt");
1248 /* initialize async here to make sure it is not NULL */
1252 if (devpriv->dma_chan == 0) {
1253 comedi_error(dev, "interrupt with no dma channel?");
1257 spin_lock_irqsave(&dev->spinlock, spin_flags);
1258 if ((devpriv->control_state & DMA_ENABLE) == 0) {
1259 spin_unlock_irqrestore(&dev->spinlock, spin_flags);
1260 DEBUG_PRINT("interrupt while dma disabled?\n");
1264 dma_flags = claim_dma_lock();
1265 clear_dma_ff(devpriv->dma_chan);
1266 residue = disable_dma_on_even(dev);
1268 /* figure out how many points to read */
1269 if (residue > devpriv->dma_transfer_size) {
1270 comedi_error(dev, "residue > transfer size!\n");
1271 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1274 num_bytes = devpriv->dma_transfer_size - residue;
1276 if (cmd->stop_src == TRIG_COUNT &&
1277 num_bytes >= devpriv->adc_byte_count) {
1278 num_bytes = devpriv->adc_byte_count;
1279 async->events |= COMEDI_CB_EOA;
1282 buffer_index = devpriv->current_buffer;
1283 devpriv->current_buffer = (devpriv->current_buffer + 1) % 2;
1284 devpriv->adc_byte_count -= num_bytes;
1286 /* figure out how many bytes for next transfer */
1287 if (cmd->stop_src == TRIG_COUNT && devpriv->timer_mode == 0 &&
1288 devpriv->dma_transfer_size > devpriv->adc_byte_count)
1289 devpriv->dma_transfer_size = devpriv->adc_byte_count;
1292 if ((async->events & COMEDI_CB_EOA) == 0) {
1293 set_dma_addr(devpriv->dma_chan,
1294 devpriv->dma_buffer_addr[devpriv->current_buffer]);
1295 set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
1296 enable_dma(devpriv->dma_chan);
1297 /* reenable conversions for das1600 mode, (stupid hardware) */
1298 if (thisboard->size > 0x400 && devpriv->timer_mode == 0)
1299 outb(0x00, dev->iobase + DAS1600_CONV);
1302 release_dma_lock(dma_flags);
1304 spin_unlock_irqrestore(&dev->spinlock, spin_flags);
1306 cfc_write_array_to_buffer(s,
1307 devpriv->dma_buffer[buffer_index], num_bytes);
1309 cfc_handle_events(dev, s);
1312 static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
1315 i8253_cascade_ns_to_timer_2div(devpriv->clockbase, &(devpriv->divisor1),
1316 &(devpriv->divisor2), &ns,
1317 rounding_flags & TRIG_ROUND_MASK);
1319 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1320 i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 1, devpriv->divisor1, 2);
1321 i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 2, devpriv->divisor2, 2);
1326 static void reg_dump(struct comedi_device *dev)
1328 DEBUG_PRINT("********DAS1600 REGISTER DUMP********\n");
1329 DEBUG_PRINT("DAS16_MUX: %x\n", inb(dev->iobase + DAS16_MUX));
1330 DEBUG_PRINT("DAS16_DIO: %x\n", inb(dev->iobase + DAS16_DIO));
1331 DEBUG_PRINT("DAS16_STATUS: %x\n", inb(dev->iobase + DAS16_STATUS));
1332 DEBUG_PRINT("DAS16_CONTROL: %x\n", inb(dev->iobase + DAS16_CONTROL));
1333 DEBUG_PRINT("DAS16_PACER: %x\n", inb(dev->iobase + DAS16_PACER));
1334 DEBUG_PRINT("DAS16_GAIN: %x\n", inb(dev->iobase + DAS16_GAIN));
1335 DEBUG_PRINT("DAS16_CNTR_CONTROL: %x\n",
1336 inb(dev->iobase + DAS16_CNTR_CONTROL));
1337 DEBUG_PRINT("DAS1600_CONV: %x\n", inb(dev->iobase + DAS1600_CONV));
1338 DEBUG_PRINT("DAS1600_BURST: %x\n", inb(dev->iobase + DAS1600_BURST));
1339 DEBUG_PRINT("DAS1600_ENABLE: %x\n", inb(dev->iobase + DAS1600_ENABLE));
1340 DEBUG_PRINT("DAS1600_STATUS_B: %x\n",
1341 inb(dev->iobase + DAS1600_STATUS_B));
1344 static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it)
1349 /* status is available on all boards */
1351 status = inb(dev->iobase + DAS16_STATUS);
1353 if ((status & UNIPOLAR))
1354 devpriv->ai_unipolar = 1;
1356 devpriv->ai_unipolar = 0;
1359 if ((status & DAS16_MUXBIT))
1360 devpriv->ai_singleended = 1;
1362 devpriv->ai_singleended = 0;
1365 /* diobits indicates boards */
1367 diobits = inb(dev->iobase + DAS16_DIO) & 0xf0;
1369 printk(KERN_INFO " id bits are 0x%02x\n", diobits);
1370 if (thisboard->id != diobits) {
1371 printk(KERN_INFO " requested board's id bits are 0x%x (ignore)\n",
1378 static int das1600_mode_detect(struct comedi_device *dev)
1382 status = inb(dev->iobase + DAS1600_STATUS_B);
1384 if (status & DAS1600_CLK_10MHZ) {
1385 devpriv->clockbase = 100;
1386 printk(KERN_INFO " 10MHz pacer clock\n");
1388 devpriv->clockbase = 1000;
1389 printk(KERN_INFO " 1MHz pacer clock\n");
1403 * 3 Clock speed (in MHz)
1406 static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1408 struct comedi_subdevice *s;
1411 unsigned long iobase;
1412 unsigned int dma_chan;
1414 unsigned long flags;
1415 struct comedi_krange *user_ai_range, *user_ao_range;
1417 iobase = it->options[0];
1419 irq = it->options[1];
1420 timer_mode = it->options[8];
1422 /* always use time_mode since using irq can drop samples while
1423 * waiting for dma done interrupt (due to hardware limitations) */
1429 printk(KERN_INFO "comedi%d: das16:", dev->minor);
1431 /* check that clock setting is valid */
1432 if (it->options[3]) {
1433 if (it->options[3] != 0 &&
1434 it->options[3] != 1 && it->options[3] != 10) {
1436 ("\n Invalid option. Master clock must be set "
1437 "to 1 or 10 (MHz)\n");
1442 ret = alloc_private(dev, sizeof(struct das16_private_struct));
1446 if (thisboard->size < 0x400) {
1447 printk(" 0x%04lx-0x%04lx\n", iobase, iobase + thisboard->size);
1448 if (!request_region(iobase, thisboard->size, "das16")) {
1449 printk(KERN_ERR " I/O port conflict\n");
1453 printk(KERN_INFO " 0x%04lx-0x%04lx 0x%04lx-0x%04lx\n",
1454 iobase, iobase + 0x0f,
1456 iobase + 0x400 + (thisboard->size & 0x3ff));
1457 if (!request_region(iobase, 0x10, "das16")) {
1458 printk(KERN_ERR " I/O port conflict: 0x%04lx-0x%04lx\n",
1459 iobase, iobase + 0x0f);
1462 if (!request_region(iobase + 0x400, thisboard->size & 0x3ff,
1464 release_region(iobase, 0x10);
1465 printk(KERN_ERR " I/O port conflict: 0x%04lx-0x%04lx\n",
1467 iobase + 0x400 + (thisboard->size & 0x3ff));
1472 dev->iobase = iobase;
1474 /* probe id bits to make sure they are consistent */
1475 if (das16_probe(dev, it)) {
1476 printk(KERN_ERR " id bits do not match selected board, aborting\n");
1479 dev->board_name = thisboard->name;
1481 /* get master clock speed */
1482 if (thisboard->size < 0x400) {
1484 devpriv->clockbase = 1000 / it->options[3];
1486 devpriv->clockbase = 1000; /* 1 MHz default */
1488 das1600_mode_detect(dev);
1491 /* now for the irq */
1492 if (irq > 1 && irq < 8) {
1493 ret = request_irq(irq, das16_dma_interrupt, 0, "das16", dev);
1498 printk(KERN_INFO " ( irq = %u )", irq);
1499 } else if (irq == 0) {
1500 printk(" ( no irq )");
1502 printk(" invalid irq\n");
1506 /* initialize dma */
1507 dma_chan = it->options[2];
1508 if (dma_chan == 1 || dma_chan == 3) {
1509 /* allocate dma buffers */
1511 for (i = 0; i < 2; i++) {
1512 devpriv->dma_buffer[i] = pci_alloc_consistent(
1513 NULL, DAS16_DMA_SIZE,
1514 &devpriv->dma_buffer_addr[i]);
1516 if (devpriv->dma_buffer[i] == NULL)
1519 if (request_dma(dma_chan, "das16")) {
1520 printk(KERN_ERR " failed to allocate dma channel %i\n",
1524 devpriv->dma_chan = dma_chan;
1525 flags = claim_dma_lock();
1526 disable_dma(devpriv->dma_chan);
1527 set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
1528 release_dma_lock(flags);
1529 printk(KERN_INFO " ( dma = %u)\n", dma_chan);
1530 } else if (dma_chan == 0) {
1531 printk(KERN_INFO " ( no dma )\n");
1533 printk(KERN_ERR " invalid dma channel\n");
1537 /* get any user-defined input range */
1538 if (thisboard->ai_pg == das16_pg_none &&
1539 (it->options[4] || it->options[5])) {
1540 /* allocate single-range range table */
1541 devpriv->user_ai_range_table =
1542 kmalloc(sizeof(struct comedi_lrange) +
1543 sizeof(struct comedi_krange), GFP_KERNEL);
1544 /* initialize ai range */
1545 devpriv->user_ai_range_table->length = 1;
1546 user_ai_range = devpriv->user_ai_range_table->range;
1547 user_ai_range->min = it->options[4];
1548 user_ai_range->max = it->options[5];
1549 user_ai_range->flags = UNIT_volt;
1551 /* get any user-defined output range */
1552 if (it->options[6] || it->options[7]) {
1553 /* allocate single-range range table */
1554 devpriv->user_ao_range_table =
1555 kmalloc(sizeof(struct comedi_lrange) +
1556 sizeof(struct comedi_krange), GFP_KERNEL);
1557 /* initialize ao range */
1558 devpriv->user_ao_range_table->length = 1;
1559 user_ao_range = devpriv->user_ao_range_table->range;
1560 user_ao_range->min = it->options[6];
1561 user_ao_range->max = it->options[7];
1562 user_ao_range->flags = UNIT_volt;
1566 init_timer(&(devpriv->timer));
1567 devpriv->timer.function = das16_timer_interrupt;
1568 devpriv->timer.data = (unsigned long)dev;
1570 devpriv->timer_mode = timer_mode ? 1 : 0;
1572 ret = alloc_subdevices(dev, 5);
1576 s = dev->subdevices + 0;
1577 dev->read_subdev = s;
1579 if (thisboard->ai) {
1580 s->type = COMEDI_SUBD_AI;
1581 s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
1582 if (devpriv->ai_singleended) {
1584 s->len_chanlist = 16;
1585 s->subdev_flags |= SDF_GROUND;
1588 s->len_chanlist = 8;
1589 s->subdev_flags |= SDF_DIFF;
1591 s->maxdata = (1 << thisboard->ai_nbits) - 1;
1592 if (devpriv->user_ai_range_table) { /* user defined ai range */
1593 s->range_table = devpriv->user_ai_range_table;
1594 } else if (devpriv->ai_unipolar) {
1595 s->range_table = das16_ai_uni_lranges[thisboard->ai_pg];
1597 s->range_table = das16_ai_bip_lranges[thisboard->ai_pg];
1599 s->insn_read = thisboard->ai;
1600 s->do_cmdtest = das16_cmd_test;
1601 s->do_cmd = das16_cmd_exec;
1602 s->cancel = das16_cancel;
1603 s->munge = das16_ai_munge;
1605 s->type = COMEDI_SUBD_UNUSED;
1608 s = dev->subdevices + 1;
1610 if (thisboard->ao) {
1611 s->type = COMEDI_SUBD_AO;
1612 s->subdev_flags = SDF_WRITABLE;
1614 s->maxdata = (1 << thisboard->ao_nbits) - 1;
1615 /* user defined ao range */
1616 if (devpriv->user_ao_range_table)
1617 s->range_table = devpriv->user_ao_range_table;
1619 s->range_table = &range_unknown;
1621 s->insn_write = thisboard->ao;
1623 s->type = COMEDI_SUBD_UNUSED;
1626 s = dev->subdevices + 2;
1628 if (thisboard->di) {
1629 s->type = COMEDI_SUBD_DI;
1630 s->subdev_flags = SDF_READABLE;
1633 s->range_table = &range_digital;
1634 s->insn_bits = thisboard->di;
1636 s->type = COMEDI_SUBD_UNUSED;
1639 s = dev->subdevices + 3;
1641 if (thisboard->do_) {
1642 s->type = COMEDI_SUBD_DO;
1643 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1646 s->range_table = &range_digital;
1647 s->insn_bits = thisboard->do_;
1648 /* initialize digital output lines */
1649 outb(s->state, dev->iobase + DAS16_DIO);
1651 s->type = COMEDI_SUBD_UNUSED;
1654 s = dev->subdevices + 4;
1656 if (thisboard->i8255_offset != 0) {
1657 subdev_8255_init(dev, s, NULL, (dev->iobase +
1658 thisboard->i8255_offset));
1660 s->type = COMEDI_SUBD_UNUSED;
1664 /* set the interrupt level */
1665 devpriv->control_state = DAS16_IRQ(dev->irq);
1666 outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
1668 /* turn on das1600 mode if available */
1669 if (thisboard->size > 0x400) {
1670 outb(DAS1600_ENABLE_VAL, dev->iobase + DAS1600_ENABLE);
1671 outb(0, dev->iobase + DAS1600_CONV);
1672 outb(0, dev->iobase + DAS1600_BURST);
1678 static int das16_detach(struct comedi_device *dev)
1680 printk(KERN_INFO "comedi%d: das16: remove\n", dev->minor);
1684 if (dev->subdevices)
1685 subdev_8255_cleanup(dev, dev->subdevices + 4);
1689 for (i = 0; i < 2; i++) {
1690 if (devpriv->dma_buffer[i])
1691 pci_free_consistent(NULL, DAS16_DMA_SIZE,
1692 devpriv->dma_buffer[i],
1694 dma_buffer_addr[i]);
1696 if (devpriv->dma_chan)
1697 free_dma(devpriv->dma_chan);
1698 if (devpriv->user_ai_range_table)
1699 kfree(devpriv->user_ai_range_table);
1700 if (devpriv->user_ao_range_table)
1701 kfree(devpriv->user_ao_range_table);
1705 free_irq(dev->irq, dev);
1708 if (thisboard->size < 0x400) {
1709 release_region(dev->iobase, thisboard->size);
1711 release_region(dev->iobase, 0x10);
1712 release_region(dev->iobase + 0x400,
1713 thisboard->size & 0x3ff);
1720 COMEDI_INITCLEANUP(driver_das16);
1722 /* utility function that suggests a dma transfer size in bytes */
1723 static unsigned int das16_suggest_transfer_size(struct comedi_device *dev,
1724 struct comedi_cmd cmd)
1729 /* if we are using timer interrupt, we don't care how long it
1730 * will take to complete transfer since it will be interrupted
1731 * by timer interrupt */
1732 if (devpriv->timer_mode)
1733 return DAS16_DMA_SIZE;
1735 /* otherwise, we are relying on dma terminal count interrupt,
1736 * so pick a reasonable size */
1737 if (cmd.convert_src == TRIG_TIMER)
1738 freq = 1000000000 / cmd.convert_arg;
1739 else if (cmd.scan_begin_src == TRIG_TIMER)
1740 freq = (1000000000 / cmd.scan_begin_arg) * cmd.chanlist_len;
1741 /* return some default value */
1745 if (cmd.flags & TRIG_WAKE_EOS) {
1746 size = sample_size * cmd.chanlist_len;
1748 /* make buffer fill in no more than 1/3 second */
1749 size = (freq / 3) * sample_size;
1752 /* set a minimum and maximum size allowed */
1753 if (size > DAS16_DMA_SIZE)
1754 size = DAS16_DMA_SIZE - DAS16_DMA_SIZE % sample_size;
1755 else if (size < sample_size)
1758 if (cmd.stop_src == TRIG_COUNT && size > devpriv->adc_byte_count)
1759 size = devpriv->adc_byte_count;
1764 static void das16_ai_munge(struct comedi_device *dev,
1765 struct comedi_subdevice *s, void *array,
1766 unsigned int num_bytes,
1767 unsigned int start_chan_index)
1769 unsigned int i, num_samples = num_bytes / sizeof(short);
1770 short *data = array;
1772 for (i = 0; i < num_samples; i++) {
1773 data[i] = le16_to_cpu(data[i]);
1774 if (thisboard->ai_nbits == 12)
1775 data[i] = (data[i] >> 4) & 0xfff;