linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Input: Change BTN_TOOL_FINGER flag when hover event trigger
@ 2016-04-19  5:18 DusonLin
  0 siblings, 0 replies; 9+ messages in thread
From: DusonLin @ 2016-04-19  5:18 UTC (permalink / raw)
  To: linux-input, Linux-kernel, 'Dmitry Torokhov'
  Cc: jeff.chuang, 'Phoenix', 'Charles Mooney'

Only ABS_DISTANCE is not enough for upper OS to distingiush hover event
be triggered from object from faraway to and close touchpad surface or
from object prepare to leave the touchpad surface. Add BTN_TOOL_FINGER
flag to help it.

                 object_from_faraway    object_inside_hover_area
object_touch_surface
BTN_TOUCH                 0                          0
1
BTN_TOOL_FINGER           0                          1
1
ABS_DISTANCE              0                          1
0

Signed-off by: Duson Lin <dusonlin@emc.com.tw>
---
 drivers/hid/hid-magicmouse.c             |  2 +-
 drivers/input/input-mt.c                 |  7 +++++--
 drivers/input/mouse/elan_i2c_core.c      | 15 +++++++++------
 drivers/input/mouse/elantech.c           |  2 +-
 drivers/input/mouse/focaltech.c          |  2 +-
 drivers/input/mouse/synaptics.c          |  2 +-
 drivers/input/touchscreen/atmel_mxt_ts.c |  2 +-
 drivers/input/touchscreen/edt-ft5x06.c   |  2 +-
 drivers/input/touchscreen/egalax_ts.c    |  2 +-
 drivers/input/touchscreen/ili210x.c      |  2 +-
 drivers/input/touchscreen/mms114.c       |  4 ++--
 drivers/input/touchscreen/penmount.c     |  2 +-
 drivers/input/touchscreen/rohm_bu21023.c |  2 +-
 drivers/input/touchscreen/wacom_w8001.c  |  2 +-
 include/linux/input/mt.h                 |  3 ++-
 15 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index d6fa496..584e98b 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -353,7 +353,7 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 		input_report_rel(input, REL_Y, y);
 	} else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
 		input_report_key(input, BTN_MOUSE, clicks & 1);
-		input_mt_report_pointer_emulation(input, true);
+		input_mt_report_pointer_emulation(input, true, false);
 	}
 
 	input_sync(input);
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
index 54fce56..30855a5 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -184,6 +184,7 @@ EXPORT_SYMBOL(input_mt_report_finger_count);
  * input_mt_report_pointer_emulation() - common pointer emulation
  * @dev: input device with allocated MT slots
  * @use_count: report number of active contacts as finger count
+ * @hover: report ABS_DISTANCE as hover event
  *
  * Performs legacy pointer emulation via BTN_TOUCH, ABS_X, ABS_Y and
  * ABS_PRESSURE. Touchpad finger count is emulated if use_count is true.
@@ -191,7 +192,8 @@ EXPORT_SYMBOL(input_mt_report_finger_count);
  * The input core ensures only the KEY and ABS axes already setup for
  * this device will produce output.
  */
-void input_mt_report_pointer_emulation(struct input_dev *dev, bool
use_count)
+void input_mt_report_pointer_emulation(struct input_dev *dev, bool
use_count,
+					bool hover)
 {
 	struct input_mt *mt = dev->mt;
 	struct input_mt_slot *oldest;
@@ -220,6 +222,7 @@ void input_mt_report_pointer_emulation(struct input_dev
*dev, bool use_count)
 	input_event(dev, EV_KEY, BTN_TOUCH, count > 0);
 	if (use_count)
 		input_mt_report_finger_count(dev, count);
+	input_event(dev, EV_ABS, ABS_DISTANCE, hover);
 
 	if (oldest) {
 		int x = input_mt_get_value(oldest, ABS_MT_POSITION_X);
@@ -290,7 +293,7 @@ void input_mt_sync_frame(struct input_dev *dev)
 	if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags &
INPUT_MT_SEMI_MT))
 		use_count = true;
 
-	input_mt_report_pointer_emulation(dev, use_count);
+	input_mt_report_pointer_emulation(dev, use_count, false);
 
 	mt->frame++;
 }
diff --git a/drivers/input/mouse/elan_i2c_core.c
b/drivers/input/mouse/elan_i2c_core.c
index 2f58985..8b5e75a 100644
--- a/drivers/input/mouse/elan_i2c_core.c
+++ b/drivers/input/mouse/elan_i2c_core.c
@@ -4,7 +4,7 @@
  * Copyright (c) 2013 ELAN Microelectronics Corp.
  *
  * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
- * Version: 1.6.0
+ * Version: 1.6.2
  *
  * Based on cyapa driver:
  * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
@@ -40,7 +40,7 @@
 #include "elan_i2c.h"
 
 #define DRIVER_NAME		"elan_i2c"
-#define ELAN_DRIVER_VERSION	"1.6.1"
+#define ELAN_DRIVER_VERSION	"1.6.2"
 #define ELAN_VENDOR_ID		0x04f3
 #define ETP_MAX_PRESSURE	255
 #define ETP_FWIDTH_REDUCE	90
@@ -845,7 +845,7 @@ static void elan_report_absolute(struct elan_tp_data
*data, u8 *packet)
 {
 	struct input_dev *input = data->input;
 	u8 *finger_data = &packet[ETP_FINGER_DATA_OFFSET];
-	int i;
+	int i, valid_count = 0;
 	u8 tp_info = packet[ETP_TOUCH_INFO_OFFSET];
 	u8 hover_info = packet[ETP_HOVER_INFO_OFFSET];
 	bool contact_valid, hover_event;
@@ -855,13 +855,16 @@ static void elan_report_absolute(struct elan_tp_data
*data, u8 *packet)
 		contact_valid = tp_info & (1U << (3 + i));
 		elan_report_contact(data, i, contact_valid, finger_data);
 
-		if (contact_valid)
+		if (contact_valid) {
 			finger_data += ETP_FINGER_DATA_LEN;
+			valid_count++;
+		}
 	}
 
 	input_report_key(input, BTN_LEFT, tp_info & 0x01);
-	input_report_abs(input, ABS_DISTANCE, hover_event != 0);
-	input_mt_report_pointer_emulation(input, true);
+	input_report_key(input, BTN_TOOL_FINGER,
+			((hover_event != 0) || (valid_count > 0)));
+	input_mt_report_pointer_emulation(input, false, hover_event != 0);
 	input_sync(input);
 }
 
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 78f93cf..cc13e12 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -558,7 +558,7 @@ static void elantech_input_sync_v4(struct psmouse
*psmouse)
 		input_report_key(dev, BTN_MIDDLE, packet[0] & 0x04);
 	}
 
-	input_mt_report_pointer_emulation(dev, true);
+	input_mt_report_pointer_emulation(dev, true, false);
 	input_sync(dev);
 }
 
diff --git a/drivers/input/mouse/focaltech.c
b/drivers/input/mouse/focaltech.c
index c8c6a8c..f4339ac 100644
--- a/drivers/input/mouse/focaltech.c
+++ b/drivers/input/mouse/focaltech.c
@@ -144,7 +144,7 @@ static void focaltech_report_state(struct psmouse
*psmouse)
 			input_report_abs(dev, ABS_TOOL_WIDTH, state->width);
 		}
 	}
-	input_mt_report_pointer_emulation(dev, true);
+	input_mt_report_pointer_emulation(dev, true, false);
 
 	input_report_key(psmouse->dev, BTN_LEFT, state->pressed);
 	input_sync(psmouse->dev);
diff --git a/drivers/input/mouse/synaptics.c
b/drivers/input/mouse/synaptics.c
index a41d832..09fa835 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -944,7 +944,7 @@ static void synaptics_report_mt_data(struct psmouse
*psmouse,
 	input_mt_drop_unused(dev);
 
 	/* Don't use active slot count to generate BTN_TOOL events. */
-	input_mt_report_pointer_emulation(dev, false);
+	input_mt_report_pointer_emulation(dev, false, false);
 
 	/* Send the number of fingers reported by touchpad itself. */
 	input_mt_report_finger_count(dev, num_fingers);
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 2160512..0ab0d53 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -683,7 +683,7 @@ static void mxt_input_button(struct mxt_data *data, u8
*message)
 static void mxt_input_sync(struct mxt_data *data)
 {
 	input_mt_report_pointer_emulation(data->input_dev,
-					  data->pdata->t19_num_keys);
+					  data->pdata->t19_num_keys, false);
 	input_sync(data->input_dev);
 }
 
diff --git a/drivers/input/touchscreen/edt-ft5x06.c
b/drivers/input/touchscreen/edt-ft5x06.c
index 23fbe38..6533d8e 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -250,7 +250,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void
*dev_id)
 		input_report_abs(tsdata->input, ABS_MT_POSITION_Y, y);
 	}
 
-	input_mt_report_pointer_emulation(tsdata->input, true);
+	input_mt_report_pointer_emulation(tsdata->input, true, false);
 	input_sync(tsdata->input);
 
 out:
diff --git a/drivers/input/touchscreen/egalax_ts.c
b/drivers/input/touchscreen/egalax_ts.c
index 1afc08b..c420336 100644
--- a/drivers/input/touchscreen/egalax_ts.c
+++ b/drivers/input/touchscreen/egalax_ts.c
@@ -113,7 +113,7 @@ static irqreturn_t egalax_ts_interrupt(int irq, void
*dev_id)
 		input_report_abs(input_dev, ABS_MT_PRESSURE, z);
 	}
 
-	input_mt_report_pointer_emulation(input_dev, true);
+	input_mt_report_pointer_emulation(input_dev, true, false);
 	input_sync(input_dev);
 
 	return IRQ_HANDLED;
diff --git a/drivers/input/touchscreen/ili210x.c
b/drivers/input/touchscreen/ili210x.c
index ddf694b..5301e2b 100644
--- a/drivers/input/touchscreen/ili210x.c
+++ b/drivers/input/touchscreen/ili210x.c
@@ -99,7 +99,7 @@ static void ili210x_report_events(struct input_dev *input,
 		}
 	}
 
