Merge "hal: Fix aanc sequence during voice call"
diff --git a/configs/msm8996/mixer_paths_tasha.xml b/configs/msm8996/mixer_paths_tasha.xml
index 9f63413..64d6bfb 100644
--- a/configs/msm8996/mixer_paths_tasha.xml
+++ b/configs/msm8996/mixer_paths_tasha.xml
@@ -2278,6 +2278,9 @@
     <path name="capture-fm">
     </path>
 
+    <path name="aanc-path">
+    </path>
+
     <path name="aanc-handset-mic">
         <ctl name="AIF1_CAP Mixer SLIM TX6" value="1" />
         <ctl name="AIF1_CAP Mixer SLIM TX8" value="1" />
diff --git a/configs/msmcobalt/mixer_paths_tasha.xml b/configs/msmcobalt/mixer_paths_tasha.xml
index efd275d..23c0f06 100644
--- a/configs/msmcobalt/mixer_paths_tasha.xml
+++ b/configs/msmcobalt/mixer_paths_tasha.xml
@@ -2293,6 +2293,12 @@
     <path name="capture-fm">
     </path>
 
+    <path name="aanc-path">
+        <ctl name="ADC MUX10" value="DMIC" />
+        <ctl name="DMIC MUX10" value="DMIC4" />
+        <ctl name="ANC0 FB MUX" value="ANC_IN_EAR_SPKR" />
+    </path>
+
     <path name="aanc-handset-mic">
         <ctl name="AIF1_CAP Mixer SLIM TX6" value="1" />
         <ctl name="AIF1_CAP Mixer SLIM TX8" value="1" />
@@ -2309,9 +2315,6 @@
         <ctl name="ADC MUX7" value="DMIC" />
         <ctl name="DMIC MUX7" value="DMIC0" />
         <ctl name="IIR0 INP0 MUX" value="DEC6" />
-        <ctl name="ADC MUX10" value="DMIC" />
-        <ctl name="DMIC MUX10" value="DMIC4" />
-        <ctl name="ANC0 FB MUX" value="ANC_IN_EAR_SPKR" />
     </path>
 
     <!-- Dual MIC devices -->
diff --git a/configs/msmcobalt/mixer_paths_tavil.xml b/configs/msmcobalt/mixer_paths_tavil.xml
index 29212f9..555555d 100644
--- a/configs/msmcobalt/mixer_paths_tavil.xml
+++ b/configs/msmcobalt/mixer_paths_tavil.xml
@@ -2068,6 +2068,12 @@
     <path name="capture-fm">
     </path>
 
+    <path name="aanc-path">
+        <ctl name="ADC MUX10" value="DMIC" />
+        <ctl name="DMIC MUX10" value="DMIC4" />
+        <ctl name="ANC0 FB MUX" value="ANC_IN_EAR_SPKR" />
+    </path>
+
     <path name="aanc-handset-mic">
         <ctl name="AIF1_CAP Mixer SLIM TX6" value="1" />
         <ctl name="AIF1_CAP Mixer SLIM TX8" value="1" />
@@ -2084,9 +2090,6 @@
         <ctl name="ADC MUX7" value="DMIC" />
         <ctl name="DMIC MUX7" value="DMIC0" />
         <ctl name="IIR0 INP0 MUX" value="DEC6" />
-        <ctl name="ADC MUX10" value="DMIC" />
-        <ctl name="DMIC MUX10" value="DMIC4" />
-        <ctl name="ANC0 FB MUX" value="ANC_IN_EAR_SPKR" />
     </path>
 
     <!-- Dual MIC devices -->
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index e82cd51..270f36e 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -1424,6 +1424,10 @@
         if (voice_is_call_state_active(adev) ||
             voice_extn_compress_voip_is_started(adev))
             voice_set_sidetone(adev, usecase->out_snd_device, false);
+
+        /* Disable aanc only if voice call exists */
+        if (voice_is_call_state_active(adev))
+            voice_check_and_update_aanc_path(adev, usecase->out_snd_device, false);
     }
 
     /* Disable current sound devices */
@@ -1494,6 +1498,10 @@
     enable_audio_route(adev, usecase);
 
     if (usecase->type == VOICE_CALL || usecase->type == VOIP_CALL) {
+        /* Enable aanc only if voice call exists */
+        if (voice_is_call_state_active(adev))
+            voice_check_and_update_aanc_path(adev, out_snd_device, true);
+
         /* Enable sidetone only if other voice/voip call already exists */
         if (voice_is_call_state_active(adev) ||
             voice_extn_compress_voip_is_started(adev))
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 0a14629..a42f984 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -5623,6 +5623,14 @@
     return 0;
 }
 
