Module Name: src Committed By: blymn Date: Thu Mar 3 21:03:14 UTC 2022
Modified Files: src/sys/dev/pckbport: synaptics.c synapticsreg.h synapticsvar.h Log Message: Fix for PR kern/56613 * For trackpads that report max and min coordinates, retrieve these and use them as the boundaries instead of the hard coded limits. * Drop packets that are have x/y values that are outside the limits of the trackpad. Some trackpads report a stream of low values in some situations that cause cursor jumping. To generate a diff of this commit: cvs rdiff -u -r1.75 -r1.76 src/sys/dev/pckbport/synaptics.c cvs rdiff -u -r1.12 -r1.13 src/sys/dev/pckbport/synapticsreg.h \ src/sys/dev/pckbport/synapticsvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pckbport/synaptics.c diff -u src/sys/dev/pckbport/synaptics.c:1.75 src/sys/dev/pckbport/synaptics.c:1.76 --- src/sys/dev/pckbport/synaptics.c:1.75 Sat Dec 4 14:53:56 2021 +++ src/sys/dev/pckbport/synaptics.c Thu Mar 3 21:03:14 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: synaptics.c,v 1.75 2021/12/04 14:53:56 nia Exp $ */ +/* $NetBSD: synaptics.c,v 1.76 2022/03/03 21:03:14 blymn Exp $ */ /* * Copyright (c) 2005, Steve C. Woodford @@ -48,7 +48,7 @@ #include "opt_pms.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: synaptics.c,v 1.75 2021/12/04 14:53:56 nia Exp $"); +__KERNEL_RCSID(0, "$NetBSD: synaptics.c,v 1.76 2022/03/03 21:03:14 blymn Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -342,6 +342,12 @@ pms_synaptics_probe_extended(struct pms_ if ((val & SYN_CCAP_HAS_ADV_GESTURE_MODE)) sc->flags |= SYN_FLAG_HAS_ADV_GESTURE_MODE; + + if ((val & SYN_CCAP_REPORT_MAX)) + sc->flags |= SYN_FLAG_HAS_MAX_REPORT; + + if ((val & SYN_CCAP_REPORT_MIN)) + sc->flags |= SYN_FLAG_HAS_MIN_REPORT; } } } @@ -362,6 +368,8 @@ static const struct { { SYN_FLAG_HAS_HORIZONTAL_SCROLL, "Horizontal scroll", }, { SYN_FLAG_HAS_MULTI_FINGER_REPORT, "Multi-finger Report", }, { SYN_FLAG_HAS_MULTI_FINGER, "Multi-finger", }, + { SYN_FLAG_HAS_MAX_REPORT, "Reports max", }, + { SYN_FLAG_HAS_MIN_REPORT, "Reports min", }, }; int @@ -444,6 +452,42 @@ pms_synaptics_probe_init(void *vsc) aprint_normal("\n"); } + if (sc->flags & SYN_FLAG_HAS_MAX_REPORT) { + res = synaptics_special_read(psc, SYNAPTICS_READ_MAX_COORDS, + resp); + if (res) { + aprint_error_dev(psc->sc_dev, + "synaptics_probe: Failed to query max coords.\n"); + } else { + synaptics_edge_right = (resp[0] << 5) + + ((resp[1] & 0x0f) << 1); + synaptics_edge_top = (resp[2] << 5) + + ((resp[1] & 0xf0) >> 3); + + aprint_normal_dev(psc->sc_dev, + "Probed max coordinates right: %d, top: %d\n", + synaptics_edge_right, synaptics_edge_top); + } + } + + if (sc->flags & SYN_FLAG_HAS_MIN_REPORT) { + res = synaptics_special_read(psc, SYNAPTICS_READ_MIN_COORDS, + resp); + if (res) { + aprint_error_dev(psc->sc_dev, + "synaptics_probe: Failed to query min coords.\n"); + } else { + synaptics_edge_left = (resp[0] << 5) + + ((resp[1] & 0x0f) << 1); + synaptics_edge_bottom = (resp[2] << 5) + + ((resp[1] & 0xf0) >> 3); + + aprint_normal_dev(psc->sc_dev, + "Probed min coordinates left: %d, bottom: %d\n", + synaptics_edge_left, synaptics_edge_bottom); + } + } + done: pms_sysctl_synaptics(&clog); pckbport_set_inputhandler(psc->sc_kbctag, psc->sc_kbcslot, @@ -1068,6 +1112,27 @@ pms_synaptics_parse(struct pms_softc *ps nsp.sp_sz = (psc->packet[3] & 0x30) + ((psc->packet[5] & 0x0e) << 1); + /* + * Check if the x and y are non-zero that they + * are within the bounds of the trackpad + * otherwise ignore the packet. + */ + if (((nsp.sp_sx != 0) && + ((nsp.sp_sx < synaptics_edge_left) || + (nsp.sp_sx > synaptics_edge_right))) || + ((nsp.sp_sy != 0) && + ((nsp.sp_sy < synaptics_edge_bottom) || + (nsp.sp_sy > synaptics_edge_top)))) { + sc->gesture_type = 0; + sc->gesture_buttons = 0; + sc->total_packets--; + DPRINTF(20, sc, + "synaptics_parse: dropping out of bounds " + "packet sp_sx %d sp_sy %d\n", + nsp.sp_sx, nsp.sp_sy); + return; + } + /* work out the virtual finger width */ v = 8 + (psc->packet[1] & 0x01) + ((psc->packet[2] & 0x01) << 1) + @@ -1152,6 +1217,27 @@ pms_synaptics_parse(struct pms_softc *ps nsp.sp_z = psc->packet[2]; } + /* + * Check if the x and y are non-zero that they + * are within the bounds of the trackpad + * otherwise ignore the packet. + */ + if (((nsp.sp_x != 0) && + ((nsp.sp_x < synaptics_edge_left) || + (nsp.sp_x > synaptics_edge_right))) || + ((nsp.sp_y != 0) && + ((nsp.sp_y < synaptics_edge_bottom) || + (nsp.sp_y > synaptics_edge_top)))) { + sc->gesture_type = 0; + sc->gesture_buttons = 0; + sc->total_packets--; + DPRINTF(20, sc, + "synaptics_parse: dropping out of bounds packet " + "sp_x %d sp_y %d\n", + nsp.sp_x, nsp.sp_y); + return; + } + nsp.sp_finger_count = pms_synaptics_get_fingers(psc, nsp.sp_w, nsp.sp_z); Index: src/sys/dev/pckbport/synapticsreg.h diff -u src/sys/dev/pckbport/synapticsreg.h:1.12 src/sys/dev/pckbport/synapticsreg.h:1.13 --- src/sys/dev/pckbport/synapticsreg.h:1.12 Sun Jun 2 08:55:00 2019 +++ src/sys/dev/pckbport/synapticsreg.h Thu Mar 3 21:03:14 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: synapticsreg.h,v 1.12 2019/06/02 08:55:00 blymn Exp $ */ +/* $NetBSD: synapticsreg.h,v 1.13 2022/03/03 21:03:14 blymn Exp $ */ /* * Copyright (c) 2005, Steve C. Woodford @@ -45,6 +45,8 @@ #define SYNAPTICS_READ_MODEL_ID 0x3 #define SYNAPTICS_EXTENDED_QUERY 0x9 #define SYNAPTICS_CONTINUED_CAPABILITIES 0x0c +#define SYNAPTICS_READ_MAX_COORDS 0x0d +#define SYNAPTICS_READ_MIN_COORDS 0x0f #define SYNAPTICS_WRITE_DELUXE_3 0xc8 /* 6.2.3. Deluxe mode setting sequence */ /* Synaptics special commands */ Index: src/sys/dev/pckbport/synapticsvar.h diff -u src/sys/dev/pckbport/synapticsvar.h:1.12 src/sys/dev/pckbport/synapticsvar.h:1.13 --- src/sys/dev/pckbport/synapticsvar.h:1.12 Thu Oct 21 04:49:28 2021 +++ src/sys/dev/pckbport/synapticsvar.h Thu Mar 3 21:03:14 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: synapticsvar.h,v 1.12 2021/10/21 04:49:28 blymn Exp $ */ +/* $NetBSD: synapticsvar.h,v 1.13 2022/03/03 21:03:14 blymn Exp $ */ /* * Copyright (c) 2005, Steve C. Woodford @@ -59,6 +59,8 @@ struct synaptics_softc { #define SYN_FLAG_HAS_TWO_BUTTON_CLICKPAD (1 << 10) #define SYN_FLAG_HAS_EXTENDED_WMODE (1 << 11) #define SYN_FLAG_HAS_ADV_GESTURE_MODE (1 << 12) +#define SYN_FLAG_HAS_MAX_REPORT (1 << 13) +#define SYN_FLAG_HAS_MIN_REPORT (1 << 14) /* Total number of packets received */ u_int total_packets;