diff options
Diffstat (limited to 'drivers/input/mouse/synaptics.c')
-rw-r--r-- | drivers/input/mouse/synaptics.c | 219 |
1 files changed, 163 insertions, 56 deletions
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index f2cceb6493a0..3b06c8a360b6 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -67,9 +67,6 @@ | |||
67 | #define X_MAX_POSITIVE 8176 | 67 | #define X_MAX_POSITIVE 8176 |
68 | #define Y_MAX_POSITIVE 8176 | 68 | #define Y_MAX_POSITIVE 8176 |
69 | 69 | ||
70 | /* maximum ABS_MT_POSITION displacement (in mm) */ | ||
71 | #define DMAX 10 | ||
72 | |||
73 | /***************************************************************************** | 70 | /***************************************************************************** |
74 | * Stuff we need even when we do not want native Synaptics support | 71 | * Stuff we need even when we do not want native Synaptics support |
75 | ****************************************************************************/ | 72 | ****************************************************************************/ |
@@ -123,32 +120,46 @@ void synaptics_reset(struct psmouse *psmouse) | |||
123 | 120 | ||
124 | static bool cr48_profile_sensor; | 121 | static bool cr48_profile_sensor; |
125 | 122 | ||
123 | #define ANY_BOARD_ID 0 | ||
126 | struct min_max_quirk { | 124 | struct min_max_quirk { |
127 | const char * const *pnp_ids; | 125 | const char * const *pnp_ids; |
126 | struct { | ||
127 | unsigned long int min, max; | ||
128 | } board_id; | ||
128 | int x_min, x_max, y_min, y_max; | 129 | int x_min, x_max, y_min, y_max; |
129 | }; | 130 | }; |
130 | 131 | ||
131 | static const struct min_max_quirk min_max_pnpid_table[] = { | 132 | static const struct min_max_quirk min_max_pnpid_table[] = { |
132 | { | 133 | { |
133 | (const char * const []){"LEN0033", NULL}, | 134 | (const char * const []){"LEN0033", NULL}, |
135 | {ANY_BOARD_ID, ANY_BOARD_ID}, | ||
134 | 1024, 5052, 2258, 4832 | 136 | 1024, 5052, 2258, 4832 |
135 | }, | 137 | }, |
136 | { | 138 | { |
137 | (const char * const []){"LEN0035", "LEN0042", NULL}, | 139 | (const char * const []){"LEN0042", NULL}, |
140 | {ANY_BOARD_ID, ANY_BOARD_ID}, | ||
138 | 1232, 5710, 1156, 4696 | 141 | 1232, 5710, 1156, 4696 |
139 | }, | 142 | }, |
140 | { | 143 | { |
141 | (const char * const []){"LEN0034", "LEN0036", "LEN0037", | 144 | (const char * const []){"LEN0034", "LEN0036", "LEN0037", |
142 | "LEN0039", "LEN2002", "LEN2004", | 145 | "LEN0039", "LEN2002", "LEN2004", |
143 | NULL}, | 146 | NULL}, |
147 | {ANY_BOARD_ID, 2961}, | ||
144 | 1024, 5112, 2024, 4832 | 148 | 1024, 5112, 2024, 4832 |
145 | }, | 149 | }, |
146 | { | 150 | { |
147 | (const char * const []){"LEN2001", NULL}, | 151 | (const char * const []){"LEN2001", NULL}, |
152 | {ANY_BOARD_ID, ANY_BOARD_ID}, | ||
148 | 1024, 5022, 2508, 4832 | 153 | 1024, 5022, 2508, 4832 |
149 | }, | 154 | }, |
150 | { | 155 | { |
151 | (const char * const []){"LEN2006", NULL}, | 156 | (const char * const []){"LEN2006", NULL}, |
157 | {2691, 2691}, | ||
158 | 1024, 5045, 2457, 4832 | ||
159 | }, | ||
160 | { | ||
161 | (const char * const []){"LEN2006", NULL}, | ||
162 | {ANY_BOARD_ID, ANY_BOARD_ID}, | ||
152 | 1264, 5675, 1171, 4688 | 163 | 1264, 5675, 1171, 4688 |
153 | }, | 164 | }, |
154 | { } | 165 | { } |
@@ -175,9 +186,7 @@ static const char * const topbuttonpad_pnp_ids[] = { | |||
175 | "LEN0041", | 186 | "LEN0041", |
176 | "LEN0042", /* Yoga */ | 187 | "LEN0042", /* Yoga */ |
177 | "LEN0045", | 188 | "LEN0045", |
178 | "LEN0046", | ||
179 | "LEN0047", | 189 | "LEN0047", |
180 | "LEN0048", | ||
181 | "LEN0049", | 190 | "LEN0049", |
182 | "LEN2000", | 191 | "LEN2000", |
183 | "LEN2001", /* Edge E431 */ | 192 | "LEN2001", /* Edge E431 */ |
@@ -185,7 +194,7 @@ static const char * const topbuttonpad_pnp_ids[] = { | |||
185 | "LEN2003", | 194 | "LEN2003", |
186 | "LEN2004", /* L440 */ | 195 | "LEN2004", /* L440 */ |
187 | "LEN2005", | 196 | "LEN2005", |
188 | "LEN2006", | 197 | "LEN2006", /* Edge E440/E540 */ |
189 | "LEN2007", | 198 | "LEN2007", |
190 | "LEN2008", | 199 | "LEN2008", |
191 | "LEN2009", | 200 | "LEN2009", |
@@ -235,18 +244,39 @@ static int synaptics_model_id(struct psmouse *psmouse) | |||
235 | return 0; | 244 | return 0; |
236 | } | 245 | } |
237 | 246 | ||
247 | static int synaptics_more_extended_queries(struct psmouse *psmouse) | ||
248 | { | ||
249 | struct synaptics_data *priv = psmouse->private; | ||
250 | unsigned char buf[3]; | ||
251 | |||
252 | if (synaptics_send_cmd(psmouse, SYN_QUE_MEXT_CAPAB_10, buf)) | ||
253 | return -1; | ||
254 | |||
255 | priv->ext_cap_10 = (buf[0]<<16) | (buf[1]<<8) | buf[2]; | ||
256 | |||
257 | return 0; | ||
258 | } | ||
259 | |||
238 | /* | 260 | /* |
239 | * Read the board id from the touchpad | 261 | * Read the board id and the "More Extended Queries" from the touchpad |
240 | * The board id is encoded in the "QUERY MODES" response | 262 | * The board id is encoded in the "QUERY MODES" response |
241 | */ | 263 | */ |
242 | static int synaptics_board_id(struct psmouse *psmouse) | 264 | static int synaptics_query_modes(struct psmouse *psmouse) |
243 | { | 265 | { |
244 | struct synaptics_data *priv = psmouse->private; | 266 | struct synaptics_data *priv = psmouse->private; |
245 | unsigned char bid[3]; | 267 | unsigned char bid[3]; |
246 | 268 | ||
269 | /* firmwares prior 7.5 have no board_id encoded */ | ||
270 | if (SYN_ID_FULL(priv->identity) < 0x705) | ||
271 | return 0; | ||
272 | |||
247 | if (synaptics_send_cmd(psmouse, SYN_QUE_MODES, bid)) | 273 | if (synaptics_send_cmd(psmouse, SYN_QUE_MODES, bid)) |
248 | return -1; | 274 | return -1; |
249 | priv->board_id = ((bid[0] & 0xfc) << 6) | bid[1]; | 275 | priv->board_id = ((bid[0] & 0xfc) << 6) | bid[1]; |
276 | |||
277 | if (SYN_MEXT_CAP_BIT(bid[0])) | ||
278 | return synaptics_more_extended_queries(psmouse); | ||
279 | |||
250 | return 0; | 280 | return 0; |
251 | } | 281 | } |
252 | 282 | ||
@@ -346,7 +376,6 @@ static int synaptics_resolution(struct psmouse *psmouse) | |||
346 | { | 376 | { |
347 | struct synaptics_data *priv = psmouse->private; | 377 | struct synaptics_data *priv = psmouse->private; |
348 | unsigned char resp[3]; | 378 | unsigned char resp[3]; |
349 | int i; | ||
350 | 379 | ||
351 | if (SYN_ID_MAJOR(priv->identity) < 4) | 380 | if (SYN_ID_MAJOR(priv->identity) < 4) |
352 | return 0; | 381 | return 0; |
@@ -358,17 +387,6 @@ static int synaptics_resolution(struct psmouse *psmouse) | |||
358 | } | 387 | } |
359 | } | 388 | } |
360 | 389 | ||
361 | for (i = 0; min_max_pnpid_table[i].pnp_ids; i++) { | ||
362 | if (psmouse_matches_pnp_id(psmouse, | ||
363 | min_max_pnpid_table[i].pnp_ids)) { | ||
364 | priv->x_min = min_max_pnpid_table[i].x_min; | ||
365 | priv->x_max = min_max_pnpid_table[i].x_max; | ||
366 | priv->y_min = min_max_pnpid_table[i].y_min; | ||
367 | priv->y_max = min_max_pnpid_table[i].y_max; | ||
368 | return 0; | ||
369 | } | ||
370 | } | ||
371 | |||
372 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && | 390 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && |
373 | SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { | 391 | SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { |
374 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MAX_COORDS, resp)) { | 392 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MAX_COORDS, resp)) { |
@@ -377,23 +395,69 @@ static int synaptics_resolution(struct psmouse *psmouse) | |||
377 | } else { | 395 | } else { |
378 | priv->x_max = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); | 396 | priv->x_max = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); |
379 | priv->y_max = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); | 397 | priv->y_max = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); |
398 | psmouse_info(psmouse, | ||
399 | "queried max coordinates: x [..%d], y [..%d]\n", | ||
400 | priv->x_max, priv->y_max); | ||
380 | } | 401 | } |
381 | } | 402 | } |
382 | 403 | ||
383 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 7 && | 404 | if (SYN_CAP_MIN_DIMENSIONS(priv->ext_cap_0c) && |
384 | SYN_CAP_MIN_DIMENSIONS(priv->ext_cap_0c)) { | 405 | (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 7 || |
406 | /* | ||
407 | * Firmware v8.1 does not report proper number of extended | ||
408 | * capabilities, but has been proven to report correct min | ||
409 | * coordinates. | ||
410 | */ | ||
411 | SYN_ID_FULL(priv->identity) == 0x801)) { | ||
385 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MIN_COORDS, resp)) { | 412 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MIN_COORDS, resp)) { |
386 | psmouse_warn(psmouse, | 413 | psmouse_warn(psmouse, |
387 | "device claims to have min coordinates query, but I'm not able to read it.\n"); | 414 | "device claims to have min coordinates query, but I'm not able to read it.\n"); |
388 | } else { | 415 | } else { |
389 | priv->x_min = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); | 416 | priv->x_min = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); |
390 | priv->y_min = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); | 417 | priv->y_min = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); |
418 | psmouse_info(psmouse, | ||
419 | "queried min coordinates: x [%d..], y [%d..]\n", | ||
420 | priv->x_min, priv->y_min); | ||
391 | } | 421 | } |
392 | } | 422 | } |
393 | 423 | ||
394 | return 0; | 424 | return 0; |
395 | } | 425 | } |
396 | 426 | ||
427 | /* | ||
428 | * Apply quirk(s) if the hardware matches | ||
429 | */ | ||
430 | |||
431 | static void synaptics_apply_quirks(struct psmouse *psmouse) | ||
432 | { | ||
433 | struct synaptics_data *priv = psmouse->private; | ||
434 | int i; | ||
435 | |||
436 | for (i = 0; min_max_pnpid_table[i].pnp_ids; i++) { | ||
437 | if (!psmouse_matches_pnp_id(psmouse, | ||
438 | min_max_pnpid_table[i].pnp_ids)) | ||
439 | continue; | ||
440 | |||
441 | if (min_max_pnpid_table[i].board_id.min != ANY_BOARD_ID && | ||
442 | priv->board_id < min_max_pnpid_table[i].board_id.min) | ||
443 | continue; | ||
444 | |||
445 | if (min_max_pnpid_table[i].board_id.max != ANY_BOARD_ID && | ||
446 | priv->board_id > min_max_pnpid_table[i].board_id.max) | ||
447 | continue; | ||
448 | |||
449 | priv->x_min = min_max_pnpid_table[i].x_min; | ||
450 | priv->x_max = min_max_pnpid_table[i].x_max; | ||
451 | priv->y_min = min_max_pnpid_table[i].y_min; | ||
452 | priv->y_max = min_max_pnpid_table[i].y_max; | ||
453 | psmouse_info(psmouse, | ||
454 | "quirked min/max coordinates: x [%d..%d], y [%d..%d]\n", | ||
455 | priv->x_min, priv->x_max, | ||
456 | priv->y_min, priv->y_max); | ||
457 | break; | ||
458 | } | ||
459 | } | ||
460 | |||
397 | static int synaptics_query_hardware(struct psmouse *psmouse) | 461 | static int synaptics_query_hardware(struct psmouse *psmouse) |
398 | { | 462 | { |
399 | if (synaptics_identify(psmouse)) | 463 | if (synaptics_identify(psmouse)) |
@@ -402,13 +466,15 @@ static int synaptics_query_hardware(struct psmouse *psmouse) | |||
402 | return -1; | 466 | return -1; |
403 | if (synaptics_firmware_id(psmouse)) | 467 | if (synaptics_firmware_id(psmouse)) |
404 | return -1; | 468 | return -1; |
405 | if (synaptics_board_id(psmouse)) | 469 | if (synaptics_query_modes(psmouse)) |
406 | return -1; | 470 | return -1; |
407 | if (synaptics_capability(psmouse)) | 471 | if (synaptics_capability(psmouse)) |
408 | return -1; | 472 | return -1; |
409 | if (synaptics_resolution(psmouse)) | 473 | if (synaptics_resolution(psmouse)) |
410 | return -1; | 474 | return -1; |
411 | 475 | ||
476 | synaptics_apply_quirks(psmouse); | ||
477 | |||
412 | return 0; | 478 | return 0; |
413 | } | 479 | } |
414 | 480 | ||
@@ -516,18 +582,22 @@ static int synaptics_is_pt_packet(unsigned char *buf) | |||
516 | return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4; | 582 | return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4; |
517 | } | 583 | } |
518 | 584 | ||
519 | static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet) | 585 | static void synaptics_pass_pt_packet(struct psmouse *psmouse, |
586 | struct serio *ptport, | ||
587 | unsigned char *packet) | ||
520 | { | 588 | { |
589 | struct synaptics_data *priv = psmouse->private; | ||
521 | struct psmouse *child = serio_get_drvdata(ptport); | 590 | struct psmouse *child = serio_get_drvdata(ptport); |
522 | 591 | ||
523 | if (child && child->state == PSMOUSE_ACTIVATED) { | 592 | if (child && child->state == PSMOUSE_ACTIVATED) { |
524 | serio_interrupt(ptport, packet[1], 0); | 593 | serio_interrupt(ptport, packet[1] | priv->pt_buttons, 0); |
525 | serio_interrupt(ptport, packet[4], 0); | 594 | serio_interrupt(ptport, packet[4], 0); |
526 | serio_interrupt(ptport, packet[5], 0); | 595 | serio_interrupt(ptport, packet[5], 0); |
527 | if (child->pktsize == 4) | 596 | if (child->pktsize == 4) |
528 | serio_interrupt(ptport, packet[2], 0); | 597 | serio_interrupt(ptport, packet[2], 0); |
529 | } else | 598 | } else { |
530 | serio_interrupt(ptport, packet[1], 0); | 599 | serio_interrupt(ptport, packet[1], 0); |
600 | } | ||
531 | } | 601 | } |
532 | 602 | ||
533 | static void synaptics_pt_activate(struct psmouse *psmouse) | 603 | static void synaptics_pt_activate(struct psmouse *psmouse) |
@@ -605,6 +675,18 @@ static void synaptics_parse_agm(const unsigned char buf[], | |||
605 | } | 675 | } |
606 | } | 676 | } |
607 | 677 | ||
678 | static void synaptics_parse_ext_buttons(const unsigned char buf[], | ||
679 | struct synaptics_data *priv, | ||
680 | struct synaptics_hw_state *hw) | ||
681 | { | ||
682 | unsigned int ext_bits = | ||
683 | (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) + 1) >> 1; | ||
684 | unsigned int ext_mask = GENMASK(ext_bits - 1, 0); | ||
685 | |||
686 | hw->ext_buttons = buf[4] & ext_mask; | ||
687 | hw->ext_buttons |= (buf[5] & ext_mask) << ext_bits; | ||
688 | } | ||
689 | |||
608 | static bool is_forcepad; | 690 | static bool is_forcepad; |
609 | 691 | ||
610 | static int synaptics_parse_hw_state(const unsigned char buf[], | 692 | static int synaptics_parse_hw_state(const unsigned char buf[], |
@@ -691,28 +773,9 @@ static int synaptics_parse_hw_state(const unsigned char buf[], | |||
691 | hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; | 773 | hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; |
692 | } | 774 | } |
693 | 775 | ||
694 | if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) && | 776 | if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) > 0 && |
695 | ((buf[0] ^ buf[3]) & 0x02)) { | 777 | ((buf[0] ^ buf[3]) & 0x02)) { |
696 | switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) { | 778 | synaptics_parse_ext_buttons(buf, priv, hw); |
697 | default: | ||
698 | /* | ||
699 | * if nExtBtn is greater than 8 it should be | ||
700 | * considered invalid and treated as 0 | ||
701 | */ | ||
702 | break; | ||
703 | case 8: | ||
704 | hw->ext_buttons |= ((buf[5] & 0x08)) ? 0x80 : 0; | ||
705 | hw->ext_buttons |= ((buf[4] & 0x08)) ? 0x40 : 0; | ||
706 | case 6: | ||
707 | hw->ext_buttons |= ((buf[5] & 0x04)) ? 0x20 : 0; | ||
708 | hw->ext_buttons |= ((buf[4] & 0x04)) ? 0x10 : 0; | ||
709 | case 4: | ||
710 | hw->ext_buttons |= ((buf[5] & 0x02)) ? 0x08 : 0; | ||
711 | hw->ext_buttons |= ((buf[4] & 0x02)) ? 0x04 : 0; | ||
712 | case 2: | ||
713 | hw->ext_buttons |= ((buf[5] & 0x01)) ? 0x02 : 0; | ||
714 | hw->ext_buttons |= ((buf[4] & 0x01)) ? 0x01 : 0; | ||
715 | } | ||
716 | } | 779 | } |
717 | } else { | 780 | } else { |
718 | hw->x = (((buf[1] & 0x1f) << 8) | buf[2]); | 781 | hw->x = (((buf[1] & 0x1f) << 8) | buf[2]); |
@@ -774,12 +837,54 @@ static void synaptics_report_semi_mt_data(struct input_dev *dev, | |||
774 | } | 837 | } |
775 | } | 838 | } |
776 | 839 | ||
840 | static void synaptics_report_ext_buttons(struct psmouse *psmouse, | ||
841 | const struct synaptics_hw_state *hw) | ||
842 | { | ||
843 | struct input_dev *dev = psmouse->dev; | ||
844 | struct synaptics_data *priv = psmouse->private; | ||
845 | int ext_bits = (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) + 1) >> 1; | ||
846 | char buf[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | ||
847 | int i; | ||
848 | |||
849 | if (!SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) | ||
850 | return; | ||
851 | |||
852 | /* Bug in FW 8.1, buttons are reported only when ExtBit is 1 */ | ||
853 | if (SYN_ID_FULL(priv->identity) == 0x801 && | ||
854 | !((psmouse->packet[0] ^ psmouse->packet[3]) & 0x02)) | ||
855 | return; | ||
856 | |||
857 | if (!SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10)) { | ||
858 | for (i = 0; i < ext_bits; i++) { | ||
859 | input_report_key(dev, BTN_0 + 2 * i, | ||
860 | hw->ext_buttons & (1 << i)); | ||
861 | input_report_key(dev, BTN_1 + 2 * i, | ||
862 | hw->ext_buttons & (1 << (i + ext_bits))); | ||
863 | } | ||
864 | return; | ||
865 | } | ||
866 | |||
867 | /* | ||
868 | * This generation of touchpads has the trackstick buttons | ||
869 | * physically wired to the touchpad. Re-route them through | ||
870 | * the pass-through interface. | ||
871 | */ | ||
872 | if (!priv->pt_port) | ||
873 | return; | ||
874 | |||
875 | /* The trackstick expects at most 3 buttons */ | ||
876 | priv->pt_buttons = SYN_CAP_EXT_BUTTON_STICK_L(hw->ext_buttons) | | ||
877 | SYN_CAP_EXT_BUTTON_STICK_R(hw->ext_buttons) << 1 | | ||
878 | SYN_CAP_EXT_BUTTON_STICK_M(hw->ext_buttons) << 2; | ||
879 | |||
880 | synaptics_pass_pt_packet(psmouse, priv->pt_port, buf); | ||
881 | } | ||
882 | |||
777 | static void synaptics_report_buttons(struct psmouse *psmouse, | 883 | static void synaptics_report_buttons(struct psmouse *psmouse, |
778 | const struct synaptics_hw_state *hw) | 884 | const struct synaptics_hw_state *hw) |
779 | { | 885 | { |
780 | struct input_dev *dev = psmouse->dev; | 886 | struct input_dev *dev = psmouse->dev; |
781 | struct synaptics_data *priv = psmouse->private; | 887 | struct synaptics_data *priv = psmouse->private; |
782 | int i; | ||
783 | 888 | ||
784 | input_report_key(dev, BTN_LEFT, hw->left); | 889 | input_report_key(dev, BTN_LEFT, hw->left); |
785 | input_report_key(dev, BTN_RIGHT, hw->right); | 890 | input_report_key(dev, BTN_RIGHT, hw->right); |
@@ -792,8 +897,7 @@ static void synaptics_report_buttons(struct psmouse *psmouse, | |||
792 | input_report_key(dev, BTN_BACK, hw->down); | 897 | input_report_key(dev, BTN_BACK, hw->down); |
793 | } | 898 | } |
794 | 899 | ||
795 | for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) | 900 | synaptics_report_ext_buttons(psmouse, hw); |
796 | input_report_key(dev, BTN_0 + i, hw->ext_buttons & (1 << i)); | ||
797 | } | 901 | } |
798 | 902 | ||
799 | static void synaptics_report_mt_data(struct psmouse *psmouse, | 903 | static void synaptics_report_mt_data(struct psmouse *psmouse, |
@@ -813,7 +917,7 @@ static void synaptics_report_mt_data(struct psmouse *psmouse, | |||
813 | pos[i].y = synaptics_invert_y(hw[i]->y); | 917 | pos[i].y = synaptics_invert_y(hw[i]->y); |
814 | } | 918 | } |
815 | 919 | ||
816 | input_mt_assign_slots(dev, slot, pos, nsemi, DMAX * priv->x_res); | 920 | input_mt_assign_slots(dev, slot, pos, nsemi, 0); |
817 | 921 | ||
818 | for (i = 0; i < nsemi; i++) { | 922 | for (i = 0; i < nsemi; i++) { |
819 | input_mt_slot(dev, slot[i]); | 923 | input_mt_slot(dev, slot[i]); |
@@ -1014,7 +1118,8 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse) | |||
1014 | if (SYN_CAP_PASS_THROUGH(priv->capabilities) && | 1118 | if (SYN_CAP_PASS_THROUGH(priv->capabilities) && |
1015 | synaptics_is_pt_packet(psmouse->packet)) { | 1119 | synaptics_is_pt_packet(psmouse->packet)) { |
1016 | if (priv->pt_port) | 1120 | if (priv->pt_port) |
1017 | synaptics_pass_pt_packet(priv->pt_port, psmouse->packet); | 1121 | synaptics_pass_pt_packet(psmouse, priv->pt_port, |
1122 | psmouse->packet); | ||
1018 | } else | 1123 | } else |
1019 | synaptics_process_packet(psmouse); | 1124 | synaptics_process_packet(psmouse); |
1020 | 1125 | ||
@@ -1116,8 +1221,9 @@ static void set_input_params(struct psmouse *psmouse, | |||
1116 | __set_bit(BTN_BACK, dev->keybit); | 1221 | __set_bit(BTN_BACK, dev->keybit); |
1117 | } | 1222 | } |
1118 | 1223 | ||
1119 | for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) | 1224 | if (!SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10)) |
1120 | __set_bit(BTN_0 + i, dev->keybit); | 1225 | for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) |
1226 | __set_bit(BTN_0 + i, dev->keybit); | ||
1121 | 1227 | ||
1122 | __clear_bit(EV_REL, dev->evbit); | 1228 | __clear_bit(EV_REL, dev->evbit); |
1123 | __clear_bit(REL_X, dev->relbit); | 1229 | __clear_bit(REL_X, dev->relbit); |
@@ -1125,7 +1231,8 @@ static void set_input_params(struct psmouse *psmouse, | |||
1125 | 1231 | ||
1126 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { | 1232 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { |
1127 | __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); | 1233 | __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); |
1128 | if (psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids)) | 1234 | if (psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids) && |
1235 | !SYN_CAP_EXT_BUTTONS_STICK(priv->ext_cap_10)) | ||
1129 | __set_bit(INPUT_PROP_TOPBUTTONPAD, dev->propbit); | 1236 | __set_bit(INPUT_PROP_TOPBUTTONPAD, dev->propbit); |
1130 | /* Clickpads report only left button */ | 1237 | /* Clickpads report only left button */ |
1131 | __clear_bit(BTN_RIGHT, dev->keybit); | 1238 | __clear_bit(BTN_RIGHT, dev->keybit); |