platform/x86: int3472/discrete: Get the polarity from the _DSM entry

According to:
https://github.com/intel/ipu6-drivers/blob/master/patch/int3472-support-independent-clock-and-LED-gpios-5.17%2B.patch

Bits 31-24 of the _DSM pin entry integer value codes the active-value,
that is the actual physical signal (0 or 1) which needs to be output on
the pin to turn the sensor chip on (to make it active).

So if bits 31-24 are 0 for a reset pin, then the actual value of the reset
pin needs to be 0 to take the chip out of reset. IOW in this case the reset
signal is active-high rather then the default active-low.

And if bits 31-24 are 0 for a clk-en pin then the actual value of the clk
pin needs to be 0 to enable the clk. So in this case the clk-en signal
is active-low rather then the default active-high.

IOW if bits 31-24 are 0 for a pin, then the default polarity of the pin
is inverted.

Add a check for this and also propagate this new polarity to the clock
registration.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Link: https://lore.kernel.org/r/20230127203729.10205-6-hdegoede@redhat.com
This commit is contained in:
Hans de Goede 2023-01-27 21:37:29 +01:00
parent 8cf0e541c1
commit 7a88de319c
3 changed files with 16 additions and 4 deletions

View File

@ -87,7 +87,7 @@ static const struct clk_ops skl_int3472_clock_ops = {
};
int skl_int3472_register_clock(struct int3472_discrete_device *int3472,
struct acpi_resource_gpio *agpio)
struct acpi_resource_gpio *agpio, u32 polarity)
{
char *path = agpio->resource_source.string_ptr;
struct clk_init_data init = {
@ -105,6 +105,9 @@ int skl_int3472_register_clock(struct int3472_discrete_device *int3472,
return dev_err_probe(int3472->dev, PTR_ERR(int3472->clock.ena_gpio),
"getting clk-enable GPIO\n");
if (polarity == GPIO_ACTIVE_LOW)
gpiod_toggle_active_low(int3472->clock.ena_gpio);
/* Ensure the pin is in output mode and non-active state */
gpiod_direction_output(int3472->clock.ena_gpio, 0);

View File

@ -122,7 +122,7 @@ int skl_int3472_get_sensor_adev_and_name(struct device *dev,
const char **name_ret);
int skl_int3472_register_clock(struct int3472_discrete_device *int3472,
struct acpi_resource_gpio *agpio);
struct acpi_resource_gpio *agpio, u32 polarity);
void skl_int3472_unregister_clock(struct int3472_discrete_device *int3472);
int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,

View File

@ -220,11 +220,11 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,
struct int3472_discrete_device *int3472 = data;
struct acpi_resource_gpio *agpio;
union acpi_object *obj;
u8 active_value, type;
const char *err_msg;
const char *func;
u32 polarity;
int ret;
u8 type;
if (!acpi_gpio_get_io_resource(ares, &agpio))
return 1;
@ -248,6 +248,15 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,
int3472_get_func_and_polarity(type, &func, &polarity);
/* If bits 31-24 of the _DSM entry are all 0 then the signal is inverted */
active_value = obj->integer.value >> 24;
if (!active_value)
polarity ^= GPIO_ACTIVE_LOW;
dev_dbg(int3472->dev, "%s %s pin %d active-%s\n", func,
agpio->resource_source.string_ptr, agpio->pin_table[0],
(polarity == GPIO_ACTIVE_HIGH) ? "high" : "low");
switch (type) {
case INT3472_GPIO_TYPE_RESET:
case INT3472_GPIO_TYPE_POWERDOWN:
@ -257,7 +266,7 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,
break;
case INT3472_GPIO_TYPE_CLK_ENABLE:
ret = skl_int3472_register_clock(int3472, agpio);
ret = skl_int3472_register_clock(int3472, agpio, polarity);
if (ret)
err_msg = "Failed to register clock\n";