Subject: Re: Ibm thinkpad trackpoint issue
To: None <current-users@netbsd.org>
From: Michael van Elst <mlelstv@serpens.de>
List: current-users
Date: 09/09/2006 09:46:32
gdt@ir.bbn.com (Greg Troxel) writes:
>on most thinkpads with both trackpoint and touchpad ("UltraNav"), they
>both work unless you adjust the bios, and the system sees a single
>PS/2 mouse. Sometimes you have to diable touchpad to get the middle
>trackpoint button to work; it works under windows so there's some
>richer interface NetBSD doesn't support yet.
Yes. There is a passthrough mode where the data of the second device
is sent encapsulated. I made a crude patch for my T43:
Index: synaptics.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pckbport/synaptics.c,v
retrieving revision 1.5
diff -u -r1.5 synaptics.c
--- synaptics.c 27 Feb 2005 00:27:42 -0000 1.5
+++ synaptics.c 9 Sep 2006 09:44:18 -0000
@@ -644,12 +644,107 @@
#define PMS_MBUTMASK 0x04
static void
+pms_synaptics_parse(struct pms_softc *psc)
+{
+ struct synaptics_softc *sc = &psc->u.synaptics;
+ struct synaptics_packet sp;
+
+ /* Absolute X/Y coordinates of finger */
+ sp.sp_x = psc->packet[4] + ((psc->packet[1] & 0x0f) << 8) +
+ ((psc->packet[3] & 0x10) << 8);
+ sp.sp_y = psc->packet[5] + ((psc->packet[1] & 0xf0) << 4) +
+ ((psc->packet[3] & 0x20) << 7);
+
+ /* Pressure */
+ sp.sp_z = psc->packet[2];
+
+ /* Width of finger */
+ sp.sp_w = ((psc->packet[0] & 0x30) >> 2) +
+ ((psc->packet[0] & 0x04) >> 1) +
+ ((psc->packet[3] & 0x04) >> 2);
+
+ /* Left/Right button handling. */
+ sp.sp_left = psc->packet[0] & PMS_LBUTMASK;
+ sp.sp_right = psc->packet[0] & PMS_RBUTMASK;
+
+ /* Up/Down buttons. */
+ if (sc->flags & SYN_FLAG_HAS_BUTTONS_4_5) {
+ /* Old up/down buttons. */
+ sp.sp_up = sp.sp_left ^
+ (psc->packet[3] & PMS_LBUTMASK);
+ sp.sp_down = sp.sp_right ^
+ (psc->packet[3] & PMS_RBUTMASK);
+ } else
+ if (sc->flags & SYN_FLAG_HAS_UP_DOWN_BUTTONS &&
+ ((psc->packet[0] & PMS_RBUTMASK) ^
+ (psc->packet[3] & PMS_RBUTMASK))) {
+ /* New up/down button. */
+ sp.sp_up = psc->packet[4] & SYN_1BUTMASK;
+ sp.sp_down = psc->packet[5] & SYN_2BUTMASK;
+ } else {
+ sp.sp_up = 0;
+ sp.sp_down = 0;
+ }
+
+ /* Middle button. */
+ if (sc->flags & SYN_FLAG_HAS_MIDDLE_BUTTON) {
+ /* Old style Middle Button. */
+ sp.sp_middle = (psc->packet[0] & PMS_LBUTMASK) ^
+ (psc->packet[3] & PMS_LBUTMASK);
+ } else
+ if (synaptics_up_down_emul == 1) {
+ /* Do middle button emulation using up/down buttons */
+ sp.sp_middle = sp.sp_up | sp.sp_down;
+ sp.sp_up = sp.sp_down = 0;
+ } else
+ sp.sp_middle = 0;
+
+ pms_synaptics_process_packet(psc, &sp);
+}
+
+static void
+pms_synaptics_passthrough(struct pms_softc *psc)
+{
+ int dx, dy, dz;
+ int buttons, changed;
+ int s;
+
+ buttons = ((psc->packet[1] & PMS_LBUTMASK) ? 0x20 : 0) |
+ ((psc->packet[1] & PMS_MBUTMASK) ? 0x40 : 0) |
+ ((psc->packet[1] & PMS_RBUTMASK) ? 0x80 : 0);
+
+ dx = psc->packet[4];
+ if (dx >= 128)
+ dx -= 256;
+ if (dx == -128)
+ dx = -127;
+
+ dy = psc->packet[5];
+ if (dy >= 128)
+ dy -= 256;
+ if (dy == -128)
+ dy = -127;
+
+ dz = 0;
+
+ changed = buttons ^ (psc->buttons & 0xe0);
+ psc->buttons ^= changed;
+
+ if (dx || dy || dz || changed) {
+ buttons = (psc->buttons & 0x1f) | ((psc->buttons >> 5) & 0x7);
+ s = spltty();
+ wsmouse_input(psc->sc_wsmousedev,
+ buttons, dx, dy, dz,
+ WSMOUSE_INPUT_DELTA);
+ splx(s);
+ }
+}
+
+static void
pms_synaptics_input(void *vsc, int data)
{
struct pms_softc *psc = vsc;
- struct synaptics_softc *sc = &psc->u.synaptics;
struct timeval diff;
- struct synaptics_packet sp;
int s;
if (!psc->sc_enabled) {
@@ -688,7 +783,7 @@
case 3:
if ((data & 8) == 8) {
-#ifdef SYNAPTICS_DEBUG
+#ifdef SYNAPTICSDEBUG
printf("%s: pms_input: dropped in relative mode, "
"reset\n", psc->sc_dev.dv_xname);
#endif
@@ -707,60 +802,13 @@
*/
psc->inputstate = 0;
- /* Absolute X/Y coordinates of finger */
- sp.sp_x = psc->packet[4] + ((psc->packet[1] & 0x0f) << 8) +
- ((psc->packet[3] & 0x10) << 8);
- sp.sp_y = psc->packet[5] + ((psc->packet[1] & 0xf0) << 4) +
- ((psc->packet[3] & 0x20) << 7);
-
- /* Pressure */
- sp.sp_z = psc->packet[2];
-
- /* Width of finger */
- sp.sp_w = ((psc->packet[0] & 0x30) >> 2) +
- ((psc->packet[0] & 0x04) >> 1) +
- ((psc->packet[3] & 0x04) >> 2);
-
- /* Left/Right button handling. */
- sp.sp_left = psc->packet[0] & PMS_LBUTMASK;
- sp.sp_right = psc->packet[0] & PMS_RBUTMASK;
-
- /* Up/Down buttons. */
- if (sc->flags & SYN_FLAG_HAS_BUTTONS_4_5) {
- /* Old up/down buttons. */
- sp.sp_up = sp.sp_left ^
- (psc->packet[3] & PMS_LBUTMASK);
- sp.sp_down = sp.sp_right ^
- (psc->packet[3] & PMS_RBUTMASK);
- } else
- if (sc->flags & SYN_FLAG_HAS_UP_DOWN_BUTTONS &&
- ((psc->packet[0] & PMS_RBUTMASK) ^
- (psc->packet[3] & PMS_RBUTMASK))) {
- /* New up/down button. */
- sp.sp_up = psc->packet[4] & SYN_1BUTMASK;
- sp.sp_down = psc->packet[5] & SYN_2BUTMASK;
+ if ((psc->packet[0] & 0xfc) == 0x84 &&
+ (psc->packet[3] & 0xcc) == 0xc4) {
+ /* PS/2 passthrough */
+ pms_synaptics_passthrough(psc);
} else {
- sp.sp_up = 0;
- sp.sp_down = 0;
+ pms_synaptics_parse(psc);
}
-
- /* Middle button. */
- if (sc->flags & SYN_FLAG_HAS_MIDDLE_BUTTON) {
- /* Old style Middle Button. */
- sp.sp_middle = (psc->packet[0] & PMS_LBUTMASK) ^
- (psc->packet[3] & PMS_LBUTMASK);
- } else
- if (synaptics_up_down_emul == 1) {
- /* Do middle button emulation using up/down buttons */
- sp.sp_middle = sp.sp_up | sp.sp_down;
- sp.sp_up = sp.sp_down = 0;
- } else
- sp.sp_middle = 0;
-
- /*
- * Go process the new packet
- */
- pms_synaptics_process_packet(psc, &sp);
}
}
@@ -1205,8 +1253,8 @@
(sp->sp_right ? 0x4 : 0) |
(sp->sp_up ? 0x8 : 0) |
(sp->sp_down ? 0x10 : 0);
- changed = buttons ^ psc->buttons;
- psc->buttons = buttons;
+ changed = buttons ^ (psc->buttons & 0x1f);
+ psc->buttons ^= changed;
sc->prev_fingers = fingers;
sc->total_packets++;
@@ -1229,6 +1277,7 @@
* Pass the final results up to wsmouse_input() if necessary.
*/
if (dx || dy || dz || changed) {
+ buttons = (psc->buttons & 0x1f) | ((psc->buttons >> 5) & 0x7);
s = spltty();
wsmouse_input(psc->sc_wsmousedev, buttons, dx, dy, dz,
WSMOUSE_INPUT_DELTA);
--
--
Michael van Elst
Internet: mlelstv@serpens.de
"A potential Snark may lurk in every tree."