Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8fee4aff authored by Daniel Mack's avatar Daniel Mack Committed by Takashi Iwai
Browse files

ALSA: usbaudio: introduce new types for audio class v2



This patch adds some definitions for audio class v2.

Unfortunately, the UNIT types PROCESSING_UNIT and EXTENSION_UNIT have
different numerical representations in both standards, so there is need
for a _V1 add-on now. usbmixer.c is changed accordingly.

Signed-off-by: default avatarDaniel Mack <daniel@caiaq.de>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 28e1b773
Loading
Loading
Loading
Loading
+57 −0
Original line number Diff line number Diff line
@@ -25,6 +25,9 @@
#define USB_SUBCLASS_AUDIOSTREAMING	0x02
#define USB_SUBCLASS_MIDISTREAMING	0x03

#define UAC_VERSION_1			0x00
#define UAC_VERSION_2			0x20

/* A.5 Audio Class-Specific AC Interface Descriptor Subtypes */
#define UAC_HEADER			0x01
#define UAC_INPUT_TERMINAL		0x02
@@ -180,6 +183,19 @@ struct uac_as_header_descriptor_v1 {
	__le16 wFormatTag;		/* The Audio Data Format */
} __attribute__ ((packed));

struct uac_as_header_descriptor_v2 {
	__u8 bLength;
	__u8 bDescriptorType;
	__u8 bDescriptorSubtype;
	__u8 bTerminalLink;
	__u8 bmControls;
	__u8 bFormatType;
	__u32 bmFormats;
	__u8 bNrChannels;
	__u32 bmChannelConfig;
	__u8 iChannelNames;
} __attribute__((packed));

#define UAC_DT_AS_HEADER_SIZE		7

/* Formats - A.1.1 Audio Data Format Type I Codes */
@@ -232,6 +248,19 @@ struct uac_format_type_i_discrete_descriptor_##n { \

#define UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(n)	(8 + (n * 3))

struct uac_format_type_i_ext_descriptor {
	__u8 bLength;
	__u8 bDescriptorType;
	__u8 bDescriptorSubtype;
	__u8 bSubslotSize;
	__u8 bFormatType;
	__u8 bBitResolution;
	__u8 bHeaderLength;
	__u8 bControlSize;
	__u8 bSideBandProtocol;
} __attribute__((packed));


/* Formats - Audio Data Format Type I Codes */

