iio: kx022a: Fix acceleration value scaling
authorMatti Vaittinen <mazziesaccount@gmail.com>
Thu, 19 Oct 2023 13:23:56 +0000 (16:23 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 1 Jan 2024 12:42:37 +0000 (12:42 +0000)
commit 92bfa4ab1b79be95c4f52d13f5386390f0a513c2 upstream.

The IIO ABI mandates acceleration values from accelerometer to be
emitted in m/s^2. The KX022A was emitting values in micro m/s^2.

Fix driver to report the correct scale values.

Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com>
Reported-by: Jagath Jog J <jagathjog1996@gmail.com>
Fixes: 7c1d1677b322 ("iio: accel: Support Kionix/ROHM KX022A accelerometer")
Tested-by: Jagath Jog J <jagathjog1996@gmail.com>
Link: https://lore.kernel.org/r/ZTEt7NqfDHPOkm8j@dc78bmyyyyyyyyyyyyydt-3.rev.dnainternet.fi
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/iio/accel/kionix-kx022a.c

index 4ea3c67..971fc60 100644 (file)
@@ -273,17 +273,17 @@ static const unsigned int kx022a_odrs[] = {
  *     (range / 2^bits) * g = (range / 2^bits) * 9.80665 m/s^2
  *     => KX022A uses 16 bit (HiRes mode - assume the low 8 bits are zeroed
  *     in low-power mode(?) )
- *     => +/-2G  => 4 / 2^16 * 9,80665 * 10^6 (to scale to micro)
- *     => +/-2G  - 598.550415
- *        +/-4G  - 1197.10083
- *        +/-8G  - 2394.20166
- *        +/-16G - 4788.40332
+ *     => +/-2G  => 4 / 2^16 * 9,80665
+ *     => +/-2G  - 0.000598550415
+ *        +/-4G  - 0.00119710083
+ *        +/-8G  - 0.00239420166
+ *        +/-16G - 0.00478840332
  */
 static const int kx022a_scale_table[][2] = {
-       { 598, 550415 },
-       { 1197, 100830 },
-       { 2394, 201660 },
-       { 4788, 403320 },
+       { 0, 598550 },
+       { 0, 1197101 },
+       { 0, 2394202 },
+       { 0, 4788403 },
 };
 
 static int kx022a_read_avail(struct iio_dev *indio_dev,
@@ -302,7 +302,7 @@ static int kx022a_read_avail(struct iio_dev *indio_dev,
                *vals = (const int *)kx022a_scale_table;
                *length = ARRAY_SIZE(kx022a_scale_table) *
                          ARRAY_SIZE(kx022a_scale_table[0]);
-               *type = IIO_VAL_INT_PLUS_MICRO;
+               *type = IIO_VAL_INT_PLUS_NANO;
                return IIO_AVAIL_LIST;
        default:
                return -EINVAL;
@@ -366,6 +366,20 @@ static int kx022a_turn_on_unlock(struct kx022a_data *data)
        return ret;
 }
 
+static int kx022a_write_raw_get_fmt(struct iio_dev *idev,
+                                   struct iio_chan_spec const *chan,
+                                   long mask)
+{
+       switch (mask) {
+       case IIO_CHAN_INFO_SCALE:
+               return IIO_VAL_INT_PLUS_NANO;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               return IIO_VAL_INT_PLUS_MICRO;
+       default:
+               return -EINVAL;
+       }
+}
+
 static int kx022a_write_raw(struct iio_dev *idev,
                            struct iio_chan_spec const *chan,
                            int val, int val2, long mask)
@@ -510,7 +524,7 @@ static int kx022a_read_raw(struct iio_dev *idev,
 
                kx022a_reg2scale(regval, val, val2);
 
-               return IIO_VAL_INT_PLUS_MICRO;
+               return IIO_VAL_INT_PLUS_NANO;
        }
 
        return -EINVAL;
@@ -712,6 +726,7 @@ static int kx022a_fifo_flush(struct iio_dev *idev, unsigned int samples)
 static const struct iio_info kx022a_info = {
        .read_raw = &kx022a_read_raw,
        .write_raw = &kx022a_write_raw,
+       .write_raw_get_fmt = &kx022a_write_raw_get_fmt,
        .read_avail = &kx022a_read_avail,
 
        .validate_trigger       = iio_validate_own_trigger,