staging: comedi: addi_apci_3120: don't use timer 2 to count scans
authorH Hartley Sweeten <hsweeten@visionengravers.com>
Tue, 4 Nov 2014 17:55:11 +0000 (10:55 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Nov 2014 17:34:04 +0000 (09:34 -0800)
Timer 2 can be used to count the number of scans when the cmd->stop_src
is TRIG_COUNT. Unfortunately that timer can also be used by userspace and
this breaks the async command. Timer 2 also only works for counting the
number of scans when DMA is not used.

The number of scans is counted by the core using the private data membmer
'scans_done'. Use that to detect the End-Of-Scan for both DMA and none
DMA modes.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c

index ec488d163587cf69447fcf75a8d97a4a201d24f4..10ab6d89a6d5a5abbe30d467999175a4bb4796cf 100644 (file)
@@ -293,35 +293,11 @@ static int apci3120_ai_cmd(struct comedi_device *dev,
        apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2);
        apci3120_timer_write(dev, 0, divisor);
 
-       if (devpriv->use_dma) {
+       if (devpriv->use_dma)
                apci3120_setup_dma(dev, s);
-       } else {
+       else
                devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA;
 
-               if (cmd->stop_src == TRIG_COUNT) {
-                       /*
-                        * Timer 2 is used in MODE0 (hardware retriggerable
-                        * one-shot) to count the number of scans.
-                        *
-                        * NOTE: not sure about the -2 value
-                        */
-                       apci3120_timer_set_mode(dev, 2, APCI3120_TIMER_MODE0);
-                       apci3120_timer_write(dev, 2, cmd->stop_arg - 2);
-
-                       apci3120_clr_timer2_interrupt(dev);
-
-                       apci3120_timer_enable(dev, 2, true);
-
-                       /* configure Timer 2 For counting EOS */
-                       devpriv->mode |= APCI3120_MODE_TIMER2_AS_COUNTER |
-                                        APCI3120_MODE_TIMER2_CLK_EOS |
-                                        APCI3120_MODE_TIMER2_IRQ_ENA;
-
-                       devpriv->b_Timer2Mode = APCI3120_COUNTER;
-                       devpriv->b_Timer2Interrupt = 1;
-               }
-       }
-
        /* set mode to enable acquisition */
        outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
 
@@ -343,7 +319,8 @@ static void apci3120_interrupt_dma(int irq, void *d)
        struct comedi_device *dev = d;
        struct apci3120_private *devpriv = dev->private;
        struct comedi_subdevice *s = dev->read_subdev;
-       struct comedi_cmd *cmd = &s->async->cmd;
+       struct comedi_async *async = s->async;
+       struct comedi_cmd *cmd = &async->cmd;
        struct apci3120_dmabuf *dmabuf;
        unsigned int samplesinbuf;
 
@@ -373,13 +350,12 @@ static void apci3120_interrupt_dma(int irq, void *d)
                comedi_buf_write_samples(s, dmabuf->virt, samplesinbuf);
 
                if (!(cmd->flags & CMDF_WAKE_EOS))
-                       s->async->events |= COMEDI_CB_EOS;
+                       async->events |= COMEDI_CB_EOS;
        }
-       if (cmd->stop_src == TRIG_COUNT &&
-           s->async->scans_done >= cmd->stop_arg) {
-               s->async->events |= COMEDI_CB_EOA;
+
+       if ((async->events & COMEDI_CB_CANCEL_MASK) ||
+           (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg))
                return;
-       }
 
        if (devpriv->use_double_buffer) {
                /* switch dma buffers for next interrupt */
@@ -395,7 +371,8 @@ static irqreturn_t apci3120_interrupt(int irq, void *d)
        struct comedi_device *dev = d;
        struct apci3120_private *devpriv = dev->private;
        struct comedi_subdevice *s = dev->read_subdev;
-       struct comedi_cmd *cmd = &s->async->cmd;
+       struct comedi_async *async = s->async;
+       struct comedi_cmd *cmd = &async->cmd;
        unsigned int status;
        unsigned int int_amcc;
 
@@ -442,10 +419,6 @@ static irqreturn_t apci3120_interrupt(int irq, void *d)
        if (status & APCI3120_STATUS_TIMER2_INT) {
                switch (devpriv->b_Timer2Mode) {
                case APCI3120_COUNTER:
-                       devpriv->mode &= ~APCI3120_MODE_EOS_IRQ_ENA;
-                       outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
-
-                       s->async->events |= COMEDI_CB_EOA;
                        break;
 
                case APCI3120_TIMER:
@@ -478,6 +451,10 @@ static irqreturn_t apci3120_interrupt(int irq, void *d)
                /* do some data transfer */
                apci3120_interrupt_dma(irq, d);
        }
+
+       if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)
+               async->events |= COMEDI_CB_EOA;
+
        comedi_handle_events(dev, s);
 
        return IRQ_HANDLED;
This page took 0.027494 seconds and 5 git commands to generate.