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 <zhuwg1@motorola.com>
Reviewed-on: https://gerrit.mot.com/2521947
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Jichao Zou <zoujc@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
Wenge Zhu authored and zhuwg1 committed 2023-02-28 03:57:39 -06:00
1 parent 5a1c5d012f
commit e1c9b20d74
3 files changed
+112 -25

No files matched your search

@@ -292,7 +292,6 @@ struct reg_ioctl {
extern int get_lcd_attached(void); extern int get_lcd_attached(void);
extern unsigned int system_rev; extern unsigned int system_rev;
static volatile int __maybe_unused tpd_halt = 0;
struct class *sec_class; struct class *sec_class;
/* end header file */ /* end header file */
@@ -2096,7 +2095,7 @@ static irqreturn_t bt541_touch_work(int irq, void *data)
u32 tmp; u32 tmp;
//u8 read_result = 1; //u8 read_result = 1;
u8 palm = 0; u8 palm = 0;
#if USE_WAKEUP_GESTURE #if defined(USE_WAKEUP_GESTURE) || defined(CONFIG_INPUT_TOUCHSCREEN_MMI)
u16 gesture_flag=0; u16 gesture_flag=0;
int ret =0; int ret =0;
#endif #endif
@@ -2108,14 +2107,12 @@ static irqreturn_t bt541_touch_work(int irq, void *data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
#if ESD_TIMER_INTERVAL #if ESD_TIMER_INTERVAL
esd_timer_stop(info); esd_timer_stop(info);
#endif #endif
#if USE_WAKEUP_GESTURE #if USE_WAKEUP_GESTURE
if((tpd_halt)&&(info->work_state == SUSPEND)) //suspend state support gesture if((tpd_halt)&&(info->work_state == SUSPEND)) //suspend state support gesture
{ {
dev_err(&client->dev," gesture wakeup "); dev_err(&client->dev," gesture wakeup ");
if (read_data(client, 0x126,(u8 *)&gesture_flag, 2) < 0) //0x126 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; ret=0;
} }
} }
} }
goto out; 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 #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) { if (info->work_state != NOTHING) {
dev_err(&client->dev, "%s: Other process occupied\n", __func__); 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; info->work_state = NORMAL;
if (ts_read_coord(info) == false ) if (ts_read_coord(info) == false )
{ {
dev_err(&client->dev, "couldn't read touch_dev coord. read fail\r\n"); 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); struct bt541_ts_info *info = i2c_get_clientdata(client);
down(&info->work_lock); down(&info->work_lock);
//reset gesture register //software reset
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
for(i = 0; i < 3; i++) { for(i = 0; i < 3; i++) {
if (write_cmd(client, BT541_CLEAR_INT_STATUS_CMD) < 0) { if (write_cmd(client, BT541_SWRESET_CMD) < 0) {
dev_err(&client->dev,"tpd_suspend fail to clear int(%d)\r\n", i); dev_err(&client->dev,"tpd_suspend fail to sft reset(%d)\r\n", i);
mdelay(10); mdelay(10);
continue; continue;
} else } else
@@ -2481,6 +2516,16 @@ int zinitix_ts_mmi_gesture_suspend(struct device *dev)
up(&info->work_lock); up(&info->work_lock);
return -1; 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 //send idle cmd
for(i = 0; i < 3; i++) { for(i = 0; i < 3; i++) {
if (write_cmd(client, BT541_IDLE_CMD) < 0) { if (write_cmd(client, BT541_IDLE_CMD) < 0) {
@@ -6025,6 +6070,14 @@ static int bt541_ts_probe(struct i2c_client *client,
} }
#endif #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 #ifdef SEC_FACTORY_TEST
init_completion(&info->builtin_cmcp_threshold_complete); init_completion(&info->builtin_cmcp_threshold_complete);
INIT_WORK(&info->cmcp_threshold_update, INIT_WORK(&info->cmcp_threshold_update,
@@ -6036,6 +6089,8 @@ static int bt541_ts_probe(struct i2c_client *client,
return ret; return ret;
err_register_gesture_wakelock:
PM_WAKEUP_UNREGISTER(info->gesture_wakelock);
err_ts_mmi_register: err_ts_mmi_register:
#ifdef SEC_FACTORY_TEST #ifdef SEC_FACTORY_TEST
err_kthread_create_failed: err_kthread_create_failed:
@@ -122,6 +122,8 @@
#define MAX_TRAW_DATA_SZ \ #define MAX_TRAW_DATA_SZ \
(MAX_RAW_DATA_SZ + 4*MAX_SUPPORTED_FINGER_NUM + 2) (MAX_RAW_DATA_SZ + 4*MAX_SUPPORTED_FINGER_NUM + 2)
extern volatile int tpd_halt;
enum power_control { enum power_control {
POWER_OFF, POWER_OFF,
POWER_ON, POWER_ON,
@@ -290,6 +292,12 @@ struct bt541_ts_info {
bool checkUMSmode; bool checkUMSmode;
bool irq_enabled; bool irq_enabled;
bool gesture_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) #if defined(CONFIG_INPUT_TOUCHSCREEN_MMI)
struct ts_mmi_class_methods *imports; struct ts_mmi_class_methods *imports;
@@ -21,6 +21,8 @@
return -ENODEV; \ return -ENODEV; \
} }
volatile int tpd_halt = 0;
static int zinitix_ts_mmi_methods_get_vendor(struct device *dev, void *cdata) 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"); 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, static int zinitix_ts_mmi_panel_state(struct device *dev,
enum ts_mmi_pm_mode from, enum ts_mmi_pm_mode to) 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); struct bt541_ts_info *info = dev_get_drvdata(dev);
ASSERT_PTR(info); ASSERT_PTR(info);
switch (to) { switch (to) {
case TS_MMI_PM_GESTURE: 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) { if (zinitix_ts_mmi_gesture_suspend(dev) < 0) {
dev_err(dev, "%s: Gesture suspend error.\n", __func__); dev_err(dev, "%s: Gesture suspend error.\n", __func__);
return -EINVAL; return -EINVAL;
@@ -264,6 +286,7 @@ static int zinitix_ts_mmi_pre_suspend(struct device *dev)
dev_info(dev, "%s: Suspend start \n", __func__); dev_info(dev, "%s: Suspend start \n", __func__);
down(&info->work_lock); down(&info->work_lock);
tpd_halt = 1;
//stop ESD //stop ESD
#if ESD_TIMER_INTERVAL #if ESD_TIMER_INTERVAL
flush_work(&info->tmr_work); flush_work(&info->tmr_work);
@@ -313,6 +336,7 @@ static int zinitix_ts_mmi_post_resume(struct device *dev)
#if ESD_TIMER_INTERVAL #if ESD_TIMER_INTERVAL
esd_timer_start(CHECK_ESD_TIMER, info); esd_timer_start(CHECK_ESD_TIMER, info);
#endif #endif
tpd_halt = 0;
info->work_state = NOTHING; info->work_state = NOTHING;
up(&info->work_lock); up(&info->work_lock);
dev_info(dev, "%s: Resume end\n", __func__); dev_info(dev, "%s: Resume end\n", __func__);