Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2cc9854c authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman
Browse files

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: 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 bcdbe884
Loading
Loading
Loading
Loading
+22 −32
Original line number Diff line number Diff line
@@ -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;

		/*  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);
		cb_pcidas_ao_load_fifo(dev, s, thisboard->fifo_size / 2);

		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,