Skip to content

Commit a092986

Browse files
JoseExpositoJiri Kosina
authored andcommitted
HID: uclogic: Parse the UGEE v2 frame type
The string descriptor returned by UGEE v2 devices contains a byte indicating the device frame type. The values discovered so far are: - 0: Frame with buttons, present in the XP-PEN Deco L. - 1: Frame with buttons and dial, present in the PARBLO A610 PRO. - 2: Frame with buttons and a mouse, shaped as a dial + touchpad. Present in the XP-PEN Deco Pro S. Parse the frame type and add KUnit tests. Tested-by: Jouke Witteveen <[email protected]> Signed-off-by: José Expósito <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 8640229 commit a092986

File tree

3 files changed

+59
-5
lines changed

3 files changed

+59
-5
lines changed

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

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
#include <kunit/test.h>
10+
#include "./hid-uclogic-params.h"
1011
#include "./hid-uclogic-rdesc.h"
1112

1213
#define MAX_STR_DESC_SIZE 14
@@ -17,6 +18,7 @@ struct uclogic_parse_ugee_v2_desc_case {
1718
const __u8 str_desc[MAX_STR_DESC_SIZE];
1819
size_t str_desc_size;
1920
const s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
21+
enum uclogic_params_frame_type frame_type;
2022
};
2123

2224
static struct uclogic_parse_ugee_v2_desc_case uclogic_parse_ugee_v2_desc_cases[] = {
@@ -26,6 +28,7 @@ static struct uclogic_parse_ugee_v2_desc_case uclogic_parse_ugee_v2_desc_cases[]
2628
.str_desc = {},
2729
.str_desc_size = 0,
2830
.desc_params = {},
31+
.frame_type = UCLOGIC_PARAMS_FRAME_BUTTONS,
2932
},
3033
{
3134
.name = "resolution_with_value_0",
@@ -48,6 +51,7 @@ static struct uclogic_parse_ugee_v2_desc_case uclogic_parse_ugee_v2_desc_cases[]
4851
[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = 0x1FFF,
4952
[UCLOGIC_RDESC_FRAME_PH_ID_UM] = 0x08,
5053
},
54+
.frame_type = UCLOGIC_PARAMS_FRAME_BUTTONS,
5155
},
5256
/* XP-PEN Deco L str_desc: Frame with 8 buttons */
5357
{
@@ -71,6 +75,7 @@ static struct uclogic_parse_ugee_v2_desc_case uclogic_parse_ugee_v2_desc_cases[]
7175
[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = 0x1FFF,
7276
[UCLOGIC_RDESC_FRAME_PH_ID_UM] = 0x08,
7377
},
78+
.frame_type = UCLOGIC_PARAMS_FRAME_BUTTONS,
7479
},
7580
/* PARBLO A610 PRO str_desc: Frame with 9 buttons and dial */
7681
{
@@ -94,6 +99,31 @@ static struct uclogic_parse_ugee_v2_desc_case uclogic_parse_ugee_v2_desc_cases[]
9499
[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = 0x1FFF,
95100
[UCLOGIC_RDESC_FRAME_PH_ID_UM] = 0x09,
96101
},
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,
97127
},
98128
};
99129

@@ -110,12 +140,14 @@ static void uclogic_parse_ugee_v2_desc_test(struct kunit *test)
110140
{
111141
int res;
112142
s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
143+
enum uclogic_params_frame_type frame_type;
113144
const struct uclogic_parse_ugee_v2_desc_case *params = test->param_value;
114145

115146
res = uclogic_params_parse_ugee_v2_desc(params->str_desc,
116147
params->str_desc_size,
117148
desc_params,
118-
ARRAY_SIZE(desc_params));
149+
ARRAY_SIZE(desc_params),
150+
&frame_type);
119151
KUNIT_ASSERT_EQ(test, res, params->res);
120152

121153
if (res)
@@ -139,6 +171,7 @@ static void uclogic_parse_ugee_v2_desc_test(struct kunit *test)
139171
KUNIT_EXPECT_EQ(test,
140172
params->desc_params[UCLOGIC_RDESC_FRAME_PH_ID_UM],
141173
desc_params[UCLOGIC_RDESC_FRAME_PH_ID_UM]);
174+
KUNIT_EXPECT_EQ(test, params->frame_type, frame_type);
142175
}
143176

