-
Notifications
You must be signed in to change notification settings - Fork 5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
1 parent
bd85c13
commit a251d65
Showing
5 changed files
with
271 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// SPDX-License-Identifier: GPL-2.0+ | ||
|
||
/* | ||
* HID driver for UC-Logic devices not fully compliant with HID standard | ||
* | ||
* Copyright (c) 2022 José Expósito <jose.exposito89@gmail.com> | ||
*/ | ||
|
||
#include <kunit/test.h> | ||
#include "./hid-uclogic-params.h" | ||
|
||
#define MAX_EVENT_SIZE 12 | ||
|
||
struct uclogic_raw_event_hook_test { | ||
u8 event[MAX_EVENT_SIZE]; | ||
size_t size; | ||
bool expected; | ||
}; | ||
|
||
static struct uclogic_raw_event_hook_test hook_events[] = { | ||
{ | ||
.event = { 0xA1, 0xB2, 0xC3, 0xD4 }, | ||
.size = 4, | ||
}, | ||
{ | ||
.event = { 0x1F, 0x2E, 0x3D, 0x4C, 0x5B, 0x6A }, | ||
.size = 6, | ||
}, | ||
}; | ||
|
||
static struct uclogic_raw_event_hook_test test_events[] = { | ||
{ | ||
.event = { 0xA1, 0xB2, 0xC3, 0xD4 }, | ||
.size = 4, | ||
.expected = true, | ||
}, | ||
{ | ||
.event = { 0x1F, 0x2E, 0x3D, 0x4C, 0x5B, 0x6A }, | ||
.size = 6, | ||
.expected = true, | ||
}, | ||
{ | ||
.event = { 0xA1, 0xB2, 0xC3 }, | ||
.size = 3, | ||
.expected = false, | ||
}, | ||
{ | ||
.event = { 0xA1, 0xB2, 0xC3, 0xD4, 0x00 }, | ||
.size = 5, | ||
.expected = false, | ||
}, | ||
{ | ||
.event = { 0x2E, 0x3D, 0x4C, 0x5B, 0x6A, 0x1F }, | ||
.size = 6, | ||
.expected = false, | ||
}, | ||
}; | ||
|
||
static void hid_test_uclogic_exec_event_hook_test(struct kunit *test) | ||
{ | ||
struct uclogic_params p = {0, }; | ||
struct uclogic_raw_event_hook *filter; | ||
bool res; | ||
int n; | ||
|
||
/* Initialize the list of events to hook */ | ||
p.event_hooks = kunit_kzalloc(test, sizeof(*p.event_hooks), GFP_KERNEL); | ||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p.event_hooks); | ||
INIT_LIST_HEAD(&p.event_hooks->list); | ||
|
||
for (n = 0; n < ARRAY_SIZE(hook_events); n++) { | ||
filter = kunit_kzalloc(test, sizeof(*filter), GFP_KERNEL); | ||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, filter); | ||
|
||
filter->size = hook_events[n].size; | ||
filter->event = kunit_kzalloc(test, filter->size, GFP_KERNEL); | ||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, filter->event); | ||
memcpy(filter->event, &hook_events[n].event[0], filter->size); | ||
|
||
list_add_tail(&filter->list, &p.event_hooks->list); | ||
} | ||
|
||
/* Test uclogic_exec_event_hook() */ | ||
for (n = 0; n < ARRAY_SIZE(test_events); n++) { | ||
res = uclogic_exec_event_hook(&p, &test_events[n].event[0], | ||
test_events[n].size); | ||
KUNIT_ASSERT_EQ(test, res, test_events[n].expected); | ||
} | ||
} | ||
|
||
static struct kunit_case hid_uclogic_core_test_cases[] = { | ||
KUNIT_CASE(hid_test_uclogic_exec_event_hook_test), | ||
{} | ||
}; | ||
|
||
static struct kunit_suite hid_uclogic_core_test_suite = { | ||
.name = "hid_uclogic_core_test", | ||
.test_cases = hid_uclogic_core_test_cases, | ||
}; | ||
|
||
kunit_test_suite(hid_uclogic_core_test_suite); | ||
|
||
MODULE_DESCRIPTION("KUnit tests for the UC-Logic driver"); | ||
MODULE_LICENSE("GPL"); | ||
MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters