summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRavindra Lokhande <rlokhande@nvidia.com>2011-01-12 17:20:38 +0530
committerBharat Nihalani <bnihalani@nvidia.com>2011-01-12 21:51:38 -0800
commit1503bf380cf05df14cf477245ee21228d75dbff9 (patch)
tree4e8e5933d14ffcddf57ebbf9632047df6244d5fc
parent6b27d35c0ccb5193691282feef2e1d5abfdd1ce2 (diff)
[tegra ALSA] separated codec and control code
- separated codec and control code - codec specific code is added to tegra_soc_xxx - alsa controls code added to tegra_soc_controls Fixes bug 759167 Change-Id: Ib8cd19364b3d4a0cb726d20b4eb1a7fab4017bf1 Reviewed-on: http://git-master/r/15637 Tested-by: Ravindra Lokhande <rlokhande@nvidia.com> Reviewed-by: Sachin Nikam <snikam@nvidia.com> Reviewed-by: Scott Peterson <speterson@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
-rw-r--r--sound/soc/tegra/Makefile9
-rw-r--r--sound/soc/tegra/tegra_soc.h3
-rw-r--r--sound/soc/tegra/tegra_soc_controls.c (renamed from sound/soc/tegra/tegra_soc.c)277
-rw-r--r--sound/soc/tegra/tegra_soc_wm8903.c227
4 files changed, 271 insertions, 245 deletions
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index b1bc3d02109c..afd353f62f9e 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -1,6 +1,7 @@
-ccflags-y += -DNV_DEBUG=0
-obj-$(CONFIG_TEGRA_PCM) += tegra_pcm.o
-obj-$(CONFIG_TEGRA_I2S) += tegra_i2s.o
-obj-$(CONFIG_TEGRA_ALSA) += tegra_soc.o
+ccflags-y += -DNV_DEBUG=0
+obj-$(CONFIG_TEGRA_PCM) += tegra_pcm.o
+obj-$(CONFIG_TEGRA_I2S) += tegra_i2s.o
+obj-$(CONFIG_TEGRA_ALSA) += tegra_soc_controls.o
+obj-${CONFIG_SND_SOC_WM8903} += tegra_soc_wm8903.o
diff --git a/sound/soc/tegra/tegra_soc.h b/sound/soc/tegra/tegra_soc.h
index 5aeedc9fd0d4..c9ef76acebc0 100644
--- a/sound/soc/tegra/tegra_soc.h
+++ b/sound/soc/tegra/tegra_soc.h
@@ -106,4 +106,7 @@ struct tegra_audio_data {
bool is_call_mode;
};
+int tegra_controls_init(struct snd_soc_codec *codec);
+void tegra_controls_exit(void);
+
#endif
diff --git a/sound/soc/tegra/tegra_soc.c b/sound/soc/tegra/tegra_soc_controls.c
index afb3d1c761a2..a090740a3f7d 100644
--- a/sound/soc/tegra/tegra_soc.c
+++ b/sound/soc/tegra/tegra_soc_controls.c
@@ -1,25 +1,27 @@
/*
- * tegra_soc.c -- SoC audio for tegra
+ * tegra_soc_controls.c -- alsa controls for tegra SoC
*
- * (c) 2010 Nvidia Graphics Pvt. Ltd.
- * http://www.nvidia.com
+ * Copyright (c) 2010, NVIDIA Corporation.
*
- * Copyright 2007 Wolfson Microelectronics PLC.
- * Author: Graeme Gregory
- * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
*
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
#include "tegra_soc.h"
#include <mach/audio.h>
-#include "../codecs/wm8903.h"
-static struct platform_device *tegra_snd_device;
static struct tegra_audio_data *audio_data;
static int tegra_jack_func;
static int tegra_spk_func;
@@ -32,38 +34,6 @@ static int tegra_spk_func;
#define TEGRA_SPK_ON 0
#define TEGRA_SPK_OFF 1
-/* codec register values */
-#define B07_INEMUTE 7
-#define B06_VOL_M3DB 6
-#define B00_IN_VOL 0
-#define B00_INR_ENA 0
-#define B01_INL_ENA 1
-#define R06_MICBIAS_CTRL_0 6
-#define B07_MICDET_HYST_ENA 7
-#define B04_MICDET_THR 4
-#define B02_MICSHORT_THR 2
-#define B01_MICDET_ENA 1
-#define B00_MICBIAS_ENA 0
-#define B15_DRC_ENA 15
-#define B03_DACL_ENA 3
-#define B02_DACR_ENA 2
-#define B01_ADCL_ENA 1
-#define B00_ADCR_ENA 0
-#define B06_IN_CM_ENA 6
-#define B04_IP_SEL_N 4
-#define B02_IP_SEL_P 2
-#define B00_MODE 0
-#define B06_AIF_ADCL 7
-#define B06_AIF_ADCR 6
-#define B05_ADC_HPF_CUT 5
-#define B04_ADC_HPF_ENA 4
-#define B01_ADCL_DATINV 1
-#define B00_ADCR_DATINV 0
-#define R20_SIDETONE_CTRL 32
-#define R29_DRC_1 41
-#define SET_REG_VAL(r,m,l,v) (((r)&(~((m)<<(l))))|(((v)&(m))<<(l)))
-
-
static void tegra_ext_control(struct snd_soc_codec *codec)
{
/* set up jack connection */
@@ -105,109 +75,6 @@ static void tegra_ext_control(struct snd_soc_codec *codec)
snd_soc_dapm_sync(codec);
}
-static int tegra_hifi_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
- int err;
- struct snd_soc_codec *codec = codec_dai->codec;
- int CtrlReg = 0;
- int VolumeCtrlReg = 0;
- int SidetoneCtrlReg = 0;
- int SideToneAtenuation = 0;
-
- err = snd_soc_dai_set_fmt(codec_dai,
- SND_SOC_DAIFMT_I2S | \
- SND_SOC_DAIFMT_NB_NF | \
- SND_SOC_DAIFMT_CBS_CFS);
- if (err < 0) {
- printk(KERN_ERR "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);
- if (err < 0) {
- printk(KERN_ERR "cpu_dai fmt not set \n");
- return err;
- }
- err = snd_soc_dai_set_sysclk(codec_dai, 0, I2S_CLK, SND_SOC_CLOCK_IN);
-
- if (err<0) {
- printk(KERN_ERR "codec_dai clock not set\n");
- return err;
- }
- err = snd_soc_dai_set_sysclk(cpu_dai, 0, I2S_CLK, SND_SOC_CLOCK_IN);
-
- if (err<0) {
- printk(KERN_ERR "cpu_dai clock not set\n");
- return err;
- }
-
- if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) {
- snd_soc_write(codec, WM8903_ANALOGUE_LEFT_INPUT_0, 0X7);
- snd_soc_write(codec, WM8903_ANALOGUE_RIGHT_INPUT_0, 0X7);
- // Mic Bias enable
- CtrlReg = (0x1<<B00_MICBIAS_ENA) | (0x1<<B01_MICDET_ENA);
- snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0, CtrlReg);
- // Enable DRC
- CtrlReg = snd_soc_read(codec, WM8903_DRC_0);
- CtrlReg |= (1<<B15_DRC_ENA);
- snd_soc_write(codec, WM8903_DRC_0, CtrlReg);
- // Single Ended Mic
- CtrlReg = (0x0<<B06_IN_CM_ENA) |
- (0x0<<B00_MODE) | (0x0<<B04_IP_SEL_N)
- | (0x1<<B02_IP_SEL_P);
- VolumeCtrlReg = (0x5 << B00_IN_VOL);
- // Mic Setting
- snd_soc_write(codec, WM8903_ANALOGUE_LEFT_INPUT_1, CtrlReg);
- snd_soc_write(codec, WM8903_ANALOGUE_RIGHT_INPUT_1, CtrlReg);
- // voulme for single ended mic
- snd_soc_write(codec, WM8903_ANALOGUE_LEFT_INPUT_0,
- VolumeCtrlReg);
- snd_soc_write(codec, WM8903_ANALOGUE_RIGHT_INPUT_0,
- VolumeCtrlReg);
- // replicate mic setting on both channels
- CtrlReg = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_0);
- CtrlReg = SET_REG_VAL(CtrlReg, 0x1, B06_AIF_ADCR, 0x0);
- CtrlReg = SET_REG_VAL(CtrlReg, 0x1, B06_AIF_ADCL, 0x0);
- snd_soc_write(codec, WM8903_AUDIO_INTERFACE_0, CtrlReg);
- // Enable analog inputs
- CtrlReg = (0x1<<B01_INL_ENA) | (0x1<<B00_INR_ENA);
- snd_soc_write(codec, WM8903_POWER_MANAGEMENT_0, CtrlReg);
- // ADC Settings
- CtrlReg = snd_soc_read(codec, WM8903_ADC_DIGITAL_0);
- CtrlReg |= (0x1<<B04_ADC_HPF_ENA);
- snd_soc_write(codec, WM8903_ADC_DIGITAL_0, CtrlReg);
- SidetoneCtrlReg = 0;
- snd_soc_write(codec, R20_SIDETONE_CTRL, SidetoneCtrlReg);
- // Enable ADC
- CtrlReg = snd_soc_read(codec, WM8903_POWER_MANAGEMENT_6);
- CtrlReg |= (0x1<<B00_ADCR_ENA)|(0x1<<B01_ADCL_ENA);
- snd_soc_write(codec, WM8903_POWER_MANAGEMENT_6, CtrlReg);
- // Enable Sidetone
- SidetoneCtrlReg = (0x1<<2) | (0x2<<0);
- SideToneAtenuation = 12 ; // sidetone 0 db
- SidetoneCtrlReg |= (SideToneAtenuation<<8)
- | (SideToneAtenuation<<4);
- snd_soc_write(codec, R20_SIDETONE_CTRL, SidetoneCtrlReg);
- CtrlReg = snd_soc_read(codec, R29_DRC_1);
- CtrlReg |= 0x3; //mic volume 18 db
- snd_soc_write(codec, R29_DRC_1, CtrlReg);
- }
-
- return 0;
-}
-
-static struct snd_soc_ops tegra_hifi_ops = {
- .hw_params = tegra_hifi_hw_params,
-};
-
-
static int tegra_get_jack(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -250,7 +117,7 @@ static int tegra_set_spk(struct snd_kcontrol *kcontrol,
}
/*tegra machine dapm widgets */
-static const struct snd_soc_dapm_widget wm8903_dapm_widgets[] = {
+static const struct snd_soc_dapm_widget tegra_dapm_widgets[] = {
SND_SOC_DAPM_HP("Headphone Jack", NULL),
SND_SOC_DAPM_MIC("Mic Jack", NULL),
SND_SOC_DAPM_SPK("Ext Spk", NULL),
@@ -286,7 +153,7 @@ static const struct soc_enum tegra_enum[] = {
SOC_ENUM_SINGLE_EXT(2, spk_function),
};
-static const struct snd_kcontrol_new wm8903_tegra_controls[] = {
+static const struct snd_kcontrol_new tegra_controls[] = {
SOC_ENUM_EXT("Jack Function", tegra_enum[0], tegra_get_jack,
tegra_set_jack),
SOC_ENUM_EXT("Speaker Function", tegra_enum[1], tegra_get_spk,
@@ -408,8 +275,7 @@ static int tegra_play_route_put(struct snd_kcontrol *kcontrol,
return -EINVAL;
}
-struct snd_kcontrol_new tegra_play_route_control =
-{
+struct snd_kcontrol_new tegra_play_route_control = {
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Pcm Playback Route",
@@ -458,8 +324,7 @@ static int tegra_capture_route_put(struct snd_kcontrol *kcontrol,
return -EINVAL;
}
-struct snd_kcontrol_new tegra_capture_route_control =
-{
+struct snd_kcontrol_new tegra_capture_route_control = {
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Pcm Capture Route",
@@ -508,8 +373,7 @@ static int tegra_call_mode_put(struct snd_kcontrol *kcontrol,
return -EINVAL;
}
-struct snd_kcontrol_new tegra_call_mode_control =
-{
+struct snd_kcontrol_new tegra_call_mode_control = {
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Call Mode Switch",
@@ -519,19 +383,25 @@ struct snd_kcontrol_new tegra_call_mode_control =
.put = tegra_call_mode_put
};
-static int tegra_codec_init(struct snd_soc_codec *codec)
+int tegra_controls_init(struct snd_soc_codec *codec)
{
int err;
+ audio_data = kzalloc(sizeof(*audio_data), GFP_KERNEL);
+ if (!audio_data) {
+ pr_err("failed to allocate tegra_audio_data \n");
+ return -ENOMEM;
+ }
+
/* Add tegra specific controls */
- err = snd_soc_add_controls(codec, wm8903_tegra_controls,
- ARRAY_SIZE(wm8903_tegra_controls));
+ err = snd_soc_add_controls(codec, tegra_controls,
+ ARRAY_SIZE(tegra_controls));
if (err < 0)
- return err;
+ goto fail;
/* Add tegra specific widgets */
- snd_soc_dapm_new_controls(codec, wm8903_dapm_widgets,
- ARRAY_SIZE(wm8903_dapm_widgets));
+ snd_soc_dapm_new_controls(codec, tegra_dapm_widgets,
+ ARRAY_SIZE(tegra_dapm_widgets));
/* Set up tegra specific audio path audio_map */
snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
@@ -541,19 +411,19 @@ static int tegra_codec_init(struct snd_soc_codec *codec)
err = snd_ctl_add(codec->card,
snd_ctl_new1(&tegra_play_route_control, NULL));
if (err < 0)
- return err;
+ goto fail;
/* Add capture route control */
err = snd_ctl_add(codec->card,
snd_ctl_new1(&tegra_capture_route_control, NULL));
if (err < 0)
- return err;
+ goto fail;
/* Add call mode switch control */
err = snd_ctl_add(codec->card,
snd_ctl_new1(&tegra_call_mode_control, NULL));
if (err < 0)
- return err;
+ goto fail;
/* Default to HP output */
tegra_jack_func = TEGRA_HP;
@@ -563,93 +433,18 @@ static int tegra_codec_init(struct snd_soc_codec *codec)
snd_soc_dapm_sync(codec);
return 0;
-}
-
-extern struct snd_soc_dai tegra_i2s_dai;
-extern struct snd_soc_platform tegra_soc_platform;
-
-static struct snd_soc_dai_link tegra_soc_dai = {
- .name = "WM8903",
- .stream_name = "WM8903 HiFi",
- .cpu_dai = &tegra_i2s_dai,
- .codec_dai = &wm8903_dai,
- .init = tegra_codec_init,
- .ops = &tegra_hifi_ops,
-};
-
-static struct snd_soc_card tegra_snd_soc = {
- .name = "tegra",
- .platform = &tegra_soc_platform,
- .dai_link = &tegra_soc_dai,
- .num_links = 1,
-};
-
-struct tegra_setup_data {
- int i2c_bus;
- unsigned short i2c_address;
-};
-
-static struct snd_soc_device tegra_snd_devdata = {
- .card = &tegra_snd_soc,
- .codec_dev = &soc_codec_dev_wm8903,
-};
-
-static int __init tegra_init(void)
-{
- int ret = 0;
- struct tegra_setup_data tegra_setup;
-
- tegra_snd_device = platform_device_alloc("soc-audio", -1);
- if (!tegra_snd_device) {
- pr_err("failed to allocate soc-audio \n");
- ret = -ENOMEM;
- goto fail;
- }
-
- audio_data = kzalloc(sizeof(*audio_data), GFP_KERNEL);
- if (!audio_data) {
- pr_err("failed to allocate tegra_audio_data \n");
- ret = -ENOMEM;
- goto fail;
- }
-
- memset(&tegra_setup,0,sizeof(struct tegra_setup_data));
- platform_set_drvdata(tegra_snd_device, &tegra_snd_devdata);
- tegra_snd_devdata.dev = &tegra_snd_device->dev;
- ret = platform_device_add(tegra_snd_device);
- if (ret) {
- pr_err("audio device could not be added \n");
- goto fail;
- }
-
- return 0;
-
fail:
if (audio_data) {
kfree(audio_data);
audio_data = 0;
}
-
- if (tegra_snd_device) {
- platform_device_put(tegra_snd_device);
- tegra_snd_device = 0;
- }
-
- return ret;
+ return err;
}
-static void __exit tegra_exit(void)
+void tegra_controls_exit(void)
{
if (audio_data) {
kfree(audio_data);
audio_data = 0;
}
- platform_device_unregister(tegra_snd_device);
}
-
-module_init(tegra_init);
-module_exit(tegra_exit);
-
-/* Module information */
-MODULE_DESCRIPTION("Tegra ALSA SoC");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/tegra/tegra_soc_wm8903.c b/sound/soc/tegra/tegra_soc_wm8903.c
new file mode 100644
index 000000000000..80d85f985fdf
--- /dev/null
+++ b/sound/soc/tegra/tegra_soc_wm8903.c
@@ -0,0 +1,227 @@
+/*
+ * tegra_soc_wm8903.c -- SoC audio for tegra
+ *
+ * (c) 2010 Nvidia Graphics Pvt. Ltd.
+ * http://www.nvidia.com
+ *
+ * Copyright 2007 Wolfson Microelectronics PLC.
+ * Author: Graeme Gregory
+ * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include "tegra_soc.h"
+#include "../codecs/wm8903.h"
+
+static struct platform_device *tegra_snd_device;
+
+extern struct snd_soc_dai tegra_i2s_dai;
+extern struct snd_soc_platform tegra_soc_platform;
+
+/* codec register values */
+#define B07_INEMUTE 7
+#define B06_VOL_M3DB 6
+#define B00_IN_VOL 0
+#define B00_INR_ENA 0
+#define B01_INL_ENA 1
+#define R06_MICBIAS_CTRL_0 6
+#define B07_MICDET_HYST_ENA 7
+#define B04_MICDET_THR 4
+#define B02_MICSHORT_THR 2
+#define B01_MICDET_ENA 1
+#define B00_MICBIAS_ENA 0
+#define B15_DRC_ENA 15
+#define B03_DACL_ENA 3
+#define B02_DACR_ENA 2
+#define B01_ADCL_ENA 1
+#define B00_ADCR_ENA 0
+#define B06_IN_CM_ENA 6
+#define B04_IP_SEL_N 4
+#define B02_IP_SEL_P 2
+#define B00_MODE 0
+#define B06_AIF_ADCL 7
+#define B06_AIF_ADCR 6
+#define B05_ADC_HPF_CUT 5
+#define B04_ADC_HPF_ENA 4
+#define B01_ADCL_DATINV 1
+#define B00_ADCR_DATINV 0
+#define R20_SIDETONE_CTRL 32
+#define R29_DRC_1 41
+#define SET_REG_VAL(r,m,l,v) (((r)&(~((m)<<(l))))|(((v)&(m))<<(l)))
+
+
+static int tegra_hifi_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ int err;
+ struct snd_soc_codec *codec = codec_dai->codec;
+ int CtrlReg = 0;
+ int VolumeCtrlReg = 0;
+ int SidetoneCtrlReg = 0;
+ int SideToneAtenuation = 0;
+
+ err = snd_soc_dai_set_fmt(codec_dai,
+ SND_SOC_DAIFMT_I2S | \
+ SND_SOC_DAIFMT_NB_NF | \
+ SND_SOC_DAIFMT_CBS_CFS);
+ if (err < 0) {
+ printk(KERN_ERR "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);
+ if (err < 0) {
+ printk(KERN_ERR "cpu_dai fmt not set \n");
+ return err;
+ }
+
+ err = snd_soc_dai_set_sysclk(codec_dai, 0, I2S_CLK, SND_SOC_CLOCK_IN);
+ if (err < 0) {
+ printk(KERN_ERR "codec_dai clock not set\n");
+ return err;
+ }
+
+ err = snd_soc_dai_set_sysclk(cpu_dai, 0, I2S_CLK, SND_SOC_CLOCK_IN);
+ if (err < 0) {
+ printk(KERN_ERR "cpu_dai clock not set\n");
+ return err;
+ }
+
+ if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) {
+ snd_soc_write(codec, WM8903_ANALOGUE_LEFT_INPUT_0, 0X7);
+ snd_soc_write(codec, WM8903_ANALOGUE_RIGHT_INPUT_0, 0X7);
+ // Mic Bias enable
+ CtrlReg = (0x1<<B00_MICBIAS_ENA) | (0x1<<B01_MICDET_ENA);
+ snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0, CtrlReg);
+ // Enable DRC
+ CtrlReg = snd_soc_read(codec, WM8903_DRC_0);
+ CtrlReg |= (1<<B15_DRC_ENA);
+ snd_soc_write(codec, WM8903_DRC_0, CtrlReg);
+ // Single Ended Mic
+ CtrlReg = (0x0<<B06_IN_CM_ENA) |
+ (0x0<<B00_MODE) | (0x0<<B04_IP_SEL_N)
+ | (0x1<<B02_IP_SEL_P);
+ VolumeCtrlReg = (0x5 << B00_IN_VOL);
+ // Mic Setting
+ snd_soc_write(codec, WM8903_ANALOGUE_LEFT_INPUT_1, CtrlReg);
+ snd_soc_write(codec, WM8903_ANALOGUE_RIGHT_INPUT_1, CtrlReg);
+ // voulme for single ended mic
+ snd_soc_write(codec, WM8903_ANALOGUE_LEFT_INPUT_0,
+ VolumeCtrlReg);
+ snd_soc_write(codec, WM8903_ANALOGUE_RIGHT_INPUT_0,
+ VolumeCtrlReg);
+ // replicate mic setting on both channels
+ CtrlReg = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_0);
+ CtrlReg = SET_REG_VAL(CtrlReg, 0x1, B06_AIF_ADCR, 0x0);
+ CtrlReg = SET_REG_VAL(CtrlReg, 0x1, B06_AIF_ADCL, 0x0);
+ snd_soc_write(codec, WM8903_AUDIO_INTERFACE_0, CtrlReg);
+ // Enable analog inputs
+ CtrlReg = (0x1<<B01_INL_ENA) | (0x1<<B00_INR_ENA);
+ snd_soc_write(codec, WM8903_POWER_MANAGEMENT_0, CtrlReg);
+ // ADC Settings
+ CtrlReg = snd_soc_read(codec, WM8903_ADC_DIGITAL_0);
+ CtrlReg |= (0x1<<B04_ADC_HPF_ENA);
+ snd_soc_write(codec, WM8903_ADC_DIGITAL_0, CtrlReg);
+ SidetoneCtrlReg = 0;
+ snd_soc_write(codec, R20_SIDETONE_CTRL, SidetoneCtrlReg);
+ // Enable ADC
+ CtrlReg = snd_soc_read(codec, WM8903_POWER_MANAGEMENT_6);
+ CtrlReg |= (0x1<<B00_ADCR_ENA)|(0x1<<B01_ADCL_ENA);
+ snd_soc_write(codec, WM8903_POWER_MANAGEMENT_6, CtrlReg);
+ // Enable Sidetone
+ SidetoneCtrlReg = (0x1<<2) | (0x2<<0);
+ SideToneAtenuation = 12 ; // sidetone 0 db
+ SidetoneCtrlReg |= (SideToneAtenuation<<8)
+ | (SideToneAtenuation<<4);
+ snd_soc_write(codec, R20_SIDETONE_CTRL, SidetoneCtrlReg);
+ CtrlReg = snd_soc_read(codec, R29_DRC_1);
+ CtrlReg |= 0x3; //mic volume 18 db
+ snd_soc_write(codec, R29_DRC_1, CtrlReg);
+ }
+
+ return 0;
+}
+
+static struct snd_soc_ops tegra_hifi_ops = {
+ .hw_params = tegra_hifi_hw_params,
+};
+
+static int tegra_codec_init(struct snd_soc_codec *codec)
+{
+ return tegra_controls_init(codec);
+}
+
+
+static struct snd_soc_dai_link tegra_soc_dai = {
+ .name = "WM8903",
+ .stream_name = "WM8903 HiFi",
+ .cpu_dai = &tegra_i2s_dai,
+ .codec_dai = &wm8903_dai,
+ .init = tegra_codec_init,
+ .ops = &tegra_hifi_ops,
+};
+
+static struct snd_soc_card tegra_snd_soc = {
+ .name = "tegra",
+ .platform = &tegra_soc_platform,
+ .dai_link = &tegra_soc_dai,
+ .num_links = 1,
+};
+
+static struct snd_soc_device tegra_snd_devdata = {
+ .card = &tegra_snd_soc,
+ .codec_dev = &soc_codec_dev_wm8903,
+};
+
+static int __init tegra_init(void)
+{
+ int ret = 0;
+
+ tegra_snd_device = platform_device_alloc("soc-audio", -1);
+ if (!tegra_snd_device) {
+ pr_err("failed to allocate soc-audio \n");
+ return ENOMEM;
+ }
+
+ platform_set_drvdata(tegra_snd_device, &tegra_snd_devdata);
+ tegra_snd_devdata.dev = &tegra_snd_device->dev;
+ ret = platform_device_add(tegra_snd_device);
+ if (ret) {
+ pr_err("audio device could not be added \n");
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ if (tegra_snd_device) {
+ platform_device_put(tegra_snd_device);
+ tegra_snd_device = 0;
+ }
+
+ return ret;
+}
+
+static void __exit tegra_exit(void)
+{
+ tegra_controls_exit();
+ platform_device_unregister(tegra_snd_device);
+}
+
+module_init(tegra_init);
+module_exit(tegra_exit);
+
+/* Module information */
+MODULE_DESCRIPTION("Tegra ALSA SoC");
+MODULE_LICENSE("GPL");