svn commit: r281709 - stable/10/sys/dev/atkbdc
Rui Paulo
rpaulo at FreeBSD.org
Sat Apr 18 21:26:48 UTC 2015
Author: rpaulo
Date: Sat Apr 18 21:26:47 2015
New Revision: 281709
URL: https://svnweb.freebsd.org/changeset/base/281709
Log:
MFC r281441:
Add support for controlling the trackpoint when Synaptics is enabled.
Modified:
stable/10/sys/dev/atkbdc/psm.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/dev/atkbdc/psm.c
==============================================================================
--- stable/10/sys/dev/atkbdc/psm.c Sat Apr 18 21:24:46 2015 (r281708)
+++ stable/10/sys/dev/atkbdc/psm.c Sat Apr 18 21:26:47 2015 (r281709)
@@ -191,7 +191,8 @@ enum {
SYNAPTICS_SYSCTL_VSCROLL_VER_AREA,
SYNAPTICS_SYSCTL_VSCROLL_MIN_DELTA,
SYNAPTICS_SYSCTL_VSCROLL_DIV_MIN,
- SYNAPTICS_SYSCTL_VSCROLL_DIV_MAX
+ SYNAPTICS_SYSCTL_VSCROLL_DIV_MAX,
+ SYNAPTICS_SYSCTL_TOUCHPAD_OFF
};
typedef struct synapticsinfo {
@@ -229,6 +230,7 @@ typedef struct synapticsinfo {
int vscroll_min_delta;
int vscroll_div_min;
int vscroll_div_max;
+ int touchpad_off;
} synapticsinfo_t;
typedef struct synapticspacket {
@@ -474,6 +476,10 @@ static probefunc_t enable_synaptics;
static probefunc_t enable_trackpoint;
static probefunc_t enable_versapad;
+static void set_trackpoint_parameters(struct psm_softc *sc);
+static void synaptics_passthrough_on(struct psm_softc *sc);
+static void synaptics_passthrough_off(struct psm_softc *sc);
+
static struct {
int model;
u_char syncmask;
@@ -881,6 +887,13 @@ doinitialize(struct psm_softc *sc, mouse
set_mouse_resolution(kbdc, mode->resolution);
set_mouse_scaling(kbdc, 1);
set_mouse_mode(kbdc);
+
+ /*
+ * Trackpoint settings are lost on resume.
+ * Restore them here.
+ */
+ if (sc->tphw > 0)
+ set_trackpoint_parameters(sc);
}
/* Record sync on the next data packet we see. */
@@ -2715,6 +2728,12 @@ proc_synaptics(struct psm_softc *sc, pac
goto SYNAPTICS_END;
}
+ if (sc->syninfo.touchpad_off) {
+ *x = *y = *z = 0;
+ ms->button = ms->obutton;
+ goto SYNAPTICS_END;
+ }
+
/* Button presses */
touchpad_buttons = 0;
if (pb->ipacket[0] & 0x01)
@@ -4121,6 +4140,10 @@ synaptics_sysctl(SYSCTL_HANDLER_ARGS)
if (arg < -6143 || arg > 6143)
return (EINVAL);
break;
+ case SYNAPTICS_SYSCTL_TOUCHPAD_OFF:
+ if (arg < 0 || arg > 1)
+ return (EINVAL);
+ break;
default:
return (EINVAL);
}
@@ -4448,6 +4471,15 @@ synaptics_sysctl_create_tree(struct psm_
&sc->syninfo.vscroll_div_max, SYNAPTICS_SYSCTL_VSCROLL_DIV_MAX,
synaptics_sysctl, "I",
"Divisor for slow scrolling");
+
+ /* hw.psm.synaptics.touchpad_off. */
+ sc->syninfo.touchpad_off = 0;
+ SYSCTL_ADD_PROC(&sc->syninfo.sysctl_ctx,
+ SYSCTL_CHILDREN(sc->syninfo.sysctl_tree), OID_AUTO,
+ "touchpad_off", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY,
+ &sc->syninfo.touchpad_off, SYNAPTICS_SYSCTL_TOUCHPAD_OFF,
+ synaptics_sysctl, "I",
+ "Turn off touchpad");
}
static int
@@ -4671,25 +4703,75 @@ enable_synaptics(KBDC kbdc, struct psm_s
VLOG(3, (LOG_DEBUG, "synaptics: END init (%d buttons)\n", buttons));
if (sc != NULL) {
+ if (trackpoint_support && synhw.capPassthrough) {
+ synaptics_passthrough_on(sc);
+ enable_trackpoint(kbdc, sc);
+ synaptics_passthrough_off(sc);
+ }
/* Create sysctl tree. */
synaptics_sysctl_create_tree(sc);
-
sc->hw.buttons = buttons;
}
return (TRUE);
}
+static void
+synaptics_passthrough_on(struct psm_softc *sc)
+{
+ int mode_byte;
+
+ mode_byte = 0xc1 | (1 << 5);
+ VLOG(2, (LOG_NOTICE, "psm: setting pass-through mode. %d\n",
+ mode_byte));
+ mouse_ext_command(sc->kbdc, mode_byte);
+
+ /* "Commit" the Set Mode Byte command sent above. */
+ set_mouse_sampling_rate(sc->kbdc, 20);
+}
+
+static void
+synaptics_passthrough_off(struct psm_softc *sc)
+{
+ int mode_byte;
+
+ mode_byte = 0xc1;
+ VLOG(2, (LOG_NOTICE, "psm: turning pass-through mode off.\n"));
+ set_mouse_scaling(sc->kbdc, 2);
+ set_mouse_scaling(sc->kbdc, 1);
+ mouse_ext_command(sc->kbdc, mode_byte);
+
+ /* "Commit" the Set Mode Byte command sent above. */
+ set_mouse_sampling_rate(sc->kbdc, 20);
+}
+
/* IBM/Lenovo TrackPoint */
static int
-trackpoint_command(KBDC kbdc, int cmd, int loc, int val)
+trackpoint_command(struct psm_softc *sc, int cmd, int loc, int val)
{
const int seq[] = { 0xe2, cmd, loc, val };
int i;
- for (i = 0; i < nitems(seq); i++)
- if (send_aux_command(kbdc, seq[i]) != PSM_ACK)
+ if (sc->synhw.capPassthrough)
+ synaptics_passthrough_on(sc);
+
+ for (i = 0; i < nitems(seq); i++) {
+ if (sc->synhw.capPassthrough &&
+ (seq[i] == 0xff || seq[i] == 0xe7))
+ if (send_aux_command(sc->kbdc, 0xe7) != PSM_ACK) {
+ synaptics_passthrough_off(sc);
+ return (EIO);
+ }
+ if (send_aux_command(sc->kbdc, seq[i]) != PSM_ACK) {
+ if (sc->synhw.capPassthrough)
+ synaptics_passthrough_off(sc);
return (EIO);
+ }
+ }
+
+ if (sc->synhw.capPassthrough)
+ synaptics_passthrough_off(sc);
+
return (0);
}
@@ -4732,7 +4814,7 @@ trackpoint_sysctl(SYSCTL_HANDLER_ARGS)
return (0);
if (newval < 0 || newval > (tp[TPMASK] == 0 ? 255 : 1))
return (EINVAL);
- error = trackpoint_command(sc->kbdc, tp[TPMASK] == 0 ? 0x81 : 0x47,
+ error = trackpoint_command(sc, tp[TPMASK] == 0 ? 0x81 : 0x47,
tp[TPLOC], tp[TPMASK] == 0 ? newval : tp[TPMASK]);
if (error != 0)
return (error);
@@ -4755,7 +4837,7 @@ trackpoint_sysctl_create_tree(struct psm
0, "IBM/Lenovo TrackPoint");
/* hw.psm.trackpoint.sensitivity */
- sc->tpinfo.sensitivity = 0x64;
+ sc->tpinfo.sensitivity = 0x80;
SYSCTL_ADD_PROC(&sc->tpinfo.sysctl_ctx,
SYSCTL_CHILDREN(sc->tpinfo.sysctl_tree), OID_AUTO,
"sensitivity", CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY,
@@ -4863,6 +4945,25 @@ trackpoint_sysctl_create_tree(struct psm
"Skip backups from drags");
}
+static void
+set_trackpoint_parameters(struct psm_softc *sc)
+{
+ trackpoint_command(sc, 0x81, 0x4a, sc->tpinfo.sensitivity);
+ trackpoint_command(sc, 0x81, 0x60, sc->tpinfo.uplateau);
+ trackpoint_command(sc, 0x81, 0x4d, sc->tpinfo.inertia);
+ trackpoint_command(sc, 0x81, 0x57, sc->tpinfo.reach);
+ trackpoint_command(sc, 0x81, 0x58, sc->tpinfo.draghys);
+ trackpoint_command(sc, 0x81, 0x59, sc->tpinfo.mindrag);
+ trackpoint_command(sc, 0x81, 0x5a, sc->tpinfo.upthresh);
+ trackpoint_command(sc, 0x81, 0x5c, sc->tpinfo.threshold);
+ trackpoint_command(sc, 0x81, 0x5d, sc->tpinfo.jenks);
+ trackpoint_command(sc, 0x81, 0x5e, sc->tpinfo.ztime);
+ if (sc->tpinfo.pts == 0x01)
+ trackpoint_command(sc, 0x47, 0x2c, 0x01);
+ if (sc->tpinfo.skipback == 0x01)
+ trackpoint_command(sc, 0x47, 0x2d, 0x08);
+}
+
static int
enable_trackpoint(KBDC kbdc, struct psm_softc *sc)
{
@@ -4883,23 +4984,14 @@ enable_trackpoint(KBDC kbdc, struct psm_
/* Create sysctl tree. */
trackpoint_sysctl_create_tree(sc);
- trackpoint_command(kbdc, 0x81, 0x4a, sc->tpinfo.sensitivity);
- trackpoint_command(kbdc, 0x81, 0x4d, sc->tpinfo.inertia);
- trackpoint_command(kbdc, 0x81, 0x60, sc->tpinfo.uplateau);
- trackpoint_command(kbdc, 0x81, 0x57, sc->tpinfo.reach);
- trackpoint_command(kbdc, 0x81, 0x58, sc->tpinfo.draghys);
- trackpoint_command(kbdc, 0x81, 0x59, sc->tpinfo.mindrag);
- trackpoint_command(kbdc, 0x81, 0x5a, sc->tpinfo.upthresh);
- trackpoint_command(kbdc, 0x81, 0x5c, sc->tpinfo.threshold);
- trackpoint_command(kbdc, 0x81, 0x5d, sc->tpinfo.jenks);
- trackpoint_command(kbdc, 0x81, 0x5e, sc->tpinfo.ztime);
- if (sc->tpinfo.pts == 0x01)
- trackpoint_command(kbdc, 0x47, 0x2c, 0x01);
- if (sc->tpinfo.skipback == 0x01)
- trackpoint_command(kbdc, 0x47, 0x2d, 0x08);
-
- sc->hw.hwid = id;
- sc->hw.buttons = 3;
+ /*
+ * Don't overwrite hwid and buttons when we are
+ * a guest device.
+ */
+ if (!sc->synhw.capPassthrough) {
+ sc->hw.hwid = id;
+ sc->hw.buttons = 3;
+ }
}
return (TRUE);
More information about the svn-src-stable
mailing list