struct uac_format_type_ii_discrete_descriptor {
@@ -245,11 +274,26 @@ struct uac_format_type_ii_discrete_descriptor {
	__u8 tSamFreq[][3];
} __attribute__((packed));

struct uac_format_type_ii_ext_descriptor {
	__u8 bLength;
	__u8 bDescriptorType;
	__u8 bDescriptorSubtype;
	__u8 bFormatType;
	__u16 wMaxBitRate;
	__u16 wSamplesPerFrame;
	__u8 bHeaderLength;
	__u8 bSideBandProtocol;
} __attribute__((packed));


/* Formats - A.2 Format Type Codes */
#define UAC_FORMAT_TYPE_UNDEFINED	0x0
#define UAC_FORMAT_TYPE_I		0x1
#define UAC_FORMAT_TYPE_II		0x2
#define UAC_FORMAT_TYPE_III		0x3
#define UAC_EXT_FORMAT_TYPE_I		0x81
#define UAC_EXT_FORMAT_TYPE_II		0x82
#define UAC_EXT_FORMAT_TYPE_III		0x83

struct uac_iso_endpoint_descriptor {
	__u8  bLength;			/* in bytes: 7 */
@@ -265,6 +309,19 @@ struct uac_iso_endpoint_descriptor {
#define UAC_EP_CS_ATTR_PITCH_CONTROL	0x02
#define UAC_EP_CS_ATTR_FILL_MAX		0x80

/* Audio class v2.0: CLOCK_SOURCE descriptor */

struct uac_clock_source_descriptor {
	__u8 bLength;
	__u8 bDescriptorType;
	__u8 bDescriptorSubtype;
	__u8 bClockID;
	__u8 bmAttributes;
	__u8 bmControls;
	__u8 bAssocTerminal;
	__u8 iClockSource;
} __attribute__((packed));

/* A.10.2 Feature Unit Control Selectors */

struct uac_feature_unit_descriptor {
+16 −3
Original line number Diff line number Diff line
@@ -36,8 +36,17 @@
#define MIXER_UNIT			0x04
#define SELECTOR_UNIT			0x05
#define FEATURE_UNIT			0x06
#define PROCESSING_UNIT			0x07
#define EXTENSION_UNIT			0x08
#define PROCESSING_UNIT_V1		0x07
#define EXTENSION_UNIT_V1		0x08

/* audio class v2 */
#define EFFECT_UNIT			0x07
#define PROCESSING_UNIT_V2		0x08
#define EXTENSION_UNIT_V2		0x09
#define CLOCK_SOURCE			0x0a
#define CLOCK_SELECTOR			0x0b
#define CLOCK_MULTIPLIER		0x0c
#define SAMPLE_RATE_CONVERTER		0x0d

#define AS_GENERAL			0x01
#define FORMAT_TYPE			0x02
@@ -60,7 +69,7 @@
#define EP_CS_ATTR_PITCH_CONTROL	0x02
#define EP_CS_ATTR_FILL_MAX		0x80

/* Audio Class specific Request Codes */
/* Audio Class specific Request Codes (v1) */

#define SET_CUR    0x01
#define GET_CUR    0x81
@@ -74,6 +83,10 @@
#define GET_MEM    0x85
#define GET_STAT   0xff

/* Audio Class specific Request Codes (v2) */
#define CS_CUR     0x01
#define CS_RANGE   0x02

/* Terminal Control Selectors */

#define COPY_PROTECT_CONTROL       0x01
+7 −7
Original line number Diff line number Diff line
@@ -286,7 +286,7 @@ static void *find_audio_control_unit(struct mixer_build *state, unsigned char un
	p = NULL;
	while ((p = snd_usb_find_desc(state->buffer, state->buflen, p,
				      USB_DT_CS_INTERFACE)) != NULL) {
		if (p[0] >= 4 && p[2] >= INPUT_TERMINAL && p[2] <= EXTENSION_UNIT && p[3] == unit)
		if (p[0] >= 4 && p[2] >= INPUT_TERMINAL && p[2] <= EXTENSION_UNIT_V1 && p[3] == unit)
			return p;
	}
	return NULL;
@@ -607,9 +607,9 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm
		switch (iterm->type >> 16) {
		case SELECTOR_UNIT:
			strcpy(name, "Selector"); return 8;
		case PROCESSING_UNIT:
		case PROCESSING_UNIT_V1:
			strcpy(name, "Process Unit"); return 12;
		case EXTENSION_UNIT:
		case EXTENSION_UNIT_V1:
			strcpy(name, "Ext Unit"); return 8;
		case MIXER_UNIT:
			strcpy(name, "Mixer"); return 5;
@@ -673,8 +673,8 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_
			term->id = id;
			term->name = p1[9 + p1[0] - 1];
			return 0;
		case PROCESSING_UNIT:
		case EXTENSION_UNIT:
		case PROCESSING_UNIT_V1:
		case EXTENSION_UNIT_V1:
			if (p1[6] == 1) {
				id = p1[7];
				break; /* continue to parse */
@@ -1747,9 +1747,9 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
		return parse_audio_selector_unit(state, unitid, p1);
	case FEATURE_UNIT:
		return parse_audio_feature_unit(state, unitid, p1);
	case PROCESSING_UNIT:
	case PROCESSING_UNIT_V1:
		return parse_audio_processing_unit(state, unitid, p1);
	case EXTENSION_UNIT:
	case EXTENSION_UNIT_V1:
		return parse_audio_extension_unit(state, unitid, p1);
	default:
		snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);