diff options
Diffstat (limited to 'drivers/hid/hid-multitouch.c')
-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 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 | ||
57 | struct mt_slot { | 58 | struct 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 | ||
63 | struct mt_class { | 65 | struct 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) |