aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Brown2012-05-12 12:35:44 +0100
committerMark Brown2012-05-12 12:54:06 +0100
commit68a02db415d13f2fde571b131deb91de67719a27 (patch)
tree80ce8a7c7efeb5c1622272c40b309746d5868eb7
parente968194b45c4e8077dada75c5bae5660b37628fe (diff)
ASoC: littlemill: Use a widget to keep track of AIF2 clocking
Since we only need to clock AIF2 when it's actively in use start up the FLL for it using a supply widget which supplies AIF2CLK. This both makes the sequencing more robust and ensures we minimise power consumption. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/samsung/littlemill.c86
1 files changed, 53 insertions, 33 deletions
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c
index fd5ac47371a1..c82c646b8a08 100644
--- a/sound/soc/samsung/littlemill.c
+++ b/sound/soc/samsung/littlemill.c
@@ -67,7 +67,6 @@ static int littlemill_set_bias_level_post(struct snd_soc_card *card,
enum snd_soc_bias_level level)
{
struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai;
- struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai;
int ret;
if (dapm->dev != aif1_dai->dev)
@@ -75,20 +74,6 @@ static int littlemill_set_bias_level_post(struct snd_soc_card *card,
switch (level) {
case SND_SOC_BIAS_STANDBY:
- ret = snd_soc_dai_set_sysclk(aif2_dai, WM8994_SYSCLK_MCLK2,
- 32768, SND_SOC_CLOCK_IN);
- if (ret < 0) {
- pr_err("Failed to switch away from FLL2: %d\n", ret);
- return ret;
- }
-
- ret = snd_soc_dai_set_pll(aif2_dai, WM8994_FLL2,
- 0, 0, 0);
- if (ret < 0) {
- pr_err("Failed to stop FLL2: %d\n", ret);
- return ret;
- }
-
ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2,
32768, SND_SOC_CLOCK_IN);
if (ret < 0) {
@@ -104,24 +89,6 @@ static int littlemill_set_bias_level_post(struct snd_soc_card *card,
}
break;
- case SND_SOC_BIAS_PREPARE:
- ret = snd_soc_dai_set_pll(aif2_dai, WM8994_FLL2,
- WM8994_FLL_SRC_BCLK, 64 * 8000,
- 8000 * 256);
- if (ret < 0) {
- pr_err("Failed to start FLL: %d\n", ret);
- return ret;
- }
-
- ret = snd_soc_dai_set_sysclk(aif2_dai, WM8994_SYSCLK_FLL2,
- 8000 * 256,
- SND_SOC_CLOCK_IN);
- if (ret < 0) {
- pr_err("Failed to set SYSCLK: %d\n", ret);
- return ret;
- }
- break;
-
default:
break;
}
@@ -197,11 +164,62 @@ static struct snd_soc_dai_link littlemill_dai[] = {
},
};
+static int bbclk_ev(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_card *card = w->dapm->card;
+ struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai;
+ int ret;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ ret = snd_soc_dai_set_pll(aif2_dai, WM8994_FLL2,
+ WM8994_FLL_SRC_BCLK, 64 * 8000,
+ 8000 * 256);
+ if (ret < 0) {
+ pr_err("Failed to start FLL: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_sysclk(aif2_dai, WM8994_SYSCLK_FLL2,
+ 8000 * 256,
+ SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ pr_err("Failed to set SYSCLK: %d\n", ret);
+ return ret;
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ ret = snd_soc_dai_set_sysclk(aif2_dai, WM8994_SYSCLK_MCLK2,
+ 32768, SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ pr_err("Failed to switch away from FLL2: %d\n", ret);
+ return ret;
+ }
+
+ ret = snd_soc_dai_set_pll(aif2_dai, WM8994_FLL2,
+ 0, 0, 0);
+ if (ret < 0) {
+ pr_err("Failed to stop FLL2: %d\n", ret);
+ return ret;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static struct snd_soc_dapm_widget widgets[] = {
SND_SOC_DAPM_HP("Headphone", NULL),
SND_SOC_DAPM_MIC("AMIC", NULL),
SND_SOC_DAPM_MIC("DMIC", NULL),
+
+ SND_SOC_DAPM_SUPPLY_S("Baseband Clock", -1, SND_SOC_NOPM, 0, 0,
+ bbclk_ev,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
};
static struct snd_soc_dapm_route audio_paths[] = {
@@ -214,6 +232,8 @@ static struct snd_soc_dapm_route audio_paths[] = {
{ "DMIC", NULL, "MICBIAS2" }, /* Default for DMICBIAS jumper */
{ "DMIC1DAT", NULL, "DMIC" },
{ "DMIC2DAT", NULL, "DMIC" },
+
+ { "AIF2CLK", NULL, "Baseband Clock" },
};
static struct snd_soc_jack littlemill_headset;