hal: Add EC reference changes for FFV

- Add changes to set EC reference device for FFV.

CRs-Fixed: 2225936
Change-Id: Ife05d9069db2880473f8e6d06ab284c011f935ae
diff --git a/hal/Android.mk b/hal/Android.mk
index ba9f2b3..91e4973 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -429,6 +429,16 @@
     LOCAL_STATIC_LIBRARIES := libhealthhalutils
 endif
 
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_KEEP_ALIVE_ARM_FFV)), true)
+    LOCAL_CFLAGS += -DRUN_KEEP_ALIVE_IN_ARM_FFV
+endif
+
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_FFV)), true)
+    LOCAL_CFLAGS += -DFFV_ENABLED
+    LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio-noship/include/ffv
+    LOCAL_SRC_FILES += audio_extn/ffv.c
+endif
+
 LOCAL_CFLAGS += -Wall -Werror
 
 LOCAL_COPY_HEADERS_TO   := mm-audio
diff --git a/hal/audio_extn/ffv.c b/hal/audio_extn/ffv.c
index 027849c..e86f434 100644
--- a/hal/audio_extn/ffv.c
+++ b/hal/audio_extn/ffv.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -45,6 +45,7 @@
 #include <cutils/log.h>
 #include <pthread.h>
 #include <sys/resource.h>
+#include <unistd.h>
 
 #include "audio_hw.h"
 #include "audio_extn.h"
@@ -59,14 +60,29 @@
 #define AUDIO_PARAMETER_FFV_EC_REF_DEVICE "ffv_ec_ref_dev"
 #define AUDIO_PARAMETER_FFV_CHANNEL_INDEX "ffv_channel_index"
 
-#define FFV_LIB "libffv.so"
+#if LINUX_ENABLED
 #define FFV_CONFIG_FILE_PATH "/etc/BF_1out.cfg"
+#ifdef __LP64__
+#define FFV_LIB "/usr/lib64/libffv.so"
+#else
+#define FFV_LIB "/usr/lib/libffv.so"
+#endif
+#else
+#define FFV_CONFIG_FILE_PATH "/vendor/etc/BF_1out.cfg"
+#ifdef __LP64__
+#define FFV_LIB "/vendor/lib64/libffv.so"
+#else
+#define FFV_LIB "/vendor/lib/libffv.so"
+#endif
+#endif
+
 #define FFV_SAMPLING_RATE_16000 16000
 #define FFV_EC_REF_LOOPBACK_DEVICE_MONO "ec-ref-loopback-mono"
 #define FFV_EC_REF_LOOPBACK_DEVICE_STEREO "ec-ref-loopback-stereo"
 
 #define FFV_CHANNEL_MODE_MONO 1
 #define FFV_CHANNEL_MODE_STEREO 2
+#define FFV_CHANNEL_MODE_QUAD 4
 #define FFV_CHANNEL_MODE_HEX 6
 #define FFV_CHANNEL_MODE_OCT 8
 
@@ -392,7 +408,7 @@
     config->period_size = ffvmod.capture_config.period_size;
 }
 
-int32_t audio_extn_ffv_init(struct audio_device *adev)
+int32_t audio_extn_ffv_init(struct audio_device *adev __unused)
 {
     int ret = 0;
 
@@ -472,7 +488,7 @@
            __func__, num_ec_ref_ch, num_tx_in_ch, num_out_ch, frame_len, sample_rate);
     ALOGD("%s: config file path %s", __func__, config_file_path);
     status_type = ffv_init_fn(&ffvmod.handle, num_tx_in_ch, num_out_ch, num_ec_ref_ch,
-                      frame_len, sample_rate, config_file_path, sm_buffer, 0,
+                      frame_len, sample_rate, config_file_path, (char *)sm_buffer, 0,
                       &total_mem_size);
     if (status_type) {
         ALOGE("%s: ERROR. ffv_init returned %d", __func__, status_type);
@@ -565,6 +581,8 @@
         return SND_DEVICE_IN_HANDSET_8MIC;
     } else if (ffvmod.capture_config.channels == FFV_CHANNEL_MODE_HEX) {
         return SND_DEVICE_IN_HANDSET_6MIC;
+    } else if (ffvmod.capture_config.channels == FFV_CHANNEL_MODE_QUAD) {
+        return SND_DEVICE_IN_HANDSET_QMIC;
     } else {
         ALOGE("%s: Invalid channels configured for capture", __func__);
         return SND_DEVICE_NONE;
@@ -572,7 +590,7 @@
 }
 
 int audio_extn_ffv_init_ec_ref_loopback(struct audio_device *adev,
-                                        snd_device_t snd_device)
+                                        snd_device_t snd_device __unused)
 {
     struct audio_usecase *uc_info_tx = NULL;
     snd_device_t in_snd_device;
@@ -664,7 +682,7 @@
 }
 
 int audio_extn_ffv_deinit_ec_ref_loopback(struct audio_device *adev,
-                                          snd_device_t snd_device)
+                                          snd_device_t snd_device __unused)
 {
     struct audio_usecase *uc_info_tx = NULL;
     snd_device_t in_snd_device;
@@ -694,7 +712,7 @@
     return ret;
 }
 
