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 12 struct 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 21 static 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 29 static 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 34 static const s32 params_frame_all[UCLOGIC_RDESC_PH_ID_NUM] = { 35 [UCLOGIC_RDESC_FRAME_PH_ID_UM] = 0xFF, 36 }; 37 38 static const __u8 template_empty[] = { }; 39 static const __u8 template_small[] = { 0x00 }; 40 static const __u8 template_no_ph[] = { 0xAA, 0xFE, 0xAA, 0xED, 0x1D }; 41 42 static const __u8 template_pen_ph_end[] = { 43 0xAA, 0xBB, UCLOGIC_RDESC_PEN_PH_HEAD 44 }; 45 46 static const __u8 template_btn_ph_end[] = { 47 0xAA, 0xBB, UCLOGIC_RDESC_FRAME_PH_BTN_HEAD 48 }; 49 50 static 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 58 static 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 66 static const __u8 template_frame_all_params[] = { 67 0x01, 0x02, 68 UCLOGIC_RDESC_FRAME_PH_BTN, 69 0x99, 70 }; 71 72 static const __u8 expected_frame_all_params[] = { 73 0x01, 0x02, 74 0x2A, 0xFF, 0x00, 75 0x99, 76 }; 77 78 static 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 85 static 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 92 static 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 98 static 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 181 static 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 187 KUNIT_ARRAY_PARAM(uclogic_template, uclogic_template_cases, 188 uclogic_template_case_desc); 189 190 static 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_EQ(test, 0, 201 memcmp(res, params->expected, params->template_size)); 202 kfree(res); 203 } 204 205 static struct kunit_case hid_uclogic_rdesc_test_cases[] = { 206 KUNIT_CASE_PARAM(hid_test_uclogic_template, uclogic_template_gen_params), 207 {} 208 }; 209 210 static struct kunit_suite hid_uclogic_rdesc_test_suite = { 211 .name = "hid_uclogic_rdesc_test", 212 .test_cases = hid_uclogic_rdesc_test_cases, 213 }; 214 215 kunit_test_suite(hid_uclogic_rdesc_test_suite); 216 217 MODULE_DESCRIPTION("KUnit tests for the UC-Logic driver"); 218 MODULE_LICENSE("GPL"); 219 MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>"); 220