unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int range = CR_RANGE(insn->chanspec);
unsigned int aref = CR_AREF(insn->chanspec);
- unsigned short val;
- int ret;
+ unsigned int val;
+ int ret = 0;
+ int i;
- /* stop any running conversion */
- devpriv->ctrl1 &= ~ME_CTRL1_ADC_MODE_MASK;
- writew(devpriv->ctrl1, dev->mmio + ME_CTRL1_REG);
+ /*
+ * For differential operation, there are only 8 input channels
+ * and only bipolar ranges are available.
+ */
+ if (aref & AREF_DIFF) {
+ if (chan > 7 || comedi_range_is_unipolar(s, range))
+ return -EINVAL;
+ }
/* clear chanlist and ad fifo */
devpriv->ctrl2 &= ~(ME_CTRL2_ADFIFO_ENA | ME_CTRL2_CHANLIST_ENA);
devpriv->ctrl1 |= ME_CTRL1_ADC_MODE_SOFT_TRIG;
writew(devpriv->ctrl1, dev->mmio + ME_CTRL1_REG);
- /* start ai conversion */
- readw(dev->mmio + ME_CTRL1_REG);
+ for (i = 0; i < insn->n; i++) {
+ /* start ai conversion */
+ readw(dev->mmio + ME_CTRL1_REG);
- /* wait for ADC fifo not empty flag */
- ret = comedi_timeout(dev, s, insn, me_ai_eoc, 0);
- if (ret)
- return ret;
+ /* wait for ADC fifo not empty flag */
+ ret = comedi_timeout(dev, s, insn, me_ai_eoc, 0);
+ if (ret)
+ break;
+
+ /* get value from ADC fifo */
+ val = readw(dev->mmio + ME_AI_FIFO_REG) & s->maxdata;
- /* get value from ADC fifo */
- val = readw(dev->mmio + ME_AI_FIFO_REG);
- val = (val ^ 0x800) & 0x0fff;
- data[0] = val;
+ /* munge 2's complement value to offset binary */
+ data[i] = comedi_offset_munge(s, val);
+ }
/* stop any running conversion */
devpriv->ctrl1 &= ~ME_CTRL1_ADC_MODE_MASK;
writew(devpriv->ctrl1, dev->mmio + ME_CTRL1_REG);
- return 1;
+ return ret ? ret : insn->n;
}
static int me_ao_insn_write(struct comedi_device *dev,
s = &dev->subdevices[0];
s->type = COMEDI_SUBD_AI;
- s->subdev_flags = SDF_READABLE | SDF_COMMON;
+ s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_DIFF;
s->n_chan = 16;
s->maxdata = 0x0fff;
s->len_chanlist = 16;