summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorRahul Mittal <rmittal@nvidia.com>2013-03-06 19:57:29 +0530
committerMandar Padmawar <mpadmawar@nvidia.com>2013-03-08 00:29:28 -0800
commitdd93f497aa136e3c73398235922409dec3ab6539 (patch)
tree846986107c39b2b9ebed5d5b01754a317596ac55 /sound
parenta80fd70068e579434426bf850806386e21fecfa6 (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.c192
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 = {