On 31/01/12(Tue) 16:52, Martin Pieuchot wrote:
> Diff below add support for the missing ALPS Dualpoint touchpads to the
> pms(4) driver. Most of the work has been done by shadchin@ and should
> fix issues you may have seen since pms(4) supports others ALPS devices
> (2011/10).
>
> It adds support for a slightly different version of the ALPS protocol,
> which send 'interleaved' PS2 packets in between absolute ALPS packets.
> Dell laptops (E6xxx and E5500 at least) have this kind of touchpad.
>
> You may have notice the problem if you see "pms0: not in sync yet" as
> soon as you move your clitpad.
>
> Please report any breakage to shadchin@ and myself.
I've got only two reports, nobody has a Dell E6x00, E5500 or Precision
M4400?
Any breakage with your already supported synaptics/alps/psm pointer?
Martin
Index: pms.c
===================================================================
RCS file: /cvs/src/sys/dev/pckbc/pms.c,v
retrieving revision 1.27
diff -u -p -r1.27 pms.c
--- pms.c 28 Jan 2012 21:00:48 -0000 1.27
+++ pms.c 30 Jan 2012 10:41:36 -0000
@@ -87,6 +87,11 @@ struct synaptics_softc {
struct alps_softc {
int model;
+#define ALPS_GLIDEPOINT (1 << 1)
+#define ALPS_DUALPOINT (1 << 2)
+#define ALPS_PASSTHROUGH (1 << 3)
+#define ALPS_INTERLEAVED (1 << 4)
+
int mask;
int version;
@@ -94,6 +99,8 @@ struct alps_softc {
int max_x, max_y;
int old_fin;
+ u_int sec_buttons; /* trackpoint */
+
/* Compat mode */
int wsmode;
int old_x, old_y;
@@ -145,18 +152,15 @@ static const struct alps_model {
int mask;
int model;
} alps_models[] = {
-#if 0
- /* FIXME some clipads are not working yet */
- { 0x5212, 0xff, ALPS_DUALPOINT | ALPS_PASSTHROUGH },
- { 0x6222, 0xcf, ALPS_DUALPOINT | ALPS_PASSTHROUGH },
-#endif
{ 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 },
@@ -228,6 +232,7 @@ int synaptics_query(struct pms_softc *,
int synaptics_get_hwinfo(struct pms_softc *);
void synaptics_sec_proc(struct pms_softc *);
+int alps_sec_proc(struct pms_softc *);
int alps_get_hwinfo(struct pms_softc *);
struct cfattach pms_ca = {
@@ -726,6 +731,7 @@ pmsinput(void *vsc, int data)
return;
}
+ sc->packet[sc->inputstate] = data;
if (sc->protocol->sync(sc, data)) {
#ifdef DIAGNOSTIC
printf("%s: not in sync yet, discard input\n", DEVNAME(sc));
@@ -734,13 +740,13 @@ pmsinput(void *vsc, int data)
return;
}
- sc->packet[sc->inputstate++] = data;
+ sc->inputstate++;
if (sc->inputstate != sc->protocol->packetsize)
return;
- sc->protocol->proc(sc);
sc->inputstate = 0;
+ sc->protocol->proc(sc);
}
int
@@ -1050,6 +1056,40 @@ pms_disable_synaptics(struct pms_softc *
}
int
+alps_sec_proc(struct pms_softc *sc)
+{
+ struct alps_softc *alps = sc->alps;
+ int dx, dy, pos = 0;
+
+ if ((sc->packet[0] & PMS_ALPS_PS2_MASK) == PMS_ALPS_PS2_VALID) {
+ /*
+ * We need to keep buttons states because interleaved
+ * packets only signalize x/y movements.
+ */
+ alps->sec_buttons = butmap[sc->packet[0] & PMS_PS2_BUTTONSMASK];
+ } else if ((sc->packet[3] & PMS_ALPS_INTERLEAVED_MASK) ==
+ PMS_ALPS_INTERLEAVED_VALID) {
+ sc->inputstate = 3;
+ pos = 3;
+ } else {
+ return (0);
+ }
+
+ if ((sc->sc_dev_enable & PMS_DEV_SECONDARY) == 0)
+ return (1);
+
+ dx = (sc->packet[pos] & PMS_PS2_XNEG) ?
+ (int)sc->packet[pos + 1] - 256 : sc->packet[pos + 1];
+ dy = (sc->packet[pos] & PMS_PS2_YNEG) ?
+ (int)sc->packet[pos + 2] - 256 : sc->packet[pos + 2];
+
+ wsmouse_input(sc->sc_sec_wsmousedev, alps->sec_buttons,
+ dx, dy, 0, 0, WSMOUSE_INPUT_DELTA);
+
+ return (1);
+}
+
+int
alps_get_hwinfo(struct pms_softc *sc)
{
struct alps_softc *alps = sc->alps;
@@ -1161,6 +1201,8 @@ pms_enable_alps(struct pms_softc *sc)
goto err;
}
+ alps->sec_buttons = 0;
+
return (1);
err:
@@ -1205,6 +1247,13 @@ pms_sync_alps(struct pms_softc *sc, int
{
struct alps_softc *alps = sc->alps;
+ if ((alps->model & ALPS_DUALPOINT) &&
+ (sc->packet[0] & PMS_ALPS_PS2_MASK) == PMS_ALPS_PS2_VALID) {
+ if (sc->inputstate == 2)
+ sc->inputstate += 3;
+ return (0);
+ }
+
switch (sc->inputstate) {
case 0:
if ((data & alps->mask) != alps->mask)
@@ -1213,9 +1262,13 @@ pms_sync_alps(struct pms_softc *sc, int
case 1:
case 2:
case 3:
+ if ((data & PMS_ALPS_MASK) != PMS_ALPS_VALID)
+ return (-1);
+ break;
case 4:
case 5:
- if ((data & 0x80) != 0)
+ if ((alps->model & ALPS_INTERLEAVED) == 0 &&
+ (data & PMS_ALPS_MASK) != PMS_ALPS_VALID)
return (-1);
break;
}
@@ -1230,6 +1283,9 @@ pms_proc_alps(struct pms_softc *sc)
int x, y, z, dx, dy;
u_int buttons;
int fin, ges;
+
+ if ((alps->model & ALPS_DUALPOINT) && alps_sec_proc(sc))
+ return;
x = sc->packet[1] | ((sc->packet[2] & 0x78) << 4);
y = sc->packet[4] | ((sc->packet[3] & 0x70) << 3);
Index: pmsreg.h
===================================================================
RCS file: /cvs/src/sys/dev/pckbc/pmsreg.h,v
retrieving revision 1.6
diff -u -p -r1.6 pmsreg.h
--- pmsreg.h 3 Dec 2011 19:43:00 -0000 1.6
+++ pmsreg.h 30 Jan 2012 10:42:39 -0000
@@ -42,6 +42,21 @@
#define PMS_ALPS_MAGIC3_1 10
#define PMS_ALPS_MAGIC3_2 100
+/*
+ * Checking for almost-standard PS/2 packet
+ * Note: ALPS devices never signal overflow condition
+ */
+#define PMS_ALPS_PS2_MASK 0xc8
+#define PMS_ALPS_PS2_VALID 0x08
+
+/* Checking for interleaved packet */
+#define PMS_ALPS_INTERLEAVED_MASK 0xcf
+#define PMS_ALPS_INTERLEAVED_VALID 0x0f
+
+/* Checking for non first byte */
+#define PMS_ALPS_MASK 0x80
+#define PMS_ALPS_VALID 0x00
+
/* Synaptics queries */
#define SYNAPTICS_QUE_IDENTIFY 0x00
#define SYNAPTICS_QUE_MODES 0x01
@@ -92,10 +107,6 @@
#define SYNAPTICS_MODEL_PEN (1 << 6)
#define SYNAPTICS_MODEL_SIMPLC (1 << 5)
#define SYNAPTICS_MODEL_GEOMETRY(m) ((m) & 0x0f)
-
-#define ALPS_GLIDEPOINT (1 << 1)
-#define ALPS_DUALPOINT (1 << 2)
-#define ALPS_PASSTHROUGH (1 << 3)
/* Resolutions */
#define SYNAPTICS_RESOLUTION_X(r) (((r) >> 16) & 0xff)