diff options
author | Ola Lilja <elilola@steludxu2785.(none)> | 2011-04-21 15:28:39 +0200 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@stericsson.com> | 2011-12-06 10:59:33 +0100 |
commit | a415e24e18a7567b4332aece55fa729c479fced6 (patch) | |
tree | 7adbaeb1b65f0f0ebaa06181f38536a1e2bf6f1e /sound | |
parent | 58f8fc271d6a2e7ddddbb15565a4e6f1c47f5b8f (diff) |
Ux500 ASoC: Added reference counter for sysclk
A reference counter is added for enable/disable of sysclk
to be able to handle playback and capture combinations.
Change-Id: Ia28d3b94f3b54561cc990aa51fa5a0bf99319656
Signed-off-by: Ola Lilja <ola.o.lilja@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/21385
Reviewed-by: Roger NILSSON1 <roger.xr.nilsson@stericsson.com>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/ab8500_audio.c | 84 |
1 files changed, 42 insertions, 42 deletions
diff --git a/sound/soc/codecs/ab8500_audio.c b/sound/soc/codecs/ab8500_audio.c index 974a1031822..9070e2dcd6d 100644 --- a/sound/soc/codecs/ab8500_audio.c +++ b/sound/soc/codecs/ab8500_audio.c @@ -174,7 +174,7 @@ static const u8 ab8500_reg_cache[AB8500_CACHEREGNUM] = { static struct snd_soc_codec *ab8500_codec; static struct clk *clk_ptr_audioclk; static struct clk *clk_ptr_sysclk; -static bool clock_on; +static int sysclk_on; /* Reads an arbitrary register from the ab8500 chip. */ @@ -1736,13 +1736,15 @@ static int ab8500_codec_pcm_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { pr_debug("%s Enter.\n", __func__); + + return 0; } static int ab8500_codec_pcm_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - int error = 0; + int ret = 0; pr_debug("%s Enter.\n", __func__); @@ -1750,44 +1752,21 @@ static int ab8500_codec_pcm_prepare(struct snd_pcm_substream *substream, ab8500_codec_read_reg_audio(dai->codec, REG_AUDINTSOURCE1); ab8500_codec_read_reg_audio(dai->codec, REG_AUDINTSOURCE2); - if (clock_on) - return 0; + sysclk_on++; + pr_debug("sysclk_on changed from %d to %d", sysclk_on-1, sysclk_on); - clk_ptr_sysclk = clk_get(dai->codec->dev, "sysclk"); - if (IS_ERR(clk_ptr_sysclk)) { - error = -EFAULT; - dev_err(dai->codec->dev, - "Sysclk get failed error = %d", error); - return error; - } - clk_ptr_audioclk = clk_get(dai->codec->dev, "audioclk"); - if (IS_ERR(clk_ptr_audioclk)) { - error = -EFAULT; - dev_err(dai->codec->dev, - "Audioclk get failed error = %d", error); - goto free_sysclk; - } - error = clk_set_parent(clk_ptr_audioclk, clk_ptr_sysclk); - if (error) { - pr_err("Setting Sysclk as parent failed error = %d", error); - return error; - } + if (sysclk_on > 1) + return 0; - error = clk_enable(clk_ptr_audioclk); - if (error) { - pr_err("Audioclk enable failed error = %d", error); - return error; + ret = clk_enable(clk_ptr_audioclk); + if (ret) { + pr_err("ERROR: clk_enable failed (ret = %d)!", ret); + sysclk_on = 0; + return ret; } - clock_on = true; - - return error; - -free_sysclk: - clk_put(clk_ptr_sysclk); + pr_debug("sysclk enabled."); - clock_on = false; - - return error; + return ret; } static void ab8500_codec_pcm_shutdown(struct snd_pcm_substream *substream, @@ -1795,10 +1774,13 @@ static void ab8500_codec_pcm_shutdown(struct snd_pcm_substream *substream, { pr_debug("%s Enter.\n", __func__); - clk_disable(clk_ptr_sysclk); - clk_put(clk_ptr_sysclk); + sysclk_on--; + pr_debug("sysclk_on changed from %d to %d", sysclk_on+1, sysclk_on); - clock_on = false; + if (sysclk_on == 0) { + clk_disable(clk_ptr_audioclk); + pr_debug("sysclk disabled."); + } ab8500_codec_dump_all_reg(dai->codec); } @@ -2044,7 +2026,7 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai, REG_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD); break; case 8: - pr_info("%s: In 8-channel mode AD-to-slot mapping is set manually.", __func__); + pr_debug("%s: In 8-channel mode AD-to-slot mapping is set manually.", __func__); break; default: pr_err("%s: Unsupported number of active RX-slots (%d)!\n", __func__, slots_active); @@ -2159,9 +2141,27 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec) } ab8500_codec = codec; - clock_on = false; - return 0; + sysclk_on = 0; + clk_ptr_sysclk = clk_get(codec->dev, "sysclk"); + if (IS_ERR(clk_ptr_sysclk)) { + pr_err("ERROR: clk_get failed (ret = %d)!", -EFAULT); + return -EFAULT; + } + clk_ptr_audioclk = clk_get(codec->dev, "audioclk"); + if (IS_ERR(clk_ptr_audioclk)) { + pr_err("ERROR: clk_get failed (ret = %d)!", -EFAULT); + clk_put(clk_ptr_sysclk); + return -EFAULT; + } + ret = clk_set_parent(clk_ptr_audioclk, clk_ptr_sysclk); + if (ret) { + pr_err("ERROR: clk_set_parent failed (ret = %d)!", ret); + clk_put(clk_ptr_sysclk); + return ret; + } + + return ret; } static int ab8500_codec_remove(struct snd_soc_codec *codec) |