[PATCH 58/66] staging: comedi: pcl816: define the mode register bits

H Hartley Sweeten hsweeten at visionengravers.com
Fri Feb 28 23:24:47 UTC 2014


Define the bits in the register to remove the magic values.

Fix pcl816_ai_cancel(). The 0x73 mask of the value read from the control
register will not stop the A/D as indicated by the comment. This would just
clear the DS1, POE, and EXT bits which would only disable the external
trigger. Setting the control register to '0' would then stop the A/D which
means the software trigger following it would not work.

Just disable the trigger and clear any pending end-of-conversion.

Signed-off-by: H Hartley Sweeten <hsweeten at visionengravers.com>
Cc: Ian Abbott <abbotti at mev.co.uk>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/staging/comedi/drivers/pcl816.c | 61 +++++++++++++++------------------
 1 file changed, 28 insertions(+), 33 deletions(-)

diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
index 8065df2..1c84066 100644
--- a/drivers/staging/comedi/drivers/pcl816.c
+++ b/drivers/staging/comedi/drivers/pcl816.c
@@ -52,6 +52,17 @@ Configuration Options:
 #define PCL816_RANGE_REG			0x09
 #define PCL816_MUX_REG				0x0b
 #define PCL816_MUX_SCAN(_first, _last)		(((_last) << 4) | (_first))
+#define PCL816_CTRL_REG				0x0c
+#define PCL816_CTRL_DISABLE_TRIG		(0 << 0)
+#define PCL816_CTRL_SOFT_TRIG			(1 << 0)
+#define PCL816_CTRL_PACER_TRIG			(1 << 1)
+#define PCL816_CTRL_EXT_TRIG			(1 << 2)
+#define PCL816_CTRL_POE				(1 << 3)
+#define PCL816_CTRL_DMAEN			(1 << 4)
+#define PCL816_CTRL_INTEN			(1 << 5)
+#define PCL816_CTRL_DMASRC_SLOT0		(0 << 6)
+#define PCL816_CTRL_DMASRC_SLOT1		(1 << 6)
+#define PCL816_CTRL_DMASRC_SLOT2		(2 << 6)
 #define PCL816_STATUS_REG			0x0d
 #define PCL816_STATUS_NEXT_CHAN_MASK		(0xf << 0)
 #define PCL816_STATUS_INTSRC_MASK		(3 << 4)
@@ -64,8 +75,6 @@ Configuration Options:
 
 /* W: clear INT request */
 #define PCL816_CLRINT 10
-/* R/W: operation control register */
-#define PCL816_CONTROL 12
 
 
 #define MAGIC_DMA_WORD 0x5a5a
@@ -466,7 +475,8 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct pcl816_private *devpriv = dev->private;
 	struct comedi_cmd *cmd = &s->async->cmd;
-	unsigned int dmairq;
+	unsigned int dmairq = 0;
+	unsigned int ctrl = 0;
 	unsigned int seglen;
 
 	if (devpriv->ai_cmd_running)
@@ -486,29 +496,23 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	devpriv->ai_poll_ptr = 0;
 	devpriv->ai_cmd_canceled = 0;
 
-	if (devpriv->dma)
+	dmairq |= dev->irq;
+	ctrl |= PCL816_CTRL_INTEN;
+	if (devpriv->dma) {
 		pcl816_ai_setup_dma(dev, s);
+		dmairq |= (devpriv->dma << 4);
+		ctrl |= (PCL816_CTRL_DMAEN | PCL816_CTRL_DMASRC_SLOT0);
+	}
 
 	pcl816_start_pacer(dev, true);
-	dmairq = ((devpriv->dma & 0x3) << 4) | (dev->irq & 0x7);
-
-	switch (cmd->convert_src) {
-	case TRIG_TIMER:
-		/*  Pacer+IRQ+DMA */
-		outb(0x32, dev->iobase + PCL816_CONTROL);
 
-		/*  write irq and DMA to card */
-		outb(dmairq, dev->iobase + PCL816_STATUS_REG);
-		break;
-
-	default:
-		/*  Ext trig+IRQ+DMA */
-		outb(0x34, dev->iobase + PCL816_CONTROL);
+	if (cmd->convert_src == TRIG_TIMER)
+		ctrl |= PCL816_CTRL_PACER_TRIG;
+	else	/* TRIG_EXT */
+		ctrl |= PCL816_CTRL_EXT_TRIG;
 
-		/*  write irq to card */
-		outb(dmairq, dev->iobase + PCL816_STATUS_REG);
-		break;
-	}
+	outb(ctrl, dev->iobase + PCL816_CTRL_REG);
+	outb(dmairq, dev->iobase + PCL816_STATUS_REG);
 
 	return 0;
 }
@@ -568,10 +572,7 @@ static int pcl816_ai_cancel(struct comedi_device *dev,
 	if (devpriv->dma)
 		disable_dma(devpriv->dma);
 
-	outb(inb(dev->iobase + PCL816_CONTROL) & 0x73,
-	     dev->iobase + PCL816_CONTROL);	/* Stop A/D */
-	udelay(1);
-	outb(0, dev->iobase + PCL816_CONTROL);	/* Stop A/D */
+	outb(PCL816_CTRL_DISABLE_TRIG, dev->iobase + PCL816_CTRL_REG);
 
 	/* Stop pacer */
 	i8254_set_mode(dev->iobase + PCL816_TIMER_BASE, 0,
@@ -579,11 +580,6 @@ static int pcl816_ai_cancel(struct comedi_device *dev,
 	i8254_set_mode(dev->iobase + PCL816_TIMER_BASE, 0,
 		       1, I8254_MODE0 | I8254_BINARY);
 
-	pcl816_ai_soft_trig(dev);
-	pcl816_ai_get_sample(dev, s);
-
-	/* Stop A/D */
-	outb(0, dev->iobase + PCL816_CONTROL);
 	pcl816_ai_clear_eoc(dev);
 
 	devpriv->ai_cmd_running = 0;
@@ -658,8 +654,7 @@ static int pcl816_ai_insn_read(struct comedi_device *dev,
 	int ret = 0;
 	int i;
 
-	/*  software trigger, DMA and INT off */
-	outb(0, dev->iobase + PCL816_CONTROL);
+	outb(PCL816_CTRL_SOFT_TRIG, dev->iobase + PCL816_CTRL_REG);
 
 	pcl816_ai_set_chan_range(dev, chan, range);
 	pcl816_ai_set_chan_scan(dev, chan, chan);
@@ -709,7 +704,7 @@ static void pcl816_reset(struct comedi_device *dev)
 {
 	unsigned long timer_base = dev->iobase + PCL816_TIMER_BASE;
 
-	outb(0, dev->iobase + PCL816_CONTROL);
+	outb(PCL816_CTRL_DISABLE_TRIG, dev->iobase + PCL816_CTRL_REG);
 	pcl816_ai_set_chan_range(dev, 0, 0);
 	pcl816_ai_clear_eoc(dev);
 
-- 
1.8.5.2



More information about the devel mailing list