/*
 * Copyright (c) 2021-2022 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <zephyr/net/buf.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/usb/usb_ch9.h>
#include "udc_common.h"

#include <zephyr/logging/log.h>
#if defined(CONFIG_UDC_DRIVER_LOG_LEVEL)
#define UDC_COMMON_LOG_LEVEL CONFIG_UDC_DRIVER_LOG_LEVEL
#else
#define UDC_COMMON_LOG_LEVEL LOG_LEVEL_NONE
#endif
LOG_MODULE_REGISTER(udc, CONFIG_UDC_DRIVER_LOG_LEVEL);

static inline void udc_buf_destroy(struct net_buf *buf);

NET_BUF_POOL_VAR_DEFINE(udc_ep_pool,
			CONFIG_UDC_BUF_COUNT, CONFIG_UDC_BUF_POOL_SIZE,
			sizeof(struct udc_buf_info), udc_buf_destroy);

#define USB_EP_LUT_IDX(ep) (USB_EP_DIR_IS_IN(ep) ? (ep & BIT_MASK(4)) + 16 : \
						   ep & BIT_MASK(4))

void udc_set_suspended(const struct device *dev, const bool value)
{
	struct udc_data *data = dev->data;

	if (value == udc_is_suspended(dev)) {
		LOG_WRN("Spurious suspend/resume event");
	}

	atomic_set_bit_to(&data->status, UDC_STATUS_SUSPENDED, value);
}

struct udc_ep_config *udc_get_ep_cfg(const struct device *dev, const uint8_t ep)
{
	struct udc_data *data = dev->data;

	return data->ep_lut[USB_EP_LUT_IDX(ep)];
}

bool udc_ep_is_busy(const struct device *dev, const uint8_t ep)
{
	struct udc_ep_config *ep_cfg;

	ep_cfg = udc_get_ep_cfg(dev, ep);
	__ASSERT(ep_cfg != NULL, "ep 0x%02x is not available", ep);

	return ep_cfg->stat.busy;
}

void udc_ep_set_busy(const struct device *dev, const uint8_t ep, const bool busy)
{
	struct udc_ep_config *ep_cfg;

	ep_cfg = udc_get_ep_cfg(dev, ep);
	__ASSERT(ep_cfg != NULL, "ep 0x%02x is not available", ep);
	ep_cfg->stat.busy = busy;
}

int udc_register_ep(const struct device *dev, struct udc_ep_config *const cfg)
{
	struct udc_data *data = dev->data;
	uint8_t idx;

	if (udc_is_initialized(dev)) {
		return -EACCES;
	}

	idx = USB_EP_LUT_IDX(cfg->addr);
	__ASSERT_NO_MSG(idx < ARRAY_SIZE(data->ep_lut));

	data->ep_lut[idx] = cfg;
	k_fifo_init(&cfg->fifo);

	return 0;
}

struct net_buf *udc_buf_get(const struct device *dev, const uint8_t ep)
{
	struct udc_ep_config *ep_cfg;

	ep_cfg = udc_get_ep_cfg(dev, ep);
	if (ep_cfg == NULL) {
		return NULL;
	}

	return net_buf_get(&ep_cfg->fifo, K_NO_WAIT);
}

struct net_buf *udc_buf_get_all(const struct device *dev, const uint8_t ep)
{
	struct udc_ep_config *ep_cfg;
	struct net_buf *buf;

	ep_cfg = udc_get_ep_cfg(dev, ep);
	if (ep_cfg == NULL) {
		return NULL;
	}

	buf = k_fifo_get(&ep_cfg->fifo, K_NO_WAIT);
	if (!buf) {
		return NULL;
	}

	LOG_DBG("ep 0x%02x dequeue %p", ep, buf);
	for (struct net_buf *n = buf; !k_fifo_is_empty(&ep_cfg->fifo); n = n->frags) {
		n->frags = k_fifo_get(&ep_cfg->fifo, K_NO_WAIT);
		LOG_DBG("|-> %p ", n->frags);
		if (n->frags == NULL) {
			break;
		}
	}

	return buf;
}

struct net_buf *udc_buf_peek(const struct device *dev, const uint8_t ep)
{
	struct udc_ep_config *ep_cfg;

	ep_cfg = udc_get_ep_cfg(dev, ep);
	if (ep_cfg == NULL) {
		return NULL;
	}

	return k_fifo_peek_head(&ep_cfg->fifo);
}

void udc_buf_put(struct udc_ep_config *const ep_cfg,
		 struct net_buf *const buf)
{
	net_buf_put(&ep_cfg->fifo, buf);
}

void udc_ep_buf_set_setup(struct net_buf *const buf)
{
	struct udc_buf_info *bi = udc_get_buf_info(buf);

	bi->setup = 1;
	bi->data = 0;
	bi->status = 0;
}

bool udc_ep_buf_has_zlp(const struct net_buf *const buf)
{
	const struct udc_buf_info *bi = udc_get_buf_info(buf);

	return bi->zlp;
}

void udc_ep_buf_clear_zlp(const struct net_buf *const buf)
{
	struct udc_buf_info *bi = udc_get_buf_info(buf);

	bi->zlp = false;
}

int udc_submit_event(const struct device *dev,
		     const enum udc_event_type type,
		     const int status,
		     struct net_buf *const buf)
{
	struct udc_data *data = dev->data;
	struct udc_event drv_evt = {
		.type = type,
		.buf = buf,
		.status = status,
		.dev = dev,
	};

	if (!udc_is_initialized(dev)) {
		return -EPERM;
	}

	return data->event_cb(dev, &drv_evt);
}

static uint8_t ep_attrib_get_transfer(uint8_t attributes)
{
	return attributes & USB_EP_TRANSFER_TYPE_MASK;
}

static bool ep_check_config(const struct device *dev,
			    const struct udc_ep_config *const cfg,
			    const uint8_t ep,
			    const uint8_t attributes,
			    const uint16_t mps,
			    const uint8_t interval)
{
	bool dir_is_in = USB_EP_DIR_IS_IN(ep);
	bool dir_is_out = USB_EP_DIR_IS_OUT(ep);

	LOG_DBG("cfg d:%c|%c t:%c|%c|%c|%c, mps %u",
		cfg->caps.in ? 'I' : '-',
		cfg->caps.out ? 'O' : '-',
		cfg->caps.iso ? 'S' : '-',
		cfg->caps.bulk ? 'B' : '-',
		cfg->caps.interrupt ? 'I' : '-',
		cfg->caps.control ? 'C' : '-',
		cfg->caps.mps);

	if (dir_is_out && !cfg->caps.out) {
		return false;
	}

	if (dir_is_in && !cfg->caps.in) {
		return false;
	}

	if (mps > cfg->caps.mps) {
		return false;
	}

	switch (ep_attrib_get_transfer(attributes)) {
	case USB_EP_TYPE_BULK:
		if (!cfg->caps.bulk) {
			return false;
		}
		break;
	case USB_EP_TYPE_INTERRUPT:
		if (!cfg->caps.interrupt) {
			return false;
		}
		break;
	case USB_EP_TYPE_ISO:
		if (!cfg->caps.iso) {
			return false;
		}
		break;
	case USB_EP_TYPE_CONTROL:
		if (!cfg->caps.control) {
			return false;
		}
		break;
	default:
		return false;
	}

	return true;
}

static void ep_update_mps(const struct device *dev,
			  const struct udc_ep_config *const cfg,
			  const uint8_t attributes,
			  uint16_t *const mps)
{
	struct udc_device_caps caps = udc_caps(dev);
	const uint16_t spec_iso_mps = caps.hs ? 1024 : 1023;
	const uint16_t spec_int_mps = caps.hs ? 1024 : 64;
	const uint16_t spec_bulk_mps = caps.hs ? 512 : 64;

	/*
	 * TODO: It does not take into account the actual speed of the
	 * bus after the RESET. Should be fixed/improved when the driver
	 * for high speed controller are ported.
	 */
	switch (ep_attrib_get_transfer(attributes)) {
	case USB_EP_TYPE_BULK:
		*mps = MIN(cfg->caps.mps, spec_bulk_mps);
		break;
	case USB_EP_TYPE_INTERRUPT:
		*mps = MIN(cfg->caps.mps, spec_int_mps);
		break;
	case USB_EP_TYPE_ISO:
		*mps = MIN(cfg->caps.mps, spec_iso_mps);
		break;
	case USB_EP_TYPE_CONTROL:
		*mps = 64U;
		break;
	default:
		return;
	}
}

