hid-uclogic-rdesc-test.c 5.9 KB

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