144177
static struct kunit_case hid_uclogic_params_test_cases[] = {

drivers/hid/hid-uclogic-params.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,14 +1064,16 @@ static int uclogic_probe_interface(struct hid_device *hdev, u8 *magic_arr,
10641064
* @str_desc_size: Size of the string descriptor.
10651065
* @desc_params: Output description params list.
10661066
* @desc_params_size: Size of the output description params list.
1067+
* @frame_type: Output frame type.
10671068
*
10681069
* Returns:
10691070
* Zero, if successful. A negative errno code on error.
10701071
*/
10711072
static int uclogic_params_parse_ugee_v2_desc(const __u8 *str_desc,
10721073
size_t str_desc_size,
10731074
s32 *desc_params,
1074-
size_t desc_params_size)
1075+
size_t desc_params_size,
1076+
enum uclogic_params_frame_type *frame_type)
10751077
{
10761078
s32 pen_x_lm, pen_y_lm;
10771079
s32 pen_x_pm, pen_y_pm;
@@ -1091,6 +1093,7 @@ static int uclogic_params_parse_ugee_v2_desc(const __u8 *str_desc,
10911093
pen_x_lm = get_unaligned_le16(str_desc + 2);
10921094
pen_y_lm = get_unaligned_le16(str_desc + 4);
10931095
frame_num_buttons = str_desc[6];
1096+
*frame_type = str_desc[7];
10941097
pen_pressure_lm = get_unaligned_le16(str_desc + 8);
10951098

10961099
resolution = get_unaligned_le16(str_desc + 10);
@@ -1176,6 +1179,7 @@ static int uclogic_params_ugee_v2_init(struct uclogic_params *params,
11761179
__u8 *str_desc = NULL;
11771180
__u8 *rdesc_pen = NULL;
11781181
s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
1182+
enum uclogic_params_frame_type frame_type;
11791183
__u8 magic_arr[] = {
11801184
0x02, 0xb0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
11811185
};
@@ -1219,7 +1223,8 @@ static int uclogic_params_ugee_v2_init(struct uclogic_params *params,
12191223

12201224
rc = uclogic_params_parse_ugee_v2_desc(str_desc, str_desc_len,
12211225
desc_params,
1222-
ARRAY_SIZE(desc_params));
1226+
ARRAY_SIZE(desc_params),
1227+
&frame_type);
12231228
if (rc)
12241229
goto cleanup;
12251230

@@ -1243,8 +1248,14 @@ static int uclogic_params_ugee_v2_init(struct uclogic_params *params,
12431248
p.pen.subreport_list[0].id = UCLOGIC_RDESC_V1_FRAME_ID;
12441249

12451250
/* Initialize the frame interface */
1246-
rc = uclogic_params_ugee_v2_init_frame_buttons(&p, desc_params,
1247-
ARRAY_SIZE(desc_params));
1251+
switch (frame_type) {
1252+
case UCLOGIC_PARAMS_FRAME_BUTTONS:
1253+
default:
1254+
rc = uclogic_params_ugee_v2_init_frame_buttons(&p, desc_params,
1255+
ARRAY_SIZE(desc_params));
1256+
break;
1257+
}
1258+
12481259
if (rc)
12491260
goto cleanup;
12501261

drivers/hid/hid-uclogic-params.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ enum uclogic_params_pen_inrange {
2929
UCLOGIC_PARAMS_PEN_INRANGE_NONE,
3030
};
3131

32+
/* Types of frames */
33+
enum uclogic_params_frame_type {
34+
/* Frame with buttons */
35+
UCLOGIC_PARAMS_FRAME_BUTTONS = 0,
36+
/* Frame with buttons and a dial */
37+
UCLOGIC_PARAMS_FRAME_DIAL,
38+
/* Frame with buttons and a mouse (shaped as a dial + touchpad) */
39+
UCLOGIC_PARAMS_FRAME_MOUSE,
40+
};
41+
3242
/*
3343
* Pen report's subreport data.
3444
*/

0 commit comments

Comments
 (0)