svn commit: r317811 - head/sys/dev/atkbdc
Vladimir Kondratyev
wulf at FreeBSD.org
Thu May 4 22:47:19 UTC 2017
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 */
More information about the svn-src-head
mailing list