Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S265731AbTFNUgc (ORCPT ); Sat, 14 Jun 2003 16:36:32 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S265730AbTFNUe5 (ORCPT ); Sat, 14 Jun 2003 16:34:57 -0400 Received: from twilight.ucw.cz ([81.30.235.3]:41194 "EHLO twilight.ucw.cz") by vger.kernel.org with ESMTP id S265710AbTFNUci (ORCPT ); Sat, 14 Jun 2003 16:32:38 -0400 Date: Sat, 14 Jun 2003 22:46:19 +0200 From: Vojtech Pavlik To: Vojtech Pavlik Cc: torvalds@transmeta.com, linux-kernel@vger.kernel.org Subject: [patch] input: Add Synaptics touchpad support [13/13] Message-ID: <20030614224619.L25997@ucw.cz> References: <20030614223708.B25997@ucw.cz> <20030614223934.C25997@ucw.cz> <20030614224022.D25997@ucw.cz> <20030614224052.E25997@ucw.cz> <20030614224149.F25997@ucw.cz> <20030614224253.G25997@ucw.cz> <20030614224358.H25997@ucw.cz> <20030614224432.I25997@ucw.cz> <20030614224510.J25997@ucw.cz> <20030614224549.K25997@ucw.cz> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <20030614224549.K25997@ucw.cz>; from vojtech@suse.cz on Sat, Jun 14, 2003 at 10:45:49PM +0200 Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 19713 Lines: 662 You can pull this changeset from: bk://kernel.bkbits.net/vojtech/input =================================================================== ChangeSet@1.1307.5.13, 2003-06-14 18:33:19+02:00, petero2@telia.com input: Add Synaptics touchpad absolute mode support. b/drivers/input/mouse/Kconfig | 13 b/drivers/input/mouse/Makefile | 5 b/drivers/input/mouse/psmouse-base.c | 661 +++++++++++++++++++++++++++++++++ b/drivers/input/mouse/psmouse.h | 49 ++ b/drivers/input/mouse/synaptics.c | 390 +++++++++++++++++++ b/drivers/input/mouse/synaptics.h | 105 +++++ b/include/linux/input.h | 1 drivers/input/mouse/psmouse.c | 689 ----------------------------------- 8 files changed, 1224 insertions(+), 689 deletions(-) =================================================================== diff -Nru a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig --- a/drivers/input/mouse/Kconfig Sat Jun 14 22:24:35 2003 +++ b/drivers/input/mouse/Kconfig Sat Jun 14 22:24:35 2003 @@ -28,6 +28,19 @@ The module will be called psmouse. If you want to compile it as a module, say M here and read . +config MOUSE_PS2_SYNAPTICS + bool "Synaptics TouchPad" + default n + depends on INPUT && INPUT_MOUSE && SERIO && MOUSE_PS2 + ---help--- + Say Y here if you have a Synaptics TouchPad connected to your system. + This touchpad is found on many modern laptop computers. + Note that you also need a user space driver to interpret the data + generated by the kernel. A compatible driver for XFree86 is available + from http://... + + If unsure, say Y. + config MOUSE_SERIAL tristate "Serial mouse" depends on INPUT && INPUT_MOUSE && SERIO diff -Nru a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile --- a/drivers/input/mouse/Makefile Sat Jun 14 22:24:35 2003 +++ b/drivers/input/mouse/Makefile Sat Jun 14 22:24:35 2003 @@ -13,3 +13,8 @@ obj-$(CONFIG_MOUSE_PC9800) += 98busmouse.o obj-$(CONFIG_MOUSE_PS2) += psmouse.o obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o + +psmouse-objs := psmouse-base.o +ifeq ($(CONFIG_MOUSE_PS2_SYNAPTICS),y) + psmouse-objs += synaptics.o +endif diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/input/mouse/psmouse-base.c Sat Jun 14 22:24:35 2003 [snip] + if (psmouse->pktcnt == 1 && psmouse->type == PSMOUSE_SYNAPTICS) { + /* + * The synaptics driver has its own resync logic, + * so it needs to receive all bytes one at a time. + */ + synaptics_process_byte(psmouse, regs); + psmouse->pktcnt = 0; + goto out; + } [snip] +/* + * Try Synaptics TouchPad magic ID + */ + + param[0] = 0; + psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); + psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); + psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); + psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); + psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO); + + if (param[1] == 0x47) { + psmouse->vendor = "Synaptics"; + psmouse->name = "TouchPad"; + if (!synaptics_init(psmouse)) + return PSMOUSE_SYNAPTICS; + else + return PSMOUSE_PS2; + } diff -Nru a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/input/mouse/psmouse.h Sat Jun 14 22:24:35 2003 @@ -0,0 +1,49 @@ +#ifndef _PSMOUSE_H +#define _PSMOUSE_H + +#define PSMOUSE_CMD_SETSCALE11 0x00e6 +#define PSMOUSE_CMD_SETRES 0x10e8 +#define PSMOUSE_CMD_GETINFO 0x03e9 +#define PSMOUSE_CMD_SETSTREAM 0x00ea +#define PSMOUSE_CMD_POLL 0x03eb +#define PSMOUSE_CMD_GETID 0x02f2 +#define PSMOUSE_CMD_SETRATE 0x10f3 +#define PSMOUSE_CMD_ENABLE 0x00f4 +#define PSMOUSE_CMD_RESET_DIS 0x00f6 +#define PSMOUSE_CMD_RESET_BAT 0x02ff + +#define PSMOUSE_RET_BAT 0xaa +#define PSMOUSE_RET_ACK 0xfa +#define PSMOUSE_RET_NAK 0xfe + +struct psmouse { + void *private; + struct input_dev dev; + struct serio *serio; + char *vendor; + char *name; + unsigned char cmdbuf[8]; + unsigned char packet[8]; + unsigned char cmdcnt; + unsigned char pktcnt; + unsigned char type; + unsigned char model; + unsigned long last; + char acking; + volatile char ack; + char error; + char devname[64]; + char phys[32]; +}; + +#define PSMOUSE_PS2 1 +#define PSMOUSE_PS2PP 2 +#define PSMOUSE_PS2TPP 3 +#define PSMOUSE_GENPS 4 +#define PSMOUSE_IMPS 5 +#define PSMOUSE_IMEX 6 +#define PSMOUSE_SYNAPTICS 7 + +int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command); + +#endif /* _PSMOUSE_H */ diff -Nru a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/input/mouse/synaptics.c Sat Jun 14 22:24:35 2003 @@ -0,0 +1,390 @@ +/* + * Synaptics TouchPad PS/2 mouse driver + * + * 2003 Peter Osterlund + * Ported to 2.5 input device infrastructure. + * + * Copyright (C) 2001 Stefan Gmeiner + * start merging tpconfig and gpm code to a xfree-input module + * adding some changes and extensions (ex. 3rd and 4th button) + * + * Copyright (c) 1997 C. Scott Ananian + * Copyright (c) 1998-2000 Bruce Kalk + * code for the special synaptics commands (from the tpconfig-source) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * Trademarks are the property of their respective owners. + */ + +#include +#include +#include "psmouse.h" +#include "synaptics.h" + +/***************************************************************************** + * Synaptics communications functions + ****************************************************************************/ + +/* + * Use the Synaptics extended ps/2 syntax to write a special command byte. + * special command: 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu + * is the command. A 0xF3 or 0xE9 must follow (see synaptics_send_cmd + * and synaptics_set_mode) + */ +static int synaptics_special_cmd(struct psmouse *psmouse, unsigned char command) +{ + int i; + + if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11)) + return -1; + + for (i = 6; i >= 0; i -= 2) { + unsigned char d = (command >> i) & 3; + if (psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES)) + return -1; + } + + return 0; +} + +/* + * Send a command to the synpatics touchpad by special commands + */ +static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param) +{ + if (synaptics_special_cmd(psmouse, c)) + return -1; + if (psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO)) + return -1; + return 0; +} + +/* + * Set the synaptics touchpad mode byte by special commands + */ +static int synaptics_set_mode(struct psmouse *psmouse, unsigned char mode) +{ + unsigned char param[1]; + + if (synaptics_special_cmd(psmouse, mode)) + return -1; + param[0] = 0x14; + if (psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE)) + return -1; + return 0; +} + +static int synaptics_reset(struct psmouse *psmouse) +{ + unsigned char r[2]; + + if (psmouse_command(psmouse, r, PSMOUSE_CMD_RESET_BAT)) + return -1; + if (r[0] == 0xAA && r[1] == 0x00) + return 0; + return -1; +} + +/* + * Read the model-id bytes from the touchpad + * see also SYN_MODEL_* macros + */ +static int synaptics_model_id(struct psmouse *psmouse, unsigned long int *model_id) +{ + unsigned char mi[3]; + + if (synaptics_send_cmd(psmouse, SYN_QUE_MODEL, mi)) + return -1; + *model_id = (mi[0]<<16) | (mi[1]<<8) | mi[2]; + return 0; +} + +/* + * Read the capability-bits from the touchpad + * see also the SYN_CAP_* macros + */ +static int synaptics_capability(struct psmouse *psmouse, unsigned long int *capability) +{ + unsigned char cap[3]; + + if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap)) + return -1; + *capability = (cap[0]<<16) | (cap[1]<<8) | cap[2]; + if (SYN_CAP_VALID(*capability)) + return 0; + return -1; +} + +/* + * Identify Touchpad + * See also the SYN_ID_* macros + */ +static int synaptics_identify(struct psmouse *psmouse, unsigned long int *ident) +{ + unsigned char id[3]; + + if (synaptics_send_cmd(psmouse, SYN_QUE_IDENTIFY, id)) + return -1; + *ident = (id[0]<<16) | (id[1]<<8) | id[2]; + if (SYN_ID_IS_SYNAPTICS(*ident)) + return 0; + return -1; +} + +static int synaptics_enable_device(struct psmouse *psmouse) +{ + if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_ENABLE)) + return -1; + return 0; +} + +static void print_ident(struct synaptics_data *priv) +{ + printk(KERN_INFO "Synaptics Touchpad, model: %ld\n", SYN_ID_MODEL(priv->identity)); + printk(KERN_INFO " Firware: %ld.%ld\n", SYN_ID_MAJOR(priv->identity), + SYN_ID_MINOR(priv->identity)); + + if (SYN_MODEL_ROT180(priv->model_id)) + printk(KERN_INFO " 180 degree mounted touchpad\n"); + if (SYN_MODEL_PORTRAIT(priv->model_id)) + printk(KERN_INFO " portrait touchpad\n"); + printk(KERN_INFO " Sensor: %ld\n", SYN_MODEL_SENSOR(priv->model_id)); + if (SYN_MODEL_NEWABS(priv->model_id)) + printk(KERN_INFO " new absolute packet format\n"); + if (SYN_MODEL_PEN(priv->model_id)) + printk(KERN_INFO " pen detection\n"); + + if (SYN_CAP_EXTENDED(priv->capabilities)) { + printk(KERN_INFO " Touchpad has extended capability bits\n"); + if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) + printk(KERN_INFO " -> four buttons\n"); + if (SYN_CAP_MULTIFINGER(priv->capabilities)) + printk(KERN_INFO " -> multifinger detection\n"); + if (SYN_CAP_PALMDETECT(priv->capabilities)) + printk(KERN_INFO " -> palm detection\n"); + } +} + +static int query_hardware(struct psmouse *psmouse) +{ + struct synaptics_data *priv = psmouse->private; + int retries = 3; + + while ((retries++ <= 3) && synaptics_reset(psmouse)) + printk(KERN_ERR "synaptics reset failed\n"); + + if (synaptics_identify(psmouse, &priv->identity)) + return -1; + if (synaptics_model_id(psmouse, &priv->model_id)) + return -1; + if (synaptics_capability(psmouse, &priv->capabilities)) + return -1; + if (synaptics_set_mode(psmouse, (SYN_BIT_ABSOLUTE_MODE | + SYN_BIT_HIGH_RATE | + SYN_BIT_DISABLE_GESTURE | + SYN_BIT_W_MODE))) + return -1; + + synaptics_enable_device(psmouse); + + print_ident(priv); + + return 0; +} + +/***************************************************************************** + * Driver initialization/cleanup functions + ****************************************************************************/ + +static inline void set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat) +{ + dev->absmin[axis] = min; + dev->absmax[axis] = max; + dev->absfuzz[axis] = fuzz; + dev->absflat[axis] = flat; + + set_bit(axis, dev->absbit); +} + +int synaptics_init(struct psmouse *psmouse) +{ + struct synaptics_data *priv; + + psmouse->private = priv = kmalloc(sizeof(struct synaptics_data), GFP_KERNEL); + if (!priv) + return -1; + memset(priv, 0, sizeof(struct synaptics_data)); + + priv->inSync = 1; + + if (query_hardware(psmouse)) { + printk(KERN_ERR "Unable to query/initialize Synaptics hardware.\n"); + goto init_fail; + } + + /* + * The x/y limits are taken from the Synaptics TouchPad interfacing Guide, + * which says that they should be valid regardless of the actual size of + * the senser. + */ + set_bit(EV_ABS, psmouse->dev.evbit); + set_abs_params(&psmouse->dev, ABS_X, 1472, 5472, 0, 0); + set_abs_params(&psmouse->dev, ABS_Y, 1408, 4448, 0, 0); + set_abs_params(&psmouse->dev, ABS_PRESSURE, 0, 255, 0, 0); + + set_bit(EV_MSC, psmouse->dev.evbit); + set_bit(MSC_GESTURE, psmouse->dev.mscbit); + + set_bit(EV_KEY, psmouse->dev.evbit); + set_bit(BTN_LEFT, psmouse->dev.keybit); + set_bit(BTN_RIGHT, psmouse->dev.keybit); + set_bit(BTN_FORWARD, psmouse->dev.keybit); + set_bit(BTN_BACK, psmouse->dev.keybit); + + clear_bit(EV_REL, psmouse->dev.evbit); + clear_bit(REL_X, psmouse->dev.relbit); + clear_bit(REL_Y, psmouse->dev.relbit); + + return 0; + + init_fail: + kfree(priv); + return -1; +} + +void synaptics_disconnect(struct psmouse *psmouse) +{ + struct synaptics_data *priv = psmouse->private; + + kfree(priv); +} + +/***************************************************************************** + * Functions to interpret the absolute mode packets + ****************************************************************************/ + +static void synaptics_parse_hw_state(struct synaptics_data *priv, + struct synaptics_hw_state *hw) +{ + unsigned char *buf = priv->proto_buf; + + hw->x = (((buf[3] & 0x10) << 8) | + ((buf[1] & 0x0f) << 8) | + buf[4]); + hw->y = (((buf[3] & 0x20) << 7) | + ((buf[1] & 0xf0) << 4) | + buf[5]); + + hw->z = buf[2]; + hw->w = (((buf[0] & 0x30) >> 2) | + ((buf[0] & 0x04) >> 1) | + ((buf[3] & 0x04) >> 2)); + + hw->left = (buf[0] & 0x01) ? 1 : 0; + hw->right = (buf[0] & 0x2) ? 1 : 0; + hw->up = 0; + hw->down = 0; + + if (SYN_CAP_EXTENDED(priv->capabilities) && + (SYN_CAP_FOUR_BUTTON(priv->capabilities))) { + hw->up = ((buf[3] & 0x01)) ? 1 : 0; + if (hw->left) + hw->up = !hw->up; + hw->down = ((buf[3] & 0x02)) ? 1 : 0; + if (hw->right) + hw->down = !hw->down; + } +} + +/* + * called for each full received packet from the touchpad + */ +static void synaptics_process_packet(struct psmouse *psmouse) +{ + struct input_dev *dev = &psmouse->dev; + struct synaptics_data *priv = psmouse->private; + struct synaptics_hw_state hw; + + synaptics_parse_hw_state(priv, &hw); + + if (hw.z > 0) { + int w_ok = 0; + /* + * Use capability bits to decide if the w value is valid. + * If not, set it to 5, which corresponds to a finger of + * normal width. + */ + if (SYN_CAP_EXTENDED(priv->capabilities)) { + switch (hw.w) { + case 0 ... 1: + w_ok = SYN_CAP_MULTIFINGER(priv->capabilities); + break; + case 2: + w_ok = SYN_MODEL_PEN(priv->model_id); + break; + case 4 ... 15: + w_ok = SYN_CAP_PALMDETECT(priv->capabilities); + break; + } + } + if (!w_ok) + hw.w = 5; + } + + /* Post events */ + input_report_abs(dev, ABS_X, hw.x); + input_report_abs(dev, ABS_Y, hw.y); + input_report_abs(dev, ABS_PRESSURE, hw.z); + + if (hw.w != priv->old_w) { + input_event(dev, EV_MSC, MSC_GESTURE, hw.w); + priv->old_w = hw.w; + } + + input_report_key(dev, BTN_LEFT, hw.left); + input_report_key(dev, BTN_RIGHT, hw.right); + input_report_key(dev, BTN_FORWARD, hw.up); + input_report_key(dev, BTN_BACK, hw.down); + + input_sync(dev); +} + +void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs) +{ + struct input_dev *dev = &psmouse->dev; + struct synaptics_data *priv = psmouse->private; + unsigned char *pBuf = priv->proto_buf; + unsigned char u = psmouse->packet[0]; + + input_regs(dev, regs); + + pBuf[priv->proto_buf_tail++] = u; + + /* check first byte */ + if ((priv->proto_buf_tail == 1) && ((u & 0xC8) != 0x80)) { + priv->inSync = 0; + priv->proto_buf_tail = 0; + printk(KERN_WARNING "Synaptics driver lost sync at 1st byte\n"); + return; + } + + /* check 4th byte */ + if ((priv->proto_buf_tail == 4) && ((u & 0xc8) != 0xc0)) { + priv->inSync = 0; + priv->proto_buf_tail = 0; + printk(KERN_WARNING "Synaptics driver lost sync at 4th byte\n"); + return; + } + + if (priv->proto_buf_tail >= 6) { /* Full packet received */ + if (!priv->inSync) { + priv->inSync = 1; + printk(KERN_NOTICE "Synaptics driver resynced.\n"); + } + synaptics_process_packet(psmouse); + priv->proto_buf_tail = 0; + } +} diff -Nru a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/input/mouse/synaptics.h Sat Jun 14 22:24:35 2003 @@ -0,0 +1,105 @@ +/* + * Synaptics TouchPad PS/2 mouse driver + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#ifndef _SYNAPTICS_H +#define _SYNAPTICS_H + +#ifdef CONFIG_MOUSE_PS2_SYNAPTICS + +extern void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs); +extern int synaptics_init(struct psmouse *psmouse); +extern void synaptics_disconnect(struct psmouse *psmouse); + +#else + +static inline void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs) {} +static inline int synaptics_init(struct psmouse *psmouse) { return -1; } +static inline void synaptics_disconnect(struct psmouse *psmouse) {} + +#endif + + +/* synaptics queries */ +#define SYN_QUE_IDENTIFY 0x00 +#define SYN_QUE_MODES 0x01 +#define SYN_QUE_CAPABILITIES 0x02 +#define SYN_QUE_MODEL 0x03 +#define SYN_QUE_SERIAL_NUMBER_PREFIX 0x06 +#define SYN_QUE_SERIAL_NUMBER_SUFFIX 0x07 +#define SYN_QUE_RESOLUTION 0x08 + +/* synatics modes */ +#define SYN_BIT_ABSOLUTE_MODE (1 << 7) +#define SYN_BIT_HIGH_RATE (1 << 6) +#define SYN_BIT_SLEEP_MODE (1 << 3) +#define SYN_BIT_DISABLE_GESTURE (1 << 2) +#define SYN_BIT_W_MODE (1 << 0) + +/* synaptics model ID bits */ +#define SYN_MODEL_ROT180(m) ((m) & (1 << 23)) +#define SYN_MODEL_PORTRAIT(m) ((m) & (1 << 22)) +#define SYN_MODEL_SENSOR(m) (((m) >> 16) & 0x3f) +#define SYN_MODEL_HARDWARE(m) (((m) >> 9) & 0x7f) +#define SYN_MODEL_NEWABS(m) ((m) & (1 << 7)) +#define SYN_MODEL_PEN(m) ((m) & (1 << 6)) +#define SYN_MODEL_SIMPLIC(m) ((m) & (1 << 5)) +#define SYN_MODEL_GEOMETRY(m) ((m) & 0x0f) + +/* synaptics capability bits */ +#define SYN_CAP_EXTENDED(c) ((c) & (1 << 23)) +#define SYN_CAP_SLEEP(c) ((c) & (1 << 4)) +#define SYN_CAP_FOUR_BUTTON(c) ((c) & (1 << 3)) +#define SYN_CAP_MULTIFINGER(c) ((c) & (1 << 1)) +#define SYN_CAP_PALMDETECT(c) ((c) & (1 << 0)) +#define SYN_CAP_VALID(c) ((((c) & 0x00ff00) >> 8) == 0x47) + +/* synaptics modes query bits */ +#define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) +#define SYN_MODE_RATE(m) ((m) & (1 << 6)) +#define SYN_MODE_BAUD_SLEEP(m) ((m) & (1 << 3)) +#define SYN_MODE_DISABLE_GESTURE(m) ((m) & (1 << 2)) +#define SYN_MODE_PACKSIZE(m) ((m) & (1 << 1)) +#define SYN_MODE_WMODE(m) ((m) & (1 << 0)) + +/* synaptics identify query bits */ +#define SYN_ID_MODEL(i) (((i) >> 4) & 0x0f) +#define SYN_ID_MAJOR(i) ((i) & 0x0f) +#define SYN_ID_MINOR(i) (((i) >> 16) & 0xff) +#define SYN_ID_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47) + +/* + * A structure to describe the state of the touchpad hardware (buttons and pad) + */ + +struct synaptics_hw_state { + int x; + int y; + int z; + int w; + int left; + int right; + int up; + int down; +}; + +struct synaptics_data { + /* Data read from the touchpad */ + unsigned long int model_id; /* Model-ID */ + unsigned long int capabilities; /* Capabilities */ + unsigned long int identity; /* Identification */ + + /* Data for normal processing */ + unsigned char proto_buf[6]; /* Buffer for Packet */ + unsigned char last_byte; /* last received byte */ + int inSync; /* Packets in sync */ + int proto_buf_tail; + + int old_w; /* Previous w value */ +}; + +#endif /* _SYNAPTICS_H */ diff -Nru a/include/linux/input.h b/include/linux/input.h --- a/include/linux/input.h Sat Jun 14 22:24:35 2003 +++ b/include/linux/input.h Sat Jun 14 22:24:35 2003 @@ -530,6 +530,7 @@ #define MSC_SERIAL 0x00 #define MSC_PULSELED 0x01 +#define MSC_GESTURE 0x02 #define MSC_MAX 0x07 /* - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/