From b10ab7b838bdd86031aececcb386dc253ef3466f Mon Sep 17 00:00:00 2001 From: Tushar Behera Date: Mon, 26 May 2014 13:58:21 +0530 Subject: ASoC: max98090: Add master clock handling If master clock is provided through device tree, then update the master clock frequency during set_sysclk. Documentation has been updated to reflect the change. Signed-off-by: Tushar Behera Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/max98090.txt | 6 ++++++ sound/soc/codecs/max98090.c | 23 ++++++++++++++++++++++ sound/soc/codecs/max98090.h | 1 + 3 files changed, 30 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/max98090.txt b/Documentation/devicetree/bindings/sound/max98090.txt index e4c8b36dcf89..a5e63fa47dc5 100644 --- a/Documentation/devicetree/bindings/sound/max98090.txt +++ b/Documentation/devicetree/bindings/sound/max98090.txt @@ -10,6 +10,12 @@ Required properties: - interrupts : The CODEC's interrupt output. +Optional properties: + +- clocks: The phandle of the master clock to the CODEC + +- clock-names: Should be "mclk" + Pins on the device (for linking into audio routes): * MIC1 diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 4ee1f88760c4..8857be798f3b 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -1798,6 +1799,19 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_PREPARE: + /* + * SND_SOC_BIAS_PREPARE is called while preparing for a + * transition to ON or away from ON. If current bias_level + * is SND_SOC_BIAS_ON, then it is preparing for a transition + * away from ON. Disable the clock in that case, otherwise + * enable it. + */ + if (!IS_ERR(max98090->mclk)) { + if (codec->dapm.bias_level == SND_SOC_BIAS_ON) + clk_disable_unprepare(max98090->mclk); + else + clk_prepare_enable(max98090->mclk); + } break; case SND_SOC_BIAS_STANDBY: @@ -1927,6 +1941,11 @@ static int max98090_dai_set_sysclk(struct snd_soc_dai *dai, if (freq == max98090->sysclk) return 0; + if (!IS_ERR(max98090->mclk)) { + freq = clk_round_rate(max98090->mclk, freq); + clk_set_rate(max98090->mclk, freq); + } + /* Setup clocks for slave mode, and using the PLL * PSCLK = 0x01 (when master clk is 10MHz to 20MHz) * 0x02 (when master clk is 20MHz to 40MHz).. @@ -2211,6 +2230,10 @@ static int max98090_probe(struct snd_soc_codec *codec) dev_dbg(codec->dev, "max98090_probe\n"); + max98090->mclk = devm_clk_get(codec->dev, "mclk"); + if (PTR_ERR(max98090->mclk) == -EPROBE_DEFER) + return -EPROBE_DEFER; + max98090->codec = codec; /* Reset the codec, the DSP core, and disable all interrupts */ diff --git a/sound/soc/codecs/max98090.h b/sound/soc/codecs/max98090.h index 5a3c8d0613cb..cf1b6062ba8c 100644 --- a/sound/soc/codecs/max98090.h +++ b/sound/soc/codecs/max98090.h @@ -1524,6 +1524,7 @@ struct max98090_priv { struct snd_soc_codec *codec; enum max98090_type devtype; struct max98090_pdata *pdata; + struct clk *mclk; unsigned int sysclk; unsigned int bclk; unsigned int lrclk; -- cgit v1.2.3