Merge "policy_hal: remove VGS check for BT volume"
diff --git a/hal/audio_extn/fm.c b/hal/audio_extn/fm.c
index a4157f8..35b20b8 100644
--- a/hal/audio_extn/fm.c
+++ b/hal/audio_extn/fm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -64,7 +64,7 @@
 {
     int32_t vol, ret = 0;
     struct mixer_ctl *ctl;
-    const char *mixer_ctl_name = "Internal FM RX Volume";
+    const char *mixer_ctl_name = FM_RX_VOLUME;
 
     ALOGV("%s: entry", __func__);
     ALOGD("%s: (%f)\n", __func__, value);
@@ -92,7 +92,6 @@
         return -EINVAL;
     }
     mixer_ctl_set_value(ctl, 0, vol);
-
     ALOGV("%s: exit", __func__);
     return ret;
 }
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 9f76d31..2f67784 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -300,10 +300,12 @@
      * control in use-case does not work because rate update takes place after
      * AFE port open due to the limitation of mixer control order execution.
      */
-    if (snd_device == SND_DEVICE_OUT_BT_SCO) {
+    if ((snd_device == SND_DEVICE_OUT_BT_SCO) ||
+        (snd_device == SND_DEVICE_IN_BT_SCO_MIC)) {
         audio_route_apply_path(adev->audio_route, BT_SCO_SAMPLE_RATE);
         audio_route_update_mixer(adev->audio_route);
-    } else if (snd_device == SND_DEVICE_OUT_BT_SCO_WB) {
+    } else if ((snd_device == SND_DEVICE_OUT_BT_SCO_WB) ||
+               (snd_device == SND_DEVICE_IN_BT_SCO_MIC_WB)) {
         audio_route_apply_path(adev->audio_route, BT_SCO_WB_SAMPLE_RATE);
         audio_route_update_mixer(adev->audio_route);
     }
@@ -437,23 +439,22 @@
         /* Make sure all the streams are de-routed before disabling the device */
         audio_route_update_mixer(adev->audio_route);
 
+        /* Make sure the previous devices to be disabled first and then enable the
+           selected devices */
         list_for_each(node, &adev->usecase_list) {
             usecase = node_to_item(node, struct audio_usecase, list);
             if (switch_device[usecase->id]) {
-                disable_snd_device(adev, usecase->out_snd_device, false);
+                disable_snd_device(adev, usecase->out_snd_device, true);
             }
         }
 
         list_for_each(node, &adev->usecase_list) {
             usecase = node_to_item(node, struct audio_usecase, list);
             if (switch_device[usecase->id]) {
-                enable_snd_device(adev, snd_device, false);
+                enable_snd_device(adev, snd_device, true);
             }
         }
 
-        /* Make sure new snd device is enabled before re-routing the streams */
-        audio_route_update_mixer(adev->audio_route);
-
         /* Re-route all the usecases on the shared backend other than the
            specified usecase to new snd devices */
         list_for_each(node, &adev->usecase_list) {
@@ -507,23 +508,22 @@
         /* Make sure all the streams are de-routed before disabling the device */
         audio_route_update_mixer(adev->audio_route);
 
+        /* Make sure the previous devices to be disabled first and then enable the
+           selected devices */
         list_for_each(node, &adev->usecase_list) {
             usecase = node_to_item(node, struct audio_usecase, list);
             if (switch_device[usecase->id]) {
-                disable_snd_device(adev, usecase->in_snd_device, false);
+                disable_snd_device(adev, usecase->in_snd_device, true);
             }
         }
 
         list_for_each(node, &adev->usecase_list) {
             usecase = node_to_item(node, struct audio_usecase, list);
             if (switch_device[usecase->id]) {
-                enable_snd_device(adev, snd_device, false);
+                enable_snd_device(adev, snd_device, true);
             }
         }
 
-        /* Make sure new snd device is enabled before re-routing the streams */
-        audio_route_update_mixer(adev->audio_route);
-
         /* Re-route all the usecases on the shared backend other than the
            specified usecase to new snd devices */
         list_for_each(node, &adev->usecase_list) {
@@ -637,7 +637,8 @@
             }
         } else if (voice_extn_compress_voip_is_active(adev)) {
             voip_usecase = get_usecase_from_list(adev, USECASE_COMPRESS_VOIP_CALL);
-            if (voip_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) {
+            if ((voip_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) &&
+                (usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND)) {
                     in_snd_device = voip_usecase->in_snd_device;
                     out_snd_device = voip_usecase->out_snd_device;
             }
@@ -698,12 +699,12 @@
     /* Disable current sound devices */
     if (usecase->out_snd_device != SND_DEVICE_NONE) {
         disable_audio_route(adev, usecase, true);
-        disable_snd_device(adev, usecase->out_snd_device, false);
+        disable_snd_device(adev, usecase->out_snd_device, true);
     }
 
     if (usecase->in_snd_device != SND_DEVICE_NONE) {
         disable_audio_route(adev, usecase, true);
-        disable_snd_device(adev, usecase->in_snd_device, false);
+        disable_snd_device(adev, usecase->in_snd_device, true);
     }
 
     /* Applicable only on the targets that has external modem.
@@ -1424,13 +1425,14 @@
         pthread_mutex_lock(&adev->lock);
 
         /*
-         * When HDMI cable is unplugged the music playback is paused and
-         * the policy manager sends routing=0. But the audioflinger
-         * continues to write data until standby time (3sec).
-         * As the HDMI core is turned off, the write gets blocked.
+         * When HDMI cable is unplugged/usb hs is disconnected the
+         * music playback is paused and the policy manager sends routing=0
+         * But the audioflingercontinues to write data until standby time
+         * (3sec). As the HDMI core is turned off, the write gets blocked.
          * Avoid this by routing audio to speaker until standby.
          */
-        if (out->devices == AUDIO_DEVICE_OUT_AUX_DIGITAL &&
+        if ((out->devices == AUDIO_DEVICE_OUT_AUX_DIGITAL ||
+                out->devices == AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET) &&
                 val == AUDIO_DEVICE_NONE) {
             val = AUDIO_DEVICE_OUT_SPEAKER;
         }
@@ -2255,7 +2257,8 @@
 
     /* Check if this usecase is already existing */
     pthread_mutex_lock(&adev->lock);
-    if (get_usecase_from_list(adev, out->usecase) != NULL) {
+    if ((get_usecase_from_list(adev, out->usecase) != NULL) &&
+        (out->usecase != USECASE_COMPRESS_VOIP_CALL)) {
         ALOGE("%s: Usecase (%d) is already present", __func__, out->usecase);
         pthread_mutex_unlock(&adev->lock);
         ret = -EEXIST;
diff --git a/hal/msm8916/hw_info.c b/hal/msm8916/hw_info.c
index 7b955ba..661a0d0 100644
--- a/hal/msm8916/hw_info.c
+++ b/hal/msm8916/hw_info.c
@@ -137,6 +137,12 @@
         hw_info->snd_devices = NULL;
         hw_info->num_snd_devices = 0;
         strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
+    } else if (!strcmp(snd_card_name, "msm8x16-skui-snd-card")) {
+        strlcpy(hw_info->type, "skui", sizeof(hw_info->type));
+        strlcpy(hw_info->name, "msm8x16", sizeof(hw_info->name));
+        hw_info->snd_devices = NULL;
+        hw_info->num_snd_devices = 0;
+        strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
     } else {
         ALOGW("%s: Not an  8x16 device", __func__);
     }
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index f081912..f12697c 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -178,6 +178,8 @@
 #define PLAYBACK_OFFLOAD_DEVICE 9
 #define COMPRESS_VOIP_CALL_PCM_DEVICE 3
 
+/* Define macro for Internal FM volume mixer */
+#define FM_RX_VOLUME "Internal FM RX Volume"
 
 #define LOWLATENCY_PCM_DEVICE 12
 #define EC_REF_RX "I2S_RX"
diff --git a/hal/msm8960/platform.h b/hal/msm8960/platform.h
index e38d801..e326785 100644
--- a/hal/msm8960/platform.h
+++ b/hal/msm8960/platform.h
@@ -118,4 +118,7 @@
 #define AUDIO_CAPTURE_PERIOD_DURATION_MSEC 20
 #define AUDIO_CAPTURE_PERIOD_COUNT 2
 
+/* Define macro for Internal FM volume mixer */
+#define FM_RX_VOLUME "Internal FM RX Volume"
+
 #endif // QCOM_AUDIO_PLATFORM_H
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index a303a30..5315e78 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1433,6 +1433,7 @@
             }
         } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
             snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
+            set_echo_reference(adev->mixer, EC_REF_RX);
         } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
             if (my_data->btsco_sample_rate == SAMPLE_RATE_16KHZ)
                 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
@@ -1454,6 +1455,7 @@
                 }
             } else {
                 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
+                set_echo_reference(adev->mixer, EC_REF_RX);
             }
         }
     } else if (source == AUDIO_SOURCE_CAMCORDER) {
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 1f25aa2..209ee2b 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -221,7 +221,7 @@
 #define VOICE_CALL_PCM_DEVICE 20
 #define VOICE2_CALL_PCM_DEVICE 25
 #define VOLTE_CALL_PCM_DEVICE 21
-#define QCHAT_CALL_PCM_DEVICE 06
+#define QCHAT_CALL_PCM_DEVICE 33
 #define VOWLAN_CALL_PCM_DEVICE -1
 #elif PLATFORM_MSM8610
 #define VOICE_CALL_PCM_DEVICE 2
@@ -245,6 +245,12 @@
 #define HFP_ASM_RX_TX 24
 #endif
 
+#ifdef PLATFORM_APQ8084
+#define FM_RX_VOLUME "Quat MI2S FM RX Volume"
+#else
+#define FM_RX_VOLUME "Internal FM RX Volume"
+#endif
+
 #define LIB_CSD_CLIENT "libcsd-client.so"
 /* CSD-CLIENT related functions */
 typedef int (*init_t)(bool);