hid-uclogic-params.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /* SPDX-License-Identifier: GPL-2.0+ */
  2. /*
  3. * HID driver for UC-Logic devices not fully compliant with HID standard
  4. * - tablet initialization and parameter retrieval
  5. *
  6. * Copyright (c) 2018 Nikolai Kondrashov
  7. */
  8. /*
  9. * This program is free software; you can redistribute it and/or modify it
  10. * under the terms of the GNU General Public License as published by the Free
  11. * Software Foundation; either version 2 of the License, or (at your option)
  12. * any later version.
  13. */
  14. #ifndef _HID_UCLOGIC_PARAMS_H
  15. #define _HID_UCLOGIC_PARAMS_H
  16. #include <linux/usb.h>
  17. #include <linux/hid.h>
  18. /* Types of pen in-range reporting */
  19. enum uclogic_params_pen_inrange {
  20. /* Normal reports: zero - out of proximity, one - in proximity */
  21. UCLOGIC_PARAMS_PEN_INRANGE_NORMAL = 0,
  22. /* Inverted reports: zero - in proximity, one - out of proximity */
  23. UCLOGIC_PARAMS_PEN_INRANGE_INVERTED,
  24. /* No reports */
  25. UCLOGIC_PARAMS_PEN_INRANGE_NONE,
  26. };
  27. /* Convert a pen in-range reporting type to a string */
  28. extern const char *uclogic_params_pen_inrange_to_str(
  29. enum uclogic_params_pen_inrange inrange);
  30. /*
  31. * Tablet interface's pen input parameters.
  32. *
  33. * Must use declarative (descriptive) language, not imperative, to simplify
  34. * understanding and maintain consistency.
  35. *
  36. * Noop (preserving functionality) when filled with zeroes.
  37. */
  38. struct uclogic_params_pen {
  39. /*
  40. * Pointer to report descriptor describing the inputs.
  41. * Allocated with kmalloc.
  42. */
  43. __u8 *desc_ptr;
  44. /*
  45. * Size of the report descriptor.
  46. * Only valid, if "desc_ptr" is not NULL.
  47. */
  48. unsigned int desc_size;
  49. /* Report ID, if reports should be tweaked, zero if not */
  50. unsigned int id;
  51. /* Type of in-range reporting, only valid if "id" is not zero */
  52. enum uclogic_params_pen_inrange inrange;
  53. /*
  54. * True, if reports include fragmented high resolution coords, with
  55. * high-order X and then Y bytes following the pressure field.
  56. * Only valid if "id" is not zero.
  57. */
  58. bool fragmented_hires;
  59. };
  60. /*
  61. * Parameters of frame control inputs of a tablet interface.
  62. *
  63. * Must use declarative (descriptive) language, not imperative, to simplify
  64. * understanding and maintain consistency.
  65. *
  66. * Noop (preserving functionality) when filled with zeroes.
  67. */
  68. struct uclogic_params_frame {
  69. /*
  70. * Pointer to report descriptor describing the inputs.
  71. * Allocated with kmalloc.
  72. */
  73. __u8 *desc_ptr;
  74. /*
  75. * Size of the report descriptor.
  76. * Only valid, if "desc_ptr" is not NULL.
  77. */
  78. unsigned int desc_size;
  79. /*
  80. * Report ID, if reports should be tweaked, zero if not.
  81. */
  82. unsigned int id;
  83. /*
  84. * Number of the least-significant bit of the 2-bit state of a rotary
  85. * encoder, in the report. Cannot point to a 2-bit field crossing a
  86. * byte boundary. Zero if not present. Only valid if "id" is not zero.
  87. */
  88. unsigned int re_lsb;
  89. /*
  90. * Offset of the Wacom-style device ID byte in the report, to be set
  91. * to pad device ID (0xf), for compatibility with Wacom drivers. Zero
  92. * if no changes to the report should be made. Only valid if "id" is
  93. * not zero.
  94. */
  95. unsigned int dev_id_byte;
  96. };
  97. /*
  98. * Tablet interface report parameters.
  99. *
  100. * Must use declarative (descriptive) language, not imperative, to simplify
  101. * understanding and maintain consistency.
  102. *
  103. * When filled with zeros represents a "noop" configuration - passes all
  104. * reports unchanged and lets the generic HID driver handle everything.
  105. *
  106. * The resulting device report descriptor is assembled from all the report
  107. * descriptor parts referenced by the structure. No order of assembly should
  108. * be assumed. The structure represents original device report descriptor if
  109. * all the parts are NULL.
  110. */
  111. struct uclogic_params {
  112. /*
  113. * True if the whole interface is invalid, false otherwise.
  114. */
  115. bool invalid;
  116. /*
  117. * Pointer to the common part of the replacement report descriptor,
  118. * allocated with kmalloc. NULL if no common part is needed.
  119. * Only valid, if "invalid" is false.
  120. */
  121. __u8 *desc_ptr;
  122. /*
  123. * Size of the common part of the replacement report descriptor.
  124. * Only valid, if "desc_ptr" is not NULL.
  125. */
  126. unsigned int desc_size;
  127. /*
  128. * True, if pen usage in report descriptor is invalid, when present.
  129. * Only valid, if "invalid" is false.
  130. */
  131. bool pen_unused;
  132. /*
  133. * Pen parameters and optional report descriptor part.
  134. * Only valid if "pen_unused" is valid and false.
  135. */
  136. struct uclogic_params_pen pen;
  137. /*
  138. * Frame control parameters and optional report descriptor part.
  139. * Only valid, if "invalid" is false.
  140. */
  141. struct uclogic_params_frame frame;
  142. /*
  143. * Bitmask matching frame controls "sub-report" flag in the second
  144. * byte of the pen report, or zero if it's not expected.
  145. * Only valid if both "pen" and "frame" are valid, and "frame.id" is
  146. * not zero.
  147. */
  148. __u8 pen_frame_flag;
  149. };
  150. /* Initialize a tablet interface and discover its parameters */
  151. extern int uclogic_params_init(struct uclogic_params *params,
  152. struct hid_device *hdev);
  153. /* Tablet interface parameters *printf format string */
  154. #define UCLOGIC_PARAMS_FMT_STR \
  155. ".invalid = %s\n" \
  156. ".desc_ptr = %p\n" \
  157. ".desc_size = %u\n" \
  158. ".pen_unused = %s\n" \
  159. ".pen.desc_ptr = %p\n" \
  160. ".pen.desc_size = %u\n" \
  161. ".pen.id = %u\n" \
  162. ".pen.inrange = %s\n" \
  163. ".pen.fragmented_hires = %s\n" \
  164. ".frame.desc_ptr = %p\n" \
  165. ".frame.desc_size = %u\n" \
  166. ".frame.id = %u\n" \
  167. ".frame.re_lsb = %u\n" \
  168. ".frame.dev_id_byte = %u\n" \
  169. ".pen_frame_flag = 0x%02x\n"
  170. /* Tablet interface parameters *printf format arguments */
  171. #define UCLOGIC_PARAMS_FMT_ARGS(_params) \
  172. ((_params)->invalid ? "true" : "false"), \
  173. (_params)->desc_ptr, \
  174. (_params)->desc_size, \
  175. ((_params)->pen_unused ? "true" : "false"), \
  176. (_params)->pen.desc_ptr, \
  177. (_params)->pen.desc_size, \
  178. (_params)->pen.id, \
  179. uclogic_params_pen_inrange_to_str((_params)->pen.inrange), \
  180. ((_params)->pen.fragmented_hires ? "true" : "false"), \
  181. (_params)->frame.desc_ptr, \
  182. (_params)->frame.desc_size, \
  183. (_params)->frame.id, \
  184. (_params)->frame.re_lsb, \
  185. (_params)->frame.dev_id_byte, \
  186. (_params)->pen_frame_flag
  187. /* Get a replacement report descriptor for a tablet's interface. */
  188. extern int uclogic_params_get_desc(const struct uclogic_params *params,
  189. __u8 **pdesc,
  190. unsigned int *psize);
  191. /* Free resources used by tablet interface's parameters */
  192. extern void uclogic_params_cleanup(struct uclogic_params *params);
  193. #endif /* _HID_UCLOGIC_PARAMS_H */