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)

Reply via email to