HID: i2c-hid: Delayed i2c resume wakeup for 0x0d42 Goodix touchpad
authorBartłomiej Maryńczak <marynczakbartlomiej@gmail.com>
Mon, 7 Oct 2024 22:25:42 +0000 (00:25 +0200)
committerJiri Kosina <jkosina@suse.com>
Fri, 18 Oct 2024 10:32:06 +0000 (12:32 +0200)
Patch for Goodix 27c6:0d42 touchpads found in Inspiron 5515 laptops.

After resume from suspend, one can communicate with this device just fine.
We can read data from it or request a reset,
but for some reason the interrupt line will not go up
when new events are available.
(it can correctly respond to a reset with an interrupt tho)

The only way I found to wake this device up
is to send anything to it after ~1.5s mark,
for example a simple read request, or power mode change.

In this patch, I simply delay the resume steps with msleep,
this will cause the set_power request to happen after
the ~1.5s barrier causing the device to resume its event interrupts.

Sleep was used rather than delayed_work
to make this workaround as non-invasive as possible.

[jkosina@suse.com: shortlog update]
Signed-off-by: Bartłomiej Maryńczak <marynczakbartlomiej@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
drivers/hid/hid-ids.h
drivers/hid/i2c-hid/i2c-hid-core.c

index 8a991b3..25f9649 100644 (file)
 #define I2C_DEVICE_ID_GOODIX_01E8      0x01e8
 #define I2C_DEVICE_ID_GOODIX_01E9      0x01e9
 #define I2C_DEVICE_ID_GOODIX_01F0      0x01f0
+#define I2C_DEVICE_ID_GOODIX_0D42      0x0d42
 
 #define USB_VENDOR_ID_GOODTOUCH                0x1aad
 #define USB_DEVICE_ID_GOODTOUCH_000f   0x000f
index 2f8a9d3..8914c7d 100644 (file)
@@ -50,6 +50,7 @@
 #define I2C_HID_QUIRK_BAD_INPUT_SIZE           BIT(3)
 #define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET    BIT(4)
 #define I2C_HID_QUIRK_NO_SLEEP_ON_SUSPEND      BIT(5)
+#define I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME BIT(6)
 
 /* Command opcodes */
 #define I2C_HID_OPCODE_RESET                   0x01
@@ -140,6 +141,8 @@ static const struct i2c_hid_quirks {
        { USB_VENDOR_ID_ELAN, HID_ANY_ID,
                 I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET |
                 I2C_HID_QUIRK_BOGUS_IRQ },
+       { I2C_VENDOR_ID_GOODIX, I2C_DEVICE_ID_GOODIX_0D42,
+                I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME },
        { 0, 0 }
 };
 
@@ -981,6 +984,13 @@ static int i2c_hid_core_resume(struct i2c_hid *ihid)
                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.
+        */
+       if (ihid->quirks & I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME)
+               msleep(1500);
+
        /* 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