summaryrefslogtreecommitdiff
path: root/sys/dev/pckbc/pms.c
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2015-03-26 01:30:23 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2015-03-26 01:30:23 +0000
commit48729bf69dcd4670ba8aee95f240b5d27e29772a (patch)
treeff97f6633ad796ae1964230a0bcd2a33f35c8632 /sys/dev/pckbc/pms.c
parent460ab578443f59ae1e9050049235ddee1dcbd9c9 (diff)
Use the 0x10 extended capability to determine if the trackstick
buttons are wired to the trackpad and need to be re-routed to the trackstick. Without this change the buttons on 2015 thinkpads get picked up as extended buttons that show up as scroll up/down. Remove the X1 Carbon 2015 (LEN0048) and X250 (LEN0046) from the top button area/soft buttons quirks list. Also avoid using the quirk list entirely if the capability bit is set. Based on work from jcs@ with feedback from mpi@ ok mpi@ jcs@
Diffstat (limited to 'sys/dev/pckbc/pms.c')
-rw-r--r--sys/dev/pckbc/pms.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/sys/dev/pckbc/pms.c b/sys/dev/pckbc/pms.c
index fdffa119241..60da6e43e66 100644
--- a/sys/dev/pckbc/pms.c
+++ b/sys/dev/pckbc/pms.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pms.c,v 1.57 2015/02/09 04:05:25 mpi Exp $ */
+/* $OpenBSD: pms.c,v 1.58 2015/03/26 01:30:22 jsg Exp $ */
/* $NetBSD: psm.c,v 1.11 2000/06/05 22:20:57 sommerfeld Exp $ */
/*-
@@ -82,9 +82,10 @@ struct pms_protocol {
struct synaptics_softc {
int identify;
- int capabilities, ext_capabilities;
+ int capabilities, ext_capabilities, ext2_capabilities;
int model, ext_model;
int resolution, dimension;
+ int modes;
int mode;
@@ -102,6 +103,7 @@ struct synaptics_softc {
int wsmode;
int old_x, old_y;
u_int old_buttons;
+ u_int sec_buttons;
#define SYNAPTICS_SCALE 4
#define SYNAPTICS_PRESSURE 30
};
@@ -937,6 +939,14 @@ synaptics_get_hwinfo(struct pms_softc *sc)
(syn->ext_capabilities & SYNAPTICS_EXT_CAP_MAX_DIMENSIONS) &&
synaptics_query(sc, SYNAPTICS_QUE_EXT_DIMENSIONS, &syn->dimension))
return (-1);
+ if (SYNAPTICS_ID_FULL(syn->identify) >= 0x705) {
+ if (synaptics_query(sc, SYNAPTICS_QUE_MODES, &syn->modes))
+ return (-1);
+ if ((syn->modes & SYNAPTICS_EXT2_CAP) &&
+ synaptics_query(sc, SYNAPTICS_QUE_EXT2_CAPABILITIES,
+ &syn->ext2_capabilities))
+ return (-1);
+ }
syn->res_x = SYNAPTICS_RESOLUTION_X(syn->resolution);
syn->res_y = SYNAPTICS_RESOLUTION_Y(syn->resolution);
@@ -947,6 +957,8 @@ synaptics_get_hwinfo(struct pms_softc *sc)
syn->max_y = (syn->dimension) ?
SYNAPTICS_DIM_Y(syn->dimension) : SYNAPTICS_YMAX_BEZEL;
+ syn->sec_buttons = 0;
+
if (SYNAPTICS_EXT_MODEL_BUTTONS(syn->ext_model) > 8)
syn->ext_model &= ~0xf000;
@@ -967,6 +979,7 @@ synaptics_get_hwinfo(struct pms_softc *sc)
void
synaptics_sec_proc(struct pms_softc *sc)
{
+ struct synaptics_softc *syn = sc->synaptics;
u_int buttons;
int dx, dy;
@@ -974,6 +987,7 @@ synaptics_sec_proc(struct pms_softc *sc)
return;
buttons = butmap[sc->packet[1] & PMS_PS2_BUTTONSMASK];
+ buttons |= syn->sec_buttons;
dx = (sc->packet[1] & PMS_PS2_XNEG) ?
(int)sc->packet[4] - 256 : sc->packet[4];
dy = (sc->packet[1] & PMS_PS2_YNEG) ?
@@ -1092,7 +1106,8 @@ pms_ioctl_synaptics(struct pms_softc *sc, u_long cmd, caddr_t data, int flag,
switch (cmd) {
case WSMOUSEIO_GTYPE:
if ((syn->ext_capabilities & SYNAPTICS_EXT_CAP_CLICKPAD) &&
- mouse_has_softbtn)
+ !(syn->ext2_capabilities & SYNAPTICS_EXT2_CAP_BUTTONS_STICK)
+ && mouse_has_softbtn)
*(u_int *)data = WSMOUSE_TYPE_SYNAP_SBTN;
else
*(u_int *)data = WSMOUSE_TYPE_SYNAPTICS;
@@ -1185,6 +1200,23 @@ pms_proc_synaptics(struct pms_softc *sc)
WSMOUSE_BUTTON(5) : 0;
} else if (SYNAPTICS_EXT_MODEL_BUTTONS(syn->ext_model) &&
((sc->packet[0] ^ sc->packet[3]) & 0x02)) {
+ if (syn->ext2_capabilities & SYNAPTICS_EXT2_CAP_BUTTONS_STICK) {
+ /*
+ * Trackstick buttons on this machine are wired to the
+ * trackpad as extra buttons, so route the event
+ * through the trackstick interface as normal buttons
+ */
+ syn->sec_buttons =
+ (sc->packet[4] & 0x01) ? WSMOUSE_BUTTON(1) : 0;
+ syn->sec_buttons |=
+ (sc->packet[5] & 0x01) ? WSMOUSE_BUTTON(3) : 0;
+ syn->sec_buttons |=
+ (sc->packet[4] & 0x02) ? WSMOUSE_BUTTON(2) : 0;
+ wsmouse_input(sc->sc_sec_wsmousedev,
+ syn->sec_buttons, 0, 0, 0, 0, WSMOUSE_INPUT_DELTA);
+ return;
+ }
+
buttons |= (sc->packet[4] & 0x01) ? WSMOUSE_BUTTON(6) : 0;
buttons |= (sc->packet[5] & 0x01) ? WSMOUSE_BUTTON(7) : 0;
buttons |= (sc->packet[4] & 0x02) ? WSMOUSE_BUTTON(8) : 0;