-	input_mt_report_pointer_emulation(input, false);
+	input_mt_report_pointer_emulation(input, false, false);
 	input_sync(input);
 }
 
diff --git a/drivers/input/touchscreen/mms114.c
b/drivers/input/touchscreen/mms114.c
index 1fafc9f..4f7b20a 100644
--- a/drivers/input/touchscreen/mms114.c
+++ b/drivers/input/touchscreen/mms114.c
@@ -221,7 +221,7 @@ static irqreturn_t mms114_interrupt(int irq, void
*dev_id)
 	for (index = 0; index < touch_size; index++)
 		mms114_process_mt(data, touch + index);
 
-	input_mt_report_pointer_emulation(data->input_dev, true);
+	input_mt_report_pointer_emulation(data->input_dev, true, false);
 	input_sync(data->input_dev);
 
 out:
@@ -528,7 +528,7 @@ static int __maybe_unused mms114_suspend(struct device
*dev)
 		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
false);
 	}
 
-	input_mt_report_pointer_emulation(input_dev, true);
+	input_mt_report_pointer_emulation(input_dev, true, false);
 	input_sync(input_dev);
 
 	mutex_lock(&input_dev->mutex);
diff --git a/drivers/input/touchscreen/penmount.c
b/drivers/input/touchscreen/penmount.c
index 417d873..ceaf1ee 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -81,7 +81,7 @@ static void pm_mtevent(struct pm *pm, struct input_dev
*input)
 		}
 	}
 
-	input_mt_report_pointer_emulation(input, true);
+	input_mt_report_pointer_emulation(input, true, false);
 	input_sync(input);
 }
 
diff --git a/drivers/input/touchscreen/rohm_bu21023.c
b/drivers/input/touchscreen/rohm_bu21023.c
index 611156a..aecd457 100644
--- a/drivers/input/touchscreen/rohm_bu21023.c
+++ b/drivers/input/touchscreen/rohm_bu21023.c
@@ -627,7 +627,7 @@ static irqreturn_t rohm_ts_soft_irq(int irq, void
*dev_id)
 		}
 
 		input_mt_sync_frame(input_dev);
-		input_mt_report_pointer_emulation(input_dev, true);
+		input_mt_report_pointer_emulation(input_dev, true, false);
 		input_sync(input_dev);
 
 		ts->finger_count = finger_count;
diff --git a/drivers/input/touchscreen/wacom_w8001.c
b/drivers/input/touchscreen/wacom_w8001.c
index bab3c6a..05164b1 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -176,7 +176,7 @@ static void parse_multi_touch(struct w8001 *w8001)
 	if (w8001->type != BTN_TOOL_PEN &&
 			    w8001->type != BTN_TOOL_RUBBER) {
 		w8001->type = count == 1 ? BTN_TOOL_FINGER : KEY_RESERVED;
-		input_mt_report_pointer_emulation(dev, true);
+		input_mt_report_pointer_emulation(dev, true, false);
 	}
 
 	input_sync(dev);
diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h
index d7188de..67c7bdd 100644
--- a/include/linux/input/mt.h
+++ b/include/linux/input/mt.h
@@ -104,7 +104,8 @@ void input_mt_report_slot_state(struct input_dev *dev,
 				unsigned int tool_type, bool active);
 
 void input_mt_report_finger_count(struct input_dev *dev, int count);
-void input_mt_report_pointer_emulation(struct input_dev *dev, bool
use_count);
+void input_mt_report_pointer_emulation(struct input_dev *dev, bool
use_count,
+					bool hover);
 void input_mt_drop_unused(struct input_dev *dev);
 
 void input_mt_sync_frame(struct input_dev *dev);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] Input: Change BTN_TOOL_FINGER flag when hover event trigger
  2016-05-23 14:28           ` 廖崇榮
@ 2016-05-26  0:11             ` 'Dmitry Torokhov'
  0 siblings, 0 replies; 9+ messages in thread
From: 'Dmitry Torokhov' @ 2016-05-26  0:11 UTC (permalink / raw)
  To: 廖崇榮
  Cc: linux-input, linux-kernel, zac.hsieh,
	'黃世鵬 經理',
	'Charles Mooney', 'Agnes Cheng', 'jeff'

Hi KT,

On Mon, May 23, 2016 at 10:28:59PM +0800, 廖崇榮 wrote:
> Hi Dmitry,
> 
> Thanks for your confirmation.
> 
> I think the best and simplest way is to add below code to emit BTN_TOOL_FINGER if hover condition meets.
> 
> input_report_key(dev, BTN_TOOL_FINGER, input_mt_get_value(dev, ABS_DISTANCE));
> 
> Is it ok for you?
> 
> 	if (use_count) {
> 		if (count == 0 &&
> 		    !test_bit(ABS_MT_DISTANCE, dev->absbit) &&
> 		    test_bit(ABS_DISTANCE, dev->absbit) &&
> 		    input_abs_get_val(dev, ABS_DISTANCE) != 0) {
> 
> 			/* Emit BTN_TOOL_FINGER*/
> 			input_report_key(dev, BTN_TOOL_FINGER, input_mt_get_value(dev, ABS_DISTANCE));

I do not see why we need to emit BTN_TOOL_FINGER event twice, once
here, and second time in input_mt_report_finger_count():

- If distance is non-zero (and all other conditions are true) then count
  will be 1 and will be calling input_mt_report_finger_count(dev, 1)
  which will result in sending EV_KEY/BTN_TOOL_FINGER/1 event.

- If distance is 0 then count will remain 0 and
  input_mt_report_finger_count(dev, 0) will result in
  EV_KEY/BTN_TOOL_FINGER/0.

which is exactly what we need as far as I can see.

Thanks.

> 
> 			count = 1;
> 		}
> 
> B.R  KT
> -----Original Message-----
> From: 'Dmitry Torokhov' [mailto:dmitry.torokhov@gmail.com] 
> Sent: Friday, May 20, 2016 8:52 AM
> To: 廖崇榮
> Cc: linux-input@vger.kernel.org; linux-kernel@vger.kernel.org; zac.hsieh@emc.com.tw; '黃世鵬 經理'; 'Charles Mooney'; 'Agnes Cheng'; 'jeff'
> Subject: Re: [PATCH] Input: Change BTN_TOOL_FINGER flag when hover event trigger
> 
> On Tue, May 17, 2016 at 10:20:40PM +0800, 廖崇榮 wrote:
> > Hi Dmitry,
> > 
> > I want to confirm my thought for your idea to avoid misunderstanding.
> > I think you want to encapsulate " BTN_TOOL_FINGER" in the [input_mt_report_pointer_emulation] if hover happen.
> > Vendor driver only report "ABS_DISTANCE" and let [input_mt_report_pointer_emulation] emit BTN_TOOL_FINGER report without change function parameter.
> > 
> > Please let me know if my misunderstand about your idea.
> 
> Yes, that is correct. Something like this:
> 
> diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index 54fce56..a1bbec9 100644
> --- a/drivers/input/input-mt.c
> +++ b/drivers/input/input-mt.c
> @@ -218,8 +218,23 @@ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
>  	}
>  
>  	input_event(dev, EV_KEY, BTN_TOUCH, count > 0);
> -	if (use_count)
> +
> +	if (use_count) {
> +		if (count == 0 &&
> +		    !test_bit(ABS_MT_DISTANCE, dev->absbit) &&
> +		    test_bit(ABS_DISTANCE, dev->absbit) &&
> +		    input_abs_get_val(dev, ABS_DISTANCE) != 0) {
> +			/*
> +			 * Force reporting BTN_TOOL_FINGER for devices that
> +			 * only report general hover (and not per-contact
> +			 * distance) when contact is in proximity but not
> +			 * on the surface.
> +			 */
> +			count = 1;
> +		}
> +
>  		input_mt_report_finger_count(dev, count);
> +	}
>  
>  	if (oldest) {
>  		int x = input_mt_get_value(oldest, ABS_MT_POSITION_X);
> 
> --
> Dmitry
> 

-- 
Dmitry

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH] Input: Change BTN_TOOL_FINGER flag when hover event trigger
  2016-05-20  0:51         ` 'Dmitry Torokhov'
@ 2016-05-23 14:28           ` 廖崇榮
  2016-05-26  0:11             ` 'Dmitry Torokhov'
  0 siblings, 1 reply; 9+ messages in thread
From: 廖崇榮 @ 2016-05-23 14:28 UTC (permalink / raw)
  To: 'Dmitry Torokhov'
  Cc: linux-input, linux-kernel, zac.hsieh,
	'黃世鵬 經理',
	'Charles Mooney', 'Agnes Cheng', 'jeff'

Hi Dmitry,

Thanks for your confirmation.

I think the best and simplest way is to add below code to emit BTN_TOOL_FINGER if hover condition meets.

input_report_key(dev, BTN_TOOL_FINGER, input_mt_get_value(dev, ABS_DISTANCE));

Is it ok for you?

	if (use_count) {
		if (count == 0 &&
		    !test_bit(ABS_MT_DISTANCE, dev->absbit) &&
		    test_bit(ABS_DISTANCE, dev->absbit) &&
		    input_abs_get_val(dev, ABS_DISTANCE) != 0) {

			/* Emit BTN_TOOL_FINGER*/
			input_report_key(dev, BTN_TOOL_FINGER, input_mt_get_value(dev, ABS_DISTANCE));

			count = 1;
		}

B.R  KT
-----Original Message-----
From: 'Dmitry Torokhov' [mailto:dmitry.torokhov@gmail.com] 
Sent: Friday, May 20, 2016 8:52 AM
To: 廖崇榮
Cc: linux-input@vger.kernel.org; linux-kernel@vger.kernel.org; zac.hsieh@emc.com.tw; '黃世鵬 經理'; 'Charles Mooney'; 'Agnes Cheng'; 'jeff'
Subject: Re: [PATCH] Input: Change BTN_TOOL_FINGER flag when hover event trigger

On Tue, May 17, 2016 at 10:20:40PM +0800, 廖崇榮 wrote:
> Hi Dmitry,
> 
> I want to confirm my thought for your idea to avoid misunderstanding.
> I think you want to encapsulate " BTN_TOOL_FINGER" in the [input_mt_report_pointer_emulation] if hover happen.
> Vendor driver only report "ABS_DISTANCE" and let [input_mt_report_pointer_emulation] emit BTN_TOOL_FINGER report without change function parameter.
> 
> Please let me know if my misunderstand about your idea.

Yes, that is correct. Something like this:

diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index 54fce56..a1bbec9 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -218,8 +218,23 @@ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
 	}
 
 	input_event(dev, EV_KEY, BTN_TOUCH, count > 0);
-	if (use_count)
+
+	if (use_count) {
+		if (count == 0 &&
+		    !test_bit(ABS_MT_DISTANCE, dev->absbit) &&
+		    test_bit(ABS_DISTANCE, dev->absbit) &&
+		    input_abs_get_val(dev, ABS_DISTANCE) != 0) {
+			/*
+			 * Force reporting BTN_TOOL_FINGER for devices that
+			 * only report general hover (and not per-contact
+			 * distance) when contact is in proximity but not
+			 * on the surface.
+			 */
+			count = 1;
+		}
+
 		input_mt_report_finger_count(dev, count);
+	}
 
 	if (oldest) {
 		int x = input_mt_get_value(oldest, ABS_MT_POSITION_X);

--
Dmitry

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Input: Change BTN_TOOL_FINGER flag when hover event trigger
  2016-05-17 14:20       ` 廖崇榮
