[PATCH 45/47 v2] staging: comedi: dmm32at: use comedi_timeout()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Use comedi_timeout() to wait for the analog input settle and end-of-
conversion. These tests use different registers but the same bit so
the register is passed as the 'context'. The same test is used in
dmm32at_ai_cmd() but the 'insn' is not available. This is ok since
the test function, and comedi_timeout() don't use it.

Use comedi_timout() to wait for the analog output end-of-conversion.

Signed-off-by: H Hartley Sweeten <hsweeten@xxxxxxxxxxxxxxxxxxx>
Cc: Ian Abbott <abbotti@xxxxxxxxx>
Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
 drivers/staging/comedi/drivers/dmm32at.c | 83 +++++++++++++++++++-------------
 1 file changed, 50 insertions(+), 33 deletions(-)

diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c
index 78a1962..c8a36eb 100644
--- a/drivers/staging/comedi/drivers/dmm32at.c
+++ b/drivers/staging/comedi/drivers/dmm32at.c
@@ -164,16 +164,29 @@ struct dmm32at_private {
 
 };
 
+static int dmm32at_ai_status(struct comedi_device *dev,
+			     struct comedi_subdevice *s,
+			     struct comedi_insn *insn,
+			     unsigned long context)
+{
+	unsigned char status;
+
+	status = inb(dev->iobase + context);
+	if ((status & DMM32AT_STATUS) == 0)
+		return 0;
+	return -EBUSY;
+}
+
 static int dmm32at_ai_rinsn(struct comedi_device *dev,
 			    struct comedi_subdevice *s,
 			    struct comedi_insn *insn, unsigned int *data)
 {
-	int n, i;
+	int n;
 	unsigned int d;
-	unsigned char status;
 	unsigned short msb, lsb;
 	unsigned char chan;
 	int range;
+	int ret;
 
 	/* get the channel and range number */
 
@@ -190,26 +203,20 @@ static int dmm32at_ai_rinsn(struct comedi_device *dev,
 	outb(dmm32at_rangebits[range], dev->iobase + DMM32AT_AICONF);
 
 	/* wait for circuit to settle */
-	for (i = 0; i < 40000; i++) {
-		status = inb(dev->iobase + DMM32AT_AIRBACK);
-		if ((status & DMM32AT_STATUS) == 0)
-			break;
-	}
-	if (i == 40000)
-		return -ETIMEDOUT;
+	ret = comedi_timeout(dev, s, insn, dmm32at_ai_status, DMM32AT_AIRBACK);
+	if (ret)
+		return ret;
 
 	/* convert n samples */
 	for (n = 0; n < insn->n; n++) {
 		/* trigger conversion */
 		outb(0xff, dev->iobase + DMM32AT_CONV);
+
 		/* wait for conversion to end */
-		for (i = 0; i < 40000; i++) {
-			status = inb(dev->iobase + DMM32AT_AISTAT);
-			if ((status & DMM32AT_STATUS) == 0)
-				break;
-		}
-		if (i == 40000)
-			return -ETIMEDOUT;
+		ret = comedi_timeout(dev, s, insn, dmm32at_ai_status,
+				     DMM32AT_AISTAT);
+		if (ret)
+			return ret;
 
 		/* read data */
 		lsb = inb(dev->iobase + DMM32AT_AILSB);
@@ -403,8 +410,9 @@ static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct dmm32at_private *devpriv = dev->private;
 	struct comedi_cmd *cmd = &s->async->cmd;
-	int i, range;
-	unsigned char chanlo, chanhi, status;
+	int range;
+	unsigned char chanlo, chanhi;
+	int ret;
 
 	if (!cmd->chanlist)
 		return -EINVAL;
@@ -439,14 +447,13 @@ static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 						      * isr */
 	}
 
-	/* wait for circuit to settle */
-	for (i = 0; i < 40000; i++) {
-		status = inb(dev->iobase + DMM32AT_AIRBACK);
-		if ((status & DMM32AT_STATUS) == 0)
-			break;
-	}
-	if (i == 40000)
-		return -ETIMEDOUT;
+	/*
+	 * wait for circuit to settle
+	 * we don't have the 'insn' here but it's not needed
+	 */
+	ret = comedi_timeout(dev, s, NULL, dmm32at_ai_status, DMM32AT_AIRBACK);
+	if (ret)
+		return ret;
 
 	if (devpriv->ai_scans_left > 1) {
 		/* start the clock and enable the interrupts */
@@ -525,6 +532,19 @@ static irqreturn_t dmm32at_isr(int irq, void *d)
 	return IRQ_HANDLED;
 }
 
+static int dmm32at_ao_eoc(struct comedi_device *dev,
+			  struct comedi_subdevice *s,
+			  struct comedi_insn *insn,
+			  unsigned long context)
+{
+	unsigned char status;
+
+	status = inb(dev->iobase + DMM32AT_DACSTAT);
+	if ((status & DMM32AT_DACBUSY) == 0)
+		return 0;
+	return -EBUSY;
+}
+
 static int dmm32at_ao_winsn(struct comedi_device *dev,
 			    struct comedi_subdevice *s,
 			    struct comedi_insn *insn, unsigned int *data)
@@ -533,6 +553,7 @@ static int dmm32at_ao_winsn(struct comedi_device *dev,
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
 	unsigned char hi, lo, status;
+	int ret;
 
 	/* Writing a list of values to an AO channel is probably not
 	 * very useful, but that's how the interface is defined. */
@@ -549,13 +570,9 @@ static int dmm32at_ao_winsn(struct comedi_device *dev,
 		outb(hi, dev->iobase + DMM32AT_DACMSB);
 
 		/* wait for circuit to settle */
-		for (i = 0; i < 40000; i++) {
-			status = inb(dev->iobase + DMM32AT_DACSTAT);
-			if ((status & DMM32AT_DACBUSY) == 0)
-				break;
-		}
-		if (i == 40000)
-			return -ETIMEDOUT;
+		ret = comedi_timeout(dev, s, insn, dmm32at_ao_eoc, 0);
+		if (ret)
+			return ret;
 
 		/* dummy read to update trigger the output */
 		status = inb(dev->iobase + DMM32AT_DACMSB);
-- 
1.8.5.2

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux