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 static int das1800_attach(struct comedi_device
*dev
,
187 struct comedi_devconfig
*it
);
188 static int das1800_detach(struct comedi_device
*dev
);
189 static int das1800_probe(struct comedi_device
*dev
);
190 static int das1800_cancel(struct comedi_device
*dev
,
191 struct comedi_subdevice
*s
);
192 static irqreturn_t
das1800_interrupt(int irq
, void *d
);
193 static int das1800_ai_poll(struct comedi_device
*dev
,
194 struct comedi_subdevice
*s
);
195 static void das1800_ai_handler(struct comedi_device
*dev
);
196 static void das1800_handle_dma(struct comedi_device
*dev
,
197 struct comedi_subdevice
*s
, unsigned int status
);
198 static void das1800_flush_dma(struct comedi_device
*dev
,
199 struct comedi_subdevice
*s
);
200 static void das1800_flush_dma_channel(struct comedi_device
*dev
,
201 struct comedi_subdevice
*s
,
202 unsigned int channel
, uint16_t * buffer
);
203 static void das1800_handle_fifo_half_full(struct comedi_device
*dev
,
204 struct comedi_subdevice
*s
);
205 static void das1800_handle_fifo_not_empty(struct comedi_device
*dev
,
206 struct comedi_subdevice
*s
);
207 static int das1800_ai_do_cmdtest(struct comedi_device
*dev
,
208 struct comedi_subdevice
*s
,
209 struct comedi_cmd
*cmd
);
210 static int das1800_ai_do_cmd(struct comedi_device
*dev
,
211 struct comedi_subdevice
*s
);
212 static int das1800_ai_rinsn(struct comedi_device
*dev
,
213 struct comedi_subdevice
*s
,
214 struct comedi_insn
*insn
, unsigned int *data
);
215 static int das1800_ao_winsn(struct comedi_device
*dev
,
216 struct comedi_subdevice
*s
,
217 struct comedi_insn
*insn
, unsigned int *data
);
218 static int das1800_di_rbits(struct comedi_device
*dev
,
219 struct comedi_subdevice
*s
,
220 struct comedi_insn
*insn
, unsigned int *data
);
221 static int das1800_do_wbits(struct comedi_device
*dev
,
222 struct comedi_subdevice
*s
,
223 struct comedi_insn
*insn
, unsigned int *data
);
225 static int das1800_set_frequency(struct comedi_device
*dev
);
226 static unsigned int burst_convert_arg(unsigned int convert_arg
, int round_mode
);
227 static unsigned int suggest_transfer_size(struct comedi_cmd
*cmd
);
229 /* analog input ranges */
230 static const struct comedi_lrange range_ai_das1801
= {
244 static const struct comedi_lrange range_ai_das1802
= {
258 struct das1800_board
{
260 int ai_speed
; /* max conversion period in nanoseconds */
261 int resolution
; /* bits of ai resolution */
262 int qram_len
; /* length of card's channel / gain queue */
263 int common
; /* supports AREF_COMMON flag */
264 int do_n_chan
; /* number of digital output channels */
265 int ao_ability
; /* 0 == no analog out, 1 == basic analog out, 2 == waveform analog out */
266 int ao_n_chan
; /* number of analog out channels */
267 const struct comedi_lrange
*range_ai
; /* available input ranges */
270 /* Warning: the maximum conversion speeds listed below are
271 * not always achievable depending on board setup (see
274 static const struct das1800_board das1800_boards
[] = {
276 .name
= "das-1701st",
284 .range_ai
= &range_ai_das1801
,
287 .name
= "das-1701st-da",
295 .range_ai
= &range_ai_das1801
,
298 .name
= "das-1702st",
306 .range_ai
= &range_ai_das1802
,
309 .name
= "das-1702st-da",
317 .range_ai
= &range_ai_das1802
,
320 .name
= "das-1702hr",
328 .range_ai
= &range_ai_das1802
,
331 .name
= "das-1702hr-da",
339 .range_ai
= &range_ai_das1802
,
342 .name
= "das-1701ao",
350 .range_ai
= &range_ai_das1801
,
353 .name
= "das-1702ao",
361 .range_ai
= &range_ai_das1802
,
364 .name
= "das-1801st",
372 .range_ai
= &range_ai_das1801
,
375 .name
= "das-1801st-da",
383 .range_ai
= &range_ai_das1801
,
386 .name
= "das-1802st",
394 .range_ai
= &range_ai_das1802
,
397 .name
= "das-1802st-da",
405 .range_ai
= &range_ai_das1802
,
408 .name
= "das-1802hr",
416 .range_ai
= &range_ai_das1802
,
419 .name
= "das-1802hr-da",
427 .range_ai
= &range_ai_das1802
,
430 .name
= "das-1801hc",
438 .range_ai
= &range_ai_das1801
,
441 .name
= "das-1802hc",
449 .range_ai
= &range_ai_das1802
,
452 .name
= "das-1801ao",
460 .range_ai
= &range_ai_das1801
,
463 .name
= "das-1802ao",
471 .range_ai
= &range_ai_das1802
,
476 * Useful for shorthand access to the particular board structure
478 #define thisboard ((const struct das1800_board *)dev->board_ptr)
480 struct das1800_private
{
481 volatile unsigned int count
; /* number of data points left to be taken */
482 unsigned int divisor1
; /* value to load into board's counter 1 for timed conversions */
483 unsigned int divisor2
; /* value to load into board's counter 2 for timed conversions */
484 int do_bits
; /* digital output bits */
485 int irq_dma_bits
; /* bits for control register b */
486 /* dma bits for control register b, stored so that dma can be
487 * turned on and off */
489 unsigned int dma0
; /* dma channels used */
491 volatile unsigned int dma_current
; /* dma channel currently in use */
492 uint16_t *ai_buf0
; /* pointers to dma buffers */
494 uint16_t *dma_current_buf
; /* pointer to dma buffer currently being used */
495 unsigned int dma_transfer_size
; /* size of transfer currently used, in bytes */
496 unsigned long iobase2
; /* secondary io address used for analog out on 'ao' boards */
497 short ao_update_bits
; /* remembers the last write to the 'update' dac */
500 #define devpriv ((struct das1800_private *)dev->private)
502 /* analog out range for boards with basic analog out */
503 static const struct comedi_lrange range_ao_1
= {
510 /* analog out range for 'ao' boards */
512 static const struct comedi_lrange range_ao_2 = {
521 static struct comedi_driver driver_das1800
= {
522 .driver_name
= "das1800",
523 .module
= THIS_MODULE
,
524 .attach
= das1800_attach
,
525 .detach
= das1800_detach
,
526 .num_names
= ARRAY_SIZE(das1800_boards
),
527 .board_name
= &das1800_boards
[0].name
,
528 .offset
= sizeof(struct das1800_board
),
532 * A convenient macro that defines init_module() and cleanup_module(),
535 static int __init
driver_das1800_init_module(void)
537 return comedi_driver_register(&driver_das1800
);
540 static void __exit
driver_das1800_cleanup_module(void)
542 comedi_driver_unregister(&driver_das1800
);
545 module_init(driver_das1800_init_module
);
546 module_exit(driver_das1800_cleanup_module
);
548 static int das1800_init_dma(struct comedi_device
*dev
, unsigned int dma0
,
553 /* need an irq to do dma */
554 if (dev
->irq
&& dma0
) {
555 /* encode dma0 and dma1 into 2 digit hexadecimal for switch */
556 switch ((dma0
& 0x7) | (dma1
<< 4)) {
557 case 0x5: /* dma0 == 5 */
558 devpriv
->dma_bits
|= DMA_CH5
;
560 case 0x6: /* dma0 == 6 */
561 devpriv
->dma_bits
|= DMA_CH6
;
563 case 0x7: /* dma0 == 7 */
564 devpriv
->dma_bits
|= DMA_CH7
;
566 case 0x65: /* dma0 == 5, dma1 == 6 */
567 devpriv
->dma_bits
|= DMA_CH5_CH6
;
569 case 0x76: /* dma0 == 6, dma1 == 7 */
570 devpriv
->dma_bits
|= DMA_CH6_CH7
;
572 case 0x57: /* dma0 == 7, dma1 == 5 */
573 devpriv
->dma_bits
|= DMA_CH7_CH5
;
576 printk(" only supports dma channels 5 through 7\n"
577 " Dual dma only allows the following combinations:\n"
578 " dma 5,6 / 6,7 / or 7,5\n");
582 if (request_dma(dma0
, driver_das1800
.driver_name
)) {
583 printk(" failed to allocate dma channel %i\n", dma0
);
586 devpriv
->dma0
= dma0
;
587 devpriv
->dma_current
= dma0
;
589 if (request_dma(dma1
, driver_das1800
.driver_name
)) {
590 printk(" failed to allocate dma channel %i\n",
594 devpriv
->dma1
= dma1
;
596 devpriv
->ai_buf0
= kmalloc(DMA_BUF_SIZE
, GFP_KERNEL
| GFP_DMA
);
597 if (devpriv
->ai_buf0
== NULL
)
599 devpriv
->dma_current_buf
= devpriv
->ai_buf0
;
602 kmalloc(DMA_BUF_SIZE
, GFP_KERNEL
| GFP_DMA
);
603 if (devpriv
->ai_buf1
== NULL
)
606 flags
= claim_dma_lock();
607 disable_dma(devpriv
->dma0
);
608 set_dma_mode(devpriv
->dma0
, DMA_MODE_READ
);
610 disable_dma(devpriv
->dma1
);
611 set_dma_mode(devpriv
->dma1
, DMA_MODE_READ
);
613 release_dma_lock(flags
);
618 static int das1800_attach(struct comedi_device
*dev
,
619 struct comedi_devconfig
*it
)
621 struct comedi_subdevice
*s
;
622 unsigned long iobase
= it
->options
[0];
623 unsigned int irq
= it
->options
[1];
624 unsigned int dma0
= it
->options
[2];
625 unsigned int dma1
= it
->options
[3];
626 unsigned long iobase2
;
630 /* allocate and initialize dev->private */
631 if (alloc_private(dev
, sizeof(struct das1800_private
)) < 0)
634 printk("comedi%d: %s: io 0x%lx", dev
->minor
, driver_das1800
.driver_name
,
637 printk(", irq %u", irq
);
639 printk(", dma %u", dma0
);
641 printk(" and %u", dma1
);
647 printk(" io base address required\n");
651 /* check if io addresses are available */
652 if (!request_region(iobase
, DAS1800_SIZE
, driver_das1800
.driver_name
)) {
654 (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
655 iobase
, iobase
+ DAS1800_SIZE
- 1);
658 dev
->iobase
= iobase
;
660 board
= das1800_probe(dev
);
662 printk(" unable to determine board type\n");
666 dev
->board_ptr
= das1800_boards
+ board
;
667 dev
->board_name
= thisboard
->name
;
669 /* if it is an 'ao' board with fancy analog out then we need extra io ports */
670 if (thisboard
->ao_ability
== 2) {
671 iobase2
= iobase
+ IOBASE2
;
672 if (!request_region(iobase2
, DAS1800_SIZE
,
673 driver_das1800
.driver_name
)) {
675 (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
676 iobase2
, iobase2
+ DAS1800_SIZE
- 1);
679 devpriv
->iobase2
= iobase2
;
684 if (request_irq(irq
, das1800_interrupt
, 0,
685 driver_das1800
.driver_name
, dev
)) {
686 printk(" unable to allocate irq %u\n", irq
);
692 /* set bits that tell card which irq to use */
697 devpriv
->irq_dma_bits
|= 0x8;
700 devpriv
->irq_dma_bits
|= 0x10;
703 devpriv
->irq_dma_bits
|= 0x18;
706 devpriv
->irq_dma_bits
|= 0x28;
709 devpriv
->irq_dma_bits
|= 0x30;
712 devpriv
->irq_dma_bits
|= 0x38;
715 printk(" irq out of range\n");
720 retval
= das1800_init_dma(dev
, dma0
, dma1
);
724 if (devpriv
->ai_buf0
== NULL
) {
726 kmalloc(FIFO_SIZE
* sizeof(uint16_t), GFP_KERNEL
);
727 if (devpriv
->ai_buf0
== NULL
)
731 if (alloc_subdevices(dev
, 4) < 0)
734 /* analog input subdevice */
735 s
= dev
->subdevices
+ 0;
736 dev
->read_subdev
= s
;
737 s
->type
= COMEDI_SUBD_AI
;
738 s
->subdev_flags
= SDF_READABLE
| SDF_DIFF
| SDF_GROUND
| SDF_CMD_READ
;
739 if (thisboard
->common
)
740 s
->subdev_flags
|= SDF_COMMON
;
741 s
->n_chan
= thisboard
->qram_len
;
742 s
->len_chanlist
= thisboard
->qram_len
;
743 s
->maxdata
= (1 << thisboard
->resolution
) - 1;
744 s
->range_table
= thisboard
->range_ai
;
745 s
->do_cmd
= das1800_ai_do_cmd
;
746 s
->do_cmdtest
= das1800_ai_do_cmdtest
;
747 s
->insn_read
= das1800_ai_rinsn
;
748 s
->poll
= das1800_ai_poll
;
749 s
->cancel
= das1800_cancel
;
752 s
= dev
->subdevices
+ 1;
753 if (thisboard
->ao_ability
== 1) {
754 s
->type
= COMEDI_SUBD_AO
;
755 s
->subdev_flags
= SDF_WRITABLE
;
756 s
->n_chan
= thisboard
->ao_n_chan
;
757 s
->maxdata
= (1 << thisboard
->resolution
) - 1;
758 s
->range_table
= &range_ao_1
;
759 s
->insn_write
= das1800_ao_winsn
;
761 s
->type
= COMEDI_SUBD_UNUSED
;
765 s
= dev
->subdevices
+ 2;
766 s
->type
= COMEDI_SUBD_DI
;
767 s
->subdev_flags
= SDF_READABLE
;
770 s
->range_table
= &range_digital
;
771 s
->insn_bits
= das1800_di_rbits
;
774 s
= dev
->subdevices
+ 3;
775 s
->type
= COMEDI_SUBD_DO
;
776 s
->subdev_flags
= SDF_WRITABLE
| SDF_READABLE
;
777 s
->n_chan
= thisboard
->do_n_chan
;
779 s
->range_table
= &range_digital
;
780 s
->insn_bits
= das1800_do_wbits
;
782 das1800_cancel(dev
, dev
->read_subdev
);
784 /* initialize digital out channels */
785 outb(devpriv
->do_bits
, dev
->iobase
+ DAS1800_DIGITAL
);
787 /* initialize analog out channels */
788 if (thisboard
->ao_ability
== 1) {
789 /* select 'update' dac channel for baseAddress + 0x0 */
790 outb(DAC(thisboard
->ao_n_chan
- 1),
791 dev
->iobase
+ DAS1800_SELECT
);
792 outw(devpriv
->ao_update_bits
, dev
->iobase
+ DAS1800_DAC
);
798 static int das1800_detach(struct comedi_device
*dev
)
800 /* only free stuff if it has been allocated by _attach */
802 release_region(dev
->iobase
, DAS1800_SIZE
);
804 free_irq(dev
->irq
, dev
);
806 if (devpriv
->iobase2
)
807 release_region(devpriv
->iobase2
, DAS1800_SIZE
);
809 free_dma(devpriv
->dma0
);
811 free_dma(devpriv
->dma1
);
812 kfree(devpriv
->ai_buf0
);
813 kfree(devpriv
->ai_buf1
);
816 printk("comedi%d: %s: remove\n", dev
->minor
,
817 driver_das1800
.driver_name
);
822 /* probes and checks das-1800 series board type
824 static int das1800_probe(struct comedi_device
*dev
)
829 id
= (inb(dev
->iobase
+ DAS1800_DIGITAL
) >> 4) & 0xf; /* get id bits */
830 board
= ((struct das1800_board
*)dev
->board_ptr
) - das1800_boards
;
834 if (board
== das1801st_da
|| board
== das1802st_da
||
835 board
== das1701st_da
|| board
== das1702st_da
) {
836 printk(" Board model: %s\n",
837 das1800_boards
[board
].name
);
841 (" Board model (probed, not recommended): das-1800st-da series\n");
845 if (board
== das1802hr_da
|| board
== das1702hr_da
) {
846 printk(" Board model: %s\n",
847 das1800_boards
[board
].name
);
851 (" Board model (probed, not recommended): das-1802hr-da\n");
855 if (board
== das1801ao
|| board
== das1802ao
||
856 board
== das1701ao
|| board
== das1702ao
) {
857 printk(" Board model: %s\n",
858 das1800_boards
[board
].name
);
862 (" Board model (probed, not recommended): das-1800ao series\n");
866 if (board
== das1802hr
|| board
== das1702hr
) {
867 printk(" Board model: %s\n",
868 das1800_boards
[board
].name
);
871 printk(" Board model (probed, not recommended): das-1802hr\n");
875 if (board
== das1801st
|| board
== das1802st
||
876 board
== das1701st
|| board
== das1702st
) {
877 printk(" Board model: %s\n",
878 das1800_boards
[board
].name
);
882 (" Board model (probed, not recommended): das-1800st series\n");
886 if (board
== das1801hc
|| board
== das1802hc
) {
887 printk(" Board model: %s\n",
888 das1800_boards
[board
].name
);
892 (" Board model (probed, not recommended): das-1800hc series\n");
897 (" Board model: probe returned 0x%x (unknown, please report)\n",
905 static int das1800_ai_poll(struct comedi_device
*dev
,
906 struct comedi_subdevice
*s
)
910 /* prevent race with interrupt handler */
911 spin_lock_irqsave(&dev
->spinlock
, flags
);
912 das1800_ai_handler(dev
);
913 spin_unlock_irqrestore(&dev
->spinlock
, flags
);
915 return s
->async
->buf_write_count
- s
->async
->buf_read_count
;
918 static irqreturn_t
das1800_interrupt(int irq
, void *d
)
920 struct comedi_device
*dev
= d
;
923 if (dev
->attached
== 0) {
924 comedi_error(dev
, "premature interrupt");
928 /* Prevent race with das1800_ai_poll() on multi processor systems.
929 * Also protects indirect addressing in das1800_ai_handler */
930 spin_lock(&dev
->spinlock
);
931 status
= inb(dev
->iobase
+ DAS1800_STATUS
);
933 /* if interrupt was not caused by das-1800 */
934 if (!(status
& INT
)) {
935 spin_unlock(&dev
->spinlock
);
938 /* clear the interrupt status bit INT */
939 outb(CLEAR_INTR_MASK
& ~INT
, dev
->iobase
+ DAS1800_STATUS
);
940 /* handle interrupt */
941 das1800_ai_handler(dev
);
943 spin_unlock(&dev
->spinlock
);
947 /* the guts of the interrupt handler, that is shared with das1800_ai_poll */
948 static void das1800_ai_handler(struct comedi_device
*dev
)
950 struct comedi_subdevice
*s
= dev
->subdevices
+ 0; /* analog input subdevice */
951 struct comedi_async
*async
= s
->async
;
952 struct comedi_cmd
*cmd
= &async
->cmd
;
953 unsigned int status
= inb(dev
->iobase
+ DAS1800_STATUS
);
956 /* select adc for base address + 0 */
957 outb(ADC
, dev
->iobase
+ DAS1800_SELECT
);
958 /* dma buffer full */
959 if (devpriv
->irq_dma_bits
& DMA_ENABLED
) {
960 /* look for data from dma transfer even if dma terminal count hasn't happened yet */
961 das1800_handle_dma(dev
, s
, status
);
962 } else if (status
& FHF
) { /* if fifo half full */
963 das1800_handle_fifo_half_full(dev
, s
);
964 } else if (status
& FNE
) { /* if fifo not empty */
965 das1800_handle_fifo_not_empty(dev
, s
);
968 async
->events
|= COMEDI_CB_BLOCK
;
969 /* if the card's fifo has overflowed */
971 /* clear OVF interrupt bit */
972 outb(CLEAR_INTR_MASK
& ~OVF
, dev
->iobase
+ DAS1800_STATUS
);
973 comedi_error(dev
, "DAS1800 FIFO overflow");
974 das1800_cancel(dev
, s
);
975 async
->events
|= COMEDI_CB_ERROR
| COMEDI_CB_EOA
;
976 comedi_event(dev
, s
);
979 /* stop taking data if appropriate */
980 /* stop_src TRIG_EXT */
981 if (status
& CT0TC
) {
982 /* clear CT0TC interrupt bit */
983 outb(CLEAR_INTR_MASK
& ~CT0TC
, dev
->iobase
+ DAS1800_STATUS
);
984 /* make sure we get all remaining data from board before quitting */
985 if (devpriv
->irq_dma_bits
& DMA_ENABLED
)
986 das1800_flush_dma(dev
, s
);
988 das1800_handle_fifo_not_empty(dev
, s
);
989 das1800_cancel(dev
, s
); /* disable hardware conversions */
990 async
->events
|= COMEDI_CB_EOA
;
991 } else if (cmd
->stop_src
== TRIG_COUNT
&& devpriv
->count
== 0) { /* stop_src TRIG_COUNT */
992 das1800_cancel(dev
, s
); /* disable hardware conversions */
993 async
->events
|= COMEDI_CB_EOA
;
996 comedi_event(dev
, s
);
1001 static void das1800_handle_dma(struct comedi_device
*dev
,
1002 struct comedi_subdevice
*s
, unsigned int status
)
1004 unsigned long flags
;
1005 const int dual_dma
= devpriv
->irq_dma_bits
& DMA_DUAL
;
1007 flags
= claim_dma_lock();
1008 das1800_flush_dma_channel(dev
, s
, devpriv
->dma_current
,
1009 devpriv
->dma_current_buf
);
1010 /* re-enable dma channel */
1011 set_dma_addr(devpriv
->dma_current
,
1012 virt_to_bus(devpriv
->dma_current_buf
));
1013 set_dma_count(devpriv
->dma_current
, devpriv
->dma_transfer_size
);
1014 enable_dma(devpriv
->dma_current
);
1015 release_dma_lock(flags
);
1017 if (status
& DMATC
) {
1018 /* clear DMATC interrupt bit */
1019 outb(CLEAR_INTR_MASK
& ~DMATC
, dev
->iobase
+ DAS1800_STATUS
);
1020 /* switch dma channels for next time, if appropriate */
1022 /* read data from the other channel next time */
1023 if (devpriv
->dma_current
== devpriv
->dma0
) {
1024 devpriv
->dma_current
= devpriv
->dma1
;
1025 devpriv
->dma_current_buf
= devpriv
->ai_buf1
;
1027 devpriv
->dma_current
= devpriv
->dma0
;
1028 devpriv
->dma_current_buf
= devpriv
->ai_buf0
;
1036 static inline uint16_t munge_bipolar_sample(const struct comedi_device
*dev
,
1039 sample
+= 1 << (thisboard
->resolution
- 1);
1043 static void munge_data(struct comedi_device
*dev
, uint16_t * array
,
1044 unsigned int num_elements
)
1049 /* see if card is using a unipolar or bipolar range so we can munge data correctly */
1050 unipolar
= inb(dev
->iobase
+ DAS1800_CONTROL_C
) & UB
;
1052 /* convert to unsigned type if we are in a bipolar mode */
1054 for (i
= 0; i
< num_elements
; i
++) {
1055 array
[i
] = munge_bipolar_sample(dev
, array
[i
]);
1060 /* Utility function used by das1800_flush_dma() and das1800_handle_dma().
1061 * Assumes dma lock is held */
1062 static void das1800_flush_dma_channel(struct comedi_device
*dev
,
1063 struct comedi_subdevice
*s
,
1064 unsigned int channel
, uint16_t * buffer
)
1066 unsigned int num_bytes
, num_samples
;
1067 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
1069 disable_dma(channel
);
1071 /* clear flip-flop to make sure 2-byte registers
1072 * get set correctly */
1073 clear_dma_ff(channel
);
1075 /* figure out how many points to read */
1076 num_bytes
= devpriv
->dma_transfer_size
- get_dma_residue(channel
);
1077 num_samples
= num_bytes
/ sizeof(short);
1079 /* if we only need some of the points */
1080 if (cmd
->stop_src
== TRIG_COUNT
&& devpriv
->count
< num_samples
)
1081 num_samples
= devpriv
->count
;
1083 munge_data(dev
, buffer
, num_samples
);
1084 cfc_write_array_to_buffer(s
, buffer
, num_bytes
);
1085 if (s
->async
->cmd
.stop_src
== TRIG_COUNT
)
1086 devpriv
->count
-= num_samples
;
1091 /* flushes remaining data from board when external trigger has stopped acquisition
1092 * and we are using dma transfers */
1093 static void das1800_flush_dma(struct comedi_device
*dev
,
1094 struct comedi_subdevice
*s
)
1096 unsigned long flags
;
1097 const int dual_dma
= devpriv
->irq_dma_bits
& DMA_DUAL
;
1099 flags
= claim_dma_lock();
1100 das1800_flush_dma_channel(dev
, s
, devpriv
->dma_current
,
1101 devpriv
->dma_current_buf
);
1104 /* switch to other channel and flush it */
1105 if (devpriv
->dma_current
== devpriv
->dma0
) {
1106 devpriv
->dma_current
= devpriv
->dma1
;
1107 devpriv
->dma_current_buf
= devpriv
->ai_buf1
;
1109 devpriv
->dma_current
= devpriv
->dma0
;
1110 devpriv
->dma_current_buf
= devpriv
->ai_buf0
;
1112 das1800_flush_dma_channel(dev
, s
, devpriv
->dma_current
,
1113 devpriv
->dma_current_buf
);
1116 release_dma_lock(flags
);
1118 /* get any remaining samples in fifo */
1119 das1800_handle_fifo_not_empty(dev
, s
);
1124 static void das1800_handle_fifo_half_full(struct comedi_device
*dev
,
1125 struct comedi_subdevice
*s
)
1127 int numPoints
= 0; /* number of points to read */
1128 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
1130 numPoints
= FIFO_SIZE
/ 2;
1131 /* if we only need some of the points */
1132 if (cmd
->stop_src
== TRIG_COUNT
&& devpriv
->count
< numPoints
)
1133 numPoints
= devpriv
->count
;
1134 insw(dev
->iobase
+ DAS1800_FIFO
, devpriv
->ai_buf0
, numPoints
);
1135 munge_data(dev
, devpriv
->ai_buf0
, numPoints
);
1136 cfc_write_array_to_buffer(s
, devpriv
->ai_buf0
,
1137 numPoints
* sizeof(devpriv
->ai_buf0
[0]));
1138 if (cmd
->stop_src
== TRIG_COUNT
)
1139 devpriv
->count
-= numPoints
;
1143 static void das1800_handle_fifo_not_empty(struct comedi_device
*dev
,
1144 struct comedi_subdevice
*s
)
1148 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
1150 unipolar
= inb(dev
->iobase
+ DAS1800_CONTROL_C
) & UB
;
1152 while (inb(dev
->iobase
+ DAS1800_STATUS
) & FNE
) {
1153 if (cmd
->stop_src
== TRIG_COUNT
&& devpriv
->count
== 0)
1155 dpnt
= inw(dev
->iobase
+ DAS1800_FIFO
);
1156 /* convert to unsigned type if we are in a bipolar mode */
1158 dpnt
= munge_bipolar_sample(dev
, dpnt
);
1159 cfc_write_to_buffer(s
, dpnt
);
1160 if (cmd
->stop_src
== TRIG_COUNT
)
1167 static int das1800_cancel(struct comedi_device
*dev
, struct comedi_subdevice
*s
)
1169 outb(0x0, dev
->iobase
+ DAS1800_STATUS
); /* disable conversions */
1170 outb(0x0, dev
->iobase
+ DAS1800_CONTROL_B
); /* disable interrupts and dma */
1171 outb(0x0, dev
->iobase
+ DAS1800_CONTROL_A
); /* disable and clear fifo and stop triggering */
1173 disable_dma(devpriv
->dma0
);
1175 disable_dma(devpriv
->dma1
);
1179 /* test analog input cmd */
1180 static int das1800_ai_do_cmdtest(struct comedi_device
*dev
,
1181 struct comedi_subdevice
*s
,
1182 struct comedi_cmd
*cmd
)
1186 unsigned int tmp_arg
;
1190 /* step 1: make sure trigger sources are trivially valid */
1192 tmp
= cmd
->start_src
;
1193 cmd
->start_src
&= TRIG_NOW
| TRIG_EXT
;
1194 if (!cmd
->start_src
|| tmp
!= cmd
->start_src
)
1197 tmp
= cmd
->scan_begin_src
;
1198 cmd
->scan_begin_src
&= TRIG_FOLLOW
| TRIG_TIMER
| TRIG_EXT
;
1199 if (!cmd
->scan_begin_src
|| tmp
!= cmd
->scan_begin_src
)
1202 tmp
= cmd
->convert_src
;
1203 cmd
->convert_src
&= TRIG_TIMER
| TRIG_EXT
;
1204 if (!cmd
->convert_src
|| tmp
!= cmd
->convert_src
)
1207 tmp
= cmd
->scan_end_src
;
1208 cmd
->scan_end_src
&= TRIG_COUNT
;
1209 if (!cmd
->scan_end_src
|| tmp
!= cmd
->scan_end_src
)
1212 tmp
= cmd
->stop_src
;
1213 cmd
->stop_src
&= TRIG_COUNT
| TRIG_EXT
| TRIG_NONE
;
1214 if (!cmd
->stop_src
|| tmp
!= cmd
->stop_src
)
1220 /* step 2: make sure trigger sources are unique and mutually compatible */
1222 /* uniqueness check */
1223 if (cmd
->start_src
!= TRIG_NOW
&& cmd
->start_src
!= TRIG_EXT
)
1225 if (cmd
->scan_begin_src
!= TRIG_FOLLOW
&&
1226 cmd
->scan_begin_src
!= TRIG_TIMER
&&
1227 cmd
->scan_begin_src
!= TRIG_EXT
)
1229 if (cmd
->convert_src
!= TRIG_TIMER
&& cmd
->convert_src
!= TRIG_EXT
)
1231 if (cmd
->stop_src
!= TRIG_COUNT
&&
1232 cmd
->stop_src
!= TRIG_NONE
&& cmd
->stop_src
!= TRIG_EXT
)
1234 /* compatibility check */
1235 if (cmd
->scan_begin_src
!= TRIG_FOLLOW
&&
1236 cmd
->convert_src
!= TRIG_TIMER
)
1242 /* step 3: make sure arguments are trivially compatible */
1244 if (cmd
->start_arg
!= 0) {
1248 if (cmd
->convert_src
== TRIG_TIMER
) {
1249 if (cmd
->convert_arg
< thisboard
->ai_speed
) {
1250 cmd
->convert_arg
= thisboard
->ai_speed
;
1254 if (!cmd
->chanlist_len
) {
1255 cmd
->chanlist_len
= 1;
1258 if (cmd
->scan_end_arg
!= cmd
->chanlist_len
) {
1259 cmd
->scan_end_arg
= cmd
->chanlist_len
;
1263 switch (cmd
->stop_src
) {
1265 if (!cmd
->stop_arg
) {
1271 if (cmd
->stop_arg
!= 0) {
1283 /* step 4: fix up any arguments */
1285 if (cmd
->convert_src
== TRIG_TIMER
) {
1286 /* if we are not in burst mode */
1287 if (cmd
->scan_begin_src
== TRIG_FOLLOW
) {
1288 tmp_arg
= cmd
->convert_arg
;
1289 /* calculate counter values that give desired timing */
1290 i8253_cascade_ns_to_timer_2div(TIMER_BASE
,
1291 &(devpriv
->divisor1
),
1292 &(devpriv
->divisor2
),
1293 &(cmd
->convert_arg
),
1295 flags
& TRIG_ROUND_MASK
);
1296 if (tmp_arg
!= cmd
->convert_arg
)
1299 /* if we are in burst mode */
1301 /* check that convert_arg is compatible */
1302 tmp_arg
= cmd
->convert_arg
;
1304 burst_convert_arg(cmd
->convert_arg
,
1305 cmd
->flags
& TRIG_ROUND_MASK
);
1306 if (tmp_arg
!= cmd
->convert_arg
)
1309 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
1310 /* if scans are timed faster than conversion rate allows */
1311 if (cmd
->convert_arg
* cmd
->chanlist_len
>
1312 cmd
->scan_begin_arg
) {
1313 cmd
->scan_begin_arg
=
1318 tmp_arg
= cmd
->scan_begin_arg
;
1319 /* calculate counter values that give desired timing */
1320 i8253_cascade_ns_to_timer_2div(TIMER_BASE
,
1330 if (tmp_arg
!= cmd
->scan_begin_arg
)
1339 /* make sure user is not trying to mix unipolar and bipolar ranges */
1340 if (cmd
->chanlist
) {
1341 unipolar
= CR_RANGE(cmd
->chanlist
[0]) & UNIPOLAR
;
1342 for (i
= 1; i
< cmd
->chanlist_len
; i
++) {
1343 if (unipolar
!= (CR_RANGE(cmd
->chanlist
[i
]) & UNIPOLAR
)) {
1345 "unipolar and bipolar ranges cannot be mixed in the chanlist");
1358 /* analog input cmd interface */
1360 /* first, some utility functions used in the main ai_do_cmd() */
1362 /* returns appropriate bits for control register a, depending on command */
1363 static int control_a_bits(struct comedi_cmd cmd
)
1367 control_a
= FFEN
; /* enable fifo */
1368 if (cmd
.stop_src
== TRIG_EXT
) {
1371 switch (cmd
.start_src
) {
1373 control_a
|= TGEN
| CGSL
;
1385 /* returns appropriate bits for control register c, depending on command */
1386 static int control_c_bits(struct comedi_cmd cmd
)
1391 /* set clock source to internal or external, select analog reference,
1392 * select unipolar / bipolar
1394 aref
= CR_AREF(cmd
.chanlist
[0]);
1395 control_c
= UQEN
; /* enable upper qram addresses */
1396 if (aref
!= AREF_DIFF
)
1398 if (aref
== AREF_COMMON
)
1400 /* if a unipolar range was selected */
1401 if (CR_RANGE(cmd
.chanlist
[0]) & UNIPOLAR
)
1403 switch (cmd
.scan_begin_src
) {
1404 case TRIG_FOLLOW
: /* not in burst mode */
1405 switch (cmd
.convert_src
) {
1407 /* trig on cascaded counters */
1411 /* trig on falling edge of external trigger */
1419 /* burst mode with internal pacer clock */
1420 control_c
|= BMDE
| IPCLK
;
1423 /* burst mode with external trigger */
1424 control_c
|= BMDE
| XPCLK
;
1433 /* sets up counters */
1434 static int setup_counters(struct comedi_device
*dev
, struct comedi_cmd cmd
)
1436 /* setup cascaded counters for conversion/scan frequency */
1437 switch (cmd
.scan_begin_src
) {
1438 case TRIG_FOLLOW
: /* not in burst mode */
1439 if (cmd
.convert_src
== TRIG_TIMER
) {
1440 /* set conversion frequency */
1441 i8253_cascade_ns_to_timer_2div(TIMER_BASE
,
1442 &(devpriv
->divisor1
),
1443 &(devpriv
->divisor2
),
1446 flags
& TRIG_ROUND_MASK
);
1447 if (das1800_set_frequency(dev
) < 0) {
1452 case TRIG_TIMER
: /* in burst mode */
1453 /* set scan frequency */
1454 i8253_cascade_ns_to_timer_2div(TIMER_BASE
, &(devpriv
->divisor1
),
1455 &(devpriv
->divisor2
),
1456 &(cmd
.scan_begin_arg
),
1457 cmd
.flags
& TRIG_ROUND_MASK
);
1458 if (das1800_set_frequency(dev
) < 0) {
1466 /* setup counter 0 for 'about triggering' */
1467 if (cmd
.stop_src
== TRIG_EXT
) {
1468 /* load counter 0 in mode 0 */
1469 i8254_load(dev
->iobase
+ DAS1800_COUNTER
, 0, 0, 1, 0);
1476 static void setup_dma(struct comedi_device
*dev
, struct comedi_cmd cmd
)
1478 unsigned long lock_flags
;
1479 const int dual_dma
= devpriv
->irq_dma_bits
& DMA_DUAL
;
1481 if ((devpriv
->irq_dma_bits
& DMA_ENABLED
) == 0)
1484 /* determine a reasonable dma transfer size */
1485 devpriv
->dma_transfer_size
= suggest_transfer_size(&cmd
);
1486 lock_flags
= claim_dma_lock();
1487 disable_dma(devpriv
->dma0
);
1488 /* clear flip-flop to make sure 2-byte registers for
1489 * count and address get set correctly */
1490 clear_dma_ff(devpriv
->dma0
);
1491 set_dma_addr(devpriv
->dma0
, virt_to_bus(devpriv
->ai_buf0
));
1492 /* set appropriate size of transfer */
1493 set_dma_count(devpriv
->dma0
, devpriv
->dma_transfer_size
);
1494 devpriv
->dma_current
= devpriv
->dma0
;
1495 devpriv
->dma_current_buf
= devpriv
->ai_buf0
;
1496 enable_dma(devpriv
->dma0
);
1497 /* set up dual dma if appropriate */
1499 disable_dma(devpriv
->dma1
);
1500 /* clear flip-flop to make sure 2-byte registers for
1501 * count and address get set correctly */
1502 clear_dma_ff(devpriv
->dma1
);
1503 set_dma_addr(devpriv
->dma1
, virt_to_bus(devpriv
->ai_buf1
));
1504 /* set appropriate size of transfer */
1505 set_dma_count(devpriv
->dma1
, devpriv
->dma_transfer_size
);
1506 enable_dma(devpriv
->dma1
);
1508 release_dma_lock(lock_flags
);
1513 /* programs channel/gain list into card */
1514 static void program_chanlist(struct comedi_device
*dev
, struct comedi_cmd cmd
)
1516 int i
, n
, chan_range
;
1517 unsigned long irq_flags
;
1518 const int range_mask
= 0x3; /* masks unipolar/bipolar bit off range */
1519 const int range_bitshift
= 8;
1521 n
= cmd
.chanlist_len
;
1522 /* spinlock protects indirect addressing */
1523 spin_lock_irqsave(&dev
->spinlock
, irq_flags
);
1524 outb(QRAM
, dev
->iobase
+ DAS1800_SELECT
); /* select QRAM for baseAddress + 0x0 */
1525 outb(n
- 1, dev
->iobase
+ DAS1800_QRAM_ADDRESS
); /*set QRAM address start */
1526 /* make channel / gain list */
1527 for (i
= 0; i
< n
; i
++) {
1530 chanlist
[i
]) | ((CR_RANGE(cmd
.chanlist
[i
]) &
1531 range_mask
) << range_bitshift
);
1532 outw(chan_range
, dev
->iobase
+ DAS1800_QRAM
);
1534 outb(n
- 1, dev
->iobase
+ DAS1800_QRAM_ADDRESS
); /*finish write to QRAM */
1535 spin_unlock_irqrestore(&dev
->spinlock
, irq_flags
);
1540 /* analog input do_cmd */
1541 static int das1800_ai_do_cmd(struct comedi_device
*dev
,
1542 struct comedi_subdevice
*s
)
1545 int control_a
, control_c
;
1546 struct comedi_async
*async
= s
->async
;
1547 struct comedi_cmd cmd
= async
->cmd
;
1551 "no irq assigned for das-1800, cannot do hardware conversions");
1555 /* disable dma on TRIG_WAKE_EOS, or TRIG_RT
1556 * (because dma in handler is unsafe at hard real-time priority) */
1557 if (cmd
.flags
& (TRIG_WAKE_EOS
| TRIG_RT
)) {
1558 devpriv
->irq_dma_bits
&= ~DMA_ENABLED
;
1560 devpriv
->irq_dma_bits
|= devpriv
->dma_bits
;
1562 /* interrupt on end of conversion for TRIG_WAKE_EOS */
1563 if (cmd
.flags
& TRIG_WAKE_EOS
) {
1564 /* interrupt fifo not empty */
1565 devpriv
->irq_dma_bits
&= ~FIMD
;
1567 /* interrupt fifo half full */
1568 devpriv
->irq_dma_bits
|= FIMD
;
1570 /* determine how many conversions we need */
1571 if (cmd
.stop_src
== TRIG_COUNT
) {
1572 devpriv
->count
= cmd
.stop_arg
* cmd
.chanlist_len
;
1575 das1800_cancel(dev
, s
);
1577 /* determine proper bits for control registers */
1578 control_a
= control_a_bits(cmd
);
1579 control_c
= control_c_bits(cmd
);
1581 /* setup card and start */
1582 program_chanlist(dev
, cmd
);
1583 ret
= setup_counters(dev
, cmd
);
1585 comedi_error(dev
, "Error setting up counters");
1588 setup_dma(dev
, cmd
);
1589 outb(control_c
, dev
->iobase
+ DAS1800_CONTROL_C
);
1590 /* set conversion rate and length for burst mode */
1591 if (control_c
& BMDE
) {
1592 /* program conversion period with number of microseconds minus 1 */
1593 outb(cmd
.convert_arg
/ 1000 - 1,
1594 dev
->iobase
+ DAS1800_BURST_RATE
);
1595 outb(cmd
.chanlist_len
- 1, dev
->iobase
+ DAS1800_BURST_LENGTH
);
1597 outb(devpriv
->irq_dma_bits
, dev
->iobase
+ DAS1800_CONTROL_B
); /* enable irq/dma */
1598 outb(control_a
, dev
->iobase
+ DAS1800_CONTROL_A
); /* enable fifo and triggering */
1599 outb(CVEN
, dev
->iobase
+ DAS1800_STATUS
); /* enable conversions */
1604 /* read analog input */
1605 static int das1800_ai_rinsn(struct comedi_device
*dev
,
1606 struct comedi_subdevice
*s
,
1607 struct comedi_insn
*insn
, unsigned int *data
)
1610 int chan
, range
, aref
, chan_range
;
1614 unsigned long irq_flags
;
1616 /* set up analog reference and unipolar / bipolar mode */
1617 aref
= CR_AREF(insn
->chanspec
);
1619 if (aref
!= AREF_DIFF
)
1621 if (aref
== AREF_COMMON
)
1623 /* if a unipolar range was selected */
1624 if (CR_RANGE(insn
->chanspec
) & UNIPOLAR
)
1627 outb(conv_flags
, dev
->iobase
+ DAS1800_CONTROL_C
); /* software conversion enabled */
1628 outb(CVEN
, dev
->iobase
+ DAS1800_STATUS
); /* enable conversions */
1629 outb(0x0, dev
->iobase
+ DAS1800_CONTROL_A
); /* reset fifo */
1630 outb(FFEN
, dev
->iobase
+ DAS1800_CONTROL_A
);
1632 chan
= CR_CHAN(insn
->chanspec
);
1633 /* mask of unipolar/bipolar bit from range */
1634 range
= CR_RANGE(insn
->chanspec
) & 0x3;
1635 chan_range
= chan
| (range
<< 8);
1636 spin_lock_irqsave(&dev
->spinlock
, irq_flags
);
1637 outb(QRAM
, dev
->iobase
+ DAS1800_SELECT
); /* select QRAM for baseAddress + 0x0 */
1638 outb(0x0, dev
->iobase
+ DAS1800_QRAM_ADDRESS
); /* set QRAM address start */
1639 outw(chan_range
, dev
->iobase
+ DAS1800_QRAM
);
1640 outb(0x0, dev
->iobase
+ DAS1800_QRAM_ADDRESS
); /*finish write to QRAM */
1641 outb(ADC
, dev
->iobase
+ DAS1800_SELECT
); /* select ADC for baseAddress + 0x0 */
1643 for (n
= 0; n
< insn
->n
; n
++) {
1644 /* trigger conversion */
1645 outb(0, dev
->iobase
+ DAS1800_FIFO
);
1646 for (i
= 0; i
< timeout
; i
++) {
1647 if (inb(dev
->iobase
+ DAS1800_STATUS
) & FNE
)
1651 comedi_error(dev
, "timeout");
1655 dpnt
= inw(dev
->iobase
+ DAS1800_FIFO
);
1656 /* shift data to offset binary for bipolar ranges */
1657 if ((conv_flags
& UB
) == 0)
1658 dpnt
+= 1 << (thisboard
->resolution
- 1);
1662 spin_unlock_irqrestore(&dev
->spinlock
, irq_flags
);
1667 /* writes to an analog output channel */
1668 static int das1800_ao_winsn(struct comedi_device
*dev
,
1669 struct comedi_subdevice
*s
,
1670 struct comedi_insn
*insn
, unsigned int *data
)
1672 int chan
= CR_CHAN(insn
->chanspec
);
1673 /* int range = CR_RANGE(insn->chanspec); */
1674 int update_chan
= thisboard
->ao_n_chan
- 1;
1676 unsigned long irq_flags
;
1678 /* card expects two's complement data */
1679 output
= data
[0] - (1 << (thisboard
->resolution
- 1));
1680 /* if the write is to the 'update' channel, we need to remember its value */
1681 if (chan
== update_chan
)
1682 devpriv
->ao_update_bits
= output
;
1683 /* write to channel */
1684 spin_lock_irqsave(&dev
->spinlock
, irq_flags
);
1685 outb(DAC(chan
), dev
->iobase
+ DAS1800_SELECT
); /* select dac channel for baseAddress + 0x0 */
1686 outw(output
, dev
->iobase
+ DAS1800_DAC
);
1687 /* now we need to write to 'update' channel to update all dac channels */
1688 if (chan
!= update_chan
) {
1689 outb(DAC(update_chan
), dev
->iobase
+ DAS1800_SELECT
); /* select 'update' channel for baseAddress + 0x0 */
1690 outw(devpriv
->ao_update_bits
, dev
->iobase
+ DAS1800_DAC
);
1692 spin_unlock_irqrestore(&dev
->spinlock
, irq_flags
);
1697 /* reads from digital input channels */
1698 static int das1800_di_rbits(struct comedi_device
*dev
,
1699 struct comedi_subdevice
*s
,
1700 struct comedi_insn
*insn
, unsigned int *data
)
1703 data
[1] = inb(dev
->iobase
+ DAS1800_DIGITAL
) & 0xf;
1709 /* writes to digital output channels */
1710 static int das1800_do_wbits(struct comedi_device
*dev
,
1711 struct comedi_subdevice
*s
,
1712 struct comedi_insn
*insn
, unsigned int *data
)
1716 /* only set bits that have been masked */
1717 data
[0] &= (1 << s
->n_chan
) - 1;
1718 wbits
= devpriv
->do_bits
;
1720 wbits
|= data
[0] & data
[1];
1721 devpriv
->do_bits
= wbits
;
1723 outb(devpriv
->do_bits
, dev
->iobase
+ DAS1800_DIGITAL
);
1725 data
[1] = devpriv
->do_bits
;
1730 /* loads counters with divisor1, divisor2 from private structure */
1731 static int das1800_set_frequency(struct comedi_device
*dev
)
1735 /* counter 1, mode 2 */
1736 if (i8254_load(dev
->iobase
+ DAS1800_COUNTER
, 0, 1, devpriv
->divisor1
,
1739 /* counter 2, mode 2 */
1740 if (i8254_load(dev
->iobase
+ DAS1800_COUNTER
, 0, 2, devpriv
->divisor2
,
1749 /* converts requested conversion timing to timing compatible with
1750 * hardware, used only when card is in 'burst mode'
1752 static unsigned int burst_convert_arg(unsigned int convert_arg
, int round_mode
)
1754 unsigned int micro_sec
;
1756 /* in burst mode, the maximum conversion time is 64 microseconds */
1757 if (convert_arg
> 64000)
1758 convert_arg
= 64000;
1760 /* the conversion time must be an integral number of microseconds */
1761 switch (round_mode
) {
1762 case TRIG_ROUND_NEAREST
:
1764 micro_sec
= (convert_arg
+ 500) / 1000;
1766 case TRIG_ROUND_DOWN
:
1767 micro_sec
= convert_arg
/ 1000;
1770 micro_sec
= (convert_arg
- 1) / 1000 + 1;
1774 /* return number of nanoseconds */
1775 return micro_sec
* 1000;
1778 /* utility function that suggests a dma transfer size based on the conversion period 'ns' */
1779 static unsigned int suggest_transfer_size(struct comedi_cmd
*cmd
)
1781 unsigned int size
= DMA_BUF_SIZE
;
1782 static const int sample_size
= 2; /* size in bytes of one sample from board */
1783 unsigned int fill_time
= 300000000; /* target time in nanoseconds for filling dma buffer */
1784 unsigned int max_size
; /* maximum size we will allow for a transfer */
1786 /* make dma buffer fill in 0.3 seconds for timed modes */
1787 switch (cmd
->scan_begin_src
) {
1788 case TRIG_FOLLOW
: /* not in burst mode */
1789 if (cmd
->convert_src
== TRIG_TIMER
)
1790 size
= (fill_time
/ cmd
->convert_arg
) * sample_size
;
1793 size
= (fill_time
/ (cmd
->scan_begin_arg
* cmd
->chanlist_len
)) *
1797 size
= DMA_BUF_SIZE
;
1801 /* set a minimum and maximum size allowed */
1802 max_size
= DMA_BUF_SIZE
;
1803 /* if we are taking limited number of conversions, limit transfer size to that */
1804 if (cmd
->stop_src
== TRIG_COUNT
&&
1805 cmd
->stop_arg
* cmd
->chanlist_len
* sample_size
< max_size
)
1806 max_size
= cmd
->stop_arg
* cmd
->chanlist_len
* sample_size
;
1808 if (size
> max_size
)
1810 if (size
< sample_size
)
1816 MODULE_AUTHOR("Comedi http://www.comedi.org");
1817 MODULE_DESCRIPTION("Comedi low-level driver");
1818 MODULE_LICENSE("GPL");