From 69228e6b7bb9c8d55967a2b56e2347d825df8312 Mon Sep 17 00:00:00 2001 From: wangyq13 Date: Fri, 8 May 2020 00:20:33 +0800 Subject: [PATCH] input: himax_v2_mmi: Sync touch suspend and resume thread himax_v2_mmi: 1: Because system use drm notify to call touch suspend before display driver pull down vsn/vsp, rst pin. So touch suspend thread wait until touch resume thread end, avoid touch resume thread is interrupted by touch suspend thread. Set flag for resume start and end. Suspend tread will check this flag, if resume is not end, then don't pull down the vsn/vsp and reset pin, to avoid affect touch resume thread, especially touch firmware upgrade. 2: Sometimes the reverse thing happen, suspend thread is interrupted by resume thread. Such as the following process: touch suspend->lcd resume+touch resume->lcd suspend. So when lcd resume again, the last state of touch is resume, so touch will skip current resume process, don't download touch firmware. To fix this issue, force touch driver to execute the resume process. Change-Id: I0ed48ec2bf8f65e2db281bef0c7f6cc63051ea64 Signed-off-by: wangyq13 Reviewed-on: https://gerrit.mot.com/1549942 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Yiwen Liu Reviewed-by: Jun Weng Reviewed-by: Huosheng Liao Submit-Approved: Jira Key --- .../touchscreen/himax_v2_mmi/himax_common.c | 57 +++++++++++++++++++ .../touchscreen/himax_v2_mmi/himax_common.h | 2 + .../himax_v2_mmi/himax_ic_incell_core.c | 7 ++- .../himax_v2_mmi/himax_platform_QCT_SPI.c | 3 + .../himax_v2_mmi_hx83102d/himax_ic_HX83102d.c | 9 ++- 5 files changed, 73 insertions(+), 5 deletions(-) diff --git a/drivers/input/touchscreen/himax_v2_mmi/himax_common.c b/drivers/input/touchscreen/himax_v2_mmi/himax_common.c index 3b82778c2e4a..9607048b7e3b 100644 --- a/drivers/input/touchscreen/himax_v2_mmi/himax_common.c +++ b/drivers/input/touchscreen/himax_v2_mmi/himax_common.c @@ -140,6 +140,9 @@ int g_f_0f_updat; #endif struct himax_ts_data *private_ts; +#if defined(__HIMAX_HX83102D_MOD__) +extern struct zf_operation *pzf_op; +#endif EXPORT_SYMBOL(private_ts); struct himax_ic_data *ic_data; @@ -3434,11 +3437,38 @@ static int charger_notifier_callback(struct notifier_block *nb, } #endif +#if defined(__HIMAX_HX83102D_MOD__) +#define TP_CHECK_TIMES 30 +#define TP_CHECK_INTERVAL 10 +void himax_resume_thread_check(void) +{ + uint8_t cycle = 0; + + while (true) { + if(cycle++ > TP_CHECK_TIMES) + break; + + if (atomic_read(&private_ts->resume_thread_is_runing)) + msleep(TP_CHECK_INTERVAL); + else + break; + } + I("cycle:%d",cycle); + return; +} +#endif + #if defined(HX_RESUME_SET_FW) void himax_resume_work_func(struct work_struct *work) { struct himax_ts_data *ts = private_ts; +#if defined(__HIMAX_HX83102D_MOD__) + atomic_set(&private_ts->resume_thread_is_runing, 1); +#endif himax_chip_common_resume(ts); +#if defined(__HIMAX_HX83102D_MOD__) + atomic_set(&private_ts->resume_thread_is_runing, 0); +#endif return; } #endif @@ -3644,6 +3674,8 @@ FW_force_upgrade: pdata->cable_config[1] = 0x00; #endif ts->suspended = false; + atomic_set(&ts->resume_update_fail, 0); + atomic_set(&ts->resume_thread_is_runing, 0); mutex_init(&ts->suspend_resume_mutex); #if defined(HX_USB_DETECT_CALLBACK) || defined(HX_USB_DETECT_GLOBAL) ts->usb_connected = 0x00; @@ -3948,6 +3980,9 @@ END: int himax_chip_common_suspend(struct himax_ts_data *ts) { int ret = 0; +#if defined(__HIMAX_HX83102D_MOD__) + himax_resume_thread_check(); +#endif mutex_lock(&ts->suspend_resume_mutex); ret = _himax_chip_common_suspend(ts); mutex_unlock(&ts->suspend_resume_mutex); @@ -3959,15 +3994,29 @@ int _himax_chip_common_resume(struct himax_ts_data *ts) { #if defined(HX_ZERO_FLASH) && defined(HX_RESUME_SET_FW) int result = 0; +#endif +#if defined(__HIMAX_HX83102D_MOD__) + uint8_t tmp_data[DATA_LEN_4] = {0}; #endif I("%s: enter\n", __func__); +#if defined(__HIMAX_HX83102D_MOD__) + if (atomic_read(&ts->resume_update_fail)) { + I("%s:Last time update Fail!\n", __func__); + atomic_set(&ts->resume_update_fail, 0); + ts->suspended = false; + goto START_RESUME; + } +#endif if (ts->suspended == false) { I("%s: It had entered resume, skip this step\n", __func__); goto END; } else { ts->suspended = false; } +#if defined(__HIMAX_HX83102D_MOD__) +START_RESUME: +#endif #ifdef HX_ESD_RECOVERY /* continuous N times record, not total N times. */ @@ -4003,6 +4052,9 @@ int _himax_chip_common_resume(struct himax_ts_data *ts) result = g_core_fp.fp_0f_operation_dirly(); if (result) { E("Something is wrong! Skip Update with zero flash!\n"); +#if defined(__HIMAX_HX83102D_MOD__) + atomic_set(&ts->resume_update_fail, 1); +#endif goto ESCAPE_0F_UPDATE; } } @@ -4010,6 +4062,11 @@ int _himax_chip_common_resume(struct himax_ts_data *ts) g_core_fp.fp_reload_disable(0); if (g_core_fp.fp_sense_on != NULL) g_core_fp.fp_sense_on(0x00); +#if defined(__HIMAX_HX83102D_MOD__) + g_core_fp.fp_register_read(pzf_op->addr_sts_chk, DATA_LEN_4, tmp_data, 0); + if (tmp_data[0] != 0x05) + atomic_set(&ts->resume_update_fail, 1); +#endif #ifdef HX_SMART_WAKEUP } #endif diff --git a/drivers/input/touchscreen/himax_v2_mmi/himax_common.h b/drivers/input/touchscreen/himax_v2_mmi/himax_common.h index 4f016cf22ec4..7ac38db5afcc 100755 --- a/drivers/input/touchscreen/himax_v2_mmi/himax_common.h +++ b/drivers/input/touchscreen/himax_v2_mmi/himax_common.h @@ -364,6 +364,8 @@ struct himax_report_data { struct himax_ts_data { bool initialized; bool suspended; + atomic_t resume_update_fail; + atomic_t resume_thread_is_runing; atomic_t suspend_mode; struct mutex suspend_resume_mutex; uint8_t x_channel; diff --git a/drivers/input/touchscreen/himax_v2_mmi/himax_ic_incell_core.c b/drivers/input/touchscreen/himax_v2_mmi/himax_ic_incell_core.c index c78c28c633ff..5b790c1db55b 100755 --- a/drivers/input/touchscreen/himax_v2_mmi/himax_ic_incell_core.c +++ b/drivers/input/touchscreen/himax_v2_mmi/himax_ic_incell_core.c @@ -1177,13 +1177,16 @@ static void himax_mcu_idle_mode(int disable) static void himax_mcu_reload_disable(int disable) { + int ret = 0; I("%s:entering\n", __func__); if (disable) { /*reload disable*/ - g_core_fp.fp_register_write(pdriver_op->addr_fw_define_flash_reload, DATA_LEN_4, pdriver_op->data_fw_define_flash_reload_dis, 0); + ret= g_core_fp.fp_register_write(pdriver_op->addr_fw_define_flash_reload, DATA_LEN_4, pdriver_op->data_fw_define_flash_reload_dis, 0); } else { /*reload enable*/ - g_core_fp.fp_register_write(pdriver_op->addr_fw_define_flash_reload, DATA_LEN_4, pdriver_op->data_fw_define_flash_reload_en, 0); + ret= g_core_fp.fp_register_write(pdriver_op->addr_fw_define_flash_reload, DATA_LEN_4, pdriver_op->data_fw_define_flash_reload_en, 0); } + if (ret != 0) + atomic_set(&private_ts->resume_update_fail, 1); I("%s: setting OK!\n", __func__); } diff --git a/drivers/input/touchscreen/himax_v2_mmi/himax_platform_QCT_SPI.c b/drivers/input/touchscreen/himax_v2_mmi/himax_platform_QCT_SPI.c index d4c8f649b173..bb222d90c18d 100755 --- a/drivers/input/touchscreen/himax_v2_mmi/himax_platform_QCT_SPI.c +++ b/drivers/input/touchscreen/himax_v2_mmi/himax_platform_QCT_SPI.c @@ -950,6 +950,8 @@ int drm_notifier_callback(struct notifier_block *self, } } + /* Avoid HX83102D is called for early event and event, two times */ +#if !defined(__HIMAX_HX83102D_MOD__) if (evdata->data && event == MSM_DRM_EVENT_BLANK && ts != NULL && ts->dev != NULL) { blank = evdata->data; @@ -959,6 +961,7 @@ int drm_notifier_callback(struct notifier_block *self, break; } } +#endif return 0; } diff --git a/drivers/input/touchscreen/himax_v2_mmi/support_ic/himax_v2_mmi_hx83102d/himax_ic_HX83102d.c b/drivers/input/touchscreen/himax_v2_mmi/support_ic/himax_v2_mmi_hx83102d/himax_ic_HX83102d.c index 2ca679fbc37c..5f095fdebce3 100644 --- a/drivers/input/touchscreen/himax_v2_mmi/support_ic/himax_v2_mmi_hx83102d/himax_ic_HX83102d.c +++ b/drivers/input/touchscreen/himax_v2_mmi/support_ic/himax_v2_mmi_hx83102d/himax_ic_HX83102d.c @@ -694,6 +694,7 @@ static void himax_hx83102d_reload_to_active(void) uint8_t addr[DATA_LEN_4] = {0}; uint8_t data[DATA_LEN_4] = {0}; uint8_t retry_cnt = 0; + int ret = 0; addr[3] = 0x90; addr[2] = 0x00; @@ -705,12 +706,14 @@ static void himax_hx83102d_reload_to_active(void) data[2] = 0x00; data[1] = 0x00; data[0] = 0xEC; - kp_g_core_fp->fp_register_write(addr, DATA_LEN_4, data, 0); + ret = kp_g_core_fp->fp_register_write(addr, DATA_LEN_4, data, 0); usleep_range(1000, 1100); - kp_g_core_fp->fp_register_read(addr, DATA_LEN_4, data, 0); - I("%s: data[1]=%d, data[0]=%d, retry_cnt=%d\n", __func__, data[1], data[0], retry_cnt); + ret = kp_g_core_fp->fp_register_read(addr, DATA_LEN_4, data, 0); + I("%s: data[1]=%d, data[0]=%d, reload_to_active_cnt=%d\n", __func__, data[1], data[0], retry_cnt); retry_cnt++; } while ((data[1] != 0x01 || data[0] != 0xEC) && retry_cnt < HIMAX_REG_RETRY_TIMES); + if (ret != 0) + atomic_set(&(*kp_private_ts)->resume_update_fail, 1); } static void himax_hx83102d_resume_ic_action(void)