+void platform_update_aanc_path(struct audio_device *adev __unused,
+                               snd_device_t out_snd_device __unused,
+                               bool enable __unused,
+                               char *str __unused)
+{
+   return;
+}
+
 bool platform_check_codec_dsd_support(void *platform __unused)
 {
     return false;
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index b5a4f11..e025772 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1315,6 +1315,14 @@
     return 0;
 }
 
+void platform_update_aanc_path(struct audio_device *adev __unused,
+                               snd_device_t out_snd_device __unused,
+                               bool enable __unused,
+                               char *str __unused)
+{
+    return;
+}
+
 bool platform_check_codec_dsd_support(void *platform __unused)
 {
     return false;
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index f506130..d209359 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -5647,6 +5647,22 @@
     return 0;
 }
 
+void platform_update_aanc_path(struct audio_device *adev,
+                               snd_device_t out_snd_device,
+                               bool enable,
+                               char *str)
+{
+    ALOGD("%s: aanc out device(%d) mixer cmd = %s, enable = %d\n",
+          __func__, out_snd_device, str, enable);
+
+    if (enable)
+        audio_route_apply_and_update_path(adev->audio_route, str);
+    else
+        audio_route_reset_and_update_path(adev->audio_route, str);
+
+    return;
+}
+
 static void make_cal_cfg(acdb_audio_cal_cfg_t* cal, int acdb_dev_id,
         int acdb_device_type, int app_type, int topology_id,
         int sample_rate, uint32_t module_id, uint32_t param_id, bool persist)
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 76d99b3..61f42de 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -157,6 +157,10 @@
                           snd_device_t out_snd_device,
                           bool enable,
                           char * str);
+void platform_update_aanc_path(struct audio_device *adev,
+                              snd_device_t out_snd_device,
+                              bool enable,
+                              char * str);
 bool platform_supports_true_32bit();
 bool platform_check_if_backend_has_to_be_disabled(snd_device_t new_snd_device, snd_device_t cuurent_snd_device);
 bool platform_check_codec_dsd_support(void *platform);
diff --git a/hal/voice.c b/hal/voice.c
index b84c7b7..ca3098b 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -95,6 +95,39 @@
     return;
 }
 
+static bool voice_is_aanc_device(snd_device_t out_device,
+                                 char *mixer_path)
+{
+    bool is_aanc_dev;
+
+    switch (out_device) {
+        case SND_DEVICE_OUT_ANC_HANDSET:
+            is_aanc_dev = true;
+            strlcpy(mixer_path, "aanc-path", MIXER_PATH_MAX_LENGTH);
+            break;
+        default:
+            is_aanc_dev = false;
+            break;
+    }
+
+    return is_aanc_dev;
+}
+
+void voice_check_and_update_aanc_path(struct audio_device *adev,
+                                      snd_device_t out_snd_device,
+                                      bool enable)
+{
+    char mixer_path[MIXER_PATH_MAX_LENGTH];
+
+    ALOGV("%s: %s, out_snd_device: %d\n",
+          __func__, (enable ? "enable" : "disable"), out_snd_device);
+
+    if (voice_is_aanc_device(out_snd_device, mixer_path))
+        platform_update_aanc_path(adev, out_snd_device, enable, mixer_path);
+
+    return;
+}
+
 int voice_stop_usecase(struct audio_device *adev, audio_usecase_t usecase_id)
 {
     int ret = 0;
@@ -125,6 +158,10 @@
     if (!voice_is_call_state_active(adev))
         voice_set_sidetone(adev, uc_info->out_snd_device, false);
 
+    /* Disable aanc only when no calls are active */
+    if (!voice_is_call_state_active(adev))
+        voice_check_and_update_aanc_path(adev, uc_info->out_snd_device, false);
+
     ret = platform_stop_voice_call(adev->platform, session->vsid);
 
     /* 1. Close the PCM devices */
@@ -229,6 +266,10 @@
     pcm_start(session->pcm_tx);
     pcm_start(session->pcm_rx);
 
+    /* Enable aanc only when no calls are active */
+    if (!voice_is_call_state_active(adev))
+        voice_check_and_update_aanc_path(adev, uc_info->out_snd_device, true);
+
     /* Enable sidetone only when no calls are already active */
     if (!voice_is_call_state_active(adev))
         voice_set_sidetone(adev, uc_info->out_snd_device, true);
diff --git a/hal/voice.h b/hal/voice.h
index efe48d8..3ae42a8 100644
--- a/hal/voice.h
+++ b/hal/voice.h
@@ -97,5 +97,8 @@
 void voice_set_sidetone(struct audio_device *adev,
                        snd_device_t out_snd_device,
                        bool enable);
+void voice_check_and_update_aanc_path(struct audio_device *adev,
+                                      snd_device_t out_snd_device,
+                                      bool enable);
 bool voice_is_call_state_active(struct audio_device *adev);
 #endif //VOICE_H