You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

184 lines
5.2KB

  1. /*-
  2. * Copyright (c) 2019 Vladimir Kondratyev <wulf@FreeBSD.org>
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  14. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  16. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  17. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  19. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  20. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  22. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  23. * SUCH DAMAGE.
  24. */
  25. #ifndef _HIDBUS_H_
  26. #define _HIDBUS_H_
  27. #define HID_INPUT_REPORT 0x1
  28. #define HID_OUTPUT_REPORT 0x2
  29. #define HID_FEATURE_REPORT 0x3
  30. typedef void hid_intr_t(void *context, void *data, uint16_t len);
  31. struct hid_device_info {
  32. device_t parent;
  33. char name[80];
  34. char serial[80];
  35. uint16_t idBus;
  36. uint16_t idVendor;
  37. uint16_t idProduct;
  38. uint16_t idVersion;
  39. };
  40. struct hidbus_ivars {
  41. device_t child;
  42. uint32_t usage;
  43. uint8_t index;
  44. uintptr_t driver_info; /* for internal use */
  45. hid_intr_t *intr;
  46. bool open;
  47. STAILQ_ENTRY(hidbus_ivars) link;
  48. };
  49. enum {
  50. HIDBUS_IVAR_USAGE,
  51. HIDBUS_IVAR_INDEX,
  52. HIDBUS_IVAR_INTR,
  53. HIDBUS_IVAR_DRIVER_INFO,
  54. };
  55. #define HIDBUS_ACCESSOR(A, B, T) \
  56. __BUS_ACCESSOR(hidbus, A, HIDBUS, B, T)
  57. HIDBUS_ACCESSOR(usage, USAGE, uint32_t)
  58. HIDBUS_ACCESSOR(index, INDEX, uint8_t)
  59. HIDBUS_ACCESSOR(intr, INTR, hid_intr_t *)
  60. HIDBUS_ACCESSOR(driver_info, DRIVER_INFO, uintptr_t)
  61. /*
  62. * The following structure is used when looking up an HID driver for
  63. * an HID device. It is inspired by the structure called "usb_device_id".
  64. * which is originated in Linux and ported to FreeBSD.
  65. */
  66. struct hid_device_id {
  67. /* Select which fields to match against */
  68. uint8_t
  69. match_flag_usage:1,
  70. match_flag_bus:1,
  71. match_flag_vendor:1,
  72. match_flag_product:1,
  73. match_flag_ver_lo:1,
  74. match_flag_ver_hi:1,
  75. match_flag_unused:2;
  76. /* Used for top level collection usage matches */
  77. uint32_t usage;
  78. /* Used for product specific matches; the Version range is inclusive */
  79. uint16_t idBus;
  80. uint16_t idVendor;
  81. uint16_t idProduct;
  82. uint16_t idVersion_lo;
  83. uint16_t idVersion_hi;
  84. /* Hook for driver specific information */
  85. uintptr_t driver_info;
  86. };
  87. #define HID_TLC(page,usg) \
  88. .match_flag_usage = 1, .usage = HID_USAGE2((page),(usg))
  89. #define HID_BUS(bus) \
  90. .match_flag_bus = 1, .idBus = (bus)
  91. #define HID_VENDOR(vend) \
  92. .match_flag_vendor = 1, .idVendor = (vend)
  93. #define HID_PRODUCT(prod) \
  94. .match_flag_product = 1, .idProduct = (prod)
  95. #define HID_VP(vend,prod) \
  96. HID_VENDOR(vend), HID_PRODUCT(prod)
  97. #define HID_BVP(bus,vend,prod) \
  98. HID_BUS(bus), HID_VENDOR(vend), HID_PRODUCT(prod)
  99. #define HID_BVPI(bus,vend,prod,info) \
  100. HID_BUS(bus), HID_VENDOR(vend), HID_PRODUCT(prod), HID_DRIVER_INFO(info)
  101. #define HID_VERSION_GTEQ(lo) /* greater than or equal */ \
  102. .match_flag_ver_lo = 1, .idVersion_lo = (lo)
  103. #define HID_VERSION_LTEQ(hi) /* less than or equal */ \
  104. .match_flag_ver_hi = 1, .idVersion_hi = (hi)
  105. #define HID_DRIVER_INFO(n) \
  106. .driver_info = (n)
  107. #define HID_GET_DRIVER_INFO(did) \
  108. (did)->driver_info
  109. /*
  110. * General purpose locking wrappers to ease supporting
  111. * HID polled mode:
  112. */
  113. #define HID_SYSCONS_MTX (&Giant)
  114. #ifdef INVARIANTS
  115. #define HID_MTX_ASSERT(_m, _t) do { \
  116. if (!HID_IN_POLLING_MODE_FUNC()) \
  117. mtx_assert(_m, _t); \
  118. } while (0)
  119. #else
  120. #define HID_MTX_ASSERT(_m, _t) do { } while (0)
  121. #endif
  122. #define HID_MTX_LOCK(_m) do { \
  123. if (!HID_IN_POLLING_MODE_FUNC()) \
  124. mtx_lock(_m); \
  125. } while (0)
  126. #define HID_MTX_UNLOCK(_m) do { \
  127. if (!HID_IN_POLLING_MODE_FUNC()) \
  128. mtx_unlock(_m); \
  129. } while (0)
  130. const struct hid_device_id *hidbus_lookup_id(device_t,
  131. const struct hid_device_id *, size_t);
  132. int hidbus_lookup_driver_info(device_t,
  133. const struct hid_device_id *, size_t);
  134. struct mtx * hidbus_get_lock(device_t);
  135. int hidbus_intr_start(device_t);
  136. int hidbus_intr_stop(device_t);
  137. void hidbus_intr_poll(device_t);
  138. /* hidbus HID interface */
  139. int hid_get_report_descr(device_t, void **, uint16_t *);
  140. int hid_read(device_t, void *, uint16_t, uint16_t *);
  141. int hid_write(device_t, void *, uint16_t);
  142. int hid_get_report(device_t, void *, uint16_t, uint16_t *, uint8_t,
  143. uint8_t);
  144. int hid_set_report(device_t, void *, uint16_t, uint8_t, uint8_t);
  145. int hid_set_idle(device_t, uint16_t, uint8_t);
  146. int hid_set_protocol(device_t, uint16_t);
  147. static inline const struct hid_device_info *
  148. hid_get_device_info(device_t child)
  149. {
  150. return (device_get_ivars(device_get_parent(child)));
  151. }
  152. #endif /* _HIDBUS_H_ */