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