hal: Add dynamic enablement of AEC/NS for VoIP

Add capability to dynamically enable or disable AEC/NS audio effects
on DSP for a VoIP call.

Bug: 70805651
Test: manual
Change-Id: I16f1f6664b39afaedfca92afbc87002685f6e369
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 481b57d..f03356b 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -72,6 +72,8 @@
 #define TOSTRING_(x) #x
 #define TOSTRING(x) TOSTRING_(x)
 
+#define GET_IN_DEVICE_INDEX(SND_DEVICE) ((SND_DEVICE) - (SND_DEVICE_IN_BEGIN))
+
 struct audio_block_header
 {
     int reserved;
@@ -368,6 +370,32 @@
     [SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE] = "camcorder-mic",
     [SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE] = "camcorder-mic",
     [SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = "camcorder-mic",
+    [SND_DEVICE_IN_SPEAKER_QMIC_NS] = "quad-mic",
+    [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = "quad-mic",
+};
+
+static struct audio_effect_config \
+                  effect_config_table[GET_IN_DEVICE_INDEX(SND_DEVICE_MAX)][EFFECT_COUNT] = {
+    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)][EFFECT_AEC] = \
+                                      {TX_VOICE_FLUENCE_PROV2, 0x0, 0x10EAF, 0x01},
+    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)][EFFECT_NS] = \
+                                      {TX_VOICE_FLUENCE_PROV2,  0x0, 0x10EAF, 0x02},
+    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)][EFFECT_AEC] = \
+                                      {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x01},
+    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)][EFFECT_NS] = \
+                                      {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x02},
+    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)][EFFECT_AEC] = \
+                                      {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x01},
+    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)][EFFECT_NS] = \
+                                      {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x02},
+    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)][EFFECT_AEC] = \
+                                      {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x01},
+    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)][EFFECT_NS] = \
+                                      {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x02},
+    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)][EFFECT_AEC] = \
+                                      {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x01},
+    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)][EFFECT_NS] = \
+                                      {TX_VOICE_FV5ECNS_SM, 0x0, 0x10EAF, 0x02},
 };
 
 /* ACDB IDs (audio DSP path configuration IDs) for each sound device */
@@ -491,6 +519,8 @@
     [SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE] = 61,
     [SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE] = 61,
     [SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = 61,
+    [SND_DEVICE_IN_SPEAKER_QMIC_NS] = 129,
+    [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = 129,
 };
 
 // Platform specific backend bit width table
@@ -627,6 +657,8 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT)},
     /* For legacy xml file parsing */
     {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_NS)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)},
 };
 
 static char * backend_tag_table[SND_DEVICE_MAX] = {0};
@@ -1342,6 +1374,8 @@
     hw_interface_table[SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_DMIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_DMIC_TMUS] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_SPEAKER_QMIC_NS] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_SPEAKER_MIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP] = strdup("SLIMBUS_0_TX");
@@ -2067,6 +2101,57 @@
     return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
 }
 
