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/mouse/alps.c | |
| 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/mouse/alps.c')
| -rw-r--r-- | drivers/input/mouse/alps.c | 66 |
1 files changed, 50 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) |
