diff options
author | Manoj Gangwal <mgangwal@nvidia.com> | 2012-04-30 20:59:19 +0530 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-05-01 14:32:48 -0700 |
commit | 7f7ea77ef60a0fc4b02b7a23388ba42b11e2a774 (patch) | |
tree | 9e140361afcd0a0ea08b0a1d4ab8d5f9ce83a8a1 | |
parent | 9349cedf17f9b3c10760c8d48f831473f87a3a15 (diff) |
asoc: tegra: ALC5640 machine: Add support for setting bias level
Allow setting bias level to turn off clock extern1 when codec
is idle.
Bug 964287
Reviewed on: http://git-master/r/#change,93950
Change-Id: Icc11e8bfb359b432f0bfd9ba214877259188de2b
Signed-off-by: Manoj Gangwal <mgangwal@nvidia.com>
Reviewed-on: http://git-master/r/99659
Reviewed-by: Automatic_Commit_Validation_User
Tested-by: Hunk Lin <hulin@nvidia.com>
Reviewed-by: Scott Peterson <speterson@nvidia.com>
-rw-r--r-- | sound/soc/tegra/tegra_rt5640.c | 39 |
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", |