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

#include <zephyr/kernel.h>
#include <zephyr/sys/atomic.h>
#include <zephyr/sys/byteorder.h>

#include <zephyr/usb/usbd.h>
#include <zephyr/usb/usb_ch9.h>
#include <zephyr/usb/class/usbd_uac2.h>
#include <zephyr/drivers/usb/udc.h>

#include "usbd_uac2_macros.h"

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(usbd_uac2, CONFIG_USBD_UAC2_LOG_LEVEL);

#define DT_DRV_COMPAT zephyr_uac2

#define COUNT_UAC2_AS_ENDPOINTS(node)						\
	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_audio_streaming), (	\
		+ AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node) +			\
		AS_HAS_EXPLICIT_FEEDBACK_ENDPOINT(node)))
#define COUNT_UAC2_ENDPOINTS(i)							\
	+ DT_PROP(DT_DRV_INST(i), interrupt_endpoint)				\
	DT_INST_FOREACH_CHILD(i, COUNT_UAC2_AS_ENDPOINTS)
#define UAC2_NUM_ENDPOINTS DT_INST_FOREACH_STATUS_OKAY(COUNT_UAC2_ENDPOINTS)

/* Net buf is used mostly with external data. The main reason behind external
 * data is avoiding unnecessary isochronous data copy operations.
 *
 * Allow up to 6 bytes per item to facilitate optional interrupt endpoint (which
 * requires 6 bytes) and feedback endpoint (4 bytes on High-Speed, 3 bytes on
 * Full-Speed). Because the total number of endpoints is really small (typically
 * there will be just 2 isochronous endpoints; the upper bound originating from
 * the USB specification itself is 30 non-control endpoints). Therefore, the
 * "wasted memory" here is likely to be smaller than the memory overhead for
 * more complex "only as much as needed" schemes (e.g. heap).
 */
NET_BUF_POOL_DEFINE(uac2_pool, UAC2_NUM_ENDPOINTS, 6,
		    sizeof(struct udc_buf_info), NULL);

/* 5.2.2 Control Request Layout */
#define SET_CLASS_REQUEST_TYPE		0x21
#define GET_CLASS_REQUEST_TYPE		0xA1

/* A.14 Audio Class-Specific Request Codes */
#define CUR				0x01
#define RANGE				0x02
#define MEM				0x03

/* A.17.1 Clock Source Control Selectors */
#define CS_SAM_FREQ_CONTROL		0x01
#define CS_CLOCK_VALID_CONTROL		0x02

#define CONTROL_ATTRIBUTE(setup)	(setup->bRequest)
#define CONTROL_ENTITY_ID(setup)	((setup->wIndex & 0xFF00) >> 8)
#define CONTROL_SELECTOR(setup)		((setup->wValue & 0xFF00) >> 8)
#define CONTROL_CHANNEL_NUMBER(setup)	(setup->wValue & 0x00FF)

typedef enum {
	ENTITY_TYPE_INVALID,
	ENTITY_TYPE_CLOCK_SOURCE,
	ENTITY_TYPE_INPUT_TERMINAL,
	ENTITY_TYPE_OUTPUT_TERMINAL,
} entity_type_t;

static size_t clock_frequencies(struct usbd_class_node *const node,
				const uint8_t id, const uint32_t **frequencies);

/* UAC2 device runtime data */
struct uac2_ctx {
	const struct uac2_ops *ops;
	void *user_data;
	/* Bit set indicates the AudioStreaming interface has non-zero bandwidth
	 * alternate setting active.
	 */
	atomic_t as_active;
	atomic_t as_queued;
	uint32_t fb_queued;
};

/* UAC2 device constant data */
struct uac2_cfg {
	struct usbd_class_node *const node;
	/* Entity 1 type is at entity_types[0] */
	const entity_type_t *entity_types;
	/* Array of offsets to data endpoint bEndpointAddress in descriptors.
	 * First AudioStreaming interface is at ep_offsets[0]. Offset is 0 if
	 * the interface is external interface (Type IV), i.e. no endpoint.
	 */
	const uint16_t *ep_offsets;
	/* Same as ep_offsets, but for explicit feedback endpoints. */
	const uint16_t *fb_offsets;
	/* First AudioStreaming interface Terminal ID is at as_terminals[0]. */
	const uint8_t *as_terminals;
	/* Number of interfaces (ep_offsets, fb_offset and as_terminals size) */
	uint8_t num_ifaces;
	/* Number of entities (entity_type array size) */
	uint8_t num_entities;
};

