/*
 * Copyright (c) 2021 Gerson Fernando Budke <nandojve@gmail.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT atmel_sam_usbc

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(usb_dc_sam_usbc, CONFIG_USB_DRIVER_LOG_LEVEL);

#include <zephyr/kernel.h>
#include <zephyr/usb/usb_device.h>
#include <soc.h>
#include <string.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/barrier.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/irq.h>

#define EP_UDINT_MASK           0x000FF000

#define NUM_OF_EP_MAX           DT_INST_PROP(0, num_bidir_endpoints)
#define USBC_RAM_ADDR           DT_REG_ADDR(DT_NODELABEL(sram1))
#define USBC_RAM_SIZE           DT_REG_SIZE(DT_NODELABEL(sram1))

/**
 * @brief USB Driver Control Endpoint Finite State Machine states
 *
 * FSM states to keep tracking of control endpoint hidden states.
 */
enum usb_dc_epctrl_state {
	/* Wait a SETUP packet */
	USB_EPCTRL_SETUP,
	/* Wait a OUT data packet */
	USB_EPCTRL_DATA_OUT,
	/* Wait a IN data packet */
	USB_EPCTRL_DATA_IN,
	/* Wait a IN ZLP packet */
	USB_EPCTRL_HANDSHAKE_WAIT_IN_ZLP,
	/* Wait a OUT ZLP packet */
	USB_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP,
	/* STALL enabled on IN & OUT packet */
	USB_EPCTRL_STALL_REQ,
};

struct sam_usbc_udesc_sizes {
	uint32_t byte_count:15;
	uint32_t reserved:1;
	uint32_t multi_packet_size:15;
	uint32_t auto_zlp:1;
};

struct sam_usbc_udesc_bk_ctrl_stat {
	uint32_t stallrq:1;
	uint32_t reserved1:15;
	uint32_t crcerri:1;
	uint32_t overfi:1;
	uint32_t underfi:1;
	uint32_t reserved2:13;
};

struct sam_usbc_udesc_ep_ctrl_stat {
	uint32_t pipe_dev_addr:7;
	uint32_t reserved1:1;
	uint32_t pipe_num:4;
	uint32_t pipe_error_cnt_max:4;
	uint32_t pipe_error_status:8;
	uint32_t reserved2:8;
};

struct sam_usbc_desc_table {
	uint8_t *ep_pipe_addr;
	union {
		uint32_t sizes;
		struct sam_usbc_udesc_sizes udesc_sizes;
	};
	union {
		uint32_t bk_ctrl_stat;
		struct sam_usbc_udesc_bk_ctrl_stat udesc_bk_ctrl_stat;
	};
	union {
		uint32_t ep_ctrl_stat;
		struct sam_usbc_udesc_ep_ctrl_stat udesc_ep_ctrl_stat;
	};
};

struct usb_device_ep_data {
	usb_dc_ep_callback cb_in;
	usb_dc_ep_callback cb_out;
	uint16_t mps;
	bool mps_x2;
	bool is_configured;
	uint32_t out_at;
};

struct usb_device_data {
	usb_dc_status_callback status_cb;
	struct usb_device_ep_data ep_data[NUM_OF_EP_MAX];
};

static struct sam_usbc_desc_table dev_desc[(NUM_OF_EP_MAX + 1) * 2];
static struct usb_device_data dev_data;
static volatile Usbc *regs = (Usbc *) DT_INST_REG_ADDR(0);
PINCTRL_DT_INST_DEFINE(0);
static const struct pinctrl_dev_config *pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0);
static enum usb_dc_epctrl_state epctrl_fsm;
static const char *const usb_dc_epctrl_state_string[] = {
	"STP",
	"DOUT",
	"DIN",
	"IN_ZLP",
	"OUT_ZLP",
	"STALL",
};

#if defined(CONFIG_USB_DRIVER_LOG_LEVEL_DBG)
static uint32_t dev_ep_sta_dbg[2][NUM_OF_EP_MAX];

static void usb_dc_sam_usbc_isr_sta_dbg(uint32_t ep_idx, uint32_t sr)
{
	if (regs->UESTA[ep_idx] != dev_ep_sta_dbg[0][ep_idx]) {
		dev_ep_sta_dbg[0][ep_idx] = regs->UESTA[ep_idx];
		dev_ep_sta_dbg[1][ep_idx] = 0;

		LOG_INF("ISR[%d] CON=%08x INT=%08x INTE=%08x "
			"ECON=%08x ESTA=%08x%s", ep_idx,
			regs->UDCON, regs->UDINT, regs->UDINTE,
			regs->UECON[ep_idx], regs->UESTA[ep_idx],
			((sr & USBC_UESTA0_RXSTPI) ? " STP" : ""));
	} else if (dev_ep_sta_dbg[0][ep_idx] != dev_ep_sta_dbg[1][ep_idx]) {
		dev_ep_sta_dbg[1][ep_idx] = dev_ep_sta_dbg[0][ep_idx];

		LOG_INF("ISR[%d] CON=%08x INT=%08x INTE=%08x "
			"ECON=%08x ESTA=%08x LOOP", ep_idx,
			regs->UDCON, regs->UDINT, regs->UDINTE,
			regs->UECON[ep_idx], regs->UESTA[ep_idx]);
	}
}

static void usb_dc_sam_usbc_clean_sta_dbg(void)
{
	for (int i = 0; i < NUM_OF_EP_MAX; i++) {
		dev_ep_sta_dbg[0][i] = 0;
		dev_ep_sta_dbg[1][i] = 0;
	}
}
#else
#define usb_dc_sam_usbc_isr_sta_dbg(ep_idx, sr)
#define usb_dc_sam_usbc_clean_sta_dbg()
#endif

static ALWAYS_INLINE bool usb_dc_sam_usbc_is_frozen_clk(void)
{
	return USBC->USBCON & USBC_USBCON_FRZCLK;
}

static ALWAYS_INLINE void usb_dc_sam_usbc_freeze_clk(void)
{
	USBC->USBCON |= USBC_USBCON_FRZCLK;
}

static ALWAYS_INLINE void usb_dc_sam_usbc_unfreeze_clk(void)
{
	USBC->USBCON &= ~USBC_USBCON_FRZCLK;

	while (USBC->USBCON & USBC_USBCON_FRZCLK) {
		;
	};
}

static uint8_t usb_dc_sam_usbc_ep_curr_bank(uint8_t ep_idx)
{
	uint8_t idx = ep_idx * 2;

	if ((ep_idx > 0) &&
	    (regs->UESTA[ep_idx] & USBC_UESTA0_CURRBK(1)) > 0) {
		idx++;
	}

	return idx;
}

static bool usb_dc_is_attached(void)
{
	return (regs->UDCON & USBC_UDCON_DETACH) == 0;
}

static bool usb_dc_ep_is_enabled(uint8_t ep_idx)
{
	int reg = regs->UERST;

	return (reg & BIT(USBC_UERST_EPEN0_Pos + ep_idx));
}

static int usb_dc_sam_usbc_ep_alloc_buf(int ep_idx)
{
	struct sam_usbc_desc_table *ep_desc_bk;
	bool ep_enabled[NUM_OF_EP_MAX];
	int desc_mem_alloc;
	int mps;

	if (ep_idx >= NUM_OF_EP_MAX) {
		return -EINVAL;
	}

	desc_mem_alloc = 0;

	mps = dev_data.ep_data[ep_idx].mps_x2
	    ? dev_data.ep_data[ep_idx].mps * 2
	    : dev_data.ep_data[ep_idx].mps;

	/* Check if there are memory to all endpoints */
	for (int i = 0; i < NUM_OF_EP_MAX; i++) {
		if (!dev_data.ep_data[i].is_configured || i == ep_idx) {
			continue;
		}

		desc_mem_alloc += dev_data.ep_data[i].mps_x2
				? dev_data.ep_data[i].mps * 2
				: dev_data.ep_data[i].mps;
	}

	if ((desc_mem_alloc + mps) > USBC_RAM_SIZE) {
		memset(&dev_data.ep_data[ep_idx], 0,
		       sizeof(struct usb_device_ep_data));
		return -ENOMEM;
	}

	for (int i = NUM_OF_EP_MAX - 1; i >= ep_idx; i--) {
		ep_enabled[i] = usb_dc_ep_is_enabled(i);
		if (ep_enabled[i]) {
			usb_dc_ep_disable(i);
		}
	}

	desc_mem_alloc = 0U;
	for (int i = 0; i < ep_idx; i++) {
		if (!dev_data.ep_data[i].is_configured) {
			continue;
		}

		desc_mem_alloc += dev_data.ep_data[i].mps_x2
				? dev_data.ep_data[i].mps * 2
				: dev_data.ep_data[i].mps;
	}

	ep_desc_bk = ((struct sam_usbc_desc_table *) &dev_desc)
		   + (ep_idx * 2);
	for (int i = ep_idx; i < NUM_OF_EP_MAX; i++) {
		if (!dev_data.ep_data[i].is_configured && (i != ep_idx)) {
			ep_desc_bk += 2;
			continue;
		}

		/* Alloc bank 0 */
		ep_desc_bk->ep_pipe_addr = ((uint8_t *) USBC_RAM_ADDR)
					 + desc_mem_alloc;
		ep_desc_bk->sizes = 0;
		ep_desc_bk->bk_ctrl_stat = 0;
		ep_desc_bk->ep_ctrl_stat = 0;
		ep_desc_bk++;

		/**
		 * Alloc bank 1
		 *
		 * if dual bank,
		 * then ep_pipe_addr[1] = ep_pipe_addr[0] address + mps size
		 * else ep_pipe_addr[1] = ep_pipe_addr[0] address
		 */
		ep_desc_bk->ep_pipe_addr = ((uint8_t *) USBC_RAM_ADDR)
					 + desc_mem_alloc
					 + (dev_data.ep_data[i].mps_x2
					 ?  dev_data.ep_data[i].mps
					 :  0);
		ep_desc_bk->sizes = 0;
		ep_desc_bk->bk_ctrl_stat = 0;
		ep_desc_bk->ep_ctrl_stat = 0;
		ep_desc_bk++;

		desc_mem_alloc += dev_data.ep_data[i].mps_x2
				? dev_data.ep_data[i].mps * 2
				: dev_data.ep_data[i].mps;
	}

	ep_enabled[ep_idx] = false;
	for (int i = ep_idx; i < NUM_OF_EP_MAX; i++) {
		if (ep_enabled[i]) {
			usb_dc_ep_enable(i);
		}
	}
	return 0;
}

static void usb_dc_ep_enable_interrupts(uint8_t ep_idx)
{
	if (ep_idx == 0U) {
		/* Control endpoint: enable SETUP */
		regs->UECONSET[ep_idx] = USBC_UECON0SET_RXSTPES;
	} else if (regs->UECFG[ep_idx] & USBC_UECFG0_EPDIR_IN) {
		/* TX - IN direction: acknowledge FIFO empty interrupt */
		regs->UESTACLR[ep_idx] = USBC_UESTA0CLR_TXINIC;
		regs->UECONSET[ep_idx] = USBC_UECON0SET_TXINES;
	} else {
		/* RX - OUT direction */
		regs->UECONSET[ep_idx] = USBC_UECON0SET_RXOUTES;
	}
}

static void usb_dc_ep_isr_sta(uint8_t ep_idx)
{
	uint32_t sr = regs->UESTA[ep_idx];

	usb_dc_sam_usbc_isr_sta_dbg(ep_idx, sr);

	if (sr & USBC_UESTA0_RAMACERI) {
		regs->UESTACLR[ep_idx] = USBC_UESTA0CLR_RAMACERIC;
		LOG_ERR("ISR: EP%d RAM Access Error", ep_idx);
	}
}

static void usb_dc_ctrl_init(void)
{
	LOG_INF("STP - INIT");

	/* In case of abort of IN Data Phase:
	 * No need to abort IN transfer (rise TXINI),
	 * because it is automatically done by hardware when a Setup packet is
	 * received. But the interrupt must be disabled to don't generate
	 * interrupt TXINI after SETUP reception.
	 */
	regs->UECONCLR[0] = USBC_UECON0CLR_TXINEC;

	/* In case of OUT ZLP event is no processed before Setup event occurs */
	regs->UESTACLR[0] = USBC_UESTA0CLR_RXOUTIC;
	regs->UECONCLR[0] = USBC_UECON0CLR_RXOUTEC
			  | USBC_UECON0CLR_NAKOUTEC
			  | USBC_UECON0CLR_NAKINEC;

	epctrl_fsm = USB_EPCTRL_SETUP;
}

