Skip to content
This repository has been archived by the owner on Dec 28, 2020. It is now read-only.

Commit

Permalink
s3320: Add kernel wake gesture support for custom ROMs
Browse files Browse the repository at this point in the history
Unfortunately, there's no ideal way to support native wake gestures on stock and
custom ROMs simultaneously. I'm willing to make every effort (within reason) to
maintain universal compatibility provided it doesn't impact functionality on
OxygenOS. In this case, the best I can do is implement a kernel-based wake gesture
alternative that can be controlled via sysfs for use on custom ROMs.

[@0ctobot: Squash flar2/OnePlus6@61fd668 with flar2/OnePlus6@490a5a9 and flar2/OnePlus6@2673041]
Signed-off-by: Adam W. Willis <return.of.octobot@gmail.com>
  • Loading branch information
flar2 authored and 0ctobot committed Mar 18, 2019
1 parent d89cd52 commit 5bc34ca
Showing 1 changed file with 214 additions and 3 deletions.
217 changes: 214 additions & 3 deletions drivers/input/touchscreen/synaptics_driver_s3320.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,23 @@
#include "synaptics_dsx_core.h"

#include <linux/moduleparam.h>

#define WAKE_GESTURES 1
#ifdef WAKE_GESTURES
#define WAKE_GESTURE 0x0b
#define SWEEP_RIGHT 0x01
#define SWEEP_LEFT 0x02
#define SWEEP_UP 0x04
#define SWEEP_DOWN 0x08
static struct synaptics_ts_data *gl_ts;
static struct input_dev *gesture_dev;
struct kobject *android_touch_kobj;
EXPORT_SYMBOL_GPL(android_touch_kobj);
static int gestures_switch = 0;
static int s2w_switch = 0;
static int dt2w_switch = 0;
#endif

/*------------------------------------------------Global Define--------------------------------------------*/

#define TP_UNKNOWN 0
Expand Down Expand Up @@ -1452,7 +1469,7 @@ static void gesture_judge(struct synaptics_ts_data *ts)
gesture_sign = gesture_buffer[0];

