Here's the device info: ** Model information sys_vendor: LENOVO product_name: 82AT product_version: IdeaPad Duet 3 10IGL5 chassis_vendor: LENOVO chassis_version: IdeaPad Duet 3 10IGL5 bios_vendor: LENOVO bios_version: EQCN35WW board_vendor: LENOVO board_name: LNVNB161216 board_version: SDK0R32802 WIN I'll try to adapt the full patches to my Debian 6.1 source for testing, and report back to you. Darrell On Mon, 30 Jan 2023 at 19:56, Jonathan Cameron <jic23@xxxxxxxxxx> wrote: > > From: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx> > > DSDT ROTM method seen in the wild with SMO8B30 _HID. > Making assumption it is similar to that used for bmc150 plus > information from Darrell that the rotation is out by 90 degrees at boot. > > Method (ROTM, 0, NotSerialized) > { > Name (RBUF, Package (0x03) > { > "0 -1 0", > "1 0 0", > "0 0 1" > }) > Return (RBUF) /* \_SB_.PCI0.I2C5.DEV_.ROTM.RBUF */ > } > > Reported-by: Darrell Kavanagh <darrell.kavanagh@xxxxxxxxx> > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx> > > --- > Untested. Fingers crossed. > > We could factor this out if it keeps turning up. The bmc150 varient > is more complex as multiple method IDs exist depending on the configuration. > > --- > drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 65 +++++++++++++++++++- > 1 file changed, 62 insertions(+), 3 deletions(-) > > diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c > index 3f6060c64f32..3c2d67f8d9b7 100644 > --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c > +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c > @@ -56,6 +56,7 @@ > > #include <linux/kernel.h> > #include <linux/module.h> > +#include <linux/acpi.h> > #include <linux/delay.h> > #include <linux/iio/events.h> > #include <linux/iio/iio.h> > @@ -2602,6 +2603,61 @@ static int st_lsm6dsx_init_regulators(struct device *dev) > return 0; > } > > +static bool lsm6dsx_get_acpi_mount_matrix(struct device *dev, > + struct iio_mount_matrix *orientation) > +{ > + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; > + struct acpi_device *adev = ACPI_COMPANION(dev); > + union acpi_object *obj, *elements; > + acpi_status status; > + int i, j, val[3]; > + char *str; > + > + if (!has_acpi_companion(dev)) > + return -EINVAL; > + > + if (!acpi_has_method(adev->handle, "ROTM")) > + return -EINVAL; > + > + status = acpi_evaluate_object(adev->handle, "ROTM", NULL, &buffer); > + if (ACPI_FAILURE(status)) { > + dev_warn(dev, "Failed to get ACPI mount matrix: %d\n", status); > + return -EINVAL; > + } > + > + obj = buffer.pointer; > + if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 3) > + goto unknown_format; > + > + elements = obj->package.elements; > + for (i = 0; i < 3; i++) { > + if (elements[i].type != ACPI_TYPE_STRING) > + goto unknown_format; > + > + str = elements[i].string.pointer; > + if (sscanf(str, "%d %d %d", &val[0], &val[1], &val[2]) != 3) > + goto unknown_format; > + > + for (j = 0; j < 3; j++) { > + switch (val[j]) { > + case -1: str = "-1"; break; > + case 0: str = "0"; break; > + case 1: str = "1"; break; > + default: goto unknown_format; > + } > + orientation->rotation[i * 3 + j] = str; > + } > + } > + > + kfree(buffer.pointer); > + return 0; > + > +unknown_format: > + dev_warn(dev, "Unknown ACPI mount matrix format, ignoring\n"); > + kfree(buffer.pointer); > + return -EINVAL; > +} > + > int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, > struct regmap *regmap) > { > @@ -2676,9 +2732,12 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, > return err; > } > > - err = iio_read_mount_matrix(hw->dev, &hw->orientation); > - if (err) > - return err; > + err = lsm6dsx_get_acpi_mount_matrix(hw->dev, &hw->orientation); > + if (err) { > + err = iio_read_mount_matrix(hw->dev, &hw->orientation); > + if (err) > + return err; > + } > > for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { > if (!hw->iio_devs[i]) > -- > 2.39.1 >