Commit c216843c authored by Jiri Kosina's avatar Jiri Kosina

Merge branch 'for-6.10/i2c-hid' into for-linus

- PM fixes for STM and Weida Tech devices (Kenny Levinsen)
parents 88a8049f d2b34fa8
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment