Version:  2.0.40 2.2.26 2.4.37 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0

Linux/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/pci.h>
 26 #include <linux/interrupt.h>
 27 
 28 #include "../comedidev.h"
 29 #include "comedi_fc.h"
 30 #include "amcc_s5933.h"
 31 
 32 /*
 33  * PCI BAR 0 register map (devpriv->amcc)
 34  * see amcc_s5933.h for register and bit defines
 35  */
 36 #define APCI3120_FIFO_ADVANCE_ON_BYTE_2         (1 << 29)
 37 
 38 /*
 39  * PCI BAR 1 register map (dev->iobase)
 40  */
 41 #define APCI3120_AI_FIFO_REG                    0x00
 42 #define APCI3120_CTRL_REG                       0x00
 43 #define APCI3120_CTRL_EXT_TRIG                  (1 << 15)
 44 #define APCI3120_CTRL_GATE(x)                   (1 << (12 + (x)))
 45 #define APCI3120_CTRL_PR(x)                     (((x) & 0xf) << 8)
 46 #define APCI3120_CTRL_PA(x)                     (((x) & 0xf) << 0)
 47 #define APCI3120_AI_SOFTTRIG_REG                0x02
 48 #define APCI3120_STATUS_REG                     0x02
 49 #define APCI3120_STATUS_EOC_INT                 (1 << 15)
 50 #define APCI3120_STATUS_AMCC_INT                (1 << 14)
 51 #define APCI3120_STATUS_EOS_INT                 (1 << 13)
 52 #define APCI3120_STATUS_TIMER2_INT              (1 << 12)
 53 #define APCI3120_STATUS_INT_MASK                (0xf << 12)
 54 #define APCI3120_STATUS_TO_DI_BITS(x)           (((x) >> 8) & 0xf)
 55 #define APCI3120_STATUS_TO_VERSION(x)           (((x) >> 4) & 0xf)
 56 #define APCI3120_STATUS_FIFO_FULL               (1 << 2)
 57 #define APCI3120_STATUS_FIFO_EMPTY              (1 << 1)
 58 #define APCI3120_STATUS_DA_READY                (1 << 0)
 59 #define APCI3120_TIMER_REG                      0x04
 60 #define APCI3120_CHANLIST_REG                   0x06
 61 #define APCI3120_CHANLIST_INDEX(x)              (((x) & 0xf) << 8)
 62 #define APCI3120_CHANLIST_UNIPOLAR              (1 << 7)
 63 #define APCI3120_CHANLIST_GAIN(x)               (((x) & 0x3) << 4)
 64 #define APCI3120_CHANLIST_MUX(x)                (((x) & 0xf) << 0)
 65 #define APCI3120_AO_REG(x)                      (0x08 + (((x) / 4) * 2))
 66 #define APCI3120_AO_MUX(x)                      (((x) & 0x3) << 14)
 67 #define APCI3120_AO_DATA(x)                     ((x) << 0)
 68 #define APCI3120_TIMER_MODE_REG                 0x0c
 69 #define APCI3120_TIMER_MODE(_t, _m)             ((_m) << ((_t) * 2))
 70 #define APCI3120_TIMER_MODE0                    0  /* I8254_MODE0 */
 71 #define APCI3120_TIMER_MODE2                    1  /* I8254_MODE2 */
 72 #define APCI3120_TIMER_MODE4                    2  /* I8254_MODE4 */
 73 #define APCI3120_TIMER_MODE5                    3  /* I8254_MODE5 */
 74 #define APCI3120_TIMER_MODE_MASK(_t)            (3 << ((_t) * 2))
 75 #define APCI3120_CTR0_REG                       0x0d
 76 #define APCI3120_CTR0_DO_BITS(x)                ((x) << 4)
 77 #define APCI3120_CTR0_TIMER_SEL(x)              ((x) << 0)
 78 #define APCI3120_MODE_REG                       0x0e
 79 #define APCI3120_MODE_TIMER2_CLK_OSC            (0 << 6)
 80 #define APCI3120_MODE_TIMER2_CLK_OUT1           (1 << 6)
 81 #define APCI3120_MODE_TIMER2_CLK_EOC            (2 << 6)
 82 #define APCI3120_MODE_TIMER2_CLK_EOS            (3 << 6)
 83 #define APCI3120_MODE_TIMER2_CLK_MASK           (3 << 6)
 84 #define APCI3120_MODE_TIMER2_AS_TIMER           (0 << 4)
 85 #define APCI3120_MODE_TIMER2_AS_COUNTER         (1 << 4)
 86 #define APCI3120_MODE_TIMER2_AS_WDOG            (2 << 4)
 87 #define APCI3120_MODE_TIMER2_AS_MASK            (3 << 4)  /* sets AS_TIMER */
 88 #define APCI3120_MODE_SCAN_ENA                  (1 << 3)
 89 #define APCI3120_MODE_TIMER2_IRQ_ENA            (1 << 2)
 90 #define APCI3120_MODE_EOS_IRQ_ENA               (1 << 1)
 91 #define APCI3120_MODE_EOC_IRQ_ENA               (1 << 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           (1 << 1)
