/*
 * Copyright (c) 2017 PHYTEC Messtechnik GmbH
 * Copyright (c) 2022 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/*
 * Driver for the USBFSOTG device controller which can be found on
 * devices like Kinetis K64F.
 */
#define DT_DRV_COMPAT nxp_kinetis_usbd

#include <soc.h>
#include <string.h>
#include <stdio.h>

#include <zephyr/device.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/drivers/usb/udc.h>

#include "udc_common.h"

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(usbfsotg, CONFIG_UDC_DRIVER_LOG_LEVEL);

#define USBFSOTG_BD_OWN		BIT(5)
#define USBFSOTG_BD_DATA1	BIT(4)
#define USBFSOTG_BD_KEEP	BIT(3)
#define USBFSOTG_BD_NINC	BIT(2)
#define USBFSOTG_BD_DTS		BIT(1)
#define USBFSOTG_BD_STALL	BIT(0)

#define USBFSOTG_SETUP_TOKEN	0x0D
#define USBFSOTG_IN_TOKEN	0x09
#define USBFSOTG_OUT_TOKEN	0x01

#define USBFSOTG_PERID		0x04
#define USBFSOTG_REV		0x33

/*
 * Buffer Descriptor (BD) entry provides endpoint buffer control
 * information for USBFSOTG controller. Every endpoint direction requires
 * two BD entries.
 */
struct usbfsotg_bd {
	union {
		uint32_t bd_fields;

		struct {
			uint32_t reserved_1_0 : 2;
			uint32_t tok_pid : 4;
			uint32_t data1 : 1;
			uint32_t own : 1;
			uint32_t reserved_15_8 : 8;
			uint32_t bc : 16;
		} get __packed;

		struct {
			uint32_t reserved_1_0 : 2;
			uint32_t bd_ctrl : 6;
			uint32_t reserved_15_8 : 8;
			uint32_t bc : 16;
		} set __packed;

	} __packed;
	uint32_t   buf_addr;
} __packed;

struct usbfsotg_config {
	USB_Type *base;
	/*
	 * Pointer to Buffer Descriptor Table for the endpoints
	 * buffer management. The driver configuration with 16 fully
	 * bidirectional endpoints would require four BD entries
	 * per endpoint and 512 bytes of memory.
	 */
	struct usbfsotg_bd *bdt;
	void (*irq_enable_func)(const struct device *dev);
	void (*irq_disable_func)(const struct device *dev);
	size_t num_of_eps;
	struct udc_ep_config *ep_cfg_in;
	struct udc_ep_config *ep_cfg_out;
};

enum usbfsotg_event_type {
	/* Trigger next transfer, must not be used for control OUT */
	USBFSOTG_EVT_XFER,
	/* Setup packet received */
	USBFSOTG_EVT_SETUP,
	/* OUT transaction for specific endpoint is finished */
	USBFSOTG_EVT_DOUT,
	/* IN transaction for specific endpoint is finished */
	USBFSOTG_EVT_DIN,
	/* Workaround for clear halt in ISR */
	USBFSOTG_EVT_CLEAR_HALT,
};

/* Structure for driver's endpoint events */
struct usbfsotg_ep_event {
	sys_snode_t node;
	const struct device *dev;
	enum usbfsotg_event_type event;
	uint8_t ep;
};

K_MEM_SLAB_DEFINE(usbfsotg_ee_slab, sizeof(struct usbfsotg_ep_event),
		  CONFIG_UDC_KINETIS_EVENT_COUNT, sizeof(void *));

struct usbfsotg_data {
	struct k_work work;
	struct k_fifo fifo;
	/*
	 * Buffer pointers and busy flags used only for control OUT
	 * to map the buffers to BDs when both are occupied
	 */
	struct net_buf *out_buf[2];
	bool busy[2];
};

static int usbfsotg_ep_clear_halt(const struct device *dev,
				  struct udc_ep_config *const cfg);

/* Get buffer descriptor (BD) based on endpoint address */
static struct usbfsotg_bd *usbfsotg_get_ebd(const struct device *const dev,
					    struct udc_ep_config *const cfg,
					    const bool opposite)
{
	const struct usbfsotg_config *config = dev->config;
	uint8_t bd_idx;

	bd_idx = USB_EP_GET_IDX(cfg->addr) * 4U + (cfg->stat.odd ^ opposite);
	if (USB_EP_DIR_IS_IN(cfg->addr)) {
		bd_idx += 2U;
	}

	return &config->bdt[bd_idx];
}

static bool usbfsotg_bd_is_busy(const struct usbfsotg_bd *const bd)
{
	/* Do not use it for control OUT endpoint */
	return bd->get.own;
}

static void usbfsotg_bd_set_ctrl(struct usbfsotg_bd *const bd,
				 const size_t bc,
				 uint8_t *const data,
				 const bool data1)
{
	bd->set.bc = bc;
	bd->buf_addr = POINTER_TO_UINT(data);

	if (data1) {
		bd->set.bd_ctrl = USBFSOTG_BD_OWN | USBFSOTG_BD_DATA1 |
				  USBFSOTG_BD_DTS;
	} else {
		bd->set.bd_ctrl = USBFSOTG_BD_OWN | USBFSOTG_BD_DTS;
	}

}

