Skip to content

Commit 3485143

Browse files
kennylevinsenBenjamin Tissoires
authored and
Benjamin Tissoires
committed
HID: i2c-hid: Revert to using power commands to wake on resume
commit 7d6f065 ("HID: i2c-hid: Use address probe to wake on resume") replaced the retry of power commands with the dummy read "bus probe" we use on boot which accounts for a necessary delay before retry. This made at least one Weida device (2575:0910 in an ASUS Vivobook S14) very unhappy, as the bus probe despite being successful somehow lead to the following power command failing so hard that the device never lets go of the bus. This means that even retries of the power command would fail on a timeout as the bus remains busy. Remove the bus probe on resume and instead reintroduce retry of the power command for wake-up purposes while respecting the newly established wake-up retry timings. Fixes: 7d6f065 ("HID: i2c-hid: Use address probe to wake on resume") Cc: stable@vger.kernel.org Reported-by: Michael <auslands-kv@gmx.de> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219440 Link: https://lore.kernel.org/r/d5acb485-7377-4139-826d-4df04d21b5ed@leemhuis.info/ Signed-off-by: Kenny Levinsen <kl@kl.wtf> Link: https://patch.msgid.link/20241119235615.23902-1-kl@kl.wtf Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
1 parent 919464d commit 3485143

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

drivers/hid/i2c-hid/i2c-hid-core.c

+12-8
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,19 @@ static int i2c_hid_set_power(struct i2c_hid *ihid, int power_state)
414414

415415
i2c_hid_dbg(ihid, "%s\n", __func__);
416416

417+
/*
418+
* Some STM-based devices need 400µs after a rising clock edge to wake
419+
* from deep sleep, in which case the first request will fail due to
420+
* the address not being acknowledged. Try after a short sleep to see
421+
* if the device came alive on the bus. Certain Weida Tech devices also
422+
* need this.
423+
*/
417424
ret = i2c_hid_set_power_command(ihid, power_state);
425+
if (ret && power_state == I2C_HID_PWR_ON) {
426+
usleep_range(400, 500);
427+
ret = i2c_hid_set_power_command(ihid, I2C_HID_PWR_ON);
428+
}
429+
418430
if (ret)
419431
dev_err(&ihid->client->dev,
420432
"failed to change power setting.\n");
@@ -976,14 +988,6 @@ static int i2c_hid_core_resume(struct i2c_hid *ihid)
976988

977989
enable_irq(client->irq);
978990

979-
/* Make sure the device is awake on the bus */
980-
ret = i2c_hid_probe_address(ihid);
981-
if (ret < 0) {
982-
dev_err(&client->dev, "nothing at address after resume: %d\n",
983-
ret);
984-
return -ENXIO;
985-
}
986-
987991
/* On Goodix 27c6:0d42 wait extra time before device wakeup.
988992
* It's not clear why but if we send wakeup too early, the device will
989993
* never trigger input interrupts.

0 commit comments

Comments
 (0)