int udc_ep_try_config(const struct device *dev,
		      const uint8_t ep,
		      const uint8_t attributes,
		      uint16_t *const mps,
		      const uint8_t interval)
{
	const struct udc_api *api = dev->api;
	struct udc_ep_config *cfg;
	bool ret;

	cfg = udc_get_ep_cfg(dev, ep);
	if (cfg == NULL) {
		return -ENODEV;
	}

	api->lock(dev);

	ret = ep_check_config(dev, cfg, ep, attributes, *mps, interval);
	if (ret == true && *mps == 0U) {
		ep_update_mps(dev, cfg, attributes, mps);
	}

	api->unlock(dev);

	return (ret == false) ? -ENOTSUP : 0;
}

int udc_ep_enable_internal(const struct device *dev,
			   const uint8_t ep,
			   const uint8_t attributes,
			   const uint16_t mps,
			   const uint8_t interval)
{
	const struct udc_api *api = dev->api;
	struct udc_ep_config *cfg;
	int ret;

	cfg = udc_get_ep_cfg(dev, ep);
	if (cfg == NULL) {
		return -ENODEV;
	}

	if (cfg->stat.enabled) {
		LOG_ERR("ep 0x%02x already enabled", cfg->addr);
		return -EALREADY;
	}

	if (!ep_check_config(dev, cfg, ep, attributes, mps, interval)) {
		LOG_ERR("Endpoint 0x%02x validation failed", cfg->addr);
		return -ENODEV;
	}

	cfg->attributes = attributes;
	cfg->mps = mps;
	cfg->interval = interval;

	cfg->stat.odd = 0;
	cfg->stat.halted = 0;
	cfg->stat.data1 = false;
	ret = api->ep_enable(dev, cfg);
	cfg->stat.enabled = ret ? false : true;

	return ret;
}

