Skip to content

Commit e734839

Browse files
Masaki Otadtor
authored andcommitted
Input: ALPS - fix V8+ protocol handling (73 03 28)
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: aeaa881 ("Input: ALPS - set DualPoint flag for 74 03 28 devices") Signed-off-by: Masaki Ota <[email protected]> Acked-by: Pali Rohar <[email protected]> Tested-by: Paul Donohue <[email protected]> Tested-by: Nick Fletcher <[email protected]> Cc: [email protected] Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent 92461f5 commit e734839

File tree

2 files changed

+61
-16
lines changed

2 files changed

+61
-16
lines changed

drivers/input/mouse/alps.c

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2462,14 +2462,34 @@ static int alps_update_device_area_ss4_v2(unsigned char otp[][4],
24622462
int num_y_electrode;
24632463
int x_pitch, y_pitch, x_phys, y_phys;
24642464

2465-
num_x_electrode = SS4_NUMSENSOR_XOFFSET + (otp[1][0] & 0x0F);
2466-
num_y_electrode = SS4_NUMSENSOR_YOFFSET + ((otp[1][0] >> 4) & 0x0F);
2465+
if (IS_SS4PLUS_DEV(priv->dev_id)) {
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);
24672470

2468-
priv->x_max = (num_x_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
2469-
priv->y_max = (num_y_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
2471+
priv->x_max =
2472+
(num_x_electrode - 1) * SS4PLUS_COUNT_PER_ELECTRODE;
2473+
priv->y_max =
2474+
(num_y_electrode - 1) * SS4PLUS_COUNT_PER_ELECTRODE;
24702475

2471-
x_pitch = ((otp[1][2] >> 2) & 0x07) + SS4_MIN_PITCH_MM;
2472-
y_pitch = ((otp[1][2] >> 5) & 0x07) + SS4_MIN_PITCH_MM;
2476+
x_pitch = (otp[0][1] & 0x0F) + SS4PLUS_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+
}
24732493

24742494
x_phys = x_pitch * (num_x_electrode - 1); /* In 0.1 mm units */
24752495
y_phys = y_pitch * (num_y_electrode - 1); /* In 0.1 mm units */
@@ -2485,14 +2505,32 @@ static int alps_update_btn_info_ss4_v2(unsigned char otp[][4],
24852505
{
24862506
unsigned char is_btnless;
24872507

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;
24892512

24902513
if (is_btnless)
24912514
priv->flags |= ALPS_BUTTONPAD;
24922515

24932516
return 0;
24942517
}
24952518

2519+
static 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+
24962534
static int alps_set_defaults_ss4_v2(struct psmouse *psmouse,
24972535
struct alps_data *priv)
24982536
{
@@ -2508,6 +2546,8 @@ static int alps_set_defaults_ss4_v2(struct psmouse *psmouse,
25082546

25092547
alps_update_btn_info_ss4_v2(otp, priv);
25102548

2549+
alps_update_dual_info_ss4_v2(otp, priv);
2550+
25112551
return 0;
25122552
}
25132553

@@ -2753,10 +2793,6 @@ static int alps_set_protocol(struct psmouse *psmouse,
27532793
if (alps_set_defaults_ss4_v2(psmouse, priv))
27542794
return -EIO;
27552795

2756-
if (priv->fw_ver[1] == 0x1)
2757-
priv->flags |= ALPS_DUALPOINT |
2758-
ALPS_DUALPOINT_WITH_PRESSURE;
2759-
27602796
break;
27612797
}
27622798

@@ -2827,10 +2863,7 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
28272863
ec[2] >= 0x90 && ec[2] <= 0x9d) {
28282864
protocol = &alps_v3_protocol_data;
28292865
} else if (e7[0] == 0x73 && e7[1] == 0x03 &&
2830-
e7[2] == 0x14 && ec[1] == 0x02) {
2831-
protocol = &alps_v8_protocol_data;
2832-
} else if (e7[0] == 0x73 && e7[1] == 0x03 &&
2833-
e7[2] == 0x28 && ec[1] == 0x01) {
2866+
(e7[2] == 0x14 || e7[2] == 0x28)) {
28342867
protocol = &alps_v8_protocol_data;
28352868
} else {
28362869
psmouse_dbg(psmouse,
@@ -2840,7 +2873,8 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
28402873
}
28412874

28422875
if (priv) {
2843-
/* Save the Firmware version */
2876+
/* Save Device ID and Firmware version */
2877+
memcpy(priv->dev_id, e7, 3);
28442878
memcpy(priv->fw_ver, ec, 3);
28452879
error = alps_set_protocol(psmouse, priv, protocol);
28462880
if (error)

drivers/input/mouse/alps.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ enum SS4_PACKET_ID {
5454

5555
#define SS4_MASK_NORMAL_BUTTONS 0x07
5656

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+
5767
#define SS4_IS_IDLE_V2(_b) (((_b[0]) == 0x18) && \
5868
((_b[1]) == 0x10) && \
5969
((_b[2]) == 0x00) && \
@@ -283,6 +293,7 @@ struct alps_data {
283293
int addr_command;
284294
u16 proto_version;
285295
u8 byte0, mask0;
296+
u8 dev_id[3];
286297
u8 fw_ver[3];
287298
int flags;
288299
int x_max;

0 commit comments

Comments
 (0)