Version:  2.0.40 2.2.26 2.4.37 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6

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/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 ''.
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");
1127 

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