Hi,
Please test latest patch for support Synaptics touchpad
(or http://koba.devio.us/distfiles/synaptics.v5.diff)
Patch for snapshot from 18-Jul-2011 or newer.
It seems everything regression eliminated.
--
Alexandr Shadchin
Index: dev/pckbc/pms.c
===================================================================
RCS file: /cvs/src/sys/dev/pckbc/pms.c,v
retrieving revision 1.18
diff -u -p -r1.18 pms.c
--- dev/pckbc/pms.c 3 Jan 2011 19:46:34 -0000 1.18
+++ dev/pckbc/pms.c 6 Jul 2011 06:35:28 -0000
@@ -28,6 +28,7 @@
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/ioctl.h>
+#include <sys/malloc.h>
#include <machine/bus.h>
@@ -40,12 +41,15 @@
#define DEVNAME(sc) ((sc)->sc_dev.dv_xname)
+#define WSMOUSE_BUTTON(x) (1 << ((x) - 1))
+
struct pms_softc;
struct pms_protocol {
int type;
#define PMS_STANDARD 0
#define PMS_INTELLI 1
+#define PMS_SYNAPTICS 2
u_int packetsize;
int (*enable)(struct pms_softc *);
int (*ioctl)(struct pms_softc *, u_long, caddr_t, int, struct proc *);
@@ -54,6 +58,26 @@ struct pms_protocol {
void (*disable)(struct pms_softc *);
};
+struct synaptics_softc {
+ int identify;
+ int capabilities, ext_capabilities;
+ int model, ext_model;
+ int resolution, dimension;
+
+ int mode;
+
+ int res_x, res_y;
+ int min_x, min_y;
+ int max_x, max_y;
+
+ /* Compat mode */
+ int wsmode;
+ int old_x, old_y;
+ u_int old_buttons;
+#define SYNAPTICS_SCALE 4
+#define SYNAPTICS_PRESSURE 30
+};
+
struct pms_softc { /* driver status information */
struct device sc_dev;
@@ -64,56 +88,47 @@ struct pms_softc { /* driver status inf
#define PMS_STATE_ENABLED 1
#define PMS_STATE_SUSPENDED 2
+ int sc_dev_enable;
+#define PMS_DEV_IGNORE 0x00
+#define PMS_DEV_PRIMARY 0x01
+#define PMS_DEV_SECONDARY 0x02
+
int poll;
int inputstate;
const struct pms_protocol *protocol;
+ struct synaptics_softc *synaptics;
u_char packet[8];
struct device *sc_wsmousedev;
+ struct device *sc_pt_wsmousedev;
};
-#define PMS_BUTTON1DOWN 0x0001 /* left */
-#define PMS_BUTTON2DOWN 0x0002 /* middle */
-#define PMS_BUTTON3DOWN 0x0004 /* right */
-
static const u_int butmap[8] = {
0,
- PMS_BUTTON1DOWN,
- PMS_BUTTON3DOWN,
- PMS_BUTTON1DOWN | PMS_BUTTON3DOWN,
- PMS_BUTTON2DOWN,
- PMS_BUTTON1DOWN | PMS_BUTTON2DOWN,
- PMS_BUTTON2DOWN | PMS_BUTTON3DOWN,
- PMS_BUTTON1DOWN | PMS_BUTTON2DOWN | PMS_BUTTON3DOWN
+ WSMOUSE_BUTTON(1),
+ WSMOUSE_BUTTON(3),
+ WSMOUSE_BUTTON(1) | WSMOUSE_BUTTON(3),
+ WSMOUSE_BUTTON(2),
+ WSMOUSE_BUTTON(1) | WSMOUSE_BUTTON(2),
+ WSMOUSE_BUTTON(2) | WSMOUSE_BUTTON(3),
+ WSMOUSE_BUTTON(1) | WSMOUSE_BUTTON(2) | WSMOUSE_BUTTON(3)
};
-/* PS/2 mouse data packet */
-#define PMS_PS2_BUTTONSMASK 0x07
-#define PMS_PS2_BUTTON1 0x01 /* left */
-#define PMS_PS2_BUTTON2 0x04 /* middle */
-#define PMS_PS2_BUTTON3 0x02 /* right */
-#define PMS_PS2_XNEG 0x10
-#define PMS_PS2_YNEG 0x20
-
-#define PMS_INTELLI_MAGIC1 200
-#define PMS_INTELLI_MAGIC2 100
-#define PMS_INTELLI_MAGIC3 80
-#define PMS_INTELLI_ID 0x03
-
int pmsprobe(struct device *, void *, void *);
void pmsattach(struct device *, struct device *, void *);
int pmsactivate(struct device *, int);
void pmsinput(void *, int);
-int pms_change_state(struct pms_softc *, int);
+int pms_change_state(struct pms_softc *, int, int);
int pms_ioctl(void *, u_long, caddr_t, int, struct proc *);
int pms_enable(void *);
void pms_disable(void *);
int pms_cmd(struct pms_softc *, u_char *, int, u_char *, int);
+int pms_spec_cmd(struct pms_softc *, int);
int pms_get_devid(struct pms_softc *, u_char *);
int pms_get_status(struct pms_softc *, u_char *);
int pms_set_rate(struct pms_softc *, int);
@@ -129,6 +144,22 @@ int pms_ioctl_mouse(struct pms_softc *,
int pms_sync_mouse(struct pms_softc *, int);
void pms_proc_mouse(struct pms_softc *);
+int pms_enable_synaptics(struct pms_softc *);
+int pms_ioctl_synaptics(struct pms_softc *, u_long, caddr_t, int, struct
proc *);
+int pms_sync_synaptics(struct pms_softc *, int);
+void pms_proc_synaptics(struct pms_softc *);
+void pms_disable_synaptics(struct pms_softc *);
+
+int synaptics_set_mode(struct pms_softc *, int);
+int synaptics_query(struct pms_softc *, int, int *);
+int synaptics_get_hwinfo(struct pms_softc *);
+
+void synaptics_pt_proc(struct pms_softc *);
+
+int synaptics_pt_ioctl(void *, u_long, caddr_t, int, struct proc *);
+int synaptics_pt_enable(void *);
+void synaptics_pt_disable(void *);
+
struct cfattach pms_ca = {
sizeof(struct pms_softc), pmsprobe, pmsattach, NULL,
pmsactivate
@@ -144,7 +175,13 @@ const struct wsmouse_accessops pms_acces
pms_disable,
};
-const struct pms_protocol pms_mouse[] = {
+const struct wsmouse_accessops synaptics_pt_accessops = {
+ synaptics_pt_enable,
+ synaptics_pt_ioctl,
+ synaptics_pt_disable,
+};
+
+const struct pms_protocol pms_protocols[] = {
/* Generic PS/2 mouse */
{
PMS_STANDARD, 3,
@@ -162,6 +199,15 @@ const struct pms_protocol pms_mouse[] =
pms_sync_mouse,
pms_proc_mouse,
NULL
+ },
+ /* Synaptics touchpad */
+ {
+ PMS_SYNAPTICS, 6,
+ pms_enable_synaptics,
+ pms_ioctl_synaptics,
+ pms_sync_synaptics,
+ pms_proc_synaptics,
+ pms_disable_synaptics
}
};
@@ -178,6 +224,18 @@ pms_cmd(struct pms_softc *sc, u_char *cm
}
int
+pms_spec_cmd(struct pms_softc *sc, int cmd)
+{
+ if (pms_set_scaling(sc, 1) ||
+ pms_set_resolution(sc, (cmd >> 6) & 0x03) ||
+ pms_set_resolution(sc, (cmd >> 4) & 0x03) ||
+ pms_set_resolution(sc, (cmd >> 2) & 0x03) ||
+ pms_set_resolution(sc, (cmd >> 0) & 0x03))
+ return (-1);
+ return (0);
+}
+
+int
pms_get_devid(struct pms_softc *sc, u_char *resp)
{
u_char cmd[1];
@@ -395,6 +453,7 @@ pmsattach(struct device *parent, struct
struct pms_softc *sc = (void *)self;
struct pckbc_attach_args *pa = aux;
struct wsmousedev_attach_args a;
+ int i;
sc->sc_kbctag = pa->pa_tag;
@@ -414,11 +473,18 @@ pmsattach(struct device *parent, struct
*/
sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
- /* no interrupts until enabled */
sc->poll = 1;
- pms_change_state(sc, PMS_STATE_ENABLED);
- sc->poll = 1; /* XXX */
- pms_change_state(sc, PMS_STATE_DISABLED);
+ sc->sc_dev_enable = 0;
+
+ sc->protocol = &pms_protocols[0];
+ for (i = 1; i < nitems(pms_protocols); i++) {
+ pms_reset(sc);
+ if (pms_protocols[i].enable(sc))
+ sc->protocol = &pms_protocols[i];
+ }
+
+ /* no interrupts until enabled */
+ pms_change_state(sc, PMS_STATE_DISABLED, PMS_DEV_IGNORE);
}
int
@@ -429,26 +495,47 @@ pmsactivate(struct device *self, int act
switch (act) {
case DVACT_SUSPEND:
if (sc->sc_state == PMS_STATE_ENABLED)
- pms_change_state(sc, PMS_STATE_SUSPENDED);
+ pms_change_state(sc, PMS_STATE_SUSPENDED,
+ PMS_DEV_IGNORE);
break;
case DVACT_RESUME:
if (sc->sc_state == PMS_STATE_SUSPENDED)
- pms_change_state(sc, PMS_STATE_ENABLED);
+ pms_change_state(sc, PMS_STATE_ENABLED,
+ PMS_DEV_IGNORE);
break;
}
return (0);
}
int
-pms_change_state(struct pms_softc *sc, int newstate)
+pms_change_state(struct pms_softc *sc, int newstate, int dev)
{
int i;
+ if (dev != PMS_DEV_IGNORE) {
+ switch (newstate) {
+ case PMS_STATE_ENABLED:
+ if (sc->sc_dev_enable & dev)
+ return (EBUSY);
+
+ sc->sc_dev_enable |= dev;
+
+ if (sc->sc_state == PMS_STATE_ENABLED)
+ return (0);
+
+ break;
+ case PMS_STATE_DISABLED:
+ sc->sc_dev_enable &= ~dev;
+
+ if (sc->sc_dev_enable)
+ return (0);
+
+ break;
+ }
+ }
+
switch (newstate) {
case PMS_STATE_ENABLED:
- if (sc->sc_state == PMS_STATE_ENABLED)
- return (EBUSY);
-
sc->inputstate = 0;
pckbc_slot_enable(sc->sc_kbctag, PCKBC_AUX_SLOT, 1);
@@ -458,10 +545,16 @@ pms_change_state(struct pms_softc *sc, i
pms_reset(sc);
- sc->protocol = &pms_mouse[0];
- for (i = 1; i < nitems(pms_mouse); i++)
- if (pms_mouse[i].enable(sc))
- sc->protocol = &pms_mouse[i];
+ if (sc->protocol->type != PMS_STANDARD &&
+ sc->protocol->enable(sc) == 0)
+ sc->protocol = &pms_protocols[0];
+
+ if (sc->protocol->type == PMS_STANDARD)
+ for (i = 1; i < nitems(pms_protocols); i++) {
+ pms_reset(sc);
+ if (pms_protocols[i].enable(sc))
+ sc->protocol = &pms_protocols[i];
+ }
#ifdef DEBUG
printf("%s: protocol type %d\n", DEVNAME(sc),
sc->protocol->type);
@@ -491,7 +584,7 @@ pms_enable(void *v)
{
struct pms_softc *sc = v;
- return pms_change_state(sc, PMS_STATE_ENABLED);
+ return pms_change_state(sc, PMS_STATE_ENABLED, PMS_DEV_PRIMARY);
}
void
@@ -499,7 +592,7 @@ pms_disable(void *v)
{
struct pms_softc *sc = v;
- pms_change_state(sc, PMS_STATE_DISABLED);
+ pms_change_state(sc, PMS_STATE_DISABLED, PMS_DEV_PRIMARY);
}
int
@@ -524,7 +617,7 @@ pmsinput(void *vsc, int data)
}
if (sc->protocol->sync(sc, data)) {
-#ifdef DEBUG
+#ifdef DIAGNOSTIC
printf("%s: not in sync yet, discard input\n", DEVNAME(sc));
#endif
sc->inputstate = 0;
@@ -537,4 +630,339 @@ pmsinput(void *vsc, int data)
sc->protocol->proc(sc);
sc->inputstate = 0;
+}
+
+int
+synaptics_set_mode(struct pms_softc *sc, int mode)
+{
+ struct synaptics_softc *syn = sc->synaptics;
+
+ if (pms_spec_cmd(sc, mode) ||
+ pms_set_rate(sc, SYNAPTICS_CMD_SET_MODE))
+ return (-1);
+
+ syn->mode = mode;
+
+ return (0);
+}
+
+int
+synaptics_query(struct pms_softc *sc, int query, int *val)
+{
+ u_char resp[3];
+
+ if (pms_spec_cmd(sc, query) ||
+ pms_get_status(sc, resp))
+ return (-1);
+
+ if (val)
+ *val = (resp[0] << 16) | (resp[1] << 8) | resp[2];
+
+ return (0);
+}
+
+int
+synaptics_get_hwinfo(struct pms_softc *sc)
+{
+ struct synaptics_softc *syn = sc->synaptics;
+
+ if (synaptics_query(sc, SYNAPTICS_QUE_IDENTIFY, &syn->identify))
+ return (-1);
+ if (synaptics_query(sc, SYNAPTICS_QUE_CAPABILITIES,
+ &syn->capabilities))
+ return (-1);
+ if (synaptics_query(sc, SYNAPTICS_QUE_MODEL, &syn->model))
+ return (-1);
+ if ((SYNAPTICS_CAP_EXTENDED_QUERIES(syn->capabilities) >= 1) &&
+ synaptics_query(sc, SYNAPTICS_QUE_EXT_MODEL, &syn->ext_model))
+ return (-1);
+ if ((SYNAPTICS_CAP_EXTENDED_QUERIES(syn->capabilities) >= 4) &&
+ synaptics_query(sc, SYNAPTICS_QUE_EXT_CAPABILITIES,
+ &syn->ext_capabilities))
+ return (-1);
+ if ((SYNAPTICS_ID_MAJOR(syn->identify) >= 4) &&
+ synaptics_query(sc, SYNAPTICS_QUE_RESOLUTION, &syn->resolution))
+ return (-1);
+ if ((SYNAPTICS_CAP_EXTENDED_QUERIES(syn->capabilities) >= 5) &&
+ (syn->ext_capabilities & SYNAPTICS_EXT_CAP_MAX_DIMENSIONS) &&
+ synaptics_query(sc, SYNAPTICS_QUE_EXT_DIMENSIONS, &syn->dimension))
+ return (-1);
+
+ 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) ?
+ SYNAPTICS_DIM_X(syn->dimension) : SYNAPTICS_XMAX_BEZEL;
+ syn->max_y = (syn->dimension) ?
+ SYNAPTICS_DIM_Y(syn->dimension) : SYNAPTICS_YMAX_BEZEL;
+
+ if (SYNAPTICS_EXT_MODEL_BUTTONS(syn->ext_model) > 8)
+ syn->ext_model &= ~0xf000;
+
+ return (0);
+}
+
+void
+synaptics_pt_proc(struct pms_softc *sc)
+{
+ u_int buttons;
+ int dx, dy;
+
+ if ((sc->sc_dev_enable & PMS_DEV_SECONDARY) == 0)
+ return;
+
+ buttons = butmap[sc->packet[1] & PMS_PS2_BUTTONSMASK];
+ dx = (sc->packet[1] & PMS_PS2_XNEG) ?
+ (int)sc->packet[4] - 256 : sc->packet[4];
+ dy = (sc->packet[1] & PMS_PS2_YNEG) ?
+ (int)sc->packet[5] - 256 : sc->packet[5];
+
+ wsmouse_input(sc->sc_pt_wsmousedev,
+ buttons, dx, dy, 0, 0, WSMOUSE_INPUT_DELTA);
+}
+
+int
+synaptics_pt_enable(void *v)
+{
+ struct pms_softc *sc = v;
+
+ return (pms_change_state(sc, PMS_STATE_ENABLED, PMS_DEV_SECONDARY));
+}
+
+void
+synaptics_pt_disable(void *v)
+{
+ struct pms_softc *sc = v;
+
+ pms_change_state(sc, PMS_STATE_DISABLED, PMS_DEV_SECONDARY);
+}
+
+int
+synaptics_pt_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ switch (cmd) {
+ case WSMOUSEIO_GTYPE:
+ *(u_int *)data = WSMOUSE_TYPE_PS2;
+ break;
+ default:
+ return (-1);
+ }
+ return (0);
+}
+
+int
+pms_enable_synaptics(struct pms_softc *sc)
+{
+ struct synaptics_softc *syn = sc->synaptics;
+ struct wsmousedev_attach_args a;
+ u_char resp[3];
+ int mode;
+
+ if (pms_set_resolution(sc, 0) ||
+ pms_set_resolution(sc, 0) ||
+ pms_set_resolution(sc, 0) ||
+ pms_set_resolution(sc, 0) ||
+ pms_get_status(sc, resp) ||
+ resp[1] != SYNAPTICS_ID_MAGIC)
+ return (0);
+
+ if (sc->synaptics == NULL) {
+ sc->synaptics = syn = malloc(sizeof(struct synaptics_softc),
+ M_DEVBUF, M_WAITOK | M_ZERO);
+ if (syn == NULL) {
+ printf("%s: synaptics: not enough memory\n",
+ DEVNAME(sc));
+ return (0);
+ }
+
+ if (synaptics_get_hwinfo(sc))
+ return (0);
+
+ if ((syn->model & SYNAPTICS_MODEL_NEWABS) == 0) {
+ printf("%s: don't support Synaptics OLDABS\n",
+ DEVNAME(sc));
+ return (0);
+ }
+
+ /* enable pass-through PS/2 port if supported */
+ if (syn->capabilities & SYNAPTICS_CAP_PASSTHROUGH) {
+ a.accessops = &synaptics_pt_accessops;
+ a.accesscookie = sc;
+ sc->sc_pt_wsmousedev = config_found((void *)sc, &a,
+ wsmousedevprint);
+ }
+
+ syn->wsmode = WSMOUSE_COMPAT;
+
+ printf("%s: Synaptics %s, firmware %d.%d\n", DEVNAME(sc),
+ (syn->ext_capabilities & SYNAPTICS_EXT_CAP_CLICKPAD ?
+ "clickpad" : "touchpad"),
+ SYNAPTICS_ID_MAJOR(syn->identify),
+ SYNAPTICS_ID_MINOR(syn->identify));
+ }
+
+ mode = SYNAPTICS_ABSOLUTE_MODE | SYNAPTICS_HIGH_RATE;
+ if (SYNAPTICS_ID_MAJOR(syn->identify) >= 4)
+ mode |= SYNAPTICS_DISABLE_GESTURE;
+ if (syn->capabilities & SYNAPTICS_CAP_EXTENDED)
+ mode |= SYNAPTICS_W_MODE;
+ if (synaptics_set_mode(sc, mode))
+ return (0);
+
+ /* enable advanced gesture mode if supported */
+ if ((syn->ext_capabilities & SYNAPTICS_EXT_CAP_ADV_GESTURE) &&
+ (pms_spec_cmd(sc, SYNAPTICS_QUE_MODEL) ||
+ pms_set_rate(sc, SYNAPTICS_CMD_SET_ADV_GESTURE_MODE)))
+ return (0);
+
+ return (1);
+}
+
+int
+pms_ioctl_synaptics(struct pms_softc *sc, u_long cmd, caddr_t data, int flag,
+ struct proc *p)
+{
+ struct synaptics_softc *syn = sc->synaptics;
+ struct wsmouse_calibcoords *wsmc = (struct wsmouse_calibcoords *)data;
+ int wsmode;
+
+ switch (cmd) {
+ case WSMOUSEIO_GTYPE:
+ *(u_int *)data = WSMOUSE_TYPE_SYNAPTICS;
+ break;
+ case WSMOUSEIO_GCALIBCOORDS:
+ wsmc->minx = syn->min_x;
+ wsmc->maxx = syn->max_x;
+ wsmc->miny = syn->min_y;
+ wsmc->maxy = syn->max_y;
+ wsmc->swapxy = 0;
+ wsmc->resx = syn->res_x;
+ wsmc->resy = syn->res_y;
+ break;
+ case WSMOUSEIO_SETMODE:
+ wsmode = *(u_int *)data;
+ if (wsmode != WSMOUSE_COMPAT && wsmode != WSMOUSE_NATIVE)
+ return (EINVAL);
+ syn->wsmode = wsmode;
+ break;
+ default:
+ return (-1);
+ }
+ return (0);
+}
+
+int
+pms_sync_synaptics(struct pms_softc *sc, int data)
+{
+ switch (sc->inputstate) {
+ case 0:
+ if ((data & 0xc8) != 0x80)
+ return (-1);
+ break;
+ case 3:
+ if ((data & 0xc8) != 0xc0)
+ return (-1);
+ break;
+ }
+
+ return (0);
+}
+
+void
+pms_proc_synaptics(struct pms_softc *sc)
+{
+ struct synaptics_softc *syn = sc->synaptics;
+ u_int buttons;
+ int x, y, z, w, dx, dy;
+
+ w = ((sc->packet[0] & 0x30) >> 2) | ((sc->packet[0] & 0x04) >> 1) |
+ ((sc->packet[3] & 0x04) >> 2);
+
+ if ((syn->capabilities & SYNAPTICS_CAP_PASSTHROUGH) && w == 3) {
+ synaptics_pt_proc(sc);
+ return;
+ }
+
+ if ((sc->sc_dev_enable & PMS_DEV_PRIMARY) == 0)
+ return;
+
+ /* XXX ignore advanced gesture packet, not yet supported */
+ if ((syn->ext_capabilities & SYNAPTICS_EXT_CAP_ADV_GESTURE) && w == 2)
+ return;
+
+ x = ((sc->packet[3] & 0x10) << 8) | ((sc->packet[1] & 0x0f) << 8) |
+ 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;
+ buttons |= ((sc->packet[0] & sc->packet[3]) & 0x02) ?
+ WSMOUSE_BUTTON(3) : 0;
+
+ if (syn->ext_capabilities & SYNAPTICS_EXT_CAP_CLICKPAD) {
+ buttons |= ((sc->packet[0] ^ sc->packet[3]) & 0x01) ?
+ WSMOUSE_BUTTON(1) : 0;
+ } else if (syn->capabilities & SYNAPTICS_CAP_MIDDLE_BUTTON) {
+ buttons |= ((sc->packet[0] ^ sc->packet[3]) & 0x01) ?
+ WSMOUSE_BUTTON(2) : 0;
+ }
+
+ if (syn->capabilities & SYNAPTICS_CAP_FOUR_BUTTON) {
+ buttons |= ((sc->packet[0] ^ sc->packet[3]) & 0x01) ?
+ WSMOUSE_BUTTON(4) : 0;
+ buttons |= ((sc->packet[0] ^ sc->packet[3]) & 0x02) ?
+ WSMOUSE_BUTTON(5) : 0;
+ } else if (SYNAPTICS_EXT_MODEL_BUTTONS(syn->ext_model) &&
+ ((sc->packet[0] ^ sc->packet[3]) & 0x02)) {
+ buttons |= (sc->packet[4] & 0x01) ? WSMOUSE_BUTTON(6) : 0;
+ buttons |= (sc->packet[5] & 0x01) ? WSMOUSE_BUTTON(7) : 0;
+ buttons |= (sc->packet[4] & 0x02) ? WSMOUSE_BUTTON(8) : 0;
+ buttons |= (sc->packet[5] & 0x02) ? WSMOUSE_BUTTON(9) : 0;
+ buttons |= (sc->packet[4] & 0x04) ? WSMOUSE_BUTTON(10) : 0;
+ buttons |= (sc->packet[5] & 0x04) ? WSMOUSE_BUTTON(11) : 0;
+ buttons |= (sc->packet[4] & 0x08) ? WSMOUSE_BUTTON(12) : 0;
+ buttons |= (sc->packet[5] & 0x08) ? WSMOUSE_BUTTON(13) : 0;
+ x &= ~0x0f;
+ y &= ~0x0f;
+ }
+
+ /* ignore final events that happen when removing all fingers */
+ if (x <= 1 || y <= 1) {
+ x = syn->old_x;
+ y = syn->old_y;
+ }
+
+ if (syn->wsmode == WSMOUSE_NATIVE) {
+ wsmouse_input(sc->sc_wsmousedev, buttons, x, y, z, w,
+ WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y |
+ WSMOUSE_INPUT_ABSOLUTE_Z | WSMOUSE_INPUT_ABSOLUTE_W);
+ } else {
+ dx = dy = 0;
+ if (z > SYNAPTICS_PRESSURE) {
+ dx = x - syn->old_x;
+ dy = y - syn->old_y;
+ dx /= SYNAPTICS_SCALE;
+ dy /= SYNAPTICS_SCALE;
+ }
+ if (dx || dy || buttons != syn->old_buttons)
+ wsmouse_input(sc->sc_wsmousedev, buttons, dx, dy, 0, 0,
+ WSMOUSE_INPUT_DELTA);
+ syn->old_buttons = buttons;
+ }
+
+ syn->old_x = x;
+ syn->old_y = y;
+}
+
+void
+pms_disable_synaptics(struct pms_softc *sc)
+{
+ struct synaptics_softc *syn = sc->synaptics;
+
+ if (syn->capabilities & SYNAPTICS_CAP_SLEEP)
+ synaptics_set_mode(sc, SYNAPTICS_SLEEP_MODE |
+ SYNAPTICS_DISABLE_GESTURE);
}
Index: dev/pckbc/pmsreg.h
===================================================================
RCS file: /cvs/src/sys/dev/pckbc/pmsreg.h,v
retrieving revision 1.1
diff -u -p -r1.1 pmsreg.h
--- dev/pckbc/pmsreg.h 1 Aug 2007 12:16:59 -0000 1.1
+++ dev/pckbc/pmsreg.h 6 Jul 2011 06:35:28 -0000
@@ -1,20 +1,124 @@
/* $OpenBSD: pmsreg.h,v 1.1 2007/08/01 12:16:59 kettenis Exp $ */
/* $NetBSD: psmreg.h,v 1.1 1998/03/22 15:41:28 drochner Exp $ */
+#ifndef SYS_DEV_PCKBC_PMSREG_H
+#define SYS_DEV_PCKBC_PMSREG_H
+
/* mouse commands */
-#define PMS_SET_SCALE11 0xe6 /* set scaling 1:1 */
-#define PMS_SET_SCALE21 0xe7 /* set scaling 2:1 */
-#define PMS_SET_RES 0xe8 /* set resolution (0..3) */
-#define PMS_GET_SCALE 0xe9 /* get scaling factor */
-#define PMS_SEND_DEV_STATUS 0xe9
-#define PMS_SET_STREAM 0xea /* set streaming mode */
-#define PMS_SEND_DEV_DATA 0xeb
+#define PMS_SET_SCALE11 0xe6 /* set scaling 1:1 */
+#define PMS_SET_SCALE21 0xe7 /* set scaling 2:1 */
+#define PMS_SET_RES 0xe8 /* set resolution (0..3) */
+#define PMS_SEND_DEV_STATUS 0xe9 /* status request */
+#define PMS_SET_STREAM_MODE 0xea
+#define PMS_SEND_DEV_DATA 0xeb /* read data */
+#define PMS_RESET_WRAP_MODE 0xec
+#define PMS_SET_WRAP_MODE 0xed
#define PMS_SET_REMOTE_MODE 0xf0
-#define PMS_SEND_DEV_ID 0xf2
-#define PMS_SET_SAMPLE 0xf3 /* set sampling rate */
-#define PMS_DEV_ENABLE 0xf4 /* mouse on */
-#define PMS_DEV_DISABLE 0xf5 /* mouse off */
+#define PMS_SEND_DEV_ID 0xf2 /* read device type */
+#define PMS_SET_SAMPLE 0xf3 /* set sampling rate */
+#define PMS_DEV_ENABLE 0xf4 /* mouse on */
+#define PMS_DEV_DISABLE 0xf5 /* mouse off */
#define PMS_SET_DEFAULTS 0xf6
-#define PMS_RESET 0xff /* reset */
+#define PMS_RESEND 0xfe
+#define PMS_RESET 0xff /* reset */
+
+#define PMS_RSTDONE 0xaa
+
+/* PS/2 mouse data packet */
+#define PMS_PS2_BUTTONSMASK 0x07
+#define PMS_PS2_BUTTON1 0x01 /* left */
+#define PMS_PS2_BUTTON2 0x04 /* middle */
+#define PMS_PS2_BUTTON3 0x02 /* right */
+#define PMS_PS2_XNEG 0x10
+#define PMS_PS2_YNEG 0x20
+
+#define PMS_INTELLI_MAGIC1 200
+#define PMS_INTELLI_MAGIC2 100
+#define PMS_INTELLI_MAGIC3 80
+#define PMS_INTELLI_ID 0x03
+
+/* Synaptics queries */
+#define SYNAPTICS_QUE_IDENTIFY 0x00
+#define SYNAPTICS_QUE_MODES 0x01
+#define SYNAPTICS_QUE_CAPABILITIES 0x02
+#define SYNAPTICS_QUE_MODEL 0x03
+#define SYNAPTICS_QUE_SERIAL_NUMBER_PREFIX 0x06
+#define SYNAPTICS_QUE_SERIAL_NUMBER_SUFFIX 0x07
+#define SYNAPTICS_QUE_RESOLUTION 0x08
+#define SYNAPTICS_QUE_EXT_MODEL 0x09
+#define SYNAPTICS_QUE_EXT_CAPABILITIES 0x0c
+#define SYNAPTICS_QUE_EXT_DIMENSIONS 0x0d
+
+#define SYNAPTICS_CMD_SET_MODE 0x14
+#define SYNAPTICS_CMD_SEND_CLIENT 0x28
+#define SYNAPTICS_CMD_SET_ADV_GESTURE_MODE 0xc8
+
+/* Identify */
+#define SYNAPTICS_ID_MODEL(id) (((id) >> 4) & 0x0f)
+#define SYNAPTICS_ID_MINOR(id) (((id) >> 16) & 0xff)
+#define SYNAPTICS_ID_MAJOR(id) ((id) & 0x0f)
+#define SYNAPTICS_ID_MAGIC 0x47
+
+/* Modes bits */
+#define SYNAPTICS_ABSOLUTE_MODE (1 << 7)
+#define SYNAPTICS_HIGH_RATE (1 << 6)
+#define SYNAPTICS_SLEEP_MODE (1 << 3)
+#define SYNAPTICS_DISABLE_GESTURE (1 << 2)
+#define SYNAPTICS_FOUR_BYTE_CLIENT (1 << 1)
+#define SYNAPTICS_W_MODE (1 << 0)
+
+/* Capability bits */
+#define SYNAPTICS_CAP_EXTENDED (1 << 23)
+#define SYNAPTICS_CAP_EXTENDED_QUERIES(c) (((c) >> 20) & 0x07)
+#define SYNAPTICS_CAP_MIDDLE_BUTTON (1 << 18)
+#define SYNAPTICS_CAP_PASSTHROUGH (1 << 7)
+#define SYNAPTICS_CAP_SLEEP (1 << 4)
+#define SYNAPTICS_CAP_FOUR_BUTTON (1 << 3)
+#define SYNAPTICS_CAP_BALLISTICS (1 << 2)
+#define SYNAPTICS_CAP_MULTIFINGER (1 << 1)
+#define SYNAPTICS_CAP_PALMDETECT (1 << 0)
+
+/* Model ID bits */
+#define SYNAPTICS_MODEL_ROT180 (1 << 23)
+#define SYNAPTICS_MODEL_PORTRAIT (1 << 22)
+#define SYNAPTICS_MODEL_SENSOR(m) (((m) >> 16) & 0x3f)
+#define SYNAPTICS_MODEL_HARDWARE(m) (((m) >> 9) & 0x7f)
+#define SYNAPTICS_MODEL_NEWABS (1 << 7)
+#define SYNAPTICS_MODEL_PEN (1 << 6)
+#define SYNAPTICS_MODEL_SIMPLC (1 << 5)
+#define SYNAPTICS_MODEL_GEOMETRY(m) ((m) & 0x0f)
+
+/* Resolutions */
+#define SYNAPTICS_RESOLUTION_X(r) (((r) >> 16) & 0xff)
+#define SYNAPTICS_RESOLUTION_Y(r) ((r) & 0xff)
+
+/* Extended Model ID bits */
+#define SYNAPTICS_EXT_MODEL_LIGHTCONTROL (1 << 22)
+#define SYNAPTICS_EXT_MODEL_PEAKDETECT (1 << 21)
+#define SYNAPTICS_EXT_MODEL_VWHEEL (1 << 19)
+#define SYNAPTICS_EXT_MODEL_EW_MODE (1 << 18)
+#define SYNAPTICS_EXT_MODEL_HSCROLL (1 << 17)
+#define SYNAPTICS_EXT_MODEL_VSCROLL (1 << 16)
+#define SYNAPTICS_EXT_MODEL_BUTTONS(em) ((em >> 12) & 0x0f)
+#define SYNAPTICS_EXT_MODEL_SENSOR(em) ((em >> 10) & 0x03)
+#define SYNAPTICS_EXT_MODEL_PRODUCT(em) ((em) & 0xff)
+
+/* Extended Capability bits */
+#define SYNAPTICS_EXT_CAP_CLICKPAD (1 << 20)
+#define SYNAPTICS_EXT_CAP_ADV_GESTURE (1 << 19)
+#define SYNAPTICS_EXT_CAP_MAX_DIMENSIONS (1 << 17)
+#define SYNAPTICS_EXT_CAP_CLICKPAD_2BTN (1 << 8)
+
+/* Extended Dimensions */
+#define SYNAPTICS_DIM_X(d) ((((d) & 0xff0000) >> 11) | \
+ (((d) & 0xf00) >> 7))
+#define SYNAPTICS_DIM_Y(d) ((((d) & 0xff) << 5) | \
+ (((d) & 0xf000) >> 11))
+
+/* Typical bezel limit */
+#define SYNAPTICS_XMIN_BEZEL 1472
+#define SYNAPTICS_XMAX_BEZEL 5472
+#define SYNAPTICS_YMIN_BEZEL 1408
+#define SYNAPTICS_YMAX_BEZEL 4448
-#define PMS_RSTDONE 0xaa
+#endif /* !define(SYS_DEV_PCKBC_PMSREG_H) */
Index: dev/wscons/wsmouse.c
===================================================================
RCS file: /cvs/src/sys/dev/wscons/wsmouse.c,v
retrieving revision 1.21
diff -u -p -r1.21 wsmouse.c
--- dev/wscons/wsmouse.c 26 Jul 2010 01:56:27 -0000 1.21
+++ dev/wscons/wsmouse.c 6 Jul 2011 06:35:28 -0000
@@ -507,6 +507,14 @@ wsmouseopen(dev_t dev, int flags, int mo
return (0); /* always allow open for write
so ioctl() is possible. */
+#if NWSMUX > 0
+ if (sc->sc_base.me_parent != NULL) {
+ /* Grab the mouse out of the greedy hands of the mux. */
+ DPRINTF(("wsmouseopen: detach\n"));
+ wsmux_detach_sc(&sc->sc_base);
+ }
+#endif
+
if (sc->sc_base.me_evp != NULL)
return (EBUSY);
@@ -540,6 +548,21 @@ wsmouseclose(dev_t dev, int flags, int m
sc->sc_base.me_evp = NULL;
(*sc->sc_accessops->disable)(sc->sc_accesscookie);
wsevent_fini(evar);
+
+#if NWSMUX > 0
+ if (sc->sc_base.me_parent == NULL) {
+ int mux, error;
+
+ DPRINTF(("wsmouseclose: attach\n"));
+ mux = sc->sc_base.me_dv.dv_cfdata->wsmousedevcf_mux;
+ if (mux >= 0) {
+ error = wsmux_attach_sc(wsmux_getmux(mux),
&sc->sc_base);
+ if (error)
+ printf("%s: can't attach mux (error=%d)\n",
+ sc->sc_base.me_dv.dv_xname, error);
+ }
+ }
+#endif
return (0);
}