1 /*
2  * Copyright (c) 2023 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT zephyr_hid_device
8 
9 #include "usbd_hid_internal.h"
10 
11 #include <stdlib.h>
12 #include <assert.h>
13 #include <zephyr/device.h>
14 #include <zephyr/devicetree.h>
15 #include <zephyr/sys/byteorder.h>
16 #include <zephyr/usb/usbd.h>
17 #include <zephyr/usb/class/usbd_hid.h>
18 #include <zephyr/drivers/usb/udc.h>
19 
20 #include <zephyr/logging/log.h>
21 LOG_MODULE_REGISTER(usbd_hid, CONFIG_USBD_HID_LOG_LEVEL);
22 
23 #define HID_GET_IDLE_DURATION(wValue)		((wValue) >> 8)
24 #define HID_GET_IDLE_ID(wValue)			(wValue)
25 #define HID_GET_REPORT_TYPE(wValue)		((wValue) >> 8)
26 #define HID_GET_REPORT_ID(wValue)		(wValue)
27 
28 #define HID_SUBORDINATE_DESC_NUM		1
29 
30 struct subordinate_info {
31 	uint8_t bDescriptorType;
32 	uint16_t wDescriptorLength;
33 } __packed;
34 
35 /* See HID spec. 6.2 Class-Specific Descriptors */
36 struct hid_descriptor {
37 	uint8_t bLength;
38 	uint8_t bDescriptorType;
39 	uint16_t bcdHID;
40 	uint8_t bCountryCode;
41 	uint8_t bNumDescriptors;
42 	/* At least report subordinate descriptor is required. */
43 	struct subordinate_info sub[HID_SUBORDINATE_DESC_NUM];
44 } __packed;
45 
46 struct usbd_hid_descriptor {
47 	struct usb_if_descriptor if0;
48 	struct hid_descriptor hid;
49 	struct usb_ep_descriptor in_ep;
50 	struct usb_ep_descriptor hs_in_ep;
51 	struct usb_ep_descriptor out_ep;
52 	struct usb_ep_descriptor hs_out_ep;
53 
54 	struct usb_if_descriptor if0_1;
55 	struct usb_ep_descriptor alt_hs_in_ep;
56 	struct usb_ep_descriptor alt_hs_out_ep;
57 };
58 
59 enum {
60 	HID_DEV_CLASS_ENABLED,
61 };
62 
63 struct hid_device_config {
64 	struct usbd_hid_descriptor *desc;
65 	struct usbd_class_data *c_data;
66 	struct net_buf_pool *pool_out;
67 	struct net_buf_pool *pool_in;
68 	const struct usb_desc_header **fs_desc;
69 	const struct usb_desc_header **hs_desc;
70 };
71 
72 struct hid_device_data {
73 	const struct device *dev;
74 	const struct hid_device_ops *ops;
75 	const uint8_t *rdesc;
76 	size_t rsize;
77 	atomic_t state;
78 	struct k_sem in_sem;
79 	struct k_work output_work;
80 	uint8_t idle_rate;
81 	uint8_t protocol;
82 };
83 
hid_get_in_ep(struct usbd_class_data * const c_data)84 static inline uint8_t hid_get_in_ep(struct usbd_class_data *const c_data)
85 {
86 	const struct device *dev = usbd_class_get_private(c_data);
87 	const struct hid_device_config *dcfg = dev->config;
88 	struct usbd_hid_descriptor *desc = dcfg->desc;
89 
90 	return desc->in_ep.bEndpointAddress;
91 }
92 
hid_get_out_ep(struct usbd_class_data * const c_data)93 static inline uint8_t hid_get_out_ep(struct usbd_class_data *const c_data)
94 {
95 	const struct device *dev = usbd_class_get_private(c_data);
96 	const struct hid_device_config *dcfg = dev->config;
97 	struct usbd_hid_descriptor *desc = dcfg->desc;
98 
99 	return desc->out_ep.bEndpointAddress;
100 }
101 
usbd_hid_request(struct usbd_class_data * const c_data,struct net_buf * const buf,const int err)102 static int usbd_hid_request(struct usbd_class_data *const c_data,
103 			    struct net_buf *const buf, const int err)
104 {
105 	struct usbd_context *uds_ctx = usbd_class_get_ctx(c_data);
106 	const struct device *dev = usbd_class_get_private(c_data);
107 	struct hid_device_data *ddata = dev->data;
108 	const struct hid_device_ops *ops = ddata->ops;
109 	struct udc_buf_info *bi;
110 
111 	bi = udc_get_buf_info(buf);
112 
113 	if (bi->ep == hid_get_out_ep(c_data)) {
114 		if (ops->output_report != NULL) {
115 			if (err == 0) {
116 				ops->output_report(dev, buf->len, buf->data);
117 			}
118 
119 			k_work_submit(&ddata->output_work);
120 		}
121 	}
122 
123 	if (bi->ep == hid_get_in_ep(c_data)) {
124 		if (ops->input_report_done != NULL) {
125 			ops->input_report_done(dev);
126 		} else {
127 			k_sem_give(&ddata->in_sem);
128 		}
129 	}
130 
131 	return usbd_ep_buf_free(uds_ctx, buf);
132 }
133 
handle_set_idle(const struct device * dev,const struct usb_setup_packet * const setup)134 static int handle_set_idle(const struct device *dev,
135 			   const struct usb_setup_packet *const setup)
136 {
137 	const uint32_t duration = HID_GET_IDLE_DURATION(setup->wValue);
138 	const uint8_t id = HID_GET_IDLE_ID(setup->wValue);
139 	struct hid_device_data *const ddata = dev->data;
140 	const struct hid_device_ops *ops = ddata->ops;
141 
142 	if (id == 0U) {
143 		/* Only the common idle rate is stored. */
144 		ddata->idle_rate = duration;
145 	}
146 
147 	if (ops->set_idle != NULL) {
148 		ops->set_idle(dev, id, duration * 4UL);
149 	} else {
150 		errno = -ENOTSUP;
151 	}
152 
153 	LOG_DBG("Set Idle, Report ID %u Duration %u", id, duration);
154 
155 	return 0;
156 }
157 
handle_get_idle(const struct device * dev,const struct usb_setup_packet * const setup,struct net_buf * const buf)158 static int handle_get_idle(const struct device *dev,
159 			   const struct usb_setup_packet *const setup,
160 			   struct net_buf *const buf)
161 {
162 	const uint8_t id = HID_GET_IDLE_ID(setup->wValue);
163 	struct hid_device_data *const ddata = dev->data;
164 	const struct hid_device_ops *ops = ddata->ops;
165 	uint32_t duration;
166 
167 	if (setup->wLength != 1U) {
168 		errno = -ENOTSUP;
169 		return 0;
170 	}
171 
172 	/*
173 	 * There is no Get Idle callback in the leagacy API, do not issue a
174 	 * protocol error if no callback is provided but ID is 0.
175 	 */
176 	if (id != 0U && ops->get_idle == NULL) {
177 		errno = -ENOTSUP;
178 		return 0;
179 	}
180 
181 	if (id == 0U) {
182 		/* Only the common idle rate is stored. */
183 		duration = ddata->idle_rate;
184 	} else {
185 		duration = ops->get_idle(dev, id) / 4UL;
186 	}
187 
188 	LOG_DBG("Get Idle, Report ID %u Duration %u", id, duration);
189 	net_buf_add_u8(buf, duration);
190 
191 	return 0;
192 }
193 
handle_set_report(const struct device * dev,const struct usb_setup_packet * const setup,const struct net_buf * const buf)194 static int handle_set_report(const struct device *dev,
195 			     const struct usb_setup_packet *const setup,
196 			     const struct net_buf *const buf)
197 {
198 	const uint8_t type = HID_GET_REPORT_TYPE(setup->wValue);
199 	const uint8_t id = HID_GET_REPORT_ID(setup->wValue);
200 	struct hid_device_data *const ddata = dev->data;
201 	const struct hid_device_ops *ops = ddata->ops;
202 
203 	if (ops->set_report == NULL) {
204 		errno = -ENOTSUP;
205 		LOG_DBG("Set Report not supported");
206 		return 0;
207 	}
208 
209 	switch (type) {
210 	case HID_REPORT_TYPE_INPUT:
211 		LOG_DBG("Set Report, Input Report ID %u", id);
212 		errno = ops->set_report(dev, type, id, buf->len, buf->data);
213 		break;
214 	case HID_REPORT_TYPE_OUTPUT:
215 		LOG_DBG("Set Report, Output Report ID %u", id);
216 		errno = ops->set_report(dev, type, id, buf->len, buf->data);
217 		break;
218 	case HID_REPORT_TYPE_FEATURE:
219 		LOG_DBG("Set Report, Feature Report ID %u", id);
220 		errno = ops->set_report(dev, type, id, buf->len, buf->data);
221 		break;
222 	default:
223 		errno = -ENOTSUP;
224 		break;
225 	}
226 
227 	return 0;
228 }
229 
handle_get_report(const struct device * dev,const struct usb_setup_packet * const setup,struct net_buf * const buf)230 static int handle_get_report(const struct device *dev,
231 			     const struct usb_setup_packet *const setup,
232 			     struct net_buf *const buf)
233 {
234 	const uint8_t type = HID_GET_REPORT_TYPE(setup->wValue);
235 	const uint8_t id = HID_GET_REPORT_ID(setup->wValue);
236 	struct hid_device_data *const ddata = dev->data;
237 	const struct hid_device_ops *ops = ddata->ops;
238 	const size_t size = setup->wLength;
239 	int ret = 0;
240 
241 	switch (type) {
242 	case HID_REPORT_TYPE_INPUT:
243 		LOG_DBG("Get Report, Input Report ID %u", id);
244 		ret = ops->get_report(dev, type, id, size, buf->data);
245 		break;
246 	case HID_REPORT_TYPE_OUTPUT:
247 		LOG_DBG("Get Report, Output Report ID %u", id);
248 		ret = ops->get_report(dev, type, id, size, buf->data);
249 		break;
250 	case HID_REPORT_TYPE_FEATURE:
251 		LOG_DBG("Get Report, Feature Report ID %u", id);
252 		ret = ops->get_report(dev, type, id, size, buf->data);
253 		break;
254 	default:
255 		errno = -ENOTSUP;
256 		break;
257 	}
258 
259 	if (ret > 0) {
260 		__ASSERT(ret <= net_buf_tailroom(buf),
261 			 "Buffer overflow in the HID driver");
262 		net_buf_add(buf, MIN(net_buf_tailroom(buf), ret));
263 	} else {
264 		errno = ret ? ret : -ENOTSUP;
265 	}
266 
267 	return 0;
268 }
269 
handle_set_protocol(const struct device * dev,const struct usb_setup_packet * const setup)270 static int handle_set_protocol(const struct device *dev,
271 			       const struct usb_setup_packet *const setup)
272 {
273 	const struct hid_device_config *dcfg = dev->config;
274 	struct hid_device_data *const ddata = dev->data;
275 	struct usbd_hid_descriptor *const desc = dcfg->desc;
276 	const struct hid_device_ops *const ops = ddata->ops;
277 	const uint16_t protocol = setup->wValue;
278 
279 	if (protocol > HID_PROTOCOL_REPORT) {
280 		/* Can only be 0 (Boot Protocol) or 1 (Report Protocol). */
281 		errno = -ENOTSUP;
282 		return 0;
283 	}
284 
285 	if (desc->if0.bInterfaceSubClass == 0) {
286 		/*
287 		 * The device does not support the boot protocol and we will
288 		 * not notify it.
289 		 */
290 		errno = -ENOTSUP;
291 		return 0;
292 	}
293 
294 	LOG_DBG("Set Protocol: %s", protocol ? "Report" : "Boot");
295 
296 	if (ddata->protocol != protocol) {
297 		ddata->protocol = protocol;
298 
299 		if (ops->set_protocol) {
300 			ops->set_protocol(dev, protocol);
301 		}
302 	}
303 
304 	return 0;
305 }
306 
handle_get_protocol(const struct device * dev,const struct usb_setup_packet * const setup,struct net_buf * const buf)307 static int handle_get_protocol(const struct device *dev,
308 			       const struct usb_setup_packet *const setup,
309 			       struct net_buf *const buf)
310 {
311 	const struct hid_device_config *dcfg = dev->config;
312 	struct hid_device_data *const ddata = dev->data;
313 	struct usbd_hid_descriptor *const desc = dcfg->desc;
314 
315 	if (setup->wValue != 0 || setup->wLength != 1) {
316 		errno = -ENOTSUP;
317 		return 0;
318 	}
319 
320 	if (desc->if0.bInterfaceSubClass == 0) {
321 		/* The device does not support the boot protocol */
322 		errno = -ENOTSUP;
323 		return 0;
324 	}
325 
326 	LOG_DBG("Get Protocol: %s", ddata->protocol ? "Report" : "Boot");
327 	net_buf_add_u8(buf, ddata->protocol);
328 
329 	return 0;
330 }
331 
handle_get_descriptor(const struct device * dev,const struct usb_setup_packet * const setup,struct net_buf * const buf)332 static int handle_get_descriptor(const struct device *dev,
333 				 const struct usb_setup_packet *const setup,
334 				 struct net_buf *const buf)
335 {
336 	const struct hid_device_config *dcfg = dev->config;
337 	struct hid_device_data *const ddata = dev->data;
338 	uint8_t desc_type = USB_GET_DESCRIPTOR_TYPE(setup->wValue);
339 	uint8_t desc_idx = USB_GET_DESCRIPTOR_INDEX(setup->wValue);
340 	struct usbd_hid_descriptor *const desc = dcfg->desc;
341 
342 	switch (desc_type) {
343 	case USB_DESC_HID_REPORT:
344 		LOG_DBG("Get descriptor report");
345 		net_buf_add_mem(buf, ddata->rdesc, MIN(ddata->rsize, setup->wLength));
346 		break;
347 	case USB_DESC_HID:
348 		LOG_DBG("Get descriptor HID");
349 		net_buf_add_mem(buf, &desc->hid, MIN(desc->hid.bLength, setup->wLength));
350 		break;
351 	case USB_DESC_HID_PHYSICAL:
352 		LOG_DBG("Get descriptor physical %u", desc_idx);
353 		errno = -ENOTSUP;
354 		break;
355 	default:
356 		errno = -ENOTSUP;
357 		break;
358 	}
359 
360 	return 0;
361 }
362 
usbd_hid_ctd(struct usbd_class_data * const c_data,const struct usb_setup_packet * const setup,const struct net_buf * const buf)363 static int usbd_hid_ctd(struct usbd_class_data *const c_data,
364 			const struct usb_setup_packet *const setup,
365 			const struct net_buf *const buf)
366 {
367 	const struct device *dev = usbd_class_get_private(c_data);
368 	int ret = 0;
369 
370 	switch (setup->bRequest) {
371 	case USB_HID_SET_IDLE:
372 		ret = handle_set_idle(dev, setup);
373 		break;
374 	case USB_HID_SET_REPORT:
375 		ret = handle_set_report(dev, setup, buf);
376 		break;
377 	case USB_HID_SET_PROTOCOL:
378 		ret = handle_set_protocol(dev, setup);
379 		break;
380 	default:
381 		errno = -ENOTSUP;
382 		break;
383 	}
384 
385 	return ret;
386 }
387 
usbd_hid_cth(struct usbd_class_data * const c_data,const struct usb_setup_packet * const setup,struct net_buf * const buf)388 static int usbd_hid_cth(struct usbd_class_data *const c_data,
389 			const struct usb_setup_packet *const setup,
390 			struct net_buf *const buf)
391 {
392 	const struct device *dev = usbd_class_get_private(c_data);
393 	int ret = 0;
394 
395 	switch (setup->bRequest) {
396 	case USB_HID_GET_IDLE:
397 		ret = handle_get_idle(dev, setup, buf);
398 		break;
399 	case USB_HID_GET_REPORT:
400 		ret = handle_get_report(dev, setup, buf);
401 		break;
402 	case USB_HID_GET_PROTOCOL:
403 		ret = handle_get_protocol(dev, setup, buf);
404 		break;
405 	case USB_SREQ_GET_DESCRIPTOR:
406 		ret = handle_get_descriptor(dev, setup, buf);
407 		break;
408 	default:
409 		errno = -ENOTSUP;
410 		break;
411 	}
412 
413 	return ret;
414 }
415 
usbd_hid_sof(struct usbd_class_data * const c_data)416 static void usbd_hid_sof(struct usbd_class_data *const c_data)
417 {
418 	const struct device *dev = usbd_class_get_private(c_data);
419 	struct hid_device_data *ddata = dev->data;
420 	const struct hid_device_ops *const ops = ddata->ops;
421 
422 	if (ops->sof) {
423 		ops->sof(dev);
424 	}
425 }
426 
usbd_hid_enable(struct usbd_class_data * const c_data)427 static void usbd_hid_enable(struct usbd_class_data *const c_data)
428 {
429 	const struct device *dev = usbd_class_get_private(c_data);
430 	const struct hid_device_config *dcfg = dev->config;
431 	struct hid_device_data *ddata = dev->data;
432 	const struct hid_device_ops *const ops = ddata->ops;
433 	struct usbd_hid_descriptor *const desc = dcfg->desc;
434 
435 	atomic_set_bit(&ddata->state, HID_DEV_CLASS_ENABLED);
436 	ddata->protocol = HID_PROTOCOL_REPORT;
437 	if (ops->iface_ready) {
438 		ops->iface_ready(dev, true);
439 	}
440 
441 	if (desc->out_ep.bLength != 0U) {
442 		k_work_submit(&ddata->output_work);
443 	}
444 
445 	LOG_DBG("Configuration enabled");
446 }
447 
usbd_hid_disable(struct usbd_class_data * const c_data)448 static void usbd_hid_disable(struct usbd_class_data *const c_data)
449 {
450 	const struct device *dev = usbd_class_get_private(c_data);
451 	struct hid_device_data *ddata = dev->data;
452 	const struct hid_device_ops *const ops = ddata->ops;
453 
454 	atomic_clear_bit(&ddata->state, HID_DEV_CLASS_ENABLED);
455 	if (ops->iface_ready) {
456 		ops->iface_ready(dev, false);
457 	}
458 
459 	LOG_DBG("Configuration disabled");
460 }
461 
usbd_hid_suspended(struct usbd_class_data * const c_data)462 static void usbd_hid_suspended(struct usbd_class_data *const c_data)
463 {
464 	const struct device *dev = usbd_class_get_private(c_data);
465 
466 	LOG_DBG("Configuration suspended, device %s", dev->name);
467 }
468 
usbd_hid_resumed(struct usbd_class_data * const c_data)469 static void usbd_hid_resumed(struct usbd_class_data *const c_data)
470 {
471 	const struct device *dev = usbd_class_get_private(c_data);
472 
473 	LOG_DBG("Configuration resumed, device %s", dev->name);
474 }
475 
usbd_hid_get_desc(struct usbd_class_data * const c_data,const enum usbd_speed speed)476 static void *usbd_hid_get_desc(struct usbd_class_data *const c_data,
477 			       const enum usbd_speed speed)
478 {
479 	const struct device *dev = usbd_class_get_private(c_data);
480 	const struct hid_device_config *dcfg = dev->config;
481 
482 	if (speed == USBD_SPEED_HS) {
483 		return dcfg->hs_desc;
484 	}
485 
486 	return dcfg->fs_desc;
487 }
488 
usbd_hid_init(struct usbd_class_data * const c_data)489 static int usbd_hid_init(struct usbd_class_data *const c_data)
490 {
491 	LOG_DBG("HID class %s init", c_data->name);
492 
493 	return 0;
494 }
495 
usbd_hid_shutdown(struct usbd_class_data * const c_data)496 static void usbd_hid_shutdown(struct usbd_class_data *const c_data)
497 {
498 	LOG_DBG("HID class %s shutdown", c_data->name);
499 }
500 
hid_buf_alloc_ext(const struct hid_device_config * const dcfg,const uint16_t size,void * const data,const uint8_t ep)501 static struct net_buf *hid_buf_alloc_ext(const struct hid_device_config *const dcfg,
502 					 const uint16_t size, void *const data,
503 					 const uint8_t ep)
504 {
505 	struct net_buf *buf = NULL;
506 	struct udc_buf_info *bi;
507 
508 	__ASSERT(IS_UDC_ALIGNED(data), "Application provided unaligned buffer");
509 
510 	buf = net_buf_alloc_with_data(dcfg->pool_in, data, size, K_NO_WAIT);
511 	if (!buf) {
512 		return NULL;
513 	}
514 
515 	bi = udc_get_buf_info(buf);
516 	bi->ep = ep;
517 
518 	return buf;
519 }
520 
hid_buf_alloc(const struct hid_device_config * const dcfg,const uint8_t ep)521 static struct net_buf *hid_buf_alloc(const struct hid_device_config *const dcfg,
522 				     const uint8_t ep)
523 {
524 	struct net_buf *buf = NULL;
525 	struct udc_buf_info *bi;
526 
527 	buf = net_buf_alloc(dcfg->pool_out, K_NO_WAIT);
528 	if (!buf) {
529 		return NULL;
530 	}
531 
532 	bi = udc_get_buf_info(buf);
533 	bi->ep = ep;
534 
535 	return buf;
536 }
537 
hid_dev_output_handler(struct k_work * work)538 static void hid_dev_output_handler(struct k_work *work)
539 {
540 	struct hid_device_data *ddata = CONTAINER_OF(work,
541 						     struct hid_device_data,
542 						     output_work);
543 	const struct device *dev = ddata->dev;
544 	const struct hid_device_config *dcfg = dev->config;
545 	struct usbd_class_data *c_data = dcfg->c_data;
546 	struct net_buf *buf;
547 
548 	if (!atomic_test_bit(&ddata->state, HID_DEV_CLASS_ENABLED)) {
549 		return;
550 	}
551 
552 	buf = hid_buf_alloc(dcfg, hid_get_out_ep(c_data));
553 	if (buf == NULL) {
554 		LOG_ERR("Failed to allocate buffer");
555 		return;
556 	}
557 
558 	if (usbd_ep_enqueue(c_data, buf)) {
559 		net_buf_unref(buf);
560 		LOG_ERR("Failed to enqueue buffer");
561 	}
562 }
563 
hid_dev_submit_report(const struct device * dev,const uint16_t size,const uint8_t * const report)564 static int hid_dev_submit_report(const struct device *dev,
565 				 const uint16_t size, const uint8_t *const report)
566 {
567 	const struct hid_device_config *dcfg = dev->config;
568 	struct hid_device_data *const ddata = dev->data;
569 	const struct hid_device_ops *ops = ddata->ops;
570 	struct usbd_class_data *c_data = dcfg->c_data;
571 	struct net_buf *buf;
572 	int ret;
573 
574 	__ASSERT(IS_ALIGNED(report, sizeof(void *)), "Report buffer is not aligned");
575 
576 	if (!atomic_test_bit(&ddata->state, HID_DEV_CLASS_ENABLED)) {
577 		return -EACCES;
578 	}
579 
580 	buf = hid_buf_alloc_ext(dcfg, size, (void *)report, hid_get_in_ep(c_data));
581 	if (buf == NULL) {
582 		LOG_ERR("Failed to allocate net_buf");
583 		return -ENOMEM;
584 	}
585 
586 	ret = usbd_ep_enqueue(c_data, buf);
587 	if (ret) {
588 		net_buf_unref(buf);
589 		return ret;
590 	}
591 
592 	if (ops->input_report_done == NULL) {
593 		k_sem_take(&ddata->in_sem, K_FOREVER);
594 	}
595 
596 	return 0;
597 }
598 
hid_dev_register(const struct device * dev,const uint8_t * const rdesc,const uint16_t rsize,const struct hid_device_ops * const ops)599 static int hid_dev_register(const struct device *dev,
600 			    const uint8_t *const rdesc, const uint16_t rsize,
601 			    const struct hid_device_ops *const ops)
602 {
603 	const struct hid_device_config *dcfg = dev->config;
604 	struct hid_device_data *const ddata = dev->data;
605 	struct usbd_hid_descriptor *const desc = dcfg->desc;
606 
607 	if (atomic_test_bit(&ddata->state, HID_DEV_CLASS_ENABLED)) {
608 		return -EALREADY;
609 	}
610 
611 	/* Get Report is required for all HID device types. */
612 	if (ops == NULL || ops->get_report == NULL) {
613 		LOG_ERR("get_report callback is missing");
614 		return -EINVAL;
615 	}
616 
617 	/* Set Report is required when an output report is declared. */
618 	if (desc->out_ep.bLength && ops->set_report == NULL) {
619 		LOG_ERR("set_report callback is missing");
620 		return -EINVAL;
621 	}
622 
623 	/*
624 	 * Get/Set Protocol are required when device supports boot interface.
625 	 * Get Protocol is handled internally, no callback is required.
626 	 */
627 	if (desc->if0.bInterfaceSubClass && ops->set_protocol == NULL) {
628 		LOG_ERR("set_protocol callback is missing");
629 		return -EINVAL;
630 	}
631 
632 	ddata->rdesc = rdesc;
633 	ddata->rsize = rsize;
634 	ddata->ops = ops;
635 
636 	sys_put_le16(ddata->rsize, (uint8_t *)&(desc->hid.sub[0].wDescriptorLength));
637 
638 	return 0;
639 }
640 
hid_device_init(const struct device * dev)641 static int hid_device_init(const struct device *dev)
642 {
643 	struct hid_device_data *const ddata = dev->data;
644 
645 	ddata->dev = dev;
646 
647 	k_sem_init(&ddata->in_sem, 0, 1);
648 
649 	k_work_init(&ddata->output_work, hid_dev_output_handler);
650 	LOG_DBG("HID device %s init", dev->name);
651 
652 	return 0;
653 }
654 
655 struct usbd_class_api usbd_hid_api = {
656 	.request = usbd_hid_request,
657 	.update = NULL,
658 	.sof = usbd_hid_sof,
659 	.enable = usbd_hid_enable,
660 	.disable = usbd_hid_disable,
661 	.suspended = usbd_hid_suspended,
662 	.resumed = usbd_hid_resumed,
663 	.control_to_dev = usbd_hid_ctd,
664 	.control_to_host = usbd_hid_cth,
665 	.get_desc = usbd_hid_get_desc,
666 	.init = usbd_hid_init,
667 	.shutdown = usbd_hid_shutdown,
668 };
669 
670 static const struct hid_device_driver_api hid_device_api = {
671 	.submit_report = hid_dev_submit_report,
672 	.dev_register = hid_dev_register,
673 };
674 
675 #include "usbd_hid_macros.h"
676 
677 #define USBD_HID_INTERFACE_SIMPLE_DEFINE(n)					\
678 	static struct usbd_hid_descriptor hid_desc_##n = {			\
679 		.if0 = HID_INTERFACE_DEFINE(n, 0),				\
680 		.hid = HID_DESCRIPTOR_DEFINE(n),				\
681 		.in_ep = HID_IN_EP_DEFINE(n, false, true),			\
682 		.hs_in_ep = HID_IN_EP_DEFINE(n, true, true),			\
683 		.out_ep = HID_OUT_EP_DEFINE_OR_ZERO(n, false, true),		\
684 		.hs_out_ep = HID_OUT_EP_DEFINE_OR_ZERO(n, true, true),		\
685 	};									\
686 										\
687 	const static struct usb_desc_header *hid_fs_desc_##n[] = {		\
688 		(struct usb_desc_header *) &hid_desc_##n.if0,			\
689 		(struct usb_desc_header *) &hid_desc_##n.hid,			\
690 		(struct usb_desc_header *) &hid_desc_##n.in_ep,			\
691 		(struct usb_desc_header *) &hid_desc_##n.out_ep,		\
692 		NULL,								\
693 	};									\
694 										\
695 	const static struct usb_desc_header *hid_hs_desc_##n[] = {		\
696 		(struct usb_desc_header *) &hid_desc_##n.if0,			\
697 		(struct usb_desc_header *) &hid_desc_##n.hid,			\
698 		(struct usb_desc_header *) &hid_desc_##n.hs_in_ep,		\
699 		(struct usb_desc_header *) &hid_desc_##n.hs_out_ep,		\
700 		NULL,								\
701 	}
702 
703 #define USBD_HID_INTERFACE_ALTERNATE_DEFINE(n)					\
704 	static struct usbd_hid_descriptor hid_desc_##n = {			\
705 		.if0 = HID_INTERFACE_DEFINE(n, 0),				\
706 		.hid = HID_DESCRIPTOR_DEFINE(n),				\
707 		.in_ep = HID_IN_EP_DEFINE(n, false, false),			\
708 		.hs_in_ep = HID_IN_EP_DEFINE(n, true, false),			\
709 		.out_ep = HID_OUT_EP_DEFINE_OR_ZERO(n, false, false),		\
710 		.hs_out_ep = HID_OUT_EP_DEFINE_OR_ZERO(n, true, false),		\
711 		.if0_1 = HID_INTERFACE_DEFINE(n, 1),				\
712 		.alt_hs_in_ep = HID_IN_EP_DEFINE(n, true, true),		\
713 		.alt_hs_out_ep = HID_OUT_EP_DEFINE_OR_ZERO(n, true, true),	\
714 	};									\
715 										\
716 	const static struct usb_desc_header *hid_fs_desc_##n[] = {		\
717 		(struct usb_desc_header *) &hid_desc_##n.if0,			\
718 		(struct usb_desc_header *) &hid_desc_##n.hid,			\
719 		(struct usb_desc_header *) &hid_desc_##n.in_ep,			\
720 		(struct usb_desc_header *) &hid_desc_##n.out_ep,		\
721 		NULL,								\
722 	};									\
723 										\
724 	const static struct usb_desc_header *hid_hs_desc_##n[] = {		\
725 		(struct usb_desc_header *) &hid_desc_##n.if0,			\
726 		(struct usb_desc_header *) &hid_desc_##n.hid,			\
727 		(struct usb_desc_header *) &hid_desc_##n.hs_in_ep,		\
728 	COND_CODE_1(DT_INST_NODE_HAS_PROP(n, out_report_size),			\
729 		((struct usb_desc_header *) &hid_desc_##n.hs_out_ep,), ())	\
730 		(struct usb_desc_header *)&hid_desc_##n.if0_1,			\
731 		(struct usb_desc_header *) &hid_desc_##n.hid,			\
732 		(struct usb_desc_header *) &hid_desc_##n.alt_hs_in_ep,		\
733 	COND_CODE_1(DT_INST_NODE_HAS_PROP(n, out_report_size),			\
734 		((struct usb_desc_header *) &hid_desc_##n.alt_hs_out_ep,), ())	\
735 		NULL,								\
736 	}
737 
738 #define USBD_HID_INTERFACE_DEFINE(n)						\
739 	COND_CODE_1(HID_ALL_MPS_LESS_65(n),					\
740 		    (USBD_HID_INTERFACE_SIMPLE_DEFINE(n)),			\
741 		    (USBD_HID_INTERFACE_ALTERNATE_DEFINE(n)))
742 
743 #define USBD_HID_INSTANCE_DEFINE(n)						\
744 	HID_VERIFY_REPORT_SIZES(n);						\
745 										\
746 	NET_BUF_POOL_DEFINE(hid_buf_pool_in_##n,				\
747 			    CONFIG_USBD_HID_IN_BUF_COUNT, 0,			\
748 			    sizeof(struct udc_buf_info), NULL);			\
749 										\
750 	HID_OUT_POOL_DEFINE(n);							\
751 	USBD_HID_INTERFACE_DEFINE(n);						\
752 										\
753 	USBD_DEFINE_CLASS(hid_##n,						\
754 			  &usbd_hid_api,					\
755 			  (void *)DEVICE_DT_GET(DT_DRV_INST(n)), NULL);		\
756 										\
757 	static const struct hid_device_config hid_config_##n = {		\
758 		.desc = &hid_desc_##n,						\
759 		.c_data = &hid_##n,						\
760 		.pool_in = &hid_buf_pool_in_##n,				\
761 		.pool_out = HID_OUT_POOL_ADDR(n),				\
762 		.fs_desc = hid_fs_desc_##n,					\
763 		.hs_desc = hid_hs_desc_##n,					\
764 	};									\
765 										\
766 	static struct hid_device_data hid_data_##n;				\
767 										\
768 	DEVICE_DT_INST_DEFINE(n, hid_device_init, NULL,				\
769 		&hid_data_##n, &hid_config_##n,					\
770 		POST_KERNEL, CONFIG_USBD_HID_INIT_PRIORITY,			\
771 		&hid_device_api);
772 
773 DT_INST_FOREACH_STATUS_OKAY(USBD_HID_INSTANCE_DEFINE);
774