hal: Add codec EC reference support

- We need to set codec EC reference instead of MSM/AFE
  EC ref for Native audio usecase along with other
  usecases running on 48K port. In this scenario we
  will run two AFE ports, one regular port and the
  other port running at 44.1KHz and mixing done in codec.
  So set appropriate codec EC reference.

- One example of such usecase is VoIP over audio path
  and a 44.1KHz stream playback. But this change is generic
  enough to accommodate other possible usecases if any.

Change-Id: Ib980e36d111c1671303abe2b19341568d9fd2331
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 873dd4f..5f0353e 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -225,6 +225,7 @@
     void *edid_info;
     bool edid_valid;
     codec_backend_cfg_t current_backend_cfg[MAX_CODEC_BACKENDS];
+    char ec_ref_mixer_path[64];
 };
 
 static bool is_external_codec = false;
@@ -883,21 +884,33 @@
     }
 }
 
-void platform_set_echo_reference(void *platform, bool enable)
+void platform_set_echo_reference(struct audio_device *adev, bool enable, audio_devices_t out_device)
 {
-    struct platform_data *my_data = (struct platform_data *)platform;
-    struct audio_device *adev = my_data->adev;
+    struct platform_data *my_data = (struct platform_data *)adev->platform;
+    snd_device_t snd_device = SND_DEVICE_NONE;
+    struct stream_out out;
 
-    if (my_data->ec_ref_enabled) {
-        my_data->ec_ref_enabled = false;
-        ALOGV("%s: disabling echo-reference", __func__);
-        audio_route_reset_and_update_path(adev->audio_route, "echo-reference");
+    out.devices = out_device;
+
+    if (strcmp(my_data->ec_ref_mixer_path, "")) {
+        ALOGV("%s: disabling %s", __func__, my_data->ec_ref_mixer_path);
+        audio_route_reset_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
     }
 
     if (enable) {
-         my_data->ec_ref_enabled = true;
-         ALOGD("%s: enabling echo-reference", __func__);
-         audio_route_apply_and_update_path(adev->audio_route, "echo-reference");
+        strlcpy(my_data->ec_ref_mixer_path, "echo-reference", sizeof(my_data->ec_ref_mixer_path));
+        snd_device = platform_get_output_snd_device(adev->platform, &out);
+        /*
+         * If native audio device reference count > 0, then apply codec EC otherwise
+         * fallback to headphones if so or default
+         */
+        if (adev->snd_dev_ref_cnt[SND_DEVICE_OUT_HEADPHONES_44_1] > 0)
+            platform_add_backend_name(my_data->ec_ref_mixer_path, SND_DEVICE_OUT_HEADPHONES_44_1);
+        else
+            platform_add_backend_name(my_data->ec_ref_mixer_path, snd_device);
+
+        ALOGD("%s: enabling %s", __func__, my_data->ec_ref_mixer_path);
+        audio_route_apply_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
     }
 }
 
@@ -2442,7 +2455,7 @@
                 my_data->fluence_in_voice_call == false) {
                 snd_device = SND_DEVICE_IN_HANDSET_MIC;
                 if (audio_extn_hfp_is_active(adev))
-                    platform_set_echo_reference(adev->platform, true);
+                    platform_set_echo_reference(adev, true, out_device);
             } else {
                 snd_device = SND_DEVICE_IN_VOICE_DMIC;
                 adev->acdb_settings |= DMIC_FLAG;
@@ -2450,7 +2463,7 @@
         } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
             snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
             if (audio_extn_hfp_is_active(adev))
-                platform_set_echo_reference(adev->platform, true);
+                platform_set_echo_reference(adev, true, out_device);
         } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
             if (adev->bt_wb_speech_enabled) {
                 if (adev->bluetooth_nrec)
@@ -2480,7 +2493,7 @@
             } else {
                 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
                 if (audio_extn_hfp_is_active(adev))
-                    platform_set_echo_reference(adev->platform, true);
+                    platform_set_echo_reference(adev, true, out_device);
             }
         } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX)
             snd_device = SND_DEVICE_IN_VOICE_RX;
@@ -2537,7 +2550,7 @@
                 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
                     snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
                 }
-                platform_set_echo_reference(adev->platform, 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) {
@@ -2561,7 +2574,7 @@
                 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
                     snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
                 }
-                platform_set_echo_reference(adev->platform, true);
+                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) {
@@ -2585,9 +2598,9 @@
                 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
                     snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
                 }
-                platform_set_echo_reference(adev->platform,false);
+                platform_set_echo_reference(adev, false, out_device);
             } else
-                platform_set_echo_reference(adev->platform, false);
+                platform_set_echo_reference(adev, false, out_device);
         }
     } else if (source == AUDIO_SOURCE_MIC) {
         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&
@@ -2595,10 +2608,10 @@
             if(my_data->fluence_in_audio_rec) {
                 if(my_data->fluence_type & FLUENCE_QUAD_MIC) {
                     snd_device = SND_DEVICE_IN_HANDSET_QMIC;
-                    platform_set_echo_reference(adev->platform, true);
+                    platform_set_echo_reference(adev, true, out_device);
                 } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
                     snd_device = SND_DEVICE_IN_HANDSET_DMIC;
-                    platform_set_echo_reference(adev->platform, true);
+                    platform_set_echo_reference(adev, true, out_device);
                 }
             }
         }
@@ -3648,9 +3661,11 @@
     ALOGI("%s Codec selected backend: %d current bit width: %d and sample rate: %d",
                __func__, backend_idx, bit_width, sample_rate);
 
-    // For voice calls use default configuration
+    // For voice calls use default configuration i.e. 16b/48K, only applicable to
+    // default backend
     // force routing is not required here, caller will do it anyway
-    if (voice_is_in_call(adev) || adev->mode == AUDIO_MODE_IN_COMMUNICATION) {
+    if ((voice_is_in_call(adev) || adev->mode == AUDIO_MODE_IN_COMMUNICATION) &&
+        backend_idx == DEFAULT_CODEC_BACKEND) {
         ALOGW("%s:Use default bw and sr for voice/voip calls ",__func__);
         bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
         sample_rate =  CODEC_BACKEND_DEFAULT_SAMPLE_RATE;