/* Resume TX token processing, see USBx_CTL field descriptions */
static ALWAYS_INLINE void usbfsotg_resume_tx(const struct device *dev)
{
	const struct usbfsotg_config *config = dev->config;
	USB_Type *base = config->base;

	base->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
}

/* Initiate a new transfer, must not be used for control endpoint OUT */
static int usbfsotg_xfer_start(const struct device *dev,
			       struct udc_ep_config *const cfg)
{
	const struct usbfsotg_config *config = dev->config;
	USB_Type *base = config->base;
	struct usbfsotg_bd *bd;
	struct net_buf *buf;
	uint8_t *data_ptr;
	size_t len;

	buf = udc_buf_peek(dev, cfg->addr, true);
	if (buf == NULL) {
		return -ENODATA;
	}

	bd = usbfsotg_get_ebd(dev, cfg, false);
	if (usbfsotg_bd_is_busy(bd)) {
		LOG_DBG("ep 0x%02x buf busy", cfg->addr);
		return -EBUSY;
	}

	if (USB_EP_DIR_IS_OUT(cfg->addr)) {
		len = MIN(net_buf_tailroom(buf), cfg->mps);
		data_ptr = net_buf_tail(buf);
	} else {
		len = MIN(buf->len, cfg->mps);
		data_ptr = buf->data;
	}

	usbfsotg_bd_set_ctrl(bd, len, data_ptr, cfg->stat.data1);

	if (USB_EP_GET_IDX(cfg->addr) == 0U) {
		usbfsotg_resume_tx(dev);
	}

	LOG_DBG("xfer %p, bd %p, ENDPT 0x%x, bd field 0x%02x",
		buf, bd, base->ENDPOINT[USB_EP_GET_IDX(cfg->addr)].ENDPT,
		bd->bd_fields);

	return 0;
}

static inline int usbfsotg_ctrl_feed_start(const struct device *dev,
					   struct net_buf *const buf)
{
	struct usbfsotg_data *priv = udc_get_private(dev);
	struct udc_ep_config *cfg;
	struct usbfsotg_bd *bd;
	size_t length;

	cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT);
	if (priv->busy[cfg->stat.odd]) {
		return -EBUSY;
	}

	bd = usbfsotg_get_ebd(dev, cfg, false);
	length = MIN(net_buf_tailroom(buf), cfg->mps);

	priv->out_buf[cfg->stat.odd] = buf;
	priv->busy[cfg->stat.odd] = true;
	usbfsotg_bd_set_ctrl(bd, length, net_buf_tail(buf), cfg->stat.data1);
	LOG_DBG("ep0 %p|odd: %u|d: %u", buf, cfg->stat.odd, cfg->stat.data1);

	return 0;
}

static inline int usbfsotg_ctrl_feed_start_next(const struct device *dev,
						struct net_buf *const buf)
{
	struct usbfsotg_data *priv = udc_get_private(dev);
	struct udc_ep_config *cfg;
	struct usbfsotg_bd *bd;
	size_t length;

	cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT);
	if (priv->busy[!cfg->stat.odd]) {
		return -EBUSY;
	}

	bd = usbfsotg_get_ebd(dev, cfg, true);
	length = MIN(net_buf_tailroom(buf), cfg->mps);

	priv->out_buf[!cfg->stat.odd] = buf;
	priv->busy[!cfg->stat.odd] = true;
	usbfsotg_bd_set_ctrl(bd, length, net_buf_tail(buf), cfg->stat.data1);
	LOG_DBG("ep0 %p|odd: %u|d: %u (n)", buf, cfg->stat.odd, cfg->stat.data1);

	return 0;
}

/*
 * Allocate buffer and initiate a new control OUT transfer,
 * use successive buffer descriptor when next is true.
 */
static int usbfsotg_ctrl_feed_dout(const struct device *dev,
				   const size_t length,
				   const bool next,
				   const bool resume_tx)
{
	struct net_buf *buf;
	int ret;

	buf = udc_ctrl_alloc(dev, USB_CONTROL_EP_OUT, length);
	if (buf == NULL) {
		return -ENOMEM;
	}

	if (next) {
		ret = usbfsotg_ctrl_feed_start_next(dev, buf);
	} else {
		ret = usbfsotg_ctrl_feed_start(dev, buf);
	}

	if (ret) {
		net_buf_unref(buf);
		return ret;
	}

	if (resume_tx) {
		usbfsotg_resume_tx(dev);
	}

	return 0;
}

