Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 19 Mar 2018 03:49:54 +0000 (UTC)
From:      Eitan Adler <eadler@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r331172 - stable/11/sys/dev/atkbdc
Message-ID:  <201803190349.w2J3nsaa006010@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: eadler
Date: Mon Mar 19 03:49:54 2018
New Revision: 331172
URL: https://svnweb.freebsd.org/changeset/base/331172

Log:
  MFC r328640:
  
  psm: Add a kludge to support 0x46 identity middle byte Synaptics touchpads
  
  Most synaptics touchpads return 0x47 in middle byte in responce to identify
  command as stated in p.4.4 of "Synaptics PS/2 TouchPad Interfacing Guide".
  But some devices e.g. found on HP EliteBook 9470m return 0x46 here.
  Allow them to be identified as Synaptics as well as 0x47.
  ExtendedQueries return incorrect data on such a touchpads so we ignore
  their result and set conservative defaults.
  
  PR:		222667

Modified:
  stable/11/sys/dev/atkbdc/psm.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/dev/atkbdc/psm.c
==============================================================================
--- stable/11/sys/dev/atkbdc/psm.c	Mon Mar 19 03:47:46 2018	(r331171)
+++ stable/11/sys/dev/atkbdc/psm.c	Mon Mar 19 03:49:54 2018	(r331172)
@@ -136,6 +136,7 @@ struct psmcpnp_softc {
 	enum {
 		PSMCPNP_GENERIC,
 		PSMCPNP_FORCEPAD,
+		PSMCPNP_HPSYN81,
 	} type;		/* Based on PnP ID */
 };
 
