/*
 * 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 udc_data *data = dev->data;
	struct udc_event drv_evt = {
		.type = type,
		.status = status,
		.dev = dev,
	};

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

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

int udc_submit_ep_event(const struct device *dev,
			struct net_buf *const buf,
			const int err)
{
	struct udc_buf_info *bi = udc_get_buf_info(buf);
	struct udc_data *data = dev->data;
	const struct udc_event drv_evt = {
		.type = UDC_EVT_EP_REQUEST,
		.buf = buf,
		.dev = dev,
	};

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

	bi->err = err;

	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_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_CONTROL:
		__fallthrough;
	case USB_EP_TYPE_ISO:
		__fallthrough;
	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;
}

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_ep_event(dev, data->setup, ret);
}

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_ep_event(dev, data->setup, ret);
}

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_ep_event(dev, data->setup, ret);
}

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_ep_event(dev, buf, 0);
}

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(void)
{

	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
