Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Jan 2019 21:11:02 +0000 (UTC)
From:      Vladimir Kondratyev <wulf@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r343157 - stable/12/sys/dev/atkbdc
Message-ID:  <201901182111.x0ILB2RH024078@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: wulf
Date: Fri Jan 18 21:11:02 2019
New Revision: 343157
URL: https://svnweb.freebsd.org/changeset/base/343157

Log:
  MFC r340912,r340913:
  
  psm(4): Revert r328640 and add minimal support for active AUX port
          multiplexers
  
  Active PS/2 multiplexing is a method for attaching up to four PS/2
  pointing devices to a computer. Enabling of multiplexed mode allows
  commands to be directed to individual devices using routing prefixes.
  Multiplexed mode reports input with each byte tagged to identify
  its source. This method differs from one currently supported by psm(4)
  where so called guest device (trackpoint) is attached to special
  interface located on the host device (touchpad) and latter performs
  guest protocol conversion to special encapsulation packet format.
  
  At present time active PS/2 multiplexing is used in some models of
  HP laptops e.g. EliteBook 8560w, 9470m. Enabling of absolute operation
  mode on such touchpads is connected with following problems:
  1. Touchpad's port priority is lower than trackpoint's. That blocks
     information queries thus prevents touchpad detection and configuration.
  2. Touchpad and trackpoint have different protocol packet sizes and
     sync bytes.
  
  As PS/2 usage is on decline only minimal possible set of changes to
  support Synaptics touchpad and generic mouses is implemented.
  Active multiplexing mode is enabled only at probe stage to scan through
  attached PS/2 devices to query and configure Synaptics touchpad.
  After touchpad has been configured, mux is switched back to legacy
  (hidden multiplexing) mode to perform normal interrupt-driven input
  data processing. Overflow bit values rather than tags are used to
  separate packets produced by different devices. Switching back to
  legacy mode allows to avoid psm(4) and atkbd(4) rework to support
  4 instances of mouse driver.
  
  Note: While in hidden multiplexing mode KBC does some editing of the
  packet stream. It remembers the button bits from the last packet
  received from each device, and replaces the button bits of every
  packet with the logical OR of all devices’ most recent button bits.
  This sort of button crosstalk results in spurious button events
  which are inhibitted with various tricks. E.g. trackpoint middle
  button events are suppressed while trackpad surface is touched and
  touchpad left and right button events are suppressed if corresponding
  trackpoint buttons are pressed.
  
  PR:		231058
  Reported by:	Michael Figiel <mifigiel at gmail.com>
  Tested by:	Michael Figiel <mifigiel at gmail.com>

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

Modified: stable/12/sys/dev/atkbdc/atkbdc.c
==============================================================================
--- stable/12/sys/dev/atkbdc/atkbdc.c	Fri Jan 18 21:00:54 2019	(r343156)
+++ stable/12/sys/dev/atkbdc/atkbdc.c	Fri Jan 18 21:11:02 2019	(r343157)
@@ -296,6 +296,7 @@ atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag, 
 	    sc->lock = FALSE;
 	    sc->kbd.head = sc->kbd.tail = 0;
 	    sc->aux.head = sc->aux.tail = 0;
+	    sc->aux_mux_enabled = FALSE;
 #if KBDIO_DEBUG >= 2
 	    sc->kbd.call_count = 0;
 	    sc->kbd.qcount = sc->kbd.max_qcount = 0;
@@ -639,7 +640,12 @@ write_kbd_command(KBDC p, int c)
 int
 write_aux_command(KBDC p, int c)
 {
-    if (!write_controller_command(p, KBDC_WRITE_TO_AUX))
+    int f;
+
+    f = aux_mux_is_enabled(p) ?
+        KBDC_WRITE_TO_AUX_MUX + kbdcp(p)->aux_mux_port : KBDC_WRITE_TO_AUX;
+
+    if (!write_controller_command(p, f))
 	return FALSE;
     return write_controller_data(p, c);
 }
@@ -1200,4 +1206,79 @@ set_controller_command_byte(KBDC p, int mask, int comm
 	    command);
 
     return TRUE;
+}
+
+/*
+ * Rudimentary support for active PS/2 AUX port multiplexing.
+ * Only write commands can be routed to a selected AUX port.
+ * Source port of data processed by read commands is totally ignored.
+ */
+static int
+set_aux_mux_state(KBDC p, int enabled)
+{
+	int command, version;
+
+	if (write_controller_command(p, KBDC_FORCE_AUX_OUTPUT) == 0 ||
+	    write_controller_data(p, 0xF0) == 0 ||
+	    read_controller_data(p) != 0xF0)
+		return (-1);
+
+	if (write_controller_command(p, KBDC_FORCE_AUX_OUTPUT) == 0 ||
+	    write_controller_data(p, 0x56) == 0 ||
+	    read_controller_data(p) != 0x56)
+		return (-1);
+
+	command = enabled ? 0xa4 : 0xa5;
+	if (write_controller_command(p, KBDC_FORCE_AUX_OUTPUT) == 0 ||
+	    write_controller_data(p, command) == 0 ||
+	    (version = read_controller_data(p)) == command)
+		return (-1);
+
+	return (version);
+}
+
+int
+set_active_aux_mux_port(KBDC p, int port)
+{
+
+	if (!aux_mux_is_enabled(p))
+		return (FALSE);
+
+	if (port < 0 || port >= KBDC_AUX_MUX_NUM_PORTS)
+		return (FALSE);
+
+	kbdcp(p)->aux_mux_port = port;
+
+	return (TRUE);
+}
+
+/* Checks for active multiplexing support and enables it */
+int
+enable_aux_mux(KBDC p)
+{
+	int version;
+
+	version = set_aux_mux_state(p, TRUE);
+	if (version >= 0) {
+		kbdcp(p)->aux_mux_enabled = TRUE;
+		set_active_aux_mux_port(p, 0);
+	}
+
+	return (version);
+}
+
+int
+disable_aux_mux(KBDC p)
+{
+
+	kbdcp(p)->aux_mux_enabled = FALSE;
+
+	return (set_aux_mux_state(p, FALSE));
+}
+
+int
+aux_mux_is_enabled(KBDC p)
+{
+
+	return (kbdcp(p)->aux_mux_enabled);
 }

Modified: stable/12/sys/dev/atkbdc/atkbdcreg.h
==============================================================================
--- stable/12/sys/dev/atkbdc/atkbdcreg.h	Fri Jan 18 21:00:54 2019	(r343156)
+++ stable/12/sys/dev/atkbdc/atkbdcreg.h	Fri Jan 18 21:11:02 2019	(r343157)
@@ -51,6 +51,8 @@
 /* controller commands (sent to KBD_COMMAND_PORT) */
 #define KBDC_SET_COMMAND_BYTE 	0x0060
 #define KBDC_GET_COMMAND_BYTE 	0x0020
+#define KBDC_WRITE_TO_AUX_MUX	0x0090
+#define KBDC_FORCE_AUX_OUTPUT	0x00d3
 #define KBDC_WRITE_TO_AUX    	0x00d4
 #define KBDC_DISABLE_AUX_PORT 	0x00a7
 #define KBDC_ENABLE_AUX_PORT 	0x00a8
