On Sun, Oct 16, 2011 at 11:57:43AM -0400, Okan Demirmen wrote: > On Sun 2011.10.16 at 17:12 +0200, Martin Pieuchot wrote: > > On 16/10/11(Sun) 16:05, Mathieu - wrote: > > > Martin Pieuchot wrote: > > > > If your touchpad/clitpad is recognized as an ALPS Dualpoint, like: > > > > > > > > $ dmesg |grep pms0 > > > > pms0: ALPS Dualpoint, version 0x6222 > > > > > > > > Please test the diff below and report me any breakage/improvement. It > > > > should > > > > at least fix the "pms0: not in sync yet, discard input" error you may > > > > have seen recently. > > > > <snip> > > > > > > > > > Yes that diff does improve things. Before I wasn't even able to move the > > > cursor getting tons of "not int sync yet" messages. > > > With this diff my touchpad works, including the scrolling part at the > > > right of the touchpad. > > > > Thanks for testings. Here's and improved version of the diff that should > > really handle interleaved packets. > > > > Can you tell me if you still see "not in sync yet" after applying this > > diff. If yes, how often? I'm also interested in the number of "PS/2 > > interleaved packet" messages. > > Hi Martin, > > Both of these diffs allow the pad to work, but the clit remains > unmovable. Below is a dmesg with this last diff. > > Cheers, > Okan >
Small rework mpi@ diff. Test please. -- Alexandr Shadchin Index: pms.c =================================================================== RCS file: /cvs/src/sys/dev/pckbc/pms.c,v retrieving revision 1.22 diff -u -p -r1.22 pms.c --- pms.c 4 Oct 2011 06:30:40 -0000 1.22 +++ pms.c 16 Oct 2011 20:34:24 -0000 @@ -39,6 +39,8 @@ #include <dev/wscons/wsconsio.h> #include <dev/wscons/wsmousevar.h> +#define DEBUG + #ifdef DEBUG #define DPRINTF(x...) do { printf(x); } while (0); #else @@ -87,6 +89,7 @@ struct synaptics_softc { struct alps_softc { int model; + int mask; int version; int min_x, min_y; @@ -141,28 +144,29 @@ static const u_int butmap[8] = { static const struct alps_model { int version; + int mask; int model; } alps_models[] = { - { 0x2021, ALPS_DUALPOINT | ALPS_PASSTHROUGH }, - { 0x2221, ALPS_DUALPOINT | ALPS_PASSTHROUGH }, - { 0x2222, ALPS_DUALPOINT | ALPS_PASSTHROUGH }, - { 0x3222, ALPS_DUALPOINT | ALPS_PASSTHROUGH }, - { 0x5212, ALPS_DUALPOINT | ALPS_PASSTHROUGH }, - { 0x5321, ALPS_GLIDEPOINT }, - { 0x5322, ALPS_GLIDEPOINT }, - { 0x603b, ALPS_GLIDEPOINT }, - { 0x6222, ALPS_DUALPOINT | ALPS_PASSTHROUGH }, - { 0x6321, ALPS_GLIDEPOINT }, - { 0x6322, ALPS_GLIDEPOINT }, - { 0x6323, ALPS_GLIDEPOINT }, - { 0x6324, ALPS_GLIDEPOINT }, - { 0x6325, ALPS_GLIDEPOINT }, - { 0x6326, ALPS_GLIDEPOINT }, - { 0x633b, ALPS_DUALPOINT | ALPS_PASSTHROUGH }, - { 0x7301, ALPS_DUALPOINT }, - { 0x7321, ALPS_GLIDEPOINT }, - { 0x7322, ALPS_GLIDEPOINT }, - { 0x7325, ALPS_GLIDEPOINT }, + { 0x2021, 0xf8, ALPS_DUALPOINT | ALPS_PASSTHROUGH }, + { 0x2221, 0xf8, ALPS_DUALPOINT | ALPS_PASSTHROUGH }, + { 0x2222, 0xff, ALPS_DUALPOINT | ALPS_PASSTHROUGH }, + { 0x3222, 0xf8, ALPS_DUALPOINT | ALPS_PASSTHROUGH }, + { 0x5212, 0xff, ALPS_DUALPOINT | ALPS_PASSTHROUGH | ALPS_INTERLEAVED }, + { 0x5321, 0xf8, ALPS_GLIDEPOINT }, + { 0x5322, 0xf8, ALPS_GLIDEPOINT }, + { 0x603b, 0xf8, ALPS_GLIDEPOINT }, + { 0x6222, 0xcf, ALPS_DUALPOINT | ALPS_PASSTHROUGH | ALPS_INTERLEAVED }, + { 0x6321, 0xf8, ALPS_GLIDEPOINT }, + { 0x6322, 0xf8, ALPS_GLIDEPOINT }, + { 0x6323, 0xf8, ALPS_GLIDEPOINT }, + { 0x6324, 0x8f, ALPS_GLIDEPOINT }, + { 0x6325, 0xef, ALPS_GLIDEPOINT }, + { 0x6326, 0xf8, ALPS_GLIDEPOINT }, + { 0x633b, 0xf8, ALPS_DUALPOINT | ALPS_PASSTHROUGH }, + { 0x7301, 0xf8, ALPS_DUALPOINT }, + { 0x7321, 0xf8, ALPS_GLIDEPOINT }, + { 0x7322, 0xf8, ALPS_GLIDEPOINT }, + { 0x7325, 0xcf, ALPS_GLIDEPOINT }, #if 0 { 0x7326, 0 }, /* XXX Uses unknown v3 protocol */ #endif @@ -212,6 +216,7 @@ int synaptics_query(struct pms_softc *, int synaptics_get_hwinfo(struct pms_softc *); void synaptics_pt_proc(struct pms_softc *); +void alps_pt_proc(struct pms_softc *); int synaptics_pt_ioctl(void *, u_long, caddr_t, int, struct proc *); int synaptics_pt_enable(void *); @@ -698,8 +703,8 @@ pmsinput(void *vsc, int data) if (sc->inputstate != sc->protocol->packetsize) return; - sc->protocol->proc(sc); sc->inputstate = 0; + sc->protocol->proc(sc); } int @@ -1058,6 +1063,7 @@ alps_get_hwinfo(struct pms_softc *sc) for (i = 0; i < nitems(alps_models); i++) if (alps->version == alps_models[i].version) { alps->model = alps_models[i].model; + alps->mask = alps_models[i].mask; return (0); } @@ -1065,10 +1071,38 @@ alps_get_hwinfo(struct pms_softc *sc) } +void +alps_pt_proc(struct pms_softc *sc) +{ + struct alps_softc *alps = sc->alps; + int dx, dy; + + if ((sc->sc_dev_enable & PMS_DEV_SECONDARY) == 0) + return; + + if (alps->model & ALPS_INTERLEAVED) { + dx = (sc->packet[3] & PMS_PS2_XNEG) ? + (int)sc->packet[4] - 256 : sc->packet[4]; + dy = (sc->packet[3] & PMS_PS2_YNEG) ? + (int)sc->packet[5] - 256 : sc->packet[5]; + } else { + dx = sc->packet[1] | ((sc->packet[2] & 0x78) << 4); + dy = sc->packet[4] | ((sc->packet[3] & 0x70) << 3); + dx = (dx > 383) ? (dx - 768) : dx; + dy = (dy > 255) ? (dy - 512) : dy; + } + + DPRINTF("%s: dx=%d, dy=%d\n", DEVNAME(sc), dx, dy); + + wsmouse_input(sc->sc_pt_wsmousedev, + 0, dx, dy, 0, 0, WSMOUSE_INPUT_DELTA); +} + int pms_enable_alps(struct pms_softc *sc) { struct alps_softc *alps = sc->alps; + struct wsmousedev_attach_args a; u_char resp[3]; if (pms_set_resolution(sc, 0) || @@ -1102,6 +1136,13 @@ pms_enable_alps(struct pms_softc *sc) alps->max_y = ALPS_YMAX_BEZEL; alps->wsmode = WSMOUSE_COMPAT; + + if (alps->model & (ALPS_INTERLEAVED | ALPS_DUALPOINT)) { + a.accessops = &synaptics_pt_accessops; + a.accesscookie = sc; + sc->sc_pt_wsmousedev = config_found((void *)sc, &a, + wsmousedevprint); + } } if (alps->model == 0) @@ -1183,17 +1224,22 @@ pms_ioctl_alps(struct pms_softc *sc, u_l int pms_sync_alps(struct pms_softc *sc, int data) { + struct alps_softc *alps = sc->alps; + switch (sc->inputstate) { case 0: - if ((data & 0xf8) != 0xf8) /* XXX model dependant? */ + if ((data & alps->mask) != alps->mask) return (-1); break; case 1: case 2: case 3: + if ((data & 0x80) != 0) + return (-1); + break; case 4: case 5: - if ((data & 0x80) != 0) + if ((data & 0x80) != 0 && (alps->model & ALPS_INTERLEAVED) == 0) return (-1); break; } @@ -1209,9 +1255,23 @@ pms_proc_alps(struct pms_softc *sc) u_int buttons; int fin, ges; + z = sc->packet[5]; + + if ((alps->model & ALPS_INTERLEAVED) && (sc->packet[3] & 0x0f) == 0x0f) { + DPRINTF("%s: PS/2 interleaved packet\n", DEVNAME(sc)); + alps_pt_proc(sc); + sc->inputstate = 3; + return; + } else if ((alps->model & ALPS_DUALPOINT) && z == 127) { + alps_pt_proc(sc); + return; + } + + if ((sc->sc_dev_enable & PMS_DEV_PRIMARY) == 0) + return; + x = sc->packet[1] | ((sc->packet[2] & 0x78) << 4); y = sc->packet[4] | ((sc->packet[3] & 0x70) << 3); - z = sc->packet[5]; /* * XXX The Y-axis is in the oposit direction compared to @@ -1226,13 +1286,6 @@ pms_proc_alps(struct pms_softc *sc) ((sc->packet[3] & 4) ? WSMOUSE_BUTTON(2) : 0); if (alps->wsmode == WSMOUSE_NATIVE) { - if (z == 127) { - /* DualPoint touchpads are not absolute. */ - wsmouse_input(sc->sc_wsmousedev, buttons, x, y, 0, 0, - WSMOUSE_INPUT_DELTA); - return; - } - ges = sc->packet[2] & 0x01; fin = sc->packet[2] & 0x02; Index: pmsreg.h =================================================================== RCS file: /cvs/src/sys/dev/pckbc/pmsreg.h,v retrieving revision 1.5 diff -u -p -r1.5 pmsreg.h --- pmsreg.h 4 Oct 2011 06:30:40 -0000 1.5 +++ pmsreg.h 16 Oct 2011 20:34:24 -0000 @@ -96,6 +96,7 @@ #define ALPS_GLIDEPOINT (1 << 1) #define ALPS_DUALPOINT (1 << 2) #define ALPS_PASSTHROUGH (1 << 3) +#define ALPS_INTERLEAVED (1 << 4) /* Resolutions */ #define SYNAPTICS_RESOLUTION_X(r) (((r) >> 16) & 0xff)