| From eaf833befbfcc9b992e54f4cd94cf1bf12c7dc53 Mon Sep 17 00:00:00 2001 |
| From: Kai-Heng Feng <kai.heng.feng@canonical.com> |
| Date: Thu, 7 Nov 2019 22:28:11 +0800 |
| Subject: [PATCH] HID: i2c-hid: Reset ALPS touchpads on resume |
| |
| commit fd70466d37bf3fe0118d18c56ddde85b428f86cf upstream. |
| |
| Commit 52cf93e63ee6 ("HID: i2c-hid: Don't reset device upon system |
| resume") fixes many touchpads and touchscreens, however ALPS touchpads |
| start to trigger IRQ storm after system resume. |
| |
| Since it's total silence from ALPS, let's bring the old behavior back |
| to ALPS touchpads. |
| |
| Fixes: 52cf93e63ee6 ("HID: i2c-hid: Don't reset device upon system resume") |
| Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com> |
| Signed-off-by: Jiri Kosina <jkosina@suse.cz> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c |
| index 7df445a6da1f..44d6fcf46ffa 100644 |
| --- a/drivers/hid/i2c-hid/i2c-hid-core.c |
| +++ b/drivers/hid/i2c-hid/i2c-hid-core.c |
| @@ -51,6 +51,7 @@ |
| #define I2C_HID_QUIRK_NO_RUNTIME_PM BIT(2) |
| #define I2C_HID_QUIRK_DELAY_AFTER_SLEEP BIT(3) |
| #define I2C_HID_QUIRK_BOGUS_IRQ BIT(4) |
| +#define I2C_HID_QUIRK_RESET_ON_RESUME BIT(5) |
| |
| /* flags */ |
| #define I2C_HID_STARTED 0 |
| @@ -186,6 +187,8 @@ static const struct i2c_hid_quirks { |
| I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, |
| { USB_VENDOR_ID_ELAN, HID_ANY_ID, |
| I2C_HID_QUIRK_BOGUS_IRQ }, |
| + { USB_VENDOR_ID_ALPS_JP, HID_ANY_ID, |
| + I2C_HID_QUIRK_RESET_ON_RESUME }, |
| { 0, 0 } |
| }; |
| |
| @@ -1294,8 +1297,15 @@ static int i2c_hid_resume(struct device *dev) |
| * solves "incomplete reports" on Raydium devices 2386:3118 and |
| * 2386:4B33 and fixes various SIS touchscreens no longer sending |
| * data after a suspend/resume. |
| + * |
| + * However some ALPS touchpads generate IRQ storm without reset, so |
| + * let's still reset them here. |
| */ |
| - ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); |
| + if (ihid->quirks & I2C_HID_QUIRK_RESET_ON_RESUME) |
| + ret = i2c_hid_hwreset(client); |
| + else |
| + ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); |
| + |
| if (ret) |
| return ret; |
| |
| -- |
| 2.7.4 |
| |