platform/x86: int3472: Rework AVDD second sensor quirk handling
authorHans de Goede <hdegoede@redhat.com>
Thu, 17 Apr 2025 11:13:32 +0000 (13:13 +0200)
committerIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Thu, 24 Apr 2025 13:05:34 +0000 (16:05 +0300)
Rework the discrete quirk handling to use a quirks struct which is
pointed to by a dmi_system_id table, rather then having a dmi_system_id
table per type of quirk.

This is a preparation patch for adding support for multiple regulators,
where not all regulators might be shared between sensors.

Reviewed-by: Andy Shevchenko <andy@kernel.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Tested-by: David Heidelberg <david@ixit.cz> # Dell Latitude 9440
Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Link: https://lore.kernel.org/r/20250417111337.38142-5-hdegoede@redhat.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
drivers/platform/x86/intel/int3472/Makefile
drivers/platform/x86/intel/int3472/clk_and_regulator.c
drivers/platform/x86/intel/int3472/common.h
drivers/platform/x86/intel/int3472/discrete.c
drivers/platform/x86/intel/int3472/discrete_quirks.c [new file with mode: 0644]

index a8aba07..103661e 100644 (file)
@@ -1,7 +1,8 @@
 obj-$(CONFIG_INTEL_SKL_INT3472)                += intel_skl_int3472_discrete.o \
                                           intel_skl_int3472_tps68470.o \
                                           intel_skl_int3472_common.o
-intel_skl_int3472_discrete-y           := discrete.o clk_and_regulator.o led.o
+intel_skl_int3472_discrete-y           := discrete.o discrete_quirks.o \
+                                          clk_and_regulator.o led.o
 intel_skl_int3472_tps68470-y           := tps68470.o tps68470_board_data.o
 
 intel_skl_int3472_common-y             += common.o
index 5f6c662..374a99d 100644 (file)
@@ -5,7 +5,6 @@
 #include <linux/clkdev.h>
 #include <linux/clk-provider.h>
 #include <linux/device.h>
-#include <linux/dmi.h>
 #include <linux/gpio/consumer.h>
 #include <linux/regulator/driver.h>
 #include <linux/slab.h>
@@ -205,37 +204,14 @@ static const char * const skl_int3472_regulator_map_supplies[] = {
 static_assert(ARRAY_SIZE(skl_int3472_regulator_map_supplies) ==
              GPIO_REGULATOR_SUPPLY_MAP_COUNT);
 
-/*
- * On some models there is a single GPIO regulator which is shared between
- * sensors and only listed in the ACPI resources of one sensor.
- * This DMI table contains the name of the second sensor. This is used to add
- * entries for the second sensor to the supply_map.
- */
-static const struct dmi_system_id skl_int3472_regulator_second_sensor[] = {
-       {
-               /* Lenovo Miix 510-12IKB */
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                       DMI_MATCH(DMI_PRODUCT_VERSION, "MIIX 510-12IKB"),
-               },
-               .driver_data = "i2c-OVTI2680:00",
-       },
-       { }
-};
-
 int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
-                                  struct gpio_desc *gpio)
+                                  struct gpio_desc *gpio,
+                                  const char *second_sensor)
 {
        struct regulator_init_data init_data = { };
        struct regulator_config cfg = { };
-       const char *second_sensor = NULL;
-       const struct dmi_system_id *id;
        int i, j;
 
-       id = dmi_first_match(skl_int3472_regulator_second_sensor);
-       if (id)
-               second_sensor = id->driver_data;
-
        for (i = 0, j = 0; i < ARRAY_SIZE(skl_int3472_regulator_map_supplies); i++) {
                int3472->regulator.supply_map[j].supply = skl_int3472_regulator_map_supplies[i];
                int3472->regulator.supply_map[j].dev_name = int3472->sensor_name;
index e0fa34b..3728f38 100644 (file)
@@ -48,6 +48,7 @@
        container_of(clk, struct int3472_discrete_device, clock)
 
 struct acpi_device;
+struct dmi_system_id;
 struct i2c_client;
 struct platform_device;
 
@@ -68,6 +69,11 @@ struct int3472_cldb {
        u8 reserved2[17];
 };
 
+struct int3472_discrete_quirks {
+       /* For models where AVDD GPIO is shared between sensors */
+       const char *avdd_second_sensor;
+};
+
 struct int3472_discrete_device {
        struct acpi_device *adev;
        struct device *dev;
@@ -100,11 +106,15 @@ struct int3472_discrete_device {
                struct gpio_desc *gpio;
        } pled;
 
+       struct int3472_discrete_quirks quirks;
+
        unsigned int ngpios; /* how many GPIOs have we seen */
        unsigned int n_sensor_gpios; /* how many have we mapped to sensor */
        struct gpiod_lookup_table gpios;
 };
 
+extern const struct dmi_system_id skl_int3472_discrete_quirks[];
+
 union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev,
                                               char *id);
 int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb);
@@ -118,7 +128,8 @@ int skl_int3472_register_dsm_clock(struct int3472_discrete_device *int3472);
 void skl_int3472_unregister_clock(struct int3472_discrete_device *int3472);
 
 int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
-                                  struct gpio_desc *gpio);
+                                  struct gpio_desc *gpio,
+                                  const char *second_sensor);
 void skl_int3472_unregister_regulator(struct int3472_discrete_device *int3472);
 
 int skl_int3472_register_pled(struct int3472_discrete_device *int3472, struct gpio_desc *gpio);
index 30ff8f3..cbf3945 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/array_size.h>
 #include <linux/bitfield.h>
 #include <linux/device.h>
+#include <linux/dmi.h>
 #include <linux/gpio/consumer.h>
 #include <linux/gpio/machine.h>
 #include <linux/i2c.h>
@@ -310,7 +311,8 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,
 
                        break;
                case INT3472_GPIO_TYPE_POWER_ENABLE:
-                       ret = skl_int3472_register_regulator(int3472, gpio);
+                       ret = skl_int3472_register_regulator(int3472, gpio,
+                                                            int3472->quirks.avdd_second_sensor);
                        if (ret)
                                err_msg = "Failed to map regulator to sensor\n";
 
@@ -378,13 +380,19 @@ static void skl_int3472_discrete_remove(struct platform_device *pdev)
 static int skl_int3472_discrete_probe(struct platform_device *pdev)
 {
        struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
+       const struct int3472_discrete_quirks *quirks = NULL;
        struct int3472_discrete_device *int3472;
+       const struct dmi_system_id *id;
        struct int3472_cldb cldb;
        int ret;
 
        if (!adev)
                return -ENODEV;
 
+       id = dmi_first_match(skl_int3472_discrete_quirks);
+       if (id)
+               quirks = id->driver_data;
+
        ret = skl_int3472_fill_cldb(adev, &cldb);
        if (ret) {
                dev_err(&pdev->dev, "Couldn't fill CLDB structure\n");
@@ -408,6 +416,9 @@ static int skl_int3472_discrete_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, int3472);
        int3472->clock.imgclk_index = cldb.clock_source;
 
+       if (quirks)
+               int3472->quirks = *quirks;
+
        ret = skl_int3472_get_sensor_adev_and_name(&pdev->dev, &int3472->sensor,
                                                   &int3472->sensor_name);
        if (ret)
diff --git a/drivers/platform/x86/intel/int3472/discrete_quirks.c b/drivers/platform/x86/intel/int3472/discrete_quirks.c
new file mode 100644 (file)
index 0000000..bf88863
--- /dev/null
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Author: Hans de Goede <hansg@kernel.org> */
+
+#include <linux/dmi.h>
+
+#include "common.h"
+
+static const struct int3472_discrete_quirks lenovo_miix_510_quirks = {
+       .avdd_second_sensor = "i2c-OVTI2680:00",
+};
+
+const struct dmi_system_id skl_int3472_discrete_quirks[] = {
+       {
+               /* Lenovo Miix 510-12IKB */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "MIIX 510-12IKB"),
+               },
+               .driver_data = (void *)&lenovo_miix_510_quirks,
+       },
+       { }
+};