Patchwork make ektf3k driver report non-MT events too

login
register
mail settings
Submitter Matt Whitlock
Date Aug. 7, 2013, 5:51 p.m.
Message ID <1658315.vxlUMBhYuy@crushinator>
Download mbox | patch
Permalink /patch/265618/
State New
Headers show

Comments

Matt Whitlock - Aug. 7, 2013, 5:51 p.m.
Joseph Salisbury requested that I submit this patch to the Ubuntu Kernel Team mailing list for review.

> This patch resolves a shortcoming of the ektf3k driver. Previously, the
> driver was reporting only multi-touch events. xf86-input-evdev 2.7.3
> crashes upon receiving input events from [that] driver, and 2.8.1 simply
> ignores the input device altogether as a workaround for the crash.
> 
> This patch adds single-touch ABS_X, ABS_Y, and ABS_PRESSURE axes, as well as
> the BTN_TOUCH key. Only the first finger touching reports on these
> single-touch axes (while continuing to report on the multi-touch axes);
> additional fingers report only on the multi-touch axes.
> 
> I have tested this patch on a Nexus 7 running X.org server 1.13.4 and
> xf86-input-evdev 2.8.1. Without the patch, evdev ignores all input from the
> touchscreen. With the patch, evdev generates mouse events in response to
> touches, as one would expect.

https://bugs.launchpad.net/ubuntu/+source/linux-grouper/+bug/1209049
Tim Gardner - Aug. 8, 2013, 4:38 p.m.
On 08/07/2013 11:51 AM, Matt Whitlock wrote:
> Joseph Salisbury requested that I submit this patch to the Ubuntu Kernel Team mailing list for review.
> 
>> This patch resolves a shortcoming of the ektf3k driver. Previously, the
>> driver was reporting only multi-touch events. xf86-input-evdev 2.7.3
>> crashes upon receiving input events from [that] driver, and 2.8.1 simply
>> ignores the input device altogether as a workaround for the crash.
>>
>> This patch adds single-touch ABS_X, ABS_Y, and ABS_PRESSURE axes, as well as
>> the BTN_TOUCH key. Only the first finger touching reports on these
>> single-touch axes (while continuing to report on the multi-touch axes);
>> additional fingers report only on the multi-touch axes.
>>
>> I have tested this patch on a Nexus 7 running X.org server 1.13.4 and
>> xf86-input-evdev 2.8.1. Without the patch, evdev ignores all input from the
>> touchscreen. With the patch, evdev generates mouse events in response to
>> touches, as one would expect.
> 
> https://bugs.launchpad.net/ubuntu/+source/linux-grouper/+bug/1209049
> 
> 
> 

I need provenance on this patch.

rtg
Seth Forshee - Aug. 8, 2013, 6:49 p.m.
On Wed, Aug 07, 2013 at 01:51:12PM -0400, Matt Whitlock wrote:
> Joseph Salisbury requested that I submit this patch to the Ubuntu Kernel Team mailing list for review.
> 
> > This patch resolves a shortcoming of the ektf3k driver. Previously, the
> > driver was reporting only multi-touch events. xf86-input-evdev 2.7.3
> > crashes upon receiving input events from [that] driver, and 2.8.1 simply
> > ignores the input device altogether as a workaround for the crash.
> > 
> > This patch adds single-touch ABS_X, ABS_Y, and ABS_PRESSURE axes, as well as
> > the BTN_TOUCH key. Only the first finger touching reports on these
> > single-touch axes (while continuing to report on the multi-touch axes);
> > additional fingers report only on the multi-touch axes.
> > 
> > I have tested this patch on a Nexus 7 running X.org server 1.13.4 and
> > xf86-input-evdev 2.8.1. Without the patch, evdev ignores all input from the
> > touchscreen. With the patch, evdev generates mouse events in response to
> > touches, as one would expect.
> 
> https://bugs.launchpad.net/ubuntu/+source/linux-grouper/+bug/1209049

input_mt_report_pointer_emulation() exists for exactly this purpose, so
it would be preferable to use that instead.

