summaryrefslogtreecommitdiff
path: root/drivers/hid/hid-uclogic-core.c
diff options
context:
space:
mode:
authorJosé Expósito <jose.exposito89@gmail.com>2022-12-26 13:54:52 +0100
committerJiri Kosina <jkosina@suse.cz>2023-01-18 09:44:57 +0100
commita251d6576d2a29fc0806ef4775719e3b6e672d91 (patch)
treedc01207f77f9300469c0ca9f7e8916a3e7bfd178 /drivers/hid/hid-uclogic-core.c
parentbd85c131b2e3edf2cf1a498652e8c3a066a338e7 (diff)
HID: uclogic: Handle wireless device reconnection
UGEEv2 tablets with battery can be connected using a USB cable or a USB Bluetooth dongle. When the Bluetooth dongle is used, the connection to that tablet can be lost because the tablet is out of the range of the receiver or because it was switched off using the switch placed in the back of the tablet's frame. After losing connection, the tablet is able to reconnect automatically and its firmware sends a special packet indicating that the device was reconnected. In response to this packet, the tablet needs to receive the same array of magic data it expects on probe to enable its interfaces. This patch implements a generic mechanism to hook raw events and schedule a work to perform any custom action. Tested-by: Mia Kanashi <chad@redpilled.dev> Tested-by: Andreas Grosse <andig.mail@t-online.de> Signed-off-by: José Expósito <jose.exposito89@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-uclogic-core.c')
-rw-r--r--drivers/hid/hid-uclogic-core.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/hid/hid-uclogic-core.c b/drivers/hid/hid-uclogic-core.c
index 7a5480b6f046..9ddb17ad0d04 100644
--- a/drivers/hid/hid-uclogic-core.c
+++ b/drivers/hid/hid-uclogic-core.c
@@ -250,6 +250,34 @@ static int uclogic_resume(struct hid_device *hdev)
#endif
/**
+ * uclogic_exec_event_hook - if the received event is hooked schedules the
+ * associated work.
+ *
+ * @p: Tablet interface report parameters.
+ * @event: Raw event.
+ * @size: The size of event.
+ *
+ * Returns:
+ * Whether the event was hooked or not.
+ */
+static bool uclogic_exec_event_hook(struct uclogic_params *p, u8 *event, int size)
+{
+ struct uclogic_raw_event_hook *curr;
+
+ if (!p->event_hooks)
+ return false;
+
+ list_for_each_entry(curr, &p->event_hooks->list, list) {
+ if (curr->size == size && memcmp(curr->event, event, size) == 0) {
+ schedule_work(&curr->work);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
* uclogic_raw_event_pen - handle raw pen events (pen HID reports).
*
* @drvdata: Driver data.
@@ -407,6 +435,9 @@ static int uclogic_raw_event(struct hid_device *hdev,
if (report->type != HID_INPUT_REPORT)
return 0;
+ if (uclogic_exec_event_hook(params, data, size))
+ return 0;
+
while (true) {
/* Tweak pen reports, if necessary */
if ((report_id == params->pen.id) && (size >= 2)) {
@@ -536,3 +567,7 @@ module_hid_driver(uclogic_driver);
MODULE_AUTHOR("Martin Rusko");
MODULE_AUTHOR("Nikolai Kondrashov");
MODULE_LICENSE("GPL");
+
+#ifdef CONFIG_HID_KUNIT_TEST
+#include "hid-uclogic-core-test.c"
+#endif