/*
 *  LPCUSB, an USB device driver for LPC microcontrollers
 *  Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
 *  Copyright (c) 2016 Intel Corporation
 *  Copyright (c) 2020 PHYTEC Messtechnik GmbH
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 * @brief USB device core layer
 *
 * This module handles control transfer handler, standard request handler and
 * USB Interface for customer application.
 *
 * Control transfers handler is normally installed on the
 * endpoint 0 callback.
 *
 * Control transfers can be of the following type:
 * 0 Standard;
 * 1 Class;
 * 2 Vendor;
 * 3 Reserved.
 *
 * A callback can be installed for each of these control transfers using
 * usb_register_request_handler.
 * When an OUT request arrives, data is collected in the data store provided
 * with the usb_register_request_handler call. When the transfer is done, the
 * callback is called.
 * When an IN request arrives, the callback is called immediately to either
 * put the control transfer data in the data store, or to get a pointer to
 * control transfer data. The data is then packetized and sent to the host.
 *
 * Standard request handler handles the 'chapter 9' processing, specifically
 * the standard device requests in table 9-3 from the universal serial bus
 * specification revision 2.0
 */

#include <errno.h>
#include <stddef.h>
#include <zephyr/sys/util.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/init.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/usb/usb_device.h>
#include <usb_descriptor.h>
#include <zephyr/usb/class/usb_audio.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(usb_device, CONFIG_USB_DEVICE_LOG_LEVEL);

#include <zephyr/usb/bos.h>
#include <os_desc.h>
#include "usb_transfer.h"

#define MAX_DESC_HANDLERS           4 /** Device, interface, endpoint, other */

/* general descriptor field offsets */
#define DESC_bLength                0 /** Length offset */
#define DESC_bDescriptorType        1 /** Descriptor type offset */

/* config descriptor field offsets */
#define CONF_DESC_wTotalLength      2 /** Total length offset */
#define CONF_DESC_bConfigurationValue 5 /** Configuration value offset */
#define CONF_DESC_bmAttributes      7 /** configuration characteristics */

/* interface descriptor field offsets */
#define INTF_DESC_bInterfaceNumber  2 /** Interface number offset */
#define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */

/* endpoint descriptor field offsets */
#define ENDP_DESC_bEndpointAddress  2U /** Endpoint address offset */
#define ENDP_DESC_bmAttributes      3U /** Bulk or interrupt? */
#define ENDP_DESC_wMaxPacketSize    4U /** Maximum packet size offset */

#define MAX_NUM_REQ_HANDLERS        4U
#define MAX_STD_REQ_MSG_SIZE        8U

K_MUTEX_DEFINE(usb_enable_lock);

static struct usb_dev_priv {
	/** Setup packet */
	struct usb_setup_packet setup;
	/** Pointer to data buffer */
	uint8_t *data_buf;
	/** Remaining bytes in buffer */
	int32_t data_buf_residue;
	/** Total length of control transfer */
	int32_t data_buf_len;
	/** Zero length packet flag of control transfer */
	bool zlp_flag;
	/** Installed custom request handler */
	usb_request_handler custom_req_handler;
	/** USB stack status callback */
	usb_dc_status_callback status_callback;
	/** USB user status callback */
	usb_dc_status_callback user_status_callback;
	/** Pointer to registered descriptors */
	const uint8_t *descriptors;
	/** Array of installed request handler callbacks */
	usb_request_handler req_handlers[MAX_NUM_REQ_HANDLERS];
	/* Buffer used for storing standard, class and vendor request data */
	uint8_t req_data[CONFIG_USB_REQUEST_BUFFER_SIZE];

	/** Variable to check whether the usb has been enabled */
	bool enabled;
	/** Variable to check whether the usb has been configured */
	bool configured;
	/** Currently selected configuration */
	uint8_t configuration;
	/** Currently selected alternate setting */
	uint8_t alt_setting[CONFIG_USB_MAX_ALT_SETTING];
	/** Remote wakeup feature status */
	bool remote_wakeup;
	/** Tracks whether set_endpoint() had been called on an EP */
	uint32_t ep_bm;
} usb_dev;

/* Setup packet definition used to read raw data from USB line */
struct usb_setup_packet_packed {
	uint8_t bmRequestType;
	uint8_t bRequest;
	uint16_t wValue;
	uint16_t wIndex;
	uint16_t wLength;
} __packed;

static bool reset_endpoint(const struct usb_ep_descriptor *ep_desc);

/*
 * @brief print the contents of a setup packet
 *
 * @param [in] setup The setup packet
 *
 */
static void usb_print_setup(struct usb_setup_packet *setup)
{
	/* avoid compiler warning if LOG_DBG is not defined */
	ARG_UNUSED(setup);

	LOG_DBG("Setup: "
		"bmRT 0x%02x, bR 0x%02x, wV 0x%04x, wI 0x%04x, wL 0x%04x",
		setup->bmRequestType,
		setup->bRequest,
		setup->wValue,
		setup->wIndex,
		setup->wLength);
}

static void usb_reset_alt_setting(void)
{
	memset(usb_dev.alt_setting, 0, ARRAY_SIZE(usb_dev.alt_setting));
}

static bool usb_set_alt_setting(uint8_t iface, uint8_t alt_setting)
{
	if (iface < ARRAY_SIZE(usb_dev.alt_setting)) {
		usb_dev.alt_setting[iface] = alt_setting;
		return true;
	}

	return false;
}

static uint8_t usb_get_alt_setting(uint8_t iface)
{
	if (iface < ARRAY_SIZE(usb_dev.alt_setting)) {
		return usb_dev.alt_setting[iface];
	}

	return 0;
}

/*
 * @brief handle a request by calling one of the installed request handlers
 *
 * Local function to handle a request by calling one of the installed request
 * handlers. In case of data going from host to device, the data is at *ppbData.
 * In case of data going from device to host, the handler can either choose to
 * write its data at *ppbData or update the data pointer.
 *
 * @param [in]     setup The setup packet
 * @param [in,out] len   Pointer to data length
 * @param [in,out] data  Data buffer
 *
 * @return true if the request was handles successfully
 */
static bool usb_handle_request(struct usb_setup_packet *setup,
			       int32_t *len, uint8_t **data)
{
	uint32_t type = setup->RequestType.type;
	usb_request_handler handler;

	if (type >= MAX_NUM_REQ_HANDLERS) {
		LOG_DBG("Error Incorrect iType %d", type);
		return false;
	}

	handler = usb_dev.req_handlers[type];
	if (handler == NULL) {
		LOG_DBG("No handler for reqtype %d", type);
		return false;
	}

	if ((*handler)(setup, len, data) < 0) {
		LOG_DBG("Handler Error %d", type);
		usb_print_setup(setup);
		return false;
	}

	return true;
}

