staging: iio: resolver: ad2s1210: implement IIO_CHAN_INFO_SCALE
authorDavid Lechner <dlechner@baylibre.com>
Fri, 29 Sep 2023 17:23:13 +0000 (12:23 -0500)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Sat, 30 Sep 2023 14:42:32 +0000 (15:42 +0100)
This adds an implementation of IIO_CHAN_INFO_SCALE to the ad2s1210
resolver driver. This allows userspace to get the scale factor for the
raw values.

Signed-off-by: David Lechner <dlechner@baylibre.com>
Link: https://lore.kernel.org/r/20230929-ad2s1210-mainline-v3-8-fa4364281745@baylibre.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/staging/iio/resolver/ad2s1210.c

index f9774dff2df4df5d27bcc01945e60ce59968483d..a710598a64f0728931600b5eb38610b9c7b69469 100644 (file)
@@ -461,13 +461,10 @@ error_ret:
        return ret < 0 ? ret : len;
 }
 
-static int ad2s1210_read_raw(struct iio_dev *indio_dev,
-                            struct iio_chan_spec const *chan,
-                            int *val,
-                            int *val2,
-                            long m)
+static int ad2s1210_single_conversion(struct ad2s1210_state *st,
+                                     struct iio_chan_spec const *chan,
+                                     int *val)
 {
-       struct ad2s1210_state *st = iio_priv(indio_dev);
        int ret = 0;
 
        mutex_lock(&st->lock);
@@ -514,6 +511,44 @@ error_ret:
        return ret;
 }
 
+static const int ad2s1210_velocity_scale[] = {
+       17089132, /* 8.192MHz / (2*pi * 2500 / 2^15) */
+       42722830, /* 8.192MHz / (2*pi * 1000 / 2^15) */
+       85445659, /* 8.192MHz / (2*pi * 500 / 2^15) */
+       341782638, /* 8.192MHz / (2*pi * 125 / 2^15) */
+};
+
+static int ad2s1210_read_raw(struct iio_dev *indio_dev,
+                            struct iio_chan_spec const *chan,
+                            int *val,
+                            int *val2,
+                            long mask)
+{
+       struct ad2s1210_state *st = iio_priv(indio_dev);
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               return ad2s1210_single_conversion(st, chan, val);
+       case IIO_CHAN_INFO_SCALE:
+               switch (chan->type) {
+               case IIO_ANGL:
+                       /* approx 0.3 arc min converted to radians */
+                       *val = 0;
+                       *val2 = 95874;
+                       return IIO_VAL_INT_PLUS_NANO;
+               case IIO_ANGL_VEL:
+                       *val = st->fclkin;
+                       *val2 = ad2s1210_velocity_scale[st->resolution];
+                       return IIO_VAL_FRACTIONAL;
+               default:
+                       return -EINVAL;
+               }
+
+       default:
+               return -EINVAL;
+       }
+}
+
 static IIO_DEVICE_ATTR(fclkin, 0644,
                       ad2s1210_show_fclkin, ad2s1210_store_fclkin, 0);
 static IIO_DEVICE_ATTR(fexcit, 0644,
@@ -552,12 +587,14 @@ static const struct iio_chan_spec ad2s1210_channels[] = {
                .type = IIO_ANGL,
                .indexed = 1,
                .channel = 0,
-               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+                                     BIT(IIO_CHAN_INFO_SCALE),
        }, {
                .type = IIO_ANGL_VEL,
                .indexed = 1,
                .channel = 0,
-               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+                                     BIT(IIO_CHAN_INFO_SCALE),
        }
 };