Skip to content

Commit

Permalink
HID: i2c-hid: Revert to using power commands to wake on resume
Browse files Browse the repository at this point in the history
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: [email protected]
Reported-by: Michael <[email protected]>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219440
Link: https://lore.kernel.org/r/[email protected]/
Signed-off-by: Kenny Levinsen <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Benjamin Tissoires <[email protected]>
  • Loading branch information
kennylevinsen authored and Benjamin Tissoires committed Nov 28, 2024
1 parent 919464d commit 3485143
Showing 1 changed file with 12 additions and 8 deletions.
20 changes: 12 additions & 8 deletions drivers/hid/i2c-hid/i2c-hid-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,19 @@ static int i2c_hid_set_power(struct i2c_hid *ihid, int power_state)

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

/*
* Some STM-based devices need 400µs after a rising clock edge to wake
* from deep sleep, in which case the first request will fail due to
* the address not being acknowledged. Try after a short sleep to see
* if the device came alive on the bus. Certain Weida Tech devices also
* need this.
*/
ret = i2c_hid_set_power_command(ihid, power_state);
if (ret && power_state == I2C_HID_PWR_ON) {
usleep_range(400, 500);
ret = i2c_hid_set_power_command(ihid, I2C_HID_PWR_ON);
}

if (ret)
dev_err(&ihid->client->dev,
"failed to change power setting.\n");
Expand Down Expand Up @@ -976,14 +988,6 @@ static int i2c_hid_core_resume(struct i2c_hid *ihid)

enable_irq(client->irq);

/* Make sure the device is awake on the bus */
ret = i2c_hid_probe_address(ihid);
if (ret < 0) {
dev_err(&client->dev, "nothing at address after resume: %d\n",
ret);
return -ENXIO;
}

/* On Goodix 27c6:0d42 wait extra time before device wakeup.
* It's not clear why but if we send wakeup too early, the device will
* never trigger input interrupts.
Expand Down

0 comments on commit 3485143

Please sign in to comment.