Skip to content

Commit

Permalink
ALSA: usbaudio: introduce new types for audio class v2
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Daniel Mack authored and Takashi Iwai committed Feb 23, 2010
1 parent 28e1b77 commit 8fee4af
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 10 deletions.
57 changes: 57 additions & 0 deletions include/linux/usb/audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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 {
Expand All @@ -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 */
Expand All @@ -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 {
Expand Down
19 changes: 16 additions & 3 deletions sound/usb/usbaudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
14 changes: 7 additions & 7 deletions sound/usb/usbmixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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]);
Expand Down

0 comments on commit 8fee4af

Please sign in to comment.