]> git.pld-linux.org Git - packages/kernel.git/blame - 2.6.6-ALPS-touchpad-driver.patch
- added description of djurban's branch
[packages/kernel.git] / 2.6.6-ALPS-touchpad-driver.patch
CommitLineData
8422b624 1 ChangeSet@1.1907, 2004-04-23 02:22:22-05:00, dtor_core@ameritech.net
2 ALPS driver
3
4 Makefile | 2
5 alps.c | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 alps.h | 17 +++++
7 psmouse-base.c | 19 +++++
8 psmouse.h | 3
9 5 files changed, 224 insertions(+), 2 deletions(-)
10
11diff -Nru a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
12--- a/drivers/input/mouse/Makefile Fri Apr 23 02:24:19 2004
13+++ b/drivers/input/mouse/Makefile Fri Apr 23 02:24:19 2004
14@@ -15,4 +15,4 @@
15 obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o
16 obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o
17
18-psmouse-objs := psmouse-base.o logips2pp.o synaptics.o
19+psmouse-objs := psmouse-base.o alps.o logips2pp.o synaptics.o
20diff -Nru a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
21--- /dev/null Wed Dec 31 16:00:00 1969
22+++ b/drivers/input/mouse/alps.c Fri Apr 23 02:24:19 2004
23@@ -0,0 +1,185 @@
24+/*
25+ * ALPS touchpad PS/2 mouse driver
26+ *
27+ * Copyright (c) 2003 Neil Brown <neilb@cse.unsw.edu.au>
28+ * Copyright (c) 2003 Peter Osterlund <petero2@telia.com>
29+ * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru>
30+ *
31+ * This program is free software; you can redistribute it and/or modify it
32+ * under the terms of the GNU General Public License version 2 as published by
33+ * the Free Software Foundation.
34+ */
35+
36+#include <linux/input.h>
37+#include <linux/serio.h>
38+
39+#include "psmouse.h"
40+#include "alps.h"
41+
42+/*
43+ * ALPS abolute Mode
44+ * byte 0: 1 1 1 1 1 mid0 rig0 lef0
45+ * byte 1: 0 x6 x5 x4 x3 x2 x1 x0
46+ * byte 2: 0 x10 x9 x8 x7 up1 fin ges
47+ * byte 3: 0 y9 y8 y7 1 mid1 rig1 lef1
48+ * byte 4: 0 y6 y5 y4 y3 y2 y1 y0
49+ * byte 5: 0 z6 z5 z4 z3 z2 z1 z0
50+ *
51+ * On a dualpoint, {mid,rig,lef}0 are the stick, 1 are the pad.
52+ * We just 'or' them together for now.
53+ *
54+ * We used to send 'ges'tures as BTN_TOUCH but this made it impossible
55+ * to disable tap events in the synaptics driver since the driver
56+ * was unable to distinguish a gesture tap from an actual button click.
57+ * A tap gesture now creates an emulated touch that the synaptics
58+ * driver can interpret as a tap event, if MaxTapTime=0 and
59+ * MaxTapMove=0 then the driver will ignore taps.
60+ *
61+ * The touchpad on an 'Acer Aspire' has 4 buttons:
62+ * left,right,up,down.
63+ * This device always sets {mid,rig,lef}0 to 1 and
64+ * reflects left,right,down,up in lef1,rig1,mid1,up1.
65+ */
66+
67+static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
68+{
69+ unsigned char *packet = psmouse->packet;
70+ struct input_dev *dev = &psmouse->dev;
71+ int x, y, z;
72+ int left = 0, right = 0, middle = 0;
73+
74+ input_regs(dev, regs);
75+
76+ x = (packet[1] & 0x7f) | ((packet[2] & 0x78)<<(7-3));
77+ y = (packet[4] & 0x7f) | ((packet[3] & 0x70)<<(7-4));
78+ z = packet[5];
79+
80+ if (z > 30) input_report_key(dev, BTN_TOUCH, 1);
81+ if (z < 25) input_report_key(dev, BTN_TOUCH, 0);
82+
83+ if (z > 0) {
84+ input_report_abs(dev, ABS_X, x);
85+ input_report_abs(dev, ABS_Y, y);
86+ }
87+ input_report_abs(dev, ABS_PRESSURE, z);
88+ input_report_key(dev, BTN_TOOL_FINGER, z > 0);
89+
90+ left |= (packet[2] ) & 1;
91+ left |= (packet[3] ) & 1;
92+ right |= (packet[3] >> 1) & 1;
93+ if (packet[0] == 0xff) {
94+ int back = (packet[3] >> 2) & 1;
95+ int forward = (packet[2] >> 2) & 1;
96+ if (back && forward) {
97+ middle = 1;
98+ back = 0;
99+ forward = 0;
100+ }
101+ input_report_key(dev, BTN_BACK, back);
102+ input_report_key(dev, BTN_FORWARD, forward);
103+ } else {
104+ left |= (packet[0] ) & 1;
105+ right |= (packet[0] >> 1) & 1;
106+ middle |= (packet[0] >> 2) & 1;
107+ middle |= (packet[3] >> 2) & 1;
108+ }
109+
110+ input_report_key(dev, BTN_LEFT, left);
111+ input_report_key(dev, BTN_RIGHT, right);
112+ input_report_key(dev, BTN_MIDDLE, middle);
113+
114+ input_sync(dev);
115+}
116+
117+static psmouse_ret_t alps_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
118+{
119+ /* ALPS absolute mode packets start with 0b11111mrl */
120+ if ((psmouse->packet[0] & 0xf8) != 0xf8)
121+ return PSMOUSE_BAD_DATA;
122+
123+ /* Bytes 2 - 6 should have 0 in the highest bit */
124+ if (psmouse->pktcnt > 1 && psmouse->pktcnt <= 6 &&
125+ (psmouse->packet[psmouse->pktcnt] & 0x80))
126+ return PSMOUSE_BAD_DATA;
127+
128+ if (psmouse->pktcnt == 6) {
129+ alps_process_packet(psmouse, regs);
130+ return PSMOUSE_FULL_PACKET;
131+ }
132+
133+ return PSMOUSE_GOOD_DATA;
134+}
135+
136+int alps_detect(struct psmouse *psmouse)
137+{
138+ unsigned char param[4];
139+
140+ /* First try "E6 report". ALPS should return 0x00 0x00 0x0a */
141+ param[0] = 0;
142+ if (psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES) ||
143+ psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11) ||
144+ psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11) ||
145+ psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11))
146+ return 0;
147+
148+ param[0] = param[1] = param[2] = 0xff;
149+ if (psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO))
150+ return 0;
151+
152+ printk(KERN_INFO "alps.c: E6 report: %2.2x %2.2x %2.2x\n",
153+ param[0], param[1], param[2]);
154+
155+ if (param[0] != 0x00 || param[1] != 0x00 || param[2] != 0x0a)
156+ return 0;
157+
158+ /* Now try "E7 report". ALPS should return 0x33 in byte 1 */
159+ param[0] = 0;
160+ if (psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES) ||
161+ psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE21) ||
162+ psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE21) ||
163+ psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE21))
164+ return 0;
165+
166+ param[0] = param[1] = param[2] = 0xff;
167+ if (psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO))
168+ return 0;
169+
170+ printk(KERN_INFO "alps.c: E7 report: %2.2x %2.2x %2.2x\n",
171+ param[0], param[1], param[2]);
172+
173+ return param[0] != 0x33;
174+}
175+
176+static void alps_disconnect(struct psmouse *psmouse)
177+{
178+ psmouse_reset(psmouse);
179+}
180+
181+int alps_init(struct psmouse *psmouse)
182+{
183+ /* Try ALPS magic knock */
184+ if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_DISABLE) ||
185+ psmouse_command(psmouse, NULL, PSMOUSE_CMD_DISABLE) ||
186+ psmouse_command(psmouse, NULL, PSMOUSE_CMD_DISABLE) ||
187+ psmouse_command(psmouse, NULL, PSMOUSE_CMD_DISABLE))
188+ return -1;
189+
190+ psmouse->dev.evbit[LONG(EV_REL)] &= ~BIT(EV_REL);
191+ psmouse->dev.relbit[LONG(REL_X)] &= ~BIT(REL_X);
192+ psmouse->dev.relbit[LONG(REL_X)] &= ~BIT(REL_X);
193+
194+ psmouse->dev.evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
195+ input_set_abs_params(&psmouse->dev, ABS_X, 0, 0, 0, 0);
196+ input_set_abs_params(&psmouse->dev, ABS_Y, 0, 0, 0, 0);
197+ input_set_abs_params(&psmouse->dev, ABS_PRESSURE, 0, 127, 0, 0);
198+
199+ psmouse->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
200+ psmouse->dev.keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER);
201+ psmouse->dev.keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD);
202+ psmouse->dev.keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK);
203+
204+ psmouse->protocol_handler = alps_process_byte;
205+ psmouse->disconnect = alps_disconnect;
206+
207+ return 0;
208+}
209diff -Nru a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
210--- /dev/null Wed Dec 31 16:00:00 1969
211+++ b/drivers/input/mouse/alps.h Fri Apr 23 02:24:19 2004
212@@ -0,0 +1,17 @@
213+/*
214+ * ALPS touchpad PS/2 mouse driver
215+ *
216+ * Copyright (c) 2003 Peter Osterlund <petero2@telia.com>
217+ *
218+ * This program is free software; you can redistribute it and/or modify it
219+ * under the terms of the GNU General Public License version 2 as published by
220+ * the Free Software Foundation.
221+ */
222+
223+#ifndef _ALPS_H
224+#define _ALPS_H
225+
226+int alps_detect(struct psmouse *psmouse);
227+int alps_init(struct psmouse *psmouse);
228+
229+#endif
230diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
231--- a/drivers/input/mouse/psmouse-base.c Fri Apr 23 02:24:19 2004
232+++ b/drivers/input/mouse/psmouse-base.c Fri Apr 23 02:24:19 2004
233@@ -2,6 +2,7 @@
234 * PS/2 mouse driver
235 *
236 * Copyright (c) 1999-2002 Vojtech Pavlik
237+ * Copyright (c) 2003-2004 Dmitry Torokhov
238 */
239
240 /*
241@@ -21,6 +22,7 @@
242 #include "psmouse.h"
243 #include "synaptics.h"
244 #include "logips2pp.h"
245+#include "alps.h"
246
247 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
248 MODULE_DESCRIPTION("PS/2 mouse driver");
249@@ -53,7 +55,7 @@
250 __obsolete_setup("psmouse_resetafter=");
251 __obsolete_setup("psmouse_rate=");
252
253-static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2"};
254+static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2", "AlpsPS/2" };
255
256 /*
257 * psmouse_process_byte() analyzes the PS/2 data stream and reports
258@@ -440,6 +442,21 @@
259 * Make sure that touchpad is in relative mode, gestures (taps) are enabled
260 */
261 synaptics_reset(psmouse);
262+ }
263+
264+/*
265+ * Try ALPS TouchPad
266+ */
267+ if (max_proto > PSMOUSE_PS2 && alps_detect(psmouse)) {
268+
269+ if (set_properties) {
270+ psmouse->vendor = "ALPS";
271+ psmouse->name = "TouchPad";
272+ }
273+
274+ if (max_proto > PSMOUSE_IMEX)
275+ if (alps_detect(psmouse) == 0)
276+ return PSMOUSE_ALPS;
277 }
278
279 if (max_proto > PSMOUSE_IMEX && genius_detect(psmouse)) {
280diff -Nru a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
281--- a/drivers/input/mouse/psmouse.h Fri Apr 23 02:24:19 2004
282+++ b/drivers/input/mouse/psmouse.h Fri Apr 23 02:24:19 2004
283@@ -2,6 +2,7 @@
284 #define _PSMOUSE_H
285
286 #define PSMOUSE_CMD_SETSCALE11 0x00e6
287+#define PSMOUSE_CMD_SETSCALE21 0x00e7
288 #define PSMOUSE_CMD_SETRES 0x10e8
289 #define PSMOUSE_CMD_GETINFO 0x03e9
290 #define PSMOUSE_CMD_SETSTREAM 0x00ea
291@@ -9,6 +10,7 @@
292 #define PSMOUSE_CMD_GETID 0x02f2
293 #define PSMOUSE_CMD_SETRATE 0x10f3
294 #define PSMOUSE_CMD_ENABLE 0x00f4
295+#define PSMOUSE_CMD_DISABLE 0x00f5
296 #define PSMOUSE_CMD_RESET_DIS 0x00f6
297 #define PSMOUSE_CMD_RESET_BAT 0x02ff
298
299@@ -72,6 +74,7 @@
300 #define PSMOUSE_IMPS 5
301 #define PSMOUSE_IMEX 6
302 #define PSMOUSE_SYNAPTICS 7
303+#define PSMOUSE_ALPS 8
304
305 int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command);
306 int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);
307-
308To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
309the body of a message to majordomo@vger.kernel.org
310More majordomo info at http://vger.kernel.org/majordomo-info.html
311Please read the FAQ at http://www.tux.org/lkml/
312
This page took 0.589976 seconds and 4 git commands to generate.