touchscreen_mmi: clip area support

This introduces a new class method to suppress touch events sourced
outside or within specified clip area. To enable suppressing touch
events reported outside specified clip area, add the following DT
property:

mmi,clip-area = <xUL yUL xBR yBR>;

Suppressing touch events from within requires DT property:

mmi,clip-inversion;

Class driver's method will send forced lift event when an active
touch moves outside/within clip area and indicate this to the vendor
driver by setting type to TS_COORDINATE_ACTION_FORCE_LIFT in
touch_event_data structure.

Change-Id: I327af4441e179e381be97cb8083698d76882caa8
Signed-off-by: Konstantin Makariev <hcv867@motorola.com>
Reviewed-on: https://gerrit.mot.com/2641660
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: <zhuwg1@motorola.com>
Reviewed-by: Jun Weng <wengjun1@motorola.com>
Reviewed-by: Qing Chang <qing@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
Konstantin Makariev authored and Konstantin Makariev committed 2023-06-16 13:40:10 -05:00
1 parent c7aa054681
commit 4580159511
3 files changed
+53 -2

No files matched your search

@@ -809,6 +809,29 @@ static int ts_mmi_default_pinctrl(struct device *parent, int on)
return 0;
}
static int ts_mmi_clip_event_handler(struct device *parent,
struct touch_event_data *tev, struct input_dev *input_dev)
{
struct ts_mmi_dev *touch_cdev = ts_mmi_dev_to_cdev(parent);
bool inside;
inside = (tev->x >= touch_cdev->clip.xUL) && (tev->x <= touch_cdev->clip.xBR) &&
(tev->y >= touch_cdev->clip.yUL) && (tev->y <= touch_cdev->clip.yBR);
if (inside == touch_cdev->clip.inversion) {
if (tev->type == TS_COORDINATE_ACTION_MOVE) {
/* cancel active touch when it falls off the clip area */
input_mt_slot(input_dev, tev->id);
input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, false);
/* indicate cancelled touch to vendor driver */
tev->type = TS_COORDINATE_ACTION_FORCE_LIFT;
}
tev->skip_report = true;
}
return 0;
}
/**
* ts_mmi_dev_register - register a new object of ts_mmi_dev class.
* @parent: The device to register.
@@ -955,6 +978,11 @@ int ts_mmi_dev_register(struct device *parent,
}
}
if (touch_cdev->pdata.clip_area_ctrl) {
/* export report touch event function to vendor */
touch_cdev->mdata->exports.clip_touch_event = ts_mmi_clip_event_handler;
}
dev_info(DEV_TS, "Registered touchscreen device: %s.\n", class_fname);
return 0;
@@ -47,7 +47,7 @@ int ts_mmi_parse_dt(struct ts_mmi_dev *touch_cdev,
{
struct device_node *chosen;
struct ts_mmi_dev_pdata *ppdata = &touch_cdev->pdata;
u32 coords[2];
u32 coords[4];
dev_info(DEV_TS, "%s: Start parse touchscreen mmi device tree.\n", __func__);
if (!of_property_read_string(of_node, "mmi,class-entry-name", &ppdata->class_entry_name))
@@ -172,6 +172,20 @@ int ts_mmi_parse_dt(struct ts_mmi_dev *touch_cdev,
ppdata->support_liquid_detection = true;
}
if (!of_property_read_u32_array(of_node, "mmi,clip-area", coords, 4)) {
ppdata->clip_area_ctrl = true;
touch_cdev->clip.xUL = coords[0];
touch_cdev->clip.yUL = coords[1];
touch_cdev->clip.xBR = coords[2];
touch_cdev->clip.yBR = coords[3];
if (of_property_read_bool(of_node, "mmi,clip-inversion"))
touch_cdev->clip.inversion = true;
dev_info(DEV_TS, "%s: clip %sarea: (%u,%u) (%u,%u)\n", __func__,
touch_cdev->clip.inversion ? "IN " : "OUT ",
touch_cdev->clip.xUL, touch_cdev->clip.yUL,
touch_cdev->clip.xBR, touch_cdev->clip.yBR);
}
chosen = of_find_node_by_name(NULL, "chosen");
if (chosen) {
struct device_node *child;
+10 -1
View File
@@ -246,7 +246,8 @@ enum touch_event_mode {
TS_COORDINATE_ACTION_NONE = 0,
TS_COORDINATE_ACTION_PRESS,
TS_COORDINATE_ACTION_RELEASE,
TS_COORDINATE_ACTION_MOVE
TS_COORDINATE_ACTION_MOVE,
TS_COORDINATE_ACTION_FORCE_LIFT
};
enum TS_FW_UPGRADE_MODE {
@@ -270,6 +271,11 @@ struct gesture_event_data {
};
};
struct touch_clip_area {
unsigned xUL, yUL, xBR, yBR;
bool inversion; /* clip inside (when true) or outside otherwise */
};
/**
* struct touchscreen_mmi_class_methods - export class methods to vendor
*
@@ -282,6 +288,7 @@ struct ts_mmi_class_methods {
int (*get_class_fname)(struct device *dev , const char **fname);
int (*get_supplier)(struct device *dev , const char **sname);
int (*report_touch_event)(struct touch_event_data *tev, struct input_dev *input_dev);
int (*clip_touch_event)(struct device *dev, struct touch_event_data *tev, struct input_dev *input_dev);
int (*report_liquid_detection_status)(struct device *parent, int status);
struct kobject *kobj_notify;
};
@@ -434,6 +441,7 @@ struct ts_mmi_dev_pdata {
bool poison_slot_ctrl;
bool active_region_ctrl;
bool support_liquid_detection;
bool clip_area_ctrl;
int max_x;
int max_y;
int fod_x;
@@ -540,6 +548,7 @@ struct ts_mmi_dev {
int update_baseline;
struct attribute_group *extern_group;
struct list_head node;
struct touch_clip_area clip;
/*
* vendor provided
*/