3 * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
8 * Tel: +19(0)7223/9493-0
9 * Fax: +49(0)7223/9493-92
10 * http://www.addi-data.com
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
18 * This program is distributed in the hope that it will be useful, but WITHOUT
19 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
24 #include <linux/module.h>
25 #include <linux/interrupt.h>
27 #include "../comedi_pci.h"
28 #include "amcc_s5933.h"
31 * PCI BAR 0 register map (devpriv->amcc)
32 * see amcc_s5933.h for register and bit defines
34 #define APCI3120_FIFO_ADVANCE_ON_BYTE_2 BIT(29)
37 * PCI BAR 1 register map (dev->iobase)
39 #define APCI3120_AI_FIFO_REG 0x00
40 #define APCI3120_CTRL_REG 0x00
41 #define APCI3120_CTRL_EXT_TRIG BIT(15)
42 #define APCI3120_CTRL_GATE(x) BIT(12 + (x))
43 #define APCI3120_CTRL_PR(x) (((x) & 0xf) << 8)
44 #define APCI3120_CTRL_PA(x) (((x) & 0xf) << 0)
45 #define APCI3120_AI_SOFTTRIG_REG 0x02
46 #define APCI3120_STATUS_REG 0x02
47 #define APCI3120_STATUS_EOC_INT BIT(15)
48 #define APCI3120_STATUS_AMCC_INT BIT(14)
49 #define APCI3120_STATUS_EOS_INT BIT(13)
50 #define APCI3120_STATUS_TIMER2_INT BIT(12)
51 #define APCI3120_STATUS_INT_MASK (0xf << 12)
52 #define APCI3120_STATUS_TO_DI_BITS(x) (((x) >> 8) & 0xf)
53 #define APCI3120_STATUS_TO_VERSION(x) (((x) >> 4) & 0xf)
54 #define APCI3120_STATUS_FIFO_FULL BIT(2)
55 #define APCI3120_STATUS_FIFO_EMPTY BIT(1)
56 #define APCI3120_STATUS_DA_READY BIT(0)
57 #define APCI3120_TIMER_REG 0x04
58 #define APCI3120_CHANLIST_REG 0x06
59 #define APCI3120_CHANLIST_INDEX(x) (((x) & 0xf) << 8)
60 #define APCI3120_CHANLIST_UNIPOLAR BIT(7)
61 #define APCI3120_CHANLIST_GAIN(x) (((x) & 0x3) << 4)
62 #define APCI3120_CHANLIST_MUX(x) (((x) & 0xf) << 0)
63 #define APCI3120_AO_REG(x) (0x08 + (((x) / 4) * 2))
64 #define APCI3120_AO_MUX(x) (((x) & 0x3) << 14)
65 #define APCI3120_AO_DATA(x) ((x) << 0)
66 #define APCI3120_TIMER_MODE_REG 0x0c
67 #define APCI3120_TIMER_MODE(_t, _m) ((_m) << ((_t) * 2))
68 #define APCI3120_TIMER_MODE0 0 /* I8254_MODE0 */
69 #define APCI3120_TIMER_MODE2 1 /* I8254_MODE2 */
70 #define APCI3120_TIMER_MODE4 2 /* I8254_MODE4 */
71 #define APCI3120_TIMER_MODE5 3 /* I8254_MODE5 */
72 #define APCI3120_TIMER_MODE_MASK(_t) (3 << ((_t) * 2))
73 #define APCI3120_CTR0_REG 0x0d
74 #define APCI3120_CTR0_DO_BITS(x) ((x) << 4)
75 #define APCI3120_CTR0_TIMER_SEL(x) ((x) << 0)
76 #define APCI3120_MODE_REG 0x0e
77 #define APCI3120_MODE_TIMER2_CLK(x) (((x) & 0x3) << 6)
78 #define APCI3120_MODE_TIMER2_CLK_OSC APCI3120_MODE_TIMER2_CLK(0)
79 #define APCI3120_MODE_TIMER2_CLK_OUT1 APCI3120_MODE_TIMER2_CLK(1)
80 #define APCI3120_MODE_TIMER2_CLK_EOC APCI3120_MODE_TIMER2_CLK(2)
81 #define APCI3120_MODE_TIMER2_CLK_EOS APCI3120_MODE_TIMER2_CLK(3)
82 #define APCI3120_MODE_TIMER2_CLK_MASK APCI3120_MODE_TIMER2_CLK(3)
83 #define APCI3120_MODE_TIMER2_AS(x) (((x) & 0x3) << 4)
84 #define APCI3120_MODE_TIMER2_AS_TIMER APCI3120_MODE_TIMER2_AS(0)
85 #define APCI3120_MODE_TIMER2_AS_COUNTER APCI3120_MODE_TIMER2_AS(1)
86 #define APCI3120_MODE_TIMER2_AS_WDOG APCI3120_MODE_TIMER2_AS(2)
87 #define APCI3120_MODE_TIMER2_AS_MASK APCI3120_MODE_TIMER2_AS(3)
88 #define APCI3120_MODE_SCAN_ENA BIT(3)
89 #define APCI3120_MODE_TIMER2_IRQ_ENA BIT(2)
90 #define APCI3120_MODE_EOS_IRQ_ENA BIT(1)
91 #define APCI3120_MODE_EOC_IRQ_ENA BIT(0)
94 * PCI BAR 2 register map (devpriv->addon)
96 #define APCI3120_ADDON_ADDR_REG 0x00
97 #define APCI3120_ADDON_DATA_REG 0x02
98 #define APCI3120_ADDON_CTRL_REG 0x04
99 #define APCI3120_ADDON_CTRL_AMWEN_ENA BIT(1)
100 #define APCI3120_ADDON_CTRL_A2P_FIFO_ENA BIT(0)
105 #define APCI3120_REVA 0xa
106 #define APCI3120_REVB 0xb
107 #define APCI3120_REVA_OSC_BASE 70 /* 70ns = 14.29MHz */
108 #define APCI3120_REVB_OSC_BASE 50 /* 50ns = 20MHz */
110 static const struct comedi_lrange apci3120_ai_range
= {
123 enum apci3120_boardid
{
128 struct apci3120_board
{
130 unsigned int ai_is_16bit
:1;
131 unsigned int has_ao
:1;
134 static const struct apci3120_board apci3120_boardtypes
[] = {
145 struct apci3120_dmabuf
{
146 unsigned short *virt
;
149 unsigned int use_size
;
152 struct apci3120_private
{
155 unsigned int osc_base
;
156 unsigned int use_dma
:1;
157 unsigned int use_double_buffer
:1;
158 unsigned int cur_dmabuf
:1;
159 struct apci3120_dmabuf dmabuf
[2];
160 unsigned char do_bits
;
161 unsigned char timer_mode
;
166 static void apci3120_addon_write(struct comedi_device
*dev
,
167 unsigned int val
, unsigned int reg
)
169 struct apci3120_private
*devpriv
= dev
->private;
171 /* 16-bit interface for AMCC add-on registers */
173 outw(reg
, devpriv
->addon
+ APCI3120_ADDON_ADDR_REG
);
174 outw(val
& 0xffff, devpriv
->addon
+ APCI3120_ADDON_DATA_REG
);
176 outw(reg
+ 2, devpriv
->addon
+ APCI3120_ADDON_ADDR_REG
);
177 outw((val
>> 16) & 0xffff, devpriv
->addon
+ APCI3120_ADDON_DATA_REG
);
180 static void apci3120_init_dma(struct comedi_device
*dev
,
181 struct apci3120_dmabuf
*dmabuf
)
183 struct apci3120_private
*devpriv
= dev
->private;
185 /* AMCC - enable transfer count and reset A2P FIFO */
186 outl(AGCSTS_TC_ENABLE
| AGCSTS_RESET_A2P_FIFO
,
187 devpriv
->amcc
+ AMCC_OP_REG_AGCSTS
);
189 /* Add-On - enable transfer count and reset A2P FIFO */
190 apci3120_addon_write(dev
, AGCSTS_TC_ENABLE
| AGCSTS_RESET_A2P_FIFO
,
193 /* AMCC - enable transfers and reset A2P flags */
194 outl(RESET_A2P_FLAGS
| EN_A2P_TRANSFERS
,
195 devpriv
->amcc
+ AMCC_OP_REG_MCSR
);
197 /* Add-On - DMA start address */
198 apci3120_addon_write(dev
, dmabuf
->hw
, AMCC_OP_REG_AMWAR
);
200 /* Add-On - Number of acquisitions */
201 apci3120_addon_write(dev
, dmabuf
->use_size
, AMCC_OP_REG_AMWTC
);
203 /* AMCC - enable write complete (DMA) and set FIFO advance */
204 outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2
| AINT_WRITE_COMPL
,
205 devpriv
->amcc
+ AMCC_OP_REG_INTCSR
);
207 /* Add-On - enable DMA */
208 outw(APCI3120_ADDON_CTRL_AMWEN_ENA
| APCI3120_ADDON_CTRL_A2P_FIFO_ENA
,
209 devpriv
->addon
+ APCI3120_ADDON_CTRL_REG
);
212 static void apci3120_setup_dma(struct comedi_device
*dev
,
213 struct comedi_subdevice
*s
)
215 struct apci3120_private
*devpriv
= dev
->private;
216 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
217 struct apci3120_dmabuf
*dmabuf0
= &devpriv
->dmabuf
[0];
218 struct apci3120_dmabuf
*dmabuf1
= &devpriv
->dmabuf
[1];
219 unsigned int dmalen0
= dmabuf0
->size
;
220 unsigned int dmalen1
= dmabuf1
->size
;
221 unsigned int scan_bytes
;
223 scan_bytes
= comedi_samples_to_bytes(s
, cmd
->scan_end_arg
);
225 if (cmd
->stop_src
== TRIG_COUNT
) {
227 * Must we fill full first buffer? And must we fill
228 * full second buffer when first is once filled?
230 if (dmalen0
> (cmd
->stop_arg
* scan_bytes
))
231 dmalen0
= cmd
->stop_arg
* scan_bytes
;
232 else if (dmalen1
> (cmd
->stop_arg
* scan_bytes
- dmalen0
))
233 dmalen1
= cmd
->stop_arg
* scan_bytes
- dmalen0
;
236 if (cmd
->flags
& CMDF_WAKE_EOS
) {
237 /* don't we want wake up every scan? */
238 if (dmalen0
> scan_bytes
) {
239 dmalen0
= scan_bytes
;
240 if (cmd
->scan_end_arg
& 1)
243 if (dmalen1
> scan_bytes
) {
244 dmalen1
= scan_bytes
;
245 if (cmd
->scan_end_arg
& 1)
251 /* isn't output buff smaller that our DMA buff? */
252 if (dmalen0
> s
->async
->prealloc_bufsz
)
253 dmalen0
= s
->async
->prealloc_bufsz
;
254 if (dmalen1
> s
->async
->prealloc_bufsz
)
255 dmalen1
= s
->async
->prealloc_bufsz
;
257 dmabuf0
->use_size
= dmalen0
;
258 dmabuf1
->use_size
= dmalen1
;
260 apci3120_init_dma(dev
, dmabuf0
);
264 * There are three timers on the board. They all use the same base
265 * clock with a fixed prescaler for each timer. The base clock used
266 * depends on the board version and type.
268 * APCI-3120 Rev A boards OSC = 14.29MHz base clock (~70ns)
269 * APCI-3120 Rev B boards OSC = 20MHz base clock (50ns)
270 * APCI-3001 boards OSC = 20MHz base clock (50ns)
272 * The prescalers for each timer are:
273 * Timer 0 CLK = OSC/10
274 * Timer 1 CLK = OSC/1000
275 * Timer 2 CLK = OSC/1000
277 static unsigned int apci3120_ns_to_timer(struct comedi_device
*dev
,
282 struct apci3120_private
*devpriv
= dev
->private;
283 unsigned int prescale
= (timer
== 0) ? 10 : 1000;
284 unsigned int timer_base
= devpriv
->osc_base
* prescale
;
285 unsigned int divisor
;
287 switch (flags
& CMDF_ROUND_MASK
) {
289 divisor
= DIV_ROUND_UP(ns
, timer_base
);
291 case CMDF_ROUND_DOWN
:
292 divisor
= ns
/ timer_base
;
294 case CMDF_ROUND_NEAREST
:
296 divisor
= DIV_ROUND_CLOSEST(ns
, timer_base
);
301 /* timer 2 is 24-bits */
302 if (divisor
> 0x00ffffff)
303 divisor
= 0x00ffffff;
305 /* timers 0 and 1 are 16-bits */
306 if (divisor
> 0xffff)
309 /* the timers require a minimum divisor of 2 */
316 static void apci3120_clr_timer2_interrupt(struct comedi_device
*dev
)
318 /* a dummy read of APCI3120_CTR0_REG clears the timer 2 interrupt */
319 inb(dev
->iobase
+ APCI3120_CTR0_REG
);
322 static void apci3120_timer_write(struct comedi_device
*dev
,
323 unsigned int timer
, unsigned int val
)
325 struct apci3120_private
*devpriv
= dev
->private;
327 /* write 16-bit value to timer (lower 16-bits of timer 2) */
328 outb(APCI3120_CTR0_DO_BITS(devpriv
->do_bits
) |
329 APCI3120_CTR0_TIMER_SEL(timer
),
330 dev
->iobase
+ APCI3120_CTR0_REG
);
331 outw(val
& 0xffff, dev
->iobase
+ APCI3120_TIMER_REG
);
334 /* write upper 16-bits to timer 2 */
335 outb(APCI3120_CTR0_DO_BITS(devpriv
->do_bits
) |
336 APCI3120_CTR0_TIMER_SEL(timer
+ 1),
337 dev
->iobase
+ APCI3120_CTR0_REG
);
338 outw((val
>> 16) & 0xffff, dev
->iobase
+ APCI3120_TIMER_REG
);
342 static unsigned int apci3120_timer_read(struct comedi_device
*dev
,
345 struct apci3120_private
*devpriv
= dev
->private;
348 /* read 16-bit value from timer (lower 16-bits of timer 2) */
349 outb(APCI3120_CTR0_DO_BITS(devpriv
->do_bits
) |
350 APCI3120_CTR0_TIMER_SEL(timer
),
351 dev
->iobase
+ APCI3120_CTR0_REG
);
352 val
= inw(dev
->iobase
+ APCI3120_TIMER_REG
);
355 /* read upper 16-bits from timer 2 */
356 outb(APCI3120_CTR0_DO_BITS(devpriv
->do_bits
) |
357 APCI3120_CTR0_TIMER_SEL(timer
+ 1),
358 dev
->iobase
+ APCI3120_CTR0_REG
);
359 val
|= (inw(dev
->iobase
+ APCI3120_TIMER_REG
) << 16);
365 static void apci3120_timer_set_mode(struct comedi_device
*dev
,
366 unsigned int timer
, unsigned int mode
)
368 struct apci3120_private
*devpriv
= dev
->private;
370 devpriv
->timer_mode
&= ~APCI3120_TIMER_MODE_MASK(timer
);
371 devpriv
->timer_mode
|= APCI3120_TIMER_MODE(timer
, mode
);
372 outb(devpriv
->timer_mode
, dev
->iobase
+ APCI3120_TIMER_MODE_REG
);
375 static void apci3120_timer_enable(struct comedi_device
*dev
,
376 unsigned int timer
, bool enable
)
378 struct apci3120_private
*devpriv
= dev
->private;
381 devpriv
->ctrl
|= APCI3120_CTRL_GATE(timer
);
383 devpriv
->ctrl
&= ~APCI3120_CTRL_GATE(timer
);
384 outw(devpriv
->ctrl
, dev
->iobase
+ APCI3120_CTRL_REG
);
387 static void apci3120_exttrig_enable(struct comedi_device
*dev
, bool enable
)
389 struct apci3120_private
*devpriv
= dev
->private;
392 devpriv
->ctrl
|= APCI3120_CTRL_EXT_TRIG
;
394 devpriv
->ctrl
&= ~APCI3120_CTRL_EXT_TRIG
;
395 outw(devpriv
->ctrl
, dev
->iobase
+ APCI3120_CTRL_REG
);
398 static void apci3120_set_chanlist(struct comedi_device
*dev
,
399 struct comedi_subdevice
*s
,
400 int n_chan
, unsigned int *chanlist
)
402 struct apci3120_private
*devpriv
= dev
->private;
405 /* set chanlist for scan */
406 for (i
= 0; i
< n_chan
; i
++) {
407 unsigned int chan
= CR_CHAN(chanlist
[i
]);
408 unsigned int range
= CR_RANGE(chanlist
[i
]);
411 val
= APCI3120_CHANLIST_MUX(chan
) |
412 APCI3120_CHANLIST_GAIN(range
) |
413 APCI3120_CHANLIST_INDEX(i
);
415 if (comedi_range_is_unipolar(s
, range
))
416 val
|= APCI3120_CHANLIST_UNIPOLAR
;
418 outw(val
, dev
->iobase
+ APCI3120_CHANLIST_REG
);
421 /* a dummy read of APCI3120_TIMER_MODE_REG resets the ai FIFO */
422 inw(dev
->iobase
+ APCI3120_TIMER_MODE_REG
);
424 /* set scan length (PR) and scan start (PA) */
425 devpriv
->ctrl
= APCI3120_CTRL_PR(n_chan
- 1) | APCI3120_CTRL_PA(0);
426 outw(devpriv
->ctrl
, dev
->iobase
+ APCI3120_CTRL_REG
);
428 /* enable chanlist scanning if necessary */
430 devpriv
->mode
|= APCI3120_MODE_SCAN_ENA
;
433 static void apci3120_interrupt_dma(struct comedi_device
*dev
,
434 struct comedi_subdevice
*s
)
436 struct apci3120_private
*devpriv
= dev
->private;
437 struct comedi_async
*async
= s
->async
;
438 struct comedi_cmd
*cmd
= &async
->cmd
;
439 struct apci3120_dmabuf
*dmabuf
;
441 unsigned int nsamples
;
443 dmabuf
= &devpriv
->dmabuf
[devpriv
->cur_dmabuf
];
445 nbytes
= dmabuf
->use_size
- inl(devpriv
->amcc
+ AMCC_OP_REG_MWTC
);
447 if (nbytes
< dmabuf
->use_size
)
448 dev_err(dev
->class_dev
, "Interrupted DMA transfer!\n");
450 dev_err(dev
->class_dev
, "Odd count of bytes in DMA ring!\n");
451 async
->events
|= COMEDI_CB_ERROR
;
455 nsamples
= comedi_bytes_to_samples(s
, nbytes
);
457 comedi_buf_write_samples(s
, dmabuf
->virt
, nsamples
);
459 if (!(cmd
->flags
& CMDF_WAKE_EOS
))
460 async
->events
|= COMEDI_CB_EOS
;
463 if ((async
->events
& COMEDI_CB_CANCEL_MASK
) ||
464 (cmd
->stop_src
== TRIG_COUNT
&& async
->scans_done
>= cmd
->stop_arg
))
467 if (devpriv
->use_double_buffer
) {
468 /* switch DMA buffers for next interrupt */
469 devpriv
->cur_dmabuf
= !devpriv
->cur_dmabuf
;
470 dmabuf
= &devpriv
->dmabuf
[devpriv
->cur_dmabuf
];
471 apci3120_init_dma(dev
, dmabuf
);
473 /* restart DMA if not using double buffering */
474 apci3120_init_dma(dev
, dmabuf
);
478 static irqreturn_t
apci3120_interrupt(int irq
, void *d
)
480 struct comedi_device
*dev
= d
;
481 struct apci3120_private
*devpriv
= dev
->private;
482 struct comedi_subdevice
*s
= dev
->read_subdev
;
483 struct comedi_async
*async
= s
->async
;
484 struct comedi_cmd
*cmd
= &async
->cmd
;
486 unsigned int int_amcc
;
488 status
= inw(dev
->iobase
+ APCI3120_STATUS_REG
);
489 int_amcc
= inl(devpriv
->amcc
+ AMCC_OP_REG_INTCSR
);
491 if (!(status
& APCI3120_STATUS_INT_MASK
) &&
492 !(int_amcc
& ANY_S593X_INT
)) {
493 dev_err(dev
->class_dev
, "IRQ from unknown source\n");
497 outl(int_amcc
| AINT_INT_MASK
, devpriv
->amcc
+ AMCC_OP_REG_INTCSR
);
499 if (devpriv
->ctrl
& APCI3120_CTRL_EXT_TRIG
)
500 apci3120_exttrig_enable(dev
, false);
502 if (int_amcc
& MASTER_ABORT_INT
)
503 dev_err(dev
->class_dev
, "AMCC IRQ - MASTER DMA ABORT!\n");
504 if (int_amcc
& TARGET_ABORT_INT
)
505 dev_err(dev
->class_dev
, "AMCC IRQ - TARGET DMA ABORT!\n");
507 if ((status
& APCI3120_STATUS_EOS_INT
) &&
508 (devpriv
->mode
& APCI3120_MODE_EOS_IRQ_ENA
)) {
512 for (i
= 0; i
< cmd
->chanlist_len
; i
++) {
513 val
= inw(dev
->iobase
+ APCI3120_AI_FIFO_REG
);
514 comedi_buf_write_samples(s
, &val
, 1);
517 devpriv
->mode
|= APCI3120_MODE_EOS_IRQ_ENA
;
518 outb(devpriv
->mode
, dev
->iobase
+ APCI3120_MODE_REG
);
521 if (status
& APCI3120_STATUS_TIMER2_INT
) {
524 * timer2 interrupts are not enabled in the driver
526 apci3120_clr_timer2_interrupt(dev
);
529 if (status
& APCI3120_STATUS_AMCC_INT
) {
530 /* AMCC- Clear write complete interrupt (DMA) */
531 outl(AINT_WT_COMPLETE
, devpriv
->amcc
+ AMCC_OP_REG_INTCSR
);
533 /* do some data transfer */
534 apci3120_interrupt_dma(dev
, s
);
537 if (cmd
->stop_src
== TRIG_COUNT
&& async
->scans_done
>= cmd
->stop_arg
)
538 async
->events
|= COMEDI_CB_EOA
;
540 comedi_handle_events(dev
, s
);
545 static int apci3120_ai_cmd(struct comedi_device
*dev
,
546 struct comedi_subdevice
*s
)
548 struct apci3120_private
*devpriv
= dev
->private;
549 struct comedi_cmd
*cmd
= &s
->async
->cmd
;
550 unsigned int divisor
;
552 /* set default mode bits */
553 devpriv
->mode
= APCI3120_MODE_TIMER2_CLK_OSC
|
554 APCI3120_MODE_TIMER2_AS_TIMER
;
556 /* AMCC- Clear write complete interrupt (DMA) */
557 outl(AINT_WT_COMPLETE
, devpriv
->amcc
+ AMCC_OP_REG_INTCSR
);
559 devpriv
->cur_dmabuf
= 0;
561 /* load chanlist for command scan */
562 apci3120_set_chanlist(dev
, s
, cmd
->chanlist_len
, cmd
->chanlist
);
564 if (cmd
->start_src
== TRIG_EXT
)
565 apci3120_exttrig_enable(dev
, true);
567 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
569 * Timer 1 is used in MODE2 (rate generator) to set the
570 * start time for each scan.
572 divisor
= apci3120_ns_to_timer(dev
, 1, cmd
->scan_begin_arg
,
574 apci3120_timer_set_mode(dev
, 1, APCI3120_TIMER_MODE2
);
575 apci3120_timer_write(dev
, 1, divisor
);
579 * Timer 0 is used in MODE2 (rate generator) to set the conversion
580 * time for each acquisition.
582 divisor
= apci3120_ns_to_timer(dev
, 0, cmd
->convert_arg
, cmd
->flags
);
583 apci3120_timer_set_mode(dev
, 0, APCI3120_TIMER_MODE2
);
584 apci3120_timer_write(dev
, 0, divisor
);
586 if (devpriv
->use_dma
)
587 apci3120_setup_dma(dev
, s
);
589 devpriv
->mode
|= APCI3120_MODE_EOS_IRQ_ENA
;
591 /* set mode to enable acquisition */
592 outb(devpriv
->mode
, dev
->iobase
+ APCI3120_MODE_REG
);
594 if (cmd
->scan_begin_src
== TRIG_TIMER
)
595 apci3120_timer_enable(dev
, 1, true);
596 apci3120_timer_enable(dev
, 0, true);
601 static int apci3120_ai_cmdtest(struct comedi_device
*dev
,
602 struct comedi_subdevice
*s
,
603 struct comedi_cmd
*cmd
)
608 /* Step 1 : check if triggers are trivially valid */
610 err
|= comedi_check_trigger_src(&cmd
->start_src
, TRIG_NOW
| TRIG_EXT
);
611 err
|= comedi_check_trigger_src(&cmd
->scan_begin_src
,
612 TRIG_TIMER
| TRIG_FOLLOW
);
613 err
|= comedi_check_trigger_src(&cmd
->convert_src
, TRIG_TIMER
);
614 err
|= comedi_check_trigger_src(&cmd
->scan_end_src
, TRIG_COUNT
);
615 err
|= comedi_check_trigger_src(&cmd
->stop_src
, TRIG_COUNT
| TRIG_NONE
);
620 /* Step 2a : make sure trigger sources are unique */
622 err
|= comedi_check_trigger_is_unique(cmd
->start_src
);
623 err
|= comedi_check_trigger_is_unique(cmd
->scan_begin_src
);
624 err
|= comedi_check_trigger_is_unique(cmd
->stop_src
);
626 /* Step 2b : and mutually compatible */
631 /* Step 3: check if arguments are trivially valid */
633 err
|= comedi_check_trigger_arg_is(&cmd
->start_arg
, 0);
635 if (cmd
->scan_begin_src
== TRIG_TIMER
) { /* Test Delay timing */
636 err
|= comedi_check_trigger_arg_min(&cmd
->scan_begin_arg
,
640 /* minimum conversion time per sample is 10us */
641 err
|= comedi_check_trigger_arg_min(&cmd
->convert_arg
, 10000);
643 err
|= comedi_check_trigger_arg_min(&cmd
->chanlist_len
, 1);
644 err
|= comedi_check_trigger_arg_is(&cmd
->scan_end_arg
,
647 if (cmd
->stop_src
== TRIG_COUNT
)
648 err
|= comedi_check_trigger_arg_min(&cmd
->stop_arg
, 1);
650 err
|= comedi_check_trigger_arg_is(&cmd
->stop_arg
, 0);
655 /* Step 4: fix up any arguments */
657 if (cmd
->scan_begin_src
== TRIG_TIMER
) {
658 /* scan begin must be larger than the scan time */
659 arg
= cmd
->convert_arg
* cmd
->scan_end_arg
;
660 err
|= comedi_check_trigger_arg_min(&cmd
->scan_begin_arg
, arg
);
666 /* Step 5: check channel list if it exists */
671 static int apci3120_cancel(struct comedi_device
*dev
,
672 struct comedi_subdevice
*s
)
674 struct apci3120_private
*devpriv
= dev
->private;
676 /* Add-On - disable DMA */
677 outw(0, devpriv
->addon
+ 4);
679 /* Add-On - disable bus master */
680 apci3120_addon_write(dev
, 0, AMCC_OP_REG_AGCSTS
);
682 /* AMCC - disable bus master */
683 outl(0, devpriv
->amcc
+ AMCC_OP_REG_MCSR
);
685 /* disable all counters, ext trigger, and reset scan */
687 outw(devpriv
->ctrl
, dev
->iobase
+ APCI3120_CTRL_REG
);
689 /* DISABLE_ALL_INTERRUPT */
691 outb(devpriv
->mode
, dev
->iobase
+ APCI3120_MODE_REG
);
693 inw(dev
->iobase
+ APCI3120_STATUS_REG
);
694 devpriv
->cur_dmabuf
= 0;
699 static int apci3120_ai_eoc(struct comedi_device
*dev
,
700 struct comedi_subdevice
*s
,
701 struct comedi_insn
*insn
,
702 unsigned long context
)
706 status
= inw(dev
->iobase
+ APCI3120_STATUS_REG
);
707 if ((status
& APCI3120_STATUS_EOC_INT
) == 0)
712 static int apci3120_ai_insn_read(struct comedi_device
*dev
,
713 struct comedi_subdevice
*s
,
714 struct comedi_insn
*insn
,
717 struct apci3120_private
*devpriv
= dev
->private;
718 unsigned int divisor
;
722 /* set mode for A/D conversions by software trigger with timer 0 */
723 devpriv
->mode
= APCI3120_MODE_TIMER2_CLK_OSC
|
724 APCI3120_MODE_TIMER2_AS_TIMER
;
725 outb(devpriv
->mode
, dev
->iobase
+ APCI3120_MODE_REG
);
727 /* load chanlist for single channel scan */
728 apci3120_set_chanlist(dev
, s
, 1, &insn
->chanspec
);
731 * Timer 0 is used in MODE4 (software triggered strobe) to set the
732 * conversion time for each acquisition. Each conversion is triggered
733 * when the divisor is written to the timer, The conversion is done
734 * when the EOC bit in the status register is '0'.
736 apci3120_timer_set_mode(dev
, 0, APCI3120_TIMER_MODE4
);
737 apci3120_timer_enable(dev
, 0, true);
739 /* fixed conversion time of 10 us */
740 divisor
= apci3120_ns_to_timer(dev
, 0, 10000, CMDF_ROUND_NEAREST
);
742 for (i
= 0; i
< insn
->n
; i
++) {
743 /* trigger conversion */
744 apci3120_timer_write(dev
, 0, divisor
);
746 ret
= comedi_timeout(dev
, s
, insn
, apci3120_ai_eoc
, 0);
750 data
[i
] = inw(dev
->iobase
+ APCI3120_AI_FIFO_REG
);
756 static int apci3120_ao_ready(struct comedi_device
*dev
,
757 struct comedi_subdevice
*s
,
758 struct comedi_insn
*insn
,
759 unsigned long context
)
763 status
= inw(dev
->iobase
+ APCI3120_STATUS_REG
);
764 if (status
& APCI3120_STATUS_DA_READY
)
769 static int apci3120_ao_insn_write(struct comedi_device
*dev
,
770 struct comedi_subdevice
*s
,
771 struct comedi_insn
*insn
,
774 unsigned int chan
= CR_CHAN(insn
->chanspec
);
777 for (i
= 0; i
< insn
->n
; i
++) {
778 unsigned int val
= data
[i
];
781 ret
= comedi_timeout(dev
, s
, insn
, apci3120_ao_ready
, 0);
785 outw(APCI3120_AO_MUX(chan
) | APCI3120_AO_DATA(val
),
786 dev
->iobase
+ APCI3120_AO_REG(chan
));
788 s
->readback
[chan
] = val
;
794 static int apci3120_di_insn_bits(struct comedi_device
*dev
,
795 struct comedi_subdevice
*s
,
796 struct comedi_insn
*insn
,
801 status
= inw(dev
->iobase
+ APCI3120_STATUS_REG
);
802 data
[1] = APCI3120_STATUS_TO_DI_BITS(status
);
807 static int apci3120_do_insn_bits(struct comedi_device
*dev
,
808 struct comedi_subdevice
*s
,
809 struct comedi_insn
*insn
,
812 struct apci3120_private
*devpriv
= dev
->private;
814 if (comedi_dio_update_state(s
, data
)) {
815 devpriv
->do_bits
= s
->state
;
816 outb(APCI3120_CTR0_DO_BITS(devpriv
->do_bits
),
817 dev
->iobase
+ APCI3120_CTR0_REG
);
825 static int apci3120_timer_insn_config(struct comedi_device
*dev
,
826 struct comedi_subdevice
*s
,
827 struct comedi_insn
*insn
,
830 struct apci3120_private
*devpriv
= dev
->private;
831 unsigned int divisor
;
834 unsigned int timer_mode
;
837 case INSN_CONFIG_ARM
:
838 apci3120_clr_timer2_interrupt(dev
);
839 divisor
= apci3120_ns_to_timer(dev
, 2, data
[1],
841 apci3120_timer_write(dev
, 2, divisor
);
842 apci3120_timer_enable(dev
, 2, true);
845 case INSN_CONFIG_DISARM
:
846 apci3120_timer_enable(dev
, 2, false);
847 apci3120_clr_timer2_interrupt(dev
);
850 case INSN_CONFIG_GET_COUNTER_STATUS
:
852 data
[2] = COMEDI_COUNTER_ARMED
| COMEDI_COUNTER_COUNTING
|
853 COMEDI_COUNTER_TERMINAL_COUNT
;
855 if (devpriv
->ctrl
& APCI3120_CTRL_GATE(2)) {
856 data
[1] |= COMEDI_COUNTER_ARMED
;
857 data
[1] |= COMEDI_COUNTER_COUNTING
;
859 status
= inw(dev
->iobase
+ APCI3120_STATUS_REG
);
860 if (status
& APCI3120_STATUS_TIMER2_INT
) {
861 data
[1] &= ~COMEDI_COUNTER_COUNTING
;
862 data
[1] |= COMEDI_COUNTER_TERMINAL_COUNT
;
866 case INSN_CONFIG_SET_COUNTER_MODE
:
869 mode
= APCI3120_MODE_TIMER2_AS_COUNTER
;
870 timer_mode
= APCI3120_TIMER_MODE0
;
873 mode
= APCI3120_MODE_TIMER2_AS_TIMER
;
874 timer_mode
= APCI3120_TIMER_MODE2
;
877 mode
= APCI3120_MODE_TIMER2_AS_TIMER
;
878 timer_mode
= APCI3120_TIMER_MODE4
;
881 mode
= APCI3120_MODE_TIMER2_AS_WDOG
;
882 timer_mode
= APCI3120_TIMER_MODE5
;
887 apci3120_timer_enable(dev
, 2, false);
888 apci3120_clr_timer2_interrupt(dev
);
889 apci3120_timer_set_mode(dev
, 2, timer_mode
);
890 devpriv
->mode
&= ~APCI3120_MODE_TIMER2_AS_MASK
;
891 devpriv
->mode
|= mode
;
892 outb(devpriv
->mode
, dev
->iobase
+ APCI3120_MODE_REG
);
902 static int apci3120_timer_insn_read(struct comedi_device
*dev
,
903 struct comedi_subdevice
*s
,
904 struct comedi_insn
*insn
,
909 for (i
= 0; i
< insn
->n
; i
++)
910 data
[i
] = apci3120_timer_read(dev
, 2);
915 static void apci3120_dma_alloc(struct comedi_device
*dev
)
917 struct apci3120_private
*devpriv
= dev
->private;
918 struct apci3120_dmabuf
*dmabuf
;
922 for (i
= 0; i
< 2; i
++) {
923 dmabuf
= &devpriv
->dmabuf
[i
];
924 for (order
= 2; order
>= 0; order
--) {
925 dmabuf
->virt
= dma_alloc_coherent(dev
->hw_dev
,
934 dmabuf
->size
= PAGE_SIZE
<< order
;
937 devpriv
->use_dma
= 1;
939 devpriv
->use_double_buffer
= 1;
943 static void apci3120_dma_free(struct comedi_device
*dev
)
945 struct apci3120_private
*devpriv
= dev
->private;
946 struct apci3120_dmabuf
*dmabuf
;
952 for (i
= 0; i
< 2; i
++) {
953 dmabuf
= &devpriv
->dmabuf
[i
];
955 dma_free_coherent(dev
->hw_dev
, dmabuf
->size
,
956 dmabuf
->virt
, dmabuf
->hw
);
961 static void apci3120_reset(struct comedi_device
*dev
)
963 /* disable all interrupt sources */
964 outb(0, dev
->iobase
+ APCI3120_MODE_REG
);
966 /* disable all counters, ext trigger, and reset scan */
967 outw(0, dev
->iobase
+ APCI3120_CTRL_REG
);
969 /* clear interrupt status */
970 inw(dev
->iobase
+ APCI3120_STATUS_REG
);
973 static int apci3120_auto_attach(struct comedi_device
*dev
,
974 unsigned long context
)
976 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
977 const struct apci3120_board
*board
= NULL
;
978 struct apci3120_private
*devpriv
;
979 struct comedi_subdevice
*s
;
983 if (context
< ARRAY_SIZE(apci3120_boardtypes
))
984 board
= &apci3120_boardtypes
[context
];
987 dev
->board_ptr
= board
;
988 dev
->board_name
= board
->name
;
990 devpriv
= comedi_alloc_devpriv(dev
, sizeof(*devpriv
));
994 ret
= comedi_pci_enable(dev
);
997 pci_set_master(pcidev
);
999 dev
->iobase
= pci_resource_start(pcidev
, 1);
1000 devpriv
->amcc
= pci_resource_start(pcidev
, 0);
1001 devpriv
->addon
= pci_resource_start(pcidev
, 2);
1003 apci3120_reset(dev
);
1005 if (pcidev
->irq
> 0) {
1006 ret
= request_irq(pcidev
->irq
, apci3120_interrupt
, IRQF_SHARED
,
1007 dev
->board_name
, dev
);
1009 dev
->irq
= pcidev
->irq
;
1011 apci3120_dma_alloc(dev
);
1015 status
= inw(dev
->iobase
+ APCI3120_STATUS_REG
);
1016 if (APCI3120_STATUS_TO_VERSION(status
) == APCI3120_REVB
||
1017 context
== BOARD_APCI3001
)
1018 devpriv
->osc_base
= APCI3120_REVB_OSC_BASE
;
1020 devpriv
->osc_base
= APCI3120_REVA_OSC_BASE
;
1022 ret
= comedi_alloc_subdevices(dev
, 5);
1026 /* Analog Input subdevice */
1027 s
= &dev
->subdevices
[0];
1028 s
->type
= COMEDI_SUBD_AI
;
1029 s
->subdev_flags
= SDF_READABLE
| SDF_COMMON
| SDF_GROUND
| SDF_DIFF
;
1031 s
->maxdata
= board
->ai_is_16bit
? 0xffff : 0x0fff;
1032 s
->range_table
= &apci3120_ai_range
;
1033 s
->insn_read
= apci3120_ai_insn_read
;
1035 dev
->read_subdev
= s
;
1036 s
->subdev_flags
|= SDF_CMD_READ
;
1037 s
->len_chanlist
= s
->n_chan
;
1038 s
->do_cmdtest
= apci3120_ai_cmdtest
;
1039 s
->do_cmd
= apci3120_ai_cmd
;
1040 s
->cancel
= apci3120_cancel
;
1043 /* Analog Output subdevice */
1044 s
= &dev
->subdevices
[1];
1045 if (board
->has_ao
) {
1046 s
->type
= COMEDI_SUBD_AO
;
1047 s
->subdev_flags
= SDF_WRITABLE
| SDF_GROUND
| SDF_COMMON
;
1049 s
->maxdata
= 0x3fff;
1050 s
->range_table
= &range_bipolar10
;
1051 s
->insn_write
= apci3120_ao_insn_write
;
1053 ret
= comedi_alloc_subdev_readback(s
);
1057 s
->type
= COMEDI_SUBD_UNUSED
;
1060 /* Digital Input subdevice */
1061 s
= &dev
->subdevices
[2];
1062 s
->type
= COMEDI_SUBD_DI
;
1063 s
->subdev_flags
= SDF_READABLE
;
1066 s
->range_table
= &range_digital
;
1067 s
->insn_bits
= apci3120_di_insn_bits
;
1069 /* Digital Output subdevice */
1070 s
= &dev
->subdevices
[3];
1071 s
->type
= COMEDI_SUBD_DO
;
1072 s
->subdev_flags
= SDF_WRITABLE
;
1075 s
->range_table
= &range_digital
;
1076 s
->insn_bits
= apci3120_do_insn_bits
;
1078 /* Timer subdevice */
1079 s
= &dev
->subdevices
[4];
1080 s
->type
= COMEDI_SUBD_TIMER
;
1081 s
->subdev_flags
= SDF_READABLE
;
1083 s
->maxdata
= 0x00ffffff;
1084 s
->insn_config
= apci3120_timer_insn_config
;
1085 s
->insn_read
= apci3120_timer_insn_read
;
1090 static void apci3120_detach(struct comedi_device
*dev
)
1092 comedi_pci_detach(dev
);
1093 apci3120_dma_free(dev
);
1096 static struct comedi_driver apci3120_driver
= {
1097 .driver_name
= "addi_apci_3120",
1098 .module
= THIS_MODULE
,
1099 .auto_attach
= apci3120_auto_attach
,
1100 .detach
= apci3120_detach
,
1103 static int apci3120_pci_probe(struct pci_dev
*dev
,
1104 const struct pci_device_id
*id
)
1106 return comedi_pci_auto_config(dev
, &apci3120_driver
, id
->driver_data
);
1109 static const struct pci_device_id apci3120_pci_table
[] = {
1110 { PCI_VDEVICE(AMCC
, 0x818d), BOARD_APCI3120
},
1111 { PCI_VDEVICE(AMCC
, 0x828d), BOARD_APCI3001
},
1114 MODULE_DEVICE_TABLE(pci
, apci3120_pci_table
);
1116 static struct pci_driver apci3120_pci_driver
= {
1117 .name
= "addi_apci_3120",
1118 .id_table
= apci3120_pci_table
,
1119 .probe
= apci3120_pci_probe
,
1120 .remove
= comedi_pci_auto_unconfig
,
1122 module_comedi_pci_driver(apci3120_driver
, apci3120_pci_driver
);
1124 MODULE_AUTHOR("Comedi http://www.comedi.org");
1125 MODULE_DESCRIPTION("ADDI-DATA APCI-3120, Analog input board");
1126 MODULE_LICENSE("GPL");