1 From abe8f448547d1bd69ac2963e07e2657f27b79691 Mon Sep 17 00:00:00 2001
2 From: I-Fan Chen <tick@openmoko.com>
3 Date: Wed, 29 Oct 2008 03:15:18 +0000
4 Subject: [PATCH] palliate_touch_screen_jitter.patch
6 S3C24XX touchscreen: To palliate the data jitter from touchpanel
7 Thanks to Dima Kogan patch eff39cde0d3cdd2afd5e1b4be5a8eb6cf195543e,
8 in which try to balence the up/down events, and inspired this patch.
9 We can observe a serious up/down jitter phenomenon when touching the touchscreen lightly.
10 This only happens when the press pressure is pretty light:
11 eg. large scale light touch,
13 or going to move finger from touch panel.
14 This will make user space library think it got extra click events.
15 In order to palliate with this phenomenon, we delayed the up event for a while,
16 and see if it is a jitter or not.
17 The threshold is crucial. If it is too long, multiple clicks will be filtered out.
18 If it is too short we did not filter anything out.
19 From the log and some survey we can see that the interval of two clicks is generally over 0.1 sec.
20 And Most jitter events happens in 0.3 sec.
21 And the longest duration of vision is about 1/16 sec, and it's not easy for human to notice.
22 So I choose 1/16 sec as the threshold.
23 This filters out most (not all) jitter events, and preserves the normal behavior we expected.
25 Signed-off-by: I-Fan Chen <tick@openmoko.com>
27 drivers/input/touchscreen/s3c2410_ts.c | 47 +++++++++++++++++---------------
28 1 files changed, 25 insertions(+), 22 deletions(-)
30 diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c
31 index fc1c500..95672ff 100644
32 --- a/drivers/input/touchscreen/s3c2410_ts.c
33 +++ b/drivers/input/touchscreen/s3c2410_ts.c
36 #define DEBUG_LVL KERN_DEBUG
38 +#define TOUCH_STANDBY_FLAG 0
39 +#define TOUCH_PRESSED_FLAG 1
40 +#define TOUCH_RELEASE_FLAG 2
42 +#define TOUCH_RELEASE_TIMEOUT (HZ >> 4)
44 MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
45 MODULE_DESCRIPTION("s3c2410 touchscreen driver");
46 MODULE_LICENSE("GPL");
47 @@ -131,7 +137,7 @@ static void clear_raw_fifo(void)
48 ts.raw_running_avg.x = 0;
49 ts.raw_running_avg.y = 0;
50 ts.flag_previous_exceeded_threshold = 0;
51 - ts.flag_first_touch_sent = 0;
52 + ts.flag_first_touch_sent = TOUCH_STANDBY_FLAG;
56 @@ -143,6 +149,10 @@ static inline void s3c2410_ts_connect(void)
57 s3c2410_gpio_cfgpin(S3C2410_GPG15, S3C2410_GPG15_nYPON);
60 +static void touch_timer_fire(unsigned long data);
61 +static struct timer_list touch_timer =
62 + TIMER_INITIALIZER(touch_timer_fire, 0, 0);
64 static void touch_timer_fire(unsigned long data)
67 @@ -155,18 +165,9 @@ static void touch_timer_fire(unsigned long data)
68 updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) &&
69 (!(data1 & S3C2410_ADCDAT0_UPDOWN));
71 - // if we need to send an untouch event, but we haven't yet sent the
72 - // touch event (this happens if the touchscreen was tapped lightly),
73 - // send the touch event first
74 - if (!updown && !ts.flag_first_touch_sent && ts.count != 0) {
75 - input_report_abs(ts.dev, ABS_X, ts.xp >> ts.shift);
76 - input_report_abs(ts.dev, ABS_Y, ts.yp >> ts.shift);
78 - input_report_key(ts.dev, BTN_TOUCH, 1);
79 - input_report_abs(ts.dev, ABS_PRESSURE, 1);
81 - ts.flag_first_touch_sent = 1;
83 + if ( updown && ts.flag_first_touch_sent == TOUCH_RELEASE_FLAG ) {
84 + ts.flag_first_touch_sent = TOUCH_PRESSED_FLAG;
89 @@ -189,7 +190,7 @@ static void touch_timer_fire(unsigned long data)
90 input_report_key(ts.dev, BTN_TOUCH, 1);
91 input_report_abs(ts.dev, ABS_PRESSURE, 1);
93 - ts.flag_first_touch_sent = 1;
94 + ts.flag_first_touch_sent = TOUCH_PRESSED_FLAG;
98 @@ -202,19 +203,21 @@ static void touch_timer_fire(unsigned long data)
99 S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);
103 - input_report_key(ts.dev, BTN_TOUCH, 0);
104 - input_report_abs(ts.dev, ABS_PRESSURE, 0);
105 - input_sync(ts.dev);
106 - ts.flag_first_touch_sent = 0;
108 + if ( ts.flag_first_touch_sent == TOUCH_RELEASE_FLAG ) {
109 + input_report_key(ts.dev, BTN_TOUCH, 0);
110 + input_report_abs(ts.dev, ABS_PRESSURE, 0);
111 + input_sync(ts.dev);
112 + ts.flag_first_touch_sent = TOUCH_STANDBY_FLAG;
113 + } if ( ts.flag_first_touch_sent == TOUCH_PRESSED_FLAG ) {
114 + ts.flag_first_touch_sent = TOUCH_RELEASE_FLAG;
115 + mod_timer(&touch_timer, jiffies + TOUCH_RELEASE_TIMEOUT);
118 writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
122 -static struct timer_list touch_timer =
123 - TIMER_INITIALIZER(touch_timer_fire, 0, 0);
125 static irqreturn_t stylus_updown(int irq, void *dev_id)