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.
23 * Description: DAS16 compatible boards
24 * Author: Sam Moore, Warren Jasper, ds, Chris Baugher, Frank Hess, Roman Fietze
25 * Devices: (Keithley Metrabyte) DAS-16 [das-16]
26 * (Keithley Metrabyte) DAS-16G [das-16g]
27 * (Keithley Metrabyte) DAS-16F [das-16f]
28 * (Keithley Metrabyte) DAS-1201 [das-1201]
29 * (Keithley Metrabyte) DAS-1202 [das-1202]
30 * (Keithley Metrabyte) DAS-1401 [das-1401]
31 * (Keithley Metrabyte) DAS-1402 [das-1402]
32 * (Keithley Metrabyte) DAS-1601 [das-1601]
33 * (Keithley Metrabyte) DAS-1602 [das-1602]
34 * (ComputerBoards) PC104-DAS16/JR [pc104-das16jr]
35 * (ComputerBoards) PC104-DAS16JR/16 [pc104-das16jr/16]
36 * (ComputerBoards) CIO-DAS16 [cio-das16]
37 * (ComputerBoards) CIO-DAS16F [cio-das16/f]
38 * (ComputerBoards) CIO-DAS16/JR [cio-das16/jr]
39 * (ComputerBoards) CIO-DAS16JR/16 [cio-das16jr/16]
40 * (ComputerBoards) CIO-DAS1401/12 [cio-das1401/12]
41 * (ComputerBoards) CIO-DAS1402/12 [cio-das1402/12]
42 * (ComputerBoards) CIO-DAS1402/16 [cio-das1402/16]
43 * (ComputerBoards) CIO-DAS1601/12 [cio-das1601/12]
44 * (ComputerBoards) CIO-DAS1602/12 [cio-das1602/12]
45 * (ComputerBoards) CIO-DAS1602/16 [cio-das1602/16]
46 * (ComputerBoards) CIO-DAS16/330 [cio-das16/330]
50 * A rewrite of the das16 and das1600 drivers.
53 * [0] - base io address
54 * [1] - irq (does nothing, irq is not used anymore)
55 * [2] - dma channel (optional, required for comedi_command support)
56 * [3] - master clock speed in MHz (optional, 1 or 10, ignored if
57 * board can probe clock, defaults to 1)
58 * [4] - analog input range lowest voltage in microvolts (optional,
59 * only useful if your board does not have software
61 * [5] - analog input range highest voltage in microvolts (optional,
62 * only useful if board does not have software programmable
64 * [6] - analog output range lowest voltage in microvolts (optional)
65 * [7] - analog output range highest voltage in microvolts (optional)
67 * Passing a zero for an option is the same as leaving it unspecified.
71 * Testing and debugging help provided by Daniel Koch.
75 * 4919.PDF (das1400, 1600)
77 * 4923.PDF (das1200, 1400, 1600)
79 * Computer boards manuals also available from their website
80 * www.measurementcomputing.com
83 #include <linux/module.h>
84 #include <linux/slab.h>
85 #include <linux/delay.h>
86 #include <linux/pci.h>
87 #include <linux/interrupt.h>
91 #include "../comedidev.h"
95 #include "comedi_fc.h"
97 #define DAS16_DMA_SIZE 0xff00 /* size in bytes of allocated dma buffer */
102 #define DAS16_TRIG_REG 0x00
103 #define DAS16_AI_LSB_REG 0x00
104 #define DAS16_AI_MSB_REG 0x01
105 #define DAS16_MUX_REG 0x02
106 #define DAS16_DIO_REG 0x03
107 #define DAS16_AO_LSB_REG(x) ((x) ? 0x06 : 0x04)
108 #define DAS16_AO_MSB_REG(x) ((x) ? 0x07 : 0x05)
109 #define DAS16_STATUS_REG 0x08
110 #define DAS16_STATUS_BUSY (1 << 7)
111 #define DAS16_STATUS_UNIPOLAR (1 << 6)
112 #define DAS16_STATUS_MUXBIT (1 << 5)
113 #define DAS16_STATUS_INT (1 << 4)
114 #define DAS16_CTRL_REG 0x09
115 #define DAS16_CTRL_INTE (1 << 7)
116 #define DAS16_CTRL_IRQ(x) (((x) & 0x7) << 4)
117 #define DAS16_CTRL_DMAE (1 << 2)
118 #define DAS16_CTRL_PACING_MASK (3 << 0)
119 #define DAS16_CTRL_INT_PACER (3 << 0)
120 #define DAS16_CTRL_EXT_PACER (2 << 0)
121 #define DAS16_CTRL_SOFT_PACER (0 << 0)
122 #define DAS16_PACER_REG 0x0a
123 #define DAS16_PACER_BURST_LEN(x) (((x) & 0xf) << 4)
124 #define DAS16_PACER_CTR0 (1 << 1)
125 #define DAS16_PACER_TRIG0 (1 << 0)
126 #define DAS16_GAIN_REG 0x0b
127 #define DAS16_TIMER_BASE_REG 0x0c /* to 0x0f */
129 #define DAS1600_CONV_REG 0x404
130 #define DAS1600_CONV_DISABLE (1 << 6)
131 #define DAS1600_BURST_REG 0x405
132 #define DAS1600_BURST_VAL (1 << 6)
133 #define DAS1600_ENABLE_REG 0x406
134 #define DAS1600_ENABLE_VAL (1 << 6)
135 #define DAS1600_STATUS_REG 0x407
136 #define DAS1600_STATUS_BME (1 << 6)
137 #define DAS1600_STATUS_ME (1 << 5)
138 #define DAS1600_STATUS_CD (1 << 4)
139 #define DAS1600_STATUS_WS (1 << 1)
140 #define DAS1600_STATUS_CLK_10MHZ (1 << 0)
142 static const struct comedi_lrange range_das1x01_bip
= {
151 static const struct comedi_lrange range_das1x01_unip
= {
160 static const struct comedi_lrange range_das1x02_bip
= {
169 static const struct comedi_lrange range_das1x02_unip
= {
178 static const struct comedi_lrange range_das16jr
= {
192 static const struct comedi_lrange range_das16jr_16
= {
205 static const int das16jr_gainlist
[] = { 8, 0, 1, 2, 3, 4, 5, 6, 7 };
206 static const int das16jr_16_gainlist
[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
207 static const int das1600_gainlist
[] = { 0, 1, 2, 3 };
216 static const int *const das16_gainlists
[] = {
224 static const struct comedi_lrange
*const das16_ai_uni_lranges
[] = {
232 static const struct comedi_lrange
*const das16_ai_bip_lranges
[] = {
242 unsigned int ai_maxdata
;
243 unsigned int ai_speed
; /* max conversion speed in nanosec */
245 unsigned int has_ao
:1;
246 unsigned int has_8255
:1;
248 unsigned int i8255_offset
;
254 static const struct das16_board das16_boards
[] = {
257 .ai_maxdata
= 0x0fff,
259 .ai_pg
= das16_pg_none
,
262 .i8255_offset
= 0x10,
267 .ai_maxdata
= 0x0fff,
269 .ai_pg
= das16_pg_none
,
272 .i8255_offset
= 0x10,
277 .ai_maxdata
= 0x0fff,
279 .ai_pg
= das16_pg_none
,
282 .i8255_offset
= 0x10,
287 .ai_maxdata
= 0x0fff,
289 .ai_pg
= das16_pg_none
,
292 .i8255_offset
= 0x10,
296 .name
= "cio-das16/f",
297 .ai_maxdata
= 0x0fff,
299 .ai_pg
= das16_pg_none
,
302 .i8255_offset
= 0x10,
306 .name
= "cio-das16/jr",
307 .ai_maxdata
= 0x0fff,
309 .ai_pg
= das16_pg_16jr
,
313 .name
= "pc104-das16jr",
314 .ai_maxdata
= 0x0fff,
316 .ai_pg
= das16_pg_16jr
,
320 .name
= "cio-das16jr/16",
321 .ai_maxdata
= 0xffff,
323 .ai_pg
= das16_pg_16jr_16
,
327 .name
= "pc104-das16jr/16",
328 .ai_maxdata
= 0xffff,
330 .ai_pg
= das16_pg_16jr_16
,
335 .ai_maxdata
= 0x0fff,
337 .ai_pg
= das16_pg_none
,
339 .i8255_offset
= 0x400,
344 .ai_maxdata
= 0x0fff,
346 .ai_pg
= das16_pg_none
,
348 .i8255_offset
= 0x400,
353 .ai_maxdata
= 0x0fff,
355 .ai_pg
= das16_pg_1601
,
360 .ai_maxdata
= 0x0fff,
362 .ai_pg
= das16_pg_1602
,
367 .ai_maxdata
= 0x0fff,
369 .ai_pg
= das16_pg_1601
,
372 .i8255_offset
= 0x400,
377 .ai_maxdata
= 0x0fff,
379 .ai_pg
= das16_pg_1602
,
382 .i8255_offset
= 0x400,
386 .name
= "cio-das1401/12",
387 .ai_maxdata
= 0x0fff,
389 .ai_pg
= das16_pg_1601
,
393 .name
= "cio-das1402/12",
394 .ai_maxdata
= 0x0fff,
396 .ai_pg
= das16_pg_1602
,
400 .name
= "cio-das1402/16",
401 .ai_maxdata
= 0xffff,
403 .ai_pg
= das16_pg_1602
,
407 .name
= "cio-das1601/12",
408 .ai_maxdata
= 0x0fff,
410 .ai_pg
= das16_pg_1601
,
413 .i8255_offset
= 0x400,
417 .name
= "cio-das1602/12",
418 .ai_maxdata
= 0x0fff,
420 .ai_pg
= das16_pg_1602
,
423 .i8255_offset
= 0x400,
427 .name
= "cio-das1602/16",
428 .ai_maxdata
= 0xffff,
430 .ai_pg
= das16_pg_1602
,
433 .i8255_offset
= 0x400,
437 .name
= "cio-das16/330",
438 .ai_maxdata
= 0x0fff,
440 .ai_pg
= das16_pg_16jr
,
446 /* Period for timer interrupt in jiffies. It's a function
447 * to deal with possibility of dynamic HZ patches */
448 static inline int timer_period(void)
453 struct das16_private_struct
{
454 unsigned int clockbase
;
455 unsigned int ctrl_reg
;
456 unsigned long adc_byte_count
;
457 unsigned int divisor1
;
458 unsigned int divisor2
;
459 unsigned int dma_chan
;
460 uint16_t *dma_buffer
[2];
461 dma_addr_t dma_buffer_addr
[2];
462 unsigned int current_buffer
;
463 unsigned int dma_transfer_size
;
464 struct comedi_lrange
*user_ai_range_table
;
465 struct comedi_lrange
*user_ao_range_table
;
466 struct timer_list timer
;
468 unsigned long extra_iobase
;
469 unsigned int can_burst
:1;
472 static void das16_ai_enable(struct comedi_device
*dev
,
473 unsigned int mode
, unsigned int src
)
475 struct das16_private_struct
*devpriv
= dev
->private;
477 devpriv
->ctrl_reg
&= ~(DAS16_CTRL_INTE
|
479 DAS16_CTRL_PACING_MASK
);
480 devpriv
->ctrl_reg
|= mode
;
483 devpriv
->ctrl_reg
|= DAS16_CTRL_EXT_PACER
;
485 devpriv
->ctrl_reg
|= DAS16_CTRL_INT_PACER
;
486 outb(devpriv
->ctrl_reg
, dev
->iobase
+ DAS16_CTRL_REG
);
489 static void das16_ai_disable(struct comedi_device
*dev
)
491 struct das16_private_struct
*devpriv
= dev
->private;
493 /* disable interrupts, dma and pacer clocked conversions */
494 devpriv
->ctrl_reg
&= ~(DAS16_CTRL_INTE
|
496 DAS16_CTRL_PACING_MASK
);
497 outb(devpriv
->ctrl_reg
, dev
->iobase
+ DAS16_CTRL_REG
);
500 /* the pc104-das16jr (at least) has problems if the dma
501 transfer is interrupted in the middle of transferring
502 a 16 bit sample, so this function takes care to get
503 an even transfer count after disabling dma
506 static int disable_dma_on_even(struct comedi_device
*dev
)
508 struct das16_private_struct
*devpriv
= dev
->private;
511 static const int disable_limit
= 100;
512 static const int enable_timeout
= 100;
514 disable_dma(devpriv
->dma_chan
);
515 residue
= get_dma_residue(devpriv
->dma_chan
);
516 for (i
= 0; i
< disable_limit
&& (residue
% 2); ++i
) {
518 enable_dma(devpriv
->dma_chan
);
519 for (j
= 0; j
< enable_timeout
; ++j
) {
522 new_residue
= get_dma_residue(devpriv
->dma_chan
);
523 if (new_residue
!= residue
)
526 disable_dma(devpriv
->dma_chan
);
527 residue
= get_dma_residue(devpriv
->dma_chan
);
529 if (i
== disable_limit
) {
530 dev_err(dev
->class_dev
,
531 "failed to get an even dma transfer, could be trouble\n");
536 static void das16_interrupt(struct comedi_device
*dev
)
538 struct das16_private_struct
*devpriv
= dev
->private;
539 struct comedi_subdevice
*s
= dev
->read_subdev
;
540 struct comedi_async
*async
= s
->async
;
541 struct comedi_cmd
*cmd
= &async
->cmd
;
542 unsigned long spin_flags
;
543 unsigned long dma_flags
;
544 int num_bytes
, residue
;
547 spin_lock_irqsave(&dev
->spinlock
, spin_flags
);
548 if (!(devpriv
->ctrl_reg
& DAS16_CTRL_DMAE
)) {
549 spin_unlock_irqrestore(&dev
->spinlock
, spin_flags
);
553 dma_flags
= claim_dma_lock();
554 clear_dma_ff(devpriv
->dma_chan
);
555 residue
= disable_dma_on_even(dev
);
557 /* figure out how many points to read */
558 if (residue
> devpriv
->dma_transfer_size
) {
559 dev_err(dev
->class_dev
, "residue > transfer size!\n");
560 async
->events
|= COMEDI_CB_ERROR
| COMEDI_CB_EOA
;
563 num_bytes
= devpriv
->dma_transfer_size
- residue
;
565 if (cmd
->stop_src
== TRIG_COUNT
&&
566 num_bytes
>= devpriv
->adc_byte_count
) {
567 num_bytes
= devpriv
->adc_byte_count
;
568 async
->events
|= COMEDI_CB_EOA
;
571 buffer_index
= devpriv
->current_buffer
;
572 devpriv
->current_buffer
= (devpriv
->current_buffer
+ 1) % 2;
573 devpriv
->adc_byte_count
-= num_bytes
;
576 if ((async
->events
& COMEDI_CB_EOA
) == 0) {
577 set_dma_addr(devpriv
->dma_chan
,
578 devpriv
->dma_buffer_addr
[devpriv
->current_buffer
]);
579 set_dma_count(devpriv
->dma_chan
, devpriv
->dma_transfer_size
);
580 enable_dma(devpriv
->dma_chan
);
582 release_dma_lock(dma_flags
);
584 spin_unlock_irqrestore(&dev
->spinlock
, spin_flags
);
586 cfc_write_array_to_buffer(s
,
587 devpriv
->dma_buffer
[buffer_index
], num_bytes
);
589 cfc_handle_events(dev
, s
);
592 static void das16_timer_interrupt(unsigned long arg
)
594 struct comedi_device
*dev
= (struct comedi_device
*)arg
;
595 struct das16_private_struct
*devpriv
= dev
->private;
597 das16_interrupt(dev
);
599 if (devpriv
->timer_running
)
600 mod_timer(&devpriv
->timer
, jiffies
+ timer_period());
603 static int das16_cmd_test(struct comedi_device
*dev
, struct comedi_subdevice
*s
,
604 struct comedi_cmd
*cmd
)
606 const struct das16_board
*board
= comedi_board(dev
);
607 struct das16_private_struct
*devpriv
= dev
->private;
609 int gain
, start_chan
, i
;
612 /* Step 1 : check if triggers are trivially valid */
614 err
|= cfc_check_trigger_src(&cmd
->start_src
, TRIG_NOW
);
617 if (devpriv
->can_burst
)
618 mask
|= TRIG_TIMER
| TRIG_EXT
;
619 err
|= cfc_check_trigger_src(&cmd
->scan_begin_src
, mask
);
621 tmp
= cmd
->convert_src
;
622 mask
= TRIG_TIMER
| TRIG_EXT
;
623 if (devpriv
->can_burst
)
625 err
|= cfc_check_trigger_src(&cmd
->convert_src
, mask
);
627 err
|= cfc_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
628 err
|= cfc_check_trigger_src(&cmd
->stop_src
, TRIG_COUNT
| TRIG_NONE
);
633 /* Step 2a : make sure trigger sources are unique */
635 err
|= cfc_check_trigger_is_unique(cmd
->scan_begin_src
);
636 err
|= cfc_check_trigger_is_unique(cmd
->convert_src
);
637 err
|= cfc_check_trigger_is_unique(cmd
->stop_src
);
639 /* Step 2b : and mutually compatible */
641 /* make sure scan_begin_src and convert_src dont conflict */
642 if (cmd
->scan_begin_src
== TRIG_FOLLOW
&& cmd
->convert_src
== TRIG_NOW
)
644 if (cmd
->scan_begin_src
!= TRIG_FOLLOW
&& cmd
->convert_src
!= TRIG_NOW
)
650 /* Step 3: check if arguments are trivially valid */
652 err
|= cfc_check_trigger_arg_is(&cmd
->start_arg
, 0);
654 if (cmd
->scan_begin_src
== TRIG_FOLLOW
) /* internal trigger */
655 err
|= cfc_check_trigger_arg_is(&cmd
->scan_begin_arg
, 0);
657 err
|= cfc_check_trigger_arg_is(&cmd
->scan_end_arg
, cmd
->chanlist_len
);
659 /* check against maximum frequency */
660 if (cmd
->scan_begin_src
== TRIG_TIMER
)
661 err
|= cfc_check_trigger_arg_min(&cmd
->scan_begin_arg
,
662 board
->ai_speed
* cmd
->chanlist_len
);
664 if (cmd
->convert_src
== TRIG_TIMER
)
665 err
|= cfc_check_trigger_arg_min(&cmd
->convert_arg
,
668 if (cmd
->stop_src
== TRIG_NONE
)
669 err
|= cfc_check_trigger_arg_is(&cmd
->stop_arg
, 0);
674 /* step 4: fix up arguments */
675 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
676 unsigned int tmp
= cmd
->scan_begin_arg
;
677 /* set divisors, correct timing arguments */
678 i8253_cascade_ns_to_timer(devpriv
->clockbase
,
681 &cmd
->scan_begin_arg
, cmd
->flags
);
682 err
+= (tmp
!= cmd
->scan_begin_arg
);
684 if (cmd
->convert_src
== TRIG_TIMER
) {
685 unsigned int tmp
= cmd
->convert_arg
;
686 /* set divisors, correct timing arguments */
687 i8253_cascade_ns_to_timer(devpriv
->clockbase
,
690 &cmd
->convert_arg
, cmd
->flags
);
691 err
+= (tmp
!= cmd
->convert_arg
);
696 /* check channel/gain list against card's limitations */
698 gain
= CR_RANGE(cmd
->chanlist
[0]);
699 start_chan
= CR_CHAN(cmd
->chanlist
[0]);
700 for (i
= 1; i
< cmd
->chanlist_len
; i
++) {
701 if (CR_CHAN(cmd
->chanlist
[i
]) !=
702 (start_chan
+ i
) % s
->n_chan
) {
703 dev_err(dev
->class_dev
,
704 "entries in chanlist must be consecutive channels, counting upwards\n");
707 if (CR_RANGE(cmd
->chanlist
[i
]) != gain
) {
708 dev_err(dev
->class_dev
,
709 "entries in chanlist must all have the same gain\n");
720 static unsigned int das16_set_pacer(struct comedi_device
*dev
, unsigned int ns
,
723 struct das16_private_struct
*devpriv
= dev
->private;
724 unsigned long timer_base
= dev
->iobase
+ DAS16_TIMER_BASE_REG
;
726 i8253_cascade_ns_to_timer(devpriv
->clockbase
,
727 &devpriv
->divisor1
, &devpriv
->divisor2
,
728 &ns
, rounding_flags
);
730 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
731 i8254_load(timer_base
, 0, 1, devpriv
->divisor1
, 2);
732 i8254_load(timer_base
, 0, 2, devpriv
->divisor2
, 2);
737 static int das16_cmd_exec(struct comedi_device
*dev
, struct comedi_subdevice
*s
)
739 const struct das16_board
*board
= comedi_board(dev
);
740 struct das16_private_struct
*devpriv
= dev
->private;
741 struct comedi_async
*async
= s
->async
;
742 struct comedi_cmd
*cmd
= &async
->cmd
;
747 if (cmd
->flags
& TRIG_RT
) {
748 dev_err(dev
->class_dev
,
749 "isa dma transfers cannot be performed with TRIG_RT, aborting\n");
753 devpriv
->adc_byte_count
=
754 cmd
->stop_arg
* cmd
->chanlist_len
* sizeof(uint16_t);
756 if (devpriv
->can_burst
)
757 outb(DAS1600_CONV_DISABLE
, dev
->iobase
+ DAS1600_CONV_REG
);
759 /* set scan limits */
760 byte
= CR_CHAN(cmd
->chanlist
[0]);
761 byte
|= CR_CHAN(cmd
->chanlist
[cmd
->chanlist_len
- 1]) << 4;
762 outb(byte
, dev
->iobase
+ DAS16_MUX_REG
);
764 /* set gain (this is also burst rate register but according to
765 * computer boards manual, burst rate does nothing, even on
767 if (board
->ai_pg
!= das16_pg_none
) {
768 range
= CR_RANGE(cmd
->chanlist
[0]);
769 outb((das16_gainlists
[board
->ai_pg
])[range
],
770 dev
->iobase
+ DAS16_GAIN_REG
);
773 /* set counter mode and counts */
775 das16_set_pacer(dev
, cmd
->convert_arg
,
776 cmd
->flags
& TRIG_ROUND_MASK
);
778 /* enable counters */
780 if (devpriv
->can_burst
) {
781 if (cmd
->convert_src
== TRIG_NOW
) {
782 outb(DAS1600_BURST_VAL
,
783 dev
->iobase
+ DAS1600_BURST_REG
);
784 /* set burst length */
785 byte
|= DAS16_PACER_BURST_LEN(cmd
->chanlist_len
- 1);
787 outb(0, dev
->iobase
+ DAS1600_BURST_REG
);
790 outb(byte
, dev
->iobase
+ DAS16_PACER_REG
);
792 /* set up dma transfer */
793 flags
= claim_dma_lock();
794 disable_dma(devpriv
->dma_chan
);
795 /* clear flip-flop to make sure 2-byte registers for
796 * count and address get set correctly */
797 clear_dma_ff(devpriv
->dma_chan
);
798 devpriv
->current_buffer
= 0;
799 set_dma_addr(devpriv
->dma_chan
,
800 devpriv
->dma_buffer_addr
[devpriv
->current_buffer
]);
801 devpriv
->dma_transfer_size
= DAS16_DMA_SIZE
;
802 set_dma_count(devpriv
->dma_chan
, devpriv
->dma_transfer_size
);
803 enable_dma(devpriv
->dma_chan
);
804 release_dma_lock(flags
);
806 /* set up interrupt */
807 devpriv
->timer_running
= 1;
808 devpriv
->timer
.expires
= jiffies
+ timer_period();
809 add_timer(&devpriv
->timer
);
811 das16_ai_enable(dev
, DAS16_CTRL_DMAE
, cmd
->convert_src
);
813 if (devpriv
->can_burst
)
814 outb(0, dev
->iobase
+ DAS1600_CONV_REG
);
819 static int das16_cancel(struct comedi_device
*dev
, struct comedi_subdevice
*s
)
821 struct das16_private_struct
*devpriv
= dev
->private;
824 spin_lock_irqsave(&dev
->spinlock
, flags
);
826 das16_ai_disable(dev
);
827 disable_dma(devpriv
->dma_chan
);
829 /* disable SW timer */
830 if (devpriv
->timer_running
) {
831 devpriv
->timer_running
= 0;
832 del_timer(&devpriv
->timer
);
835 if (devpriv
->can_burst
)
836 outb(0, dev
->iobase
+ DAS1600_BURST_REG
);
838 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
843 static void das16_ai_munge(struct comedi_device
*dev
,
844 struct comedi_subdevice
*s
, void *array
,
845 unsigned int num_bytes
,
846 unsigned int start_chan_index
)
848 unsigned int i
, num_samples
= num_bytes
/ sizeof(short);
849 unsigned short *data
= array
;
851 for (i
= 0; i
< num_samples
; i
++) {
852 data
[i
] = le16_to_cpu(data
[i
]);
853 if (s
->maxdata
== 0x0fff)
855 data
[i
] &= s
->maxdata
;
859 static int das16_ai_wait_for_conv(struct comedi_device
*dev
,
860 unsigned int timeout
)
865 for (i
= 0; i
< timeout
; i
++) {
866 status
= inb(dev
->iobase
+ DAS16_STATUS_REG
);
867 if (!(status
& DAS16_STATUS_BUSY
))
873 static int das16_ai_insn_read(struct comedi_device
*dev
,
874 struct comedi_subdevice
*s
,
875 struct comedi_insn
*insn
,
878 const struct das16_board
*board
= comedi_board(dev
);
879 unsigned int chan
= CR_CHAN(insn
->chanspec
);
880 unsigned int range
= CR_RANGE(insn
->chanspec
);
885 das16_ai_disable(dev
);
887 /* set multiplexer */
888 outb(chan
| (chan
<< 4), dev
->iobase
+ DAS16_MUX_REG
);
891 if (board
->ai_pg
!= das16_pg_none
) {
892 outb((das16_gainlists
[board
->ai_pg
])[range
],
893 dev
->iobase
+ DAS16_GAIN_REG
);
896 for (i
= 0; i
< insn
->n
; i
++) {
897 /* trigger conversion */
898 outb_p(0, dev
->iobase
+ DAS16_TRIG_REG
);
900 ret
= das16_ai_wait_for_conv(dev
, 1000);
904 val
= inb(dev
->iobase
+ DAS16_AI_MSB_REG
) << 8;
905 val
|= inb(dev
->iobase
+ DAS16_AI_LSB_REG
);
906 if (s
->maxdata
== 0x0fff)
916 static int das16_ao_insn_write(struct comedi_device
*dev
,
917 struct comedi_subdevice
*s
,
918 struct comedi_insn
*insn
,
921 unsigned int chan
= CR_CHAN(insn
->chanspec
);
925 for (i
= 0; i
< insn
->n
; i
++) {
929 outb(val
& 0xff, dev
->iobase
+ DAS16_AO_LSB_REG(chan
));
930 outb((val
>> 8) & 0xff, dev
->iobase
+ DAS16_AO_MSB_REG(chan
));
936 static int das16_di_insn_bits(struct comedi_device
*dev
,
937 struct comedi_subdevice
*s
,
938 struct comedi_insn
*insn
,
941 data
[1] = inb(dev
->iobase
+ DAS16_DIO_REG
) & 0xf;
946 static int das16_do_insn_bits(struct comedi_device
*dev
,
947 struct comedi_subdevice
*s
,
948 struct comedi_insn
*insn
,
951 if (comedi_dio_update_state(s
, data
))
952 outb(s
->state
, dev
->iobase
+ DAS16_DIO_REG
);
959 static int das16_probe(struct comedi_device
*dev
, struct comedi_devconfig
*it
)
961 const struct das16_board
*board
= comedi_board(dev
);
964 /* diobits indicates boards */
965 diobits
= inb(dev
->iobase
+ DAS16_DIO_REG
) & 0xf0;
966 if (board
->id
!= diobits
) {
967 dev_err(dev
->class_dev
,
968 "requested board's id bits are incorrect (0x%x != 0x%x)\n",
976 static void das16_reset(struct comedi_device
*dev
)
978 outb(0, dev
->iobase
+ DAS16_STATUS_REG
);
979 outb(0, dev
->iobase
+ DAS16_CTRL_REG
);
980 outb(0, dev
->iobase
+ DAS16_PACER_REG
);
981 outb(0, dev
->iobase
+ DAS16_TIMER_BASE_REG
+ i8254_control_reg
);
984 static int das16_attach(struct comedi_device
*dev
, struct comedi_devconfig
*it
)
986 const struct das16_board
*board
= comedi_board(dev
);
987 struct das16_private_struct
*devpriv
;
988 struct comedi_subdevice
*s
;
989 struct comedi_lrange
*lrange
;
990 struct comedi_krange
*krange
;
991 unsigned int dma_chan
= it
->options
[2];
995 /* check that clock setting is valid */
996 if (it
->options
[3]) {
997 if (it
->options
[3] != 0 &&
998 it
->options
[3] != 1 && it
->options
[3] != 10) {
999 dev_err(dev
->class_dev
,
1000 "Invalid option. Master clock must be set to 1 or 10 (MHz)\n");
1005 devpriv
= comedi_alloc_devpriv(dev
, sizeof(*devpriv
));
1009 if (board
->size
< 0x400) {
1010 ret
= comedi_request_region(dev
, it
->options
[0], board
->size
);
1014 ret
= comedi_request_region(dev
, it
->options
[0], 0x10);
1017 /* Request an additional region for the 8255 */
1018 ret
= __comedi_request_region(dev
, dev
->iobase
+ 0x400,
1019 board
->size
& 0x3ff);
1022 devpriv
->extra_iobase
= dev
->iobase
+ 0x400;
1023 devpriv
->can_burst
= 1;
1026 /* probe id bits to make sure they are consistent */
1027 if (das16_probe(dev
, it
))
1030 /* get master clock speed */
1031 if (devpriv
->can_burst
) {
1032 status
= inb(dev
->iobase
+ DAS1600_STATUS_REG
);
1034 if (status
& DAS1600_STATUS_CLK_10MHZ
)
1035 devpriv
->clockbase
= I8254_OSC_BASE_10MHZ
;
1037 devpriv
->clockbase
= I8254_OSC_BASE_1MHZ
;
1040 devpriv
->clockbase
= I8254_OSC_BASE_1MHZ
/
1043 devpriv
->clockbase
= I8254_OSC_BASE_1MHZ
;
1046 /* initialize dma */
1047 if (dma_chan
== 1 || dma_chan
== 3) {
1048 unsigned long flags
;
1051 if (request_dma(dma_chan
, dev
->board_name
)) {
1052 dev_err(dev
->class_dev
,
1053 "failed to request dma channel %i\n",
1057 devpriv
->dma_chan
= dma_chan
;
1059 /* allocate dma buffers */
1060 for (i
= 0; i
< 2; i
++) {
1063 p
= pci_alloc_consistent(NULL
, DAS16_DMA_SIZE
,
1064 &devpriv
->dma_buffer_addr
[i
]);
1067 devpriv
->dma_buffer
[i
] = p
;
1070 flags
= claim_dma_lock();
1071 disable_dma(devpriv
->dma_chan
);
1072 set_dma_mode(devpriv
->dma_chan
, DMA_MODE_READ
);
1073 release_dma_lock(flags
);
1075 init_timer(&devpriv
->timer
);
1076 devpriv
->timer
.function
= das16_timer_interrupt
;
1077 devpriv
->timer
.data
= (unsigned long)dev
;
1080 /* get any user-defined input range */
1081 if (board
->ai_pg
== das16_pg_none
&&
1082 (it
->options
[4] || it
->options
[5])) {
1083 /* allocate single-range range table */
1084 lrange
= kzalloc(sizeof(*lrange
) + sizeof(*krange
), GFP_KERNEL
);
1088 /* initialize ai range */
1089 devpriv
->user_ai_range_table
= lrange
;
1091 krange
= devpriv
->user_ai_range_table
->range
;
1092 krange
->min
= it
->options
[4];
1093 krange
->max
= it
->options
[5];
1094 krange
->flags
= UNIT_volt
;
1097 /* get any user-defined output range */
1098 if (it
->options
[6] || it
->options
[7]) {
1099 /* allocate single-range range table */
1100 lrange
= kzalloc(sizeof(*lrange
) + sizeof(*krange
), GFP_KERNEL
);
1104 /* initialize ao range */
1105 devpriv
->user_ao_range_table
= lrange
;
1107 krange
= devpriv
->user_ao_range_table
->range
;
1108 krange
->min
= it
->options
[6];
1109 krange
->max
= it
->options
[7];
1110 krange
->flags
= UNIT_volt
;
1113 ret
= comedi_alloc_subdevices(dev
, 4 + board
->has_8255
);
1117 status
= inb(dev
->iobase
+ DAS16_STATUS_REG
);
1119 /* Analog Input subdevice */
1120 s
= &dev
->subdevices
[0];
1121 s
->type
= COMEDI_SUBD_AI
;
1122 s
->subdev_flags
= SDF_READABLE
;
1123 if (status
& DAS16_STATUS_MUXBIT
) {
1124 s
->subdev_flags
|= SDF_GROUND
;
1127 s
->subdev_flags
|= SDF_DIFF
;
1130 s
->len_chanlist
= s
->n_chan
;
1131 s
->maxdata
= board
->ai_maxdata
;
1132 if (devpriv
->user_ai_range_table
) { /* user defined ai range */
1133 s
->range_table
= devpriv
->user_ai_range_table
;
1134 } else if (status
& DAS16_STATUS_UNIPOLAR
) {
1135 s
->range_table
= das16_ai_uni_lranges
[board
->ai_pg
];
1137 s
->range_table
= das16_ai_bip_lranges
[board
->ai_pg
];
1139 s
->insn_read
= das16_ai_insn_read
;
1140 if (devpriv
->dma_chan
) {
1141 dev
->read_subdev
= s
;
1142 s
->subdev_flags
|= SDF_CMD_READ
;
1143 s
->do_cmdtest
= das16_cmd_test
;
1144 s
->do_cmd
= das16_cmd_exec
;
1145 s
->cancel
= das16_cancel
;
1146 s
->munge
= das16_ai_munge
;
1149 /* Analog Output subdevice */
1150 s
= &dev
->subdevices
[1];
1151 if (board
->has_ao
) {
1152 s
->type
= COMEDI_SUBD_AO
;
1153 s
->subdev_flags
= SDF_WRITABLE
;
1155 s
->maxdata
= 0x0fff;
1156 s
->range_table
= devpriv
->user_ao_range_table
;
1157 s
->insn_write
= das16_ao_insn_write
;
1159 s
->type
= COMEDI_SUBD_UNUSED
;
1162 /* Digital Input subdevice */
1163 s
= &dev
->subdevices
[2];
1164 s
->type
= COMEDI_SUBD_DI
;
1165 s
->subdev_flags
= SDF_READABLE
;
1168 s
->range_table
= &range_digital
;
1169 s
->insn_bits
= das16_di_insn_bits
;
1171 /* Digital Output subdevice */
1172 s
= &dev
->subdevices
[3];
1173 s
->type
= COMEDI_SUBD_DO
;
1174 s
->subdev_flags
= SDF_WRITABLE
;
1177 s
->range_table
= &range_digital
;
1178 s
->insn_bits
= das16_do_insn_bits
;
1180 /* initialize digital output lines */
1181 outb(s
->state
, dev
->iobase
+ DAS16_DIO_REG
);
1183 /* 8255 Digital I/O subdevice */
1184 if (board
->has_8255
) {
1185 s
= &dev
->subdevices
[4];
1186 ret
= subdev_8255_init(dev
, s
, NULL
,
1187 dev
->iobase
+ board
->i8255_offset
);
1193 /* set the interrupt level */
1194 devpriv
->ctrl_reg
= DAS16_CTRL_IRQ(dev
->irq
);
1195 outb(devpriv
->ctrl_reg
, dev
->iobase
+ DAS16_CTRL_REG
);
1197 if (devpriv
->can_burst
) {
1198 outb(DAS1600_ENABLE_VAL
, dev
->iobase
+ DAS1600_ENABLE_REG
);
1199 outb(0, dev
->iobase
+ DAS1600_CONV_REG
);
1200 outb(0, dev
->iobase
+ DAS1600_BURST_REG
);
1206 static void das16_detach(struct comedi_device
*dev
)
1208 const struct das16_board
*board
= comedi_board(dev
);
1209 struct das16_private_struct
*devpriv
= dev
->private;
1216 for (i
= 0; i
< 2; i
++) {
1217 if (devpriv
->dma_buffer
[i
])
1218 pci_free_consistent(NULL
, DAS16_DMA_SIZE
,
1219 devpriv
->dma_buffer
[i
],
1221 dma_buffer_addr
[i
]);
1223 if (devpriv
->dma_chan
)
1224 free_dma(devpriv
->dma_chan
);
1225 kfree(devpriv
->user_ai_range_table
);
1226 kfree(devpriv
->user_ao_range_table
);
1228 if (devpriv
->extra_iobase
)
1229 release_region(devpriv
->extra_iobase
,
1230 board
->size
& 0x3ff);
1233 comedi_legacy_detach(dev
);
1236 static struct comedi_driver das16_driver
= {
1237 .driver_name
= "das16",
1238 .module
= THIS_MODULE
,
1239 .attach
= das16_attach
,
1240 .detach
= das16_detach
,
1241 .board_name
= &das16_boards
[0].name
,
1242 .num_names
= ARRAY_SIZE(das16_boards
),
1243 .offset
= sizeof(das16_boards
[0]),
1245 module_comedi_driver(das16_driver
);
1247 MODULE_AUTHOR("Comedi http://www.comedi.org");
1248 MODULE_DESCRIPTION("Comedi driver for DAS16 compatible boards");
1249 MODULE_LICENSE("GPL");