diff options
author | H Hartley Sweeten <hsweeten@visionengravers.com> | 2013-04-22 21:37:03 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-04-23 13:41:51 -0400 |
commit | b4780a3afb944765f4b94d79463e570e4472ccb6 (patch) | |
tree | 3774db3ff7da245953406a5e47351a56d120d722 | |
parent | e245b6d12691c1e178a6a075ac3cd1b7cd0d2e0e (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.c | 63 |
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 | ||
476 | static 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 | |||
476 | static irqreturn_t das800_interrupt(int irq, void *d) | 484 | static 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 | ||
581 | static 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 | |||
573 | static int das800_ai_insn_read(struct comedi_device *dev, | 592 | static 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 | ||
630 | static int das800_di_insn_bits(struct comedi_device *dev, | 637 | static int das800_di_insn_bits(struct comedi_device *dev, |