@ 2016-05-20  0:51         ` 'Dmitry Torokhov'
  2016-05-23 14:28           ` 廖崇榮
  0 siblings, 1 reply; 9+ messages in thread
From: 'Dmitry Torokhov' @ 2016-05-20  0:51 UTC (permalink / raw)
  To: 廖崇榮
  Cc: linux-input, linux-kernel, zac.hsieh,
	'黃世鵬 經理',
	'Charles Mooney', 'Agnes Cheng', 'jeff'

On Tue, May 17, 2016 at 10:20:40PM +0800, 廖崇榮 wrote:
> Hi Dmitry,
> 
> I want to confirm my thought for your idea to avoid misunderstanding.
> I think you want to encapsulate " BTN_TOOL_FINGER" in the [input_mt_report_pointer_emulation] if hover happen.
> Vendor driver only report "ABS_DISTANCE" and let [input_mt_report_pointer_emulation] emit BTN_TOOL_FINGER report without change function parameter.
> 
> Please let me know if my misunderstand about your idea.

Yes, that is correct. Something like this:

diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
index 54fce56..a1bbec9 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -218,8 +218,23 @@ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
 	}
 
 	input_event(dev, EV_KEY, BTN_TOUCH, count > 0);
-	if (use_count)
+
+	if (use_count) {
+		if (count == 0 &&
+		    !test_bit(ABS_MT_DISTANCE, dev->absbit) &&
+		    test_bit(ABS_DISTANCE, dev->absbit) &&
+		    input_abs_get_val(dev, ABS_DISTANCE) != 0) {
+			/*
+			 * Force reporting BTN_TOOL_FINGER for devices that
+			 * only report general hover (and not per-contact
+			 * distance) when contact is in proximity but not
+			 * on the surface.
+			 */
+			count = 1;
+		}
+
 		input_mt_report_finger_count(dev, count);
+	}
 
 	if (oldest) {
 		int x = input_mt_get_value(oldest, ABS_MT_POSITION_X);

-- 
Dmitry

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* RE: [PATCH] Input: Change BTN_TOOL_FINGER flag when hover event trigger
  2016-05-16 17:53     ` Dmitry Torokhov
@ 2016-05-17 14:20       ` 廖崇榮
  2016-05-20  0:51         ` 'Dmitry Torokhov'
  0 siblings, 1 reply; 9+ messages in thread
From: 廖崇榮 @ 2016-05-17 14:20 UTC (permalink / raw)
  To: 'Dmitry Torokhov'
  Cc: linux-input, linux-kernel, zac.hsieh,
	'黃世鵬 經理',
	'Charles Mooney', 'Agnes Cheng', 'jeff'

Hi Dmitry,

I want to confirm my thought for your idea to avoid misunderstanding.
I think you want to encapsulate " BTN_TOOL_FINGER" in the [input_mt_report_pointer_emulation] if hover happen.
Vendor driver only report "ABS_DISTANCE" and let [input_mt_report_pointer_emulation] emit BTN_TOOL_FINGER report without change function parameter.

Please let me know if my misunderstand about your idea.

Thanks  KT

-----Original Message-----
From: Dmitry Torokhov [mailto:dmitry.torokhov@gmail.com] 
Sent: Tuesday, May 17, 2016 1:54 AM
To: 廖崇榮
Cc: linux-input@vger.kernel.org; linux-kernel@vger.kernel.org; zac.hsieh@emc.com.tw; 黃世鵬 經理; 'Charles Mooney'; 'Agnes Cheng'
Subject: Re: [PATCH] Input: Change BTN_TOOL_FINGER flag when hover event trigger

Hi Kt,

On Mon, May 16, 2016 at 07:27:25PM +0800, 廖崇榮 wrote:
> 
> Only ABS_DISTANCE is not enough for upper OS to distingiush hover 
> event be triggered from object from faraway to and close touchpad 
> surface or from object prepare to leave the touchpad surface. Add 
> BTN_TOOL_FINGER flag to help it.
> 
>                  object_from_faraway    object_inside_hover_area
> object_touch_surface
> BTN_TOUCH                 0                          0             1
> BTN_TOOL_FINGER           0                          1              1
> ABS_DISTANCE               0                           1             0
> 
> Signed-off by: Duson Lin <dusonlin@emc.com.tw>

I was wondering if we could do without modifying all the drivers that are using input_mt_report_pointer_emulation(), by figuring out if we should be emitting BTN_TOOL_FINGER right there:

"If device supports ABS_DISTANCE and does not support ABS_MT_DISTANCE and ABS_DISTANCE != 0 is reported in current frame and there are no other contacts then report BTN_TOOL_FINGER."

Thanks.

--
Dmitry

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Input: Change BTN_TOOL_FINGER flag when hover event trigger
  2016-05-16 11:27   ` 廖崇榮
@ 2016-05-16 17:53     ` Dmitry Torokhov
  2016-05-17 14:20       ` 廖崇榮
  0 siblings, 1 reply; 9+ messages in thread
From: Dmitry Torokhov @ 2016-05-16 17:53 UTC (permalink / raw)
  To: 廖崇榮
  Cc: linux-input, linux-kernel, zac.hsieh,
	黃世鵬 經理,
	'Charles Mooney', 'Agnes Cheng'

Hi Kt,

On Mon, May 16, 2016 at 07:27:25PM +0800, 廖崇榮 wrote:
> 
> Only ABS_DISTANCE is not enough for upper OS to distingiush hover event be
> triggered from object from faraway to and close touchpad surface or from
> object prepare to leave the touchpad surface. Add BTN_TOOL_FINGER flag to
> help it.
> 
>                  object_from_faraway    object_inside_hover_area
> object_touch_surface
> BTN_TOUCH                 0                          0             1
> BTN_TOOL_FINGER           0                          1              1
> ABS_DISTANCE               0                           1             0
> 
> Signed-off by: Duson Lin <dusonlin@emc.com.tw>

I was wondering if we could do without modifying all the drivers that
are using input_mt_report_pointer_emulation(), by figuring out if we
should be emitting BTN_TOOL_FINGER right there:

"If device supports ABS_DISTANCE and does not support ABS_MT_DISTANCE and
ABS_DISTANCE != 0 is reported in current frame and there are no other
contacts then report BTN_TOOL_FINGER."

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH] Input: Change BTN_TOOL_FINGER flag when hover event trigger
       [not found] ` <006901d1acea$8207d090$861771b0$@emc.com.tw>
@ 2016-05-16 11:27   ` 廖崇榮
  2016-05-16 17:53     ` Dmitry Torokhov
  0 siblings, 1 reply; 9+ messages in thread
From: 廖崇榮 @ 2016-05-16 11:27 UTC (permalink / raw)
  To: linux-input, linux-kernel, Dmitry.torokhov
  Cc: zac.hsieh, 黃世鵬 經理,
	'Charles Mooney', 'Agnes Cheng'

[-- Attachment #1: Type: text/plain, Size: 12180 bytes --]


Only ABS_DISTANCE is not enough for upper OS to distingiush hover event be
triggered from object from faraway to and close touchpad surface or from
object prepare to leave the touchpad surface. Add BTN_TOOL_FINGER flag to
help it.

                 object_from_faraway    object_inside_hover_area
object_touch_surface
BTN_TOUCH                 0                          0             1
BTN_TOOL_FINGER           0                          1              1
ABS_DISTANCE               0                           1             0

Signed-off by: Duson Lin <dusonlin@emc.com.tw>
---
 drivers/hid/hid-magicmouse.c             |  2 +-
 drivers/input/input-mt.c                 |  7 +++++--
 drivers/input/mouse/elan_i2c_core.c      | 15 +++++++++------
 drivers/input/mouse/elantech.c           |  2 +-
 drivers/input/mouse/focaltech.c          |  2 +-
 drivers/input/mouse/synaptics.c          |  2 +-
 drivers/input/touchscreen/atmel_mxt_ts.c |  2 +-
 drivers/input/touchscreen/edt-ft5x06.c   |  2 +-
 drivers/input/touchscreen/egalax_ts.c    |  2 +-
 drivers/input/touchscreen/ili210x.c      |  2 +-
 drivers/input/touchscreen/mms114.c       |  4 ++--
 drivers/input/touchscreen/penmount.c     |  2 +-
 drivers/input/touchscreen/rohm_bu21023.c |  2 +-
drivers/input/touchscreen/wacom_w8001.c  |  2 +-
 include/linux/input/mt.h                 |  3 ++-
 15 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index d6fa496..584e98b 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -353,7 +353,7 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 		input_report_rel(input, REL_Y, y);
 	} else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
 		input_report_key(input, BTN_MOUSE, clicks & 1);
-		input_mt_report_pointer_emulation(input, true);
+		input_mt_report_pointer_emulation(input, true, false);
 	}
 
 	input_sync(input);
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index
54fce56..30855a5 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -184,6 +184,7 @@ EXPORT_SYMBOL(input_mt_report_finger_count);
  * input_mt_report_pointer_emulation() - common pointer emulation
  * @dev: input device with allocated MT slots
  * @use_count: report number of active contacts as finger count
+ * @hover: report ABS_DISTANCE as hover event
  *
  * Performs legacy pointer emulation via BTN_TOUCH, ABS_X, ABS_Y and
  * ABS_PRESSURE. Touchpad finger count is emulated if use_count is true.
@@ -191,7 +192,8 @@ EXPORT_SYMBOL(input_mt_report_finger_count);
  * The input core ensures only the KEY and ABS axes already setup for
  * this device will produce output.
  */
-void input_mt_report_pointer_emulation(struct input_dev *dev, bool
use_count)
+void input_mt_report_pointer_emulation(struct input_dev *dev, bool
use_count,
+					bool hover)
 {
 	struct input_mt *mt = dev->mt;
 	struct input_mt_slot *oldest;
@@ -220,6 +222,7 @@ void input_mt_report_pointer_emulation(struct input_dev
*dev, bool use_count)
 	input_event(dev, EV_KEY, BTN_TOUCH, count > 0);
 	if (use_count)
 		input_mt_report_finger_count(dev, count);
+	input_event(dev, EV_ABS, ABS_DISTANCE, hover);
 
 	if (oldest) {
 		int x = input_mt_get_value(oldest, ABS_MT_POSITION_X); @@
-290,7 +293,7 @@ void input_mt_sync_frame(struct input_dev *dev)
 	if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags &
INPUT_MT_SEMI_MT))
 		use_count = true;
 
-	input_mt_report_pointer_emulation(dev, use_count);
+	input_mt_report_pointer_emulation(dev, use_count, false);
 
 	mt->frame++;
 }
diff --git a/drivers/input/mouse/elan_i2c_core.c
b/drivers/input/mouse/elan_i2c_core.c
index 2f58985..8b5e75a 100644
--- a/drivers/input/mouse/elan_i2c_core.c
+++ b/drivers/input/mouse/elan_i2c_core.c
@@ -4,7 +4,7 @@
  * Copyright (c) 2013 ELAN Microelectronics Corp.
  *
  * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
- * Version: 1.6.0
+ * Version: 1.6.2
  *
  * Based on cyapa driver:
  * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
@@ -40,7 +40,7 @@
 #include "elan_i2c.h"
 
 #define DRIVER_NAME		"elan_i2c"
-#define ELAN_DRIVER_VERSION	"1.6.1"
+#define ELAN_DRIVER_VERSION	"1.6.2"
 #define ELAN_VENDOR_ID		0x04f3
 #define ETP_MAX_PRESSURE	255
 #define ETP_FWIDTH_REDUCE	90
@@ -845,7 +845,7 @@ static void elan_report_absolute(struct elan_tp_data
*data, u8 *packet)  {
 	struct input_dev *input = data->input;
 	u8 *finger_data = &packet[ETP_FINGER_DATA_OFFSET];
-	int i;
+	int i, valid_count = 0;
 	u8 tp_info = packet[ETP_TOUCH_INFO_OFFSET];
 	u8 hover_info = packet[ETP_HOVER_INFO_OFFSET];
 	bool contact_valid, hover_event;
@@ -855,13 +855,16 @@ static void elan_report_absolute(struct elan_tp_data
*data, u8 *packet)
 		contact_valid = tp_info & (1U << (3 + i));
 		elan_report_contact(data, i, contact_valid, finger_data);
 
-		if (contact_valid)
+		if (contact_valid) {
 			finger_data += ETP_FINGER_DATA_LEN;
+			valid_count++;
+		}
 	}
 
 	input_report_key(input, BTN_LEFT, tp_info & 0x01);
-	input_report_abs(input, ABS_DISTANCE, hover_event != 0);
-	input_mt_report_pointer_emulation(input, true);
+	input_report_key(input, BTN_TOOL_FINGER,
+			((hover_event != 0) || (valid_count > 0)));
+	input_mt_report_pointer_emulation(input, false, hover_event != 0);
 	input_sync(input);
 }
 
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 78f93cf..cc13e12 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -558,7 +558,7 @@ static void elantech_input_sync_v4(struct psmouse
*psmouse)
 		input_report_key(dev, BTN_MIDDLE, packet[0] & 0x04);
 	}
 
-	input_mt_report_pointer_emulation(dev, true);
+	input_mt_report_pointer_emulation(dev, true, false);
 	input_sync(dev);
 }
 
diff --git a/drivers/input/mouse/focaltech.c
b/drivers/input/mouse/focaltech.c index c8c6a8c..f4339ac 100644
--- a/drivers/input/mouse/focaltech.c
+++ b/drivers/input/mouse/focaltech.c
@@ -144,7 +144,7 @@ static void focaltech_report_state(struct psmouse
*psmouse)
 			input_report_abs(dev, ABS_TOOL_WIDTH, state->width);
 		}
 	}
-	input_mt_report_pointer_emulation(dev, true);
+	input_mt_report_pointer_emulation(dev, true, false);
 
 	input_report_key(psmouse->dev, BTN_LEFT, state->pressed);
 	input_sync(psmouse->dev);
diff --git a/drivers/input/mouse/synaptics.c
b/drivers/input/mouse/synaptics.c index a41d832..09fa835 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -944,7 +944,7 @@ static void synaptics_report_mt_data(struct psmouse
*psmouse,
 	input_mt_drop_unused(dev);
 
 	/* Don't use active slot count to generate BTN_TOOL events. */
-	input_mt_report_pointer_emulation(dev, false);
+	input_mt_report_pointer_emulation(dev, false, false);
 
 	/* Send the number of fingers reported by touchpad itself. */
 	input_mt_report_finger_count(dev, num_fingers); diff --git
a/drivers/input/touchscreen/atmel_mxt_ts.c
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 2160512..0ab0d53 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -683,7 +683,7 @@ static void mxt_input_button(struct mxt_data *data, u8
*message)  static void mxt_input_sync(struct mxt_data *data)  {
 	input_mt_report_pointer_emulation(data->input_dev,
-					  data->pdata->t19_num_keys);
+					  data->pdata->t19_num_keys, false);
 	input_sync(data->input_dev);
 }
 
diff --git a/drivers/input/touchscreen/edt-ft5x06.c
b/drivers/input/touchscreen/edt-ft5x06.c
index 23fbe38..6533d8e 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -250,7 +250,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void
*dev_id)
 		input_report_abs(tsdata->input, ABS_MT_POSITION_Y, y);
 	}
 
-	input_mt_report_pointer_emulation(tsdata->input, true);
+	input_mt_report_pointer_emulation(tsdata->input, true, false);
 	input_sync(tsdata->input);
 
 out:
diff --git a/drivers/input/touchscreen/egalax_ts.c
b/drivers/input/touchscreen/egalax_ts.c
index 1afc08b..c420336 100644
--- a/drivers/input/touchscreen/egalax_ts.c
+++ b/drivers/input/touchscreen/egalax_ts.c
@@ -113,7 +113,7 @@ static irqreturn_t egalax_ts_interrupt(int irq, void
*dev_id)
 		input_report_abs(input_dev, ABS_MT_PRESSURE, z);
 	}
 
-	input_mt_report_pointer_emulation(input_dev, true);
+	input_mt_report_pointer_emulation(input_dev, true, false);
 	input_sync(input_dev);
 
 	return IRQ_HANDLED;
diff --git a/drivers/input/touchscreen/ili210x.c
b/drivers/input/touchscreen/ili210x.c
index ddf694b..5301e2b 100644
--- a/drivers/input/touchscreen/ili210x.c
+++ b/drivers/input/touchscreen/ili210x.c
@@ -99,7 +99,7 @@ static void ili210x_report_events(struct input_dev *input,
 		}
 	}
 
-	input_mt_report_pointer_emulation(input, false);
+	input_mt_report_pointer_emulation(input, false, false);
 	input_sync(input);
 }
 
diff --git a/drivers/input/touchscreen/mms114.c
b/drivers/input/touchscreen/mms114.c
index 1fafc9f..4f7b20a 100644
--- a/drivers/input/touchscreen/mms114.c
+++ b/drivers/input/touchscreen/mms114.c
@@ -221,7 +221,7 @@ static irqreturn_t mms114_interrupt(int irq, void
*dev_id)
 	for (index = 0; index < touch_size; index++)
 		mms114_process_mt(data, touch + index);
 
-	input_mt_report_pointer_emulation(data->input_dev, true);
+	input_mt_report_pointer_emulation(data->input_dev, true, false);
 	input_sync(data->input_dev);
 
 out:
@@ -528,7 +528,7 @@ static int __maybe_unused mms114_suspend(struct device
*dev)
 		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
false);
 	}
 
-	input_mt_report_pointer_emulation(input_dev, true);
+	input_mt_report_pointer_emulation(input_dev, true, false);
 	input_sync(input_dev);
 
 	mutex_lock(&input_dev->mutex);
diff --git a/drivers/input/touchscreen/penmount.c
b/drivers/input/touchscreen/penmount.c
index 417d873..ceaf1ee 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -81,7 +81,7 @@ static void pm_mtevent(struct pm *pm, struct input_dev
*input)
 		}
 	}
 
-	input_mt_report_pointer_emulation(input, true);
+	input_mt_report_pointer_emulation(input, true, false);
 	input_sync(input);
 }
 
diff --git a/drivers/input/touchscreen/rohm_bu21023.c
b/drivers/input/touchscreen/rohm_bu21023.c
index 611156a..aecd457 100644
--- a/drivers/input/touchscreen/rohm_bu21023.c
+++ b/drivers/input/touchscreen/rohm_bu21023.c
@@ -627,7 +627,7 @@ static irqreturn_t rohm_ts_soft_irq(int irq, void
*dev_id)
 		}
 
 		input_mt_sync_frame(input_dev);
-		input_mt_report_pointer_emulation(input_dev, true);
+		input_mt_report_pointer_emulation(input_dev, true, false);
 		input_sync(input_dev);
 
 		ts->finger_count = finger_count;
diff --git a/drivers/input/touchscreen/wacom_w8001.c
b/drivers/input/touchscreen/wacom_w8001.c
index bab3c6a..05164b1 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -176,7 +176,7 @@ static void parse_multi_touch(struct w8001 *w8001)
 	if (w8001->type != BTN_TOOL_PEN &&
 			    w8001->type != BTN_TOOL_RUBBER) {
 		w8001->type = count == 1 ? BTN_TOOL_FINGER : KEY_RESERVED;
-		input_mt_report_pointer_emulation(dev, true);
+		input_mt_report_pointer_emulation(dev, true, false);
 	}
 
 	input_sync(dev);
diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h index
d7188de..67c7bdd 100644
--- a/include/linux/input/mt.h
+++ b/include/linux/input/mt.h
@@ -104,7 +104,8 @@ void input_mt_report_slot_state(struct input_dev *dev,
 				unsigned int tool_type, bool active);
 
 void input_mt_report_finger_count(struct input_dev *dev, int count); -void
input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count);
+void input_mt_report_pointer_emulation(struct input_dev *dev, bool
use_count,
+					bool hover);
 void input_mt_drop_unused(struct input_dev *dev);
 
 void input_mt_sync_frame(struct input_dev *dev);
--
2.1.4






[-- Attachment #2: 0001-Input-Change-BTN_TOOL_FINGER-flag-when-hover-event-t.patch --]
[-- Type: application/octet-stream, Size: 12411 bytes --]

IFrom 7ab46f3f3560b404c07f89632e2fbfacfa447afb Mon Sep 17 00:00:00 2001
From: Duson Lin <dusonlin@emc.com.tw>
Date: Sat, 2 Apr 2016 21:26:18 -0700
Subject: [PATCH] Input: Change BTN_TOOL_FINGER flag when hover event trigger

Only ABS_DISTANCE is not enough for upper OS to distingiush hover event
be triggered from object from faraway to and close touchpad surface or
from object prepare to leave the touchpad surface. Add BTN_TOOL_FINGER
flag to help it.

                 object_from_faraway    object_inside_hover_area  object_touch_surface
BTN_TOUCH                 0                          0                        1
BTN_TOOL_FINGER           0                          1                        1
ABS_DISTANCE              0                          1                        0

Signed-off by: Duson Lin <dusonlin@emc.com.tw>
---
 drivers/hid/hid-magicmouse.c             |  2 +-
 drivers/input/input-mt.c                 |  7 +++++--
 drivers/input/mouse/elan_i2c_core.c      | 15 +++++++++------
 drivers/input/mouse/elantech.c           |  2 +-
 drivers/input/mouse/focaltech.c          |  2 +-
 drivers/input/mouse/synaptics.c          |  2 +-
 drivers/input/touchscreen/atmel_mxt_ts.c |  2 +-
 drivers/input/touchscreen/edt-ft5x06.c   |  2 +-
 drivers/input/touchscreen/egalax_ts.c    |  2 +-
 drivers/input/touchscreen/ili210x.c      |  2 +-
 drivers/input/touchscreen/mms114.c       |  4 ++--
 drivers/input/touchscreen/penmount.c     |  2 +-
 drivers/input/touchscreen/rohm_bu21023.c |  2 +-
 drivers/input/touchscreen/wacom_w8001.c  |  2 +-
 include/linux/input/mt.h                 |  3 ++-
 15 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index d6fa496..584e98b 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -353,7 +353,7 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 		input_report_rel(input, REL_Y, y);
 	} else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
 		input_report_key(input, BTN_MOUSE, clicks & 1);
-		input_mt_report_pointer_emulation(input, true);
+		input_mt_report_pointer_emulation(input, true, false);
 	}
 
 	input_sync(input);
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
index 54fce56..30855a5 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -184,6 +184,7 @@ EXPORT_SYMBOL(input_mt_report_finger_count);
  * input_mt_report_pointer_emulation() - common pointer emulation
  * @dev: input device with allocated MT slots
  * @use_count: report number of active contacts as finger count
+ * @hover: report ABS_DISTANCE as hover event
  *
  * Performs legacy pointer emulation via BTN_TOUCH, ABS_X, ABS_Y and
  * ABS_PRESSURE. Touchpad finger count is emulated if use_count is true.
@@ -191,7 +192,8 @@ EXPORT_SYMBOL(input_mt_report_finger_count);
  * The input core ensures only the KEY and ABS axes already setup for
  * this device will produce output.
  */
-void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
+void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count,
+					bool hover)
 {
 	struct input_mt *mt = dev->mt;
 	struct input_mt_slot *oldest;
@@ -220,6 +222,7 @@ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
 	input_event(dev, EV_KEY, BTN_TOUCH, count > 0);
 	if (use_count)
 		input_mt_report_finger_count(dev, count);
+	input_event(dev, EV_ABS, ABS_DISTANCE, hover);
 
 	if (oldest) {
 		int x = input_mt_get_value(oldest, ABS_MT_POSITION_X);
@@ -290,7 +293,7 @@ void input_mt_sync_frame(struct input_dev *dev)
 	if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags & INPUT_MT_SEMI_MT))
 		use_count = true;
 
-	input_mt_report_pointer_emulation(dev, use_count);
+	input_mt_report_pointer_emulation(dev, use_count, false);
 
 	mt->frame++;
 }
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
index 2f58985..8b5e75a 100644
--- a/drivers/input/mouse/elan_i2c_core.c
+++ b/drivers/input/mouse/elan_i2c_core.c
@@ -4,7 +4,7 @@
  * Copyright (c) 2013 ELAN Microelectronics Corp.
  *
  * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
- * Version: 1.6.0
+ * Version: 1.6.2
  *
  * Based on cyapa driver:
  * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
@@ -40,7 +40,7 @@
 #include "elan_i2c.h"
 
 #define DRIVER_NAME		"elan_i2c"
-#define ELAN_DRIVER_VERSION	"1.6.1"
+#define ELAN_DRIVER_VERSION	"1.6.2"
 #define ELAN_VENDOR_ID		0x04f3
 #define ETP_MAX_PRESSURE	255
 #define ETP_FWIDTH_REDUCE	90
@@ -845,7 +845,7 @@ static void elan_report_absolute(struct elan_tp_data *data, u8 *packet)
 {
 	struct input_dev *input = data->input;
 	u8 *finger_data = &packet[ETP_FINGER_DATA_OFFSET];
-	int i;
+	int i, valid_count = 0;
 	u8 tp_info = packet[ETP_TOUCH_INFO_OFFSET];
 	u8 hover_info = packet[ETP_HOVER_INFO_OFFSET];
 	bool contact_valid, hover_event;
@@ -855,13 +855,16 @@ static void elan_report_absolute(struct elan_tp_data *data, u8 *packet)
 		contact_valid = tp_info & (1U << (3 + i));
 		elan_report_contact(data, i, contact_valid, finger_data);
 
-		if (contact_valid)
+		if (contact_valid) {
 			finger_data += ETP_FINGER_DATA_LEN;
+			valid_count++;
+		}
 	}
 
 	input_report_key(input, BTN_LEFT, tp_info & 0x01);
-	input_report_abs(input, ABS_DISTANCE, hover_event != 0);
-	input_mt_report_pointer_emulation(input, true);
+	input_report_key(input, BTN_TOOL_FINGER,
+			((hover_event != 0) || (valid_count > 0)));
+	input_mt_report_pointer_emulation(input, false, hover_event != 0);
 	input_sync(input);
 }
 
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 78f93cf..cc13e12 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -558,7 +558,7 @@ static void elantech_input_sync_v4(struct psmouse *psmouse)
 		input_report_key(dev, BTN_MIDDLE, packet[0] & 0x04);
 	}
 
-	input_mt_report_pointer_emulation(dev, true);
+	input_mt_report_pointer_emulation(dev, true, false);
 	input_sync(dev);
 }
 
diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c
index c8c6a8c..f4339ac 100644
--- a/drivers/input/mouse/focaltech.c
+++ b/drivers/input/mouse/focaltech.c
@@ -144,7 +144,7 @@ static void focaltech_report_state(struct psmouse *psmouse)
 			input_report_abs(dev, ABS_TOOL_WIDTH, state->width);
 		}
 	}
-	input_mt_report_pointer_emulation(dev, true);
+	input_mt_report_pointer_emulation(dev, true, false);
 
 	input_report_key(psmouse->dev, BTN_LEFT, state->pressed);
 	input_sync(psmouse->dev);
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index a41d832..09fa835 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -944,7 +944,7 @@ static void synaptics_report_mt_data(struct psmouse *psmouse,
 	input_mt_drop_unused(dev);
 
 	/* Don't use active slot count to generate BTN_TOOL events. */
-	input_mt_report_pointer_emulation(dev, false);
+	input_mt_report_pointer_emulation(dev, false, false);
 
 	/* Send the number of fingers reported by touchpad itself. */
 	input_mt_report_finger_count(dev, num_fingers);
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 2160512..0ab0d53 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -683,7 +683,7 @@ static void mxt_input_button(struct mxt_data *data, u8 *message)
 static void mxt_input_sync(struct mxt_data *data)
 {
 	input_mt_report_pointer_emulation(data->input_dev,
-					  data->pdata->t19_num_keys);
+					  data->pdata->t19_num_keys, false);
 	input_sync(data->input_dev);
 }
 
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 23fbe38..6533d8e 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -250,7 +250,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
 		input_report_abs(tsdata->input, ABS_MT_POSITION_Y, y);
 	}
 
-	input_mt_report_pointer_emulation(tsdata->input, true);
+	input_mt_report_pointer_emulation(tsdata->input, true, false);
 	input_sync(tsdata->input);
 
 out:
diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c
index 1afc08b..c420336 100644
--- a/drivers/input/touchscreen/egalax_ts.c
+++ b/drivers/input/touchscreen/egalax_ts.c
@@ -113,7 +113,7 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id)
 		input_report_abs(input_dev, ABS_MT_PRESSURE, z);
 	}
 
-	input_mt_report_pointer_emulation(input_dev, true);
+	input_mt_report_pointer_emulation(input_dev, true, false);
 	input_sync(input_dev);
 
 	return IRQ_HANDLED;
diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c
index ddf694b..5301e2b 100644
--- a/drivers/input/touchscreen/ili210x.c
+++ b/drivers/input/touchscreen/ili210x.c
@@ -99,7 +99,7 @@ static void ili210x_report_events(struct input_dev *input,
 		}
 	}
 
-	input_mt_report_pointer_emulation(input, false);
+	input_mt_report_pointer_emulation(input, false, false);
 	input_sync(input);
 }
 
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c
index 1fafc9f..4f7b20a 100644
--- a/drivers/input/touchscreen/mms114.c
+++ b/drivers/input/touchscreen/mms114.c
@@ -221,7 +221,7 @@ static irqreturn_t mms114_interrupt(int irq, void *dev_id)
 	for (index = 0; index < touch_size; index++)
 		mms114_process_mt(data, touch + index);
 
-	input_mt_report_pointer_emulation(data->input_dev, true);
+	input_mt_report_pointer_emulation(data->input_dev, true, false);
 	input_sync(data->input_dev);
 
 out:
@@ -528,7 +528,7 @@ static int __maybe_unused mms114_suspend(struct device *dev)
 		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, false);
 	}
 
-	input_mt_report_pointer_emulation(input_dev, true);
+	input_mt_report_pointer_emulation(input_dev, true, false);
 	input_sync(input_dev);
 
 	mutex_lock(&input_dev->mutex);
diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
index 417d873..ceaf1ee 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -81,7 +81,7 @@ static void pm_mtevent(struct pm *pm, struct input_dev *input)
 		}
 	}
 
-	input_mt_report_pointer_emulation(input, true);
+	input_mt_report_pointer_emulation(input, true, false);
 	input_sync(input);
 }
 
diff --git a/drivers/input/touchscreen/rohm_bu21023.c b/drivers/input/touchscreen/rohm_bu21023.c
index 611156a..aecd457 100644
--- a/drivers/input/touchscreen/rohm_bu21023.c
+++ b/drivers/input/touchscreen/rohm_bu21023.c
@@ -627,7 +627,7 @@ static irqreturn_t rohm_ts_soft_irq(int irq, void *dev_id)
 		}
 
 		input_mt_sync_frame(input_dev);
-		input_mt_report_pointer_emulation(input_dev, true);
+		input_mt_report_pointer_emulation(input_dev, true, false);
 		input_sync(input_dev);
 
 		ts->finger_count = finger_count;
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c
index bab3c6a..05164b1 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -176,7 +176,7 @@ static void parse_multi_touch(struct w8001 *w8001)
 	if (w8001->type != BTN_TOOL_PEN &&
 			    w8001->type != BTN_TOOL_RUBBER) {
 		w8001->type = count == 1 ? BTN_TOOL_FINGER : KEY_RESERVED;
-		input_mt_report_pointer_emulation(dev, true);
+		input_mt_report_pointer_emulation(dev, true, false);
 	}
 
 	input_sync(dev);
diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h
index d7188de..67c7bdd 100644
--- a/include/linux/input/mt.h
+++ b/include/linux/input/mt.h
@@ -104,7 +104,8 @@ void input_mt_report_slot_state(struct input_dev *dev,
 				unsigned int tool_type, bool active);
 
 void input_mt_report_finger_count(struct input_dev *dev, int count);
-void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count);
+void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count,
+					bool hover);
 void input_mt_drop_unused(struct input_dev *dev);
 
 void input_mt_sync_frame(struct input_dev *dev);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH] Input: Change BTN_TOOL_FINGER flag when hover event trigger
@ 2016-04-11  0:58 DusonLin
  0 siblings, 0 replies; 9+ messages in thread
From: DusonLin @ 2016-04-11  0:58 UTC (permalink / raw)
  To: linux-input, Linux-kernel, 'Dmitry Torokhov'
  Cc: 'jeff', 'Phoenix'

Only ABS_DISTANCE is not enough for upper OS to distingiush hover event
be triggered from object from faraway to and close touchpad surface or
from object prepare to leave the touchpad surface. Add BTN_TOOL_FINGER
flag to help it.

                 object_from_faraway    object_inside_hover_area
object_touch_surface
BTN_TOUCH                 0                          0
1
BTN_TOOL_FINGER           0                          1
1
ABS_DISTANCE              0                          1
0

Signed-off by: Duson Lin <dusonlin@emc.com.tw>
---
 drivers/hid/hid-magicmouse.c             |  2 +-
 drivers/input/input-mt.c                 |  7 +++++--
 drivers/input/mouse/elan_i2c_core.c      | 15 +++++++++------
 drivers/input/mouse/elantech.c           |  2 +-
 drivers/input/mouse/focaltech.c          |  2 +-
 drivers/input/mouse/synaptics.c          |  2 +-
 drivers/input/touchscreen/atmel_mxt_ts.c |  2 +-
 drivers/input/touchscreen/edt-ft5x06.c   |  2 +-
 drivers/input/touchscreen/egalax_ts.c    |  2 +-
 drivers/input/touchscreen/ili210x.c      |  2 +-
 drivers/input/touchscreen/mms114.c       |  4 ++--
 drivers/input/touchscreen/penmount.c     |  2 +-
 drivers/input/touchscreen/rohm_bu21023.c |  2 +-
 drivers/input/touchscreen/wacom_w8001.c  |  2 +-
 include/linux/input/mt.h                 |  3 ++-
 15 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index d6fa496..584e98b 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -353,7 +353,7 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 		input_report_rel(input, REL_Y, y);
 	} else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
 		input_report_key(input, BTN_MOUSE, clicks & 1);
-		input_mt_report_pointer_emulation(input, true);
+		input_mt_report_pointer_emulation(input, true, false);
 	}
 
 	input_sync(input);
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
index 54fce56..30855a5 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -184,6 +184,7 @@ EXPORT_SYMBOL(input_mt_report_finger_count);
  * input_mt_report_pointer_emulation() - common pointer emulation
  * @dev: input device with allocated MT slots
  * @use_count: report number of active contacts as finger count
+ * @hover: report ABS_DISTANCE as hover event
  *
  * Performs legacy pointer emulation via BTN_TOUCH, ABS_X, ABS_Y and
  * ABS_PRESSURE. Touchpad finger count is emulated if use_count is true.
@@ -191,7 +192,8 @@ EXPORT_SYMBOL(input_mt_report_finger_count);
  * The input core ensures only the KEY and ABS axes already setup for
  * this device will produce output.
  */
-void input_mt_report_pointer_emulation(struct input_dev *dev, bool
use_count)
+void input_mt_report_pointer_emulation(struct input_dev *dev, bool
use_count,
+					bool hover)
 {
 	struct input_mt *mt = dev->mt;
 	struct input_mt_slot *oldest;
@@ -220,6 +222,7 @@ void input_mt_report_pointer_emulation(struct input_dev
*dev, bool use_count)
 	input_event(dev, EV_KEY, BTN_TOUCH, count > 0);
 	if (use_count)
 		input_mt_report_finger_count(dev, count);
+	input_event(dev, EV_ABS, ABS_DISTANCE, hover);
 
 	if (oldest) {
 		int x = input_mt_get_value(oldest, ABS_MT_POSITION_X);
@@ -290,7 +293,7 @@ void input_mt_sync_frame(struct input_dev *dev)
 	if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags &
INPUT_MT_SEMI_MT))
 		use_count = true;
 
-	input_mt_report_pointer_emulation(dev, use_count);
+	input_mt_report_pointer_emulation(dev, use_count, false);
 
 	mt->frame++;
 }
diff --git a/drivers/input/mouse/elan_i2c_core.c
b/drivers/input/mouse/elan_i2c_core.c
index 2f58985..8b5e75a 100644
--- a/drivers/input/mouse/elan_i2c_core.c
+++ b/drivers/input/mouse/elan_i2c_core.c
@@ -4,7 +4,7 @@
  * Copyright (c) 2013 ELAN Microelectronics Corp.
  *
  * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
- * Version: 1.6.0
+ * Version: 1.6.2
  *
  * Based on cyapa driver:
  * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
@@ -40,7 +40,7 @@
 #include "elan_i2c.h"
 
 #define DRIVER_NAME		"elan_i2c"
-#define ELAN_DRIVER_VERSION	"1.6.1"
+#define ELAN_DRIVER_VERSION	"1.6.2"
 #define ELAN_VENDOR_ID		0x04f3
 #define ETP_MAX_PRESSURE	255
 #define ETP_FWIDTH_REDUCE	90
@@ -845,7 +845,7 @@ static void elan_report_absolute(struct elan_tp_data
*data, u8 *packet)
 {
 	struct input_dev *input = data->input;
 	u8 *finger_data = &packet[ETP_FINGER_DATA_OFFSET];
-	int i;
+	int i, valid_count = 0;
 	u8 tp_info = packet[ETP_TOUCH_INFO_OFFSET];
 	u8 hover_info = packet[ETP_HOVER_INFO_OFFSET];
 	bool contact_valid, hover_event;
@@ -855,13 +855,16 @@ static void elan_report_absolute(struct elan_tp_data
*data, u8 *packet)
 		contact_valid = tp_info & (1U << (3 + i));
 		elan_report_contact(data, i, contact_valid, finger_data);
 
-		if (contact_valid)
+		if (contact_valid) {
 			finger_data += ETP_FINGER_DATA_LEN;
+			valid_count++;
+		}
 	}
 
 	input_report_key(input, BTN_LEFT, tp_info & 0x01);
-	input_report_abs(input, ABS_DISTANCE, hover_event != 0);
-	input_mt_report_pointer_emulation(input, true);
+	input_report_key(input, BTN_TOOL_FINGER,
+			((hover_event != 0) || (valid_count > 0)));
+	input_mt_report_pointer_emulation(input, false, hover_event != 0);
 	input_sync(input);
 }
 
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 78f93cf..cc13e12 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -558,7 +558,7 @@ static void elantech_input_sync_v4(struct psmouse
*psmouse)
 		input_report_key(dev, BTN_MIDDLE, packet[0] & 0x04);
 	}
 
-	input_mt_report_pointer_emulation(dev, true);
+	input_mt_report_pointer_emulation(dev, true, false);
 	input_sync(dev);
 }
 
diff --git a/drivers/input/mouse/focaltech.c
b/drivers/input/mouse/focaltech.c
index c8c6a8c..f4339ac 100644
--- a/drivers/input/mouse/focaltech.c
+++ b/drivers/input/mouse/focaltech.c
@@ -144,7 +144,7 @@ static void focaltech_report_state(struct psmouse
*psmouse)
 			input_report_abs(dev, ABS_TOOL_WIDTH, state->width);
 		}
 	}
-	input_mt_report_pointer_emulation(dev, true);
+	input_mt_report_pointer_emulation(dev, true, false);
 
 	input_report_key(psmouse->dev, BTN_LEFT, state->pressed);
 	input_sync(psmouse->dev);
diff --git a/drivers/input/mouse/synaptics.c
b/drivers/input/mouse/synaptics.c
index a41d832..09fa835 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -944,7 +944,7 @@ static void synaptics_report_mt_data(struct psmouse
*psmouse,
 	input_mt_drop_unused(dev);
 
 	/* Don't use active slot count to generate BTN_TOOL events. */
-	input_mt_report_pointer_emulation(dev, false);
+	input_mt_report_pointer_emulation(dev, false, false);
 
 	/* Send the number of fingers reported by touchpad itself. */
 	input_mt_report_finger_count(dev, num_fingers);
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 2160512..0ab0d53 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -683,7 +683,7 @@ static void mxt_input_button(struct mxt_data *data, u8
*message)
 static void mxt_input_sync(struct mxt_data *data)
 {
 	input_mt_report_pointer_emulation(data->input_dev,
-					  data->pdata->t19_num_keys);
+					  data->pdata->t19_num_keys, false);
 	input_sync(data->input_dev);
 }
 
diff --git a/drivers/input/touchscreen/edt-ft5x06.c
b/drivers/input/touchscreen/edt-ft5x06.c
index 23fbe38..6533d8e 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -250,7 +250,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void
*dev_id)
 		input_report_abs(tsdata->input, ABS_MT_POSITION_Y, y);
 	}
 
-	input_mt_report_pointer_emulation(tsdata->input, true);
+	input_mt_report_pointer_emulation(tsdata->input, true, false);
 	input_sync(tsdata->input);
 
 out:
diff --git a/drivers/input/touchscreen/egalax_ts.c
b/drivers/input/touchscreen/egalax_ts.c
index 1afc08b..c420336 100644
--- a/drivers/input/touchscreen/egalax_ts.c
+++ b/drivers/input/touchscreen/egalax_ts.c
@@ -113,7 +113,7 @@ static irqreturn_t egalax_ts_interrupt(int irq, void
*dev_id)
 		input_report_abs(input_dev, ABS_MT_PRESSURE, z);
 	}
 
-	input_mt_report_pointer_emulation(input_dev, true);
+	input_mt_report_pointer_emulation(input_dev, true, false);
 	input_sync(input_dev);
 
 	return IRQ_HANDLED;
diff --git a/drivers/input/touchscreen/ili210x.c
b/drivers/input/touchscreen/ili210x.c
index ddf694b..5301e2b 100644
--- a/drivers/input/touchscreen/ili210x.c
+++ b/drivers/input/touchscreen/ili210x.c
@@ -99,7 +99,7 @@ static void ili210x_report_events(struct input_dev *input,
 		}
 	}
 
-	input_mt_report_pointer_emulation(input, false);
+	input_mt_report_pointer_emulation(input, false, false);
 	input_sync(input);
 }
 
diff --git a/drivers/input/touchscreen/mms114.c
b/drivers/input/touchscreen/mms114.c
index 1fafc9f..4f7b20a 100644
--- a/drivers/input/touchscreen/mms114.c
+++ b/drivers/input/touchscreen/mms114.c
@@ -221,7 +221,7 @@ static irqreturn_t mms114_interrupt(int irq, void
*dev_id)
 	for (index = 0; index < touch_size; index++)
 		mms114_process_mt(data, touch + index);
 
-	input_mt_report_pointer_emulation(data->input_dev, true);
+	input_mt_report_pointer_emulation(data->input_dev, true, false);
 	input_sync(data->input_dev);
 
 out:
@@ -528,7 +528,7 @@ static int __maybe_unused mms114_suspend(struct device
*dev)
 		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
false);
 	}
 
-	input_mt_report_pointer_emulation(input_dev, true);
+	input_mt_report_pointer_emulation(input_dev, true, false);
 	input_sync(input_dev);
 
 	mutex_lock(&input_dev->mutex);
diff --git a/drivers/input/touchscreen/penmount.c
b/drivers/input/touchscreen/penmount.c
index 417d873..ceaf1ee 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -81,7 +81,7 @@ static void pm_mtevent(struct pm *pm, struct input_dev
*input)
 		}
 	}
 
-	input_mt_report_pointer_emulation(input, true);
+	input_mt_report_pointer_emulation(input, true, false);
 	input_sync(input);
 }
 
diff --git a/drivers/input/touchscreen/rohm_bu21023.c
b/drivers/input/touchscreen/rohm_bu21023.c
index 611156a..aecd457 100644
--- a/drivers/input/touchscreen/rohm_bu21023.c
+++ b/drivers/input/touchscreen/rohm_bu21023.c
@@ -627,7 +627,7 @@ static irqreturn_t rohm_ts_soft_irq(int irq, void
*dev_id)
 		}
 
 		input_mt_sync_frame(input_dev);
-		input_mt_report_pointer_emulation(input_dev, true);
+		input_mt_report_pointer_emulation(input_dev, true, false);
 		input_sync(input_dev);
 
 		ts->finger_count = finger_count;
diff --git a/drivers/input/touchscreen/wacom_w8001.c
b/drivers/input/touchscreen/wacom_w8001.c
index bab3c6a..05164b1 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -176,7 +176,7 @@ static void parse_multi_touch(struct w8001 *w8001)
 	if (w8001->type != BTN_TOOL_PEN &&
 			    w8001->type != BTN_TOOL_RUBBER) {
 		w8001->type = count == 1 ? BTN_TOOL_FINGER : KEY_RESERVED;
-		input_mt_report_pointer_emulation(dev, true);
+		input_mt_report_pointer_emulation(dev, true, false);
 	}
 
 	input_sync(dev);
diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h
index d7188de..67c7bdd 100644
--- a/include/linux/input/mt.h
+++ b/include/linux/input/mt.h
@@ -104,7 +104,8 @@ void input_mt_report_slot_state(struct input_dev *dev,
 				unsigned int tool_type, bool active);
 
 void input_mt_report_finger_count(struct input_dev *dev, int count);
-void input_mt_report_pointer_emulation(struct input_dev *dev, bool
use_count);
+void input_mt_report_pointer_emulation(struct input_dev *dev, bool
use_count,
+					bool hover);
 void input_mt_drop_unused(struct input_dev *dev);
 
 void input_mt_sync_frame(struct input_dev *dev);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH] Input: Change BTN_TOOL_FINGER flag when hover event trigger
@ 2016-04-06  0:34 duson
       [not found] ` <006901d1acea$8207d090$861771b0$@emc.com.tw>
  0 siblings, 1 reply; 9+ messages in thread
