============================================= (cd /usr/src && patch -p6) < synaptic-current.diff ============================================= --- //depot/vendor/freebsd/src/sys/isa/psm.c 2004/07/16 22:05:34 +++ //depot/user/nork/nork_mobile/sys/isa/psm.c 2004/07/28 16:00:19 @@ -159,6 +159,7 @@ struct resource *intr; /* IRQ resource */ void *ih; /* interrupt handle */ mousehw_t hw; /* hardware information */ + synapticshw_t synhw; /* Synaptics specific hardware information */ mousemode_t mode; /* operation mode */ mousemode_t dflt_mode; /* default operation mode */ mousestatus_t status; /* accumulated mouse movement */ @@ -290,6 +291,7 @@ static probefunc_t enable_4dmouse; static probefunc_t enable_4dplus; static probefunc_t enable_mmanplus; +static probefunc_t enable_synaptics; static probefunc_t enable_versapad; static int tame_mouse(struct psm_softc *, packetbuf_t *, mousestatus_t *, unsigned char *); @@ -323,6 +325,8 @@ 0x80, MOUSE_PS2_PACKETSIZE, enable_kmouse, }, { MOUSE_MODEL_VERSAPAD, /* Interlink electronics VersaPad */ 0xe8, MOUSE_PS2VERSA_PACKETSIZE, enable_versapad, }, + { MOUSE_MODEL_SYNAPTICS, /* Synaptics Touchpad */ + 0xc0, MOUSE_SYNAPTICS_PACKETSIZE, enable_synaptics, }, { MOUSE_MODEL_GENERIC, 0xc0, MOUSE_PS2_PACKETSIZE, NULL, }, }; @@ -578,6 +582,7 @@ { MOUSE_MODEL_EXPLORER, "IntelliMouse Explorer" }, { MOUSE_MODEL_4D, "4D Mouse" }, { MOUSE_MODEL_4DPLUS, "4D+ Mouse" }, + { MOUSE_MODEL_SYNAPTICS, "Synaptics Touchpad" }, { MOUSE_MODEL_GENERIC, "Generic PS/2 mouse" }, { MOUSE_MODEL_UNKNOWN, NULL }, }; @@ -1719,6 +1724,12 @@ splx(s); break; + case MOUSE_SYNGETHWINFO: + s = spltty(); + *(synapticshw_t *)addr = sc->synhw; + splx(s); + break; + case OLD_MOUSE_GETMODE: s = spltty(); switch (sc->mode.level) { @@ -1896,6 +1907,28 @@ unblock_mouse_data(sc, command_byte); break; + case MOUSE_SYNAPTICS_CMD: + if (sc->hw.model != MOUSE_MODEL_SYNAPTICS || sc->mode.level < PSM_LEVEL_NATIVE) + return EINVAL; + + mouse_ext_command(sc->kbdc, *(int *)addr); + set_mouse_sampling_rate(sc->kbdc, 0x0014); + break; + + case MOUSE_SYNAPTICS_INFO: + if (sc->hw.model != MOUSE_MODEL_SYNAPTICS || sc->mode.level < PSM_LEVEL_NATIVE) + return EINVAL; + + mouse_ext_command(sc->kbdc, *(int *)addr); + send_aux_command(sc->kbdc, PSMC_SEND_DEV_STATUS); + set_mouse_sampling_rate(sc->kbdc, 0x0014); + break; + + case MOUSE_SYNAPTICS_ENABLE_PASSTHROUGH: + if (sc->hw.model != MOUSE_MODEL_SYNAPTICS || sc->mode.level < PSM_LEVEL_NATIVE) + return EINVAL; + break; + #if (defined(MOUSE_SETRESOLUTION)) case MOUSE_SETRESOLUTION: mode.resolution = *(int *)addr; @@ -2154,7 +2187,7 @@ }; register struct psm_softc *sc = arg; mousestatus_t ms; - int x, y, z; + int x, y, z, w; int c; int l; int x0, y0; @@ -2444,6 +2477,85 @@ } break; + case MOUSE_MODEL_SYNAPTICS: + /* TouchPad PS/2 absolute mode message format + * + * Bits: 7 6 5 4 3 2 1 0 (LSB) + * ------------------------------------------------ + * ipacket[0]: 1 0 W3 W2 0 W1 R L + * ipacket[1]: Yb Ya Y9 Y8 Xb Xa X9 X8 + * ipacket[2]: Z7 Z6 Z5 Z4 Z3 Z2 Z1 Z0 + * ipacket[3]: 1 1 Yc Xc 0 W0 D U + * ipacket[4]: X7 X6 X5 X4 X3 X2 X1 X0 + * ipacket[5]: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 + * + * Legend: + * L: left physical mouse button + * R: right physical mouse button + * D: down button + * U: up button + * W: "wrist" value + * X: x position + * Y: x position + * Z: pressure + * + * Absolute reportable limits: 0 - 6143. + * Typical bezel limites: 1472 - 5472. + * Typical edge marings: 1632 - 5312. + * w = 3 Passthrough Packet + * (I hope I guessed right, but looks as if I had luck :)) + * + * Byte 2,5,6 == Byte 1,2,3 of "Guest" + */ + + /* Sanity check for out of sync packets. */ + if ((pb->ipacket[0] & 0xc8) != 0x80 || (pb->ipacket[3] & 0xc8) != 0xc0) + continue; + + x = y = x0 = y0 = 0; + + /* pressure */ + z = pb->ipacket[2]; + w = ((pb->ipacket[0] & 0x30) >> 2) | + ((pb->ipacket[0] & 0x04) >> 1) | + ((pb->ipacket[3] & 0x04) >> 2); + + ms.button = 0; + if (pb->ipacket[0] & 0x01) + ms.button |= MOUSE_BUTTON1DOWN; + if (pb->ipacket[0] & 0x02) + ms.button |= MOUSE_BUTTON3DOWN; + + if ((pb->ipacket[3] & 0x01) && !(pb->ipacket[0] & 0x01)) + ms.button |= MOUSE_BUTTON2DOWN; + if ((pb->ipacket[3] & 0x02) && !(pb->ipacket[0] & 0x02)) + ms.button |= MOUSE_BUTTON4DOWN; + + /* There is a finger on the pad */ + if ((w >= 4 && w <= 7) && (z >= 16 && z < 200) ) { + x0 = ((pb->ipacket[3] & 0x10) << 8) | ((pb->ipacket[1] & 0x0f) << 8) | + pb->ipacket[4]; + y0 = ((pb->ipacket[3] & 0x20) << 7) | ((pb->ipacket[1] & 0xf0) << 4) | + pb->ipacket[5]; + + if (sc->flags & PSM_FLAGS_FINGERDOWN) { + x0 = (x0 + sc->xold * 3) / 4; + y0 = (y0 + sc->yold * 3) / 4; + + x = (x0 - sc->xold) / 4; + y = (y0 - sc->yold) / 4; + } else { + sc->flags |= PSM_FLAGS_FINGERDOWN; + } + + sc->xold = x0; + sc->yold = y0; + } else { + sc->flags &= ~PSM_FLAGS_FINGERDOWN; + } + z = 0; + break; + case MOUSE_MODEL_GENERIC: default: break; @@ -2667,6 +2779,126 @@ return TRUE; } +/* Synaptics Touchpad */ +static int +enable_synaptics(struct psm_softc *sc) +{ + int status[3]; + + KBDC kbdc = sc->kbdc; + + disable_aux_dev(kbdc); + set_mouse_scaling(kbdc, 1); /* Just to be on the safe side */ + + if(!mouse_ext_command(kbdc, 0)) + return FALSE; + + if( get_mouse_status(kbdc, status, 0, 3) != 3) + return FALSE; + + if(status[1] != 0x47) /* If it is a Synaptics byte2 is $47 */ + return FALSE; + + /* Identify the Touchpad version number */ + sc->synhw.infoMinor = status[0]; /* the first Byte contains the minor version number */ + /* the lower 4 bits of third Byte contain the infoMajor */ + /* the upper 4 bits of third Byte contain the (obsolte) infoModelCode */ + sc->synhw.infoMajor = status[2] & 0x0f; + if(verbose >= 2) { + printf("Synaptics Touchpad:\n"); + printf(" Version: %d.%d\n", sc->synhw.infoMajor, sc->synhw.infoMinor); + } + + if(sc->synhw.infoMajor < 4) { + printf("Synaptics prior Version 4 detected, this is not (yet?) supported\n"); + return FALSE; + } + + if(!mouse_ext_command(kbdc, 3)) + return FALSE; + + if(get_mouse_status(kbdc, status, 0, 3) != 3) + return FALSE; + + if((status[1] & 0x01) != 0) { + printf(" Could not read Model id Bytes from the Touchpad"); + return FALSE; + } + + sc->synhw.infoRot180 = (status[0] & 0x80) >> 7; + sc->synhw.infoPortrait = (status[0] & 0x40) >> 6; + sc->synhw.infoSensor = status[0] & 0x3f; + sc->synhw.infoHardware = (status[1] & 0xfe) >> 1; + sc->synhw.infoNewAbs = (status[2] & 0x80) >> 7; + sc->synhw.capPen = (status[2] & 0x40) >> 6; + sc->synhw.infoSimplC = (status[2] & 0x20) >> 5; + sc->synhw.infoGeometry = status[2] & 0x0f; + if(verbose >= 2) { + printf(" Model id: %02x %02x %02x\n", status[0] , status[1] , status[2]); + printf(" infoRot180: %d\n",sc->synhw.infoRot180); + printf(" infoPortrait: %d\n",sc->synhw.infoPortrait); + printf(" infoSensor: %d\n",sc->synhw.infoSensor); + printf(" infoHardware: %d\n",sc->synhw.infoHardware); + printf(" infoNewAbs: %d\n",sc->synhw.infoNewAbs); + printf(" capPen: %d\n",sc->synhw.capPen); + printf(" infoSimplC: %d\n",sc->synhw.infoSimplC); + printf(" infoGeometry: %d\n",sc->synhw.infoGeometry); + } + + if(!mouse_ext_command(kbdc, 2)) + return FALSE; + + if(get_mouse_status(kbdc, status, 0, 3) != 3) + return FALSE; + + if(status[1] != 0x47) { + printf(" Could not read Capabilities from the Touchpad\n"); + return FALSE; + } + + sc->synhw.capExtended = (status[0] & 0x80) >> 7; + sc->synhw.capPassthrough = (status[2] & 0x80) >> 7; + sc->synhw.capSleep = (status[2] & 0x10) >> 4; + sc->synhw.capFourButtons = (status[2] & 0x08) >> 3; + sc->synhw.capMultiFinger = (status[2] & 0x02) >> 1; + sc->synhw.capPalmDetect = (status[2] & 0x01); + if(verbose >= 2) { + printf(" Capability Bytes: %02x %02x %02x\n", status[0], status[1], status[2]); + } + + + if(!mouse_ext_command(kbdc, 1)) + return FALSE; + + if(get_mouse_status(kbdc, status, 0, 3) != 3) + return FALSE; + + if(status[0] != 0x3b || status[1] != 0x47) { + printf(" Could not read Mode Byte from the Touchpad\n"); + return FALSE; + } + + if(verbose >= 2) + printf(" Mode Byte set by Bios: %02x\n" , status[2]); + + /* Mode Byte + 1 (absolute) + 1 rate (0 = 40/1 = 80) + 0 + 0 (reserved) + 0 (Sleep (Only buttons)) + 0 DisGest (not for absolute Mode) + 0 pktsize (0 for ps2) + 1 wmode + */ + sc->hw.buttons = 3; + + mouse_ext_command(kbdc, 0xc1); /* encode mode byte */ + set_mouse_sampling_rate(kbdc, 0x0014); /* set mode byte */ + + return TRUE; +} + /* Kensington ThinkingMouse/Trackball */ static int enable_kmouse(struct psm_softc *sc) --- //depot/vendor/freebsd/src/sys/sys/mouse.h 2002/03/24 03:10:16 +++ //depot/user/nork/nork_mobile/sys/sys/mouse.h 2004/04/11 16:11:36 @@ -40,6 +40,10 @@ #define MOUSE_SETVARS _IOW('M', 7, mousevar_t) #define MOUSE_READSTATE _IOWR('M', 8, mousedata_t) #define MOUSE_READDATA _IOWR('M', 9, mousedata_t) +#define MOUSE_SYNAPTICS_CMD _IOW('M', 10, char) +#define MOUSE_SYNAPTICS_INFO _IOW('M', 11, char) +#define MOUSE_SYNAPTICS_ENABLE_PASSTHROUGH _IOW('M', 12, char) +#define MOUSE_SYNGETHWINFO _IOR('M', 13, synapticshw_t) #if notyet #define MOUSE_SETRESOLUTION _IOW('M', 10, int) @@ -88,6 +92,25 @@ */ } mousehw_t; +typedef struct synapticshw { + int infoMajor; + int infoMinor; + int infoRot180; + int infoPortrait; + int infoSensor; + int infoHardware; + int infoNewAbs; + int capPen; + int infoSimplC; + int infoGeometry; + int capExtended; + int capSleep; + int capFourButtons; + int capMultiFinger; + int capPalmDetect; + int capPassthrough; +} synapticshw_t; + /* iftype */ #define MOUSE_IF_UNKNOWN (-1) #define MOUSE_IF_SERIAL 0 @@ -119,6 +142,7 @@ #define MOUSE_MODEL_EXPLORER 10 #define MOUSE_MODEL_4D 11 #define MOUSE_MODEL_4DPLUS 12 +#define MOUSE_MODEL_SYNAPTICS 13 typedef struct mousemode { int protocol; /* MOUSE_PROTO_XXX */ @@ -185,6 +209,10 @@ #endif /* MOUSE_GETVARS */ +/* Synaptics Touchpad */ +#define MOUSE_SYNAPTICS_PACKETSIZE 6 +/* Packetsize 6 is the real packetsize but that 3 works better :) */ + /* Microsoft Serial mouse data packet */ #define MOUSE_MSS_PACKETSIZE 3 #define MOUSE_MSS_SYNCMASK 0x40