summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/soc/tegra/tegra_rt5640.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c
index 6ca6f76c84aa..231b0ee61308 100644
--- a/sound/soc/tegra/tegra_rt5640.c
+++ b/sound/soc/tegra/tegra_rt5640.c
@@ -69,6 +69,8 @@ struct tegra_rt5640 {
#ifdef CONFIG_SWITCH
int jack_status;
#endif
+ enum snd_soc_bias_level bias_level;
+ volatile int clock_enabled;
};
static int tegra_rt5640_hw_params(struct snd_pcm_substream *substream,
@@ -532,6 +534,9 @@ static int tegra_rt5640_init(struct snd_soc_pcm_runtime *rtd)
machine->gpio_requested |= GPIO_HP_DET;
}
+ machine->bias_level = SND_SOC_BIAS_STANDBY;
+ machine->clock_enabled = 1;
+
ret = snd_soc_add_controls(codec, cardhu_controls,
ARRAY_SIZE(cardhu_controls));
if (ret < 0)
@@ -596,12 +601,44 @@ static int tegra_rt5640_resume_pre(struct snd_soc_card *card)
return 0;
}
+static int tegra_rt5640_set_bias_level(struct snd_soc_card *card,
+ struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
+{
+ struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card);
+
+ if (machine->bias_level == SND_SOC_BIAS_OFF &&
+ level != SND_SOC_BIAS_OFF && (!machine->clock_enabled)) {
+ machine->clock_enabled = 1;
+ tegra_asoc_utils_clk_enable(&machine->util_data);
+ machine->bias_level = level;
+ }
+
+ return 0;
+}
+
+static int tegra_rt5640_set_bias_level_post(struct snd_soc_card *card,
+ struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
+{
+ struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card);
+
+ if (machine->bias_level != SND_SOC_BIAS_OFF &&
+ level == SND_SOC_BIAS_OFF && machine->clock_enabled) {
+ machine->clock_enabled = 0;
+ tegra_asoc_utils_clk_disable(&machine->util_data);
+ }
+
+ machine->bias_level = level;
+
+ return 0 ;
+}
static struct snd_soc_card snd_soc_tegra_rt5640 = {
.name = "tegra-rt5640",
.dai_link = tegra_rt5640_dai,
.num_links = ARRAY_SIZE(tegra_rt5640_dai),
.resume_pre = tegra_rt5640_resume_pre,
+ .set_bias_level = tegra_rt5640_set_bias_level,
+ .set_bias_level_post = tegra_rt5640_set_bias_level_post,
};
static __devinit int tegra_rt5640_driver_probe(struct platform_device *pdev)
@@ -659,7 +696,7 @@ static __devinit int tegra_rt5640_driver_probe(struct platform_device *pdev)
card->dev = &pdev->dev;
platform_set_drvdata(pdev, card);
snd_soc_card_set_drvdata(card, machine);
-
+ card->dapm.idle_bias_off = 1;
ret = snd_soc_register_card(card);
if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",