From: duson @ 2016-04-06  0:34 UTC (permalink / raw)
  To: linux-input, linux-kernel, Dmitry Torokhov
  Cc: Charles Mooney, jeff, 黃世鵬

Only ABS_DISTANCE is not enough for upper OS to distingiush hover event
be triggered from object from faraway to and close touchpad surface or
from object prepare to leave the touchpad surface. Add BTN_TOOL_FINGER
flag to help it.

                 object_from_faraway    object_inside_hover_area  object_touch_surface
BTN_TOUCH                 0                          0                        1
BTN_TOOL_FINGER           0                          1                        1
ABS_DISTANCE              0                          1                        0

Signed-off by: Duson Lin <dusonlin@emc.com.tw>
---
 drivers/hid/hid-magicmouse.c             |  2 +-
 drivers/input/input-mt.c                 |  7 +++++--
 drivers/input/mouse/elan_i2c_core.c      | 15 +++++++++------
 drivers/input/mouse/elantech.c           |  2 +-
 drivers/input/mouse/focaltech.c          |  2 +-
 drivers/input/mouse/synaptics.c          |  2 +-
 drivers/input/touchscreen/atmel_mxt_ts.c |  2 +-
 drivers/input/touchscreen/edt-ft5x06.c   |  2 +-
 drivers/input/touchscreen/egalax_ts.c    |  2 +-
 drivers/input/touchscreen/ili210x.c      |  2 +-
 drivers/input/touchscreen/mms114.c       |  4 ++--
 drivers/input/touchscreen/penmount.c     |  2 +-
 drivers/input/touchscreen/rohm_bu21023.c |  2 +-
 drivers/input/touchscreen/wacom_w8001.c  |  2 +-
 include/linux/input/mt.h                 |  3 ++-
 15 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index d6fa496..584e98b 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -353,7 +353,7 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 		input_report_rel(input, REL_Y, y);
 	} else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
 		input_report_key(input, BTN_MOUSE, clicks & 1);
