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