From patchwork Sun Sep 25 03:31:19 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe TORDEUX X-Patchwork-Id: 9349419 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 381106077A for ; Sun, 25 Sep 2016 03:39:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 198CC28981 for ; Sun, 25 Sep 2016 03:39:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0A35C28F6E; Sun, 25 Sep 2016 03:39:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_TVD_MIME_EPI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BADE528981 for ; Sun, 25 Sep 2016 03:39:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965305AbcIYDjs (ORCPT ); Sat, 24 Sep 2016 23:39:48 -0400 Received: from mx496502.smtp-engine.com ([212.227.20.70]:35225 "EHLO mx496502.smtp-engine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965202AbcIYDjr (ORCPT ); Sat, 24 Sep 2016 23:39:47 -0400 X-Greylist: delayed 500 seconds by postgrey-1.27 at vger.kernel.org; Sat, 24 Sep 2016 23:39:47 EDT Received: from sherka (unknown [117.9.218.203]) by mx496502.smtp-engine.com (Postfix) with ESMTPSA id 2D289276; Sun, 25 Sep 2016 04:31:22 +0100 (BST) Received: from maze by sherka with local (Exim 4.87) (envelope-from ) id 1bo09v-00057m-5r; Sun, 25 Sep 2016 11:31:19 +0800 Date: Sun, 25 Sep 2016 11:31:19 +0800 From: Christophe TORDEUX To: Rydberg , Dmitry Torokhov , Tai-hwa Liang , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 01/01] drivers:input:byd fix greedy detection of Sentelic FSP by the BYD touchpad driver Message-ID: <20160925033119.rvptljq3zs4hkmmf@sherka.pkbd.org> MIME-Version: 1.0 Content-Disposition: inline X-PGP-Key: http://christophe.tordeux.net/data/pgp/c-tor2/pubkey.asc User-Agent: NeoMutt/ (1.7.0) Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Christophe TORDEUX With kernel v4.6 and later, the Sentelic touchpad STL3888_C0 and probably other Sentelic FSP touchpads are detected as a BYD touchpad and lose multitouch features. During the BYD handshake in the byd_detect function, the BYD driver mistakenly interprets a standard PS/2 protocol status request answer from the Sentelic touchpad as a successful handshake with a BYD touchpad. This is clearly a bug of the BYD driver. Description of the patch: In byd_detect function, remove positive detection result based on standard PS/2 protocol status request answer. Replace it with positive detection based on handshake answers as they can be inferred from the BYD touchpad datasheets found on BYD website. Signed-off-by: Christophe TORDEUX --- Comments/discussion: A Sentelic touchpad STL3888_C0 is available to the author of this patch. No BYD touchpad device is available to the author of this patch for testing purpose. The BYD website contains 5 data sheets documents for 5 touchpads. Unfortunately the handshake procedure description from the BYD datasheets is either not fully consistent or not fully detailed. This means that while the author is positive the bug of Sentelic greedy detection is fixed by this patch, the effect on detection of BYD touchpads is not tested on actual hardware. But, because this patch codes the detection according to expected handshake answers based on BYD datasheets, the approach taken by this patch is probably the best in the author's opinion. Nevertheless alternatives can be considered. Alternative 1: move the detection of Sentelic touchpads above the detection of BYD touchpads in psmouse_try_protocol function. However based on the code comments, this could have adverse effects which I don't really know about. Alternative2: Sentelic STL3888_C0 answers E9 status request with a standard PS/2 protocol answer, however I found out my Sentelic STL3888_C0 answers E8/00/E8/00/E8/00/E8/00/E9 with 00/88/64, which looks like a handshake answer. This could be used as a test to exit the byd_detect function. Still effect on detection of a BYD device is not known. --- drivers/input/mouse/byd.c | 76 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 14 deletions(-) diff --git a/drivers/input/mouse/byd.c b/drivers/input/mouse/byd.c index b27aa63..b5acca0 100644 --- a/drivers/input/mouse/byd.c +++ b/drivers/input/mouse/byd.c @@ -35,6 +35,18 @@ * BYD pad constants */ +/* Handshake answer of BTP6034 */ +#define BYD_MODEL_BTP6034 0x00E801 +/* Handshake answer of BTP6740 */ +#define BYD_MODEL_BTP6740 0x001155 +/* Handshake answers of BTP8644, BTP10463 and BTP11484 */ +#define BYD_MODEL_BTP8644 0x011155 + +/* Handshake SETRES byte of BTP6034 and BTP6740 */ +#define BYD_SHAKE_BYTE_A 0x00 +/* Handshake SETRES byte of BTP8644, BTP10463 and BTP11484 */ +#define BYD_SHAKE_BYTE_B 0x03 + /* * True device resolution is unknown, however experiments show the * resolution is about 111 units/mm. @@ -434,23 +446,59 @@ static void byd_disconnect(struct psmouse *psmouse) } } +u32 byd_try_model(u32 model) +{ + size_t i; + + u32 byd_model[] = { + BYD_MODEL_BTP6034, + BYD_MODEL_BTP6740, + BYD_MODEL_BTP8644 + }; + + for (i=0; i < ARRAY_SIZE(byd_model); i++) { + if (model == byd_model[i]) + return model; + } + + return 0; +} + int byd_detect(struct psmouse *psmouse, bool set_properties) { struct ps2dev *ps2dev = &psmouse->ps2dev; - u8 param[4] = {0x03, 0x00, 0x00, 0x00}; - - if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) - return -1; - if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) - return -1; - if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) - return -1; - if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) - return -1; - if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) - return -1; - - if (param[1] != 0x03 || param[2] != 0x64) + size_t i; + + u8 byd_shbyte[] = { + BYD_SHAKE_BYTE_A, + BYD_SHAKE_BYTE_B + }; + + bool detect = false; + for (i=0; i < ARRAY_SIZE(byd_shbyte); i++) { + u32 model; + u8 param[4] = {byd_shbyte[i], 0x00, 0x00, 0x00}; + + if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) + return -1; + if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) + return -1; + if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) + return -1; + if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) + return -1; + if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) + return -1; + + model = param[2]; + model += param[1] << 8; + model += param[0] << 16; + model = byd_try_model(model); + if (model) + detect = true; + } + + if (!detect) return -ENODEV; psmouse_dbg(psmouse, "BYD touchpad detected\n");