From 7d2e824e978130dafe242504169d398b6386580d Mon Sep 17 00:00:00 2001 From: Alper Nebi Yasak Date: Tue, 28 Nov 2023 13:40:04 +0300 Subject: [PATCH] acp: Disable active UCM profile before enabling Pro Audio profile While switching to the Pro Audio profile from a UCM profile, the active UCM profile is not disabled because the devices may need a UCM verb to be set before being used. Then, switching away from the Pro profile to a UCM profile is done by passing the Off profile as the old profile, instead of the actually-still-enabled UCM profile. This means the devices from the old UCM profile are kept enabled when we try to switch to another UCM profile. And the devices to enable may be conflicting with the still-enabled devices, which will cause failures. To avoid this, we need to tell the UCM code to disable the profile when switching away from it. Doing so disables UCM devices and the UCM verb. Existing code sets the highest priority UCM verb before probing the Pro profile, so manually enable the same one here as well, instead of relying on unclean state from whatever profile that was last active. Signed-off-by: Alper Nebi Yasak --- spa/plugins/alsa/acp/acp.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/spa/plugins/alsa/acp/acp.c b/spa/plugins/alsa/acp/acp.c index 71a9df2b3..3c814da86 100644 --- a/spa/plugins/alsa/acp/acp.c +++ b/spa/plugins/alsa/acp/acp.c @@ -1537,9 +1537,19 @@ int acp_card_set_profile(struct acp_card *card, uint32_t new_index, uint32_t fla } /* if UCM is available for this card then update the verb */ - if (impl->use_ucm && !(np->profile.flags & ACP_PROFILE_PRO)) { - if ((res = pa_alsa_ucm_set_profile(&impl->ucm, impl, - np->profile.flags & ACP_PROFILE_OFF ? NULL : np, op)) < 0) { + if (impl->use_ucm) { + if (np->profile.flags & ACP_PROFILE_OFF) { + if ((res = pa_alsa_ucm_set_profile(&impl->ucm, impl, NULL, op)) < 0) + return res; + } else if (np->profile.flags & ACP_PROFILE_PRO) { + const char *verb = find_best_verb(impl); + if ((res = pa_alsa_ucm_set_profile(&impl->ucm, impl, NULL, op)) < 0) + return res; + if ((res = snd_use_case_set(impl->ucm.ucm_mgr, "_verb", verb)) < 0) { + pa_log_error("error setting verb: %s", snd_strerror(res)); + return res; + } + } else if ((res = pa_alsa_ucm_set_profile(&impl->ucm, impl, np, op)) < 0) { return res; } }