Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions sound/soc/codecs/wm8962.c
Original file line number Diff line number Diff line change
Expand Up @@ -2466,6 +2466,7 @@ static void wm8962_configure_bclk(struct snd_soc_component *component)
int clocking2 = 0;
int clocking4 = 0;
int aif2 = 0;
bool sysclk_was_ena;

if (!wm8962->sysclk_rate) {
dev_dbg(component->dev, "No SYSCLK configured\n");
Expand Down Expand Up @@ -2498,8 +2499,19 @@ static void wm8962_configure_bclk(struct snd_soc_component *component)
/* DSPCLK_DIV can be only generated correctly after enabling SYSCLK.
* So we here provisionally enable it and then disable it afterward
* if current bias_level hasn't reached SND_SOC_BIAS_ON.
*
* SYSCLK_ENA is owned by the "SYSCLK" DAPM supply widget, which may
* already have it set even below SND_SOC_BIAS_ON: wm8962_mic_detect()
* force-enables that pin, so on boards using it (the Tegra machine
* driver) the bit is set once at card init and DAPM never writes it
* again. If we unconditionally clear it here, SYSCLK stays off for
* every stream, DAPM still believes it is on, and the codec is
* silent with "DC servo timed out" errors. Only undo what we did.
*/
if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_ON)
sysclk_was_ena = snd_soc_component_read(component, WM8962_CLOCKING2) &
WM8962_SYSCLK_ENA;
if (!sysclk_was_ena &&
snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_ON)
snd_soc_component_update_bits(component, WM8962_CLOCKING2,
WM8962_SYSCLK_ENA_MASK, WM8962_SYSCLK_ENA);

Expand All @@ -2513,7 +2525,8 @@ static void wm8962_configure_bclk(struct snd_soc_component *component)
usleep_range(500, 1000);
dspclk = snd_soc_component_read(component, WM8962_CLOCKING1);

if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_ON)
if (!sysclk_was_ena &&
snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_ON)
snd_soc_component_update_bits(component, WM8962_CLOCKING2,
WM8962_SYSCLK_ENA_MASK, 0);

Expand Down