59 #include "../comedidev.h"
70 #define DT2821_TIMEOUT 100
71 #define DT2821_SIZE 0x10
77 #define DT2821_ADCSR 0x00
78 #define DT2821_CHANCSR 0x02
79 #define DT2821_ADDAT 0x04
80 #define DT2821_DACSR 0x06
81 #define DT2821_DADAT 0x08
82 #define DT2821_DIODAT 0x0a
83 #define DT2821_SUPCSR 0x0c
84 #define DT2821_TMRCTR 0x0e
91 #define DT2821_ADCSR_MASK 0xfff0
92 #define DT2821_ADCSR_VAL 0x7c00
94 #define DT2821_CHANCSR_MASK 0xf0f0
95 #define DT2821_CHANCSR_VAL 0x70f0
97 #define DT2821_DACSR_MASK 0x7c93
98 #define DT2821_DACSR_VAL 0x7c90
100 #define DT2821_SUPCSR_MASK 0xf8ff
101 #define DT2821_SUPCSR_VAL 0x0000
103 #define DT2821_TMRCTR_MASK 0xff00
104 #define DT2821_TMRCTR_VAL 0xf000
112 #define DT2821_ADERR 0x8000
113 #define DT2821_ADCLK 0x0200
115 #define DT2821_MUXBUSY 0x0100
116 #define DT2821_ADDONE 0x0080
117 #define DT2821_IADDONE 0x0040
123 #define DT2821_LLE 0x8000
131 #define DT2821_DAERR 0x8000
132 #define DT2821_YSEL 0x0200
133 #define DT2821_SSEL 0x0100
134 #define DT2821_DACRDY 0x0080
135 #define DT2821_IDARDY 0x0040
136 #define DT2821_DACLK 0x0020
137 #define DT2821_HBOE 0x0002
138 #define DT2821_LBOE 0x0001
142 #define DT2821_DMAD 0x8000
143 #define DT2821_ERRINTEN 0x4000
144 #define DT2821_CLRDMADNE 0x2000
145 #define DT2821_DDMA 0x1000
146 #define DT2821_DS1 0x0800
147 #define DT2821_DS0 0x0400
148 #define DT2821_BUFFB 0x0200
149 #define DT2821_SCDN 0x0100
150 #define DT2821_DACON 0x0080
151 #define DT2821_ADCINIT 0x0040
152 #define DT2821_DACINIT 0x0020
153 #define DT2821_PRLD 0x0010
154 #define DT2821_STRIG 0x0008
155 #define DT2821_XTRIG 0x0004
156 #define DT2821_XCLK 0x0002
157 #define DT2821_BDINIT 0x0001
159 static const struct comedi_lrange range_dt282x_ai_lo_bipolar = {
168 static const struct comedi_lrange range_dt282x_ai_lo_unipolar = {
177 static const struct comedi_lrange range_dt282x_ai_5_bipolar = {
186 static const struct comedi_lrange range_dt282x_ai_5_unipolar = {
195 static const struct comedi_lrange range_dt282x_ai_hi_bipolar = {
204 static const struct comedi_lrange range_dt282x_ai_hi_unipolar = {
251 #define devpriv ((struct dt282x_private *)dev->private)
252 #define boardtype (*(const struct dt282x_board *)dev->board_ptr)
257 #define chan_to_DAC(a) ((a)&1)
258 #define mux_busy() (inw(dev->iobase+DT2821_ADCSR)&DT2821_MUXBUSY)
259 #define ad_done() (inw(dev->iobase+DT2821_ADCSR)&DT2821_ADDONE)
265 #define wait_for(a, b) \
268 for (_i = 0; _i < DT2821_TIMEOUT; _i++) { \
285 static int dt282x_ns_to_timer(
int *nanosec,
int round_mode);
304 comedi_error(dev,
"bug! odd number of bytes from dma xfer");
306 for (i = 0; i <
n; i++)
307 buf[i] = (buf[i] & mask) ^
sign;
310 static void dt282x_ao_dma_interrupt(
struct comedi_device *dev)
319 if (!s->
async->prealloc_buf) {
324 i =
devpriv->current_dma_index;
334 dt282x_ao_cancel(dev, s);
338 prep_ao_dma(dev, i, size);
342 static void dt282x_ai_dma_interrupt(
struct comedi_device *dev)
352 if (!s->
async->prealloc_buf) {
357 i =
devpriv->current_dma_index;
365 dt282x_munge(dev, ptr, size);
368 dt282x_ai_cancel(dev, s);
378 dt282x_ai_cancel(dev, s);
391 prep_ai_dma(dev, i, 0);
394 static int prep_ai_dma(
struct comedi_device *dev,
int dma_index,
int n)
397 unsigned long dma_ptr;
410 dma_chan =
devpriv->dma[dma_index].chan;
415 clear_dma_ff(dma_chan);
416 set_dma_addr(dma_chan, dma_ptr);
425 static int prep_ao_dma(
struct comedi_device *dev,
int dma_index,
int n)
428 unsigned long dma_ptr;
432 dma_chan =
devpriv->dma[dma_index].chan;
437 clear_dma_ff(dma_chan);
438 set_dma_addr(dma_chan, dma_ptr);
452 unsigned int supcsr, adcsr, dacsr;
467 dt282x_ai_dma_interrupt(dev);
469 dt282x_ao_dma_interrupt(dev);
475 dt282x_ai_cancel(dev, s);
489 dt282x_ao_cancel(dev, s_ao);
525 static void dt282x_load_changain(
struct comedi_device *dev,
int n,
532 for (i = 0; i <
n; i++) {
557 dt282x_load_changain(dev, 1, &insn->
chanspec);
562 for (i = 0; i < insn->
n; i++) {
600 err |= cfc_check_trigger_is_unique(cmd->
stop_src);
632 #define SLOWEST_TIMER (250*(1<<15)*255)
679 "driver requires 2 dma channels"
680 " to execute command");
684 dt282x_disable_dma(dev);
705 devpriv->current_dma_index = 0;
706 prep_ai_dma(dev, 0, 0);
708 prep_ai_dma(dev, 1, 0);
745 dt282x_disable_dma(dev);
756 static int dt282x_ns_to_timer(
int *nanosec,
int round_mode)
760 for (prescale = 0; prescale < 16; prescale++) {
764 switch (round_mode) {
767 divider = (*nanosec + base / 2) / base;
770 divider = (*nanosec) / base;
773 divider = (*nanosec + base - 1) / base;
777 *nanosec = divider * base;
778 return (prescale << 8) | (255 - divider);
781 base = 250 * (1 << 15);
783 *nanosec = divider * base;
784 return (15 << 8) | (255 - divider);
855 err |= cfc_check_trigger_is_unique(cmd->
stop_src);
922 prep_ao_dma(dev, 0, size);
930 prep_ao_dma(dev, 1, size);
945 "driver requires 2 dma channels"
946 " to execute command");
950 dt282x_disable_dma(dev);
960 devpriv->current_dma_index = 0;
968 s->
async->inttrig = dt282x_ao_inttrig;
976 dt282x_disable_dma(dev);
992 s->
state &= ~data[0];
993 s->
state |= (data[0] & data[1]);
1002 static int dt282x_dio_insn_config(
struct comedi_device *dev,
1028 static const struct comedi_lrange *
const ai_range_table[] = {
1029 &range_dt282x_ai_lo_bipolar,
1030 &range_dt282x_ai_lo_unipolar,
1031 &range_dt282x_ai_5_bipolar,
1032 &range_dt282x_ai_5_unipolar
1035 static const struct comedi_lrange *
const ai_range_pgl_table[] = {
1036 &range_dt282x_ai_hi_bipolar,
1037 &range_dt282x_ai_hi_unipolar
1040 static const struct comedi_lrange *opt_ai_range_lkup(
int ispgl,
int x)
1043 if (x < 0 || x >= 2)
1045 return ai_range_pgl_table[
x];
1047 if (x < 0 || x >= 4)
1049 return ai_range_table[
x];
1053 static const struct comedi_lrange *
const ao_range_table[] = {
1063 if (x < 0 || x >= 5)
1065 return ao_range_table[
x];
1075 static int dt282x_grab_dma(
struct comedi_device *dev,
int dma1,
int dma2)
1081 if (!dma1 && !dma2) {
1086 if (dma1 == dma2 || dma1 < 5 || dma2 < 5 || dma1 > 7 || dma2 > 7)
1185 unsigned long flags;
1197 restore_flags(flags);
1204 ret =
request_irq(irq, dt282x_interrupt, 0,
"dt282x", dev);
1210 }
else if (irq == 0) {
1244 s->
do_cmd = dt282x_ai_cmd;
1245 s->
cancel = dt282x_ai_cancel;
1263 s->
do_cmd = dt282x_ao_cmd;
1264 s->
cancel = dt282x_ao_cancel;
1349 .name =
"dt2824-pgh",
1358 .name =
"dt2824-pgl",
1430 .name =
"dt24-ez-pgl",
1442 .driver_name =
"dt282x",
1444 .attach = dt282x_attach,
1445 .detach = dt282x_detach,
1446 .board_name = &boardtypes[0].
name,