mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-04 10:12:16 +09:00
staging: comedi: cb_pcidas: introduce cb_pcidas_ao_load_fifo()
Introduce a helper function to load the analog output FIFO. This fixes a bug in cb_pcidas_ao_inttrig(). That function was writing 'num_bytes' data values to the FIFO instead of 'num_points'. This results in twice the number of data values getting written to the FIFO. Use comedi_buf_read_samples() 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>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
bcdbe8848e
commit
2cc9854caf
@@ -1134,32 +1134,39 @@ static int cb_pcidas_cancel(struct comedi_device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cb_pcidas_ao_load_fifo(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
unsigned int nsamples)
|
||||
{
|
||||
struct cb_pcidas_private *devpriv = dev->private;
|
||||
struct comedi_cmd *cmd = &s->async->cmd;
|
||||
unsigned int nbytes;
|
||||
|
||||
if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < nsamples)
|
||||
nsamples = devpriv->ao_count;
|
||||
|
||||
nbytes = comedi_buf_read_samples(s, devpriv->ao_buffer, nsamples);
|
||||
nsamples = nbytes / bytes_per_sample(s);
|
||||
if (cmd->stop_src == TRIG_COUNT)
|
||||
devpriv->ao_count -= nsamples;
|
||||
|
||||
outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, nsamples);
|
||||
}
|
||||
|
||||
static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
unsigned int trig_num)
|
||||
{
|
||||
const struct cb_pcidas_board *thisboard = dev->board_ptr;
|
||||
struct cb_pcidas_private *devpriv = dev->private;
|
||||
unsigned int num_bytes, num_points = thisboard->fifo_size;
|
||||
struct comedi_async *async = s->async;
|
||||
struct comedi_cmd *cmd = &s->async->cmd;
|
||||
struct comedi_cmd *cmd = &async->cmd;
|
||||
unsigned long flags;
|
||||
|
||||
if (trig_num != cmd->start_arg)
|
||||
return -EINVAL;
|
||||
|
||||
/* load up fifo */
|
||||
if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
|
||||
num_points = devpriv->ao_count;
|
||||
|
||||
num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
|
||||
num_points * sizeof(short));
|
||||
num_points = num_bytes / sizeof(short);
|
||||
|
||||
if (cmd->stop_src == TRIG_COUNT)
|
||||
devpriv->ao_count -= num_points;
|
||||
/* write data to board's fifo */
|
||||
outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
|
||||
cb_pcidas_ao_load_fifo(dev, s, thisboard->fifo_size);
|
||||
|
||||
/* enable dac half-full and empty interrupts */
|
||||
spin_lock_irqsave(&dev->spinlock, flags);
|
||||
@@ -1275,8 +1282,6 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
|
||||
struct comedi_subdevice *s = dev->write_subdev;
|
||||
struct comedi_async *async = s->async;
|
||||
struct comedi_cmd *cmd = &async->cmd;
|
||||
unsigned int half_fifo = thisboard->fifo_size / 2;
|
||||
unsigned int num_points;
|
||||
unsigned long flags;
|
||||
|
||||
if (status & DAEMI) {
|
||||
@@ -1295,23 +1300,8 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
|
||||
async->events |= COMEDI_CB_EOA;
|
||||
}
|
||||
} else if (status & DAHFI) {
|
||||
unsigned int num_bytes;
|
||||
cb_pcidas_ao_load_fifo(dev, s, thisboard->fifo_size / 2);
|
||||
|
||||
/* figure out how many points we are writing to fifo */
|
||||
num_points = half_fifo;
|
||||
if (cmd->stop_src == TRIG_COUNT &&
|
||||
devpriv->ao_count < num_points)
|
||||
num_points = devpriv->ao_count;
|
||||
num_bytes =
|
||||
cfc_read_array_from_buffer(s, devpriv->ao_buffer,
|
||||
num_points * sizeof(short));
|
||||
num_points = num_bytes / sizeof(short);
|
||||
|
||||
if (cmd->stop_src == TRIG_COUNT)
|
||||
devpriv->ao_count -= num_points;
|
||||
/* write data to board's fifo */
|
||||
outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
|
||||
num_points);
|
||||
/* clear half-full interrupt latch */
|
||||
spin_lock_irqsave(&dev->spinlock, flags);
|
||||
outw(devpriv->adc_fifo_bits | DAHFI,
|
||||
|
||||
Reference in New Issue
Block a user