staging: comedi: pcl818: introduce pcl818_ai_get_sample()
Introduce a helper function to read the 12-bit analog input data sample and optionally return the channel that the sample was for. The channel is only used in the interrupt routine to check for dropped samples. 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:
parent
66581ca576
commit
8fc9f652ab
1 changed files with 21 additions and 9 deletions
|
@ -372,6 +372,21 @@ static int pcl818_ai_cancel(struct comedi_device *dev,
|
||||||
static void start_pacer(struct comedi_device *dev, int mode,
|
static void start_pacer(struct comedi_device *dev, int mode,
|
||||||
unsigned int divisor1, unsigned int divisor2);
|
unsigned int divisor1, unsigned int divisor2);
|
||||||
|
|
||||||
|
static unsigned int pcl818_ai_get_sample(struct comedi_device *dev,
|
||||||
|
struct comedi_subdevice *s,
|
||||||
|
unsigned int *chan)
|
||||||
|
{
|
||||||
|
unsigned int val;
|
||||||
|
|
||||||
|
val = inb(dev->iobase + PCL818_AD_HI) << 8;
|
||||||
|
val |= inb(dev->iobase + PCL818_AD_LO);
|
||||||
|
|
||||||
|
if (chan)
|
||||||
|
*chan = val & 0xf;
|
||||||
|
|
||||||
|
return (val >> 4) & s->maxdata;
|
||||||
|
}
|
||||||
|
|
||||||
static int pcl818_ai_eoc(struct comedi_device *dev,
|
static int pcl818_ai_eoc(struct comedi_device *dev,
|
||||||
struct comedi_subdevice *s,
|
struct comedi_subdevice *s,
|
||||||
struct comedi_insn *insn,
|
struct comedi_insn *insn,
|
||||||
|
@ -416,8 +431,7 @@ static int pcl818_ai_insn_read(struct comedi_device *dev,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
data[n] = ((inb(dev->iobase + PCL818_AD_HI) << 4) |
|
data[n] = pcl818_ai_get_sample(dev, s, NULL);
|
||||||
(inb(dev->iobase + PCL818_AD_LO) >> 4));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
|
@ -502,7 +516,7 @@ 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;
|
||||||
unsigned char low;
|
unsigned int chan;
|
||||||
int timeout = 50; /* wait max 50us */
|
int timeout = 50; /* wait max 50us */
|
||||||
|
|
||||||
while (timeout--) {
|
while (timeout--) {
|
||||||
|
@ -518,14 +532,13 @@ static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d)
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
|
|
||||||
conv_finish:
|
conv_finish:
|
||||||
low = inb(dev->iobase + PCL818_AD_LO);
|
comedi_buf_put(s->async, pcl818_ai_get_sample(dev, s, &chan));
|
||||||
comedi_buf_put(s->async, ((inb(dev->iobase + PCL818_AD_HI) << 4) | (low >> 4))); /* get one sample */
|
|
||||||
outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */
|
outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */
|
||||||
|
|
||||||
if ((low & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) { /* dropout! */
|
if (chan != devpriv->act_chanlist[devpriv->act_chanlist_pos]) {
|
||||||
dev_dbg(dev->class_dev,
|
dev_dbg(dev->class_dev,
|
||||||
"A/D mode1/3 IRQ - channel dropout %x!=%x !\n",
|
"A/D mode1/3 IRQ - channel dropout %x!=%x !\n",
|
||||||
(low & 0xf),
|
chan,
|
||||||
devpriv->act_chanlist[devpriv->act_chanlist_pos]);
|
devpriv->act_chanlist[devpriv->act_chanlist_pos]);
|
||||||
pcl818_ai_cancel(dev, s);
|
pcl818_ai_cancel(dev, s);
|
||||||
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
|
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
|
||||||
|
@ -1166,8 +1179,7 @@ static int pcl818_ai_cancel(struct comedi_device *dev,
|
||||||
udelay(1);
|
udelay(1);
|
||||||
start_pacer(dev, -1, 0, 0);
|
start_pacer(dev, -1, 0, 0);
|
||||||
outb(0, dev->iobase + PCL818_AD_LO);
|
outb(0, dev->iobase + PCL818_AD_LO);
|
||||||
inb(dev->iobase + PCL818_AD_LO);
|
pcl818_ai_get_sample(dev, s, NULL);
|
||||||
inb(dev->iobase + PCL818_AD_HI);
|
|
||||||
outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */
|
outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */
|
||||||
outb(0, dev->iobase + PCL818_CONTROL); /* Stop A/D */
|
outb(0, dev->iobase + PCL818_CONTROL); /* Stop A/D */
|
||||||
if (devpriv->usefifo) { /* FIFO shutdown */
|
if (devpriv->usefifo) { /* FIFO shutdown */
|
||||||
|
|
Loading…
Add table
Reference in a new issue