aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOla Lilja <elilola@steludxu2785.(none)>2011-04-21 15:28:39 +0200
committerOla LILJA2 <ola.o.lilja@stericsson.com>2011-04-21 15:48:03 +0200
commitcbe7e71af8a8b68acb650f06874c0b4feed7817f (patch)
tree1abce14d6fc10de4999802ee690388820c8a459c
parent8fd63b94c44be823a9d9b1df41e4463046b3aba8 (diff)
Ux500 ASoC: Added reference counter for sysclku5500-android-2.3_v0.51
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>
-rw-r--r--sound/soc/codecs/ab8500_audio.c84
1 files changed, 42 insertions, 42 deletions
diff --git a/sound/soc/codecs/ab8500_audio.c b/sound/soc/codecs/ab8500_audio.c
index 4b651be2ac2..a958388d947 100644
--- a/sound/soc/codecs/ab8500_audio.c
+++ b/sound/soc/codecs/ab8500_audio.c
@@ -171,7 +171,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.
*/
@@ -1792,13 +1792,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__);
@@ -1806,44 +1808,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,
@@ -1851,10 +1830,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);
}
@@ -2100,7 +2082,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);
@@ -2208,9 +2190,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)