[PATCH 26/29] staging: comedi: dt282x: avoid calculating the timer divisor multiple times

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

 



A common timer is used for analog input and output async commands. The
(*do_cmdtest) for both subdevices calculates the divisor as part of
Step 4 when validating the trigger arguments. The divisor is calculated
again in the (*do_cmd) for both subdevices in order to set the timer.

The comedi core only calls the (*do_cmd) is called after a successful
(*do_cmdtest). Save the divisor from the (*do_cmdtest) in the private
data and use that value in the (*do_cmd).

The extra check of the cmd->convert_arg in dt282x_ai_cmd() is not necessary.
The convert_arg was already checked in the (*do_cmdtest), and it's not used
in the (*do_cmd).

Tidy up dt282x_ns_to_timer(), the parameters are all unsigned int's and the
mask of the 'flags' can be moved here to simplify the callers.

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

diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c
index 28ee5a3..9d8b603 100644
--- a/drivers/staging/comedi/drivers/dt282x.c
+++ b/drivers/staging/comedi/drivers/dt282x.c
@@ -331,6 +331,8 @@ struct dt282x_private {
 	unsigned int da0_2scomp:1;
 	unsigned int da1_2scomp:1;
 
+	unsigned int divisor;
+
 	unsigned short ao_readback[2];
 
 	int dacsr;	/* software copies of registers */
@@ -413,34 +415,34 @@ static void dt282x_disable_dma(struct comedi_device *dev)
 	disable_dma(devpriv->dma[1].chan);
 }
 
-static int dt282x_ns_to_timer(int *nanosec, int round_mode)
+static unsigned int dt282x_ns_to_timer(unsigned int *ns, unsigned int flags)
 {
-	int prescale, base, divider;
+	unsigned int prescale, base, divider;
 
 	for (prescale = 0; prescale < 16; prescale++) {
 		if (prescale == 1)
 			continue;
 		base = 250 * (1 << prescale);
-		switch (round_mode) {
+		switch (flags & TRIG_ROUND_MASK) {
 		case TRIG_ROUND_NEAREST:
 		default:
-			divider = (*nanosec + base / 2) / base;
+			divider = (*ns + base / 2) / base;
 			break;
 		case TRIG_ROUND_DOWN:
-			divider = (*nanosec) / base;
+			divider = (*ns) / base;
 			break;
 		case TRIG_ROUND_UP:
-			divider = (*nanosec + base - 1) / base;
+			divider = (*ns + base - 1) / base;
 			break;
 		}
 		if (divider < 256) {
-			*nanosec = divider * base;
+			*ns = divider * base;
 			return (prescale << 8) | (255 - divider);
 		}
 	}
 	base = 250 * (1 << 15);
 	divider = 255;
-	*nanosec = divider * base;
+	*ns = divider * base;
 	return (15 << 8) | (255 - divider);
 }
 
@@ -688,9 +690,11 @@ static int dt282x_ai_insn_read(struct comedi_device *dev,
 }
 
 static int dt282x_ai_cmdtest(struct comedi_device *dev,
-			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
+			     struct comedi_subdevice *s,
+			     struct comedi_cmd *cmd)
 {
 	const struct dt282x_board *board = comedi_board(dev);
+	struct dt282x_private *devpriv = dev->private;
 	int err = 0;
 	unsigned int arg;
 
@@ -748,7 +752,7 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev,
 	/* step 4: fix up any arguments */
 
 	arg = cmd->convert_arg;
-	dt282x_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+	devpriv->divisor = dt282x_ns_to_timer(&arg, cmd->flags);
 	err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
 
 	if (err)
@@ -759,18 +763,13 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev,
 
 static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
-	const struct dt282x_board *board = comedi_board(dev);
 	struct dt282x_private *devpriv = dev->private;
 	struct comedi_cmd *cmd = &s->async->cmd;
-	int timer;
 	int ret;
 
 	dt282x_disable_dma(dev);
 
-	if (cmd->convert_arg < board->ai_speed)
-		cmd->convert_arg = board->ai_speed;
-	timer = dt282x_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_NEAREST);
-	outw(timer, dev->iobase + DT2821_TMRCTR);
+	outw(devpriv->divisor, dev->iobase + DT2821_TMRCTR);
 
 	if (cmd->scan_begin_src == TRIG_FOLLOW) {
 		/* internal trigger */
@@ -889,8 +888,10 @@ static int dt282x_ao_insn_write(struct comedi_device *dev,
 }
 
 static int dt282x_ao_cmdtest(struct comedi_device *dev,
-			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
+			     struct comedi_subdevice *s,
+			     struct comedi_cmd *cmd)
 {
+	struct dt282x_private *devpriv = dev->private;
 	int err = 0;
 	unsigned int arg;
 
@@ -933,7 +934,7 @@ static int dt282x_ao_cmdtest(struct comedi_device *dev,
 	/* step 4: fix up any arguments */
 
 	arg = cmd->scan_begin_arg;
-	dt282x_ns_to_timer(&arg, cmd->flags & TRIG_ROUND_MASK);
+	devpriv->divisor = dt282x_ns_to_timer(&arg, cmd->flags);
 	err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
 
 	if (err)
@@ -979,7 +980,6 @@ static int dt282x_ao_inttrig(struct comedi_device *dev,
 static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct dt282x_private *devpriv = dev->private;
-	int timer;
 	struct comedi_cmd *cmd = &s->async->cmd;
 
 	dt282x_disable_dma(dev);
@@ -994,8 +994,7 @@ static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	devpriv->dma_dir = DMA_MODE_WRITE;
 	devpriv->current_dma_index = 0;
 
-	timer = dt282x_ns_to_timer(&cmd->scan_begin_arg, TRIG_ROUND_NEAREST);
-	outw(timer, dev->iobase + DT2821_TMRCTR);
+	outw(devpriv->divisor, dev->iobase + DT2821_TMRCTR);
 
 	devpriv->dacsr = DT2821_SSEL | DT2821_DACLK | DT2821_IDARDY;
 	outw(devpriv->dacsr, dev->iobase + DT2821_DACSR);
-- 
1.9.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