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 static int das16_attach(struct comedi_device
*dev
, struct comedi_devconfig
*it
);
707 static int das16_detach(struct comedi_device
*dev
);
708 static struct comedi_driver driver_das16
= {
709 .driver_name
= "das16",
710 .module
= THIS_MODULE
,
711 .attach
= das16_attach
,
712 .detach
= das16_detach
,
713 .board_name
= &das16_boards
[0].name
,
714 .num_names
= ARRAY_SIZE(das16_boards
),
715 .offset
= sizeof(das16_boards
[0]),
718 #define DAS16_TIMEOUT 1000
720 /* Period for timer interrupt in jiffies. It's a function
721 * to deal with possibility of dynamic HZ patches */
722 static inline int timer_period(void)
727 struct das16_private_struct
{
728 unsigned int ai_unipolar
; /* unipolar flag */
729 unsigned int ai_singleended
; /* single ended flag */
730 unsigned int clockbase
; /* master clock speed in ns */
731 volatile unsigned int control_state
; /* dma, interrupt and trigger control bits */
732 volatile unsigned long adc_byte_count
; /* number of bytes remaining */
733 /* divisor dividing master clock to get conversion frequency */
734 unsigned int divisor1
;
735 /* divisor dividing master clock to get conversion frequency */
736 unsigned int divisor2
;
737 unsigned int dma_chan
; /* dma channel */
738 uint16_t *dma_buffer
[2];
739 dma_addr_t dma_buffer_addr
[2];
740 unsigned int current_buffer
;
741 volatile unsigned int dma_transfer_size
; /* target number of bytes to transfer per dma shot */
743 * user-defined analog input and output ranges
744 * defined from config options
746 struct comedi_lrange
*user_ai_range_table
;
747 struct comedi_lrange
*user_ao_range_table
;
749 struct timer_list timer
; /* for timed interrupt */
750 volatile short timer_running
;
751 volatile short timer_mode
; /* true if using timer mode */
753 #define devpriv ((struct das16_private_struct *)(dev->private))
754 #define thisboard ((struct das16_board *)(dev->board_ptr))
756 static int das16_cmd_test(struct comedi_device
*dev
, struct comedi_subdevice
*s
,
757 struct comedi_cmd
*cmd
)
760 int gain
, start_chan
, i
;
763 /* make sure triggers are valid */
764 tmp
= cmd
->start_src
;
765 cmd
->start_src
&= TRIG_NOW
;
766 if (!cmd
->start_src
|| tmp
!= cmd
->start_src
)
769 tmp
= cmd
->scan_begin_src
;
771 /* if board supports burst mode */
772 if (thisboard
->size
> 0x400)
773 mask
|= TRIG_TIMER
| TRIG_EXT
;
774 cmd
->scan_begin_src
&= mask
;
775 if (!cmd
->scan_begin_src
|| tmp
!= cmd
->scan_begin_src
)
778 tmp
= cmd
->convert_src
;
779 mask
= TRIG_TIMER
| TRIG_EXT
;
780 /* if board supports burst mode */
781 if (thisboard
->size
> 0x400)
783 cmd
->convert_src
&= mask
;
784 if (!cmd
->convert_src
|| tmp
!= cmd
->convert_src
)
787 tmp
= cmd
->scan_end_src
;
788 cmd
->scan_end_src
&= TRIG_COUNT
;
789 if (!cmd
->scan_end_src
|| tmp
!= cmd
->scan_end_src
)
793 cmd
->stop_src
&= TRIG_COUNT
| TRIG_NONE
;
794 if (!cmd
->stop_src
|| tmp
!= cmd
->stop_src
)
801 * step 2: make sure trigger sources are unique and
802 * mutually compatible
804 if (cmd
->scan_begin_src
!= TRIG_TIMER
&&
805 cmd
->scan_begin_src
!= TRIG_EXT
&&
806 cmd
->scan_begin_src
!= TRIG_FOLLOW
)
808 if (cmd
->convert_src
!= TRIG_TIMER
&&
809 cmd
->convert_src
!= TRIG_EXT
&& cmd
->convert_src
!= TRIG_NOW
)
811 if (cmd
->stop_src
!= TRIG_NONE
&& cmd
->stop_src
!= TRIG_COUNT
)
814 /* make sure scan_begin_src and convert_src dont conflict */
815 if (cmd
->scan_begin_src
== TRIG_FOLLOW
&& cmd
->convert_src
== TRIG_NOW
)
817 if (cmd
->scan_begin_src
!= TRIG_FOLLOW
&& cmd
->convert_src
!= TRIG_NOW
)
823 /* step 3: make sure arguments are trivially compatible */
824 if (cmd
->start_arg
!= 0) {
829 if (cmd
->scan_begin_src
== TRIG_FOLLOW
) {
830 /* internal trigger */
831 if (cmd
->scan_begin_arg
!= 0) {
832 cmd
->scan_begin_arg
= 0;
837 if (cmd
->scan_end_arg
!= cmd
->chanlist_len
) {
838 cmd
->scan_end_arg
= cmd
->chanlist_len
;
841 /* check against maximum frequency */
842 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
843 if (cmd
->scan_begin_arg
<
844 thisboard
->ai_speed
* cmd
->chanlist_len
) {
845 cmd
->scan_begin_arg
=
846 thisboard
->ai_speed
* cmd
->chanlist_len
;
850 if (cmd
->convert_src
== TRIG_TIMER
) {
851 if (cmd
->convert_arg
< thisboard
->ai_speed
) {
852 cmd
->convert_arg
= thisboard
->ai_speed
;
857 if (cmd
->stop_src
== TRIG_NONE
) {
858 if (cmd
->stop_arg
!= 0) {
866 /* step 4: fix up arguments */
867 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
868 unsigned int tmp
= cmd
->scan_begin_arg
;
869 /* set divisors, correct timing arguments */
870 i8253_cascade_ns_to_timer_2div(devpriv
->clockbase
,
871 &(devpriv
->divisor1
),
872 &(devpriv
->divisor2
),
873 &(cmd
->scan_begin_arg
),
874 cmd
->flags
& TRIG_ROUND_MASK
);
875 err
+= (tmp
!= cmd
->scan_begin_arg
);
877 if (cmd
->convert_src
== TRIG_TIMER
) {
878 unsigned int tmp
= cmd
->convert_arg
;
879 /* set divisors, correct timing arguments */
880 i8253_cascade_ns_to_timer_2div(devpriv
->clockbase
,
881 &(devpriv
->divisor1
),
882 &(devpriv
->divisor2
),
884 cmd
->flags
& TRIG_ROUND_MASK
);
885 err
+= (tmp
!= cmd
->convert_arg
);
890 /* check channel/gain list against card's limitations */
892 gain
= CR_RANGE(cmd
->chanlist
[0]);
893 start_chan
= CR_CHAN(cmd
->chanlist
[0]);
894 for (i
= 1; i
< cmd
->chanlist_len
; i
++) {
895 if (CR_CHAN(cmd
->chanlist
[i
]) !=
896 (start_chan
+ i
) % s
->n_chan
) {
898 "entries in chanlist must be "
899 "consecutive channels, "
900 "counting upwards\n");
903 if (CR_RANGE(cmd
->chanlist
[i
]) != gain
) {
905 "entries in chanlist must all "
906 "have the same gain\n");
917 static int das16_cmd_exec(struct comedi_device
*dev
, struct comedi_subdevice
*s
)
919 struct comedi_async
*async
= s
->async
;
920 struct comedi_cmd
*cmd
= &async
->cmd
;
925 if (devpriv
->dma_chan
== 0 || (dev
->irq
== 0
926 && devpriv
->timer_mode
== 0)) {
928 "irq (or use of 'timer mode') dma required to "
929 "execute comedi_cmd");
932 if (cmd
->flags
& TRIG_RT
) {
933 comedi_error(dev
, "isa dma transfers cannot be performed with "
934 "TRIG_RT, aborting");
938 devpriv
->adc_byte_count
=
939 cmd
->stop_arg
* cmd
->chanlist_len
* sizeof(uint16_t);
941 /* disable conversions for das1600 mode */
942 if (thisboard
->size
> 0x400)
943 outb(DAS1600_CONV_DISABLE
, dev
->iobase
+ DAS1600_CONV
);
945 /* set scan limits */
946 byte
= CR_CHAN(cmd
->chanlist
[0]);
947 byte
|= CR_CHAN(cmd
->chanlist
[cmd
->chanlist_len
- 1]) << 4;
948 outb(byte
, dev
->iobase
+ DAS16_MUX
);
950 /* set gain (this is also burst rate register but according to
951 * computer boards manual, burst rate does nothing, even on
953 if (thisboard
->ai_pg
!= das16_pg_none
) {
954 range
= CR_RANGE(cmd
->chanlist
[0]);
955 outb((das16_gainlists
[thisboard
->ai_pg
])[range
],
956 dev
->iobase
+ DAS16_GAIN
);
959 /* set counter mode and counts */
961 das16_set_pacer(dev
, cmd
->convert_arg
,
962 cmd
->flags
& TRIG_ROUND_MASK
);
963 DEBUG_PRINT("pacer period: %d ns\n", cmd
->convert_arg
);
965 /* enable counters */
967 /* Enable burst mode if appropriate. */
968 if (thisboard
->size
> 0x400) {
969 if (cmd
->convert_src
== TRIG_NOW
) {
970 outb(DAS1600_BURST_VAL
, dev
->iobase
+ DAS1600_BURST
);
971 /* set burst length */
972 byte
|= BURST_LEN_BITS(cmd
->chanlist_len
- 1);
974 outb(0, dev
->iobase
+ DAS1600_BURST
);
977 outb(byte
, dev
->iobase
+ DAS16_PACER
);
979 /* set up dma transfer */
980 flags
= claim_dma_lock();
981 disable_dma(devpriv
->dma_chan
);
982 /* clear flip-flop to make sure 2-byte registers for
983 * count and address get set correctly */
984 clear_dma_ff(devpriv
->dma_chan
);
985 devpriv
->current_buffer
= 0;
986 set_dma_addr(devpriv
->dma_chan
,
987 devpriv
->dma_buffer_addr
[devpriv
->current_buffer
]);
988 /* set appropriate size of transfer */
989 devpriv
->dma_transfer_size
= das16_suggest_transfer_size(dev
, *cmd
);
990 set_dma_count(devpriv
->dma_chan
, devpriv
->dma_transfer_size
);
991 enable_dma(devpriv
->dma_chan
);
992 release_dma_lock(flags
);
994 /* set up interrupt */
995 if (devpriv
->timer_mode
) {
996 devpriv
->timer_running
= 1;
997 devpriv
->timer
.expires
= jiffies
+ timer_period();
998 add_timer(&devpriv
->timer
);
999 devpriv
->control_state
&= ~DAS16_INTE
;
1001 /* clear interrupt bit */
1002 outb(0x00, dev
->iobase
+ DAS16_STATUS
);
1003 /* enable interrupts */
1004 devpriv
->control_state
|= DAS16_INTE
;
1006 devpriv
->control_state
|= DMA_ENABLE
;
1007 devpriv
->control_state
&= ~PACING_MASK
;
1008 if (cmd
->convert_src
== TRIG_EXT
)
1009 devpriv
->control_state
|= EXT_PACER
;
1011 devpriv
->control_state
|= INT_PACER
;
1012 outb(devpriv
->control_state
, dev
->iobase
+ DAS16_CONTROL
);
1014 /* Enable conversions if using das1600 mode */
1015 if (thisboard
->size
> 0x400)
1016 outb(0, dev
->iobase
+ DAS1600_CONV
);
1022 static int das16_cancel(struct comedi_device
*dev
, struct comedi_subdevice
*s
)
1024 unsigned long flags
;
1026 spin_lock_irqsave(&dev
->spinlock
, flags
);
1027 /* disable interrupts, dma and pacer clocked conversions */
1028 devpriv
->control_state
&= ~DAS16_INTE
& ~PACING_MASK
& ~DMA_ENABLE
;
1029 outb(devpriv
->control_state
, dev
->iobase
+ DAS16_CONTROL
);
1030 if (devpriv
->dma_chan
)
1031 disable_dma(devpriv
->dma_chan
);
1033 /* disable SW timer */
1034 if (devpriv
->timer_mode
&& devpriv
->timer_running
) {
1035 devpriv
->timer_running
= 0;
1036 del_timer(&devpriv
->timer
);
1039 /* disable burst mode */
1040 if (thisboard
->size
> 0x400)
1041 outb(0, dev
->iobase
+ DAS1600_BURST
);
1044 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
1049 static void das16_reset(struct comedi_device
*dev
)
1051 outb(0, dev
->iobase
+ DAS16_STATUS
);
1052 outb(0, dev
->iobase
+ DAS16_CONTROL
);
1053 outb(0, dev
->iobase
+ DAS16_PACER
);
1054 outb(0, dev
->iobase
+ DAS16_CNTR_CONTROL
);
1057 static int das16_ai_rinsn(struct comedi_device
*dev
, struct comedi_subdevice
*s
,
1058 struct comedi_insn
*insn
, unsigned int *data
)
1065 /* disable interrupts and pacing */
1066 devpriv
->control_state
&= ~DAS16_INTE
& ~DMA_ENABLE
& ~PACING_MASK
;
1067 outb(devpriv
->control_state
, dev
->iobase
+ DAS16_CONTROL
);
1069 /* set multiplexer */
1070 chan
= CR_CHAN(insn
->chanspec
);
1071 chan
|= CR_CHAN(insn
->chanspec
) << 4;
1072 outb(chan
, dev
->iobase
+ DAS16_MUX
);
1075 if (thisboard
->ai_pg
!= das16_pg_none
) {
1076 range
= CR_RANGE(insn
->chanspec
);
1077 outb((das16_gainlists
[thisboard
->ai_pg
])[range
],
1078 dev
->iobase
+ DAS16_GAIN
);
1081 for (n
= 0; n
< insn
->n
; n
++) {
1082 /* trigger conversion */
1083 outb_p(0, dev
->iobase
+ DAS16_TRIG
);
1085 for (i
= 0; i
< DAS16_TIMEOUT
; i
++) {
1086 if (!(inb(dev
->iobase
+ DAS16_STATUS
) & BUSY
))
1089 if (i
== DAS16_TIMEOUT
) {
1090 printk("das16: timeout\n");
1093 msb
= inb(dev
->iobase
+ DAS16_AI_MSB
);
1094 lsb
= inb(dev
->iobase
+ DAS16_AI_LSB
);
1095 if (thisboard
->ai_nbits
== 12)
1096 data
[n
] = ((lsb
>> 4) & 0xf) | (msb
<< 4);
1098 data
[n
] = lsb
| (msb
<< 8);
1105 static int das16_di_rbits(struct comedi_device
*dev
, struct comedi_subdevice
*s
,
1106 struct comedi_insn
*insn
, unsigned int *data
)
1110 bits
= inb(dev
->iobase
+ DAS16_DIO
) & 0xf;
1117 static int das16_do_wbits(struct comedi_device
*dev
, struct comedi_subdevice
*s
,
1118 struct comedi_insn
*insn
, unsigned int *data
)
1122 /* only set bits that have been masked */
1125 /* zero bits that have been masked */
1127 /* set masked bits */
1128 wbits
|= data
[0] & data
[1];
1132 outb(s
->state
, dev
->iobase
+ DAS16_DIO
);
1137 static int das16_ao_winsn(struct comedi_device
*dev
, struct comedi_subdevice
*s
,
1138 struct comedi_insn
*insn
, unsigned int *data
)
1144 chan
= CR_CHAN(insn
->chanspec
);
1146 for (i
= 0; i
< insn
->n
; i
++) {
1147 if (thisboard
->ao_nbits
== 12) {
1148 lsb
= (data
[i
] << 4) & 0xff;
1149 msb
= (data
[i
] >> 4) & 0xff;
1151 lsb
= data
[i
] & 0xff;
1152 msb
= (data
[i
] >> 8) & 0xff;
1154 outb(lsb
, dev
->iobase
+ DAS16_AO_LSB(chan
));
1155 outb(msb
, dev
->iobase
+ DAS16_AO_MSB(chan
));
1161 static irqreturn_t
das16_dma_interrupt(int irq
, void *d
)
1164 struct comedi_device
*dev
= d
;
1166 status
= inb(dev
->iobase
+ DAS16_STATUS
);
1168 if ((status
& DAS16_INT
) == 0) {
1169 DEBUG_PRINT("spurious interrupt\n");
1173 /* clear interrupt */
1174 outb(0x00, dev
->iobase
+ DAS16_STATUS
);
1175 das16_interrupt(dev
);
1179 static void das16_timer_interrupt(unsigned long arg
)
1181 struct comedi_device
*dev
= (struct comedi_device
*)arg
;
1183 das16_interrupt(dev
);
1185 if (devpriv
->timer_running
)
1186 mod_timer(&devpriv
->timer
, jiffies
+ timer_period());
1189 /* the pc104-das16jr (at least) has problems if the dma
1190 transfer is interrupted in the middle of transferring
1191 a 16 bit sample, so this function takes care to get
1192 an even transfer count after disabling dma
1195 static int disable_dma_on_even(struct comedi_device
*dev
)
1199 static const int disable_limit
= 100;
1200 static const int enable_timeout
= 100;
1201 disable_dma(devpriv
->dma_chan
);
1202 residue
= get_dma_residue(devpriv
->dma_chan
);
1203 for (i
= 0; i
< disable_limit
&& (residue
% 2); ++i
) {
1205 enable_dma(devpriv
->dma_chan
);
1206 for (j
= 0; j
< enable_timeout
; ++j
) {
1209 new_residue
= get_dma_residue(devpriv
->dma_chan
);
1210 if (new_residue
!= residue
)
1213 disable_dma(devpriv
->dma_chan
);
1214 residue
= get_dma_residue(devpriv
->dma_chan
);
1216 if (i
== disable_limit
) {
1217 comedi_error(dev
, "failed to get an even dma transfer, "
1218 "could be trouble.");
1223 static void das16_interrupt(struct comedi_device
*dev
)
1225 unsigned long dma_flags
, spin_flags
;
1226 struct comedi_subdevice
*s
= dev
->read_subdev
;
1227 struct comedi_async
*async
;
1228 struct comedi_cmd
*cmd
;
1229 int num_bytes
, residue
;
1232 if (dev
->attached
== 0) {
1233 comedi_error(dev
, "premature interrupt");
1236 /* initialize async here to make sure it is not NULL */
1240 if (devpriv
->dma_chan
== 0) {
1241 comedi_error(dev
, "interrupt with no dma channel?");
1245 spin_lock_irqsave(&dev
->spinlock
, spin_flags
);
1246 if ((devpriv
->control_state
& DMA_ENABLE
) == 0) {
1247 spin_unlock_irqrestore(&dev
->spinlock
, spin_flags
);
1248 DEBUG_PRINT("interrupt while dma disabled?\n");
1252 dma_flags
= claim_dma_lock();
1253 clear_dma_ff(devpriv
->dma_chan
);
1254 residue
= disable_dma_on_even(dev
);
1256 /* figure out how many points to read */
1257 if (residue
> devpriv
->dma_transfer_size
) {
1258 comedi_error(dev
, "residue > transfer size!\n");
1259 async
->events
|= COMEDI_CB_ERROR
| COMEDI_CB_EOA
;
1262 num_bytes
= devpriv
->dma_transfer_size
- residue
;
1264 if (cmd
->stop_src
== TRIG_COUNT
&&
1265 num_bytes
>= devpriv
->adc_byte_count
) {
1266 num_bytes
= devpriv
->adc_byte_count
;
1267 async
->events
|= COMEDI_CB_EOA
;
1270 buffer_index
= devpriv
->current_buffer
;
1271 devpriv
->current_buffer
= (devpriv
->current_buffer
+ 1) % 2;
1272 devpriv
->adc_byte_count
-= num_bytes
;
1274 /* figure out how many bytes for next transfer */
1275 if (cmd
->stop_src
== TRIG_COUNT
&& devpriv
->timer_mode
== 0 &&
1276 devpriv
->dma_transfer_size
> devpriv
->adc_byte_count
)
1277 devpriv
->dma_transfer_size
= devpriv
->adc_byte_count
;
1280 if ((async
->events
& COMEDI_CB_EOA
) == 0) {
1281 set_dma_addr(devpriv
->dma_chan
,
1282 devpriv
->dma_buffer_addr
[devpriv
->current_buffer
]);
1283 set_dma_count(devpriv
->dma_chan
, devpriv
->dma_transfer_size
);
1284 enable_dma(devpriv
->dma_chan
);
1285 /* reenable conversions for das1600 mode, (stupid hardware) */
1286 if (thisboard
->size
> 0x400 && devpriv
->timer_mode
== 0)
1287 outb(0x00, dev
->iobase
+ DAS1600_CONV
);
1290 release_dma_lock(dma_flags
);
1292 spin_unlock_irqrestore(&dev
->spinlock
, spin_flags
);
1294 cfc_write_array_to_buffer(s
,
1295 devpriv
->dma_buffer
[buffer_index
], num_bytes
);
1297 cfc_handle_events(dev
, s
);
1300 static unsigned int das16_set_pacer(struct comedi_device
*dev
, unsigned int ns
,
1303 i8253_cascade_ns_to_timer_2div(devpriv
->clockbase
, &(devpriv
->divisor1
),
1304 &(devpriv
->divisor2
), &ns
,
1305 rounding_flags
& TRIG_ROUND_MASK
);
1307 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1308 i8254_load(dev
->iobase
+ DAS16_CNTR0_DATA
, 0, 1, devpriv
->divisor1
, 2);
1309 i8254_load(dev
->iobase
+ DAS16_CNTR0_DATA
, 0, 2, devpriv
->divisor2
, 2);
1314 static void reg_dump(struct comedi_device
*dev
)
1316 DEBUG_PRINT("********DAS1600 REGISTER DUMP********\n");
1317 DEBUG_PRINT("DAS16_MUX: %x\n", inb(dev
->iobase
+ DAS16_MUX
));
1318 DEBUG_PRINT("DAS16_DIO: %x\n", inb(dev
->iobase
+ DAS16_DIO
));
1319 DEBUG_PRINT("DAS16_STATUS: %x\n", inb(dev
->iobase
+ DAS16_STATUS
));
1320 DEBUG_PRINT("DAS16_CONTROL: %x\n", inb(dev
->iobase
+ DAS16_CONTROL
));
1321 DEBUG_PRINT("DAS16_PACER: %x\n", inb(dev
->iobase
+ DAS16_PACER
));
1322 DEBUG_PRINT("DAS16_GAIN: %x\n", inb(dev
->iobase
+ DAS16_GAIN
));
1323 DEBUG_PRINT("DAS16_CNTR_CONTROL: %x\n",
1324 inb(dev
->iobase
+ DAS16_CNTR_CONTROL
));
1325 DEBUG_PRINT("DAS1600_CONV: %x\n", inb(dev
->iobase
+ DAS1600_CONV
));
1326 DEBUG_PRINT("DAS1600_BURST: %x\n", inb(dev
->iobase
+ DAS1600_BURST
));
1327 DEBUG_PRINT("DAS1600_ENABLE: %x\n", inb(dev
->iobase
+ DAS1600_ENABLE
));
1328 DEBUG_PRINT("DAS1600_STATUS_B: %x\n",
1329 inb(dev
->iobase
+ DAS1600_STATUS_B
));
1332 static int das16_probe(struct comedi_device
*dev
, struct comedi_devconfig
*it
)
1337 /* status is available on all boards */
1339 status
= inb(dev
->iobase
+ DAS16_STATUS
);
1341 if ((status
& UNIPOLAR
))
1342 devpriv
->ai_unipolar
= 1;
1344 devpriv
->ai_unipolar
= 0;
1347 if ((status
& DAS16_MUXBIT
))
1348 devpriv
->ai_singleended
= 1;
1350 devpriv
->ai_singleended
= 0;
1353 /* diobits indicates boards */
1355 diobits
= inb(dev
->iobase
+ DAS16_DIO
) & 0xf0;
1357 printk(KERN_INFO
" id bits are 0x%02x\n", diobits
);
1358 if (thisboard
->id
!= diobits
) {
1359 printk(KERN_INFO
" requested board's id bits are 0x%x (ignore)\n",
1366 static int das1600_mode_detect(struct comedi_device
*dev
)
1370 status
= inb(dev
->iobase
+ DAS1600_STATUS_B
);
1372 if (status
& DAS1600_CLK_10MHZ
) {
1373 devpriv
->clockbase
= 100;
1374 printk(KERN_INFO
" 10MHz pacer clock\n");
1376 devpriv
->clockbase
= 1000;
1377 printk(KERN_INFO
" 1MHz pacer clock\n");
1391 * 3 Clock speed (in MHz)
1394 static int das16_attach(struct comedi_device
*dev
, struct comedi_devconfig
*it
)
1396 struct comedi_subdevice
*s
;
1399 unsigned long iobase
;
1400 unsigned int dma_chan
;
1402 unsigned long flags
;
1403 struct comedi_krange
*user_ai_range
, *user_ao_range
;
1405 iobase
= it
->options
[0];
1406 /* always use time_mode since using irq can drop samples while
1407 * waiting for dma done interrupt (due to hardware limitations) */
1413 printk(KERN_INFO
"comedi%d: das16:", dev
->minor
);
1415 /* check that clock setting is valid */
1416 if (it
->options
[3]) {
1417 if (it
->options
[3] != 0 &&
1418 it
->options
[3] != 1 && it
->options
[3] != 10) {
1420 ("\n Invalid option. Master clock must be set "
1421 "to 1 or 10 (MHz)\n");
1426 ret
= alloc_private(dev
, sizeof(struct das16_private_struct
));
1430 if (thisboard
->size
< 0x400) {
1431 printk(" 0x%04lx-0x%04lx\n", iobase
, iobase
+ thisboard
->size
);
1432 if (!request_region(iobase
, thisboard
->size
, "das16")) {
1433 printk(KERN_ERR
" I/O port conflict\n");
1437 printk(KERN_INFO
" 0x%04lx-0x%04lx 0x%04lx-0x%04lx\n",
1438 iobase
, iobase
+ 0x0f,
1440 iobase
+ 0x400 + (thisboard
->size
& 0x3ff));
1441 if (!request_region(iobase
, 0x10, "das16")) {
1442 printk(KERN_ERR
" I/O port conflict: 0x%04lx-0x%04lx\n",
1443 iobase
, iobase
+ 0x0f);
1446 if (!request_region(iobase
+ 0x400, thisboard
->size
& 0x3ff,
1448 release_region(iobase
, 0x10);
1449 printk(KERN_ERR
" I/O port conflict: 0x%04lx-0x%04lx\n",
1451 iobase
+ 0x400 + (thisboard
->size
& 0x3ff));
1456 dev
->iobase
= iobase
;
1458 /* probe id bits to make sure they are consistent */
1459 if (das16_probe(dev
, it
)) {
1460 printk(KERN_ERR
" id bits do not match selected board, aborting\n");
1463 dev
->board_name
= thisboard
->name
;
1465 /* get master clock speed */
1466 if (thisboard
->size
< 0x400) {
1468 devpriv
->clockbase
= 1000 / it
->options
[3];
1470 devpriv
->clockbase
= 1000; /* 1 MHz default */
1472 das1600_mode_detect(dev
);
1475 /* now for the irq */
1476 if (irq
> 1 && irq
< 8) {
1477 ret
= request_irq(irq
, das16_dma_interrupt
, 0, "das16", dev
);
1482 printk(KERN_INFO
" ( irq = %u )", irq
);
1483 } else if (irq
== 0) {
1484 printk(" ( no irq )");
1486 printk(" invalid irq\n");
1490 /* initialize dma */
1491 dma_chan
= it
->options
[2];
1492 if (dma_chan
== 1 || dma_chan
== 3) {
1493 /* allocate dma buffers */
1495 for (i
= 0; i
< 2; i
++) {
1496 devpriv
->dma_buffer
[i
] = pci_alloc_consistent(
1497 NULL
, DAS16_DMA_SIZE
,
1498 &devpriv
->dma_buffer_addr
[i
]);
1500 if (devpriv
->dma_buffer
[i
] == NULL
)
1503 if (request_dma(dma_chan
, "das16")) {
1504 printk(KERN_ERR
" failed to allocate dma channel %i\n",
1508 devpriv
->dma_chan
= dma_chan
;
1509 flags
= claim_dma_lock();
1510 disable_dma(devpriv
->dma_chan
);
1511 set_dma_mode(devpriv
->dma_chan
, DMA_MODE_READ
);
1512 release_dma_lock(flags
);
1513 printk(KERN_INFO
" ( dma = %u)\n", dma_chan
);
1514 } else if (dma_chan
== 0) {
1515 printk(KERN_INFO
" ( no dma )\n");
1517 printk(KERN_ERR
" invalid dma channel\n");
1521 /* get any user-defined input range */
1522 if (thisboard
->ai_pg
== das16_pg_none
&&
1523 (it
->options
[4] || it
->options
[5])) {
1524 /* allocate single-range range table */
1525 devpriv
->user_ai_range_table
=
1526 kmalloc(sizeof(struct comedi_lrange
) +
1527 sizeof(struct comedi_krange
), GFP_KERNEL
);
1528 /* initialize ai range */
1529 devpriv
->user_ai_range_table
->length
= 1;
1530 user_ai_range
= devpriv
->user_ai_range_table
->range
;
1531 user_ai_range
->min
= it
->options
[4];
1532 user_ai_range
->max
= it
->options
[5];
1533 user_ai_range
->flags
= UNIT_volt
;
1535 /* get any user-defined output range */
1536 if (it
->options
[6] || it
->options
[7]) {
1537 /* allocate single-range range table */
1538 devpriv
->user_ao_range_table
=
1539 kmalloc(sizeof(struct comedi_lrange
) +
1540 sizeof(struct comedi_krange
), GFP_KERNEL
);
1541 /* initialize ao range */
1542 devpriv
->user_ao_range_table
->length
= 1;
1543 user_ao_range
= devpriv
->user_ao_range_table
->range
;
1544 user_ao_range
->min
= it
->options
[6];
1545 user_ao_range
->max
= it
->options
[7];
1546 user_ao_range
->flags
= UNIT_volt
;
1550 init_timer(&(devpriv
->timer
));
1551 devpriv
->timer
.function
= das16_timer_interrupt
;
1552 devpriv
->timer
.data
= (unsigned long)dev
;
1554 devpriv
->timer_mode
= timer_mode
? 1 : 0;
1556 ret
= alloc_subdevices(dev
, 5);
1560 s
= dev
->subdevices
+ 0;
1561 dev
->read_subdev
= s
;
1563 if (thisboard
->ai
) {
1564 s
->type
= COMEDI_SUBD_AI
;
1565 s
->subdev_flags
= SDF_READABLE
| SDF_CMD_READ
;
1566 if (devpriv
->ai_singleended
) {
1568 s
->len_chanlist
= 16;
1569 s
->subdev_flags
|= SDF_GROUND
;
1572 s
->len_chanlist
= 8;
1573 s
->subdev_flags
|= SDF_DIFF
;
1575 s
->maxdata
= (1 << thisboard
->ai_nbits
) - 1;
1576 if (devpriv
->user_ai_range_table
) { /* user defined ai range */
1577 s
->range_table
= devpriv
->user_ai_range_table
;
1578 } else if (devpriv
->ai_unipolar
) {
1579 s
->range_table
= das16_ai_uni_lranges
[thisboard
->ai_pg
];
1581 s
->range_table
= das16_ai_bip_lranges
[thisboard
->ai_pg
];
1583 s
->insn_read
= thisboard
->ai
;
1584 s
->do_cmdtest
= das16_cmd_test
;
1585 s
->do_cmd
= das16_cmd_exec
;
1586 s
->cancel
= das16_cancel
;
1587 s
->munge
= das16_ai_munge
;
1589 s
->type
= COMEDI_SUBD_UNUSED
;
1592 s
= dev
->subdevices
+ 1;
1594 if (thisboard
->ao
) {
1595 s
->type
= COMEDI_SUBD_AO
;
1596 s
->subdev_flags
= SDF_WRITABLE
;
1598 s
->maxdata
= (1 << thisboard
->ao_nbits
) - 1;
1599 /* user defined ao range */
1600 if (devpriv
->user_ao_range_table
)
1601 s
->range_table
= devpriv
->user_ao_range_table
;
1603 s
->range_table
= &range_unknown
;
1605 s
->insn_write
= thisboard
->ao
;
1607 s
->type
= COMEDI_SUBD_UNUSED
;
1610 s
= dev
->subdevices
+ 2;
1612 if (thisboard
->di
) {
1613 s
->type
= COMEDI_SUBD_DI
;
1614 s
->subdev_flags
= SDF_READABLE
;
1617 s
->range_table
= &range_digital
;
1618 s
->insn_bits
= thisboard
->di
;
1620 s
->type
= COMEDI_SUBD_UNUSED
;
1623 s
= dev
->subdevices
+ 3;
1625 if (thisboard
->do_
) {
1626 s
->type
= COMEDI_SUBD_DO
;
1627 s
->subdev_flags
= SDF_WRITABLE
| SDF_READABLE
;
1630 s
->range_table
= &range_digital
;
1631 s
->insn_bits
= thisboard
->do_
;
1632 /* initialize digital output lines */
1633 outb(s
->state
, dev
->iobase
+ DAS16_DIO
);
1635 s
->type
= COMEDI_SUBD_UNUSED
;
1638 s
= dev
->subdevices
+ 4;
1640 if (thisboard
->i8255_offset
!= 0) {
1641 subdev_8255_init(dev
, s
, NULL
, (dev
->iobase
+
1642 thisboard
->i8255_offset
));
1644 s
->type
= COMEDI_SUBD_UNUSED
;
1648 /* set the interrupt level */
1649 devpriv
->control_state
= DAS16_IRQ(dev
->irq
);
1650 outb(devpriv
->control_state
, dev
->iobase
+ DAS16_CONTROL
);
1652 /* turn on das1600 mode if available */
1653 if (thisboard
->size
> 0x400) {
1654 outb(DAS1600_ENABLE_VAL
, dev
->iobase
+ DAS1600_ENABLE
);
1655 outb(0, dev
->iobase
+ DAS1600_CONV
);
1656 outb(0, dev
->iobase
+ DAS1600_BURST
);
1662 static int das16_detach(struct comedi_device
*dev
)
1664 printk(KERN_INFO
"comedi%d: das16: remove\n", dev
->minor
);
1668 if (dev
->subdevices
)
1669 subdev_8255_cleanup(dev
, dev
->subdevices
+ 4);
1673 for (i
= 0; i
< 2; i
++) {
1674 if (devpriv
->dma_buffer
[i
])
1675 pci_free_consistent(NULL
, DAS16_DMA_SIZE
,
1676 devpriv
->dma_buffer
[i
],
1678 dma_buffer_addr
[i
]);
1680 if (devpriv
->dma_chan
)
1681 free_dma(devpriv
->dma_chan
);
1682 if (devpriv
->user_ai_range_table
)
1683 kfree(devpriv
->user_ai_range_table
);
1684 if (devpriv
->user_ao_range_table
)
1685 kfree(devpriv
->user_ao_range_table
);
1689 free_irq(dev
->irq
, dev
);
1692 if (thisboard
->size
< 0x400) {
1693 release_region(dev
->iobase
, thisboard
->size
);
1695 release_region(dev
->iobase
, 0x10);
1696 release_region(dev
->iobase
+ 0x400,
1697 thisboard
->size
& 0x3ff);
1704 static int __init
driver_das16_init_module(void)
1706 return comedi_driver_register(&driver_das16
);
1709 static void __exit
driver_das16_cleanup_module(void)
1711 comedi_driver_unregister(&driver_das16
);
1714 module_init(driver_das16_init_module
);
1715 module_exit(driver_das16_cleanup_module
);
1717 /* utility function that suggests a dma transfer size in bytes */
1718 static unsigned int das16_suggest_transfer_size(struct comedi_device
*dev
,
1719 struct comedi_cmd cmd
)
1724 /* if we are using timer interrupt, we don't care how long it
1725 * will take to complete transfer since it will be interrupted
1726 * by timer interrupt */
1727 if (devpriv
->timer_mode
)
1728 return DAS16_DMA_SIZE
;
1730 /* otherwise, we are relying on dma terminal count interrupt,
1731 * so pick a reasonable size */
1732 if (cmd
.convert_src
== TRIG_TIMER
)
1733 freq
= 1000000000 / cmd
.convert_arg
;
1734 else if (cmd
.scan_begin_src
== TRIG_TIMER
)
1735 freq
= (1000000000 / cmd
.scan_begin_arg
) * cmd
.chanlist_len
;
1736 /* return some default value */
1740 if (cmd
.flags
& TRIG_WAKE_EOS
) {
1741 size
= sample_size
* cmd
.chanlist_len
;
1743 /* make buffer fill in no more than 1/3 second */
1744 size
= (freq
/ 3) * sample_size
;
1747 /* set a minimum and maximum size allowed */
1748 if (size
> DAS16_DMA_SIZE
)
1749 size
= DAS16_DMA_SIZE
- DAS16_DMA_SIZE
% sample_size
;
1750 else if (size
< sample_size
)
1753 if (cmd
.stop_src
== TRIG_COUNT
&& size
> devpriv
->adc_byte_count
)
1754 size
= devpriv
->adc_byte_count
;
1759 static void das16_ai_munge(struct comedi_device
*dev
,
1760 struct comedi_subdevice
*s
, void *array
,
1761 unsigned int num_bytes
,
1762 unsigned int start_chan_index
)
1764 unsigned int i
, num_samples
= num_bytes
/ sizeof(short);
1765 short *data
= array
;
1767 for (i
= 0; i
< num_samples
; i
++) {
1768 data
[i
] = le16_to_cpu(data
[i
]);
1769 if (thisboard
->ai_nbits
== 12)
1770 data
[i
] = (data
[i
] >> 4) & 0xfff;
1775 MODULE_AUTHOR("Comedi http://www.comedi.org");
1776 MODULE_DESCRIPTION("Comedi low-level driver");
1777 MODULE_LICENSE("GPL");