int udc_ep_enable(const struct device *dev,
		  const uint8_t ep,
		  const uint8_t attributes,
		  const uint16_t mps,
		  const uint8_t interval)
{
	const struct udc_api *api = dev->api;
	int ret;

	if (ep == USB_CONTROL_EP_OUT || ep == USB_CONTROL_EP_IN) {
		return -EINVAL;
	}

	api->lock(dev);

	if (!udc_is_enabled(dev)) {
		ret = -EPERM;
		goto ep_enable_error;
	}

	ret = udc_ep_enable_internal(dev, ep, attributes, mps, interval);

ep_enable_error:
	api->unlock(dev);

	return ret;
}

int udc_ep_disable_internal(const struct device *dev, const uint8_t ep)
{
	const struct udc_api *api = dev->api;
	struct udc_ep_config *cfg;
	int ret;

	cfg = udc_get_ep_cfg(dev, ep);
	if (cfg == NULL) {
		return -ENODEV;
	}

	if (!cfg->stat.enabled) {
		LOG_ERR("ep 0x%02x already disabled", cfg->addr);
		return -EALREADY;
	}

	ret = api->ep_disable(dev, cfg);
	cfg->stat.enabled = ret ? cfg->stat.enabled : false;

	return ret;
}

int udc_ep_disable(const struct device *dev, const uint8_t ep)
{
	const struct udc_api *api = dev->api;
	int ret;

	if (ep == USB_CONTROL_EP_OUT || ep == USB_CONTROL_EP_IN) {
		return -EINVAL;
	}

	api->lock(dev);

	if (!udc_is_initialized(dev)) {
		ret = -EPERM;
		goto ep_disable_error;
	}

	ret = udc_ep_disable_internal(dev, ep);

ep_disable_error:
	api->unlock(dev);

	return ret;
}

