Hi,
Default touchpad behaves as mouse (compatible with xf86-input-mouse)
for full power need used xf86-input-synaptics.
Please check work of touchpad in compat mode (xf86-input-mouse),
who are interested check xf86-input-synaptics.
Driver xf86-input-synaptics need to build manually:
update src and xenocara tree
cd /usr/src
make obj includes
cd /usr/xenocara/driver/xf86-input-synaptics
make -f Makefile.bsd-wrapper obj build
--
Alexandr Shadchin
Index: pms.c
===================================================================
RCS file: /cvs/src/sys/dev/pckbc/pms.c,v
retrieving revision 1.18
diff -u -p -r1.18 pms.c
--- pms.c 3 Jan 2011 19:46:34 -0000 1.18
+++ pms.c 7 May 2011 21:27:46 -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,30 @@ 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;
+ int count;
+#define SYNAPTICS_COUNT 2
+#define SYNAPTICS_SCALE 4
+#define SYNAPTICS_PRESSURE 30
+#define SYNAPTICS_MAXSPEED 30
+
+ int dev_pt_attach;
+};
+
struct pms_softc { /* driver status information */
struct device sc_dev;
@@ -64,56 +92,48 @@ 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;
+ int is_touchpad;
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 +149,21 @@ 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 *);
+
+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,6 +179,12 @@ const struct wsmouse_accessops pms_acces
pms_disable,
};
+const struct wsmouse_accessops synaptics_pt_accessops = {
+ synaptics_pt_enable,
+ synaptics_pt_ioctl,
+ synaptics_pt_disable,
+};
+
const struct pms_protocol pms_mouse[] = {
/* Generic PS/2 mouse */
{
@@ -165,6 +206,18 @@ const struct pms_protocol pms_mouse[] =
}
};
+const struct pms_protocol pms_touchpad[] = {
+ /* Synaptics touchpad */
+ {
+ PMS_SYNAPTICS, 6,
+ pms_enable_synaptics,
+ pms_ioctl_synaptics,
+ pms_sync_synaptics,
+ pms_proc_synaptics,
+ pms_disable_synaptics
+ }
+};
+
int
pms_cmd(struct pms_softc *sc, u_char *cmd, int len, u_char *resp, int resplen)
{
@@ -178,6 +231,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 +460,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 +480,26 @@ 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;
+
+ /* init protocol as generic mouse */
+ sc->protocol = &pms_mouse[0];
+
+ /* try detect touchpad */
+ sc->is_touchpad = 0;
+ for (i = 0; i < nitems(pms_touchpad); i++) {
+ pms_reset(sc);
+ if (pms_touchpad[i].enable(sc)) {
+ sc->protocol = &pms_touchpad[i];
+ sc->is_touchpad = 1;
+ break;
+ }
+ }
+
+ /* no interrupts until enabled */
+ pms_change_state(sc, PMS_STATE_DISABLED, PMS_DEV_IGNORE);
}
int
@@ -429,26 +510,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 +560,14 @@ 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->is_touchpad) {
+ sc->protocol->enable(sc);
+ } else {
+ sc->protocol = &pms_mouse[0];
+ for (i = 1; i < nitems(pms_mouse); i++)
+ if (pms_mouse[i].enable(sc))
+ sc->protocol = &pms_mouse[i];
+ }
#ifdef DEBUG
printf("%s: protocol type %d\n", DEVNAME(sc),
sc->protocol->type);
@@ -491,7 +597,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 +605,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
@@ -537,4 +643,314 @@ 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);
+}
+
+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, first = 0;
+
+ 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) {
+ syn = malloc(sizeof(struct synaptics_softc), M_DEVBUF,
+ M_WAITOK | M_ZERO);
+ sc->synaptics = syn;
+ first = 1;
+ }
+
+ synaptics_query(sc, SYNAPTICS_QUE_IDENTIFY, &syn->identify);
+ synaptics_query(sc, SYNAPTICS_QUE_CAPABILITIES, &syn->capabilities);
+ synaptics_query(sc, SYNAPTICS_QUE_MODEL, &syn->model);
+
+ if ((syn->model & SYNAPTICS_MODEL_NEWABS) == 0) {
+ printf("%s: don't support Synaptics OLDABS\n", DEVNAME(sc));
+ return (0);
+ }
+
+ 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);
+
+ if (SYNAPTICS_CAP_EXTENDED_QUERIES(syn->capabilities) >= 1)
+ synaptics_query(sc, SYNAPTICS_QUE_EXT_MODEL, &syn->ext_model);
+ if (SYNAPTICS_CAP_EXTENDED_QUERIES(syn->capabilities) >= 4)
+ synaptics_query(sc, SYNAPTICS_QUE_EXT_CAPABILITIES,
+ &syn->ext_capabilities);
+ if (SYNAPTICS_ID_MAJOR(syn->identify) >= 4)
+ synaptics_query(sc, SYNAPTICS_QUE_RESOLUTION, &syn->resolution);
+ 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);
+ }
+
+ 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;
+
+ if ((syn->dev_pt_attach == 0) &&
+ (syn->capabilities & SYNAPTICS_CAP_PASSTHROUGH)) {
+ a.accessops = &synaptics_pt_accessops;
+ a.accesscookie = sc;
+ sc->sc_pt_wsmousedev = config_found((void *)sc, &a,
+ wsmousedevprint);
+ syn->dev_pt_attach = 1;
+ }
+
+ if (first) {
+ syn->wsmode = WSMOUSE_COMPAT;
+ syn->count = 0;
+
+ printf("%s: Synaptics touchpad, firmware %d.%d\n", DEVNAME(sc),
+ SYNAPTICS_ID_MAJOR(syn->identify),
+ SYNAPTICS_ID_MINOR(syn->identify));
+ }
+
+ 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;
+
+ 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:
+ syn->wsmode = (*(u_int *)data == WSMOUSE_NATIVE);
+ 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;
+
+ 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] & 0x01) & (sc->packet[3] & 0x01)) ?
+ WSMOUSE_BUTTON(1) : 0;
+ buttons |= ((sc->packet[0] & 0x02) & (sc->packet[3] & 0x02)) ?
+ WSMOUSE_BUTTON(3) : 0;
+
+ if (syn->capabilities & SYNAPTICS_CAP_MIDDLE_BUTTON) {
+ buttons |= ((sc->packet[0] & 0x01) ^ (sc->packet[3] & 0x01)) ?
+ WSMOUSE_BUTTON(2) : 0;
+ }
+
+ if (syn->capabilities & SYNAPTICS_CAP_FOUR_BUTTON) {
+ buttons |= ((sc->packet[0] & 0x01) ^ (sc->packet[3] & 0x01)) ?
+ WSMOUSE_BUTTON(4) : 0;
+ buttons |= ((sc->packet[0] & 0x02) ^ (sc->packet[3] & 0x02)) ?
+ WSMOUSE_BUTTON(5) : 0;
+ } else if (SYNAPTICS_EXT_MODEL_BUTTONS(syn->ext_model) &&
+ ((sc->packet[0] & 0x02) ^ (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;
+ }
+
+ 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 {
+ if (syn->count < SYNAPTICS_COUNT) {
+ syn->old_x += x;
+ syn->old_y += y;
+ syn->count++;
+ return;
+ }
+
+ syn->old_x /= SYNAPTICS_COUNT;
+ syn->old_y /= SYNAPTICS_COUNT;
+ dx = x - syn->old_x;
+ dy = y - syn->old_y;
+ syn->old_x = (dx % SYNAPTICS_SCALE) * SYNAPTICS_COUNT;
+ syn->old_y = (dy % SYNAPTICS_SCALE) * SYNAPTICS_COUNT;
+ dx /= SYNAPTICS_SCALE;
+ dy /= SYNAPTICS_SCALE;
+ syn->count = 0;
+
+ if (z < SYNAPTICS_PRESSURE) {
+ dx = dy = 0;
+ syn->old_x = syn->old_y = 0;
+ syn->count = 0;
+ }
+
+ if (abs(dx) > SYNAPTICS_MAXSPEED)
+ dx = SYNAPTICS_MAXSPEED * dx / abs(dx);
+ if (abs(dy) > SYNAPTICS_MAXSPEED)
+ dy = SYNAPTICS_MAXSPEED * dy / abs(dy);
+
+ wsmouse_input(sc->sc_wsmousedev, buttons, dx, dy, 0, 0,
+ WSMOUSE_INPUT_DELTA);
+ }
+}
+
+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: pmsreg.h
===================================================================
RCS file: /cvs/src/sys/dev/pckbc/pmsreg.h,v
retrieving revision 1.1
diff -u -p -r1.1 pmsreg.h
--- pmsreg.h 1 Aug 2007 12:16:59 -0000 1.1
+++ pmsreg.h 7 May 2011 21:27:46 -0000
@@ -1,20 +1,123 @@
/* $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
+
+/* 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_MULTITOUCH (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) */