static inline int work_handler_setup(const struct device *dev)
{
	struct net_buf *buf;
	int err;

	buf = udc_buf_get(dev, USB_CONTROL_EP_OUT, true);
	if (buf == NULL) {
		return -ENODATA;
	}

	/* Update to next stage of control transfer */
	udc_ctrl_update_stage(dev, buf);

	if (udc_ctrl_stage_is_data_out(dev)) {
		/*  Allocate and feed buffer for data OUT stage */
		LOG_DBG("s:%p|feed for -out-", buf);
		err = usbfsotg_ctrl_feed_dout(dev, udc_data_stage_length(buf),
					      false, true);
		if (err == -ENOMEM) {
			err = udc_submit_event(dev, UDC_EVT_EP_REQUEST, err, buf);
		}
	} else if (udc_ctrl_stage_is_data_in(dev)) {
		/*
		 * Here we have to feed both descriptor tables so that
		 * no setup packets are lost in case of successive
		 * status OUT stage and next setup.
		 */
		LOG_DBG("s:%p|feed for -in-status >setup", buf);
		err = usbfsotg_ctrl_feed_dout(dev, 8U, false, false);
		if (err == 0) {
			err = usbfsotg_ctrl_feed_dout(dev, 8U, true, true);
		}

		/* Finally alloc buffer for IN and submit to upper layer */
		if (err == 0) {
			err = udc_ctrl_submit_s_in_status(dev);
		}
	} else {
		LOG_DBG("s:%p|feed >setup", buf);
		/*
		 * For all other cases we feed with a buffer
		 * large enough for setup packet.
		 */
		err = usbfsotg_ctrl_feed_dout(dev, 8U, false, true);
		if (err == 0) {
			err = udc_ctrl_submit_s_status(dev);
		}
	}

	return err;
}

static inline int work_handler_out(const struct device *dev,
				   const uint8_t ep)
{
	struct net_buf *buf;
	int err = 0;

	buf = udc_buf_get(dev, ep, true);
	if (buf == NULL) {
		return -ENODATA;
	}

	if (ep == USB_CONTROL_EP_OUT) {
		if (udc_ctrl_stage_is_status_out(dev)) {
			/* s-in-status finished, next bd is already fed */
			LOG_DBG("dout:%p|no feed", buf);
			/* Status stage finished, notify upper layer */
			udc_ctrl_submit_status(dev, buf);
		} else {
			/*
			 * For all other cases we feed with a buffer
			 * large enough for setup packet.
			 */
			LOG_DBG("dout:%p|feed >setup", buf);
			err = usbfsotg_ctrl_feed_dout(dev, 8U, false, false);
		}

		/* Update to next stage of control transfer */
		udc_ctrl_update_stage(dev, buf);

		if (udc_ctrl_stage_is_status_in(dev)) {
			err = udc_ctrl_submit_s_out_status(dev, buf);
		}
	} else {
		err = udc_submit_event(dev, UDC_EVT_EP_REQUEST, 0, buf);
	}

	return err;
}

static inline int work_handler_in(const struct device *dev,
				  const uint8_t ep)
{
	struct net_buf *buf;

	buf = udc_buf_get(dev, ep, true);
	if (buf == NULL) {
		return -ENODATA;
	}

	if (ep == USB_CONTROL_EP_IN) {
		if (udc_ctrl_stage_is_status_in(dev) ||
		    udc_ctrl_stage_is_no_data(dev)) {
			/* Status stage finished, notify upper layer */
			udc_ctrl_submit_status(dev, buf);
		}

		/* Update to next stage of control transfer */
		udc_ctrl_update_stage(dev, buf);

		if (udc_ctrl_stage_is_status_out(dev)) {
			/*
			 * IN transfer finished, release buffer,
			 * control OUT buffer should be already fed.
			 */
			net_buf_unref(buf);
		}

		return 0;
	}

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

static void usbfsotg_event_submit(const struct device *dev,
				 const uint8_t ep,
				 const enum usbfsotg_event_type event)
{
	struct usbfsotg_data *priv = udc_get_private(dev);
	struct usbfsotg_ep_event *ev;
	int ret;

	ret = k_mem_slab_alloc(&usbfsotg_ee_slab, (void **)&ev, K_NO_WAIT);
	if (ret) {
		udc_submit_event(dev, UDC_EVT_ERROR, ret, NULL);
	}

	ev->dev = dev;
	ev->ep = ep;
	ev->event = event;
	k_fifo_put(&priv->fifo, ev);
	k_work_submit_to_queue(udc_get_work_q(), &priv->work);
}

static void xfer_work_handler(struct k_work *item)
{
	struct usbfsotg_ep_event *ev;
	struct usbfsotg_data *priv;

	priv = CONTAINER_OF(item, struct usbfsotg_data, work);
	while ((ev = k_fifo_get(&priv->fifo, K_NO_WAIT)) != NULL) {
		struct udc_ep_config *ep_cfg;
		int err = 0;

		LOG_DBG("dev %p, ep 0x%02x, event %u",
			ev->dev, ev->ep, ev->event);
		ep_cfg = udc_get_ep_cfg(ev->dev, ev->ep);
		if (unlikely(ep_cfg == NULL)) {
			udc_submit_event(ev->dev, UDC_EVT_ERROR, -ENODATA, NULL);
			goto xfer_work_error;
		}

		switch (ev->event) {
		case USBFSOTG_EVT_SETUP:
			err = work_handler_setup(ev->dev);
			break;
		case USBFSOTG_EVT_DOUT:
			err = work_handler_out(ev->dev, ev->ep);
			break;
		case USBFSOTG_EVT_DIN:
			err = work_handler_in(ev->dev, ev->ep);
			break;
		case USBFSOTG_EVT_CLEAR_HALT:
			err = usbfsotg_ep_clear_halt(ev->dev, ep_cfg);
		case USBFSOTG_EVT_XFER:
		default:
			break;
		}

		if (unlikely(err)) {
			udc_submit_event(ev->dev, UDC_EVT_ERROR, err, NULL);
		}

		/* Peek next transer */
		if (ev->ep != USB_CONTROL_EP_OUT) {
			usbfsotg_xfer_start(ev->dev, ep_cfg);
		}

xfer_work_error:
		k_mem_slab_free(&usbfsotg_ee_slab, (void **)&ev);
	}
}

static ALWAYS_INLINE uint8_t stat_reg_get_ep(const uint8_t status)
{
	uint8_t ep_idx = status >> USB_STAT_ENDP_SHIFT;

	return (status & USB_STAT_TX_MASK) ? (USB_EP_DIR_IN | ep_idx) : ep_idx;
}

static ALWAYS_INLINE bool stat_reg_is_odd(const uint8_t status)
{
	return (status & USB_STAT_ODD_MASK) >> USB_STAT_ODD_SHIFT;
}

static ALWAYS_INLINE void set_control_in_pid_data1(const struct device *dev)
{
	struct udc_ep_config *ep_cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_IN);

	/* Set DATA1 PID for data or status stage */
	ep_cfg->stat.data1 = true;
}

