1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <linux/module.h>
27#include <linux/delay.h>
28#include <linux/dmi.h>
29#include <linux/input/mt.h>
30#include <linux/serio.h>
31#include <linux/libps2.h>
32#include <linux/slab.h>
33#include "psmouse.h"
34#include "synaptics.h"
35
36
37
38
39
40
41
42
43#define XMIN 0
44#define XMAX 6143
45#define YMIN 0
46#define YMAX 6143
47#define XMIN_NOMINAL 1472
48#define XMAX_NOMINAL 5472
49#define YMIN_NOMINAL 1408
50#define YMAX_NOMINAL 4448
51
52
53#define ABS_POS_BITS 13
54
55
56
57
58
59
60
61
62
63
64
65
66
67#define X_MAX_POSITIVE 8176
68#define Y_MAX_POSITIVE 8176
69
70
71
72
73
74
75
76
77static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode)
78{
79 unsigned char param[1];
80
81 if (psmouse_sliced_command(psmouse, mode))
82 return -1;
83 param[0] = SYN_PS_SET_MODE2;
84 if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_SETRATE))
85 return -1;
86 return 0;
87}
88
89int synaptics_detect(struct psmouse *psmouse, bool set_properties)
90{
91 struct ps2dev *ps2dev = &psmouse->ps2dev;
92 unsigned char param[4];
93
94 param[0] = 0;
95
96 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
97 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
98 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
99 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
100 ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
101
102 if (param[1] != 0x47)
103 return -ENODEV;
104
105 if (set_properties) {
106 psmouse->vendor = "Synaptics";
107 psmouse->name = "TouchPad";
108 }
109
110 return 0;
111}
112
113void synaptics_reset(struct psmouse *psmouse)
114{
115
116 synaptics_mode_cmd(psmouse, 0);
117}
118
119#ifdef CONFIG_MOUSE_PS2_SYNAPTICS
120
121#define ANY_BOARD_ID 0
122struct min_max_quirk {
123 const char * const *pnp_ids;
124 struct {
125 unsigned long int min, max;
126 } board_id;
127 int x_min, x_max, y_min, y_max;
128};
129
130static const struct min_max_quirk min_max_pnpid_table[] = {
131 {
132 (const char * const []){"LEN0033", NULL},
133 {ANY_BOARD_ID, ANY_BOARD_ID},
134 1024, 5052, 2258, 4832
135 },
136 {
137 (const char * const []){"LEN0042", NULL},
138 {ANY_BOARD_ID, ANY_BOARD_ID},
139 1232, 5710, 1156, 4696
140 },
141 {
142 (const char * const []){"LEN0034", "LEN0036", "LEN0037",
143 "LEN0039", "LEN2002", "LEN2004",
144 NULL},
145 {ANY_BOARD_ID, 2961},
146 1024, 5112, 2024, 4832
147 },
148 {
149 (const char * const []){"LEN2001", NULL},
150 {ANY_BOARD_ID, ANY_BOARD_ID},
151 1024, 5022, 2508, 4832
152 },
153 {
154 (const char * const []){"LEN2006", NULL},
155 {ANY_BOARD_ID, ANY_BOARD_ID},
156 1264, 5675, 1171, 4688
157 },
158 { }
159};
160
161
162static const char * const topbuttonpad_pnp_ids[] = {
163 "LEN0017",
164 "LEN0018",
165 "LEN0019",
166 "LEN0023",
167 "LEN002A",
168 "LEN002B",
169 "LEN002C",
170 "LEN002D",
171 "LEN002E",
172 "LEN0033",
173 "LEN0034",
174 "LEN0035",
175 "LEN0036",
176 "LEN0037",
177 "LEN0038",
178 "LEN0039",
179 "LEN0041",
180 "LEN0042",
181 "LEN0045",
182 "LEN0047",
183 "LEN0049",
184 "LEN2000",
185 "LEN2001",
186 "LEN2002",
187 "LEN2003",
188 "LEN2004",
189 "LEN2005",
190 "LEN2006",
191 "LEN2007",
192 "LEN2008",
193 "LEN2009",
194 "LEN200A",
195 "LEN200B",
196 NULL
197};
198
199
200
201
202
203
204
205
206
207
208static int synaptics_invert_y(int y)
209{
210 return YMAX_NOMINAL + YMIN_NOMINAL - y;
211}
212
213
214
215
216static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param)
217{
218 if (psmouse_sliced_command(psmouse, c))
219 return -1;
220 if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO))
221 return -1;
222 return 0;
223}
224
225
226
227
228
229static int synaptics_model_id(struct psmouse *psmouse)
230{
231 struct synaptics_data *priv = psmouse->private;
232 unsigned char mi[3];
233
234 if (synaptics_send_cmd(psmouse, SYN_QUE_MODEL, mi))
235 return -1;
236 priv->model_id = (mi[0]<<16) | (mi[1]<<8) | mi[2];
237 return 0;
238}
239
240static int synaptics_more_extended_queries(struct psmouse *psmouse)
241{
242 struct synaptics_data *priv = psmouse->private;
243 unsigned char buf[3];
244
245 if (synaptics_send_cmd(psmouse, SYN_QUE_MEXT_CAPAB_10, buf))
246 return -1;
247
248 priv->ext_cap_10 = (buf[0]<<16) | (buf[1]<<8) | buf[2];
249
250 return 0;
251}
252
253
254
255
256
257static int synaptics_query_modes(struct psmouse *psmouse)
258{
259 struct synaptics_data *priv = psmouse->private;
260 unsigned char bid[3];
261
262
263 if (SYN_ID_FULL(priv->identity) < 0x705)
264 return 0;
265
266 if (synaptics_send_cmd(psmouse, SYN_QUE_MODES, bid))
267 return -1;
268 priv->board_id = ((bid[0] & 0xfc) << 6) | bid[1];
269
270 if (SYN_MEXT_CAP_BIT(bid[0]))
271 return synaptics_more_extended_queries(psmouse);
272
273 return 0;
274}
275
276
277
278
279static int synaptics_firmware_id(struct psmouse *psmouse)
280{
281 struct synaptics_data *priv = psmouse->private;
282 unsigned char fwid[3];
283
284 if (synaptics_send_cmd(psmouse, SYN_QUE_FIRMWARE_ID, fwid))
285 return -1;
286 priv->firmware_id = (fwid[0] << 16) | (fwid[1] << 8) | fwid[2];
287 return 0;
288}
289
290
291
292
293
294static int synaptics_capability(struct psmouse *psmouse)
295{
296 struct synaptics_data *priv = psmouse->private;
297 unsigned char cap[3];
298
299 if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap))
300 return -1;
301 priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2];
302 priv->ext_cap = priv->ext_cap_0c = 0;
303
304
305
306
307 if (SYN_ID_FULL(priv->identity) < 0x705 &&
308 SYN_CAP_SUBMODEL_ID(priv->capabilities) != 0x47) {
309 return -1;
310 }
311
312
313
314
315 if (!SYN_CAP_EXTENDED(priv->capabilities))
316 priv->capabilities = 0;
317
318 if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) {
319 if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) {
320 psmouse_warn(psmouse,
321 "device claims to have extended capabilities, but I'm not able to read them.\n");
322 } else {
323 priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2];
324
325
326
327
328
329 if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) > 8)
330 priv->ext_cap &= 0xff0fff;
331 }
332 }
333
334 if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 4) {
335 if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB_0C, cap)) {
336 psmouse_warn(psmouse,
337 "device claims to have extended capability 0x0c, but I'm not able to read it.\n");
338 } else {
339 priv->ext_cap_0c = (cap[0] << 16) | (cap[1] << 8) | cap[2];
340 }
341 }
342
343 return 0;
344}
345
346
347
348
349
350static int synaptics_identify(struct psmouse *psmouse)
351{
352 struct synaptics_data *priv = psmouse->private;
353 unsigned char id[3];
354
355 if (synaptics_send_cmd(psmouse, SYN_QUE_IDENTIFY, id))
356 return -1;
357 priv->identity = (id[0]<<16) | (id[1]<<8) | id[2];
358 if (SYN_ID_IS_SYNAPTICS(priv->identity))
359 return 0;
360 return -1;
361}
362
363
364
365
366
367
368static int synaptics_resolution(struct psmouse *psmouse)
369{
370 struct synaptics_data *priv = psmouse->private;
371 unsigned char resp[3];
372
373 if (SYN_ID_MAJOR(priv->identity) < 4)
374 return 0;
375
376 if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, resp) == 0) {
377 if (resp[0] != 0 && (resp[1] & 0x80) && resp[2] != 0) {
378 priv->x_res = resp[0];
379 priv->y_res = resp[2];
380 }
381 }
382
383 if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 &&
384 SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) {
385 if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MAX_COORDS, resp)) {
386 psmouse_warn(psmouse,
387 "device claims to have max coordinates query, but I'm not able to read it.\n");
388 } else {
389 priv->x_max = (resp[0] << 5) | ((resp[1] & 0x0f) << 1);
390 priv->y_max = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3);
391 psmouse_info(psmouse,
392 "queried max coordinates: x [..%d], y [..%d]\n",
393 priv->x_max, priv->y_max);
394 }
395 }
396
397 if (SYN_CAP_MIN_DIMENSIONS(priv->ext_cap_0c) &&
398 (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 7 ||
399
400
401
402
403
404 SYN_ID_FULL(priv->identity) == 0x801)) {
405 if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MIN_COORDS, resp)) {
406 psmouse_warn(psmouse,
407 "device claims to have min coordinates query, but I'm not able to read it.\n");
408 } else {
409 priv->x_min = (resp[0] << 5) | ((resp[1] & 0x0f) << 1);
410 priv->y_min = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3);
411 psmouse_info(psmouse,
412 "queried min coordinates: x [%d..], y [%d..]\n",
413 priv->x_min, priv->y_min);
414 }
415 }
416
417 return 0;
418}
419
420
421
422
423
424static void synaptics_apply_quirks(struct psmouse *psmouse)
425{
426 struct synaptics_data *priv = psmouse->private;
427 int i;
428
429 for (i = 0; min_max_pnpid_table[i].pnp_ids; i++) {
430 if (!psmouse_matches_pnp_id(psmouse,
431 min_max_pnpid_table[i].pnp_ids))
432 continue;
433
434 if (min_max_pnpid_table[i].board_id.min != ANY_BOARD_ID &&
435 priv->board_id < min_max_pnpid_table[i].board_id.min)
436 continue;
437
438 if (min_max_pnpid_table[i].board_id.max != ANY_BOARD_ID &&
439 priv->board_id > min_max_pnpid_table[i].board_id.max)
440 continue;
441
442 priv->x_min = min_max_pnpid_table[i].x_min;
443 priv->x_max = min_max_pnpid_table[i].x_max;
444 priv->y_min = min_max_pnpid_table[i].y_min;
445 priv->y_max = min_max_pnpid_table[i].y_max;
446 psmouse_info(psmouse,
447 "quirked min/max coordinates: x [%d..%d], y [%d..%d]\n",
448 priv->x_min, priv->x_max,
449 priv->y_min, priv->y_max);
450 break;
451 }
452}
453
454static int synaptics_query_hardware(struct psmouse *psmouse)
455{
456 if (synaptics_identify(psmouse))
457 return -1;
458 if (synaptics_model_id(psmouse))
459 return -1;
460 if (synaptics_firmware_id(psmouse))
461 return -1;
462 if (synaptics_query_modes(psmouse))
463 return -1;
464 if (synaptics_capability(psmouse))
465 return -1;
466 if (synaptics_resolution(psmouse))
467 return -1;
468
469 synaptics_apply_quirks(psmouse);
470
471 return 0;
472}
473
474static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)
475{
476 static unsigned char param = 0xc8;
477 struct synaptics_data *priv = psmouse->private;
478
479 if (!(SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) ||
480 SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)))
481 return 0;
482
483 if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL))
484 return -1;
485
486 if (ps2_command(&psmouse->ps2dev, ¶m, PSMOUSE_CMD_SETRATE))
487 return -1;
488
489
490 priv->capabilities |= BIT(1);
491
492 return 0;
493}
494
495static int synaptics_set_mode(struct psmouse *psmouse)
496{
497 struct synaptics_data *priv = psmouse->private;
498
499 priv->mode = 0;
500 if (priv->absolute_mode)
501 priv->mode |= SYN_BIT_ABSOLUTE_MODE;
502 if (priv->disable_gesture)
503 priv->mode |= SYN_BIT_DISABLE_GESTURE;
504 if (psmouse->rate >= 80)
505 priv->mode |= SYN_BIT_HIGH_RATE;
506 if (SYN_CAP_EXTENDED(priv->capabilities))
507 priv->mode |= SYN_BIT_W_MODE;
508
509 if (synaptics_mode_cmd(psmouse, priv->mode))
510 return -1;
511
512 if (priv->absolute_mode &&
513 synaptics_set_advanced_gesture_mode(psmouse)) {
514 psmouse_err(psmouse, "Advanced gesture mode init failed.\n");
515 return -1;
516 }
517
518 return 0;
519}
520
521static void synaptics_set_rate(struct psmouse *psmouse, unsigned int rate)
522{
523 struct synaptics_data *priv = psmouse->private;
524
525 if (rate >= 80) {
526 priv->mode |= SYN_BIT_HIGH_RATE;
527 psmouse->rate = 80;
528 } else {
529 priv->mode &= ~SYN_BIT_HIGH_RATE;
530 psmouse->rate = 40;
531 }
532
533 synaptics_mode_cmd(psmouse, priv->mode);
534}
535
536
537
538
539static int synaptics_pt_write(struct serio *serio, unsigned char c)
540{
541 struct psmouse *parent = serio_get_drvdata(serio->parent);
542 char rate_param = SYN_PS_CLIENT_CMD;
543
544 if (psmouse_sliced_command(parent, c))
545 return -1;
546 if (ps2_command(&parent->ps2dev, &rate_param, PSMOUSE_CMD_SETRATE))
547 return -1;
548 return 0;
549}
550
551static int synaptics_pt_start(struct serio *serio)
552{
553 struct psmouse *parent = serio_get_drvdata(serio->parent);
554 struct synaptics_data *priv = parent->private;
555
556 serio_pause_rx(parent->ps2dev.serio);
557 priv->pt_port = serio;
558 serio_continue_rx(parent->ps2dev.serio);
559
560 return 0;
561}
562
563static void synaptics_pt_stop(struct serio *serio)
564{
565 struct psmouse *parent = serio_get_drvdata(serio->parent);
566 struct synaptics_data *priv = parent->private;
567
568 serio_pause_rx(parent->ps2dev.serio);
569 priv->pt_port = NULL;
570 serio_continue_rx(parent->ps2dev.serio);
571}
572
573static int synaptics_is_pt_packet(unsigned char *buf)
574{
575 return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4;
576}
577
578static void synaptics_pass_pt_packet(struct psmouse *psmouse,
579 struct serio *ptport,
580 unsigned char *packet)
581{
582 struct synaptics_data *priv = psmouse->private;
583 struct psmouse *child = serio_get_drvdata(ptport);
584
585 if (child && child->state == PSMOUSE_ACTIVATED) {
586 serio_interrupt(ptport, packet[1] | priv->pt_buttons, 0);
587 serio_interrupt(ptport, packet[4], 0);
588 serio_interrupt(ptport, packet[5], 0);
589 if (child->pktsize == 4)
590 serio_interrupt(ptport, packet[2], 0);
591 } else {
592 serio_interrupt(ptport, packet[1], 0);
593 }
594}
595
596static void synaptics_pt_activate(struct psmouse *psmouse)
597{
598 struct synaptics_data *priv = psmouse->private;
599 struct psmouse *child = serio_get_drvdata(priv->pt_port);
600
601
602 if (child) {
603 if (child->pktsize == 4)
604 priv->mode |= SYN_BIT_FOUR_BYTE_CLIENT;
605 else
606 priv->mode &= ~SYN_BIT_FOUR_BYTE_CLIENT;
607
608 if (synaptics_mode_cmd(psmouse, priv->mode))
609 psmouse_warn(psmouse,
610 "failed to switch guest protocol\n");
611 }
612}
613
614static void synaptics_pt_create(struct psmouse *psmouse)
615{
616 struct serio *serio;
617
618 serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
619 if (!serio) {
620 psmouse_err(psmouse,
621 "not enough memory for pass-through port\n");
622 return;
623 }
624
625 serio->id.type = SERIO_PS_PSTHRU;
626 strlcpy(serio->name, "Synaptics pass-through", sizeof(serio->name));
627 strlcpy(serio->phys, "synaptics-pt/serio0", sizeof(serio->name));
628 serio->write = synaptics_pt_write;
629 serio->start = synaptics_pt_start;
630 serio->stop = synaptics_pt_stop;
631 serio->parent = psmouse->ps2dev.serio;
632
633 psmouse->pt_activate = synaptics_pt_activate;
634
635 psmouse_info(psmouse, "serio: %s port at %s\n",
636 serio->name, psmouse->phys);
637 serio_register_port(serio);
638}
639
640
641
642
643
644static void synaptics_mt_state_set(struct synaptics_mt_state *state, int count,
645 int sgm, int agm)
646{
647 state->count = count;
648 state->sgm = sgm;
649 state->agm = agm;
650}
651
652static void synaptics_parse_agm(const unsigned char buf[],
653 struct synaptics_data *priv,
654 struct synaptics_hw_state *hw)
655{
656 struct synaptics_hw_state *agm = &priv->agm;
657 int agm_packet_type;
658
659 agm_packet_type = (buf[5] & 0x30) >> 4;
660 switch (agm_packet_type) {
661 case 1:
662
663 agm->w = hw->w;
664 agm->x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1;
665 agm->y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1;
666 agm->z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1;
667 break;
668
669 case 2:
670
671 synaptics_mt_state_set(&agm->mt_state, buf[1], buf[2], buf[4]);
672 break;
673
674 default:
675 break;
676 }
677
678
679 priv->agm_pending = true;
680}
681
682static void synaptics_parse_ext_buttons(const unsigned char buf[],
683 struct synaptics_data *priv,
684 struct synaptics_hw_state *hw)
685{
686 unsigned int ext_bits =
687 (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) + 1) >> 1;
688 unsigned int ext_mask = GENMASK(ext_bits - 1, 0);
689
690 hw->ext_buttons = buf[4] & ext_mask;
691 hw->ext_buttons |= (buf[5] & ext_mask) << ext_bits;
692}
693
694static int synaptics_parse_hw_state(const unsigned char buf[],
695 struct synaptics_data *priv,
696 struct synaptics_hw_state *hw)
697{
698 memset(hw, 0, sizeof(struct synaptics_hw_state));
699
700 if (SYN_MODEL_NEWABS(priv->model_id)) {
701 hw->w = (((buf[0] & 0x30) >> 2) |
702 ((buf[0] & 0x04) >> 1) |
703 ((buf[3] & 0x04) >> 2));
704
705 hw->left = (buf[0] & 0x01) ? 1 : 0;
706 hw->right = (buf[0] & 0x02) ? 1 : 0;
707
708 if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
709
710
711
712
713
714 hw->left = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
715
716 } else if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) {
717 hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
718 if (hw->w == 2)
719 hw->scroll = (signed char)(buf[1]);
720 }
721
722 if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) {
723 hw->up = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
724 hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0;
725 }
726
727 if ((SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) ||
728 SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) &&
729 hw->w == 2) {
730 synaptics_parse_agm(buf, priv, hw);
731 return 1;
732 }
733
734 hw->x = (((buf[3] & 0x10) << 8) |
735 ((buf[1] & 0x0f) << 8) |
736 buf[4]);
737 hw->y = (((buf[3] & 0x20) << 7) |
738 ((buf[1] & 0xf0) << 4) |
739 buf[5]);
740 hw->z = buf[2];
741
742 if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) > 0 &&
743 ((buf[0] ^ buf[3]) & 0x02)) {
744 synaptics_parse_ext_buttons(buf, priv, hw);
745 }
746 } else {
747 hw->x = (((buf[1] & 0x1f) << 8) | buf[2]);
748 hw->y = (((buf[4] & 0x1f) << 8) | buf[5]);
749
750 hw->z = (((buf[0] & 0x30) << 2) | (buf[3] & 0x3F));
751 hw->w = (((buf[1] & 0x80) >> 4) | ((buf[0] & 0x04) >> 1));
752
753 hw->left = (buf[0] & 0x01) ? 1 : 0;
754 hw->right = (buf[0] & 0x02) ? 1 : 0;
755 }
756
757
758
759
760
761
762
763 if (hw->x > X_MAX_POSITIVE)
764 hw->x -= 1 << ABS_POS_BITS;
765 else if (hw->x == X_MAX_POSITIVE)
766 hw->x = XMAX;
767
768 if (hw->y > Y_MAX_POSITIVE)
769 hw->y -= 1 << ABS_POS_BITS;
770 else if (hw->y == Y_MAX_POSITIVE)
771 hw->y = YMAX;
772
773 return 0;
774}
775
776static void synaptics_report_semi_mt_slot(struct input_dev *dev, int slot,
777 bool active, int x, int y)
778{
779 input_mt_slot(dev, slot);
780 input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
781 if (active) {
782 input_report_abs(dev, ABS_MT_POSITION_X, x);
783 input_report_abs(dev, ABS_MT_POSITION_Y, synaptics_invert_y(y));
784 }
785}
786
787static void synaptics_report_semi_mt_data(struct input_dev *dev,
788 const struct synaptics_hw_state *a,
789 const struct synaptics_hw_state *b,
790 int num_fingers)
791{
792 if (num_fingers >= 2) {
793 synaptics_report_semi_mt_slot(dev, 0, true, min(a->x, b->x),
794 min(a->y, b->y));
795 synaptics_report_semi_mt_slot(dev, 1, true, max(a->x, b->x),
796 max(a->y, b->y));
797 } else if (num_fingers == 1) {
798 synaptics_report_semi_mt_slot(dev, 0, true, a->x, a->y);
799 synaptics_report_semi_mt_slot(dev, 1, false, 0, 0);
800 } else {
801 synaptics_report_semi_mt_slot(dev, 0, false, 0, 0);
802 synaptics_report_semi_mt_slot(dev, 1, false, 0, 0);
803 }
804}
805
806static void synaptics_report_ext_buttons(struct psmouse *psmouse,
807 const struct synaptics_hw_state *hw)
808{
809 struct input_dev *dev = psmouse->dev;
810 struct synaptics_data *priv = psmouse->private;
811 int ext_bits = (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) + 1) >> 1;
812 char buf[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
813 int i;
814
815 if (!SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))
816 return;
817
818
819 if ((SYN_ID_FULL(priv->identity) == 0x801 ||
820 SYN_ID_FULL(priv->identity) == 0x802) &&
821 !((psmouse->packet[0] ^ psmouse->packet[3]) & 0x02))
822 return;
823
824 if (!SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10)) {
825 for (i = 0; i < ext_bits; i++) {
826 input_report_key(dev, BTN_0 + 2 * i,
827 hw->ext_buttons & (1 << i));
828 input_report_key(dev, BTN_1 + 2 * i,
829 hw->ext_buttons & (1 << (i + ext_bits)));
830 }
831 return;
832 }
833
834
835
836
837
838
839 if (!priv->pt_port)
840 return;
841
842
843 priv->pt_buttons = SYN_CAP_EXT_BUTTON_STICK_L(hw->ext_buttons) |
844 SYN_CAP_EXT_BUTTON_STICK_R(hw->ext_buttons) << 1 |
845 SYN_CAP_EXT_BUTTON_STICK_M(hw->ext_buttons) << 2;
846
847 synaptics_pass_pt_packet(psmouse, priv->pt_port, buf);
848}
849
850static void synaptics_report_buttons(struct psmouse *psmouse,
851 const struct synaptics_hw_state *hw)
852{
853 struct input_dev *dev = psmouse->dev;
854 struct synaptics_data *priv = psmouse->private;
855
856 input_report_key(dev, BTN_LEFT, hw->left);
857 input_report_key(dev, BTN_RIGHT, hw->right);
858
859 if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
860 input_report_key(dev, BTN_MIDDLE, hw->middle);
861
862 if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) {
863 input_report_key(dev, BTN_FORWARD, hw->up);
864 input_report_key(dev, BTN_BACK, hw->down);
865 }
866
867 synaptics_report_ext_buttons(psmouse, hw);
868}
869
870static void synaptics_report_slot(struct input_dev *dev, int slot,
871 const struct synaptics_hw_state *hw)
872{
873 input_mt_slot(dev, slot);
874 input_mt_report_slot_state(dev, MT_TOOL_FINGER, (hw != NULL));
875 if (!hw)
876 return;
877
878 input_report_abs(dev, ABS_MT_POSITION_X, hw->x);
879 input_report_abs(dev, ABS_MT_POSITION_Y, synaptics_invert_y(hw->y));
880 input_report_abs(dev, ABS_MT_PRESSURE, hw->z);
881}
882
883static void synaptics_report_mt_data(struct psmouse *psmouse,
884 struct synaptics_mt_state *mt_state,
885 const struct synaptics_hw_state *sgm)
886{
887 struct input_dev *dev = psmouse->dev;
888 struct synaptics_data *priv = psmouse->private;
889 struct synaptics_hw_state *agm = &priv->agm;
890 struct synaptics_mt_state *old = &priv->mt_state;
891
892 switch (mt_state->count) {
893 case 0:
894 synaptics_report_slot(dev, 0, NULL);
895 synaptics_report_slot(dev, 1, NULL);
896 break;
897 case 1:
898 if (mt_state->sgm == -1) {
899 synaptics_report_slot(dev, 0, NULL);
900 synaptics_report_slot(dev, 1, NULL);
901 } else if (mt_state->sgm == 0) {
902 synaptics_report_slot(dev, 0, sgm);
903 synaptics_report_slot(dev, 1, NULL);
904 } else {
905 synaptics_report_slot(dev, 0, NULL);
906 synaptics_report_slot(dev, 1, sgm);
907 }
908 break;
909 default:
910
911
912
913
914
915
916 if (mt_state->sgm != -1 &&
917 (mt_state->sgm == old->sgm ||
918 old->sgm == -1 || mt_state->agm == old->sgm))
919 synaptics_report_slot(dev, 0, sgm);
920 else
921 synaptics_report_slot(dev, 0, NULL);
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948 if (mt_state->agm != -1 &&
949 (mt_state->agm == old->agm ||
950 (old->agm == -1 &&
951 (old->sgm == -1 || mt_state->agm == old->sgm))))
952 synaptics_report_slot(dev, 1, agm);
953 else
954 synaptics_report_slot(dev, 1, NULL);
955 break;
956 }
957
958
959 input_mt_report_pointer_emulation(dev, false);
960
961
962 input_mt_report_finger_count(dev, mt_state->count);
963
964 synaptics_report_buttons(psmouse, sgm);
965
966 input_sync(dev);
967}
968
969
970static void synaptics_image_sensor_0f(struct synaptics_data *priv,
971 struct synaptics_mt_state *mt_state)
972{
973 synaptics_mt_state_set(mt_state, 0, -1, -1);
974 priv->mt_state_lost = false;
975}
976
977
978static void synaptics_image_sensor_1f(struct synaptics_data *priv,
979 struct synaptics_mt_state *mt_state)
980{
981 struct synaptics_hw_state *agm = &priv->agm;
982 struct synaptics_mt_state *old = &priv->mt_state;
983
984
985
986
987
988
989 if (priv->agm_pending && agm->z == 0) {
990 synaptics_mt_state_set(mt_state, 1, 0, -1);
991 priv->mt_state_lost = false;
992 return;
993 }
994
995 switch (old->count) {
996 case 0:
997 synaptics_mt_state_set(mt_state, 1, 0, -1);
998 break;
999 case 1:
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025 if (priv->mt_state_lost ||
1026 (priv->agm_pending && old->sgm <= 0))
1027 synaptics_mt_state_set(mt_state, 1, 1, -1);
1028 else if (old->sgm == -1)
1029 synaptics_mt_state_set(mt_state, 1, 0, -1);
1030 break;
1031 case 2:
1032
1033
1034
1035
1036
1037
1038 if (priv->mt_state_lost) {
1039 synaptics_mt_state_set(mt_state, 1, -1, -1);
1040 break;
1041 }
1042
1043
1044
1045
1046
1047
1048 synaptics_mt_state_set(mt_state, 1, old->agm, -1);
1049 break;
1050 case 3:
1051
1052
1053
1054
1055
1056
1057
1058 synaptics_mt_state_set(mt_state, 1, -1, -1);
1059 priv->mt_state_lost = true;
1060 break;
1061 case 4:
1062 case 5:
1063
1064 break;
1065 }
1066}
1067
1068
1069static void synaptics_image_sensor_2f(struct synaptics_data *priv,
1070 struct synaptics_mt_state *mt_state)
1071{
1072 struct synaptics_mt_state *old = &priv->mt_state;
1073
1074 switch (old->count) {
1075 case 0:
1076 synaptics_mt_state_set(mt_state, 2, 0, 1);
1077 break;
1078 case 1:
1079
1080
1081
1082
1083
1084
1085
1086
1087 if (old->sgm >= 1)
1088 synaptics_mt_state_set(mt_state, 2, 0, old->sgm);
1089 else
1090 synaptics_mt_state_set(mt_state, 2, 0, 1);
1091 break;
1092 case 2:
1093
1094
1095
1096
1097
1098 if (priv->mt_state_lost)
1099 synaptics_mt_state_set(mt_state, 2, 0, 1);
1100
1101
1102
1103
1104
1105 break;
1106 case 3:
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116 synaptics_mt_state_set(mt_state, 2, -1, -1);
1117 priv->mt_state_lost = true;
1118 break;
1119 case 4:
1120 case 5:
1121
1122 break;
1123 }
1124}
1125
1126
1127static void synaptics_image_sensor_3f(struct synaptics_data *priv,
1128 struct synaptics_mt_state *mt_state)
1129{
1130 struct synaptics_mt_state *old = &priv->mt_state;
1131
1132 switch (old->count) {
1133 case 0:
1134 synaptics_mt_state_set(mt_state, 3, 0, 2);
1135 break;
1136 case 1:
1137
1138
1139
1140
1141
1142
1143
1144 if (old->sgm >= 2)
1145 synaptics_mt_state_set(mt_state, 3, 0, old->sgm);
1146 else
1147 synaptics_mt_state_set(mt_state, 3, 0, 2);
1148 break;
1149 case 2:
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161 if (old->agm >= 3) {
1162 synaptics_mt_state_set(mt_state, 3, 0, old->agm);
1163 break;
1164 }
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176 if (priv->mt_state_lost) {
1177 synaptics_mt_state_set(mt_state, 3, -1, -1);
1178 break;
1179 }
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192 synaptics_mt_state_set(mt_state, 3, 0, -1);
1193 break;
1194 case 3:
1195
1196
1197
1198
1199 if (old->agm <= 2)
1200 synaptics_mt_state_set(mt_state, 3, 0, 2);
1201
1202
1203
1204
1205 break;
1206
1207 case 4:
1208 case 5:
1209
1210 break;
1211 }
1212}
1213
1214
1215static void synaptics_image_sensor_45f(struct synaptics_data *priv,
1216 struct synaptics_mt_state *mt_state)
1217{
1218
1219 priv->mt_state_lost = false;
1220}
1221
1222static void synaptics_image_sensor_process(struct psmouse *psmouse,
1223 struct synaptics_hw_state *sgm)
1224{
1225 struct synaptics_data *priv = psmouse->private;
1226 struct synaptics_hw_state *agm = &priv->agm;
1227 struct synaptics_mt_state mt_state;
1228
1229
1230 mt_state = agm->mt_state;
1231
1232
1233
1234
1235 if (sgm->z == 0)
1236 synaptics_image_sensor_0f(priv, &mt_state);
1237 else if (sgm->w >= 4)
1238 synaptics_image_sensor_1f(priv, &mt_state);
1239 else if (sgm->w == 0)
1240 synaptics_image_sensor_2f(priv, &mt_state);
1241 else if (sgm->w == 1 && mt_state.count <= 3)
1242 synaptics_image_sensor_3f(priv, &mt_state);
1243 else
1244 synaptics_image_sensor_45f(priv, &mt_state);
1245
1246
1247 synaptics_report_mt_data(psmouse, &mt_state, sgm);
1248
1249
1250 priv->mt_state = agm->mt_state = mt_state;
1251 priv->agm_pending = false;
1252}
1253
1254
1255
1256
1257static void synaptics_process_packet(struct psmouse *psmouse)
1258{
1259 struct input_dev *dev = psmouse->dev;
1260 struct synaptics_data *priv = psmouse->private;
1261 struct synaptics_hw_state hw;
1262 int num_fingers;
1263 int finger_width;
1264
1265 if (synaptics_parse_hw_state(psmouse->packet, priv, &hw))
1266 return;
1267
1268 if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) {
1269 synaptics_image_sensor_process(psmouse, &hw);
1270 return;
1271 }
1272
1273 if (hw.scroll) {
1274 priv->scroll += hw.scroll;
1275
1276 while (priv->scroll >= 4) {
1277 input_report_key(dev, BTN_BACK, !hw.down);
1278 input_sync(dev);
1279 input_report_key(dev, BTN_BACK, hw.down);
1280 input_sync(dev);
1281 priv->scroll -= 4;
1282 }
1283 while (priv->scroll <= -4) {
1284 input_report_key(dev, BTN_FORWARD, !hw.up);
1285 input_sync(dev);
1286 input_report_key(dev, BTN_FORWARD, hw.up);
1287 input_sync(dev);
1288 priv->scroll += 4;
1289 }
1290 return;
1291 }
1292
1293 if (hw.z > 0 && hw.x > 1) {
1294 num_fingers = 1;
1295 finger_width = 5;
1296 if (SYN_CAP_EXTENDED(priv->capabilities)) {
1297 switch (hw.w) {
1298 case 0 ... 1:
1299 if (SYN_CAP_MULTIFINGER(priv->capabilities))
1300 num_fingers = hw.w + 2;
1301 break;
1302 case 2:
1303 if (SYN_MODEL_PEN(priv->model_id))
1304 ;
1305 break;
1306 case 4 ... 15:
1307 if (SYN_CAP_PALMDETECT(priv->capabilities))
1308 finger_width = hw.w;
1309 break;
1310 }
1311 }
1312 } else {
1313 num_fingers = 0;
1314 finger_width = 0;
1315 }
1316
1317 if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c))
1318 synaptics_report_semi_mt_data(dev, &hw, &priv->agm,
1319 num_fingers);
1320
1321
1322
1323
1324
1325 if (hw.z > 30) input_report_key(dev, BTN_TOUCH, 1);
1326 if (hw.z < 25) input_report_key(dev, BTN_TOUCH, 0);
1327
1328 if (num_fingers > 0) {
1329 input_report_abs(dev, ABS_X, hw.x);
1330 input_report_abs(dev, ABS_Y, synaptics_invert_y(hw.y));
1331 }
1332 input_report_abs(dev, ABS_PRESSURE, hw.z);
1333
1334 if (SYN_CAP_PALMDETECT(priv->capabilities))
1335 input_report_abs(dev, ABS_TOOL_WIDTH, finger_width);
1336
1337 input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1);
1338 if (SYN_CAP_MULTIFINGER(priv->capabilities)) {
1339 input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2);
1340 input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3);
1341 }
1342
1343 synaptics_report_buttons(psmouse, &hw);
1344
1345 input_sync(dev);
1346}
1347
1348static int synaptics_validate_byte(struct psmouse *psmouse,
1349 int idx, unsigned char pkt_type)
1350{
1351 static const unsigned char newabs_mask[] = { 0xC8, 0x00, 0x00, 0xC8, 0x00 };
1352 static const unsigned char newabs_rel_mask[] = { 0xC0, 0x00, 0x00, 0xC0, 0x00 };
1353 static const unsigned char newabs_rslt[] = { 0x80, 0x00, 0x00, 0xC0, 0x00 };
1354 static const unsigned char oldabs_mask[] = { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
1355 static const unsigned char oldabs_rslt[] = { 0xC0, 0x00, 0x00, 0x80, 0x00 };
1356 const char *packet = psmouse->packet;
1357
1358 if (idx < 0 || idx > 4)
1359 return 0;
1360
1361 switch (pkt_type) {
1362
1363 case SYN_NEWABS:
1364 case SYN_NEWABS_RELAXED:
1365 return (packet[idx] & newabs_rel_mask[idx]) == newabs_rslt[idx];
1366
1367 case SYN_NEWABS_STRICT:
1368 return (packet[idx] & newabs_mask[idx]) == newabs_rslt[idx];
1369
1370 case SYN_OLDABS:
1371 return (packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx];
1372
1373 default:
1374 psmouse_err(psmouse, "unknown packet type %d\n", pkt_type);
1375 return 0;
1376 }
1377}
1378
1379static unsigned char synaptics_detect_pkt_type(struct psmouse *psmouse)
1380{
1381 int i;
1382
1383 for (i = 0; i < 5; i++)
1384 if (!synaptics_validate_byte(psmouse, i, SYN_NEWABS_STRICT)) {
1385 psmouse_info(psmouse, "using relaxed packet validation\n");
1386 return SYN_NEWABS_RELAXED;
1387 }
1388
1389 return SYN_NEWABS_STRICT;
1390}
1391
1392static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse)
1393{
1394 struct synaptics_data *priv = psmouse->private;
1395
1396 if (psmouse->pktcnt >= 6) {
1397 if (unlikely(priv->pkt_type == SYN_NEWABS))
1398 priv->pkt_type = synaptics_detect_pkt_type(psmouse);
1399
1400 if (SYN_CAP_PASS_THROUGH(priv->capabilities) &&
1401 synaptics_is_pt_packet(psmouse->packet)) {
1402 if (priv->pt_port)
1403 synaptics_pass_pt_packet(psmouse, priv->pt_port,
1404 psmouse->packet);
1405 } else
1406 synaptics_process_packet(psmouse);
1407
1408 return PSMOUSE_FULL_PACKET;
1409 }
1410
1411 return synaptics_validate_byte(psmouse, psmouse->pktcnt - 1, priv->pkt_type) ?
1412 PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA;
1413}
1414
1415
1416
1417
1418static void set_abs_position_params(struct input_dev *dev,
1419 struct synaptics_data *priv, int x_code,
1420 int y_code)
1421{
1422 int x_min = priv->x_min ?: XMIN_NOMINAL;
1423 int x_max = priv->x_max ?: XMAX_NOMINAL;
1424 int y_min = priv->y_min ?: YMIN_NOMINAL;
1425 int y_max = priv->y_max ?: YMAX_NOMINAL;
1426 int fuzz = SYN_CAP_REDUCED_FILTERING(priv->ext_cap_0c) ?
1427 SYN_REDUCED_FILTER_FUZZ : 0;
1428
1429 input_set_abs_params(dev, x_code, x_min, x_max, fuzz, 0);
1430 input_set_abs_params(dev, y_code, y_min, y_max, fuzz, 0);
1431 input_abs_set_res(dev, x_code, priv->x_res);
1432 input_abs_set_res(dev, y_code, priv->y_res);
1433}
1434
1435static void set_input_params(struct psmouse *psmouse,
1436 struct synaptics_data *priv)
1437{
1438 struct input_dev *dev = psmouse->dev;
1439 int i;
1440
1441
1442 __set_bit(INPUT_PROP_POINTER, dev->propbit);
1443 __set_bit(EV_KEY, dev->evbit);
1444 __set_bit(BTN_LEFT, dev->keybit);
1445 __set_bit(BTN_RIGHT, dev->keybit);
1446
1447 if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
1448 __set_bit(BTN_MIDDLE, dev->keybit);
1449
1450 if (!priv->absolute_mode) {
1451
1452 __set_bit(EV_REL, dev->evbit);
1453 __set_bit(REL_X, dev->relbit);
1454 __set_bit(REL_Y, dev->relbit);
1455 return;
1456 }
1457
1458
1459 __set_bit(EV_ABS, dev->evbit);
1460 set_abs_position_params(dev, priv, ABS_X, ABS_Y);
1461 input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
1462
1463 if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) {
1464 set_abs_position_params(dev, priv, ABS_MT_POSITION_X,
1465 ABS_MT_POSITION_Y);
1466
1467 input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
1468 input_mt_init_slots(dev, 2, INPUT_MT_POINTER);
1469
1470
1471 __set_bit(BTN_TOOL_QUADTAP, dev->keybit);
1472 __set_bit(BTN_TOOL_QUINTTAP, dev->keybit);
1473 } else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) {
1474
1475 __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
1476 input_mt_init_slots(dev, 2, 0);
1477 set_abs_position_params(dev, priv, ABS_MT_POSITION_X,
1478 ABS_MT_POSITION_Y);
1479 }
1480
1481 if (SYN_CAP_PALMDETECT(priv->capabilities))
1482 input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
1483
1484 __set_bit(BTN_TOUCH, dev->keybit);
1485 __set_bit(BTN_TOOL_FINGER, dev->keybit);
1486
1487 if (SYN_CAP_MULTIFINGER(priv->capabilities)) {
1488 __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
1489 __set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
1490 }
1491
1492 if (SYN_CAP_FOUR_BUTTON(priv->capabilities) ||
1493 SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) {
1494 __set_bit(BTN_FORWARD, dev->keybit);
1495 __set_bit(BTN_BACK, dev->keybit);
1496 }
1497
1498 if (!SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10))
1499 for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++)
1500 __set_bit(BTN_0 + i, dev->keybit);
1501
1502 __clear_bit(EV_REL, dev->evbit);
1503 __clear_bit(REL_X, dev->relbit);
1504 __clear_bit(REL_Y, dev->relbit);
1505
1506 if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
1507 __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
1508 if (psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids) &&
1509 !SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10))
1510 __set_bit(INPUT_PROP_TOPBUTTONPAD, dev->propbit);
1511
1512 __clear_bit(BTN_RIGHT, dev->keybit);
1513 __clear_bit(BTN_MIDDLE, dev->keybit);
1514 }
1515}
1516
1517static ssize_t synaptics_show_disable_gesture(struct psmouse *psmouse,
1518 void *data, char *buf)
1519{
1520 struct synaptics_data *priv = psmouse->private;
1521
1522 return sprintf(buf, "%c\n", priv->disable_gesture ? '1' : '0');
1523}
1524
1525static ssize_t synaptics_set_disable_gesture(struct psmouse *psmouse,
1526 void *data, const char *buf,
1527 size_t len)
1528{
1529 struct synaptics_data *priv = psmouse->private;
1530 unsigned int value;
1531 int err;
1532
1533 err = kstrtouint(buf, 10, &value);
1534 if (err)
1535 return err;
1536
1537 if (value > 1)
1538 return -EINVAL;
1539
1540 if (value == priv->disable_gesture)
1541 return len;
1542
1543 priv->disable_gesture = value;
1544 if (value)
1545 priv->mode |= SYN_BIT_DISABLE_GESTURE;
1546 else
1547 priv->mode &= ~SYN_BIT_DISABLE_GESTURE;
1548
1549 if (synaptics_mode_cmd(psmouse, priv->mode))
1550 return -EIO;
1551
1552 return len;
1553}
1554
1555PSMOUSE_DEFINE_ATTR(disable_gesture, S_IWUSR | S_IRUGO, NULL,
1556 synaptics_show_disable_gesture,
1557 synaptics_set_disable_gesture);
1558
1559static void synaptics_disconnect(struct psmouse *psmouse)
1560{
1561 struct synaptics_data *priv = psmouse->private;
1562
1563 if (!priv->absolute_mode && SYN_ID_DISGEST_SUPPORTED(priv->identity))
1564 device_remove_file(&psmouse->ps2dev.serio->dev,
1565 &psmouse_attr_disable_gesture.dattr);
1566
1567 synaptics_reset(psmouse);
1568 kfree(priv);
1569 psmouse->private = NULL;
1570}
1571
1572static int synaptics_reconnect(struct psmouse *psmouse)
1573{
1574 struct synaptics_data *priv = psmouse->private;
1575 struct synaptics_data old_priv = *priv;
1576 unsigned char param[2];
1577 int retry = 0;
1578 int error;
1579
1580 do {
1581 psmouse_reset(psmouse);
1582 if (retry) {
1583
1584
1585
1586
1587
1588
1589
1590 ssleep(1);
1591 }
1592 ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETID);
1593 error = synaptics_detect(psmouse, 0);
1594 } while (error && ++retry < 3);
1595
1596 if (error)
1597 return -1;
1598
1599 if (retry > 1)
1600 psmouse_dbg(psmouse, "reconnected after %d tries\n", retry);
1601
1602 if (synaptics_query_hardware(psmouse)) {
1603 psmouse_err(psmouse, "Unable to query device.\n");
1604 return -1;
1605 }
1606
1607 if (synaptics_set_mode(psmouse)) {
1608 psmouse_err(psmouse, "Unable to initialize device.\n");
1609 return -1;
1610 }
1611
1612 if (old_priv.identity != priv->identity ||
1613 old_priv.model_id != priv->model_id ||
1614 old_priv.capabilities != priv->capabilities ||
1615 old_priv.ext_cap != priv->ext_cap) {
1616 psmouse_err(psmouse,
1617 "hardware appears to be different: id(%ld-%ld), model(%ld-%ld), caps(%lx-%lx), ext(%lx-%lx).\n",
1618 old_priv.identity, priv->identity,
1619 old_priv.model_id, priv->model_id,
1620 old_priv.capabilities, priv->capabilities,
1621 old_priv.ext_cap, priv->ext_cap);
1622 return -1;
1623 }
1624
1625 return 0;
1626}
1627
1628static bool impaired_toshiba_kbc;
1629
1630static const struct dmi_system_id toshiba_dmi_table[] __initconst = {
1631#if defined(CONFIG_DMI) && defined(CONFIG_X86)
1632 {
1633
1634 .matches = {
1635 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
1636 DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"),
1637 },
1638 },
1639 {
1640
1641 .matches = {
1642 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
1643 DMI_MATCH(DMI_PRODUCT_NAME, "dynabook"),
1644 },
1645 },
1646 {
1647
1648 .matches = {
1649 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
1650 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
1651 },
1652
1653 },
1654 {
1655
1656 .matches = {
1657 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
1658 DMI_MATCH(DMI_PRODUCT_NAME, "Portable PC"),
1659 DMI_MATCH(DMI_PRODUCT_VERSION, "Version 1.0"),
1660 },
1661
1662 },
1663#endif
1664 { }
1665};
1666
1667static bool broken_olpc_ec;
1668
1669static const struct dmi_system_id olpc_dmi_table[] __initconst = {
1670#if defined(CONFIG_DMI) && defined(CONFIG_OLPC)
1671 {
1672
1673 .matches = {
1674 DMI_MATCH(DMI_SYS_VENDOR, "OLPC"),
1675 DMI_MATCH(DMI_PRODUCT_NAME, "XO"),
1676 },
1677 },
1678#endif
1679 { }
1680};
1681
1682void __init synaptics_module_init(void)
1683{
1684 impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table);
1685 broken_olpc_ec = dmi_check_system(olpc_dmi_table);
1686}
1687
1688static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode)
1689{
1690 struct synaptics_data *priv;
1691 int err = -1;
1692
1693
1694
1695
1696
1697
1698
1699 if (absolute_mode && broken_olpc_ec) {
1700 psmouse_info(psmouse,
1701 "OLPC XO detected, not enabling Synaptics protocol.\n");
1702 return -ENODEV;
1703 }
1704
1705 psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL);
1706 if (!priv)
1707 return -ENOMEM;
1708
1709 psmouse_reset(psmouse);
1710
1711 if (synaptics_query_hardware(psmouse)) {
1712 psmouse_err(psmouse, "Unable to query device.\n");
1713 goto init_fail;
1714 }
1715
1716 priv->absolute_mode = absolute_mode;
1717 if (SYN_ID_DISGEST_SUPPORTED(priv->identity))
1718 priv->disable_gesture = true;
1719
1720 if (synaptics_set_mode(psmouse)) {
1721 psmouse_err(psmouse, "Unable to initialize device.\n");
1722 goto init_fail;
1723 }
1724
1725 priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
1726
1727 psmouse_info(psmouse,
1728 "Touchpad model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx, board id: %lu, fw id: %lu\n",
1729 SYN_ID_MODEL(priv->identity),
1730 SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity),
1731 priv->model_id,
1732 priv->capabilities, priv->ext_cap, priv->ext_cap_0c,
1733 priv->board_id, priv->firmware_id);
1734
1735 set_input_params(psmouse, priv);
1736
1737
1738
1739
1740
1741
1742
1743
1744 psmouse->model = ((priv->model_id & 0x00ff0000) >> 8) |
1745 (priv->model_id & 0x000000ff);
1746
1747 if (absolute_mode) {
1748 psmouse->protocol_handler = synaptics_process_byte;
1749 psmouse->pktsize = 6;
1750 } else {
1751
1752 psmouse->protocol_handler = psmouse_process_byte;
1753 psmouse->pktsize = 3;
1754 }
1755
1756 psmouse->set_rate = synaptics_set_rate;
1757 psmouse->disconnect = synaptics_disconnect;
1758 psmouse->reconnect = synaptics_reconnect;
1759 psmouse->cleanup = synaptics_reset;
1760
1761 psmouse->resync_time = 0;
1762
1763 if (SYN_CAP_PASS_THROUGH(priv->capabilities))
1764 synaptics_pt_create(psmouse);
1765
1766
1767
1768
1769
1770
1771 if (psmouse->rate >= 80 && impaired_toshiba_kbc) {
1772 psmouse_info(psmouse,
1773 "Toshiba %s detected, limiting rate to 40pps.\n",
1774 dmi_get_system_info(DMI_PRODUCT_NAME));
1775 psmouse->rate = 40;
1776 }
1777
1778 if (!priv->absolute_mode && SYN_ID_DISGEST_SUPPORTED(priv->identity)) {
1779 err = device_create_file(&psmouse->ps2dev.serio->dev,
1780 &psmouse_attr_disable_gesture.dattr);
1781 if (err) {
1782 psmouse_err(psmouse,
1783 "Failed to create disable_gesture attribute (%d)",
1784 err);
1785 goto init_fail;
1786 }
1787 }
1788
1789 return 0;
1790
1791 init_fail:
1792 kfree(priv);
1793 return err;
1794}
1795
1796int synaptics_init(struct psmouse *psmouse)
1797{
1798 return __synaptics_init(psmouse, true);
1799}
1800
1801int synaptics_init_relative(struct psmouse *psmouse)
1802{
1803 return __synaptics_init(psmouse, false);
1804}
1805
1806bool synaptics_supported(void)
1807{
1808 return true;
1809}
1810
1811#else
1812
1813void __init synaptics_module_init(void)
1814{
1815}
1816
1817int synaptics_init(struct psmouse *psmouse)
1818{
1819 return -ENOSYS;
1820}
1821
1822bool synaptics_supported(void)
1823{
1824 return false;
1825}
1826
1827#endif
1828