From patchwork Wed Jul 13 19:08:14 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 9228403 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 A848C6075D for ; Wed, 13 Jul 2016 19:08:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9687E275A2 for ; Wed, 13 Jul 2016 19:08:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8B90427FBE; Wed, 13 Jul 2016 19:08:53 +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.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID 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 9428F27FA9 for ; Wed, 13 Jul 2016 19:08:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751832AbcGMTI0 (ORCPT ); Wed, 13 Jul 2016 15:08:26 -0400 Received: from mail-pa0-f65.google.com ([209.85.220.65]:36254 "EHLO mail-pa0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751528AbcGMTIY (ORCPT ); Wed, 13 Jul 2016 15:08:24 -0400 Received: by mail-pa0-f65.google.com with SMTP id ez1so22008pab.3; Wed, 13 Jul 2016 12:08:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to :user-agent; bh=kwOLKlElEwpuEM3dhsgYeGP3PFJvecgXuMX7WsolWc8=; b=zZ0IFd9qJ80esY9cdxeRwjfZ6cjdvtD0kQqTYHoFPLt4mDIZ/8VkY8wK8ENPCfN/Y/ Wdb9vf8WkUT4LqWRgwW7cR45hkbfoCRe/Axr0pAzLDMzQ0lYnzQpD2BcKi0XroJdCmHO YD7H6v7fREJUcoghdRjhZ3CqUuMZJuyGov5jkIMWD/PnF/tzMDHDyLU/02D2q3GzU9Zo KdQQX7TQ+c1HNXV+k0ZOGM4Oq0zXXar6/3QvvzI49K1Gr6sI40SvKZ9+C3bKpNp+5wss 3oM+JBeXT9m6k/1TrtvZca5Gj0tpnjpz0x7U/BMKEV+lzW3jTZP6rs1dvO/Fm60B+CIF zjqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to:user-agent; bh=kwOLKlElEwpuEM3dhsgYeGP3PFJvecgXuMX7WsolWc8=; b=Udz6/qaZY7Lxq/vInblRntdY7V9lZiPAgejw6rw2MwI6dh/xEn5w4ePQ3WDBOdgd4K G8jM05YZGQ+Rz/dVkQKmcJVme0pix8tIk3uFtrPKi8ebfQc6qnx05Vkikf82Gi3wBQ0i SWZUVLS4zWzA3JB6nswSbmdlB5Wm6R4A7H9fSEQe4SxkJTDQZMnv3bXKVtgkJXda1ySC RlHNddkBtxOpXzT8AtnW7UR/KuJGb3pu0omrKhvOB0J5Y7Q62Ne2Uc4YjgVtzOC0upUV nLflapM9qVuYkUD6hOXz08lnZS0J0bfeZuXUxcLZtoXo5O0WDXHS3hHwIh3SUqzxyMtK CVTA== X-Gm-Message-State: ALyK8tLwuRc/iFovCT+qy+pllR8B2HcrCGsx0n+iTBG7WAMar79TxWbb5fO0caVYqv0hiw== X-Received: by 10.66.100.202 with SMTP id fa10mr7097152pab.106.1468436898200; Wed, 13 Jul 2016 12:08:18 -0700 (PDT) Received: from dtor-ws ([2620:0:1000:1311:d161:f27b:b6b7:e602]) by smtp.gmail.com with ESMTPSA id d72sm1354190pfj.15.2016.07.13.12.08.16 (version=TLS1_2 cipher=AES128-SHA bits=128/128); Wed, 13 Jul 2016 12:08:16 -0700 (PDT) Date: Wed, 13 Jul 2016 12:08:14 -0700 From: Dmitry Torokhov To: KT Liao Cc: linux-kernel@vger.kernel.org, linux-input@vger.kernel.org, phoenix@emc.com.tw, kt.liao@emc.com.tw, Benjamin Tissoires Subject: Re: [PATCH] Input: /input/mouse/elan_i2c_core.c Message-ID: <20160713190814.GA10821@dtor-ws> References: <1468416629-4615-1-git-send-email-kt.liao@emc.com.tw> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1468416629-4615-1-git-send-email-kt.liao@emc.com.tw> User-Agent: Mutt/1.5.21 (2010-09-15) 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 On Wed, Jul 13, 2016 at 09:30:29PM +0800, KT Liao wrote: > Fix some Asus touchapod which casue TP no funciton sometimes, the patch detect some specific touchpad and run a special initialize > > Signed-off-by: KT Liao > --- > drivers/input/mouse/elan_i2c_core.c | 93 ++++++++++++++++++++++++++++--------- > 1 file changed, 71 insertions(+), 22 deletions(-) > > diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c > index 2f58985..36a69d2 100644 > --- a/drivers/input/mouse/elan_i2c_core.c > +++ b/drivers/input/mouse/elan_i2c_core.c > @@ -3,8 +3,8 @@ > * > * Copyright (c) 2013 ELAN Microelectronics Corp. > * > - * Author: 林政維 (Duson Lin) Let's not remove Duson's name, he did quite a bit of work on the driver. > - * Version: 1.6.0 > + * Author: KT Liao > + * Version: 1.6.2 > * > * Based on cyapa driver: > * copyright (c) 2011-2012 Cypress Semiconductor, Inc. > @@ -40,7 +40,7 @@ > #include "elan_i2c.h" > > #define DRIVER_NAME "elan_i2c" > -#define ELAN_DRIVER_VERSION "1.6.1" > +#define ELAN_DRIVER_VERSION "1.6.2" > #define ELAN_VENDOR_ID 0x04f3 > #define ETP_MAX_PRESSURE 255 > #define ETP_FWIDTH_REDUCE 90 > @@ -95,6 +95,8 @@ struct elan_tp_data { > bool baseline_ready; > }; > > +static int check_ASUS_special_fw(struct elan_tp_data *data); > + > static int elan_get_fwinfo(u8 iap_version, u16 *validpage_count, > u16 *signature_address) > { > @@ -210,21 +212,40 @@ static int __elan_initialize(struct elan_tp_data *data) > return error; > } > > - data->mode |= ETP_ENABLE_ABS; > - error = data->ops->set_mode(client, data->mode); > - if (error) { > - dev_err(&client->dev, > - "failed to switch to absolute mode: %d\n", error); > - return error; > - } > + /* If it's the special FW, it need a different flow for mode change.*/ > + if (check_ASUS_special_fw(data)) { > + error = data->ops->sleep_control(client, false); > + if (error) { > + dev_err(&client->dev, > + "failed to wake device up: %d\n", error); > + return error; > + } > > - error = data->ops->sleep_control(client, false); > - if (error) { > - dev_err(&client->dev, > - "failed to wake device up: %d\n", error); > - return error; > - } > + msleep(200); > > + data->mode |= ETP_ENABLE_ABS; > + error = data->ops->set_mode(client, data->mode); > + if (error) { > + dev_err(&client->dev, > + "failed to switch to absolute mode: %d\n", error); > + return error; > + } > + } else { > + data->mode |= ETP_ENABLE_ABS; > + error = data->ops->set_mode(client, data->mode); > + if (error) { > + dev_err(&client->dev, > + "failed to switch to absolute mode: %d\n", error); > + return error; > + } > + > + error = data->ops->sleep_control(client, false); > + if (error) { > + dev_err(&client->dev, > + "failed to wake device up: %d\n", error); > + return error; > + } > + } > return 0; > } > > @@ -244,7 +265,7 @@ static int elan_initialize(struct elan_tp_data *data) > return error; > } > > -static int elan_query_device_info(struct elan_tp_data *data) > +static int elan_query_device_pid_smver(struct elan_tp_data *data) > { > int error; > > @@ -252,17 +273,24 @@ static int elan_query_device_info(struct elan_tp_data *data) > if (error) > return error; > > - error = data->ops->get_version(data->client, false, &data->fw_version); > + error = data->ops->get_sm_version(data->client, &data->ic_type, > + &data->sm_version); > if (error) > return error; > > - error = data->ops->get_checksum(data->client, false, > - &data->fw_checksum); > + return 0; > +} > + > +static int elan_query_device_info(struct elan_tp_data *data) > +{ > + int error; > + > + error = data->ops->get_version(data->client, false, &data->fw_version); > if (error) > return error; > > - error = data->ops->get_sm_version(data->client, &data->ic_type, > - &data->sm_version); > + error = data->ops->get_checksum(data->client, false, > + &data->fw_checksum); > if (error) > return error; > > @@ -419,6 +447,7 @@ static int elan_update_firmware(struct elan_tp_data *data, > data->ops->iap_reset(client); > } else { > /* Reinitialize TP after fw is updated */ > + elan_query_device_pid_smver(data); > elan_initialize(data); > elan_query_device_info(data); > } > @@ -757,6 +786,22 @@ out: > return retval; > } > > +static int check_ASUS_special_fw(struct elan_tp_data *data) > +{ > + if (data->ic_type != 0x0E) > + return false; > + > + switch (data->product_id) { > + case 0x05: > + case 0x06: > + case 0x07: > + case 0x09: > + case 0x013: > + return true; > + default: > + return false; > + } > +} > > static DEVICE_ATTR_WO(acquire); > static DEVICE_ATTR_RO(min); > @@ -1033,6 +1078,10 @@ static int elan_probe(struct i2c_client *client, > return error; > } > > + error = elan_query_device_pid_smver(data); > + if (error) > + return error; The original code was fetching product ID and IC type after calling the transport "initialize" function; I'd prefer if we kept this order. Could you tell me if the following version of the patch looks OK to you? Vlad, Chris, Jonathan, could you please tell me if this version of the patch fixes your touchpad issue? Thanks! diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index 2f58985..d15b338 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -4,7 +4,8 @@ * Copyright (c) 2013 ELAN Microelectronics Corp. * * Author: 林政維 (Duson Lin) - * Version: 1.6.0 + * Author: KT Liao + * Version: 1.6.2 * * Based on cyapa driver: * copyright (c) 2011-2012 Cypress Semiconductor, Inc. @@ -40,7 +41,7 @@ #include "elan_i2c.h" #define DRIVER_NAME "elan_i2c" -#define ELAN_DRIVER_VERSION "1.6.1" +#define ELAN_DRIVER_VERSION "1.6.2" #define ELAN_VENDOR_ID 0x04f3 #define ETP_MAX_PRESSURE 255 #define ETP_FWIDTH_REDUCE 90 @@ -199,9 +200,41 @@ static int elan_sleep(struct elan_tp_data *data) return error; } +static int elan_query_product(struct elan_tp_data *data) +{ + int error; + + error = data->ops->get_product_id(data->client, &data->product_id); + if (error) + return error; + + error = data->ops->get_sm_version(data->client, &data->ic_type, + &data->sm_version); + if (error) + return error; + + return 0; +} + +static int elan_check_ASUS_special_fw(struct elan_tp_data *data) +{ + if (data->ic_type != 0x0E) + return false; + + switch (data->product_id) { + case 0x05 ... 0x07: + case 0x09: + case 0x13: + return true; + default: + return false; + } +} + static int __elan_initialize(struct elan_tp_data *data) { struct i2c_client *client = data->client; + bool woken_up = false; int error; error = data->ops->initialize(client); @@ -210,6 +243,27 @@ static int __elan_initialize(struct elan_tp_data *data) return error; } + error = elan_query_product(data); + if (error) + return error; + + /* + * Some ASUS devices were shipped with firmware that requires + * touchpads to be woken up first, before attempting to switch + * them into absolute reporting mode. + */ + if (elan_check_ASUS_special_fw(data)) { + error = data->ops->sleep_control(client, false); + if (error) { + dev_err(&client->dev, + "failed to wake device up: %d\n", error); + return error; + } + + msleep(200); + woken_up = true; + } + data->mode |= ETP_ENABLE_ABS; error = data->ops->set_mode(client, data->mode); if (error) { @@ -218,11 +272,13 @@ static int __elan_initialize(struct elan_tp_data *data) return error; } - error = data->ops->sleep_control(client, false); - if (error) { - dev_err(&client->dev, - "failed to wake device up: %d\n", error); - return error; + if (!woken_up) { + error = data->ops->sleep_control(client, false); + if (error) { + dev_err(&client->dev, + "failed to wake device up: %d\n", error); + return error; + } } return 0; @@ -248,10 +304,6 @@ static int elan_query_device_info(struct elan_tp_data *data) { int error; - error = data->ops->get_product_id(data->client, &data->product_id); - if (error) - return error; - error = data->ops->get_version(data->client, false, &data->fw_version); if (error) return error; @@ -261,11 +313,6 @@ static int elan_query_device_info(struct elan_tp_data *data) if (error) return error; - error = data->ops->get_sm_version(data->client, &data->ic_type, - &data->sm_version); - if (error) - return error; - error = data->ops->get_version(data->client, true, &data->iap_version); if (error) return error;