diff options
author | Allen Hung <allen_hung@dell.com> | 2016-06-23 04:31:30 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2016-06-28 07:24:14 -0400 |
commit | 6dd2e27a103d716921cc4a1a96a9adc0a8e3ab57 (patch) | |
tree | 8a5a00fbf90ed15d8e153fd6e3d531cb41b7523d | |
parent | 62630ea768869beeb1e514b0bf5607a0c9b93d12 (diff) |
HID: multitouch: enable palm rejection for Windows Precision Touchpad
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
Cc: stable@vger.kernel.org # v4.5+
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>
-rw-r--r-- | drivers/hid/hid-multitouch.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 4ef700688657..fb6f1f447279 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -61,6 +61,7 @@ MODULE_LICENSE("GPL"); | |||
61 | #define MT_QUIRK_ALWAYS_VALID (1 << 4) | 61 | #define MT_QUIRK_ALWAYS_VALID (1 << 4) |
62 | #define MT_QUIRK_VALID_IS_INRANGE (1 << 5) | 62 | #define MT_QUIRK_VALID_IS_INRANGE (1 << 5) |
63 | #define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 6) | 63 | #define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 6) |
64 | #define MT_QUIRK_CONFIDENCE (1 << 7) | ||
64 | #define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 8) | 65 | #define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 8) |
65 | #define MT_QUIRK_NO_AREA (1 << 9) | 66 | #define MT_QUIRK_NO_AREA (1 << 9) |
66 | #define MT_QUIRK_IGNORE_DUPLICATES (1 << 10) | 67 | #define MT_QUIRK_IGNORE_DUPLICATES (1 << 10) |
@@ -78,6 +79,7 @@ struct mt_slot { | |||
78 | __s32 contactid; /* the device ContactID assigned to this slot */ | 79 | __s32 contactid; /* the device ContactID assigned to this slot */ |
79 | bool touch_state; /* is the touch valid? */ | 80 | bool touch_state; /* is the touch valid? */ |
80 | bool inrange_state; /* is the finger in proximity of the sensor? */ | 81 | bool inrange_state; /* is the finger in proximity of the sensor? */ |
82 | bool confidence_state; /* is the touch made by a finger? */ | ||
81 | }; | 83 | }; |
82 | 84 | ||
83 | struct mt_class { | 85 | struct mt_class { |
@@ -502,6 +504,9 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
502 | mt_store_field(usage, td, hi); | 504 | mt_store_field(usage, td, hi); |
503 | return 1; | 505 | return 1; |
504 | case HID_DG_CONFIDENCE: | 506 | case HID_DG_CONFIDENCE: |
507 | if (cls->name == MT_CLS_WIN_8 && | ||
508 | field->application == HID_DG_TOUCHPAD) | ||
509 | cls->quirks |= MT_QUIRK_CONFIDENCE; | ||
505 | mt_store_field(usage, td, hi); | 510 | mt_store_field(usage, td, hi); |
506 | return 1; | 511 | return 1; |
507 | case HID_DG_TIPSWITCH: | 512 | case HID_DG_TIPSWITCH: |
@@ -614,6 +619,7 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input) | |||
614 | return; | 619 | return; |
615 | 620 | ||
616 | if (td->curvalid || (td->mtclass.quirks & MT_QUIRK_ALWAYS_VALID)) { | 621 | if (td->curvalid || (td->mtclass.quirks & MT_QUIRK_ALWAYS_VALID)) { |
622 | int active; | ||
617 | int slotnum = mt_compute_slot(td, input); | 623 | int slotnum = mt_compute_slot(td, input); |
618 | struct mt_slot *s = &td->curdata; | 624 | struct mt_slot *s = &td->curdata; |
619 | struct input_mt *mt = input->mt; | 625 | struct input_mt *mt = input->mt; |
@@ -628,10 +634,14 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input) | |||
628 | return; | 634 | return; |
629 | } | 635 | } |
630 | 636 | ||
637 | if (!(td->mtclass.quirks & MT_QUIRK_CONFIDENCE)) | ||
638 | s->confidence_state = 1; | ||
639 | active = (s->touch_state || s->inrange_state) && | ||
640 | s->confidence_state; | ||
641 | |||
631 | input_mt_slot(input, slotnum); | 642 | input_mt_slot(input, slotnum); |
632 | input_mt_report_slot_state(input, MT_TOOL_FINGER, | 643 | input_mt_report_slot_state(input, MT_TOOL_FINGER, active); |
633 | s->touch_state || s->inrange_state); | 644 | if (active) { |
634 | if (s->touch_state || s->inrange_state) { | ||
635 | /* this finger is in proximity of the sensor */ | 645 | /* this finger is in proximity of the sensor */ |
636 | int wide = (s->w > s->h); | 646 | int wide = (s->w > s->h); |
637 | /* divided by two to match visual scale of touch */ | 647 | /* divided by two to match visual scale of touch */ |
@@ -696,6 +706,8 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, | |||
696 | td->curdata.touch_state = value; | 706 | td->curdata.touch_state = value; |
697 | break; | 707 | break; |
698 | case HID_DG_CONFIDENCE: | 708 | case HID_DG_CONFIDENCE: |
709 | if (quirks & MT_QUIRK_CONFIDENCE) | ||
710 | td->curdata.confidence_state = value; | ||
699 | if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE) | 711 | if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE) |
700 | td->curvalid = value; | 712 | td->curvalid = value; |
701 | break; | 713 | break; |