diff options
author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2019-09-20 16:02:12 +0300 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2019-10-01 14:10:10 +0300 |
commit | 419e2f50833661cec15200d5ee7385daee733667 (patch) | |
tree | 696cf9daee71c2f77ec60a8188b44202df459e82 /sound/soc/codecs/wm8994.c | |
parent | 7cf2804775f8a388411624b3e768e55d08711e9d (diff) | |
download | linux-419e2f50833661cec15200d5ee7385daee733667.tar.xz |
ASoC: wm8994: Add support for setting MCLK clock rate
Extend the set_sysclk() handler so we also set frequency of the MCLK1,
MCLK2 clocks through clk API when those clocks are specified in DT.
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
Link: https://lore.kernel.org/r/20190920130218.32690-4-s.nawrocki@samsung.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/codecs/wm8994.c')
-rw-r--r-- | sound/soc/codecs/wm8994.c | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index c3d06e8bc54f..35fbaa0138bf 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -167,12 +167,12 @@ static int configure_aif_clock(struct snd_soc_component *component, int aif) switch (wm8994->sysclk[aif]) { case WM8994_SYSCLK_MCLK1: - rate = wm8994->mclk[0]; + rate = wm8994->mclk_rate[0]; break; case WM8994_SYSCLK_MCLK2: reg1 |= 0x8; - rate = wm8994->mclk[1]; + rate = wm8994->mclk_rate[1]; break; case WM8994_SYSCLK_FLL1: @@ -2367,12 +2367,29 @@ static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src, return _wm8994_set_fll(dai->component, id, src, freq_in, freq_out); } +static int wm8994_set_mclk_rate(struct wm8994_priv *wm8994, unsigned int id, + unsigned int *freq) +{ + int ret; + + if (!wm8994->mclk[id].clk || *freq == wm8994->mclk_rate[id]) + return 0; + + ret = clk_set_rate(wm8994->mclk[id].clk, *freq); + if (ret < 0) + return ret; + + *freq = clk_get_rate(wm8994->mclk[id].clk); + + return 0; +} + static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_component *component = dai->component; struct wm8994_priv *wm8994 = snd_soc_component_get_drvdata(component); - int i; + int ret, i; switch (dai->id) { case 1: @@ -2387,7 +2404,12 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, switch (clk_id) { case WM8994_SYSCLK_MCLK1: wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK1; - wm8994->mclk[0] = freq; + + ret = wm8994_set_mclk_rate(wm8994, dai->id - 1, &freq); + if (ret < 0) + return ret; + + wm8994->mclk_rate[0] = freq; dev_dbg(dai->dev, "AIF%d using MCLK1 at %uHz\n", dai->id, freq); break; @@ -2395,7 +2417,12 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, case WM8994_SYSCLK_MCLK2: /* TODO: Set GPIO AF */ wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK2; - wm8994->mclk[1] = freq; + + ret = wm8994_set_mclk_rate(wm8994, dai->id - 1, &freq); + if (ret < 0) + return ret; + + wm8994->mclk_rate[1] = freq; dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n", dai->id, freq); break; @@ -4447,6 +4474,7 @@ static const struct snd_soc_component_driver soc_component_dev_wm8994 = { static int wm8994_probe(struct platform_device *pdev) { struct wm8994_priv *wm8994; + int ret; wm8994 = devm_kzalloc(&pdev->dev, sizeof(struct wm8994_priv), GFP_KERNEL); @@ -4458,6 +4486,16 @@ static int wm8994_probe(struct platform_device *pdev) wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent); + wm8994->mclk[WM8994_MCLK1].id = "MCLK1"; + wm8994->mclk[WM8994_MCLK2].id = "MCLK2"; + + ret = devm_clk_bulk_get_optional(pdev->dev.parent, ARRAY_SIZE(wm8994->mclk), + wm8994->mclk); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to get clocks: %d\n", ret); + return ret; + } + pm_runtime_enable(&pdev->dev); pm_runtime_idle(&pdev->dev); |