aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-multitouch.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-multitouch.c')
-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 e86fbf4be639..0a0489309905 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -53,11 +53,13 @@ MODULE_LICENSE("GPL");
53#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 8) 53#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 8)
54#define MT_QUIRK_NO_AREA (1 << 9) 54#define MT_QUIRK_NO_AREA (1 << 9)
55#define MT_QUIRK_IGNORE_DUPLICATES (1 << 10) 55#define MT_QUIRK_IGNORE_DUPLICATES (1 << 10)
56#define MT_QUIRK_HOVERING (1 << 11)
56 57
57struct mt_slot { 58struct mt_slot {
58 __s32 x, y, cx, cy, p, w, h; 59 __s32 x, y, cx, cy, p, w, h;
59 __s32 contactid; /* the device ContactID assigned to this slot */ 60 __s32 contactid; /* the device ContactID assigned to this slot */
60 bool touch_state; /* is the touch valid? */ 61 bool touch_state; /* is the touch valid? */
62 bool inrange_state; /* is the finger in proximity of the sensor? */
61}; 63};
62 64
63struct mt_class { 65struct mt_class {
@@ -391,6 +393,12 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
391 case HID_UP_DIGITIZER: 393 case HID_UP_DIGITIZER:
392 switch (usage->hid) { 394 switch (usage->hid) {
393 case HID_DG_INRANGE: 395 case HID_DG_INRANGE:
396 if (cls->quirks & MT_QUIRK_HOVERING) {
397 hid_map_usage(hi, usage, bit, max,
398 EV_ABS, ABS_MT_DISTANCE);
399 input_set_abs_params(hi->input,
400 ABS_MT_DISTANCE, 0, 1, 0, 0);
401 }
394 mt_store_field(usage, td, hi); 402 mt_store_field(usage, td, hi);
395 td->last_field_index = field->index; 403 td->last_field_index = field->index;
396 return 1; 404 return 1;
@@ -520,9 +528,9 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
520 528
521 input_mt_slot(input, slotnum); 529 input_mt_slot(input, slotnum);
522 input_mt_report_slot_state(input, MT_TOOL_FINGER, 530 input_mt_report_slot_state(input, MT_TOOL_FINGER,
523 s->touch_state); 531 s->touch_state || s->inrange_state);
524 if (s->touch_state) { 532 if (s->touch_state || s->inrange_state) {
525 /* this finger is on the screen */ 533 /* this finger is in proximity of the sensor */
526 int wide = (s->w > s->h); 534 int wide = (s->w > s->h);
527 /* divided by two to match visual scale of touch */ 535 /* divided by two to match visual scale of touch */
528 int major = max(s->w, s->h) >> 1; 536 int major = max(s->w, s->h) >> 1;
@@ -532,6 +540,8 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
532 input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); 540 input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y);
533 input_event(input, EV_ABS, ABS_MT_TOOL_X, s->cx); 541 input_event(input, EV_ABS, ABS_MT_TOOL_X, s->cx);
534 input_event(input, EV_ABS, ABS_MT_TOOL_Y, s->cy); 542 input_event(input, EV_ABS, ABS_MT_TOOL_Y, s->cy);
543 input_event(input, EV_ABS, ABS_MT_DISTANCE,
544 !s->touch_state);
535 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); 545 input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
536 input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); 546 input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p);
537 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); 547 input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
@@ -564,6 +574,8 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
564 case HID_DG_INRANGE: 574 case HID_DG_INRANGE:
565 if (quirks & MT_QUIRK_VALID_IS_INRANGE) 575 if (quirks & MT_QUIRK_VALID_IS_INRANGE)
566 td->curvalid = value; 576 td->curvalid = value;
577 if (quirks & MT_QUIRK_HOVERING)
578 td->curdata.inrange_state = value;
567 break; 579 break;
568 case HID_DG_TIPSWITCH: 580 case HID_DG_TIPSWITCH:
569 if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) 581 if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)