git: 2bcef59d428a - main - psm: recognize post-IBM trackpoints on Thinkpads

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Tue, 19 Sep 2023 16:45:11 UTC
The branch main has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=2bcef59d428a672a9144c574b4b4f42f5f0e5b2a

commit 2bcef59d428a672a9144c574b4b4f42f5f0e5b2a
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2023-09-19 16:41:04 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2023-09-19 16:41:04 +0000

    psm: recognize post-IBM trackpoints on Thinkpads
    
    Newer Thinkpads come with trackpoints from different vendors.  They
    are mostly compatible with the original one.  Not sure all features
    are going to work, but at least this fixes resume operation.
    
    Tested on:              Thinkpad X1 Carbon 7th Gen
    Reviewed by:            wulf, imp
    Diffrential Revision:   https://reviews.FreeBSD.org/D41871
---
 sys/dev/atkbdc/psm.c | 33 +++++++++++++++++++++++----------
 1 file changed, 23 insertions(+), 10 deletions(-)

diff --git a/sys/dev/atkbdc/psm.c b/sys/dev/atkbdc/psm.c
index 318112e2e3e5..1a02dbcec020 100644
--- a/sys/dev/atkbdc/psm.c
+++ b/sys/dev/atkbdc/psm.c
@@ -297,6 +297,16 @@ enum {
 typedef struct trackpointinfo {
 	struct sysctl_ctx_list sysctl_ctx;
 	struct sysctl_oid *sysctl_tree;
+	enum {
+		TRACKPOINT_VENDOR_IBM	= 0x01,
+		TRACKPOINT_VENDOR_ALPS	= 0x02,
+		TRACKPOINT_VENDOR_ELAN	= 0x03,
+		TRACKPOINT_VENDOR_NXP	= 0x04,
+		TRACKPOINT_VENDOR_JYT	= 0x05,
+		TRACKPOINT_VENDOR_SYNAPTICS = 0x06,
+		TRACKPOINT_VENDOR_UNKNOWN = 0x07,
+	}	vendor;
+	int	firmware;
 	int	sensitivity;
 	int	inertia;
 	int	uplateau;
@@ -431,7 +441,6 @@ struct psm_softc {		/* Driver status information */
 	gesture_t	gesture;	/* Gesture context */
 	elantechhw_t	elanhw;		/* Elantech hardware information */
 	elantechaction_t elanaction;	/* Elantech action context */
-	int		tphw;		/* TrackPoint hardware information */
 	trackpointinfo_t tpinfo;	/* TrackPoint configuration */
 	mousemode_t	mode;		/* operation mode */
 	mousemode_t	dflt_mode;	/* default operation mode */
@@ -1995,7 +2004,7 @@ psmattach(device_t dev)
 		sc->config |= PSM_CONFIG_INITAFTERSUSPEND;
 		break;
 	default:
-		if (sc->synhw.infoMajor >= 4 || sc->tphw > 0)
+		if (sc->synhw.infoMajor >= 4 || sc->tpinfo.sysctl_tree != NULL)
 			sc->config |= PSM_CONFIG_INITAFTERSUSPEND;
 		break;
 	}
@@ -6950,7 +6959,7 @@ static int
 enable_trackpoint(struct psm_softc *sc, enum probearg arg)
 {
 	KBDC kbdc = sc->kbdc;
-	int id;
+	int vendor, firmware;
 
 	/*
 	 * If called from enable_synaptics(), make sure that passthrough
@@ -6962,14 +6971,14 @@ enable_trackpoint(struct psm_softc *sc, enum probearg arg)
 	if (sc->synhw.capPassthrough)
 		synaptics_passthrough_on(sc);
 
-	if (send_aux_command(kbdc, 0xe1) != PSM_ACK ||
-	    read_aux_data(kbdc) != 0x01)
+	if (send_aux_command(kbdc, 0xe1) != PSM_ACK)
 		goto no_trackpoint;
-	id = read_aux_data(kbdc);
-	if (id < 0x01)
+	vendor = read_aux_data(kbdc);
+	if (vendor <= 0 || vendor >= TRACKPOINT_VENDOR_UNKNOWN)
+		goto no_trackpoint;
+	firmware = read_aux_data(kbdc);
+	if (firmware < 0x01)
 		goto no_trackpoint;
-	if (arg == PROBE)
-		sc->tphw = id;
 	if (!trackpoint_support)
 		goto no_trackpoint;
 
@@ -6983,9 +6992,13 @@ enable_trackpoint(struct psm_softc *sc, enum probearg arg)
 		 * a guest device.
 		 */
 		if (!sc->synhw.capPassthrough) {
-			sc->hw.hwid = id;
+			sc->hw.hwid = firmware;
 			sc->hw.buttons = 3;
 		}
+		VDLOG(2, sc->dev, LOG_NOTICE, "Trackpoint v=0x%x f=0x%x",
+		    vendor, firmware);
+		sc->tpinfo.vendor = vendor;
+		sc->tpinfo.firmware = firmware;
 	}
 
 	set_trackpoint_parameters(sc);