static ALWAYS_INLINE void isr_handle_xfer_done(const struct device *dev,
					       const uint8_t istatus,
					       const uint8_t status)
{
	struct usbfsotg_data *priv = udc_get_private(dev);
	uint8_t ep = stat_reg_get_ep(status);
	bool odd = stat_reg_is_odd(status);
	struct usbfsotg_bd *bd, *bd_op;
	struct udc_ep_config *ep_cfg;
	struct net_buf *buf;
	uint8_t token_pid;
	bool data1;
	size_t len;

	ep_cfg = udc_get_ep_cfg(dev, ep);
	bd = usbfsotg_get_ebd(dev, ep_cfg, false);
	bd_op = usbfsotg_get_ebd(dev, ep_cfg, true);
	token_pid = bd->get.tok_pid;
	len  = bd->get.bc;
	data1 = bd->get.data1 ? true : false;

	LOG_DBG("TOKDNE, ep 0x%02x len %u odd %u data1 %u",
		ep, len, odd, data1);

	switch (token_pid) {
	case USBFSOTG_SETUP_TOKEN:
		ep_cfg->stat.odd = !odd;
		ep_cfg->stat.data1 = true;
		set_control_in_pid_data1(dev);

		if (priv->out_buf[odd] != NULL) {
			net_buf_add(priv->out_buf[odd], len);
			udc_ep_buf_set_setup(priv->out_buf[odd]);
			udc_buf_put(ep_cfg, priv->out_buf[odd]);
			priv->busy[odd] = false;
			priv->out_buf[odd] = NULL;
			usbfsotg_event_submit(dev, ep, USBFSOTG_EVT_SETUP);
		} else {
			LOG_ERR("No buffer for ep 0x00");
			udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS, NULL);
		}

		break;
	case USBFSOTG_OUT_TOKEN:
		ep_cfg->stat.odd = !odd;
		ep_cfg->stat.data1 = !data1;

		if (ep == USB_CONTROL_EP_OUT) {
			buf = priv->out_buf[odd];
			priv->busy[odd] = false;
			priv->out_buf[odd] = NULL;
		} else {
			buf = udc_buf_peek(dev, ep_cfg->addr, true);
		}

		if (buf == NULL) {
			LOG_ERR("No buffer for ep 0x%02x", ep);
			udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS, NULL);
			break;
		}

		net_buf_add(buf, len);
		if (net_buf_tailroom(buf) >= ep_cfg->mps && len == ep_cfg->mps) {
			if (ep == USB_CONTROL_EP_OUT) {
				usbfsotg_ctrl_feed_start(dev, buf);
			} else {
				usbfsotg_xfer_start(dev, ep_cfg);
			}
		} else {
			if (ep == USB_CONTROL_EP_OUT) {
				udc_buf_put(ep_cfg, buf);
			}

			usbfsotg_event_submit(dev, ep, USBFSOTG_EVT_DOUT);
		}

		break;
	case USBFSOTG_IN_TOKEN:
		ep_cfg->stat.odd = !odd;
		ep_cfg->stat.data1 = !data1;

		buf = udc_buf_peek(dev, ep_cfg->addr, true);
		if (buf == NULL) {
			LOG_ERR("No buffer for ep 0x%02x", ep);
			udc_submit_event(dev, UDC_EVT_ERROR, -ENOBUFS, NULL);
			break;
		}

		net_buf_pull(buf, len);
		if (buf->len) {
			usbfsotg_xfer_start(dev, ep_cfg);
		} else {
			if (udc_ep_buf_has_zlp(buf)) {
				usbfsotg_xfer_start(dev, ep_cfg);
				udc_ep_buf_clear_zlp(buf);
				break;
			}

			usbfsotg_event_submit(dev, ep, USBFSOTG_EVT_DIN);
		}

		break;
	default:
		break;
	}
}

