From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752382AbcGMNb3 (ORCPT ); Wed, 13 Jul 2016 09:31:29 -0400 Received: from mail-pa0-f66.google.com ([209.85.220.66]:36229 "EHLO mail-pa0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751288AbcGMNbV (ORCPT ); Wed, 13 Jul 2016 09:31:21 -0400 From: KT Liao X-Google-Original-From: KT Liao To: linux-kernel@vger.kernel.org, linux-input@vger.kernel.org, dmitry.torokhov@gmail.com Cc: phoenix@emc.com.tw, kt.liao@emc.com.tw Subject: [PATCH] Input: /input/mouse/elan_i2c_core.c Date: Wed, 13 Jul 2016 21:30:29 +0800 Message-Id: <1468416629-4615-1-git-send-email-kt.liao@emc.com.tw> X-Mailer: git-send-email 2.7.4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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) - * 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; + /* Initialize the touchpad. */ error = elan_initialize(data); if (error) -- 2.7.4