aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/input/mouse/alps.c66
-rw-r--r--drivers/input/mouse/alps.h11
2 files changed, 61 insertions, 16 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 72b28ebfe360..262d9b620fcf 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -2462,14 +2462,34 @@ static int alps_update_device_area_ss4_v2(unsigned char otp[][4],
2462 int num_y_electrode; 2462 int num_y_electrode;
2463 int x_pitch, y_pitch, x_phys, y_phys; 2463 int x_pitch, y_pitch, x_phys, y_phys;
2464 2464
2465 num_x_electrode = SS4_NUMSENSOR_XOFFSET + (otp[1][0] & 0x0F); 2465 if (IS_SS4PLUS_DEV(priv->dev_id)) {
2466 num_y_electrode = SS4_NUMSENSOR_YOFFSET + ((otp[1][0] >> 4) & 0x0F); 2466 num_x_electrode =
2467 SS4PLUS_NUMSENSOR_XOFFSET + (otp[0][2] & 0x0F);
2468 num_y_electrode =
2469 SS4PLUS_NUMSENSOR_YOFFSET + ((otp[0][2] >> 4) & 0x0F);
2467 2470
2468 priv->x_max = (num_x_electrode - 1) * SS4_COUNT_PER_ELECTRODE; 2471 priv->x_max =
2469 priv->y_max = (num_y_electrode - 1) * SS4_COUNT_PER_ELECTRODE; 2472 (num_x_electrode - 1) * SS4PLUS_COUNT_PER_ELECTRODE;
2473 priv->y_max =
2474 (num_y_electrode - 1) * SS4PLUS_COUNT_PER_ELECTRODE;
2470 2475
2471 x_pitch = ((otp[1][2] >> 2) & 0x07) + SS4_MIN_PITCH_MM; 2476 x_pitch = (otp[0][1] & 0x0F) + SS4PLUS_MIN_PITCH_MM;
2472 y_pitch = ((otp[1][2] >> 5) & 0x07) + SS4_MIN_PITCH_MM; 2477 y_pitch = ((otp[0][1] >> 4) & 0x0F) + SS4PLUS_MIN_PITCH_MM;
2478
2479 } else {
2480 num_x_electrode =
2481 SS4_NUMSENSOR_XOFFSET + (otp[1][0] & 0x0F);
2482 num_y_electrode =
2483 SS4_NUMSENSOR_YOFFSET + ((otp[1][0] >> 4) & 0x0F);
2484
2485 priv->x_max =
2486 (num_x_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
2487 priv->y_max =
2488 (num_y_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
2489
2490 x_pitch = ((otp[1][2] >> 2) & 0x07) + SS4_MIN_PITCH_MM;
2491 y_pitch = ((otp[1][2] >> 5) & 0x07) + SS4_MIN_PITCH_MM;
2492 }
2473 2493
2474 x_phys = x_pitch * (num_x_electrode - 1); /* In 0.1 mm units */ 2494 x_phys = x_pitch * (num_x_electrode - 1); /* In 0.1 mm units */
2475 y_phys = y_pitch * (num_y_electrode - 1); /* In 0.1 mm units */ 2495 y_phys = y_pitch * (num_y_electrode - 1); /* In 0.1 mm units */
@@ -2485,7 +2505,10 @@ static int alps_update_btn_info_ss4_v2(unsigned char otp[][4],
2485{ 2505{
2486 unsigned char is_btnless; 2506 unsigned char is_btnless;
2487 2507
2488 is_btnless = (otp[1][1] >> 3) & 0x01; 2508 if (IS_SS4PLUS_DEV(priv->dev_id))
2509 is_btnless = (otp[1][0] >> 1) & 0x01;
2510 else
2511 is_btnless = (otp[1][1] >> 3) & 0x01;
2489 2512
2490 if (is_btnless) 2513 if (is_btnless)
2491 priv->flags |= ALPS_BUTTONPAD; 2514 priv->flags |= ALPS_BUTTONPAD;
@@ -2493,6 +2516,21 @@ static int alps_update_btn_info_ss4_v2(unsigned char otp[][4],
2493 return 0; 2516 return 0;
2494} 2517}
2495 2518
2519static int alps_update_dual_info_ss4_v2(unsigned char otp[][4],
2520 struct alps_data *priv)
2521{
2522 bool is_dual = false;
2523
2524 if (IS_SS4PLUS_DEV(priv->dev_id))
2525 is_dual = (otp[0][0] >> 4) & 0x01;
2526
2527 if (is_dual)
2528 priv->flags |= ALPS_DUALPOINT |
2529 ALPS_DUALPOINT_WITH_PRESSURE;
2530
2531 return 0;
2532}
2533
2496static int alps_set_defaults_ss4_v2(struct psmouse *psmouse, 2534static int alps_set_defaults_ss4_v2(struct psmouse *psmouse,
2497 struct alps_data *priv) 2535 struct alps_data *priv)
2498{ 2536{
@@ -2508,6 +2546,8 @@ static int alps_set_defaults_ss4_v2(struct psmouse *psmouse,
2508 2546
2509 alps_update_btn_info_ss4_v2(otp, priv); 2547 alps_update_btn_info_ss4_v2(otp, priv);
2510 2548
2549 alps_update_dual_info_ss4_v2(otp, priv);
2550
2511 return 0; 2551 return 0;
2512} 2552}
2513 2553
@@ -2753,10 +2793,6 @@ static int alps_set_protocol(struct psmouse *psmouse,
2753 if (alps_set_defaults_ss4_v2(psmouse, priv)) 2793 if (alps_set_defaults_ss4_v2(psmouse, priv))
2754 return -EIO; 2794 return -EIO;
2755 2795
2756 if (priv->fw_ver[1] == 0x1)
2757 priv->flags |= ALPS_DUALPOINT |
2758 ALPS_DUALPOINT_WITH_PRESSURE;
2759
2760 break; 2796 break;
2761 } 2797 }
2762 2798
@@ -2827,10 +2863,7 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
2827 ec[2] >= 0x90 && ec[2] <= 0x9d) { 2863 ec[2] >= 0x90 && ec[2] <= 0x9d) {
2828 protocol = &alps_v3_protocol_data; 2864 protocol = &alps_v3_protocol_data;
2829 } else if (e7[0] == 0x73 && e7[1] == 0x03 && 2865 } else if (e7[0] == 0x73 && e7[1] == 0x03 &&
2830 e7[2] == 0x14 && ec[1] == 0x02) { 2866 (e7[2] == 0x14 || e7[2] == 0x28)) {
2831 protocol = &alps_v8_protocol_data;
2832 } else if (e7[0] == 0x73 && e7[1] == 0x03 &&
2833 e7[2] == 0x28 && ec[1] == 0x01) {
2834 protocol = &alps_v8_protocol_data; 2867 protocol = &alps_v8_protocol_data;
2835 } else { 2868 } else {
2836 psmouse_dbg(psmouse, 2869 psmouse_dbg(psmouse,
@@ -2840,7 +2873,8 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
2840 } 2873 }
2841 2874
2842 if (priv) { 2875 if (priv) {
2843 /* Save the Firmware version */ 2876 /* Save Device ID and Firmware version */
2877 memcpy(priv->dev_id, e7, 3);
2844 memcpy(priv->fw_ver, ec, 3); 2878 memcpy(priv->fw_ver, ec, 3);
2845 error = alps_set_protocol(psmouse, priv, protocol); 2879 error = alps_set_protocol(psmouse, priv, protocol);
2846 if (error) 2880 if (error)
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
index 6d279aa27cb9..4334f2805d93 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_IS_IDLE_V2(_b) (((_b[0]) == 0x18) && \ 67#define SS4_IS_IDLE_V2(_b) (((_b[0]) == 0x18) && \
58 ((_b[1]) == 0x10) && \ 68 ((_b[1]) == 0x10) && \
59 ((_b[2]) == 0x00) && \ 69 ((_b[2]) == 0x00) && \
@@ -283,6 +293,7 @@ struct alps_data {
283 int addr_command; 293 int addr_command;
284 u16 proto_version; 294 u16 proto_version;
285 u8 byte0, mask0; 295 u8 byte0, mask0;
296 u8 dev_id[3];
286 u8 fw_ver[3]; 297 u8 fw_ver[3];
287 int flags; 298 int flags;
288 int x_max; 299 int x_max;