blob: 616ae8332bf792d6c10f2aa5aa8ea1df26a166f9 [file] [log] [blame]
/*
* Copyright © 2016 FocalTech Systems Co., Ltd. All Rights Reserved.
*
* This program is free software; you may redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/*******************************************************************************
* 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_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 "/sdcard/"
/*******************************************************************************
* Private enumerations, structures and unions using typedef
*******************************************************************************/
/*******************************************************************************
* Static variables
*******************************************************************************/
static unsigned char CTPM_FW_TP_ID_0[] = {
#include "FTS_FW/CEI_ESW1_3267_0x90_app.i"
};
static unsigned char CTPM_FW_TP_ID_1[] = {
#include "FTS_FW/CEI_ESW1_3267_0x91_app.i"
};
static unsigned char CTPM_FW_TP_ID_2[] = {
#include "FTS_FW/CEI_ESW1_3267_0x92_app.i"
};
static unsigned char CTPM_FW_TP_ID_3[] = {
#include "FTS_FW/CEI_ESW1_3267_0x93_app.i"
};
struct fts_Upgrade_Info fts_updateinfo[] =
{
{0x33,FTS_MAX_POINTS_2,AUTO_CLB_NONEED,10, 10, 0x79, 0x1c, 10, 2000}, //,"FT3267"
{0x55,FTS_MAX_POINTS_5,AUTO_CLB_NEED,50, 30, 0x79, 0x03, 10, 2000}, //,"FT5x06"
{0x08,FTS_MAX_POINTS_5,AUTO_CLB_NEED,50, 10, 0x79, 0x06, 100, 2000}, //,"FT5606"
{0x0a,FTS_MAX_POINTS_5,AUTO_CLB_NEED,50, 30, 0x79, 0x07, 10, 1500}, //,"FT5x16"
{0x06,FTS_MAX_POINTS_2,AUTO_CLB_NONEED,100, 30, 0x79, 0x08, 10, 2000}, //,"FT6x06"
{0x36,FTS_MAX_POINTS_2,AUTO_CLB_NONEED,10, 10, 0x79, 0x18, 10, 2000}, //,"FT6x36"
{0x64,FTS_MAX_POINTS_2,AUTO_CLB_NONEED,10, 10, 0x79, 0x1c, 10, 2000}, //,"FT6336GU"
{0x55,FTS_MAX_POINTS_5,AUTO_CLB_NEED,50, 30, 0x79, 0x03, 10, 2000}, //,"FT5x06i"
{0x14,FTS_MAX_POINTS_5,AUTO_CLB_NONEED,30, 30, 0x79, 0x11, 10, 2000}, //,"FT5336"
{0x13,FTS_MAX_POINTS_5,AUTO_CLB_NONEED,30, 30, 0x79, 0x11, 10, 2000}, //,"FT3316"
{0x12,FTS_MAX_POINTS_5,AUTO_CLB_NONEED,30, 30, 0x79, 0x11, 10, 2000}, //,"FT5436i"
{0x11,FTS_MAX_POINTS_5,AUTO_CLB_NONEED,30, 30, 0x79, 0x11, 10, 2000}, //,"FT5336i"
{0x54,FTS_MAX_POINTS_5,AUTO_CLB_NONEED,2, 2, 0x54, 0x2c, 20, 2000}, //,"FT5x46"
{0x58,FTS_MAX_POINTS_5,AUTO_CLB_NONEED,2, 2, 0x58, 0x2c, 20, 2000},//"FT5822",
{0x59,FTS_MAX_POINTS_10,AUTO_CLB_NONEED,30, 50, 0x79, 0x10, 1, 2000},//"FT5x26",
{0x86,FTS_MAX_POINTS_10,AUTO_CLB_NONEED,2, 2, 0x86, 0xA6, 20, 2000},//"FT8606",
{0x0e,FTS_MAX_POINTS_2,AUTO_CLB_NONEED,10, 10, 0x79, 0x18, 10, 2000}, //,"FT3X07"
};
/*******************************************************************************
* Global variable or extern global variabls/functions
*******************************************************************************/
struct fts_Upgrade_Info fts_updateinfo_curr;
/*The newest firmware, if update must be changed here*/
u8 *CTPM_FW = NULL;
u16 fw_size = 0;
/*******************************************************************************
* Static function prototypes
*******************************************************************************/
int fts_6x36_ctpm_fw_upgrade(struct i2c_client *client, u8 *pbt_buf, u32 dw_lenth);
int fts_6336GU_ctpm_fw_upgrade(struct i2c_client *client, u8 *pbt_buf, u32 dw_lenth);
int fts_6x06_ctpm_fw_upgrade(struct i2c_client *client, u8 *pbt_buf, u32 dw_lenth);
int fts_5x36_ctpm_fw_upgrade(struct i2c_client *client, u8 *pbt_buf, u32 dw_lenth);
int fts_5x06_ctpm_fw_upgrade(struct i2c_client *client, u8 *pbt_buf, u32 dw_lenth);
int fts_5x46_ctpm_fw_upgrade(struct i2c_client * client, u8* pbt_buf, u32 dw_lenth);
int fts_5822_ctpm_fw_upgrade(struct i2c_client * client, u8* pbt_buf, u32 dw_lenth);
int fts_5x26_ctpm_fw_upgrade(struct i2c_client *client, u8 *pbt_buf, u32 dw_lenth);
int fts_8606_writepram(struct i2c_client * client, u8* pbt_buf, u32 dw_lenth);
int fts_8606_ctpm_fw_upgrade(struct i2c_client * client, u8* pbt_buf, u32 dw_lenth);
int fts_3x07_ctpm_fw_upgrade(struct i2c_client *client, u8 *pbt_buf, u32 dw_lenth);
int hidi2c_to_stdi2c(struct i2c_client * client);
int fts_fwupg_reset_in_boot(struct i2c_client *client);
bool fts_fwupg_check_state(struct i2c_client *client, enum FW_STATUS rstate);
bool fts_fwupg_check_fw_valid(struct i2c_client *client);
/************************************************************************
* 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);
msleep(10);
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(0xeb==auc_i2c_write_buf[0] && 0xaa==auc_i2c_write_buf[1] && 0x08==auc_i2c_write_buf[2])
{
pr_info("hidi2c_to_stdi2c successful.\n");
bRet = 1;
}
else
{
pr_err("hidi2c_to_stdi2c error.\n");
bRet = 0;
}
return bRet;
}
static int fts_fwupg_reset_to_boot(struct i2c_client *client)
{
int ret = 0;
u8 reg = FTS_REG_UPGRADE2;
ret = fts_write_reg(client, reg, FTS_UPGRADE_AA);
if (ret < 0) {
printk(KERN_ERR "fts write FC=0xAA fail\n");
return ret;
}
msleep(FTS_DELAY_UPGRADE_AA);
ret = fts_write_reg(client, reg, FTS_UPGRADE_55);
if (ret < 0) {
printk(KERN_ERR"fts write FC=0x55 fail");
return ret;
}
msleep(FTS_DELAY_UPGRADE_RESET);
return 0;
}
/************************************************************************
* Name: fts_fwupg_enter_into_boot
* Brief: enter into boot environment, ready for upgrade
* Input:
* Output:
* Return: return 0 if success, otherwise return error code
***********************************************************************/
int fts_fwupg_enter_into_boot(struct i2c_client *client)
{
int ret = 0;
bool state = false;
bool fwvalid = false;
fwvalid = fts_fwupg_check_fw_valid(client);
if (fwvalid) {
printk(KERN_INFO "fts fwvalid true\n");
ret = fts_fwupg_reset_to_boot(client);
if (ret < 0) {
printk(KERN_ERR "fts enter into romboot/bootloader fail\n");
return ret;
}
} else {
printk(KERN_INFO "fts fwvalid false\n");
ret = fts_fwupg_reset_in_boot(client);
if (ret < 0) {
printk(KERN_ERR "fts reset before read boot id when fw invalid fail\n");
return ret;
}
}
state = fts_fwupg_check_state(client, FTS_RUN_IN_BOOTLOADER);
if (!state) {
printk(KERN_ERR "fts fw not in bootloader, fail\n");
return -EIO;
}
return 0;
}
/************************************************************************
* Name: fts_flash_read_buf
* Brief: read data from flash
* Input: saddr - start address data write to flash
* buf - buffer to store data read from flash
* len - read length
* Output:
* Return: return 0 if success, otherwise return error code
*
* Warning: can't call this function directly, need call in boot environment
***********************************************************************/
int fts_flash_read_buf(struct i2c_client *client, u32 saddr, u8 *buf, u32 len)
{
int ret = 0;
u32 i = 0;
u32 packet_number = 0;
u32 packet_len = 0;
u32 addr = 0;
u32 offset = 0;
u32 remainder = 0;
u8 wbuf[FTS_CMD_READ_LEN];
if ((NULL == buf) || (0 == len)) {
printk(KERN_ERR "fts buf is NULL or len is 0\n");
return -EINVAL;
}
packet_number = len / FTS_FLASH_PACKET_LENGTH;
remainder = len % FTS_FLASH_PACKET_LENGTH;
if (remainder > 0)
packet_number++;
packet_len = FTS_FLASH_PACKET_LENGTH;
printk(KERN_INFO "fts read packet_number:%d, remainder:%d\n", packet_number, remainder);
wbuf[0] = FTS_CMD_READ;
for (i = 0; i < packet_number; i++) {
offset = i * FTS_FLASH_PACKET_LENGTH;
addr = saddr + offset;
wbuf[1] = BYTE_OFF_16(addr);
wbuf[2] = BYTE_OFF_8(addr);
wbuf[3] = BYTE_OFF_0(addr);
/* last packet */
if ((i == (packet_number - 1)) && remainder)
packet_len = remainder;
ret = fts_i2c_write(client, wbuf, FTS_CMD_READ_LEN);
if (ret < 0) {
printk(KERN_ERR "fts pram/bootloader write 03 command fail\n");
return ret;
}
msleep(FTS_CMD_READ_DELAY); /* must wait, otherwise read wrong data */
ret = fts_i2c_read(client, NULL, 0, buf + offset, packet_len);
if (ret < 0) {
printk(KERN_ERR "fts pram/bootloader read 03 command fail\n");
return ret;
}
}
return 0;
}
/************************************************************************
* Name: fts_flash_read
* Brief:
* Input: addr - address of flash
* len - length of read
* Output: buf - data read from flash
* Return: return 0 if success, otherwise return error code
***********************************************************************/
int fts_flash_read(struct i2c_client *client, u32 addr, u8 *buf, u32 len)
{
int ret = 0;
if ((NULL == buf) || (0 == len)) {
printk(KERN_ERR "fts buf is NULL or len is 0\n");
return -EINVAL;
}
ret = fts_fwupg_enter_into_boot(client);
if (ret < 0) {
printk(KERN_ERR "fts enter into pramboot/bootloader fail\n");
goto read_flash_err;
}
ret = fts_flash_read_buf(client, addr, buf, len);
if (ret < 0) {
printk(KERN_ERR "fts read flash fail\n");
goto read_flash_err;
}
read_flash_err:
/* reset to normal boot */
ret = fts_fwupg_reset_in_boot(client);
if (ret < 0)
printk(KERN_ERR "fts reset to normal boot fail\n");
return ret;
}
/*******************************************************************************
* 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;
int err;
u32 fwcfg_addr = 0x07B0;
u8 cfgbuf[FTS_HEADER_LEN] = { 0 };
err = fts_flash_read(client, fwcfg_addr, cfgbuf, FTS_HEADER_LEN);
data->fw_vendor_id = cfgbuf[FTS_CONIFG_VENDORID_OFF];
}
/*******************************************************************************
* 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, &reg_addr, 1, &data->fw_ver[0], 1);
if (err < 0)
dev_err(&client->dev, "fw major version read failed");
dev_info(&client->dev, "Firmware version = 0x%x\n",
data->fw_ver[0]);
}
/************************************************************************
* 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)
{
FTS_DBG("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)
{
FTS_DBG("HidI2c change to StdI2c fail ! \n");
}
msleep(10);
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) {
FTS_DBG("failed writing 0x55 and 0xaa ! \n");
continue;
}
/*********Step 3:check READ-ID***********************/
msleep(10);
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) {
FTS_DBG("[FTS] Step 3: READ OK CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n", reg_val[0], reg_val[1]);
break;
}
else
{
dev_err(&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***********************/
msleep(10);
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);
msleep(5);
reg_val[0] = reg_val[1] = 0x00;
i_ret = fts_i2c_read(client, auc_i2c_write_buf, 0, reg_val, 2);
if (0 != reg_val[0])
{
*ucPVendorID = 0;
FTS_DBG("In upgrade 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];
FTS_DBG("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***********************/
FTS_DBG("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)
{
FTS_DBG("HidI2c change to StdI2c fail ! \n");
}
msleep(10);
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)
{
FTS_DBG("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)
{
FTS_DBG("HidI2c change to StdI2c fail ! \n");
}
msleep(10);
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)
{
FTS_DBG("failed writing 0x55 and 0xaa ! \n");
continue;
}
/*********Step 3:check READ-ID***********************/
msleep(10);
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)
{
FTS_DBG("[FTS] Step 3: READ OK CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n", reg_val[0], reg_val[1]);
break;
}
else
{
dev_err(&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***********************/
msleep(10);
/*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***********************/
FTS_DBG("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)
{
FTS_DBG("HidI2c change to StdI2c fail ! \n");
}
msleep(10);
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;
ret = fts_read_reg(fts_i2c_client, FTS_REG_ID,&chip_id);
if (ret<0)
{
printk("[Focal][Touch] read value fail");
}
printk("%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[15], 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)) //5x36,5x36i
{
for(i=0;i<100;i++)
{
fts_read_reg(client, 0x02, &uc_temp);
if (0x02 == uc_temp || 0xFF == uc_temp)
{
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_lenth)
{
u8 reg_val[2] = {0};
u32 i = 0;
u32 packet_number;
u32 j;
u32 temp;
u32 lenght;
u32 fw_length;
u8 packet_buf[FTS_PACKET_LENGTH + 6];
u8 auc_i2c_write_buf[10];
u8 bt_ecc;
if(pbt_buf[0] != 0x02)
{
FTS_DBG("[FTS] FW first byte is not 0x02. so it is invalid \n");
return -1;
}
if(dw_lenth > 0x11f)
{
fw_length = ((u32)pbt_buf[0x100]<<8) + pbt_buf[0x101];
if(dw_lenth < fw_length)
{
FTS_DBG("[FTS] Fw length is invalid \n");
return -1;
}
}
else
{
FTS_DBG("[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)
{
FTS_DBG("[FTS] Step 3: GET CTPM ID OK,ID1 = 0x%x,ID2 = 0x%x\n",
reg_val[0], reg_val[1]);
break;
}
else
{
dev_err(&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) {
dev_err(&client->dev, "[FTS] i >= FTS_UPGRADE_LOOP, return EIO \n");
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*/
FTS_DBG("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])
{
FTS_DBG("[FTS] erase app finished \n");
break;
}
msleep(50);
}
/*********Step 5:write firmware(FW) to ctpm flash*********/
bt_ecc = 0;
FTS_DBG("Step 5:write firmware(FW) to ctpm flash\n");
dw_lenth = fw_length;
packet_number = (dw_lenth) / 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;
lenght = FTS_PACKET_LENGTH;
packet_buf[4] = (u8) (lenght >> 8);
packet_buf[5] = (u8) lenght;
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)) == (((reg_val[0] & 0x0f) << 8) |reg_val[1]))
{
FTS_DBG("[FTS] write a block data finished \n");
break;
}
msleep(1);
}
}
if ((dw_lenth) % FTS_PACKET_LENGTH > 0)
{
temp = packet_number * FTS_PACKET_LENGTH;
packet_buf[2] = (u8) (temp >> 8);
packet_buf[3] = (u8) temp;
temp = (dw_lenth) % 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)) == (((reg_val[0] & 0x0f) << 8) |reg_val[1]))
{
FTS_DBG("[FTS] write a block data finished \n");
break;
}
msleep(1);
}
}
/*********Step 6: read out checksum***********************/
FTS_DBG("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_err(&client->dev, "[FTS]--ecc error! FW=%02x bt_ecc=%02x\n",
reg_val[0], bt_ecc);
return -EIO;
}
/*********Step 7: reset the new FW***********************/
FTS_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);
return 0;
}
/************************************************************************
* Name: fts_i2c_write_reg
* Brief: write register
* Input: i2c info, reg address, reg value
* Output: no
* Return: fail <0
***********************************************************************/
int fts_i2c_write_reg(struct i2c_client *client, u8 regaddr, u8 regvalue)
{
u8 buf[2] = {0};
buf[0] = regaddr;
buf[1] = regvalue;
return fts_i2c_write(client, buf, sizeof(buf));
}
/************************************************************************
* Name: fts_i2c_read_reg
* Brief: read register
* Input: i2c info, reg address, reg value
* Output: get reg value
* Return: fail <0
***********************************************************************/
int fts_i2c_read_reg(struct i2c_client *client, u8 regaddr, u8 *regvalue)
{
return fts_i2c_read(client, &regaddr, 1, regvalue, 1);
}
/*****************************************************************************
* Name: fts_wait_tp_to_valid
* Brief: Read chip id until TP FW become valid(Timeout: TIMEOUT_READ_REG),
* need call when reset/power on/resume...
* Input:
* Output:
* Return: return 0 if tp valid, otherwise return error code
*****************************************************************************/
int fts_wait_tp_to_valid(struct i2c_client *client)
{
int ret = 0;
int cnt = 0;
u8 reg_value = 0;
//struct fts_ts_data *fts_data = (struct fts_ts_data *)i2c_get_clientdata(client);
//u8 chip_id = fts_data->ic_info.ids.chip_idh;
u8 chip_id = 0x64;
do {
ret = fts_i2c_read_reg(client, FTS_REG_CHIP_ID, &reg_value);
if ((ret < 0) || (reg_value != chip_id)) {
printk(KERN_INFO "TP Not Ready, ReadData = 0x%x", reg_value);
} else if (reg_value == chip_id) {
printk(KERN_INFO "TP Ready, Device ID = 0x%x", reg_value);
return 0;
}
cnt++;
msleep(INTERVAL_READ_REG);
} while ((cnt * INTERVAL_READ_REG) < TIMEOUT_READ_REG);
return -EIO;
}
/************************************************************************
* Name: fts_fwupg_check_fw_valid
* Brief: check fw in tp is valid or not
* Input:
* Output:
* Return: return true if fw is valid, otherwise return false
***********************************************************************/
bool fts_fwupg_check_fw_valid(struct i2c_client *client)
{
int ret = 0;
ret = fts_wait_tp_to_valid(client);
if (ret < 0) {
printk(KERN_INFO "tp fw invaild");
return false;
}
printk(KERN_INFO "tp fw vaild");
return true;
}
int fts_ft6336gu_reset_to_boot(struct i2c_client *client)
{
int ret = 0;
printk(KERN_INFO "send 0xAA and 0x55 to FW, reset to boot environment");
ret = fts_i2c_write_reg(client, FTS_REG_UPGRADE2, FTS_UPGRADE_AA);
if (ret < 0) {
printk(KERN_ERR "write FC=0xAA fail");
return ret;
}
msleep(FTS_DELAY_FC_AA);
ret = fts_i2c_write_reg(client, FTS_REG_UPGRADE2, FTS_UPGRADE_55);
if (ret < 0) {
printk(KERN_ERR "write FC=0x55 fail");
return ret;
}
msleep(FTS_DELAY_UPGRADE_RESET);
return 0;
}
/************************************************************************
* Name: fts_fwupg_get_boot_state
* Brief: read boot id(rom/pram/bootloader), confirm boot environment
* Input:
* Output:
* Return: return 0 if success, otherwise return error code
***********************************************************************/
int fts_fwupg_get_boot_state(struct i2c_client *client, enum FW_STATUS *fw_sts)
{
int ret = 0;
u8 cmd[4] = { 0 };
u32 cmd_len = 0;
u8 val[2] = { 0 };
struct fts_ts_data *fts_data = (struct fts_ts_data *)i2c_get_clientdata(client);
//struct ft_chip_t ids = fts_data->ic_info.ids;
/*
struct fts_upgrade *upg = fwupgrade;
printk(KERN_INFO "**********read boot id**********");
if ((NULL == fw_sts) || (NULL == upg) || (NULL == upg->func)) {
printk(KERN_ERR "upgrade/func/fw_sts is null");
return -EINVAL;
}
if (upg->func->hid_supported)
fts_i2c_hid2std(client);
*/
cmd[0] = FTS_CMD_START1;
cmd[1] = FTS_CMD_START2;
ret = fts_i2c_write(client, cmd, 2);
if (ret < 0) {
printk(KERN_ERR "write 55 aa cmd fail");
return ret;
}
msleep(FTS_CMD_START_DELAY);
cmd[0] = FTS_CMD_READ_ID;
cmd[1] = cmd[2] = cmd[3] = 0x00;
if (fts_data->ic_info.is_incell)
cmd_len = FTS_CMD_READ_ID_LEN_INCELL;
else
cmd_len = FTS_CMD_READ_ID_LEN;
ret = fts_i2c_read(client, cmd, cmd_len, val, 2);
if (ret < 0) {
printk(KERN_ERR "write 90 cmd fail");
return ret;
}
printk(KERN_INFO "read boot id:0x%02x%02x", val[0], val[1]);
/*
if ((val[0] == ids.rom_idh) && (val[1] == ids.rom_idl)) {
printk(KERN_INFO "tp run in romboot");
*fw_sts = FTS_RUN_IN_ROM;
} else if ((val[0] == ids.pb_idh) && (val[1] == ids.pb_idl)) {
printk(KERN_INFO "tp run in pramboot");
*fw_sts = FTS_RUN_IN_PRAM;
} else if ((val[0] == ids.bl_idh) && (val[1] == ids.bl_idl)) {
printk(KERN_INFO "tp run in bootloader");
*fw_sts = FTS_RUN_IN_BOOTLOADER;
}
*/
if ((val[0] == 0x64) && (val[1] == 0x26)) {
printk(KERN_INFO "tp run in romboot");
*fw_sts = FTS_RUN_IN_ROM;
} else if ((val[0] == 0) && (val[1] == 0)) {
printk(KERN_INFO "tp run in pramboot");
*fw_sts = FTS_RUN_IN_PRAM;
} else if ((val[0] == 0x79) && (val[1] == 0x1C)) {
printk(KERN_INFO "tp run in bootloader");
*fw_sts = FTS_RUN_IN_BOOTLOADER;
}
return 0;
}
/************************************************************************
* Name: fts_fwupg_check_state
* Brief: confirm tp run in romboot/pramboot/bootloader
* Input:
* Output:
* Return: return true if state is match, otherwise return false
***********************************************************************/
bool fts_fwupg_check_state(struct i2c_client *client, enum FW_STATUS rstate)
{
int ret = 0;
int i = 0;
enum FW_STATUS cstate = FTS_RUN_IN_ERROR;
for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
ret = fts_fwupg_get_boot_state(client, &cstate);
/* FTS_DEBUG("fw state=%d, retries=%d", cstate, i); */
if (cstate == rstate)
return true;
msleep(FTS_DELAY_READ_ID);
}
return false;
}
/************************************************************************
* Name: fts_ft6336gu_check_flash_status
* Brief:
* Input: flash_status: correct value from tp
* retries: read retry times
* retries_delay: retry delay
* Output:
* Return: return true if flash status check pass, otherwise return false
***********************************************************************/
static bool fts_ft6336gu_check_flash_status(
struct i2c_client *client,
u16 flash_status,
int retries,
int retries_delay)
{
int ret = 0;
int i = 0;
u8 cmd[4] = { 0 };
u8 val[FTS_CMD_FLASH_STATUS_LEN] = { 0 };
u16 read_status = 0;
for (i = 0; i < retries; i++) {
/* w 6a 00 00 00 r 2 */
cmd[0] = FTS_CMD_FLASH_STATUS;
ret = fts_i2c_read(client, cmd, 4, val, FTS_CMD_FLASH_STATUS_LEN);
read_status = (((u16)val[0]) << 8) + val[1];
if (flash_status == read_status) {
/* FTS_DEBUG("[UPGRADE]flash status ok"); */
return true;
}
printk(KERN_DEBUG "flash status fail,ok:%04x read:%04x, retries:%d", flash_status, read_status, i);
msleep(retries_delay);
}
return false;
}
/************************************************************************
* Name: fts_ft6336gu_erase
* Brief:
* Input:
* Output:
* Return: return 0 if success, otherwise return error code
***********************************************************************/
static int fts_ft6336gu_erase(struct i2c_client *client)
{
int ret = 0;
u8 cmd = 0;
bool flag = false;
printk(KERN_INFO "**********erase app now**********");
/*send to erase flash*/
cmd = FTS_CMD_ERASE_APP;
ret = fts_i2c_write(client, &cmd, 1);
if (ret < 0) {
printk(KERN_ERR "erase cmd fail");
return ret;
}
msleep(500);
/* read status 0xF0AA: success */
flag = fts_ft6336gu_check_flash_status(client, FTS_FLASH_STATUS_OK_FT6336GU, 50, 100);
if (!flag) {
printk(KERN_ERR "ecc flash status check fail");
return -EIO;
}
return 0;
}
/************************************************************************
* Name: fts_ft6336gu_write_app
* Brief:
* Input:
* Output:
* Return: return ecc if success, otherwise return error code
***********************************************************************/
static int fts_ft6336gu_write_app(struct i2c_client *client, u32 start_addr, u8 *buf, u32 len)
{
int ret = 0;
u32 i = 0;
u32 j = 0;
u32 packet_number = 0;
u32 packet_len = 0;
u32 addr = 0;
u32 offset = 0;
u32 remainder = 0;
u8 packet_buf[FTS_FLASH_PACKET_LENGTH + FTS_CMD_WRITE_LEN] = { 0 };
u8 ecc_in_host = 0;
u8 cmd[4] = {0};
u8 val[FTS_CMD_FLASH_STATUS_LEN] = { 0 };
u16 read_status = 0;
u16 wr_ok = 0;
printk(KERN_INFO "**********write app to flash**********");
if (NULL == buf) {
printk(KERN_ERR "buf is null");
return -EINVAL;
}
printk(KERN_INFO "tp fw len=%d", len);
packet_number = len / FTS_FLASH_PACKET_LENGTH;
remainder = len % FTS_FLASH_PACKET_LENGTH;
if (remainder > 0)
packet_number++;
packet_len = FTS_FLASH_PACKET_LENGTH;
printk(KERN_INFO "write fw,num:%d, remainder:%d", packet_number, remainder);
packet_buf[0] = FTS_CMD_WRITE;
for (i = 0; i < packet_number; i++) {
offset = i * FTS_FLASH_PACKET_LENGTH;
addr = start_addr + offset;
packet_buf[1] = BYTE_OFF_16(addr);
packet_buf[2] = BYTE_OFF_8(addr);
packet_buf[3] = BYTE_OFF_0(addr);
/* last packet */
if ((i == (packet_number - 1)) && remainder)
packet_len = remainder;
packet_buf[4] = BYTE_OFF_8(packet_len);
packet_buf[5] = BYTE_OFF_0(packet_len);
for (j = 0; j < packet_len; j++) {
packet_buf[FTS_CMD_WRITE_LEN + j] = buf[offset + j];
ecc_in_host ^= packet_buf[FTS_CMD_WRITE_LEN + j];
}
ret = fts_i2c_write(client, packet_buf, packet_len + FTS_CMD_WRITE_LEN);
if (ret < 0) {
printk(KERN_ERR "[UPGRADE]app write fail");
return ret;
}
mdelay(1);
/* read status */
wr_ok = FTS_FLASH_STATUS_OK_FT6336GU + i + 1;
for (j = 0; j < FTS_RETRIES_WRITE; j++) {
cmd[0] = FTS_CMD_FLASH_STATUS;
cmd[1] = 0x00;
cmd[2] = 0x00;
cmd[3] = 0x00;
ret = fts_i2c_read(client, cmd , 4, val, FTS_CMD_FLASH_STATUS_LEN);
read_status = (((u16)val[0]) << 8) + val[1];
if (wr_ok == read_status) {
break;
}
mdelay(FTS_RETRIES_DELAY_WRITE);
}
}
return (int)ecc_in_host;
}
/************************************************************************
* Name: fts_ft6336gu_ecc_cal
* Brief:
* Input:
* Output:
* Return: return ecc if success, otherwise return error code
***********************************************************************/
static int fts_ft6336gu_ecc_cal(struct i2c_client *client)
{
int ret = 0;
u8 reg_val = 0;
u8 cmd = 0;
printk(KERN_INFO "read out ecc");
cmd = 0xcc;
ret = fts_i2c_read(client, &cmd, 1, &reg_val, 1);
if (ret < 0) {
printk(KERN_ERR "read ft6336gu ecc fail");
return ret;
}
return reg_val;
}
/************************************************************************
* Name: fts_fwupg_reset_in_boot
* Brief: RST CMD(07), reset to romboot(bootloader) in boot environment
* Input:
* Output:
* Return: return 0 if success, otherwise return error code
***********************************************************************/
int fts_fwupg_reset_in_boot(struct i2c_client *client)
{
int ret = 0;
u8 cmd = FTS_CMD_RESET;
printk(KERN_INFO "reset in boot environment");
ret = fts_i2c_write(client, &cmd, 1);
if (ret < 0) {
printk(KERN_ERR "pram/rom/bootloader reset cmd write fail");
return ret;
}
msleep(FTS_DELAY_UPGRADE_RESET);
return 0;
}
/************************************************************************
* Name: fts_ft6336gu_upgrade
* Brief:
* Input:
* Output:
* Return: return 0 if success, otherwise return error code
***********************************************************************/
static int fts_ft6336gu_upgrade(struct i2c_client *client, u8 *buf, u32 len)
{
int ret = 0;
bool state = false;
u32 start_addr = 0;
int ecc_in_host = 0;
int ecc_in_tp = 0;
u32 fw_length = 0;
if (NULL == buf) {
printk(KERN_ERR "fw buf is null");
return -EINVAL;
}
if ((len < 0x120) || (len > (60 * 1024))) {
printk(KERN_ERR "fw buffer len(%x) fail", len);
return -EINVAL;
}
fw_length = ((u32)buf[0x100] << 8) + buf[0x101];
printk(KERN_INFO "fw length is %d %d", fw_length, len);
/* enter into upgrade environment */
state = fts_fwupg_check_fw_valid(client);
if (true == state) {
ret = fts_ft6336gu_reset_to_boot(client);
if (ret < 0) {
printk(KERN_ERR "enter into bootloader fail");
goto fw_reset;
}
}
state = fts_fwupg_check_state(client, FTS_RUN_IN_BOOTLOADER);
if (!state) {
printk(KERN_ERR "fw not in bootloader, fail");
goto fw_reset;
}
ret = fts_ft6336gu_erase(client);
if (ret < 0) {
printk(KERN_ERR "erase cmd write fail");
goto fw_reset;
}
/* write app */
//start_addr = upgrade_func_ft6336gu.appoff;
start_addr = 0x0000;
ecc_in_host = fts_ft6336gu_write_app(client, start_addr, buf, fw_length);
if (ecc_in_host < 0 ) {
printk(KERN_ERR "lcd initial code write fail");
goto fw_reset;
}
/* ecc */
ecc_in_tp = fts_ft6336gu_ecc_cal(client);
if (ecc_in_tp < 0 ) {
printk(KERN_ERR "ecc read fail");
goto fw_reset;
}
printk(KERN_INFO "ecc in tp:%x, host:%x", ecc_in_tp, ecc_in_host);
if (ecc_in_tp != ecc_in_host) {
printk(KERN_ERR "ecc check fail");
goto fw_reset;
}
printk(KERN_INFO "upgrade success, reset to normal boot");
ret = fts_fwupg_reset_in_boot(client);
if (ret < 0) {
printk(KERN_ERR "reset to normal boot fail");
}
msleep(200);
return 0;
fw_reset:
printk(KERN_INFO "upgrade fail, reset to normal boot");
ret = fts_fwupg_reset_in_boot(client);
if (ret < 0) {
printk(KERN_ERR "reset to normal boot fail");
}
return -EIO;
}
/************************************************************************
* 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_lenth)
{
u8 reg_val[2] = {0};
u32 i = 0;
u32 packet_number;
u32 j;
u32 temp;
u32 lenght;
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);
msleep(5);
} 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)
{
FTS_DBG("[FTS] Step 3: CTPM ID OK ,ID1 = 0x%x,ID2 = 0x%x\n",reg_val[0], reg_val[1]);
break;
}
else
{
dev_err(&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*/
FTS_DBG("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;
FTS_DBG("Step 5:write firmware(FW) to ctpm flash\n");
dw_lenth = dw_lenth - 8;
packet_number = (dw_lenth) / 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;
lenght = FTS_PACKET_LENGTH;
packet_buf[4] = (u8) (lenght >> 8);
packet_buf[5] = (u8) lenght;
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_lenth) % FTS_PACKET_LENGTH > 0)
{
temp = packet_number * FTS_PACKET_LENGTH;
packet_buf[2] = (u8) (temp >> 8);
packet_buf[3] = (u8) temp;
temp = (dw_lenth) % 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_lenth + i];
bt_ecc ^= packet_buf[6];
fts_i2c_write(client, packet_buf, 7);
msleep(20);
}
/*********Step 6: read out checksum***********************/
/*send the opration head */
FTS_DBG("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_err(&client->dev, "[FTS]--ecc error! FW=%02x bt_ecc=%02x\n",reg_val[0],bt_ecc);
return -EIO;
}
/*********Step 7: reset the new FW***********************/
FTS_DBG("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_lenth)
{
u8 reg_val[4] = {0};
u32 i = 0;
u32 packet_number;
u32 j;
u32 temp;
u32 lenght;
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)
{
FTS_DBG("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)
{
FTS_DBG("[FTS] Step 3: READ OK CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n", reg_val[0], reg_val[1]);
break;
}
else
{
dev_err(&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*/
FTS_DBG("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;
FTS_DBG("Step 5:write firmware(FW) to ctpm flash\n");
temp = 0;
packet_number = (dw_lenth) / 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;
lenght = FTS_PACKET_LENGTH;
packet_buf[4] = (u8) (lenght >> 8);
packet_buf[5] = (u8) lenght;
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_lenth) % FTS_PACKET_LENGTH > 0)
{
temp = packet_number * FTS_PACKET_LENGTH;
packet_buf[2] = (u8) (temp >> 8);
packet_buf[3] = (u8) temp;
temp = (dw_lenth) % 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***********************/
FTS_DBG("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);
printk(KERN_WARNING "Checksum FT5X26:%X %X \n", reg_val[0], bt_ecc);
if (reg_val[0] != bt_ecc)
{
dev_err(&client->dev, "[FTS]--ecc error! FW=%02x bt_ecc=%02x\n",reg_val[0],bt_ecc);
return -EIO;
}
/*********Step 7: reset the new FW***********************/
FTS_DBG("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*****/
FTS_DBG("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_lenth)
{
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 = 0;
u32 lenght;
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;
}
else
{
dev_err(&client->dev, "[FTS] Step 3: CTPM ID FAILD,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_lenth = dw_lenth - 8;
}
else if(is_5336_new_bootloader == BL_VERSION_GZF)
{
dw_lenth = dw_lenth - 14;
}
packet_number = (dw_lenth) / 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;
lenght = FTS_PACKET_LENGTH;
packet_buf[4] = (u8)(lenght>>8);
packet_buf[5] = (u8)lenght;
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_lenth) % FTS_PACKET_LENGTH > 0)
{
temp = packet_number * FTS_PACKET_LENGTH;
packet_buf[2] = (u8)(temp>>8);
packet_buf[3] = (u8)temp;
temp = (dw_lenth) % 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_lenth + i];
bt_ecc ^= packet_buf[6];
fts_i2c_write(client, packet_buf, 7);
msleep(10);
}
}
else if(is_5336_new_bootloader == BL_VERSION_GZF)
{
for (i = 0; i<12; i++)
{
if (is_5336_new_bootloader == BL_VERSION_Z7)
{
temp = 0x7ff4 + i;
}
else if(is_5336_new_bootloader == BL_VERSION_LZ4)
{
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_lenth + i];
bt_ecc ^= packet_buf[6];
fts_i2c_write(client, packet_buf, 7);
msleep(10);
}
}
/*********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_err(&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_lenth)
{
u8 reg_val[4] = {0};
u32 i = 0;
u32 packet_number;
u32 j;
u32 temp;
u32 lenght;
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)
{
FTS_DBG("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)
{
FTS_DBG("HidI2c change to StdI2c fail ! \n");
}
msleep(5);
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)
{
FTS_DBG("failed writing 0x55 and 0xaa ! \n");
continue;
}
/*********Step 3:check READ-ID***********************/
msleep(1);
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)
{
FTS_DBG("[FTS] Step 3: READ OK CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n", reg_val[0], reg_val[1]);
break;
}
else
{
dev_err(&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*/
FTS_DBG("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);
}
printk("[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_lenth >> 16) & 0xFF);
auc_i2c_write_buf[2] = (u8) ((dw_lenth >> 8) & 0xFF);
auc_i2c_write_buf[3] = (u8) (dw_lenth & 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;
FTS_DBG("Step 5:write firmware(FW) to ctpm flash\n");
temp = 0;
packet_number = (dw_lenth) / 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;
lenght = FTS_PACKET_LENGTH;
packet_buf[4] = (u8) (lenght >> 8);
packet_buf[5] = (u8) lenght;
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];
}
printk("[FTS][%s] bt_ecc = %x \n", __func__, bt_ecc);
if (bt_ecc != bt_ecc_check)
printk("[FTS][%s] Host checksum 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;
}
printk("[FTS][%s] reg_val[0] = %x reg_val[1] = %x \n", __func__, reg_val[0], reg_val[1]);
msleep(1);
}
}
if ((dw_lenth) % FTS_PACKET_LENGTH > 0)
{
temp = packet_number * FTS_PACKET_LENGTH;
packet_buf[2] = (u8) (temp >> 8);
packet_buf[3] = (u8) temp;
temp = (dw_lenth) % 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);
printk("[FTS][%s] bt_ecc = %x \n", __func__, bt_ecc);
if (bt_ecc != bt_ecc_check)
printk("[FTS][%s] Host checksum 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);
printk("[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;
}
printk("[FTS][%s] reg_val[0] = %x reg_val[1] = %x \n", __func__, reg_val[0], reg_val[1]);
msleep(1);
}
}
msleep(50);
/*********Step 6: read out checksum***********************/
/*send the opration head */
FTS_DBG("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_lenth;
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_lenth/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_err(&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_err(&client->dev, "[FTS]--reg_val[0]=%02x reg_val[0]=%02x\n", reg_val[0], reg_val[1]);
break;
}
msleep(1);
}
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_err(&client->dev, "[FTS]--ecc error! FW=%02x bt_ecc=%02x\n", reg_val[0], bt_ecc);
return -EIO;
}
printk(KERN_WARNING "checksum %X %X \n", reg_val[0], bt_ecc);
/*********Step 7: reset the new FW***********************/
FTS_DBG("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)
{
FTS_DBG("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_lenth)
{
u8 reg_val[2] = {0};
u32 i = 0;
u32 packet_number;
u32 j;
u32 temp;
u32 lenght;
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);
msleep(5);
} 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)
{
FTS_DBG("[FTS] Step 3: CTPM ID OK,ID1 = 0x%x,ID2 = 0x%x\n",reg_val[0], reg_val[1]);
break;
}
else
{
dev_err(&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*/
FTS_DBG("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;
FTS_DBG("Step 5:write firmware(FW) to ctpm flash\n");
dw_lenth = dw_lenth - 8;
packet_number = (dw_lenth) / 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;
lenght = FTS_PACKET_LENGTH;
packet_buf[4] = (u8) (lenght >> 8);
packet_buf[5] = (u8) lenght;
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_lenth) % FTS_PACKET_LENGTH > 0)
{
temp = packet_number * FTS_PACKET_LENGTH;
packet_buf[2] = (u8) (temp >> 8);
packet_buf[3] = (u8) temp;
temp = (dw_lenth) % 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_lenth + i];
bt_ecc ^= packet_buf[6];
fts_i2c_write(client, packet_buf, 7);
msleep(20);
}
/*********Step 6: read out checksum***********************/
/*send the opration head */
FTS_DBG("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_err(&client->dev, "[FTS]--ecc error! FW=%02x bt_ecc=%02x\n",
reg_val[0], bt_ecc);
return -EIO;
}
/*********Step 7: reset the new FW***********************/
FTS_DBG("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_lenth)
{
u8 reg_val[4] = {0};
u32 i = 0;
u32 packet_number;
u32 j;
u32 temp;
u32 lenght;
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)
{
FTS_DBG("[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)
{
FTS_DBG("[FTS] hid change to i2c fail ! \n");
}
msleep(10);
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)
{
FTS_DBG("[FTS] failed writing 0x55 and 0xaa ! \n");
continue;
}
/*********Step 3:check READ-ID***********************/
msleep(1);
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)
{
FTS_DBG("[FTS] Step 3: READ OK CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",reg_val[0], reg_val[1]);
break;
}
else
{
dev_err(&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*/
FTS_DBG("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);
}
printk("[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_lenth >> 16) & 0xFF);
auc_i2c_write_buf[2] = (u8) ((dw_lenth >> 8) & 0xFF);
auc_i2c_write_buf[3] = (u8) (dw_lenth & 0xFF);
fts_i2c_write(client, auc_i2c_write_buf, 4);
/*********Step 5:write firmware(FW) to ctpm flash*********/
bt_ecc = 0;
FTS_DBG("Step 5:write firmware(FW) to ctpm flash\n");
temp = 0;
packet_number = (dw_lenth) / 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;
lenght = FTS_PACKET_LENGTH;
packet_buf[4] = (u8) (lenght >> 8);
packet_buf[5] = (u8) lenght;
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;
}
printk("[FTS][%s] reg_val[0] = %x reg_val[1] = %x \n", __func__, reg_val[0], reg_val[1]);
msleep(1);
}
}
if ((dw_lenth) % FTS_PACKET_LENGTH > 0)
{
temp = packet_number * FTS_PACKET_LENGTH;
packet_buf[2] = (u8) (temp >> 8);
packet_buf[3] = (u8) temp;
temp = (dw_lenth) % 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);
printk("[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;
}
printk("[FTS][%s] reg_val[0] = %x reg_val[1] = %x \n", __func__, reg_val[0], reg_val[1]);
msleep(1);
}
}
msleep(50);
/*********Step 6: read out checksum***********************/
/*send the opration head */
FTS_DBG("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_lenth;
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_lenth/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_err(&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_err(&client->dev, "[FTS]--reg_val[0]=%02x reg_val[0]=%02x\n", reg_val[0], reg_val[1]);
break;
}
msleep(1);
}
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_err(&client->dev, "[FTS]--ecc error! FW=%02x bt_ecc=%02x\n",
reg_val[0], bt_ecc);
return -EIO;
}
printk(KERN_WARNING "checksum %X %X \n",reg_val[0],bt_ecc);
/*********Step 7: reset the new FW***********************/
FTS_DBG("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)
{
FTS_DBG("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_lenth)
{
u8 reg_val[4] = {0};
u32 i = 0;
u32 packet_number;
u32 j;
u32 temp;
u32 lenght;
u8 packet_buf[FTS_PACKET_LENGTH + 6];
u8 auc_i2c_write_buf[10];
u8 bt_ecc;
int i_ret;
FTS_DBG("8606 dw_lenth= %d",dw_lenth);
if(dw_lenth > 0x10000 || dw_lenth ==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)
{
FTS_DBG("[FTS] failed writing 0x55 ! \n");
continue;
}
/*********Step 3:check READ-ID***********************/
msleep(1);
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] == 0x06))
{
msleep(50);
break;
}
else
{
dev_err(&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;
FTS_DBG("Step 5:write firmware(FW) to ctpm flash\n");
temp = 0;
packet_number = (dw_lenth) / 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;
lenght = FTS_PACKET_LENGTH;
packet_buf[4] = (u8) (lenght >> 8);
packet_buf[5] = (u8) lenght;
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_lenth) % FTS_PACKET_LENGTH > 0)
{
temp = packet_number * FTS_PACKET_LENGTH;
packet_buf[2] = (u8) (temp >> 8);
packet_buf[3] = (u8) temp;
temp = (dw_lenth) % 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 */
FTS_DBG("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_err(&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);
FTS_DBG("Read flash and compare\n");
msleep(50);
/*********Step 6: start app***********************/
FTS_DBG("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_lenth)
{
u8 reg_val[4] = {0};
u8 reg_val_id[4] = {0};
u32 i = 0;
u32 packet_number;
u32 j;
u32 temp;
u32 lenght;
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_lenth == 0)
{
return -EIO;
}
if(0x81 == (int)reg_val_id[0])
{
if(dw_lenth > 1024*60)
{
return -EIO;
}
}
else if(0x80 == (int)reg_val_id[0])
{
if(dw_lenth > 1024*64)
{
return -EIO;
}
}
for (i = 0; i < FTS_UPGRADE_LOOP; i++)
{
msleep(10);
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)
{
FTS_DBG("failed writing 0x55 and 0xaa ! \n");
continue;
}
/*********Step 3:check READ-ID***********************/
msleep(1);
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)) {
FTS_DBG("[FTS] Step 3: READ OK CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",
reg_val[0], reg_val[1]);
break;
} else {
dev_err(&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*/
FTS_DBG("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_lenth ; 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;
FTS_DBG("Step 5:write firmware(FW) to ctpm flash\n");
temp = 0;
packet_number = (dw_lenth) / 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;
lenght = FTS_PACKET_LENGTH;
packet_buf[4] = (u8) (lenght >> 8);
packet_buf[5] = (u8) lenght;
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;
}
msleep(1);
}
}
if ((dw_lenth) % 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_lenth) % 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;
}
msleep(1);
}
}
msleep(50);
/*********Step 6: read out checksum***********************/
/*send the opration head */
FTS_DBG("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_lenth > LEN_FLASH_ECC_MAX)
{
temp = LEN_FLASH_ECC_MAX;
}
else
{
temp = dw_lenth;
FTS_DBG("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_lenth/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;
}
msleep(1);
}
//----------------------------------------------------------------------
if (dw_lenth > 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_lenth-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_lenth/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;
}
msleep(1);
}
}
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_err(&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***********************/
FTS_DBG("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_3x27_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_lenth)
{
u8 reg_val[2] = {0};
u32 i = 0;
u32 packet_number;
u32 j;
u32 temp;
u32 lenght;
u32 fw_length;
u8 packet_buf[FTS_PACKET_LENGTH + 6];
u8 auc_i2c_write_buf[10];
u8 bt_ecc;
if(pbt_buf[0] != 0x02)
{
FTS_DBG("[FTS] FW first byte is not 0x02. so it is invalid \n");
return -1;
}
if(dw_lenth > 0x11f)
{
fw_length = ((u32)pbt_buf[0x100]<<8) + pbt_buf[0x101];
if(dw_lenth < fw_length)
{
FTS_DBG("[FTS] Fw length is invalid \n");
return -1;
}
}
else
{
FTS_DBG("[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)
{
FTS_DBG("[FTS] Step 3: GET CTPM ID OK,ID1 = 0x%x,ID2 = 0x%x\n",
reg_val[0], reg_val[1]);
break;
}
else
{
dev_err(&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*/
FTS_DBG("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])
{
FTS_DBG("[FTS] erase app finished \n");
break;
}
msleep(50);
}
/*********Step 5:write firmware(FW) to ctpm flash*********/
bt_ecc = 0;
FTS_DBG("Step 5:write firmware(FW) to ctpm flash\n");
dw_lenth = fw_length;
packet_number = (dw_lenth) / 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;
lenght = FTS_PACKET_LENGTH;
packet_buf[4] = (u8) (lenght >> 8);
packet_buf[5] = (u8) lenght;
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)) == (((reg_val[0] & 0x0f) << 8) |reg_val[1]))
{
FTS_DBG("[FTS] write a block data finished \n");
break;
}
msleep(1);
}
}
if ((dw_lenth) % FTS_PACKET_LENGTH > 0)
{
temp = packet_number * FTS_PACKET_LENGTH;
packet_buf[2] = (u8) (temp >> 8);
packet_buf[3] = (u8) temp;
temp = (dw_lenth) % 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)) == (((reg_val[0] & 0x0f) << 8) |reg_val[1]))
{
FTS_DBG("[FTS] write a block data finished \n");
break;
}
msleep(1);
}
}
/*********Step 6: read out checksum***********************/
FTS_DBG("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_err(&client->dev, "[FTS]--ecc error! FW=%02x bt_ecc=%02x\n",
reg_val[0],
bt_ecc);
return -EIO;
}
/*********Step 7: reset the new FW***********************/
FTS_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);
return 0;
}
/*
*note:the firmware default path is sdcard.
if you want to change the dir, please modify by yourself.
*/
/************************************************************************
* Name: fts_GetFirmwareSize
* Brief: get file size
* Input: file name
* Output: no
* Return: file size
***********************************************************************/
static int fts_GetFirmwareSize(char *firmware_name)
{
struct file *pfile = NULL;
struct inode *inode;
unsigned long magic;
off_t fsize = 0;
char filepath[128];
memset(filepath, 0, sizeof(filepath));
sprintf(filepath, "%s%s", FTXXXX_INI_FILEPATH_CONFIG, firmware_name);
if (NULL == pfile)
{
pfile = filp_open(filepath, O_RDONLY, 0);
}
if (IS_ERR(pfile))
{
pr_err("error occured while opening file %s.\n", filepath);
return -EIO;
}
inode = pfile->f_dentry->d_inode;
magic = inode->i_sb->s_magic;
fsize = inode->i_size;
filp_close(pfile, NULL);
return fsize;
}
/************************************************************************
* 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 (NULL == pfile)
{
pfile = filp_open(filepath, O_RDONLY, 0);
}
if (IS_ERR(pfile))
{
pr_err("error occured while opening file %s.\n", filepath);
return -EIO;
}
inode = pfile->f_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 = fts_GetFirmwareSize(firmware_name);
if (fwsize <= 0)
{
dev_err(&client->dev, "%s ERROR:Get firmware size failed\n",__func__);
return -EIO;
}
dev_err(&client->dev, "dean tag CHIP_ID : 0x%x\n", fts_updateinfo_curr.CHIP_ID);
/*=========FW upgrade========================*/
pbt_buf = (unsigned char *)kmalloc(fwsize + 1, GFP_ATOMIC);
if (fts_ReadFirmware(firmware_name, pbt_buf))
{
dev_err(&client->dev, "%s() - ERROR: request_firmware failed\n",__func__);
kfree(pbt_buf);
return -EIO;
}
i_ret = fts_ft6336gu_upgrade(client, pbt_buf, fwsize);
if (i_ret != 0)
dev_err(&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
***********************************************************************/
int fts_ctpm_get_i_file_ver(void)
{
u16 ui_sz;
ui_sz = sizeof(CTPM_FW);
if (ui_sz > 2)
{
if(fts_updateinfo_curr.CHIP_ID==0x36 || fts_updateinfo_curr.CHIP_ID==0x86 || fts_updateinfo_curr.CHIP_ID==0x64)
return CTPM_FW[0x10a];
else if(fts_updateinfo_curr.CHIP_ID==0x58)
return CTPM_FW[0x1D0A];
else
return CTPM_FW[ui_sz - 2];
}
return 0x00;
}
int fts_ctpm_get_i_file_ver_for_cci(void)
{
u16 ui_sz = fw_size;
if (ui_sz > 0)
return CTPM_FW[0xB4EC];
else
return 0x00;
}
/************************************************************************
* 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);
msleep(5);
} 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_err(&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_err(&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_err(&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_err(&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_err(&client->dev, "%s:upgrade failed. err.\n",__func__);
}
else if ((fts_updateinfo_curr.CHIP_ID==0x64))
{
pbt_buf = CTPM_FW;
i_ret = fts_ft6336gu_upgrade(client, pbt_buf, sizeof(CTPM_FW));
if (i_ret != 0)
dev_err(&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_err("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_err(&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_err("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_err(&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_err("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_err(&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_err(&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_err(&client->dev, "%s:upgrade failed. err.\n",__func__);
}
else if ((fts_updateinfo_curr.CHIP_ID==0x86))
{
/*FW upgrade*/
pbt_buf = CTPM_FW;
dev_err(&client->dev, "%s:upgrade failed. err, chip is 3027\n",__func__);
return -EIO;
/*call the upgrade function*/
//i_ret = fts_8606_writepram(client, aucFW_PRAM_BOOT, sizeof(aucFW_PRAM_BOOT));
if (i_ret != 0)
{
dev_err(&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_err(&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;
}
int fts_ctpm_fw_upgrade_with_i_file_for_cci_3207(struct i2c_client *client)
{
int i_ret= -1;
/*judge the fw that will be upgraded
* if illegal, then stop upgrade and return.
*/
i_ret = fts_ft6336gu_upgrade(client, CTPM_FW, fw_size);
if (i_ret != 0)
dev_err(&client->dev, "%s:upgrade failed. err.\n",__func__);
return i_ret;
}
/************************************************************************
* Name: fts_ctpm_auto_upgrade
* Brief: auto upgrade
* Input: i2c info
* Output: no
* Return: 0
***********************************************************************/
int fts_ctpm_auto_upgrade(struct i2c_client *client)
{
u8 uc_host_fm_ver = FTS_REG_FW_VER;
u8 uc_tp_fm_ver;
int i_ret;
fts_read_reg(client, FTS_REG_FW_VER, &uc_tp_fm_ver);
uc_host_fm_ver = fts_ctpm_get_i_file_ver();
FTS_DBG("[FTS] uc_tp_fm_ver = 0x%x, uc_host_fm_ver = 0x%x\n",uc_tp_fm_ver, uc_host_fm_ver);
if (uc_tp_fm_ver == FTS_REG_FW_VER || uc_tp_fm_ver < uc_host_fm_ver )
{
msleep(100);
i_ret = fts_ctpm_fw_upgrade_with_i_file(client);
if (i_ret == 0)
{
msleep(300);
uc_host_fm_ver = fts_ctpm_get_i_file_ver();
FTS_DBG("[FTS] upgrade to new version 0x%x\n",uc_host_fm_ver);
}
else
{
pr_err("[FTS] upgrade failed ret=%d.\n", i_ret);
return -EIO;
}
} else {
FTS_DBG("[FTS] version is newest, no need upgrade FW\n");
}
return 0;
}
/************************************************************************
* Name: fts_ctpm_auto_upgrade_for_cci
* Brief: auto upgrade
* Input: i2c info
* Output: no
* Return: 0
***********************************************************************/
int fts_ctpm_auto_upgrade_for_cci(struct i2c_client *client, const u8 tp_id, bool force_upgrade)
{
u8 uc_host_fm_ver = FTS_REG_FW_VER;
u8 uc_tp_fm_ver;
int i_ret;
struct fts_ts_data *fts_data = (struct fts_ts_data *)i2c_get_clientdata(client);
switch (tp_id) {
case 0:
case TP_ID_0:
CTPM_FW = CTPM_FW_TP_ID_0;
fw_size = sizeof(CTPM_FW_TP_ID_0);
break;
case TP_ID_1:
CTPM_FW = CTPM_FW_TP_ID_1;
fw_size = sizeof(CTPM_FW_TP_ID_1);
break;
case TP_ID_2:
CTPM_FW = CTPM_FW_TP_ID_2;
fw_size = sizeof(CTPM_FW_TP_ID_2);
break;
case TP_ID_3:
CTPM_FW = CTPM_FW_TP_ID_3;
fw_size = sizeof(CTPM_FW_TP_ID_3);
break;
default:
FTS_DBG("[FTS] TP ID 0x%x isn't correct\n", tp_id);
return 1;
break;
}
uc_tp_fm_ver = fts_data->fw_ver[0];
uc_host_fm_ver = fts_ctpm_get_i_file_ver_for_cci();
FTS_DBG("[FTS] uc_tp_fm_ver = 0x%x, uc_host_fm_ver = 0x%x\n",uc_tp_fm_ver, uc_host_fm_ver);
if ( uc_tp_fm_ver != uc_host_fm_ver || force_upgrade)
{
msleep(100);
i_ret = fts_ctpm_fw_upgrade_with_i_file_for_cci_3207(client);
if (i_ret == 0)
{
msleep(300);
FTS_DBG("[FTS] upgrade to new version 0x%x\n",uc_host_fm_ver);
}
else
{
pr_err("[FTS] upgrade failed ret=%d.\n", i_ret);
return -EIO;
}
} else {
FTS_DBG("[FTS] version is newest, no need upgrade FW\n");
return 1;
}
return 0;
}