hal: update EC reference handling

Change-Id: I745e28c14902f810754887f9db195cf4f5261713
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 0a1ebf8..cd9ded8 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -1731,6 +1731,8 @@
             pcm_close(in->pcm);
             in->pcm = NULL;
         }
+        adev->enable_voicerx = false;
+        platform_set_echo_reference(adev, false, AUDIO_DEVICE_NONE );
         status = stop_input_stream(in);
         pthread_mutex_unlock(&adev->lock);
     }
@@ -1855,6 +1857,7 @@
                                    bool enable)
 {
     struct stream_in *in = (struct stream_in *)stream;
+    struct audio_device *adev = in->dev;
     int status = 0;
     effect_descriptor_t desc;
 
@@ -1868,6 +1871,18 @@
             in->enable_aec != enable &&
             (memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
         in->enable_aec = enable;
+        if (!enable)
+            platform_set_echo_reference(in->dev, enable, AUDIO_DEVICE_NONE);
+        adev->enable_voicerx = enable;
+        struct audio_usecase *usecase;
+        struct listnode *node;
+        list_for_each(node, &adev->usecase_list) {
+            usecase = node_to_item(node, struct audio_usecase, list);
+            if (usecase->type == PCM_PLAYBACK) {
+                select_devices(adev, usecase->id);
+            break;
+            }
+        }
         if (!in->standby)
             select_devices(in->dev, in->usecase);
     }
@@ -2337,7 +2352,7 @@
                                   struct audio_stream_in **stream_in,
                                   audio_input_flags_t flags,
                                   const char *address __unused,
-                                  audio_source_t source __unused)
+                                  audio_source_t source )
 {
     struct audio_device *adev = (struct audio_device *)dev;
     struct stream_in *in;
@@ -2371,7 +2386,7 @@
     in->stream.get_input_frames_lost = in_get_input_frames_lost;
 
     in->device = devices;
-    in->source = AUDIO_SOURCE_DEFAULT;
+    in->source = source;
     in->dev = adev;
     in->standby = 1;
     in->channel_mask = config->channel_mask;
@@ -2704,6 +2719,7 @@
     }
 
     adev->bt_wb_speech_enabled = false;
+    adev->enable_voicerx = false;
 
     *device = &adev->device.common;
     if (k_enable_extended_precision)
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index e742bc7..bec19d0 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -212,6 +212,7 @@
     unsigned int cur_hdmi_channels;
     bool bt_wb_speech_enabled;
     bool mic_muted;
+    bool enable_voicerx;
 
     int snd_card;
     void *platform;
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index 1a8d0ab..bc38b1d 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1002,3 +1002,8 @@
 {
     return -ENOSYS;
 }
+
+void platform_set_echo_reference(struct audio_device *adev, bool enable, audio_devices_t out_device)
+{
+    return;
+}
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 887f4f2..27e39d9 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -172,6 +172,7 @@
     [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = "speaker-dmic-endfire",
 
     [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
+    [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
 
     [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
     [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
@@ -243,6 +244,7 @@
     [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = 35,
 
     [SND_DEVICE_IN_HEADSET_MIC] = 8,
+    [SND_DEVICE_IN_HEADSET_MIC_AEC] = ACDB_ID_HEADSET_MIC_AEC,
 
     [SND_DEVICE_IN_HDMI_MIC] = 4,
     [SND_DEVICE_IN_BT_SCO_MIC] = 21,
@@ -405,14 +407,25 @@
     return is_tmus;
 }
 
-static void set_echo_reference(struct audio_device *adev, bool enable)
+void platform_set_echo_reference(struct audio_device *adev, bool enable, audio_devices_t out_device)
 {
-    if (enable)
-        audio_route_apply_and_update_path(adev->audio_route, "echo-reference");
-    else
-        audio_route_reset_and_update_path(adev->audio_route, "echo-reference");
+    char mixer_path[50] = { 0 } ;
+    snd_device_t snd_device = SND_DEVICE_NONE;
+    struct listnode *node;
+    struct audio_usecase *usecase;
 
-    ALOGV("Setting EC Reference: %d", enable);
+    strcpy(mixer_path, "echo-reference");
+    if (out_device != AUDIO_DEVICE_NONE) {
+        snd_device = platform_get_output_snd_device(adev->platform, out_device);
+        platform_add_backend_name(adev->platform, mixer_path, snd_device);
+    }
+
+    if (enable)
+        audio_route_apply_and_update_path(adev->audio_route, mixer_path);
+    else
+        audio_route_reset_and_update_path(adev->audio_route, mixer_path);
+
+    ALOGV("Setting EC Reference: %d for %s", enable, mixer_path);
 }
 
 static struct csd_data *open_csd_client(bool i2s_ext_modem)
@@ -1173,15 +1186,19 @@
         goto exit;
     }
 
-    if (mode == AUDIO_MODE_IN_CALL) {
+    if ((mode == AUDIO_MODE_IN_CALL) ||
+        (adev->enable_voicerx)) {
         if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
             devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
             devices & AUDIO_DEVICE_OUT_LINE) {
-            if (adev->voice.tty_mode == TTY_MODE_FULL)
+            if ((mode == AUDIO_MODE_IN_CALL) &&
+                (adev->voice.tty_mode == TTY_MODE_FULL))
                 snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
-            else if (adev->voice.tty_mode == TTY_MODE_VCO)
+            else if ((mode == AUDIO_MODE_IN_CALL) &&
+                (adev->voice.tty_mode == TTY_MODE_VCO))
                 snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
-            else if (adev->voice.tty_mode == TTY_MODE_HCO)
+            else if ((mode == AUDIO_MODE_IN_CALL) &&
+                (adev->voice.tty_mode == TTY_MODE_HCO))
                 snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
             else {
                 if (devices & AUDIO_DEVICE_OUT_LINE)
@@ -1319,7 +1336,6 @@
         if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
             if (my_data->fluence_in_voice_call == false) {
                 snd_device = SND_DEVICE_IN_HANDSET_MIC;
-                set_echo_reference(adev, true);
             } else {
                 if (is_operator_tmus())
                     snd_device = SND_DEVICE_IN_VOICE_DMIC_TMUS;
@@ -1343,7 +1359,6 @@
                 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
             } else {
                 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
-                set_echo_reference(adev, true);
             }
         } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX)
             snd_device = SND_DEVICE_IN_VOICE_RX;
@@ -1388,8 +1403,10 @@
                         snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
                     } else
                         snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
+                } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+                    snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
                 }
-                set_echo_reference(adev, true);
+                platform_set_echo_reference(adev, true, out_device);
             } else if (adev->active_input->enable_aec) {
                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
                     if (my_data->fluence_in_spkr_mode &&
@@ -1404,8 +1421,10 @@
                         snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
                     } else
                         snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
-                }
-                set_echo_reference(adev, true);
+               } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+                   snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
+               }
+                platform_set_echo_reference(adev, true, out_device);
             } else if (adev->active_input->enable_ns) {
                 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
                     if (my_data->fluence_in_spkr_mode &&
@@ -1421,9 +1440,7 @@
                     } else
                         snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
                 }
-                set_echo_reference(adev, false);
-            } else
-                set_echo_reference(adev, false);
+            }
         }
     } else if (source == AUDIO_SOURCE_DEFAULT) {
         goto exit;
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index a785fa0..4dc83bb 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -88,6 +88,7 @@
     SND_DEVICE_IN_SPEAKER_DMIC_STEREO,
 
     SND_DEVICE_IN_HEADSET_MIC,
+    SND_DEVICE_IN_HEADSET_MIC_AEC,
 
     SND_DEVICE_IN_HDMI_MIC,
     SND_DEVICE_IN_BT_SCO_MIC,
@@ -128,11 +129,13 @@
 #define ACDB_ID_VOICE_HANDSET 67
 #define ACDB_ID_VOICE_HANDSET_TMUS 67
 #define ACDB_ID_VOICE_DMIC_EF_TMUS 89
+#define ACDB_ID_HEADSET_MIC_AEC 47
 #else
 #define ACDB_ID_VOICE_SPEAKER 15
 #define ACDB_ID_VOICE_HANDSET 7
 #define ACDB_ID_VOICE_HANDSET_TMUS 88
 #define ACDB_ID_VOICE_DMIC_EF_TMUS 89
+#define ACDB_ID_HEADSET_MIC_AEC 10
 #endif
 
 #define MAX_VOL_INDEX 5
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 1363629..e50e06d 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -63,5 +63,6 @@
 
 int platform_get_usecase_index(const char * usecase);
 int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id);
+void platform_set_echo_reference(struct audio_device *adev, bool enable, audio_devices_t out_device);
 
 #endif // AUDIO_PLATFORM_API_H