if (ts->project_version == 0x03) {
if (DouTap_gesture) {
if (DouTap_gesture || dt2w_switch) {
if (gesture_sign == SINGLE_TAP) {
is_double_tap = double_tap(ts);
if (is_double_tap == 1) {
Expand Down Expand Up @@ -1546,8 +1563,9 @@ static void gesture_judge(struct synaptics_ts_data *ts)
gesture = UnkownGestrue;
break;
}

#endif
#ifdef VENDOR_EDIT_OXYGEN
#ifndef WAKE_GESTURES
keyCode = UnkownGestrue;
// Get key code based on registered gesture.
switch (gesture) {
Expand Down Expand Up @@ -1584,6 +1602,7 @@ static void gesture_judge(struct synaptics_ts_data *ts)
default:
break;
}
#endif
#endif

TPD_ERR("detect %s gesture\n", gesture == DouTap ? "(double tap)" :
Expand All @@ -1608,6 +1627,59 @@ static void gesture_judge(struct synaptics_ts_data *ts)
("gesture suport LeftVee:%d RightVee:%d DouSwip:%d Circle:%d UpVee:%d DouTap:%d\n",
LeftVee_gesture, RightVee_gesture, DouSwip_gesture, Circle_gesture,
UpVee_gesture, DouTap_gesture);

#ifdef WAKE_GESTURES
if ((gesture == Down2UpSwip && s2w_switch & SWEEP_UP) ||
(gesture == Up2DownSwip && s2w_switch & SWEEP_DOWN) ||
(gesture == Right2LeftSwip && s2w_switch & SWEEP_LEFT) ||
(gesture == Left2RightSwip && s2w_switch & SWEEP_RIGHT) ||
(gesture == DouTap && dt2w_switch)) {

//wake gestures (requires app)
if (gestures_switch) {
int gest;
switch (gesture) {
case DouTap:
gest = 5;
break;
case Down2UpSwip:
gest = 3;
break;
case Up2DownSwip:
gest = 4;
break;
case Right2LeftSwip:
gest = 2;
break;
case Left2RightSwip:
gest = 1;
break;
}

input_report_rel(gesture_dev, WAKE_GESTURE, gest);
input_sync(gesture_dev);

//traditional s2w using userspace doubletap gesture from OnePlus (checks proximity sensor and vibrates)
} else if (DouTap_gesture) {
gesture = DouTap;
input_report_key(ts->input_dev, keyCode, 1);
input_sync(ts->input_dev);
input_report_key(ts->input_dev, keyCode, 0);
input_sync(ts->input_dev);

if (haptic_feedback_disable)
qpnp_hap_ignore_next_request();

//traditional s2w if gestures not enabled in OnePlus settings (only turns on screen)
} else {
input_report_key(ts->input_dev, KEY_POWER, 1);
input_sync(ts->input_dev);
input_report_key(ts->input_dev, KEY_POWER, 0);
input_sync(ts->input_dev);
}
} else
#endif

if ((gesture == DouTap && DouTap_gesture)
|| (gesture == RightVee && RightVee_gesture)
|| (gesture == LeftVee && LeftVee_gesture) || (gesture == UpVee
Expand All @@ -1619,6 +1691,12 @@ static void gesture_judge(struct synaptics_ts_data *ts)
Wgestrue_gesture)
|| (gesture == Mgestrue && Mgestrue_gesture)
|| (gesture == SingleTap && Single_gesture)) {

#ifdef WAKE_GESTURES
if (!dt2w_switch && s2w_switch && gesture == DouTap)
return;
#endif

input_report_key(ts->input_dev, keyCode, 1);
input_sync(ts->input_dev);
input_report_key(ts->input_dev, keyCode, 0);
Expand All @@ -1640,7 +1718,7 @@ static void gesture_judge(struct synaptics_ts_data *ts)
}
TPD_DEBUG("%s end!\n", __func__);
}
#endif

/***************end****************/
static char prlog_count = 0;
#ifdef REPORT_2D_PRESSURE
Expand Down Expand Up @@ -2091,6 +2169,17 @@ static ssize_t i2c_device_test_read_func(struct file *file,
}

#ifdef SUPPORT_GESTURE
#ifdef WAKE_GESTURES
static void gestures_enable(void)
{
struct synaptics_ts_data *ts = gl_ts;
ts->gesture_enable = (gestures_switch || s2w_switch || dt2w_switch ||
LeftVee_gesture || RightVee_gesture || DouSwip_gesture ||
Circle_gesture || UpVee_gesture || DouTap_gesture ||
Enable_gesture) ? 1 : 0;
}
#endif

static ssize_t tp_gesture_read_func(struct file *file, char __user * user_buf,
size_t count, loff_t * ppos)
{
Expand Down Expand Up @@ -2136,6 +2225,10 @@ static ssize_t tp_gesture_write_func(struct file *file,
//enable gesture
Enable_gesture = (buf[1] & BIT7) ? 1 : 0;

#ifdef WAKE_GESTURES
gestures_enable();
#else

if (DouTap_gesture || Circle_gesture || UpVee_gesture
|| LeftVee_gesture || RightVee_gesture || DouSwip_gesture
|| Sgestrue_gesture || Mgestrue_gesture || Wgestrue_gesture
Expand All @@ -2144,6 +2237,7 @@ static ssize_t tp_gesture_write_func(struct file *file,
} else {
ts->gesture_enable = 0;
}
#endif
return count;
}

Expand Down Expand Up @@ -3817,6 +3911,10 @@ static int synaptics_input_init(struct synaptics_ts_data *ts)
set_bit(BTN_TOOL_FINGER, ts->input_dev->keybit);
#ifdef SUPPORT_GESTURE
set_bit(KEY_F4, ts->input_dev->keybit); //doulbe-tap resume
#ifdef WAKE_GESTURES
set_bit(KEY_POWER, ts->input_dev->keybit);
input_set_capability(ts->input_dev, EV_KEY, KEY_POWER);
#endif
#ifdef VENDOR_EDIT_OXYGEN
set_bit(KEY_DOUBLE_TAP, ts->input_dev->keybit);
set_bit(KEY_GESTURE_CIRCLE, ts->input_dev->keybit);
Expand Down Expand Up @@ -6163,6 +6261,80 @@ static int synaptics_ts_init_virtual_key(struct synaptics_ts_data *ts)
}
#endif

#ifdef WAKE_GESTURES
static ssize_t sweep2wake_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
size_t count = 0;
count += sprintf(buf, "%d\n", s2w_switch);

return count;
}

static ssize_t sweep2wake_dump(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int input;
sscanf(buf, "%d ", &input);
if (input < 0 || input > 15) {
s2w_switch = 0;
} else {
s2w_switch = input;
}
gestures_enable();

return count;
}

static DEVICE_ATTR(sweep2wake, (S_IWUSR|S_IRUGO),
sweep2wake_show, sweep2wake_dump);


static ssize_t doubletap2wake_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
size_t count = 0;
count += sprintf(buf, "%d\n", dt2w_switch);

return count;
}

static ssize_t doubletap2wake_dump(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int input;
sscanf(buf, "%d ", &input);
dt2w_switch = (input) ? 1 : 0;
gestures_enable();

return count;
}

static DEVICE_ATTR(doubletap2wake, (S_IWUSR|S_IRUGO),
doubletap2wake_show, doubletap2wake_dump);

static ssize_t wake_gestures_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
size_t count = 0;
count += sprintf(buf, "%d\n", gestures_switch);
return count;
}
static ssize_t wake_gestures_dump(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int input;
sscanf(buf, "%d ", &input);
gestures_switch = (input) ? 1 : 0;
gestures_enable();

return count;
}

static DEVICE_ATTR(wake_gestures, (S_IWUSR|S_IRUGO),
wake_gestures_show, wake_gestures_dump);
#endif

static int synaptics_ts_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
Expand Down Expand Up @@ -6456,11 +6628,50 @@ static int synaptics_ts_probe(struct i2c_client *client,
}
#endif
init_synaptics_proc();
#ifdef WAKE_GESTURES
gl_ts = ts;

gesture_dev = input_allocate_device();
if (!gesture_dev) {
pr_err("Can't allocate gesture device\n");
goto exit_init_failed;
}

gesture_dev->name = "wake_gesture";
gesture_dev->phys = "wake_gesture/input0";
input_set_capability(gesture_dev, EV_REL, WAKE_GESTURE);

ret = input_register_device(gesture_dev);
if (ret) {
pr_err("%s: input_register_device err=%d\n", __func__, ret);
goto err_gesture_dev;
}

android_touch_kobj = kobject_create_and_add("android_touch", NULL) ;
if (android_touch_kobj == NULL) {
pr_warn("%s: android_touch_kobj create_and_add failed\n", __func__);
}
ret = sysfs_create_file(android_touch_kobj, &dev_attr_sweep2wake.attr);
if (ret) {
pr_warn("%s: sysfs_create_file failed for sweep2wake\n", __func__);
}
ret = sysfs_create_file(android_touch_kobj, &dev_attr_doubletap2wake.attr);
if (ret) {
pr_warn("%s: sysfs_create_file failed for doubletap2wake\n", __func__);
}
ret = sysfs_create_file(android_touch_kobj, &dev_attr_wake_gestures.attr);
if (ret) {
pr_warn("%s: sysfs_create_file failed for wake_gestures\n", __func__);
}
#endif
TPDTM_DMESG("synaptics_ts_probe 3203: normal end\n");

return 0;

#ifdef WAKE_GESTURES
err_gesture_dev:
input_free_device(gesture_dev);
#endif
exit_init_failed:
free_irq(client->irq, ts);
exit_createworkqueue_failed:
Expand Down

0 comments on commit 5bc34ca

Please sign in to comment.