static void usb_dc_ctrl_stall_data(uint32_t flags)
{
	LOG_INF("STP - STALL");

	epctrl_fsm = USB_EPCTRL_STALL_REQ;

	regs->UECONSET[0] = USBC_UECON0SET_STALLRQS;
	regs->UESTACLR[0] = flags;
}

static void usb_dc_ctrl_send_zlp_in(void)
{
	uint32_t key;

	LOG_INF("STP - ZLP IN");

	epctrl_fsm = USB_EPCTRL_HANDSHAKE_WAIT_IN_ZLP;

	/* Validate and send empty IN packet on control endpoint */
	dev_desc[0].sizes = 0;

	key = irq_lock();

	/* Send ZLP on IN endpoint */
	regs->UESTACLR[0] = USBC_UESTA0CLR_TXINIC;
	regs->UECONSET[0] = USBC_UECON0SET_TXINES;

	/* To detect a protocol error, enable nak interrupt on data OUT phase */
	regs->UESTACLR[0] = USBC_UESTA0CLR_NAKOUTIC;
	regs->UECONSET[0] = USBC_UECON0SET_NAKOUTES;
	irq_unlock(key);
}

static void usb_dc_ctrl_send_zlp_out(void)
{
	uint32_t key;

	LOG_INF("STP - ZLP OUT");

	epctrl_fsm = USB_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP;

	/* To detect a protocol error, enable nak interrupt on data IN phase */
	key = irq_lock();
	regs->UESTACLR[0] = USBC_UESTA0CLR_NAKINIC;
	regs->UECONSET[0] = USBC_UECON0SET_NAKINES;
	irq_unlock(key);
}

static void usb_dc_ep0_isr(void)
{
	uint32_t sr = regs->UESTA[0];
	uint32_t dev_ctrl = regs->UDCON;

	usb_dc_ep_isr_sta(0);

	regs->UECONCLR[0] = USBC_UECON0CLR_NAKINEC;
	regs->UECONCLR[0] = USBC_UECON0CLR_NAKOUTEC;

	if (sr & USBC_UESTA0_RXSTPI) {
		/* May be a hidden DATA or ZLP phase or protocol abort */
		if (epctrl_fsm != USB_EPCTRL_SETUP) {
			/* Reinitializes control endpoint management */
			usb_dc_ctrl_init();
		}

		/* SETUP data received */
		dev_data.ep_data[0].cb_out(USB_EP_DIR_OUT, USB_DC_EP_SETUP);
		return;
	}

	if (sr & USBC_UESTA0_RXOUTI) {
		LOG_DBG("RXOUT= fsm: %s",
			usb_dc_epctrl_state_string[epctrl_fsm]);

		if (epctrl_fsm != USB_EPCTRL_DATA_OUT) {
			if ((epctrl_fsm == USB_EPCTRL_DATA_IN)
			||  (epctrl_fsm == USB_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP)) {
				/* End of SETUP request:
				 * - Data IN Phase aborted,
				 * - or last Data IN Phase hidden by ZLP OUT
				 *   sending quickly,
				 * - or ZLP OUT received normally.
				 *
				 * Nothing to do
				 */
			} else {
				/* Protocol error during SETUP request */
				usb_dc_ctrl_stall_data(0);
			}

			usb_dc_ctrl_init();
			return;
		}

		/* OUT (to device) data received */
		dev_data.ep_data[0].cb_out(USB_EP_DIR_OUT, USB_DC_EP_DATA_OUT);
		return;
	}

	if ((sr & USBC_UESTA0_TXINI) &&
	    (regs->UECON[0] & USBC_UECON0_TXINE)) {
		LOG_DBG("TXINI= fsm: %s",
			usb_dc_epctrl_state_string[epctrl_fsm]);

		regs->UECONCLR[0] = USBC_UECON0CLR_TXINEC;

		if (epctrl_fsm == USB_EPCTRL_HANDSHAKE_WAIT_IN_ZLP) {
			if (!(dev_ctrl & USBC_UDCON_ADDEN)
			&&   (dev_ctrl & USBC_UDCON_UADD_Msk) != 0U) {
				/* Commit the pending address update.  This
				 * must be done after the ack to the host
				 * completes else the ack will get dropped.
				 */
				regs->UDCON |= USBC_UDCON_ADDEN;
			}

			/* ZLP on IN is sent */
			usb_dc_ctrl_init();
			return;
		}

		/* IN (to host) transmit complete */
		dev_data.ep_data[0].cb_in(USB_EP_DIR_IN, USB_DC_EP_DATA_IN);
		return;
	}

	if (sr & USBC_UESTA0_NAKOUTI) {
		LOG_DBG("NAKOUT= fsm: %s",
			usb_dc_epctrl_state_string[epctrl_fsm]);

		regs->UESTACLR[0] = USBC_UESTA0CLR_NAKOUTIC;

		if (regs->UESTA[0] & USBC_UESTA0_TXINI) {
			/** overflow ignored if IN data is received */
			return;
		}

		if (epctrl_fsm == USB_EPCTRL_HANDSHAKE_WAIT_IN_ZLP) {
			/* A IN handshake is waiting by device, but host want
			 * extra OUT data then stall extra OUT data
			 */
			regs->UECONSET[0] = USBC_UECON0SET_STALLRQS;
		}
		return;
	}

	if (sr & USBC_UESTA0_NAKINI) {
		LOG_DBG("NAKIN= fsm: %s",
			usb_dc_epctrl_state_string[epctrl_fsm]);

		regs->UESTACLR[0] = USBC_UESTA0CLR_NAKINIC;

		if (regs->UESTA[0] & USBC_UESTA0_RXOUTI) {
			/** underflow ignored if OUT data is received */
			return;
		}

		if (epctrl_fsm == USB_EPCTRL_DATA_OUT) {
			/* Host want to stop OUT transaction then stop to
			 * wait OUT data phase and wait IN ZLP handshake.
			 */
			usb_dc_ctrl_send_zlp_in();
		} else if (epctrl_fsm == USB_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP) {
			/* A OUT handshake is waiting by device, but host want
			 * extra IN data then stall extra IN data.
			 */
			regs->UECONSET[0] = USBC_UECON0SET_STALLRQS;
		} else {
			/** Nothing to do */
		}
		return;
	}
}

