Line data Source code
1 1 : /*
2 : * Copyright (c) 2023 Nordic Semiconductor ASA
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @brief USBD HID device API header
10 : */
11 :
12 : #ifndef ZEPHYR_INCLUDE_USBD_HID_CLASS_DEVICE_H_
13 : #define ZEPHYR_INCLUDE_USBD_HID_CLASS_DEVICE_H_
14 :
15 : #include <stdint.h>
16 : #include <zephyr/device.h>
17 : #include <zephyr/usb/class/hid.h>
18 :
19 : #ifdef __cplusplus
20 : extern "C" {
21 : #endif
22 :
23 : /**
24 : * @brief USBD HID Device API
25 : * @defgroup usbd_hid_device USBD HID device API
26 : * @ingroup usb
27 : * @since 3.7
28 : * @version 0.1.0
29 : * @{
30 : */
31 :
32 : /*
33 : * HID Device overview:
34 : *
35 : * +---------------------+
36 : * | |
37 : * | |
38 : * | HID Device |
39 : * | User "top half" |
40 : * | of the device that +-------+
41 : * | deals with input | |
42 : * | sampling | |
43 : * | | |
44 : * | | |
45 : * | ------------------- | |
46 : * | | |
47 : * | HID Device user | |
48 : * | callbacks | |
49 : * | handlers | |
50 : * +---------------------+ |
51 : * ^ | HID Device Driver API:
52 : * | |
53 : * set_protocol() | | hid_device_register()
54 : * get_report() | | hid_device_submit_report(
55 : * .... | | ...
56 : * v |
57 : * +---------------------+ |
58 : * | | |
59 : * | HID Device | |
60 : * | "bottom half" |<------+
61 : * | USB HID class |
62 : * | implementation |
63 : * | |
64 : * | |
65 : * +---------------------+
66 : * ^
67 : * v
68 : * +--------------------+
69 : * | |
70 : * | USB Device |
71 : * | Support |
72 : * | |
73 : * +--------------------+
74 : */
75 :
76 : /** HID report types
77 : * Report types used in Get/Set Report requests.
78 : */
79 0 : enum {
80 : HID_REPORT_TYPE_INPUT = 1,
81 : HID_REPORT_TYPE_OUTPUT,
82 : HID_REPORT_TYPE_FEATURE,
83 : };
84 :
85 : /**
86 : * @brief HID device user callbacks
87 : *
88 : * Each device depends on a user part that handles feature, input, and output
89 : * report processing according to the device functionality described by the
90 : * report descriptor. Which callbacks must be implemented depends on the device
91 : * functionality. The USB device part of the HID device, cannot interpret
92 : * device specific report descriptor and only handles USB specific parts,
93 : * transfers and validation of requests, all reports are opaque to it.
94 : * Callbacks are called from the USB device stack thread and must not block.
95 : */
96 1 : struct hid_device_ops {
97 : /**
98 : * The interface ready callback is called with the ready argument set
99 : * to true when the corresponding interface is part of the active
100 : * configuration and the device can e.g. begin submitting input
101 : * reports, and with the argument set to false when the interface is no
102 : * longer active. This callback is optional.
103 : */
104 1 : void (*iface_ready)(const struct device *dev, const bool ready);
105 :
106 : /**
107 : * This callback is called for the HID Get Report request to get a
108 : * feature, input, or output report, which is specified by the argument
109 : * type. If there is no report ID in the report descriptor, the id
110 : * argument is zero. The callback implementation must check the
111 : * arguments, such as whether the report type is supported and the
112 : * report length, and return a negative value to indicate an
113 : * unsupported type or an error, or return the length of the report
114 : * written to the buffer.
115 : */
116 1 : int (*get_report)(const struct device *dev,
117 : const uint8_t type, const uint8_t id,
118 : const uint16_t len, uint8_t *const buf);
119 :
120 : /**
121 : * This callback is called for the HID Set Report request to set a
122 : * feature, input, or output report, which is specified by the argument
123 : * type. If there is no report ID in the report descriptor, the id
124 : * argument is zero. The callback implementation must check the
125 : * arguments, such as whether the report type is supported, and return
126 : * a nonzero value to indicate an unsupported type or an error.
127 : */
128 1 : int (*set_report)(const struct device *dev,
129 : const uint8_t type, const uint8_t id,
130 : const uint16_t len, const uint8_t *const buf);
131 :
132 : /**
133 : * Notification to limit input report frequency.
134 : * The device should mute an input report submission until a new
135 : * event occurs or until the time specified by the duration value has
136 : * elapsed. If a report ID is used in the report descriptor, the
137 : * device must store the duration and handle the specified report
138 : * accordingly. Duration time resolution is in milliseconds.
139 : */
140 1 : void (*set_idle)(const struct device *dev,
141 : const uint8_t id, const uint32_t duration);
142 :
143 : /**
144 : * If a report ID is used in the report descriptor, the device
145 : * must implement this callback and return the duration for the
146 : * specified report ID. Duration time resolution is in milliseconds.
147 : */
148 1 : uint32_t (*get_idle)(const struct device *dev, const uint8_t id);
149 :
150 : /**
151 : * Notification that the host has changed the protocol from
152 : * Boot Protocol(0) to Report Protocol(1) or vice versa.
153 : */
154 1 : void (*set_protocol)(const struct device *dev, const uint8_t proto);
155 :
156 : /**
157 : * Notification that input report submitted with
158 : * hid_device_submit_report() has been sent.
159 : * If the device does not use the callback, hid_device_submit_report()
160 : * will be processed synchronously.
161 : */
162 1 : void (*input_report_done)(const struct device *dev);
163 :
164 : /**
165 : * New output report callback. Callback will only be called for reports
166 : * received through the optional interrupt OUT pipe. If there is no
167 : * interrupt OUT pipe, output reports will be received using set_report().
168 : * If a report ID is used in the report descriptor, the host places the ID
169 : * in the buffer first, followed by the report data.
170 : */
171 1 : void (*output_report)(const struct device *dev, const uint16_t len,
172 : const uint8_t *const buf);
173 : /**
174 : * Optional Start of Frame (SoF) event callback.
175 : * There will always be software and hardware dependent jitter and
176 : * latency. This should be used very carefully, it should not block
177 : * and the execution time should be quite short.
178 : */
179 1 : void (*sof)(const struct device *dev);
180 : };
181 :
182 : /**
183 : * @brief Register HID device report descriptor and user callbacks
184 : *
185 : * The device must register report descriptor and user callbacks before
186 : * USB device support is initialized and enabled.
187 : *
188 : * @param[in] dev Pointer to HID device
189 : * @param[in] rdesc Pointer to HID report descriptor
190 : * @param[in] rsize Size of HID report descriptor
191 : * @param[in] ops Pointer to HID device callbacks
192 : */
193 1 : int hid_device_register(const struct device *dev,
194 : const uint8_t *const rdesc, const uint16_t rsize,
195 : const struct hid_device_ops *const ops);
196 :
197 : /**
198 : * @brief Submit new input report
199 : *
200 : * Submit a new input report to be sent via the interrupt IN pipe. If sync is
201 : * true, the functions will block until the report is sent.
202 : * If the device does not provide input_report_done() callback,
203 : * hid_device_submit_report() will be processed synchronously.
204 : *
205 : * @param[in] dev Pointer to HID device
206 : * @param[in] size Size of the input report
207 : * @param[in] report Input report buffer. Report buffer must be aligned.
208 : *
209 : * @return 0 on success, negative errno code on fail.
210 : */
211 1 : int hid_device_submit_report(const struct device *dev,
212 : const uint16_t size, const uint8_t *const report);
213 :
214 : /**
215 : * @}
216 : */
217 :
218 : #ifdef __cplusplus
219 : }
220 : #endif
221 :
222 : #endif /* ZEPHYR_INCLUDE_USBD_HID_CLASS_DEVICE_H_ */
|