-int32_t audio_extn_ffv_read(struct audio_stream_in *stream,
+int32_t audio_extn_ffv_read(struct audio_stream_in *stream __unused,
                        void *buffer, size_t bytes)
 {
     int status = 0;
@@ -702,7 +720,7 @@
     int16_t *process_ec_ref_ptr = NULL;
     size_t in_buf_size, out_buf_size, bytes_to_copy;
     int retry_num = 0;
-    int i, j, ch;
+    int i, ch;
     int total_in_ch, in_ch, ec_ref_ch;
 
     if (!ffvmod.ffv_lib_handle) {
@@ -790,7 +808,7 @@
         total_in_ch = ffvmod.capture_config.channels;
         ec_ref_ch = ffvmod.ec_ref_config.channels;
         in_ch = total_in_ch - ec_ref_ch;
-        for (i = 0; i < ffvmod.capture_config.period_size; i++) {
+        for (i = 0; i < (int)ffvmod.capture_config.period_size; i++) {
             for (ch = 0; ch < in_ch; ch++) {
                 process_in_ptr[i*in_ch+ch] =
                           in_ptr[i*total_in_ch+ch];
@@ -810,7 +828,7 @@
     bytes_to_copy = (bytes <= out_buf_size) ? bytes : out_buf_size;
     memcpy(buffer, process_out_ptr, bytes_to_copy);
     if (bytes_to_copy != out_buf_size)
-        ALOGD("%s: out buffer data dropped, copied %d bytes",
+        ALOGD("%s: out buffer data dropped, copied %zu bytes",
                __func__, bytes_to_copy);
 
 #ifdef FFV_PCM_DUMP
@@ -831,7 +849,6 @@
 void audio_extn_ffv_set_parameters(struct audio_device *adev __unused,
                                    struct str_parms *parms)
 {
-    int err;
     int val;
     int ret = 0;
     char value[128];
@@ -876,10 +893,15 @@
                 ALOGE("%s: Invalid ec ref", __func__);
             }
         }
-
-        ret = str_parms_get_int(parms, AUDIO_PARAMETER_FFV_EC_REF_DEVICE, &val);
-        if (ret >= 0) {
+        ret = -1;
+        if (str_parms_get_int(parms, AUDIO_PARAMETER_FFV_EC_REF_DEVICE, &val) >= 0) {
+            ret = 1;
             str_parms_del(parms, AUDIO_PARAMETER_FFV_EC_REF_DEVICE);
+        } else if (str_parms_get_int(parms, AUDIO_PARAMETER_DEVICE_CONNECT, &val) >= 0) {
+            ret = 1;
+            str_parms_del(parms, AUDIO_PARAMETER_DEVICE_CONNECT);
+        }
+        if (ret == 1) {
             if (val & AUDIO_DEVICE_OUT_SPEAKER) {
                 ALOGD("%s: capture ec ref from speaker", __func__);
                 ffvmod.ec_ref_dev = AUDIO_DEVICE_OUT_SPEAKER;
@@ -891,6 +913,15 @@
             }
         }
 
+        ret = str_parms_get_int(parms, AUDIO_PARAMETER_DEVICE_DISCONNECT, &val);
+        if (ret >= 0) {
+            str_parms_del(parms, AUDIO_PARAMETER_DEVICE_DISCONNECT);
+            if (val & AUDIO_DEVICE_OUT_LINE) {
+                ALOGD("%s: capture ec ref from speaker", __func__);
+                ffvmod.ec_ref_dev = AUDIO_DEVICE_OUT_SPEAKER;
+            }
+        }
+
         ret = str_parms_get_int(parms, AUDIO_PARAMETER_FFV_CHANNEL_INDEX, &val);
         if (ret >= 0) {
             str_parms_del(parms, AUDIO_PARAMETER_FFV_CHANNEL_INDEX);
diff --git a/hal/audio_extn/soundtrigger.c b/hal/audio_extn/soundtrigger.c
index a233bad..a728bd8 100644
--- a/hal/audio_extn/soundtrigger.c
+++ b/hal/audio_extn/soundtrigger.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, 2016-2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 2016-2019 The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -581,13 +581,15 @@
     }
 
     ret = str_parms_get_int(params, AUDIO_PARAMETER_DEVICE_CONNECT, &val);
-    if ((ret >= 0) && audio_is_input_device(val)) {
+    if ((ret >= 0) && (audio_is_input_device(val) ||
+           (val == AUDIO_DEVICE_OUT_LINE))) {
         event.u.value = val;
         st_dev->st_callback(AUDIO_EVENT_DEVICE_CONNECT, &event);
     }
 
     ret = str_parms_get_int(params, AUDIO_PARAMETER_DEVICE_DISCONNECT, &val);
-    if ((ret >= 0) && audio_is_input_device(val)) {
+    if ((ret >= 0) && (audio_is_input_device(val) ||
+           (val == AUDIO_DEVICE_OUT_LINE))) {
         event.u.value = val;
         st_dev->st_callback(AUDIO_EVENT_DEVICE_DISCONNECT, &event);
     }
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 7d6db15..91f2a74 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -1116,7 +1116,8 @@
                                               "true-native-mode");
             adev->native_playback_enabled = true;
         }
-        if ((snd_device == SND_DEVICE_IN_HANDSET_6MIC) &&
+        if (((snd_device == SND_DEVICE_IN_HANDSET_6MIC) ||
+            (snd_device == SND_DEVICE_IN_HANDSET_QMIC)) &&
             (audio_extn_ffv_get_stream() == adev->active_input)) {
             ALOGD("%s: init ec ref loopback", __func__);
             audio_extn_ffv_init_ec_ref_loopback(adev, snd_device);