Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pckbport Fix for PR kern/56613



details:   https://anonhg.NetBSD.org/src/rev/fe93a63822b6
branches:  trunk
changeset: 362598:fe93a63822b6
user:      blymn <blymn%NetBSD.org@localhost>
date:      Thu Mar 03 21:03:14 2022 +0000

description:
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.

diffstat:

 sys/dev/pckbport/synaptics.c    |  90 ++++++++++++++++++++++++++++++++++++++++-
 sys/dev/pckbport/synapticsreg.h |   4 +-
 sys/dev/pckbport/synapticsvar.h |   4 +-
 3 files changed, 94 insertions(+), 4 deletions(-)

diffs (175 lines):

diff -r d3b7060b8e18 -r fe93a63822b6 sys/dev/pckbport/synaptics.c
--- a/sys/dev/pckbport/synaptics.c      Thu Mar 03 20:20:23 2022 +0000
+++ b/sys/dev/pckbport/synaptics.c      Thu Mar 03 21:03:14 2022 +0000
@@ -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 @@
 
                        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 @@
        { 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 @@
                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 @@
                        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 @@
                        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);
 
diff -r d3b7060b8e18 -r fe93a63822b6 sys/dev/pckbport/synapticsreg.h
--- a/sys/dev/pckbport/synapticsreg.h   Thu Mar 03 20:20:23 2022 +0000
+++ b/sys/dev/pckbport/synapticsreg.h   Thu Mar 03 21:03:14 2022 +0000
@@ -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 */
diff -r d3b7060b8e18 -r fe93a63822b6 sys/dev/pckbport/synapticsvar.h
--- a/sys/dev/pckbport/synapticsvar.h   Thu Mar 03 20:20:23 2022 +0000
+++ b/sys/dev/pckbport/synapticsvar.h   Thu Mar 03 21:03:14 2022 +0000
@@ -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 @@
 #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;



Home | Main Index | Thread Index | Old Index