mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 15:11:48 -04:00
touchscreen_mmi: Control baseline update by FPS notifier
FOD sensor will depend on touch event to trigger fingerprint authentication. When device is waken up, and user put finger on FOD area just when touch IC is resuming, IC will update baseline and set current finger on screen as touch baseline. In this situation, no touch event will report. To fix this issue, touchscreen class will disable touch IC baseline update function by FPS working status. If FPS is working, delay baseline update to FPS stop working or get touch up event. Change-Id: I16b964c71bf1adc71832a8d25c74b7734dd88d20 Signed-off-by: haojl2 <haojl2@motorola.com> Reviewed-on: https://gerrit.mot.com/1551682 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Konstantin Makariev <kmakariev@motorola.com> Submit-Approved: Jira Key
This commit is contained in:
parent
31bac7f50d
commit
04f414b1fa
4 changed files with 131 additions and 4 deletions
|
|
@ -26,7 +26,12 @@ struct ts_mmi_sensor_platform_data {
|
|||
struct ts_mmi_dev *touch_cdev;
|
||||
};
|
||||
|
||||
struct ts_mmi_touch_events_data {
|
||||
struct ts_mmi_dev *touch_cdev;
|
||||
};
|
||||
|
||||
static struct ts_mmi_sensor_platform_data *sensor_pdata;
|
||||
static struct ts_mmi_touch_events_data *events_data;
|
||||
|
||||
static int ts_mmi_gesture_handler(struct gesture_event_data *gev)
|
||||
{
|
||||
|
|
@ -62,6 +67,9 @@ static int ts_mmi_gesture_handler(struct gesture_event_data *gev)
|
|||
|
||||
static int ts_mmi_touch_event_handler(struct touch_event_data *tev)
|
||||
{
|
||||
struct ts_mmi_dev *touch_cdev = events_data->touch_cdev;
|
||||
int ret = 0;
|
||||
|
||||
switch (tev->type) {
|
||||
case TS_COORDINATE_ACTION_PRESS:
|
||||
#if defined(CONFIG_TOUCHCLASS_MMI_DEBUG_INFO)
|
||||
|
|
@ -74,6 +82,13 @@ static int ts_mmi_touch_event_handler(struct touch_event_data *tev)
|
|||
#if defined(CONFIG_TOUCHCLASS_MMI_DEBUG_INFO)
|
||||
pr_info("%s: [R]Finger %d: UP", __func__, tev->id);
|
||||
#endif
|
||||
|
||||
if (touch_cdev->pdata.fps_detection) {
|
||||
if (touch_cdev->delay_baseline_update) {
|
||||
TRY_TO_CALL(update_baseline, TS_MMI_UPDATE_BASELINE_ON);
|
||||
touch_cdev->delay_baseline_update = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -147,9 +162,16 @@ int ts_mmi_gesture_init(struct ts_mmi_dev *touch_cdev)
|
|||
sensor_pdata = devm_kzalloc(&sensor_input_dev->dev,
|
||||
sizeof(struct ts_mmi_sensor_platform_data), GFP_KERNEL);
|
||||
if (!sensor_pdata) {
|
||||
dev_err(DEV_TS, "%s: Failed to allocate memory", __func__);
|
||||
goto free_sensor_input_dev;
|
||||
}
|
||||
events_data = devm_kzalloc(DEV_TS,
|
||||
sizeof(struct ts_mmi_touch_events_data), GFP_KERNEL);
|
||||
if (!events_data) {
|
||||
dev_err(DEV_TS, "%s: Failed to allocate memory", __func__);
|
||||
goto free_sensor_pdata;
|
||||
}
|
||||
events_data->touch_cdev = touch_cdev;
|
||||
|
||||
__set_bit(EV_KEY, sensor_input_dev->evbit);
|
||||
__set_bit(KEY_F1, sensor_input_dev->keybit);
|
||||
|
|
@ -166,7 +188,7 @@ int ts_mmi_gesture_init(struct ts_mmi_dev *touch_cdev)
|
|||
err = input_register_device(sensor_input_dev);
|
||||
if (err) {
|
||||
dev_err(DEV_TS, "%s: Unable to register device, err=%d", __func__, err);
|
||||
goto free_sensor_input_dev;
|
||||
goto free_touch_events_data;
|
||||
}
|
||||
|
||||
sensor_pdata->ps_cdev = sensors_touch_cdev;
|
||||
|
|
@ -187,10 +209,12 @@ int ts_mmi_gesture_init(struct ts_mmi_dev *touch_cdev)
|
|||
|
||||
unregister_sensor_input_device:
|
||||
input_unregister_device(sensor_input_dev);
|
||||
free_sensor_input_dev:
|
||||
input_free_device(sensor_input_dev);
|
||||
free_touch_events_data:
|
||||
devm_kfree(DEV_TS, events_data);
|
||||
free_sensor_pdata:
|
||||
devm_kfree(&sensor_input_dev->dev, sensor_pdata);
|
||||
free_sensor_input_dev:
|
||||
input_free_device(sensor_input_dev);
|
||||
exit:
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -200,6 +224,8 @@ int ts_mmi_gesture_remove(struct ts_mmi_dev *touch_cdev)
|
|||
sensors_classdev_unregister(&sensor_pdata->ps_cdev);
|
||||
input_unregister_device(sensor_pdata->input_sensor_dev);
|
||||
devm_kfree(&sensor_pdata->input_sensor_dev->dev, sensor_pdata);
|
||||
devm_kfree(DEV_TS, events_data);
|
||||
input_free_device(sensor_pdata->input_sensor_dev);
|
||||
sensor_pdata = NULL;
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/usb.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/touchscreen_mmi.h>
|
||||
#include <linux/fingerprint_mmi.h>
|
||||
|
||||
#if defined(CONFIG_DRM_DYNAMIC_REFRESH_RATE)
|
||||
extern struct blocking_notifier_head dsi_freq_head;
|
||||
|
|
@ -44,7 +45,8 @@ extern struct blocking_notifier_head dsi_freq_head;
|
|||
enum ts_mmi_work {
|
||||
TS_MMI_DO_RESUME,
|
||||
TS_MMI_DO_PS,
|
||||
TS_MMI_DO_REFRESH_RATE
|
||||
TS_MMI_DO_REFRESH_RATE,
|
||||
TS_MMI_DO_FPS,
|
||||
};
|
||||
|
||||
static int ts_mmi_panel_off(struct ts_mmi_dev *touch_cdev) {
|
||||
|
|
@ -182,6 +184,21 @@ static void ts_mmi_queued_resume(struct ts_mmi_dev *touch_cdev)
|
|||
|
||||
TRY_TO_CALL(pre_resume);
|
||||
|
||||
/* touch IC baseline update always done when IC resume.
|
||||
* So touchscreen class need let vendor driver know baseline update work need to be done
|
||||
* or not before vendor resume is called.
|
||||
*/
|
||||
if (touch_cdev->pdata.fps_detection) {
|
||||
if (touch_cdev->fps_state) {
|
||||
TRY_TO_CALL(update_baseline, TS_MMI_UPDATE_BASELINE_OFF);
|
||||
touch_cdev->delay_baseline_update = true;
|
||||
}
|
||||
if (!touch_cdev->fps_state) {
|
||||
TRY_TO_CALL(update_baseline, TS_MMI_UPDATE_BASELINE_ON);
|
||||
touch_cdev->delay_baseline_update = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (NEED_TO_SET_POWER) {
|
||||
/* power turn on in PANEL_EVENT_PRE_DISPLAY_ON.
|
||||
* IC need some time to boot up.
|
||||
|
|
@ -246,6 +263,17 @@ static void ts_mmi_worker_func(struct work_struct *w)
|
|||
case TS_MMI_DO_REFRESH_RATE:
|
||||
TRY_TO_CALL(refresh_rate, (int)touch_cdev->refresh_rate);
|
||||
break;
|
||||
case TS_MMI_DO_FPS:
|
||||
if (touch_cdev->fps_state) {/* on */
|
||||
TRY_TO_CALL(update_baseline, TS_MMI_UPDATE_BASELINE_OFF);
|
||||
touch_cdev->delay_baseline_update = true;
|
||||
} else { /* off */
|
||||
if (touch_cdev->delay_baseline_update) {
|
||||
TRY_TO_CALL(update_baseline, TS_MMI_UPDATE_BASELINE_ON);
|
||||
touch_cdev->delay_baseline_update = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dev_dbg(DEV_MMI, "%s: unknown command %d\n", __func__, cmd);
|
||||
}
|
||||
|
|
@ -324,6 +352,57 @@ static int ts_mmi_charger_cb(struct notifier_block *self,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ts_mmi_fps_cb(struct notifier_block *self,
|
||||
unsigned long event, void *p)
|
||||
{
|
||||
int fps_state = *(int *)p;
|
||||
struct ts_mmi_dev *touch_cdev = container_of(
|
||||
self, struct ts_mmi_dev, fps_notif);
|
||||
|
||||
if (touch_cdev && event == 0xBEEF && fps_state != touch_cdev->fps_state) {
|
||||
touch_cdev->fps_state = fps_state;
|
||||
dev_info(DEV_MMI, "FPS: state is %s\n", touch_cdev->fps_state ? "ON" : "OFF");
|
||||
if (is_touch_active) {
|
||||
kfifo_put(&touch_cdev->cmd_pipe, TS_MMI_DO_FPS);
|
||||
schedule_delayed_work(&touch_cdev->work, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ts_mmi_fps_notifier_register(struct ts_mmi_dev *touch_cdev, bool enable) {
|
||||
int (*register_link)(struct notifier_block *nb, unsigned long stype, bool report);
|
||||
int (*unregister_link)(struct notifier_block *nb, unsigned long stype);
|
||||
int ret;
|
||||
|
||||
if (enable) {
|
||||
register_link = symbol_get(FPS_register_notifier);
|
||||
if (register_link) {
|
||||
touch_cdev->fps_notif.notifier_call = ts_mmi_fps_cb;
|
||||
ret = register_link(&touch_cdev->fps_notif, 0xBEEF, false);
|
||||
symbol_put(FPS_register_notifier);
|
||||
if (ret < 0) {
|
||||
dev_err(DEV_TS,
|
||||
"Failed to register fps_notifier: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
touch_cdev->is_fps_registered = true;
|
||||
dev_info(DEV_TS, "Register fps_notifier OK\n");
|
||||
} else
|
||||
dev_err(DEV_TS, "no FPS_register_notifier exported.\n");
|
||||
} else if (touch_cdev->is_fps_registered) {
|
||||
unregister_link = symbol_get(FPS_unregister_notifier);
|
||||
if (unregister_link)
|
||||
unregister_link(&touch_cdev->fps_notif, 0xBEEF);
|
||||
else
|
||||
dev_err(DEV_TS, "no FPS_unregister_notifier exported.\n");
|
||||
touch_cdev->is_fps_registered = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ts_mmi_notifiers_register(struct ts_mmi_dev *touch_cdev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
|
@ -366,6 +445,13 @@ int ts_mmi_notifiers_register(struct ts_mmi_dev *touch_cdev)
|
|||
goto FREQ_NOTIF_REGISTER_FAILED;
|
||||
}
|
||||
|
||||
if (touch_cdev->pdata.fps_detection) {
|
||||
ret = ts_mmi_fps_notifier_register(touch_cdev, true);
|
||||
if (ret < 0)
|
||||
dev_err(DEV_TS,
|
||||
"Failed to register fps_notifier: %d\n", ret);
|
||||
}
|
||||
|
||||
dev_info(DEV_TS, "%s: Notifiers init OK.\n", __func__);
|
||||
return 0;
|
||||
|
||||
|
|
@ -386,6 +472,9 @@ void ts_mmi_notifiers_unregister(struct ts_mmi_dev *touch_cdev)
|
|||
return;
|
||||
}
|
||||
|
||||
if (touch_cdev->pdata.fps_detection)
|
||||
ts_mmi_fps_notifier_register(touch_cdev, false);
|
||||
|
||||
if (touch_cdev->pdata.update_refresh_rate)
|
||||
unregister_dynamic_refresh_rate_notifier(&touch_cdev->freq_nb);
|
||||
|
||||
|
|
|
|||
|
|
@ -113,6 +113,11 @@ int ts_mmi_parse_dt(struct ts_mmi_dev *touch_cdev,
|
|||
ppdata->hold_grip_ctrl = true;
|
||||
}
|
||||
|
||||
if (of_property_read_bool(of_node, "mmi,fps_detection")) {
|
||||
dev_info(DEV_TS, "%s: using fps detection\n", __func__);
|
||||
ppdata->fps_detection = true;
|
||||
}
|
||||
|
||||
chosen = of_find_node_by_name(NULL, "chosen");
|
||||
if (chosen) {
|
||||
struct device_node *child;
|
||||
|
|
|
|||
|
|
@ -229,6 +229,7 @@ enum ts_mmi_pm_mode {
|
|||
|
||||
struct ts_mmi_dev_pdata {
|
||||
bool power_off_suspend;
|
||||
bool fps_detection;
|
||||
bool usb_detection;
|
||||
bool update_refresh_rate;
|
||||
bool gestures_enabled;
|
||||
|
|
@ -286,6 +287,12 @@ struct ts_mmi_dev {
|
|||
struct work_struct ps_notify_work;
|
||||
struct notifier_block ps_notif;
|
||||
bool ps_is_present;
|
||||
|
||||
struct notifier_block fps_notif;
|
||||
bool is_fps_registered; /* FPS notif registration might be delayed */
|
||||
bool fps_state;
|
||||
bool delay_baseline_update;
|
||||
|
||||
/*
|
||||
* sys entey variable
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue