diff options
author | Rahul Mittal <rmittal@nvidia.com> | 2013-02-27 15:25:30 +0530 |
---|---|---|
committer | Mandar Padmawar <mpadmawar@nvidia.com> | 2013-03-06 00:46:08 -0800 |
commit | 04ef9a3374c361821390deaeca9b94a3b7181366 (patch) | |
tree | a94ad59a31b2b89005170171af00af7d1ebd2588 /sound | |
parent | e833ce3a44d057638d157103b6bf76b13558033d (diff) |
asoc: tegra: aic326x: Fix DAM allocation for BT voice call
Added a check to not allocate call record DAMs if it is a BT call
BT call requires 2 DAMs, and since we have only 3 DAMs,
we can't allocate the 2 DAMs that are needed for call recording
Fixed system sound mixing during BT call
Bug 1242683
Change-Id: I515ac5627c9221ada5a6d4491d6a37ad38c3196f
Signed-off-by: Rahul Mittal <rmittal@nvidia.com>
Reviewed-on: http://git-master/r/204524
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Vijay Mali <vmali@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Scott Peterson <speterson@nvidia.com>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/tegra/tegra_aic326x.c | 71 |
1 files changed, 59 insertions, 12 deletions
diff --git a/sound/soc/tegra/tegra_aic326x.c b/sound/soc/tegra/tegra_aic326x.c index 50631cb65119..9a52382f1b5d 100644 --- a/sound/soc/tegra/tegra_aic326x.c +++ b/sound/soc/tegra/tegra_aic326x.c @@ -530,24 +530,51 @@ static int tegra_aic326x_startup(struct snd_pcm_substream *substream) return 0; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - /* - *make apbif tx to i2s rx connection if this is the only client - *using i2s for playback - */ - if (i2s->playback_ref_count == 1) { + if (i2s->id == machine->codec_info[BT_SCO].i2s_id) { + /*dam configuration*/ + if (!i2s->dam_ch_refcount) + i2s->dam_ifc = + tegra30_dam_allocate_controller(); + if (i2s->dam_ifc < 0) + return i2s->dam_ifc; + tegra30_dam_allocate_channel(i2s->dam_ifc, + TEGRA30_DAM_CHIN1); + i2s->dam_ch_refcount++; + tegra30_dam_enable_clock(i2s->dam_ifc); + tegra30_ahub_set_rx_cif_source( - TEGRA30_AHUB_RXCIF_I2S0_RX0 + i2s->id, - i2s->txcif); + TEGRA30_AHUB_RXCIF_DAM0_RX1 + (i2s->dam_ifc*2), + i2s->txcif); + + /* make the dam tx to i2s rx connection if this is + * the only client using i2s for playback */ + if (i2s->playback_ref_count == 1) + tegra30_ahub_set_rx_cif_source( + TEGRA30_AHUB_RXCIF_I2S0_RX0 + i2s->id, + TEGRA30_AHUB_TXCIF_DAM0_TX0 + i2s->dam_ifc); + + /* enable the dam*/ + tegra30_dam_enable(i2s->dam_ifc, TEGRA30_DAM_ENABLE, + TEGRA30_DAM_CHIN1); + } else { + /* make apbif tx to i2s rx connection if this is + * the only client using i2s for playback */ + if (i2s->playback_ref_count == 1) { + tegra30_ahub_set_rx_cif_source( + TEGRA30_AHUB_RXCIF_I2S0_RX0 + i2s->id, + i2s->txcif); tegra30_ahub_enable_clocks(); + } } - } else { i2s->is_call_mode_rec = machine->is_call_mode; if (!i2s->is_call_mode_rec) return 0; - if (machine->is_device_bt) - codec_index = BT_SCO; + if (machine->is_device_bt) { + i2s->is_call_mode_rec = 0; + return 0; + } else codec_index = VOICE_CODEC; @@ -641,14 +668,34 @@ static void tegra_aic326x_shutdown(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai); + struct tegra_aic326x *machine = snd_soc_card_get_drvdata(rtd->card); if (!i2s->is_dam_used) return; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - tegra30_ahub_unset_rx_cif_source( + if (i2s->id == machine->codec_info[BT_SCO].i2s_id) { + /* disable the dam*/ + tegra30_dam_enable(i2s->dam_ifc, TEGRA30_DAM_DISABLE, + TEGRA30_DAM_CHIN1); + + /* disconnect the ahub connections*/ + tegra30_ahub_unset_rx_cif_source( + TEGRA30_AHUB_RXCIF_DAM0_RX1 + (i2s->dam_ifc*2)); + + /* disable the dam and free the controller */ + tegra30_dam_disable_clock(i2s->dam_ifc); + tegra30_dam_free_channel(i2s->dam_ifc, + TEGRA30_DAM_CHIN1); + i2s->dam_ch_refcount--; + if (!i2s->dam_ch_refcount) + tegra30_dam_free_controller(i2s->dam_ifc); + + } else { + tegra30_ahub_unset_rx_cif_source( TEGRA30_AHUB_RXCIF_I2S0_RX0 + i2s->id); - tegra30_ahub_disable_clocks(); + tegra30_ahub_disable_clocks(); + } } else { if (!i2s->is_call_mode_rec) return; |