summaryrefslogtreecommitdiff
path: root/drivers/input
diff options
context:
space:
mode:
authorJoshua Cha <joshuac@nvidia.com>2011-11-10 20:29:17 +0900
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:52:39 -0800
commit1486dfe88e07a1c6a54992c6e5e814616c3292cb (patch)
treebaf82ea7a095aba23ad2b70a265c33c00a7818c0 /drivers/input
parent645f91c68b19172da28779e86c2d60045fc64705 (diff)
Input: synaptics_i2c_rmi: Correct 2nd multi touch removing
When 2nd multi touch is removed, release point is (0,0) point. To correct this, in removing 2nd multi touch, we send last touched position of 2nd multi touch. And this removes noise touch event and joystick event also. Bug 896919 Change-Id: Icccaa3ccc28e613565ce696339b83d60335b344a Reviewed-on: http://git-master/r/64008 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com> Rebase-Id: Re3c488cd60c5b02ec43fa8f3e700dc93afbff043
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/touchscreen/synaptics_i2c_rmi.c58
1 files changed, 41 insertions, 17 deletions
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi.c b/drivers/input/touchscreen/synaptics_i2c_rmi.c
index 5729602cbb63..6f9b83af0359 100644
--- a/drivers/input/touchscreen/synaptics_i2c_rmi.c
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi.c
@@ -25,6 +25,8 @@
#include <linux/slab.h>
#include <linux/synaptics_i2c_rmi.h>
+#define ABS_DIFF(a, b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a)))
+
static struct workqueue_struct *synaptics_wq;
struct synaptics_ts_data {
@@ -45,6 +47,7 @@ struct synaptics_ts_data {
int snap_up[2];
uint32_t flags;
int reported_finger_count;
+ int last_pos[2][2];
int8_t sensitivity_adjust;
int (*power)(int on);
struct early_suspend early_suspend;
@@ -136,6 +139,7 @@ static void synaptics_ts_work_func(struct work_struct *work)
break;
} else {
int pos[2][2];
+ int rmpos_x, rmpos_y;
int f, a;
int base;
/* int x = buf[3] | (uint16_t)(buf[2] & 0x1f) << 8; */
@@ -193,22 +197,19 @@ static void synaptics_ts_work_func(struct work_struct *work)
if (ts->flags & SYNAPTICS_SWAP_XY)
swap(pos[f][0], pos[f][1]);
}
- if (z) {
- input_report_abs(ts->input_dev, ABS_X, pos[0][0]);
- input_report_abs(ts->input_dev, ABS_Y, pos[0][1]);
- }
- input_report_abs(ts->input_dev, ABS_PRESSURE, z);
- input_report_abs(ts->input_dev, ABS_TOOL_WIDTH, w);
- input_report_key(ts->input_dev, BTN_TOUCH, finger);
- finger2_pressed = finger > 1 && finger != 7;
- input_report_key(ts->input_dev, BTN_2, finger2_pressed);
- if (finger2_pressed) {
- input_report_abs(ts->input_dev, ABS_HAT0X, pos[1][0]);
- input_report_abs(ts->input_dev, ABS_HAT0Y, pos[1][1]);
- }
- if (!finger)
+ if (!finger) {
z = 0;
+ if (ts->reported_finger_count > 0) {
+ pos[0][0] = ts->last_pos[0][0];
+ pos[0][1] = ts->last_pos[0][1];
+ }
+ else
+ continue; /* skip touch noise */
+ }
+ finger = (finger == 7) ? 1 : finger; /* correct wrong finger count */
+ finger2_pressed = finger > 1;
+
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, z);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w);
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, pos[0][0]);
@@ -220,11 +221,37 @@ static void synaptics_ts_work_func(struct work_struct *work)
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, pos[1][0]);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, pos[1][1]);
input_mt_sync(ts->input_dev);
+ ts->last_pos[1][0] = pos[1][0];
+ ts->last_pos[1][1] = pos[1][1];
} else if (ts->reported_finger_count > 1) {
+ /* check which point was removed */
+ if ((ABS_DIFF(pos[0][0],ts->last_pos[0][0]) +
+ ABS_DIFF(pos[0][1],ts->last_pos[0][1])) <
+ (ABS_DIFF(pos[0][0],ts->last_pos[1][0]) +
+ ABS_DIFF(pos[0][1],ts->last_pos[1][1]))) {
+ rmpos_x = ts->last_pos[1][0];
+ rmpos_y = ts->last_pos[1][1];
+ }
+ else {
+ rmpos_x = ts->last_pos[0][0];
+ rmpos_y = ts->last_pos[0][1];
+ }
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0);
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_X, rmpos_x);
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, rmpos_y);
input_mt_sync(ts->input_dev);
}
+
+ if (z) {
+ input_report_abs(ts->input_dev, ABS_X, pos[0][0]);
+ input_report_abs(ts->input_dev, ABS_Y, pos[0][1]);
+ ts->last_pos[0][0] = pos[0][0];
+ ts->last_pos[0][1] = pos[0][1];
+ }
+ input_report_abs(ts->input_dev, ABS_PRESSURE, z);
+ input_report_abs(ts->input_dev, ABS_TOOL_WIDTH, w);
+ input_report_key(ts->input_dev, BTN_TOUCH, finger);
ts->reported_finger_count = finger;
input_sync(ts->input_dev);
}
@@ -464,7 +491,6 @@ static int synaptics_ts_probe(
set_bit(EV_SYN, ts->input_dev->evbit);
set_bit(EV_KEY, ts->input_dev->evbit);
set_bit(BTN_TOUCH, ts->input_dev->keybit);
- set_bit(BTN_2, ts->input_dev->keybit);
set_bit(EV_ABS, ts->input_dev->evbit);
inactive_area_left = inactive_area_left * max_x / 0x10000;
inactive_area_right = inactive_area_right * max_x / 0x10000;
@@ -503,8 +529,6 @@ static int synaptics_ts_probe(
input_set_abs_params(ts->input_dev, ABS_Y, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0);
input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, fuzz_p, 0);
input_set_abs_params(ts->input_dev, ABS_TOOL_WIDTH, 0, 15, fuzz_w, 0);
- input_set_abs_params(ts->input_dev, ABS_HAT0X, -inactive_area_left, max_x + inactive_area_right, fuzz_x, 0);
- input_set_abs_params(ts->input_dev, ABS_HAT0Y, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0);
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, -inactive_area_left, max_x + inactive_area_right, fuzz_x, 0);
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0);
input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, fuzz_p, 0);