[PATCH 54/66] staging: comedi: pcl812: cleanup setup_range_channel()

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


Move this function to remove the need for the forward declaration. Rename it
so it has namespace associated with the driver. Remove the unnecessary
comedi_subdevice parameter from the function.

The hardware does not support analog input channel scanning so the mux and
range need to be set before each (*insn_read) and when advancing to the next
channel in an async command. Instead of storing the last chan/range in the
private data just store the chanspec to determine if the mux and range need
to be changed.

Refactor pcl812_reset() a bit so we can use the helper function to set the
mux and range.

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

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/pcl812.c | 109 +++++++++++++++-----------------
 1 file changed, 50 insertions(+), 59 deletions(-)

diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c
index 7e105c8..862e379 100644
--- a/drivers/staging/comedi/drivers/pcl812.c
+++ b/drivers/staging/comedi/drivers/pcl812.c
@@ -141,8 +141,11 @@
 #define PCL812_DI_MSB_REG			0x07
 #define PCL812_STATUS_REG			0x08
 #define PCL812_STATUS_DRDY			(1 << 5)
-#define PCL812_GAIN	      9
-#define PCL812_MUX	     10
+#define PCL812_RANGE_REG			0x09
+#define PCL812_MUX_REG				0x0a
+#define PCL812_MUX_CHAN(x)			((x) << 0)
+#define PCL812_MUX_CS0				(1 << 4)
+#define PCL812_MUX_CS1				(1 << 5)
 #define PCL812_MODE	     11
 #define PCL812_CNTENABLE     10
 #define PCL812_SOFTTRIG	     12
