diff options
author | Bard Liao <bardliao@realtek.com> | 2015-03-09 04:55:23 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-03-09 14:12:48 -0400 |
commit | 485372dc24ca2eaac18ce41a51b9dd017bc11400 (patch) | |
tree | 3f18931542971cfc56369cc115c1da1e231761de | |
parent | bd22f9d405eb14cc074d294919d0b909e0bc6170 (diff) |
ASoC: rt5670: Check sysclk source by private data
Currently, is_sys_clk_from_pll check sysclk source by reading codec
register value. And it will be invoked before updating dapm widget
power. In some machine driver, snd_soc_dai_set_sysclk is called in
dapm event to switch codec sysclk to RC clock in idle mode. And in
some use cases (such as syspend/resume) hw_params will not be called
when the dapm widget is powered up. As a result, is_sys_clk_from_pll
will return 0 although it is supposed to be 1.
To solve this, we let is_sys_clk_from_pll check sysclk sysclk_src
which is stored in private data and don't change the value of sysclk_src
when codec sysclk is switched to internal clock. The internal clock
can only be used in idle mode, so it sould be fine if we don't set
sysclk_src to internal clock.
Signed-off-by: Bard Liao <bardliao@realtek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | sound/soc/codecs/rt5670.c | 13 |
1 files changed, 5 insertions, 8 deletions
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 32cd26678bae..9e3bc43178f1 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c | |||
@@ -517,11 +517,10 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w, | |||
517 | static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, | 517 | static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, |
518 | struct snd_soc_dapm_widget *sink) | 518 | struct snd_soc_dapm_widget *sink) |
519 | { | 519 | { |
520 | unsigned int val; | 520 | struct snd_soc_codec *codec = source->codec; |
521 | struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); | ||
521 | 522 | ||
522 | val = snd_soc_read(source->codec, RT5670_GLB_CLK); | 523 | if (rt5670->sysclk_src == RT5670_SCLK_S_PLL1) |
523 | val &= RT5670_SCLK_SRC_MASK; | ||
524 | if (val == RT5670_SCLK_SRC_PLL1) | ||
525 | return 1; | 524 | return 1; |
526 | else | 525 | else |
527 | return 0; | 526 | return 0; |
@@ -2270,9 +2269,6 @@ static int rt5670_set_dai_sysclk(struct snd_soc_dai *dai, | |||
2270 | struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); | 2269 | struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); |
2271 | unsigned int reg_val = 0; | 2270 | unsigned int reg_val = 0; |
2272 | 2271 | ||
2273 | if (freq == rt5670->sysclk && clk_id == rt5670->sysclk_src) | ||
2274 | return 0; | ||
2275 | |||
2276 | switch (clk_id) { | 2272 | switch (clk_id) { |
2277 | case RT5670_SCLK_S_MCLK: | 2273 | case RT5670_SCLK_S_MCLK: |
2278 | reg_val |= RT5670_SCLK_SRC_MCLK; | 2274 | reg_val |= RT5670_SCLK_SRC_MCLK; |
@@ -2290,7 +2286,8 @@ static int rt5670_set_dai_sysclk(struct snd_soc_dai *dai, | |||
2290 | snd_soc_update_bits(codec, RT5670_GLB_CLK, | 2286 | snd_soc_update_bits(codec, RT5670_GLB_CLK, |
2291 | RT5670_SCLK_SRC_MASK, reg_val); | 2287 | RT5670_SCLK_SRC_MASK, reg_val); |
2292 | rt5670->sysclk = freq; | 2288 | rt5670->sysclk = freq; |
2293 | rt5670->sysclk_src = clk_id; | 2289 | if (clk_id != RT5670_SCLK_S_RCCLK) |
2290 | rt5670->sysclk_src = clk_id; | ||
2294 | 2291 | ||
2295 | dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id); | 2292 | dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id); |
2296 | 2293 | ||