iio: accel: mxc4005: Read orientation matrix from ACPI ROTM method
authorHans de Goede <hdegoede@redhat.com>
Thu, 25 Apr 2024 12:57:54 +0000 (14:57 +0200)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Mon, 29 Apr 2024 19:53:25 +0000 (20:53 +0100)
Some devices use the semi-standard ACPI "ROTM" method to store
the accelerometers orientation matrix.

Add support for this using the new iio_read_acpi_mount_matrix() helper, if
the helper fails to read the matrix fall back to iio_read_mount_matrix()
which will try to get it from device-properties (devicetree) and if
that fails it will fill the matrix with the identity matrix.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=218578
Acked-by: Rafael J. Wysocki <rafael@kernel.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20240425125754.76010-5-hdegoede@redhat.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/accel/mxc4005.c

index 61839be501c21a023790c15c40f55a48cd8d3da3..34d0f7f3f664a375de14cc308c2fb9b790857904 100644 (file)
@@ -56,6 +56,7 @@ struct mxc4005_data {
        struct mutex mutex;
        struct regmap *regmap;
        struct iio_trigger *dready_trig;
+       struct iio_mount_matrix orientation;
        /* Ensure timestamp is naturally aligned */
        struct {
                __be16 chans[3];
@@ -259,6 +260,20 @@ static int mxc4005_write_raw(struct iio_dev *indio_dev,
        }
 }
 
+static const struct iio_mount_matrix *
+mxc4005_get_mount_matrix(const struct iio_dev *indio_dev,
+                          const struct iio_chan_spec *chan)
+{
+       struct mxc4005_data *data = iio_priv(indio_dev);
+
+       return &data->orientation;
+}
+
+static const struct iio_chan_spec_ext_info mxc4005_ext_info[] = {
+       IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, mxc4005_get_mount_matrix),
+       { }
+};
+
 static const struct iio_info mxc4005_info = {
        .read_raw       = mxc4005_read_raw,
        .write_raw      = mxc4005_write_raw,
@@ -285,6 +300,7 @@ static const unsigned long mxc4005_scan_masks[] = {
                .shift = 4,                                     \
                .endianness = IIO_BE,                           \
        },                                                      \
+       .ext_info = mxc4005_ext_info,                           \
 }
 
 static const struct iio_chan_spec mxc4005_channels[] = {
@@ -415,6 +431,12 @@ static int mxc4005_probe(struct i2c_client *client)
 
        mutex_init(&data->mutex);
 
+       if (!iio_read_acpi_mount_matrix(&client->dev, &data->orientation, "ROTM")) {
+               ret = iio_read_mount_matrix(&client->dev, &data->orientation);
+               if (ret)
+                       return ret;
+       }
+
        indio_dev->channels = mxc4005_channels;
        indio_dev->num_channels = ARRAY_SIZE(mxc4005_channels);
        indio_dev->available_scan_masks = mxc4005_scan_masks;