@@ -500,8 +503,7 @@ static const struct pcl812_board boardtypes[] = {
 struct pcl812_private {
 	unsigned char dma;	/*  >0 use dma ( usedDMA channel) */
 	unsigned char range_correction;	/*  =1 we must add 1 to range number */
-	unsigned char old_chan_reg;	/*  lastly used chan/gain pair */
-	unsigned char old_gain_reg;
+	unsigned int last_ai_chanspec;
 	unsigned char mode_reg_int;	/*  there is stored INT number for some card */
 	unsigned int ai_poll_ptr;	/*  how many sampes transfer poll */
 	unsigned int ai_act_scan;	/*  how many scans we finished */
@@ -524,10 +526,6 @@ struct pcl812_private {
 	unsigned int ai_eos:1;
 };
 
-static void setup_range_channel(struct comedi_device *dev,
-				struct comedi_subdevice *s,
-				unsigned int rangechan, char wait);
-
 static void pcl812_start_pacer(struct comedi_device *dev, bool load_timers)
 {
 	struct pcl812_private *devpriv = dev->private;
@@ -633,6 +631,41 @@ static void pcl812_ai_setup_next_dma(struct comedi_device *dev,
 	enable_dma(devpriv->dma);
 }
 
+static void pcl812_ai_set_chan_range(struct comedi_device *dev,
+				     unsigned int chanspec, char wait)
+{
+	struct pcl812_private *devpriv = dev->private;
+	unsigned int chan = CR_CHAN(chanspec);
+	unsigned int range = CR_RANGE(chanspec);
+	unsigned int mux = 0;
+
+	if (chanspec == devpriv->last_ai_chanspec)
+		return;
+
+	devpriv->last_ai_chanspec = chanspec;
+
+	if (devpriv->use_mpc508) {
+		if (devpriv->use_diff) {
+			mux |= PCL812_MUX_CS0 | PCL812_MUX_CS1;
+		} else {
+			if (chan < 8)
+				mux |= PCL812_MUX_CS0;
+			else
+				mux |= PCL812_MUX_CS1;
+		}
+	}
+
+	outb(mux | PCL812_MUX_CHAN(chan), dev->iobase + PCL812_MUX_REG);
+	outb(range + devpriv->range_correction, dev->iobase + PCL812_RANGE_REG);
+
+	if (wait)
+		/*
+		 * XXX this depends on selected range and can be very long for
+		 * some high gain ranges!
+		 */
+		udelay(devpriv->max_812_ai_mode0_rangewait);
+}
+
 static void pcl812_ai_clear_eoc(struct comedi_device *dev)
 {
 	/* writing any value clears the interrupt request */
@@ -761,8 +794,7 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	pcl812_start_pacer(dev, false);
 
-	/*  select first channel and range */
-	setup_range_channel(dev, s, cmd->chanlist[0], 1);
+	pcl812_ai_set_chan_range(dev, cmd->chanlist[0], 1);
 
 	if (devpriv->dma) {	/*  check if we can use DMA transfer */
 		devpriv->ai_dma = 1;
@@ -851,7 +883,7 @@ static void pcl812_handle_eoc(struct comedi_device *dev,
 	if (next_chan >= cmd->chanlist_len)
 		next_chan = 0;
 	if (cmd->chanlist[s->async->cur_chan] != cmd->chanlist[next_chan])
-		setup_range_channel(dev, s, cmd->chanlist[next_chan], 0);
+		pcl812_ai_set_chan_range(dev, cmd->chanlist[next_chan], 0);
 
 	pcl812_ai_next_chan(dev, s);
 }
@@ -956,48 +988,6 @@ static int pcl812_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
 	return s->async->buf_write_count - s->async->buf_read_count;
 }
 
-static void setup_range_channel(struct comedi_device *dev,
-				struct comedi_subdevice *s,
-				unsigned int rangechan, char wait)
-{
-	struct pcl812_private *devpriv = dev->private;
-	unsigned char chan_reg = CR_CHAN(rangechan);	/*  normal board */
-							/*  gain index */
-	unsigned char gain_reg = CR_RANGE(rangechan) +
-				 devpriv->range_correction;
-
-	if ((chan_reg == devpriv->old_chan_reg)
-	    && (gain_reg == devpriv->old_gain_reg))
-		return;		/*  we can return, no change */
-
-	devpriv->old_chan_reg = chan_reg;
-	devpriv->old_gain_reg = gain_reg;
-
-	if (devpriv->use_mpc508) {
-		if (devpriv->use_diff) {
-			chan_reg = chan_reg | 0x30;	/*  DIFF inputs */
-		} else {
-			if (chan_reg & 0x80)
-							/*  SE inputs 8-15 */
-				chan_reg = chan_reg | 0x20;
-			else
-							/*  SE inputs 0-7 */
-				chan_reg = chan_reg | 0x10;
-		}
-	}
-
-	outb(chan_reg, dev->iobase + PCL812_MUX);	/* select channel */
-	outb(gain_reg, dev->iobase + PCL812_GAIN);	/* select gain */
-
-
-	if (wait)
-		/*
-		 * XXX this depends on selected range and can be very long for
-		 * some high gain ranges!
-		 */
-		udelay(devpriv->max_812_ai_mode0_rangewait);
-}
-
 static int pcl812_ai_cancel(struct comedi_device *dev,
 			    struct comedi_subdevice *s)
 {
@@ -1025,8 +1015,7 @@ static int pcl812_ai_insn_read(struct comedi_device *dev,
 	/* select software trigger */
 	outb(devpriv->mode_reg_int | 1, dev->iobase + PCL812_MODE);
 
-	/*  select channel and renge */
-	setup_range_channel(dev, s, insn->chanspec, 1);
+	pcl812_ai_set_chan_range(dev, insn->chanspec, 1);
 
 	for (i = 0; i < insn->n; i++) {
 		pcl812_ai_clear_eoc(dev);
@@ -1110,10 +1099,12 @@ static void pcl812_reset(struct comedi_device *dev)
 	const struct pcl812_board *board = comedi_board(dev);
 	struct pcl812_private *devpriv = dev->private;
 
-	outb(0, dev->iobase + PCL812_MUX);
-	outb(0 + devpriv->range_correction, dev->iobase + PCL812_GAIN);
-	devpriv->old_chan_reg = -1;	/*  invalidate chain/gain memory */
-	devpriv->old_gain_reg = -1;
+	/*
+	 * Invalidate last_ai_chanspec then set analog input to
+	 * known channel/range.
+	 */
+	devpriv->last_ai_chanspec = CR_PACK(16, 0, 0);
+	pcl812_ai_set_chan_range(dev, CR_PACK(0, 0, 0), 0);
 
 	switch (board->board_type) {
 	case boardPCL812PG:
-- 
1.8.5.2



More information about the devel mailing list