Browse Source

usb: device_next: Document if callbacks are mandatory

Adds additional documentation to the callbacks of uac2_ops
to describe if/when they are mandatory to register.

Additionally add asserts before calling them to help debugging
if the user did not register the required ones.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
pull/85516/head
Emil Gydesen 5 months ago committed by Benjamin Cabé
parent
commit
72b94f0d05
  1. 8
      include/zephyr/usb/class/usbd_uac2.h
  2. 44
      subsys/usb/device_next/class/usbd_uac2.c

8
include/zephyr/usb/class/usbd_uac2.h

@ -47,6 +47,7 @@ struct uac2_ops { @@ -47,6 +47,7 @@ struct uac2_ops {
* @brief Start of Frame callback
*
* Notifies application about SOF event on the bus.
* This callback is mandatory to register.
*
* @param dev USB Audio 2 device
* @param user_data Opaque user data pointer
@ -56,6 +57,7 @@ struct uac2_ops { @@ -56,6 +57,7 @@ struct uac2_ops {
* @brief Terminal update callback
*
* Notifies application that host has enabled or disabled a terminal.
* This callback is mandatory to register.
*
* @param dev USB Audio 2 device
* @param terminal Terminal ID linked to AudioStreaming interface
@ -73,6 +75,7 @@ struct uac2_ops { @@ -73,6 +75,7 @@ struct uac2_ops {
* AudioStreaming interface. The buffer is owned by USB stack until
* @ref data_recv_cb callback is called. The buffer must be sufficiently
* aligned and otherwise suitable for use by UDC driver.
* This callback is mandatory to register for devices receiving USB audio from the USB host.
*
* @param dev USB Audio 2 device
* @param terminal Input Terminal ID linked to AudioStreaming interface
@ -86,6 +89,7 @@ struct uac2_ops { @@ -86,6 +89,7 @@ struct uac2_ops {
*
* This function releases buffer obtained in @ref get_recv_buf after USB
* has written data to the buffer and/or no longer needs it.
* This callback is mandatory to register for devices receiving USB audio from the USB host.
*
* @param dev USB Audio 2 device
* @param terminal Input Terminal ID linked to AudioStreaming interface
@ -100,6 +104,7 @@ struct uac2_ops { @@ -100,6 +104,7 @@ struct uac2_ops {
*
* This function releases buffer provided in @ref usbd_uac2_send when
* the class no longer needs it.
* This callback is mandatory to register if calling @ref usbd_uac2_send.
*
* @param dev USB Audio 2 device
* @param terminal Output Terminal ID linked to AudioStreaming interface
@ -118,6 +123,9 @@ struct uac2_ops { @@ -118,6 +123,9 @@ struct uac2_ops {
* capable device is operating at Full-Speed (microframes was false),
* the format is Q10.14 stored on 24 least significant bits (i.e. 8 most
* significant bits are ignored).
* This callback is mandatory to register if there is USB Audio Streaming interface linked
* to Input Terminal clocked from asynchronous clock (i.e. clock source without
* sof-synchronized;) and there is no implicit-feedback; on the interface.
*
* @param dev USB Audio 2 device
* @param terminal Input Terminal ID whose feedback should be returned

44
subsys/usb/device_next/class/usbd_uac2.c

@ -4,7 +4,11 @@ @@ -4,7 +4,11 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <stddef.h>
#include <stdint.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/sys/atomic.h>
#include <zephyr/sys/byteorder.h>
@ -209,9 +213,49 @@ static int terminal_to_as_interface(const struct device *dev, uint8_t terminal) @@ -209,9 +213,49 @@ static int terminal_to_as_interface(const struct device *dev, uint8_t terminal)
void usbd_uac2_set_ops(const struct device *dev,
const struct uac2_ops *ops, void *user_data)
{
const struct uac2_cfg *cfg = dev->config;
struct uac2_ctx *ctx = dev->data;
__ASSERT(ops->sof_cb, "SOF callback is mandatory");
__ASSERT(ops->terminal_update_cb, "terminal_update_cb is mandatory");
for (uint8_t i = 0U; i < cfg->num_ifaces; i++) {
const uint16_t ep_idx = cfg->ep_indexes[i];
if (cfg->fb_indexes[i] != 0U) {
__ASSERT(ops->feedback_cb, "feedback_cb is mandatory");
}
if (ep_idx) {
const struct usb_ep_descriptor *desc = NULL;
if (cfg->fs_descriptors != NULL) {
/* If fs_descriptors is non-NULL and ep_idx is non-zero then
* cfg->fs_descriptors[ep_idx] is non-NULL
*/
desc = (const struct usb_ep_descriptor *)
cfg->fs_descriptors[ep_idx];
} else if (cfg->hs_descriptors != NULL) {
/* If hs_descriptors is non-NULL and ep_idx is non-zero then
* cfg->hs_descriptors[ep_idx] is non-NULL
*/
desc = (const struct usb_ep_descriptor *)
cfg->hs_descriptors[ep_idx];
}
if (desc != NULL) {
if (USB_EP_DIR_IS_OUT(desc->bEndpointAddress)) {
__ASSERT(ops->get_recv_buf, "get_recv_buf is mandatory");
__ASSERT(ops->data_recv_cb, "data_recv_cb is mandatory");
}
if (USB_EP_DIR_IS_IN(desc->bEndpointAddress)) {
__ASSERT(ops->buf_release_cb,
"buf_release_cb is mandatory");
}
}
}
}
ctx->ops = ops;
ctx->user_data = user_data;

Loading…
Cancel
Save