static entity_type_t id_type(struct usbd_class_node *const node, uint8_t id)
{
	const struct device *dev = node->data->priv;
	const struct uac2_cfg *cfg = dev->config;

	if ((id - 1) < cfg->num_entities) {
		return cfg->entity_types[id - 1];
	}

	return ENTITY_TYPE_INVALID;
}

static const struct usb_ep_descriptor *
get_as_data_ep(struct usbd_class_node *const node, int as_idx)
{
	const struct device *dev = node->data->priv;
	const struct uac2_cfg *cfg = dev->config;
	const uint8_t *desc = node->data->desc;

	if ((as_idx < cfg->num_ifaces) && cfg->ep_offsets[as_idx]) {
		return CONTAINER_OF(&desc[cfg->ep_offsets[as_idx]],
				    const struct usb_ep_descriptor,
				    bEndpointAddress);
	}

	return NULL;
}

static const struct usb_ep_descriptor *
get_as_feedback_ep(struct usbd_class_node *const node, int as_idx)
{
	const struct device *dev = node->data->priv;
	const struct uac2_cfg *cfg = dev->config;
	const uint8_t *desc = node->data->desc;

	if ((as_idx < cfg->num_ifaces) && cfg->fb_offsets[as_idx]) {
		return CONTAINER_OF(&desc[cfg->fb_offsets[as_idx]],
				    const struct usb_ep_descriptor,
				    bEndpointAddress);
	}

	return NULL;
}

static int ep_to_as_interface(const struct device *dev, uint8_t ep, bool *fb)
{
	const struct uac2_cfg *cfg = dev->config;
	const uint8_t *desc = cfg->node->data->desc;

	for (int i = 0; i < cfg->num_ifaces; i++) {
		if (!cfg->ep_offsets[i]) {
			/* If there is no data endpoint there cannot be feedback
			 * endpoint. Simply skip external interfaces.
			 */
			continue;
		}

		if (ep == desc[cfg->ep_offsets[i]]) {
			*fb = false;
			return i;
		}

		if (cfg->fb_offsets[i] && (ep == desc[cfg->fb_offsets[i]])) {
			*fb = true;
			return i;
		}
	}

	*fb = false;
	return -ENOENT;
}

static int terminal_to_as_interface(const struct device *dev, uint8_t terminal)
{
	const struct uac2_cfg *cfg = dev->config;

	for (int as_idx = 0; as_idx < cfg->num_ifaces; as_idx++) {
		if (terminal == cfg->as_terminals[as_idx]) {
			return as_idx;
		}
	}

	return -ENOENT;
}

void usbd_uac2_set_ops(const struct device *dev,
		       const struct uac2_ops *ops, void *user_data)
{
	struct uac2_ctx *ctx = dev->data;

	__ASSERT(ops->sof_cb, "SOF callback is mandatory");

	ctx->ops = ops;
	ctx->user_data = user_data;
}

static struct net_buf *
uac2_buf_alloc(const uint8_t ep, void *data, uint16_t size)
{
	struct net_buf *buf = NULL;
	struct udc_buf_info *bi;

	buf = net_buf_alloc_with_data(&uac2_pool, data, size, K_NO_WAIT);
	if (!buf) {
		return NULL;
	}

	bi = udc_get_buf_info(buf);
	memset(bi, 0, sizeof(struct udc_buf_info));
	bi->ep = ep;

	if (USB_EP_DIR_IS_OUT(ep)) {
		/* Buffer is empty, USB stack will write data from host */
		buf->len = 0;
	}

	return buf;
}

