From: H Hartley Sweeten Date: Wed, 22 Oct 2014 21:36:38 +0000 (-0700) Subject: staging: comedi: dt282x: introduce dt282x_ao_setup_dma() X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=ecb11d8c28aa7fe761467873e69a3c5c66b57aed;p=linux-beck.git staging: comedi: dt282x: introduce dt282x_ao_setup_dma() 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 Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index f23d883f2544..88b56104d4e7 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -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);