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
387387 #define UAC3_CONNECTORS 0x0f
388388 #define UAC3_POWER_DOMAIN 0x10
389389
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+
390396 /* A.22 AUDIO CLASS-SPECIFIC REQUEST CODES */
391397 /* see audio-v2.h for the rest, which is identical to v2 */
392398 #define UAC3_CS_REQ_INTEN 0x04
@@ -406,6 +412,15 @@ struct uac3_interrupt_data_msg { · 13 unmodified lines
406412 #define UAC3_TE_OVERFLOW 0x04
407413 #define UAC3_TE_LATENCY 0x05
408414
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+
409424 /* BADD predefined Unit/Terminal values */
410425 #define UAC3_BADD_IT_ID1 1 /* Input Terminal ID1: bTerminalID = 1 */
411426 #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
390390 static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_descriptor *desc,
391391 int protocol)
392392 {
393− return (protocol == UAC_VERSION_1) ?
394− desc->baSourceID[desc->bNrInPins + 4] :
395− 2; /* in UAC2, this value is constant */
393+ switch (protocol) {
394+ case UAC_VERSION_1:
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+ }
396403 }
397404
398405 static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc,
399406 int protocol)
400407 {
401− return (protocol == UAC_VERSION_1) ?
402− &desc->baSourceID[desc->bNrInPins + 5] :
403− &desc->baSourceID[desc->bNrInPins + 6];
408+ switch (protocol) {
409+ case UAC_VERSION_1:
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+ }
404418 }
405419
406420 static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc,
407421 int protocol)
408422 {
409423 __u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
410− return *(uac_processing_unit_bmControls(desc, protocol)
411− + control_size);
424+
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+ }
412434 }
413435
414436 static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_descriptor *desc,
415437 int protocol)
416438 {
417439 __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)
419446 + control_size + 1;
447+ case UAC_VERSION_3:
448+ return uac_processing_unit_bmControls(desc, protocol)
449+ + control_size;
450+ }
420451 }
421452
422453 /* 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
953953
954954 return 0;
955955 }
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+ }
956973 default:
957974 return -ENODEV;
958975 }
@@ -2180,6 +2197,11 @@ struct procunit_info { · 1221 unmodified lines
21802197 struct procunit_value_info *values;
21812198 };
21822199
2200+static struct procunit_value_info undefined_proc_info[] = {
2201+ { 0x00, "Control Undefined", 0 },
2202+ { 0 }
2203+};
2204+
21832205 static struct procunit_value_info updown_proc_info[] = {
21842206 { UAC_UD_ENABLE, "Switch", USB_MIXER_BOOLEAN },
21852207 { UAC_UD_MODE_SELECT, "Mode Select", USB_MIXER_U8, 1 },
@@ -2228,6 +2250,23 @@ static struct procunit_info procunits[] = { · 42 unmodified lines
22282250 { UAC_PROCESS_DYN_RANGE_COMP, "DCR", dcr_proc_info },
22292251 { 0 },
22302252 };
2253+
2254+static struct procunit_value_info uac3_updown_proc_info[] = {
2255+ { UAC3_UD_MODE_SELECT, "Mode Select", USB_MIXER_U8, 1 },
2256+ { 0 }
2257+};
2258+static struct procunit_value_info uac3_stereo_ext_proc_info[] = {
2259+ { UAC3_EXT_WIDTH_CONTROL, "Width Control", USB_MIXER_U8 },
2260+ { 0 }
2261+};
2262+
2263+static 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+
22312270 /*
22322271 * predefined data for extension units
22332272 */
@@ -2388,8 +2427,16 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, · 154 unmodified lines
23882427 static int parse_audio_processing_unit(struct mixer_build *state, int unitid,
23892428 void *raw_desc)
23902429 {
2391− return build_audio_procunit(state, unitid, raw_desc,
2392− procunits, "Processing Unit");
2430+ switch (state->mixer->protocol) {
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+ }
23932440 }
23942441
23952442 static 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