diff --git a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.c b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.c index 6a299ae8701c..d87f375a5816 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.c +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.c @@ -1132,6 +1132,11 @@ static int goodix_parse_dt(struct device_node *node, if (board_data->edge_ctrl) ts_info("support goodix edge mode"); + board_data->stowed_mode_ctrl = of_property_read_bool(node, + "goodix,stowed-mode-ctrl"); + if (board_data->stowed_mode_ctrl) + ts_info("Support goodix touch stowed mode"); + if (of_property_read_bool(node, "goodix,gesture-wait-pm")) { ts_info("gesture-wait-pm set"); board_data->gesture_wait_pm = true; 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 551d6ee02210..407fc15c0ded 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.h +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.h @@ -307,6 +307,7 @@ struct goodix_ts_board_data { bool sample_ctrl; bool report_rate_ctrl; bool edge_ctrl; + bool stowed_mode_ctrl; bool gesture_wait_pm; }; @@ -498,6 +499,7 @@ struct goodix_mode_info { #ifdef GOODIX_PALM_SENSOR_EN int palm_detection; #endif + int stowed; }; struct goodix_ts_core { @@ -535,6 +537,7 @@ struct goodix_ts_core { atomic_t irq_enabled; atomic_t suspended; + atomic_t post_suspended; /* when this flag is true, driver should not clean the sync flag */ bool tools_ctrl_sync; 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 e4fe27736137..4984ec2f4309 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.c +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.c @@ -58,6 +58,10 @@ static ssize_t goodix_ts_log_trigger_store(struct device *dev, static ssize_t goodix_ts_log_trigger_show(struct device *dev, struct device_attribute *attr, char *buf); #endif +static ssize_t goodix_ts_stowed_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size); +static ssize_t goodix_ts_stowed_show(struct device *dev, + struct device_attribute *attr, char *buf); static DEVICE_ATTR(edge, (S_IRUGO | S_IWUSR | S_IWGRP), goodix_ts_edge_show, goodix_ts_edge_store); @@ -76,6 +80,8 @@ static DEVICE_ATTR(timestamp, S_IRUGO, goodix_ts_timestamp_show, NULL); static DEVICE_ATTR(log_trigger, (S_IRUGO | S_IWUSR | S_IWGRP), goodix_ts_log_trigger_show, goodix_ts_log_trigger_store); #endif +static DEVICE_ATTR(stowed, (S_IWUSR | S_IWGRP | S_IRUGO), + goodix_ts_stowed_show, goodix_ts_stowed_store); /* hal settings */ #define ROTATE_0 0 @@ -129,6 +135,9 @@ static int goodix_ts_mmi_extend_attribute_group(struct device *dev, struct attri if (core_data->board_data.sensitivity_ctrl) ADD_ATTR(sensitivity); + if (core_data->board_data.stowed_mode_ctrl) + ADD_ATTR(stowed); + #ifdef CONFIG_GTP_LAST_TIME ADD_ATTR(timestamp); #endif @@ -573,6 +582,67 @@ static ssize_t goodix_ts_sample_show(struct device *dev, return scnprintf(buf, PAGE_SIZE, "0x%02x", core_data->set_mode.sample); } +static ssize_t goodix_ts_stowed_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int ret = 0; + unsigned long mode = 0; + struct platform_device *pdev; + struct goodix_ts_core *core_data; + + dev = MMI_DEV_TO_TS_DEV(dev); + GET_GOODIX_DATA(dev); + + ret = kstrtoul(buf, 0, &mode); + if (ret < 0) { + pr_info("Failed to convert value.\n"); + return -EINVAL; + } + + mutex_lock(&core_data->mode_lock); + core_data->get_mode.stowed = mode; + if (core_data->set_mode.stowed == mode) { + ts_debug("The value = %lu is same, so not to write", mode); + ret = size; + goto exit; + } + + if ((atomic_read(&core_data->post_suspended) == 1) && (core_data->power_on == 1)) { + ret = goodix_ts_send_cmd(core_data, ENTER_STOWED_MODE_CMD, 5, + core_data->get_mode.stowed, 0x00); + if (ret < 0) { + ts_err("Failed to set stowed mode %lu\n", mode); + goto exit; + } + } else { + ts_info("Skip stowed mode setting post_suspended:%d, power_on:%d.\n", + atomic_read(&core_data->post_suspended), core_data->power_on); + ret = size; + goto exit; + } + + core_data->set_mode.stowed = mode; + ts_info("Success to set stowed mode %lu\n", mode); + + ret = size; +exit: + mutex_unlock(&core_data->mode_lock); + return ret; +} + +static ssize_t goodix_ts_stowed_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct platform_device *pdev; + struct goodix_ts_core *core_data; + + dev = MMI_DEV_TO_TS_DEV(dev); + GET_GOODIX_DATA(dev); + + ts_info("Stowed state = %d.\n", core_data->set_mode.stowed); + return scnprintf(buf, PAGE_SIZE, "0x%02x", core_data->set_mode.stowed); +} + static int goodix_ts_mmi_refresh_rate(struct device *dev, int freq) { struct platform_device *pdev; @@ -1089,6 +1159,7 @@ static int goodix_ts_mmi_pre_resume(struct device *dev) { GET_GOODIX_DATA(dev); atomic_set(&core_data->suspended, 0); + atomic_set(&core_data->post_suspended, 0); if (core_data->gesture_enabled) { core_data->hw_ops->irq_enable(core_data, false); disable_irq_wake(core_data->irq); @@ -1200,6 +1271,10 @@ static int goodix_ts_mmi_post_resume(struct device *dev) { } } #endif + + if (core_data->board_data.stowed_mode_ctrl) { + core_data->set_mode.stowed = 0; + } mutex_unlock(&core_data->mode_lock); #ifdef CONFIG_GTP_FOD if(core_data->zerotap_data[0]) { @@ -1267,6 +1342,7 @@ static int goodix_ts_mmi_pre_suspend(struct device *dev) { static int goodix_ts_mmi_post_suspend(struct device *dev) { + int ret = 0; struct goodix_ts_core *core_data; struct platform_device *pdev; @@ -1274,6 +1350,19 @@ static int goodix_ts_mmi_post_suspend(struct device *dev) { goodix_ts_release_connects(core_data); + atomic_set(&core_data->post_suspended, 1); + mutex_lock(&core_data->mode_lock); + if (core_data->board_data.stowed_mode_ctrl && core_data->get_mode.stowed) { + ret = goodix_ts_send_cmd(core_data, ENTER_STOWED_MODE_CMD, 5, core_data->get_mode.stowed, 0x00); + if (ret < 0) { + ts_err("Failed to set stowed mode %d\n", core_data->get_mode.stowed); + } else { + core_data->set_mode.stowed = core_data->get_mode.stowed; + ts_info("Enable stowed mode %d success.\n", core_data->set_mode.stowed); + } + } + mutex_unlock(&core_data->mode_lock); + ts_info("Suspend end"); return 0; } 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 6021e4b99d58..55bd1d483f60 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.h +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.h @@ -59,4 +59,5 @@ int goodix_ts_send_cmd(struct goodix_ts_core *core_data, #define ENTER_GESTURE_MODE_CMD 0xA6 #define LIQUID_DETECTION_SWITCH_CMD 0x33 #define PALM_DETECTION_SWITCH_CMD 0x93 +#define ENTER_STOWED_MODE_CMD 0x97 #endif