[PATCH 11/30] staging: comedi: dmm32at: introduce dmm32at_ai_set_chanspec()

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

 



Introduce a helper function to set the analog input channel scan and range
control registers. Use the new helper in the analog input (*insn_read) and
(*do_cmd) functions.

The extra sanity checks in the (*do_cmd) are not necessary. The cmd->chanlist
will always be valid and the (*do_cmdtest) validates the channel list in
Step 5.

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 | 53 ++++++++++++--------------------
 1 file changed, 20 insertions(+), 33 deletions(-)

diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c
index 6413f60..dc222d1 100644
--- a/drivers/staging/comedi/drivers/dmm32at.c
+++ b/drivers/staging/comedi/drivers/dmm32at.c
@@ -154,6 +154,24 @@ struct dmm32at_private {
 	unsigned char dio_config;
 };
 
+static void dmm32at_ai_set_chanspec(struct comedi_device *dev,
+				    struct comedi_subdevice *s,
+				    unsigned int chanspec, int nchan)
+{
+	unsigned int chan = CR_CHAN(chanspec);
+	unsigned int range = CR_RANGE(chanspec);
+	unsigned int last_chan = (chan + nchan - 1) % s->n_chan;
+
+	outb(DMM32AT_FIFORESET, dev->iobase + DMM32AT_FIFOCNTRL);
+
+	if (nchan > 1)
+		outb(DMM32AT_SCANENABLE, dev->iobase + DMM32AT_FIFOCNTRL);
+
+	outb(chan, dev->iobase + DMM32AT_AILOW);
+	outb(last_chan, dev->iobase + DMM32AT_AIHIGH);
+	outb(dmm32at_rangebits[range], dev->iobase + DMM32AT_AICONF);
+}
+
 static unsigned int dmm32at_ai_get_sample(struct comedi_device *dev,
 					  struct comedi_subdevice *s)
 {
@@ -184,18 +202,10 @@ static int dmm32at_ai_insn_read(struct comedi_device *dev,
 				struct comedi_insn *insn,
 				unsigned int *data)
 {
-	unsigned int chan = CR_CHAN(insn->chanspec);
-	unsigned int range = CR_RANGE(insn->chanspec);
 	int ret;
 	int i;
 
-	/* zero scan and fifo control and reset fifo */
-	outb(DMM32AT_FIFORESET, dev->iobase + DMM32AT_FIFOCNTRL);
-
-	/* set the channel and range */
-	outb(chan, dev->iobase + DMM32AT_AILOW);
-	outb(chan, dev->iobase + DMM32AT_AIHIGH);
-	outb(dmm32at_rangebits[range], dev->iobase + DMM32AT_AICONF);
+	dmm32at_ai_set_chanspec(dev, s, insn->chanspec, 1);
 
 	/* wait for circuit to settle */
 	ret = comedi_timeout(dev, s, insn, dmm32at_ai_status, DMM32AT_AIRBACK);
@@ -347,32 +357,9 @@ static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec)
 static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct comedi_cmd *cmd = &s->async->cmd;
-	int range;
-	unsigned char chanlo, chanhi;
 	int ret;
 
-	if (!cmd->chanlist)
-		return -EINVAL;
-
-	/* get the channel list and range */
-	chanlo = CR_CHAN(cmd->chanlist[0]) & (s->n_chan - 1);
-	chanhi = chanlo + cmd->chanlist_len - 1;
-	if (chanhi >= s->n_chan)
-		return -EINVAL;
-	range = CR_RANGE(cmd->chanlist[0]);
-
-	/* reset fifo */
-	outb(DMM32AT_FIFORESET, dev->iobase + DMM32AT_FIFOCNTRL);
-
-	/* set scan enable */
-	outb(DMM32AT_SCANENABLE, dev->iobase + DMM32AT_FIFOCNTRL);
-
-	/* write the ai channel range regs */
-	outb(chanlo, dev->iobase + DMM32AT_AILOW);
-	outb(chanhi, dev->iobase + DMM32AT_AIHIGH);
-
-	/* set the range bits */
-	outb(dmm32at_rangebits[range], dev->iobase + DMM32AT_AICONF);
+	dmm32at_ai_set_chanspec(dev, s, cmd->chanlist[0], cmd->chanlist_len);
 
 	/* reset the interrupt just in case */
 	outb(DMM32AT_INTRESET, dev->iobase + DMM32AT_CNTRL);
-- 
2.0.3

_______________________________________________
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