Some weeks ago a change was made in pms to support Synaptics touchpads that don't provide W mode. I assume that only fairly old models are concerned, and that the variant in the patch below is more accurate. It only fakes W values where necessary.
The patch contains a second change, a check whether the resolution query was successful. According to the "Synaptics PS/2 Interfacing Guide", bit 7 of the second response byte will be set in case of success. It seems that if it isn't set, the other bytes are garbage or have an unknown meaning. Unfortunately I only have that old model - with firmware 4.1 - for testing. Could someone confirm that newer models aren't affected by these changes? Index: dev/pckbc/pms.c =================================================================== RCS file: /cvs/src/sys/dev/pckbc/pms.c,v retrieving revision 1.65 diff -u -p -r1.65 pms.c --- dev/pckbc/pms.c 23 Aug 2015 04:45:23 -0000 1.65 +++ dev/pckbc/pms.c 28 Aug 2015 18:04:45 -0000 @@ -949,8 +949,10 @@ synaptics_get_hwinfo(struct pms_softc *s return (-1); } - syn->res_x = SYNAPTICS_RESOLUTION_X(syn->resolution); - syn->res_y = SYNAPTICS_RESOLUTION_Y(syn->resolution); + if (syn->resolution & 0x8000) { + syn->res_x = SYNAPTICS_RESOLUTION_X(syn->resolution); + syn->res_y = SYNAPTICS_RESOLUTION_Y(syn->resolution); + } syn->min_x = SYNAPTICS_XMIN_BEZEL; syn->min_y = SYNAPTICS_YMIN_BEZEL; syn->max_x = (syn->dimension) ? @@ -1163,30 +1165,21 @@ pms_proc_synaptics(struct pms_softc *sc) w = ((sc->packet[0] & 0x30) >> 2) | ((sc->packet[0] & 0x04) >> 1) | ((sc->packet[3] & 0x04) >> 2); + z = sc->packet[2]; - /* - * Conform to the encoding understood by - * /usr/xenocara/driver/xf86-input-synaptics/src/wsconscomm.c - */ - switch (w) { - case 0: - /* fingerwidth 5, numfingers 2 */ - break; - case 1: - /* fingerwidth 5, numfingers 3 */ - break; - case 5: - /* fingerwidth 5, numfingers 1 */ - break; - case 4: - case 8: - /* fingerwidth 4, numfingers 1 */ - w = 4; - break; - default: - break; + if ((syn->capabilities & SYNAPTICS_CAP_EXTENDED) == 0) { + /* + * Emulate W mode for models that don't provide it. Bit 3 + * of the w-input signals a touch ("finger"), Bit 2 and + * the "gesture" bits 1-0 can be ignored. + */ + if (w & 8) + w = 4; + else + z = w = 0; } + if ((syn->capabilities & SYNAPTICS_CAP_PASSTHROUGH) && w == 3) { synaptics_sec_proc(sc); return; @@ -1203,7 +1196,6 @@ pms_proc_synaptics(struct pms_softc *sc) sc->packet[4]; y = ((sc->packet[3] & 0x20) << 7) | ((sc->packet[1] & 0xf0) << 4) | sc->packet[5]; - z = sc->packet[2]; buttons = ((sc->packet[0] & sc->packet[3]) & 0x01) ? WSMOUSE_BUTTON(1) : 0;