@@ -209,6 +211,8 @@ typedef struct atkbdc_softc {
 #define KBDC_QUIRK_IGNORE_PROBE_RESULT	(1 << 1)
 #define KBDC_QUIRK_RESET_AFTER_PROBE	(1 << 2)
 #define KBDC_QUIRK_SETLEDS_ON_INIT	(1 << 3)
+    int aux_mux_enabled;	/* active PS/2 multiplexing is enabled */
+    int aux_mux_port;		/* current aux mux port */
 } atkbdc_softc_t; 
 
 enum kbdc_device_ivar {
@@ -223,6 +227,8 @@ typedef caddr_t KBDC;
 #define KBDC_RID_KBD	0
 #define KBDC_RID_AUX	1
 
+#define KBDC_AUX_MUX_NUM_PORTS	4
+
 /* function prototypes */
 
 atkbdc_softc_t *atkbdc_get_softc(int unit);
@@ -267,6 +273,11 @@ void kbdc_set_device_mask(KBDC kbdc, int mask);
 
 int get_controller_command_byte(KBDC kbdc);
 int set_controller_command_byte(KBDC kbdc, int command, int flag);
+
+int set_active_aux_mux_port(KBDC p, int port);
+int enable_aux_mux(KBDC p);
+int disable_aux_mux(KBDC p);
+int aux_mux_is_enabled(KBDC p);
 
 #endif /* _KERNEL */
 

Modified: stable/12/sys/dev/atkbdc/psm.c
==============================================================================
--- stable/12/sys/dev/atkbdc/psm.c	Fri Jan 18 21:00:54 2019	(r343156)
+++ stable/12/sys/dev/atkbdc/psm.c	Fri Jan 18 21:11:02 2019	(r343157)
@@ -136,7 +136,6 @@ struct psmcpnp_softc {
 	enum {
 		PSMCPNP_GENERIC,
 		PSMCPNP_FORCEPAD,
-		PSMCPNP_HPSYN81,
 	} type;		/* Based on PnP ID */
 };
 
@@ -151,6 +150,9 @@ struct psmcpnp_softc {
 #define	PSM_LEVEL_MIN		PSM_LEVEL_BASE
 #define	PSM_LEVEL_MAX		PSM_LEVEL_NATIVE
 
+/* Active PS/2 multiplexing */
+#define	PSM_NOMUX		(-1)
+
 /* Logitech PS2++ protocol */
 #define	MOUSE_PS2PLUS_CHECKBITS(b)	\
     ((((b[2] & 0x03) << 2) | 0x02) == (b[1] & 0x0f))
@@ -175,15 +177,6 @@ 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;
@@ -448,6 +441,11 @@ struct psm_softc {		/* Driver status information */
 	int		cmdcount;
 	struct sigio	*async;		/* Processes waiting for SIGIO */
 	int		extended_buttons;
+	int		muxport;	/* MUX port with attached Synaptics */
+	u_char		muxsave[3];	/* 3->6 byte proto conversion buffer */
+	int		muxtpbuttons;	/* Touchpad button state */
+	int		muxmsbuttons;	/* Mouse (trackpoint) button state */
+	struct timeval	muxmidtimeout;	/* middle button supression timeout */
 #ifdef EVDEV_SUPPORT
 	struct evdev_dev *evdev_a;	/* Absolute reporting device */
 	struct evdev_dev *evdev_r;	/* Relative reporting device */
@@ -613,6 +611,7 @@ static void	proc_mmanplus(struct psm_softc *, packetbu
 		    mousestatus_t *, int *, int *, int *);
 static int	proc_synaptics(struct psm_softc *, packetbuf_t *,
 		    mousestatus_t *, int *, int *, int *);
+static int	proc_synaptics_mux(struct psm_softc *, packetbuf_t *);
 static void	proc_versapad(struct psm_softc *, packetbuf_t *,
 		    mousestatus_t *, int *, int *, int *);
 static int	proc_elantech(struct psm_softc *, packetbuf_t *,
@@ -642,6 +641,7 @@ static probefunc_t	enable_4dmouse;
 static probefunc_t	enable_4dplus;
 static probefunc_t	enable_mmanplus;
 static probefunc_t	enable_synaptics;
+static probefunc_t	enable_synaptics_mux;
 static probefunc_t	enable_trackpoint;
 static probefunc_t	enable_versapad;
 static probefunc_t	enable_elantech;
@@ -662,6 +662,8 @@ static struct {
 	 * WARNING: the order of probe is very important.  Don't mess it
 	 * unless you know what you are doing.
 	 */
+	{ MOUSE_MODEL_SYNAPTICS,	/* Synaptics Touchpad on Active Mux */
+	  0x00, MOUSE_PS2_PACKETSIZE, enable_synaptics_mux },
 	{ MOUSE_MODEL_NET,		/* Genius NetMouse */
 	  0x08, MOUSE_PS2INTELLI_PACKETSIZE, enable_gmouse },
 	{ MOUSE_MODEL_NETSCROLL,	/* Genius NetScroll */
@@ -1092,6 +1094,7 @@ static int
 doopen(struct psm_softc *sc, int command_byte)
 {
 	int stat[3];
+	int mux_enabled = FALSE;
 
 	/*
 	 * FIXME: Synaptics TouchPad seems to go back to Relative Mode with
@@ -1106,16 +1109,27 @@ doopen(struct psm_softc *sc, int command_byte)
 	 * doesn't show any evidence of such a command.
 	 */
 	if (sc->hw.model == MOUSE_MODEL_SYNAPTICS) {
+		if (sc->muxport != PSM_NOMUX) {
+			mux_enabled = enable_aux_mux(sc->kbdc) >= 0;
+			if (mux_enabled)
+				set_active_aux_mux_port(sc->kbdc, sc->muxport);
+			else
+				log(LOG_ERR, "psm%d: failed to enable "
+				    "active multiplexing mode.\n",
+				    sc->unit);
+		}
 		mouse_ext_command(sc->kbdc, 1);
 		get_mouse_status(sc->kbdc, stat, 0, 3);
 		if ((SYNAPTICS_VERSION_GE(sc->synhw, 7, 5) ||
-		     stat[1] == 0x46 || stat[1] == 0x47) &&
+		     stat[1] == 0x47) &&
 		     stat[2] == 0x40) {
 			synaptics_set_mode(sc, synaptics_preferred_mode(sc));
 			VLOG(5, (LOG_DEBUG, "psm%d: Synaptis Absolute Mode "
 			    "hopefully restored\n",
 			    sc->unit));
 		}
+		if (mux_enabled)
+			disable_aux_mux(sc->kbdc);
 	}
 
 	/*
@@ -1364,6 +1378,7 @@ psmprobe(device_t dev)
 #endif
 #endif /* PSM_HOOKRESUME | PSM_HOOKAPM */
 	sc->flags = 0;
+	sc->muxport = PSM_NOMUX;
 	if (bootverbose)
 		++verbose;
 
@@ -1833,7 +1848,7 @@ psm_register_synaptics(device_t dev)
 			evdev_support_key(evdev_a, BTN_0 + i);
 
 	error = evdev_register_mtx(evdev_a, &Giant);
-	if (!error && sc->synhw.capPassthrough) {
+	if (!error && (sc->synhw.capPassthrough || sc->muxport != PSM_NOMUX)) {
 		guest_model = sc->tpinfo.sysctl_tree != NULL ?
 		    MOUSE_MODEL_TRACKPOINT : MOUSE_MODEL_GENERIC;
 		error = psm_register(dev, guest_model);
@@ -2941,6 +2956,9 @@ psmintr(void *arg)
 	int c;
 	packetbuf_t *pb;
 
+	if (aux_mux_is_enabled(sc->kbdc))
+		VLOG(2, (LOG_DEBUG, "psmintr: active multiplexing mode is not "
+		    "supported!\n"));
 
 	/* read until there is nothing to read */
 	while((c = read_aux_data_no_wait(sc->kbdc)) != -1) {
@@ -3292,7 +3310,7 @@ proc_synaptics(struct psm_softc *sc, packetbuf_t *pb, 
 		 * Handle packets from the guest device. See:
 		 * Synaptics PS/2 TouchPad Interfacing Guide, Section 5.1
 		 */
-		if (sc->synhw.capPassthrough) {
+		if (sc->synhw.capPassthrough || sc->muxport != PSM_NOMUX) {
 			*x = ((pb->ipacket[1] & 0x10) ?
 			    pb->ipacket[4] - 256 : pb->ipacket[4]);
 			*y = ((pb->ipacket[1] & 0x20) ?
@@ -3592,6 +3610,83 @@ SYNAPTICS_END:
 }
 
 static int
+proc_synaptics_mux(struct psm_softc *sc, packetbuf_t *pb)
+{
+	int butt;
+
+	/*
+	 * Convert 3-byte interleaved mixture of Synaptics and generic mouse
+	 * packets into plain 6-byte Synaptics packet protocol.
+	 * While in hidden multiplexing mode KBC does some editing of the
+	 * packet stream. It remembers the button bits from the last packet
+	 * received from each device, and replaces the button bits of every
+	 * packet with the logical OR of all devices’ most recent button bits.
+	 * This button crosstalk should be filtered out as Synaptics and
+	 * generic mouse encode middle button presses in a different way.
+	 */
+	switch (pb->ipacket[0] & 0xc0) {
+	case 0x80:	/* First 3 bytes of Synaptics packet */
+		bcopy(pb->ipacket, sc->muxsave, 3);
+		/* Compute middle mouse button supression timeout. */
+		sc->muxmidtimeout.tv_sec  = 0;
+		sc->muxmidtimeout.tv_usec = 50000;	/* ~2-3 ints */
+		timevaladd(&sc->muxmidtimeout, &sc->lastsoftintr);
+		return (1);
+
+	case 0xc0:	/* Second 3 bytes of Synaptics packet */
+		/* Join two 3-bytes absolute packets */
+		bcopy(pb->ipacket, pb->ipacket + 3, 3);
+		bcopy(sc->muxsave, pb->ipacket, 3);
+		/* Prefer trackpoint buttons over touchpad's */
+		pb->ipacket[0] &= ~(0x08 | sc->muxmsbuttons);
+		pb->ipacket[3] &= ~(0x08 | sc->muxmsbuttons);
+		butt = (pb->ipacket[3] & 0x03) << 2 | (pb->ipacket[0] & 0x03);
+		/* Add hysteresis to remove spurious middle button events */
+		if (butt != sc->muxtpbuttons && sc->fpcount < 1) {
+			pb->ipacket[0] &= 0xfc;
+			pb->ipacket[0] |= sc->muxtpbuttons & 0x03;
+			pb->ipacket[3] &= 0xfc;
+			pb->ipacket[3] |= sc->muxtpbuttons >> 2 & 0x03;
+			++sc->fpcount;
+		} else {
+			sc->fpcount = 0;
+			sc->muxtpbuttons = butt;
+		}
+		/* Filter out impossible w induced by middle trackpoint btn */
+		if (sc->synhw.capExtended && !sc->synhw.capPassthrough &&
+		    (pb->ipacket[0] & 0x34) == 0x04 &&
+		    (pb->ipacket[3] & 0x04) == 0x04) {
+			pb->ipacket[0] &= 0xfb;
+			pb->ipacket[3] &= 0xfb;
+		}
+		sc->muxsave[0] &= 0x30;
+		break;
+
+	default:	/* Generic mouse (Trackpoint) packet */
+		/* Filter out middle button events induced by some w values */
+		if (sc->muxmsbuttons & 0x03 || pb->ipacket[0] & 0x03 ||
+		    (timevalcmp(&sc->lastsoftintr, &sc->muxmidtimeout, <=) &&
+		     (sc->muxsave[0] & 0x30 || sc->muxsave[2] > 8)))
+			pb->ipacket[0] &= 0xfb;
+		sc->muxmsbuttons = pb->ipacket[0] & 0x07;
+		/* Convert to Synaptics pass-through protocol */
+		pb->ipacket[4] = pb->ipacket[1];
+		pb->ipacket[5] = pb->ipacket[2];
+		pb->ipacket[1] = pb->ipacket[0];
+		pb->ipacket[2] = 0;
+		pb->ipacket[0] = 0x84 | (sc->muxtpbuttons & 0x03);
+		pb->ipacket[3] = 0xc4 | (sc->muxtpbuttons >> 2 & 0x03);
+	}
+
+	VLOG(4, (LOG_DEBUG, "synaptics: %02x %02x %02x %02x %02x %02x\n",
+	    pb->ipacket[0], pb->ipacket[1], pb->ipacket[2],
+	    pb->ipacket[3], pb->ipacket[4], pb->ipacket[5]));
+
+	pb->inputbytes = MOUSE_SYNAPTICS_PACKETSIZE;
+	return (0);
+}
+
+static int
 psmpalmdetect(struct psm_softc *sc, finger_t *f, int nfingers)
 {
 	if (!(
@@ -4929,6 +5024,10 @@ psmsoftintr(void *arg)
 			break;
 
 		case MOUSE_MODEL_SYNAPTICS:
+			if (pb->inputbytes == MOUSE_PS2_PACKETSIZE)
+				if (proc_synaptics_mux(sc, pb))
+					goto next;
+
 			if (proc_synaptics(sc, pb, &ms, &x, &y, &z) != 0) {
 				VLOG(3, (LOG_DEBUG, "synaptics: "
 				    "packet rejected\n"));
@@ -6039,7 +6138,61 @@ synaptics_set_mode(struct psm_softc *sc, int mode_byte
 	}
 }
 
+/*
+ * AUX MUX detection code should be placed at very beginning of probe sequence
+ * at least before 4-byte protocol mouse probes e.g. MS IntelliMouse probe as
+ * latter can trigger switching the MUX to incompatible state.
+ */
 static int
+enable_synaptics_mux(struct psm_softc *sc, enum probearg arg)
+{
+	KBDC kbdc = sc->kbdc;
+	int port, version;
+	int probe = FALSE;
+	int active_ports_count = 0;
+	int active_ports_mask = 0;
+
+	version = enable_aux_mux(kbdc);
+	if (version == -1)
+		return (FALSE);
+
+	for (port = 0; port < KBDC_AUX_MUX_NUM_PORTS; port++) {
+		VLOG(3, (LOG_DEBUG, "aux_mux: ping port %d\n", port));
+		set_active_aux_mux_port(kbdc, port);
+		if (enable_aux_dev(kbdc) && disable_aux_dev(kbdc)) {
+			active_ports_count++;
+			active_ports_mask |= 1 << port;
+		}
+	}
+
+	if (verbose >= 2)
+		printf("Active Multiplexing PS/2 controller v%d.%d with %d "
+		    "active port(s)\n", version >> 4 & 0x0f, version & 0x0f,
+		    active_ports_count);
+
+	/* psm has a special support for GenMouse + SynTouchpad combination */
+	if (active_ports_count >= 2) {
+		for (port = 0; port < KBDC_AUX_MUX_NUM_PORTS; port++) {
+			if ((active_ports_mask & 1 << port) == 0)
+				continue;
+			VLOG(3, (LOG_DEBUG, "aux_mux: probe port %d\n", port));
+			set_active_aux_mux_port(kbdc, port);
+			probe = enable_synaptics(sc, arg);
+			if (probe) {
+				if (arg == PROBE)
+					sc->muxport = port;
+				break;
+			}
+		}
+	}
+
+	/* IRQ handler does not support active multiplexing mode */
+	disable_aux_mux(kbdc);
+
+	return (probe);
+}
+
+static int
 enable_synaptics(struct psm_softc *sc, enum probearg arg)
 {
 	device_t psmcpnp;
@@ -6047,7 +6200,7 @@ enable_synaptics(struct psm_softc *sc, enum probearg a
 	KBDC kbdc = sc->kbdc;
 	synapticshw_t synhw;
 	int status[3];
-	int buttons, middle_byte;
+	int buttons;
 
 	VLOG(3, (LOG_DEBUG, "synaptics: BEGIN init\n"));
 
@@ -6064,8 +6217,7 @@ enable_synaptics(struct psm_softc *sc, enum probearg a
 		return (FALSE);
 	if (get_mouse_status(kbdc, status, 0, 3) != 3)
 		return (FALSE);
-	middle_byte = status[1];
-	if (middle_byte != 0x46 && middle_byte != 0x47)
+	if (status[1] != 0x47)
 		return (FALSE);
 
 	bzero(&synhw, sizeof(synhw));
@@ -6076,15 +6228,7 @@ enable_synaptics(struct psm_softc *sc, enum probearg a
 		printf("Synaptics Touchpad v%d.%d\n", synhw.infoMajor,
 		    synhw.infoMinor);
 
-	/*
-	 * 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)) {
+	if (synhw.infoMajor < 4) {
 		printf("  Unsupported (pre-v4) Touchpad detected\n");
 		return (FALSE);
 	}
@@ -6125,7 +6269,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] != middle_byte) {
+	if (!SYNAPTICS_VERSION_GE(synhw, 7, 5) && status[1] != 0x47) {
 		printf("  Failed to read extended capability bits\n");
 		return (FALSE);
 	}
@@ -6134,29 +6278,10 @@ 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;
-	if (synhw.capExtended && middle_byte == 0x47) {
+	synhw.capExtended = (status[0] & 0x80) != 0;
+	if (synhw.capExtended) {
 		synhw.nExtendedQueries = (status[0] & 0x70) >> 4;
 		synhw.capMiddle        = (status[0] & 0x04) != 0;
 		synhw.capPassthrough   = (status[2] & 0x80) != 0;
@@ -6278,8 +6403,12 @@ enable_synaptics(struct psm_softc *sc, enum probearg a
 				synhw.maximumYCoord = (status[2] << 5) |
 						     ((status[1] & 0xf0) >> 3);
 			} else {
-				synhw.maximumXCoord = SYNAPTICS_DEFAULT_MAX_X;
-				synhw.maximumYCoord = SYNAPTICS_DEFAULT_MAX_Y;
+				/*
+				 * Typical bezel limits. Taken from 'Synaptics
+				 * PS/2 * TouchPad Interfacing Guide' p.3.2.3.
+				 */
+				synhw.maximumXCoord = 5472;
+				synhw.maximumYCoord = 4448;
 			}
 
 			if (synhw.capReportsMin) {
@@ -6295,8 +6424,12 @@ enable_synaptics(struct psm_softc *sc, enum probearg a
 				synhw.minimumYCoord = (status[2] << 5) |
 						     ((status[1] & 0xf0) >> 3);
 			} else {
-				synhw.minimumXCoord = SYNAPTICS_DEFAULT_MIN_X;
-				synhw.minimumYCoord = SYNAPTICS_DEFAULT_MIN_Y;
+				/*
+				 * Typical bezel limits. Taken from 'Synaptics
+				 * PS/2 * TouchPad Interfacing Guide' p.3.2.3.
+				 */
+				synhw.minimumXCoord = 1472;
+				synhw.minimumYCoord = 1408;
 			}
 
 			/*
@@ -6382,7 +6515,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] != middle_byte) {
+	if (!SYNAPTICS_VERSION_GE(synhw, 7, 5) && status[1] != 0x47) {
 		printf("  Failed to read mode byte\n");
 		return (FALSE);
 	}
@@ -7205,12 +7338,6 @@ 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)
 {
@@ -7244,8 +7371,6 @@ 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?201901182111.x0ILB2RH024078>