提交 e413ba88 编写于 作者: M Mark Brown

ASoC: wm8994: Don't allow reconfiguration of FLL when it provides SYSCLK

Rather than trying to work around machine drivers which try to reprogram
the FLL while it is providing SYSCLK just return an error if they try.
This will avoid audio glitches during FLL reconfiguration, or at least
move the introduction of the glitches to the machine driver.

Since disabling the source for an active SYSCLK is not supported in the
first place systems shouldn't be doing this in the first place.
Signed-off-by: NMark Brown <broonie@opensource.wolfsonmicro.com>
上级 95cd98f9
...@@ -1900,24 +1900,20 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, ...@@ -1900,24 +1900,20 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
struct wm8994 *control = wm8994->wm8994; struct wm8994 *control = wm8994->wm8994;
int reg_offset, ret; int reg_offset, ret;
struct fll_div fll; struct fll_div fll;
u16 reg, aif1, aif2; u16 reg, clk1, aif_reg, aif_src;
unsigned long timeout; unsigned long timeout;
bool was_enabled; bool was_enabled;
aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
& WM8994_AIF1CLK_ENA;
aif2 = snd_soc_read(codec, WM8994_AIF2_CLOCKING_1)
& WM8994_AIF2CLK_ENA;
switch (id) { switch (id) {
case WM8994_FLL1: case WM8994_FLL1:
reg_offset = 0; reg_offset = 0;
id = 0; id = 0;
aif_src = 0x10;
break; break;
case WM8994_FLL2: case WM8994_FLL2:
reg_offset = 0x20; reg_offset = 0x20;
id = 1; id = 1;
aif_src = 0x18;
break; break;
default: default:
return -EINVAL; return -EINVAL;
...@@ -1959,11 +1955,20 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, ...@@ -1959,11 +1955,20 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
if (ret < 0) if (ret < 0)
return ret; return ret;
/* Gate the AIF clocks while we reclock */ /* Make sure that we're not providing SYSCLK right now */
snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, clk1 = snd_soc_read(codec, WM8994_CLOCKING_1);
WM8994_AIF1CLK_ENA, 0); if (clk1 & WM8994_SYSCLK_SRC)
snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, aif_reg = WM8994_AIF2_CLOCKING_1;
WM8994_AIF2CLK_ENA, 0); else
aif_reg = WM8994_AIF1_CLOCKING_1;
reg = snd_soc_read(codec, aif_reg);
if ((reg & WM8994_AIF1CLK_ENA) &&
(reg & WM8994_AIF1CLK_SRC_MASK) == aif_src) {
dev_err(codec->dev, "FLL%d is currently providing SYSCLK\n",
id + 1);
return -EBUSY;
}
/* We always need to disable the FLL while reconfiguring */ /* We always need to disable the FLL while reconfiguring */
snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset, snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
...@@ -2049,12 +2054,6 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, ...@@ -2049,12 +2054,6 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
wm8994->fll[id].out = freq_out; wm8994->fll[id].out = freq_out;
wm8994->fll[id].src = src; wm8994->fll[id].src = src;
/* Enable any gated AIF clocks */
snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
WM8994_AIF1CLK_ENA, aif1);
snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
WM8994_AIF2CLK_ENA, aif2);
configure_clock(codec); configure_clock(codec);
return 0; return 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册