/*
 * @brief send next chunk of data (possibly 0 bytes) to host
 */
static void usb_data_to_host(void)
{
	if (usb_dev.zlp_flag == false) {
		uint32_t chunk = usb_dev.data_buf_residue;

		/*Always EP0 for control*/
		usb_write(USB_CONTROL_EP_IN, usb_dev.data_buf,
			  usb_dev.data_buf_residue, &chunk);
		usb_dev.data_buf += chunk;
		usb_dev.data_buf_residue -= chunk;

		/*
		 * Set ZLP flag when host asks for a bigger length and the
		 * last chunk is wMaxPacketSize long, to indicate the last
		 * packet.
		 */
		if (!usb_dev.data_buf_residue && chunk &&
		    usb_dev.setup.wLength > usb_dev.data_buf_len) {
			/* Send less data as requested during the Setup stage */
			if (!(usb_dev.data_buf_len % USB_MAX_CTRL_MPS)) {
				/* Transfers a zero-length packet */
				LOG_DBG("ZLP, requested %u , length %u ",
					usb_dev.setup.wLength,
					usb_dev.data_buf_len);
				usb_dev.zlp_flag = true;
			}
		}

	} else {
		usb_dev.zlp_flag = false;
		usb_dc_ep_write(USB_CONTROL_EP_IN, NULL, 0, NULL);
	}
}

/*
 * @brief handle IN/OUT transfers on EP0
 *
 * @param [in] ep        Endpoint address
 * @param [in] ep_status Endpoint status
 */
static void usb_handle_control_transfer(uint8_t ep,
					enum usb_dc_ep_cb_status_code ep_status)
{
	uint32_t chunk = 0U;
	struct usb_setup_packet *setup = &usb_dev.setup;
	struct usb_setup_packet_packed setup_raw;

	LOG_DBG("ep 0x%02x, status 0x%02x", ep, ep_status);

	if (ep == USB_CONTROL_EP_OUT && ep_status == USB_DC_EP_SETUP) {
		/*
		 * OUT transfer, Setup packet,
		 * reset request message state machine
		 */
		if (usb_dc_ep_read(ep, (uint8_t *)&setup_raw,
				   sizeof(setup_raw), NULL) < 0) {
			LOG_DBG("Read Setup Packet failed");
			usb_dc_ep_set_stall(USB_CONTROL_EP_IN);
			return;
		}

		/* Take care of endianness */
		setup->bmRequestType = setup_raw.bmRequestType;
		setup->bRequest = setup_raw.bRequest;
		setup->wValue = sys_le16_to_cpu(setup_raw.wValue);
		setup->wIndex = sys_le16_to_cpu(setup_raw.wIndex);
		setup->wLength = sys_le16_to_cpu(setup_raw.wLength);

		usb_dev.data_buf = usb_dev.req_data;
		usb_dev.zlp_flag = false;
		/*
		 * Set length to 0 as a precaution so that no trouble
		 * happens if control request handler does not check the
		 * request values sufficiently.
		 */
		usb_dev.data_buf_len = 0;
		usb_dev.data_buf_residue = 0;

		if (usb_reqtype_is_to_device(setup)) {
			if (setup->wLength > CONFIG_USB_REQUEST_BUFFER_SIZE) {
				LOG_ERR("Request buffer too small");
				usb_dc_ep_set_stall(USB_CONTROL_EP_IN);
				usb_dc_ep_set_stall(USB_CONTROL_EP_OUT);
				return;
			}

			if (setup->wLength) {
				/* Continue with data OUT stage */
				usb_dev.data_buf_len = setup->wLength;
				usb_dev.data_buf_residue = setup->wLength;
				return;
			}
		}

		/* Ask installed handler to process request */
		if (!usb_handle_request(setup,
					&usb_dev.data_buf_len,
					&usb_dev.data_buf)) {
			LOG_DBG("usb_handle_request failed");
			usb_dc_ep_set_stall(USB_CONTROL_EP_IN);
			return;
		}

		/* Send smallest of requested and offered length */
		usb_dev.data_buf_residue = MIN(usb_dev.data_buf_len,
					       setup->wLength);
		/* Send first part (possibly a zero-length status message) */
		usb_data_to_host();
	} else if (ep == USB_CONTROL_EP_OUT) {
		/* OUT transfer, data or status packets */
		if (usb_dev.data_buf_residue <= 0) {
			/* absorb zero-length status message */
			if (usb_dc_ep_read(USB_CONTROL_EP_OUT,
					   usb_dev.data_buf, 0, &chunk) < 0) {
				LOG_DBG("Read DATA Packet failed");
				usb_dc_ep_set_stall(USB_CONTROL_EP_IN);
			}
			return;
		}

		if (usb_dc_ep_read(USB_CONTROL_EP_OUT,
				   usb_dev.data_buf,
				   usb_dev.data_buf_residue, &chunk) < 0) {
			LOG_DBG("Read DATA Packet failed");
			usb_dc_ep_set_stall(USB_CONTROL_EP_IN);
			usb_dc_ep_set_stall(USB_CONTROL_EP_OUT);
			return;
		}

		usb_dev.data_buf += chunk;
		usb_dev.data_buf_residue -= chunk;
		if (usb_dev.data_buf_residue == 0) {
			/* Received all, send data to handler */
			usb_dev.data_buf = usb_dev.req_data;
			if (!usb_handle_request(setup,
						&usb_dev.data_buf_len,
						&usb_dev.data_buf)) {
				LOG_DBG("usb_handle_request1 failed");
				usb_dc_ep_set_stall(USB_CONTROL_EP_IN);
				return;
			}

			/*Send status to host*/
			LOG_DBG(">> usb_data_to_host(2)");
			usb_data_to_host();
		}
	} else if (ep == USB_CONTROL_EP_IN) {
		/* Send more data if available */
		if (usb_dev.data_buf_residue != 0 || usb_dev.zlp_flag == true) {
			usb_data_to_host();
		}
	} else {
		__ASSERT_NO_MSG(false);
	}
}

/*
 * @brief register a callback for handling requests
 *
 * @param [in] type       Type of request, e.g. USB_REQTYPE_TYPE_STANDARD
 * @param [in] handler    Callback function pointer
 */
static void usb_register_request_handler(int32_t type,
					 usb_request_handler handler)
{
	usb_dev.req_handlers[type] = handler;
}

/*
 * @brief register a pointer to a descriptor block
 *
 * This function registers a pointer to a descriptor block containing all
 * descriptors for the device.
 *
 * @param [in] usb_descriptors The descriptor byte array
 */
static void usb_register_descriptors(const uint8_t *usb_descriptors)
{
	usb_dev.descriptors = usb_descriptors;
}

static bool usb_get_status(struct usb_setup_packet *setup,
			   int32_t *len, uint8_t **data_buf)
{
	uint8_t *data = *data_buf;

	LOG_DBG("Get Status request");
	data[0] = 0U;
	data[1] = 0U;

	if (IS_ENABLED(CONFIG_USB_SELF_POWERED)) {
		data[0] |= USB_GET_STATUS_SELF_POWERED;
	}

	if (IS_ENABLED(CONFIG_USB_DEVICE_REMOTE_WAKEUP)) {
		data[0] |= (usb_dev.remote_wakeup ?
			    USB_GET_STATUS_REMOTE_WAKEUP : 0);
	}

	*len = 2;

	return true;
}

/*
 * @brief get specified USB descriptor
 *
 * This function parses the list of installed USB descriptors and attempts
 * to find the specified USB descriptor.
 *
 * @param [in]  setup      The setup packet
 * @param [out] len        Descriptor length
 * @param [out] data       Descriptor data
 *
 * @return true if the descriptor was found, false otherwise
 */
static bool usb_get_descriptor(struct usb_setup_packet *setup,
			       int32_t *len, uint8_t **data)
{
	uint8_t type = 0U;
	uint8_t index = 0U;
	uint8_t *p = NULL;
	uint32_t cur_index = 0U;
	bool found = false;

	LOG_DBG("Get Descriptor request");
	type = USB_GET_DESCRIPTOR_TYPE(setup->wValue);
	index = USB_GET_DESCRIPTOR_INDEX(setup->wValue);

	/*
	 * Invalid types of descriptors,
	 * see USB Spec. Revision 2.0, 9.4.3 Get Descriptor
	 */
	if ((type == USB_DESC_INTERFACE) || (type == USB_DESC_ENDPOINT) ||
	    (type > USB_DESC_OTHER_SPEED)) {
		return false;
	}

	p = (uint8_t *)usb_dev.descriptors;
	cur_index = 0U;

	while (p[DESC_bLength] != 0U) {
		if (p[DESC_bDescriptorType] == type) {
			if (cur_index == index) {
				found = true;
				break;
			}
			cur_index++;
		}
		/* skip to next descriptor */
		p += p[DESC_bLength];
	}

	if (found) {
		/* set data pointer */
		*data = p;
		/* get length from structure */
		if (type == USB_DESC_CONFIGURATION) {
			/* configuration descriptor is an
			 * exception, length is at offset
			 * 2 and 3
			 */
			*len = (p[CONF_DESC_wTotalLength]) |
			    (p[CONF_DESC_wTotalLength + 1] << 8);
		} else {
			/* normally length is at offset 0 */
			*len = p[DESC_bLength];
		}
	} else {
		/* nothing found */
		LOG_DBG("Desc %x not found!", setup->wValue);
	}
	return found;
}

/*
 * @brief Get 32-bit endpoint bitmask from index
 *
 * In the returned 32-bit word, the bit positions in the lower 16 bits
 * indicate OUT endpoints, while the upper 16 bits indicate IN
 * endpoints
 *
 * @param [in]  ep Endpoint of interest
 *
 * @return 32-bit bitmask
 */
static uint32_t get_ep_bm_from_addr(uint8_t ep)
{
	uint32_t ep_bm = 0;
	uint8_t ep_idx;

	ep_idx = ep & (~USB_EP_DIR_IN);
	if (ep_idx > 15) {
		LOG_ERR("Endpoint 0x%02x is invalid", ep);
		goto done;
	}

	if (ep & USB_EP_DIR_IN) {
		ep_bm = BIT(ep_idx + 16);
	} else {
		ep_bm = BIT(ep_idx);
	}
done:
	return ep_bm;
}

/*
 * @brief configure and enable endpoint
 *
 * This function sets endpoint configuration according to one specified in USB
 * endpoint descriptor and then enables it for data transfers.
 *
 * @param [in]  ep_desc Endpoint descriptor byte array
 *
 * @return true if successfully configured and enabled
 */
static bool set_endpoint(const struct usb_ep_descriptor *ep_desc)
{
	struct usb_dc_ep_cfg_data ep_cfg;
	uint32_t ep_bm;
	int ret;

	ep_cfg.ep_addr = ep_desc->bEndpointAddress;
	ep_cfg.ep_mps = sys_le16_to_cpu(ep_desc->wMaxPacketSize);
	ep_cfg.ep_type = ep_desc->bmAttributes & USB_EP_TRANSFER_TYPE_MASK;

	LOG_DBG("Set endpoint 0x%x type %u MPS %u",
		ep_cfg.ep_addr, ep_cfg.ep_type, ep_cfg.ep_mps);

	/* if endpoint is has been set() previously, reset() it first */
	ep_bm = get_ep_bm_from_addr(ep_desc->bEndpointAddress);
	if (ep_bm & usb_dev.ep_bm) {
		reset_endpoint(ep_desc);
		/* allow any canceled transfers to terminate */
		k_usleep(150);
	}

	ret = usb_dc_ep_configure(&ep_cfg);
	if (ret == -EALREADY) {
		LOG_WRN("Endpoint 0x%02x already configured", ep_cfg.ep_addr);
	} else if (ret) {
		LOG_ERR("Failed to configure endpoint 0x%02x", ep_cfg.ep_addr);
		return false;
	} else {
		;
	}

	ret = usb_dc_ep_enable(ep_cfg.ep_addr);
	if (ret == -EALREADY) {
		LOG_WRN("Endpoint 0x%02x already enabled", ep_cfg.ep_addr);
	} else if (ret) {
		LOG_ERR("Failed to enable endpoint 0x%02x", ep_cfg.ep_addr);
		return false;
	} else {
		;
	}

	usb_dev.configured = true;
	usb_dev.ep_bm |= ep_bm;

	return true;
}

static int disable_endpoint(uint8_t ep_addr)
{
	uint32_t ep_bm;
	int ret;

	ret = usb_dc_ep_disable(ep_addr);
	if (ret == -EALREADY) {
		LOG_WRN("Endpoint 0x%02x already disabled", ep_addr);
	} else if (ret) {
		LOG_ERR("Failed to disable endpoint 0x%02x", ep_addr);
		return ret;
	}

	/* clear endpoint mask */
	ep_bm = get_ep_bm_from_addr(ep_addr);
	usb_dev.ep_bm &= ~ep_bm;

	return 0;
}

/*
 * @brief Disable endpoint for transferring data
 *
 * This function cancels transfers that are associated with endpoint and
 * disabled endpoint itself.
 *
 * @param [in]  ep_desc Endpoint descriptor byte array
 *
 * @return true if successfully deconfigured and disabled
 */
static bool reset_endpoint(const struct usb_ep_descriptor *ep_desc)
{
	struct usb_dc_ep_cfg_data ep_cfg;

	ep_cfg.ep_addr = ep_desc->bEndpointAddress;
	ep_cfg.ep_type = ep_desc->bmAttributes & USB_EP_TRANSFER_TYPE_MASK;

	LOG_DBG("Reset endpoint 0x%02x type %u",
		ep_cfg.ep_addr, ep_cfg.ep_type);

	usb_cancel_transfer(ep_cfg.ep_addr);

	return disable_endpoint(ep_cfg.ep_addr) ? false : true;
}

static bool usb_eps_reconfigure(struct usb_ep_descriptor *ep_desc,
				uint8_t cur_alt_setting,
				uint8_t alt_setting)
{
	bool ret;

	if (cur_alt_setting != alt_setting) {
		LOG_DBG("Disable endpoint 0x%02x", ep_desc->bEndpointAddress);
		ret = reset_endpoint(ep_desc);
	} else {
		LOG_DBG("Enable endpoint 0x%02x", ep_desc->bEndpointAddress);
		ret = set_endpoint(ep_desc);
	}

	return ret;
}

/*
 * @brief set USB configuration
 *
 * This function configures the device according to the specified configuration
 * index and alternate setting by parsing the installed USB descriptor list.
 * A configuration index of 0 unconfigures the device.
 *
 * @param [in] setup        The setup packet
 *
 * @return true if successfully configured false if error or unconfigured
 */
static bool usb_set_configuration(struct usb_setup_packet *setup)
{
	uint8_t *p = (uint8_t *)usb_dev.descriptors;
	uint8_t cur_alt_setting = 0xFF;
	uint8_t cur_config = 0xFF;
	bool found = false;

	LOG_DBG("Set Configuration %u request", setup->wValue);

	if (setup->wValue == 0U) {
		usb_reset_alt_setting();
		usb_dev.configuration = setup->wValue;
		if (usb_dev.status_callback) {
			usb_dev.status_callback(USB_DC_CONFIGURED,
						&usb_dev.configuration);
		}

		return true;
	}

	/* configure endpoints for this configuration/altsetting */
	while (p[DESC_bLength] != 0U) {
		switch (p[DESC_bDescriptorType]) {
		case USB_DESC_CONFIGURATION:
			/* remember current configuration index */
			cur_config = p[CONF_DESC_bConfigurationValue];
			if (cur_config == setup->wValue) {
				found = true;
			}

			break;

		case USB_DESC_INTERFACE:
			/* remember current alternate setting */
			cur_alt_setting =
			    p[INTF_DESC_bAlternateSetting];
			break;

		case USB_DESC_ENDPOINT:
			if ((cur_config != setup->wValue) ||
			    (cur_alt_setting != 0)) {
				break;
			}

			found = set_endpoint((struct usb_ep_descriptor *)p);
			break;

		default:
			break;
		}

		/* skip to next descriptor */
		p += p[DESC_bLength];
	}

	if (found) {
		usb_reset_alt_setting();
		usb_dev.configuration = setup->wValue;
		if (usb_dev.status_callback) {
			usb_dev.status_callback(USB_DC_CONFIGURED,
						&usb_dev.configuration);
		}
	} else {
		LOG_DBG("Set Configuration %u failed", setup->wValue);
	}

	return found;
}

/*
 * @brief set USB interface
 *
 * @param [in] setup        The setup packet
 *
 * @return true if successfully configured false if error or unconfigured
 */
static bool usb_set_interface(struct usb_setup_packet *setup)
{
	const uint8_t *p = usb_dev.descriptors;
	const uint8_t *if_desc = NULL;
	struct usb_ep_descriptor *ep;
	uint8_t cur_alt_setting = 0xFF;
	uint8_t cur_iface = 0xFF;
	bool ret = false;

	LOG_DBG("Set Interface %u alternate %u", setup->wIndex, setup->wValue);

	while (p[DESC_bLength] != 0U) {
		switch (p[DESC_bDescriptorType]) {
		case USB_DESC_INTERFACE:
			/* remember current alternate setting */
			cur_alt_setting = p[INTF_DESC_bAlternateSetting];
			cur_iface = p[INTF_DESC_bInterfaceNumber];

			if (cur_iface == setup->wIndex &&
			    cur_alt_setting == setup->wValue) {
				ret = usb_set_alt_setting(setup->wIndex,
							  setup->wValue);
				if_desc = (void *)p;
			}

			LOG_DBG("Current iface %u alt setting %u",
				cur_iface, cur_alt_setting);
			break;
		case USB_DESC_ENDPOINT:
			if (cur_iface == setup->wIndex) {
				ep = (struct usb_ep_descriptor *)p;
				ret = usb_eps_reconfigure(ep, cur_alt_setting,
							  setup->wValue);
			}
			break;
		default:
			break;
		}

		/* skip to next descriptor */
		p += p[DESC_bLength];
	}

	if (usb_dev.status_callback) {
		usb_dev.status_callback(USB_DC_INTERFACE, if_desc);
	}

	return ret;
}

static bool usb_get_interface(struct usb_setup_packet *setup,
			      int32_t *len, uint8_t **data_buf)
{
	const uint8_t *p = usb_dev.descriptors;
	uint8_t *data = *data_buf;
	uint8_t cur_iface;

	while (p[DESC_bLength] != 0U) {
		if (p[DESC_bDescriptorType] == USB_DESC_INTERFACE) {
			cur_iface = p[INTF_DESC_bInterfaceNumber];
			if (cur_iface == setup->wIndex) {
				data[0] = usb_get_alt_setting(cur_iface);
				LOG_DBG("Current iface %u alt setting %u",
					setup->wIndex, data[0]);
				*len = 1;
				return true;
			}
		}

		/* skip to next descriptor */
		p += p[DESC_bLength];
	}

	return false;
}

/**
 * @brief Check if the device is in Configured state
 *
 * @return true if Configured, false otherwise.
 */
static bool is_device_configured(void)
{
	return (usb_dev.configuration != 0);
}

/*
 * @brief handle a standard device request
 *
 * @param [in]     setup    The setup packet
 * @param [in,out] len      Pointer to data length
 * @param [in,out] data_buf Data buffer
 *
 * @return true if the request was handled successfully
 */
static bool usb_handle_std_device_req(struct usb_setup_packet *setup,
				      int32_t *len, uint8_t **data_buf)
{
	uint8_t *data = *data_buf;

	if (usb_reqtype_is_to_host(setup)) {
		switch (setup->bRequest) {
		case USB_SREQ_GET_STATUS:
			return usb_get_status(setup, len, data_buf);

		case USB_SREQ_GET_DESCRIPTOR:
			return usb_get_descriptor(setup, len, data_buf);

		case USB_SREQ_GET_CONFIGURATION:
			LOG_DBG("Get Configuration request");
			/* indicate if we are configured */
			data[0] = usb_dev.configuration;
			*len = 1;
			return true;
		default:
			break;
		}
	} else {
		switch (setup->bRequest) {
		case USB_SREQ_SET_ADDRESS:
			LOG_DBG("Set Address %u request", setup->wValue);
			return !usb_dc_set_address(setup->wValue);

		case USB_SREQ_SET_CONFIGURATION:
			return usb_set_configuration(setup);

		case USB_SREQ_CLEAR_FEATURE:
			LOG_DBG("Clear Feature request");

			if (IS_ENABLED(CONFIG_USB_DEVICE_REMOTE_WAKEUP)) {
				if (setup->wValue == USB_SFS_REMOTE_WAKEUP) {
					usb_dev.remote_wakeup = false;
					return true;
				}
			}
			break;

		case USB_SREQ_SET_FEATURE:
			LOG_DBG("Set Feature request");

			if (IS_ENABLED(CONFIG_USB_DEVICE_REMOTE_WAKEUP)) {
				if (setup->wValue == USB_SFS_REMOTE_WAKEUP) {
					usb_dev.remote_wakeup = true;
					return true;
				}
			}
			break;

		default:
			break;
		}
	}

	LOG_DBG("Unsupported bmRequestType 0x%02x bRequest 0x%02x",
		setup->bmRequestType, setup->bRequest);
	return false;
}

/**
 * @brief Check if the interface of given number is valid
 *
 * @param [in] interface Number of the addressed interface
 *
 * This function searches through descriptor and checks
 * is the Host has addressed valid interface.
 *
 * @return true if interface exists - valid
 */
static bool is_interface_valid(uint8_t interface)
{
	const uint8_t *p = (uint8_t *)usb_dev.descriptors;
	const struct usb_cfg_descriptor *cfg_descr;

	/* Search through descriptor for matching interface */
	while (p[DESC_bLength] != 0U) {
		if (p[DESC_bDescriptorType] == USB_DESC_CONFIGURATION) {
			cfg_descr = (const struct usb_cfg_descriptor *)p;
			if (interface < cfg_descr->bNumInterfaces) {
				return true;
			}
		}
		p += p[DESC_bLength];
	}

	return false;
}

/*
 * @brief handle a standard interface request
 *
 * @param [in]     setup    The setup packet
 * @param [in,out] len      Pointer to data length
 * @param [in]     data_buf Data buffer
 *
 * @return true if the request was handled successfully
 */
static bool usb_handle_std_interface_req(struct usb_setup_packet *setup,
					 int32_t *len, uint8_t **data_buf)
{
	uint8_t *data = *data_buf;

	/** The device must be configured to accept standard interface
	 * requests and the addressed Interface must be valid.
	 */
	if (!is_device_configured() ||
	   (!is_interface_valid((uint8_t)setup->wIndex))) {
		return false;
	}

	if (usb_reqtype_is_to_host(setup)) {
		switch (setup->bRequest) {
		case USB_SREQ_GET_STATUS:
			/* no bits specified */
			data[0] = 0U;
			data[1] = 0U;
			*len = 2;
			return true;

		case USB_SREQ_GET_INTERFACE:
			return usb_get_interface(setup, len, data_buf);

		default:
			break;
		}
	} else {
		if (setup->bRequest == USB_SREQ_SET_INTERFACE) {
			return usb_set_interface(setup);
		}

	}

	LOG_DBG("Unsupported bmRequestType 0x%02x bRequest 0x%02x",
		setup->bmRequestType, setup->bRequest);
	return false;
}

/**
 * @brief Check if the endpoint of given address is valid
 *
 * @param [in] ep Address of the Endpoint
 *
 * This function checks if the Endpoint of given address
 * is valid for the configured device. Valid Endpoint is
 * either Control Endpoint or one used by the device.
 *
 * @return true if endpoint exists - valid
 */
static bool is_ep_valid(uint8_t ep)
{
	const struct usb_ep_cfg_data *ep_data;

	/* Check if its Endpoint 0 */
	if (USB_EP_GET_IDX(ep) == 0) {
		return true;
	}

	STRUCT_SECTION_FOREACH(usb_cfg_data, cfg_data) {
		ep_data = cfg_data->endpoint;

		for (uint8_t n = 0; n < cfg_data->num_endpoints; n++) {
			if (ep_data[n].ep_addr == ep) {
				return true;
			}
		}
	}

	return false;
}

static bool usb_get_status_endpoint(struct usb_setup_packet *setup,
				    int32_t *len, uint8_t **data_buf)
{
	uint8_t ep = setup->wIndex;
	uint8_t *data = *data_buf;

	/* Check if request addresses valid Endpoint */
	if (!is_ep_valid(ep)) {
		return false;
	}

	/* This request is valid for Control Endpoints when
	 * the device is not yet configured. For other
	 * Endpoints the device must be configured.
	 * Firstly check if addressed ep is Control Endpoint.
	 * If no then the device must be in Configured state
	 * to accept the request.
	 */
	if ((USB_EP_GET_IDX(ep) == 0) || is_device_configured()) {
		/* bit 0 - Endpoint halted or not */
		usb_dc_ep_is_stalled(ep, &data[0]);
		data[1] = 0U;
		*len = 2;
		return true;
	}

	return false;
}


static bool usb_halt_endpoint_req(struct usb_setup_packet *setup, bool halt)
{
	uint8_t ep = setup->wIndex;

	/* Check if request addresses valid Endpoint */
	if (!is_ep_valid(ep)) {
		return false;
	}

	/* This request is valid for Control Endpoints when
	 * the device is not yet configured. For other
	 * Endpoints the device must be configured.
	 * Firstly check if addressed ep is Control Endpoint.
	 * If no then the device must be in Configured state
	 * to accept the request.
	 */
	if ((USB_EP_GET_IDX(ep) == 0) || is_device_configured()) {
		if (halt) {
			LOG_INF("Set halt ep 0x%02x", ep);
			usb_dc_ep_set_stall(ep);
			if (usb_dev.status_callback) {
				usb_dev.status_callback(USB_DC_SET_HALT, &ep);
			}
		} else {
			LOG_INF("Clear halt ep 0x%02x", ep);
			usb_dc_ep_clear_stall(ep);
			if (usb_dev.status_callback) {
				usb_dev.status_callback(USB_DC_CLEAR_HALT, &ep);
			}
		}

		return true;
	}

	return false;
}

/*
 * @brief handle a standard endpoint request
 *
 * @param [in]     setup    The setup packet
 * @param [in,out] len      Pointer to data length
 * @param [in]     data_buf Data buffer
 *
 * @return true if the request was handled successfully
 */
static bool usb_handle_std_endpoint_req(struct usb_setup_packet *setup,
					int32_t *len, uint8_t **data_buf)
{

	if (usb_reqtype_is_to_host(setup)) {
		if (setup->bRequest == USB_SREQ_GET_STATUS) {
			return usb_get_status_endpoint(setup, len, data_buf);
		}
	} else {
		switch (setup->bRequest) {
		case USB_SREQ_CLEAR_FEATURE:
			if (setup->wValue == USB_SFS_ENDPOINT_HALT) {
				return usb_halt_endpoint_req(setup, false);
			}
			break;
		case USB_SREQ_SET_FEATURE:
			if (setup->wValue == USB_SFS_ENDPOINT_HALT) {
				return usb_halt_endpoint_req(setup, true);
			}
			break;
		default:
			break;
		}
	}

	LOG_DBG("Unsupported bmRequestType 0x%02x bRequest 0x%02x",
		setup->bmRequestType, setup->bRequest);
	return false;
}

/*
 * @brief default handler for standard ('chapter 9') requests
 *
 * If a custom request handler was installed, this handler is called first.
 *
 * @param [in]     setup    The setup packet
 * @param [in,out] len      Pointer to data length
 * @param [in]     data_buf Data buffer
 *
 * @return true if the request was handled successfully
 */
static int usb_handle_standard_request(struct usb_setup_packet *setup,
				       int32_t *len, uint8_t **data_buf)
{
	int rc = 0;

	if (!usb_handle_bos(setup, len, data_buf)) {
		return 0;
	}

	if (!usb_handle_os_desc(setup, len, data_buf)) {
		return 0;
	}

	/* try the custom request handler first */
	if (usb_dev.custom_req_handler &&
	    !usb_dev.custom_req_handler(setup, len, data_buf)) {
		return 0;
	}

	switch (setup->RequestType.recipient) {
	case USB_REQTYPE_RECIPIENT_DEVICE:
		if (usb_handle_std_device_req(setup, len, data_buf) == false) {
			rc = -EINVAL;
		}
		break;
	case USB_REQTYPE_RECIPIENT_INTERFACE:
		if (usb_handle_std_interface_req(setup, len, data_buf) == false) {
			rc = -EINVAL;
		}
		break;
	case USB_REQTYPE_RECIPIENT_ENDPOINT:
		if (usb_handle_std_endpoint_req(setup, len, data_buf) == false) {
			rc = -EINVAL;
		}
		break;
	default:
		rc = -EINVAL;
	}
	return rc;
}

/*
 * @brief Registers a callback for custom device requests
 *
 * In usb_register_custom_req_handler, the custom request handler gets a first
 * chance at handling the request before it is handed over to the 'chapter 9'
 * request handler.
 *
 * This can be used for example in HID devices, where a REQ_GET_DESCRIPTOR
 * request is sent to an interface, which is not covered by the 'chapter 9'
 * specification.
 *
 * @param [in] handler Callback function pointer
 */
static void usb_register_custom_req_handler(usb_request_handler handler)
{
	usb_dev.custom_req_handler = handler;
}

/*
 * @brief register a callback for device status
 *
 * This function registers a callback for device status. The registered callback
 * is used to report changes in the status of the device controller.
 *
 * @param [in] cb Callback function pointer
 */
static void usb_register_status_callback(usb_dc_status_callback cb)
{
	usb_dev.status_callback = cb;
}

static int foreach_ep(int (* endpoint_callback)(const struct usb_ep_cfg_data *))
{
	struct usb_ep_cfg_data *ep_data;

	STRUCT_SECTION_FOREACH(usb_cfg_data, cfg_data) {
		ep_data = cfg_data->endpoint;

		for (uint8_t n = 0; n < cfg_data->num_endpoints; n++) {
			int ret;

			ret = endpoint_callback(&ep_data[n]);
			if (ret < 0) {
				return ret;
			}
		}
	}

	return 0;
}

static int disable_interface_ep(const struct usb_ep_cfg_data *ep_data)
{
	uint32_t ep_bm;
	int ret;

	ret = usb_dc_ep_disable(ep_data->ep_addr);

	/* clear endpoint mask */
	ep_bm = get_ep_bm_from_addr(ep_data->ep_addr);
	usb_dev.ep_bm &= ~ep_bm;

	return ret;
}

static void forward_status_cb(enum usb_dc_status_code status, const uint8_t *param)
{
	if (status == USB_DC_DISCONNECTED) {
		usb_reset_alt_setting();
	}

	if (status == USB_DC_DISCONNECTED || status == USB_DC_RESET) {
		if (usb_dev.configured) {
			usb_cancel_transfers();
			foreach_ep(disable_interface_ep);
			usb_dev.configured = false;
		}
	}

	STRUCT_SECTION_FOREACH(usb_cfg_data, cfg_data) {
		if (cfg_data->cb_usb_status) {
			cfg_data->cb_usb_status(cfg_data, status, param);
		}
	}

	if (usb_dev.user_status_callback) {
		usb_dev.user_status_callback(status, param);
	}
}

/**
 * @brief turn on/off USB VBUS voltage
 *
 * To utilize this in the devicetree the chosen node should have a
 * zephyr,usb-device property that points to the usb device controller node.
 * Additionally the usb device controller node should have a vbus-gpios
 * property that has the GPIO details.
 *
 * Something like:
 *
 * chosen {
 *      zephyr,usb-device = &usbd;
 * };
 *
 * usbd: usbd {
 *      vbus-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
 * };
 *
 * @param on Set to false to turn off and to true to turn on VBUS
 *
 * @return 0 on success, negative errno code on fail
 */
static int usb_vbus_set(bool on)
{
#define USB_DEV_NODE DT_CHOSEN(zephyr_usb_device)
#if DT_NODE_HAS_STATUS(USB_DEV_NODE, okay) && \
    DT_NODE_HAS_PROP(USB_DEV_NODE, vbus_gpios)
	int ret = 0;
	struct gpio_dt_spec gpio_dev = GPIO_DT_SPEC_GET(USB_DEV_NODE, vbus_gpios);

	if (!device_is_ready(gpio_dev.port)) {
		LOG_DBG("USB requires GPIO. Device %s is not ready!", gpio_dev.port->name);
		return -ENODEV;
	}

	/* Enable USB IO */
	ret = gpio_pin_configure_dt(&gpio_dev, GPIO_OUTPUT);
	if (ret) {
		return ret;
	}

	ret = gpio_pin_set_dt(&gpio_dev, on == true ? 1 : 0);
	if (ret) {
		return ret;
	}
#endif

	return 0;
}

int usb_deconfig(void)
{
	/* unregister descriptors */
	usb_register_descriptors(NULL);

	/* unregister standard request handler */
	usb_register_request_handler(USB_REQTYPE_TYPE_STANDARD, NULL);

	/* unregister class request handlers for each interface*/
	usb_register_request_handler(USB_REQTYPE_TYPE_CLASS, NULL);

	/* unregister class request handlers for each interface*/
	usb_register_custom_req_handler(NULL);

	/* unregister status callback */
	usb_register_status_callback(NULL);

	/* unregister user status callback */
	usb_dev.user_status_callback = NULL;

	/* Reset USB controller */
	usb_dc_reset();

	return 0;
}

int usb_disable(void)
{
	int ret;

	if (usb_dev.enabled != true) {
		/*Already disabled*/
		return 0;
	}

	ret = usb_dc_detach();
	if (ret < 0) {
		return ret;
	}

	usb_cancel_transfers();
	for (uint8_t i = 0; i <= 15; i++) {
		if (usb_dev.ep_bm & BIT(i)) {
			ret = disable_endpoint(i);
			if (ret < 0) {
				return ret;
			}
		}
		if (usb_dev.ep_bm & BIT(i + 16)) {
			ret = disable_endpoint(USB_EP_DIR_IN | i);
			if (ret < 0) {
				return ret;
			}
		}
	}

	/* Disable VBUS if needed */
	usb_vbus_set(false);

	usb_dev.enabled = false;

	return 0;
}

int usb_write(uint8_t ep, const uint8_t *data, uint32_t data_len, uint32_t *bytes_ret)
{
	int tries = CONFIG_USB_NUMOF_EP_WRITE_RETRIES;
	int ret;

	do {
		ret = usb_dc_ep_write(ep, data, data_len, bytes_ret);
		if (ret == -EAGAIN) {
			LOG_WRN("Failed to write endpoint buffer 0x%02x", ep);
			k_yield();
		}

	} while (ret == -EAGAIN && tries--);

	return ret;
}

int usb_read(uint8_t ep, uint8_t *data, uint32_t max_data_len, uint32_t *ret_bytes)
{
	return usb_dc_ep_read(ep, data, max_data_len, ret_bytes);
}

int usb_ep_set_stall(uint8_t ep)
{
	return usb_dc_ep_set_stall(ep);
}

int usb_ep_clear_stall(uint8_t ep)
{
	return usb_dc_ep_clear_stall(ep);
}

int usb_ep_read_wait(uint8_t ep, uint8_t *data, uint32_t max_data_len, uint32_t *ret_bytes)
{
	return usb_dc_ep_read_wait(ep, data, max_data_len, ret_bytes);
}

int usb_ep_read_continue(uint8_t ep)
{
	return usb_dc_ep_read_continue(ep);
}

bool usb_get_remote_wakeup_status(void)
{
	return usb_dev.remote_wakeup;
}

int usb_wakeup_request(void)
{
	if (IS_ENABLED(CONFIG_USB_DEVICE_REMOTE_WAKEUP)) {
		if (usb_get_remote_wakeup_status()) {
			return usb_dc_wakeup_request();
		}
		return -EACCES;
	} else {
		return -ENOTSUP;
	}
}

/*
 * The functions class_handler(), custom_handler() and vendor_handler()
 * go through the interfaces one after the other and compare the
 * bInterfaceNumber with the wIndex and and then call the appropriate
 * callback of the USB function.
 * Note, a USB function can have more than one interface and the
 * request does not have to be directed to the first interface (unlikely).
 * These functions can be simplified and moved to usb_handle_request()
 * when legacy initialization through the usb_set_config() and
 * usb_enable() is no longer needed.
 */

static int class_handler(struct usb_setup_packet *pSetup,
			 int32_t *len, uint8_t **data)
{
	const struct usb_if_descriptor *if_descr;
	struct usb_interface_cfg_data *iface;

	LOG_DBG("bRequest 0x%02x, wIndex 0x%04x",
		pSetup->bRequest, pSetup->wIndex);

	STRUCT_SECTION_FOREACH(usb_cfg_data, cfg_data) {
		iface = &cfg_data->interface;
		if_descr = cfg_data->interface_descriptor;
		/*
		 * Wind forward until it is within the range
		 * of the current descriptor.
		 */
		if ((uint8_t *)if_descr < usb_dev.descriptors) {
			continue;
		}

		if (iface->class_handler &&
		    if_descr->bInterfaceNumber == (pSetup->wIndex & 0xFF)) {
			return iface->class_handler(pSetup, len, data);
		}
	}

	return -ENOTSUP;
}

