in drivers/ni_mio_common.c [1821:1924]
static int ni_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct ni_private *devpriv = dev->private;
unsigned int mask = s->maxdata;
int i, n;
unsigned int signbits;
unsigned int d;
ni_load_channelgain_list(dev, s, 1, &insn->chanspec);
ni_clear_ai_fifo(dev);
signbits = devpriv->ai_offset[0];
if (devpriv->is_611x) {
for (n = 0; n < num_adc_stages_611x; n++) {
ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE,
NISTC_AI_CMD1_REG);
udelay(1);
}
for (n = 0; n < insn->n; n++) {
ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE,
NISTC_AI_CMD1_REG);
/* The 611x has screwy 32-bit FIFOs. */
d = 0;
for (i = 0; i < NI_TIMEOUT; i++) {
if (ni_readb(dev, NI_E_STATUS_REG) & 0x80) {
d = ni_readl(dev,
NI611X_AI_FIFO_DATA_REG);
d >>= 16;
d &= 0xffff;
break;
}
if (!(ni_stc_readw(dev, NISTC_AI_STATUS1_REG) &
NISTC_AI_STATUS1_FIFO_E)) {
d = ni_readl(dev,
NI611X_AI_FIFO_DATA_REG);
d &= 0xffff;
break;
}
}
if (i == NI_TIMEOUT) {
dev_err(dev->class_dev, "timeout\n");
return -ETIME;
}
d += signbits;
data[n] = d & 0xffff;
}
} else if (devpriv->is_6143) {
for (n = 0; n < insn->n; n++) {
ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE,
NISTC_AI_CMD1_REG);
/*
* The 6143 has 32-bit FIFOs. You need to strobe a
* bit to move a single 16bit stranded sample into
* the FIFO.
*/
d = 0;
for (i = 0; i < NI_TIMEOUT; i++) {
if (ni_readl(dev, NI6143_AI_FIFO_STATUS_REG) &
0x01) {
/* Get stranded sample into FIFO */
ni_writel(dev, 0x01,
NI6143_AI_FIFO_CTRL_REG);
d = ni_readl(dev,
NI6143_AI_FIFO_DATA_REG);
break;
}
}
if (i == NI_TIMEOUT) {
dev_err(dev->class_dev, "timeout\n");
return -ETIME;
}
data[n] = (((d >> 16) & 0xFFFF) + signbits) & 0xFFFF;
}
} else {
for (n = 0; n < insn->n; n++) {
ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE,
NISTC_AI_CMD1_REG);
for (i = 0; i < NI_TIMEOUT; i++) {
if (!(ni_stc_readw(dev, NISTC_AI_STATUS1_REG) &
NISTC_AI_STATUS1_FIFO_E))
break;
}
if (i == NI_TIMEOUT) {
dev_err(dev->class_dev, "timeout\n");
return -ETIME;
}
if (devpriv->is_m_series) {
d = ni_readl(dev, NI_M_AI_FIFO_DATA_REG);
d &= mask;
data[n] = d;
} else {
d = ni_readw(dev, NI_E_AI_FIFO_DATA_REG);
d += signbits;
data[n] = d & 0xffff;
}
}
}
return insn->n;
}