Gentoo Archives: gentoo-commits

From: "Mike Pagano (mpagano)" <mpagano@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] linux-patches r1982 - genpatches-2.6/trunk/3.0
Date: Wed, 28 Sep 2011 14:30:41
Message-Id: 20110928143020.0C49C20036@flycatcher.gentoo.org
1 Author: mpagano
2 Date: 2011-09-28 14:30:19 +0000 (Wed, 28 Sep 2011)
3 New Revision: 1982
4
5 Added:
6 genpatches-2.6/trunk/3.0/2600_Input-ALPS-Move-protocol-information-to-Documentation.patch
7 genpatches-2.6/trunk/3.0/2605_Input-psmouse-Add-PSMOUSE_CMD_RESET_WRAP.patch
8 genpatches-2.6/trunk/3.0/2610_Input-ALPS-Add-protocol-version-field-in-alps_model.patch
9 genpatches-2.6/trunk/3.0/2615_Input-ALPS-Remove-assumptions-about-packet-size.patch
10 genpatches-2.6/trunk/3.0/2620_Input-ALPS-Add-support-for-protocol-versions-3-and-4.patch
11 genpatches-2.6/trunk/3.0/2625_Input-ALPS-Add-documentation-for-protocol-versions-3.patch
12 genpatches-2.6/trunk/3.0/2630_Input-ALPS-Add-semi-MT-support-for-v3-protocol.patch
13 genpatches-2.6/trunk/3.0/2635_Input-ALPS-dump-raw-packet-data.patch
14 Modified:
15 genpatches-2.6/trunk/3.0/0000_README
16 Log:
17 Adding ALPS patches for new touchpads from Seth Forshee at Ubuntu
18
19 Modified: genpatches-2.6/trunk/3.0/0000_README
20 ===================================================================
21 --- genpatches-2.6/trunk/3.0/0000_README 2011-09-22 21:09:14 UTC (rev 1981)
22 +++ genpatches-2.6/trunk/3.0/0000_README 2011-09-28 14:30:19 UTC (rev 1982)
23 @@ -67,6 +67,38 @@
24 From: http://bugs.gentoo.org/show_bug.cgi?id=381963
25 Desc: Fix vmscan count in small memcgs
26
27 +Patch: 2600_Input-ALPS-Move-protocol-information-to-Documentation.patch
28 +From: http://bugs.gentoo.org/show_bug.cgi?id=318567
29 +Desc: ALPS Touchpad - Move protocol information to Documentation
30 +
31 +Patch: 2605_Input-psmouse-Add-PSMOUSE_CMD_RESET_WRAP.patch
32 +From: http://bugs.gentoo.org/show_bug.cgi?id=318567
33 +Desc: ALPS Touchpad - Add PSMOUSE_CMD_RESET_WRAP
34 +
35 +Patch: 2610_Input-ALPS-Add-protocol-version-field-in-alps_model.patch
36 +From: http://bugs.gentoo.org/show_bug.cgi?id=318567
37 +Desc: ALPS Touchpad - Add protocol version field in alps_model_info
38 +
39 +Patch: 2615_Input-ALPS-Remove-assumptions-about-packet-size.patch
40 +From: http://bugs.gentoo.org/show_bug.cgi?id=318567
41 +Desc: ALPS Touchpad - Remove assumptions about packet size
42 +
43 +Patch: 2620_Input-ALPS-Add-support-for-protocol-versions-3-and-4.patch
44 +From: http://bugs.gentoo.org/show_bug.cgi?id=318567
45 +Desc: ALPS Touchpad - Add support for protocol versions 3 and 4
46 +
47 +Patch: 2625_Input-ALPS-Add-documentation-for-protocol-versions-3.patch
48 +From: http://bugs.gentoo.org/show_bug.cgi?id=318567
49 +Desc: ALPS Touchpad - Add documentation for protocol versions 3 and 4
50 +
51 +Patch: 2630_Input-ALPS-Add-semi-MT-support-for-v3-protocol.patch
52 +From: http://bugs.gentoo.org/show_bug.cgi?id=318567
53 +Desc: ALPS Touchpad - Add semi-MT support for v3 protocol
54 +
55 +Patch: 2635_Input-ALPS-dump-raw-packet-data.patch
56 +From: http://bugs.gentoo.org/show_bug.cgi?id=318567
57 +Desc: ALPS Touchpad - dump raw packet data
58 +
59 Patch: 2900_change-dvb-firmware-url.patch
60 From: http://bugs.gentoo.org/show_bug.cgi?id=383819
61 Desc: Change firmware download url, thanks to Markos Chandras
62
63 Added: genpatches-2.6/trunk/3.0/2600_Input-ALPS-Move-protocol-information-to-Documentation.patch
64 ===================================================================
65 --- genpatches-2.6/trunk/3.0/2600_Input-ALPS-Move-protocol-information-to-Documentation.patch (rev 0)
66 +++ genpatches-2.6/trunk/3.0/2600_Input-ALPS-Move-protocol-information-to-Documentation.patch 2011-09-28 14:30:19 UTC (rev 1982)
67 @@ -0,0 +1,147 @@
68 +From ffe7d2822d760868afc78e9c8239a77e913ed564 Mon Sep 17 00:00:00 2001
69 +From: Seth Forshee <seth.forshee@×××××××××.com>
70 +Date: Wed, 14 Sep 2011 11:40:37 -0500
71 +Subject: [PATCH 1/8] Input: ALPS - Move protocol information to Documentation
72 +
73 +In preparation for new protocol support, move the protocol
74 +information currently documented in alps.c to
75 +Documentation/input/alps.txt, where it can be expanded without
76 +cluttering up the driver.
77 +---
78 + Documentation/input/alps.txt | 75 ++++++++++++++++++++++++++++++++++++++++++
79 + drivers/input/mouse/alps.c | 37 +--------------------
80 + 2 files changed, 76 insertions(+), 36 deletions(-)
81 + create mode 100644 Documentation/input/alps.txt
82 +
83 +diff --git a/Documentation/input/alps.txt b/Documentation/input/alps.txt
84 +new file mode 100644
85 +index 0000000..e88c921
86 +--- /dev/null
87 ++++ b/Documentation/input/alps.txt
88 +@@ -0,0 +1,75 @@
89 ++ALPS Touchpad Protocol
90 ++----------------------
91 ++
92 ++Introduction
93 ++------------
94 ++
95 ++Currently the ALPS touchpad driver supports two protocol versions in use by
96 ++ALPS touchpads, the "old" and "new" protocol versions. Fundamentally these
97 ++differ only in the format of their event packets (in reality many features may
98 ++be found on new protocol devices that aren't found on the old protocol
99 ++devices, but these are handled transparently as feature differences rather
100 ++than protocol differences).
101 ++
102 ++Detection
103 ++---------
104 ++
105 ++All ALPS touchpads should respond to the "E6 report" command sequence:
106 ++E8-E6-E6-E6-E9. An ALPS touchpad should respond with either 00-00-0A or
107 ++00-00-64.
108 ++
109 ++If the E6 report is successful, the touchpad model is identified using the "E7
110 ++report" sequence: E8-E7-E7-E7-E9. The response is the model signature and is
111 ++matched against known models in the alps_model_data_array.
112 ++
113 ++Packet Format
114 ++-------------
115 ++
116 ++In the following tables, the following notation us used.
117 ++
118 ++ CAPITALS = stick, miniscules = touchpad
119 ++
120 ++?'s can have different meanings on different models, such as wheel rotation,
121 ++extra buttons, stick buttons on a dualpoint, etc.
122 ++
123 ++PS/2 packet format
124 ++------------------
125 ++
126 ++ byte 0: 0 0 YSGN XSGN 1 M R L
127 ++ byte 1: X7 X6 X5 X4 X3 X2 X1 X0
128 ++ byte 2: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
129 ++
130 ++Note that the device never signals overflow condition.
131 ++
132 ++ALPS Absolute Mode - Old Format
133 ++-------------------------------
134 ++
135 ++ byte 0: 1 0 0 0 1 x9 x8 x7
136 ++ byte 1: 0 x6 x5 x4 x3 x2 x1 x0
137 ++ byte 2: 0 ? ? l r ? fin ges
138 ++ byte 3: 0 ? ? ? ? y9 y8 y7
139 ++ byte 4: 0 y6 y5 y4 y3 y2 y1 y0
140 ++ byte 5: 0 z6 z5 z4 z3 z2 z1 z0
141 ++
142 ++ALPS Absolute Mode - New Format
143 ++-------------------------------
144 ++
145 ++ byte 0: 1 ? ? ? 1 ? ? ?
146 ++ byte 1: 0 x6 x5 x4 x3 x2 x1 x0
147 ++ byte 2: 0 x10 x9 x8 x7 ? fin ges
148 ++ byte 3: 0 y9 y8 y7 1 M R L
149 ++ byte 4: 0 y6 y5 y4 y3 y2 y1 y0
150 ++ byte 5: 0 z6 z5 z4 z3 z2 z1 z0
151 ++
152 ++Dualpoint device -- interleaved packet format
153 ++---------------------------------------------
154 ++
155 ++ byte 0: 1 1 0 0 1 1 1 1
156 ++ byte 1: 0 x6 x5 x4 x3 x2 x1 x0
157 ++ byte 2: 0 x10 x9 x8 x7 0 fin ges
158 ++ byte 3: 0 0 YSGN XSGN 1 1 1 1
159 ++ byte 4: X7 X6 X5 X4 X3 X2 X1 X0
160 ++ byte 5: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
161 ++ byte 6: 0 y9 y8 y7 1 m r l
162 ++ byte 7: 0 y6 y5 y4 y3 y2 y1 y0
163 ++ byte 8: 0 z6 z5 z4 z3 z2 z1 z0
164 +diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
165 +index 99d5876..ad15e7c 100644
166 +--- a/drivers/input/mouse/alps.c
167 ++++ b/drivers/input/mouse/alps.c
168 +@@ -74,42 +74,7 @@ static const struct alps_model_info alps_model_data[] = {
169 + * isn't valid per PS/2 spec.
170 + */
171 +
172 +-/*
173 +- * PS/2 packet format
174 +- *
175 +- * byte 0: 0 0 YSGN XSGN 1 M R L
176 +- * byte 1: X7 X6 X5 X4 X3 X2 X1 X0
177 +- * byte 2: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
178 +- *
179 +- * Note that the device never signals overflow condition.
180 +- *
181 +- * ALPS absolute Mode - new format
182 +- *
183 +- * byte 0: 1 ? ? ? 1 ? ? ?
184 +- * byte 1: 0 x6 x5 x4 x3 x2 x1 x0
185 +- * byte 2: 0 x10 x9 x8 x7 ? fin ges
186 +- * byte 3: 0 y9 y8 y7 1 M R L
187 +- * byte 4: 0 y6 y5 y4 y3 y2 y1 y0
188 +- * byte 5: 0 z6 z5 z4 z3 z2 z1 z0
189 +- *
190 +- * Dualpoint device -- interleaved packet format
191 +- *
192 +- * byte 0: 1 1 0 0 1 1 1 1
193 +- * byte 1: 0 x6 x5 x4 x3 x2 x1 x0
194 +- * byte 2: 0 x10 x9 x8 x7 0 fin ges
195 +- * byte 3: 0 0 YSGN XSGN 1 1 1 1
196 +- * byte 4: X7 X6 X5 X4 X3 X2 X1 X0
197 +- * byte 5: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
198 +- * byte 6: 0 y9 y8 y7 1 m r l
199 +- * byte 7: 0 y6 y5 y4 y3 y2 y1 y0
200 +- * byte 8: 0 z6 z5 z4 z3 z2 z1 z0
201 +- *
202 +- * CAPITALS = stick, miniscules = touchpad
203 +- *
204 +- * ?'s can have different meanings on different models,
205 +- * such as wheel rotation, extra buttons, stick buttons
206 +- * on a dualpoint, etc.
207 +- */
208 ++/* Packet formats are described in Documentation/input/alps.txt */
209 +
210 + static bool alps_is_valid_first_byte(const struct alps_model_info *model,
211 + unsigned char data)
212 +--
213 +1.7.4.1
214 +
215
216 Added: genpatches-2.6/trunk/3.0/2605_Input-psmouse-Add-PSMOUSE_CMD_RESET_WRAP.patch
217 ===================================================================
218 --- genpatches-2.6/trunk/3.0/2605_Input-psmouse-Add-PSMOUSE_CMD_RESET_WRAP.patch (rev 0)
219 +++ genpatches-2.6/trunk/3.0/2605_Input-psmouse-Add-PSMOUSE_CMD_RESET_WRAP.patch 2011-09-28 14:30:19 UTC (rev 1982)
220 @@ -0,0 +1,25 @@
221 +From e96c3fffedbaf13c6dfbdccead95fe49f8dce4a4 Mon Sep 17 00:00:00 2001
222 +From: Seth Forshee <seth.forshee@×××××××××.com>
223 +Date: Wed, 14 Sep 2011 11:40:38 -0500
224 +Subject: [PATCH 2/8] Input: psmouse - Add PSMOUSE_CMD_RESET_WRAP
225 +
226 +Add this command in preparation for new ALPS protocol support.
227 +---
228 + drivers/input/mouse/psmouse.h | 1 +
229 + 1 files changed, 1 insertions(+), 0 deletions(-)
230 +
231 +diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
232 +index 593e910..c2b5aa6 100644
233 +--- a/drivers/input/mouse/psmouse.h
234 ++++ b/drivers/input/mouse/psmouse.h
235 +@@ -8,6 +8,7 @@
236 + #define PSMOUSE_CMD_SETSTREAM 0x00ea
237 + #define PSMOUSE_CMD_SETPOLL 0x00f0
238 + #define PSMOUSE_CMD_POLL 0x00eb /* caller sets number of bytes to receive */
239 ++#define PSMOUSE_CMD_RESET_WRAP 0x00ec
240 + #define PSMOUSE_CMD_GETID 0x02f2
241 + #define PSMOUSE_CMD_SETRATE 0x10f3
242 + #define PSMOUSE_CMD_ENABLE 0x00f4
243 +--
244 +1.7.4.1
245 +
246
247 Added: genpatches-2.6/trunk/3.0/2610_Input-ALPS-Add-protocol-version-field-in-alps_model.patch
248 ===================================================================
249 --- genpatches-2.6/trunk/3.0/2610_Input-ALPS-Add-protocol-version-field-in-alps_model.patch (rev 0)
250 +++ genpatches-2.6/trunk/3.0/2610_Input-ALPS-Add-protocol-version-field-in-alps_model.patch 2011-09-28 14:30:19 UTC (rev 1982)
251 @@ -0,0 +1,107 @@
252 +From bd161b52aed9877253b03ebc2fba5a1326c45c8d Mon Sep 17 00:00:00 2001
253 +From: Seth Forshee <seth.forshee@×××××××××.com>
254 +Date: Wed, 14 Sep 2011 11:40:38 -0500
255 +Subject: [PATCH 3/8] Input: ALPS - Add protocol version field in alps_model_info
256 +
257 +In preparation for adding support for more ALPS protocol versions,
258 +add a field for the protocol version to the model info instead of
259 +using a field in the flags.
260 +---
261 + drivers/input/mouse/alps.c | 47 +++++++++++++++++++++----------------------
262 + drivers/input/mouse/alps.h | 4 +++
263 + 2 files changed, 27 insertions(+), 24 deletions(-)
264 +
265 +diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
266 +index ad15e7c..572cb21 100644
267 +--- a/drivers/input/mouse/alps.c
268 ++++ b/drivers/input/mouse/alps.c
269 +@@ -30,7 +30,6 @@
270 + #define dbg(format, arg...) do {} while (0)
271 + #endif
272 +
273 +-#define ALPS_OLDPROTO 0x01 /* old style input */
274 + #define ALPS_DUALPOINT 0x02 /* touchpad has trackstick */
275 + #define ALPS_PASS 0x04 /* device has a pass-through port */
276 +
277 +@@ -42,30 +41,30 @@
278 + 6-byte ALPS packet */
279 +
280 + static const struct alps_model_info alps_model_data[] = {
281 +- { { 0x32, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */
282 +- { { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO }, /* UMAX-530T */
283 +- { { 0x53, 0x02, 0x0a }, 0xf8, 0xf8, 0 },
284 +- { { 0x53, 0x02, 0x14 }, 0xf8, 0xf8, 0 },
285 +- { { 0x60, 0x03, 0xc8 }, 0xf8, 0xf8, 0 }, /* HP ze1115 */
286 +- { { 0x63, 0x02, 0x0a }, 0xf8, 0xf8, 0 },
287 +- { { 0x63, 0x02, 0x14 }, 0xf8, 0xf8, 0 },
288 +- { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */
289 +- { { 0x63, 0x02, 0x3c }, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */
290 +- { { 0x63, 0x02, 0x50 }, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */
291 +- { { 0x63, 0x02, 0x64 }, 0xf8, 0xf8, 0 },
292 +- { { 0x63, 0x03, 0xc8 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D800 */
293 +- { { 0x73, 0x00, 0x0a }, 0xf8, 0xf8, ALPS_DUALPOINT }, /* ThinkPad R61 8918-5QG */
294 +- { { 0x73, 0x02, 0x0a }, 0xf8, 0xf8, 0 },
295 +- { { 0x73, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Ahtec Laptop */
296 +- { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
297 +- { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
298 +- { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
299 ++ { { 0x32, 0x02, 0x14 }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */
300 ++ { { 0x33, 0x02, 0x0a }, ALPS_PROTO_V1, 0x88, 0xf8, 0 }, /* UMAX-530T */
301 ++ { { 0x53, 0x02, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
302 ++ { { 0x53, 0x02, 0x14 }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
303 ++ { { 0x60, 0x03, 0xc8 }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, /* HP ze1115 */
304 ++ { { 0x63, 0x02, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
305 ++ { { 0x63, 0x02, 0x14 }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
306 ++ { { 0x63, 0x02, 0x28 }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */
307 ++ { { 0x63, 0x02, 0x3c }, ALPS_PROTO_V2, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */
308 ++ { { 0x63, 0x02, 0x50 }, ALPS_PROTO_V2, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */
309 ++ { { 0x63, 0x02, 0x64 }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
310 ++ { { 0x63, 0x03, 0xc8 }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D800 */
311 ++ { { 0x73, 0x00, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_DUALPOINT }, /* ThinkPad R61 8918-5QG */
312 ++ { { 0x73, 0x02, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
313 ++ { { 0x73, 0x02, 0x14 }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Ahtec Laptop */
314 ++ { { 0x20, 0x02, 0x0e }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
315 ++ { { 0x22, 0x02, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
316 ++ { { 0x22, 0x02, 0x14 }, ALPS_PROTO_V2, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
317 + /* Dell Latitude E5500, E6400, E6500, Precision M4400 */
318 +- { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf,
319 ++ { { 0x62, 0x02, 0x14 }, ALPS_PROTO_V2, 0xcf, 0xcf,
320 + ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
321 +- { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */
322 +- { { 0x52, 0x01, 0x14 }, 0xff, 0xff,
323 +- ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */
324 ++ { { 0x73, 0x02, 0x50 }, ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */
325 ++ { { 0x52, 0x01, 0x14 }, ALPS_PROTO_V2, 0xff, 0xff,
326 ++ ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */
327 + };
328 +
329 + /*
330 +@@ -119,7 +118,7 @@ static void alps_process_packet(struct psmouse *psmouse)
331 + int x, y, z, ges, fin, left, right, middle;
332 + int back = 0, forward = 0;
333 +
334 +- if (model->flags & ALPS_OLDPROTO) {
335 ++ if (model->proto_version == ALPS_PROTO_V1) {
336 + left = packet[2] & 0x10;
337 + right = packet[2] & 0x08;
338 + middle = 0;
339 +diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
340 +index 904ed8b..4ce9bba 100644
341 +--- a/drivers/input/mouse/alps.h
342 ++++ b/drivers/input/mouse/alps.h
343 +@@ -12,8 +12,12 @@
344 + #ifndef _ALPS_H
345 + #define _ALPS_H
346 +
347 ++#define ALPS_PROTO_V1 0
348 ++#define ALPS_PROTO_V2 1
349 ++
350 + struct alps_model_info {
351 + unsigned char signature[3];
352 ++ unsigned char proto_version;
353 + unsigned char byte0, mask0;
354 + unsigned char flags;
355 + };
356 +--
357 +1.7.4.1
358 +
359
360 Added: genpatches-2.6/trunk/3.0/2615_Input-ALPS-Remove-assumptions-about-packet-size.patch
361 ===================================================================
362 --- genpatches-2.6/trunk/3.0/2615_Input-ALPS-Remove-assumptions-about-packet-size.patch (rev 0)
363 +++ genpatches-2.6/trunk/3.0/2615_Input-ALPS-Remove-assumptions-about-packet-size.patch 2011-09-28 14:30:19 UTC (rev 1982)
364 @@ -0,0 +1,89 @@
365 +From 32d5e73c517b64db55586dd60edfa635b2121213 Mon Sep 17 00:00:00 2001
366 +From: Seth Forshee <seth.forshee@×××××××××.com>
367 +Date: Wed, 14 Sep 2011 11:40:38 -0500
368 +Subject: [PATCH 4/8] Input: ALPS - Remove assumptions about packet size
369 +
370 +In preparation for version 4 protocol support, which has 8-byte
371 +data packets, remove all hard-coded assumptions about packet size
372 +and use psmouse->pktsize instead.
373 +---
374 + drivers/input/mouse/alps.c | 27 ++++++++++++++++++---------
375 + 1 files changed, 18 insertions(+), 9 deletions(-)
376 +
377 +diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
378 +index 572cb21..14d1f64 100644
379 +--- a/drivers/input/mouse/alps.c
380 ++++ b/drivers/input/mouse/alps.c
381 +@@ -315,7 +315,7 @@ static void alps_flush_packet(unsigned long data)
382 +
383 + serio_pause_rx(psmouse->ps2dev.serio);
384 +
385 +- if (psmouse->pktcnt == 6) {
386 ++ if (psmouse->pktcnt == psmouse->pktsize) {
387 +
388 + /*
389 + * We did not any more data in reasonable amount of time.
390 +@@ -365,15 +365,15 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
391 + return PSMOUSE_BAD_DATA;
392 + }
393 +
394 +- /* Bytes 2 - 6 should have 0 in the highest bit */
395 +- if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= 6 &&
396 ++ /* Bytes 2 - pktsize should have 0 in the highest bit */
397 ++ if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
398 + (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
399 + dbg("refusing packet[%i] = %x\n",
400 + psmouse->pktcnt - 1, psmouse->packet[psmouse->pktcnt - 1]);
401 + return PSMOUSE_BAD_DATA;
402 + }
403 +
404 +- if (psmouse->pktcnt == 6) {
405 ++ if (psmouse->pktcnt == psmouse->pktsize) {
406 + alps_process_packet(psmouse);
407 + return PSMOUSE_FULL_PACKET;
408 + }
409 +@@ -531,8 +531,13 @@ static int alps_tap_mode(struct psmouse *psmouse, int enable)
410 + static int alps_poll(struct psmouse *psmouse)
411 + {
412 + struct alps_data *priv = psmouse->private;
413 +- unsigned char buf[6];
414 ++ unsigned char *buf;
415 + bool poll_failed;
416 ++ int ret = -1;
417 ++
418 ++ buf = kmalloc(psmouse->pktsize, GFP_KERNEL);
419 ++ if (!buf)
420 ++ return -1;
421 +
422 + if (priv->i->flags & ALPS_PASS)
423 + alps_passthrough_mode(psmouse, true);
424 +@@ -544,18 +549,22 @@ static int alps_poll(struct psmouse *psmouse)
425 + alps_passthrough_mode(psmouse, false);
426 +
427 + if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0)
428 +- return -1;
429 ++ goto out;
430 +
431 + if ((psmouse->badbyte & 0xc8) == 0x08) {
432 + /*
433 + * Poll the track stick ...
434 + */
435 + if (ps2_command(&psmouse->ps2dev, buf, PSMOUSE_CMD_POLL | (3 << 8)))
436 +- return -1;
437 ++ goto out;
438 + }
439 +
440 +- memcpy(psmouse->packet, buf, sizeof(buf));
441 +- return 0;
442 ++ memcpy(psmouse->packet, buf, psmouse->pktsize);
443 ++ ret = 0;
444 ++
445 ++out:
446 ++ kfree(buf);
447 ++ return ret;
448 + }
449 +
450 + static int alps_hw_init(struct psmouse *psmouse)
451 +--
452 +1.7.4.1
453 +
454
455 Added: genpatches-2.6/trunk/3.0/2620_Input-ALPS-Add-support-for-protocol-versions-3-and-4.patch
456 ===================================================================
457 --- genpatches-2.6/trunk/3.0/2620_Input-ALPS-Add-support-for-protocol-versions-3-and-4.patch (rev 0)
458 +++ genpatches-2.6/trunk/3.0/2620_Input-ALPS-Add-support-for-protocol-versions-3-and-4.patch 2011-09-28 14:30:19 UTC (rev 1982)
459 @@ -0,0 +1,943 @@
460 +From baf5955491da6d651054b32b7e43850a49c9c116 Mon Sep 17 00:00:00 2001
461 +From: Seth Forshee <seth.forshee@×××××××××.com>
462 +Date: Wed, 14 Sep 2011 11:40:39 -0500
463 +Subject: [PATCH 5/8] Input: ALPS - Add support for protocol versions 3 and 4
464 +
465 +Currently only single-touch, multi-touch to be added in the future.
466 +---
467 + drivers/input/mouse/alps.c | 761 +++++++++++++++++++++++++++++++++++++++++---
468 + drivers/input/mouse/alps.h | 11 +
469 + 2 files changed, 734 insertions(+), 38 deletions(-)
470 +
471 +diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
472 +index 14d1f64..2615b92 100644
473 +--- a/drivers/input/mouse/alps.c
474 ++++ b/drivers/input/mouse/alps.c
475 +@@ -30,6 +30,50 @@
476 + #define dbg(format, arg...) do {} while (0)
477 + #endif
478 +
479 ++/*
480 ++ * Definitions for ALPS version 3 and 4 command mode protocol
481 ++ */
482 ++#define ALPS_CMD_NIBBLE_10 0x01f2
483 ++
484 ++static const struct alps_nibble_commands alps_v3_nibble_commands[] = {
485 ++ { PSMOUSE_CMD_SETPOLL, 0x00 }, /* 0 */
486 ++ { PSMOUSE_CMD_RESET_DIS, 0x00 }, /* 1 */
487 ++ { PSMOUSE_CMD_SETSCALE21, 0x00 }, /* 2 */
488 ++ { PSMOUSE_CMD_SETRATE, 0x0a }, /* 3 */
489 ++ { PSMOUSE_CMD_SETRATE, 0x14 }, /* 4 */
490 ++ { PSMOUSE_CMD_SETRATE, 0x28 }, /* 5 */
491 ++ { PSMOUSE_CMD_SETRATE, 0x3c }, /* 6 */
492 ++ { PSMOUSE_CMD_SETRATE, 0x50 }, /* 7 */
493 ++ { PSMOUSE_CMD_SETRATE, 0x64 }, /* 8 */
494 ++ { PSMOUSE_CMD_SETRATE, 0xc8 }, /* 9 */
495 ++ { ALPS_CMD_NIBBLE_10, 0x00 }, /* a */
496 ++ { PSMOUSE_CMD_SETRES, 0x00 }, /* b */
497 ++ { PSMOUSE_CMD_SETRES, 0x01 }, /* c */
498 ++ { PSMOUSE_CMD_SETRES, 0x02 }, /* d */
499 ++ { PSMOUSE_CMD_SETRES, 0x03 }, /* e */
500 ++ { PSMOUSE_CMD_SETSCALE11, 0x00 }, /* f */
501 ++};
502 ++
503 ++static const struct alps_nibble_commands alps_v4_nibble_commands[] = {
504 ++ { PSMOUSE_CMD_ENABLE, 0x00 }, /* 0 */
505 ++ { PSMOUSE_CMD_RESET_DIS, 0x00 }, /* 1 */
506 ++ { PSMOUSE_CMD_SETSCALE21, 0x00 }, /* 2 */
507 ++ { PSMOUSE_CMD_SETRATE, 0x0a }, /* 3 */
508 ++ { PSMOUSE_CMD_SETRATE, 0x14 }, /* 4 */
509 ++ { PSMOUSE_CMD_SETRATE, 0x28 }, /* 5 */
510 ++ { PSMOUSE_CMD_SETRATE, 0x3c }, /* 6 */
511 ++ { PSMOUSE_CMD_SETRATE, 0x50 }, /* 7 */
512 ++ { PSMOUSE_CMD_SETRATE, 0x64 }, /* 8 */
513 ++ { PSMOUSE_CMD_SETRATE, 0xc8 }, /* 9 */
514 ++ { ALPS_CMD_NIBBLE_10, 0x00 }, /* a */
515 ++ { PSMOUSE_CMD_SETRES, 0x00 }, /* b */
516 ++ { PSMOUSE_CMD_SETRES, 0x01 }, /* c */
517 ++ { PSMOUSE_CMD_SETRES, 0x02 }, /* d */
518 ++ { PSMOUSE_CMD_SETRES, 0x03 }, /* e */
519 ++ { PSMOUSE_CMD_SETSCALE11, 0x00 }, /* f */
520 ++};
521 ++
522 ++
523 + #define ALPS_DUALPOINT 0x02 /* touchpad has trackstick */
524 + #define ALPS_PASS 0x04 /* device has a pass-through port */
525 +
526 +@@ -41,30 +85,33 @@
527 + 6-byte ALPS packet */
528 +
529 + static const struct alps_model_info alps_model_data[] = {
530 +- { { 0x32, 0x02, 0x14 }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */
531 +- { { 0x33, 0x02, 0x0a }, ALPS_PROTO_V1, 0x88, 0xf8, 0 }, /* UMAX-530T */
532 +- { { 0x53, 0x02, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
533 +- { { 0x53, 0x02, 0x14 }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
534 +- { { 0x60, 0x03, 0xc8 }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, /* HP ze1115 */
535 +- { { 0x63, 0x02, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
536 +- { { 0x63, 0x02, 0x14 }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
537 +- { { 0x63, 0x02, 0x28 }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */
538 +- { { 0x63, 0x02, 0x3c }, ALPS_PROTO_V2, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */
539 +- { { 0x63, 0x02, 0x50 }, ALPS_PROTO_V2, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */
540 +- { { 0x63, 0x02, 0x64 }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
541 +- { { 0x63, 0x03, 0xc8 }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D800 */
542 +- { { 0x73, 0x00, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_DUALPOINT }, /* ThinkPad R61 8918-5QG */
543 +- { { 0x73, 0x02, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
544 +- { { 0x73, 0x02, 0x14 }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Ahtec Laptop */
545 +- { { 0x20, 0x02, 0x0e }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
546 +- { { 0x22, 0x02, 0x0a }, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
547 +- { { 0x22, 0x02, 0x14 }, ALPS_PROTO_V2, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
548 ++ { { 0x32, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */
549 ++ { { 0x33, 0x02, 0x0a }, 0x00, ALPS_PROTO_V1, 0x88, 0xf8, 0 }, /* UMAX-530T */
550 ++ { { 0x53, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
551 ++ { { 0x53, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
552 ++ { { 0x60, 0x03, 0xc8 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 }, /* HP ze1115 */
553 ++ { { 0x63, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
554 ++ { { 0x63, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
555 ++ { { 0x63, 0x02, 0x28 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */
556 ++ { { 0x63, 0x02, 0x3c }, 0x00, ALPS_PROTO_V2, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */
557 ++ { { 0x63, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */
558 ++ { { 0x63, 0x02, 0x64 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
559 ++ { { 0x63, 0x03, 0xc8 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D800 */
560 ++ { { 0x73, 0x00, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_DUALPOINT }, /* ThinkPad R61 8918-5QG */
561 ++ { { 0x73, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
562 ++ { { 0x73, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Ahtec Laptop */
563 ++ { { 0x20, 0x02, 0x0e }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
564 ++ { { 0x22, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
565 ++ { { 0x22, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
566 + /* Dell Latitude E5500, E6400, E6500, Precision M4400 */
567 +- { { 0x62, 0x02, 0x14 }, ALPS_PROTO_V2, 0xcf, 0xcf,
568 ++ { { 0x62, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf,
569 + ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
570 +- { { 0x73, 0x02, 0x50 }, ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */
571 +- { { 0x52, 0x01, 0x14 }, ALPS_PROTO_V2, 0xff, 0xff,
572 +- ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */
573 ++ { { 0x73, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS }, /* Dell Vostro 1400 */
574 ++ { { 0x52, 0x01, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff,
575 ++ ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED }, /* Toshiba Tecra A11-11L */
576 ++ { { 0x73, 0x02, 0x64 }, 0x9b, ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT }, /* Ahtec Laptop */
577 ++ { { 0x73, 0x02, 0x64 }, 0x9d, ALPS_PROTO_V3, 0x8f, 0x8f, ALPS_DUALPOINT }, /* Ahtec Laptop */
578 ++ { { 0x73, 0x02, 0x64 }, 0x8a, ALPS_PROTO_V4, 0x8f, 0x8f, 0 }, /* Ahtec Laptop */
579 + };
580 +
581 + /*
582 +@@ -108,7 +155,7 @@ static void alps_report_buttons(struct psmouse *psmouse,
583 + input_sync(dev2);
584 + }
585 +
586 +-static void alps_process_packet(struct psmouse *psmouse)
587 ++static void alps_process_packet_v1_v2(struct psmouse *psmouse)
588 + {
589 + struct alps_data *priv = psmouse->private;
590 + const struct alps_model_info *model = priv->i;
591 +@@ -210,6 +257,200 @@ static void alps_process_packet(struct psmouse *psmouse)
592 + input_sync(dev);
593 + }
594 +
595 ++static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
596 ++{
597 ++ struct alps_data *priv = psmouse->private;
598 ++ unsigned char *packet = psmouse->packet;
599 ++ struct input_dev *dev = priv->dev2;
600 ++ int x, y, z, left, right, middle;
601 ++
602 ++ /* Sanity check packet */
603 ++ if (!(packet[0] & 0x40)) {
604 ++ pr_debug("alps.c: Bad trackstick packet, discarding\n");
605 ++ return;
606 ++ }
607 ++
608 ++ /*
609 ++ * There's a special packet that seems to indicate the end
610 ++ * of a stream of trackstick data. Filter these out.
611 ++ */
612 ++ if (packet[1] == 0x7f && packet[2] == 0x7f && packet[4] == 0x7f)
613 ++ return;
614 ++
615 ++ x = (s8)(((packet[0] & 0x20) << 2) | (packet[1] & 0x7f));
616 ++ y = (s8)(((packet[0] & 0x10) << 3) | (packet[2] & 0x7f));
617 ++ z = (packet[4] & 0x7c) >> 2;
618 ++
619 ++ left = packet[3] & 0x01;
620 ++ right = packet[3] & 0x02;
621 ++ middle = packet[3] & 0x04;
622 ++
623 ++ /*
624 ++ * The x and y values tend to be quite large, and when used
625 ++ * alone the trackstick is difficult to use. Scale them down
626 ++ * to compensate.
627 ++ */
628 ++ x /= 8;
629 ++ y /= 8;
630 ++
631 ++ input_report_rel(dev, REL_X, x);
632 ++ input_report_rel(dev, REL_Y, -y);
633 ++
634 ++ input_report_key(dev, BTN_LEFT, left);
635 ++ input_report_key(dev, BTN_RIGHT, right);
636 ++ input_report_key(dev, BTN_MIDDLE, middle);
637 ++
638 ++ input_sync(dev);
639 ++ return;
640 ++}
641 ++
642 ++static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
643 ++{
644 ++ struct alps_data *priv = psmouse->private;
645 ++ unsigned char *packet = psmouse->packet;
646 ++ struct input_dev *dev = psmouse->dev;
647 ++ int x, y, z;
648 ++ int left, right, middle;
649 ++
650 ++ /*
651 ++ * There's no single feature of touchpad position and bitmap
652 ++ * packets that can be used to distinguish between them. We
653 ++ * rely on the fact that a bitmap packet should always follow
654 ++ * a position packet with bit 6 of packet[4] set.
655 ++ */
656 ++ if (priv->multi_packet) {
657 ++ priv->multi_packet = 0;
658 ++
659 ++ /*
660 ++ * Sometimes a position packet will indicate a multi-packet
661 ++ * sequence, but then what follows is another position
662 ++ * packet. Check for this, and when it happens process the
663 ++ * position packet as usual.
664 ++ */
665 ++ if (packet[0] & 0x40) {
666 ++ /*
667 ++ * Bitmap packets are not yet supported, so for now
668 ++ * just ignore them.
669 ++ */
670 ++ return;
671 ++ }
672 ++ }
673 ++
674 ++ if (!priv->multi_packet && (packet[4] & 0x40))
675 ++ priv->multi_packet = 1;
676 ++ else
677 ++ priv->multi_packet = 0;
678 ++
679 ++ /*
680 ++ * Bits in the upper nibble of byte 3 represent the trackstick
681 ++ * buttons on some models, but on other models the trackstick
682 ++ * buttons are reported in the trackstic packets. If we try to
683 ++ * report the buttons on the trackstick device from here it can
684 ++ * lead to conflicts, so we treat any buttons reported in the
685 ++ * touchpad packets as belonging to the touchpad.
686 ++ */
687 ++ left = packet[3] & 0x11;
688 ++ right = packet[3] & 0x22;
689 ++ middle = packet[3] & 0x44;
690 ++
691 ++ x = ((packet[1] & 0x7f) << 4) | ((packet[4] & 0x30) >> 2) |
692 ++ ((packet[0] & 0x30) >> 4);
693 ++ y = ((packet[2] & 0x7f) << 4) | (packet[4] & 0x0f);
694 ++ z = packet[5] & 0x7f;
695 ++
696 ++ if (z >= 64) {
697 ++ input_report_key(dev, BTN_TOUCH, 1);
698 ++ } else {
699 ++ input_report_key(dev, BTN_TOUCH, 0);
700 ++ }
701 ++
702 ++ if (z > 0) {
703 ++ input_report_abs(dev, ABS_X, x);
704 ++ input_report_abs(dev, ABS_Y, y);
705 ++ }
706 ++ input_report_abs(dev, ABS_PRESSURE, z);
707 ++
708 ++ input_report_key(dev, BTN_TOOL_FINGER, z > 0);
709 ++ input_report_key(dev, BTN_LEFT, left);
710 ++ input_report_key(dev, BTN_RIGHT, right);
711 ++ input_report_key(dev, BTN_MIDDLE, middle);
712 ++
713 ++ input_sync(dev);
714 ++}
715 ++
716 ++static void alps_process_packet_v3(struct psmouse *psmouse)
717 ++{
718 ++ unsigned char *packet = psmouse->packet;
719 ++
720 ++ /*
721 ++ * v3 protocol packets come in three types, two representing
722 ++ * touchpad data and one representing trackstick data.
723 ++ * Trackstick packets seem to be distinguished by always
724 ++ * having 0x3f in the last byte. This value has never been
725 ++ * observed in the last byte of either of the other types
726 ++ * of packets.
727 ++ */
728 ++ if (packet[5] == 0x3f) {
729 ++ alps_process_trackstick_packet_v3(psmouse);
730 ++ return;
731 ++ }
732 ++
733 ++ alps_process_touchpad_packet_v3(psmouse);
734 ++}
735 ++
736 ++static void alps_process_packet_v4(struct psmouse *psmouse)
737 ++{
738 ++ unsigned char *packet = psmouse->packet;
739 ++ struct input_dev *dev = psmouse->dev;
740 ++ int x, y, z;
741 ++ int left, right;
742 ++
743 ++ left = packet[4] & 0x01;
744 ++ right = packet[4] & 0x02;
745 ++
746 ++ x = ((packet[1] & 0x7f) << 4) | ((packet[3] & 0x30) >> 2) |
747 ++ ((packet[0] & 0x30) >> 4);
748 ++ y = ((packet[2] & 0x7f) << 4) | (packet[3] & 0x0f);
749 ++ z = packet[5] & 0x7f;
750 ++
751 ++ if (z >= 64) {
752 ++ input_report_key(dev, BTN_TOUCH, 1);
753 ++ } else {
754 ++ input_report_key(dev, BTN_TOUCH, 0);
755 ++ }
756 ++
757 ++ if (z > 0) {
758 ++ input_report_abs(dev, ABS_X, x);
759 ++ input_report_abs(dev, ABS_Y, y);
760 ++ }
761 ++ input_report_abs(dev, ABS_PRESSURE, z);
762 ++
763 ++ input_report_key(dev, BTN_TOOL_FINGER, z > 0);
764 ++ input_report_key(dev, BTN_LEFT, left);
765 ++ input_report_key(dev, BTN_RIGHT, right);
766 ++
767 ++ input_sync(dev);
768 ++}
769 ++
770 ++static void alps_process_packet(struct psmouse *psmouse)
771 ++{
772 ++ struct alps_data *priv = psmouse->private;
773 ++ const struct alps_model_info *model = priv->i;
774 ++
775 ++ switch (model->proto_version) {
776 ++ case ALPS_PROTO_V1:
777 ++ case ALPS_PROTO_V2:
778 ++ alps_process_packet_v1_v2(psmouse);
779 ++ break;
780 ++ case ALPS_PROTO_V3:
781 ++ alps_process_packet_v3(psmouse);
782 ++ break;
783 ++ case ALPS_PROTO_V4:
784 ++ alps_process_packet_v4(psmouse);
785 ++ break;
786 ++ }
787 ++}
788 ++
789 + static void alps_report_bare_ps2_packet(struct psmouse *psmouse,
790 + unsigned char packet[],
791 + bool report_buttons)
792 +@@ -381,11 +622,126 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
793 + return PSMOUSE_GOOD_DATA;
794 + }
795 +
796 ++static int alps_command_mode_send_nibble(struct psmouse *psmouse, int nibble)
797 ++{
798 ++ struct ps2dev *ps2dev = &psmouse->ps2dev;
799 ++ struct alps_data *priv = psmouse->private;
800 ++ int command;
801 ++ unsigned char *param;
802 ++ unsigned char dummy[4];
803 ++
804 ++ BUG_ON(nibble > 0xf);
805 ++
806 ++ command = priv->nibble_commands[nibble].command;
807 ++ param = (command & 0x0f00) ?
808 ++ dummy : (unsigned char *)&priv->nibble_commands[nibble].data;
809 ++
810 ++ if (ps2_command(ps2dev, param, command))
811 ++ return -1;
812 ++
813 ++ return 0;
814 ++}
815 ++
816 ++static int alps_command_mode_set_addr(struct psmouse *psmouse, int addr)
817 ++{
818 ++ struct ps2dev *ps2dev = &psmouse->ps2dev;
819 ++ struct alps_data *priv = psmouse->private;
820 ++ int i, nibble;
821 ++
822 ++ if (ps2_command(ps2dev, NULL, priv->addr_command))
823 ++ return -1;
824 ++
825 ++ for (i = 12; i >= 0; i -= 4) {
826 ++ nibble = (addr >> i) & 0xf;
827 ++ if (alps_command_mode_send_nibble(psmouse, nibble))
828 ++ return -1;
829 ++ }
830 ++
831 ++ return 0;
832 ++}
833 ++
834 ++static int __alps_command_mode_read_reg(struct psmouse *psmouse, int addr)
835 ++{
836 ++ struct ps2dev *ps2dev = &psmouse->ps2dev;
837 ++ unsigned char param[4];
838 ++
839 ++ if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
840 ++ return -1;
841 ++
842 ++ /*
843 ++ * The address being read is returned in the first two bytes
844 ++ * of the result. Check that this address matches the expected
845 ++ * address.
846 ++ */
847 ++ if (addr != ((param[0] << 8) | param[1]))
848 ++ return -1;
849 ++
850 ++ return param[2];
851 ++}
852 ++
853 ++static int alps_command_mode_read_reg(struct psmouse *psmouse, int addr)
854 ++{
855 ++ if (alps_command_mode_set_addr(psmouse, addr))
856 ++ return -1;
857 ++ return __alps_command_mode_read_reg(psmouse, addr);
858 ++}
859 ++
860 ++static int __alps_command_mode_write_reg(struct psmouse *psmouse, u8 value)
861 ++{
862 ++ if (alps_command_mode_send_nibble(psmouse, (value >> 4) & 0xf))
863 ++ return -1;
864 ++ if (alps_command_mode_send_nibble(psmouse, value & 0xf))
865 ++ return -1;
866 ++ return 0;
867 ++}
868 ++
869 ++static int alps_command_mode_write_reg(struct psmouse *psmouse, int addr,
870 ++ u8 value)
871 ++{
872 ++ if (alps_command_mode_set_addr(psmouse, addr))
873 ++ return -1;
874 ++ return __alps_command_mode_write_reg(psmouse, value);
875 ++}
876 ++
877 ++static int alps_enter_command_mode(struct psmouse *psmouse,
878 ++ unsigned char *resp)
879 ++{
880 ++ unsigned char param[4];
881 ++ struct ps2dev *ps2dev = &psmouse->ps2dev;
882 ++
883 ++ if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) ||
884 ++ ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) ||
885 ++ ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) ||
886 ++ ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
887 ++ pr_err("alps.c: failed to enter command mode\n");
888 ++ return -1;
889 ++ }
890 ++
891 ++ if (param[0] != 0x88 && param[1] != 0x07) {
892 ++ pr_debug("alps.c: unknown response while entering command mode: %2.2x %2.2x %2.2x\n",
893 ++ param[0], param[1], param[2]);
894 ++ return -1;
895 ++ }
896 ++
897 ++ if (resp)
898 ++ *resp = param[2];
899 ++ return 0;
900 ++}
901 ++
902 ++static inline int alps_exit_command_mode(struct psmouse *psmouse)
903 ++{
904 ++ struct ps2dev *ps2dev = &psmouse->ps2dev;
905 ++ if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM))
906 ++ return -1;
907 ++ return 0;
908 ++}
909 ++
910 + static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *version)
911 + {
912 + struct ps2dev *ps2dev = &psmouse->ps2dev;
913 + static const unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 };
914 + unsigned char param[4];
915 ++ const struct alps_model_info *model = NULL;
916 + int i;
917 +
918 + /*
919 +@@ -431,12 +787,38 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int
920 + *version = (param[0] << 8) | (param[1] << 4) | i;
921 + }
922 +
923 +- for (i = 0; i < ARRAY_SIZE(alps_model_data); i++)
924 ++ for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) {
925 + if (!memcmp(param, alps_model_data[i].signature,
926 +- sizeof(alps_model_data[i].signature)))
927 +- return alps_model_data + i;
928 ++ sizeof(alps_model_data[i].signature))) {
929 ++ model = alps_model_data + i;
930 ++ break;
931 ++ }
932 ++ }
933 ++
934 ++ if (model && model->proto_version > ALPS_PROTO_V2) {
935 ++ /*
936 ++ * Need to check command mode response to identify
937 ++ * model
938 ++ */
939 ++ model = NULL;
940 ++ if (alps_enter_command_mode(psmouse, param)) {
941 ++ pr_warn("alps.c: touchpad failed to enter command mode\n");
942 ++ } else {
943 ++ for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) {
944 ++ if (alps_model_data[i].proto_version > ALPS_PROTO_V2 &&
945 ++ alps_model_data[i].command_mode_resp == param[0]) {
946 ++ model = alps_model_data + i;
947 ++ break;
948 ++ }
949 ++ }
950 ++ alps_exit_command_mode(psmouse);
951 ++
952 ++ if (!model)
953 ++ pr_debug("alps.c: Unknown command mode response %2.2x\n", param[0]);
954 ++ }
955 ++ }
956 +
957 +- return NULL;
958 ++ return model;
959 + }
960 +
961 + /*
962 +@@ -444,7 +826,7 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int
963 + * subsequent commands. It looks like glidepad is behind stickpointer,
964 + * I'd thought it would be other way around...
965 + */
966 +-static int alps_passthrough_mode(struct psmouse *psmouse, bool enable)
967 ++static int alps_passthrough_mode_v2(struct psmouse *psmouse, bool enable)
968 + {
969 + struct ps2dev *ps2dev = &psmouse->ps2dev;
970 + int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11;
971 +@@ -461,7 +843,7 @@ static int alps_passthrough_mode(struct psmouse *psmouse, bool enable)
972 + return 0;
973 + }
974 +
975 +-static int alps_absolute_mode(struct psmouse *psmouse)
976 ++static int alps_absolute_mode_v1_v2(struct psmouse *psmouse)
977 + {
978 + struct ps2dev *ps2dev = &psmouse->ps2dev;
979 +
980 +@@ -540,13 +922,13 @@ static int alps_poll(struct psmouse *psmouse)
981 + return -1;
982 +
983 + if (priv->i->flags & ALPS_PASS)
984 +- alps_passthrough_mode(psmouse, true);
985 ++ alps_passthrough_mode_v2(psmouse, true);
986 +
987 + poll_failed = ps2_command(&psmouse->ps2dev, buf,
988 + PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0;
989 +
990 + if (priv->i->flags & ALPS_PASS)
991 +- alps_passthrough_mode(psmouse, false);
992 ++ alps_passthrough_mode_v2(psmouse, false);
993 +
994 + if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0)
995 + goto out;
996 +@@ -567,13 +949,13 @@ out:
997 + return ret;
998 + }
999 +
1000 +-static int alps_hw_init(struct psmouse *psmouse)
1001 ++static int alps_hw_init_v1_v2(struct psmouse *psmouse)
1002 + {
1003 + struct alps_data *priv = psmouse->private;
1004 + const struct alps_model_info *model = priv->i;
1005 +
1006 + if ((model->flags & ALPS_PASS) &&
1007 +- alps_passthrough_mode(psmouse, true)) {
1008 ++ alps_passthrough_mode_v2(psmouse, true)) {
1009 + return -1;
1010 + }
1011 +
1012 +@@ -582,13 +964,13 @@ static int alps_hw_init(struct psmouse *psmouse)
1013 + return -1;
1014 + }
1015 +
1016 +- if (alps_absolute_mode(psmouse)) {
1017 ++ if (alps_absolute_mode_v1_v2(psmouse)) {
1018 + printk(KERN_ERR "alps.c: Failed to enable absolute mode\n");
1019 + return -1;
1020 + }
1021 +
1022 + if ((model->flags & ALPS_PASS) &&
1023 +- alps_passthrough_mode(psmouse, false)) {
1024 ++ alps_passthrough_mode_v2(psmouse, false)) {
1025 + return -1;
1026 + }
1027 +
1028 +@@ -601,6 +983,295 @@ static int alps_hw_init(struct psmouse *psmouse)
1029 + return 0;
1030 + }
1031 +
1032 ++/*
1033 ++ * Enable or disable passthrough mode to the trackstick. Must be in
1034 ++ * command mode when calling this function.
1035 ++ */
1036 ++static int alps_passthrough_mode_v3(struct psmouse *psmouse, bool enable)
1037 ++{
1038 ++ int reg_val;
1039 ++
1040 ++ reg_val = alps_command_mode_read_reg(psmouse, 0x0008);
1041 ++ if (reg_val == -1)
1042 ++ return -1;
1043 ++
1044 ++ if (enable)
1045 ++ reg_val |= 0x01;
1046 ++ else
1047 ++ reg_val &= ~0x01;
1048 ++
1049 ++ if (__alps_command_mode_write_reg(psmouse, reg_val))
1050 ++ return -1;
1051 ++
1052 ++ return 0;
1053 ++}
1054 ++
1055 ++/* Must be in command mode when calling this function */
1056 ++static int alps_absolute_mode_v3(struct psmouse *psmouse)
1057 ++{
1058 ++ int reg_val;
1059 ++
1060 ++ reg_val = alps_command_mode_read_reg(psmouse, 0x0004);
1061 ++ if (reg_val == -1)
1062 ++ return -1;
1063 ++
1064 ++ reg_val |= 0x06;
1065 ++ if (__alps_command_mode_write_reg(psmouse, reg_val))
1066 ++ return -1;
1067 ++
1068 ++ return 0;
1069 ++}
1070 ++
1071 ++static int alps_hw_init_v3(struct psmouse *psmouse)
1072 ++{
1073 ++ struct alps_data *priv = psmouse->private;
1074 ++ struct ps2dev *ps2dev = &psmouse->ps2dev;
1075 ++ int reg_val;
1076 ++ unsigned char param[4];
1077 ++
1078 ++ priv->nibble_commands = alps_v3_nibble_commands;
1079 ++ priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
1080 ++
1081 ++ if (alps_enter_command_mode(psmouse, NULL))
1082 ++ goto error;
1083 ++
1084 ++ /* Check for trackstick */
1085 ++ reg_val = alps_command_mode_read_reg(psmouse, 0x0008);
1086 ++ if (reg_val == -1)
1087 ++ goto error;
1088 ++ if (reg_val & 0x80) {
1089 ++ if (alps_passthrough_mode_v3(psmouse, true))
1090 ++ goto error;
1091 ++ if (alps_exit_command_mode(psmouse))
1092 ++ goto error;
1093 ++
1094 ++ /*
1095 ++ * E7 report for the trackstick
1096 ++ *
1097 ++ * There have been reports of failures to seem to trace back
1098 ++ * to the above trackstick check failing. When these occur
1099 ++ * this E7 report fails, so when that happens we continue
1100 ++ * with the assumption that there isn't a trackstick after
1101 ++ * all.
1102 ++ */
1103 ++ param[0] = 0x64;
1104 ++ if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
1105 ++ ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
1106 ++ ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
1107 ++ ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
1108 ++ pr_warn("alps.c: trackstick E7 report failed\n");
1109 ++ } else {
1110 ++ pr_debug("alps.c: trackstick E7 report: %2.2x %2.2x %2.2x\n",
1111 ++ param[0], param[1], param[2]);
1112 ++
1113 ++ /*
1114 ++ * Not sure what this does, but it is absolutely
1115 ++ * essential. Without it, the touchpad does not
1116 ++ * work at all and the trackstick just emits normal
1117 ++ * PS/2 packets.
1118 ++ */
1119 ++ if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
1120 ++ ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
1121 ++ ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
1122 ++ alps_command_mode_send_nibble(psmouse, 0x9) ||
1123 ++ alps_command_mode_send_nibble(psmouse, 0x4)) {
1124 ++ pr_err("alps.c: Error sending magic E6 sequence\n");
1125 ++ goto error_passthrough;
1126 ++ }
1127 ++ }
1128 ++
1129 ++ if (alps_enter_command_mode(psmouse, NULL))
1130 ++ goto error_passthrough;
1131 ++ if (alps_passthrough_mode_v3(psmouse, false))
1132 ++ goto error;
1133 ++ }
1134 ++
1135 ++ if (alps_absolute_mode_v3(psmouse)) {
1136 ++ pr_err("alps.c: Failed to enter absolute mode\n");
1137 ++ goto error;
1138 ++ }
1139 ++
1140 ++ reg_val = alps_command_mode_read_reg(psmouse, 0x0006);
1141 ++ if (reg_val == -1)
1142 ++ goto error;
1143 ++ if (__alps_command_mode_write_reg(psmouse, reg_val | 0x01))
1144 ++ goto error;
1145 ++
1146 ++ reg_val = alps_command_mode_read_reg(psmouse, 0x0007);
1147 ++ if (reg_val == -1)
1148 ++ goto error;
1149 ++ if (__alps_command_mode_write_reg(psmouse, reg_val | 0x01))
1150 ++ goto error;
1151 ++
1152 ++ if (alps_command_mode_read_reg(psmouse, 0x0144) == -1)
1153 ++ goto error;
1154 ++ if (__alps_command_mode_write_reg(psmouse, 0x04))
1155 ++ goto error;
1156 ++
1157 ++ if (alps_command_mode_read_reg(psmouse, 0x0159) == -1)
1158 ++ goto error;
1159 ++ if (__alps_command_mode_write_reg(psmouse, 0x03))
1160 ++ goto error;
1161 ++
1162 ++ if (alps_command_mode_read_reg(psmouse, 0x0163) == -1)
1163 ++ goto error;
1164 ++ if (alps_command_mode_write_reg(psmouse, 0x0163, 0x03))
1165 ++ goto error;
1166 ++
1167 ++ if (alps_command_mode_read_reg(psmouse, 0x0162) == -1)
1168 ++ goto error;
1169 ++ if (alps_command_mode_write_reg(psmouse, 0x0162, 0x04))
1170 ++ goto error;
1171 ++
1172 ++ /*
1173 ++ * This ensures the trackstick packets are in the format
1174 ++ * supported by this driver. If bit 1 isn't set the packet
1175 ++ * format is different.
1176 ++ */
1177 ++ if (alps_command_mode_write_reg(psmouse, 0x0008, 0x82))
1178 ++ goto error;
1179 ++
1180 ++ alps_exit_command_mode(psmouse);
1181 ++
1182 ++ /* Set rate and enable data reporting */
1183 ++ param[0] = 0x64;
1184 ++ if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE) ||
1185 ++ ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE)) {
1186 ++ pr_err("alps.c: Failed to enable data reporting\n");
1187 ++ return -1;
1188 ++ }
1189 ++
1190 ++ return 0;
1191 ++
1192 ++error_passthrough:
1193 ++ /* Something failed while in passthrough mode, so try to get out */
1194 ++ if (!alps_enter_command_mode(psmouse, NULL))
1195 ++ alps_passthrough_mode_v3(psmouse, false);
1196 ++error:
1197 ++ /*
1198 ++ * Leaving the touchpad in command mode will essentially render
1199 ++ * it unusable until the machine reboots, so exit it here just
1200 ++ * to be safe
1201 ++ */
1202 ++ alps_exit_command_mode(psmouse);
1203 ++ return -1;
1204 ++}
1205 ++
1206 ++/* Must be in command mode when calling this function */
1207 ++static int alps_absolute_mode_v4(struct psmouse *psmouse)
1208 ++{
1209 ++ int reg_val;
1210 ++
1211 ++ reg_val = alps_command_mode_read_reg(psmouse, 0x0004);
1212 ++ if (reg_val == -1)
1213 ++ return -1;
1214 ++
1215 ++ reg_val |= 0x02;
1216 ++ if (__alps_command_mode_write_reg(psmouse, reg_val))
1217 ++ return -1;
1218 ++
1219 ++ return 0;
1220 ++}
1221 ++
1222 ++static int alps_hw_init_v4(struct psmouse *psmouse)
1223 ++{
1224 ++ struct alps_data *priv = psmouse->private;
1225 ++ struct ps2dev *ps2dev = &psmouse->ps2dev;
1226 ++ unsigned char param[4];
1227 ++
1228 ++ priv->nibble_commands = alps_v4_nibble_commands;
1229 ++ priv->addr_command = PSMOUSE_CMD_DISABLE;
1230 ++
1231 ++ if (alps_enter_command_mode(psmouse, NULL))
1232 ++ goto error;
1233 ++
1234 ++ if (alps_absolute_mode_v4(psmouse)) {
1235 ++ pr_err("alps.c: Failed to enter absolute mode\n");
1236 ++ goto error;
1237 ++ }
1238 ++
1239 ++ if (alps_command_mode_write_reg(psmouse, 0x0007, 0x8c))
1240 ++ goto error;
1241 ++
1242 ++ if (alps_command_mode_write_reg(psmouse, 0x0149, 0x03))
1243 ++ goto error;
1244 ++
1245 ++ if (alps_command_mode_write_reg(psmouse, 0x0160, 0x03))
1246 ++ goto error;
1247 ++
1248 ++ if (alps_command_mode_write_reg(psmouse, 0x017f, 0x15))
1249 ++ goto error;
1250 ++
1251 ++ if (alps_command_mode_write_reg(psmouse, 0x0151, 0x01))
1252 ++ goto error;
1253 ++
1254 ++ if (alps_command_mode_write_reg(psmouse, 0x0168, 0x03))
1255 ++ goto error;
1256 ++
1257 ++ if (alps_command_mode_write_reg(psmouse, 0x014a, 0x03))
1258 ++ goto error;
1259 ++
1260 ++ if (alps_command_mode_write_reg(psmouse, 0x0161, 0x03))
1261 ++ goto error;
1262 ++
1263 ++ alps_exit_command_mode(psmouse);
1264 ++
1265 ++ /*
1266 ++ * This sequence changes the output from a 9-byte to an
1267 ++ * 8-byte format. All the same data seems to be present,
1268 ++ * just in a more compact format.
1269 ++ */
1270 ++ param[0] = 0xc8;
1271 ++ param[1] = 0x64;
1272 ++ param[2] = 0x50;
1273 ++ if (ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE) ||
1274 ++ ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRATE) ||
1275 ++ ps2_command(ps2dev, &param[2], PSMOUSE_CMD_SETRATE) ||
1276 ++ ps2_command(ps2dev, param, PSMOUSE_CMD_GETID))
1277 ++ return -1;
1278 ++
1279 ++ /* Set rate and enable data reporting */
1280 ++ param[0] = 0x64;
1281 ++ if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE) ||
1282 ++ ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE)) {
1283 ++ pr_err("alps.c: Failed to enable data reporting\n");
1284 ++ return -1;
1285 ++ }
1286 ++
1287 ++ return 0;
1288 ++
1289 ++error:
1290 ++ /*
1291 ++ * Leaving the touchpad in command mode will essentially render
1292 ++ * it unusable until the machine reboots, so exit it here just
1293 ++ * to be safe
1294 ++ */
1295 ++ alps_exit_command_mode(psmouse);
1296 ++ return -1;
1297 ++}
1298 ++
1299 ++static int alps_hw_init(struct psmouse *psmouse)
1300 ++{
1301 ++ struct alps_data *priv = psmouse->private;
1302 ++ const struct alps_model_info *model = priv->i;
1303 ++ int ret = -1;
1304 ++
1305 ++ switch (model->proto_version) {
1306 ++ case ALPS_PROTO_V1:
1307 ++ case ALPS_PROTO_V2:
1308 ++ ret = alps_hw_init_v1_v2(psmouse);
1309 ++ break;
1310 ++ case ALPS_PROTO_V3:
1311 ++ ret = alps_hw_init_v3(psmouse);
1312 ++ break;
1313 ++ case ALPS_PROTO_V4:
1314 ++ ret = alps_hw_init_v4(psmouse);
1315 ++ break;
1316 ++ }
1317 ++
1318 ++ return ret;
1319 ++}
1320 ++
1321 + static int alps_reconnect(struct psmouse *psmouse)
1322 + {
1323 + const struct alps_model_info *model;
1324 +@@ -641,6 +1312,8 @@ int alps_init(struct psmouse *psmouse)
1325 +
1326 + psmouse->private = priv;
1327 +
1328 ++ psmouse_reset(psmouse);
1329 ++
1330 + model = alps_get_model(psmouse, &version);
1331 + if (!model)
1332 + goto init_fail;
1333 +@@ -668,8 +1341,20 @@ int alps_init(struct psmouse *psmouse)
1334 + BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
1335 +
1336 + dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS);
1337 +- input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0);
1338 +- input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
1339 ++
1340 ++ switch (model->proto_version) {
1341 ++ case ALPS_PROTO_V1:
1342 ++ case ALPS_PROTO_V2:
1343 ++ input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0);
1344 ++ input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
1345 ++ break;
1346 ++ case ALPS_PROTO_V3:
1347 ++ case ALPS_PROTO_V4:
1348 ++ input_set_abs_params(dev1, ABS_X, 0, 2000, 0, 0);
1349 ++ input_set_abs_params(dev1, ABS_Y, 0, 1400, 0, 0);
1350 ++ break;
1351 ++ }
1352 ++
1353 + input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
1354 +
1355 + if (model->flags & ALPS_WHEEL) {
1356 +@@ -712,7 +1397,7 @@ int alps_init(struct psmouse *psmouse)
1357 + psmouse->poll = alps_poll;
1358 + psmouse->disconnect = alps_disconnect;
1359 + psmouse->reconnect = alps_reconnect;
1360 +- psmouse->pktsize = 6;
1361 ++ psmouse->pktsize = model->proto_version == ALPS_PROTO_V4 ? 8 : 6;
1362 +
1363 + /* We are having trouble resyncing ALPS touchpads so disable it for now */
1364 + psmouse->resync_time = 0;
1365 +diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
1366 +index 4ce9bba..0d911cf 100644
1367 +--- a/drivers/input/mouse/alps.h
1368 ++++ b/drivers/input/mouse/alps.h
1369 +@@ -14,19 +14,30 @@
1370 +
1371 + #define ALPS_PROTO_V1 0
1372 + #define ALPS_PROTO_V2 1
1373 ++#define ALPS_PROTO_V3 2
1374 ++#define ALPS_PROTO_V4 3
1375 +
1376 + struct alps_model_info {
1377 + unsigned char signature[3];
1378 ++ unsigned char command_mode_resp; /* v3/v4 only */
1379 + unsigned char proto_version;
1380 + unsigned char byte0, mask0;
1381 + unsigned char flags;
1382 + };
1383 +
1384 ++struct alps_nibble_commands {
1385 ++ int command;
1386 ++ unsigned char data;
1387 ++};
1388 ++
1389 + struct alps_data {
1390 + struct input_dev *dev2; /* Relative device */
1391 + char phys[32]; /* Phys */
1392 + const struct alps_model_info *i;/* Info */
1393 ++ const struct alps_nibble_commands *nibble_commands;
1394 ++ int addr_command; /* Command to set register address */
1395 + int prev_fin; /* Finger bit from previous packet */
1396 ++ int multi_packet; /* Multi-packet data in progress */
1397 + struct timer_list timer;
1398 + };
1399 +
1400 +--
1401 +1.7.4.1
1402 +
1403
1404 Added: genpatches-2.6/trunk/3.0/2625_Input-ALPS-Add-documentation-for-protocol-versions-3.patch
1405 ===================================================================
1406 --- genpatches-2.6/trunk/3.0/2625_Input-ALPS-Add-documentation-for-protocol-versions-3.patch (rev 0)
1407 +++ genpatches-2.6/trunk/3.0/2625_Input-ALPS-Add-documentation-for-protocol-versions-3.patch 2011-09-28 14:30:19 UTC (rev 1982)
1408 @@ -0,0 +1,205 @@
1409 +From 986ad99c2ea79ba04d6f2f739513e721643ec78e Mon Sep 17 00:00:00 2001
1410 +From: Seth Forshee <seth.forshee@×××××××××.com>
1411 +Date: Wed, 14 Sep 2011 11:40:38 -0500
1412 +Subject: [PATCH 6/8] Input: ALPS - Add documentation for protocol versions 3 and 4
1413 +
1414 +Also converts from using "old" and "new" to describe the already-known
1415 +protocols to using "version 1" and "version 2."
1416 +---
1417 + Documentation/input/alps.txt | 134 ++++++++++++++++++++++++++++++++++++++---
1418 + drivers/input/mouse/alps.c | 9 +++
1419 + 2 files changed, 133 insertions(+), 10 deletions(-)
1420 +
1421 +diff --git a/Documentation/input/alps.txt b/Documentation/input/alps.txt
1422 +index e88c921..2768ad1 100644
1423 +--- a/Documentation/input/alps.txt
1424 ++++ b/Documentation/input/alps.txt
1425 +@@ -4,12 +4,9 @@ ALPS Touchpad Protocol
1426 + Introduction
1427 + ------------
1428 +
1429 +-Currently the ALPS touchpad driver supports two protocol versions in use by
1430 +-ALPS touchpads, the "old" and "new" protocol versions. Fundamentally these
1431 +-differ only in the format of their event packets (in reality many features may
1432 +-be found on new protocol devices that aren't found on the old protocol
1433 +-devices, but these are handled transparently as feature differences rather
1434 +-than protocol differences).
1435 ++Currently the ALPS touchpad driver supports four protocol versions in use by
1436 ++ALPS touchpads, called versions 1, 2, 3, and 4. Information about the various
1437 ++protocol versions is contained in the following sections.
1438 +
1439 + Detection
1440 + ---------
1441 +@@ -22,6 +19,34 @@ If the E6 report is successful, the touchpad model is identified using the "E7
1442 + report" sequence: E8-E7-E7-E7-E9. The response is the model signature and is
1443 + matched against known models in the alps_model_data_array.
1444 +
1445 ++With protocol versions 3 and 4, the E7 report model signature is always
1446 ++73-02-64. To differentiate between these versions, the response from the
1447 ++"Enter Command Mode" sequence must be inspected as described below.
1448 ++
1449 ++Command Mode
1450 ++------------
1451 ++
1452 ++Protocol versions 3 and 4 have a command mode that is used to read and write
1453 ++one-byte device registers in a 16-bit address space. The command sequence
1454 ++EC-EC-EC-E9 places the device in command mode, and the device will respond
1455 ++with 88-07 followed by a third byte. This third byte can be used to determine
1456 ++whether the devices uses the version
1457 ++3 or 4 protocol.
1458 ++
1459 ++To exit command mode, PSMOUSE_CMD_SETSTREAM (EA) is sent to the touchpad.
1460 ++
1461 ++While in command mode, register addresses can be set by first sending a
1462 ++specific command, either EC for v3 devices or F5 for E4 devices. Then the
1463 ++address is sent one nibble at a time, where each nibble is encoded as a
1464 ++command with optional data. This enoding differs slightly between the v3 and
1465 ++v4 protocols.
1466 ++
1467 ++Once an address has been set, the addressed register can be read by sending
1468 ++PSMOUSE_CMD_GETINFO (E9). The first two bytes of the response contains the
1469 ++address of the register being read, and the third contains the value of the
1470 ++register. Registers are written by writing the value one nibble at a time
1471 ++using the same encoding used for addresses.
1472 ++
1473 + Packet Format
1474 + -------------
1475 +
1476 +@@ -41,8 +66,8 @@ PS/2 packet format
1477 +
1478 + Note that the device never signals overflow condition.
1479 +
1480 +-ALPS Absolute Mode - Old Format
1481 +--------------------------------
1482 ++ALPS Absolute Mode - Protocol Verion 1
1483 ++--------------------------------------
1484 +
1485 + byte 0: 1 0 0 0 1 x9 x8 x7
1486 + byte 1: 0 x6 x5 x4 x3 x2 x1 x0
1487 +@@ -51,8 +76,8 @@ ALPS Absolute Mode - Old Format
1488 + byte 4: 0 y6 y5 y4 y3 y2 y1 y0
1489 + byte 5: 0 z6 z5 z4 z3 z2 z1 z0
1490 +
1491 +-ALPS Absolute Mode - New Format
1492 +--------------------------------
1493 ++ALPS Absolute Mode - Protocol Version 2
1494 ++---------------------------------------
1495 +
1496 + byte 0: 1 ? ? ? 1 ? ? ?
1497 + byte 1: 0 x6 x5 x4 x3 x2 x1 x0
1498 +@@ -73,3 +98,92 @@ Dualpoint device -- interleaved packet format
1499 + byte 6: 0 y9 y8 y7 1 m r l
1500 + byte 7: 0 y6 y5 y4 y3 y2 y1 y0
1501 + byte 8: 0 z6 z5 z4 z3 z2 z1 z0
1502 ++
1503 ++ALPS Absolute Mode - Protocol Version 3
1504 ++---------------------------------------
1505 ++
1506 ++ALPS protocol version 3 has three different packet formats. The first two are
1507 ++associated with touchpad events, and the third is associatd with trackstick
1508 ++events.
1509 ++
1510 ++The first type is the touchpad position packet.
1511 ++
1512 ++ byte 0: 1 ? x1 x0 1 1 1 1
1513 ++ byte 1: 0 x10 x9 x8 x7 x6 x5 x4
1514 ++ byte 2: 0 y10 y9 y8 y7 y6 y5 y4
1515 ++ byte 3: 0 M R L 1 m r l
1516 ++ byte 4: 0 mt x3 x2 y3 y2 y1 y0
1517 ++ byte 5: 0 z6 z5 z4 z3 z2 z1 z0
1518 ++
1519 ++Note that for some devices the trackstick buttons are reported in this packet,
1520 ++and on others it is reported in the trackstick packets.
1521 ++
1522 ++The second packet type contains bitmaps representing the x and y axes. In the
1523 ++bitmaps a given bit is set if there is a finger covering that position on the
1524 ++given axis. Thus the bitmap packet can be used for low-resolution multi-touch
1525 ++data, although finger tracking is not possible. This packet also encodes the
1526 ++number of contacts (f1 and f0 in the table below).
1527 ++
1528 ++ byte 0: 1 1 x1 x0 1 1 1 1
1529 ++ byte 1: 0 x8 x7 x6 x5 x4 x3 x2
1530 ++ byte 2: 0 y7 y6 y5 y4 y3 y2 y1
1531 ++ byte 3: 0 y10 y9 y8 1 1 1 1
1532 ++ byte 4: 0 x14 x13 x12 x11 x10 x9 y0
1533 ++ byte 5: 0 1 ? ? ? ? f1 f0
1534 ++
1535 ++This packet only appears after a position packet with the mt bit set, and
1536 ++ususally only appears when there are two or more contacts (although
1537 ++ocassionally it's seen with only a single contact).
1538 ++
1539 ++The final v3 packet type is the trackstick packet.
1540 ++
1541 ++ byte 0: 1 1 x7 y7 1 1 1 1
1542 ++ byte 1: 0 x6 x5 x4 x3 x2 x1 x0
1543 ++ byte 2: 0 y6 y5 y4 y3 y2 y1 y0
1544 ++ byte 3: 0 1 0 0 1 0 0 0
1545 ++ byte 4: 0 z4 z3 z2 z1 z0 ? ?
1546 ++ byte 5: 0 0 1 1 1 1 1 1
1547 ++
1548 ++ALPS Absolute Mode - Protocol Version 4
1549 ++---------------------------------------
1550 ++
1551 ++Protocol version 4 has a 9-byte packet format.
1552 ++
1553 ++ byte 0: 1 ? x1 x0 1 1 1 1
1554 ++ byte 1: 0 x10 x9 x8 x7 x6 x5 x4
1555 ++ byte 2: 0 y10 y9 y8 y7 y6 y5 y4
1556 ++ byte 3: 0 1 x3 x2 y3 y2 y1 y0
1557 ++ byte 4: 0 ? ? ? 1 ? r l
1558 ++ byte 5: 0 z6 z5 z4 z3 z2 z1 z0
1559 ++ byte 6: bitmap data (described below)
1560 ++ byte 7: bitmap data (described below)
1561 ++
1562 ++The last two bytes represent a partial bitmap packet, with 3 full packets
1563 ++required to construct a complete bitmap packet. Once assembled, the 6-byte
1564 ++bitmap packet has the following format:
1565 ++
1566 ++ byte 0: 0 1 x7 x6 x5 x4 x3 x2
1567 ++ byte 1: 0 x1 x0 y4 y3 y2 y1 y0
1568 ++ byte 2: 0 ? ? x14 x13 x12 x11 x10
1569 ++ byte 3: 0 x9 x8 y9 y8 y7 y6 y5
1570 ++ byte 4: 0 0 0 0 0 0 0 0
1571 ++ byte 5: 0 0 0 0 0 0 0 y10
1572 ++
1573 ++There are several things worth noting here.
1574 ++
1575 ++ 1) In the bitmap data, bit 6 of byte 0 serves as a sync byte to
1576 ++ identify the first fragment of a bitmap packet.
1577 ++
1578 ++ 2) The bitmaps represent the same data as in the v3 bitmap packets, although
1579 ++ the packet layout is different.
1580 ++
1581 ++ 3) There doesn't seem to be a count of the contact points anywhere in the v4
1582 ++ protocol packets. Deriving a count of contact points must be done by
1583 ++ analyzing the bitmaps.
1584 ++
1585 ++ 4) There is a 3 to 1 ratio of position packets to bitmap packets. Therefore
1586 ++ MT position can only be updated for every third ST position update, and
1587 ++ the count of contact points can only be updated every third packet as
1588 ++ well.
1589 ++
1590 ++So far no v4 devices with tracksticks have been encountered.
1591 +diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
1592 +index 2615b92..165c7a0 100644
1593 +--- a/drivers/input/mouse/alps.c
1594 ++++ b/drivers/input/mouse/alps.c
1595 +@@ -358,6 +358,15 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
1596 + y = ((packet[2] & 0x7f) << 4) | (packet[4] & 0x0f);
1597 + z = packet[5] & 0x7f;
1598 +
1599 ++ /*
1600 ++ * Sometimes the hardware sends a single packet with z = 0
1601 ++ * in the middle of a stream. Real releases generate a good
1602 ++ * number of packets with x, y, and z all zero, so these seem
1603 ++ * to be flukes. Ignore them.
1604 ++ */
1605 ++ if (x && y && !z)
1606 ++ return;
1607 ++
1608 + if (z >= 64) {
1609 + input_report_key(dev, BTN_TOUCH, 1);
1610 + } else {
1611 +--
1612 +1.7.4.1
1613 +
1614
1615 Added: genpatches-2.6/trunk/3.0/2630_Input-ALPS-Add-semi-MT-support-for-v3-protocol.patch
1616 ===================================================================
1617 --- genpatches-2.6/trunk/3.0/2630_Input-ALPS-Add-semi-MT-support-for-v3-protocol.patch (rev 0)
1618 +++ genpatches-2.6/trunk/3.0/2630_Input-ALPS-Add-semi-MT-support-for-v3-protocol.patch 2011-09-28 14:30:19 UTC (rev 1982)
1619 @@ -0,0 +1,318 @@
1620 +From aca6e9b053bbd08d26fbabe226a9df876460b97c Mon Sep 17 00:00:00 2001
1621 +From: Seth Forshee <seth.forshee@×××××××××.com>
1622 +Date: Thu, 15 Sep 2011 16:50:09 -0500
1623 +Subject: [PATCH 7/8] Input: ALPS - Add semi-MT support for v3 protocol
1624 +
1625 +---
1626 + drivers/input/mouse/alps.c | 214 ++++++++++++++++++++++++++++++++++++++++---
1627 + drivers/input/mouse/alps.h | 1 +
1628 + 2 files changed, 200 insertions(+), 15 deletions(-)
1629 +
1630 +diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
1631 +index 165c7a0..ce06b08 100644
1632 +--- a/drivers/input/mouse/alps.c
1633 ++++ b/drivers/input/mouse/alps.c
1634 +@@ -17,6 +17,7 @@
1635 +
1636 + #include <linux/slab.h>
1637 + #include <linux/input.h>
1638 ++#include <linux/input/mt.h>
1639 + #include <linux/serio.h>
1640 + #include <linux/libps2.h>
1641 +
1642 +@@ -33,6 +34,12 @@
1643 + /*
1644 + * Definitions for ALPS version 3 and 4 command mode protocol
1645 + */
1646 ++#define ALPS_V3_X_MAX 2000
1647 ++#define ALPS_V3_Y_MAX 1400
1648 ++
1649 ++#define ALPS_BITMAP_X_BITS 15
1650 ++#define ALPS_BITMAP_Y_BITS 11
1651 ++
1652 + #define ALPS_CMD_NIBBLE_10 0x01f2
1653 +
1654 + static const struct alps_nibble_commands alps_v3_nibble_commands[] = {
1655 +@@ -257,6 +264,137 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse)
1656 + input_sync(dev);
1657 + }
1658 +
1659 ++/*
1660 ++ * Process bitmap data from v3 and v4 protocols. Returns the number of
1661 ++ * fingers detected. A return value of 0 means at least one of the
1662 ++ * bitmaps was empty.
1663 ++ *
1664 ++ * The bitmaps don't have enough data to track fingers, so this function
1665 ++ * only generates points representing a bounding box of all contacts.
1666 ++ * These points are returned in x1, y1, x2, and y2 when the return value
1667 ++ * is greater than 0.
1668 ++ */
1669 ++static int alps_process_bitmap(unsigned int x_map, unsigned int y_map,
1670 ++ int *x1, int *y1, int *x2, int *y2)
1671 ++{
1672 ++ struct alps_bitmap_point {
1673 ++ int start_bit;
1674 ++ int num_bits;
1675 ++ };
1676 ++
1677 ++ int fingers_x = 0, fingers_y = 0, fingers;
1678 ++ int i, bit, prev_bit;
1679 ++ struct alps_bitmap_point x_low = {0,}, x_high = {0,};
1680 ++ struct alps_bitmap_point y_low = {0,}, y_high = {0,};
1681 ++ struct alps_bitmap_point *point;
1682 ++
1683 ++ if (!x_map || !y_map)
1684 ++ return 0;
1685 ++
1686 ++ *x1 = *y1 = *x2 = *y2 = 0;
1687 ++
1688 ++ prev_bit = 0;
1689 ++ point = &x_low;
1690 ++ for (i = 0; x_map != 0; i++, x_map >>= 1) {
1691 ++ bit = x_map & 1;
1692 ++ if (bit) {
1693 ++ if (!prev_bit) {
1694 ++ point->start_bit = i;
1695 ++ fingers_x++;
1696 ++ }
1697 ++ point->num_bits++;
1698 ++ } else {
1699 ++ if (prev_bit)
1700 ++ point = &x_high;
1701 ++ else
1702 ++ point->num_bits = 0;
1703 ++ }
1704 ++ prev_bit = bit;
1705 ++ }
1706 ++
1707 ++ /*
1708 ++ * y bitmap is reversed for what we need (lower positions are in
1709 ++ * higher bits), so we process from the top end.
1710 ++ */
1711 ++ y_map = y_map << (sizeof(y_map) * BITS_PER_BYTE - ALPS_BITMAP_Y_BITS);
1712 ++ prev_bit = 0;
1713 ++ point = &y_low;
1714 ++ for (i = 0; y_map != 0; i++, y_map <<= 1) {
1715 ++ bit = y_map & (1 << (sizeof(y_map) * BITS_PER_BYTE - 1));
1716 ++ if (bit) {
1717 ++ if (!prev_bit) {
1718 ++ point->start_bit = i;
1719 ++ fingers_y++;
1720 ++ }
1721 ++ point->num_bits++;
1722 ++ } else {
1723 ++ if (prev_bit)
1724 ++ point = &y_high;
1725 ++ else
1726 ++ point->num_bits = 0;
1727 ++ }
1728 ++ prev_bit = bit;
1729 ++ }
1730 ++
1731 ++ /*
1732 ++ * Fingers can overlap, so we use the maximum count of fingers
1733 ++ * on either axis as the finger count.
1734 ++ */
1735 ++ fingers = max(fingers_x, fingers_y);
1736 ++
1737 ++ /*
1738 ++ * If total fingers is > 1 but either axis reports only a single
1739 ++ * contact, we have overlapping or adjacent fingers. For the
1740 ++ * purposes of creating a bounding box, divide the single contact
1741 ++ * (roughly) equally between the two points.
1742 ++ */
1743 ++ if (fingers > 1) {
1744 ++ if (fingers_x == 1) {
1745 ++ i = x_low.num_bits / 2;
1746 ++ x_low.num_bits = x_low.num_bits - i;
1747 ++ x_high.start_bit = x_low.start_bit + i;
1748 ++ x_high.num_bits = max(i, 1);
1749 ++ } else if (fingers_y == 1) {
1750 ++ i = y_low.num_bits / 2;
1751 ++ y_low.num_bits = y_low.num_bits - i;
1752 ++ y_high.start_bit = y_low.start_bit + i;
1753 ++ y_high.num_bits = max(i, 1);
1754 ++ }
1755 ++ }
1756 ++
1757 ++ *x1 = (ALPS_V3_X_MAX * (2 * x_low.start_bit + x_low.num_bits - 1)) /
1758 ++ (2 * (ALPS_BITMAP_X_BITS - 1));
1759 ++ *y1 = (ALPS_V3_Y_MAX * (2 * y_low.start_bit + y_low.num_bits - 1)) /
1760 ++ (2 * (ALPS_BITMAP_Y_BITS - 1));
1761 ++
1762 ++ if (fingers > 1) {
1763 ++ *x2 = (ALPS_V3_X_MAX * (2 * x_high.start_bit + x_high.num_bits - 1)) /
1764 ++ (2 * (ALPS_BITMAP_X_BITS - 1));
1765 ++ *y2 = (ALPS_V3_Y_MAX * (2 * y_high.start_bit + y_high.num_bits - 1)) /
1766 ++ (2 * (ALPS_BITMAP_Y_BITS - 1));
1767 ++ }
1768 ++
1769 ++ return fingers;
1770 ++}
1771 ++
1772 ++static void alps_set_slot(struct input_dev *dev, int slot, bool active,
1773 ++ int x, int y)
1774 ++{
1775 ++ input_mt_slot(dev, slot);
1776 ++ input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
1777 ++ if (active) {
1778 ++ input_report_abs(dev, ABS_MT_POSITION_X, x);
1779 ++ input_report_abs(dev, ABS_MT_POSITION_Y, y);
1780 ++ }
1781 ++}
1782 ++
1783 ++static void alps_report_semi_mt_data(struct input_dev *dev, int num_fingers,
1784 ++ int x1, int y1, int x2, int y2)
1785 ++{
1786 ++ alps_set_slot(dev, 0, num_fingers != 0, x1, y1);
1787 ++ alps_set_slot(dev, 1, num_fingers == 2, x2, y2);
1788 ++}
1789 ++
1790 + static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
1791 + {
1792 + struct alps_data *priv = psmouse->private;
1793 +@@ -311,6 +449,9 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
1794 + struct input_dev *dev = psmouse->dev;
1795 + int x, y, z;
1796 + int left, right, middle;
1797 ++ int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
1798 ++ int fingers = 0, bmap_fingers;
1799 ++ unsigned int x_bitmap, y_bitmap;
1800 +
1801 + /*
1802 + * There's no single feature of touchpad position and bitmap
1803 +@@ -319,8 +460,6 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
1804 + * a position packet with bit 6 of packet[4] set.
1805 + */
1806 + if (priv->multi_packet) {
1807 +- priv->multi_packet = 0;
1808 +-
1809 + /*
1810 + * Sometimes a position packet will indicate a multi-packet
1811 + * sequence, but then what follows is another position
1812 +@@ -328,18 +467,38 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
1813 + * position packet as usual.
1814 + */
1815 + if (packet[0] & 0x40) {
1816 ++ fingers = (packet[5] & 0x3) + 1;
1817 ++ x_bitmap = ((packet[4] & 0x7e) << 8) |
1818 ++ ((packet[1] & 0x7f) << 2) |
1819 ++ ((packet[0] & 0x30) >> 4);
1820 ++ y_bitmap = ((packet[3] & 0x70) << 4) |
1821 ++ ((packet[2] & 0x7f) << 1) |
1822 ++ (packet[4] & 0x01);
1823 ++
1824 ++ bmap_fingers = alps_process_bitmap(x_bitmap, y_bitmap,
1825 ++ &x1, &y1, &x2, &y2);
1826 ++
1827 + /*
1828 +- * Bitmap packets are not yet supported, so for now
1829 +- * just ignore them.
1830 ++ * We shouldn't report more than one finger if
1831 ++ * we don't have two coordinates.
1832 + */
1833 +- return;
1834 ++ if (fingers > 1 && bmap_fingers < 2)
1835 ++ fingers = bmap_fingers;
1836 ++
1837 ++ /* Now process position packet */
1838 ++ packet = priv->multi_data;
1839 ++ } else {
1840 ++ priv->multi_packet = 0;
1841 + }
1842 + }
1843 +
1844 +- if (!priv->multi_packet && (packet[4] & 0x40))
1845 ++ if (!priv->multi_packet && packet[4] & 0x40) {
1846 + priv->multi_packet = 1;
1847 +- else
1848 +- priv->multi_packet = 0;
1849 ++ memcpy(priv->multi_data, packet, sizeof(priv->multi_data));
1850 ++ return;
1851 ++ }
1852 ++
1853 ++ priv->multi_packet = 0;
1854 +
1855 + /*
1856 + * Bits in the upper nibble of byte 3 represent the trackstick
1857 +@@ -367,23 +526,39 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
1858 + if (x && y && !z)
1859 + return;
1860 +
1861 ++ /*
1862 ++ * If we don't have MT data or the bitmaps were empty, we have
1863 ++ * to rely on ST data.
1864 ++ */
1865 ++ if (!fingers) {
1866 ++ x1 = x;
1867 ++ y1 = y;
1868 ++ fingers = z > 0 ? 1 : 0;
1869 ++ }
1870 ++
1871 + if (z >= 64) {
1872 + input_report_key(dev, BTN_TOUCH, 1);
1873 + } else {
1874 + input_report_key(dev, BTN_TOUCH, 0);
1875 + }
1876 +
1877 ++ alps_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
1878 ++
1879 ++ input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
1880 ++ input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
1881 ++ input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
1882 ++ input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4);
1883 ++
1884 ++ input_report_key(dev, BTN_LEFT, left);
1885 ++ input_report_key(dev, BTN_RIGHT, right);
1886 ++ input_report_key(dev, BTN_MIDDLE, middle);
1887 ++
1888 + if (z > 0) {
1889 + input_report_abs(dev, ABS_X, x);
1890 + input_report_abs(dev, ABS_Y, y);
1891 + }
1892 + input_report_abs(dev, ABS_PRESSURE, z);
1893 +
1894 +- input_report_key(dev, BTN_TOOL_FINGER, z > 0);
1895 +- input_report_key(dev, BTN_LEFT, left);
1896 +- input_report_key(dev, BTN_RIGHT, right);
1897 +- input_report_key(dev, BTN_MIDDLE, middle);
1898 +-
1899 + input_sync(dev);
1900 + }
1901 +
1902 +@@ -1358,9 +1533,18 @@ int alps_init(struct psmouse *psmouse)
1903 + input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
1904 + break;
1905 + case ALPS_PROTO_V3:
1906 ++ set_bit(INPUT_PROP_SEMI_MT, dev1->propbit);
1907 ++ input_mt_init_slots(dev1, 2);
1908 ++ input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, ALPS_V3_X_MAX, 0, 0);
1909 ++ input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, ALPS_V3_Y_MAX, 0, 0);
1910 ++
1911 ++ set_bit(BTN_TOOL_DOUBLETAP, dev1->keybit);
1912 ++ set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit);
1913 ++ set_bit(BTN_TOOL_QUADTAP, dev1->keybit);
1914 ++ /* fall through */
1915 + case ALPS_PROTO_V4:
1916 +- input_set_abs_params(dev1, ABS_X, 0, 2000, 0, 0);
1917 +- input_set_abs_params(dev1, ABS_Y, 0, 1400, 0, 0);
1918 ++ input_set_abs_params(dev1, ABS_X, 0, ALPS_V3_X_MAX, 0, 0);
1919 ++ input_set_abs_params(dev1, ABS_Y, 0, ALPS_V3_Y_MAX, 0, 0);
1920 + break;
1921 + }
1922 +
1923 +diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
1924 +index 0d911cf..e73995b 100644
1925 +--- a/drivers/input/mouse/alps.h
1926 ++++ b/drivers/input/mouse/alps.h
1927 +@@ -38,6 +38,7 @@ struct alps_data {
1928 + int addr_command; /* Command to set register address */
1929 + int prev_fin; /* Finger bit from previous packet */
1930 + int multi_packet; /* Multi-packet data in progress */
1931 ++ unsigned char multi_data[6]; /* Saved multi-packet data */
1932 + struct timer_list timer;
1933 + };
1934 +
1935 +--
1936 +1.7.4.1
1937 +
1938
1939 Added: genpatches-2.6/trunk/3.0/2635_Input-ALPS-dump-raw-packet-data.patch
1940 ===================================================================
1941 --- genpatches-2.6/trunk/3.0/2635_Input-ALPS-dump-raw-packet-data.patch (rev 0)
1942 +++ genpatches-2.6/trunk/3.0/2635_Input-ALPS-dump-raw-packet-data.patch 2011-09-28 14:30:19 UTC (rev 1982)
1943 @@ -0,0 +1,125 @@
1944 +From a4eab730f720a2a89be05aef40e35a08a8d85a37 Mon Sep 17 00:00:00 2001
1945 +From: Seth Forshee <seth.forshee@×××××××××.com>
1946 +Date: Wed, 14 Sep 2011 11:40:39 -0500
1947 +Subject: [PATCH 8/8] Input: ALPS - dump raw packet data
1948 +
1949 +---
1950 + drivers/input/mouse/alps.c | 51 ++++++++++++++++++++++++++-----------------
1951 + 1 files changed, 31 insertions(+), 20 deletions(-)
1952 +
1953 +diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
1954 +index ce06b08..90f45ed 100644
1955 +--- a/drivers/input/mouse/alps.c
1956 ++++ b/drivers/input/mouse/alps.c
1957 +@@ -129,6 +129,19 @@ static const struct alps_model_info alps_model_data[] = {
1958 +
1959 + /* Packet formats are described in Documentation/input/alps.txt */
1960 +
1961 ++static int alps_dump_packets = 0;
1962 ++module_param(alps_dump_packets, int, 0644);
1963 ++
1964 ++static void alps_packet_dump(unsigned char *packet, int size)
1965 ++{
1966 ++ int i;
1967 ++
1968 ++ printk("ALPS data ");
1969 ++ for (i = 0; i < size; i++)
1970 ++ printk("%02hhx ", packet[i]);
1971 ++ printk("\n");
1972 ++}
1973 ++
1974 + static bool alps_is_valid_first_byte(const struct alps_model_info *model,
1975 + unsigned char data)
1976 + {
1977 +@@ -400,7 +413,7 @@ static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
1978 + struct alps_data *priv = psmouse->private;
1979 + unsigned char *packet = psmouse->packet;
1980 + struct input_dev *dev = priv->dev2;
1981 +- int x, y, z, left, right, middle;
1982 ++ int x, y, z;
1983 +
1984 + /* Sanity check packet */
1985 + if (!(packet[0] & 0x40)) {
1986 +@@ -419,10 +432,6 @@ static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
1987 + y = (s8)(((packet[0] & 0x10) << 3) | (packet[2] & 0x7f));
1988 + z = (packet[4] & 0x7c) >> 2;
1989 +
1990 +- left = packet[3] & 0x01;
1991 +- right = packet[3] & 0x02;
1992 +- middle = packet[3] & 0x04;
1993 +-
1994 + /*
1995 + * The x and y values tend to be quite large, and when used
1996 + * alone the trackstick is difficult to use. Scale them down
1997 +@@ -434,10 +443,6 @@ static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
1998 + input_report_rel(dev, REL_X, x);
1999 + input_report_rel(dev, REL_Y, -y);
2000 +
2001 +- input_report_key(dev, BTN_LEFT, left);
2002 +- input_report_key(dev, BTN_RIGHT, right);
2003 +- input_report_key(dev, BTN_MIDDLE, middle);
2004 +-
2005 + input_sync(dev);
2006 + return;
2007 + }
2008 +@@ -447,8 +452,10 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
2009 + struct alps_data *priv = psmouse->private;
2010 + unsigned char *packet = psmouse->packet;
2011 + struct input_dev *dev = psmouse->dev;
2012 ++ struct input_dev *dev2 = priv->dev2;
2013 + int x, y, z;
2014 + int left, right, middle;
2015 ++ int stick_left, stick_right, stick_middle;
2016 + int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
2017 + int fingers = 0, bmap_fingers;
2018 + unsigned int x_bitmap, y_bitmap;
2019 +@@ -500,17 +507,13 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
2020 +
2021 + priv->multi_packet = 0;
2022 +
2023 +- /*
2024 +- * Bits in the upper nibble of byte 3 represent the trackstick
2025 +- * buttons on some models, but on other models the trackstick
2026 +- * buttons are reported in the trackstic packets. If we try to
2027 +- * report the buttons on the trackstick device from here it can
2028 +- * lead to conflicts, so we treat any buttons reported in the
2029 +- * touchpad packets as belonging to the touchpad.
2030 +- */
2031 +- left = packet[3] & 0x11;
2032 +- right = packet[3] & 0x22;
2033 +- middle = packet[3] & 0x44;
2034 ++ left = packet[3] & 0x01;
2035 ++ right = packet[3] & 0x02;
2036 ++ middle = packet[3] & 0x04;
2037 ++
2038 ++ stick_left = packet[3] & 0x10;
2039 ++ stick_right = packet[3] & 0x20;
2040 ++ stick_middle = packet[3] & 0x40;
2041 +
2042 + x = ((packet[1] & 0x7f) << 4) | ((packet[4] & 0x30) >> 2) |
2043 + ((packet[0] & 0x30) >> 4);
2044 +@@ -560,6 +563,11 @@ static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
2045 + input_report_abs(dev, ABS_PRESSURE, z);
2046 +
2047 + input_sync(dev);
2048 ++
2049 ++ input_report_key(dev2, BTN_LEFT, stick_left);
2050 ++ input_report_key(dev2, BTN_RIGHT, stick_right);
2051 ++ input_report_key(dev2, BTN_MIDDLE, stick_middle);
2052 ++ input_sync(dev2);
2053 + }
2054 +
2055 + static void alps_process_packet_v3(struct psmouse *psmouse)
2056 +@@ -621,6 +629,9 @@ static void alps_process_packet(struct psmouse *psmouse)
2057 + struct alps_data *priv = psmouse->private;
2058 + const struct alps_model_info *model = priv->i;
2059 +
2060 ++ if (alps_dump_packets)
2061 ++ alps_packet_dump(psmouse->packet, psmouse->pktcnt);
2062 ++
2063 + switch (model->proto_version) {
2064 + case ALPS_PROTO_V1:
2065 + case ALPS_PROTO_V2:
2066 +--
2067 +1.7.4.1
2068 +