@@ -174,6 +175,15 @@ typedef struct packetbuf {
 #define	PSM_PACKETQUEUE	128
 #endif
 
+/*
+ * Typical bezel limits. Taken from 'Synaptics
+ * PS/2 TouchPad Interfacing Guide' p.3.2.3.
+ */
+#define	SYNAPTICS_DEFAULT_MAX_X	5472
+#define	SYNAPTICS_DEFAULT_MAX_Y	4448
+#define	SYNAPTICS_DEFAULT_MIN_X	1472
+#define	SYNAPTICS_DEFAULT_MIN_Y	1408
+
 typedef struct synapticsinfo {
 	struct sysctl_ctx_list	 sysctl_ctx;
 	struct sysctl_oid	*sysctl_tree;
@@ -1096,7 +1106,7 @@ doopen(struct psm_softc *sc, int command_byte)
 		mouse_ext_command(sc->kbdc, 1);
 		get_mouse_status(sc->kbdc, stat, 0, 3);
 		if ((SYNAPTICS_VERSION_GE(sc->synhw, 7, 5) ||
-		     stat[1] == 0x47) &&
+		     stat[1] == 0x46 || stat[1] == 0x47) &&
 		     stat[2] == 0x40) {
 			synaptics_set_mode(sc, synaptics_preferred_mode(sc));
 			VLOG(5, (LOG_DEBUG, "psm%d: Synaptis Absolute Mode "
@@ -6043,7 +6053,7 @@ enable_synaptics(struct psm_softc *sc, enum probearg a
 	KBDC kbdc = sc->kbdc;
 	synapticshw_t synhw;
 	int status[3];
-	int buttons;
+	int buttons, middle_byte;
 
 	VLOG(3, (LOG_DEBUG, "synaptics: BEGIN init\n"));
 
@@ -6060,7 +6070,8 @@ enable_synaptics(struct psm_softc *sc, enum probearg a
 		return (FALSE);
 	if (get_mouse_status(kbdc, status, 0, 3) != 3)
 		return (FALSE);
-	if (status[1] != 0x47)
+	middle_byte = status[1];
+	if (middle_byte != 0x46 && middle_byte != 0x47)
 		return (FALSE);
 
 	bzero(&synhw, sizeof(synhw));
@@ -6071,7 +6082,15 @@ enable_synaptics(struct psm_softc *sc, enum probearg a
 		printf("Synaptics Touchpad v%d.%d\n", synhw.infoMajor,
 		    synhw.infoMinor);
 
-	if (synhw.infoMajor < 4) {
+	/*
+	 * Most synaptics touchpads return 0x47 in middle byte in responce to
+	 * identify command as stated in p.4.4 of "Synaptics PS/2 TouchPad
+	 * Interfacing Guide" and we only support v4.0 or better. But some
+	 * devices return 0x46 here and have a different numbering scheme.
+	 * In the case of 0x46, we allow versions as low as v2.0
+	 */
+	if ((middle_byte == 0x47 && synhw.infoMajor < 4) ||
+	    (middle_byte == 0x46 && synhw.infoMajor < 2)) {
 		printf("  Unsupported (pre-v4) Touchpad detected\n");
 		return (FALSE);
 	}
@@ -6112,7 +6131,7 @@ enable_synaptics(struct psm_softc *sc, enum probearg a
 		return (FALSE);
 	if (get_mouse_status(kbdc, status, 0, 3) != 3)
 		return (FALSE);
-	if (!SYNAPTICS_VERSION_GE(synhw, 7, 5) && status[1] != 0x47) {
+	if (!SYNAPTICS_VERSION_GE(synhw, 7, 5) && status[1] != middle_byte) {
 		printf("  Failed to read extended capability bits\n");
 		return (FALSE);
 	}
@@ -6121,10 +6140,29 @@ enable_synaptics(struct psm_softc *sc, enum probearg a
 	    sc->unit);
 	psmcpnp_sc = (psmcpnp != NULL) ? device_get_softc(psmcpnp) : NULL;
 
+	/*
+	 * Set conservative defaults for 0x46 middle byte touchpads
+	 * as ExtendedQueries return bogus data.
+	 */
+	if (middle_byte == 0x46) {
+		synhw.capExtended = 1;
+		synhw.capPalmDetect = 1;
+		synhw.capPassthrough = 1;
+		synhw.capMultiFinger = 1;
+		synhw.maximumXCoord = SYNAPTICS_DEFAULT_MAX_X;
+		synhw.maximumYCoord = SYNAPTICS_DEFAULT_MAX_Y;
+		synhw.minimumXCoord = SYNAPTICS_DEFAULT_MIN_X;
+		synhw.minimumYCoord = SYNAPTICS_DEFAULT_MIN_Y;
+		/* Enable multitouch mode for HW v8.1 devices */
+		if (psmcpnp_sc != NULL &&
+		    psmcpnp_sc->type == PSMCPNP_HPSYN81)
+			synhw.capReportsV = 1;
+	} else
+		synhw.capExtended = (status[0] & 0x80) != 0;
+
 	/* Set the different capabilities when they exist. */
 	buttons = 0;
-	synhw.capExtended = (status[0] & 0x80) != 0;
-	if (synhw.capExtended) {
+	if (synhw.capExtended && middle_byte == 0x47) {
 		synhw.nExtendedQueries = (status[0] & 0x70) >> 4;
 		synhw.capMiddle        = (status[0] & 0x04) != 0;
 		synhw.capPassthrough   = (status[2] & 0x80) != 0;
@@ -6246,12 +6284,8 @@ enable_synaptics(struct psm_softc *sc, enum probearg a
 				synhw.maximumYCoord = (status[2] << 5) |
 						     ((status[1] & 0xf0) >> 3);
 			} else {
-				/*
-				 * Typical bezel limits. Taken from 'Synaptics
-				 * PS/2 * TouchPad Interfacing Guide' p.3.2.3.
-				 */
-				synhw.maximumXCoord = 5472;
-				synhw.maximumYCoord = 4448;
+				synhw.maximumXCoord = SYNAPTICS_DEFAULT_MAX_X;
+				synhw.maximumYCoord = SYNAPTICS_DEFAULT_MAX_Y;
 			}
 
 			if (synhw.capReportsMin) {
@@ -6267,12 +6301,8 @@ enable_synaptics(struct psm_softc *sc, enum probearg a
 				synhw.minimumYCoord = (status[2] << 5) |
 						     ((status[1] & 0xf0) >> 3);
 			} else {
-				/*
-				 * Typical bezel limits. Taken from 'Synaptics
-				 * PS/2 * TouchPad Interfacing Guide' p.3.2.3.
-				 */
-				synhw.minimumXCoord = 1472;
-				synhw.minimumYCoord = 1408;
+				synhw.minimumXCoord = SYNAPTICS_DEFAULT_MIN_X;
+				synhw.minimumYCoord = SYNAPTICS_DEFAULT_MIN_Y;
 			}
 
 			/*
@@ -6358,7 +6388,7 @@ enable_synaptics(struct psm_softc *sc, enum probearg a
 		return (FALSE);
 	if (get_mouse_status(kbdc, status, 0, 3) != 3)
 		return (FALSE);
-	if (!SYNAPTICS_VERSION_GE(synhw, 7, 5) && status[1] != 0x47) {
+	if (!SYNAPTICS_VERSION_GE(synhw, 7, 5) && status[1] != middle_byte) {
 		printf("  Failed to read mode byte\n");
 		return (FALSE);
 	}
@@ -7181,6 +7211,12 @@ static struct isa_pnp_id forcepad_ids[] = {
 	{ 0 }
 };
 
+/* List of HW v8.1 synaptics touchpads erroneously detected as HW v2.0 */
+static struct isa_pnp_id hpsyn81_ids[] = {
+	{ 0x9e012e4f, "HP PS/2 trackpad port" },	/* SYN019E, EB 9470 */
+	{ 0 }
+};
+
 static int
 create_a_copy(device_t atkbdc, device_t me)
 {
@@ -7214,6 +7250,8 @@ psmcpnp_probe(device_t dev)
 
 	if (ISA_PNP_PROBE(device_get_parent(dev), dev, forcepad_ids) == 0)
 		sc->type = PSMCPNP_FORCEPAD;
+	else if(ISA_PNP_PROBE(device_get_parent(dev), dev, hpsyn81_ids) == 0)
+		sc->type = PSMCPNP_HPSYN81;
 	else if (ISA_PNP_PROBE(device_get_parent(dev), dev, psmcpnp_ids) == 0)
 		sc->type = PSMCPNP_GENERIC;
 	else



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201803190349.w2J3nsaa006010>