Message ID | 20250207134126.1769183-3-sakari.ailus@linux.intel.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | int3472: Support GPIO con_id based on _HID | expand |
On Fri, Feb 07, 2025 at 03:41:25PM +0200, Sakari Ailus wrote: > The DT bindings for ov7251 specify "enable" GPIO (xshutdown in > documentation) but the int3472 indiscriminately provides this as a "reset" > GPIO to sensor drivers. Take this into account by assigning it as "enable" > with active high polarity for INT347E devices, i.e. ov7251. "reset" with > active low polarity remains the default GPIO name for other devices. ... > +static const struct int3472_gpio_map int3472_gpio_map[] = { > + { "INT347E", INT3472_GPIO_TYPE_RESET, INT3472_GPIO_TYPE_RESET, false, "enable" }, > +}; > + > +static void int3472_get_func_and_polarity(struct acpi_device *adev, u8 *type, > + const char **func, unsigned long *gpio_flags) > { > - switch (type) { > + unsigned int i; > + > + for (i = 0; i < ARRAY_SIZE(int3472_gpio_map); i++) { > + /* > + * Map the firmware-provided GPIO to whatever a driver expects > + * (as in DT bindings). First check if the requested GPIO name What name? > + * matches the GPIO map, then see that the device _HID matches. > + */ > + if (*type != int3472_gpio_map[i].type_from) > + continue; > + > + if (!acpi_dev_hid_uid_match(adev, int3472_gpio_map[i].hid, NULL)) > + continue; I still think this is unusual and confusing order of checks. At the end, it is up to the PDx86 maintainers. > + *type = int3472_gpio_map[i].type_to; > + *gpio_flags = int3472_gpio_map[i].polarity_low ? > + GPIO_ACTIVE_LOW : GPIO_ACTIVE_HIGH; > + *func = int3472_gpio_map[i].func; > + return; > + }
Hi Andy, On Fri, Feb 07, 2025 at 05:30:40PM +0200, Andy Shevchenko wrote: > On Fri, Feb 07, 2025 at 03:41:25PM +0200, Sakari Ailus wrote: > > The DT bindings for ov7251 specify "enable" GPIO (xshutdown in > > documentation) but the int3472 indiscriminately provides this as a "reset" > > GPIO to sensor drivers. Take this into account by assigning it as "enable" > > with active high polarity for INT347E devices, i.e. ov7251. "reset" with > > active low polarity remains the default GPIO name for other devices. > > ... > > > +static const struct int3472_gpio_map int3472_gpio_map[] = { > > + { "INT347E", INT3472_GPIO_TYPE_RESET, INT3472_GPIO_TYPE_RESET, false, "enable" }, > > +}; > > + > > +static void int3472_get_func_and_polarity(struct acpi_device *adev, u8 *type, > > + const char **func, unsigned long *gpio_flags) > > { > > - switch (type) { > > + unsigned int i; > > + > > + for (i = 0; i < ARRAY_SIZE(int3472_gpio_map); i++) { > > + /* > > + * Map the firmware-provided GPIO to whatever a driver expects > > + * (as in DT bindings). First check if the requested GPIO name > > What name? Right, I was accidentally thinking of a driver here. How about: Map the firmware-provided GPIO type to whatever a driver expects (as in DT bindings). First check if the type matches with the GPIO map, then further check that the device _HID matches. > > > + * matches the GPIO map, then see that the device _HID matches. > > + */ > > + if (*type != int3472_gpio_map[i].type_from) > > + continue; > > + > > + if (!acpi_dev_hid_uid_match(adev, int3472_gpio_map[i].hid, NULL)) > > + continue; > > I still think this is unusual and confusing order of checks. > > At the end, it is up to the PDx86 maintainers. > > > + *type = int3472_gpio_map[i].type_to; > > + *gpio_flags = int3472_gpio_map[i].polarity_low ? > > + GPIO_ACTIVE_LOW : GPIO_ACTIVE_HIGH; > > + *func = int3472_gpio_map[i].func; > > + return; > > + } >
diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c index b891b064fbf7..c70404afefc0 100644 --- a/drivers/platform/x86/intel/int3472/discrete.c +++ b/drivers/platform/x86/intel/int3472/discrete.c @@ -2,6 +2,7 @@ /* Author: Dan Scally <djrscally@gmail.com> */ #include <linux/acpi.h> +#include <linux/array_size.h> #include <linux/bitfield.h> #include <linux/device.h> #include <linux/gpio/consumer.h> @@ -122,10 +123,53 @@ skl_int3472_gpiod_get_from_temp_lookup(struct int3472_discrete_device *int3472, return desc; } -static void int3472_get_func_and_polarity(u8 type, const char **func, - unsigned long *gpio_flags) +/** + * struct int3472_gpio_map - Map GPIOs to whatever is expected by the + * sensor driver (as in DT bindings) + * @hid: The ACPI HID of the device without the instance number e.g. INT347E + * @type_from: The GPIO type from ACPI ?SDT + * @type_to: The assigned GPIO type, typically same as @type_from + * @func: The function, e.g. "enable" + * @polarity_low: GPIO_ACTIVE_LOW true if the @polarity_low is true, + * GPIO_ACTIVE_HIGH otherwise + */ +struct int3472_gpio_map { + const char *hid; + u8 type_from; + u8 type_to; + bool polarity_low; + const char *func; +}; + +static const struct int3472_gpio_map int3472_gpio_map[] = { + { "INT347E", INT3472_GPIO_TYPE_RESET, INT3472_GPIO_TYPE_RESET, false, "enable" }, +}; + +static void int3472_get_func_and_polarity(struct acpi_device *adev, u8 *type, + const char **func, unsigned long *gpio_flags) { - switch (type) { + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(int3472_gpio_map); i++) { + /* + * Map the firmware-provided GPIO to whatever a driver expects + * (as in DT bindings). First check if the requested GPIO name + * matches the GPIO map, then see that the device _HID matches. + */ + if (*type != int3472_gpio_map[i].type_from) + continue; + + if (!acpi_dev_hid_uid_match(adev, int3472_gpio_map[i].hid, NULL)) + continue; + + *type = int3472_gpio_map[i].type_to; + *gpio_flags = int3472_gpio_map[i].polarity_low ? + GPIO_ACTIVE_LOW : GPIO_ACTIVE_HIGH; + *func = int3472_gpio_map[i].func; + return; + } + + switch (*type) { case INT3472_GPIO_TYPE_RESET: *func = "reset"; *gpio_flags = GPIO_ACTIVE_LOW; @@ -218,7 +262,7 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares, type = FIELD_GET(INT3472_GPIO_DSM_TYPE, obj->integer.value); - int3472_get_func_and_polarity(type, &func, &gpio_flags); + int3472_get_func_and_polarity(int3472->sensor, &type, &func, &gpio_flags); pin = FIELD_GET(INT3472_GPIO_DSM_PIN, obj->integer.value); /* Pin field is not really used under Windows and wraps around at 8 bits */