Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pckbport PR/48831: J?rg Grundmann: Synaptics Touch p...



details:   https://anonhg.NetBSD.org/src/rev/878d2dc1b4ba
branches:  trunk
changeset: 329397:878d2dc1b4ba
user:      christos <christos%NetBSD.org@localhost>
date:      Fri May 23 01:11:29 2014 +0000

description:
PR/48831: J?rg Grundmann: Synaptics Touch pad (ClickPad) and
Klick-by-tap-gestures do not work

diffstat:

 sys/dev/pckbport/synaptics.c    |  187 +++++++++++++++++++++++++++++++--------
 sys/dev/pckbport/synapticsreg.h |   58 ++++++-----
 sys/dev/pckbport/synapticsvar.h |   21 ++-
 3 files changed, 193 insertions(+), 73 deletions(-)

diffs (truncated from 404 to 300 lines):

diff -r b4bf9cf4ed5f -r 878d2dc1b4ba sys/dev/pckbport/synaptics.c
--- a/sys/dev/pckbport/synaptics.c      Fri May 23 00:02:14 2014 +0000
+++ b/sys/dev/pckbport/synaptics.c      Fri May 23 01:11:29 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: synaptics.c,v 1.31 2014/02/25 18:30:10 pooka Exp $     */
+/*     $NetBSD: synaptics.c,v 1.32 2014/05/23 01:11:29 christos 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.31 2014/02/25 18:30:10 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: synaptics.c,v 1.32 2014/05/23 01:11:29 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -131,6 +131,93 @@
 static int synaptics_max_speed_y_nodenum;
 static int synaptics_movement_threshold_nodenum;
 
+static void
+pms_synaptics_probe_extended(struct pms_softc *psc)
+{
+       struct synaptics_softc *sc = &psc->u.synaptics;
+       u_char cmd[1], resp[3];
+       int res;
+
+       aprint_debug_dev(psc->sc_dev,
+           "synaptics_probe: Capabilities 0x%04x.\n", sc->caps);
+       if (sc->caps & SYNAPTICS_CAP_PASSTHROUGH)
+               sc->flags |= SYN_FLAG_HAS_PASSTHROUGH;
+
+       if (sc->caps & SYNAPTICS_CAP_PALMDETECT)
+               sc->flags |= SYN_FLAG_HAS_PALM_DETECT;
+
+       if (sc->caps & SYNAPTICS_CAP_MULTIDETECT)
+               sc->flags |= SYN_FLAG_HAS_MULTI_FINGER;
+
+       if (sc->caps & SYNAPTICS_CAP_MULTIFINGERREPORT)
+               sc->flags |= SYN_FLAG_HAS_MULTI_FINGER_REPORT;
+
+       /* Ask about extra buttons to detect up/down. */
+       if (((sc->caps & SYNAPTICS_CAP_EXTNUM) + 0x08)
+           >= SYNAPTICS_EXTENDED_QUERY)
+       {
+               res = pms_sliced_command(psc->sc_kbctag,
+                   psc->sc_kbcslot, SYNAPTICS_EXTENDED_QUERY);
+               cmd[0] = PMS_SEND_DEV_STATUS;
+               res |= pckbport_poll_cmd(psc->sc_kbctag,
+                   psc->sc_kbcslot, cmd, 1, 3, resp, 0);
+               if (res == 0) {
+                       int buttons = (resp[1] >> 4);
+                       aprint_debug_dev(psc->sc_dev,
+                           "%s: Extended Buttons: %d.\n", __func__, buttons);
+
+                       aprint_debug_dev(psc->sc_dev, "%s: Extended "
+                           "Capabilities: 0x%02x 0x%02x 0x%02x.\n", __func__,
+                           resp[0], resp[1], resp[2]);
+                       if (buttons >= 2) {
+                               /* Yes. */
+                               sc->flags |= SYN_FLAG_HAS_UP_DOWN_BUTTONS;
+                       }
+                       if (resp[0] & 0x1) {
+                               /* Vertical scroll area */
+                               sc->flags |= SYN_FLAG_HAS_VERTICAL_SCROLL;
+                       }
+                       if (resp[0] & 0x2) {
+                               /* Horizontal scroll area */
+                               sc->flags |= SYN_FLAG_HAS_HORIZONTAL_SCROLL;
+                       }
+                       if (resp[0] & 0x4) {
+                               /* Extended W-Mode */
+                               sc->flags |= SYN_FLAG_HAS_EXTENDED_WMODE;
+                       }
+               }
+       }
+
+       /* Ask about click pad */
+       if (((sc->caps & SYNAPTICS_CAP_EXTNUM) + 0x08) >=
+           SYNAPTICS_CONTINUED_CAPABILITIES)
+       {
+               res = pms_sliced_command(psc->sc_kbctag,
+                   psc->sc_kbcslot, SYNAPTICS_CONTINUED_CAPABILITIES);
+               cmd[0] = PMS_SEND_DEV_STATUS;
+               res |= pckbport_poll_cmd(psc->sc_kbctag,
+                   psc->sc_kbcslot, cmd, 1, 3, resp, 0);
+               if (res == 0) {
+                       u_char clickpad_type = (resp[1] & 0x1);
+                       clickpad_type |= ((resp[0] >> 4) & 0x1);
+
+                       aprint_debug_dev(psc->sc_dev, "%s: Continued "
+                           "Capabilities 0x%02x 0x%02x 0x%02x.\n", __func__,
+                           resp[0], resp[1], resp[2]);
+                       switch (clickpad_type) {
+                       case 1:
+                               sc->flags |= SYN_FLAG_HAS_ONE_BUTTON_CLICKPAD;
+                               break;
+                       case 2:
+                               sc->flags |= SYN_FLAG_HAS_TWO_BUTTON_CLICKPAD;
+                               break;
+                       default:
+                               break;
+                       }
+               }
+       }
+}
+
 int
 pms_synaptics_probe_init(void *vsc)
 {
@@ -200,39 +287,17 @@
                sc->flags |= SYN_FLAG_HAS_BUTTONS_4_5;
 
        if (sc->caps & SYNAPTICS_CAP_EXTENDED) {
-               aprint_debug_dev(psc->sc_dev,
-                   "synaptics_probe: Capabilities 0x%04x.\n", sc->caps);
-               if (sc->caps & SYNAPTICS_CAP_PASSTHROUGH)
-                       sc->flags |= SYN_FLAG_HAS_PASSTHROUGH;
-
-               if (sc->caps & SYNAPTICS_CAP_PALMDETECT)
-                       sc->flags |= SYN_FLAG_HAS_PALM_DETECT;
-
-               if (sc->caps & SYNAPTICS_CAP_MULTIDETECT)
-                       sc->flags |= SYN_FLAG_HAS_MULTI_FINGER;
-
-               /* Ask about extra buttons to detect up/down. */
-               if (sc->caps & SYNAPTICS_CAP_EXTNUM) {
-                       res = pms_sliced_command(psc->sc_kbctag,
-                           psc->sc_kbcslot, SYNAPTICS_EXTENDED_QUERY);
-                       cmd[0] = PMS_SEND_DEV_STATUS;
-                       res |= pckbport_poll_cmd(psc->sc_kbctag,
-                           psc->sc_kbcslot, cmd, 1, 3, resp, 0);
-                       if (res == 0)
-                               aprint_debug_dev(psc->sc_dev,
-                                   "synaptics_probe: Extended "
-                                   "Capabilities 0x%02x.\n", resp[1]);
-                       if (!res && (resp[1] >> 4) >= 2) {
-                               /* Yes. */
-                               sc->flags |= SYN_FLAG_HAS_UP_DOWN_BUTTONS;
-                       }
-               }
+               pms_synaptics_probe_extended(psc);
        }
 
        if (sc->flags) {
                const char comma[] = ", ";
                const char *sep = "";
                aprint_normal_dev(psc->sc_dev, "");
+               if (sc->flags & SYN_FLAG_HAS_EXTENDED_WMODE) {
+                       aprint_normal("%sExtended W mode", sep);
+                       sep = comma;
+               }
                if (sc->flags & SYN_FLAG_HAS_PASSTHROUGH) {
                        aprint_normal("%sPassthrough", sep);
                        sep = comma;
@@ -253,6 +318,26 @@
                        aprint_normal("%sPalm detect", sep);
                        sep = comma;
                }
+               if (sc->flags & SYN_FLAG_HAS_ONE_BUTTON_CLICKPAD) {
+                       aprint_normal("%sOne button click pad", sep);
+                       sep = comma;
+               }
+               if (sc->flags & SYN_FLAG_HAS_TWO_BUTTON_CLICKPAD) {
+                       aprint_normal("%sTwo button click pad", sep);
+                       sep = comma;
+               }
+               if (sc->flags & SYN_FLAG_HAS_VERTICAL_SCROLL) {
+                       aprint_normal("%sVertical scroll", sep);
+                       sep = comma;
+               }
+               if (sc->flags & SYN_FLAG_HAS_HORIZONTAL_SCROLL) {
+                       aprint_normal("%sHorizontal scroll", sep);
+                       sep = comma;
+               }
+               if (sc->flags & SYN_FLAG_HAS_MULTI_FINGER_REPORT) {
+                       aprint_normal("%sMulti-finger Report", sep);
+                       sep = comma;
+               }
                if (sc->flags & SYN_FLAG_HAS_MULTI_FINGER)
                        aprint_normal("%sMulti-finger", sep);
 
@@ -276,7 +361,7 @@
        int res;
 
        if (sc->flags & SYN_FLAG_HAS_PASSTHROUGH) {
-               /* 
+               /*
                 * Extended capability probes can confuse the passthrough device;
                 * reset the touchpad now to cure that.
                 */
@@ -621,6 +706,8 @@
        struct synaptics_softc *sc = &psc->u.synaptics;
        struct synaptics_packet sp;
 
+       memset(&sp, 0, sizeof(sp));
+
        /* Absolute X/Y coordinates of finger */
        sp.sp_x = psc->packet[4] + ((psc->packet[1] & 0x0f) << 8) +
           ((psc->packet[3] & 0x10) << 8);
@@ -658,6 +745,12 @@
                sp.sp_down = 0;
        }
 
+       if(sc->flags & SYN_FLAG_HAS_ONE_BUTTON_CLICKPAD) {
+               /* This is not correctly specified. Read this button press
+                * from L/U bit.
+                */
+               sp.sp_left = ((psc->packet[0] ^ psc->packet[3]) & 0x01) ? 1 : 0;
+       } else
        /* Middle button. */
        if (sc->flags & SYN_FLAG_HAS_MIDDLE_BUTTON) {
                /* Old style Middle Button. */
@@ -861,12 +954,17 @@
 synaptics_gesture_detect(struct synaptics_softc *sc,
     struct synaptics_packet *sp, int fingers)
 {
-       int gesture_len, gesture_move_x, gesture_move_y, gesture_buttons;
+       int gesture_len, gesture_buttons;
        int set_buttons;
 
        gesture_len = SYN_TIME(sc, sc->gesture_start_packet);
        gesture_buttons = sc->gesture_buttons;
 
+       if (fingers > 0 && (fingers == sc->prev_fingers)) {
+               /* Finger is still present */
+               sc->gesture_move_x = abs(sc->gesture_start_x - sp->sp_x);
+               sc->gesture_move_y = abs(sc->gesture_start_y - sp->sp_y);
+       } else
        if (fingers && sc->prev_fingers == 0) {
                /*
                 * Finger was just applied.
@@ -880,9 +978,16 @@
                if (SYN_IS_SINGLE_TAP(sc->gesture_type))
                        sc->gesture_type |= SYN_GESTURE_DRAG;
 
-               sc->gesture_start_x = sp->sp_x;
-               sc->gesture_start_y = sp->sp_y;
+               sc->gesture_start_x = abs(sp->sp_x);
+               sc->gesture_start_y = abs(sp->sp_y);
+               sc->gesture_move_x = 0;
+               sc->gesture_move_y = 0;
                sc->gesture_start_packet = sc->total_packets;
+
+#ifdef DIAGNOSTIC
+               aprint_debug("Finger applied: gesture_start_x: %d gesture_start_y: %d\n",
+                       sc->gesture_start_x, sc->gesture_start_y);
+#endif
        } else
        if (fingers == 0 && sc->prev_fingers != 0) {
                /*
@@ -893,13 +998,19 @@
                 * detected (the pad may report coordinates for any
                 * of the fingers).
                 */
-               gesture_move_x = abs(sc->gesture_start_x - sp->sp_x);
-               gesture_move_y = abs(sc->gesture_start_y - sp->sp_y);
+
+#ifdef DIAGNOSTIC
+               aprint_debug("Finger removed: gesture_len: %d (%d)\n",
+                       gesture_len, synaptics_gesture_length);
+               aprint_debug("gesture_move_x: %d (%d) sp_x: %d\n",
+                       sc->gesture_move_x, synaptics_gesture_move, abs(sp->sp_x));
+               aprint_debug("gesture_move_y: %d (%d) sp_y: %d\n",
+                       sc->gesture_move_y, synaptics_gesture_move, abs(sp->sp_y));
+#endif
 
                if (gesture_len < synaptics_gesture_length &&
-                   (sc->prev_fingers > 1 ||
-                   (gesture_move_x < synaptics_gesture_move &&
-                    gesture_move_y < synaptics_gesture_move))) {
+                   ((sc->gesture_move_x < synaptics_gesture_move &&
+                    sc->gesture_move_y < synaptics_gesture_move))) {
                        /*
                         * Looking good so far.
                         */
diff -r b4bf9cf4ed5f -r 878d2dc1b4ba sys/dev/pckbport/synapticsreg.h
--- a/sys/dev/pckbport/synapticsreg.h   Fri May 23 00:02:14 2014 +0000
+++ b/sys/dev/pckbport/synapticsreg.h   Fri May 23 01:11:29 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: synapticsreg.h,v 1.7 2011/09/10 18:38:20 jakllsch Exp $        */
+/*     $NetBSD: synapticsreg.h,v 1.8 2014/05/23 01:11:29 christos Exp $        */
 
 /*
  * Copyright (c) 2005, Steve C. Woodford
@@ -35,45 +35,47 @@
  *
  */
 
-#ifndef _DEV_PCKBCPORT_SYNAPTICSREG_H_
-#define _DEV_PCKBCPORT_SYNAPTICSREG_H_
+#ifndef        _DEV_PCKBCPORT_SYNAPTICSREG_H_
+#define        _DEV_PCKBCPORT_SYNAPTICSREG_H_
 
 /* Synaptics information queries. */
-#define SYNAPTICS_IDENTIFY_TOUCHPAD    0x0
-#define SYNAPTICS_READ_MODE            0x1
-#define SYNAPTICS_READ_CAPABILITIES    0x2



Home | Main Index | Thread Index | Old Index