diff --git a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_class.c b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_class.c index b58a789e16d2..b6390bb9ac33 100644 --- a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_class.c +++ b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_class.c @@ -367,7 +367,6 @@ static const struct attribute_group sysfs_class_group = { * pill_region input value is much different between others sys entry * override default functions */ - static ssize_t pill_region_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -428,11 +427,89 @@ static ssize_t pill_region_store(struct device *dev, } static DEVICE_ATTR(pill_region, (S_IWUSR | S_IWGRP | S_IRUGO), pill_region_show, pill_region_store); +/* + * active_region input requires 4 parameters + */ +static ssize_t active_region_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ts_mmi_dev *touch_cdev = dev_get_drvdata(dev); + int ret = 0; + + if (!touch_cdev) { + dev_err(dev, "get_active_region: invalid pointer\n"); + return (ssize_t)0; + } + mutex_lock(&touch_cdev->extif_mutex); + if (is_touch_active) { + TRY_TO_GET(active_region, &touch_cdev->active_region); + if (ret < 0) { + dev_err(dev, "get_active_region: return error %d\n", ret); + ret = 0; + goto ACTIVE_REGION_SHOW_OUT; + } + } else + dev_dbg(dev, "get_active_region: read from cache data.\n"); + + ret = scnprintf(buf, PAGE_SIZE, "%u %u %u %u", + touch_cdev->active_region[0], touch_cdev->active_region[1], + touch_cdev->active_region[2], touch_cdev->active_region[3]); +ACTIVE_REGION_SHOW_OUT: + mutex_unlock(&touch_cdev->extif_mutex); + + return (ssize_t)ret; + +} +static ssize_t active_region_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct ts_mmi_dev *touch_cdev = dev_get_drvdata(dev); + unsigned int args[TS_MMI_ACTIVE_REGION_REQ_ARGS_NUM] = {0}; + int ret = 0; + int i = TS_MMI_ACTIVE_REGION_REQ_ARGS_NUM; + + ret = sscanf(buf, "%u %u %u %u", &args[0], &args[1], &args[2], &args[3]); + if (ret < TS_MMI_ACTIVE_REGION_REQ_ARGS_NUM) { + dev_err(dev, "active_region: Failed to convert value\n"); + return -EINVAL; + } + + if (!touch_cdev) { + dev_err(dev, "active_region: invalid pointer\n"); + return -EINVAL; + } + mutex_lock(&touch_cdev->extif_mutex); + mutex_lock(&touch_cdev->method_mutex); + while (i--) + touch_cdev->active_region[i] = args[i]; + if (is_touch_active) + _TRY_TO_CALL(active_region, touch_cdev->active_region); + else + dev_dbg(dev, "active_region: write to cache data.\n"); + mutex_unlock(&touch_cdev->method_mutex); + mutex_unlock(&touch_cdev->extif_mutex); + + return size; +} +static DEVICE_ATTR(active_region, (S_IWUSR | S_IWGRP | S_IRUGO), active_region_show, active_region_store); + static int ts_mmi_sysfs_create_edge_entries(struct ts_mmi_dev *touch_cdev, bool create) { int ret = 0; if (create) { /*initialize value*/ + if (touch_cdev->pdata.active_region_ctrl) { + TRY_TO_GET(active_region, &touch_cdev->active_region); + if (ret < 0) + dev_err(DEV_TS, "%s: failed to read active_region info (%d)\n", + __func__, ret); + ret = sysfs_create_file(&DEV_MMI->kobj, &dev_attr_active_region.attr); + if (ret < 0) { + dev_err(DEV_TS, "%s: failed to create active_region entry (%d)\n", + __func__, ret); + goto CREATE_SUPPRESSION_FAILED; + } + } if (touch_cdev->pdata.suppression_ctrl) { TRY_TO_GET(suppression, &touch_cdev->suppression); if (ret < 0) diff --git a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c index f7cb7e7357b2..6bd5732b8230 100644 --- a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c +++ b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_notif.c @@ -234,6 +234,8 @@ static inline void ts_mmi_restore_settings(struct ts_mmi_dev *touch_cdev) TRY_TO_CALL(hold_distance, (int)touch_cdev->hold_distance); if (touch_cdev->pdata.gs_distance_ctrl) TRY_TO_CALL(gs_distance, (int)touch_cdev->gs_distance); + if (touch_cdev->pdata.active_region_ctrl) + TRY_TO_CALL(active_region, (unsigned int *)touch_cdev->active_region); dev_dbg(DEV_MMI, "%s: done\n", __func__); } diff --git a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_panel.c b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_panel.c index 439872e74d46..55cb4be254bb 100644 --- a/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_panel.c +++ b/drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_panel.c @@ -110,6 +110,11 @@ int ts_mmi_parse_dt(struct ts_mmi_dev *touch_cdev, ppdata->pill_region_ctrl = true; } + if (of_property_read_bool(of_node, "mmi,active-region-control")) { + dev_info(DEV_TS, "%s: using active region\n", __func__); + ppdata->active_region_ctrl = true; + } + if (of_property_read_bool(of_node, "mmi,hold-distance-control")) { dev_info(DEV_TS, "%s: using hold distance\n", __func__); ppdata->hold_distance_ctrl = true; diff --git a/include/linux/touchscreen_mmi.h b/include/linux/touchscreen_mmi.h index e193a0c7063c..505c3fa1dc91 100644 --- a/include/linux/touchscreen_mmi.h +++ b/include/linux/touchscreen_mmi.h @@ -238,6 +238,7 @@ static inline unsigned long long timediff_ms( #define TS_MMI_MAX_CLASS_NAME_LEN 16 #define TS_MMI_MAX_PANEL_LEN 16 #define TS_MMI_PILL_REGION_REQ_ARGS_NUM 3 +#define TS_MMI_ACTIVE_REGION_REQ_ARGS_NUM 4 #define TS_MMI_FW_PARAM_PATH "/data/vendor/param/touch/" enum touch_event_mode { @@ -352,6 +353,7 @@ enum ts_mmi_panel_event { int (*get_poison_timeout)(struct device *dev, void *idata); int (*get_poison_distance)(struct device *dev, void *idata); int (*get_poison_trigger_distance)(struct device *dev, void *idata); + int (*get_active_region)(struct device *dev, void *uiadata); /* SET methods */ int (*reset)(struct device *dev, int type); int (*drv_irq)(struct device *dev, int state); @@ -371,6 +373,7 @@ enum ts_mmi_panel_event { int (*poison_trigger_distance)(struct device *dev, int dis); int (*update_baseline)(struct device *dev, int enable); int (*update_fod_mode)(struct device *dev, int enable); + int (*active_region)(struct device *dev, int *region_array); /* Firmware */ int (*firmware_update)(struct device *dev, char *fwname); int (*firmware_erase)(struct device *dev); @@ -410,6 +413,7 @@ struct ts_mmi_dev_pdata { bool gs_distance_ctrl; bool hold_grip_ctrl; bool poison_slot_ctrl; + bool active_region_ctrl; int max_x; int max_y; int fod_x; @@ -493,6 +497,7 @@ struct ts_mmi_dev { int flashprog; int suppression; unsigned int pill_region[TS_MMI_PILL_REGION_REQ_ARGS_NUM]; + unsigned int active_region[TS_MMI_ACTIVE_REGION_REQ_ARGS_NUM]; int hold_distance; int gs_distance; int hold_grip;