/**
 * USB Audio Class protocol definitions
 * Copyright (c) 2021 Bigscreen
 */
 
 
#ifndef _USB_PROTOCOL_AUDIO_H_
#define _USB_PROTOCOL_AUDIO_H_

#include "compiler.h"

// Audio Interface Class Code
#define AUDIO_CLASS_DEVICE		0x01 // USB Audio Device Class

// Audio Interface Subclass Codes
#define AUDIO_SUBCLASS_UNDEFINED    0x00
#define AUDIO_SUBCLASS_CONTROL      0x01
#define AUDIO_SUBCLASS_STREAMING    0x02
#define AUDIO_SUBCLASS_MIDISTREAMING    0x03

// Audio Interface Protocol Codes
#define AUDIO_PROTOCOL_UNDEFINED    0x00

// Audio Class-Specific Descriptor Types
#define AUDIO_CS_UNDEFINED          0x20
#define AUDIO_CS_DEVICE             0x21
#define AUDIO_CS_CONFIGURATION      0x22
#define AUDIO_CS_STRING             0x23
#define AUDIO_CS_INTERFACE          0x24
#define AUDIO_CS_ENDPOINT           0x25

// Audio Class-Specific AC Interface Descriptor Subtypes
#define AUDIO_AC_DESCRIPTOR_UNDEFINED   0x00
#define AUDIO_AC_HEADER             0x01
#define AUDIO_AC_INPUT_TERMINAL     0x02
#define AUDIO_AC_OUTPUT_TERMINAL    0x03
#define AUDIO_AC_MIXER_UNIT         0x04
#define AUDIO_AC_SELECTOR_UNIT      0x05
#define AUDIO_AC_FEATURE_UNIT       0x06
#define AUDIO_AC_PROCESSING_UNIT    0x07
#define AUDIO_AC_EXTENSION_UNIT     0x08

// Audio Class-Specific AS Interface Descriptor Subtypes
#define AUDIO_AS_DESCRIPTOR_UNDEFINED   0x00
#define AUDIO_AS_GENERAL            0x01
#define AUDIO_AS_FORMAT_TYPE        0x02
#define AUDIO_AS_FORMAT_SPECIFIC    0x03

// Audio Processing Unit Types
#define AUDIO_PROCESS_UNDEFINED     0x00
#define AUDIO_PROCESS_UPDOWNMIX     0x01
#define AUDIO_PROCESS_DOLBY_PROLOGIC    0x02
#define AUDIO_PROCESS_3D_STEREO_EXENDER 0x03
#define AUDIO_PROCESS_REVERBERATION 0x04
#define AUDIO_PROCESS_CHORUS        0x05
#define AUDIO_PROCESS_DYN_RANGE_COMP    0x06

// Audio Class-Specific Endpoint Descriptor Subtypes
#define AUDIO_DESCRIPTOR_UNDEFINED  0x00
#define AUDIO_DESCRIPTOR_EP_GENERAL 0x01

// Requests...TODO

// Descriptors
COMPILER_PACK_SET(1)

// Audio AC Interface Header Descriptor
#define USB_AUDIO_NR_IFACE      1
typedef struct {
	uint8_t bLength;
	uint8_t bDescriptorType;
	uint8_t bDescriptorSubtype;
	le16_t bcdADC;
    le16_t wTotalLength;
    uint8_t bInCollection;
    uint8_t baInterfaceNr[USB_AUDIO_NR_IFACE];
} usb_audio_ac_interface_hdr_desc_t;

// Input Terminal Descriptor
typedef struct {
    uint8_t bLength;
    uint8_t bDescriptorType;
	uint8_t bDescriptorSubtype;
    uint8_t bTerminalId;
    le16_t wTerminalType;
    uint8_t bAssocTerminal;
    uint8_t bNrChannels;
    le16_t wChannelConfig;
    uint8_t iChannelNames;
    uint8_t iTerminal;
} usb_audio_input_terminal_desc_t;

// Ouput Terminal Descriptor
typedef struct {
    uint8_t bLength;
    uint8_t bDescriptorType;
	uint8_t bDescriptorSubtype;
    uint8_t bTerminalId;
    le16_t wTerminalType;
    uint8_t bAssocTerminal;
    uint8_t bSourceID;
    uint8_t iTerminal;
} usb_audio_output_terminal_desc_t;

// Audio Class-Specific Interface Descriptor
typedef struct {
    uint8_t bLength;
    uint8_t bDescriptorType;
    uint8_t bDescriptorSubtype;
    uint8_t bTerminalLink;
    uint8_t bDelay;
    le16_t wFormatTag;
} usb_audio_cs_iface_desc_t;

// Extended standard endpoint descriptor
typedef struct {
    uint8_t bLength;
    uint8_t bDescriptorType;
    uint8_t bEndpointAddress;
    uint8_t bmAttributes;
    le16_t wMaxPacketSize;
    uint8_t bInterval;
    uint8_t bRefresh;
    uint8_t bSynchAddress;
} usb_ep_ext_desc_t;

// Audio Class-Specific Streaming Endpoint Descriptor
typedef struct {
    uint8_t bLength;
    uint8_t bDescriptorType;
    uint8_t bDescriptorSubtype;
    uint8_t bmAttributes;
    uint8_t bLockDelayUnits;
    le16_t wLockDelay;
} usb_audio_cs_endpoint_desc_t;

// Audio Format Type I Descriptor
#define USB_AUDIO_NR_SAM_FREQ   1
typedef struct {
    uint8_t bLength;
    uint8_t bDescriptorType;
    uint8_t bDescriptorSubtype;
    uint8_t bFormatType;
    uint8_t bNrChannels;
    uint8_t bSubframeSize;
    uint8_t bBitResolution;
    uint8_t bSamFreqType;
    uint8_t tSamFreq[USB_AUDIO_NR_SAM_FREQ][3];
} usb_audio_format_type_i_desc_t;

COMPILER_PACK_RESET()

#endif