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;