summaryrefslogtreecommitdiff
path: root/sound/soc/tegra/tegra_max98095.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/tegra/tegra_max98095.c')
-rw-r--r--sound/soc/tegra/tegra_max98095.c57
1 files changed, 44 insertions, 13 deletions
diff --git a/sound/soc/tegra/tegra_max98095.c b/sound/soc/tegra/tegra_max98095.c
index d065b78164ac..1d03980f276f 100644
--- a/sound/soc/tegra/tegra_max98095.c
+++ b/sound/soc/tegra/tegra_max98095.c
@@ -8,7 +8,7 @@
*
* Based on code copyright/by:
*
- * (c) 2010, 2011, 2012 Nvidia Graphics Pvt. Ltd.
+ * Copyright (c) 2010-12, NVIDIA CORPORATION. All rights reserved.
*
* Copyright 2007 Wolfson Microelectronics PLC.
* Author: Graeme Gregory
@@ -32,6 +32,7 @@
#include <asm/mach-types.h>
+#include <linux/clk.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
@@ -118,11 +119,12 @@ static int tegra_max98095_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_card *card = codec->card;
struct tegra_max98095 *machine = snd_soc_card_get_drvdata(card);
+ struct tegra_asoc_platform_data *pdata = machine->pdata;
#ifndef CONFIG_ARCH_TEGRA_2x_SOC
struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai);
#endif
- unsigned int srate, mclk, sample_size;
- int err;
+ unsigned int srate, mclk, sample_size, i2s_daifmt;
+ int err, rate;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
@@ -154,6 +156,31 @@ static int tegra_max98095_hw_params(struct snd_pcm_substream *substream,
break;
}
+ i2s_daifmt = SND_SOC_DAIFMT_NB_NF;
+ i2s_daifmt |= pdata->i2s_param[HIFI_CODEC].is_i2s_master ?
+ SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBM_CFM;
+
+ switch (pdata->i2s_param[HIFI_CODEC].i2s_mode) {
+ case TEGRA_DAIFMT_I2S :
+ i2s_daifmt |= SND_SOC_DAIFMT_I2S;
+ break;
+ case TEGRA_DAIFMT_DSP_A :
+ i2s_daifmt |= SND_SOC_DAIFMT_DSP_A;
+ break;
+ case TEGRA_DAIFMT_DSP_B :
+ i2s_daifmt |= SND_SOC_DAIFMT_DSP_B;
+ break;
+ case TEGRA_DAIFMT_LEFT_J :
+ i2s_daifmt |= SND_SOC_DAIFMT_LEFT_J;
+ break;
+ case TEGRA_DAIFMT_RIGHT_J :
+ i2s_daifmt |= SND_SOC_DAIFMT_RIGHT_J;
+ break;
+ default :
+ dev_err(card->dev, "Can't configure i2s format\n");
+ return -EINVAL;
+ }
+
err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
if (err < 0) {
if (!(machine->util_data.set_mclk % mclk))
@@ -166,26 +193,20 @@ static int tegra_max98095_hw_params(struct snd_pcm_substream *substream,
tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
- err = snd_soc_dai_set_fmt(codec_dai,
- SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS);
+ rate = clk_get_rate(machine->util_data.clk_cdev1);
+ err = snd_soc_dai_set_fmt(codec_dai, i2s_daifmt);
if (err < 0) {
dev_err(card->dev, "codec_dai fmt not set\n");
return err;
}
- err = snd_soc_dai_set_fmt(cpu_dai,
- SND_SOC_DAIFMT_I2S |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS);
+ err = snd_soc_dai_set_fmt(cpu_dai, i2s_daifmt);
if (err < 0) {
dev_err(card->dev, "cpu_dai fmt not set\n");
return err;
}
- err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
- SND_SOC_CLOCK_IN);
+ err = snd_soc_dai_set_sysclk(codec_dai, 0, rate, SND_SOC_CLOCK_IN);
if (err < 0) {
dev_err(card->dev, "codec_dai clock not set\n");
return err;
@@ -667,6 +688,16 @@ static __devinit int tegra_max98095_driver_probe(struct platform_device *pdev)
goto err_unregister_card;
}
+#ifndef CONFIG_ARCH_TEGRA_2x_SOC
+ ret = tegra_asoc_utils_set_parent(&machine->util_data,
+ pdata->i2s_param[HIFI_CODEC].is_i2s_master);
+ if (ret) {
+ dev_err(&pdev->dev, "tegra_asoc_utils_set_parent failed (%d)\n",
+ ret);
+ goto err_switch_unregister;
+ }
+#endif
+
return 0;
err_unregister_card: