From 1f77e12c0337ba64b65898d57cedf7525c5763e3 Mon Sep 17 00:00:00 2001 From: wengjun1 Date: Mon, 30 Jul 2018 11:29:30 +0800 Subject: [PATCH] DLKM: Improve ili9881h touch driver Optimization of firmware upgrading process Change-Id: I776b3b69157600e2ac63ce7e4b785e342e02f5f8 Signed-off-by: wengjun1 Reviewed-on: https://gerrit.mot.com/1216816 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Yeqing Wang Reviewed-by: Huosheng Liao Submit-Approved: Jira Key --- .../touchscreen/ilitek_mmi/core/firmware.c | 105 ++++++++++++++++++ .../touchscreen/ilitek_mmi/core/firmware.h | 12 ++ .../input/touchscreen/ilitek_mmi/core/i2c.c | 1 - .../input/touchscreen/ilitek_mmi/platform.c | 24 ++++ 4 files changed, 141 insertions(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/ilitek_mmi/core/firmware.c b/drivers/input/touchscreen/ilitek_mmi/core/firmware.c index c551accdb467..03123a3e1723 100644 --- a/drivers/input/touchscreen/ilitek_mmi/core/firmware.c +++ b/drivers/input/touchscreen/ilitek_mmi/core/firmware.c @@ -63,6 +63,7 @@ uint8_t gesture_fw[MAX_GESTURE_FIRMWARE_SIZE] = { 0 }; uint8_t iram_fw[MAX_IRAM_FIRMWARE_SIZE] = { 0 }; #endif +#define CRC_ONESET(X, Y) ({Y = (*(X+0) << 24) | (*(X+1) << 16) | (*(X+2) << 8) | (*(X+3));}) /* the length of array in each sector */ int g_section_len; int g_total_sector; @@ -470,6 +471,110 @@ out: return res; } +static int tddi_read_flash(uint32_t start, uint32_t end, uint8_t *data, int dlen) +{ + uint32_t i, cont = 0; + + ipio_info("start = %x , end = %x\n", start, end); + if (data == NULL) { + ipio_err("data is null, read failed\n"); + return -1; + } + + if (end - start > dlen) { + ipio_err("the length (%d) reading crc is over than dlen(%d)\n", end - start, dlen); + return -1; + } + + core_config_ice_mode_write(0x041000, 0x0, 1); /* CS low */ + core_config_ice_mode_write(0x041004, 0x66aa55, 3); /* Key */ + core_config_ice_mode_write(0x041008, 0x03, 1); + + core_config_ice_mode_write(0x041008, (start & 0xFF0000) >> 16, 1); + core_config_ice_mode_write(0x041008, (start & 0x00FF00) >> 8, 1); + core_config_ice_mode_write(0x041008, (start & 0x0000FF), 1); + + for (i = start; i <= end; i++) { + core_config_ice_mode_write(0x041008, 0xFF, 1); /* Dummy */ + + data[cont] = core_config_read_write_onebyte(0x41010); + ipio_info("data[%d] = %x\n", cont, data[cont]); + cont++; + } + + core_config_ice_mode_write(0x041000, 0x1, 1); /* CS high */ + return 0; +} + +int tddi_check_fw_upgrade(void) +{ + int ret = NO_NEED_UPDATE; + int i, crc_byte_len = 4; + uint8_t flash_crc[4] = {0}; + uint32_t start_addr = 0, end_addr = 0, flash_crc_cb; + + ilitek_platform_disable_irq(); + + ret = core_config_ice_mode_enable(); + if (ret < 0) { + ipio_err("Failed to enable ICE mode\n"); + goto out; + } + + mdelay(25); + + if (core_config_set_watch_dog(false) < 0) { + ipio_err("Failed to disable watch dog\n"); + ret = -EINVAL; + goto out; + } + + g_flash_block_info[0].start_addr = AP_STAR_ADDR; + g_flash_block_info[0].end_addr = AP_END_ADDR; + g_flash_block_info[1].start_addr = DATA_STAR_ADDR; + g_flash_block_info[1].end_addr = DATA_END_ADDR; + g_flash_block_info[2].start_addr = MP_STAR_ADDR; + g_flash_block_info[2].end_addr = MP_END_ADDR; + /* Check Flash CRC and HW CRC */ + for(i = 0; i <3; i++) { + start_addr = g_flash_block_info[i].start_addr; + end_addr = g_flash_block_info[i].end_addr; + + /* Invaild end address */ + if (end_addr == 0) + continue; + + ret = tddi_read_flash(end_addr - crc_byte_len + 1, end_addr, flash_crc, sizeof(flash_crc)); + if (ret < 0) { + ipio_info("Read Flash failed\n"); + ret = CHECK_FW_FAIL; + goto out; + } + CRC_ONESET(flash_crc, flash_crc_cb); + + if (g_flash_block_info[i].block_crc == 0) + g_flash_block_info[i].block_crc = tddi_check_data(start_addr, end_addr - start_addr - crc_byte_len + 1); + + ipio_info("HW CRC = 0x%06x, Flash CRC = 0x%06x\n", g_flash_block_info[i].block_crc, flash_crc_cb); + + /* Compare Hex to HW's CRC directly instead of fw version */ + if(flash_crc_cb != g_flash_block_info[i].block_crc) + { + ret = NEED_UPDATE; + goto out; + } + + memset(flash_crc, 0, sizeof(flash_crc)); + } + +out: + /* We do have to reset chip in order to move new code from flash to iram. */ + ipio_info("Doing Soft Reset ..\n"); + core_config_ic_reset(); + + return ret; +} + #ifndef HOST_DOWNLOAD static int iram_upgrade(void) { diff --git a/drivers/input/touchscreen/ilitek_mmi/core/firmware.h b/drivers/input/touchscreen/ilitek_mmi/core/firmware.h index 863c83a3a4a9..9f830820da33 100644 --- a/drivers/input/touchscreen/ilitek_mmi/core/firmware.h +++ b/drivers/input/touchscreen/ilitek_mmi/core/firmware.h @@ -25,6 +25,17 @@ #ifndef __FIRMWARE_H #define __FIRMWARE_H +#define CHECK_FW_FAIL -1 +#define NEED_UPDATE 1 +#define NO_NEED_UPDATE 0 + +#define AP_STAR_ADDR 0x00000 +#define AP_END_ADDR 0x0FFFF +#define DATA_STAR_ADDR 0x10000 +#define DATA_END_ADDR 0x11FFF +#define MP_STAR_ADDR 0x13000 +#define MP_END_ADDR 0x1BFFF + struct core_firmware_data { uint8_t new_fw_ver[4]; uint8_t old_fw_ver[4]; @@ -59,6 +70,7 @@ extern int core_firmware_boot_upgrade(void); /* extern int core_firmware_iram_upgrade(const char* fpath); */ extern int core_firmware_upgrade(const char *pFilePath, bool isIRAM); extern int core_firmware_init(void); +extern int tddi_check_fw_upgrade(void); extern void core_firmware_remove(void); #endif /* __FIRMWARE_H */ diff --git a/drivers/input/touchscreen/ilitek_mmi/core/i2c.c b/drivers/input/touchscreen/ilitek_mmi/core/i2c.c index d5452c43932c..c3df71268921 100644 --- a/drivers/input/touchscreen/ilitek_mmi/core/i2c.c +++ b/drivers/input/touchscreen/ilitek_mmi/core/i2c.c @@ -110,7 +110,6 @@ int core_i2c_write(uint8_t nSlaveId, uint8_t *pBuf, uint16_t nSize) goto out; } if (protocol->major >= 5 && protocol->mid >= 4) { - ipio_info("core_fr->actual_fw_mode=%d,pBuf[0]=%x", core_fr->actual_fw_mode, pBuf[0]); if (core_fr->actual_fw_mode == protocol->test_mode && pBuf[0] == 0xF1) { check_sum = core_fr_calc_checksum(pBuf, nSize); memcpy(txbuf, pBuf, nSize); diff --git a/drivers/input/touchscreen/ilitek_mmi/platform.c b/drivers/input/touchscreen/ilitek_mmi/platform.c index 0d9c918f5580..32595bb5b5d8 100644 --- a/drivers/input/touchscreen/ilitek_mmi/platform.c +++ b/drivers/input/touchscreen/ilitek_mmi/platform.c @@ -802,6 +802,25 @@ static int Ili_parse_dt(struct device *dev, } +/* + * The function will check the flash data is correct. + */ +void flash_data_check(void) +{ + int ret = NO_NEED_UPDATE; + ret = tddi_check_fw_upgrade(); + if (ret == NEED_UPDATE || ret == CHECK_FW_FAIL) { + core_config->firmware_ver[1] = 0; + core_config->firmware_ver[2] = 0; + core_config->firmware_ver[3] = 0; + core_config->firmware_ver[4] = 0; + ipio_err(" flash data is not correct\n"); + } else { + + ipio_info(" flash data is correct\n"); + } +} + /* * The probe func would be called after an i2c device was detected by kernel. * @@ -964,6 +983,11 @@ static int ilitek_platform_probe(struct spi_device *spi) goto read_tp_info_err; } + /* + * Check flash data is correct. + */ + flash_data_check(); + /* If it defines boot upgrade, input register will be done inside boot * function. */