Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: soc-dai: add flag to mute and unmute stream during trigger

In some setups like Speaker amps which are very sensitive, ex: keeping them
unmute without actual data stream for very short duration results in a
static charge and results in pop and clicks. To minimize this, provide a way
to mute and unmute such codecs during trigger callbacks.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Tested-by: Johan Hovold <johan+linaro@kernel.org>
Link: https://lore.kernel.org/r/20231027105747.32450-2-srinivas.kandagatla@linaro.org
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Srinivas Kandagatla and committed by
Mark Brown
f0220575 168d9784

+16 -4
+1
include/sound/soc-dai.h
··· 370 370 371 371 /* bit field */ 372 372 unsigned int no_capture_mute:1; 373 + unsigned int mute_unmute_on_trigger:1; 373 374 }; 374 375 375 376 struct snd_soc_cdai_ops {
+7
sound/soc/soc-dai.c
··· 658 658 ret = soc_dai_trigger(dai, substream, cmd); 659 659 if (ret < 0) 660 660 break; 661 + 662 + if (dai->driver->ops && dai->driver->ops->mute_unmute_on_trigger) 663 + snd_soc_dai_digital_mute(dai, 0, substream->stream); 664 + 661 665 soc_dai_mark_push(dai, substream, trigger); 662 666 } 663 667 break; ··· 671 667 for_each_rtd_dais(rtd, i, dai) { 672 668 if (rollback && !soc_dai_mark_match(dai, substream, trigger)) 673 669 continue; 670 + 671 + if (dai->driver->ops && dai->driver->ops->mute_unmute_on_trigger) 672 + snd_soc_dai_digital_mute(dai, 1, substream->stream); 674 673 675 674 r = soc_dai_trigger(dai, substream, cmd); 676 675 if (r < 0)
+8 -4
sound/soc/soc-pcm.c
··· 703 703 if (snd_soc_dai_active(dai) == 0) 704 704 soc_pcm_set_dai_params(dai, NULL); 705 705 706 - if (snd_soc_dai_stream_active(dai, substream->stream) == 0) 707 - snd_soc_dai_digital_mute(dai, 1, substream->stream); 706 + if (snd_soc_dai_stream_active(dai, substream->stream) == 0) { 707 + if (dai->driver->ops && !dai->driver->ops->mute_unmute_on_trigger) 708 + snd_soc_dai_digital_mute(dai, 1, substream->stream); 709 + } 708 710 } 709 711 } 710 712 ··· 900 898 snd_soc_dapm_stream_event(rtd, substream->stream, 901 899 SND_SOC_DAPM_STREAM_START); 902 900 903 - for_each_rtd_dais(rtd, i, dai) 904 - snd_soc_dai_digital_mute(dai, 0, substream->stream); 901 + for_each_rtd_dais(rtd, i, dai) { 902 + if (dai->driver->ops && !dai->driver->ops->mute_unmute_on_trigger) 903 + snd_soc_dai_digital_mute(dai, 0, substream->stream); 904 + } 905 905 906 906 out: 907 907 return soc_pcm_ret(rtd, ret);