From 327cd14766947ac85f03c45e53929dd4988dd7a8 Mon Sep 17 00:00:00 2001 From: Fei Mao Date: Wed, 1 Jul 2020 11:21:34 +0800 Subject: [PATCH] input: touchscreen: focaltech_touch: support dynamic report rate Add a new sys node to support runtime dynamic report rate. Change-Id: Ifa7f4290b648f79cfeec80ae421af4c7c7a36aaf Signed-off-by: Fei Mao --- .../focaltech_touch/focaltech_common.h | 1 + .../focaltech_touch/focaltech_core.c | 8 +- .../focaltech_touch/focaltech_core.h | 1 + .../focaltech_touch/focaltech_ex_mode.c | 97 ++++++++++++++----- 4 files changed, 79 insertions(+), 28 deletions(-) diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_common.h b/drivers/input/touchscreen/focaltech_touch/focaltech_common.h index 67415c4d9f3c..2065760487b8 100644 --- a/drivers/input/touchscreen/focaltech_touch/focaltech_common.h +++ b/drivers/input/touchscreen/focaltech_touch/focaltech_common.h @@ -88,6 +88,7 @@ #define FTS_REG_IDE_PARA_STATUS 0xB6 #define FTS_REG_GLOVE_MODE_EN 0xC0 #define FTS_REG_COVER_MODE_EN 0xC1 +#define FTS_REG_REPORT_RATE 0x88 #define FTS_REG_CHARGER_MODE_EN 0x8B #define FTS_REG_GESTURE_EN 0xD0 #define FTS_REG_GESTURE_OUTPUT_ADDRESS 0xD3 diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_core.c b/drivers/input/touchscreen/focaltech_touch/focaltech_core.c index 362bd7273e6f..3ca97d949b52 100644 --- a/drivers/input/touchscreen/focaltech_touch/focaltech_core.c +++ b/drivers/input/touchscreen/focaltech_touch/focaltech_core.c @@ -1271,11 +1271,11 @@ static int fb_notifier_callback(struct notifier_block *self, } blank = evdata->data; - FTS_INFO("FB event:%lu,blank:%d", event, *blank); + FTS_DEBUG("FB event:%lu,blank:%d", event, *blank); switch (*blank) { case DRM_PANEL_BLANK_UNBLANK: if (event == DRM_PANEL_EARLY_EVENT_BLANK) { - FTS_INFO("resume: event = %lu, not care\n", event); + FTS_DEBUG("resume: event = %lu, not care\n", event); } else if (event == DRM_PANEL_EVENT_BLANK) { queue_work(fts_data->ts_workqueue, &fts_data->resume_work); } @@ -1286,12 +1286,12 @@ static int fb_notifier_callback(struct notifier_block *self, cancel_work_sync(&fts_data->resume_work); fts_ts_suspend(ts_data->dev); } else if (event == DRM_PANEL_EVENT_BLANK) { - FTS_INFO("suspend: event = %lu, not care\n", event); + FTS_DEBUG("suspend: event = %lu, not care\n", event); } break; default: - FTS_INFO("FB BLANK(%d) do not need process\n", *blank); + FTS_DEBUG("FB BLANK(%d) do not need process\n", *blank); break; } diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_core.h b/drivers/input/touchscreen/focaltech_touch/focaltech_core.h index 7603a64b9d02..cb5e78f688bc 100644 --- a/drivers/input/touchscreen/focaltech_touch/focaltech_core.h +++ b/drivers/input/touchscreen/focaltech_touch/focaltech_core.h @@ -166,6 +166,7 @@ struct fts_ts_data { bool cover_mode; bool charger_mode; bool gesture_mode; /* gesture enable or disable, default: disable */ + int report_rate; /* multi-touch */ struct ts_event *events; u8 *bus_tx_buf; diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_ex_mode.c b/drivers/input/touchscreen/focaltech_touch/focaltech_ex_mode.c index 4727744b6b59..03cec68d1aa9 100644 --- a/drivers/input/touchscreen/focaltech_touch/focaltech_ex_mode.c +++ b/drivers/input/touchscreen/focaltech_touch/focaltech_ex_mode.c @@ -45,6 +45,7 @@ enum _ex_mode { MODE_GLOVE = 0, MODE_COVER, MODE_CHARGER, + REPORT_RATE, }; /***************************************************************************** @@ -61,33 +62,30 @@ enum _ex_mode { static int fts_ex_mode_switch(enum _ex_mode mode, u8 value) { int ret = 0; - u8 m_val = 0; - - if (value) - m_val = 0x01; - else - m_val = 0x00; switch (mode) { case MODE_GLOVE: - ret = fts_write_reg(FTS_REG_GLOVE_MODE_EN, m_val); - if (ret < 0) { - FTS_ERROR("MODE_GLOVE switch to %d fail", m_val); - } + ret = fts_write_reg(FTS_REG_GLOVE_MODE_EN, value > 0 ? 1 : 0); + if (ret < 0) + FTS_ERROR("MODE_GLOVE switch to %d fail", value); break; case MODE_COVER: - ret = fts_write_reg(FTS_REG_COVER_MODE_EN, m_val); - if (ret < 0) { - FTS_ERROR("MODE_COVER switch to %d fail", m_val); - } + ret = fts_write_reg(FTS_REG_COVER_MODE_EN, value > 0 ? 1 : 0); + if (ret < 0) + FTS_ERROR("MODE_COVER switch to %d fail", value); break; case MODE_CHARGER: - ret = fts_write_reg(FTS_REG_CHARGER_MODE_EN, m_val); - if (ret < 0) { - FTS_ERROR("MODE_CHARGER switch to %d fail", m_val); - } + ret = fts_write_reg(FTS_REG_CHARGER_MODE_EN, value > 0 ? 1 : 0); + if (ret < 0) + FTS_ERROR("MODE_CHARGER switch to %d fail", value); + break; + + case REPORT_RATE: + ret = fts_write_reg(FTS_REG_REPORT_RATE, value); + if (ret < 0) + FTS_ERROR("REPORT_RATE switch to %d fail", value); break; default: @@ -109,9 +107,10 @@ static ssize_t fts_glove_mode_show( mutex_lock(&input_dev->mutex); fts_read_reg(FTS_REG_GLOVE_MODE_EN, &val); - count = snprintf(buf + count, PAGE_SIZE, "Glove Mode:%s\n", + count = scnprintf(buf + count, PAGE_SIZE, "Glove Mode:%s\n", ts_data->glove_mode ? "On" : "Off"); - count += snprintf(buf + count, PAGE_SIZE, "Glove Reg(0xC0):%d\n", val); + count += scnprintf(buf + count, PAGE_SIZE - count, + "Glove Reg(0xC0):%d\n", val); mutex_unlock(&input_dev->mutex); return count; @@ -157,9 +156,10 @@ static ssize_t fts_cover_mode_show( mutex_lock(&input_dev->mutex); fts_read_reg(FTS_REG_COVER_MODE_EN, &val); - count = snprintf(buf + count, PAGE_SIZE, "Cover Mode:%s\n", + count = scnprintf(buf + count, PAGE_SIZE, "Cover Mode:%s\n", ts_data->cover_mode ? "On" : "Off"); - count += snprintf(buf + count, PAGE_SIZE, "Cover Reg(0xC1):%d\n", val); + count += scnprintf(buf + count, PAGE_SIZE - count, + "Cover Reg(0xC1):%d\n", val); mutex_unlock(&input_dev->mutex); return count; @@ -204,9 +204,10 @@ static ssize_t fts_charger_mode_show( mutex_lock(&input_dev->mutex); fts_read_reg(FTS_REG_CHARGER_MODE_EN, &val); - count = snprintf(buf + count, PAGE_SIZE, "Charger Mode:%s\n", + count = scnprintf(buf + count, PAGE_SIZE, "Charger Mode:%s\n", ts_data->charger_mode ? "On" : "Off"); - count += snprintf(buf + count, PAGE_SIZE, "Charger Reg(0x8B):%d\n", val); + count += scnprintf(buf + count, PAGE_SIZE - count, + "Charger Reg(0x8B):%d\n", val); mutex_unlock(&input_dev->mutex); return count; @@ -241,6 +242,47 @@ static ssize_t fts_charger_mode_store( return count; } +static ssize_t fts_report_rate_show( + struct device *dev, struct device_attribute *attr, char *buf) +{ + int count = 0; + u8 val = 0; + struct fts_ts_data *ts_data = fts_data; + struct input_dev *input_dev = ts_data->input_dev; + + mutex_lock(&input_dev->mutex); + fts_read_reg(FTS_REG_REPORT_RATE, &val); + count = scnprintf(buf + count, PAGE_SIZE, + "Report Rate:%d\n", ts_data->report_rate); + count += scnprintf(buf + count, PAGE_SIZE - count, + "Report Rate Reg(0x88):%d\n", val); + mutex_unlock(&input_dev->mutex); + + return count; +} + +static ssize_t fts_report_rate_store( + struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int ret = 0; + struct fts_ts_data *ts_data = fts_data; + int rate; + + ret = kstrtoint(buf, 16, &rate); + if (ret) + return ret; + + if (rate != ts_data->report_rate) { + ret = fts_ex_mode_switch(REPORT_RATE, (u8)rate); + if (ret >= 0) + ts_data->report_rate = rate; + } + + FTS_DEBUG("report rate:%d", ts_data->report_rate); + return count; +} + /* read and write charger mode * read example: cat fts_glove_mode ---read glove mode @@ -255,10 +297,13 @@ static DEVICE_ATTR(fts_cover_mode, S_IRUGO | S_IWUSR, static DEVICE_ATTR(fts_charger_mode, S_IRUGO | S_IWUSR, fts_charger_mode_show, fts_charger_mode_store); +static DEVICE_ATTR_RW(fts_report_rate); + static struct attribute *fts_touch_mode_attrs[] = { &dev_attr_fts_glove_mode.attr, &dev_attr_fts_cover_mode.attr, &dev_attr_fts_charger_mode.attr, + &dev_attr_fts_report_rate.attr, NULL, }; @@ -280,6 +325,9 @@ int fts_ex_mode_recovery(struct fts_ts_data *ts_data) fts_ex_mode_switch(MODE_CHARGER, ENABLE); } + if (ts_data->report_rate > 0) + fts_ex_mode_switch(REPORT_RATE, ts_data->report_rate); + return 0; } @@ -290,6 +338,7 @@ int fts_ex_mode_init(struct fts_ts_data *ts_data) ts_data->glove_mode = DISABLE; ts_data->cover_mode = DISABLE; ts_data->charger_mode = DISABLE; + ts_data->report_rate = 0; ret = sysfs_create_group(&ts_data->dev->kobj, &fts_touch_mode_group); if (ret < 0) {