[PATCH v4 0/4] ASoC: qcom: volume fixes and codec cleanups
To reduce the risk of speaker damage the PA gain needs to be limited on machines like the Lenovo Thinkpad X13s until we have active speaker protection in place.
Limit the gain to the current default setting provided by the UCM configuration which most user have so far been using (due to a bug in the configuration files which prevented hardware volume control [1]).
The wsa883x PA volume control also turned out to be broken, which meant that the default setting used by UCM configuration is actually the lowest level (-3 dB). With the codec driver fixed, hardware volume control also works as expected.
Note that the new wsa884x driver most likely suffers from a similar bug, I'll send a fix for that once I've got that confirmed.
Included is also a related fix for the LPASS WSA macro driver, which was changing the digital gain setting behind the back of user space and which can result in excessive (or too low) digital gain.
There are further Qualcomm codec drivers that similarly appear to manipulate various gain settings, but on closer inspection it turns out that they only write back the current settings. Tests reveal that these writes are indeed needed for any prior updates to take effect (at least for the WSA and RX macros).
Johan
[1] https://github.com/alsa-project/alsa-ucm-conf/pull/382
Changes in v4 - keep the full PA volume control range and only fix the exported dB values - use a combined -3 dB machine limit as limiting just the PA volume confuses PulseAudio - drop the PA gain initialisation which is no longer needed
Changes in v3 - fix the wsa883x PA volume control and update the machine limits accordingly
Changes in v2 - keep the volume register write on power-on in lpass-wsa-macro - drop the other patches removing volume register writes on DAPM events - only drop the constant-zero gain offsets in wcd9335
Johan Hovold (4): ASoC: codecs: wsa883x: fix PA volume control ASoC: qcom: sc8280xp: limit speaker volumes ASoC: codecs: lpass-wsa-macro: fix compander volume hack ASoC: codecs: wcd9335: drop unused gain hack remnant
sound/soc/codecs/lpass-wsa-macro.c | 7 ------- sound/soc/codecs/wcd9335.c | 4 ---- sound/soc/codecs/wsa883x.c | 6 +++++- sound/soc/qcom/sc8280xp.c | 12 +++++++----- 4 files changed, 12 insertions(+), 17 deletions(-)
The PA gain can be set in steps of 1.5 dB from -3 dB to 18 dB, that is, in 15 levels.
Fix the dB values for the PA volume control as experiments using wsa8835 show that the first 16 levels all map to the same lowest gain while the last three map to the highest gain.
These values specifically need to be correct for the sound server to provide proper volume control.
Note that level 0 (-3 dB) does not mute the PA so the mute flag should also not be set.
Fixes: cdb09e623143 ("ASoC: codecs: wsa883x: add control, dapm widgets and map") Cc: stable@vger.kernel.org # 6.0 Cc: Srinivas Kandagatla srinivas.kandagatla@linaro.org Signed-off-by: Johan Hovold johan+linaro@kernel.org --- sound/soc/codecs/wsa883x.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c index cb83c569e18d..a2e86ef7d18f 100644 --- a/sound/soc/codecs/wsa883x.c +++ b/sound/soc/codecs/wsa883x.c @@ -1098,7 +1098,11 @@ static int wsa_dev_mode_put(struct snd_kcontrol *kcontrol, return 1; }
-static const DECLARE_TLV_DB_SCALE(pa_gain, -300, 150, -300); +static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(pa_gain, + 0, 14, TLV_DB_SCALE_ITEM(-300, 0, 0), + 15, 29, TLV_DB_SCALE_ITEM(-300, 150, 0), + 30, 31, TLV_DB_SCALE_ITEM(1800, 0, 0), +);
static int wsa883x_get_swr_port(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
The UCM configuration for the Lenovo ThinkPad X13s has up until now been setting the speaker PA volume to the minimum -3 dB when enabling the speakers, but this does not prevent the user from increasing the volume further.
Limit the digital gain and PA volumes to a combined -3 dB in the machine driver to reduce the risk of speaker damage until we have active speaker protection in place (or higher safe levels have been established).
Note that the PA volume limit cannot be set lower than 0 dB or PulseAudio gets confused when the first 16 levels all map to -3 dB.
Also note that this will probably need to be generalised using machine-specific limits, but a common limit should do for now.
Cc: stable@vger.kernel.org # 6.5 Signed-off-by: Johan Hovold johan+linaro@kernel.org --- sound/soc/qcom/sc8280xp.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c index ed4bb551bfbb..b7fd503a1666 100644 --- a/sound/soc/qcom/sc8280xp.c +++ b/sound/soc/qcom/sc8280xp.c @@ -32,12 +32,14 @@ static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd) case WSA_CODEC_DMA_RX_0: case WSA_CODEC_DMA_RX_1: /* - * set limit of 0dB on Digital Volume for Speakers, - * this can prevent damage of speakers to some extent without - * active speaker protection + * Set limit of -3 dB on Digital Volume and 0 dB on PA Volume + * to reduce the risk of speaker damage until we have active + * speaker protection in place. */ - snd_soc_limit_volume(card, "WSA_RX0 Digital Volume", 84); - snd_soc_limit_volume(card, "WSA_RX1 Digital Volume", 84); + snd_soc_limit_volume(card, "WSA_RX0 Digital Volume", 81); + snd_soc_limit_volume(card, "WSA_RX1 Digital Volume", 81); + snd_soc_limit_volume(card, "SpkrLeft PA Volume", 17); + snd_soc_limit_volume(card, "SpkrRight PA Volume", 17); break; default: break;
On Fri, Jan 19, 2024 at 12:24:18PM +0100, Johan Hovold wrote:
The UCM configuration for the Lenovo ThinkPad X13s has up until now been setting the speaker PA volume to the minimum -3 dB when enabling the speakers, but this does not prevent the user from increasing the volume further.
Limit the digital gain and PA volumes to a combined -3 dB in the machine driver to reduce the risk of speaker damage until we have active speaker protection in place (or higher safe levels have been established).
Note that the PA volume limit cannot be set lower than 0 dB or PulseAudio gets confused when the first 16 levels all map to -3 dB.
I tracked the down the root cause for this, which appears to be a bug (feature) in pulseaudio that causes it to reject the dB range if the maximum is negative:
https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/447
This happened to work with v3 which limited the PA volume to the single lowest setting, but would similarly break if anyone wants to set a -1.5 dB limit.
Johan
On Fri, Jan 19, 2024 at 12:24:18PM +0100, Johan Hovold wrote:
The UCM configuration for the Lenovo ThinkPad X13s has up until now been setting the speaker PA volume to the minimum -3 dB when enabling the speakers, but this does not prevent the user from increasing the volume further.
This doesn't apply against current code, please check and resend.
On Mon, Jan 22, 2024 at 12:03:55AM +0000, Mark Brown wrote:
On Fri, Jan 19, 2024 at 12:24:18PM +0100, Johan Hovold wrote:
The UCM configuration for the Lenovo ThinkPad X13s has up until now been setting the speaker PA volume to the minimum -3 dB when enabling the speakers, but this does not prevent the user from increasing the volume further.
This doesn't apply against current code, please check and resend.
These patches are based on Linus's tree after merging the sound updates and I just verified that they apply cleanly to 6.8-rc1.
I couldn't find anything related in either linux-next or your ASoC tree that should interfere.
Could you please try again or let me know which branch to rebase on?
Johan
On Mon, Jan 22, 2024 at 08:41:59AM +0100, Johan Hovold wrote:
On Mon, Jan 22, 2024 at 12:03:55AM +0000, Mark Brown wrote:
This doesn't apply against current code, please check and resend.
These patches are based on Linus's tree after merging the sound updates and I just verified that they apply cleanly to 6.8-rc1.
I couldn't find anything related in either linux-next or your ASoC tree that should interfere.
Could you please try again or let me know which branch to rebase on?
I was applying it against v6.8-rc1.
On Mon, Jan 22, 2024 at 04:05:37PM +0000, Mark Brown wrote:
On Mon, Jan 22, 2024 at 08:41:59AM +0100, Johan Hovold wrote:
On Mon, Jan 22, 2024 at 12:03:55AM +0000, Mark Brown wrote:
This doesn't apply against current code, please check and resend.
These patches are based on Linus's tree after merging the sound updates and I just verified that they apply cleanly to 6.8-rc1.
I couldn't find anything related in either linux-next or your ASoC tree that should interfere.
Could you please try again or let me know which branch to rebase on?
I was applying it against v6.8-rc1.
That's what I assumed, but I still don't understand why it doesn't apply on your end:
$ git checkout -b tmp v6.8-rc1 $ b4 am 20240119112420.7446-1-johan+linaro@kernel.org ... $ git am ./v4_20240119_johan_linaro_asoc_qcom_volume_fixes_and_codec_cleanups.mbx Applying: ASoC: codecs: wsa883x: fix PA volume control Applying: ASoC: qcom: sc8280xp: limit speaker volumes Applying: ASoC: codecs: lpass-wsa-macro: fix compander volume hack Applying: ASoC: codecs: wcd9335: drop unused gain hack remnant
And if I generate patches from this branch, the diffs are identical to the v4 patches I sent.
Could you please try again, and tell me which patch fails to apply and how it fails?
Johan
On Mon, Jan 22, 2024 at 06:29:12PM +0100, Johan Hovold wrote:
Could you please try again, and tell me which patch fails to apply and how it fails?
It was the specific patch I replied to, just the standard "this patch doesn't apply" message.
On Mon, Jan 22, 2024 at 06:06:25PM +0000, Mark Brown wrote:
On Mon, Jan 22, 2024 at 06:29:12PM +0100, Johan Hovold wrote:
Could you please try again, and tell me which patch fails to apply and how it fails?
It was the specific patch I replied to, just the standard "this patch doesn't apply" message.
Ok, thanks. No idea what goes wrong here. I just sent the regenerated patches as a v5.
Johan
The LPASS WSA macro codec driver is updating the digital gain settings behind the back of user space on DAPM events if companding has been enabled.
As compander control is exported to user space, this can result in the digital gain setting being incremented (or decremented) every time the sound server is started and the codec suspended depending on what the UCM configuration looks like.
Soon enough playback will become distorted (or too quiet).
This is specifically a problem on the Lenovo ThinkPad X13s as this bypasses the limit for the digital gain setting that has been set by the machine driver.
Fix this by simply dropping the compander gain offset hack. If someone cares about modelling the impact of the compander setting this can possibly be done by exporting it as a volume control later.
Note that the volume registers still need to be written after enabling clocks in order for any prior updates to take effect.
Fixes: 2c4066e5d428 ("ASoC: codecs: lpass-wsa-macro: add dapm widgets and route") Cc: stable@vger.kernel.org # 5.11 Cc: Srinivas Kandagatla srinivas.kandagatla@linaro.org Signed-off-by: Johan Hovold johan+linaro@kernel.org --- sound/soc/codecs/lpass-wsa-macro.c | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c index 7e21cec3c2fb..6ce309980cd1 100644 --- a/sound/soc/codecs/lpass-wsa-macro.c +++ b/sound/soc/codecs/lpass-wsa-macro.c @@ -1584,7 +1584,6 @@ static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, u16 gain_reg; u16 reg; int val; - int offset_val = 0; struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
if (w->shift == WSA_MACRO_COMP1) { @@ -1623,10 +1622,8 @@ static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, CDC_WSA_RX1_RX_PATH_MIX_SEC0, CDC_WSA_RX_PGA_HALF_DB_MASK, CDC_WSA_RX_PGA_HALF_DB_ENABLE); - offset_val = -2; } val = snd_soc_component_read(component, gain_reg); - val += offset_val; snd_soc_component_write(component, gain_reg, val); wsa_macro_config_ear_spkr_gain(component, wsa, event, gain_reg); @@ -1654,10 +1651,6 @@ static int wsa_macro_enable_interpolator(struct snd_soc_dapm_widget *w, CDC_WSA_RX1_RX_PATH_MIX_SEC0, CDC_WSA_RX_PGA_HALF_DB_MASK, CDC_WSA_RX_PGA_HALF_DB_DISABLE); - offset_val = 2; - val = snd_soc_component_read(component, gain_reg); - val += offset_val; - snd_soc_component_write(component, gain_reg, val); } wsa_macro_config_ear_spkr_gain(component, wsa, event, gain_reg);
The vendor driver appears to be modifying the gain settings behind the back of user space but these hacks never made it upstream except for some essentially dead code that adds a constant zero to the current gain setting on DAPM events.
Note that the volume registers still need to be written after enabling clocks in order for any prior updates to take effect.
Reviewed-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Signed-off-by: Johan Hovold johan+linaro@kernel.org --- sound/soc/codecs/wcd9335.c | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 43c648efd0d9..deb15b95992d 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -3033,7 +3033,6 @@ static int wcd9335_codec_enable_mix_path(struct snd_soc_dapm_widget *w, { struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); u16 gain_reg; - int offset_val = 0; int val = 0;
switch (w->reg) { @@ -3073,7 +3072,6 @@ static int wcd9335_codec_enable_mix_path(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_POST_PMU: val = snd_soc_component_read(comp, gain_reg); - val += offset_val; snd_soc_component_write(comp, gain_reg, val); break; case SND_SOC_DAPM_POST_PMD: @@ -3294,7 +3292,6 @@ static int wcd9335_codec_enable_interpolator(struct snd_soc_dapm_widget *w, u16 gain_reg; u16 reg; int val; - int offset_val = 0;
if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT0 INTERP"))) { reg = WCD9335_CDC_RX0_RX_PATH_CTL; @@ -3337,7 +3334,6 @@ static int wcd9335_codec_enable_interpolator(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMU: wcd9335_config_compander(comp, w->shift, event); val = snd_soc_component_read(comp, gain_reg); - val += offset_val; snd_soc_component_write(comp, gain_reg, val); break; case SND_SOC_DAPM_POST_PMD:
On Fri, 19 Jan 2024 12:24:16 +0100, Johan Hovold wrote:
To reduce the risk of speaker damage the PA gain needs to be limited on machines like the Lenovo Thinkpad X13s until we have active speaker protection in place.
Limit the gain to the current default setting provided by the UCM configuration which most user have so far been using (due to a bug in the configuration files which prevented hardware volume control [1]).
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/4] ASoC: codecs: wsa883x: fix PA volume control (no commit info) [2/4] ASoC: qcom: sc8280xp: limit speaker volumes commit: c481016bb4f8a9c059c39ac06e7b65e233a61f6a [3/4] ASoC: codecs: lpass-wsa-macro: fix compander volume hack (no commit info) [4/4] ASoC: codecs: wcd9335: drop unused gain hack remnant (no commit info)
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 Mon, Jan 22, 2024 at 09:54:10PM +0000, Mark Brown wrote:
On Fri, 19 Jan 2024 12:24:16 +0100, Johan Hovold wrote:
To reduce the risk of speaker damage the PA gain needs to be limited on machines like the Lenovo Thinkpad X13s until we have active speaker protection in place.
Limit the gain to the current default setting provided by the UCM configuration which most user have so far been using (due to a bug in the configuration files which prevented hardware volume control [1]).
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/4] ASoC: codecs: wsa883x: fix PA volume control (no commit info) [2/4] ASoC: qcom: sc8280xp: limit speaker volumes commit: c481016bb4f8a9c059c39ac06e7b65e233a61f6a [3/4] ASoC: codecs: lpass-wsa-macro: fix compander volume hack (no commit info) [4/4] ASoC: codecs: wcd9335: drop unused gain hack remnant (no commit info)
Thanks, Mark.
Could you consider applying at least patches 1/4 and 3/4 for 6.8 as well?
The former is needed for proper hardware volume control with the fixed UCM files, and the latter avoids ending up with the digital gain setting set too low or too high while by-passing the volume limit set by the machine driver.
Johan
On Tue, Jan 23, 2024 at 08:58:20AM +0100, Johan Hovold wrote:
Could you consider applying at least patches 1/4 and 3/4 for 6.8 as well?
Please check git and resend anything you think has been missed. When you resent the whole series rather than just the problematic patch that most likely confused b4.
On Tue, Jan 23, 2024 at 01:05:21PM +0000, Mark Brown wrote:
On Tue, Jan 23, 2024 at 08:58:20AM +0100, Johan Hovold wrote:
Could you consider applying at least patches 1/4 and 3/4 for 6.8 as well?
Please check git and resend anything you think has been missed. When you resent the whole series rather than just the problematic patch that most likely confused b4.
Everything appears to be in your for-6.8 branch now, thanks!
The merge commit for the series does not include the volume limit patch, so it looks like that one got applied separately before you applied the rest of the series:
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git/commit/?h=...
But all four patches are there now.
Johan
On Tue, Jan 23, 2024 at 02:30:54PM +0100, Johan Hovold wrote:
The merge commit for the series does not include the volume limit patch, so it looks like that one got applied separately before you applied the rest of the series:
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git/commit/?h=...
Yes, loose patches go before serieses.
participants (3)
-
Johan Hovold
-
Johan Hovold
-
Mark Brown