Loading...
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 <jose.exposito89@gmail.com>
7 */
8
9#include <kunit/test.h>
10#include "./hid-uclogic-rdesc.h"
11
12struct uclogic_template_case {
13 const char *name;
14 const __u8 *template;
15 size_t template_size;
16 const s32 *param_list;
17 size_t param_num;
18 const __u8 *expected;
19};
20
21static const s32 params_pen_all[UCLOGIC_RDESC_PH_ID_NUM] = {
22 [UCLOGIC_RDESC_PEN_PH_ID_X_LM] = 0xAA,
23 [UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0xBB,
24 [UCLOGIC_RDESC_PEN_PH_ID_Y_LM] = 0xCC,
25 [UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0xDD,
26 [UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = 0xEE,
27};
28
29static const s32 params_pen_some[] = {
30 [UCLOGIC_RDESC_PEN_PH_ID_X_LM] = 0xAA,
31 [UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0xBB,
32};
33
34static const s32 params_frame_all[UCLOGIC_RDESC_PH_ID_NUM] = {
35 [UCLOGIC_RDESC_FRAME_PH_ID_UM] = 0xFF,
36};
37
38static const __u8 template_empty[] = { };
39static const __u8 template_small[] = { 0x00 };
40static const __u8 template_no_ph[] = { 0xAA, 0xFE, 0xAA, 0xED, 0x1D };
41
42static const __u8 template_pen_ph_end[] = {
43 0xAA, 0xBB, UCLOGIC_RDESC_PEN_PH_HEAD
44};
45
46static const __u8 template_btn_ph_end[] = {
47 0xAA, 0xBB, UCLOGIC_RDESC_FRAME_PH_BTN_HEAD
48};
49
50static const __u8 template_pen_all_params[] = {
51 UCLOGIC_RDESC_PEN_PH(X_LM),
52 0x47, UCLOGIC_RDESC_PEN_PH(X_PM),
53 0x27, UCLOGIC_RDESC_PEN_PH(Y_LM),
54 UCLOGIC_RDESC_PEN_PH(Y_PM),
55 0x00, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM),
56};
57
58static const __u8 expected_pen_all_params[] = {
59 0xAA, 0x00, 0x00, 0x00,
60 0x47, 0xBB, 0x00, 0x00, 0x00,
61 0x27, 0xCC, 0x00, 0x00, 0x00,
62 0xDD, 0x00, 0x00, 0x00,
63 0x00, 0xEE, 0x00, 0x00, 0x00,
64};
65
66static const __u8 template_frame_all_params[] = {
67 0x01, 0x02,
68 UCLOGIC_RDESC_FRAME_PH_BTN,
69 0x99,
70};
71
72static const __u8 expected_frame_all_params[] = {
73 0x01, 0x02,
74 0x2A, 0xFF, 0x00,
75 0x99,
76};
77
78static const __u8 template_pen_some_params[] = {
79 0x01, 0x02,
80 UCLOGIC_RDESC_PEN_PH(X_LM),
81 0x03, UCLOGIC_RDESC_PEN_PH(X_PM),
82 0x04, 0x05,
83};
84
85static const __u8 expected_pen_some_params[] = {
86 0x01, 0x02,
87 0xAA, 0x00, 0x00, 0x00,
88 0x03, 0xBB, 0x00, 0x00, 0x00,
89 0x04, 0x05,
90};
91
92static const __u8 template_params_none[] = {
93 0x27, UCLOGIC_RDESC_PEN_PH(Y_LM),
94 UCLOGIC_RDESC_PEN_PH(Y_PM),
95 0x00, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM),
96};
97
98static struct uclogic_template_case uclogic_template_cases[] = {
99 {
100 .name = "empty_template",
101 .template = template_empty,
102 .template_size = sizeof(template_empty),
103 .param_list = params_pen_all,
104 .param_num = ARRAY_SIZE(params_pen_all),
105 .expected = template_empty,
106 },
107 {
108 .name = "template_smaller_than_the_placeholder",
109 .template = template_small,
110 .template_size = sizeof(template_small),
111 .param_list = params_pen_all,
112 .param_num = ARRAY_SIZE(params_pen_all),
113 .expected = template_small,
114 },
115 {
116 .name = "no_placeholder",
117 .template = template_no_ph,
118 .template_size = sizeof(template_no_ph),
119 .param_list = params_pen_all,
120 .param_num = ARRAY_SIZE(params_pen_all),
121 .expected = template_no_ph,
122 },
123 {
124 .name = "pen_placeholder_at_the_end_without_id",
125 .template = template_pen_ph_end,
126 .template_size = sizeof(template_pen_ph_end),
127 .param_list = params_pen_all,
128 .param_num = ARRAY_SIZE(params_pen_all),
129 .expected = template_pen_ph_end,
130 },
131 {
132 .name = "frame_button_placeholder_at_the_end_without_id",
133 .template = template_btn_ph_end,
134 .template_size = sizeof(template_btn_ph_end),
135 .param_list = params_frame_all,
136 .param_num = ARRAY_SIZE(params_frame_all),
137 .expected = template_btn_ph_end,
138 },
139 {
140 .name = "all_params_present_in_the_pen_template",
141 .template = template_pen_all_params,
142 .template_size = sizeof(template_pen_all_params),
143 .param_list = params_pen_all,
144 .param_num = ARRAY_SIZE(params_pen_all),
145 .expected = expected_pen_all_params,
146 },
147 {
148 .name = "all_params_present_in_the_frame_template",
149 .template = template_frame_all_params,
150 .template_size = sizeof(template_frame_all_params),
151 .param_list = params_frame_all,
152 .param_num = ARRAY_SIZE(params_frame_all),
153 .expected = expected_frame_all_params,
154 },
155 {
156 .name = "some_params_present_in_the_pen_template_with_complete_param_list",
157 .template = template_pen_some_params,
158 .template_size = sizeof(template_pen_some_params),
159 .param_list = params_pen_all,
160 .param_num = ARRAY_SIZE(params_pen_all),
161 .expected = expected_pen_some_params,
162 },
163 {
164 .name = "some_params_present_in_the_pen_template_with_incomplete_param_list",
165 .template = template_pen_some_params,
166 .template_size = sizeof(template_pen_some_params),
167 .param_list = params_pen_some,
168 .param_num = ARRAY_SIZE(params_pen_some),
169 .expected = expected_pen_some_params,
170 },
171 {
172 .name = "no_params_present_in_the_template",
173 .template = template_params_none,
174 .template_size = sizeof(template_params_none),
175 .param_list = params_pen_some,
176 .param_num = ARRAY_SIZE(params_pen_some),
177 .expected = template_params_none,
178 },
179};
180
181static void uclogic_template_case_desc(struct uclogic_template_case *t,
182 char *desc)
183{
184 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
185}
186
187KUNIT_ARRAY_PARAM(uclogic_template, uclogic_template_cases,
188 uclogic_template_case_desc);
189
190static void hid_test_uclogic_template(struct kunit *test)
191{
192 __u8 *res;
193 const struct uclogic_template_case *params = test->param_value;
194
195 res = uclogic_rdesc_template_apply(params->template,
196 params->template_size,
197 params->param_list,
198 params->param_num);
199 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, res);
200 KUNIT_EXPECT_MEMEQ(test, res, params->expected, params->template_size);
201 kfree(res);
202}
203
204static struct kunit_case hid_uclogic_rdesc_test_cases[] = {
205 KUNIT_CASE_PARAM(hid_test_uclogic_template, uclogic_template_gen_params),
206 {}
207};
208
209static struct kunit_suite hid_uclogic_rdesc_test_suite = {
210 .name = "hid_uclogic_rdesc_test",
211 .test_cases = hid_uclogic_rdesc_test_cases,
212};
213
214kunit_test_suite(hid_uclogic_rdesc_test_suite);
215
216MODULE_DESCRIPTION("KUnit tests for the UC-Logic driver");
217MODULE_LICENSE("GPL");
218MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>");
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 <jose.exposito89@gmail.com>
7 */
8
9#include <kunit/test.h>
10#include "./hid-uclogic-rdesc.h"
11
12MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
13
14struct uclogic_template_case {
15 const char *name;
16 const __u8 *template;
17 size_t template_size;
18 const s32 *param_list;
19 size_t param_num;
20 const __u8 *expected;
21};
22
23static const s32 params_pen_all[UCLOGIC_RDESC_PH_ID_NUM] = {
24 [UCLOGIC_RDESC_PEN_PH_ID_X_LM] = 0xAA,
25 [UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0xBB,
26 [UCLOGIC_RDESC_PEN_PH_ID_Y_LM] = 0xCC,
27 [UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0xDD,
28 [UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = 0xEE,
29};
30
31static const s32 params_pen_some[] = {
32 [UCLOGIC_RDESC_PEN_PH_ID_X_LM] = 0xAA,
33 [UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0xBB,
34};
35
36static const s32 params_frame_all[UCLOGIC_RDESC_PH_ID_NUM] = {
37 [UCLOGIC_RDESC_FRAME_PH_ID_UM] = 0xFF,
38};
39
40static const __u8 template_empty[] = { };
41static const __u8 template_small[] = { 0x00 };
42static const __u8 template_no_ph[] = { 0xAA, 0xFE, 0xAA, 0xED, 0x1D };
43
44static const __u8 template_pen_ph_end[] = {
45 0xAA, 0xBB, UCLOGIC_RDESC_PEN_PH_HEAD
46};
47
48static const __u8 template_btn_ph_end[] = {
49 0xAA, 0xBB, UCLOGIC_RDESC_FRAME_PH_BTN_HEAD
50};
51
52static const __u8 template_pen_all_params[] = {
53 UCLOGIC_RDESC_PEN_PH(X_LM),
54 0x47, UCLOGIC_RDESC_PEN_PH(X_PM),
55 0x27, UCLOGIC_RDESC_PEN_PH(Y_LM),
56 UCLOGIC_RDESC_PEN_PH(Y_PM),
57 0x00, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM),
58};
59
60static const __u8 expected_pen_all_params[] = {
61 0xAA, 0x00, 0x00, 0x00,
62 0x47, 0xBB, 0x00, 0x00, 0x00,
63 0x27, 0xCC, 0x00, 0x00, 0x00,
64 0xDD, 0x00, 0x00, 0x00,
65 0x00, 0xEE, 0x00, 0x00, 0x00,
66};
67
68static const __u8 template_frame_all_params[] = {
69 0x01, 0x02,
70 UCLOGIC_RDESC_FRAME_PH_BTN,
71 0x99,
72};
73
74static const __u8 expected_frame_all_params[] = {
75 0x01, 0x02,
76 0x2A, 0xFF, 0x00,
77 0x99,
78};
79
80static const __u8 template_pen_some_params[] = {
81 0x01, 0x02,
82 UCLOGIC_RDESC_PEN_PH(X_LM),
83 0x03, UCLOGIC_RDESC_PEN_PH(X_PM),
84 0x04, 0x05,
85};
86
87static const __u8 expected_pen_some_params[] = {
88 0x01, 0x02,
89 0xAA, 0x00, 0x00, 0x00,
90 0x03, 0xBB, 0x00, 0x00, 0x00,
91 0x04, 0x05,
92};
93
94static const __u8 template_params_none[] = {
95 0x27, UCLOGIC_RDESC_PEN_PH(Y_LM),
96 UCLOGIC_RDESC_PEN_PH(Y_PM),
97 0x00, UCLOGIC_RDESC_PEN_PH(PRESSURE_LM),
98};
99
100static struct uclogic_template_case uclogic_template_cases[] = {
101 {
102 .name = "empty_template",
103 .template = template_empty,
104 .template_size = sizeof(template_empty),
105 .param_list = params_pen_all,
106 .param_num = ARRAY_SIZE(params_pen_all),
107 .expected = template_empty,
108 },
109 {
110 .name = "template_smaller_than_the_placeholder",
111 .template = template_small,
112 .template_size = sizeof(template_small),
113 .param_list = params_pen_all,
114 .param_num = ARRAY_SIZE(params_pen_all),
115 .expected = template_small,
116 },
117 {
118 .name = "no_placeholder",
119 .template = template_no_ph,
120 .template_size = sizeof(template_no_ph),
121 .param_list = params_pen_all,
122 .param_num = ARRAY_SIZE(params_pen_all),
123 .expected = template_no_ph,
124 },
125 {
126 .name = "pen_placeholder_at_the_end_without_id",
127 .template = template_pen_ph_end,
128 .template_size = sizeof(template_pen_ph_end),
129 .param_list = params_pen_all,
130 .param_num = ARRAY_SIZE(params_pen_all),
131 .expected = template_pen_ph_end,
132 },
133 {
134 .name = "frame_button_placeholder_at_the_end_without_id",
135 .template = template_btn_ph_end,
136 .template_size = sizeof(template_btn_ph_end),
137 .param_list = params_frame_all,
138 .param_num = ARRAY_SIZE(params_frame_all),
139 .expected = template_btn_ph_end,
140 },
141 {
142 .name = "all_params_present_in_the_pen_template",
143 .template = template_pen_all_params,
144 .template_size = sizeof(template_pen_all_params),
145 .param_list = params_pen_all,
146 .param_num = ARRAY_SIZE(params_pen_all),
147 .expected = expected_pen_all_params,
148 },
149 {
150 .name = "all_params_present_in_the_frame_template",
151 .template = template_frame_all_params,
152 .template_size = sizeof(template_frame_all_params),
153 .param_list = params_frame_all,
154 .param_num = ARRAY_SIZE(params_frame_all),
155 .expected = expected_frame_all_params,
156 },
157 {
158 .name = "some_params_present_in_the_pen_template_with_complete_param_list",
159 .template = template_pen_some_params,
160 .template_size = sizeof(template_pen_some_params),
161 .param_list = params_pen_all,
162 .param_num = ARRAY_SIZE(params_pen_all),
163 .expected = expected_pen_some_params,
164 },
165 {
166 .name = "some_params_present_in_the_pen_template_with_incomplete_param_list",
167 .template = template_pen_some_params,
168 .template_size = sizeof(template_pen_some_params),
169 .param_list = params_pen_some,
170 .param_num = ARRAY_SIZE(params_pen_some),
171 .expected = expected_pen_some_params,
172 },
173 {
174 .name = "no_params_present_in_the_template",
175 .template = template_params_none,
176 .template_size = sizeof(template_params_none),
177 .param_list = params_pen_some,
178 .param_num = ARRAY_SIZE(params_pen_some),
179 .expected = template_params_none,
180 },
181};
182
183static void uclogic_template_case_desc(struct uclogic_template_case *t,
184 char *desc)
185{
186 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
187}
188
189KUNIT_ARRAY_PARAM(uclogic_template, uclogic_template_cases,
190 uclogic_template_case_desc);
191
192static void hid_test_uclogic_template(struct kunit *test)
193{
194 __u8 *res;
195 const struct uclogic_template_case *params = test->param_value;
196
197 res = uclogic_rdesc_template_apply(params->template,
198 params->template_size,
199 params->param_list,
200 params->param_num);
201 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, res);
202 KUNIT_EXPECT_MEMEQ(test, res, params->expected, params->template_size);
203 kfree(res);
204}
205
206static struct kunit_case hid_uclogic_rdesc_test_cases[] = {
207 KUNIT_CASE_PARAM(hid_test_uclogic_template, uclogic_template_gen_params),
208 {}
209};
210
211static struct kunit_suite hid_uclogic_rdesc_test_suite = {
212 .name = "hid_uclogic_rdesc_test",
213 .test_cases = hid_uclogic_rdesc_test_cases,
214};
215
216kunit_test_suite(hid_uclogic_rdesc_test_suite);
217
218MODULE_DESCRIPTION("KUnit tests for the UC-Logic driver");
219MODULE_LICENSE("GPL");
220MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>");