Commit d3c19637 authored by Allen Hung's avatar Allen Hung Committed by Kamal Mostafa

HID: multitouch: enable palm rejection for Windows Precision Touchpad

BugLink: http://bugs.launchpad.net/bugs/1593124

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: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Tested-by: Andy Lutomirski <luto@kernel.org> # XPS 13 9350, BIOS 1.4.3
Signed-off-by: default avatarAllen Hung <allen_hung@dell.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
(cherry picked from commit 6dd2e27a)
Signed-off-by: default avatarPhidias Chiang <phidias.chiang@canonical.com>
Acked-by: default avatarTim Gardner <tim.gardner@canonical.com>
Signed-off-by: default avatarKamal Mostafa <kamal@canonical.com>
parent 55a80dc6
...@@ -61,6 +61,7 @@ MODULE_LICENSE("GPL"); ...@@ -61,6 +61,7 @@ MODULE_LICENSE("GPL");
#define MT_QUIRK_ALWAYS_VALID (1 << 4) #define MT_QUIRK_ALWAYS_VALID (1 << 4)
#define MT_QUIRK_VALID_IS_INRANGE (1 << 5) #define MT_QUIRK_VALID_IS_INRANGE (1 << 5)
#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 6) #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_SLOT_IS_CONTACTID_MINUS_ONE (1 << 8)
#define MT_QUIRK_NO_AREA (1 << 9) #define MT_QUIRK_NO_AREA (1 << 9)
#define MT_QUIRK_IGNORE_DUPLICATES (1 << 10) #define MT_QUIRK_IGNORE_DUPLICATES (1 << 10)
...@@ -78,6 +79,7 @@ struct mt_slot { ...@@ -78,6 +79,7 @@ struct mt_slot {
__s32 contactid; /* the device ContactID assigned to this slot */ __s32 contactid; /* the device ContactID assigned to this slot */
bool touch_state; /* is the touch valid? */ bool touch_state; /* is the touch valid? */
bool inrange_state; /* is the finger in proximity of the sensor? */ bool inrange_state; /* is the finger in proximity of the sensor? */
bool confidence_state; /* is the touch made by a finger? */
}; };
struct mt_class { struct mt_class {
...@@ -502,6 +504,9 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, ...@@ -502,6 +504,9 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
mt_store_field(usage, td, hi); mt_store_field(usage, td, hi);
return 1; return 1;
case HID_DG_CONFIDENCE: 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); mt_store_field(usage, td, hi);
return 1; return 1;
case HID_DG_TIPSWITCH: case HID_DG_TIPSWITCH:
...@@ -614,6 +619,7 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input) ...@@ -614,6 +619,7 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
return; return;
if (td->curvalid || (td->mtclass.quirks & MT_QUIRK_ALWAYS_VALID)) { if (td->curvalid || (td->mtclass.quirks & MT_QUIRK_ALWAYS_VALID)) {
int active;
int slotnum = mt_compute_slot(td, input); int slotnum = mt_compute_slot(td, input);
struct mt_slot *s = &td->curdata; struct mt_slot *s = &td->curdata;
struct input_mt *mt = input->mt; struct input_mt *mt = input->mt;
...@@ -628,10 +634,14 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input) ...@@ -628,10 +634,14 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
return; 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_slot(input, slotnum);
input_mt_report_slot_state(input, MT_TOOL_FINGER, input_mt_report_slot_state(input, MT_TOOL_FINGER, active);
s->touch_state || s->inrange_state); if (active) {
if (s->touch_state || s->inrange_state) {
/* this finger is in proximity of the sensor */ /* this finger is in proximity of the sensor */
int wide = (s->w > s->h); int wide = (s->w > s->h);
/* divided by two to match visual scale of touch */ /* 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,6 +706,8 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
td->curdata.touch_state = value; td->curdata.touch_state = value;
break; break;
case HID_DG_CONFIDENCE: case HID_DG_CONFIDENCE:
if (quirks & MT_QUIRK_CONFIDENCE)
td->curdata.confidence_state = value;
if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE) if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE)
td->curvalid = value; td->curvalid = value;
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment