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 <wangyq13@lenovo.com>
Reviewed-on: https://gerrit.mot.com/1549942
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Yiwen Liu <liuyw2@motorola.com>
Reviewed-by: Jun Weng <wengjun1@motorola.com>
Reviewed-by: Huosheng Liao <liaohs@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
wangyq13 2020-05-08 00:20:33 +08:00 • committed by Yeqing Wang
commit 69228e6b7b
5 changed files with 73 additions and 5 deletions

View file

@ -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

View file

@ -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;

View file

@ -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__);
}

View file

@ -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;
}

View file

@ -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)