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) */