blob: 53a72417569534f8efb40950524094b442b77dbe [file] [log] [blame]
From c92b082e3a3ec41ab7a2b26f0512dda6ce9b97fa Mon Sep 17 00:00:00 2001
From: Bartosz Szczepanek <bsz@semihalf.com>
Date: Fri, 12 Jun 2020 18:06:18 +0200
Subject: [PATCH] CHROMIUM: i2c-hid: retry SMBUS read sequence on failure
This is a mitigation for problem specific to Rose touchpad on Eve. In
case of warm boot, touchpad doesn't always respond correctly to SMBUS
read sequence what causes i2c-hid driver to not attach even though
device is on the bus.
This temporary patch makes i2c-hid repeat the sequence 10 times before
it returns.
BUG=b:156232671
TEST=Reboot Eve 10-20 times. Make sure touchpad is working.
TOREVERT=Revert this as soon as Eve touchpad NACK issue is resolved.
Change-Id: Id85c3c6121148f09192433792846f7b04fe69622
Signed-off-by: Bartosz Szczepanek <bsz@semihalf.com>
Signed-off-by: Radoslaw Biernacki <biernacki@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2243178
Reviewed-by: Alex Levin <levinale@google.com>
Commit-Queue: Alex Levin <levinale@google.com>
---
drivers/hid/i2c-hid/i2c-hid-core.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
index 9601c0605fd9e6c1cfbd4a85754d3c45dc545da5..425843d4a14e742c0a8b1533cc1b9c3bb49f87a2 100644
--- a/drivers/hid/i2c-hid/i2c-hid-core.c
+++ b/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -71,6 +71,10 @@
#define i2c_hid_dbg(ihid, ...) dev_dbg(&(ihid)->client->dev, __VA_ARGS__)
+#define EVE_TP_I2C_ADDR 0x49
+#define EVE_TP_RETRIES 10
+#define EVE_TP_DELAY_MS 1
+
struct i2c_hid_desc {
__le16 wHIDDescLength;
__le16 bcdVersion;
@@ -1183,7 +1187,7 @@ static void i2c_hid_core_final_power_down(struct i2c_hid *ihid)
int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops,
u16 hid_descriptor_address, u32 quirks)
{
- int ret;
+ int ret, retries = 0;
struct i2c_hid *ihid;
struct hid_device *hid;
@@ -1223,8 +1227,23 @@ int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops,
if (ret < 0)
return ret;
device_enable_async_suspend(&client->dev);
+ /*
+ * Eve touchpad does not consistently ACK the slave address.
+ * Retry the SMBUS sequence as a mitigation until proper fix
+ * is prepared.
+ * This is a temporary workaround for b/156232671.
+ */
+ if (client->addr == EVE_TP_I2C_ADDR)
+ retries = EVE_TP_RETRIES;
+
+
ret = i2c_hid_init_irq(client);
+ while ((ret < 0) && (retries--)) {
+ dev_err(&client->dev, "no response, retry left %d", retries);
+ msleep(EVE_TP_DELAY_MS);
+ ret = i2c_smbus_read_byte(client);
+ }
if (ret < 0)
goto err_buffers_allocated;
--
2.34.1