+int platform_get_effect_config_data(snd_device_t snd_device,
+                                      struct audio_effect_config *effect_config,
+                                      effect_type_t effect_type)
+{
+    int ret = 0;
+
+    if ((snd_device < SND_DEVICE_IN_BEGIN) || (snd_device >= SND_DEVICE_MAX) ||
+        (effect_type <= EFFECT_NONE) || (effect_type >= EFFECT_COUNT)) {
+        ALOGE("%s: Invalid snd_device = %d or effect_type = %d",
+            __func__, snd_device, effect_type);
+        ret = -EINVAL;
+        goto done;
+    }
+
+    if (effect_config == NULL) {
+        ALOGE("%s: Invalid effect_config", __func__);
+        ret = -EINVAL;
+        goto done;
+    }
+
+    ALOGV("%s: snd_device = %d module_id = %d",
+            __func__, snd_device, effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type].module_id);
+    *effect_config = effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type];
+
+done:
+    return ret;
+}
+
+int platform_set_effect_config_data(snd_device_t snd_device,
+                                      struct audio_effect_config effect_config,
+                                      effect_type_t effect_type)
+{
+    int ret = 0;
+
+    if ((snd_device < SND_DEVICE_IN_BEGIN) || (snd_device >= SND_DEVICE_MAX) ||
+        (effect_type <= EFFECT_NONE) || (effect_type >= EFFECT_COUNT)) {
+        ALOGE("%s: Invalid snd_device = %d or effect_type = %d",
+            __func__, snd_device, effect_type);
+        ret = -EINVAL;
+        goto done;
+    }
+
+    ALOGV("%s 0x%x 0x%x 0x%x 0x%x", __func__, effect_config.module_id,
+           effect_config.instance_id, effect_config.param_id,
+           effect_config.param_value);
+    effect_config_table[GET_IN_DEVICE_INDEX(snd_device)][effect_type] = effect_config;
+
+done:
+    return ret;
+}
+
 void platform_add_operator_specific_device(snd_device_t snd_device,
                                            const char *operator,
                                            const char *mixer_path,
@@ -2865,6 +2950,126 @@
     return snd_device;
 }
 
+#ifdef DYNAMIC_ECNS_ENABLED
+static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
+                                                  struct stream_in *in __unused,
+                                                  audio_devices_t out_device,
+                                                  audio_devices_t in_device)
+{
+    struct audio_device *adev = my_data->adev;
+    snd_device_t snd_device = SND_DEVICE_NONE;
+
+    if (my_data->fluence_type != FLUENCE_DISABLE) {
+        switch(AUDIO_DEVICE_BIT_IN | in_device) {
+            case AUDIO_DEVICE_IN_BACK_MIC:
+                if (my_data->fluence_in_spkr_mode) {
+                    if ((my_data->fluence_type & FLUENCE_PRO_ENABLE) &&
+                        (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
+                        snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
+                    } else if (((my_data->fluence_type & FLUENCE_PRO_ENABLE) ||
+                               (my_data->fluence_type & FLUENCE_ENABLE)) &&
+                               (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+                            snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
+                    }
+                    adev->acdb_settings |= DMIC_FLAG;
+                } else
+                    snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
+                break;
+            case AUDIO_DEVICE_IN_BUILTIN_MIC:
+                if (((my_data->fluence_type & FLUENCE_PRO_ENABLE) ||
+                    (my_data->fluence_type & FLUENCE_ENABLE)) &&
+                    (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+                    snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
+                    adev->acdb_settings |= DMIC_FLAG;
+                } else
+                    snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
+                break;
+            default:
+                ALOGE("%s: Unsupported in_device %#x", __func__, in_device);
+                break;
+        }
+        platform_set_echo_reference(adev, true, out_device);
+    }
+
+    return snd_device;
+}
+#else
+static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
+                                                  struct stream_in *in,
+                                                  audio_devices_t out_device,
+                                                  audio_devices_t in_device)
+{
+    struct audio_device *adev = my_data->adev;
+    snd_device_t snd_device = SND_DEVICE_NONE;
+
+    if (in->enable_aec &&
+            in->enable_ns) {
+        if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+            if (my_data->fluence_in_spkr_mode &&
+                    my_data->fluence_in_voice_comm &&
+                    (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+                snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
+            } else {
+                snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
+            }
+        } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+            if (my_data->fluence_in_voice_comm &&
+                    (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+                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;
+        } else if (audio_is_usb_in_device(in_device | AUDIO_DEVICE_BIT_IN)) {
+            snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
+        }
+        platform_set_echo_reference(adev, true, out_device);
+    } else if (in->enable_aec) {
+        if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+            if (my_data->fluence_in_spkr_mode &&
+                    my_data->fluence_in_voice_comm &&
+                    (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+                snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
+            } else {
+                snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
+            }
+        } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+            if (my_data->fluence_in_voice_comm &&
+                    (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+                snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
+            } else {
+                snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
+            }
+       } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+           snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
+       } else if (audio_is_usb_in_device(in_device | AUDIO_DEVICE_BIT_IN)) {
+           snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
+       }
+       platform_set_echo_reference(adev, true, out_device);
+    } else if (in->enable_ns) {
+        if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+            if (my_data->fluence_in_spkr_mode &&
+                    my_data->fluence_in_voice_comm &&
+                    (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+                snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
+            } else {
+                snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
+            }
+        } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+            if (my_data->fluence_in_voice_comm &&
+                    (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+                snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
+            } else {
+                snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
+            }
+        }
+    }
+
+    return snd_device;
+}
+#endif //DYNAMIC_ECNS_ENABLED
+
 snd_device_t platform_get_input_snd_device(void *platform,
                                            struct stream_in *in,
                                            audio_devices_t out_device)
@@ -3091,70 +3296,9 @@
                 !audio_extn_usb_is_capture_supported())) {
             in_device = AUDIO_DEVICE_IN_BACK_MIC;
         }
+
         if (in) {
-            if (in->enable_aec &&
-                    in->enable_ns) {
-                if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
-                    if (my_data->fluence_in_spkr_mode &&
-                            my_data->fluence_in_voice_comm &&
-                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
-                        snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
-                    } else {
-                        snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
-                    }
-                } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
-                    if (my_data->fluence_in_voice_comm &&
-                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
-                        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;
-                } else if (audio_is_usb_in_device(in_device | AUDIO_DEVICE_BIT_IN)) {
-                    snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
-                }
-                platform_set_echo_reference(adev, true, out_device);
-            } else if (in->enable_aec) {
-                if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
-                    if (my_data->fluence_in_spkr_mode &&
-                            my_data->fluence_in_voice_comm &&
-                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
-                        snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
-                    } else {
-                        snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
-                    }
-                } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
-                    if (my_data->fluence_in_voice_comm &&
-                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
-                        snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
-                    } else {
-                        snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
-                    }
-               } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
-                   snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
-               } else if (audio_is_usb_in_device(in_device | AUDIO_DEVICE_BIT_IN)) {
-                   snd_device = SND_DEVICE_IN_USB_HEADSET_MIC_AEC;
-               }
-               platform_set_echo_reference(adev, true, out_device);
-            } else if (in->enable_ns) {
-                if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
-                    if (my_data->fluence_in_spkr_mode &&
-                            my_data->fluence_in_voice_comm &&
-                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
-                        snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
-                    } else {
-                        snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
-                    }
-                } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
-                    if (my_data->fluence_in_voice_comm &&
-                            (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
-                        snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
-                    } else {
-                        snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
-                    }
-                }
-            }
+            snd_device = get_snd_device_for_voice_comm(my_data, in, out_device, in_device);
         }
     } else if (source == AUDIO_SOURCE_DEFAULT) {
         goto exit;
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index f6c5a58..a885f27 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -190,6 +190,8 @@
     SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE,
     SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE,
     SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT,
+    SND_DEVICE_IN_SPEAKER_QMIC_NS,
+    SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS,
     SND_DEVICE_IN_END,
 
     SND_DEVICE_MAX = SND_DEVICE_IN_END,
@@ -343,6 +345,11 @@
 #define HFP_ASM_RX_TX 24
 #endif
 
+#define TX_VOICE_FLUENCE_PROV2 0x10F17
+#define TX_VOICE_DM_FV5_BROADSIDE 0x10F18
+#define TX_VOICE_FV5ECNS_SM 0x10F09
+#define TX_VOICE_FV5ECNS_DM 0x10F0A
+
 #define LIB_CSD_CLIENT "libcsd-client.so"
 #define LIB_MDM_DETECT "libmdmdetect.so"