staging: comedi: comedi_test: simplify time since last AI scan
[deliverable/linux.git] / drivers / staging / comedi / drivers / addi_apci_3120.c
1 /*
2 * addi_apci_3120.c
3 * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
4 *
5 * ADDI-DATA GmbH
6 * Dieselstrasse 3
7 * D-77833 Ottersweier
8 * Tel: +19(0)7223/9493-0
9 * Fax: +49(0)7223/9493-92
10 * http://www.addi-data.com
11 * info@addi-data.com
12 *
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.
17 *
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
21 * more details.
22 */
23
24 #include <linux/module.h>
25 #include <linux/interrupt.h>
26
27 #include "../comedi_pci.h"
28 #include "amcc_s5933.h"
29
30 /*
31 * PCI BAR 0 register map (devpriv->amcc)
32 * see amcc_s5933.h for register and bit defines
33 */
34 #define APCI3120_FIFO_ADVANCE_ON_BYTE_2 BIT(29)
35
36 /*
37 * PCI BAR 1 register map (dev->iobase)
38 */
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)
92
93 /*
94 * PCI BAR 2 register map (devpriv->addon)
95 */
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)
101
102 /*
103 * Board revisions
104 */
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 */
109
110 static const struct comedi_lrange apci3120_ai_range = {
111 8, {
112 BIP_RANGE(10),
113 BIP_RANGE(5),
114 BIP_RANGE(2),
115 BIP_RANGE(1),
116 UNI_RANGE(10),
117 UNI_RANGE(5),
118 UNI_RANGE(2),
119 UNI_RANGE(1)
120 }
121 };
122
123 enum apci3120_boardid {
124 BOARD_APCI3120,
125 BOARD_APCI3001,
126 };
127
128 struct apci3120_board {
129 const char *name;
130 unsigned int ai_is_16bit:1;
131 unsigned int has_ao:1;
132 };
133
134 static const struct apci3120_board apci3120_boardtypes[] = {
135 [BOARD_APCI3120] = {
136 .name = "apci3120",
137 .ai_is_16bit = 1,
138 .has_ao = 1,
139 },
140 [BOARD_APCI3001] = {
141 .name = "apci3001",
142 },
143 };
144
145 struct apci3120_dmabuf {
146 unsigned short *virt;
147 dma_addr_t hw;
148 unsigned int size;
149 unsigned int use_size;
150 };
151
152 struct apci3120_private {
153 unsigned long amcc;
154 unsigned long addon;
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;
162 unsigned char mode;
163 unsigned short ctrl;
164 };
165
166 static void apci3120_addon_write(struct comedi_device *dev,
167 unsigned int val, unsigned int reg)
168 {
169 struct apci3120_private *devpriv = dev->private;
170
171 /* 16-bit interface for AMCC add-on registers */
172
173 outw(reg, devpriv->addon + APCI3120_ADDON_ADDR_REG);
174 outw(val & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG);
175
176 outw(reg + 2, devpriv->addon + APCI3120_ADDON_ADDR_REG);
177 outw((val >> 16) & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG);
178 }
179
180 static void apci3120_init_dma(struct comedi_device *dev,
181 struct apci3120_dmabuf *dmabuf)
182 {
183 struct apci3120_private *devpriv = dev->private;
184
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);
188
189 /* Add-On - enable transfer count and reset A2P FIFO */
190 apci3120_addon_write(dev, AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO,
191 AMCC_OP_REG_AGCSTS);
192
193 /* AMCC - enable transfers and reset A2P flags */
194 outl(RESET_A2P_FLAGS | EN_A2P_TRANSFERS,
195 devpriv->amcc + AMCC_OP_REG_MCSR);
196
197 /* Add-On - DMA start address */
198 apci3120_addon_write(dev, dmabuf->hw, AMCC_OP_REG_AMWAR);
199
200 /* Add-On - Number of acquisitions */
201 apci3120_addon_write(dev, dmabuf->use_size, AMCC_OP_REG_AMWTC);
202
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);
206
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);
210 }
211
212 static void apci3120_setup_dma(struct comedi_device *dev,
213 struct comedi_subdevice *s)
214 {
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;
222
223 scan_bytes = comedi_samples_to_bytes(s, cmd->scan_end_arg);
224
225 if (cmd->stop_src == TRIG_COUNT) {
226 /*
227 * Must we fill full first buffer? And must we fill
228 * full second buffer when first is once filled?
229 */
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;
234 }
235
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)
241 dmalen0 += 2;
242 }
243 if (dmalen1 > scan_bytes) {
244 dmalen1 = scan_bytes;
245 if (cmd->scan_end_arg & 1)
246 dmalen1 -= 2;
247 if (dmalen1 < 4)
248 dmalen1 = 4;
249 }
250 } else {
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;
256 }
257 dmabuf0->use_size = dmalen0;
258 dmabuf1->use_size = dmalen1;
259
260 apci3120_init_dma(dev, dmabuf0);
261 }
262
263 /*
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.
267 *
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)
271 *
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
276 */
277 static unsigned int apci3120_ns_to_timer(struct comedi_device *dev,
278 unsigned int timer,
279 unsigned int ns,
280 unsigned int flags)
281 {
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;
286
287 switch (flags & CMDF_ROUND_MASK) {
288 case CMDF_ROUND_UP:
289 divisor = DIV_ROUND_UP(ns, timer_base);
290 break;
291 case CMDF_ROUND_DOWN:
292 divisor = ns / timer_base;
293 break;
294 case CMDF_ROUND_NEAREST:
295 default:
296 divisor = DIV_ROUND_CLOSEST(ns, timer_base);
297 break;
298 }
299
300 if (timer == 2) {
301 /* timer 2 is 24-bits */
302 if (divisor > 0x00ffffff)
303 divisor = 0x00ffffff;
304 } else {
305 /* timers 0 and 1 are 16-bits */
306 if (divisor > 0xffff)
307 divisor = 0xffff;
308 }
309 /* the timers require a minimum divisor of 2 */
310 if (divisor < 2)
311 divisor = 2;
312
313 return divisor;
314 }
315
316 static void apci3120_clr_timer2_interrupt(struct comedi_device *dev)
317 {
318 /* a dummy read of APCI3120_CTR0_REG clears the timer 2 interrupt */
319 inb(dev->iobase + APCI3120_CTR0_REG);
320 }
321
322 static void apci3120_timer_write(struct comedi_device *dev,
323 unsigned int timer, unsigned int val)
324 {
325 struct apci3120_private *devpriv = dev->private;
326
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);
332
333 if (timer == 2) {
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);
339 }
340 }
341
342 static unsigned int apci3120_timer_read(struct comedi_device *dev,
343 unsigned int timer)
344 {
345 struct apci3120_private *devpriv = dev->private;
346 unsigned int val;
347
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);
353
354 if (timer == 2) {
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);
360 }
361
362 return val;
363 }
364
365 static void apci3120_timer_set_mode(struct comedi_device *dev,
366 unsigned int timer, unsigned int mode)
367 {
368 struct apci3120_private *devpriv = dev->private;
369
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);
373 }
374
375 static void apci3120_timer_enable(struct comedi_device *dev,
376 unsigned int timer, bool enable)
377 {
378 struct apci3120_private *devpriv = dev->private;
379
380 if (enable)
381 devpriv->ctrl |= APCI3120_CTRL_GATE(timer);
382 else
383 devpriv->ctrl &= ~APCI3120_CTRL_GATE(timer);
384 outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
385 }
386
387 static void apci3120_exttrig_enable(struct comedi_device *dev, bool enable)
388 {
389 struct apci3120_private *devpriv = dev->private;
390
391 if (enable)
392 devpriv->ctrl |= APCI3120_CTRL_EXT_TRIG;
393 else
394 devpriv->ctrl &= ~APCI3120_CTRL_EXT_TRIG;
395 outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
396 }
397
398 static void apci3120_set_chanlist(struct comedi_device *dev,
399 struct comedi_subdevice *s,
400 int n_chan, unsigned int *chanlist)
401 {
402 struct apci3120_private *devpriv = dev->private;
403 int i;
404
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]);
409 unsigned int val;
410
411 val = APCI3120_CHANLIST_MUX(chan) |
412 APCI3120_CHANLIST_GAIN(range) |
413 APCI3120_CHANLIST_INDEX(i);
414
415 if (comedi_range_is_unipolar(s, range))
416 val |= APCI3120_CHANLIST_UNIPOLAR;
417
418 outw(val, dev->iobase + APCI3120_CHANLIST_REG);
419 }
420
421 /* a dummy read of APCI3120_TIMER_MODE_REG resets the ai FIFO */
422 inw(dev->iobase + APCI3120_TIMER_MODE_REG);
423
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);
427
428 /* enable chanlist scanning if necessary */
429 if (n_chan > 1)
430 devpriv->mode |= APCI3120_MODE_SCAN_ENA;
431 }
432
433 static void apci3120_interrupt_dma(struct comedi_device *dev,
434 struct comedi_subdevice *s)
435 {
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;
440 unsigned int nbytes;
441 unsigned int nsamples;
442
443 dmabuf = &devpriv->dmabuf[devpriv->cur_dmabuf];
444
445 nbytes = dmabuf->use_size - inl(devpriv->amcc + AMCC_OP_REG_MWTC);
446
447 if (nbytes < dmabuf->use_size)
448 dev_err(dev->class_dev, "Interrupted DMA transfer!\n");
449 if (nbytes & 1) {
450 dev_err(dev->class_dev, "Odd count of bytes in DMA ring!\n");
451 async->events |= COMEDI_CB_ERROR;
452 return;
453 }
454
455 nsamples = comedi_bytes_to_samples(s, nbytes);
456 if (nsamples) {
457 comedi_buf_write_samples(s, dmabuf->virt, nsamples);
458
459 if (!(cmd->flags & CMDF_WAKE_EOS))
460 async->events |= COMEDI_CB_EOS;
461 }
462
463 if ((async->events & COMEDI_CB_CANCEL_MASK) ||
464 (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg))
465 return;
466
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);
472 } else {
473 /* restart DMA if not using double buffering */
474 apci3120_init_dma(dev, dmabuf);
475 }
476 }
477
478 static irqreturn_t apci3120_interrupt(int irq, void *d)
479 {
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;
485 unsigned int status;
486 unsigned int int_amcc;
487
488 status = inw(dev->iobase + APCI3120_STATUS_REG);
489 int_amcc = inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
490
491 if (!(status & APCI3120_STATUS_INT_MASK) &&
492 !(int_amcc & ANY_S593X_INT)) {
493 dev_err(dev->class_dev, "IRQ from unknown source\n");
494 return IRQ_NONE;
495 }
496
497 outl(int_amcc | AINT_INT_MASK, devpriv->amcc + AMCC_OP_REG_INTCSR);
498
499 if (devpriv->ctrl & APCI3120_CTRL_EXT_TRIG)
500 apci3120_exttrig_enable(dev, false);
501
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");
506
507 if ((status & APCI3120_STATUS_EOS_INT) &&
508 (devpriv->mode & APCI3120_MODE_EOS_IRQ_ENA)) {
509 unsigned short val;
510 int i;
511
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);
515 }
516
517 devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA;
518 outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
519 }
520
521 if (status & APCI3120_STATUS_TIMER2_INT) {
522 /*
523 * for safety...
524 * timer2 interrupts are not enabled in the driver
525 */
526 apci3120_clr_timer2_interrupt(dev);
527 }
528
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);
532
533 /* do some data transfer */
534 apci3120_interrupt_dma(dev, s);
535 }
536
537 if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)
538 async->events |= COMEDI_CB_EOA;
539
540 comedi_handle_events(dev, s);
541
542 return IRQ_HANDLED;
543 }
544
545 static int apci3120_ai_cmd(struct comedi_device *dev,
546 struct comedi_subdevice *s)
547 {
548 struct apci3120_private *devpriv = dev->private;
549 struct comedi_cmd *cmd = &s->async->cmd;
550 unsigned int divisor;
551
552 /* set default mode bits */
553 devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC |
554 APCI3120_MODE_TIMER2_AS_TIMER;
555
556 /* AMCC- Clear write complete interrupt (DMA) */
557 outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR);
558
559 devpriv->cur_dmabuf = 0;
560
561 /* load chanlist for command scan */
562 apci3120_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist);
563
564 if (cmd->start_src == TRIG_EXT)
565 apci3120_exttrig_enable(dev, true);
566
567 if (cmd->scan_begin_src == TRIG_TIMER) {
568 /*
569 * Timer 1 is used in MODE2 (rate generator) to set the
570 * start time for each scan.
571 */
572 divisor = apci3120_ns_to_timer(dev, 1, cmd->scan_begin_arg,
573 cmd->flags);
574 apci3120_timer_set_mode(dev, 1, APCI3120_TIMER_MODE2);
575 apci3120_timer_write(dev, 1, divisor);
576 }
577
578 /*
579 * Timer 0 is used in MODE2 (rate generator) to set the conversion
580 * time for each acquisition.
581 */
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);
585
586 if (devpriv->use_dma)
587 apci3120_setup_dma(dev, s);
588 else
589 devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA;
590
591 /* set mode to enable acquisition */
592 outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
593
594 if (cmd->scan_begin_src == TRIG_TIMER)
595 apci3120_timer_enable(dev, 1, true);
596 apci3120_timer_enable(dev, 0, true);
597
598 return 0;
599 }
600
601 static int apci3120_ai_cmdtest(struct comedi_device *dev,
602 struct comedi_subdevice *s,
603 struct comedi_cmd *cmd)
604 {
605 unsigned int arg;
606 int err = 0;
607
608 /* Step 1 : check if triggers are trivially valid */
609
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);
616
617 if (err)
618 return 1;
619
620 /* Step 2a : make sure trigger sources are unique */
621
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);
625
626 /* Step 2b : and mutually compatible */
627
628 if (err)
629 return 2;
630
631 /* Step 3: check if arguments are trivially valid */
632
633 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
634
635 if (cmd->scan_begin_src == TRIG_TIMER) { /* Test Delay timing */
636 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
637 100000);
638 }
639
640 /* minimum conversion time per sample is 10us */
641 err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 10000);
642
643 err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
644 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
645 cmd->chanlist_len);
646
647 if (cmd->stop_src == TRIG_COUNT)
648 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
649 else /* TRIG_NONE */
650 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
651
652 if (err)
653 return 3;
654
655 /* Step 4: fix up any arguments */
656
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);
661 }
662
663 if (err)
664 return 4;
665
666 /* Step 5: check channel list if it exists */
667
668 return 0;
669 }
670
671 static int apci3120_cancel(struct comedi_device *dev,
672 struct comedi_subdevice *s)
673 {
674 struct apci3120_private *devpriv = dev->private;
675
676 /* Add-On - disable DMA */
677 outw(0, devpriv->addon + 4);
678
679 /* Add-On - disable bus master */
680 apci3120_addon_write(dev, 0, AMCC_OP_REG_AGCSTS);
681
682 /* AMCC - disable bus master */
683 outl(0, devpriv->amcc + AMCC_OP_REG_MCSR);
684
685 /* disable all counters, ext trigger, and reset scan */
686 devpriv->ctrl = 0;
687 outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
688
689 /* DISABLE_ALL_INTERRUPT */
690 devpriv->mode = 0;
691 outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
692
693 inw(dev->iobase + APCI3120_STATUS_REG);
694 devpriv->cur_dmabuf = 0;
695
696 return 0;
697 }
698
699 static int apci3120_ai_eoc(struct comedi_device *dev,
700 struct comedi_subdevice *s,
701 struct comedi_insn *insn,
702 unsigned long context)
703 {
704 unsigned int status;
705
706 status = inw(dev->iobase + APCI3120_STATUS_REG);
707 if ((status & APCI3120_STATUS_EOC_INT) == 0)
708 return 0;
709 return -EBUSY;
710 }
711
712 static int apci3120_ai_insn_read(struct comedi_device *dev,
713 struct comedi_subdevice *s,
714 struct comedi_insn *insn,
715 unsigned int *data)
716 {
717 struct apci3120_private *devpriv = dev->private;
718 unsigned int divisor;
719 int ret;
720 int i;
721
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);
726
727 /* load chanlist for single channel scan */
728 apci3120_set_chanlist(dev, s, 1, &insn->chanspec);
729
730 /*
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'.
735 */
736 apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE4);
737 apci3120_timer_enable(dev, 0, true);
738
739 /* fixed conversion time of 10 us */
740 divisor = apci3120_ns_to_timer(dev, 0, 10000, CMDF_ROUND_NEAREST);
741
742 for (i = 0; i < insn->n; i++) {
743 /* trigger conversion */
744 apci3120_timer_write(dev, 0, divisor);
745
746 ret = comedi_timeout(dev, s, insn, apci3120_ai_eoc, 0);
747 if (ret)
748 return ret;
749
750 data[i] = inw(dev->iobase + APCI3120_AI_FIFO_REG);
751 }
752
753 return insn->n;
754 }
755
756 static int apci3120_ao_ready(struct comedi_device *dev,
757 struct comedi_subdevice *s,
758 struct comedi_insn *insn,
759 unsigned long context)
760 {
761 unsigned int status;
762
763 status = inw(dev->iobase + APCI3120_STATUS_REG);
764 if (status & APCI3120_STATUS_DA_READY)
765 return 0;
766 return -EBUSY;
767 }
768
769 static int apci3120_ao_insn_write(struct comedi_device *dev,
770 struct comedi_subdevice *s,
771 struct comedi_insn *insn,
772 unsigned int *data)
773 {
774 unsigned int chan = CR_CHAN(insn->chanspec);
775 int i;
776
777 for (i = 0; i < insn->n; i++) {
778 unsigned int val = data[i];
779 int ret;
780
781 ret = comedi_timeout(dev, s, insn, apci3120_ao_ready, 0);
782 if (ret)
783 return ret;
784
785 outw(APCI3120_AO_MUX(chan) | APCI3120_AO_DATA(val),
786 dev->iobase + APCI3120_AO_REG(chan));
787
788 s->readback[chan] = val;
789 }
790
791 return insn->n;
792 }
793
794 static int apci3120_di_insn_bits(struct comedi_device *dev,
795 struct comedi_subdevice *s,
796 struct comedi_insn *insn,
797 unsigned int *data)
798 {
799 unsigned int status;
800
801 status = inw(dev->iobase + APCI3120_STATUS_REG);
802 data[1] = APCI3120_STATUS_TO_DI_BITS(status);
803
804 return insn->n;
805 }
806
807 static int apci3120_do_insn_bits(struct comedi_device *dev,
808 struct comedi_subdevice *s,
809 struct comedi_insn *insn,
810 unsigned int *data)
811 {
812 struct apci3120_private *devpriv = dev->private;
813
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);
818 }
819
820 data[1] = s->state;
821
822 return insn->n;
823 }
824
825 static int apci3120_timer_insn_config(struct comedi_device *dev,
826 struct comedi_subdevice *s,
827 struct comedi_insn *insn,
828 unsigned int *data)
829 {
830 struct apci3120_private *devpriv = dev->private;
831 unsigned int divisor;
832 unsigned int status;
833 unsigned int mode;
834 unsigned int timer_mode;
835
836 switch (data[0]) {
837 case INSN_CONFIG_ARM:
838 apci3120_clr_timer2_interrupt(dev);
839 divisor = apci3120_ns_to_timer(dev, 2, data[1],
840 CMDF_ROUND_DOWN);
841 apci3120_timer_write(dev, 2, divisor);
842 apci3120_timer_enable(dev, 2, true);
843 break;
844
845 case INSN_CONFIG_DISARM:
846 apci3120_timer_enable(dev, 2, false);
847 apci3120_clr_timer2_interrupt(dev);
848 break;
849
850 case INSN_CONFIG_GET_COUNTER_STATUS:
851 data[1] = 0;
852 data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING |
853 COMEDI_COUNTER_TERMINAL_COUNT;
854
855 if (devpriv->ctrl & APCI3120_CTRL_GATE(2)) {
856 data[1] |= COMEDI_COUNTER_ARMED;
857 data[1] |= COMEDI_COUNTER_COUNTING;
858 }
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;
863 }
864 break;
865
866 case INSN_CONFIG_SET_COUNTER_MODE:
867 switch (data[1]) {
868 case I8254_MODE0:
869 mode = APCI3120_MODE_TIMER2_AS_COUNTER;
870 timer_mode = APCI3120_TIMER_MODE0;
871 break;
872 case I8254_MODE2:
873 mode = APCI3120_MODE_TIMER2_AS_TIMER;
874 timer_mode = APCI3120_TIMER_MODE2;
875 break;
876 case I8254_MODE4:
877 mode = APCI3120_MODE_TIMER2_AS_TIMER;
878 timer_mode = APCI3120_TIMER_MODE4;
879 break;
880 case I8254_MODE5:
881 mode = APCI3120_MODE_TIMER2_AS_WDOG;
882 timer_mode = APCI3120_TIMER_MODE5;
883 break;
884 default:
885 return -EINVAL;
886 }
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);
893 break;
894
895 default:
896 return -EINVAL;
897 }
898
899 return insn->n;
900 }
901
902 static int apci3120_timer_insn_read(struct comedi_device *dev,
903 struct comedi_subdevice *s,
904 struct comedi_insn *insn,
905 unsigned int *data)
906 {
907 int i;
908
909 for (i = 0; i < insn->n; i++)
910 data[i] = apci3120_timer_read(dev, 2);
911
912 return insn->n;
913 }
914
915 static void apci3120_dma_alloc(struct comedi_device *dev)
916 {
917 struct apci3120_private *devpriv = dev->private;
918 struct apci3120_dmabuf *dmabuf;
919 int order;
920 int i;
921
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,
926 PAGE_SIZE << order,
927 &dmabuf->hw,
928 GFP_KERNEL);
929 if (dmabuf->virt)
930 break;
931 }
932 if (!dmabuf->virt)
933 break;
934 dmabuf->size = PAGE_SIZE << order;
935
936 if (i == 0)
937 devpriv->use_dma = 1;
938 if (i == 1)
939 devpriv->use_double_buffer = 1;
940 }
941 }
942
943 static void apci3120_dma_free(struct comedi_device *dev)
944 {
945 struct apci3120_private *devpriv = dev->private;
946 struct apci3120_dmabuf *dmabuf;
947 int i;
948
949 if (!devpriv)
950 return;
951
952 for (i = 0; i < 2; i++) {
953 dmabuf = &devpriv->dmabuf[i];
954 if (dmabuf->virt) {
955 dma_free_coherent(dev->hw_dev, dmabuf->size,
956 dmabuf->virt, dmabuf->hw);
957 }
958 }
959 }
960
961 static void apci3120_reset(struct comedi_device *dev)
962 {
963 /* disable all interrupt sources */
964 outb(0, dev->iobase + APCI3120_MODE_REG);
965
966 /* disable all counters, ext trigger, and reset scan */
967 outw(0, dev->iobase + APCI3120_CTRL_REG);
968
969 /* clear interrupt status */
970 inw(dev->iobase + APCI3120_STATUS_REG);
971 }
972
973 static int apci3120_auto_attach(struct comedi_device *dev,
974 unsigned long context)
975 {
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;
980 unsigned int status;
981 int ret;
982
983 if (context < ARRAY_SIZE(apci3120_boardtypes))
984 board = &apci3120_boardtypes[context];
985 if (!board)
986 return -ENODEV;
987 dev->board_ptr = board;
988 dev->board_name = board->name;
989
990 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
991 if (!devpriv)
992 return -ENOMEM;
993
994 ret = comedi_pci_enable(dev);
995 if (ret)
996 return ret;
997 pci_set_master(pcidev);
998
999 dev->iobase = pci_resource_start(pcidev, 1);
1000 devpriv->amcc = pci_resource_start(pcidev, 0);
1001 devpriv->addon = pci_resource_start(pcidev, 2);
1002
1003 apci3120_reset(dev);
1004
1005 if (pcidev->irq > 0) {
1006 ret = request_irq(pcidev->irq, apci3120_interrupt, IRQF_SHARED,
1007 dev->board_name, dev);
1008 if (ret == 0) {
1009 dev->irq = pcidev->irq;
1010
1011 apci3120_dma_alloc(dev);
1012 }
1013 }
1014
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;
1019 else
1020 devpriv->osc_base = APCI3120_REVA_OSC_BASE;
1021
1022 ret = comedi_alloc_subdevices(dev, 5);
1023 if (ret)
1024 return ret;
1025
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;
1030 s->n_chan = 16;
1031 s->maxdata = board->ai_is_16bit ? 0xffff : 0x0fff;
1032 s->range_table = &apci3120_ai_range;
1033 s->insn_read = apci3120_ai_insn_read;
1034 if (dev->irq) {
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;
1041 }
1042
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;
1048 s->n_chan = 8;
1049 s->maxdata = 0x3fff;
1050 s->range_table = &range_bipolar10;
1051 s->insn_write = apci3120_ao_insn_write;
1052
1053 ret = comedi_alloc_subdev_readback(s);
1054 if (ret)
1055 return ret;
1056 } else {
1057 s->type = COMEDI_SUBD_UNUSED;
1058 }
1059
1060 /* Digital Input subdevice */
1061 s = &dev->subdevices[2];
1062 s->type = COMEDI_SUBD_DI;
1063 s->subdev_flags = SDF_READABLE;
1064 s->n_chan = 4;
1065 s->maxdata = 1;
1066 s->range_table = &range_digital;
1067 s->insn_bits = apci3120_di_insn_bits;
1068
1069 /* Digital Output subdevice */
1070 s = &dev->subdevices[3];
1071 s->type = COMEDI_SUBD_DO;
1072 s->subdev_flags = SDF_WRITABLE;
1073 s->n_chan = 4;
1074 s->maxdata = 1;
1075 s->range_table = &range_digital;
1076 s->insn_bits = apci3120_do_insn_bits;
1077
1078 /* Timer subdevice */
1079 s = &dev->subdevices[4];
1080 s->type = COMEDI_SUBD_TIMER;
1081 s->subdev_flags = SDF_READABLE;
1082 s->n_chan = 1;
1083 s->maxdata = 0x00ffffff;
1084 s->insn_config = apci3120_timer_insn_config;
1085 s->insn_read = apci3120_timer_insn_read;
1086
1087 return 0;
1088 }
1089
1090 static void apci3120_detach(struct comedi_device *dev)
1091 {
1092 comedi_pci_detach(dev);
1093 apci3120_dma_free(dev);
1094 }
1095
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,
1101 };
1102
1103 static int apci3120_pci_probe(struct pci_dev *dev,
1104 const struct pci_device_id *id)
1105 {
1106 return comedi_pci_auto_config(dev, &apci3120_driver, id->driver_data);
1107 }
1108
1109 static const struct pci_device_id apci3120_pci_table[] = {
1110 { PCI_VDEVICE(AMCC, 0x818d), BOARD_APCI3120 },
1111 { PCI_VDEVICE(AMCC, 0x828d), BOARD_APCI3001 },
1112 { 0 }
1113 };
1114 MODULE_DEVICE_TABLE(pci, apci3120_pci_table);
1115
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,
1121 };
1122 module_comedi_pci_driver(apci3120_driver, apci3120_pci_driver);
1123
1124 MODULE_AUTHOR("Comedi http://www.comedi.org");
1125 MODULE_DESCRIPTION("ADDI-DATA APCI-3120, Analog input board");
1126 MODULE_LICENSE("GPL");
This page took 0.085585 seconds and 5 git commands to generate.