static void usb_dc_ep_isr(uint8_t ep_idx)
{
	uint32_t sr = regs->UESTA[ep_idx];

	usb_dc_ep_isr_sta(ep_idx);

	if (sr & USBC_UESTA0_RXOUTI) {
		uint8_t ep = ep_idx | USB_EP_DIR_OUT;

		regs->UESTACLR[ep_idx] = USBC_UESTA0CLR_RXOUTIC;

		/* OUT (to device) data received */
		dev_data.ep_data[ep_idx].cb_out(ep, USB_DC_EP_DATA_OUT);
	}
	if (sr & USBC_UESTA0_TXINI) {
		uint8_t ep = ep_idx | USB_EP_DIR_IN;

		regs->UESTACLR[ep_idx] = USBC_UESTA0CLR_TXINIC;

		/* IN (to host) transmit complete */
		dev_data.ep_data[ep_idx].cb_in(ep, USB_DC_EP_DATA_IN);
	}
}

static void usb_dc_sam_usbc_isr(void)
{
	uint32_t sr = regs->UDINT;

	if (IS_ENABLED(CONFIG_USB_DEVICE_SOF)) {
		/* SOF interrupt */
		if (sr & USBC_UDINT_SOF) {
			/* Acknowledge the interrupt */
			regs->UDINTCLR = USBC_UDINTCLR_SOFC;

			dev_data.status_cb(USB_DC_SOF, NULL);

			goto usb_dc_sam_usbc_isr_barrier;
		}
	}

	/* EP0 endpoint interrupt */
	if (sr & USBC_UDINT_EP0INT) {
		usb_dc_ep0_isr();

		goto usb_dc_sam_usbc_isr_barrier;
	}

	/* Other endpoints interrupt */
	if (sr & EP_UDINT_MASK) {
		for (int ep_idx = 1; ep_idx < NUM_OF_EP_MAX; ep_idx++) {
			if (sr & (USBC_UDINT_EP0INT << ep_idx)) {
				usb_dc_ep_isr(ep_idx);
			}
		}

		goto usb_dc_sam_usbc_isr_barrier;
	}

	/* End of resume interrupt */
	if (sr & USBC_UDINT_EORSM) {
		LOG_DBG("ISR: End Of Resume");

		regs->UDINTCLR = USBC_UDINTCLR_EORSMC;

		dev_data.status_cb(USB_DC_RESUME, NULL);

		goto usb_dc_sam_usbc_isr_barrier;
	}

	/* End of reset interrupt */
	if (sr & USBC_UDINT_EORST) {
		LOG_DBG("ISR: End Of Reset");

		regs->UDINTCLR = USBC_UDINTCLR_EORSTC;

		if (usb_dc_ep_is_enabled(0)) {
			/* The device clears some of the configuration of EP0
			 * when it receives the EORST. Re-enable interrupts.
			 */
			usb_dc_ep_enable_interrupts(0);
			usb_dc_ctrl_init();
		}

		dev_data.status_cb(USB_DC_RESET, NULL);

		usb_dc_sam_usbc_clean_sta_dbg();

		goto usb_dc_sam_usbc_isr_barrier;
	}

	/* Suspend interrupt */
	if (sr & USBC_UDINT_SUSP && regs->UDINTE & USBC_UDINTE_SUSPE) {
		LOG_DBG("ISR: Suspend");

		regs->UDINTCLR = USBC_UDINTCLR_SUSPC;

		usb_dc_sam_usbc_unfreeze_clk();

		/**
		 * Sync Generic Clock
		 * Check USB clock ready after suspend and
		 * eventually sleep USB clock
		 */
		while ((regs->USBSTA & USBC_USBSTA_CLKUSABLE) == 0) {
			;
		};

		regs->UDINTECLR = USBC_UDINTECLR_SUSPEC;
		regs->UDINTCLR = USBC_UDINTCLR_WAKEUPC;
		regs->UDINTESET = USBC_UDINTESET_WAKEUPES;

		usb_dc_sam_usbc_freeze_clk();

		dev_data.status_cb(USB_DC_SUSPEND, NULL);

		goto usb_dc_sam_usbc_isr_barrier;
	}

	/* Wakeup interrupt */
	if (sr & USBC_UDINT_WAKEUP && regs->UDINTE & USBC_UDINTE_WAKEUPE) {
		LOG_DBG("ISR: Wake Up");

		regs->UDINTCLR = USBC_UDINTCLR_WAKEUPC;

		usb_dc_sam_usbc_unfreeze_clk();

		/**
		 * Sync Generic Clock
		 * Check USB clock ready after suspend and
		 * eventually sleep USB clock
		 */
		while ((regs->USBSTA & USBC_USBSTA_CLKUSABLE) == 0) {
			;
		};

		regs->UDINTECLR = USBC_UDINTECLR_WAKEUPEC;
		regs->UDINTCLR = USBC_UDINTCLR_SUSPC;
		regs->UDINTESET = USBC_UDINTESET_SUSPES;
	}

usb_dc_sam_usbc_isr_barrier:
	barrier_dmem_fence_full();
}

int usb_dc_attach(void)
{
	uint32_t pmcon;
	uint32_t regval;
	uint32_t key = irq_lock();
	int retval;

	/* Enable USBC asynchronous wake-up source */
	PM->AWEN |= BIT(PM_AWEN_USBC);

	/* Always authorize asynchronous USB interrupts to exit of sleep mode
	 * For SAM USB wake up device except BACKUP mode
	 */
	pmcon = BPM->PMCON | BPM_PMCON_FASTWKUP;
	BPM->UNLOCK = BPM_UNLOCK_KEY(0xAAu)
		    | BPM_UNLOCK_ADDR((uint32_t)&BPM->PMCON - (uint32_t)BPM);
	BPM->PMCON = pmcon;

	/* Start the peripheral clock PBB & DATA */
	soc_pmc_peripheral_enable(
		PM_CLOCK_MASK(PM_CLK_GRP_PBB, SYSCLK_USBC_REGS));
	soc_pmc_peripheral_enable(
		PM_CLOCK_MASK(PM_CLK_GRP_HSB, SYSCLK_USBC_DATA));

	/* Enable USB Generic clock */
	SCIF->GCCTRL[GEN_CLK_USBC] = 0;
	SCIF->GCCTRL[GEN_CLK_USBC] = SCIF_GCCTRL_OSCSEL(SCIF_GC_USES_CLK_HSB)
				   | SCIF_GCCTRL_CEN;

	/* Sync Generic Clock */
	while ((regs->USBSTA & USBC_USBSTA_CLKUSABLE) == 0) {
		;
	};

	retval = pinctrl_apply_state(pcfg, PINCTRL_STATE_DEFAULT);
	if (retval < 0) {
		return retval;
	}

	/* Enable the USB controller in device mode with the clock unfrozen */
	regs->USBCON = USBC_USBCON_UIMOD | USBC_USBCON_USBE;

	usb_dc_sam_usbc_unfreeze_clk();

	regs->UDESC = USBC_UDESC_UDESCA((int) &dev_desc);

	/* Select the speed with pads detached */
	regval = USBC_UDCON_DETACH;

	switch (DT_INST_ENUM_IDX(0, maximum_speed)) {
	case 1:
		WRITE_BIT(regval, USBC_UDCON_LS_Pos, 0);
		break;
	case 0:
		WRITE_BIT(regval, USBC_UDCON_LS_Pos, 1);
		break;
	default:
		WRITE_BIT(regval, USBC_UDCON_LS_Pos, 0);
		LOG_WRN("Unsupported maximum speed defined in device tree. "
			"USB controller will default to its maximum HW "
			"capability");
	}

	regs->UDCON = regval;

	/* Enable device interrupts
	 *  EORSM	End of Resume Interrupt
	 *  SOF		Start of Frame Interrupt
	 *  EORST	End of Reset Interrupt
	 *  SUSP	Suspend Interrupt
	 *  WAKEUP	Wake-Up Interrupt
	 */
	regs->UDINTCLR = USBC_UDINTCLR_EORSMC
		       | USBC_UDINTCLR_EORSTC
		       | USBC_UDINTCLR_SOFC
		       | USBC_UDINTCLR_SUSPC
		       | USBC_UDINTCLR_WAKEUPC;

	regs->UDINTESET = USBC_UDINTESET_EORSMES
			| USBC_UDINTESET_EORSTES
			| USBC_UDINTESET_SUSPES
			| USBC_UDINTESET_WAKEUPES;

	if (IS_ENABLED(CONFIG_USB_DEVICE_SOF)) {
		regs->UDINTESET |= USBC_UDINTESET_SOFES;
	}

	IRQ_CONNECT(DT_INST_IRQN(0),
		    DT_INST_IRQ(0, priority),
		    usb_dc_sam_usbc_isr, 0, 0);
	irq_enable(DT_INST_IRQN(0));

	/* Attach the device */
	regs->UDCON &= ~USBC_UDCON_DETACH;

	/* Put USB on low power state (wait Susp/Wake int) */
	usb_dc_sam_usbc_freeze_clk();

	/* Force Susp 2 Wake transition */
	regs->UDINTSET = USBC_UDINTSET_SUSPS;

	irq_unlock(key);

	LOG_DBG("USB DC attach");
	return 0;
}

int usb_dc_detach(void)
{
	uint32_t key = irq_lock();

	regs->UDCON |= USBC_UDCON_DETACH;

	/* Disable the USB controller and freeze the clock */
	regs->USBCON = USBC_USBCON_UIMOD | USBC_USBCON_FRZCLK;

	/* Disable USB Generic clock */
	SCIF->GCCTRL[GEN_CLK_USBC] = 0;

	/* Disable USBC asynchronous wake-up source */
	PM->AWEN &= ~(BIT(PM_AWEN_USBC));

	/* Disable the peripheral clock HSB & PBB */
	soc_pmc_peripheral_enable(
		PM_CLOCK_MASK(PM_CLK_GRP_HSB, SYSCLK_USBC_DATA));
	soc_pmc_peripheral_enable(
		PM_CLOCK_MASK(PM_CLK_GRP_PBB, SYSCLK_USBC_REGS));

	irq_disable(DT_INST_IRQN(0));
	irq_unlock(key);

	LOG_DBG("USB DC detach");
	return 0;
}

int usb_dc_reset(void)
{
	uint32_t key = irq_lock();

	/* Reset the controller */
	regs->USBCON = USBC_USBCON_UIMOD | USBC_USBCON_FRZCLK;

	/* Clear private data */
	(void)memset(&dev_data, 0, sizeof(dev_data));
	(void)memset(&dev_desc, 0, sizeof(dev_desc));

	irq_unlock(key);

	LOG_DBG("USB DC reset");
	return 0;
}

int usb_dc_set_address(uint8_t addr)
{
	/*
	 * Set the address but keep it disabled for now. It should be enabled
	 * only after the ack to the host completes.
	 */
	regs->UDCON &= ~USBC_UDCON_ADDEN;
	regs->UDCON |= USBC_UDCON_UADD(addr);

	LOG_DBG("USB DC set address 0x%02x", addr);
	return 0;
}

void usb_dc_set_status_callback(const usb_dc_status_callback cb)
{
	regs->UDINTECLR = USBC_UDINTECLR_MASK;
	regs->UDINTCLR = USBC_UDINTCLR_MASK;

	usb_dc_detach();
	usb_dc_reset();

	dev_data.status_cb = cb;

	LOG_DBG("USB DC set callback");
}

int usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data * const cfg)
{
	uint8_t ep_idx = USB_EP_GET_IDX(cfg->ep_addr);

	if (ep_idx >= NUM_OF_EP_MAX) {
		LOG_ERR("endpoint index/address out of range");
		return -EINVAL;
	}

	if (ep_idx == 0U) {
		if (cfg->ep_type != USB_DC_EP_CONTROL) {
			LOG_ERR("pre-selected as control endpoint");
			return -EINVAL;
		}
	} else if (ep_idx & BIT(0)) {
		if (USB_EP_DIR_IS_OUT(cfg->ep_addr)) {
			LOG_INF("pre-selected as IN endpoint");
			return -EINVAL;
		}
	} else {
		if (USB_EP_DIR_IS_IN(cfg->ep_addr)) {
			LOG_INF("pre-selected as OUT endpoint");
			return -EINVAL;
		}
	}

	if (cfg->ep_mps < 1 || cfg->ep_mps > 1024 ||
	    (cfg->ep_type == USB_DC_EP_CONTROL && cfg->ep_mps > 64)) {
		LOG_ERR("invalid endpoint size");
		return -EINVAL;
	}
	return 0;
}

