mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] Input: synaptics-rmi4 - add support for reset gpios
@ 2026-09-12 17:59 Roman Vivchar via B4 Relay
  0 siblings, 0 replies; only message 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	[flat|nested] only message in thread

only message in thread, other threads:[~2026-09-12 18:01 UTC | newest]

Thread overview: (only message) (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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®