CHROMIUM: iio: isl29018: make read delay depend on resolution
authorOlof Johansson <olofj@chromium.org>
Tue, 7 Aug 2012 22:34:32 +0000 (15:34 -0700)
committerGerrit <chrome-bot@google.com>
Wed, 8 Aug 2012 02:06:35 +0000 (19:06 -0700)
Currently the driver sleeps for 100ms on any read, but it's really
dependent on the configured resolution, and O(2^n). So for devices that
are configured with lower resolution, we can have a much shorter delay.

BUG=chrome-os-partner:12369
TEST=regular backlight test suite

Change-Id: Id54c127512ab1aa40d83b7bfca5a6675761349e3
Signed-off-by: Olof Johansson <olofj@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/29487
Reviewed-by: Bryan Freed <bfreed@chromium.org>
Reviewed-by: Benson Leung <bleung@chromium.org>
drivers/staging/iio/light/isl29018.c

index a0aecd6..826c510 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/slab.h>
 #include "../iio.h"
 #include "../sysfs.h"
-#define CONVERSION_TIME_MS             100
 
 #define ISL29018_REG_ADD_COMMAND1      0x00
 #define COMMMAND1_OPMODE_SHIFT         5
@@ -138,6 +137,22 @@ static int isl29018_set_resolution(struct i2c_client *client,
                        COMMANDII_RESOLUTION_SHIFT);
 }
 
+static void integration_wait(struct isl29018_chip *chip)
+{
+       int wait_time;
+
+       /* Integration and conversion time is described in the data sheet
+        * as 2^n x (constant), and for 16 bits it's 90ms. So calculate
+        * from there.
+        *
+        * Since the time taken depends on a resistor value, leave some
+        * margin above the 90ms timeout, otherwise we risk reading a
+        * stale value.
+        */
+       wait_time = DIV_ROUND_UP(100, 1 << (16 - chip->adc_bit));
+       msleep(wait_time);
+}
+
 static int isl29018_read_sensor_input(struct i2c_client *client, int mode)
 {
        int status;
@@ -150,7 +165,7 @@ static int isl29018_read_sensor_input(struct i2c_client *client, int mode)
                dev_err(&client->dev, "Error in setting operating mode\n");
                return status;
        }
-       msleep(CONVERSION_TIME_MS);
+       integration_wait(iio_priv(i2c_get_clientdata(client)));
        status = i2c_smbus_read_word_data(client, ISL29018_REG_ADD_DATA_LSB);
        if (status < 0) {
                dev_err(&client->dev, "Error in reading Lux DATA\n");