Skip to content

Commit 430257d

Browse files
committed
Merge branch 'for-6.1/uclogic' into for-linus
- Add UGEEv2 support (XP-PEN Deco Pro S and Parblo A610 PRO) (José Expósito)
2 parents d7ae8ff + 7495fb7 commit 430257d

10 files changed

+500
-51
lines changed

drivers/hid/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1261,7 +1261,7 @@ config HID_MCP2221
12611261
will be called hid-mcp2221.ko.
12621262

12631263
config HID_KUNIT_TEST
1264-
bool "KUnit tests for HID" if !KUNIT_ALL_TESTS
1264+
tristate "KUnit tests for HID" if !KUNIT_ALL_TESTS
12651265
depends on KUNIT=y
12661266
depends on HID_UCLOGIC
12671267
default KUNIT_ALL_TESTS

drivers/hid/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,10 @@ obj-$(CONFIG_HID_WIIMOTE) += hid-wiimote.o
147147
obj-$(CONFIG_HID_SENSOR_HUB) += hid-sensor-hub.o
148148
obj-$(CONFIG_HID_SENSOR_CUSTOM_SENSOR) += hid-sensor-custom.o
149149

150-
obj-$(CONFIG_HID_KUNIT_TEST) += hid-uclogic-rdesc.o \
150+
hid-uclogic-test-objs := hid-uclogic-rdesc.o \
151+
hid-uclogic-params.o \
151152
hid-uclogic-rdesc-test.o
153+
obj-$(CONFIG_HID_KUNIT_TEST) += hid-uclogic-test.o
152154

153155
obj-$(CONFIG_USB_HID) += usbhid/
154156
obj-$(CONFIG_USB_MOUSE) += usbhid/

drivers/hid/hid-ids.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,10 +1282,12 @@
12821282
#define USB_DEVICE_ID_YIYNOVA_TABLET 0x004d
12831283

12841284
#define USB_VENDOR_ID_UGEE 0x28bd
1285+
#define USB_DEVICE_ID_UGEE_PARBLO_A610_PRO 0x1903
12851286
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540 0x0075
12861287
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_G640 0x0094
12871288
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01 0x0042
12881289
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L 0x0935
1290+
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_S 0x0909
12891291
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06 0x0078
12901292
#define USB_DEVICE_ID_UGEE_TABLET_G5 0x0074
12911293
#define USB_DEVICE_ID_UGEE_TABLET_EX07S 0x0071

drivers/hid/hid-uclogic-core.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ static int uclogic_input_configured(struct hid_device *hdev,
153153
suffix = "Pad";
154154
break;
155155
case HID_DG_PEN:
156+
case HID_DG_DIGITIZER:
156157
suffix = "Pen";
157158
break;
158159
case HID_CP_CONSUMER_CONTROL:
@@ -509,6 +510,8 @@ static const struct hid_device_id uclogic_devices[] = {
509510
USB_DEVICE_ID_UGTIZER_TABLET_GP0610) },
510511
{ HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER,
511512
USB_DEVICE_ID_UGTIZER_TABLET_GT5040) },
513+
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
514+
USB_DEVICE_ID_UGEE_PARBLO_A610_PRO) },
512515
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
513516
USB_DEVICE_ID_UGEE_TABLET_G5) },
514517
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
@@ -523,6 +526,8 @@ static const struct hid_device_id uclogic_devices[] = {
523526
USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01) },
524527
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
525528
USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L) },
529+
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
530+
USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_S) },
526531
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
527532
USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06) },
528533
{ }

