On Wed, Dec 14, 2016 at 6:57 AM, Mark Brown broonie@kernel.org wrote:
On Mon, Dec 12, 2016 at 10:12:06PM -0800, Ben Zhang wrote:
Add a DAPM_MUX for userspace to control the Class G function: "Switching": Use +-1.8V or +-0.9V supply, based on signal amplitude. "1.8V": Always use +-1.8V.
This doesn't affect audio routing so why is it being done with a DAPM mux?
When user wants the switching voltages, the Class G register bit needs to be toggled at a specific time in the widget power up/down sequences on the playback route. It helps reduce pop and is consistent with existing behavior. DAPM_MUX achieves this by taking DAPM_PGA_S in and out of the playback route based on user selection. If the register bit is directly controlled by a separate kcontrol in snd_soc_codec_driver.controls unrelated to widgets, the bit will be set immediately by user even when there is no active playback. Then when playback starts, Class G is already on before the DACs/charge pumps/output drivers/pulldowns are enabled. The existing/desired behavior is to turn on Class G last and turn it off first.
John has sent me a patch which uses a separate SOC_ENUM_EXT kcontrol in snd_soc_codec_driver.controls to set a flag, then has DAPM_PGA_S PM event callbacks selectively setting the register bit based on the flag. But it feels cleaner to implement this with a DAPM_MUX: The DAPM_PGA_S widget power status correctly reflects the actual register bit. User can experiment with the setting during playback.
John, to make SND_SOC_NOPM work with DAPM_MUX on older kernels, commit 236aaa686358 ("ASoC: dapm: Consolidate MUXs and virtual MUXs") can be backported, which landed in v3.15. chromeos-3.14 has backported it already. Another solution is to backport my patch by using SND_SOC_DAPM_VIRT_MUX on older kernels.