int usbd_uac2_send(const struct device *dev, uint8_t terminal,
		   void *data, uint16_t size)
{
	const struct uac2_cfg *cfg = dev->config;
	const uint8_t *desc = cfg->node->data->desc;
	struct uac2_ctx *ctx = dev->data;
	struct net_buf *buf;
	uint8_t ep = 0;
	int as_idx = terminal_to_as_interface(dev, terminal);
	int ret;

	if ((as_idx >= 0) && cfg->ep_offsets[as_idx]) {
		ep = desc[cfg->ep_offsets[as_idx]];
	}

	if (!ep) {
		LOG_ERR("No endpoint for terminal %d", terminal);
		return -ENOENT;
	}

	if (!atomic_test_bit(&ctx->as_active, as_idx)) {
		/* Host is not interested in the data */
		ctx->ops->buf_release_cb(dev, terminal, data, ctx->user_data);
		return 0;
	}

	if (atomic_test_and_set_bit(&ctx->as_queued, as_idx)) {
		LOG_ERR("Previous send not finished yet on 0x%02x", ep);
		return -EAGAIN;
	}

	buf = uac2_buf_alloc(ep, data, size);
	if (!buf) {
		/* This shouldn't really happen because netbuf should be large
		 * enough, but if it does all we loose is just single packet.
		 */
		LOG_ERR("No netbuf for send");
		atomic_clear_bit(&ctx->as_queued, as_idx);
		ctx->ops->buf_release_cb(dev, terminal, data, ctx->user_data);
		return -ENOMEM;
	}

	ret = usbd_ep_enqueue(cfg->node, buf);
	if (ret) {
		LOG_ERR("Failed to enqueue net_buf for 0x%02x", ep);
		net_buf_unref(buf);
		atomic_clear_bit(&ctx->as_queued, as_idx);
		ctx->ops->buf_release_cb(dev, terminal, data, ctx->user_data);
	}

	return ret;
}

static void schedule_iso_out_read(struct usbd_class_node *const node,
				  uint8_t ep, uint16_t mps, uint8_t terminal)
{
	struct device *dev = node->data->priv;
	const struct uac2_cfg *cfg = dev->config;
	struct uac2_ctx *ctx = dev->data;
	struct net_buf *buf;
	void *data_buf;
	int as_idx = terminal_to_as_interface(dev, terminal);
	int ret;

	/* All calls to this function are internal to class, if terminal is not
	 * associated with interface there is a bug in class implementation.
	 */
	__ASSERT_NO_MSG((as_idx >= 0) && (as_idx < cfg->num_ifaces));
	/* Silence warning if asserts are not enabled */
	ARG_UNUSED(cfg);

	if (!((as_idx >= 0) && atomic_test_bit(&ctx->as_active, as_idx))) {
		/* Host won't send data */
		return;
	}

	if (atomic_test_and_set_bit(&ctx->as_queued, as_idx)) {
		/* Transfer already queued - do not requeue */
		return;
	}

	/* Prepare transfer to read audio OUT data from host */
	data_buf = ctx->ops->get_recv_buf(dev, terminal, mps, ctx->user_data);
	if (!data_buf) {
		LOG_ERR("No data buffer for terminal %d", terminal);
		atomic_clear_bit(&ctx->as_queued, as_idx);
		return;
	}

	buf = uac2_buf_alloc(ep, data_buf, mps);
	if (!buf) {
		LOG_ERR("No netbuf for read");
		/* Netbuf pool should be large enough, but if for some reason
		 * we are out of netbuf, there's nothing better to do than to
		 * pass the buffer back to application.
		 */
		ctx->ops->data_recv_cb(dev, terminal,
				       data_buf, 0, ctx->user_data);
		atomic_clear_bit(&ctx->as_queued, as_idx);
		return;
	}

	ret = usbd_ep_enqueue(node, buf);
	if (ret) {
		LOG_ERR("Failed to enqueue net_buf for 0x%02x", ep);
		net_buf_unref(buf);
		atomic_clear_bit(&ctx->as_queued, as_idx);
	}
}

