aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorOla Lilja <elilola@steludxu2785.(none)>2011-04-21 11:49:23 +0200
committerJonas ABERG <jonas.aberg@stericsson.com>2011-04-21 12:11:56 +0200
commit2dc2254326f05af37ec1dcaf2e3f72f2b8b3b32b (patch)
treea563718504a5e64ebd3567d8585bf231fb98f9c7 /sound
parent663714fca17e15a6643eca160ff52de4fe8610a1 (diff)
Ux500 ASoC: Take sysclk during audio-playback
Change-Id: Iad133756a33d6f15f78806a29d9d3653e918578f Signed-off-by: Ola Lilja <ola.o.lilja@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/21325 Reviewed-by: Roger NILSSON1 <roger.xr.nilsson@stericsson.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/ab8500_audio.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/sound/soc/codecs/ab8500_audio.c b/sound/soc/codecs/ab8500_audio.c
index 64354df91b9..4b651be2ac2 100644
--- a/sound/soc/codecs/ab8500_audio.c
+++ b/sound/soc/codecs/ab8500_audio.c
@@ -14,6 +14,7 @@
* by the Free Software Foundation.
*/
+#include <linux/clk.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/moduleparam.h>
@@ -168,6 +169,9 @@ 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;
/* Reads an arbitrary register from the ab8500 chip.
*/
@@ -1794,26 +1798,72 @@ static int ab8500_codec_pcm_startup(struct snd_pcm_substream *substream,
static int ab8500_codec_pcm_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
+ int error = 0;
+
pr_debug("%s Enter.\n", __func__);
/* Clear interrupt status registers by reading them. */
ab8500_codec_read_reg_audio(dai->codec, REG_AUDINTSOURCE1);
ab8500_codec_read_reg_audio(dai->codec, REG_AUDINTSOURCE2);
- return 0;
+ if (clock_on)
+ return 0;
+
+ 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;
+ }
+
+ error = clk_enable(clk_ptr_audioclk);
+ if (error) {
+ pr_err("Audioclk enable failed error = %d", error);
+ return error;
+ }
+ clock_on = true;
+
+ return error;
+
+free_sysclk:
+ clk_put(clk_ptr_sysclk);
+
+ clock_on = false;
+
+ return error;
}
static void ab8500_codec_pcm_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
pr_debug("%s Enter.\n", __func__);
+
+ clk_disable(clk_ptr_sysclk);
+ clk_put(clk_ptr_sysclk);
+
+ clock_on = false;
+
ab8500_codec_dump_all_reg(dai->codec);
}
static int ab8500_codec_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
unsigned int freq, int dir)
{
- pr_debug("%s Enter.\n", __func__);
+ pr_err("%s Enter.\n", __func__);
+
return 0;
}
@@ -2158,6 +2208,7 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
}
ab8500_codec = codec;
+ clock_on = false;
return 0;
}