diff options
author | davidycchen <davidycchen@google.com> | 2022-03-09 15:30:23 +0800 |
---|---|---|
committer | davidycchen <davidycchen@google.com> | 2022-05-06 10:37:20 +0800 |
commit | dd8ac97f73c32cf96e2690a8b9efb911cccdee98 (patch) | |
tree | 36729654cff3295dd5dff582b6876faf5ccbd12f | |
parent | 55784dc0c6a43f8b0437848d80c60c77a31c45a2 (diff) | |
download | synaptics_touch-dd8ac97f73c32cf96e2690a8b9efb911cccdee98.tar.gz |
synaptics: dynamic change the touch report rate
Dynamic change the touch report rate depending on the display refresh
rate.
Bug: 222217451
Test: Switch the display refresh rate while finger is sliding without
issue.
Signed-off-by: davidycchen <davidycchen@google.com>
Change-Id: Ia258208d644ef2b0c94b3a2296e5d8253cae1774
-rw-r--r-- | syna_tcm2.c | 74 | ||||
-rw-r--r-- | syna_tcm2.h | 6 | ||||
-rw-r--r-- | syna_tcm2_platform.h | 1 | ||||
-rw-r--r-- | syna_tcm2_platform_spi.c | 2 | ||||
-rw-r--r-- | tcm/synaptics_touchcom_core_dev.h | 5 |
5 files changed, 84 insertions, 4 deletions
diff --git a/syna_tcm2.c b/syna_tcm2.c index b0cef72..08be4a2 100644 --- a/syna_tcm2.c +++ b/syna_tcm2.c @@ -301,7 +301,15 @@ static void syna_dev_restore_feature_setting(struct syna_tcm *tcm) DC_COMPRESSION_THRESHOLD, tcm->hw_if->compression_threhsold, RESP_IN_POLLING); + + if (tcm->hw_if->dynamic_report_rate) { + syna_tcm_set_dynamic_config(tcm->tcm_dev, + DC_REPORT_RATE_SWITCH, + tcm->touch_report_rate_config, + RESP_IN_POLLING); + } } + /* Update a state machine used to toggle control of the touch IC's motion * filter. */ @@ -380,6 +388,28 @@ static void syna_motion_filter_work(struct work_struct *work) RESP_IN_ATTN); } +static void syna_set_report_rate_work(struct work_struct *work) +{ + struct syna_tcm *tcm; + struct delayed_work *delayed_work; + delayed_work = container_of(work, struct delayed_work, work); + tcm = container_of(delayed_work, struct syna_tcm, set_report_rate_work); + + if (tcm->touch_count != 0) { + queue_delayed_work(tcm->event_wq, &tcm->set_report_rate_work, + msecs_to_jiffies(10)); + return; + } + + tcm->touch_report_rate_config = tcm->next_report_rate_config; + syna_tcm_set_dynamic_config(tcm->tcm_dev, + DC_REPORT_RATE_SWITCH, + tcm->touch_report_rate_config, + RESP_IN_ATTN); + LOGI("Set touch report rate as %dHz", + (tcm->touch_report_rate_config == CONFIG_HIGH_REPORT_RATE) ? 240 : 120); +} + #ifdef ENABLE_CUSTOM_TOUCH_ENTITY /** * syna_dev_parse_custom_touch_data_cb() @@ -742,6 +772,7 @@ static void syna_dev_report_input_events(struct syna_tcm *tcm) input_set_timestamp(input_dev, tcm->coords_timestamp); input_sync(input_dev); + tcm->touch_count = touch_count; syna_update_motion_filter(tcm, touch_count); @@ -1043,6 +1074,8 @@ static void syna_offload_report(void *handle, input_report_key(tcm->input_dev, BTN_TOOL_FINGER, touch_down); input_sync(tcm->input_dev); + tcm->touch_count = touch_count; + syna_update_motion_filter(tcm, touch_count); syna_pal_mutex_unlock(&tcm->tp_event_mutex); @@ -2037,6 +2070,9 @@ static int syna_dev_suspend(struct device *dev) LOGI("Prepare to suspend device\n"); + if (tcm->hw_if->dynamic_report_rate) + cancel_delayed_work_sync(&tcm->set_report_rate_work); + reinit_completion(&tcm->bus_resumed); /* clear all input events */ @@ -2319,7 +2355,7 @@ static void syna_panel_bridge_enable(struct drm_bridge *bridge) struct syna_tcm *tcm = container_of(bridge, struct syna_tcm, panel_bridge); - pr_debug("%s\n", __func__); + LOGD("%s\n", __func__); if (!tcm ->is_panel_lp_mode) syna_set_bus_ref(tcm, SYNA_BUS_REF_SCREEN_ON, true); } @@ -2336,7 +2372,7 @@ static void syna_panel_bridge_disable(struct drm_bridge *bridge) return; } - pr_debug("%s\n", __func__); + LOGD("%s\n", __func__); syna_set_bus_ref(tcm, SYNA_BUS_REF_SCREEN_ON, false); } @@ -2347,10 +2383,10 @@ static void syna_panel_bridge_mode_set(struct drm_bridge *bridge, struct syna_tcm *tcm = container_of(bridge, struct syna_tcm, panel_bridge); - pr_debug("%s\n", __func__); + LOGD("%s\n", __func__); if (!tcm->connector || !tcm->connector->state) { - pr_info("%s: Get bridge connector.\n", __func__); + LOGI("%s: Get bridge connector.\n", __func__); tcm->connector = syna_get_bridge_connector(bridge); } @@ -2359,6 +2395,31 @@ static void syna_panel_bridge_mode_set(struct drm_bridge *bridge, syna_set_bus_ref(tcm, SYNA_BUS_REF_SCREEN_ON, false); else syna_set_bus_ref(tcm, SYNA_BUS_REF_SCREEN_ON, true); + + if (mode && tcm->hw_if->dynamic_report_rate) { + int vrefresh = drm_mode_vrefresh(mode); + LOGD("Display refresh rate %dHz", vrefresh); + if (vrefresh == 120 || vrefresh == 90) + tcm->next_report_rate_config = CONFIG_HIGH_REPORT_RATE; + else + tcm->next_report_rate_config = CONFIG_LOW_REPORT_RATE; + + if (tcm->last_vrefresh_rate != vrefresh) + cancel_delayed_work_sync(&tcm->set_report_rate_work); + + if (tcm->next_report_rate_config != tcm->touch_report_rate_config && + tcm->pwr_state == PWR_ON && tcm->bus_refmask != 0) { + /* + * Queue the work immediately for increasing touch report rate + * to 240Hz and queue 2 seconds delay work for decreasing + * touch report rate. + */ + queue_delayed_work(tcm->event_wq, &tcm->set_report_rate_work, + (tcm->next_report_rate_config == CONFIG_HIGH_REPORT_RATE) ? + 0 : msecs_to_jiffies(2 * MSEC_PER_SEC)); + } + tcm->last_vrefresh_rate = vrefresh; + } } static const struct drm_bridge_funcs panel_bridge_funcs = { @@ -2783,6 +2844,9 @@ static int syna_dev_probe(struct platform_device *pdev) INIT_WORK(&tcm->motion_filter_work, syna_motion_filter_work); + tcm->touch_report_rate_config = CONFIG_HIGH_REPORT_RATE; + INIT_DELAYED_WORK(&tcm->set_report_rate_work, syna_set_report_rate_work); + #ifdef HAS_SYSFS_INTERFACE /* create the device file and register to char device classes */ retval = syna_cdev_create_sysfs(tcm, pdev); @@ -2904,6 +2968,8 @@ static int syna_dev_remove(struct platform_device *pdev) cancel_work_sync(&tcm->suspend_work); cancel_work_sync(&tcm->resume_work); + cancel_work_sync(&tcm->motion_filter_work); + cancel_delayed_work_sync(&tcm->set_report_rate_work); #if IS_ENABLED(CONFIG_TOUCHSCREEN_TBN) if (tcm->tbn_register_mask) diff --git a/syna_tcm2.h b/syna_tcm2.h index b37a1a9..89668fc 100644 --- a/syna_tcm2.h +++ b/syna_tcm2.h @@ -480,6 +480,12 @@ struct syna_tcm { pid_t proc_pid; struct task_struct *proc_task; + int touch_count; + bool touch_report_rate_config; + bool next_report_rate_config; + int last_vrefresh_rate; + struct delayed_work set_report_rate_work; + /* flags */ int pwr_state; bool slept_in_early_suspend; diff --git a/syna_tcm2_platform.h b/syna_tcm2_platform.h index e38e5a2..8242d95 100644 --- a/syna_tcm2_platform.h +++ b/syna_tcm2_platform.h @@ -153,6 +153,7 @@ struct syna_hw_interface { #endif int udfps_x; int udfps_y; + bool dynamic_report_rate; /* Operation to do power on/off, if supported * diff --git a/syna_tcm2_platform_spi.c b/syna_tcm2_platform_spi.c index b8ac888..d0a4098 100644 --- a/syna_tcm2_platform_spi.c +++ b/syna_tcm2_platform_spi.c @@ -696,6 +696,8 @@ static int syna_spi_parse_dt(struct syna_hw_interface *hw_if, hw_if->compression_threhsold = 15; } + hw_if->dynamic_report_rate = of_property_read_bool(np,"synaptics,dynamic-report-rate"); + #if IS_ENABLED(CONFIG_TOUCHSCREEN_OFFLOAD) hw_if->offload_id = 0; retval = of_property_read_u8_array(np, "synaptics,touch_offload_id", diff --git a/tcm/synaptics_touchcom_core_dev.h b/tcm/synaptics_touchcom_core_dev.h index 9e136ba..0871dbc 100644 --- a/tcm/synaptics_touchcom_core_dev.h +++ b/tcm/synaptics_touchcom_core_dev.h @@ -121,6 +121,9 @@ #define RESP_IN_ATTN (1) #define RESP_IN_POLLING (CMD_RESPONSE_POLLING_DELAY_MS) +#define CONFIG_HIGH_REPORT_RATE 0 +#define CONFIG_LOW_REPORT_RATE 1 + /** * @section: Macro to show string in log */ @@ -221,6 +224,8 @@ enum dynamic_tcm_config_id { DC_INHIBIT_ACTIVE_GESTURE = 0x0f, DC_DISABLE_PROXIMITY = 0x10, DC_HIGH_SENSITIVIRY_MODE = 0xCB, + /* Set 0 for high report rate(240Hz), 1 for low report rate(120Hz). */ + DC_REPORT_RATE_SWITCH = 0xE6, DC_FORCE_DOZE_MODE = 0xF0, DC_COMPRESSION_THRESHOLD = 0xF1, DC_TOUCH_SCAN_MODE = 0xF2, |