Re: [PATCH] iio: accel: st_sensors: Support generic mounting matrix

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, May 15, 2021 at 6:17 AM Linus Walleij <linus.walleij@xxxxxxxxxx> wrote:
>
> The ST accelerators support a special type of quirky
> mounting matrix found in ACPI systems, but not a generic
> mounting matrix such as from the device tree.
>
> Augment the ACPI hack to be a bit more generic and
> accept a mounting matrix from device properties.
>
> This makes it possible to fix orientation on the Ux500
> HREF device.

I think this entire thread may be interesting to Hans, hence Cc him.


> Cc: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
> Cc: Denis Ciocca <denis.ciocca@xxxxxx>
> Cc: Daniel Drake <drake@xxxxxxxxxxxx>
> Signed-off-by: Linus Walleij <linus.walleij@xxxxxxxxxx>
> ---
>  drivers/iio/accel/st_accel_core.c | 51 ++++++++++++++++++++-----------
>  1 file changed, 34 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
> index 43c50167d220..cfbcf740e3cb 100644
> --- a/drivers/iio/accel/st_accel_core.c
> +++ b/drivers/iio/accel/st_accel_core.c
> @@ -1069,26 +1069,25 @@ static const struct iio_trigger_ops st_accel_trigger_ops = {
>  #define ST_ACCEL_TRIGGER_OPS NULL
>  #endif
>
> -#ifdef CONFIG_ACPI
>  static const struct iio_mount_matrix *
> -get_mount_matrix(const struct iio_dev *indio_dev,
> -                const struct iio_chan_spec *chan)
> +st_accel_get_mount_matrix(const struct iio_dev *indio_dev,
> +                         const struct iio_chan_spec *chan)
>  {
>         struct st_sensor_data *adata = iio_priv(indio_dev);
>
>         return adata->mount_matrix;
>  }
>
> -static const struct iio_chan_spec_ext_info mount_matrix_ext_info[] = {
> -       IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, get_mount_matrix),
> +static const struct iio_chan_spec_ext_info st_accel_mount_matrix_ext_info[] = {
> +       IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, st_accel_get_mount_matrix),
>         { },
>  };
>
> +#ifdef CONFIG_ACPI
>  /* Read ST-specific _ONT orientation data from ACPI and generate an
>   * appropriate mount matrix.
>   */
> -static int apply_acpi_orientation(struct iio_dev *indio_dev,
> -                                 struct iio_chan_spec *channels)
> +static int apply_acpi_orientation(struct iio_dev *indio_dev)
>  {
>         struct st_sensor_data *adata = iio_priv(indio_dev);
>         struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
> @@ -1207,22 +1206,20 @@ static int apply_acpi_orientation(struct iio_dev *indio_dev,
>                 }
>         }
>
> -       /* Expose the mount matrix via ext_info */
> -       for (i = 0; i < indio_dev->num_channels; i++)
> -               channels[i].ext_info = mount_matrix_ext_info;
> -
>         ret = 0;
>         dev_info(&indio_dev->dev, "computed mount matrix from ACPI\n");
>
>  out:
>         kfree(buffer.pointer);
> +       dev_warn(&indio_dev->dev,
> +                "failed to apply ACPI orientation data: %d\n", ret);
> +
>         return ret;
>  }
>  #else /* !CONFIG_ACPI */
> -static int apply_acpi_orientation(struct iio_dev *indio_dev,
> -                                 struct iio_chan_spec *channels)
> +static int apply_acpi_orientation(struct iio_dev *indio_dev)
>  {
> -       return 0;
> +       return -EINVAL;
>  }
>  #endif
>
> @@ -1251,6 +1248,7 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
>         struct iio_chan_spec *channels;
>         size_t channels_size;
>         int err;
> +       int i;
>
>         indio_dev->modes = INDIO_DIRECT_MODE;
>         indio_dev->info = &accel_info;
> @@ -1275,9 +1273,28 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
>                 goto st_accel_power_off;
>         }
>
> -       if (apply_acpi_orientation(indio_dev, channels))
> -               dev_warn(&indio_dev->dev,
> -                        "failed to apply ACPI orientation data: %d\n", err);
> +       /* First try ACPI orientation then try the generic function */
> +       err = apply_acpi_orientation(indio_dev);
> +       if (err) {
> +               adata->mount_matrix = devm_kmalloc(&indio_dev->dev,
> +                                                  sizeof(*adata->mount_matrix),
> +                                                  GFP_KERNEL);
> +               if (!adata->mount_matrix) {
> +                       err = -ENOMEM;
> +                       goto st_accel_power_off;
> +               }
> +
> +               err = iio_read_mount_matrix(adata->dev, "mount-matrix",
> +                                           adata->mount_matrix);
> +               if (err)
> +                       goto st_accel_power_off;
> +       }
> +       /*
> +        * We have at least an identity matrix, so expose the mount
> +        * matrix via ext_info
> +        */
> +       for (i = 0; i < indio_dev->num_channels; i++)
> +               channels[i].ext_info = st_accel_mount_matrix_ext_info;
>
>         indio_dev->channels = channels;
>         adata->current_fullscale = &adata->sensor_settings->fs.fs_avl[0];
> --
> 2.31.1
>


-- 
With Best Regards,
Andy Shevchenko



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux