/* * 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 /** * @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 Feature endpoint halt update handler * * Called when an endpoint of the interface belonging * to the instance has been halted or cleared by either * a Set Feature Endpoint Halt or Clear Feature Endpoint Halt request. * * The execution of the handler must not block. * * @param[in] dev Pointer to device struct of the class instance * @param[in] ep Endpoint * @param[in] halted True if the endpoint has been halted and false if * the endpoint halt has been cleared by a Feature request. */ static inline void usbd_class_feature_halt(struct usbd_class_node *const node, const uint8_t ep, const bool halted) { const struct usbd_class_api *api = node->api; if (api->feature_halt != NULL) { api->feature_halt(node, ep, halted); } } /** * @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 */