Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4384aaad authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman
Browse files

staging: comedi: pcl812: cleanup setup_range_channel()



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: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 598e61e6
Loading
Loading
Loading
Loading
+50 −59
Original line number Diff line number Diff line
@@ -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: