* [PATCH] Input: synaptics-rmi4 - add support for reset gpios
@ 2026-09-12 17:59 Roman Vivchar via B4 Relay
2026-09-12 18:10 ` sashiko-bot
0 siblings, 1 reply; 2+ messages in thread
From: Roman Vivchar via B4 Relay @ 2026-09-12 17:59 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input, linux-kernel, Roman Vivchar
From: Roman Vivchar <rva333@protonmail.com>
In some cases, the touchscreen is wired to the always-on regulator, so
resetting is required for proper I2C communication. Add reset support to
the rmi_i2c driver.
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
Tested on Lenovo Vibe X2 (S3528 IC).
Before:
[ 3.944523] rmi4_i2c 2-0038: rmi_set_page: set page failed: -6.
[ 3.944615] rmi4_i2c 2-0038: Failed to set page select to 0
[ 3.944747] rmi4_i2c 2-0038: Dropping the link to regulator.29
[ 3.944917] rmi4_i2c 2-0038: Dropping the link to regulator.0
[ 3.945052] rmi4_i2c 2-0038: probe with driver rmi4_i2c rejects match -6
After:
[ 3.824640] rmi4_i2c 1-0038: using DT '/soc/i2c@11009000/touchscreen@38' for 'reset' GPIO lookup
[ 3.964557] rmi4_i2c 1-0038: registering I2C-connected sensor
[ 3.964655] device: 'rmi4-00': device_add
[ 3.964682] bus: 'rmi4': add device rmi4-00
[ 3.964716] PM: Adding info for rmi4:rmi4-00
[ 3.964752] rmi4 rmi4-00: bus: 'rmi4': __driver_probe_device: matched device with driver rmi4_physical
[ 3.964768] rmi4 rmi4-00: bus: 'rmi4': really_probe: probing driver rmi4_physical with device
[ 3.964788] rmi4_physical rmi4-00: no default pinctrl state
[ 4.131969] device: 'rmi4-00.fn34': device_add
[ 4.132003] bus: 'rmi4': add device rmi4-00.fn34
[ 4.132041] PM: Adding info for rmi4:rmi4-00.fn34
[ 4.132077] rmi4 rmi4-00.fn34: bus: 'rmi4': __driver_probe_device: matched device with driver rmi4_f34
[ 4.132099] rmi4 rmi4-00.fn34: bus: 'rmi4': really_probe: probing driver rmi4_f34 with device
[ 4.132121] rmi4_f34 rmi4-00.fn34: no default pinctrl state
[ 4.133001] rmi4_f34 rmi4-00.fn34: rmi_f34v7_probe: Unrecognized bootloader version: 29 (\x1d) 16 (\x10)
[ 4.133118] rmi4_f34 rmi4-00.fn34: probe with driver rmi4_f34 failed with error -22
[ 4.134425] device: 'rmi4-00.fn01': device_add
[ 4.134448] bus: 'rmi4': add device rmi4-00.fn01
[ 4.134477] PM: Adding info for rmi4:rmi4-00.fn01
[ 4.134502] rmi4 rmi4-00.fn01: bus: 'rmi4': __driver_probe_device: matched device with driver rmi4_f01
[ 4.134517] rmi4 rmi4-00.fn01: bus: 'rmi4': really_probe: probing driver rmi4_f01 with device
[ 4.134534] rmi4_f01 rmi4-00.fn01: no default pinctrl state
[ 4.141919] rmi4_f01 rmi4-00.fn01: found RMI device, manufacturer: Synaptics, product: X2, fw id: 1730877
[ 4.144846] rmi4_f01 rmi4-00.fn01: driver: 'rmi4_f01': driver_bound: bound to device
[ 4.144898] rmi4_f01 rmi4-00.fn01: bus: 'rmi4': really_probe: bound device to driver rmi4_f01
[ 4.145874] device: 'rmi4-00.fn12': device_add
[ 4.145901] bus: 'rmi4': add device rmi4-00.fn12
[ 4.145935] PM: Adding info for rmi4:rmi4-00.fn12
[ 4.145963] rmi4 rmi4-00.fn12: bus: 'rmi4': __driver_probe_device: matched device with driver rmi4_f12
[ 4.145980] rmi4 rmi4-00.fn12: bus: 'rmi4': really_probe: probing driver rmi4_f12 with device
[ 4.145998] rmi4_f12 rmi4-00.fn12: no default pinctrl state
[ 4.159397] rmi4_f12 rmi4-00.fn12: driver: 'rmi4_f12': driver_bound: bound to device
[ 4.159446] rmi4_f12 rmi4-00.fn12: bus: 'rmi4': really_probe: bound device to driver rmi4_f12
[ 4.161703] device: 'rmi4-00.fn54': device_add
[ 4.161730] bus: 'rmi4': add device rmi4-00.fn54
[ 4.161764] PM: Adding info for rmi4:rmi4-00.fn54
[ 4.164027] device: 'rmi4-00.fn1a': device_add
[ 4.164052] bus: 'rmi4': add device rmi4-00.fn1a
[ 4.164085] PM: Adding info for rmi4:rmi4-00.fn1a
[ 4.164113] rmi4 rmi4-00.fn1a: bus: 'rmi4': __driver_probe_device: matched device with driver rmi4_f1a
[ 4.164128] rmi4 rmi4-00.fn1a: bus: 'rmi4': really_probe: probing driver rmi4_f1a with device
[ 4.164148] rmi4_f1a rmi4-00.fn1a: no default pinctrl state
[ 4.164262] rmi4_f1a rmi4-00.fn1a: driver: 'rmi4_f1a': driver_bound: bound to device
[ 4.164302] rmi4_f1a rmi4-00.fn1a: bus: 'rmi4': really_probe: bound device to driver rmi4_f1a
[ 4.166558] device: 'rmi4-00.fn55': device_add
[ 4.166588] bus: 'rmi4': add device rmi4-00.fn55
[ 4.166619] PM: Adding info for rmi4:rmi4-00.fn55
[ 4.166648] rmi4 rmi4-00.fn55: bus: 'rmi4': __driver_probe_device: matched device with driver rmi4_f55
[ 4.166664] rmi4 rmi4-00.fn55: bus: 'rmi4': really_probe: probing driver rmi4_f55 with device
[ 4.166683] rmi4_f55 rmi4-00.fn55: no default pinctrl state
[ 4.173199] rmi4_f55 rmi4-00.fn55: driver: 'rmi4_f55': driver_bound: bound to device
[ 4.173233] rmi4_f55 rmi4-00.fn55: bus: 'rmi4': really_probe: bound device to driver rmi4_f55
[ 4.175496] device: 'rmi4-00.fn51': device_add
[ 4.175523] bus: 'rmi4': add device rmi4-00.fn51
[ 4.175557] PM: Adding info for rmi4:rmi4-00.fn51
[ 4.180078] input: Synaptics X2 as /devices/platform/soc/11009000.i2c/i2c-1/1-0038/rmi4-00/input/input2
[ 4.184031] rmi4_physical rmi4-00: driver: 'rmi4_physical': driver_bound: bound to device
[ 4.184072] rmi4_physical rmi4-00: bus: 'rmi4': really_probe: bound device to driver rmi4_physical
[ 4.184095] rmi4_i2c 1-0038: driver: 'rmi4_i2c': driver_bound: bound to device
[ 4.184151] rmi4_i2c 1-0038: bus: 'i2c': really_probe: bound device to driver rmi4_i2c
---
drivers/input/rmi4/rmi_i2c.c | 29 ++++++++++++++++++++++++++---
1 file changed, 26 insertions(+), 3 deletions(-)
diff --git a/drivers/input/rmi4/rmi_i2c.c b/drivers/input/rmi4/rmi_i2c.c
index e11d0acb9b96..da560988f44a 100644
--- a/drivers/input/rmi4/rmi_i2c.c
+++ b/drivers/input/rmi4/rmi_i2c.c
@@ -8,6 +8,7 @@
#include <linux/rmi.h>
#include <linux/of.h>
#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>
#include "rmi_driver.h"
@@ -40,6 +41,7 @@ struct rmi_i2c_xport {
struct regulator_bulk_data supplies[2];
u32 startup_delay;
+ struct gpio_desc *reset_gpio;
};
#define RMI_PAGE_SELECT_REGISTER 0xff
@@ -198,6 +200,16 @@ static void rmi_i2c_unregister_transport(void *data)
rmi_unregister_transport_device(&rmi_i2c->xport);
}
+static void rmi_i2c_release_reset(struct rmi_i2c_xport *rmi_i2c)
+{
+ if (rmi_i2c->reset_gpio) {
+ usleep_range(10000, 20000);
+ gpiod_set_value_cansleep(rmi_i2c->reset_gpio, 0);
+ }
+
+ msleep(rmi_i2c->startup_delay);
+}
+
static int rmi_i2c_probe(struct i2c_client *client)
{
struct rmi_device_platform_data *pdata;
@@ -235,6 +247,11 @@ static int rmi_i2c_probe(struct i2c_client *client)
if (error < 0)
return error;
+ rmi_i2c->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(rmi_i2c->reset_gpio))
+ return PTR_ERR(rmi_i2c->reset_gpio);
+
error = regulator_bulk_enable(ARRAY_SIZE(rmi_i2c->supplies),
rmi_i2c->supplies);
if (error < 0)
@@ -249,7 +266,7 @@ static int rmi_i2c_probe(struct i2c_client *client)
of_property_read_u32(client->dev.of_node, "syna,startup-delay-ms",
&rmi_i2c->startup_delay);
- msleep(rmi_i2c->startup_delay);
+ rmi_i2c_release_reset(rmi_i2c);
rmi_i2c->client = client;
mutex_init(&rmi_i2c->page_mutex);
@@ -297,6 +314,9 @@ static int rmi_i2c_suspend(struct device *dev)
if (ret)
dev_warn(dev, "Failed to resume device: %d\n", ret);
+ if (rmi_i2c->reset_gpio)
+ gpiod_set_value_cansleep(rmi_i2c->reset_gpio, 1);
+
regulator_bulk_disable(ARRAY_SIZE(rmi_i2c->supplies),
rmi_i2c->supplies);
@@ -314,7 +334,7 @@ static int rmi_i2c_resume(struct device *dev)
if (ret)
return ret;
- msleep(rmi_i2c->startup_delay);
+ rmi_i2c_release_reset(rmi_i2c);
ret = rmi_driver_resume(rmi_i2c->xport.rmi_dev, true);
if (ret)
@@ -333,6 +353,9 @@ static int rmi_i2c_runtime_suspend(struct device *dev)
if (ret)
dev_warn(dev, "Failed to resume device: %d\n", ret);
+ if (rmi_i2c->reset_gpio)
+ gpiod_set_value_cansleep(rmi_i2c->reset_gpio, 1);
+
regulator_bulk_disable(ARRAY_SIZE(rmi_i2c->supplies),
rmi_i2c->supplies);
@@ -350,7 +373,7 @@ static int rmi_i2c_runtime_resume(struct device *dev)
if (ret)
return ret;
- msleep(rmi_i2c->startup_delay);
+ rmi_i2c_release_reset(rmi_i2c);
ret = rmi_driver_resume(rmi_i2c->xport.rmi_dev, false);
if (ret)
---
base-commit: 68142f986ff04b2b70b31db00f719bf690f64a9a
change-id: 20260912-rmi4-reset-9a3d22aa024e
Best regards,
--
Roman Vivchar <rva333@protonmail.com>
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] Input: synaptics-rmi4 - add support for reset gpios
2026-09-12 17:59 [PATCH] Input: synaptics-rmi4 - add support for reset gpios Roman Vivchar via B4 Relay
@ 2026-09-12 18:10 ` sashiko-bot
0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-09-12 18:10 UTC (permalink / raw)
To: Roman Vivchar; +Cc: dmitry.torokhov, linux-input
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Missing reset GPIO assertion before disabling regulators on driver unbind and probe error paths leads to potential backpowering.
--
commit 11e1dedc5b986fa6ff95c5549b898574a80bff23
Author: Roman Vivchar <rva333@protonmail.com>
Input: synaptics-rmi4 - add support for reset gpios
In some cases, the touchscreen is wired to the always-on regulator, so
resetting is required for proper I2C communication. Add reset support to
the rmi_i2c driver.
> diff --git a/drivers/input/rmi4/rmi_i2c.c b/drivers/input/rmi4/rmi_i2c.c
> index e11d0acb9b96d..da560988f44a1 100644
> --- a/drivers/input/rmi4/rmi_i2c.c
> +++ b/drivers/input/rmi4/rmi_i2c.c
[ ... ]
> @@ -235,6 +247,11 @@ static int rmi_i2c_probe(struct i2c_client *client)
> if (error < 0)
> return error;
>
> + rmi_i2c->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
> + GPIOD_OUT_HIGH);
> + if (IS_ERR(rmi_i2c->reset_gpio))
> + return PTR_ERR(rmi_i2c->reset_gpio);
> +
> error = regulator_bulk_enable(ARRAY_SIZE(rmi_i2c->supplies),
> rmi_i2c->supplies);
> if (error < 0)
[Severity: High]
If a probe error occurs later in rmi_i2c_probe() (for example, when calling
rmi_register_transport_device()), or if the driver is unbound, devres will
run rmi_i2c_regulator_bulk_disable() to disable the regulators.
Should the reset GPIO be asserted before disabling the regulators in the
devres cleanup paths?
Unlike the suspend callbacks which do assert the GPIO, the devres cleanup
does not. This appears to leave the reset GPIO driven while the chip is
unpowered, which could lead to backpowering the device.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260912-rmi4-reset-v1-1-4a3fc8856830@protonmail.com?part=1
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-12 18:10 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-12 17:59 [PATCH] Input: synaptics-rmi4 - add support for reset gpios Roman Vivchar via B4 Relay
2026-09-12 18:10 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox