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]); |