From be6449a242ab5e645e0e33b4e3d1a0909b877a2a Mon Sep 17 00:00:00 2001 From: Xiaojun Lv Date: Fri, 17 Nov 2023 12:16:18 +0800 Subject: [PATCH] focaltech: support stowed detection when gesture mode for focal Support for touch stowed detection when gesture mode. Under gesture mode, when entering Stowed, touch will enter deep standby mode, and detection will resume when unstowed. Refer: (CR) Change-Id: I1c6591d83ccc17894c03246599903d0680ab2941 Reviewed-on: https://gerrit.mot.com/2797264 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Yeqing Wang Reviewed-by: Jun Weng Reviewed-by: Huosheng Liao Submit-Approved: Jira Key --- .../focaltech_touch_v3/focaltech_common.h | 2 + .../focaltech_touch_v3/focaltech_core.c | 5 ++ .../focaltech_touch_v3/focaltech_core.h | 2 + .../focaltech_touch_v3/focaltech_ts_mmi.c | 90 +++++++++++++++++++ 4 files changed, 99 insertions(+) diff --git a/drivers/input/touchscreen/focaltech_touch_v3/focaltech_common.h b/drivers/input/touchscreen/focaltech_touch_v3/focaltech_common.h index dfbc9497a711..14155c223eea 100644 --- a/drivers/input/touchscreen/focaltech_touch_v3/focaltech_common.h +++ b/drivers/input/touchscreen/focaltech_touch_v3/focaltech_common.h @@ -82,6 +82,8 @@ #define FTS_REG_CHIP_ID 0xA3 #define FTS_REG_CHIP_ID2 0x9F #define FTS_REG_POWER_MODE 0xA5 +#define FTS_REG_POWER_MODE_ACTIVE 0 +#define FTS_REG_POWER_MODE_STANDBY 0x02 #define FTS_REG_POWER_MODE_SLEEP 0x03 #define FTS_REG_FW_VER 0xA6 #define FTS_REG_VENDOR_ID 0xA8 diff --git a/drivers/input/touchscreen/focaltech_touch_v3/focaltech_core.c b/drivers/input/touchscreen/focaltech_touch_v3/focaltech_core.c index cd1cefa93584..027dd3bb2899 100644 --- a/drivers/input/touchscreen/focaltech_touch_v3/focaltech_core.c +++ b/drivers/input/touchscreen/focaltech_touch_v3/focaltech_core.c @@ -1972,6 +1972,11 @@ static int fts_parse_dt(struct device *dev, struct fts_ts_platform_data *pdata) if (pdata->sample_ctrl) FTS_INFO("support focaltech sample mode"); + pdata->stowed_mode_ctrl = of_property_read_bool(np, + "focaltech,stowed-mode-ctrl"); + if (pdata->stowed_mode_ctrl) + FTS_INFO("Support focaltech touch stowed mode"); + FTS_FUNC_EXIT(); return 0; diff --git a/drivers/input/touchscreen/focaltech_touch_v3/focaltech_core.h b/drivers/input/touchscreen/focaltech_touch_v3/focaltech_core.h index eec08c0315f2..8f8952aca0e7 100644 --- a/drivers/input/touchscreen/focaltech_touch_v3/focaltech_core.h +++ b/drivers/input/touchscreen/focaltech_touch_v3/focaltech_core.h @@ -161,6 +161,7 @@ struct fts_ts_platform_data { bool interpolation_ctrl; bool report_rate_ctrl; bool sample_ctrl; + bool stowed_mode_ctrl; }; struct ts_event { @@ -201,6 +202,7 @@ struct fts_mode_info { int sample; int report_rate_mode; int edge_mode[2]; + int stowed; }; struct fts_ts_data { struct i2c_client *client; diff --git a/drivers/input/touchscreen/focaltech_touch_v3/focaltech_ts_mmi.c b/drivers/input/touchscreen/focaltech_touch_v3/focaltech_ts_mmi.c index 81208b517c27..8485409c1aad 100644 --- a/drivers/input/touchscreen/focaltech_touch_v3/focaltech_ts_mmi.c +++ b/drivers/input/touchscreen/focaltech_touch_v3/focaltech_ts_mmi.c @@ -71,6 +71,10 @@ static ssize_t fts_sample_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size); static ssize_t fts_sample_show(struct device *dev, struct device_attribute *attr, char *buf); +static ssize_t fts_stowed_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size); +static ssize_t fts_stowed_show(struct device *dev, + struct device_attribute *attr, char *buf); static DEVICE_ATTR(edge, (S_IRUGO | S_IWUSR | S_IWGRP), @@ -79,6 +83,8 @@ static DEVICE_ATTR(interpolation, (S_IRUGO | S_IWUSR | S_IWGRP), fts_interpolation_show, fts_interpolation_store); static DEVICE_ATTR(sample, (S_IRUGO | S_IWUSR | S_IWGRP), fts_sample_show, fts_sample_store); +static DEVICE_ATTR(stowed, (S_IWUSR | S_IWGRP | S_IRUGO), + fts_stowed_show, fts_stowed_store); #define ADD_ATTR(name) { \ if (idx < MAX_ATTRS_ENTRIES) { \ @@ -397,6 +403,67 @@ static ssize_t fts_sample_show(struct device *dev, return scnprintf(buf, PAGE_SIZE, "0x%02x", ts_data->set_mode.sample); } +static ssize_t fts_stowed_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int ret = 0; + unsigned long mode = 0; + struct fts_ts_data *ts_data; + + dev = MMI_DEV_TO_TS_DEV(dev); + GET_TS_DATA(dev); + + ret = kstrtoul(buf, 0, &mode); + if (ret < 0) { + FTS_INFO("Failed to convert value.\n"); + return -EINVAL; + } + + mutex_lock(&ts_data->mode_lock); + + ts_data->get_mode.stowed = mode; + if (ts_data->set_mode.stowed == mode) { + FTS_DEBUG("The value = %lu is same, so not to write", mode); + ret = size; + goto exit; + } + + if ((ts_data->power_disabled == false) && (ts_data->suspended == true)) { + if (mode) + ret = fts_write_reg(FTS_REG_POWER_MODE, FTS_REG_POWER_MODE_STANDBY); + else + ret = fts_write_reg(FTS_REG_POWER_MODE, FTS_REG_POWER_MODE_ACTIVE); + if (ret < 0) { + FTS_ERROR("failed to set report rate, mode = %lu", mode); + goto exit; + } + } else { + FTS_INFO("Skip stowed mode setting suspended:%d, power_disabled:%d.\n", ts_data->suspended, ts_data->power_disabled); + ret = size; + goto exit; + } + + ts_data->set_mode.stowed = mode; + FTS_INFO("Success to set stowed mode %lu\n", mode); + + ret = size; +exit: + mutex_unlock(&ts_data->mode_lock); + return ret; +} + +static ssize_t fts_stowed_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct fts_ts_data *ts_data; + + dev = MMI_DEV_TO_TS_DEV(dev); + GET_TS_DATA(dev); + + FTS_INFO("Stowed state = %d.\n", ts_data->set_mode.stowed); + return scnprintf(buf, PAGE_SIZE, "0x%02x", ts_data->set_mode.stowed); +} + static int fts_mmi_methods_get_vendor(struct device *dev, void *cdata) { return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_VENDOR_LEN, "%s", "focaltech"); @@ -808,6 +875,10 @@ exit: } } + if (pdata->stowed_mode_ctrl) { + ts_data->set_mode.stowed = 0; + } + mutex_unlock(&ts_data->mode_lock); FTS_FUNC_EXIT(); @@ -837,8 +908,11 @@ static int fts_mmi_pre_suspend(struct device *dev) static int fts_mmi_post_suspend(struct device *dev) { struct fts_ts_data *ts_data; + struct fts_ts_platform_data *pdata; + int ret = 0; GET_TS_DATA(dev); + pdata = ts_data->pdata; FTS_FUNC_ENTER(); @@ -852,6 +926,19 @@ static int fts_mmi_post_suspend(struct device *dev) #endif ts_data->suspended = true; + + if (pdata->stowed_mode_ctrl && ts_data->get_mode.stowed && (ts_data->power_disabled == false)) { + mutex_lock(&ts_data->mode_lock); + ret = fts_write_reg(FTS_REG_POWER_MODE, FTS_REG_POWER_MODE_STANDBY); + if (ret < 0) { + FTS_ERROR("Failed to set stowed mode %d", ts_data->get_mode.stowed); + } else { + ts_data->set_mode.stowed = ts_data->get_mode.stowed; + FTS_INFO("Enable stowed mode %d success.", ts_data->set_mode.stowed); + } + mutex_unlock(&ts_data->mode_lock); + } + FTS_FUNC_EXIT(); return 0; @@ -1004,6 +1091,9 @@ static int fts_mmi_extend_attribute_group(struct device *dev, struct attribute_g if (pdata->sample_ctrl) ADD_ATTR(sample); + if (pdata->stowed_mode_ctrl) + ADD_ATTR(stowed); + if (idx) { ext_attributes[idx] = NULL; *group = &ext_attr_group;