summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorManoj Gangwal <mgangwal@nvidia.com>2014-02-28 18:24:23 +0530
committerBharat Nihalani <bnihalani@nvidia.com>2014-03-09 20:58:30 -0700
commitc560b5509e0cfc7d35a0a50217e76afc553893f4 (patch)
tree68f0d70f3e3d04e40bdef7f75af7ed7dc1a1da42 /sound
parentd69b1ecadad2f3954ca7c5708ea23153c4b95074 (diff)
Asoc: tegra: Fix audio mixing issue
There is hardware issue in t114 & t124 DAM. It does not handle mixing and down sampling simultaneously. This a work around to use 2 DAM for doing SRC and mixing separately. Bug 1461763 Change-Id: Ib9d728b0c2eba7a9c243d499cf2a0fb160e318e5 Signed-off-by: Manoj Gangwal <mgangwal@nvidia.com> Reviewed-on: http://git-master/r/376019 (cherry picked from commit b91b1fb99f16a9855703cb33a13e48753d7ec35d) Reviewed-on: http://git-master/r/378210 Reviewed-by: Sumit Bhattacharya <sumitb@nvidia.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/tegra/tegra30_dam.c10
-rw-r--r--sound/soc/tegra/tegra30_i2s.c72
2 files changed, 57 insertions, 25 deletions
diff --git a/sound/soc/tegra/tegra30_dam.c b/sound/soc/tegra/tegra30_dam.c
index 123044262cc7..66d1f7b098ba 100644
--- a/sound/soc/tegra/tegra30_dam.c
+++ b/sound/soc/tegra/tegra30_dam.c
@@ -3,7 +3,7 @@
*
* Author: Nikesh Oswal <noswal@nvidia.com>
* Copyright (C) 2011 - NVIDIA, Inc.
- * Copyright (C) 2012-2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2012-2014, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -654,10 +654,12 @@ static void tegra30_dam_write_coeff_ram(struct tegra30_dam_context *dam, int fsi
tegra30_dam_writel(dam, 0x00005000,
TEGRA30_DAM_AUDIORAMCTL_DAM_CTRL_0);
- for (i = 0; i < 64; i++) {
- val = coefRam[i];
- tegra30_dam_writel(dam, val,
+ if (coefRam) {
+ for (i = 0; i < 64; i++) {
+ val = coefRam[i];
+ tegra30_dam_writel(dam, val,
TEGRA30_DAM_AUDIORAMCTL_DAM_DATA_0);
+ }
}
}
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index 02d596b7d2e2..d6705bb0abd3 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -1704,7 +1704,8 @@ int tegra30_make_voice_call_connections(struct codec_config *codec_info,
en_flwcntrl = 1;
}
} else {
- /*configure codec dam*/
+
+ /*configure dam for system sound*/
ret = configure_dam(codec_i2s, codec_info->channels,
codec_info->rate, codec_info->bitsize,
bb_info->channels, 48000,
@@ -1713,42 +1714,57 @@ int tegra30_make_voice_call_connections(struct codec_config *codec_info,
if (ret)
pr_info("%s:Failed to configure dam\n", __func__);
- ret = tegra30_dam_allocate_channel(codec_i2s->dam_ifc,
+ /*configure codec dam*/
+ ret = configure_dam(bb_i2s, bb_info->channels,
+ bb_info->rate, bb_info->bitsize,
+ codec_info->channels, codec_info->rate,
+ codec_info->bitsize);
+
+ if (ret)
+ pr_info("%s:Failed to configure dam\n", __func__);
+
+ ret = tegra30_dam_allocate_channel(bb_i2s->dam_ifc,
TEGRA30_DAM_CHIN1);
if (ret)
pr_info("%s:Failed to allocate dam\n", __func__);
- tegra30_dam_set_gain(codec_i2s->dam_ifc,
+ tegra30_dam_set_gain(bb_i2s->dam_ifc,
TEGRA30_DAM_CHIN1, 0x1000);
- tegra30_dam_set_acif(codec_i2s->dam_ifc, TEGRA30_DAM_CHIN1, 1,
+ tegra30_dam_set_acif(bb_i2s->dam_ifc, TEGRA30_DAM_CHIN1, 1,
bb_info->bitsize, 1, 32);
- tegra30_dam_set_acif(codec_i2s->dam_ifc, TEGRA30_DAM_CHOUT,
+ tegra30_dam_set_acif(bb_i2s->dam_ifc, TEGRA30_DAM_CHOUT,
2, codec_info->bitsize, 1, 32);
- tegra30_dam_ch0_set_datasync(codec_i2s->dam_ifc, 2);
- tegra30_dam_ch1_set_datasync(codec_i2s->dam_ifc, 0);
+ tegra30_dam_ch0_set_datasync(bb_i2s->dam_ifc, 2);
+ tegra30_dam_ch1_set_datasync(bb_i2s->dam_ifc, 0);
/* do routing in ahub */
tegra30_ahub_set_rx_cif_source(
- TEGRA30_AHUB_RXCIF_DAM0_RX1 + (codec_i2s->dam_ifc*2),
- TEGRA30_AHUB_TXCIF_I2S0_TX0 + bb_info->i2s_id);
+ TEGRA30_AHUB_RXCIF_DAM0_RX0 + (codec_i2s->dam_ifc*2),
+ codec_i2s->playback_fifo_cif);
tegra30_ahub_set_rx_cif_source(
- TEGRA30_AHUB_RXCIF_DAM0_RX0 + (codec_i2s->dam_ifc*2),
- codec_i2s->playback_fifo_cif);
+ TEGRA30_AHUB_RXCIF_DAM0_RX0 + (bb_i2s->dam_ifc*2),
+ TEGRA30_AHUB_TXCIF_DAM0_TX0 + codec_i2s->dam_ifc);
+
+ tegra30_ahub_set_rx_cif_source(
+ TEGRA30_AHUB_RXCIF_DAM0_RX1 + (bb_i2s->dam_ifc*2),
+ TEGRA30_AHUB_TXCIF_I2S0_TX0 + bb_info->i2s_id);
tegra30_ahub_set_rx_cif_source(
TEGRA30_AHUB_RXCIF_I2S0_RX0 + codec_info->i2s_id,
- TEGRA30_AHUB_TXCIF_DAM0_TX0 + codec_i2s->dam_ifc);
+ TEGRA30_AHUB_TXCIF_DAM0_TX0 + bb_i2s->dam_ifc);
tegra30_ahub_set_rx_cif_source(
TEGRA30_AHUB_RXCIF_I2S0_RX0 + bb_info->i2s_id,
TEGRA30_AHUB_TXCIF_I2S0_TX0 + codec_info->i2s_id);
/*enable dam and i2s*/
- tegra30_dam_enable(codec_i2s->dam_ifc, TEGRA30_DAM_ENABLE,
+ tegra30_dam_enable(bb_i2s->dam_ifc, TEGRA30_DAM_ENABLE,
TEGRA30_DAM_CHIN0_SRC);
- tegra30_dam_enable(codec_i2s->dam_ifc, TEGRA30_DAM_ENABLE,
+ tegra30_dam_enable(bb_i2s->dam_ifc, TEGRA30_DAM_ENABLE,
TEGRA30_DAM_CHIN1);
+ tegra30_dam_enable(codec_i2s->dam_ifc, TEGRA30_DAM_ENABLE,
+ TEGRA30_DAM_CHIN0_SRC);
}
val = TEGRA30_I2S_CTRL_XFER_EN_TX | TEGRA30_I2S_CTRL_XFER_EN_RX;
@@ -1825,24 +1841,37 @@ int tegra30_break_voice_call_connections(struct codec_config *codec_info,
} else {
/*Disable Codec DAM*/
- tegra30_dam_enable(codec_i2s->dam_ifc,
+ tegra30_dam_enable(bb_i2s->dam_ifc,
TEGRA30_DAM_DISABLE, TEGRA30_DAM_CHIN0_SRC);
- tegra30_dam_free_channel(codec_i2s->dam_ifc,
+ tegra30_dam_free_channel(bb_i2s->dam_ifc,
TEGRA30_DAM_CHIN0_SRC);
- tegra30_dam_enable(codec_i2s->dam_ifc,
+ tegra30_dam_enable(bb_i2s->dam_ifc,
TEGRA30_DAM_DISABLE, TEGRA30_DAM_CHIN1);
- tegra30_dam_free_channel(codec_i2s->dam_ifc,
+ tegra30_dam_free_channel(bb_i2s->dam_ifc,
TEGRA30_DAM_CHIN1);
+ tegra30_dam_enable(codec_i2s->dam_ifc,
+ TEGRA30_DAM_DISABLE, TEGRA30_DAM_CHIN0_SRC);
+ tegra30_dam_free_channel(codec_i2s->dam_ifc,
+ TEGRA30_DAM_CHIN0_SRC);
+
+ bb_i2s->dam_ch_refcount--;
codec_i2s->dam_ch_refcount--;
+
+ if (!bb_i2s->dam_ch_refcount)
+ tegra30_dam_free_controller(bb_i2s->dam_ifc);
+
if (!codec_i2s->dam_ch_refcount)
tegra30_dam_free_controller(codec_i2s->dam_ifc);
tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_I2S0_RX0
+ bb_info->i2s_id);
tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX1
- + (codec_i2s->dam_ifc*2));
+ + (bb_i2s->dam_ifc*2));
+
+ tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX0
+ + (bb_i2s->dam_ifc*2));
tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX0
+ (codec_i2s->dam_ifc*2));
@@ -1850,9 +1879,10 @@ int tegra30_break_voice_call_connections(struct codec_config *codec_info,
tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_I2S0_RX0 +
codec_info->i2s_id);
- tegra30_dam_ch0_set_datasync(codec_i2s->dam_ifc, 0);
- tegra30_dam_ch1_set_datasync(codec_i2s->dam_ifc, 0);
+ tegra30_dam_ch0_set_datasync(bb_i2s->dam_ifc, 0);
+ tegra30_dam_ch1_set_datasync(bb_i2s->dam_ifc, 0);
+ tegra30_dam_disable_clock(bb_i2s->dam_ifc);
tegra30_dam_disable_clock(codec_i2s->dam_ifc);
}
/* Decrement the codec and bb i2s playback ref count */