static void usbfsotg_isr_handler(const struct device *dev)
{
	const struct usbfsotg_config *config = dev->config;
	USB_Type *base = config->base;
	const uint8_t istatus  = base->ISTAT;
	const uint8_t status  = base->STAT;

	if (istatus & USB_ISTAT_USBRST_MASK) {
		base->ADDR = 0U;
		udc_submit_event(dev, UDC_EVT_RESET, 0, NULL);
	}

	if (istatus == USB_ISTAT_ERROR_MASK) {
		LOG_DBG("ERROR IRQ 0x%02x", base->ERRSTAT);
		udc_submit_event(dev, UDC_EVT_ERROR, base->ERRSTAT, NULL);
		base->ERRSTAT = 0xFF;
	}

	if (istatus & USB_ISTAT_STALL_MASK) {
		struct udc_ep_config *ep_cfg;

		LOG_DBG("STALL sent");

		ep_cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT);
		if (ep_cfg->stat.halted) {
			/*
			 * usbfsotg_ep_clear_halt(dev, ep_cfg); cannot
			 * be called in ISR context
			 */
			usbfsotg_event_submit(dev, USB_CONTROL_EP_OUT,
					      USBFSOTG_EVT_CLEAR_HALT);
		}

		ep_cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_IN);
		if (ep_cfg->stat.halted) {
			usbfsotg_event_submit(dev, USB_CONTROL_EP_IN,
					      USBFSOTG_EVT_CLEAR_HALT);
		}
	}

	if (istatus & USB_ISTAT_TOKDNE_MASK) {
		isr_handle_xfer_done(dev, istatus, status);
	}

	if (istatus & USB_ISTAT_SLEEP_MASK) {
		LOG_DBG("SLEEP IRQ");
		/* Enable resume interrupt */
		base->INTEN |= USB_INTEN_RESUMEEN_MASK;

		udc_set_suspended(dev, true);
		udc_submit_event(dev, UDC_EVT_SUSPEND, 0, NULL);
	}

	if (istatus & USB_ISTAT_RESUME_MASK) {
		LOG_DBG("RESUME IRQ");
		/* Disable resume interrupt */
		base->INTEN &= ~USB_INTEN_RESUMEEN_MASK;

		udc_set_suspended(dev, false);
		udc_submit_event(dev, UDC_EVT_RESUME, 0, NULL);
	}

	/* Clear interrupt status bits */
	base->ISTAT = istatus;
}

static int usbfsotg_ep_enqueue(const struct device *dev,
			       struct udc_ep_config *const cfg,
			       struct net_buf *const buf)
{

	udc_buf_put(cfg, buf);
	if (cfg->stat.halted) {
		LOG_DBG("ep 0x%02x halted", cfg->addr);
		return 0;
	}

	usbfsotg_event_submit(dev, cfg->addr, USBFSOTG_EVT_XFER);

	return 0;
}

static int usbfsotg_ep_dequeue(const struct device *dev,
			       struct udc_ep_config *const cfg)
{
	struct usbfsotg_bd *bd;
	unsigned int lock_key;
	struct net_buf *buf;

	bd = usbfsotg_get_ebd(dev, cfg, false);

	lock_key = irq_lock();
	bd->set.bd_ctrl = USBFSOTG_BD_DTS;
	irq_unlock(lock_key);

	cfg->stat.halted = false;
	buf = udc_buf_get_all(dev, cfg->addr);
	if (buf) {
		udc_submit_event(dev, UDC_EVT_EP_REQUEST, -ECONNABORTED, buf);
	}

	return 0;
}

static int usbfsotg_ep_flush(const struct device *dev,
			     struct udc_ep_config *const cfg)
{
	return -ENOTSUP;
}

static void ctrl_drop_out_successor(const struct device *dev)
{
	struct usbfsotg_data *priv = udc_get_private(dev);
	struct udc_ep_config *cfg;
	struct usbfsotg_bd *bd;
	struct net_buf *buf;

	cfg = udc_get_ep_cfg(dev, USB_CONTROL_EP_OUT);

	if (priv->busy[!cfg->stat.odd]) {
		bd = usbfsotg_get_ebd(dev, cfg, true);
		buf = priv->out_buf[!cfg->stat.odd];

		bd->bd_fields = 0U;
		priv->busy[!cfg->stat.odd] = false;
		if (buf) {
			net_buf_unref(buf);
		}
	}
}

static int usbfsotg_ep_set_halt(const struct device *dev,
				struct udc_ep_config *const cfg)
{
	struct usbfsotg_bd *bd;

	bd = usbfsotg_get_ebd(dev, cfg, false);
	bd->set.bd_ctrl = USBFSOTG_BD_STALL | USBFSOTG_BD_DTS | USBFSOTG_BD_OWN;
	cfg->stat.halted = true;
	LOG_DBG("Halt ep 0x%02x bd %p", cfg->addr, bd);

	if (cfg->addr == USB_CONTROL_EP_IN) {
		/* Drop subsequent out transfer, current can be re-used */
		ctrl_drop_out_successor(dev);
	}

	if (USB_EP_GET_IDX(cfg->addr) == 0U) {
		usbfsotg_resume_tx(dev);
	}

	return 0;
}

static int usbfsotg_ep_clear_halt(const struct device *dev,
				  struct udc_ep_config *const cfg)
{
	const struct usbfsotg_config *config = dev->config;
	struct usbfsotg_data *priv = udc_get_private(dev);
	USB_Type *base = config->base;
	uint8_t ep_idx = USB_EP_GET_IDX(cfg->addr);
	struct usbfsotg_bd *bd;

	LOG_DBG("Clear halt ep 0x%02x", cfg->addr);
	bd = usbfsotg_get_ebd(dev, cfg, false);

	if (bd->set.bd_ctrl & USBFSOTG_BD_STALL) {
		LOG_DBG("bd %p: %x", bd, bd->set.bd_ctrl);
		bd->set.bd_ctrl = USBFSOTG_BD_DTS;
	} else {
		LOG_WRN("bd %p is not halted", bd);
	}

	cfg->stat.data1 = false;
	cfg->stat.halted = false;
	base->ENDPOINT[ep_idx].ENDPT &= ~USB_ENDPT_EPSTALL_MASK;

	if (cfg->addr == USB_CONTROL_EP_OUT) {
		if (priv->busy[cfg->stat.odd]) {
			LOG_DBG("bd %p restarted", bd);
			bd->set.bd_ctrl = USBFSOTG_BD_DTS | USBFSOTG_BD_OWN;
		} else {
			usbfsotg_ctrl_feed_dout(dev, 8U, false, false);
		}
	}

	if (USB_EP_GET_IDX(cfg->addr) == 0U) {
		usbfsotg_resume_tx(dev);
	} else {
		/* TODO: trigger queued transfers? */
	}

	return 0;
}

static int usbfsotg_ep_enable(const struct device *dev,
			      struct udc_ep_config *const cfg)
{
	const struct usbfsotg_config *config = dev->config;
	struct usbfsotg_data *priv = udc_get_private(dev);
	USB_Type *base = config->base;
	const uint8_t ep_idx = USB_EP_GET_IDX(cfg->addr);
	struct usbfsotg_bd *bd_even, *bd_odd;

	LOG_DBG("Enable ep 0x%02x", cfg->addr);
	bd_even = usbfsotg_get_ebd(dev, cfg, false);
	bd_odd = usbfsotg_get_ebd(dev, cfg, true);

	bd_even->bd_fields = 0U;
	bd_even->buf_addr = 0U;
	bd_odd->bd_fields = 0U;
	bd_odd->buf_addr = 0U;

	switch (cfg->attributes & USB_EP_TRANSFER_TYPE_MASK) {
	case USB_EP_TYPE_CONTROL:
		base->ENDPOINT[ep_idx].ENDPT = (USB_ENDPT_EPHSHK_MASK |
						USB_ENDPT_EPRXEN_MASK |
						USB_ENDPT_EPTXEN_MASK);
		break;
	case USB_EP_TYPE_BULK:
	case USB_EP_TYPE_INTERRUPT:
		base->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPHSHK_MASK;
		if (USB_EP_DIR_IS_OUT(cfg->addr)) {
			base->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPRXEN_MASK;
		} else {
			base->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPTXEN_MASK;
		}
		break;
	case USB_EP_TYPE_ISO:
		if (USB_EP_DIR_IS_OUT(cfg->addr)) {
			base->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPRXEN_MASK;
		} else {
			base->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPTXEN_MASK;
		}
		break;
	default:
		return -EINVAL;
	}

	if (cfg->addr == USB_CONTROL_EP_OUT) {
		struct net_buf *buf;

		buf = udc_ctrl_alloc(dev, USB_CONTROL_EP_OUT, 64);
		usbfsotg_bd_set_ctrl(bd_even, buf->size, buf->data, false);
		priv->out_buf[0] = buf;
	}

	return 0;
}

static int usbfsotg_ep_disable(const struct device *dev,
			       struct udc_ep_config *const cfg)
{
	const struct usbfsotg_config *config = dev->config;
	USB_Type *base = config->base;
	uint8_t ep_idx = USB_EP_GET_IDX(cfg->addr);
	struct usbfsotg_bd *bd_even, *bd_odd;

	bd_even = usbfsotg_get_ebd(dev, cfg, false);
	bd_odd = usbfsotg_get_ebd(dev, cfg, true);

	if (USB_EP_DIR_IS_OUT(cfg->addr)) {
		base->ENDPOINT[ep_idx].ENDPT &= ~USB_ENDPT_EPRXEN_MASK;
	} else {
		base->ENDPOINT[ep_idx].ENDPT &= ~USB_ENDPT_EPTXEN_MASK;
	}

	if (usbfsotg_bd_is_busy(bd_even) || usbfsotg_bd_is_busy(bd_odd)) {
		LOG_DBG("Endpoint buffer is busy");
	}

	bd_even->bd_fields = 0U;
	bd_even->buf_addr = 0U;
	bd_odd->bd_fields = 0U;
	bd_odd->buf_addr = 0U;

	LOG_DBG("Disable ep 0x%02x", cfg->addr);

	return 0;
}

static int usbfsotg_host_wakeup(const struct device *dev)
{
	return -ENOTSUP;
}

static int usbfsotg_set_address(const struct device *dev, const uint8_t addr)
{
	const struct usbfsotg_config *config = dev->config;
	USB_Type *base = config->base;

	base->ADDR = addr;

	return 0;
}

static int usbfsotg_enable(const struct device *dev)
{
	const struct usbfsotg_config *config = dev->config;
	USB_Type *base = config->base;

	/* non-OTG device mode, enable DP Pullup */
	base->CONTROL = USB_CONTROL_DPPULLUPNONOTG_MASK;

	return 0;
}

static int usbfsotg_disable(const struct device *dev)
{
	const struct usbfsotg_config *config = dev->config;
	USB_Type *base = config->base;

	/* disable USB and DP Pullup */
	base->CTL  &= ~USB_CTL_USBENSOFEN_MASK;
	base->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK;

	return 0;
}

static bool usbfsotg_is_supported(const struct device *dev)
{
	const struct usbfsotg_config *config = dev->config;
	USB_Type *base = config->base;

	if ((base->PERID != USBFSOTG_PERID) || (base->REV != USBFSOTG_REV)) {
		return false;
	}

	return true;
}

static int usbfsotg_init(const struct device *dev)
{
	const struct usbfsotg_config *config = dev->config;
	USB_Type *base = config->base;

	/* (FIXME) Enable USB voltage regulator */
	SIM->SOPT1 |= SIM_SOPT1_USBREGEN_MASK;

	/* Reset USB module */
	base->USBTRC0 |= USB_USBTRC0_USBRESET_MASK;
	k_busy_wait(2000);

	/* enable USB module, AKA USBEN bit in CTL1 register */
	base->CTL = USB_CTL_USBENSOFEN_MASK;

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

	for (uint8_t i = 0; i < 16U; i++) {
		base->ENDPOINT[i].ENDPT = 0;
	}

	base->BDTPAGE1 = (uint8_t)(POINTER_TO_UINT(config->bdt) >> 8);
	base->BDTPAGE2 = (uint8_t)(POINTER_TO_UINT(config->bdt) >> 16);
	base->BDTPAGE3 = (uint8_t)(POINTER_TO_UINT(config->bdt) >> 24);

	/* (FIXME) Enables the weak pulldowns on the USB transceiver */
	base->USBCTRL = USB_USBCTRL_PDE_MASK;

	/* Clear interrupt flags */
	base->ISTAT = 0xFF;
	/* Clear error flags */
	base->ERRSTAT = 0xFF;

	/* Enable all error interrupt sources */
	base->ERREN = 0xFF;
	/* Enable reset interrupt */
	base->INTEN = (USB_INTEN_SLEEPEN_MASK  |
		       USB_INTEN_STALLEN_MASK |
		       USB_INTEN_TOKDNEEN_MASK |
		       USB_INTEN_SOFTOKEN_MASK |
		       USB_INTEN_ERROREN_MASK |
		       USB_INTEN_USBRSTEN_MASK);

	if (udc_ep_enable_internal(dev, USB_CONTROL_EP_OUT,
				   USB_EP_TYPE_CONTROL, 64, 0)) {
		LOG_ERR("Failed to enable control endpoint");
		return -EIO;
	}

	if (udc_ep_enable_internal(dev, USB_CONTROL_EP_IN,
				   USB_EP_TYPE_CONTROL, 64, 0)) {
		LOG_ERR("Failed to enable control endpoint");
		return -EIO;
	}

	/* Connect and enable USB interrupt */
	config->irq_enable_func(dev);

	LOG_DBG("Initialized USB controller %p", base);

	return 0;
}

static int usbfsotg_shutdown(const struct device *dev)
{
	const struct usbfsotg_config *config = dev->config;

	config->irq_disable_func(dev);

	if (udc_ep_disable_internal(dev, USB_CONTROL_EP_OUT)) {
		LOG_ERR("Failed to disable control endpoint");
		return -EIO;
	}

	if (udc_ep_disable_internal(dev, USB_CONTROL_EP_IN)) {
		LOG_ERR("Failed to disable control endpoint");
		return -EIO;
	}

	/* Disable USB module */
	config->base->CTL = 0;

	/* Disable USB voltage regulator */
	SIM->SOPT1 &= ~SIM_SOPT1_USBREGEN_MASK;

	return 0;
}

static int usbfsotg_lock(const struct device *dev)
{
	return udc_lock_internal(dev, K_FOREVER);
}

static int usbfsotg_unlock(const struct device *dev)
{
	return udc_unlock_internal(dev);
}

