aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/s3c24xx/patches-2.6.24/1314-palliate_touch_screen_jitter.patch.patch
blob: 751d4641607f17a9b5136b72ecf99da46beee802 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
From abe8f448547d1bd69ac2963e07e2657f27b79691 Mon Sep 17 00:00:00 2001
From: I-Fan Chen <tick@openmoko.com>
Date: Wed, 29 Oct 2008 03:15:18 +0000
Subject: [PATCH] palliate_touch_screen_jitter.patch

    S3C24XX touchscreen: To palliate the data jitter from touchpanel
    	Thanks to Dima Kogan patch eff39cde0d3cdd2afd5e1b4be5a8eb6cf195543e,
    	in which try to balence the up/down events, and inspired this patch.
    	We can observe a serious up/down jitter phenomenon when touching the touchscreen lightly.
    	This only happens when the press  pressure is pretty light:
    		eg. large scale light touch,
    		starting to touch,
    		or going to move finger from touch panel.
    	This will make user space library think it got extra click events.
    	In order to palliate with this phenomenon, we delayed the up event for a while,
    	and see if it is a jitter or not.
    	The threshold is crucial. If it is too long, multiple clicks will be filtered out.
    	If it is too short we did not filter anything out.
    	From the log and some survey we can see that the interval of two clicks is generally over 0.1 sec.
    	And Most jitter events happens in 0.3 sec.
    	And the longest duration of vision is about 1/16 sec, and it's not easy for human to notice.
    	So I choose 1/16 sec as the threshold.
    	This filters out most (not all) jitter events, and preserves the normal behavior we expected.

Signed-off-by: I-Fan Chen <tick@openmoko.com>
---
 drivers/input/touchscreen/s3c2410_ts.c |   47 +++++++++++++++++---------------
 1 files changed, 25 insertions(+), 22 deletions(-)

diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c
index fc1c500..95672ff 100644
--- a/drivers/input/touchscreen/s3c2410_ts.c
+++ b/drivers/input/touchscreen/s3c2410_ts.c
@@ -78,6 +78,12 @@
 
 #define DEBUG_LVL    KERN_DEBUG
 
+#define TOUCH_STANDBY_FLAG 0
+#define TOUCH_PRESSED_FLAG 1
+#define TOUCH_RELEASE_FLAG 2
+
+#define TOUCH_RELEASE_TIMEOUT (HZ >> 4)
+
 MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
 MODULE_DESCRIPTION("s3c2410 touchscreen driver");
 MODULE_LICENSE("GPL");
@@ -131,7 +137,7 @@ static void clear_raw_fifo(void)
 	ts.raw_running_avg.x = 0;
 	ts.raw_running_avg.y = 0;
 	ts.flag_previous_exceeded_threshold = 0;
-	ts.flag_first_touch_sent = 0;
+	ts.flag_first_touch_sent = TOUCH_STANDBY_FLAG;
 }
 
 
@@ -143,6 +149,10 @@ static inline void s3c2410_ts_connect(void)
 	s3c2410_gpio_cfgpin(S3C2410_GPG15, S3C2410_GPG15_nYPON);
 }
 
+static void touch_timer_fire(unsigned long data);
+static struct timer_list touch_timer =
+		TIMER_INITIALIZER(touch_timer_fire, 0, 0);
+
 static void touch_timer_fire(unsigned long data)
 {
   	unsigned long data0;
@@ -155,18 +165,9 @@ static void touch_timer_fire(unsigned long data)
 	updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) &&
 					    (!(data1 & S3C2410_ADCDAT0_UPDOWN));
 
-	// if we need to send an untouch event, but we haven't yet sent the
-	// touch event (this happens if the touchscreen was tapped lightly),
-	// send the touch event first
-	if (!updown && !ts.flag_first_touch_sent && ts.count != 0) {
-		input_report_abs(ts.dev, ABS_X, ts.xp >> ts.shift);
-		input_report_abs(ts.dev, ABS_Y, ts.yp >> ts.shift);
-
-		input_report_key(ts.dev, BTN_TOUCH, 1);
-		input_report_abs(ts.dev, ABS_PRESSURE, 1);
-		input_sync(ts.dev);
-		ts.flag_first_touch_sent = 1;
-	}
+        if ( updown && ts.flag_first_touch_sent == TOUCH_RELEASE_FLAG ) {
+        	ts.flag_first_touch_sent = TOUCH_PRESSED_FLAG;
+        }
 
 	if (updown) {
 		if (ts.count != 0) {
@@ -189,7 +190,7 @@ static void touch_timer_fire(unsigned long data)
 			input_report_key(ts.dev, BTN_TOUCH, 1);
 			input_report_abs(ts.dev, ABS_PRESSURE, 1);
 			input_sync(ts.dev);
-			ts.flag_first_touch_sent = 1;
+			ts.flag_first_touch_sent = TOUCH_PRESSED_FLAG;
 		}
 
 		ts.xp = 0;
@@ -202,19 +203,21 @@ static void touch_timer_fire(unsigned long data)
 			 S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);
 	} else {
 		ts.count = 0;
-
-		input_report_key(ts.dev, BTN_TOUCH, 0);
-		input_report_abs(ts.dev, ABS_PRESSURE, 0);
-		input_sync(ts.dev);
-		ts.flag_first_touch_sent = 0;
+                
+                if ( ts.flag_first_touch_sent == TOUCH_RELEASE_FLAG ) {
+			input_report_key(ts.dev, BTN_TOUCH, 0);
+			input_report_abs(ts.dev, ABS_PRESSURE, 0);
+			input_sync(ts.dev);
+			ts.flag_first_touch_sent = TOUCH_STANDBY_FLAG;
+                } if ( ts.flag_first_touch_sent == TOUCH_PRESSED_FLAG ) {
+                	ts.flag_first_touch_sent = TOUCH_RELEASE_FLAG;
+                	mod_timer(&touch_timer, jiffies + TOUCH_RELEASE_TIMEOUT);
+                }
 
 		writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
 	}
 }
 
-static struct timer_list touch_timer =
-		TIMER_INITIALIZER(touch_timer_fire, 0, 0);
-
 static irqreturn_t stylus_updown(int irq, void *dev_id)
 {
 	unsigned long data0;
-- 
1.5.6.5