Skip to content

Commit 7796de1

Browse files
jfischer-nocarlescufi
authored andcommitted
[nrf fromtree] usb: device_next: hid: allow to set polling period at runtime
Allow to set input or output report polling period at runtime. Signed-off-by: Johann Fischer <[email protected]> (cherry picked from commit bca0ce0)
1 parent b259923 commit 7796de1

File tree

5 files changed

+115
-0
lines changed

5 files changed

+115
-0
lines changed

include/zephyr/usb/class/usbd_hid.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,38 @@ int hid_device_register(const struct device *dev,
212212
int hid_device_submit_report(const struct device *dev,
213213
const uint16_t size, const uint8_t *const report);
214214

215+
/**
216+
* @brief Set input report polling period
217+
*
218+
* Similar to devicetree property in-polling-period-us, but it allows setting
219+
* different polling periods at runtime.
220+
*
221+
* @kconfig_dep{CONFIG_USBD_HID_SET_POLLING_PERIOD}
222+
*
223+
* @param[in] dev Pointer to HID device
224+
* @param[in] period_us Polling period in microseconds
225+
*
226+
* @return 0 on success, negative errno code on failure.
227+
* @retval -ENOTSUP If API is not enabled.
228+
*/
229+
int hid_device_set_in_polling(const struct device *dev, const unsigned int period_us);
230+
231+
/**
232+
* @brief Set output report polling period
233+
*
234+
* Similar to devicetree property out-polling-period-us, but it allows setting
235+
* different polling periods at runtime.
236+
*
237+
* @kconfig_dep{CONFIG_USBD_HID_SET_POLLING_PERIOD}
238+
*
239+
* @param[in] dev Pointer to HID device
240+
* @param[in] period_us Polling period in microseconds
241+
*
242+
* @return 0 on success, negative errno code on failure.
243+
* @retval -ENOTSUP If API is not enabled.
244+
*/
245+
int hid_device_set_out_polling(const struct device *dev, const unsigned int period_us);
246+
215247
/**
216248
* @}
217249
*/

subsys/usb/device_next/class/Kconfig.hid

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ config USBD_HID_INIT_PRIORITY
3030
help
3131
HID device initialization priority
3232

33+
config USBD_HID_SET_POLLING_PERIOD
34+
bool "Allow to set polling period at runtime"
35+
help
36+
Allow to set input or output report polling period at runtime.
37+
3338
module = USBD_HID
3439
module-str = usbd hid
3540
source "subsys/logging/Kconfig.template.log_config"

subsys/usb/device_next/class/usbd_hid.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,56 @@ static int hid_dev_submit_report(const struct device *dev,
632632
return 0;
633633
}
634634

635+
static inline int hid_dev_set_out_polling(const struct device *dev,
636+
const unsigned int period_us)
637+
{
638+
const struct hid_device_config *const dcfg = dev->config;
639+
struct hid_device_data *const ddata = dev->data;
640+
struct usbd_hid_descriptor *const desc = dcfg->desc;
641+
642+
if (atomic_test_bit(&ddata->state, HID_DEV_CLASS_INITIALIZED)) {
643+
return -EBUSY;
644+
}
645+
646+
if (USBD_SUPPORTS_HIGH_SPEED) {
647+
if (desc->hs_out_ep.bLength == 0) {
648+
/* This device does not have output reports. */
649+
return -ENOTSUP;
650+
}
651+
652+
desc->hs_out_ep.bInterval = USB_HS_INT_EP_INTERVAL(period_us);
653+
}
654+
655+
if (desc->out_ep.bLength == 0) {
656+
/* This device does not have output reports. */
657+
return -ENOTSUP;
658+
}
659+
660+
desc->out_ep.bInterval = USB_FS_INT_EP_INTERVAL(period_us);
661+
662+
return 0;
663+
}
664+
665+
static inline int hid_dev_set_in_polling(const struct device *dev,
666+
const unsigned int period_us)
667+
{
668+
const struct hid_device_config *const dcfg = dev->config;
669+
struct hid_device_data *const ddata = dev->data;
670+
struct usbd_hid_descriptor *const desc = dcfg->desc;
671+
672+
if (atomic_test_bit(&ddata->state, HID_DEV_CLASS_INITIALIZED)) {
673+
return -EBUSY;
674+
}
675+
676+
if (USBD_SUPPORTS_HIGH_SPEED) {
677+
desc->hs_in_ep.bInterval = USB_HS_INT_EP_INTERVAL(period_us);
678+
}
679+
680+
desc->in_ep.bInterval = USB_FS_INT_EP_INTERVAL(period_us);
681+
682+
return 0;
683+
}
684+
635685
static int hid_dev_register(const struct device *dev,
636686
const uint8_t *const rdesc, const uint16_t rsize,
637687
const struct hid_device_ops *const ops)
@@ -706,6 +756,10 @@ struct usbd_class_api usbd_hid_api = {
706756
static const struct hid_device_driver_api hid_device_api = {
707757
.submit_report = hid_dev_submit_report,
708758
.dev_register = hid_dev_register,
759+
#if CONFIG_USBD_HID_SET_POLLING_PERIOD
760+
.set_out_polling = hid_dev_set_out_polling,
761+
.set_in_polling = hid_dev_set_in_polling,
762+
#endif
709763
};
710764

711765
#include "usbd_hid_macros.h"

subsys/usb/device_next/class/usbd_hid_api.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,28 @@ int hid_device_register(const struct device *dev,
3434
return api->dev_register(dev, rdesc, rsize, ops);
3535
}
3636

37+
int hid_device_set_in_polling(const struct device *dev, const unsigned int period_us)
38+
{
39+
const struct hid_device_driver_api *const api = dev->api;
40+
41+
if (IS_ENABLED(CONFIG_USBD_HID_SET_POLLING_PERIOD)) {
42+
return api->set_in_polling(dev, period_us);
43+
}
44+
45+
return -ENOTSUP;
46+
}
47+
48+
int hid_device_set_out_polling(const struct device *dev, const unsigned int period_us)
49+
{
50+
const struct hid_device_driver_api *const api = dev->api;
51+
52+
if (IS_ENABLED(CONFIG_USBD_HID_SET_POLLING_PERIOD)) {
53+
return api->set_out_polling(dev, period_us);
54+
}
55+
56+
return -ENOTSUP;
57+
}
58+
3759
/* Legacy HID API wrapper below */
3860

3961
struct legacy_wrapper {

subsys/usb/device_next/class/usbd_hid_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,6 @@ struct hid_device_driver_api {
2020
int (*dev_register)(const struct device *dev,
2121
const uint8_t *const rdesc, const uint16_t rsize,
2222
const struct hid_device_ops *const ops);
23+
int (*set_in_polling)(const struct device *dev, const unsigned int period_us);
24+
int (*set_out_polling)(const struct device *dev, const unsigned int period_us);
2325
};

0 commit comments

Comments
 (0)