int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data *const cfg)
{
	uint8_t ep_idx = USB_EP_GET_IDX(cfg->ep_addr);
	uint32_t regval = 0U;
	int log2ceil_mps;

	if (usb_dc_ep_check_cap(cfg) != 0) {
		return -EINVAL;
	}

	if (!usb_dc_is_attached()) {
		LOG_ERR("device not attached");
		return -ENODEV;
	}

	/* Allow re-configure any endpoint */
	if (usb_dc_ep_is_enabled(ep_idx)) {
		usb_dc_ep_disable(ep_idx);
	}

	LOG_DBG("Configure ep 0x%02x, mps %d, type %d",
		cfg->ep_addr, cfg->ep_mps, cfg->ep_type);

	switch (cfg->ep_type) {
	case USB_DC_EP_CONTROL:
		regval |= USBC_UECFG0_EPTYPE_CONTROL;
		break;
	case USB_DC_EP_ISOCHRONOUS:
		regval |= USBC_UECFG0_EPTYPE_ISOCHRONOUS;
		break;
	case USB_DC_EP_BULK:
		regval |= USBC_UECFG0_EPTYPE_BULK;
		break;
	case USB_DC_EP_INTERRUPT:
		regval |= USBC_UECFG0_EPTYPE_INTERRUPT;
		break;
	default:
		return -EINVAL;
	}

	if (USB_EP_DIR_IS_OUT(cfg->ep_addr) ||
	    cfg->ep_type == USB_DC_EP_CONTROL) {
		regval |= USBC_UECFG0_EPDIR_OUT;
	} else {
		regval |= USBC_UECFG0_EPDIR_IN;
	}

	/*
	 * Map the endpoint size to the buffer size. Only power of 2 buffer
	 * sizes between 8 and 1024 are possible, get the next power of 2.
	 */
	log2ceil_mps = 32 - __builtin_clz((MAX(cfg->ep_mps, 8) << 1) - 1) - 1;
	regval |= USBC_UECFG0_EPSIZE(log2ceil_mps - 3);
	dev_data.ep_data[ep_idx].mps = cfg->ep_mps;

	/* Use double bank buffering for: ISOCHRONOUS, BULK and INTERRUPT */
	if (cfg->ep_type != USB_DC_EP_CONTROL) {
		regval |= USBC_UECFG0_EPBK_DOUBLE;
		dev_data.ep_data[ep_idx].mps_x2 = true;
	} else {
		regval |= USBC_UECFG0_EPBK_SINGLE;
		dev_data.ep_data[ep_idx].mps_x2 = false;
	}

	/** Enable Global NAK */
	regs->UDCON |= USBC_UDCON_GNAK;
	if (usb_dc_sam_usbc_ep_alloc_buf(ep_idx) < 0) {
		dev_data.ep_data[ep_idx].is_configured = false;
		regs->UDCON &= ~USBC_UDCON_GNAK;
		return -ENOMEM;
	}
	regs->UDCON &= ~USBC_UDCON_GNAK;

	/* Configure the endpoint */
	dev_data.ep_data[ep_idx].is_configured = true;
	regs->UECFG[ep_idx] = regval;

	LOG_DBG("ep 0x%02x configured", cfg->ep_addr);
	return 0;
}

int usb_dc_ep_set_stall(uint8_t ep)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);

	if (ep_idx >= NUM_OF_EP_MAX) {
		LOG_ERR("wrong endpoint index/address");
		return -EINVAL;
	}

	if (ep_idx == 0) {
		if (epctrl_fsm == USB_EPCTRL_SETUP) {
			usb_dc_ctrl_stall_data(USBC_UESTA0CLR_RXSTPIC);
		} else if (epctrl_fsm == USB_EPCTRL_DATA_OUT) {
			usb_dc_ctrl_stall_data(USBC_UESTA0CLR_RXOUTIC);
		} else {
			/** Stall without commit any status */
			usb_dc_ctrl_stall_data(0);
		}
	} else {
		regs->UECONSET[ep_idx] = USBC_UECON0SET_STALLRQS;
	}

	LOG_WRN("USB DC stall set ep 0x%02x", ep);
	return 0;
}

int usb_dc_ep_clear_stall(uint8_t ep)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);
	uint32_t key;

	if (ep_idx >= NUM_OF_EP_MAX) {
		LOG_ERR("wrong endpoint index/address");
		return -EINVAL;
	}

	if (regs->UECON[ep_idx] & USBC_UECON0_STALLRQ) {
		key = irq_lock();

		dev_data.ep_data[ep_idx].out_at = 0U;

		regs->UECONCLR[ep_idx] = USBC_UECON0CLR_STALLRQC;
		if (regs->UESTA[ep_idx] & USBC_UESTA0_STALLEDI) {
			regs->UESTACLR[ep_idx] = USBC_UESTA0CLR_STALLEDIC;
			regs->UECONSET[ep_idx] = USBC_UECON0SET_RSTDTS;
		}

		irq_unlock(key);
	}

	LOG_DBG("USB DC stall clear ep 0x%02x", ep);
	return 0;
}

int usb_dc_ep_is_stalled(uint8_t ep, uint8_t *stalled)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);

	if (ep_idx >= NUM_OF_EP_MAX) {
		LOG_ERR("wrong endpoint index/address");
		return -EINVAL;
	}

	if (!stalled) {
		return -EINVAL;
	}

	*stalled = ((regs->UECON[ep_idx] & USBC_UECON0_STALLRQ) != 0);

	LOG_DBG("USB DC stall check ep 0x%02x stalled: %d", ep, *stalled);
	return 0;
}

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

int usb_dc_ep_enable(uint8_t ep)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);
	uint32_t key;

	if (ep_idx >= NUM_OF_EP_MAX) {
		LOG_ERR("wrong endpoint index/address");
		return -EINVAL;
	}

	if (!dev_data.ep_data[ep_idx].is_configured) {
		LOG_ERR("endpoint not configured");
		return -ENODEV;
	}

	key = irq_lock();
	dev_data.ep_data[ep_idx].out_at = 0U;

	/* Enable endpoint */
	regs->UERST |= BIT(USBC_UERST_EPEN0_Pos + ep_idx);
	/* Enable global endpoint interrupts */
	regs->UDINTESET = (USBC_UDINTESET_EP0INTES << ep_idx);

	usb_dc_ep_enable_interrupts(ep_idx);
	irq_unlock(key);

	LOG_DBG("Enable ep 0x%02x", ep);
	return 0;
}

int usb_dc_ep_disable(uint8_t ep)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);
	uint32_t key;

	if (ep_idx >= NUM_OF_EP_MAX) {
		LOG_ERR("wrong endpoint index/address");
		return -EINVAL;
	}

	key = irq_lock();

	/* Disable global endpoint interrupt */
	regs->UDINTECLR = BIT(USBC_UDINTESET_EP0INTES_Pos + ep_idx);

	/* Disable endpoint and reset */
	regs->UERST &= ~BIT(USBC_UERST_EPEN0_Pos + ep_idx);

	irq_unlock(key);

	LOG_DBG("Disable ep 0x%02x", ep);
	return 0;
}

int usb_dc_ep_flush(uint8_t ep)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);
	uint32_t key;

	if (ep_idx >= NUM_OF_EP_MAX) {
		LOG_ERR("wrong endpoint index/address");
		return -EINVAL;
	}

	if (!usb_dc_ep_is_enabled(ep_idx)) {
		LOG_ERR("endpoint not enabled");
		return -ENODEV;
	}

	key = irq_lock();

	/* Disable the IN interrupt */
	regs->UECONCLR[ep_idx] = USBC_UECON0CLR_TXINEC;

	/* Reset the endpoint */
	regs->UERST &= ~(BIT(ep_idx));
	regs->UERST |= BIT(ep_idx);

	dev_data.ep_data[ep_idx].out_at = 0U;

	/* Reenable interrupts */
	usb_dc_ep_enable_interrupts(ep_idx);

	irq_unlock(key);

	LOG_DBG("ep 0x%02x flushed", ep);
	return 0;
}

int usb_dc_ep_set_callback(uint8_t ep, const usb_dc_ep_callback cb)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);

	if (ep_idx >= NUM_OF_EP_MAX) {
		LOG_ERR("wrong endpoint index/address");
		return -EINVAL;
	}

	if (USB_EP_DIR_IS_IN(ep)) {
		dev_data.ep_data[ep_idx].cb_in = cb;
	} else {
		dev_data.ep_data[ep_idx].cb_out = cb;
	}

	LOG_DBG("set ep 0x%02x %s callback", ep,
		USB_EP_DIR_IS_IN(ep) ? "IN" : "OUT");
	return 0;
}

static int usb_dc_ep_write_stp(uint8_t ep_bank, const uint8_t *data,
			       uint32_t packet_len)
{
	uint32_t key;

	if (epctrl_fsm == USB_EPCTRL_SETUP) {
		regs->UESTACLR[0] = USBC_UESTA0CLR_RXSTPIC;

		epctrl_fsm = USB_EPCTRL_DATA_IN;

		key = irq_lock();
		regs->UECONCLR[0] = USBC_UECON0CLR_TXINEC;
		irq_unlock(key);
	}

	if (epctrl_fsm == USB_EPCTRL_DATA_IN) {
		/* All data requested are transferred or a short packet has
		 * been sent then it is the end of data phase.
		 *
		 * Generate an OUT ZLP for handshake phase.
		 */
		if (packet_len == 0) {
			usb_dc_ctrl_send_zlp_out();
			return 0;
		}

		/** Critical section
		 * Only in case of DATA IN phase abort without USB Reset
		 * signal after.  The IN data don't must be written in
		 * endpoint 0 DPRAM during a next setup reception in same
		 * endpoint 0 DPRAM.  Thereby, an OUT ZLP reception must
		 * check before IN data write and if no OUT ZLP is received
		 * the data must be written quickly (800us) before an
		 * eventually ZLP OUT and SETUP reception.
		 */
		key = irq_lock();

		if (regs->UESTA[0] & USBC_UESTA0_RXOUTI) {

			/* IN DATA phase aborted by OUT ZLP */
			irq_unlock(key);

			epctrl_fsm = USB_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP;
			return 0;
		}

		if (data) {
			memcpy(dev_desc[ep_bank].ep_pipe_addr,
			       data, packet_len);
			barrier_dsync_fence_full();
		}
		dev_desc[ep_bank].sizes = packet_len;

		/*
		 * Control endpoint: clear the interrupt flag to send
		 * the data, and re-enable the interrupts to trigger
		 * an interrupt at the end of the transfer.
		 */
		regs->UESTACLR[0] = USBC_UESTA0CLR_TXINIC;
		regs->UECONSET[0] = USBC_UECON0SET_TXINES;

		/* In case of abort of DATA IN phase, no need to enable
		 * nak OUT interrupt because OUT endpoint is already
		 * free and ZLP OUT accepted.
		 */
		irq_unlock(key);
	} else if (epctrl_fsm == USB_EPCTRL_DATA_OUT ||
		   epctrl_fsm == USB_EPCTRL_HANDSHAKE_WAIT_IN_ZLP) {
		/* ZLP on IN is sent, then valid end of setup request
		 * or
		 * No data phase requested.
		 *
		 * Send IN ZLP to ACK setup request
		 */
		usb_dc_ctrl_send_zlp_in();
	} else {
		LOG_ERR("Invalid STP state %d on IN phase", epctrl_fsm);
		return -EPERM;
	}
	return 0;
}

int usb_dc_ep_write(uint8_t ep, const uint8_t *data,
		    uint32_t data_len, uint32_t *ret_bytes)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);
	uint8_t ep_bank;
	uint32_t packet_len;

	if (ep_idx >= NUM_OF_EP_MAX) {
		LOG_ERR("wrong endpoint index/address");
		return -EINVAL;
	}

	if (!usb_dc_ep_is_enabled(ep_idx)) {
		LOG_ERR("endpoint not enabled");
		return -ENODEV;
	}

	if (USB_EP_DIR_IS_OUT(ep)) {
		LOG_ERR("wrong endpoint direction");
		return -EINVAL;
	}

	if ((regs->UECON[ep_idx] & USBC_UECON0_STALLRQ) != 0) {
		LOG_WRN("endpoint is stalled");
		return -EBUSY;
	}

	/* Check if there is bank available */
	if (ep_idx > 0) {
		if ((regs->UECON[ep_idx] & USBC_UECON0_FIFOCON) == 0) {
			return -EAGAIN;
		}
	}

	ep_bank = usb_dc_sam_usbc_ep_curr_bank(ep_idx);

	packet_len = MIN(data_len, dev_data.ep_data[ep_idx].mps);

	if (ret_bytes) {
		*ret_bytes = packet_len;
	}

	if (ep_idx == 0U) {
		if (usb_dc_ep_write_stp(ep_bank, data, packet_len)) {
			return -EPERM;
		}
	} else {
		if (data && packet_len > 0) {
			memcpy(dev_desc[ep_bank].ep_pipe_addr, data, packet_len);
			barrier_dsync_fence_full();
		}
		dev_desc[ep_bank].sizes = packet_len;

		/*
		 * Other endpoint types: clear the FIFO control flag to send
		 * the data.
		 */
		regs->UECONCLR[ep_idx] = USBC_UECON0CLR_FIFOCONC;
	}

	LOG_INF("ep 0x%02x write %d bytes from %d to bank %d%s",
		ep, packet_len, data_len, ep_bank % 2,
		packet_len == 0 ? " (ZLP)" : "");
	return 0;
}

