From e1c9b20d746c43451a9bf7c798c43adde4f30f16 Mon Sep 17 00:00:00 2001 From: Wenge Zhu Date: Mon, 27 Feb 2023 11:39:01 +0800 Subject: [PATCH] Add gesture support for zinitix touch IC Add single and double tap gesture support for zinitix touch IC. Change-Id: I23530196d21c8800845f2b5b81096006a7da2421 Signed-off-by: Wenge Zhu Reviewed-on: https://gerrit.mot.com/2521947 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Jichao Zou Submit-Approved: Jira Key --- .../touchscreen/zinitix_ztw62x_mmi/zinitix.c | 105 +++++++++++++----- .../zinitix_ztw62x_mmi/zinitix_touch.h | 8 ++ .../zinitix_ztw62x_mmi/zinitix_ts_mmi.c | 24 ++++ 3 files changed, 112 insertions(+), 25 deletions(-) diff --git a/drivers/input/touchscreen/zinitix_ztw62x_mmi/zinitix.c b/drivers/input/touchscreen/zinitix_ztw62x_mmi/zinitix.c index 716947585194..8ee3262b8a92 100644 --- a/drivers/input/touchscreen/zinitix_ztw62x_mmi/zinitix.c +++ b/drivers/input/touchscreen/zinitix_ztw62x_mmi/zinitix.c @@ -292,7 +292,6 @@ struct reg_ioctl { extern int get_lcd_attached(void); extern unsigned int system_rev; -static volatile int __maybe_unused tpd_halt = 0; struct class *sec_class; /* end header file */ @@ -2096,7 +2095,7 @@ static irqreturn_t bt541_touch_work(int irq, void *data) u32 tmp; //u8 read_result = 1; u8 palm = 0; -#if USE_WAKEUP_GESTURE +#if defined(USE_WAKEUP_GESTURE) || defined(CONFIG_INPUT_TOUCHSCREEN_MMI) u16 gesture_flag=0; int ret =0; #endif @@ -2108,14 +2107,12 @@ static irqreturn_t bt541_touch_work(int irq, void *data) return IRQ_HANDLED; } - #if ESD_TIMER_INTERVAL esd_timer_stop(info); #endif #if USE_WAKEUP_GESTURE if((tpd_halt)&&(info->work_state == SUSPEND)) //suspend state support gesture { - dev_err(&client->dev," gesture wakeup "); if (read_data(client, 0x126,(u8 *)&gesture_flag, 2) < 0) //0x126 { @@ -2149,15 +2146,69 @@ static irqreturn_t bt541_touch_work(int irq, void *data) ret=0; } - } - } goto out; } +#elif defined(CONFIG_INPUT_TOUCHSCREEN_MMI) + if((tpd_halt)&&(info->work_state == SUSPEND)) //suspend state support gesture + { + dev_info(&client->dev," gesture wakeup "); + if (read_data(client, 0x126,(u8 *)&gesture_flag, 2) < 0) //0x126 + { + dev_err(&client->dev," gesture read reg error!!!\r\n"); + ret=0; + /*eric add 20160920*/ + write_cmd(client, BT541_CLEAR_INT_STATUS_CMD); + } + else + { + /*wake up*/ + /*eric add 20160920*/ + write_cmd(client, BT541_CLEAR_INT_STATUS_CMD); + /*1 single click*/ + if(gesture_flag==1) + { + dev_info(&client->dev,"%s: got single tap event\n", __func__); + if (info->imports && info->imports->report_gesture) { + struct gesture_event_data event; + + dev_info(&client->dev,"%s: report single tap gesture event\n", __func__); + event.evcode = 1; + /* call class method */ + ret = info->imports->report_gesture(&event); + } + } + /*1 double click*/ + else if (gesture_flag==2) { + dev_info(&client->dev,"%s: got double tap event\n", __func__); + if (info->imports && info->imports->report_gesture) { + struct gesture_event_data event; + + dev_info(&client->dev,"%s: report double tap gesture event\n", __func__); + event.evcode = 4; + /* call class method */ + ret = info->imports->report_gesture(&event); + } + } + if (!ret) { +#ifdef CONFIG_HAS_WAKELOCK + wake_lock_timeout(&info->gesture_wakelock, msecs_to_jiffies(3000)); +#else + PM_WAKEUP_EVENT(info->gesture_wakelock, 3000); #endif + } + if (write_reg(client, 0x126, 0) != 0) + { + dev_err(&client->dev," gesture write reg error!!!\r\n"); + ret=0; + } + } + goto out; + } +#endif if (info->work_state != NOTHING) { dev_err(&client->dev, "%s: Other process occupied\n", __func__); @@ -2168,7 +2219,6 @@ static irqreturn_t bt541_touch_work(int irq, void *data) info->work_state = NORMAL; - if (ts_read_coord(info) == false ) { dev_err(&client->dev, "couldn't read touch_dev coord. read fail\r\n"); @@ -2453,25 +2503,10 @@ int zinitix_ts_mmi_gesture_suspend(struct device *dev) struct bt541_ts_info *info = i2c_get_clientdata(client); down(&info->work_lock); - //reset gesture register - if (write_reg(client, 0x126, 0) != I2C_SUCCESS) { - dev_err(dev, "%s: Reset gesture register error.\n", __func__); - up(&info->work_lock); - return -1; - } - //enable irq wake - enable_irq_wake(info->irq); - info->irq_enabled = true; - //send enable easy wake gesture cmd - if (write_reg(client, 0x011D, 0x0089) != I2C_SUCCESS) { - zinitix_printk("easy_wakeup_gesture write_reg[0x0089] failed!!!-------------\n"); - up(&info->work_lock); - return -1; - } - //clear INT status + //software reset for(i = 0; i < 3; i++) { - if (write_cmd(client, BT541_CLEAR_INT_STATUS_CMD) < 0) { - dev_err(&client->dev,"tpd_suspend fail to clear int(%d)\r\n", i); + if (write_cmd(client, BT541_SWRESET_CMD) < 0) { + dev_err(&client->dev,"tpd_suspend fail to sft reset(%d)\r\n", i); mdelay(10); continue; } else @@ -2481,6 +2516,16 @@ int zinitix_ts_mmi_gesture_suspend(struct device *dev) up(&info->work_lock); return -1; } + msleep(20); + //enable irq wake + enable_irq_wake(info->irq); + info->irq_enabled = true; + //send enable easy wake gesture cmd + if (write_reg(client, 0x011D, info->gesture_command) != I2C_SUCCESS) { + zinitix_printk("easy_wakeup_gesture write_reg[0x0089] failed!!!-------------\n"); + up(&info->work_lock); + return -1; + } //send idle cmd for(i = 0; i < 3; i++) { if (write_cmd(client, BT541_IDLE_CMD) < 0) { @@ -6025,6 +6070,14 @@ static int bt541_ts_probe(struct i2c_client *client, } #endif + PM_WAKEUP_REGISTER(&client->dev, info->gesture_wakelock, + "zinitix_gesture_wakelock"); + if (!info->gesture_wakelock) { + dev_info(&client->dev, "%s: allocate gesture wakeup source err!\n", __func__); + ret = -ENOMEM; + goto err_register_gesture_wakelock; + } + #ifdef SEC_FACTORY_TEST init_completion(&info->builtin_cmcp_threshold_complete); INIT_WORK(&info->cmcp_threshold_update, @@ -6036,6 +6089,8 @@ static int bt541_ts_probe(struct i2c_client *client, return ret; +err_register_gesture_wakelock: + PM_WAKEUP_UNREGISTER(info->gesture_wakelock); err_ts_mmi_register: #ifdef SEC_FACTORY_TEST err_kthread_create_failed: diff --git a/drivers/input/touchscreen/zinitix_ztw62x_mmi/zinitix_touch.h b/drivers/input/touchscreen/zinitix_ztw62x_mmi/zinitix_touch.h index 6a1a438159f5..57551788110d 100644 --- a/drivers/input/touchscreen/zinitix_ztw62x_mmi/zinitix_touch.h +++ b/drivers/input/touchscreen/zinitix_ztw62x_mmi/zinitix_touch.h @@ -122,6 +122,8 @@ #define MAX_TRAW_DATA_SZ \ (MAX_RAW_DATA_SZ + 4*MAX_SUPPORTED_FINGER_NUM + 2) +extern volatile int tpd_halt; + enum power_control { POWER_OFF, POWER_ON, @@ -290,6 +292,12 @@ struct bt541_ts_info { bool checkUMSmode; bool irq_enabled; bool gesture_enabled; + u16 gesture_command; +#ifdef CONFIG_HAS_WAKELOCK + struct wake_lock gesture_wakelock; +#else + struct wakeup_source *gesture_wakelock; +#endif #if defined(CONFIG_INPUT_TOUCHSCREEN_MMI) struct ts_mmi_class_methods *imports; diff --git a/drivers/input/touchscreen/zinitix_ztw62x_mmi/zinitix_ts_mmi.c b/drivers/input/touchscreen/zinitix_ztw62x_mmi/zinitix_ts_mmi.c index 2cf0799888bd..009eec0dc22f 100644 --- a/drivers/input/touchscreen/zinitix_ztw62x_mmi/zinitix_ts_mmi.c +++ b/drivers/input/touchscreen/zinitix_ztw62x_mmi/zinitix_ts_mmi.c @@ -21,6 +21,8 @@ return -ENODEV; \ } +volatile int tpd_halt = 0; + static int zinitix_ts_mmi_methods_get_vendor(struct device *dev, void *cdata) { return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_VENDOR_LEN, "%s", "zinitix"); @@ -219,11 +221,31 @@ static int zinitix_ts_mmi_methods_drv_irq(struct device *dev, int state) static int zinitix_ts_mmi_panel_state(struct device *dev, enum ts_mmi_pm_mode from, enum ts_mmi_pm_mode to) { + unsigned char gesture_type = 0; struct bt541_ts_info *info = dev_get_drvdata(dev); ASSERT_PTR(info); switch (to) { case TS_MMI_PM_GESTURE: + if (info->imports && info->imports->get_gesture_type) { + if (info->imports->get_gesture_type(dev, &gesture_type) < 0) { + dev_err(dev, "%s: get gesture type error.\n", __func__); + return -EINVAL; + } + } + + info->gesture_command = 0; + + if (gesture_type & TS_MMI_GESTURE_SINGLE) { + info->gesture_command |= 0x0089; + dev_info(dev, "Enable GESTURE_CLI_SINGLE command: 0x%04x", info->gesture_command); + } + if (gesture_type & TS_MMI_GESTURE_DOUBLE) { + info->gesture_command |= 0x0091; + dev_info(dev, "Enable GESTURE_CLI_DOUBLE command: 0x%04x", info->gesture_command); + } + dev_info(dev, "CLI GESTURE SWITCH command: 0x%04x", info->gesture_command); + if (zinitix_ts_mmi_gesture_suspend(dev) < 0) { dev_err(dev, "%s: Gesture suspend error.\n", __func__); return -EINVAL; @@ -264,6 +286,7 @@ static int zinitix_ts_mmi_pre_suspend(struct device *dev) dev_info(dev, "%s: Suspend start \n", __func__); down(&info->work_lock); + tpd_halt = 1; //stop ESD #if ESD_TIMER_INTERVAL flush_work(&info->tmr_work); @@ -313,6 +336,7 @@ static int zinitix_ts_mmi_post_resume(struct device *dev) #if ESD_TIMER_INTERVAL esd_timer_start(CHECK_ESD_TIMER, info); #endif + tpd_halt = 0; info->work_state = NOTHING; up(&info->work_lock); dev_info(dev, "%s: Resume end\n", __func__);