static int usbfsotg_driver_preinit(const struct device *dev)
{
	const struct usbfsotg_config *config = dev->config;
	struct udc_data *data = dev->data;
	struct usbfsotg_data *priv = data->priv;
	int err;

	k_mutex_init(&data->mutex);
	k_fifo_init(&priv->fifo);
	k_work_init(&priv->work, xfer_work_handler);

	for (int i = 0; i < config->num_of_eps; i++) {
		config->ep_cfg_out[i].caps.out = 1;
		if (i == 0) {
			config->ep_cfg_out[i].caps.control = 1;
			config->ep_cfg_out[i].caps.mps = 64;
		} else {
			config->ep_cfg_out[i].caps.bulk = 1;
			config->ep_cfg_out[i].caps.interrupt = 1;
			config->ep_cfg_out[i].caps.iso = 1;
			config->ep_cfg_out[i].caps.mps = 1023;
		}

		config->ep_cfg_out[i].addr = USB_EP_DIR_OUT | i;
		err = udc_register_ep(dev, &config->ep_cfg_out[i]);
		if (err != 0) {
			LOG_ERR("Failed to register endpoint");
			return err;
		}
	}

	for (int i = 0; i < config->num_of_eps; i++) {
		config->ep_cfg_in[i].caps.in = 1;
		if (i == 0) {
			config->ep_cfg_in[i].caps.control = 1;
			config->ep_cfg_in[i].caps.mps = 64;
		} else {
			config->ep_cfg_in[i].caps.bulk = 1;
			config->ep_cfg_in[i].caps.interrupt = 1;
			config->ep_cfg_in[i].caps.iso = 1;
			config->ep_cfg_in[i].caps.mps = 1023;
		}

		config->ep_cfg_in[i].addr = USB_EP_DIR_IN | i;
		err = udc_register_ep(dev, &config->ep_cfg_in[i]);
		if (err != 0) {
			LOG_ERR("Failed to register endpoint");
			return err;
		}
	}

	data->caps.rwup = false;

	return 0;
}

static const struct udc_api usbfsotg_api = {
	.ep_enqueue = usbfsotg_ep_enqueue,
	.ep_dequeue = usbfsotg_ep_dequeue,
	.ep_flush = usbfsotg_ep_flush,
	.ep_set_halt = usbfsotg_ep_set_halt,
	.ep_clear_halt = usbfsotg_ep_clear_halt,
	.ep_try_config = NULL,
	.ep_enable = usbfsotg_ep_enable,
	.ep_disable = usbfsotg_ep_disable,
	.host_wakeup = usbfsotg_host_wakeup,
	.set_address = usbfsotg_set_address,
	.enable = usbfsotg_enable,
	.disable = usbfsotg_disable,
	.init = usbfsotg_init,
	.shutdown = usbfsotg_shutdown,
	.lock = usbfsotg_lock,
	.unlock = usbfsotg_unlock,
};

#define USBFSOTG_DEVICE_DEFINE(n)						\
	static void udc_irq_enable_func##n(const struct device *dev)		\
	{									\
		IRQ_CONNECT(DT_INST_IRQN(n),					\
			    DT_INST_IRQ(n, priority),				\
			    usbfsotg_isr_handler,				\
			    DEVICE_DT_INST_GET(n), 0);				\
										\
		irq_enable(DT_INST_IRQN(n));					\
	}									\
										\
	static void udc_irq_disable_func##n(const struct device *dev)		\
	{									\
		irq_disable(DT_INST_IRQN(n));					\
	}									\
										\
	static struct usbfsotg_bd __aligned(512)				\
		bdt_##n[DT_INST_PROP(n, num_bidir_endpoints) * 2 * 2];		\
										\
	static struct udc_ep_config						\
		ep_cfg_out[DT_INST_PROP(n, num_bidir_endpoints)];		\
	static struct udc_ep_config						\
		ep_cfg_in[DT_INST_PROP(n, num_bidir_endpoints)];		\
										\
	static struct usbfsotg_config priv_config_##n = {			\
		.base = (USB_Type *)DT_INST_REG_ADDR(n),			\
		.bdt = bdt_##n,							\
		.irq_enable_func = udc_irq_enable_func##n,			\
		.irq_disable_func = udc_irq_disable_func##n,			\
		.num_of_eps = DT_INST_PROP(n, num_bidir_endpoints),		\
		.ep_cfg_in = ep_cfg_out,					\
		.ep_cfg_out = ep_cfg_in,					\
	};									\
										\
	static struct usbfsotg_data priv_data_##n = {				\
	};									\
										\
	static struct udc_data udc_data_##n = {					\
		.mutex = Z_MUTEX_INITIALIZER(udc_data_##n.mutex),		\
		.priv = &priv_data_##n,						\
	};									\
										\
	DEVICE_DT_INST_DEFINE(n, usbfsotg_driver_preinit, NULL,			\
			      &udc_data_##n, &priv_config_##n,			\
			      POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,	\
			      &usbfsotg_api);

DT_INST_FOREACH_STATUS_OKAY(USBFSOTG_DEVICE_DEFINE)
