From 6f0074005e2b2cab9f1690f71d0560436033c5f1 Mon Sep 17 00:00:00 2001 From: hujing3 Date: Thu, 20 Dec 2018 13:01:22 +0800 Subject: [PATCH] DLKM: focaltech tp firmware support for ft5446 surfNA: focaltech new ft5422u IC support add new ft5446/5422u firmware upgrade logic Change-Id: I91f8bd41f6ea4cc2d7cd8999e3d4e87ee8742918 Signed-off-by: hujing3 Reviewed-on: https://gerrit.mot.com/1285518 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Wei Deng Reviewed-by: Wang Wang Submit-Approved: Jira Key --- .../input/touchscreen/focaltech_mmi/Kbuild | 1 + .../focaltech_mmi/focaltech_flash.c | 9 +- .../focaltech_mmi/focaltech_flash.h | 3 + .../touchscreen/focaltech_mmi/focaltech_ts.c | 4 +- .../focaltech_mmi/focaltech_upgrade_ft5422u.c | 184 ++++++++++++++++++ include/linux/input/focaltech_mmi_modules.h | 1 + 6 files changed, 198 insertions(+), 4 deletions(-) create mode 100644 drivers/input/touchscreen/focaltech_mmi/focaltech_upgrade_ft5422u.c diff --git a/drivers/input/touchscreen/focaltech_mmi/Kbuild b/drivers/input/touchscreen/focaltech_mmi/Kbuild index 9f1eb6df5053..229af9197872 100644 --- a/drivers/input/touchscreen/focaltech_mmi/Kbuild +++ b/drivers/input/touchscreen/focaltech_mmi/Kbuild @@ -9,4 +9,5 @@ focaltech_mmi-objs += focaltech_flash.o focaltech_mmi-objs += focaltech_upgrade_ft8716.o focaltech_mmi-objs += focaltech_upgrade_idc.o focaltech_mmi-objs += focaltech_upgrade_ft5x46.o +focaltech_mmi-objs += focaltech_upgrade_ft5422u.o focaltech_mmi-objs += focaltech_upgrade_ft8006u.o diff --git a/drivers/input/touchscreen/focaltech_mmi/focaltech_flash.c b/drivers/input/touchscreen/focaltech_mmi/focaltech_flash.c index 35de0e3c5c80..5171f26899e9 100644 --- a/drivers/input/touchscreen/focaltech_mmi/focaltech_flash.c +++ b/drivers/input/touchscreen/focaltech_mmi/focaltech_flash.c @@ -376,7 +376,7 @@ int fts_ctpm_auto_upgrade(struct i2c_client *client, ft5x46_set_chip_id(&fts_chip_type_curr); } - if (pdata->family_id == FT8006U_ID) { + if ((pdata->family_id == FT8006U_ID) || (pdata->family_id == FT5422U_ID)) { return fts_fwupg_do_upgrade(fw_name); } @@ -1995,6 +1995,11 @@ int fts_extra_init(struct i2c_client *client, struct input_dev *input_dev, struc fts_data->ic_info.ids = ft8006u_fct; fts_data->ic_info.is_incell = true; fts_data->ic_info.hid_supported = false; - } + } else if (FT5422U_ID == type) { + fwupgrade->func = &upgrade_func_ft5422u; + fts_data->ic_info.ids = ft5422u_fct; + fts_data->ic_info.is_incell = false; + fts_data->ic_info.hid_supported = true; + } return 0; } diff --git a/drivers/input/touchscreen/focaltech_mmi/focaltech_flash.h b/drivers/input/touchscreen/focaltech_mmi/focaltech_flash.h index 6f39f65b626b..4b306841d763 100644 --- a/drivers/input/touchscreen/focaltech_mmi/focaltech_flash.h +++ b/drivers/input/touchscreen/focaltech_mmi/focaltech_flash.h @@ -171,6 +171,7 @@ struct upgrade_func { bool hid_supported; bool pramboot_supported; bool fts_8006u; + bool fts_5422u; u8 *pramboot; u32 pb_length; int (*init)(void); @@ -202,6 +203,8 @@ struct upgrade_fw { extern struct fts_upgrade *fwupgrade; extern struct upgrade_func upgrade_func_ft8006; extern struct upgrade_func upgrade_func_ft8006u; +extern struct upgrade_func upgrade_func_ft5422u; +extern struct ft_chip_t ft5422u_fct; /***************************************************************************** * Static function prototypes diff --git a/drivers/input/touchscreen/focaltech_mmi/focaltech_ts.c b/drivers/input/touchscreen/focaltech_mmi/focaltech_ts.c index 6b79f97ecfea..f6e73754fc73 100644 --- a/drivers/input/touchscreen/focaltech_mmi/focaltech_ts.c +++ b/drivers/input/touchscreen/focaltech_mmi/focaltech_ts.c @@ -3512,7 +3512,7 @@ static int ft_ts_probe(struct i2c_client *client, goto input_register_device_err; } - if (pdata->family_id == FT8006U_ID) { + if ((pdata->family_id == FT8006U_ID) || (pdata->family_id == FT5422U_ID)) { fts_extra_init(client, input_dev, pdata); } @@ -3851,7 +3851,7 @@ static int ft_ts_remove(struct i2c_client *client) ft_gpio_configure(data, false); - if (data->pdata->family_id == FT8006U_ID) { + if ((data->pdata->family_id == FT8006U_ID) || (data->pdata->family_id == FT5422U_ID)) { fts_extra_exit(); } diff --git a/drivers/input/touchscreen/focaltech_mmi/focaltech_upgrade_ft5422u.c b/drivers/input/touchscreen/focaltech_mmi/focaltech_upgrade_ft5422u.c new file mode 100644 index 000000000000..9d4d34be9e55 --- /dev/null +++ b/drivers/input/touchscreen/focaltech_mmi/focaltech_upgrade_ft5422u.c @@ -0,0 +1,184 @@ +/* + * + * FocalTech fts TouchScreen driver. + * + * Copyright (c) 2012-2018, Focaltech Ltd. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +/***************************************************************************** +* +* File Name: focaltech_upgrade_ft5422u.c +* +* Author: Focaltech Driver Team +* +* Created: 2017-07-22 +* +* Abstract: +* +* Reference: +* +*****************************************************************************/ +/***************************************************************************** +* 1.Included header files +*****************************************************************************/ +#include "focaltech_flash.h" + +/***************************************************************************** +* Static function prototypes +*****************************************************************************/ +struct ft_chip_t ft5422u_fct = { + .type = 0x82, + .chip_idh = 0x54, + .chip_idl = 0x22, + .rom_idh = 0x54, + .rom_idl = 0x22, + .pramboot_idh = 0x54, + .pramboot_idl = 0x2D, + .bootloader_idh = 0x54, + .bootloader_idl = 0x2E, + .chip_type = 0x5446C482, +}; + +/************************************************************************ +* Name: fts_ft5422u_upgrade +* Brief: +* Input: +* Output: +* Return: return 0 if success, otherwise return error code +***********************************************************************/ +static int fts_ft5422u_upgrade(struct i2c_client *client, u8 *buf, u32 len) +{ + int ret = 0; + u32 start_addr = 0; + u8 cmd[4] = { 0 }; + int ecc_in_host = 0; + int ecc_in_tp = 0; + + u8 wbuf[7] = { 0 }; + u8 reg_val[4] = {0}; + u32 temp = 0; + int i; + + if (NULL == buf) { + FTS_ERROR("fw buf is null"); + return -EINVAL; + } + + if ((len < FTS_MIN_LEN) || (len > (116 * 1024))) { + FTS_ERROR("fw buffer len(%x) fail", len); + return -EINVAL; + } + + /* enter into upgrade environment */ + ret = fts_fwupg_enter_into_boot(client); + if (ret < 0) { + FTS_ERROR("enter into pramboot/bootloader fail,ret=%d", ret); + goto fw_reset; + } + + cmd[0] = FTS_CMD_FLASH_MODE; + cmd[1] = FLASH_MODE_UPGRADE_VALUE; + ret = fts_i2c_write(client, cmd, 2); + if (ret < 0) { + FTS_ERROR("upgrade mode(09) cmd write fail"); + goto fw_reset; + } + + cmd[0] = FTS_CMD_DATA_LEN; + cmd[1] = BYTE_OFF_16(len); + cmd[2] = BYTE_OFF_8(len); + cmd[3] = BYTE_OFF_0(len); + ret = fts_i2c_write(client, cmd, FTS_CMD_DATA_LEN_LEN); + if (ret < 0) { + FTS_ERROR("data len cmd write fail"); + goto fw_reset; + } + + ret = fts_fwupg_erase(client, FTS_REASE_APP_DELAY); + if (ret < 0) { + FTS_ERROR("erase cmd write fail"); + goto fw_reset; + } + + /* write app */ + start_addr = upgrade_func_ft5422u.appoff; + ecc_in_host = fts_flash_write_buf(client, start_addr, buf, len, 1); + if (ecc_in_host < 0 ) { + FTS_ERROR("lcd initial code write fail"); + goto fw_reset; + } + + FTS_DEBUG("[UPGRADE]: read out checksum!!"); + wbuf[0] = FTS_CMD_ECC_INIT; + fts_i2c_write(client, wbuf, 1); + + temp = 0; + wbuf[0] = FTS_CMD_ECC_CAL; + wbuf[1] = BYTE_OFF_16(temp); + wbuf[2] = BYTE_OFF_8(temp); + wbuf[3] = BYTE_OFF_0(temp); + + wbuf[4] = BYTE_OFF_16(len); + wbuf[5] = BYTE_OFF_8(len); + wbuf[6] = BYTE_OFF_0(len); + ret = fts_i2c_write(client, wbuf, 7); + msleep(len / 256); + + for (i = 0; i < FTS_RETRIES_ECC_CAL; i++) { + wbuf[0] = FTS_CMD_FLASH_STATUS; + reg_val[0] = reg_val[1] = 0x00; + fts_i2c_read(client, wbuf, 1, reg_val, 2); + FTS_DEBUG("[UPGRADE]: reg_val[0]=%02x reg_val[0]=%02x!!", reg_val[0], reg_val[1]); + if ((0xF0 == reg_val[0]) && (0x55 == reg_val[1])) { + break; + } + msleep(FTS_RETRIES_DELAY_ECC_CAL); + } + wbuf[0] = FTS_CMD_ECC_READ; + fts_i2c_read(client, wbuf, 1, reg_val, 1); + + ecc_in_tp = reg_val[0]; + FTS_INFO("ecc in tp:%x, host:%x", ecc_in_tp, ecc_in_host); + if (ecc_in_tp != ecc_in_host) { + FTS_ERROR("ecc check fail"); + goto fw_reset; + } + + FTS_INFO("upgrade success, reset to normal boot"); + ret = fts_fwupg_reset_in_boot(client); + if (ret < 0) { + FTS_ERROR("reset to normal boot fail"); + } + + msleep(200); + return 0; + +fw_reset: + FTS_INFO("upgrade fail, reset to normal boot"); + ret = fts_fwupg_reset_in_boot(client); + if (ret < 0) { + FTS_ERROR("reset to normal boot fail"); + } + return -EIO; +} + +struct upgrade_func upgrade_func_ft5422u = { + .ctype = {0x82}, + .fwveroff = 0x0014, + .fwcfgoff = 0xD780, + .appoff = 0x0000, + .pramboot_supported = false, + .hid_supported = true, + .fts_5422u = true, + .upgrade = fts_ft5422u_upgrade, +}; diff --git a/include/linux/input/focaltech_mmi_modules.h b/include/linux/input/focaltech_mmi_modules.h index 9d69d9b0dd54..7b676206e305 100644 --- a/include/linux/input/focaltech_mmi_modules.h +++ b/include/linux/input/focaltech_mmi_modules.h @@ -26,6 +26,7 @@ #define FT8716_ID 0x87 #define FT5X46_ID 0x54 #define FT8006U_ID 0xF0 +#define FT5422U_ID 0x22 #define MAX_PANEL_SUPPLIERS 5