hal: add external echo reference to ecns-hfp calls

* Add ec_car_state to switch between single-mic
  and multi-mic ecns hfp calls.
* Add the capability to have an echo reference for
  both single-mic and multi-mic ecns hfp call.
* New snd device is introduced for multi-mic ecns hfp.

Change-Id: I5a8c869cf6854020e15efb61cbaf78f3f027e1ee
Signed-off-by: Guodong Hu <guodhu@codeaurora.org>
Signed-off-by: Derek Chen <chenche@codeaurora.org>
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index 62eb9e6..e646bc1 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -83,6 +83,7 @@
     struct pcm *hfp_sco_tx;
     struct pcm *hfp_pcm_rx;
     struct pcm *hfp_pcm_tx;
+    struct pcm *hfp_ext_ec_tx;
     bool is_hfp_running;
     float hfp_volume;
     int32_t hfp_pcm_dev_id;
@@ -96,6 +97,7 @@
     .hfp_sco_tx = NULL,
     .hfp_pcm_rx = NULL,
     .hfp_pcm_tx = NULL,
+    .hfp_ext_ec_tx = NULL,
     .is_hfp_running = 0,
     .hfp_volume = 0,
     .hfp_pcm_dev_id = HFP_ASM_RX_TX,
@@ -288,6 +290,7 @@
     int32_t ret = 0;
     struct audio_usecase *uc_info;
     int32_t pcm_dev_rx_id, pcm_dev_tx_id, pcm_dev_asm_rx_id, pcm_dev_asm_tx_id;
+    int32_t pcm_ext_ec_ref_id;
 
     ALOGD("%s: enter", __func__);
 
@@ -396,6 +399,27 @@
         goto exit;
     }
 
+#ifdef PLATFORM_AUTO
+    /* echo reference path for single-mic/multi-mic surround ECNS hfp calls */
+    pcm_ext_ec_ref_id = HFP_EXT_EC_REF_TX;
+    ALOGD("%s: Opening PCM capture device card_id(%d) device_id(%d)",
+            __func__, adev->snd_card, pcm_ext_ec_ref_id);
+    hfpmod.hfp_ext_ec_tx = pcm_open(adev->snd_card,
+                                    pcm_ext_ec_ref_id,
+                                    PCM_IN, &pcm_config_hfp);
+    if (hfpmod.hfp_ext_ec_tx && !pcm_is_ready(hfpmod.hfp_ext_ec_tx)) {
+        ALOGE("%s: %s", __func__, pcm_get_error(hfpmod.hfp_ext_ec_tx));
+        ret = -EIO;
+        goto exit;
+    }
+
+    if (pcm_start(hfpmod.hfp_ext_ec_tx) < 0) {
+        ALOGE("%s: pcm start for hfp ext ec tx failed", __func__);
+        ret = -EINVAL;
+        goto exit;
+    }
+#endif
+
     hfpmod.is_hfp_running = true;
     hfp_set_volume(adev, hfpmod.hfp_volume);
 
@@ -438,6 +462,14 @@
         hfpmod.hfp_pcm_tx = NULL;
     }
 
+#ifdef PLATFORM_AUTO
+    /* echo reference path for single-mic/multi-mic surround ECNS hfp calls */
+    if (hfpmod.hfp_ext_ec_tx) {
+        pcm_close(hfpmod.hfp_ext_ec_tx);
+        hfpmod.hfp_ext_ec_tx = NULL;
+    }
+#endif
+
     uc_info = fp_get_usecase_from_list(adev, hfpmod.ucid);
     if (uc_info == NULL) {
         ALOGE("%s: Could not find the usecase (%d) in the list",