| From 6dd2e27a103d716921cc4a1a96a9adc0a8e3ab57 Mon Sep 17 00:00:00 2001 |
| From: Allen Hung <allen_hung@dell.com> |
| Date: Thu, 23 Jun 2016 16:31:30 +0800 |
| Subject: HID: multitouch: enable palm rejection for Windows Precision Touchpad |
| |
| From: Allen Hung <allen_hung@dell.com> |
| |
| commit 6dd2e27a103d716921cc4a1a96a9adc0a8e3ab57 upstream. |
| |
| The usage Confidence is mandary to Windows Precision Touchpad devices. If |
| it is examined in input_mapping on a WIndows Precision Touchpad, a new add |
| quirk MT_QUIRK_CONFIDENCE desgned for such devices will be applied to the |
| device. A touch with the confidence bit is not set is determined as |
| invalid. |
| |
| Tested on Dell XPS13 9343 |
| |
| Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> |
| Tested-by: Andy Lutomirski <luto@kernel.org> # XPS 13 9350, BIOS 1.4.3 |
| Signed-off-by: Allen Hung <allen_hung@dell.com> |
| Signed-off-by: Jiri Kosina <jkosina@suse.cz> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/hid/hid-multitouch.c | 18 +++++++++++++++--- |
| 1 file changed, 15 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/hid/hid-multitouch.c |
| +++ b/drivers/hid/hid-multitouch.c |
| @@ -61,6 +61,7 @@ MODULE_LICENSE("GPL"); |
| #define MT_QUIRK_ALWAYS_VALID (1 << 4) |
| #define MT_QUIRK_VALID_IS_INRANGE (1 << 5) |
| #define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 6) |
| +#define MT_QUIRK_CONFIDENCE (1 << 7) |
| #define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 8) |
| #define MT_QUIRK_NO_AREA (1 << 9) |
| #define MT_QUIRK_IGNORE_DUPLICATES (1 << 10) |
| @@ -78,6 +79,7 @@ struct mt_slot { |
| __s32 contactid; /* the device ContactID assigned to this slot */ |
| bool touch_state; /* is the touch valid? */ |
| bool inrange_state; /* is the finger in proximity of the sensor? */ |
| + bool confidence_state; /* is the touch made by a finger? */ |
| }; |
| |
| struct mt_class { |
| @@ -502,6 +504,9 @@ static int mt_touch_input_mapping(struct |
| mt_store_field(usage, td, hi); |
| return 1; |
| case HID_DG_CONFIDENCE: |
| + if (cls->name == MT_CLS_WIN_8 && |
| + field->application == HID_DG_TOUCHPAD) |
| + cls->quirks |= MT_QUIRK_CONFIDENCE; |
| mt_store_field(usage, td, hi); |
| return 1; |
| case HID_DG_TIPSWITCH: |
| @@ -614,6 +619,7 @@ static void mt_complete_slot(struct mt_d |
| return; |
| |
| if (td->curvalid || (td->mtclass.quirks & MT_QUIRK_ALWAYS_VALID)) { |
| + int active; |
| int slotnum = mt_compute_slot(td, input); |
| struct mt_slot *s = &td->curdata; |
| struct input_mt *mt = input->mt; |
| @@ -628,10 +634,14 @@ static void mt_complete_slot(struct mt_d |
| return; |
| } |
| |
| + if (!(td->mtclass.quirks & MT_QUIRK_CONFIDENCE)) |
| + s->confidence_state = 1; |
| + active = (s->touch_state || s->inrange_state) && |
| + s->confidence_state; |
| + |
| input_mt_slot(input, slotnum); |
| - input_mt_report_slot_state(input, MT_TOOL_FINGER, |
| - s->touch_state || s->inrange_state); |
| - if (s->touch_state || s->inrange_state) { |
| + input_mt_report_slot_state(input, MT_TOOL_FINGER, active); |
| + if (active) { |
| /* this finger is in proximity of the sensor */ |
| int wide = (s->w > s->h); |
| /* divided by two to match visual scale of touch */ |
| @@ -696,6 +706,8 @@ static void mt_process_mt_event(struct h |
| td->curdata.touch_state = value; |
| break; |
| case HID_DG_CONFIDENCE: |
| + if (quirks & MT_QUIRK_CONFIDENCE) |
| + td->curdata.confidence_state = value; |
| if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE) |
| td->curvalid = value; |
| break; |