diff options
author | yokota <yokota@FreeBSD.org> | 1999-08-17 12:14:13 +0000 |
---|---|---|
committer | yokota <yokota@FreeBSD.org> | 1999-08-17 12:14:13 +0000 |
commit | 07e185d5d22b6bf3ae7cbe52f179f8b0430a8ba7 (patch) | |
tree | 14001c24e51511731e05fcd195611a323407fc0b /sys/isa/psm.c | |
parent | f7e3121c8c384eae668e8194c0bd2bdb39fb7f35 (diff) | |
download | FreeBSD-src-07e185d5d22b6bf3ae7cbe52f179f8b0430a8ba7.zip FreeBSD-src-07e185d5d22b6bf3ae7cbe52f179f8b0430a8ba7.tar.gz |
Recognize Interlink VersaPad. `Tap' action will be recognized
as the button 4.
Submitted by: Masachika ISHIZUKA <ishizuka@ish.org>
Diffstat (limited to 'sys/isa/psm.c')
-rw-r--r-- | sys/isa/psm.c | 104 |
1 files changed, 100 insertions, 4 deletions
diff --git a/sys/isa/psm.c b/sys/isa/psm.c index 467c769..fa5ba72 100644 --- a/sys/isa/psm.c +++ b/sys/isa/psm.c @@ -20,7 +20,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: psm.c,v 1.13 1999/07/12 13:40:21 yokota Exp $ + * $Id: psm.c,v 1.14 1999/07/12 15:16:04 yokota Exp $ */ /* @@ -179,6 +179,8 @@ struct psm_softc { /* Driver status information */ unsigned char ipacket[16]; /* interim input buffer */ int inputbytes; /* # of bytes in the input buffer */ int button; /* the latest button state */ + int xold; /* previous absolute X position */ + int yold; /* previous absolute Y position */ #ifdef DEVFS void *devfs_token; void *b_devfs_token; @@ -213,6 +215,7 @@ devclass_t psm_devclass; | PSM_CONFIG_IGNPORTERROR) /* other flags (flags) */ +#define PSM_FLAGS_FINGERDOWN 0x0001 /* VersaPad finger down */ /* for backward compatibility */ #define OLD_MOUSE_GETHWINFO _IOR('M', 1, old_mousehw_t) @@ -281,6 +284,7 @@ static probefunc_t enable_aglide; static probefunc_t enable_kmouse; static probefunc_t enable_msintelli; static probefunc_t enable_mmanplus; +static probefunc_t enable_versapad; static int tame_mouse __P((struct psm_softc *, mousestatus_t *, unsigned char *)); static struct { @@ -301,10 +305,12 @@ static struct { 0x80, MOUSE_PS2_PACKETSIZE, enable_kmouse, }, { MOUSE_MODEL_INTELLI, /* Microsoft IntelliMouse */ 0xc8, MOUSE_INTELLI_PACKETSIZE, enable_msintelli, }, + { MOUSE_MODEL_VERSAPAD, /* Interlink electronics VersaPad */ + 0xe8, MOUSE_PS2VERSA_PACKETSIZE, enable_versapad, }, { MOUSE_MODEL_GENERIC, 0xc0, MOUSE_PS2_PACKETSIZE, NULL, }, }; -#define GENERIC_MOUSE_ENTRY 6 +#define GENERIC_MOUSE_ENTRY 7 /* device driver declarateion */ static device_method_t psm_methods[] = { @@ -563,6 +569,7 @@ model_name(int model) { MOUSE_MODEL_THINK, "ThinkingMouse" }, { MOUSE_MODEL_INTELLI, "IntelliMouse" }, { MOUSE_MODEL_MOUSEMANPLUS, "MouseMan+" }, + { MOUSE_MODEL_VERSAPAD, "VersaPad" }, { MOUSE_MODEL_GENERIC, "Generic PS/2 mouse" }, { MOUSE_MODEL_UNKNOWN, NULL }, }; @@ -1794,11 +1801,22 @@ psmintr(void *arg) MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN, MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN }; + static int butmap_versapad[8] = { + 0, + MOUSE_BUTTON3DOWN, + 0, + MOUSE_BUTTON3DOWN, + MOUSE_BUTTON1DOWN, + MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN, + MOUSE_BUTTON1DOWN, + MOUSE_BUTTON1DOWN | MOUSE_BUTTON3DOWN + }; register struct psm_softc *sc = arg; mousestatus_t ms; int x, y, z; int c; int l; + int x0, y0; /* read until there is nothing to read */ while((c = read_aux_data_no_wait(sc->kbdc)) != -1) { @@ -1831,14 +1849,15 @@ psmintr(void *arg) c = sc->ipacket[0]; - /* + /* * A kludge for Kensington device! * The MSB of the horizontal count appears to be stored in * a strange place. This kludge doesn't affect other mice * because the bit is the overflow bit which is, in most cases, * expected to be zero when we reach here. XXX */ - sc->ipacket[1] |= (c & MOUSE_PS2_XOVERFLOW) ? 0x80 : 0; + if (sc->hw.model != MOUSE_MODEL_VERSAPAD) + sc->ipacket[1] |= (c & MOUSE_PS2_XOVERFLOW) ? 0x80 : 0; /* ignore the overflow bits... */ x = (c & MOUSE_PS2_XNEG) ? sc->ipacket[1] - 256 : sc->ipacket[1]; @@ -1946,6 +1965,61 @@ psmintr(void *arg) ms.button |= (c & MOUSE_PS2_TAP) ? MOUSE_BUTTON4DOWN : 0; break; + case MOUSE_MODEL_VERSAPAD: + /* VersaPad PS/2 absolute mode message format + * + * [packet1] 7 6 5 4 3 2 1 0(LSB) + * ipacket[0]: 1 1 0 A 1 L T R + * ipacket[1]: H7 H6 H5 H4 H3 H2 H1 H0 + * ipacket[2]: V7 V6 V5 V4 V3 V2 V1 V0 + * ipacket[3]: 1 1 1 A 1 L T R + * ipacket[4]:V11 V10 V9 V8 H11 H10 H9 H8 + * ipacket[5]: 0 P6 P5 P4 P3 P2 P1 P0 + * + * [note] + * R: right physical mouse button (1=on) + * T: touch pad virtual button (1=tapping) + * L: left physical mouse button (1=on) + * A: position data is valid (1=valid) + * H: horizontal data (12bit signed integer. H11 is sign bit.) + * V: vertical data (12bit signed integer. V11 is sign bit.) + * P: pressure data + * + * Tapping is mapped to MOUSE_BUTTON4. + */ + ms.button = butmap_versapad[c & MOUSE_PS2VERSA_BUTTONS]; + ms.button |= (c & MOUSE_PS2VERSA_TAP) ? MOUSE_BUTTON4DOWN : 0; + x = y = 0; + if (c & MOUSE_PS2VERSA_IN_USE) { + x0 = sc->ipacket[1] | (((sc->ipacket[4]) & 0x0f) << 8); + y0 = sc->ipacket[2] | (((sc->ipacket[4]) & 0xf0) << 4); + if (x0 & 0x800) + x0 -= 0x1000; + if (y0 & 0x800) + y0 -= 0x1000; + if (sc->flags & PSM_FLAGS_FINGERDOWN) { + x = sc->xold - x0; + y = y0 - sc->yold; + if (x < 0) /* XXX */ + x++; + else if (x) + x--; + if (y < 0) + y++; + else if (y) + y--; + } else { + sc->flags |= PSM_FLAGS_FINGERDOWN; + } + sc->xold = x0; + sc->yold = y0; + } else { + sc->flags &= ~PSM_FLAGS_FINGERDOWN; + } + c = ((x < 0) ? MOUSE_PS2_XNEG : 0) + | ((y < 0) ? MOUSE_PS2_YNEG : 0); + break; + case MOUSE_MODEL_GENERIC: default: break; @@ -2289,6 +2363,28 @@ enable_msintelli(struct psm_softc *sc) return TRUE; } +/* Interlink electronics VersaPad */ +static int +enable_versapad(struct psm_softc *sc) +{ + KBDC kbdc = sc->kbdc; + int data[3]; + + set_mouse_resolution(kbdc, PSMD_RES_MEDIUM_HIGH); /* set res. 2 */ + set_mouse_sampling_rate(kbdc, 100); /* set rate 100 */ + set_mouse_scaling(kbdc, 1); /* set scale 1:1 */ + set_mouse_scaling(kbdc, 1); /* set scale 1:1 */ + set_mouse_scaling(kbdc, 1); /* set scale 1:1 */ + set_mouse_scaling(kbdc, 1); /* set scale 1:1 */ + if (get_mouse_status(kbdc, data, 0, 3) < 3) /* get status */ + return FALSE; + if (data[2] != 0xa || data[1] != 0 ) /* rate == 0xa && res. == 0 */ + return FALSE; + set_mouse_scaling(kbdc, 1); /* set scale 1:1 */ + + return TRUE; /* PS/2 absolute mode */ +} + #ifdef PSM_HOOKAPM static int psmresume(void *dummy) |