staging: comedi: dt282x: introduce dt282x_ao_setup_dma()
authorH Hartley Sweeten <hsweeten@visionengravers.com>
Wed, 22 Oct 2014 21:36:38 +0000 (14:36 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Oct 2014 08:01:19 +0000 (16:01 +0800)
Introduce a helper function to read the analog output samples from the
async buffer and prep the DMA.

Use comedi_buf_read_samples() to read the analog output samples from
the async buffer.

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/dt282x.c

index f23d883..88b5610 100644 (file)
@@ -449,13 +449,29 @@ static void dt282x_munge(struct comedi_device *dev,
        }
 }
 
+static unsigned int dt282x_ao_setup_dma(struct comedi_device *dev,
+                                       struct comedi_subdevice *s,
+                                       int cur_dma)
+{
+       struct dt282x_private *devpriv = dev->private;
+       void *ptr = devpriv->dma[cur_dma].buf;
+       unsigned int nsamples = devpriv->dma_maxsize / bytes_per_sample(s);
+       unsigned int nbytes;
+
+       nbytes = comedi_buf_read_samples(s, ptr, nsamples);
+       if (nbytes)
+               dt282x_prep_ao_dma(dev, cur_dma, nbytes);
+       else
+               dev_err(dev->class_dev, "AO underrun\n");
+
+       return nbytes;
+}
+
 static void dt282x_ao_dma_interrupt(struct comedi_device *dev,
                                    struct comedi_subdevice *s)
 {
        struct dt282x_private *devpriv = dev->private;
        int cur_dma = devpriv->current_dma_index;
-       void *ptr = devpriv->dma[cur_dma].buf;
-       int size;
 
        outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE,
             dev->iobase + DT2821_SUPCSR_REG);
@@ -464,13 +480,8 @@ static void dt282x_ao_dma_interrupt(struct comedi_device *dev,
 
        devpriv->current_dma_index = 1 - cur_dma;
 
-       size = cfc_read_array_from_buffer(s, ptr, devpriv->dma_maxsize);
-       if (size == 0) {
-               dev_err(dev->class_dev, "AO underrun\n");
+       if (!dt282x_ao_setup_dma(dev, s, cur_dma))
                s->async->events |= COMEDI_CB_OVERFLOW;
-       } else {
-               dt282x_prep_ao_dma(dev, cur_dma, size);
-       }
 }
 
 static void dt282x_ai_dma_interrupt(struct comedi_device *dev,
@@ -916,26 +927,15 @@ static int dt282x_ao_inttrig(struct comedi_device *dev,
 {
        struct dt282x_private *devpriv = dev->private;
        struct comedi_cmd *cmd = &s->async->cmd;
-       int size;
 
        if (trig_num != cmd->start_src)
                return -EINVAL;
 
-       size = cfc_read_array_from_buffer(s, devpriv->dma[0].buf,
-                                         devpriv->dma_maxsize);
-       if (size == 0) {
-               dev_err(dev->class_dev, "AO underrun\n");
+       if (!dt282x_ao_setup_dma(dev, s, 0))
                return -EPIPE;
-       }
-       dt282x_prep_ao_dma(dev, 0, size);
 
-       size = cfc_read_array_from_buffer(s, devpriv->dma[1].buf,
-                                         devpriv->dma_maxsize);
-       if (size == 0) {
-               dev_err(dev->class_dev, "AO underrun\n");
+       if (!dt282x_ao_setup_dma(dev, s, 1))
                return -EPIPE;
-       }
-       dt282x_prep_ao_dma(dev, 1, size);
 
        outw(devpriv->supcsr | DT2821_SUPCSR_STRIG,
             dev->iobase + DT2821_SUPCSR_REG);