drivers/hid/hid-uclogic-params-test.c

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
// SPDX-License-Identifier: GPL-2.0+
2+
3+
/*
4+
* HID driver for UC-Logic devices not fully compliant with HID standard
5+
*
6+
* Copyright (c) 2022 José Expósito <[email protected]>
7+
*/
8+
9+
#include <kunit/test.h>
10+
#include "./hid-uclogic-params.h"
11+
#include "./hid-uclogic-rdesc.h"
12+
13+
#define MAX_STR_DESC_SIZE 14
14+
15+
struct uclogic_parse_ugee_v2_desc_case {
16+
const char *name;
17+
int res;
18+
const __u8 str_desc[MAX_STR_DESC_SIZE];
19+
size_t str_desc_size;
20+
const s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
21+
enum uclogic_params_frame_type frame_type;
22+
};
23+
24+
static struct uclogic_parse_ugee_v2_desc_case uclogic_parse_ugee_v2_desc_cases[] = {
25+
{
26+
.name = "invalid_str_desc",
27+
.res = -EINVAL,
28+
.str_desc = {},
29+
.str_desc_size = 0,
30+
.desc_params = {},
31+
.frame_type = UCLOGIC_PARAMS_FRAME_BUTTONS,
32+
},
33+
{
34+
.name = "resolution_with_value_0",
35+
.res = 0,
36+
.str_desc = {
37+
0x0E, 0x03,
38+
0x70, 0xB2,
39+
0x10, 0x77,
40+
0x08,
41+
0x00,
42+
0xFF, 0x1F,
43+
0x00, 0x00,
44+
},
45+
.str_desc_size = 12,
46+
.desc_params = {
47+
[UCLOGIC_RDESC_PEN_PH_ID_X_LM] = 0xB270,
48+
[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0,
49+
[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] = 0x7710,
50+
[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0,
51+
[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = 0x1FFF,
52+
[UCLOGIC_RDESC_FRAME_PH_ID_UM] = 0x08,
53+
},
54+
.frame_type = UCLOGIC_PARAMS_FRAME_BUTTONS,
55+
},
56+
/* XP-PEN Deco L str_desc: Frame with 8 buttons */
57+
{
58+
.name = "frame_type_buttons",
59+
.res = 0,
60+
.str_desc = {
61+
0x0E, 0x03,
62+
0x70, 0xB2,
63+
0x10, 0x77,
64+
0x08,
65+
0x00,
66+
0xFF, 0x1F,
67+
0xD8, 0x13,
68+
},
69+
.str_desc_size = 12,
70+
.desc_params = {
71+
[UCLOGIC_RDESC_PEN_PH_ID_X_LM] = 0xB270,
72+
[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0x2320,
73+
[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] = 0x7710,
74+
[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0x1770,
75+
[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = 0x1FFF,
76+
[UCLOGIC_RDESC_FRAME_PH_ID_UM] = 0x08,
77+
},
78+
.frame_type = UCLOGIC_PARAMS_FRAME_BUTTONS,
79+
},
80+
/* PARBLO A610 PRO str_desc: Frame with 9 buttons and dial */
81+
{
82+
.name = "frame_type_dial",
83+
.res = 0,
84+
.str_desc = {
85+
0x0E, 0x03,
86+
0x96, 0xC7,
87+
0xF9, 0x7C,
88+
0x09,
89+
0x01,
90+
0xFF, 0x1F,
91+
0xD8, 0x13,
92+
},
93+
.str_desc_size = 12,
94+
.desc_params = {
95+
[UCLOGIC_RDESC_PEN_PH_ID_X_LM] = 0xC796,
96+
[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0x2749,
97+
[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] = 0x7CF9,
98+
[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0x1899,
99+
[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = 0x1FFF,
100+
[UCLOGIC_RDESC_FRAME_PH_ID_UM] = 0x09,
101+
},
102+
.frame_type = UCLOGIC_PARAMS_FRAME_DIAL,
103+
},
104+
/* XP-PEN Deco Pro S str_desc: Frame with 8 buttons and mouse */
105+
{
106+
.name = "frame_type_mouse",
107+
.res = 0,
108+
.str_desc = {
109+
0x0E, 0x03,
110+
0xC8, 0xB3,
111+
0x34, 0x65,
112+
0x08,
113+
0x02,
114+
0xFF, 0x1F,
115+
0xD8, 0x13,
116+
},
117+
.str_desc_size = 12,
118+
.desc_params = {
119+
[UCLOGIC_RDESC_PEN_PH_ID_X_LM] = 0xB3C8,
120+
[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0x2363,
121+
[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] = 0x6534,
122+
[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0x13EC,
123+
[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = 0x1FFF,
124+
[UCLOGIC_RDESC_FRAME_PH_ID_UM] = 0x08,
125+
},
126+
.frame_type = UCLOGIC_PARAMS_FRAME_MOUSE,
127+
},
128+
};
129+
130+
static void uclogic_parse_ugee_v2_desc_case_desc(struct uclogic_parse_ugee_v2_desc_case *t,
131+
char *desc)
132+
{
133+
strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
134+
}
135+
136+
KUNIT_ARRAY_PARAM(uclogic_parse_ugee_v2_desc, uclogic_parse_ugee_v2_desc_cases,
137+
uclogic_parse_ugee_v2_desc_case_desc);
138+
139+
static void uclogic_parse_ugee_v2_desc_test(struct kunit *test)
140+
{
141+
int res;
142+
s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
143+
enum uclogic_params_frame_type frame_type;
144+
const struct uclogic_parse_ugee_v2_desc_case *params = test->param_value;
145+
146+
res = uclogic_params_parse_ugee_v2_desc(params->str_desc,
147+
params->str_desc_size,
148+
desc_params,
149+
ARRAY_SIZE(desc_params),
150+
&frame_type);
151+
KUNIT_ASSERT_EQ(test, res, params->res);
152+
153+
if (res)
154+
return;
155+
156+
KUNIT_EXPECT_EQ(test,
157+
params->desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM],
158+
desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM]);
159+
KUNIT_EXPECT_EQ(test,
160+
params->desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM],
161+
desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM]);
162+
KUNIT_EXPECT_EQ(test,
163+
params->desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM],
164+
desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM]);
165+
KUNIT_EXPECT_EQ(test,
166+
params->desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM],
167+
desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM]);
168+
KUNIT_EXPECT_EQ(test,
169+
params->desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM],
170+
desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM]);
171+
KUNIT_EXPECT_EQ(test,
172+
params->desc_params[UCLOGIC_RDESC_FRAME_PH_ID_UM],
173+
desc_params[UCLOGIC_RDESC_FRAME_PH_ID_UM]);
174+
KUNIT_EXPECT_EQ(test, params->frame_type, frame_type);
175+
}
176+
177+
static struct kunit_case hid_uclogic_params_test_cases[] = {
178+
KUNIT_CASE_PARAM(uclogic_parse_ugee_v2_desc_test,
179+
uclogic_parse_ugee_v2_desc_gen_params),
180+
{}
181+
};
182+
183+
static struct kunit_suite hid_uclogic_params_test_suite = {
184+
.name = "hid_uclogic_params_test",
185+
.test_cases = hid_uclogic_params_test_cases,
186+
};
187+
188+
kunit_test_suite(hid_uclogic_params_test_suite);
189+
190+
MODULE_DESCRIPTION("KUnit tests for the UC-Logic driver");
191+
MODULE_LICENSE("GPL");
192+
MODULE_AUTHOR("José Expósito <[email protected]>");

0 commit comments

Comments
 (0)