staging: comedi: das800: tidy up das800_ai_insn_read()
Introduce a couple helper functions to read the 16-bit analog input sample and to wait for the analog conversion to complete. Tidy up the das800_ai_insn_read() function by using the new helpers. Also, remove the need for 'thisboard' in the function by checking the subdevice 'maxdata' variable to determine the analog input resolution. 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:
Родитель
e245b6d126
Коммит
b4780a3afb
|
@ -473,6 +473,14 @@ static int das800_ai_do_cmd(struct comedi_device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int das800_ai_get_sample(struct comedi_device *dev)
|
||||
{
|
||||
unsigned int lsb = inb(dev->iobase + DAS800_LSB);
|
||||
unsigned int msb = inb(dev->iobase + DAS800_MSB);
|
||||
|
||||
return (msb << 8) | lsb;
|
||||
}
|
||||
|
||||
static irqreturn_t das800_interrupt(int irq, void *d)
|
||||
{
|
||||
short i; /* loop index */
|
||||
|
@ -570,61 +578,60 @@ static irqreturn_t das800_interrupt(int irq, void *d)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int das800_wait_for_conv(struct comedi_device *dev, int timeout)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < timeout; i++) {
|
||||
if (!(inb(dev->iobase + DAS800_STATUS) & BUSY))
|
||||
return 0;
|
||||
}
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
static int das800_ai_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
const struct das800_board *thisboard = comedi_board(dev);
|
||||
struct das800_private *devpriv = dev->private;
|
||||
int i, n;
|
||||
int chan;
|
||||
int range;
|
||||
int lsb, msb;
|
||||
int timeout = 1000;
|
||||
unsigned int chan = CR_CHAN(insn->chanspec);
|
||||
unsigned int range = CR_RANGE(insn->chanspec);
|
||||
unsigned long irq_flags;
|
||||
unsigned int val;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
das800_disable(dev);
|
||||
|
||||
/* set multiplexer */
|
||||
chan = CR_CHAN(insn->chanspec);
|
||||
|
||||
spin_lock_irqsave(&dev->spinlock, irq_flags);
|
||||
das800_ind_write(dev, chan | devpriv->do_bits, CONTROL1);
|
||||
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
|
||||
|
||||
/* set gain / range */
|
||||
range = CR_RANGE(insn->chanspec);
|
||||
if (thisboard->resolution == 12 && range)
|
||||
if (s->maxdata == 0x0fff && range)
|
||||
range += 0x7;
|
||||
range &= 0xf;
|
||||
outb(range, dev->iobase + DAS800_GAIN);
|
||||
|
||||
udelay(5);
|
||||
|
||||
for (n = 0; n < insn->n; n++) {
|
||||
for (i = 0; i < insn->n; i++) {
|
||||
/* trigger conversion */
|
||||
outb_p(0, dev->iobase + DAS800_MSB);
|
||||
|
||||
for (i = 0; i < timeout; i++) {
|
||||
if (!(inb(dev->iobase + DAS800_STATUS) & BUSY))
|
||||
break;
|
||||
}
|
||||
if (i == timeout) {
|
||||
comedi_error(dev, "timeout");
|
||||
return -ETIME;
|
||||
}
|
||||
lsb = inb(dev->iobase + DAS800_LSB);
|
||||
msb = inb(dev->iobase + DAS800_MSB);
|
||||
if (thisboard->resolution == 12) {
|
||||
data[n] = (lsb >> 4) & 0xff;
|
||||
data[n] |= (msb << 4);
|
||||
} else {
|
||||
data[n] = (msb << 8) | lsb;
|
||||
}
|
||||
ret = das800_wait_for_conv(dev, 1000);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val = das800_ai_get_sample(dev);
|
||||
if (s->maxdata == 0x0fff)
|
||||
val >>= 4; /* 12-bit sample */
|
||||
data[i] = val & s->maxdata;
|
||||
}
|
||||
|
||||
return n;
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
static int das800_di_insn_bits(struct comedi_device *dev,
|
||||
|
|
Загрузка…
Ссылка в новой задаче