1 // SPDX-License-Identifier: GPL-2.0+
4 * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
9 * Tel: +19(0)7223/9493-0
10 * Fax: +49(0)7223/9493-92
11 * http://www.addi-data.com
15 #include <linux/module.h>
16 #include <linux/interrupt.h>
17 #include <linux/comedi/comedi_pci.h>
19 #include "amcc_s5933.h"
22 * PCI BAR 0 register map (devpriv->amcc)
23 * see amcc_s5933.h for register and bit defines
25 #define APCI3120_FIFO_ADVANCE_ON_BYTE_2 BIT(29)
28 * PCI BAR 1 register map (dev->iobase)
30 #define APCI3120_AI_FIFO_REG 0x00
31 #define APCI3120_CTRL_REG 0x00
32 #define APCI3120_CTRL_EXT_TRIG BIT(15)
33 #define APCI3120_CTRL_GATE(x) BIT(12 + (x))
34 #define APCI3120_CTRL_PR(x) (((x) & 0xf) << 8)
35 #define APCI3120_CTRL_PA(x) (((x) & 0xf) << 0)
36 #define APCI3120_AI_SOFTTRIG_REG 0x02
37 #define APCI3120_STATUS_REG 0x02
38 #define APCI3120_STATUS_EOC_INT BIT(15)
39 #define APCI3120_STATUS_AMCC_INT BIT(14)
40 #define APCI3120_STATUS_EOS_INT BIT(13)
41 #define APCI3120_STATUS_TIMER2_INT BIT(12)
42 #define APCI3120_STATUS_INT_MASK (0xf << 12)
43 #define APCI3120_STATUS_TO_DI_BITS(x) (((x) >> 8) & 0xf)
44 #define APCI3120_STATUS_TO_VERSION(x) (((x) >> 4) & 0xf)
45 #define APCI3120_STATUS_FIFO_FULL BIT(2)
46 #define APCI3120_STATUS_FIFO_EMPTY BIT(1)
47 #define APCI3120_STATUS_DA_READY BIT(0)
48 #define APCI3120_TIMER_REG 0x04
49 #define APCI3120_CHANLIST_REG 0x06
50 #define APCI3120_CHANLIST_INDEX(x) (((x) & 0xf) << 8)
51 #define APCI3120_CHANLIST_UNIPOLAR BIT(7)
52 #define APCI3120_CHANLIST_GAIN(x) (((x) & 0x3) << 4)
53 #define APCI3120_CHANLIST_MUX(x) (((x) & 0xf) << 0)
54 #define APCI3120_AO_REG(x) (0x08 + (((x) / 4) * 2))
55 #define APCI3120_AO_MUX(x) (((x) & 0x3) << 14)
56 #define APCI3120_AO_DATA(x) ((x) << 0)
57 #define APCI3120_TIMER_MODE_REG 0x0c
58 #define APCI3120_TIMER_MODE(_t, _m) ((_m) << ((_t) * 2))
59 #define APCI3120_TIMER_MODE0 0 /* I8254_MODE0 */
60 #define APCI3120_TIMER_MODE2 1 /* I8254_MODE2 */
61 #define APCI3120_TIMER_MODE4 2 /* I8254_MODE4 */
62 #define APCI3120_TIMER_MODE5 3 /* I8254_MODE5 */
63 #define APCI3120_TIMER_MODE_MASK(_t) (3 << ((_t) * 2))
64 #define APCI3120_CTR0_REG 0x0d
65 #define APCI3120_CTR0_DO_BITS(x) ((x) << 4)
66 #define APCI3120_CTR0_TIMER_SEL(x) ((x) << 0)
67 #define APCI3120_MODE_REG 0x0e
68 #define APCI3120_MODE_TIMER2_CLK(x) (((x) & 0x3) << 6)
69 #define APCI3120_MODE_TIMER2_CLK_OSC APCI3120_MODE_TIMER2_CLK(0)
70 #define APCI3120_MODE_TIMER2_CLK_OUT1 APCI3120_MODE_TIMER2_CLK(1)
71 #define APCI3120_MODE_TIMER2_CLK_EOC APCI3120_MODE_TIMER2_CLK(2)
72 #define APCI3120_MODE_TIMER2_CLK_EOS APCI3120_MODE_TIMER2_CLK(3)
73 #define APCI3120_MODE_TIMER2_CLK_MASK APCI3120_MODE_TIMER2_CLK(3)
74 #define APCI3120_MODE_TIMER2_AS(x) (((x) & 0x3) << 4)
75 #define APCI3120_MODE_TIMER2_AS_TIMER APCI3120_MODE_TIMER2_AS(0)
76 #define APCI3120_MODE_TIMER2_AS_COUNTER APCI3120_MODE_TIMER2_AS(1)
77 #define APCI3120_MODE_TIMER2_AS_WDOG APCI3120_MODE_TIMER2_AS(2)
78 #define APCI3120_MODE_TIMER2_AS_MASK APCI3120_MODE_TIMER2_AS(3)
79 #define APCI3120_MODE_SCAN_ENA BIT(3)
80 #define APCI3120_MODE_TIMER2_IRQ_ENA BIT(2)
81 #define APCI3120_MODE_EOS_IRQ_ENA BIT(1)
82 #define APCI3120_MODE_EOC_IRQ_ENA BIT(0)
85 * PCI BAR 2 register map (devpriv->addon)
87 #define APCI3120_ADDON_ADDR_REG 0x00
88 #define APCI3120_ADDON_DATA_REG 0x02
89 #define APCI3120_ADDON_CTRL_REG 0x04
90 #define APCI3120_ADDON_CTRL_AMWEN_ENA BIT(1)
91 #define APCI3120_ADDON_CTRL_A2P_FIFO_ENA BIT(0)
96 #define APCI3120_REVA 0xa
97 #define APCI3120_REVB 0xb
98 #define APCI3120_REVA_OSC_BASE 70 /* 70ns = 14.29MHz */
99 #define APCI3120_REVB_OSC_BASE 50 /* 50ns = 20MHz */
101 static const struct comedi_lrange apci3120_ai_range
= {
114 enum apci3120_boardid
{
119 struct apci3120_board
{
121 unsigned int ai_is_16bit
:1;
122 unsigned int has_ao
:1;
125 static const struct apci3120_board apci3120_boardtypes
[] = {
136 struct apci3120_dmabuf
{
137 unsigned short *virt
;
140 unsigned int use_size
;
143 struct apci3120_private
{
146 unsigned int osc_base
;
147 unsigned int use_dma
:1;
148 unsigned int use_double_buffer
:1;
149 unsigned int cur_dmabuf
:1;
150 struct apci3120_dmabuf dmabuf
[2];
151 unsigned char do_bits
;
152 unsigned char timer_mode
;
157 static void apci3120_addon_write(struct comedi_device
*dev
,
158 unsigned int val
, unsigned int reg
)
160 struct apci3120_private
*devpriv
= dev
->private;
162 /* 16-bit interface for AMCC add-on registers */
164 outw(reg
, devpriv
->addon
+ APCI3120_ADDON_ADDR_REG
);
165 outw(val
& 0xffff, devpriv
->addon
+ APCI3120_ADDON_DATA_REG
);
167 outw(reg
+ 2, devpriv
->addon
+ APCI3120_ADDON_ADDR_REG
);
168 outw((val
>> 16) & 0xffff, devpriv
->addon
+ APCI3120_ADDON_DATA_REG
);
171 static void apci3120_init_dma(struct comedi_device
*dev
,
172 struct apci3120_dmabuf
*dmabuf
)
174 struct apci3120_private
*devpriv
= dev
->private;
176 /* AMCC - enable transfer count and reset A2P FIFO */
177 outl(AGCSTS_TC_ENABLE
| AGCSTS_RESET_A2P_FIFO
,
178 devpriv
->amcc
+ AMCC_OP_REG_AGCSTS
);
180 /* Add-On - enable transfer count and reset A2P FIFO */
181 apci3120_addon_write(dev
, AGCSTS_TC_ENABLE
| AGCSTS_RESET_A2P_FIFO
,
184 /* AMCC - enable transfers and reset A2P flags */
185 outl(RESET_A2P_FLAGS
| EN_A2P_TRANSFERS
,
186 devpriv
->amcc
+ AMCC_OP_REG_MCSR
);
188 /* Add-On - DMA start address */
189 apci3120_addon_write(dev
, dmabuf
->hw
, AMCC_OP_REG_AMWAR
);
191 /* Add-On - Number of acquisitions */
192 apci3120_addon_write(dev
, dmabuf
->use_size
, AMCC_OP_REG_AMWTC
);
194 /* AMCC - enable write complete (DMA) and set FIFO advance */
195 outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2
| AINT_WRITE_COMPL
,
196 devpriv
->amcc
+ AMCC_OP_REG_INTCSR
);
198 /* Add-On - enable DMA */
199 outw(APCI3120_ADDON_CTRL_AMWEN_ENA
| APCI3120_ADDON_CTRL_A2P_FIFO_ENA
,
200 devpriv
->addon
+ APCI3120_ADDON_CTRL_REG
);
203 static void apci3120_setup_dma(struct comedi_device
*dev
,
204 struct comedi_subdevice
*s
)
206 struct apci3120_private
*devpriv
= dev
->private;
207 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
208 struct apci3120_dmabuf
*dmabuf0
= &devpriv
->dmabuf
[0];
209 struct apci3120_dmabuf
*dmabuf1
= &devpriv
->dmabuf
[1];
210 unsigned int dmalen0
= dmabuf0
->size
;
211 unsigned int dmalen1
= dmabuf1
->size
;
212 unsigned int scan_bytes
;
214 scan_bytes
= comedi_samples_to_bytes(s
, cmd
->scan_end_arg
);
216 if (cmd
->stop_src
== TRIG_COUNT
) {
218 * Must we fill full first buffer? And must we fill
219 * full second buffer when first is once filled?
221 if (dmalen0
> (cmd
->stop_arg
* scan_bytes
))
222 dmalen0
= cmd
->stop_arg
* scan_bytes
;
223 else if (dmalen1
> (cmd
->stop_arg
* scan_bytes
- dmalen0
))
224 dmalen1
= cmd
->stop_arg
* scan_bytes
- dmalen0
;
227 if (cmd
->flags
& CMDF_WAKE_EOS
) {
228 /* don't we want wake up every scan? */
229 if (dmalen0
> scan_bytes
) {
230 dmalen0
= scan_bytes
;
231 if (cmd
->scan_end_arg
& 1)
234 if (dmalen1
> scan_bytes
) {
235 dmalen1
= scan_bytes
;
236 if (cmd
->scan_end_arg
& 1)
242 /* isn't output buff smaller that our DMA buff? */
243 if (dmalen0
> s
->async
->prealloc_bufsz
)
244 dmalen0
= s
->async
->prealloc_bufsz
;
245 if (dmalen1
> s
->async
->prealloc_bufsz
)
246 dmalen1
= s
->async
->prealloc_bufsz
;
248 dmabuf0
->use_size
= dmalen0
;
249 dmabuf1
->use_size
= dmalen1
;
251 apci3120_init_dma(dev
, dmabuf0
);
255 * There are three timers on the board. They all use the same base
256 * clock with a fixed prescaler for each timer. The base clock used
257 * depends on the board version and type.
259 * APCI-3120 Rev A boards OSC = 14.29MHz base clock (~70ns)
260 * APCI-3120 Rev B boards OSC = 20MHz base clock (50ns)
261 * APCI-3001 boards OSC = 20MHz base clock (50ns)
263 * The prescalers for each timer are:
264 * Timer 0 CLK = OSC/10
265 * Timer 1 CLK = OSC/1000
266 * Timer 2 CLK = OSC/1000
268 static unsigned int apci3120_ns_to_timer(struct comedi_device
*dev
,
273 struct apci3120_private
*devpriv
= dev
->private;
274 unsigned int prescale
= (timer
== 0) ? 10 : 1000;
275 unsigned int timer_base
= devpriv
->osc_base
* prescale
;
276 unsigned int divisor
;
278 switch (flags
& CMDF_ROUND_MASK
) {
280 divisor
= DIV_ROUND_UP(ns
, timer_base
);
282 case CMDF_ROUND_DOWN
:
283 divisor
= ns
/ timer_base
;
285 case CMDF_ROUND_NEAREST
:
287 divisor
= DIV_ROUND_CLOSEST(ns
, timer_base
);
292 /* timer 2 is 24-bits */
293 if (divisor
> 0x00ffffff)
294 divisor
= 0x00ffffff;
296 /* timers 0 and 1 are 16-bits */
297 if (divisor
> 0xffff)
300 /* the timers require a minimum divisor of 2 */
307 static void apci3120_clr_timer2_interrupt(struct comedi_device
*dev
)
309 /* a dummy read of APCI3120_CTR0_REG clears the timer 2 interrupt */
310 inb(dev
->iobase
+ APCI3120_CTR0_REG
);
313 static void apci3120_timer_write(struct comedi_device
*dev
,
314 unsigned int timer
, unsigned int val
)
316 struct apci3120_private
*devpriv
= dev
->private;
318 /* write 16-bit value to timer (lower 16-bits of timer 2) */
319 outb(APCI3120_CTR0_DO_BITS(devpriv
->do_bits
) |
320 APCI3120_CTR0_TIMER_SEL(timer
),
321 dev
->iobase
+ APCI3120_CTR0_REG
);
322 outw(val
& 0xffff, dev
->iobase
+ APCI3120_TIMER_REG
);
325 /* write upper 16-bits to timer 2 */
326 outb(APCI3120_CTR0_DO_BITS(devpriv
->do_bits
) |
327 APCI3120_CTR0_TIMER_SEL(timer
+ 1),
328 dev
->iobase
+ APCI3120_CTR0_REG
);
329 outw((val
>> 16) & 0xffff, dev
->iobase
+ APCI3120_TIMER_REG
);
333 static unsigned int apci3120_timer_read(struct comedi_device
*dev
,
336 struct apci3120_private
*devpriv
= dev
->private;
339 /* read 16-bit value from timer (lower 16-bits of timer 2) */
340 outb(APCI3120_CTR0_DO_BITS(devpriv
->do_bits
) |
341 APCI3120_CTR0_TIMER_SEL(timer
),
342 dev
->iobase
+ APCI3120_CTR0_REG
);
343 val
= inw(dev
->iobase
+ APCI3120_TIMER_REG
);
346 /* read upper 16-bits from timer 2 */
347 outb(APCI3120_CTR0_DO_BITS(devpriv
->do_bits
) |
348 APCI3120_CTR0_TIMER_SEL(timer
+ 1),
349 dev
->iobase
+ APCI3120_CTR0_REG
);
350 val
|= (inw(dev
->iobase
+ APCI3120_TIMER_REG
) << 16);
356 static void apci3120_timer_set_mode(struct comedi_device
*dev
,
357 unsigned int timer
, unsigned int mode
)
359 struct apci3120_private
*devpriv
= dev
->private;
361 devpriv
->timer_mode
&= ~APCI3120_TIMER_MODE_MASK(timer
);
362 devpriv
->timer_mode
|= APCI3120_TIMER_MODE(timer
, mode
);
363 outb(devpriv
->timer_mode
, dev
->iobase
+ APCI3120_TIMER_MODE_REG
);
366 static void apci3120_timer_enable(struct comedi_device
*dev
,
367 unsigned int timer
, bool enable
)
369 struct apci3120_private
*devpriv
= dev
->private;
372 devpriv
->ctrl
|= APCI3120_CTRL_GATE(timer
);
374 devpriv
->ctrl
&= ~APCI3120_CTRL_GATE(timer
);
375 outw(devpriv
->ctrl
, dev
->iobase
+ APCI3120_CTRL_REG
);
378 static void apci3120_exttrig_enable(struct comedi_device
*dev
, bool enable
)
380 struct apci3120_private
*devpriv
= dev
->private;
383 devpriv
->ctrl
|= APCI3120_CTRL_EXT_TRIG
;
385 devpriv
->ctrl
&= ~APCI3120_CTRL_EXT_TRIG
;
386 outw(devpriv
->ctrl
, dev
->iobase
+ APCI3120_CTRL_REG
);
389 static void apci3120_set_chanlist(struct comedi_device
*dev
,
390 struct comedi_subdevice
*s
,
391 int n_chan
, unsigned int *chanlist
)
393 struct apci3120_private
*devpriv
= dev
->private;
396 /* set chanlist for scan */
397 for (i
= 0; i
< n_chan
; i
++) {
398 unsigned int chan
= CR_CHAN(chanlist
[i
]);
399 unsigned int range
= CR_RANGE(chanlist
[i
]);
402 val
= APCI3120_CHANLIST_MUX(chan
) |
403 APCI3120_CHANLIST_GAIN(range
) |
404 APCI3120_CHANLIST_INDEX(i
);
406 if (comedi_range_is_unipolar(s
, range
))
407 val
|= APCI3120_CHANLIST_UNIPOLAR
;
409 outw(val
, dev
->iobase
+ APCI3120_CHANLIST_REG
);
412 /* a dummy read of APCI3120_TIMER_MODE_REG resets the ai FIFO */
413 inw(dev
->iobase
+ APCI3120_TIMER_MODE_REG
);
415 /* set scan length (PR) and scan start (PA) */
416 devpriv
->ctrl
= APCI3120_CTRL_PR(n_chan
- 1) | APCI3120_CTRL_PA(0);
417 outw(devpriv
->ctrl
, dev
->iobase
+ APCI3120_CTRL_REG
);
419 /* enable chanlist scanning if necessary */
421 devpriv
->mode
|= APCI3120_MODE_SCAN_ENA
;
424 static void apci3120_interrupt_dma(struct comedi_device
*dev
,
425 struct comedi_subdevice
*s
)
427 struct apci3120_private
*devpriv
= dev
->private;
428 struct comedi_async
*async
= s
->async
;
429 struct comedi_cmd
*cmd
= &async
->cmd
;
430 struct apci3120_dmabuf
*dmabuf
;
432 unsigned int nsamples
;
434 dmabuf
= &devpriv
->dmabuf
[devpriv
->cur_dmabuf
];
436 nbytes
= dmabuf
->use_size
- inl(devpriv
->amcc
+ AMCC_OP_REG_MWTC
);
438 if (nbytes
< dmabuf
->use_size
)
439 dev_err(dev
->class_dev
, "Interrupted DMA transfer!\n");
441 dev_err(dev
->class_dev
, "Odd count of bytes in DMA ring!\n");
442 async
->events
|= COMEDI_CB_ERROR
;
446 nsamples
= comedi_bytes_to_samples(s
, nbytes
);
448 comedi_buf_write_samples(s
, dmabuf
->virt
, nsamples
);
450 if (!(cmd
->flags
& CMDF_WAKE_EOS
))
451 async
->events
|= COMEDI_CB_EOS
;
454 if ((async
->events
& COMEDI_CB_CANCEL_MASK
) ||
455 (cmd
->stop_src
== TRIG_COUNT
&& async
->scans_done
>= cmd
->stop_arg
))
458 if (devpriv
->use_double_buffer
) {
459 /* switch DMA buffers for next interrupt */
460 devpriv
->cur_dmabuf
= !devpriv
->cur_dmabuf
;
461 dmabuf
= &devpriv
->dmabuf
[devpriv
->cur_dmabuf
];
462 apci3120_init_dma(dev
, dmabuf
);
464 /* restart DMA if not using double buffering */
465 apci3120_init_dma(dev
, dmabuf
);
469 static irqreturn_t
apci3120_interrupt(int irq
, void *d
)
471 struct comedi_device
*dev
= d
;
472 struct apci3120_private
*devpriv
= dev
->private;
473 struct comedi_subdevice
*s
= dev
->read_subdev
;
474 struct comedi_async
*async
= s
->async
;
475 struct comedi_cmd
*cmd
= &async
->cmd
;
477 unsigned int int_amcc
;
479 status
= inw(dev
->iobase
+ APCI3120_STATUS_REG
);
480 int_amcc
= inl(devpriv
->amcc
+ AMCC_OP_REG_INTCSR
);
482 if (!(status
& APCI3120_STATUS_INT_MASK
) &&
483 !(int_amcc
& ANY_S593X_INT
)) {
484 dev_err(dev
->class_dev
, "IRQ from unknown source\n");
488 outl(int_amcc
| AINT_INT_MASK
, devpriv
->amcc
+ AMCC_OP_REG_INTCSR
);
490 if (devpriv
->ctrl
& APCI3120_CTRL_EXT_TRIG
)
491 apci3120_exttrig_enable(dev
, false);
493 if (int_amcc
& MASTER_ABORT_INT
)
494 dev_err(dev
->class_dev
, "AMCC IRQ - MASTER DMA ABORT!\n");
495 if (int_amcc
& TARGET_ABORT_INT
)
496 dev_err(dev
->class_dev
, "AMCC IRQ - TARGET DMA ABORT!\n");
498 if ((status
& APCI3120_STATUS_EOS_INT
) &&
499 (devpriv
->mode
& APCI3120_MODE_EOS_IRQ_ENA
)) {
503 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
504 val
= inw(dev
->iobase
+ APCI3120_AI_FIFO_REG
);
505 comedi_buf_write_samples(s
, &val
, 1);
508 devpriv
->mode
|= APCI3120_MODE_EOS_IRQ_ENA
;
509 outb(devpriv
->mode
, dev
->iobase
+ APCI3120_MODE_REG
);
512 if (status
& APCI3120_STATUS_TIMER2_INT
) {
515 * timer2 interrupts are not enabled in the driver
517 apci3120_clr_timer2_interrupt(dev
);
520 if (status
& APCI3120_STATUS_AMCC_INT
) {
521 /* AMCC- Clear write complete interrupt (DMA) */
522 outl(AINT_WT_COMPLETE
, devpriv
->amcc
+ AMCC_OP_REG_INTCSR
);
524 /* do some data transfer */
525 apci3120_interrupt_dma(dev
, s
);
528 if (cmd
->stop_src
== TRIG_COUNT
&& async
->scans_done
>= cmd
->stop_arg
)
529 async
->events
|= COMEDI_CB_EOA
;
531 comedi_handle_events(dev
, s
);
536 static int apci3120_ai_cmd(struct comedi_device
*dev
,
537 struct comedi_subdevice
*s
)
539 struct apci3120_private
*devpriv
= dev
->private;
540 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
541 unsigned int divisor
;
543 /* set default mode bits */
544 devpriv
->mode
= APCI3120_MODE_TIMER2_CLK_OSC
|
545 APCI3120_MODE_TIMER2_AS_TIMER
;
547 /* AMCC- Clear write complete interrupt (DMA) */
548 outl(AINT_WT_COMPLETE
, devpriv
->amcc
+ AMCC_OP_REG_INTCSR
);
550 devpriv
->cur_dmabuf
= 0;
552 /* load chanlist for command scan */
553 apci3120_set_chanlist(dev
, s
, cmd
->chanlist_len
, cmd
->chanlist
);
555 if (cmd
->start_src
== TRIG_EXT
)
556 apci3120_exttrig_enable(dev
, true);
558 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
560 * Timer 1 is used in MODE2 (rate generator) to set the
561 * start time for each scan.
563 divisor
= apci3120_ns_to_timer(dev
, 1, cmd
->scan_begin_arg
,
565 apci3120_timer_set_mode(dev
, 1, APCI3120_TIMER_MODE2
);
566 apci3120_timer_write(dev
, 1, divisor
);
570 * Timer 0 is used in MODE2 (rate generator) to set the conversion
571 * time for each acquisition.
573 divisor
= apci3120_ns_to_timer(dev
, 0, cmd
->convert_arg
, cmd
->flags
);
574 apci3120_timer_set_mode(dev
, 0, APCI3120_TIMER_MODE2
);
575 apci3120_timer_write(dev
, 0, divisor
);
577 if (devpriv
->use_dma
)
578 apci3120_setup_dma(dev
, s
);
580 devpriv
->mode
|= APCI3120_MODE_EOS_IRQ_ENA
;
582 /* set mode to enable acquisition */
583 outb(devpriv
->mode
, dev
->iobase
+ APCI3120_MODE_REG
);
585 if (cmd
->scan_begin_src
== TRIG_TIMER
)
586 apci3120_timer_enable(dev
, 1, true);
587 apci3120_timer_enable(dev
, 0, true);
592 static int apci3120_ai_cmdtest(struct comedi_device
*dev
,
593 struct comedi_subdevice
*s
,
594 struct comedi_cmd
*cmd
)
599 /* Step 1 : check if triggers are trivially valid */
601 err
|= comedi_check_trigger_src(&cmd
->start_src
, TRIG_NOW
| TRIG_EXT
);
602 err
|= comedi_check_trigger_src(&cmd
->scan_begin_src
,
603 TRIG_TIMER
| TRIG_FOLLOW
);
604 err
|= comedi_check_trigger_src(&cmd
->convert_src
, TRIG_TIMER
);
605 err
|= comedi_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
606 err
|= comedi_check_trigger_src(&cmd
->stop_src
, TRIG_COUNT
| TRIG_NONE
);
611 /* Step 2a : make sure trigger sources are unique */
613 err
|= comedi_check_trigger_is_unique(cmd
->start_src
);
614 err
|= comedi_check_trigger_is_unique(cmd
->scan_begin_src
);
615 err
|= comedi_check_trigger_is_unique(cmd
->stop_src
);
617 /* Step 2b : and mutually compatible */
622 /* Step 3: check if arguments are trivially valid */
624 err
|= comedi_check_trigger_arg_is(&cmd
->start_arg
, 0);
626 if (cmd
->scan_begin_src
== TRIG_TIMER
) { /* Test Delay timing */
627 err
|= comedi_check_trigger_arg_min(&cmd
->scan_begin_arg
,
631 /* minimum conversion time per sample is 10us */
632 err
|= comedi_check_trigger_arg_min(&cmd
->convert_arg
, 10000);
634 err
|= comedi_check_trigger_arg_min(&cmd
->chanlist_len
, 1);
635 err
|= comedi_check_trigger_arg_is(&cmd
->scan_end_arg
,
638 if (cmd
->stop_src
== TRIG_COUNT
)
639 err
|= comedi_check_trigger_arg_min(&cmd
->stop_arg
, 1);
641 err
|= comedi_check_trigger_arg_is(&cmd
->stop_arg
, 0);
646 /* Step 4: fix up any arguments */
648 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
649 /* scan begin must be larger than the scan time */
650 arg
= cmd
->convert_arg
* cmd
->scan_end_arg
;
651 err
|= comedi_check_trigger_arg_min(&cmd
->scan_begin_arg
, arg
);
657 /* Step 5: check channel list if it exists */
662 static int apci3120_cancel(struct comedi_device
*dev
,
663 struct comedi_subdevice
*s
)
665 struct apci3120_private
*devpriv
= dev
->private;
667 /* Add-On - disable DMA */
668 outw(0, devpriv
->addon
+ 4);
670 /* Add-On - disable bus master */
671 apci3120_addon_write(dev
, 0, AMCC_OP_REG_AGCSTS
);
673 /* AMCC - disable bus master */
674 outl(0, devpriv
->amcc
+ AMCC_OP_REG_MCSR
);
676 /* disable all counters, ext trigger, and reset scan */
678 outw(devpriv
->ctrl
, dev
->iobase
+ APCI3120_CTRL_REG
);
680 /* DISABLE_ALL_INTERRUPT */
682 outb(devpriv
->mode
, dev
->iobase
+ APCI3120_MODE_REG
);
684 inw(dev
->iobase
+ APCI3120_STATUS_REG
);
685 devpriv
->cur_dmabuf
= 0;
690 static int apci3120_ai_eoc(struct comedi_device
*dev
,
691 struct comedi_subdevice
*s
,
692 struct comedi_insn
*insn
,
693 unsigned long context
)
697 status
= inw(dev
->iobase
+ APCI3120_STATUS_REG
);
698 if ((status
& APCI3120_STATUS_EOC_INT
) == 0)
703 static int apci3120_ai_insn_read(struct comedi_device
*dev
,
704 struct comedi_subdevice
*s
,
705 struct comedi_insn
*insn
,
708 struct apci3120_private
*devpriv
= dev
->private;
709 unsigned int divisor
;
713 /* set mode for A/D conversions by software trigger with timer 0 */
714 devpriv
->mode
= APCI3120_MODE_TIMER2_CLK_OSC
|
715 APCI3120_MODE_TIMER2_AS_TIMER
;
716 outb(devpriv
->mode
, dev
->iobase
+ APCI3120_MODE_REG
);
718 /* load chanlist for single channel scan */
719 apci3120_set_chanlist(dev
, s
, 1, &insn
->chanspec
);
722 * Timer 0 is used in MODE4 (software triggered strobe) to set the
723 * conversion time for each acquisition. Each conversion is triggered
724 * when the divisor is written to the timer, The conversion is done
725 * when the EOC bit in the status register is '0'.
727 apci3120_timer_set_mode(dev
, 0, APCI3120_TIMER_MODE4
);
728 apci3120_timer_enable(dev
, 0, true);
730 /* fixed conversion time of 10 us */
731 divisor
= apci3120_ns_to_timer(dev
, 0, 10000, CMDF_ROUND_NEAREST
);
733 for (i
= 0; i
< insn
->n
; i
++) {
734 /* trigger conversion */
735 apci3120_timer_write(dev
, 0, divisor
);
737 ret
= comedi_timeout(dev
, s
, insn
, apci3120_ai_eoc
, 0);
741 data
[i
] = inw(dev
->iobase
+ APCI3120_AI_FIFO_REG
);
747 static int apci3120_ao_ready(struct comedi_device
*dev
,
748 struct comedi_subdevice
*s
,
749 struct comedi_insn
*insn
,
750 unsigned long context
)
754 status
= inw(dev
->iobase
+ APCI3120_STATUS_REG
);
755 if (status
& APCI3120_STATUS_DA_READY
)
760 static int apci3120_ao_insn_write(struct comedi_device
*dev
,
761 struct comedi_subdevice
*s
,
762 struct comedi_insn
*insn
,
765 unsigned int chan
= CR_CHAN(insn
->chanspec
);
768 for (i
= 0; i
< insn
->n
; i
++) {
769 unsigned int val
= data
[i
];
772 ret
= comedi_timeout(dev
, s
, insn
, apci3120_ao_ready
, 0);
776 outw(APCI3120_AO_MUX(chan
) | APCI3120_AO_DATA(val
),
777 dev
->iobase
+ APCI3120_AO_REG(chan
));
779 s
->readback
[chan
] = val
;
785 static int apci3120_di_insn_bits(struct comedi_device
*dev
,
786 struct comedi_subdevice
*s
,
787 struct comedi_insn
*insn
,
792 status
= inw(dev
->iobase
+ APCI3120_STATUS_REG
);
793 data
[1] = APCI3120_STATUS_TO_DI_BITS(status
);
798 static int apci3120_do_insn_bits(struct comedi_device
*dev
,
799 struct comedi_subdevice
*s
,
800 struct comedi_insn
*insn
,
803 struct apci3120_private
*devpriv
= dev
->private;
805 if (comedi_dio_update_state(s
, data
)) {
806 devpriv
->do_bits
= s
->state
;
807 outb(APCI3120_CTR0_DO_BITS(devpriv
->do_bits
),
808 dev
->iobase
+ APCI3120_CTR0_REG
);
816 static int apci3120_timer_insn_config(struct comedi_device
*dev
,
817 struct comedi_subdevice
*s
,
818 struct comedi_insn
*insn
,
821 struct apci3120_private
*devpriv
= dev
->private;
822 unsigned int divisor
;
825 unsigned int timer_mode
;
828 case INSN_CONFIG_ARM
:
829 apci3120_clr_timer2_interrupt(dev
);
830 divisor
= apci3120_ns_to_timer(dev
, 2, data
[1],
832 apci3120_timer_write(dev
, 2, divisor
);
833 apci3120_timer_enable(dev
, 2, true);
836 case INSN_CONFIG_DISARM
:
837 apci3120_timer_enable(dev
, 2, false);
838 apci3120_clr_timer2_interrupt(dev
);
841 case INSN_CONFIG_GET_COUNTER_STATUS
:
843 data
[2] = COMEDI_COUNTER_ARMED
| COMEDI_COUNTER_COUNTING
|
844 COMEDI_COUNTER_TERMINAL_COUNT
;
846 if (devpriv
->ctrl
& APCI3120_CTRL_GATE(2)) {
847 data
[1] |= COMEDI_COUNTER_ARMED
;
848 data
[1] |= COMEDI_COUNTER_COUNTING
;
850 status
= inw(dev
->iobase
+ APCI3120_STATUS_REG
);
851 if (status
& APCI3120_STATUS_TIMER2_INT
) {
852 data
[1] &= ~COMEDI_COUNTER_COUNTING
;
853 data
[1] |= COMEDI_COUNTER_TERMINAL_COUNT
;
857 case INSN_CONFIG_SET_COUNTER_MODE
:
860 mode
= APCI3120_MODE_TIMER2_AS_COUNTER
;
861 timer_mode
= APCI3120_TIMER_MODE0
;
864 mode
= APCI3120_MODE_TIMER2_AS_TIMER
;
865 timer_mode
= APCI3120_TIMER_MODE2
;
868 mode
= APCI3120_MODE_TIMER2_AS_TIMER
;
869 timer_mode
= APCI3120_TIMER_MODE4
;
872 mode
= APCI3120_MODE_TIMER2_AS_WDOG
;
873 timer_mode
= APCI3120_TIMER_MODE5
;
878 apci3120_timer_enable(dev
, 2, false);
879 apci3120_clr_timer2_interrupt(dev
);
880 apci3120_timer_set_mode(dev
, 2, timer_mode
);
881 devpriv
->mode
&= ~APCI3120_MODE_TIMER2_AS_MASK
;
882 devpriv
->mode
|= mode
;
883 outb(devpriv
->mode
, dev
->iobase
+ APCI3120_MODE_REG
);
893 static int apci3120_timer_insn_read(struct comedi_device
*dev
,
894 struct comedi_subdevice
*s
,
895 struct comedi_insn
*insn
,
900 for (i
= 0; i
< insn
->n
; i
++)
901 data
[i
] = apci3120_timer_read(dev
, 2);
906 static void apci3120_dma_alloc(struct comedi_device
*dev
)
908 struct apci3120_private
*devpriv
= dev
->private;
909 struct apci3120_dmabuf
*dmabuf
;
913 for (i
= 0; i
< 2; i
++) {
914 dmabuf
= &devpriv
->dmabuf
[i
];
915 for (order
= 2; order
>= 0; order
--) {
916 dmabuf
->virt
= dma_alloc_coherent(dev
->hw_dev
,
925 dmabuf
->size
= PAGE_SIZE
<< order
;
928 devpriv
->use_dma
= 1;
930 devpriv
->use_double_buffer
= 1;
934 static void apci3120_dma_free(struct comedi_device
*dev
)
936 struct apci3120_private
*devpriv
= dev
->private;
937 struct apci3120_dmabuf
*dmabuf
;
943 for (i
= 0; i
< 2; i
++) {
944 dmabuf
= &devpriv
->dmabuf
[i
];
946 dma_free_coherent(dev
->hw_dev
, dmabuf
->size
,
947 dmabuf
->virt
, dmabuf
->hw
);
952 static void apci3120_reset(struct comedi_device
*dev
)
954 /* disable all interrupt sources */
955 outb(0, dev
->iobase
+ APCI3120_MODE_REG
);
957 /* disable all counters, ext trigger, and reset scan */
958 outw(0, dev
->iobase
+ APCI3120_CTRL_REG
);
960 /* clear interrupt status */
961 inw(dev
->iobase
+ APCI3120_STATUS_REG
);
964 static int apci3120_auto_attach(struct comedi_device
*dev
,
965 unsigned long context
)
967 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
968 const struct apci3120_board
*board
= NULL
;
969 struct apci3120_private
*devpriv
;
970 struct comedi_subdevice
*s
;
974 if (context
< ARRAY_SIZE(apci3120_boardtypes
))
975 board
= &apci3120_boardtypes
[context
];
978 dev
->board_ptr
= board
;
979 dev
->board_name
= board
->name
;
981 devpriv
= comedi_alloc_devpriv(dev
, sizeof(*devpriv
));
985 ret
= comedi_pci_enable(dev
);
988 pci_set_master(pcidev
);
990 dev
->iobase
= pci_resource_start(pcidev
, 1);
991 devpriv
->amcc
= pci_resource_start(pcidev
, 0);
992 devpriv
->addon
= pci_resource_start(pcidev
, 2);
996 if (pcidev
->irq
> 0) {
997 ret
= request_irq(pcidev
->irq
, apci3120_interrupt
, IRQF_SHARED
,
998 dev
->board_name
, dev
);
1000 dev
->irq
= pcidev
->irq
;
1002 apci3120_dma_alloc(dev
);
1006 status
= inw(dev
->iobase
+ APCI3120_STATUS_REG
);
1007 if (APCI3120_STATUS_TO_VERSION(status
) == APCI3120_REVB
||
1008 context
== BOARD_APCI3001
)
1009 devpriv
->osc_base
= APCI3120_REVB_OSC_BASE
;
1011 devpriv
->osc_base
= APCI3120_REVA_OSC_BASE
;
1013 ret
= comedi_alloc_subdevices(dev
, 5);
1017 /* Analog Input subdevice */
1018 s
= &dev
->subdevices
[0];
1019 s
->type
= COMEDI_SUBD_AI
;
1020 s
->subdev_flags
= SDF_READABLE
| SDF_COMMON
| SDF_GROUND
| SDF_DIFF
;
1022 s
->maxdata
= board
->ai_is_16bit
? 0xffff : 0x0fff;
1023 s
->range_table
= &apci3120_ai_range
;
1024 s
->insn_read
= apci3120_ai_insn_read
;
1026 dev
->read_subdev
= s
;
1027 s
->subdev_flags
|= SDF_CMD_READ
;
1028 s
->len_chanlist
= s
->n_chan
;
1029 s
->do_cmdtest
= apci3120_ai_cmdtest
;
1030 s
->do_cmd
= apci3120_ai_cmd
;
1031 s
->cancel
= apci3120_cancel
;
1034 /* Analog Output subdevice */
1035 s
= &dev
->subdevices
[1];
1036 if (board
->has_ao
) {
1037 s
->type
= COMEDI_SUBD_AO
;
1038 s
->subdev_flags
= SDF_WRITABLE
| SDF_GROUND
| SDF_COMMON
;
1040 s
->maxdata
= 0x3fff;
1041 s
->range_table
= &range_bipolar10
;
1042 s
->insn_write
= apci3120_ao_insn_write
;
1044 ret
= comedi_alloc_subdev_readback(s
);
1048 s
->type
= COMEDI_SUBD_UNUSED
;
1051 /* Digital Input subdevice */
1052 s
= &dev
->subdevices
[2];
1053 s
->type
= COMEDI_SUBD_DI
;
1054 s
->subdev_flags
= SDF_READABLE
;
1057 s
->range_table
= &range_digital
;
1058 s
->insn_bits
= apci3120_di_insn_bits
;
1060 /* Digital Output subdevice */
1061 s
= &dev
->subdevices
[3];
1062 s
->type
= COMEDI_SUBD_DO
;
1063 s
->subdev_flags
= SDF_WRITABLE
;
1066 s
->range_table
= &range_digital
;
1067 s
->insn_bits
= apci3120_do_insn_bits
;
1069 /* Timer subdevice */
1070 s
= &dev
->subdevices
[4];
1071 s
->type
= COMEDI_SUBD_TIMER
;
1072 s
->subdev_flags
= SDF_READABLE
;
1074 s
->maxdata
= 0x00ffffff;
1075 s
->insn_config
= apci3120_timer_insn_config
;
1076 s
->insn_read
= apci3120_timer_insn_read
;
1081 static void apci3120_detach(struct comedi_device
*dev
)
1083 comedi_pci_detach(dev
);
1084 apci3120_dma_free(dev
);
1087 static struct comedi_driver apci3120_driver
= {
1088 .driver_name
= "addi_apci_3120",
1089 .module
= THIS_MODULE
,
1090 .auto_attach
= apci3120_auto_attach
,
1091 .detach
= apci3120_detach
,
1094 static int apci3120_pci_probe(struct pci_dev
*dev
,
1095 const struct pci_device_id
*id
)
1097 return comedi_pci_auto_config(dev
, &apci3120_driver
, id
->driver_data
);
1100 static const struct pci_device_id apci3120_pci_table
[] = {
1101 { PCI_VDEVICE(AMCC
, 0x818d), BOARD_APCI3120
},
1102 { PCI_VDEVICE(AMCC
, 0x828d), BOARD_APCI3001
},
1105 MODULE_DEVICE_TABLE(pci
, apci3120_pci_table
);
1107 static struct pci_driver apci3120_pci_driver
= {
1108 .name
= "addi_apci_3120",
1109 .id_table
= apci3120_pci_table
,
1110 .probe
= apci3120_pci_probe
,
1111 .remove
= comedi_pci_auto_unconfig
,
1113 module_comedi_pci_driver(apci3120_driver
, apci3120_pci_driver
);
1115 MODULE_AUTHOR("Comedi https://www.comedi.org");
1116 MODULE_DESCRIPTION("ADDI-DATA APCI-3120, Analog input board");
1117 MODULE_LICENSE("GPL");