ASoC:Tegra: use DAM for BT-SCO playback
Lei Fan [Thu, 20 Feb 2014 13:07:27 +0000 (21:07 +0800)]
Add DAM for BT audio path even there is no voice call.
Because of race condition, it is difficult to check device is in BT call
or not. So tone will break voice call path sometime.

Bug 1461765

Change-Id: Iabc3dfc59a570f0c58a66937fc94b65626f332a7
Signed-off-by: Lei Fan <leif@nvidia.com>
Reviewed-on: http://git-master/r/369937
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Martin Chi <mchi@nvidia.com>

sound/soc/tegra/tegra_rt5640.c

index a91e3a8..1dbe35b 100644 (file)
@@ -736,7 +736,7 @@ static void tegra_rt5640_shutdown(struct snd_pcm_substream *substream)
                i2s->dam_ch_refcount--;
                if (!i2s->dam_ch_refcount)
                        tegra30_dam_free_controller(i2s->dam_ifc);
-        } else {
+       } else {
                if (!i2s->is_call_mode_rec)
                        return;
 
@@ -762,7 +762,7 @@ static void tegra_rt5640_shutdown(struct snd_pcm_substream *substream)
                tegra30_dam_free_channel(i2s->call_record_dam_ifc,
                        TEGRA30_DAM_CHIN0_SRC);
                tegra30_dam_free_controller(i2s->call_record_dam_ifc);
-        }
+       }
 
        return;
 }
@@ -787,15 +787,20 @@ static int tegra_bt_startup(struct snd_pcm_substream *substream)
                        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);
+               tegra30_dam_allocate_channel(i2s->dam_ifc,
+                       TEGRA30_DAM_CHIN0_SRC);
+               tegra30_dam_allocate_channel(i2s->dam_ifc,
+                       TEGRA30_DAM_CHIN1);
                i2s->dam_ch_refcount++;
                tegra30_dam_enable_clock(i2s->dam_ifc);
 
-               if (machine->is_call_mode) {
+               tegra_bt_set_dam_cif(i2s->dam_ifc,
+                       8000, 1, 16, 1, 16000, 1, 16);
+
+               if (1) {
                        tegra30_ahub_set_rx_cif_source(
                                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
@@ -807,14 +812,13 @@ static int tegra_bt_startup(struct snd_pcm_substream *substream)
                                        i2s->id,
                                        TEGRA30_AHUB_TXCIF_DAM0_TX0 +
                                        i2s->dam_ifc);
-               } else {
-                       tegra30_ahub_set_rx_cif_source(
-                               TEGRA30_AHUB_RXCIF_I2S0_RX0 + i2s->id,
-                               i2s->txcif);
                }
                /* enable the dam*/
                tegra30_dam_enable(i2s->dam_ifc, TEGRA30_DAM_ENABLE,
                                TEGRA30_DAM_CHIN1);
+               tegra30_dam_enable(i2s->dam_ifc, TEGRA30_DAM_ENABLE,
+                               TEGRA30_DAM_CHIN0_SRC);
+
        } else {
                i2s->is_call_mode_rec = machine->is_call_mode;
 
@@ -886,16 +890,19 @@ static void tegra_bt_shutdown(struct snd_pcm_substream *substream)
                                TEGRA30_DAM_CHIN1);
 
                /* disconnect the ahub connections*/
-               tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX0 +
+               if (i2s->playback_ref_count == 1)
+                       tegra30_ahub_unset_rx_cif_source(
+                               TEGRA30_AHUB_RXCIF_DAM0_RX0 +
                                        (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);
+               tegra30_dam_free_channel(i2s->dam_ifc, TEGRA30_DAM_CHIN0_SRC);
                i2s->dam_ch_refcount--;
                if (!i2s->dam_ch_refcount)
                        tegra30_dam_free_controller(i2s->dam_ifc);
-        } else {
+       } else {
                if (!i2s->is_call_mode_rec)
                        return;
 
@@ -921,7 +928,7 @@ static void tegra_bt_shutdown(struct snd_pcm_substream *substream)
                tegra30_dam_free_channel(i2s->call_record_dam_ifc,
                        TEGRA30_DAM_CHIN0_SRC);
                tegra30_dam_free_controller(i2s->call_record_dam_ifc);
-        }
+       }
 
        return;
 }