platform/x86: int3472: Avoid GPIO regulator spikes
authorHans de Goede <hdegoede@redhat.com>
Thu, 17 Apr 2025 11:13:34 +0000 (13:13 +0200)
committerIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Thu, 24 Apr 2025 13:05:37 +0000 (16:05 +0300)
Avoid the GPIO controlling the avdd regulator being driven low or high
for a very short time leading to spikes by adding an enable delay of 2 ms
and a minimum off to on delay of also 2 ms.

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-7-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/clk_and_regulator.c
drivers/platform/x86/intel/int3472/common.h
drivers/platform/x86/intel/int3472/discrete.c

index 1d116b6..0a46d48 100644 (file)
@@ -187,6 +187,7 @@ void skl_int3472_unregister_clock(struct int3472_discrete_device *int3472)
 
 int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
                                   struct gpio_desc *gpio,
+                                  unsigned int enable_time,
                                   const char *supply_name,
                                   const char *second_sensor)
 {
@@ -227,9 +228,9 @@ int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
        snprintf(regulator->regulator_name, sizeof(regulator->regulator_name), "%s-%s",
                 acpi_dev_name(int3472->adev), supply_name);
 
-       int3472->regulator.rdesc = INT3472_REGULATOR(
-                                               int3472->regulator.regulator_name,
-                                               &int3472_gpio_regulator_ops);
+       regulator->rdesc = INT3472_REGULATOR(regulator->regulator_name,
+                                            &int3472_gpio_regulator_ops,
+                                            enable_time, GPIO_REGULATOR_OFF_ON_DELAY);
 
        cfg.dev = &int3472->adev->dev;
        cfg.init_data = &init_data;
index 4bfd60d..2af8dc1 100644 (file)
 #define GPIO_REGULATOR_NAME_LENGTH                             (12 + GPIO_SUPPLY_NAME_LENGTH)
 /* lower- and upper-case mapping */
 #define GPIO_REGULATOR_SUPPLY_MAP_COUNT                                2
+/*
+ * Ensure the GPIO is driven low/high for at least 2 ms before changing.
+ *
+ * 2 ms has been chosen because it is the minimum time ovXXXX sensors need to
+ * have their reset line driven logical high to properly register a reset.
+ */
+#define GPIO_REGULATOR_ENABLE_TIME                             (2 * USEC_PER_MSEC)
+#define GPIO_REGULATOR_OFF_ON_DELAY                            (2 * USEC_PER_MSEC)
 
 #define INT3472_LED_MAX_NAME_LEN                               32
 
 #define CIO2_SENSOR_SSDB_MCLKSPEED_OFFSET                      86
 
-#define INT3472_REGULATOR(_name, _ops)                         \
+#define INT3472_REGULATOR(_name, _ops, _enable_time, _off_on_delay) \
        (const struct regulator_desc) {                         \
                .name = _name,                                  \
                .type = REGULATOR_VOLTAGE,                      \
                .ops = _ops,                                    \
                .owner = THIS_MODULE,                           \
+               .enable_time = _enable_time,                    \
+               .off_on_delay = _off_on_delay,                  \
        }
 
 #define to_int3472_clk(hw)                                     \
@@ -134,6 +144,7 @@ void skl_int3472_unregister_clock(struct int3472_discrete_device *int3472);
 
 int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
                                   struct gpio_desc *gpio,
+                                  unsigned int enable_time,
                                   const char *supply_name,
                                   const char *second_sensor);
 void skl_int3472_unregister_regulator(struct int3472_discrete_device *int3472);
index f6dae82..a2db4fa 100644 (file)
@@ -311,7 +311,9 @@ 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, con_id,
+                       ret = skl_int3472_register_regulator(int3472, gpio,
+                                                            GPIO_REGULATOR_ENABLE_TIME,
+                                                            con_id,
                                                             int3472->quirks.avdd_second_sensor);
                        if (ret)
                                err_msg = "Failed to map regulator to sensor\n";