mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-14 01:49:20 -04:00
ASoC: codecs: lpass-wsa-macro: Fix speaker quality distortion
Commitbb4a0f497b("ASoC: codecs: lpass: Drop unused AIF_INVALID first DAI identifier") removed first entry in enum with DAI identifiers, because it looked unused. Turns out that there is a relation between DAI ID and "WSA RX0 Mux"-like kcontrols (which use "rx_mux_text" array). That "rx_mux_text" array used first three entries of DAI IDs enum, with value '0' being invalid. The value passed tp "WSA RX0 Mux"-like kcontrols was used as DAI ID and set to configure active channel count and mask, which are arrays indexed by DAI ID. After removal of first AIF_INVALID DAI identifier, this kcontrol was updating wrong entries in active channel count and mask arrays which was visible in reduced quality (distortions) during speaker playback on several boards like Lenovo T14s laptop and Qualcomm SM8550-based boards. Reported-by: Alexey Klimov <alexey.klimov@linaro.org> Fixes:bb4a0f497b("ASoC: codecs: lpass: Drop unused AIF_INVALID first DAI identifier") Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com> Tested-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com> Message-ID: <20250831151401.30897-2-krzysztof.kozlowski@linaro.org> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
committed by
Mark Brown
parent
d0f61658db
commit
9004a450fc
@@ -368,6 +368,7 @@ static struct interp_sample_rate int_mix_sample_rate_val[] = {
|
||||
{192000, 0x6}, /* 192K */
|
||||
};
|
||||
|
||||
/* Matches also rx_mux_text */
|
||||
enum {
|
||||
WSA_MACRO_AIF1_PB,
|
||||
WSA_MACRO_AIF_MIX1_PB,
|
||||
@@ -465,6 +466,7 @@ static const char *const rx_mix_ec_text[] = {
|
||||
"ZERO", "RX_MIX_TX0", "RX_MIX_TX1"
|
||||
};
|
||||
|
||||
/* Order must match WSA_MACRO_MAX_DAIS enum (offset by 1) */
|
||||
static const char *const rx_mux_text[] = {
|
||||
"ZERO", "AIF1_PB", "AIF_MIX1_PB"
|
||||
};
|
||||
@@ -2207,6 +2209,7 @@ static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol,
|
||||
u32 rx_port_value = ucontrol->value.integer.value[0];
|
||||
u32 bit_input;
|
||||
u32 aif_rst;
|
||||
unsigned int dai_id;
|
||||
struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
|
||||
|
||||
aif_rst = wsa->rx_port_value[widget->shift];
|
||||
@@ -2224,17 +2227,22 @@ static int wsa_macro_rx_mux_put(struct snd_kcontrol *kcontrol,
|
||||
|
||||
switch (rx_port_value) {
|
||||
case 0:
|
||||
if (wsa->active_ch_cnt[aif_rst]) {
|
||||
clear_bit(bit_input,
|
||||
&wsa->active_ch_mask[aif_rst]);
|
||||
wsa->active_ch_cnt[aif_rst]--;
|
||||
/*
|
||||
* active_ch_cnt and active_ch_mask use DAI IDs (WSA_MACRO_MAX_DAIS).
|
||||
* active_ch_cnt == 0 was tested in if() above.
|
||||
*/
|
||||
dai_id = aif_rst - 1;
|
||||
if (wsa->active_ch_cnt[dai_id]) {
|
||||
clear_bit(bit_input, &wsa->active_ch_mask[dai_id]);
|
||||
wsa->active_ch_cnt[dai_id]--;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
set_bit(bit_input,
|
||||
&wsa->active_ch_mask[rx_port_value]);
|
||||
wsa->active_ch_cnt[rx_port_value]++;
|
||||
/* active_ch_cnt and active_ch_mask use DAI IDs (WSA_MACRO_MAX_DAIS). */
|
||||
dai_id = rx_port_value - 1;
|
||||
set_bit(bit_input, &wsa->active_ch_mask[dai_id]);
|
||||
wsa->active_ch_cnt[dai_id]++;
|
||||
break;
|
||||
default:
|
||||
dev_err(component->dev,
|
||||
|
||||
Reference in New Issue
Block a user