Commit 6d5b7858 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

staging: comedi: pcl818: factor out the common "next ai chan" code

The DMA, FIFO, and EOC interrupt handlers all have common code that
bumps the counters in the private data that keep track of what channel
is being sampled next and when all the data has been sampled.

Factor this common code into a helper function.

Make sure the COMEDI_CB_BLOCK event is set when advancing to the next
channel so that when the comedi_event() is finally called the core will
wake the async_queue to return the analog input data.

Also, make sure the COMEDI_CB_EOS event is set at the completion of each
scan.
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 0f8837bc
...@@ -540,12 +540,41 @@ static int pcl818_do_insn_bits(struct comedi_device *dev, ...@@ -540,12 +540,41 @@ static int pcl818_do_insn_bits(struct comedi_device *dev,
return insn->n; return insn->n;
} }
static bool pcl818_ai_next_chan(struct comedi_device *dev,
struct comedi_subdevice *s)
{
struct pcl818_private *devpriv = dev->private;
struct comedi_cmd *cmd = &s->async->cmd;
s->async->events |= COMEDI_CB_BLOCK;
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 >= cmd->chanlist_len) {
s->async->cur_chan = 0;
devpriv->ai_act_scan--;
s->async->events |= COMEDI_CB_EOS;
}
if (cmd->stop_src == TRIG_COUNT && devpriv->ai_act_scan == 0) {
/* all data sampled */
s->cancel(dev, s);
s->async->events |= COMEDI_CB_EOA;
comedi_event(dev, s);
return false;
}
return true;
}
static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d) static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d)
{ {
struct comedi_device *dev = d; struct comedi_device *dev = d;
struct pcl818_private *devpriv = dev->private; struct pcl818_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev; struct comedi_subdevice *s = dev->read_subdev;
struct comedi_cmd *cmd = &s->async->cmd;
unsigned int chan; unsigned int chan;
if (pcl818_ai_eoc(dev, s, NULL, 0)) { if (pcl818_ai_eoc(dev, s, NULL, 0)) {
...@@ -570,21 +599,10 @@ static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d) ...@@ -570,21 +599,10 @@ static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d)
comedi_event(dev, s); comedi_event(dev, s);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
devpriv->act_chanlist_pos++;
if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len)
devpriv->act_chanlist_pos = 0;
s->async->cur_chan++; if (!pcl818_ai_next_chan(dev, s))
if (s->async->cur_chan >= cmd->chanlist_len) { return IRQ_HANDLED;
s->async->cur_chan = 0;
devpriv->ai_act_scan--;
}
if (cmd->stop_src == TRIG_COUNT && devpriv->ai_act_scan == 0) {
/* all data sampled */
s->cancel(dev, s);
s->async->events |= COMEDI_CB_EOA;
}
comedi_event(dev, s); comedi_event(dev, s);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -594,7 +612,6 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d) ...@@ -594,7 +612,6 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
struct comedi_device *dev = d; struct comedi_device *dev = d;
struct pcl818_private *devpriv = dev->private; struct pcl818_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev; struct comedi_subdevice *s = dev->read_subdev;
struct comedi_cmd *cmd = &s->async->cmd;
int i, len, bufptr; int i, len, bufptr;
unsigned short *ptr; unsigned short *ptr;
...@@ -621,23 +638,8 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d) ...@@ -621,23 +638,8 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
comedi_buf_put(s->async, ptr[bufptr++] >> 4); /* get one sample */ comedi_buf_put(s->async, ptr[bufptr++] >> 4); /* get one sample */
devpriv->act_chanlist_pos++; if (!pcl818_ai_next_chan(dev, s))
if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len)
devpriv->act_chanlist_pos = 0;
s->async->cur_chan++;
if (s->async->cur_chan >= cmd->chanlist_len) {
s->async->cur_chan = 0;
devpriv->ai_act_scan--;
}
if (cmd->stop_src == TRIG_COUNT && devpriv->ai_act_scan == 0) {
/* all data sampled */
s->cancel(dev, s);
s->async->events |= COMEDI_CB_EOA;
comedi_event(dev, s);
return IRQ_HANDLED; return IRQ_HANDLED;
}
} }
if (len > 0) if (len > 0)
...@@ -650,7 +652,6 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d) ...@@ -650,7 +652,6 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d)
struct comedi_device *dev = d; struct comedi_device *dev = d;
struct pcl818_private *devpriv = dev->private; struct pcl818_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev; struct comedi_subdevice *s = dev->read_subdev;
struct comedi_cmd *cmd = &s->async->cmd;
int i, len; int i, len;
unsigned char lo; unsigned char lo;
...@@ -694,23 +695,8 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d) ...@@ -694,23 +695,8 @@ 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 */ comedi_buf_put(s->async, (lo >> 4) | (inb(dev->iobase + PCL818_FI_DATAHI) << 4)); /* get one sample */
devpriv->act_chanlist_pos++; if (!pcl818_ai_next_chan(dev, s))
if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len)
devpriv->act_chanlist_pos = 0;
s->async->cur_chan++;
if (s->async->cur_chan >= cmd->chanlist_len) {
s->async->cur_chan = 0;
devpriv->ai_act_scan--;
}
if (cmd->stop_src == TRIG_COUNT && devpriv->ai_act_scan == 0) {
/* all data sampled */
s->cancel(dev, s);
s->async->events |= COMEDI_CB_EOA;
comedi_event(dev, s);
return IRQ_HANDLED; return IRQ_HANDLED;
}
} }
if (len > 0) if (len > 0)
......
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