summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Abbott <abbotti@mev.co.uk>2010-01-20 13:04:46 (GMT)
committerGreg Kroah-Hartman <gregkh@suse.de>2010-03-04 00:42:47 (GMT)
commitb3559cb1aa5f863e1ce9b94b518be7ddf6680e45 (patch)
tree76a55c0276395056cf6aabffb03346fd41b0ad54
parent13de4f000ec491b16a820e4ed59de2c98b7807be (diff)
downloadlinux-fsl-qoriq-b3559cb1aa5f863e1ce9b94b518be7ddf6680e45.tar.xz
Staging: comedi: pcl818: Correct AI scan counting and channel checks
For AI commands, the scan counter should be updated after every scan. It was being updated after every sample except for DMA mode where it was being updated after every repeated segment of the channel list. Also AI commands with multiple channels were being terminated with an error prematurely except in DMA mode. This was because the driver was comparing channel numbers received from the hardware (combined with the sample value) with the expected channel numbers to check for a "channel dropout". This test was failing incorrectly because the driver was not keeping the current position within the (repeated segment of the) channel list up to date. Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/staging/comedi/drivers/pcl818.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
index d048101..40ac293 100644
--- a/drivers/staging/comedi/drivers/pcl818.c
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -557,8 +557,14 @@ conv_finish:
comedi_event(dev, s);
return IRQ_HANDLED;
}
- if (s->async->cur_chan == 0) {
+ devpriv->act_chanlist_pos++;
+ if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
+ devpriv->act_chanlist_pos = 0;
+ }
+ s->async->cur_chan++;
+ if (s->async->cur_chan >= devpriv->ai_n_chan) {
/* printk("E"); */
+ s->async->cur_chan = 0;
devpriv->ai_act_scan--;
}
@@ -627,9 +633,13 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
devpriv->act_chanlist_pos++;
if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
- devpriv->ai_act_scan--;
devpriv->act_chanlist_pos = 0;
}
+ s->async->cur_chan++;
+ if (s->async->cur_chan >= devpriv->ai_n_chan) {
+ s->async->cur_chan = 0;
+ devpriv->ai_act_scan--;
+ }
if (!devpriv->neverending_ai)
if (devpriv->ai_act_scan == 0) { /* all data sampled */
@@ -717,7 +727,14 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d)
comedi_buf_put(s->async, dmabuf[bufptr++] >> 4); /* get one sample */
bufptr &= (devpriv->dmasamplsize - 1);
- if (s->async->cur_chan == 0) {
+ devpriv->act_chanlist_pos++;
+ if (devpriv->act_chanlist_pos >=
+ devpriv->act_chanlist_len) {
+ devpriv->act_chanlist_pos = 0;
+ }
+ s->async->cur_chan++;
+ if (s->async->cur_chan >= devpriv->ai_n_chan) {
+ s->async->cur_chan = 0;
devpriv->ai_act_scan--;
}
@@ -796,7 +813,13 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d)
comedi_buf_put(s->async, (lo >> 4) | (inb(dev->iobase + PCL818_FI_DATAHI) << 4)); /* get one sample */
- if (s->async->cur_chan == 0) {
+ devpriv->act_chanlist_pos++;
+ if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
+ devpriv->act_chanlist_pos = 0;
+ }
+ s->async->cur_chan++;
+ if (s->async->cur_chan >= devpriv->ai_n_chan) {
+ s->async->cur_chan = 0;
devpriv->ai_act_scan--;
}