-		input_mt_report_pointer_emulation(input, true);
+		input_mt_report_pointer_emulation(input, true, false);
 	}
 
 	input_sync(input);
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c
index 54fce56..30855a5 100644
--- a/drivers/input/input-mt.c
+++ b/drivers/input/input-mt.c
@@ -184,6 +184,7 @@ EXPORT_SYMBOL(input_mt_report_finger_count);
  * input_mt_report_pointer_emulation() - common pointer emulation
  * @dev: input device with allocated MT slots
  * @use_count: report number of active contacts as finger count
+ * @hover: report ABS_DISTANCE as hover event
  *
  * Performs legacy pointer emulation via BTN_TOUCH, ABS_X, ABS_Y and
  * ABS_PRESSURE. Touchpad finger count is emulated if use_count is true.
@@ -191,7 +192,8 @@ EXPORT_SYMBOL(input_mt_report_finger_count);
  * The input core ensures only the KEY and ABS axes already setup for
  * this device will produce output.
  */
-void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
+void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count,
+					bool hover)
 {
 	struct input_mt *mt = dev->mt;
 	struct input_mt_slot *oldest;
@@ -220,6 +222,7 @@ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count)
 	input_event(dev, EV_KEY, BTN_TOUCH, count > 0);
 	if (use_count)
 		input_mt_report_finger_count(dev, count);
