Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 May 2017 22:47:18 +0000 (UTC)
From:      Vladimir Kondratyev <wulf@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r317811 - head/sys/dev/atkbdc
Message-ID:  <201705042247.v44MlI8H006040@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: wulf
Date: Thu May  4 22:47:18 2017
New Revision: 317811
URL: https://svnweb.freebsd.org/changeset/base/317811

Log:
  Fix triple-finger taps reported as double-finger for Elan hw v.4 touchpads
  
  Wait for all advertised head packets after status packet have been received.
  This fixes rare but quite annoying issue in Elan hw v.4 touchpads support
  when triple-finger taps are reported as double-finger taps under several
  circumstances.
  
  Reviewed by:	gonzo
  Approved by:	gonzo (mentor)
  MFC after:	2 weeks
  Differential Revision:	https://reviews.freebsd.org/D10266

Modified:
  head/sys/dev/atkbdc/psm.c

Modified: head/sys/dev/atkbdc/psm.c
==============================================================================
--- head/sys/dev/atkbdc/psm.c	Thu May  4 21:40:16 2017	(r317810)
+++ head/sys/dev/atkbdc/psm.c	Thu May  4 22:47:18 2017	(r317811)
@@ -366,6 +366,7 @@ enum {
 typedef struct elantechaction {
 	finger_t		fingers[ELANTECH_MAX_FINGERS];
 	int			mask;
+	int			mask_v4wait;
 } elantechaction_t;
 
 /* driver control block */
@@ -3879,9 +3880,15 @@ proc_elantech(struct psm_softc *sc, pack
 		mask = pb->ipacket[1] & 0x1f;
 		nfingers = bitcount(mask);
 
+		if (sc->elanaction.mask_v4wait != 0)
+			VLOG(3, (LOG_DEBUG, "elantech: HW v4 status packet"
+			    " when not all previous head packets received\n"));
+
+		/* Bitmap of fingers to receive before gesture processing */
+		sc->elanaction.mask_v4wait = mask & ~sc->elanaction.mask;
+
 		/* Skip "new finger is on touchpad" packets */
-		if ((sc->elanaction.mask & mask) == sc->elanaction.mask &&
-		    (mask & ~sc->elanaction.mask)) {
+		if (sc->elanaction.mask_v4wait) {
 			sc->elanaction.mask = mask;
 			return (0);
 		}
@@ -3906,11 +3913,33 @@ proc_elantech(struct psm_softc *sc, pack
 		mask = sc->elanaction.mask;
 		nfingers = bitcount(mask);
 		id = ((pb->ipacket[3] & 0xe0) >> 5) - 1;
+		fn = ELANTECH_FINGER_SET_XYP(pb);
+		fn.w =(pb->ipacket[0] & 0xf0) >> 4;
 
-		if (id >= 0 && id < ELANTECH_MAX_FINGERS) {
-			f[id] = ELANTECH_FINGER_SET_XYP(pb);
-			f[id].w = (pb->ipacket[0] & 0xf0) >> 4;
+		if (id < 0)
+			return (0);
+
+		/* Packet is finger position update. Report it */
+		if (sc->elanaction.mask_v4wait == 0) {
+			if (id < ELANTECH_MAX_FINGERS)
+				f[id] = fn;
+			break;
 		}
+
+		/* Remove finger from waiting bitmap and store into context */
+		sc->elanaction.mask_v4wait &= ~(1 << id);
+		if (id < ELANTECH_MAX_FINGERS)
+			sc->elanaction.fingers[id] = fn;
+
+		/* Wait for other fingers if needed */
+		if (sc->elanaction.mask_v4wait != 0)
+			return (0);
+
+		/* All new fingers are received. Report them from context */
+		for (id = 0; id < ELANTECH_MAX_FINGERS; id++)
+			if (sc->elanaction.mask & (1 << id))
+				f[id] =  sc->elanaction.fingers[id];
+
 		break;
 
 	case ELANTECH_PKT_V4_MOTION:	/* HW Version 4. Motion packet */



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