6db4831e98
Android 14
3652 lines
104 KiB
C
3652 lines
104 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (c) 2019 MediaTek Inc.
|
|
*/
|
|
|
|
/*****************************************************************
|
|
*
|
|
* File Name: Focaltech_IC_Program.c
|
|
*
|
|
* Author: Xu YongFeng
|
|
*
|
|
* Created: 2015-01-29
|
|
*
|
|
* Modify by mshl on 2015-10-26
|
|
*
|
|
* Abstract:
|
|
*
|
|
* Reference:
|
|
*
|
|
*****************************************************************/
|
|
|
|
/*****************************************************************
|
|
* 1.Included header files
|
|
*****************************************************************/
|
|
#include "focaltech_core.h"
|
|
|
|
/*****************************************************************
|
|
* Private constant and macro definitions using #define
|
|
*****************************************************************/
|
|
#define FTS_REG_FW_MAJ_VER 0xB1
|
|
#define FTS_REG_FW_MIN_VER 0xB2
|
|
#define FTS_REG_FW_SUB_MIN_VER 0xB3
|
|
#define FTS_FW_MIN_SIZE 8
|
|
#define FTS_FW_MAX_SIZE (54 * 1024)
|
|
/* Firmware file is not supporting minor and sub minor so use 0 */
|
|
#define FTS_FW_FILE_MAJ_VER(x) ((x)->data[(x)->size - 2])
|
|
#define FTS_FW_FILE_MIN_VER(x) 0
|
|
#define FTS_FW_FILE_SUB_MIN_VER(x) 0
|
|
#define FTS_FW_FILE_VENDOR_ID(x) ((x)->data[(x)->size - 1])
|
|
#define FTS_FW_FILE_MAJ_VER_FT6X36(x) ((x)->data[0x10a])
|
|
#define FTS_FW_FILE_VENDOR_ID_FT6X36(x) ((x)->data[0x108])
|
|
#define FTS_MAX_TRIES 5
|
|
#define FTS_RETRY_DLY 20
|
|
#define FTS_MAX_WR_BUF 10
|
|
#define FTS_MAX_RD_BUF 2
|
|
#define FTS_FW_PKT_META_LEN 6
|
|
#define FTS_FW_PKT_DLY_MS 20
|
|
#define FTS_FW_LAST_PKT 0x6ffa
|
|
#define FTS_EARSE_DLY_MS 100
|
|
#define FTS_55_AA_DLY_NS 5000
|
|
#define FTS_CAL_START 0x04
|
|
#define FTS_CAL_FIN 0x00
|
|
#define FTS_CAL_STORE 0x05
|
|
#define FTS_CAL_RETRY 100
|
|
#define FTS_REG_CAL 0x00
|
|
#define FTS_CAL_MASK 0x70
|
|
#define FTS_BLOADER_SIZE_OFF 12
|
|
#define FTS_BLOADER_NEW_SIZE 30
|
|
#define FTS_DATA_LEN_OFF_OLD_FW 8
|
|
#define FTS_DATA_LEN_OFF_NEW_FW 14
|
|
#define FTS_FINISHING_PKT_LEN_OLD_FW 6
|
|
#define FTS_FINISHING_PKT_LEN_NEW_FW 12
|
|
#define FTS_MAGIC_BLOADER_Z7 0x7bfa
|
|
#define FTS_MAGIC_BLOADER_LZ4 0x6ffa
|
|
#define FTS_MAGIC_BLOADER_GZF_30 0x7ff4
|
|
#define FTS_MAGIC_BLOADER_GZF 0x7bf4
|
|
#define FTS_REG_ECC 0xCC
|
|
#define FTS_RST_CMD_REG2 0xBC
|
|
#define FTS_READ_ID_REG 0x90
|
|
#define FTS_ERASE_APP_REG 0x61
|
|
#define FTS_ERASE_PARAMS_CMD 0x63
|
|
#define FTS_FW_WRITE_CMD 0xBF
|
|
#define FTS_REG_RESET_FW 0x07
|
|
#define FTS_RST_CMD_REG1 0xFC
|
|
#define FTS_FACTORYMODE_VALUE 0x40
|
|
#define FTS_WORKMODE_VALUE 0x00
|
|
#define FTS_APP_INFO_ADDR 0xd7f8
|
|
|
|
#define BL_VERSION_LZ4 0
|
|
#define BL_VERSION_Z7 1
|
|
#define BL_VERSION_GZF 2
|
|
#define FTS_REG_ID 0xA3
|
|
#define FTS_REG_FW_VENDOR_ID 0xA8
|
|
|
|
#define FTS_PACKET_LENGTH 128
|
|
#define FTS_SETTING_BUF_LEN 128
|
|
|
|
#define FTS_UPGRADE_LOOP 30
|
|
#define FTS_MAX_POINTS_2 2
|
|
#define FTS_MAX_POINTS_5 5
|
|
#define FTS_MAX_POINTS_10 10
|
|
#define AUTO_CLB_NEED 1
|
|
#define AUTO_CLB_NONEED 0
|
|
#define FTS_UPGRADE_AA 0xAA
|
|
#define FTS_UPGRADE_55 0x55
|
|
#define HIDTOI2C_DISABLE 0
|
|
#define FTXXXX_INI_FILEPATH_CONFIG ""
|
|
/*****************************************************************
|
|
* Private enumerations, structures and unions using typedef
|
|
*****************************************************************/
|
|
|
|
/*****************************************************************
|
|
* Static variables
|
|
*****************************************************************/
|
|
#ifdef CONFIG_TOUCHSCREEN_FT5X26_WUXGA
|
|
static unsigned char CTPM_FW[] = {
|
|
#include "Acer_JetfireLTE_neostra_A10_4G_FT5826S_V85_D04_20170227_app.i"
|
|
};
|
|
#else
|
|
static unsigned char CTPM_FW[] = {
|
|
#include "Acer_JetfireHD_neostra_FT5826S_V16_D03_20160525_app.i"
|
|
};
|
|
#endif
|
|
|
|
#ifdef CONFIG_TOUCHSCREEN_FT5X26_WUXGA
|
|
static unsigned char TAIGUAN_FW[] = {
|
|
#include "Acer_A10L2_TaiGuan_FT5826S_V51_D04_20170117_app.i"
|
|
};
|
|
#else
|
|
static unsigned char TAIGUAN_FW[] = {
|
|
#include "Acer_JetfireHD_neostra_FT5826S_V40_D03_20161012_app.i"
|
|
};
|
|
#endif
|
|
|
|
static u8 vendor_tp_id;
|
|
/* End Neostra huangxiaohui add 20160726 */
|
|
static unsigned char aucFW_PRAM_BOOT[] = {
|
|
|
|
/* #include "FT8716_Pramboot_V0.2_20160127.i" */
|
|
/* #include "FT5822_Ref_V11_D10_20160414_app.i" */
|
|
};
|
|
|
|
struct fts_Upgrade_Info fts_updateinfo[] = {
|
|
|
|
{0x54, FTS_MAX_POINTS_5, AUTO_CLB_NONEED, 2, 2, 0x54, 0x2c, 20, 2000},
|
|
{0x55, FTS_MAX_POINTS_5, AUTO_CLB_NEED, 50, 30, 0x79, 0x03, 10, 2000},
|
|
{0x08, FTS_MAX_POINTS_5, AUTO_CLB_NEED, 50, 10, 0x79, 0x06, 100, 2000},
|
|
{0x0a, FTS_MAX_POINTS_5, AUTO_CLB_NEED, 50, 30, 0x79, 0x07, 10, 1500},
|
|
{0x06, FTS_MAX_POINTS_2, AUTO_CLB_NONEED, 100, 30, 0x79, 0x08, 10,
|
|
2000},
|
|
{0x36, FTS_MAX_POINTS_2, AUTO_CLB_NONEED, 10, 10, 0x79, 0x18, 10, 2000},
|
|
{0x64, FTS_MAX_POINTS_2, AUTO_CLB_NONEED, 10, 10, 0x79, 0x1c, 10, 2000},
|
|
{0x55, FTS_MAX_POINTS_5, AUTO_CLB_NEED, 50, 30, 0x79, 0x03, 10, 2000},
|
|
{0x14, FTS_MAX_POINTS_5, AUTO_CLB_NONEED, 30, 30, 0x79, 0x11, 10, 2000},
|
|
{0x13, FTS_MAX_POINTS_5, AUTO_CLB_NONEED, 30, 30, 0x79, 0x11, 10, 2000},
|
|
{0x12, FTS_MAX_POINTS_5, AUTO_CLB_NONEED, 30, 30, 0x79, 0x11, 10, 2000},
|
|
{0x11, FTS_MAX_POINTS_5, AUTO_CLB_NONEED, 30, 30, 0x79, 0x11, 10, 2000},
|
|
{0x58, FTS_MAX_POINTS_5, AUTO_CLB_NONEED, 2, 2, 0x58, 0x2c, 20, 2000},
|
|
{0x59, FTS_MAX_POINTS_10, AUTO_CLB_NONEED, 30, 50, 0x79, 0x10, 1, 2000},
|
|
{0x86, FTS_MAX_POINTS_10, AUTO_CLB_NONEED, 2, 2, 0x86, 0xA6, 20, 2000},
|
|
{0x87, FTS_MAX_POINTS_10, AUTO_CLB_NONEED, 2, 2, 0x87, 0xA6, 20, 2000},
|
|
{0x0E, FTS_MAX_POINTS_2, AUTO_CLB_NONEED, 10, 10, 0x79, 0x18, 10, 2000},
|
|
};
|
|
/*****************************************************************
|
|
* Global variable or extern global variabls/functions
|
|
*****************************************************************/
|
|
struct fts_Upgrade_Info fts_updateinfo_curr;
|
|
|
|
/*****************************************************************
|
|
* Name: hidi2c_to_stdi2c
|
|
* Brief: HID to I2C
|
|
* Input: i2c info
|
|
* Output: no
|
|
* Return: fail =0
|
|
*****************************************************************/
|
|
int hidi2c_to_stdi2c(struct i2c_client *client)
|
|
{
|
|
u8 auc_i2c_write_buf[5] = {0};
|
|
int bRet = 0;
|
|
#if HIDTOI2C_DISABLE
|
|
return 0;
|
|
#endif
|
|
|
|
auc_i2c_write_buf[0] = 0xeb;
|
|
auc_i2c_write_buf[1] = 0xaa;
|
|
auc_i2c_write_buf[2] = 0x09;
|
|
bRet = fts_i2c_write(client, auc_i2c_write_buf, 3);
|
|
usleep_range(10000, 11000);
|
|
auc_i2c_write_buf[0] = auc_i2c_write_buf[1] = auc_i2c_write_buf[2] = 0;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 0, auc_i2c_write_buf, 3);
|
|
|
|
if (auc_i2c_write_buf[0] == 0xeb && auc_i2c_write_buf[1] == 0xaa &&
|
|
auc_i2c_write_buf[2] == 0x08) {
|
|
pr_info("hidi2c to_stdi2c successful.\n");
|
|
bRet = 1;
|
|
} else {
|
|
pr_notice("hidi2c to_stdi2c error.\n");
|
|
bRet = 0;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* Name: fts_update_fw_vendor_id
|
|
* Brief:
|
|
* Input:
|
|
* Output: None
|
|
* Return: None
|
|
*****************************************************************/
|
|
void fts_update_fw_vendor_id(struct fts_ts_data *data)
|
|
{
|
|
struct i2c_client *client = data->client;
|
|
u8 reg_addr;
|
|
int err;
|
|
|
|
reg_addr = FTS_REG_FW_VENDOR_ID;
|
|
err = fts_i2c_read(client, ®_addr, 1, &data->fw_vendor_id, 1);
|
|
if (err < 0)
|
|
dev_notice(&client->dev, "fw vendor id read failed");
|
|
}
|
|
|
|
/*****************************************************************
|
|
* Name: fts_update_fw_ver
|
|
* Brief:
|
|
* Input:
|
|
* Output: None
|
|
* Return: None
|
|
*****************************************************************/
|
|
void fts_update_fw_ver(struct fts_ts_data *data)
|
|
{
|
|
struct i2c_client *client = data->client;
|
|
u8 reg_addr;
|
|
int err;
|
|
|
|
reg_addr = FTS_REG_FW_VER;
|
|
err = fts_i2c_read(client, ®_addr, 1, &data->fw_ver[0], 1);
|
|
if (err < 0)
|
|
dev_notice(&client->dev, "fw major version read failed");
|
|
|
|
reg_addr = FTS_REG_FW_MIN_VER;
|
|
err = fts_i2c_read(client, ®_addr, 1, &data->fw_ver[1], 1);
|
|
if (err < 0)
|
|
dev_notice(&client->dev, "fw minor version read failed");
|
|
|
|
reg_addr = FTS_REG_FW_SUB_MIN_VER;
|
|
err = fts_i2c_read(client, ®_addr, 1, &data->fw_ver[2], 1);
|
|
if (err < 0)
|
|
dev_notice(&client->dev, "fw sub minor version read failed");
|
|
|
|
dev_info(&client->dev, "Firmware version = %d.%d.%d\n", data->fw_ver[0],
|
|
data->fw_ver[1], data->fw_ver[2]);
|
|
}
|
|
|
|
/*****************************************************************
|
|
* Name: fts_ctpm_fw_upgrade_ReadVendorID
|
|
* Brief: read vendor ID
|
|
* Input: i2c info, vendor ID
|
|
* Output: no
|
|
* Return: fail <0
|
|
*****************************************************************/
|
|
int fts_ctpm_fw_upgrade_ReadVendorID(struct i2c_client *client, u8 *ucPVendorID)
|
|
{
|
|
u8 reg_val[4] = {0};
|
|
u32 i = 0;
|
|
u8 auc_i2c_write_buf[10];
|
|
int i_ret;
|
|
|
|
*ucPVendorID = 0;
|
|
i_ret = hidi2c_to_stdi2c(client);
|
|
if (i_ret == 0)
|
|
TPD_DEBUG("hidi2c change to stdi2c fail !\n");
|
|
|
|
for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
|
|
/*********Step 1:Reset CTPM *****/
|
|
fts_write_reg(client, 0xfc, FTS_UPGRADE_AA);
|
|
msleep(fts_updateinfo_curr.delay_aa);
|
|
fts_write_reg(client, 0xfc, FTS_UPGRADE_55);
|
|
msleep(200);
|
|
/*********Step 2:Enter upgrade mode *****/
|
|
i_ret = hidi2c_to_stdi2c(client);
|
|
if (i_ret == 0)
|
|
TPD_DEBUG("hidi2c change to stdi2c fail !\n");
|
|
usleep_range(10000, 11000);
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_55;
|
|
auc_i2c_write_buf[1] = FTS_UPGRADE_AA;
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 2);
|
|
if (i_ret < 0) {
|
|
TPD_DEBUG("failed writing 0x55 and 0xaa !\n");
|
|
continue;
|
|
}
|
|
/*********Step 3:check READ-ID***********************/
|
|
usleep_range(10000, 11000);
|
|
auc_i2c_write_buf[0] = 0x90;
|
|
auc_i2c_write_buf[1] = auc_i2c_write_buf[2] =
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
if (reg_val[0] == fts_updateinfo_curr.upgrade_id_1 &&
|
|
reg_val[1] == fts_updateinfo_curr.upgrade_id_2) {
|
|
TPD_DEBUG(
|
|
"[FTS] Step 3: READ OK CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
break;
|
|
}
|
|
dev_notice(&client->dev,
|
|
"[FTS] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
continue;
|
|
}
|
|
if (i >= FTS_UPGRADE_LOOP)
|
|
return -EIO;
|
|
/*********Step 4: read vendor id from app param
|
|
* area***********************/
|
|
usleep_range(10000, 11000);
|
|
auc_i2c_write_buf[0] = 0x03;
|
|
auc_i2c_write_buf[1] = 0x00;
|
|
auc_i2c_write_buf[2] = 0xd7;
|
|
auc_i2c_write_buf[3] = 0x84;
|
|
for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
|
|
fts_i2c_write(client, auc_i2c_write_buf, 4);
|
|
usleep_range(5000, 6000);
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
i_ret = fts_i2c_read(client, auc_i2c_write_buf, 0, reg_val, 2);
|
|
if (reg_val[0] != 0) {
|
|
*ucPVendorID = 0;
|
|
TPD_DEBUG(
|
|
"Vendor ID Mismatch, REG1 = 0x%x, REG2 = 0x%x, Definition:0x%x, i_ret=%d\n",
|
|
reg_val[0], reg_val[1], 0, i_ret);
|
|
} else {
|
|
*ucPVendorID = reg_val[0];
|
|
TPD_DEBUG(
|
|
"In upgrade Vendor ID, REG1 = 0x%x, REG2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
break;
|
|
}
|
|
}
|
|
msleep(50);
|
|
/*********Step 5: reset the new FW***********************/
|
|
TPD_DEBUG("Step 5: reset the new FW\n");
|
|
auc_i2c_write_buf[0] = 0x07;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(200);
|
|
i_ret = hidi2c_to_stdi2c(client);
|
|
if (i_ret == 0)
|
|
TPD_DEBUG("hidi2c change to stdi2c fail !\n");
|
|
usleep_range(10000, 11000);
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* Name: fts_ctpm_fw_upgrade_ReadProjectCode
|
|
* Brief: read project code
|
|
* Input: i2c info, project code
|
|
* Output: no
|
|
* Return: fail <0
|
|
*****************************************************************/
|
|
int fts_ctpm_fw_upgrade_ReadProjectCode(struct i2c_client *client,
|
|
char *pProjectCode)
|
|
{
|
|
u8 reg_val[4] = {0};
|
|
u32 i = 0;
|
|
u8 j = 0;
|
|
u8 auc_i2c_write_buf[10];
|
|
int i_ret;
|
|
u32 temp;
|
|
|
|
i_ret = hidi2c_to_stdi2c(client);
|
|
if (i_ret == 0)
|
|
TPD_DEBUG("hidi2c change to stdi2c fail !\n");
|
|
for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
|
|
/*********Step 1:Reset CTPM *****/
|
|
fts_write_reg(client, 0xfc, FTS_UPGRADE_AA);
|
|
msleep(fts_updateinfo_curr.delay_aa);
|
|
fts_write_reg(client, 0xfc, FTS_UPGRADE_55);
|
|
msleep(200);
|
|
/*********Step 2:Enter upgrade mode *****/
|
|
i_ret = hidi2c_to_stdi2c(client);
|
|
if (i_ret == 0)
|
|
TPD_DEBUG("hidi2c change to stdi2c fail !\n");
|
|
usleep_range(10000, 11000);
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_55;
|
|
auc_i2c_write_buf[1] = FTS_UPGRADE_AA;
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 2);
|
|
if (i_ret < 0) {
|
|
TPD_DEBUG("failed writing 0x55 and 0xaa !\n");
|
|
continue;
|
|
}
|
|
/*********Step 3:check READ-ID***********************/
|
|
usleep_range(10000, 11000);
|
|
auc_i2c_write_buf[0] = 0x90;
|
|
auc_i2c_write_buf[1] = auc_i2c_write_buf[2] =
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
if (reg_val[0] == fts_updateinfo_curr.upgrade_id_1 &&
|
|
reg_val[1] == fts_updateinfo_curr.upgrade_id_2) {
|
|
TPD_DEBUG(
|
|
"[FTS] Step 3: READ OK CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
break;
|
|
}
|
|
dev_notice(&client->dev,
|
|
"[FTS] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
continue;
|
|
}
|
|
if (i >= FTS_UPGRADE_LOOP)
|
|
return -EIO;
|
|
/*********Step 4: read vendor id from app param
|
|
* area***********************/
|
|
usleep_range(10000, 11000);
|
|
/*read project code*/
|
|
auc_i2c_write_buf[0] = 0x03;
|
|
auc_i2c_write_buf[1] = 0x00;
|
|
for (j = 0; j < 33; j++) {
|
|
temp = 0xD7A0 + j;
|
|
auc_i2c_write_buf[2] = (u8)(temp >> 8);
|
|
auc_i2c_write_buf[3] = (u8)temp;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, pProjectCode + j, 1);
|
|
if (*(pProjectCode + j) == '\0')
|
|
break;
|
|
}
|
|
pr_info("project code = %s\n", pProjectCode);
|
|
msleep(50);
|
|
/*********Step 5: reset the new FW***********************/
|
|
TPD_DEBUG("Step 5: reset the new FW\n");
|
|
auc_i2c_write_buf[0] = 0x07;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(200);
|
|
i_ret = hidi2c_to_stdi2c(client);
|
|
if (i_ret == 0)
|
|
TPD_DEBUG("hidi2c change to stdi2c fail !\n");
|
|
usleep_range(10000, 11000);
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* Name: fts_get_upgrade_array
|
|
* Brief: decide which ic
|
|
* Input: no
|
|
* Output: get ic info in fts_updateinfo_curr
|
|
* Return: no
|
|
*****************************************************************/
|
|
void fts_get_upgrade_array(void)
|
|
{
|
|
|
|
u8 chip_id;
|
|
u32 i;
|
|
int ret = 0;
|
|
#ifdef Boot_Upgrade_Protect
|
|
chip_id = FTS_CHIP_ID;
|
|
#else
|
|
ret = fts_read_reg(fts_i2c_client, FTS_REG_ID, &chip_id);
|
|
#endif
|
|
if (ret < 0)
|
|
FTS_ERR("[Focal][Touch] read value fail");
|
|
FTS_DBG("%s chip_id = %x\n", __func__, chip_id);
|
|
|
|
for (i = 0;
|
|
i < sizeof(fts_updateinfo) / sizeof(struct fts_Upgrade_Info);
|
|
i++) {
|
|
if (chip_id == fts_updateinfo[i].CHIP_ID) {
|
|
memcpy(&fts_updateinfo_curr, &fts_updateinfo[i],
|
|
sizeof(struct fts_Upgrade_Info));
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i >= sizeof(fts_updateinfo) / sizeof(struct fts_Upgrade_Info))
|
|
memcpy(&fts_updateinfo_curr, &fts_updateinfo[0],
|
|
sizeof(struct fts_Upgrade_Info));
|
|
}
|
|
|
|
/*****************************************************************
|
|
* Name: fts_ctpm_auto_clb
|
|
* Brief: auto calibration
|
|
* Input: i2c info
|
|
* Output: no
|
|
* Return: 0
|
|
*****************************************************************/
|
|
int fts_ctpm_auto_clb(struct i2c_client *client)
|
|
{
|
|
unsigned char uc_temp = 0x00;
|
|
unsigned char i = 0;
|
|
|
|
/*start auto CLB */
|
|
msleep(200);
|
|
|
|
fts_write_reg(client, 0, FTS_FACTORYMODE_VALUE);
|
|
/*make sure already enter factory mode */
|
|
msleep(100);
|
|
/*write command to start calibration */
|
|
fts_write_reg(client, 2, 0x4);
|
|
msleep(300);
|
|
if ((fts_updateinfo_curr.CHIP_ID == 0x11) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x12) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x13) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x14)) {
|
|
for (i = 0; i < 100; i++) {
|
|
fts_read_reg(client, 0x02, &uc_temp);
|
|
if (uc_temp == 0x02 || uc_temp == 0xFF)
|
|
break;
|
|
msleep(20);
|
|
}
|
|
} else {
|
|
for (i = 0; i < 100; i++) {
|
|
fts_read_reg(client, 0, &uc_temp);
|
|
if (0x0 == ((uc_temp & 0x70) >> 4))
|
|
break;
|
|
msleep(20);
|
|
}
|
|
}
|
|
fts_write_reg(client, 0, 0x40);
|
|
msleep(200);
|
|
fts_write_reg(client, 2, 0x5);
|
|
msleep(300);
|
|
fts_write_reg(client, 0, FTS_WORKMODE_VALUE);
|
|
msleep(300);
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* Name: fts_6x36_ctpm_fw_upgrade
|
|
* Brief: fw upgrade
|
|
* Input: i2c info, file buf, file len
|
|
* Output: no
|
|
* Return: fail <0
|
|
*****************************************************************/
|
|
int fts_6x36_ctpm_fw_upgrade(struct i2c_client *client, u8 *pbt_buf,
|
|
u32 dw_length)
|
|
{
|
|
u8 reg_val[2] = {0};
|
|
u32 i = 0;
|
|
u32 packet_number;
|
|
u32 j;
|
|
u32 temp;
|
|
u32 length;
|
|
u32 fw_length;
|
|
u8 packet_buf[FTS_PACKET_LENGTH + 6];
|
|
u8 auc_i2c_write_buf[10];
|
|
u8 bt_ecc;
|
|
|
|
if (pbt_buf[0] != 0x02) {
|
|
TPD_DEBUG(
|
|
"[FTS] FW first byte is not 0x02. so it is invalid\n");
|
|
return -1;
|
|
}
|
|
|
|
if (dw_length > 0x11f) {
|
|
fw_length = ((u32)pbt_buf[0x100] << 8) + pbt_buf[0x101];
|
|
if (dw_length < fw_length) {
|
|
TPD_DEBUG("[FTS] Fw length is invalid\n");
|
|
return -1;
|
|
}
|
|
} else {
|
|
TPD_DEBUG("[FTS] Fw length is invalid\n");
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
|
|
/*********Step 1:Reset CTPM *****/
|
|
fts_write_reg(client, FTS_RST_CMD_REG2, FTS_UPGRADE_AA);
|
|
msleep(fts_updateinfo_curr.delay_aa);
|
|
fts_write_reg(client, FTS_RST_CMD_REG2, FTS_UPGRADE_55);
|
|
msleep(fts_updateinfo_curr.delay_55);
|
|
/*********Step 2:Enter upgrade mode *****/
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_55;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_AA;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(fts_updateinfo_curr.delay_readid);
|
|
/*********Step 3:check READ-ID***********************/
|
|
auc_i2c_write_buf[0] = FTS_READ_ID_REG;
|
|
auc_i2c_write_buf[1] = auc_i2c_write_buf[2] =
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
reg_val[0] = 0x00;
|
|
reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
|
|
if (reg_val[0] == fts_updateinfo_curr.upgrade_id_1 &&
|
|
reg_val[1] == fts_updateinfo_curr.upgrade_id_2) {
|
|
TPD_DEBUG(
|
|
"[FTS] Step 3: GET CTPM ID OK,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
break;
|
|
}
|
|
dev_notice(
|
|
&client->dev,
|
|
"[FTS] Step 3: GET CTPM ID FAIL,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
}
|
|
if (i >= FTS_UPGRADE_LOOP)
|
|
return -EIO;
|
|
|
|
auc_i2c_write_buf[0] = FTS_READ_ID_REG;
|
|
auc_i2c_write_buf[1] = 0x00;
|
|
auc_i2c_write_buf[2] = 0x00;
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
auc_i2c_write_buf[4] = 0x00;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 5);
|
|
|
|
/*Step 4:erase app and panel paramenter area*/
|
|
TPD_DEBUG("Step 4:erase app and panel paramenter area\n");
|
|
auc_i2c_write_buf[0] = FTS_ERASE_APP_REG;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(fts_updateinfo_curr.delay_erase_flash);
|
|
|
|
for (i = 0; i < 200; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
auc_i2c_write_buf[1] = 0x00;
|
|
auc_i2c_write_buf[2] = 0x00;
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
reg_val[0] = 0x00;
|
|
reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
if (0xb0 == reg_val[0] && 0x02 == reg_val[1]) {
|
|
TPD_DEBUG("[FTS] erase app finished\n");
|
|
break;
|
|
}
|
|
msleep(50);
|
|
}
|
|
|
|
/*********Step 5:write firmware(FW) to ctpm flash*********/
|
|
bt_ecc = 0;
|
|
TPD_DEBUG("Step 5:write firmware(FW) to ctpm flash\n");
|
|
|
|
dw_length = fw_length;
|
|
packet_number = (dw_length) / FTS_PACKET_LENGTH;
|
|
packet_buf[0] = FTS_FW_WRITE_CMD;
|
|
packet_buf[1] = 0x00;
|
|
|
|
for (j = 0; j < packet_number; j++) {
|
|
temp = j * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
length = FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(length >> 8);
|
|
packet_buf[5] = (u8)length;
|
|
|
|
for (i = 0; i < FTS_PACKET_LENGTH; i++) {
|
|
packet_buf[6 + i] = pbt_buf[j * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
|
|
fts_i2c_write(client, packet_buf, FTS_PACKET_LENGTH + 6);
|
|
|
|
for (i = 0; i < 30; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
auc_i2c_write_buf[1] = 0x00;
|
|
auc_i2c_write_buf[2] = 0x00;
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
reg_val[0] = 0x00;
|
|
reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
if ((0xb0 == (reg_val[0] & 0xf0) &&
|
|
(0x03 + (j % 0x0ffd))) &&
|
|
(0xb0 ==
|
|
(((reg_val[0] & 0x0f) << 8) | reg_val[1]))) {
|
|
TPD_DEBUG(
|
|
"[FTS] write a block data finished\n");
|
|
break;
|
|
}
|
|
usleep_range(1000, 1100);
|
|
}
|
|
}
|
|
|
|
if ((dw_length) % FTS_PACKET_LENGTH > 0) {
|
|
temp = packet_number * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
temp = (dw_length) % FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(temp >> 8);
|
|
packet_buf[5] = (u8)temp;
|
|
|
|
for (i = 0; i < temp; i++) {
|
|
packet_buf[6 + i] =
|
|
pbt_buf[packet_number * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
|
|
fts_i2c_write(client, packet_buf, temp + 6);
|
|
|
|
for (i = 0; i < 30; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
auc_i2c_write_buf[1] = 0x00;
|
|
auc_i2c_write_buf[2] = 0x00;
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
reg_val[0] = 0x00;
|
|
reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
if ((0xb0 == (reg_val[0] & 0xf0) &&
|
|
(0x03 + (j % 0x0ffd))) &&
|
|
(0xb0 ==
|
|
(((reg_val[0] & 0x0f) << 8) | reg_val[1]))) {
|
|
TPD_DEBUG(
|
|
"[FTS] write a block data finished\n");
|
|
break;
|
|
}
|
|
usleep_range(1000, 1100);
|
|
}
|
|
}
|
|
|
|
/*********Step 6: read out checksum***********************/
|
|
TPD_DEBUG("Step 6: read out checksum\n");
|
|
auc_i2c_write_buf[0] = FTS_REG_ECC;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
|
|
if (reg_val[0] != bt_ecc) {
|
|
dev_notice(&client->dev,
|
|
"[FTS]--ecc error! FW=%02x bt_ecc=%02x\n",
|
|
reg_val[0], bt_ecc);
|
|
return -EIO;
|
|
}
|
|
|
|
/*********Step 7: reset the new FW***********************/
|
|
TPD_DEBUG("Step 7: reset the new FW\n");
|
|
auc_i2c_write_buf[0] = 0x07;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(300);
|
|
|
|
return 0;
|
|
}
|
|
/*****************************************************************
|
|
* Name: fts_6336GU_ctpm_fw_upgrade
|
|
* Brief: fw upgrade
|
|
* Input: i2c info, file buf, file len
|
|
* Output: no
|
|
* Return: fail <0
|
|
*****************************************************************/
|
|
int fts_6336GU_ctpm_fw_upgrade(struct i2c_client *client, u8 *pbt_buf,
|
|
u32 dw_length)
|
|
{
|
|
u8 reg_val[2] = {0};
|
|
u32 i = 0;
|
|
u32 packet_number;
|
|
u32 j;
|
|
u32 temp;
|
|
u32 length;
|
|
u32 fw_length;
|
|
u8 packet_buf[FTS_PACKET_LENGTH + 6];
|
|
u8 auc_i2c_write_buf[10];
|
|
u8 bt_ecc;
|
|
|
|
if (pbt_buf[0] != 0x02) {
|
|
TPD_DEBUG(
|
|
"[FTS] FW first byte is not 0x02. so it is invalid\n");
|
|
return -1;
|
|
}
|
|
|
|
if (dw_length > 0x11f) {
|
|
fw_length = ((u32)pbt_buf[0x100] << 8) + pbt_buf[0x101];
|
|
if (dw_length < fw_length) {
|
|
TPD_DEBUG("[FTS] Fw length is invalid\n");
|
|
return -1;
|
|
}
|
|
} else {
|
|
TPD_DEBUG("[FTS] Fw length is invalid\n");
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
|
|
/*********Step 1:Reset CTPM *****/
|
|
fts_write_reg(client, FTS_RST_CMD_REG2, FTS_UPGRADE_AA);
|
|
msleep(fts_updateinfo_curr.delay_aa);
|
|
fts_write_reg(client, FTS_RST_CMD_REG2, FTS_UPGRADE_55);
|
|
msleep(fts_updateinfo_curr.delay_55);
|
|
/*********Step 2:Enter upgrade mode *****/
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_55;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_AA;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(fts_updateinfo_curr.delay_readid);
|
|
/*********Step 3:check READ-ID***********************/
|
|
auc_i2c_write_buf[0] = FTS_READ_ID_REG;
|
|
auc_i2c_write_buf[1] = auc_i2c_write_buf[2] =
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
reg_val[0] = 0x00;
|
|
reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
|
|
if (reg_val[0] == fts_updateinfo_curr.upgrade_id_1 &&
|
|
reg_val[1] == fts_updateinfo_curr.upgrade_id_2) {
|
|
TPD_DEBUG(
|
|
"[FTS] Step 3: GET CTPM ID OK,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
break;
|
|
}
|
|
dev_notice(
|
|
&client->dev,
|
|
"[FTS] Step 3: GET CTPM ID FAIL,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
}
|
|
if (i >= FTS_UPGRADE_LOOP)
|
|
return -EIO;
|
|
|
|
auc_i2c_write_buf[0] = FTS_READ_ID_REG;
|
|
auc_i2c_write_buf[1] = 0x00;
|
|
auc_i2c_write_buf[2] = 0x00;
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
auc_i2c_write_buf[4] = 0x00;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 5);
|
|
|
|
/*Step 4:erase app and panel paramenter area*/
|
|
TPD_DEBUG("Step 4:erase app and panel paramenter area\n");
|
|
auc_i2c_write_buf[0] = FTS_ERASE_APP_REG;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(fts_updateinfo_curr.delay_erase_flash);
|
|
|
|
for (i = 0; i < 200; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
auc_i2c_write_buf[1] = 0x00;
|
|
auc_i2c_write_buf[2] = 0x00;
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
reg_val[0] = 0x00;
|
|
reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
if (0xb0 == reg_val[0] && 0x02 == reg_val[1]) {
|
|
TPD_DEBUG("[FTS] erase app finished\n");
|
|
break;
|
|
}
|
|
msleep(50);
|
|
}
|
|
|
|
/*********Step 5:write firmware(FW) to ctpm flash*********/
|
|
bt_ecc = 0;
|
|
TPD_DEBUG("Step 5:write firmware(FW) to ctpm flash\n");
|
|
|
|
dw_length = fw_length;
|
|
packet_number = (dw_length) / FTS_PACKET_LENGTH;
|
|
packet_buf[0] = FTS_FW_WRITE_CMD;
|
|
packet_buf[1] = 0x00;
|
|
|
|
for (j = 0; j < packet_number; j++) {
|
|
temp = j * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
length = FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(length >> 8);
|
|
packet_buf[5] = (u8)length;
|
|
|
|
for (i = 0; i < FTS_PACKET_LENGTH; i++) {
|
|
packet_buf[6 + i] = pbt_buf[j * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
|
|
fts_i2c_write(client, packet_buf, FTS_PACKET_LENGTH + 6);
|
|
|
|
for (i = 0; i < 30; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
auc_i2c_write_buf[1] = 0x00;
|
|
auc_i2c_write_buf[2] = 0x00;
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
reg_val[0] = 0x00;
|
|
reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
if ((0xb0 == (reg_val[0] & 0xf0) &&
|
|
(0x03 + (j % 0x0ffd))) &&
|
|
(0xb0 ==
|
|
(((reg_val[0] & 0x0f) << 8) | reg_val[1]))) {
|
|
TPD_DEBUG(
|
|
"[FTS] write a block data finished\n");
|
|
break;
|
|
}
|
|
usleep_range(1000, 1100);
|
|
}
|
|
}
|
|
|
|
if ((dw_length) % FTS_PACKET_LENGTH > 0) {
|
|
temp = packet_number * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
temp = (dw_length) % FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(temp >> 8);
|
|
packet_buf[5] = (u8)temp;
|
|
|
|
for (i = 0; i < temp; i++) {
|
|
packet_buf[6 + i] =
|
|
pbt_buf[packet_number * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
|
|
fts_i2c_write(client, packet_buf, temp + 6);
|
|
|
|
for (i = 0; i < 30; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
auc_i2c_write_buf[1] = 0x00;
|
|
auc_i2c_write_buf[2] = 0x00;
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
reg_val[0] = 0x00;
|
|
reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
if ((0xb0 == (reg_val[0] & 0xf0) &&
|
|
(0x03 + (j % 0x0ffd))) &&
|
|
(0xb0 ==
|
|
(((reg_val[0] & 0x0f) << 8) | reg_val[1]))) {
|
|
TPD_DEBUG(
|
|
"[FTS] write a block data finished\n");
|
|
break;
|
|
}
|
|
usleep_range(1000, 1100);
|
|
}
|
|
}
|
|
|
|
/*********Step 6: read out checksum***********************/
|
|
TPD_DEBUG("Step 6: read out checksum\n");
|
|
auc_i2c_write_buf[0] = FTS_REG_ECC;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
|
|
if (reg_val[0] != bt_ecc) {
|
|
dev_notice(&client->dev,
|
|
"[FTS]--ecc error! FW=%02x bt_ecc=%02x\n",
|
|
reg_val[0], bt_ecc);
|
|
return -EIO;
|
|
}
|
|
|
|
/*********Step 7: reset the new FW***********************/
|
|
TPD_DEBUG("Step 7: reset the new FW\n");
|
|
auc_i2c_write_buf[0] = 0x07;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(300);
|
|
|
|
return 0;
|
|
}
|
|
/*****************************************************************
|
|
* Name: fts_6x06_ctpm_fw_upgrade
|
|
* Brief: fw upgrade
|
|
* Input: i2c info, file buf, file len
|
|
* Output: no
|
|
* Return: fail <0
|
|
*****************************************************************/
|
|
int fts_6x06_ctpm_fw_upgrade(struct i2c_client *client, u8 *pbt_buf,
|
|
u32 dw_length)
|
|
{
|
|
u8 reg_val[2] = {0};
|
|
u32 i = 0;
|
|
u32 packet_number;
|
|
u32 j;
|
|
u32 temp;
|
|
u32 length;
|
|
u8 packet_buf[FTS_PACKET_LENGTH + 6];
|
|
u8 auc_i2c_write_buf[10];
|
|
u8 bt_ecc;
|
|
int i_ret;
|
|
|
|
for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
|
|
/*********Step 1:Reset CTPM *****/
|
|
fts_write_reg(client, FTS_RST_CMD_REG2, FTS_UPGRADE_AA);
|
|
msleep(fts_updateinfo_curr.delay_aa);
|
|
|
|
fts_write_reg(client, FTS_RST_CMD_REG2, FTS_UPGRADE_55);
|
|
|
|
msleep(fts_updateinfo_curr.delay_55);
|
|
|
|
/*********Step 2:Enter upgrade mode *****/
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_55;
|
|
auc_i2c_write_buf[1] = FTS_UPGRADE_AA;
|
|
do {
|
|
i++;
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 2);
|
|
usleep_range(5000, 6000);
|
|
} while (i_ret <= 0 && i < 5);
|
|
|
|
/*********Step 3:check READ-ID***********************/
|
|
msleep(fts_updateinfo_curr.delay_readid);
|
|
auc_i2c_write_buf[0] = FTS_READ_ID_REG;
|
|
auc_i2c_write_buf[1] = auc_i2c_write_buf[2] =
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
|
|
if (reg_val[0] == fts_updateinfo_curr.upgrade_id_1 &&
|
|
reg_val[1] == fts_updateinfo_curr.upgrade_id_2) {
|
|
TPD_DEBUG(
|
|
"[FTS] Step 3: CTPM ID OK ,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
break;
|
|
}
|
|
dev_notice(&client->dev,
|
|
"[FTS] Step 3: CTPM ID FAIL,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
}
|
|
if (i > FTS_UPGRADE_LOOP)
|
|
return -EIO;
|
|
auc_i2c_write_buf[0] = 0xcd;
|
|
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
|
|
|
|
/*Step 4:erase app and panel paramenter area*/
|
|
TPD_DEBUG("Step 4:erase app and panel paramenter area\n");
|
|
auc_i2c_write_buf[0] = FTS_ERASE_APP_REG;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(fts_updateinfo_curr.delay_erase_flash);
|
|
/*erase panel parameter area */
|
|
auc_i2c_write_buf[0] = FTS_ERASE_PARAMS_CMD;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(100);
|
|
|
|
/*********Step 5:write firmware(FW) to ctpm flash*********/
|
|
bt_ecc = 0;
|
|
TPD_DEBUG("Step 5:write firmware(FW) to ctpm flash\n");
|
|
|
|
dw_length = dw_length - 8;
|
|
packet_number = (dw_length) / FTS_PACKET_LENGTH;
|
|
packet_buf[0] = FTS_FW_WRITE_CMD;
|
|
packet_buf[1] = 0x00;
|
|
|
|
for (j = 0; j < packet_number; j++) {
|
|
temp = j * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
length = FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(length >> 8);
|
|
packet_buf[5] = (u8)length;
|
|
|
|
for (i = 0; i < FTS_PACKET_LENGTH; i++) {
|
|
packet_buf[6 + i] = pbt_buf[j * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
|
|
fts_i2c_write(client, packet_buf, FTS_PACKET_LENGTH + 6);
|
|
msleep(FTS_PACKET_LENGTH / 6 + 1);
|
|
}
|
|
|
|
if ((dw_length) % FTS_PACKET_LENGTH > 0) {
|
|
temp = packet_number * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
temp = (dw_length) % FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(temp >> 8);
|
|
packet_buf[5] = (u8)temp;
|
|
|
|
for (i = 0; i < temp; i++) {
|
|
packet_buf[6 + i] =
|
|
pbt_buf[packet_number * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
|
|
fts_i2c_write(client, packet_buf, temp + 6);
|
|
msleep(20);
|
|
}
|
|
|
|
/*send the last six byte */
|
|
for (i = 0; i < 6; i++) {
|
|
temp = 0x6ffa + i;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
temp = 1;
|
|
packet_buf[4] = (u8)(temp >> 8);
|
|
packet_buf[5] = (u8)temp;
|
|
packet_buf[6] = pbt_buf[dw_length + i];
|
|
bt_ecc ^= packet_buf[6];
|
|
fts_i2c_write(client, packet_buf, 7);
|
|
msleep(20);
|
|
}
|
|
|
|
/*********Step 6: read out checksum***********************/
|
|
/*send the opration head */
|
|
TPD_DEBUG("Step 6: read out checksum\n");
|
|
auc_i2c_write_buf[0] = FTS_REG_ECC;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
|
|
if (reg_val[0] != bt_ecc) {
|
|
dev_notice(&client->dev,
|
|
"[FTS]--ecc error! FW=%02x bt_ecc=%02x\n",
|
|
reg_val[0], bt_ecc);
|
|
return -EIO;
|
|
}
|
|
|
|
/*********Step 7: reset the new FW***********************/
|
|
TPD_DEBUG("Step 7: reset the new FW\n");
|
|
auc_i2c_write_buf[0] = FTS_REG_RESET_FW;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(300);
|
|
|
|
return 0;
|
|
}
|
|
/*****************************************************************
|
|
* Name: fts_5x26_ctpm_fw_upgrade
|
|
* Brief: fw upgrade
|
|
* Input: i2c info, file buf, file len
|
|
* Output: no
|
|
* Return: fail <0
|
|
*****************************************************************/
|
|
int fts_5x26_ctpm_fw_upgrade(struct i2c_client *client, u8 *pbt_buf,
|
|
u32 dw_length)
|
|
{
|
|
u8 reg_val[4] = {0};
|
|
u32 i = 0;
|
|
u32 packet_number;
|
|
u32 j;
|
|
u32 temp;
|
|
u32 length;
|
|
u8 packet_buf[FTS_PACKET_LENGTH + 6];
|
|
u8 auc_i2c_write_buf[10];
|
|
u8 bt_ecc;
|
|
int i_ret = 0;
|
|
|
|
for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
|
|
|
|
/*********Step 1:Reset CTPM *****/
|
|
fts_write_reg(client, 0xfc, FTS_UPGRADE_AA);
|
|
msleep(fts_updateinfo_curr.delay_aa);
|
|
fts_write_reg(client, 0xfc, FTS_UPGRADE_55);
|
|
msleep(fts_updateinfo_curr.delay_55);
|
|
|
|
/*********Step 2:Enter upgrade mode and switch protocol*****/
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_55;
|
|
auc_i2c_write_buf[1] = FTS_UPGRADE_AA;
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 2);
|
|
if (i_ret < 0) {
|
|
TPD_DEBUG("failed writing 0x55 and 0xaa !\n");
|
|
continue;
|
|
}
|
|
|
|
/*********Step 3:check READ-ID***********************/
|
|
auc_i2c_write_buf[0] = 0x90;
|
|
auc_i2c_write_buf[1] = auc_i2c_write_buf[2] =
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
if (reg_val[0] == fts_updateinfo_curr.upgrade_id_1 &&
|
|
reg_val[1] == fts_updateinfo_curr.upgrade_id_2) {
|
|
TPD_DEBUG(
|
|
"[FTS] Step 3: READ OK CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
break;
|
|
}
|
|
dev_notice(&client->dev,
|
|
"[FTS] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
continue;
|
|
}
|
|
|
|
if (i >= FTS_UPGRADE_LOOP)
|
|
return -EIO;
|
|
/*Step 4:erase app and panel paramenter area*/
|
|
TPD_DEBUG("Step 4:erase app and panel paramenter area\n");
|
|
auc_i2c_write_buf[0] = 0x61;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
/*erase app area*/
|
|
auc_i2c_write_buf[0] = 0x63;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
/*erase panel paramenter area*/
|
|
auc_i2c_write_buf[0] = 0x04;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
/*erase panel paramenter area*/
|
|
msleep(fts_updateinfo_curr.delay_erase_flash);
|
|
/*********Step 5:write firmware(FW) to ctpm flash*********/
|
|
bt_ecc = 0;
|
|
TPD_DEBUG("Step 5:write firmware(FW) to ctpm flash\n");
|
|
temp = 0;
|
|
packet_number = (dw_length) / FTS_PACKET_LENGTH;
|
|
packet_buf[0] = 0xbf;
|
|
packet_buf[1] = 0x00;
|
|
|
|
for (j = 0; j < packet_number; j++) {
|
|
temp = j * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
length = FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(length >> 8);
|
|
packet_buf[5] = (u8)length;
|
|
|
|
for (i = 0; i < FTS_PACKET_LENGTH; i++) {
|
|
packet_buf[6 + i] = pbt_buf[j * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
fts_i2c_write(client, packet_buf, FTS_PACKET_LENGTH + 6);
|
|
msleep(FTS_PACKET_LENGTH / 6 + 1);
|
|
}
|
|
|
|
if ((dw_length) % FTS_PACKET_LENGTH > 0) {
|
|
temp = packet_number * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
temp = (dw_length) % FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(temp >> 8);
|
|
packet_buf[5] = (u8)temp;
|
|
|
|
for (i = 0; i < temp; i++) {
|
|
packet_buf[6 + i] =
|
|
pbt_buf[packet_number * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
fts_i2c_write(client, packet_buf, temp + 6);
|
|
msleep(20);
|
|
}
|
|
/*********Step 6: read out checksum***********************/
|
|
TPD_DEBUG("Step 6: read out checksum\n");
|
|
auc_i2c_write_buf[0] = 0xcc;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
|
|
FTS_DBG("Checksum FT5X26:%X %X\n", reg_val[0], bt_ecc);
|
|
if (reg_val[0] != bt_ecc) {
|
|
dev_notice(&client->dev,
|
|
"[FTS]--ecc error! FW=%02x bt_ecc=%02x\n",
|
|
reg_val[0], bt_ecc);
|
|
return -EIO;
|
|
}
|
|
|
|
/*********Step 7: reset the new FW***********************/
|
|
TPD_DEBUG("Step 7: reset the new FW\n");
|
|
auc_i2c_write_buf[0] = 0x07;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
|
|
/********Step 8 Disable Write Flash*****/
|
|
TPD_DEBUG("Step 8: Disable Write Flash\n");
|
|
auc_i2c_write_buf[0] = 0x04;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
|
|
msleep(300);
|
|
auc_i2c_write_buf[0] = auc_i2c_write_buf[1] = 0x00;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 2);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* Name: fts_5x36_ctpm_fw_upgrade
|
|
* Brief: fw upgrade
|
|
* Input: i2c info, file buf, file len
|
|
* Output: no
|
|
* Return: fail <0
|
|
*****************************************************************/
|
|
int fts_5x36_ctpm_fw_upgrade(struct i2c_client *client, u8 *pbt_buf,
|
|
u32 dw_length)
|
|
{
|
|
u8 reg_val[2] = {0};
|
|
u32 i = 0;
|
|
u8 is_5336_new_bootloader = 0;
|
|
u8 is_5336_fwsize_30 = 0;
|
|
u32 packet_number;
|
|
u32 j;
|
|
u32 temp;
|
|
u32 length;
|
|
u8 packet_buf[FTS_PACKET_LENGTH + 6];
|
|
u8 auc_i2c_write_buf[10];
|
|
u8 bt_ecc;
|
|
int i_ret;
|
|
int fw_filenth = sizeof(CTPM_FW);
|
|
|
|
if (CTPM_FW[fw_filenth - 12] == 30)
|
|
is_5336_fwsize_30 = 1;
|
|
else
|
|
is_5336_fwsize_30 = 0;
|
|
|
|
for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
|
|
/*********Step 1:Reset CTPM *****/
|
|
fts_write_reg(client, FTS_RST_CMD_REG1, FTS_UPGRADE_AA);
|
|
msleep(fts_updateinfo_curr.delay_aa);
|
|
|
|
/*write 0x55 to register FTS_RST_CMD_REG1*/
|
|
fts_write_reg(client, FTS_RST_CMD_REG1, FTS_UPGRADE_55);
|
|
msleep(fts_updateinfo_curr.delay_55);
|
|
|
|
/*********Step 2:Enter upgrade mode *****/
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_55;
|
|
auc_i2c_write_buf[1] = FTS_UPGRADE_AA;
|
|
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 2);
|
|
|
|
/*********Step 3:check READ-ID***********************/
|
|
msleep(fts_updateinfo_curr.delay_readid);
|
|
auc_i2c_write_buf[0] = FTS_READ_ID_REG;
|
|
auc_i2c_write_buf[1] = auc_i2c_write_buf[2] =
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
if (reg_val[0] == fts_updateinfo_curr.upgrade_id_1 &&
|
|
reg_val[1] == fts_updateinfo_curr.upgrade_id_2) {
|
|
dev_dbg(&client->dev,
|
|
"[FTS] Step 3: CTPM ID OK,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
break;
|
|
}
|
|
dev_notice(
|
|
&client->dev,
|
|
"[FTS] Step 3: CTPM ID FAILED,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
continue;
|
|
}
|
|
|
|
if (i >= FTS_UPGRADE_LOOP)
|
|
return -EIO;
|
|
|
|
auc_i2c_write_buf[0] = 0xcd;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
|
|
/*********20130705 mshl ********************/
|
|
if (reg_val[0] <= 4)
|
|
is_5336_new_bootloader = BL_VERSION_LZ4;
|
|
else if (reg_val[0] == 7)
|
|
is_5336_new_bootloader = BL_VERSION_Z7;
|
|
else if (reg_val[0] >= 0x0f)
|
|
is_5336_new_bootloader = BL_VERSION_GZF;
|
|
|
|
/*********Step 4:erase app and panel paramenter area
|
|
* ********************/
|
|
if (is_5336_fwsize_30) {
|
|
auc_i2c_write_buf[0] = FTS_ERASE_APP_REG;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(fts_updateinfo_curr.delay_erase_flash);
|
|
|
|
auc_i2c_write_buf[0] = FTS_ERASE_PARAMS_CMD;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(50);
|
|
} else {
|
|
auc_i2c_write_buf[0] = FTS_ERASE_APP_REG;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(fts_updateinfo_curr.delay_erase_flash);
|
|
}
|
|
|
|
/*********Step 5:write firmware(FW) to ctpm flash*********/
|
|
bt_ecc = 0;
|
|
|
|
if (is_5336_new_bootloader == BL_VERSION_LZ4 ||
|
|
is_5336_new_bootloader == BL_VERSION_Z7)
|
|
dw_length = dw_length - 8;
|
|
else if (is_5336_new_bootloader == BL_VERSION_GZF)
|
|
dw_length = dw_length - 14;
|
|
packet_number = (dw_length) / FTS_PACKET_LENGTH;
|
|
packet_buf[0] = FTS_FW_WRITE_CMD;
|
|
packet_buf[1] = 0x00;
|
|
for (j = 0; j < packet_number; j++) {
|
|
temp = j * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
length = FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(length >> 8);
|
|
packet_buf[5] = (u8)length;
|
|
|
|
for (i = 0; i < FTS_PACKET_LENGTH; i++) {
|
|
packet_buf[6 + i] = pbt_buf[j * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
|
|
fts_i2c_write(client, packet_buf, FTS_PACKET_LENGTH + 6);
|
|
msleep(FTS_PACKET_LENGTH / 6 + 1);
|
|
}
|
|
|
|
if ((dw_length) % FTS_PACKET_LENGTH > 0) {
|
|
temp = packet_number * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
|
|
temp = (dw_length) % FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(temp >> 8);
|
|
packet_buf[5] = (u8)temp;
|
|
|
|
for (i = 0; i < temp; i++) {
|
|
packet_buf[6 + i] =
|
|
pbt_buf[packet_number * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
|
|
fts_i2c_write(client, packet_buf, temp + 6);
|
|
msleep(20);
|
|
}
|
|
/*send the last six byte*/
|
|
if (is_5336_new_bootloader == BL_VERSION_LZ4 ||
|
|
is_5336_new_bootloader == BL_VERSION_Z7) {
|
|
for (i = 0; i < 6; i++) {
|
|
if (is_5336_new_bootloader == BL_VERSION_Z7)
|
|
temp = 0x7bfa + i;
|
|
else if (is_5336_new_bootloader == BL_VERSION_LZ4)
|
|
temp = 0x6ffa + i;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
temp = 1;
|
|
packet_buf[4] = (u8)(temp >> 8);
|
|
packet_buf[5] = (u8)temp;
|
|
packet_buf[6] = pbt_buf[dw_length + i];
|
|
bt_ecc ^= packet_buf[6];
|
|
fts_i2c_write(client, packet_buf, 7);
|
|
usleep_range(10000, 11000);
|
|
}
|
|
} else if (is_5336_new_bootloader == BL_VERSION_GZF) {
|
|
for (i = 0; i < 12; i++) {
|
|
if (is_5336_fwsize_30)
|
|
temp = 0x7ff4 + i;
|
|
else
|
|
temp = 0x7bf4 + i;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
temp = 1;
|
|
packet_buf[4] = (u8)(temp >> 8);
|
|
packet_buf[5] = (u8)temp;
|
|
packet_buf[6] = pbt_buf[dw_length + i];
|
|
bt_ecc ^= packet_buf[6];
|
|
fts_i2c_write(client, packet_buf, 7);
|
|
usleep_range(10000, 11000);
|
|
}
|
|
}
|
|
|
|
/*********Step 6: read out checksum***********************/
|
|
auc_i2c_write_buf[0] = FTS_REG_ECC;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
|
|
if (reg_val[0] != bt_ecc) {
|
|
dev_notice(&client->dev,
|
|
"[FTS]--ecc error! FW=%02x bt_ecc=%02x\n",
|
|
reg_val[0], bt_ecc);
|
|
return -EIO;
|
|
}
|
|
/*********Step 7: reset the new FW***********************/
|
|
auc_i2c_write_buf[0] = FTS_REG_RESET_FW;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(300);
|
|
|
|
return 0;
|
|
}
|
|
/*****************************************************************
|
|
* Name: fts_5822_ctpm_fw_upgrade
|
|
* Brief: fw upgrade
|
|
* Input: i2c info, file buf, file len
|
|
* Output: no
|
|
* Return: fail <0
|
|
*****************************************************************/
|
|
int fts_5822_ctpm_fw_upgrade(struct i2c_client *client, u8 *pbt_buf,
|
|
u32 dw_length)
|
|
{
|
|
u8 reg_val[4] = {0};
|
|
u32 i = 0;
|
|
u32 packet_number;
|
|
u32 j;
|
|
u32 temp;
|
|
u32 length;
|
|
u8 packet_buf[FTS_PACKET_LENGTH + 6];
|
|
u8 auc_i2c_write_buf[10];
|
|
u8 bt_ecc;
|
|
u8 bt_ecc_check;
|
|
int i_ret;
|
|
|
|
i_ret = hidi2c_to_stdi2c(client);
|
|
if (i_ret == 0)
|
|
TPD_DEBUG("HidI2c change to StdI2c fail !\n");
|
|
|
|
for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
|
|
/*********Step 1:Reset CTPM *****/
|
|
fts_write_reg(client, 0xfc, FTS_UPGRADE_AA);
|
|
msleep(fts_updateinfo_curr.delay_aa);
|
|
fts_write_reg(client, 0xfc, FTS_UPGRADE_55);
|
|
msleep(200);
|
|
/*********Step 2:Enter upgrade mode *****/
|
|
i_ret = hidi2c_to_stdi2c(client);
|
|
if (i_ret == 0)
|
|
TPD_DEBUG("HidI2c change to StdI2c fail !\n");
|
|
usleep_range(5000, 6000);
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_55;
|
|
auc_i2c_write_buf[1] = FTS_UPGRADE_AA;
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 2);
|
|
if (i_ret < 0) {
|
|
TPD_DEBUG("failed writing 0x55 and 0xaa !\n");
|
|
continue;
|
|
}
|
|
/*********Step 3:check READ-ID***********************/
|
|
usleep_range(1000, 1100);
|
|
auc_i2c_write_buf[0] = 0x90;
|
|
auc_i2c_write_buf[1] = auc_i2c_write_buf[2] =
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
if (reg_val[0] == fts_updateinfo_curr.upgrade_id_1 &&
|
|
reg_val[1] == fts_updateinfo_curr.upgrade_id_2) {
|
|
TPD_DEBUG(
|
|
"[FTS] Step 3: READ OK CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
break;
|
|
}
|
|
dev_notice(&client->dev,
|
|
"[FTS] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
continue;
|
|
}
|
|
if (i >= FTS_UPGRADE_LOOP)
|
|
return -EIO;
|
|
/*Step 4:erase app and panel paramenter area*/
|
|
TPD_DEBUG("Step 4:erase app and panel paramenter area\n");
|
|
auc_i2c_write_buf[0] = 0x61;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(1350);
|
|
for (i = 0; i < 15; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
|
if (0xF0 == reg_val[0] && 0xAA == reg_val[1])
|
|
break;
|
|
msleep(50);
|
|
}
|
|
FTS_DBG("[FTS][%s] erase app area reg_val[0] = %x reg_val[1] = %x\n",
|
|
__func__, reg_val[0], reg_val[1]);
|
|
auc_i2c_write_buf[0] = 0xB0;
|
|
auc_i2c_write_buf[1] = (u8)((dw_length >> 16) & 0xFF);
|
|
auc_i2c_write_buf[2] = (u8)((dw_length >> 8) & 0xFF);
|
|
auc_i2c_write_buf[3] = (u8)(dw_length & 0xFF);
|
|
fts_i2c_write(client, auc_i2c_write_buf, 4);
|
|
/*********Step 5:write firmware(FW) to ctpm flash*********/
|
|
bt_ecc = 0;
|
|
bt_ecc_check = 0;
|
|
TPD_DEBUG("Step 5:write firmware(FW) to ctpm flash\n");
|
|
temp = 0;
|
|
packet_number = (dw_length) / FTS_PACKET_LENGTH;
|
|
packet_buf[0] = 0xbf;
|
|
packet_buf[1] = 0x00;
|
|
for (j = 0; j < packet_number; j++) {
|
|
temp = j * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
length = FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(length >> 8);
|
|
packet_buf[5] = (u8)length;
|
|
for (i = 0; i < FTS_PACKET_LENGTH; i++) {
|
|
packet_buf[6 + i] = pbt_buf[j * FTS_PACKET_LENGTH + i];
|
|
bt_ecc_check ^= pbt_buf[j * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
FTS_DBG("[FTS][%s] bt_ecc = %x\n", __func__, bt_ecc);
|
|
if (bt_ecc != bt_ecc_check)
|
|
FTS_DBG("[FTS][%s] error bt_ecc_check = %x\n",
|
|
__func__, bt_ecc_check);
|
|
fts_i2c_write(client, packet_buf, FTS_PACKET_LENGTH + 6);
|
|
for (i = 0; i < 30; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
|
if ((j + 0x1000) == (((reg_val[0]) << 8) | reg_val[1]))
|
|
break;
|
|
FTS_DBG("[FTS][%s] reg_val[0] = %x reg_val[1] = %x\n",
|
|
__func__, reg_val[0], reg_val[1]);
|
|
usleep_range(1000, 1100);
|
|
}
|
|
}
|
|
if ((dw_length) % FTS_PACKET_LENGTH > 0) {
|
|
temp = packet_number * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
temp = (dw_length) % FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(temp >> 8);
|
|
packet_buf[5] = (u8)temp;
|
|
for (i = 0; i < temp; i++) {
|
|
packet_buf[6 + i] =
|
|
pbt_buf[packet_number * FTS_PACKET_LENGTH + i];
|
|
bt_ecc_check ^=
|
|
pbt_buf[packet_number * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
fts_i2c_write(client, packet_buf, temp + 6);
|
|
FTS_DBG("[FTS][%s] bt_ecc = %x\n", __func__, bt_ecc);
|
|
if (bt_ecc != bt_ecc_check)
|
|
FTS_DBG("[FTS][%s] error bt_ecc_check = %x\n",
|
|
__func__, bt_ecc_check);
|
|
for (i = 0; i < 30; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
|
FTS_DBG("[FTS][%s] reg_val[0] = %x reg_val[1] = %x\n",
|
|
__func__, reg_val[0], reg_val[1]);
|
|
if ((j + 0x1000) == (((reg_val[0]) << 8) | reg_val[1]))
|
|
break;
|
|
FTS_DBG("[FTS][%s] reg_val[0] = %x reg_val[1] = %x\n",
|
|
__func__, reg_val[0], reg_val[1]);
|
|
usleep_range(1000, 1100);
|
|
}
|
|
}
|
|
msleep(50);
|
|
/*********Step 6: read out checksum***********************/
|
|
/*send the opration head */
|
|
TPD_DEBUG("Step 6: read out checksum\n");
|
|
auc_i2c_write_buf[0] = 0x64;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(300);
|
|
temp = 0;
|
|
auc_i2c_write_buf[0] = 0x65;
|
|
auc_i2c_write_buf[1] = (u8)(temp >> 16);
|
|
auc_i2c_write_buf[2] = (u8)(temp >> 8);
|
|
auc_i2c_write_buf[3] = (u8)(temp);
|
|
temp = dw_length;
|
|
auc_i2c_write_buf[4] = (u8)(temp >> 8);
|
|
auc_i2c_write_buf[5] = (u8)(temp);
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 6);
|
|
msleep(dw_length / 256);
|
|
for (i = 0; i < 100; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
|
dev_notice(&client->dev,
|
|
"[FTS]--reg_val[0]=%02x reg_val[0]=%02x\n",
|
|
reg_val[0], reg_val[1]);
|
|
if (0xF0 == reg_val[0] && 0x55 == reg_val[1]) {
|
|
dev_notice(&client->dev,
|
|
"[FTS]--reg_val[0]=%02x reg_val[0]=%02x\n",
|
|
reg_val[0], reg_val[1]);
|
|
break;
|
|
}
|
|
usleep_range(1000, 1100);
|
|
}
|
|
auc_i2c_write_buf[0] = 0x66;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
|
|
if (reg_val[0] != bt_ecc) {
|
|
dev_notice(&client->dev,
|
|
"[FTS]--ecc error! FW=%02x bt_ecc=%02x\n",
|
|
reg_val[0], bt_ecc);
|
|
return -EIO;
|
|
}
|
|
FTS_DBG("checksum %X %X\n", reg_val[0], bt_ecc);
|
|
/*********Step 7: reset the new FW***********************/
|
|
TPD_DEBUG("Step 7: reset the new FW\n");
|
|
auc_i2c_write_buf[0] = 0x07;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(200);
|
|
i_ret = hidi2c_to_stdi2c(client);
|
|
if (i_ret == 0)
|
|
TPD_DEBUG("HidI2c change to StdI2c fail !\n");
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* Name: fts_5x06_ctpm_fw_upgrade
|
|
* Brief: fw upgrade
|
|
* Input: i2c info, file buf, file len
|
|
* Output: no
|
|
* Return: fail <0
|
|
*****************************************************************/
|
|
int fts_5x06_ctpm_fw_upgrade(struct i2c_client *client, u8 *pbt_buf,
|
|
u32 dw_length)
|
|
{
|
|
u8 reg_val[2] = {0};
|
|
u32 i = 0;
|
|
u32 packet_number;
|
|
u32 j;
|
|
u32 temp;
|
|
u32 length;
|
|
u8 packet_buf[FTS_PACKET_LENGTH + 6];
|
|
u8 auc_i2c_write_buf[10];
|
|
u8 bt_ecc;
|
|
int i_ret;
|
|
|
|
for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
|
|
/*********Step 1:Reset CTPM *****/
|
|
/*write 0xaa to register FTS_RST_CMD_REG1 */
|
|
fts_write_reg(client, FTS_RST_CMD_REG1, FTS_UPGRADE_AA);
|
|
msleep(fts_updateinfo_curr.delay_aa);
|
|
|
|
/*write 0x55 to register FTS_RST_CMD_REG1 */
|
|
fts_write_reg(client, FTS_RST_CMD_REG1, FTS_UPGRADE_55);
|
|
msleep(fts_updateinfo_curr.delay_55);
|
|
/*********Step 2:Enter upgrade mode *****/
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_55;
|
|
auc_i2c_write_buf[1] = FTS_UPGRADE_AA;
|
|
do {
|
|
i++;
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 2);
|
|
usleep_range(5000, 6000);
|
|
} while (i_ret <= 0 && i < 5);
|
|
|
|
/*********Step 3:check READ-ID***********************/
|
|
msleep(fts_updateinfo_curr.delay_readid);
|
|
auc_i2c_write_buf[0] = FTS_READ_ID_REG;
|
|
auc_i2c_write_buf[1] = auc_i2c_write_buf[2] =
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
|
|
if (reg_val[0] == fts_updateinfo_curr.upgrade_id_1 &&
|
|
reg_val[1] == fts_updateinfo_curr.upgrade_id_2) {
|
|
TPD_DEBUG(
|
|
"[FTS] Step 3: CTPM ID OK,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
break;
|
|
}
|
|
dev_notice(&client->dev,
|
|
"[FTS] Step 3: CTPM ID FAIL,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
}
|
|
if (i >= FTS_UPGRADE_LOOP)
|
|
return -EIO;
|
|
/*Step 4:erase app and panel paramenter area*/
|
|
TPD_DEBUG("Step 4:erase app and panel paramenter area\n");
|
|
auc_i2c_write_buf[0] = FTS_ERASE_APP_REG;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1); /*erase app area */
|
|
msleep(fts_updateinfo_curr.delay_erase_flash);
|
|
/*erase panel parameter area */
|
|
auc_i2c_write_buf[0] = FTS_ERASE_PARAMS_CMD;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(100);
|
|
|
|
/*********Step 5:write firmware(FW) to ctpm flash*********/
|
|
bt_ecc = 0;
|
|
TPD_DEBUG("Step 5:write firmware(FW) to ctpm flash\n");
|
|
dw_length = dw_length - 8;
|
|
packet_number = (dw_length) / FTS_PACKET_LENGTH;
|
|
packet_buf[0] = FTS_FW_WRITE_CMD;
|
|
packet_buf[1] = 0x00;
|
|
for (j = 0; j < packet_number; j++) {
|
|
temp = j * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
length = FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(length >> 8);
|
|
packet_buf[5] = (u8)length;
|
|
for (i = 0; i < FTS_PACKET_LENGTH; i++) {
|
|
packet_buf[6 + i] = pbt_buf[j * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
fts_i2c_write(client, packet_buf, FTS_PACKET_LENGTH + 6);
|
|
msleep(FTS_PACKET_LENGTH / 6 + 1);
|
|
}
|
|
if ((dw_length) % FTS_PACKET_LENGTH > 0) {
|
|
temp = packet_number * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
temp = (dw_length) % FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(temp >> 8);
|
|
packet_buf[5] = (u8)temp;
|
|
for (i = 0; i < temp; i++) {
|
|
packet_buf[6 + i] =
|
|
pbt_buf[packet_number * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
|
|
fts_i2c_write(client, packet_buf, temp + 6);
|
|
msleep(20);
|
|
}
|
|
/*send the last six byte */
|
|
for (i = 0; i < 6; i++) {
|
|
temp = 0x6ffa + i;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
temp = 1;
|
|
packet_buf[4] = (u8)(temp >> 8);
|
|
packet_buf[5] = (u8)temp;
|
|
packet_buf[6] = pbt_buf[dw_length + i];
|
|
bt_ecc ^= packet_buf[6];
|
|
fts_i2c_write(client, packet_buf, 7);
|
|
msleep(20);
|
|
}
|
|
/*********Step 6: read out checksum***********************/
|
|
/*send the opration head */
|
|
TPD_DEBUG("Step 6: read out checksum\n");
|
|
auc_i2c_write_buf[0] = FTS_REG_ECC;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
|
|
if (reg_val[0] != bt_ecc) {
|
|
dev_notice(&client->dev,
|
|
"[FTS]--ecc error! FW=%02x bt_ecc=%02x\n",
|
|
reg_val[0], bt_ecc);
|
|
return -EIO;
|
|
}
|
|
/*********Step 7: reset the new FW***********************/
|
|
TPD_DEBUG("Step 7: reset the new FW\n");
|
|
auc_i2c_write_buf[0] = FTS_REG_RESET_FW;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(300); /*make sure CTP startup normally */
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* Name: fts_5x46_ctpm_fw_upgrade
|
|
* Brief: fw upgrade
|
|
* Input: i2c info, file buf, file len
|
|
* Output: no
|
|
* Return: fail <0
|
|
*****************************************************************/
|
|
int fts_5x46_ctpm_fw_upgrade(struct i2c_client *client, u8 *pbt_buf,
|
|
u32 dw_length)
|
|
{
|
|
u8 reg_val[4] = {0};
|
|
u32 i = 0;
|
|
u32 packet_number;
|
|
u32 j;
|
|
u32 temp;
|
|
u32 length;
|
|
u8 packet_buf[FTS_PACKET_LENGTH + 6];
|
|
u8 auc_i2c_write_buf[10];
|
|
u8 bt_ecc;
|
|
int i_ret;
|
|
|
|
i_ret = hidi2c_to_stdi2c(client);
|
|
if (i_ret == 0)
|
|
TPD_DEBUG("[FTS] hid change to i2c fail !\n");
|
|
|
|
for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
|
|
/*********Step 1:Reset CTPM *****/
|
|
/*write 0xaa to register FTS_RST_CMD_REG1 */
|
|
fts_write_reg(client, FTS_RST_CMD_REG1, FTS_UPGRADE_AA);
|
|
msleep(fts_updateinfo_curr.delay_aa);
|
|
|
|
/* write 0x55 to register FTS_RST_CMD_REG1 */
|
|
fts_write_reg(client, FTS_RST_CMD_REG1, FTS_UPGRADE_55);
|
|
msleep(200);
|
|
/*********Step 2:Enter upgrade mode *****/
|
|
i_ret = hidi2c_to_stdi2c(client);
|
|
|
|
if (i_ret == 0)
|
|
TPD_DEBUG("[FTS] hid change to i2c fail !\n");
|
|
usleep_range(10000, 11000);
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_55;
|
|
auc_i2c_write_buf[1] = FTS_UPGRADE_AA;
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 2);
|
|
if (i_ret < 0) {
|
|
TPD_DEBUG("[FTS] failed writing 0x55 and 0xaa !\n");
|
|
continue;
|
|
}
|
|
/*********Step 3:check READ-ID***********************/
|
|
usleep_range(1000, 1100);
|
|
auc_i2c_write_buf[0] = FTS_READ_ID_REG;
|
|
auc_i2c_write_buf[1] = auc_i2c_write_buf[2] =
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
|
|
if (reg_val[0] == fts_updateinfo_curr.upgrade_id_1 &&
|
|
reg_val[1] == fts_updateinfo_curr.upgrade_id_2) {
|
|
TPD_DEBUG(
|
|
"[FTS] Step 3: READ OK CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
break;
|
|
}
|
|
dev_notice(&client->dev,
|
|
"[FTS] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
continue;
|
|
}
|
|
if (i >= FTS_UPGRADE_LOOP)
|
|
return -EIO;
|
|
/*Step 4:erase app and panel paramenter area*/
|
|
TPD_DEBUG("Step 4:erase app and panel paramenter area\n");
|
|
auc_i2c_write_buf[0] = FTS_ERASE_APP_REG;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(1350);
|
|
for (i = 0; i < 15; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
|
if (0xF0 == reg_val[0] && 0xAA == reg_val[1])
|
|
break;
|
|
msleep(50);
|
|
}
|
|
FTS_DBG("[FTS][%s] erase app area reg_val[0] = %x reg_val[1] = %x\n",
|
|
__func__, reg_val[0], reg_val[1]);
|
|
auc_i2c_write_buf[0] = 0xB0;
|
|
auc_i2c_write_buf[1] = (u8)((dw_length >> 16) & 0xFF);
|
|
auc_i2c_write_buf[2] = (u8)((dw_length >> 8) & 0xFF);
|
|
auc_i2c_write_buf[3] = (u8)(dw_length & 0xFF);
|
|
fts_i2c_write(client, auc_i2c_write_buf, 4);
|
|
/*********Step 5:write firmware(FW) to ctpm flash*********/
|
|
bt_ecc = 0;
|
|
TPD_DEBUG("Step 5:write firmware(FW) to ctpm flash\n");
|
|
temp = 0;
|
|
packet_number = (dw_length) / FTS_PACKET_LENGTH;
|
|
packet_buf[0] = FTS_FW_WRITE_CMD;
|
|
packet_buf[1] = 0x00;
|
|
|
|
for (j = 0; j < packet_number; j++) {
|
|
temp = j * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
length = FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(length >> 8);
|
|
packet_buf[5] = (u8)length;
|
|
for (i = 0; i < FTS_PACKET_LENGTH; i++) {
|
|
packet_buf[6 + i] = pbt_buf[j * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
fts_i2c_write(client, packet_buf, FTS_PACKET_LENGTH + 6);
|
|
msleep(20);
|
|
/*
|
|
*for(i = 0;i < 30;i++)
|
|
*{
|
|
* auc_i2c_write_buf[0] = 0x6a;
|
|
* reg_val[0] = reg_val[1] = 0x00;
|
|
* fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
|
* if ((j + 0x1000) == (((reg_val[0]) << 8) | reg_val[1]))
|
|
* {
|
|
* break;
|
|
* }
|
|
* FTS_DBG("[FTS][%s] reg_val[0] = %x reg_val[1] = %x\n",
|
|
*__func__, reg_val[0], reg_val[1]);
|
|
* usleep_range(1000, 1100);
|
|
*}
|
|
*/
|
|
}
|
|
if ((dw_length) % FTS_PACKET_LENGTH > 0) {
|
|
temp = packet_number * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
temp = (dw_length) % FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(temp >> 8);
|
|
packet_buf[5] = (u8)temp;
|
|
for (i = 0; i < temp; i++) {
|
|
packet_buf[6 + i] =
|
|
pbt_buf[packet_number * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
fts_i2c_write(client, packet_buf, temp + 6);
|
|
for (i = 0; i < 30; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
|
FTS_DBG("[FTS][%s] reg_val[0] = %x reg_val[1] = %x\n",
|
|
__func__, reg_val[0], reg_val[1]);
|
|
if ((j + 0x1000) == (((reg_val[0]) << 8) | reg_val[1]))
|
|
break;
|
|
FTS_DBG("[FTS][%s] reg_val[0] = %x reg_val[1] = %x\n",
|
|
__func__, reg_val[0], reg_val[1]);
|
|
usleep_range(1000, 1100);
|
|
}
|
|
}
|
|
|
|
msleep(50);
|
|
|
|
/*********Step 6: read out checksum***********************/
|
|
/*send the opration head */
|
|
TPD_DEBUG("Step 6: read out checksum\n");
|
|
auc_i2c_write_buf[0] = 0x64;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(300);
|
|
|
|
temp = 0;
|
|
auc_i2c_write_buf[0] = 0x65;
|
|
auc_i2c_write_buf[1] = (u8)(temp >> 16);
|
|
auc_i2c_write_buf[2] = (u8)(temp >> 8);
|
|
auc_i2c_write_buf[3] = (u8)(temp);
|
|
temp = dw_length;
|
|
auc_i2c_write_buf[4] = (u8)(temp >> 8);
|
|
auc_i2c_write_buf[5] = (u8)(temp);
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 6);
|
|
msleep(dw_length / 256);
|
|
|
|
for (i = 0; i < 100; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
|
dev_notice(&client->dev,
|
|
"[FTS]--reg_val[0]=%02x reg_val[0]=%02x\n",
|
|
reg_val[0], reg_val[1]);
|
|
if (0xF0 == reg_val[0] && 0x55 == reg_val[1]) {
|
|
dev_notice(&client->dev,
|
|
"[FTS]--reg_val[0]=%02x reg_val[0]=%02x\n",
|
|
reg_val[0], reg_val[1]);
|
|
break;
|
|
}
|
|
usleep_range(1000, 1100);
|
|
}
|
|
auc_i2c_write_buf[0] = 0x66;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
|
|
if (reg_val[0] != bt_ecc) {
|
|
dev_notice(&client->dev,
|
|
"[FTS]--ecc error! FW=%02x bt_ecc=%02x\n",
|
|
reg_val[0], bt_ecc);
|
|
|
|
return -EIO;
|
|
}
|
|
FTS_DBG("checksum %X %X\n", reg_val[0], bt_ecc);
|
|
/*********Step 7: reset the new FW***********************/
|
|
TPD_DEBUG("Step 7: reset the new FW\n");
|
|
auc_i2c_write_buf[0] = FTS_REG_RESET_FW;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(200);
|
|
i_ret = hidi2c_to_stdi2c(client);
|
|
if (i_ret == 0)
|
|
TPD_DEBUG("HidI2c change to StdI2c fail !\n");
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* Name: fts_8606_writepram
|
|
* Brief: fw upgrade
|
|
* Input: i2c info, file buf, file len
|
|
* Output: no
|
|
* Return: fail <0
|
|
*****************************************************************/
|
|
int fts_8606_writepram(struct i2c_client *client, u8 *pbt_buf, u32 dw_length)
|
|
{
|
|
|
|
u8 reg_val[4] = {0};
|
|
u32 i = 0;
|
|
u32 packet_number;
|
|
u32 j;
|
|
u32 temp;
|
|
u32 length;
|
|
u8 packet_buf[FTS_PACKET_LENGTH + 6];
|
|
u8 auc_i2c_write_buf[10];
|
|
u8 bt_ecc;
|
|
int i_ret;
|
|
|
|
TPD_DEBUG("8606 dw_length= %d", dw_length);
|
|
if (dw_length > 0x10000 || dw_length == 0)
|
|
return -EIO;
|
|
|
|
for (i = 0; i < 20; i++) {
|
|
fts_write_reg(client, 0xfc, FTS_UPGRADE_AA);
|
|
msleep(fts_updateinfo_curr.delay_aa);
|
|
fts_write_reg(client, 0xfc, FTS_UPGRADE_55);
|
|
msleep(200);
|
|
/*********Step 2:Enter upgrade mode *****/
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_55;
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
if (i_ret < 0) {
|
|
TPD_DEBUG("[FTS] failed writing 0x55 !\n");
|
|
continue;
|
|
}
|
|
|
|
/*********Step 3:check READ-ID***********************/
|
|
usleep_range(1000, 1100);
|
|
auc_i2c_write_buf[0] = 0x90;
|
|
auc_i2c_write_buf[1] = auc_i2c_write_buf[2] =
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
|
|
if ((reg_val[0] == 0x86 && reg_val[1] == 0x06) ||
|
|
(reg_val[0] == 0x86 && reg_val[1] == 0x07)) {
|
|
msleep(50);
|
|
break;
|
|
}
|
|
dev_notice(&client->dev,
|
|
"[FTS] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
continue;
|
|
}
|
|
|
|
if (i >= FTS_UPGRADE_LOOP)
|
|
return -EIO;
|
|
|
|
/*********Step 4:write firmware(FW) to ctpm flash*********/
|
|
bt_ecc = 0;
|
|
TPD_DEBUG("Step 5:write firmware(FW) to ctpm flash\n");
|
|
temp = 0;
|
|
packet_number = (dw_length) / FTS_PACKET_LENGTH;
|
|
packet_buf[0] = 0xae;
|
|
packet_buf[1] = 0x00;
|
|
|
|
for (j = 0; j < packet_number; j++) {
|
|
temp = j * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
length = FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(length >> 8);
|
|
packet_buf[5] = (u8)length;
|
|
|
|
for (i = 0; i < FTS_PACKET_LENGTH; i++) {
|
|
packet_buf[6 + i] = pbt_buf[j * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
fts_i2c_write(client, packet_buf, FTS_PACKET_LENGTH + 6);
|
|
}
|
|
|
|
if ((dw_length) % FTS_PACKET_LENGTH > 0) {
|
|
temp = packet_number * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
temp = (dw_length) % FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(temp >> 8);
|
|
packet_buf[5] = (u8)temp;
|
|
|
|
for (i = 0; i < temp; i++) {
|
|
packet_buf[6 + i] =
|
|
pbt_buf[packet_number * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
fts_i2c_write(client, packet_buf, temp + 6);
|
|
}
|
|
|
|
/*********Step 5: read out checksum***********************/
|
|
/*send the opration head */
|
|
TPD_DEBUG("Step 6: read out checksum\n");
|
|
auc_i2c_write_buf[0] = 0xcc;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
|
|
if (reg_val[0] != bt_ecc) {
|
|
dev_notice(&client->dev,
|
|
"[FTS]--ecc error! FW=%02x bt_ecc=%02x\n",
|
|
reg_val[0], bt_ecc);
|
|
return -EIO;
|
|
}
|
|
TPD_DEBUG("checksum %X %X\n", reg_val[0], bt_ecc);
|
|
TPD_DEBUG("Read flash and compare\n");
|
|
|
|
msleep(50);
|
|
|
|
/*********Step 6: start app***********************/
|
|
TPD_DEBUG("Step 6: start app\n");
|
|
auc_i2c_write_buf[0] = 0x08;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(20);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* Name: fts_8606_ctpm_fw_upgrade
|
|
* Brief: fw upgrade
|
|
* Input: i2c info, file buf, file len
|
|
* Output: no
|
|
* Return: fail <0
|
|
*****************************************************************/
|
|
int fts_8606_ctpm_fw_upgrade(struct i2c_client *client, u8 *pbt_buf,
|
|
u32 dw_length)
|
|
{
|
|
u8 reg_val[4] = {0};
|
|
u8 reg_val_id[4] = {0};
|
|
u32 i = 0;
|
|
u32 packet_number;
|
|
u32 j;
|
|
u32 temp;
|
|
u32 length;
|
|
u8 packet_buf[FTS_PACKET_LENGTH + 6];
|
|
u8 auc_i2c_write_buf[10];
|
|
u8 bt_ecc;
|
|
int i_ret;
|
|
unsigned char cmd[20];
|
|
unsigned char Checksum = 0;
|
|
|
|
auc_i2c_write_buf[0] = 0x05;
|
|
reg_val_id[0] = 0x00;
|
|
|
|
i_ret = fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val_id, 1);
|
|
if (dw_length == 0)
|
|
|
|
return -EIO;
|
|
|
|
if (0x81 == (int)reg_val_id[0]) {
|
|
if (dw_length > 1024 * 60)
|
|
return -EIO;
|
|
} else if (0x80 == (int)reg_val_id[0]) {
|
|
if (dw_length > 1024 * 64)
|
|
return -EIO;
|
|
}
|
|
|
|
for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
|
|
usleep_range(10000, 11000);
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_55;
|
|
auc_i2c_write_buf[1] = FTS_UPGRADE_AA;
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 2);
|
|
if (i_ret < 0) {
|
|
TPD_DEBUG("failed writing 0x55 and 0xaa !\n");
|
|
continue;
|
|
}
|
|
|
|
/*********Step 3:check READ-ID***********************/
|
|
usleep_range(1000, 1100);
|
|
auc_i2c_write_buf[0] = 0x90;
|
|
auc_i2c_write_buf[1] = auc_i2c_write_buf[2] =
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
|
|
if ((reg_val[0] == fts_updateinfo_curr.upgrade_id_1 &&
|
|
reg_val[1] == fts_updateinfo_curr.upgrade_id_2) ||
|
|
(reg_val[0] == 0x86 && reg_val[1] == 0xA6)) {
|
|
TPD_DEBUG(
|
|
"[FTS] Step 3: READ OK CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
break;
|
|
}
|
|
dev_notice(&client->dev,
|
|
"[FTS] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
continue;
|
|
}
|
|
|
|
if (i >= FTS_UPGRADE_LOOP)
|
|
return -EIO;
|
|
|
|
/*Step 4:erase app and panel paramenter area*/
|
|
TPD_DEBUG("Step 4:erase app and panel paramenter area\n");
|
|
|
|
{
|
|
cmd[0] = 0x05;
|
|
cmd[1] = reg_val_id[0]; /* 0x80; */
|
|
cmd[2] = 0x00; /* ??? */
|
|
fts_i2c_write(client, cmd, 3);
|
|
}
|
|
|
|
{
|
|
cmd[0] = 0x09;
|
|
cmd[1] = 0x0B;
|
|
fts_i2c_write(client, cmd, 2);
|
|
}
|
|
|
|
for (i = 0; i < dw_length; i++)
|
|
Checksum ^= pbt_buf[i];
|
|
msleep(50);
|
|
|
|
auc_i2c_write_buf[0] = 0x61;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(1350);
|
|
|
|
for (i = 0; i < 15; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
|
|
|
if (0xF0 == reg_val[0] && 0xAA == reg_val[1])
|
|
break;
|
|
msleep(50);
|
|
}
|
|
|
|
bt_ecc = 0;
|
|
TPD_DEBUG("Step 5:write firmware(FW) to ctpm flash\n");
|
|
|
|
temp = 0;
|
|
packet_number = (dw_length) / FTS_PACKET_LENGTH;
|
|
packet_buf[0] = 0xbf;
|
|
|
|
for (j = 0; j < packet_number; j++) {
|
|
temp = 0x1000 + j * FTS_PACKET_LENGTH;
|
|
packet_buf[1] = (u8)(temp >> 16);
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
length = FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(length >> 8);
|
|
packet_buf[5] = (u8)length;
|
|
|
|
for (i = 0; i < FTS_PACKET_LENGTH; i++) {
|
|
packet_buf[6 + i] = pbt_buf[j * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
fts_i2c_write(client, packet_buf, FTS_PACKET_LENGTH + 6);
|
|
|
|
for (i = 0; i < 30; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
|
|
|
if ((j + 0x1000) == (((reg_val[0]) << 8) | reg_val[1]))
|
|
break;
|
|
usleep_range(1000, 1100);
|
|
}
|
|
}
|
|
|
|
if ((dw_length) % FTS_PACKET_LENGTH > 0) {
|
|
temp = 0x1000 + packet_number * FTS_PACKET_LENGTH;
|
|
packet_buf[1] = (u8)(temp >> 16);
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
temp = (dw_length) % FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(temp >> 8);
|
|
packet_buf[5] = (u8)temp;
|
|
|
|
for (i = 0; i < temp; i++) {
|
|
packet_buf[6 + i] =
|
|
pbt_buf[packet_number * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
fts_i2c_write(client, packet_buf, temp + 6);
|
|
|
|
for (i = 0; i < 30; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
|
|
|
if ((j + 0x1000) == (((reg_val[0]) << 8) | reg_val[1]))
|
|
break;
|
|
usleep_range(1000, 1100);
|
|
}
|
|
}
|
|
|
|
msleep(50);
|
|
|
|
/*********Step 6: read out checksum***********************/
|
|
/*send the opration head */
|
|
TPD_DEBUG("Step 6: read out checksum\n");
|
|
auc_i2c_write_buf[0] = 0x64;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(300);
|
|
temp = 0x1000 + 0;
|
|
|
|
auc_i2c_write_buf[0] = 0x65;
|
|
auc_i2c_write_buf[1] = (u8)(temp >> 16);
|
|
auc_i2c_write_buf[2] = (u8)(temp >> 8);
|
|
auc_i2c_write_buf[3] = (u8)(temp);
|
|
|
|
if (dw_length > LEN_FLASH_ECC_MAX)
|
|
temp = LEN_FLASH_ECC_MAX;
|
|
else {
|
|
temp = dw_length;
|
|
TPD_DEBUG("Step 6_1: read out checksum\n");
|
|
}
|
|
auc_i2c_write_buf[4] = (u8)(temp >> 8);
|
|
auc_i2c_write_buf[5] = (u8)(temp);
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 6);
|
|
msleep(dw_length / 256);
|
|
|
|
for (i = 0; i < 100; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
|
|
|
if (0xF0 == reg_val[0] && 0x55 == reg_val[1])
|
|
break;
|
|
usleep_range(1000, 1100);
|
|
}
|
|
|
|
if (dw_length > LEN_FLASH_ECC_MAX) {
|
|
temp = LEN_FLASH_ECC_MAX; /* ??? 0x1000+LEN_FLASH_ECC_MAX */
|
|
auc_i2c_write_buf[0] = 0x65;
|
|
auc_i2c_write_buf[1] = (u8)(temp >> 16);
|
|
auc_i2c_write_buf[2] = (u8)(temp >> 8);
|
|
auc_i2c_write_buf[3] = (u8)(temp);
|
|
temp = dw_length - LEN_FLASH_ECC_MAX;
|
|
auc_i2c_write_buf[4] = (u8)(temp >> 8);
|
|
auc_i2c_write_buf[5] = (u8)(temp);
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 6);
|
|
|
|
msleep(dw_length / 256);
|
|
|
|
for (i = 0; i < 100; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
|
|
|
if (0xF0 == reg_val[0] && 0x55 == reg_val[1])
|
|
break;
|
|
usleep_range(1000, 1100);
|
|
}
|
|
}
|
|
auc_i2c_write_buf[0] = 0x66;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
|
|
if (reg_val[0] != bt_ecc) {
|
|
dev_notice(&client->dev,
|
|
"[FTS]--ecc error! FW=%02x bt_ecc=%02x\n",
|
|
reg_val[0], bt_ecc);
|
|
|
|
return -EIO;
|
|
}
|
|
TPD_DEBUG("checksum %X %X\n", reg_val[0], bt_ecc);
|
|
/*********Step 7: reset the new FW***********************/
|
|
TPD_DEBUG("Step 7: reset the new FW\n");
|
|
auc_i2c_write_buf[0] = 0x07;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(200); /* make sure CTP startup normally */
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* Name: fts_8716_ctpm_fw_write_pram
|
|
* Brief: fw upgrade
|
|
* Input: i2c info, file buf, file len
|
|
* Output: no
|
|
* Return: fail <0
|
|
*****************************************************************/
|
|
int fts_8716_writepram(struct i2c_client *client, u8 *pbt_buf, u32 dw_length)
|
|
{
|
|
|
|
u8 reg_val[4] = {0};
|
|
u32 i = 0;
|
|
u32 packet_number;
|
|
u32 j;
|
|
u32 temp;
|
|
u32 length;
|
|
u8 packet_buf[FTS_PACKET_LENGTH + 6];
|
|
u8 auc_i2c_write_buf[10];
|
|
u8 bt_ecc;
|
|
int i_ret;
|
|
|
|
TPD_DEBUG("8716 dw_length= %d", dw_length);
|
|
if (dw_length > 0x10000 || dw_length == 0)
|
|
return -EIO;
|
|
|
|
for (i = 0; i < 20; i++) {
|
|
fts_write_reg(client, 0xfc, FTS_UPGRADE_AA);
|
|
msleep(fts_updateinfo_curr.delay_aa);
|
|
fts_write_reg(client, 0xfc, FTS_UPGRADE_55);
|
|
msleep(200);
|
|
/********* Step 2:Enter upgrade mode *****/
|
|
|
|
i_ret = hidi2c_to_stdi2c(client);
|
|
if (i_ret == 0)
|
|
TPD_DEBUG("[FTS] hid change to i2c fail !\n");
|
|
|
|
usleep_range(10000, 11000);
|
|
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_55;
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
if (i_ret < 0) {
|
|
TPD_DEBUG("[FTS] failed writing 0x55 !\n");
|
|
continue;
|
|
}
|
|
|
|
/********* Step 3:check READ-ID ***********************/
|
|
usleep_range(1000, 1100);
|
|
auc_i2c_write_buf[0] = 0x90;
|
|
auc_i2c_write_buf[1] = auc_i2c_write_buf[2] =
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
|
|
if ((reg_val[0] == 0x87 && reg_val[1] == 0x16)) {
|
|
TPD_DEBUG(
|
|
"[FTS] Step 3: READ CTPM ID OK,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
break;
|
|
}
|
|
dev_notice(
|
|
&client->dev,
|
|
"[FTS] Step 3: READ CTPM ID FAIL,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
continue;
|
|
}
|
|
|
|
if (i >= FTS_UPGRADE_LOOP)
|
|
return -EIO;
|
|
|
|
/********* Step 4:write firmware(FW) to ctpm flash *********/
|
|
bt_ecc = 0;
|
|
TPD_DEBUG("Step 5:write firmware(FW) to ctpm flash\n");
|
|
|
|
temp = 0;
|
|
packet_number = (dw_length) / FTS_PACKET_LENGTH;
|
|
packet_buf[0] = 0xae;
|
|
packet_buf[1] = 0x00;
|
|
|
|
for (j = 0; j < packet_number; j++) {
|
|
temp = j * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
length = FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(length >> 8);
|
|
packet_buf[5] = (u8)length;
|
|
|
|
for (i = 0; i < FTS_PACKET_LENGTH; i++) {
|
|
packet_buf[6 + i] = pbt_buf[j * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
fts_i2c_write(client, packet_buf, FTS_PACKET_LENGTH + 6);
|
|
}
|
|
|
|
if ((dw_length) % FTS_PACKET_LENGTH > 0) {
|
|
temp = packet_number * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
temp = (dw_length) % FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(temp >> 8);
|
|
packet_buf[5] = (u8)temp;
|
|
|
|
for (i = 0; i < temp; i++) {
|
|
packet_buf[6 + i] =
|
|
pbt_buf[packet_number * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
fts_i2c_write(client, packet_buf, temp + 6);
|
|
}
|
|
|
|
/********* Step 5: read out checksum ***********************/
|
|
/* send the opration head */
|
|
TPD_DEBUG("Step 6: read out checksum\n");
|
|
auc_i2c_write_buf[0] = 0xcc;
|
|
usleep_range(2000, 2100);
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
|
|
if (reg_val[0] != bt_ecc) {
|
|
dev_notice(&client->dev,
|
|
"[FTS]--ecc error! FW=%02x bt_ecc=%02x\n",
|
|
reg_val[0], bt_ecc);
|
|
return -EIO;
|
|
}
|
|
FTS_DBG("checksum %X %X\n", reg_val[0], bt_ecc);
|
|
msleep(100);
|
|
|
|
/********* Step 6: start app ***********************/
|
|
TPD_DEBUG("Step 6: start app\n");
|
|
auc_i2c_write_buf[0] = 0x08;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(20);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* Name: fts_8716_ctpm_fw_upgrade
|
|
* Brief: fw upgrade
|
|
* Input: i2c info, file buf, file len
|
|
* Output: no
|
|
* Return: fail <0
|
|
*****************************************************************/
|
|
int fts_8716_ctpm_fw_upgrade(struct i2c_client *client, u8 *pbt_buf,
|
|
u32 dw_length)
|
|
{
|
|
u8 reg_val[4] = {0};
|
|
u8 reg_val_id[4] = {0};
|
|
u32 i = 0;
|
|
u32 packet_number;
|
|
u32 j;
|
|
u32 temp;
|
|
u32 length;
|
|
u8 packet_buf[FTS_PACKET_LENGTH + 6];
|
|
u8 auc_i2c_write_buf[10];
|
|
u8 bt_ecc;
|
|
int i_ret;
|
|
unsigned char cmd[20];
|
|
unsigned char Checksum = 0;
|
|
|
|
i_ret = hidi2c_to_stdi2c(client);
|
|
if (i_ret == 0)
|
|
TPD_DEBUG("[FTS] hid change to i2c fail !\n");
|
|
|
|
auc_i2c_write_buf[0] = 0x05;
|
|
reg_val_id[0] = 0x00;
|
|
|
|
i_ret = fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val_id, 1);
|
|
|
|
if (dw_length == 0)
|
|
return -EIO;
|
|
|
|
if (0x81 == (int)reg_val_id[0]) {
|
|
if (dw_length > 1024 * 60)
|
|
return -EIO;
|
|
} else if (0x80 == (int)reg_val_id[0]) {
|
|
if (dw_length > 1024 * 64)
|
|
return -EIO;
|
|
}
|
|
|
|
for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
|
|
/********* Step 1:Reset CTPM *****/
|
|
usleep_range(10000, 11000);
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_55;
|
|
auc_i2c_write_buf[1] = FTS_UPGRADE_AA;
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 2);
|
|
if (i_ret < 0) {
|
|
TPD_DEBUG("failed writing 0x55 and 0xaa !\n");
|
|
continue;
|
|
}
|
|
|
|
/********* Step 3:check READ-ID ***********************/
|
|
usleep_range(1000, 1100);
|
|
auc_i2c_write_buf[0] = 0x90;
|
|
auc_i2c_write_buf[1] = auc_i2c_write_buf[2] =
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
|
|
if ((reg_val[0] == fts_updateinfo_curr.upgrade_id_1 &&
|
|
reg_val[1] == fts_updateinfo_curr.upgrade_id_2)
|
|
/*|| (reg_val[0] == 0x87 && reg_val[1] == 0xA6)*/) {
|
|
TPD_DEBUG(
|
|
"[FTS] Step 3: READ OK CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
break;
|
|
}
|
|
dev_notice(
|
|
&client->dev,
|
|
"[FTS] Step 3: READ FAIL CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
continue;
|
|
}
|
|
if (i >= FTS_UPGRADE_LOOP)
|
|
return -EIO;
|
|
/* Step 4:erase app and panel paramenter area */
|
|
TPD_DEBUG("Step 4:erase app and panel paramenter area\n");
|
|
|
|
{
|
|
cmd[0] = 0x05;
|
|
cmd[1] = reg_val_id[0]; /* 0x80; */
|
|
cmd[2] = 0x00;
|
|
fts_i2c_write(client, cmd, 3);
|
|
}
|
|
|
|
{
|
|
cmd[0] = 0x09;
|
|
cmd[1] = 0x0B;
|
|
fts_i2c_write(client, cmd, 2);
|
|
}
|
|
for (i = 0; i < dw_length; i++)
|
|
|
|
Checksum ^= pbt_buf[i];
|
|
msleep(50);
|
|
|
|
auc_i2c_write_buf[0] = 0x61;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(1350);
|
|
|
|
for (i = 0; i < 15; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
|
|
|
if (0xF0 == reg_val[0] && 0xAA == reg_val[1])
|
|
break;
|
|
msleep(50);
|
|
}
|
|
|
|
/********* Step 5:write firmware(FW) to ctpm flash *********/
|
|
bt_ecc = 0;
|
|
TPD_DEBUG("Step 5:write firmware(FW) to ctpm flash\n");
|
|
|
|
temp = 0;
|
|
packet_number = (dw_length) / FTS_PACKET_LENGTH;
|
|
packet_buf[0] = 0xbf;
|
|
for (j = 0; j < packet_number; j++) {
|
|
temp = 0x1000 + j * FTS_PACKET_LENGTH;
|
|
packet_buf[1] = (u8)(temp >> 16);
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
length = FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(length >> 8);
|
|
packet_buf[5] = (u8)length;
|
|
|
|
for (i = 0; i < FTS_PACKET_LENGTH; i++) {
|
|
packet_buf[6 + i] = pbt_buf[j * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
fts_i2c_write(client, packet_buf, FTS_PACKET_LENGTH + 6);
|
|
|
|
for (i = 0; i < 30; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
|
|
|
if ((j + 0x22 + 0x1000) ==
|
|
(((reg_val[0]) << 8) | reg_val[1]))
|
|
break;
|
|
usleep_range(1000, 1100);
|
|
}
|
|
}
|
|
|
|
if ((dw_length) % FTS_PACKET_LENGTH > 0) {
|
|
temp = 0x1000 + packet_number * FTS_PACKET_LENGTH;
|
|
packet_buf[1] = (u8)(temp >> 16);
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
temp = (dw_length) % FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(temp >> 8);
|
|
packet_buf[5] = (u8)temp;
|
|
|
|
for (i = 0; i < temp; i++) {
|
|
packet_buf[6 + i] =
|
|
pbt_buf[packet_number * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
fts_i2c_write(client, packet_buf, temp + 6);
|
|
|
|
for (i = 0; i < 30; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
|
|
|
if ((j + 0x22 + 0x1000) ==
|
|
(((reg_val[0]) << 8) | reg_val[1]))
|
|
break;
|
|
usleep_range(1000, 1100);
|
|
}
|
|
}
|
|
|
|
msleep(50);
|
|
|
|
/********* Step 6: read out checksum ***********************/
|
|
/*send the opration head */
|
|
TPD_DEBUG("Step 6: read out checksum\n");
|
|
auc_i2c_write_buf[0] = 0x64;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(300);
|
|
|
|
temp = 0x1000 + 0;
|
|
|
|
auc_i2c_write_buf[0] = 0x65;
|
|
auc_i2c_write_buf[1] = (u8)(temp >> 16);
|
|
auc_i2c_write_buf[2] = (u8)(temp >> 8);
|
|
auc_i2c_write_buf[3] = (u8)(temp);
|
|
|
|
if (dw_length > LEN_FLASH_ECC_MAX)
|
|
temp = LEN_FLASH_ECC_MAX;
|
|
else {
|
|
temp = dw_length;
|
|
TPD_DEBUG("Step 6_1: read out checksum\n");
|
|
}
|
|
auc_i2c_write_buf[4] = (u8)(temp >> 8);
|
|
auc_i2c_write_buf[5] = (u8)(temp);
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 6);
|
|
msleep(dw_length / 256);
|
|
|
|
for (i = 0; i < 100; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
|
|
|
if (0xF0 == reg_val[0] && 0x55 == reg_val[1])
|
|
break;
|
|
usleep_range(1000, 1100);
|
|
}
|
|
|
|
if (dw_length > LEN_FLASH_ECC_MAX) {
|
|
temp = LEN_FLASH_ECC_MAX;
|
|
auc_i2c_write_buf[0] = 0x65;
|
|
auc_i2c_write_buf[1] = (u8)(temp >> 16);
|
|
auc_i2c_write_buf[2] = (u8)(temp >> 8);
|
|
auc_i2c_write_buf[3] = (u8)(temp);
|
|
temp = dw_length - LEN_FLASH_ECC_MAX;
|
|
auc_i2c_write_buf[4] = (u8)(temp >> 8);
|
|
auc_i2c_write_buf[5] = (u8)(temp);
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 6);
|
|
|
|
msleep(dw_length / 256);
|
|
|
|
for (i = 0; i < 100; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
reg_val[0] = reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 2);
|
|
|
|
if (0xF0 == reg_val[0] && 0x55 == reg_val[1])
|
|
break;
|
|
usleep_range(1000, 1100);
|
|
}
|
|
}
|
|
auc_i2c_write_buf[0] = 0x66;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
|
|
if (reg_val[0] != bt_ecc) {
|
|
dev_notice(&client->dev,
|
|
"[FTS]--ecc error! FW=%02x bt_ecc=%02x\n",
|
|
reg_val[0], bt_ecc);
|
|
return -EIO;
|
|
}
|
|
FTS_DBG("checksum %X %X\n", reg_val[0], bt_ecc);
|
|
/********* Step 7: reset the new FW ***********************/
|
|
TPD_DEBUG("Step 7: reset the new FW\n");
|
|
auc_i2c_write_buf[0] = 0x07;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(200);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* Name: fts_3x07_ctpm_fw_upgrade
|
|
* Brief: fw upgrade
|
|
* Input: i2c info, file buf, file len
|
|
* Output: no
|
|
* Return: fail <0
|
|
*****************************************************************/
|
|
int fts_3x07_ctpm_fw_upgrade(struct i2c_client *client, u8 *pbt_buf,
|
|
u32 dw_length)
|
|
{
|
|
u8 reg_val[2] = {0};
|
|
u32 i = 0;
|
|
u32 packet_number;
|
|
u32 j;
|
|
u32 temp;
|
|
u32 length;
|
|
u32 fw_length;
|
|
u8 packet_buf[FTS_PACKET_LENGTH + 6];
|
|
u8 auc_i2c_write_buf[10];
|
|
u8 bt_ecc;
|
|
|
|
if (pbt_buf[0] != 0x02) {
|
|
TPD_DEBUG(
|
|
"[FTS] FW first byte is not 0x02. so it is invalid\n");
|
|
return -1;
|
|
}
|
|
|
|
if (dw_length > 0x11f) {
|
|
fw_length = ((u32)pbt_buf[0x100] << 8) + pbt_buf[0x101];
|
|
if (dw_length < fw_length) {
|
|
TPD_DEBUG("[FTS] Fw length is invalid\n");
|
|
return -1;
|
|
}
|
|
} else {
|
|
TPD_DEBUG("[FTS] Fw length is invalid\n");
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
|
|
/*********Step 1:Reset CTPM *****/
|
|
fts_write_reg(client, FTS_RST_CMD_REG2, FTS_UPGRADE_AA);
|
|
msleep(fts_updateinfo_curr.delay_aa);
|
|
fts_write_reg(client, FTS_RST_CMD_REG2, FTS_UPGRADE_55);
|
|
msleep(fts_updateinfo_curr.delay_55);
|
|
/*********Step 2:Enter upgrade mode *****/
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_55;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_AA;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(fts_updateinfo_curr.delay_readid);
|
|
/*********Step 3:check READ-ID***********************/
|
|
auc_i2c_write_buf[0] = FTS_READ_ID_REG;
|
|
auc_i2c_write_buf[1] = auc_i2c_write_buf[2] =
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
reg_val[0] = 0x00;
|
|
reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
|
|
if (reg_val[0] == fts_updateinfo_curr.upgrade_id_1 &&
|
|
reg_val[1] == fts_updateinfo_curr.upgrade_id_2) {
|
|
TPD_DEBUG(
|
|
"[FTS] Step 3: GET CTPM ID OK,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
break;
|
|
}
|
|
dev_notice(
|
|
&client->dev,
|
|
"[FTS] Step 3: GET CTPM ID FAIL,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
}
|
|
if (i >= FTS_UPGRADE_LOOP)
|
|
return -EIO;
|
|
|
|
auc_i2c_write_buf[0] = FTS_READ_ID_REG;
|
|
auc_i2c_write_buf[1] = 0x00;
|
|
auc_i2c_write_buf[2] = 0x00;
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
auc_i2c_write_buf[4] = 0x00;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 5);
|
|
|
|
/*Step 4:erase app and panel paramenter area*/
|
|
TPD_DEBUG("Step 4:erase app and panel paramenter area\n");
|
|
auc_i2c_write_buf[0] = FTS_ERASE_APP_REG;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(fts_updateinfo_curr.delay_erase_flash);
|
|
|
|
for (i = 0; i < 200; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
auc_i2c_write_buf[1] = 0x00;
|
|
auc_i2c_write_buf[2] = 0x00;
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
reg_val[0] = 0x00;
|
|
reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
if (0xb0 == reg_val[0] && 0x02 == reg_val[1]) {
|
|
TPD_DEBUG("[FTS] erase app finished\n");
|
|
break;
|
|
}
|
|
msleep(50);
|
|
}
|
|
|
|
/*********Step 5:write firmware(FW) to ctpm flash*********/
|
|
bt_ecc = 0;
|
|
TPD_DEBUG("Step 5:write firmware(FW) to ctpm flash\n");
|
|
|
|
dw_length = fw_length;
|
|
packet_number = (dw_length) / FTS_PACKET_LENGTH;
|
|
packet_buf[0] = FTS_FW_WRITE_CMD;
|
|
packet_buf[1] = 0x00;
|
|
|
|
for (j = 0; j < packet_number; j++) {
|
|
temp = j * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
length = FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(length >> 8);
|
|
packet_buf[5] = (u8)length;
|
|
|
|
for (i = 0; i < FTS_PACKET_LENGTH; i++) {
|
|
packet_buf[6 + i] = pbt_buf[j * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
|
|
fts_i2c_write(client, packet_buf, FTS_PACKET_LENGTH + 6);
|
|
|
|
for (i = 0; i < 30; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
auc_i2c_write_buf[1] = 0x00;
|
|
auc_i2c_write_buf[2] = 0x00;
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
reg_val[0] = 0x00;
|
|
reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
if ((0xb0 == (reg_val[0] & 0xf0) &&
|
|
(0x03 + (j % 0x0ffd))) &&
|
|
(0xb0 ==
|
|
(((reg_val[0] & 0x0f) << 8) | reg_val[1]))) {
|
|
TPD_DEBUG(
|
|
"[FTS] write a block data finished\n");
|
|
break;
|
|
}
|
|
usleep_range(1000, 1100);
|
|
}
|
|
}
|
|
|
|
if ((dw_length) % FTS_PACKET_LENGTH > 0) {
|
|
temp = packet_number * FTS_PACKET_LENGTH;
|
|
packet_buf[2] = (u8)(temp >> 8);
|
|
packet_buf[3] = (u8)temp;
|
|
temp = (dw_length) % FTS_PACKET_LENGTH;
|
|
packet_buf[4] = (u8)(temp >> 8);
|
|
packet_buf[5] = (u8)temp;
|
|
|
|
for (i = 0; i < temp; i++) {
|
|
packet_buf[6 + i] =
|
|
pbt_buf[packet_number * FTS_PACKET_LENGTH + i];
|
|
bt_ecc ^= packet_buf[6 + i];
|
|
}
|
|
|
|
fts_i2c_write(client, packet_buf, temp + 6);
|
|
|
|
for (i = 0; i < 30; i++) {
|
|
auc_i2c_write_buf[0] = 0x6a;
|
|
auc_i2c_write_buf[1] = 0x00;
|
|
auc_i2c_write_buf[2] = 0x00;
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
reg_val[0] = 0x00;
|
|
reg_val[1] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
if ((0xb0 == (reg_val[0] & 0xf0) &&
|
|
(0x03 + (j % 0x0ffd))) &&
|
|
(0xb0 ==
|
|
(((reg_val[0] & 0x0f) << 8) | reg_val[1]))) {
|
|
TPD_DEBUG(
|
|
"[FTS] write a block data finished\n");
|
|
break;
|
|
}
|
|
usleep_range(1000, 1100);
|
|
}
|
|
}
|
|
|
|
/*********Step 6: read out checksum***********************/
|
|
TPD_DEBUG("Step 6: read out checksum\n");
|
|
auc_i2c_write_buf[0] = FTS_REG_ECC;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
|
|
if (reg_val[0] != bt_ecc) {
|
|
dev_notice(&client->dev,
|
|
"[FTS]--ecc error! FW=%02x bt_ecc=%02x\n",
|
|
reg_val[0], bt_ecc);
|
|
return -EIO;
|
|
}
|
|
|
|
/*********Step 7: reset the new FW***********************/
|
|
TPD_DEBUG("Step 7: reset the new FW\n");
|
|
auc_i2c_write_buf[0] = 0x07;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(300);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* Name: fts_ReadFirmware
|
|
* Brief: read firmware buf for .bin file.
|
|
* Input: file name, data buf
|
|
* Output: data buf
|
|
* Return: 0
|
|
*****************************************************************/
|
|
/*
|
|
* note:the firmware default path is sdcard.
|
|
* if you want to change the dir, please modify by yourself.
|
|
*/
|
|
static int fts_ReadFirmware(char *firmware_name, unsigned char *firmware_buf)
|
|
{
|
|
struct file *pfile = NULL;
|
|
struct inode *inode;
|
|
unsigned long magic;
|
|
off_t fsize;
|
|
char filepath[128];
|
|
loff_t pos;
|
|
mm_segment_t old_fs;
|
|
|
|
memset(filepath, 0, sizeof(filepath));
|
|
sprintf(filepath, "%s%s", FTXXXX_INI_FILEPATH_CONFIG, firmware_name);
|
|
if (pfile == NULL)
|
|
pfile = filp_open(filepath, O_RDONLY, 0);
|
|
if (IS_ERR(pfile)) {
|
|
pr_notice("error occurred while opening file %s.\n", filepath);
|
|
return -EIO;
|
|
}
|
|
inode = pfile->f_path.dentry->d_inode;
|
|
magic = inode->i_sb->s_magic;
|
|
fsize = inode->i_size;
|
|
old_fs = get_fs();
|
|
set_fs(KERNEL_DS);
|
|
pos = 0;
|
|
vfs_read(pfile, firmware_buf, fsize, &pos);
|
|
filp_close(pfile, NULL);
|
|
set_fs(old_fs);
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* Name: fts_ctpm_fw_upgrade_with_app_file
|
|
* Brief: upgrade with *.bin file
|
|
* Input: i2c info, file name
|
|
* Output: no
|
|
* Return: success =0
|
|
*****************************************************************/
|
|
int fts_ctpm_fw_upgrade_with_app_file(struct i2c_client *client,
|
|
char *firmware_name)
|
|
{
|
|
u8 *pbt_buf = NULL;
|
|
int i_ret = 0;
|
|
int fwsize = 0;
|
|
|
|
FTS_DBG("***fts ctpm_fw_upgrade_with_app_file start****\n");
|
|
|
|
if (fwsize <= 0) {
|
|
dev_notice(&client->dev, "%s ERROR:Get firmware size failed\n",
|
|
__func__);
|
|
return -EIO;
|
|
}
|
|
if (fwsize < 8 || fwsize > 54 * 1024) {
|
|
dev_notice(&client->dev, "FW length error\n");
|
|
return -EIO;
|
|
}
|
|
/*=========FW upgrade========================*/
|
|
pbt_buf = kmalloc(fwsize + 1, GFP_ATOMIC);
|
|
if (fts_ReadFirmware(firmware_name, pbt_buf)) {
|
|
dev_notice(&client->dev,
|
|
"%s() - ERROR: request_firmware failed\n", __func__);
|
|
kfree(pbt_buf);
|
|
return -EIO;
|
|
}
|
|
if ((fts_updateinfo_curr.CHIP_ID == 0x55) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x08) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x0a))
|
|
i_ret = fts_5x06_ctpm_fw_upgrade(client, pbt_buf, fwsize);
|
|
else if ((fts_updateinfo_curr.CHIP_ID == 0x11) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x12) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x13) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x14))
|
|
i_ret = fts_5x36_ctpm_fw_upgrade(client, pbt_buf, fwsize);
|
|
else if (fts_updateinfo_curr.CHIP_ID == 0x06)
|
|
i_ret = fts_6x06_ctpm_fw_upgrade(client, pbt_buf, fwsize);
|
|
else if (fts_updateinfo_curr.CHIP_ID == 0x36)
|
|
i_ret = fts_6x36_ctpm_fw_upgrade(client, pbt_buf, fwsize);
|
|
else if (fts_updateinfo_curr.CHIP_ID == 0x64)
|
|
i_ret = fts_6336GU_ctpm_fw_upgrade(client, pbt_buf, fwsize);
|
|
else if (fts_updateinfo_curr.CHIP_ID == 0x54)
|
|
i_ret = fts_5x46_ctpm_fw_upgrade(client, pbt_buf, fwsize);
|
|
else if (fts_updateinfo_curr.CHIP_ID == 0x58)
|
|
i_ret = fts_5822_ctpm_fw_upgrade(client, pbt_buf, fwsize);
|
|
else if (fts_updateinfo_curr.CHIP_ID == 0x59)
|
|
i_ret = fts_5x26_ctpm_fw_upgrade(client, pbt_buf, fwsize);
|
|
else if (fts_updateinfo_curr.CHIP_ID == 0x86) {
|
|
/*call the upgrade function*/
|
|
i_ret = fts_8606_writepram(client, aucFW_PRAM_BOOT,
|
|
sizeof(aucFW_PRAM_BOOT));
|
|
|
|
if (i_ret != 0) {
|
|
dev_notice(&client->dev,
|
|
"%s:fts_8606_writepram failed. err.\n",
|
|
__func__);
|
|
return -EIO;
|
|
}
|
|
|
|
i_ret = fts_8606_ctpm_fw_upgrade(client, pbt_buf, fwsize);
|
|
} else if (fts_updateinfo_curr.CHIP_ID == 0x87) {
|
|
/*call the upgrade function*/
|
|
i_ret = fts_8716_writepram(client, aucFW_PRAM_BOOT,
|
|
sizeof(aucFW_PRAM_BOOT));
|
|
|
|
if (i_ret != 0) {
|
|
dev_notice(&client->dev,
|
|
"%s:fts_8716_writepram failed. err.\n",
|
|
__func__);
|
|
return -EIO;
|
|
}
|
|
|
|
i_ret = fts_8716_ctpm_fw_upgrade(client, pbt_buf, fwsize);
|
|
} else if (fts_updateinfo_curr.CHIP_ID == 0x0E)
|
|
i_ret = fts_3x07_ctpm_fw_upgrade(client, pbt_buf, fwsize);
|
|
if (i_ret != 0)
|
|
dev_notice(&client->dev,
|
|
"%s() - ERROR:[FTS] upgrade failed..\n", __func__);
|
|
else if (fts_updateinfo_curr.AUTO_CLB == AUTO_CLB_NEED)
|
|
fts_ctpm_auto_clb(client);
|
|
|
|
kfree(pbt_buf);
|
|
|
|
return i_ret;
|
|
}
|
|
/*****************************************************************
|
|
* Name: fts_ctpm_get_i_file_ver
|
|
* Brief: get .i file version
|
|
* Input: no
|
|
* Output: no
|
|
* Return: fw version
|
|
*****************************************************************/
|
|
/* Begin Neostra huangxiaohui mod 20160726 */
|
|
int fts_ctpm_get_i_file_ver(void)
|
|
{
|
|
u16 ui_sz = 0;
|
|
u8 uc_host_fm_ver = 0x00;
|
|
|
|
FTS_DBG("[FTS] hxh fts ctpm_get_i_file_ver tp_vendor_id = 0x%x\n",
|
|
vendor_tp_id);
|
|
|
|
if (vendor_tp_id == 0x7b) {
|
|
|
|
ui_sz = sizeof(CTPM_FW);
|
|
uc_host_fm_ver = CTPM_FW[0x010A];
|
|
FTS_DBG("[FTS] hxh tp_vendor_id==0x%x\n", uc_host_fm_ver);
|
|
|
|
} else if (vendor_tp_id == 0x3e) {
|
|
ui_sz = sizeof(TAIGUAN_FW);
|
|
uc_host_fm_ver = TAIGUAN_FW[0x010A];
|
|
FTS_DBG("[FTS] hxh tp_vendor_id==0x%x\n", uc_host_fm_ver);
|
|
}
|
|
|
|
if (ui_sz > 2) {
|
|
if (fts_updateinfo_curr.CHIP_ID == 0x58)
|
|
return uc_host_fm_ver; /* 0x010A + 0x1C00 */
|
|
}
|
|
|
|
/*
|
|
* ui_sz = sizeof(CTPM_FW);
|
|
* if (ui_sz > 2)
|
|
* {
|
|
* if(fts_updateinfo_curr.CHIP_ID==0x36)
|
|
* return CTPM_FW[0x10A];
|
|
* else if(fts_updateinfo_curr.CHIP_ID==0x86 ||
|
|
*fts_updateinfo_curr.CHIP_ID==0x87)
|
|
* return CTPM_FW[0x10E];
|
|
* else if(fts_updateinfo_curr.CHIP_ID==0x58)
|
|
* return CTPM_FW[0x010A]; //0x010A + 0x1C00
|
|
* else
|
|
* return CTPM_FW[ui_sz - 2];
|
|
* }
|
|
*/
|
|
return 0x00;
|
|
}
|
|
/* End Neostra huangxiaohui mod 20160726 */
|
|
/*****************************************************************
|
|
* Name: fts_ctpm_update_project_setting
|
|
* Brief: update project setting,
|
|
* only update these settings for COB project, or
|
|
*for some special case
|
|
* Input: i2c info
|
|
* Output: no
|
|
* Return: fail <0
|
|
*****************************************************************/
|
|
int fts_ctpm_update_project_setting(struct i2c_client *client)
|
|
{
|
|
u8 uc_i2c_addr;
|
|
u8 uc_io_voltage;
|
|
u8 uc_panel_factory_id;
|
|
u8 buf[FTS_SETTING_BUF_LEN];
|
|
u8 reg_val[2] = {0};
|
|
u8 auc_i2c_write_buf[10] = {0};
|
|
u8 packet_buf[FTS_SETTING_BUF_LEN + 6];
|
|
u32 i = 0;
|
|
int i_ret;
|
|
|
|
uc_i2c_addr = client->addr;
|
|
uc_io_voltage = 0x0;
|
|
uc_panel_factory_id = 0x5a;
|
|
|
|
/*Step 1:Reset CTPM*/
|
|
if (fts_updateinfo_curr.CHIP_ID == 0x06 ||
|
|
fts_updateinfo_curr.CHIP_ID == 0x36)
|
|
fts_write_reg(client, 0xbc, 0xaa);
|
|
else
|
|
fts_write_reg(client, 0xfc, 0xaa);
|
|
msleep(50);
|
|
|
|
/*write 0x55 to register 0xfc */
|
|
if (fts_updateinfo_curr.CHIP_ID == 0x06 ||
|
|
fts_updateinfo_curr.CHIP_ID == 0x36)
|
|
fts_write_reg(client, 0xbc, 0x55);
|
|
else
|
|
fts_write_reg(client, 0xfc, 0x55);
|
|
msleep(30);
|
|
|
|
/*********Step 2:Enter upgrade mode *****/
|
|
auc_i2c_write_buf[0] = 0x55;
|
|
auc_i2c_write_buf[1] = 0xaa;
|
|
do {
|
|
i++;
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 2);
|
|
usleep_range(5000, 6000);
|
|
} while (i_ret <= 0 && i < 5);
|
|
|
|
/*********Step 3:check READ-ID***********************/
|
|
auc_i2c_write_buf[0] = 0x90;
|
|
auc_i2c_write_buf[1] = auc_i2c_write_buf[2] = auc_i2c_write_buf[3] =
|
|
0x00;
|
|
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
|
|
if (reg_val[0] == fts_updateinfo_curr.upgrade_id_1 &&
|
|
reg_val[1] == fts_updateinfo_curr.upgrade_id_2)
|
|
dev_dbg(&client->dev,
|
|
"[FTS] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
else
|
|
return -EIO;
|
|
|
|
auc_i2c_write_buf[0] = 0xcd;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
|
|
dev_dbg(&client->dev, "bootloader version = 0x%x\n", reg_val[0]);
|
|
|
|
/*--------- read current project setting ---------- */
|
|
/*set read start address */
|
|
buf[0] = 0x3;
|
|
buf[1] = 0x0;
|
|
buf[2] = 0x78;
|
|
buf[3] = 0x0;
|
|
|
|
fts_i2c_read(client, buf, 4, buf, FTS_SETTING_BUF_LEN);
|
|
dev_dbg(&client->dev,
|
|
"[FTS] old setting: uc_i2c_addr = 0x%x, uc_io_voltage = %d, uc_panel_factory_id = 0x%x\n",
|
|
buf[0], buf[2], buf[4]);
|
|
|
|
/*--------- Step 4:erase project setting --------------*/
|
|
auc_i2c_write_buf[0] = 0x63;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(100);
|
|
|
|
/*---------- Set new settings ---------------*/
|
|
buf[0] = uc_i2c_addr;
|
|
buf[1] = ~uc_i2c_addr;
|
|
buf[2] = uc_io_voltage;
|
|
buf[3] = ~uc_io_voltage;
|
|
buf[4] = uc_panel_factory_id;
|
|
buf[5] = ~uc_panel_factory_id;
|
|
packet_buf[0] = 0xbf;
|
|
packet_buf[1] = 0x00;
|
|
packet_buf[2] = 0x78;
|
|
packet_buf[3] = 0x0;
|
|
packet_buf[4] = 0;
|
|
packet_buf[5] = FTS_SETTING_BUF_LEN;
|
|
|
|
for (i = 0; i < FTS_SETTING_BUF_LEN; i++)
|
|
packet_buf[6 + i] = buf[i];
|
|
|
|
fts_i2c_write(client, packet_buf, FTS_SETTING_BUF_LEN + 6);
|
|
msleep(100);
|
|
|
|
/********* reset the new FW***********************/
|
|
auc_i2c_write_buf[0] = 0x07;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
|
|
msleep(200);
|
|
return 0;
|
|
}
|
|
/*****************************************************************
|
|
* Name: fts_ctpm_fw_upgrade_with_i_file
|
|
* Brief: upgrade with *.i file
|
|
* Input: i2c info
|
|
* Output: no
|
|
* Return: fail <0
|
|
*****************************************************************/
|
|
int fts_ctpm_fw_upgrade_with_i_file(struct i2c_client *client)
|
|
{
|
|
u8 *pbt_buf = NULL;
|
|
int i_ret = 0;
|
|
int fw_len = sizeof(CTPM_FW);
|
|
|
|
/*judge the fw that will be upgraded
|
|
* if illegal, then stop upgrade and return.
|
|
*/
|
|
if ((fts_updateinfo_curr.CHIP_ID == 0x11) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x12) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x13) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x14) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x55) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x06) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x0a) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x08)) {
|
|
if (fw_len < 8 || fw_len > 32 * 1024) {
|
|
dev_notice(&client->dev, "%s:FW length error\n",
|
|
__func__);
|
|
return -EIO;
|
|
}
|
|
|
|
if ((CTPM_FW[fw_len - 8] ^ CTPM_FW[fw_len - 6]) == 0xFF &&
|
|
(CTPM_FW[fw_len - 7] ^ CTPM_FW[fw_len - 5]) == 0xFF &&
|
|
(CTPM_FW[fw_len - 3] ^ CTPM_FW[fw_len - 4]) == 0xFF) {
|
|
/*FW upgrade */
|
|
pbt_buf = CTPM_FW;
|
|
/*call the upgrade function */
|
|
if ((fts_updateinfo_curr.CHIP_ID == 0x55) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x08) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x0a))
|
|
i_ret = fts_5x06_ctpm_fw_upgrade(
|
|
client, pbt_buf, sizeof(CTPM_FW));
|
|
else if ((fts_updateinfo_curr.CHIP_ID == 0x11) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x12) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x13) ||
|
|
(fts_updateinfo_curr.CHIP_ID == 0x14))
|
|
i_ret = fts_5x36_ctpm_fw_upgrade(
|
|
client, pbt_buf, sizeof(CTPM_FW));
|
|
else if (fts_updateinfo_curr.CHIP_ID == 0x06)
|
|
i_ret = fts_6x06_ctpm_fw_upgrade(
|
|
client, pbt_buf, sizeof(CTPM_FW));
|
|
if (i_ret != 0)
|
|
dev_notice(&client->dev,
|
|
"%s:upgrade failed. err.\n",
|
|
__func__);
|
|
else if (fts_updateinfo_curr.AUTO_CLB == AUTO_CLB_NEED)
|
|
fts_ctpm_auto_clb(client);
|
|
} else {
|
|
dev_notice(&client->dev, "%s:FW format error\n",
|
|
__func__);
|
|
return -EBADFD;
|
|
}
|
|
} else if (fts_updateinfo_curr.CHIP_ID == 0x36) {
|
|
if (fw_len < 8 || fw_len > 32 * 1024) {
|
|
dev_notice(&client->dev, "%s:FW length error\n",
|
|
__func__);
|
|
return -EIO;
|
|
}
|
|
pbt_buf = CTPM_FW;
|
|
i_ret = fts_6x36_ctpm_fw_upgrade(client, pbt_buf,
|
|
sizeof(CTPM_FW));
|
|
if (i_ret != 0)
|
|
dev_notice(&client->dev, "%s:upgrade failed. err.\n",
|
|
__func__);
|
|
} else if (fts_updateinfo_curr.CHIP_ID == 0x64) {
|
|
if (fw_len < 8 || fw_len > 48 * 1024) {
|
|
dev_notice(&client->dev, "%s:FW length error\n",
|
|
__func__);
|
|
return -EIO;
|
|
}
|
|
pbt_buf = CTPM_FW;
|
|
i_ret = fts_6336GU_ctpm_fw_upgrade(client, pbt_buf,
|
|
sizeof(CTPM_FW));
|
|
if (i_ret != 0)
|
|
dev_notice(&client->dev, "%s:upgrade failed. err.\n",
|
|
__func__);
|
|
} else if (fts_updateinfo_curr.CHIP_ID == 0x54) {
|
|
if (fw_len < 8 || fw_len > 54 * 1024) {
|
|
pr_notice("FW length error\n");
|
|
return -EIO;
|
|
}
|
|
/*FW upgrade*/
|
|
pbt_buf = CTPM_FW;
|
|
/*call the upgrade function*/
|
|
i_ret = fts_5x46_ctpm_fw_upgrade(client, pbt_buf,
|
|
sizeof(CTPM_FW));
|
|
if (i_ret != 0)
|
|
dev_notice(&client->dev,
|
|
"[FTS] upgrade failed. err=%d.\n", i_ret);
|
|
else {
|
|
#ifdef AUTO_CLB
|
|
fts_ctpm_auto_clb(client); /*start auto CLB*/
|
|
#endif
|
|
}
|
|
} else if (fts_updateinfo_curr.CHIP_ID == 0x58) {
|
|
if (fw_len < 8 || fw_len > 54 * 1024) {
|
|
pr_notice("FW length error\n");
|
|
return -EIO;
|
|
}
|
|
|
|
/*FW upgrade*/
|
|
pbt_buf = CTPM_FW;
|
|
/*call the upgrade function*/
|
|
i_ret = fts_5822_ctpm_fw_upgrade(client, pbt_buf,
|
|
sizeof(CTPM_FW));
|
|
if (i_ret != 0)
|
|
dev_notice(&client->dev,
|
|
"[FTS] upgrade failed. err=%d.\n", i_ret);
|
|
else {
|
|
#ifdef AUTO_CLB
|
|
fts_ctpm_auto_clb(client); /*start auto CLB*/
|
|
#endif
|
|
}
|
|
} else if (fts_updateinfo_curr.CHIP_ID == 0x59) {
|
|
if (fw_len < 8 || fw_len > 54 * 1024) {
|
|
pr_notice("FW length error\n");
|
|
return -EIO;
|
|
}
|
|
|
|
/*FW upgrade*/
|
|
pbt_buf = CTPM_FW;
|
|
/*call the upgrade function*/
|
|
i_ret = fts_5x26_ctpm_fw_upgrade(client, pbt_buf,
|
|
sizeof(CTPM_FW));
|
|
if (i_ret != 0)
|
|
dev_notice(&client->dev,
|
|
"[FTS] upgrade failed. err=%d.\n", i_ret);
|
|
else {
|
|
#ifdef AUTO_CLB
|
|
fts_ctpm_auto_clb(client); /*start auto CLB*/
|
|
#endif
|
|
}
|
|
} else if (fts_updateinfo_curr.CHIP_ID == 0x86) {
|
|
/*FW upgrade*/
|
|
pbt_buf = CTPM_FW;
|
|
/*call the upgrade function*/
|
|
i_ret = fts_8606_writepram(client, aucFW_PRAM_BOOT,
|
|
sizeof(aucFW_PRAM_BOOT));
|
|
|
|
if (i_ret != 0) {
|
|
dev_notice(&client->dev, "%s:upgrade failed. err.\n",
|
|
__func__);
|
|
return -EIO;
|
|
}
|
|
|
|
i_ret = fts_8606_ctpm_fw_upgrade(client, pbt_buf,
|
|
sizeof(CTPM_FW));
|
|
|
|
if (i_ret != 0)
|
|
dev_notice(&client->dev,
|
|
"[FTS] upgrade failed. err=%d.\n", i_ret);
|
|
else {
|
|
#ifdef AUTO_CLB
|
|
fts_ctpm_auto_clb(client); /*start auto CLB*/
|
|
#endif
|
|
}
|
|
} else if (fts_updateinfo_curr.CHIP_ID == 0x87) {
|
|
/*FW upgrade*/
|
|
pbt_buf = CTPM_FW;
|
|
/*call the upgrade function*/
|
|
i_ret = fts_8716_writepram(client, aucFW_PRAM_BOOT,
|
|
sizeof(aucFW_PRAM_BOOT));
|
|
|
|
if (i_ret != 0) {
|
|
dev_notice(&client->dev, "%s:upgrade failed. err.\n",
|
|
__func__);
|
|
return -EIO;
|
|
}
|
|
|
|
i_ret = fts_8716_ctpm_fw_upgrade(client, pbt_buf,
|
|
sizeof(CTPM_FW));
|
|
|
|
if (i_ret != 0)
|
|
dev_notice(&client->dev,
|
|
"[FTS] upgrade failed. err=%d.\n", i_ret);
|
|
else {
|
|
#ifdef AUTO_CLB
|
|
fts_ctpm_auto_clb(client); /*start auto CLB*/
|
|
#endif
|
|
}
|
|
} else if (fts_updateinfo_curr.CHIP_ID == 0x0E) {
|
|
if (fw_len < 8 || fw_len > 32 * 1024) {
|
|
dev_notice(&client->dev, "%s:FW length error\n",
|
|
__func__);
|
|
return -EIO;
|
|
}
|
|
pbt_buf = CTPM_FW;
|
|
i_ret = fts_3x07_ctpm_fw_upgrade(client, pbt_buf,
|
|
sizeof(CTPM_FW));
|
|
if (i_ret != 0)
|
|
dev_notice(&client->dev, "%s:upgrade failed. err.\n",
|
|
__func__);
|
|
}
|
|
return i_ret;
|
|
}
|
|
|
|
/* Begin Neostra huangxiaohui add 20160726 */
|
|
int taiguan_fw_upgrade_with_i_file(struct i2c_client *client)
|
|
{
|
|
u8 *pbt_buf = NULL;
|
|
int i_ret = 0;
|
|
int fw_len = sizeof(TAIGUAN_FW);
|
|
|
|
/*judge the fw that will be upgraded
|
|
* if illegal, then stop upgrade and return.
|
|
*/
|
|
|
|
if (fts_updateinfo_curr.CHIP_ID == 0x58) {
|
|
if (fw_len < 8 || fw_len > 54 * 1024) {
|
|
pr_notice("FW length error\n");
|
|
return -EIO;
|
|
}
|
|
|
|
/*FW upgrade*/
|
|
pbt_buf = TAIGUAN_FW;
|
|
/*call the upgrade function*/
|
|
i_ret = fts_5822_ctpm_fw_upgrade(client, pbt_buf,
|
|
sizeof(TAIGUAN_FW));
|
|
if (i_ret != 0)
|
|
dev_notice(&client->dev,
|
|
"[FTS] upgrade failed. err=%d.\n", i_ret);
|
|
else {
|
|
#ifdef AUTO_CLB
|
|
fts_ctpm_auto_clb(client); /*start auto CLB*/
|
|
#endif
|
|
}
|
|
}
|
|
|
|
return i_ret;
|
|
}
|
|
/* End Neostra huangxiaohui add 20160726 */
|
|
|
|
#if 0
|
|
static unsigned char
|
|
ft5x46_ctpm_VidFWid_get_from_boot(struct i2c_client *client)
|
|
{
|
|
unsigned char auc_i2c_write_buf[10];
|
|
unsigned char reg_val[4] = {0};
|
|
unsigned char i = 0;
|
|
unsigned char vid = 0xFF;
|
|
int i_ret;
|
|
|
|
fts_get_upgrade_array();
|
|
|
|
i_ret = hidi2c_to_stdi2c(client);
|
|
|
|
for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
|
|
msleep(100);
|
|
DBG("[FTS] Step 1:Reset CTPM\n");
|
|
/*********Step 1:Reset CTPM *****/
|
|
#if 0
|
|
mt_set_gpio_mode(GPIO_CTP_RST_PIN, GPIO_CTP_RST_PIN_M_GPIO);
|
|
mt_set_gpio_dir(GPIO_CTP_RST_PIN, GPIO_DIR_OUT);
|
|
mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ZERO);
|
|
usleep_range(5000, 6000);
|
|
mt_set_gpio_mode(GPIO_CTP_RST_PIN, GPIO_CTP_RST_PIN_M_GPIO);
|
|
mt_set_gpio_dir(GPIO_CTP_RST_PIN, GPIO_DIR_OUT);
|
|
mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ONE);
|
|
#else
|
|
/*write 0xaa to register 0xfc */
|
|
fts_write_reg(client, 0xfc, FTS_UPGRADE_AA);
|
|
usleep_range(5000, 6000);
|
|
|
|
/*write 0x55 to register 0xfc */
|
|
fts_write_reg(client, 0xfc, FTS_UPGRADE_55);
|
|
|
|
#endif
|
|
if (i <= 15)
|
|
msleep(fts_updateinfo_curr.delay_55 + i * 3);
|
|
else
|
|
msleep(fts_updateinfo_curr.delay_55 - (i - 15) * 2);
|
|
|
|
i_ret = hidi2c_to_stdi2c(client);
|
|
usleep_range(5000, 6000);
|
|
|
|
/*********Step 2:Enter upgrade mode *****/
|
|
DBG("[FTS] Step 2:Enter upgrade mode\n");
|
|
#if 0
|
|
auc_i2c_write_buf[0] = FT_UPGRADE_55;
|
|
auc_i2c_write_buf[1] = FT_UPGRADE_AA;
|
|
do {
|
|
j++;
|
|
i_ret = fts_i2c_Write(client, auc_i2c_write_buf, 2);
|
|
usleep_range(5000, 6000);
|
|
} while (i_ret <= 0 && j < 5);
|
|
#else
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_55;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
usleep_range(5000, 6000);
|
|
auc_i2c_write_buf[0] = FTS_UPGRADE_AA;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
#endif
|
|
|
|
#if 1
|
|
/*********Step 3:check READ-ID***********************/
|
|
msleep(fts_updateinfo_curr.delay_readid);
|
|
auc_i2c_write_buf[0] = 0x90;
|
|
auc_i2c_write_buf[1] = auc_i2c_write_buf[2] =
|
|
auc_i2c_write_buf[3] = 0x00;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 4, reg_val, 2);
|
|
|
|
DBG("[FTS] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",
|
|
reg_val[0], reg_val[1]);
|
|
if (reg_val[0] == fts_updateinfo_curr.upgrade_id_1
|
|
&& reg_val[1] != 0) {
|
|
|
|
DBG("[FTS]3 ok:0x%x,ID2 = 0x%x ,0x%x, 0x%x:\n",
|
|
reg_val[0], reg_val[1],
|
|
fts_updateinfo_curr.upgrade_id_1,
|
|
fts_updateinfo_curr.upgrade_id_2);
|
|
break;
|
|
}
|
|
dev_notice(&client->dev,
|
|
"[FTS]3 fail:0x%x,ID2 = 0x%x, 0x%x, 0x%x:\n",
|
|
reg_val[0], reg_val[1], fts_updateinfo_curr.upgrade_id_1,
|
|
fts_updateinfo_curr.upgrade_id_2);
|
|
|
|
#endif
|
|
}
|
|
if (i >= FTS_UPGRADE_LOOP) {
|
|
DBG("[FTS] FTS_UPGRADE_LOOP is i = %d\n", i);
|
|
return -EIO;
|
|
}
|
|
DBG("[FTS] OK: FTS_UPGRADE_LOOP is i = %d\n", i);
|
|
auc_i2c_write_buf[0] = 0xcd;
|
|
fts_i2c_read(client, auc_i2c_write_buf, 1, reg_val, 1);
|
|
DBG("[FTS]bootloader version = 0x%x\n", reg_val[0]);
|
|
auc_i2c_write_buf[0] = 0x03;
|
|
auc_i2c_write_buf[1] = 0x00;
|
|
for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
|
|
auc_i2c_write_buf[2] = 0xd7;
|
|
auc_i2c_write_buf[3] = 0x83;/* 84 */
|
|
i_ret = fts_i2c_write(client, auc_i2c_write_buf, 4);
|
|
if (i_ret < 0) {
|
|
DBG("[FTS] Step 4: error i_ret = %d\n", i_ret);
|
|
continue;
|
|
}
|
|
/* fts_i2c_Read(client, auc_i2c_write_buf, 4, reg_val, 2); */
|
|
|
|
i_ret = fts_i2c_read(client, auc_i2c_write_buf, 0, reg_val, 2);
|
|
if (i_ret < 0) {
|
|
DBG("[FTS] Step 4: error i_ret = %d\n", i_ret);
|
|
continue;
|
|
}
|
|
|
|
vid = reg_val[1];
|
|
|
|
DBG("%s: REG VAL ID1 = 0x%x,ID2 = 0x%x\n",
|
|
__func__, reg_val[0], reg_val[1]);
|
|
break;
|
|
|
|
|
|
}
|
|
DBG("Step 7: reset the new FW\n");
|
|
auc_i2c_write_buf[0] = 0x07;
|
|
fts_i2c_write(client, auc_i2c_write_buf, 1);
|
|
msleep(300); /*make sure CTP startup normally */
|
|
return vid;
|
|
}
|
|
#endif
|
|
|
|
/*****************************************************************
|
|
* Name: fts_ctpm_auto_upgrade
|
|
* Brief: auto upgrade
|
|
* Input: i2c info
|
|
* Output: no
|
|
* Return: 0
|
|
*****************************************************************/
|
|
int fts_ctpm_auto_upgrade(struct i2c_client *client)
|
|
{
|
|
#if TPD_AUTO_UPGRADE
|
|
u8 uc_host_fm_ver = FTS_REG_FW_VER;
|
|
/* u8 uc_tp_fm_ver,uc_tp_vendor_id,uc_boot_vendor_id; */
|
|
u8 uc_tp_fm_ver, uc_tp_vendor_id;
|
|
int i_ret = -1;
|
|
|
|
fts_read_reg(client, FTS_REG_FW_VER, &uc_tp_fm_ver);
|
|
fts_read_reg(client, FTS_REG_VENDOR_ID, &uc_tp_vendor_id);
|
|
vendor_tp_id = uc_tp_vendor_id;
|
|
FTS_DBG("[FTS] uc_tp_fm_ver = 0x%x, uc_tp_vendor_id = 0x%x\n",
|
|
uc_tp_fm_ver, uc_tp_vendor_id);
|
|
|
|
#if 0
|
|
if ((uc_tp_vendor_id != FTS_Vendor_1_ID) &&
|
|
(uc_tp_vendor_id != FTS_Vendor_2_ID)) {
|
|
uc_boot_vendor_id = ft5x46_ctpm_VidFWid_get_from_boot(client);
|
|
FTS_DBG("[FTS] uc_boot_vendor_id= 0x%x!\n", uc_boot_vendor_id);
|
|
if ((uc_boot_vendor_id == FTS_Vendor_1_ID) ||
|
|
(uc_boot_vendor_id == FTS_Vendor_2_ID)) {
|
|
uc_tp_fm_ver = 0;/* force to upgrade the FW */
|
|
uc_tp_vendor_id = uc_boot_vendor_id;
|
|
} else {
|
|
FTS_DBG("[FTS] FW .i unmatched,stop upgrade\n");
|
|
return -EIO;/* FW unmatched */
|
|
}
|
|
}
|
|
#endif
|
|
|
|
uc_host_fm_ver = fts_ctpm_get_i_file_ver();
|
|
FTS_DBG("[FTS] uc_host_fm_ver = 0x%x\n", uc_host_fm_ver);
|
|
/* Neostra huangxiaohui add for taiguan new FW version:0x40 */
|
|
if ((uc_tp_fm_ver == FTS_REG_FW_VER) ||
|
|
(uc_tp_fm_ver < uc_host_fm_ver)) {
|
|
|
|
msleep(100);
|
|
dev_dbg(&client->dev,
|
|
"[FTS] uc_tp_fm_ver = 0x%x, uc_host_fm_ver = 0x%x\n",
|
|
uc_tp_fm_ver, uc_host_fm_ver);
|
|
/* Beging Neostra huangxiaohui mod 20160726 */
|
|
FTS_DBG("--->>hxh begin TP upgrade\n");
|
|
if (uc_tp_vendor_id == 0x7b) {
|
|
FTS_DBG("--->>hxh pingbo TP upgrade\n");
|
|
i_ret = fts_ctpm_fw_upgrade_with_i_file(client);
|
|
} else if (uc_tp_vendor_id == 0x3e) {
|
|
FTS_DBG("--->>hxh taiguan TP upgrade\n");
|
|
i_ret = taiguan_fw_upgrade_with_i_file(client);
|
|
}
|
|
/* End Neostra huangxiaohui mod 20160726 */
|
|
if (i_ret == 0) {
|
|
msleep(300);
|
|
uc_host_fm_ver = fts_ctpm_get_i_file_ver();
|
|
dev_dbg(&client->dev,
|
|
"[FTS] upgrade to new version 0x%x\n",
|
|
uc_host_fm_ver);
|
|
FTS_DBG("[FTS] upgrade to new version 0x%x\n",
|
|
uc_host_fm_ver);
|
|
} else {
|
|
pr_notice("[FTS] upgrade failed ret=%d.\n", i_ret);
|
|
FTS_DBG("[FTS] upgrade failed ret=%d.\n", i_ret);
|
|
return -EIO;
|
|
}
|
|
}
|
|
#endif
|
|
return 0;
|
|
}
|