+	input_event(dev, EV_ABS, ABS_DISTANCE, hover);
 
 	if (oldest) {
 		int x = input_mt_get_value(oldest, ABS_MT_POSITION_X);
@@ -290,7 +293,7 @@ void input_mt_sync_frame(struct input_dev *dev)
 	if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags & INPUT_MT_SEMI_MT))
 		use_count = true;
 
-	input_mt_report_pointer_emulation(dev, use_count);
+	input_mt_report_pointer_emulation(dev, use_count, false);
 
 	mt->frame++;
 }
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
index 2f58985..8b5e75a 100644
--- a/drivers/input/mouse/elan_i2c_core.c
+++ b/drivers/input/mouse/elan_i2c_core.c
@@ -4,7 +4,7 @@
  * Copyright (c) 2013 ELAN Microelectronics Corp.
  *
  * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
- * Version: 1.6.0
+ * Version: 1.6.2
  *
  * Based on cyapa driver:
  * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
@@ -40,7 +40,7 @@
 #include "elan_i2c.h"
 
 #define DRIVER_NAME		"elan_i2c"
-#define ELAN_DRIVER_VERSION	"1.6.1"
+#define ELAN_DRIVER_VERSION	"1.6.2"
 #define ELAN_VENDOR_ID		0x04f3
 #define ETP_MAX_PRESSURE	255
 #define ETP_FWIDTH_REDUCE	90
@@ -845,7 +845,7 @@ static void elan_report_absolute(struct elan_tp_data *data, u8 *packet)
 {
 	struct input_dev *input = data->input;
 	u8 *finger_data = &packet[ETP_FINGER_DATA_OFFSET];
-	int i;
+	int i, valid_count = 0;
 	u8 tp_info = packet[ETP_TOUCH_INFO_OFFSET];
 	u8 hover_info = packet[ETP_HOVER_INFO_OFFSET];
 	bool contact_valid, hover_event;
@@ -855,13 +855,16 @@ static void elan_report_absolute(struct elan_tp_data *data, u8 *packet)
 		contact_valid = tp_info & (1U << (3 + i));
 		elan_report_contact(data, i, contact_valid, finger_data);
 
-		if (contact_valid)
+		if (contact_valid) {
 			finger_data += ETP_FINGER_DATA_LEN;
+			valid_count++;
+		}
 	}
 
 	input_report_key(input, BTN_LEFT, tp_info & 0x01);
-	input_report_abs(input, ABS_DISTANCE, hover_event != 0);
-	input_mt_report_pointer_emulation(input, true);
+	input_report_key(input, BTN_TOOL_FINGER,
+			((hover_event != 0) || (valid_count > 0)));
+	input_mt_report_pointer_emulation(input, false, hover_event != 0);
 	input_sync(input);
 }
 
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 78f93cf..cc13e12 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -558,7 +558,7 @@ static void elantech_input_sync_v4(struct psmouse *psmouse)
 		input_report_key(dev, BTN_MIDDLE, packet[0] & 0x04);
 	}
 
