Thank you for taking the time to help out.
On 11/15/2018 01:02 AM, Mark Brown wrote:
I've no idea what you're proposing, sorry.
I mentioned it in the message you replied to initially, so you can consult that for more details if you want, but I'll give a summary below:
As far as I could determine experimentally, switching clocks when the DAC is not suspended seems to result in a spike at the input of the DAC, the level of which doesn't depend on the digital volume setting (so that it's always very loud). I tried various potential fixes, based on guesses about probable causes of the spike (see first message where I CCed you for a brief list of attempted fixes) and it seems that a pop can be avoided either by suppressing it, by muting the DAC, or by avoiding generating it in the first place by switching the PCM5122 into standby (via bit PCM512x_RQST of the PCM512x_POWER register) before switching the external clock and switching it back out of standby afterwards.
Avoiding the spike instead of relying on muting seems preferable, but, since the power state of the PCM5122 is manipulated by the CODEC driver, in response to requests to set the bias level, I'm concerned about potential race conditions.
Right now I have the following implementation for switching the external clock:
/* Figure out if a clock switch is necessary based on currently used clock and requested sample rate . */
...
if (no_switch_needed) return;
snd_soc_dapm_mutex_lock(dapm); force = (snd_soc_dapm_get_bias_level(dapm) != SND_SOC_BIAS_OFF);
if (force) snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_OFF);
/* Switch the clock here. */
...
if (force) snd_soc_dapm_sync_unlocked(dapm);
snd_soc_dapm_mutex_unlock(dapm);
It seems to work fine, both in consistently avoiding the pop and in not producing any obvious side-effects. Does that look reasonable, or is there a better way to temporarily switch the PCM5122 into standby in a safe way?