diff options
author | Rahul Mittal <rmittal@nvidia.com> | 2013-03-06 19:57:29 +0530 |
---|---|---|
committer | Mandar Padmawar <mpadmawar@nvidia.com> | 2013-03-08 00:29:28 -0800 |
commit | dd93f497aa136e3c73398235922409dec3ab6539 (patch) | |
tree | 846986107c39b2b9ebed5d5b01754a317596ac55 /sound | |
parent | a80fd70068e579434426bf850806386e21fecfa6 (diff) |
asoc: tegra: aic326x: Add support for BT voice call recording
Added BT voice call recording support
Call recording works fine on BT and normal call switching
Bug 1247059
Change-Id: Ide4e0ed0b69485dd9d7f0a2877970b3fe04b1f38
Signed-off-by: Rahul Mittal <rmittal@nvidia.com>
Reviewed-on: http://git-master/r/206692
Reviewed-by: Mandar Padmawar <mpadmawar@nvidia.com>
Tested-by: Mandar Padmawar <mpadmawar@nvidia.com>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/tegra/tegra_aic326x.c | 192 |
1 files changed, 119 insertions, 73 deletions
diff --git a/sound/soc/tegra/tegra_aic326x.c b/sound/soc/tegra/tegra_aic326x.c index 9a52382f1b5d..54e7c8f09f5c 100644 --- a/sound/soc/tegra/tegra_aic326x.c +++ b/sound/soc/tegra/tegra_aic326x.c @@ -524,7 +524,6 @@ static int tegra_aic326x_startup(struct snd_pcm_substream *substream) struct codec_config *codec_info; struct codec_config *bb_info; struct codec_config *hifi_info; - int codec_index; if (!i2s->is_dam_used) return 0; @@ -571,14 +570,6 @@ static int tegra_aic326x_startup(struct snd_pcm_substream *substream) if (!i2s->is_call_mode_rec) return 0; - if (machine->is_device_bt) { - i2s->is_call_mode_rec = 0; - return 0; - } - else - codec_index = VOICE_CODEC; - - codec_info = &machine->codec_info[codec_index]; bb_info = &machine->codec_info[BASEBAND]; hifi_info = &machine->codec_info[HIFI_CODEC]; @@ -595,69 +586,124 @@ static int tegra_aic326x_startup(struct snd_pcm_substream *substream) TEGRA30_DAM_CHIN1); tegra30_dam_enable_clock(i2s->call_record_dam_ifc); - i2s->call_record_dam_ifc2 = tegra30_dam_allocate_controller(); + if (machine->is_device_bt) { + codec_info = &machine->codec_info[BT_SCO]; - if (i2s->call_record_dam_ifc2 < 0) - return i2s->call_record_dam_ifc2; + /* configure the dam */ + /* SRC bb rate to bt rate */ + tegra_aic326x_set_dam_cif(i2s->call_record_dam_ifc, + bb_info->rate, bb_info->channels, + bb_info->bitsize, 1, codec_info->rate, + codec_info->channels, codec_info->bitsize); - tegra30_dam_allocate_channel(i2s->call_record_dam_ifc2, - TEGRA30_DAM_CHIN0_SRC); - tegra30_dam_allocate_channel(i2s->call_record_dam_ifc2, - TEGRA30_DAM_CHIN1); - tegra30_dam_enable_clock(i2s->call_record_dam_ifc2); - - /* configure the dams */ - /* DAM0 SRC bb rate to hifi rate */ - tegra_aic326x_set_dam_cif(i2s->call_record_dam_ifc, - codec_info->rate, codec_info->channels, - codec_info->bitsize, 1, hifi_info->rate, - hifi_info->channels, hifi_info->bitsize); - /* DAM1 UL + DL Mix */ - tegra_aic326x_set_dam_cif(i2s->call_record_dam_ifc2, - codec_info->rate, codec_info->channels, - codec_info->bitsize, 1, bb_info->rate, - bb_info->channels, bb_info->bitsize); - - /* setup the connections for voice call record */ - tegra30_ahub_unset_rx_cif_source(i2s->rxcif); - tegra30_ahub_set_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX0 + - (i2s->call_record_dam_ifc2*2), - TEGRA30_AHUB_TXCIF_I2S0_TX0 + bb_info->i2s_id); - tegra30_ahub_set_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX1 + - (i2s->call_record_dam_ifc2*2), - TEGRA30_AHUB_TXCIF_I2S0_TX0 + codec_info->i2s_id); - tegra30_ahub_set_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX0 + - (i2s->call_record_dam_ifc*2), - TEGRA30_AHUB_TXCIF_DAM0_TX0 + - i2s->call_record_dam_ifc2); - tegra30_ahub_set_rx_cif_source(i2s->rxcif, + /* set ahub connections for bt call record*/ + tegra30_ahub_unset_rx_cif_source(i2s->rxcif); + + tegra30_ahub_set_rx_cif_source( + TEGRA30_AHUB_RXCIF_DAM0_RX0 + + (i2s->call_record_dam_ifc*2), + TEGRA30_AHUB_TXCIF_I2S0_TX0 + bb_info->i2s_id); + + tegra30_ahub_set_rx_cif_source( + TEGRA30_AHUB_RXCIF_DAM0_RX1 + + (i2s->call_record_dam_ifc*2), + TEGRA30_AHUB_TXCIF_I2S0_TX0 + codec_info->i2s_id); + + tegra30_ahub_set_rx_cif_source(i2s->rxcif, TEGRA30_AHUB_TXCIF_DAM0_TX0 + i2s->call_record_dam_ifc); + #ifndef CONFIG_ARCH_TEGRA_3x_SOC - /* Configure DAM0 for SRC */ - if (bb_info->rate != hifi_info->rate) { + /* Configure DAM for SRC */ + if (bb_info->rate != codec_info->rate) { tegra30_dam_write_coeff_ram(i2s->call_record_dam_ifc, - bb_info->rate, hifi_info->rate); + bb_info->rate, codec_info->rate); tegra30_dam_set_farrow_param(i2s->call_record_dam_ifc, - bb_info->rate, hifi_info->rate); + bb_info->rate, codec_info->rate); tegra30_dam_set_biquad_fixed_coef( i2s->call_record_dam_ifc); tegra30_dam_enable_coeff_ram(i2s->call_record_dam_ifc); tegra30_dam_set_filter_stages(i2s->call_record_dam_ifc, bb_info->rate, - hifi_info->rate); + codec_info->rate); } #endif - /* enable the dam */ - tegra30_dam_enable(i2s->call_record_dam_ifc, TEGRA30_DAM_ENABLE, - TEGRA30_DAM_CHIN1); - tegra30_dam_enable(i2s->call_record_dam_ifc, TEGRA30_DAM_ENABLE, + } else { + codec_info = &machine->codec_info[VOICE_CODEC]; + + i2s->call_record_dam_ifc2 = + tegra30_dam_allocate_controller(); + + if (i2s->call_record_dam_ifc2 < 0) + return i2s->call_record_dam_ifc2; + + tegra30_dam_allocate_channel(i2s->call_record_dam_ifc2, TEGRA30_DAM_CHIN0_SRC); - tegra30_dam_enable(i2s->call_record_dam_ifc2, + tegra30_dam_allocate_channel(i2s->call_record_dam_ifc2, + TEGRA30_DAM_CHIN1); + tegra30_dam_enable_clock(i2s->call_record_dam_ifc2); + + /* configure the dams */ + /* DAM0 SRC bb rate to hifi rate */ + tegra_aic326x_set_dam_cif(i2s->call_record_dam_ifc, + codec_info->rate, codec_info->channels, + codec_info->bitsize, 1, hifi_info->rate, + hifi_info->channels, hifi_info->bitsize); + /* DAM1 UL + DL Mix */ + tegra_aic326x_set_dam_cif(i2s->call_record_dam_ifc2, + codec_info->rate, codec_info->channels, + codec_info->bitsize, 1, bb_info->rate, + bb_info->channels, bb_info->bitsize); + + /* setup the connections for voice call record */ + tegra30_ahub_unset_rx_cif_source(i2s->rxcif); + tegra30_ahub_set_rx_cif_source( + TEGRA30_AHUB_RXCIF_DAM0_RX0 + + (i2s->call_record_dam_ifc2*2), + TEGRA30_AHUB_TXCIF_I2S0_TX0 + bb_info->i2s_id); + tegra30_ahub_set_rx_cif_source( + TEGRA30_AHUB_RXCIF_DAM0_RX1 + + (i2s->call_record_dam_ifc2*2), + TEGRA30_AHUB_TXCIF_I2S0_TX0 + codec_info->i2s_id); + tegra30_ahub_set_rx_cif_source( + TEGRA30_AHUB_RXCIF_DAM0_RX0 + + (i2s->call_record_dam_ifc*2), + TEGRA30_AHUB_TXCIF_DAM0_TX0 + + i2s->call_record_dam_ifc2); + tegra30_ahub_set_rx_cif_source(i2s->rxcif, + TEGRA30_AHUB_TXCIF_DAM0_TX0 + + i2s->call_record_dam_ifc); +#ifndef CONFIG_ARCH_TEGRA_3x_SOC + /* Configure DAM0 for SRC */ + if (bb_info->rate != hifi_info->rate) { + tegra30_dam_write_coeff_ram( + i2s->call_record_dam_ifc, + bb_info->rate, hifi_info->rate); + tegra30_dam_set_farrow_param( + i2s->call_record_dam_ifc, + bb_info->rate, hifi_info->rate); + tegra30_dam_set_biquad_fixed_coef( + i2s->call_record_dam_ifc); + tegra30_dam_enable_coeff_ram( + i2s->call_record_dam_ifc); + tegra30_dam_set_filter_stages( + i2s->call_record_dam_ifc, + bb_info->rate, hifi_info->rate); + } +#endif + /* enable the dam */ + tegra30_dam_enable(i2s->call_record_dam_ifc2, TEGRA30_DAM_ENABLE, TEGRA30_DAM_CHIN1); - tegra30_dam_enable(i2s->call_record_dam_ifc2, + tegra30_dam_enable(i2s->call_record_dam_ifc2, TEGRA30_DAM_ENABLE, TEGRA30_DAM_CHIN0_SRC); + } + + /* enable the dam */ + tegra30_dam_enable(i2s->call_record_dam_ifc, TEGRA30_DAM_ENABLE, + TEGRA30_DAM_CHIN1); + tegra30_dam_enable(i2s->call_record_dam_ifc, TEGRA30_DAM_ENABLE, + TEGRA30_DAM_CHIN0_SRC); } return 0; @@ -707,16 +753,7 @@ static void tegra_aic326x_shutdown(struct snd_pcm_substream *substream) TEGRA30_DAM_DISABLE, TEGRA30_DAM_CHIN1); tegra30_dam_enable(i2s->call_record_dam_ifc, TEGRA30_DAM_DISABLE, TEGRA30_DAM_CHIN0_SRC); - tegra30_dam_enable(i2s->call_record_dam_ifc2, - TEGRA30_DAM_DISABLE, TEGRA30_DAM_CHIN1); - tegra30_dam_enable(i2s->call_record_dam_ifc2, - TEGRA30_DAM_DISABLE, TEGRA30_DAM_CHIN0_SRC); - /* disconnect the ahub connections*/ - tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX0 + - (i2s->call_record_dam_ifc2*2)); - tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX1 + - (i2s->call_record_dam_ifc2*2)); tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX0 + (i2s->call_record_dam_ifc*2)); tegra30_ahub_unset_rx_cif_source(i2s->rxcif); @@ -729,12 +766,27 @@ static void tegra_aic326x_shutdown(struct snd_pcm_substream *substream) TEGRA30_DAM_CHIN0_SRC); tegra30_dam_free_controller(i2s->call_record_dam_ifc); - tegra30_dam_disable_clock(i2s->call_record_dam_ifc2); - tegra30_dam_free_channel(i2s->call_record_dam_ifc2, + if (!machine->is_device_bt) { + tegra30_dam_enable(i2s->call_record_dam_ifc2, + TEGRA30_DAM_DISABLE, TEGRA30_DAM_CHIN1); + tegra30_dam_enable(i2s->call_record_dam_ifc2, + TEGRA30_DAM_DISABLE, TEGRA30_DAM_CHIN0_SRC); + + /* disconnect the ahub connections*/ + tegra30_ahub_unset_rx_cif_source( + TEGRA30_AHUB_RXCIF_DAM0_RX0 + + (i2s->call_record_dam_ifc2*2)); + tegra30_ahub_unset_rx_cif_source( + TEGRA30_AHUB_RXCIF_DAM0_RX1 + + (i2s->call_record_dam_ifc2*2)); + + tegra30_dam_disable_clock(i2s->call_record_dam_ifc2); + tegra30_dam_free_channel(i2s->call_record_dam_ifc2, TEGRA30_DAM_CHIN1); - tegra30_dam_free_channel(i2s->call_record_dam_ifc2, + tegra30_dam_free_channel(i2s->call_record_dam_ifc2, TEGRA30_DAM_CHIN0_SRC); - tegra30_dam_free_controller(i2s->call_record_dam_ifc2); + tegra30_dam_free_controller(i2s->call_record_dam_ifc2); + } } return; @@ -852,7 +904,6 @@ static int tegra_aic326x_voice_call_hw_params( #endif machine->is_device_bt = 0; - return 0; } @@ -867,8 +918,6 @@ static void tegra_aic326x_voice_call_shutdown( machine->codec_info[VOICE_CODEC].rate = 0; machine->codec_info[VOICE_CODEC].channels = 0; #endif - - machine->is_device_bt = 0; } static int tegra_aic326x_bt_voice_call_hw_params( @@ -907,7 +956,6 @@ static int tegra_aic326x_bt_voice_call_hw_params( #endif machine->is_device_bt = 1; - return 0; } @@ -922,8 +970,6 @@ static void tegra_aic326x_bt_voice_call_shutdown( machine->codec_info[BT_SCO].rate = 0; machine->codec_info[BT_SCO].channels = 0; #endif - - machine->is_device_bt = 0; } static struct snd_soc_ops tegra_aic326x_hifi_ops = { |