PR/48831: Jörg Grundmann: Synaptics Touch pad (ClickPad) and
Klick-by-tap-gestures do not work
This commit is contained in:
parent
92bd82246b
commit
ef2e77d3d6
|
@ -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_x_nodenum;
|
|||
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 @@ pms_synaptics_probe_init(void *vsc)
|
|||
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 @@ pms_synaptics_probe_init(void *vsc)
|
|||
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 @@ pms_synaptics_enable(void *vsc)
|
|||
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 @@ pms_synaptics_parse(struct pms_softc *psc)
|
|||
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 @@ pms_synaptics_parse(struct pms_softc *psc)
|
|||
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 @@ static inline void
|
|||
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 @@ synaptics_gesture_detect(struct synaptics_softc *sc,
|
|||
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 @@ synaptics_gesture_detect(struct synaptics_softc *sc,
|
|||
* 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.
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
#define SYNAPTICS_READ_MODEL_ID 0x3
|
||||
#define SYNAPTICS_EXTENDED_QUERY 0x9
|
||||
#define SYNAPTICS_IDENTIFY_TOUCHPAD 0x0
|
||||
#define SYNAPTICS_READ_MODE 0x1
|
||||
#define SYNAPTICS_READ_CAPABILITIES 0x2
|
||||
#define SYNAPTICS_READ_MODEL_ID 0x3
|
||||
#define SYNAPTICS_EXTENDED_QUERY 0x9
|
||||
#define SYNAPTICS_CONTINUED_CAPABILITIES 0x0c
|
||||
|
||||
/* Synaptics special commands */
|
||||
#define SYNAPTICS_CMD_SET_MODE2 0x14
|
||||
#define SYNAPTICS_CMD_CLIENT_CMD 0x28
|
||||
#define SYNAPTICS_CMD_SET_MODE2 0x14
|
||||
#define SYNAPTICS_CMD_CLIENT_CMD 0x28
|
||||
|
||||
/* Magic numbers. */
|
||||
#define SYNAPTICS_MIN_VERSION 45 /* 4.5 */
|
||||
#define SYNAPTICS_MAGIC_BYTE 0x47
|
||||
#define SYNAPTICS_MIN_VERSION 45 /* 4.5 */
|
||||
#define SYNAPTICS_MAGIC_BYTE 0x47
|
||||
|
||||
/* Capability bits. */
|
||||
#define SYNAPTICS_CAP_EXTENDED (1 << 15)
|
||||
#define SYNAPTICS_CAP_EXTNUM (1 << 14 | 1 << 13 | 1 << 12)
|
||||
#define SYNAPTICS_CAP_MBUTTON (1 << 10)
|
||||
#define SYNAPTICS_CAP_PASSTHROUGH (1 << 7)
|
||||
#define SYNAPTICS_CAP_SLEEP (1 << 4)
|
||||
#define SYNAPTICS_CAP_4BUTTON (1 << 3)
|
||||
#define SYNAPTICS_CAP_MULTIDETECT (1 << 1)
|
||||
#define SYNAPTICS_CAP_PALMDETECT (1 << 0)
|
||||
#define SYNAPTICS_CAP_EXTENDED (1 << 15)
|
||||
#define SYNAPTICS_CAP_EXTNUM (1 << 14 | 1 << 13 | 1 << 12)
|
||||
#define SYNAPTICS_CAP_MBUTTON (1 << 10)
|
||||
#define SYNAPTICS_CAP_PASSTHROUGH (1 << 7)
|
||||
#define SYNAPTICS_CAP_MULTIFINGERREPORT (1 << 5)
|
||||
#define SYNAPTICS_CAP_SLEEP (1 << 4)
|
||||
#define SYNAPTICS_CAP_4BUTTON (1 << 3)
|
||||
#define SYNAPTICS_CAP_MULTIDETECT (1 << 1)
|
||||
#define SYNAPTICS_CAP_PALMDETECT (1 << 0)
|
||||
|
||||
/* Mode bits. */
|
||||
#define SYNAPTICS_MODE_ABSOLUTE (1 << 7)
|
||||
#define SYNAPTICS_MODE_RATE (1 << 6)
|
||||
#define SYNAPTICS_MODE_SLEEP (1 << 3)
|
||||
#define SYNAPTICS_MODE_GEST (1 << 2)
|
||||
#define SYNAPTICS_MODE_4BYTE_CLIENT (1 << 1)
|
||||
#define SYNAPTICS_MODE_W (1)
|
||||
#define SYNAPTICS_MODE_ABSOLUTE (1 << 7)
|
||||
#define SYNAPTICS_MODE_RATE (1 << 6)
|
||||
#define SYNAPTICS_MODE_SLEEP (1 << 3)
|
||||
#define SYNAPTICS_MODE_GEST (1 << 2)
|
||||
#define SYNAPTICS_MODE_4BYTE_CLIENT (1 << 1)
|
||||
#define SYNAPTICS_MODE_W (1)
|
||||
|
||||
/* Extended mode button masks. */
|
||||
#define SYN_1BUTMASK 0x1
|
||||
#define SYN_2BUTMASK 0x1
|
||||
#define SYN_1BUTMASK 0x1
|
||||
#define SYN_2BUTMASK 0x1
|
||||
|
||||
/* Touchpad edge boundaries (Recommended values from Synaptics documentation) */
|
||||
#define SYNAPTICS_EDGE_LEFT 1632
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: synapticsvar.h,v 1.5 2011/09/10 18:38:20 jakllsch Exp $ */
|
||||
/* $NetBSD: synapticsvar.h,v 1.6 2014/05/23 01:11:29 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005, Steve C. Woodford
|
||||
|
@ -42,12 +42,18 @@ struct synaptics_softc {
|
|||
int caps;
|
||||
|
||||
int flags;
|
||||
#define SYN_FLAG_HAS_MIDDLE_BUTTON (1 << 0)
|
||||
#define SYN_FLAG_HAS_BUTTONS_4_5 (1 << 1)
|
||||
#define SYN_FLAG_HAS_UP_DOWN_BUTTONS (1 << 2)
|
||||
#define SYN_FLAG_HAS_PASSTHROUGH (1 << 3)
|
||||
#define SYN_FLAG_HAS_PALM_DETECT (1 << 4)
|
||||
#define SYN_FLAG_HAS_MULTI_FINGER (1 << 5)
|
||||
#define SYN_FLAG_HAS_MIDDLE_BUTTON (1 << 0)
|
||||
#define SYN_FLAG_HAS_BUTTONS_4_5 (1 << 1)
|
||||
#define SYN_FLAG_HAS_UP_DOWN_BUTTONS (1 << 2)
|
||||
#define SYN_FLAG_HAS_PASSTHROUGH (1 << 3)
|
||||
#define SYN_FLAG_HAS_PALM_DETECT (1 << 4)
|
||||
#define SYN_FLAG_HAS_MULTI_FINGER (1 << 5)
|
||||
#define SYN_FLAG_HAS_MULTI_FINGER_REPORT (1 << 6)
|
||||
#define SYN_FLAG_HAS_VERTICAL_SCROLL (1 << 7)
|
||||
#define SYN_FLAG_HAS_HORIZONTAL_SCROLL (1 << 8)
|
||||
#define SYN_FLAG_HAS_ONE_BUTTON_CLICKPAD (1 << 9)
|
||||
#define SYN_FLAG_HAS_TWO_BUTTON_CLICKPAD (1 << 10)
|
||||
#define SYN_FLAG_HAS_EXTENDED_WMODE (1 << 11)
|
||||
|
||||
u_int total_packets; /* Total number of packets received */
|
||||
#define SYN_TIME(sc,c) (((sc)->total_packets >= (c)) ? \
|
||||
|
@ -58,6 +64,7 @@ struct synaptics_softc {
|
|||
int prev_fingers;
|
||||
|
||||
int gesture_start_x, gesture_start_y;
|
||||
int gesture_move_x, gesture_move_y;
|
||||
u_int gesture_start_packet;
|
||||
u_int gesture_tap_packet;
|
||||
|
||||
|
|
Loading…
Reference in New Issue