HID: i2c-hid: elan: fix reset suspend current leakage

The Elan eKTH5015M touch controller found on the Lenovo ThinkPad X13s
shares the VCC33 supply with other peripherals that may remain powered
during suspend (e.g. when enabled as wakeup sources).

The reset line is also wired so that it can be left deasserted when the
supply is off.

This is important as it avoids holding the controller in reset for
extended periods of time when it remains powered, which can lead to
increased power consumption, and also avoids leaking current through the
X13s reset circuitry during suspend (and after driver unbind).

Use the new 'no-reset-on-power-off' devicetree property to determine
when reset needs to be asserted on power down.

Notably this also avoids wasting power on machine variants without a
touchscreen for which the driver would otherwise exit probe with reset
asserted.

Fixes: bd3cba00dcc6 ("HID: i2c-hid: elan: Add support for Elan eKTH6915 i2c-hid touchscreens")
Cc: <stable@vger.kernel.org> # 6.0
Cc: Douglas Anderson <dianders@chromium.org>
Tested-by: Steev Klimaszewski <steev@kali.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Link: https://lore.kernel.org/r/20240507144821.12275-5-johan+linaro@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>

authored by Johan Hovold and committed by Benjamin Tissoires 0eafc58f e538d4b8

+47 -12
+47 -12
drivers/hid/i2c-hid/i2c-hid-of-elan.c
··· 31 struct regulator *vcc33; 32 struct regulator *vccio; 33 struct gpio_desc *reset_gpio; 34 const struct elan_i2c_hid_chip_data *chip_data; 35 }; 36 ··· 41 container_of(ops, struct i2c_hid_of_elan, ops); 42 int ret; 43 44 if (ihid_elan->vcc33) { 45 ret = regulator_enable(ihid_elan->vcc33); 46 if (ret) 47 - return ret; 48 } 49 50 ret = regulator_enable(ihid_elan->vccio); 51 - if (ret) { 52 - regulator_disable(ihid_elan->vcc33); 53 - return ret; 54 - } 55 56 if (ihid_elan->chip_data->post_power_delay_ms) 57 msleep(ihid_elan->chip_data->post_power_delay_ms); ··· 61 msleep(ihid_elan->chip_data->post_gpio_reset_on_delay_ms); 62 63 return 0; 64 } 65 66 static void elan_i2c_hid_power_down(struct i2chid_ops *ops) ··· 77 struct i2c_hid_of_elan *ihid_elan = 78 container_of(ops, struct i2c_hid_of_elan, ops); 79 80 - gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1); 81 if (ihid_elan->chip_data->post_gpio_reset_off_delay_ms) 82 msleep(ihid_elan->chip_data->post_gpio_reset_off_delay_ms); 83 ··· 96 static int i2c_hid_of_elan_probe(struct i2c_client *client) 97 { 98 struct i2c_hid_of_elan *ihid_elan; 99 100 ihid_elan = devm_kzalloc(&client->dev, sizeof(*ihid_elan), GFP_KERNEL); 101 if (!ihid_elan) ··· 111 if (IS_ERR(ihid_elan->reset_gpio)) 112 return PTR_ERR(ihid_elan->reset_gpio); 113 114 ihid_elan->vccio = devm_regulator_get(&client->dev, "vccio"); 115 - if (IS_ERR(ihid_elan->vccio)) 116 - return PTR_ERR(ihid_elan->vccio); 117 118 ihid_elan->chip_data = device_get_match_data(&client->dev); 119 120 if (ihid_elan->chip_data->main_supply_name) { 121 ihid_elan->vcc33 = devm_regulator_get(&client->dev, 122 ihid_elan->chip_data->main_supply_name); 123 - if (IS_ERR(ihid_elan->vcc33)) 124 - return PTR_ERR(ihid_elan->vcc33); 125 } 126 127 - return i2c_hid_core_probe(client, &ihid_elan->ops, 128 - ihid_elan->chip_data->hid_descriptor_address, 0); 129 } 130 131 static const struct elan_i2c_hid_chip_data elan_ekth6915_chip_data = {
··· 31 struct regulator *vcc33; 32 struct regulator *vccio; 33 struct gpio_desc *reset_gpio; 34 + bool no_reset_on_power_off; 35 const struct elan_i2c_hid_chip_data *chip_data; 36 }; 37 ··· 40 container_of(ops, struct i2c_hid_of_elan, ops); 41 int ret; 42 43 + gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1); 44 + 45 if (ihid_elan->vcc33) { 46 ret = regulator_enable(ihid_elan->vcc33); 47 if (ret) 48 + goto err_deassert_reset; 49 } 50 51 ret = regulator_enable(ihid_elan->vccio); 52 + if (ret) 53 + goto err_disable_vcc33; 54 55 if (ihid_elan->chip_data->post_power_delay_ms) 56 msleep(ihid_elan->chip_data->post_power_delay_ms); ··· 60 msleep(ihid_elan->chip_data->post_gpio_reset_on_delay_ms); 61 62 return 0; 63 + 64 + err_disable_vcc33: 65 + if (ihid_elan->vcc33) 66 + regulator_disable(ihid_elan->vcc33); 67 + err_deassert_reset: 68 + if (ihid_elan->no_reset_on_power_off) 69 + gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0); 70 + 71 + return ret; 72 } 73 74 static void elan_i2c_hid_power_down(struct i2chid_ops *ops) ··· 67 struct i2c_hid_of_elan *ihid_elan = 68 container_of(ops, struct i2c_hid_of_elan, ops); 69 70 + /* 71 + * Do not assert reset when the hardware allows for it to remain 72 + * deasserted regardless of the state of the (shared) power supply to 73 + * avoid wasting power when the supply is left on. 74 + */ 75 + if (!ihid_elan->no_reset_on_power_off) 76 + gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1); 77 + 78 if (ihid_elan->chip_data->post_gpio_reset_off_delay_ms) 79 msleep(ihid_elan->chip_data->post_gpio_reset_off_delay_ms); 80 ··· 79 static int i2c_hid_of_elan_probe(struct i2c_client *client) 80 { 81 struct i2c_hid_of_elan *ihid_elan; 82 + int ret; 83 84 ihid_elan = devm_kzalloc(&client->dev, sizeof(*ihid_elan), GFP_KERNEL); 85 if (!ihid_elan) ··· 93 if (IS_ERR(ihid_elan->reset_gpio)) 94 return PTR_ERR(ihid_elan->reset_gpio); 95 96 + ihid_elan->no_reset_on_power_off = of_property_read_bool(client->dev.of_node, 97 + "no-reset-on-power-off"); 98 + 99 ihid_elan->vccio = devm_regulator_get(&client->dev, "vccio"); 100 + if (IS_ERR(ihid_elan->vccio)) { 101 + ret = PTR_ERR(ihid_elan->vccio); 102 + goto err_deassert_reset; 103 + } 104 105 ihid_elan->chip_data = device_get_match_data(&client->dev); 106 107 if (ihid_elan->chip_data->main_supply_name) { 108 ihid_elan->vcc33 = devm_regulator_get(&client->dev, 109 ihid_elan->chip_data->main_supply_name); 110 + if (IS_ERR(ihid_elan->vcc33)) { 111 + ret = PTR_ERR(ihid_elan->vcc33); 112 + goto err_deassert_reset; 113 + } 114 } 115 116 + ret = i2c_hid_core_probe(client, &ihid_elan->ops, 117 + ihid_elan->chip_data->hid_descriptor_address, 0); 118 + if (ret) 119 + goto err_deassert_reset; 120 + 121 + return 0; 122 + 123 + err_deassert_reset: 124 + if (ihid_elan->no_reset_on_power_off) 125 + gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0); 126 + 127 + return ret; 128 } 129 130 static const struct elan_i2c_hid_chip_data elan_ekth6915_chip_data = {