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

/**
 * @file
 * @brief Audio device class driver
 *
 * Driver for USB Audio device class driver
 */

#include <kernel.h>
#include <usb/usb_device.h>
#include <usb_descriptor.h>
#include <usb/class/usb_audio.h>
#include "usb_audio_internal.h"

#include <sys/byteorder.h>
#include <sys/util.h>
#include <net/buf.h>

#include <logging/log.h>
LOG_MODULE_REGISTER(usb_audio, CONFIG_USB_AUDIO_LOG_LEVEL);

/* Device data structure */
struct usb_audio_dev_data {
	const struct usb_audio_ops *ops;

	uint8_t *controls[2];

	uint8_t ch_cnt[2];

	const struct cs_ac_if_descriptor *desc_hdr;

	struct usb_dev_data common;

	struct net_buf_pool *pool;

	/* Not applicable for Headphones, left with 0 */
	uint16_t in_frame_size;

	bool rx_enable;
	bool tx_enable;
};

static sys_slist_t usb_audio_data_devlist;

/**
 * @brief Fill the USB Audio descriptor
 *
 * This macro fills USB descriptor for specific type of device
 * (Heahphones or Microphone) depending on dev param.
 *
 * @note Feature unit has variable length and only 1st field of
 *	 .bmaControls is filled. Later its fixed in usb_fix_descriptor()
 * @note Audio control and Audio streaming interfaces are numerated starting
 *	 from 0 and are later fixed in usb_fix_descriptor()
 *
 * @param [in] dev	Device type. Must be HP/MIC
 * @param [in] i	Instance of device of current type (dev)
 * @param [in] id	Param for counting logic entities
 * @param [in] link	ID of IN/OUT terminal to which General Descriptor
 *			is linked.
 * @param [in] it_type	Input terminal type
 * @param [in] ot_type	Output terminal type
 */
#define DEFINE_AUDIO_DESCRIPTOR(dev, i, id, link, it_type, ot_type, cb, addr) \
USBD_CLASS_DESCR_DEFINE(primary, audio)					      \
struct dev##_descriptor_##i dev##_desc_##i = {				      \
	USB_AUDIO_IAD(2)						      \
	.std_ac_interface = INIT_STD_IF(USB_AUDIO_AUDIOCONTROL, 0, 0, 0),     \
	.cs_ac_interface = INIT_CS_AC_IF(dev, i, 1),			      \
	.input_terminal = INIT_IN_TERMINAL(dev, i, id, it_type),	      \
	.feature_unit = INIT_FEATURE_UNIT(dev, i, id + 1, id),		      \
	.output_terminal = INIT_OUT_TERMINAL(id + 2, id + 1, ot_type),	      \
	.as_interface_alt_0 = INIT_STD_IF(USB_AUDIO_AUDIOSTREAMING, 1, 0, 0), \
	.as_interface_alt_1 = INIT_STD_IF(USB_AUDIO_AUDIOSTREAMING, 1, 1, 1), \
	.as_cs_interface = INIT_AS_GENERAL(link),			      \
	.format = INIT_AS_FORMAT_I(CH_CNT(dev, i), GET_RES(dev, i)),	      \
	.std_ep = INIT_STD_AS_AD_EP(dev, i, addr),			      \
	.cs_ep = INIT_CS_AS_AD_EP,					      \
};									      \
static struct usb_ep_cfg_data dev##_usb_audio_ep_data_##i[] = {		      \
	INIT_EP_DATA(cb, addr),						      \
}

/**
 * @brief Fill the USB Audio descriptor
 *
 * This macro fills USB descriptor for specific type of device.
 * Macro is used when the device uses 2 audiostreaming interfaces,
 * eg. Headset
 *
 * @note Feature units have variable length and only 1st field of
 *	 .bmaControls is filled. Its fixed in usb_fix_descriptor()
 * @note Audio control and Audio streaming interfaces are numerated starting
 *	 from 0 and are later fixed in usb_fix_descriptor()
 *
 * @param [in] dev	Device type.
 * @param [in] i	Instance of device of current type (dev)
 * @param [in] id	Param for counting logic entities
 */
