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: Daniel Mack <daniel@caiaq.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
committed by
Takashi Iwai
parent
28e1b77308
commit
8fee4aff8c
@@ -25,6 +25,9 @@
|
|||||||
#define USB_SUBCLASS_AUDIOSTREAMING 0x02
|
#define USB_SUBCLASS_AUDIOSTREAMING 0x02
|
||||||
#define USB_SUBCLASS_MIDISTREAMING 0x03
|
#define USB_SUBCLASS_MIDISTREAMING 0x03
|
||||||
|
|
||||||
|
#define UAC_VERSION_1 0x00
|
||||||
|
#define UAC_VERSION_2 0x20
|
||||||
|
|
||||||
/* A.5 Audio Class-Specific AC Interface Descriptor Subtypes */
|
/* A.5 Audio Class-Specific AC Interface Descriptor Subtypes */
|
||||||
#define UAC_HEADER 0x01
|
#define UAC_HEADER 0x01
|
||||||
#define UAC_INPUT_TERMINAL 0x02
|
#define UAC_INPUT_TERMINAL 0x02
|
||||||
@@ -180,6 +183,19 @@ struct uac_as_header_descriptor_v1 {
|
|||||||
__le16 wFormatTag; /* The Audio Data Format */
|
__le16 wFormatTag; /* The Audio Data Format */
|
||||||
} __attribute__ ((packed));
|
} __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
|
#define UAC_DT_AS_HEADER_SIZE 7
|
||||||
|
|
||||||
/* Formats - A.1.1 Audio Data Format Type I Codes */
|
/* 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))
|
#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 */
|
/* Formats - Audio Data Format Type I Codes */
|
||||||
|
|
||||||
struct uac_format_type_ii_discrete_descriptor {
|
struct uac_format_type_ii_discrete_descriptor {
|
||||||
@@ -245,11 +274,26 @@ struct uac_format_type_ii_discrete_descriptor {
|
|||||||
__u8 tSamFreq[][3];
|
__u8 tSamFreq[][3];
|
||||||
} __attribute__((packed));
|
} __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 */
|
/* Formats - A.2 Format Type Codes */
|
||||||
#define UAC_FORMAT_TYPE_UNDEFINED 0x0
|
#define UAC_FORMAT_TYPE_UNDEFINED 0x0
|
||||||
#define UAC_FORMAT_TYPE_I 0x1
|
#define UAC_FORMAT_TYPE_I 0x1
|
||||||
#define UAC_FORMAT_TYPE_II 0x2
|
#define UAC_FORMAT_TYPE_II 0x2
|
||||||
#define UAC_FORMAT_TYPE_III 0x3
|
#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 {
|
struct uac_iso_endpoint_descriptor {
|
||||||
__u8 bLength; /* in bytes: 7 */
|
__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_PITCH_CONTROL 0x02
|
||||||
#define UAC_EP_CS_ATTR_FILL_MAX 0x80
|
#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 */
|
/* A.10.2 Feature Unit Control Selectors */
|
||||||
|
|
||||||
struct uac_feature_unit_descriptor {
|
struct uac_feature_unit_descriptor {
|
||||||
|
@@ -36,8 +36,17 @@
|
|||||||
#define MIXER_UNIT 0x04
|
#define MIXER_UNIT 0x04
|
||||||
#define SELECTOR_UNIT 0x05
|
#define SELECTOR_UNIT 0x05
|
||||||
#define FEATURE_UNIT 0x06
|
#define FEATURE_UNIT 0x06
|
||||||
#define PROCESSING_UNIT 0x07
|
#define PROCESSING_UNIT_V1 0x07
|
||||||
#define EXTENSION_UNIT 0x08
|
#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 AS_GENERAL 0x01
|
||||||
#define FORMAT_TYPE 0x02
|
#define FORMAT_TYPE 0x02
|
||||||
@@ -60,7 +69,7 @@
|
|||||||
#define EP_CS_ATTR_PITCH_CONTROL 0x02
|
#define EP_CS_ATTR_PITCH_CONTROL 0x02
|
||||||
#define EP_CS_ATTR_FILL_MAX 0x80
|
#define EP_CS_ATTR_FILL_MAX 0x80
|
||||||
|
|
||||||
/* Audio Class specific Request Codes */
|
/* Audio Class specific Request Codes (v1) */
|
||||||
|
|
||||||
#define SET_CUR 0x01
|
#define SET_CUR 0x01
|
||||||
#define GET_CUR 0x81
|
#define GET_CUR 0x81
|
||||||
@@ -74,6 +83,10 @@
|
|||||||
#define GET_MEM 0x85
|
#define GET_MEM 0x85
|
||||||
#define GET_STAT 0xff
|
#define GET_STAT 0xff
|
||||||
|
|
||||||
|
/* Audio Class specific Request Codes (v2) */
|
||||||
|
#define CS_CUR 0x01
|
||||||
|
#define CS_RANGE 0x02
|
||||||
|
|
||||||
/* Terminal Control Selectors */
|
/* Terminal Control Selectors */
|
||||||
|
|
||||||
#define COPY_PROTECT_CONTROL 0x01
|
#define COPY_PROTECT_CONTROL 0x01
|
||||||
|
@@ -286,7 +286,7 @@ static void *find_audio_control_unit(struct mixer_build *state, unsigned char un
|
|||||||
p = NULL;
|
p = NULL;
|
||||||
while ((p = snd_usb_find_desc(state->buffer, state->buflen, p,
|
while ((p = snd_usb_find_desc(state->buffer, state->buflen, p,
|
||||||
USB_DT_CS_INTERFACE)) != NULL) {
|
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 p;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -607,9 +607,9 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm
|
|||||||
switch (iterm->type >> 16) {
|
switch (iterm->type >> 16) {
|
||||||
case SELECTOR_UNIT:
|
case SELECTOR_UNIT:
|
||||||
strcpy(name, "Selector"); return 8;
|
strcpy(name, "Selector"); return 8;
|
||||||
case PROCESSING_UNIT:
|
case PROCESSING_UNIT_V1:
|
||||||
strcpy(name, "Process Unit"); return 12;
|
strcpy(name, "Process Unit"); return 12;
|
||||||
case EXTENSION_UNIT:
|
case EXTENSION_UNIT_V1:
|
||||||
strcpy(name, "Ext Unit"); return 8;
|
strcpy(name, "Ext Unit"); return 8;
|
||||||
case MIXER_UNIT:
|
case MIXER_UNIT:
|
||||||
strcpy(name, "Mixer"); return 5;
|
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->id = id;
|
||||||
term->name = p1[9 + p1[0] - 1];
|
term->name = p1[9 + p1[0] - 1];
|
||||||
return 0;
|
return 0;
|
||||||
case PROCESSING_UNIT:
|
case PROCESSING_UNIT_V1:
|
||||||
case EXTENSION_UNIT:
|
case EXTENSION_UNIT_V1:
|
||||||
if (p1[6] == 1) {
|
if (p1[6] == 1) {
|
||||||
id = p1[7];
|
id = p1[7];
|
||||||
break; /* continue to parse */
|
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);
|
return parse_audio_selector_unit(state, unitid, p1);
|
||||||
case FEATURE_UNIT:
|
case FEATURE_UNIT:
|
||||||
return parse_audio_feature_unit(state, unitid, p1);
|
return parse_audio_feature_unit(state, unitid, p1);
|
||||||
case PROCESSING_UNIT:
|
case PROCESSING_UNIT_V1:
|
||||||
return parse_audio_processing_unit(state, unitid, p1);
|
return parse_audio_processing_unit(state, unitid, p1);
|
||||||
case EXTENSION_UNIT:
|
case EXTENSION_UNIT_V1:
|
||||||
return parse_audio_extension_unit(state, unitid, p1);
|
return parse_audio_extension_unit(state, unitid, p1);
|
||||||
default:
|
default:
|
||||||
snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
|
snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]);
|
||||||
|
Reference in New Issue
Block a user