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..f5f0084f 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,134 @@ 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 DT2W_TIMEOUT_MAX 600 +#define DT2W_DELTA 230 + +#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 s2w_switch = 15; +static int s2s_switch = 2; +static int gestures_switch = 1; +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 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 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 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 && pocket_detect) { + if (pocket_detection_check()) { + if (wake_lock_active(&l2w_wakelock)) + wake_unlock(&l2w_wakelock); + return; + } + } + + 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; +} + +#endif + static void syn_page_select(struct i2c_client *client, uint8_t page) { struct synaptics_ts_data *ts = i2c_get_clientdata(client); @@ -1720,6 +1856,132 @@ 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_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 +2101,41 @@ 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_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 +2182,14 @@ 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_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,13 +2304,273 @@ 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 (!scr_suspended || (!gestures_switch && !(s2w_switch & SWEEP_UP) && !(s2w_switch & SWEEP_DOWN))){ + return; + } + + if (firsty == 0) { + firsty = y; + firsty_time = jiffies; + } + if (firsty > 2000) + reset_sv2w(); + //sweep up + if (x > 100 && x < 1500) { + if (firsty > 1500) { + prevy = firsty; + nexty = prevy - 160; + if (barriery[0] == true || (y < prevy && y > nexty)) { + prevy = nexty; + nexty -= 180; + barriery[0] = true; + if (barriery[1] == true || (y < prevy && y > nexty)) { + prevy = nexty; + barriery[1] = true; + if (y < prevy) { + if (y < (nexty - 160)) { + if (exec_county && (jiffies - firsty_time < S2W_TIMEOUT)) { + printk("[TP]: sweep up\n"); + wake_lock_timeout(&l2w_wakelock, HZ/2); + if (gestures_switch) { + report_gesture(3); + } else if (s2w_switch & SWEEP_UP) { + wakesleep_vib = 1; + sweep2wake_pwrtrigger(); + } + exec_county = false; + } + } + } + } + } + //sweep down + } + else if (firsty <= 1500) { + prevy = firsty; + nexty = prevy + 160; + if (barriery[0] == true || (y > prevy && y < nexty)) { + prevy = nexty; + nexty += 180; + barriery[0] = true; + if (barriery[1] == true || (y > prevy && y < nexty)) { + prevy = nexty; + barriery[1] = true; + if (y > prevy) { + if (y > (nexty + 160)) { + if (exec_county && (jiffies - firsty_time < S2W_TIMEOUT)) { + printk("[TP]: sweep down\n"); + wake_lock_timeout(&l2w_wakelock, HZ/2); + if (gestures_switch) { + report_gesture(4); + } else if (s2w_switch & SWEEP_DOWN) { + 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 (!scr_suspended || !gestures_switch) + return; + + if (firstx == 0) { + firstx = x; + firstx_time = jiffies; + } + if (firstx > 1619) + reset_sh2w(); + + //sweep right + if (firstx < 810 && y < 2700) { + prevx = firstx; + nextx = prevx + 180; + 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 < 2700 )) { + prevx = nextx; + barrierx[1] = true; + if (x > prevx && y < 2700 ) { + if (x > (nextx + 180)) { + if (exec_countx && (jiffies - firstx_time < S2W_TIMEOUT)) { + printk("[TP]: sweep right\n"); + wake_lock_timeout(&l2w_wakelock, HZ/2); + report_gesture(1); + exec_countx = false; + } + } + } + } + } + //sweep left + } else if (firstx >= 810 && y < 2700) { + prevx = firstx; + nextx = prevx - 180; + 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 < 2700)) { + prevx = nextx; + barrierx[1] = true; + if (x < prevx && y < 2700) { + if (x < (nextx - 180)) { + if (exec_countx && (jiffies - firstx_time < S2W_TIMEOUT)) { + printk("[TP]: sweep left\n"); + wake_lock_timeout(&l2w_wakelock, HZ/2); + report_gesture(2); + exec_countx = false; + } + } + } + } + } + } + +} + +static void sweep2wake_func(int button_id) { + 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[1]) < S2W_TIMEOUT && (s2w_time[0]-s2w_time[1]) > S2W_START) { + + if (s2w_hist[1] == 1 && s2w_hist[0] == 2) { + reset_sweep2wake(); + 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 ((scr_suspended && (s2w_switch & SWEEP_LEFT)) || + (!scr_suspended && (s2s_switch & SWEEP_LEFT))) { + printk("[S2W]: sweep left\n"); + wakesleep_vib = 1; + sweep2wake_pwrtrigger(); + } + } else { + reset_sweep2wake(); + return; + } + } +} + +static int last_touch_position_x = 0; +static int last_touch_position_y = 0; + +static cputime64_t prev_time; +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); + gpio_direction_output(ts->gpio_reset, 1); + } +} + +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 > 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(); + 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; 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) @@ -2030,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) @@ -2067,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){ - printk(KERN_INFO - "[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)) { @@ -2125,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) { @@ -2156,6 +2667,21 @@ 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) { + 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(); + } + } + } +#endif if (ts->pre_finger_data[0][0] < 2 || finger_pressed) { if (ts->package_id < 3400) base = (ts->finger_support + 3) / 4; @@ -2265,6 +2791,15 @@ 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 (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]); @@ -2298,9 +2833,20 @@ 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 (scr_suspended){ + sweep2wake_horiz_func(x_pos[0], y_pos[0]); + 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)) { 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, @@ -2354,19 +2900,8 @@ 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) { #ifdef SYN_CALIBRATION_CONTROL if (ts->multitouch_calibration) { @@ -2438,7 +2973,9 @@ static void synaptics_ts_button_func(struct synaptics_ts_data *ts) int ret; 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) { @@ -2547,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); } @@ -2569,6 +3108,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); @@ -2576,15 +3120,24 @@ 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); } } } + if (buf & get_address_base(ts, 0x1A, INTR_SOURCE)) { - if (!ts->finger_count) +#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(KERN_DEBUG "[TP] synaptics_ts_button_func 2\n"); synaptics_ts_button_func(ts); - else - printk("[TP] Ignore VK interrupt due to 2d points did not leave\n"); + } +#endif } if (buf & get_address_base(ts, 0x01, INTR_SOURCE)) synaptics_ts_status_func(ts); @@ -3270,6 +3823,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 +3875,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: @@ -3376,8 +3954,12 @@ 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; err_detect_failed: @@ -3402,7 +3984,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) @@ -3422,12 +4007,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 || 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 && !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 && !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,40 +4196,46 @@ static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg) } ts->disable_CBC = 0; } - - 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 +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + 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(); +#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,25 +4245,34 @@ 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__); - if (ts->power) { - ts->power(1); - hr_msleep(100); +#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE + //screen on, disable_irq_wake + if (s2w_switch || dt2w_switch || gestures_switch) + disable_irq_wake(client->irq); + + if (!s2w_switch && !dt2w_switch && !gestures_switch) { +#endif + 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 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 +4298,19 @@ static int synaptics_ts_resume(struct i2c_client *client) ts->psensor_phone_enable = 1; } } - - 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 + 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); +#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