diff options
author | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2015-03-05 17:36:54 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2015-03-16 15:18:20 -0400 |
commit | 5fcad167315f224eaf6750b0fb85ee6c92f087cd (patch) | |
tree | 143318838d56f88253e8c40e81f004d119d65850 | |
parent | 71fa641ebbfd2402bdb76d3c6ba7e4a2d1eb2dfc (diff) |
HID: wacom: ask for a in-prox report when it was missed
If noone listens to the input device when a tool comes in proximity,
the tablet does not send the in-prox event when a client becomes available.
That means that no events will be sent until the tool is taken out of
proximity.
In this situation, ask for the report WACOM_REPORT_INTUOSREAD which will
read the corresponding feature and generate an in-prox event.
To make some generation of hardware working, we need to unset the
quirk NO_GET set by hid-core because the interfaces are seen as "boot
mouse".
We don't schedule this read in a worker while we are in an IO interrupt.
We know that usbhid will do it asynchronously. If this is triggered by
uhid, then this is obviously a client side bug :)
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Acked-by: Jason Gerecke <killertofu@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/wacom_sys.c | 3 | ||||
-rw-r--r-- | drivers/hid/wacom_wac.c | 18 |
2 files changed, 20 insertions, 1 deletions
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index ab7bf84c1ca7..353fe476be26 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
@@ -1408,6 +1408,9 @@ static int wacom_probe(struct hid_device *hdev, | |||
1408 | 1408 | ||
1409 | hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; | 1409 | hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; |
1410 | 1410 | ||
1411 | /* hid-core sets this quirk for the boot interface */ | ||
1412 | hdev->quirks &= ~HID_QUIRK_NOGET; | ||
1413 | |||
1411 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); | 1414 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); |
1412 | if (!wacom) | 1415 | if (!wacom) |
1413 | return -ENOMEM; | 1416 | return -ENOMEM; |
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 92626228d7b5..9406b128a44c 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
@@ -447,6 +447,19 @@ exit: | |||
447 | return retval; | 447 | return retval; |
448 | } | 448 | } |
449 | 449 | ||
450 | static void wacom_intuos_schedule_prox_event(struct wacom_wac *wacom_wac) | ||
451 | { | ||
452 | struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); | ||
453 | struct hid_report *r; | ||
454 | struct hid_report_enum *re; | ||
455 | |||
456 | re = &(wacom->hdev->report_enum[HID_FEATURE_REPORT]); | ||
457 | r = re->report_id_hash[WACOM_REPORT_INTUOSREAD]; | ||
458 | if (r) { | ||
459 | hid_hw_request(wacom->hdev, r, HID_REQ_GET_REPORT); | ||
460 | } | ||
461 | } | ||
462 | |||
450 | static int wacom_intuos_inout(struct wacom_wac *wacom) | 463 | static int wacom_intuos_inout(struct wacom_wac *wacom) |
451 | { | 464 | { |
452 | struct wacom_features *features = &wacom->features; | 465 | struct wacom_features *features = &wacom->features; |
@@ -623,8 +636,11 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
623 | } | 636 | } |
624 | 637 | ||
625 | /* don't report other events if we don't know the ID */ | 638 | /* don't report other events if we don't know the ID */ |
626 | if (!wacom->id[idx]) | 639 | if (!wacom->id[idx]) { |
640 | /* but reschedule a read of the current tool */ | ||
641 | wacom_intuos_schedule_prox_event(wacom); | ||
627 | return 1; | 642 | return 1; |
643 | } | ||
628 | 644 | ||
629 | return 0; | 645 | return 0; |
630 | } | 646 | } |