static void write_explicit_feedback(struct usbd_class_node *const node,
				    uint8_t ep, uint8_t terminal)
{
	struct device *dev = node->data->priv;
	struct uac2_ctx *ctx = dev->data;
	struct net_buf *buf;
	struct udc_buf_info *bi;
	uint32_t fb_value;
	int as_idx = terminal_to_as_interface(dev, terminal);
	int ret;

	buf = net_buf_alloc(&uac2_pool, K_NO_WAIT);
	if (!buf) {
		LOG_ERR("No buf for feedback");
		return;
	}

	bi = udc_get_buf_info(buf);
	memset(bi, 0, sizeof(struct udc_buf_info));
	bi->ep = ep;

	fb_value = ctx->ops->feedback_cb(dev, terminal, ctx->user_data);

	/* REVISE: How to determine operating speed? Should we have separate
	 * class instances for high-speed and full-speed (because high-speed
	 * allows more sampling rates and/or bit depths)?
	 */
	if (udc_device_speed(node->data->uds_ctx->dev) == UDC_BUS_SPEED_FS) {
		net_buf_add_le24(buf, fb_value);
	} else {
		net_buf_add_le32(buf, fb_value);
	}

	ret = usbd_ep_enqueue(node, buf);
	if (ret) {
		LOG_ERR("Failed to enqueue net_buf for 0x%02x", ep);
		net_buf_unref(buf);
	} else {
		ctx->fb_queued |= BIT(as_idx);
	}
}

void uac2_update(struct usbd_class_node *const node,
		 uint8_t iface, uint8_t alternate)
{
	struct device *dev = node->data->priv;
	const struct uac2_cfg *cfg = dev->config;
	struct uac2_ctx *ctx = dev->data;
	const struct usb_association_descriptor *iad;
	const struct usb_ep_descriptor *data_ep, *fb_ep;
	uint8_t as_idx;
	bool microframes;

	LOG_DBG("iface %d alt %d", iface, alternate);

	iad = (const struct usb_association_descriptor *)node->data->desc;

	/* AudioControl interface (bFirstInterface) doesn't have alternate
	 * configurations, therefore the iface must be AudioStreaming.
	 */
	__ASSERT_NO_MSG((iface > iad->bFirstInterface) &&
			(iface < iad->bFirstInterface + iad->bInterfaceCount));
	as_idx = iface - iad->bFirstInterface - 1;

	/* Audio class is forbidden on Low-Speed, therefore the only possibility
	 * for not using microframes is when device operates at Full-Speed.
	 */
	if (udc_device_speed(node->data->uds_ctx->dev) == UDC_BUS_SPEED_FS) {
		microframes = false;
	} else {
		microframes = true;
	}

	/* Notify application about terminal state change */
	ctx->ops->terminal_update_cb(dev, cfg->as_terminals[as_idx], alternate,
				     microframes, ctx->user_data);

	if (alternate == 0) {
		/* Mark interface as inactive, any pending endpoint transfers
		 * were already cancelled by the USB stack.
		 */
		atomic_clear_bit(&ctx->as_active, as_idx);
		return;
	}

	atomic_set_bit(&ctx->as_active, as_idx);

	data_ep = get_as_data_ep(node, as_idx);
	/* External interfaces (i.e. NULL data_ep) do not have alternate
	 * configuration and therefore data_ep must be valid here.
	 */
	__ASSERT_NO_MSG(data_ep);

	if (USB_EP_DIR_IS_OUT(data_ep->bEndpointAddress)) {
		schedule_iso_out_read(node, data_ep->bEndpointAddress,
				      sys_le16_to_cpu(data_ep->wMaxPacketSize),
				      cfg->as_terminals[as_idx]);

		fb_ep = get_as_feedback_ep(node, as_idx);
		if (fb_ep) {
			write_explicit_feedback(node, fb_ep->bEndpointAddress,
						cfg->as_terminals[as_idx]);
		}
	}
}

/* Table 5-6: 4-byte Control CUR Parameter Block */
static void layout3_cur_response(struct net_buf *const buf, uint16_t length,
				 const uint32_t value)
{
	uint8_t tmp[4];

	/* dCUR */
	sys_put_le32(value, tmp);
	net_buf_add_mem(buf, tmp, MIN(length, 4));
}

/* Table 5-7: 4-byte Control RANGE Parameter Block */
static void layout3_range_response(struct net_buf *const buf, uint16_t length,
				   const uint32_t *min, const uint32_t *max,
				   const uint32_t *res, int n)
{
	uint16_t to_add;
	uint8_t tmp[4];
	int i;
	int item;

	/* wNumSubRanges */
	sys_put_le16(n, tmp);
	to_add = MIN(length, 2);
	net_buf_add_mem(buf, tmp, to_add);
	length -= to_add;

	/* Keep adding dMIN, dMAX, dRES as long as we have entries to add and
	 * we didn't reach wLength response limit.
	 */
	i = item = 0;
	while ((length > 0) && (i < n)) {
		to_add = MIN(length, 4);
		if (item == 0) {
			sys_put_le32(min[i], tmp);
		} else if (item == 1) {
			sys_put_le32(max[i], tmp);
		} else if (item == 2) {
			if (res) {
				sys_put_le32(res[i], tmp);
			} else {
				memset(tmp, 0, 4);
			}
		}
		net_buf_add_mem(buf, tmp, to_add);
		length -= to_add;

		if (++item == 3) {
			item = 0;
			i++;
		}
	}
}

