diff options
author | ScottPeterson <speterson@nvidia.com> | 2012-01-17 17:32:11 -0800 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2012-01-30 13:28:18 -0800 |
commit | 2e3c724c167ec5da8b1ed5ab07cda55232ecdf13 (patch) | |
tree | d82c4c6da45dd46de1aa0c75393869470fe033e3 /sound/soc/tegra/tegra_wm8903.c | |
parent | 6814bf677b18c10cee192e813d3d468b01229a25 (diff) |
asoc:tegra: Support I2S slave mode
Support I2S slave mode. Disable pll_p_out1 and
pll_a to reduce power when in slave mode.
Slave mode disabled by default.
Reviewed-on: http://git-master/r/76046
Change-Id: I873a11d54f1e037d99c86ff4cec06ee83064902a
Signed-off-by: ScottPeterson <speterson@nvidia.com>
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Reviewed-on: http://git-master/r/77765
Reviewed-by: Automatic_Commit_Validation_User
Diffstat (limited to 'sound/soc/tegra/tegra_wm8903.c')
-rw-r--r-- | sound/soc/tegra/tegra_wm8903.c | 60 |
1 files changed, 57 insertions, 3 deletions
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index bdd355574066..80b05dcd654c 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -30,6 +30,7 @@ #include <asm/mach-types.h> +#include <linux/clk.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/slab.h> @@ -73,6 +74,7 @@ struct tegra_wm8903 { #ifdef CONFIG_SWITCH int jack_status; #endif + enum snd_soc_bias_level bias_level; }; static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream, @@ -86,6 +88,8 @@ static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream, struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); int srate, mclk, i2s_daifmt; int err; + struct clk *clk_m; + int rate; srate = params_rate(params); switch (srate) { @@ -98,10 +102,33 @@ static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream, mclk = 256 * srate; break; } + + + + clk_m = clk_get_sys(NULL, "clk_m"); + if (IS_ERR(clk_m)) { + dev_err(card->dev, "Can't retrieve clk clk_m\n"); + err = PTR_ERR(clk_m); + return err; + } + rate = clk_get_rate(clk_m); + printk("extern1 rate=%d\n",rate); + +#if TEGRA30_I2S_MASTER_PLAYBACK /* FIXME: Codec only requires >= 3MHz if OSR==0 */ while (mclk < 6000000) mclk *= 2; + i2s_daifmt = SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS; +#else + mclk = rate; + + i2s_daifmt = SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM; +#endif + + err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { if (!(machine->util_data.set_mclk % mclk)) @@ -114,9 +141,6 @@ static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream, tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1); - i2s_daifmt = SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS; - /* Use DSP mode for mono on Tegra20 */ if ((params_channels(params) != 2) && (machine_is_ventana() || machine_is_harmony() || @@ -557,6 +581,8 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) struct tegra_wm8903_platform_data *pdata = machine->pdata; int ret; + machine->bias_level = SND_SOC_BIAS_STANDBY; + if (gpio_is_valid(pdata->gpio_spkr_en)) { ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); if (ret) { @@ -664,6 +690,32 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) return 0; } +static int tegra30_soc_set_bias_level(struct snd_soc_card *card, + enum snd_soc_bias_level level) +{ + struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); + + if (machine->bias_level == SND_SOC_BIAS_OFF && + level != SND_SOC_BIAS_OFF) + tegra_asoc_utils_clk_enable(&machine->util_data); + + return 0; +} + +static int tegra30_soc_set_bias_level_post(struct snd_soc_card *card, + enum snd_soc_bias_level level) +{ + struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); + + if (machine->bias_level != SND_SOC_BIAS_OFF && + level == SND_SOC_BIAS_OFF) + tegra_asoc_utils_clk_disable(&machine->util_data); + + machine->bias_level = level; + + return 0 ; +} + static struct snd_soc_dai_link tegra_wm8903_dai[] = { { .name = "WM8903", @@ -699,6 +751,8 @@ static struct snd_soc_card snd_soc_tegra_wm8903 = { .name = "tegra-wm8903", .dai_link = tegra_wm8903_dai, .num_links = ARRAY_SIZE(tegra_wm8903_dai), + //.set_bias_level = tegra30_soc_set_bias_level, + //.set_bias_level_post = tegra30_soc_set_bias_level_post, }; static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) |