@@ -44,6 +44,30 @@ static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c,
return 0;
}
+/*
+ * A retrying version of synaptics_send_cmd
+ */
+static int synaptics_send_cmd_retry(struct psmouse *psmouse, unsigned char c,
+ unsigned char *param)
+{
+ int rc;
+ int tries = ETP_PS2_COMMAND_TRIES;
+
+ do {
+ rc = synaptics_send_cmd(psmouse, c, param);
+ if (rc == 0)
+ break;
+ tries--;
+ psmouse_dbg(psmouse, "%s retrying query 0x%02x (%d).\n", __func__, c, tries);
+ msleep(ETP_PS2_COMMAND_DELAY);
+ } while (tries > 0);
+
+ if (rc)
+ psmouse_err(psmouse, "%s query 0x%02x with retry failed.\n", __func__, c);
+
+ return rc;
+}
+
/*
* V3 and later support this fast command
*/
@@ -1432,7 +1456,7 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties)
* value to avoid mis-detection. Logitech mice are known to respond
* to Elantech magic knock and there might be more.
*/
- if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) {
+ if (synaptics_send_cmd_retry(psmouse, ETP_FW_VERSION_QUERY, param)) {
psmouse_dbg(psmouse, "failed to query firmware version.\n");
return -1;
}
@@ -1718,7 +1742,7 @@ static int elantech_query_info(struct psmouse *psmouse,
/*
* Do the version query again so we can store the result
*/
- if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) {
+ if (synaptics_send_cmd_retry(psmouse, ETP_FW_VERSION_QUERY, param)) {
psmouse_err(psmouse, "failed to query firmware version.\n");
return -EINVAL;
}
On the ThinkPad E14 Gen2, the touchpad occasionally fails to respond to the ETP_FW_VERSION_QUERY during initialization at boot. As a result, the touchpad is detected as a generic mouse. Reloading the `psmouse` kernel module after startup resolves the issue, suggesting a timing-related problem. This patch retries the ETP_FW_VERSION_QUERY command if it fails. This allows the touchpad more time to initialize and respond during firmware version queries. Signed-off-by: Maurice Hieronymus <mhi@mailbox.org> --- On the Lenovo ThinkPad E12 Gen2, the touchpad does not respond to scrolling gestures after startup. The kernel log (`dmesg`) reveals the following: [1.439036] psmouse serio1: elantech: synaptics_send_cmd query 0x01 failed. [1.801802] input: PS/2 Logitech Wheel Mouse as /devices/platform/i8042/serio1/input/input6 A command failure causes the touchpad to be recognized as a generic mouse. Reloading the `psmouse` kernel module resolves the issue: [158.928793] psmouse serio1: elantech: assuming hardware version 4 (with firmware version 0x5f3001) [158.941924] psmouse serio1: elantech: Synaptics capabilities query result 0x90, 0x18, 0x0d. [158.968111] psmouse serio1: elantech: Elan ic body: 0x11, current fw version: 0x4 [159.084746] input: ETPS/2 Elantech Touchpad as /devices/platform/i8042/serio1/input/input15 Enabling debug logging revealed that the driver fails to query the firmware version of the touchpad during initialization: [1.435339] libps2:ps2_sliced_command: psmouse serio1: 01 - -5 [1.436523] psmouse:elantech_detect: psmouse serio1: elantech: failed to query firmware version. The issue appears to be a timing problem, where the touchpad is not fully initialized during the firmware query. Interestingly, enabling debug logging reduces the frequency of the issue, giving the touchpad more time to initialize. This patch introduces a retry mechanism for PS/2 sliced commands during firmware queries, similar to the retry logic in `elantech_ps2_command`. Testing over several weeks confirms that this change resolves the issue reliably on my hardware. --- drivers/input/mouse/elantech.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) --- base-commit: 08bd5b7c9a2401faabdaa1472d45c7de0755fd7e change-id: 20250101-fix-elantech-firmware-query-07619912f603 Best regards,