History

ALSA: usb-audio: Add support for Processing Units in UAC3

This patch adds support for the Processig Units defined in the UAC3 spec. The main difference with the previous specs is the lack of on/off switches in the controls for these units and the addiction of the new Multi Function Processing Unit. The current version of the UAC3 spec doesn't define any useful controls for the new Multi Function Processing Unit so no control will get created once this unit is parsed.

Jorge Sanjuan committed 8 years ago

Commit 0f292f01 parent 4e887af3 files · +104 −11Browse files

Unified · Split

3 files
  1. include/linux/usb/audio-v3.h +15 −0
  2. include/uapi/linux/usb/audio.h +40 −9
  3. sound/usb/mixer.c +49 −2
include/linux/usb/audio-v3.h+15−0
@@ -387,6 +387,12 @@ struct uac3_interrupt_data_msg { · 386 unmodified lines
387#define UAC3_CONNECTORS 0x0f387#define UAC3_CONNECTORS 0x0f
388#define UAC3_POWER_DOMAIN 0x10388#define UAC3_POWER_DOMAIN 0x10
389 389
390/* A.20 PROCESSING UNIT PROCESS TYPES */
391#define UAC3_PROCESS_UNDEFINED 0x00
392#define UAC3_PROCESS_UP_DOWNMIX 0x01
393#define UAC3_PROCESS_STEREO_EXTENDER 0x02
394#define UAC3_PROCESS_MULTI_FUNCTION 0x03
395
390/* A.22 AUDIO CLASS-SPECIFIC REQUEST CODES */396/* A.22 AUDIO CLASS-SPECIFIC REQUEST CODES */
391/* see audio-v2.h for the rest, which is identical to v2 */397/* see audio-v2.h for the rest, which is identical to v2 */
392#define UAC3_CS_REQ_INTEN 0x04398#define UAC3_CS_REQ_INTEN 0x04
@@ -406,6 +412,15 @@ struct uac3_interrupt_data_msg { · 13 unmodified lines
406#define UAC3_TE_OVERFLOW 0x04412#define UAC3_TE_OVERFLOW 0x04
407#define UAC3_TE_LATENCY 0x05413#define UAC3_TE_LATENCY 0x05
408 414
415/* A.23.10 PROCESSING UNITS CONTROL SELECTROS */
416
417/* Up/Down Mixer */
418#define UAC3_UD_MODE_SELECT 0x01
419
420/* Stereo Extender */
421#define UAC3_EXT_WIDTH_CONTROL 0x01
422
423
409/* BADD predefined Unit/Terminal values */424/* BADD predefined Unit/Terminal values */
410#define UAC3_BADD_IT_ID1 1 /* Input Terminal ID1: bTerminalID = 1 */425#define UAC3_BADD_IT_ID1 1 /* Input Terminal ID1: bTerminalID = 1 */
411#define UAC3_BADD_FU_ID2 2 /* Feature Unit ID2: bUnitID = 2 */426#define UAC3_BADD_FU_ID2 2 /* Feature Unit ID2: bUnitID = 2 */
include/uapi/linux/usb/audio.h+40−9
@@ -390,33 +390,64 @@ static inline __u8 uac_processing_unit_iChannelNames(struct uac_processing_unit_ · 389 unmodified lines
390static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_descriptor *desc,390static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_descriptor *desc,
391 int protocol)391 int protocol)
392{392{
393 return (protocol == UAC_VERSION_1) ?393 switch (protocol) {
394 desc->baSourceID[desc->bNrInPins + 4] :394 case UAC_VERSION_1:
395 2; /* in UAC2, this value is constant */395 return desc->baSourceID[desc->bNrInPins + 4];
396 case UAC_VERSION_2:
397 return 2; /* in UAC2, this value is constant */
398 case UAC_VERSION_3:
399 return 4; /* in UAC3, this value is constant */
400 default:
401 return 1;
402 }
396}403}
397 404
398static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc,405static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc,
399 int protocol)406 int protocol)
400{407{
401 return (protocol == UAC_VERSION_1) ?408 switch (protocol) {
402 &desc->baSourceID[desc->bNrInPins + 5] :409 case UAC_VERSION_1:
403 &desc->baSourceID[desc->bNrInPins + 6];410 return &desc->baSourceID[desc->bNrInPins + 5];
411 case UAC_VERSION_2:
412 return &desc->baSourceID[desc->bNrInPins + 6];
413 case UAC_VERSION_3:
414 return &desc->baSourceID[desc->bNrInPins + 2];
415 default:
416 return NULL;
417 }
404}418}
405 419
406static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc,420static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc,
407 int protocol)421 int protocol)
408{422{
409 __u8 control_size = uac_processing_unit_bControlSize(desc, protocol);423 __u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
410 return *(uac_processing_unit_bmControls(desc, protocol)424
411 + control_size);425 switch (protocol) {
426 case UAC_VERSION_1:
427 case UAC_VERSION_2:
428 default:
429 return *(uac_processing_unit_bmControls(desc, protocol)
430 + control_size);
431 case UAC_VERSION_3:
432 return 0; /* UAC3 does not have this field */
433 }
412}434}
413 435
414static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_descriptor *desc,436static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_descriptor *desc,
415 int protocol)437 int protocol)
416{438{
417 __u8 control_size = uac_processing_unit_bControlSize(desc, protocol);439 __u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
418 return uac_processing_unit_bmControls(desc, protocol)440
441 switch (protocol) {
442 case UAC_VERSION_1:
443 case UAC_VERSION_2:
444 default:
445 return uac_processing_unit_bmControls(desc, protocol)
419 + control_size + 1;446 + control_size + 1;
447 case UAC_VERSION_3:
448 return uac_processing_unit_bmControls(desc, protocol)
449 + control_size;
450 }
420}451}
421 452
422/* 4.5.2 Class-Specific AS Interface Descriptor */453/* 4.5.2 Class-Specific AS Interface Descriptor */
sound/usb/mixer.c+49−2
@@ -953,6 +953,23 @@ static int check_input_term(struct mixer_build *state, int id, · 952 unmodified lines
953 953
954 return 0;954 return 0;
955 }955 }
956 case UAC3_PROCESSING_UNIT: {
957 struct uac_processing_unit_descriptor *d = p1;
958
959 if (!d->bNrInPins)
960 return -EINVAL;
961
962 /* call recursively to retrieve the channel info */
963 err = check_input_term(state, d->baSourceID[0], term);
964 if (err < 0)
965 return err;
966
967 term->type = d->bDescriptorSubtype << 16; /* virtual type */
968 term->id = id;
969 term->name = 0; /* TODO: UAC3 Class-specific strings */
970
971 return 0;
972 }
956 default:973 default:
957 return -ENODEV;974 return -ENODEV;
958 }975 }
@@ -2180,6 +2197,11 @@ struct procunit_info { · 1221 unmodified lines
2180 struct procunit_value_info *values;2197 struct procunit_value_info *values;
2181};2198};
2182 2199
2200static struct procunit_value_info undefined_proc_info[] = {
2201 { 0x00, "Control Undefined", 0 },
2202 { 0 }
2203};
2204
2183static struct procunit_value_info updown_proc_info[] = {2205static struct procunit_value_info updown_proc_info[] = {
2184 { UAC_UD_ENABLE, "Switch", USB_MIXER_BOOLEAN },2206 { UAC_UD_ENABLE, "Switch", USB_MIXER_BOOLEAN },
2185 { UAC_UD_MODE_SELECT, "Mode Select", USB_MIXER_U8, 1 },2207 { UAC_UD_MODE_SELECT, "Mode Select", USB_MIXER_U8, 1 },
@@ -2228,6 +2250,23 @@ static struct procunit_info procunits[] = { · 42 unmodified lines
2228 { UAC_PROCESS_DYN_RANGE_COMP, "DCR", dcr_proc_info },2250 { UAC_PROCESS_DYN_RANGE_COMP, "DCR", dcr_proc_info },
2229 { 0 },2251 { 0 },
2230};2252};
2253
2254static struct procunit_value_info uac3_updown_proc_info[] = {
2255 { UAC3_UD_MODE_SELECT, "Mode Select", USB_MIXER_U8, 1 },
2256 { 0 }
2257};
2258static struct procunit_value_info uac3_stereo_ext_proc_info[] = {
2259 { UAC3_EXT_WIDTH_CONTROL, "Width Control", USB_MIXER_U8 },
2260 { 0 }
2261};
2262
2263static struct procunit_info uac3_procunits[] = {
2264 { UAC3_PROCESS_UP_DOWNMIX, "Up Down", uac3_updown_proc_info },
2265 { UAC3_PROCESS_STEREO_EXTENDER, "3D Stereo Extender", uac3_stereo_ext_proc_info },
2266 { UAC3_PROCESS_MULTI_FUNCTION, "Multi-Function", undefined_proc_info },
2267 { 0 },
2268};
2269
2231/*2270/*
2232 * predefined data for extension units2271 * predefined data for extension units
2233 */2272 */
@@ -2388,8 +2427,16 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, · 154 unmodified lines
2388static int parse_audio_processing_unit(struct mixer_build *state, int unitid,2427static int parse_audio_processing_unit(struct mixer_build *state, int unitid,
2389 void *raw_desc)2428 void *raw_desc)
2390{2429{
2391 return build_audio_procunit(state, unitid, raw_desc,2430 switch (state->mixer->protocol) {
2392 procunits, "Processing Unit");2431 case UAC_VERSION_1:
2432 case UAC_VERSION_2:
2433 default:
2434 return build_audio_procunit(state, unitid, raw_desc,
2435 procunits, "Processing Unit");
2436 case UAC_VERSION_3:
2437 return build_audio_procunit(state, unitid, raw_desc,
2438 uac3_procunits, "Processing Unit");
2439 }
2393}2440}
2394 2441
2395static int parse_audio_extension_unit(struct mixer_build *state, int unitid,2442static int parse_audio_extension_unit(struct mixer_build *state, int unitid,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t