From owner-dev-commits-src-main@freebsd.org Wed Jan 20 20:10:44 2021 Return-Path: Delivered-To: dev-commits-src-main@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 9AB924D88DB; Wed, 20 Jan 2021 20:10:44 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4DLc8h3YrSz3mT2; Wed, 20 Jan 2021 20:10:44 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 5F6281F26D; Wed, 20 Jan 2021 20:10:44 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 10KKAidO045064; Wed, 20 Jan 2021 20:10:44 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 10KKAiA6045063; Wed, 20 Jan 2021 20:10:44 GMT (envelope-from git) Date: Wed, 20 Jan 2021 20:10:44 GMT Message-Id: <202101202010.10KKAiA6045063@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Vladimir Kondratyev Subject: git: 3e954a8bc64e - main - hms: Workaround idle mouse drift in I2C sampling mode. MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: wulf X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 3e954a8bc64ebc21893eedba0f2f1159c242c9b6 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-main@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for the main branch of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 20 Jan 2021 20:10:44 -0000 The branch main has been updated by wulf: URL: https://cgit.FreeBSD.org/src/commit/?id=3e954a8bc64ebc21893eedba0f2f1159c242c9b6 commit 3e954a8bc64ebc21893eedba0f2f1159c242c9b6 Author: Vladimir Kondratyev AuthorDate: 2021-01-20 20:10:07 +0000 Commit: Vladimir Kondratyev CommitDate: 2021-01-20 20:10:07 +0000 hms: Workaround idle mouse drift in I2C sampling mode. Many I2C "compatibility" mouse devices found on touchpads continue to return last report data in sampling mode after touch has been ended. That results in cursor drift. Filter out such a reports with comparing content of current report with content of previous one. Reported by: many Tested by: omatsuda, gllb (github.com) Obtained from: sysutils/iichid --- sys/dev/hid/hms.c | 71 +++++++++++++++++++++++++++++++++++++++++++- sys/modules/hid/hms/Makefile | 1 + 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/sys/dev/hid/hms.c b/sys/dev/hid/hms.c index 7f3455ff2725..94267b3fcd52 100644 --- a/sys/dev/hid/hms.c +++ b/sys/dev/hid/hms.c @@ -32,6 +32,8 @@ __FBSDID("$FreeBSD$"); * HID spec: https://www.usb.org/sites/default/files/documents/hid1_11.pdf */ +#include "opt_hid.h" + #include #include #include @@ -65,6 +67,9 @@ enum { }; static hidmap_cb_t hms_final_cb; +#ifdef IICHID_SAMPLING +static hid_intr_t hms_intr; +#endif #define HMS_MAP_BUT_RG(usage_from, usage_to, code) \ { HIDMAP_KEY_RANGE(HUP_BUTTON, usage_from, usage_to, code) } @@ -110,8 +115,46 @@ static const struct hid_device_id hms_devs[] = { struct hms_softc { struct hidmap hm; HIDMAP_CAPS(caps, hms_map); +#ifdef IICHID_SAMPLING + bool iichid_sampling; + void *last_ir; + hid_size_t last_irsize; + hid_size_t isize; + uint32_t drift_cnt; + uint32_t drift_thresh; +#endif }; +#ifdef IICHID_SAMPLING +static void +hms_intr(void *context, void *buf, hid_size_t len) +{ + struct hidmap *hm = context; + struct hms_softc *sc = device_get_softc(hm->dev); + + if (len > sc->isize) + len = sc->isize; + + /* + * Many I2C "compatibility" mouse devices found on touchpads continue + * to return last report data in sampling mode even after touch has + * been ended. That results in cursor drift. Filter out such a + * reports through comparing with previous one. + */ + if (len == sc->last_irsize && memcmp(buf, sc->last_ir, len) == 0) { + sc->drift_cnt++; + if (sc->drift_thresh != 0 && sc->drift_cnt >= sc->drift_thresh) + return; + } else { + sc->drift_cnt = 0; + sc->last_irsize = len; + bcopy(buf, sc->last_ir, len); + } + + hidmap_intr(context, buf, len); +} +#endif + static int hms_final_cb(HIDMAP_CB_ARGS) { @@ -124,6 +167,11 @@ hms_final_cb(HIDMAP_CB_ARGS) evdev_support_prop(evdev, INPUT_PROP_DIRECT); else evdev_support_prop(evdev, INPUT_PROP_POINTER); +#ifdef IICHID_SAMPLING + /* Overload interrupt handler to skip identical reports */ + if (sc->iichid_sampling) + hidbus_set_intr(sc->hm.dev, hms_intr, &sc->hm); +#endif } /* Do not execute callback at interrupt handler and detach */ @@ -212,6 +260,21 @@ hms_attach(device_t dev) else HIDMAP_ADD_MAP(&sc->hm, hms_map_wheel, cap_wheel); +#ifdef IICHID_SAMPLING + if (hid_test_quirk(hw, HQ_IICHID_SAMPLING) && + hidmap_test_cap(sc->caps, HMS_REL_X) && + hidmap_test_cap(sc->caps, HMS_REL_Y)) { + sc->iichid_sampling = true; + sc->isize = hid_report_size_max(d_ptr, d_len, hid_input, NULL); + sc->last_ir = malloc(sc->isize, M_DEVBUF, M_WAITOK | M_ZERO); + sc->drift_thresh = 2; + SYSCTL_ADD_U32(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, + "drift_thresh", CTLFLAG_RW, &sc->drift_thresh, 0, + "drift detection threshhold"); + } +#endif + error = hidmap_attach(&sc->hm); if (error) return (error); @@ -243,8 +306,14 @@ static int hms_detach(device_t dev) { struct hms_softc *sc = device_get_softc(dev); + int error; - return (hidmap_detach(&sc->hm)); + error = hidmap_detach(&sc->hm); +#ifdef IICHID_SAMPLING + if (error == 0) + free(sc->last_ir, M_DEVBUF); +#endif + return (error); } static devclass_t hms_devclass; diff --git a/sys/modules/hid/hms/Makefile b/sys/modules/hid/hms/Makefile index 71fbd2a77b89..29514b86385b 100644 --- a/sys/modules/hid/hms/Makefile +++ b/sys/modules/hid/hms/Makefile @@ -4,6 +4,7 @@ KMOD= hms SRCS= hms.c +SRCS+= opt_hid.h SRCS+= bus_if.h device_if.h .include