git: 3d85dcd1a9aa - main - psm(4): Add middle button support for Elantech V4 touchpads

From: Vladimir Kondratyev <wulf_at_FreeBSD.org>
Date: Tue, 10 Feb 2026 22:59:51 UTC
The branch main has been updated by wulf:

URL: https://cgit.FreeBSD.org/src/commit/?id=3d85dcd1a9aa2e1b903935062500cb15b1a700f8

commit 3d85dcd1a9aa2e1b903935062500cb15b1a700f8
Author:     Vladimir Kondratyev <wulf@FreeBSD.org>
AuthorDate: 2026-02-10 22:59:06 +0000
Commit:     Vladimir Kondratyev <wulf@FreeBSD.org>
CommitDate: 2026-02-10 22:59:06 +0000

    psm(4): Add middle button support for Elantech V4 touchpads
    
    based on firmware version.
    
    PR:             291262
    MFC after:      1 month
---
 sys/dev/atkbdc/psm.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/sys/dev/atkbdc/psm.c b/sys/dev/atkbdc/psm.c
index d36396df0fa0..95acf43a3bc6 100644
--- a/sys/dev/atkbdc/psm.c
+++ b/sys/dev/atkbdc/psm.c
@@ -352,6 +352,8 @@ typedef struct elantechhw {
 	int			dptracey;
 	int			issemimt;
 	int			isclickpad;
+	int			hassmbusnotify;
+	int			has3buttons;
 	int			hascrc;
 	int			hastrackpoint;
 	int			haspressure;
@@ -417,7 +419,7 @@ enum {
     ((pb)->ipacket[0] & 0x0c) == 0x0c && ((pb)->ipacket[3] & 0xce) == 0x0c)
 #define	ELANTECH_PKT_IS_V4(pb, hascrc) ((hascrc) ? 			\
     ((pb)->ipacket[3] & 0x08) == 0x00 :					\
-    ((pb)->ipacket[0] & 0x0c) == 0x04 && ((pb)->ipacket[3] & 0x1c) == 0x10)
+    ((pb)->ipacket[0] & 0x08) == 0x00 && ((pb)->ipacket[3] & 0x1c) == 0x10)
 
 typedef struct elantechaction {
 	finger_t		fingers[ELANTECH_MAX_FINGERS];
@@ -1930,8 +1932,11 @@ psm_register_elantech(device_t dev)
 	evdev_support_key(evdev_a, BTN_TOUCH);
 	evdev_support_nfingers(evdev_a, ELANTECH_MAX_FINGERS);
 	evdev_support_key(evdev_a, BTN_LEFT);
-	if (!sc->elanhw.isclickpad)
+	if (!sc->elanhw.isclickpad) {
 		evdev_support_key(evdev_a, BTN_RIGHT);
+		if (sc->elanhw.has3buttons)
+			evdev_support_key(evdev_a, BTN_MIDDLE);
+	}
 	psm_support_abs_bulk(evdev_a, elantech_absinfo);
 
 	error = evdev_register_mtx(evdev_a, &Giant);
@@ -4755,6 +4760,9 @@ proc_elantech(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms,
 		touchpad_button =
 		    ((pb->ipacket[0] & 0x01) ? MOUSE_BUTTON1DOWN : 0) |
 		    ((pb->ipacket[0] & 0x02) ? MOUSE_BUTTON3DOWN : 0);
+		if (sc->elanhw.has3buttons)
+			touchpad_button |=
+			    ((pb->ipacket[0] & 0x04) ? MOUSE_BUTTON2DOWN : 0);
 	}
 
 #ifdef EVDEV_SUPPORT
@@ -7347,6 +7355,9 @@ enable_elantech(struct psm_softc *sc, enum probearg arg)
 	elanhw.hwversion = hwversion;
 	elanhw.issemimt = hwversion == 2;
 	elanhw.isclickpad = (resp[1] & 0x10) != 0;
+	elanhw.hassmbusnotify =
+	    icversion == 0x0f && (resp[1] & 0x20) != 0 && resp[2] != 0;
+	elanhw.has3buttons = elanhw.hassmbusnotify;
 	elanhw.hascrc = (resp[1] & 0x40) != 0;
 	elanhw.haspressure = elanhw.fwversion >= 0x020800;