aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2016-09-01 05:44:43 -0400
committerJonathan Cameron <jic23@kernel.org>2016-09-18 06:31:31 -0400
commit84e2f6f9583f195b9851a8f6340bb526749ea609 (patch)
tree5a259880d554cb2a87225e98e2d30bf398875b20 /drivers/iio
parentdc6ac050c7d405cf99f847d5f7b485a7dfa00840 (diff)
iio: accel: kxsd9: Fix up offset and scaling
This fixes several errors in the offset and scaling of the raw values from the KXSD9 sensor: - The code did not convert the big endian value from the sensor into the endianness of the host CPU. Fix this with be16_to_cpu() on the raw obtained value. - The code did not regard the fact that only the upper 12 bits of the accelerometer values are valid. Shift these down four bits to yield the real raw value. - Further the sensor provides 2048 at zero g. This means that an offset of 2048 must be subtracted from the raw value before scaling. This was not taken into account by the driver, yielding a weird value. Fix this by providing this offset in sysfs. To house the scaling code better, the value reading code was factored into the raw reading function. This proper scaling and offseting is necessary to get proper values out of triggered buffer by offsetting, shifting and scaling them. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Tested-by: Jonathan Cameron <jic23@kernel.org> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/accel/kxsd9.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/drivers/iio/accel/kxsd9.c b/drivers/iio/accel/kxsd9.c
index dc0bea7cbf4f..6a1e67723d0c 100644
--- a/drivers/iio/accel/kxsd9.c
+++ b/drivers/iio/accel/kxsd9.c
@@ -55,6 +55,8 @@ struct kxsd9_state {
55/* reverse order */ 55/* reverse order */
56static const int kxsd9_micro_scales[4] = { 47853, 35934, 23927, 11978 }; 56static const int kxsd9_micro_scales[4] = { 47853, 35934, 23927, 11978 };
57 57
58#define KXSD9_ZERO_G_OFFSET -2048
59
58static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro) 60static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro)
59{ 61{
60 int ret, i; 62 int ret, i;
@@ -82,19 +84,6 @@ error_ret:
82 return ret; 84 return ret;
83} 85}
84 86
85static int kxsd9_read(struct iio_dev *indio_dev, u8 address)
86{
87 int ret;
88 struct kxsd9_state *st = iio_priv(indio_dev);
89 __be16 raw_val;
90
91 ret = regmap_bulk_read(st->map, address, &raw_val, sizeof(raw_val));
92 if (ret)
93 return ret;
94 /* Only 12 bits are valid */
95 return be16_to_cpu(raw_val) & 0xfff0;
96}
97
98static IIO_CONST_ATTR(accel_scale_available, 87static IIO_CONST_ATTR(accel_scale_available,
99 KXSD9_SCALE_2G " " 88 KXSD9_SCALE_2G " "
100 KXSD9_SCALE_4G " " 89 KXSD9_SCALE_4G " "
@@ -131,13 +120,24 @@ static int kxsd9_read_raw(struct iio_dev *indio_dev,
131 int ret = -EINVAL; 120 int ret = -EINVAL;
132 struct kxsd9_state *st = iio_priv(indio_dev); 121 struct kxsd9_state *st = iio_priv(indio_dev);
133 unsigned int regval; 122 unsigned int regval;
123 __be16 raw_val;
124 u16 nval;
134 125
135 switch (mask) { 126 switch (mask) {
136 case IIO_CHAN_INFO_RAW: 127 case IIO_CHAN_INFO_RAW:
137 ret = kxsd9_read(indio_dev, chan->address); 128 ret = regmap_bulk_read(st->map, chan->address, &raw_val,
138 if (ret < 0) 129 sizeof(raw_val));
130 if (ret)
139 goto error_ret; 131 goto error_ret;
140 *val = ret; 132 nval = be16_to_cpu(raw_val);
133 /* Only 12 bits are valid */
134 nval >>= 4;
135 *val = nval;
136 ret = IIO_VAL_INT;
137 break;
138 case IIO_CHAN_INFO_OFFSET:
139 /* This has a bias of -2048 */
140 *val = KXSD9_ZERO_G_OFFSET;
141 ret = IIO_VAL_INT; 141 ret = IIO_VAL_INT;
142 break; 142 break;
143 case IIO_CHAN_INFO_SCALE: 143 case IIO_CHAN_INFO_SCALE:
@@ -161,7 +161,8 @@ error_ret:
161 .modified = 1, \ 161 .modified = 1, \
162 .channel2 = IIO_MOD_##axis, \ 162 .channel2 = IIO_MOD_##axis, \
163 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 163 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
164 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 164 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
165 BIT(IIO_CHAN_INFO_OFFSET), \
165 .address = KXSD9_REG_##axis, \ 166 .address = KXSD9_REG_##axis, \
166 } 167 }
167 168