blob: f57aa4b8aece68345a2e347f7e1cd101c034a61f [file] [log] [blame]
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief USB device stack class instances API
*
* This file contains the USB device stack class instances API.
*/
#ifndef ZEPHYR_INCLUDE_USBD_CLASS_API_H
#define ZEPHYR_INCLUDE_USBD_CLASS_API_H
#include <zephyr/usb/usbd.h>
/**
* @brief Endpoint request completion event handler
*
* This is the event handler for all endpoint accommodated
* by a class instance.
*
* @param[in] dev Pointer to device struct of the class instance
* @param[in] buf Control Request Data buffer
* @param[in] err Result of the transfer. 0 if the transfer was successful.
*/
static inline int usbd_class_request(struct usbd_class_node *const node,
struct net_buf *const buf,
int err)
{
const struct usbd_class_api *api = node->api;
if (api->request != NULL) {
return api->request(node, buf, err);
}
return -ENOTSUP;
}
/**
* @brief USB control request handler
*
* Common handler for all control request.
* Regardless requests recipient, interface or endpoint,
* the USB device core will identify proper class instance
* and call this handler.
* For the vendor type request USBD_VENDOR_REQ macro must be used
* to identify the class, if more than one class instance is
* present, only the first one will be called.
*
* The execution of the handler must not block.
*
* @param[in] dev Pointer to device struct of the class instance
* @param[in] setup Pointer to USB Setup Packet
* @param[in] buf Control Request Data buffer
*
* @return 0 on success, other values on fail.
*/
static inline int usbd_class_control_to_host(struct usbd_class_node *const node,
struct usb_setup_packet *const setup,
struct net_buf *const buf)
{
const struct usbd_class_api *api = node->api;
if (api->control_to_host != NULL) {
return api->control_to_host(node, setup, buf);
}
errno = -ENOTSUP;
return 0;
}
/**
* @brief USB control request handler
*
* Common handler for all control request.
* Regardless requests recipient, interface or endpoint,
* the USB device core will identify proper class instance
* and call this handler.
* For the vendor type request USBD_VENDOR_REQ macro must be used
* to identify the class, if more than one class instance is
* present, only the first one will be called.
*
* The execution of the handler must not block.
*
* @param[in] dev Pointer to device struct of the class instance
* @param[in] setup Pointer to USB Setup Packet
* @param[in] buf Control Request Data buffer
*
* @return 0 on success, other values on fail.
*/
static inline int usbd_class_control_to_dev(struct usbd_class_node *const node,
struct usb_setup_packet *const setup,
struct net_buf *const buf)
{
const struct usbd_class_api *api = node->api;
if (api->control_to_dev != NULL) {
return api->control_to_dev(node, setup, buf);
}
errno = -ENOTSUP;
return 0;
}
/**
* @brief Configuration update handler
*
* Called when the configuration of the interface belonging
* to the instance has been changed, either because of
* Set Configuration or Set Interface request.
*
* The execution of the handler must not block.
*
* @param[in] dev Pointer to device struct of the class instance
* @param[in] setup Pointer to USB setup packet
*/
static inline void usbd_class_update(struct usbd_class_node *const node,
const uint8_t iface,
const uint8_t alternate)
{
const struct usbd_class_api *api = node->api;
if (api->update != NULL) {
api->update(node, iface, alternate);
}
}
/**
* @brief USB suspended handler
*
* @param[in] dev Pointer to device struct of the class instance
* @param[in] event Power management event
*
* @return 0 on success, other values on fail.
*/
static inline void usbd_class_suspended(struct usbd_class_node *const node)
{
const struct usbd_class_api *api = node->api;
if (api->suspended != NULL) {
api->suspended(node);
}
}
/**
* @brief USB resumed handler
*
* @param[in] dev Pointer to device struct of the class instance
* @param[in] event Power management event
*
* @return 0 on success, other values on fail.
*/
static inline void usbd_class_resumed(struct usbd_class_node *const node)
{
const struct usbd_class_api *api = node->api;
if (api->resumed != NULL) {
api->resumed(node);
}
}
/**
* @brief Class associated configuration activ handler
*
* @note The execution of the handler must not block.
*
* @param[in] dev Pointer to device struct of the class instance
*/
static inline void usbd_class_enable(struct usbd_class_node *const node)
{
const struct usbd_class_api *api = node->api;
if (api->enable != NULL) {
api->enable(node);
}
}
/**
* @brief Class associated configuration shutdown handler
*
* @note The execution of the handler must not block.
*
* @param[in] dev Pointer to device struct of the class instance
*/
static inline void usbd_class_disable(struct usbd_class_node *const node)
{
const struct usbd_class_api *api = node->api;
if (api->disable != NULL) {
api->disable(node);
}
}
/**
* @brief Initialization of the class implementation
*
* This is called for each instance during the initialization phase
* after the interface number and endpoint addresses are assigned
* to the corresponding instance.
* It can be used to initialize class specific descriptors or
* underlying systems.
*
* @note If this call fails the core will terminate stack initialization.
*
* @param[in] dev Pointer to device struct of the class instance
*
* @return 0 on success, other values on fail.
*/
static inline int usbd_class_init(struct usbd_class_node *const node)
{
const struct usbd_class_api *api = node->api;
if (api->init != NULL) {
return api->init(node);
}
return -ENOTSUP;
}
#endif /* ZEPHYR_INCLUDE_USBD_CLASS_API_H */