100 #define APCI3120_ADDON_CTRL_A2P_FIFO_ENA        (1 << 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_EOC_INT) == 0 &&
508             (devpriv->mode & APCI3120_MODE_EOC_IRQ_ENA)) {
509                 /* nothing to do... EOC mode is not currently used */
510         }
511 
512         if ((status & APCI3120_STATUS_EOS_INT) &&
513             (devpriv->mode & APCI3120_MODE_EOS_IRQ_ENA)) {
514                 unsigned short val;
515                 int i;
516 
517                 for (i = 0; i < cmd->chanlist_len; i++) {
518                         val = inw(dev->iobase + APCI3120_AI_FIFO_REG);
519                         comedi_buf_write_samples(s, &val, 1);
520                 }
521 
522                 devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA;
523                 outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
524         }
525 
526         if (status & APCI3120_STATUS_TIMER2_INT) {
527                 /*
528                  * for safety...
529                  * timer2 interrupts are not enabled in the driver
530                  */
531                 apci3120_clr_timer2_interrupt(dev);
532         }
533 
534         if (status & APCI3120_STATUS_AMCC_INT) {
535                 /* AMCC- Clear write complete interrupt (DMA) */
536                 outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR);
537 
538                 /* do some data transfer */
539                 apci3120_interrupt_dma(dev, s);
540         }
541 
542         if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)
543                 async->events |= COMEDI_CB_EOA;
544 
545         comedi_handle_events(dev, s);
546 
547         return IRQ_HANDLED;
548 }
549 
550 static int apci3120_ai_cmd(struct comedi_device *dev,
551                            struct comedi_subdevice *s)
552 {
553         struct apci3120_private *devpriv = dev->private;
554         struct comedi_cmd *cmd = &s->async->cmd;
555         unsigned int divisor;
556 
557         /* set default mode bits */
558         devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC |
559                         APCI3120_MODE_TIMER2_AS_TIMER;
560 
561         /* AMCC- Clear write complete interrupt (DMA) */
562         outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR);
563 
564         devpriv->cur_dmabuf = 0;
565 
566         /* load chanlist for command scan */
567         apci3120_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist);
568 
569         if (cmd->start_src == TRIG_EXT)
570                 apci3120_exttrig_enable(dev, true);
571 
572         if (cmd->scan_begin_src == TRIG_TIMER) {
573                 /*
574                  * Timer 1 is used in MODE2 (rate generator) to set the
575                  * start time for each scan.
576                  */
577                 divisor = apci3120_ns_to_timer(dev, 1, cmd->scan_begin_arg,
578                                                cmd->flags);
579                 apci3120_timer_set_mode(dev, 1, APCI3120_TIMER_MODE2);
580                 apci3120_timer_write(dev, 1, divisor);
581         }
582 
583         /*
584          * Timer 0 is used in MODE2 (rate generator) to set the conversion
585          * time for each acquisition.
586          */
587         divisor = apci3120_ns_to_timer(dev, 0, cmd->convert_arg, cmd->flags);
588         apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2);
589         apci3120_timer_write(dev, 0, divisor);
590 
591         if (devpriv->use_dma)
592                 apci3120_setup_dma(dev, s);
593         else
594                 devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA;
595 
596         /* set mode to enable acquisition */
597         outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
598 
599         if (cmd->scan_begin_src == TRIG_TIMER)
600                 apci3120_timer_enable(dev, 1, true);
601         apci3120_timer_enable(dev, 0, true);
602 
603         return 0;
604 }
605 
606 static int apci3120_ai_cmdtest(struct comedi_device *dev,
607                                struct comedi_subdevice *s,
608                                struct comedi_cmd *cmd)
609 {
610         unsigned int arg;
611         int err = 0;
612 
613         /* Step 1 : check if triggers are trivially valid */
614 
615         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
616         err |= cfc_check_trigger_src(&cmd->scan_begin_src,
617                                         TRIG_TIMER | TRIG_FOLLOW);
618         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
619         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
620         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
621 
622         if (err)
623                 return 1;
624 
625         /* Step 2a : make sure trigger sources are unique */
626 
627         err |= cfc_check_trigger_is_unique(cmd->start_src);
628         err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
629         err |= cfc_check_trigger_is_unique(cmd->stop_src);
630 
631         /* Step 2b : and mutually compatible */
632 
633         if (err)
634                 return 2;
635 
636         /* Step 3: check if arguments are trivially valid */
637 
638         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
639 
640         if (cmd->scan_begin_src == TRIG_TIMER)  /* Test Delay timing */
641                 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 100000);
642 
643         /* minimum conversion time per sample is 10us */
644         err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 10000);
645 
646         err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
647         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
648 
649         if (cmd->stop_src == TRIG_COUNT)
650                 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
651         else    /*  TRIG_NONE */
652                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
653 
654         if (err)
655                 return 3;
656 
657         /* Step 4: fix up any arguments */
658 
659         if (cmd->scan_begin_src == TRIG_TIMER) {
660                 /* scan begin must be larger than the scan time */
661                 arg = cmd->convert_arg * cmd->scan_end_arg;
662                 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, arg);
663         }
664 
665         if (err)
666                 return 4;
667 
668         /* Step 5: check channel list if it exists */
669 
670         return 0;
671 }
672 
673 static int apci3120_cancel(struct comedi_device *dev,
674                            struct comedi_subdevice *s)
675 {
676         struct apci3120_private *devpriv = dev->private;
677 
678         /* Add-On - disable DMA */
679         outw(0, devpriv->addon + 4);
680 
681         /* Add-On - disable bus master */
682         apci3120_addon_write(dev, 0, AMCC_OP_REG_AGCSTS);
683 
684         /* AMCC - disable bus master */
685         outl(0, devpriv->amcc + AMCC_OP_REG_MCSR);
686 
687         /* disable all counters, ext trigger, and reset scan */
688         devpriv->ctrl = 0;
689         outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
690 
691         /* DISABLE_ALL_INTERRUPT */
692         devpriv->mode = 0;
693         outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
694 
695         inw(dev->iobase + APCI3120_STATUS_REG);
696         devpriv->cur_dmabuf = 0;
697 
698         return 0;
699 }
700 
701 static int apci3120_ai_eoc(struct comedi_device *dev,
702                            struct comedi_subdevice *s,
703                            struct comedi_insn *insn,
704                            unsigned long context)
705 {
706         unsigned int status;
707 
708         status = inw(dev->iobase + APCI3120_STATUS_REG);
709         if ((status & APCI3120_STATUS_EOC_INT) == 0)
710                 return 0;
711         return -EBUSY;
712 }
713 
714 static int apci3120_ai_insn_read(struct comedi_device *dev,
715                                  struct comedi_subdevice *s,
716                                  struct comedi_insn *insn,
717                                  unsigned int *data)
718 {
719         struct apci3120_private *devpriv = dev->private;
720         unsigned int divisor;
721         int ret;
722         int i;
723 
724         /* set mode for A/D conversions by software trigger with timer 0 */
725         devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC |
726                         APCI3120_MODE_TIMER2_AS_TIMER;
727         outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
728 
729         /* load chanlist for single channel scan */
730         apci3120_set_chanlist(dev, s, 1, &insn->chanspec);
731 
732         /*
733          * Timer 0 is used in MODE4 (software triggered strobe) to set the
734          * conversion time for each acquisition. Each conversion is triggered
735          * when the divisor is written to the timer, The conversion is done
736          * when the EOC bit in the status register is ''.
737          */
738         apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE4);
739         apci3120_timer_enable(dev, 0, true);
740 
741         /* fixed conversion time of 10 us */
742         divisor = apci3120_ns_to_timer(dev, 0, 10000, CMDF_ROUND_NEAREST);
743 
744         for (i = 0; i < insn->n; i++) {
745                 /* trigger conversion */
746                 apci3120_timer_write(dev, 0, divisor);
747 
748                 ret = comedi_timeout(dev, s, insn, apci3120_ai_eoc, 0);
749                 if (ret)
750                         return ret;
751 
752                 data[i] = inw(dev->iobase + APCI3120_AI_FIFO_REG);
753         }
754 
755         return insn->n;
756 }
757 
758 static int apci3120_ao_ready(struct comedi_device *dev,
759                              struct comedi_subdevice *s,
760                              struct comedi_insn *insn,
761                              unsigned long context)
762 {
763         unsigned int status;
764 
765         status = inw(dev->iobase + APCI3120_STATUS_REG);
766         if (status & APCI3120_STATUS_DA_READY)
767                 return 0;
768         return -EBUSY;
769 }
770 
771 static int apci3120_ao_insn_write(struct comedi_device *dev,
772                                   struct comedi_subdevice *s,
773                                   struct comedi_insn *insn,
774                                   unsigned int *data)
775 {
776         unsigned int chan = CR_CHAN(insn->chanspec);
777         int i;
778 
779         for (i = 0; i < insn->n; i++) {
780                 unsigned int val = data[i];
781                 int ret;
782 
783                 ret = comedi_timeout(dev, s, insn, apci3120_ao_ready, 0);
784                 if (ret)
785                         return ret;
786 
787                 outw(APCI3120_AO_MUX(chan) | APCI3120_AO_DATA(val),
788                      dev->iobase + APCI3120_AO_REG(chan));
789 
790                 s->readback[chan] = val;
791         }
792 
793         return insn->n;
794 }
795 
796 static int apci3120_di_insn_bits(struct comedi_device *dev,
797                                  struct comedi_subdevice *s,
798                                  struct comedi_insn *insn,
799                                  unsigned int *data)
800 {
801         unsigned int status;
802 
803         status = inw(dev->iobase + APCI3120_STATUS_REG);
804         data[1] = APCI3120_STATUS_TO_DI_BITS(status);
805 
806         return insn->n;
807 }
808 
809 static int apci3120_do_insn_bits(struct comedi_device *dev,
810                                  struct comedi_subdevice *s,
811                                  struct comedi_insn *insn,
812                                  unsigned int *data)
813 {
814         struct apci3120_private *devpriv = dev->private;
815 
816         if (comedi_dio_update_state(s, data)) {
817                 devpriv->do_bits = s->state;
818                 outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits),
819                      dev->iobase + APCI3120_CTR0_REG);
820         }
821 
822         data[1] = s->state;
823 
824         return insn->n;
825 }
826 
827 static int apci3120_timer_insn_config(struct comedi_device *dev,
828                                       struct comedi_subdevice *s,
829                                       struct comedi_insn *insn,
830                                       unsigned int *data)
831 {
832         struct apci3120_private *devpriv = dev->private;
833         unsigned int divisor;
834         unsigned int status;
835         unsigned int mode;
836         unsigned int timer_mode;
837 
838         switch (data[0]) {
839         case INSN_CONFIG_ARM:
840                 apci3120_clr_timer2_interrupt(dev);
841                 divisor = apci3120_ns_to_timer(dev, 2, data[1],
842                                                CMDF_ROUND_DOWN);
843                 apci3120_timer_write(dev, 2, divisor);
844                 apci3120_timer_enable(dev, 2, true);
845                 break;
846 
847         case INSN_CONFIG_DISARM:
848                 apci3120_timer_enable(dev, 2, false);
849                 apci3120_clr_timer2_interrupt(dev);
850                 break;
851 
852         case INSN_CONFIG_GET_COUNTER_STATUS:
853                 data[1] = 0;
854                 data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING |
855                           COMEDI_COUNTER_TERMINAL_COUNT;
856 
857                 if (devpriv->ctrl & APCI3120_CTRL_GATE(2)) {
858                         data[1] |= COMEDI_COUNTER_ARMED;
859                         data[1] |= COMEDI_COUNTER_COUNTING;
860                 }
861                 status = inw(dev->iobase + APCI3120_STATUS_REG);
862                 if (status & APCI3120_STATUS_TIMER2_INT) {
863                         data[1] &= ~COMEDI_COUNTER_COUNTING;
864                         data[1] |= COMEDI_COUNTER_TERMINAL_COUNT;
865                 }
866                 break;
867 
868         case INSN_CONFIG_SET_COUNTER_MODE:
869                 switch (data[1]) {
870                 case I8254_MODE0:
871                         mode = APCI3120_MODE_TIMER2_AS_COUNTER;
872                         timer_mode = APCI3120_TIMER_MODE0;
873                         break;
874                 case I8254_MODE2:
875                         mode = APCI3120_MODE_TIMER2_AS_TIMER;
876                         timer_mode = APCI3120_TIMER_MODE2;
877                         break;
878                 case I8254_MODE4:
879                         mode = APCI3120_MODE_TIMER2_AS_TIMER;
880                         timer_mode = APCI3120_TIMER_MODE4;
881                         break;
882                 case I8254_MODE5:
883                         mode = APCI3120_MODE_TIMER2_AS_WDOG;
884                         timer_mode = APCI3120_TIMER_MODE5;
885                         break;
886                 default:
887                         return -EINVAL;
888                 }
889                 apci3120_timer_enable(dev, 2, false);
890                 apci3120_clr_timer2_interrupt(dev);
891                 apci3120_timer_set_mode(dev, 2, timer_mode);
892                 devpriv->mode &= ~APCI3120_MODE_TIMER2_AS_MASK;
893                 devpriv->mode |= mode;
894                 outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
895                 break;
896 
897         default:
898                 return -EINVAL;
899         }
900 
901         return insn->n;
902 }
903 
904 static int apci3120_timer_insn_read(struct comedi_device *dev,
905                                     struct comedi_subdevice *s,
906                                     struct comedi_insn *insn,
907                                     unsigned int *data)
908 {
909         int i;
910 
911         for (i = 0; i < insn->n; i++)
912                 data[i] = apci3120_timer_read(dev, 2);
913 
914         return insn->n;
915 }
916 
917 static void apci3120_dma_alloc(struct comedi_device *dev)
918 {
919         struct apci3120_private *devpriv = dev->private;
920         struct apci3120_dmabuf *dmabuf;
921         int order;
922         int i;
923 
924         for (i = 0; i < 2; i++) {
925                 dmabuf = &devpriv->dmabuf[i];
926                 for (order = 2; order >= 0; order--) {
927                         dmabuf->virt = dma_alloc_coherent(dev->hw_dev,
928                                                           PAGE_SIZE << order,
929                                                           &dmabuf->hw,
930                                                           GFP_KERNEL);
931                         if (dmabuf->virt)
932                                 break;
933                 }
934                 if (!dmabuf->virt)
935                         break;
936                 dmabuf->size = PAGE_SIZE << order;
937 
938                 if (i == 0)
939                         devpriv->use_dma = 1;
940                 if (i == 1)
941                         devpriv->use_double_buffer = 1;
942         }
943 }
944 
945 static void apci3120_dma_free(struct comedi_device *dev)
946 {
947         struct apci3120_private *devpriv = dev->private;
948         struct apci3120_dmabuf *dmabuf;
949         int i;
950 
951         if (!devpriv)
952                 return;
953 
954         for (i = 0; i < 2; i++) {
955                 dmabuf = &devpriv->dmabuf[i];
956                 if (dmabuf->virt) {
957                         dma_free_coherent(dev->hw_dev, dmabuf->size,
958                                           dmabuf->virt, dmabuf->hw);
959                 }
960         }
961 }
962 
963 static void apci3120_reset(struct comedi_device *dev)
964 {
965         /* disable all interrupt sources */
966         outb(0, dev->iobase + APCI3120_MODE_REG);
967 
968         /* disable all counters, ext trigger, and reset scan */
969         outw(0, dev->iobase + APCI3120_CTRL_REG);
970 
971         /* clear interrupt status */
972         inw(dev->iobase + APCI3120_STATUS_REG);
973 }
974 
975 static int apci3120_auto_attach(struct comedi_device *dev,
976                                 unsigned long context)
977 {
978         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
979         const struct apci3120_board *this_board = NULL;
980         struct apci3120_private *devpriv;
981         struct comedi_subdevice *s;
982         unsigned int status;
983         int ret;
984 
985         if (context < ARRAY_SIZE(apci3120_boardtypes))
986                 this_board = &apci3120_boardtypes[context];
987         if (!this_board)
988                 return -ENODEV;
989         dev->board_ptr = this_board;
990         dev->board_name = this_board->name;
991 
992         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
993         if (!devpriv)
994                 return -ENOMEM;
995 
996         ret = comedi_pci_enable(dev);
997         if (ret)
998                 return ret;
999         pci_set_master(pcidev);
1000 
1001         dev->iobase = pci_resource_start(pcidev, 1);
1002         devpriv->amcc = pci_resource_start(pcidev, 0);
1003         devpriv->addon = pci_resource_start(pcidev, 2);
1004 
1005         apci3120_reset(dev);
1006 
1007         if (pcidev->irq > 0) {
1008                 ret = request_irq(pcidev->irq, apci3120_interrupt, IRQF_SHARED,
1009                                   dev->board_name, dev);
1010                 if (ret == 0) {
1011                         dev->irq = pcidev->irq;
1012 
1013                         apci3120_dma_alloc(dev);
1014                 }
1015         }
1016 
1017         status = inw(dev->iobase + APCI3120_STATUS_REG);
1018         if (APCI3120_STATUS_TO_VERSION(status) == APCI3120_REVB ||
1019             context == BOARD_APCI3001)
1020                 devpriv->osc_base = APCI3120_REVB_OSC_BASE;
1021         else
1022                 devpriv->osc_base = APCI3120_REVA_OSC_BASE;
1023 
1024         ret = comedi_alloc_subdevices(dev, 5);
1025         if (ret)
1026                 return ret;
1027 
1028         /* Analog Input subdevice */
1029         s = &dev->subdevices[0];
1030         s->type         = COMEDI_SUBD_AI;
1031         s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
1032         s->n_chan       = 16;
1033         s->maxdata      = this_board->ai_is_16bit ? 0xffff : 0x0fff;
1034         s->range_table  = &apci3120_ai_range;
1035         s->insn_read    = apci3120_ai_insn_read;
1036         if (dev->irq) {
1037                 dev->read_subdev = s;
1038                 s->subdev_flags |= SDF_CMD_READ;
1039                 s->len_chanlist = s->n_chan;
1040                 s->do_cmdtest   = apci3120_ai_cmdtest;
1041                 s->do_cmd       = apci3120_ai_cmd;
1042                 s->cancel       = apci3120_cancel;
1043         }
1044 
1045         /* Analog Output subdevice */
1046         s = &dev->subdevices[1];
1047         if (this_board->has_ao) {
1048                 s->type         = COMEDI_SUBD_AO;
1049                 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
1050                 s->n_chan       = 8;
1051                 s->maxdata      = 0x3fff;
1052                 s->range_table  = &range_bipolar10;
1053                 s->insn_write   = apci3120_ao_insn_write;
1054 
1055                 ret = comedi_alloc_subdev_readback(s);
1056                 if (ret)
1057                         return ret;
1058         } else {
1059                 s->type         = COMEDI_SUBD_UNUSED;
1060         }
1061 
1062         /* Digital Input subdevice */
1063         s = &dev->subdevices[2];
1064         s->type         = COMEDI_SUBD_DI;
1065         s->subdev_flags = SDF_READABLE;
1066         s->n_chan       = 4;
1067         s->maxdata      = 1;
1068         s->range_table  = &range_digital;
1069         s->insn_bits    = apci3120_di_insn_bits;
1070 
1071         /* Digital Output subdevice */
1072         s = &dev->subdevices[3];
1073         s->type         = COMEDI_SUBD_DO;
1074         s->subdev_flags = SDF_WRITABLE;
1075         s->n_chan       = 4;
1076         s->maxdata      = 1;
1077         s->range_table  = &range_digital;
1078         s->insn_bits    = apci3120_do_insn_bits;
1079 
1080         /* Timer subdevice */
1081         s = &dev->subdevices[4];
1082         s->type         = COMEDI_SUBD_TIMER;
1083         s->subdev_flags = SDF_READABLE;
1084         s->n_chan       = 1;
1085         s->maxdata      = 0x00ffffff;
1086         s->insn_config  = apci3120_timer_insn_config;
1087         s->insn_read    = apci3120_timer_insn_read;
1088 
1089         return 0;
1090 }
1091 
1092 static void apci3120_detach(struct comedi_device *dev)
1093 {
1094         comedi_pci_detach(dev);
1095         apci3120_dma_free(dev);
1096 }
1097 
1098 static struct comedi_driver apci3120_driver = {
1099         .driver_name    = "addi_apci_3120",
1100         .module         = THIS_MODULE,
1101         .auto_attach    = apci3120_auto_attach,
1102         .detach         = apci3120_detach,
1103 };
1104 
1105 static int apci3120_pci_probe(struct pci_dev *dev,
1106                               const struct pci_device_id *id)
1107 {
1108         return comedi_pci_auto_config(dev, &apci3120_driver, id->driver_data);
1109 }
1110 
1111 static const struct pci_device_id apci3120_pci_table[] = {
1112         { PCI_VDEVICE(AMCC, 0x818d), BOARD_APCI3120 },
1113         { PCI_VDEVICE(AMCC, 0x828d), BOARD_APCI3001 },
1114         { 0 }
1115 };
1116 MODULE_DEVICE_TABLE(pci, apci3120_pci_table);
1117 
1118 static struct pci_driver apci3120_pci_driver = {
1119         .name           = "addi_apci_3120",
1120         .id_table       = apci3120_pci_table,
1121         .probe          = apci3120_pci_probe,
1122         .remove         = comedi_pci_auto_unconfig,
1123 };
1124 module_comedi_pci_driver(apci3120_driver, apci3120_pci_driver);
1125 
1126 MODULE_AUTHOR("Comedi http://www.comedi.org");
1127 MODULE_DESCRIPTION("ADDI-DATA APCI-3120, Analog input board");
1128 MODULE_LICENSE("GPL");
1129 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us