diff options
author | Manoj Gangwal <mgangwal@nvidia.com> | 2014-02-28 18:24:23 +0530 |
---|---|---|
committer | Bharat Nihalani <bnihalani@nvidia.com> | 2014-03-09 20:58:30 -0700 |
commit | c560b5509e0cfc7d35a0a50217e76afc553893f4 (patch) | |
tree | 68f0d70f3e3d04e40bdef7f75af7ed7dc1a1da42 /sound | |
parent | d69b1ecadad2f3954ca7c5708ea23153c4b95074 (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.c | 10 | ||||
-rw-r--r-- | sound/soc/tegra/tegra30_i2s.c | 72 |
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 */ |