From 39087fae46bba164aacb41ccce043df8e4754d1c Mon Sep 17 00:00:00 2001 From: litong20 Date: Fri, 21 May 2021 13:47:35 +0800 Subject: [PATCH] Support novatek single tap in berlna TP: Support novatek single tap function in berlin NA. Change-Id: I8f1d8d82b919b20fcba4812a74f247399a097ddf Reviewed-on: https://gerrit.mot.com/1955575 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Jun Weng Reviewed-by: Jichao Zou Submit-Approved: Jira Key --- .../touchscreen/nova_0flash_mmi/nt36xxx.c | 118 +++++++++++------- .../touchscreen/nova_0flash_mmi/nt36xxx.h | 22 +++- .../nova_0flash_mmi/nt36xxx_mmi_class.c | 90 +++++++++++-- 3 files changed, 168 insertions(+), 62 deletions(-) diff --git a/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx.c b/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx.c index d1cabd88436b..0ca9606d4ea4 100644 --- a/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx.c +++ b/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx.c @@ -69,12 +69,15 @@ enum touch_state { extern int nvt_mmi_init(struct nvt_ts_data *ts_data, bool enable); #endif -#ifdef NVT_SENSOR_EN +#if defined (NVT_SENSOR_EN) || defined (CONFIG_INPUT_TOUCHSCREEN_MMI) #ifdef CONFIG_HAS_WAKELOCK static struct wake_lock gesture_wakelock; #else static struct wakeup_source *gesture_wakelock; #endif +#endif + +#if defined (NVT_SENSOR_EN) static struct sensors_classdev __maybe_unused sensors_touch_cdev = { .name = "dt-gesture", @@ -230,8 +233,6 @@ const struct mtk_chip_config spi_ctrdata = { }; #endif -static uint8_t bTouchIsAwake = 0; - /******************************************************* Description: Novatek touchscreen irq enable/disable function. @@ -1018,55 +1019,55 @@ void nvt_ts_wakeup_gesture_report(uint8_t gesture_id, uint8_t *data) switch (gesture_id) { case GESTURE_WORD_C: - NVT_LOG("Gesture : Word-C.\n"); + NVT_DBG("Gesture : Word-C.\n"); keycode = gesture_key_array[0]; break; case GESTURE_WORD_W: - NVT_LOG("Gesture : Word-W.\n"); + NVT_DBG("Gesture : Word-W.\n"); keycode = gesture_key_array[1]; break; case GESTURE_WORD_V: - NVT_LOG("Gesture : Word-V.\n"); + NVT_DBG("Gesture : Word-V.\n"); keycode = gesture_key_array[2]; break; case GESTURE_DOUBLE_CLICK: - NVT_LOG("Gesture : Double Click.\n"); + NVT_DBG("Gesture : Double Click.\n"); keycode = gesture_key_array[3]; break; case GESTURE_WORD_Z: - NVT_LOG("Gesture : Word-Z.\n"); + NVT_DBG("Gesture : Word-Z.\n"); keycode = gesture_key_array[4]; break; case GESTURE_WORD_M: - NVT_LOG("Gesture : Word-M.\n"); + NVT_DBG("Gesture : Word-M.\n"); keycode = gesture_key_array[5]; break; case GESTURE_WORD_O: - NVT_LOG("Gesture : Word-O.\n"); + NVT_DBG("Gesture : Word-O.\n"); keycode = gesture_key_array[6]; break; case GESTURE_WORD_e: - NVT_LOG("Gesture : Word-e.\n"); + NVT_DBG("Gesture : Word-e.\n"); keycode = gesture_key_array[7]; break; case GESTURE_WORD_S: - NVT_LOG("Gesture : Word-S.\n"); + NVT_DBG("Gesture : Word-S.\n"); keycode = gesture_key_array[8]; break; case GESTURE_SLIDE_UP: - NVT_LOG("Gesture : Slide UP.\n"); + NVT_DBG("Gesture : Slide UP.\n"); keycode = gesture_key_array[9]; break; case GESTURE_SLIDE_DOWN: - NVT_LOG("Gesture : Slide DOWN.\n"); + NVT_DBG("Gesture : Slide DOWN.\n"); keycode = gesture_key_array[10]; break; case GESTURE_SLIDE_LEFT: - NVT_LOG("Gesture : Slide LEFT.\n"); + NVT_DBG("Gesture : Slide LEFT.\n"); keycode = gesture_key_array[11]; break; case GESTURE_SLIDE_RIGHT: - NVT_LOG("Gesture : Slide RIGHT.\n"); + NVT_DBG("Gesture : Slide RIGHT.\n"); keycode = gesture_key_array[12]; break; default: @@ -1074,7 +1075,21 @@ void nvt_ts_wakeup_gesture_report(uint8_t gesture_id, uint8_t *data) } if (keycode > 0) { -#ifdef NVT_SENSOR_EN +#ifdef CONFIG_INPUT_TOUCHSCREEN_MMI + if (ts->imports && ts->imports->report_gesture) { + struct gesture_event_data event; + int ret = 0; + + dev_dbg(&ts->client->dev, + "%s: invoke imported report gesture function\n", __func__); + /* extract X and Y coordinates */ + event.evcode = 1; + /* call class method */ + ret = ts->imports->report_gesture(&event); + if (!ret) + PM_WAKEUP_EVENT(gesture_wakelock, 5000); + } +#elif NVT_SENSOR_EN if (!(ts->wakeable && ts->should_enable_gesture)) { NVT_LOG("Gesture got but wakeable not set. Skip this gesture."); return; @@ -1569,7 +1584,7 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) int32_t finger_cnt = 0; #if WAKEUP_GESTURE - if (bTouchIsAwake == 0) { + if (ts->bTouchIsAwake == 0) { pm_wakeup_event(&ts->input_dev->dev, 5000); } #endif @@ -1638,7 +1653,7 @@ static irqreturn_t nvt_ts_work_func(int irq, void *data) #endif /* POINT_DATA_CHECKSUM */ #if WAKEUP_GESTURE - if (bTouchIsAwake == 0) { + if (ts->bTouchIsAwake == 0) { input_id = (uint8_t)(point_data[1] >> 3); nvt_ts_wakeup_gesture_report(input_id, point_data); mutex_unlock(&ts->lock); @@ -2204,7 +2219,7 @@ static int pen_notifier_callback(struct notifier_block *self, else if (event == PEN_DETECTION_PULL) ts->nvt_pen_detect_flag = PEN_DETECTION_PULL; - if (!bTouchIsAwake || !ts->fw_ready_flag) { + if (!ts->bTouchIsAwake || !ts->fw_ready_flag) { NVT_LOG("touch in suspend or no firmware, so store."); } else { ret = nvt_mcu_pen_detect_set(ts->nvt_pen_detect_flag); @@ -2639,7 +2654,7 @@ static int32_t nvt_ts_probe(struct spi_device *client) goto err_create_touchscreen_class_failed; } - bTouchIsAwake = 1; + ts->bTouchIsAwake = 1; NVT_LOG("end\n"); nvt_irq_enable(true); @@ -2941,6 +2956,34 @@ static void nvt_ts_shutdown(struct spi_device *client) #endif } +/** + * Release all the touches in the linux input subsystem + * @param info pointer to fts_ts_info which contains info about the device and + * its hw setup + */ + +void release_all_touches(void) +{ +#if MT_PROTOCOL_B + uint32_t i = 0; + for (i = 0; i < ts->max_touch_num; i++) { + input_mt_slot(ts->input_dev, i); +#ifdef PALM_GESTURE_RANGE + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MINOR, 0); + input_report_abs(ts->input_dev, ABS_MT_ORIENTATION, 0); +#endif + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 0); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0); + } +#endif + input_report_key(ts->input_dev, BTN_TOUCH, 0); +#if !MT_PROTOCOL_B + input_mt_sync(ts->input_dev); +#endif + input_sync(ts->input_dev); +} + /******************************************************* Description: Novatek touchscreen driver suspend function. @@ -2951,15 +2994,12 @@ return: int32_t nvt_ts_suspend(struct device *dev) { uint8_t buf[4] = {0}; -#if MT_PROTOCOL_B - uint32_t i = 0; -#endif #ifdef NVT_SENSOR_EN mutex_lock(&ts->state_mutex); #endif - if (!bTouchIsAwake) { + if (!ts->bTouchIsAwake) { #ifdef NVT_SENSOR_EN mutex_unlock(&ts->state_mutex); #endif @@ -2986,7 +3026,7 @@ int32_t nvt_ts_suspend(struct device *dev) NVT_LOG("start\n"); - bTouchIsAwake = 0; + ts->bTouchIsAwake = 0; #if WAKEUP_GESTURE #ifdef NVT_SENSOR_EN @@ -3021,25 +3061,7 @@ int32_t nvt_ts_suspend(struct device *dev) mutex_unlock(&ts->lock); - /* release all touches */ -#if MT_PROTOCOL_B - for (i = 0; i < ts->max_touch_num; i++) { - input_mt_slot(ts->input_dev, i); -#ifdef PALM_GESTURE_RANGE - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MINOR, 0); - input_report_abs(ts->input_dev, ABS_MT_ORIENTATION, 0); -#endif - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); - input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 0); - input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0); - } -#endif - input_report_key(ts->input_dev, BTN_TOUCH, 0); -#if !MT_PROTOCOL_B - input_mt_sync(ts->input_dev); -#endif - input_sync(ts->input_dev); - + release_all_touches(); msleep(50); NVT_LOG("end\n"); @@ -3064,7 +3086,7 @@ int32_t nvt_ts_resume(struct device *dev) #ifdef NVT_SENSOR_EN mutex_lock(&ts->state_mutex); #endif - if (bTouchIsAwake) { + if (ts->bTouchIsAwake) { #ifdef NVT_SENSOR_EN mutex_unlock(&ts->state_mutex); #endif @@ -3111,7 +3133,7 @@ int32_t nvt_ts_resume(struct device *dev) #endif #endif - bTouchIsAwake = 1; + ts->bTouchIsAwake = 1; mutex_unlock(&ts->lock); @@ -3414,7 +3436,7 @@ static int charger_notifier_callback(struct notifier_block *nb, }else{ charger_detection->usb_connected = USB_DETECT_OUT; } - if (bTouchIsAwake){ + if (ts->bTouchIsAwake){ queue_work(charger_detection->nvt_charger_notify_wq, &charger_detection->charger_notify_work); } diff --git a/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx.h b/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx.h index d53a40e4383b..43d4ad24e68c 100644 --- a/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx.h +++ b/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx.h @@ -54,6 +54,10 @@ #include +#if defined(CONFIG_INPUT_TOUCHSCREEN_MMI) +#include +#endif + #define NVT_DEBUG 1 //---GPIO number--- @@ -77,6 +81,7 @@ #define NVT_LOG(fmt, args...) pr_info("[%s] %s %d: " fmt, NVT_SPI_NAME, __func__, __LINE__, ##args) #endif #define NVT_ERR(fmt, args...) pr_err("[%s] %s %d: " fmt, NVT_SPI_NAME, __func__, __LINE__, ##args) +#define NVT_DBG(fmt, args...) pr_debug("[%s] %s %d: " fmt, NVT_SPI_NAME, __func__, __LINE__, ##args) //---Input device info.--- #define NVT_TS_NAME "NVTCapacitiveTouchScreen" @@ -117,7 +122,7 @@ extern const uint16_t touch_key_array[TOUCH_KEY_NUM]; #define NVT_TOUCH_EXT_PROC 1 #define NVT_TOUCH_MP 1 #define MT_PROTOCOL_B 1 -#ifdef NVT_SENSOR_EN +#if defined (NVT_SENSOR_EN) || defined (CONFIG_INPUT_TOUCHSCREEN_MMI) #define WAKEUP_GESTURE 1 #else #define WAKEUP_GESTURE 0 @@ -179,7 +184,7 @@ struct nvt_ts_data { struct delayed_work nvt_fwu_work; uint16_t addr; int8_t phys[32]; - + uint8_t bTouchIsAwake; uint8_t fw_ver; uint8_t x_num; uint8_t y_num; @@ -211,10 +216,12 @@ struct nvt_ts_data { #ifdef CONFIG_SPI_MT65XX struct mtk_chip_config spi_ctrl; #endif -#ifdef NVT_SENSOR_EN - bool wakeable; - bool should_enable_gesture; +#ifdef WAKEUP_GESTURE bool gesture_enabled; + bool wakeable; +#endif +#ifdef NVT_SENSOR_EN + bool should_enable_gesture; #ifdef NOVATECH_PEN_NOTIFIER bool fw_ready_flag; int nvt_pen_detect_flag; @@ -253,6 +260,10 @@ struct nvt_ts_data { struct notifier_block panel_notif; #endif #endif //version code >= 5.4.0 + +#if defined(CONFIG_INPUT_TOUCHSCREEN_MMI) + struct ts_mmi_class_methods *imports; +#endif }; #if NVT_TOUCH_PROC @@ -348,4 +359,5 @@ extern int nvt_palm_set(bool enabled); extern int32_t nvt_edge_reject_set(uint32_t status); extern uint8_t nvt_edge_reject_read(void); #endif +void release_all_touches(void); #endif /* _LINUX_NVT_TOUCH_H */ diff --git a/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx_mmi_class.c b/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx_mmi_class.c index deaf86587d17..0ae794f17479 100644 --- a/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx_mmi_class.c +++ b/drivers/input/touchscreen/nova_0flash_mmi/nt36xxx_mmi_class.c @@ -11,6 +11,7 @@ * GNU General Public License for more details. */ +#include #include #include #include @@ -182,11 +183,16 @@ static int nvt_mmi_panel_state(struct device *dev, GET_TS_DATA(dev); dev_dbg(dev, "%s: panel state change: %d->%d\n", __func__, from, to); - pr_info("panel state change: %d->%d\n", from, to); + NVT_LOG("panel state change: %d->%d\n", from, to); switch (to) { case TS_MMI_PM_GESTURE: + ts->gesture_enabled = true; + touch_set_state(TS_MMI_PM_GESTURE, TOUCH_PANEL_IDX_PRIMARY); + break; + case TS_MMI_PM_DEEPSLEEP: - nvt_ts_suspend(&ts_data->client->dev); + ts->gesture_enabled = false; + touch_set_state(TS_MMI_PM_DEEPSLEEP, TOUCH_PANEL_IDX_PRIMARY); break; case TS_MMI_PM_ACTIVE: @@ -195,20 +201,82 @@ static int nvt_mmi_panel_state(struct device *dev, dev_warn(dev, "panel mode %d is invalid.\n", to); return -EINVAL; } - - pr_info("IRQ is %s\n", ts_data->irq_enabled ? "EN" : "DIS"); + NVT_LOG("IRQ is %s\n", ts_data->irq_enabled ? "EN" : "DIS"); return 0; - } + +int32_t nvt_mmi_post_suspend(struct device *dev) +{ + uint8_t buf[4] = {0}; + + mutex_lock(&ts->lock); + NVT_LOG("enter\n"); + + if (ts->gesture_enabled) { + //---write command to enter "wakeup gesture mode"--- + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x13; + CTP_SPI_WRITE(ts->client, buf, 2); + enable_irq_wake(ts->client->irq); + NVT_LOG("Enabled touch wakeup gesture\n"); + } else { + //---write command to enter "deep sleep mode"--- + buf[0] = EVENT_MAP_HOST_CMD; + buf[1] = 0x11; + CTP_SPI_WRITE(ts->client, buf, 2); + } + ts->bTouchIsAwake = 0; + + mutex_unlock(&ts->lock); + + release_all_touches(); + msleep(50); + + return 0; +} + +/******************************************************* +Description: + Novatek touchscreen driver resume function. + +return: + Executive outcomes. 0---succeed. +*******************************************************/ +static int nvt_mmi_pre_resume(struct device *dev) +{ + struct nvt_ts_data *ts_data; + int ret = 0; + + GET_TS_DATA(dev); + NVT_LOG("enter\n"); + + mutex_lock(&ts->lock); + ret = nvt_update_firmware(nvt_boot_firmware_name); + if (ret) { + NVT_ERR("download firmware failed, ignore check fw state\n"); + } else { + nvt_check_fw_reset_state(RESET_STATE_REK); + } + mutex_unlock(&ts->lock); + + return 0; +} + static int nvt_mmi_post_resume(struct device *dev) { struct nvt_ts_data *ts_data; GET_TS_DATA(dev); - pr_info("enter\n"); - dev_dbg(dev, "%s\n", __func__); - nvt_ts_resume(&ts_data->client->dev); - pr_info("IRQ is %s\n", ts_data->irq_enabled ? "EN" : "DIS"); + NVT_LOG("enter\n"); + + mutex_lock(&ts->lock); + if (ts->gesture_enabled) + disable_irq_wake(ts_data->client->irq); + + ts->bTouchIsAwake = 1; + mutex_unlock(&ts->lock); + + NVT_LOG("IRQ is %s\n", ts_data->irq_enabled ? "EN" : "DIS"); return 0; } @@ -230,7 +298,9 @@ static struct ts_mmi_methods nvt_mmi_methods = { .firmware_update = nvt_mmi_firmware_update, /* PM callback */ .panel_state = nvt_mmi_panel_state, + .pre_resume = nvt_mmi_pre_resume, .post_resume = nvt_mmi_post_resume, + .post_suspend = nvt_mmi_post_suspend, }; @@ -241,6 +311,8 @@ int nvt_mmi_init(struct nvt_ts_data *ts_data, bool enable) { ret = ts_mmi_dev_register(&ts_data->client->dev, &nvt_mmi_methods); if (ret) dev_err(&ts_data->client->dev, "Failed to register ts mmi\n"); + /* initialize class imported methods */ + ts_data->imports = &nvt_mmi_methods.exports; } else ts_mmi_dev_unregister(&ts_data->client->dev);