summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorDara Ramesh <dramesh@nvidia.com>2011-05-03 19:33:31 +0530
committerVarun Colbert <vcolbert@nvidia.com>2011-05-05 14:31:15 -0700
commit4dad57c5a8b3c1695ff437c443692bfa12111e8f (patch)
tree578d55a37138a622c151db85807a3ccc8be24928 /sound
parentfdefc174936fec8ef0c6e471f6bcb7d8518544e2 (diff)
arm: tegra: Add support for I2S Loopback
Added the control code to enable/disable I2S Loopback accordingly. Bug 725009 Change-Id: I3f172ef303dd4c6ac5bc41277e13e5405234a77e Reviewed-on: http://git-master/r/30221 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/tegra/tegra_i2s.c7
-rw-r--r--sound/soc/tegra/tegra_soc.h2
-rw-r--r--sound/soc/tegra/tegra_soc_controls.c45
3 files changed, 54 insertions, 0 deletions
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c
index 83dc452f000c..e4dc4e3c8c19 100644
--- a/sound/soc/tegra/tegra_i2s.c
+++ b/sound/soc/tegra/tegra_i2s.c
@@ -32,6 +32,8 @@ struct tegra_i2s_info {
struct das_regs_cache das_regs;
};
+extern int tegra_i2sloopback_func;
+
void free_i2s_dma_request(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -154,6 +156,11 @@ static int tegra_i2s_hw_params(struct snd_pcm_substream *substream,
}
i2s_set_bit_size(i2s_id, val);
+ if (tegra_i2sloopback_func == TEGRA_INT_I2SLOOPBACK_ON)
+ i2s_set_loopback(i2s_id,1);
+ else
+ i2s_set_loopback(i2s_id,0);
+
switch (params_rate(params)) {
case 8000:
case 32000:
diff --git a/sound/soc/tegra/tegra_soc.h b/sound/soc/tegra/tegra_soc.h
index 53366d33b090..4b839e33bf0e 100644
--- a/sound/soc/tegra/tegra_soc.h
+++ b/sound/soc/tegra/tegra_soc.h
@@ -70,6 +70,8 @@
#define I2S1_CLK 11289600
#define I2S2_CLK 2000000
#define TEGRA_DEFAULT_SR 44100
+#define TEGRA_INT_I2SLOOPBACK_ON 1
+#define TEGRA_INT_I2SLOOPBACK_OFF 0
#define TEGRA_SAMPLE_RATES (SNDRV_PCM_RATE_8000_96000)
#define TEGRA_VOICE_SAMPLE_RATES SNDRV_PCM_RATE_8000
diff --git a/sound/soc/tegra/tegra_soc_controls.c b/sound/soc/tegra/tegra_soc_controls.c
index c430703f4bd4..90e8679d4dec 100644
--- a/sound/soc/tegra/tegra_soc_controls.c
+++ b/sound/soc/tegra/tegra_soc_controls.c
@@ -20,6 +20,8 @@
#include "tegra_soc.h"
+int tegra_i2sloopback_func = TEGRA_INT_I2SLOOPBACK_OFF;
+
static void tegra_audio_route(struct tegra_audio_data* audio_data,
int device_new, int is_call_mode_new)
{
@@ -260,6 +262,43 @@ struct snd_kcontrol_new tegra_call_mode_control = {
.put = tegra_call_mode_put
};
+static int tegra_i2s_loopback_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 1;
+ return 0;
+}
+
+static int tegra_i2s_loopback_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = tegra_i2sloopback_func;
+ return 0;
+}
+
+static int tegra_i2s_loopback_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ if (tegra_i2sloopback_func == ucontrol->value.integer.value[0])
+ return 0;
+
+ tegra_i2sloopback_func = ucontrol->value.integer.value[0];
+ return 1;
+}
+
+struct snd_kcontrol_new tegra_i2s_loopback_control = {
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "I2S loopback",
+ .private_value = 0xffff,
+ .info = tegra_i2s_loopback_info,
+ .get = tegra_i2s_loopback_get,
+ .put = tegra_i2s_loopback_put
+};
+
int tegra_controls_init(struct snd_soc_codec *codec)
{
struct tegra_audio_data* audio_data = codec->socdev->codec_data;
@@ -283,5 +322,11 @@ int tegra_controls_init(struct snd_soc_codec *codec)
if (err < 0)
return err;
+ /* Add I2S loopback control */
+ err = snd_ctl_add(codec->card,
+ snd_ctl_new1(&tegra_i2s_loopback_control, audio_data));
+ if (err < 0)
+ return err;
+
return 0;
}