]> git.pld-linux.org Git - packages/kernel.git/blob - 2.6.6-ALPS-touchpad-driver.patch
- added description of djurban's branch
[packages/kernel.git] / 2.6.6-ALPS-touchpad-driver.patch
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
11 diff -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
20 diff -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 +}
209 diff -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
230 diff -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)) {
280 diff -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 -
308 To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
309 the body of a message to majordomo@vger.kernel.org
310 More majordomo info at  http://vger.kernel.org/majordomo-info.html
311 Please read the FAQ at  http://www.tux.org/lkml/
312
This page took 0.896471 seconds and 3 git commands to generate.