Commit 7bd7d905 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

staging: comedi: cb_pcidas: introduce cb_pcidas64_ao_fill_buffer()

Introduce a helper function to read the analog output samples from the
async buffer.

This fixes a bug in load_ao_dma_buffer(). That function was decrementing
the 'ao_count' by the number of bytes, not the number of samples, that
were read from the async buffer.

Use comedi_buf_read_samples() to read the analog output samples from
the async buffer.
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 2cc9854c
......@@ -2912,32 +2912,46 @@ static void restart_ao_dma(struct comedi_device *dev)
dma_start_sync(dev, 0);
}
static unsigned int cb_pcidas64_ao_fill_buffer(struct comedi_device *dev,
struct comedi_subdevice *s,
unsigned short *dest,
unsigned int max_bytes)
{
struct pcidas64_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
unsigned int nsamples = max_bytes / bytes_per_sample(s);
unsigned int actual_bytes;
if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < nsamples)
nsamples = devpriv->ao_count;
actual_bytes = comedi_buf_read_samples(s, dest, nsamples);
nsamples = actual_bytes / bytes_per_sample(s);
if (cmd->stop_src == TRIG_COUNT)
devpriv->ao_count -= nsamples;
return nsamples;
}
static unsigned int load_ao_dma_buffer(struct comedi_device *dev,
const struct comedi_cmd *cmd)
{
struct pcidas64_private *devpriv = dev->private;
unsigned int num_bytes, buffer_index, prev_buffer_index;
struct comedi_subdevice *s = dev->write_subdev;
unsigned int buffer_index = devpriv->ao_dma_index;
unsigned int prev_buffer_index = prev_ao_dma_index(dev);
unsigned int nsamples;
unsigned int nbytes;
unsigned int next_bits;
buffer_index = devpriv->ao_dma_index;
prev_buffer_index = prev_ao_dma_index(dev);
num_bytes = comedi_buf_read_n_available(dev->write_subdev);
if (num_bytes > DMA_BUFFER_SIZE)
num_bytes = DMA_BUFFER_SIZE;
if (cmd->stop_src == TRIG_COUNT && num_bytes > devpriv->ao_count)
num_bytes = devpriv->ao_count;
num_bytes -= num_bytes % bytes_in_sample;
if (num_bytes == 0)
nsamples = cb_pcidas64_ao_fill_buffer(dev, s,
devpriv->ao_buffer[buffer_index],
DMA_BUFFER_SIZE);
if (nsamples == 0)
return 0;
num_bytes = cfc_read_array_from_buffer(dev->write_subdev,
devpriv->
ao_buffer[buffer_index],
num_bytes);
devpriv->ao_dma_desc[buffer_index].transfer_size =
cpu_to_le32(num_bytes);
nbytes = nsamples * bytes_per_sample(s);
devpriv->ao_dma_desc[buffer_index].transfer_size = cpu_to_le32(nbytes);
/* set end of chain bit so we catch underruns */
next_bits = le32_to_cpu(devpriv->ao_dma_desc[buffer_index].next);
next_bits |= PLX_END_OF_CHAIN_BIT;
......@@ -2949,9 +2963,8 @@ static unsigned int load_ao_dma_buffer(struct comedi_device *dev,
devpriv->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits);
devpriv->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT;
devpriv->ao_count -= num_bytes;
return num_bytes;
return nbytes;
}
static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
......@@ -3191,7 +3204,9 @@ static void set_dac_interval_regs(struct comedi_device *dev,
static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
{
struct pcidas64_private *devpriv = dev->private;
unsigned int num_bytes;
struct comedi_subdevice *s = dev->write_subdev;
unsigned int nsamples;
unsigned int nbytes;
int i;
/* clear queue pointer too, since external queue has
......@@ -3199,22 +3214,22 @@ static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG);
writew(0, devpriv->main_iobase + DAC_BUFFER_CLEAR_REG);
num_bytes = (DAC_FIFO_SIZE / 2) * bytes_in_sample;
if (cmd->stop_src == TRIG_COUNT &&
num_bytes / bytes_in_sample > devpriv->ao_count)
num_bytes = devpriv->ao_count * bytes_in_sample;
num_bytes = cfc_read_array_from_buffer(dev->write_subdev,
devpriv->ao_bounce_buffer,
num_bytes);
for (i = 0; i < num_bytes / bytes_in_sample; i++) {
nsamples = cb_pcidas64_ao_fill_buffer(dev, s,
devpriv->ao_bounce_buffer,
DAC_FIFO_SIZE);
if (nsamples == 0)
return -1;
for (i = 0; i < nsamples; i++) {
writew(devpriv->ao_bounce_buffer[i],
devpriv->main_iobase + DAC_FIFO_REG);
}
devpriv->ao_count -= num_bytes / bytes_in_sample;
if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count == 0)
return 0;
num_bytes = load_ao_dma_buffer(dev, cmd);
if (num_bytes == 0)
nbytes = load_ao_dma_buffer(dev, cmd);
if (nbytes == 0)
return -1;
load_ao_dma(dev, cmd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment