aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllen Hung <allen_hung@dell.com>2016-06-23 04:31:30 -0400
committerJiri Kosina <jkosina@suse.cz>2016-06-28 07:24:14 -0400
commit6dd2e27a103d716921cc4a1a96a9adc0a8e3ab57 (patch)
tree8a5a00fbf90ed15d8e153fd6e3d531cb41b7523d
parent62630ea768869beeb1e514b0bf5607a0c9b93d12 (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.c18
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
83struct mt_class { 85struct 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;