diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2018-03-17 13:58:05 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2018-03-17 13:58:05 -0400 |
commit | ba521f1bd202237d2c1dea95e4213169b8c6ba01 (patch) | |
tree | 2a0a1b5e158a2a2311221f05b873cbae6672643d | |
parent | 83fc580dcc2f0f36114477c4ac7adbe5c32329a3 (diff) | |
parent | 3aceaa34d7723c2556555b05ad04a89ce2d66374 (diff) |
Merge branch 'psmouse' into next
Merge various PS/2 handling improvements.
-rw-r--r-- | drivers/input/mouse/alps.c | 30 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.c | 40 | ||||
-rw-r--r-- | drivers/input/mouse/lifebook.c | 62 | ||||
-rw-r--r-- | drivers/input/mouse/logips2pp.c | 152 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse-base.c | 189 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse.h | 5 | ||||
-rw-r--r-- | drivers/input/mouse/sentelic.c | 11 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.c | 8 | ||||
-rw-r--r-- | drivers/input/mouse/trackpoint.c | 60 | ||||
-rw-r--r-- | drivers/input/serio/libps2.c | 322 | ||||
-rw-r--r-- | include/linux/libps2.h | 38 |
11 files changed, 521 insertions, 396 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index dbe57da8c1a1..f9c7f2452264 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -827,7 +827,7 @@ static void alps_process_packet_v6(struct psmouse *psmouse) | |||
827 | unsigned char *packet = psmouse->packet; | 827 | unsigned char *packet = psmouse->packet; |
828 | struct input_dev *dev = psmouse->dev; | 828 | struct input_dev *dev = psmouse->dev; |
829 | struct input_dev *dev2 = priv->dev2; | 829 | struct input_dev *dev2 = priv->dev2; |
830 | int x, y, z, left, right, middle; | 830 | int x, y, z; |
831 | 831 | ||
832 | /* | 832 | /* |
833 | * We can use Byte5 to distinguish if the packet is from Touchpad | 833 | * We can use Byte5 to distinguish if the packet is from Touchpad |
@@ -847,9 +847,6 @@ static void alps_process_packet_v6(struct psmouse *psmouse) | |||
847 | x = packet[1] | ((packet[3] & 0x20) << 2); | 847 | x = packet[1] | ((packet[3] & 0x20) << 2); |
848 | y = packet[2] | ((packet[3] & 0x40) << 1); | 848 | y = packet[2] | ((packet[3] & 0x40) << 1); |
849 | z = packet[4]; | 849 | z = packet[4]; |
850 | left = packet[3] & 0x01; | ||
851 | right = packet[3] & 0x02; | ||
852 | middle = packet[3] & 0x04; | ||
853 | 850 | ||
854 | /* To prevent the cursor jump when finger lifted */ | 851 | /* To prevent the cursor jump when finger lifted */ |
855 | if (x == 0x7F && y == 0x7F && z == 0x7F) | 852 | if (x == 0x7F && y == 0x7F && z == 0x7F) |
@@ -859,9 +856,7 @@ static void alps_process_packet_v6(struct psmouse *psmouse) | |||
859 | input_report_rel(dev2, REL_X, (char)x / 4); | 856 | input_report_rel(dev2, REL_X, (char)x / 4); |
860 | input_report_rel(dev2, REL_Y, -((char)y / 4)); | 857 | input_report_rel(dev2, REL_Y, -((char)y / 4)); |
861 | 858 | ||
862 | input_report_key(dev2, BTN_LEFT, left); | 859 | psmouse_report_standard_buttons(dev2, packet[3]); |
863 | input_report_key(dev2, BTN_RIGHT, right); | ||
864 | input_report_key(dev2, BTN_MIDDLE, middle); | ||
865 | 860 | ||
866 | input_sync(dev2); | 861 | input_sync(dev2); |
867 | return; | 862 | return; |
@@ -871,8 +866,6 @@ static void alps_process_packet_v6(struct psmouse *psmouse) | |||
871 | x = packet[1] | ((packet[3] & 0x78) << 4); | 866 | x = packet[1] | ((packet[3] & 0x78) << 4); |
872 | y = packet[2] | ((packet[4] & 0x78) << 4); | 867 | y = packet[2] | ((packet[4] & 0x78) << 4); |
873 | z = packet[5]; | 868 | z = packet[5]; |
874 | left = packet[3] & 0x01; | ||
875 | right = packet[3] & 0x02; | ||
876 | 869 | ||
877 | if (z > 30) | 870 | if (z > 30) |
878 | input_report_key(dev, BTN_TOUCH, 1); | 871 | input_report_key(dev, BTN_TOUCH, 1); |
@@ -888,8 +881,8 @@ static void alps_process_packet_v6(struct psmouse *psmouse) | |||
888 | input_report_key(dev, BTN_TOOL_FINGER, z > 0); | 881 | input_report_key(dev, BTN_TOOL_FINGER, z > 0); |
889 | 882 | ||
890 | /* v6 touchpad does not have middle button */ | 883 | /* v6 touchpad does not have middle button */ |
891 | input_report_key(dev, BTN_LEFT, left); | 884 | packet[3] &= ~BIT(2); |
892 | input_report_key(dev, BTN_RIGHT, right); | 885 | psmouse_report_standard_buttons(dev2, packet[3]); |
893 | 886 | ||
894 | input_sync(dev); | 887 | input_sync(dev); |
895 | } | 888 | } |
@@ -1098,7 +1091,7 @@ static void alps_process_trackstick_packet_v7(struct psmouse *psmouse) | |||
1098 | struct alps_data *priv = psmouse->private; | 1091 | struct alps_data *priv = psmouse->private; |
1099 | unsigned char *packet = psmouse->packet; | 1092 | unsigned char *packet = psmouse->packet; |
1100 | struct input_dev *dev2 = priv->dev2; | 1093 | struct input_dev *dev2 = priv->dev2; |
1101 | int x, y, z, left, right, middle; | 1094 | int x, y, z; |
1102 | 1095 | ||
1103 | /* It should be a DualPoint when received trackstick packet */ | 1096 | /* It should be a DualPoint when received trackstick packet */ |
1104 | if (!(priv->flags & ALPS_DUALPOINT)) { | 1097 | if (!(priv->flags & ALPS_DUALPOINT)) { |
@@ -1112,16 +1105,10 @@ static void alps_process_trackstick_packet_v7(struct psmouse *psmouse) | |||
1112 | ((packet[3] & 0x20) << 1); | 1105 | ((packet[3] & 0x20) << 1); |
1113 | z = (packet[5] & 0x3f) | ((packet[3] & 0x80) >> 1); | 1106 | z = (packet[5] & 0x3f) | ((packet[3] & 0x80) >> 1); |
1114 | 1107 | ||
1115 | left = (packet[1] & 0x01); | ||
1116 | right = (packet[1] & 0x02) >> 1; | ||
1117 | middle = (packet[1] & 0x04) >> 2; | ||
1118 | |||
1119 | input_report_rel(dev2, REL_X, (char)x); | 1108 | input_report_rel(dev2, REL_X, (char)x); |
1120 | input_report_rel(dev2, REL_Y, -((char)y)); | 1109 | input_report_rel(dev2, REL_Y, -((char)y)); |
1121 | 1110 | ||
1122 | input_report_key(dev2, BTN_LEFT, left); | 1111 | psmouse_report_standard_buttons(dev2, packet[1]); |
1123 | input_report_key(dev2, BTN_RIGHT, right); | ||
1124 | input_report_key(dev2, BTN_MIDDLE, middle); | ||
1125 | 1112 | ||
1126 | input_sync(dev2); | 1113 | input_sync(dev2); |
1127 | } | 1114 | } |
@@ -1503,10 +1490,7 @@ static void alps_report_bare_ps2_packet(struct psmouse *psmouse, | |||
1503 | alps_report_buttons(dev, dev2, | 1490 | alps_report_buttons(dev, dev2, |
1504 | packet[0] & 1, packet[0] & 2, packet[0] & 4); | 1491 | packet[0] & 1, packet[0] & 2, packet[0] & 4); |
1505 | 1492 | ||
1506 | input_report_rel(dev, REL_X, | 1493 | psmouse_report_standard_motion(dev, packet); |
1507 | packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0); | ||
1508 | input_report_rel(dev, REL_Y, | ||
1509 | packet[2] ? ((packet[0] << 3) & 0x100) - packet[2] : 0); | ||
1510 | 1494 | ||
1511 | input_sync(dev); | 1495 | input_sync(dev); |
1512 | } | 1496 | } |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index a4aaa748e987..db47a5e1d114 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -35,7 +35,7 @@ | |||
35 | static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, | 35 | static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, |
36 | unsigned char *param) | 36 | unsigned char *param) |
37 | { | 37 | { |
38 | if (psmouse_sliced_command(psmouse, c) || | 38 | if (ps2_sliced_command(&psmouse->ps2dev, c) || |
39 | ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) { | 39 | ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) { |
40 | psmouse_err(psmouse, "%s query 0x%02x failed.\n", __func__, c); | 40 | psmouse_err(psmouse, "%s query 0x%02x failed.\n", __func__, c); |
41 | return -1; | 41 | return -1; |
@@ -107,8 +107,8 @@ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg, | |||
107 | 107 | ||
108 | switch (etd->hw_version) { | 108 | switch (etd->hw_version) { |
109 | case 1: | 109 | case 1: |
110 | if (psmouse_sliced_command(psmouse, ETP_REGISTER_READ) || | 110 | if (ps2_sliced_command(&psmouse->ps2dev, ETP_REGISTER_READ) || |
111 | psmouse_sliced_command(psmouse, reg) || | 111 | ps2_sliced_command(&psmouse->ps2dev, reg) || |
112 | ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) { | 112 | ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) { |
113 | rc = -1; | 113 | rc = -1; |
114 | } | 114 | } |
@@ -162,9 +162,9 @@ static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg, | |||
162 | 162 | ||
163 | switch (etd->hw_version) { | 163 | switch (etd->hw_version) { |
164 | case 1: | 164 | case 1: |
165 | if (psmouse_sliced_command(psmouse, ETP_REGISTER_WRITE) || | 165 | if (ps2_sliced_command(&psmouse->ps2dev, ETP_REGISTER_WRITE) || |
166 | psmouse_sliced_command(psmouse, reg) || | 166 | ps2_sliced_command(&psmouse->ps2dev, reg) || |
167 | psmouse_sliced_command(psmouse, val) || | 167 | ps2_sliced_command(&psmouse->ps2dev, val) || |
168 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11)) { | 168 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11)) { |
169 | rc = -1; | 169 | rc = -1; |
170 | } | 170 | } |
@@ -279,8 +279,8 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
279 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); | 279 | input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); |
280 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); | 280 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); |
281 | input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); | 281 | input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); |
282 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | 282 | |
283 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | 283 | psmouse_report_standard_buttons(dev, packet[0]); |
284 | 284 | ||
285 | if (etd->fw_version < 0x020000 && | 285 | if (etd->fw_version < 0x020000 && |
286 | (etd->capabilities[0] & ETP_CAP_HAS_ROCKER)) { | 286 | (etd->capabilities[0] & ETP_CAP_HAS_ROCKER)) { |
@@ -390,8 +390,7 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
390 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); | 390 | input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); |
391 | input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); | 391 | input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); |
392 | input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4); | 392 | input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4); |
393 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | 393 | psmouse_report_standard_buttons(dev, packet[0]); |
394 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | ||
395 | if (etd->reports_pressure) { | 394 | if (etd->reports_pressure) { |
396 | input_report_abs(dev, ABS_PRESSURE, pres); | 395 | input_report_abs(dev, ABS_PRESSURE, pres); |
397 | input_report_abs(dev, ABS_TOOL_WIDTH, width); | 396 | input_report_abs(dev, ABS_TOOL_WIDTH, width); |
@@ -434,9 +433,7 @@ static void elantech_report_trackpoint(struct psmouse *psmouse, | |||
434 | x = packet[4] - (int)((packet[1]^0x80) << 1); | 433 | x = packet[4] - (int)((packet[1]^0x80) << 1); |
435 | y = (int)((packet[2]^0x80) << 1) - packet[5]; | 434 | y = (int)((packet[2]^0x80) << 1) - packet[5]; |
436 | 435 | ||
437 | input_report_key(tp_dev, BTN_LEFT, packet[0] & 0x01); | 436 | psmouse_report_standard_buttons(tp_dev, packet[0]); |
438 | input_report_key(tp_dev, BTN_RIGHT, packet[0] & 0x02); | ||
439 | input_report_key(tp_dev, BTN_MIDDLE, packet[0] & 0x04); | ||
440 | 437 | ||
441 | input_report_rel(tp_dev, REL_X, x); | 438 | input_report_rel(tp_dev, REL_X, x); |
442 | input_report_rel(tp_dev, REL_Y, y); | 439 | input_report_rel(tp_dev, REL_Y, y); |
@@ -526,12 +523,10 @@ static void elantech_report_absolute_v3(struct psmouse *psmouse, | |||
526 | input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); | 523 | input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); |
527 | 524 | ||
528 | /* For clickpads map both buttons to BTN_LEFT */ | 525 | /* For clickpads map both buttons to BTN_LEFT */ |
529 | if (etd->fw_version & 0x001000) { | 526 | if (etd->fw_version & 0x001000) |
530 | input_report_key(dev, BTN_LEFT, packet[0] & 0x03); | 527 | input_report_key(dev, BTN_LEFT, packet[0] & 0x03); |
531 | } else { | 528 | else |
532 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | 529 | psmouse_report_standard_buttons(dev, packet[0]); |
533 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | ||
534 | } | ||
535 | 530 | ||
536 | input_report_abs(dev, ABS_PRESSURE, pres); | 531 | input_report_abs(dev, ABS_PRESSURE, pres); |
537 | input_report_abs(dev, ABS_TOOL_WIDTH, width); | 532 | input_report_abs(dev, ABS_TOOL_WIDTH, width); |
@@ -546,13 +541,10 @@ static void elantech_input_sync_v4(struct psmouse *psmouse) | |||
546 | unsigned char *packet = psmouse->packet; | 541 | unsigned char *packet = psmouse->packet; |
547 | 542 | ||
548 | /* For clickpads map both buttons to BTN_LEFT */ | 543 | /* For clickpads map both buttons to BTN_LEFT */ |
549 | if (etd->fw_version & 0x001000) { | 544 | if (etd->fw_version & 0x001000) |
550 | input_report_key(dev, BTN_LEFT, packet[0] & 0x03); | 545 | input_report_key(dev, BTN_LEFT, packet[0] & 0x03); |
551 | } else { | 546 | else |
552 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | 547 | psmouse_report_standard_buttons(dev, packet[0]); |
553 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | ||
554 | input_report_key(dev, BTN_MIDDLE, packet[0] & 0x04); | ||
555 | } | ||
556 | 548 | ||
557 | input_mt_report_pointer_emulation(dev, true); | 549 | input_mt_report_pointer_emulation(dev, true); |
558 | input_sync(dev); | 550 | input_sync(dev); |
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 13d324cef7df..a5765f747c02 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/libps2.h> | 17 | #include <linux/libps2.h> |
18 | #include <linux/dmi.h> | 18 | #include <linux/dmi.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/types.h> | ||
20 | 21 | ||
21 | #include "psmouse.h" | 22 | #include "psmouse.h" |
22 | #include "lifebook.h" | 23 | #include "lifebook.h" |
@@ -136,7 +137,7 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) | |||
136 | struct lifebook_data *priv = psmouse->private; | 137 | struct lifebook_data *priv = psmouse->private; |
137 | struct input_dev *dev1 = psmouse->dev; | 138 | struct input_dev *dev1 = psmouse->dev; |
138 | struct input_dev *dev2 = priv ? priv->dev2 : NULL; | 139 | struct input_dev *dev2 = priv ? priv->dev2 : NULL; |
139 | unsigned char *packet = psmouse->packet; | 140 | u8 *packet = psmouse->packet; |
140 | bool relative_packet = packet[0] & 0x08; | 141 | bool relative_packet = packet[0] & 0x08; |
141 | 142 | ||
142 | if (relative_packet || !lifebook_use_6byte_proto) { | 143 | if (relative_packet || !lifebook_use_6byte_proto) { |
@@ -188,14 +189,10 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) | |||
188 | } | 189 | } |
189 | 190 | ||
190 | if (dev2) { | 191 | if (dev2) { |
191 | if (relative_packet) { | 192 | if (relative_packet) |
192 | input_report_rel(dev2, REL_X, | 193 | psmouse_report_standard_motion(dev2, packet); |
193 | ((packet[0] & 0x10) ? packet[1] - 256 : packet[1])); | 194 | |
194 | input_report_rel(dev2, REL_Y, | 195 | psmouse_report_standard_buttons(dev2, packet[0]); |
195 | -(int)((packet[0] & 0x20) ? packet[2] - 256 : packet[2])); | ||
196 | } | ||
197 | input_report_key(dev2, BTN_LEFT, packet[0] & 0x01); | ||
198 | input_report_key(dev2, BTN_RIGHT, packet[0] & 0x02); | ||
199 | input_sync(dev2); | 196 | input_sync(dev2); |
200 | } | 197 | } |
201 | 198 | ||
@@ -205,10 +202,12 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) | |||
205 | static int lifebook_absolute_mode(struct psmouse *psmouse) | 202 | static int lifebook_absolute_mode(struct psmouse *psmouse) |
206 | { | 203 | { |
207 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 204 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
208 | unsigned char param; | 205 | u8 param; |
206 | int error; | ||
209 | 207 | ||
210 | if (psmouse_reset(psmouse)) | 208 | error = psmouse_reset(psmouse); |
211 | return -1; | 209 | if (error) |
210 | return error; | ||
212 | 211 | ||
213 | /* | 212 | /* |
214 | * Enable absolute output -- ps2_command fails always but if | 213 | * Enable absolute output -- ps2_command fails always but if |
@@ -224,15 +223,15 @@ static int lifebook_absolute_mode(struct psmouse *psmouse) | |||
224 | static void lifebook_relative_mode(struct psmouse *psmouse) | 223 | static void lifebook_relative_mode(struct psmouse *psmouse) |
225 | { | 224 | { |
226 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 225 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
227 | unsigned char param = 0x06; | 226 | u8 param = 0x06; |
228 | 227 | ||
229 | ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); | 228 | ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); |
230 | } | 229 | } |
231 | 230 | ||
232 | static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolution) | 231 | static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolution) |
233 | { | 232 | { |
234 | static const unsigned char params[] = { 0, 1, 2, 2, 3 }; | 233 | static const u8 params[] = { 0, 1, 2, 2, 3 }; |
235 | unsigned char p; | 234 | u8 p; |
236 | 235 | ||
237 | if (resolution == 0 || resolution > 400) | 236 | if (resolution == 0 || resolution > 400) |
238 | resolution = 400; | 237 | resolution = 400; |
@@ -257,11 +256,11 @@ static void lifebook_disconnect(struct psmouse *psmouse) | |||
257 | int lifebook_detect(struct psmouse *psmouse, bool set_properties) | 256 | int lifebook_detect(struct psmouse *psmouse, bool set_properties) |
258 | { | 257 | { |
259 | if (!lifebook_present) | 258 | if (!lifebook_present) |
260 | return -1; | 259 | return -ENXIO; |
261 | 260 | ||
262 | if (desired_serio_phys && | 261 | if (desired_serio_phys && |
263 | strcmp(psmouse->ps2dev.serio->phys, desired_serio_phys)) | 262 | strcmp(psmouse->ps2dev.serio->phys, desired_serio_phys)) |
264 | return -1; | 263 | return -ENXIO; |
265 | 264 | ||
266 | if (set_properties) { | 265 | if (set_properties) { |
267 | psmouse->vendor = "Fujitsu"; | 266 | psmouse->vendor = "Fujitsu"; |
@@ -294,10 +293,10 @@ static int lifebook_create_relative_device(struct psmouse *psmouse) | |||
294 | dev2->id.version = 0x0000; | 293 | dev2->id.version = 0x0000; |
295 | dev2->dev.parent = &psmouse->ps2dev.serio->dev; | 294 | dev2->dev.parent = &psmouse->ps2dev.serio->dev; |
296 | 295 | ||
297 | dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); | 296 | input_set_capability(dev2, EV_REL, REL_X); |
298 | dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); | 297 | input_set_capability(dev2, EV_REL, REL_Y); |
299 | dev2->keybit[BIT_WORD(BTN_LEFT)] = | 298 | input_set_capability(dev2, EV_KEY, BTN_LEFT); |
300 | BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); | 299 | input_set_capability(dev2, EV_KEY, BTN_RIGHT); |
301 | 300 | ||
302 | error = input_register_device(priv->dev2); | 301 | error = input_register_device(priv->dev2); |
303 | if (error) | 302 | if (error) |
@@ -316,21 +315,26 @@ int lifebook_init(struct psmouse *psmouse) | |||
316 | { | 315 | { |
317 | struct input_dev *dev1 = psmouse->dev; | 316 | struct input_dev *dev1 = psmouse->dev; |
318 | int max_coord = lifebook_use_6byte_proto ? 4096 : 1024; | 317 | int max_coord = lifebook_use_6byte_proto ? 4096 : 1024; |
318 | int error; | ||
319 | |||
320 | error = lifebook_absolute_mode(psmouse); | ||
321 | if (error) | ||
322 | return error; | ||
319 | 323 | ||
320 | if (lifebook_absolute_mode(psmouse)) | 324 | /* Clear default capabilities */ |
321 | return -1; | 325 | bitmap_zero(dev1->evbit, EV_CNT); |
326 | bitmap_zero(dev1->relbit, REL_CNT); | ||
327 | bitmap_zero(dev1->keybit, KEY_CNT); | ||
322 | 328 | ||
323 | dev1->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); | 329 | input_set_capability(dev1, EV_KEY, BTN_TOUCH); |
324 | dev1->relbit[0] = 0; | ||
325 | dev1->keybit[BIT_WORD(BTN_MOUSE)] = 0; | ||
326 | dev1->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
327 | input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0); | 330 | input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0); |
328 | input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0); | 331 | input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0); |
329 | 332 | ||
330 | if (!desired_serio_phys) { | 333 | if (!desired_serio_phys) { |
331 | if (lifebook_create_relative_device(psmouse)) { | 334 | error = lifebook_create_relative_device(psmouse); |
335 | if (error) { | ||
332 | lifebook_relative_mode(psmouse); | 336 | lifebook_relative_mode(psmouse); |
333 | return -1; | 337 | return error; |
334 | } | 338 | } |
335 | } | 339 | } |
336 | 340 | ||
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index ef9c97f5e3d7..3d5637e6fa5f 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c | |||
@@ -9,9 +9,11 @@ | |||
9 | * the Free Software Foundation. | 9 | * the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/bitops.h> | ||
12 | #include <linux/input.h> | 13 | #include <linux/input.h> |
13 | #include <linux/serio.h> | 14 | #include <linux/serio.h> |
14 | #include <linux/libps2.h> | 15 | #include <linux/libps2.h> |
16 | #include <linux/types.h> | ||
15 | #include "psmouse.h" | 17 | #include "psmouse.h" |
16 | #include "logips2pp.h" | 18 | #include "logips2pp.h" |
17 | 19 | ||
@@ -22,12 +24,12 @@ | |||
22 | #define PS2PP_KIND_TRACKMAN 4 | 24 | #define PS2PP_KIND_TRACKMAN 4 |
23 | 25 | ||
24 | /* Logitech mouse features */ | 26 | /* Logitech mouse features */ |
25 | #define PS2PP_WHEEL 0x01 | 27 | #define PS2PP_WHEEL BIT(0) |
26 | #define PS2PP_HWHEEL 0x02 | 28 | #define PS2PP_HWHEEL BIT(1) |
27 | #define PS2PP_SIDE_BTN 0x04 | 29 | #define PS2PP_SIDE_BTN BIT(2) |
28 | #define PS2PP_EXTRA_BTN 0x08 | 30 | #define PS2PP_EXTRA_BTN BIT(3) |
29 | #define PS2PP_TASK_BTN 0x10 | 31 | #define PS2PP_TASK_BTN BIT(4) |
30 | #define PS2PP_NAV_BTN 0x20 | 32 | #define PS2PP_NAV_BTN BIT(5) |
31 | 33 | ||
32 | struct ps2pp_info { | 34 | struct ps2pp_info { |
33 | u8 model; | 35 | u8 model; |
@@ -42,7 +44,7 @@ struct ps2pp_info { | |||
42 | static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse) | 44 | static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse) |
43 | { | 45 | { |
44 | struct input_dev *dev = psmouse->dev; | 46 | struct input_dev *dev = psmouse->dev; |
45 | unsigned char *packet = psmouse->packet; | 47 | u8 *packet = psmouse->packet; |
46 | 48 | ||
47 | if (psmouse->pktcnt < 3) | 49 | if (psmouse->pktcnt < 3) |
48 | return PSMOUSE_GOOD_DATA; | 50 | return PSMOUSE_GOOD_DATA; |
@@ -58,28 +60,30 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse) | |||
58 | 60 | ||
59 | case 0x0d: /* Mouse extra info */ | 61 | case 0x0d: /* Mouse extra info */ |
60 | 62 | ||
61 | input_report_rel(dev, packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL, | 63 | input_report_rel(dev, |
62 | (int) (packet[2] & 8) - (int) (packet[2] & 7)); | 64 | packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL, |
63 | input_report_key(dev, BTN_SIDE, (packet[2] >> 4) & 1); | 65 | -sign_extend32(packet[2], 3)); |
64 | input_report_key(dev, BTN_EXTRA, (packet[2] >> 5) & 1); | 66 | input_report_key(dev, BTN_SIDE, packet[2] & BIT(4)); |
67 | input_report_key(dev, BTN_EXTRA, packet[2] & BIT(5)); | ||
65 | 68 | ||
66 | break; | 69 | break; |
67 | 70 | ||
68 | case 0x0e: /* buttons 4, 5, 6, 7, 8, 9, 10 info */ | 71 | case 0x0e: /* buttons 4, 5, 6, 7, 8, 9, 10 info */ |
69 | 72 | ||
70 | input_report_key(dev, BTN_SIDE, (packet[2]) & 1); | 73 | input_report_key(dev, BTN_SIDE, packet[2] & BIT(0)); |
71 | input_report_key(dev, BTN_EXTRA, (packet[2] >> 1) & 1); | 74 | input_report_key(dev, BTN_EXTRA, packet[2] & BIT(1)); |
72 | input_report_key(dev, BTN_BACK, (packet[2] >> 3) & 1); | 75 | input_report_key(dev, BTN_TASK, packet[2] & BIT(2)); |
73 | input_report_key(dev, BTN_FORWARD, (packet[2] >> 4) & 1); | 76 | input_report_key(dev, BTN_BACK, packet[2] & BIT(3)); |
74 | input_report_key(dev, BTN_TASK, (packet[2] >> 2) & 1); | 77 | input_report_key(dev, BTN_FORWARD, packet[2] & BIT(4)); |
75 | 78 | ||
76 | break; | 79 | break; |
77 | 80 | ||
78 | case 0x0f: /* TouchPad extra info */ | 81 | case 0x0f: /* TouchPad extra info */ |
79 | 82 | ||
80 | input_report_rel(dev, packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL, | 83 | input_report_rel(dev, |
81 | (int) ((packet[2] >> 4) & 8) - (int) ((packet[2] >> 4) & 7)); | 84 | packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL, |
82 | packet[0] = packet[2] | 0x08; | 85 | -sign_extend32(packet[2] >> 4, 3)); |
86 | packet[0] = packet[2] | BIT(3); | ||
83 | break; | 87 | break; |
84 | 88 | ||
85 | default: | 89 | default: |
@@ -88,16 +92,14 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse) | |||
88 | (packet[1] >> 4) | (packet[0] & 0x30)); | 92 | (packet[1] >> 4) | (packet[0] & 0x30)); |
89 | break; | 93 | break; |
90 | } | 94 | } |
95 | |||
96 | psmouse_report_standard_buttons(dev, packet[0]); | ||
97 | |||
91 | } else { | 98 | } else { |
92 | /* Standard PS/2 motion data */ | 99 | /* Standard PS/2 motion data */ |
93 | input_report_rel(dev, REL_X, packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0); | 100 | psmouse_report_standard_packet(dev, packet); |
94 | input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0); | ||
95 | } | 101 | } |
96 | 102 | ||
97 | input_report_key(dev, BTN_LEFT, packet[0] & 1); | ||
98 | input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1); | ||
99 | input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1); | ||
100 | |||
101 | input_sync(dev); | 103 | input_sync(dev); |
102 | 104 | ||
103 | return PSMOUSE_FULL_PACKET; | 105 | return PSMOUSE_FULL_PACKET; |
@@ -111,13 +113,17 @@ static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse) | |||
111 | * Ugly. | 113 | * Ugly. |
112 | */ | 114 | */ |
113 | 115 | ||
114 | static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned char command) | 116 | static int ps2pp_cmd(struct psmouse *psmouse, u8 *param, u8 command) |
115 | { | 117 | { |
116 | if (psmouse_sliced_command(psmouse, command)) | 118 | int error; |
117 | return -1; | ||
118 | 119 | ||
119 | if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL | 0x0300)) | 120 | error = ps2_sliced_command(&psmouse->ps2dev, command); |
120 | return -1; | 121 | if (error) |
122 | return error; | ||
123 | |||
124 | error = ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL | 0x0300); | ||
125 | if (error) | ||
126 | return error; | ||
121 | 127 | ||
122 | return 0; | 128 | return 0; |
123 | } | 129 | } |
@@ -133,7 +139,7 @@ static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned cha | |||
133 | static void ps2pp_set_smartscroll(struct psmouse *psmouse, bool smartscroll) | 139 | static void ps2pp_set_smartscroll(struct psmouse *psmouse, bool smartscroll) |
134 | { | 140 | { |
135 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 141 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
136 | unsigned char param[4]; | 142 | u8 param[4]; |
137 | 143 | ||
138 | ps2pp_cmd(psmouse, param, 0x32); | 144 | ps2pp_cmd(psmouse, param, 0x32); |
139 | 145 | ||
@@ -171,7 +177,7 @@ static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, | |||
171 | } | 177 | } |
172 | 178 | ||
173 | PSMOUSE_DEFINE_ATTR(smartscroll, S_IWUSR | S_IRUGO, NULL, | 179 | PSMOUSE_DEFINE_ATTR(smartscroll, S_IWUSR | S_IRUGO, NULL, |
174 | ps2pp_attr_show_smartscroll, ps2pp_attr_set_smartscroll); | 180 | ps2pp_attr_show_smartscroll, ps2pp_attr_set_smartscroll); |
175 | 181 | ||
176 | /* | 182 | /* |
177 | * Support 800 dpi resolution _only_ if the user wants it (there are good | 183 | * Support 800 dpi resolution _only_ if the user wants it (there are good |
@@ -179,11 +185,12 @@ PSMOUSE_DEFINE_ATTR(smartscroll, S_IWUSR | S_IRUGO, NULL, | |||
179 | * also good reasons to use it, let the user decide). | 185 | * also good reasons to use it, let the user decide). |
180 | */ | 186 | */ |
181 | 187 | ||
182 | static void ps2pp_set_resolution(struct psmouse *psmouse, unsigned int resolution) | 188 | static void ps2pp_set_resolution(struct psmouse *psmouse, |
189 | unsigned int resolution) | ||
183 | { | 190 | { |
184 | if (resolution > 400) { | 191 | if (resolution > 400) { |
185 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 192 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
186 | unsigned char param = 3; | 193 | u8 param = 3; |
187 | 194 | ||
188 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); | 195 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); |
189 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); | 196 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); |
@@ -196,7 +203,8 @@ static void ps2pp_set_resolution(struct psmouse *psmouse, unsigned int resolutio | |||
196 | 203 | ||
197 | static void ps2pp_disconnect(struct psmouse *psmouse) | 204 | static void ps2pp_disconnect(struct psmouse *psmouse) |
198 | { | 205 | { |
199 | device_remove_file(&psmouse->ps2dev.serio->dev, &psmouse_attr_smartscroll.dattr); | 206 | device_remove_file(&psmouse->ps2dev.serio->dev, |
207 | &psmouse_attr_smartscroll.dattr); | ||
200 | } | 208 | } |
201 | 209 | ||
202 | static const struct ps2pp_info *get_model_info(unsigned char model) | 210 | static const struct ps2pp_info *get_model_info(unsigned char model) |
@@ -269,24 +277,24 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse, | |||
269 | struct input_dev *input_dev = psmouse->dev; | 277 | struct input_dev *input_dev = psmouse->dev; |
270 | 278 | ||
271 | if (model_info->features & PS2PP_SIDE_BTN) | 279 | if (model_info->features & PS2PP_SIDE_BTN) |
272 | __set_bit(BTN_SIDE, input_dev->keybit); | 280 | input_set_capability(input_dev, EV_KEY, BTN_SIDE); |
273 | 281 | ||
274 | if (model_info->features & PS2PP_EXTRA_BTN) | 282 | if (model_info->features & PS2PP_EXTRA_BTN) |
275 | __set_bit(BTN_EXTRA, input_dev->keybit); | 283 | input_set_capability(input_dev, EV_KEY, BTN_EXTRA); |
276 | 284 | ||
277 | if (model_info->features & PS2PP_TASK_BTN) | 285 | if (model_info->features & PS2PP_TASK_BTN) |
278 | __set_bit(BTN_TASK, input_dev->keybit); | 286 | input_set_capability(input_dev, EV_KEY, BTN_TASK); |
279 | 287 | ||
280 | if (model_info->features & PS2PP_NAV_BTN) { | 288 | if (model_info->features & PS2PP_NAV_BTN) { |
281 | __set_bit(BTN_FORWARD, input_dev->keybit); | 289 | input_set_capability(input_dev, EV_KEY, BTN_FORWARD); |
282 | __set_bit(BTN_BACK, input_dev->keybit); | 290 | input_set_capability(input_dev, EV_KEY, BTN_BACK); |
283 | } | 291 | } |
284 | 292 | ||
285 | if (model_info->features & PS2PP_WHEEL) | 293 | if (model_info->features & PS2PP_WHEEL) |
286 | __set_bit(REL_WHEEL, input_dev->relbit); | 294 | input_set_capability(input_dev, EV_REL, REL_WHEEL); |
287 | 295 | ||
288 | if (model_info->features & PS2PP_HWHEEL) | 296 | if (model_info->features & PS2PP_HWHEEL) |
289 | __set_bit(REL_HWHEEL, input_dev->relbit); | 297 | input_set_capability(input_dev, EV_REL, REL_HWHEEL); |
290 | 298 | ||
291 | switch (model_info->kind) { | 299 | switch (model_info->kind) { |
292 | 300 | ||
@@ -318,6 +326,30 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse, | |||
318 | } | 326 | } |
319 | } | 327 | } |
320 | 328 | ||
329 | static int ps2pp_setup_protocol(struct psmouse *psmouse, | ||
330 | const struct ps2pp_info *model_info) | ||
331 | { | ||
332 | int error; | ||
333 | |||
334 | psmouse->protocol_handler = ps2pp_process_byte; | ||
335 | psmouse->pktsize = 3; | ||
336 | |||
337 | if (model_info->kind != PS2PP_KIND_TP3) { | ||
338 | psmouse->set_resolution = ps2pp_set_resolution; | ||
339 | psmouse->disconnect = ps2pp_disconnect; | ||
340 | |||
341 | error = device_create_file(&psmouse->ps2dev.serio->dev, | ||
342 | &psmouse_attr_smartscroll.dattr); | ||
343 | if (error) { | ||
344 | psmouse_err(psmouse, | ||
345 | "failed to create smartscroll sysfs attribute, error: %d\n", | ||
346 | error); | ||
347 | return error; | ||
348 | } | ||
349 | } | ||
350 | |||
351 | return 0; | ||
352 | } | ||
321 | 353 | ||
322 | /* | 354 | /* |
323 | * Logitech magic init. Detect whether the mouse is a Logitech one | 355 | * Logitech magic init. Detect whether the mouse is a Logitech one |
@@ -328,9 +360,9 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse, | |||
328 | int ps2pp_detect(struct psmouse *psmouse, bool set_properties) | 360 | int ps2pp_detect(struct psmouse *psmouse, bool set_properties) |
329 | { | 361 | { |
330 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 362 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
331 | unsigned char param[4]; | ||
332 | unsigned char model, buttons; | ||
333 | const struct ps2pp_info *model_info; | 363 | const struct ps2pp_info *model_info; |
364 | u8 param[4]; | ||
365 | u8 model, buttons; | ||
334 | bool use_ps2pp = false; | 366 | bool use_ps2pp = false; |
335 | int error; | 367 | int error; |
336 | 368 | ||
@@ -346,7 +378,7 @@ int ps2pp_detect(struct psmouse *psmouse, bool set_properties) | |||
346 | buttons = param[1]; | 378 | buttons = param[1]; |
347 | 379 | ||
348 | if (!model || !buttons) | 380 | if (!model || !buttons) |
349 | return -1; | 381 | return -ENXIO; |
350 | 382 | ||
351 | model_info = get_model_info(model); | 383 | model_info = get_model_info(model); |
352 | if (model_info) { | 384 | if (model_info) { |
@@ -368,7 +400,8 @@ int ps2pp_detect(struct psmouse *psmouse, bool set_properties) | |||
368 | 400 | ||
369 | param[0] = 0; | 401 | param[0] = 0; |
370 | if (!ps2_command(ps2dev, param, 0x13d1) && | 402 | if (!ps2_command(ps2dev, param, 0x13d1) && |
371 | param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) { | 403 | param[0] == 0x06 && param[1] == 0x00 && |
404 | param[2] == 0x14) { | ||
372 | use_ps2pp = true; | 405 | use_ps2pp = true; |
373 | } | 406 | } |
374 | 407 | ||
@@ -387,7 +420,9 @@ int ps2pp_detect(struct psmouse *psmouse, bool set_properties) | |||
387 | } | 420 | } |
388 | 421 | ||
389 | } else { | 422 | } else { |
390 | psmouse_warn(psmouse, "Detected unknown Logitech mouse model %d\n", model); | 423 | psmouse_warn(psmouse, |
424 | "Detected unknown Logitech mouse model %d\n", | ||
425 | model); | ||
391 | } | 426 | } |
392 | 427 | ||
393 | if (set_properties) { | 428 | if (set_properties) { |
@@ -395,31 +430,18 @@ int ps2pp_detect(struct psmouse *psmouse, bool set_properties) | |||
395 | psmouse->model = model; | 430 | psmouse->model = model; |
396 | 431 | ||
397 | if (use_ps2pp) { | 432 | if (use_ps2pp) { |
398 | psmouse->protocol_handler = ps2pp_process_byte; | 433 | error = ps2pp_setup_protocol(psmouse, model_info); |
399 | psmouse->pktsize = 3; | 434 | if (error) |
400 | 435 | return error; | |
401 | if (model_info->kind != PS2PP_KIND_TP3) { | ||
402 | psmouse->set_resolution = ps2pp_set_resolution; | ||
403 | psmouse->disconnect = ps2pp_disconnect; | ||
404 | |||
405 | error = device_create_file(&ps2dev->serio->dev, | ||
406 | &psmouse_attr_smartscroll.dattr); | ||
407 | if (error) { | ||
408 | psmouse_err(psmouse, | ||
409 | "failed to create smartscroll sysfs attribute, error: %d\n", | ||
410 | error); | ||
411 | return -1; | ||
412 | } | ||
413 | } | ||
414 | } | 436 | } |
415 | 437 | ||
416 | if (buttons >= 3) | 438 | if (buttons >= 3) |
417 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | 439 | input_set_capability(psmouse->dev, EV_KEY, BTN_MIDDLE); |
418 | 440 | ||
419 | if (model_info) | 441 | if (model_info) |
420 | ps2pp_set_model_properties(psmouse, model_info, use_ps2pp); | 442 | ps2pp_set_model_properties(psmouse, model_info, use_ps2pp); |
421 | } | 443 | } |
422 | 444 | ||
423 | return use_ps2pp ? 0 : -1; | 445 | return use_ps2pp ? 0 : -ENXIO; |
424 | } | 446 | } |
425 | 447 | ||
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 8ac9e03c05b4..8900c3166ebf 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
15 | #define psmouse_fmt(fmt) fmt | 15 | #define psmouse_fmt(fmt) fmt |
16 | 16 | ||
17 | #include <linux/bitops.h> | ||
17 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
19 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
@@ -23,6 +24,7 @@ | |||
23 | #include <linux/init.h> | 24 | #include <linux/init.h> |
24 | #include <linux/libps2.h> | 25 | #include <linux/libps2.h> |
25 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
27 | #include <linux/types.h> | ||
26 | 28 | ||
27 | #include "psmouse.h" | 29 | #include "psmouse.h" |
28 | #include "synaptics.h" | 30 | #include "synaptics.h" |
@@ -68,6 +70,10 @@ static bool psmouse_smartscroll = true; | |||
68 | module_param_named(smartscroll, psmouse_smartscroll, bool, 0644); | 70 | module_param_named(smartscroll, psmouse_smartscroll, bool, 0644); |
69 | MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled."); | 71 | MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled."); |
70 | 72 | ||
73 | static bool psmouse_a4tech_2wheels; | ||
74 | module_param_named(a4tech_workaround, psmouse_a4tech_2wheels, bool, 0644); | ||
75 | MODULE_PARM_DESC(a4tech_workaround, "A4Tech second scroll wheel workaround, 1 = enabled, 0 = disabled (default)."); | ||
76 | |||
71 | static unsigned int psmouse_resetafter = 5; | 77 | static unsigned int psmouse_resetafter = 5; |
72 | module_param_named(resetafter, psmouse_resetafter, uint, 0644); | 78 | module_param_named(resetafter, psmouse_resetafter, uint, 0644); |
73 | MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never)."); | 79 | MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never)."); |
@@ -116,13 +122,30 @@ static DEFINE_MUTEX(psmouse_mutex); | |||
116 | 122 | ||
117 | static struct workqueue_struct *kpsmoused_wq; | 123 | static struct workqueue_struct *kpsmoused_wq; |
118 | 124 | ||
119 | static void psmouse_report_standard_buttons(struct input_dev *dev, u8 buttons) | 125 | void psmouse_report_standard_buttons(struct input_dev *dev, u8 buttons) |
120 | { | 126 | { |
121 | input_report_key(dev, BTN_LEFT, buttons & BIT(0)); | 127 | input_report_key(dev, BTN_LEFT, buttons & BIT(0)); |
122 | input_report_key(dev, BTN_MIDDLE, buttons & BIT(2)); | 128 | input_report_key(dev, BTN_MIDDLE, buttons & BIT(2)); |
123 | input_report_key(dev, BTN_RIGHT, buttons & BIT(1)); | 129 | input_report_key(dev, BTN_RIGHT, buttons & BIT(1)); |
124 | } | 130 | } |
125 | 131 | ||
132 | void psmouse_report_standard_motion(struct input_dev *dev, u8 *packet) | ||
133 | { | ||
134 | int x, y; | ||
135 | |||
136 | x = packet[1] ? packet[1] - ((packet[0] << 4) & 0x100) : 0; | ||
137 | y = packet[2] ? packet[2] - ((packet[0] << 3) & 0x100) : 0; | ||
138 | |||
139 | input_report_rel(dev, REL_X, x); | ||
140 | input_report_rel(dev, REL_Y, -y); | ||
141 | } | ||
142 | |||
143 | void psmouse_report_standard_packet(struct input_dev *dev, u8 *packet) | ||
144 | { | ||
145 | psmouse_report_standard_buttons(dev, packet[0]); | ||
146 | psmouse_report_standard_motion(dev, packet); | ||
147 | } | ||
148 | |||
126 | /* | 149 | /* |
127 | * psmouse_process_byte() analyzes the PS/2 data stream and reports | 150 | * psmouse_process_byte() analyzes the PS/2 data stream and reports |
128 | * relevant events to the input module once full packet has arrived. | 151 | * relevant events to the input module once full packet has arrived. |
@@ -130,7 +153,8 @@ static void psmouse_report_standard_buttons(struct input_dev *dev, u8 buttons) | |||
130 | psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) | 153 | psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) |
131 | { | 154 | { |
132 | struct input_dev *dev = psmouse->dev; | 155 | struct input_dev *dev = psmouse->dev; |
133 | unsigned char *packet = psmouse->packet; | 156 | u8 *packet = psmouse->packet; |
157 | int wheel; | ||
134 | 158 | ||
135 | if (psmouse->pktcnt < psmouse->pktsize) | 159 | if (psmouse->pktcnt < psmouse->pktsize) |
136 | return PSMOUSE_GOOD_DATA; | 160 | return PSMOUSE_GOOD_DATA; |
@@ -140,39 +164,52 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) | |||
140 | switch (psmouse->protocol->type) { | 164 | switch (psmouse->protocol->type) { |
141 | case PSMOUSE_IMPS: | 165 | case PSMOUSE_IMPS: |
142 | /* IntelliMouse has scroll wheel */ | 166 | /* IntelliMouse has scroll wheel */ |
143 | input_report_rel(dev, REL_WHEEL, -(signed char) packet[3]); | 167 | input_report_rel(dev, REL_WHEEL, -(s8) packet[3]); |
144 | break; | 168 | break; |
145 | 169 | ||
146 | case PSMOUSE_IMEX: | 170 | case PSMOUSE_IMEX: |
147 | /* Scroll wheel and buttons on IntelliMouse Explorer */ | 171 | /* Scroll wheel and buttons on IntelliMouse Explorer */ |
148 | switch (packet[3] & 0xC0) { | 172 | switch (packet[3] & 0xC0) { |
149 | case 0x80: /* vertical scroll on IntelliMouse Explorer 4.0 */ | 173 | case 0x80: /* vertical scroll on IntelliMouse Explorer 4.0 */ |
150 | input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); | 174 | input_report_rel(dev, REL_WHEEL, |
175 | -sign_extend32(packet[3], 5)); | ||
151 | break; | 176 | break; |
152 | case 0x40: /* horizontal scroll on IntelliMouse Explorer 4.0 */ | 177 | case 0x40: /* horizontal scroll on IntelliMouse Explorer 4.0 */ |
153 | input_report_rel(dev, REL_HWHEEL, (int) (packet[3] & 32) - (int) (packet[3] & 31)); | 178 | input_report_rel(dev, REL_HWHEEL, |
179 | -sign_extend32(packet[3], 5)); | ||
154 | break; | 180 | break; |
155 | case 0x00: | 181 | case 0x00: |
156 | case 0xC0: | 182 | case 0xC0: |
157 | input_report_rel(dev, REL_WHEEL, (int) (packet[3] & 8) - (int) (packet[3] & 7)); | 183 | wheel = sign_extend32(packet[3], 3); |
158 | input_report_key(dev, BTN_SIDE, (packet[3] >> 4) & 1); | 184 | |
159 | input_report_key(dev, BTN_EXTRA, (packet[3] >> 5) & 1); | 185 | /* |
186 | * Some A4Tech mice have two scroll wheels, with first | ||
187 | * one reporting +/-1 in the lower nibble, and second | ||
188 | * one reporting +/-2. | ||
189 | */ | ||
190 | if (psmouse_a4tech_2wheels && abs(wheel) > 1) | ||
191 | input_report_rel(dev, REL_HWHEEL, wheel / 2); | ||
192 | else | ||
193 | input_report_rel(dev, REL_WHEEL, -wheel); | ||
194 | |||
195 | input_report_key(dev, BTN_SIDE, BIT(4)); | ||
196 | input_report_key(dev, BTN_EXTRA, BIT(5)); | ||
160 | break; | 197 | break; |
161 | } | 198 | } |
162 | break; | 199 | break; |
163 | 200 | ||
164 | case PSMOUSE_GENPS: | 201 | case PSMOUSE_GENPS: |
165 | /* Report scroll buttons on NetMice */ | 202 | /* Report scroll buttons on NetMice */ |
166 | input_report_rel(dev, REL_WHEEL, -(signed char) packet[3]); | 203 | input_report_rel(dev, REL_WHEEL, -(s8) packet[3]); |
167 | 204 | ||
168 | /* Extra buttons on Genius NewNet 3D */ | 205 | /* Extra buttons on Genius NewNet 3D */ |
169 | input_report_key(dev, BTN_SIDE, (packet[0] >> 6) & 1); | 206 | input_report_key(dev, BTN_SIDE, BIT(6)); |
170 | input_report_key(dev, BTN_EXTRA, (packet[0] >> 7) & 1); | 207 | input_report_key(dev, BTN_EXTRA, BIT(7)); |
171 | break; | 208 | break; |
172 | 209 | ||
173 | case PSMOUSE_THINKPS: | 210 | case PSMOUSE_THINKPS: |
174 | /* Extra button on ThinkingMouse */ | 211 | /* Extra button on ThinkingMouse */ |
175 | input_report_key(dev, BTN_EXTRA, (packet[0] >> 3) & 1); | 212 | input_report_key(dev, BTN_EXTRA, BIT(3)); |
176 | 213 | ||
177 | /* | 214 | /* |
178 | * Without this bit of weirdness moving up gives wildly | 215 | * Without this bit of weirdness moving up gives wildly |
@@ -186,8 +223,8 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) | |||
186 | * Cortron PS2 Trackball reports SIDE button in the | 223 | * Cortron PS2 Trackball reports SIDE button in the |
187 | * 4th bit of the first byte. | 224 | * 4th bit of the first byte. |
188 | */ | 225 | */ |
189 | input_report_key(dev, BTN_SIDE, (packet[0] >> 3) & 1); | 226 | input_report_key(dev, BTN_SIDE, BIT(3)); |
190 | packet[0] |= 0x08; | 227 | packet[0] |= BIT(3); |
191 | break; | 228 | break; |
192 | 229 | ||
193 | default: | 230 | default: |
@@ -195,11 +232,8 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse) | |||
195 | } | 232 | } |
196 | 233 | ||
197 | /* Generic PS/2 Mouse */ | 234 | /* Generic PS/2 Mouse */ |
198 | psmouse_report_standard_buttons(dev, | 235 | packet[0] |= psmouse->extra_buttons; |
199 | packet[0] | psmouse->extra_buttons); | 236 | psmouse_report_standard_packet(dev, packet); |
200 | |||
201 | input_report_rel(dev, REL_X, packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0); | ||
202 | input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0); | ||
203 | 237 | ||
204 | input_sync(dev); | 238 | input_sync(dev); |
205 | 239 | ||
@@ -255,7 +289,7 @@ static int psmouse_handle_byte(struct psmouse *psmouse) | |||
255 | psmouse_notice(psmouse, | 289 | psmouse_notice(psmouse, |
256 | "issuing reconnect request\n"); | 290 | "issuing reconnect request\n"); |
257 | serio_reconnect(psmouse->ps2dev.serio); | 291 | serio_reconnect(psmouse->ps2dev.serio); |
258 | return -1; | 292 | return -EIO; |
259 | } | 293 | } |
260 | } | 294 | } |
261 | psmouse->pktcnt = 0; | 295 | psmouse->pktcnt = 0; |
@@ -306,7 +340,7 @@ static void psmouse_handle_oob_data(struct psmouse *psmouse, u8 data) | |||
306 | * for normal processing or gathering them as command response. | 340 | * for normal processing or gathering them as command response. |
307 | */ | 341 | */ |
308 | static irqreturn_t psmouse_interrupt(struct serio *serio, | 342 | static irqreturn_t psmouse_interrupt(struct serio *serio, |
309 | unsigned char data, unsigned int flags) | 343 | u8 data, unsigned int flags) |
310 | { | 344 | { |
311 | struct psmouse *psmouse = serio_get_drvdata(serio); | 345 | struct psmouse *psmouse = serio_get_drvdata(serio); |
312 | 346 | ||
@@ -398,40 +432,19 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, | |||
398 | } | 432 | } |
399 | 433 | ||
400 | /* | 434 | /* |
401 | * psmouse_sliced_command() sends an extended PS/2 command to the mouse | ||
402 | * using sliced syntax, understood by advanced devices, such as Logitech | ||
403 | * or Synaptics touchpads. The command is encoded as: | ||
404 | * 0xE6 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu | ||
405 | * is the command. | ||
406 | */ | ||
407 | int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command) | ||
408 | { | ||
409 | int i; | ||
410 | |||
411 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11)) | ||
412 | return -1; | ||
413 | |||
414 | for (i = 6; i >= 0; i -= 2) { | ||
415 | unsigned char d = (command >> i) & 3; | ||
416 | if (ps2_command(&psmouse->ps2dev, &d, PSMOUSE_CMD_SETRES)) | ||
417 | return -1; | ||
418 | } | ||
419 | |||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | /* | ||
424 | * psmouse_reset() resets the mouse into power-on state. | 435 | * psmouse_reset() resets the mouse into power-on state. |
425 | */ | 436 | */ |
426 | int psmouse_reset(struct psmouse *psmouse) | 437 | int psmouse_reset(struct psmouse *psmouse) |
427 | { | 438 | { |
428 | unsigned char param[2]; | 439 | u8 param[2]; |
440 | int error; | ||
429 | 441 | ||
430 | if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_RESET_BAT)) | 442 | error = ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_RESET_BAT); |
431 | return -1; | 443 | if (error) |
444 | return error; | ||
432 | 445 | ||
433 | if (param[0] != PSMOUSE_RET_BAT && param[1] != PSMOUSE_RET_ID) | 446 | if (param[0] != PSMOUSE_RET_BAT && param[1] != PSMOUSE_RET_ID) |
434 | return -1; | 447 | return -EIO; |
435 | 448 | ||
436 | return 0; | 449 | return 0; |
437 | } | 450 | } |
@@ -441,8 +454,8 @@ int psmouse_reset(struct psmouse *psmouse) | |||
441 | */ | 454 | */ |
442 | void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution) | 455 | void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution) |
443 | { | 456 | { |
444 | static const unsigned char params[] = { 0, 1, 2, 2, 3 }; | 457 | static const u8 params[] = { 0, 1, 2, 2, 3 }; |
445 | unsigned char p; | 458 | u8 p; |
446 | 459 | ||
447 | if (resolution == 0 || resolution > 200) | 460 | if (resolution == 0 || resolution > 200) |
448 | resolution = 200; | 461 | resolution = 200; |
@@ -457,11 +470,12 @@ void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution) | |||
457 | */ | 470 | */ |
458 | static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate) | 471 | static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate) |
459 | { | 472 | { |
460 | static const unsigned char rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 }; | 473 | static const u8 rates[] = { 200, 100, 80, 60, 40, 20, 10, 0 }; |
461 | unsigned char r; | 474 | u8 r; |
462 | int i = 0; | 475 | int i = 0; |
463 | 476 | ||
464 | while (rates[i] > rate) i++; | 477 | while (rates[i] > rate) |
478 | i++; | ||
465 | r = rates[i]; | 479 | r = rates[i]; |
466 | ps2_command(&psmouse->ps2dev, &r, PSMOUSE_CMD_SETRATE); | 480 | ps2_command(&psmouse->ps2dev, &r, PSMOUSE_CMD_SETRATE); |
467 | psmouse->rate = r; | 481 | psmouse->rate = r; |
@@ -533,7 +547,7 @@ bool psmouse_matches_pnp_id(struct psmouse *psmouse, const char * const ids[]) | |||
533 | static int genius_detect(struct psmouse *psmouse, bool set_properties) | 547 | static int genius_detect(struct psmouse *psmouse, bool set_properties) |
534 | { | 548 | { |
535 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 549 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
536 | unsigned char param[4]; | 550 | u8 param[4]; |
537 | 551 | ||
538 | param[0] = 3; | 552 | param[0] = 3; |
539 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); | 553 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); |
@@ -543,7 +557,7 @@ static int genius_detect(struct psmouse *psmouse, bool set_properties) | |||
543 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); | 557 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); |
544 | 558 | ||
545 | if (param[0] != 0x00 || param[1] != 0x33 || param[2] != 0x55) | 559 | if (param[0] != 0x00 || param[1] != 0x33 || param[2] != 0x55) |
546 | return -1; | 560 | return -ENODEV; |
547 | 561 | ||
548 | if (set_properties) { | 562 | if (set_properties) { |
549 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | 563 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); |
@@ -565,7 +579,7 @@ static int genius_detect(struct psmouse *psmouse, bool set_properties) | |||
565 | static int intellimouse_detect(struct psmouse *psmouse, bool set_properties) | 579 | static int intellimouse_detect(struct psmouse *psmouse, bool set_properties) |
566 | { | 580 | { |
567 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 581 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
568 | unsigned char param[2]; | 582 | u8 param[2]; |
569 | 583 | ||
570 | param[0] = 200; | 584 | param[0] = 200; |
571 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); | 585 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE); |
@@ -576,7 +590,7 @@ static int intellimouse_detect(struct psmouse *psmouse, bool set_properties) | |||
576 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); | 590 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); |
577 | 591 | ||
578 | if (param[0] != 3) | 592 | if (param[0] != 3) |
579 | return -1; | 593 | return -ENODEV; |
580 | 594 | ||
581 | if (set_properties) { | 595 | if (set_properties) { |
582 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | 596 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); |
@@ -598,7 +612,7 @@ static int intellimouse_detect(struct psmouse *psmouse, bool set_properties) | |||
598 | static int im_explorer_detect(struct psmouse *psmouse, bool set_properties) | 612 | static int im_explorer_detect(struct psmouse *psmouse, bool set_properties) |
599 | { | 613 | { |
600 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 614 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
601 | unsigned char param[2]; | 615 | u8 param[2]; |
602 | 616 | ||
603 | intellimouse_detect(psmouse, 0); | 617 | intellimouse_detect(psmouse, 0); |
604 | 618 | ||
@@ -611,7 +625,7 @@ static int im_explorer_detect(struct psmouse *psmouse, bool set_properties) | |||
611 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); | 625 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); |
612 | 626 | ||
613 | if (param[0] != 4) | 627 | if (param[0] != 4) |
614 | return -1; | 628 | return -ENODEV; |
615 | 629 | ||
616 | /* Magic to enable horizontal scrolling on IntelliMouse 4.0 */ | 630 | /* Magic to enable horizontal scrolling on IntelliMouse 4.0 */ |
617 | param[0] = 200; | 631 | param[0] = 200; |
@@ -644,8 +658,8 @@ static int im_explorer_detect(struct psmouse *psmouse, bool set_properties) | |||
644 | static int thinking_detect(struct psmouse *psmouse, bool set_properties) | 658 | static int thinking_detect(struct psmouse *psmouse, bool set_properties) |
645 | { | 659 | { |
646 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 660 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
647 | unsigned char param[2]; | 661 | u8 param[2]; |
648 | static const unsigned char seq[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20 }; | 662 | static const u8 seq[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20 }; |
649 | int i; | 663 | int i; |
650 | 664 | ||
651 | param[0] = 10; | 665 | param[0] = 10; |
@@ -659,7 +673,7 @@ static int thinking_detect(struct psmouse *psmouse, bool set_properties) | |||
659 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); | 673 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); |
660 | 674 | ||
661 | if (param[0] != 2) | 675 | if (param[0] != 2) |
662 | return -1; | 676 | return -ENODEV; |
663 | 677 | ||
664 | if (set_properties) { | 678 | if (set_properties) { |
665 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | 679 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); |
@@ -687,7 +701,7 @@ static int ps2bare_detect(struct psmouse *psmouse, bool set_properties) | |||
687 | * We have no way of figuring true number of buttons so let's | 701 | * We have no way of figuring true number of buttons so let's |
688 | * assume that the device has 3. | 702 | * assume that the device has 3. |
689 | */ | 703 | */ |
690 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | 704 | input_set_capability(psmouse->dev, EV_KEY, BTN_MIDDLE); |
691 | } | 705 | } |
692 | 706 | ||
693 | return 0; | 707 | return 0; |
@@ -942,20 +956,17 @@ static void psmouse_apply_defaults(struct psmouse *psmouse) | |||
942 | { | 956 | { |
943 | struct input_dev *input_dev = psmouse->dev; | 957 | struct input_dev *input_dev = psmouse->dev; |
944 | 958 | ||
945 | memset(input_dev->evbit, 0, sizeof(input_dev->evbit)); | 959 | bitmap_zero(input_dev->evbit, EV_CNT); |
946 | memset(input_dev->keybit, 0, sizeof(input_dev->keybit)); | 960 | bitmap_zero(input_dev->keybit, KEY_CNT); |
947 | memset(input_dev->relbit, 0, sizeof(input_dev->relbit)); | 961 | bitmap_zero(input_dev->relbit, REL_CNT); |
948 | memset(input_dev->absbit, 0, sizeof(input_dev->absbit)); | 962 | bitmap_zero(input_dev->absbit, ABS_CNT); |
949 | memset(input_dev->mscbit, 0, sizeof(input_dev->mscbit)); | 963 | bitmap_zero(input_dev->mscbit, MSC_CNT); |
950 | |||
951 | __set_bit(EV_KEY, input_dev->evbit); | ||
952 | __set_bit(EV_REL, input_dev->evbit); | ||
953 | 964 | ||
954 | __set_bit(BTN_LEFT, input_dev->keybit); | 965 | input_set_capability(input_dev, EV_KEY, BTN_LEFT); |
955 | __set_bit(BTN_RIGHT, input_dev->keybit); | 966 | input_set_capability(input_dev, EV_KEY, BTN_RIGHT); |
956 | 967 | ||
957 | __set_bit(REL_X, input_dev->relbit); | 968 | input_set_capability(input_dev, EV_REL, REL_X); |
958 | __set_bit(REL_Y, input_dev->relbit); | 969 | input_set_capability(input_dev, EV_REL, REL_Y); |
959 | 970 | ||
960 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); | 971 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); |
961 | 972 | ||
@@ -1225,7 +1236,8 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
1225 | static int psmouse_probe(struct psmouse *psmouse) | 1236 | static int psmouse_probe(struct psmouse *psmouse) |
1226 | { | 1237 | { |
1227 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 1238 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
1228 | unsigned char param[2]; | 1239 | u8 param[2]; |
1240 | int error; | ||
1229 | 1241 | ||
1230 | /* | 1242 | /* |
1231 | * First, we check if it's a mouse. It should send 0x00 or 0x03 in | 1243 | * First, we check if it's a mouse. It should send 0x00 or 0x03 in |
@@ -1234,20 +1246,22 @@ static int psmouse_probe(struct psmouse *psmouse) | |||
1234 | * subsequent ID queries, probably due to a firmware bug. | 1246 | * subsequent ID queries, probably due to a firmware bug. |
1235 | */ | 1247 | */ |
1236 | param[0] = 0xa5; | 1248 | param[0] = 0xa5; |
1237 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETID)) | 1249 | error = ps2_command(ps2dev, param, PSMOUSE_CMD_GETID); |
1238 | return -1; | 1250 | if (error) |
1251 | return error; | ||
1239 | 1252 | ||
1240 | if (param[0] != 0x00 && param[0] != 0x03 && | 1253 | if (param[0] != 0x00 && param[0] != 0x03 && |
1241 | param[0] != 0x04 && param[0] != 0xff) | 1254 | param[0] != 0x04 && param[0] != 0xff) |
1242 | return -1; | 1255 | return -ENODEV; |
1243 | 1256 | ||
1244 | /* | 1257 | /* |
1245 | * Then we reset and disable the mouse so that it doesn't generate | 1258 | * Then we reset and disable the mouse so that it doesn't generate |
1246 | * events. | 1259 | * events. |
1247 | */ | 1260 | */ |
1248 | if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS)) | 1261 | error = ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); |
1249 | psmouse_warn(psmouse, "Failed to reset mouse on %s\n", | 1262 | if (error) |
1250 | ps2dev->serio->phys); | 1263 | psmouse_warn(psmouse, "Failed to reset mouse on %s: %d\n", |
1264 | ps2dev->serio->phys, error); | ||
1251 | 1265 | ||
1252 | return 0; | 1266 | return 0; |
1253 | } | 1267 | } |
@@ -1288,10 +1302,13 @@ int psmouse_activate(struct psmouse *psmouse) | |||
1288 | */ | 1302 | */ |
1289 | int psmouse_deactivate(struct psmouse *psmouse) | 1303 | int psmouse_deactivate(struct psmouse *psmouse) |
1290 | { | 1304 | { |
1291 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) { | 1305 | int error; |
1292 | psmouse_warn(psmouse, "Failed to deactivate mouse on %s\n", | 1306 | |
1293 | psmouse->ps2dev.serio->phys); | 1307 | error = ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE); |
1294 | return -1; | 1308 | if (error) { |
1309 | psmouse_warn(psmouse, "Failed to deactivate mouse on %s: %d\n", | ||
1310 | psmouse->ps2dev.serio->phys, error); | ||
1311 | return error; | ||
1295 | } | 1312 | } |
1296 | 1313 | ||
1297 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | 1314 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); |
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index 8cd453808cc7..71ac50082c8b 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h | |||
@@ -131,7 +131,6 @@ struct psmouse { | |||
131 | 131 | ||
132 | void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work, | 132 | void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work, |
133 | unsigned long delay); | 133 | unsigned long delay); |
134 | int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command); | ||
135 | int psmouse_reset(struct psmouse *psmouse); | 134 | int psmouse_reset(struct psmouse *psmouse); |
136 | void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state); | 135 | void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state); |
137 | void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution); | 136 | void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution); |
@@ -140,6 +139,10 @@ int psmouse_activate(struct psmouse *psmouse); | |||
140 | int psmouse_deactivate(struct psmouse *psmouse); | 139 | int psmouse_deactivate(struct psmouse *psmouse); |
141 | bool psmouse_matches_pnp_id(struct psmouse *psmouse, const char * const ids[]); | 140 | bool psmouse_matches_pnp_id(struct psmouse *psmouse, const char * const ids[]); |
142 | 141 | ||
142 | void psmouse_report_standard_buttons(struct input_dev *, u8 buttons); | ||
143 | void psmouse_report_standard_motion(struct input_dev *, u8 *packet); | ||
144 | void psmouse_report_standard_packet(struct input_dev *, u8 *packet); | ||
145 | |||
143 | struct psmouse_attribute { | 146 | struct psmouse_attribute { |
144 | struct device_attribute dattr; | 147 | struct device_attribute dattr; |
145 | void *data; | 148 | void *data; |
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index 11c32ac8234b..1d6010d463e2 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c | |||
@@ -710,7 +710,6 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) | |||
710 | unsigned char *packet = psmouse->packet; | 710 | unsigned char *packet = psmouse->packet; |
711 | unsigned char button_status = 0, lscroll = 0, rscroll = 0; | 711 | unsigned char button_status = 0, lscroll = 0, rscroll = 0; |
712 | unsigned short abs_x, abs_y, fgrs = 0; | 712 | unsigned short abs_x, abs_y, fgrs = 0; |
713 | int rel_x, rel_y; | ||
714 | 713 | ||
715 | if (psmouse->pktcnt < 4) | 714 | if (psmouse->pktcnt < 4) |
716 | return PSMOUSE_GOOD_DATA; | 715 | return PSMOUSE_GOOD_DATA; |
@@ -840,15 +839,7 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) | |||
840 | /* | 839 | /* |
841 | * Standard PS/2 Mouse | 840 | * Standard PS/2 Mouse |
842 | */ | 841 | */ |
843 | input_report_key(dev, BTN_LEFT, packet[0] & 1); | 842 | psmouse_report_standard_packet(dev, packet); |
844 | input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1); | ||
845 | input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1); | ||
846 | |||
847 | rel_x = packet[1] ? (int)packet[1] - (int)((packet[0] << 4) & 0x100) : 0; | ||
848 | rel_y = packet[2] ? (int)((packet[0] << 3) & 0x100) - (int)packet[2] : 0; | ||
849 | |||
850 | input_report_rel(dev, REL_X, rel_x); | ||
851 | input_report_rel(dev, REL_Y, rel_y); | ||
852 | break; | 843 | break; |
853 | } | 844 | } |
854 | 845 | ||
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index dcb8e0cfaa1a..0d7c781674ca 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -84,7 +84,7 @@ static int synaptics_mode_cmd(struct psmouse *psmouse, u8 mode) | |||
84 | u8 param[1]; | 84 | u8 param[1]; |
85 | int error; | 85 | int error; |
86 | 86 | ||
87 | error = psmouse_sliced_command(psmouse, mode); | 87 | error = ps2_sliced_command(&psmouse->ps2dev, mode); |
88 | if (error) | 88 | if (error) |
89 | return error; | 89 | return error; |
90 | 90 | ||
@@ -190,7 +190,7 @@ static int synaptics_send_cmd(struct psmouse *psmouse, u8 cmd, u8 *param) | |||
190 | { | 190 | { |
191 | int error; | 191 | int error; |
192 | 192 | ||
193 | error = psmouse_sliced_command(psmouse, cmd); | 193 | error = ps2_sliced_command(&psmouse->ps2dev, cmd); |
194 | if (error) | 194 | if (error) |
195 | return error; | 195 | return error; |
196 | 196 | ||
@@ -547,7 +547,7 @@ static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse) | |||
547 | static u8 param = 0xc8; | 547 | static u8 param = 0xc8; |
548 | int error; | 548 | int error; |
549 | 549 | ||
550 | error = psmouse_sliced_command(psmouse, SYN_QUE_MODEL); | 550 | error = ps2_sliced_command(&psmouse->ps2dev, SYN_QUE_MODEL); |
551 | if (error) | 551 | if (error) |
552 | return error; | 552 | return error; |
553 | 553 | ||
@@ -614,7 +614,7 @@ static int synaptics_pt_write(struct serio *serio, u8 c) | |||
614 | u8 rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */ | 614 | u8 rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */ |
615 | int error; | 615 | int error; |
616 | 616 | ||
617 | error = psmouse_sliced_command(parent, c); | 617 | error = ps2_sliced_command(&parent->ps2dev, c); |
618 | if (error) | 618 | if (error) |
619 | return error; | 619 | return error; |
620 | 620 | ||
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index bbd29220dbe9..6590d10f166f 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c | |||
@@ -33,18 +33,15 @@ static const char * const trackpoint_variants[] = { | |||
33 | */ | 33 | */ |
34 | static int trackpoint_power_on_reset(struct ps2dev *ps2dev) | 34 | static int trackpoint_power_on_reset(struct ps2dev *ps2dev) |
35 | { | 35 | { |
36 | u8 results[2]; | 36 | u8 param[2] = { TP_POR }; |
37 | int tries = 0; | 37 | int err; |
38 | 38 | ||
39 | /* Issue POR command, and repeat up to once if 0xFC00 received */ | 39 | err = ps2_command(ps2dev, param, MAKE_PS2_CMD(1, 2, TP_COMMAND)); |
40 | do { | 40 | if (err) |
41 | if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) || | 41 | return err; |
42 | ps2_command(ps2dev, results, MAKE_PS2_CMD(0, 2, TP_POR))) | ||
43 | return -1; | ||
44 | } while (results[0] == 0xFC && results[1] == 0x00 && ++tries < 2); | ||
45 | 42 | ||
46 | /* Check for success response -- 0xAA00 */ | 43 | /* Check for success response -- 0xAA00 */ |
47 | if (results[0] != 0xAA || results[1] != 0x00) | 44 | if (param[0] != 0xAA || param[1] != 0x00) |
48 | return -ENODEV; | 45 | return -ENODEV; |
49 | 46 | ||
50 | return 0; | 47 | return 0; |
@@ -55,49 +52,39 @@ static int trackpoint_power_on_reset(struct ps2dev *ps2dev) | |||
55 | */ | 52 | */ |
56 | static int trackpoint_read(struct ps2dev *ps2dev, u8 loc, u8 *results) | 53 | static int trackpoint_read(struct ps2dev *ps2dev, u8 loc, u8 *results) |
57 | { | 54 | { |
58 | if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) || | 55 | results[0] = loc; |
59 | ps2_command(ps2dev, results, MAKE_PS2_CMD(0, 1, loc))) { | ||
60 | return -1; | ||
61 | } | ||
62 | 56 | ||
63 | return 0; | 57 | return ps2_command(ps2dev, results, MAKE_PS2_CMD(1, 1, TP_COMMAND)); |
64 | } | 58 | } |
65 | 59 | ||
66 | static int trackpoint_write(struct ps2dev *ps2dev, u8 loc, u8 val) | 60 | static int trackpoint_write(struct ps2dev *ps2dev, u8 loc, u8 val) |
67 | { | 61 | { |
68 | if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) || | 62 | u8 param[3] = { TP_WRITE_MEM, loc, val }; |
69 | ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_WRITE_MEM)) || | ||
70 | ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, loc)) || | ||
71 | ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, val))) { | ||
72 | return -1; | ||
73 | } | ||
74 | 63 | ||
75 | return 0; | 64 | return ps2_command(ps2dev, param, MAKE_PS2_CMD(3, 0, TP_COMMAND)); |
76 | } | 65 | } |
77 | 66 | ||
78 | static int trackpoint_toggle_bit(struct ps2dev *ps2dev, u8 loc, u8 mask) | 67 | static int trackpoint_toggle_bit(struct ps2dev *ps2dev, u8 loc, u8 mask) |
79 | { | 68 | { |
69 | u8 param[3] = { TP_TOGGLE, loc, mask }; | ||
70 | |||
80 | /* Bad things will happen if the loc param isn't in this range */ | 71 | /* Bad things will happen if the loc param isn't in this range */ |
81 | if (loc < 0x20 || loc >= 0x2F) | 72 | if (loc < 0x20 || loc >= 0x2F) |
82 | return -1; | 73 | return -EINVAL; |
83 | |||
84 | if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) || | ||
85 | ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_TOGGLE)) || | ||
86 | ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, loc)) || | ||
87 | ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, mask))) { | ||
88 | return -1; | ||
89 | } | ||
90 | 74 | ||
91 | return 0; | 75 | return ps2_command(ps2dev, param, MAKE_PS2_CMD(3, 0, TP_COMMAND)); |
92 | } | 76 | } |
93 | 77 | ||
94 | static int trackpoint_update_bit(struct ps2dev *ps2dev, | 78 | static int trackpoint_update_bit(struct ps2dev *ps2dev, |
95 | u8 loc, u8 mask, u8 value) | 79 | u8 loc, u8 mask, u8 value) |
96 | { | 80 | { |
97 | int retval = 0; | 81 | int retval; |
98 | u8 data; | 82 | u8 data; |
99 | 83 | ||
100 | trackpoint_read(ps2dev, loc, &data); | 84 | retval = trackpoint_read(ps2dev, loc, &data); |
85 | if (retval) | ||
86 | return retval; | ||
87 | |||
101 | if (((data & mask) == mask) != !!value) | 88 | if (((data & mask) == mask) != !!value) |
102 | retval = trackpoint_toggle_bit(ps2dev, loc, mask); | 89 | retval = trackpoint_toggle_bit(ps2dev, loc, mask); |
103 | 90 | ||
@@ -142,9 +129,9 @@ static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data, | |||
142 | return err; | 129 | return err; |
143 | 130 | ||
144 | *field = value; | 131 | *field = value; |
145 | trackpoint_write(&psmouse->ps2dev, attr->command, value); | 132 | err = trackpoint_write(&psmouse->ps2dev, attr->command, value); |
146 | 133 | ||
147 | return count; | 134 | return err ?: count; |
148 | } | 135 | } |
149 | 136 | ||
150 | #define TRACKPOINT_INT_ATTR(_name, _command, _default) \ | 137 | #define TRACKPOINT_INT_ATTR(_name, _command, _default) \ |
@@ -175,10 +162,11 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data, | |||
175 | 162 | ||
176 | if (*field != value) { | 163 | if (*field != value) { |
177 | *field = value; | 164 | *field = value; |
178 | trackpoint_toggle_bit(&psmouse->ps2dev, attr->command, attr->mask); | 165 | err = trackpoint_toggle_bit(&psmouse->ps2dev, |
166 | attr->command, attr->mask); | ||
179 | } | 167 | } |
180 | 168 | ||
181 | return count; | 169 | return err ?: count; |
182 | } | 170 | } |
183 | 171 | ||
184 | 172 | ||
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index 83e9c663aa67..e6a07e68d1ff 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c | |||
@@ -26,31 +26,79 @@ MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>"); | |||
26 | MODULE_DESCRIPTION("PS/2 driver library"); | 26 | MODULE_DESCRIPTION("PS/2 driver library"); |
27 | MODULE_LICENSE("GPL"); | 27 | MODULE_LICENSE("GPL"); |
28 | 28 | ||
29 | static int ps2_do_sendbyte(struct ps2dev *ps2dev, u8 byte, | ||
30 | unsigned int timeout, unsigned int max_attempts) | ||
31 | __releases(&ps2dev->serio->lock) __acquires(&ps2dev->serio->lock) | ||
32 | { | ||
33 | int attempt = 0; | ||
34 | int error; | ||
35 | |||
36 | lockdep_assert_held(&ps2dev->serio->lock); | ||
37 | |||
38 | do { | ||
39 | ps2dev->nak = 1; | ||
40 | ps2dev->flags |= PS2_FLAG_ACK; | ||
41 | |||
42 | serio_continue_rx(ps2dev->serio); | ||
43 | |||
44 | error = serio_write(ps2dev->serio, byte); | ||
45 | if (error) | ||
46 | dev_dbg(&ps2dev->serio->dev, | ||
47 | "failed to write %#02x: %d\n", byte, error); | ||
48 | else | ||
49 | wait_event_timeout(ps2dev->wait, | ||
50 | !(ps2dev->flags & PS2_FLAG_ACK), | ||
51 | msecs_to_jiffies(timeout)); | ||
52 | |||
53 | serio_pause_rx(ps2dev->serio); | ||
54 | } while (ps2dev->nak == PS2_RET_NAK && ++attempt < max_attempts); | ||
55 | |||
56 | ps2dev->flags &= ~PS2_FLAG_ACK; | ||
57 | |||
58 | if (!error) { | ||
59 | switch (ps2dev->nak) { | ||
60 | case 0: | ||
61 | break; | ||
62 | case PS2_RET_NAK: | ||
63 | error = -EAGAIN; | ||
64 | break; | ||
65 | case PS2_RET_ERR: | ||
66 | error = -EPROTO; | ||
67 | break; | ||
68 | default: | ||
69 | error = -EIO; | ||
70 | break; | ||
71 | } | ||
72 | } | ||
73 | |||
74 | if (error || attempt > 1) | ||
75 | dev_dbg(&ps2dev->serio->dev, | ||
76 | "%02x - %d (%x), attempt %d\n", | ||
77 | byte, error, ps2dev->nak, attempt); | ||
78 | |||
79 | return error; | ||
80 | } | ||
81 | |||
29 | /* | 82 | /* |
30 | * ps2_sendbyte() sends a byte to the device and waits for acknowledge. | 83 | * ps2_sendbyte() sends a byte to the device and waits for acknowledge. |
31 | * It doesn't handle retransmission, though it could - because if there | 84 | * It doesn't handle retransmission, the caller is expected to handle |
32 | * is a need for retransmissions device has to be replaced anyway. | 85 | * it when needed. |
33 | * | 86 | * |
34 | * ps2_sendbyte() can only be called from a process context. | 87 | * ps2_sendbyte() can only be called from a process context. |
35 | */ | 88 | */ |
36 | 89 | ||
37 | int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout) | 90 | int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout) |
38 | { | 91 | { |
92 | int retval; | ||
93 | |||
39 | serio_pause_rx(ps2dev->serio); | 94 | serio_pause_rx(ps2dev->serio); |
40 | ps2dev->nak = 1; | ||
41 | ps2dev->flags |= PS2_FLAG_ACK; | ||
42 | serio_continue_rx(ps2dev->serio); | ||
43 | 95 | ||
44 | if (serio_write(ps2dev->serio, byte) == 0) | 96 | retval = ps2_do_sendbyte(ps2dev, byte, timeout, 1); |
45 | wait_event_timeout(ps2dev->wait, | 97 | dev_dbg(&ps2dev->serio->dev, "%02x - %x\n", byte, ps2dev->nak); |
46 | !(ps2dev->flags & PS2_FLAG_ACK), | ||
47 | msecs_to_jiffies(timeout)); | ||
48 | 98 | ||
49 | serio_pause_rx(ps2dev->serio); | ||
50 | ps2dev->flags &= ~PS2_FLAG_ACK; | ||
51 | serio_continue_rx(ps2dev->serio); | 99 | serio_continue_rx(ps2dev->serio); |
52 | 100 | ||
53 | return -ps2dev->nak; | 101 | return retval; |
54 | } | 102 | } |
55 | EXPORT_SYMBOL(ps2_sendbyte); | 103 | EXPORT_SYMBOL(ps2_sendbyte); |
56 | 104 | ||
@@ -75,7 +123,7 @@ EXPORT_SYMBOL(ps2_end_command); | |||
75 | * and discards them. | 123 | * and discards them. |
76 | */ | 124 | */ |
77 | 125 | ||
78 | void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout) | 126 | void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout) |
79 | { | 127 | { |
80 | if (maxbytes > sizeof(ps2dev->cmdbuf)) { | 128 | if (maxbytes > sizeof(ps2dev->cmdbuf)) { |
81 | WARN_ON(1); | 129 | WARN_ON(1); |
@@ -102,9 +150,9 @@ EXPORT_SYMBOL(ps2_drain); | |||
102 | * known keyboard IDs. | 150 | * known keyboard IDs. |
103 | */ | 151 | */ |
104 | 152 | ||
105 | int ps2_is_keyboard_id(char id_byte) | 153 | bool ps2_is_keyboard_id(u8 id_byte) |
106 | { | 154 | { |
107 | static const char keyboard_ids[] = { | 155 | static const u8 keyboard_ids[] = { |
108 | 0xab, /* Regular keyboards */ | 156 | 0xab, /* Regular keyboards */ |
109 | 0xac, /* NCD Sun keyboard */ | 157 | 0xac, /* NCD Sun keyboard */ |
110 | 0x2b, /* Trust keyboard, translated */ | 158 | 0x2b, /* Trust keyboard, translated */ |
@@ -123,49 +171,50 @@ EXPORT_SYMBOL(ps2_is_keyboard_id); | |||
123 | * completion. | 171 | * completion. |
124 | */ | 172 | */ |
125 | 173 | ||
126 | static int ps2_adjust_timeout(struct ps2dev *ps2dev, int command, int timeout) | 174 | static int ps2_adjust_timeout(struct ps2dev *ps2dev, |
175 | unsigned int command, unsigned int timeout) | ||
127 | { | 176 | { |
128 | switch (command) { | 177 | switch (command) { |
129 | case PS2_CMD_RESET_BAT: | 178 | case PS2_CMD_RESET_BAT: |
130 | /* | 179 | /* |
131 | * Device has sent the first response byte after | 180 | * Device has sent the first response byte after |
132 | * reset command, reset is thus done, so we can | 181 | * reset command, reset is thus done, so we can |
133 | * shorten the timeout. | 182 | * shorten the timeout. |
134 | * The next byte will come soon (keyboard) or not | 183 | * The next byte will come soon (keyboard) or not |
135 | * at all (mouse). | 184 | * at all (mouse). |
136 | */ | 185 | */ |
137 | if (timeout > msecs_to_jiffies(100)) | 186 | if (timeout > msecs_to_jiffies(100)) |
138 | timeout = msecs_to_jiffies(100); | 187 | timeout = msecs_to_jiffies(100); |
139 | break; | 188 | break; |
140 | 189 | ||
141 | case PS2_CMD_GETID: | 190 | case PS2_CMD_GETID: |
142 | /* | 191 | /* |
143 | * Microsoft Natural Elite keyboard responds to | 192 | * Microsoft Natural Elite keyboard responds to |
144 | * the GET ID command as it were a mouse, with | 193 | * the GET ID command as it were a mouse, with |
145 | * a single byte. Fail the command so atkbd will | 194 | * a single byte. Fail the command so atkbd will |
146 | * use alternative probe to detect it. | 195 | * use alternative probe to detect it. |
147 | */ | 196 | */ |
148 | if (ps2dev->cmdbuf[1] == 0xaa) { | 197 | if (ps2dev->cmdbuf[1] == 0xaa) { |
149 | serio_pause_rx(ps2dev->serio); | 198 | serio_pause_rx(ps2dev->serio); |
150 | ps2dev->flags = 0; | 199 | ps2dev->flags = 0; |
151 | serio_continue_rx(ps2dev->serio); | 200 | serio_continue_rx(ps2dev->serio); |
152 | timeout = 0; | 201 | timeout = 0; |
153 | } | 202 | } |
154 | |||
155 | /* | ||
156 | * If device behind the port is not a keyboard there | ||
157 | * won't be 2nd byte of ID response. | ||
158 | */ | ||
159 | if (!ps2_is_keyboard_id(ps2dev->cmdbuf[1])) { | ||
160 | serio_pause_rx(ps2dev->serio); | ||
161 | ps2dev->flags = ps2dev->cmdcnt = 0; | ||
162 | serio_continue_rx(ps2dev->serio); | ||
163 | timeout = 0; | ||
164 | } | ||
165 | break; | ||
166 | 203 | ||
167 | default: | 204 | /* |
168 | break; | 205 | * If device behind the port is not a keyboard there |
206 | * won't be 2nd byte of ID response. | ||
207 | */ | ||
208 | if (!ps2_is_keyboard_id(ps2dev->cmdbuf[1])) { | ||
209 | serio_pause_rx(ps2dev->serio); | ||
210 | ps2dev->flags = ps2dev->cmdcnt = 0; | ||
211 | serio_continue_rx(ps2dev->serio); | ||
212 | timeout = 0; | ||
213 | } | ||
214 | break; | ||
215 | |||
216 | default: | ||
217 | break; | ||
169 | } | 218 | } |
170 | 219 | ||
171 | return timeout; | 220 | return timeout; |
@@ -178,50 +227,60 @@ static int ps2_adjust_timeout(struct ps2dev *ps2dev, int command, int timeout) | |||
178 | * ps2_command() can only be called from a process context | 227 | * ps2_command() can only be called from a process context |
179 | */ | 228 | */ |
180 | 229 | ||
181 | int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) | 230 | int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command) |
182 | { | 231 | { |
183 | int timeout; | 232 | unsigned int timeout; |
184 | int send = (command >> 12) & 0xf; | 233 | unsigned int send = (command >> 12) & 0xf; |
185 | int receive = (command >> 8) & 0xf; | 234 | unsigned int receive = (command >> 8) & 0xf; |
186 | int rc = -1; | 235 | int rc; |
187 | int i; | 236 | int i; |
237 | u8 send_param[16]; | ||
188 | 238 | ||
189 | if (receive > sizeof(ps2dev->cmdbuf)) { | 239 | if (receive > sizeof(ps2dev->cmdbuf)) { |
190 | WARN_ON(1); | 240 | WARN_ON(1); |
191 | return -1; | 241 | return -EINVAL; |
192 | } | 242 | } |
193 | 243 | ||
194 | if (send && !param) { | 244 | if (send && !param) { |
195 | WARN_ON(1); | 245 | WARN_ON(1); |
196 | return -1; | 246 | return -EINVAL; |
197 | } | 247 | } |
198 | 248 | ||
249 | memcpy(send_param, param, send); | ||
250 | |||
199 | serio_pause_rx(ps2dev->serio); | 251 | serio_pause_rx(ps2dev->serio); |
252 | |||
200 | ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0; | 253 | ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0; |
201 | ps2dev->cmdcnt = receive; | 254 | ps2dev->cmdcnt = receive; |
202 | if (receive && param) | 255 | if (receive && param) |
203 | for (i = 0; i < receive; i++) | 256 | for (i = 0; i < receive; i++) |
204 | ps2dev->cmdbuf[(receive - 1) - i] = param[i]; | 257 | ps2dev->cmdbuf[(receive - 1) - i] = param[i]; |
205 | serio_continue_rx(ps2dev->serio); | 258 | |
259 | /* Signal that we are sending the command byte */ | ||
260 | ps2dev->flags |= PS2_FLAG_ACK_CMD; | ||
206 | 261 | ||
207 | /* | 262 | /* |
208 | * Some devices (Synaptics) peform the reset before | 263 | * Some devices (Synaptics) peform the reset before |
209 | * ACKing the reset command, and so it can take a long | 264 | * ACKing the reset command, and so it can take a long |
210 | * time before the ACK arrives. | 265 | * time before the ACK arrives. |
211 | */ | 266 | */ |
212 | if (ps2_sendbyte(ps2dev, command & 0xff, | 267 | timeout = command == PS2_CMD_RESET_BAT ? 1000 : 200; |
213 | command == PS2_CMD_RESET_BAT ? 1000 : 200)) { | 268 | |
214 | serio_pause_rx(ps2dev->serio); | 269 | rc = ps2_do_sendbyte(ps2dev, command & 0xff, timeout, 2); |
270 | if (rc) | ||
215 | goto out_reset_flags; | 271 | goto out_reset_flags; |
216 | } | 272 | |
273 | /* Now we are sending command parameters, if any */ | ||
274 | ps2dev->flags &= ~PS2_FLAG_ACK_CMD; | ||
217 | 275 | ||
218 | for (i = 0; i < send; i++) { | 276 | for (i = 0; i < send; i++) { |
219 | if (ps2_sendbyte(ps2dev, param[i], 200)) { | 277 | rc = ps2_do_sendbyte(ps2dev, param[i], 200, 2); |
220 | serio_pause_rx(ps2dev->serio); | 278 | if (rc) |
221 | goto out_reset_flags; | 279 | goto out_reset_flags; |
222 | } | ||
223 | } | 280 | } |
224 | 281 | ||
282 | serio_continue_rx(ps2dev->serio); | ||
283 | |||
225 | /* | 284 | /* |
226 | * The reset command takes a long time to execute. | 285 | * The reset command takes a long time to execute. |
227 | */ | 286 | */ |
@@ -243,8 +302,11 @@ int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) | |||
243 | for (i = 0; i < receive; i++) | 302 | for (i = 0; i < receive; i++) |
244 | param[i] = ps2dev->cmdbuf[(receive - 1) - i]; | 303 | param[i] = ps2dev->cmdbuf[(receive - 1) - i]; |
245 | 304 | ||
246 | if (ps2dev->cmdcnt && (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1)) | 305 | if (ps2dev->cmdcnt && |
306 | (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1)) { | ||
307 | rc = -EPROTO; | ||
247 | goto out_reset_flags; | 308 | goto out_reset_flags; |
309 | } | ||
248 | 310 | ||
249 | rc = 0; | 311 | rc = 0; |
250 | 312 | ||
@@ -252,11 +314,21 @@ int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) | |||
252 | ps2dev->flags = 0; | 314 | ps2dev->flags = 0; |
253 | serio_continue_rx(ps2dev->serio); | 315 | serio_continue_rx(ps2dev->serio); |
254 | 316 | ||
255 | return rc; | 317 | dev_dbg(&ps2dev->serio->dev, |
318 | "%02x [%*ph] - %x/%08lx [%*ph]\n", | ||
319 | command & 0xff, send, send_param, | ||
320 | ps2dev->nak, ps2dev->flags, | ||
321 | receive, param ?: send_param); | ||
322 | |||
323 | /* | ||
324 | * ps_command() handles resends itself, so do not leak -EAGAIN | ||
325 | * to the callers. | ||
326 | */ | ||
327 | return rc != -EAGAIN ? rc : -EPROTO; | ||
256 | } | 328 | } |
257 | EXPORT_SYMBOL(__ps2_command); | 329 | EXPORT_SYMBOL(__ps2_command); |
258 | 330 | ||
259 | int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) | 331 | int ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command) |
260 | { | 332 | { |
261 | int rc; | 333 | int rc; |
262 | 334 | ||
@@ -269,6 +341,39 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) | |||
269 | EXPORT_SYMBOL(ps2_command); | 341 | EXPORT_SYMBOL(ps2_command); |
270 | 342 | ||
271 | /* | 343 | /* |
344 | * ps2_sliced_command() sends an extended PS/2 command to the mouse | ||
345 | * using sliced syntax, understood by advanced devices, such as Logitech | ||
346 | * or Synaptics touchpads. The command is encoded as: | ||
347 | * 0xE6 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu | ||
348 | * is the command. | ||
349 | */ | ||
350 | |||
351 | int ps2_sliced_command(struct ps2dev *ps2dev, u8 command) | ||
352 | { | ||
353 | int i; | ||
354 | int retval; | ||
355 | |||
356 | ps2_begin_command(ps2dev); | ||
357 | |||
358 | retval = __ps2_command(ps2dev, NULL, PS2_CMD_SETSCALE11); | ||
359 | if (retval) | ||
360 | goto out; | ||
361 | |||
362 | for (i = 6; i >= 0; i -= 2) { | ||
363 | u8 d = (command >> i) & 3; | ||
364 | retval = __ps2_command(ps2dev, &d, PS2_CMD_SETRES); | ||
365 | if (retval) | ||
366 | break; | ||
367 | } | ||
368 | |||
369 | out: | ||
370 | dev_dbg(&ps2dev->serio->dev, "%02x - %d\n", command, retval); | ||
371 | ps2_end_command(ps2dev); | ||
372 | return retval; | ||
373 | } | ||
374 | EXPORT_SYMBOL(ps2_sliced_command); | ||
375 | |||
376 | /* | ||
272 | * ps2_init() initializes ps2dev structure | 377 | * ps2_init() initializes ps2dev structure |
273 | */ | 378 | */ |
274 | 379 | ||
@@ -286,42 +391,53 @@ EXPORT_SYMBOL(ps2_init); | |||
286 | * to properly process ACK/NAK of a command from a PS/2 device. | 391 | * to properly process ACK/NAK of a command from a PS/2 device. |
287 | */ | 392 | */ |
288 | 393 | ||
289 | int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data) | 394 | bool ps2_handle_ack(struct ps2dev *ps2dev, u8 data) |
290 | { | 395 | { |
291 | switch (data) { | 396 | switch (data) { |
292 | case PS2_RET_ACK: | 397 | case PS2_RET_ACK: |
293 | ps2dev->nak = 0; | 398 | ps2dev->nak = 0; |
399 | break; | ||
400 | |||
401 | case PS2_RET_NAK: | ||
402 | ps2dev->flags |= PS2_FLAG_NAK; | ||
403 | ps2dev->nak = PS2_RET_NAK; | ||
404 | break; | ||
405 | |||
406 | case PS2_RET_ERR: | ||
407 | if (ps2dev->flags & PS2_FLAG_NAK) { | ||
408 | ps2dev->flags &= ~PS2_FLAG_NAK; | ||
409 | ps2dev->nak = PS2_RET_ERR; | ||
294 | break; | 410 | break; |
411 | } | ||
295 | 412 | ||
296 | case PS2_RET_NAK: | 413 | /* |
297 | ps2dev->flags |= PS2_FLAG_NAK; | 414 | * Workaround for mice which don't ACK the Get ID command. |
298 | ps2dev->nak = PS2_RET_NAK; | 415 | * These are valid mouse IDs that we recognize. |
416 | */ | ||
417 | case 0x00: | ||
418 | case 0x03: | ||
419 | case 0x04: | ||
420 | if (ps2dev->flags & PS2_FLAG_WAITID) { | ||
421 | ps2dev->nak = 0; | ||
299 | break; | 422 | break; |
300 | 423 | } | |
301 | case PS2_RET_ERR: | 424 | /* Fall through */ |
302 | if (ps2dev->flags & PS2_FLAG_NAK) { | 425 | default: |
303 | ps2dev->flags &= ~PS2_FLAG_NAK; | ||
304 | ps2dev->nak = PS2_RET_ERR; | ||
305 | break; | ||
306 | } | ||
307 | |||
308 | /* | 426 | /* |
309 | * Workaround for mice which don't ACK the Get ID command. | 427 | * Do not signal errors if we get unexpected reply while |
310 | * These are valid mouse IDs that we recognize. | 428 | * waiting for an ACK to the initial (first) command byte: |
429 | * the device might not be quiesced yet and continue | ||
430 | * delivering data. | ||
431 | * Note that we reset PS2_FLAG_WAITID flag, so the workaround | ||
432 | * for mice not acknowledging the Get ID command only triggers | ||
433 | * on the 1st byte; if device spews data we really want to see | ||
434 | * a real ACK from it. | ||
311 | */ | 435 | */ |
312 | case 0x00: | 436 | dev_dbg(&ps2dev->serio->dev, "unexpected %#02x\n", data); |
313 | case 0x03: | 437 | ps2dev->flags &= ~PS2_FLAG_WAITID; |
314 | case 0x04: | 438 | return ps2dev->flags & PS2_FLAG_ACK_CMD; |
315 | if (ps2dev->flags & PS2_FLAG_WAITID) { | ||
316 | ps2dev->nak = 0; | ||
317 | break; | ||
318 | } | ||
319 | /* Fall through */ | ||
320 | default: | ||
321 | return 0; | ||
322 | } | 439 | } |
323 | 440 | ||
324 | |||
325 | if (!ps2dev->nak) { | 441 | if (!ps2dev->nak) { |
326 | ps2dev->flags &= ~PS2_FLAG_NAK; | 442 | ps2dev->flags &= ~PS2_FLAG_NAK; |
327 | if (ps2dev->cmdcnt) | 443 | if (ps2dev->cmdcnt) |
@@ -334,7 +450,7 @@ int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data) | |||
334 | if (data != PS2_RET_ACK) | 450 | if (data != PS2_RET_ACK) |
335 | ps2_handle_response(ps2dev, data); | 451 | ps2_handle_response(ps2dev, data); |
336 | 452 | ||
337 | return 1; | 453 | return true; |
338 | } | 454 | } |
339 | EXPORT_SYMBOL(ps2_handle_ack); | 455 | EXPORT_SYMBOL(ps2_handle_ack); |
340 | 456 | ||
@@ -344,7 +460,7 @@ EXPORT_SYMBOL(ps2_handle_ack); | |||
344 | * waiting for completion of the command. | 460 | * waiting for completion of the command. |
345 | */ | 461 | */ |
346 | 462 | ||
347 | int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data) | 463 | bool ps2_handle_response(struct ps2dev *ps2dev, u8 data) |
348 | { | 464 | { |
349 | if (ps2dev->cmdcnt) | 465 | if (ps2dev->cmdcnt) |
350 | ps2dev->cmdbuf[--ps2dev->cmdcnt] = data; | 466 | ps2dev->cmdbuf[--ps2dev->cmdcnt] = data; |
@@ -360,7 +476,7 @@ int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data) | |||
360 | wake_up(&ps2dev->wait); | 476 | wake_up(&ps2dev->wait); |
361 | } | 477 | } |
362 | 478 | ||
363 | return 1; | 479 | return true; |
364 | } | 480 | } |
365 | EXPORT_SYMBOL(ps2_handle_response); | 481 | EXPORT_SYMBOL(ps2_handle_response); |
366 | 482 | ||
diff --git a/include/linux/libps2.h b/include/linux/libps2.h index 4ad06e824f76..5f18fe02ae37 100644 --- a/include/linux/libps2.h +++ b/include/linux/libps2.h | |||
@@ -10,7 +10,13 @@ | |||
10 | * the Free Software Foundation. | 10 | * the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/bitops.h> | ||
14 | #include <linux/mutex.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <linux/wait.h> | ||
13 | 17 | ||
18 | #define PS2_CMD_SETSCALE11 0x00e6 | ||
19 | #define PS2_CMD_SETRES 0x10e8 | ||
14 | #define PS2_CMD_GETID 0x02f2 | 20 | #define PS2_CMD_GETID 0x02f2 |
15 | #define PS2_CMD_RESET_BAT 0x02ff | 21 | #define PS2_CMD_RESET_BAT 0x02ff |
16 | 22 | ||
@@ -20,11 +26,12 @@ | |||
20 | #define PS2_RET_NAK 0xfe | 26 | #define PS2_RET_NAK 0xfe |
21 | #define PS2_RET_ERR 0xfc | 27 | #define PS2_RET_ERR 0xfc |
22 | 28 | ||
23 | #define PS2_FLAG_ACK 1 /* Waiting for ACK/NAK */ | 29 | #define PS2_FLAG_ACK BIT(0) /* Waiting for ACK/NAK */ |
24 | #define PS2_FLAG_CMD 2 /* Waiting for command to finish */ | 30 | #define PS2_FLAG_CMD BIT(1) /* Waiting for a command to finish */ |
25 | #define PS2_FLAG_CMD1 4 /* Waiting for the first byte of command response */ | 31 | #define PS2_FLAG_CMD1 BIT(2) /* Waiting for the first byte of command response */ |
26 | #define PS2_FLAG_WAITID 8 /* Command execiting is GET ID */ | 32 | #define PS2_FLAG_WAITID BIT(3) /* Command executing is GET ID */ |
27 | #define PS2_FLAG_NAK 16 /* Last transmission was NAKed */ | 33 | #define PS2_FLAG_NAK BIT(4) /* Last transmission was NAKed */ |
34 | #define PS2_FLAG_ACK_CMD BIT(5) /* Waiting to ACK the command (first) byte */ | ||
28 | 35 | ||
29 | struct ps2dev { | 36 | struct ps2dev { |
30 | struct serio *serio; | 37 | struct serio *serio; |
@@ -36,21 +43,22 @@ struct ps2dev { | |||
36 | wait_queue_head_t wait; | 43 | wait_queue_head_t wait; |
37 | 44 | ||
38 | unsigned long flags; | 45 | unsigned long flags; |
39 | unsigned char cmdbuf[8]; | 46 | u8 cmdbuf[8]; |
40 | unsigned char cmdcnt; | 47 | u8 cmdcnt; |
41 | unsigned char nak; | 48 | u8 nak; |
42 | }; | 49 | }; |
43 | 50 | ||
44 | void ps2_init(struct ps2dev *ps2dev, struct serio *serio); | 51 | void ps2_init(struct ps2dev *ps2dev, struct serio *serio); |
45 | int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout); | 52 | int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout); |
46 | void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout); | 53 | void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout); |
47 | void ps2_begin_command(struct ps2dev *ps2dev); | 54 | void ps2_begin_command(struct ps2dev *ps2dev); |
48 | void ps2_end_command(struct ps2dev *ps2dev); | 55 | void ps2_end_command(struct ps2dev *ps2dev); |
49 | int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command); | 56 | int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command); |
50 | int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command); | 57 | int ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command); |
51 | int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data); | 58 | int ps2_sliced_command(struct ps2dev *ps2dev, u8 command); |
52 | int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data); | 59 | bool ps2_handle_ack(struct ps2dev *ps2dev, u8 data); |
60 | bool ps2_handle_response(struct ps2dev *ps2dev, u8 data); | ||
53 | void ps2_cmd_aborted(struct ps2dev *ps2dev); | 61 | void ps2_cmd_aborted(struct ps2dev *ps2dev); |
54 | int ps2_is_keyboard_id(char id); | 62 | bool ps2_is_keyboard_id(u8 id); |
55 | 63 | ||
56 | #endif /* _LIBPS2_H */ | 64 | #endif /* _LIBPS2_H */ |