diff options
author | Bryan Freed <bfreed@chromium.org> | 2011-12-02 14:19:30 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-12-08 11:30:24 -0800 |
commit | 014fcb1db5d8fd1dde1e3b777389edcd8d85a2e2 (patch) | |
tree | e010e88a74ef182219505a0fedfd38eeb50e2638 /drivers/staging/iio | |
parent | d666c0d490d85d35fe6d6d45ba029cf16046dc82 (diff) |
iio: light sensor: Improve granularity of tsl2583 lux values.
When illuminance0_calibbias gets 4000 (for a 4x multiplier), we see lux
granularity of 4. Reversing the order of the right shift and multiplication
retains the precision of the unadjusted lux value.
Signed-off-by: Bryan Freed <bfreed@chromium.org>
Acked-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/iio')
-rw-r--r-- | drivers/staging/iio/light/tsl2583.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/staging/iio/light/tsl2583.c b/drivers/staging/iio/light/tsl2583.c index 80f77cf8e9c2..25f4c1dd5bf2 100644 --- a/drivers/staging/iio/light/tsl2583.c +++ b/drivers/staging/iio/light/tsl2583.c @@ -194,6 +194,7 @@ static int taos_get_lux(struct iio_dev *indio_dev) { u16 ch0, ch1; /* separated ch0/ch1 data from device */ u32 lux; /* raw lux calculated from device data */ + u64 lux64; u32 ratio; u8 buf[5]; struct taos_lux *p; @@ -297,9 +298,19 @@ static int taos_get_lux(struct iio_dev *indio_dev) lux = (lux + (chip->als_time_scale >> 1)) / chip->als_time_scale; - /* adjust for active gain scale */ - lux >>= 13; /* tables have factor of 8192 builtin for accuracy */ - lux = (lux * chip->taos_settings.als_gain_trim + 500) / 1000; + /* Adjust for active gain scale. + * The taos_device_lux tables above have a factor of 8192 built in, + * so we need to shift right. + * User-specified gain provides a multiplier. + * Apply user-specified gain before shifting right to retain precision. + * Use 64 bits to avoid overflow on multiplication. + * Then go back to 32 bits before division to avoid using div_u64(). + */ + lux64 = lux; + lux64 = lux64 * chip->taos_settings.als_gain_trim; + lux64 >>= 13; + lux = lux64; + lux = (lux + 500) / 1000; if (lux > TSL258X_LUX_CALC_OVER_FLOW) { /* check for overflow */ return_max: lux = TSL258X_LUX_CALC_OVER_FLOW; |