static int custom_handler(struct usb_setup_packet *pSetup,
			  int32_t *len, uint8_t **data)
{
	const struct usb_if_descriptor *if_descr;
	struct usb_interface_cfg_data *iface;

	LOG_DBG("bRequest 0x%02x, wIndex 0x%04x",
		pSetup->bRequest, pSetup->wIndex);

	STRUCT_SECTION_FOREACH(usb_cfg_data, cfg_data) {
		iface = &cfg_data->interface;
		if_descr = cfg_data->interface_descriptor;
		/*
		 * Wind forward until it is within the range
		 * of the current descriptor.
		 */
		if ((uint8_t *)if_descr < usb_dev.descriptors) {
			continue;
		}

		if (iface->custom_handler == NULL) {
			continue;
		}

		if (if_descr->bInterfaceNumber == (pSetup->wIndex & 0xFF)) {
			return iface->custom_handler(pSetup, len, data);
		} else {
			/*
			 * Audio has several interfaces.  if_descr points to
			 * the first interface, but the request may be for
			 * subsequent ones, so forward each request to audio.
			 * The class does not actively engage in request
			 * handling and therefore we can ignore return value.
			 */
			if (if_descr->bInterfaceClass == USB_BCC_AUDIO) {
				(void)iface->custom_handler(pSetup, len, data);
			}
		}
	}

	return -ENOTSUP;
}

static int vendor_handler(struct usb_setup_packet *pSetup,
			  int32_t *len, uint8_t **data)
{
	struct usb_interface_cfg_data *iface;

	LOG_DBG("bRequest 0x%02x, wIndex 0x%04x",
		pSetup->bRequest, pSetup->wIndex);

	if (usb_os_desc_enabled()) {
		if (!usb_handle_os_desc_feature(pSetup, len, data)) {
			return 0;
		}
	}

	STRUCT_SECTION_FOREACH(usb_cfg_data, cfg_data) {
		iface = &cfg_data->interface;
		if (iface->vendor_handler) {
			if (!iface->vendor_handler(pSetup, len, data)) {
				return 0;
			}
		}
	}

	return -ENOTSUP;
}

static int composite_setup_ep_cb(void)
{
	struct usb_ep_cfg_data *ep_data;

	STRUCT_SECTION_FOREACH(usb_cfg_data, cfg_data) {
		ep_data = cfg_data->endpoint;
		for (uint8_t n = 0; n < cfg_data->num_endpoints; n++) {
			LOG_DBG("set cb, ep: 0x%x", ep_data[n].ep_addr);
			if (usb_dc_ep_set_callback(ep_data[n].ep_addr,
						   ep_data[n].ep_cb)) {
				return -1;
			}
		}
	}

	return 0;
}

int usb_set_config(const uint8_t *device_descriptor)
{
	/* register descriptors */
	usb_register_descriptors(device_descriptor);

	/* register standard request handler */
	usb_register_request_handler(USB_REQTYPE_TYPE_STANDARD,
				     usb_handle_standard_request);

	/* register class request handlers for each interface*/
	usb_register_request_handler(USB_REQTYPE_TYPE_CLASS, class_handler);

	/* register vendor request handler */
	usb_register_request_handler(USB_REQTYPE_TYPE_VENDOR, vendor_handler);

	/* register class request handlers for each interface*/
	usb_register_custom_req_handler(custom_handler);

	return 0;
}

int usb_enable(usb_dc_status_callback status_cb)
{
	int ret;
	struct usb_dc_ep_cfg_data ep0_cfg;

	/* Prevent from calling usb_enable form different context.
	 * This should only be called once.
	 */
	LOG_DBG("lock usb_enable_lock mutex");
	k_mutex_lock(&usb_enable_lock, K_FOREVER);

	if (usb_dev.enabled == true) {
		LOG_WRN("USB device support already enabled");
		ret = -EALREADY;
		goto out;
	}

	/* Enable VBUS if needed */
	ret = usb_vbus_set(true);
	if (ret < 0) {
		goto out;
	}

	usb_dev.user_status_callback = status_cb;
	usb_register_status_callback(forward_status_cb);
	usb_dc_set_status_callback(forward_status_cb);

	ret = usb_dc_attach();
	if (ret < 0) {
		goto out;
	}

	ret = usb_transfer_init();
	if (ret < 0) {
		goto out;
	}

	/* Configure control EP */
	ep0_cfg.ep_mps = USB_MAX_CTRL_MPS;
	ep0_cfg.ep_type = USB_DC_EP_CONTROL;

	ep0_cfg.ep_addr = USB_CONTROL_EP_OUT;
	ret = usb_dc_ep_configure(&ep0_cfg);
	if (ret < 0) {
		goto out;
	}

	ep0_cfg.ep_addr = USB_CONTROL_EP_IN;
	ret = usb_dc_ep_configure(&ep0_cfg);
	if (ret < 0) {
		goto out;
	}

	/* Register endpoint 0 handlers*/
	ret = usb_dc_ep_set_callback(USB_CONTROL_EP_OUT,
				     usb_handle_control_transfer);
	if (ret < 0) {
		goto out;
	}

	ret = usb_dc_ep_set_callback(USB_CONTROL_EP_IN,
				     usb_handle_control_transfer);
	if (ret < 0) {
		goto out;
	}

	/* Register endpoint handlers*/
	ret = composite_setup_ep_cb();
	if (ret < 0) {
		goto out;
	}

	/* Enable control EP */
	ret = usb_dc_ep_enable(USB_CONTROL_EP_OUT);
	if (ret < 0) {
		goto out;
	}
	usb_dev.ep_bm |= get_ep_bm_from_addr(USB_CONTROL_EP_OUT);

	ret = usb_dc_ep_enable(USB_CONTROL_EP_IN);
	if (ret < 0) {
		goto out;
	}
	usb_dev.ep_bm |= get_ep_bm_from_addr(USB_CONTROL_EP_IN);

	usb_dev.enabled = true;
	ret = 0;
out:
	LOG_DBG("unlock usb_enable_lock mutex");
	k_mutex_unlock(&usb_enable_lock);
	return ret;
}

/*
 * This function configures the USB device stack based on USB descriptor and
 * usb_cfg_data.
 */
static int usb_device_init(const struct device *dev)
{
	uint8_t *device_descriptor;

	if (usb_dev.enabled == true) {
		return -EALREADY;
	}

	/* register device descriptor */
	device_descriptor = usb_get_device_descriptor();
	if (!device_descriptor) {
		LOG_ERR("Failed to configure USB device stack");
		return -1;
	}

	usb_set_config(device_descriptor);

	if (IS_ENABLED(CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT)) {
		return usb_enable(NULL);
	}

	return 0;
}

SYS_INIT(usb_device_init, POST_KERNEL, CONFIG_APPLICATION_INIT_PRIORITY);
