1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/slab.h>
19#include <linux/input.h>
20#include <linux/input/mt.h>
21#include <linux/serio.h>
22#include <linux/libps2.h>
23
24#include "psmouse.h"
25#include "alps.h"
26
27
28
29
30#define ALPS_CMD_NIBBLE_10 0x01f2
31
32#define ALPS_REG_BASE_RUSHMORE 0xc2c0
33#define ALPS_REG_BASE_PINNACLE 0x0000
34
35static const struct alps_nibble_commands alps_v3_nibble_commands[] = {
36 { PSMOUSE_CMD_SETPOLL, 0x00 },
37 { PSMOUSE_CMD_RESET_DIS, 0x00 },
38 { PSMOUSE_CMD_SETSCALE21, 0x00 },
39 { PSMOUSE_CMD_SETRATE, 0x0a },
40 { PSMOUSE_CMD_SETRATE, 0x14 },
41 { PSMOUSE_CMD_SETRATE, 0x28 },
42 { PSMOUSE_CMD_SETRATE, 0x3c },
43 { PSMOUSE_CMD_SETRATE, 0x50 },
44 { PSMOUSE_CMD_SETRATE, 0x64 },
45 { PSMOUSE_CMD_SETRATE, 0xc8 },
46 { ALPS_CMD_NIBBLE_10, 0x00 },
47 { PSMOUSE_CMD_SETRES, 0x00 },
48 { PSMOUSE_CMD_SETRES, 0x01 },
49 { PSMOUSE_CMD_SETRES, 0x02 },
50 { PSMOUSE_CMD_SETRES, 0x03 },
51 { PSMOUSE_CMD_SETSCALE11, 0x00 },
52};
53
54static const struct alps_nibble_commands alps_v4_nibble_commands[] = {
55 { PSMOUSE_CMD_ENABLE, 0x00 },
56 { PSMOUSE_CMD_RESET_DIS, 0x00 },
57 { PSMOUSE_CMD_SETSCALE21, 0x00 },
58 { PSMOUSE_CMD_SETRATE, 0x0a },
59 { PSMOUSE_CMD_SETRATE, 0x14 },
60 { PSMOUSE_CMD_SETRATE, 0x28 },
61 { PSMOUSE_CMD_SETRATE, 0x3c },
62 { PSMOUSE_CMD_SETRATE, 0x50 },
63 { PSMOUSE_CMD_SETRATE, 0x64 },
64 { PSMOUSE_CMD_SETRATE, 0xc8 },
65 { ALPS_CMD_NIBBLE_10, 0x00 },
66 { PSMOUSE_CMD_SETRES, 0x00 },
67 { PSMOUSE_CMD_SETRES, 0x01 },
68 { PSMOUSE_CMD_SETRES, 0x02 },
69 { PSMOUSE_CMD_SETRES, 0x03 },
70 { PSMOUSE_CMD_SETSCALE11, 0x00 },
71};
72
73static const struct alps_nibble_commands alps_v6_nibble_commands[] = {
74 { PSMOUSE_CMD_ENABLE, 0x00 },
75 { PSMOUSE_CMD_SETRATE, 0x0a },
76 { PSMOUSE_CMD_SETRATE, 0x14 },
77 { PSMOUSE_CMD_SETRATE, 0x28 },
78 { PSMOUSE_CMD_SETRATE, 0x3c },
79 { PSMOUSE_CMD_SETRATE, 0x50 },
80 { PSMOUSE_CMD_SETRATE, 0x64 },
81 { PSMOUSE_CMD_SETRATE, 0xc8 },
82 { PSMOUSE_CMD_GETID, 0x00 },
83 { PSMOUSE_CMD_GETINFO, 0x00 },
84 { PSMOUSE_CMD_SETRES, 0x00 },
85 { PSMOUSE_CMD_SETRES, 0x01 },
86 { PSMOUSE_CMD_SETRES, 0x02 },
87 { PSMOUSE_CMD_SETRES, 0x03 },
88 { PSMOUSE_CMD_SETSCALE21, 0x00 },
89 { PSMOUSE_CMD_SETSCALE11, 0x00 },
90};
91
92
93#define ALPS_DUALPOINT 0x02
94#define ALPS_PASS 0x04
95
96#define ALPS_WHEEL 0x08
97#define ALPS_FW_BK_1 0x10
98#define ALPS_FW_BK_2 0x20
99#define ALPS_FOUR_BUTTONS 0x40
100#define ALPS_PS2_INTERLEAVED 0x80
101
102#define ALPS_IS_RUSHMORE 0x100
103#define ALPS_BUTTONPAD 0x200
104
105static const struct alps_model_info alps_model_data[] = {
106 { { 0x32, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
107 { { 0x33, 0x02, 0x0a }, 0x00, ALPS_PROTO_V1, 0x88, 0xf8, 0 },
108 { { 0x53, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
109 { { 0x53, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
110 { { 0x60, 0x03, 0xc8 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
111 { { 0x63, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
112 { { 0x63, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
113 { { 0x63, 0x02, 0x28 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 },
114 { { 0x63, 0x02, 0x3c }, 0x00, ALPS_PROTO_V2, 0x8f, 0x8f, ALPS_WHEEL },
115 { { 0x63, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xef, 0xef, ALPS_FW_BK_1 },
116 { { 0x63, 0x02, 0x64 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
117 { { 0x63, 0x03, 0xc8 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
118 { { 0x73, 0x00, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_DUALPOINT },
119 { { 0x73, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, 0 },
120 { { 0x73, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_FW_BK_2 },
121 { { 0x20, 0x02, 0x0e }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
122 { { 0x22, 0x02, 0x0a }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
123 { { 0x22, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT },
124
125 { { 0x62, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf,
126 ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
127 { { 0x73, 0x00, 0x14 }, 0x00, ALPS_PROTO_V6, 0xff, 0xff, ALPS_DUALPOINT },
128 { { 0x73, 0x02, 0x50 }, 0x00, ALPS_PROTO_V2, 0xcf, 0xcf, ALPS_FOUR_BUTTONS },
129 { { 0x52, 0x01, 0x14 }, 0x00, ALPS_PROTO_V2, 0xff, 0xff,
130 ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
131 { { 0x73, 0x02, 0x64 }, 0x8a, ALPS_PROTO_V4, 0x8f, 0x8f, 0 },
132};
133
134static void alps_set_abs_params_st(struct alps_data *priv,
135 struct input_dev *dev1);
136static void alps_set_abs_params_mt(struct alps_data *priv,
137 struct input_dev *dev1);
138
139
140
141
142
143
144
145
146
147static bool alps_is_valid_first_byte(struct alps_data *priv,
148 unsigned char data)
149{
150 return (data & priv->mask0) == priv->byte0;
151}
152
153static void alps_report_buttons(struct psmouse *psmouse,
154 struct input_dev *dev1, struct input_dev *dev2,
155 int left, int right, int middle)
156{
157 struct input_dev *dev;
158
159
160
161
162
163
164 dev = test_bit(BTN_LEFT, dev2->key) ? dev2 : dev1;
165 input_report_key(dev, BTN_LEFT, left);
166
167 dev = test_bit(BTN_RIGHT, dev2->key) ? dev2 : dev1;
168 input_report_key(dev, BTN_RIGHT, right);
169
170 dev = test_bit(BTN_MIDDLE, dev2->key) ? dev2 : dev1;
171 input_report_key(dev, BTN_MIDDLE, middle);
172
173
174
175
176
177 input_sync(dev2);
178}
179
180static void alps_process_packet_v1_v2(struct psmouse *psmouse)
181{
182 struct alps_data *priv = psmouse->private;
183 unsigned char *packet = psmouse->packet;
184 struct input_dev *dev = psmouse->dev;
185 struct input_dev *dev2 = priv->dev2;
186 int x, y, z, ges, fin, left, right, middle;
187 int back = 0, forward = 0;
188
189 if (priv->proto_version == ALPS_PROTO_V1) {
190 left = packet[2] & 0x10;
191 right = packet[2] & 0x08;
192 middle = 0;
193 x = packet[1] | ((packet[0] & 0x07) << 7);
194 y = packet[4] | ((packet[3] & 0x07) << 7);
195 z = packet[5];
196 } else {
197 left = packet[3] & 1;
198 right = packet[3] & 2;
199 middle = packet[3] & 4;
200 x = packet[1] | ((packet[2] & 0x78) << (7 - 3));
201 y = packet[4] | ((packet[3] & 0x70) << (7 - 4));
202 z = packet[5];
203 }
204
205 if (priv->flags & ALPS_FW_BK_1) {
206 back = packet[0] & 0x10;
207 forward = packet[2] & 4;
208 }
209
210 if (priv->flags & ALPS_FW_BK_2) {
211 back = packet[3] & 4;
212 forward = packet[2] & 4;
213 if ((middle = forward && back))
214 forward = back = 0;
215 }
216
217 ges = packet[2] & 1;
218 fin = packet[2] & 2;
219
220 if ((priv->flags & ALPS_DUALPOINT) && z == 127) {
221 input_report_rel(dev2, REL_X, (x > 383 ? (x - 768) : x));
222 input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y));
223
224 alps_report_buttons(psmouse, dev2, dev, left, right, middle);
225
226 input_sync(dev2);
227 return;
228 }
229
230 alps_report_buttons(psmouse, dev, dev2, left, right, middle);
231
232
233 if (ges && !fin)
234 z = 40;
235
236
237
238
239
240
241 if (ges && fin && !priv->prev_fin) {
242 input_report_abs(dev, ABS_X, x);
243 input_report_abs(dev, ABS_Y, y);
244 input_report_abs(dev, ABS_PRESSURE, 0);
245 input_report_key(dev, BTN_TOOL_FINGER, 0);
246 input_sync(dev);
247 }
248 priv->prev_fin = fin;
249
250 if (z > 30)
251 input_report_key(dev, BTN_TOUCH, 1);
252 if (z < 25)
253 input_report_key(dev, BTN_TOUCH, 0);
254
255 if (z > 0) {
256 input_report_abs(dev, ABS_X, x);
257 input_report_abs(dev, ABS_Y, y);
258 }
259
260 input_report_abs(dev, ABS_PRESSURE, z);
261 input_report_key(dev, BTN_TOOL_FINGER, z > 0);
262
263 if (priv->flags & ALPS_WHEEL)
264 input_report_rel(dev, REL_WHEEL, ((packet[2] << 1) & 0x08) - ((packet[0] >> 4) & 0x07));
265
266 if (priv->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
267 input_report_key(dev, BTN_FORWARD, forward);
268 input_report_key(dev, BTN_BACK, back);
269 }
270
271 if (priv->flags & ALPS_FOUR_BUTTONS) {
272 input_report_key(dev, BTN_0, packet[2] & 4);
273 input_report_key(dev, BTN_1, packet[0] & 0x10);
274 input_report_key(dev, BTN_2, packet[3] & 4);
275 input_report_key(dev, BTN_3, packet[0] & 0x20);
276 }
277
278 input_sync(dev);
279}
280
281
282
283
284
285
286
287
288static void alps_process_bitmap_dolphin(struct alps_data *priv,
289 struct alps_fields *fields)
290{
291 int box_middle_x, box_middle_y;
292 unsigned int x_map, y_map;
293 unsigned char start_bit, end_bit;
294 unsigned char x_msb, x_lsb, y_msb, y_lsb;
295
296 x_map = fields->x_map;
297 y_map = fields->y_map;
298
299 if (!x_map || !y_map)
300 return;
301
302
303 x_msb = fls(x_map);
304 x_lsb = ffs(x_map);
305 y_msb = fls(y_map);
306 y_lsb = ffs(y_map);
307
308
309 if (x_msb > priv->x_bits || y_msb > priv->y_bits)
310 return;
311
312 if (fields->fingers > 1) {
313 start_bit = priv->x_bits - x_msb;
314 end_bit = priv->x_bits - x_lsb;
315 box_middle_x = (priv->x_max * (start_bit + end_bit)) /
316 (2 * (priv->x_bits - 1));
317
318 start_bit = y_lsb - 1;
319 end_bit = y_msb - 1;
320 box_middle_y = (priv->y_max * (start_bit + end_bit)) /
321 (2 * (priv->y_bits - 1));
322 fields->mt[0] = fields->st;
323 fields->mt[1].x = 2 * box_middle_x - fields->mt[0].x;
324 fields->mt[1].y = 2 * box_middle_y - fields->mt[0].y;
325 }
326}
327
328static void alps_get_bitmap_points(unsigned int map,
329 struct alps_bitmap_point *low,
330 struct alps_bitmap_point *high,
331 int *fingers)
332{
333 struct alps_bitmap_point *point;
334 int i, bit, prev_bit = 0;
335
336 point = low;
337 for (i = 0; map != 0; i++, map >>= 1) {
338 bit = map & 1;
339 if (bit) {
340 if (!prev_bit) {
341 point->start_bit = i;
342 point->num_bits = 0;
343 (*fingers)++;
344 }
345 point->num_bits++;
346 } else {
347 if (prev_bit)
348 point = high;
349 }
350 prev_bit = bit;
351 }
352}
353
354
355
356
357
358
359
360
361
362
363
364static int alps_process_bitmap(struct alps_data *priv,
365 struct alps_fields *fields)
366{
367 int i, fingers_x = 0, fingers_y = 0, fingers;
368 struct alps_bitmap_point x_low = {0,}, x_high = {0,};
369 struct alps_bitmap_point y_low = {0,}, y_high = {0,};
370
371 if (!fields->x_map || !fields->y_map)
372 return 0;
373
374 alps_get_bitmap_points(fields->x_map, &x_low, &x_high, &fingers_x);
375 alps_get_bitmap_points(fields->y_map, &y_low, &y_high, &fingers_y);
376
377
378
379
380
381 fingers = max(fingers_x, fingers_y);
382
383
384
385
386
387 if (fingers_x == 1) {
388 i = (x_low.num_bits - 1) / 2;
389 x_low.num_bits = x_low.num_bits - i;
390 x_high.start_bit = x_low.start_bit + i;
391 x_high.num_bits = max(i, 1);
392 }
393 if (fingers_y == 1) {
394 i = (y_low.num_bits - 1) / 2;
395 y_low.num_bits = y_low.num_bits - i;
396 y_high.start_bit = y_low.start_bit + i;
397 y_high.num_bits = max(i, 1);
398 }
399
400 fields->mt[0].x =
401 (priv->x_max * (2 * x_low.start_bit + x_low.num_bits - 1)) /
402 (2 * (priv->x_bits - 1));
403 fields->mt[0].y =
404 (priv->y_max * (2 * y_low.start_bit + y_low.num_bits - 1)) /
405 (2 * (priv->y_bits - 1));
406
407 fields->mt[1].x =
408 (priv->x_max * (2 * x_high.start_bit + x_high.num_bits - 1)) /
409 (2 * (priv->x_bits - 1));
410 fields->mt[1].y =
411 (priv->y_max * (2 * y_high.start_bit + y_high.num_bits - 1)) /
412 (2 * (priv->y_bits - 1));
413
414
415 if (!(priv->flags & ALPS_IS_RUSHMORE)) {
416 fields->mt[0].y = priv->y_max - fields->mt[0].y;
417 fields->mt[1].y = priv->y_max - fields->mt[1].y;
418 }
419
420 return fingers;
421}
422
423static void alps_set_slot(struct input_dev *dev, int slot, int x, int y)
424{
425 input_mt_slot(dev, slot);
426 input_mt_report_slot_state(dev, MT_TOOL_FINGER, true);
427 input_report_abs(dev, ABS_MT_POSITION_X, x);
428 input_report_abs(dev, ABS_MT_POSITION_Y, y);
429}
430
431static void alps_report_mt_data(struct psmouse *psmouse, int n)
432{
433 struct alps_data *priv = psmouse->private;
434 struct input_dev *dev = psmouse->dev;
435 struct alps_fields *f = &priv->f;
436 int i, slot[MAX_TOUCHES];
437
438 input_mt_assign_slots(dev, slot, f->mt, n);
439 for (i = 0; i < n; i++)
440 alps_set_slot(dev, slot[i], f->mt[i].x, f->mt[i].y);
441
442 input_mt_sync_frame(dev);
443}
444
445static void alps_report_semi_mt_data(struct psmouse *psmouse, int fingers)
446{
447 struct alps_data *priv = psmouse->private;
448 struct input_dev *dev = psmouse->dev;
449 struct alps_fields *f = &priv->f;
450
451
452 if (fingers < 2) {
453 f->mt[0].x = f->st.x;
454 f->mt[0].y = f->st.y;
455 fingers = f->pressure > 0 ? 1 : 0;
456 }
457
458 alps_report_mt_data(psmouse, (fingers <= 2) ? fingers : 2);
459
460 input_mt_report_finger_count(dev, fingers);
461
462 input_report_key(dev, BTN_LEFT, f->left);
463 input_report_key(dev, BTN_RIGHT, f->right);
464 input_report_key(dev, BTN_MIDDLE, f->middle);
465
466 input_report_abs(dev, ABS_PRESSURE, f->pressure);
467
468 input_sync(dev);
469}
470
471static void alps_process_trackstick_packet_v3(struct psmouse *psmouse)
472{
473 struct alps_data *priv = psmouse->private;
474 unsigned char *packet = psmouse->packet;
475 struct input_dev *dev = priv->dev2;
476 int x, y, z, left, right, middle;
477
478
479 if (!(packet[0] & 0x40)) {
480 psmouse_dbg(psmouse, "Bad trackstick packet, discarding\n");
481 return;
482 }
483
484
485
486
487
488 if (packet[1] == 0x7f && packet[2] == 0x7f && packet[4] == 0x7f)
489 return;
490
491 x = (s8)(((packet[0] & 0x20) << 2) | (packet[1] & 0x7f));
492 y = (s8)(((packet[0] & 0x10) << 3) | (packet[2] & 0x7f));
493 z = (packet[4] & 0x7c) >> 2;
494
495
496
497
498
499
500 x /= 8;
501 y /= 8;
502
503 input_report_rel(dev, REL_X, x);
504 input_report_rel(dev, REL_Y, -y);
505
506
507
508
509
510
511
512
513 left = packet[3] & 0x01;
514 right = packet[3] & 0x02;
515 middle = packet[3] & 0x04;
516
517 if (!(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS) &&
518 (left || right || middle))
519 priv->quirks |= ALPS_QUIRK_TRACKSTICK_BUTTONS;
520
521 if (priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS) {
522 input_report_key(dev, BTN_LEFT, left);
523 input_report_key(dev, BTN_RIGHT, right);
524 input_report_key(dev, BTN_MIDDLE, middle);
525 }
526
527 input_sync(dev);
528 return;
529}
530
531static void alps_decode_buttons_v3(struct alps_fields *f, unsigned char *p)
532{
533 f->left = !!(p[3] & 0x01);
534 f->right = !!(p[3] & 0x02);
535 f->middle = !!(p[3] & 0x04);
536
537 f->ts_left = !!(p[3] & 0x10);
538 f->ts_right = !!(p[3] & 0x20);
539 f->ts_middle = !!(p[3] & 0x40);
540}
541
542static int alps_decode_pinnacle(struct alps_fields *f, unsigned char *p,
543 struct psmouse *psmouse)
544{
545 f->first_mp = !!(p[4] & 0x40);
546 f->is_mp = !!(p[0] & 0x40);
547
548 f->fingers = (p[5] & 0x3) + 1;
549 f->x_map = ((p[4] & 0x7e) << 8) |
550 ((p[1] & 0x7f) << 2) |
551 ((p[0] & 0x30) >> 4);
552 f->y_map = ((p[3] & 0x70) << 4) |
553 ((p[2] & 0x7f) << 1) |
554 (p[4] & 0x01);
555
556 f->st.x = ((p[1] & 0x7f) << 4) | ((p[4] & 0x30) >> 2) |
557 ((p[0] & 0x30) >> 4);
558 f->st.y = ((p[2] & 0x7f) << 4) | (p[4] & 0x0f);
559 f->pressure = p[5] & 0x7f;
560
561 alps_decode_buttons_v3(f, p);
562
563 return 0;
564}
565
566static int alps_decode_rushmore(struct alps_fields *f, unsigned char *p,
567 struct psmouse *psmouse)
568{
569 alps_decode_pinnacle(f, p, psmouse);
570
571
572 f->is_mp = !!(p[5] & 0x40);
573 f->fingers = max((p[5] & 0x3), ((p[5] >> 2) & 0x3)) + 1;
574 f->x_map |= (p[5] & 0x10) << 11;
575 f->y_map |= (p[5] & 0x20) << 6;
576
577 return 0;
578}
579
580static int alps_decode_dolphin(struct alps_fields *f, unsigned char *p,
581 struct psmouse *psmouse)
582{
583 u64 palm_data = 0;
584 struct alps_data *priv = psmouse->private;
585
586 f->first_mp = !!(p[0] & 0x02);
587 f->is_mp = !!(p[0] & 0x20);
588
589 if (!f->is_mp) {
590 f->st.x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7));
591 f->st.y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3));
592 f->pressure = (p[0] & 4) ? 0 : p[5] & 0x7f;
593 alps_decode_buttons_v3(f, p);
594 } else {
595 f->fingers = ((p[0] & 0x6) >> 1 |
596 (p[0] & 0x10) >> 2);
597
598 palm_data = (p[1] & 0x7f) |
599 ((p[2] & 0x7f) << 7) |
600 ((p[4] & 0x7f) << 14) |
601 ((p[5] & 0x7f) << 21) |
602 ((p[3] & 0x07) << 28) |
603 (((u64)p[3] & 0x70) << 27) |
604 (((u64)p[0] & 0x01) << 34);
605
606
607 f->y_map = palm_data & (BIT(priv->y_bits) - 1);
608
609
610 f->x_map = (palm_data >> priv->y_bits) &
611 (BIT(priv->x_bits) - 1);
612 }
613
614 return 0;
615}
616
617static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse)
618{
619 struct alps_data *priv = psmouse->private;
620 unsigned char *packet = psmouse->packet;
621 struct input_dev *dev2 = priv->dev2;
622 struct alps_fields *f = &priv->f;
623 int fingers = 0;
624
625 memset(f, 0, sizeof(*f));
626
627 priv->decode_fields(f, packet, psmouse);
628
629
630
631
632
633
634
635 if (priv->multi_packet) {
636
637
638
639
640
641
642 if (f->is_mp) {
643 fingers = f->fingers;
644 if (priv->proto_version == ALPS_PROTO_V3) {
645 if (alps_process_bitmap(priv, f) == 0)
646 fingers = 0;
647
648
649 priv->decode_fields(f, priv->multi_data,
650 psmouse);
651 } else {
652
653
654
655
656
657
658 priv->decode_fields(f, priv->multi_data,
659 psmouse);
660
661
662
663
664
665 alps_process_bitmap_dolphin(priv, f);
666 }
667 } else {
668 priv->multi_packet = 0;
669 }
670 }
671
672
673
674
675
676
677
678
679
680 if (f->is_mp)
681 return;
682
683 if (!priv->multi_packet && f->first_mp) {
684 priv->multi_packet = 1;
685 memcpy(priv->multi_data, packet, sizeof(priv->multi_data));
686 return;
687 }
688
689 priv->multi_packet = 0;
690
691
692
693
694
695
696
697 if (f->st.x && f->st.y && !f->pressure)
698 return;
699
700 alps_report_semi_mt_data(psmouse, fingers);
701
702 if (!(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS)) {
703 input_report_key(dev2, BTN_LEFT, f->ts_left);
704 input_report_key(dev2, BTN_RIGHT, f->ts_right);
705 input_report_key(dev2, BTN_MIDDLE, f->ts_middle);
706 input_sync(dev2);
707 }
708}
709
710static void alps_process_packet_v3(struct psmouse *psmouse)
711{
712 unsigned char *packet = psmouse->packet;
713
714
715
716
717
718
719
720
721
722 if (packet[5] == 0x3f) {
723 alps_process_trackstick_packet_v3(psmouse);
724 return;
725 }
726
727 alps_process_touchpad_packet_v3_v5(psmouse);
728}
729
730static void alps_process_packet_v6(struct psmouse *psmouse)
731{
732 struct alps_data *priv = psmouse->private;
733 unsigned char *packet = psmouse->packet;
734 struct input_dev *dev = psmouse->dev;
735 struct input_dev *dev2 = priv->dev2;
736 int x, y, z, left, right, middle;
737
738
739
740
741
742
743
744 if (packet[5] == 0x7F) {
745
746 if (!(priv->flags & ALPS_DUALPOINT))
747 return;
748
749
750 x = packet[1] | ((packet[3] & 0x20) << 2);
751 y = packet[2] | ((packet[3] & 0x40) << 1);
752 z = packet[4];
753 left = packet[3] & 0x01;
754 right = packet[3] & 0x02;
755 middle = packet[3] & 0x04;
756
757
758 if (x == 0x7F && y == 0x7F && z == 0x7F)
759 x = y = z = 0;
760
761
762 input_report_rel(dev2, REL_X, (char)x / 4);
763 input_report_rel(dev2, REL_Y, -((char)y / 4));
764
765 input_report_key(dev2, BTN_LEFT, left);
766 input_report_key(dev2, BTN_RIGHT, right);
767 input_report_key(dev2, BTN_MIDDLE, middle);
768
769 input_sync(dev2);
770 return;
771 }
772
773
774 x = packet[1] | ((packet[3] & 0x78) << 4);
775 y = packet[2] | ((packet[4] & 0x78) << 4);
776 z = packet[5];
777 left = packet[3] & 0x01;
778 right = packet[3] & 0x02;
779
780 if (z > 30)
781 input_report_key(dev, BTN_TOUCH, 1);
782 if (z < 25)
783 input_report_key(dev, BTN_TOUCH, 0);
784
785 if (z > 0) {
786 input_report_abs(dev, ABS_X, x);
787 input_report_abs(dev, ABS_Y, y);
788 }
789
790 input_report_abs(dev, ABS_PRESSURE, z);
791 input_report_key(dev, BTN_TOOL_FINGER, z > 0);
792
793
794 input_report_key(dev, BTN_LEFT, left);
795 input_report_key(dev, BTN_RIGHT, right);
796
797 input_sync(dev);
798}
799
800static void alps_process_packet_v4(struct psmouse *psmouse)
801{
802 struct alps_data *priv = psmouse->private;
803 unsigned char *packet = psmouse->packet;
804 struct alps_fields *f = &priv->f;
805 int offset;
806
807
808
809
810
811
812 if (packet[6] & 0x40) {
813
814 priv->multi_packet = 0;
815 }
816
817 if (WARN_ON_ONCE(priv->multi_packet > 2))
818 return;
819
820 offset = 2 * priv->multi_packet;
821 priv->multi_data[offset] = packet[6];
822 priv->multi_data[offset + 1] = packet[7];
823
824 if (++priv->multi_packet > 2) {
825 priv->multi_packet = 0;
826
827 f->x_map = ((priv->multi_data[2] & 0x1f) << 10) |
828 ((priv->multi_data[3] & 0x60) << 3) |
829 ((priv->multi_data[0] & 0x3f) << 2) |
830 ((priv->multi_data[1] & 0x60) >> 5);
831 f->y_map = ((priv->multi_data[5] & 0x01) << 10) |
832 ((priv->multi_data[3] & 0x1f) << 5) |
833 (priv->multi_data[1] & 0x1f);
834
835 f->fingers = alps_process_bitmap(priv, f);
836 }
837
838 f->left = !!(packet[4] & 0x01);
839 f->right = !!(packet[4] & 0x02);
840
841 f->st.x = ((packet[1] & 0x7f) << 4) | ((packet[3] & 0x30) >> 2) |
842 ((packet[0] & 0x30) >> 4);
843 f->st.y = ((packet[2] & 0x7f) << 4) | (packet[3] & 0x0f);
844 f->pressure = packet[5] & 0x7f;
845
846 alps_report_semi_mt_data(psmouse, f->fingers);
847}
848
849static bool alps_is_valid_package_v7(struct psmouse *psmouse)
850{
851 switch (psmouse->pktcnt) {
852 case 3:
853 return (psmouse->packet[2] & 0x40) == 0x40;
854 case 4:
855 return (psmouse->packet[3] & 0x48) == 0x48;
856 case 6:
857 return (psmouse->packet[5] & 0x40) == 0x00;
858 }
859 return true;
860}
861
862static unsigned char alps_get_packet_id_v7(char *byte)
863{
864 unsigned char packet_id;
865
866 if (byte[4] & 0x40)
867 packet_id = V7_PACKET_ID_TWO;
868 else if (byte[4] & 0x01)
869 packet_id = V7_PACKET_ID_MULTI;
870 else if ((byte[0] & 0x10) && !(byte[4] & 0x43))
871 packet_id = V7_PACKET_ID_NEW;
872 else if (byte[1] == 0x00 && byte[4] == 0x00)
873 packet_id = V7_PACKET_ID_IDLE;
874 else
875 packet_id = V7_PACKET_ID_UNKNOWN;
876
877 return packet_id;
878}
879
880static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt,
881 unsigned char *pkt,
882 unsigned char pkt_id)
883{
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912 mt[0].x = ((pkt[2] & 0x80) << 4);
913 mt[0].x |= ((pkt[2] & 0x3F) << 5);
914 mt[0].x |= ((pkt[3] & 0x30) >> 1);
915 mt[0].x |= (pkt[3] & 0x07);
916 mt[0].y = (pkt[1] << 3) | (pkt[0] & 0x07);
917
918 mt[1].x = ((pkt[3] & 0x80) << 4);
919 mt[1].x |= ((pkt[4] & 0x80) << 3);
920 mt[1].x |= ((pkt[4] & 0x3F) << 4);
921 mt[1].y = ((pkt[5] & 0x80) << 3);
922 mt[1].y |= ((pkt[5] & 0x3F) << 4);
923
924 switch (pkt_id) {
925 case V7_PACKET_ID_TWO:
926 mt[1].x &= ~0x000F;
927 mt[1].y |= 0x000F;
928 break;
929
930 case V7_PACKET_ID_MULTI:
931 mt[1].x &= ~0x003F;
932 mt[1].y &= ~0x0020;
933 mt[1].y |= ((pkt[4] & 0x02) << 4);
934 mt[1].y |= 0x001F;
935 break;
936
937 case V7_PACKET_ID_NEW:
938 mt[1].x &= ~0x003F;
939 mt[1].x |= (pkt[0] & 0x20);
940 mt[1].y |= 0x000F;
941 break;
942 }
943
944 mt[0].y = 0x7FF - mt[0].y;
945 mt[1].y = 0x7FF - mt[1].y;
946}
947
948static int alps_get_mt_count(struct input_mt_pos *mt)
949{
950 int i, fingers = 0;
951
952 for (i = 0; i < MAX_TOUCHES; i++) {
953 if (mt[i].x != 0 || mt[i].y != 0)
954 fingers++;
955 }
956
957 return fingers;
958}
959
960static int alps_decode_packet_v7(struct alps_fields *f,
961 unsigned char *p,
962 struct psmouse *psmouse)
963{
964 struct alps_data *priv = psmouse->private;
965 unsigned char pkt_id;
966
967 pkt_id = alps_get_packet_id_v7(p);
968 if (pkt_id == V7_PACKET_ID_IDLE)
969 return 0;
970 if (pkt_id == V7_PACKET_ID_UNKNOWN)
971 return -1;
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990 if (pkt_id == V7_PACKET_ID_NEW)
991 return 1;
992
993 alps_get_finger_coordinate_v7(f->mt, p, pkt_id);
994
995 if (pkt_id == V7_PACKET_ID_TWO)
996 f->fingers = alps_get_mt_count(f->mt);
997 else
998 f->fingers = 3 + (p[5] & 0x03);
999
1000 f->left = (p[0] & 0x80) >> 7;
1001 if (priv->flags & ALPS_BUTTONPAD) {
1002 if (p[0] & 0x20)
1003 f->fingers++;
1004 if (p[0] & 0x10)
1005 f->fingers++;
1006 } else {
1007 f->right = (p[0] & 0x20) >> 5;
1008 f->middle = (p[0] & 0x10) >> 4;
1009 }
1010
1011
1012 if (f->fingers == 1 && f->mt[0].x == 0 && f->mt[0].y == 0) {
1013 f->mt[0].x = f->mt[1].x;
1014 f->mt[0].y = f->mt[1].y;
1015 f->mt[1].x = 0;
1016 f->mt[1].y = 0;
1017 }
1018
1019 return 0;
1020}
1021
1022static void alps_process_trackstick_packet_v7(struct psmouse *psmouse)
1023{
1024 struct alps_data *priv = psmouse->private;
1025 unsigned char *packet = psmouse->packet;
1026 struct input_dev *dev2 = priv->dev2;
1027 int x, y, z, left, right, middle;
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040 x = ((packet[2] & 0xbf)) | ((packet[3] & 0x10) << 2);
1041 y = (packet[3] & 0x07) | (packet[4] & 0xb8) |
1042 ((packet[3] & 0x20) << 1);
1043 z = (packet[5] & 0x3f) | ((packet[3] & 0x80) >> 1);
1044
1045 left = (packet[1] & 0x01);
1046 right = (packet[1] & 0x02) >> 1;
1047 middle = (packet[1] & 0x04) >> 2;
1048
1049
1050 input_report_rel(dev2, REL_X, (char)x / 2);
1051 input_report_rel(dev2, REL_Y, -((char)y / 2));
1052
1053 input_report_key(dev2, BTN_LEFT, left);
1054 input_report_key(dev2, BTN_RIGHT, right);
1055 input_report_key(dev2, BTN_MIDDLE, middle);
1056
1057 input_sync(dev2);
1058}
1059
1060static void alps_process_touchpad_packet_v7(struct psmouse *psmouse)
1061{
1062 struct alps_data *priv = psmouse->private;
1063 struct input_dev *dev = psmouse->dev;
1064 struct alps_fields *f = &priv->f;
1065
1066 memset(f, 0, sizeof(*f));
1067
1068 if (priv->decode_fields(f, psmouse->packet, psmouse))
1069 return;
1070
1071 alps_report_mt_data(psmouse, alps_get_mt_count(f->mt));
1072
1073 input_mt_report_finger_count(dev, f->fingers);
1074
1075 input_report_key(dev, BTN_LEFT, f->left);
1076 input_report_key(dev, BTN_RIGHT, f->right);
1077 input_report_key(dev, BTN_MIDDLE, f->middle);
1078
1079 input_sync(dev);
1080}
1081
1082static void alps_process_packet_v7(struct psmouse *psmouse)
1083{
1084 unsigned char *packet = psmouse->packet;
1085
1086 if (packet[0] == 0x48 && (packet[4] & 0x47) == 0x06)
1087 alps_process_trackstick_packet_v7(psmouse);
1088 else
1089 alps_process_touchpad_packet_v7(psmouse);
1090}
1091
1092static void alps_report_bare_ps2_packet(struct psmouse *psmouse,
1093 unsigned char packet[],
1094 bool report_buttons)
1095{
1096 struct alps_data *priv = psmouse->private;
1097 struct input_dev *dev2 = priv->dev2;
1098
1099 if (report_buttons)
1100 alps_report_buttons(psmouse, dev2, psmouse->dev,
1101 packet[0] & 1, packet[0] & 2, packet[0] & 4);
1102
1103 input_report_rel(dev2, REL_X,
1104 packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0);
1105 input_report_rel(dev2, REL_Y,
1106 packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0);
1107
1108 input_sync(dev2);
1109}
1110
1111static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse)
1112{
1113 struct alps_data *priv = psmouse->private;
1114
1115 if (psmouse->pktcnt < 6)
1116 return PSMOUSE_GOOD_DATA;
1117
1118 if (psmouse->pktcnt == 6) {
1119
1120
1121
1122
1123
1124
1125 mod_timer(&priv->timer, jiffies + msecs_to_jiffies(20));
1126 return PSMOUSE_GOOD_DATA;
1127 }
1128
1129 del_timer(&priv->timer);
1130
1131 if (psmouse->packet[6] & 0x80) {
1132
1133
1134
1135
1136
1137
1138
1139 if (((psmouse->packet[3] |
1140 psmouse->packet[4] |
1141 psmouse->packet[5]) & 0x80) ||
1142 (!alps_is_valid_first_byte(priv, psmouse->packet[6]))) {
1143 psmouse_dbg(psmouse,
1144 "refusing packet %4ph (suspected interleaved ps/2)\n",
1145 psmouse->packet + 3);
1146 return PSMOUSE_BAD_DATA;
1147 }
1148
1149 priv->process_packet(psmouse);
1150
1151
1152 psmouse->packet[0] = psmouse->packet[6];
1153 psmouse->pktcnt = 1;
1154
1155 } else {
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173 alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3],
1174 false);
1175
1176
1177
1178
1179
1180
1181
1182
1183 psmouse->packet[3] = psmouse->packet[6] & 0xf7;
1184 psmouse->pktcnt = 4;
1185 }
1186
1187 return PSMOUSE_GOOD_DATA;
1188}
1189
1190static void alps_flush_packet(unsigned long data)
1191{
1192 struct psmouse *psmouse = (struct psmouse *)data;
1193 struct alps_data *priv = psmouse->private;
1194
1195 serio_pause_rx(psmouse->ps2dev.serio);
1196
1197 if (psmouse->pktcnt == psmouse->pktsize) {
1198
1199
1200
1201
1202
1203
1204 if ((psmouse->packet[3] |
1205 psmouse->packet[4] |
1206 psmouse->packet[5]) & 0x80) {
1207 psmouse_dbg(psmouse,
1208 "refusing packet %3ph (suspected interleaved ps/2)\n",
1209 psmouse->packet + 3);
1210 } else {
1211 priv->process_packet(psmouse);
1212 }
1213 psmouse->pktcnt = 0;
1214 }
1215
1216 serio_continue_rx(psmouse->ps2dev.serio);
1217}
1218
1219static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
1220{
1221 struct alps_data *priv = psmouse->private;
1222
1223 if ((psmouse->packet[0] & 0xc8) == 0x08) {
1224 if (psmouse->pktcnt == 3) {
1225 alps_report_bare_ps2_packet(psmouse, psmouse->packet,
1226 true);
1227 return PSMOUSE_FULL_PACKET;
1228 }
1229 return PSMOUSE_GOOD_DATA;
1230 }
1231
1232
1233
1234 if ((priv->flags & ALPS_PS2_INTERLEAVED) &&
1235 psmouse->pktcnt >= 4 && (psmouse->packet[3] & 0x0f) == 0x0f) {
1236 return alps_handle_interleaved_ps2(psmouse);
1237 }
1238
1239 if (!alps_is_valid_first_byte(priv, psmouse->packet[0])) {
1240 psmouse_dbg(psmouse,
1241 "refusing packet[0] = %x (mask0 = %x, byte0 = %x)\n",
1242 psmouse->packet[0], priv->mask0, priv->byte0);
1243 return PSMOUSE_BAD_DATA;
1244 }
1245
1246
1247 if ((priv->proto_version < ALPS_PROTO_V5) &&
1248 psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
1249 (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
1250 psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
1251 psmouse->pktcnt - 1,
1252 psmouse->packet[psmouse->pktcnt - 1]);
1253 return PSMOUSE_BAD_DATA;
1254 }
1255
1256 if (priv->proto_version == ALPS_PROTO_V7 &&
1257 !alps_is_valid_package_v7(psmouse)) {
1258 psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
1259 psmouse->pktcnt - 1,
1260 psmouse->packet[psmouse->pktcnt - 1]);
1261 return PSMOUSE_BAD_DATA;
1262 }
1263
1264 if (psmouse->pktcnt == psmouse->pktsize) {
1265 priv->process_packet(psmouse);
1266 return PSMOUSE_FULL_PACKET;
1267 }
1268
1269 return PSMOUSE_GOOD_DATA;
1270}
1271
1272static int alps_command_mode_send_nibble(struct psmouse *psmouse, int nibble)
1273{
1274 struct ps2dev *ps2dev = &psmouse->ps2dev;
1275 struct alps_data *priv = psmouse->private;
1276 int command;
1277 unsigned char *param;
1278 unsigned char dummy[4];
1279
1280 BUG_ON(nibble > 0xf);
1281
1282 command = priv->nibble_commands[nibble].command;
1283 param = (command & 0x0f00) ?
1284 dummy : (unsigned char *)&priv->nibble_commands[nibble].data;
1285
1286 if (ps2_command(ps2dev, param, command))
1287 return -1;
1288
1289 return 0;
1290}
1291
1292static int alps_command_mode_set_addr(struct psmouse *psmouse, int addr)
1293{
1294 struct ps2dev *ps2dev = &psmouse->ps2dev;
1295 struct alps_data *priv = psmouse->private;
1296 int i, nibble;
1297
1298 if (ps2_command(ps2dev, NULL, priv->addr_command))
1299 return -1;
1300
1301 for (i = 12; i >= 0; i -= 4) {
1302 nibble = (addr >> i) & 0xf;
1303 if (alps_command_mode_send_nibble(psmouse, nibble))
1304 return -1;
1305 }
1306
1307 return 0;
1308}
1309
1310static int __alps_command_mode_read_reg(struct psmouse *psmouse, int addr)
1311{
1312 struct ps2dev *ps2dev = &psmouse->ps2dev;
1313 unsigned char param[4];
1314
1315 if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
1316 return -1;
1317
1318
1319
1320
1321
1322
1323 if (addr != ((param[0] << 8) | param[1]))
1324 return -1;
1325
1326 return param[2];
1327}
1328
1329static int alps_command_mode_read_reg(struct psmouse *psmouse, int addr)
1330{
1331 if (alps_command_mode_set_addr(psmouse, addr))
1332 return -1;
1333 return __alps_command_mode_read_reg(psmouse, addr);
1334}
1335
1336static int __alps_command_mode_write_reg(struct psmouse *psmouse, u8 value)
1337{
1338 if (alps_command_mode_send_nibble(psmouse, (value >> 4) & 0xf))
1339 return -1;
1340 if (alps_command_mode_send_nibble(psmouse, value & 0xf))
1341 return -1;
1342 return 0;
1343}
1344
1345static int alps_command_mode_write_reg(struct psmouse *psmouse, int addr,
1346 u8 value)
1347{
1348 if (alps_command_mode_set_addr(psmouse, addr))
1349 return -1;
1350 return __alps_command_mode_write_reg(psmouse, value);
1351}
1352
1353static int alps_rpt_cmd(struct psmouse *psmouse, int init_command,
1354 int repeated_command, unsigned char *param)
1355{
1356 struct ps2dev *ps2dev = &psmouse->ps2dev;
1357
1358 param[0] = 0;
1359 if (init_command && ps2_command(ps2dev, param, init_command))
1360 return -EIO;
1361
1362 if (ps2_command(ps2dev, NULL, repeated_command) ||
1363 ps2_command(ps2dev, NULL, repeated_command) ||
1364 ps2_command(ps2dev, NULL, repeated_command))
1365 return -EIO;
1366
1367 param[0] = param[1] = param[2] = 0xff;
1368 if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
1369 return -EIO;
1370
1371 psmouse_dbg(psmouse, "%2.2X report: %3ph\n",
1372 repeated_command, param);
1373 return 0;
1374}
1375
1376static bool alps_check_valid_firmware_id(unsigned char id[])
1377{
1378 if (id[0] == 0x73)
1379 return true;
1380
1381 if (id[0] == 0x88 &&
1382 (id[1] == 0x07 ||
1383 id[1] == 0x08 ||
1384 (id[1] & 0xf0) == 0xb0 ||
1385 (id[1] & 0xf0) == 0xc0)) {
1386 return true;
1387 }
1388
1389 return false;
1390}
1391
1392static int alps_enter_command_mode(struct psmouse *psmouse)
1393{
1394 unsigned char param[4];
1395
1396 if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_RESET_WRAP, param)) {
1397 psmouse_err(psmouse, "failed to enter command mode\n");
1398 return -1;
1399 }
1400
1401 if (!alps_check_valid_firmware_id(param)) {
1402 psmouse_dbg(psmouse,
1403 "unknown response while entering command mode\n");
1404 return -1;
1405 }
1406 return 0;
1407}
1408
1409static inline int alps_exit_command_mode(struct psmouse *psmouse)
1410{
1411 struct ps2dev *ps2dev = &psmouse->ps2dev;
1412 if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM))
1413 return -1;
1414 return 0;
1415}
1416
1417
1418
1419
1420
1421
1422static int alps_passthrough_mode_v2(struct psmouse *psmouse, bool enable)
1423{
1424 struct ps2dev *ps2dev = &psmouse->ps2dev;
1425 int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11;
1426
1427 if (ps2_command(ps2dev, NULL, cmd) ||
1428 ps2_command(ps2dev, NULL, cmd) ||
1429 ps2_command(ps2dev, NULL, cmd) ||
1430 ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE))
1431 return -1;
1432
1433
1434 ps2_drain(ps2dev, 3, 100);
1435
1436 return 0;
1437}
1438
1439static int alps_absolute_mode_v1_v2(struct psmouse *psmouse)
1440{
1441 struct ps2dev *ps2dev = &psmouse->ps2dev;
1442
1443
1444 if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
1445 ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
1446 ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
1447 ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
1448 ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE))
1449 return -1;
1450
1451
1452
1453
1454
1455 return ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETPOLL);
1456}
1457
1458static int alps_monitor_mode_send_word(struct psmouse *psmouse, u16 word)
1459{
1460 int i, nibble;
1461
1462
1463
1464
1465
1466 for (i = 0; i <= 8; i += 4) {
1467 nibble = (word >> i) & 0xf;
1468 if (alps_command_mode_send_nibble(psmouse, nibble))
1469 return -1;
1470 }
1471
1472 return 0;
1473}
1474
1475static int alps_monitor_mode_write_reg(struct psmouse *psmouse,
1476 u16 addr, u16 value)
1477{
1478 struct ps2dev *ps2dev = &psmouse->ps2dev;
1479
1480
1481 if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE) ||
1482 alps_monitor_mode_send_word(psmouse, 0x0A0) ||
1483 alps_monitor_mode_send_word(psmouse, addr) ||
1484 alps_monitor_mode_send_word(psmouse, value) ||
1485 ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE))
1486 return -1;
1487
1488 return 0;
1489}
1490
1491static int alps_monitor_mode(struct psmouse *psmouse, bool enable)
1492{
1493 struct ps2dev *ps2dev = &psmouse->ps2dev;
1494
1495 if (enable) {
1496
1497 if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) ||
1498 ps2_command(ps2dev, NULL, PSMOUSE_CMD_GETINFO) ||
1499 ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
1500 ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
1501 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
1502 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
1503 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
1504 ps2_command(ps2dev, NULL, PSMOUSE_CMD_GETINFO))
1505 return -1;
1506 } else {
1507
1508 if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP))
1509 return -1;
1510 }
1511
1512 return 0;
1513}
1514
1515static int alps_absolute_mode_v6(struct psmouse *psmouse)
1516{
1517 u16 reg_val = 0x181;
1518 int ret = -1;
1519
1520
1521 if (alps_monitor_mode(psmouse, true))
1522 return -1;
1523
1524 ret = alps_monitor_mode_write_reg(psmouse, 0x000, reg_val);
1525
1526 if (alps_monitor_mode(psmouse, false))
1527 ret = -1;
1528
1529 return ret;
1530}
1531
1532static int alps_get_status(struct psmouse *psmouse, char *param)
1533{
1534
1535 if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_DISABLE, param))
1536 return -1;
1537
1538 return 0;
1539}
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550static int alps_tap_mode(struct psmouse *psmouse, int enable)
1551{
1552 struct ps2dev *ps2dev = &psmouse->ps2dev;
1553 int cmd = enable ? PSMOUSE_CMD_SETRATE : PSMOUSE_CMD_SETRES;
1554 unsigned char tap_arg = enable ? 0x0A : 0x00;
1555 unsigned char param[4];
1556
1557 if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO) ||
1558 ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
1559 ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
1560 ps2_command(ps2dev, &tap_arg, cmd))
1561 return -1;
1562
1563 if (alps_get_status(psmouse, param))
1564 return -1;
1565
1566 return 0;
1567}
1568
1569
1570
1571
1572
1573static int alps_poll(struct psmouse *psmouse)
1574{
1575 struct alps_data *priv = psmouse->private;
1576 unsigned char buf[sizeof(psmouse->packet)];
1577 bool poll_failed;
1578
1579 if (priv->flags & ALPS_PASS)
1580 alps_passthrough_mode_v2(psmouse, true);
1581
1582 poll_failed = ps2_command(&psmouse->ps2dev, buf,
1583 PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0;
1584
1585 if (priv->flags & ALPS_PASS)
1586 alps_passthrough_mode_v2(psmouse, false);
1587
1588 if (poll_failed || (buf[0] & priv->mask0) != priv->byte0)
1589 return -1;
1590
1591 if ((psmouse->badbyte & 0xc8) == 0x08) {
1592
1593
1594
1595 if (ps2_command(&psmouse->ps2dev, buf, PSMOUSE_CMD_POLL | (3 << 8)))
1596 return -1;
1597 }
1598
1599 memcpy(psmouse->packet, buf, sizeof(buf));
1600 return 0;
1601}
1602
1603static int alps_hw_init_v1_v2(struct psmouse *psmouse)
1604{
1605 struct alps_data *priv = psmouse->private;
1606
1607 if ((priv->flags & ALPS_PASS) &&
1608 alps_passthrough_mode_v2(psmouse, true)) {
1609 return -1;
1610 }
1611
1612 if (alps_tap_mode(psmouse, true)) {
1613 psmouse_warn(psmouse, "Failed to enable hardware tapping\n");
1614 return -1;
1615 }
1616
1617 if (alps_absolute_mode_v1_v2(psmouse)) {
1618 psmouse_err(psmouse, "Failed to enable absolute mode\n");
1619 return -1;
1620 }
1621
1622 if ((priv->flags & ALPS_PASS) &&
1623 alps_passthrough_mode_v2(psmouse, false)) {
1624 return -1;
1625 }
1626
1627
1628 if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) {
1629 psmouse_err(psmouse, "Failed to enable stream mode\n");
1630 return -1;
1631 }
1632
1633 return 0;
1634}
1635
1636static int alps_hw_init_v6(struct psmouse *psmouse)
1637{
1638 unsigned char param[2] = {0xC8, 0x14};
1639
1640
1641 if (alps_passthrough_mode_v2(psmouse, true))
1642 return -1;
1643
1644 if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
1645 ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
1646 ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
1647 ps2_command(&psmouse->ps2dev, ¶m[0], PSMOUSE_CMD_SETRATE) ||
1648 ps2_command(&psmouse->ps2dev, ¶m[1], PSMOUSE_CMD_SETRATE))
1649 return -1;
1650
1651 if (alps_passthrough_mode_v2(psmouse, false))
1652 return -1;
1653
1654 if (alps_absolute_mode_v6(psmouse)) {
1655 psmouse_err(psmouse, "Failed to enable absolute mode\n");
1656 return -1;
1657 }
1658
1659 return 0;
1660}
1661
1662
1663
1664
1665static int alps_passthrough_mode_v3(struct psmouse *psmouse,
1666 int reg_base, bool enable)
1667{
1668 int reg_val, ret = -1;
1669
1670 if (alps_enter_command_mode(psmouse))
1671 return -1;
1672
1673 reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x0008);
1674 if (reg_val == -1)
1675 goto error;
1676
1677 if (enable)
1678 reg_val |= 0x01;
1679 else
1680 reg_val &= ~0x01;
1681
1682 ret = __alps_command_mode_write_reg(psmouse, reg_val);
1683
1684error:
1685 if (alps_exit_command_mode(psmouse))
1686 ret = -1;
1687 return ret;
1688}
1689
1690
1691static int alps_absolute_mode_v3(struct psmouse *psmouse)
1692{
1693 int reg_val;
1694
1695 reg_val = alps_command_mode_read_reg(psmouse, 0x0004);
1696 if (reg_val == -1)
1697 return -1;
1698
1699 reg_val |= 0x06;
1700 if (__alps_command_mode_write_reg(psmouse, reg_val))
1701 return -1;
1702
1703 return 0;
1704}
1705
1706static int alps_probe_trackstick_v3(struct psmouse *psmouse, int reg_base)
1707{
1708 int ret = -EIO, reg_val;
1709
1710 if (alps_enter_command_mode(psmouse))
1711 goto error;
1712
1713 reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x08);
1714 if (reg_val == -1)
1715 goto error;
1716
1717
1718 ret = reg_val & 0x80 ? 0 : -ENODEV;
1719
1720error:
1721 alps_exit_command_mode(psmouse);
1722 return ret;
1723}
1724
1725static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base)
1726{
1727 struct ps2dev *ps2dev = &psmouse->ps2dev;
1728 int ret = 0;
1729 unsigned char param[4];
1730
1731 if (alps_passthrough_mode_v3(psmouse, reg_base, true))
1732 return -EIO;
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743 if (alps_rpt_cmd(psmouse, 0, PSMOUSE_CMD_SETSCALE21, param)) {
1744 psmouse_warn(psmouse, "trackstick E7 report failed\n");
1745 ret = -ENODEV;
1746 } else {
1747 psmouse_dbg(psmouse, "trackstick E7 report: %3ph\n", param);
1748
1749
1750
1751
1752
1753
1754
1755 if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
1756 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
1757 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) ||
1758 alps_command_mode_send_nibble(psmouse, 0x9) ||
1759 alps_command_mode_send_nibble(psmouse, 0x4)) {
1760 psmouse_err(psmouse,
1761 "Error sending magic E6 sequence\n");
1762 ret = -EIO;
1763 goto error;
1764 }
1765
1766
1767
1768
1769
1770
1771 if (alps_enter_command_mode(psmouse) ||
1772 alps_command_mode_write_reg(psmouse,
1773 reg_base + 0x08, 0x82) ||
1774 alps_exit_command_mode(psmouse))
1775 ret = -EIO;
1776 }
1777
1778error:
1779 if (alps_passthrough_mode_v3(psmouse, reg_base, false))
1780 ret = -EIO;
1781
1782 return ret;
1783}
1784
1785static int alps_hw_init_v3(struct psmouse *psmouse)
1786{
1787 struct ps2dev *ps2dev = &psmouse->ps2dev;
1788 int reg_val;
1789 unsigned char param[4];
1790
1791 reg_val = alps_probe_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE);
1792 if (reg_val == -EIO)
1793 goto error;
1794
1795 if (reg_val == 0 &&
1796 alps_setup_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE) == -EIO)
1797 goto error;
1798
1799 if (alps_enter_command_mode(psmouse) ||
1800 alps_absolute_mode_v3(psmouse)) {
1801 psmouse_err(psmouse, "Failed to enter absolute mode\n");
1802 goto error;
1803 }
1804
1805 reg_val = alps_command_mode_read_reg(psmouse, 0x0006);
1806 if (reg_val == -1)
1807 goto error;
1808 if (__alps_command_mode_write_reg(psmouse, reg_val | 0x01))
1809 goto error;
1810
1811 reg_val = alps_command_mode_read_reg(psmouse, 0x0007);
1812 if (reg_val == -1)
1813 goto error;
1814 if (__alps_command_mode_write_reg(psmouse, reg_val | 0x01))
1815 goto error;
1816
1817 if (alps_command_mode_read_reg(psmouse, 0x0144) == -1)
1818 goto error;
1819 if (__alps_command_mode_write_reg(psmouse, 0x04))
1820 goto error;
1821
1822 if (alps_command_mode_read_reg(psmouse, 0x0159) == -1)
1823 goto error;
1824 if (__alps_command_mode_write_reg(psmouse, 0x03))
1825 goto error;
1826
1827 if (alps_command_mode_read_reg(psmouse, 0x0163) == -1)
1828 goto error;
1829 if (alps_command_mode_write_reg(psmouse, 0x0163, 0x03))
1830 goto error;
1831
1832 if (alps_command_mode_read_reg(psmouse, 0x0162) == -1)
1833 goto error;
1834 if (alps_command_mode_write_reg(psmouse, 0x0162, 0x04))
1835 goto error;
1836
1837 alps_exit_command_mode(psmouse);
1838
1839
1840 param[0] = 0x64;
1841 if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE) ||
1842 ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE)) {
1843 psmouse_err(psmouse, "Failed to enable data reporting\n");
1844 return -1;
1845 }
1846
1847 return 0;
1848
1849error:
1850
1851
1852
1853
1854
1855 alps_exit_command_mode(psmouse);
1856 return -1;
1857}
1858
1859static int alps_get_v3_v7_resolution(struct psmouse *psmouse, int reg_pitch)
1860{
1861 int reg, x_pitch, y_pitch, x_electrode, y_electrode, x_phys, y_phys;
1862 struct alps_data *priv = psmouse->private;
1863
1864 reg = alps_command_mode_read_reg(psmouse, reg_pitch);
1865 if (reg < 0)
1866 return reg;
1867
1868 x_pitch = (char)(reg << 4) >> 4;
1869 x_pitch = 50 + 2 * x_pitch;
1870
1871 y_pitch = (char)reg >> 4;
1872 y_pitch = 36 + 2 * y_pitch;
1873
1874 reg = alps_command_mode_read_reg(psmouse, reg_pitch + 1);
1875 if (reg < 0)
1876 return reg;
1877
1878 x_electrode = (char)(reg << 4) >> 4;
1879 x_electrode = 17 + x_electrode;
1880
1881 y_electrode = (char)reg >> 4;
1882 y_electrode = 13 + y_electrode;
1883
1884 x_phys = x_pitch * (x_electrode - 1);
1885 y_phys = y_pitch * (y_electrode - 1);
1886
1887 priv->x_res = priv->x_max * 10 / x_phys;
1888 priv->y_res = priv->y_max * 10 / y_phys;
1889
1890 psmouse_dbg(psmouse,
1891 "pitch %dx%d num-electrodes %dx%d physical size %dx%d mm res %dx%d\n",
1892 x_pitch, y_pitch, x_electrode, y_electrode,
1893 x_phys / 10, y_phys / 10, priv->x_res, priv->y_res);
1894
1895 return 0;
1896}
1897
1898static int alps_hw_init_rushmore_v3(struct psmouse *psmouse)
1899{
1900 struct alps_data *priv = psmouse->private;
1901 struct ps2dev *ps2dev = &psmouse->ps2dev;
1902 int reg_val, ret = -1;
1903
1904 if (priv->flags & ALPS_DUALPOINT) {
1905 reg_val = alps_setup_trackstick_v3(psmouse,
1906 ALPS_REG_BASE_RUSHMORE);
1907 if (reg_val == -EIO)
1908 goto error;
1909 if (reg_val == -ENODEV)
1910 priv->flags &= ~ALPS_DUALPOINT;
1911 }
1912
1913 if (alps_enter_command_mode(psmouse) ||
1914 alps_command_mode_read_reg(psmouse, 0xc2d9) == -1 ||
1915 alps_command_mode_write_reg(psmouse, 0xc2cb, 0x00))
1916 goto error;
1917
1918 if (alps_get_v3_v7_resolution(psmouse, 0xc2da))
1919 goto error;
1920
1921 reg_val = alps_command_mode_read_reg(psmouse, 0xc2c6);
1922 if (reg_val == -1)
1923 goto error;
1924 if (__alps_command_mode_write_reg(psmouse, reg_val & 0xfd))
1925 goto error;
1926
1927 if (alps_command_mode_write_reg(psmouse, 0xc2c9, 0x64))
1928 goto error;
1929
1930
1931 reg_val = alps_command_mode_read_reg(psmouse, 0xc2c4);
1932 if (reg_val == -1)
1933 goto error;
1934 if (__alps_command_mode_write_reg(psmouse, reg_val | 0x02))
1935 goto error;
1936
1937 alps_exit_command_mode(psmouse);
1938 return ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
1939
1940error:
1941 alps_exit_command_mode(psmouse);
1942 return ret;
1943}
1944
1945
1946static int alps_absolute_mode_v4(struct psmouse *psmouse)
1947{
1948 int reg_val;
1949
1950 reg_val = alps_command_mode_read_reg(psmouse, 0x0004);
1951 if (reg_val == -1)
1952 return -1;
1953
1954 reg_val |= 0x02;
1955 if (__alps_command_mode_write_reg(psmouse, reg_val))
1956 return -1;
1957
1958 return 0;
1959}
1960
1961static int alps_hw_init_v4(struct psmouse *psmouse)
1962{
1963 struct ps2dev *ps2dev = &psmouse->ps2dev;
1964 unsigned char param[4];
1965
1966 if (alps_enter_command_mode(psmouse))
1967 goto error;
1968
1969 if (alps_absolute_mode_v4(psmouse)) {
1970 psmouse_err(psmouse, "Failed to enter absolute mode\n");
1971 goto error;
1972 }
1973
1974 if (alps_command_mode_write_reg(psmouse, 0x0007, 0x8c))
1975 goto error;
1976
1977 if (alps_command_mode_write_reg(psmouse, 0x0149, 0x03))
1978 goto error;
1979
1980 if (alps_command_mode_write_reg(psmouse, 0x0160, 0x03))
1981 goto error;
1982
1983 if (alps_command_mode_write_reg(psmouse, 0x017f, 0x15))
1984 goto error;
1985
1986 if (alps_command_mode_write_reg(psmouse, 0x0151, 0x01))
1987 goto error;
1988
1989 if (alps_command_mode_write_reg(psmouse, 0x0168, 0x03))
1990 goto error;
1991
1992 if (alps_command_mode_write_reg(psmouse, 0x014a, 0x03))
1993 goto error;
1994
1995 if (alps_command_mode_write_reg(psmouse, 0x0161, 0x03))
1996 goto error;
1997
1998 alps_exit_command_mode(psmouse);
1999
2000
2001
2002
2003
2004
2005 param[0] = 0xc8;
2006 param[1] = 0x64;
2007 param[2] = 0x50;
2008 if (ps2_command(ps2dev, ¶m[0], PSMOUSE_CMD_SETRATE) ||
2009 ps2_command(ps2dev, ¶m[1], PSMOUSE_CMD_SETRATE) ||
2010 ps2_command(ps2dev, ¶m[2], PSMOUSE_CMD_SETRATE) ||
2011 ps2_command(ps2dev, param, PSMOUSE_CMD_GETID))
2012 return -1;
2013
2014
2015 param[0] = 0x64;
2016 if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE) ||
2017 ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE)) {
2018 psmouse_err(psmouse, "Failed to enable data reporting\n");
2019 return -1;
2020 }
2021
2022 return 0;
2023
2024error:
2025
2026
2027
2028
2029
2030 alps_exit_command_mode(psmouse);
2031 return -1;
2032}
2033
2034static int alps_dolphin_get_device_area(struct psmouse *psmouse,
2035 struct alps_data *priv)
2036{
2037 struct ps2dev *ps2dev = &psmouse->ps2dev;
2038 unsigned char param[4] = {0};
2039 int num_x_electrode, num_y_electrode;
2040
2041 if (alps_enter_command_mode(psmouse))
2042 return -1;
2043
2044 param[0] = 0x0a;
2045 if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_WRAP) ||
2046 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL) ||
2047 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL) ||
2048 ps2_command(ps2dev, ¶m[0], PSMOUSE_CMD_SETRATE) ||
2049 ps2_command(ps2dev, ¶m[0], PSMOUSE_CMD_SETRATE))
2050 return -1;
2051
2052 if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
2053 return -1;
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067 num_x_electrode = DOLPHIN_PROFILE_XOFFSET + (param[2] & 0x0F);
2068 num_y_electrode = DOLPHIN_PROFILE_YOFFSET + ((param[2] >> 4) & 0x0F);
2069 priv->x_bits = num_x_electrode;
2070 priv->y_bits = num_y_electrode;
2071 priv->x_max = (num_x_electrode - 1) * DOLPHIN_COUNT_PER_ELECTRODE;
2072 priv->y_max = (num_y_electrode - 1) * DOLPHIN_COUNT_PER_ELECTRODE;
2073
2074 if (alps_exit_command_mode(psmouse))
2075 return -1;
2076
2077 return 0;
2078}
2079
2080static int alps_hw_init_dolphin_v1(struct psmouse *psmouse)
2081{
2082 struct ps2dev *ps2dev = &psmouse->ps2dev;
2083 unsigned char param[2];
2084
2085
2086 param[0] = 0x64;
2087 param[1] = 0x28;
2088
2089 if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM) ||
2090 ps2_command(ps2dev, ¶m[0], PSMOUSE_CMD_SETRATE) ||
2091 ps2_command(ps2dev, ¶m[1], PSMOUSE_CMD_SETRATE))
2092 return -1;
2093
2094 return 0;
2095}
2096
2097static int alps_hw_init_v7(struct psmouse *psmouse)
2098{
2099 struct ps2dev *ps2dev = &psmouse->ps2dev;
2100 int reg_val, ret = -1;
2101
2102 if (alps_enter_command_mode(psmouse) ||
2103 alps_command_mode_read_reg(psmouse, 0xc2d9) == -1)
2104 goto error;
2105
2106 if (alps_get_v3_v7_resolution(psmouse, 0xc397))
2107 goto error;
2108
2109 if (alps_command_mode_write_reg(psmouse, 0xc2c9, 0x64))
2110 goto error;
2111
2112 reg_val = alps_command_mode_read_reg(psmouse, 0xc2c4);
2113 if (reg_val == -1)
2114 goto error;
2115 if (__alps_command_mode_write_reg(psmouse, reg_val | 0x02))
2116 goto error;
2117
2118 alps_exit_command_mode(psmouse);
2119 return ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
2120
2121error:
2122 alps_exit_command_mode(psmouse);
2123 return ret;
2124}
2125
2126static void alps_set_defaults(struct alps_data *priv)
2127{
2128 priv->byte0 = 0x8f;
2129 priv->mask0 = 0x8f;
2130 priv->flags = ALPS_DUALPOINT;
2131
2132 priv->x_max = 2000;
2133 priv->y_max = 1400;
2134 priv->x_bits = 15;
2135 priv->y_bits = 11;
2136
2137 switch (priv->proto_version) {
2138 case ALPS_PROTO_V1:
2139 case ALPS_PROTO_V2:
2140 priv->hw_init = alps_hw_init_v1_v2;
2141 priv->process_packet = alps_process_packet_v1_v2;
2142 priv->set_abs_params = alps_set_abs_params_st;
2143 priv->x_max = 1023;
2144 priv->y_max = 767;
2145 break;
2146 case ALPS_PROTO_V3:
2147 priv->hw_init = alps_hw_init_v3;
2148 priv->process_packet = alps_process_packet_v3;
2149 priv->set_abs_params = alps_set_abs_params_mt;
2150 priv->decode_fields = alps_decode_pinnacle;
2151 priv->nibble_commands = alps_v3_nibble_commands;
2152 priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
2153 break;
2154 case ALPS_PROTO_V4:
2155 priv->hw_init = alps_hw_init_v4;
2156 priv->process_packet = alps_process_packet_v4;
2157 priv->set_abs_params = alps_set_abs_params_mt;
2158 priv->nibble_commands = alps_v4_nibble_commands;
2159 priv->addr_command = PSMOUSE_CMD_DISABLE;
2160 break;
2161 case ALPS_PROTO_V5:
2162 priv->hw_init = alps_hw_init_dolphin_v1;
2163 priv->process_packet = alps_process_touchpad_packet_v3_v5;
2164 priv->decode_fields = alps_decode_dolphin;
2165 priv->set_abs_params = alps_set_abs_params_mt;
2166 priv->nibble_commands = alps_v3_nibble_commands;
2167 priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
2168 priv->byte0 = 0xc8;
2169 priv->mask0 = 0xd8;
2170 priv->flags = 0;
2171 priv->x_max = 1360;
2172 priv->y_max = 660;
2173 priv->x_bits = 23;
2174 priv->y_bits = 12;
2175 break;
2176 case ALPS_PROTO_V6:
2177 priv->hw_init = alps_hw_init_v6;
2178 priv->process_packet = alps_process_packet_v6;
2179 priv->set_abs_params = alps_set_abs_params_st;
2180 priv->nibble_commands = alps_v6_nibble_commands;
2181 priv->x_max = 2047;
2182 priv->y_max = 1535;
2183 break;
2184 case ALPS_PROTO_V7:
2185 priv->hw_init = alps_hw_init_v7;
2186 priv->process_packet = alps_process_packet_v7;
2187 priv->decode_fields = alps_decode_packet_v7;
2188 priv->set_abs_params = alps_set_abs_params_mt;
2189 priv->nibble_commands = alps_v3_nibble_commands;
2190 priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
2191 priv->x_max = 0xfff;
2192 priv->y_max = 0x7ff;
2193 priv->byte0 = 0x48;
2194 priv->mask0 = 0x48;
2195
2196 if (priv->fw_ver[1] != 0xba)
2197 priv->flags |= ALPS_BUTTONPAD;
2198 break;
2199 }
2200}
2201
2202static int alps_match_table(struct psmouse *psmouse, struct alps_data *priv,
2203 unsigned char *e7, unsigned char *ec)
2204{
2205 const struct alps_model_info *model;
2206 int i;
2207
2208 for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) {
2209 model = &alps_model_data[i];
2210
2211 if (!memcmp(e7, model->signature, sizeof(model->signature)) &&
2212 (!model->command_mode_resp ||
2213 model->command_mode_resp == ec[2])) {
2214
2215 priv->proto_version = model->proto_version;
2216 alps_set_defaults(priv);
2217
2218 priv->flags = model->flags;
2219 priv->byte0 = model->byte0;
2220 priv->mask0 = model->mask0;
2221
2222 return 0;
2223 }
2224 }
2225
2226 return -EINVAL;
2227}
2228
2229static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
2230{
2231 unsigned char e6[4], e7[4], ec[4];
2232
2233
2234
2235
2236
2237
2238
2239 if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES,
2240 PSMOUSE_CMD_SETSCALE11, e6))
2241 return -EIO;
2242
2243 if ((e6[0] & 0xf8) != 0 || e6[1] != 0 || (e6[2] != 10 && e6[2] != 100))
2244 return -EINVAL;
2245
2246
2247
2248
2249
2250 if (alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES,
2251 PSMOUSE_CMD_SETSCALE21, e7) ||
2252 alps_rpt_cmd(psmouse, PSMOUSE_CMD_SETRES,
2253 PSMOUSE_CMD_RESET_WRAP, ec) ||
2254 alps_exit_command_mode(psmouse))
2255 return -EIO;
2256
2257
2258 memcpy(priv->fw_ver, ec, 3);
2259
2260 if (alps_match_table(psmouse, priv, e7, ec) == 0) {
2261 return 0;
2262 } else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 &&
2263 ec[0] == 0x73 && (ec[1] == 0x01 || ec[1] == 0x02)) {
2264 priv->proto_version = ALPS_PROTO_V5;
2265 alps_set_defaults(priv);
2266 if (alps_dolphin_get_device_area(psmouse, priv))
2267 return -EIO;
2268 else
2269 return 0;
2270 } else if (ec[0] == 0x88 &&
2271 ((ec[1] & 0xf0) == 0xb0 || (ec[1] & 0xf0) == 0xc0)) {
2272 priv->proto_version = ALPS_PROTO_V7;
2273 alps_set_defaults(priv);
2274
2275 return 0;
2276 } else if (ec[0] == 0x88 && ec[1] == 0x08) {
2277 priv->proto_version = ALPS_PROTO_V3;
2278 alps_set_defaults(priv);
2279
2280 priv->hw_init = alps_hw_init_rushmore_v3;
2281 priv->decode_fields = alps_decode_rushmore;
2282 priv->x_bits = 16;
2283 priv->y_bits = 12;
2284 priv->flags |= ALPS_IS_RUSHMORE;
2285
2286
2287 psmouse->private = priv;
2288
2289 if (alps_probe_trackstick_v3(psmouse, ALPS_REG_BASE_RUSHMORE))
2290 priv->flags &= ~ALPS_DUALPOINT;
2291
2292 return 0;
2293 } else if (ec[0] == 0x88 && ec[1] == 0x07 &&
2294 ec[2] >= 0x90 && ec[2] <= 0x9d) {
2295 priv->proto_version = ALPS_PROTO_V3;
2296 alps_set_defaults(priv);
2297
2298 return 0;
2299 }
2300
2301 psmouse_info(psmouse,
2302 "Unknown ALPS touchpad: E7=%3ph, EC=%3ph\n", e7, ec);
2303
2304 return -EINVAL;
2305}
2306
2307static int alps_reconnect(struct psmouse *psmouse)
2308{
2309 struct alps_data *priv = psmouse->private;
2310
2311 psmouse_reset(psmouse);
2312
2313 if (alps_identify(psmouse, priv) < 0)
2314 return -1;
2315
2316 return priv->hw_init(psmouse);
2317}
2318
2319static void alps_disconnect(struct psmouse *psmouse)
2320{
2321 struct alps_data *priv = psmouse->private;
2322
2323 psmouse_reset(psmouse);
2324 del_timer_sync(&priv->timer);
2325 input_unregister_device(priv->dev2);
2326 kfree(priv);
2327}
2328
2329static void alps_set_abs_params_st(struct alps_data *priv,
2330 struct input_dev *dev1)
2331{
2332 input_set_abs_params(dev1, ABS_X, 0, priv->x_max, 0, 0);
2333 input_set_abs_params(dev1, ABS_Y, 0, priv->y_max, 0, 0);
2334}
2335
2336static void alps_set_abs_params_mt(struct alps_data *priv,
2337 struct input_dev *dev1)
2338{
2339 input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, priv->x_max, 0, 0);
2340 input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, priv->y_max, 0, 0);
2341
2342 input_abs_set_res(dev1, ABS_MT_POSITION_X, priv->x_res);
2343 input_abs_set_res(dev1, ABS_MT_POSITION_Y, priv->y_res);
2344
2345 input_mt_init_slots(dev1, MAX_TOUCHES, INPUT_MT_POINTER |
2346 INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK | INPUT_MT_SEMI_MT);
2347
2348 set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit);
2349 set_bit(BTN_TOOL_QUADTAP, dev1->keybit);
2350
2351
2352 if (priv->proto_version == ALPS_PROTO_V7)
2353 clear_bit(INPUT_PROP_SEMI_MT, dev1->propbit);
2354}
2355
2356int alps_init(struct psmouse *psmouse)
2357{
2358 struct alps_data *priv;
2359 struct input_dev *dev1 = psmouse->dev, *dev2;
2360
2361 priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL);
2362 dev2 = input_allocate_device();
2363 if (!priv || !dev2)
2364 goto init_fail;
2365
2366 priv->dev2 = dev2;
2367 setup_timer(&priv->timer, alps_flush_packet, (unsigned long)psmouse);
2368
2369 psmouse->private = priv;
2370
2371 psmouse_reset(psmouse);
2372
2373 if (alps_identify(psmouse, priv) < 0)
2374 goto init_fail;
2375
2376 if (priv->hw_init(psmouse))
2377 goto init_fail;
2378
2379
2380
2381
2382
2383 __clear_bit(EV_REL, dev1->evbit);
2384 __clear_bit(REL_X, dev1->relbit);
2385 __clear_bit(REL_Y, dev1->relbit);
2386
2387
2388
2389
2390 dev1->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY);
2391 dev1->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH);
2392 dev1->keybit[BIT_WORD(BTN_TOOL_FINGER)] |= BIT_MASK(BTN_TOOL_FINGER);
2393 dev1->keybit[BIT_WORD(BTN_LEFT)] |=
2394 BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
2395
2396 dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS);
2397
2398 priv->set_abs_params(priv, dev1);
2399
2400 if (priv->proto_version != ALPS_PROTO_V7)
2401 input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
2402
2403 if (priv->flags & ALPS_WHEEL) {
2404 dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL);
2405 dev1->relbit[BIT_WORD(REL_WHEEL)] |= BIT_MASK(REL_WHEEL);
2406 }
2407
2408 if (priv->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
2409 dev1->keybit[BIT_WORD(BTN_FORWARD)] |= BIT_MASK(BTN_FORWARD);
2410 dev1->keybit[BIT_WORD(BTN_BACK)] |= BIT_MASK(BTN_BACK);
2411 }
2412
2413 if (priv->flags & ALPS_FOUR_BUTTONS) {
2414 dev1->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_0);
2415 dev1->keybit[BIT_WORD(BTN_1)] |= BIT_MASK(BTN_1);
2416 dev1->keybit[BIT_WORD(BTN_2)] |= BIT_MASK(BTN_2);
2417 dev1->keybit[BIT_WORD(BTN_3)] |= BIT_MASK(BTN_3);
2418 } else if (priv->flags & ALPS_BUTTONPAD) {
2419 set_bit(INPUT_PROP_BUTTONPAD, dev1->propbit);
2420 clear_bit(BTN_RIGHT, dev1->keybit);
2421 } else {
2422 dev1->keybit[BIT_WORD(BTN_MIDDLE)] |= BIT_MASK(BTN_MIDDLE);
2423 }
2424
2425 snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys);
2426 dev2->phys = priv->phys;
2427 dev2->name = (priv->flags & ALPS_DUALPOINT) ?
2428 "DualPoint Stick" : "ALPS PS/2 Device";
2429 dev2->id.bustype = BUS_I8042;
2430 dev2->id.vendor = 0x0002;
2431 dev2->id.product = PSMOUSE_ALPS;
2432 dev2->id.version = 0x0000;
2433 dev2->dev.parent = &psmouse->ps2dev.serio->dev;
2434
2435 dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
2436 dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
2437 dev2->keybit[BIT_WORD(BTN_LEFT)] =
2438 BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
2439
2440 __set_bit(INPUT_PROP_POINTER, dev2->propbit);
2441 if (priv->flags & ALPS_DUALPOINT)
2442 __set_bit(INPUT_PROP_POINTING_STICK, dev2->propbit);
2443
2444 if (input_register_device(priv->dev2))
2445 goto init_fail;
2446
2447 psmouse->protocol_handler = alps_process_byte;
2448 psmouse->poll = alps_poll;
2449 psmouse->disconnect = alps_disconnect;
2450 psmouse->reconnect = alps_reconnect;
2451 psmouse->pktsize = priv->proto_version == ALPS_PROTO_V4 ? 8 : 6;
2452
2453
2454 psmouse->resync_time = 0;
2455
2456 return 0;
2457
2458init_fail:
2459 psmouse_reset(psmouse);
2460 input_free_device(dev2);
2461 kfree(priv);
2462 psmouse->private = NULL;
2463 return -1;
2464}
2465
2466int alps_detect(struct psmouse *psmouse, bool set_properties)
2467{
2468 struct alps_data dummy;
2469
2470 if (alps_identify(psmouse, &dummy) < 0)
2471 return -1;
2472
2473 if (set_properties) {
2474 psmouse->vendor = "ALPS";
2475 psmouse->name = dummy.flags & ALPS_DUALPOINT ?
2476 "DualPoint TouchPad" : "GlidePoint";
2477 psmouse->model = dummy.proto_version << 8;
2478 }
2479 return 0;
2480}
2481
2482