2 comedi/drivers/das1800.c
3 Driver for Keitley das1700/das1800 series boards
4 Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
6 COMEDI - Linux Control and Measurement Device Interface
7 Copyright (C) 2000 David A. Schleef <ds@schleef.org>
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 ************************************************************************
27 Description: Keithley Metrabyte DAS1800 (& compatibles)
28 Author: Frank Mori Hess <fmhess@users.sourceforge.net>
29 Devices: [Keithley Metrabyte] DAS-1701ST (das-1701st),
30 DAS-1701ST-DA (das-1701st-da), DAS-1701/AO (das-1701ao),
31 DAS-1702ST (das-1702st), DAS-1702ST-DA (das-1702st-da),
32 DAS-1702HR (das-1702hr), DAS-1702HR-DA (das-1702hr-da),
33 DAS-1702/AO (das-1702ao), DAS-1801ST (das-1801st),
34 DAS-1801ST-DA (das-1801st-da), DAS-1801HC (das-1801hc),
35 DAS-1801AO (das-1801ao), DAS-1802ST (das-1802st),
36 DAS-1802ST-DA (das-1802st-da), DAS-1802HR (das-1802hr),
37 DAS-1802HR-DA (das-1802hr-da), DAS-1802HC (das-1802hc),
38 DAS-1802AO (das-1802ao)
41 The waveform analog output on the 'ao' cards is not supported.
42 If you need it, send me (Frank Hess) an email.
44 Configuration options:
45 [0] - I/O port base address
46 [1] - IRQ (optional, required for timed or externally triggered conversions)
47 [2] - DMA0 (optional, requires irq)
48 [3] - DMA1 (optional, requires irq and dma0)
52 This driver supports the following Keithley boards:
75 [1] - irq (optional, required for timed or externally triggered conversions)
76 [2] - dma0 (optional, requires irq)
77 [3] - dma1 (optional, requires irq and dma0)
79 irq can be omitted, although the cmd interface will not work without it.
81 analog input cmd triggers supported:
82 start_src: TRIG_NOW | TRIG_EXT
83 scan_begin_src: TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT
84 scan_end_src: TRIG_COUNT
85 convert_src: TRIG_TIMER | TRIG_EXT (TRIG_EXT requires scan_begin_src == TRIG_FOLLOW)
86 stop_src: TRIG_COUNT | TRIG_EXT | TRIG_NONE
88 scan_begin_src triggers TRIG_TIMER and TRIG_EXT use the card's
89 'burst mode' which limits the valid conversion time to 64 microseconds
90 (convert_arg <= 64000). This limitation does not apply if scan_begin_src
94 Only the DAS-1801ST has been tested by me.
95 Unipolar and bipolar ranges cannot be mixed in the channel/gain list.
98 Make it automatically allocate irq and dma channels if they are not specified
99 Add support for analog out on 'ao' cards
100 read insn for analog out
103 #include <linux/interrupt.h>
104 #include <linux/slab.h>
105 #include <linux/io.h>
106 #include "../comedidev.h"
108 #include <linux/ioport.h>
112 #include "comedi_fc.h"
115 #define DAS1800_SIZE 16 /* uses 16 io addresses */
116 #define FIFO_SIZE 1024 /* 1024 sample fifo */
117 #define TIMER_BASE 200 /* 5 Mhz master clock */
118 #define UNIPOLAR 0x4 /* bit that determines whether input range is uni/bipolar */
119 #define DMA_BUF_SIZE 0x1ff00 /* size in bytes of dma buffers */
121 /* Registers for the das1800 */
122 #define DAS1800_FIFO 0x0
123 #define DAS1800_QRAM 0x0
124 #define DAS1800_DAC 0x0
125 #define DAS1800_SELECT 0x2
128 #define DAC(a) (0x2 + a)
129 #define DAS1800_DIGITAL 0x3
130 #define DAS1800_CONTROL_A 0x4
137 #define DAS1800_CONTROL_B 0x5
141 #define DMA_CH5_CH6 0x5
142 #define DMA_CH6_CH7 0x6
143 #define DMA_CH7_CH5 0x7
144 #define DMA_ENABLED 0x3 /* mask used to determine if dma is enabled */
153 #define DAS1800_CONTROL_C 0X6
161 #define DAS1800_STATUS 0x7
162 /* bits that prevent interrupt status bits (and CVEN) from being cleared on write */
163 #define CLEAR_INTR_MASK (CVEN_MASK | 0x1f)
170 #define CVEN_MASK 0x40 /* masks CVEN on write */
172 #define DAS1800_BURST_LENGTH 0x8
173 #define DAS1800_BURST_RATE 0x9
174 #define DAS1800_QRAM_ADDRESS 0xa
175 #define DAS1800_COUNTER 0xc
177 #define IOBASE2 0x400 /* offset of additional ioports used on 'ao' cards */
180 das1701st
, das1701st_da
, das1702st
, das1702st_da
, das1702hr
,
182 das1701ao
, das1702ao
, das1801st
, das1801st_da
, das1802st
, das1802st_da
,
183 das1802hr
, das1802hr_da
, das1801hc
, das1802hc
, das1801ao
, das1802ao
186 /* analog input ranges */
187 static const struct comedi_lrange range_ai_das1801
= {
201 static const struct comedi_lrange range_ai_das1802
= {
215 struct das1800_board
{
217 int ai_speed
; /* max conversion period in nanoseconds */
218 int resolution
; /* bits of ai resolution */
219 int qram_len
; /* length of card's channel / gain queue */
220 int common
; /* supports AREF_COMMON flag */
221 int do_n_chan
; /* number of digital output channels */
222 int ao_ability
; /* 0 == no analog out, 1 == basic analog out, 2 == waveform analog out */
223 int ao_n_chan
; /* number of analog out channels */
224 const struct comedi_lrange
*range_ai
; /* available input ranges */
227 /* Warning: the maximum conversion speeds listed below are
228 * not always achievable depending on board setup (see
231 static const struct das1800_board das1800_boards
[] = {
233 .name
= "das-1701st",
241 .range_ai
= &range_ai_das1801
,
244 .name
= "das-1701st-da",
252 .range_ai
= &range_ai_das1801
,
255 .name
= "das-1702st",
263 .range_ai
= &range_ai_das1802
,
266 .name
= "das-1702st-da",
274 .range_ai
= &range_ai_das1802
,
277 .name
= "das-1702hr",
285 .range_ai
= &range_ai_das1802
,
288 .name
= "das-1702hr-da",
296 .range_ai
= &range_ai_das1802
,
299 .name
= "das-1701ao",
307 .range_ai
= &range_ai_das1801
,
310 .name
= "das-1702ao",
318 .range_ai
= &range_ai_das1802
,
321 .name
= "das-1801st",
329 .range_ai
= &range_ai_das1801
,
332 .name
= "das-1801st-da",
340 .range_ai
= &range_ai_das1801
,
343 .name
= "das-1802st",
351 .range_ai
= &range_ai_das1802
,
354 .name
= "das-1802st-da",
362 .range_ai
= &range_ai_das1802
,
365 .name
= "das-1802hr",
373 .range_ai
= &range_ai_das1802
,
376 .name
= "das-1802hr-da",
384 .range_ai
= &range_ai_das1802
,
387 .name
= "das-1801hc",
395 .range_ai
= &range_ai_das1801
,
398 .name
= "das-1802hc",
406 .range_ai
= &range_ai_das1802
,
409 .name
= "das-1801ao",
417 .range_ai
= &range_ai_das1801
,
420 .name
= "das-1802ao",
428 .range_ai
= &range_ai_das1802
,
433 * Useful for shorthand access to the particular board structure
435 #define thisboard ((const struct das1800_board *)dev->board_ptr)
437 struct das1800_private
{
438 volatile unsigned int count
; /* number of data points left to be taken */
439 unsigned int divisor1
; /* value to load into board's counter 1 for timed conversions */
440 unsigned int divisor2
; /* value to load into board's counter 2 for timed conversions */
441 int do_bits
; /* digital output bits */
442 int irq_dma_bits
; /* bits for control register b */
443 /* dma bits for control register b, stored so that dma can be
444 * turned on and off */
446 unsigned int dma0
; /* dma channels used */
448 volatile unsigned int dma_current
; /* dma channel currently in use */
449 uint16_t *ai_buf0
; /* pointers to dma buffers */
451 uint16_t *dma_current_buf
; /* pointer to dma buffer currently being used */
452 unsigned int dma_transfer_size
; /* size of transfer currently used, in bytes */
453 unsigned long iobase2
; /* secondary io address used for analog out on 'ao' boards */
454 short ao_update_bits
; /* remembers the last write to the 'update' dac */
457 #define devpriv ((struct das1800_private *)dev->private)
459 /* analog out range for boards with basic analog out */
460 static const struct comedi_lrange range_ao_1
= {
467 /* analog out range for 'ao' boards */
469 static const struct comedi_lrange range_ao_2 = {
478 static inline uint16_t munge_bipolar_sample(const struct comedi_device
*dev
,
481 sample
+= 1 << (thisboard
->resolution
- 1);
485 static void munge_data(struct comedi_device
*dev
, uint16_t * array
,
486 unsigned int num_elements
)
491 /* see if card is using a unipolar or bipolar range so we can munge data correctly */
492 unipolar
= inb(dev
->iobase
+ DAS1800_CONTROL_C
) & UB
;
494 /* convert to unsigned type if we are in a bipolar mode */
496 for (i
= 0; i
< num_elements
; i
++)
497 array
[i
] = munge_bipolar_sample(dev
, array
[i
]);
501 static void das1800_handle_fifo_half_full(struct comedi_device
*dev
,
502 struct comedi_subdevice
*s
)
504 int numPoints
= 0; /* number of points to read */
505 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
507 numPoints
= FIFO_SIZE
/ 2;
508 /* if we only need some of the points */
509 if (cmd
->stop_src
== TRIG_COUNT
&& devpriv
->count
< numPoints
)
510 numPoints
= devpriv
->count
;
511 insw(dev
->iobase
+ DAS1800_FIFO
, devpriv
->ai_buf0
, numPoints
);
512 munge_data(dev
, devpriv
->ai_buf0
, numPoints
);
513 cfc_write_array_to_buffer(s
, devpriv
->ai_buf0
,
514 numPoints
* sizeof(devpriv
->ai_buf0
[0]));
515 if (cmd
->stop_src
== TRIG_COUNT
)
516 devpriv
->count
-= numPoints
;
520 static void das1800_handle_fifo_not_empty(struct comedi_device
*dev
,
521 struct comedi_subdevice
*s
)
525 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
527 unipolar
= inb(dev
->iobase
+ DAS1800_CONTROL_C
) & UB
;
529 while (inb(dev
->iobase
+ DAS1800_STATUS
) & FNE
) {
530 if (cmd
->stop_src
== TRIG_COUNT
&& devpriv
->count
== 0)
532 dpnt
= inw(dev
->iobase
+ DAS1800_FIFO
);
533 /* convert to unsigned type if we are in a bipolar mode */
536 dpnt
= munge_bipolar_sample(dev
, dpnt
);
537 cfc_write_to_buffer(s
, dpnt
);
538 if (cmd
->stop_src
== TRIG_COUNT
)
545 /* Utility function used by das1800_flush_dma() and das1800_handle_dma().
546 * Assumes dma lock is held */
547 static void das1800_flush_dma_channel(struct comedi_device
*dev
,
548 struct comedi_subdevice
*s
,
549 unsigned int channel
, uint16_t *buffer
)
551 unsigned int num_bytes
, num_samples
;
552 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
554 disable_dma(channel
);
556 /* clear flip-flop to make sure 2-byte registers
557 * get set correctly */
558 clear_dma_ff(channel
);
560 /* figure out how many points to read */
561 num_bytes
= devpriv
->dma_transfer_size
- get_dma_residue(channel
);
562 num_samples
= num_bytes
/ sizeof(short);
564 /* if we only need some of the points */
565 if (cmd
->stop_src
== TRIG_COUNT
&& devpriv
->count
< num_samples
)
566 num_samples
= devpriv
->count
;
568 munge_data(dev
, buffer
, num_samples
);
569 cfc_write_array_to_buffer(s
, buffer
, num_bytes
);
570 if (s
->async
->cmd
.stop_src
== TRIG_COUNT
)
571 devpriv
->count
-= num_samples
;
576 /* flushes remaining data from board when external trigger has stopped acquisition
577 * and we are using dma transfers */
578 static void das1800_flush_dma(struct comedi_device
*dev
,
579 struct comedi_subdevice
*s
)
582 const int dual_dma
= devpriv
->irq_dma_bits
& DMA_DUAL
;
584 flags
= claim_dma_lock();
585 das1800_flush_dma_channel(dev
, s
, devpriv
->dma_current
,
586 devpriv
->dma_current_buf
);
589 /* switch to other channel and flush it */
590 if (devpriv
->dma_current
== devpriv
->dma0
) {
591 devpriv
->dma_current
= devpriv
->dma1
;
592 devpriv
->dma_current_buf
= devpriv
->ai_buf1
;
594 devpriv
->dma_current
= devpriv
->dma0
;
595 devpriv
->dma_current_buf
= devpriv
->ai_buf0
;
597 das1800_flush_dma_channel(dev
, s
, devpriv
->dma_current
,
598 devpriv
->dma_current_buf
);
601 release_dma_lock(flags
);
603 /* get any remaining samples in fifo */
604 das1800_handle_fifo_not_empty(dev
, s
);
609 static void das1800_handle_dma(struct comedi_device
*dev
,
610 struct comedi_subdevice
*s
, unsigned int status
)
613 const int dual_dma
= devpriv
->irq_dma_bits
& DMA_DUAL
;
615 flags
= claim_dma_lock();
616 das1800_flush_dma_channel(dev
, s
, devpriv
->dma_current
,
617 devpriv
->dma_current_buf
);
618 /* re-enable dma channel */
619 set_dma_addr(devpriv
->dma_current
,
620 virt_to_bus(devpriv
->dma_current_buf
));
621 set_dma_count(devpriv
->dma_current
, devpriv
->dma_transfer_size
);
622 enable_dma(devpriv
->dma_current
);
623 release_dma_lock(flags
);
625 if (status
& DMATC
) {
626 /* clear DMATC interrupt bit */
627 outb(CLEAR_INTR_MASK
& ~DMATC
, dev
->iobase
+ DAS1800_STATUS
);
628 /* switch dma channels for next time, if appropriate */
630 /* read data from the other channel next time */
631 if (devpriv
->dma_current
== devpriv
->dma0
) {
632 devpriv
->dma_current
= devpriv
->dma1
;
633 devpriv
->dma_current_buf
= devpriv
->ai_buf1
;
635 devpriv
->dma_current
= devpriv
->dma0
;
636 devpriv
->dma_current_buf
= devpriv
->ai_buf0
;
644 static int das1800_cancel(struct comedi_device
*dev
, struct comedi_subdevice
*s
)
646 outb(0x0, dev
->iobase
+ DAS1800_STATUS
); /* disable conversions */
647 outb(0x0, dev
->iobase
+ DAS1800_CONTROL_B
); /* disable interrupts and dma */
648 outb(0x0, dev
->iobase
+ DAS1800_CONTROL_A
); /* disable and clear fifo and stop triggering */
650 disable_dma(devpriv
->dma0
);
652 disable_dma(devpriv
->dma1
);
656 /* the guts of the interrupt handler, that is shared with das1800_ai_poll */
657 static void das1800_ai_handler(struct comedi_device
*dev
)
659 struct comedi_subdevice
*s
= dev
->subdevices
+ 0; /* analog input subdevice */
660 struct comedi_async
*async
= s
->async
;
661 struct comedi_cmd
*cmd
= &async
->cmd
;
662 unsigned int status
= inb(dev
->iobase
+ DAS1800_STATUS
);
665 /* select adc for base address + 0 */
666 outb(ADC
, dev
->iobase
+ DAS1800_SELECT
);
667 /* dma buffer full */
668 if (devpriv
->irq_dma_bits
& DMA_ENABLED
) {
669 /* look for data from dma transfer even if dma terminal count hasn't happened yet */
670 das1800_handle_dma(dev
, s
, status
);
671 } else if (status
& FHF
) { /* if fifo half full */
672 das1800_handle_fifo_half_full(dev
, s
);
673 } else if (status
& FNE
) { /* if fifo not empty */
674 das1800_handle_fifo_not_empty(dev
, s
);
677 async
->events
|= COMEDI_CB_BLOCK
;
678 /* if the card's fifo has overflowed */
680 /* clear OVF interrupt bit */
681 outb(CLEAR_INTR_MASK
& ~OVF
, dev
->iobase
+ DAS1800_STATUS
);
682 comedi_error(dev
, "DAS1800 FIFO overflow");
683 das1800_cancel(dev
, s
);
684 async
->events
|= COMEDI_CB_ERROR
| COMEDI_CB_EOA
;
685 comedi_event(dev
, s
);
688 /* stop taking data if appropriate */
689 /* stop_src TRIG_EXT */
690 if (status
& CT0TC
) {
691 /* clear CT0TC interrupt bit */
692 outb(CLEAR_INTR_MASK
& ~CT0TC
, dev
->iobase
+ DAS1800_STATUS
);
693 /* make sure we get all remaining data from board before quitting */
694 if (devpriv
->irq_dma_bits
& DMA_ENABLED
)
695 das1800_flush_dma(dev
, s
);
697 das1800_handle_fifo_not_empty(dev
, s
);
698 das1800_cancel(dev
, s
); /* disable hardware conversions */
699 async
->events
|= COMEDI_CB_EOA
;
700 } else if (cmd
->stop_src
== TRIG_COUNT
&& devpriv
->count
== 0) { /* stop_src TRIG_COUNT */
701 das1800_cancel(dev
, s
); /* disable hardware conversions */
702 async
->events
|= COMEDI_CB_EOA
;
705 comedi_event(dev
, s
);
710 static int das1800_ai_poll(struct comedi_device
*dev
,
711 struct comedi_subdevice
*s
)
715 /* prevent race with interrupt handler */
716 spin_lock_irqsave(&dev
->spinlock
, flags
);
717 das1800_ai_handler(dev
);
718 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
720 return s
->async
->buf_write_count
- s
->async
->buf_read_count
;
723 static irqreturn_t
das1800_interrupt(int irq
, void *d
)
725 struct comedi_device
*dev
= d
;
728 if (dev
->attached
== 0) {
729 comedi_error(dev
, "premature interrupt");
733 /* Prevent race with das1800_ai_poll() on multi processor systems.
734 * Also protects indirect addressing in das1800_ai_handler */
735 spin_lock(&dev
->spinlock
);
736 status
= inb(dev
->iobase
+ DAS1800_STATUS
);
738 /* if interrupt was not caused by das-1800 */
739 if (!(status
& INT
)) {
740 spin_unlock(&dev
->spinlock
);
743 /* clear the interrupt status bit INT */
744 outb(CLEAR_INTR_MASK
& ~INT
, dev
->iobase
+ DAS1800_STATUS
);
745 /* handle interrupt */
746 das1800_ai_handler(dev
);
748 spin_unlock(&dev
->spinlock
);
752 /* converts requested conversion timing to timing compatible with
753 * hardware, used only when card is in 'burst mode'
755 static unsigned int burst_convert_arg(unsigned int convert_arg
, int round_mode
)
757 unsigned int micro_sec
;
759 /* in burst mode, the maximum conversion time is 64 microseconds */
760 if (convert_arg
> 64000)
763 /* the conversion time must be an integral number of microseconds */
764 switch (round_mode
) {
765 case TRIG_ROUND_NEAREST
:
767 micro_sec
= (convert_arg
+ 500) / 1000;
769 case TRIG_ROUND_DOWN
:
770 micro_sec
= convert_arg
/ 1000;
773 micro_sec
= (convert_arg
- 1) / 1000 + 1;
777 /* return number of nanoseconds */
778 return micro_sec
* 1000;
781 /* test analog input cmd */
782 static int das1800_ai_do_cmdtest(struct comedi_device
*dev
,
783 struct comedi_subdevice
*s
,
784 struct comedi_cmd
*cmd
)
788 unsigned int tmp_arg
;
792 /* step 1: make sure trigger sources are trivially valid */
794 tmp
= cmd
->start_src
;
795 cmd
->start_src
&= TRIG_NOW
| TRIG_EXT
;
796 if (!cmd
->start_src
|| tmp
!= cmd
->start_src
)
799 tmp
= cmd
->scan_begin_src
;
800 cmd
->scan_begin_src
&= TRIG_FOLLOW
| TRIG_TIMER
| TRIG_EXT
;
801 if (!cmd
->scan_begin_src
|| tmp
!= cmd
->scan_begin_src
)
804 tmp
= cmd
->convert_src
;
805 cmd
->convert_src
&= TRIG_TIMER
| TRIG_EXT
;
806 if (!cmd
->convert_src
|| tmp
!= cmd
->convert_src
)
809 tmp
= cmd
->scan_end_src
;
810 cmd
->scan_end_src
&= TRIG_COUNT
;
811 if (!cmd
->scan_end_src
|| tmp
!= cmd
->scan_end_src
)
815 cmd
->stop_src
&= TRIG_COUNT
| TRIG_EXT
| TRIG_NONE
;
816 if (!cmd
->stop_src
|| tmp
!= cmd
->stop_src
)
822 /* step 2: make sure trigger sources are unique and mutually compatible */
824 /* uniqueness check */
825 if (cmd
->start_src
!= TRIG_NOW
&& cmd
->start_src
!= TRIG_EXT
)
827 if (cmd
->scan_begin_src
!= TRIG_FOLLOW
&&
828 cmd
->scan_begin_src
!= TRIG_TIMER
&&
829 cmd
->scan_begin_src
!= TRIG_EXT
)
831 if (cmd
->convert_src
!= TRIG_TIMER
&& cmd
->convert_src
!= TRIG_EXT
)
833 if (cmd
->stop_src
!= TRIG_COUNT
&&
834 cmd
->stop_src
!= TRIG_NONE
&& cmd
->stop_src
!= TRIG_EXT
)
836 /* compatibility check */
837 if (cmd
->scan_begin_src
!= TRIG_FOLLOW
&&
838 cmd
->convert_src
!= TRIG_TIMER
)
844 /* step 3: make sure arguments are trivially compatible */
846 if (cmd
->start_arg
!= 0) {
850 if (cmd
->convert_src
== TRIG_TIMER
) {
851 if (cmd
->convert_arg
< thisboard
->ai_speed
) {
852 cmd
->convert_arg
= thisboard
->ai_speed
;
856 if (!cmd
->chanlist_len
) {
857 cmd
->chanlist_len
= 1;
860 if (cmd
->scan_end_arg
!= cmd
->chanlist_len
) {
861 cmd
->scan_end_arg
= cmd
->chanlist_len
;
865 switch (cmd
->stop_src
) {
867 if (!cmd
->stop_arg
) {
873 if (cmd
->stop_arg
!= 0) {
885 /* step 4: fix up any arguments */
887 if (cmd
->convert_src
== TRIG_TIMER
) {
888 /* if we are not in burst mode */
889 if (cmd
->scan_begin_src
== TRIG_FOLLOW
) {
890 tmp_arg
= cmd
->convert_arg
;
891 /* calculate counter values that give desired timing */
892 i8253_cascade_ns_to_timer_2div(TIMER_BASE
,
893 &(devpriv
->divisor1
),
894 &(devpriv
->divisor2
),
897 flags
& TRIG_ROUND_MASK
);
898 if (tmp_arg
!= cmd
->convert_arg
)
901 /* if we are in burst mode */
903 /* check that convert_arg is compatible */
904 tmp_arg
= cmd
->convert_arg
;
906 burst_convert_arg(cmd
->convert_arg
,
907 cmd
->flags
& TRIG_ROUND_MASK
);
908 if (tmp_arg
!= cmd
->convert_arg
)
911 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
912 /* if scans are timed faster than conversion rate allows */
913 if (cmd
->convert_arg
* cmd
->chanlist_len
>
914 cmd
->scan_begin_arg
) {
915 cmd
->scan_begin_arg
=
920 tmp_arg
= cmd
->scan_begin_arg
;
921 /* calculate counter values that give desired timing */
922 i8253_cascade_ns_to_timer_2div(TIMER_BASE
,
932 if (tmp_arg
!= cmd
->scan_begin_arg
)
941 /* make sure user is not trying to mix unipolar and bipolar ranges */
943 unipolar
= CR_RANGE(cmd
->chanlist
[0]) & UNIPOLAR
;
944 for (i
= 1; i
< cmd
->chanlist_len
; i
++) {
945 if (unipolar
!= (CR_RANGE(cmd
->chanlist
[i
]) & UNIPOLAR
)) {
947 "unipolar and bipolar ranges cannot be mixed in the chanlist");
960 /* returns appropriate bits for control register a, depending on command */
961 static int control_a_bits(struct comedi_cmd cmd
)
965 control_a
= FFEN
; /* enable fifo */
966 if (cmd
.stop_src
== TRIG_EXT
)
968 switch (cmd
.start_src
) {
970 control_a
|= TGEN
| CGSL
;
982 /* returns appropriate bits for control register c, depending on command */
983 static int control_c_bits(struct comedi_cmd cmd
)
988 /* set clock source to internal or external, select analog reference,
989 * select unipolar / bipolar
991 aref
= CR_AREF(cmd
.chanlist
[0]);
992 control_c
= UQEN
; /* enable upper qram addresses */
993 if (aref
!= AREF_DIFF
)
995 if (aref
== AREF_COMMON
)
997 /* if a unipolar range was selected */
998 if (CR_RANGE(cmd
.chanlist
[0]) & UNIPOLAR
)
1000 switch (cmd
.scan_begin_src
) {
1001 case TRIG_FOLLOW
: /* not in burst mode */
1002 switch (cmd
.convert_src
) {
1004 /* trig on cascaded counters */
1008 /* trig on falling edge of external trigger */
1016 /* burst mode with internal pacer clock */
1017 control_c
|= BMDE
| IPCLK
;
1020 /* burst mode with external trigger */
1021 control_c
|= BMDE
| XPCLK
;
1030 /* loads counters with divisor1, divisor2 from private structure */
1031 static int das1800_set_frequency(struct comedi_device
*dev
)
1035 /* counter 1, mode 2 */
1036 if (i8254_load(dev
->iobase
+ DAS1800_COUNTER
, 0, 1, devpriv
->divisor1
,
1039 /* counter 2, mode 2 */
1040 if (i8254_load(dev
->iobase
+ DAS1800_COUNTER
, 0, 2, devpriv
->divisor2
,
1049 /* sets up counters */
1050 static int setup_counters(struct comedi_device
*dev
, struct comedi_cmd cmd
)
1052 /* setup cascaded counters for conversion/scan frequency */
1053 switch (cmd
.scan_begin_src
) {
1054 case TRIG_FOLLOW
: /* not in burst mode */
1055 if (cmd
.convert_src
== TRIG_TIMER
) {
1056 /* set conversion frequency */
1057 i8253_cascade_ns_to_timer_2div(TIMER_BASE
,
1058 &(devpriv
->divisor1
),
1059 &(devpriv
->divisor2
),
1062 flags
& TRIG_ROUND_MASK
);
1063 if (das1800_set_frequency(dev
) < 0)
1067 case TRIG_TIMER
: /* in burst mode */
1068 /* set scan frequency */
1069 i8253_cascade_ns_to_timer_2div(TIMER_BASE
, &(devpriv
->divisor1
),
1070 &(devpriv
->divisor2
),
1071 &(cmd
.scan_begin_arg
),
1072 cmd
.flags
& TRIG_ROUND_MASK
);
1073 if (das1800_set_frequency(dev
) < 0)
1080 /* setup counter 0 for 'about triggering' */
1081 if (cmd
.stop_src
== TRIG_EXT
) {
1082 /* load counter 0 in mode 0 */
1083 i8254_load(dev
->iobase
+ DAS1800_COUNTER
, 0, 0, 1, 0);
1089 /* utility function that suggests a dma transfer size based on the conversion period 'ns' */
1090 static unsigned int suggest_transfer_size(struct comedi_cmd
*cmd
)
1092 unsigned int size
= DMA_BUF_SIZE
;
1093 static const int sample_size
= 2; /* size in bytes of one sample from board */
1094 unsigned int fill_time
= 300000000; /* target time in nanoseconds for filling dma buffer */
1095 unsigned int max_size
; /* maximum size we will allow for a transfer */
1097 /* make dma buffer fill in 0.3 seconds for timed modes */
1098 switch (cmd
->scan_begin_src
) {
1099 case TRIG_FOLLOW
: /* not in burst mode */
1100 if (cmd
->convert_src
== TRIG_TIMER
)
1101 size
= (fill_time
/ cmd
->convert_arg
) * sample_size
;
1104 size
= (fill_time
/ (cmd
->scan_begin_arg
* cmd
->chanlist_len
)) *
1108 size
= DMA_BUF_SIZE
;
1112 /* set a minimum and maximum size allowed */
1113 max_size
= DMA_BUF_SIZE
;
1114 /* if we are taking limited number of conversions, limit transfer size to that */
1115 if (cmd
->stop_src
== TRIG_COUNT
&&
1116 cmd
->stop_arg
* cmd
->chanlist_len
* sample_size
< max_size
)
1117 max_size
= cmd
->stop_arg
* cmd
->chanlist_len
* sample_size
;
1119 if (size
> max_size
)
1121 if (size
< sample_size
)
1128 static void setup_dma(struct comedi_device
*dev
, struct comedi_cmd cmd
)
1130 unsigned long lock_flags
;
1131 const int dual_dma
= devpriv
->irq_dma_bits
& DMA_DUAL
;
1133 if ((devpriv
->irq_dma_bits
& DMA_ENABLED
) == 0)
1136 /* determine a reasonable dma transfer size */
1137 devpriv
->dma_transfer_size
= suggest_transfer_size(&cmd
);
1138 lock_flags
= claim_dma_lock();
1139 disable_dma(devpriv
->dma0
);
1140 /* clear flip-flop to make sure 2-byte registers for
1141 * count and address get set correctly */
1142 clear_dma_ff(devpriv
->dma0
);
1143 set_dma_addr(devpriv
->dma0
, virt_to_bus(devpriv
->ai_buf0
));
1144 /* set appropriate size of transfer */
1145 set_dma_count(devpriv
->dma0
, devpriv
->dma_transfer_size
);
1146 devpriv
->dma_current
= devpriv
->dma0
;
1147 devpriv
->dma_current_buf
= devpriv
->ai_buf0
;
1148 enable_dma(devpriv
->dma0
);
1149 /* set up dual dma if appropriate */
1151 disable_dma(devpriv
->dma1
);
1152 /* clear flip-flop to make sure 2-byte registers for
1153 * count and address get set correctly */
1154 clear_dma_ff(devpriv
->dma1
);
1155 set_dma_addr(devpriv
->dma1
, virt_to_bus(devpriv
->ai_buf1
));
1156 /* set appropriate size of transfer */
1157 set_dma_count(devpriv
->dma1
, devpriv
->dma_transfer_size
);
1158 enable_dma(devpriv
->dma1
);
1160 release_dma_lock(lock_flags
);
1165 /* programs channel/gain list into card */
1166 static void program_chanlist(struct comedi_device
*dev
, struct comedi_cmd cmd
)
1168 int i
, n
, chan_range
;
1169 unsigned long irq_flags
;
1170 const int range_mask
= 0x3; /* masks unipolar/bipolar bit off range */
1171 const int range_bitshift
= 8;
1173 n
= cmd
.chanlist_len
;
1174 /* spinlock protects indirect addressing */
1175 spin_lock_irqsave(&dev
->spinlock
, irq_flags
);
1176 outb(QRAM
, dev
->iobase
+ DAS1800_SELECT
); /* select QRAM for baseAddress + 0x0 */
1177 outb(n
- 1, dev
->iobase
+ DAS1800_QRAM_ADDRESS
); /*set QRAM address start */
1178 /* make channel / gain list */
1179 for (i
= 0; i
< n
; i
++) {
1182 chanlist
[i
]) | ((CR_RANGE(cmd
.chanlist
[i
]) &
1183 range_mask
) << range_bitshift
);
1184 outw(chan_range
, dev
->iobase
+ DAS1800_QRAM
);
1186 outb(n
- 1, dev
->iobase
+ DAS1800_QRAM_ADDRESS
); /*finish write to QRAM */
1187 spin_unlock_irqrestore(&dev
->spinlock
, irq_flags
);
1192 /* analog input do_cmd */
1193 static int das1800_ai_do_cmd(struct comedi_device
*dev
,
1194 struct comedi_subdevice
*s
)
1197 int control_a
, control_c
;
1198 struct comedi_async
*async
= s
->async
;
1199 struct comedi_cmd cmd
= async
->cmd
;
1203 "no irq assigned for das-1800, cannot do hardware conversions");
1207 /* disable dma on TRIG_WAKE_EOS, or TRIG_RT
1208 * (because dma in handler is unsafe at hard real-time priority) */
1209 if (cmd
.flags
& (TRIG_WAKE_EOS
| TRIG_RT
))
1210 devpriv
->irq_dma_bits
&= ~DMA_ENABLED
;
1212 devpriv
->irq_dma_bits
|= devpriv
->dma_bits
;
1213 /* interrupt on end of conversion for TRIG_WAKE_EOS */
1214 if (cmd
.flags
& TRIG_WAKE_EOS
) {
1215 /* interrupt fifo not empty */
1216 devpriv
->irq_dma_bits
&= ~FIMD
;
1218 /* interrupt fifo half full */
1219 devpriv
->irq_dma_bits
|= FIMD
;
1221 /* determine how many conversions we need */
1222 if (cmd
.stop_src
== TRIG_COUNT
)
1223 devpriv
->count
= cmd
.stop_arg
* cmd
.chanlist_len
;
1225 das1800_cancel(dev
, s
);
1227 /* determine proper bits for control registers */
1228 control_a
= control_a_bits(cmd
);
1229 control_c
= control_c_bits(cmd
);
1231 /* setup card and start */
1232 program_chanlist(dev
, cmd
);
1233 ret
= setup_counters(dev
, cmd
);
1235 comedi_error(dev
, "Error setting up counters");
1238 setup_dma(dev
, cmd
);
1239 outb(control_c
, dev
->iobase
+ DAS1800_CONTROL_C
);
1240 /* set conversion rate and length for burst mode */
1241 if (control_c
& BMDE
) {
1242 /* program conversion period with number of microseconds minus 1 */
1243 outb(cmd
.convert_arg
/ 1000 - 1,
1244 dev
->iobase
+ DAS1800_BURST_RATE
);
1245 outb(cmd
.chanlist_len
- 1, dev
->iobase
+ DAS1800_BURST_LENGTH
);
1247 outb(devpriv
->irq_dma_bits
, dev
->iobase
+ DAS1800_CONTROL_B
); /* enable irq/dma */
1248 outb(control_a
, dev
->iobase
+ DAS1800_CONTROL_A
); /* enable fifo and triggering */
1249 outb(CVEN
, dev
->iobase
+ DAS1800_STATUS
); /* enable conversions */
1254 /* read analog input */
1255 static int das1800_ai_rinsn(struct comedi_device
*dev
,
1256 struct comedi_subdevice
*s
,
1257 struct comedi_insn
*insn
, unsigned int *data
)
1260 int chan
, range
, aref
, chan_range
;
1264 unsigned long irq_flags
;
1266 /* set up analog reference and unipolar / bipolar mode */
1267 aref
= CR_AREF(insn
->chanspec
);
1269 if (aref
!= AREF_DIFF
)
1271 if (aref
== AREF_COMMON
)
1273 /* if a unipolar range was selected */
1274 if (CR_RANGE(insn
->chanspec
) & UNIPOLAR
)
1277 outb(conv_flags
, dev
->iobase
+ DAS1800_CONTROL_C
); /* software conversion enabled */
1278 outb(CVEN
, dev
->iobase
+ DAS1800_STATUS
); /* enable conversions */
1279 outb(0x0, dev
->iobase
+ DAS1800_CONTROL_A
); /* reset fifo */
1280 outb(FFEN
, dev
->iobase
+ DAS1800_CONTROL_A
);
1282 chan
= CR_CHAN(insn
->chanspec
);
1283 /* mask of unipolar/bipolar bit from range */
1284 range
= CR_RANGE(insn
->chanspec
) & 0x3;
1285 chan_range
= chan
| (range
<< 8);
1286 spin_lock_irqsave(&dev
->spinlock
, irq_flags
);
1287 outb(QRAM
, dev
->iobase
+ DAS1800_SELECT
); /* select QRAM for baseAddress + 0x0 */
1288 outb(0x0, dev
->iobase
+ DAS1800_QRAM_ADDRESS
); /* set QRAM address start */
1289 outw(chan_range
, dev
->iobase
+ DAS1800_QRAM
);
1290 outb(0x0, dev
->iobase
+ DAS1800_QRAM_ADDRESS
); /*finish write to QRAM */
1291 outb(ADC
, dev
->iobase
+ DAS1800_SELECT
); /* select ADC for baseAddress + 0x0 */
1293 for (n
= 0; n
< insn
->n
; n
++) {
1294 /* trigger conversion */
1295 outb(0, dev
->iobase
+ DAS1800_FIFO
);
1296 for (i
= 0; i
< timeout
; i
++) {
1297 if (inb(dev
->iobase
+ DAS1800_STATUS
) & FNE
)
1301 comedi_error(dev
, "timeout");
1305 dpnt
= inw(dev
->iobase
+ DAS1800_FIFO
);
1306 /* shift data to offset binary for bipolar ranges */
1307 if ((conv_flags
& UB
) == 0)
1308 dpnt
+= 1 << (thisboard
->resolution
- 1);
1312 spin_unlock_irqrestore(&dev
->spinlock
, irq_flags
);
1317 /* writes to an analog output channel */
1318 static int das1800_ao_winsn(struct comedi_device
*dev
,
1319 struct comedi_subdevice
*s
,
1320 struct comedi_insn
*insn
, unsigned int *data
)
1322 int chan
= CR_CHAN(insn
->chanspec
);
1323 /* int range = CR_RANGE(insn->chanspec); */
1324 int update_chan
= thisboard
->ao_n_chan
- 1;
1326 unsigned long irq_flags
;
1328 /* card expects two's complement data */
1329 output
= data
[0] - (1 << (thisboard
->resolution
- 1));
1330 /* if the write is to the 'update' channel, we need to remember its value */
1331 if (chan
== update_chan
)
1332 devpriv
->ao_update_bits
= output
;
1333 /* write to channel */
1334 spin_lock_irqsave(&dev
->spinlock
, irq_flags
);
1335 outb(DAC(chan
), dev
->iobase
+ DAS1800_SELECT
); /* select dac channel for baseAddress + 0x0 */
1336 outw(output
, dev
->iobase
+ DAS1800_DAC
);
1337 /* now we need to write to 'update' channel to update all dac channels */
1338 if (chan
!= update_chan
) {
1339 outb(DAC(update_chan
), dev
->iobase
+ DAS1800_SELECT
); /* select 'update' channel for baseAddress + 0x0 */
1340 outw(devpriv
->ao_update_bits
, dev
->iobase
+ DAS1800_DAC
);
1342 spin_unlock_irqrestore(&dev
->spinlock
, irq_flags
);
1347 /* reads from digital input channels */
1348 static int das1800_di_rbits(struct comedi_device
*dev
,
1349 struct comedi_subdevice
*s
,
1350 struct comedi_insn
*insn
, unsigned int *data
)
1353 data
[1] = inb(dev
->iobase
+ DAS1800_DIGITAL
) & 0xf;
1359 /* writes to digital output channels */
1360 static int das1800_do_wbits(struct comedi_device
*dev
,
1361 struct comedi_subdevice
*s
,
1362 struct comedi_insn
*insn
, unsigned int *data
)
1366 /* only set bits that have been masked */
1367 data
[0] &= (1 << s
->n_chan
) - 1;
1368 wbits
= devpriv
->do_bits
;
1370 wbits
|= data
[0] & data
[1];
1371 devpriv
->do_bits
= wbits
;
1373 outb(devpriv
->do_bits
, dev
->iobase
+ DAS1800_DIGITAL
);
1375 data
[1] = devpriv
->do_bits
;
1380 static int das1800_init_dma(struct comedi_device
*dev
, unsigned int dma0
,
1383 unsigned long flags
;
1385 /* need an irq to do dma */
1386 if (dev
->irq
&& dma0
) {
1387 /* encode dma0 and dma1 into 2 digit hexadecimal for switch */
1388 switch ((dma0
& 0x7) | (dma1
<< 4)) {
1389 case 0x5: /* dma0 == 5 */
1390 devpriv
->dma_bits
|= DMA_CH5
;
1392 case 0x6: /* dma0 == 6 */
1393 devpriv
->dma_bits
|= DMA_CH6
;
1395 case 0x7: /* dma0 == 7 */
1396 devpriv
->dma_bits
|= DMA_CH7
;
1398 case 0x65: /* dma0 == 5, dma1 == 6 */
1399 devpriv
->dma_bits
|= DMA_CH5_CH6
;
1401 case 0x76: /* dma0 == 6, dma1 == 7 */
1402 devpriv
->dma_bits
|= DMA_CH6_CH7
;
1404 case 0x57: /* dma0 == 7, dma1 == 5 */
1405 devpriv
->dma_bits
|= DMA_CH7_CH5
;
1408 dev_err(dev
->class_dev
,
1409 "only supports dma channels 5 through 7\n");
1410 dev_err(dev
->class_dev
,
1411 "Dual dma only allows the following combinations:\n");
1412 dev_err(dev
->class_dev
,
1413 "dma 5,6 / 6,7 / or 7,5\n");
1417 if (request_dma(dma0
, dev
->driver
->driver_name
)) {
1418 dev_err(dev
->class_dev
,
1419 "failed to allocate dma channel %i\n", dma0
);
1422 devpriv
->dma0
= dma0
;
1423 devpriv
->dma_current
= dma0
;
1425 if (request_dma(dma1
, dev
->driver
->driver_name
)) {
1426 dev_err(dev
->class_dev
,
1427 "failed to allocate dma channel %i\n",
1431 devpriv
->dma1
= dma1
;
1433 devpriv
->ai_buf0
= kmalloc(DMA_BUF_SIZE
, GFP_KERNEL
| GFP_DMA
);
1434 if (devpriv
->ai_buf0
== NULL
)
1436 devpriv
->dma_current_buf
= devpriv
->ai_buf0
;
1439 kmalloc(DMA_BUF_SIZE
, GFP_KERNEL
| GFP_DMA
);
1440 if (devpriv
->ai_buf1
== NULL
)
1443 flags
= claim_dma_lock();
1444 disable_dma(devpriv
->dma0
);
1445 set_dma_mode(devpriv
->dma0
, DMA_MODE_READ
);
1447 disable_dma(devpriv
->dma1
);
1448 set_dma_mode(devpriv
->dma1
, DMA_MODE_READ
);
1450 release_dma_lock(flags
);
1455 static int das1800_probe(struct comedi_device
*dev
)
1460 id
= (inb(dev
->iobase
+ DAS1800_DIGITAL
) >> 4) & 0xf; /* get id bits */
1461 board
= ((struct das1800_board
*)dev
->board_ptr
) - das1800_boards
;
1465 if (board
== das1801st_da
|| board
== das1802st_da
||
1466 board
== das1701st_da
|| board
== das1702st_da
) {
1467 dev_dbg(dev
->class_dev
, "Board model: %s\n",
1468 das1800_boards
[board
].name
);
1472 (" Board model (probed, not recommended): das-1800st-da series\n");
1476 if (board
== das1802hr_da
|| board
== das1702hr_da
) {
1477 dev_dbg(dev
->class_dev
, "Board model: %s\n",
1478 das1800_boards
[board
].name
);
1482 (" Board model (probed, not recommended): das-1802hr-da\n");
1486 if (board
== das1801ao
|| board
== das1802ao
||
1487 board
== das1701ao
|| board
== das1702ao
) {
1488 dev_dbg(dev
->class_dev
, "Board model: %s\n",
1489 das1800_boards
[board
].name
);
1493 (" Board model (probed, not recommended): das-1800ao series\n");
1497 if (board
== das1802hr
|| board
== das1702hr
) {
1498 dev_dbg(dev
->class_dev
, "Board model: %s\n",
1499 das1800_boards
[board
].name
);
1503 (" Board model (probed, not recommended): das-1802hr\n");
1507 if (board
== das1801st
|| board
== das1802st
||
1508 board
== das1701st
|| board
== das1702st
) {
1509 dev_dbg(dev
->class_dev
, "Board model: %s\n",
1510 das1800_boards
[board
].name
);
1514 (" Board model (probed, not recommended): das-1800st series\n");
1518 if (board
== das1801hc
|| board
== das1802hc
) {
1519 dev_dbg(dev
->class_dev
, "Board model: %s\n",
1520 das1800_boards
[board
].name
);
1524 (" Board model (probed, not recommended): das-1800hc series\n");
1529 (" Board model: probe returned 0x%x (unknown, please report)\n",
1537 static int das1800_attach(struct comedi_device
*dev
,
1538 struct comedi_devconfig
*it
)
1540 struct comedi_subdevice
*s
;
1541 unsigned long iobase
= it
->options
[0];
1542 unsigned int irq
= it
->options
[1];
1543 unsigned int dma0
= it
->options
[2];
1544 unsigned int dma1
= it
->options
[3];
1545 unsigned long iobase2
;
1549 /* allocate and initialize dev->private */
1550 if (alloc_private(dev
, sizeof(struct das1800_private
)) < 0)
1553 printk(KERN_DEBUG
"comedi%d: %s: io 0x%lx", dev
->minor
,
1554 dev
->driver
->driver_name
, iobase
);
1556 printk(KERN_CONT
", irq %u", irq
);
1558 printk(KERN_CONT
", dma %u", dma0
);
1560 printk(KERN_CONT
" and %u", dma1
);
1563 printk(KERN_CONT
"\n");
1566 dev_err(dev
->class_dev
, "io base address required\n");
1570 /* check if io addresses are available */
1571 if (!request_region(iobase
, DAS1800_SIZE
, dev
->driver
->driver_name
)) {
1573 (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
1574 iobase
, iobase
+ DAS1800_SIZE
- 1);
1577 dev
->iobase
= iobase
;
1579 board
= das1800_probe(dev
);
1581 dev_err(dev
->class_dev
, "unable to determine board type\n");
1585 dev
->board_ptr
= das1800_boards
+ board
;
1586 dev
->board_name
= thisboard
->name
;
1588 /* if it is an 'ao' board with fancy analog out then we need extra io ports */
1589 if (thisboard
->ao_ability
== 2) {
1590 iobase2
= iobase
+ IOBASE2
;
1591 if (!request_region(iobase2
, DAS1800_SIZE
,
1592 dev
->driver
->driver_name
)) {
1594 (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
1595 iobase2
, iobase2
+ DAS1800_SIZE
- 1);
1598 devpriv
->iobase2
= iobase2
;
1603 if (request_irq(irq
, das1800_interrupt
, 0,
1604 dev
->driver
->driver_name
, dev
)) {
1605 dev_dbg(dev
->class_dev
, "unable to allocate irq %u\n",
1612 /* set bits that tell card which irq to use */
1617 devpriv
->irq_dma_bits
|= 0x8;
1620 devpriv
->irq_dma_bits
|= 0x10;
1623 devpriv
->irq_dma_bits
|= 0x18;
1626 devpriv
->irq_dma_bits
|= 0x28;
1629 devpriv
->irq_dma_bits
|= 0x30;
1632 devpriv
->irq_dma_bits
|= 0x38;
1635 dev_err(dev
->class_dev
, "irq out of range\n");
1640 retval
= das1800_init_dma(dev
, dma0
, dma1
);
1644 if (devpriv
->ai_buf0
== NULL
) {
1646 kmalloc(FIFO_SIZE
* sizeof(uint16_t), GFP_KERNEL
);
1647 if (devpriv
->ai_buf0
== NULL
)
1651 retval
= comedi_alloc_subdevices(dev
, 4);
1655 /* analog input subdevice */
1656 s
= dev
->subdevices
+ 0;
1657 dev
->read_subdev
= s
;
1658 s
->type
= COMEDI_SUBD_AI
;
1659 s
->subdev_flags
= SDF_READABLE
| SDF_DIFF
| SDF_GROUND
| SDF_CMD_READ
;
1660 if (thisboard
->common
)
1661 s
->subdev_flags
|= SDF_COMMON
;
1662 s
->n_chan
= thisboard
->qram_len
;
1663 s
->len_chanlist
= thisboard
->qram_len
;
1664 s
->maxdata
= (1 << thisboard
->resolution
) - 1;
1665 s
->range_table
= thisboard
->range_ai
;
1666 s
->do_cmd
= das1800_ai_do_cmd
;
1667 s
->do_cmdtest
= das1800_ai_do_cmdtest
;
1668 s
->insn_read
= das1800_ai_rinsn
;
1669 s
->poll
= das1800_ai_poll
;
1670 s
->cancel
= das1800_cancel
;
1673 s
= dev
->subdevices
+ 1;
1674 if (thisboard
->ao_ability
== 1) {
1675 s
->type
= COMEDI_SUBD_AO
;
1676 s
->subdev_flags
= SDF_WRITABLE
;
1677 s
->n_chan
= thisboard
->ao_n_chan
;
1678 s
->maxdata
= (1 << thisboard
->resolution
) - 1;
1679 s
->range_table
= &range_ao_1
;
1680 s
->insn_write
= das1800_ao_winsn
;
1682 s
->type
= COMEDI_SUBD_UNUSED
;
1686 s
= dev
->subdevices
+ 2;
1687 s
->type
= COMEDI_SUBD_DI
;
1688 s
->subdev_flags
= SDF_READABLE
;
1691 s
->range_table
= &range_digital
;
1692 s
->insn_bits
= das1800_di_rbits
;
1695 s
= dev
->subdevices
+ 3;
1696 s
->type
= COMEDI_SUBD_DO
;
1697 s
->subdev_flags
= SDF_WRITABLE
| SDF_READABLE
;
1698 s
->n_chan
= thisboard
->do_n_chan
;
1700 s
->range_table
= &range_digital
;
1701 s
->insn_bits
= das1800_do_wbits
;
1703 das1800_cancel(dev
, dev
->read_subdev
);
1705 /* initialize digital out channels */
1706 outb(devpriv
->do_bits
, dev
->iobase
+ DAS1800_DIGITAL
);
1708 /* initialize analog out channels */
1709 if (thisboard
->ao_ability
== 1) {
1710 /* select 'update' dac channel for baseAddress + 0x0 */
1711 outb(DAC(thisboard
->ao_n_chan
- 1),
1712 dev
->iobase
+ DAS1800_SELECT
);
1713 outw(devpriv
->ao_update_bits
, dev
->iobase
+ DAS1800_DAC
);
1719 static void das1800_detach(struct comedi_device
*dev
)
1722 release_region(dev
->iobase
, DAS1800_SIZE
);
1724 free_irq(dev
->irq
, dev
);
1726 if (devpriv
->iobase2
)
1727 release_region(devpriv
->iobase2
, DAS1800_SIZE
);
1729 free_dma(devpriv
->dma0
);
1731 free_dma(devpriv
->dma1
);
1732 kfree(devpriv
->ai_buf0
);
1733 kfree(devpriv
->ai_buf1
);
1737 static struct comedi_driver das1800_driver
= {
1738 .driver_name
= "das1800",
1739 .module
= THIS_MODULE
,
1740 .attach
= das1800_attach
,
1741 .detach
= das1800_detach
,
1742 .num_names
= ARRAY_SIZE(das1800_boards
),
1743 .board_name
= &das1800_boards
[0].name
,
1744 .offset
= sizeof(struct das1800_board
),
1746 module_comedi_driver(das1800_driver
);
1748 MODULE_AUTHOR("Comedi http://www.comedi.org");
1749 MODULE_DESCRIPTION("Comedi low-level driver");
1750 MODULE_LICENSE("GPL");