diff options
author | Masaki Ota <masaki.ota@jp.alps.com> | 2017-03-17 17:10:57 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-03-30 03:41:22 -0400 |
commit | 81643d000315229e5ff13cff943a69da9ab92a80 (patch) | |
tree | eb5f77e5ab5c5a4ff933a38ffb28d59ebbbe7278 /drivers/input | |
parent | 9e13bcef24691b44c4de1257ba1ab6d2b8a43440 (diff) |
Input: ALPS - fix V8+ protocol handling (73 03 28)
commit e7348396c6d51b57c95c6646c390cd078e038e19 upstream.
Devices identified as E7="73 03 28" use slightly modified version of V8
protocol, with lower count per electrode, different offsets, and different
feature bits in OTP data.
Fixes: aeaa881f9b17 ("Input: ALPS - set DualPoint flag for 74 03 28 devices")
Signed-off-by: Masaki Ota <masaki.ota@jp.alps.com>
Acked-by: Pali Rohar <pali.rohar@gmail.com>
Tested-by: Paul Donohue <linux-kernel@PaulSD.com>
Tested-by: Nick Fletcher <nick.m.fletcher@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/mouse/alps.c | 66 | ||||
-rw-r--r-- | drivers/input/mouse/alps.h | 11 |
2 files changed, 61 insertions, 16 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index b93fe83a0b63..3101a84ec8b5 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -2461,14 +2461,34 @@ static int alps_update_device_area_ss4_v2(unsigned char otp[][4], | |||
2461 | int num_y_electrode; | 2461 | int num_y_electrode; |
2462 | int x_pitch, y_pitch, x_phys, y_phys; | 2462 | int x_pitch, y_pitch, x_phys, y_phys; |
2463 | 2463 | ||
2464 | num_x_electrode = SS4_NUMSENSOR_XOFFSET + (otp[1][0] & 0x0F); | 2464 | if (IS_SS4PLUS_DEV(priv->dev_id)) { |
2465 | num_y_electrode = SS4_NUMSENSOR_YOFFSET + ((otp[1][0] >> 4) & 0x0F); | 2465 | num_x_electrode = |
2466 | SS4PLUS_NUMSENSOR_XOFFSET + (otp[0][2] & 0x0F); | ||
2467 | num_y_electrode = | ||
2468 | SS4PLUS_NUMSENSOR_YOFFSET + ((otp[0][2] >> 4) & 0x0F); | ||
2466 | 2469 | ||
2467 | priv->x_max = (num_x_electrode - 1) * SS4_COUNT_PER_ELECTRODE; | 2470 | priv->x_max = |
2468 | priv->y_max = (num_y_electrode - 1) * SS4_COUNT_PER_ELECTRODE; | 2471 | (num_x_electrode - 1) * SS4PLUS_COUNT_PER_ELECTRODE; |
2472 | priv->y_max = | ||
2473 | (num_y_electrode - 1) * SS4PLUS_COUNT_PER_ELECTRODE; | ||
2469 | 2474 | ||
2470 | x_pitch = ((otp[1][2] >> 2) & 0x07) + SS4_MIN_PITCH_MM; | 2475 | x_pitch = (otp[0][1] & 0x0F) + SS4PLUS_MIN_PITCH_MM; |
2471 | y_pitch = ((otp[1][2] >> 5) & 0x07) + SS4_MIN_PITCH_MM; | 2476 | y_pitch = ((otp[0][1] >> 4) & 0x0F) + SS4PLUS_MIN_PITCH_MM; |
2477 | |||
2478 | } else { | ||
2479 | num_x_electrode = | ||
2480 | SS4_NUMSENSOR_XOFFSET + (otp[1][0] & 0x0F); | ||
2481 | num_y_electrode = | ||
2482 | SS4_NUMSENSOR_YOFFSET + ((otp[1][0] >> 4) & 0x0F); | ||
2483 | |||
2484 | priv->x_max = | ||
2485 | (num_x_electrode - 1) * SS4_COUNT_PER_ELECTRODE; | ||
2486 | priv->y_max = | ||
2487 | (num_y_electrode - 1) * SS4_COUNT_PER_ELECTRODE; | ||
2488 | |||
2489 | x_pitch = ((otp[1][2] >> 2) & 0x07) + SS4_MIN_PITCH_MM; | ||
2490 | y_pitch = ((otp[1][2] >> 5) & 0x07) + SS4_MIN_PITCH_MM; | ||
2491 | } | ||
2472 | 2492 | ||
2473 | x_phys = x_pitch * (num_x_electrode - 1); /* In 0.1 mm units */ | 2493 | x_phys = x_pitch * (num_x_electrode - 1); /* In 0.1 mm units */ |
2474 | y_phys = y_pitch * (num_y_electrode - 1); /* In 0.1 mm units */ | 2494 | y_phys = y_pitch * (num_y_electrode - 1); /* In 0.1 mm units */ |
@@ -2484,7 +2504,10 @@ static int alps_update_btn_info_ss4_v2(unsigned char otp[][4], | |||
2484 | { | 2504 | { |
2485 | unsigned char is_btnless; | 2505 | unsigned char is_btnless; |
2486 | 2506 | ||
2487 | is_btnless = (otp[1][1] >> 3) & 0x01; | 2507 | if (IS_SS4PLUS_DEV(priv->dev_id)) |
2508 | is_btnless = (otp[1][0] >> 1) & 0x01; | ||
2509 | else | ||
2510 | is_btnless = (otp[1][1] >> 3) & 0x01; | ||
2488 | 2511 | ||
2489 | if (is_btnless) | 2512 | if (is_btnless) |
2490 | priv->flags |= ALPS_BUTTONPAD; | 2513 | priv->flags |= ALPS_BUTTONPAD; |
@@ -2492,6 +2515,21 @@ static int alps_update_btn_info_ss4_v2(unsigned char otp[][4], | |||
2492 | return 0; | 2515 | return 0; |
2493 | } | 2516 | } |
2494 | 2517 | ||
2518 | static int alps_update_dual_info_ss4_v2(unsigned char otp[][4], | ||
2519 | struct alps_data *priv) | ||
2520 | { | ||
2521 | bool is_dual = false; | ||
2522 | |||
2523 | if (IS_SS4PLUS_DEV(priv->dev_id)) | ||
2524 | is_dual = (otp[0][0] >> 4) & 0x01; | ||
2525 | |||
2526 | if (is_dual) | ||
2527 | priv->flags |= ALPS_DUALPOINT | | ||
2528 | ALPS_DUALPOINT_WITH_PRESSURE; | ||
2529 | |||
2530 | return 0; | ||
2531 | } | ||
2532 | |||
2495 | static int alps_set_defaults_ss4_v2(struct psmouse *psmouse, | 2533 | static int alps_set_defaults_ss4_v2(struct psmouse *psmouse, |
2496 | struct alps_data *priv) | 2534 | struct alps_data *priv) |
2497 | { | 2535 | { |
@@ -2507,6 +2545,8 @@ static int alps_set_defaults_ss4_v2(struct psmouse *psmouse, | |||
2507 | 2545 | ||
2508 | alps_update_btn_info_ss4_v2(otp, priv); | 2546 | alps_update_btn_info_ss4_v2(otp, priv); |
2509 | 2547 | ||
2548 | alps_update_dual_info_ss4_v2(otp, priv); | ||
2549 | |||
2510 | return 0; | 2550 | return 0; |
2511 | } | 2551 | } |
2512 | 2552 | ||
@@ -2752,10 +2792,6 @@ static int alps_set_protocol(struct psmouse *psmouse, | |||
2752 | if (alps_set_defaults_ss4_v2(psmouse, priv)) | 2792 | if (alps_set_defaults_ss4_v2(psmouse, priv)) |
2753 | return -EIO; | 2793 | return -EIO; |
2754 | 2794 | ||
2755 | if (priv->fw_ver[1] == 0x1) | ||
2756 | priv->flags |= ALPS_DUALPOINT | | ||
2757 | ALPS_DUALPOINT_WITH_PRESSURE; | ||
2758 | |||
2759 | break; | 2795 | break; |
2760 | } | 2796 | } |
2761 | 2797 | ||
@@ -2826,10 +2862,7 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) | |||
2826 | ec[2] >= 0x90 && ec[2] <= 0x9d) { | 2862 | ec[2] >= 0x90 && ec[2] <= 0x9d) { |
2827 | protocol = &alps_v3_protocol_data; | 2863 | protocol = &alps_v3_protocol_data; |
2828 | } else if (e7[0] == 0x73 && e7[1] == 0x03 && | 2864 | } else if (e7[0] == 0x73 && e7[1] == 0x03 && |
2829 | e7[2] == 0x14 && ec[1] == 0x02) { | 2865 | (e7[2] == 0x14 || e7[2] == 0x28)) { |
2830 | protocol = &alps_v8_protocol_data; | ||
2831 | } else if (e7[0] == 0x73 && e7[1] == 0x03 && | ||
2832 | e7[2] == 0x28 && ec[1] == 0x01) { | ||
2833 | protocol = &alps_v8_protocol_data; | 2866 | protocol = &alps_v8_protocol_data; |
2834 | } else { | 2867 | } else { |
2835 | psmouse_dbg(psmouse, | 2868 | psmouse_dbg(psmouse, |
@@ -2839,7 +2872,8 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) | |||
2839 | } | 2872 | } |
2840 | 2873 | ||
2841 | if (priv) { | 2874 | if (priv) { |
2842 | /* Save the Firmware version */ | 2875 | /* Save Device ID and Firmware version */ |
2876 | memcpy(priv->dev_id, e7, 3); | ||
2843 | memcpy(priv->fw_ver, ec, 3); | 2877 | memcpy(priv->fw_ver, ec, 3); |
2844 | error = alps_set_protocol(psmouse, priv, protocol); | 2878 | error = alps_set_protocol(psmouse, priv, protocol); |
2845 | if (error) | 2879 | if (error) |
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index b9417e2d7ad3..dbfd26073e1a 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h | |||
@@ -54,6 +54,16 @@ enum SS4_PACKET_ID { | |||
54 | 54 | ||
55 | #define SS4_MASK_NORMAL_BUTTONS 0x07 | 55 | #define SS4_MASK_NORMAL_BUTTONS 0x07 |
56 | 56 | ||
57 | #define SS4PLUS_COUNT_PER_ELECTRODE 128 | ||
58 | #define SS4PLUS_NUMSENSOR_XOFFSET 16 | ||
59 | #define SS4PLUS_NUMSENSOR_YOFFSET 5 | ||
60 | #define SS4PLUS_MIN_PITCH_MM 37 | ||
61 | |||
62 | #define IS_SS4PLUS_DEV(_b) (((_b[0]) == 0x73) && \ | ||
63 | ((_b[1]) == 0x03) && \ | ||
64 | ((_b[2]) == 0x28) \ | ||
65 | ) | ||
66 | |||
57 | #define SS4_1F_X_V2(_b) ((_b[0] & 0x0007) | \ | 67 | #define SS4_1F_X_V2(_b) ((_b[0] & 0x0007) | \ |
58 | ((_b[1] << 3) & 0x0078) | \ | 68 | ((_b[1] << 3) & 0x0078) | \ |
59 | ((_b[1] << 2) & 0x0380) | \ | 69 | ((_b[1] << 2) & 0x0380) | \ |
@@ -263,6 +273,7 @@ struct alps_data { | |||
263 | int addr_command; | 273 | int addr_command; |
264 | u16 proto_version; | 274 | u16 proto_version; |
265 | u8 byte0, mask0; | 275 | u8 byte0, mask0; |
276 | u8 dev_id[3]; | ||
266 | u8 fw_ver[3]; | 277 | u8 fw_ver[3]; |
267 | int flags; | 278 | int flags; |
268 | int x_max; | 279 | int x_max; |