#define DEFINE_AUDIO_DESCRIPTOR_BIDIR(dev, i, id)			  \
USBD_CLASS_DESCR_DEFINE(primary, audio)					  \
struct dev##_descriptor_##i dev##_desc_##i = {				  \
	USB_AUDIO_IAD(3)						  \
	.std_ac_interface = INIT_STD_IF(USB_AUDIO_AUDIOCONTROL, 0, 0, 0), \
	.cs_ac_interface = INIT_CS_AC_IF_BIDIR(dev, i, 2),		  \
	.input_terminal_0 = INIT_IN_TERMINAL(dev##_MIC, i, id,		  \
						USB_AUDIO_IO_HEADSET),	  \
	.feature_unit_0 = INIT_FEATURE_UNIT(dev##_MIC, i, id+1, id),	  \
	.output_terminal_0 = INIT_OUT_TERMINAL(id+2, id+1,		  \
					USB_AUDIO_USB_STREAMING),	  \
	.input_terminal_1 = INIT_IN_TERMINAL(dev##_HP, i, id+3,		  \
					USB_AUDIO_USB_STREAMING),	  \
	.feature_unit_1 = INIT_FEATURE_UNIT(dev##_HP, i, id+4, id+3),	  \
	.output_terminal_1 = INIT_OUT_TERMINAL(id+5, id+4,		  \
						USB_AUDIO_IO_HEADSET),	  \
	.as_interface_alt_0_0 = INIT_STD_IF(USB_AUDIO_AUDIOSTREAMING,	  \
						1, 0, 0),		  \
	.as_interface_alt_0_1 = INIT_STD_IF(USB_AUDIO_AUDIOSTREAMING,	  \
						1, 1, 1),		  \
		.as_cs_interface_0 = INIT_AS_GENERAL(id+2),		  \
		.format_0 = INIT_AS_FORMAT_I(CH_CNT(dev##_MIC, i),	  \
					     GET_RES(dev##_MIC, i)),	  \
		.std_ep_0 = INIT_STD_AS_AD_EP(dev##_MIC, i,		  \
						   AUTO_EP_IN),		  \
		.cs_ep_0 = INIT_CS_AS_AD_EP,				  \
	.as_interface_alt_1_0 = INIT_STD_IF(USB_AUDIO_AUDIOSTREAMING,	  \
						2, 0, 0),		  \
	.as_interface_alt_1_1 = INIT_STD_IF(USB_AUDIO_AUDIOSTREAMING,	  \
						2, 1, 1),		  \
		.as_cs_interface_1 = INIT_AS_GENERAL(id+3),		  \
		.format_1 = INIT_AS_FORMAT_I(CH_CNT(dev##_HP, i),	  \
					     GET_RES(dev##_HP, i)),	  \
		.std_ep_1 = INIT_STD_AS_AD_EP(dev##_HP, i,		  \
						   AUTO_EP_OUT),	  \
		.cs_ep_1 = INIT_CS_AS_AD_EP,				  \
};									  \
static struct usb_ep_cfg_data dev##_usb_audio_ep_data_##i[] = {		  \
	INIT_EP_DATA(usb_transfer_ep_callback, AUTO_EP_IN),		  \
	INIT_EP_DATA(audio_receive_cb, AUTO_EP_OUT),			  \
}

#define DEFINE_AUDIO_DEV_DATA(dev, i, __out_pool, __in_pool_size)   \
	static uint8_t dev##_controls_##i[FEATURES_SIZE(dev, i)] = {0};\
	static struct usb_audio_dev_data dev##_audio_dev_data_##i = \
		{ .pool = __out_pool,				    \
		  .in_frame_size = __in_pool_size,		    \
		  .controls = {dev##_controls_##i, NULL},	    \
		  .ch_cnt = {(CH_CNT(dev, i) + 1), 0}		    \
		}

#define DEFINE_AUDIO_DEV_DATA_BIDIR(dev, i, __out_pool, __in_pool_size)	   \
	static uint8_t dev##_controls0_##i[FEATURES_SIZE(dev##_MIC, i)] = {0};\
	static uint8_t dev##_controls1_##i[FEATURES_SIZE(dev##_HP, i)] = {0}; \
	static struct usb_audio_dev_data dev##_audio_dev_data_##i =	   \
		{ .pool = __out_pool,					   \
		  .in_frame_size = __in_pool_size,			   \
		  .controls = {dev##_controls0_##i, dev##_controls1_##i},  \
		  .ch_cnt = {(CH_CNT(dev##_MIC, i) + 1),		   \
			     (CH_CNT(dev##_HP, i) + 1)}			   \
		}

/**
 * Helper function for getting channel number directly from the
 * feature unit descriptor.
 */
static uint8_t get_num_of_channels(const struct feature_unit_descriptor *fu)
{
	return (fu->bLength - FU_FIXED_ELEMS_SIZE)/sizeof(uint16_t);
}

/**
 * Helper function for getting supported controls directly from
 * the feature unit descriptor.
 */
static uint16_t get_controls(const struct feature_unit_descriptor *fu)
{
	return sys_get_le16((uint8_t *)&fu->bmaControls[0]);
}

/**
 * Helper function for getting the device streaming direction
 */
static enum usb_audio_direction get_fu_dir(
				const struct feature_unit_descriptor *fu)
{
	const struct output_terminal_descriptor *ot =
		(struct output_terminal_descriptor *)
		((uint8_t *)fu + fu->bLength);
	enum usb_audio_direction dir;

	if (ot->wTerminalType == USB_AUDIO_USB_STREAMING) {
		dir = USB_AUDIO_IN;
	} else {
		dir = USB_AUDIO_OUT;
	}

	return dir;
}

/**
 * Helper function for fixing controls in feature units descriptors.
 */
static void fix_fu_descriptors(struct usb_if_descriptor *iface)
{
	struct cs_ac_if_descriptor *header;
	struct feature_unit_descriptor *fu;

	header = (struct cs_ac_if_descriptor *)
			((uint8_t *)iface + USB_PASSIVE_IF_DESC_SIZE);

	fu = (struct feature_unit_descriptor *)((uint8_t *)header +
						header->bLength +
						INPUT_TERMINAL_DESC_SIZE);

	/* start from 1 as elem 0 is filled when descriptor is declared */
	for (int i = 1; i < get_num_of_channels(fu); i++) {
		(void)memcpy(&fu->bmaControls[i],
			     &fu->bmaControls[0],
			     sizeof(uint16_t));
	}

	if (header->bInCollection == 2) {
		fu = (struct feature_unit_descriptor *)((uint8_t *)fu +
			fu->bLength +
			INPUT_TERMINAL_DESC_SIZE +
			OUTPUT_TERMINAL_DESC_SIZE);
		for (int i = 1; i < get_num_of_channels(fu); i++) {
			(void)memcpy(&fu->bmaControls[i],
				     &fu->bmaControls[0],
				     sizeof(uint16_t));
		}
	}
}

/**
 * Helper function for getting pointer to feature unit descriptor.
 * This is needed in order to address audio specific requests to proper
 * controls struct.
 */
static struct feature_unit_descriptor *get_feature_unit(
				struct usb_audio_dev_data *audio_dev_data,
				uint8_t *device, uint8_t fu_id)
{
	struct feature_unit_descriptor *fu;

	fu = (struct feature_unit_descriptor *)
		((uint8_t *)audio_dev_data->desc_hdr +
		audio_dev_data->desc_hdr->bLength +
		INPUT_TERMINAL_DESC_SIZE);

	if (fu->bUnitID == fu_id) {
		*device = 0;
		return fu;
	}
	/* skip to the next Feature Unit */
	fu = (struct feature_unit_descriptor *)
			((uint8_t *)fu + fu->bLength +
			INPUT_TERMINAL_DESC_SIZE +
			OUTPUT_TERMINAL_DESC_SIZE);
	*device = 1;

	return fu;
}

/**
 * @brief This is a helper function user to inform the user about
 * possibility to write the data to the device.
 */
static void audio_dc_sof(struct usb_cfg_data *cfg,
			 struct usb_audio_dev_data *dev_data)
{
	uint8_t ep_addr;

	/* In endpoint always at index 0 */
	ep_addr = cfg->endpoint[0].ep_addr;
	if ((ep_addr & USB_EP_DIR_MASK) && (dev_data->tx_enable)) {
		if (dev_data->ops && dev_data->ops->data_request_cb) {
			dev_data->ops->data_request_cb(
				dev_data->common.dev);
		}
	}
}

static void audio_interface_config(struct usb_desc_header *head,
				   uint8_t bInterfaceNumber)
{
	struct usb_if_descriptor *iface = (struct usb_if_descriptor *)head;
	struct cs_ac_if_descriptor *header;

#ifdef CONFIG_USB_COMPOSITE_DEVICE
	struct usb_association_descriptor *iad =
		(struct usb_association_descriptor *)
		((char *)iface - sizeof(struct usb_association_descriptor));
	iad->bFirstInterface = bInterfaceNumber;
#endif
	fix_fu_descriptors(iface);

	/* Audio Control Interface */
	iface->bInterfaceNumber = bInterfaceNumber;
	header = (struct cs_ac_if_descriptor *)
		 ((uint8_t *)iface + iface->bLength);
	header->baInterfaceNr[0] = bInterfaceNumber + 1;

	/* Audio Streaming Interface Passive */
	iface = (struct usb_if_descriptor *)
			  ((uint8_t *)header + header->wTotalLength);
	iface->bInterfaceNumber = bInterfaceNumber + 1;

	/* Audio Streaming Interface Active */
	iface = (struct usb_if_descriptor *)
			  ((uint8_t *)iface + iface->bLength);
	iface->bInterfaceNumber = bInterfaceNumber + 1;

	if (header->bInCollection == 2) {
		header->baInterfaceNr[1] = bInterfaceNumber + 2;
		/* Audio Streaming Interface Passive */
		iface = (struct usb_if_descriptor *)
			((uint8_t *)iface + USB_ACTIVE_IF_DESC_SIZE);
		iface->bInterfaceNumber = bInterfaceNumber + 2;

		/* Audio Streaming Interface Active */
		iface = (struct usb_if_descriptor *)
			((uint8_t *)iface + USB_PASSIVE_IF_DESC_SIZE);
		iface->bInterfaceNumber = bInterfaceNumber + 2;
	}
}

static void audio_cb_usb_status(struct usb_cfg_data *cfg,
			 enum usb_dc_status_code cb_status,
			 const uint8_t *param)
{
	struct usb_audio_dev_data *audio_dev_data;
	struct usb_dev_data *dev_data;

	dev_data = usb_get_dev_data_by_cfg(&usb_audio_data_devlist, cfg);

	if (dev_data == NULL) {
		LOG_ERR("Device data not found for cfg %p", cfg);
		return;
	}

	audio_dev_data = CONTAINER_OF(dev_data, struct usb_audio_dev_data,
				      common);

	switch (cb_status) {
	case USB_DC_SOF:
		audio_dc_sof(cfg, audio_dev_data);
		break;
	default:
		break;
	}
}

/**
 * @brief Helper funciton for checking if particular entity is a part of
 *	  the audio device.
 *
 * This function checks if given entity is a part of given audio device.
 * If so then true is returned and audio_dev_data is considered correct device
 * data.
 *
 * @note For now this function searches through feature units only. The
 *	 descriptors are known and are not using any other entity type.
 *	 If there is a need to add other units to audio function then this
 *	 must be reworked.
 *
 * @param [in]      audio_dev_data USB audio device data.
 * @param [in, out] entity	   USB Audio entity.
 *				   .id      [in]  id of searched entity
 *				   .subtype [out] subtype of entity (if found)
 *
 * @return true if entity matched audio_dev_data, false otherwise.
 */
static bool is_entity_valid(struct usb_audio_dev_data *audio_dev_data,
			    struct usb_audio_entity *entity)
{
	const struct cs_ac_if_descriptor *header;
	const struct feature_unit_descriptor *fu;

	header = audio_dev_data->desc_hdr;
	fu = (struct feature_unit_descriptor *)((uint8_t *)header +
						header->bLength +
						INPUT_TERMINAL_DESC_SIZE);
	if (fu->bUnitID == entity->id) {
		entity->subtype = fu->bDescriptorSubtype;
		return true;
	}

	if (header->bInCollection == 2) {
		fu = (struct feature_unit_descriptor *)((uint8_t *)fu +
			fu->bLength +
			INPUT_TERMINAL_DESC_SIZE +
			OUTPUT_TERMINAL_DESC_SIZE);
		if (fu->bUnitID == entity->id) {
			entity->subtype = fu->bDescriptorSubtype;
			return true;
		}
	}

	return false;
}

/**
 * @brief Helper funciton for getting the audio_dev_data by the entity number.
 *
 * This function searches through all audio devices the one with given
 * entity number and return the audio_dev_data structure for this entity.
 *
 * @param [in, out] entity USB Audio entity addressed by the request.
 *			   .id      [in]  id of searched entity
 *			   .subtype [out] subtype of entity (if found)
 *
 * @return audio_dev_data for given entity, NULL if not found.
 */
static struct usb_audio_dev_data *get_audio_dev_data_by_entity(
					struct usb_audio_entity *entity)
{
	struct usb_dev_data *dev_data;
	struct usb_audio_dev_data *audio_dev_data;

	SYS_SLIST_FOR_EACH_CONTAINER(&usb_audio_data_devlist, dev_data, node) {
		audio_dev_data = CONTAINER_OF(dev_data,
					      struct usb_audio_dev_data,
					      common);

		if (is_entity_valid(audio_dev_data, entity)) {
			return audio_dev_data;
		}
	}
	return NULL;
}

/**
 * @brief Helper funciton for checking if particular interface is a part of
 *	  the audio device.
 *
 * This function checks if given interface is a part of given audio device.
 * If so then true is returned and audio_dev_data is considered correct device
 * data.
 *
 * @param [in] audio_dev_data USB audio device data.
 * @param [in] interface      USB Audio interface number.
 *
 * @return true if interface matched audio_dev_data, false otherwise.
 */
static bool is_interface_valid(struct usb_audio_dev_data *audio_dev_data,
			       uint8_t interface)
{
	const struct cs_ac_if_descriptor *header;

	header = audio_dev_data->desc_hdr;
	uint8_t desc_iface = 0;

	for (size_t i = 0; i < header->bInCollection; i++) {
		desc_iface = header->baInterfaceNr[i];
		if (desc_iface == interface) {
			return true;
		}
	}

	return false;
}

/**
 * @brief Helper funciton for getting the audio_dev_data by the interface
 *	  number.
 *
 * This function searches through all audio devices the one with given
 * interface number and returns the audio_dev_data structure for this device.
 *
 * @param [in] interface USB Audio interface addressed by the request.
 *
 * @return audio_dev_data for given interface, NULL if not found.
 */
static struct usb_audio_dev_data *get_audio_dev_data_by_iface(uint8_t interface)
{
	struct usb_dev_data *dev_data;
	struct usb_audio_dev_data *audio_dev_data;

	SYS_SLIST_FOR_EACH_CONTAINER(&usb_audio_data_devlist, dev_data, node) {
		audio_dev_data = CONTAINER_OF(dev_data,
					      struct usb_audio_dev_data,
					      common);

		if (is_interface_valid(audio_dev_data, interface)) {
			return audio_dev_data;
		}
	}
	return NULL;
}

/**
 * @brief Handler for feature unit mute control requests.
 *
 * This function handles feature unit mute control request.
 *
 * @param audio_dev_data USB audio device data.
 * @param setup          Information about the executed request.
 * @param len		 Size of the buffer.
 * @param data		 Buffer containing the request result.
 * @param evt		 Feature Unit Event info.
 * @param device	 Device part that has been addressed. Applicable for
 *			 bidirectional device.
 *
 * @return 0 if succesfulf, negative errno otherwise.
 */
static int handle_fu_mute_req(struct usb_audio_dev_data *audio_dev_data,
			      struct usb_setup_packet *setup,
			      int32_t *len, uint8_t **data,
			      struct usb_audio_fu_evt *evt,
			      uint8_t device)
{
	uint8_t ch = (setup->wValue) & 0xFF;
	uint8_t ch_cnt = audio_dev_data->ch_cnt[device];
	uint8_t *controls = audio_dev_data->controls[device];
	uint8_t *control_val = &controls[POS(MUTE, ch, ch_cnt)];

	if (usb_reqtype_is_to_device(setup)) {
		/* Check if *len has valid value */
		if (*len != LEN(1, MUTE)) {
			return -EINVAL;
		}

		if (setup->bRequest == USB_AUDIO_SET_CUR) {
			evt->val = control_val;
			evt->val_len = *len;
			memcpy(control_val, *data, *len);
			return 0;
		}
	} else {
		if (setup->bRequest == USB_AUDIO_GET_CUR) {
			*data = control_val;
			*len = LEN(1, MUTE);
			return 0;
		}
	}

	return -EINVAL;
}

/**
 * @brief Handler for feature unit requests.
 *
 * This function handles feature unit specific requests.
 * If request is properly served 0 is returned. Negative errno
 * is returned in case of an error. This leads to setting stall on IN EP0.
 *
 * @param audio_dev_data USB audio device data.
 * @param pSetup         Information about the executed request.
 * @param len            Size of the buffer.
 * @param data           Buffer containing the request result.
 *
 * @return 0 if succesfulf, negative errno otherwise.
 */
static int handle_feature_unit_req(struct usb_audio_dev_data *audio_dev_data,
				   struct usb_setup_packet *pSetup,
				   int32_t *len, uint8_t **data)
{
	const struct feature_unit_descriptor *fu;
	struct usb_audio_fu_evt evt;
	enum usb_audio_fucs cs;
	uint8_t device;
	uint8_t fu_id;
	uint8_t ch_cnt;
	uint8_t ch;
	int ret;

	fu_id = ((pSetup->wIndex) >> 8) & 0xFF;
	fu = get_feature_unit(audio_dev_data, &device, fu_id);
	ch = (pSetup->wValue) & 0xFF;
	cs = ((pSetup->wValue) >> 8) & 0xFF;
	ch_cnt = audio_dev_data->ch_cnt[device];

	LOG_DBG("CS: %d, CN: %d, len: %d", cs, ch, *len);

	/* Error checking */
	if (!(BIT(cs) & (get_controls(fu) << 1))) {
		/* Feature not supported by this FU */
		return -EINVAL;
	} else if (ch >= ch_cnt) {
		/* Invalid ch */
		return -EINVAL;
	}

	switch (cs) {
	case USB_AUDIO_FU_MUTE_CONTROL:
		ret = handle_fu_mute_req(audio_dev_data, pSetup,
					 len, data, &evt, device);
		break;
	default:
		return -ENOTSUP;
	}

	if (ret) {
		return ret;
	}

	/* Inform the app */
	if (audio_dev_data->ops && audio_dev_data->ops->feature_update_cb) {
		if (usb_reqtype_is_to_device(pSetup) &&
		    pSetup->bRequest == USB_AUDIO_SET_CUR) {
			evt.cs = cs;
			evt.channel = ch;
			evt.dir = get_fu_dir(fu);
			audio_dev_data->ops->feature_update_cb(
					audio_dev_data->common.dev, &evt);
		}
	}

	return 0;
}

/**
 * @brief Handler called for class specific interface request.
 *
 * This function handles all class specific interface requests to a usb audio
 * device. If request is properly server then 0 is returned. Returning negative
 * value will lead to set stall on IN EP0.
 *
 * @param pSetup    Information about the executed request.
 * @param len       Size of the buffer.
 * @param data      Buffer containing the request result.
 *
 * @return  0 on success, negative errno code on fail.
 */
static int handle_interface_req(struct usb_setup_packet *pSetup,
				int32_t *len,
				uint8_t **data)
{
	struct usb_audio_dev_data *audio_dev_data;
	struct usb_audio_entity entity;

	/* parse wIndex for interface request */
	uint8_t entity_id = ((pSetup->wIndex) >> 8) & 0xFF;

	entity.id = entity_id;

	/** Normally there should be a call to usb_get_dev_data_by_iface()
	 * and addressed interface should be read from wIndex low byte.
	 *
	 * uint8_t interface = (pSetup->wIndex) & 0xFF;
	 *
	 * However, Linux is using special form of Audio Requests
	 * which always left wIndex low byte 0 no matter which device and
	 * entity is addressed. Because of that there is a need to obtain
	 * this information from the device descriptor using entity id.
	 */
	audio_dev_data = get_audio_dev_data_by_entity(&entity);

	if (audio_dev_data == NULL) {
		LOG_ERR("Device data not found for entity %u", entity.id);
		return -ENODEV;
	}

	switch (entity.subtype) {
	case USB_AUDIO_FEATURE_UNIT:
		return handle_feature_unit_req(audio_dev_data,
					       pSetup, len, data);
	default:
		LOG_INF("Currently not supported");
		return -ENODEV;
	}

	return 0;
}

/**
 * @brief Custom callback for USB Device requests.
 *
 * This callback is called when set/get interface request is directed
 * to the device. This is Zephyr way to address those requests.
 * It's not possible to do that in the core stack as common USB device
 * stack does not know the amount of devices that has alternate interfaces.
 *
 * @param pSetup    Information about the request to execute.
 * @param len       Size of the buffer.
 * @param data      Buffer containing the request result.
 *
 * @return 0 on success, positive value if request is intended to be handled
 *	   by the core USB stack. Negative error code on fail.
 */
static int audio_custom_handler(struct usb_setup_packet *pSetup, int32_t *len,
				uint8_t **data)
{
	const struct cs_ac_if_descriptor *header;
	struct usb_audio_dev_data *audio_dev_data;
	const struct usb_if_descriptor *if_desc;
	const struct usb_ep_descriptor *ep_desc;

	uint8_t iface = (pSetup->wIndex) & 0xFF;

	if (pSetup->RequestType.recipient != USB_REQTYPE_RECIPIENT_INTERFACE ||
	    usb_reqtype_is_to_host(pSetup)) {
		return -EINVAL;
	}

	audio_dev_data = get_audio_dev_data_by_iface(iface);
	if (audio_dev_data == NULL) {
		return -EINVAL;
	}

	/* Search for endpoint associated to addressed interface
	 * Endpoint is searched in order to know the direction of
	 * addressed interface.
	 */
	header = audio_dev_data->desc_hdr;

	/* Skip to the first interface */
	if_desc = (struct usb_if_descriptor *)((uint8_t *)header +
						header->wTotalLength +
						USB_PASSIVE_IF_DESC_SIZE);

	if (if_desc->bInterfaceNumber == iface) {
		ep_desc = (struct usb_ep_descriptor *)((uint8_t *)if_desc +
						USB_PASSIVE_IF_DESC_SIZE +
						USB_AC_CS_IF_DESC_SIZE +
						USB_FORMAT_TYPE_I_DESC_SIZE);
	} else {
		/* In case first interface address is not the one addressed
		 * we can be sure the second one is because
		 * get_audio_dev_data_by_iface() found the device. It
		 * must be the second interface associated with the device.
		 */
		if_desc = (struct usb_if_descriptor *)((uint8_t *)if_desc +
						USB_ACTIVE_IF_DESC_SIZE);
		ep_desc = (struct usb_ep_descriptor *)((uint8_t *)if_desc +
						USB_PASSIVE_IF_DESC_SIZE +
						USB_AC_CS_IF_DESC_SIZE +
						USB_FORMAT_TYPE_I_DESC_SIZE);
	}

	if (pSetup->bRequest == USB_SREQ_SET_INTERFACE) {
		if (ep_desc->bEndpointAddress & USB_EP_DIR_MASK) {
			audio_dev_data->tx_enable = pSetup->wValue;
		} else {
			audio_dev_data->rx_enable = pSetup->wValue;
		}
	}

	return -EINVAL;
}

/**
 * @brief Handler called for Class requests not handled by the USB stack.
 *
 * @param pSetup    Information about the request to execute.
 * @param len       Size of the buffer.
 * @param data      Buffer containing the request result.
 *
 * @return  0 on success, negative errno code on fail.
 */
static int audio_class_handle_req(struct usb_setup_packet *pSetup,
				  int32_t *len, uint8_t **data)
{
	LOG_DBG("bmRT 0x%02x, bR 0x%02x, wV 0x%04x, wI 0x%04x, wL 0x%04x",
		pSetup->bmRequestType, pSetup->bRequest, pSetup->wValue,
		pSetup->wIndex, pSetup->wLength);

	switch (pSetup->RequestType.recipient) {
	case USB_REQTYPE_RECIPIENT_INTERFACE:
		return handle_interface_req(pSetup, len, data);
	default:
		LOG_ERR("Request recipient invalid");
		return -EINVAL;
	}
}

static int usb_audio_device_init(const struct device *dev)
{
	LOG_DBG("Init Audio Device: dev %p (%s)", dev, dev->name);

	return 0;
}

static void audio_write_cb(uint8_t ep, int size, void *priv)
{
	struct usb_dev_data *dev_data;
	struct usb_audio_dev_data *audio_dev_data;
	struct net_buf *buffer = priv;

	dev_data = usb_get_dev_data_by_ep(&usb_audio_data_devlist, ep);
	audio_dev_data = dev_data->dev->data;

	LOG_DBG("Written %d bytes on ep 0x%02x, *audio_dev_data %p",
		size, ep, audio_dev_data);

	/* Ask installed callback to process the data.
	 * User is responsible for freeing the buffer.
	 * In case no callback is installed free the buffer.
	 */
	if (audio_dev_data->ops && audio_dev_data->ops->data_written_cb) {
		audio_dev_data->ops->data_written_cb(dev_data->dev,
						     buffer, size);
	} else {
		/* Release net_buf back to the pool */
		net_buf_unref(buffer);
	}
}

int usb_audio_send(const struct device *dev, struct net_buf *buffer,
		   size_t len)
{
	struct usb_audio_dev_data *audio_dev_data = dev->data;
	struct usb_cfg_data *cfg = (void *)dev->config;
	/* EP ISO IN is always placed first in the endpoint table */
	uint8_t ep = cfg->endpoint[0].ep_addr;

	if (!(ep & USB_EP_DIR_MASK)) {
		LOG_ERR("Wrong device");
		return -EINVAL;
	}

	if (!audio_dev_data->tx_enable) {
		LOG_DBG("sending dropped -> Host chose passive interface");
		return -EAGAIN;
	}

	if (len > buffer->size) {
		LOG_ERR("Cannot send %d bytes, to much data", len);
		return -EINVAL;
	}

	/** buffer passed to *priv because completion callback
	 * needs to release it to the pool
	 */
	usb_transfer(ep, buffer->data, len, USB_TRANS_WRITE | USB_TRANS_NO_ZLP,
		     audio_write_cb, buffer);
	return 0;
}

size_t usb_audio_get_in_frame_size(const struct device *dev)
{
	struct usb_audio_dev_data *audio_dev_data = dev->data;

	return audio_dev_data->in_frame_size;
}

static void audio_receive_cb(uint8_t ep, enum usb_dc_ep_cb_status_code status)
{
	struct usb_audio_dev_data *audio_dev_data;
	struct usb_dev_data *common;
	struct net_buf *buffer;
	int ret_bytes;
	int ret;

	__ASSERT(status == USB_DC_EP_DATA_OUT, "Invalid ep status");

	common = usb_get_dev_data_by_ep(&usb_audio_data_devlist, ep);
	if (common == NULL) {
		return;
	}

	audio_dev_data = CONTAINER_OF(common, struct usb_audio_dev_data,
				      common);

	/** Check if active audiostreaming interface is selected
	 * If no there is no point to read the data. Return from callback
	 */
	if (!audio_dev_data->rx_enable) {
		return;
	}

	/* Check if application installed callback and process the data.
	 * In case no callback is installed do not alloc the buffer at all.
	 */
	if (audio_dev_data->ops && audio_dev_data->ops->data_received_cb) {
		buffer = net_buf_alloc(audio_dev_data->pool, K_NO_WAIT);
		if (!buffer) {
			LOG_ERR("Failed to allocate data buffer");
			return;
		}

		ret = usb_read(ep, buffer->data, buffer->size, &ret_bytes);

		if (ret) {
			LOG_ERR("ret=%d ", ret);
			net_buf_unref(buffer);
			return;
		}

		if (!ret_bytes) {
			net_buf_unref(buffer);
			return;
		}
		audio_dev_data->ops->data_received_cb(common->dev,
						      buffer, ret_bytes);
	}
}

void usb_audio_register(const struct device *dev,
			const struct usb_audio_ops *ops)
{
	struct usb_audio_dev_data *audio_dev_data = dev->data;
	const struct usb_cfg_data *cfg = dev->config;
	const struct std_if_descriptor *iface_descr =
		cfg->interface_descriptor;
	const struct cs_ac_if_descriptor *header =
		(struct cs_ac_if_descriptor *)
		((uint8_t *)iface_descr + USB_PASSIVE_IF_DESC_SIZE);

	audio_dev_data->ops = ops;
	audio_dev_data->common.dev = dev;
	audio_dev_data->rx_enable = false;
	audio_dev_data->tx_enable = false;
	audio_dev_data->desc_hdr = header;

	sys_slist_append(&usb_audio_data_devlist, &audio_dev_data->common.node);

	LOG_DBG("Device dev %p dev_data %p cfg %p added to devlist %p",
		dev, audio_dev_data, dev->config,
		&usb_audio_data_devlist);
}

#define DEFINE_AUDIO_DEVICE(dev, i)					  \
	USBD_CFG_DATA_DEFINE(primary, audio)				  \
	struct usb_cfg_data dev##_audio_config_##i = {			  \
		.usb_device_description	= NULL,				  \
		.interface_config = audio_interface_config,		  \
		.interface_descriptor = &dev##_desc_##i.std_ac_interface, \
		.cb_usb_status = audio_cb_usb_status,			  \
		.interface = {						  \
			.class_handler = audio_class_handle_req,	  \
			.custom_handler = audio_custom_handler,		  \
			.vendor_handler = NULL,				  \
		},							  \
		.num_endpoints = ARRAY_SIZE(dev##_usb_audio_ep_data_##i), \
		.endpoint = dev##_usb_audio_ep_data_##i,		  \
	};								  \
	DEVICE_DT_DEFINE(DT_INST(i, COMPAT_##dev),			  \
			    &usb_audio_device_init,			  \
			    NULL,					  \
			    &dev##_audio_dev_data_##i,			  \
			    &dev##_audio_config_##i, APPLICATION,	  \
			    CONFIG_KERNEL_INIT_PRIORITY_DEVICE,		  \
			    DUMMY_API)

#define DEFINE_BUF_POOL(name, size) \
	NET_BUF_POOL_FIXED_DEFINE(name, 5, size, net_buf_destroy)

#define UNIDIR_DEVICE(dev, i, out_pool, in_size, it_type, ot_type, cb, addr) \
	UTIL_EXPAND( \
	DEFINE_AUDIO_DEV_DATA(dev, i, out_pool, in_size); \
	DECLARE_DESCRIPTOR(dev, i, 1); \
	DEFINE_AUDIO_DESCRIPTOR(dev, i, dev##_ID(i), dev##_LINK(i), \
				it_type, ot_type, cb, addr); \
	DEFINE_AUDIO_DEVICE(dev, i))

#define HEADPHONES_DEVICE(i, dev) UTIL_EXPAND( \
	DEFINE_BUF_POOL(audio_data_pool_hp_##i, EP_SIZE(dev, i));  \
	UNIDIR_DEVICE(dev, i, &audio_data_pool_hp_##i, 0, \
		      USB_AUDIO_USB_STREAMING, USB_AUDIO_OUT_HEADPHONES, \
		      audio_receive_cb, AUTO_EP_OUT);)

#define MICROPHONE_DEVICE(i, dev) UTIL_EXPAND( \
	UNIDIR_DEVICE(dev, i, NULL, EP_SIZE(dev, i), \
		      USB_AUDIO_IN_MICROPHONE, USB_AUDIO_USB_STREAMING, \
		      usb_transfer_ep_callback, AUTO_EP_IN);)

#define HEADSET_DEVICE(i, dev) UTIL_EXPAND( \
	DEFINE_BUF_POOL(audio_data_pool_hs_##i, EP_SIZE(dev##_HP, i)); \
	DEFINE_AUDIO_DEV_DATA_BIDIR(dev, i, &audio_data_pool_hs_##i, \
				    EP_SIZE(dev##_MIC, i)); \
	DECLARE_DESCRIPTOR_BIDIR(dev, i, 2); \
	DEFINE_AUDIO_DESCRIPTOR_BIDIR(dev, i, dev##_ID(i)); \
	DEFINE_AUDIO_DEVICE(dev, i);)

UTIL_LISTIFY(HEADPHONES_DEVICE_COUNT, HEADPHONES_DEVICE, HP)
UTIL_LISTIFY(MICROPHONE_DEVICE_COUNT, MICROPHONE_DEVICE, MIC)
UTIL_LISTIFY(HEADSET_DEVICE_COUNT, HEADSET_DEVICE, HS)