static int get_clock_source_request(struct usbd_class_node *const node,
				    const struct usb_setup_packet *const setup,
				    struct net_buf *const buf)
{
	const uint32_t *frequencies;
	size_t count;

	/* Channel Number must be zero */
	if (CONTROL_CHANNEL_NUMBER(setup) != 0) {
		LOG_DBG("Clock source control with channel %d",
			CONTROL_CHANNEL_NUMBER(setup));
		errno = -EINVAL;
		return 0;
	}

	count = clock_frequencies(node, CONTROL_ENTITY_ID(setup), &frequencies);

	if (CONTROL_SELECTOR(setup) == CS_SAM_FREQ_CONTROL) {
		if (CONTROL_ATTRIBUTE(setup) == CUR) {
			if (count == 1) {
				layout3_cur_response(buf, setup->wLength,
						     frequencies[0]);
				return 0;
			}
			/* TODO: If there is more than one frequency supported,
			 * call registered application API to determine active
			 * sample rate.
			 */
		} else if (CONTROL_ATTRIBUTE(setup) == RANGE) {
			layout3_range_response(buf, setup->wLength, frequencies,
					       frequencies, NULL, count);
			return 0;
		}
	} else {
		LOG_DBG("Unhandled clock control selector 0x%02x",
			CONTROL_SELECTOR(setup));
	}

	errno = -ENOTSUP;
	return 0;
}

static int uac2_control_to_host(struct usbd_class_node *const node,
				const struct usb_setup_packet *const setup,
				struct net_buf *const buf)
{
	entity_type_t entity_type;

	if ((CONTROL_ATTRIBUTE(setup) != CUR) &&
	    (CONTROL_ATTRIBUTE(setup) != RANGE)) {
		errno = -ENOTSUP;
		return 0;
	}

	if (setup->bmRequestType == GET_CLASS_REQUEST_TYPE) {
		entity_type = id_type(node, CONTROL_ENTITY_ID(setup));
		if (entity_type == ENTITY_TYPE_CLOCK_SOURCE) {
			return get_clock_source_request(node, setup, buf);
		}
	}

	errno = -ENOTSUP;
	return 0;
}

static int uac2_request(struct usbd_class_node *const node, struct net_buf *buf,
			int err)
{
	struct device *dev = node->data->priv;
	const struct uac2_cfg *cfg = dev->config;
	struct uac2_ctx *ctx = dev->data;
	struct usbd_contex *uds_ctx = node->data->uds_ctx;
	struct udc_buf_info *bi;
	uint8_t ep, terminal;
	uint16_t mps;
	int as_idx;
	bool is_feedback;

	bi = udc_get_buf_info(buf);
	if (err) {
		if (err == -ECONNABORTED) {
			LOG_WRN("request ep 0x%02x, len %u cancelled",
				bi->ep, buf->len);
		} else {
			LOG_ERR("request ep 0x%02x, len %u failed",
				bi->ep, buf->len);
		}
	}

	mps = buf->size;
	ep = bi->ep;
	as_idx = ep_to_as_interface(dev, ep, &is_feedback);
	__ASSERT_NO_MSG((as_idx >= 0) && (as_idx < cfg->num_ifaces));
	terminal = cfg->as_terminals[as_idx];

	if (is_feedback) {
		ctx->fb_queued &= ~BIT(as_idx);
	} else {
		atomic_clear_bit(&ctx->as_queued, as_idx);
	}

	if (USB_EP_DIR_IS_OUT(ep)) {
		ctx->ops->data_recv_cb(dev, terminal, buf->__buf, buf->len,
				       ctx->user_data);
	} else if (!is_feedback) {
		ctx->ops->buf_release_cb(dev, terminal, buf->__buf, ctx->user_data);
	}

	usbd_ep_buf_free(uds_ctx, buf);
	if (err) {
		return 0;
	}

	/* Reschedule the read or explicit feedback write */
	if (USB_EP_DIR_IS_OUT(ep)) {
		schedule_iso_out_read(node, ep, mps, terminal);
	}

	return 0;
}

