Skip to content

Commit cd17620

Browse files
committed
usbh: billboard:
USB host Billboard class implementation at PoC stage according to SoW Block 2 (REQ-VND-USB-003) Signed-off-by: Marian Cingel <marian.c@embedd.it> Signed-off-by: Valentyn Gololobov <val@embedd.it>
1 parent f3ec01a commit cd17620

17 files changed

Lines changed: 1448 additions & 0 deletions

File tree

include/zephyr/usb/bos.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,18 @@ enum usb_bos_capability_types {
4646
USB_BOS_CAPABILITY_EXTENSION = 0x02,
4747
/** Platform-specific capability (e.g., WebUSB, MS OS). */
4848
USB_BOS_CAPABILITY_PLATFORM = 0x05,
49+
/** Billboard capability */
50+
USB_BOS_CAPABILITY_BILLBOARD = 0x0D,
51+
/** Billboard Ex capability */
52+
USB_BOS_CAPABILITY_BILLBOARD_EX = 0x0F,
4953
};
5054

55+
struct usb_bos_capability_header {
56+
uint8_t bLength;
57+
uint8_t bDescriptorType;
58+
uint8_t bDevCapabilityType;
59+
} __packed;
60+
5161
/**
5262
* BOS USB 2.0 extension capability descriptor
5363
*
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright (c) 2026 Renesas Electronics Corporation, Embedd
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/**
8+
* @file
9+
* @brief Device/host common USB Billboard header file
10+
*/
11+
12+
#ifndef ZEPHYR_INCLUDE_USB_CLASS_USB_BILLBOARD_H
13+
#define ZEPHYR_INCLUDE_USB_CLASS_USB_BILLBOARD_H
14+
15+
#include <stdint.h>
16+
#include <zephyr/sys/util.h>
17+
18+
/**
19+
* @brief AUM part of Billboard capability descriptor
20+
*/
21+
struct usb_billboard_aum {
22+
uint16_t wSVID;
23+
uint8_t bAlternateOrUSB4Mode;
24+
uint8_t iAlternateOrUSB4ModeString;
25+
} __packed;
26+
27+
/**
28+
* @brief Billboard capability descriptor with flexible AUM array
29+
*/
30+
struct usb_billboard_capability_descriptor {
31+
uint8_t bLength;
32+
uint8_t bDescriptorType;
33+
uint8_t bDevCapabilityType;
34+
uint8_t iAdditionalInfoURL;
35+
uint8_t bNumberOfAlternateOrUSB4Modes;
36+
uint8_t bPreferredAlternateOrUSB4Mode;
37+
uint16_t VCONNPower;
38+
uint8_t bmConfigured[32];
39+
uint16_t bcdVersion;
40+
uint8_t bAdditionalFailureInfo;
41+
uint8_t bReserved;
42+
FLEXIBLE_ARRAY_DECLARE(struct usb_billboard_aum, aum);
43+
} __packed;
44+
45+
/**
46+
* @brief AUM capability descriptor
47+
*/
48+
struct usb_aum_capability_descriptor {
49+
uint8_t bLength;
50+
uint8_t bDescriptorType;
51+
uint8_t bDevCapabilityType;
52+
uint8_t bIndex;
53+
uint32_t dwAlternateModeVdo;
54+
} __packed;
55+
56+
#define USB_BILLBOARD_SUBCLASS 0x00
57+
#define USB_BILLBOARD_RUNTIME 0x00
58+
59+
enum usb_billboard_vconn_needed {
60+
USB_BILLBOARD_VCONN_NEEDED_1W = 0,
61+
USB_BILLBOARD_VCONN_NEEDED_1W5 = 1,
62+
USB_BILLBOARD_VCONN_NEEDED_2W = 2,
63+
USB_BILLBOARD_VCONN_NEEDED_3W = 3,
64+
USB_BILLBOARD_VCONN_NEEDED_4W = 4,
65+
USB_BILLBOARD_VCONN_NEEDED_5W = 5,
66+
USB_BILLBOARD_VCONN_NEEDED_6W = 6,
67+
USB_BILLBOARD_VCONN_NEEDED_RESERVED = 7
68+
};
69+
70+
#define USB_BILLBOARD_VCONN_GET_NEEDED(vconn_field) ((vconn_field) & 0x7)
71+
72+
#define USB_BILLBOARD_VCONN_NOT_NEEDED_MASK (1U << 15)
73+
#define USBBILLBOARD__VCONN_NOT_NEEDED(vconn_field) \
74+
(!!((vconn_field) & (USB_BILLBOARD_VCONN_NOT_NEEDED_MASK)))
75+
76+
enum usb_billboard_aum_state {
77+
USB_BILLBOARD_AUM_STATE_ERROR = 0,
78+
USB_BILLBOARD_AUM_STATE_NOT_ATTEMPTED = 1,
79+
USB_BILLBOARD_AUM_STATE_NOT_ATTEMPTED_FAILED = 2,
80+
USB_BILLBOARD_AUM_STATE_SUCCESSFUL = 3
81+
};
82+
83+
#define USB_BILLBOARD_GET_AUM_INDEX(alt_idx) ((alt_idx) / 4)
84+
#define USB_BILLBOARD_GET_AUM_BITPOS(aum_elem, alt_idx) \
85+
(((aum_elem) >> (((alt_idx) % 4) * 2)) & 0x3)
86+
#define USB_BILLBOARD_GET_AUM(bmConfigured, alt_idx) \
87+
USB_BILLBOARD_GET_AUM_BITPOS((bmConfigured)[USB_BILLBOARD_GET_AUM_INDEX(alt_idx)], alt_idx)
88+
89+
#endif
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
/*
2+
* Copyright (c) 2026 Renesas Electronics Corporation, Embedd
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_INCLUDE_USB_CLASS_USBH_BILLBOARD_H_
8+
#define ZEPHYR_INCLUDE_USB_CLASS_USBH_BILLBOARD_H_
9+
10+
#include <zephyr/device.h>
11+
#include <zephyr/syscall.h>
12+
#include <zephyr/usb/class/usb_billboard.h>
13+
#include <zephyr/usb/bos.h>
14+
15+
#ifdef __cplusplus
16+
extern "C" {
17+
#endif
18+
19+
/**
20+
* @brief App callback to handle parsed capabilities descriptors
21+
*
22+
* @param cb_arg Pointer to callback specific context structure
23+
* @param cap_header Pointer to capability
24+
*
25+
*/
26+
typedef void (*usbh_billboard_cb_t)(void *cb_arg, struct usb_bos_capability_header *cap_header);
27+
28+
/**
29+
* @brief Fetches BOS and parse billboard capabilities descriptors
30+
*
31+
* @param dev Pointer to the device
32+
* @param billboard_cb Application callback
33+
* @param cb_arg Pointer to callback specific context structure
34+
*
35+
* @return 0 on success, negative errno value on failure.
36+
*/
37+
typedef int (*usbh_billboard_fetch_and_parse_t)(struct device const *dev,
38+
usbh_billboard_cb_t billboard_cb, void *cb_arg);
39+
40+
/**
41+
* @brief Fetches string descriptors
42+
*
43+
* @param dev Pointer to the device
44+
* @param str_idx String descriptor index
45+
* @param str_desc Output argument, double pointer to string descriptor
46+
*
47+
* @return 0 on success, negative errno value on failure.
48+
*/
49+
typedef int (*usbh_billboard_fetch_string_t)(struct device const *dev, uint8_t str_idx,
50+
struct usb_string_descriptor **str_desc);
51+
52+
/**
53+
* @brief Fetches the supported languages from the device
54+
*
55+
* @param dev Pointer to the device
56+
* @param str_desc Output argument, double pointer to string descriptor
57+
*
58+
* @return 0 on success, negative errno value on failure.
59+
*/
60+
typedef int (*usbh_billboard_fetch_langs_t)(struct device const *dev,
61+
struct usb_string_descriptor **str_desc);
62+
63+
/**
64+
* @brief Changes the language used for fetching string descriptors
65+
*
66+
* @param dev Pointer to the device
67+
* @param lang_code Language code
68+
*
69+
* @return 0 on success, negative errno value on failure.
70+
*/
71+
typedef int (*usbh_billboard_use_lang_t)(struct device const *dev, uint16_t lang_code);
72+
73+
__subsystem struct usbh_billboard_driver_api {
74+
/**
75+
* @driver_ops_mandatory @copybrief usbh_billboard_fetch_and_parse
76+
*/
77+
usbh_billboard_fetch_and_parse_t fetch_and_parse;
78+
/**
79+
* @driver_ops_mandatory @copybrief usbh_billboard_fetch_string_desc
80+
*/
81+
usbh_billboard_fetch_string_t fetch_string;
82+
/**
83+
* @driver_ops_mandatory @copybrief usbh_billboard_fetch_langs_desc
84+
*/
85+
usbh_billboard_fetch_langs_t fetch_langs;
86+
/**
87+
* @driver_ops_mandatory @copybrief usbh_billboard_use_lang
88+
*/
89+
usbh_billboard_use_lang_t use_lang;
90+
};
91+
92+
/**
93+
* @brief Fetches BOS and parse billboard capabilities descriptors
94+
*
95+
* @param dev Pointer to the device
96+
* @param billboard_cb Application callback
97+
* @param cb_arg Pointer to callback specific context structure
98+
*
99+
* @return 0 on success, negative errno value on failure.
100+
*/
101+
__syscall int usbh_billboard_fetch_and_parse(struct device const *dev,
102+
usbh_billboard_cb_t billboard_cb, void *cb_arg);
103+
104+
static inline int z_impl_usbh_billboard_fetch_and_parse(struct device const *dev,
105+
usbh_billboard_cb_t billboard_cb,
106+
void *cb_arg)
107+
{
108+
struct usbh_billboard_driver_api const *api = DEVICE_API_GET(usbh_billboard, dev);
109+
110+
if (api->fetch_and_parse == NULL) {
111+
return -ENOSYS;
112+
}
113+
return api->fetch_and_parse(dev, billboard_cb, cb_arg);
114+
}
115+
116+
/**
117+
* @brief Fetches string descriptors
118+
*
119+
* @param dev Pointer to the device
120+
* @param str_idx String descriptor index
121+
* @param str_desc Output argument, double pointer to string descriptor
122+
*
123+
* @return 0 on success, negative errno value on failure.
124+
*/
125+
__syscall int usbh_billboard_fetch_string_desc(struct device const *dev, uint8_t str_idx,
126+
struct usb_string_descriptor **str_desc);
127+
128+
static inline int z_impl_usbh_billboard_fetch_string_desc(struct device const *dev, uint8_t str_idx,
129+
struct usb_string_descriptor **str_desc)
130+
{
131+
struct usbh_billboard_driver_api const *api = DEVICE_API_GET(usbh_billboard, dev);
132+
133+
if (api->fetch_string == NULL) {
134+
return -ENOSYS;
135+
}
136+
return api->fetch_string(dev, str_idx, str_desc);
137+
}
138+
139+
/**
140+
* @brief Fetches the supported languages from the device
141+
*
142+
* @param dev Pointer to the device
143+
* @param str_desc Output argument, double pointer to string descriptor
144+
*
145+
* @return 0 on success, negative errno value on failure.
146+
*/
147+
__syscall int usbh_billboard_fetch_langs_desc(struct device const *dev,
148+
struct usb_string_descriptor **str_desc);
149+
150+
static inline int z_impl_usbh_billboard_fetch_langs_desc(struct device const *dev,
151+
struct usb_string_descriptor **str_desc)
152+
{
153+
struct usbh_billboard_driver_api const *api = DEVICE_API_GET(usbh_billboard, dev);
154+
155+
if (api->fetch_langs == NULL) {
156+
return -ENOSYS;
157+
}
158+
return api->fetch_langs(dev, str_desc);
159+
}
160+
161+
/**
162+
* @brief Changes the language used for fetching string descriptors
163+
*
164+
* @param dev Pointer to the device
165+
* @param lang_code Language code
166+
*
167+
* @return 0 on success, negative errno value on failure.
168+
*/
169+
__syscall int usbh_billboard_use_lang(struct device const *dev, uint16_t lang_code);
170+
171+
static inline int z_impl_usbh_billboard_use_lang(struct device const *dev, uint16_t lang_code)
172+
{
173+
struct usbh_billboard_driver_api const *api = DEVICE_API_GET(usbh_billboard, dev);
174+
175+
if (api->use_lang == NULL) {
176+
return -ENOSYS;
177+
}
178+
return api->use_lang(dev, lang_code);
179+
}
180+
181+
int usbh_billboard_find_dev(struct usb_device *udev, struct device **dev);
182+
183+
#include <zephyr/syscalls/usbh_billboard.h>
184+
185+
#ifdef __cplusplus
186+
}
187+
#endif
188+
189+
#endif /* ZEPHYR_INCLUDE_USB_CLASS_USBH_BILLBOARD_H_ */

