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 <wengjun1@motorola.com>
Reviewed-by: Jichao Zou <zoujc@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
litong20 2021-05-21 13:47:35 +08:00 • committed by litong
commit 39087fae46
3 changed files with 165 additions and 59 deletions

View file

@ -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);
}

View file

@ -54,6 +54,10 @@
#include <linux/mmi_wake_lock.h>
#if defined(CONFIG_INPUT_TOUCHSCREEN_MMI)
#include <linux/touchscreen_mmi.h>
#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 */

View file

@ -11,6 +11,7 @@
* GNU General Public License for more details.
*/
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/touchscreen_mmi.h>
#include <linux/regulator/consumer.h>
@ -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);