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 eeb9ccde3602..14706eb6fb15 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.c +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.c @@ -1100,6 +1100,11 @@ static int goodix_parse_dt(struct device_node *node, if (board_data->leather_mode_ctrl) ts_info("support goodix leather mode"); + board_data->interpolation_ctrl = of_property_read_bool(node, + "goodix,interpolation-ctrl"); + if (board_data->interpolation_ctrl) + ts_info("support goodix interpolation mode"); + return 0; } #endif 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 75715c07fbd8..b33358a196b7 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.h +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_core.h @@ -273,6 +273,7 @@ struct goodix_ts_board_data { bool sensitivity_ctrl; bool stylus_mode_ctrl; bool leather_mode_ctrl; + bool interpolation_ctrl; }; enum goodix_fw_update_mode { @@ -486,6 +487,7 @@ struct goodix_ts_core { int leather_mode; int stylus_mode; + int interpolation; struct clk *stylus_clk; /* touchscreen_mmi */ 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 69b4c2904530..f1570097f748 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.c +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.c @@ -29,6 +29,10 @@ } \ } +static ssize_t goodix_ts_interpolation_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size); +static ssize_t goodix_ts_interpolation_show(struct device *dev, + struct device_attribute *attr, char *buf); static ssize_t goodix_ts_stylus_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size); static ssize_t goodix_ts_stylus_mode_show(struct device *dev, @@ -36,6 +40,8 @@ static ssize_t goodix_ts_stylus_mode_show(struct device *dev, static ssize_t goodix_ts_sensitivity_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size); +static DEVICE_ATTR(interpolation, (S_IRUGO | S_IWUSR | S_IWGRP), + goodix_ts_interpolation_show, goodix_ts_interpolation_store); static DEVICE_ATTR(stylus_mode, (S_IRUGO | S_IWUSR | S_IWGRP), goodix_ts_stylus_mode_show, goodix_ts_stylus_mode_store); static DEVICE_ATTR(sensitivity, (S_IRUGO | S_IWUSR | S_IWGRP), @@ -66,6 +72,9 @@ static int goodix_ts_mmi_extend_attribute_group(struct device *dev, struct attri GET_GOODIX_DATA(dev); + if (core_data->board_data.interpolation_ctrl) + ADD_ATTR(interpolation); + if (core_data->board_data.stylus_mode_ctrl) ADD_ATTR(stylus_mode); @@ -138,7 +147,7 @@ static ssize_t goodix_ts_sensitivity_store(struct device *dev, dev = MMI_DEV_TO_TS_DEV(dev); GET_GOODIX_DATA(dev); - ret = kstrtoul(buf, 16, &mode); + ret = kstrtoul(buf, 0, &mode); if (ret < 0) { pr_info("Failed to convert value.\n"); return -EINVAL; @@ -237,6 +246,61 @@ static ssize_t goodix_ts_stylus_mode_show(struct device *dev, return scnprintf(buf, PAGE_SIZE, "0x%02x", core_data->stylus_mode); } +static ssize_t goodix_ts_interpolation_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; + const struct goodix_ts_hw_ops *hw_ops; + + dev = MMI_DEV_TO_TS_DEV(dev); + GET_GOODIX_DATA(dev); + hw_ops = core_data->hw_ops; + + ret = kstrtoul(buf, 0, &mode); + if (ret < 0) { + pr_info("Failed to convert value.\n"); + return -EINVAL; + } + + if (core_data->interpolation == mode) { + ts_debug("value is same,so not write.\n"); + return size; + } + + if (core_data->power_on == 0) { + core_data->interpolation = mode; + ts_debug("The touch is in sleep state, restore the value when resume\n"); + return 0; + } + + ret = goodix_ts_send_cmd(core_data, INTERPOLATION_SWITCH_CMD, 5, mode, 0x00); + if (ret < 0) { + ts_err("failed to send interpolation cmd"); + return -EINVAL; + } + + msleep(20); + core_data->interpolation = mode; + ts_info("Success to %s interpolation mode", mode ? "Enable" : "Disable"); + return size; +} + +static ssize_t goodix_ts_interpolation_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("interpolation = %d.\n", core_data->interpolation); + return scnprintf(buf, PAGE_SIZE, "0x%02x", core_data->interpolation); +} + static int goodix_ts_mmi_methods_get_vendor(struct device *dev, void *cdata) { return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_VENDOR_LEN, "%s", "goodix"); } @@ -517,8 +581,17 @@ static int goodix_ts_mmi_post_resume(struct device *dev) { if (core_data->board_data.leather_mode_ctrl && core_data->leather_mode) { ret = goodix_ts_send_cmd(core_data, LEATHER_MODE_SWITCH_CMD, 5, core_data->leather_mode, 0x00); - if (!ret) + if (!ret) { ts_info("Success to %s leather mode", core_data->leather_mode ? "Enable" : "Disable"); + msleep(20); + } + } + + if (core_data->board_data.interpolation_ctrl && core_data->interpolation) { + ret = goodix_ts_send_cmd(core_data, INTERPOLATION_SWITCH_CMD, 5, + core_data->interpolation, 0x00); + if (!ret) + ts_info("Success to %s interpolation mode", core_data->interpolation ? "Enable" : "Disable"); } 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 9bd8bc3351f0..0fd4e98a15d5 100644 --- a/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.h +++ b/drivers/input/touchscreen/goodix_berlin_mmi/goodix_ts_mmi.h @@ -34,5 +34,6 @@ static void inline goodix_ts_mmi_dev_unregister(struct platform_device *ts_devic #define EXIT_LEATHER_MODE 0x00 #define STYLUS_MODE_SWITCH_CMD 0xA4 +#define INTERPOLATION_SWITCH_CMD 0xC2 #endif