-	input_mt_report_pointer_emulation(dev, true);
+	input_mt_report_pointer_emulation(dev, true, false);
 	input_sync(dev);
 }
 
diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c
index c8c6a8c..f4339ac 100644
--- a/drivers/input/mouse/focaltech.c
+++ b/drivers/input/mouse/focaltech.c
@@ -144,7 +144,7 @@ static void focaltech_report_state(struct psmouse *psmouse)
 			input_report_abs(dev, ABS_TOOL_WIDTH, state->width);
 		}
 	}
-	input_mt_report_pointer_emulation(dev, true);
+	input_mt_report_pointer_emulation(dev, true, false);
 
 	input_report_key(psmouse->dev, BTN_LEFT, state->pressed);
 	input_sync(psmouse->dev);
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index a41d832..09fa835 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -944,7 +944,7 @@ static void synaptics_report_mt_data(struct psmouse *psmouse,
 	input_mt_drop_unused(dev);
 
 	/* Don't use active slot count to generate BTN_TOOL events. */
-	input_mt_report_pointer_emulation(dev, false);
+	input_mt_report_pointer_emulation(dev, false, false);
 
 	/* Send the number of fingers reported by touchpad itself. */
 	input_mt_report_finger_count(dev, num_fingers);
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 2160512..0ab0d53 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -683,7 +683,7 @@ static void mxt_input_button(struct mxt_data *data, u8 *message)
 static void mxt_input_sync(struct mxt_data *data)
 {
 	input_mt_report_pointer_emulation(data->input_dev,
-					  data->pdata->t19_num_keys);
+					  data->pdata->t19_num_keys, false);
 	input_sync(data->input_dev);
 }
 
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 23fbe38..6533d8e 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -250,7 +250,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
 		input_report_abs(tsdata->input, ABS_MT_POSITION_Y, y);
 	}
 
-	input_mt_report_pointer_emulation(tsdata->input, true);
+	input_mt_report_pointer_emulation(tsdata->input, true, false);
 	input_sync(tsdata->input);
 
 out:
diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c
index 1afc08b..c420336 100644
--- a/drivers/input/touchscreen/egalax_ts.c
+++ b/drivers/input/touchscreen/egalax_ts.c
@@ -113,7 +113,7 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id)
 		input_report_abs(input_dev, ABS_MT_PRESSURE, z);
 	}
 
-	input_mt_report_pointer_emulation(input_dev, true);
+	input_mt_report_pointer_emulation(input_dev, true, false);
 	input_sync(input_dev);
 
 	return IRQ_HANDLED;
diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c
index ddf694b..5301e2b 100644
--- a/drivers/input/touchscreen/ili210x.c
+++ b/drivers/input/touchscreen/ili210x.c
@@ -99,7 +99,7 @@ static void ili210x_report_events(struct input_dev *input,
 		}
 	}
 
-	input_mt_report_pointer_emulation(input, false);
+	input_mt_report_pointer_emulation(input, false, false);
 	input_sync(input);
 }
 
diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c
index 1fafc9f..4f7b20a 100644
--- a/drivers/input/touchscreen/mms114.c
+++ b/drivers/input/touchscreen/mms114.c
@@ -221,7 +221,7 @@ static irqreturn_t mms114_interrupt(int irq, void *dev_id)
 	for (index = 0; index < touch_size; index++)
 		mms114_process_mt(data, touch + index);
 
-	input_mt_report_pointer_emulation(data->input_dev, true);
+	input_mt_report_pointer_emulation(data->input_dev, true, false);
 	input_sync(data->input_dev);
 
 out:
@@ -528,7 +528,7 @@ static int __maybe_unused mms114_suspend(struct device *dev)
 		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, false);
 	}
 
-	input_mt_report_pointer_emulation(input_dev, true);
+	input_mt_report_pointer_emulation(input_dev, true, false);
 	input_sync(input_dev);
 
 	mutex_lock(&input_dev->mutex);
diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
index 417d873..ceaf1ee 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -81,7 +81,7 @@ static void pm_mtevent(struct pm *pm, struct input_dev *input)
 		}
 	}
 
-	input_mt_report_pointer_emulation(input, true);
+	input_mt_report_pointer_emulation(input, true, false);
 	input_sync(input);
 }
 
diff --git a/drivers/input/touchscreen/rohm_bu21023.c b/drivers/input/touchscreen/rohm_bu21023.c
index 611156a..aecd457 100644
--- a/drivers/input/touchscreen/rohm_bu21023.c
+++ b/drivers/input/touchscreen/rohm_bu21023.c
@@ -627,7 +627,7 @@ static irqreturn_t rohm_ts_soft_irq(int irq, void *dev_id)
 		}
 
 		input_mt_sync_frame(input_dev);
-		input_mt_report_pointer_emulation(input_dev, true);
+		input_mt_report_pointer_emulation(input_dev, true, false);
 		input_sync(input_dev);
 
 		ts->finger_count = finger_count;
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c
index bab3c6a..05164b1 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -176,7 +176,7 @@ static void parse_multi_touch(struct w8001 *w8001)
 	if (w8001->type != BTN_TOOL_PEN &&
 			    w8001->type != BTN_TOOL_RUBBER) {
 		w8001->type = count == 1 ? BTN_TOOL_FINGER : KEY_RESERVED;
-		input_mt_report_pointer_emulation(dev, true);
+		input_mt_report_pointer_emulation(dev, true, false);
 	}
 
 	input_sync(dev);
diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h
index d7188de..67c7bdd 100644
--- a/include/linux/input/mt.h
+++ b/include/linux/input/mt.h
@@ -104,7 +104,8 @@ void input_mt_report_slot_state(struct input_dev *dev,
 				unsigned int tool_type, bool active);
 
 void input_mt_report_finger_count(struct input_dev *dev, int count);
-void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count);
+void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count,
+					bool hover);
 void input_mt_drop_unused(struct input_dev *dev);
 
 void input_mt_sync_frame(struct input_dev *dev);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2016-05-26  0:26 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-19  5:18 [PATCH] Input: Change BTN_TOOL_FINGER flag when hover event trigger DusonLin
  -- strict thread matches above, loose matches on Subject: below --
2016-04-11  0:58 DusonLin
2016-04-06  0:34 duson
     [not found] ` <006901d1acea$8207d090$861771b0$@emc.com.tw>
2016-05-16 11:27   ` 廖崇榮
2016-05-16 17:53     ` Dmitry Torokhov
2016-05-17 14:20       ` 廖崇榮
2016-05-20  0:51         ` 'Dmitry Torokhov'
2016-05-23 14:28           ` 廖崇榮
2016-05-26  0:11             ` 'Dmitry Torokhov'

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).