aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH Hartley Sweeten <hsweeten@visionengravers.com>2013-04-22 21:37:03 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-04-23 13:41:51 -0400
commitb4780a3afb944765f4b94d79463e570e4472ccb6 (patch)
tree3774db3ff7da245953406a5e47351a56d120d722
parente245b6d12691c1e178a6a075ac3cd1b7cd0d2e0e (diff)
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>
-rw-r--r--drivers/staging/comedi/drivers/das800.c63
1 files changed, 35 insertions, 28 deletions
diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c
index cc4202eb3958..c30309cbc855 100644
--- a/drivers/staging/comedi/drivers/das800.c
+++ b/drivers/staging/comedi/drivers/das800.c
@@ -473,6 +473,14 @@ static int das800_ai_do_cmd(struct comedi_device *dev,
473 return 0; 473 return 0;
474} 474}
475 475
476static unsigned int das800_ai_get_sample(struct comedi_device *dev)
477{
478 unsigned int lsb = inb(dev->iobase + DAS800_LSB);
479 unsigned int msb = inb(dev->iobase + DAS800_MSB);
480
481 return (msb << 8) | lsb;
482}
483
476static irqreturn_t das800_interrupt(int irq, void *d) 484static irqreturn_t das800_interrupt(int irq, void *d)
477{ 485{
478 short i; /* loop index */ 486 short i; /* loop index */
@@ -570,61 +578,60 @@ static irqreturn_t das800_interrupt(int irq, void *d)
570 return IRQ_HANDLED; 578 return IRQ_HANDLED;
571} 579}
572 580
581static int das800_wait_for_conv(struct comedi_device *dev, int timeout)
582{
583 int i;
584
585 for (i = 0; i < timeout; i++) {
586 if (!(inb(dev->iobase + DAS800_STATUS) & BUSY))
587 return 0;
588 }
589 return -ETIME;
590}
591
573static int das800_ai_insn_read(struct comedi_device *dev, 592static int das800_ai_insn_read(struct comedi_device *dev,
574 struct comedi_subdevice *s, 593 struct comedi_subdevice *s,
575 struct comedi_insn *insn, 594 struct comedi_insn *insn,
576 unsigned int *data) 595 unsigned int *data)
577{ 596{
578 const struct das800_board *thisboard = comedi_board(dev);
579 struct das800_private *devpriv = dev->private; 597 struct das800_private *devpriv = dev->private;
580 int i, n; 598 unsigned int chan = CR_CHAN(insn->chanspec);
581 int chan; 599 unsigned int range = CR_RANGE(insn->chanspec);
582 int range;
583 int lsb, msb;
584 int timeout = 1000;
585 unsigned long irq_flags; 600 unsigned long irq_flags;
601 unsigned int val;
602 int ret;
603 int i;
586 604
587 das800_disable(dev); 605 das800_disable(dev);
588 606
589 /* set multiplexer */ 607 /* set multiplexer */
590 chan = CR_CHAN(insn->chanspec);
591
592 spin_lock_irqsave(&dev->spinlock, irq_flags); 608 spin_lock_irqsave(&dev->spinlock, irq_flags);
593 das800_ind_write(dev, chan | devpriv->do_bits, CONTROL1); 609 das800_ind_write(dev, chan | devpriv->do_bits, CONTROL1);
594 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 610 spin_unlock_irqrestore(&dev->spinlock, irq_flags);
595 611
596 /* set gain / range */ 612 /* set gain / range */
597 range = CR_RANGE(insn->chanspec); 613 if (s->maxdata == 0x0fff && range)
598 if (thisboard->resolution == 12 && range)
599 range += 0x7; 614 range += 0x7;
600 range &= 0xf; 615 range &= 0xf;
601 outb(range, dev->iobase + DAS800_GAIN); 616 outb(range, dev->iobase + DAS800_GAIN);
602 617
603 udelay(5); 618 udelay(5);
604 619
605 for (n = 0; n < insn->n; n++) { 620 for (i = 0; i < insn->n; i++) {
606 /* trigger conversion */ 621 /* trigger conversion */
607 outb_p(0, dev->iobase + DAS800_MSB); 622 outb_p(0, dev->iobase + DAS800_MSB);
608 623
609 for (i = 0; i < timeout; i++) { 624 ret = das800_wait_for_conv(dev, 1000);
610 if (!(inb(dev->iobase + DAS800_STATUS) & BUSY)) 625 if (ret)
611 break; 626 return ret;
612 } 627
613 if (i == timeout) { 628 val = das800_ai_get_sample(dev);
614 comedi_error(dev, "timeout"); 629 if (s->maxdata == 0x0fff)
615 return -ETIME; 630 val >>= 4; /* 12-bit sample */
616 } 631 data[i] = val & s->maxdata;
617 lsb = inb(dev->iobase + DAS800_LSB);
618 msb = inb(dev->iobase + DAS800_MSB);
619 if (thisboard->resolution == 12) {
620 data[n] = (lsb >> 4) & 0xff;
621 data[n] |= (msb << 4);
622 } else {
623 data[n] = (msb << 8) | lsb;
624 }
625 } 632 }
626 633
627 return n; 634 return insn->n;
628} 635}
629 636
630static int das800_di_insn_bits(struct comedi_device *dev, 637static int das800_di_insn_bits(struct comedi_device *dev,