Version:  2.0.40 2.2.26 2.4.37 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 4.1

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         (1 << 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                  (1 << 15)
 42 #define APCI3120_CTRL_GATE(x)                   (1 << (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                 (1 << 15)
 48 #define APCI3120_STATUS_AMCC_INT                (1 << 14)
 49 #define APCI3120_STATUS_EOS_INT                 (1 << 13)
 50 #define APCI3120_STATUS_TIMER2_INT              (1 << 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               (1 << 2)
 55 #define APCI3120_STATUS_FIFO_EMPTY              (1 << 1)
 56 #define APCI3120_STATUS_DA_READY                (1 << 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              (1 << 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_OSC            (0 << 6)
 78 #define APCI3120_MODE_TIMER2_CLK_OUT1           (1 << 6)
 79 #define APCI3120_MODE_TIMER2_CLK_EOC            (2 << 6)
 80 #define APCI3120_MODE_TIMER2_CLK_EOS            (3 << 6)
 81 #define APCI3120_MODE_TIMER2_CLK_MASK           (3 << 6)
 82 #define APCI3120_MODE_TIMER2_AS_TIMER           (0 << 4)
 83 #define APCI3120_MODE_TIMER2_AS_COUNTER         (1 << 4)
 84 #define APCI3120_MODE_TIMER2_AS_WDOG            (2 << 4)
 85 #define APCI3120_MODE_TIMER2_AS_MASK            (3 << 4)  /* sets AS_TIMER */
 86 #define APCI3120_MODE_SCAN_ENA                  (1 << 3)
 87 #define APCI3120_MODE_TIMER2_IRQ_ENA            (1 << 2)
 88 #define APCI3120_MODE_EOS_IRQ_ENA               (1 << 1)
 89 #define APCI3120_MODE_EOC_IRQ_ENA               (1 << 0)
 90 
 91 /*
 92  * PCI BAR 2 register map (devpriv->addon)
 93  */
 94 #define APCI3120_ADDON_ADDR_REG                 0x00
 95 #define APCI3120_ADDON_DATA_REG                 0x02
 96 #define APCI3120_ADDON_CTRL_REG                 0x04
 97 #define APCI3120_ADDON_CTRL_AMWEN_ENA           (1 << 1)
 98 #define APCI3120_ADDON_CTRL_A2P_FIFO_ENA        (1 << 0)
 99 
100 /*
101  * Board revisions
102  */
103 #define APCI3120_REVA                           0xa
104 #define APCI3120_REVB                           0xb
105 #define APCI3120_REVA_OSC_BASE                  70      /* 70ns = 14.29MHz */
106 #define APCI3120_REVB_OSC_BASE                  50      /* 50ns = 20MHz */
107 
108 static const struct comedi_lrange apci3120_ai_range = {
109         8, {
110                 BIP_RANGE(10),
111                 BIP_RANGE(5),
112                 BIP_RANGE(2),
113                 BIP_RANGE(1),
114                 UNI_RANGE(10),
115                 UNI_RANGE(5),
116                 UNI_RANGE(2),
117                 UNI_RANGE(1)
118         }
119 };
120 
121 enum apci3120_boardid {
122         BOARD_APCI3120,
123         BOARD_APCI3001,
124 };
125 
126 struct apci3120_board {
127         const char *name;
128         unsigned int ai_is_16bit:1;
129         unsigned int has_ao:1;
130 };
131 
132 static const struct apci3120_board apci3120_boardtypes[] = {
133         [BOARD_APCI3120] = {
134                 .name           = "apci3120",
135                 .ai_is_16bit    = 1,
136                 .has_ao         = 1,
137         },
138         [BOARD_APCI3001] = {
139                 .name           = "apci3001",
140         },
141 };
142 
143 struct apci3120_dmabuf {
144         unsigned short *virt;
145         dma_addr_t hw;
146         unsigned int size;
147         unsigned int use_size;
148 };
149 
150 struct apci3120_private {
151         unsigned long amcc;
152         unsigned long addon;
153         unsigned int osc_base;
154         unsigned int use_dma:1;
155         unsigned int use_double_buffer:1;
156         unsigned int cur_dmabuf:1;
157         struct apci3120_dmabuf dmabuf[2];
158         unsigned char do_bits;
159         unsigned char timer_mode;
160         unsigned char mode;
161         unsigned short ctrl;
162 };
163 
164 static void apci3120_addon_write(struct comedi_device *dev,
165                                  unsigned int val, unsigned int reg)
166 {
167         struct apci3120_private *devpriv = dev->private;
168 
169         /* 16-bit interface for AMCC add-on registers */
170 
171         outw(reg, devpriv->addon + APCI3120_ADDON_ADDR_REG);
172         outw(val & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG);
173 
174         outw(reg + 2, devpriv->addon + APCI3120_ADDON_ADDR_REG);
175         outw((val >> 16) & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG);
176 }
177 
178 static void apci3120_init_dma(struct comedi_device *dev,
179                               struct apci3120_dmabuf *dmabuf)
180 {
181         struct apci3120_private *devpriv = dev->private;
182 
183         /* AMCC - enable transfer count and reset A2P FIFO */
184         outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO,
185              devpriv->amcc + AMCC_OP_REG_AGCSTS);
186 
187         /* Add-On - enable transfer count and reset A2P FIFO */
188         apci3120_addon_write(dev, AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO,
189                              AMCC_OP_REG_AGCSTS);
190 
191         /* AMCC - enable transfers and reset A2P flags */
192         outl(RESET_A2P_FLAGS | EN_A2P_TRANSFERS,
193              devpriv->amcc + AMCC_OP_REG_MCSR);
194 
195         /* Add-On - DMA start address */
196         apci3120_addon_write(dev, dmabuf->hw, AMCC_OP_REG_AMWAR);
197 
198         /* Add-On - Number of acquisitions */
199         apci3120_addon_write(dev, dmabuf->use_size, AMCC_OP_REG_AMWTC);
200 
201         /* AMCC - enable write complete (DMA) and set FIFO advance */
202         outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | AINT_WRITE_COMPL,
203              devpriv->amcc + AMCC_OP_REG_INTCSR);
204 
205         /* Add-On - enable DMA */
206         outw(APCI3120_ADDON_CTRL_AMWEN_ENA | APCI3120_ADDON_CTRL_A2P_FIFO_ENA,
207              devpriv->addon + APCI3120_ADDON_CTRL_REG);
208 }
209 
210 static void apci3120_setup_dma(struct comedi_device *dev,
211                                struct comedi_subdevice *s)
212 {
213         struct apci3120_private *devpriv = dev->private;
214         struct comedi_cmd *cmd = &s->async->cmd;
215         struct apci3120_dmabuf *dmabuf0 = &devpriv->dmabuf[0];
216         struct apci3120_dmabuf *dmabuf1 = &devpriv->dmabuf[1];
217         unsigned int dmalen0 = dmabuf0->size;
218         unsigned int dmalen1 = dmabuf1->size;
219         unsigned int scan_bytes;
220 
221         scan_bytes = comedi_samples_to_bytes(s, cmd->scan_end_arg);
222 
223         if (cmd->stop_src == TRIG_COUNT) {
224                 /*
225                  * Must we fill full first buffer? And must we fill
226                  * full second buffer when first is once filled?
227                  */
228                 if (dmalen0 > (cmd->stop_arg * scan_bytes))
229                         dmalen0 = cmd->stop_arg * scan_bytes;
230                 else if (dmalen1 > (cmd->stop_arg * scan_bytes - dmalen0))
231                         dmalen1 = cmd->stop_arg * scan_bytes - dmalen0;
232         }
233 
234         if (cmd->flags & CMDF_WAKE_EOS) {
235                 /* don't we want wake up every scan? */
236                 if (dmalen0 > scan_bytes) {
237                         dmalen0 = scan_bytes;
238                         if (cmd->scan_end_arg & 1)
239                                 dmalen0 += 2;
240                 }
241                 if (dmalen1 > scan_bytes) {
242                         dmalen1 = scan_bytes;
243                         if (cmd->scan_end_arg & 1)
244                                 dmalen1 -= 2;
245                         if (dmalen1 < 4)
246                                 dmalen1 = 4;
247                 }
248         } else {
249                 /* isn't output buff smaller that our DMA buff? */
250                 if (dmalen0 > s->async->prealloc_bufsz)
251                         dmalen0 = s->async->prealloc_bufsz;
252                 if (dmalen1 > s->async->prealloc_bufsz)
253                         dmalen1 = s->async->prealloc_bufsz;
254         }
255         dmabuf0->use_size = dmalen0;
256         dmabuf1->use_size = dmalen1;
257 
258         apci3120_init_dma(dev, dmabuf0);
259 }
260 
261 /*
262  * There are three timers on the board. They all use the same base
263  * clock with a fixed prescaler for each timer. The base clock used
264  * depends on the board version and type.
265  *
266  * APCI-3120 Rev A boards OSC = 14.29MHz base clock (~70ns)
267  * APCI-3120 Rev B boards OSC = 20MHz base clock (50ns)
268  * APCI-3001 boards OSC = 20MHz base clock (50ns)
269  *
270  * The prescalers for each timer are:
271  * Timer 0 CLK = OSC/10
272  * Timer 1 CLK = OSC/1000
273  * Timer 2 CLK = OSC/1000
274  */
275 static unsigned int apci3120_ns_to_timer(struct comedi_device *dev,
276                                          unsigned int timer,
277                                          unsigned int ns,
278                                          unsigned int flags)
279 {
280         struct apci3120_private *devpriv = dev->private;
281         unsigned int prescale = (timer == 0) ? 10 : 1000;
282         unsigned int timer_base = devpriv->osc_base * prescale;
283         unsigned int divisor;
284 
285         switch (flags & CMDF_ROUND_MASK) {
286         case CMDF_ROUND_UP:
287                 divisor = DIV_ROUND_UP(ns, timer_base);
288                 break;
289         case CMDF_ROUND_DOWN:
290                 divisor = ns / timer_base;
291                 break;
292         case CMDF_ROUND_NEAREST:
293         default:
294                 divisor = DIV_ROUND_CLOSEST(ns, timer_base);
295                 break;
296         }
297 
298         if (timer == 2) {
299                 /* timer 2 is 24-bits */
300                 if (divisor > 0x00ffffff)
301                         divisor = 0x00ffffff;
302         } else {
303                 /* timers 0 and 1 are 16-bits */
304                 if (divisor > 0xffff)
305                         divisor = 0xffff;
306         }
307         /* the timers require a minimum divisor of 2 */
308         if (divisor < 2)
309                 divisor = 2;
310 
311         return divisor;
312 }
313 
314 static void apci3120_clr_timer2_interrupt(struct comedi_device *dev)
315 {
316         /* a dummy read of APCI3120_CTR0_REG clears the timer 2 interrupt */
317         inb(dev->iobase + APCI3120_CTR0_REG);
318 }
319 
320 static void apci3120_timer_write(struct comedi_device *dev,
321                                  unsigned int timer, unsigned int val)
322 {
323         struct apci3120_private *devpriv = dev->private;
324 
325         /* write 16-bit value to timer (lower 16-bits of timer 2) */
326         outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
327              APCI3120_CTR0_TIMER_SEL(timer),
328              dev->iobase + APCI3120_CTR0_REG);
329         outw(val & 0xffff, dev->iobase + APCI3120_TIMER_REG);
330 
331         if (timer == 2) {
332                 /* write upper 16-bits to timer 2 */
333                 outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
334                      APCI3120_CTR0_TIMER_SEL(timer + 1),
335                      dev->iobase + APCI3120_CTR0_REG);
336                 outw((val >> 16) & 0xffff, dev->iobase + APCI3120_TIMER_REG);
337         }
338 }
339 
340 static unsigned int apci3120_timer_read(struct comedi_device *dev,
341                                         unsigned int timer)
342 {
343         struct apci3120_private *devpriv = dev->private;
344         unsigned int val;
345 
346         /* read 16-bit value from timer (lower 16-bits of timer 2) */
347         outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
348              APCI3120_CTR0_TIMER_SEL(timer),
349              dev->iobase + APCI3120_CTR0_REG);
350         val = inw(dev->iobase + APCI3120_TIMER_REG);
351 
352         if (timer == 2) {
353                 /* read upper 16-bits from timer 2 */
354                 outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
355                      APCI3120_CTR0_TIMER_SEL(timer + 1),
356                      dev->iobase + APCI3120_CTR0_REG);
357                 val |= (inw(dev->iobase + APCI3120_TIMER_REG) << 16);
358         }
359 
360         return val;
361 }
362 
363 static void apci3120_timer_set_mode(struct comedi_device *dev,
364                                     unsigned int timer, unsigned int mode)
365 {
366         struct apci3120_private *devpriv = dev->private;
367 
368         devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(timer);
369         devpriv->timer_mode |= APCI3120_TIMER_MODE(timer, mode);
370         outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_MODE_REG);
371 }
372 
373 static void apci3120_timer_enable(struct comedi_device *dev,
374                                   unsigned int timer, bool enable)
375 {
376         struct apci3120_private *devpriv = dev->private;
377 
378         if (enable)
379                 devpriv->ctrl |= APCI3120_CTRL_GATE(timer);
380         else
381                 devpriv->ctrl &= ~APCI3120_CTRL_GATE(timer);
382         outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
383 }
384 
385 static void apci3120_exttrig_enable(struct comedi_device *dev, bool enable)
386 {
387         struct apci3120_private *devpriv = dev->private;
388 
389         if (enable)
390                 devpriv->ctrl |= APCI3120_CTRL_EXT_TRIG;
391         else
392                 devpriv->ctrl &= ~APCI3120_CTRL_EXT_TRIG;
393         outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
394 }
395 
396 static void apci3120_set_chanlist(struct comedi_device *dev,
397                                   struct comedi_subdevice *s,
398                                   int n_chan, unsigned int *chanlist)
399 {
400         struct apci3120_private *devpriv = dev->private;
401         int i;
402 
403         /* set chanlist for scan */
404         for (i = 0; i < n_chan; i++) {
405                 unsigned int chan = CR_CHAN(chanlist[i]);
406                 unsigned int range = CR_RANGE(chanlist[i]);
407                 unsigned int val;
408 
409                 val = APCI3120_CHANLIST_MUX(chan) |
410                       APCI3120_CHANLIST_GAIN(range) |
411                       APCI3120_CHANLIST_INDEX(i);
412 
413                 if (comedi_range_is_unipolar(s, range))
414                         val |= APCI3120_CHANLIST_UNIPOLAR;
415 
416                 outw(val, dev->iobase + APCI3120_CHANLIST_REG);
417         }
418 
419         /* a dummy read of APCI3120_TIMER_MODE_REG resets the ai FIFO */
420         inw(dev->iobase + APCI3120_TIMER_MODE_REG);
421 
422         /* set scan length (PR) and scan start (PA) */
423         devpriv->ctrl = APCI3120_CTRL_PR(n_chan - 1) | APCI3120_CTRL_PA(0);
424         outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
425 
426         /* enable chanlist scanning if necessary */
427         if (n_chan > 1)
428                 devpriv->mode |= APCI3120_MODE_SCAN_ENA;
429 }
430 
431 static void apci3120_interrupt_dma(struct comedi_device *dev,
432                                    struct comedi_subdevice *s)
433 {
434         struct apci3120_private *devpriv = dev->private;
435         struct comedi_async *async = s->async;
436         struct comedi_cmd *cmd = &async->cmd;
437         struct apci3120_dmabuf *dmabuf;
438         unsigned int nbytes;
439         unsigned int nsamples;
440 
441         dmabuf = &devpriv->dmabuf[devpriv->cur_dmabuf];
442 
443         nbytes = dmabuf->use_size - inl(devpriv->amcc + AMCC_OP_REG_MWTC);
444 
445         if (nbytes < dmabuf->use_size)
446                 dev_err(dev->class_dev, "Interrupted DMA transfer!\n");
447         if (nbytes & 1) {
448                 dev_err(dev->class_dev, "Odd count of bytes in DMA ring!\n");
449                 async->events |= COMEDI_CB_ERROR;
450                 return;
451         }
452 
453         nsamples = comedi_bytes_to_samples(s, nbytes);
454         if (nsamples) {
455                 comedi_buf_write_samples(s, dmabuf->virt, nsamples);
456 
457                 if (!(cmd->flags & CMDF_WAKE_EOS))
458                         async->events |= COMEDI_CB_EOS;
459         }
460 
461         if ((async->events & COMEDI_CB_CANCEL_MASK) ||
462             (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg))
463                 return;
464 
465         if (devpriv->use_double_buffer) {
466                 /* switch DMA buffers for next interrupt */
467                 devpriv->cur_dmabuf = !devpriv->cur_dmabuf;
468                 dmabuf = &devpriv->dmabuf[devpriv->cur_dmabuf];
469                 apci3120_init_dma(dev, dmabuf);
470         } else {
471                 /* restart DMA if not using double buffering */
472                 apci3120_init_dma(dev, dmabuf);
473         }
474 }
475 
476 static irqreturn_t apci3120_interrupt(int irq, void *d)
477 {
478         struct comedi_device *dev = d;
479         struct apci3120_private *devpriv = dev->private;
480         struct comedi_subdevice *s = dev->read_subdev;
481         struct comedi_async *async = s->async;
482         struct comedi_cmd *cmd = &async->cmd;
483         unsigned int status;
484         unsigned int int_amcc;
485 
486         status = inw(dev->iobase + APCI3120_STATUS_REG);
487         int_amcc = inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
488 
489         if (!(status & APCI3120_STATUS_INT_MASK) &&
490             !(int_amcc & ANY_S593X_INT)) {
491                 dev_err(dev->class_dev, "IRQ from unknown source\n");
492                 return IRQ_NONE;
493         }
494 
495         outl(int_amcc | AINT_INT_MASK, devpriv->amcc + AMCC_OP_REG_INTCSR);
496 
497         if (devpriv->ctrl & APCI3120_CTRL_EXT_TRIG)
498                 apci3120_exttrig_enable(dev, false);
499 
500         if (int_amcc & MASTER_ABORT_INT)
501                 dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n");
502         if (int_amcc & TARGET_ABORT_INT)
503                 dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n");
504 
505         if ((status & APCI3120_STATUS_EOC_INT) == 0 &&
506             (devpriv->mode & APCI3120_MODE_EOC_IRQ_ENA)) {
507                 /* nothing to do... EOC mode is not currently used */
508         }
509 
510         if ((status & APCI3120_STATUS_EOS_INT) &&
511             (devpriv->mode & APCI3120_MODE_EOS_IRQ_ENA)) {
512                 unsigned short val;
513                 int i;
514 
515                 for (i = 0; i < cmd->chanlist_len; i++) {
516                         val = inw(dev->iobase + APCI3120_AI_FIFO_REG);
517                         comedi_buf_write_samples(s, &val, 1);
518                 }
519 
520                 devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA;
521                 outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
522         }
523 
524         if (status & APCI3120_STATUS_TIMER2_INT) {
525                 /*
526                  * for safety...
527                  * timer2 interrupts are not enabled in the driver
528                  */
529                 apci3120_clr_timer2_interrupt(dev);
530         }
531 
532         if (status & APCI3120_STATUS_AMCC_INT) {
533                 /* AMCC- Clear write complete interrupt (DMA) */
534                 outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR);
535 
536                 /* do some data transfer */
537                 apci3120_interrupt_dma(dev, s);
538         }
539 
540         if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)
541                 async->events |= COMEDI_CB_EOA;
542 
543         comedi_handle_events(dev, s);
544 
545         return IRQ_HANDLED;
546 }
547 
548 static int apci3120_ai_cmd(struct comedi_device *dev,
549                            struct comedi_subdevice *s)
550 {
551         struct apci3120_private *devpriv = dev->private;
552         struct comedi_cmd *cmd = &s->async->cmd;
553         unsigned int divisor;
554 
555         /* set default mode bits */
556         devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC |
557                         APCI3120_MODE_TIMER2_AS_TIMER;
558 
559         /* AMCC- Clear write complete interrupt (DMA) */
560         outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR);
561 
562         devpriv->cur_dmabuf = 0;
563 
564         /* load chanlist for command scan */
565         apci3120_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist);
566 
567         if (cmd->start_src == TRIG_EXT)
568                 apci3120_exttrig_enable(dev, true);
569 
570         if (cmd->scan_begin_src == TRIG_TIMER) {
571                 /*
572                  * Timer 1 is used in MODE2 (rate generator) to set the
573                  * start time for each scan.
574                  */
575                 divisor = apci3120_ns_to_timer(dev, 1, cmd->scan_begin_arg,
576                                                cmd->flags);
577                 apci3120_timer_set_mode(dev, 1, APCI3120_TIMER_MODE2);
578                 apci3120_timer_write(dev, 1, divisor);
579         }
580 
581         /*
582          * Timer 0 is used in MODE2 (rate generator) to set the conversion
583          * time for each acquisition.
584          */
585         divisor = apci3120_ns_to_timer(dev, 0, cmd->convert_arg, cmd->flags);
586         apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2);
587         apci3120_timer_write(dev, 0, divisor);
588 
589         if (devpriv->use_dma)
590                 apci3120_setup_dma(dev, s);
591         else
592                 devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA;
593 
594         /* set mode to enable acquisition */
595         outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
596 
597         if (cmd->scan_begin_src == TRIG_TIMER)
598                 apci3120_timer_enable(dev, 1, true);
599         apci3120_timer_enable(dev, 0, true);
600 
601         return 0;
602 }
603 
604 static int apci3120_ai_cmdtest(struct comedi_device *dev,
605                                struct comedi_subdevice *s,
606                                struct comedi_cmd *cmd)
607 {
608         unsigned int arg;
609         int err = 0;
610 
611         /* Step 1 : check if triggers are trivially valid */
612 
613         err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
614         err |= comedi_check_trigger_src(&cmd->scan_begin_src,
615                                         TRIG_TIMER | TRIG_FOLLOW);
616         err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
617         err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
618         err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
619 
620         if (err)
621                 return 1;
622 
623         /* Step 2a : make sure trigger sources are unique */
624 
625         err |= comedi_check_trigger_is_unique(cmd->start_src);
626         err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
627         err |= comedi_check_trigger_is_unique(cmd->stop_src);
628 
629         /* Step 2b : and mutually compatible */
630 
631         if (err)
632                 return 2;
633 
634         /* Step 3: check if arguments are trivially valid */
635 
636         err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
637 
638         if (cmd->scan_begin_src == TRIG_TIMER) {        /* Test Delay timing */
639                 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
640                                                     100000);
641         }
642 
643         /* minimum conversion time per sample is 10us */
644         err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 10000);
645 
646         err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
647         err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
648                                            cmd->chanlist_len);
649 
650         if (cmd->stop_src == TRIG_COUNT)
651                 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
652         else    /*  TRIG_NONE */
653                 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
654 
655         if (err)
656                 return 3;
657 
658         /* Step 4: fix up any arguments */
659 
660         if (cmd->scan_begin_src == TRIG_TIMER) {
661                 /* scan begin must be larger than the scan time */
662                 arg = cmd->convert_arg * cmd->scan_end_arg;
663                 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, arg);
664         }
665 
666         if (err)
667                 return 4;
668 
669         /* Step 5: check channel list if it exists */
670 
671         return 0;
672 }
673 
674 static int apci3120_cancel(struct comedi_device *dev,
675                            struct comedi_subdevice *s)
676 {
677         struct apci3120_private *devpriv = dev->private;
678 
679         /* Add-On - disable DMA */
680         outw(0, devpriv->addon + 4);
681 
682         /* Add-On - disable bus master */
683         apci3120_addon_write(dev, 0, AMCC_OP_REG_AGCSTS);
684 
685         /* AMCC - disable bus master */
686         outl(0, devpriv->amcc + AMCC_OP_REG_MCSR);
687 
688         /* disable all counters, ext trigger, and reset scan */
689         devpriv->ctrl = 0;
690         outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
691 
692         /* DISABLE_ALL_INTERRUPT */
693         devpriv->mode = 0;
694         outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
695 
696         inw(dev->iobase + APCI3120_STATUS_REG);
697         devpriv->cur_dmabuf = 0;
698 
699         return 0;
700 }
701 
702 static int apci3120_ai_eoc(struct comedi_device *dev,
703                            struct comedi_subdevice *s,
704                            struct comedi_insn *insn,
705                            unsigned long context)
706 {
707         unsigned int status;
708 
709         status = inw(dev->iobase + APCI3120_STATUS_REG);
710         if ((status & APCI3120_STATUS_EOC_INT) == 0)
711                 return 0;
712         return -EBUSY;
713 }
714 
715 static int apci3120_ai_insn_read(struct comedi_device *dev,
716                                  struct comedi_subdevice *s,
717                                  struct comedi_insn *insn,
718                                  unsigned int *data)
719 {
720         struct apci3120_private *devpriv = dev->private;
721         unsigned int divisor;
722         int ret;
723         int i;
724 
725         /* set mode for A/D conversions by software trigger with timer 0 */
726         devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC |
727                         APCI3120_MODE_TIMER2_AS_TIMER;
728         outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
729 
730         /* load chanlist for single channel scan */
731         apci3120_set_chanlist(dev, s, 1, &insn->chanspec);
732 
733         /*
734          * Timer 0 is used in MODE4 (software triggered strobe) to set the
735          * conversion time for each acquisition. Each conversion is triggered
736          * when the divisor is written to the timer, The conversion is done
737          * when the EOC bit in the status register is ''.
738          */
739         apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE4);
740         apci3120_timer_enable(dev, 0, true);
741 
742         /* fixed conversion time of 10 us */
743         divisor = apci3120_ns_to_timer(dev, 0, 10000, CMDF_ROUND_NEAREST);
744 
745         for (i = 0; i < insn->n; i++) {
746                 /* trigger conversion */
747                 apci3120_timer_write(dev, 0, divisor);
748 
749                 ret = comedi_timeout(dev, s, insn, apci3120_ai_eoc, 0);
750                 if (ret)
751                         return ret;
752 
753                 data[i] = inw(dev->iobase + APCI3120_AI_FIFO_REG);
754         }
755 
756         return insn->n;
757 }
758 
759 static int apci3120_ao_ready(struct comedi_device *dev,
760                              struct comedi_subdevice *s,
761                              struct comedi_insn *insn,
762                              unsigned long context)
763 {
764         unsigned int status;
765 
766         status = inw(dev->iobase + APCI3120_STATUS_REG);
767         if (status & APCI3120_STATUS_DA_READY)
768                 return 0;
769         return -EBUSY;
770 }
771 
772 static int apci3120_ao_insn_write(struct comedi_device *dev,
773                                   struct comedi_subdevice *s,
774                                   struct comedi_insn *insn,
775                                   unsigned int *data)
776 {
777         unsigned int chan = CR_CHAN(insn->chanspec);
778         int i;
779 
780         for (i = 0; i < insn->n; i++) {
781                 unsigned int val = data[i];
782                 int ret;
783 
784                 ret = comedi_timeout(dev, s, insn, apci3120_ao_ready, 0);
785                 if (ret)
786                         return ret;
787 
788                 outw(APCI3120_AO_MUX(chan) | APCI3120_AO_DATA(val),
789                      dev->iobase + APCI3120_AO_REG(chan));
790 
791                 s->readback[chan] = val;
792         }
793 
794         return insn->n;
795 }
796 
797 static int apci3120_di_insn_bits(struct comedi_device *dev,
798                                  struct comedi_subdevice *s,
799                                  struct comedi_insn *insn,
800                                  unsigned int *data)
801 {
802         unsigned int status;
803 
804         status = inw(dev->iobase + APCI3120_STATUS_REG);
805         data[1] = APCI3120_STATUS_TO_DI_BITS(status);
806 
807         return insn->n;
808 }
809 
810 static int apci3120_do_insn_bits(struct comedi_device *dev,
811                                  struct comedi_subdevice *s,
812                                  struct comedi_insn *insn,
813                                  unsigned int *data)
814 {
815         struct apci3120_private *devpriv = dev->private;
816 
817         if (comedi_dio_update_state(s, data)) {
818                 devpriv->do_bits = s->state;
819                 outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits),
820                      dev->iobase + APCI3120_CTR0_REG);
821         }
822 
823         data[1] = s->state;
824 
825         return insn->n;
826 }
827 
828 static int apci3120_timer_insn_config(struct comedi_device *dev,
829                                       struct comedi_subdevice *s,
830                                       struct comedi_insn *insn,
831                                       unsigned int *data)
832 {
833         struct apci3120_private *devpriv = dev->private;
834         unsigned int divisor;
835         unsigned int status;
836         unsigned int mode;
837         unsigned int timer_mode;
838 
839         switch (data[0]) {
840         case INSN_CONFIG_ARM:
841                 apci3120_clr_timer2_interrupt(dev);
842                 divisor = apci3120_ns_to_timer(dev, 2, data[1],
843                                                CMDF_ROUND_DOWN);
844                 apci3120_timer_write(dev, 2, divisor);
845                 apci3120_timer_enable(dev, 2, true);
846                 break;
847 
848         case INSN_CONFIG_DISARM:
849                 apci3120_timer_enable(dev, 2, false);
850                 apci3120_clr_timer2_interrupt(dev);
851                 break;
852 
853         case INSN_CONFIG_GET_COUNTER_STATUS:
854                 data[1] = 0;
855                 data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING |
856                           COMEDI_COUNTER_TERMINAL_COUNT;
857 
858                 if (devpriv->ctrl & APCI3120_CTRL_GATE(2)) {
859                         data[1] |= COMEDI_COUNTER_ARMED;
860                         data[1] |= COMEDI_COUNTER_COUNTING;
861                 }
862                 status = inw(dev->iobase + APCI3120_STATUS_REG);
863                 if (status & APCI3120_STATUS_TIMER2_INT) {
864                         data[1] &= ~COMEDI_COUNTER_COUNTING;
865                         data[1] |= COMEDI_COUNTER_TERMINAL_COUNT;
866                 }
867                 break;
868 
869         case INSN_CONFIG_SET_COUNTER_MODE:
870                 switch (data[1]) {
871                 case I8254_MODE0:
872                         mode = APCI3120_MODE_TIMER2_AS_COUNTER;
873                         timer_mode = APCI3120_TIMER_MODE0;
874                         break;
875                 case I8254_MODE2:
876                         mode = APCI3120_MODE_TIMER2_AS_TIMER;
877                         timer_mode = APCI3120_TIMER_MODE2;
878                         break;
879                 case I8254_MODE4:
880                         mode = APCI3120_MODE_TIMER2_AS_TIMER;
881                         timer_mode = APCI3120_TIMER_MODE4;
882                         break;
883                 case I8254_MODE5:
884                         mode = APCI3120_MODE_TIMER2_AS_WDOG;
885                         timer_mode = APCI3120_TIMER_MODE5;
886                         break;
887                 default:
888                         return -EINVAL;
889                 }
890                 apci3120_timer_enable(dev, 2, false);
891                 apci3120_clr_timer2_interrupt(dev);
892                 apci3120_timer_set_mode(dev, 2, timer_mode);
893                 devpriv->mode &= ~APCI3120_MODE_TIMER2_AS_MASK;
894                 devpriv->mode |= mode;
895                 outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
896                 break;
897 
898         default:
899                 return -EINVAL;
900         }
901 
902         return insn->n;
903 }
904 
905 static int apci3120_timer_insn_read(struct comedi_device *dev,
906                                     struct comedi_subdevice *s,
907                                     struct comedi_insn *insn,
908                                     unsigned int *data)
909 {
910         int i;
911 
912         for (i = 0; i < insn->n; i++)
913                 data[i] = apci3120_timer_read(dev, 2);
914 
915         return insn->n;
916 }
917 
918 static void apci3120_dma_alloc(struct comedi_device *dev)
919 {
920         struct apci3120_private *devpriv = dev->private;
921         struct apci3120_dmabuf *dmabuf;
922         int order;
923         int i;
924 
925         for (i = 0; i < 2; i++) {
926                 dmabuf = &devpriv->dmabuf[i];
927                 for (order = 2; order >= 0; order--) {
928                         dmabuf->virt = dma_alloc_coherent(dev->hw_dev,
929                                                           PAGE_SIZE << order,
930                                                           &dmabuf->hw,
931                                                           GFP_KERNEL);
932                         if (dmabuf->virt)
933                                 break;
934                 }
935                 if (!dmabuf->virt)
936                         break;
937                 dmabuf->size = PAGE_SIZE << order;
938 
939                 if (i == 0)
940                         devpriv->use_dma = 1;
941                 if (i == 1)
942                         devpriv->use_double_buffer = 1;
943         }
944 }
945 
946 static void apci3120_dma_free(struct comedi_device *dev)
947 {
948         struct apci3120_private *devpriv = dev->private;
949         struct apci3120_dmabuf *dmabuf;
950         int i;
951 
952         if (!devpriv)
953                 return;
954 
955         for (i = 0; i < 2; i++) {
956                 dmabuf = &devpriv->dmabuf[i];
957                 if (dmabuf->virt) {
958                         dma_free_coherent(dev->hw_dev, dmabuf->size,
959                                           dmabuf->virt, dmabuf->hw);
960                 }
961         }
962 }
963 
964 static void apci3120_reset(struct comedi_device *dev)
965 {
966         /* disable all interrupt sources */
967         outb(0, dev->iobase + APCI3120_MODE_REG);
968 
969         /* disable all counters, ext trigger, and reset scan */
970         outw(0, dev->iobase + APCI3120_CTRL_REG);
971 
972         /* clear interrupt status */
973         inw(dev->iobase + APCI3120_STATUS_REG);
974 }
975 
976 static int apci3120_auto_attach(struct comedi_device *dev,
977                                 unsigned long context)
978 {
979         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
980         const struct apci3120_board *this_board = NULL;
981         struct apci3120_private *devpriv;
982         struct comedi_subdevice *s;
983         unsigned int status;
984         int ret;
985 
986         if (context < ARRAY_SIZE(apci3120_boardtypes))
987                 this_board = &apci3120_boardtypes[context];
988         if (!this_board)
989                 return -ENODEV;
990         dev->board_ptr = this_board;
991         dev->board_name = this_board->name;
992 
993         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
994         if (!devpriv)
995                 return -ENOMEM;
996 
997         ret = comedi_pci_enable(dev);
998         if (ret)
999                 return ret;
1000         pci_set_master(pcidev);
1001 
1002         dev->iobase = pci_resource_start(pcidev, 1);
1003         devpriv->amcc = pci_resource_start(pcidev, 0);
1004         devpriv->addon = pci_resource_start(pcidev, 2);
1005 
1006         apci3120_reset(dev);
1007 
1008         if (pcidev->irq > 0) {
1009                 ret = request_irq(pcidev->irq, apci3120_interrupt, IRQF_SHARED,
1010                                   dev->board_name, dev);
1011                 if (ret == 0) {
1012                         dev->irq = pcidev->irq;
1013 
1014                         apci3120_dma_alloc(dev);
1015                 }
1016         }
1017 
1018         status = inw(dev->iobase + APCI3120_STATUS_REG);
1019         if (APCI3120_STATUS_TO_VERSION(status) == APCI3120_REVB ||
1020             context == BOARD_APCI3001)
1021                 devpriv->osc_base = APCI3120_REVB_OSC_BASE;
1022         else
1023                 devpriv->osc_base = APCI3120_REVA_OSC_BASE;
1024 
1025         ret = comedi_alloc_subdevices(dev, 5);
1026         if (ret)
1027                 return ret;
1028 
1029         /* Analog Input subdevice */
1030         s = &dev->subdevices[0];
1031         s->type         = COMEDI_SUBD_AI;
1032         s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
1033         s->n_chan       = 16;
1034         s->maxdata      = this_board->ai_is_16bit ? 0xffff : 0x0fff;
1035         s->range_table  = &apci3120_ai_range;
1036         s->insn_read    = apci3120_ai_insn_read;
1037         if (dev->irq) {
1038                 dev->read_subdev = s;
1039                 s->subdev_flags |= SDF_CMD_READ;
1040                 s->len_chanlist = s->n_chan;
1041                 s->do_cmdtest   = apci3120_ai_cmdtest;
1042                 s->do_cmd       = apci3120_ai_cmd;
1043                 s->cancel       = apci3120_cancel;
1044         }
1045 
1046         /* Analog Output subdevice */
1047         s = &dev->subdevices[1];
1048         if (this_board->has_ao) {
1049                 s->type         = COMEDI_SUBD_AO;
1050                 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
1051                 s->n_chan       = 8;
1052                 s->maxdata      = 0x3fff;
1053                 s->range_table  = &range_bipolar10;
1054                 s->insn_write   = apci3120_ao_insn_write;
1055 
1056                 ret = comedi_alloc_subdev_readback(s);
1057                 if (ret)
1058                         return ret;
1059         } else {
1060                 s->type         = COMEDI_SUBD_UNUSED;
1061         }
1062 
1063         /* Digital Input subdevice */
1064         s = &dev->subdevices[2];
1065         s->type         = COMEDI_SUBD_DI;
1066         s->subdev_flags = SDF_READABLE;
1067         s->n_chan       = 4;
1068         s->maxdata      = 1;
1069         s->range_table  = &range_digital;
1070         s->insn_bits    = apci3120_di_insn_bits;
1071 
1072         /* Digital Output subdevice */
1073         s = &dev->subdevices[3];
1074         s->type         = COMEDI_SUBD_DO;
1075         s->subdev_flags = SDF_WRITABLE;
1076         s->n_chan       = 4;
1077         s->maxdata      = 1;
1078         s->range_table  = &range_digital;
1079         s->insn_bits    = apci3120_do_insn_bits;
1080 
1081         /* Timer subdevice */
1082         s = &dev->subdevices[4];
1083         s->type         = COMEDI_SUBD_TIMER;
1084         s->subdev_flags = SDF_READABLE;
1085         s->n_chan       = 1;
1086         s->maxdata      = 0x00ffffff;
1087         s->insn_config  = apci3120_timer_insn_config;
1088         s->insn_read    = apci3120_timer_insn_read;
1089 
1090         return 0;
1091 }
1092 
1093 static void apci3120_detach(struct comedi_device *dev)
1094 {
1095         comedi_pci_detach(dev);
1096         apci3120_dma_free(dev);
1097 }
1098 
1099 static struct comedi_driver apci3120_driver = {
1100         .driver_name    = "addi_apci_3120",
1101         .module         = THIS_MODULE,
1102         .auto_attach    = apci3120_auto_attach,
1103         .detach         = apci3120_detach,
1104 };
1105 
1106 static int apci3120_pci_probe(struct pci_dev *dev,
1107                               const struct pci_device_id *id)
1108 {
1109         return comedi_pci_auto_config(dev, &apci3120_driver, id->driver_data);
1110 }
1111 
1112 static const struct pci_device_id apci3120_pci_table[] = {
1113         { PCI_VDEVICE(AMCC, 0x818d), BOARD_APCI3120 },
1114         { PCI_VDEVICE(AMCC, 0x828d), BOARD_APCI3001 },
1115         { 0 }
1116 };
1117 MODULE_DEVICE_TABLE(pci, apci3120_pci_table);
1118 
1119 static struct pci_driver apci3120_pci_driver = {
1120         .name           = "addi_apci_3120",
1121         .id_table       = apci3120_pci_table,
1122         .probe          = apci3120_pci_probe,
1123         .remove         = comedi_pci_auto_unconfig,
1124 };
1125 module_comedi_pci_driver(apci3120_driver, apci3120_pci_driver);
1126 
1127 MODULE_AUTHOR("Comedi http://www.comedi.org");
1128 MODULE_DESCRIPTION("ADDI-DATA APCI-3120, Analog input board");
1129 MODULE_LICENSE("GPL");
1130 

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