Message ID | 20201125083618.10989-4-hdegoede@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/3] iio: accel: bmc150: Removed unused bmc150_accel_dat irq member | expand |
On Wed, Nov 25, 2020 at 10:37 AM Hans de Goede <hdegoede@redhat.com> wrote: > > bmc150 accelerometers with an ACPI hardware-id of BOSC0200 have an ACPI > method providing their mount-matrix, add support for retrieving this. ... > + if (strcmp(dev_name(dev), "i2c-BOSC0200:base") == 0) > + alt_name = "ROMK"; > + else > + alt_name = "ROMS"; > + > + if (acpi_has_method(adev->handle, "ROTM")) > + name = "ROTM"; My gosh, it's a third method of this... ... > + 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; > + } > + } I'm wondering if we can come up with some common code out of this and existing apply_acpi_orientation().
Hi, On 11/25/20 12:07 PM, Andy Shevchenko wrote: > On Wed, Nov 25, 2020 at 10:37 AM Hans de Goede <hdegoede@redhat.com> wrote: >> >> bmc150 accelerometers with an ACPI hardware-id of BOSC0200 have an ACPI >> method providing their mount-matrix, add support for retrieving this. > > ... > >> + if (strcmp(dev_name(dev), "i2c-BOSC0200:base") == 0) >> + alt_name = "ROMK"; >> + else >> + alt_name = "ROMS"; >> + >> + if (acpi_has_method(adev->handle, "ROTM")) >> + name = "ROTM"; > > My gosh, it's a third method of this... > > ... > >> + 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; >> + } >> + } > > I'm wondering if we can come up with some common code out of this and > existing apply_acpi_orientation(). Honestly they are all different enough that I don't think it is worth the trouble (I did take a look at this, but it did not seem feasible without creating horrible code). Regards, Hans
On Wed, Nov 25, 2020 at 1:12 PM Hans de Goede <hdegoede@redhat.com> wrote: > On 11/25/20 12:07 PM, Andy Shevchenko wrote: > > On Wed, Nov 25, 2020 at 10:37 AM Hans de Goede <hdegoede@redhat.com> wrote: ... > > I'm wondering if we can come up with some common code out of this and > > existing apply_acpi_orientation(). > > Honestly they are all different enough that I don't think it is worth > the trouble (I did take a look at this, but it did not seem feasible > without creating horrible code). Okay!
diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c index 2976aefad89b..2ce65d509f93 100644 --- a/drivers/iio/accel/bmc150-accel-core.c +++ b/drivers/iio/accel/bmc150-accel-core.c @@ -410,6 +410,78 @@ static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on) } #endif +#ifdef CONFIG_ACPI +static bool bmc150_apply_acpi_orientation(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; + char *name, *alt_name, *str; + acpi_status status; + int i, j, val[3]; + + if (!adev || !acpi_dev_hid_uid_match(adev, "BOSC0200", NULL)) + return false; + + if (strcmp(dev_name(dev), "i2c-BOSC0200:base") == 0) + alt_name = "ROMK"; + else + alt_name = "ROMS"; + + if (acpi_has_method(adev->handle, "ROTM")) + name = "ROTM"; + else if (acpi_has_method(adev->handle, alt_name)) + name = alt_name; + else + return false; + + status = acpi_evaluate_object(adev->handle, name, NULL, &buffer); + if (ACPI_FAILURE(status)) { + dev_warn(dev, "Failed to get ACPI mount matrix: %d\n", status); + return false; + } + + 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 true; + +unknown_format: + dev_warn(dev, "Unknown ACPI mount matrix format, ignoring\n"); + kfree(buffer.pointer); + return false; +} +#else +static bool bmc150_apply_acpi_orientation(struct device *dev, + struct iio_mount_matrix *orientation) +{ + return false; +} +#endif + static const struct bmc150_accel_interrupt_info { u8 map_reg; u8 map_bitmask; @@ -1571,10 +1643,12 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq, data->regmap = regmap; - ret = iio_read_mount_matrix(dev, "mount-matrix", - &data->orientation); - if (ret) - return ret; + if (!bmc150_apply_acpi_orientation(dev, &data->orientation)) { + ret = iio_read_mount_matrix(dev, "mount-matrix", + &data->orientation); + if (ret) + return ret; + } ret = bmc150_accel_chip_init(data); if (ret < 0)
bmc150 accelerometers with an ACPI hardware-id of BOSC0200 have an ACPI method providing their mount-matrix, add support for retrieving this. Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/iio/accel/bmc150-accel-core.c | 82 +++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 4 deletions(-)