mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-07 13:53:24 +00:00
Merge branch 'for-6.10/i2c-hid' into for-linus
- PM fixes for STM and Weida Tech devices (Kenny Levinsen)
This commit is contained in:
commit
c216843ca4
@ -163,6 +163,24 @@ static u32 i2c_hid_lookup_quirk(const u16 idVendor, const u16 idProduct)
|
||||
return quirks;
|
||||
}
|
||||
|
||||
static int i2c_hid_probe_address(struct i2c_hid *ihid)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Some STM-based devices need 400µs after a rising clock edge to wake
|
||||
* from deep sleep, in which case the first read will fail. Try after a
|
||||
* short sleep to see if the device came alive on the bus. Certain
|
||||
* Weida Tech devices also need this.
|
||||
*/
|
||||
ret = i2c_smbus_read_byte(ihid->client);
|
||||
if (ret < 0) {
|
||||
usleep_range(400, 500);
|
||||
ret = i2c_smbus_read_byte(ihid->client);
|
||||
}
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
static int i2c_hid_xfer(struct i2c_hid *ihid,
|
||||
u8 *send_buf, int send_len, u8 *recv_buf, int recv_len)
|
||||
{
|
||||
@ -384,26 +402,11 @@ static int i2c_hid_set_power(struct i2c_hid *ihid, int power_state)
|
||||
|
||||
i2c_hid_dbg(ihid, "%s\n", __func__);
|
||||
|
||||
/*
|
||||
* Some devices require to send a command to wakeup before power on.
|
||||
* The call will get a return value (EREMOTEIO) but device will be
|
||||
* triggered and activated. After that, it goes like a normal device.
|
||||
*/
|
||||
if (power_state == I2C_HID_PWR_ON) {
|
||||
ret = i2c_hid_set_power_command(ihid, I2C_HID_PWR_ON);
|
||||
|
||||
/* Device was already activated */
|
||||
if (!ret)
|
||||
goto set_pwr_exit;
|
||||
}
|
||||
|
||||
ret = i2c_hid_set_power_command(ihid, power_state);
|
||||
if (ret)
|
||||
dev_err(&ihid->client->dev,
|
||||
"failed to change power setting.\n");
|
||||
|
||||
set_pwr_exit:
|
||||
|
||||
/*
|
||||
* The HID over I2C specification states that if a DEVICE needs time
|
||||
* after the PWR_ON request, it should utilise CLOCK stretching.
|
||||
@ -959,6 +962,14 @@ 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;
|
||||
}
|
||||
|
||||
/* Instead of resetting device, simply powers the device on. This
|
||||
* solves "incomplete reports" on Raydium devices 2386:3118 and
|
||||
* 2386:4B33 and fixes various SIS touchscreens no longer sending
|
||||
@ -992,8 +1003,7 @@ static int __i2c_hid_core_probe(struct i2c_hid *ihid)
|
||||
struct hid_device *hid = ihid->hid;
|
||||
int ret;
|
||||
|
||||
/* Make sure there is something at this address */
|
||||
ret = i2c_smbus_read_byte(client);
|
||||
ret = i2c_hid_probe_address(ihid);
|
||||
if (ret < 0) {
|
||||
i2c_hid_dbg(ihid, "nothing at this address: %d\n", ret);
|
||||
return -ENXIO;
|
||||
|
Loading…
Reference in New Issue
Block a user