static void uac2_sof(struct usbd_class_node *const node)
{
	struct device *dev = node->data->priv;
	const struct usb_ep_descriptor *data_ep;
	const struct uac2_cfg *cfg = dev->config;
	const uint8_t *desc = node->data->desc;
	struct uac2_ctx *ctx = dev->data;
	int as_idx;

	ctx->ops->sof_cb(dev, ctx->user_data);

	for (as_idx = 0; as_idx < cfg->num_ifaces; as_idx++) {
		/* Make sure OUT endpoint has read request pending. The request
		 * won't be pending only if there was buffer underrun, i.e. the
		 * application failed to supply receive buffer.
		 */
		data_ep = get_as_data_ep(node, as_idx);
		if (data_ep && USB_EP_DIR_IS_OUT(data_ep->bEndpointAddress)) {
			schedule_iso_out_read(node, data_ep->bEndpointAddress,
				sys_le16_to_cpu(data_ep->wMaxPacketSize),
				cfg->as_terminals[as_idx]);
		}

		/* Skip interfaces without explicit feedback endpoint */
		if (cfg->fb_offsets[as_idx] == 0) {
			continue;
		}

		/* We didn't get feedback write request callback yet, skip it
		 * for now to allow faster recovery (i.e. reduce workload to be
		 * done during this frame).
		 */
		if (ctx->fb_queued & BIT(as_idx)) {
			continue;
		}

		/* Only send feedback if host has enabled alternate interface */
		if (!atomic_test_bit(&ctx->as_active, as_idx)) {
			continue;
		}

		/* Make feedback available on every frame (value "sent" in
		 * previous SOF is "gone" even if USB host did not attempt to
		 * read it).
		 */
		write_explicit_feedback(node, desc[cfg->fb_offsets[as_idx]],
					cfg->as_terminals[as_idx]);
	}
}

static int uac2_init(struct usbd_class_node *const node)
{
	struct device *dev = node->data->priv;
	struct uac2_ctx *ctx = dev->data;

	if (ctx->ops == NULL) {
		LOG_ERR("Application did not register UAC2 ops");
		return -EINVAL;
	}

	return 0;
}

struct usbd_class_api uac2_api = {
	.update = uac2_update,
	.control_to_host = uac2_control_to_host,
	.request = uac2_request,
	.sof = uac2_sof,
	.init = uac2_init,
};

#define DEFINE_ENTITY_TYPES(node)						\
	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_clock_source), (	\
		ENTITY_TYPE_CLOCK_SOURCE					\
	))									\
	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_input_terminal), (	\
		ENTITY_TYPE_INPUT_TERMINAL					\
	))									\
	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_output_terminal), (	\
		ENTITY_TYPE_OUTPUT_TERMINAL					\
	))									\
	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_audio_streaming), (	\
		ENTITY_TYPE_INVALID						\
	))									\
	, /* Comma here causes unknown types to fail at compile time */
#define DEFINE_AS_EP_OFFSETS(node)						\
	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_audio_streaming), (	\
		COND_CODE_1(AS_HAS_ISOCHRONOUS_DATA_ENDPOINT(node),		\
			(UAC2_DESCRIPTOR_AS_DATA_EP_OFFSET(node),), (0,))	\
	))
#define DEFINE_AS_FB_OFFSETS(node)						\
	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_audio_streaming), (	\
		COND_CODE_1(AS_HAS_EXPLICIT_FEEDBACK_ENDPOINT(node),		\
			(UAC2_DESCRIPTOR_AS_FEEDBACK_EP_OFFSET(node),), (0,))	\
	))
#define DEFINE_AS_TERMINALS(node)						\
	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_audio_streaming), (	\
		ENTITY_ID(DT_PROP(node, linked_terminal)),			\
	))

#define FREQUENCY_TABLE_NAME(node, i)						\
	UTIL_CAT(frequencies_##i##_, ENTITY_ID(node))
#define DEFINE_CLOCK_SOURCES(node, i)						\
	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_clock_source), (	\
		static const uint32_t FREQUENCY_TABLE_NAME(node, i)[] =		\
				DT_PROP(node, sampling_frequencies);		\
	))

