diff options
Diffstat (limited to 'sound/soc/codecs/wm8904.c')
-rw-r--r-- | sound/soc/codecs/wm8904.c | 73 |
1 files changed, 45 insertions, 28 deletions
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index bcb3c9d5abf0..7d7ea15d73e0 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -1410,34 +1410,6 @@ static int wm8904_hw_params(struct snd_pcm_substream *substream, return 0; } - -static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id, - unsigned int freq, int dir) -{ - struct snd_soc_component *component = dai->component; - struct wm8904_priv *priv = snd_soc_component_get_drvdata(component); - - switch (clk_id) { - case WM8904_CLK_MCLK: - priv->sysclk_src = clk_id; - priv->mclk_rate = freq; - break; - - case WM8904_CLK_FLL: - priv->sysclk_src = clk_id; - break; - - default: - return -EINVAL; - } - - dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq); - - wm8904_configure_clocking(component); - - return 0; -} - static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct snd_soc_component *component = dai->component; @@ -1824,6 +1796,50 @@ out: return 0; } +static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id, + unsigned int freq, int dir) +{ + struct snd_soc_component *component = dai->component; + struct wm8904_priv *priv = snd_soc_component_get_drvdata(component); + unsigned long mclk_freq; + int ret; + + switch (clk_id) { + case WM8904_CLK_AUTO: + mclk_freq = clk_get_rate(priv->mclk); + /* enable FLL if a different sysclk is desired */ + if (mclk_freq != freq) { + priv->sysclk_src = WM8904_CLK_FLL; + ret = wm8904_set_fll(dai, WM8904_FLL_MCLK, + WM8904_FLL_MCLK, + mclk_freq, freq); + if (ret) + return ret; + break; + } + clk_id = WM8904_CLK_MCLK; + /* fallthrough */ + + case WM8904_CLK_MCLK: + priv->sysclk_src = clk_id; + priv->mclk_rate = freq; + break; + + case WM8904_CLK_FLL: + priv->sysclk_src = clk_id; + break; + + default: + return -EINVAL; + } + + dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq); + + wm8904_configure_clocking(component); + + return 0; +} + static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute) { struct snd_soc_component *component = codec_dai->component; @@ -1917,6 +1933,7 @@ static int wm8904_set_bias_level(struct snd_soc_component *component, snd_soc_component_update_bits(component, WM8904_BIAS_CONTROL_0, WM8904_BIAS_ENA, 0); + snd_soc_component_write(component, WM8904_SW_RESET_AND_ID, 0); regcache_cache_only(wm8904->regmap, true); regcache_mark_dirty(wm8904->regmap); |