include/zephyr/usb/usb_ch9.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,14 +503,40 @@ struct usb_association_descriptor {
503503
#define USB_BCC_CDC_CONTROL 0x02
504504
/** HID device class. */
505505
#define USB_BCC_HID 0x03
506+
/** Physical device class */
507+
#define USB_BCC_PHYSICAL 0x05
508+
/** Image device class */
509+
#define USB_BCC_IMAGE 0x06
510+
/** Printer device class */
511+
#define USB_BCC_PRINTER 0x07
506512
/** Mass storage device class. */
507513
#define USB_BCC_MASS_STORAGE 0x08
514+
/** HUB device class. */
515+
#define USB_BCC_HUB 0x09
508516
/** CDC data device class. */
509517
#define USB_BCC_CDC_DATA 0x0A
518+
/** Smart card device class. */
519+
#define USB_BCC_SMART_CARD 0x0B
520+
/** Content security device class. */
521+
#define USB_BCC_SECURITY 0x0D
510522
/** Video device class. */
511523
#define USB_BCC_VIDEO 0x0E
524+
/** Healthcare device class. */
525+
#define USB_BCC_HEALTHCARE 0x0F
526+
/** Audio/Video device class. */
527+
#define USB_BCC_AUDIO_VIDEO 0x10
528+
/** Billboard device class. */
529+
#define USB_BCC_BILLBOARD 0x11
530+
/** USB-C Bridge device class. */
531+
#define USB_BCC_USBC_BRIDGE 0x12
532+
/** USB Bulk display device class. */
533+
#define USB_BCC_BULK_DISPLAY 0x13
512534
/** MCTP device class. */
513535
#define USB_BCC_MCTP 0x14
536+
/** I3C device class. */
537+
#define USB_BCC_I3C 0x3C
538+
/** Diagnostic device class. */
539+
#define USB_BCC_DIAGNOSTIC 0xDC
514540
/** Wireless controller device class. */
515541
#define USB_BCC_WIRELESS_CONTROLLER 0xE0
516542
/** Miscellaneous device class. */
@@ -761,6 +787,34 @@ struct usb_association_descriptor {
761787
((tpl) > 1024) ? ((tpl) % 2 == 0) : \
762788
((tpl) >= 0))
763789

790+
/**
791+
* @brief Simple function to retrieve ASCII c-string from string_descriptor
792+
*
793+
* @param str_desc Pointer to input string descriptor
794+
* @param str_desc Pointer to output c-string
795+
* @param str_desc Max capacity of c-string
796+
*
797+
* @return 0 on success, negative value on error
798+
*/
799+
static ALWAYS_INLINE int strdesc_to_ascii7_string(struct usb_string_descriptor *str_desc,
800+
char *cstr, size_t cstr_len)
801+
{
802+
uint8_t utf16_len, cstr_pos, strdesc_pos;
803+
804+
if ((str_desc == NULL) || (cstr == NULL) || (cstr_len < 2)) {
805+
return -EINVAL;
806+
}
807+
808+
utf16_len = str_desc->bLength;
809+
for (cstr_pos = 0, strdesc_pos = 2; (strdesc_pos < utf16_len) && (cstr_pos + 1 < cstr_len);
810+
strdesc_pos += 2, cstr_pos++) {
811+
cstr[cstr_pos] = ((uint8_t *)str_desc)[strdesc_pos];
812+
}
813+
cstr[cstr_pos] = '\0';
814+
815+
return 0;
816+
}
817+
764818
#ifdef __cplusplus
765819
}
766820
#endif

samples/subsys/usb/shell/prj_host.conf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ CONFIG_USBH_SHELL=y
66
CONFIG_LOG=y
77
CONFIG_USBH_LOG_LEVEL_WRN=y
88
CONFIG_UHC_DRIVER_LOG_LEVEL_WRN=y
9+
10+
CONFIG_USBH_BILLBOARD_CLASS=y
11+
CONFIG_USBH_BILLBOARD_LOG_LEVEL_DBG=y

subsys/usb/host/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ zephyr_library_sources_ifdef(
2424
class/usbh_uvc.c
2525
)
2626

27+
zephyr_library_sources_ifdef(
28+
CONFIG_USBH_BILLBOARD_CLASS
29+
class/usbh_billboard.c
30+
)
31+
2732
zephyr_library_sources_ifdef(
2833
CONFIG_USBIP
2934
usbip.c

subsys/usb/host/class/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
# SPDX-License-Identifier: Apache-2.0
33

44
rsource "Kconfig.uvc"
5+
rsource "Kconfig.billboard"
6+

0 commit comments

Comments
 (0)