input: touchscreen: goodix_berlin_driver: Implement gestures via xiaomi touch
Change-Id: I64ffe8fd3131bb7428b187c503908d73195e15a7
This commit is contained in:
parent
614b119f31
commit
fa989c6913
@ -342,8 +342,9 @@ int brl_gesture(struct goodix_ts_core *cd, int gesture_type)
|
||||
cmd.cmd = GOODIX_GESTURE_CMD_BA;
|
||||
else
|
||||
cmd.cmd = GOODIX_GESTURE_CMD;
|
||||
cmd.len = 5;
|
||||
cmd.data[0] = gesture_type;
|
||||
cmd.len = 6;
|
||||
cmd.data[0] = (gesture_type >> 0) & 0x01;
|
||||
cmd.data[1] = (gesture_type >> 1) & 0x01;
|
||||
if (cd->hw_ops->send_cmd(cd, &cmd))
|
||||
ts_err("failed send gesture cmd");
|
||||
|
||||
|
@ -1903,6 +1903,8 @@ static int goodix_ts_resume(struct goodix_ts_core *core_data)
|
||||
atomic_set(&core_data->suspended, 0);
|
||||
hw_ops->irq_enable(core_data, false);
|
||||
|
||||
cancel_delayed_work_sync(&core_data->gesture_work);
|
||||
|
||||
mutex_lock(&goodix_modules.mutex);
|
||||
if (!list_empty(&goodix_modules.head)) {
|
||||
list_for_each_entry_safe(ext_module, next,
|
||||
@ -1962,6 +1964,45 @@ static void goodix_resume_work(struct work_struct *work)
|
||||
goodix_ts_resume(core_data);
|
||||
}
|
||||
|
||||
static void goodix_set_gesture_work(struct work_struct *work)
|
||||
{
|
||||
struct delayed_work *dwork = to_delayed_work(work);
|
||||
struct goodix_ts_core *core_data = container_of(dwork, struct goodix_ts_core, gesture_work);
|
||||
struct goodix_ts_hw_ops *hw_ops = core_data->hw_ops;
|
||||
unsigned int target_gesture_type;
|
||||
int res;
|
||||
|
||||
if (!atomic_read(&core_data->suspended)) {
|
||||
ts_debug("touch is not suspended, skip re-wake");
|
||||
return;
|
||||
}
|
||||
|
||||
pm_stay_awake(core_data->bus->dev);
|
||||
|
||||
target_gesture_type = core_data->nonui_enabled ? 0 : core_data->gesture_type;
|
||||
|
||||
if (target_gesture_type == 0) {
|
||||
disable_irq_wake(core_data->irq);
|
||||
hw_ops->irq_enable(core_data, false);
|
||||
hw_ops->gesture(core_data, 0);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
hw_ops->reset(core_data, GOODIX_NORMAL_RESET_DELAY_MS);
|
||||
res = hw_ops->gesture(core_data, target_gesture_type);
|
||||
if (res) {
|
||||
ts_err("failed enter gesture mode");
|
||||
goto exit;
|
||||
} else {
|
||||
ts_err("enter gesture mode");
|
||||
}
|
||||
hw_ops->irq_enable(core_data, true);
|
||||
enable_irq_wake(core_data->irq);
|
||||
|
||||
exit:
|
||||
pm_relax(core_data->bus->dev);
|
||||
}
|
||||
|
||||
static int goodix_set_cur_value(int mode, int value)
|
||||
{
|
||||
ts_debug("mode: %d, value: %d", mode, value);
|
||||
@ -1969,11 +2010,34 @@ static int goodix_set_cur_value(int mode, int value)
|
||||
if (!ts_core || value < 0) return 0;
|
||||
|
||||
switch (mode) {
|
||||
case Touch_Doubletap_Mode:
|
||||
if (value)
|
||||
ts_core->gesture_type |= GESTURE_DOUBLE_TAP;
|
||||
else
|
||||
ts_core->gesture_type &= ~GESTURE_DOUBLE_TAP;
|
||||
break;
|
||||
case Touch_Singletap_Gesture:
|
||||
if (value)
|
||||
ts_core->gesture_type |= GESTURE_SINGLE_TAP;
|
||||
else
|
||||
ts_core->gesture_type &= ~GESTURE_SINGLE_TAP;
|
||||
break;
|
||||
case Touch_Fod_Longpress_Gesture:
|
||||
if (value)
|
||||
ts_core->gesture_type |= GESTURE_FOD_PRESS;
|
||||
else
|
||||
ts_core->gesture_type &= ~GESTURE_FOD_PRESS;
|
||||
break;
|
||||
case Touch_Nonui_Mode:
|
||||
ts_core->nonui_enabled = value != 0;
|
||||
break;
|
||||
default:
|
||||
ts_err("handler got mode %d with value %d, not implemented", mode, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
queue_delayed_work(ts_core->gesture_wq, &ts_core->gesture_work, msecs_to_jiffies(GOODIX_NORMAL_GESTURE_DELAY_MS));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1984,6 +2048,14 @@ static int goodix_get_mode_value(int mode, int value_type)
|
||||
if (!ts_core) return -1;
|
||||
|
||||
switch (mode) {
|
||||
case Touch_Doubletap_Mode:
|
||||
return (ts_core->gesture_type & GESTURE_DOUBLE_TAP) != 0;
|
||||
case Touch_Singletap_Gesture:
|
||||
return (ts_core->gesture_type & GESTURE_SINGLE_TAP) != 0;
|
||||
case Touch_Fod_Longpress_Gesture:
|
||||
return (ts_core->gesture_type & GESTURE_FOD_PRESS) != 0;
|
||||
case Touch_Nonui_Mode:
|
||||
return ts_core->nonui_enabled ? 2 : 0;
|
||||
default:
|
||||
ts_err("handler got mode %d with value_type %d, not implemented", mode, value_type);
|
||||
return -1;
|
||||
@ -2168,6 +2240,15 @@ int goodix_ts_stage2_init(struct goodix_ts_core *cd)
|
||||
INIT_WORK(&cd->resume_work, goodix_resume_work);
|
||||
INIT_WORK(&cd->suspend_work, goodix_suspend_work);
|
||||
|
||||
cd->gesture_wq =
|
||||
alloc_workqueue("gtp-gesture-queue",
|
||||
WQ_UNBOUND | WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1);
|
||||
if (!cd->gesture_wq) {
|
||||
ts_err("cannot create gesture work thread");
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
INIT_DELAYED_WORK(&cd->gesture_work, goodix_set_gesture_work);
|
||||
#if defined(CONFIG_DRM)
|
||||
if (active_panel)
|
||||
goodix_register_for_panel_events(cd->bus->dev->of_node, cd);
|
||||
|
@ -56,6 +56,7 @@
|
||||
#define GOODIX_GESTURE_DATA_LEN 16
|
||||
|
||||
#define GOODIX_NORMAL_RESET_DELAY_MS 100
|
||||
#define GOODIX_NORMAL_GESTURE_DELAY_MS 300
|
||||
#define GOODIX_HOLD_CPU_RESET_DELAY_MS 5
|
||||
|
||||
#define GOODIX_RETRY_3 3
|
||||
@ -552,6 +553,11 @@ struct goodix_ts_core {
|
||||
struct workqueue_struct *power_wq;
|
||||
struct work_struct resume_work;
|
||||
struct work_struct suspend_work;
|
||||
|
||||
struct workqueue_struct *gesture_wq;
|
||||
struct delayed_work gesture_work;
|
||||
|
||||
bool nonui_enabled;
|
||||
};
|
||||
|
||||
/* external module structures */
|
||||
|
@ -236,10 +236,11 @@ static int gsx_gesture_ist(struct goodix_ts_core *cd,
|
||||
{
|
||||
struct goodix_ts_hw_ops *hw_ops = cd->hw_ops;
|
||||
struct goodix_ts_event gs_event = {0};
|
||||
int fodx, fody, overlay_area;
|
||||
int ret;
|
||||
|
||||
if (atomic_read(&cd->suspended) == 0 || cd->gesture_type == 0)
|
||||
ts_debug("gsx_gesture_ist called, gesture type is %d, nonui enabled is %d", cd->gesture_type, cd->nonui_enabled);
|
||||
|
||||
if (atomic_read(&cd->suspended) == 0 || cd->gesture_type == 0 || cd->nonui_enabled)
|
||||
return EVT_CONTINUE;
|
||||
|
||||
ret = hw_ops->event_handler(cd, &gs_event);
|
||||
@ -258,12 +259,7 @@ static int gsx_gesture_ist(struct goodix_ts_core *cd,
|
||||
case GOODIX_GESTURE_SINGLE_TAP:
|
||||
if (cd->gesture_type & GESTURE_SINGLE_TAP) {
|
||||
ts_info("get SINGLE-TAP gesture");
|
||||
input_report_key(cd->input_dev, KEY_WAKEUP, 1);
|
||||
// input_report_key(cd->input_dev, KEY_GOTO, 1);
|
||||
input_sync(cd->input_dev);
|
||||
input_report_key(cd->input_dev, KEY_WAKEUP, 0);
|
||||
// input_report_key(cd->input_dev, KEY_GOTO, 0);
|
||||
input_sync(cd->input_dev);
|
||||
notify_gesture_single_tap();
|
||||
} else {
|
||||
ts_debug("not enable SINGLE-TAP");
|
||||
}
|
||||
@ -271,10 +267,7 @@ static int gsx_gesture_ist(struct goodix_ts_core *cd,
|
||||
case GOODIX_GESTURE_DOUBLE_TAP:
|
||||
if (cd->gesture_type & GESTURE_DOUBLE_TAP) {
|
||||
ts_info("get DOUBLE-TAP gesture");
|
||||
input_report_key(cd->input_dev, KEY_WAKEUP, 1);
|
||||
input_sync(cd->input_dev);
|
||||
input_report_key(cd->input_dev, KEY_WAKEUP, 0);
|
||||
input_sync(cd->input_dev);
|
||||
notify_gesture_double_tap();
|
||||
} else {
|
||||
ts_debug("not enable DOUBLE-TAP");
|
||||
}
|
||||
@ -282,17 +275,7 @@ static int gsx_gesture_ist(struct goodix_ts_core *cd,
|
||||
case GOODIX_GESTURE_FOD_DOWN:
|
||||
if (cd->gesture_type & GESTURE_FOD_PRESS) {
|
||||
ts_info("get FOD-DOWN gesture");
|
||||
fodx = le16_to_cpup((__le16 *)gs_event.gesture_data);
|
||||
fody = le16_to_cpup((__le16 *)(gs_event.gesture_data + 2));
|
||||
overlay_area = gs_event.gesture_data[4];
|
||||
ts_debug("fodx:%d fody:%d overlay_area:%d", fodx, fody, overlay_area);
|
||||
input_report_key(cd->input_dev, BTN_TOUCH, 1);
|
||||
input_mt_slot(cd->input_dev, 0);
|
||||
input_mt_report_slot_state(cd->input_dev, MT_TOOL_FINGER, 1);
|
||||
input_report_abs(cd->input_dev, ABS_MT_POSITION_X, fodx);
|
||||
input_report_abs(cd->input_dev, ABS_MT_POSITION_Y, fody);
|
||||
input_report_abs(cd->input_dev, ABS_MT_WIDTH_MAJOR, overlay_area);
|
||||
input_sync(cd->input_dev);
|
||||
update_fod_press_status(1);
|
||||
} else {
|
||||
ts_debug("not enable FOD-DOWN");
|
||||
}
|
||||
@ -300,14 +283,7 @@ static int gsx_gesture_ist(struct goodix_ts_core *cd,
|
||||
case GOODIX_GESTURE_FOD_UP:
|
||||
if (cd->gesture_type & GESTURE_FOD_PRESS) {
|
||||
ts_info("get FOD-UP gesture");
|
||||
fodx = le16_to_cpup((__le16 *)gs_event.gesture_data);
|
||||
fody = le16_to_cpup((__le16 *)(gs_event.gesture_data + 2));
|
||||
overlay_area = gs_event.gesture_data[4];
|
||||
input_report_key(cd->input_dev, BTN_TOUCH, 0);
|
||||
input_mt_slot(cd->input_dev, 0);
|
||||
input_mt_report_slot_state(cd->input_dev,
|
||||
MT_TOOL_FINGER, 0);
|
||||
input_sync(cd->input_dev);
|
||||
update_fod_press_status(0);
|
||||
} else {
|
||||
ts_debug("not enable FOD-UP");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user