staging: comedi: cb_pcidas64: use comedi_async 'scans_done' to detect AI EOA

Remove the private data member 'ai_count' and use the comedi_async 'scans_done'
member to detect the analog output end-of-acquisition.

Use the comedi_nsamples_left() helper to get the number of samples to actually
add to 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:
H Hartley Sweeten 2014-11-05 10:31:38 -07:00 committed by Greg Kroah-Hartman
parent 9e4d755cdf
commit ccedb44075
1 changed files with 14 additions and 41 deletions

View File

@ -1065,8 +1065,6 @@ struct pcidas64_private {
/* local address (used by dma controller) */ /* local address (used by dma controller) */
uint32_t local0_iobase; uint32_t local0_iobase;
uint32_t local1_iobase; uint32_t local1_iobase;
/* number of analog input samples remaining */
unsigned int ai_count;
/* dma buffers for analog input */ /* dma buffers for analog input */
uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT]; uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT];
/* physical addresses of ai dma buffers */ /* physical addresses of ai dma buffers */
@ -2199,10 +2197,6 @@ static void setup_sample_counters(struct comedi_device *dev,
{ {
struct pcidas64_private *devpriv = dev->private; struct pcidas64_private *devpriv = dev->private;
if (cmd->stop_src == TRIG_COUNT) {
/* set software count */
devpriv->ai_count = cmd->stop_arg * cmd->chanlist_len;
}
/* load hardware conversion counter */ /* load hardware conversion counter */
if (use_hw_sample_counter(cmd)) { if (use_hw_sample_counter(cmd)) {
writew(cmd->stop_arg & 0xffff, writew(cmd->stop_arg & 0xffff,
@ -2642,8 +2636,6 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev)
{ {
struct pcidas64_private *devpriv = dev->private; struct pcidas64_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev; struct comedi_subdevice *s = dev->read_subdev;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
unsigned int i; unsigned int i;
uint16_t prepost_bits; uint16_t prepost_bits;
int read_segment, read_index, write_segment, write_index; int read_segment, read_index, write_segment, write_index;
@ -2672,22 +2664,16 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev)
devpriv->ai_fifo_segment_length - read_index; devpriv->ai_fifo_segment_length - read_index;
else else
num_samples = write_index - read_index; num_samples = write_index - read_index;
if (cmd->stop_src == TRIG_COUNT) {
if (devpriv->ai_count == 0)
break;
if (num_samples > devpriv->ai_count)
num_samples = devpriv->ai_count;
devpriv->ai_count -= num_samples;
}
if (num_samples < 0) { if (num_samples < 0) {
dev_err(dev->class_dev, dev_err(dev->class_dev,
"cb_pcidas64: bug! num_samples < 0\n"); "cb_pcidas64: bug! num_samples < 0\n");
break; break;
} }
num_samples = comedi_nsamples_left(s, num_samples);
if (num_samples == 0)
break;
for (i = 0; i < num_samples; i++) { for (i = 0; i < num_samples; i++) {
unsigned short val; unsigned short val;
@ -2707,29 +2693,23 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev)
{ {
struct pcidas64_private *devpriv = dev->private; struct pcidas64_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev; struct comedi_subdevice *s = dev->read_subdev;
struct comedi_async *async = s->async; unsigned int nsamples;
struct comedi_cmd *cmd = &async->cmd;
unsigned int i; unsigned int i;
unsigned int max_transfer = 100000;
uint32_t fifo_data; uint32_t fifo_data;
int write_code = int write_code =
readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff; readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff;
int read_code = int read_code =
readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff;
if (cmd->stop_src == TRIG_COUNT) { nsamples = comedi_nsamples_left(s, 100000);
if (max_transfer > devpriv->ai_count) for (i = 0; read_code != write_code && i < nsamples;) {
max_transfer = devpriv->ai_count;
}
for (i = 0; read_code != write_code && i < max_transfer;) {
unsigned short val; unsigned short val;
fifo_data = readl(dev->mmio + ADC_FIFO_REG); fifo_data = readl(dev->mmio + ADC_FIFO_REG);
val = fifo_data & 0xffff; val = fifo_data & 0xffff;
comedi_buf_write_samples(s, &val, 1); comedi_buf_write_samples(s, &val, 1);
i++; i++;
if (i < max_transfer) { if (i < nsamples) {
val = (fifo_data >> 16) & 0xffff; val = (fifo_data >> 16) & 0xffff;
comedi_buf_write_samples(s, &val, 1); comedi_buf_write_samples(s, &val, 1);
i++; i++;
@ -2737,7 +2717,6 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev)
read_code = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & read_code = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) &
0x7fff; 0x7fff;
} }
devpriv->ai_count -= i;
} }
/* empty fifo */ /* empty fifo */
@ -2755,8 +2734,7 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
{ {
const struct pcidas64_board *thisboard = dev->board_ptr; const struct pcidas64_board *thisboard = dev->board_ptr;
struct pcidas64_private *devpriv = dev->private; struct pcidas64_private *devpriv = dev->private;
struct comedi_async *async = dev->read_subdev->async; struct comedi_subdevice *s = dev->read_subdev;
struct comedi_cmd *cmd = &async->cmd;
uint32_t next_transfer_addr; uint32_t next_transfer_addr;
int j; int j;
int num_samples = 0; int num_samples = 0;
@ -2777,13 +2755,8 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] + devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] +
DMA_BUFFER_SIZE) && j < ai_dma_ring_count(thisboard); j++) { DMA_BUFFER_SIZE) && j < ai_dma_ring_count(thisboard); j++) {
/* transfer data from dma buffer to comedi buffer */ /* transfer data from dma buffer to comedi buffer */
num_samples = dma_transfer_size(dev); num_samples = comedi_nsamples_left(s, dma_transfer_size(dev));
if (cmd->stop_src == TRIG_COUNT) { comedi_buf_write_samples(s,
if (num_samples > devpriv->ai_count)
num_samples = devpriv->ai_count;
devpriv->ai_count -= num_samples;
}
comedi_buf_write_samples(dev->read_subdev,
devpriv->ai_buffer[devpriv->ai_dma_index], devpriv->ai_buffer[devpriv->ai_dma_index],
num_samples); num_samples);
devpriv->ai_dma_index = (devpriv->ai_dma_index + 1) % devpriv->ai_dma_index = (devpriv->ai_dma_index + 1) %
@ -2835,10 +2808,10 @@ static void handle_ai_interrupt(struct comedi_device *dev,
spin_unlock_irqrestore(&dev->spinlock, flags); spin_unlock_irqrestore(&dev->spinlock, flags);
} }
/* if we are have all the data, then quit */ /* if we are have all the data, then quit */
if ((cmd->stop_src == TRIG_COUNT && (int)devpriv->ai_count <= 0) || if ((cmd->stop_src == TRIG_COUNT &&
(cmd->stop_src == TRIG_EXT && (status & ADC_STOP_BIT))) { async->scans_done >= cmd->stop_arg) ||
(cmd->stop_src == TRIG_EXT && (status & ADC_STOP_BIT)))
async->events |= COMEDI_CB_EOA; async->events |= COMEDI_CB_EOA;
}
comedi_handle_events(dev, s); comedi_handle_events(dev, s);
} }