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>