hid-uclogic-rdesc-test.c 6.0 KB

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