return insn->n;
}
+static bool pcl818_ai_dropout(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int chan)
+{
+ struct pcl818_private *devpriv = dev->private;
+ unsigned int expected_chan;
+
+ expected_chan = devpriv->act_chanlist[devpriv->act_chanlist_pos];
+ if (chan != expected_chan) {
+ dev_dbg(dev->class_dev,
+ "A/D mode1/3 %s - channel dropout %d!=%d !\n",
+ (devpriv->dma) ? "DMA" :
+ (devpriv->usefifo) ? "FIFO" : "IRQ",
+ chan, expected_chan);
+ s->cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return true;
+ }
+ return false;
+}
+
static bool pcl818_ai_next_chan(struct comedi_device *dev,
struct comedi_subdevice *s)
{
static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d)
{
struct comedi_device *dev = d;
- struct pcl818_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
unsigned int chan;
+ unsigned int val;
if (pcl818_ai_eoc(dev, s, NULL, 0)) {
outb(0, dev->iobase + PCL818_STATUS); /* clear INT request */
return IRQ_HANDLED;
}
- comedi_buf_put(s->async, pcl818_ai_get_sample(dev, s, &chan));
+ val = pcl818_ai_get_sample(dev, s, &chan);
outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */
- if (chan != devpriv->act_chanlist[devpriv->act_chanlist_pos]) {
- dev_dbg(dev->class_dev,
- "A/D mode1/3 IRQ - channel dropout %x!=%x !\n",
- chan,
- devpriv->act_chanlist[devpriv->act_chanlist_pos]);
- s->cancel(dev, s);
- s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev, s);
+ if (pcl818_ai_dropout(dev, s, chan))
return IRQ_HANDLED;
- }
+
+ comedi_buf_put(s->async, val);
if (!pcl818_ai_next_chan(dev, s))
return IRQ_HANDLED;
struct comedi_device *dev = d;
struct pcl818_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
- int i, len, bufptr;
unsigned short *ptr;
+ unsigned int chan;
+ unsigned int val;
+ int i, len, bufptr;
pcl818_ai_setup_next_dma(dev, s);
bufptr = 0;
for (i = 0; i < len; i++) {
- if ((ptr[bufptr] & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) { /* dropout! */
- dev_dbg(dev->class_dev,
- "A/D mode1/3 DMA - channel dropout %d(card)!=%d(chanlist) at %d !\n",
- (ptr[bufptr] & 0xf),
- devpriv->act_chanlist[devpriv->act_chanlist_pos],
- devpriv->act_chanlist_pos);
- s->cancel(dev, s);
- s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev, s);
+ val = ptr[bufptr++];
+ chan = val & 0xf;
+ val = (val >> 4) & s->maxdata;
+
+ if (pcl818_ai_dropout(dev, s, chan))
return IRQ_HANDLED;
- }
- comedi_buf_put(s->async, ptr[bufptr++] >> 4); /* get one sample */
+ comedi_buf_put(s->async, val);
if (!pcl818_ai_next_chan(dev, s))
return IRQ_HANDLED;
static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d)
{
struct comedi_device *dev = d;
- struct pcl818_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
unsigned int status;
unsigned int chan;
for (i = 0; i < len; i++) {
val = pcl818_ai_get_fifo_sample(dev, s, &chan);
- if (chan != devpriv->act_chanlist[devpriv->act_chanlist_pos]) {
- dev_dbg(dev->class_dev,
- "A/D mode1/3 FIFO - channel dropout %d!=%d !\n",
- chan,
- devpriv->act_chanlist[devpriv->act_chanlist_pos]);
- s->cancel(dev, s);
- s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev, s);
+
+ if (pcl818_ai_dropout(dev, s, chan))
return IRQ_HANDLED;
- }
comedi_buf_put(s->async, val);