summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorvijay mali <vmali@nvidia.com>2010-11-03 15:56:00 +0530
committerBharat Nihalani <bnihalani@nvidia.com>2010-11-16 03:34:46 -0800
commit05d829ac1d6a8429a61b56cef3a1adfb50168c4e (patch)
tree7986f5f389d0680ac7f37cbac696c35efcb7b2fc /sound
parentabb56df6ff6c5fa4e252c1955f49c4dd65daec55 (diff)
[tegra ALSA] Fix for no audio in recording
Added audio codec settings for volume, sidetone, ADC for both left and right channels. Fixed dma source and destination addresses which were set exactly in opposite direction. With this change, valid audio data is received in recorded buffers. Change-Id: I7ab33600812fafad6f390310d756fac15db84ea8 Reviewed-on: http://git-master/r/10945 Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Tested-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/tegra/tegra_pcm.c6
-rw-r--r--sound/soc/tegra/tegra_soc.c93
2 files changed, 94 insertions, 5 deletions
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index 3cdff93a4678..6ec095d6a3a8 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -121,13 +121,13 @@ static void tegra_pcm_capture(struct tegra_runtime_data *prtd)
if (runtime->dma_addr) {
prtd->size = frames_to_bytes(runtime, runtime->period_size);
if (reqid == 0) {
- prtd->dma_req1.source_addr = buf->addr +
+ prtd->dma_req1.dest_addr = buf->addr +
+ frames_to_bytes(runtime,prtd->dma_pos);
prtd->dma_req1.size = prtd->size;
tegra_dma_enqueue_req(prtd->dma_chan, &prtd->dma_req1);
reqid = 1;
} else {
- prtd->dma_req2.source_addr = buf->addr +
+ prtd->dma_req2.dest_addr = buf->addr +
+ frames_to_bytes(runtime,prtd->dma_pos);
prtd->dma_req2.size = prtd->size;
tegra_dma_enqueue_req(prtd->dma_chan, &prtd->dma_req2);
@@ -161,7 +161,7 @@ static void setup_dma_rx_request(struct tegra_dma_req *req)
memset(req, 0, sizeof(*req));
req->complete = dma_rx_complete_callback;
req->to_memory = true;
- req->dest_addr = i2s_get_fifo_phy_base(I2S_IFC, I2S_FIFO_RX);
+ req->source_addr = i2s_get_fifo_phy_base(I2S_IFC, I2S_FIFO_RX);
req->dest_wrap = 0;
req->source_bus_width = 32;
req->source_wrap = 4;
diff --git a/sound/soc/tegra/tegra_soc.c b/sound/soc/tegra/tegra_soc.c
index 4d8d24c40d6a..306a31138733 100644
--- a/sound/soc/tegra/tegra_soc.c
+++ b/sound/soc/tegra/tegra_soc.c
@@ -31,13 +31,45 @@ 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 */
switch (tegra_jack_func) {
case TEGRA_HP:
/* set = unmute headphone */
- snd_soc_dapm_disable_pin(codec, "Mic Jack");
+ snd_soc_dapm_enable_pin(codec, "Mic Jack");
snd_soc_dapm_disable_pin(codec, "Line Jack");
snd_soc_dapm_enable_pin(codec, "Headphone Jack");
snd_soc_dapm_disable_pin(codec, "Headset Jack");
@@ -79,6 +111,11 @@ static int tegra_hifi_hw_params(struct snd_pcm_substream *substream,
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 | \
@@ -106,10 +143,62 @@ static int tegra_hifi_hw_params(struct snd_pcm_substream *substream,
err = snd_soc_dai_set_sysclk(cpu_dai, 0, I2S_CLK, SND_SOC_CLOCK_IN);
if (err<0) {
- printk(KERN_ERR "codec_dai clock not set\n");
+ 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;
}