sound/soc/codecs/lpass-wsa-macro.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
Commit bb4a0f497bc1 ("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: bb4a0f497bc1 ("ASoC: codecs: lpass: Drop unused AIF_INVALID first DAI identifier")
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
Reported via IRC.
Fix for current v6.17-RC cycle.
I will be investigating rest of lpass macro codecs a bit later.
---
sound/soc/codecs/lpass-wsa-macro.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c
index da6adb3de21d..d7eec9fdaf9c 100644
--- a/sound/soc/codecs/lpass-wsa-macro.c
+++ b/sound/soc/codecs/lpass-wsa-macro.c
@@ -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,
--
2.48.1
On Sun Aug 31, 2025 at 4:14 PM BST, Krzysztof Kozlowski wrote: > Commit bb4a0f497bc1 ("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: bb4a0f497bc1 ("ASoC: codecs: lpass: Drop unused AIF_INVALID first DAI identifier") > Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> > > --- > > Reported via IRC. > Fix for current v6.17-RC cycle. > > I will be investigating rest of lpass macro codecs a bit later. Any updates on other lpass macro codecs? Is something still broken there or are they fine? So I guess the changes for wsa and rx macro were applied. va, tx? FWIW, I understand that I am late to the party but I tested this one anyway on sm8550 and it seems to fix the distorted sound and unstable volume. Sorry for delay. Just confirming. Thank you, Alexey
On 11/09/2025 03:29, Alexey Klimov wrote: > On Sun Aug 31, 2025 at 4:14 PM BST, Krzysztof Kozlowski wrote: >> 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: bb4a0f497bc1 ("ASoC: codecs: lpass: Drop unused AIF_INVALID first DAI identifier") >> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> >> >> --- >> >> Reported via IRC. >> Fix for current v6.17-RC cycle. >> >> I will be investigating rest of lpass macro codecs a bit later. > > Any updates on other lpass macro codecs? Is something still broken there > or are they fine? So I guess the changes for wsa and rx macro were applied. > va, tx? The remaining two - VA and TX - are fine, I checked them. Best regards, Krzysztof
On Sun, 31 Aug 2025 17:14:02 +0200, Krzysztof Kozlowski wrote: > Commit bb4a0f497bc1 ("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. > > [...] Applied to https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next Thanks! [1/1] ASoC: codecs: lpass-wsa-macro: Fix speaker quality distortion commit: 9004a450fccbeb40a71cc173747da37a459fd4dc All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark
On 8/31/25 4:14 PM, Krzysztof Kozlowski wrote: > Commit bb4a0f497bc1 ("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: bb4a0f497bc1 ("ASoC: codecs: lpass: Drop unused AIF_INVALID first DAI identifier") > Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> > Thanks for fixing this, tested this on T14s, WSA speakers, VA DMICs, RX and TX on headphones.. everything seems to work fine. Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com> Tested-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com> --srini > --- > > Reported via IRC. > Fix for current v6.17-RC cycle. > > I will be investigating rest of lpass macro codecs a bit later. > --- > sound/soc/codecs/lpass-wsa-macro.c | 22 +++++++++++++++------- > 1 file changed, 15 insertions(+), 7 deletions(-) > > diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c > index da6adb3de21d..d7eec9fdaf9c 100644 > --- a/sound/soc/codecs/lpass-wsa-macro.c > +++ b/sound/soc/codecs/lpass-wsa-macro.c > @@ -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,
© 2016 - 2025 Red Hat, Inc.