summaryrefslogtreecommitdiffstats
path: root/sound/usb/mixer.c
diff options
context:
space:
mode:
authorJorge Sanjuan <jorge.sanjuan@codethink.co.uk>2018-07-11 08:37:51 -0400
committerTakashi Iwai <tiwai@suse.de>2018-07-16 10:34:44 -0400
commitc77e1ef1cdf74dba09edfa706fecc9fddd7bd084 (patch)
treebbf515da4082d4f8d0eb6ccc886598225a5dacb8 /sound/usb/mixer.c
parentd6e08c7eabefc9b027d31d56024810eba76ce113 (diff)
ALSA: usb-audio: Add support for Selector Units in UAC3
This patch add support for Selector Units and Clock Selector Units defined in the new UAC3 spec. Selector Units play a really important role in the new UAC3 spec as Processing Units do not define an on/off switch control anymore. This forces topology designers to add bypass paths in the topology to enable/dissable the Processing Units. Signed-off-by: Jorge Sanjuan <jorge.sanjuan@codethink.co.uk> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/mixer.c')
-rw-r--r--sound/usb/mixer.c54
1 files changed, 44 insertions, 10 deletions
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index ca963e94ec03..a51f2320a3dd 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -940,6 +940,19 @@ static int check_input_term(struct mixer_build *state, int id,
940 940
941 return 0; 941 return 0;
942 } 942 }
943 case UAC3_SELECTOR_UNIT:
944 case UAC3_CLOCK_SELECTOR: {
945 struct uac_selector_unit_descriptor *d = p1;
946 /* call recursively to retrieve the channel info */
947 err = check_input_term(state, d->baSourceID[0], term);
948 if (err < 0)
949 return err;
950 term->type = d->bDescriptorSubtype << 16; /* virtual type */
951 term->id = id;
952 term->name = 0; /* TODO: UAC3 Class-specific strings */
953
954 return 0;
955 }
943 default: 956 default:
944 return -ENODEV; 957 return -ENODEV;
945 } 958 }
@@ -2509,11 +2522,20 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
2509 cval->res = 1; 2522 cval->res = 1;
2510 cval->initialized = 1; 2523 cval->initialized = 1;
2511 2524
2512 if (state->mixer->protocol == UAC_VERSION_1) 2525 switch (state->mixer->protocol) {
2526 case UAC_VERSION_1:
2527 default:
2513 cval->control = 0; 2528 cval->control = 0;
2514 else /* UAC_VERSION_2 */ 2529 break;
2515 cval->control = (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR) ? 2530 case UAC_VERSION_2:
2516 UAC2_CX_CLOCK_SELECTOR : UAC2_SU_SELECTOR; 2531 case UAC_VERSION_3:
2532 if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR ||
2533 desc->bDescriptorSubtype == UAC3_CLOCK_SELECTOR)
2534 cval->control = UAC2_CX_CLOCK_SELECTOR;
2535 else /* UAC2/3_SELECTOR_UNIT */
2536 cval->control = UAC2_SU_SELECTOR;
2537 break;
2538 }
2517 2539
2518 namelist = kmalloc_array(desc->bNrInPins, sizeof(char *), GFP_KERNEL); 2540 namelist = kmalloc_array(desc->bNrInPins, sizeof(char *), GFP_KERNEL);
2519 if (!namelist) { 2541 if (!namelist) {
@@ -2555,12 +2577,22 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
2555 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); 2577 len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name));
2556 if (!len) { 2578 if (!len) {
2557 /* no mapping ? */ 2579 /* no mapping ? */
2580 switch (state->mixer->protocol) {
2581 case UAC_VERSION_1:
2582 case UAC_VERSION_2:
2583 default:
2558 /* if iSelector is given, use it */ 2584 /* if iSelector is given, use it */
2559 nameid = uac_selector_unit_iSelector(desc); 2585 nameid = uac_selector_unit_iSelector(desc);
2560 if (nameid) 2586 if (nameid)
2561 len = snd_usb_copy_string_desc(state->chip, nameid, 2587 len = snd_usb_copy_string_desc(state->chip,
2562 kctl->id.name, 2588 nameid, kctl->id.name,
2563 sizeof(kctl->id.name)); 2589 sizeof(kctl->id.name));
2590 break;
2591 case UAC_VERSION_3:
2592 /* TODO: Class-Specific strings not yet supported */
2593 break;
2594 }
2595
2564 /* ... or pick up the terminal name at next */ 2596 /* ... or pick up the terminal name at next */
2565 if (!len) 2597 if (!len)
2566 len = get_term_name(state->chip, &state->oterm, 2598 len = get_term_name(state->chip, &state->oterm,
@@ -2570,7 +2602,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
2570 strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name)); 2602 strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name));
2571 2603
2572 /* and add the proper suffix */ 2604 /* and add the proper suffix */
2573 if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR) 2605 if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR ||
2606 desc->bDescriptorSubtype == UAC3_CLOCK_SELECTOR)
2574 append_ctl_name(kctl, " Clock Source"); 2607 append_ctl_name(kctl, " Clock Source");
2575 else if ((state->oterm.type & 0xff00) == 0x0100) 2608 else if ((state->oterm.type & 0xff00) == 0x0100)
2576 append_ctl_name(kctl, " Capture Source"); 2609 append_ctl_name(kctl, " Capture Source");
@@ -2641,6 +2674,7 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
2641 return parse_audio_mixer_unit(state, unitid, p1); 2674 return parse_audio_mixer_unit(state, unitid, p1);
2642 case UAC3_CLOCK_SOURCE: 2675 case UAC3_CLOCK_SOURCE:
2643 return parse_clock_source_unit(state, unitid, p1); 2676 return parse_clock_source_unit(state, unitid, p1);
2677 case UAC3_SELECTOR_UNIT:
2644 case UAC3_CLOCK_SELECTOR: 2678 case UAC3_CLOCK_SELECTOR:
2645 return parse_audio_selector_unit(state, unitid, p1); 2679 return parse_audio_selector_unit(state, unitid, p1);
2646 case UAC3_FEATURE_UNIT: 2680 case UAC3_FEATURE_UNIT: