summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSuper Liu <supercjliu@google.com>2023-05-18 00:33:40 +0000
committerSuper Liu <supercjliu@google.com>2023-05-19 00:34:48 +0000
commit811afaf0c3643b404bb3dad6b0a304abf0f90bb5 (patch)
treea967f08770109321d250c9f6512a26b85327609a
parentad942489f62ab7224970d0813684fcc79de449c2 (diff)
downloadfelix-811afaf0c3643b404bb3dad6b0a304abf0f90bb5.tar.gz
ftm5: Powercyle IC to recover unexpected system reset fail
Bug: 281546039 Test: stress verification to check wired-out signals. Change-Id: Ib0786ad8c37e8f251b02d443575db091d6c5006f Signed-off-by: Super Liu <supercjliu@google.com>
-rw-r--r--touch/ftm5/fts.c18
-rw-r--r--touch/ftm5/fts.h2
-rw-r--r--touch/ftm5/fts_lib/ftsCore.c18
-rw-r--r--touch/ftm5/fts_lib/ftsCore.h2
-rw-r--r--touch/ftm5/fts_lib/ftsError.c2
-rw-r--r--touch/ftm5/fts_lib/ftsTime.h2
-rw-r--r--touch/ftm5/fts_proc.c2
7 files changed, 31 insertions, 15 deletions
diff --git a/touch/ftm5/fts.c b/touch/ftm5/fts.c
index 738afa4..38801ab 100644
--- a/touch/ftm5/fts.c
+++ b/touch/ftm5/fts.c
@@ -3163,7 +3163,7 @@ static bool fts_error_event_handler(struct fts_ts_info *info, unsigned
/* before reset clear all slot */
release_all_touches(info);
#endif
- fts_chip_powercycle(info);
+ fts_chip_powercycle(info, false);
error = fts_system_reset(info);
error |= fts_mode_handler(info, 0);
@@ -4265,7 +4265,7 @@ static int fts_fw_update(struct fts_ts_info *info)
dev_err(info->dev, "%s: firmware update failed; retrying. ERROR %08X\n",
__func__, ret);
/* Power cycle the touch IC */
- fts_chip_powercycle(info);
+ fts_chip_powercycle(info, false);
ret = flashProcedure(info, info->board->fw_name,
info->reflash_fw, keep_cx);
if ((ret & 0xFF000000) == ERROR_FLASH_PROCEDURE) {
@@ -4457,7 +4457,7 @@ static int fts_chip_initialization(struct fts_ts_info *info, int init_type)
initretrycnt++;
dev_err(info->dev, "initialization cycle count = %04d - ERROR %08X\n",
initretrycnt, ret2);
- fts_chip_powercycle(info);
+ fts_chip_powercycle(info, false);
}
if (ret2 < OK) /* initialization error */
@@ -4582,9 +4582,10 @@ static int fts_init(struct fts_ts_info *info)
* Execute a power cycle in the IC, toggling the power lines (AVDD and DVDD)
* @param info pointer to fts_ts_info struct which contain information of the
* regulators
+ * @param wait_drain to drain the AVDD/DVDD before reenable
* @return 0 if success or another value if fail
*/
-int fts_chip_powercycle(struct fts_ts_info *info)
+int fts_chip_powercycle(struct fts_ts_info *info, bool wait_drain)
{
int error = 0;
@@ -4608,10 +4609,15 @@ int fts_chip_powercycle(struct fts_ts_info *info)
__func__);
}
- if (info->board->reset_gpio != GPIO_NOT_DEFINED)
+ if (info->board->reset_gpio != GPIO_NOT_DEFINED) {
+ if (wait_drain)
+ usleep_range(15 * USEC_PER_MSEC, 15 * USEC_PER_MSEC + 100);
gpio_set_value(info->board->reset_gpio, 0);
- else
+ if (wait_drain)
+ usleep_range(5 * USEC_PER_MSEC, 5 * USEC_PER_MSEC + 100);
+ } else {
mdelay(300);
+ }
/* in FTI power up first the digital and then the analog */
if (info->vdd_reg) {
diff --git a/touch/ftm5/fts.h b/touch/ftm5/fts.h
index 93b4037..825eac6 100644
--- a/touch/ftm5/fts.h
+++ b/touch/ftm5/fts.h
@@ -851,7 +851,7 @@ struct fts_ts_info {
int dsi_panel_read_vendor_extinfo(struct drm_panel *panel, char *buffer,
size_t len);
-int fts_chip_powercycle(struct fts_ts_info *info);
+int fts_chip_powercycle(struct fts_ts_info *info, bool wait_drain);
extern int input_register_notifier_client(struct notifier_block *nb);
extern int input_unregister_notifier_client(struct notifier_block *nb);
diff --git a/touch/ftm5/fts_lib/ftsCore.c b/touch/ftm5/fts_lib/ftsCore.c
index 4c52fe2..6cc9b50 100644
--- a/touch/ftm5/fts_lib/ftsCore.c
+++ b/touch/ftm5/fts_lib/ftsCore.c
@@ -91,7 +91,7 @@ int fts_system_reset(struct fts_ts_info *info)
data));
else {
gpio_set_value(info->board->reset_gpio, 0);
- msleep(10);
+ usleep_range(10 * USEC_PER_MSEC, 10 * USEC_PER_MSEC + 100);
gpio_set_value(info->board->reset_gpio, 1);
res = OK;
}
@@ -99,16 +99,24 @@ int fts_system_reset(struct fts_ts_info *info)
dev_err(info->dev, "fts_system_reset: ERROR %08X\n", ERROR_BUS_W);
else {
res = pollForEvent(info, &event_to_search, 1, readData,
- GENERAL_TIMEOUT);
+ TIMEOUT_SYSTEM_RESET);
if (res < OK)
dev_err(info->dev, "fts_system_reset: ERROR %08X\n", res);
}
}
if (res < OK) {
- dev_err(info->dev, "fts_system_reset...failed after 3 attempts: ERROR %08X\n",
- (res | ERROR_SYSTEM_RESET_FAIL));
- return res | ERROR_SYSTEM_RESET_FAIL;
+ dev_err(info->dev, "%s: failed after %d attempts: ERROR %08X\n",
+ __func__, i, (res | ERROR_SYSTEM_RESET_FAIL));
+ /* Do powercycle to recover unexpected system reset fail. */
+ fts_chip_powercycle(info, true);
+ res = pollForEvent(info, &event_to_search, 1, readData, TIMEOUT_SYSTEM_RESET);
+ if (res < OK) {
+ dev_err(info->dev, "%s: no ready ack after powercycle!\n", __func__);
+ return res | ERROR_SYSTEM_RESET_FAIL;
+ }
+
+ return OK;
} else {
#ifdef FTS_GPIO6_UNUSED
u8ToU64_be(&cmd[1], &addr, ADDR_SIZE_HW_REG);
diff --git a/touch/ftm5/fts_lib/ftsCore.h b/touch/ftm5/fts_lib/ftsCore.h
index 4c87907..8edc6c8 100644
--- a/touch/ftm5/fts_lib/ftsCore.h
+++ b/touch/ftm5/fts_lib/ftsCore.h
@@ -63,7 +63,7 @@ typedef enum {
#define RETRY_MAX_REQU_DATA 2 /* /< Max number of attempts
* performed
* when requesting data */
-#define RETRY_SYSTEM_RESET 3 /* /< Max number of attempts
+#define RETRY_SYSTEM_RESET 2 /* /< Max number of attempts
* performed
* to reset the IC */
diff --git a/touch/ftm5/fts_lib/ftsError.c b/touch/ftm5/fts_lib/ftsError.c
index fcffbce..2e2b307 100644
--- a/touch/ftm5/fts_lib/ftsError.c
+++ b/touch/ftm5/fts_lib/ftsError.c
@@ -143,7 +143,7 @@ int errorHandler(struct fts_ts_info *info, u8 *event, int size)
switch (event[1]) { /* TODO: write an error log for
* undefined command subtype 0xBA */
case EVT_TYPE_ERROR_ESD: /* esd */
- res = fts_chip_powercycle(info);
+ res = fts_chip_powercycle(info, false);
if (res < OK)
dev_err(info->dev, "errorHandler: Error performing powercycle ERROR %08X\n",
res);
diff --git a/touch/ftm5/fts_lib/ftsTime.h b/touch/ftm5/fts_lib/ftsTime.h
index f2b99a8..6b9095b 100644
--- a/touch/ftm5/fts_lib/ftsTime.h
+++ b/touch/ftm5/fts_lib/ftsTime.h
@@ -37,6 +37,8 @@
#define RELEASE_INFO_TIMEOUT (2 * TIMEOUT_RESOLUTION)
/* /< timeout to request release info in ms */
+#define TIMEOUT_SYSTEM_RESET (2 * TIMEOUT_RESOLUTION)
+/* /< timeout to system reset in ms */
#define TIMEOUT_CMD_CUSTOM_W (1 * TIMEOUT_RESOLUTION)
/* /< timeout to perform custom write cmd in ms */
#define TIMEOUT_CMD_SCAN_MODE (1 * TIMEOUT_RESOLUTION)
diff --git a/touch/ftm5/fts_proc.c b/touch/ftm5/fts_proc.c
index 3492127..ffc7a86 100644
--- a/touch/ftm5/fts_proc.c
+++ b/touch/ftm5/fts_proc.c
@@ -2046,7 +2046,7 @@ static ssize_t fts_driver_test_write(struct file *file, const char __user *buf,
break;
case CMD_POWERCYCLE:
- res = fts_chip_powercycle(info);
+ res = fts_chip_powercycle(info, false);
break;
case CMD_GETLIMITSFILE: