summaryrefslogtreecommitdiff
path: root/sound/soc/tegra/tegra_wm8903.c
diff options
context:
space:
mode:
authorScottPeterson <speterson@nvidia.com>2012-01-17 17:32:11 -0800
committerVarun Colbert <vcolbert@nvidia.com>2012-01-30 13:28:18 -0800
commit2e3c724c167ec5da8b1ed5ab07cda55232ecdf13 (patch)
treed82c4c6da45dd46de1aa0c75393869470fe033e3 /sound/soc/tegra/tegra_wm8903.c
parent6814bf677b18c10cee192e813d3d468b01229a25 (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.c60
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)