int udc_ep_set_halt(const struct device *dev, const uint8_t ep)
{
	const struct udc_api *api = dev->api;
	struct udc_ep_config *cfg;
	int ret;

	api->lock(dev);

	if (!udc_is_enabled(dev)) {
		ret = -EPERM;
		goto ep_set_halt_error;
	}

	cfg = udc_get_ep_cfg(dev, ep);
	if (cfg == NULL) {
		ret = -ENODEV;
		goto ep_set_halt_error;
	}

	if (!cfg->stat.enabled) {
		ret = -ENODEV;
		goto ep_set_halt_error;
	}

	if (ep_attrib_get_transfer(cfg->attributes) == USB_EP_TYPE_ISO) {
		ret = -ENOTSUP;
		goto ep_set_halt_error;
	}

	ret = api->ep_set_halt(dev, cfg);

ep_set_halt_error:
	api->unlock(dev);

	return ret;
}

int udc_ep_clear_halt(const struct device *dev, const uint8_t ep)
{
	const struct udc_api *api = dev->api;
	struct udc_ep_config *cfg;
	int ret;

	api->lock(dev);

	if (!udc_is_enabled(dev)) {
		ret = -EPERM;
		goto ep_clear_halt_error;
	}

	cfg = udc_get_ep_cfg(dev, ep);
	if (cfg == NULL) {
		ret = -ENODEV;
		goto ep_clear_halt_error;
	}

	if (!cfg->stat.enabled) {
		ret = -ENODEV;
		goto ep_clear_halt_error;
	}

	if (ep_attrib_get_transfer(cfg->attributes) == USB_EP_TYPE_ISO) {
		ret = -ENOTSUP;
		goto ep_clear_halt_error;
	}

	ret = api->ep_clear_halt(dev, cfg);
	if (ret == 0) {
		cfg->stat.halted = false;
	}

ep_clear_halt_error:
	api->unlock(dev);

	return ret;
}

int udc_ep_flush(const struct device *dev, const uint8_t ep)
{
	const struct udc_api *api = dev->api;
	struct udc_ep_config *cfg;
	int ret;

	api->lock(dev);

	if (!udc_is_enabled(dev)) {
		ret = -EPERM;
		goto ep_flush_error;
	}

	cfg = udc_get_ep_cfg(dev, ep);
	if (cfg == NULL) {
		ret = -ENODEV;
		goto ep_flush_error;
	}

	ret = api->ep_flush(dev, cfg);

ep_flush_error:
	api->unlock(dev);

	return ret;
}

static void udc_debug_ep_enqueue(const struct device *dev,
				 struct udc_ep_config *const cfg)
{
	struct udc_buf_info *bi;
	struct net_buf *buf;
	sys_slist_t list;

	list.head = k_fifo_peek_head(&cfg->fifo);
	list.tail = k_fifo_peek_tail(&cfg->fifo);
	if (list.head == NULL) {
		LOG_DBG("ep 0x%02x queue is empty", cfg->addr);
		return;
	}

	LOG_DBG("[de]queue ep 0x%02x:", cfg->addr);

	SYS_SLIST_FOR_EACH_CONTAINER(&list, buf, node) {
		bi = udc_get_buf_info(buf);
		LOG_DBG("|-> %p (%u) ->", buf, buf->size);
	}
}

