hal: Fix audio mute issue on MT call over a2dp

- Random audio mute issues are seen on BT SCO
  device during MT voice call
- As a part of MT call ringtone playback on a2dp,
  a2dp start request is failing from BT IPC library
  as BT IPC librbary does not support a2dp playback when
  phone state is MODE_IN_RINGTONE/MODE_IN_NORMAL.
  When a2dp playback start fails on low latency,pcm_prepare()
  is called continouly till audio routes to a2dp.
  This impacts voice call routing to sco as primary output/
  low latency session is in improper state.
- Do not route audio to a2dp device if phone state is
  MODE_IN_RINGTONE/MODE_IN_CALL.

Change-Id: Icf1f10c00365b0b401464ebcbe6135fe93a0dd0e
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index e72cb76..28d0f75 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -645,6 +645,35 @@
     return ret;
 }
 
+static void reset_a2dp_enc_config_params()
+{
+    int ret =0;
+
+    struct mixer_ctl *ctl_enc_config, *ctrl_bit_format;
+    struct sbc_enc_cfg_t dummy_reset_config;
+
+    memset(&dummy_reset_config, 0x0, sizeof(struct sbc_enc_cfg_t));
+    ctl_enc_config = mixer_get_ctl_by_name(a2dp.adev->mixer,
+                                           MIXER_ENC_CONFIG_BLOCK);
+    if (!ctl_enc_config) {
+        ALOGE(" ERROR  a2dp encoder format mixer control not identifed");
+    } else {
+        ret = mixer_ctl_set_array(ctl_enc_config, (void *)&dummy_reset_config,
+                                        sizeof(struct sbc_enc_cfg_t));
+         a2dp.bt_encoder_format = ENC_MEDIA_FMT_NONE;
+    }
+    ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
+                                            MIXER_ENC_BIT_FORMAT);
+    if (!ctrl_bit_format) {
+        ALOGE(" ERROR  bit format CONFIG data mixer control not identifed");
+    } else {
+        ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
+        if (ret != 0) {
+            ALOGE("%s: Failed to set bit format to encoder", __func__);
+        }
+    }
+}
+
 int audio_extn_a2dp_stop_playback()
 {
     int ret =0;
@@ -659,35 +688,13 @@
         a2dp.a2dp_total_active_session_request--;
 
     if ( a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
-        struct mixer_ctl *ctl_enc_config, *ctrl_bit_format;
-        struct sbc_enc_cfg_t dummy_reset_config;
-
         ALOGV("calling BT module stream stop");
         ret = a2dp.audio_stop_stream();
         if (ret < 0)
             ALOGE("stop stream to BT IPC lib failed");
         else
             ALOGV("stop steam to BT IPC lib successful");
-         memset(&dummy_reset_config, 0x0, sizeof(struct sbc_enc_cfg_t));
-        ctl_enc_config = mixer_get_ctl_by_name(a2dp.adev->mixer,
-                                               MIXER_ENC_CONFIG_BLOCK);
-        if (!ctl_enc_config) {
-            ALOGE(" ERROR  a2dp encoder format mixer control not identifed");
-        } else {
-            ret = mixer_ctl_set_array(ctl_enc_config, (void *)&dummy_reset_config,
-                                            sizeof(struct sbc_enc_cfg_t));
-             a2dp.bt_encoder_format = ENC_MEDIA_FMT_NONE;
-        }
-        ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
-                                                MIXER_ENC_BIT_FORMAT);
-        if (!ctrl_bit_format) {
-            ALOGE(" ERROR  bit format CONFIG data mixer control not identifed");
-        } else {
-            ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
-            if (ret != 0) {
-                ALOGE("%s: Failed to set bit format to encoder", __func__);
-            }
-        }
+        reset_a2dp_enc_config_params();
     }
     if(!a2dp.a2dp_total_active_session_request)
        a2dp.a2dp_started = false;
@@ -724,6 +731,7 @@
          val = atoi(value);
          if (val & AUDIO_DEVICE_OUT_ALL_A2DP) {
              ALOGV("Received device dis- connect request");
+             reset_a2dp_enc_config_params();
              close_a2dp_output();
          }
          goto param_handled;
@@ -735,6 +743,7 @@
              if ((!strncmp(value,"true",sizeof(value)))) {
                 ALOGD("Setting a2dp to suspend state");
                 a2dp.a2dp_suspended = true;
+                reset_a2dp_enc_config_params();
                 if(a2dp.audio_suspend_stream)
                    a2dp.audio_suspend_stream();
             } else if (a2dp.a2dp_suspended == true) {
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 3816748..b354c6a 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -2452,7 +2452,15 @@
                 (val == AUDIO_DEVICE_NONE)) {
                 val = AUDIO_DEVICE_OUT_SPEAKER;
         }
-
+        /* To avoid a2dp to sco overlapping force route BT usecases
+         * to speaker based on Phone state
+         */
+        if ((val & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) &&
+            ((adev->mode == AUDIO_MODE_RINGTONE) ||
+            (adev->mode == AUDIO_MODE_IN_CALL))) {
+            ALOGD("Forcing a2dp routing to speaker for ring/call mode");
+            val = AUDIO_DEVICE_OUT_SPEAKER;
+        }
         /*
          * select_devices() call below switches all the usecases on the same
          * backend to the new device. Refer to check_usecases_codec_backend() in
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index a5cc804..cf65be6 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -2924,6 +2924,7 @@
         *num_devices = 2;
         new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
         new_snd_devices[1] = SND_DEVICE_OUT_BT_A2DP;
+        status = true;
     }
 
     ALOGD("%s: snd_device(%d) num devices(%d) new_snd_devices(%d)", __func__,
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index fa67342..885d29f 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -2742,9 +2742,9 @@
         *num_devices = 2;
         new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
         new_snd_devices[1] = SND_DEVICE_OUT_BT_A2DP;
+        status = true;
     }
 
-
     ALOGD("%s: snd_device(%d) num devices(%d) new_snd_devices(%d)", __func__,
         snd_device, *num_devices, *new_snd_devices);