diff options
| -rw-r--r-- | include/linux/usb/audio.h | 57 | ||||
| -rw-r--r-- | sound/usb/usbaudio.h | 19 | ||||
| -rw-r--r-- | sound/usb/usbmixer.c | 14 |
3 files changed, 80 insertions, 10 deletions
diff --git a/include/linux/usb/audio.h b/include/linux/usb/audio.h index 44f82d8e09c5..fb1a97bf943d 100644 --- a/include/linux/usb/audio.h +++ b/include/linux/usb/audio.h | |||
| @@ -25,6 +25,9 @@ | |||
| 25 | #define USB_SUBCLASS_AUDIOSTREAMING 0x02 | 25 | #define USB_SUBCLASS_AUDIOSTREAMING 0x02 |
| 26 | #define USB_SUBCLASS_MIDISTREAMING 0x03 | 26 | #define USB_SUBCLASS_MIDISTREAMING 0x03 |
| 27 | 27 | ||
| 28 | #define UAC_VERSION_1 0x00 | ||
| 29 | #define UAC_VERSION_2 0x20 | ||
| 30 | |||
| 28 | /* A.5 Audio Class-Specific AC Interface Descriptor Subtypes */ | 31 | /* A.5 Audio Class-Specific AC Interface Descriptor Subtypes */ |
| 29 | #define UAC_HEADER 0x01 | 32 | #define UAC_HEADER 0x01 |
| 30 | #define UAC_INPUT_TERMINAL 0x02 | 33 | #define UAC_INPUT_TERMINAL 0x02 |
| @@ -180,6 +183,19 @@ struct uac_as_header_descriptor_v1 { | |||
| 180 | __le16 wFormatTag; /* The Audio Data Format */ | 183 | __le16 wFormatTag; /* The Audio Data Format */ |
| 181 | } __attribute__ ((packed)); | 184 | } __attribute__ ((packed)); |
| 182 | 185 | ||
| 186 | struct uac_as_header_descriptor_v2 { | ||
| 187 | __u8 bLength; | ||
| 188 | __u8 bDescriptorType; | ||
| 189 | __u8 bDescriptorSubtype; | ||
| 190 | __u8 bTerminalLink; | ||
| 191 | __u8 bmControls; | ||
| 192 | __u8 bFormatType; | ||
| 193 | __u32 bmFormats; | ||
| 194 | __u8 bNrChannels; | ||
| 195 | __u32 bmChannelConfig; | ||
| 196 | __u8 iChannelNames; | ||
| 197 | } __attribute__((packed)); | ||
| 198 | |||
| 183 | #define UAC_DT_AS_HEADER_SIZE 7 | 199 | #define UAC_DT_AS_HEADER_SIZE 7 |
| 184 | 200 | ||
| 185 | /* Formats - A.1.1 Audio Data Format Type I Codes */ | 201 | /* Formats - A.1.1 Audio Data Format Type I Codes */ |
| @@ -232,6 +248,19 @@ struct uac_format_type_i_discrete_descriptor_##n { \ | |||
| 232 | 248 | ||
| 233 | #define UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(n) (8 + (n * 3)) | 249 | #define UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(n) (8 + (n * 3)) |
| 234 | 250 | ||
| 251 | struct uac_format_type_i_ext_descriptor { | ||
| 252 | __u8 bLength; | ||
| 253 | __u8 bDescriptorType; | ||
| 254 | __u8 bDescriptorSubtype; | ||
| 255 | __u8 bSubslotSize; | ||
| 256 | __u8 bFormatType; | ||
| 257 | __u8 bBitResolution; | ||
| 258 | __u8 bHeaderLength; | ||
| 259 | __u8 bControlSize; | ||
| 260 | __u8 bSideBandProtocol; | ||
| 261 | } __attribute__((packed)); | ||
| 262 | |||
| 263 | |||
| 235 | /* Formats - Audio Data Format Type I Codes */ | 264 | /* Formats - Audio Data Format Type I Codes */ |
| 236 | 265 | ||
| 237 | struct uac_format_type_ii_discrete_descriptor { | 266 | struct uac_format_type_ii_discrete_descriptor { |
| @@ -245,11 +274,26 @@ struct uac_format_type_ii_discrete_descriptor { | |||
| 245 | __u8 tSamFreq[][3]; | 274 | __u8 tSamFreq[][3]; |
| 246 | } __attribute__((packed)); | 275 | } __attribute__((packed)); |
| 247 | 276 | ||
| 277 | struct uac_format_type_ii_ext_descriptor { | ||
| 278 | __u8 bLength; | ||
| 279 | __u8 bDescriptorType; | ||
| 280 | __u8 bDescriptorSubtype; | ||
| 281 | __u8 bFormatType; | ||
| 282 | __u16 wMaxBitRate; | ||
| 283 | __u16 wSamplesPerFrame; | ||
| 284 | __u8 bHeaderLength; | ||
| 285 | __u8 bSideBandProtocol; | ||
| 286 | } __attribute__((packed)); | ||
| 287 | |||
| 288 | |||
| 248 | /* Formats - A.2 Format Type Codes */ | 289 | /* Formats - A.2 Format Type Codes */ |
| 249 | #define UAC_FORMAT_TYPE_UNDEFINED 0x0 | 290 | #define UAC_FORMAT_TYPE_UNDEFINED 0x0 |
| 250 | #define UAC_FORMAT_TYPE_I 0x1 | 291 | #define UAC_FORMAT_TYPE_I 0x1 |
| 251 | #define UAC_FORMAT_TYPE_II 0x2 | 292 | #define UAC_FORMAT_TYPE_II 0x2 |
| 252 | #define UAC_FORMAT_TYPE_III 0x3 | 293 | #define UAC_FORMAT_TYPE_III 0x3 |
| 294 | #define UAC_EXT_FORMAT_TYPE_I 0x81 | ||
| 295 | #define UAC_EXT_FORMAT_TYPE_II 0x82 | ||
| 296 | #define UAC_EXT_FORMAT_TYPE_III 0x83 | ||
| 253 | 297 | ||
| 254 | struct uac_iso_endpoint_descriptor { | 298 | struct uac_iso_endpoint_descriptor { |
| 255 | __u8 bLength; /* in bytes: 7 */ | 299 | __u8 bLength; /* in bytes: 7 */ |
| @@ -265,6 +309,19 @@ struct uac_iso_endpoint_descriptor { | |||
| 265 | #define UAC_EP_CS_ATTR_PITCH_CONTROL 0x02 | 309 | #define UAC_EP_CS_ATTR_PITCH_CONTROL 0x02 |
| 266 | #define UAC_EP_CS_ATTR_FILL_MAX 0x80 | 310 | #define UAC_EP_CS_ATTR_FILL_MAX 0x80 |
| 267 | 311 | ||
| 312 | /* Audio class v2.0: CLOCK_SOURCE descriptor */ | ||
| 313 | |||
| 314 | struct uac_clock_source_descriptor { | ||
| 315 | __u8 bLength; | ||
| 316 | __u8 bDescriptorType; | ||
| 317 | __u8 bDescriptorSubtype; | ||
| 318 | __u8 bClockID; | ||
| 319 | __u8 bmAttributes; | ||
| 320 | __u8 bmControls; | ||
| 321 | __u8 bAssocTerminal; | ||
| 322 | __u8 iClockSource; | ||
| 323 | } __attribute__((packed)); | ||
| 324 | |||
| 268 | /* A.10.2 Feature Unit Control Selectors */ | 325 | /* A.10.2 Feature Unit Control Selectors */ |
| 269 | 326 | ||
| 270 | struct uac_feature_unit_descriptor { | 327 | struct uac_feature_unit_descriptor { |
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 9d8cea48fc5f..4f482939e8e8 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
| @@ -36,8 +36,17 @@ | |||
| 36 | #define MIXER_UNIT 0x04 | 36 | #define MIXER_UNIT 0x04 |
| 37 | #define SELECTOR_UNIT 0x05 | 37 | #define SELECTOR_UNIT 0x05 |
| 38 | #define FEATURE_UNIT 0x06 | 38 | #define FEATURE_UNIT 0x06 |
| 39 | #define PROCESSING_UNIT 0x07 | 39 | #define PROCESSING_UNIT_V1 0x07 |
| 40 | #define EXTENSION_UNIT 0x08 | 40 | #define EXTENSION_UNIT_V1 0x08 |
| 41 | |||
| 42 | /* audio class v2 */ | ||
| 43 | #define EFFECT_UNIT 0x07 | ||
| 44 | #define PROCESSING_UNIT_V2 0x08 | ||
| 45 | #define EXTENSION_UNIT_V2 0x09 | ||
| 46 | #define CLOCK_SOURCE 0x0a | ||
| 47 | #define CLOCK_SELECTOR 0x0b | ||
| 48 | #define CLOCK_MULTIPLIER 0x0c | ||
| 49 | #define SAMPLE_RATE_CONVERTER 0x0d | ||
| 41 | 50 | ||
| 42 | #define AS_GENERAL 0x01 | 51 | #define AS_GENERAL 0x01 |
| 43 | #define FORMAT_TYPE 0x02 | 52 | #define FORMAT_TYPE 0x02 |
| @@ -60,7 +69,7 @@ | |||
| 60 | #define EP_CS_ATTR_PITCH_CONTROL 0x02 | 69 | #define EP_CS_ATTR_PITCH_CONTROL 0x02 |
| 61 | #define EP_CS_ATTR_FILL_MAX 0x80 | 70 | #define EP_CS_ATTR_FILL_MAX 0x80 |
| 62 | 71 | ||
| 63 | /* Audio Class specific Request Codes */ | 72 | /* Audio Class specific Request Codes (v1) */ |
| 64 | 73 | ||
| 65 | #define SET_CUR 0x01 | 74 | #define SET_CUR 0x01 |
| 66 | #define GET_CUR 0x81 | 75 | #define GET_CUR 0x81 |
| @@ -74,6 +83,10 @@ | |||
| 74 | #define GET_MEM 0x85 | 83 | #define GET_MEM 0x85 |
| 75 | #define GET_STAT 0xff | 84 | #define GET_STAT 0xff |
| 76 | 85 | ||
| 86 | /* Audio Class specific Request Codes (v2) */ | ||
| 87 | #define CS_CUR 0x01 | ||
| 88 | #define CS_RANGE 0x02 | ||
| 89 | |||
| 77 | /* Terminal Control Selectors */ | 90 | /* Terminal Control Selectors */ |
| 78 | 91 | ||
| 79 | #define COPY_PROTECT_CONTROL 0x01 | 92 | #define COPY_PROTECT_CONTROL 0x01 |
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c index 11636a6112d5..ca7949598191 100644 --- a/sound/usb/usbmixer.c +++ b/sound/usb/usbmixer.c | |||
| @@ -286,7 +286,7 @@ static void *find_audio_control_unit(struct mixer_build *state, unsigned char un | |||
| 286 | p = NULL; | 286 | p = NULL; |
| 287 | while ((p = snd_usb_find_desc(state->buffer, state->buflen, p, | 287 | while ((p = snd_usb_find_desc(state->buffer, state->buflen, p, |
| 288 | USB_DT_CS_INTERFACE)) != NULL) { | 288 | USB_DT_CS_INTERFACE)) != NULL) { |
| 289 | if (p[0] >= 4 && p[2] >= INPUT_TERMINAL && p[2] <= EXTENSION_UNIT && p[3] == unit) | 289 | if (p[0] >= 4 && p[2] >= INPUT_TERMINAL && p[2] <= EXTENSION_UNIT_V1 && p[3] == unit) |
| 290 | return p; | 290 | return p; |
| 291 | } | 291 | } |
| 292 | return NULL; | 292 | return NULL; |
| @@ -607,9 +607,9 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm | |||
| 607 | switch (iterm->type >> 16) { | 607 | switch (iterm->type >> 16) { |
| 608 | case SELECTOR_UNIT: | 608 | case SELECTOR_UNIT: |
| 609 | strcpy(name, "Selector"); return 8; | 609 | strcpy(name, "Selector"); return 8; |
| 610 | case PROCESSING_UNIT: | 610 | case PROCESSING_UNIT_V1: |
| 611 | strcpy(name, "Process Unit"); return 12; | 611 | strcpy(name, "Process Unit"); return 12; |
| 612 | case EXTENSION_UNIT: | 612 | case EXTENSION_UNIT_V1: |
| 613 | strcpy(name, "Ext Unit"); return 8; | 613 | strcpy(name, "Ext Unit"); return 8; |
| 614 | case MIXER_UNIT: | 614 | case MIXER_UNIT: |
| 615 | strcpy(name, "Mixer"); return 5; | 615 | strcpy(name, "Mixer"); return 5; |
| @@ -673,8 +673,8 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_ | |||
| 673 | term->id = id; | 673 | term->id = id; |
| 674 | term->name = p1[9 + p1[0] - 1]; | 674 | term->name = p1[9 + p1[0] - 1]; |
| 675 | return 0; | 675 | return 0; |
| 676 | case PROCESSING_UNIT: | 676 | case PROCESSING_UNIT_V1: |
| 677 | case EXTENSION_UNIT: | 677 | case EXTENSION_UNIT_V1: |
| 678 | if (p1[6] == 1) { | 678 | if (p1[6] == 1) { |
| 679 | id = p1[7]; | 679 | id = p1[7]; |
| 680 | break; /* continue to parse */ | 680 | break; /* continue to parse */ |
| @@ -1747,9 +1747,9 @@ static int parse_audio_unit(struct mixer_build *state, int unitid) | |||
| 1747 | return parse_audio_selector_unit(state, unitid, p1); | 1747 | return parse_audio_selector_unit(state, unitid, p1); |
| 1748 | case FEATURE_UNIT: | 1748 | case FEATURE_UNIT: |
| 1749 | return parse_audio_feature_unit(state, unitid, p1); | 1749 | return parse_audio_feature_unit(state, unitid, p1); |
| 1750 | case PROCESSING_UNIT: | 1750 | case PROCESSING_UNIT_V1: |
| 1751 | return parse_audio_processing_unit(state, unitid, p1); | 1751 | return parse_audio_processing_unit(state, unitid, p1); |
| 1752 | case EXTENSION_UNIT: | 1752 | case EXTENSION_UNIT_V1: |
| 1753 | return parse_audio_extension_unit(state, unitid, p1); | 1753 | return parse_audio_extension_unit(state, unitid, p1); |
| 1754 | default: | 1754 | default: |
| 1755 | snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]); | 1755 | snd_printk(KERN_ERR "usbaudio: unit %u: unexpected type 0x%02x\n", unitid, p1[2]); |