Seth

Patch

=== modified file 'drivers/input/touchscreen/ektf3k.c'
--- drivers/input/touchscreen/ektf3k.c	2013-05-02 01:22:19 +0000
+++ drivers/input/touchscreen/ektf3k.c	2013-08-06 22:15:53 +0000
@@ -910,6 +910,9 @@ 
           for(i = 0; i < FINGER_NUM; i++){
               active = fbits & 0x1;
               if(active || mTouchStatus[i]){
+				if (active != mTouchStatus[i]) {
+					input_report_key(idev, BTN_TOUCH, active);
+				}
 		     input_mt_slot(ts->input_dev, i);
                   input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, active);
                   if(active){
@@ -923,6 +926,11 @@ 
                       input_report_abs(idev, ABS_MT_POSITION_X, y);
                       input_report_abs(idev, ABS_MT_POSITION_Y, x);
                       if(unlikely(gPrint_point)) touch_debug(DEBUG_INFO, "[elan] finger id=%d X=%d y=%d size=%d pressure=%d\n", i, x, y, touch_size, pressure_size);
+				if (i == 0) {
+					input_report_abs(idev, ABS_PRESSURE, pressure_size);
+					input_report_abs(idev, ABS_X, y);
+					input_report_abs(idev, ABS_Y, x);
+				}
 		     }
 		 }
 		 mTouchStatus[i] = active;
@@ -956,10 +964,12 @@ 
 	if ( (num < 3) || ((checksum & 0x00ff) == buf[34])) {   
           fbits = buf[2] & 0x30;	
 	    fbits = (fbits << 4) | buf[1]; 
-	    //input_report_key(idev, BTN_TOUCH, 1);
           for(i = 0; i < FINGER_NUM; i++){
               active = fbits & 0x1;
               if(active || mTouchStatus[i]){
+				if (active != mTouchStatus[i]) {
+					input_report_key(idev, BTN_TOUCH, active);
+				}
 		     input_mt_slot(ts->input_dev, i);
                   input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, active);
                   if(active){
@@ -973,6 +983,11 @@ 
 			   input_report_abs(idev, ABS_MT_POSITION_X, y);
 			   input_report_abs(idev, ABS_MT_POSITION_Y, x);
 			   if(unlikely(gPrint_point)) touch_debug(DEBUG_INFO, "[elan] finger id=%d X=%d y=%d size=%d pressure=%d\n", i, x, y, touch_size, pressure_size);
+				if (i == 0) {
+					input_report_abs(idev, ABS_PRESSURE, pressure_size);
+					input_report_abs(idev, ABS_X, y);
+					input_report_abs(idev, ABS_Y, x);
+				}
 		     }
 		 }
 		 mTouchStatus[i] = active;
@@ -1505,11 +1520,15 @@ 
 	}
 	ts->input_dev->name = "elan-touchscreen";  
 
-	//set_bit(BTN_TOUCH, ts->input_dev->keybit);
+	set_bit(BTN_TOUCH, ts->input_dev->keybit);
 	ts->abs_x_max =  pdata->abs_x_max;
 	ts->abs_y_max = pdata->abs_y_max;
 	touch_debug(DEBUG_INFO, "[Elan] Max X=%d, Max Y=%d\n", ts->abs_x_max, ts->abs_y_max);
 
+	input_set_abs_params(ts->input_dev, ABS_X, pdata->abs_y_min, pdata->abs_y_max, 0, 0); // for 800 * 1280
+	input_set_abs_params(ts->input_dev, ABS_Y, pdata->abs_x_min, pdata->abs_x_max, 0, 0); // for 800 * 1280
+	input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, MAX_FINGER_PRESSURE, 0, 0);
+
 	input_mt_init_slots(ts->input_dev, FINGER_NUM);
 	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, pdata->abs_y_min,  pdata->abs_y_max, 0, 0); // for 800 * 1280 
 	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, pdata->abs_x_min,  pdata->abs_x_max, 0, 0);// for 800 * 1280