From e993e67fc36eb48a746f9a04af39882af9eb3aa2 Mon Sep 17 00:00:00 2001 From: Andrey Voloshin Date: Wed, 9 Jul 2014 18:05:43 +0300 Subject: [PATCH 1/4] Wake Gestures added --- Makefile | 4 +- arch/arm/mach-msm/htc_battery_core.c | 5 +- drivers/i2c/chips/cm3629.c | 19 + drivers/input/misc/gpio_event.c | 10 + drivers/input/touchscreen/Kconfig | 4 + drivers/input/touchscreen/synaptics_3200.c | 1046 ++++++++++++++++++-- drivers/misc/pm8xxx-vibrator-pwm.c | 8 + include/linux/mfd/pm8xxx/vibrator.h | 2 + include/linux/pl_sensor.h | 1 + include/linux/synaptics_i2c_rmi.h | 9 + 10 files changed, 1042 insertions(+), 66 deletions(-) diff --git a/Makefile b/Makefile index 09fa1272..b6ead879 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ VERSION = 3 PATCHLEVEL = 4 SUBLEVEL = 10 -EXTRAVERSION =-BoA -NAME = Saber-toothed Squirrel +EXTRAVERSION =-anvol +NAME = CTO at mobiliuz.com # *DOCUMENTATION* # To see a list of typical targets execute "make help" diff --git a/arch/arm/mach-msm/htc_battery_core.c b/arch/arm/mach-msm/htc_battery_core.c index dc2952b6..fde11f1c 100644 --- a/arch/arm/mach-msm/htc_battery_core.c +++ b/arch/arm/mach-msm/htc_battery_core.c @@ -28,6 +28,9 @@ #include #include +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE +#include +#endif static ssize_t htc_battery_show_property(struct device *dev, struct device_attribute *attr, @@ -82,7 +85,7 @@ static struct alarm batt_charger_ctrl_alarm; static struct work_struct batt_charger_ctrl_work; struct workqueue_struct *batt_charger_ctrl_wq; static unsigned int charger_ctrl_stat; -static unsigned int phone_call_stat; +unsigned int phone_call_stat; static int test_power_monitor; diff --git a/drivers/i2c/chips/cm3629.c b/drivers/i2c/chips/cm3629.c index 0d8b66b4..56fc0dd1 100644 --- a/drivers/i2c/chips/cm3629.c +++ b/drivers/i2c/chips/cm3629.c @@ -579,6 +579,7 @@ static void report_psensor_input_event(struct cm3629_info *lpi, int interrupt_fl } else { val = (interrupt_flag == 2) ? 0 : 1; } + ps_near = !val; if (lpi->ps_debounce == 1 && lpi->mfg_mode != MFG_MODE) { if (val == 0) { @@ -2571,6 +2572,24 @@ int power_key_check_in_pocket(void) return (ls_dark && ps_near); } +int pocket_detection_check(void) +{ + struct cm3629_info *lpi = lp_info; + + if (!is_probe_success) { + printk("[cm3629] %s return by cm3629 probe fail\n", __func__); + return 0; + } + pocket_mode_flag = 1; + + psensor_enable(lpi); + D("[cm3629] %s ps_near = %d\n", __func__, ps_near); + psensor_disable(lpi); + + pocket_mode_flag = 0; + return (ps_near); +} + int psensor_enable_by_touch_driver(int on) { struct cm3629_info *lpi = lp_info; diff --git a/drivers/input/misc/gpio_event.c b/drivers/input/misc/gpio_event.c index 5d04adb5..8795b49b 100644 --- a/drivers/input/misc/gpio_event.c +++ b/drivers/input/misc/gpio_event.c @@ -22,6 +22,10 @@ #include #include +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE +#include +#endif + struct gpio_event { struct gpio_event_input_devs *input_devs; const struct gpio_event_platform_data *info; @@ -177,6 +181,12 @@ static int gpio_event_probe(struct platform_device *pdev) event_info->name : event_info->names[i]; input_dev->event = gpio_input_event; ip->input_devs->dev[i] = input_dev; +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + if (!strcmp(input_dev->name, "keypad_8960")) { + sweep2wake_setdev(input_dev); + printk(KERN_INFO "[sweep2wake]: set device %s\n", input_dev->name); + } +#endif } ip->input_devs->count = dev_count; ip->info = event_info; diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index f5b71e05..5b6a8970 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -523,6 +523,10 @@ config TOUCHSCREEN_SYNAPTICS_I2C_RMI help This enables support for Synaptics RMI over I2C based touchscreens. +config TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + tristate "Sweep2Wake for SYNAPTICS_3k based touchscreens" + default y + config TOUCHSCREEN_SYNAPTICS_RMI4_I2C tristate "Synaptics i2c touchscreen(ClearPad 3000)" depends on I2C diff --git a/drivers/input/touchscreen/synaptics_3200.c b/drivers/input/touchscreen/synaptics_3200.c index cff83907..d2dd10ad 100644 --- a/drivers/input/touchscreen/synaptics_3200.c +++ b/drivers/input/touchscreen/synaptics_3200.c @@ -2,6 +2,8 @@ * * Copyright (C) 2011 HTC Corporation. * + * Sweep2wake, Doubletap2wake & Wake Gestures with Pocket Detection for HTC One + * Copyright (C) 2013,2014 Aaron Segaert aka flar2 (asegaert at gmail.com) * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -37,6 +39,11 @@ #include #include +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE +#include +#include +#endif + #define SYN_I2C_RETRY_TIMES 10 #define SYN_UPDATE_RETRY_TIMES 5 #define SHIFT_BITS 10 @@ -137,6 +144,7 @@ struct synaptics_ts_data { uint8_t block_touch_time_near; uint8_t block_touch_time_far; uint8_t block_touch_event; + }; #ifdef CONFIG_HAS_EARLYSUSPEND @@ -194,6 +202,237 @@ static void syn_handle_block_touch(struct synaptics_ts_data *ts, int enable) } } +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + +#define S2W_START 3 +#define S2W_TIMEOUT 30 +#define S2W_TIMEOUT2 60 +#define S2W_TIMEOUT3 50 +#define L2M_TIMEOUT 30 +#define DT2W_TIMEOUT_MAX 400 +#define DT2W_DELTA 230 +#define L2W_TIMEOUT 50 + +#define WAKE_GESTURE 0x0b +#define SWEEP_RIGHT 0x01 +#define SWEEP_LEFT 0x02 +#define SWEEP_UP 0x04 +#define SWEEP_DOWN 0x08 + +static bool scr_suspended = false; +static int button_id = 0; +static int s2w_switch = 15; +static int s2s_switch = 2; +static int gestures_switch = 1; +static int l2m_switch = 1; +static int l2w_switch = 0; +static int dt2w_switch = 1; +static int pocket_detect = 1; +static int s2w_hist[2] = {0, 0}; +static unsigned long s2w_time[3] = {0, 0, 0}; +static unsigned long l2m_time[2] = {0, 0}; +static unsigned long pwrtrigger_time[2] = {0, 0}; +static bool barriery[2] = {false, false}, exec_county = true; +static bool barrierx[2] = {false, false}, exec_countx = true; +static int firstx = 0, firsty = 0; +static unsigned long firsty_time = 0, firstx_time = 0; +static int wakesleep_vib = 0; +static int vib_strength = 15; +static int break_longtap_count = 0; + +static struct wake_lock l2w_wakelock; + +static struct input_dev *gesture_dev; + + +extern uint8_t touchscreen_is_on(void) +{ + if (scr_suspended == false) { + return 1; + } + return 0; +} + +static struct input_dev * sweep2wake_pwrdev; +static DEFINE_MUTEX(pwrkeyworklock); +static DEFINE_MUTEX(longtap_count_lock); + +static void report_gesture(int gest) +{ + pwrtrigger_time[1] = pwrtrigger_time[0]; + pwrtrigger_time[0] = jiffies; + + if (pwrtrigger_time[0] - pwrtrigger_time[1] < S2W_TIMEOUT3) { + if (wake_lock_active(&l2w_wakelock)) + wake_unlock(&l2w_wakelock); + return; + } + + if ((pocket_detect && !pocket_detection_check()) || !pocket_detect) { + input_report_rel(gesture_dev, WAKE_GESTURE, gest); + input_sync(gesture_dev); + } +} + +static void reset_sweep2wake (void) { + s2w_time[0] = 0; + s2w_time[1] = 0; + s2w_time[2] = 0; + + s2w_hist[0] = 0; + s2w_hist[1] = 0; +} + +extern void sweep2wake_setdev(struct input_dev * input_device) { + sweep2wake_pwrdev = input_device; + return; +} +EXPORT_SYMBOL(sweep2wake_setdev); + +static void sweep2wake_presspwr(struct work_struct * sweep2wake_presspwr_work) { + + if (scr_suspended == true && pocket_detect == 1) { + if (pocket_detection_check()) { + if (wake_lock_active(&l2w_wakelock)) + wake_unlock(&l2w_wakelock); + return; + } + } + + if (l2w_switch == 1) + break_longtap_count = 1; + + if (wakesleep_vib) { + vibrate(vib_strength); + wakesleep_vib = 0; + } + + if (!mutex_trylock(&pwrkeyworklock)) + return; + input_event(sweep2wake_pwrdev, EV_KEY, KEY_POWER, 1); + input_event(sweep2wake_pwrdev, EV_SYN, 0, 0); + msleep(60); + input_event(sweep2wake_pwrdev, EV_KEY, KEY_POWER, 0); + input_event(sweep2wake_pwrdev, EV_SYN, 0, 0); + msleep(60); + mutex_unlock(&pwrkeyworklock); + + if (wake_lock_active(&l2w_wakelock)) + wake_unlock(&l2w_wakelock); + + return; +} +static DECLARE_WORK(sweep2wake_presspwr_work, sweep2wake_presspwr); + +void sweep2wake_pwrtrigger(void) { + + pwrtrigger_time[1] = pwrtrigger_time[0]; + pwrtrigger_time[0] = jiffies; + + if (pwrtrigger_time[0] - pwrtrigger_time[1] < S2W_TIMEOUT3) { + if (wake_lock_active(&l2w_wakelock)) + wake_unlock(&l2w_wakelock); + return; + } + schedule_work(&sweep2wake_presspwr_work); + return; +} + +static void logo2menu_pressmenu(struct work_struct * logo2menu_pressmenu_work) { + struct synaptics_ts_data *ts = gl_ts; + + if (l2w_switch == 1) + break_longtap_count = 1; + + input_event(ts->input_dev, EV_KEY, KEY_MENU, 1); + input_sync(ts->input_dev); + msleep(60); + input_event(ts->input_dev, EV_KEY, KEY_MENU, 0); + input_sync(ts->input_dev); + msleep(60); + return; +} + +static DECLARE_WORK(logo2menu_pressmenu_work, logo2menu_pressmenu); + +void logo2menu_menutrigger(void) { + schedule_work(&logo2menu_pressmenu_work); + return; +} + +static int allow_longtap_count = 1; + +static void logo2wake_longtap_count(struct work_struct * logo2wake_longtap_count_work) +{ + unsigned long time_count = 0; + + if (!mutex_trylock(&longtap_count_lock)) + return; + + time_count = jiffies; + + if (scr_suspended) + wake_lock_timeout(&l2w_wakelock, HZ/3); + + for (;;) { + + if (break_longtap_count) { + if (wake_lock_active(&l2w_wakelock)) + wake_unlock(&l2w_wakelock); + pr_debug("[L2W] breaking longtap count work...\n"); + break_longtap_count = 0; + mutex_unlock(&longtap_count_lock); + return; + } + + if (jiffies - time_count > L2W_TIMEOUT) { + pr_debug("[L2W] counted to longtap time!\n"); + if (wake_lock_active(&l2w_wakelock)) + wake_unlock(&l2w_wakelock); + break; + } + msleep(3); + } + if (!break_longtap_count) { + + time_count = 0; + pr_debug(KERN_INFO "[L2W] sending event KEY_POWER 1\n"); + if ((pocket_detect && !pocket_detection_check()) || !pocket_detect) { + if (gestures_switch && scr_suspended) { + report_gesture(6); + } else if (l2w_switch) { + vibrate(vib_strength); + input_event(sweep2wake_pwrdev, EV_KEY, KEY_POWER, 1); + input_sync(sweep2wake_pwrdev); + msleep(100); + input_event(sweep2wake_pwrdev, EV_KEY, KEY_POWER, 0); + input_sync(sweep2wake_pwrdev); + msleep(100); + } + } + } + + mutex_unlock(&longtap_count_lock); + return; +} + +static DECLARE_WORK(logo2wake_longtap_count_work, logo2wake_longtap_count); + +void logo2wake_longtap_count_trigger(void) +{ + break_longtap_count = 0; + if (allow_longtap_count) { + allow_longtap_count = 0; + pr_debug("[L2W] starting longtap count work\n"); + schedule_work(&logo2wake_longtap_count_work); + } else { + pr_debug("[L2W] not longtap count work - not allowed (waiting for finger release)\n"); + } + return; +} + +#endif + static void syn_page_select(struct i2c_client *client, uint8_t page) { struct synaptics_ts_data *ts = i2c_get_clientdata(client); @@ -1720,6 +1959,170 @@ static DEVICE_ATTR(reset, (S_IWUSR), #endif +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE +static ssize_t synaptics_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 synaptics_sweep2wake_dump(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + sscanf(buf, "%d ", &s2w_switch); + if (s2w_switch < 0 || s2w_switch > 15) + s2w_switch = 15; + return count; +} + +static DEVICE_ATTR(sweep2wake, 0666, + synaptics_sweep2wake_show, synaptics_sweep2wake_dump); + +static ssize_t synaptics_sweep2sleep_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + size_t count = 0; + count += sprintf(buf, "%d\n", s2s_switch); + return count; +} + +static ssize_t synaptics_sweep2sleep_dump(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + if (buf[0] >= '0' && buf[0] <= '3' && buf[1] == '\n') + if (s2s_switch != buf[0] - '0') + s2s_switch = buf[0] - '0'; + return count; +} + +static DEVICE_ATTR(sweep2sleep, 0666, + synaptics_sweep2sleep_show, synaptics_sweep2sleep_dump); + + +static ssize_t synaptics_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 synaptics_wake_gestures_dump(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + if (buf[0] >= '0' && buf[0] <= '1' && buf[1] == '\n') + if (gestures_switch != buf[0] - '0') + gestures_switch = buf[0] - '0'; + return count; +} + +static DEVICE_ATTR(wake_gestures, 0666, + synaptics_wake_gestures_show, synaptics_wake_gestures_dump); + + +static ssize_t synaptics_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 synaptics_doubletap2wake_dump(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + if (buf[0] >= '0' && buf[0] <= '2' && buf[1] == '\n') + if (dt2w_switch != buf[0] - '0') { + dt2w_switch = buf[0] - '0'; + } + return count; +} + +static DEVICE_ATTR(doubletap2wake, (S_IWUSR|S_IRUGO), + synaptics_doubletap2wake_show, synaptics_doubletap2wake_dump); + + +static ssize_t synaptics_logo2menu_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + size_t count = 0; + count += sprintf(buf, "%d\n", l2m_switch); + return count; +} + +static ssize_t synaptics_logo2menu_dump(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + if (buf[0] >= '0' && buf[0] <= '1' && buf[1] == '\n') + if (l2m_switch != buf[0] - '0') { + l2m_switch = buf[0] - '0'; + } + return count; +} + +static DEVICE_ATTR(logo2menu, (S_IWUSR|S_IRUGO), + synaptics_logo2menu_show, synaptics_logo2menu_dump); + +static ssize_t synaptics_logo2wake_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + size_t count = 0; + count += sprintf(buf, "%d\n", l2w_switch); + return count; +} + +static ssize_t synaptics_logo2wake_dump(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + if (buf[0] >= '0' && buf[0] <= '1' && buf[1] == '\n') + if (l2w_switch != buf[0] - '0') { + l2w_switch = buf[0] - '0'; + } + return count; +} + +static DEVICE_ATTR(logo2wake, (S_IWUSR|S_IRUGO), + synaptics_logo2wake_show, synaptics_logo2wake_dump); + +static ssize_t synaptics_pocket_detect_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + size_t count = 0; + count += sprintf(buf, "%d\n", pocket_detect); + return count; +} + +static ssize_t synaptics_pocket_detect_dump(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + if (buf[0] >= '0' && buf[0] <= '1' && buf[1] == '\n') + if (pocket_detect != buf[0] - '0') + pocket_detect = buf[0] - '0'; + + return count; +} + +static DEVICE_ATTR(pocket_detect, 0666, + synaptics_pocket_detect_show, synaptics_pocket_detect_dump); + + + + + +static ssize_t synaptics_vib_strength_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + size_t count = 0; + count += sprintf(buf, "%d\n", vib_strength); + return count; +} + +static ssize_t synaptics_vib_strength_dump(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + sscanf(buf, "%d ",&vib_strength); + if (vib_strength < 0 || vib_strength > 60) + vib_strength = 15; + + return count; +} + +static DEVICE_ATTR(vib_strength, 0666, + synaptics_vib_strength_show, synaptics_vib_strength_dump); +#endif + enum SR_REG_STATE{ ALLOCATE_DEV_FAIL = -2, REGISTER_DEV_FAIL, @@ -1839,6 +2242,51 @@ static int synaptics_touch_sysfs_init(void) sysfs_create_file(android_touch_kobj, &dev_attr_disable_cbc.attr)) return -ENOMEM; +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + ret = sysfs_create_file(android_touch_kobj, &dev_attr_sweep2wake.attr); + if (ret) { + printk(KERN_ERR "%s: sysfs_create_file failed\n", __func__); + return ret; + } + ret = sysfs_create_file(android_touch_kobj, &dev_attr_sweep2sleep.attr); + if (ret) { + printk(KERN_ERR "%s: sysfs_create_file failed\n", __func__); + return ret; + } + ret = sysfs_create_file(android_touch_kobj, &dev_attr_wake_gestures.attr); + if (ret) { + printk(KERN_ERR "%s: sysfs_create_file failed\n", __func__); + return ret; + } + ret = sysfs_create_file(android_touch_kobj, &dev_attr_doubletap2wake.attr); + if (ret) { + printk(KERN_ERR "%s: sysfs_create_file failed\n", __func__); + return ret; + } + ret = sysfs_create_file(android_touch_kobj, &dev_attr_logo2menu.attr); + if (ret) { + printk(KERN_ERR "%s: sysfs_create_file failed\n", __func__); + return ret; + } + ret = sysfs_create_file(android_touch_kobj, &dev_attr_logo2wake.attr); + if (ret) { + printk(KERN_ERR "%s: sysfs_create_file failed\n", __func__); + return ret; + } + + ret = sysfs_create_file(android_touch_kobj, &dev_attr_pocket_detect.attr); + if (ret) { + printk(KERN_ERR "%s: sysfs_create_file failed\n", __func__); + return ret; + } + + ret = sysfs_create_file(android_touch_kobj, &dev_attr_vib_strength.attr); + if (ret) { + printk(KERN_ERR "%s: sysfs_create_file failed\n", __func__); + return ret; + } +#endif + #ifdef SYN_WIRELESS_DEBUG ret= gpio_request(ts->gpio_irq, "synaptics_attn"); if (ret) { @@ -1885,6 +2333,16 @@ static void synaptics_touch_sysfs_remove(void) sysfs_remove_file(android_touch_kobj, &dev_attr_htc_event.attr); sysfs_remove_file(android_touch_kobj, &dev_attr_reset.attr); sysfs_remove_file(android_touch_kobj, &dev_attr_sr_en.attr); +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + sysfs_remove_file(android_touch_kobj, &dev_attr_sweep2wake.attr); + sysfs_remove_file(android_touch_kobj, &dev_attr_sweep2sleep.attr); + sysfs_remove_file(android_touch_kobj, &dev_attr_wake_gestures.attr); + sysfs_remove_file(android_touch_kobj, &dev_attr_doubletap2wake.attr); + sysfs_remove_file(android_touch_kobj, &dev_attr_logo2menu.attr); + sysfs_remove_file(android_touch_kobj, &dev_attr_logo2wake.attr); + sysfs_remove_file(android_touch_kobj, &dev_attr_pocket_detect.attr); + sysfs_remove_file(android_touch_kobj, &dev_attr_vib_strength.attr); +#endif #ifdef SYN_WIRELESS_DEBUG sysfs_remove_file(android_touch_kobj, &dev_attr_enabled.attr); #endif @@ -1999,6 +2457,287 @@ static int synaptics_init_panel(struct synaptics_ts_data *ts) return ret; } +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + +static void reset_sv2w(void) +{ + exec_county = true; + barriery[0] = false; + barriery[1] = false; + firsty = 0; + firsty_time = 0; +} + +static void sweep2wake_vert_func(int x, int y) +{ + int prevy = 0, nexty = 0; + + if (firsty == 0) { + firsty = y; + firsty_time = jiffies; + } + if (firsty > 2279) + reset_sv2w(); + //sweep up + if ((x > 100 && x < 1500) && (gestures_switch || (s2w_switch & SWEEP_UP))) { + if (firsty > 1500) { + prevy = firsty; + nexty = prevy - 170; + if (barriery[0] == true || (y < prevy && y > nexty)) { + prevy = nexty; + nexty -= 200; + barriery[0] = true; + if (barriery[1] == true || (y < prevy && y > nexty)) { + prevy = nexty; + barriery[1] = true; + if (y < prevy) { + if (y < (nexty - 170)) { + if (exec_county && (jiffies - firsty_time < S2W_TIMEOUT)) { + pr_debug("wake_gesture: sweep up\n"); + wake_lock_timeout(&l2w_wakelock, HZ/2); + if (gestures_switch) { + report_gesture(3); + } else { + wakesleep_vib = 1; + sweep2wake_pwrtrigger(); + } + exec_county = false; + } + } + } + } + } + //sweep down + } else if ((firsty <= 1500) && (gestures_switch || (s2w_switch & SWEEP_DOWN))) { + prevy = firsty; + nexty = prevy + 170; + if (barriery[0] == true || (y > prevy && y < nexty)) { + prevy = nexty; + nexty += 200; + barriery[0] = true; + if (barriery[1] == true || (y > prevy && y < nexty)) { + prevy = nexty; + barriery[1] = true; + if (y > prevy) { + if (y > (nexty + 170)) { + if (exec_county && (jiffies - firsty_time < S2W_TIMEOUT)) { + pr_debug("wake_gesture: sweep down\n"); + wake_lock_timeout(&l2w_wakelock, HZ/2); + if (gestures_switch) { + report_gesture(4); + } else { + wakesleep_vib = 1; + sweep2wake_pwrtrigger(); + } + exec_county = false; + } + } + } + } + } + } + } +} + +static void reset_sh2w(void) +{ + exec_countx = true; + barrierx[0] = false; + barrierx[1] = false; + firstx = 0; + firstx_time = 0; +} + +static void sweep2wake_horiz_func(int x, int y) +{ + int prevx = 0, nextx = 0; + + if (firstx == 0) { + firstx = x; + firstx_time = jiffies; + } + if (firstx > 1619) + reset_sh2w(); + + //sweep right + if (firstx < 810 && (gestures_switch || (s2w_switch & SWEEP_RIGHT))) { + prevx = firstx; + nextx = prevx + 180; + if (barrierx[0] == true || (x > prevx && x < nextx)) { + prevx = nextx; + nextx += 200; + barrierx[0] = true; + if (barrierx[1] == true || (x > prevx && x < nextx)) { + prevx = nextx; + barrierx[1] = true; + if (x > prevx) { + if (x > (nextx + 180)) { + if (exec_countx && (jiffies - firstx_time < S2W_TIMEOUT)) { + pr_debug("wake_gesture: sweep right\n"); + wake_lock_timeout(&l2w_wakelock, HZ/2); + if (gestures_switch) { + report_gesture(1); + } else { + wakesleep_vib = 1; + sweep2wake_pwrtrigger(); + } + exec_countx = false; + } + } + } + } + } + //sweep left + } else if (firstx >= 810 && y < 2790 && (gestures_switch || (s2w_switch & SWEEP_LEFT))) { + prevx = firstx; + nextx = prevx - 180; + if ((barrierx[0] == true) ||(x < prevx && x > nextx && y < 2790)) { + prevx = nextx; + nextx -= 200; + barrierx[0] = true; + if ((barrierx[1] == true) || (x < prevx && x > nextx && y < 2790)) { + prevx = nextx; + barrierx[1] = true; + if (x < prevx && y < 2790) { + if (x < (nextx - 180)) { + if (exec_countx && (jiffies - firstx_time < S2W_TIMEOUT)) { + pr_debug("wake_gesture: sweep left\n"); + wake_lock_timeout(&l2w_wakelock, HZ/2); + if (gestures_switch) { + report_gesture(2); + } else { + wakesleep_vib = 1; + sweep2wake_pwrtrigger(); + } + exec_countx = false; + } + } + } + } + } + } + +} + +static void sweep2wake_func(int button_id) { + + s2w_time[2] = s2w_time[1]; + s2w_time[1] = s2w_time[0]; + s2w_time[0] = jiffies; + + s2w_hist[1] = s2w_hist[0]; + s2w_hist[0] = button_id; + + if ((s2w_time[0]-s2w_time[2]) < S2W_TIMEOUT2 && !scr_suspended) { + printk("[S2W]: canceled by timeout2\n"); + return; + } + + if ((s2w_time[0]-s2w_time[1]) < S2W_TIMEOUT && (s2w_time[0]-s2w_time[1]) > S2W_START) { + + if (s2w_hist[1] == 1 && s2w_hist[0] == 2) { + pr_debug("[S2W]: OFF->ON\n"); + reset_sweep2wake(); + if (gestures_switch && scr_suspended) { + report_gesture(1); + } else if (((s2w_switch & SWEEP_RIGHT) && scr_suspended) || (!scr_suspended && (s2s_switch & SWEEP_RIGHT))) { + wakesleep_vib = 1; + sweep2wake_pwrtrigger(); + } + + } else if (s2w_hist[1] == 2 && s2w_hist[0] == 1) { + reset_sweep2wake(); + if (gestures_switch && scr_suspended) { + report_gesture(2); + } else if (((s2w_switch & SWEEP_LEFT) && scr_suspended) || (!scr_suspended && (s2s_switch & SWEEP_LEFT))) { + pr_debug("[S2W]: ON->OFF\n"); + wakesleep_vib = 1; + sweep2wake_pwrtrigger(); + } + } else { + reset_sweep2wake(); + return; + } + } +} + +static void logo2menu_func(void) { + + if (l2m_switch == 1 && scr_suspended == false && ((l2m_time[0]-l2m_time[1]) < L2M_TIMEOUT)) { + pr_debug("[L2M]: menu button activated\n"); + logo2menu_menutrigger(); + } + + return; +} + + +static int last_touch_position_x = 0; +static int last_touch_position_y = 0; + +static int report_htc_logo_area(int x, int y) { + if (l2m_switch == 0 && l2w_switch == 0 && gestures_switch == 0) + return 0; + + if (last_touch_position_x > 620 && last_touch_position_x < 1150) { + if (last_touch_position_y > 2835 || (scr_suspended == true && last_touch_position_y > 2750)) { + l2m_time[1] = l2m_time[0]; + l2m_time[0] = jiffies; + return 1; + } + } + break_longtap_count=1; + return 0; +} + + +static cputime64_t prev_time; +static int prev_x = 0, prev_y = 0; + +static void reset_dt2w(void) +{ + prev_time = 0; + prev_x = 0; + prev_y = 0; +} + +static void dt2w_func(int x, int y, cputime64_t trigger_time) +{ + if ((x > 0 && x < 150) || x > 1470 || y > 2880 || (!gestures_switch && dt2w_switch == 1 && (y > 0 && y < 2100))) { + reset_dt2w(); + return; + } + + if (prev_time == 0) { + prev_time = trigger_time; + prev_x = x; + prev_y = y; + } else if ((trigger_time - prev_time) > DT2W_TIMEOUT_MAX) { + prev_time = trigger_time; + prev_x = x; + prev_y = y; + } else { + if (((abs(x - prev_x) < DT2W_DELTA) && (abs(y - prev_y) < DT2W_DELTA)) + || (prev_x == 0 && prev_y == 0)) { + reset_dt2w(); + pr_debug("[DT2W]: ON\n"); + wake_lock_timeout(&l2w_wakelock, HZ/2); + if (gestures_switch) { + report_gesture(5); + } else { + wakesleep_vib = 1; + sweep2wake_pwrtrigger(); + } + + } else { + prev_time = trigger_time; + prev_x = x; + prev_y = y; + } + } +} +#endif + static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) { int ret; @@ -2006,6 +2745,8 @@ static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) uint16_t temp_im = 0, temp_cidim = 0; static int x_pos[10] = {0}, y_pos[10] = {0}; + cputime64_t dt_trigger_time; + memset(buf, 0x0, sizeof(buf)); memset(noise_index, 0x0, sizeof(noise_index)); if (ts->package_id < 3400) @@ -2097,7 +2838,7 @@ static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) if (ts->layout[1] < finger_data[i][0]) finger_data[i][0] = ts->layout[1]; if(ts->width_factor && ts->height_factor){ - printk(KERN_INFO + pr_debug( "[TP] Screen:F[%02d]:Up, X=%d, Y=%d, W=%d, Z=%d, IM:%d, CIDIM:%d, Freq:%d, NS:%d\n", i+1, (x_pos[i]*ts->width_factor)>>SHIFT_BITS, (y_pos[i]*ts->height_factor)>>SHIFT_BITS, @@ -2156,6 +2897,32 @@ static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) printk(KERN_INFO "[TP] Finger leave\n"); } +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + if (((ts->finger_count > 0)?1:0) == 0) { + + if (scr_suspended == true) { + if (dt2w_switch || gestures_switch) { + dt_trigger_time = ktime_to_ms(ktime_get()); + dt2w_func(last_touch_position_x, last_touch_position_y, dt_trigger_time); + } + + if (gestures_switch || s2w_switch) { + reset_sv2w(); + reset_sh2w(); + } + } + + if (l2m_switch || l2w_switch || gestures_switch) { + + // released (supposedly before long tap happened), break long tap count work... + break_longtap_count = 1; + // released, should allow logo long tap counting again... + allow_longtap_count = 1; + if (report_htc_logo_area(last_touch_position_x,last_touch_position_x)) + logo2menu_func(); + } + } +#endif if (ts->pre_finger_data[0][0] < 2 || finger_pressed) { if (ts->package_id < 3400) base = (ts->finger_support + 3) / 4; @@ -2265,6 +3032,16 @@ static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) finger_data[i][1]); input_mt_sync(ts->input_dev); } else if (ts->htc_event == SYN_AND_REPORT_TYPE_B) { +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + last_touch_position_x = finger_data[i][0]; + last_touch_position_y = finger_data[i][1]; + + if (!report_htc_logo_area(last_touch_position_x,last_touch_position_y)) { + if (scr_suspended && phone_call_stat == 1) { + finger_data[i][0] = -10; + finger_data[i][1] = -10; + } +#endif if (ts->support_htc_event) { input_report_abs(ts->input_dev, ABS_MT_AMPLITUDE, finger_data[i][3] << 16 | finger_data[i][2]); @@ -2285,6 +3062,13 @@ static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) finger_data[i][0]); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, finger_data[i][1]); +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + } else { + if (l2w_switch == 1 || gestures_switch) { + logo2wake_longtap_count_trigger(); + } + } +#endif } else if (ts->htc_event == SYN_AND_REPORT_TYPE_HTC) { input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, i); input_report_abs(ts->input_dev, ABS_MT_AMPLITUDE, @@ -2298,9 +3082,16 @@ static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) y_pos[i] = finger_data[i][1]; finger_pressed &= ~BIT(i); +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + if (gestures_switch && scr_suspended) + sweep2wake_horiz_func(x_pos[0], y_pos[0]); + if ((gestures_switch || s2w_switch) && scr_suspended) + sweep2wake_vert_func(x_pos[0], y_pos[0]); +#endif + if ((finger_press_changed & BIT(i)) && ts->debug_log_level & BIT(3)) { if(ts->width_factor && ts->height_factor){ - printk(KERN_INFO + pr_debug( "[TP] Screen:F[%02d]:Down, X=%d, Y=%d, W=%d, Z=%d, IM:%d, CIDIM:%d, Freq:%d, NS:%d\n", i+1, (finger_data[i][0]*ts->width_factor)>>SHIFT_BITS, (finger_data[i][1]*ts->height_factor)>>SHIFT_BITS, @@ -2367,6 +3158,7 @@ static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) finger_data[i][3], noise_index[1] | noise_index[0], noise_index[6] | noise_index[5], noise_index[9], noise_index[4]); } + if (ts->packrat_number < SYNAPTICS_FW_NOCAL_PACKRAT) { #ifdef SYN_CALIBRATION_CONTROL if (ts->multitouch_calibration) { @@ -2436,68 +3228,114 @@ static void synaptics_ts_report_func(struct synaptics_ts_data *ts) static void synaptics_ts_button_func(struct synaptics_ts_data *ts) { int ret; - uint8_t data = 0, idx = 0; + uint8_t data = 0; uint16_t x_position = 0, y_position = 0; ret = i2c_syn_read(ts->client, get_address_base(ts, 0x1A, DATA_BASE), &data, 1); if (data) { - vk_press = 1; - if (ts->button) { - idx = (data == 0x01 ? 0: - data == 0x02 ? 1: - data == 0x04 ? 2: - 100); + if (data & 0x01) { + printk("[TP] back key pressed\n"); + vk_press = 1; + +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + break_longtap_count = 1; + last_touch_position_x = 0; + last_touch_position_y = 0; + button_id = 1; +#endif - if (idx == 100) { - vk_press = 0; - pr_err("[TP] vk_data:%#x, idx=%d", data, idx); - return; + if (ts->button) { + if (ts->button[0].index) { + x_position = (ts->button[0].x_range_min + ts->button[0].x_range_max) / 2; + y_position = (ts->button[0].y_range_min + ts->button[0].y_range_max) / 2; + } + } + if (ts->htc_event == SYN_AND_REPORT_TYPE_B) { +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + if (!scr_suspended) { +#endif + if (ts->support_htc_event) { + input_report_abs(ts->input_dev, ABS_MT_AMPLITUDE, + 100 << 16 | 100); + input_report_abs(ts->input_dev, ABS_MT_POSITION, + x_position << 16 | y_position); + } + input_mt_slot(ts->input_dev, 0); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, + 1); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, + 100); + input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, + 100); + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, + 100); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, + x_position); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, + y_position); +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + } +#endif } - x_position = (ts->button[idx].x_range_min + ts->button[idx].x_range_max) / 2; - y_position = (ts->button[idx].y_range_min + ts->button[idx].y_range_max) / 2; } - data == 0x01 ? pr_info("[TP] back key pressed, vk=%x\n", data) : - data == 0x02 ? pr_info("[TP] home key pressed, vk=%x\n", data) : - data == 0x04 ? pr_info("[TP] app key pressed , vk=%x\n", data) : - pr_info("[TP] vk=%#x\n", data); + else if (data & 0x02) { + printk("[TP] home key pressed\n"); + vk_press = 1; + +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + break_longtap_count = 1; + last_touch_position_x = 0; + last_touch_position_y = 0; + button_id = 2; +#endif - if (ts->support_htc_event) { - input_report_abs(ts->input_dev, ABS_MT_AMPLITUDE, 100 << 16 | 100); - input_report_abs(ts->input_dev, ABS_MT_POSITION, x_position << 16 | y_position); - } - switch (ts->htc_event) { - case SYN_AND_REPORT_TYPE_A: - input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0); - break; - case SYN_AND_REPORT_TYPE_B: - input_mt_slot(ts->input_dev, 0); - input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 1); - break; - } - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 100); - input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 100); - input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 100); - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x_position); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y_position); - switch (ts->htc_event) { - case SYN_AND_REPORT_TYPE_A: - input_mt_sync(ts->input_dev); - break; - case SYN_AND_REPORT_TYPE_B: - break; + if (ts->button) { + if (ts->button[1].index) { + x_position = (ts->button[1].x_range_min + ts->button[1].x_range_max) / 2; + y_position = (ts->button[1].y_range_min + ts->button[1].y_range_max) / 2; + } + } + if (ts->htc_event == SYN_AND_REPORT_TYPE_B) { +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + if (!scr_suspended) { +#endif + if (ts->support_htc_event) { + input_report_abs(ts->input_dev, ABS_MT_AMPLITUDE, + 100 << 16 | 100); + input_report_abs(ts->input_dev, ABS_MT_POSITION, + x_position << 16 | y_position); + } + input_mt_slot(ts->input_dev, 0); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, + 1); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, + 100); + input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, + 100); + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, + 100); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, + x_position); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, + y_position); +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + } +#endif + } } - } else { + }else { printk("[TP] virtual key released\n"); vk_press = 0; - if (ts->htc_event == SYN_AND_REPORT_TYPE_A) { - if (ts->support_htc_event) { - input_report_abs(ts->input_dev, ABS_MT_AMPLITUDE, 0); - input_report_abs(ts->input_dev, ABS_MT_POSITION, 1 << 31); - } - input_mt_sync(ts->input_dev); + +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + if (s2w_switch || s2s_switch || gestures_switch) { + sweep2wake_func(button_id); } - else if (ts->htc_event == SYN_AND_REPORT_TYPE_B) { + + if (!scr_suspended) { +#endif + if (ts->htc_event == SYN_AND_REPORT_TYPE_B) { if (ts->support_htc_event) { input_report_abs(ts->input_dev, ABS_MT_AMPLITUDE, 0); input_report_abs(ts->input_dev, ABS_MT_POSITION, 1 << 31); @@ -2505,8 +3343,17 @@ static void synaptics_ts_button_func(struct synaptics_ts_data *ts) input_mt_slot(ts->input_dev, 0); input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0); } +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + } +#endif } - input_sync(ts->input_dev); +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + if (!scr_suspended) { +#endif + input_sync(ts->input_dev); +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + } +#endif } static void synaptics_ts_status_func(struct synaptics_ts_data *ts) @@ -2581,10 +3428,13 @@ static irqreturn_t synaptics_irq_thread(int irq, void *ptr) } } if (buf & get_address_base(ts, 0x1A, INTR_SOURCE)) { - if (!ts->finger_count) + if (s2w_switch == 0) { + if (!ts->finger_count) + synaptics_ts_button_func(ts); + } else { +// printk("[TP] Ignore VK interrupt due to 2d points did not leave\n"); synaptics_ts_button_func(ts); - else - printk("[TP] Ignore VK interrupt due to 2d points did not leave\n"); + } } if (buf & get_address_base(ts, 0x01, INTR_SOURCE)) synaptics_ts_status_func(ts); @@ -3270,6 +4120,24 @@ static int syn_probe_init(void *arg) register_early_suspend(&ts->early_suspend); #endif +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + gesture_dev = input_allocate_device(); + + if (!gesture_dev) { + goto err_alloc_dev; + } + + 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_input_dev; + } +#endif + #ifdef SYN_CABLE_CONTROL if (ts->cable_support) { usb_register_notifier(&cable_status_handler); @@ -3304,6 +4172,13 @@ static int syn_probe_init(void *arg) destroy_workqueue(ts->syn_wq); #endif +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE +err_input_dev: + input_free_device(gesture_dev); +err_alloc_dev: + pr_info("%s failed create input device\n", __func__); +#endif + err_create_wq_failed: err_get_intr_bit_failed: @@ -3377,7 +4252,11 @@ static int synaptics_ts_probe( kthread_run(syn_fw_update_init, (void *)ts, "SYN_FW_UPDATE"); } +//l2w + wake_lock_init(&l2w_wakelock, WAKE_LOCK_SUSPEND, "l2w_wakelock"); + kthread_run(syn_probe_init, (void *)ts, "SYN_PROBE_INIT"); + return 0; err_detect_failed: @@ -3402,6 +4281,8 @@ static int synaptics_ts_remove(struct i2c_client *client) if(ts->sr_input_dev != NULL) input_unregister_device(ts->sr_input_dev); input_unregister_device(ts->input_dev); +//l2w + wake_lock_destroy(&l2w_wakelock); synaptics_touch_sysfs_remove(); @@ -3422,12 +4303,31 @@ static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg) struct synaptics_ts_data *ts = i2c_get_clientdata(client); printk(KERN_INFO "[TP] %s: enter\n", __func__); +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + if (s2w_switch || dt2w_switch || l2w_switch || gestures_switch) { + //screen off, enable_irq_wake + enable_irq_wake(client->irq); + } +#endif + if (ts->use_irq) { - disable_irq(client->irq); - ts->irq_enabled = 0; +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + if (!s2w_switch && !dt2w_switch && !l2w_switch && !gestures_switch) { +#endif + disable_irq(client->irq); + ts->irq_enabled = 0; +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + } +#endif } else { hrtimer_cancel(&ts->timer); ret = cancel_work_sync(&ts->work); +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + if (!s2w_switch && !dt2w_switch && !l2w_switch && !gestures_switch) { + if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */ + enable_irq(client->irq); + } +#endif } if(ts->psensor_detection) { @@ -3592,7 +4492,9 @@ static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg) } ts->disable_CBC = 0; } - +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + if (!s2w_switch && !dt2w_switch && !l2w_switch && !gestures_switch) { +#endif if (ts->power) ts->power(0); else { @@ -3621,11 +4523,15 @@ static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg) if (ts->lpm_power) ts->lpm_power(1); } - +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + } + scr_suspended = true; + reset_sv2w(); + reset_sh2w(); +#endif if ((ts->block_touch_time_near | ts->block_touch_time_far) && ts->block_touch_event) { syn_handle_block_touch(ts, 0); } - return 0; } @@ -3635,6 +4541,13 @@ static int synaptics_ts_resume(struct i2c_client *client) struct synaptics_ts_data *ts = i2c_get_clientdata(client); printk(KERN_INFO "[TP] %s: enter\n", __func__); +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + //screen on, disable_irq_wake + if (s2w_switch || dt2w_switch || l2w_switch || gestures_switch) + disable_irq_wake(client->irq); + + if (!s2w_switch && !dt2w_switch && !l2w_switch && !gestures_switch) { +#endif if (ts->power) { ts->power(1); hr_msleep(100); @@ -3653,7 +4566,9 @@ static int synaptics_ts_resume(struct i2c_client *client) if (ret < 0) i2c_syn_error_handler(ts, ts->i2c_err_handler_en, "wake up", __func__); } - +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + } +#endif if (ts->htc_event == SYN_AND_REPORT_TYPE_A) { if (ts->support_htc_event) { input_report_abs(ts->input_dev, ABS_MT_AMPLITUDE, 0); @@ -3679,14 +4594,19 @@ static int synaptics_ts_resume(struct i2c_client *client) ts->psensor_phone_enable = 1; } } - +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + if (!s2w_switch && !dt2w_switch && !l2w_switch && !gestures_switch) { +#endif if (ts->use_irq) { enable_irq(client->irq); ts->irq_enabled = 1; } else hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); - +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + } + scr_suspended = false; +#endif return 0; } diff --git a/drivers/misc/pm8xxx-vibrator-pwm.c b/drivers/misc/pm8xxx-vibrator-pwm.c index c4902b61..7aac8cee 100644 --- a/drivers/misc/pm8xxx-vibrator-pwm.c +++ b/drivers/misc/pm8xxx-vibrator-pwm.c @@ -44,6 +44,7 @@ struct pm8xxx_vib_pwm { int pwm_gpio; int (*set_vdd_power)(int en); }; +static struct pm8xxx_vib_pwm *vib_dev; static int duty_us, period_us; static int switch_state = 1; static int pm8xxx_vib_set_on(struct pm8xxx_vib_pwm *vib) @@ -161,6 +162,12 @@ static void pm8xxx_vib_enable(struct timed_output_dev *dev, int value) } } +int vibrate(int time) +{ + pm8xxx_vib_enable(&vib_dev->timed_dev, time); + return 0; +} + static void pm8xxx_vib_update(struct work_struct *work) { struct pm8xxx_vib_pwm *vib = container_of(work, struct pm8xxx_vib_pwm, @@ -348,6 +355,7 @@ static int __devinit pm8xxx_vib_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, vib); + vib_dev = vib; duty_us= vib->pdata->duty_us; period_us=vib->pdata->PERIOD_US; VIB_PWM_INFO("%s-\n", __func__); diff --git a/include/linux/mfd/pm8xxx/vibrator.h b/include/linux/mfd/pm8xxx/vibrator.h index 82562c00..552ad373 100644 --- a/include/linux/mfd/pm8xxx/vibrator.h +++ b/include/linux/mfd/pm8xxx/vibrator.h @@ -39,4 +39,6 @@ struct pm8xxx_vibrator_platform_data { int pm8xxx_vibrator_config(struct pm8xxx_vib_config *vib_config); +extern int vibrate(int time); + #endif /* __PMIC8XXX_VIBRATOR_H__ */ diff --git a/include/linux/pl_sensor.h b/include/linux/pl_sensor.h index 1c1022bb..614f6e48 100644 --- a/include/linux/pl_sensor.h +++ b/include/linux/pl_sensor.h @@ -8,5 +8,6 @@ extern int register_notifier_by_psensor(struct notifier_block *nb); extern int unregister_notifier_by_psensor(struct notifier_block *nb); int psensor_enable_by_touch_driver(int on); int power_key_check_in_pocket(void); +int pocket_detection_check(void); #endif diff --git a/include/linux/synaptics_i2c_rmi.h b/include/linux/synaptics_i2c_rmi.h index 70f7cf33..66ba48e7 100644 --- a/include/linux/synaptics_i2c_rmi.h +++ b/include/linux/synaptics_i2c_rmi.h @@ -17,6 +17,10 @@ #ifndef _LINUX_SYNAPTICS_I2C_RMI_H #define _LINUX_SYNAPTICS_I2C_RMI_H +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE +#include +#endif + #define SYNAPTICS_I2C_RMI_NAME "synaptics-rmi-ts" #define SYNAPTICS_T1007_NAME "synaptics-t1007" #define SYNAPTICS_T1021_NAME "synaptics-t1021" @@ -174,5 +178,10 @@ enum { FUNCTION }; +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE +extern void sweep2wake_setdev(struct input_dev * input_device); +extern unsigned int phone_call_stat; +#endif + extern uint8_t getPowerKeyState(void); #endif From ea805f65418bb3ce4cc897d8a34e89b13041a059 Mon Sep 17 00:00:00 2001 From: Andrey Voloshin Date: Thu, 10 Jul 2014 05:48:03 +0300 Subject: [PATCH 2/4] Wake Gestures: config sections fixes --- drivers/input/touchscreen/synaptics_3200.c | 32 ++++++++++++++-------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/input/touchscreen/synaptics_3200.c b/drivers/input/touchscreen/synaptics_3200.c index d2dd10ad..90b0f468 100644 --- a/drivers/input/touchscreen/synaptics_3200.c +++ b/drivers/input/touchscreen/synaptics_3200.c @@ -316,7 +316,7 @@ static void sweep2wake_presspwr(struct work_struct * sweep2wake_presspwr_work) { input_event(sweep2wake_pwrdev, EV_SYN, 0, 0); msleep(60); mutex_unlock(&pwrkeyworklock); - + if (wake_lock_active(&l2w_wakelock)) wake_unlock(&l2w_wakelock); @@ -2744,9 +2744,9 @@ static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) uint8_t buf[ts->finger_support * 8 ], noise_index[10]; uint16_t temp_im = 0, temp_cidim = 0; static int x_pos[10] = {0}, y_pos[10] = {0}; - +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE cputime64_t dt_trigger_time; - +#endif memset(buf, 0x0, sizeof(buf)); memset(noise_index, 0x0, sizeof(noise_index)); if (ts->package_id < 3400) @@ -3032,7 +3032,7 @@ static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) finger_data[i][1]); input_mt_sync(ts->input_dev); } else if (ts->htc_event == SYN_AND_REPORT_TYPE_B) { -#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE last_touch_position_x = finger_data[i][0]; last_touch_position_y = finger_data[i][1]; @@ -3041,7 +3041,7 @@ static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) finger_data[i][0] = -10; finger_data[i][1] = -10; } -#endif +#endif if (ts->support_htc_event) { input_report_abs(ts->input_dev, ABS_MT_AMPLITUDE, finger_data[i][3] << 16 | finger_data[i][2]); @@ -3427,14 +3427,19 @@ static irqreturn_t synaptics_irq_thread(int irq, void *ptr) } } } + if (buf & get_address_base(ts, 0x1A, INTR_SOURCE)) { - if (s2w_switch == 0) { - if (!ts->finger_count) +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + if (s2w_switch == 0) { +#endif + if (!ts->finger_count) synaptics_ts_button_func(ts); +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE } else { // printk("[TP] Ignore VK interrupt due to 2d points did not leave\n"); synaptics_ts_button_func(ts); } +#endif } if (buf & get_address_base(ts, 0x01, INTR_SOURCE)) synaptics_ts_status_func(ts); @@ -4251,10 +4256,10 @@ static int synaptics_ts_probe( atomic_set(&ts->syn_fw_condition, 0); kthread_run(syn_fw_update_init, (void *)ts, "SYN_FW_UPDATE"); } - +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE //l2w wake_lock_init(&l2w_wakelock, WAKE_LOCK_SUSPEND, "l2w_wakelock"); - +#endif kthread_run(syn_probe_init, (void *)ts, "SYN_PROBE_INIT"); return 0; @@ -4281,9 +4286,10 @@ static int synaptics_ts_remove(struct i2c_client *client) if(ts->sr_input_dev != NULL) input_unregister_device(ts->sr_input_dev); input_unregister_device(ts->input_dev); +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE //l2w wake_lock_destroy(&l2w_wakelock); - +#endif synaptics_touch_sysfs_remove(); if(ts->report_data != NULL) @@ -4306,14 +4312,16 @@ static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg) #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE if (s2w_switch || dt2w_switch || l2w_switch || gestures_switch) { //screen off, enable_irq_wake + printk(KERN_INFO "[TP] %s: enter\n", "enable_irq_wake"); enable_irq_wake(client->irq); } #endif - + printk(KERN_INFO "[TP] %s: enter\n", "if (ts->use_irq) {"); if (ts->use_irq) { #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE if (!s2w_switch && !dt2w_switch && !l2w_switch && !gestures_switch) { #endif + printk(KERN_INFO "[TP] %s: enter\n", "disable_irq(client->irq);"); disable_irq(client->irq); ts->irq_enabled = 0; #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE @@ -4324,6 +4332,7 @@ static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg) ret = cancel_work_sync(&ts->work); #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE if (!s2w_switch && !dt2w_switch && !l2w_switch && !gestures_switch) { + printk(KERN_INFO "[TP] %s: enter\n", "enable_irq(client->irq);"); if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */ enable_irq(client->irq); } @@ -4528,6 +4537,7 @@ static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg) scr_suspended = true; reset_sv2w(); reset_sh2w(); + printk(KERN_INFO "[TP] %s: all reseted\n", __func__); #endif if ((ts->block_touch_time_near | ts->block_touch_time_far) && ts->block_touch_event) { syn_handle_block_touch(ts, 0); From 90a0a3d02cc14d9b516ec6fbb800c2b90c35e540 Mon Sep 17 00:00:00 2001 From: Andrey Voloshin Date: Thu, 10 Jul 2014 10:46:03 +0300 Subject: [PATCH 3/4] i2c issue workaround, fixes reboots removed logo2* functions (we have home button at that place) Signed-off-by: Andrey Voloshin --- drivers/input/touchscreen/synaptics_3200.c | 346 +++++---------------- 1 file changed, 79 insertions(+), 267 deletions(-) diff --git a/drivers/input/touchscreen/synaptics_3200.c b/drivers/input/touchscreen/synaptics_3200.c index 90b0f468..ae4a95d3 100644 --- a/drivers/input/touchscreen/synaptics_3200.c +++ b/drivers/input/touchscreen/synaptics_3200.c @@ -208,10 +208,8 @@ static void syn_handle_block_touch(struct synaptics_ts_data *ts, int enable) #define S2W_TIMEOUT 30 #define S2W_TIMEOUT2 60 #define S2W_TIMEOUT3 50 -#define L2M_TIMEOUT 30 -#define DT2W_TIMEOUT_MAX 400 +#define DT2W_TIMEOUT_MAX 600 #define DT2W_DELTA 230 -#define L2W_TIMEOUT 50 #define WAKE_GESTURE 0x0b #define SWEEP_RIGHT 0x01 @@ -224,13 +222,10 @@ static int button_id = 0; static int s2w_switch = 15; static int s2s_switch = 2; static int gestures_switch = 1; -static int l2m_switch = 1; -static int l2w_switch = 0; static int dt2w_switch = 1; static int pocket_detect = 1; static int s2w_hist[2] = {0, 0}; static unsigned long s2w_time[3] = {0, 0, 0}; -static unsigned long l2m_time[2] = {0, 0}; static unsigned long pwrtrigger_time[2] = {0, 0}; static bool barriery[2] = {false, false}, exec_county = true; static bool barrierx[2] = {false, false}, exec_countx = true; @@ -238,7 +233,6 @@ static int firstx = 0, firsty = 0; static unsigned long firsty_time = 0, firstx_time = 0; static int wakesleep_vib = 0; static int vib_strength = 15; -static int break_longtap_count = 0; static struct wake_lock l2w_wakelock; @@ -255,7 +249,6 @@ extern uint8_t touchscreen_is_on(void) static struct input_dev * sweep2wake_pwrdev; static DEFINE_MUTEX(pwrkeyworklock); -static DEFINE_MUTEX(longtap_count_lock); static void report_gesture(int gest) { @@ -299,9 +292,6 @@ static void sweep2wake_presspwr(struct work_struct * sweep2wake_presspwr_work) { } } - if (l2w_switch == 1) - break_longtap_count = 1; - if (wakesleep_vib) { vibrate(vib_strength); wakesleep_vib = 0; @@ -338,99 +328,6 @@ void sweep2wake_pwrtrigger(void) { return; } -static void logo2menu_pressmenu(struct work_struct * logo2menu_pressmenu_work) { - struct synaptics_ts_data *ts = gl_ts; - - if (l2w_switch == 1) - break_longtap_count = 1; - - input_event(ts->input_dev, EV_KEY, KEY_MENU, 1); - input_sync(ts->input_dev); - msleep(60); - input_event(ts->input_dev, EV_KEY, KEY_MENU, 0); - input_sync(ts->input_dev); - msleep(60); - return; -} - -static DECLARE_WORK(logo2menu_pressmenu_work, logo2menu_pressmenu); - -void logo2menu_menutrigger(void) { - schedule_work(&logo2menu_pressmenu_work); - return; -} - -static int allow_longtap_count = 1; - -static void logo2wake_longtap_count(struct work_struct * logo2wake_longtap_count_work) -{ - unsigned long time_count = 0; - - if (!mutex_trylock(&longtap_count_lock)) - return; - - time_count = jiffies; - - if (scr_suspended) - wake_lock_timeout(&l2w_wakelock, HZ/3); - - for (;;) { - - if (break_longtap_count) { - if (wake_lock_active(&l2w_wakelock)) - wake_unlock(&l2w_wakelock); - pr_debug("[L2W] breaking longtap count work...\n"); - break_longtap_count = 0; - mutex_unlock(&longtap_count_lock); - return; - } - - if (jiffies - time_count > L2W_TIMEOUT) { - pr_debug("[L2W] counted to longtap time!\n"); - if (wake_lock_active(&l2w_wakelock)) - wake_unlock(&l2w_wakelock); - break; - } - msleep(3); - } - if (!break_longtap_count) { - - time_count = 0; - pr_debug(KERN_INFO "[L2W] sending event KEY_POWER 1\n"); - if ((pocket_detect && !pocket_detection_check()) || !pocket_detect) { - if (gestures_switch && scr_suspended) { - report_gesture(6); - } else if (l2w_switch) { - vibrate(vib_strength); - input_event(sweep2wake_pwrdev, EV_KEY, KEY_POWER, 1); - input_sync(sweep2wake_pwrdev); - msleep(100); - input_event(sweep2wake_pwrdev, EV_KEY, KEY_POWER, 0); - input_sync(sweep2wake_pwrdev); - msleep(100); - } - } - } - - mutex_unlock(&longtap_count_lock); - return; -} - -static DECLARE_WORK(logo2wake_longtap_count_work, logo2wake_longtap_count); - -void logo2wake_longtap_count_trigger(void) -{ - break_longtap_count = 0; - if (allow_longtap_count) { - allow_longtap_count = 0; - pr_debug("[L2W] starting longtap count work\n"); - schedule_work(&logo2wake_longtap_count_work); - } else { - pr_debug("[L2W] not longtap count work - not allowed (waiting for finger release)\n"); - } - return; -} - #endif static void syn_page_select(struct i2c_client *client, uint8_t page) @@ -2042,44 +1939,6 @@ static DEVICE_ATTR(doubletap2wake, (S_IWUSR|S_IRUGO), synaptics_doubletap2wake_show, synaptics_doubletap2wake_dump); -static ssize_t synaptics_logo2menu_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - size_t count = 0; - count += sprintf(buf, "%d\n", l2m_switch); - return count; -} - -static ssize_t synaptics_logo2menu_dump(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - if (buf[0] >= '0' && buf[0] <= '1' && buf[1] == '\n') - if (l2m_switch != buf[0] - '0') { - l2m_switch = buf[0] - '0'; - } - return count; -} - -static DEVICE_ATTR(logo2menu, (S_IWUSR|S_IRUGO), - synaptics_logo2menu_show, synaptics_logo2menu_dump); - -static ssize_t synaptics_logo2wake_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - size_t count = 0; - count += sprintf(buf, "%d\n", l2w_switch); - return count; -} - -static ssize_t synaptics_logo2wake_dump(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -{ - if (buf[0] >= '0' && buf[0] <= '1' && buf[1] == '\n') - if (l2w_switch != buf[0] - '0') { - l2w_switch = buf[0] - '0'; - } - return count; -} - -static DEVICE_ATTR(logo2wake, (S_IWUSR|S_IRUGO), - synaptics_logo2wake_show, synaptics_logo2wake_dump); - static ssize_t synaptics_pocket_detect_show(struct device *dev, struct device_attribute *attr, char *buf) { size_t count = 0; @@ -2263,16 +2122,6 @@ static int synaptics_touch_sysfs_init(void) printk(KERN_ERR "%s: sysfs_create_file failed\n", __func__); return ret; } - ret = sysfs_create_file(android_touch_kobj, &dev_attr_logo2menu.attr); - if (ret) { - printk(KERN_ERR "%s: sysfs_create_file failed\n", __func__); - return ret; - } - ret = sysfs_create_file(android_touch_kobj, &dev_attr_logo2wake.attr); - if (ret) { - printk(KERN_ERR "%s: sysfs_create_file failed\n", __func__); - return ret; - } ret = sysfs_create_file(android_touch_kobj, &dev_attr_pocket_detect.attr); if (ret) { @@ -2338,8 +2187,6 @@ static void synaptics_touch_sysfs_remove(void) sysfs_remove_file(android_touch_kobj, &dev_attr_sweep2sleep.attr); sysfs_remove_file(android_touch_kobj, &dev_attr_wake_gestures.attr); sysfs_remove_file(android_touch_kobj, &dev_attr_doubletap2wake.attr); - sysfs_remove_file(android_touch_kobj, &dev_attr_logo2menu.attr); - sysfs_remove_file(android_touch_kobj, &dev_attr_logo2wake.attr); sysfs_remove_file(android_touch_kobj, &dev_attr_pocket_detect.attr); sysfs_remove_file(android_touch_kobj, &dev_attr_vib_strength.attr); #endif @@ -2482,16 +2329,16 @@ static void sweep2wake_vert_func(int x, int y) if ((x > 100 && x < 1500) && (gestures_switch || (s2w_switch & SWEEP_UP))) { if (firsty > 1500) { prevy = firsty; - nexty = prevy - 170; + nexty = prevy - 160; if (barriery[0] == true || (y < prevy && y > nexty)) { prevy = nexty; - nexty -= 200; + nexty -= 180; barriery[0] = true; if (barriery[1] == true || (y < prevy && y > nexty)) { prevy = nexty; barriery[1] = true; if (y < prevy) { - if (y < (nexty - 170)) { + if (y < (nexty - 160)) { if (exec_county && (jiffies - firsty_time < S2W_TIMEOUT)) { pr_debug("wake_gesture: sweep up\n"); wake_lock_timeout(&l2w_wakelock, HZ/2); @@ -2510,16 +2357,16 @@ static void sweep2wake_vert_func(int x, int y) //sweep down } else if ((firsty <= 1500) && (gestures_switch || (s2w_switch & SWEEP_DOWN))) { prevy = firsty; - nexty = prevy + 170; + nexty = prevy + 160; if (barriery[0] == true || (y > prevy && y < nexty)) { prevy = nexty; - nexty += 200; + nexty += 180; barriery[0] = true; if (barriery[1] == true || (y > prevy && y < nexty)) { prevy = nexty; barriery[1] = true; if (y > prevy) { - if (y > (nexty + 170)) { + if (y > (nexty + 160)) { if (exec_county && (jiffies - firsty_time < S2W_TIMEOUT)) { pr_debug("wake_gesture: sweep down\n"); wake_lock_timeout(&l2w_wakelock, HZ/2); @@ -2661,39 +2508,23 @@ static void sweep2wake_func(int button_id) { } } -static void logo2menu_func(void) { - - if (l2m_switch == 1 && scr_suspended == false && ((l2m_time[0]-l2m_time[1]) < L2M_TIMEOUT)) { - pr_debug("[L2M]: menu button activated\n"); - logo2menu_menutrigger(); - } - - return; -} - - static int last_touch_position_x = 0; static int last_touch_position_y = 0; -static int report_htc_logo_area(int x, int y) { - if (l2m_switch == 0 && l2w_switch == 0 && gestures_switch == 0) - return 0; +static cputime64_t prev_time; +static int prev_x = 0, prev_y = 0; - if (last_touch_position_x > 620 && last_touch_position_x < 1150) { - if (last_touch_position_y > 2835 || (scr_suspended == true && last_touch_position_y > 2750)) { - l2m_time[1] = l2m_time[0]; - l2m_time[0] = jiffies; - return 1; - } +static void dt2w_reset_handler(void) +{ + struct synaptics_ts_data *ts = gl_ts; + + if (ts->gpio_reset) { + gpio_direction_output(ts->gpio_reset, 0); + hr_msleep(1); + gpio_direction_output(ts->gpio_reset, 1); } - break_longtap_count=1; - return 0; } - -static cputime64_t prev_time; -static int prev_x = 0, prev_y = 0; - static void reset_dt2w(void) { prev_time = 0; @@ -2911,16 +2742,6 @@ static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) reset_sh2w(); } } - - if (l2m_switch || l2w_switch || gestures_switch) { - - // released (supposedly before long tap happened), break long tap count work... - break_longtap_count = 1; - // released, should allow logo long tap counting again... - allow_longtap_count = 1; - if (report_htc_logo_area(last_touch_position_x,last_touch_position_x)) - logo2menu_func(); - } } #endif if (ts->pre_finger_data[0][0] < 2 || finger_pressed) { @@ -3033,10 +2854,9 @@ static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) input_mt_sync(ts->input_dev); } else if (ts->htc_event == SYN_AND_REPORT_TYPE_B) { #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - last_touch_position_x = finger_data[i][0]; - last_touch_position_y = finger_data[i][1]; + last_touch_position_x = finger_data[i][0]; + last_touch_position_y = finger_data[i][1]; - if (!report_htc_logo_area(last_touch_position_x,last_touch_position_y)) { if (scr_suspended && phone_call_stat == 1) { finger_data[i][0] = -10; finger_data[i][1] = -10; @@ -3062,13 +2882,6 @@ static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) finger_data[i][0]); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, finger_data[i][1]); -#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - } else { - if (l2w_switch == 1 || gestures_switch) { - logo2wake_longtap_count_trigger(); - } - } -#endif } else if (ts->htc_event == SYN_AND_REPORT_TYPE_HTC) { input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, i); input_report_abs(ts->input_dev, ABS_MT_AMPLITUDE, @@ -3239,7 +3052,6 @@ static void synaptics_ts_button_func(struct synaptics_ts_data *ts) vk_press = 1; #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - break_longtap_count = 1; last_touch_position_x = 0; last_touch_position_y = 0; button_id = 1; @@ -3284,7 +3096,6 @@ static void synaptics_ts_button_func(struct synaptics_ts_data *ts) vk_press = 1; #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - break_longtap_count = 1; last_touch_position_x = 0; last_touch_position_y = 0; button_id = 2; @@ -3416,6 +3227,11 @@ static irqreturn_t synaptics_irq_thread(int irq, void *ptr) if (ret < 0) { i2c_syn_error_handler(ts, ts->i2c_err_handler_en, "r", __func__); } else { +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + if (!buf) { + dt2w_reset_handler(); + } +#endif if (buf & get_address_base(ts, ts->finger_func_idx, INTR_SOURCE)) { if (!vk_press) { synaptics_ts_finger_func(ts); @@ -4310,18 +4126,16 @@ static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg) printk(KERN_INFO "[TP] %s: enter\n", __func__); #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - if (s2w_switch || dt2w_switch || l2w_switch || gestures_switch) { + if (s2w_switch || dt2w_switch || gestures_switch) { //screen off, enable_irq_wake - printk(KERN_INFO "[TP] %s: enter\n", "enable_irq_wake"); enable_irq_wake(client->irq); } #endif - printk(KERN_INFO "[TP] %s: enter\n", "if (ts->use_irq) {"); + if (ts->use_irq) { #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - if (!s2w_switch && !dt2w_switch && !l2w_switch && !gestures_switch) { + if (!s2w_switch && !dt2w_switch && !gestures_switch) { #endif - printk(KERN_INFO "[TP] %s: enter\n", "disable_irq(client->irq);"); disable_irq(client->irq); ts->irq_enabled = 0; #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE @@ -4331,11 +4145,10 @@ static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg) hrtimer_cancel(&ts->timer); ret = cancel_work_sync(&ts->work); #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - if (!s2w_switch && !dt2w_switch && !l2w_switch && !gestures_switch) { - printk(KERN_INFO "[TP] %s: enter\n", "enable_irq(client->irq);"); - if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */ - enable_irq(client->irq); - } + if (!s2w_switch && !dt2w_switch && !gestures_switch) { + if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */ + enable_irq(client->irq); + } #endif } @@ -4502,42 +4315,41 @@ static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg) ts->disable_CBC = 0; } #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - if (!s2w_switch && !dt2w_switch && !l2w_switch && !gestures_switch) { -#endif - if (ts->power) - ts->power(0); - else { - if (ts->packrat_number >= SYNAPTICS_FW_2IN1_PACKRAT) { - ret = i2c_syn_write_byte_data(client, - get_address_base(ts, 0x01, CONTROL_BASE), 0x01); - if (ret < 0) - i2c_syn_error_handler(ts, ts->i2c_err_handler_en, "sleep: 0x01", __func__); - } else { - if ((ts->psensor_status & PSENSOR_STATUS) > 0 -#ifdef CONFIG_PWRKEY_STATUS_API - && getPowerKeyState() == 0 + if (!s2w_switch && !dt2w_switch && !gestures_switch) { #endif - ) { - ret = i2c_syn_write_byte_data(client, - get_address_base(ts, 0x01, CONTROL_BASE), 0x02); - if (ret < 0) - i2c_syn_error_handler(ts, ts->i2c_err_handler_en, "sleep: 0x02", __func__); - } else { + if (ts->power) + ts->power(0); + else { + if (ts->packrat_number >= SYNAPTICS_FW_2IN1_PACKRAT) { ret = i2c_syn_write_byte_data(client, get_address_base(ts, 0x01, CONTROL_BASE), 0x01); if (ret < 0) i2c_syn_error_handler(ts, ts->i2c_err_handler_en, "sleep: 0x01", __func__); + } else { + if ((ts->psensor_status & PSENSOR_STATUS) > 0 +#ifdef CONFIG_PWRKEY_STATUS_API + && getPowerKeyState() == 0 +#endif + ) { + ret = i2c_syn_write_byte_data(client, + get_address_base(ts, 0x01, CONTROL_BASE), 0x02); + if (ret < 0) + i2c_syn_error_handler(ts, ts->i2c_err_handler_en, "sleep: 0x02", __func__); + } else { + ret = i2c_syn_write_byte_data(client, + get_address_base(ts, 0x01, CONTROL_BASE), 0x01); + if (ret < 0) + i2c_syn_error_handler(ts, ts->i2c_err_handler_en, "sleep: 0x01", __func__); + } } + if (ts->lpm_power) + ts->lpm_power(1); } - if (ts->lpm_power) - ts->lpm_power(1); - } #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE } scr_suspended = true; reset_sv2w(); reset_sh2w(); - printk(KERN_INFO "[TP] %s: all reseted\n", __func__); #endif if ((ts->block_touch_time_near | ts->block_touch_time_far) && ts->block_touch_event) { syn_handle_block_touch(ts, 0); @@ -4553,29 +4365,29 @@ static int synaptics_ts_resume(struct i2c_client *client) #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE //screen on, disable_irq_wake - if (s2w_switch || dt2w_switch || l2w_switch || gestures_switch) + if (s2w_switch || dt2w_switch || gestures_switch) disable_irq_wake(client->irq); - if (!s2w_switch && !dt2w_switch && !l2w_switch && !gestures_switch) { + if (!s2w_switch && !dt2w_switch && !gestures_switch) { #endif - if (ts->power) { - ts->power(1); - hr_msleep(100); + if (ts->power) { + ts->power(1); + hr_msleep(100); #ifdef SYN_CABLE_CONTROL - if (ts->cable_support) { - if (usb_get_connect_type()) - cable_tp_status_handler_func(1); - printk(KERN_INFO "%s: ts->cable_config: %x\n", __func__, ts->cable_config); - } + if (ts->cable_support) { + if (usb_get_connect_type()) + cable_tp_status_handler_func(1); + printk(KERN_INFO "%s: ts->cable_config: %x\n", __func__, ts->cable_config); + } #endif - } else { - if (ts->lpm_power) - ts->lpm_power(0); - ret = i2c_syn_write_byte_data(client, - get_address_base(ts, 0x01, CONTROL_BASE), 0x00); - if (ret < 0) - i2c_syn_error_handler(ts, ts->i2c_err_handler_en, "wake up", __func__); - } + } else { + if (ts->lpm_power) + ts->lpm_power(0); + ret = i2c_syn_write_byte_data(client, + get_address_base(ts, 0x01, CONTROL_BASE), 0x00); + if (ret < 0) + i2c_syn_error_handler(ts, ts->i2c_err_handler_en, "wake up", __func__); + } #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE } #endif @@ -4605,14 +4417,14 @@ static int synaptics_ts_resume(struct i2c_client *client) } } #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - if (!s2w_switch && !dt2w_switch && !l2w_switch && !gestures_switch) { + if (!s2w_switch && !dt2w_switch && !gestures_switch) { #endif - if (ts->use_irq) { - enable_irq(client->irq); - ts->irq_enabled = 1; - } - else - hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); + if (ts->use_irq) { + enable_irq(client->irq); + ts->irq_enabled = 1; + } + else + hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE } scr_suspended = false; From c73de4d82cc250ee48d015ed630cc127c14c12db Mon Sep 17 00:00:00 2001 From: Andrey Voloshin Date: Sat, 19 Jul 2014 06:10:53 +0300 Subject: [PATCH 4/4] s2w s2s fixes, code cleanup --- drivers/input/touchscreen/synaptics_3200.c | 408 ++++++++------------- 1 file changed, 145 insertions(+), 263 deletions(-) diff --git a/drivers/input/touchscreen/synaptics_3200.c b/drivers/input/touchscreen/synaptics_3200.c index ae4a95d3..f5f0084f 100644 --- a/drivers/input/touchscreen/synaptics_3200.c +++ b/drivers/input/touchscreen/synaptics_3200.c @@ -218,7 +218,6 @@ static void syn_handle_block_touch(struct synaptics_ts_data *ts, int enable) #define SWEEP_DOWN 0x08 static bool scr_suspended = false; -static int button_id = 0; static int s2w_switch = 15; static int s2s_switch = 2; static int gestures_switch = 1; @@ -284,7 +283,7 @@ EXPORT_SYMBOL(sweep2wake_setdev); static void sweep2wake_presspwr(struct work_struct * sweep2wake_presspwr_work) { - if (scr_suspended == true && pocket_detect == 1) { + if (scr_suspended && pocket_detect) { if (pocket_detection_check()) { if (wake_lock_active(&l2w_wakelock)) wake_unlock(&l2w_wakelock); @@ -299,13 +298,14 @@ static void sweep2wake_presspwr(struct work_struct * sweep2wake_presspwr_work) { if (!mutex_trylock(&pwrkeyworklock)) return; + input_event(sweep2wake_pwrdev, EV_KEY, KEY_POWER, 1); input_event(sweep2wake_pwrdev, EV_SYN, 0, 0); msleep(60); input_event(sweep2wake_pwrdev, EV_KEY, KEY_POWER, 0); input_event(sweep2wake_pwrdev, EV_SYN, 0, 0); msleep(60); - mutex_unlock(&pwrkeyworklock); + mutex_unlock(&pwrkeyworklock); if (wake_lock_active(&l2w_wakelock)) wake_unlock(&l2w_wakelock); @@ -2318,15 +2318,18 @@ static void reset_sv2w(void) static void sweep2wake_vert_func(int x, int y) { int prevy = 0, nexty = 0; - + if (!scr_suspended || (!gestures_switch && !(s2w_switch & SWEEP_UP) && !(s2w_switch & SWEEP_DOWN))){ + return; + } + if (firsty == 0) { firsty = y; firsty_time = jiffies; } - if (firsty > 2279) + if (firsty > 2000) reset_sv2w(); //sweep up - if ((x > 100 && x < 1500) && (gestures_switch || (s2w_switch & SWEEP_UP))) { + if (x > 100 && x < 1500) { if (firsty > 1500) { prevy = firsty; nexty = prevy - 160; @@ -2340,11 +2343,11 @@ static void sweep2wake_vert_func(int x, int y) if (y < prevy) { if (y < (nexty - 160)) { if (exec_county && (jiffies - firsty_time < S2W_TIMEOUT)) { - pr_debug("wake_gesture: sweep up\n"); + printk("[TP]: sweep up\n"); wake_lock_timeout(&l2w_wakelock, HZ/2); if (gestures_switch) { report_gesture(3); - } else { + } else if (s2w_switch & SWEEP_UP) { wakesleep_vib = 1; sweep2wake_pwrtrigger(); } @@ -2355,7 +2358,8 @@ static void sweep2wake_vert_func(int x, int y) } } //sweep down - } else if ((firsty <= 1500) && (gestures_switch || (s2w_switch & SWEEP_DOWN))) { + } + else if (firsty <= 1500) { prevy = firsty; nexty = prevy + 160; if (barriery[0] == true || (y > prevy && y < nexty)) { @@ -2368,11 +2372,11 @@ static void sweep2wake_vert_func(int x, int y) if (y > prevy) { if (y > (nexty + 160)) { if (exec_county && (jiffies - firsty_time < S2W_TIMEOUT)) { - pr_debug("wake_gesture: sweep down\n"); + printk("[TP]: sweep down\n"); wake_lock_timeout(&l2w_wakelock, HZ/2); if (gestures_switch) { report_gesture(4); - } else { + } else if (s2w_switch & SWEEP_DOWN) { wakesleep_vib = 1; sweep2wake_pwrtrigger(); } @@ -2397,8 +2401,11 @@ static void reset_sh2w(void) static void sweep2wake_horiz_func(int x, int y) { - int prevx = 0, nextx = 0; + int prevx = 0, nextx = 0; + if (!scr_suspended || !gestures_switch) + return; + if (firstx == 0) { firstx = x; firstx_time = jiffies; @@ -2407,27 +2414,22 @@ static void sweep2wake_horiz_func(int x, int y) reset_sh2w(); //sweep right - if (firstx < 810 && (gestures_switch || (s2w_switch & SWEEP_RIGHT))) { + if (firstx < 810 && y < 2700) { prevx = firstx; nextx = prevx + 180; - if (barrierx[0] == true || (x > prevx && x < nextx)) { + if (barrierx[0] == true || (x > prevx && x < nextx && y < 2700 )) { prevx = nextx; nextx += 200; barrierx[0] = true; - if (barrierx[1] == true || (x > prevx && x < nextx)) { + if (barrierx[1] == true || (x > prevx && x < nextx && y < 2700 )) { prevx = nextx; barrierx[1] = true; - if (x > prevx) { + if (x > prevx && y < 2700 ) { if (x > (nextx + 180)) { if (exec_countx && (jiffies - firstx_time < S2W_TIMEOUT)) { - pr_debug("wake_gesture: sweep right\n"); + printk("[TP]: sweep right\n"); wake_lock_timeout(&l2w_wakelock, HZ/2); - if (gestures_switch) { - report_gesture(1); - } else { - wakesleep_vib = 1; - sweep2wake_pwrtrigger(); - } + report_gesture(1); exec_countx = false; } } @@ -2435,27 +2437,22 @@ static void sweep2wake_horiz_func(int x, int y) } } //sweep left - } else if (firstx >= 810 && y < 2790 && (gestures_switch || (s2w_switch & SWEEP_LEFT))) { + } else if (firstx >= 810 && y < 2700) { prevx = firstx; nextx = prevx - 180; - if ((barrierx[0] == true) ||(x < prevx && x > nextx && y < 2790)) { + if ((barrierx[0] == true) ||(x < prevx && x > nextx && y < 2700)) { prevx = nextx; nextx -= 200; barrierx[0] = true; - if ((barrierx[1] == true) || (x < prevx && x > nextx && y < 2790)) { + if ((barrierx[1] == true) || (x < prevx && x > nextx && y < 2700)) { prevx = nextx; barrierx[1] = true; - if (x < prevx && y < 2790) { + if (x < prevx && y < 2700) { if (x < (nextx - 180)) { if (exec_countx && (jiffies - firstx_time < S2W_TIMEOUT)) { - pr_debug("wake_gesture: sweep left\n"); + printk("[TP]: sweep left\n"); wake_lock_timeout(&l2w_wakelock, HZ/2); - if (gestures_switch) { - report_gesture(2); - } else { - wakesleep_vib = 1; - sweep2wake_pwrtrigger(); - } + report_gesture(2); exec_countx = false; } } @@ -2467,37 +2464,34 @@ static void sweep2wake_horiz_func(int x, int y) } static void sweep2wake_func(int button_id) { - - s2w_time[2] = s2w_time[1]; - s2w_time[1] = s2w_time[0]; - s2w_time[0] = jiffies; + if (!s2s_switch && + !(s2w_switch & SWEEP_RIGHT) && !(s2w_switch & SWEEP_LEFT)) { + return; + } + + s2w_time[2] = s2w_time[1]; + s2w_time[1] = s2w_time[0]; + s2w_time[0] = jiffies; s2w_hist[1] = s2w_hist[0]; s2w_hist[0] = button_id; - if ((s2w_time[0]-s2w_time[2]) < S2W_TIMEOUT2 && !scr_suspended) { - printk("[S2W]: canceled by timeout2\n"); - return; - } - if ((s2w_time[0]-s2w_time[1]) < S2W_TIMEOUT && (s2w_time[0]-s2w_time[1]) > S2W_START) { if (s2w_hist[1] == 1 && s2w_hist[0] == 2) { - pr_debug("[S2W]: OFF->ON\n"); reset_sweep2wake(); - if (gestures_switch && scr_suspended) { - report_gesture(1); - } else if (((s2w_switch & SWEEP_RIGHT) && scr_suspended) || (!scr_suspended && (s2s_switch & SWEEP_RIGHT))) { + if ((scr_suspended && (s2w_switch & SWEEP_RIGHT)) || + (!scr_suspended && (s2s_switch & SWEEP_RIGHT))) { + printk("[S2W]: sweep right\n"); wakesleep_vib = 1; sweep2wake_pwrtrigger(); } } else if (s2w_hist[1] == 2 && s2w_hist[0] == 1) { reset_sweep2wake(); - if (gestures_switch && scr_suspended) { - report_gesture(2); - } else if (((s2w_switch & SWEEP_LEFT) && scr_suspended) || (!scr_suspended && (s2s_switch & SWEEP_LEFT))) { - pr_debug("[S2W]: ON->OFF\n"); + if ((scr_suspended && (s2w_switch & SWEEP_LEFT)) || + (!scr_suspended && (s2s_switch & SWEEP_LEFT))) { + printk("[S2W]: sweep left\n"); wakesleep_vib = 1; sweep2wake_pwrtrigger(); } @@ -2517,7 +2511,6 @@ static int prev_x = 0, prev_y = 0; static void dt2w_reset_handler(void) { struct synaptics_ts_data *ts = gl_ts; - if (ts->gpio_reset) { gpio_direction_output(ts->gpio_reset, 0); hr_msleep(1); @@ -2534,38 +2527,38 @@ static void reset_dt2w(void) static void dt2w_func(int x, int y, cputime64_t trigger_time) { - if ((x > 0 && x < 150) || x > 1470 || y > 2880 || (!gestures_switch && dt2w_switch == 1 && (y > 0 && y < 2100))) { - reset_dt2w(); - return; - } + if ((x > 0 && x < 150) || x > 1470 || y > 2700 || + (!gestures_switch && dt2w_switch == 1 && (y > 0 && y < 2100))) { + reset_dt2w(); + return; + } - if (prev_time == 0) { - prev_time = trigger_time; - prev_x = x; - prev_y = y; - } else if ((trigger_time - prev_time) > DT2W_TIMEOUT_MAX) { - prev_time = trigger_time; - prev_x = x; - prev_y = y; - } else { - if (((abs(x - prev_x) < DT2W_DELTA) && (abs(y - prev_y) < DT2W_DELTA)) - || (prev_x == 0 && prev_y == 0)) { - reset_dt2w(); + if (prev_time == 0) { + prev_time = trigger_time; + prev_x = x; + prev_y = y; + } else if ((trigger_time - prev_time) > DT2W_TIMEOUT_MAX) { + prev_time = trigger_time; + prev_x = x; + prev_y = y; + } else { + if (((abs(x - prev_x) < DT2W_DELTA) && (abs(y - prev_y) < DT2W_DELTA)) + || (prev_x == 0 && prev_y == 0)) { + reset_dt2w(); pr_debug("[DT2W]: ON\n"); wake_lock_timeout(&l2w_wakelock, HZ/2); if (gestures_switch) { report_gesture(5); } else { - wakesleep_vib = 1; - sweep2wake_pwrtrigger(); + wakesleep_vib = 1; + sweep2wake_pwrtrigger(); } - - } else { + } else { prev_time = trigger_time; prev_x = x; prev_y = y; - } - } + } + } } #endif @@ -2602,12 +2595,7 @@ static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) if (ts->package_id < 3400) base = (ts->finger_support + 3) / 4; ts->finger_count = 0; - if (ts->debug_log_level & BIT(0)) { - printk(KERN_INFO "[TP] Touch:"); - for (i = 0; i < sizeof(buf); i++) - printk(KERN_INFO " %2x", buf[i]); - printk(KERN_INFO "\n"); - } + for (i = 0; i < ts->finger_support; i++) { uint8_t finger_state; if (ts->package_id < 3400) @@ -2639,54 +2627,6 @@ static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) ts->finger_pressed = finger_pressed; } - if(ts->debug_log_level & BIT(3)) { - for(i = 0; i < ts->finger_support; i++) { - if (finger_release_changed & BIT(i) ) { - if (ts->package_id < 3400) { - uint32_t flip_flag = SYNAPTICS_FLIP_X; - uint8_t pos_mask = 0x0f; - for (j = 0; j < 2; j++) { - finger_data[i][j] - = (buf[base+2] & pos_mask) >> (j * 4) | - (uint16_t)buf[base + j] << 4; - if (ts->flags & flip_flag) - finger_data[i][j] = ts->max[j] - finger_data[i][j]; - flip_flag <<= 1; - pos_mask <<= 4; - } - finger_data[i][2] = (buf[base+3] >> 4 & 0x0F) + (buf[base+3] & 0x0F); - finger_data[i][3] = buf[base+4]; - } else { - finger_data[i][0] = (buf[base+2] << 8) + buf[base+1]; - finger_data[i][1] = (buf[base+4] << 8) + buf[base+3]; - finger_data[i][2] = buf[base+6] + buf[base+7]; - finger_data[i][3] = buf[base+5]; - } - - if (ts->flags & SYNAPTICS_SWAP_XY) - swap(finger_data[i][0], finger_data[i][1]); - - if (ts->layout[1] < finger_data[i][0]) - finger_data[i][0] = ts->layout[1]; - if(ts->width_factor && ts->height_factor){ - pr_debug( - "[TP] Screen:F[%02d]:Up, X=%d, Y=%d, W=%d, Z=%d, IM:%d, CIDIM:%d, Freq:%d, NS:%d\n", - i+1, (x_pos[i]*ts->width_factor)>>SHIFT_BITS, - (y_pos[i]*ts->height_factor)>>SHIFT_BITS, - finger_data[i][2], finger_data[i][3], - temp_im, temp_cidim, noise_index[9], noise_index[4]); - } else { - printk(KERN_INFO - "[TP] Raw:F[%02d]:Up, X=%d, Y=%d, W=%d, Z=%d, IM:%d, CIDIM:%d, Freq:%d, NS:%d\n", - i+1, x_pos[i], y_pos[i], - finger_data[i][2], finger_data[i][3], - temp_im, temp_cidim, noise_index[9], noise_index[4]); - } - } - base += 5; - } - } - if (ts->htc_event == SYN_AND_REPORT_TYPE_B && finger_release_changed) { for (i = 0; i < ts->finger_support; i++) { if (finger_release_changed & BIT(i)) { @@ -2697,8 +2637,7 @@ static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) } } - if (finger_pressed == 0 -) { + if (finger_pressed == 0) { if (ts->htc_event == SYN_AND_REPORT_TYPE_A) { if (ts->support_htc_event) { @@ -2729,20 +2668,19 @@ static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) } #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - if (((ts->finger_count > 0)?1:0) == 0) { - - if (scr_suspended == true) { - if (dt2w_switch || gestures_switch) { - dt_trigger_time = ktime_to_ms(ktime_get()); - dt2w_func(last_touch_position_x, last_touch_position_y, dt_trigger_time); - } + if (((ts->finger_count > 0)?1:0) == 0) { + if (scr_suspended) { + if (gestures_switch || dt2w_switch) { + dt_trigger_time = ktime_to_ms(ktime_get()); + dt2w_func(last_touch_position_x, last_touch_position_y, dt_trigger_time); + } - if (gestures_switch || s2w_switch) { - reset_sv2w(); - reset_sh2w(); + if (gestures_switch || s2w_switch) { + reset_sv2w(); + reset_sh2w(); + } } - } - } + } #endif if (ts->pre_finger_data[0][0] < 2 || finger_pressed) { if (ts->package_id < 3400) @@ -2896,10 +2834,14 @@ static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) finger_pressed &= ~BIT(i); #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - if (gestures_switch && scr_suspended) + if (scr_suspended){ sweep2wake_horiz_func(x_pos[0], y_pos[0]); - if ((gestures_switch || s2w_switch) && scr_suspended) sweep2wake_vert_func(x_pos[0], y_pos[0]); + } + if (y_pos[i] > 2700 && x_pos[i] < 500) + sweep2wake_func(1); // back button + else if (y_pos[i] > 2700 && x_pos[i] > 1100) + sweep2wake_func(2); // apps button #endif if ((finger_press_changed & BIT(i)) && ts->debug_log_level & BIT(3)) { @@ -2958,18 +2900,6 @@ static void synaptics_ts_finger_func(struct synaptics_ts_data *ts) ts->tap_timeout[i] = jiffies + msecs_to_jiffies(ts->reduce_report_level[TAP_TIMEOUT]); } } - - if (ts->debug_log_level & BIT(1)) - printk(KERN_INFO - "[TP] Finger %d=> X:%d, Y:%d W:%d, Z:%d\n", - i + 1, finger_data[i][0], finger_data[i][1], - finger_data[i][2], finger_data[i][3]); - if (ts->debug_log_level & BIT(17)) - printk(KERN_INFO - "[TP] Finger %d=> X:%d, Y:%d W:%d, Z:%d, IM:%d, CIDIM:%d, Freq:%d, NS:%d\n", - i + 1, finger_data[i][0], finger_data[i][1], finger_data[i][2], - finger_data[i][3], noise_index[1] | noise_index[0], - noise_index[6] | noise_index[5], noise_index[9], noise_index[4]); } if (ts->packrat_number < SYNAPTICS_FW_NOCAL_PACKRAT) { @@ -3041,112 +2971,70 @@ static void synaptics_ts_report_func(struct synaptics_ts_data *ts) static void synaptics_ts_button_func(struct synaptics_ts_data *ts) { int ret; - uint8_t data = 0; + uint8_t data = 0, idx = 0; uint16_t x_position = 0, y_position = 0; - +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + if (scr_suspended) return; +#endif ret = i2c_syn_read(ts->client, get_address_base(ts, 0x1A, DATA_BASE), &data, 1); if (data) { - if (data & 0x01) { - printk("[TP] back key pressed\n"); - vk_press = 1; - -#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - last_touch_position_x = 0; - last_touch_position_y = 0; - button_id = 1; -#endif - - if (ts->button) { - if (ts->button[0].index) { - x_position = (ts->button[0].x_range_min + ts->button[0].x_range_max) / 2; - y_position = (ts->button[0].y_range_min + ts->button[0].y_range_max) / 2; - } - } - if (ts->htc_event == SYN_AND_REPORT_TYPE_B) { -#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - if (!scr_suspended) { -#endif - if (ts->support_htc_event) { - input_report_abs(ts->input_dev, ABS_MT_AMPLITUDE, - 100 << 16 | 100); - input_report_abs(ts->input_dev, ABS_MT_POSITION, - x_position << 16 | y_position); - } - input_mt_slot(ts->input_dev, 0); - input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, - 1); - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, - 100); - input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, - 100); - input_report_abs(ts->input_dev, ABS_MT_PRESSURE, - 100); - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, - x_position); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, - y_position); -#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - } -#endif + vk_press = 1; + if (ts->button) { + idx = (data == 0x01 ? 0: + data == 0x02 ? 1: + data == 0x04 ? 2: + 100); + + if (idx == 100) { + vk_press = 0; + pr_err("[TP] vk_data:%#x, idx=%d", data, idx); + return; } + x_position = (ts->button[idx].x_range_min + ts->button[idx].x_range_max) / 2; + y_position = (ts->button[idx].y_range_min + ts->button[idx].y_range_max) / 2; } - else if (data & 0x02) { - printk("[TP] home key pressed\n"); - vk_press = 1; - -#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - last_touch_position_x = 0; - last_touch_position_y = 0; - button_id = 2; -#endif + data == 0x01 ? pr_info("[TP] back key pressed, vk=%x\n", data) : + data == 0x02 ? pr_info("[TP] home key pressed, vk=%x\n", data) : + data == 0x04 ? pr_info("[TP] app key pressed , vk=%x\n", data) : + pr_info("[TP] vk=%#x\n", data); - if (ts->button) { - if (ts->button[1].index) { - x_position = (ts->button[1].x_range_min + ts->button[1].x_range_max) / 2; - y_position = (ts->button[1].y_range_min + ts->button[1].y_range_max) / 2; - } - } - if (ts->htc_event == SYN_AND_REPORT_TYPE_B) { -#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - if (!scr_suspended) { -#endif - if (ts->support_htc_event) { - input_report_abs(ts->input_dev, ABS_MT_AMPLITUDE, - 100 << 16 | 100); - input_report_abs(ts->input_dev, ABS_MT_POSITION, - x_position << 16 | y_position); - } - input_mt_slot(ts->input_dev, 0); - input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, - 1); - input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, - 100); - input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, - 100); - input_report_abs(ts->input_dev, ABS_MT_PRESSURE, - 100); - input_report_abs(ts->input_dev, ABS_MT_POSITION_X, - x_position); - input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, - y_position); -#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - } -#endif - } + if (ts->support_htc_event) { + input_report_abs(ts->input_dev, ABS_MT_AMPLITUDE, 100 << 16 | 100); + input_report_abs(ts->input_dev, ABS_MT_POSITION, x_position << 16 | y_position); + } + switch (ts->htc_event) { + case SYN_AND_REPORT_TYPE_A: + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0); + break; + case SYN_AND_REPORT_TYPE_B: + input_mt_slot(ts->input_dev, 0); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 1); + break; + } + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 100); + input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 100); + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, 100); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x_position); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y_position); + switch (ts->htc_event) { + case SYN_AND_REPORT_TYPE_A: + input_mt_sync(ts->input_dev); + break; + case SYN_AND_REPORT_TYPE_B: + break; } - }else { + } else { printk("[TP] virtual key released\n"); vk_press = 0; - -#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - if (s2w_switch || s2s_switch || gestures_switch) { - sweep2wake_func(button_id); + if (ts->htc_event == SYN_AND_REPORT_TYPE_A) { + if (ts->support_htc_event) { + input_report_abs(ts->input_dev, ABS_MT_AMPLITUDE, 0); + input_report_abs(ts->input_dev, ABS_MT_POSITION, 1 << 31); + } + input_mt_sync(ts->input_dev); } - - if (!scr_suspended) { -#endif - if (ts->htc_event == SYN_AND_REPORT_TYPE_B) { + else if (ts->htc_event == SYN_AND_REPORT_TYPE_B) { if (ts->support_htc_event) { input_report_abs(ts->input_dev, ABS_MT_AMPLITUDE, 0); input_report_abs(ts->input_dev, ABS_MT_POSITION, 1 << 31); @@ -3154,17 +3042,8 @@ static void synaptics_ts_button_func(struct synaptics_ts_data *ts) input_mt_slot(ts->input_dev, 0); input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0); } -#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - } -#endif } -#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - if (!scr_suspended) { -#endif - input_sync(ts->input_dev); -#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE - } -#endif + input_sync(ts->input_dev); } static void synaptics_ts_status_func(struct synaptics_ts_data *ts) @@ -3205,6 +3084,8 @@ static void synaptics_ts_work_func(struct work_struct *work) synaptics_ts_finger_func(ts); if (buf & get_address_base(ts, 0x01, INTR_SOURCE)) synaptics_ts_status_func(ts); + if (buf & get_address_base(ts, 0x1A, INTR_SOURCE)) + synaptics_ts_button_func(ts); if (buf & get_address_base(ts, 0x54, INTR_SOURCE)) synaptics_ts_report_func(ts); } @@ -3239,7 +3120,7 @@ static irqreturn_t synaptics_irq_thread(int irq, void *ptr) getnstimeofday(&timeEnd); timeDelta.tv_nsec = (timeEnd.tv_sec*1000000000+timeEnd.tv_nsec) -(timeStart.tv_sec*1000000000+timeStart.tv_nsec); - printk(KERN_INFO "[TP] Touch latency = %ld us\n", timeDelta.tv_nsec/1000); + printk(KERN_DEBUG "[TP] Touch latency = %ld us\n", timeDelta.tv_nsec/1000); } } } @@ -3247,12 +3128,13 @@ static irqreturn_t synaptics_irq_thread(int irq, void *ptr) if (buf & get_address_base(ts, 0x1A, INTR_SOURCE)) { #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE if (s2w_switch == 0) { + printk(KERN_DEBUG "[TP] synaptics_ts_button_func 1\n"); #endif if (!ts->finger_count) synaptics_ts_button_func(ts); #ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE } else { -// printk("[TP] Ignore VK interrupt due to 2d points did not leave\n"); + printk(KERN_DEBUG "[TP] synaptics_ts_button_func 2\n"); synaptics_ts_button_func(ts); } #endif