int udc_ep_enqueue(const struct device *dev, struct net_buf *const buf)
{
	const struct udc_api *api = dev->api;
	struct udc_ep_config *cfg;
	struct udc_buf_info *bi;
	int ret;

	api->lock(dev);

	if (!udc_is_enabled(dev)) {
		ret = -EPERM;
		goto ep_enqueue_error;
	}

	bi = udc_get_buf_info(buf);
	if (bi->ep == USB_CONTROL_EP_OUT) {
		ret = -EPERM;
		goto ep_enqueue_error;
	}

	cfg = udc_get_ep_cfg(dev, bi->ep);
	if (cfg == NULL) {
		ret = -ENODEV;
		goto ep_enqueue_error;
	}

	LOG_DBG("Queue ep 0x%02x %p len %u", cfg->addr, buf,
		USB_EP_DIR_IS_IN(cfg->addr) ? buf->len : buf->size);

	bi->setup = 0;
	ret = api->ep_enqueue(dev, cfg, buf);

ep_enqueue_error:
	api->unlock(dev);

	return ret;
}

int udc_ep_dequeue(const struct device *dev, const uint8_t ep)
{
	const struct udc_api *api = dev->api;
	struct udc_ep_config *cfg;
	int ret;

	api->lock(dev);

	if (!udc_is_initialized(dev)) {
		ret = -EPERM;
		goto ep_dequeue_error;
	}

	cfg = udc_get_ep_cfg(dev, ep);
	if (cfg == NULL) {
		ret = -ENODEV;
		goto ep_dequeue_error;
	}

	if (cfg->stat.enabled || cfg->stat.halted) {
		LOG_INF("ep 0x%02x is not halted|disabled", cfg->addr);
	}

	if (UDC_COMMON_LOG_LEVEL == LOG_LEVEL_DBG) {
		udc_debug_ep_enqueue(dev, cfg);
	}

	if (k_fifo_is_empty(&cfg->fifo)) {
		ret = 0;
	} else  {
		ret = api->ep_dequeue(dev, cfg);
	}

ep_dequeue_error:
	api->unlock(dev);

	return ret;
}

struct net_buf *udc_ep_buf_alloc(const struct device *dev,
				 const uint8_t ep,
				 const size_t size)
{
	const struct udc_api *api = dev->api;
	struct net_buf *buf = NULL;
	struct udc_buf_info *bi;

	api->lock(dev);

	buf = net_buf_alloc_len(&udc_ep_pool, size, K_NO_WAIT);
	if (!buf) {
		LOG_ERR("Failed to allocate net_buf %zd", size);
		goto ep_alloc_error;
	}

	bi = udc_get_buf_info(buf);
	memset(bi, 0, sizeof(struct udc_buf_info));
	bi->ep = ep;
	LOG_DBG("Allocate net_buf, ep 0x%02x, size %zd", ep, size);

ep_alloc_error:
	api->unlock(dev);

	return buf;
}

struct net_buf *udc_ctrl_alloc(const struct device *dev,
			       const uint8_t ep,
			       const size_t size)
{
	/* TODO: for now just pass to udc_buf_alloc() */
	return udc_ep_buf_alloc(dev, ep, size);
}

static inline void udc_buf_destroy(struct net_buf *buf)
{
	/* Adjust level and use together with the log in udc_ep_buf_alloc() */
	LOG_DBG("destroy %p", buf);
	net_buf_destroy(buf);
}

int udc_ep_buf_free(const struct device *dev, struct net_buf *const buf)
{
	const struct udc_api *api = dev->api;
	int ret = 0;

	api->lock(dev);
	net_buf_unref(buf);
	api->unlock(dev);

	return ret;
}

enum udc_bus_speed udc_device_speed(const struct device *dev)
{
	const struct udc_api *api = dev->api;
	enum udc_bus_speed speed = UDC_BUS_UNKNOWN;

	api->lock(dev);

	if (!udc_is_enabled(dev)) {
		goto device_speed_error;
	}

	if (api->device_speed) {
		speed = api->device_speed(dev);
	} else {
		/* TODO: Shall we track connected status in UDC? */
		speed = UDC_BUS_SPEED_FS;
	}

device_speed_error:
	api->unlock(dev);

	return speed;
}

int udc_enable(const struct device *dev)
{
	const struct udc_api *api = dev->api;
	struct udc_data *data = dev->data;
	int ret;

	api->lock(dev);

	if (!udc_is_initialized(dev)) {
		ret = -EPERM;
		goto udc_enable_error;
	}

	if (udc_is_enabled(dev)) {
		ret = -EALREADY;
		goto udc_enable_error;
	}

	data->stage = CTRL_PIPE_STAGE_SETUP;

	ret = api->enable(dev);
	if (ret == 0) {
		atomic_set_bit(&data->status, UDC_STATUS_ENABLED);
	}

udc_enable_error:
	api->unlock(dev);

	return ret;
}

int udc_disable(const struct device *dev)
{
	const struct udc_api *api = dev->api;
	struct udc_data *data = dev->data;
	int ret;

	api->lock(dev);

	if (!udc_is_enabled(dev)) {
		ret = -EALREADY;
		goto udc_disable_error;
	}

	ret = api->disable(dev);
	atomic_clear_bit(&data->status, UDC_STATUS_ENABLED);

udc_disable_error:
	api->unlock(dev);

	return ret;
}

int udc_init(const struct device *dev, udc_event_cb_t event_cb)
{
	const struct udc_api *api = dev->api;
	struct udc_data *data = dev->data;
	int ret;

	if (event_cb == NULL) {
		return -EINVAL;
	}

	api->lock(dev);

	if (udc_is_initialized(dev)) {
		ret = -EALREADY;
		goto udc_init_error;
	}

	data->event_cb = event_cb;

	ret = api->init(dev);
	if (ret == 0) {
		atomic_set_bit(&data->status, UDC_STATUS_INITIALIZED);
	}

udc_init_error:
	api->unlock(dev);

	return ret;
}

int udc_shutdown(const struct device *dev)
{
	const struct udc_api *api = dev->api;
	struct udc_data *data = dev->data;
	int ret;

	api->lock(dev);

	if (udc_is_enabled(dev)) {
		ret = -EBUSY;
		goto udc_shutdown_error;
	}

	if (!udc_is_initialized(dev)) {
		ret = -EALREADY;
		goto udc_shutdown_error;
	}

	ret = api->shutdown(dev);
	atomic_clear_bit(&data->status, UDC_STATUS_INITIALIZED);

udc_shutdown_error:
	api->unlock(dev);

	return ret;
}

static ALWAYS_INLINE
struct net_buf *udc_ctrl_alloc_stage(const struct device *dev,
				     struct net_buf *const parent,
				     const uint8_t ep,
				     const size_t size)
{
	struct net_buf *buf;

	buf = udc_ctrl_alloc(dev, ep, size);
	if (buf == NULL) {
		return NULL;
	}

	if (parent) {
		net_buf_frag_add(parent, buf);
	}

	return buf;
}

static struct net_buf *udc_ctrl_alloc_data(const struct device *dev,
					   struct net_buf *const setup,
					   const uint8_t ep)
{
	size_t size = udc_data_stage_length(setup);
	struct udc_buf_info *bi;
	struct net_buf *buf;

	buf = udc_ctrl_alloc_stage(dev, setup, ep, size);
	if (buf) {
		bi = udc_get_buf_info(buf);
		bi->data = true;
	}

	return buf;
}

static struct net_buf *udc_ctrl_alloc_status(const struct device *dev,
					     struct net_buf *const parent,
					     const uint8_t ep)
{
	size_t size = (ep == USB_CONTROL_EP_OUT) ? 64 : 0;
	struct udc_buf_info *bi;
	struct net_buf *buf;

	buf = udc_ctrl_alloc_stage(dev, parent, ep, size);
	if (buf) {
		bi = udc_get_buf_info(buf);
		bi->status = true;
	}

	return buf;
}

int udc_ctrl_submit_s_out_status(const struct device *dev,
			      struct net_buf *const dout)
{
	struct udc_buf_info *bi = udc_get_buf_info(dout);
	struct udc_data *data = dev->data;
	struct net_buf *buf;
	int ret = 0;

	bi->data = true;
	net_buf_frag_add(data->setup, dout);

	buf = udc_ctrl_alloc_status(dev, dout, USB_CONTROL_EP_IN);
	if (buf == NULL) {
		ret = -ENOMEM;
	}

	return udc_submit_event(dev, UDC_EVT_EP_REQUEST, ret, data->setup);
}

int udc_ctrl_submit_s_in_status(const struct device *dev)
{
	struct udc_data *data = dev->data;
	struct net_buf *buf;
	int ret = 0;

	if (!udc_ctrl_stage_is_data_in(dev)) {
		return -ENOTSUP;
	}

	/* Allocate buffer for data stage IN */
	buf = udc_ctrl_alloc_data(dev, data->setup, USB_CONTROL_EP_IN);
	if (buf == NULL) {
		ret = -ENOMEM;
	}

	return udc_submit_event(dev, UDC_EVT_EP_REQUEST, ret, data->setup);
}

int udc_ctrl_submit_s_status(const struct device *dev)
{
	struct udc_data *data = dev->data;
	struct net_buf *buf;
	int ret = 0;

	/* Allocate buffer for possible status IN */
	buf = udc_ctrl_alloc_status(dev, data->setup, USB_CONTROL_EP_IN);
	if (buf == NULL) {
		ret = -ENOMEM;
	}

	return udc_submit_event(dev, UDC_EVT_EP_REQUEST, ret, data->setup);
}

int udc_ctrl_submit_status(const struct device *dev,
			   struct net_buf *const buf)
{
	struct udc_buf_info *bi = udc_get_buf_info(buf);

	bi->status = true;

	return udc_submit_event(dev, UDC_EVT_EP_REQUEST, 0, buf);
}

bool udc_ctrl_stage_is_data_out(const struct device *dev)
{
	struct udc_data *data = dev->data;

	return data->stage == CTRL_PIPE_STAGE_DATA_OUT ? true : false;
}

bool udc_ctrl_stage_is_data_in(const struct device *dev)
{
	struct udc_data *data = dev->data;

	return data->stage == CTRL_PIPE_STAGE_DATA_IN ? true : false;
}

bool udc_ctrl_stage_is_status_out(const struct device *dev)
{
	struct udc_data *data = dev->data;

	return data->stage == CTRL_PIPE_STAGE_STATUS_OUT ? true : false;
}

bool udc_ctrl_stage_is_status_in(const struct device *dev)
{
	struct udc_data *data = dev->data;

	return data->stage == CTRL_PIPE_STAGE_STATUS_IN ? true : false;
}

bool udc_ctrl_stage_is_no_data(const struct device *dev)
{
	struct udc_data *data = dev->data;

	return data->stage == CTRL_PIPE_STAGE_NO_DATA ? true : false;
}

static bool udc_data_stage_to_host(const struct net_buf *const buf)
{
	struct usb_setup_packet *setup = (void *)buf->data;

	return USB_REQTYPE_GET_DIR(setup->bmRequestType);
}

void udc_ctrl_update_stage(const struct device *dev,
			   struct net_buf *const buf)
{
	struct udc_buf_info *bi = udc_get_buf_info(buf);
	struct udc_device_caps caps = udc_caps(dev);
	uint8_t next_stage = CTRL_PIPE_STAGE_ERROR;
	struct udc_data *data = dev->data;

	__ASSERT(USB_EP_GET_IDX(bi->ep) == 0,
		 "0x%02x is not a control endpoint", bi->ep);

	if (bi->setup && bi->ep == USB_CONTROL_EP_OUT) {
		uint16_t length  = udc_data_stage_length(buf);

		data->setup = buf;

		if (data->stage != CTRL_PIPE_STAGE_SETUP) {
			LOG_INF("Sequence %u not completed", data->stage);
			data->stage = CTRL_PIPE_STAGE_SETUP;
		}

		/*
		 * Setup Stage has been completed (setup packet received),
		 * regardless of the previous stage, this is now being reset.
		 * Next state depends on wLength and the direction bit (D7).
		 */
		if (length == 0) {
			/*
			 * No Data Stage, next is Status Stage
			 * complete sequence: s->status
			 */
			LOG_DBG("s->(status)");
			next_stage = CTRL_PIPE_STAGE_NO_DATA;
		} else if (udc_data_stage_to_host(buf)) {
			/*
			 * Next is Data Stage (to host / IN)
			 * complete sequence: s->in->status
			 */
			LOG_DBG("s->(in)");
			next_stage = CTRL_PIPE_STAGE_DATA_IN;
		} else {
			/*
			 * Next is Data Stage (to device / OUT)
			 * complete sequence: s->out->status
			 */
			LOG_DBG("s->(out)");
			next_stage = CTRL_PIPE_STAGE_DATA_OUT;
		}

	} else if (bi->ep == USB_CONTROL_EP_OUT) {
		if (data->stage == CTRL_PIPE_STAGE_DATA_OUT) {
			/*
			 * Next sequence is Status Stage if request is okay,
			 * (IN ZLP status to host)
			 */
			next_stage = CTRL_PIPE_STAGE_STATUS_IN;
		} else if (data->stage == CTRL_PIPE_STAGE_STATUS_OUT) {
			/*
			 * End of a sequence: s->in->status,
			 * We should check the length here because we always
			 * submit a OUT request with the minimum length
			 * of the control endpoint.
			 */
			if (buf->len == 0) {
				LOG_DBG("s-in-status");
				next_stage = CTRL_PIPE_STAGE_SETUP;
			} else {
				LOG_WRN("ZLP expected");
				next_stage = CTRL_PIPE_STAGE_ERROR;
			}
		} else {
			LOG_ERR("Cannot determine the next stage");
			next_stage = CTRL_PIPE_STAGE_ERROR;
		}

	} else { /* if (bi->ep == USB_CONTROL_EP_IN) */
		if (data->stage == CTRL_PIPE_STAGE_STATUS_IN) {
			/*
			 * End of a sequence: setup->out->in
			 */
			LOG_DBG("s-out-status");
			next_stage = CTRL_PIPE_STAGE_SETUP;
		} else if (data->stage == CTRL_PIPE_STAGE_DATA_IN) {
			/*
			 * Data IN stage completed, next sequence
			 * is Status Stage (OUT ZLP status to device).
			 * over-engineered controllers can send status
			 * on their own, skip this state then.
			 */
			if (caps.out_ack) {
				LOG_DBG("s-in->[status]");
				next_stage = CTRL_PIPE_STAGE_SETUP;
			} else {
				LOG_DBG("s-in->(status)");
				next_stage = CTRL_PIPE_STAGE_STATUS_OUT;
			}
		} else if (data->stage == CTRL_PIPE_STAGE_NO_DATA) {
			/*
			 * End of a sequence (setup->in)
			 * Previous NO Data stage was completed and
			 * we confirmed it with an IN ZLP.
			 */
			LOG_DBG("s-status");
			next_stage = CTRL_PIPE_STAGE_SETUP;
		} else {
			LOG_ERR("Cannot determine the next stage");
			next_stage = CTRL_PIPE_STAGE_ERROR;
		}
	}


	if (next_stage == data->stage) {
		LOG_WRN("State not changed!");
	}

	data->stage = next_stage;
}

#if defined(CONFIG_UDC_WORKQUEUE)
K_KERNEL_STACK_DEFINE(udc_work_q_stack, CONFIG_UDC_WORKQUEUE_STACK_SIZE);

struct k_work_q udc_work_q;

static int udc_work_q_init(const struct device *dev)
{
	ARG_UNUSED(dev);

	k_work_queue_start(&udc_work_q,
			   udc_work_q_stack,
			   K_KERNEL_STACK_SIZEOF(udc_work_q_stack),
			   CONFIG_UDC_WORKQUEUE_PRIORITY, NULL);
	k_thread_name_set(&udc_work_q.thread, "udc_work_q");

	return 0;
}

SYS_INIT(udc_work_q_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
#endif
