touchscreen_mmi: update RW sys entry.

For touchscreen class sys entries which support read and write.
Those entry value is set by user space and will be read by user space.
When IC is not active, read and write to touch IC may fail (power off or
interrupt closed). So, when write to those entries, just save value to
cache and restore when IC resume. Read those entries just return cached
value.

Change-Id: Ieee193597b68b2d87c6234116f2f085e5ab6aeac
Signed-off-by: haojl2 <haojl2@motorola.com>
Reviewed-on: https://gerrit.mot.com/1544046
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: <litong20@motorola.com>
Reviewed-by: Jianqi Yang <yangj@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
haojl2 2020-04-28 17:06:36 +08:00 • committed by Jialei Hao
commit 1044348204
3 changed files with 83 additions and 33 deletions

View file

@ -32,7 +32,7 @@
#define FMT_INTEGER "%d"
#define FMT_HEX_INTEGER "0x%02x"
#define TOUCH_MMI_SHOW(name, fmt) \
#define TOUCH_MMI_SHOW(name, chk_tp_status, fmt) \
static ssize_t name##_show(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ \
@ -42,14 +42,22 @@ static ssize_t name##_show(struct device *dev, \
dev_err(dev, "get_%s: invalid pointer\n", #name); \
return (ssize_t)0; \
} \
ret = touch_cdev->mdata->get_##name(DEV_TS, &touch_cdev->name); \
if (ret < 0) { \
dev_err(dev, "get_%s: return error %d\n", #name, ret); \
return (ssize_t)0; \
} \
return (ssize_t)scnprintf(buf, PAGE_SIZE, fmt, touch_cdev->name); \
mutex_lock(&touch_cdev->extif_mutex); \
if (!chk_tp_status || is_touch_active) { \
ret = touch_cdev->mdata->get_##name(DEV_TS, &touch_cdev->name); \
if (ret < 0) { \
dev_err(dev, "get_%s: return error %d\n", #name, ret); \
ret = 0; \
goto TOUCH_MMI_SHOW_OUT; \
} \
} else \
dev_dbg(dev, "get_%s: read from cache data.\n", #name); \
ret = scnprintf(buf, PAGE_SIZE, fmt, touch_cdev->name); \
TOUCH_MMI_SHOW_OUT: \
mutex_unlock(&touch_cdev->extif_mutex); \
return (ssize_t)ret; \
}
#define TOUCH_MMI_STORE(name, fmt) \
#define TOUCH_MMI_STORE(name, chk_tp_status, fmt) \
static ssize_t name##_store(struct device *dev, \
struct device_attribute *attr, const char *buf, size_t size) \
{ \
@ -65,21 +73,32 @@ static ssize_t name##_store(struct device *dev, \
dev_err(dev, "%s: invalid pointer\n", #name); \
return -EINVAL; \
} \
touch_cdev->mdata->name(DEV_TS, value); \
mutex_lock(&touch_cdev->extif_mutex); \
touch_cdev->name = value; \
if (!chk_tp_status || is_touch_active) { \
err = touch_cdev->mdata->name(DEV_TS, touch_cdev->name); \
if (err < 0) { \
dev_err(dev, "%s: return error %d\n", #name, err); \
goto TOUCH_MMI_STORE_OUT; \
} \
} else \
dev_dbg(dev, "%s: write to cache data.\n", #name); \
TOUCH_MMI_STORE_OUT: \
mutex_unlock(&touch_cdev->extif_mutex); \
return size; \
} \
#define TOUCH_MMI_GET_ATTR_RO(name, fmt) \
TOUCH_MMI_SHOW(name, fmt) \
TOUCH_MMI_SHOW(name, false, fmt) \
static DEVICE_ATTR(name, S_IRUGO, name##_show, NULL)
#define TOUCH_MMI_GET_ATTR_WO(name) \
TOUCH_MMI_STORE(name, fmt) \
TOUCH_MMI_STORE(name, false, fmt) \
static DEVICE_ATTR(name, (S_IWUSR | S_IWGRP), NULL, name##_store)
#define TOUCH_MMI_GET_ATTR_RW(name, fmt) \
TOUCH_MMI_SHOW(name, fmt) \
TOUCH_MMI_STORE(name, fmt) \
TOUCH_MMI_SHOW(name, true, fmt) \
TOUCH_MMI_STORE(name, true, fmt) \
static DEVICE_ATTR(name, (S_IWUSR | S_IWGRP | S_IRUGO), name##_show, name##_store)
static struct class *touchscreens_class;
@ -304,13 +323,22 @@ static ssize_t pill_region_show(struct device *dev,
dev_err(dev, "get_pill_region: invalid pointer\n");
return (ssize_t)0;
}
ret = touch_cdev->mdata->get_pill_region(DEV_TS, &touch_cdev->pill_region);
if (ret < 0) {
dev_err(dev, "get_pill_region: return error %d\n", ret);
return (ssize_t)0;
}
return scnprintf(buf, PAGE_SIZE, "0x%02x 0x%x 0x%x",
mutex_lock(&touch_cdev->extif_mutex);
if (is_touch_active) {
ret = touch_cdev->mdata->get_pill_region(DEV_TS, &touch_cdev->pill_region);
if (ret < 0) {
dev_err(dev, "get_pill_region: return error %d\n", ret);
ret = 0;
goto PILL_REGION_SHOW_OUT;
}
} else
dev_dbg(dev, "get_pill_region: read from cache data.\n");
ret = scnprintf(buf, PAGE_SIZE, "0x%02x 0x%x 0x%x",
touch_cdev->pill_region[0], touch_cdev->pill_region[1], touch_cdev->pill_region[2]);
PILL_REGION_SHOW_OUT:
mutex_unlock(&touch_cdev->extif_mutex);
return (ssize_t)ret;
}
static ssize_t pill_region_store(struct device *dev,
@ -331,9 +359,14 @@ static ssize_t pill_region_store(struct device *dev,
dev_err(dev, "pill_region: invalid pointer\n");
return -EINVAL;
}
mutex_lock(&touch_cdev->extif_mutex);
while (i--)
touch_cdev->pill_region[i] = args[i];
touch_cdev->mdata->pill_region(DEV_TS, touch_cdev->pill_region);
if (is_touch_active)
touch_cdev->mdata->pill_region(DEV_TS, touch_cdev->pill_region);
else
dev_dbg(dev, "pill_region: write to cache data.\n");
mutex_unlock(&touch_cdev->extif_mutex);
return size;
}
static DEVICE_ATTR(pill_region, (S_IWUSR | S_IWGRP | S_IRUGO), pill_region_show, pill_region_store);
@ -485,6 +518,7 @@ int ts_mmi_dev_register(struct device *parent,
dev_info(parent, "%s: new device\n", __func__);
DEV_TS = parent;
touch_cdev->mdata = mdata;
mutex_init(&touch_cdev->extif_mutex);
ret = ts_mmi_parse_dt(touch_cdev, DEV_TS->of_node);
if (ret < 0) {

View file

@ -172,6 +172,24 @@ static int ts_mmi_panel_cb(struct notifier_block *nb,
return 0;
}
static inline void ts_mmi_restore_settings(struct ts_mmi_dev *touch_cdev)
{
if (touch_cdev->pdata.usb_detection)
TRY_TO_CALL(charger_mode, (int)touch_cdev->ps_is_present);
if (touch_cdev->pdata.update_refresh_rate)
TRY_TO_CALL(refresh_rate, (int)touch_cdev->refresh_rate);
if (touch_cdev->pdata.suppression_ctrl)
TRY_TO_CALL(suppression, (int)touch_cdev->suppression);
if (touch_cdev->pdata.pill_region_ctrl)
TRY_TO_CALL(pill_region, (unsigned int *)touch_cdev->pill_region);
if (touch_cdev->pdata.hold_distance_ctrl)
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);
dev_dbg(DEV_MMI, "%s: done\n", __func__);
}
static void ts_mmi_queued_resume(struct ts_mmi_dev *touch_cdev)
{
bool wait4_boot_complete = true;
@ -209,20 +227,13 @@ static void ts_mmi_queued_resume(struct ts_mmi_dev *touch_cdev)
TRY_TO_CALL(post_resume);
if (touch_cdev->pdata.usb_detection)
TRY_TO_CALL(charger_mode, (int)touch_cdev->ps_is_present);
if (touch_cdev->pdata.update_refresh_rate)
TRY_TO_CALL(refresh_rate, (int)touch_cdev->refresh_rate);
if (touch_cdev->pdata.suppression_ctrl)
TRY_TO_CALL(suppression, (int)touch_cdev->suppression);
if (touch_cdev->pdata.pill_region_ctrl)
TRY_TO_CALL(pill_region, (unsigned int *)touch_cdev->pill_region);
if (touch_cdev->pdata.hold_distance_ctrl)
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);
/* Incase user space interface is R/W during restore cached value,
* hold extif mutex when restore those values.
*/
mutex_lock(&touch_cdev->extif_mutex);
ts_mmi_restore_settings(touch_cdev);
touch_cdev->pm_mode = TS_MMI_PM_ACTIVE;
mutex_unlock(&touch_cdev->extif_mutex);
dev_info(DEV_MMI, "%s: done\n", __func__);
}

View file

@ -175,6 +175,8 @@ struct ts_mmi_dev {
int forcereflash;
struct ts_mmi_dev_pdata pdata;
struct notifier_block panel_nb;
struct mutex extif_mutex;
atomic_t touch_stopped;
enum ts_mmi_pm_mode pm_mode;
@ -208,6 +210,9 @@ struct ts_mmi_dev {
int hold_distance;
int gs_distance;
int hold_grip;
int charger_mode;
int reset;
int pinctrl;
struct attribute_group *extern_group;
struct list_head node;
/*