summaryrefslogtreecommitdiff
path: root/sound/soc/ux500/ux500_ab5500.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/ux500/ux500_ab5500.c')
-rwxr-xr-x[-rw-r--r--]sound/soc/ux500/ux500_ab5500.c74
1 files changed, 72 insertions, 2 deletions
diff --git a/sound/soc/ux500/ux500_ab5500.c b/sound/soc/ux500/ux500_ab5500.c
index 6dbf72e9153..3a1dab0a990 100644..100755
--- a/sound/soc/ux500/ux500_ab5500.c
+++ b/sound/soc/ux500/ux500_ab5500.c
@@ -13,17 +13,69 @@
*/
#include <sound/soc.h>
+#include <linux/clk.h>
#include "../codecs/ab5500.h"
#include "ux500_msp_dai.h"
-int ux500_ab5500_startup(struct snd_pcm_substream *substream)
+/* For a workwround purpose we enable sysclk
+ by default this will be changed later */
+static unsigned int sysclk_state = 1;/* Enabled */
+static struct clk *ux500_ab5500_sysclk;
+
+static int sysclk_input_select_control_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 1;
+ return 0;
+}
+
+static int sysclk_input_select_control_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
{
+ ucontrol->value.integer.value[0] = sysclk_state;
return 0;
}
+static int sysclk_input_select_control_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ sysclk_state = ucontrol->value.integer.value[0];
+ return 0;
+}
+
+static const struct snd_kcontrol_new sysclk_input_select_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Sysclk Input Select",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = sysclk_input_select_control_info,
+ .get = sysclk_input_select_control_get,
+ .put = sysclk_input_select_control_put
+};
+
+int ux500_ab5500_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ int ret = 0;
+
+ if (sysclk_state == 1) {
+ ret = clk_enable(ux500_ab5500_sysclk);
+ if (ret)
+ dev_err(codec->dev, "failed to enable clock %d\n", ret);
+ }
+
+ return ret;
+}
+
void ux500_ab5500_shutdown(struct snd_pcm_substream *substream)
{
- printk(KERN_DEBUG "%s: Enter.\n", __func__);
+ pr_info("%s: Enter.\n", __func__);
+ if (sysclk_state == 1)
+ clk_disable(ux500_ab5500_sysclk);
}
int ux500_ab5500_hw_params(struct snd_pcm_substream *substream,
@@ -60,3 +112,21 @@ int ux500_ab5500_hw_params(struct snd_pcm_substream *substream,
return ret;
}
+
+int ux500_ab5500_machine_codec_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_codec *codec = rtd->codec;
+ int ret = 0;
+
+ snd_ctl_add(codec->card->snd_card,
+ snd_ctl_new1(&sysclk_input_select_control, codec));
+
+ ux500_ab5500_sysclk = clk_get(codec->dev, "sysclk");
+ if (IS_ERR(ux500_ab5500_sysclk)) {
+ dev_err(codec->dev, "could not get sysclk %ld\n",
+ PTR_ERR(ux500_ab5500_sysclk));
+ ret = PTR_ERR(ux500_ab5500_sysclk);
+ }
+
+ return ret;
+}