From 3f23e29dd793e0650bd6b524313899c391fb883c Mon Sep 17 00:00:00 2001 From: Wenge Zhu Date: Sun, 12 Jun 2022 18:36:14 +0800 Subject: [PATCH] Support double tap to wake up the screen TP: Support double tap to wake up the screen. Change-Id: Ie99fda37fd7dcba66f3c4d91e9fd6b8179d61018 Signed-off-by: Wenge Zhu Reviewed-on: https://gerrit.mot.com/2298079 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Wei Deng Reviewed-by: Jun Weng Reviewed-by: Jichao Zou Submit-Approved: Jira Key --- .../goodix_berlin_mmi/goodix_ts_core.h | 5 ++ .../goodix_berlin_mmi/goodix_ts_gesture.c | 9 ++- .../goodix_berlin_mmi/goodix_ts_gesture_fod.c | 22 ++++--- .../goodix_berlin_mmi/goodix_ts_mmi.c | 32 ++++++++++ .../goodix_berlin_mmi/goodix_ts_mmi.h | 1 + .../touchscreen/touchscreen_mmi/Android.mk | 4 ++ .../input/touchscreen/touchscreen_mmi/Kbuild | 3 + .../touchscreen_mmi/touchscreen_mmi_class.c | 64 +++++++++++++++++++ .../touchscreen_mmi/touchscreen_mmi_gesture.c | 7 ++ .../touchscreen_mmi/touchscreen_mmi_notif.c | 22 +++++++ .../touchscreen_mmi/touchscreen_mmi_panel.c | 7 ++ include/linux/touchscreen_mmi.h | 10 +++ 12 files changed, 175 insertions(+), 11 deletions(-) diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.h b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.h index bb84a8b299d2..ccba070d185e 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.h +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.h @@ -59,6 +59,11 @@ #define STYLUS_CLK_SRC_GPIO "stylus_clk_gpio" #define STYLUS_CLK_SRC_PMIC "stylus_clk_pmic" +#define GOODIX_GESTURE_DOUBLE_TAP 0xCC +#define GOODIX_GESTURE_SINGLE_TAP 0x4C +#define GOODIX_GESTURE_FOD_DOWN 0x46 +#define GOODIX_GESTURE_FOD_UP 0x55 + enum GOODIX_GESTURE_TYP { GESTURE_SINGLE_TAP = (1 << 0), GESTURE_DOUBLE_TAP = (1 << 1), diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_gesture.c b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_gesture.c index 26f168b0c737..af50591f1fd2 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_gesture.c +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_gesture.c @@ -250,8 +250,13 @@ static int gsx_gesture_ist(struct goodix_ts_core *cd, if (cd->imports && cd->imports->report_gesture) { struct gesture_event_data mmi_event; - ts_info("invoke imported report gesture function\n"); - mmi_event.evcode = 1; + ts_info("invoke imported report gesture function, gesture_type = %d\n", + gs_event.gesture_type); + if(gs_event.gesture_type == GOODIX_GESTURE_SINGLE_TAP) { + mmi_event.evcode = 1; + } else if(gs_event.gesture_type == GOODIX_GESTURE_DOUBLE_TAP) { + mmi_event.evcode =4; + } /* call class method */ ret = cd->imports->report_gesture(&mmi_event); diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_gesture_fod.c b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_gesture_fod.c index 523378e12cc2..aeace59f42c8 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_gesture_fod.c +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_gesture_fod.c @@ -30,12 +30,6 @@ #include "goodix_ts_core.h" #include "goodix_ts_mmi.h" - - -#define GOODIX_GESTURE_DOUBLE_TAP 0xCC -#define GOODIX_GESTURE_SINGLE_TAP 0x4C -#define GOODIX_GESTURE_FOD_DOWN 0x46 -#define GOODIX_GESTURE_FOD_UP 0x55 /* * struct gesture_module - gesture module data * @registered: module register state @@ -334,7 +328,7 @@ static int gsx_gesture_init(struct goodix_ts_core *cd, gsx->ts_core = cd; /*enable all gesture wakeup by default */ - gsx->ts_core->gesture_type = GESTURE_SINGLE_TAP |GESTURE_FOD_PRESS; + gsx->ts_core->gesture_type = GESTURE_SINGLE_TAP |GESTURE_FOD_PRESS | GESTURE_DOUBLE_TAP; cd->zerotap_data[0] = 0; //default on the fod event cd->fod_enable = true; @@ -403,7 +397,7 @@ static int gsx_gesture_ist(struct goodix_ts_core *cd, gs_event.event_type); goto re_send_ges_cmd; } - ts_debug("got gesture type 0x%x", gs_event.gesture_type); + ts_info("got gesture type 0x%x", gs_event.gesture_type); #if defined(CONFIG_INPUT_TOUCHSCREEN_MMI) mmi_event.evcode =0; if ( cd->imports && cd->imports->report_gesture) { @@ -412,6 +406,16 @@ static int gsx_gesture_ist(struct goodix_ts_core *cd, mmi_event.evcode =1; fod_down = 0; + /* call class method */ + ret = cd->imports->report_gesture(&mmi_event); + if (!ret) + PM_WAKEUP_EVENT(cd->gesture_wakelock, 3000); + goto gesture_ist_exit; + } else if(cd->gesture_type & GESTURE_DOUBLE_TAP && gs_event.gesture_type == GOODIX_GESTURE_DOUBLE_TAP) { + ts_info("get DOUBLE-TAP gesture"); + mmi_event.evcode =4; + fod_down = 0; + /* call class method */ ret = cd->imports->report_gesture(&mmi_event); if (!ret) @@ -427,7 +431,7 @@ static int gsx_gesture_ist(struct goodix_ts_core *cd, mmi_event.evdata.x= 0; mmi_event.evdata.y= 0; - ts_debug("Get FOD-DOWN gesture:%d interval:%d",fod_down,fod_down_interval); + ts_info("Get FOD-DOWN gesture:%d interval:%d",fod_down,fod_down_interval); if(fod_down_interval > 2000) fod_down = 0; if(fod_down_interval > 0 && fod_down_interval < 250 && fod_down) { diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.c b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.c index 2123c2d30fcb..a57feb5de40c 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.c +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.c @@ -901,6 +901,8 @@ static int goodix_ts_mmi_panel_state(struct device *dev, struct platform_device *pdev; struct goodix_ts_core *core_data; const struct goodix_ts_hw_ops *hw_ops; + int ret = 0; + static unsigned short gesture_cmd = 0xFFFF; GET_GOODIX_DATA(dev); hw_ops = core_data->hw_ops; @@ -919,6 +921,36 @@ static int goodix_ts_mmi_panel_state(struct device *dev, enable_irq_wake(core_data->irq); core_data->gesture_enabled = true; break; + case TS_MMI_PM_GESTURE_ZERO: + gesture_cmd &= ~(1 << 5); + ts_info("enable zero gesture mode cmd 0x%04x\n", gesture_cmd); + break; + case TS_MMI_PM_GESTURE_SINGLE: + gesture_cmd &= ~(1 << 4); + ts_info("enable single gesture mode cmd 0x%04x\n", gesture_cmd); + break; + case TS_MMI_PM_GESTURE_DOUBLE: + gesture_cmd &= ~(1 << 15); + ts_info("enable double gesture mode cmd 0x%04x\n", gesture_cmd); + break; + case TS_MMI_PM_GESTURE_SWITCH: + hw_ops->irq_enable(core_data, false); + ret = goodix_ts_send_cmd(core_data, ENTER_GESTURE_MODE_CMD, 6, 0xFF, 0xFF); + if (ret < 0) { + ts_err("Failed to send enter gesture mode\n"); + } + ret = goodix_ts_send_cmd(core_data, ENTER_GESTURE_MODE_CMD, 6, gesture_cmd >> 8, + gesture_cmd & 0xFF); + if (ret < 0) { + ts_err("Failed to send enable gesture mode\n"); + } + ts_info("Send enable gesture mode 0x%04x\n", gesture_cmd); + gesture_cmd = 0xFFFF; + msleep(16); + hw_ops->irq_enable(core_data, true); + enable_irq_wake(core_data->irq); + core_data->gesture_enabled = true; + break; case TS_MMI_PM_DEEPSLEEP: /* enter sleep mode or power off */ /* if (hw_ops->suspend) diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.h b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.h index 8069ca08ad3f..40cbd9506855 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.h +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.h @@ -49,4 +49,5 @@ static int inline goodix_ts_mmi_dev_unregister(struct platform_device *ts_device #define EXIT_HIGH_REPORT_RATE_CMD 0xC100 #define SAMPLE_SWITCH_CMD 0xC2 +#define ENTER_GESTURE_MODE_CMD 0xA6 #endif diff --git a/drivers/input/touchscreen/touchscreen_mmi/Android.mk b/drivers/input/touchscreen/touchscreen_mmi/Android.mk index c01eb47d9015..fe10a4d5ae97 100644 --- a/drivers/input/touchscreen/touchscreen_mmi/Android.mk +++ b/drivers/input/touchscreen/touchscreen_mmi/Android.mk @@ -33,6 +33,10 @@ ifneq (,$(findstring gki, $(KERNEL_DEFCONFIG))) KERNEL_CFLAGS += CONFIG_TS_KERNEL_USE_GKI=y endif +ifeq ($(BOARD_USES_DOUBLE_TAP_CTRL),true) + KBUILD_OPTIONS += CONFIG_BOARD_USES_DOUBLE_TAP_CTRL=y +endif + include $(CLEAR_VARS) LOCAL_MODULE := touchscreen_mmi.ko LOCAL_MODULE_TAGS := optional diff --git a/drivers/input/touchscreen/touchscreen_mmi/Kbuild b/drivers/input/touchscreen/touchscreen_mmi/Kbuild index aeffe2821189..f937be291cf6 100644 --- a/drivers/input/touchscreen/touchscreen_mmi/Kbuild +++ b/drivers/input/touchscreen/touchscreen_mmi/Kbuild @@ -29,6 +29,9 @@ endif ifneq ($(filter m y, $(CONFIG_TS_KERNEL_USE_GKI)),) EXTRA_CFLAGS += -DCONFIG_TS_KERNEL_USE_GKI endif +ifneq ($(filter m y, $(CONFIG_BOARD_USES_DOUBLE_TAP_CTRL)),) + EXTRA_CFLAGS += -DCONFIG_BOARD_USES_DOUBLE_TAP_CTRL +endif obj-m := touchscreen_mmi.o touchscreen_mmi-objs := touchscreen_mmi_class.o touchscreen_mmi_panel.o touchscreen_mmi_notif.o touchscreen_mmi_gesture.o diff --git a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_class.c b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_class.c index b6390bb9ac33..12618452be52 100644 --- a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_class.c +++ b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_class.c @@ -327,6 +327,67 @@ static ssize_t pwr_store(struct device *dev, } static DEVICE_ATTR(pwr, (S_IWUSR | S_IWGRP), NULL, pwr_store); +#ifdef CONFIG_BOARD_USES_DOUBLE_TAP_CTRL +/* + * gesture value used to indicate which gesture mode type is enabled + */ +static ssize_t gesture_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ts_mmi_dev *touch_cdev = dev_get_drvdata(dev); + + return scnprintf(buf, PAGE_SIZE, "%02x\n", touch_cdev->pdata.supported_gesture_type); +} +static ssize_t gesture_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct ts_mmi_dev *touch_cdev = dev_get_drvdata(dev); + unsigned int value = 0; + int err = 0; + + mutex_lock(&touch_cdev->extif_mutex); + err = sscanf(buf, "%d", &value); + if (err < 0) { + dev_err(dev, "forcereflash: Failed to convert value\n"); + return -EINVAL; + } + switch (value) { + case 0x10: + dev_info(dev, "%s: zero tap disable\n", __func__); + touch_cdev->gesture_mode_type &= 0xFE; + break; + case 0x11: + dev_info(dev, "%s: zero tap enable\n", __func__); + touch_cdev->gesture_mode_type |= 0x01; + break; + case 0x20: + dev_info(dev, "%s: single tap disable\n", __func__); + touch_cdev->gesture_mode_type &= 0xFD; + break; + case 0x21: + dev_info(dev, "%s: single tap enable\n", __func__); + touch_cdev->gesture_mode_type |= 0x02; + break; + case 0x30: + dev_info(dev, "%s: double tap disable\n", __func__); + touch_cdev->gesture_mode_type &= 0xFB; + break; + case 0x31: + dev_info(dev, "%s: double tap enable\n", __func__); + touch_cdev->gesture_mode_type |= 0x04; + break; + default: + dev_info(dev, "%s: unsupport gesture mode type\n", __func__); + ; + } + mutex_unlock(&touch_cdev->extif_mutex); + dev_info(dev, "%s: gesture_mode_type = 0x%02x \n", __func__, touch_cdev->gesture_mode_type); + + return size; +} +static DEVICE_ATTR(gesture, (S_IWUSR | S_IWGRP | S_IRUGO), gesture_show, gesture_store); +#endif + static struct attribute *sysfs_class_attrs[] = { &dev_attr_path.attr, &dev_attr_vendor.attr, @@ -355,6 +416,9 @@ static struct attribute *sysfs_class_attrs[] = { &dev_attr_poison_timeout.attr, &dev_attr_poison_distance.attr, &dev_attr_poison_trigger_distance.attr, +#endif +#ifdef CONFIG_BOARD_USES_DOUBLE_TAP_CTRL + &dev_attr_gesture.attr, #endif NULL, }; diff --git a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_gesture.c b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_gesture.c index 7055aa99c97e..373404e66fd6 100644 --- a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_gesture.c +++ b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_gesture.c @@ -233,6 +233,10 @@ static int ts_mmi_gesture_handler(struct gesture_event_data *gev) key_code = KEY_F3; pr_info("%s: zero tap up\n", __func__); break; + case 4: + key_code = KEY_F4; + pr_info("%s: double tap\n", __func__); + break; default: need2report = false; pr_info("%s: unknown id=%x\n", __func__, gev->evcode); @@ -377,6 +381,7 @@ bool ts_mmi_is_sensor_enable(void) static int ts_mmi_sensor_set_enable(struct sensors_classdev *sensors_cdev, unsigned int enable) { +#ifndef CONFIG_BOARD_USES_DOUBLE_TAP_CTRL struct ts_mmi_sensor_platform_data *sensor_pdata = container_of( sensors_cdev, struct ts_mmi_sensor_platform_data, ps_cdev); struct ts_mmi_dev *touch_cdev = sensor_pdata->touch_cdev; @@ -389,6 +394,7 @@ static int ts_mmi_sensor_set_enable(struct sensors_classdev *sensors_cdev, } else { dev_err(DEV_TS, "%s: unknown enable symbol\n", __func__); } +#endif return 0; } @@ -491,6 +497,7 @@ int ts_mmi_gesture_init(struct ts_mmi_dev *touch_cdev) __set_bit(KEY_F1, sensor_input_dev->keybit); __set_bit(KEY_F2, sensor_input_dev->keybit); __set_bit(KEY_F3, sensor_input_dev->keybit); + __set_bit(KEY_F4, sensor_input_dev->keybit); __set_bit(EV_ABS, sensor_input_dev->evbit); __set_bit(EV_SYN, sensor_input_dev->evbit); /* TODO: fill in real screen resolution */ diff --git a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c index 6bd5732b8230..086c12eb1a93 100644 --- a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c +++ b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c @@ -60,11 +60,33 @@ static int ts_mmi_panel_off(struct ts_mmi_dev *touch_cdev) { TRY_TO_CALL(pre_suspend); if (touch_cdev->pdata.gestures_enabled) { +#ifdef CONFIG_BOARD_USES_DOUBLE_TAP_CTRL + if(touch_cdev->gesture_mode_type != 0) { + if(touch_cdev->gesture_mode_type & 0x01) { + dev_info(DEV_MMI, "%s: try to enter zero Gesture mode\n", __func__); + TRY_TO_CALL(panel_state, touch_cdev->pm_mode, TS_MMI_PM_GESTURE_ZERO); + } + if(touch_cdev->gesture_mode_type & 0x02) { + dev_info(DEV_MMI, "%s: try to enter single Gesture mode\n", __func__); + TRY_TO_CALL(panel_state, touch_cdev->pm_mode, TS_MMI_PM_GESTURE_SINGLE); + } + if(touch_cdev->gesture_mode_type & 0x04) { + dev_info(DEV_MMI, "%s: try to enter double Gesture mode\n", __func__); + TRY_TO_CALL(panel_state, touch_cdev->pm_mode, TS_MMI_PM_GESTURE_DOUBLE); + } + + dev_info(DEV_MMI, "%s: notify touch driver to switch gesture mode\n", __func__); + TRY_TO_CALL(panel_state, touch_cdev->pm_mode, TS_MMI_PM_GESTURE_SWITCH); + + touch_cdev->pm_mode = TS_MMI_PM_GESTURE; + } +#else if(ts_mmi_is_sensor_enable()) { dev_info(DEV_MMI, "%s: try to enter Gesture mode\n", __func__); TRY_TO_CALL(panel_state, touch_cdev->pm_mode, TS_MMI_PM_GESTURE); touch_cdev->pm_mode = TS_MMI_PM_GESTURE; } +#endif } if (IS_ACTIVE_MODE) { /* IC power is off. IRQ pin status is floated. So disable IRQ. */ diff --git a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_panel.c b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_panel.c index 55cb4be254bb..658336d8c89e 100644 --- a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_panel.c +++ b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_panel.c @@ -155,6 +155,13 @@ int ts_mmi_parse_dt(struct ts_mmi_dev *touch_cdev, ppdata->fod_y = coords[1]; dev_info(DEV_TS, "%s: get fod_coords property x:%d y:%d\n", __func__,ppdata->fod_x,ppdata->fod_y); } + +#ifdef CONFIG_BOARD_USES_DOUBLE_TAP_CTRL + if (!of_property_read_u32(of_node, "mmi,supported_gesture_type", &ppdata->supported_gesture_type)) + dev_info(DEV_TS, "%s: supported_gesture_type property %02x\n", + __func__, ppdata->supported_gesture_type); +#endif + chosen = of_find_node_by_name(NULL, "chosen"); if (chosen) { struct device_node *child; diff --git a/include/linux/touchscreen_mmi.h b/include/linux/touchscreen_mmi.h index 505c3fa1dc91..cebb9fe7275e 100644 --- a/include/linux/touchscreen_mmi.h +++ b/include/linux/touchscreen_mmi.h @@ -287,6 +287,10 @@ enum ts_mmi_pm_mode { TS_MMI_PM_DEEPSLEEP = 0, TS_MMI_PM_GESTURE, TS_MMI_PM_ACTIVE, + TS_MMI_PM_GESTURE_SINGLE, + TS_MMI_PM_GESTURE_DOUBLE, + TS_MMI_PM_GESTURE_ZERO, + TS_MMI_PM_GESTURE_SWITCH, }; enum ts_mmi_panel_event { @@ -422,6 +426,9 @@ struct ts_mmi_dev_pdata { int reset; const char *class_entry_name; const char *bound_display; +#ifdef CONFIG_BOARD_USES_DOUBLE_TAP_CTRL + int supported_gesture_type; +#endif }; /** @@ -446,6 +453,9 @@ struct ts_mmi_dev { struct device *class_dev; dev_t class_dev_no; int forcereflash; +#ifdef CONFIG_BOARD_USES_DOUBLE_TAP_CTRL + unsigned char gesture_mode_type; +#endif int panel_status; struct ts_mmi_dev_pdata pdata; #if defined(CONFIG_DRM_PANEL_NOTIFICATIONS) || defined (CONFIG_DRM_PANEL_EVENT_NOTIFICATIONS)