diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-27 02:44:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-27 02:44:20 -0400 |
commit | 396e6e49c58bb23d1814d3c240c736c9f01523c5 (patch) | |
tree | a6ec8dac896c3ea3ac7b1bb0dce8728766afcf91 /drivers/input/mouse | |
parent | 18974369cfe23acf16d0fb79e0d1fba7a9a95ec0 (diff) | |
parent | 6ad390a25a9d1d8606b9b826878f0a30639dc2b3 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (68 commits)
Input: adp5589-keys - add support for the ADP5585 derivatives
Input: imx_keypad - add pm suspend and resume support
Input: force feedback - potential integer wrap in input_ff_create()
Input: tsc2007 - make sure that X plate resistance is specified
Input: serio_raw - fix memory leak when closing char device
Input: serio_raw - kick clients when disconnecting port
Input: serio_raw - explicitly mark disconnected ports as dead
Input: serio_raw - fix coding style issues
Input: serio_raw - use dev_*() for messages
Input: serio_raw - use bool for boolean data
Input: serio_raw - perform proper locking when adding clients to list
Input: serio_raw - rename serio_raw_list to serio_raw_client
Input: serio_raw - use kref instead of rolling out its own refcounting
Input: psmouse - switch to using dev_*() for messages
Input: wacom - correct max Y value on medium bamboos
Input: wacom - add ABS_DISTANCE to Bamboo Pen reports
Input: wacom - remove unneeded touch pressure initialization
Input: lm8323 - wrap suspend and resume in CONFIG_PM_SLEEP
Input: ad7879-i2c - wrap suspend and resume in CONFIG_PM_SLEEP
Input: synaptics_i2c - wrap suspend and resume in CONFIG_PM_SLEEP
...
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r-- | drivers/input/mouse/alps.c | 52 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.c | 734 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.h | 57 | ||||
-rw-r--r-- | drivers/input/mouse/hgpk.c | 84 | ||||
-rw-r--r-- | drivers/input/mouse/hgpk.h | 11 | ||||
-rw-r--r-- | drivers/input/mouse/lifebook.c | 6 | ||||
-rw-r--r-- | drivers/input/mouse/logips2pp.c | 16 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse-base.c | 67 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse.h | 25 | ||||
-rw-r--r-- | drivers/input/mouse/pxa930_trkball.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/sentelic.c | 13 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.c | 610 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.h | 27 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics_i2c.c | 4 |
14 files changed, 1363 insertions, 345 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 99d58764ef03..003587c71f43 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -23,13 +23,6 @@ | |||
23 | #include "psmouse.h" | 23 | #include "psmouse.h" |
24 | #include "alps.h" | 24 | #include "alps.h" |
25 | 25 | ||
26 | #undef DEBUG | ||
27 | #ifdef DEBUG | ||
28 | #define dbg(format, arg...) printk(KERN_INFO "alps.c: " format "\n", ## arg) | ||
29 | #else | ||
30 | #define dbg(format, arg...) do {} while (0) | ||
31 | #endif | ||
32 | |||
33 | #define ALPS_OLDPROTO 0x01 /* old style input */ | 26 | #define ALPS_OLDPROTO 0x01 /* old style input */ |
34 | #define ALPS_DUALPOINT 0x02 /* touchpad has trackstick */ | 27 | #define ALPS_DUALPOINT 0x02 /* touchpad has trackstick */ |
35 | #define ALPS_PASS 0x04 /* device has a pass-through port */ | 28 | #define ALPS_PASS 0x04 /* device has a pass-through port */ |
@@ -297,10 +290,10 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse) | |||
297 | psmouse->packet[4] | | 290 | psmouse->packet[4] | |
298 | psmouse->packet[5]) & 0x80) || | 291 | psmouse->packet[5]) & 0x80) || |
299 | (!alps_is_valid_first_byte(priv->i, psmouse->packet[6]))) { | 292 | (!alps_is_valid_first_byte(priv->i, psmouse->packet[6]))) { |
300 | dbg("refusing packet %x %x %x %x " | 293 | psmouse_dbg(psmouse, |
301 | "(suspected interleaved ps/2)\n", | 294 | "refusing packet %x %x %x %x (suspected interleaved ps/2)\n", |
302 | psmouse->packet[3], psmouse->packet[4], | 295 | psmouse->packet[3], psmouse->packet[4], |
303 | psmouse->packet[5], psmouse->packet[6]); | 296 | psmouse->packet[5], psmouse->packet[6]); |
304 | return PSMOUSE_BAD_DATA; | 297 | return PSMOUSE_BAD_DATA; |
305 | } | 298 | } |
306 | 299 | ||
@@ -319,13 +312,13 @@ static psmouse_ret_t alps_handle_interleaved_ps2(struct psmouse *psmouse) | |||
319 | * There is also possibility that we got 6-byte ALPS | 312 | * There is also possibility that we got 6-byte ALPS |
320 | * packet followed by 3-byte packet from trackpoint. We | 313 | * packet followed by 3-byte packet from trackpoint. We |
321 | * can not distinguish between these 2 scenarios but | 314 | * can not distinguish between these 2 scenarios but |
322 | * becase the latter is unlikely to happen in course of | 315 | * because the latter is unlikely to happen in course of |
323 | * normal operation (user would need to press all | 316 | * normal operation (user would need to press all |
324 | * buttons on the pad and start moving trackpoint | 317 | * buttons on the pad and start moving trackpoint |
325 | * without touching the pad surface) we assume former. | 318 | * without touching the pad surface) we assume former. |
326 | * Even if we are wrong the wost thing that would happen | 319 | * Even if we are wrong the wost thing that would happen |
327 | * the cursor would jump but we should not get protocol | 320 | * the cursor would jump but we should not get protocol |
328 | * desynchronization. | 321 | * de-synchronization. |
329 | */ | 322 | */ |
330 | 323 | ||
331 | alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3], | 324 | alps_report_bare_ps2_packet(psmouse, &psmouse->packet[3], |
@@ -361,10 +354,10 @@ static void alps_flush_packet(unsigned long data) | |||
361 | if ((psmouse->packet[3] | | 354 | if ((psmouse->packet[3] | |
362 | psmouse->packet[4] | | 355 | psmouse->packet[4] | |
363 | psmouse->packet[5]) & 0x80) { | 356 | psmouse->packet[5]) & 0x80) { |
364 | dbg("refusing packet %x %x %x " | 357 | psmouse_dbg(psmouse, |
365 | "(suspected interleaved ps/2)\n", | 358 | "refusing packet %x %x %x (suspected interleaved ps/2)\n", |
366 | psmouse->packet[3], psmouse->packet[4], | 359 | psmouse->packet[3], psmouse->packet[4], |
367 | psmouse->packet[5]); | 360 | psmouse->packet[5]); |
368 | } else { | 361 | } else { |
369 | alps_process_packet(psmouse); | 362 | alps_process_packet(psmouse); |
370 | } | 363 | } |
@@ -396,16 +389,18 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) | |||
396 | } | 389 | } |
397 | 390 | ||
398 | if (!alps_is_valid_first_byte(model, psmouse->packet[0])) { | 391 | if (!alps_is_valid_first_byte(model, psmouse->packet[0])) { |
399 | dbg("refusing packet[0] = %x (mask0 = %x, byte0 = %x)\n", | 392 | psmouse_dbg(psmouse, |
400 | psmouse->packet[0], model->mask0, model->byte0); | 393 | "refusing packet[0] = %x (mask0 = %x, byte0 = %x)\n", |
394 | psmouse->packet[0], model->mask0, model->byte0); | ||
401 | return PSMOUSE_BAD_DATA; | 395 | return PSMOUSE_BAD_DATA; |
402 | } | 396 | } |
403 | 397 | ||
404 | /* Bytes 2 - 6 should have 0 in the highest bit */ | 398 | /* Bytes 2 - 6 should have 0 in the highest bit */ |
405 | if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= 6 && | 399 | if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= 6 && |
406 | (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) { | 400 | (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) { |
407 | dbg("refusing packet[%i] = %x\n", | 401 | psmouse_dbg(psmouse, "refusing packet[%i] = %x\n", |
408 | psmouse->pktcnt - 1, psmouse->packet[psmouse->pktcnt - 1]); | 402 | psmouse->pktcnt - 1, |
403 | psmouse->packet[psmouse->pktcnt - 1]); | ||
409 | return PSMOUSE_BAD_DATA; | 404 | return PSMOUSE_BAD_DATA; |
410 | } | 405 | } |
411 | 406 | ||
@@ -439,7 +434,8 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int | |||
439 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) | 434 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) |
440 | return NULL; | 435 | return NULL; |
441 | 436 | ||
442 | dbg("E6 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]); | 437 | psmouse_dbg(psmouse, "E6 report: %2.2x %2.2x %2.2x", |
438 | param[0], param[1], param[2]); | ||
443 | 439 | ||
444 | if (param[0] != 0 || param[1] != 0 || (param[2] != 10 && param[2] != 100)) | 440 | if (param[0] != 0 || param[1] != 0 || (param[2] != 10 && param[2] != 100)) |
445 | return NULL; | 441 | return NULL; |
@@ -459,7 +455,8 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int | |||
459 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) | 455 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) |
460 | return NULL; | 456 | return NULL; |
461 | 457 | ||
462 | dbg("E7 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]); | 458 | psmouse_dbg(psmouse, "E7 report: %2.2x %2.2x %2.2x", |
459 | param[0], param[1], param[2]); | ||
463 | 460 | ||
464 | if (version) { | 461 | if (version) { |
465 | for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++) | 462 | for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++) |
@@ -527,7 +524,8 @@ static int alps_get_status(struct psmouse *psmouse, char *param) | |||
527 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) | 524 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) |
528 | return -1; | 525 | return -1; |
529 | 526 | ||
530 | dbg("Status: %2.2x %2.2x %2.2x", param[0], param[1], param[2]); | 527 | psmouse_dbg(psmouse, "Status: %2.2x %2.2x %2.2x", |
528 | param[0], param[1], param[2]); | ||
531 | 529 | ||
532 | return 0; | 530 | return 0; |
533 | } | 531 | } |
@@ -605,12 +603,12 @@ static int alps_hw_init(struct psmouse *psmouse) | |||
605 | } | 603 | } |
606 | 604 | ||
607 | if (alps_tap_mode(psmouse, true)) { | 605 | if (alps_tap_mode(psmouse, true)) { |
608 | printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n"); | 606 | psmouse_warn(psmouse, "Failed to enable hardware tapping\n"); |
609 | return -1; | 607 | return -1; |
610 | } | 608 | } |
611 | 609 | ||
612 | if (alps_absolute_mode(psmouse)) { | 610 | if (alps_absolute_mode(psmouse)) { |
613 | printk(KERN_ERR "alps.c: Failed to enable absolute mode\n"); | 611 | psmouse_err(psmouse, "Failed to enable absolute mode\n"); |
614 | return -1; | 612 | return -1; |
615 | } | 613 | } |
616 | 614 | ||
@@ -621,7 +619,7 @@ static int alps_hw_init(struct psmouse *psmouse) | |||
621 | 619 | ||
622 | /* ALPS needs stream mode, otherwise it won't report any data */ | 620 | /* ALPS needs stream mode, otherwise it won't report any data */ |
623 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) { | 621 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) { |
624 | printk(KERN_ERR "alps.c: Failed to enable stream mode\n"); | 622 | psmouse_err(psmouse, "Failed to enable stream mode\n"); |
625 | return -1; | 623 | return -1; |
626 | } | 624 | } |
627 | 625 | ||
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 32503565faf9..09b93b11a274 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -10,8 +10,6 @@ | |||
10 | * Trademarks are the property of their respective owners. | 10 | * Trademarks are the property of their respective owners. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #define pr_fmt(fmt) KBUILD_BASENAME ": " fmt | ||
14 | |||
15 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
16 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
17 | #include <linux/module.h> | 15 | #include <linux/module.h> |
@@ -25,13 +23,10 @@ | |||
25 | #define elantech_debug(fmt, ...) \ | 23 | #define elantech_debug(fmt, ...) \ |
26 | do { \ | 24 | do { \ |
27 | if (etd->debug) \ | 25 | if (etd->debug) \ |
28 | printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ | 26 | psmouse_printk(KERN_DEBUG, psmouse, \ |
27 | fmt, ##__VA_ARGS__); \ | ||
29 | } while (0) | 28 | } while (0) |
30 | 29 | ||
31 | static bool force_elantech; | ||
32 | module_param_named(force_elantech, force_elantech, bool, 0644); | ||
33 | MODULE_PARM_DESC(force_elantech, "Force the Elantech PS/2 protocol extension to be used, 1 = enabled, 0 = disabled (default)."); | ||
34 | |||
35 | /* | 30 | /* |
36 | * Send a Synaptics style sliced query command | 31 | * Send a Synaptics style sliced query command |
37 | */ | 32 | */ |
@@ -40,7 +35,7 @@ static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, | |||
40 | { | 35 | { |
41 | if (psmouse_sliced_command(psmouse, c) || | 36 | if (psmouse_sliced_command(psmouse, c) || |
42 | ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) { | 37 | ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) { |
43 | pr_err("synaptics_send_cmd query 0x%02x failed.\n", c); | 38 | psmouse_err(psmouse, "%s query 0x%02x failed.\n", __func__, c); |
44 | return -1; | 39 | return -1; |
45 | } | 40 | } |
46 | 41 | ||
@@ -69,7 +64,7 @@ static int elantech_ps2_command(struct psmouse *psmouse, | |||
69 | } while (tries > 0); | 64 | } while (tries > 0); |
70 | 65 | ||
71 | if (rc) | 66 | if (rc) |
72 | pr_err("ps2 command 0x%02x failed.\n", command); | 67 | psmouse_err(psmouse, "ps2 command 0x%02x failed.\n", command); |
73 | 68 | ||
74 | return rc; | 69 | return rc; |
75 | } | 70 | } |
@@ -84,7 +79,7 @@ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg, | |||
84 | unsigned char param[3]; | 79 | unsigned char param[3]; |
85 | int rc = 0; | 80 | int rc = 0; |
86 | 81 | ||
87 | if (reg < 0x10 || reg > 0x26) | 82 | if (reg < 0x07 || reg > 0x26) |
88 | return -1; | 83 | return -1; |
89 | 84 | ||
90 | if (reg > 0x11 && reg < 0x20) | 85 | if (reg > 0x11 && reg < 0x20) |
@@ -108,12 +103,24 @@ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg, | |||
108 | rc = -1; | 103 | rc = -1; |
109 | } | 104 | } |
110 | break; | 105 | break; |
106 | |||
107 | case 3 ... 4: | ||
108 | if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || | ||
109 | elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) || | ||
110 | elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || | ||
111 | elantech_ps2_command(psmouse, NULL, reg) || | ||
112 | elantech_ps2_command(psmouse, param, PSMOUSE_CMD_GETINFO)) { | ||
113 | rc = -1; | ||
114 | } | ||
115 | break; | ||
111 | } | 116 | } |
112 | 117 | ||
113 | if (rc) | 118 | if (rc) |
114 | pr_err("failed to read register 0x%02x.\n", reg); | 119 | psmouse_err(psmouse, "failed to read register 0x%02x.\n", reg); |
115 | else | 120 | else if (etd->hw_version != 4) |
116 | *val = param[0]; | 121 | *val = param[0]; |
122 | else | ||
123 | *val = param[1]; | ||
117 | 124 | ||
118 | return rc; | 125 | return rc; |
119 | } | 126 | } |
@@ -127,7 +134,7 @@ static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg, | |||
127 | struct elantech_data *etd = psmouse->private; | 134 | struct elantech_data *etd = psmouse->private; |
128 | int rc = 0; | 135 | int rc = 0; |
129 | 136 | ||
130 | if (reg < 0x10 || reg > 0x26) | 137 | if (reg < 0x07 || reg > 0x26) |
131 | return -1; | 138 | return -1; |
132 | 139 | ||
133 | if (reg > 0x11 && reg < 0x20) | 140 | if (reg > 0x11 && reg < 0x20) |
@@ -154,11 +161,38 @@ static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg, | |||
154 | rc = -1; | 161 | rc = -1; |
155 | } | 162 | } |
156 | break; | 163 | break; |
164 | |||
165 | case 3: | ||
166 | if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || | ||
167 | elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) || | ||
168 | elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || | ||
169 | elantech_ps2_command(psmouse, NULL, reg) || | ||
170 | elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || | ||
171 | elantech_ps2_command(psmouse, NULL, val) || | ||
172 | elantech_ps2_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11)) { | ||
173 | rc = -1; | ||
174 | } | ||
175 | break; | ||
176 | |||
177 | case 4: | ||
178 | if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || | ||
179 | elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) || | ||
180 | elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || | ||
181 | elantech_ps2_command(psmouse, NULL, reg) || | ||
182 | elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || | ||
183 | elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) || | ||
184 | elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || | ||
185 | elantech_ps2_command(psmouse, NULL, val) || | ||
186 | elantech_ps2_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11)) { | ||
187 | rc = -1; | ||
188 | } | ||
189 | break; | ||
157 | } | 190 | } |
158 | 191 | ||
159 | if (rc) | 192 | if (rc) |
160 | pr_err("failed to write register 0x%02x with value 0x%02x.\n", | 193 | psmouse_err(psmouse, |
161 | reg, val); | 194 | "failed to write register 0x%02x with value 0x%02x.\n", |
195 | reg, val); | ||
162 | 196 | ||
163 | return rc; | 197 | return rc; |
164 | } | 198 | } |
@@ -166,13 +200,13 @@ static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg, | |||
166 | /* | 200 | /* |
167 | * Dump a complete mouse movement packet to the syslog | 201 | * Dump a complete mouse movement packet to the syslog |
168 | */ | 202 | */ |
169 | static void elantech_packet_dump(unsigned char *packet, int size) | 203 | static void elantech_packet_dump(struct psmouse *psmouse) |
170 | { | 204 | { |
171 | int i; | 205 | int i; |
172 | 206 | ||
173 | printk(KERN_DEBUG pr_fmt("PS/2 packet [")); | 207 | psmouse_printk(KERN_DEBUG, psmouse, "PS/2 packet ["); |
174 | for (i = 0; i < size; i++) | 208 | for (i = 0; i < psmouse->pktsize; i++) |
175 | printk("%s0x%02x ", (i) ? ", " : " ", packet[i]); | 209 | printk("%s0x%02x ", i ? ", " : " ", psmouse->packet[i]); |
176 | printk("]\n"); | 210 | printk("]\n"); |
177 | } | 211 | } |
178 | 212 | ||
@@ -223,7 +257,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
223 | input_report_abs(dev, ABS_X, | 257 | input_report_abs(dev, ABS_X, |
224 | ((packet[1] & 0x0c) << 6) | packet[2]); | 258 | ((packet[1] & 0x0c) << 6) | packet[2]); |
225 | input_report_abs(dev, ABS_Y, | 259 | input_report_abs(dev, ABS_Y, |
226 | ETP_YMAX_V1 - (((packet[1] & 0x03) << 8) | packet[3])); | 260 | etd->y_max - (((packet[1] & 0x03) << 8) | packet[3])); |
227 | } | 261 | } |
228 | 262 | ||
229 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); | 263 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); |
@@ -233,7 +267,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
233 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | 267 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); |
234 | 268 | ||
235 | if (etd->fw_version < 0x020000 && | 269 | if (etd->fw_version < 0x020000 && |
236 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { | 270 | (etd->capabilities[0] & ETP_CAP_HAS_ROCKER)) { |
237 | /* rocker up */ | 271 | /* rocker up */ |
238 | input_report_key(dev, BTN_FORWARD, packet[0] & 0x40); | 272 | input_report_key(dev, BTN_FORWARD, packet[0] & 0x40); |
239 | /* rocker down */ | 273 | /* rocker down */ |
@@ -273,11 +307,11 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
273 | struct elantech_data *etd = psmouse->private; | 307 | struct elantech_data *etd = psmouse->private; |
274 | struct input_dev *dev = psmouse->dev; | 308 | struct input_dev *dev = psmouse->dev; |
275 | unsigned char *packet = psmouse->packet; | 309 | unsigned char *packet = psmouse->packet; |
276 | unsigned int fingers, x1 = 0, y1 = 0, x2 = 0, y2 = 0, width = 0, pres = 0; | 310 | unsigned int fingers, x1 = 0, y1 = 0, x2 = 0, y2 = 0; |
311 | unsigned int width = 0, pres = 0; | ||
277 | 312 | ||
278 | /* byte 0: n1 n0 . . . . R L */ | 313 | /* byte 0: n1 n0 . . . . R L */ |
279 | fingers = (packet[0] & 0xc0) >> 6; | 314 | fingers = (packet[0] & 0xc0) >> 6; |
280 | input_report_key(dev, BTN_TOUCH, fingers != 0); | ||
281 | 315 | ||
282 | switch (fingers) { | 316 | switch (fingers) { |
283 | case 3: | 317 | case 3: |
@@ -290,18 +324,15 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
290 | /* pass through... */ | 324 | /* pass through... */ |
291 | case 1: | 325 | case 1: |
292 | /* | 326 | /* |
293 | * byte 1: . . . . . x10 x9 x8 | 327 | * byte 1: . . . . x11 x10 x9 x8 |
294 | * byte 2: x7 x6 x5 x4 x4 x2 x1 x0 | 328 | * byte 2: x7 x6 x5 x4 x4 x2 x1 x0 |
295 | */ | 329 | */ |
296 | x1 = ((packet[1] & 0x07) << 8) | packet[2]; | 330 | x1 = ((packet[1] & 0x0f) << 8) | packet[2]; |
297 | /* | 331 | /* |
298 | * byte 4: . . . . . . y9 y8 | 332 | * byte 4: . . . . y11 y10 y9 y8 |
299 | * byte 5: y7 y6 y5 y4 y3 y2 y1 y0 | 333 | * byte 5: y7 y6 y5 y4 y3 y2 y1 y0 |
300 | */ | 334 | */ |
301 | y1 = ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5]); | 335 | y1 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]); |
302 | |||
303 | input_report_abs(dev, ABS_X, x1); | ||
304 | input_report_abs(dev, ABS_Y, y1); | ||
305 | 336 | ||
306 | pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4); | 337 | pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4); |
307 | width = ((packet[0] & 0x30) >> 2) | ((packet[3] & 0x30) >> 4); | 338 | width = ((packet[0] & 0x30) >> 2) | ((packet[3] & 0x30) >> 4); |
@@ -314,22 +345,18 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
314 | * byte 0: . . ay8 ax8 . . . . | 345 | * byte 0: . . ay8 ax8 . . . . |
315 | * byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 | 346 | * byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 |
316 | */ | 347 | */ |
317 | x1 = ((packet[0] & 0x10) << 4) | packet[1]; | 348 | x1 = (((packet[0] & 0x10) << 4) | packet[1]) << 2; |
318 | /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */ | 349 | /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */ |
319 | y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]); | 350 | y1 = etd->y_max - |
351 | ((((packet[0] & 0x20) << 3) | packet[2]) << 2); | ||
320 | /* | 352 | /* |
321 | * byte 3: . . by8 bx8 . . . . | 353 | * byte 3: . . by8 bx8 . . . . |
322 | * byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 | 354 | * byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 |
323 | */ | 355 | */ |
324 | x2 = ((packet[3] & 0x10) << 4) | packet[4]; | 356 | x2 = (((packet[3] & 0x10) << 4) | packet[4]) << 2; |
325 | /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */ | 357 | /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */ |
326 | y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]); | 358 | y2 = etd->y_max - |
327 | /* | 359 | ((((packet[3] & 0x20) << 3) | packet[5]) << 2); |
328 | * For compatibility with the X Synaptics driver scale up | ||
329 | * one coordinate and report as ordinary mouse movent | ||
330 | */ | ||
331 | input_report_abs(dev, ABS_X, x1 << 2); | ||
332 | input_report_abs(dev, ABS_Y, y1 << 2); | ||
333 | 360 | ||
334 | /* Unknown so just report sensible values */ | 361 | /* Unknown so just report sensible values */ |
335 | pres = 127; | 362 | pres = 127; |
@@ -337,6 +364,11 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
337 | break; | 364 | break; |
338 | } | 365 | } |
339 | 366 | ||
367 | input_report_key(dev, BTN_TOUCH, fingers != 0); | ||
368 | if (fingers != 0) { | ||
369 | input_report_abs(dev, ABS_X, x1); | ||
370 | input_report_abs(dev, ABS_Y, y1); | ||
371 | } | ||
340 | elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2); | 372 | elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2); |
341 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); | 373 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); |
342 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); | 374 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); |
@@ -352,7 +384,208 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
352 | input_sync(dev); | 384 | input_sync(dev); |
353 | } | 385 | } |
354 | 386 | ||
355 | static int elantech_check_parity_v1(struct psmouse *psmouse) | 387 | /* |
388 | * Interpret complete data packets and report absolute mode input events for | ||
389 | * hardware version 3. (12 byte packets for two fingers) | ||
390 | */ | ||
391 | static void elantech_report_absolute_v3(struct psmouse *psmouse, | ||
392 | int packet_type) | ||
393 | { | ||
394 | struct input_dev *dev = psmouse->dev; | ||
395 | struct elantech_data *etd = psmouse->private; | ||
396 | unsigned char *packet = psmouse->packet; | ||
397 | unsigned int fingers = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0; | ||
398 | unsigned int width = 0, pres = 0; | ||
399 | |||
400 | /* byte 0: n1 n0 . . . . R L */ | ||
401 | fingers = (packet[0] & 0xc0) >> 6; | ||
402 | |||
403 | switch (fingers) { | ||
404 | case 3: | ||
405 | case 1: | ||
406 | /* | ||
407 | * byte 1: . . . . x11 x10 x9 x8 | ||
408 | * byte 2: x7 x6 x5 x4 x4 x2 x1 x0 | ||
409 | */ | ||
410 | x1 = ((packet[1] & 0x0f) << 8) | packet[2]; | ||
411 | /* | ||
412 | * byte 4: . . . . y11 y10 y9 y8 | ||
413 | * byte 5: y7 y6 y5 y4 y3 y2 y1 y0 | ||
414 | */ | ||
415 | y1 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]); | ||
416 | break; | ||
417 | |||
418 | case 2: | ||
419 | if (packet_type == PACKET_V3_HEAD) { | ||
420 | /* | ||
421 | * byte 1: . . . . ax11 ax10 ax9 ax8 | ||
422 | * byte 2: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 | ||
423 | */ | ||
424 | etd->mt[0].x = ((packet[1] & 0x0f) << 8) | packet[2]; | ||
425 | /* | ||
426 | * byte 4: . . . . ay11 ay10 ay9 ay8 | ||
427 | * byte 5: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 | ||
428 | */ | ||
429 | etd->mt[0].y = etd->y_max - | ||
430 | (((packet[4] & 0x0f) << 8) | packet[5]); | ||
431 | /* | ||
432 | * wait for next packet | ||
433 | */ | ||
434 | return; | ||
435 | } | ||
436 | |||
437 | /* packet_type == PACKET_V3_TAIL */ | ||
438 | x1 = etd->mt[0].x; | ||
439 | y1 = etd->mt[0].y; | ||
440 | x2 = ((packet[1] & 0x0f) << 8) | packet[2]; | ||
441 | y2 = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]); | ||
442 | break; | ||
443 | } | ||
444 | |||
445 | pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4); | ||
446 | width = ((packet[0] & 0x30) >> 2) | ((packet[3] & 0x30) >> 4); | ||
447 | |||
448 | input_report_key(dev, BTN_TOUCH, fingers != 0); | ||
449 | if (fingers != 0) { | ||
450 | input_report_abs(dev, ABS_X, x1); | ||
451 | input_report_abs(dev, ABS_Y, y1); | ||
452 | } | ||
453 | elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2); | ||
454 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); | ||
455 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); | ||
456 | input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); | ||
457 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | ||
458 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | ||
459 | input_report_abs(dev, ABS_PRESSURE, pres); | ||
460 | input_report_abs(dev, ABS_TOOL_WIDTH, width); | ||
461 | |||
462 | input_sync(dev); | ||
463 | } | ||
464 | |||
465 | static void elantech_input_sync_v4(struct psmouse *psmouse) | ||
466 | { | ||
467 | struct input_dev *dev = psmouse->dev; | ||
468 | unsigned char *packet = psmouse->packet; | ||
469 | |||
470 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | ||
471 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | ||
472 | input_mt_report_pointer_emulation(dev, true); | ||
473 | input_sync(dev); | ||
474 | } | ||
475 | |||
476 | static void process_packet_status_v4(struct psmouse *psmouse) | ||
477 | { | ||
478 | struct input_dev *dev = psmouse->dev; | ||
479 | unsigned char *packet = psmouse->packet; | ||
480 | unsigned fingers; | ||
481 | int i; | ||
482 | |||
483 | /* notify finger state change */ | ||
484 | fingers = packet[1] & 0x1f; | ||
485 | for (i = 0; i < ETP_MAX_FINGERS; i++) { | ||
486 | if ((fingers & (1 << i)) == 0) { | ||
487 | input_mt_slot(dev, i); | ||
488 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, false); | ||
489 | } | ||
490 | } | ||
491 | |||
492 | elantech_input_sync_v4(psmouse); | ||
493 | } | ||
494 | |||
495 | static void process_packet_head_v4(struct psmouse *psmouse) | ||
496 | { | ||
497 | struct input_dev *dev = psmouse->dev; | ||
498 | struct elantech_data *etd = psmouse->private; | ||
499 | unsigned char *packet = psmouse->packet; | ||
500 | int id = ((packet[3] & 0xe0) >> 5) - 1; | ||
501 | int pres, traces; | ||
502 | |||
503 | if (id < 0) | ||
504 | return; | ||
505 | |||
506 | etd->mt[id].x = ((packet[1] & 0x0f) << 8) | packet[2]; | ||
507 | etd->mt[id].y = etd->y_max - (((packet[4] & 0x0f) << 8) | packet[5]); | ||
508 | pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4); | ||
509 | traces = (packet[0] & 0xf0) >> 4; | ||
510 | |||
511 | input_mt_slot(dev, id); | ||
512 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, true); | ||
513 | |||
514 | input_report_abs(dev, ABS_MT_POSITION_X, etd->mt[id].x); | ||
515 | input_report_abs(dev, ABS_MT_POSITION_Y, etd->mt[id].y); | ||
516 | input_report_abs(dev, ABS_MT_PRESSURE, pres); | ||
517 | input_report_abs(dev, ABS_MT_TOUCH_MAJOR, traces * etd->width); | ||
518 | /* report this for backwards compatibility */ | ||
519 | input_report_abs(dev, ABS_TOOL_WIDTH, traces); | ||
520 | |||
521 | elantech_input_sync_v4(psmouse); | ||
522 | } | ||
523 | |||
524 | static void process_packet_motion_v4(struct psmouse *psmouse) | ||
525 | { | ||
526 | struct input_dev *dev = psmouse->dev; | ||
527 | struct elantech_data *etd = psmouse->private; | ||
528 | unsigned char *packet = psmouse->packet; | ||
529 | int weight, delta_x1 = 0, delta_y1 = 0, delta_x2 = 0, delta_y2 = 0; | ||
530 | int id, sid; | ||
531 | |||
532 | id = ((packet[0] & 0xe0) >> 5) - 1; | ||
533 | if (id < 0) | ||
534 | return; | ||
535 | |||
536 | sid = ((packet[3] & 0xe0) >> 5) - 1; | ||
537 | weight = (packet[0] & 0x10) ? ETP_WEIGHT_VALUE : 1; | ||
538 | /* | ||
539 | * Motion packets give us the delta of x, y values of specific fingers, | ||
540 | * but in two's complement. Let the compiler do the conversion for us. | ||
541 | * Also _enlarge_ the numbers to int, in case of overflow. | ||
542 | */ | ||
543 | delta_x1 = (signed char)packet[1]; | ||
544 | delta_y1 = (signed char)packet[2]; | ||
545 | delta_x2 = (signed char)packet[4]; | ||
546 | delta_y2 = (signed char)packet[5]; | ||
547 | |||
548 | etd->mt[id].x += delta_x1 * weight; | ||
549 | etd->mt[id].y -= delta_y1 * weight; | ||
550 | input_mt_slot(dev, id); | ||
551 | input_report_abs(dev, ABS_MT_POSITION_X, etd->mt[id].x); | ||
552 | input_report_abs(dev, ABS_MT_POSITION_Y, etd->mt[id].y); | ||
553 | |||
554 | if (sid >= 0) { | ||
555 | etd->mt[sid].x += delta_x2 * weight; | ||
556 | etd->mt[sid].y -= delta_y2 * weight; | ||
557 | input_mt_slot(dev, sid); | ||
558 | input_report_abs(dev, ABS_MT_POSITION_X, etd->mt[sid].x); | ||
559 | input_report_abs(dev, ABS_MT_POSITION_Y, etd->mt[sid].y); | ||
560 | } | ||
561 | |||
562 | elantech_input_sync_v4(psmouse); | ||
563 | } | ||
564 | |||
565 | static void elantech_report_absolute_v4(struct psmouse *psmouse, | ||
566 | int packet_type) | ||
567 | { | ||
568 | switch (packet_type) { | ||
569 | case PACKET_V4_STATUS: | ||
570 | process_packet_status_v4(psmouse); | ||
571 | break; | ||
572 | |||
573 | case PACKET_V4_HEAD: | ||
574 | process_packet_head_v4(psmouse); | ||
575 | break; | ||
576 | |||
577 | case PACKET_V4_MOTION: | ||
578 | process_packet_motion_v4(psmouse); | ||
579 | break; | ||
580 | |||
581 | case PACKET_UNKNOWN: | ||
582 | default: | ||
583 | /* impossible to get here */ | ||
584 | break; | ||
585 | } | ||
586 | } | ||
587 | |||
588 | static int elantech_packet_check_v1(struct psmouse *psmouse) | ||
356 | { | 589 | { |
357 | struct elantech_data *etd = psmouse->private; | 590 | struct elantech_data *etd = psmouse->private; |
358 | unsigned char *packet = psmouse->packet; | 591 | unsigned char *packet = psmouse->packet; |
@@ -376,31 +609,142 @@ static int elantech_check_parity_v1(struct psmouse *psmouse) | |||
376 | etd->parity[packet[3]] == p3; | 609 | etd->parity[packet[3]] == p3; |
377 | } | 610 | } |
378 | 611 | ||
612 | static int elantech_debounce_check_v2(struct psmouse *psmouse) | ||
613 | { | ||
614 | /* | ||
615 | * When we encounter packet that matches this exactly, it means the | ||
616 | * hardware is in debounce status. Just ignore the whole packet. | ||
617 | */ | ||
618 | const u8 debounce_packet[] = { 0x84, 0xff, 0xff, 0x02, 0xff, 0xff }; | ||
619 | unsigned char *packet = psmouse->packet; | ||
620 | |||
621 | return !memcmp(packet, debounce_packet, sizeof(debounce_packet)); | ||
622 | } | ||
623 | |||
624 | static int elantech_packet_check_v2(struct psmouse *psmouse) | ||
625 | { | ||
626 | struct elantech_data *etd = psmouse->private; | ||
627 | unsigned char *packet = psmouse->packet; | ||
628 | |||
629 | /* | ||
630 | * V2 hardware has two flavors. Older ones that do not report pressure, | ||
631 | * and newer ones that reports pressure and width. With newer ones, all | ||
632 | * packets (1, 2, 3 finger touch) have the same constant bits. With | ||
633 | * older ones, 1/3 finger touch packets and 2 finger touch packets | ||
634 | * have different constant bits. | ||
635 | * With all three cases, if the constant bits are not exactly what I | ||
636 | * expected, I consider them invalid. | ||
637 | */ | ||
638 | if (etd->reports_pressure) | ||
639 | return (packet[0] & 0x0c) == 0x04 && | ||
640 | (packet[3] & 0x0f) == 0x02; | ||
641 | |||
642 | if ((packet[0] & 0xc0) == 0x80) | ||
643 | return (packet[0] & 0x0c) == 0x0c && | ||
644 | (packet[3] & 0x0e) == 0x08; | ||
645 | |||
646 | return (packet[0] & 0x3c) == 0x3c && | ||
647 | (packet[1] & 0xf0) == 0x00 && | ||
648 | (packet[3] & 0x3e) == 0x38 && | ||
649 | (packet[4] & 0xf0) == 0x00; | ||
650 | } | ||
651 | |||
652 | /* | ||
653 | * We check the constant bits to determine what packet type we get, | ||
654 | * so packet checking is mandatory for v3 and later hardware. | ||
655 | */ | ||
656 | static int elantech_packet_check_v3(struct psmouse *psmouse) | ||
657 | { | ||
658 | const u8 debounce_packet[] = { 0xc4, 0xff, 0xff, 0x02, 0xff, 0xff }; | ||
659 | unsigned char *packet = psmouse->packet; | ||
660 | |||
661 | /* | ||
662 | * check debounce first, it has the same signature in byte 0 | ||
663 | * and byte 3 as PACKET_V3_HEAD. | ||
664 | */ | ||
665 | if (!memcmp(packet, debounce_packet, sizeof(debounce_packet))) | ||
666 | return PACKET_DEBOUNCE; | ||
667 | |||
668 | if ((packet[0] & 0x0c) == 0x04 && (packet[3] & 0xcf) == 0x02) | ||
669 | return PACKET_V3_HEAD; | ||
670 | |||
671 | if ((packet[0] & 0x0c) == 0x0c && (packet[3] & 0xce) == 0x0c) | ||
672 | return PACKET_V3_TAIL; | ||
673 | |||
674 | return PACKET_UNKNOWN; | ||
675 | } | ||
676 | |||
677 | static int elantech_packet_check_v4(struct psmouse *psmouse) | ||
678 | { | ||
679 | unsigned char *packet = psmouse->packet; | ||
680 | |||
681 | if ((packet[0] & 0x0c) == 0x04 && | ||
682 | (packet[3] & 0x1f) == 0x11) | ||
683 | return PACKET_V4_HEAD; | ||
684 | |||
685 | if ((packet[0] & 0x0c) == 0x04 && | ||
686 | (packet[3] & 0x1f) == 0x12) | ||
687 | return PACKET_V4_MOTION; | ||
688 | |||
689 | if ((packet[0] & 0x0c) == 0x04 && | ||
690 | (packet[3] & 0x1f) == 0x10) | ||
691 | return PACKET_V4_STATUS; | ||
692 | |||
693 | return PACKET_UNKNOWN; | ||
694 | } | ||
695 | |||
379 | /* | 696 | /* |
380 | * Process byte stream from mouse and handle complete packets | 697 | * Process byte stream from mouse and handle complete packets |
381 | */ | 698 | */ |
382 | static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse) | 699 | static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse) |
383 | { | 700 | { |
384 | struct elantech_data *etd = psmouse->private; | 701 | struct elantech_data *etd = psmouse->private; |
702 | int packet_type; | ||
385 | 703 | ||
386 | if (psmouse->pktcnt < psmouse->pktsize) | 704 | if (psmouse->pktcnt < psmouse->pktsize) |
387 | return PSMOUSE_GOOD_DATA; | 705 | return PSMOUSE_GOOD_DATA; |
388 | 706 | ||
389 | if (etd->debug > 1) | 707 | if (etd->debug > 1) |
390 | elantech_packet_dump(psmouse->packet, psmouse->pktsize); | 708 | elantech_packet_dump(psmouse); |
391 | 709 | ||
392 | switch (etd->hw_version) { | 710 | switch (etd->hw_version) { |
393 | case 1: | 711 | case 1: |
394 | if (etd->paritycheck && !elantech_check_parity_v1(psmouse)) | 712 | if (etd->paritycheck && !elantech_packet_check_v1(psmouse)) |
395 | return PSMOUSE_BAD_DATA; | 713 | return PSMOUSE_BAD_DATA; |
396 | 714 | ||
397 | elantech_report_absolute_v1(psmouse); | 715 | elantech_report_absolute_v1(psmouse); |
398 | break; | 716 | break; |
399 | 717 | ||
400 | case 2: | 718 | case 2: |
401 | /* We don't know how to check parity in protocol v2 */ | 719 | /* ignore debounce */ |
720 | if (elantech_debounce_check_v2(psmouse)) | ||
721 | return PSMOUSE_FULL_PACKET; | ||
722 | |||
723 | if (etd->paritycheck && !elantech_packet_check_v2(psmouse)) | ||
724 | return PSMOUSE_BAD_DATA; | ||
725 | |||
402 | elantech_report_absolute_v2(psmouse); | 726 | elantech_report_absolute_v2(psmouse); |
403 | break; | 727 | break; |
728 | |||
729 | case 3: | ||
730 | packet_type = elantech_packet_check_v3(psmouse); | ||
731 | /* ignore debounce */ | ||
732 | if (packet_type == PACKET_DEBOUNCE) | ||
733 | return PSMOUSE_FULL_PACKET; | ||
734 | |||
735 | if (packet_type == PACKET_UNKNOWN) | ||
736 | return PSMOUSE_BAD_DATA; | ||
737 | |||
738 | elantech_report_absolute_v3(psmouse, packet_type); | ||
739 | break; | ||
740 | |||
741 | case 4: | ||
742 | packet_type = elantech_packet_check_v4(psmouse); | ||
743 | if (packet_type == PACKET_UNKNOWN) | ||
744 | return PSMOUSE_BAD_DATA; | ||
745 | |||
746 | elantech_report_absolute_v4(psmouse, packet_type); | ||
747 | break; | ||
404 | } | 748 | } |
405 | 749 | ||
406 | return PSMOUSE_FULL_PACKET; | 750 | return PSMOUSE_FULL_PACKET; |
@@ -435,15 +779,29 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse) | |||
435 | elantech_write_reg(psmouse, 0x11, etd->reg_11) || | 779 | elantech_write_reg(psmouse, 0x11, etd->reg_11) || |
436 | elantech_write_reg(psmouse, 0x21, etd->reg_21)) { | 780 | elantech_write_reg(psmouse, 0x21, etd->reg_21)) { |
437 | rc = -1; | 781 | rc = -1; |
438 | break; | ||
439 | } | 782 | } |
783 | break; | ||
784 | |||
785 | case 3: | ||
786 | etd->reg_10 = 0x0b; | ||
787 | if (elantech_write_reg(psmouse, 0x10, etd->reg_10)) | ||
788 | rc = -1; | ||
789 | |||
790 | break; | ||
791 | |||
792 | case 4: | ||
793 | etd->reg_07 = 0x01; | ||
794 | if (elantech_write_reg(psmouse, 0x07, etd->reg_07)) | ||
795 | rc = -1; | ||
796 | |||
797 | goto skip_readback_reg_10; /* v4 has no reg 0x10 to read */ | ||
440 | } | 798 | } |
441 | 799 | ||
442 | if (rc == 0) { | 800 | if (rc == 0) { |
443 | /* | 801 | /* |
444 | * Read back reg 0x10. For hardware version 1 we must make | 802 | * Read back reg 0x10. For hardware version 1 we must make |
445 | * sure the absolute mode bit is set. For hardware version 2 | 803 | * sure the absolute mode bit is set. For hardware version 2 |
446 | * the touchpad is probably initalising and not ready until | 804 | * the touchpad is probably initializing and not ready until |
447 | * we read back the value we just wrote. | 805 | * we read back the value we just wrote. |
448 | */ | 806 | */ |
449 | do { | 807 | do { |
@@ -456,27 +814,115 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse) | |||
456 | } while (tries > 0); | 814 | } while (tries > 0); |
457 | 815 | ||
458 | if (rc) { | 816 | if (rc) { |
459 | pr_err("failed to read back register 0x10.\n"); | 817 | psmouse_err(psmouse, |
818 | "failed to read back register 0x10.\n"); | ||
460 | } else if (etd->hw_version == 1 && | 819 | } else if (etd->hw_version == 1 && |
461 | !(val & ETP_R10_ABSOLUTE_MODE)) { | 820 | !(val & ETP_R10_ABSOLUTE_MODE)) { |
462 | pr_err("touchpad refuses to switch to absolute mode.\n"); | 821 | psmouse_err(psmouse, |
822 | "touchpad refuses to switch to absolute mode.\n"); | ||
463 | rc = -1; | 823 | rc = -1; |
464 | } | 824 | } |
465 | } | 825 | } |
466 | 826 | ||
827 | skip_readback_reg_10: | ||
467 | if (rc) | 828 | if (rc) |
468 | pr_err("failed to initialise registers.\n"); | 829 | psmouse_err(psmouse, "failed to initialise registers.\n"); |
469 | 830 | ||
470 | return rc; | 831 | return rc; |
471 | } | 832 | } |
472 | 833 | ||
834 | static int elantech_set_range(struct psmouse *psmouse, | ||
835 | unsigned int *x_min, unsigned int *y_min, | ||
836 | unsigned int *x_max, unsigned int *y_max, | ||
837 | unsigned int *width) | ||
838 | { | ||
839 | struct elantech_data *etd = psmouse->private; | ||
840 | unsigned char param[3]; | ||
841 | unsigned char traces; | ||
842 | |||
843 | switch (etd->hw_version) { | ||
844 | case 1: | ||
845 | *x_min = ETP_XMIN_V1; | ||
846 | *y_min = ETP_YMIN_V1; | ||
847 | *x_max = ETP_XMAX_V1; | ||
848 | *y_max = ETP_YMAX_V1; | ||
849 | break; | ||
850 | |||
851 | case 2: | ||
852 | if (etd->fw_version == 0x020800 || | ||
853 | etd->fw_version == 0x020b00 || | ||
854 | etd->fw_version == 0x020030) { | ||
855 | *x_min = ETP_XMIN_V2; | ||
856 | *y_min = ETP_YMIN_V2; | ||
857 | *x_max = ETP_XMAX_V2; | ||
858 | *y_max = ETP_YMAX_V2; | ||
859 | } else { | ||
860 | int i; | ||
861 | int fixed_dpi; | ||
862 | |||
863 | i = (etd->fw_version > 0x020800 && | ||
864 | etd->fw_version < 0x020900) ? 1 : 2; | ||
865 | |||
866 | if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param)) | ||
867 | return -1; | ||
868 | |||
869 | fixed_dpi = param[1] & 0x10; | ||
870 | |||
871 | if (((etd->fw_version >> 16) == 0x14) && fixed_dpi) { | ||
872 | if (synaptics_send_cmd(psmouse, ETP_SAMPLE_QUERY, param)) | ||
873 | return -1; | ||
874 | |||
875 | *x_max = (etd->capabilities[1] - i) * param[1] / 2; | ||
876 | *y_max = (etd->capabilities[2] - i) * param[2] / 2; | ||
877 | } else if (etd->fw_version == 0x040216) { | ||
878 | *x_max = 819; | ||
879 | *y_max = 405; | ||
880 | } else if (etd->fw_version == 0x040219 || etd->fw_version == 0x040215) { | ||
881 | *x_max = 900; | ||
882 | *y_max = 500; | ||
883 | } else { | ||
884 | *x_max = (etd->capabilities[1] - i) * 64; | ||
885 | *y_max = (etd->capabilities[2] - i) * 64; | ||
886 | } | ||
887 | } | ||
888 | break; | ||
889 | |||
890 | case 3: | ||
891 | if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param)) | ||
892 | return -1; | ||
893 | |||
894 | *x_max = (0x0f & param[0]) << 8 | param[1]; | ||
895 | *y_max = (0xf0 & param[0]) << 4 | param[2]; | ||
896 | break; | ||
897 | |||
898 | case 4: | ||
899 | if (synaptics_send_cmd(psmouse, ETP_FW_ID_QUERY, param)) | ||
900 | return -1; | ||
901 | |||
902 | *x_max = (0x0f & param[0]) << 8 | param[1]; | ||
903 | *y_max = (0xf0 & param[0]) << 4 | param[2]; | ||
904 | traces = etd->capabilities[1]; | ||
905 | if ((traces < 2) || (traces > *x_max)) | ||
906 | return -1; | ||
907 | |||
908 | *width = *x_max / (traces - 1); | ||
909 | break; | ||
910 | } | ||
911 | |||
912 | return 0; | ||
913 | } | ||
914 | |||
473 | /* | 915 | /* |
474 | * Set the appropriate event bits for the input subsystem | 916 | * Set the appropriate event bits for the input subsystem |
475 | */ | 917 | */ |
476 | static void elantech_set_input_params(struct psmouse *psmouse) | 918 | static int elantech_set_input_params(struct psmouse *psmouse) |
477 | { | 919 | { |
478 | struct input_dev *dev = psmouse->dev; | 920 | struct input_dev *dev = psmouse->dev; |
479 | struct elantech_data *etd = psmouse->private; | 921 | struct elantech_data *etd = psmouse->private; |
922 | unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, width = 0; | ||
923 | |||
924 | if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &width)) | ||
925 | return -1; | ||
480 | 926 | ||
481 | __set_bit(EV_KEY, dev->evbit); | 927 | __set_bit(EV_KEY, dev->evbit); |
482 | __set_bit(EV_ABS, dev->evbit); | 928 | __set_bit(EV_ABS, dev->evbit); |
@@ -494,30 +940,64 @@ static void elantech_set_input_params(struct psmouse *psmouse) | |||
494 | case 1: | 940 | case 1: |
495 | /* Rocker button */ | 941 | /* Rocker button */ |
496 | if (etd->fw_version < 0x020000 && | 942 | if (etd->fw_version < 0x020000 && |
497 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { | 943 | (etd->capabilities[0] & ETP_CAP_HAS_ROCKER)) { |
498 | __set_bit(BTN_FORWARD, dev->keybit); | 944 | __set_bit(BTN_FORWARD, dev->keybit); |
499 | __set_bit(BTN_BACK, dev->keybit); | 945 | __set_bit(BTN_BACK, dev->keybit); |
500 | } | 946 | } |
501 | input_set_abs_params(dev, ABS_X, ETP_XMIN_V1, ETP_XMAX_V1, 0, 0); | 947 | input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0); |
502 | input_set_abs_params(dev, ABS_Y, ETP_YMIN_V1, ETP_YMAX_V1, 0, 0); | 948 | input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0); |
503 | break; | 949 | break; |
504 | 950 | ||
505 | case 2: | 951 | case 2: |
506 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); | 952 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); |
507 | input_set_abs_params(dev, ABS_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0); | 953 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); |
508 | input_set_abs_params(dev, ABS_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0); | 954 | /* fall through */ |
955 | case 3: | ||
956 | input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0); | ||
957 | input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0); | ||
509 | if (etd->reports_pressure) { | 958 | if (etd->reports_pressure) { |
510 | input_set_abs_params(dev, ABS_PRESSURE, ETP_PMIN_V2, | 959 | input_set_abs_params(dev, ABS_PRESSURE, ETP_PMIN_V2, |
511 | ETP_PMAX_V2, 0, 0); | 960 | ETP_PMAX_V2, 0, 0); |
512 | input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, | 961 | input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, |
513 | ETP_WMAX_V2, 0, 0); | 962 | ETP_WMAX_V2, 0, 0); |
514 | } | 963 | } |
515 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); | ||
516 | input_mt_init_slots(dev, 2); | 964 | input_mt_init_slots(dev, 2); |
517 | input_set_abs_params(dev, ABS_MT_POSITION_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0); | 965 | input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); |
518 | input_set_abs_params(dev, ABS_MT_POSITION_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0); | 966 | input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); |
967 | break; | ||
968 | |||
969 | case 4: | ||
970 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); | ||
971 | /* For X to recognize me as touchpad. */ | ||
972 | input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0); | ||
973 | input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0); | ||
974 | /* | ||
975 | * range of pressure and width is the same as v2, | ||
976 | * report ABS_PRESSURE, ABS_TOOL_WIDTH for compatibility. | ||
977 | */ | ||
978 | input_set_abs_params(dev, ABS_PRESSURE, ETP_PMIN_V2, | ||
979 | ETP_PMAX_V2, 0, 0); | ||
980 | input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, | ||
981 | ETP_WMAX_V2, 0, 0); | ||
982 | /* Multitouch capable pad, up to 5 fingers. */ | ||
983 | input_mt_init_slots(dev, ETP_MAX_FINGERS); | ||
984 | input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); | ||
985 | input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); | ||
986 | input_set_abs_params(dev, ABS_MT_PRESSURE, ETP_PMIN_V2, | ||
987 | ETP_PMAX_V2, 0, 0); | ||
988 | /* | ||
989 | * The firmware reports how many trace lines the finger spans, | ||
990 | * convert to surface unit as Protocol-B requires. | ||
991 | */ | ||
992 | input_set_abs_params(dev, ABS_MT_TOUCH_MAJOR, 0, | ||
993 | ETP_WMAX_V2 * width, 0, 0); | ||
519 | break; | 994 | break; |
520 | } | 995 | } |
996 | |||
997 | etd->y_max = y_max; | ||
998 | etd->width = width; | ||
999 | |||
1000 | return 0; | ||
521 | } | 1001 | } |
522 | 1002 | ||
523 | struct elantech_attr_data { | 1003 | struct elantech_attr_data { |
@@ -587,6 +1067,7 @@ static ssize_t elantech_set_int_attr(struct psmouse *psmouse, | |||
587 | elantech_show_int_attr, \ | 1067 | elantech_show_int_attr, \ |
588 | elantech_set_int_attr) | 1068 | elantech_set_int_attr) |
589 | 1069 | ||
1070 | ELANTECH_INT_ATTR(reg_07, 0x07); | ||
590 | ELANTECH_INT_ATTR(reg_10, 0x10); | 1071 | ELANTECH_INT_ATTR(reg_10, 0x10); |
591 | ELANTECH_INT_ATTR(reg_11, 0x11); | 1072 | ELANTECH_INT_ATTR(reg_11, 0x11); |
592 | ELANTECH_INT_ATTR(reg_20, 0x20); | 1073 | ELANTECH_INT_ATTR(reg_20, 0x20); |
@@ -600,6 +1081,7 @@ ELANTECH_INT_ATTR(debug, 0); | |||
600 | ELANTECH_INT_ATTR(paritycheck, 0); | 1081 | ELANTECH_INT_ATTR(paritycheck, 0); |
601 | 1082 | ||
602 | static struct attribute *elantech_attrs[] = { | 1083 | static struct attribute *elantech_attrs[] = { |
1084 | &psmouse_attr_reg_07.dattr.attr, | ||
603 | &psmouse_attr_reg_10.dattr.attr, | 1085 | &psmouse_attr_reg_10.dattr.attr, |
604 | &psmouse_attr_reg_11.dattr.attr, | 1086 | &psmouse_attr_reg_11.dattr.attr, |
605 | &psmouse_attr_reg_20.dattr.attr, | 1087 | &psmouse_attr_reg_20.dattr.attr, |
@@ -651,7 +1133,7 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) | |||
651 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | 1133 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || |
652 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | 1134 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || |
653 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { | 1135 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { |
654 | pr_debug("sending Elantech magic knock failed.\n"); | 1136 | psmouse_dbg(psmouse, "sending Elantech magic knock failed.\n"); |
655 | return -1; | 1137 | return -1; |
656 | } | 1138 | } |
657 | 1139 | ||
@@ -659,9 +1141,11 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) | |||
659 | * Report this in case there are Elantech models that use a different | 1141 | * Report this in case there are Elantech models that use a different |
660 | * set of magic numbers | 1142 | * set of magic numbers |
661 | */ | 1143 | */ |
662 | if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) { | 1144 | if (param[0] != 0x3c || param[1] != 0x03 || |
663 | pr_debug("unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n", | 1145 | (param[2] != 0xc8 && param[2] != 0x00)) { |
664 | param[0], param[1], param[2]); | 1146 | psmouse_dbg(psmouse, |
1147 | "unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n", | ||
1148 | param[0], param[1], param[2]); | ||
665 | return -1; | 1149 | return -1; |
666 | } | 1150 | } |
667 | 1151 | ||
@@ -671,20 +1155,18 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) | |||
671 | * to Elantech magic knock and there might be more. | 1155 | * to Elantech magic knock and there might be more. |
672 | */ | 1156 | */ |
673 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { | 1157 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { |
674 | pr_debug("failed to query firmware version.\n"); | 1158 | psmouse_dbg(psmouse, "failed to query firmware version.\n"); |
675 | return -1; | 1159 | return -1; |
676 | } | 1160 | } |
677 | 1161 | ||
678 | pr_debug("Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n", | 1162 | psmouse_dbg(psmouse, |
679 | param[0], param[1], param[2]); | 1163 | "Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n", |
1164 | param[0], param[1], param[2]); | ||
680 | 1165 | ||
681 | if (!elantech_is_signature_valid(param)) { | 1166 | if (!elantech_is_signature_valid(param)) { |
682 | if (!force_elantech) { | 1167 | psmouse_dbg(psmouse, |
683 | pr_debug("Probably not a real Elantech touchpad. Aborting.\n"); | 1168 | "Probably not a real Elantech touchpad. Aborting.\n"); |
684 | return -1; | 1169 | return -1; |
685 | } | ||
686 | |||
687 | pr_debug("Probably not a real Elantech touchpad. Enabling anyway due to force_elantech.\n"); | ||
688 | } | 1170 | } |
689 | 1171 | ||
690 | if (set_properties) { | 1172 | if (set_properties) { |
@@ -715,7 +1197,8 @@ static int elantech_reconnect(struct psmouse *psmouse) | |||
715 | return -1; | 1197 | return -1; |
716 | 1198 | ||
717 | if (elantech_set_absolute_mode(psmouse)) { | 1199 | if (elantech_set_absolute_mode(psmouse)) { |
718 | pr_err("failed to put touchpad back into absolute mode.\n"); | 1200 | psmouse_err(psmouse, |
1201 | "failed to put touchpad back into absolute mode.\n"); | ||
719 | return -1; | 1202 | return -1; |
720 | } | 1203 | } |
721 | 1204 | ||
@@ -723,6 +1206,48 @@ static int elantech_reconnect(struct psmouse *psmouse) | |||
723 | } | 1206 | } |
724 | 1207 | ||
725 | /* | 1208 | /* |
1209 | * determine hardware version and set some properties according to it. | ||
1210 | */ | ||
1211 | static int elantech_set_properties(struct elantech_data *etd) | ||
1212 | { | ||
1213 | int ver = (etd->fw_version & 0x0f0000) >> 16; | ||
1214 | |||
1215 | if (etd->fw_version < 0x020030 || etd->fw_version == 0x020600) | ||
1216 | etd->hw_version = 1; | ||
1217 | else if (etd->fw_version < 0x150600) | ||
1218 | etd->hw_version = 2; | ||
1219 | else if (ver == 5) | ||
1220 | etd->hw_version = 3; | ||
1221 | else if (ver == 6) | ||
1222 | etd->hw_version = 4; | ||
1223 | else | ||
1224 | return -1; | ||
1225 | |||
1226 | /* | ||
1227 | * Turn on packet checking by default. | ||
1228 | */ | ||
1229 | etd->paritycheck = 1; | ||
1230 | |||
1231 | /* | ||
1232 | * This firmware suffers from misreporting coordinates when | ||
1233 | * a touch action starts causing the mouse cursor or scrolled page | ||
1234 | * to jump. Enable a workaround. | ||
1235 | */ | ||
1236 | etd->jumpy_cursor = | ||
1237 | (etd->fw_version == 0x020022 || etd->fw_version == 0x020600); | ||
1238 | |||
1239 | if (etd->hw_version > 1) { | ||
1240 | /* For now show extra debug information */ | ||
1241 | etd->debug = 1; | ||
1242 | |||
1243 | if (etd->fw_version >= 0x020800) | ||
1244 | etd->reports_pressure = true; | ||
1245 | } | ||
1246 | |||
1247 | return 0; | ||
1248 | } | ||
1249 | |||
1250 | /* | ||
726 | * Initialize the touchpad and create sysfs entries | 1251 | * Initialize the touchpad and create sysfs entries |
727 | */ | 1252 | */ |
728 | int elantech_init(struct psmouse *psmouse) | 1253 | int elantech_init(struct psmouse *psmouse) |
@@ -743,70 +1268,53 @@ int elantech_init(struct psmouse *psmouse) | |||
743 | * Do the version query again so we can store the result | 1268 | * Do the version query again so we can store the result |
744 | */ | 1269 | */ |
745 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { | 1270 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { |
746 | pr_err("failed to query firmware version.\n"); | 1271 | psmouse_err(psmouse, "failed to query firmware version.\n"); |
747 | goto init_fail; | 1272 | goto init_fail; |
748 | } | 1273 | } |
749 | |||
750 | etd->fw_version = (param[0] << 16) | (param[1] << 8) | param[2]; | 1274 | etd->fw_version = (param[0] << 16) | (param[1] << 8) | param[2]; |
751 | 1275 | ||
752 | /* | 1276 | if (elantech_set_properties(etd)) { |
753 | * Assume every version greater than this is new EeePC style | 1277 | psmouse_err(psmouse, "unknown hardware version, aborting...\n"); |
754 | * hardware with 6 byte packets | ||
755 | */ | ||
756 | if (etd->fw_version >= 0x020030) { | ||
757 | etd->hw_version = 2; | ||
758 | /* For now show extra debug information */ | ||
759 | etd->debug = 1; | ||
760 | /* Don't know how to do parity checking for version 2 */ | ||
761 | etd->paritycheck = 0; | ||
762 | |||
763 | if (etd->fw_version >= 0x020800) | ||
764 | etd->reports_pressure = true; | ||
765 | |||
766 | } else { | ||
767 | etd->hw_version = 1; | ||
768 | etd->paritycheck = 1; | ||
769 | } | ||
770 | |||
771 | pr_info("assuming hardware version %d, firmware version %d.%d.%d\n", | ||
772 | etd->hw_version, param[0], param[1], param[2]); | ||
773 | |||
774 | if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) { | ||
775 | pr_err("failed to query capabilities.\n"); | ||
776 | goto init_fail; | 1278 | goto init_fail; |
777 | } | 1279 | } |
778 | pr_info("Synaptics capabilities query result 0x%02x, 0x%02x, 0x%02x.\n", | 1280 | psmouse_info(psmouse, |
779 | param[0], param[1], param[2]); | 1281 | "assuming hardware version %d (with firmware version 0x%02x%02x%02x)\n", |
780 | etd->capabilities = param[0]; | 1282 | etd->hw_version, param[0], param[1], param[2]); |
781 | 1283 | ||
782 | /* | 1284 | if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, |
783 | * This firmware suffers from misreporting coordinates when | 1285 | etd->capabilities)) { |
784 | * a touch action starts causing the mouse cursor or scrolled page | 1286 | psmouse_err(psmouse, "failed to query capabilities.\n"); |
785 | * to jump. Enable a workaround. | 1287 | goto init_fail; |
786 | */ | ||
787 | if (etd->fw_version == 0x020022 || etd->fw_version == 0x020600) { | ||
788 | pr_info("firmware version 2.0.34/2.6.0 detected, enabling jumpy cursor workaround\n"); | ||
789 | etd->jumpy_cursor = true; | ||
790 | } | 1288 | } |
1289 | psmouse_info(psmouse, | ||
1290 | "Synaptics capabilities query result 0x%02x, 0x%02x, 0x%02x.\n", | ||
1291 | etd->capabilities[0], etd->capabilities[1], | ||
1292 | etd->capabilities[2]); | ||
791 | 1293 | ||
792 | if (elantech_set_absolute_mode(psmouse)) { | 1294 | if (elantech_set_absolute_mode(psmouse)) { |
793 | pr_err("failed to put touchpad into absolute mode.\n"); | 1295 | psmouse_err(psmouse, |
1296 | "failed to put touchpad into absolute mode.\n"); | ||
794 | goto init_fail; | 1297 | goto init_fail; |
795 | } | 1298 | } |
796 | 1299 | ||
797 | elantech_set_input_params(psmouse); | 1300 | if (elantech_set_input_params(psmouse)) { |
1301 | psmouse_err(psmouse, "failed to query touchpad range.\n"); | ||
1302 | goto init_fail; | ||
1303 | } | ||
798 | 1304 | ||
799 | error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj, | 1305 | error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj, |
800 | &elantech_attr_group); | 1306 | &elantech_attr_group); |
801 | if (error) { | 1307 | if (error) { |
802 | pr_err("failed to create sysfs attributes, error: %d.\n", error); | 1308 | psmouse_err(psmouse, |
1309 | "failed to create sysfs attributes, error: %d.\n", | ||
1310 | error); | ||
803 | goto init_fail; | 1311 | goto init_fail; |
804 | } | 1312 | } |
805 | 1313 | ||
806 | psmouse->protocol_handler = elantech_process_byte; | 1314 | psmouse->protocol_handler = elantech_process_byte; |
807 | psmouse->disconnect = elantech_disconnect; | 1315 | psmouse->disconnect = elantech_disconnect; |
808 | psmouse->reconnect = elantech_reconnect; | 1316 | psmouse->reconnect = elantech_reconnect; |
809 | psmouse->pktsize = etd->hw_version == 2 ? 6 : 4; | 1317 | psmouse->pktsize = etd->hw_version > 1 ? 6 : 4; |
810 | 1318 | ||
811 | return 0; | 1319 | return 0; |
812 | 1320 | ||
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index fabb2b99615c..9e5f1aabea7e 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h | |||
@@ -16,14 +16,17 @@ | |||
16 | /* | 16 | /* |
17 | * Command values for Synaptics style queries | 17 | * Command values for Synaptics style queries |
18 | */ | 18 | */ |
19 | #define ETP_FW_ID_QUERY 0x00 | ||
19 | #define ETP_FW_VERSION_QUERY 0x01 | 20 | #define ETP_FW_VERSION_QUERY 0x01 |
20 | #define ETP_CAPABILITIES_QUERY 0x02 | 21 | #define ETP_CAPABILITIES_QUERY 0x02 |
22 | #define ETP_SAMPLE_QUERY 0x03 | ||
21 | 23 | ||
22 | /* | 24 | /* |
23 | * Command values for register reading or writing | 25 | * Command values for register reading or writing |
24 | */ | 26 | */ |
25 | #define ETP_REGISTER_READ 0x10 | 27 | #define ETP_REGISTER_READ 0x10 |
26 | #define ETP_REGISTER_WRITE 0x11 | 28 | #define ETP_REGISTER_WRITE 0x11 |
29 | #define ETP_REGISTER_READWRITE 0x00 | ||
27 | 30 | ||
28 | /* | 31 | /* |
29 | * Hardware version 2 custom PS/2 command value | 32 | * Hardware version 2 custom PS/2 command value |
@@ -66,16 +69,13 @@ | |||
66 | #define ETP_YMAX_V1 (384 - ETP_EDGE_FUZZ_V1) | 69 | #define ETP_YMAX_V1 (384 - ETP_EDGE_FUZZ_V1) |
67 | 70 | ||
68 | /* | 71 | /* |
69 | * It seems the resolution for hardware version 2 doubled. | 72 | * The resolution for older v2 hardware doubled. |
70 | * Hence the X and Y ranges are doubled too. | 73 | * (newer v2's firmware provides command so we can query) |
71 | * The bezel around the pad also appears to be smaller | ||
72 | */ | 74 | */ |
73 | #define ETP_EDGE_FUZZ_V2 8 | 75 | #define ETP_XMIN_V2 0 |
74 | 76 | #define ETP_XMAX_V2 1152 | |
75 | #define ETP_XMIN_V2 ( 0 + ETP_EDGE_FUZZ_V2) | 77 | #define ETP_YMIN_V2 0 |
76 | #define ETP_XMAX_V2 (1152 - ETP_EDGE_FUZZ_V2) | 78 | #define ETP_YMAX_V2 768 |
77 | #define ETP_YMIN_V2 ( 0 + ETP_EDGE_FUZZ_V2) | ||
78 | #define ETP_YMAX_V2 ( 768 - ETP_EDGE_FUZZ_V2) | ||
79 | 79 | ||
80 | #define ETP_PMIN_V2 0 | 80 | #define ETP_PMIN_V2 0 |
81 | #define ETP_PMAX_V2 255 | 81 | #define ETP_PMAX_V2 255 |
@@ -83,17 +83,37 @@ | |||
83 | #define ETP_WMAX_V2 15 | 83 | #define ETP_WMAX_V2 15 |
84 | 84 | ||
85 | /* | 85 | /* |
86 | * For two finger touches the coordinate of each finger gets reported | 86 | * v3 hardware has 2 kinds of packet types, |
87 | * separately but with reduced resolution. | 87 | * v4 hardware has 3. |
88 | */ | ||
89 | #define PACKET_UNKNOWN 0x01 | ||
90 | #define PACKET_DEBOUNCE 0x02 | ||
91 | #define PACKET_V3_HEAD 0x03 | ||
92 | #define PACKET_V3_TAIL 0x04 | ||
93 | #define PACKET_V4_HEAD 0x05 | ||
94 | #define PACKET_V4_MOTION 0x06 | ||
95 | #define PACKET_V4_STATUS 0x07 | ||
96 | |||
97 | /* | ||
98 | * track up to 5 fingers for v4 hardware | ||
99 | */ | ||
100 | #define ETP_MAX_FINGERS 5 | ||
101 | |||
102 | /* | ||
103 | * weight value for v4 hardware | ||
88 | */ | 104 | */ |
89 | #define ETP_2FT_FUZZ 4 | 105 | #define ETP_WEIGHT_VALUE 5 |
90 | 106 | ||
91 | #define ETP_2FT_XMIN ( 0 + ETP_2FT_FUZZ) | 107 | /* |
92 | #define ETP_2FT_XMAX (288 - ETP_2FT_FUZZ) | 108 | * The base position for one finger, v4 hardware |
93 | #define ETP_2FT_YMIN ( 0 + ETP_2FT_FUZZ) | 109 | */ |
94 | #define ETP_2FT_YMAX (192 - ETP_2FT_FUZZ) | 110 | struct finger_pos { |
111 | unsigned int x; | ||
112 | unsigned int y; | ||
113 | }; | ||
95 | 114 | ||
96 | struct elantech_data { | 115 | struct elantech_data { |
116 | unsigned char reg_07; | ||
97 | unsigned char reg_10; | 117 | unsigned char reg_10; |
98 | unsigned char reg_11; | 118 | unsigned char reg_11; |
99 | unsigned char reg_20; | 119 | unsigned char reg_20; |
@@ -104,13 +124,16 @@ struct elantech_data { | |||
104 | unsigned char reg_25; | 124 | unsigned char reg_25; |
105 | unsigned char reg_26; | 125 | unsigned char reg_26; |
106 | unsigned char debug; | 126 | unsigned char debug; |
107 | unsigned char capabilities; | 127 | unsigned char capabilities[3]; |
108 | bool paritycheck; | 128 | bool paritycheck; |
109 | bool jumpy_cursor; | 129 | bool jumpy_cursor; |
110 | bool reports_pressure; | 130 | bool reports_pressure; |
111 | unsigned char hw_version; | 131 | unsigned char hw_version; |
112 | unsigned int fw_version; | 132 | unsigned int fw_version; |
113 | unsigned int single_finger_reports; | 133 | unsigned int single_finger_reports; |
134 | unsigned int y_max; | ||
135 | unsigned int width; | ||
136 | struct finger_pos mt[ETP_MAX_FINGERS]; | ||
114 | unsigned char parity[256]; | 137 | unsigned char parity[256]; |
115 | }; | 138 | }; |
116 | 139 | ||
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index 4d17d9f3320b..0470dd46b566 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c | |||
@@ -136,10 +136,10 @@ static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y) | |||
136 | /* discard if too big, or half that but > 4 times the prev delta */ | 136 | /* discard if too big, or half that but > 4 times the prev delta */ |
137 | if (avx > recalib_delta || | 137 | if (avx > recalib_delta || |
138 | (avx > recalib_delta / 2 && ((avx / 4) > priv->xlast))) { | 138 | (avx > recalib_delta / 2 && ((avx / 4) > priv->xlast))) { |
139 | hgpk_err(psmouse, "detected %dpx jump in x\n", x); | 139 | psmouse_warn(psmouse, "detected %dpx jump in x\n", x); |
140 | priv->xbigj = avx; | 140 | priv->xbigj = avx; |
141 | } else if (approx_half(avx, priv->xbigj)) { | 141 | } else if (approx_half(avx, priv->xbigj)) { |
142 | hgpk_err(psmouse, "detected secondary %dpx jump in x\n", x); | 142 | psmouse_warn(psmouse, "detected secondary %dpx jump in x\n", x); |
143 | priv->xbigj = avx; | 143 | priv->xbigj = avx; |
144 | priv->xsaw_secondary++; | 144 | priv->xsaw_secondary++; |
145 | } else { | 145 | } else { |
@@ -151,10 +151,10 @@ static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y) | |||
151 | 151 | ||
152 | if (avy > recalib_delta || | 152 | if (avy > recalib_delta || |
153 | (avy > recalib_delta / 2 && ((avy / 4) > priv->ylast))) { | 153 | (avy > recalib_delta / 2 && ((avy / 4) > priv->ylast))) { |
154 | hgpk_err(psmouse, "detected %dpx jump in y\n", y); | 154 | psmouse_warn(psmouse, "detected %dpx jump in y\n", y); |
155 | priv->ybigj = avy; | 155 | priv->ybigj = avy; |
156 | } else if (approx_half(avy, priv->ybigj)) { | 156 | } else if (approx_half(avy, priv->ybigj)) { |
157 | hgpk_err(psmouse, "detected secondary %dpx jump in y\n", y); | 157 | psmouse_warn(psmouse, "detected secondary %dpx jump in y\n", y); |
158 | priv->ybigj = avy; | 158 | priv->ybigj = avy; |
159 | priv->ysaw_secondary++; | 159 | priv->ysaw_secondary++; |
160 | } else { | 160 | } else { |
@@ -168,7 +168,7 @@ static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y) | |||
168 | priv->ylast = avy; | 168 | priv->ylast = avy; |
169 | 169 | ||
170 | if (do_recal && jumpy_delay) { | 170 | if (do_recal && jumpy_delay) { |
171 | hgpk_err(psmouse, "scheduling recalibration\n"); | 171 | psmouse_warn(psmouse, "scheduling recalibration\n"); |
172 | psmouse_queue_work(psmouse, &priv->recalib_wq, | 172 | psmouse_queue_work(psmouse, &priv->recalib_wq, |
173 | msecs_to_jiffies(jumpy_delay)); | 173 | msecs_to_jiffies(jumpy_delay)); |
174 | } | 174 | } |
@@ -260,8 +260,8 @@ static void hgpk_spewing_hack(struct psmouse *psmouse, | |||
260 | * movement, it is probably a case of the user moving the | 260 | * movement, it is probably a case of the user moving the |
261 | * cursor very slowly across the screen. */ | 261 | * cursor very slowly across the screen. */ |
262 | if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) { | 262 | if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) { |
263 | hgpk_err(psmouse, "packet spew detected (%d,%d)\n", | 263 | psmouse_warn(psmouse, "packet spew detected (%d,%d)\n", |
264 | priv->x_tally, priv->y_tally); | 264 | priv->x_tally, priv->y_tally); |
265 | priv->spew_flag = RECALIBRATING; | 265 | priv->spew_flag = RECALIBRATING; |
266 | psmouse_queue_work(psmouse, &priv->recalib_wq, | 266 | psmouse_queue_work(psmouse, &priv->recalib_wq, |
267 | msecs_to_jiffies(spew_delay)); | 267 | msecs_to_jiffies(spew_delay)); |
@@ -333,12 +333,12 @@ static bool hgpk_is_byte_valid(struct psmouse *psmouse, unsigned char *packet) | |||
333 | } | 333 | } |
334 | 334 | ||
335 | if (!valid) | 335 | if (!valid) |
336 | hgpk_dbg(psmouse, | 336 | psmouse_dbg(psmouse, |
337 | "bad data, mode %d (%d) %02x %02x %02x %02x %02x %02x\n", | 337 | "bad data, mode %d (%d) %02x %02x %02x %02x %02x %02x\n", |
338 | priv->mode, pktcnt, | 338 | priv->mode, pktcnt, |
339 | psmouse->packet[0], psmouse->packet[1], | 339 | psmouse->packet[0], psmouse->packet[1], |
340 | psmouse->packet[2], psmouse->packet[3], | 340 | psmouse->packet[2], psmouse->packet[3], |
341 | psmouse->packet[4], psmouse->packet[5]); | 341 | psmouse->packet[4], psmouse->packet[5]); |
342 | 342 | ||
343 | return valid; | 343 | return valid; |
344 | } | 344 | } |
@@ -361,19 +361,20 @@ static void hgpk_process_advanced_packet(struct psmouse *psmouse) | |||
361 | 361 | ||
362 | input_report_abs(idev, ABS_PRESSURE, z); | 362 | input_report_abs(idev, ABS_PRESSURE, z); |
363 | if (tpdebug) | 363 | if (tpdebug) |
364 | hgpk_dbg(psmouse, "pd=%d fd=%d z=%d", | 364 | psmouse_dbg(psmouse, "pd=%d fd=%d z=%d", |
365 | pt_down, finger_down, z); | 365 | pt_down, finger_down, z); |
366 | } else { | 366 | } else { |
367 | /* | 367 | /* |
368 | * PenTablet mode does not report pressure, so we don't | 368 | * PenTablet mode does not report pressure, so we don't |
369 | * report it here | 369 | * report it here |
370 | */ | 370 | */ |
371 | if (tpdebug) | 371 | if (tpdebug) |
372 | hgpk_dbg(psmouse, "pd=%d ", down); | 372 | psmouse_dbg(psmouse, "pd=%d ", down); |
373 | } | 373 | } |
374 | 374 | ||
375 | if (tpdebug) | 375 | if (tpdebug) |
376 | hgpk_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", left, right, x, y); | 376 | psmouse_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", |
377 | left, right, x, y); | ||
377 | 378 | ||
378 | input_report_key(idev, BTN_TOUCH, down); | 379 | input_report_key(idev, BTN_TOUCH, down); |
379 | input_report_key(idev, BTN_LEFT, left); | 380 | input_report_key(idev, BTN_LEFT, left); |
@@ -395,7 +396,7 @@ static void hgpk_process_advanced_packet(struct psmouse *psmouse) | |||
395 | if (x == priv->abs_x && y == priv->abs_y) { | 396 | if (x == priv->abs_x && y == priv->abs_y) { |
396 | if (++priv->dupe_count > SPEW_WATCH_COUNT) { | 397 | if (++priv->dupe_count > SPEW_WATCH_COUNT) { |
397 | if (tpdebug) | 398 | if (tpdebug) |
398 | hgpk_dbg(psmouse, "hard spew detected\n"); | 399 | psmouse_dbg(psmouse, "hard spew detected\n"); |
399 | priv->spew_flag = RECALIBRATING; | 400 | priv->spew_flag = RECALIBRATING; |
400 | psmouse_queue_work(psmouse, &priv->recalib_wq, | 401 | psmouse_queue_work(psmouse, &priv->recalib_wq, |
401 | msecs_to_jiffies(spew_delay)); | 402 | msecs_to_jiffies(spew_delay)); |
@@ -412,7 +413,7 @@ static void hgpk_process_advanced_packet(struct psmouse *psmouse) | |||
412 | int y_diff = priv->abs_y - y; | 413 | int y_diff = priv->abs_y - y; |
413 | if (hgpk_discard_decay_hack(psmouse, x_diff, y_diff)) { | 414 | if (hgpk_discard_decay_hack(psmouse, x_diff, y_diff)) { |
414 | if (tpdebug) | 415 | if (tpdebug) |
415 | hgpk_dbg(psmouse, "discarding\n"); | 416 | psmouse_dbg(psmouse, "discarding\n"); |
416 | goto done; | 417 | goto done; |
417 | } | 418 | } |
418 | hgpk_spewing_hack(psmouse, left, right, x_diff, y_diff); | 419 | hgpk_spewing_hack(psmouse, left, right, x_diff, y_diff); |
@@ -437,20 +438,21 @@ static void hgpk_process_simple_packet(struct psmouse *psmouse) | |||
437 | int y = ((packet[0] << 3) & 0x100) - packet[2]; | 438 | int y = ((packet[0] << 3) & 0x100) - packet[2]; |
438 | 439 | ||
439 | if (packet[0] & 0xc0) | 440 | if (packet[0] & 0xc0) |
440 | hgpk_dbg(psmouse, | 441 | psmouse_dbg(psmouse, |
441 | "overflow -- 0x%02x 0x%02x 0x%02x\n", | 442 | "overflow -- 0x%02x 0x%02x 0x%02x\n", |
442 | packet[0], packet[1], packet[2]); | 443 | packet[0], packet[1], packet[2]); |
443 | 444 | ||
444 | if (hgpk_discard_decay_hack(psmouse, x, y)) { | 445 | if (hgpk_discard_decay_hack(psmouse, x, y)) { |
445 | if (tpdebug) | 446 | if (tpdebug) |
446 | hgpk_dbg(psmouse, "discarding\n"); | 447 | psmouse_dbg(psmouse, "discarding\n"); |
447 | return; | 448 | return; |
448 | } | 449 | } |
449 | 450 | ||
450 | hgpk_spewing_hack(psmouse, left, right, x, y); | 451 | hgpk_spewing_hack(psmouse, left, right, x, y); |
451 | 452 | ||
452 | if (tpdebug) | 453 | if (tpdebug) |
453 | hgpk_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", left, right, x, y); | 454 | psmouse_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", |
455 | left, right, x, y); | ||
454 | 456 | ||
455 | input_report_key(dev, BTN_LEFT, left); | 457 | input_report_key(dev, BTN_LEFT, left); |
456 | input_report_key(dev, BTN_RIGHT, right); | 458 | input_report_key(dev, BTN_RIGHT, right); |
@@ -482,9 +484,8 @@ static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse) | |||
482 | * ugh, got a packet inside our recalibration | 484 | * ugh, got a packet inside our recalibration |
483 | * window, schedule another recalibration. | 485 | * window, schedule another recalibration. |
484 | */ | 486 | */ |
485 | hgpk_dbg(psmouse, | 487 | psmouse_dbg(psmouse, |
486 | "packet inside calibration window, " | 488 | "packet inside calibration window, queueing another recalibration\n"); |
487 | "queueing another recalibration\n"); | ||
488 | psmouse_queue_work(psmouse, &priv->recalib_wq, | 489 | psmouse_queue_work(psmouse, &priv->recalib_wq, |
489 | msecs_to_jiffies(post_interrupt_delay)); | 490 | msecs_to_jiffies(post_interrupt_delay)); |
490 | } | 491 | } |
@@ -628,7 +629,7 @@ static int hgpk_reset_device(struct psmouse *psmouse, bool recalibrate) | |||
628 | 629 | ||
629 | err = hgpk_select_mode(psmouse); | 630 | err = hgpk_select_mode(psmouse); |
630 | if (err) { | 631 | if (err) { |
631 | hgpk_err(psmouse, "failed to select mode\n"); | 632 | psmouse_err(psmouse, "failed to select mode\n"); |
632 | return err; | 633 | return err; |
633 | } | 634 | } |
634 | 635 | ||
@@ -648,11 +649,11 @@ static int hgpk_force_recalibrate(struct psmouse *psmouse) | |||
648 | return 0; | 649 | return 0; |
649 | 650 | ||
650 | if (!autorecal) { | 651 | if (!autorecal) { |
651 | hgpk_dbg(psmouse, "recalibrations disabled, ignoring\n"); | 652 | psmouse_dbg(psmouse, "recalibration disabled, ignoring\n"); |
652 | return 0; | 653 | return 0; |
653 | } | 654 | } |
654 | 655 | ||
655 | hgpk_dbg(psmouse, "recalibrating touchpad..\n"); | 656 | psmouse_dbg(psmouse, "recalibrating touchpad..\n"); |
656 | 657 | ||
657 | /* we don't want to race with the irq handler, nor with resyncs */ | 658 | /* we don't want to race with the irq handler, nor with resyncs */ |
658 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); | 659 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); |
@@ -675,7 +676,7 @@ static int hgpk_force_recalibrate(struct psmouse *psmouse) | |||
675 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); | 676 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); |
676 | 677 | ||
677 | if (tpdebug) | 678 | if (tpdebug) |
678 | hgpk_dbg(psmouse, "touchpad reactivated\n"); | 679 | psmouse_dbg(psmouse, "touchpad reactivated\n"); |
679 | 680 | ||
680 | /* | 681 | /* |
681 | * If we get packets right away after recalibrating, it's likely | 682 | * If we get packets right away after recalibrating, it's likely |
@@ -727,16 +728,16 @@ static int hgpk_toggle_powersave(struct psmouse *psmouse, int enable) | |||
727 | 728 | ||
728 | err = hgpk_reset_device(psmouse, false); | 729 | err = hgpk_reset_device(psmouse, false); |
729 | if (err) { | 730 | if (err) { |
730 | hgpk_err(psmouse, "Failed to reset device!\n"); | 731 | psmouse_err(psmouse, "Failed to reset device!\n"); |
731 | return err; | 732 | return err; |
732 | } | 733 | } |
733 | 734 | ||
734 | /* should be all set, enable the touchpad */ | 735 | /* should be all set, enable the touchpad */ |
735 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE); | 736 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE); |
736 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); | 737 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); |
737 | hgpk_dbg(psmouse, "Touchpad powered up.\n"); | 738 | psmouse_dbg(psmouse, "Touchpad powered up.\n"); |
738 | } else { | 739 | } else { |
739 | hgpk_dbg(psmouse, "Powering off touchpad.\n"); | 740 | psmouse_dbg(psmouse, "Powering off touchpad.\n"); |
740 | 741 | ||
741 | if (ps2_command(ps2dev, NULL, 0xec) || | 742 | if (ps2_command(ps2dev, NULL, 0xec) || |
742 | ps2_command(ps2dev, NULL, 0xec) || | 743 | ps2_command(ps2dev, NULL, 0xec) || |
@@ -923,7 +924,7 @@ static void hgpk_recalib_work(struct work_struct *work) | |||
923 | struct psmouse *psmouse = priv->psmouse; | 924 | struct psmouse *psmouse = priv->psmouse; |
924 | 925 | ||
925 | if (hgpk_force_recalibrate(psmouse)) | 926 | if (hgpk_force_recalibrate(psmouse)) |
926 | hgpk_err(psmouse, "recalibration failed!\n"); | 927 | psmouse_err(psmouse, "recalibration failed!\n"); |
927 | } | 928 | } |
928 | 929 | ||
929 | static int hgpk_register(struct psmouse *psmouse) | 930 | static int hgpk_register(struct psmouse *psmouse) |
@@ -947,14 +948,15 @@ static int hgpk_register(struct psmouse *psmouse) | |||
947 | err = device_create_file(&psmouse->ps2dev.serio->dev, | 948 | err = device_create_file(&psmouse->ps2dev.serio->dev, |
948 | &psmouse_attr_powered.dattr); | 949 | &psmouse_attr_powered.dattr); |
949 | if (err) { | 950 | if (err) { |
950 | hgpk_err(psmouse, "Failed creating 'powered' sysfs node\n"); | 951 | psmouse_err(psmouse, "Failed creating 'powered' sysfs node\n"); |
951 | return err; | 952 | return err; |
952 | } | 953 | } |
953 | 954 | ||
954 | err = device_create_file(&psmouse->ps2dev.serio->dev, | 955 | err = device_create_file(&psmouse->ps2dev.serio->dev, |
955 | &psmouse_attr_hgpk_mode.dattr); | 956 | &psmouse_attr_hgpk_mode.dattr); |
956 | if (err) { | 957 | if (err) { |
957 | hgpk_err(psmouse, "Failed creating 'hgpk_mode' sysfs node\n"); | 958 | psmouse_err(psmouse, |
959 | "Failed creating 'hgpk_mode' sysfs node\n"); | ||
958 | goto err_remove_powered; | 960 | goto err_remove_powered; |
959 | } | 961 | } |
960 | 962 | ||
@@ -963,8 +965,8 @@ static int hgpk_register(struct psmouse *psmouse) | |||
963 | err = device_create_file(&psmouse->ps2dev.serio->dev, | 965 | err = device_create_file(&psmouse->ps2dev.serio->dev, |
964 | &psmouse_attr_recalibrate.dattr); | 966 | &psmouse_attr_recalibrate.dattr); |
965 | if (err) { | 967 | if (err) { |
966 | hgpk_err(psmouse, | 968 | psmouse_err(psmouse, |
967 | "Failed creating 'recalibrate' sysfs node\n"); | 969 | "Failed creating 'recalibrate' sysfs node\n"); |
968 | goto err_remove_mode; | 970 | goto err_remove_mode; |
969 | } | 971 | } |
970 | } | 972 | } |
@@ -1027,13 +1029,13 @@ static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse) | |||
1027 | return -EIO; | 1029 | return -EIO; |
1028 | } | 1030 | } |
1029 | 1031 | ||
1030 | hgpk_dbg(psmouse, "ID: %02x %02x %02x\n", param[0], param[1], param[2]); | 1032 | psmouse_dbg(psmouse, "ID: %02x %02x %02x\n", param[0], param[1], param[2]); |
1031 | 1033 | ||
1032 | /* HGPK signature: 0x67, 0x00, 0x<model> */ | 1034 | /* HGPK signature: 0x67, 0x00, 0x<model> */ |
1033 | if (param[0] != 0x67 || param[1] != 0x00) | 1035 | if (param[0] != 0x67 || param[1] != 0x00) |
1034 | return -ENODEV; | 1036 | return -ENODEV; |
1035 | 1037 | ||
1036 | hgpk_info(psmouse, "OLPC touchpad revision 0x%x\n", param[2]); | 1038 | psmouse_info(psmouse, "OLPC touchpad revision 0x%x\n", param[2]); |
1037 | 1039 | ||
1038 | return param[2]; | 1040 | return param[2]; |
1039 | } | 1041 | } |
diff --git a/drivers/input/mouse/hgpk.h b/drivers/input/mouse/hgpk.h index 311c0e87fcbf..dd686771cfe0 100644 --- a/drivers/input/mouse/hgpk.h +++ b/drivers/input/mouse/hgpk.h | |||
@@ -46,17 +46,6 @@ struct hgpk_data { | |||
46 | int xsaw_secondary, ysaw_secondary; /* jumpiness detection */ | 46 | int xsaw_secondary, ysaw_secondary; /* jumpiness detection */ |
47 | }; | 47 | }; |
48 | 48 | ||
49 | #define hgpk_dbg(psmouse, format, arg...) \ | ||
50 | dev_dbg(&(psmouse)->ps2dev.serio->dev, format, ## arg) | ||
51 | #define hgpk_err(psmouse, format, arg...) \ | ||
52 | dev_err(&(psmouse)->ps2dev.serio->dev, format, ## arg) | ||
53 | #define hgpk_info(psmouse, format, arg...) \ | ||
54 | dev_info(&(psmouse)->ps2dev.serio->dev, format, ## arg) | ||
55 | #define hgpk_warn(psmouse, format, arg...) \ | ||
56 | dev_warn(&(psmouse)->ps2dev.serio->dev, format, ## arg) | ||
57 | #define hgpk_notice(psmouse, format, arg...) \ | ||
58 | dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg) | ||
59 | |||
60 | #ifdef CONFIG_MOUSE_PS2_OLPC | 49 | #ifdef CONFIG_MOUSE_PS2_OLPC |
61 | void hgpk_module_init(void); | 50 | void hgpk_module_init(void); |
62 | int hgpk_detect(struct psmouse *psmouse, bool set_properties); | 51 | int hgpk_detect(struct psmouse *psmouse, bool set_properties); |
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 83bcaba96b89..2c4db636de6c 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c | |||
@@ -169,8 +169,8 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) | |||
169 | 169 | ||
170 | if (relative_packet) { | 170 | if (relative_packet) { |
171 | if (!dev2) | 171 | if (!dev2) |
172 | printk(KERN_WARNING "lifebook.c: got relative packet " | 172 | psmouse_warn(psmouse, |
173 | "but no relative device set up\n"); | 173 | "got relative packet but no relative device set up\n"); |
174 | } else { | 174 | } else { |
175 | if (lifebook_use_6byte_proto) { | 175 | if (lifebook_use_6byte_proto) { |
176 | input_report_abs(dev1, ABS_X, | 176 | input_report_abs(dev1, ABS_X, |
@@ -212,7 +212,7 @@ static int lifebook_absolute_mode(struct psmouse *psmouse) | |||
212 | 212 | ||
213 | /* | 213 | /* |
214 | * Enable absolute output -- ps2_command fails always but if | 214 | * Enable absolute output -- ps2_command fails always but if |
215 | * you leave this call out the touchsreen will never send | 215 | * you leave this call out the touchscreen will never send |
216 | * absolute coordinates | 216 | * absolute coordinates |
217 | */ | 217 | */ |
218 | param = lifebook_use_6byte_proto ? 0x08 : 0x07; | 218 | param = lifebook_use_6byte_proto ? 0x08 : 0x07; |
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index c9983aee9082..faac2c3bef74 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c | |||
@@ -82,11 +82,11 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse) | |||
82 | packet[0] = packet[2] | 0x08; | 82 | packet[0] = packet[2] | 0x08; |
83 | break; | 83 | break; |
84 | 84 | ||
85 | #ifdef DEBUG | ||
86 | default: | 85 | default: |
87 | printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n", | 86 | psmouse_dbg(psmouse, |
88 | (packet[1] >> 4) | (packet[0] & 0x30)); | 87 | "Received PS2++ packet #%x, but don't know how to handle.\n", |
89 | #endif | 88 | (packet[1] >> 4) | (packet[0] & 0x30)); |
89 | break; | ||
90 | } | 90 | } |
91 | } else { | 91 | } else { |
92 | /* Standard PS/2 motion data */ | 92 | /* Standard PS/2 motion data */ |
@@ -382,7 +382,7 @@ int ps2pp_init(struct psmouse *psmouse, bool set_properties) | |||
382 | } | 382 | } |
383 | 383 | ||
384 | } else { | 384 | } else { |
385 | printk(KERN_WARNING "logips2pp: Detected unknown logitech mouse model %d\n", model); | 385 | psmouse_warn(psmouse, "Detected unknown Logitech mouse model %d\n", model); |
386 | } | 386 | } |
387 | 387 | ||
388 | if (set_properties) { | 388 | if (set_properties) { |
@@ -400,9 +400,9 @@ int ps2pp_init(struct psmouse *psmouse, bool set_properties) | |||
400 | error = device_create_file(&psmouse->ps2dev.serio->dev, | 400 | error = device_create_file(&psmouse->ps2dev.serio->dev, |
401 | &psmouse_attr_smartscroll.dattr); | 401 | &psmouse_attr_smartscroll.dattr); |
402 | if (error) { | 402 | if (error) { |
403 | printk(KERN_ERR | 403 | psmouse_err(psmouse, |
404 | "logips2pp.c: failed to create smartscroll " | 404 | "failed to create smartscroll sysfs attribute, error: %d\n", |
405 | "sysfs attribute, error: %d\n", error); | 405 | error); |
406 | return -1; | 406 | return -1; |
407 | } | 407 | } |
408 | } | 408 | } |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 3f74baee102b..9f352fbd7b4f 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -11,6 +11,9 @@ | |||
11 | * the Free Software Foundation. | 11 | * the Free Software Foundation. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
15 | #define psmouse_fmt(fmt) fmt | ||
16 | |||
14 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
15 | #include <linux/module.h> | 18 | #include <linux/module.h> |
16 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
@@ -251,11 +254,14 @@ static int psmouse_handle_byte(struct psmouse *psmouse) | |||
251 | switch (rc) { | 254 | switch (rc) { |
252 | case PSMOUSE_BAD_DATA: | 255 | case PSMOUSE_BAD_DATA: |
253 | if (psmouse->state == PSMOUSE_ACTIVATED) { | 256 | if (psmouse->state == PSMOUSE_ACTIVATED) { |
254 | printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n", | 257 | psmouse_warn(psmouse, |
255 | psmouse->name, psmouse->phys, psmouse->pktcnt); | 258 | "%s at %s lost sync at byte %d\n", |
259 | psmouse->name, psmouse->phys, | ||
260 | psmouse->pktcnt); | ||
256 | if (++psmouse->out_of_sync_cnt == psmouse->resetafter) { | 261 | if (++psmouse->out_of_sync_cnt == psmouse->resetafter) { |
257 | __psmouse_set_state(psmouse, PSMOUSE_IGNORE); | 262 | __psmouse_set_state(psmouse, PSMOUSE_IGNORE); |
258 | printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); | 263 | psmouse_notice(psmouse, |
264 | "issuing reconnect request\n"); | ||
259 | serio_reconnect(psmouse->ps2dev.serio); | 265 | serio_reconnect(psmouse->ps2dev.serio); |
260 | return -1; | 266 | return -1; |
261 | } | 267 | } |
@@ -267,8 +273,9 @@ static int psmouse_handle_byte(struct psmouse *psmouse) | |||
267 | psmouse->pktcnt = 0; | 273 | psmouse->pktcnt = 0; |
268 | if (psmouse->out_of_sync_cnt) { | 274 | if (psmouse->out_of_sync_cnt) { |
269 | psmouse->out_of_sync_cnt = 0; | 275 | psmouse->out_of_sync_cnt = 0; |
270 | printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n", | 276 | psmouse_notice(psmouse, |
271 | psmouse->name, psmouse->phys); | 277 | "%s at %s - driver resynced.\n", |
278 | psmouse->name, psmouse->phys); | ||
272 | } | 279 | } |
273 | break; | 280 | break; |
274 | 281 | ||
@@ -295,9 +302,10 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, | |||
295 | ((flags & SERIO_PARITY) && !psmouse->ignore_parity))) { | 302 | ((flags & SERIO_PARITY) && !psmouse->ignore_parity))) { |
296 | 303 | ||
297 | if (psmouse->state == PSMOUSE_ACTIVATED) | 304 | if (psmouse->state == PSMOUSE_ACTIVATED) |
298 | printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n", | 305 | psmouse_warn(psmouse, |
299 | flags & SERIO_TIMEOUT ? " timeout" : "", | 306 | "bad data from KBC -%s%s\n", |
300 | flags & SERIO_PARITY ? " bad parity" : ""); | 307 | flags & SERIO_TIMEOUT ? " timeout" : "", |
308 | flags & SERIO_PARITY ? " bad parity" : ""); | ||
301 | ps2_cmd_aborted(&psmouse->ps2dev); | 309 | ps2_cmd_aborted(&psmouse->ps2dev); |
302 | goto out; | 310 | goto out; |
303 | } | 311 | } |
@@ -315,8 +323,8 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, | |||
315 | 323 | ||
316 | if (psmouse->state == PSMOUSE_ACTIVATED && | 324 | if (psmouse->state == PSMOUSE_ACTIVATED && |
317 | psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) { | 325 | psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) { |
318 | printk(KERN_INFO "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n", | 326 | psmouse_info(psmouse, "%s at %s lost synchronization, throwing %d bytes away.\n", |
319 | psmouse->name, psmouse->phys, psmouse->pktcnt); | 327 | psmouse->name, psmouse->phys, psmouse->pktcnt); |
320 | psmouse->badbyte = psmouse->packet[0]; | 328 | psmouse->badbyte = psmouse->packet[0]; |
321 | __psmouse_set_state(psmouse, PSMOUSE_RESYNCING); | 329 | __psmouse_set_state(psmouse, PSMOUSE_RESYNCING); |
322 | psmouse_queue_work(psmouse, &psmouse->resync_work, 0); | 330 | psmouse_queue_work(psmouse, &psmouse->resync_work, 0); |
@@ -943,7 +951,8 @@ static int psmouse_probe(struct psmouse *psmouse) | |||
943 | */ | 951 | */ |
944 | 952 | ||
945 | if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS)) | 953 | if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS)) |
946 | printk(KERN_WARNING "psmouse.c: Failed to reset mouse on %s\n", ps2dev->serio->phys); | 954 | psmouse_warn(psmouse, "Failed to reset mouse on %s\n", |
955 | ps2dev->serio->phys); | ||
947 | 956 | ||
948 | return 0; | 957 | return 0; |
949 | } | 958 | } |
@@ -1005,8 +1014,8 @@ static void psmouse_initialize(struct psmouse *psmouse) | |||
1005 | static void psmouse_activate(struct psmouse *psmouse) | 1014 | static void psmouse_activate(struct psmouse *psmouse) |
1006 | { | 1015 | { |
1007 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) | 1016 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) |
1008 | printk(KERN_WARNING "psmouse.c: Failed to enable mouse on %s\n", | 1017 | psmouse_warn(psmouse, "Failed to enable mouse on %s\n", |
1009 | psmouse->ps2dev.serio->phys); | 1018 | psmouse->ps2dev.serio->phys); |
1010 | 1019 | ||
1011 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); | 1020 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); |
1012 | } | 1021 | } |
@@ -1020,14 +1029,14 @@ static void psmouse_activate(struct psmouse *psmouse) | |||
1020 | static void psmouse_deactivate(struct psmouse *psmouse) | 1029 | static void psmouse_deactivate(struct psmouse *psmouse) |
1021 | { | 1030 | { |
1022 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) | 1031 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) |
1023 | printk(KERN_WARNING "psmouse.c: Failed to deactivate mouse on %s\n", | 1032 | psmouse_warn(psmouse, "Failed to deactivate mouse on %s\n", |
1024 | psmouse->ps2dev.serio->phys); | 1033 | psmouse->ps2dev.serio->phys); |
1025 | 1034 | ||
1026 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | 1035 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); |
1027 | } | 1036 | } |
1028 | 1037 | ||
1029 | /* | 1038 | /* |
1030 | * psmouse_poll() - default poll hanlder. Everyone except for ALPS uses it. | 1039 | * psmouse_poll() - default poll handler. Everyone except for ALPS uses it. |
1031 | */ | 1040 | */ |
1032 | 1041 | ||
1033 | static int psmouse_poll(struct psmouse *psmouse) | 1042 | static int psmouse_poll(struct psmouse *psmouse) |
@@ -1115,14 +1124,15 @@ static void psmouse_resync(struct work_struct *work) | |||
1115 | } | 1124 | } |
1116 | 1125 | ||
1117 | if (!enabled) { | 1126 | if (!enabled) { |
1118 | printk(KERN_WARNING "psmouse.c: failed to re-enable mouse on %s\n", | 1127 | psmouse_warn(psmouse, "failed to re-enable mouse on %s\n", |
1119 | psmouse->ps2dev.serio->phys); | 1128 | psmouse->ps2dev.serio->phys); |
1120 | failed = true; | 1129 | failed = true; |
1121 | } | 1130 | } |
1122 | 1131 | ||
1123 | if (failed) { | 1132 | if (failed) { |
1124 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); | 1133 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); |
1125 | printk(KERN_INFO "psmouse.c: resync failed, issuing reconnect request\n"); | 1134 | psmouse_info(psmouse, |
1135 | "resync failed, issuing reconnect request\n"); | ||
1126 | serio_reconnect(serio); | 1136 | serio_reconnect(serio); |
1127 | } else | 1137 | } else |
1128 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); | 1138 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); |
@@ -1155,8 +1165,8 @@ static void psmouse_cleanup(struct serio *serio) | |||
1155 | * Disable stream mode so cleanup routine can proceed undisturbed. | 1165 | * Disable stream mode so cleanup routine can proceed undisturbed. |
1156 | */ | 1166 | */ |
1157 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) | 1167 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) |
1158 | printk(KERN_WARNING "psmouse.c: Failed to disable mouse on %s\n", | 1168 | psmouse_warn(psmouse, "Failed to disable mouse on %s\n", |
1159 | psmouse->ps2dev.serio->phys); | 1169 | psmouse->ps2dev.serio->phys); |
1160 | 1170 | ||
1161 | if (psmouse->cleanup) | 1171 | if (psmouse->cleanup) |
1162 | psmouse->cleanup(psmouse); | 1172 | psmouse->cleanup(psmouse); |
@@ -1400,7 +1410,8 @@ static int psmouse_reconnect(struct serio *serio) | |||
1400 | int rc = -1; | 1410 | int rc = -1; |
1401 | 1411 | ||
1402 | if (!drv || !psmouse) { | 1412 | if (!drv || !psmouse) { |
1403 | printk(KERN_DEBUG "psmouse: reconnect request, but serio is disconnected, ignoring...\n"); | 1413 | psmouse_dbg(psmouse, |
1414 | "reconnect request, but serio is disconnected, ignoring...\n"); | ||
1404 | return -1; | 1415 | return -1; |
1405 | } | 1416 | } |
1406 | 1417 | ||
@@ -1427,8 +1438,9 @@ static int psmouse_reconnect(struct serio *serio) | |||
1427 | goto out; | 1438 | goto out; |
1428 | } | 1439 | } |
1429 | 1440 | ||
1430 | /* ok, the device type (and capabilities) match the old one, | 1441 | /* |
1431 | * we can continue using it, complete intialization | 1442 | * OK, the device type (and capabilities) match the old one, |
1443 | * we can continue using it, complete initialization | ||
1432 | */ | 1444 | */ |
1433 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | 1445 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); |
1434 | 1446 | ||
@@ -1586,9 +1598,8 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co | |||
1586 | 1598 | ||
1587 | while (!list_empty(&serio->children)) { | 1599 | while (!list_empty(&serio->children)) { |
1588 | if (++retry > 3) { | 1600 | if (++retry > 3) { |
1589 | printk(KERN_WARNING | 1601 | psmouse_warn(psmouse, |
1590 | "psmouse: failed to destroy children ports, " | 1602 | "failed to destroy children ports, protocol change aborted.\n"); |
1591 | "protocol change aborted.\n"); | ||
1592 | input_free_device(new_dev); | 1603 | input_free_device(new_dev); |
1593 | return -EIO; | 1604 | return -EIO; |
1594 | } | 1605 | } |
@@ -1715,7 +1726,7 @@ static int __init psmouse_init(void) | |||
1715 | 1726 | ||
1716 | kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); | 1727 | kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); |
1717 | if (!kpsmoused_wq) { | 1728 | if (!kpsmoused_wq) { |
1718 | printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n"); | 1729 | pr_err("failed to create kpsmoused workqueue\n"); |
1719 | return -ENOMEM; | 1730 | return -ENOMEM; |
1720 | } | 1731 | } |
1721 | 1732 | ||
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index 593e910bfc7a..9b84b0c4e371 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h | |||
@@ -150,4 +150,29 @@ static struct psmouse_attribute psmouse_attr_##_name = { \ | |||
150 | static ssize_t _set(struct psmouse *, void *, const char *, size_t); \ | 150 | static ssize_t _set(struct psmouse *, void *, const char *, size_t); \ |
151 | __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, NULL, _set, true) | 151 | __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, NULL, _set, true) |
152 | 152 | ||
153 | #ifndef psmouse_fmt | ||
154 | #define psmouse_fmt(fmt) KBUILD_BASENAME ": " fmt | ||
155 | #endif | ||
156 | |||
157 | #define psmouse_dbg(psmouse, format, ...) \ | ||
158 | dev_dbg(&(psmouse)->ps2dev.serio->dev, \ | ||
159 | psmouse_fmt(format), ##__VA_ARGS__) | ||
160 | #define psmouse_info(psmouse, format, ...) \ | ||
161 | dev_info(&(psmouse)->ps2dev.serio->dev, \ | ||
162 | psmouse_fmt(format), ##__VA_ARGS__) | ||
163 | #define psmouse_warn(psmouse, format, ...) \ | ||
164 | dev_warn(&(psmouse)->ps2dev.serio->dev, \ | ||
165 | psmouse_fmt(format), ##__VA_ARGS__) | ||
166 | #define psmouse_err(psmouse, format, ...) \ | ||
167 | dev_err(&(psmouse)->ps2dev.serio->dev, \ | ||
168 | psmouse_fmt(format), ##__VA_ARGS__) | ||
169 | #define psmouse_notice(psmouse, format, ...) \ | ||
170 | dev_notice(&(psmouse)->ps2dev.serio->dev, \ | ||
171 | psmouse_fmt(format), ##__VA_ARGS__) | ||
172 | #define psmouse_printk(level, psmouse, format, ...) \ | ||
173 | dev_printk(level, \ | ||
174 | &(psmouse)->ps2dev.serio->dev, \ | ||
175 | psmouse_fmt(format), ##__VA_ARGS__) | ||
176 | |||
177 | |||
153 | #endif /* _PSMOUSE_H */ | 178 | #endif /* _PSMOUSE_H */ |
diff --git a/drivers/input/mouse/pxa930_trkball.c b/drivers/input/mouse/pxa930_trkball.c index 6c5d84fcdea1..ee3b0ca9d592 100644 --- a/drivers/input/mouse/pxa930_trkball.c +++ b/drivers/input/mouse/pxa930_trkball.c | |||
@@ -183,7 +183,7 @@ static int __devinit pxa930_trkball_probe(struct platform_device *pdev) | |||
183 | /* held the module in reset, will be enabled in open() */ | 183 | /* held the module in reset, will be enabled in open() */ |
184 | pxa930_trkball_disable(trkball); | 184 | pxa930_trkball_disable(trkball); |
185 | 185 | ||
186 | error = request_irq(irq, pxa930_trkball_interrupt, IRQF_DISABLED, | 186 | error = request_irq(irq, pxa930_trkball_interrupt, 0, |
187 | pdev->name, trkball); | 187 | pdev->name, trkball); |
188 | if (error) { | 188 | if (error) { |
189 | dev_err(&pdev->dev, "failed to request irq: %d\n", error); | 189 | dev_err(&pdev->dev, "failed to request irq: %d\n", error); |
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index 2fc887a51066..c5b12d2e955a 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c | |||
@@ -607,11 +607,12 @@ static void fsp_packet_debug(unsigned char packet[]) | |||
607 | 607 | ||
608 | ps2_packet_cnt++; | 608 | ps2_packet_cnt++; |
609 | jiffies_msec = jiffies_to_msecs(jiffies); | 609 | jiffies_msec = jiffies_to_msecs(jiffies); |
610 | printk(KERN_DEBUG "%08dms PS/2 packets: %02x, %02x, %02x, %02x\n", | 610 | psmouse_dbg(psmouse, |
611 | jiffies_msec, packet[0], packet[1], packet[2], packet[3]); | 611 | "%08dms PS/2 packets: %02x, %02x, %02x, %02x\n", |
612 | jiffies_msec, packet[0], packet[1], packet[2], packet[3]); | ||
612 | 613 | ||
613 | if (jiffies_msec - ps2_last_second > 1000) { | 614 | if (jiffies_msec - ps2_last_second > 1000) { |
614 | printk(KERN_DEBUG "PS/2 packets/sec = %d\n", ps2_packet_cnt); | 615 | psmouse_dbg(psmouse, "PS/2 packets/sec = %d\n", ps2_packet_cnt); |
615 | ps2_packet_cnt = 0; | 616 | ps2_packet_cnt = 0; |
616 | ps2_last_second = jiffies_msec; | 617 | ps2_last_second = jiffies_msec; |
617 | } | 618 | } |
@@ -820,9 +821,9 @@ int fsp_init(struct psmouse *psmouse) | |||
820 | return -ENODEV; | 821 | return -ENODEV; |
821 | } | 822 | } |
822 | 823 | ||
823 | printk(KERN_INFO | 824 | psmouse_info(psmouse, |
824 | "Finger Sensing Pad, hw: %d.%d.%d, sw: %s, buttons: %d\n", | 825 | "Finger Sensing Pad, hw: %d.%d.%d, sw: %s, buttons: %d\n", |
825 | ver >> 4, ver & 0x0F, rev, fsp_drv_ver, buttons & 7); | 826 | ver >> 4, ver & 0x0F, rev, fsp_drv_ver, buttons & 7); |
826 | 827 | ||
827 | psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL); | 828 | psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL); |
828 | if (!priv) | 829 | if (!priv) |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 5538fc657af1..c080b828e5dc 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -44,6 +44,16 @@ | |||
44 | #define YMIN_NOMINAL 1408 | 44 | #define YMIN_NOMINAL 1408 |
45 | #define YMAX_NOMINAL 4448 | 45 | #define YMAX_NOMINAL 4448 |
46 | 46 | ||
47 | /* | ||
48 | * Synaptics touchpads report the y coordinate from bottom to top, which is | ||
49 | * opposite from what userspace expects. | ||
50 | * This function is used to invert y before reporting. | ||
51 | */ | ||
52 | static int synaptics_invert_y(int y) | ||
53 | { | ||
54 | return YMAX_NOMINAL + YMIN_NOMINAL - y; | ||
55 | } | ||
56 | |||
47 | 57 | ||
48 | /***************************************************************************** | 58 | /***************************************************************************** |
49 | * Stuff we need even when we do not want native Synaptics support | 59 | * Stuff we need even when we do not want native Synaptics support |
@@ -157,8 +167,8 @@ static int synaptics_capability(struct psmouse *psmouse) | |||
157 | 167 | ||
158 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) { | 168 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) { |
159 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) { | 169 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) { |
160 | printk(KERN_ERR "Synaptics claims to have extended capabilities," | 170 | psmouse_warn(psmouse, |
161 | " but I'm not able to read them.\n"); | 171 | "device claims to have extended capabilities, but I'm not able to read them.\n"); |
162 | } else { | 172 | } else { |
163 | priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2]; | 173 | priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2]; |
164 | 174 | ||
@@ -173,8 +183,8 @@ static int synaptics_capability(struct psmouse *psmouse) | |||
173 | 183 | ||
174 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 4) { | 184 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 4) { |
175 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB_0C, cap)) { | 185 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB_0C, cap)) { |
176 | printk(KERN_ERR "Synaptics claims to have extended capability 0x0c," | 186 | psmouse_warn(psmouse, |
177 | " but I'm not able to read it.\n"); | 187 | "device claims to have extended capability 0x0c, but I'm not able to read it.\n"); |
178 | } else { | 188 | } else { |
179 | priv->ext_cap_0c = (cap[0] << 16) | (cap[1] << 8) | cap[2]; | 189 | priv->ext_cap_0c = (cap[0] << 16) | (cap[1] << 8) | cap[2]; |
180 | } | 190 | } |
@@ -222,8 +232,8 @@ static int synaptics_resolution(struct psmouse *psmouse) | |||
222 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && | 232 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 5 && |
223 | SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { | 233 | SYN_CAP_MAX_DIMENSIONS(priv->ext_cap_0c)) { |
224 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MAX_COORDS, resp)) { | 234 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MAX_COORDS, resp)) { |
225 | printk(KERN_ERR "Synaptics claims to have max coordinates" | 235 | psmouse_warn(psmouse, |
226 | " query, but I'm not able to read it.\n"); | 236 | "device claims to have max coordinates query, but I'm not able to read it.\n"); |
227 | } else { | 237 | } else { |
228 | priv->x_max = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); | 238 | priv->x_max = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); |
229 | priv->y_max = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); | 239 | priv->y_max = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); |
@@ -233,8 +243,8 @@ static int synaptics_resolution(struct psmouse *psmouse) | |||
233 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 7 && | 243 | if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 7 && |
234 | SYN_CAP_MIN_DIMENSIONS(priv->ext_cap_0c)) { | 244 | SYN_CAP_MIN_DIMENSIONS(priv->ext_cap_0c)) { |
235 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MIN_COORDS, resp)) { | 245 | if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_MIN_COORDS, resp)) { |
236 | printk(KERN_ERR "Synaptics claims to have min coordinates" | 246 | psmouse_warn(psmouse, |
237 | " query, but I'm not able to read it.\n"); | 247 | "device claims to have min coordinates query, but I'm not able to read it.\n"); |
238 | } else { | 248 | } else { |
239 | priv->x_min = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); | 249 | priv->x_min = (resp[0] << 5) | ((resp[1] & 0x0f) << 1); |
240 | priv->y_min = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); | 250 | priv->y_min = (resp[2] << 5) | ((resp[1] & 0xf0) >> 3); |
@@ -294,7 +304,8 @@ static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse) | |||
294 | static unsigned char param = 0xc8; | 304 | static unsigned char param = 0xc8; |
295 | struct synaptics_data *priv = psmouse->private; | 305 | struct synaptics_data *priv = psmouse->private; |
296 | 306 | ||
297 | if (!SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) | 307 | if (!(SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) || |
308 | SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c))) | ||
298 | return 0; | 309 | return 0; |
299 | 310 | ||
300 | if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL)) | 311 | if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL)) |
@@ -377,7 +388,8 @@ static void synaptics_pt_activate(struct psmouse *psmouse) | |||
377 | priv->mode &= ~SYN_BIT_FOUR_BYTE_CLIENT; | 388 | priv->mode &= ~SYN_BIT_FOUR_BYTE_CLIENT; |
378 | 389 | ||
379 | if (synaptics_mode_cmd(psmouse, priv->mode)) | 390 | if (synaptics_mode_cmd(psmouse, priv->mode)) |
380 | printk(KERN_INFO "synaptics: failed to switch guest protocol\n"); | 391 | psmouse_warn(psmouse, |
392 | "failed to switch guest protocol\n"); | ||
381 | } | 393 | } |
382 | } | 394 | } |
383 | 395 | ||
@@ -387,7 +399,8 @@ static void synaptics_pt_create(struct psmouse *psmouse) | |||
387 | 399 | ||
388 | serio = kzalloc(sizeof(struct serio), GFP_KERNEL); | 400 | serio = kzalloc(sizeof(struct serio), GFP_KERNEL); |
389 | if (!serio) { | 401 | if (!serio) { |
390 | printk(KERN_ERR "synaptics: not enough memory to allocate pass-through port\n"); | 402 | psmouse_err(psmouse, |
403 | "not enough memory for pass-through port\n"); | ||
391 | return; | 404 | return; |
392 | } | 405 | } |
393 | 406 | ||
@@ -401,7 +414,8 @@ static void synaptics_pt_create(struct psmouse *psmouse) | |||
401 | 414 | ||
402 | psmouse->pt_activate = synaptics_pt_activate; | 415 | psmouse->pt_activate = synaptics_pt_activate; |
403 | 416 | ||
404 | printk(KERN_INFO "serio: %s port at %s\n", serio->name, psmouse->phys); | 417 | psmouse_info(psmouse, "serio: %s port at %s\n", |
418 | serio->name, psmouse->phys); | ||
405 | serio_register_port(serio); | 419 | serio_register_port(serio); |
406 | } | 420 | } |
407 | 421 | ||
@@ -409,6 +423,44 @@ static void synaptics_pt_create(struct psmouse *psmouse) | |||
409 | * Functions to interpret the absolute mode packets | 423 | * Functions to interpret the absolute mode packets |
410 | ****************************************************************************/ | 424 | ****************************************************************************/ |
411 | 425 | ||
426 | static void synaptics_mt_state_set(struct synaptics_mt_state *state, int count, | ||
427 | int sgm, int agm) | ||
428 | { | ||
429 | state->count = count; | ||
430 | state->sgm = sgm; | ||
431 | state->agm = agm; | ||
432 | } | ||
433 | |||
434 | static void synaptics_parse_agm(const unsigned char buf[], | ||
435 | struct synaptics_data *priv, | ||
436 | struct synaptics_hw_state *hw) | ||
437 | { | ||
438 | struct synaptics_hw_state *agm = &priv->agm; | ||
439 | int agm_packet_type; | ||
440 | |||
441 | agm_packet_type = (buf[5] & 0x30) >> 4; | ||
442 | switch (agm_packet_type) { | ||
443 | case 1: | ||
444 | /* Gesture packet: (x, y, z) half resolution */ | ||
445 | agm->w = hw->w; | ||
446 | agm->x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1; | ||
447 | agm->y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1; | ||
448 | agm->z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1; | ||
449 | break; | ||
450 | |||
451 | case 2: | ||
452 | /* AGM-CONTACT packet: (count, sgm, agm) */ | ||
453 | synaptics_mt_state_set(&agm->mt_state, buf[1], buf[2], buf[4]); | ||
454 | break; | ||
455 | |||
456 | default: | ||
457 | break; | ||
458 | } | ||
459 | |||
460 | /* Record that at least one AGM has been received since last SGM */ | ||
461 | priv->agm_pending = true; | ||
462 | } | ||
463 | |||
412 | static int synaptics_parse_hw_state(const unsigned char buf[], | 464 | static int synaptics_parse_hw_state(const unsigned char buf[], |
413 | struct synaptics_data *priv, | 465 | struct synaptics_data *priv, |
414 | struct synaptics_hw_state *hw) | 466 | struct synaptics_hw_state *hw) |
@@ -442,11 +494,10 @@ static int synaptics_parse_hw_state(const unsigned char buf[], | |||
442 | hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; | 494 | hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0; |
443 | } | 495 | } |
444 | 496 | ||
445 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) && hw->w == 2) { | 497 | if ((SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) || |
446 | /* Gesture packet: (x, y, z) at half resolution */ | 498 | SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) && |
447 | priv->mt.x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1; | 499 | hw->w == 2) { |
448 | priv->mt.y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1; | 500 | synaptics_parse_agm(buf, priv, hw); |
449 | priv->mt.z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1; | ||
450 | return 1; | 501 | return 1; |
451 | } | 502 | } |
452 | 503 | ||
@@ -502,8 +553,7 @@ static void synaptics_report_semi_mt_slot(struct input_dev *dev, int slot, | |||
502 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); | 553 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); |
503 | if (active) { | 554 | if (active) { |
504 | input_report_abs(dev, ABS_MT_POSITION_X, x); | 555 | input_report_abs(dev, ABS_MT_POSITION_X, x); |
505 | input_report_abs(dev, ABS_MT_POSITION_Y, | 556 | input_report_abs(dev, ABS_MT_POSITION_Y, synaptics_invert_y(y)); |
506 | YMAX_NOMINAL + YMIN_NOMINAL - y); | ||
507 | } | 557 | } |
508 | } | 558 | } |
509 | 559 | ||
@@ -526,6 +576,388 @@ static void synaptics_report_semi_mt_data(struct input_dev *dev, | |||
526 | } | 576 | } |
527 | } | 577 | } |
528 | 578 | ||
579 | static void synaptics_report_buttons(struct psmouse *psmouse, | ||
580 | const struct synaptics_hw_state *hw) | ||
581 | { | ||
582 | struct input_dev *dev = psmouse->dev; | ||
583 | struct synaptics_data *priv = psmouse->private; | ||
584 | int i; | ||
585 | |||
586 | input_report_key(dev, BTN_LEFT, hw->left); | ||
587 | input_report_key(dev, BTN_RIGHT, hw->right); | ||
588 | |||
589 | if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) | ||
590 | input_report_key(dev, BTN_MIDDLE, hw->middle); | ||
591 | |||
592 | if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) { | ||
593 | input_report_key(dev, BTN_FORWARD, hw->up); | ||
594 | input_report_key(dev, BTN_BACK, hw->down); | ||
595 | } | ||
596 | |||
597 | for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) | ||
598 | input_report_key(dev, BTN_0 + i, hw->ext_buttons & (1 << i)); | ||
599 | } | ||
600 | |||
601 | static void synaptics_report_slot(struct input_dev *dev, int slot, | ||
602 | const struct synaptics_hw_state *hw) | ||
603 | { | ||
604 | input_mt_slot(dev, slot); | ||
605 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, (hw != NULL)); | ||
606 | if (!hw) | ||
607 | return; | ||
608 | |||
609 | input_report_abs(dev, ABS_MT_POSITION_X, hw->x); | ||
610 | input_report_abs(dev, ABS_MT_POSITION_Y, synaptics_invert_y(hw->y)); | ||
611 | input_report_abs(dev, ABS_MT_PRESSURE, hw->z); | ||
612 | } | ||
613 | |||
614 | static void synaptics_report_mt_data(struct psmouse *psmouse, | ||
615 | struct synaptics_mt_state *mt_state, | ||
616 | const struct synaptics_hw_state *sgm) | ||
617 | { | ||
618 | struct input_dev *dev = psmouse->dev; | ||
619 | struct synaptics_data *priv = psmouse->private; | ||
620 | struct synaptics_hw_state *agm = &priv->agm; | ||
621 | struct synaptics_mt_state *old = &priv->mt_state; | ||
622 | |||
623 | switch (mt_state->count) { | ||
624 | case 0: | ||
625 | synaptics_report_slot(dev, 0, NULL); | ||
626 | synaptics_report_slot(dev, 1, NULL); | ||
627 | break; | ||
628 | case 1: | ||
629 | if (mt_state->sgm == -1) { | ||
630 | synaptics_report_slot(dev, 0, NULL); | ||
631 | synaptics_report_slot(dev, 1, NULL); | ||
632 | } else if (mt_state->sgm == 0) { | ||
633 | synaptics_report_slot(dev, 0, sgm); | ||
634 | synaptics_report_slot(dev, 1, NULL); | ||
635 | } else { | ||
636 | synaptics_report_slot(dev, 0, NULL); | ||
637 | synaptics_report_slot(dev, 1, sgm); | ||
638 | } | ||
639 | break; | ||
640 | default: | ||
641 | /* | ||
642 | * If the finger slot contained in SGM is valid, and either | ||
643 | * hasn't changed, or is new, then report SGM in MTB slot 0. | ||
644 | * Otherwise, empty MTB slot 0. | ||
645 | */ | ||
646 | if (mt_state->sgm != -1 && | ||
647 | (mt_state->sgm == old->sgm || old->sgm == -1)) | ||
648 | synaptics_report_slot(dev, 0, sgm); | ||
649 | else | ||
650 | synaptics_report_slot(dev, 0, NULL); | ||
651 | |||
652 | /* | ||
653 | * If the finger slot contained in AGM is valid, and either | ||
654 | * hasn't changed, or is new, then report AGM in MTB slot 1. | ||
655 | * Otherwise, empty MTB slot 1. | ||
656 | */ | ||
657 | if (mt_state->agm != -1 && | ||
658 | (mt_state->agm == old->agm || old->agm == -1)) | ||
659 | synaptics_report_slot(dev, 1, agm); | ||
660 | else | ||
661 | synaptics_report_slot(dev, 1, NULL); | ||
662 | break; | ||
663 | } | ||
664 | |||
665 | /* Don't use active slot count to generate BTN_TOOL events. */ | ||
666 | input_mt_report_pointer_emulation(dev, false); | ||
667 | |||
668 | /* Send the number of fingers reported by touchpad itself. */ | ||
669 | input_mt_report_finger_count(dev, mt_state->count); | ||
670 | |||
671 | synaptics_report_buttons(psmouse, sgm); | ||
672 | |||
673 | input_sync(dev); | ||
674 | } | ||
675 | |||
676 | /* Handle case where mt_state->count = 0 */ | ||
677 | static void synaptics_image_sensor_0f(struct synaptics_data *priv, | ||
678 | struct synaptics_mt_state *mt_state) | ||
679 | { | ||
680 | synaptics_mt_state_set(mt_state, 0, -1, -1); | ||
681 | priv->mt_state_lost = false; | ||
682 | } | ||
683 | |||
684 | /* Handle case where mt_state->count = 1 */ | ||
685 | static void synaptics_image_sensor_1f(struct synaptics_data *priv, | ||
686 | struct synaptics_mt_state *mt_state) | ||
687 | { | ||
688 | struct synaptics_hw_state *agm = &priv->agm; | ||
689 | struct synaptics_mt_state *old = &priv->mt_state; | ||
690 | |||
691 | /* | ||
692 | * If the last AGM was (0,0,0), and there is only one finger left, | ||
693 | * then we absolutely know that SGM contains slot 0, and all other | ||
694 | * fingers have been removed. | ||
695 | */ | ||
696 | if (priv->agm_pending && agm->z == 0) { | ||
697 | synaptics_mt_state_set(mt_state, 1, 0, -1); | ||
698 | priv->mt_state_lost = false; | ||
699 | return; | ||
700 | } | ||
701 | |||
702 | switch (old->count) { | ||
703 | case 0: | ||
704 | synaptics_mt_state_set(mt_state, 1, 0, -1); | ||
705 | break; | ||
706 | case 1: | ||
707 | /* | ||
708 | * If mt_state_lost, then the previous transition was 3->1, | ||
709 | * and SGM now contains either slot 0 or 1, but we don't know | ||
710 | * which. So, we just assume that the SGM now contains slot 1. | ||
711 | * | ||
712 | * If pending AGM and either: | ||
713 | * (a) the previous SGM slot contains slot 0, or | ||
714 | * (b) there was no SGM slot | ||
715 | * then, the SGM now contains slot 1 | ||
716 | * | ||
717 | * Case (a) happens with very rapid "drum roll" gestures, where | ||
718 | * slot 0 finger is lifted and a new slot 1 finger touches | ||
719 | * within one reporting interval. | ||
720 | * | ||
721 | * Case (b) happens if initially two or more fingers tap | ||
722 | * briefly, and all but one lift before the end of the first | ||
723 | * reporting interval. | ||
724 | * | ||
725 | * (In both these cases, slot 0 will becomes empty, so SGM | ||
726 | * contains slot 1 with the new finger) | ||
727 | * | ||
728 | * Else, if there was no previous SGM, it now contains slot 0. | ||
729 | * | ||
730 | * Otherwise, SGM still contains the same slot. | ||
731 | */ | ||
732 | if (priv->mt_state_lost || | ||
733 | (priv->agm_pending && old->sgm <= 0)) | ||
734 | synaptics_mt_state_set(mt_state, 1, 1, -1); | ||
735 | else if (old->sgm == -1) | ||
736 | synaptics_mt_state_set(mt_state, 1, 0, -1); | ||
737 | break; | ||
738 | case 2: | ||
739 | /* | ||
740 | * If mt_state_lost, we don't know which finger SGM contains. | ||
741 | * | ||
742 | * So, report 1 finger, but with both slots empty. | ||
743 | * We will use slot 1 on subsequent 1->1 | ||
744 | */ | ||
745 | if (priv->mt_state_lost) { | ||
746 | synaptics_mt_state_set(mt_state, 1, -1, -1); | ||
747 | break; | ||
748 | } | ||
749 | /* | ||
750 | * Since the last AGM was NOT (0,0,0), it was the finger in | ||
751 | * slot 0 that has been removed. | ||
752 | * So, SGM now contains previous AGM's slot, and AGM is now | ||
753 | * empty. | ||
754 | */ | ||
755 | synaptics_mt_state_set(mt_state, 1, old->agm, -1); | ||
756 | break; | ||
757 | case 3: | ||
758 | /* | ||
759 | * Since last AGM was not (0,0,0), we don't know which finger | ||
760 | * is left. | ||
761 | * | ||
762 | * So, report 1 finger, but with both slots empty. | ||
763 | * We will use slot 1 on subsequent 1->1 | ||
764 | */ | ||
765 | synaptics_mt_state_set(mt_state, 1, -1, -1); | ||
766 | priv->mt_state_lost = true; | ||
767 | break; | ||
768 | case 4: | ||
769 | case 5: | ||
770 | /* mt_state was updated by AGM-CONTACT packet */ | ||
771 | break; | ||
772 | } | ||
773 | } | ||
774 | |||
775 | /* Handle case where mt_state->count = 2 */ | ||
776 | static void synaptics_image_sensor_2f(struct synaptics_data *priv, | ||
777 | struct synaptics_mt_state *mt_state) | ||
778 | { | ||
779 | struct synaptics_mt_state *old = &priv->mt_state; | ||
780 | |||
781 | switch (old->count) { | ||
782 | case 0: | ||
783 | synaptics_mt_state_set(mt_state, 2, 0, 1); | ||
784 | break; | ||
785 | case 1: | ||
786 | /* | ||
787 | * If previous SGM contained slot 1 or higher, SGM now contains | ||
788 | * slot 0 (the newly touching finger) and AGM contains SGM's | ||
789 | * previous slot. | ||
790 | * | ||
791 | * Otherwise, SGM still contains slot 0 and AGM now contains | ||
792 | * slot 1. | ||
793 | */ | ||
794 | if (old->sgm >= 1) | ||
795 | synaptics_mt_state_set(mt_state, 2, 0, old->sgm); | ||
796 | else | ||
797 | synaptics_mt_state_set(mt_state, 2, 0, 1); | ||
798 | break; | ||
799 | case 2: | ||
800 | /* | ||
801 | * If mt_state_lost, SGM now contains either finger 1 or 2, but | ||
802 | * we don't know which. | ||
803 | * So, we just assume that the SGM contains slot 0 and AGM 1. | ||
804 | */ | ||
805 | if (priv->mt_state_lost) | ||
806 | synaptics_mt_state_set(mt_state, 2, 0, 1); | ||
807 | /* | ||
808 | * Otherwise, use the same mt_state, since it either hasn't | ||
809 | * changed, or was updated by a recently received AGM-CONTACT | ||
810 | * packet. | ||
811 | */ | ||
812 | break; | ||
813 | case 3: | ||
814 | /* | ||
815 | * 3->2 transitions have two unsolvable problems: | ||
816 | * 1) no indication is given which finger was removed | ||
817 | * 2) no way to tell if agm packet was for finger 3 | ||
818 | * before 3->2, or finger 2 after 3->2. | ||
819 | * | ||
820 | * So, report 2 fingers, but empty all slots. | ||
821 | * We will guess slots [0,1] on subsequent 2->2. | ||
822 | */ | ||
823 | synaptics_mt_state_set(mt_state, 2, -1, -1); | ||
824 | priv->mt_state_lost = true; | ||
825 | break; | ||
826 | case 4: | ||
827 | case 5: | ||
828 | /* mt_state was updated by AGM-CONTACT packet */ | ||
829 | break; | ||
830 | } | ||
831 | } | ||
832 | |||
833 | /* Handle case where mt_state->count = 3 */ | ||
834 | static void synaptics_image_sensor_3f(struct synaptics_data *priv, | ||
835 | struct synaptics_mt_state *mt_state) | ||
836 | { | ||
837 | struct synaptics_mt_state *old = &priv->mt_state; | ||
838 | |||
839 | switch (old->count) { | ||
840 | case 0: | ||
841 | synaptics_mt_state_set(mt_state, 3, 0, 2); | ||
842 | break; | ||
843 | case 1: | ||
844 | /* | ||
845 | * If previous SGM contained slot 2 or higher, SGM now contains | ||
846 | * slot 0 (one of the newly touching fingers) and AGM contains | ||
847 | * SGM's previous slot. | ||
848 | * | ||
849 | * Otherwise, SGM now contains slot 0 and AGM contains slot 2. | ||
850 | */ | ||
851 | if (old->sgm >= 2) | ||
852 | synaptics_mt_state_set(mt_state, 3, 0, old->sgm); | ||
853 | else | ||
854 | synaptics_mt_state_set(mt_state, 3, 0, 2); | ||
855 | break; | ||
856 | case 2: | ||
857 | /* | ||
858 | * If the AGM previously contained slot 3 or higher, then the | ||
859 | * newly touching finger is in the lowest available slot. | ||
860 | * | ||
861 | * If SGM was previously 1 or higher, then the new SGM is | ||
862 | * now slot 0 (with a new finger), otherwise, the new finger | ||
863 | * is now in a hidden slot between 0 and AGM's slot. | ||
864 | * | ||
865 | * In all such cases, the SGM now contains slot 0, and the AGM | ||
866 | * continues to contain the same slot as before. | ||
867 | */ | ||
868 | if (old->agm >= 3) { | ||
869 | synaptics_mt_state_set(mt_state, 3, 0, old->agm); | ||
870 | break; | ||
871 | } | ||
872 | |||
873 | /* | ||
874 | * After some 3->1 and all 3->2 transitions, we lose track | ||
875 | * of which slot is reported by SGM and AGM. | ||
876 | * | ||
877 | * For 2->3 in this state, report 3 fingers, but empty all | ||
878 | * slots, and we will guess (0,2) on a subsequent 0->3. | ||
879 | * | ||
880 | * To userspace, the resulting transition will look like: | ||
881 | * 2:[0,1] -> 3:[-1,-1] -> 3:[0,2] | ||
882 | */ | ||
883 | if (priv->mt_state_lost) { | ||
884 | synaptics_mt_state_set(mt_state, 3, -1, -1); | ||
885 | break; | ||
886 | } | ||
887 | |||
888 | /* | ||
889 | * If the (SGM,AGM) really previously contained slots (0, 1), | ||
890 | * then we cannot know what slot was just reported by the AGM, | ||
891 | * because the 2->3 transition can occur either before or after | ||
892 | * the AGM packet. Thus, this most recent AGM could contain | ||
893 | * either the same old slot 1 or the new slot 2. | ||
894 | * Subsequent AGMs will be reporting slot 2. | ||
895 | * | ||
896 | * To userspace, the resulting transition will look like: | ||
897 | * 2:[0,1] -> 3:[0,-1] -> 3:[0,2] | ||
898 | */ | ||
899 | synaptics_mt_state_set(mt_state, 3, 0, -1); | ||
900 | break; | ||
901 | case 3: | ||
902 | /* | ||
903 | * If, for whatever reason, the previous agm was invalid, | ||
904 | * Assume SGM now contains slot 0, AGM now contains slot 2. | ||
905 | */ | ||
906 | if (old->agm <= 2) | ||
907 | synaptics_mt_state_set(mt_state, 3, 0, 2); | ||
908 | /* | ||
909 | * mt_state either hasn't changed, or was updated by a recently | ||
910 | * received AGM-CONTACT packet. | ||
911 | */ | ||
912 | break; | ||
913 | |||
914 | case 4: | ||
915 | case 5: | ||
916 | /* mt_state was updated by AGM-CONTACT packet */ | ||
917 | break; | ||
918 | } | ||
919 | } | ||
920 | |||
921 | /* Handle case where mt_state->count = 4, or = 5 */ | ||
922 | static void synaptics_image_sensor_45f(struct synaptics_data *priv, | ||
923 | struct synaptics_mt_state *mt_state) | ||
924 | { | ||
925 | /* mt_state was updated correctly by AGM-CONTACT packet */ | ||
926 | priv->mt_state_lost = false; | ||
927 | } | ||
928 | |||
929 | static void synaptics_image_sensor_process(struct psmouse *psmouse, | ||
930 | struct synaptics_hw_state *sgm) | ||
931 | { | ||
932 | struct synaptics_data *priv = psmouse->private; | ||
933 | struct synaptics_hw_state *agm = &priv->agm; | ||
934 | struct synaptics_mt_state mt_state; | ||
935 | |||
936 | /* Initialize using current mt_state (as updated by last agm) */ | ||
937 | mt_state = agm->mt_state; | ||
938 | |||
939 | /* | ||
940 | * Update mt_state using the new finger count and current mt_state. | ||
941 | */ | ||
942 | if (sgm->z == 0) | ||
943 | synaptics_image_sensor_0f(priv, &mt_state); | ||
944 | else if (sgm->w >= 4) | ||
945 | synaptics_image_sensor_1f(priv, &mt_state); | ||
946 | else if (sgm->w == 0) | ||
947 | synaptics_image_sensor_2f(priv, &mt_state); | ||
948 | else if (sgm->w == 1 && mt_state.count <= 3) | ||
949 | synaptics_image_sensor_3f(priv, &mt_state); | ||
950 | else | ||
951 | synaptics_image_sensor_45f(priv, &mt_state); | ||
952 | |||
953 | /* Send resulting input events to user space */ | ||
954 | synaptics_report_mt_data(psmouse, &mt_state, sgm); | ||
955 | |||
956 | /* Store updated mt_state */ | ||
957 | priv->mt_state = agm->mt_state = mt_state; | ||
958 | priv->agm_pending = false; | ||
959 | } | ||
960 | |||
529 | /* | 961 | /* |
530 | * called for each full received packet from the touchpad | 962 | * called for each full received packet from the touchpad |
531 | */ | 963 | */ |
@@ -536,11 +968,15 @@ static void synaptics_process_packet(struct psmouse *psmouse) | |||
536 | struct synaptics_hw_state hw; | 968 | struct synaptics_hw_state hw; |
537 | int num_fingers; | 969 | int num_fingers; |
538 | int finger_width; | 970 | int finger_width; |
539 | int i; | ||
540 | 971 | ||
541 | if (synaptics_parse_hw_state(psmouse->packet, priv, &hw)) | 972 | if (synaptics_parse_hw_state(psmouse->packet, priv, &hw)) |
542 | return; | 973 | return; |
543 | 974 | ||
975 | if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { | ||
976 | synaptics_image_sensor_process(psmouse, &hw); | ||
977 | return; | ||
978 | } | ||
979 | |||
544 | if (hw.scroll) { | 980 | if (hw.scroll) { |
545 | priv->scroll += hw.scroll; | 981 | priv->scroll += hw.scroll; |
546 | 982 | ||
@@ -586,7 +1022,8 @@ static void synaptics_process_packet(struct psmouse *psmouse) | |||
586 | } | 1022 | } |
587 | 1023 | ||
588 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) | 1024 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) |
589 | synaptics_report_semi_mt_data(dev, &hw, &priv->mt, num_fingers); | 1025 | synaptics_report_semi_mt_data(dev, &hw, &priv->agm, |
1026 | num_fingers); | ||
590 | 1027 | ||
591 | /* Post events | 1028 | /* Post events |
592 | * BTN_TOUCH has to be first as mousedev relies on it when doing | 1029 | * BTN_TOUCH has to be first as mousedev relies on it when doing |
@@ -597,7 +1034,7 @@ static void synaptics_process_packet(struct psmouse *psmouse) | |||
597 | 1034 | ||
598 | if (num_fingers > 0) { | 1035 | if (num_fingers > 0) { |
599 | input_report_abs(dev, ABS_X, hw.x); | 1036 | input_report_abs(dev, ABS_X, hw.x); |
600 | input_report_abs(dev, ABS_Y, YMAX_NOMINAL + YMIN_NOMINAL - hw.y); | 1037 | input_report_abs(dev, ABS_Y, synaptics_invert_y(hw.y)); |
601 | } | 1038 | } |
602 | input_report_abs(dev, ABS_PRESSURE, hw.z); | 1039 | input_report_abs(dev, ABS_PRESSURE, hw.z); |
603 | 1040 | ||
@@ -605,35 +1042,25 @@ static void synaptics_process_packet(struct psmouse *psmouse) | |||
605 | input_report_abs(dev, ABS_TOOL_WIDTH, finger_width); | 1042 | input_report_abs(dev, ABS_TOOL_WIDTH, finger_width); |
606 | 1043 | ||
607 | input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1); | 1044 | input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1); |
608 | input_report_key(dev, BTN_LEFT, hw.left); | ||
609 | input_report_key(dev, BTN_RIGHT, hw.right); | ||
610 | |||
611 | if (SYN_CAP_MULTIFINGER(priv->capabilities)) { | 1045 | if (SYN_CAP_MULTIFINGER(priv->capabilities)) { |
612 | input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2); | 1046 | input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2); |
613 | input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3); | 1047 | input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3); |
614 | } | 1048 | } |
615 | 1049 | ||
616 | if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) | 1050 | synaptics_report_buttons(psmouse, &hw); |
617 | input_report_key(dev, BTN_MIDDLE, hw.middle); | ||
618 | |||
619 | if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) { | ||
620 | input_report_key(dev, BTN_FORWARD, hw.up); | ||
621 | input_report_key(dev, BTN_BACK, hw.down); | ||
622 | } | ||
623 | |||
624 | for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++) | ||
625 | input_report_key(dev, BTN_0 + i, hw.ext_buttons & (1 << i)); | ||
626 | 1051 | ||
627 | input_sync(dev); | 1052 | input_sync(dev); |
628 | } | 1053 | } |
629 | 1054 | ||
630 | static int synaptics_validate_byte(unsigned char packet[], int idx, unsigned char pkt_type) | 1055 | static int synaptics_validate_byte(struct psmouse *psmouse, |
1056 | int idx, unsigned char pkt_type) | ||
631 | { | 1057 | { |
632 | static const unsigned char newabs_mask[] = { 0xC8, 0x00, 0x00, 0xC8, 0x00 }; | 1058 | static const unsigned char newabs_mask[] = { 0xC8, 0x00, 0x00, 0xC8, 0x00 }; |
633 | static const unsigned char newabs_rel_mask[] = { 0xC0, 0x00, 0x00, 0xC0, 0x00 }; | 1059 | static const unsigned char newabs_rel_mask[] = { 0xC0, 0x00, 0x00, 0xC0, 0x00 }; |
634 | static const unsigned char newabs_rslt[] = { 0x80, 0x00, 0x00, 0xC0, 0x00 }; | 1060 | static const unsigned char newabs_rslt[] = { 0x80, 0x00, 0x00, 0xC0, 0x00 }; |
635 | static const unsigned char oldabs_mask[] = { 0xC0, 0x60, 0x00, 0xC0, 0x60 }; | 1061 | static const unsigned char oldabs_mask[] = { 0xC0, 0x60, 0x00, 0xC0, 0x60 }; |
636 | static const unsigned char oldabs_rslt[] = { 0xC0, 0x00, 0x00, 0x80, 0x00 }; | 1062 | static const unsigned char oldabs_rslt[] = { 0xC0, 0x00, 0x00, 0x80, 0x00 }; |
1063 | const char *packet = psmouse->packet; | ||
637 | 1064 | ||
638 | if (idx < 0 || idx > 4) | 1065 | if (idx < 0 || idx > 4) |
639 | return 0; | 1066 | return 0; |
@@ -651,7 +1078,7 @@ static int synaptics_validate_byte(unsigned char packet[], int idx, unsigned cha | |||
651 | return (packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx]; | 1078 | return (packet[idx] & oldabs_mask[idx]) == oldabs_rslt[idx]; |
652 | 1079 | ||
653 | default: | 1080 | default: |
654 | printk(KERN_ERR "synaptics: unknown packet type %d\n", pkt_type); | 1081 | psmouse_err(psmouse, "unknown packet type %d\n", pkt_type); |
655 | return 0; | 1082 | return 0; |
656 | } | 1083 | } |
657 | } | 1084 | } |
@@ -661,8 +1088,8 @@ static unsigned char synaptics_detect_pkt_type(struct psmouse *psmouse) | |||
661 | int i; | 1088 | int i; |
662 | 1089 | ||
663 | for (i = 0; i < 5; i++) | 1090 | for (i = 0; i < 5; i++) |
664 | if (!synaptics_validate_byte(psmouse->packet, i, SYN_NEWABS_STRICT)) { | 1091 | if (!synaptics_validate_byte(psmouse, i, SYN_NEWABS_STRICT)) { |
665 | printk(KERN_INFO "synaptics: using relaxed packet validation\n"); | 1092 | psmouse_info(psmouse, "using relaxed packet validation\n"); |
666 | return SYN_NEWABS_RELAXED; | 1093 | return SYN_NEWABS_RELAXED; |
667 | } | 1094 | } |
668 | 1095 | ||
@@ -687,46 +1114,56 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse) | |||
687 | return PSMOUSE_FULL_PACKET; | 1114 | return PSMOUSE_FULL_PACKET; |
688 | } | 1115 | } |
689 | 1116 | ||
690 | return synaptics_validate_byte(psmouse->packet, psmouse->pktcnt - 1, priv->pkt_type) ? | 1117 | return synaptics_validate_byte(psmouse, psmouse->pktcnt - 1, priv->pkt_type) ? |
691 | PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; | 1118 | PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; |
692 | } | 1119 | } |
693 | 1120 | ||
694 | /***************************************************************************** | 1121 | /***************************************************************************** |
695 | * Driver initialization/cleanup functions | 1122 | * Driver initialization/cleanup functions |
696 | ****************************************************************************/ | 1123 | ****************************************************************************/ |
697 | static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | 1124 | static void set_abs_position_params(struct input_dev *dev, |
1125 | struct synaptics_data *priv, int x_code, | ||
1126 | int y_code) | ||
698 | { | 1127 | { |
699 | int i; | 1128 | int x_min = priv->x_min ?: XMIN_NOMINAL; |
1129 | int x_max = priv->x_max ?: XMAX_NOMINAL; | ||
1130 | int y_min = priv->y_min ?: YMIN_NOMINAL; | ||
1131 | int y_max = priv->y_max ?: YMAX_NOMINAL; | ||
700 | int fuzz = SYN_CAP_REDUCED_FILTERING(priv->ext_cap_0c) ? | 1132 | int fuzz = SYN_CAP_REDUCED_FILTERING(priv->ext_cap_0c) ? |
701 | SYN_REDUCED_FILTER_FUZZ : 0; | 1133 | SYN_REDUCED_FILTER_FUZZ : 0; |
702 | 1134 | ||
1135 | input_set_abs_params(dev, x_code, x_min, x_max, fuzz, 0); | ||
1136 | input_set_abs_params(dev, y_code, y_min, y_max, fuzz, 0); | ||
1137 | input_abs_set_res(dev, x_code, priv->x_res); | ||
1138 | input_abs_set_res(dev, y_code, priv->y_res); | ||
1139 | } | ||
1140 | |||
1141 | static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | ||
1142 | { | ||
1143 | int i; | ||
1144 | |||
703 | __set_bit(INPUT_PROP_POINTER, dev->propbit); | 1145 | __set_bit(INPUT_PROP_POINTER, dev->propbit); |
704 | 1146 | ||
705 | __set_bit(EV_ABS, dev->evbit); | 1147 | __set_bit(EV_ABS, dev->evbit); |
706 | input_set_abs_params(dev, ABS_X, | 1148 | set_abs_position_params(dev, priv, ABS_X, ABS_Y); |
707 | priv->x_min ?: XMIN_NOMINAL, | ||
708 | priv->x_max ?: XMAX_NOMINAL, | ||
709 | fuzz, 0); | ||
710 | input_set_abs_params(dev, ABS_Y, | ||
711 | priv->y_min ?: YMIN_NOMINAL, | ||
712 | priv->y_max ?: YMAX_NOMINAL, | ||
713 | fuzz, 0); | ||
714 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); | 1149 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); |
715 | 1150 | ||
716 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { | 1151 | if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { |
1152 | input_mt_init_slots(dev, 2); | ||
1153 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, | ||
1154 | ABS_MT_POSITION_Y); | ||
1155 | /* Image sensors can report per-contact pressure */ | ||
1156 | input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0); | ||
1157 | |||
1158 | /* Image sensors can signal 4 and 5 finger clicks */ | ||
1159 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); | ||
1160 | __set_bit(BTN_TOOL_QUINTTAP, dev->keybit); | ||
1161 | } else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { | ||
1162 | /* Non-image sensors with AGM use semi-mt */ | ||
717 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); | 1163 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); |
718 | input_mt_init_slots(dev, 2); | 1164 | input_mt_init_slots(dev, 2); |
719 | input_set_abs_params(dev, ABS_MT_POSITION_X, | 1165 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, |
720 | priv->x_min ?: XMIN_NOMINAL, | 1166 | ABS_MT_POSITION_Y); |
721 | priv->x_max ?: XMAX_NOMINAL, | ||
722 | fuzz, 0); | ||
723 | input_set_abs_params(dev, ABS_MT_POSITION_Y, | ||
724 | priv->y_min ?: YMIN_NOMINAL, | ||
725 | priv->y_max ?: YMAX_NOMINAL, | ||
726 | fuzz, 0); | ||
727 | |||
728 | input_abs_set_res(dev, ABS_MT_POSITION_X, priv->x_res); | ||
729 | input_abs_set_res(dev, ABS_MT_POSITION_Y, priv->y_res); | ||
730 | } | 1167 | } |
731 | 1168 | ||
732 | if (SYN_CAP_PALMDETECT(priv->capabilities)) | 1169 | if (SYN_CAP_PALMDETECT(priv->capabilities)) |
@@ -759,9 +1196,6 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
759 | __clear_bit(REL_X, dev->relbit); | 1196 | __clear_bit(REL_X, dev->relbit); |
760 | __clear_bit(REL_Y, dev->relbit); | 1197 | __clear_bit(REL_Y, dev->relbit); |
761 | 1198 | ||
762 | input_abs_set_res(dev, ABS_X, priv->x_res); | ||
763 | input_abs_set_res(dev, ABS_Y, priv->y_res); | ||
764 | |||
765 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { | 1199 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { |
766 | __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); | 1200 | __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); |
767 | /* Clickpads report only left button */ | 1201 | /* Clickpads report only left button */ |
@@ -793,21 +1227,21 @@ static int synaptics_reconnect(struct psmouse *psmouse) | |||
793 | return -1; | 1227 | return -1; |
794 | 1228 | ||
795 | if (retry > 1) | 1229 | if (retry > 1) |
796 | printk(KERN_DEBUG "Synaptics reconnected after %d tries\n", | 1230 | psmouse_dbg(psmouse, "reconnected after %d tries\n", retry); |
797 | retry); | ||
798 | 1231 | ||
799 | if (synaptics_query_hardware(psmouse)) { | 1232 | if (synaptics_query_hardware(psmouse)) { |
800 | printk(KERN_ERR "Unable to query Synaptics hardware.\n"); | 1233 | psmouse_err(psmouse, "Unable to query device.\n"); |
801 | return -1; | 1234 | return -1; |
802 | } | 1235 | } |
803 | 1236 | ||
804 | if (synaptics_set_absolute_mode(psmouse)) { | 1237 | if (synaptics_set_absolute_mode(psmouse)) { |
805 | printk(KERN_ERR "Unable to initialize Synaptics hardware.\n"); | 1238 | psmouse_err(psmouse, "Unable to initialize device.\n"); |
806 | return -1; | 1239 | return -1; |
807 | } | 1240 | } |
808 | 1241 | ||
809 | if (synaptics_set_advanced_gesture_mode(psmouse)) { | 1242 | if (synaptics_set_advanced_gesture_mode(psmouse)) { |
810 | printk(KERN_ERR "Advanced gesture mode reconnect failed.\n"); | 1243 | psmouse_err(psmouse, |
1244 | "Advanced gesture mode reconnect failed.\n"); | ||
811 | return -1; | 1245 | return -1; |
812 | } | 1246 | } |
813 | 1247 | ||
@@ -815,12 +1249,12 @@ static int synaptics_reconnect(struct psmouse *psmouse) | |||
815 | old_priv.model_id != priv->model_id || | 1249 | old_priv.model_id != priv->model_id || |
816 | old_priv.capabilities != priv->capabilities || | 1250 | old_priv.capabilities != priv->capabilities || |
817 | old_priv.ext_cap != priv->ext_cap) { | 1251 | old_priv.ext_cap != priv->ext_cap) { |
818 | printk(KERN_ERR "Synaptics hardware appears to be different: " | 1252 | psmouse_err(psmouse, |
819 | "id(%ld-%ld), model(%ld-%ld), caps(%lx-%lx), ext(%lx-%lx).\n", | 1253 | "hardware appears to be different: id(%ld-%ld), model(%ld-%ld), caps(%lx-%lx), ext(%lx-%lx).\n", |
820 | old_priv.identity, priv->identity, | 1254 | old_priv.identity, priv->identity, |
821 | old_priv.model_id, priv->model_id, | 1255 | old_priv.model_id, priv->model_id, |
822 | old_priv.capabilities, priv->capabilities, | 1256 | old_priv.capabilities, priv->capabilities, |
823 | old_priv.ext_cap, priv->ext_cap); | 1257 | old_priv.ext_cap, priv->ext_cap); |
824 | return -1; | 1258 | return -1; |
825 | } | 1259 | } |
826 | 1260 | ||
@@ -901,7 +1335,8 @@ int synaptics_init(struct psmouse *psmouse) | |||
901 | * just fine. | 1335 | * just fine. |
902 | */ | 1336 | */ |
903 | if (broken_olpc_ec) { | 1337 | if (broken_olpc_ec) { |
904 | printk(KERN_INFO "synaptics: OLPC XO detected, not enabling Synaptics protocol.\n"); | 1338 | psmouse_info(psmouse, |
1339 | "OLPC XO detected, not enabling Synaptics protocol.\n"); | ||
905 | return -ENODEV; | 1340 | return -ENODEV; |
906 | } | 1341 | } |
907 | 1342 | ||
@@ -912,26 +1347,28 @@ int synaptics_init(struct psmouse *psmouse) | |||
912 | psmouse_reset(psmouse); | 1347 | psmouse_reset(psmouse); |
913 | 1348 | ||
914 | if (synaptics_query_hardware(psmouse)) { | 1349 | if (synaptics_query_hardware(psmouse)) { |
915 | printk(KERN_ERR "Unable to query Synaptics hardware.\n"); | 1350 | psmouse_err(psmouse, "Unable to query device.\n"); |
916 | goto init_fail; | 1351 | goto init_fail; |
917 | } | 1352 | } |
918 | 1353 | ||
919 | if (synaptics_set_absolute_mode(psmouse)) { | 1354 | if (synaptics_set_absolute_mode(psmouse)) { |
920 | printk(KERN_ERR "Unable to initialize Synaptics hardware.\n"); | 1355 | psmouse_err(psmouse, "Unable to initialize device.\n"); |
921 | goto init_fail; | 1356 | goto init_fail; |
922 | } | 1357 | } |
923 | 1358 | ||
924 | if (synaptics_set_advanced_gesture_mode(psmouse)) { | 1359 | if (synaptics_set_advanced_gesture_mode(psmouse)) { |
925 | printk(KERN_ERR "Advanced gesture mode init failed.\n"); | 1360 | psmouse_err(psmouse, "Advanced gesture mode init failed.\n"); |
926 | goto init_fail; | 1361 | goto init_fail; |
927 | } | 1362 | } |
928 | 1363 | ||
929 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; | 1364 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; |
930 | 1365 | ||
931 | printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n", | 1366 | psmouse_info(psmouse, |
932 | SYN_ID_MODEL(priv->identity), | 1367 | "Touchpad model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n", |
933 | SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), | 1368 | SYN_ID_MODEL(priv->identity), |
934 | priv->model_id, priv->capabilities, priv->ext_cap, priv->ext_cap_0c); | 1369 | SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), |
1370 | priv->model_id, | ||
1371 | priv->capabilities, priv->ext_cap, priv->ext_cap_0c); | ||
935 | 1372 | ||
936 | set_input_params(psmouse->dev, priv); | 1373 | set_input_params(psmouse->dev, priv); |
937 | 1374 | ||
@@ -963,8 +1400,9 @@ int synaptics_init(struct psmouse *psmouse) | |||
963 | * the same rate as a standard PS/2 mouse). | 1400 | * the same rate as a standard PS/2 mouse). |
964 | */ | 1401 | */ |
965 | if (psmouse->rate >= 80 && impaired_toshiba_kbc) { | 1402 | if (psmouse->rate >= 80 && impaired_toshiba_kbc) { |
966 | printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n", | 1403 | psmouse_info(psmouse, |
967 | dmi_get_system_info(DMI_PRODUCT_NAME)); | 1404 | "Toshiba %s detected, limiting rate to 40pps.\n", |
1405 | dmi_get_system_info(DMI_PRODUCT_NAME)); | ||
968 | psmouse->rate = 40; | 1406 | psmouse->rate = 40; |
969 | } | 1407 | } |
970 | 1408 | ||
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index ca040aa80fa7..622aea8dd7e0 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
@@ -74,6 +74,8 @@ | |||
74 | * 2 0x04 reduced filtering firmware does less filtering on | 74 | * 2 0x04 reduced filtering firmware does less filtering on |
75 | * position data, driver should watch | 75 | * position data, driver should watch |
76 | * for noise. | 76 | * for noise. |
77 | * 2 0x08 image sensor image sensor tracks 5 fingers, but only | ||
78 | * reports 2. | ||
77 | * 2 0x20 report min query 0x0f gives min coord reported | 79 | * 2 0x20 report min query 0x0f gives min coord reported |
78 | */ | 80 | */ |
79 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ | 81 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ |
@@ -82,6 +84,7 @@ | |||
82 | #define SYN_CAP_MIN_DIMENSIONS(ex0c) ((ex0c) & 0x002000) | 84 | #define SYN_CAP_MIN_DIMENSIONS(ex0c) ((ex0c) & 0x002000) |
83 | #define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000) | 85 | #define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000) |
84 | #define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400) | 86 | #define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400) |
87 | #define SYN_CAP_IMAGE_SENSOR(ex0c) ((ex0c) & 0x000800) | ||
85 | 88 | ||
86 | /* synaptics modes query bits */ | 89 | /* synaptics modes query bits */ |
87 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) | 90 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) |
@@ -112,9 +115,18 @@ | |||
112 | #define SYN_REDUCED_FILTER_FUZZ 8 | 115 | #define SYN_REDUCED_FILTER_FUZZ 8 |
113 | 116 | ||
114 | /* | 117 | /* |
115 | * A structure to describe the state of the touchpad hardware (buttons and pad) | 118 | * A structure to describe which internal touchpad finger slots are being |
119 | * reported in raw packets. | ||
116 | */ | 120 | */ |
121 | struct synaptics_mt_state { | ||
122 | int count; /* num fingers being tracked */ | ||
123 | int sgm; /* which slot is reported by sgm pkt */ | ||
124 | int agm; /* which slot is reported by agm pkt*/ | ||
125 | }; | ||
117 | 126 | ||
127 | /* | ||
128 | * A structure to describe the state of the touchpad hardware (buttons and pad) | ||
129 | */ | ||
118 | struct synaptics_hw_state { | 130 | struct synaptics_hw_state { |
119 | int x; | 131 | int x; |
120 | int y; | 132 | int y; |
@@ -127,6 +139,9 @@ struct synaptics_hw_state { | |||
127 | unsigned int down:1; | 139 | unsigned int down:1; |
128 | unsigned char ext_buttons; | 140 | unsigned char ext_buttons; |
129 | signed char scroll; | 141 | signed char scroll; |
142 | |||
143 | /* As reported in last AGM-CONTACT packets */ | ||
144 | struct synaptics_mt_state mt_state; | ||
130 | }; | 145 | }; |
131 | 146 | ||
132 | struct synaptics_data { | 147 | struct synaptics_data { |
@@ -146,7 +161,15 @@ struct synaptics_data { | |||
146 | 161 | ||
147 | struct serio *pt_port; /* Pass-through serio port */ | 162 | struct serio *pt_port; /* Pass-through serio port */ |
148 | 163 | ||
149 | struct synaptics_hw_state mt; /* current gesture packet */ | 164 | struct synaptics_mt_state mt_state; /* Current mt finger state */ |
165 | bool mt_state_lost; /* mt_state may be incorrect */ | ||
166 | |||
167 | /* | ||
168 | * Last received Advanced Gesture Mode (AGM) packet. An AGM packet | ||
169 | * contains position data for a second contact, at half resolution. | ||
170 | */ | ||
171 | struct synaptics_hw_state agm; | ||
172 | bool agm_pending; /* new AGM packet received */ | ||
150 | }; | 173 | }; |
151 | 174 | ||
152 | void synaptics_module_init(void); | 175 | void synaptics_module_init(void); |
diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c index cba3c84d2f21..4b755cb5b38c 100644 --- a/drivers/input/mouse/synaptics_i2c.c +++ b/drivers/input/mouse/synaptics_i2c.c | |||
@@ -570,7 +570,7 @@ static int __devinit synaptics_i2c_probe(struct i2c_client *client, | |||
570 | "Requesting IRQ: %d\n", touch->client->irq); | 570 | "Requesting IRQ: %d\n", touch->client->irq); |
571 | 571 | ||
572 | ret = request_irq(touch->client->irq, synaptics_i2c_irq, | 572 | ret = request_irq(touch->client->irq, synaptics_i2c_irq, |
573 | IRQF_DISABLED|IRQ_TYPE_EDGE_FALLING, | 573 | IRQ_TYPE_EDGE_FALLING, |
574 | DRIVER_NAME, touch); | 574 | DRIVER_NAME, touch); |
575 | if (ret) { | 575 | if (ret) { |
576 | dev_warn(&touch->client->dev, | 576 | dev_warn(&touch->client->dev, |
@@ -619,7 +619,7 @@ static int __devexit synaptics_i2c_remove(struct i2c_client *client) | |||
619 | return 0; | 619 | return 0; |
620 | } | 620 | } |
621 | 621 | ||
622 | #ifdef CONFIG_PM | 622 | #ifdef CONFIG_PM_SLEEP |
623 | static int synaptics_i2c_suspend(struct device *dev) | 623 | static int synaptics_i2c_suspend(struct device *dev) |
624 | { | 624 | { |
625 | struct i2c_client *client = to_i2c_client(dev); | 625 | struct i2c_client *client = to_i2c_client(dev); |