]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Input: elantech - fix touchpad state on resume for Lenovo N24
authorJonathan Denose <jdenose@google.com>
Fri, 3 May 2024 16:12:07 +0000 (16:12 +0000)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Tue, 28 May 2024 23:06:46 +0000 (16:06 -0700)
The Lenovo N24 on resume becomes stuck in a state where it
sends incorrect packets, causing elantech_packet_check_v4 to fail.
The only way for the device to resume sending the correct packets is for
it to be disabled and then re-enabled.

This change adds a dmi check to trigger this behavior on resume.

Signed-off-by: Jonathan Denose <jdenose@google.com>
Link: https://lore.kernel.org/r/20240503155020.v2.1.Ifa0e25ebf968d8f307f58d678036944141ab17e6@changeid
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/mouse/elantech.c

index 4e38229404b4b001e7caceced16c43023773e0d1..b4723ea395eb9f40e7d272bd97704f6bf7db6652 100644 (file)
@@ -1476,16 +1476,47 @@ static void elantech_disconnect(struct psmouse *psmouse)
        psmouse->private = NULL;
 }
 
+/*
+ * Some hw_version 4 models fail to properly activate absolute mode on
+ * resume without going through disable/enable cycle.
+ */
+static const struct dmi_system_id elantech_needs_reenable[] = {
+#if defined(CONFIG_DMI) && defined(CONFIG_X86)
+       {
+               /* Lenovo N24 */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "81AF"),
+               },
+       },
+#endif
+       { }
+};
+
 /*
  * Put the touchpad back into absolute mode when reconnecting
  */
 static int elantech_reconnect(struct psmouse *psmouse)
 {
+       int err;
+
        psmouse_reset(psmouse);
 
        if (elantech_detect(psmouse, 0))
                return -1;
 
+       if (dmi_check_system(elantech_needs_reenable)) {
+               err = ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE);
+               if (err)
+                       psmouse_warn(psmouse, "failed to deactivate mouse on %s: %d\n",
+                                    psmouse->ps2dev.serio->phys, err);
+
+               err = ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE);
+               if (err)
+                       psmouse_warn(psmouse, "failed to reactivate mouse on %s: %d\n",
+                                    psmouse->ps2dev.serio->phys, err);
+       }
+
        if (elantech_set_absolute_mode(psmouse)) {
                psmouse_err(psmouse,
                            "failed to put touchpad back into absolute mode.\n");