[PATCH v5 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 v5 - rebase on v6.8-rc1
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;
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 Mon, 22 Jan 2024 19:18:15 +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!
[2/4] ASoC: qcom: sc8280xp: limit speaker volumes commit: c481016bb4f8a9c059c39ac06e7b65e233a61f6a
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
Hi Mark and Takashi,
On Mon, Jan 22, 2024 at 09:54:15PM +0000, Mark Brown wrote:
On Mon, 22 Jan 2024 19:18:15 +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
alsa-ucm-conf 1.2.11 was released yesterday, which means that it is now very urgent to get the speaker volume limitation backported to the stable trees.
Could you please try to make sure that these fixes get to Linus this week?
Johan
Hi Greg and Sasha,
On Tue, Jan 30, 2024 at 01:53:37PM +0100, Johan Hovold wrote:
On Mon, Jan 22, 2024 at 09:54:15PM +0000, Mark Brown wrote:
On Mon, 22 Jan 2024 19:18:15 +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
alsa-ucm-conf 1.2.11 was released yesterday, which means that it is now very urgent to get the speaker volume limitation backported to the stable trees.
Could you please try to make sure that these fixes get to Linus this week?
This series (and a related headphone codec fix) were merged into Linus's tree yesterday.
I saw that the 6.7.4 stable patches were sent out for review over night, but could it be possible to squeeze in also the following four fixes in 6.7.4 (and 6.6.16)?
c481016bb4f8 ASoC: qcom: sc8280xp: limit speaker volumes 4d0e8bdfa4a5 ASoC: codecs: wcd938x: fix headphones volume controls 46188db080bd ASoC: codecs: lpass-wsa-macro: fix compander volume hack b53cc6144a3f ASoC: codecs: wsa883x: fix PA volume control
These are needed for proper volume control and, importantly, to prevent users of the Lenovo ThinkPad X13s from potentially damaging their speakers when the distros ship the latest UCM configuration files which were released on Monday.
Johan
On Sat, Feb 03, 2024 at 09:36:14AM +0100, Johan Hovold wrote:
Hi Greg and Sasha,
On Tue, Jan 30, 2024 at 01:53:37PM +0100, Johan Hovold wrote:
On Mon, Jan 22, 2024 at 09:54:15PM +0000, Mark Brown wrote:
On Mon, 22 Jan 2024 19:18:15 +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
alsa-ucm-conf 1.2.11 was released yesterday, which means that it is now very urgent to get the speaker volume limitation backported to the stable trees.
Could you please try to make sure that these fixes get to Linus this week?
This series (and a related headphone codec fix) were merged into Linus's tree yesterday.
I saw that the 6.7.4 stable patches were sent out for review over night, but could it be possible to squeeze in also the following four fixes in 6.7.4 (and 6.6.16)?
c481016bb4f8 ASoC: qcom: sc8280xp: limit speaker volumes 4d0e8bdfa4a5 ASoC: codecs: wcd938x: fix headphones volume controls 46188db080bd ASoC: codecs: lpass-wsa-macro: fix compander volume hack b53cc6144a3f ASoC: codecs: wsa883x: fix PA volume control
These are needed for proper volume control and, importantly, to prevent users of the Lenovo ThinkPad X13s from potentially damaging their speakers when the distros ship the latest UCM configuration files which were released on Monday.
All now queued up for this round, thanks.
greg k-h
On Sat, Feb 03, 2024 at 08:04:01AM -0800, Greg Kroah-Hartman wrote:
On Sat, Feb 03, 2024 at 09:36:14AM +0100, Johan Hovold wrote:
I saw that the 6.7.4 stable patches were sent out for review over night, but could it be possible to squeeze in also the following four fixes in 6.7.4 (and 6.6.16)?
c481016bb4f8 ASoC: qcom: sc8280xp: limit speaker volumes 4d0e8bdfa4a5 ASoC: codecs: wcd938x: fix headphones volume controls 46188db080bd ASoC: codecs: lpass-wsa-macro: fix compander volume hack b53cc6144a3f ASoC: codecs: wsa883x: fix PA volume control
All now queued up for this round, thanks.
Thanks, much appreciated!
Johan
participants (4)
-
Greg Kroah-Hartman
-
Johan Hovold
-
Johan Hovold
-
Mark Brown