#define DEFINE_LOOKUP_TABLES(i)							\
	static const entity_type_t entity_types_##i[] = {			\
		DT_INST_FOREACH_CHILD_STATUS_OKAY(i, DEFINE_ENTITY_TYPES)	\
	};									\
	static const uint16_t ep_offsets_##i[] = {				\
		DT_INST_FOREACH_CHILD_STATUS_OKAY(i, DEFINE_AS_EP_OFFSETS)	\
	};									\
	static const uint16_t fb_offsets_##i[] = {				\
		DT_INST_FOREACH_CHILD_STATUS_OKAY(i, DEFINE_AS_FB_OFFSETS)	\
	};									\
	static const uint8_t as_terminals_##i[] = {				\
		DT_INST_FOREACH_CHILD_STATUS_OKAY(i, DEFINE_AS_TERMINALS)	\
	};									\
	DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(i, DEFINE_CLOCK_SOURCES, i)

#define DEFINE_UAC2_CLASS_DATA(inst)						\
	DT_INST_FOREACH_CHILD(inst, VALIDATE_NODE)				\
	static struct uac2_ctx uac2_ctx_##inst;					\
	static uint8_t uac2_descriptor_##inst[] = {				\
		UAC2_DESCRIPTORS(DT_DRV_INST(inst))				\
		0x00, 0x00 /* terminator required by USBD stack */		\
	};									\
	static struct usbd_class_data uac2_class_##inst = {			\
		.desc = (struct usb_desc_header *)uac2_descriptor_##inst,	\
		.priv = (void *)DEVICE_DT_GET(DT_DRV_INST(inst)),		\
	};									\
	USBD_DEFINE_CLASS(uac2_##inst, &uac2_api, &uac2_class_##inst);		\
	DEFINE_LOOKUP_TABLES(inst)						\
	static const struct uac2_cfg uac2_cfg_##inst = {			\
		.node = &uac2_##inst,						\
		.entity_types = entity_types_##inst,				\
		.ep_offsets = ep_offsets_##inst,				\
		.fb_offsets = fb_offsets_##inst,				\
		.as_terminals = as_terminals_##inst,				\
		.num_ifaces = ARRAY_SIZE(ep_offsets_##inst),			\
		.num_entities = ARRAY_SIZE(entity_types_##inst),		\
	};									\
	BUILD_ASSERT(ARRAY_SIZE(ep_offsets_##inst) <= 32,			\
		"UAC2 implementation supports up to 32 AS interfaces");		\
	BUILD_ASSERT(ARRAY_SIZE(entity_types_##inst) <= 255,			\
		"UAC2 supports up to 255 entities");				\
	DEVICE_DT_DEFINE(DT_DRV_INST(inst), NULL, NULL,				\
		&uac2_ctx_##inst, &uac2_cfg_##inst,				\
		POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,		\
		NULL);
DT_INST_FOREACH_STATUS_OKAY(DEFINE_UAC2_CLASS_DATA)

static size_t clock_frequencies(struct usbd_class_node *const node,
				const uint8_t id, const uint32_t **frequencies)
{
	const struct device *dev = node->data->priv;
	size_t count;

#define GET_FREQUENCY_TABLE(node, i)						\
	IF_ENABLED(DT_NODE_HAS_COMPAT(node, zephyr_uac2_clock_source), (	\
		} else if (id == ENTITY_ID(node)) {				\
			*frequencies = FREQUENCY_TABLE_NAME(node, i);		\
			count = ARRAY_SIZE(FREQUENCY_TABLE_NAME(node, i));	\
	))

	if (0) {
#define SELECT_FREQUENCY_TABLE(i)						\
	} else if (dev == DEVICE_DT_GET(DT_DRV_INST(i))) {			\
		if (0) {							\
			DT_INST_FOREACH_CHILD_VARGS(i, GET_FREQUENCY_TABLE, i)	\
		} else {							\
			*frequencies = NULL;					\
			count = 0;						\
		}
DT_INST_FOREACH_STATUS_OKAY(SELECT_FREQUENCY_TABLE)
	} else {
		*frequencies = NULL;
		count = 0;
	}

	return count;
}
