ACK: [SRU][Xenial][Yakkety][PATCH 1/1] Input: ALPS - fix V8+ protocol handling (73 03 28)
Colin Ian King
colin.king at canonical.com
Thu Apr 6 15:52:50 UTC 2017
On 06/04/17 16:25, Joseph Salisbury wrote:
> From: Masaki Ota <masaki.ota at jp.alps.com>
>
> BugLink: http://bugs.launchpad.net/bugs/1662589
>
> 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 at jp.alps.com>
> Acked-by: Pali Rohar <pali.rohar at gmail.com>
> Tested-by: Paul Donohue <linux-kernel at PaulSD.com>
> Tested-by: Nick Fletcher <nick.m.fletcher at gmail.com>
> Cc: stable at vger.kernel.org
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov at gmail.com>
> (backported from commit e7348396c6d51b57c95c6646c390cd078e038e19)
> Signed-off-by: Joseph Salisbury <joseph.salisbury at canonical.com>
> ---
> drivers/input/mouse/alps.c | 66 +++++++++++++++++++++++++++++++++++-----------
> drivers/input/mouse/alps.h | 21 ++++++++++++++-
> 2 files changed, 70 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
> index d10b14f..0fd78c3 100644
> --- a/drivers/input/mouse/alps.c
> +++ b/drivers/input/mouse/alps.c
> @@ -2458,14 +2458,34 @@ static int alps_update_device_area_ss4_v2(unsigned char otp[][4],
> int num_y_electrode;
> int x_pitch, y_pitch, x_phys, y_phys;
>
> - num_x_electrode = SS4_NUMSENSOR_XOFFSET + (otp[1][0] & 0x0F);
> - num_y_electrode = SS4_NUMSENSOR_YOFFSET + ((otp[1][0] >> 4) & 0x0F);
> + if (IS_SS4PLUS_DEV(priv->dev_id)) {
> + num_x_electrode =
> + SS4PLUS_NUMSENSOR_XOFFSET + (otp[0][2] & 0x0F);
> + num_y_electrode =
> + SS4PLUS_NUMSENSOR_YOFFSET + ((otp[0][2] >> 4) & 0x0F);
>
> - priv->x_max = (num_x_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
> - priv->y_max = (num_y_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
> + priv->x_max =
> + (num_x_electrode - 1) * SS4PLUS_COUNT_PER_ELECTRODE;
> + priv->y_max =
> + (num_y_electrode - 1) * SS4PLUS_COUNT_PER_ELECTRODE;
>
> - x_pitch = ((otp[1][2] >> 2) & 0x07) + SS4_MIN_PITCH_MM;
> - y_pitch = ((otp[1][2] >> 5) & 0x07) + SS4_MIN_PITCH_MM;
> + x_pitch = (otp[0][1] & 0x0F) + SS4PLUS_MIN_PITCH_MM;
> + y_pitch = ((otp[0][1] >> 4) & 0x0F) + SS4PLUS_MIN_PITCH_MM;
> +
> + } else {
> + num_x_electrode =
> + SS4_NUMSENSOR_XOFFSET + (otp[1][0] & 0x0F);
> + num_y_electrode =
> + SS4_NUMSENSOR_YOFFSET + ((otp[1][0] >> 4) & 0x0F);
> +
> + priv->x_max =
> + (num_x_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
> + priv->y_max =
> + (num_y_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
> +
> + x_pitch = ((otp[1][2] >> 2) & 0x07) + SS4_MIN_PITCH_MM;
> + y_pitch = ((otp[1][2] >> 5) & 0x07) + SS4_MIN_PITCH_MM;
> + }
>
> x_phys = x_pitch * (num_x_electrode - 1); /* In 0.1 mm units */
> y_phys = y_pitch * (num_y_electrode - 1); /* In 0.1 mm units */
> @@ -2481,7 +2501,10 @@ static int alps_update_btn_info_ss4_v2(unsigned char otp[][4],
> {
> unsigned char is_btnless;
>
> - is_btnless = (otp[1][1] >> 3) & 0x01;
> + if (IS_SS4PLUS_DEV(priv->dev_id))
> + is_btnless = (otp[1][0] >> 1) & 0x01;
> + else
> + is_btnless = (otp[1][1] >> 3) & 0x01;
>
> if (is_btnless)
> priv->flags |= ALPS_BUTTONPAD;
> @@ -2489,6 +2512,21 @@ static int alps_update_btn_info_ss4_v2(unsigned char otp[][4],
> return 0;
> }
>
> +static int alps_update_dual_info_ss4_v2(unsigned char otp[][4],
> + struct alps_data *priv)
> +{
> + bool is_dual = false;
> +
> + if (IS_SS4PLUS_DEV(priv->dev_id))
> + is_dual = (otp[0][0] >> 4) & 0x01;
> +
> + if (is_dual)
> + priv->flags |= ALPS_DUALPOINT |
> + ALPS_DUALPOINT_WITH_PRESSURE;
> +
> + return 0;
> +}
> +
> static int alps_set_defaults_ss4_v2(struct psmouse *psmouse,
> struct alps_data *priv)
> {
> @@ -2504,6 +2542,8 @@ static int alps_set_defaults_ss4_v2(struct psmouse *psmouse,
>
> alps_update_btn_info_ss4_v2(otp, priv);
>
> + alps_update_dual_info_ss4_v2(otp, priv);
> +
> return 0;
> }
>
> @@ -2741,10 +2781,6 @@ static int alps_set_protocol(struct psmouse *psmouse,
> if (alps_set_defaults_ss4_v2(psmouse, priv))
> return -EIO;
>
> - if (priv->fw_ver[1] == 0x1)
> - priv->flags |= ALPS_DUALPOINT |
> - ALPS_DUALPOINT_WITH_PRESSURE;
> -
> break;
> }
>
> @@ -2815,10 +2851,7 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
> ec[2] >= 0x90 && ec[2] <= 0x9d) {
> protocol = &alps_v3_protocol_data;
> } else if (e7[0] == 0x73 && e7[1] == 0x03 &&
> - e7[2] == 0x14 && ec[1] == 0x02) {
> - protocol = &alps_v8_protocol_data;
> - } else if (e7[0] == 0x73 && e7[1] == 0x03 &&
> - e7[2] == 0x28 && ec[1] == 0x01) {
> + (e7[2] == 0x14 || e7[2] == 0x28)) {
> protocol = &alps_v8_protocol_data;
> } else {
> psmouse_dbg(psmouse,
> @@ -2828,7 +2861,8 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
> }
>
> if (priv) {
> - /* Save the Firmware version */
> + /* Save Device ID and Firmware version */
> + memcpy(priv->dev_id, e7, 3);
> memcpy(priv->fw_ver, ec, 3);
> error = alps_set_protocol(psmouse, priv, protocol);
> if (error)
> diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
> index b9417e2..31c06df 100644
> --- a/drivers/input/mouse/alps.h
> +++ b/drivers/input/mouse/alps.h
> @@ -54,7 +54,25 @@ enum SS4_PACKET_ID {
>
> #define SS4_MASK_NORMAL_BUTTONS 0x07
>
> -#define SS4_1F_X_V2(_b) ((_b[0] & 0x0007) | \
> +#define SS4PLUS_COUNT_PER_ELECTRODE 128
> +#define SS4PLUS_NUMSENSOR_XOFFSET 16
> +#define SS4PLUS_NUMSENSOR_YOFFSET 5
> +#define SS4PLUS_MIN_PITCH_MM 37
> +
> +#define IS_SS4PLUS_DEV(_b) (((_b[0]) == 0x73) && \
> + ((_b[1]) == 0x03) && \
> + ((_b[2]) == 0x28) \
> + )
> +
> +#define SS4_IS_IDLE_V2(_b) (((_b[0]) == 0x18) && \
> + ((_b[1]) == 0x10) && \
> + ((_b[2]) == 0x00) && \
> + ((_b[3] & 0x88) == 0x08) && \
> + ((_b[4]) == 0x10) && \
> + ((_b[5]) == 0x00) \
> + )
> +
> +#define SS4_1F_X_V2(_b) (((_b[0]) & 0x0007) | \
> ((_b[1] << 3) & 0x0078) | \
> ((_b[1] << 2) & 0x0380) | \
> ((_b[2] << 5) & 0x1C00) \
> @@ -263,6 +281,7 @@ struct alps_data {
> int addr_command;
> u16 proto_version;
> u8 byte0, mask0;
> + u8 dev_id[3];
> u8 fw_ver[3];
> int flags;
> int x_max;
>
Upstream fix, has known test results and limit device scope, so..
Acked-by: Colin Ian King <colin.king at canonical.com>
More information about the kernel-team
mailing list