Linux Audio

Check our new training course

Loading...
v6.8
  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>");
v6.13.7
  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>");