Hi List,
  From the first observation of touch screen, we found the up/down event jitter 
phenomenon. 
If you touch the touchscreen lightly, you will get very unstable data,
and many up/down events in a very short time.
In the driver it already average the data within a threshold. But the
extra up/down events will still makes user space libraries think they get
clicks. This causes annoying problems, and make the GUI hard to use. 

Thanks for Andy's advise and the inspiration from Dima's patch, we found
that can just ignore those extra events with a little bit delay of sending up
envent. If we found it's noise, we can just throw them away. 

I asked many people to play with the touch panel and collected a lot of
logs. I found something. 

1. most jitter event happens in a very shor period of time. most of them
happens less than 0.3 sec
2. Most interval of human double clicks are over 0.1 sec. 0.11~0.2 or
so. 
3. Human is not easy to notice things happens in a very short time. For
example "visual staying phenomenon".

I choose 1/16 sec = 0.0625 sec (about the logest duration of vision) as 
the delay threshold. 

And then played with the new driver, it filters out most jitter events.
Although you can still produce noise events on purpose, but it becomes harder.

Cheers, 
Tick
commit 4760e6b7a7a495ab5c152ca46004f4f26b1dfb15
Author: I-Fan, Chen <[EMAIL PROTECTED]>
Date:   Tue Oct 28 22:02:23 2008 +0800

    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.

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 <[EMAIL PROTECTED]>");
 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;

Attachment: signature.asc
Description: Digital signature

_______________________________________________
devel mailing list
[email protected]
https://lists.openmoko.org/mailman/listinfo/devel

Reply via email to