diff options
author | davidycchen <davidycchen@google.com> | 2022-08-12 09:20:26 +0800 |
---|---|---|
committer | davidycchen <davidycchen@google.com> | 2022-08-24 17:11:38 +0800 |
commit | 6d9f3ac45834800d3a0a19aa022b80aefa83fee2 (patch) | |
tree | caf71539c4b784e4b2b9528e8eecc496c9e964ad | |
parent | 2fe4deefbfab75db7d802ee60a53300a6e14ffb6 (diff) | |
download | synaptics_touch-6d9f3ac45834800d3a0a19aa022b80aefa83fee2.tar.gz |
synaptics: dump touch check information when the touch suspends
Example:
syna_hc_dump: dump-int: #15217(2.63): S#67(+) C#7488(0x0).
syna_hc_dump: dump-int: #15218(2.60): S#67 C#7489(0x0)(+).
syna_hc_dump: dump-int: #15219(2.60): S#67 C#7489(0x0).
syna_hc_dump: dump-int: #15220(2.59): S#68(+) C#7489(0x0).
Doc: go/no_touch_debug_1p
bug: 242128411
Test: adb bugreport
Test: Turn off display.
Signed-off-by: davidycchen <davidycchen@google.com>
Change-Id: Icc6b6f3fcc7373693b29e1ea5ccdeb577ba896c9
-rw-r--r-- | syna_tcm2.c | 82 | ||||
-rw-r--r-- | syna_tcm2.h | 23 | ||||
-rw-r--r-- | syna_tcm2_runtime.h | 1 | ||||
-rw-r--r-- | syna_tcm2_sysfs.c | 6 |
4 files changed, 109 insertions, 3 deletions
diff --git a/syna_tcm2.c b/syna_tcm2.c index ec61618..e89faa6 100644 --- a/syna_tcm2.c +++ b/syna_tcm2.c @@ -53,6 +53,10 @@ #include <samsung/panel/panel-samsung-drv.h> #endif +/* Init the kfifo for health check. */ +#define SYNA_HC_KFIFO_LEN 4 /* Must be power of 2. */ +DEFINE_KFIFO(hc_fifo, struct syna_health_check_fifo, SYNA_HC_KFIFO_LEN); + /** * @section: USE_CUSTOM_TOUCH_REPORT_CONFIG * Open if willing to set up the format of touch report. @@ -107,6 +111,63 @@ static unsigned char custom_touch_format[] = { static void reserve_then_queue_frame(struct syna_tcm *tcm, bool has_heatmap); #endif +#ifdef SYNA_HC_KFIFO_LEN +inline void syna_hc_update_and_push(struct syna_tcm *tcm, struct syna_health_check_fifo *hc) +{ + hc->int_ktime = tcm->isr_timestamp; + hc->int_idx = tcm->syna_hc.int_cnt; + hc->coord_idx = tcm->syna_hc.coord_event_cnt; + hc->status_idx = tcm->syna_hc.status_event_cnt; + hc->active_bit = tcm->syna_hc.touch_idx_state; + + /* + * Use kfifo as circular buffer by skipping one element + * when fifo is full. + */ + if (kfifo_is_full(&hc_fifo)) + kfifo_skip(&hc_fifo); + kfifo_in(&hc_fifo, hc, 1); +} + +inline void syna_hc_dump(struct syna_tcm *tcm) +{ + int i; + u64 count; + s64 delta; + s64 sec_delta; + u32 ms_delta; + ktime_t current_time = ktime_get(); + struct syna_health_check_fifo last_hc_fifo[SYNA_HC_KFIFO_LEN] = { 0 }; + + count = min(tcm->syna_hc.int_cnt, (u64) ARRAY_SIZE(last_hc_fifo)); + if (kfifo_out_peek(&hc_fifo, last_hc_fifo, count) != count) { + LOGE("Fail to peak health check data.\n"); + return; + } + + for (i = 0 ; i < count ; i++) { + sec_delta = 0; + ms_delta = 0; + delta = ktime_ms_delta(current_time, last_hc_fifo[i].int_ktime); + if (delta > 0) + sec_delta = div_u64_rem(delta, MSEC_PER_SEC, &ms_delta); + + LOGI("dump-int: #%llu(%llu.%u): S#%llu%s C#%llu(0x%lx)%s.\n", + last_hc_fifo[i].int_idx, + sec_delta, ms_delta, + last_hc_fifo[i].status_idx, + (last_hc_fifo[i].status_updated) ? "(+)" : " ", + last_hc_fifo[i].coord_idx, + last_hc_fifo[i].active_bit, + (last_hc_fifo[i].coord_updated) ? "(+)" : "" + ); + } +} +#else +#define syna_hc_update_and_push(tcm, hc) do {} while (0) +#define syna_hc_dump(tcm) do {} while (0) +#endif /* #ifdef SEC_TS_HC_KFIFO_LEN */ + /** * syna_dev_enable_lowpwr_gesture() * @@ -796,6 +857,7 @@ static void syna_dev_report_input_events(struct syna_tcm *tcm) #if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) } #endif + __clear_bit(idx, &tcm->syna_hc.touch_idx_state); break; case FINGER: case GLOVED_OBJECT: @@ -883,6 +945,7 @@ static void syna_dev_report_input_events(struct syna_tcm *tcm) } #endif LOGD("Finger %d: x = %d, y = %d, z = %d\n", idx, x, y, z); + __set_bit(idx, &tcm->syna_hc.touch_idx_state); touch_count++; break; default: @@ -1460,6 +1523,7 @@ static irqreturn_t syna_dev_isr(int irq, void *handle) struct syna_tcm *tcm = handle; tcm->isr_timestamp = ktime_get(); + tcm->syna_hc.int_cnt++; return IRQ_WAKE_THREAD; } @@ -1486,6 +1550,7 @@ static irqreturn_t syna_dev_interrupt_thread(int irq, void *data) struct custom_fw_status *status; struct syna_hw_attn_data *attn = &tcm->hw_if->bdata_attn; struct tcm_dev *tcm_dev = tcm->tcm_dev; + memset(&tcm->syna_hc.hc_fifo, 0, sizeof(tcm->syna_hc.hc_fifo)); ATRACE_BEGIN(__func__); @@ -1550,6 +1615,8 @@ static irqreturn_t syna_dev_interrupt_thread(int irq, void *data) goto exit; } tcm->coords_timestamp = tcm->isr_timestamp; + tcm->syna_hc.coord_event_cnt++; + tcm->syna_hc.hc_fifo.coord_updated = true; /* forward the touch event to system */ ATRACE_BEGIN("report_input_events"); @@ -1602,11 +1669,17 @@ static irqreturn_t syna_dev_interrupt_thread(int irq, void *data) LOGI("Status: moisture:%d noise:%d freq-change:%d, grip:%d, palm:%d\n", status->b0_moisture, status->b1_noise_state, status->b2_freq_hopping, status->b3_grip, status->b4_palm); + + tcm->syna_hc.status_event_cnt++; + tcm->syna_hc.hc_fifo.status_updated = true; break; default: break; } + /* Update the health check info. */ + syna_hc_update_and_push(tcm, &tcm->syna_hc.hc_fifo); + exit: syna_set_bus_ref(tcm, SYNA_BUS_REF_IRQ, false); cpu_latency_qos_update_request(&tcm->pm_qos_req, PM_QOS_DEFAULT_VALUE); @@ -2275,7 +2348,8 @@ static int syna_dev_suspend(struct device *dev) tbn_release_bus(tcm->tbn_register_mask); #endif - LOGI("Device suspended (pwr_state:%d)\n", tcm->pwr_state); + LOGI("Device suspended (pwr_state:%d), int_cnt:%llu\n", tcm->pwr_state, + tcm->syna_hc.int_cnt); return 0; } @@ -2408,6 +2482,7 @@ static void syna_suspend_work(struct work_struct *work) struct syna_tcm *tcm = container_of(work, struct syna_tcm, suspend_work); syna_dev_suspend(&tcm->pdev->dev); + syna_hc_dump(tcm); } static void syna_resume_work(struct work_struct *work) @@ -2935,6 +3010,11 @@ static int syna_dev_probe(struct platform_device *pdev) init_completion(&tcm->raw_data_completion); complete_all(&tcm->raw_data_completion); + tcm->syna_hc.int_cnt = 0; + tcm->syna_hc.coord_event_cnt = 0; + tcm->syna_hc.status_event_cnt = 0; + tcm->syna_hc.touch_idx_state = 0; + #if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) tcm->offload.caps.touch_offload_major_version = TOUCH_OFFLOAD_INTERFACE_MAJOR_VERSION; tcm->offload.caps.touch_offload_minor_version = TOUCH_OFFLOAD_INTERFACE_MINOR_VERSION; diff --git a/syna_tcm2.h b/syna_tcm2.h index 51eb378..1f680f2 100644 --- a/syna_tcm2.h +++ b/syna_tcm2.h @@ -396,6 +396,26 @@ enum custom_data { }; #endif +struct syna_health_check_fifo { + ktime_t int_ktime; + u64 int_idx; + u64 coord_idx; + u64 status_idx; + /* Slot active bit from FW. */ + unsigned long active_bit; + /* Check whether have coord, status or unknown event. */ + bool coord_updated; + bool status_updated; +}; + +struct syna_health_check { + struct syna_health_check_fifo hc_fifo; + u64 int_cnt; + u64 coord_event_cnt; + u64 status_event_cnt; + unsigned long touch_idx_state; +}; + /** * @brief: context of the synaptics linux-based driver * @@ -464,6 +484,8 @@ struct syna_tcm { * CLOCK_MONOTONIC */ ktime_t coords_timestamp; + struct syna_health_check syna_hc; + #if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) struct touch_offload_context offload; u16 *heatmap_buff; @@ -635,6 +657,7 @@ void syna_cdev_update_report_queue(struct syna_tcm *tcm, #endif int syna_set_bus_ref(struct syna_tcm *tcm, u32 ref, bool enable); +void syna_hc_dump(struct syna_tcm *tcm); #endif /* end of _SYNAPTICS_TCM2_DRIVER_H_ */ diff --git a/syna_tcm2_runtime.h b/syna_tcm2_runtime.h index cc21e9c..7bb5b41 100644 --- a/syna_tcm2_runtime.h +++ b/syna_tcm2_runtime.h @@ -69,6 +69,7 @@ #endif #include <linux/fs.h> #include <linux/moduleparam.h> +#include <linux/kfifo.h> /** * @brief: DEV_MANAGED_API diff --git a/syna_tcm2_sysfs.c b/syna_tcm2_sysfs.c index 9b92c62..cc5572d 100644 --- a/syna_tcm2_sysfs.c +++ b/syna_tcm2_sysfs.c @@ -706,10 +706,12 @@ static ssize_t syna_sysfs_force_active_store(struct kobject *kobj, LOGI("Set bus reference bit %#x %s.", ref, active ? "enable" : "disable"); - if (active) + if (active) { pm_stay_awake(&tcm->pdev->dev); - else + syna_hc_dump(tcm); + } else { pm_relax(&tcm->pdev->dev); + } retval = syna_set_bus_ref(tcm, ref, active); if (retval < 0) { |