2 * comedi/drivers/adl_pci9118.c
4 * hardware driver for ADLink cards:
5 * card: PCI-9118DG, PCI-9118HG, PCI-9118HR
6 * driver: pci9118dg, pci9118hg, pci9118hr
8 * Author: Michal Dobes <dobes@tesnet.cz>
14 * Description: Adlink PCI-9118DG, PCI-9118HG, PCI-9118HR
15 * Author: Michal Dobes <dobes@tesnet.cz>
16 * Devices: [ADLink] PCI-9118DG (pci9118dg), PCI-9118HG (pci9118hg),
17 * PCI-9118HR (pci9118hr)
20 * This driver supports AI, AO, DI and DO subdevices.
21 * AI subdevice supports cmd and insn interface,
22 * other subdevices support only insn interface.
24 * - If cmd->scan_begin_src=TRIG_EXT then trigger input is TGIN (pin 46).
25 * - If cmd->convert_src=TRIG_EXT then trigger input is EXTTRG (pin 44).
26 * - If cmd->start_src/stop_src=TRIG_EXT then trigger input is TGIN (pin 46).
27 * - It is not necessary to have cmd.scan_end_arg=cmd.chanlist_len but
28 * cmd.scan_end_arg modulo cmd.chanlist_len must by 0.
29 * - If return value of cmdtest is 5 then you've bad channel list
30 * (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar
33 * There are some hardware limitations:
34 * a) You cann't use mixture of unipolar/bipoar ranges or differencial/single
36 * b) DMA transfers must have the length aligned to two samples (32 bit),
37 * so there is some problems if cmd->chanlist_len is odd. This driver tries
38 * bypass this with adding one sample to the end of the every scan and discard
39 * it on output but this can't be used if cmd->scan_begin_src=TRIG_FOLLOW
40 * and is used flag CMDF_WAKE_EOS, then driver switch to interrupt driven mode
41 * with interrupt after every sample.
42 * c) If isn't used DMA then you can use only mode where
43 * cmd->scan_begin_src=TRIG_FOLLOW.
45 * Configuration options:
46 * [0] - PCI bus of device (optional)
47 * [1] - PCI slot of device (optional)
48 * If bus/slot is not specified, then first available PCI
50 * [2] - 0= standard 8 DIFF/16 SE channels configuration
51 * n = external multiplexer connected, 1 <= n <= 256
53 * [4] - sample&hold signal - card can generate signal for external S&H board
54 * 0 = use SSHO(pin 45) signal is generated in onboard hardware S&H logic
55 * 0 != use ADCHN7(pin 23) signal is generated from driver, number say how
56 * long delay is requested in ns and sign polarity of the hold
57 * (in this case external multiplexor can serve only 128 channels)
64 * All the supported boards have the same PCI vendor and device IDs, so
65 * auto-attachment of PCI devices will always find the first board type.
67 * Perhaps the boards have different subdevice IDs that we could use to
70 * Need some device attributes so the board type can be corrected after
71 * attachment if necessary, and possibly to set other options supported by
75 #include <linux/module.h>
76 #include <linux/delay.h>
77 #include <linux/gfp.h>
78 #include <linux/interrupt.h>
81 #include "../comedi_pci.h"
83 #include "amcc_s5933.h"
84 #include "comedi_8254.h"
86 #define IORANGE_9118 64 /* I hope */
87 #define PCI9118_CHANLEN 255 /*
88 * len of chanlist, some source say 256,
89 * but reality looks like 255 :-(
93 * PCI BAR2 Register map (dev->iobase)
95 #define PCI9118_TIMER_BASE 0x00
96 #define PCI9118_AI_FIFO_REG 0x10
97 #define PCI9118_AO_REG(x) (0x10 + ((x) * 4))
98 #define PCI9118_AI_STATUS_REG 0x18
99 #define PCI9118_AI_STATUS_NFULL BIT(8) /* 0=FIFO full (fatal) */
100 #define PCI9118_AI_STATUS_NHFULL BIT(7) /* 0=FIFO half full */
101 #define PCI9118_AI_STATUS_NEPTY BIT(6) /* 0=FIFO empty */
102 #define PCI9118_AI_STATUS_ACMP BIT(5) /* 1=about trigger complete */
103 #define PCI9118_AI_STATUS_DTH BIT(4) /* 1=ext. digital trigger */
104 #define PCI9118_AI_STATUS_BOVER BIT(3) /* 1=burst overrun (fatal) */
105 #define PCI9118_AI_STATUS_ADOS BIT(2) /* 1=A/D over speed (warn) */
106 #define PCI9118_AI_STATUS_ADOR BIT(1) /* 1=A/D overrun (fatal) */
107 #define PCI9118_AI_STATUS_ADRDY BIT(0) /* 1=A/D ready */
108 #define PCI9118_AI_CTRL_REG 0x18
109 #define PCI9118_AI_CTRL_UNIP BIT(7) /* 1=unipolar */
110 #define PCI9118_AI_CTRL_DIFF BIT(6) /* 1=differential inputs */
111 #define PCI9118_AI_CTRL_SOFTG BIT(5) /* 1=8254 software gate */
112 #define PCI9118_AI_CTRL_EXTG BIT(4) /* 1=8254 TGIN(pin 46) gate */
113 #define PCI9118_AI_CTRL_EXTM BIT(3) /* 1=ext. trigger (pin 44) */
114 #define PCI9118_AI_CTRL_TMRTR BIT(2) /* 1=8254 is trigger source */
115 #define PCI9118_AI_CTRL_INT BIT(1) /* 1=enable interrupt */
116 #define PCI9118_AI_CTRL_DMA BIT(0) /* 1=enable DMA */
117 #define PCI9118_DIO_REG 0x1c
118 #define PCI9118_SOFTTRG_REG 0x20
119 #define PCI9118_AI_CHANLIST_REG 0x24
120 #define PCI9118_AI_CHANLIST_RANGE(x) (((x) & 0x3) << 8)
121 #define PCI9118_AI_CHANLIST_CHAN(x) ((x) << 0)
122 #define PCI9118_AI_BURST_NUM_REG 0x28
123 #define PCI9118_AI_AUTOSCAN_MODE_REG 0x2c
124 #define PCI9118_AI_CFG_REG 0x30
125 #define PCI9118_AI_CFG_PDTRG BIT(7) /* 1=positive trigger */
126 #define PCI9118_AI_CFG_PETRG BIT(6) /* 1=positive ext. trigger */
127 #define PCI9118_AI_CFG_BSSH BIT(5) /* 1=with sample & hold */
128 #define PCI9118_AI_CFG_BM BIT(4) /* 1=burst mode */
129 #define PCI9118_AI_CFG_BS BIT(3) /* 1=burst mode start */
130 #define PCI9118_AI_CFG_PM BIT(2) /* 1=post trigger */
131 #define PCI9118_AI_CFG_AM BIT(1) /* 1=about trigger */
132 #define PCI9118_AI_CFG_START BIT(0) /* 1=trigger start */
133 #define PCI9118_FIFO_RESET_REG 0x34
134 #define PCI9118_INT_CTRL_REG 0x38
135 #define PCI9118_INT_CTRL_TIMER BIT(3) /* timer interrupt */
136 #define PCI9118_INT_CTRL_ABOUT BIT(2) /* about trigger complete */
137 #define PCI9118_INT_CTRL_HFULL BIT(1) /* A/D FIFO half full */
138 #define PCI9118_INT_CTRL_DTRG BIT(0) /* ext. digital trigger */
140 #define START_AI_EXT 0x01 /* start measure on external trigger */
141 #define STOP_AI_EXT 0x02 /* stop measure on external trigger */
142 #define STOP_AI_INT 0x08 /* stop measure on internal trigger */
144 #define PCI9118_HALF_FIFO_SZ (1024 / 2)
146 static const struct comedi_lrange pci9118_ai_range
= {
159 static const struct comedi_lrange pci9118hg_ai_range
= {
172 enum pci9118_boardid
{
178 struct pci9118_boardinfo
{
180 unsigned int ai_is_16bit
:1;
181 unsigned int is_hg
:1;
184 static const struct pci9118_boardinfo pci9118_boards
[] = {
185 [BOARD_PCI9118DG
] = {
188 [BOARD_PCI9118HG
] = {
192 [BOARD_PCI9118HR
] = {
198 struct pci9118_dmabuf
{
199 unsigned short *virt
; /* virtual address of buffer */
200 dma_addr_t hw
; /* hardware (bus) address of buffer */
201 unsigned int size
; /* size of dma buffer in bytes */
202 unsigned int use_size
; /* which size we may now use for transfer */
205 struct pci9118_private
{
206 unsigned long iobase_a
; /* base+size for AMCC chip */
207 unsigned int master
:1;
208 unsigned int dma_doublebuf
:1;
209 unsigned int ai_neverending
:1;
210 unsigned int usedma
:1;
211 unsigned int usemux
:1;
212 unsigned char ai_ctrl
;
213 unsigned char int_ctrl
;
214 unsigned char ai_cfg
;
215 unsigned int ai_do
; /* what do AI? 0=nothing, 1 to 4 mode */
216 unsigned int ai_n_realscanlen
; /*
217 * what we must transfer for one
218 * outgoing scan include front/back adds
220 unsigned int ai_act_dmapos
; /* position in actual real stream */
221 unsigned int ai_add_front
; /*
222 * how many channels we must add
223 * before scan to satisfy S&H?
225 unsigned int ai_add_back
; /*
226 * how many channels we must add
227 * before scan to satisfy DMA?
229 unsigned int ai_flags
;
230 char ai12_startstop
; /*
231 * measure can start/stop
232 * on external trigger
234 unsigned int dma_actbuf
; /* which buffer is used now */
235 struct pci9118_dmabuf dmabuf
[2];
237 * >0 use software S&H,
238 * numer is requested delay in ns
240 unsigned char softsshsample
; /*
241 * polarity of S&H signal
244 unsigned char softsshhold
; /*
245 * polarity of S&H signal
248 unsigned int ai_ns_min
;
251 static void pci9118_amcc_setup_dma(struct comedi_device
*dev
, unsigned int buf
)
253 struct pci9118_private
*devpriv
= dev
->private;
254 struct pci9118_dmabuf
*dmabuf
= &devpriv
->dmabuf
[buf
];
256 /* set the master write address and transfer count */
257 outl(dmabuf
->hw
, devpriv
->iobase_a
+ AMCC_OP_REG_MWAR
);
258 outl(dmabuf
->use_size
, devpriv
->iobase_a
+ AMCC_OP_REG_MWTC
);
261 static void pci9118_amcc_dma_ena(struct comedi_device
*dev
, bool enable
)
263 struct pci9118_private
*devpriv
= dev
->private;
266 mcsr
= inl(devpriv
->iobase_a
+ AMCC_OP_REG_MCSR
);
268 mcsr
|= RESET_A2P_FLAGS
| A2P_HI_PRIORITY
| EN_A2P_TRANSFERS
;
270 mcsr
&= ~EN_A2P_TRANSFERS
;
271 outl(mcsr
, devpriv
->iobase_a
+ AMCC_OP_REG_MCSR
);
274 static void pci9118_amcc_int_ena(struct comedi_device
*dev
, bool enable
)
276 struct pci9118_private
*devpriv
= dev
->private;
279 /* enable/disable interrupt for AMCC Incoming Mailbox 4 (32-bit) */
280 intcsr
= inl(devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
285 outl(intcsr
, devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
288 static void pci9118_ai_reset_fifo(struct comedi_device
*dev
)
290 /* writing any value resets the A/D FIFO */
291 outl(0, dev
->iobase
+ PCI9118_FIFO_RESET_REG
);
294 static int pci9118_ai_check_chanlist(struct comedi_device
*dev
,
295 struct comedi_subdevice
*s
,
296 struct comedi_cmd
*cmd
)
298 struct pci9118_private
*devpriv
= dev
->private;
299 unsigned int range0
= CR_RANGE(cmd
->chanlist
[0]);
300 unsigned int aref0
= CR_AREF(cmd
->chanlist
[0]);
303 /* single channel scans are always ok */
304 if (cmd
->chanlist_len
== 1)
307 for (i
= 1; i
< cmd
->chanlist_len
; i
++) {
308 unsigned int chan
= CR_CHAN(cmd
->chanlist
[i
]);
309 unsigned int range
= CR_RANGE(cmd
->chanlist
[i
]);
310 unsigned int aref
= CR_AREF(cmd
->chanlist
[i
]);
313 dev_err(dev
->class_dev
,
314 "Differential and single ended inputs can't be mixed!\n");
317 if (comedi_range_is_bipolar(s
, range
) !=
318 comedi_range_is_bipolar(s
, range0
)) {
319 dev_err(dev
->class_dev
,
320 "Bipolar and unipolar ranges can't be mixed!\n");
323 if (!devpriv
->usemux
&& aref
== AREF_DIFF
&&
324 (chan
>= (s
->n_chan
/ 2))) {
325 dev_err(dev
->class_dev
,
326 "AREF_DIFF is only available for the first 8 channels!\n");
334 static void pci9118_set_chanlist(struct comedi_device
*dev
,
335 struct comedi_subdevice
*s
,
336 int n_chan
, unsigned int *chanlist
,
337 int frontadd
, int backadd
)
339 struct pci9118_private
*devpriv
= dev
->private;
340 unsigned int chan0
= CR_CHAN(chanlist
[0]);
341 unsigned int range0
= CR_RANGE(chanlist
[0]);
342 unsigned int aref0
= CR_AREF(chanlist
[0]);
343 unsigned int ssh
= 0x00;
348 * Configure analog input based on the first chanlist entry.
349 * All entries are either unipolar or bipolar and single-ended
352 devpriv
->ai_ctrl
= 0;
353 if (comedi_range_is_unipolar(s
, range0
))
354 devpriv
->ai_ctrl
|= PCI9118_AI_CTRL_UNIP
;
355 if (aref0
== AREF_DIFF
)
356 devpriv
->ai_ctrl
|= PCI9118_AI_CTRL_DIFF
;
357 outl(devpriv
->ai_ctrl
, dev
->iobase
+ PCI9118_AI_CTRL_REG
);
359 /* gods know why this sequence! */
360 outl(2, dev
->iobase
+ PCI9118_AI_AUTOSCAN_MODE_REG
);
361 outl(0, dev
->iobase
+ PCI9118_AI_AUTOSCAN_MODE_REG
);
362 outl(1, dev
->iobase
+ PCI9118_AI_AUTOSCAN_MODE_REG
);
364 /* insert channels for S&H */
366 val
= PCI9118_AI_CHANLIST_CHAN(chan0
) |
367 PCI9118_AI_CHANLIST_RANGE(range0
);
368 ssh
= devpriv
->softsshsample
;
369 for (i
= 0; i
< frontadd
; i
++) {
370 outl(val
| ssh
, dev
->iobase
+ PCI9118_AI_CHANLIST_REG
);
371 ssh
= devpriv
->softsshhold
;
376 for (i
= 0; i
< n_chan
; i
++) {
377 unsigned int chan
= CR_CHAN(chanlist
[i
]);
378 unsigned int range
= CR_RANGE(chanlist
[i
]);
380 val
= PCI9118_AI_CHANLIST_CHAN(chan
) |
381 PCI9118_AI_CHANLIST_RANGE(range
);
382 outl(val
| ssh
, dev
->iobase
+ PCI9118_AI_CHANLIST_REG
);
385 /* insert channels to fit onto 32bit DMA */
387 val
= PCI9118_AI_CHANLIST_CHAN(chan0
) |
388 PCI9118_AI_CHANLIST_RANGE(range0
);
389 for (i
= 0; i
< backadd
; i
++)
390 outl(val
| ssh
, dev
->iobase
+ PCI9118_AI_CHANLIST_REG
);
392 /* close scan queue */
393 outl(0, dev
->iobase
+ PCI9118_AI_AUTOSCAN_MODE_REG
);
394 /* udelay(100); important delay, or first sample will be crippled */
397 static void interrupt_pci9118_ai_mode4_switch(struct comedi_device
*dev
,
398 unsigned int next_buf
)
400 struct pci9118_private
*devpriv
= dev
->private;
401 struct pci9118_dmabuf
*dmabuf
= &devpriv
->dmabuf
[next_buf
];
403 devpriv
->ai_cfg
= PCI9118_AI_CFG_PDTRG
| PCI9118_AI_CFG_PETRG
|
405 outl(devpriv
->ai_cfg
, dev
->iobase
+ PCI9118_AI_CFG_REG
);
406 comedi_8254_load(dev
->pacer
, 0, dmabuf
->hw
>> 1,
407 I8254_MODE0
| I8254_BINARY
);
408 devpriv
->ai_cfg
|= PCI9118_AI_CFG_START
;
409 outl(devpriv
->ai_cfg
, dev
->iobase
+ PCI9118_AI_CFG_REG
);
412 static unsigned int valid_samples_in_act_dma_buf(struct comedi_device
*dev
,
413 struct comedi_subdevice
*s
,
414 unsigned int n_raw_samples
)
416 struct pci9118_private
*devpriv
= dev
->private;
417 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
418 unsigned int start_pos
= devpriv
->ai_add_front
;
419 unsigned int stop_pos
= start_pos
+ cmd
->chanlist_len
;
420 unsigned int span_len
= stop_pos
+ devpriv
->ai_add_back
;
421 unsigned int dma_pos
= devpriv
->ai_act_dmapos
;
422 unsigned int whole_spans
, n_samples
, x
;
424 if (span_len
== cmd
->chanlist_len
)
425 return n_raw_samples
; /* use all samples */
428 * Not all samples are to be used. Buffer contents consist of a
429 * possibly non-whole number of spans and a region of each span
432 * Account for samples in whole number of spans.
434 whole_spans
= n_raw_samples
/ span_len
;
435 n_samples
= whole_spans
* cmd
->chanlist_len
;
436 n_raw_samples
-= whole_spans
* span_len
;
439 * Deal with remaining samples which could overlap up to two spans.
441 while (n_raw_samples
) {
442 if (dma_pos
< start_pos
) {
443 /* Skip samples before start position. */
444 x
= start_pos
- dma_pos
;
445 if (x
> n_raw_samples
)
452 if (dma_pos
< stop_pos
) {
453 /* Include samples before stop position. */
454 x
= stop_pos
- dma_pos
;
455 if (x
> n_raw_samples
)
461 /* Advance to next span. */
462 start_pos
+= span_len
;
463 stop_pos
+= span_len
;
468 static void move_block_from_dma(struct comedi_device
*dev
,
469 struct comedi_subdevice
*s
,
470 unsigned short *dma_buffer
,
471 unsigned int n_raw_samples
)
473 struct pci9118_private
*devpriv
= dev
->private;
474 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
475 unsigned int start_pos
= devpriv
->ai_add_front
;
476 unsigned int stop_pos
= start_pos
+ cmd
->chanlist_len
;
477 unsigned int span_len
= stop_pos
+ devpriv
->ai_add_back
;
478 unsigned int dma_pos
= devpriv
->ai_act_dmapos
;
481 if (span_len
== cmd
->chanlist_len
) {
482 /* All samples are to be copied. */
483 comedi_buf_write_samples(s
, dma_buffer
, n_raw_samples
);
484 dma_pos
+= n_raw_samples
;
487 * Not all samples are to be copied. Buffer contents consist
488 * of a possibly non-whole number of spans and a region of
489 * each span is to be copied.
491 while (n_raw_samples
) {
492 if (dma_pos
< start_pos
) {
493 /* Skip samples before start position. */
494 x
= start_pos
- dma_pos
;
495 if (x
> n_raw_samples
)
502 if (dma_pos
< stop_pos
) {
503 /* Copy samples before stop position. */
504 x
= stop_pos
- dma_pos
;
505 if (x
> n_raw_samples
)
507 comedi_buf_write_samples(s
, dma_buffer
, x
);
511 /* Advance to next span. */
512 start_pos
+= span_len
;
513 stop_pos
+= span_len
;
516 /* Update position in span for next time. */
517 devpriv
->ai_act_dmapos
= dma_pos
% span_len
;
520 static void pci9118_exttrg_enable(struct comedi_device
*dev
, bool enable
)
522 struct pci9118_private
*devpriv
= dev
->private;
525 devpriv
->int_ctrl
|= PCI9118_INT_CTRL_DTRG
;
527 devpriv
->int_ctrl
&= ~PCI9118_INT_CTRL_DTRG
;
528 outl(devpriv
->int_ctrl
, dev
->iobase
+ PCI9118_INT_CTRL_REG
);
530 if (devpriv
->int_ctrl
)
531 pci9118_amcc_int_ena(dev
, true);
533 pci9118_amcc_int_ena(dev
, false);
536 static void pci9118_calc_divisors(struct comedi_device
*dev
,
537 struct comedi_subdevice
*s
,
538 unsigned int *tim1
, unsigned int *tim2
,
539 unsigned int flags
, int chans
,
540 unsigned int *div1
, unsigned int *div2
,
541 unsigned int chnsshfront
)
543 struct comedi_8254
*pacer
= dev
->pacer
;
544 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
546 *div1
= *tim2
/ pacer
->osc_base
; /* convert timer (burst) */
547 *div2
= *tim1
/ pacer
->osc_base
; /* scan timer */
548 *div2
= *div2
/ *div1
; /* major timer is c1*c2 */
552 *tim2
= *div1
* pacer
->osc_base
; /* real convert timer */
554 if (cmd
->convert_src
== TRIG_NOW
&& !chnsshfront
) {
555 /* use BSSH signal */
556 if (*div2
< (chans
+ 2))
560 *tim1
= *div1
* *div2
* pacer
->osc_base
;
563 static void pci9118_start_pacer(struct comedi_device
*dev
, int mode
)
565 if (mode
== 1 || mode
== 2 || mode
== 4)
566 comedi_8254_pacer_enable(dev
->pacer
, 1, 2, true);
569 static int pci9118_ai_cancel(struct comedi_device
*dev
,
570 struct comedi_subdevice
*s
)
572 struct pci9118_private
*devpriv
= dev
->private;
575 pci9118_amcc_dma_ena(dev
, false);
576 pci9118_exttrg_enable(dev
, false);
577 comedi_8254_pacer_enable(dev
->pacer
, 1, 2, false);
578 /* set default config (disable burst and triggers) */
579 devpriv
->ai_cfg
= PCI9118_AI_CFG_PDTRG
| PCI9118_AI_CFG_PETRG
;
580 outl(devpriv
->ai_cfg
, dev
->iobase
+ PCI9118_AI_CFG_REG
);
581 /* reset acqusition control */
582 devpriv
->ai_ctrl
= 0;
583 outl(devpriv
->ai_ctrl
, dev
->iobase
+ PCI9118_AI_CTRL_REG
);
584 outl(0, dev
->iobase
+ PCI9118_AI_BURST_NUM_REG
);
585 /* reset scan queue */
586 outl(1, dev
->iobase
+ PCI9118_AI_AUTOSCAN_MODE_REG
);
587 outl(2, dev
->iobase
+ PCI9118_AI_AUTOSCAN_MODE_REG
);
588 pci9118_ai_reset_fifo(dev
);
590 devpriv
->int_ctrl
= 0;
591 outl(devpriv
->int_ctrl
, dev
->iobase
+ PCI9118_INT_CTRL_REG
);
592 pci9118_amcc_int_ena(dev
, false);
597 devpriv
->ai_act_dmapos
= 0;
598 s
->async
->inttrig
= NULL
;
599 devpriv
->ai_neverending
= 0;
600 devpriv
->dma_actbuf
= 0;
605 static void pci9118_ai_munge(struct comedi_device
*dev
,
606 struct comedi_subdevice
*s
, void *data
,
607 unsigned int num_bytes
,
608 unsigned int start_chan_index
)
610 struct pci9118_private
*devpriv
= dev
->private;
611 unsigned short *array
= data
;
612 unsigned int num_samples
= comedi_bytes_to_samples(s
, num_bytes
);
615 for (i
= 0; i
< num_samples
; i
++) {
617 array
[i
] = be16_to_cpu(array
[i
]);
618 if (s
->maxdata
== 0xffff)
621 array
[i
] = (array
[i
] >> 4) & 0x0fff;
625 static void interrupt_pci9118_ai_onesample(struct comedi_device
*dev
,
626 struct comedi_subdevice
*s
)
628 struct pci9118_private
*devpriv
= dev
->private;
629 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
630 unsigned short sampl
;
632 sampl
= inl(dev
->iobase
+ PCI9118_AI_FIFO_REG
);
634 comedi_buf_write_samples(s
, &sampl
, 1);
636 if (!devpriv
->ai_neverending
) {
637 if (s
->async
->scans_done
>= cmd
->stop_arg
)
638 s
->async
->events
|= COMEDI_CB_EOA
;
642 static void interrupt_pci9118_ai_dma(struct comedi_device
*dev
,
643 struct comedi_subdevice
*s
)
645 struct pci9118_private
*devpriv
= dev
->private;
646 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
647 struct pci9118_dmabuf
*dmabuf
= &devpriv
->dmabuf
[devpriv
->dma_actbuf
];
648 unsigned int n_all
= comedi_bytes_to_samples(s
, dmabuf
->use_size
);
649 unsigned int n_valid
;
652 /* determine whether more DMA buffers to do after this one */
653 n_valid
= valid_samples_in_act_dma_buf(dev
, s
, n_all
);
654 more_dma
= n_valid
< comedi_nsamples_left(s
, n_valid
+ 1);
656 /* switch DMA buffers and restart DMA if double buffering */
657 if (more_dma
&& devpriv
->dma_doublebuf
) {
658 devpriv
->dma_actbuf
= 1 - devpriv
->dma_actbuf
;
659 pci9118_amcc_setup_dma(dev
, devpriv
->dma_actbuf
);
660 if (devpriv
->ai_do
== 4) {
661 interrupt_pci9118_ai_mode4_switch(dev
,
662 devpriv
->dma_actbuf
);
667 move_block_from_dma(dev
, s
, dmabuf
->virt
, n_all
);
669 if (!devpriv
->ai_neverending
) {
670 if (s
->async
->scans_done
>= cmd
->stop_arg
)
671 s
->async
->events
|= COMEDI_CB_EOA
;
674 if (s
->async
->events
& COMEDI_CB_CANCEL_MASK
)
677 /* restart DMA if not double buffering */
678 if (more_dma
&& !devpriv
->dma_doublebuf
) {
679 pci9118_amcc_setup_dma(dev
, 0);
680 if (devpriv
->ai_do
== 4)
681 interrupt_pci9118_ai_mode4_switch(dev
, 0);
685 static irqreturn_t
pci9118_interrupt(int irq
, void *d
)
687 struct comedi_device
*dev
= d
;
688 struct comedi_subdevice
*s
= dev
->read_subdev
;
689 struct pci9118_private
*devpriv
= dev
->private;
690 unsigned int intsrc
; /* IRQ reasons from card */
691 unsigned int intcsr
; /* INT register from AMCC chip */
692 unsigned int adstat
; /* STATUS register */
697 intsrc
= inl(dev
->iobase
+ PCI9118_INT_CTRL_REG
) & 0xf;
698 intcsr
= inl(devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
700 if (!intsrc
&& !(intcsr
& ANY_S593X_INT
))
703 outl(intcsr
| 0x00ff0000, devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
705 if (intcsr
& MASTER_ABORT_INT
) {
706 dev_err(dev
->class_dev
, "AMCC IRQ - MASTER DMA ABORT!\n");
707 s
->async
->events
|= COMEDI_CB_ERROR
;
711 if (intcsr
& TARGET_ABORT_INT
) {
712 dev_err(dev
->class_dev
, "AMCC IRQ - TARGET DMA ABORT!\n");
713 s
->async
->events
|= COMEDI_CB_ERROR
;
717 adstat
= inl(dev
->iobase
+ PCI9118_AI_STATUS_REG
);
718 if ((adstat
& PCI9118_AI_STATUS_NFULL
) == 0) {
719 dev_err(dev
->class_dev
,
720 "A/D FIFO Full status (Fatal Error!)\n");
721 s
->async
->events
|= COMEDI_CB_ERROR
| COMEDI_CB_OVERFLOW
;
724 if (adstat
& PCI9118_AI_STATUS_BOVER
) {
725 dev_err(dev
->class_dev
,
726 "A/D Burst Mode Overrun Status (Fatal Error!)\n");
727 s
->async
->events
|= COMEDI_CB_ERROR
| COMEDI_CB_OVERFLOW
;
730 if (adstat
& PCI9118_AI_STATUS_ADOS
) {
731 dev_err(dev
->class_dev
, "A/D Over Speed Status (Warning!)\n");
732 s
->async
->events
|= COMEDI_CB_ERROR
;
735 if (adstat
& PCI9118_AI_STATUS_ADOR
) {
736 dev_err(dev
->class_dev
, "A/D Overrun Status (Fatal Error!)\n");
737 s
->async
->events
|= COMEDI_CB_ERROR
| COMEDI_CB_OVERFLOW
;
744 if (devpriv
->ai12_startstop
) {
745 if ((adstat
& PCI9118_AI_STATUS_DTH
) &&
746 (intsrc
& PCI9118_INT_CTRL_DTRG
)) {
747 /* start/stop of measure */
748 if (devpriv
->ai12_startstop
& START_AI_EXT
) {
749 /* deactivate EXT trigger */
750 devpriv
->ai12_startstop
&= ~START_AI_EXT
;
751 if (!(devpriv
->ai12_startstop
& STOP_AI_EXT
))
752 pci9118_exttrg_enable(dev
, false);
755 pci9118_start_pacer(dev
, devpriv
->ai_do
);
756 outl(devpriv
->ai_ctrl
,
757 dev
->iobase
+ PCI9118_AI_CTRL_REG
);
758 } else if (devpriv
->ai12_startstop
& STOP_AI_EXT
) {
759 /* deactivate EXT trigger */
760 devpriv
->ai12_startstop
&= ~STOP_AI_EXT
;
761 pci9118_exttrg_enable(dev
, false);
763 /* on next interrupt measure will stop */
764 devpriv
->ai_neverending
= 0;
770 interrupt_pci9118_ai_dma(dev
, s
);
772 interrupt_pci9118_ai_onesample(dev
, s
);
775 comedi_handle_events(dev
, s
);
779 static void pci9118_ai_cmd_start(struct comedi_device
*dev
)
781 struct pci9118_private
*devpriv
= dev
->private;
783 outl(devpriv
->int_ctrl
, dev
->iobase
+ PCI9118_INT_CTRL_REG
);
784 outl(devpriv
->ai_cfg
, dev
->iobase
+ PCI9118_AI_CFG_REG
);
785 if (devpriv
->ai_do
!= 3) {
786 pci9118_start_pacer(dev
, devpriv
->ai_do
);
787 devpriv
->ai_ctrl
|= PCI9118_AI_CTRL_SOFTG
;
789 outl(devpriv
->ai_ctrl
, dev
->iobase
+ PCI9118_AI_CTRL_REG
);
792 static int pci9118_ai_inttrig(struct comedi_device
*dev
,
793 struct comedi_subdevice
*s
,
794 unsigned int trig_num
)
796 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
798 if (trig_num
!= cmd
->start_arg
)
801 s
->async
->inttrig
= NULL
;
802 pci9118_ai_cmd_start(dev
);
807 static int pci9118_ai_setup_dma(struct comedi_device
*dev
,
808 struct comedi_subdevice
*s
)
810 struct pci9118_private
*devpriv
= dev
->private;
811 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
812 struct pci9118_dmabuf
*dmabuf0
= &devpriv
->dmabuf
[0];
813 struct pci9118_dmabuf
*dmabuf1
= &devpriv
->dmabuf
[1];
814 unsigned int dmalen0
, dmalen1
, i
;
816 dmalen0
= dmabuf0
->size
;
817 dmalen1
= dmabuf1
->size
;
818 /* isn't output buff smaller that our DMA buff? */
819 if (dmalen0
> s
->async
->prealloc_bufsz
) {
820 /* align to 32bit down */
821 dmalen0
= s
->async
->prealloc_bufsz
& ~3L;
823 if (dmalen1
> s
->async
->prealloc_bufsz
) {
824 /* align to 32bit down */
825 dmalen1
= s
->async
->prealloc_bufsz
& ~3L;
828 /* we want wake up every scan? */
829 if (devpriv
->ai_flags
& CMDF_WAKE_EOS
) {
830 if (dmalen0
< (devpriv
->ai_n_realscanlen
<< 1)) {
831 /* uff, too short DMA buffer, disable EOS support! */
832 devpriv
->ai_flags
&= (~CMDF_WAKE_EOS
);
833 dev_info(dev
->class_dev
,
834 "WAR: DMA0 buf too short, can't support CMDF_WAKE_EOS (%d<%d)\n",
835 dmalen0
, devpriv
->ai_n_realscanlen
<< 1);
837 /* short first DMA buffer to one scan */
838 dmalen0
= devpriv
->ai_n_realscanlen
<< 1;
840 dev_info(dev
->class_dev
,
841 "ERR: DMA0 buf len bug? (%d<4)\n",
847 if (devpriv
->ai_flags
& CMDF_WAKE_EOS
) {
848 if (dmalen1
< (devpriv
->ai_n_realscanlen
<< 1)) {
849 /* uff, too short DMA buffer, disable EOS support! */
850 devpriv
->ai_flags
&= (~CMDF_WAKE_EOS
);
851 dev_info(dev
->class_dev
,
852 "WAR: DMA1 buf too short, can't support CMDF_WAKE_EOS (%d<%d)\n",
853 dmalen1
, devpriv
->ai_n_realscanlen
<< 1);
855 /* short second DMA buffer to one scan */
856 dmalen1
= devpriv
->ai_n_realscanlen
<< 1;
858 dev_info(dev
->class_dev
,
859 "ERR: DMA1 buf len bug? (%d<4)\n",
866 /* transfer without CMDF_WAKE_EOS */
867 if (!(devpriv
->ai_flags
& CMDF_WAKE_EOS
)) {
868 /* if it's possible then align DMA buffers to length of scan */
871 (dmalen0
/ (devpriv
->ai_n_realscanlen
<< 1)) *
872 (devpriv
->ai_n_realscanlen
<< 1);
875 dmalen0
= i
; /* uff. very long scan? */
878 (dmalen1
/ (devpriv
->ai_n_realscanlen
<< 1)) *
879 (devpriv
->ai_n_realscanlen
<< 1);
882 dmalen1
= i
; /* uff. very long scan? */
884 * if measure isn't neverending then test, if it fits whole
885 * into one or two DMA buffers
887 if (!devpriv
->ai_neverending
) {
888 /* fits whole measure into one DMA buffer? */
890 ((devpriv
->ai_n_realscanlen
<< 1) *
893 (devpriv
->ai_n_realscanlen
<< 1) *
897 * fits whole measure into
901 ((devpriv
->ai_n_realscanlen
<< 1) *
902 cmd
->stop_arg
- dmalen0
))
904 (devpriv
->ai_n_realscanlen
<< 1) *
905 cmd
->stop_arg
- dmalen0
;
911 /* these DMA buffer size will be used */
912 devpriv
->dma_actbuf
= 0;
913 dmabuf0
->use_size
= dmalen0
;
914 dmabuf1
->use_size
= dmalen1
;
916 pci9118_amcc_dma_ena(dev
, false);
917 pci9118_amcc_setup_dma(dev
, 0);
918 /* init DMA transfer */
919 outl(0x00000000 | AINT_WRITE_COMPL
,
920 devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
921 /* outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR); */
922 pci9118_amcc_dma_ena(dev
, true);
923 outl(inl(devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
) | EN_A2P_TRANSFERS
,
924 devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
925 /* allow bus mastering */
930 static int pci9118_ai_cmd(struct comedi_device
*dev
, struct comedi_subdevice
*s
)
932 struct pci9118_private
*devpriv
= dev
->private;
933 struct comedi_8254
*pacer
= dev
->pacer
;
934 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
935 unsigned int addchans
= 0;
936 unsigned int scanlen
;
938 devpriv
->ai12_startstop
= 0;
939 devpriv
->ai_flags
= cmd
->flags
;
940 devpriv
->ai_add_front
= 0;
941 devpriv
->ai_add_back
= 0;
943 /* prepare for start/stop conditions */
944 if (cmd
->start_src
== TRIG_EXT
)
945 devpriv
->ai12_startstop
|= START_AI_EXT
;
946 if (cmd
->stop_src
== TRIG_EXT
) {
947 devpriv
->ai_neverending
= 1;
948 devpriv
->ai12_startstop
|= STOP_AI_EXT
;
950 if (cmd
->stop_src
== TRIG_NONE
)
951 devpriv
->ai_neverending
= 1;
952 if (cmd
->stop_src
== TRIG_COUNT
)
953 devpriv
->ai_neverending
= 0;
956 * use additional sample at end of every scan
957 * to satisty DMA 32 bit transfer?
959 devpriv
->ai_add_front
= 0;
960 devpriv
->ai_add_back
= 0;
961 if (devpriv
->master
) {
963 if ((cmd
->flags
& CMDF_WAKE_EOS
) &&
964 (cmd
->scan_end_arg
== 1)) {
965 if (cmd
->convert_src
== TRIG_NOW
)
966 devpriv
->ai_add_back
= 1;
967 if (cmd
->convert_src
== TRIG_TIMER
) {
970 * use INT transfer if scanlist
971 * have only one channel
975 if ((cmd
->flags
& CMDF_WAKE_EOS
) &&
976 (cmd
->scan_end_arg
& 1) &&
977 (cmd
->scan_end_arg
> 1)) {
978 if (cmd
->scan_begin_src
== TRIG_FOLLOW
) {
981 * XXX maybe can be corrected to use 16 bit DMA
984 * well, we must insert one sample
985 * to end of EOS to meet 32 bit transfer
987 devpriv
->ai_add_back
= 1;
990 } else { /* interrupt transfer don't need any correction */
995 * we need software S&H signal?
996 * It adds two samples before every scan as minimum
998 if (cmd
->convert_src
== TRIG_NOW
&& devpriv
->softsshdelay
) {
999 devpriv
->ai_add_front
= 2;
1000 if ((devpriv
->usedma
== 1) && (devpriv
->ai_add_back
== 1)) {
1001 /* move it to front */
1002 devpriv
->ai_add_front
++;
1003 devpriv
->ai_add_back
= 0;
1005 if (cmd
->convert_arg
< devpriv
->ai_ns_min
)
1006 cmd
->convert_arg
= devpriv
->ai_ns_min
;
1007 addchans
= devpriv
->softsshdelay
/ cmd
->convert_arg
;
1008 if (devpriv
->softsshdelay
% cmd
->convert_arg
)
1010 if (addchans
> (devpriv
->ai_add_front
- 1)) {
1011 /* uff, still short */
1012 devpriv
->ai_add_front
= addchans
+ 1;
1013 if (devpriv
->usedma
== 1)
1014 if ((devpriv
->ai_add_front
+
1016 devpriv
->ai_add_back
) & 1)
1017 devpriv
->ai_add_front
++;
1018 /* round up to 32 bit */
1021 /* well, we now know what must be all added */
1022 scanlen
= devpriv
->ai_add_front
+ cmd
->chanlist_len
+
1023 devpriv
->ai_add_back
;
1025 * what we must take from card in real to have cmd->scan_end_arg
1028 devpriv
->ai_n_realscanlen
= scanlen
*
1029 (cmd
->scan_end_arg
/ cmd
->chanlist_len
);
1031 if (scanlen
> s
->len_chanlist
) {
1032 dev_err(dev
->class_dev
,
1033 "range/channel list is too long for actual configuration!\n");
1038 * Configure analog input and load the chanlist.
1039 * The acqusition control bits are enabled later.
1041 pci9118_set_chanlist(dev
, s
, cmd
->chanlist_len
, cmd
->chanlist
,
1042 devpriv
->ai_add_front
, devpriv
->ai_add_back
);
1044 /* Determine acqusition mode and calculate timing */
1046 if (cmd
->scan_begin_src
!= TRIG_TIMER
&&
1047 cmd
->convert_src
== TRIG_TIMER
) {
1048 /* cascaded timers 1 and 2 are used for convert timing */
1049 if (cmd
->scan_begin_src
== TRIG_EXT
)
1054 comedi_8254_cascade_ns_to_timer(pacer
, &cmd
->convert_arg
,
1056 CMDF_ROUND_NEAREST
);
1057 comedi_8254_update_divisors(pacer
);
1059 devpriv
->ai_ctrl
|= PCI9118_AI_CTRL_TMRTR
;
1061 if (!devpriv
->usedma
) {
1062 devpriv
->ai_ctrl
|= PCI9118_AI_CTRL_INT
;
1063 devpriv
->int_ctrl
|= PCI9118_INT_CTRL_TIMER
;
1066 if (cmd
->scan_begin_src
== TRIG_EXT
) {
1067 struct pci9118_dmabuf
*dmabuf
= &devpriv
->dmabuf
[0];
1069 devpriv
->ai_cfg
|= PCI9118_AI_CFG_AM
;
1070 outl(devpriv
->ai_cfg
, dev
->iobase
+ PCI9118_AI_CFG_REG
);
1071 comedi_8254_load(pacer
, 0, dmabuf
->hw
>> 1,
1072 I8254_MODE0
| I8254_BINARY
);
1073 devpriv
->ai_cfg
|= PCI9118_AI_CFG_START
;
1077 if (cmd
->scan_begin_src
== TRIG_TIMER
&&
1078 cmd
->convert_src
!= TRIG_EXT
) {
1079 if (!devpriv
->usedma
) {
1080 dev_err(dev
->class_dev
,
1081 "cmd->scan_begin_src=TRIG_TIMER works only with bus mastering!\n");
1085 /* double timed action */
1088 pci9118_calc_divisors(dev
, s
,
1089 &cmd
->scan_begin_arg
, &cmd
->convert_arg
,
1091 devpriv
->ai_n_realscanlen
,
1094 devpriv
->ai_add_front
);
1096 devpriv
->ai_ctrl
|= PCI9118_AI_CTRL_TMRTR
;
1097 devpriv
->ai_cfg
|= PCI9118_AI_CFG_BM
| PCI9118_AI_CFG_BS
;
1098 if (cmd
->convert_src
== TRIG_NOW
&& !devpriv
->softsshdelay
)
1099 devpriv
->ai_cfg
|= PCI9118_AI_CFG_BSSH
;
1100 outl(devpriv
->ai_n_realscanlen
,
1101 dev
->iobase
+ PCI9118_AI_BURST_NUM_REG
);
1104 if (cmd
->scan_begin_src
== TRIG_FOLLOW
&&
1105 cmd
->convert_src
== TRIG_EXT
) {
1106 /* external trigger conversion */
1109 devpriv
->ai_ctrl
|= PCI9118_AI_CTRL_EXTM
;
1112 if (devpriv
->ai_do
== 0) {
1113 dev_err(dev
->class_dev
,
1114 "Unable to determine acqusition mode! BUG in (*do_cmdtest)?\n");
1118 if (devpriv
->usedma
)
1119 devpriv
->ai_ctrl
|= PCI9118_AI_CTRL_DMA
;
1121 /* set default config (disable burst and triggers) */
1122 devpriv
->ai_cfg
= PCI9118_AI_CFG_PDTRG
| PCI9118_AI_CFG_PETRG
;
1123 outl(devpriv
->ai_cfg
, dev
->iobase
+ PCI9118_AI_CFG_REG
);
1125 pci9118_ai_reset_fifo(dev
);
1127 /* clear A/D and INT status registers */
1128 inl(dev
->iobase
+ PCI9118_AI_STATUS_REG
);
1129 inl(dev
->iobase
+ PCI9118_INT_CTRL_REG
);
1131 devpriv
->ai_act_dmapos
= 0;
1133 if (devpriv
->usedma
) {
1134 pci9118_ai_setup_dma(dev
, s
);
1136 outl(0x02000000 | AINT_WRITE_COMPL
,
1137 devpriv
->iobase_a
+ AMCC_OP_REG_INTCSR
);
1139 pci9118_amcc_int_ena(dev
, true);
1142 /* start async command now or wait for internal trigger */
1143 if (cmd
->start_src
== TRIG_NOW
)
1144 pci9118_ai_cmd_start(dev
);
1145 else if (cmd
->start_src
== TRIG_INT
)
1146 s
->async
->inttrig
= pci9118_ai_inttrig
;
1148 /* enable external trigger for command start/stop */
1149 if (cmd
->start_src
== TRIG_EXT
|| cmd
->stop_src
== TRIG_EXT
)
1150 pci9118_exttrg_enable(dev
, true);
1155 static int pci9118_ai_cmdtest(struct comedi_device
*dev
,
1156 struct comedi_subdevice
*s
,
1157 struct comedi_cmd
*cmd
)
1159 struct pci9118_private
*devpriv
= dev
->private;
1164 /* Step 1 : check if triggers are trivially valid */
1166 err
|= comedi_check_trigger_src(&cmd
->start_src
,
1167 TRIG_NOW
| TRIG_EXT
| TRIG_INT
);
1169 flags
= TRIG_FOLLOW
;
1170 if (devpriv
->master
)
1171 flags
|= TRIG_TIMER
| TRIG_EXT
;
1172 err
|= comedi_check_trigger_src(&cmd
->scan_begin_src
, flags
);
1174 flags
= TRIG_TIMER
| TRIG_EXT
;
1175 if (devpriv
->master
)
1177 err
|= comedi_check_trigger_src(&cmd
->convert_src
, flags
);
1179 err
|= comedi_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
1180 err
|= comedi_check_trigger_src(&cmd
->stop_src
,
1181 TRIG_COUNT
| TRIG_NONE
| TRIG_EXT
);
1186 /* Step 2a : make sure trigger sources are unique */
1188 err
|= comedi_check_trigger_is_unique(cmd
->start_src
);
1189 err
|= comedi_check_trigger_is_unique(cmd
->scan_begin_src
);
1190 err
|= comedi_check_trigger_is_unique(cmd
->convert_src
);
1191 err
|= comedi_check_trigger_is_unique(cmd
->stop_src
);
1193 /* Step 2b : and mutually compatible */
1195 if (cmd
->start_src
== TRIG_EXT
&& cmd
->scan_begin_src
== TRIG_EXT
)
1198 if ((cmd
->scan_begin_src
& (TRIG_TIMER
| TRIG_EXT
)) &&
1199 (!(cmd
->convert_src
& (TRIG_TIMER
| TRIG_NOW
))))
1202 if ((cmd
->scan_begin_src
== TRIG_FOLLOW
) &&
1203 (!(cmd
->convert_src
& (TRIG_TIMER
| TRIG_EXT
))))
1206 if (cmd
->stop_src
== TRIG_EXT
&& cmd
->scan_begin_src
== TRIG_EXT
)
1212 /* Step 3: check if arguments are trivially valid */
1214 switch (cmd
->start_src
) {
1217 err
|= comedi_check_trigger_arg_is(&cmd
->start_arg
, 0);
1220 /* start_arg is the internal trigger (any value) */
1224 if (cmd
->scan_begin_src
& (TRIG_FOLLOW
| TRIG_EXT
))
1225 err
|= comedi_check_trigger_arg_is(&cmd
->scan_begin_arg
, 0);
1227 if ((cmd
->scan_begin_src
== TRIG_TIMER
) &&
1228 (cmd
->convert_src
== TRIG_TIMER
) && (cmd
->scan_end_arg
== 1)) {
1229 cmd
->scan_begin_src
= TRIG_FOLLOW
;
1230 cmd
->convert_arg
= cmd
->scan_begin_arg
;
1231 cmd
->scan_begin_arg
= 0;
1234 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
1235 err
|= comedi_check_trigger_arg_min(&cmd
->scan_begin_arg
,
1236 devpriv
->ai_ns_min
);
1239 if (cmd
->scan_begin_src
== TRIG_EXT
) {
1240 if (cmd
->scan_begin_arg
) {
1241 cmd
->scan_begin_arg
= 0;
1243 err
|= comedi_check_trigger_arg_max(&cmd
->scan_end_arg
,
1248 if (cmd
->convert_src
& (TRIG_TIMER
| TRIG_NOW
)) {
1249 err
|= comedi_check_trigger_arg_min(&cmd
->convert_arg
,
1250 devpriv
->ai_ns_min
);
1253 if (cmd
->convert_src
== TRIG_EXT
)
1254 err
|= comedi_check_trigger_arg_is(&cmd
->convert_arg
, 0);
1256 if (cmd
->stop_src
== TRIG_COUNT
)
1257 err
|= comedi_check_trigger_arg_min(&cmd
->stop_arg
, 1);
1258 else /* TRIG_NONE */
1259 err
|= comedi_check_trigger_arg_is(&cmd
->stop_arg
, 0);
1261 err
|= comedi_check_trigger_arg_min(&cmd
->chanlist_len
, 1);
1263 err
|= comedi_check_trigger_arg_min(&cmd
->scan_end_arg
,
1266 if ((cmd
->scan_end_arg
% cmd
->chanlist_len
)) {
1268 cmd
->chanlist_len
* (cmd
->scan_end_arg
/ cmd
->chanlist_len
);
1275 /* step 4: fix up any arguments */
1277 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
1278 arg
= cmd
->scan_begin_arg
;
1279 comedi_8254_cascade_ns_to_timer(dev
->pacer
, &arg
, cmd
->flags
);
1280 err
|= comedi_check_trigger_arg_is(&cmd
->scan_begin_arg
, arg
);
1283 if (cmd
->convert_src
& (TRIG_TIMER
| TRIG_NOW
)) {
1284 arg
= cmd
->convert_arg
;
1285 comedi_8254_cascade_ns_to_timer(dev
->pacer
, &arg
, cmd
->flags
);
1286 err
|= comedi_check_trigger_arg_is(&cmd
->convert_arg
, arg
);
1288 if (cmd
->scan_begin_src
== TRIG_TIMER
&&
1289 cmd
->convert_src
== TRIG_NOW
) {
1290 if (cmd
->convert_arg
== 0) {
1291 arg
= devpriv
->ai_ns_min
*
1292 (cmd
->scan_end_arg
+ 2);
1294 arg
= cmd
->convert_arg
* cmd
->chanlist_len
;
1296 err
|= comedi_check_trigger_arg_min(&cmd
->
1305 /* Step 5: check channel list if it exists */
1308 err
|= pci9118_ai_check_chanlist(dev
, s
, cmd
);
1316 static int pci9118_ai_eoc(struct comedi_device
*dev
,
1317 struct comedi_subdevice
*s
,
1318 struct comedi_insn
*insn
,
1319 unsigned long context
)
1321 unsigned int status
;
1323 status
= inl(dev
->iobase
+ PCI9118_AI_STATUS_REG
);
1324 if (status
& PCI9118_AI_STATUS_ADRDY
)
1329 static void pci9118_ai_start_conv(struct comedi_device
*dev
)
1331 /* writing any value triggers an A/D conversion */
1332 outl(0, dev
->iobase
+ PCI9118_SOFTTRG_REG
);
1335 static int pci9118_ai_insn_read(struct comedi_device
*dev
,
1336 struct comedi_subdevice
*s
,
1337 struct comedi_insn
*insn
,
1340 struct pci9118_private
*devpriv
= dev
->private;
1346 * Configure analog input based on the chanspec.
1347 * Acqusition is software controlled without interrupts.
1349 pci9118_set_chanlist(dev
, s
, 1, &insn
->chanspec
, 0, 0);
1351 /* set default config (disable burst and triggers) */
1352 devpriv
->ai_cfg
= PCI9118_AI_CFG_PDTRG
| PCI9118_AI_CFG_PETRG
;
1353 outl(devpriv
->ai_cfg
, dev
->iobase
+ PCI9118_AI_CFG_REG
);
1355 pci9118_ai_reset_fifo(dev
);
1357 for (i
= 0; i
< insn
->n
; i
++) {
1358 pci9118_ai_start_conv(dev
);
1360 ret
= comedi_timeout(dev
, s
, insn
, pci9118_ai_eoc
, 0);
1364 val
= inl(dev
->iobase
+ PCI9118_AI_FIFO_REG
);
1365 if (s
->maxdata
== 0xffff)
1366 data
[i
] = (val
& 0xffff) ^ 0x8000;
1368 data
[i
] = (val
>> 4) & 0xfff;
1374 static int pci9118_ao_insn_write(struct comedi_device
*dev
,
1375 struct comedi_subdevice
*s
,
1376 struct comedi_insn
*insn
,
1379 unsigned int chan
= CR_CHAN(insn
->chanspec
);
1380 unsigned int val
= s
->readback
[chan
];
1383 for (i
= 0; i
< insn
->n
; i
++) {
1385 outl(val
, dev
->iobase
+ PCI9118_AO_REG(chan
));
1387 s
->readback
[chan
] = val
;
1392 static int pci9118_di_insn_bits(struct comedi_device
*dev
,
1393 struct comedi_subdevice
*s
,
1394 struct comedi_insn
*insn
,
1398 * The digital inputs and outputs share the read register.
1399 * bits [7:4] are the digital outputs
1400 * bits [3:0] are the digital inputs
1402 data
[1] = inl(dev
->iobase
+ PCI9118_DIO_REG
) & 0xf;
1407 static int pci9118_do_insn_bits(struct comedi_device
*dev
,
1408 struct comedi_subdevice
*s
,
1409 struct comedi_insn
*insn
,
1413 * The digital outputs are set with the same register that
1414 * the digital inputs and outputs are read from. But the
1415 * outputs are set with bits [3:0] so we can simply write
1416 * the s->state to set them.
1418 if (comedi_dio_update_state(s
, data
))
1419 outl(s
->state
, dev
->iobase
+ PCI9118_DIO_REG
);
1426 static void pci9118_reset(struct comedi_device
*dev
)
1428 /* reset analog input subsystem */
1429 outl(0, dev
->iobase
+ PCI9118_INT_CTRL_REG
);
1430 outl(0, dev
->iobase
+ PCI9118_AI_CTRL_REG
);
1431 outl(0, dev
->iobase
+ PCI9118_AI_CFG_REG
);
1432 pci9118_ai_reset_fifo(dev
);
1434 /* clear any pending interrupts and status */
1435 inl(dev
->iobase
+ PCI9118_INT_CTRL_REG
);
1436 inl(dev
->iobase
+ PCI9118_AI_STATUS_REG
);
1438 /* reset DMA and scan queue */
1439 outl(0, dev
->iobase
+ PCI9118_AI_BURST_NUM_REG
);
1440 outl(1, dev
->iobase
+ PCI9118_AI_AUTOSCAN_MODE_REG
);
1441 outl(2, dev
->iobase
+ PCI9118_AI_AUTOSCAN_MODE_REG
);
1443 /* reset analog outputs to 0V */
1444 outl(2047, dev
->iobase
+ PCI9118_AO_REG(0));
1445 outl(2047, dev
->iobase
+ PCI9118_AO_REG(1));
1448 static struct pci_dev
*pci9118_find_pci(struct comedi_device
*dev
,
1449 struct comedi_devconfig
*it
)
1451 struct pci_dev
*pcidev
= NULL
;
1452 int bus
= it
->options
[0];
1453 int slot
= it
->options
[1];
1455 for_each_pci_dev(pcidev
) {
1456 if (pcidev
->vendor
!= PCI_VENDOR_ID_AMCC
)
1458 if (pcidev
->device
!= 0x80d9)
1461 /* requested particular bus/slot */
1462 if (pcidev
->bus
->number
!= bus
||
1463 PCI_SLOT(pcidev
->devfn
) != slot
)
1468 dev_err(dev
->class_dev
,
1469 "no supported board found! (req. bus/slot : %d/%d)\n",
1474 static void pci9118_alloc_dma(struct comedi_device
*dev
)
1476 struct pci9118_private
*devpriv
= dev
->private;
1477 struct pci9118_dmabuf
*dmabuf
;
1481 for (i
= 0; i
< 2; i
++) {
1482 dmabuf
= &devpriv
->dmabuf
[i
];
1483 for (order
= 2; order
>= 0; order
--) {
1485 dma_alloc_coherent(dev
->hw_dev
, PAGE_SIZE
<< order
,
1486 &dmabuf
->hw
, GFP_KERNEL
);
1492 dmabuf
->size
= PAGE_SIZE
<< order
;
1495 devpriv
->master
= 1;
1497 devpriv
->dma_doublebuf
= 1;
1501 static void pci9118_free_dma(struct comedi_device
*dev
)
1503 struct pci9118_private
*devpriv
= dev
->private;
1504 struct pci9118_dmabuf
*dmabuf
;
1510 for (i
= 0; i
< 2; i
++) {
1511 dmabuf
= &devpriv
->dmabuf
[i
];
1513 dma_free_coherent(dev
->hw_dev
, dmabuf
->size
,
1514 dmabuf
->virt
, dmabuf
->hw
);
1519 static int pci9118_common_attach(struct comedi_device
*dev
,
1520 int ext_mux
, int softsshdelay
)
1522 const struct pci9118_boardinfo
*board
= dev
->board_ptr
;
1523 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
1524 struct pci9118_private
*devpriv
;
1525 struct comedi_subdevice
*s
;
1530 devpriv
= comedi_alloc_devpriv(dev
, sizeof(*devpriv
));
1534 ret
= comedi_pci_enable(dev
);
1537 pci_set_master(pcidev
);
1539 devpriv
->iobase_a
= pci_resource_start(pcidev
, 0);
1540 dev
->iobase
= pci_resource_start(pcidev
, 2);
1542 dev
->pacer
= comedi_8254_init(dev
->iobase
+ PCI9118_TIMER_BASE
,
1543 I8254_OSC_BASE_4MHZ
, I8254_IO32
, 0);
1550 ret
= request_irq(pcidev
->irq
, pci9118_interrupt
, IRQF_SHARED
,
1551 dev
->board_name
, dev
);
1553 dev
->irq
= pcidev
->irq
;
1555 pci9118_alloc_dma(dev
);
1561 ext_mux
= 256; /* max 256 channels! */
1562 if (softsshdelay
> 0)
1565 devpriv
->usemux
= 1;
1567 devpriv
->usemux
= 0;
1570 if (softsshdelay
< 0) {
1571 /* select sample&hold signal polarity */
1572 devpriv
->softsshdelay
= -softsshdelay
;
1573 devpriv
->softsshsample
= 0x80;
1574 devpriv
->softsshhold
= 0x00;
1576 devpriv
->softsshdelay
= softsshdelay
;
1577 devpriv
->softsshsample
= 0x00;
1578 devpriv
->softsshhold
= 0x80;
1581 pci_read_config_word(pcidev
, PCI_COMMAND
, &u16w
);
1582 pci_write_config_word(pcidev
, PCI_COMMAND
, u16w
| 64);
1583 /* Enable parity check for parity error */
1585 ret
= comedi_alloc_subdevices(dev
, 4);
1589 /* Analog Input subdevice */
1590 s
= &dev
->subdevices
[0];
1591 s
->type
= COMEDI_SUBD_AI
;
1592 s
->subdev_flags
= SDF_READABLE
| SDF_COMMON
| SDF_GROUND
| SDF_DIFF
;
1593 s
->n_chan
= (devpriv
->usemux
) ? ext_mux
: 16;
1594 s
->maxdata
= board
->ai_is_16bit
? 0xffff : 0x0fff;
1595 s
->range_table
= board
->is_hg
? &pci9118hg_ai_range
1596 : &pci9118_ai_range
;
1597 s
->insn_read
= pci9118_ai_insn_read
;
1599 dev
->read_subdev
= s
;
1600 s
->subdev_flags
|= SDF_CMD_READ
;
1601 s
->len_chanlist
= PCI9118_CHANLEN
;
1602 s
->do_cmdtest
= pci9118_ai_cmdtest
;
1603 s
->do_cmd
= pci9118_ai_cmd
;
1604 s
->cancel
= pci9118_ai_cancel
;
1605 s
->munge
= pci9118_ai_munge
;
1608 if (s
->maxdata
== 0xffff) {
1610 * 16-bit samples are from an ADS7805 A/D converter.
1611 * Minimum sampling rate is 10us.
1613 devpriv
->ai_ns_min
= 10000;
1616 * 12-bit samples are from an ADS7800 A/D converter.
1617 * Minimum sampling rate is 3us.
1619 devpriv
->ai_ns_min
= 3000;
1622 /* Analog Output subdevice */
1623 s
= &dev
->subdevices
[1];
1624 s
->type
= COMEDI_SUBD_AO
;
1625 s
->subdev_flags
= SDF_WRITABLE
| SDF_GROUND
| SDF_COMMON
;
1627 s
->maxdata
= 0x0fff;
1628 s
->range_table
= &range_bipolar10
;
1629 s
->insn_write
= pci9118_ao_insn_write
;
1631 ret
= comedi_alloc_subdev_readback(s
);
1635 /* the analog outputs were reset to 0V, make the readback match */
1636 for (i
= 0; i
< s
->n_chan
; i
++)
1637 s
->readback
[i
] = 2047;
1639 /* Digital Input subdevice */
1640 s
= &dev
->subdevices
[2];
1641 s
->type
= COMEDI_SUBD_DI
;
1642 s
->subdev_flags
= SDF_READABLE
;
1645 s
->range_table
= &range_digital
;
1646 s
->insn_bits
= pci9118_di_insn_bits
;
1648 /* Digital Output subdevice */
1649 s
= &dev
->subdevices
[3];
1650 s
->type
= COMEDI_SUBD_DO
;
1651 s
->subdev_flags
= SDF_WRITABLE
;
1654 s
->range_table
= &range_digital
;
1655 s
->insn_bits
= pci9118_do_insn_bits
;
1657 /* get the current state of the digital outputs */
1658 s
->state
= inl(dev
->iobase
+ PCI9118_DIO_REG
) >> 4;
1663 static int pci9118_attach(struct comedi_device
*dev
,
1664 struct comedi_devconfig
*it
)
1666 struct pci_dev
*pcidev
;
1667 int ext_mux
, softsshdelay
;
1669 ext_mux
= it
->options
[2];
1670 softsshdelay
= it
->options
[4];
1672 pcidev
= pci9118_find_pci(dev
, it
);
1675 comedi_set_hw_dev(dev
, &pcidev
->dev
);
1677 return pci9118_common_attach(dev
, ext_mux
, softsshdelay
);
1680 static int pci9118_auto_attach(struct comedi_device
*dev
,
1681 unsigned long context
)
1683 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
1684 const struct pci9118_boardinfo
*board
= NULL
;
1686 if (context
< ARRAY_SIZE(pci9118_boards
))
1687 board
= &pci9118_boards
[context
];
1690 dev
->board_ptr
= board
;
1691 dev
->board_name
= board
->name
;
1694 * Need to 'get' the PCI device to match the 'put' in pci9118_detach().
1695 * (The 'put' also matches the implicit 'get' by pci9118_find_pci().)
1697 pci_dev_get(pcidev
);
1698 /* no external mux, no sample-hold delay */
1699 return pci9118_common_attach(dev
, 0, 0);
1702 static void pci9118_detach(struct comedi_device
*dev
)
1704 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
1708 comedi_pci_detach(dev
);
1709 pci9118_free_dma(dev
);
1711 pci_dev_put(pcidev
);
1714 static struct comedi_driver adl_pci9118_driver
= {
1715 .driver_name
= "adl_pci9118",
1716 .module
= THIS_MODULE
,
1717 .attach
= pci9118_attach
,
1718 .auto_attach
= pci9118_auto_attach
,
1719 .detach
= pci9118_detach
,
1720 .num_names
= ARRAY_SIZE(pci9118_boards
),
1721 .board_name
= &pci9118_boards
[0].name
,
1722 .offset
= sizeof(struct pci9118_boardinfo
),
1725 static int adl_pci9118_pci_probe(struct pci_dev
*dev
,
1726 const struct pci_device_id
*id
)
1728 return comedi_pci_auto_config(dev
, &adl_pci9118_driver
,
1732 /* FIXME: All the supported board types have the same device ID! */
1733 static const struct pci_device_id adl_pci9118_pci_table
[] = {
1734 { PCI_VDEVICE(AMCC
, 0x80d9), BOARD_PCI9118DG
},
1735 /* { PCI_VDEVICE(AMCC, 0x80d9), BOARD_PCI9118HG }, */
1736 /* { PCI_VDEVICE(AMCC, 0x80d9), BOARD_PCI9118HR }, */
1739 MODULE_DEVICE_TABLE(pci
, adl_pci9118_pci_table
);
1741 static struct pci_driver adl_pci9118_pci_driver
= {
1742 .name
= "adl_pci9118",
1743 .id_table
= adl_pci9118_pci_table
,
1744 .probe
= adl_pci9118_pci_probe
,
1745 .remove
= comedi_pci_auto_unconfig
,
1747 module_comedi_pci_driver(adl_pci9118_driver
, adl_pci9118_pci_driver
);
1749 MODULE_AUTHOR("Comedi http://www.comedi.org");
1750 MODULE_DESCRIPTION("Comedi low-level driver");
1751 MODULE_LICENSE("GPL");