static int usb_dc_ep_read_ex_stp(uint32_t take, uint32_t wLength)
{
	uint32_t key;

	if (epctrl_fsm == USB_EPCTRL_SETUP) {
		if (regs->UESTA[0] & USBC_UESTA0_CTRLDIR) {
			/** Do Nothing */
		} else {
			regs->UESTACLR[0] = USBC_UESTA0CLR_RXSTPIC;

			epctrl_fsm = USB_EPCTRL_DATA_OUT;

			if (wLength == 0) {
				/* No data phase requested.
				 * Send IN ZLP to ACK setup request
				 *
				 * This is send at usb_dc_ep_write()
				 */
				return 0;
			}

			regs->UECONSET[0] = USBC_UECON0SET_RXOUTES;

			/* To detect a protocol error, enable nak
			 * interrupt on data IN phase
			 */
			regs->UESTACLR[0] = USBC_UESTA0CLR_NAKINIC;
			key = irq_lock();
			regs->UECONSET[0] = USBC_UECON0SET_NAKINES;
			irq_unlock(key);
		}
	} else if (epctrl_fsm == USB_EPCTRL_DATA_OUT) {
		regs->UESTACLR[0] = USBC_UESTA0CLR_RXOUTIC;

		if (take == 0) {
			usb_dc_ctrl_send_zlp_in();
		} else {
			regs->UESTACLR[0] = USBC_UESTA0CLR_NAKINIC;
			key = irq_lock();
			regs->UECONSET[0] = USBC_UECON0SET_NAKINES;
			irq_unlock(key);
		}
	} else {
		LOG_ERR("Invalid STP state %d on OUT phase", epctrl_fsm);
		return -EPERM;
	}
	return 0;
}

int usb_dc_ep_read_ex(uint8_t ep, uint8_t *data, uint32_t max_data_len,
		      uint32_t *read_bytes, bool wait)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);
	struct usb_setup_packet *setup;
	uint8_t ep_bank;
	uint32_t data_len;
	uint32_t remaining;
	uint32_t take;
	int rc = 0;

	if (ep_idx >= NUM_OF_EP_MAX) {
		LOG_ERR("wrong endpoint index/address");
		return -EINVAL;
	}

	if (!usb_dc_ep_is_enabled(ep_idx)) {
		LOG_ERR("endpoint not enabled");
		return -ENODEV;
	}

	if (USB_EP_DIR_IS_IN(ep)) {
		LOG_ERR("wrong endpoint direction");
		return -EINVAL;
	}

	if ((regs->UECON[ep_idx] & USBC_UECON0_STALLRQ) != 0) {
		LOG_WRN("endpoint is stalled");
		return -EBUSY;
	}

	ep_bank = usb_dc_sam_usbc_ep_curr_bank(ep_idx);
	data_len = dev_desc[ep_bank].udesc_sizes.byte_count;

	if (data == NULL) {
		dev_data.ep_data[ep_idx].out_at = 0U;

		if (read_bytes) {
			*read_bytes = data_len;
		}
		return 0;
	}

	remaining = data_len - dev_data.ep_data[ep_idx].out_at;
	take = MIN(max_data_len, remaining);
	if (take) {
		memcpy(data,
		       (uint8_t *) dev_desc[ep_bank].ep_pipe_addr +
		       dev_data.ep_data[ep_idx].out_at,
		       take);
		barrier_dsync_fence_full();
	}

	if (read_bytes) {
		*read_bytes = take;
	}

	if (take == remaining || take == 0) {
		if (!wait) {
			dev_data.ep_data[ep_idx].out_at = 0U;

			if (ep_idx == 0) {
				setup = (struct usb_setup_packet *) data;
				rc = usb_dc_ep_read_ex_stp(take,
							   setup->wLength);
			} else {
				rc = usb_dc_ep_read_continue(ep);
			}
		}
	} else {
		dev_data.ep_data[ep_idx].out_at += take;
	}

	LOG_INF("ep 0x%02x read %d bytes from bank %d and %s",
		ep, take, ep_bank % 2, wait ? "wait" : "NO wait");
	return rc;
}

int usb_dc_ep_read_continue(uint8_t ep)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);

	if (ep_idx == 0 || ep_idx >= NUM_OF_EP_MAX) {
		LOG_ERR("wrong endpoint index/address");
		return -EINVAL;
	}

	if (!usb_dc_ep_is_enabled(ep_idx)) {
		LOG_ERR("endpoint not enabled");
		return -ENODEV;
	}

	if (USB_EP_DIR_IS_IN(ep)) {
		LOG_ERR("wrong endpoint direction");
		return -EINVAL;
	}

	regs->UECONCLR[ep_idx] = USBC_UECON0CLR_FIFOCONC;
	return 0;
}

int usb_dc_ep_read(uint8_t ep, uint8_t *data, uint32_t max_data_len,
		   uint32_t *read_bytes)
{
	return usb_dc_ep_read_ex(ep, data, max_data_len, read_bytes, false);
}

int usb_dc_ep_read_wait(uint8_t ep, uint8_t *data, uint32_t max_data_len,
			uint32_t *read_bytes)
{
	return usb_dc_ep_read_ex(ep, data, max_data_len, read_bytes, true);
}

int usb_dc_ep_mps(uint8_t ep)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);

	if (ep_idx >= NUM_OF_EP_MAX) {
		LOG_ERR("wrong endpoint index/address");
		return -EINVAL;
	}

	return dev_data.ep_data[ep_idx].mps;
}

int usb_dc_wakeup_request(void)
{
	bool is_clk_frozen = usb_dc_sam_usbc_is_frozen_clk();

	if (is_clk_frozen) {
		usb_dc_sam_usbc_unfreeze_clk();
	}

	regs->UDCON |= USBC_UDCON_RMWKUP;

	if (is_clk_frozen) {
		usb_dc_sam_usbc_freeze_clk();
	}
	return 0;
}
