Merge "configs: Add support for QSSI"
diff --git a/Android.mk b/Android.mk
index 060bee6..6aa0e8d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,5 +1,5 @@
 ifneq ($(AUDIO_USE_STUB_HAL), true)
-ifneq ($(filter mpq8092 msm8960 msm8226 msm8x26 msm8610 msm8974 msm8x74 apq8084 msm8916 msm8994 msm8992 msm8909 msm8996 msm8952 msm8937 thorium msm8953 msmgold msm8998 sdm660 sdm845 sdm710 apq8098_latv qcs605 msmnile $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter mpq8092 msm8960 msm8226 msm8x26 msm8610 msm8974 msm8x74 apq8084 msm8916 msm8994 msm8992 msm8909 msm8996 msm8952 msm8937 thorium msm8953 msmgold msm8998 sdm660 sdm845 sdm710 apq8098_latv qcs605 msmnile kona $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
 
 MY_LOCAL_PATH := $(call my-dir)
 
@@ -11,6 +11,7 @@
 else
 include $(MY_LOCAL_PATH)/hal/Android.mk
 endif
+include $(MY_LOCAL_PATH)/hal/audio_extn/Android.mk
 include $(MY_LOCAL_PATH)/voice_processing/Android.mk
 include $(MY_LOCAL_PATH)/mm-audio/Android.mk
 include $(MY_LOCAL_PATH)/visualizer/Android.mk
diff --git a/configs/apq8098_latv/apq8098_latv.mk b/configs/apq8098_latv/apq8098_latv.mk
index b5cdcd9..103fd6a 100644
--- a/configs/apq8098_latv/apq8098_latv.mk
+++ b/configs/apq8098_latv/apq8098_latv.mk
@@ -39,7 +39,7 @@
 
 USE_XML_AUDIO_POLICY_CONF := 1
 BOARD_SUPPORTS_SOUND_TRIGGER := true
-AUDIO_USE_LL_AS_PRIMARY_OUTPUT := true
+AUDIO_USE_DEEP_AS_PRIMARY_OUTPUT := false
 AUDIO_FEATURE_ENABLED_VBAT_MONITOR := true
 AUDIO_FEATURE_ENABLED_ANC_HEADSET := true
 AUDIO_FEATURE_ENABLED_CUSTOMSTEREO := true
@@ -76,45 +76,45 @@
 ##AUDIO_FEATURE_FLAGS
 
 #Audio Specific device overlays
-DEVICE_PACKAGE_OVERLAYS += hardware/qcom/audio/configs/common/overlay
+DEVICE_PACKAGE_OVERLAYS += vendor/qcom/opensource/audio-hal/primary-hal/configs/common/overlay
 
 # Audio configuration file
 ifeq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 PRODUCT_COPY_FILES += \
-    device/qcom/common/media/audio_policy.conf:system/etc/audio_policy.conf
+    device/qcom/common/media/audio_policy.conf:vendor/etc/audio_policy.conf
 else
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/apq8098_latv/audio_policy.conf:system/etc/audio_policy.conf
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/apq8098_latv/audio_policy.conf:vendor/etc/audio_policy.conf
 endif
 
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msm8998/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf \
-    hardware/qcom/audio/configs/msm8998/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
-    hardware/qcom/audio/configs/msm8998/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths_tasha.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tasha.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths_tavil.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tavil.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths_skuk.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skuk.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths_skuk.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qvr.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths_dtp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_dtp.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_i2s.xml \
-    hardware/qcom/audio/configs/msm8998/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt \
-    hardware/qcom/audio/configs/msm8998/audio_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tavil.txt \
-    hardware/qcom/audio/configs/msm8998/audio_platform_info_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_i2s.xml \
-    hardware/qcom/audio/configs/msm8998/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
-    hardware/qcom/audio/configs/msm8998/sound_trigger_mixer_paths_wcd9330.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9330.xml \
-    hardware/qcom/audio/configs/msm8998/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
-    hardware/qcom/audio/configs/msm8998/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
-    hardware/qcom/audio/configs/msm8998/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml \
-    hardware/qcom/audio/configs/msm8998/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/mixer_paths_tasha.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tasha.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/mixer_paths_tavil.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tavil.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/mixer_paths_skuk.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skuk.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/mixer_paths_skuk.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qvr.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/mixer_paths_dtp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_dtp.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/mixer_paths_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_i2s.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/audio_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tavil.txt \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/audio_platform_info_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_i2s.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/sound_trigger_mixer_paths_wcd9330.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9330.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml
 
 #XML Audio configuration files
 ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
 ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/apq8098_latv/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/apq8098_latv/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
 endif
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/a2dp_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_volumes.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
@@ -124,7 +124,7 @@
 
 # Listen configuration file
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msm8998/listen_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/listen_platform_info.xml
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/listen_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/listen_platform_info.xml
 
 # Reduce client buffer size for fast audio output tracks
 PRODUCT_PROPERTY_OVERRIDES += \
@@ -268,6 +268,14 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 ro.af.client_heap_size_kbyte=7168
 
+#enable headset calibration
+PRODUCT_PROPERTY_OVERRIDES += \
+audio.volume.headset.gain.depcal=true
+
+#enable dualmic fluence for voice communication
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.audio.fluence.voicecomm=true
+
 # for HIDL related packages
 PRODUCT_PACKAGES += \
     android.hardware.audio@2.0-service \
diff --git a/configs/kona/audio_platform_info.xml b/configs/kona/audio_platform_info.xml
index 9dd4cfc..8e53710 100644
--- a/configs/kona/audio_platform_info.xml
+++ b/configs/kona/audio_platform_info.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
-<!-- Copyright (c) 2014, 2016-2018, The Linux Foundation. All rights reserved. -->
+<!-- Copyright (c) 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 -->
@@ -209,8 +209,8 @@
         <device name="SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_IN_AANC_HANDSET_MIC" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_IN_QUAD_MIC" interface="TX_CDC_DMA_TX_3"/>
-        <device name="SND_DEVICE_IN_HANDSET_STEREO_DMIC" interface="TX_CDC_DMA_TX_3"/>
-        <device name="SND_DEVICE_IN_SPEAKER_STEREO_DMIC" interface="TX_CDC_DMA_TX_3"/>
+        <device name="SND_DEVICE_IN_HANDSET_DMIC_STEREO" interface="TX_CDC_DMA_TX_3"/>
+        <device name="SND_DEVICE_IN_SPEAKER_DMIC_STEREO" interface="TX_CDC_DMA_TX_3"/>
         <device name="SND_DEVICE_IN_CAPTURE_VI_FEEDBACK" interface="WSA_CDC_DMA_TX_0"/>
         <device name="SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_1" interface="WSA_CDC_DMA_TX_0"/>
         <device name="SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_2" interface="WSA_CDC_DMA_TX_0"/>
@@ -423,13 +423,13 @@
                         <mic_info mic_device_id="builtin_mic_4"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                     </snd_dev>
-                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_STEREO_DMIC">
+                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_DMIC_STEREO">
                         <mic_info mic_device_id="builtin_mic_1"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                         <mic_info mic_device_id="builtin_mic_2"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                     </snd_dev>
-                    <snd_dev in_snd_device="SND_DEVICE_IN_SPEAKER_STEREO_DMIC">
+                    <snd_dev in_snd_device="SND_DEVICE_IN_SPEAKER_DMIC_STEREO">
                         <mic_info mic_device_id="builtin_mic_1"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                         <mic_info mic_device_id="builtin_mic_2"
diff --git a/configs/kona/kona.mk b/configs/kona/kona.mk
index 93e4ca0..bc1782e 100644
--- a/configs/kona/kona.mk
+++ b/configs/kona/kona.mk
@@ -30,8 +30,8 @@
 MM_AUDIO_ENABLED_SAFX := true
 AUDIO_FEATURE_ENABLED_HW_ACCELERATED_EFFECTS := false
 AUDIO_FEATURE_ENABLED_AUDIOSPHERE := true
-AUDIO_FEATURE_ENABLED_USB_TUNNEL_AUDIO := true
-AUDIO_FEATURE_ENABLED_SPLIT_A2DP := true
+AUDIO_FEATURE_ENABLED_USB_TUNNEL := true
+AUDIO_FEATURE_ENABLED_A2DP_OFFLOAD := true
 AUDIO_FEATURE_ENABLED_3D_AUDIO := false
 DOLBY_ENABLE := false
 endif
@@ -40,7 +40,7 @@
 AUDIO_FEATURE_ENABLED_DLKM := true
 BOARD_SUPPORTS_SOUND_TRIGGER := true
 AUDIO_FEATURE_ENABLED_INSTANCE_ID := true
-AUDIO_USE_LL_AS_PRIMARY_OUTPUT := true
+AUDIO_USE_DEEP_AS_PRIMARY_OUTPUT := false
 AUDIO_FEATURE_ENABLED_VBAT_MONITOR := true
 AUDIO_FEATURE_ENABLED_ANC_HEADSET := true
 AUDIO_FEATURE_ENABLED_CUSTOMSTEREO := true
@@ -70,28 +70,28 @@
 ##AUDIO_FEATURE_FLAGS
 
 #Audio Specific device overlays
-DEVICE_PACKAGE_OVERLAYS += hardware/qcom/audio/configs/common/overlay
+DEVICE_PACKAGE_OVERLAYS += vendor/qcom/opensource/audio-hal/primary-hal/configs/common/overlay
 
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/kona/audio_io_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_io_policy.conf \
-    hardware/qcom/audio/configs/kona/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
-    hardware/qcom/audio/configs/kona/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
-    hardware/qcom/audio/configs/kona/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
-    hardware/qcom/audio/configs/kona/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
-    hardware/qcom/audio/configs/kona/audio_platform_info_qrd.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_qrd.xml \
-    hardware/qcom/audio/configs/kona/audio_platform_info_intcodec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_intcodec.xml \
-    hardware/qcom/audio/configs/kona/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
-    hardware/qcom/audio/configs/kona/sound_trigger_mixer_paths_qrd.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_qrd.xml \
-    hardware/qcom/audio/configs/kona/mixer_paths_mtp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_mtp.xml \
-    hardware/qcom/audio/configs/kona/mixer_paths_qrd.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/kona/audio_io_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_io_policy.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/kona/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/kona/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/kona/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/kona/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/kona/audio_platform_info_qrd.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_qrd.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/kona/audio_platform_info_intcodec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_intcodec.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/kona/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/kona/sound_trigger_mixer_paths_qrd.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_qrd.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/kona/mixer_paths_mtp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_mtp.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/kona/mixer_paths_qrd.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd.xml \
 
 #XML Audio configuration files
 ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/kona/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/kona/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
 endif
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/a2dp_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_volumes.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
@@ -182,6 +182,18 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 persist.vendor.bt.a2dp_offload_cap=sbc-aptx-aptxtws-aptxhd-aac
 
+# A2DP offload support
+PRODUCT_PROPERTY_OVERRIDES += \
+ro.bluetooth.a2dp_offload.supported=true
+
+# Disable A2DP offload
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bluetooth.a2dp_offload.disabled=false
+
+# A2DP offload DSP supported encoder list
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bluetooth.a2dp_offload.cap=sbc-aac-aptx-aptxhd-ldac
+
 #enable software decoders for ALAC and APE
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.use.sw.alac.decoder=true
@@ -216,6 +228,14 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.adm.buffering.ms=2
 
+#enable headset calibration
+PRODUCT_PROPERTY_OVERRIDES += \
+audio.volume.headset.gain.depcal=true
+
+#enable dualmic fluence for voice communication
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.audio.fluence.voicecomm=true
+
 # for HIDL related packages
 PRODUCT_PACKAGES += \
     android.hardware.audio@2.0-service \
diff --git a/configs/msm8909/msm8909.mk b/configs/msm8909/msm8909.mk
index da2314b..4b9e935 100644
--- a/configs/msm8909/msm8909.mk
+++ b/configs/msm8909/msm8909.mk
@@ -50,7 +50,7 @@
 ##AUDIO_FEATURE_FLAGS
 
 #Audio Specific device overlays
-DEVICE_PACKAGE_OVERLAYS += hardware/qcom/audio/configs/common/overlay
+DEVICE_PACKAGE_OVERLAYS += vendor/qcom/opensource/audio-hal/primary-hal/configs/common/overlay
 
 
 # Audio configuration file
@@ -59,37 +59,37 @@
     device/qcom/common/media/audio_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy.conf
 else
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msm8909/audio_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy.conf
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/audio_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy.conf
 endif
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msm8909/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
-    hardware/qcom/audio/configs/msm8909/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
-    hardware/qcom/audio/configs/msm8909/mixer_paths_qrd_skuh.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skuh.xml \
-    hardware/qcom/audio/configs/msm8909/mixer_paths_qrd_skui.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skui.xml \
-    hardware/qcom/audio/configs/msm8909/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
-    hardware/qcom/audio/configs/msm8909/mixer_paths_msm8909_pm8916.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_msm8909_pm8916.xml \
-    hardware/qcom/audio/configs/msm8909/mixer_paths_wcd9326_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9326_i2s.xml \
-    hardware/qcom/audio/configs/msm8909/mixer_paths_wcd9326_i2s_tdm.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9326_i2s_tdm.xml \
-    hardware/qcom/audio/configs/msm8909/mixer_paths_skua.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skua.xml \
-    hardware/qcom/audio/configs/msm8909/mixer_paths_skuc.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skuc.xml \
-    hardware/qcom/audio/configs/msm8909/mixer_paths_skue.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skue.xml \
-    hardware/qcom/audio/configs/msm8909/mixer_paths_qrd_skut.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skut.xml \
-    hardware/qcom/audio/configs/msm8909/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
-    hardware/qcom/audio/configs/msm8909/sound_trigger_mixer_paths_wcd9326.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9326.xml \
-    hardware/qcom/audio/configs/msm8909/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
-    hardware/qcom/audio/configs/msm8909/sound_trigger_mixer_paths_wcd9335.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9335.xml \
-    hardware/qcom/audio/configs/msm8909/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
-    hardware/qcom/audio/configs/msm8909/audio_platform_info_extcodec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_extcodec.xml \
-    hardware/qcom/audio/configs/msm8909/audio_io_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_io_policy.conf
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/mixer_paths_qrd_skuh.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skuh.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/mixer_paths_qrd_skui.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skui.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/mixer_paths_msm8909_pm8916.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_msm8909_pm8916.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/mixer_paths_wcd9326_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9326_i2s.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/mixer_paths_wcd9326_i2s_tdm.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9326_i2s_tdm.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/mixer_paths_skua.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skua.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/mixer_paths_skuc.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skuc.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/mixer_paths_skue.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skue.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/mixer_paths_qrd_skut.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skut.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/sound_trigger_mixer_paths_wcd9326.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9326.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/sound_trigger_mixer_paths_wcd9335.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9335.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/audio_platform_info_extcodec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_extcodec.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/audio_io_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_io_policy.conf
 
 #XML Audio configuration files
 ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
 ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/msm8909/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8909/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
 endif
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/a2dp_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_volumes.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
@@ -169,6 +169,10 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 persist.vendor.bt.enable.splita2dp=false
 
+#enable headset calibration
+PRODUCT_PROPERTY_OVERRIDES += \
+audio.volume.headset.gain.depcal=true
+
 PRODUCT_PACKAGES += \
     android.hardware.audio@2.0-service \
     android.hardware.audio@2.0-impl \
diff --git a/configs/msm8937/msm8937.mk b/configs/msm8937/msm8937.mk
index 14da110..76fa4f3 100644
--- a/configs/msm8937/msm8937.mk
+++ b/configs/msm8937/msm8937.mk
@@ -35,7 +35,7 @@
 
 USE_XML_AUDIO_POLICY_CONF := 1
 BOARD_SUPPORTS_SOUND_TRIGGER := true
-AUDIO_USE_LL_AS_PRIMARY_OUTPUT := true
+AUDIO_USE_DEEP_AS_PRIMARY_OUTPUT := false
 AUDIO_FEATURE_ENABLED_HIFI_AUDIO := true
 AUDIO_FEATURE_ENABLED_VBAT_MONITOR := true
 AUDIO_FEATURE_ENABLED_NT_PAUSE_TIMEOUT := true
@@ -66,7 +66,7 @@
 ##AUDIO_FEATURE_FLAGS
 
 #Audio Specific device overlays
-DEVICE_PACKAGE_OVERLAYS += hardware/qcom/audio/configs/common/overlay
+DEVICE_PACKAGE_OVERLAYS += vendor/qcom/opensource/audio-hal/primary-hal/configs/common/overlay
 
 # Audio configuration file
 ifeq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
@@ -74,45 +74,45 @@
     device/qcom/common/media/audio_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy.conf
 else
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msm8937/audio_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy.conf
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/audio_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy.conf
 endif
 
 PRODUCT_COPY_FILES +=\
-hardware/qcom/audio/configs/msm8937/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf\
-hardware/qcom/audio/configs/msm8937/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf\
-hardware/qcom/audio/configs/msm8937/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
-hardware/qcom/audio/configs/msm8937/mixer_paths_mtp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_mtp.xml \
-hardware/qcom/audio/configs/msm8937/mixer_paths_sdm439_pm8953.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_sdm439_pm8953.xml \
-hardware/qcom/audio/configs/msm8937/mixer_paths_qrd_skuh.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skuh.xml \
-hardware/qcom/audio/configs/msm8937/mixer_paths_qrd_skui.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skui.xml \
-hardware/qcom/audio/configs/msm8937/mixer_paths_qrd_skuhf.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skuhf.xml \
-hardware/qcom/audio/configs/msm8937/mixer_paths_wcd9306.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9306.xml \
-hardware/qcom/audio/configs/msm8937/mixer_paths_skuk.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skuk.xml \
-hardware/qcom/audio/configs/msm8937/mixer_paths_qrd_skum.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skum.xml \
-hardware/qcom/audio/configs/msm8937/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
-hardware/qcom/audio/configs/msm8937/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
-hardware/qcom/audio/configs/msm8937/sound_trigger_mixer_paths_wcd9306.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9306.xml \
-hardware/qcom/audio/configs/msm8937/sound_trigger_mixer_paths_wcd9330.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9330.xml \
-hardware/qcom/audio/configs/msm8937/sound_trigger_mixer_paths_wcd9335.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9335.xml \
-hardware/qcom/audio/configs/msm8937/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
-hardware/qcom/audio/configs/msm8937/mixer_paths_wcd9330.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9330.xml \
-hardware/qcom/audio/configs/msm8937/mixer_paths_wcd9335.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9335.xml \
-hardware/qcom/audio/configs/msm8937/mixer_paths_wcd9326.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9326.xml \
-hardware/qcom/audio/configs/msm8937/mixer_paths_qrd_skun.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skun.xml \
-hardware/qcom/audio/configs/msm8937/mixer_paths_qrd_sku1.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_sku1.xml \
-hardware/qcom/audio/configs/msm8937/mixer_paths_qrd_sku2.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_sku2.xml \
-hardware/qcom/audio/configs/msm8937/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
-hardware/qcom/audio/configs/msm8937/audio_platform_info_extcodec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_extcodec.xml \
-hardware/qcom/audio/configs/msm8937/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf\
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf\
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/mixer_paths_mtp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_mtp.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/mixer_paths_sdm439_pm8953.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_sdm439_pm8953.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/mixer_paths_qrd_skuh.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skuh.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/mixer_paths_qrd_skui.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skui.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/mixer_paths_qrd_skuhf.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skuhf.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/mixer_paths_wcd9306.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9306.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/mixer_paths_skuk.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skuk.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/mixer_paths_qrd_skum.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skum.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/sound_trigger_mixer_paths_wcd9306.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9306.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/sound_trigger_mixer_paths_wcd9330.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9330.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/sound_trigger_mixer_paths_wcd9335.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9335.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/mixer_paths_wcd9330.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9330.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/mixer_paths_wcd9335.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9335.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/mixer_paths_wcd9326.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9326.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/mixer_paths_qrd_skun.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skun.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/mixer_paths_qrd_sku1.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_sku1.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/mixer_paths_qrd_sku2.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_sku2.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/audio_platform_info_extcodec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_extcodec.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt
 
 #XML Audio configuration files
 ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
 ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/msm8937/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8937/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
 endif
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/a2dp_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_volumes.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
@@ -242,6 +242,10 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 persist.vendor.bt.enable.splita2dp=false
 
+#enable headset calibration
+PRODUCT_PROPERTY_OVERRIDES += \
+audio.volume.headset.gain.depcal=true
+
 # for HIDL related packages
 PRODUCT_PACKAGES += \
     android.hardware.audio@2.0-service \
diff --git a/configs/msm8953/msm8953.mk b/configs/msm8953/msm8953.mk
index 95e6ab9..7715dd0 100644
--- a/configs/msm8953/msm8953.mk
+++ b/configs/msm8953/msm8953.mk
@@ -38,7 +38,7 @@
 AUDIO_FEATURE_ENABLED_FFV := true
 AUDIO_FEATURE_ENABLED_KEEP_ALIVE_ARM_FFV := true
 AUDIO_FEATURE_ENABLED_KEEP_ALIVE := true
-AUDIO_USE_LL_AS_PRIMARY_OUTPUT := true
+AUDIO_USE_DEEP_AS_PRIMARY_OUTPUT := false
 AUDIO_FEATURE_ENABLED_HIFI_AUDIO := true
 AUDIO_FEATURE_ENABLED_VBAT_MONITOR := true
 AUDIO_FEATURE_ENABLED_NT_PAUSE_TIMEOUT := true
@@ -72,7 +72,7 @@
 ##AUDIO_FEATURE_FLAGS
 
 #Audio Specific device overlays
-DEVICE_PACKAGE_OVERLAYS += hardware/qcom/audio/configs/common/overlay
+DEVICE_PACKAGE_OVERLAYS += vendor/qcom/opensource/audio-hal/primary-hal/configs/common/overlay
 
 # Audio configuration file
 ifeq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
@@ -80,43 +80,43 @@
     device/qcom/common/media/audio_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy.conf
 else
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msm8953/audio_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy.conf
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/audio_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy.conf
 endif
 
 PRODUCT_COPY_FILES += \
-hardware/qcom/audio/configs/msm8953/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf \
-hardware/qcom/audio/configs/msm8953/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
-hardware/qcom/audio/configs/msm8953/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
-hardware/qcom/audio/configs/msm8953/mixer_paths_mtp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_mtp.xml \
-hardware/qcom/audio/configs/msm8953/mixer_paths_qrd_skuh.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skuh.xml \
-hardware/qcom/audio/configs/msm8953/mixer_paths_qrd_skui.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skui.xml \
-hardware/qcom/audio/configs/msm8953/mixer_paths_qrd_skuhf.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skuhf.xml \
-hardware/qcom/audio/configs/msm8953/mixer_paths_qrd_skum.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skum.xml \
-hardware/qcom/audio/configs/msm8953/mixer_paths_qrd_sku3.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_sku3.xml \
-hardware/qcom/audio/configs/msm8953/mixer_paths_wcd9330.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9330.xml \
-hardware/qcom/audio/configs/msm8953/mixer_paths_wcd9306.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9306.xml \
-hardware/qcom/audio/configs/msm8953/mixer_paths_wcd9335.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9335.xml \
-hardware/qcom/audio/configs/msm8953/mixer_paths_wcd9326.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9326.xml \
-hardware/qcom/audio/configs/msm8953/mixer_paths_qrd_skun.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skun.xml \
-hardware/qcom/audio/configs/msm8953/mixer_paths_skuk.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skuk.xml \
-hardware/qcom/audio/configs/msm8953/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
-hardware/qcom/audio/configs/msm8953/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
-hardware/qcom/audio/configs/msm8953/sound_trigger_mixer_paths_wcd9306.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9306.xml \
-hardware/qcom/audio/configs/msm8953/sound_trigger_mixer_paths_wcd9330.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9330.xml \
-hardware/qcom/audio/configs/msm8953/sound_trigger_mixer_paths_wcd9335.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9335.xml \
-hardware/qcom/audio/configs/msm8953/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
-hardware/qcom/audio/configs/msm8953/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
-hardware/qcom/audio/configs/msm8953/audio_platform_info_extcodec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_extcodec.xml \
-hardware/qcom/audio/configs/msm8953/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/mixer_paths_mtp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_mtp.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/mixer_paths_qrd_skuh.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skuh.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/mixer_paths_qrd_skui.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skui.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/mixer_paths_qrd_skuhf.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skuhf.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/mixer_paths_qrd_skum.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skum.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/mixer_paths_qrd_sku3.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_sku3.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/mixer_paths_wcd9330.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9330.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/mixer_paths_wcd9306.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9306.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/mixer_paths_wcd9335.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9335.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/mixer_paths_wcd9326.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9326.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/mixer_paths_qrd_skun.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd_skun.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/mixer_paths_skuk.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skuk.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/sound_trigger_mixer_paths_wcd9306.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9306.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/sound_trigger_mixer_paths_wcd9330.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9330.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/sound_trigger_mixer_paths_wcd9335.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9335.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/audio_platform_info_extcodec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_extcodec.xml \
+vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt
 
 #XML Audio configuration files
 ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
 ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/msm8953/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8953/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
 endif
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/a2dp_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_volumes.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
@@ -249,6 +249,10 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 persist.vendor.bt.enable.splita2dp=false
 
+#enable headset calibration
+PRODUCT_PROPERTY_OVERRIDES += \
+audio.volume.headset.gain.depcal=true
+
 # for HIDL related packages
 PRODUCT_PACKAGES += \
     android.hardware.audio@2.0-service \
diff --git a/configs/msm8996/audio_platform_info.xml b/configs/msm8996/audio_platform_info.xml
index 1c376a8..c371f4a 100755
--- a/configs/msm8996/audio_platform_info.xml
+++ b/configs/msm8996/audio_platform_info.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
-<!-- Copyright (c) 2015 - 2016, 2018, The Linux Foundation. All rights reserved.         -->
+<!-- Copyright (c) 2015-2016, 2018-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 -->
@@ -240,13 +240,13 @@
                         <mic_info mic_device_id="builtin_mic_4"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                     </snd_dev>
-                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_STEREO_DMIC">
+                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_DMIC_STEREO">
                         <mic_info mic_device_id="builtin_mic_1"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                         <mic_info mic_device_id="builtin_mic_2"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                     </snd_dev>
-                    <snd_dev in_snd_device="SND_DEVICE_IN_SPEAKER_STEREO_DMIC">
+                    <snd_dev in_snd_device="SND_DEVICE_IN_SPEAKER_DMIC_STEREO">
                         <mic_info mic_device_id="builtin_mic_1"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                         <mic_info mic_device_id="builtin_mic_2"
diff --git a/configs/msm8996/msm8996.mk b/configs/msm8996/msm8996.mk
index fb760c1..58b72ee 100644
--- a/configs/msm8996/msm8996.mk
+++ b/configs/msm8996/msm8996.mk
@@ -34,7 +34,7 @@
 
 USE_XML_AUDIO_POLICY_CONF := 1
 BOARD_SUPPORTS_SOUND_TRIGGER := true
-AUDIO_USE_LL_AS_PRIMARY_OUTPUT := true
+AUDIO_USE_DEEP_AS_PRIMARY_OUTPUT := false
 AUDIO_FEATURE_ENABLED_VBAT_MONITOR := true
 AUDIO_FEATURE_ENABLED_ANC_HEADSET := true
 AUDIO_FEATURE_ENABLED_CUSTOMSTEREO := true
@@ -59,7 +59,7 @@
 ##AUDIO_FEATURE_FLAGS
 
 #Audio Specific device overlays
-DEVICE_PACKAGE_OVERLAYS += hardware/qcom/audio/configs/common/overlay
+DEVICE_PACKAGE_OVERLAYS += vendor/qcom/opensource/audio-hal/primary-hal/configs/common/overlay
 
 # Audio configuration file
 ifeq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
@@ -67,32 +67,32 @@
     device/qcom/common/media/audio_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy.conf
 else
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msm8996/audio_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy.conf
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8996/audio_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy.conf
 endif
 
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msm8996/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf \
-    hardware/qcom/audio/configs/msm8996/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
-    hardware/qcom/audio/configs/msm8996/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
-    hardware/qcom/audio/configs/msm8996/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
-    hardware/qcom/audio/configs/msm8996/mixer_paths_tasha.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tasha.xml \
-    hardware/qcom/audio/configs/msm8996/mixer_paths_dtp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_dtp.xml \
-    hardware/qcom/audio/configs/msm8996/mixer_paths_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_i2s.xml \
-    hardware/qcom/audio/configs/msm8996/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt \
-    hardware/qcom/audio/configs/msm8996/audio_platform_info_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_i2s.xml \
-    hardware/qcom/audio/configs/msm8996/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
-    hardware/qcom/audio/configs/msm8996/sound_trigger_mixer_paths_wcd9330.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9330.xml \
-    hardware/qcom/audio/configs/msm8996/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
-    hardware/qcom/audio/configs/msm8996/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8996/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8996/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8996/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8996/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8996/mixer_paths_tasha.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tasha.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8996/mixer_paths_dtp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_dtp.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8996/mixer_paths_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_i2s.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8996/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8996/audio_platform_info_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_i2s.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8996/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8996/sound_trigger_mixer_paths_wcd9330.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9330.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8996/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8996/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml
 
 #XML Audio configuration files
 ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
 ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/msm8996/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8996/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
 endif
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/a2dp_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_volumes.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
@@ -102,7 +102,7 @@
 
 # Listen configuration file
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msm8996/listen_platform_info.xml:system/etc/listen_platform_info.xml
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8996/listen_platform_info.xml:vendor/etc/listen_platform_info.xml
 
 # Reduce client buffer size for fast audio output tracks
 PRODUCT_PROPERTY_OVERRIDES += \
@@ -197,6 +197,14 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 persist.vendor.audio.hw.binder.size_kbyte=1024
 
+#enable headset calibration
+PRODUCT_PROPERTY_OVERRIDES += \
+audio.volume.headset.gain.depcal=true
+
+#enable dualmic fluence for voice communication
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.audio.fluence.voicecomm=true
+
 # for HIDL related packages
 PRODUCT_PACKAGES += \
     android.hardware.audio@2.0-service \
diff --git a/configs/msm8998/audio_platform_info.xml b/configs/msm8998/audio_platform_info.xml
index 3cd234b..38628fc 100755
--- a/configs/msm8998/audio_platform_info.xml
+++ b/configs/msm8998/audio_platform_info.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
-<!-- Copyright (c) 2014, 2016-2018, The Linux Foundation. All rights reserved.   -->
+<!-- Copyright (c) 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 -->
@@ -292,13 +292,13 @@
                         <mic_info mic_device_id="builtin_mic_4"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                     </snd_dev>
-                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_STEREO_DMIC">
+                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_DMIC_STEREO">
                         <mic_info mic_device_id="builtin_mic_1"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                         <mic_info mic_device_id="builtin_mic_2"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                     </snd_dev>
-                    <snd_dev in_snd_device="SND_DEVICE_IN_SPEAKER_STEREO_DMIC">
+                    <snd_dev in_snd_device="SND_DEVICE_IN_SPEAKER_DMIC_STEREO">
                         <mic_info mic_device_id="builtin_mic_1"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                         <mic_info mic_device_id="builtin_mic_2"
diff --git a/configs/msm8998/msm8998.mk b/configs/msm8998/msm8998.mk
index 5f4e6e1..7b63cf8 100644
--- a/configs/msm8998/msm8998.mk
+++ b/configs/msm8998/msm8998.mk
@@ -28,8 +28,8 @@
 MM_AUDIO_ENABLED_SAFX := true
 AUDIO_FEATURE_ENABLED_HW_ACCELERATED_EFFECTS := false
 AUDIO_FEATURE_ENABLED_AUDIOSPHERE := true
-AUDIO_FEATURE_ENABLED_USB_TUNNEL_AUDIO := true
-AUDIO_FEATURE_ENABLED_SPLIT_A2DP := true
+AUDIO_FEATURE_ENABLED_USB_TUNNEL := true
+AUDIO_FEATURE_ENABLED_A2DP_OFFLOAD := true
 AUDIO_FEATURE_ENABLED_3D_AUDIO := false
 AUDIO_FEATURE_ENABLED_VOICE_PRINT := false
 USE_LEGACY_AUDIO_DAEMON := false
@@ -39,7 +39,7 @@
 
 USE_XML_AUDIO_POLICY_CONF := 1
 BOARD_SUPPORTS_SOUND_TRIGGER := true
-AUDIO_USE_LL_AS_PRIMARY_OUTPUT := true
+AUDIO_USE_DEEP_AS_PRIMARY_OUTPUT := false
 AUDIO_FEATURE_ENABLED_VBAT_MONITOR := true
 AUDIO_FEATURE_ENABLED_ANC_HEADSET := true
 AUDIO_FEATURE_ENABLED_CUSTOMSTEREO := true
@@ -67,46 +67,46 @@
 ##AUDIO_FEATURE_FLAGS
 
 #Audio Specific device overlays
-DEVICE_PACKAGE_OVERLAYS += hardware/qcom/audio/configs/common/overlay
+DEVICE_PACKAGE_OVERLAYS += vendor/qcom/opensource/audio-hal/primary-hal/configs/common/overlay
 
 # Audio configuration file
 ifeq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 PRODUCT_COPY_FILES += \
-    device/qcom/common/media/audio_policy.conf:system/etc/audio_policy.conf
+    device/qcom/common/media/audio_policy.conf:vendor/etc/audio_policy.conf
 else
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msm8998/audio_policy.conf:system/etc/audio_policy.conf
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/audio_policy.conf:vendor/etc/audio_policy.conf
 endif
 
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msm8998/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf \
-    hardware/qcom/audio/configs/msm8998/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
-    hardware/qcom/audio/configs/msm8998/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths_tasha.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tasha.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths_tavil.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tavil.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths_skuk.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skuk.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths_skuk.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qvr.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths_dtp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_dtp.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_i2s.xml \
-    hardware/qcom/audio/configs/msm8998/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt \
-    hardware/qcom/audio/configs/msm8998/audio_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tavil.txt \
-    hardware/qcom/audio/configs/msm8998/audio_platform_info_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_i2s.xml \
-    hardware/qcom/audio/configs/msm8998/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
-    hardware/qcom/audio/configs/msm8998/sound_trigger_mixer_paths_wcd9330.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9330.xml \
-    hardware/qcom/audio/configs/msm8998/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
-    hardware/qcom/audio/configs/msm8998/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
-    hardware/qcom/audio/configs/msm8998/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml \
-    hardware/qcom/audio/configs/msm8998/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/mixer_paths_tasha.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tasha.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/mixer_paths_tavil.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tavil.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/mixer_paths_skuk.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skuk.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/mixer_paths_skuk.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qvr.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/mixer_paths_dtp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_dtp.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/mixer_paths_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_i2s.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/audio_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tavil.txt \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/audio_platform_info_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_i2s.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/sound_trigger_mixer_paths_wcd9330.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9330.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml
 
 #XML Audio configuration files
 ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
 ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/msm8998/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
 endif
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/a2dp_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_volumes.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
@@ -116,7 +116,7 @@
 
 # Listen configuration file
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msm8998/listen_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/listen_platform_info.xml
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msm8998/listen_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/listen_platform_info.xml
 
 # Reduce client buffer size for fast audio output tracks
 PRODUCT_PROPERTY_OVERRIDES += \
@@ -202,6 +202,18 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 persist.vendor.bt.a2dp_offload_cap=sbc-aptx-aptxhd-aac
 
+# A2DP offload support
+PRODUCT_PROPERTY_OVERRIDES += \
+ro.bluetooth.a2dp_offload.supported=true
+
+# Disable A2DP offload
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bluetooth.a2dp_offload.disabled=false
+
+# A2DP offload DSP supported encoder list
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bluetooth.a2dp_offload.cap=sbc-aac-aptx-aptxhd-ldac
+
 #enable software decoders for ALAC and APE
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.use.sw.alac.decoder=true
@@ -227,6 +239,14 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 persist.vendor.audio.hw.binder.size_kbyte=1024
 
+#enable headset calibration
+PRODUCT_PROPERTY_OVERRIDES += \
+audio.volume.headset.gain.depcal=true
+
+#enable dualmic fluence for voice communication
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.audio.fluence.voicecomm=true
+
 # for HIDL related packages
 PRODUCT_PACKAGES += \
     android.hardware.audio@2.0-service \
diff --git a/configs/msmnile/audio_configs.xml b/configs/msmnile/audio_configs.xml
new file mode 100644
index 0000000..1afcd33
--- /dev/null
+++ b/configs/msmnile/audio_configs.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+Copyright (c) 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
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<configs>
+        <!-- system properties -->
+        <property name="audio.offload.video" value="true"/>
+        <property name="audio.offload.disable" value="false"/>
+        <property name="audio.offload.min.duration.secs" value="60"/>
+        <property name="audio.deep_buffer.media" value="true"/>
+        <property name="persist.vendor.audio.sva.conc.enabled" value="false"/>
+        <property name="persist.vendor.audio.va_concurrency_enabled" value="false"/>
+        <property name="vendor.audio.av.streaming.offload.enable" value="false"/>
+        <property name="vendor.audio.offload.track.enable" value="true"/>
+        <property name="vendor.audio.offload.multiple.enabled" value="false"/>
+        <property name="vendor.audio.rec.playback.conc.disabled" value="false"/>
+        <property name="vendor.voice.conc.fallbackpath" value=""/>
+        <property name="vendor.voice.dsd.playback.conc.disabled" value="true"/>
+        <property name="vendor.voice.path.for.pcm.voip" value="true"/>
+        <property name="vendor.voice.playback.conc.disabled" value="false"/>
+        <property name="vendor.voice.record.conc.disabled" value="false"/>
+        <property name="vendor.voice.voip.conc.disabled" value="false"/>
+
+        <property name="vendor.audio.use.sw.alac.decoder" value="true"/>
+        <property name="vendor.audio.use.sw.ape.decoder" value="true"/>
+        <property name="vendor.audio.use.sw.mpegh.decoder" value="false"/>
+        <property name="vendor.audio.flac.sw.decoder.24bit" value="true"/>
+        <property name="vendor.audio.hw.aac.encoder" value="true"/>
+
+        <!-- feature flags -->
+        <flag name="audio_extn_hdmi_spk_enabled" value="true" />
+        <flag name="audio_extn_formats_enabled" value="true" />
+        <flag name="audio_extn_afe_proxy_enabled" value="true" />
+        <flag name="compress_voip_enabled" value="false" />
+        <flag name="fm_power_opt" value="true" />
+        <flag name="voice_concurrency" value="false" />
+        <flag name="record_play_concurrency" value="false" />
+        <flag name="use_xml_audio_policy_conf" value="true" />
+
+        <flag name="aac_adts_offload_enabled" value="true" />
+        <flag name="alac_offload_enabled" value="true" />
+        <flag name="ape_offload_enabled" value="true" />
+        <flag name="flac_offload_enabled" value="true" />
+        <flag name="pcm_offload_enabled_16" value="true" />
+        <flag name="pcm_offload_enabled_24" value="true" />
+        <flag name="qti_flac_decoder" value="true" />
+        <flag name="vorbis_offload_enabled" value="true" />
+        <flag name="wma_offload_enabled" value="true" />
+</configs>
diff --git a/configs/msmnile/audio_io_policy.conf b/configs/msmnile/audio_io_policy.conf
index bac3ec1..f0ec913 100644
--- a/configs/msmnile/audio_io_policy.conf
+++ b/configs/msmnile/audio_io_policy.conf
@@ -84,16 +84,29 @@
 }
 
 inputs {
+  primary {
+    formats AUDIO_FORMAT_PCM_16_BIT
+    sampling_rates 8000|16000|32000|44100|48000|88200|96000|176400|192000
+    bit_width 16
+    app_type 69938
+  }
   record_24bit {
     formats AUDIO_FORMAT_PCM_24_BIT_PACKED|AUDIO_FORMAT_PCM_24_BIT
     sampling_rates 44100|48000|88200|96000|176400|192000
     bit_width 24
-    app_type 69938
+    app_type 69948
   }
   record_32bit {
     formats AUDIO_FORMAT_PCM_32_BIT|AUDIO_FORMAT_PCM_FLOAT
     sampling_rates 44100|48000|88200|96000|176400|192000
     bit_width 32
-    app_type 69938
+    app_type 69949
   }
-}
+  record_unprocessed {
+    profile record_unprocessed
+    formats AUDIO_FORMAT_PCM_24_BIT_PACKED
+    sampling_rates 16000|48000
+    bit_width 24
+    app_type 69942
+  }
+}
\ No newline at end of file
diff --git a/configs/msmnile/audio_platform_info.xml b/configs/msmnile/audio_platform_info.xml
index 52b1b09..9761f99 100644
--- a/configs/msmnile/audio_platform_info.xml
+++ b/configs/msmnile/audio_platform_info.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
-<!-- Copyright (c) 2014, 2016-2018, The Linux Foundation. All rights reserved. -->
+<!-- Copyright (c) 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 -->
@@ -101,6 +101,7 @@
         <usecase name="USECASE_AUDIO_RECORD_MMAP" type="in" id="33" />
         <usecase name="USECASE_AUDIO_A2DP_ABR_FEEDBACK" type="in" id="40" />
         <usecase name="USECASE_INCALL_MUSIC_UPLINK" type="out" id="27" />
+        <usecase name="USECASE_AUDIO_RECORD_COMPRESS2" type="in" id="41" />
     </pcm_ids>
     <config_params>
         <param key="spkr_1_tz_name" value="wsatz.13"/>
@@ -327,13 +328,13 @@
                         <mic_info mic_device_id="builtin_mic_4"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                     </snd_dev>
-                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_STEREO_DMIC">
+                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_DMIC_STEREO">
                         <mic_info mic_device_id="builtin_mic_1"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                         <mic_info mic_device_id="builtin_mic_2"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                     </snd_dev>
-                    <snd_dev in_snd_device="SND_DEVICE_IN_SPEAKER_STEREO_DMIC">
+                    <snd_dev in_snd_device="SND_DEVICE_IN_SPEAKER_DMIC_STEREO">
                         <mic_info mic_device_id="builtin_mic_1"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                         <mic_info mic_device_id="builtin_mic_2"
diff --git a/configs/msmnile/mixer_paths_tavil.xml b/configs/msmnile/mixer_paths_tavil.xml
index 381264c..6104fbe 100644
--- a/configs/msmnile/mixer_paths_tavil.xml
+++ b/configs/msmnile/mixer_paths_tavil.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
-<!-- Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.    -->
+<!-- Copyright (c) 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 -->
@@ -59,9 +59,11 @@
     <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia14" value="0" />
     <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia15" value="0" />
     <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia16" value="0" />
+    <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia17" value="0" />
     <ctl name="SLIMBUS_6_RX Port Mixer SLIM_0_TX" value="0" />
     <ctl name="SLIMBUS_4_RX Audio Mixer MultiMedia1" value="0" />
     <ctl name="SLIMBUS_4_RX Audio Mixer MultiMedia2" value="0" />
+    <ctl name="SLIMBUS_4_RX Audio Mixer MultiMedia17" value="0" />
     <ctl name="MultiMedia5 Mixer SLIM_0_TX" value="0" />
     <ctl name="MultiMedia5 Mixer AFE_PCM_TX" value="0" />
     <ctl name="MultiMedia5 Mixer SLIM_8_TX" value="0" />
@@ -75,6 +77,9 @@
     <ctl name="MultiMedia10 Mixer SLIM_0_TX" value="0" />
     <ctl name="MultiMedia10 Mixer SLIM_7_TX" value="0" />
     <ctl name="MultiMedia10 Mixer AFE_PCM_TX" value="0" />
+    <ctl name="MultiMedia17 Mixer SLIM_0_TX" value="0" />
+    <ctl name="MultiMedia17 Mixer SLIM_4_TX" value="0" />
+    <ctl name="MultiMedia17 Mixer SLIM_7_TX" value="0" />
     <ctl name="DISPLAY_PORT Mixer MultiMedia1" value="0" />
     <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="0" />
     <ctl name="DISPLAY_PORT Mixer MultiMedia3" value="0" />
@@ -91,6 +96,7 @@
     <ctl name="DISPLAY_PORT Mixer MultiMedia14" value="0" />
     <ctl name="DISPLAY_PORT Mixer MultiMedia15" value="0" />
     <ctl name="DISPLAY_PORT Mixer MultiMedia16" value="0" />
+    <ctl name="DISPLAY_PORT Mixer MultiMedia17" value="0" />
     <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia1" value="0" />
     <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia1" value="0" />
     <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia2" value="0" />
@@ -139,6 +145,8 @@
     <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia16" value="0" />
     <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia16" value="0" />
     <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia16" value="0" />
+    <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia17" value="0" />
+    <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia17" value="0" />
     <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia1" value="0" />
     <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="0" />
     <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia3" value="0" />
@@ -153,11 +161,13 @@
     <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia14" value="0" />
     <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia15" value="0" />
     <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia16" value="0" />
+    <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia17" value="0" />
     <ctl name="MultiMedia1 Mixer USB_AUDIO_TX" value="0" />
     <ctl name="MultiMedia2 Mixer USB_AUDIO_TX" value="0" />
     <ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="0" />
     <ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="0" />
     <ctl name="MultiMedia10 Mixer USB_AUDIO_TX" value="0" />
+    <ctl name="MultiMedia17 Mixer USB_AUDIO_TX" value="0" />
     <ctl name="MultiMedia6 Mixer SLIM_0_TX" value="0" />
     <ctl name="SLIM_2_RX Format" value="UNPACKED" />
     <ctl name="SLIM_2_RX SampleRate" value="KHZ_48" />
@@ -205,7 +215,9 @@
     <ctl name="AFE_PCM_RX Audio Mixer MultiMedia14" value="0" />
     <ctl name="AFE_PCM_RX Audio Mixer MultiMedia15" value="0" />
     <ctl name="AFE_PCM_RX Audio Mixer MultiMedia16" value="0" />
+    <ctl name="AFE_PCM_RX Audio Mixer MultiMedia17" value="0" />
     <ctl name="MultiMedia1 Mixer AFE_PCM_TX" value="0" />
+    <ctl name="MultiMedia17 Mixer AFE_PCM_TX" value="0" />
     <ctl name="AFE_PCM_RX Audio Mixer MultiMedia5" value="0" />
     <!-- usb headset end -->
     <!-- fm -->
@@ -216,6 +228,7 @@
     <ctl name="SLIMBUS6_DL_HL Switch" value="0" />
     <ctl name="MultiMedia1 Mixer SLIM_8_TX" value="0" />
     <ctl name="MultiMedia2 Mixer SLIM_8_TX" value="0" />
+    <ctl name="MultiMedia17 Mixer SLIM_8_TX" value="0" />
     <!-- fm end -->
 
     <!-- Multimode Voice1 -->
@@ -266,6 +279,8 @@
     <ctl name="MultiMedia1 Mixer VOC_REC_DL" value="0" />
     <ctl name="MultiMedia8 Mixer VOC_REC_UL" value="0" />
     <ctl name="MultiMedia8 Mixer VOC_REC_DL" value="0" />
+    <ctl name="MultiMedia17 Mixer VOC_REC_UL" value="0" />
+    <ctl name="MultiMedia17 Mixer VOC_REC_DL" value="0" />
     <!-- Incall Recording End -->
 
     <!-- Incall Music -->
@@ -290,7 +305,9 @@
     <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia4" value="0" />
     <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia5" value="0" />
     <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia6" value="0" />
+    <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia17" value="0" />
     <ctl name="MultiMedia1 Mixer SLIM_7_TX" value="0" />
+    <ctl name="MultiMedia17 Mixer SLIM_7_TX" value="0" />
     <!-- audio record compress-->
     <ctl name="MultiMedia8 Mixer SLIM_0_TX" value="0" />
     <ctl name="MultiMedia8 Mixer SLIM_7_TX" value="0" />
@@ -1400,6 +1417,24 @@
         <ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="1" />
     </path>
 
+    <path name="audio-record-compress2">
+        <ctl name="MultiMedia17 Mixer SLIM_0_TX" value="1" />
+    </path>
+
+    <path name="audio-record-compress2 usb-headset-mic">
+        <ctl name="MultiMedia17 Mixer USB_AUDIO_TX" value="1" />
+    </path>
+
+    <path name="audio-record-compress2 bt-sco">
+        <ctl name="MultiMedia17 Mixer SLIM_7_TX" value="1" />
+    </path>
+
+    <path name="audio-record-compress2 bt-sco-wb">
+        <ctl name="BT SampleRate" value="KHZ_16" />
+        <path name="audio-record-compress2 bt-sco" />
+    </path>
+
+
     <path name="low-latency-record">
       <ctl name="MultiMedia8 Mixer SLIM_0_TX" value="1" />
     </path>
diff --git a/configs/msmnile/msmnile.mk b/configs/msmnile/msmnile.mk
index 1a0ab62..0d42bff 100644
--- a/configs/msmnile/msmnile.mk
+++ b/configs/msmnile/msmnile.mk
@@ -14,6 +14,8 @@
 ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 USE_CUSTOM_AUDIO_POLICY := 1
 AUDIO_FEATURE_ENABLED_COMPRESS_CAPTURE := false
+AUDIO_FEATURE_ENABLED_COMPRESS_INPUT := true
+AUDIO_FEATURE_ENABLED_CONCURRENT_CAPTURE := true
 AUDIO_FEATURE_ENABLED_COMPRESS_VOIP := false
 AUDIO_FEATURE_ENABLED_DYNAMIC_ECNS := true
 AUDIO_FEATURE_ENABLED_EXTN_FORMATS := true
@@ -37,8 +39,8 @@
 MM_AUDIO_ENABLED_SAFX := true
 AUDIO_FEATURE_ENABLED_HW_ACCELERATED_EFFECTS := false
 AUDIO_FEATURE_ENABLED_AUDIOSPHERE := true
-AUDIO_FEATURE_ENABLED_USB_TUNNEL_AUDIO := true
-AUDIO_FEATURE_ENABLED_SPLIT_A2DP := true
+AUDIO_FEATURE_ENABLED_USB_TUNNEL := true
+AUDIO_FEATURE_ENABLED_A2DP_OFFLOAD := true
 AUDIO_FEATURE_ENABLED_3D_AUDIO := true
 DOLBY_ENABLE := false
 endif
@@ -46,7 +48,7 @@
 USE_XML_AUDIO_POLICY_CONF := 1
 BOARD_SUPPORTS_SOUND_TRIGGER := true
 AUDIO_FEATURE_ENABLED_INSTANCE_ID := true
-AUDIO_USE_LL_AS_PRIMARY_OUTPUT := true
+AUDIO_USE_DEEP_AS_PRIMARY_OUTPUT := false
 AUDIO_FEATURE_ENABLED_VBAT_MONITOR := true
 AUDIO_FEATURE_ENABLED_ANC_HEADSET := true
 AUDIO_FEATURE_ENABLED_CUSTOMSTEREO := true
@@ -79,31 +81,32 @@
 
 ifneq ($(strip $(TARGET_USES_RRO)), true)
 #Audio Specific device overlays
-DEVICE_PACKAGE_OVERLAYS += hardware/qcom/audio/configs/common/overlay
+DEVICE_PACKAGE_OVERLAYS += vendor/qcom/opensource/audio-hal/primary-hal/configs/common/overlay
 endif
 
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msmnile/audio_io_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_io_policy.conf \
-    hardware/qcom/audio/configs/msmnile/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
-    hardware/qcom/audio/configs/msmnile/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
-    hardware/qcom/audio/configs/msmnile/mixer_paths_tavil.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tavil.xml \
-    hardware/qcom/audio/configs/msmnile/audio_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tavil.txt \
-    hardware/qcom/audio/configs/msmnile/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt \
-    hardware/qcom/audio/configs/msmnile/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
-    hardware/qcom/audio/configs/msmnile/sound_trigger_mixer_paths_wcd9340_qrd.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340_qrd.xml \
-    hardware/qcom/audio/configs/msmnile/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
-    hardware/qcom/audio/configs/msmnile/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml \
-    hardware/qcom/audio/configs/msmnile/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
-    hardware/qcom/audio/configs/msmnile/mixer_paths_pahu.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_pahu.xml \
-    hardware/qcom/audio/configs/msmnile/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile/audio_io_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_io_policy.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile/mixer_paths_tavil.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tavil.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile/audio_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tavil.txt \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile/sound_trigger_mixer_paths_wcd9340_qrd.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340_qrd.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile/mixer_paths_pahu.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_pahu.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile/audio_configs.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_configs.xml
 
 #XML Audio configuration files
 ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/msmnile/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
 endif
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/a2dp_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_volumes.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
@@ -112,7 +115,7 @@
 
 # Listen configuration file
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msmnile/listen_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/listen_platform_info.xml
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile/listen_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/listen_platform_info.xml
 
 # Reduce client buffer size for fast audio output tracks
 PRODUCT_PROPERTY_OVERRIDES += \
@@ -199,6 +202,18 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 persist.vendor.bt.a2dp_offload_cap=sbc-aptx-aptxtws-aptxhd-aac-ldac
 
+# A2DP offload support
+PRODUCT_PROPERTY_OVERRIDES += \
+ro.bluetooth.a2dp_offload.supported=true
+
+# Disable A2DP offload
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bluetooth.a2dp_offload.disabled=false
+
+# A2DP offload DSP supported encoder list
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bluetooth.a2dp_offload.cap=sbc-aac-aptx-aptxhd-ldac
+
 #enable software decoders for ALAC and APE
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.use.sw.alac.decoder=true
@@ -250,6 +265,14 @@
 persist.vendor.bt.aac_frm_ctl.enabled=true
 endif
 
+#enable headset calibration
+PRODUCT_PROPERTY_OVERRIDES += \
+audio.volume.headset.gain.depcal=true
+
+#enable dualmic fluence for voice communication
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.audio.fluence.voicecomm=true
+
 # for HIDL related packages
 PRODUCT_PACKAGES += \
     android.hardware.audio@2.0-service \
@@ -261,4 +284,7 @@
     android.hardware.audio.common@4.0-util \
     android.hardware.audio@4.0-impl \
     android.hardware.audio.effect@4.0 \
-    android.hardware.audio.effect@4.0-impl
+    android.hardware.audio.effect@4.0-impl \
+    vendor.qti.hardware.audiohalext@1.0 \
+    vendor.qti.hardware.audiohalext@1.0-impl \
+    vendor.qti.hardware.audiohalext-utils
diff --git a/configs/msmnile_au/msmnile_au.mk b/configs/msmnile_au/msmnile_au.mk
index 7abac58..257694a 100644
--- a/configs/msmnile_au/msmnile_au.mk
+++ b/configs/msmnile_au/msmnile_au.mk
@@ -30,8 +30,8 @@
 MM_AUDIO_ENABLED_SAFX := true
 AUDIO_FEATURE_ENABLED_HW_ACCELERATED_EFFECTS := false
 AUDIO_FEATURE_ENABLED_AUDIOSPHERE := true
-AUDIO_FEATURE_ENABLED_USB_TUNNEL_AUDIO := true
-AUDIO_FEATURE_ENABLED_SPLIT_A2DP := true
+AUDIO_FEATURE_ENABLED_USB_TUNNEL := true
+AUDIO_FEATURE_ENABLED_A2DP_OFFLOAD := true
 AUDIO_FEATURE_ENABLED_3D_AUDIO := false
 DOLBY_ENABLE := false
 endif
@@ -39,7 +39,7 @@
 USE_XML_AUDIO_POLICY_CONF := 1
 BOARD_SUPPORTS_SOUND_TRIGGER := true
 AUDIO_FEATURE_ENABLED_INSTANCE_ID := true
-AUDIO_USE_LL_AS_PRIMARY_OUTPUT := true
+AUDIO_USE_DEEP_AS_PRIMARY_OUTPUT := false
 AUDIO_FEATURE_ENABLED_VBAT_MONITOR := true
 AUDIO_FEATURE_ENABLED_ANC_HEADSET := true
 AUDIO_FEATURE_ENABLED_CUSTOMSTEREO := true
@@ -77,30 +77,30 @@
 
 ifneq ($(strip $(TARGET_USES_RRO)), true)
 #Audio Specific device overlays
-DEVICE_PACKAGE_OVERLAYS += hardware/qcom/audio/configs/common/overlay
+DEVICE_PACKAGE_OVERLAYS += vendor/qcom/opensource/audio-hal/primary-hal/configs/common/overlay
 endif
 
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msmnile_au/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf \
-    hardware/qcom/audio/configs/msmnile_au/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
-    hardware/qcom/audio/configs/msmnile_au/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
-    hardware/qcom/audio/configs/msmnile_au/mixer_paths_adp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_adp.xml \
-    hardware/qcom/audio/configs/msmnile_au/audio_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tavil.txt \
-    hardware/qcom/audio/configs/msmnile_au/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt \
-    hardware/qcom/audio/configs/msmnile_au/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
-    hardware/qcom/audio/configs/msmnile_au/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
-    hardware/qcom/audio/configs/msmnile_au/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml \
-    hardware/qcom/audio/configs/msmnile_au/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
-    hardware/qcom/audio/configs/msmnile_au/mixer_paths_custom.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_custom.xml \
-    hardware/qcom/audio/configs/msmnile_au/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile_au/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile_au/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile_au/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile_au/mixer_paths_adp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_adp.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile_au/audio_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tavil.txt \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile_au/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile_au/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile_au/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile_au/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile_au/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile_au/mixer_paths_custom.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_custom.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile_au/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml
 
 #XML Audio configuration files
 ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/msmnile_au/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile_au/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
 endif
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/a2dp_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_volumes.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
@@ -109,7 +109,7 @@
 
 # Listen configuration file
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msmnile_au/listen_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/listen_platform_info.xml
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile_au/listen_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/listen_platform_info.xml
 
 # Reduce client buffer size for fast audio output tracks
 PRODUCT_PROPERTY_OVERRIDES += \
@@ -196,6 +196,18 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 persist.vendor.bt.a2dp_offload_cap=sbc-aptx-aptxtws-aptxhd-aac-ldac
 
+# A2DP offload support
+PRODUCT_PROPERTY_OVERRIDES += \
+ro.bluetooth.a2dp_offload.supported=true
+
+# Disable A2DP offload
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bluetooth.a2dp_offload.disabled=false
+
+# A2DP offload DSP supported encoder list
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bluetooth.a2dp_offload.cap=sbc-aac-aptx-aptxhd-ldac
+
 #enable software decoders for ALAC and APE
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.use.sw.alac.decoder=true
@@ -242,6 +254,14 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 persist.vendor.audio.voicecall.speaker.stereo=true
 
+#enable headset calibration
+PRODUCT_PROPERTY_OVERRIDES += \
+audio.volume.headset.gain.depcal=true
+
+#enable dualmic fluence for voice communication
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.audio.fluence.voicecomm=true
+
 # for HIDL related packages
 PRODUCT_PACKAGES += \
     android.hardware.audio@2.0-service \
diff --git a/configs/msmsteppe/audio_platform_info.xml b/configs/msmsteppe/audio_platform_info.xml
index c89ec2c..09b2d9b 100644
--- a/configs/msmsteppe/audio_platform_info.xml
+++ b/configs/msmsteppe/audio_platform_info.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
-<!-- Copyright (c) 2014, 2016-2018, The Linux Foundation. All rights reserved. -->
+<!-- Copyright (c) 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 -->
@@ -328,13 +328,13 @@
                         <mic_info mic_device_id="builtin_mic_4"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                     </snd_dev>
-                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_STEREO_DMIC">
+                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_DMIC_STEREO">
                         <mic_info mic_device_id="builtin_mic_1"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                         <mic_info mic_device_id="builtin_mic_2"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                     </snd_dev>
-                    <snd_dev in_snd_device="SND_DEVICE_IN_SPEAKER_STEREO_DMIC">
+                    <snd_dev in_snd_device="SND_DEVICE_IN_SPEAKER_DMIC_STEREO">
                         <mic_info mic_device_id="builtin_mic_1"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                         <mic_info mic_device_id="builtin_mic_2"
diff --git a/configs/msmsteppe/msmsteppe.mk b/configs/msmsteppe/msmsteppe.mk
index a7a2011..5bf67da 100644
--- a/configs/msmsteppe/msmsteppe.mk
+++ b/configs/msmsteppe/msmsteppe.mk
@@ -30,8 +30,8 @@
 MM_AUDIO_ENABLED_SAFX := true
 AUDIO_FEATURE_ENABLED_HW_ACCELERATED_EFFECTS := false
 AUDIO_FEATURE_ENABLED_AUDIOSPHERE := true
-AUDIO_FEATURE_ENABLED_USB_TUNNEL_AUDIO := true
-AUDIO_FEATURE_ENABLED_SPLIT_A2DP := true
+AUDIO_FEATURE_ENABLED_USB_TUNNEL := true
+AUDIO_FEATURE_ENABLED_A2DP_OFFLOAD := true
 AUDIO_FEATURE_ENABLED_3D_AUDIO := false
 DOLBY_ENABLE := false
 endif
@@ -40,7 +40,7 @@
 AUDIO_FEATURE_ENABLED_DLKM := true
 BOARD_SUPPORTS_SOUND_TRIGGER := true
 AUDIO_FEATURE_ENABLED_INSTANCE_ID := true
-AUDIO_USE_LL_AS_PRIMARY_OUTPUT := true
+AUDIO_USE_DEEP_AS_PRIMARY_OUTPUT := false
 AUDIO_FEATURE_ENABLED_VBAT_MONITOR := true
 AUDIO_FEATURE_ENABLED_ANC_HEADSET := true
 AUDIO_FEATURE_ENABLED_CUSTOMSTEREO := true
@@ -70,34 +70,34 @@
 ##AUDIO_FEATURE_FLAGS
 
 #Audio Specific device overlays
-DEVICE_PACKAGE_OVERLAYS += hardware/qcom/audio/configs/common/overlay
+DEVICE_PACKAGE_OVERLAYS += vendor/qcom/opensource/audio-hal/primary-hal/configs/common/overlay
 
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msmsteppe/audio_io_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_io_policy.conf \
-    hardware/qcom/audio/configs/msmsteppe/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
-    hardware/qcom/audio/configs/msmsteppe/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
-    hardware/qcom/audio/configs/msmsteppe/audio_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tavil.txt \
-    hardware/qcom/audio/configs/msmsteppe/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
-    hardware/qcom/audio/configs/msmsteppe/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
-    hardware/qcom/audio/configs/msmsteppe/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml \
-    hardware/qcom/audio/configs/msmsteppe/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
-    hardware/qcom/audio/configs/msmsteppe/audio_platform_info_qrd.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_qrd.xml \
-    hardware/qcom/audio/configs/msmsteppe/audio_platform_info_intcodec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_intcodec.xml \
-    hardware/qcom/audio/configs/msmsteppe/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
-    hardware/qcom/audio/configs/msmsteppe/sound_trigger_mixer_paths_qrd.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_qrd.xml \
-    hardware/qcom/audio/configs/msmsteppe/mixer_paths_idp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_idp.xml \
-    hardware/qcom/audio/configs/msmsteppe/mixer_paths_wcd9375.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9375.xml \
-    hardware/qcom/audio/configs/msmsteppe/mixer_paths_qrd.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd.xml \
-    hardware/qcom/audio/configs/msmsteppe/mixer_paths_wcd9375qrd.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9375qrd.xml \
-    hardware/qcom/audio/configs/msmsteppe/mixer_paths_tavil.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tavil.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/audio_io_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_io_policy.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/audio_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tavil.txt \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/audio_platform_info_qrd.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_qrd.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/audio_platform_info_intcodec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_intcodec.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/sound_trigger_mixer_paths_qrd.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_qrd.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/mixer_paths_idp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_idp.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/mixer_paths_wcd9375.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9375.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/mixer_paths_qrd.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qrd.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/mixer_paths_wcd9375qrd.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9375qrd.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/mixer_paths_tavil.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tavil.xml \
 
 #XML Audio configuration files
 ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/msmsteppe/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
 endif
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/a2dp_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_volumes.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
@@ -106,7 +106,7 @@
 
 # Listen configuration file
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msmsteppe/listen_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/listen_platform_info.xml
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/listen_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/listen_platform_info.xml
 
 # Reduce client buffer size for fast audio output tracks
 PRODUCT_PROPERTY_OVERRIDES += \
@@ -192,6 +192,18 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 persist.vendor.bt.a2dp_offload_cap=sbc-aptx-aptxtws-aptxhd-aac
 
+# A2DP offload support
+PRODUCT_PROPERTY_OVERRIDES += \
+ro.bluetooth.a2dp_offload.supported=true
+
+# Disable A2DP offload
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bluetooth.a2dp_offload.disabled=false
+
+# A2DP offload DSP supported encoder list
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bluetooth.a2dp_offload.cap=sbc-aac-aptx-aptxhd-ldac
+
 #enable software decoders for ALAC and APE
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.use.sw.alac.decoder=true
@@ -226,6 +238,14 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.adm.buffering.ms=2
 
+#enable headset calibration
+PRODUCT_PROPERTY_OVERRIDES += \
+audio.volume.headset.gain.depcal=true
+
+#enable dualmic fluence for voice communication
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.audio.fluence.voicecomm=true
+
 # for HIDL related packages
 PRODUCT_PACKAGES += \
     android.hardware.audio@2.0-service \
diff --git a/configs/sdm660/sdm660.mk b/configs/sdm660/sdm660.mk
index aef78b1..523d8ff 100644
--- a/configs/sdm660/sdm660.mk
+++ b/configs/sdm660/sdm660.mk
@@ -28,8 +28,8 @@
 MM_AUDIO_ENABLED_SAFX := true
 AUDIO_FEATURE_ENABLED_HW_ACCELERATED_EFFECTS := false
 AUDIO_FEATURE_ENABLED_AUDIOSPHERE := true
-AUDIO_FEATURE_ENABLED_USB_TUNNEL_AUDIO := true
-AUDIO_FEATURE_ENABLED_SPLIT_A2DP := true
+AUDIO_FEATURE_ENABLED_USB_TUNNEL := true
+AUDIO_FEATURE_ENABLED_A2DP_OFFLOAD := true
 AUDIO_FEATURE_ENABLED_3D_AUDIO := false
 AUDIO_FEATURE_ENABLED_VOICE_PRINT := false
 USE_LEGACY_AUDIO_DAEMON := false
@@ -39,7 +39,7 @@
 
 USE_XML_AUDIO_POLICY_CONF := 1
 BOARD_SUPPORTS_SOUND_TRIGGER := true
-AUDIO_USE_LL_AS_PRIMARY_OUTPUT := true
+AUDIO_USE_DEEP_AS_PRIMARY_OUTPUT := false
 AUDIO_FEATURE_ENABLED_HIFI_AUDIO := true
 AUDIO_FEATURE_ENABLED_VBAT_MONITOR := true
 AUDIO_FEATURE_ENABLED_ANC_HEADSET := true
@@ -67,50 +67,50 @@
 ##AUDIO_FEATURE_FLAGS
 
 #Audio Specific device overlays
-DEVICE_PACKAGE_OVERLAYS += hardware/qcom/audio/configs/common/overlay
+DEVICE_PACKAGE_OVERLAYS += vendor/qcom/opensource/audio-hal/primary-hal/configs/common/overlay
 
 # Audio configuration file
 ifeq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 PRODUCT_COPY_FILES += \
-    device/qcom/common/media/audio_policy.conf:system/etc/audio_policy.conf
+    device/qcom/common/media/audio_policy.conf:vendor/etc/audio_policy.conf
 else
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/sdm660/audio_policy.conf:system/etc/audio_policy.conf
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/audio_policy.conf:vendor/etc/audio_policy.conf
 endif
 
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/sdm660/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf \
-    hardware/qcom/audio/configs/sdm660/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
-    hardware/qcom/audio/configs/sdm660/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
-    hardware/qcom/audio/configs/sdm660/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
-    hardware/qcom/audio/configs/sdm660/mixer_paths_mtp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_mtp.xml \
-    hardware/qcom/audio/configs/sdm660/mixer_paths_wcd9335.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9335.xml \
-    hardware/qcom/audio/configs/sdm660/mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9340.xml \
-    hardware/qcom/audio/configs/sdm660/mixer_paths_wcd9326.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9326.xml \
-    hardware/qcom/audio/configs/sdm660/mixer_paths_skus.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skus.xml \
-    hardware/qcom/audio/configs/sdm660/mixer_paths_skush.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skush.xml \
-    hardware/qcom/audio/configs/sdm660/mixer_paths_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_i2s.xml \
-    hardware/qcom/audio/configs/sdm660/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt \
-    hardware/qcom/audio/configs/sdm660/audio_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tavil.txt \
-    hardware/qcom/audio/configs/sdm660/audio_tuning_mixer_tasha.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tasha.txt \
-    hardware/qcom/audio/configs/sdm660/audio_platform_info_extcodec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_extcodec.xml \
-    hardware/qcom/audio/configs/sdm660/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
-    hardware/qcom/audio/configs/sdm660/audio_platform_info_skush.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_skush.xml \
-    hardware/qcom/audio/configs/sdm660/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
-    hardware/qcom/audio/configs/sdm660/sound_trigger_mixer_paths_wcd9330.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9330.xml \
-    hardware/qcom/audio/configs/sdm660/sound_trigger_mixer_paths_wcd9335.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9335.xml \
-    hardware/qcom/audio/configs/sdm660/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
-    hardware/qcom/audio/configs/sdm660/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
-    hardware/qcom/audio/configs/sdm660/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/mixer_paths_mtp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_mtp.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/mixer_paths_wcd9335.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9335.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9340.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/mixer_paths_wcd9326.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_wcd9326.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/mixer_paths_skus.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skus.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/mixer_paths_skush.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skush.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/mixer_paths_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_i2s.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/audio_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tavil.txt \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/audio_tuning_mixer_tasha.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tasha.txt \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/audio_platform_info_extcodec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_extcodec.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/audio_platform_info_skush.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_skush.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/sound_trigger_mixer_paths_wcd9330.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9330.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/sound_trigger_mixer_paths_wcd9335.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9335.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml
 
 #XML Audio configuration files
 ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
 ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/sdm660/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
 endif
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/a2dp_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_volumes.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
@@ -120,7 +120,7 @@
 
 # Listen configuration file
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/sdm660/listen_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/listen_platform_info.xml
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm660/listen_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/listen_platform_info.xml
 
 # Reduce client buffer size for fast audio output tracks
 PRODUCT_PROPERTY_OVERRIDES += \
@@ -210,6 +210,18 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 persist.vendor.bt.a2dp_offload_cap=sbc-aptx-aptxhd-aac
 
+# A2DP offload support
+PRODUCT_PROPERTY_OVERRIDES += \
+ro.bluetooth.a2dp_offload.supported=true
+
+# Disable A2DP offload
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bluetooth.a2dp_offload.disabled=false
+
+# A2DP offload DSP supported encoder list
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bluetooth.a2dp_offload.cap=sbc-aac-aptx-aptxhd-ldac
+
 #enable software decoders for ALAC and APE
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.use.sw.alac.decoder=true
@@ -239,6 +251,10 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 persist.vendor.audio.hw.binder.size_kbyte=1024
 
+#enable headset calibration
+PRODUCT_PROPERTY_OVERRIDES += \
+audio.volume.headset.gain.depcal=true
+
 # for HIDL related packages
 PRODUCT_PACKAGES += \
     android.hardware.audio@2.0-service \
diff --git a/configs/sdm710/audio_platform_info.xml b/configs/sdm710/audio_platform_info.xml
index 88fe66e..6eed60f 100644
--- a/configs/sdm710/audio_platform_info.xml
+++ b/configs/sdm710/audio_platform_info.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
-<!-- Copyright (c) 2014, 2016-2018, The Linux Foundation. All rights reserved. -->
+<!-- Copyright (c) 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 -->
@@ -327,13 +327,13 @@
                         <mic_info mic_device_id="builtin_mic_4"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                     </snd_dev>
-                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_STEREO_DMIC">
+                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_DMIC_STEREO">
                         <mic_info mic_device_id="builtin_mic_1"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                         <mic_info mic_device_id="builtin_mic_2"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                     </snd_dev>
-                    <snd_dev in_snd_device="SND_DEVICE_IN_SPEAKER_STEREO_DMIC">
+                    <snd_dev in_snd_device="SND_DEVICE_IN_SPEAKER_DMIC_STEREO">
                         <mic_info mic_device_id="builtin_mic_1"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                         <mic_info mic_device_id="builtin_mic_2"
diff --git a/configs/sdm710/sdm710.mk b/configs/sdm710/sdm710.mk
index 04aac8a..ccf4a6d 100644
--- a/configs/sdm710/sdm710.mk
+++ b/configs/sdm710/sdm710.mk
@@ -31,8 +31,8 @@
 MM_AUDIO_ENABLED_SAFX := true
 AUDIO_FEATURE_ENABLED_HW_ACCELERATED_EFFECTS := false
 AUDIO_FEATURE_ENABLED_AUDIOSPHERE := true
-AUDIO_FEATURE_ENABLED_USB_TUNNEL_AUDIO := true
-AUDIO_FEATURE_ENABLED_SPLIT_A2DP := true
+AUDIO_FEATURE_ENABLED_USB_TUNNEL := true
+AUDIO_FEATURE_ENABLED_A2DP_OFFLOAD := true
 AUDIO_FEATURE_ENABLED_3D_AUDIO := true
 AUDIO_FEATURE_ENABLED_VOICE_PRINT := false
 USE_LEGACY_AUDIO_DAEMON := false
@@ -42,7 +42,7 @@
 
 USE_XML_AUDIO_POLICY_CONF := 1
 BOARD_SUPPORTS_SOUND_TRIGGER := true
-AUDIO_USE_LL_AS_PRIMARY_OUTPUT := true
+AUDIO_USE_DEEP_AS_PRIMARY_OUTPUT := true
 AUDIO_FEATURE_ENABLED_HIFI_AUDIO := true
 AUDIO_FEATURE_ENABLED_VBAT_MONITOR := true
 AUDIO_FEATURE_ENABLED_ANC_HEADSET := true
@@ -79,53 +79,53 @@
 
 ifneq ($(strip $(TARGET_USES_RRO)), true)
 #Audio Specific device overlays
-DEVICE_PACKAGE_OVERLAYS += hardware/qcom/audio/configs/common/overlay
+DEVICE_PACKAGE_OVERLAYS += vendor/qcom/opensource/audio-hal/primary-hal/configs/common/overlay
 endif
 
 # Audio configuration file
 ifeq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 PRODUCT_COPY_FILES += \
-    device/qcom/common/media/audio_policy.conf:system/etc/audio_policy.conf
+    device/qcom/common/media/audio_policy.conf:vendor/etc/audio_policy.conf
 else
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/sdm710/audio_policy.conf:system/etc/audio_policy.conf
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/audio_policy.conf:vendor/etc/audio_policy.conf
 endif
 
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/sdm710/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf \
-    hardware/qcom/audio/configs/sdm710/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
-    hardware/qcom/audio/configs/sdm710/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
-    hardware/qcom/audio/configs/sdm710/mixer_paths_tavil.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tavil.xml \
-    hardware/qcom/audio/configs/sdm710/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
-    hardware/qcom/audio/configs/sdm710/mixer_paths_mtp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_mtp.xml \
-    hardware/qcom/audio/configs/sdm710/mixer_paths_tasha.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tasha.xml \
-    hardware/qcom/audio/configs/sdm710/mixer_paths_tashalite.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tashalite.xml \
-    hardware/qcom/audio/configs/sdm710/mixer_paths_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_i2s.xml \
-    hardware/qcom/audio/configs/sdm710/mixer_paths_skuw.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skuw.xml \
-    hardware/qcom/audio/configs/sdm710/mixer_paths_360cam.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_360cam.xml \
-    hardware/qcom/audio/configs/sdm710/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt \
-    hardware/qcom/audio/configs/sdm710/audio_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tavil.txt \
-    hardware/qcom/audio/configs/sdm710/audio_tuning_mixer_tasha.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tasha.txt \
-    hardware/qcom/audio/configs/sdm710/audio_platform_info_intcodec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_intcodec.xml \
-    hardware/qcom/audio/configs/sdm710/audio_platform_info_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_i2s.xml \
-    hardware/qcom/audio/configs/sdm710/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
-    hardware/qcom/audio/configs/sdm710/audio_platform_info_skuw.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_skuw.xml \
-    hardware/qcom/audio/configs/sdm710/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
-    hardware/qcom/audio/configs/sdm710/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
-    hardware/qcom/audio/configs/sdm710/sound_trigger_mixer_paths_skuw.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_skuw.xml \
-    hardware/qcom/audio/configs/sdm710/sound_trigger_mixer_paths_wcd9335.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9335.xml \
-    hardware/qcom/audio/configs/sdm710/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
-    hardware/qcom/audio/configs/sdm710/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
-    hardware/qcom/audio/configs/sdm710/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/mixer_paths_tavil.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tavil.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/mixer_paths_mtp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_mtp.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/mixer_paths_tasha.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tasha.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/mixer_paths_tashalite.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tashalite.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/mixer_paths_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_i2s.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/mixer_paths_skuw.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skuw.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/mixer_paths_360cam.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_360cam.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/audio_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tavil.txt \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/audio_tuning_mixer_tasha.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tasha.txt \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/audio_platform_info_intcodec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_intcodec.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/audio_platform_info_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_i2s.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/audio_platform_info_skuw.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_skuw.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/sound_trigger_mixer_paths_skuw.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_skuw.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/sound_trigger_mixer_paths_wcd9335.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9335.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml
 
 #XML Audio configuration files
 ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
 ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/sdm710/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
 endif
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/a2dp_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_volumes.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
@@ -135,7 +135,7 @@
 
 # Listen configuration file
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/sdm710/listen_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/listen_platform_info.xml
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm710/listen_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/listen_platform_info.xml
 
 # Reduce client buffer size for fast audio output tracks
 PRODUCT_PROPERTY_OVERRIDES += \
@@ -242,6 +242,18 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 persist.vendor.bt.a2dp_offload_cap=sbc-aptx-aptxhd-aac-ldac
 
+# A2DP offload support
+PRODUCT_PROPERTY_OVERRIDES += \
+ro.bluetooth.a2dp_offload.supported=true
+
+# Disable A2DP offload
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bluetooth.a2dp_offload.disabled=false
+
+# A2DP offload DSP supported encoder list
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bluetooth.a2dp_offload.cap=sbc-aac-aptx-aptxhd-ldac
+
 #enable software decoders for ALAC and APE
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.use.sw.alac.decoder=true
@@ -272,6 +284,14 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.keep_alive.disabled=false
 
+#enable headset calibration
+PRODUCT_PROPERTY_OVERRIDES += \
+audio.volume.headset.gain.depcal=true
+
+#enable dualmic fluence for voice communication
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.audio.fluence.voicecomm=true
+
 # for HIDL related packages
 PRODUCT_PACKAGES += \
     android.hardware.audio@2.0-service \
diff --git a/configs/sdm845/audio_platform_info.xml b/configs/sdm845/audio_platform_info.xml
index caff1e3..9e56c89 100644
--- a/configs/sdm845/audio_platform_info.xml
+++ b/configs/sdm845/audio_platform_info.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
-<!-- Copyright (c) 2014, 2016-2018, The Linux Foundation. All rights reserved. -->
+<!-- Copyright (c) 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 -->
@@ -322,13 +322,13 @@
                         <mic_info mic_device_id="builtin_mic_4"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                     </snd_dev>
-                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_STEREO_DMIC">
+                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_DMIC_STEREO">
                         <mic_info mic_device_id="builtin_mic_1"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                         <mic_info mic_device_id="builtin_mic_2"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                     </snd_dev>
-                    <snd_dev in_snd_device="SND_DEVICE_IN_SPEAKER_STEREO_DMIC">
+                    <snd_dev in_snd_device="SND_DEVICE_IN_SPEAKER_DMIC_STEREO">
                         <mic_info mic_device_id="builtin_mic_1"
                             channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
                         <mic_info mic_device_id="builtin_mic_2"
diff --git a/configs/sdm845/sdm845.mk b/configs/sdm845/sdm845.mk
index beb6fa6..177b00f 100644
--- a/configs/sdm845/sdm845.mk
+++ b/configs/sdm845/sdm845.mk
@@ -29,8 +29,8 @@
 MM_AUDIO_ENABLED_SAFX := true
 AUDIO_FEATURE_ENABLED_HW_ACCELERATED_EFFECTS := false
 AUDIO_FEATURE_ENABLED_AUDIOSPHERE := true
-AUDIO_FEATURE_ENABLED_USB_TUNNEL_AUDIO := true
-AUDIO_FEATURE_ENABLED_SPLIT_A2DP := true
+AUDIO_FEATURE_ENABLED_USB_TUNNEL := true
+AUDIO_FEATURE_ENABLED_A2DP_OFFLOAD := true
 AUDIO_FEATURE_ENABLED_3D_AUDIO := true
 DOLBY_ENABLE := false
 TARGET_USES_QCOM_MM_AUDIO := true
@@ -38,7 +38,7 @@
 
 USE_XML_AUDIO_POLICY_CONF := 1
 BOARD_SUPPORTS_SOUND_TRIGGER := true
-AUDIO_USE_LL_AS_PRIMARY_OUTPUT := true
+AUDIO_USE_DEEP_AS_PRIMARY_OUTPUT := false
 AUDIO_FEATURE_ENABLED_VBAT_MONITOR := true
 AUDIO_FEATURE_ENABLED_ANC_HEADSET := true
 AUDIO_FEATURE_ENABLED_CUSTOMSTEREO := true
@@ -67,41 +67,41 @@
 
 ifneq ($(strip $(TARGET_USES_RRO)), true)
 #Audio Specific device overlays
-DEVICE_PACKAGE_OVERLAYS += hardware/qcom/audio/configs/common/overlay
+DEVICE_PACKAGE_OVERLAYS += vendor/qcom/opensource/audio-hal/primary-hal/configs/common/overlay
 endif
 
 # Audio configuration file
 ifeq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 PRODUCT_COPY_FILES += \
-    device/qcom/common/media/audio_policy.conf:system/etc/audio_policy.conf
+    device/qcom/common/media/audio_policy.conf:vendor/etc/audio_policy.conf
 else
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/sdm845/audio_policy.conf:system/etc/audio_policy.conf
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm845/audio_policy.conf:vendor/etc/audio_policy.conf
 endif
 
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/sdm845/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf \
-    hardware/qcom/audio/configs/sdm845/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
-    hardware/qcom/audio/configs/sdm845/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
-    hardware/qcom/audio/configs/sdm845/mixer_paths_tavil.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tavil.xml \
-    hardware/qcom/audio/configs/sdm845/mixer_paths_skuk.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skuk.xml \
-    hardware/qcom/audio/configs/sdm845/mixer_paths_qvr.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qvr.xml \
-    hardware/qcom/audio/configs/sdm845/mixer_paths_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_i2s.xml \
-    hardware/qcom/audio/configs/sdm845/audio_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tavil.txt \
-    hardware/qcom/audio/configs/sdm845/audio_platform_info_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_i2s.xml \
-    hardware/qcom/audio/configs/sdm845/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
-    hardware/qcom/audio/configs/sdm845/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
-    hardware/qcom/audio/configs/sdm845/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml \
-    hardware/qcom/audio/configs/sdm845/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm845/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm845/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm845/audio_effects.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm845/mixer_paths_tavil.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tavil.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm845/mixer_paths_skuk.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skuk.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm845/mixer_paths_qvr.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qvr.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm845/mixer_paths_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_i2s.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm845/audio_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tavil.txt \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm845/audio_platform_info_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_i2s.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm845/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm845/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm845/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml \
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm845/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml
 
 #XML Audio configuration files
 ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
 ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/sdm845/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm845/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
 endif
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/a2dp_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_audio_policy_configuration.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_volumes.xml \
     $(TOPDIR)frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
@@ -111,7 +111,7 @@
 
 # Listen configuration file
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/sdm845/listen_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/listen_platform_info.xml
+    vendor/qcom/opensource/audio-hal/primary-hal/configs/sdm845/listen_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/listen_platform_info.xml
 
 # Reduce client buffer size for fast audio output tracks
 PRODUCT_PROPERTY_OVERRIDES += \
@@ -197,6 +197,18 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 persist.vendor.bt.a2dp_offload_cap=sbc-aptx-aptxtws-aptxhd-aac-ldac
 
+# A2DP offload support
+PRODUCT_PROPERTY_OVERRIDES += \
+ro.bluetooth.a2dp_offload.supported=true
+
+# Disable A2DP offload
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bluetooth.a2dp_offload.disabled=false
+
+# A2DP offload DSP supported encoder list
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bluetooth.a2dp_offload.cap=sbc-aac-aptx-aptxhd-ldac
+
 #enable software decoders for ALAC and APE
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.use.sw.alac.decoder=true
@@ -239,6 +251,14 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.enable.dp.for.voice=false
 
+#enable headset calibration
+PRODUCT_PROPERTY_OVERRIDES += \
+audio.volume.headset.gain.depcal=true
+
+#enable dualmic fluence for voice communication
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.audio.fluence.voicecomm=true
+
 # for HIDL related packages
 PRODUCT_PACKAGES += \
     android.hardware.audio@2.0-service \
diff --git a/hal/Android.mk b/hal/Android.mk
index 1ba715b..3f82b97 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -9,33 +9,54 @@
 
 AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
 
-ifneq ($(filter msm8974 msm8226 msm8610 apq8084 msm8994 msm8992 msm8996 msm8998 apq8098_latv sdm845 sdm710 qcs605 msmnile $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter msm8974 msm8226 msm8084 msm8610 apq8084 msm8994 msm8992 msm8996 msm8998 apq8098_latv sdm845 sdm710 qcs605 msmnile kona $(MSMSTEPPE) $(TRINKET),$(TARGET_BOARD_PLATFORM)),)
   # B-family platform uses msm8974 code base
   AUDIO_PLATFORM = msm8974
   MULTIPLE_HW_VARIANTS_ENABLED := true
+ifneq ($(filter msm8974,$(TARGET_BOARD_PLATFORM)),)
+  LOCAL_CFLAGS := -DPLATFORM_MSM8974
+  LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="2"
+endif
 ifneq ($(filter msm8610,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_MSM8610
 endif
 ifneq ($(filter msm8226,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_MSM8x26
+  LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="2"
+endif
+ifneq ($(filter msm8084,$(TARGET_BOARD_PLATFORM)),)
+  LOCAL_CFLAGS := -DPLATFORM_MSM8084
+  LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="2"
 endif
 ifneq ($(filter apq8084,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_APQ8084
 endif
 ifneq ($(filter msm8994,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_MSM8994
+  LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4"
+  LOCAL_CFLAGS += -DKPI_OPTIMIZE_ENABLED
 endif
 ifneq ($(filter msm8992,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_MSM8994
+  LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4"
+  LOCAL_CFLAGS += -DKPI_OPTIMIZE_ENABLED
 endif
 ifneq ($(filter msm8996,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_MSM8996
+  LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4"
+  LOCAL_CFLAGS += -DKPI_OPTIMIZE_ENABLED
+  LOCAL_CFLAGS += -DINCALL_MUSIC_ENABLED
 endif
 ifneq ($(filter msm8998 apq8098_latv,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_MSM8998
+  LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4"
+  LOCAL_CFLAGS += -DINCALL_MUSIC_ENABLED
 endif
 ifneq ($(filter sdm845,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_SDM845
+  LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4"
+  LOCAL_CFLAGS += -DINCALL_MUSIC_ENABLED
+  LOCAL_CFLAGS += -DINCALL_STEREO_CAPTURE_ENABLED
 endif
 ifneq ($(filter sdm710,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_SDM710
@@ -45,6 +66,12 @@
 endif
 ifneq ($(filter msmnile,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_MSMNILE
+  LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4"
+  LOCAL_CFLAGS += -DINCALL_MUSIC_ENABLED
+  LOCAL_CFLAGS += -DINCALL_STEREO_CAPTURE_ENABLED
+endif
+ifneq ($(filter kona,$(TARGET_BOARD_PLATFORM)),)
+  LOCAL_CFLAGS := -DPLATFORM_KONA
 endif
 ifneq ($(filter $(MSMSTEPPE) ,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_MSMSTEPPE
@@ -55,6 +82,8 @@
   AUDIO_PLATFORM = msm8916
   MULTIPLE_HW_VARIANTS_ENABLED := true
   LOCAL_CFLAGS := -DPLATFORM_MSM8916
+  LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="2"
+  LOCAL_CFLAGS += -DKPI_OPTIMIZE_ENABLED
 ifneq ($(filter msm8909,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_MSM8909
 endif
@@ -72,14 +101,22 @@
 LOCAL_HEADER_LIBRARIES := libhardware_headers
 
 LOCAL_SRC_FILES := \
-	audio_hw.c \
-	voice.c \
-	platform_info.c \
-	$(AUDIO_PLATFORM)/platform.c \
-        acdb.c
+    audio_hw.c \
+    voice.c \
+    platform_info.c \
+    $(AUDIO_PLATFORM)/platform.c \
+    acdb.c \
+    ahal_config_helper.cpp
 
 LOCAL_SRC_FILES += audio_extn/audio_extn.c \
-                   audio_extn/utils.c
+                   audio_extn/audio_feature_manager.c \
+                   audio_extn/audio_hidl.cpp \
+                   audio_extn/utils.c \
+                   audio_extn/source_track.c \
+                   voice_extn/voice_extn.c \
+                   audio_extn/fm.c \
+                   voice_extn/compress_voip.c \
+                   audio_extn/keep_alive.c
 LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
 LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/techpack/audio/include
 LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
@@ -92,106 +129,104 @@
 
 LOCAL_CFLAGS += -DUSE_VENDOR_EXTN
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_HDMI_EDID)),true)
-    LOCAL_CFLAGS += -DHDMI_EDID
-    LOCAL_SRC_FILES += edid.c
-endif
-
-ifeq ($(strip $(AUDIO_USE_LL_AS_PRIMARY_OUTPUT)),true)
-    LOCAL_CFLAGS += -DUSE_LL_AS_PRIMARY_OUTPUT
-endif
+# ifeq ($(strip $(AUDIO_FEATURE_ENABLED_HDMI_EDID)),true)
+#     LOCAL_CFLAGS += -DHDMI_EDID
+#     LOCAL_SRC_FILES += edid.c
+# endif
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_PCM_OFFLOAD)),true)
     LOCAL_CFLAGS += -DPCM_OFFLOAD_ENABLED
 endif
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_ANC_HEADSET)),true)
-    LOCAL_CFLAGS += -DANC_HEADSET_ENABLED
-endif
+# ifeq ($(strip $(AUDIO_FEATURE_ENABLED_ANC_HEADSET)),true)
+#     LOCAL_CFLAGS += -DANC_HEADSET_ENABLED
+# endif
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_HIFI_AUDIO)),true)
-    LOCAL_CFLAGS += -DHIFI_AUDIO_ENABLED
-endif
+# ifeq ($(strip $(AUDIO_FEATURE_ENABLED_HIFI_AUDIO)),true)
+#     LOCAL_CFLAGS += -DHIFI_AUDIO_ENABLED
+# endif
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_RAS)),true)
-    LOCAL_CFLAGS += -DRAS_ENABLED
-endif
+# ifeq ($(strip $(AUDIO_FEATURE_ENABLED_RAS)),true)
+#     LOCAL_CFLAGS += -DRAS_ENABLED
+# endif
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_VBAT_MONITOR)),true)
-    LOCAL_CFLAGS += -DVBAT_MONITOR_ENABLED
-endif
+#ifeq ($(strip $(AUDIO_FEATURE_ENABLED_VBAT_MONITOR)),true)
+#    LOCAL_CFLAGS += -DVBAT_MONITOR_ENABLED
+#endif
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_FLUENCE)),true)
-    LOCAL_CFLAGS += -DFLUENCE_ENABLED
-endif
+# ifeq ($(strip $(AUDIO_FEATURE_ENABLED_FLUENCE)),true)
+#     LOCAL_CFLAGS += -DFLUENCE_ENABLED
+# endif
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_PROXY_DEVICE)),true)
     LOCAL_CFLAGS += -DAFE_PROXY_ENABLED
 endif
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_KPI_OPTIMIZE)),true)
-    LOCAL_CFLAGS += -DKPI_OPTIMIZE_ENABLED
-endif
+# ifeq ($(strip $(AUDIO_FEATURE_ENABLED_KPI_OPTIMIZE)),true)
+#     LOCAL_CFLAGS += -DKPI_OPTIMIZE_ENABLED
+# endif
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_FM_POWER_OPT)),true)
-    LOCAL_CFLAGS += -DFM_POWER_OPT
-    LOCAL_SRC_FILES += audio_extn/fm.c
-endif
+# ifeq ($(strip $(AUDIO_FEATURE_ENABLED_FM_POWER_OPT)),true)
+#     LOCAL_CFLAGS += -DFM_POWER_OPT
+#     LOCAL_SRC_FILES += audio_extn/fm.c
+# endif
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_USB_TUNNEL_AUDIO)),true)
-    LOCAL_CFLAGS += -DUSB_HEADSET_ENABLED
+
+#ifeq ($(strip $(AUDIO_FEATURE_ENABLED_USB_TUNNEL)),true)
+#    LOCAL_CFLAGS += -DUSB_TUNNEL_ENABLED
     LOCAL_SRC_FILES += audio_extn/usb.c
-endif
+#endif
+
+#ifeq ($(strip $(AUDIO_FEATURE_ENABLED_USB_SIDETONE_VOLUME)),true)
+#    LOCAL_CFLAGS += -DUSB_SIDETONE_VOLUME
+#endif
+
+#ifeq ($(strip $(AUDIO_FEATURE_ENABLED_USB_BURST_MODE)), true)
+#    LOCAL_CFLAGS += -DUSB_BURST_MODE_ENABLED
+#endif
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_HFP)),true)
     LOCAL_CFLAGS += -DHFP_ENABLED
     LOCAL_SRC_FILES += audio_extn/hfp.c
 endif
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_CUSTOMSTEREO)),true)
-    LOCAL_CFLAGS += -DCUSTOM_STEREO_ENABLED
-endif
-
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_SSR)),true)
-    LOCAL_CFLAGS += -DSSR_ENABLED
-    LOCAL_SRC_FILES += audio_extn/ssr.c
-    LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/surround_sound_3mic/
-    LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/common/inc/
-endif
-
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_MULTI_VOICE_SESSIONS)),true)
-    LOCAL_CFLAGS += -DMULTI_VOICE_SESSION_ENABLED
-    LOCAL_SRC_FILES += voice_extn/voice_extn.c
+# ifeq ($(strip $(AUDIO_FEATURE_ENABLED_CUSTOMSTEREO)),true)
+#     LOCAL_CFLAGS += -DCUSTOM_STEREO_ENABLED
+# endif
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_INCALL_MUSIC)),true)
     LOCAL_CFLAGS += -DINCALL_MUSIC_ENABLED
 endif
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_COMPRESS_VOIP)),true)
-    LOCAL_CFLAGS += -DCOMPRESS_VOIP_ENABLED
-    LOCAL_SRC_FILES += voice_extn/compress_voip.c
-endif
+# ifeq ($(strip $(AUDIO_FEATURE_ENABLED_COMPRESS_VOIP)),true)
+#     LOCAL_CFLAGS += -DCOMPRESS_VOIP_ENABLED
+#     LOCAL_SRC_FILES += voice_extn/compress_voip.c
+# endif
 
-endif
+# endif
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_FORMATS)),true)
-LOCAL_CFLAGS += -DAUDIO_EXTN_FORMATS_ENABLED
+  LOCAL_CFLAGS += -DAUDIO_EXTN_FORMATS_ENABLED
 endif
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_SPKR_PROTECTION)),true)
-    LOCAL_CFLAGS += -DSPKR_PROT_ENABLED
-    LOCAL_SRC_FILES += audio_extn/spkr_protection.c
+#ifeq ($(strip $(AUDIO_FEATURE_ENABLED_SPKR_PROTECTION)),true)
+#  LOCAL_CFLAGS += -DSPKR_PROT_ENABLED
+#  LOCAL_SRC_FILES += audio_extn/spkr_protection.c
+#endif
+
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_BG_CAL)),true)
+  LOCAL_CFLAGS += -DBG_CODEC_CAL
 endif
 
+# ifeq ($(strip $(AUDIO_FEATURE_ENABLED_CIRRUS_SPKR_PROTECTION)),true)
+#     LOCAL_CFLAGS += -DSPKR_PROT_ENABLED
+#     LOCAL_SRC_FILES += audio_extn/cirrus_playback.c
+# endif
+
 ifdef MULTIPLE_HW_VARIANTS_ENABLED
   LOCAL_CFLAGS += -DHW_VARIANTS_ENABLED
   LOCAL_SRC_FILES += $(AUDIO_PLATFORM)/hw_info.c
 endif
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_COMPRESS_CAPTURE)),true)
-    LOCAL_CFLAGS += -DCOMPRESS_CAPTURE_ENABLED
-    LOCAL_SRC_FILES += audio_extn/compress_capture.c
-endif
-
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DTS_EAGLE)),true)
     LOCAL_CFLAGS += -DDTS_EAGLE
     LOCAL_SRC_FILES += audio_extn/dts_eagle.c
@@ -211,28 +246,27 @@
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_FLAC_DECODER)),true)
     LOCAL_CFLAGS += -DFLAC_OFFLOAD_ENABLED
-    LOCAL_CFLAGS += -DCOMPRESS_METADATA_NEEDED
+#    LOCAL_CFLAGS += -DCOMPRESS_METADATA_NEEDED
 endif
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_VORBIS_OFFLOAD)),true)
     LOCAL_CFLAGS += -DVORBIS_OFFLOAD_ENABLED
-    LOCAL_CFLAGS += -DCOMPRESS_METADATA_NEEDED
-
+#    LOCAL_CFLAGS += -DCOMPRESS_METADATA_NEEDED
 endif
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_WMA_OFFLOAD)),true)
     LOCAL_CFLAGS += -DWMA_OFFLOAD_ENABLED
-    LOCAL_CFLAGS += -DCOMPRESS_METADATA_NEEDED
+#    LOCAL_CFLAGS += -DCOMPRESS_METADATA_NEEDED
 endif
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_ALAC_OFFLOAD)),true)
     LOCAL_CFLAGS += -DALAC_OFFLOAD_ENABLED
-    LOCAL_CFLAGS += -DCOMPRESS_METADATA_NEEDED
+#    LOCAL_CFLAGS += -DCOMPRESS_METADATA_NEEDED
 endif
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_APE_OFFLOAD)),true)
     LOCAL_CFLAGS += -DAPE_OFFLOAD_ENABLED
-    LOCAL_CFLAGS += -DCOMPRESS_METADATA_NEEDED
+#    LOCAL_CFLAGS += -DCOMPRESS_METADATA_NEEDED
 endif
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_PCM_OFFLOAD_24)),true)
@@ -243,18 +277,20 @@
     LOCAL_CFLAGS += -DAAC_ADTS_OFFLOAD_ENABLED
 endif
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DEV_ARBI)),true)
-    LOCAL_CFLAGS += -DDEV_ARBI_ENABLED
-    LOCAL_SRC_FILES += audio_extn/dev_arbi.c
-endif
+# # Removing flag as feature below is no longer needed
+# ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DEV_ARBI)),true)
+#     LOCAL_CFLAGS += -DDEV_ARBI_ENABLED
+#     LOCAL_SRC_FILES += audio_extn/dev_arbi.c
+# endif
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_RECORD_PLAY_CONCURRENCY)),true)
     LOCAL_CFLAGS += -DRECORD_PLAY_CONCURRENCY
 endif
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_ACDB_LICENSE)), true)
-    LOCAL_CFLAGS += -DDOLBY_ACDB_LICENSE
-endif
+# Removing following flag as dolby is not being used on mobile targets
+# ifeq ($(strip $(AUDIO_FEATURE_ENABLED_ACDB_LICENSE)), true)
+#     LOCAL_CFLAGS += -DDOLBY_ACDB_LICENSE
+# endif
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DS2_DOLBY_DAP)),true)
     LOCAL_CFLAGS += -DDS2_DOLBY_DAP_ENABLED
@@ -271,25 +307,16 @@
     LOCAL_SRC_FILES += audio_extn/passthru.c
 endif
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_KEEP_ALIVE)),true)
-    LOCAL_CFLAGS += -DKEEP_ALIVE_ENABLED
-    LOCAL_SRC_FILES += audio_extn/keep_alive.c
-endif
+# ifeq ($(strip $(AUDIO_FEATURE_ENABLED_KEEP_ALIVE)),true)
+#     LOCAL_CFLAGS += -DKEEP_ALIVE_ENABLED
+#     LOCAL_SRC_FILES += audio_extn/keep_alive.c
+# endif
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_SOURCE_TRACKING)),true)
-    LOCAL_CFLAGS += -DSOURCE_TRACKING_ENABLED
-    LOCAL_SRC_FILES += audio_extn/source_track.c
-endif
-
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_SPLIT_A2DP)),true)
-    LOCAL_CFLAGS += -DSPLIT_A2DP_ENABLED
-    LOCAL_SRC_FILES += audio_extn/a2dp.c
-endif
-
-ifeq ($(strip $(AUDIO_FEATURE_IP_HDLR_ENABLED)),true)
-    LOCAL_CFLAGS += -DAUDIO_EXTN_IP_HDLR_ENABLED
-    LOCAL_SRC_FILES += audio_extn/ip_hdlr_intf.c
-endif
+#This feature is depricated, file disabled
+#ifeq ($(strip $(AUDIO_FEATURE_IP_HDLR_ENABLED)),true)
+#    LOCAL_CFLAGS += -DAUDIO_EXTN_IP_HDLR_ENABLED
+#    LOCAL_SRC_FILES += audio_extn/ip_hdlr_intf.c
+#endif
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_QAF)),true)
     LOCAL_CFLAGS += -DQAF_EXTN_ENABLED
@@ -297,6 +324,10 @@
     LOCAL_SRC_FILES += audio_extn/qaf.c
 endif
 
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_CONCURRENT_CAPTURE)),true)
+    LOCAL_CFLAGS += -DCONCURRENT_CAPTURE_ENABLED
+endif
+
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_COMPRESS_INPUT)),true)
     LOCAL_CFLAGS += -DCOMPRESS_INPUT_ENABLED
     LOCAL_SRC_FILES += audio_extn/compress_in.c
@@ -313,25 +344,30 @@
 endif
 
 LOCAL_SHARED_LIBRARIES := \
-	liblog \
-	libcutils \
-	libtinyalsa \
-	libtinycompress_vendor \
-	libaudioroute \
-	libdl \
-	libaudioutils \
-	libexpat
+    liblog \
+    libcutils \
+    libtinyalsa \
+    libtinycompress \
+    libaudioroute \
+    libdl \
+    libaudioutils \
+    libexpat \
+    libqti_vndfwk_detect \
+    libhwbinder \
+    libhidlbase \
+    libhidltransport
 
 LOCAL_C_INCLUDES += \
-	external/tinyalsa/include \
-	external/tinycompress/include \
-	system/media/audio_utils/include \
-	external/expat/lib \
-	$(call include-path-for, audio-route) \
-	$(call include-path-for, audio-effects) \
-	$(LOCAL_PATH)/$(AUDIO_PLATFORM) \
-	$(LOCAL_PATH)/audio_extn \
-	$(LOCAL_PATH)/voice_extn
+    external/tinyalsa/include \
+    external/tinycompress/include \
+    system/media/audio_utils/include \
+    external/expat/lib \
+    vendor/qcom/opensource/core-utils/fwk-detect \
+    $(call include-path-for, audio-route) \
+    $(call include-path-for, audio-effects) \
+    $(LOCAL_PATH)/$(AUDIO_PLATFORM) \
+    $(LOCAL_PATH)/audio_extn \
+    $(LOCAL_PATH)/voice_extn
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_LISTEN)),true)
     LOCAL_CFLAGS += -DAUDIO_LISTEN_ENABLED
@@ -340,10 +376,23 @@
 endif
 
 ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
+        LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
         LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/techpack/audio/include
         LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
 endif
 
+ifeq ($(strip $(AUDIO_FEATURE_SUPPORTED_EXTERNAL_BT)),true)
+  LOCAL_CFLAGS += -DEXTERNAL_BT_SUPPORTED
+endif
+
+ifeq ($(strip $(AUDIO_FEATURE_FLICKER_SENSOR_INPUT)),true)
+  LOCAL_CFLAGS += -DFLICKER_SENSOR_INPUT
+endif
+
+ifeq ($(strip $(AUDIO_FEATURE_NO_AUDIO_OUT)),true)
+  LOCAL_CFLAGS += -DNO_AUDIO_OUT
+endif
+
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXT_HDMI)),true)
     LOCAL_CFLAGS += -DAUDIO_EXTERNAL_HDMI_ENABLED
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_HDMI_PASSTHROUGH)),true)
@@ -365,6 +414,9 @@
     LOCAL_CFLAGS += -DSOUND_TRIGGER_PLATFORM_NAME=$(TARGET_BOARD_PLATFORM)
     LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/sound_trigger
     LOCAL_SRC_FILES += audio_extn/soundtrigger.c
+ifneq ($(filter msm8996,$(TARGET_BOARD_PLATFORM)),)
+    LOCAL_HEADER_LIBRARIES += sound_trigger.primary_headers
+endif
 endif
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_AUXPCM_BT)),true)
@@ -378,9 +430,9 @@
     LOCAL_SHARED_LIBRARIES += libperipheral_client
 endif
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DISPLAY_PORT)),true)
-    LOCAL_CFLAGS += -DDISPLAY_PORT_ENABLED
-endif
+# ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DISPLAY_PORT)),true)
+#     LOCAL_CFLAGS += -DDISPLAY_PORT_ENABLED
+# endif
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_GEF_SUPPORT)),true)
     LOCAL_CFLAGS += -DAUDIO_GENERIC_EFFECT_FRAMEWORK_ENABLED
@@ -406,16 +458,11 @@
     LOCAL_CFLAGS += -DINSTANCE_ID_ENABLED
 endif
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_USB_BURST_MODE)), true)
-    LOCAL_CFLAGS += -DUSB_BURST_MODE_ENABLED
-endif
-
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_BATTERY_LISTENER)), true)
     LOCAL_CFLAGS += -DBATTERY_LISTENER_ENABLED
     LOCAL_SRC_FILES += audio_extn/battery_listener.cpp
     LOCAL_SHARED_LIBRARIES += android.hardware.health@1.0 android.hardware.health@2.0 \
-                              libhidltransport libbase libhidlbase libhwbinder \
-                              libutils android.hardware.power@1.2
+                              libbase libutils android.hardware.power@1.2
     LOCAL_STATIC_LIBRARIES := libhealthhalutils
 endif
 
@@ -429,15 +476,25 @@
     LOCAL_SRC_FILES += audio_extn/ffv.c
 endif
 
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_AHAL_EXT)),true)
+    LOCAL_CFLAGS += -DAHAL_EXT_ENABLED
+    LOCAL_SHARED_LIBRARIES += vendor.qti.hardware.audiohalext@1.0
+endif
+
 LOCAL_CFLAGS += -Wall -Werror
 
 LOCAL_COPY_HEADERS_TO   := mm-audio
 LOCAL_COPY_HEADERS      := audio_extn/audio_defs.h
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_SND_MONITOR)), true)
-    LOCAL_CFLAGS += -DSND_MONITOR_ENABLED
-    LOCAL_SRC_FILES += audio_extn/sndmonitor.c
-endif
+# ifeq ($(strip $(AUDIO_FEATURE_ENABLED_SND_MONITOR)), true)
+#     LOCAL_CFLAGS += -DSND_MONITOR_ENABLED
+#     LOCAL_SRC_FILES += audio_extn/sndmonitor.c
+# endif
+
+# ifeq ($(strip $(AUDIO_FEATURE_ENABLED_MAXX_AUDIO)), true)
+#     LOCAL_CFLAGS += -DMAXXAUDIO_QDSP_ENABLED
+#     LOCAL_SRC_FILES += audio_extn/maxxaudio.c
+# endif
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_GCOV)),true)
     LOCAL_CFLAGS += --coverage -fprofile-arcs -ftest-coverage
@@ -456,6 +513,10 @@
 
 LOCAL_MODULE_TAGS := optional
 
+LOCAL_MODULE_OWNER := qti
+
+LOCAL_PROPRIETARY_MODULE := true
+
 LOCAL_VENDOR_MODULE := true
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/hal/Makefile.am b/hal/Makefile.am
index aafc3e9..bdf1b9a 100644
--- a/hal/Makefile.am
+++ b/hal/Makefile.am
@@ -26,7 +26,7 @@
 endif
 
 if USBAUDIO
-AM_CFLAGS += -DUSB_HEADSET_ENABLED
+AM_CFLAGS += -DUSB_TUNNEL_ENABLED
 c_sources += audio_extn/usb.c
 endif
 
@@ -38,7 +38,7 @@
 if SSR
 AM_CFLAGS += -DSSR_ENABLED
 c_sources += audio_extn/ssr.c
-AM_CFLAGS +=  -I ${WORKSPACE}/audio/mm-audio-noship/surround_sound_3mic/libsurround_3mic_proc/surround_rec_interface/inc/
+AM_CFLAGS +=  -I ${WORKSPACE}/audio/mm-audio-external-noship/surround_sound_3mic/libsurround_3mic_proc/surround_rec_interface/inc/
 endif
 
 if MULTI_VOICE_SESSIONS
@@ -93,11 +93,11 @@
 c_sources += audio_extn/source_track.c
 endif
 
-if LISTEN
-AM_CFLAGS += -DAUDIO_LISTEN_ENABLED
-AM_CFLAGS += -I ${WORKSPACE}/audio/mm-audio-noship/audio-listen
-c_sources += audio_extn/listen.c
-endif
+#if LISTEN
+#AM_CFLAGS += -DAUDIO_LISTEN_ENABLED
+#AM_CFLAGS += -I ${WORKSPACE}/audio/mm-audio-external-noship/audio-listen
+#c_sources += audio_extn/listen.c
+#endif
 
 if SOUND_TRIGGER
 AM_CFLAGS += -DSOUND_TRIGGER_ENABLED
@@ -170,8 +170,8 @@
 c_sources += audio_extn/adsp_hdlr.c
 endif
 
-if SPLIT_A2DP
-AM_CFLAGS += -DSPLIT_A2DP_ENABLED
+if A2DP_OFFLOAD
+AM_CFLAGS += -DA2DP_OFFLOAD_ENABLED
 c_sources += audio_extn/a2dp.c
 endif
 
diff --git a/hal/ahal_config_helper.cpp b/hal/ahal_config_helper.cpp
new file mode 100644
index 0000000..92bb520
--- /dev/null
+++ b/hal/ahal_config_helper.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 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
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ahal_config_helper"
+
+#include "ahal_config_helper.h"
+#include <cutils/properties.h>
+#include <log/log.h>
+
+struct AHalConfigHelper {
+    static AHalConfigHelper* mConfigHelper;
+
+    AHalConfigHelper() : isRemote(false) { };
+    static AHalConfigHelper* getAHalConfInstance() {
+        if (!mConfigHelper)
+            mConfigHelper = new AHalConfigHelper();
+        return mConfigHelper;
+    }
+    void initDefaultConfig(bool isVendorEnhancedFwk);
+    AHalValues* getAHalValues();
+    inline void retrieveConfigs();
+
+    AHalValues mConfigs;
+    bool isRemote; // configs specified from remote
+};
+
+AHalConfigHelper* AHalConfigHelper::mConfigHelper;
+
+void AHalConfigHelper::initDefaultConfig(bool isVendorEnhancedFwk)
+{
+    ALOGV("%s: enter", __FUNCTION__);
+    if (isVendorEnhancedFwk) {
+        mConfigs = {
+            true,        /* SND_MONITOR */
+            false,       /* COMPRESS_CAPTURE */
+            true,        /* SOURCE_TRACK */
+            true,        /* SSREC */
+            true,        /* AUDIOSPHERE */
+            true,        /* AFE_PROXY */
+            false,       /* USE_DEEP_AS_PRIMARY_OUTPUT */
+            true,        /* HDMI_EDID */
+            true,        /* KEEP_ALIVE */
+            false,       /* HIFI_AUDIO */
+            true,        /* RECEIVER_AIDED_STEREO */
+            true,        /* KPI_OPTIMIZE */
+            true,        /* DISPLAY_PORT */
+            true,        /* FLUENCE */
+            true,        /* CUSTOM_STEREO */
+            true,        /* ANC_HEADSET */
+            false,       /* DSM_FEEDBACK */
+            true,        /* USB_OFFLOAD */
+            false,       /* USB_OFFLOAD_BURST_MODE */
+            false,       /* USB_OFFLOAD_SIDETONE_VOLM */
+            true,        /* A2DP_OFFLOAD */
+            true,        /* VBAT */
+            true,        /* COMPRESS_METADATA_NEEDED */
+            false,       /* COMPRESS_VOIP */
+            false,       /* DYNAMIC_ECNS */
+        };
+    } else {
+        mConfigs = {
+            true,        /* SND_MONITOR */
+            false,       /* COMPRESS_CAPTURE */
+            false,       /* SOURCE_TRACK */
+            false,       /* SSREC */
+            false,       /* AUDIOSPHERE */
+            false,       /* AFE_PROXY */
+            false,       /* USE_DEEP_AS_PRIMARY_OUTPUT */
+            false,       /* HDMI_EDID */
+            false,       /* KEEP_ALIVE */
+            false,       /* HIFI_AUDIO */
+            false,       /* RECEIVER_AIDED_STEREO */
+            false,       /* KPI_OPTIMIZE */
+            false,       /* DISPLAY_PORT */
+            false,       /* FLUENCE */
+            false,       /* CUSTOM_STEREO */
+            false,       /* ANC_HEADSET */
+            false,       /* DSM_FEEDBACK */
+            true,        /* USB_OFFLOAD */
+            false,       /* USB_OFFLOAD_BURST_MODE */
+            false,       /* USB_OFFLOAD_SIDETONE_VOLM */
+            true,        /* A2DP_OFFLOAD */
+            false,       /* VBAT */
+            false,       /* COMPRESS_METADATA_NEEDED */
+            false,       /* COMPRESS_VOIP */
+            false,       /* DYNAMIC_ECNS */
+        };
+    }
+}
+
+AHalValues* AHalConfigHelper::getAHalValues()
+{
+    ALOGV("%s: enter", __FUNCTION__);
+    retrieveConfigs();
+    return &mConfigs;
+}
+
+void AHalConfigHelper::retrieveConfigs()
+{
+    ALOGV("%s: enter", __FUNCTION__);
+    // ToDo: Add logic to query AHalValues from config store
+    // once support is added to it
+    return;
+}
+
+extern "C" {
+
+AHalValues* confValues = nullptr;
+
+void audio_extn_ahal_config_helper_init(bool is_vendor_enhanced_fwk)
+{
+    AHalConfigHelper* confInstance = AHalConfigHelper::getAHalConfInstance();
+    if (confInstance)
+        confInstance->initDefaultConfig(is_vendor_enhanced_fwk);
+}
+
+AHalValues* audio_extn_get_feature_values()
+{
+    AHalConfigHelper* confInstance = AHalConfigHelper::getAHalConfInstance();
+    if (confInstance)
+        confValues = confInstance->getAHalValues();
+    return confValues;
+}
+
+bool audio_extn_is_config_from_remote()
+{
+    AHalConfigHelper* confInstance = AHalConfigHelper::getAHalConfInstance();
+    if (confInstance)
+        return confInstance->isRemote;
+    return false;
+}
+
+} // extern C
diff --git a/hal/ahal_config_helper.h b/hal/ahal_config_helper.h
new file mode 100644
index 0000000..6e19bfa
--- /dev/null
+++ b/hal/ahal_config_helper.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 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
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// ToDo: This struct must be used only if config store is disabled.
+// Use AHalValues struct from config store once support is added.
+struct AHalValues_t {
+    bool snd_monitor_enabled;
+    bool compress_capture_enabled;
+    bool source_track_enabled;
+    bool ssrec_enabled;
+    bool audiosphere_enabled;
+    bool afe_proxy_enabled;
+    bool use_deep_buffer_as_primary_output;
+    bool hdmi_edid_enabled;
+    bool keep_alive_enabled;
+    bool hifi_audio_enabled;
+    bool receiver_aided_stereo;
+    bool kpi_optimize_enabled;
+    bool display_port_enabled;
+    bool fluence_enabled;
+    bool custom_stereo_enabled;
+    bool anc_headset_enabled;
+    bool dsm_feedback_enabled;
+    bool usb_offload_enabled;
+    bool usb_offload_burst_mode;
+    bool usb_offload_sidetone_vol_enabled;
+    bool a2dp_offload_enabled;
+    bool vbat_enabled;
+    bool compress_metadata_needed;
+    bool compress_voip_enabled;
+    bool dynamic_ecns_enabled;
+};
+typedef struct AHalValues_t AHalValues;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void audio_extn_ahal_config_helper_init(bool isVendorEnhancedFwk);
+AHalValues* audio_extn_get_feature_values();
+bool audio_extn_is_config_from_remote();
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/hal/audio_extn/Android.mk b/hal/audio_extn/Android.mk
new file mode 100644
index 0000000..3897ba4
--- /dev/null
+++ b/hal/audio_extn/Android.mk
@@ -0,0 +1,399 @@
+#--------------------------------------------
+#          Build SND_MONITOR LIB
+#--------------------------------------------
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= libsndmonitor
+LOCAL_MODULE_OWNER := third_party
+LOCAL_PROPRIETARY_MODULE := true
+
+AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
+
+LOCAL_SRC_FILES:= \
+        sndmonitor.c
+
+LOCAL_CFLAGS += \
+    -Wall \
+    -Werror \
+    -Wno-unused-function \
+    -Wno-unused-variable \
+
+LOCAL_SHARED_LIBRARIES := \
+	libaudioutils \
+	libcutils \
+	liblog \
+	libtinyalsa \
+	libtinycompress \
+	libaudioroute \
+	libdl \
+	libexpat
+
+LOCAL_C_INCLUDES := \
+	external/tinyalsa/include \
+	external/tinycompress/include \
+	system/media/audio_utils/include \
+	external/expat/lib \
+	$(call include-path-for, audio-route) \
+	vendor/qcom/opensource/audio-hal/primary-hal/hal \
+	$(call include-path-for, audio-effects)
+
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/techpack/audio/include
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DLKM)),true)
+  LOCAL_HEADER_LIBRARIES += audio_kernel_headers
+  LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/vendor/qcom/opensource/audio-kernel/include
+  LOCAL_ADDITIONAL_DEPENDENCIES += $(BOARD_VENDOR_KERNEL_MODULES)
+endif
+
+LOCAL_HEADER_LIBRARIES += libhardware_headers
+LOCAL_HEADER_LIBRARIES += libsystem_headers
+include $(BUILD_SHARED_LIBRARY)
+
+#--------------------------------------------
+#          Build COMPRESS_CAPTURE LIB
+#--------------------------------------------
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= libcomprcapture
+LOCAL_MODULE_OWNER := third_party
+LOCAL_PROPRIETARY_MODULE := true
+
+AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
+
+ifneq ($(filter sdm845 sdm710 qcs605 msmnile $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
+  # B-family platform uses msm8974 code base
+  AUDIO_PLATFORM = msm8974
+  MULTIPLE_HW_VARIANTS_ENABLED := true
+endif
+
+LOCAL_SRC_FILES:= \
+        compress_capture.c
+
+LOCAL_CFLAGS += \
+    -Wall \
+    -Werror \
+    -Wno-unused-function \
+    -Wno-unused-variable \
+
+LOCAL_SHARED_LIBRARIES := \
+	libaudioutils \
+	libcutils \
+	liblog \
+	libtinyalsa \
+	libtinycompress \
+	libaudioroute \
+	libdl \
+	libexpat
+
+LOCAL_C_INCLUDES := \
+	external/tinyalsa/include \
+	external/tinycompress/include \
+	system/media/audio_utils/include \
+	external/expat/lib \
+	$(call include-path-for, audio-route) \
+	vendor/qcom/opensource/audio-hal/primary-hal/hal \
+    vendor/qcom/opensource/audio-hal/primary-hal/hal/$(AUDIO_PLATFORM) \
+	$(call include-path-for, audio-effects)
+
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/techpack/audio/include
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DLKM)),true)
+  LOCAL_HEADER_LIBRARIES += audio_kernel_headers
+  LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/vendor/qcom/opensource/audio-kernel/include
+  LOCAL_ADDITIONAL_DEPENDENCIES += $(BOARD_VENDOR_KERNEL_MODULES)
+endif
+
+LOCAL_HEADER_LIBRARIES += libhardware_headers
+LOCAL_HEADER_LIBRARIES += libsystem_headers
+include $(BUILD_SHARED_LIBRARY)
+
+#-------------------------------------------
+#            Build SSREC LIB
+#-------------------------------------------
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= libssrec
+LOCAL_VENDOR_MODULE := true
+
+AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
+
+ifneq ($(filter sdm845 msmnile $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
+  # B-family platform uses msm8974 code base
+  AUDIO_PLATFORM = msm8974
+  MULTIPLE_HW_VARIANTS_ENABLED := true
+endif
+
+LOCAL_SRC_FILES:= ssr.c
+
+LOCAL_CFLAGS += \
+    -Wall \
+    -Werror \
+    -Wno-unused-function \
+    -Wno-unused-variable
+
+LOCAL_SHARED_LIBRARIES := \
+    libaudioutils \
+    libcutils \
+    liblog \
+    libtinyalsa \
+    libtinycompress \
+    libaudioroute \
+    libdl \
+    libexpat
+
+LOCAL_C_INCLUDES := \
+    vendor/qcom/opensource/audio-hal/primary-hal/hal \
+    vendor/qcom/opensource/audio-hal/primary-hal/hal/$(AUDIO_PLATFORM) \
+    external/tinyalsa/include \
+    external/tinycompress/include \
+    external/expat/lib \
+    system/media/audio_utils/include \
+    $(call include-path-for, audio-route) \
+    $(call include-path-for, audio-effects) \
+    $(TARGET_OUT_HEADERS)/mm-audio/surround_sound_3mic/ \
+    $(TARGET_OUT_HEADERS)/common/inc/
+
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/techpack/audio/include
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DLKM)),true)
+  LOCAL_HEADER_LIBRARIES += audio_kernel_headers
+  LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/vendor/qcom/opensource/audio-kernel/include
+  LOCAL_ADDITIONAL_DEPENDENCIES += $(BOARD_VENDOR_KERNEL_MODULES)
+endif
+
+LOCAL_HEADER_LIBRARIES += libhardware_headers
+LOCAL_HEADER_LIBRARIES += libsystem_headers
+#include $(BUILD_SHARED_LIBRARY)
+
+#--------------------------------------------
+#          Build HDMI_EDID LIB
+#--------------------------------------------
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= libhdmiedid
+LOCAL_MODULE_OWNER := third_party
+LOCAL_PROPRIETARY_MODULE := true
+
+PRIMARY_HAL_PATH := vendor/qcom/opensource/audio-hal/primary-hal/hal
+AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
+
+ifneq ($(filter sdm845 msmnile $(MSMSTEPPE) $(TRINKET),$(TARGET_BOARD_PLATFORM)),)
+  # B-family platform uses msm8974 code base
+  AUDIO_PLATFORM = msm8974
+endif
+
+LOCAL_SRC_FILES:= \
+        edid.c
+
+LOCAL_CFLAGS += \
+    -Wall \
+    -Werror \
+    -Wno-unused-function \
+    -Wno-unused-variable \
+
+LOCAL_SHARED_LIBRARIES := \
+	libaudioutils \
+	libcutils \
+	liblog \
+	libtinyalsa \
+	libtinycompress \
+	libaudioroute \
+	libdl \
+	libexpat
+
+LOCAL_C_INCLUDES := \
+	external/tinyalsa/include \
+	external/tinycompress/include \
+	system/media/audio_utils/include \
+	external/expat/lib \
+	$(call include-path-for, audio-route) \
+	$(PRIMARY_HAL_PATH) \
+	$(PRIMARY_HAL_PATH)/$(AUDIO_PLATFORM) \
+	$(call include-path-for, audio-effects)
+
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/techpack/audio/include
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DLKM)),true)
+  LOCAL_HEADER_LIBRARIES += audio_kernel_headers
+  LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/vendor/qcom/opensource/audio-kernel/include
+  LOCAL_ADDITIONAL_DEPENDENCIES += $(BOARD_VENDOR_KERNEL_MODULES)
+endif
+
+LOCAL_HEADER_LIBRARIES += libhardware_headers
+LOCAL_HEADER_LIBRARIES += libsystem_headers
+include $(BUILD_SHARED_LIBRARY)
+
+#--------------------------------------------
+#          Build SPKR_PROTECT LIB
+#--------------------------------------------
+include $(CLEAR_VARS)
+
+ifneq ($(filter sdm845 msmnile $(MSMSTEPPE) $(TRINKET) kona,$(TARGET_BOARD_PLATFORM)),)
+  # B-family platform uses msm8974 code base
+  AUDIO_PLATFORM = msm8974
+endif
+
+LOCAL_MODULE:= libspkrprot
+LOCAL_MODULE_OWNER := third_party
+LOCAL_PROPRIETARY_MODULE := true
+
+LOCAL_SRC_FILES:= \
+        spkr_protection.c
+
+LOCAL_CFLAGS += \
+    -Wall \
+    -Werror \
+    -Wno-unused-function \
+    -Wno-unused-variable \
+
+LOCAL_CFLAGS += -DSPKR_PROT_ENABLED
+
+LOCAL_SHARED_LIBRARIES := \
+    libaudioutils \
+    libcutils \
+    liblog \
+    libtinyalsa \
+    libtinycompress \
+    libaudioroute \
+    libdl \
+    libexpat
+
+LOCAL_C_INCLUDES := \
+    external/tinyalsa/include \
+    external/tinycompress/include \
+    system/media/audio_utils/include \
+    external/expat/lib \
+    $(call include-path-for, audio-route) \
+    vendor/qcom/opensource/audio-hal/primary-hal/hal \
+    vendor/qcom/opensource/audio-hal/primary-hal/hal/audio_extn \
+    vendor/qcom/opensource/audio-hal/primary-hal/hal/$(AUDIO_PLATFORM) \
+    vendor/qcom/opensource/audio-kernel/include/uapi/ \
+    $(call include-path-for, audio-effects)
+
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/techpack/audio/include
+
+LOCAL_HEADER_LIBRARIES += libhardware_headers
+LOCAL_HEADER_LIBRARIES += libsystem_headers
+include $(BUILD_SHARED_LIBRARY)
+#====================================================================================================
+# --- enable 3rd Party Spkr-prot lib
+#====================================================================================================
+
+include $(CLEAR_VARS)
+
+ifneq ($(filter sdm845 msmnile $(MSMSTEPPE) $(TRINKET) kona,$(TARGET_BOARD_PLATFORM)),)
+  # B-family platform uses msm8974 code base
+  AUDIO_PLATFORM = msm8974
+endif
+
+LOCAL_MODULE:= libcirrusspkrprot
+LOCAL_MODULE_OWNER := third_party
+LOCAL_PROPRIETARY_MODULE := true
+
+LOCAL_SRC_FILES:= \
+        cirrus_playback.c
+
+LOCAL_CFLAGS += \
+    -Wall \
+    -Werror \
+    -Wno-unused-function \
+    -Wno-unused-variable \
+
+LOCAL_CFLAGS += -DENABLE_CIRRUS_DETECTION
+LOCAL_CFLAGS += -DCIRRUS_FACTORY_CALIBRATION
+
+LOCAL_SHARED_LIBRARIES := \
+    libaudioutils \
+    libcutils \
+    liblog \
+    libtinyalsa \
+    libaudioroute \
+    libdl \
+    libexpat
+
+LOCAL_C_INCLUDES := \
+    external/tinyalsa/include \
+    external/tinycompress/include \
+    system/media/audio_utils/include \
+    external/expat/lib \
+    $(call include-path-for, audio-route) \
+    vendor/qcom/opensource/audio-hal/primary-hal/hal \
+    vendor/qcom/opensource/audio-hal/primary-hal/hal/audio_extn \
+    vendor/qcom/opensource/audio-hal/primary-hal/hal/$(AUDIO_PLATFORM) \
+    vendor/qcom/opensource/audio-kernel/include/uapi/ \
+    $(call include-path-for, audio-effects)
+
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/techpack/audio/include
+
+LOCAL_HEADER_LIBRARIES += libhardware_headers
+LOCAL_HEADER_LIBRARIES += libsystem_headers
+include $(BUILD_SHARED_LIBRARY)
+
+#-------------------------------------------
+#            Build A2DP_OFFLOAD LIB
+#-------------------------------------------
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= liba2dpoffload
+LOCAL_PROPRIETARY_MODULE := true
+
+PRIMARY_HAL_PATH := vendor/qcom/opensource/audio-hal/primary-hal/hal
+AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
+
+ifneq ($(filter sdm845 msmnile $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
+  # B-family platform uses msm8974 code base
+  AUDIO_PLATFORM = msm8974
+  MULTIPLE_HW_VARIANTS_ENABLED := true
+endif
+
+LOCAL_SRC_FILES:= \
+        a2dp.c
+
+LOCAL_CFLAGS += \
+    -Wall \
+    -Werror \
+    -Wno-unused-function \
+    -Wno-unused-variable
+
+LOCAL_SHARED_LIBRARIES := \
+    libaudioutils \
+    libcutils \
+    liblog \
+    libtinyalsa \
+    libtinycompress \
+    libaudioroute \
+    libdl \
+    libexpat
+
+LOCAL_C_INCLUDES := \
+    $(PRIMARY_HAL_PATH) \
+    $(PRIMARY_HAL_PATH)/$(AUDIO_PLATFORM) \
+    external/tinyalsa/include \
+    external/tinycompress/include \
+    external/expat/lib \
+    system/media/audio_utils/include \
+    $(call include-path-for, audio-route) \
+
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/techpack/audio/include
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DLKM)),true)
+  LOCAL_HEADER_LIBRARIES += audio_kernel_headers
+  LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/vendor/qcom/opensource/audio-kernel/include
+  LOCAL_ADDITIONAL_DEPENDENCIES += $(BOARD_VENDOR_KERNEL_MODULES)
+endif
+
+LOCAL_HEADER_LIBRARIES += libhardware_headers
+LOCAL_HEADER_LIBRARIES += libsystem_headers
+include $(BUILD_SHARED_LIBRARY)
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index f08f379..fb71083 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015-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
@@ -26,12 +26,13 @@
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
-#define LOG_TAG "split_a2dp"
+#define LOG_TAG "a2dp_offload"
 /*#define LOG_NDEBUG 0*/
 #define LOG_NDDEBUG 0
 #include <errno.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <dlfcn.h>
+#include <pthread.h>
 #include "audio_hw.h"
 #include "platform.h"
 #include "platform_api.h"
@@ -48,7 +49,6 @@
 #include <log_utils.h>
 #endif
 
-#ifdef SPLIT_A2DP_ENABLED
 #define AUDIO_PARAMETER_A2DP_STARTED "A2dpStarted"
 #define BT_IPC_SOURCE_LIB_NAME  "libbthost_if.so"
 #define BT_IPC_SINK_LIB_NAME    "libbthost_if_sink.so"
@@ -93,6 +93,7 @@
 #define MIXER_ENC_FMT_APTX         "APTX"
 #define MIXER_FMT_TWS_CHANNEL_MODE "TWS Channel Mode"
 #define MIXER_ENC_FMT_APTXHD       "APTXHD"
+#define MIXER_END_FMT_LDAC         "LDAC"
 #define MIXER_ENC_FMT_NONE         "NONE"
 #define ENCODER_LATENCY_SBC        10
 #define ENCODER_LATENCY_APTX       40
@@ -101,6 +102,7 @@
 //To Do: Fine Tune Encoder CELT/LDAC latency.
 #define ENCODER_LATENCY_CELT       40
 #define ENCODER_LATENCY_LDAC       40
+#define ENCODER_LATENCY_PCM        50
 #define DEFAULT_SINK_LATENCY_SBC       140
 #define DEFAULT_SINK_LATENCY_APTX      160
 #define DEFAULT_SINK_LATENCY_APTX_HD   180
@@ -108,6 +110,17 @@
 //To Do: Fine Tune Default CELT/LDAC Latency.
 #define DEFAULT_SINK_LATENCY_CELT      180
 #define DEFAULT_SINK_LATENCY_LDAC      180
+#define DEFAULT_SINK_LATENCY_PCM       140
+
+#define SYSPROP_A2DP_OFFLOAD_SUPPORTED "ro.bluetooth.a2dp_offload.supported"
+#define SYSPROP_A2DP_OFFLOAD_DISABLED  "persist.bluetooth.a2dp_offload.disabled"
+#define SYSPROP_A2DP_CODEC_LATENCIES   "vendor.audio.a2dp.codec.latency"
+
+// Default encoder bit width
+#define DEFAULT_ENCODER_BIT_FORMAT 16
+
+// Default encoder latency
+#define DEFAULT_ENCODER_LATENCY    200
 
 // Slimbus Tx sample rate for ABR feedback channel
 #define ABR_TX_SAMPLE_RATE             "KHZ_8"
@@ -146,6 +159,7 @@
     CODEC_TYPE_LDAC = AUDIO_FORMAT_LDAC, // 0x23000000UL
     CODEC_TYPE_CELT = 603979776u, // 0x24000000UL
     CODEC_TYPE_APTX_AD = 620756992u, // 0x25000000UL
+    CODEC_TYPE_PCM = AUDIO_FORMAT_PCM_16_BIT, // 0x1u
 }codec_t;
 
 /*
@@ -213,6 +227,10 @@
     PEAK_BIT_RATE,
 } frame_control_type_t;
 
+// --- external function dependency ---
+fp_platform_get_pcm_device_id_t fp_platform_get_pcm_device_id;
+fp_check_a2dp_restore_t fp_check_a2dp_restore;
+
 /* PCM config for ABR Feedback hostless front end */
 static struct pcm_config pcm_config_abr = {
     .channels = 1,
@@ -605,6 +623,7 @@
     uint32_t sampling_rate;
     uint32_t bitrate;
     uint32_t bits_per_sample;
+    struct aac_frame_size_control_t frame_ctl;
 } audio_aac_encoder_config;
 #endif
 
@@ -667,60 +686,15 @@
 
 /*********** END of DSP configurable structures ********************/
 
-/* API to identify DSP encoder captabilities */
-static void a2dp_offload_codec_cap_parser(char *value)
-{
-    char *tok = NULL,*saveptr;
-
-    tok = strtok_r(value, "-", &saveptr);
-    while (tok != NULL) {
-        if (strcmp(tok, "sbc") == 0) {
-            ALOGD("%s: SBC offload supported\n",__func__);
-            a2dp.is_a2dp_offload_supported = true;
-            break;
-        } else if (strcmp(tok, "aptx") == 0) {
-            ALOGD("%s: aptx offload supported\n",__func__);
-            a2dp.is_a2dp_offload_supported = true;
-            break;
-        } else if (strcmp(tok, "aptxtws") == 0) {
-            ALOGD("%s: aptx dual mono offload supported\n",__func__);
-            a2dp.is_a2dp_offload_supported = true;
-            break;
-        } else if (strcmp(tok, "aptxhd") == 0) {
-            ALOGD("%s: aptx HD offload supported\n",__func__);
-            a2dp.is_a2dp_offload_supported = true;
-            break;
-        } else if (strcmp(tok, "aac") == 0) {
-            ALOGD("%s: aac offload supported\n",__func__);
-            a2dp.is_a2dp_offload_supported = true;
-            break;
-        } else if (strcmp(tok, "celt") == 0) {
-            ALOGD("%s: celt offload supported\n",__func__);
-            a2dp.is_a2dp_offload_supported = true;
-            break;
-        } else if (strcmp(tok, "ldac") == 0) {
-            ALOGD("%s: ldac offload supported\n",__func__);
-            a2dp.is_a2dp_offload_supported = true;
-            break;
-        } else if( strcmp(tok, "aptxadaptive") == 0) {
-            ALOGD("%s: aptx adaptive offload supported\n",__func__);
-            a2dp.is_a2dp_offload_supported = true;
-        }
-        tok = strtok_r(NULL, "-", &saveptr);
-    };
-}
-
 static void update_offload_codec_capabilities()
 {
-    char value[PROPERTY_VALUE_MAX] = {'\0'};
 
-    property_get("persist.vendor.bt.a2dp_offload_cap", value, "false");
-    ALOGD("get_offload_codec_capabilities = %s",value);
     a2dp.is_a2dp_offload_supported =
-            property_get_bool("persist.vendor.bt.a2dp_offload_cap", false);
-    if (strcmp(value, "false") != 0)
-        a2dp_offload_codec_cap_parser(value);
-    ALOGD("%s: codec cap = %s",__func__,value);
+            property_get_bool(SYSPROP_A2DP_OFFLOAD_SUPPORTED, false) &&
+            !property_get_bool(SYSPROP_A2DP_OFFLOAD_DISABLED, false);
+
+    ALOGD("%s: A2DP offload supported = %d",__func__,
+          a2dp.is_a2dp_offload_supported);
 }
 
 static int stop_abr()
@@ -811,7 +785,7 @@
     }
 
     // Open hostless front end and prepare ABR Tx path
-    abr_device_id = platform_get_pcm_device_id(USECASE_AUDIO_A2DP_ABR_FEEDBACK,
+    abr_device_id = fp_platform_get_pcm_device_id(USECASE_AUDIO_A2DP_ABR_FEEDBACK,
                                                PCM_CAPTURE);
     if (!a2dp.abr_config.abr_tx_handle) {
         a2dp.abr_config.abr_tx_handle = pcm_open(a2dp.adev->snd_card,
@@ -852,17 +826,17 @@
             a2dp.audio_source_open = (audio_source_open_t)
                           dlsym(a2dp.bt_lib_source_handle, "audio_stream_open");
             a2dp.audio_source_start = (audio_source_start_t)
-                          dlsym(a2dp.bt_lib_source_handle, "audio_start_stream");
+                          dlsym(a2dp.bt_lib_source_handle, "audio_stream_start");
             a2dp.audio_get_enc_config = (audio_get_enc_config_t)
                           dlsym(a2dp.bt_lib_source_handle, "audio_get_codec_config");
             a2dp.audio_source_suspend = (audio_source_suspend_t)
-                          dlsym(a2dp.bt_lib_source_handle, "audio_suspend_stream");
+                          dlsym(a2dp.bt_lib_source_handle, "audio_stream_suspend");
             a2dp.audio_source_handoff_triggered = (audio_source_handoff_triggered_t)
                           dlsym(a2dp.bt_lib_source_handle, "audio_handoff_triggered");
             a2dp.clear_source_a2dpsuspend_flag = (clear_source_a2dpsuspend_flag_t)
                           dlsym(a2dp.bt_lib_source_handle, "clear_a2dpsuspend_flag");
             a2dp.audio_source_stop = (audio_source_stop_t)
-                          dlsym(a2dp.bt_lib_source_handle, "audio_stop_stream");
+                          dlsym(a2dp.bt_lib_source_handle, "audio_stream_stop");
             a2dp.audio_source_close = (audio_source_close_t)
                           dlsym(a2dp.bt_lib_source_handle, "audio_stream_close");
             a2dp.audio_source_check_a2dp_ready = (audio_source_check_a2dp_ready_t)
@@ -1026,6 +1000,11 @@
         sampling_rate = sampling_rate *2;
     }
 
+    // No need to configure backend for PCM format.
+    if (a2dp.bt_encoder_format == CODEC_TYPE_PCM) {
+        return 0;
+    }
+
     //Configure backend sampling rate
     switch (sampling_rate) {
     case 44100:
@@ -2168,6 +2147,11 @@
                  configure_a2dp_source_decoder_format(MEDIA_FMT_APTX_AD));
             break;
 #endif
+        case CODEC_TYPE_PCM:
+            ALOGD("Received PCM format for BT device");
+            a2dp.bt_encoder_format = CODEC_TYPE_PCM;
+            is_configured = true;
+            break;
         default:
             ALOGD(" Received Unsupported encoder formar");
             is_configured = false;
@@ -2176,11 +2160,11 @@
     return is_configured;
 }
 
-int audio_extn_a2dp_start_playback()
+int a2dp_start_playback()
 {
     int ret = 0;
 
-    ALOGD("audio_extn_a2dp_start_playback start");
+    ALOGD("a2dp_start_playback start");
 
     if(!(a2dp.bt_lib_source_handle && a2dp.audio_source_start
        && a2dp.audio_get_enc_config)) {
@@ -2228,7 +2212,7 @@
     return ret;
 }
 
-uint64_t audio_extn_a2dp_get_decoder_latency()
+uint64_t a2dp_get_decoder_latency()
 {
     uint32_t latency = 0;
 
@@ -2251,7 +2235,7 @@
     uint64_t system_latency = 0;
     bool is_complete = false;
 
-    system_latency = audio_extn_a2dp_get_decoder_latency();
+    system_latency = a2dp_get_decoder_latency();
 
     if (a2dp.audio_sink_session_setup_complete(system_latency) == 0) {
         is_complete = true;
@@ -2259,11 +2243,22 @@
     return is_complete;
 }
 
-int audio_extn_a2dp_start_capture()
+bool a2dp_sink_is_ready()
+{
+    bool ret = false;
+
+    if ((a2dp.bt_state_sink != A2DP_STATE_DISCONNECTED) &&
+        (a2dp.is_a2dp_offload_supported) &&
+        (a2dp.audio_sink_check_a2dp_ready))
+           ret = a2dp.audio_sink_check_a2dp_ready();
+    return ret;
+}
+
+int a2dp_start_capture()
 {
     int ret = 0;
 
-    ALOGD("audio_extn_a2dp_start_capture start");
+    ALOGD("a2dp_start_capture start");
 
     if(!(a2dp.bt_lib_sink_handle && a2dp.audio_sink_start
        && a2dp.audio_get_dec_config)) {
@@ -2281,7 +2276,7 @@
            a2dp.a2dp_sink_started = false;
         } else {
 
-           if(!audio_extn_a2dp_sink_is_ready()) {
+           if(!a2dp_sink_is_ready()) {
                 ALOGD("Wait for capture ready not successful");
                 ret = -ETIMEDOUT;
            }
@@ -2318,7 +2313,7 @@
 {
     int ret =0;
 
-    struct mixer_ctl *ctl_enc_config, *ctrl_bit_format, *ctl_channel_mode;
+    struct mixer_ctl *ctl_enc_config, *ctl_channel_mode;
     struct sbc_enc_cfg_t dummy_reset_config;
     char* channel_mode;
 
@@ -2332,16 +2327,9 @@
                                         sizeof(struct sbc_enc_cfg_t));
          a2dp.bt_encoder_format = MEDIA_FMT_NONE;
     }
-    ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
-                                            MIXER_ENC_BIT_FORMAT);
-    if (!ctrl_bit_format) {
-        ALOGE(" ERROR  bit format CONFIG data mixer control not identified");
-    } else {
-        ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
-        if (ret != 0) {
-            ALOGE("%s: Failed to set bit format to encoder", __func__);
-        }
-    }
+
+    a2dp_set_bit_format(DEFAULT_ENCODER_BIT_FORMAT);
+
     ctl_channel_mode = mixer_get_ctl_by_name(a2dp.adev->mixer,MIXER_FMT_TWS_CHANNEL_MODE);
 
     if (!ctl_channel_mode) {
@@ -2408,11 +2396,11 @@
     }
 }
 
-int audio_extn_a2dp_stop_playback()
+int a2dp_stop_playback()
 {
     int ret =0;
 
-    ALOGV("audio_extn_a2dp_stop_playback start");
+    ALOGV("a2dp_stop_playback start");
     if(!(a2dp.bt_lib_source_handle && a2dp.audio_source_stop)) {
         ALOGE("a2dp handle is not identified, Ignoring stop request");
         return -ENOSYS;
@@ -2420,6 +2408,8 @@
 
     if (a2dp.a2dp_source_total_active_session_requests > 0)
         a2dp.a2dp_source_total_active_session_requests--;
+    else
+        ALOGE("%s: No active playback session requests on A2DP", __func__);
 
     if ( a2dp.a2dp_source_started && !a2dp.a2dp_source_total_active_session_requests) {
         ALOGV("calling BT module stream stop");
@@ -2444,11 +2434,11 @@
     return 0;
 }
 
-int audio_extn_a2dp_stop_capture()
+int a2dp_stop_capture()
 {
     int ret =0;
 
-    ALOGV("audio_extn_a2dp_stop_capture start");
+    ALOGV("a2dp_stop_capture start");
     if(!(a2dp.bt_lib_sink_handle && a2dp.audio_sink_stop)) {
         ALOGE("a2dp handle is not identified, Ignoring stop request");
         return -ENOSYS;
@@ -2474,16 +2464,17 @@
     return 0;
 }
 
-void audio_extn_a2dp_set_parameters(struct str_parms *parms)
+int a2dp_set_parameters(struct str_parms *parms, bool *reconfig)
 {
-     int ret, val;
+     int ret = 0, val, status = 0;
      char value[32]={0};
      struct audio_usecase *uc_info;
      struct listnode *node;
 
      if(a2dp.is_a2dp_offload_supported == false) {
-        ALOGV("no supported codecs identified,ignoring a2dp setparam");
-        return;
+        ALOGV("no supported encoders identified,ignoring a2dp setparam");
+        status = -EINVAL;
+        goto param_handled;
      }
 
      ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value,
@@ -2532,6 +2523,10 @@
      if (ret >= 0) {
          if (a2dp.bt_lib_source_handle) {
              if ((!strncmp(value,"true",sizeof(value)))) {
+                if (a2dp.a2dp_source_suspended) {
+                    ALOGD("%s: A2DP is already suspended", __func__);
+                    goto param_handled;
+                }
                 ALOGD("Setting a2dp to suspend state");
                 a2dp.a2dp_source_suspended = true;
                 if (a2dp.bt_state_source == A2DP_STATE_DISCONNECTED)
@@ -2541,7 +2536,7 @@
                     if (uc_info->type == PCM_PLAYBACK &&
                          (uc_info->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
                         pthread_mutex_unlock(&a2dp.adev->lock);
-                        check_a2dp_restore(a2dp.adev, uc_info->stream.out, false);
+                        fp_check_a2dp_restore(a2dp.adev, uc_info->stream.out, false);
                         pthread_mutex_lock(&a2dp.adev->lock);
                     }
                 }
@@ -2582,7 +2577,7 @@
                     if (uc_info->type == PCM_PLAYBACK &&
                          (uc_info->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
                         pthread_mutex_unlock(&a2dp.adev->lock);
-                        check_a2dp_restore(a2dp.adev, uc_info->stream.out, true);
+                        fp_check_a2dp_restore(a2dp.adev, uc_info->stream.out, true);
                         pthread_mutex_lock(&a2dp.adev->lock);
                     }
                 }
@@ -2590,16 +2585,28 @@
         }
         goto param_handled;
      }
+
+     ret = str_parms_get_str(parms, AUDIO_PARAMETER_RECONFIG_A2DP, value,
+                         sizeof(value));
+     if (ret >= 0) {
+         if (a2dp.is_a2dp_offload_supported &&
+                a2dp.bt_state_source != A2DP_STATE_DISCONNECTED) {
+             *reconfig = true;
+         }
+         goto param_handled;
+     }
+
 param_handled:
      ALOGV("end of a2dp setparam");
+     return status;
 }
 
-void audio_extn_a2dp_set_handoff_mode(bool is_on)
+void a2dp_set_handoff_mode(bool is_on)
 {
     a2dp.is_handoff_in_progress = is_on;
 }
 
-bool audio_extn_a2dp_is_force_device_switch()
+bool a2dp_is_force_device_switch()
 {
     //During encoder reconfiguration mode, force a2dp device switch
     // Or if a2dp device is selected but earlier start failed ( as a2dp
@@ -2607,17 +2614,17 @@
     return a2dp.is_handoff_in_progress || !a2dp.a2dp_source_started;
 }
 
-void audio_extn_a2dp_get_enc_sample_rate(int *sample_rate)
+void a2dp_get_enc_sample_rate(int *sample_rate)
 {
     *sample_rate = a2dp.enc_sampling_rate;
 }
 
-void audio_extn_a2dp_get_dec_sample_rate(int *sample_rate)
+void a2dp_get_dec_sample_rate(int *sample_rate)
 {
     *sample_rate = a2dp.dec_sampling_rate;
 }
 
-bool audio_extn_a2dp_source_is_ready()
+bool a2dp_source_is_ready()
 {
     bool ret = false;
 
@@ -2631,23 +2638,13 @@
     return ret;
 }
 
-bool audio_extn_a2dp_sink_is_ready()
-{
-    bool ret = false;
-
-    if ((a2dp.bt_state_sink != A2DP_STATE_DISCONNECTED) &&
-        (a2dp.is_a2dp_offload_supported) &&
-        (a2dp.audio_sink_check_a2dp_ready))
-           ret = a2dp.audio_sink_check_a2dp_ready();
-    return ret;
-}
-
-bool audio_extn_a2dp_source_is_suspended()
+bool a2dp_source_is_suspended()
 {
     return a2dp.a2dp_source_suspended;
 }
 
-void audio_extn_a2dp_init (void *adev)
+void a2dp_init(void *adev,
+               a2dp_offload_init_config_t *init_config)
 {
   a2dp.adev = (struct audio_device*)adev;
   a2dp.bt_lib_source_handle = NULL;
@@ -2665,6 +2662,12 @@
   a2dp.abr_config.imc_instance = 0;
   a2dp.abr_config.abr_tx_handle = NULL;
   a2dp.is_tws_mono_mode_on = false;
+
+  // init function pointers
+  fp_platform_get_pcm_device_id =
+              init_config->fp_platform_get_pcm_device_id;
+  fp_check_a2dp_restore = init_config->fp_check_a2dp_restore;
+
   reset_a2dp_enc_config_params();
   reset_a2dp_source_dec_config_params();
   reset_a2dp_sink_dec_config_params();
@@ -2679,7 +2682,7 @@
   update_offload_codec_capabilities();
 }
 
-uint32_t audio_extn_a2dp_get_encoder_latency()
+uint32_t a2dp_get_encoder_latency()
 {
     uint32_t latency = 0;
     int avsync_runtime_prop = 0;
@@ -2688,7 +2691,7 @@
     char value[PROPERTY_VALUE_MAX];
 
     memset(value, '\0', sizeof(char)*PROPERTY_VALUE_MAX);
-    avsync_runtime_prop = property_get("vendor.audio.a2dp.codec.latency", value, NULL);
+    avsync_runtime_prop = property_get(SYSPROP_A2DP_CODEC_LATENCIES, value, NULL);
     if (avsync_runtime_prop > 0) {
         if (sscanf(value, "%d/%d/%d/%d/%d%d",
                   &sbc_offset, &aptx_offset, &aptxhd_offset, &aac_offset, &celt_offset, &ldac_offset) != 6) {
@@ -2730,10 +2733,30 @@
         case CODEC_TYPE_APTX_AD: // for aptx adaptive the latency depends on the mode (HQ/LL) and
             latency = slatency;      // BT IPC will take care of accomodating the mode factor and return latency
             break;
+        case CODEC_TYPE_PCM:
+            latency = ENCODER_LATENCY_PCM;
+            latency += DEFAULT_SINK_LATENCY_PCM;
+            break;
         default:
             latency = 200;
             break;
     }
     return latency;
 }
-#endif // SPLIT_A2DP_ENABLED
+
+int a2dp_get_parameters(struct str_parms *query,
+                                   struct str_parms *reply)
+{
+    int ret, val = 0;
+    char value[32]={0};
+
+    ret = str_parms_get_str(query, AUDIO_PARAMETER_A2DP_RECONFIG_SUPPORTED,
+                            value, sizeof(value));
+    if (ret >= 0) {
+        val = a2dp.is_a2dp_offload_supported;
+        str_parms_add_int(reply, AUDIO_PARAMETER_A2DP_RECONFIG_SUPPORTED, val);
+        ALOGV("%s: called ... isReconfigA2dpSupported %d", __func__, val);
+    }
+
+    return 0;
+}
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 2d2853d..e0b07c6 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.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
@@ -44,16 +44,16 @@
 #include <dlfcn.h>
 #include <fcntl.h>
 #include <cutils/properties.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <unistd.h>
-
 #include "audio_hw.h"
 #include "audio_extn.h"
+#include "voice_extn.h"
 #include "audio_defs.h"
 #include "platform.h"
 #include "platform_api.h"
 #include "edid.h"
-
+#include "audio_feature_manager.h"
 #include "sound/compress_params.h"
 
 #ifdef DYNAMIC_LOG_ENABLED
@@ -67,6 +67,77 @@
 #define MAX_NUM_CHANNELS 8
 #define Q14_GAIN_UNITY 0x4000
 
+static bool is_running_on_stock_version = true;
+static bool is_compress_meta_data_enabled = false;
+
+struct snd_card_split cur_snd_card_split = {
+    .device = {0},
+    .snd_card = {0},
+    .form_factor = {0},
+};
+
+struct snd_card_split *audio_extn_get_snd_card_split()
+{
+    return &cur_snd_card_split;
+}
+
+void fm_set_parameters(struct audio_device *adev,
+                                  struct str_parms *parms);
+void fm_get_parameters(struct str_parms *query, struct str_parms *reply);
+
+void keep_alive_init(struct audio_device *adev);
+void keep_alive_deinit();
+void keep_alive_start(ka_mode_t ka_mode);
+void keep_alive_stop(ka_mode_t ka_mode);
+int keep_alive_set_parameters(struct audio_device *adev,
+                                         struct str_parms *parms);
+
+void audio_extn_set_snd_card_split(const char* in_snd_card_name)
+{
+    /* sound card name follows below mentioned convention
+       <target name>-<sound card name>-<form factor>-snd-card
+       parse target name, sound card name and form factor
+    */
+    char *snd_card_name = strdup(in_snd_card_name);
+    char *tmp = NULL;
+    char *device = NULL;
+    char *snd_card = NULL;
+    char *form_factor = NULL;
+
+    if (in_snd_card_name == NULL) {
+        ALOGE("%s: snd_card_name passed is NULL", __func__);
+        goto on_error;
+    }
+
+    device = strtok_r(snd_card_name, "-", &tmp);
+    if (device == NULL) {
+        ALOGE("%s: called on invalid snd card name", __func__);
+        goto on_error;
+    }
+    strlcpy(cur_snd_card_split.device, device, HW_INFO_ARRAY_MAX_SIZE);
+
+    snd_card = strtok_r(NULL, "-", &tmp);
+    if (snd_card == NULL) {
+        ALOGE("%s: called on invalid snd card name", __func__);
+        goto on_error;
+    }
+    strlcpy(cur_snd_card_split.snd_card, snd_card, HW_INFO_ARRAY_MAX_SIZE);
+
+    form_factor = strtok_r(NULL, "-", &tmp);
+    if (form_factor == NULL) {
+        ALOGE("%s: called on invalid snd card name", __func__);
+        goto on_error;
+    }
+    strlcpy(cur_snd_card_split.form_factor, form_factor, HW_INFO_ARRAY_MAX_SIZE);
+
+    ALOGI("%s: snd_card_name(%s) device(%s) snd_card(%s) form_factor(%s)",
+               __func__, in_snd_card_name, device, snd_card, form_factor);
+
+on_error:
+    if (snd_card_name)
+        free(snd_card_name);
+}
+
 struct audio_extn_module {
     bool anc_enabled;
     bool aanc_enabled;
@@ -82,6 +153,16 @@
 };
 
 static struct audio_extn_module aextnmod;
+static bool audio_extn_fm_power_opt_enabled = false;
+static bool audio_extn_keep_alive_enabled = false;
+static bool audio_extn_hifi_audio_enabled = false;
+static bool audio_extn_ras_feature_enabled = false;
+static bool audio_extn_kpi_optimize_feature_enabled = false;
+static bool audio_extn_display_port_feature_enabled = false;
+static bool audio_extn_fluence_feature_enabled = false;
+static bool audio_extn_custom_stereo_feature_enabled = false;
+static bool audio_extn_anc_headset_feature_enabled = false;
+static bool audio_extn_vbat_enabled = false;
 
 #define AUDIO_PARAMETER_KEY_AANC_NOISE_LEVEL "aanc_noise_level"
 #define AUDIO_PARAMETER_KEY_ANC        "anc_enabled"
@@ -104,6 +185,8 @@
 * this is done when device switch happens by setting audioparamter
 */
 
+#define IS_BIT_SET(NUM, bitno) (NUM & (1 << bitno))
+
 #define EXT_DISPLAY_PLUG_STATUS_NOTIFY_ENABLE 0x30
 
 static ssize_t update_sysfs_node(const char *path, const char *data, size_t len)
@@ -255,124 +338,6 @@
     }
 }
 
-#ifndef SOURCE_TRACKING_ENABLED
-#define audio_extn_source_track_set_parameters(adev, parms) (0)
-#define audio_extn_source_track_get_parameters(adev, query, reply) (0)
-#else
-void audio_extn_source_track_set_parameters(struct audio_device *adev,
-                                            struct str_parms *parms);
-void audio_extn_source_track_get_parameters(const struct audio_device *adev,
-                                            struct str_parms *query,
-                                            struct str_parms *reply);
-#endif
-
-#ifndef CUSTOM_STEREO_ENABLED
-#define audio_extn_customstereo_set_parameters(adev, parms)         (0)
-#else
-void audio_extn_customstereo_set_parameters(struct audio_device *adev,
-                                           struct str_parms *parms)
-{
-    int ret = 0;
-    char value[32]={0};
-    bool custom_stereo_state = false;
-    const char *mixer_ctl_name = "Set Custom Stereo OnOff";
-    struct mixer_ctl *ctl;
-
-    ALOGV("%s", __func__);
-    ret = str_parms_get_str(parms, AUDIO_PARAMETER_CUSTOM_STEREO, value,
-                            sizeof(value));
-    if (ret >= 0) {
-        if (!strncmp("true", value, sizeof("true")) || atoi(value))
-            custom_stereo_state = true;
-
-        if (custom_stereo_state == aextnmod.custom_stereo_enabled)
-            return;
-
-        ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
-        if (!ctl) {
-            ALOGE("%s: Could not get ctl for mixer cmd - %s",
-                  __func__, mixer_ctl_name);
-            return;
-        }
-        if (mixer_ctl_set_value(ctl, 0, custom_stereo_state) < 0) {
-            ALOGE("%s: Could not set custom stereo state %d",
-                  __func__, custom_stereo_state);
-            return;
-        }
-        aextnmod.custom_stereo_enabled = custom_stereo_state;
-        ALOGV("%s: Setting custom stereo state success", __func__);
-    }
-}
-
-void audio_extn_send_dual_mono_mixing_coefficients(struct stream_out *out)
-{
-    struct audio_device *adev = out->dev;
-    struct mixer_ctl *ctl;
-    char mixer_ctl_name[128];
-    int cust_ch_mixer_cfg[128], len = 0;
-    int ip_channel_cnt = audio_channel_count_from_out_mask(out->channel_mask);
-    int pcm_device_id = platform_get_pcm_device_id(out->usecase, PCM_PLAYBACK);
-    int op_channel_cnt= 2;
-    int i, j, err;
-
-    ALOGV("%s", __func__);
-    if (!out->started) {
-        out->set_dual_mono = true;
-        goto exit;
-    }
-
-    ALOGD("%s: i/p channel count %d, o/p channel count %d, pcm id %d", __func__,
-           ip_channel_cnt, op_channel_cnt, pcm_device_id);
-
-    snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
-             "Audio Stream %d Channel Mix Cfg", pcm_device_id);
-    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
-    if (!ctl) {
-        ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
-        __func__, mixer_ctl_name);
-        goto exit;
-    }
-
-    /* Output channel count corresponds to backend configuration channels.
-     * Input channel count corresponds to ASM session channels.
-     * Set params is called with channels that need to be selected from
-     * input to generate output.
-     * ex: "8,2" to downmix from 8 to 2 i.e. to downmix from 8 to 2,
-     *
-     * This mixer control takes values in the following sequence:
-     * - input channel count(m)
-     * - output channel count(n)
-     * - weight coeff for [out ch#1, in ch#1]
-     * ....
-     * - weight coeff for [out ch#1, in ch#m]
-     *
-     * - weight coeff for [out ch#2, in ch#1]
-     * ....
-     * - weight coeff for [out ch#2, in ch#m]
-     *
-     * - weight coeff for [out ch#n, in ch#1]
-     * ....
-     * - weight coeff for [out ch#n, in ch#m]
-     *
-     * To get dualmono ouptu weightage coeff is calculated as Unity gain
-     * divided by number of input channels.
-     */
-    cust_ch_mixer_cfg[len++] = ip_channel_cnt;
-    cust_ch_mixer_cfg[len++] = op_channel_cnt;
-    for (i = 0; i < op_channel_cnt; i++) {
-         for (j = 0; j < ip_channel_cnt; j++) {
-              cust_ch_mixer_cfg[len++] = Q14_GAIN_UNITY/ip_channel_cnt;
-         }
-    }
-
-    err = mixer_ctl_set_array(ctl, cust_ch_mixer_cfg, len);
-    if (err)
-        ALOGE("%s: ERROR. Mixer ctl set failed", __func__);
-exit:
-    return;
-}
-#endif /* CUSTOM_STEREO_ENABLED */
-
 #ifndef DTS_EAGLE
 #define audio_extn_hpx_set_parameters(adev, parms)         (0)
 #define audio_extn_hpx_get_parameters(query, reply)  (0)
@@ -444,37 +409,28 @@
 }
 #endif
 
-#ifdef HIFI_AUDIO_ENABLED
-bool audio_extn_is_hifi_audio_enabled(void)
+// START: VBAT =============================================================
+void vbat_feature_init(bool is_feature_enabled)
 {
-    ALOGV("%s: status: %d", __func__, aextnmod.hifi_audio_enabled);
-    return (aextnmod.hifi_audio_enabled ? true: false);
+    audio_extn_vbat_enabled = is_feature_enabled;
+    ALOGD(":: %s: ---- Feature VBAT is %s ----",
+                  __func__, is_feature_enabled ? "ENABLED": " NOT ENABLED");
 }
 
-bool audio_extn_is_hifi_audio_supported(void)
-{
-    /*
-     * for internal codec, check for hifiaudio property to enable hifi audio
-     */
-    if (property_get_bool("persist.vendor.audio.hifi.int_codec", false))
-    {
-        ALOGD("%s: hifi audio supported on internal codec", __func__);
-        aextnmod.hifi_audio_enabled = 1;
-    }
-
-    return (aextnmod.hifi_audio_enabled ? true: false);
-}
-#endif
-
-#ifdef VBAT_MONITOR_ENABLED
 bool audio_extn_is_vbat_enabled(void)
 {
+    if (!audio_extn_vbat_enabled)
+        return false;
+
     ALOGD("%s: status: %d", __func__, aextnmod.vbat_enabled);
     return (aextnmod.vbat_enabled ? true: false);
 }
 
 bool audio_extn_can_use_vbat(void)
 {
+    if (!audio_extn_vbat_enabled)
+        return false;
+
     char prop_vbat_enabled[PROPERTY_VALUE_MAX] = "false";
 
     property_get("persist.vendor.audio.vbat.enabled", prop_vbat_enabled, "0");
@@ -488,12 +444,18 @@
 
 bool audio_extn_is_bcl_enabled(void)
 {
+    if (!audio_extn_vbat_enabled)
+        return false;
+
     ALOGD("%s: status: %d", __func__, aextnmod.bcl_enabled);
     return (aextnmod.bcl_enabled ? true: false);
 }
 
 bool audio_extn_can_use_bcl(void)
 {
+    if (!audio_extn_vbat_enabled)
+        return false;
+
     char prop_bcl_enabled[PROPERTY_VALUE_MAX] = "false";
 
     property_get("persist.vendor.audio.bcl.enabled", prop_bcl_enabled, "0");
@@ -504,28 +466,16 @@
     ALOGD("%s: bcl.enabled property is set to %s", __func__, prop_bcl_enabled);
     return (aextnmod.bcl_enabled ? true: false);
 }
-#endif
 
-#ifdef RAS_ENABLED
-bool audio_extn_is_ras_enabled(void)
+// START: ANC_HEADSET -------------------------------------------------------
+void anc_headset_feature_init(bool is_feature_enabled)
 {
-    ALOGD("%s: status: %d", __func__, aextnmod.ras_enabled);
-    return (aextnmod.ras_enabled ? true: false);
+    audio_extn_anc_headset_feature_enabled = is_feature_enabled;
+    ALOGD(":: %s: ---- Feature FM_POWER_OPT is %s----", __func__,
+                                    is_feature_enabled? "ENABLED": "NOT ENABLED");
+
 }
 
-bool audio_extn_can_use_ras(void)
-{
-    if (property_get_bool("persist.vendor.audio.ras.enabled", false))
-        aextnmod.ras_enabled = 1;
-
-    ALOGD("%s: ras.enabled property is set to %d", __func__, aextnmod.ras_enabled);
-    return (aextnmod.ras_enabled ? true: false);
-}
-#endif
-
-#ifndef ANC_HEADSET_ENABLED
-#define audio_extn_set_anc_parameters(adev, parms)       (0)
-#else
 bool audio_extn_get_anc_enabled(void)
 {
     ALOGD("%s: anc_enabled:%d", __func__, aextnmod.anc_enabled);
@@ -534,26 +484,31 @@
 
 bool audio_extn_should_use_handset_anc(int in_channels)
 {
-    char prop_aanc[PROPERTY_VALUE_MAX] = "false";
+    if (audio_extn_anc_headset_feature_enabled) {
+        char prop_aanc[PROPERTY_VALUE_MAX] = "false";
 
-    property_get("persist.vendor.audio.aanc.enable", prop_aanc, "0");
-    if (!strncmp("true", prop_aanc, 4)) {
-        ALOGD("%s: AANC enabled in the property", __func__);
-        aextnmod.aanc_enabled = 1;
+        property_get("persist.vendor.audio.aanc.enable", prop_aanc, "0");
+        if (!strncmp("true", prop_aanc, 4)) {
+            ALOGD("%s: AANC enabled in the property", __func__);
+            aextnmod.aanc_enabled = 1;
+        }
+
+        return (aextnmod.aanc_enabled && aextnmod.anc_enabled
+                && (in_channels == 1));
     }
-
-    return (aextnmod.aanc_enabled && aextnmod.anc_enabled
-            && (in_channels == 1));
+    return false;
 }
 
 bool audio_extn_should_use_fb_anc(void)
 {
   char prop_anc[PROPERTY_VALUE_MAX] = "feedforward";
 
-  property_get("persist.vendor.audio.headset.anc.type", prop_anc, "0");
-  if (!strncmp("feedback", prop_anc, sizeof("feedback"))) {
-    ALOGD("%s: FB ANC headset type enabled\n", __func__);
-    return true;
+  if (audio_extn_anc_headset_feature_enabled) {
+      property_get("persist.vendor.audio.headset.anc.type", prop_anc, "0");
+      if (!strncmp("feedback", prop_anc, sizeof("feedback"))) {
+        ALOGD("%s: FB ANC headset type enabled\n", __func__);
+        return true;
+      }
   }
   return false;
 }
@@ -566,15 +521,17 @@
     struct mixer_ctl *ctl = NULL;
     const char *mixer_ctl_name = "AANC Noise Level";
 
-    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_AANC_NOISE_LEVEL, value,
+    if(audio_extn_anc_headset_feature_enabled) {
+        ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_AANC_NOISE_LEVEL, value,
                             sizeof(value));
-    if (ret >= 0) {
-        ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
-        if (ctl)
-            mixer_ctl_set_value(ctl, 0, atoi(value));
-        else
-            ALOGW("%s: Not able to get mixer ctl: %s",
-                  __func__, mixer_ctl_name);
+        if (ret >= 0) {
+            ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+            if (ctl)
+                mixer_ctl_set_value(ctl, 0, atoi(value));
+            else
+                ALOGW("%s: Not able to get mixer ctl: %s",
+                      __func__, mixer_ctl_name);
+        }
     }
 }
 
@@ -589,6 +546,9 @@
     struct str_parms *reply_44_1;
     struct str_parms *parms_disable_44_1;
 
+    if(!audio_extn_anc_headset_feature_enabled)
+        return;
+
     ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_ANC, value,
                             sizeof(value));
     if (ret >= 0) {
@@ -658,66 +618,8 @@
 
     ALOGD("%s: anc_enabled:%d", __func__, aextnmod.anc_enabled);
 }
-#endif /* ANC_HEADSET_ENABLED */
+// END: ANC_HEADSET -------------------------------------------------------
 
-#ifndef FLUENCE_ENABLED
-#define audio_extn_set_fluence_parameters(adev, parms) (0)
-#define audio_extn_get_fluence_parameters(adev, query, reply) (0)
-#else
-void audio_extn_set_fluence_parameters(struct audio_device *adev,
-                                            struct str_parms *parms)
-{
-    int ret = 0, err;
-    char value[32];
-    struct listnode *node;
-    struct audio_usecase *usecase;
-
-    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_FLUENCE,
-                                 value, sizeof(value));
-    ALOGV_IF(err >= 0, "%s: Set Fluence Type to %s", __func__, value);
-    if (err >= 0) {
-        ret = platform_set_fluence_type(adev->platform, value);
-        if (ret != 0) {
-            ALOGE("platform_set_fluence_type returned error: %d", ret);
-        } else {
-            /*
-             *If the fluence is manually set/reset, devices
-             *need to get updated for all the usecases
-             *i.e. audio and voice.
-             */
-             list_for_each(node, &adev->usecase_list) {
-                 usecase = node_to_item(node, struct audio_usecase, list);
-                 select_devices(adev, usecase->id);
-             }
-        }
-    }
-}
-
-int audio_extn_get_fluence_parameters(const struct audio_device *adev,
-                       struct str_parms *query, struct str_parms *reply)
-{
-    int ret = 0, err;
-    char value[256] = {0};
-
-    err = str_parms_get_str(query, AUDIO_PARAMETER_KEY_FLUENCE, value,
-                                                          sizeof(value));
-    if (err >= 0) {
-        ret = platform_get_fluence_type(adev->platform, value, sizeof(value));
-        if (ret >= 0) {
-            ALOGV("%s: Fluence Type is %s", __func__, value);
-            str_parms_add_str(reply, AUDIO_PARAMETER_KEY_FLUENCE, value);
-        } else
-            goto done;
-    }
-done:
-    return ret;
-}
-#endif /* FLUENCE_ENABLED */
-
-#ifndef AFE_PROXY_ENABLED
-#define audio_extn_set_afe_proxy_parameters(adev, parms)  (0)
-#define audio_extn_get_afe_proxy_parameters(adev, query, reply) (0)
-#else
 static int32_t afe_proxy_set_channel_mapping(struct audio_device *adev,
                                                      int channel_count)
 {
@@ -777,6 +679,11 @@
     struct mixer_ctl *ctl = NULL;
     const char *mixer_ctl_name = "PROXY_RX Channels";
 
+    if (!audio_feature_manager_is_feature_enabled(AFE_PROXY)) {
+        ALOGW("%s: AFE_PROXY is disabled", __func__);
+        return -ENOSYS;
+    }
+
     ALOGD("%s: entry", __func__);
     /* use the existing channel count set by hardware params to
     configure the back end for stereo as usb/a2dp would be
@@ -853,6 +760,11 @@
     int ret = 0;
     int channels = aextnmod.proxy_channel_num;
 
+    if (!audio_feature_manager_is_feature_enabled(AFE_PROXY)) {
+        ALOGW("%s: AFE_PROXY is disabled", __func__);
+        return -ENOSYS;
+    }
+
     switch (channels) {
         /*
          * Do not handle stereo output in Multi-channel cases
@@ -877,11 +789,15 @@
 
 int32_t audio_extn_get_afe_proxy_channel_count()
 {
+
+    if (!audio_feature_manager_is_feature_enabled(AFE_PROXY)) {
+        ALOGW("%s: AFE_PROXY is disabled", __func__);
+        return -ENOSYS;
+    }
+
     return aextnmod.proxy_channel_num;
 }
 
-#endif /* AFE_PROXY_ENABLED */
-
 static int get_active_offload_usecases(const struct audio_device *adev,
                                        struct str_parms *query,
                                        struct str_parms *reply)
@@ -906,8 +822,1515 @@
     return ret;
 }
 
+void compress_meta_data_feature_init(bool is_featuer_enabled)
+{
+    is_compress_meta_data_enabled = is_featuer_enabled;
+}
+
+bool if_compress_meta_data_feature_enabled()
+{
+    return is_compress_meta_data_enabled;
+}
+
+//START: USB_OFFLOAD ==========================================================
+// LIB is part of hal lib, so no need for dlopen and getting function pointer
+// rather have function declared here
+
+void usb_init(void *adev);
+void usb_deinit();
+void usb_add_device(audio_devices_t device, int card);
+void usb_remove_device(audio_devices_t device, int card);
+bool usb_is_config_supported(unsigned int *bit_width,
+                                        unsigned int *sample_rate,
+                                        unsigned int *ch,
+                                        bool is_playback);
+int usb_enable_sidetone(int device, bool enable);
+void usb_set_sidetone_gain(struct str_parms *parms,
+                                     char *value, int len);
+bool usb_is_capture_supported();
+int usb_get_max_channels(bool playback);
+int usb_get_max_bit_width(bool playback);
+int usb_get_sup_sample_rates(bool type, uint32_t *sr, uint32_t l);
+bool usb_is_tunnel_supported();
+bool usb_alive(int card);
+bool usb_connected(struct str_parms *parms);
+unsigned long usb_find_service_interval(bool min, bool playback);
+int usb_altset_for_service_interval(bool is_playback,
+                                               unsigned long service_interval,
+                                               uint32_t *bit_width,
+                                               uint32_t *sample_rate,
+                                               uint32_t *channel_count);
+int usb_set_service_interval(bool playback,
+                                        unsigned long service_interval,
+                                        bool *reconfig);
+int usb_get_service_interval(bool playback,
+                                        unsigned long *service_interval);
+int usb_check_and_set_svc_int(struct audio_usecase *uc_info,
+                                         bool starting_output_stream);
+bool usb_is_reconfig_req();
+void usb_set_reconfig(bool is_required);
+
+static bool is_usb_offload_enabled = false;
+static bool is_usb_burst_mode_enabled = false;
+static bool is_usb_sidetone_vol_enabled = false;
+
+void usb_offload_feature_init(bool is_feature_enabled)
+{
+    ALOGD("%s: Called with feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
+    is_usb_offload_enabled = is_feature_enabled;
+}
+
+void usb_offload_burst_mode_feature_init(bool is_feature_enabled)
+{
+    ALOGD("%s: Called with feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
+    is_usb_burst_mode_enabled = is_feature_enabled;
+}
+
+void usb_offload_sidetone_volume_feature_init(bool is_feature_enabled)
+{
+    ALOGD("%s: Called with feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
+    is_usb_sidetone_vol_enabled = is_feature_enabled;
+}
+
+bool audio_extn_usb_is_sidetone_volume_enabled()
+{
+    return is_usb_sidetone_vol_enabled;
+}
+
+void audio_extn_usb_init(void *adev)
+{
+    if (is_usb_offload_enabled)
+        usb_init(adev);
+}
+
+
+void audio_extn_usb_deinit()
+{
+    if (is_usb_offload_enabled)
+        usb_deinit();
+}
+
+void audio_extn_usb_add_device(audio_devices_t device, int card)
+{
+    if (is_usb_offload_enabled)
+        usb_add_device(device, card);
+}
+
+void audio_extn_usb_remove_device(audio_devices_t device, int card)
+{
+    if (is_usb_offload_enabled)
+        usb_remove_device(device, card);
+}
+
+bool audio_extn_usb_is_config_supported(unsigned int *bit_width,
+                                        unsigned int *sample_rate,
+                                        unsigned int *ch,
+                                        bool is_playback)
+{
+    bool ret_val = false;
+    if (is_usb_offload_enabled)
+        ret_val = usb_is_config_supported(bit_width, sample_rate, ch, is_playback);
+
+    return ret_val;
+}
+
+int audio_extn_usb_enable_sidetone(int device, bool enable)
+{
+    int ret_val = 0;
+    if (is_usb_offload_enabled)
+        ret_val = usb_enable_sidetone(device, enable);
+
+    return ret_val;
+}
+
+void audio_extn_usb_set_sidetone_gain(struct str_parms *parms,
+                                      char *value, int len)
+{
+    if (is_usb_offload_enabled)
+        usb_set_sidetone_gain(parms, value, len);
+}
+
+bool audio_extn_usb_is_capture_supported()
+{
+    bool ret_val = false;
+    if (is_usb_offload_enabled)
+        ret_val = usb_is_capture_supported();
+
+    return ret_val;
+}
+
+int audio_extn_usb_get_max_channels(bool playback)
+{
+    int ret_val = 0;
+    if (is_usb_offload_enabled)
+        ret_val = usb_get_max_channels(playback);
+
+    return ret_val;
+}
+
+int audio_extn_usb_get_max_bit_width(bool playback)
+{
+    int ret_val = 0;
+    if (is_usb_offload_enabled)
+        ret_val = usb_get_max_bit_width(playback);
+
+    return ret_val;
+}
+
+
+int audio_extn_usb_get_sup_sample_rates(bool type, uint32_t *sr, uint32_t l)
+{
+    int ret_val = 0;
+    if (is_usb_offload_enabled)
+        ret_val = usb_get_sup_sample_rates(type, sr, l);
+
+    return ret_val;
+}
+
+bool audio_extn_usb_is_tunnel_supported()
+{
+    bool ret_val = false;
+    if (is_usb_offload_enabled)
+        ret_val = usb_is_tunnel_supported();
+
+    return ret_val;
+}
+
+bool audio_extn_usb_alive(int card)
+{
+    bool ret_val = false;
+    if (is_usb_offload_enabled)
+        ret_val = usb_alive(card);
+
+    return ret_val;
+}
+
+bool audio_extn_usb_connected(struct str_parms *parms)
+{
+    bool ret_val = false;
+    if (is_usb_offload_enabled)
+        ret_val = usb_connected(parms);
+
+    return ret_val;
+}
+
+unsigned long audio_extn_usb_find_service_interval(bool min, bool playback)
+{
+    unsigned long ret_val = 0;
+    if (is_usb_offload_enabled && is_usb_burst_mode_enabled)
+        ret_val = usb_find_service_interval(min, playback);
+
+    return ret_val;
+}
+
+int audio_extn_usb_altset_for_service_interval(bool is_playback,
+                                               unsigned long service_interval,
+                                               uint32_t *bit_width,
+                                               uint32_t *sample_rate,
+                                               uint32_t *channel_count)
+{
+    int ret_val = 0;
+    if (is_usb_offload_enabled && is_usb_burst_mode_enabled)
+        ret_val = usb_altset_for_service_interval(is_playback, service_interval,
+                                         bit_width, sample_rate, channel_count);
+
+    return ret_val;
+}
+
+int audio_extn_usb_set_service_interval(bool playback,
+                                        unsigned long service_interval,
+                                        bool *reconfig)
+{
+    int ret_val = 0;
+    if (is_usb_offload_enabled && is_usb_burst_mode_enabled)
+        ret_val = usb_set_service_interval(playback, service_interval, reconfig);
+
+    return ret_val;
+}
+
+int audio_extn_usb_get_service_interval(bool playback,
+                                        unsigned long *service_interval)
+{
+    int ret_val = 0;
+    if (is_usb_offload_enabled && is_usb_burst_mode_enabled)
+        ret_val = usb_get_service_interval(playback, service_interval);
+
+    return ret_val;
+}
+
+int audio_extn_usb_check_and_set_svc_int(struct audio_usecase *uc_info,
+                                         bool starting_output_stream)
+{
+    int ret_val = 0;
+    if (is_usb_offload_enabled && is_usb_burst_mode_enabled)
+        ret_val = usb_check_and_set_svc_int(uc_info, starting_output_stream);
+
+    return ret_val;
+}
+
+bool audio_extn_usb_is_reconfig_req()
+{
+    bool ret_val = 0;
+    if (is_usb_offload_enabled && is_usb_burst_mode_enabled)
+        ret_val = usb_is_reconfig_req();
+
+    return ret_val;
+}
+
+void audio_extn_usb_set_reconfig(bool is_required)
+{
+    if (is_usb_offload_enabled && is_usb_burst_mode_enabled)
+        usb_set_reconfig(is_required);
+}
+
+//END: USB_OFFLOAD ===========================================================
+
+//START: SPEAKER_PROTECTION ==========================================================
+#ifdef __LP64__
+#define SPKR_PROT_LIB_PATH  "/vendor/lib64/libspkrprot.so"
+#define CIRRUS_SPKR_PROT_LIB_PATH  "/vendor/lib64/libcirrusspkrprot.so"
+#else
+#define SPKR_PROT_LIB_PATH  "/vendor/lib/libspkrprot.so"
+#define CIRRUS_SPKR_PROT_LIB_PATH  "/vendor/lib/libcirrusspkrprot.so"
+#endif
+
+static void *spkr_prot_lib_handle = NULL;
+
+typedef void (*spkr_prot_init_t)(void *, spkr_prot_init_config_t);
+static spkr_prot_init_t spkr_prot_init;
+
+typedef int (*spkr_prot_deinit_t)();
+static spkr_prot_deinit_t spkr_prot_deinit;
+
+typedef int (*spkr_prot_start_processing_t)(snd_device_t);
+static spkr_prot_start_processing_t spkr_prot_start_processing;
+
+typedef void (*spkr_prot_stop_processing_t)(snd_device_t);
+static spkr_prot_stop_processing_t spkr_prot_stop_processing;
+
+typedef bool (*spkr_prot_is_enabled_t)();
+static spkr_prot_is_enabled_t spkr_prot_is_enabled;
+
+typedef void (*spkr_prot_calib_cancel_t)(void *);
+static spkr_prot_calib_cancel_t spkr_prot_calib_cancel;
+
+typedef void (*spkr_prot_set_parameters_t)(struct str_parms *,
+                                           char *, int);
+static spkr_prot_set_parameters_t spkr_prot_set_parameters;
+
+typedef int (*fbsp_set_parameters_t)(struct str_parms *);
+static fbsp_set_parameters_t fbsp_set_parameters;
+
+typedef int (*fbsp_get_parameters_t)(struct str_parms *,
+                                   struct str_parms *);
+static fbsp_get_parameters_t fbsp_get_parameters;
+
+typedef int (*get_spkr_prot_snd_device_t)(snd_device_t);
+static get_spkr_prot_snd_device_t get_spkr_prot_snd_device;
+
+void spkr_prot_feature_init(bool is_feature_enabled)
+{
+    ALOGD("%s: Called with feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
+    if (is_feature_enabled) {
+        //dlopen lib
+        if (is_running_on_stock_version)
+            spkr_prot_lib_handle = dlopen(CIRRUS_SPKR_PROT_LIB_PATH, RTLD_NOW);
+        else
+            spkr_prot_lib_handle = dlopen(SPKR_PROT_LIB_PATH, RTLD_NOW);
+
+        if (spkr_prot_lib_handle == NULL) {
+            ALOGE("%s: dlopen failed", __func__);
+            goto feature_disabled;
+        }
+        //map each function
+        //if mandatoy functions are not found, disble feature
+
+        // Mandatory functions
+        if (((spkr_prot_init =
+             (spkr_prot_init_t)dlsym(spkr_prot_lib_handle, "spkr_prot_init")) == NULL) ||
+            ((spkr_prot_deinit =
+             (spkr_prot_deinit_t)dlsym(spkr_prot_lib_handle, "spkr_prot_deinit")) == NULL) ||
+            ((spkr_prot_start_processing =
+             (spkr_prot_start_processing_t)dlsym(spkr_prot_lib_handle, "spkr_prot_start_processing")) == NULL) ||
+            ((spkr_prot_stop_processing =
+             (spkr_prot_stop_processing_t)dlsym(spkr_prot_lib_handle, "spkr_prot_stop_processing")) == NULL) ||
+            ((spkr_prot_is_enabled =
+             (spkr_prot_is_enabled_t)dlsym(spkr_prot_lib_handle, "spkr_prot_is_enabled")) == NULL) ||
+            ((spkr_prot_calib_cancel =
+             (spkr_prot_calib_cancel_t)dlsym(spkr_prot_lib_handle, "spkr_prot_calib_cancel")) == NULL) ||
+            ((get_spkr_prot_snd_device =
+             (get_spkr_prot_snd_device_t)dlsym(spkr_prot_lib_handle, "get_spkr_prot_snd_device")) == NULL)) {
+            ALOGE("%s: dlsym failed", __func__);
+            goto feature_disabled;
+        }
+
+        // options functions, can be NULL
+
+        spkr_prot_set_parameters = NULL;
+        fbsp_set_parameters = NULL;
+        fbsp_get_parameters = NULL;
+        if ((spkr_prot_set_parameters =
+             (spkr_prot_set_parameters_t)dlsym(spkr_prot_lib_handle, "spkr_prot_set_parameters")) == NULL) {
+            ALOGW("%s: dlsym failed for spkr_prot_set_parameters", __func__);
+        }
+
+        if ((fbsp_set_parameters =
+             (fbsp_set_parameters_t)dlsym(spkr_prot_lib_handle, "fbsp_set_parameters")) == NULL) {
+            ALOGW("%s: dlsym failed for fbsp_set_parameters", __func__);
+        }
+
+        if ((fbsp_get_parameters =
+             (fbsp_get_parameters_t)dlsym(spkr_prot_lib_handle, "fbsp_get_parameters")) == NULL) {
+            ALOGW("%s: dlsym failed for fbsp_get_parameters", __func__);
+        }
+
+        ALOGD("%s:: ---- Feature SPKR_PROT is Enabled ----", __func__);
+        return;
+    }
+
+feature_disabled:
+    if (spkr_prot_lib_handle) {
+        dlclose(spkr_prot_lib_handle);
+        spkr_prot_lib_handle = NULL;
+    }
+
+    spkr_prot_init = NULL;
+    spkr_prot_deinit = NULL;
+    spkr_prot_start_processing = NULL;
+    spkr_prot_stop_processing = NULL;
+    spkr_prot_is_enabled = NULL;
+    spkr_prot_calib_cancel = NULL;
+    spkr_prot_set_parameters = NULL;
+    fbsp_set_parameters = NULL;
+    fbsp_get_parameters = NULL;
+    get_spkr_prot_snd_device = NULL;
+
+    ALOGW(":: %s: ---- Feature SPKR_PROT is disabled ----", __func__);
+    return;
+}
+
+void audio_extn_spkr_prot_init(void *adev) {
+    if (spkr_prot_init != NULL) {
+        // init function pointers
+        spkr_prot_init_config_t spkr_prot_config_val;
+        spkr_prot_config_val.fp_read_line_from_file = read_line_from_file;
+        spkr_prot_config_val.fp_get_usecase_from_list = get_usecase_from_list;
+        spkr_prot_config_val.fp_disable_snd_device  = disable_snd_device;
+        spkr_prot_config_val.fp_enable_snd_device = enable_snd_device;
+        spkr_prot_config_val.fp_disable_audio_route = disable_audio_route;
+        spkr_prot_config_val.fp_enable_audio_route = enable_audio_route;
+        spkr_prot_config_val.fp_platform_set_snd_device_backend = platform_set_snd_device_backend;
+        spkr_prot_config_val.fp_platform_get_snd_device_name_extn = platform_get_snd_device_name_extn;
+        spkr_prot_config_val.fp_platform_get_default_app_type_v2 = platform_get_default_app_type_v2;
+        spkr_prot_config_val.fp_platform_send_audio_calibration = platform_send_audio_calibration;
+        spkr_prot_config_val.fp_platform_get_pcm_device_id = platform_get_pcm_device_id;
+        spkr_prot_config_val.fp_platform_get_snd_device_name = platform_get_snd_device_name;
+        spkr_prot_config_val.fp_platform_spkr_prot_is_wsa_analog_mode = platform_spkr_prot_is_wsa_analog_mode;
+        spkr_prot_config_val.fp_platform_get_vi_feedback_snd_device = platform_get_vi_feedback_snd_device;
+        spkr_prot_config_val.fp_platform_get_spkr_prot_snd_device = platform_get_spkr_prot_snd_device;
+        spkr_prot_config_val.fp_platform_check_and_set_codec_backend_cfg = platform_check_and_set_codec_backend_cfg;
+        spkr_prot_config_val.fp_audio_extn_get_snd_card_split = audio_extn_get_snd_card_split;
+        spkr_prot_config_val.fp_audio_extn_is_vbat_enabled = audio_extn_is_vbat_enabled;
+
+        spkr_prot_init(adev, spkr_prot_config_val);
+    }
+
+    return;
+}
+
+int audio_extn_spkr_prot_deinit() {
+    int ret_val = 0;
+
+    if (spkr_prot_deinit != NULL)
+        ret_val = spkr_prot_deinit();
+
+    return ret_val;
+}
+
+int audio_extn_spkr_prot_start_processing(snd_device_t snd_device) {
+    int ret_val = 0;
+
+    if (spkr_prot_start_processing != NULL)
+        ret_val = spkr_prot_start_processing(snd_device);
+
+    return ret_val;
+}
+
+void audio_extn_spkr_prot_stop_processing(snd_device_t snd_device)
+{
+    if (spkr_prot_stop_processing != NULL)
+        spkr_prot_stop_processing(snd_device);
+
+    return;
+}
+
+bool audio_extn_spkr_prot_is_enabled()
+{
+    bool ret_val = false;
+
+    if (spkr_prot_is_enabled != NULL)
+        ret_val = spkr_prot_is_enabled();
+
+    return ret_val;
+}
+
+void audio_extn_spkr_prot_calib_cancel(void *adev)
+{
+    if (spkr_prot_calib_cancel != NULL)
+        spkr_prot_calib_cancel(adev);
+
+    return;
+}
+
+void audio_extn_spkr_prot_set_parameters(struct str_parms *parms,
+                                         char *value, int len)
+{
+    if (spkr_prot_set_parameters != NULL)
+        spkr_prot_set_parameters(parms, value, len);
+
+    return;
+}
+
+int audio_extn_fbsp_set_parameters(struct str_parms *parms)
+{
+    int ret_val = 0;
+
+    if (fbsp_set_parameters != NULL)
+        ret_val = fbsp_set_parameters(parms);
+
+    return ret_val;
+}
+
+int audio_extn_fbsp_get_parameters(struct str_parms *query,
+                                   struct str_parms *reply)
+{
+    int ret_val = 0;
+
+    if (fbsp_get_parameters != NULL)
+        ret_val = fbsp_get_parameters(query, reply);
+
+    return ret_val;
+}
+
+int audio_extn_get_spkr_prot_snd_device(snd_device_t snd_device)
+{
+    int ret_val = snd_device;
+
+    if (get_spkr_prot_snd_device != NULL)
+        ret_val = get_spkr_prot_snd_device(snd_device);
+
+    return ret_val;
+}
+
+//END: SPEAKER_PROTECTION ==========================================================
+
+//START: EXTERNAL_QDSP ================================================================
+#ifdef __LP64__
+#define EXTERNAL_QDSP_LIB_PATH  "/vendor/lib64/libextqdsp.so"
+#else
+#define EXTERNAL_QDSP_LIB_PATH  "/vendor/lib/libextqdsp.so"
+#endif
+
+static void *external_qdsp_lib_handle = NULL;
+
+typedef void (*external_qdsp_init_t)(void *);
+static external_qdsp_init_t external_qdsp_init;
+
+typedef void (*external_qdsp_deinit_t)(void);
+static external_qdsp_deinit_t external_qdsp_deinit;
+
+typedef bool (*external_qdsp_set_state_t)(struct audio_device *,
+                                        int , float , bool);
+static external_qdsp_set_state_t external_qdsp_set_state;
+
+typedef void (*external_qdsp_set_device_t)(struct audio_usecase *);
+static external_qdsp_set_device_t external_qdsp_set_device;
+
+typedef void (*external_qdsp_set_parameter_t)(struct audio_device *,
+                                              struct str_parms *);
+static external_qdsp_set_parameter_t external_qdsp_set_parameter;
+
+typedef bool (*external_qdsp_supported_usb_t)(void);
+static external_qdsp_supported_usb_t external_qdsp_supported_usb;
+
+void external_qdsp_feature_init(bool is_feature_enabled)
+{
+    ALOGD("%s: Called with feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
+    if (is_feature_enabled) {
+        //dlopen lib
+        external_qdsp_lib_handle = dlopen(EXTERNAL_QDSP_LIB_PATH, RTLD_NOW);
+        if (external_qdsp_lib_handle == NULL) {
+            ALOGE("%s: dlopen failed", __func__);
+            goto feature_disabled;
+        }
+        //map each function
+        //on any faliure to map any function, disble feature
+        if (((external_qdsp_init =
+             (external_qdsp_init_t)dlsym(external_qdsp_lib_handle, "ma_init")) == NULL) ||
+            ((external_qdsp_deinit =
+             (external_qdsp_deinit_t)dlsym(external_qdsp_lib_handle, "ma_deinit")) == NULL) ||
+            ((external_qdsp_set_state =
+             (external_qdsp_set_state_t)dlsym(external_qdsp_lib_handle, "set_state")) == NULL) ||
+            ((external_qdsp_set_device =
+             (external_qdsp_set_device_t)dlsym(external_qdsp_lib_handle, "set_device")) == NULL) ||
+            ((external_qdsp_set_parameter =
+             (external_qdsp_set_parameter_t)dlsym(external_qdsp_lib_handle, "set_parameters")) == NULL) ||
+            ((external_qdsp_supported_usb =
+             (external_qdsp_supported_usb_t)dlsym(external_qdsp_lib_handle, "supported_usb")) == NULL)) {
+            ALOGE("%s: dlsym failed", __func__);
+            goto feature_disabled;
+        }
+
+        ALOGD("%s:: ---- Feature EXTERNAL_QDSP is Enabled ----", __func__);
+        return;
+    }
+
+feature_disabled:
+    if (external_qdsp_lib_handle) {
+        dlclose(external_qdsp_lib_handle);
+        external_qdsp_lib_handle = NULL;
+    }
+
+    external_qdsp_init = NULL;
+    external_qdsp_deinit = NULL;
+    external_qdsp_set_state = NULL;
+    external_qdsp_set_device = NULL;
+    external_qdsp_set_parameter = NULL;
+    external_qdsp_supported_usb = NULL;
+
+    ALOGW(":: %s: ---- Feature EXTERNAL_QDSP is disabled ----", __func__);
+    return;
+}
+
+void audio_extn_qdsp_init(void *platform) {
+    if (external_qdsp_init != NULL)
+        external_qdsp_init(platform);
+
+    return;
+}
+
+void audio_extn_qdsp_deinit() {
+    if (external_qdsp_deinit != NULL)
+        external_qdsp_deinit();
+
+    return;
+}
+
+bool audio_extn_qdsp_set_state(struct audio_device *adev, int stream_type,
+                             float vol, bool active) {
+    bool ret_val = false;
+
+    if (external_qdsp_set_state != NULL)
+        ret_val = external_qdsp_set_state(adev, stream_type, vol, active);
+
+    return ret_val;
+}
+
+void audio_extn_qdsp_set_device(struct audio_usecase *usecase) {
+    if (external_qdsp_set_device != NULL)
+        external_qdsp_set_device(usecase);
+
+    return;
+}
+
+void audio_extn_qdsp_set_parameters(struct audio_device *adev,
+                                  struct str_parms *parms) {
+    if (external_qdsp_set_parameter != NULL)
+        external_qdsp_set_parameter(adev, parms);
+
+    return;
+}
+
+bool audio_extn_qdsp_supported_usb() {
+    bool ret_val = false;
+
+    if (external_qdsp_supported_usb != NULL)
+        ret_val = external_qdsp_supported_usb();
+
+    return ret_val;
+}
+
+
+//END: EXTERNAL_QDSP ================================================================
+
+//START: EXTERNAL_SPEAKER ================================================================
+#ifdef __LP64__
+#define EXTERNAL_SPKR_LIB_PATH  "/vendor/lib64/libextspkr.so"
+#else
+#define EXTERNAL_SPKR_LIB_PATH  "/vendor/lib/libextspkr.so"
+#endif
+
+static void *external_speaker_lib_handle = NULL;
+
+typedef void* (*external_speaker_init_t)(struct audio_device *);
+static external_speaker_init_t external_speaker_init;
+
+typedef void (*external_speaker_deinit_t)(void *);
+static external_speaker_deinit_t external_speaker_deinit;
+
+typedef void (*external_speaker_update_t)(void *);
+static external_speaker_update_t external_speaker_update;
+
+typedef void (*external_speaker_set_mode_t)(void *, audio_mode_t);
+static external_speaker_set_mode_t external_speaker_set_mode;
+
+typedef void (*external_speaker_set_voice_vol_t)(void *, float);
+static external_speaker_set_voice_vol_t external_speaker_set_voice_vol;
+
+
+void external_speaker_feature_init(bool is_feature_enabled)
+{
+    ALOGD("%s: Called with feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
+    if (is_feature_enabled) {
+        //dlopen lib
+        external_speaker_lib_handle = dlopen(EXTERNAL_SPKR_LIB_PATH, RTLD_NOW);
+        if (external_speaker_lib_handle == NULL) {
+            ALOGE("%s: dlopen failed", __func__);
+            goto feature_disabled;
+        }
+        //map each function
+        //on any faliure to map any function, disble feature
+        if (((external_speaker_init =
+             (external_speaker_init_t)dlsym(external_speaker_lib_handle, "extspk_init")) == NULL) ||
+            ((external_speaker_deinit =
+             (external_speaker_deinit_t)dlsym(external_speaker_lib_handle, "extspk_deinit")) == NULL) ||
+            ((external_speaker_update =
+             (external_speaker_update_t)dlsym(external_speaker_lib_handle, "extspk_update")) == NULL) ||
+            ((external_speaker_set_mode =
+             (external_speaker_set_mode_t)dlsym(external_speaker_lib_handle, "extspk_set_mode")) == NULL) ||
+            ((external_speaker_set_voice_vol =
+             (external_speaker_set_voice_vol_t)dlsym(external_speaker_lib_handle, "extspk_set_voice_vol")) == NULL)) {
+            ALOGE("%s: dlsym failed", __func__);
+            goto feature_disabled;
+        }
+
+        ALOGD("%s:: ---- Feature EXTERNAL_SPKR is Enabled ----", __func__);
+        return;
+    }
+
+feature_disabled:
+    if (external_speaker_lib_handle) {
+        dlclose(external_speaker_lib_handle);
+        external_speaker_lib_handle = NULL;
+    }
+
+    external_speaker_init = NULL;
+    external_speaker_deinit = NULL;
+    external_speaker_update = NULL;
+    external_speaker_set_mode = NULL;
+    external_speaker_set_voice_vol = NULL;
+
+    ALOGW(":: %s: ---- Feature EXTERNAL_SPKR is disabled ----", __func__);
+    return;
+}
+
+void *audio_extn_extspk_init(struct audio_device *adev) {
+    void* ret_val = NULL;
+
+    if (external_speaker_init != NULL)
+        ret_val = external_speaker_init(adev);
+
+    return ret_val;
+}
+
+void audio_extn_extspk_deinit(void *extn) {
+    if (external_speaker_deinit != NULL)
+        external_speaker_deinit(extn);
+
+    return;
+}
+
+void audio_extn_extspk_update(void* extn) {
+    if (external_speaker_update != NULL)
+        external_speaker_update(extn);
+
+    return;
+}
+
+void audio_extn_extspk_set_mode(void* extn, audio_mode_t mode) {
+    if (external_speaker_set_mode != NULL)
+        external_speaker_set_mode(extn, mode);
+
+    return;
+}
+
+void audio_extn_extspk_set_voice_vol(void* extn, float vol) {
+    if (external_speaker_set_voice_vol != NULL)
+        external_speaker_set_voice_vol(extn, vol);
+
+    return;
+}
+
+//END: EXTERNAL_SPEAKER ================================================================
+
+
+//START: EXTERNAL_SPEAKER_TFA ================================================================
+#ifdef __LP64__
+#define EXTERNAL_SPKR_TFA_LIB_PATH  "/vendor/lib64/libextspkr_tfa.so"
+#else
+#define EXTERNAL_SPKR_TFA_LIB_PATH  "/vendor/lib/libextspkr_tfa.so"
+#endif
+
+static void *external_speaker_tfa_lib_handle = NULL;
+
+typedef int (*external_speaker_tfa_enable_t)(void);
+static external_speaker_tfa_enable_t external_speaker_tfa_enable;
+
+typedef void (*external_speaker_tfa_disable_t)(snd_device_t);
+static external_speaker_tfa_disable_t external_speaker_tfa_disable;
+
+typedef void (*external_speaker_tfa_set_mode_t)();
+static external_speaker_tfa_set_mode_t external_speaker_tfa_set_mode;
+
+typedef void (*external_speaker_tfa_set_mode_bt_t)();
+static external_speaker_tfa_set_mode_bt_t external_speaker_tfa_set_mode_bt;
+
+typedef void (*external_speaker_tfa_update_t)(void);
+static external_speaker_tfa_update_t external_speaker_tfa_update;
+
+typedef void (*external_speaker_tfa_set_voice_vol_t)(float);
+static external_speaker_tfa_set_voice_vol_t external_speaker_tfa_set_voice_vol;
+
+typedef int (*external_speaker_tfa_init_t)(struct audio_device *);
+static external_speaker_tfa_init_t external_speaker_tfa_init;
+
+typedef void (*external_speaker_tfa_deinit_t)(void);
+static external_speaker_tfa_deinit_t external_speaker_tfa_deinit;
+
+typedef bool (*external_speaker_tfa_is_supported_t)(void);
+static external_speaker_tfa_is_supported_t external_speaker_tfa_is_supported;
+
+void external_speaker_tfa_feature_init(bool is_feature_enabled)
+{
+    ALOGD("%s: Called with feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
+    if (is_feature_enabled) {
+        //dlopen lib
+        external_speaker_tfa_lib_handle = dlopen(EXTERNAL_SPKR_TFA_LIB_PATH, RTLD_NOW);
+        if (external_speaker_tfa_lib_handle == NULL) {
+            ALOGE("%s: dlopen failed", __func__);
+            goto feature_disabled;
+        }
+        //map each function
+        //on any faliure to map any function, disble feature
+        if (((external_speaker_tfa_enable =
+             (external_speaker_tfa_enable_t)dlsym(external_speaker_tfa_lib_handle, "tfa_98xx_enable_speaker")) == NULL) ||
+            ((external_speaker_tfa_disable =
+             (external_speaker_tfa_disable_t)dlsym(external_speaker_tfa_lib_handle, "tfa_98xx_disable_speaker")) == NULL) ||
+            ((external_speaker_tfa_set_mode =
+             (external_speaker_tfa_set_mode_t)dlsym(external_speaker_tfa_lib_handle, "tfa_98xx_set_mode")) == NULL) ||
+            ((external_speaker_tfa_set_mode_bt =
+             (external_speaker_tfa_set_mode_bt_t)dlsym(external_speaker_tfa_lib_handle, "tfa_98xx_set_mode_bt")) == NULL) ||
+            ((external_speaker_tfa_update =
+             (external_speaker_tfa_update_t)dlsym(external_speaker_tfa_lib_handle, "tfa_98xx_update")) == NULL) ||
+            ((external_speaker_tfa_set_voice_vol =
+             (external_speaker_tfa_set_voice_vol_t)dlsym(external_speaker_tfa_lib_handle, "tfa_98xx_set_voice_vol")) == NULL) ||
+            ((external_speaker_tfa_init =
+             (external_speaker_tfa_init_t)dlsym(external_speaker_tfa_lib_handle, "tfa_98xx_init")) == NULL) ||
+            ((external_speaker_tfa_deinit =
+             (external_speaker_tfa_deinit_t)dlsym(external_speaker_tfa_lib_handle, "tfa_98xx_deinit")) == NULL) ||
+            ((external_speaker_tfa_is_supported =
+             (external_speaker_tfa_is_supported_t)dlsym(external_speaker_tfa_lib_handle, "tfa_98xx_is_supported")) == NULL)) {
+            ALOGE("%s: dlsym failed", __func__);
+            goto feature_disabled;
+        }
+
+        ALOGD("%s:: ---- Feature EXTERNAL_SPKR is Enabled ----", __func__);
+        return;
+    }
+
+feature_disabled:
+    if (external_speaker_tfa_lib_handle) {
+        dlclose(external_speaker_tfa_lib_handle);
+        external_speaker_tfa_lib_handle = NULL;
+    }
+
+    external_speaker_tfa_enable = NULL;
+    external_speaker_tfa_disable = NULL;
+    external_speaker_tfa_set_mode = NULL;
+    external_speaker_tfa_update = NULL;
+    external_speaker_tfa_set_voice_vol = NULL;
+    external_speaker_tfa_init = NULL;
+    external_speaker_tfa_deinit = NULL;
+    external_speaker_tfa_is_supported = NULL;
+
+    ALOGW(":: %s: ---- Feature EXTERNAL_SPKR_TFA is disabled ----", __func__);
+    return;
+}
+
+int audio_extn_external_speaker_tfa_enable_speaker() {
+    int ret_val = 0;
+
+    if (external_speaker_tfa_enable != NULL)
+        ret_val = external_speaker_tfa_enable();
+
+    return ret_val;
+}
+
+void audio_extn_external_speaker_tfa_disable_speaker(snd_device_t snd_device) {
+    if (external_speaker_tfa_disable != NULL)
+        external_speaker_tfa_disable(snd_device);
+
+    return;
+}
+
+void audio_extn_external_speaker_tfa_set_mode(bool is_mode_bt) {
+    if (is_mode_bt && (external_speaker_tfa_set_mode_bt != NULL))
+        external_speaker_tfa_set_mode_bt();
+    else if (external_speaker_tfa_set_mode != NULL)
+        external_speaker_tfa_set_mode();
+
+    return;
+}
+
+void audio_extn_external_speaker_tfa_update() {
+    if (external_speaker_tfa_update != NULL)
+        external_speaker_tfa_update();
+
+    return;
+}
+
+void audio_extn_external_speaker_tfa_set_voice_vol(float vol) {
+    if (external_speaker_tfa_set_voice_vol != NULL)
+        external_speaker_tfa_set_voice_vol(vol);
+
+    return;
+}
+
+int  audio_extn_external_tfa_speaker_init(struct audio_device *adev) {
+    int ret_val = 0;
+
+    if (external_speaker_tfa_init != NULL)
+        ret_val = external_speaker_tfa_init(adev);
+
+    return ret_val;
+}
+
+void audio_extn_external_speaker_tfa_deinit() {
+    if (external_speaker_tfa_deinit != NULL)
+        external_speaker_tfa_deinit();
+
+    return;
+}
+
+bool audio_extn_external_speaker_tfa_is_supported() {
+    bool ret_val = false;
+
+    if (external_speaker_tfa_is_supported != NULL)
+        ret_val = external_speaker_tfa_is_supported;
+
+    return ret_val;
+}
+
+
+//END: EXTERNAL_SPEAKER_TFA ================================================================
+
+
+//START: HWDEP_CAL ================================================================
+#ifdef __LP64__
+#define HWDEP_CAL_LIB_PATH  "/vendor/lib64/libhwdepcal.so"
+#else
+#define HWDEP_CAL_LIB_PATH  "/vendor/lib/libhwdepcal.so"
+#endif
+
+static void *hwdep_cal_lib_handle = NULL;
+
+typedef void (*hwdep_cal_send_t)(int, void*);
+static hwdep_cal_send_t hwdep_cal_send;
+
+void hwdep_cal_feature_init(bool is_feature_enabled)
+{
+    ALOGD("%s: Called with feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
+    if (is_feature_enabled) {
+        //dlopen lib
+        hwdep_cal_lib_handle = dlopen(HWDEP_CAL_LIB_PATH, RTLD_NOW);
+        if (hwdep_cal_lib_handle == NULL) {
+            ALOGE("%s: dlopen failed", __func__);
+            goto feature_disabled;
+        }
+        //map each function
+        //on any faliure to map any function, disble feature
+        if ((hwdep_cal_send =
+            (hwdep_cal_send_t)dlsym(hwdep_cal_lib_handle, "hwdep_cal_send")) == NULL) {
+            ALOGE("%s: dlsym failed", __func__);
+            goto feature_disabled;
+        }
+
+        ALOGD("%s:: ---- Feature HWDEP_CAL is Enabled ----", __func__);
+        return;
+    }
+
+feature_disabled:
+    if (hwdep_cal_lib_handle) {
+        dlclose(hwdep_cal_lib_handle);
+        hwdep_cal_lib_handle = NULL;
+    }
+
+    hwdep_cal_send = NULL;
+
+    ALOGW(":: %s: ---- Feature HWDEP_CAL is disabled ----", __func__);
+    return;
+}
+
+void audio_extn_hwdep_cal_send(int snd_card, void *acdb_handle)
+{
+    if (hwdep_cal_send != NULL)
+        hwdep_cal_send(snd_card, acdb_handle);
+
+    return;
+}
+
+
+//END: HWDEP_CAL =====================================================================
+
+
+//START: DSM_FEEDBACK ================================================================
+#ifdef __LP64__
+#define DSM_FEEDBACK_LIB_PATH  "/vendor/lib64/libdsmfeedback.so"
+#else
+#define DSM_FEEDBACK_LIB_PATH  "/vendor/lib/libdsmfeedback.so"
+#endif
+
+static void *dsm_feedback_lib_handle = NULL;
+
+typedef void (*dsm_feedback_enable_t)(struct audio_device*, snd_device_t, bool);
+static dsm_feedback_enable_t dsm_feedback_enable;
+
+void dsm_feedback_feature_init (bool is_feature_enabled)
+{
+    ALOGD("%s: Called with feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
+    if (is_feature_enabled) {
+        //dlopen lib
+        dsm_feedback_lib_handle = dlopen(DSM_FEEDBACK_LIB_PATH, RTLD_NOW);
+        if (dsm_feedback_lib_handle == NULL) {
+            ALOGE("%s: dlopen failed", __func__);
+            goto feature_disabled;
+        }
+        //map each function
+        //on any faliure to map any function, disble feature
+        if ((dsm_feedback_enable =
+            (dsm_feedback_enable_t)dlsym(dsm_feedback_lib_handle, "dsm_feedback_enable")) == NULL) {
+            ALOGE("%s: dlsym failed", __func__);
+            goto feature_disabled;
+        }
+
+        ALOGD("%s:: ---- Feature DSM_FEEDBACK is Enabled ----", __func__);
+        return;
+    }
+
+feature_disabled:
+    if (dsm_feedback_lib_handle) {
+        dlclose(dsm_feedback_lib_handle);
+        dsm_feedback_lib_handle = NULL;
+    }
+
+    dsm_feedback_enable = NULL;
+
+    ALOGW(":: %s: ---- Feature DSM_FEEDBACK is disabled ----", __func__);
+    return;
+}
+
+void audio_extn_dsm_feedback_enable(struct audio_device *adev, snd_device_t snd_device, bool benable)
+{
+    if (dsm_feedback_enable != NULL)
+        dsm_feedback_enable(adev, snd_device, benable);
+
+    return;
+}
+
+//END:   DSM_FEEDBACK ================================================================
+
+//START: SND_MONITOR_FEATURE ================================================================
+#ifdef __LP64__
+#define SND_MONITOR_PATH  "/vendor/lib64/libsndmonitor.so"
+#else
+#define SND_MONITOR_PATH  "/vendor/lib/libsndmonitor.so"
+#endif
+static void *snd_mnt_lib_handle = NULL;
+
+typedef int (*snd_mon_init_t)();
+static snd_mon_init_t snd_mon_init;
+typedef int (*snd_mon_deinit_t)();
+static snd_mon_deinit_t snd_mon_deinit;
+typedef int (*snd_mon_register_listener_t)(void *, snd_mon_cb);
+static snd_mon_register_listener_t snd_mon_register_listener;
+typedef int (*snd_mon_unregister_listener_t)(void *);
+static snd_mon_unregister_listener_t snd_mon_unregister_listener;
+
+void snd_mon_feature_init (bool is_feature_enabled)
+{
+    ALOGD("%s: Called with feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
+    if (is_feature_enabled) {
+        //dlopen lib
+        snd_mnt_lib_handle = dlopen(SND_MONITOR_PATH, RTLD_NOW);
+        if (snd_mnt_lib_handle == NULL) {
+            ALOGE("%s: dlopen failed", __func__);
+            goto feature_disabled;
+        }
+        //map each function
+        //on any faliure to map any function, disble feature
+        if (((snd_mon_init = (snd_mon_init_t)dlsym(snd_mnt_lib_handle,"snd_mon_init")) == NULL) ||
+            ((snd_mon_deinit = (snd_mon_deinit_t)dlsym(snd_mnt_lib_handle,"snd_mon_deinit")) == NULL) ||
+            ((snd_mon_register_listener = (snd_mon_register_listener_t)dlsym(snd_mnt_lib_handle,"snd_mon_register_listener")) == NULL) ||
+            ((snd_mon_unregister_listener = (snd_mon_unregister_listener_t)dlsym(snd_mnt_lib_handle,"snd_mon_unregister_listener")) == NULL)) {
+            ALOGE("%s: dlsym failed", __func__);
+            goto feature_disabled;
+        }
+        ALOGD("%s:: ---- Feature SND_MONITOR is Enabled ----", __func__);
+        return;
+    }
+
+feature_disabled:
+    if (snd_mnt_lib_handle) {
+        dlclose(snd_mnt_lib_handle);
+        snd_mnt_lib_handle = NULL;
+    }
+
+    snd_mon_init                = NULL;
+    snd_mon_deinit              = NULL;
+    snd_mon_register_listener   = NULL;
+    snd_mon_unregister_listener = NULL;
+    ALOGW(":: %s: ---- Feature SND_MONITOR is disabled ----", __func__);
+    return;
+}
+
+int audio_extn_snd_mon_init()
+{
+    int ret = 0;
+    if (snd_mon_init != NULL)
+        ret = snd_mon_init();
+
+    return ret;
+}
+
+int audio_extn_snd_mon_deinit()
+{
+    int ret = 0;
+    if (snd_mon_deinit != NULL)
+        ret = snd_mon_deinit();
+
+    return ret;
+}
+
+int audio_extn_snd_mon_register_listener(void *stream, snd_mon_cb cb)
+{
+    int ret = 0;
+    if (snd_mon_register_listener != NULL)
+        ret = snd_mon_register_listener(stream, cb);
+
+    return ret;
+}
+
+int audio_extn_snd_mon_unregister_listener(void *stream)
+{
+    int ret = 0;
+    if (snd_mon_unregister_listener != NULL)
+        ret = snd_mon_unregister_listener(stream);
+
+    return ret;
+}
+
+//END: SND_MONITOR_FEATURE ================================================================
+
+//START: SOURCE_TRACKING_FEATURE ==============================================
+int get_soundfocus_data(const struct audio_device *adev,
+                                   struct sound_focus_param *payload);
+int get_sourcetrack_data(const struct audio_device *adev,
+                                    struct source_tracking_param *payload);
+int set_soundfocus_data(struct audio_device *adev,
+                                   struct sound_focus_param *payload);
+void source_track_set_parameters(struct audio_device *adev,
+                                            struct str_parms *parms);
+void source_track_get_parameters(const struct audio_device *adev,
+                                            struct str_parms *query,
+                                            struct str_parms *reply);
+
+static bool is_src_trkn_enabled = false;
+
+void src_trkn_feature_init(bool is_feature_enabled) {
+    is_src_trkn_enabled = is_feature_enabled;
+
+    if (is_src_trkn_enabled) {
+        ALOGD("%s:: ---- Feature SOURCE_TRACKING is Enabled ----", __func__);
+        return;
+    }
+
+    ALOGW(":: %s: ---- Feature SOURCE_TRACKING is disabled ----", __func__);
+}
+
+int audio_extn_get_soundfocus_data(const struct audio_device *adev,
+                                   struct sound_focus_param *payload) {
+    int ret = 0;
+
+    if (is_src_trkn_enabled)
+        ret = get_soundfocus_data(adev, payload);
+
+    return ret;
+}
+
+int audio_extn_get_sourcetrack_data(const struct audio_device *adev,
+                                    struct source_tracking_param *payload) {
+    int ret = 0;
+
+    if (is_src_trkn_enabled)
+        ret = get_sourcetrack_data(adev, payload);
+
+    return ret;
+}
+
+int audio_extn_set_soundfocus_data(struct audio_device *adev,
+                                   struct sound_focus_param *payload) {
+    int ret = 0;
+
+    if (is_src_trkn_enabled)
+        ret = set_soundfocus_data(adev, payload);
+
+    return ret;
+}
+
+void audio_extn_source_track_set_parameters(struct audio_device *adev,
+                                            struct str_parms *parms) {
+    if (is_src_trkn_enabled)
+        source_track_set_parameters(adev, parms);
+}
+
+void audio_extn_source_track_get_parameters(const struct audio_device *adev,
+                                            struct str_parms *query,
+                                            struct str_parms *reply) {
+    if (is_src_trkn_enabled)
+        source_track_get_parameters(adev, query, reply);
+}
+//END: SOURCE_TRACKING_FEATURE ================================================
+
+//START: SSREC_FEATURE ==========================================================
+#ifdef __LP64__
+#define SSREC_LIB_PATH  "/vendor/lib64/libssrec.so"
+#else
+#define SSREC_LIB_PATH  "/vendor/lib/libssrec.so"
+#endif
+
+static void *ssrec_lib_handle = NULL;
+
+typedef bool (*ssr_check_usecase_t)(struct stream_in *);
+static ssr_check_usecase_t ssr_check_usecase;
+
+typedef int (*ssr_set_usecase_t)(struct stream_in *,
+                                 struct audio_config *,
+                                 bool *);
+static ssr_set_usecase_t ssr_set_usecase;
+
+typedef int32_t (*ssr_init_t)(struct stream_in *,
+                              int num_out_chan);
+static ssr_init_t ssr_init;
+
+typedef int32_t (*ssr_deinit_t)();
+static ssr_deinit_t ssr_deinit;
+
+typedef void (*ssr_update_enabled_t)();
+static ssr_update_enabled_t ssr_update_enabled;
+
+typedef bool (*ssr_get_enabled_t)();
+static ssr_get_enabled_t ssr_get_enabled;
+
+typedef int32_t (*ssr_read_t)(struct audio_stream_in *,
+                              void *,
+                              size_t);
+static ssr_read_t ssr_read;
+
+typedef void (*ssr_set_parameters_t)(struct audio_device *,
+                                     struct str_parms *);
+static ssr_set_parameters_t ssr_set_parameters;
+
+typedef void (*ssr_get_parameters_t)(const struct audio_device *,
+                                     struct str_parms *,
+                                     struct str_parms *);
+static ssr_get_parameters_t ssr_get_parameters;
+
+typedef struct stream_in *(*ssr_get_stream_t)();
+static ssr_get_stream_t ssr_get_stream;
+
+void ssrec_feature_init(bool is_feature_enabled) {
+
+    if (is_feature_enabled) {
+        ssrec_lib_handle = dlopen(SSREC_LIB_PATH, RTLD_NOW);
+        if (ssrec_lib_handle == NULL) {
+            ALOGE("%s: dlopen failed", __func__);
+            goto feature_disabled;
+        }
+
+        if (((ssr_check_usecase = (ssr_check_usecase_t)dlsym(ssrec_lib_handle, "ssr_check_usecase")) == NULL) ||
+            ((ssr_set_usecase = (ssr_set_usecase_t)dlsym(ssrec_lib_handle, "ssr_set_usecase")) == NULL) ||
+            ((ssr_init = (ssr_init_t)dlsym(ssrec_lib_handle, "ssr_init")) == NULL) ||
+            ((ssr_deinit = (ssr_deinit_t)dlsym(ssrec_lib_handle, "ssr_deinit")) == NULL) ||
+            ((ssr_update_enabled = (ssr_update_enabled_t)dlsym(ssrec_lib_handle, "ssr_update_enabled")) == NULL) ||
+            ((ssr_get_enabled = (ssr_get_enabled_t)dlsym(ssrec_lib_handle, "ssr_get_enabled")) == NULL) ||
+            ((ssr_read = (ssr_read_t)dlsym(ssrec_lib_handle, "ssr_read")) == NULL) ||
+            ((ssr_set_parameters = (ssr_set_parameters_t)dlsym(ssrec_lib_handle, "ssr_set_parameters")) == NULL) ||
+            ((ssr_get_parameters = (ssr_get_parameters_t)dlsym(ssrec_lib_handle, "ssr_get_parameters")) == NULL) ||
+            ((ssr_get_stream = (ssr_get_stream_t)dlsym(ssrec_lib_handle, "ssr_get_stream")) == NULL)) {
+            ALOGE("%s: dlsym failed", __func__);
+            goto feature_disabled;
+        }
+
+        ALOGD("%s:: ---- Feature SSREC is Enabled ----", __func__);
+        return;
+    }
+
+feature_disabled:
+    if(ssrec_lib_handle) {
+        dlclose(ssrec_lib_handle);
+        ssrec_lib_handle = NULL;
+    }
+
+    ssr_check_usecase = NULL;
+    ssr_set_usecase = NULL;
+    ssr_init = NULL;
+    ssr_deinit = NULL;
+    ssr_update_enabled = NULL;
+    ssr_get_enabled = NULL;
+    ssr_read = NULL;
+    ssr_set_parameters = NULL;
+    ssr_get_parameters = NULL;
+    ssr_get_stream = NULL;
+
+    ALOGW(":: %s: ---- Feature SSREC is disabled ----", __func__);
+}
+
+bool audio_extn_ssr_check_usecase(struct stream_in *in) {
+    bool ret = false;
+
+    if (ssrec_lib_handle != NULL)
+        ret = ssr_check_usecase(in);
+
+    return ret;
+}
+
+int audio_extn_ssr_set_usecase(struct stream_in *in,
+                               struct audio_config *config,
+                               bool *channel_mask_updated) {
+    int ret = 0;
+
+    if (ssrec_lib_handle != NULL)
+        ret = ssr_set_usecase(in, config, channel_mask_updated);
+
+    return ret;
+}
+
+int32_t audio_extn_ssr_init(struct stream_in *in,
+                            int num_out_chan) {
+    int32_t ret = 0;
+
+    if (ssrec_lib_handle != NULL)
+        ret = ssr_init(in, num_out_chan);
+
+    return ret;
+}
+
+int32_t audio_extn_ssr_deinit() {
+    int32_t ret = 0;
+
+    if (ssrec_lib_handle != NULL)
+        ret = ssr_deinit();
+
+    return ret;
+}
+
+void audio_extn_ssr_update_enabled() {
+
+    if (ssrec_lib_handle)
+        ssr_update_enabled();
+}
+
+bool audio_extn_ssr_get_enabled() {
+    bool ret = false;
+
+    if (ssrec_lib_handle)
+        ret = ssr_get_enabled();
+
+    return ret;
+}
+
+int32_t audio_extn_ssr_read(struct audio_stream_in *stream,
+                            void *buffer,
+                            size_t bytes) {
+    int32_t ret = 0;
+
+    if (ssrec_lib_handle)
+        ret = ssr_read(stream, buffer, bytes);
+
+    return ret;
+}
+
+void audio_extn_ssr_set_parameters(struct audio_device *adev,
+                                   struct str_parms *parms) {
+
+    if (ssrec_lib_handle)
+        ssr_set_parameters(adev, parms);
+}
+
+void audio_extn_ssr_get_parameters(const struct audio_device *adev,
+                                   struct str_parms *query,
+                                   struct str_parms *reply) {
+
+    if (ssrec_lib_handle)
+        ssr_get_parameters(adev, query, reply);
+}
+
+struct stream_in *audio_extn_ssr_get_stream() {
+    struct stream_in *ret = NULL;
+
+    if (ssrec_lib_handle)
+        ret = ssr_get_stream();
+
+    return ret;
+}
+//END: SSREC_FEATURE ============================================================
+
+//START: COMPRESS_CAPTURE_FEATURE ================================================================
+#ifdef __LP64__
+#define COMPRESS_CAPTURE_PATH  "/vendor/lib64/libcomprcapture.so"
+#else
+#define COMPRESS_CAPTURE_PATH  "/vendor/lib/libcomprcapture.so"
+#endif
+static void *compr_cap_lib_handle = NULL;
+
+typedef void (*compr_cap_init_t)(struct stream_in*);
+static compr_cap_init_t compr_cap_init;
+
+typedef void (*compr_cap_deinit_t)();
+static compr_cap_deinit_t compr_cap_deinit;
+
+typedef bool (*compr_cap_enabled_t)();
+static compr_cap_enabled_t compr_cap_enabled;
+
+typedef bool (*compr_cap_format_supported_t)(audio_format_t);
+static compr_cap_format_supported_t compr_cap_format_supported;
+
+typedef bool (*compr_cap_usecase_supported_t)(audio_usecase_t);
+static compr_cap_usecase_supported_t compr_cap_usecase_supported;
+
+typedef size_t (*compr_cap_get_buffer_size_t)(audio_usecase_t);
+static compr_cap_get_buffer_size_t compr_cap_get_buffer_size;
+
+typedef int (*compr_cap_read_t)(struct stream_in*, void*, size_t);
+static compr_cap_read_t compr_cap_read;
+
+void compr_cap_feature_init(bool is_feature_enabled)
+{
+    if(is_feature_enabled) {
+        //dlopen lib
+        compr_cap_lib_handle = dlopen(COMPRESS_CAPTURE_PATH, RTLD_NOW);
+        if (compr_cap_lib_handle == NULL) {
+            ALOGE("%s: dlopen failed", __func__);
+            goto feature_disabled;
+        }
+        //map each function
+        //on any faliure to map any function, disble feature
+        if (((compr_cap_init = (compr_cap_init_t)dlsym(compr_cap_lib_handle,"compr_cap_init")) == NULL) ||
+            ((compr_cap_deinit = (compr_cap_deinit_t)dlsym(compr_cap_lib_handle,"compr_cap_deinit")) == NULL) ||
+            ((compr_cap_enabled = (compr_cap_enabled_t)dlsym(compr_cap_lib_handle,"compr_cap_enabled")) == NULL) ||
+            ((compr_cap_format_supported = (compr_cap_format_supported_t)dlsym(compr_cap_lib_handle,"compr_cap_format_supported")) == NULL) ||
+            ((compr_cap_usecase_supported = (compr_cap_usecase_supported_t)dlsym(compr_cap_lib_handle,"compr_cap_usecase_supported")) == NULL) ||
+            ((compr_cap_get_buffer_size = (compr_cap_get_buffer_size_t)dlsym(compr_cap_lib_handle,"compr_cap_get_buffer_size")) == NULL) ||
+            ((compr_cap_read = (compr_cap_read_t)dlsym(compr_cap_lib_handle,"compr_cap_read")) == NULL)) {
+            ALOGE("%s: dlsym failed", __func__);
+            goto feature_disabled;
+        }
+
+        ALOGD("%s:: ---- Feature COMPRESS_CAPTURE is Enabled ----", __func__);
+        return;
+    }
+
+feature_disabled:
+    if (compr_cap_lib_handle) {
+        dlclose(compr_cap_lib_handle);
+        compr_cap_lib_handle = NULL;
+    }
+
+    compr_cap_init                 = NULL;
+    compr_cap_deinit               = NULL;
+    compr_cap_enabled              = NULL;
+    compr_cap_format_supported     = NULL;
+    compr_cap_usecase_supported    = NULL;
+    compr_cap_get_buffer_size      = NULL;
+    compr_cap_read                 = NULL;
+
+    ALOGW(":: %s: ---- Feature COMPRESS_CAPTURE is disabled ----", __func__);
+    return;
+}
+
+void audio_extn_compr_cap_init(struct stream_in* instream)
+{
+    if (compr_cap_init != NULL)
+        compr_cap_init(instream);
+
+    return;
+}
+
+void audio_extn_compr_cap_deinit()
+{
+    if(compr_cap_deinit)
+        compr_cap_deinit();
+
+    return;
+}
+
+bool audio_extn_compr_cap_enabled()
+{
+    bool ret_val = false;
+
+    if (compr_cap_enabled)
+        ret_val = compr_cap_enabled();
+
+    return ret_val;
+}
+
+bool audio_extn_compr_cap_format_supported(audio_format_t format)
+{
+    bool ret_val = false;
+
+    if (compr_cap_format_supported != NULL)
+        ret_val =  compr_cap_format_supported(format);
+
+    return ret_val;
+}
+
+bool audio_extn_compr_cap_usecase_supported(audio_usecase_t usecase)
+{
+    bool ret_val = false;
+
+    if (compr_cap_usecase_supported != NULL)
+        ret_val =  compr_cap_usecase_supported(usecase);
+
+    return ret_val;
+}
+
+size_t audio_extn_compr_cap_get_buffer_size(audio_format_t format)
+{
+    size_t ret_val = 0;
+
+    if (compr_cap_get_buffer_size != NULL)
+        ret_val =  compr_cap_get_buffer_size(format);
+
+    return ret_val;
+}
+
+size_t audio_extn_compr_cap_read(struct stream_in *in,
+                                        void *buffer, size_t bytes)
+{
+    size_t ret_val = 0;
+
+    if (compr_cap_read != NULL)
+        ret_val =  compr_cap_read(in, buffer, bytes);
+
+    return ret_val;
+}
+
+
 void audio_extn_init(struct audio_device *adev)
 {
+    //fix-me: check running on vendor enhanced build
+    //is_running_on_stock_version = !isRunningWithVendorEnhancedFramework();
+    audio_extn_feature_init();
     aextnmod.anc_enabled = 0;
     aextnmod.aanc_enabled = 0;
     aextnmod.custom_stereo_enabled = 0;
@@ -925,71 +2348,16 @@
     audio_extn_aptx_dec_set_license(adev);
 }
 
-void audio_extn_set_parameters(struct audio_device *adev,
-                               struct str_parms *parms)
-{
-   audio_extn_set_aanc_noise_level(adev, parms);
-   audio_extn_set_anc_parameters(adev, parms);
-   audio_extn_set_fluence_parameters(adev, parms);
-   audio_extn_set_afe_proxy_parameters(adev, parms);
-   audio_extn_fm_set_parameters(adev, parms);
-   audio_extn_sound_trigger_set_parameters(adev, parms);
-   audio_extn_listen_set_parameters(adev, parms);
-   audio_extn_ssr_set_parameters(adev, parms);
-   audio_extn_hfp_set_parameters(adev, parms);
-   audio_extn_dts_eagle_set_parameters(adev, parms);
-   audio_extn_a2dp_set_parameters(parms);
-   audio_extn_ddp_set_parameters(adev, parms);
-   audio_extn_ds2_set_parameters(adev, parms);
-   audio_extn_customstereo_set_parameters(adev, parms);
-   audio_extn_hpx_set_parameters(adev, parms);
-   audio_extn_pm_set_parameters(parms);
-   audio_extn_source_track_set_parameters(adev, parms);
-   audio_extn_fbsp_set_parameters(parms);
-   audio_extn_keep_alive_set_parameters(adev, parms);
-   audio_extn_passthru_set_parameters(adev, parms);
-   audio_extn_ext_disp_set_parameters(adev, parms);
-   audio_extn_qaf_set_parameters(adev, parms);
-   if (adev->offload_effects_set_parameters != NULL)
-       adev->offload_effects_set_parameters(parms);
-   audio_extn_set_aptx_dec_bt_addr(adev, parms);
-   audio_extn_ffv_set_parameters(adev, parms);
-   audio_extn_ext_hw_plugin_set_parameters(adev->ext_hw_plugin, parms);
-}
-
-void audio_extn_get_parameters(const struct audio_device *adev,
-                              struct str_parms *query,
-                              struct str_parms *reply)
-{
-    char *kv_pairs = NULL;
-    audio_extn_get_afe_proxy_parameters(adev, query, reply);
-    audio_extn_get_fluence_parameters(adev, query, reply);
-    audio_extn_ssr_get_parameters(adev, query, reply);
-    get_active_offload_usecases(adev, query, reply);
-    audio_extn_dts_eagle_get_parameters(adev, query, reply);
-    audio_extn_hpx_get_parameters(query, reply);
-    audio_extn_source_track_get_parameters(adev, query, reply);
-    audio_extn_fbsp_get_parameters(query, reply);
-    audio_extn_sound_trigger_get_parameters(adev, query, reply);
-    audio_extn_fm_get_parameters(query, reply);
-    if (adev->offload_effects_get_parameters != NULL)
-        adev->offload_effects_get_parameters(query, reply);
-    audio_extn_ext_hw_plugin_get_parameters(adev->ext_hw_plugin, query, reply);
-
-    kv_pairs = str_parms_to_str(reply);
-    ALOGD_IF(kv_pairs != NULL, "%s: returns %s", __func__, kv_pairs);
-    free(kv_pairs);
-}
-
-#ifndef COMPRESS_METADATA_NEEDED
-#define audio_extn_parse_compress_metadata(out, parms) (0)
-#else
 int audio_extn_parse_compress_metadata(struct stream_out *out,
                                        struct str_parms *parms)
 {
     int ret = 0;
     char value[32];
 
+    if (!if_compress_meta_data_feature_enabled()) {
+        return ret;
+    }
+
     if (out->format == AUDIO_FORMAT_FLAC) {
         ret = str_parms_get_str(parms, AUDIO_OFFLOAD_CODEC_FLAC_MIN_BLK_SIZE, value, sizeof(value));
         if (ret >= 0) {
@@ -1221,7 +2589,6 @@
 
     return ret;
 }
-#endif
 
 #ifdef AUXPCM_BT_ENABLED
 int32_t audio_extn_read_xml(struct audio_device *adev, uint32_t mixer_card,
@@ -1251,85 +2618,6 @@
 }
 #endif /* AUXPCM_BT_ENABLED */
 
-#ifdef KPI_OPTIMIZE_ENABLED
-typedef int (*perf_lock_acquire_t)(int, int, int*, int);
-typedef int (*perf_lock_release_t)(int);
-
-static void *qcopt_handle;
-static perf_lock_acquire_t perf_lock_acq;
-static perf_lock_release_t perf_lock_rel;
-
-char opt_lib_path[512] = {0};
-
-int audio_extn_perf_lock_init(void)
-{
-    int ret = 0;
-    if (qcopt_handle == NULL) {
-        if (property_get("ro.vendor.extension_library",
-                         opt_lib_path, NULL) <= 0) {
-            ALOGE("%s: Failed getting perf property \n", __func__);
-            ret = -EINVAL;
-            goto err;
-        }
-        if ((qcopt_handle = dlopen(opt_lib_path, RTLD_NOW)) == NULL) {
-            ALOGE("%s: Failed to open perf handle \n", __func__);
-            ret = -EINVAL;
-            goto err;
-        } else {
-            perf_lock_acq = (perf_lock_acquire_t)dlsym(qcopt_handle,
-                                                       "perf_lock_acq");
-            if (perf_lock_acq == NULL) {
-                ALOGE("%s: Perf lock Acquire NULL \n", __func__);
-                dlclose(qcopt_handle);
-                ret = -EINVAL;
-                goto err;
-            }
-            perf_lock_rel = (perf_lock_release_t)dlsym(qcopt_handle,
-                                                       "perf_lock_rel");
-            if (perf_lock_rel == NULL) {
-                ALOGE("%s: Perf lock Release NULL \n", __func__);
-                dlclose(qcopt_handle);
-                ret = -EINVAL;
-                goto err;
-            }
-            ALOGE("%s: Perf lock handles Success \n", __func__);
-        }
-    }
-err:
-    return ret;
-}
-
-void audio_extn_perf_lock_acquire(int *handle, int duration,
-                                 int *perf_lock_opts, int size)
-{
-
-    if (!perf_lock_opts || !size || !perf_lock_acq || !handle) {
-        ALOGE("%s: Incorrect params, Failed to acquire perf lock, err ",
-              __func__);
-        return;
-    }
-    /*
-     * Acquire performance lock for 1 sec during device path bringup.
-     * Lock will be released either after 1 sec or when perf_lock_release
-     * function is executed.
-     */
-    *handle = perf_lock_acq(*handle, duration, perf_lock_opts, size);
-    if (*handle <= 0)
-        ALOGE("%s: Failed to acquire perf lock, err: %d\n",
-              __func__, *handle);
-}
-
-void audio_extn_perf_lock_release(int *handle)
-{
-    if (perf_lock_rel && handle && (*handle > 0)) {
-        perf_lock_rel(*handle);
-        *handle = 0;
-    } else {
-        ALOGE("%s: Perf lock release error \n", __func__);
-    }
-}
-#endif /* KPI_OPTIMIZE_ENABLED */
-
 static int audio_extn_set_multichannel_mask(struct audio_device *adev,
                                             struct stream_in *in,
                                             struct audio_config *config,
@@ -1638,4 +2926,904 @@
     return 0;
 }
 
+//START: FM_POWER_OPT_FEATURE ================================================================
+void fm_feature_init(bool is_feature_enabled)
+{
+    audio_extn_fm_power_opt_enabled = is_feature_enabled;
+    ALOGD(":: %s: ---- Feature FM_POWER_OPT is %s----", __func__, is_feature_enabled? "ENABLED": "NOT ENABLED");
+}
 
+
+void audio_extn_fm_get_parameters(struct str_parms *query, struct str_parms *reply)
+{
+    if(audio_extn_fm_power_opt_enabled)
+        fm_get_parameters(query, reply);
+}
+
+void audio_extn_fm_set_parameters(struct audio_device *adev,
+                                  struct str_parms *parms)
+{
+    if(audio_extn_fm_power_opt_enabled)
+        fm_set_parameters(adev, parms);
+}
+//END: FM_POWER_OPT_FEATURE ================================================================
+
+//START: HDMI_EDID =========================================================================
+#ifdef __LP64__
+#define HDMI_EDID_LIB_PATH  "/vendor/lib64/libhdmiedid.so"
+#else
+#define HDMI_EDID_LIB_PATH  "/vendor/lib/libhdmiedid.so"
+#endif
+
+static void *hdmi_edid_lib_handle = NULL;
+
+typedef bool (*hdmi_edid_is_supported_sr_t)(edid_audio_info*, int);
+static hdmi_edid_is_supported_sr_t hdmi_edid_is_supported_sr;
+
+typedef bool (*hdmi_edid_is_supported_bps_t)(edid_audio_info*, int);
+static hdmi_edid_is_supported_bps_t hdmi_edid_is_supported_bps;
+
+typedef int (*hdmi_edid_get_highest_supported_sr_t)(edid_audio_info*);
+static hdmi_edid_get_highest_supported_sr_t hdmi_edid_get_highest_supported_sr;
+
+typedef bool (*hdmi_edid_get_sink_caps_t)(edid_audio_info*, char*);
+static hdmi_edid_get_sink_caps_t hdmi_edid_get_sink_caps;
+
+void hdmi_edid_feature_init(bool is_feature_enabled)
+{
+    ALOGD("%s: HDMI_EDID feature %s", __func__, is_feature_enabled?"Enabled":"NOT Enabled");
+    if (is_feature_enabled) {
+        //dlopen lib
+        hdmi_edid_lib_handle = dlopen(HDMI_EDID_LIB_PATH, RTLD_NOW);
+        if (hdmi_edid_lib_handle == NULL) {
+            ALOGE("%s: dlopen failed", __func__);
+            goto feature_disabled;
+        }
+        //map each function
+        //on any faliure to map any function, disble feature
+        if (((hdmi_edid_is_supported_sr =
+             (hdmi_edid_is_supported_sr_t)dlsym(hdmi_edid_lib_handle, 
+                                                "edid_is_supported_sr")) == NULL) ||
+            ((hdmi_edid_is_supported_bps =
+             (hdmi_edid_is_supported_bps_t)dlsym(hdmi_edid_lib_handle,
+                                                "edid_is_supported_bps")) == NULL) ||
+            ((hdmi_edid_get_highest_supported_sr =
+             (hdmi_edid_get_highest_supported_sr_t)dlsym(hdmi_edid_lib_handle, 
+                                                "edid_get_highest_supported_sr")) == NULL) ||
+            ((hdmi_edid_get_sink_caps =
+             (hdmi_edid_get_sink_caps_t)dlsym(hdmi_edid_lib_handle, 
+                                                "edid_get_sink_caps")) == NULL)) {
+            ALOGE("%s: dlsym failed", __func__);
+            goto feature_disabled;
+        }
+
+        ALOGD("%s:: ---- Feature HDMI_EDID is Enabled ----", __func__);
+        return;
+    }
+
+feature_disabled:
+    if (hdmi_edid_lib_handle) {
+        dlclose(hdmi_edid_lib_handle);
+        hdmi_edid_lib_handle = NULL;
+    }
+
+    hdmi_edid_is_supported_sr = NULL;
+    hdmi_edid_is_supported_bps = NULL;
+    hdmi_edid_get_highest_supported_sr = NULL;
+    hdmi_edid_get_sink_caps = NULL;
+    ALOGW(":: %s: ---- Feature HDMI_EDID is disabled ----", __func__);
+    return;
+}
+
+bool audio_extn_edid_is_supported_sr(edid_audio_info* info, int sr)
+{
+    bool ret = false;
+
+    if(hdmi_edid_is_supported_sr != NULL)
+        ret = hdmi_edid_is_supported_sr(info, sr);
+    return ret;
+}
+
+bool audio_extn_edid_is_supported_bps(edid_audio_info* info, int bps)
+{
+    bool ret = false;
+
+    if(hdmi_edid_is_supported_bps != NULL)
+        ret = hdmi_edid_is_supported_bps(info, bps);
+    return ret;
+}
+int audio_extn_edid_get_highest_supported_sr(edid_audio_info* info)
+{
+    int ret = -1;
+
+    if(hdmi_edid_get_highest_supported_sr != NULL)
+        ret = hdmi_edid_get_highest_supported_sr(info);
+    return ret;
+}
+
+bool audio_extn_edid_get_sink_caps(edid_audio_info* info, char *edid_data)
+{
+    bool ret = false;
+
+    if(hdmi_edid_get_sink_caps != NULL)
+        ret = hdmi_edid_get_sink_caps(info, edid_data);
+    return ret;
+}
+
+//END: HDMI_EDID =========================================================================
+
+
+//START: KEEP_ALIVE =========================================================================
+
+void keep_alive_feature_init(bool is_feature_enabled)
+{
+    audio_extn_keep_alive_enabled = is_feature_enabled;
+    ALOGD(":: %s: ---- Feature KEEP_ALIVE is %s ----", __func__, is_feature_enabled? "ENABLED": " NOT ENABLED");
+}
+
+void audio_extn_keep_alive_init(struct audio_device *adev)
+{
+    if(audio_extn_keep_alive_enabled)
+        keep_alive_init(adev);
+}
+
+void audio_extn_keep_alive_deinit()
+{
+    if(audio_extn_keep_alive_enabled)
+        keep_alive_deinit();
+}
+
+void audio_extn_keep_alive_start(ka_mode_t ka_mode)
+{
+    if(audio_extn_keep_alive_enabled)
+        keep_alive_start(ka_mode);
+}
+
+void audio_extn_keep_alive_stop(ka_mode_t ka_mode)
+{
+    if(audio_extn_keep_alive_enabled)
+        keep_alive_stop(ka_mode);
+}
+
+bool audio_extn_keep_alive_is_active()
+{
+    bool ret = false;
+    return ret;
+}
+
+int audio_extn_keep_alive_set_parameters(struct audio_device *adev,
+                                         struct str_parms *parms)
+{
+    int ret = -1;
+    if(audio_extn_keep_alive_enabled)
+        return keep_alive_set_parameters(adev, parms);
+    return ret;
+}
+//END: KEEP_ALIVE =========================================================================
+
+//START: HIFI_AUDIO =========================================================================
+void hifi_audio_feature_init(bool is_feature_enabled)
+{
+    audio_extn_hifi_audio_enabled = is_feature_enabled;
+    ALOGD(":: %s: ---- Feature HIFI_AUDIO is %s ----", __func__, is_feature_enabled? "ENABLED": " NOT ENABLED");
+}
+
+bool audio_extn_is_hifi_audio_enabled(void)
+{
+    bool ret = false;
+    if(audio_extn_hifi_audio_enabled)
+    {
+        ALOGV("%s: status: %d", __func__, aextnmod.hifi_audio_enabled);
+        return (aextnmod.hifi_audio_enabled ? true: false);
+    }
+    return ret;
+}
+
+bool audio_extn_is_hifi_audio_supported(void)
+{
+    bool ret = false;
+
+    if(audio_extn_hifi_audio_enabled)
+    {
+        /*
+         * for internal codec, check for hifiaudio property to enable hifi audio
+         */
+        if (property_get_bool("persist.vendor.audio.hifi.int_codec", false))
+        {
+            ALOGD("%s: hifi audio supported on internal codec", __func__);
+            aextnmod.hifi_audio_enabled = 1;
+        }
+        return (aextnmod.hifi_audio_enabled ? true: false);
+    }
+    return ret;
+}
+
+//END: HIFI_AUDIO =========================================================================
+
+//START: RAS =============================================================================
+void ras_feature_init(bool is_feature_enabled)
+{
+    audio_extn_ras_feature_enabled = is_feature_enabled;
+    ALOGD(":: %s: ---- Feature RAS_FEATURE is %s ----", __func__, is_feature_enabled? "ENABLED": " NOT ENABLED");
+}
+
+bool audio_extn_is_ras_enabled(void)
+{
+    bool ret = false;
+
+    if(audio_extn_ras_feature_enabled)
+    {
+        ALOGD("%s: status: %d", __func__, aextnmod.ras_enabled);
+        return (aextnmod.ras_enabled ? true: false);
+    }
+    return ret;
+}
+
+bool audio_extn_can_use_ras(void)
+{
+    bool ret = false;
+
+    if(audio_extn_ras_feature_enabled)
+    {
+        if (property_get_bool("persist.vendor.audio.ras.enabled", false))
+            aextnmod.ras_enabled = 1;
+        ALOGD("%s: ras.enabled property is set to %d", __func__, aextnmod.ras_enabled);
+        return (aextnmod.ras_enabled ? true: false);
+    }
+    return ret;
+}
+
+//END: RAS ===============================================================================
+
+//START: KPI_OPTIMIZE =============================================================================
+void kpi_optimize_feature_init(bool is_feature_enabled)
+{
+    audio_extn_kpi_optimize_feature_enabled = is_feature_enabled;
+    ALOGD(":: %s: ---- Feature KPI_OPTIMIZE is %s ----", __func__, is_feature_enabled? "ENABLED": " NOT ENABLED");
+}
+
+typedef int (*perf_lock_acquire_t)(int, int, int*, int);
+typedef int (*perf_lock_release_t)(int);
+
+static void *qcopt_handle;
+static perf_lock_acquire_t perf_lock_acq;
+static perf_lock_release_t perf_lock_rel;
+
+char opt_lib_path[512] = {0};
+
+int audio_extn_perf_lock_init(void)
+{
+    int ret = 0;
+
+    //if feature is disabled, exit immediately
+    if(!audio_extn_kpi_optimize_feature_enabled)
+        goto err;
+
+    if (qcopt_handle == NULL) {
+        if (property_get("ro.vendor.extension_library",
+                         opt_lib_path, NULL) <= 0) {
+            ALOGE("%s: Failed getting perf property \n", __func__);
+            ret = -EINVAL;
+            goto err;
+        }
+        if ((qcopt_handle = dlopen(opt_lib_path, RTLD_NOW)) == NULL) {
+            ALOGE("%s: Failed to open perf handle \n", __func__);
+            ret = -EINVAL;
+            goto err;
+        } else {
+            perf_lock_acq = (perf_lock_acquire_t)dlsym(qcopt_handle,
+                                                       "perf_lock_acq");
+            if (perf_lock_acq == NULL) {
+                ALOGE("%s: Perf lock Acquire NULL \n", __func__);
+                dlclose(qcopt_handle);
+                ret = -EINVAL;
+                goto err;
+            }
+            perf_lock_rel = (perf_lock_release_t)dlsym(qcopt_handle,
+                                                       "perf_lock_rel");
+            if (perf_lock_rel == NULL) {
+                ALOGE("%s: Perf lock Release NULL \n", __func__);
+                dlclose(qcopt_handle);
+                ret = -EINVAL;
+                goto err;
+            }
+            ALOGE("%s: Perf lock handles Success \n", __func__);
+        }
+    }
+err:
+    return ret;
+}
+
+void audio_extn_perf_lock_acquire(int *handle, int duration,
+                                 int *perf_lock_opts, int size)
+{
+    if (audio_extn_kpi_optimize_feature_enabled)
+    {
+        if (!perf_lock_opts || !size || !perf_lock_acq || !handle) {
+            ALOGE("%s: Incorrect params, Failed to acquire perf lock, err ",
+                  __func__);
+            return;
+        }
+        /*
+         * Acquire performance lock for 1 sec during device path bringup.
+         * Lock will be released either after 1 sec or when perf_lock_release
+         * function is executed.
+         */
+        *handle = perf_lock_acq(*handle, duration, perf_lock_opts, size);
+        if (*handle <= 0)
+            ALOGE("%s: Failed to acquire perf lock, err: %d\n",
+                  __func__, *handle);
+    }
+}
+
+void audio_extn_perf_lock_release(int *handle)
+{
+    if (audio_extn_kpi_optimize_feature_enabled) {
+         if (perf_lock_rel && handle && (*handle > 0)) {
+            perf_lock_rel(*handle);
+            *handle = 0;
+        } else
+            ALOGE("%s: Perf lock release error \n", __func__);
+    }
+}
+
+//END: KPI_OPTIMIZE =============================================================================
+
+//START: DISPLAY_PORT =============================================================================
+void display_port_feature_init(bool is_feature_enabled)
+{
+    audio_extn_display_port_feature_enabled = is_feature_enabled;
+    ALOGD(":: %s: ---- Feature DISPLAY_PORT is %s ----", __func__, is_feature_enabled? "ENABLED": " NOT ENABLED");
+}
+
+bool audio_extn_is_display_port_enabled()
+{
+    return audio_extn_display_port_feature_enabled;
+}
+//END: DISPLAY_PORT ===============================================================================
+//START: FLUENCE =============================================================================
+void fluence_feature_init(bool is_feature_enabled)
+{
+    audio_extn_fluence_feature_enabled = is_feature_enabled;
+    ALOGD(":: %s: ---- Feature FLUENCE is %s ----", __func__, is_feature_enabled? "ENABLED": " NOT ENABLED");
+}
+
+bool audio_extn_is_fluence_enabled()
+{
+    return audio_extn_fluence_feature_enabled;
+}
+
+void audio_extn_set_fluence_parameters(struct audio_device *adev,
+                                            struct str_parms *parms)
+{
+    int ret = 0, err;
+    char value[32];
+    struct listnode *node;
+    struct audio_usecase *usecase;
+
+    if (audio_extn_is_fluence_enabled()) {
+        err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_FLUENCE,
+                                 value, sizeof(value));
+        ALOGV_IF(err >= 0, "%s: Set Fluence Type to %s", __func__, value);
+        if (err >= 0) {
+            ret = platform_set_fluence_type(adev->platform, value);
+            if (ret != 0) {
+                ALOGE("platform_set_fluence_type returned error: %d", ret);
+            } else {
+                /*
+                 *If the fluence is manually set/reset, devices
+                 *need to get updated for all the usecases
+                 *i.e. audio and voice.
+                 */
+                 list_for_each(node, &adev->usecase_list) {
+                     usecase = node_to_item(node, struct audio_usecase, list);
+                     select_devices(adev, usecase->id);
+                 }
+            }
+        }
+
+    }
+}
+
+int audio_extn_get_fluence_parameters(const struct audio_device *adev,
+                       struct str_parms *query, struct str_parms *reply)
+{
+    int ret = -1, err;
+    char value[256] = {0};
+
+    if (audio_extn_is_fluence_enabled()) {
+        err = str_parms_get_str(query, AUDIO_PARAMETER_KEY_FLUENCE, value,
+                                                          sizeof(value));
+        if (err >= 0) {
+            ret = platform_get_fluence_type(adev->platform, value, sizeof(value));
+            if (ret >= 0) {
+                ALOGV("%s: Fluence Type is %s", __func__, value);
+                str_parms_add_str(reply, AUDIO_PARAMETER_KEY_FLUENCE, value);
+            } else
+                goto done;
+        }
+    }
+done:
+    return ret;
+}
+//END: FLUENCE ===============================================================================
+//START: CUSTOM_STEREO =============================================================================
+void custom_stereo_feature_init(bool is_feature_enabled)
+{
+    audio_extn_custom_stereo_feature_enabled = is_feature_enabled;
+    ALOGD(":: %s: ---- Feature CUSTOM_STEREO is %s ----", __func__, is_feature_enabled? "ENABLED": " NOT ENABLED");
+}
+
+bool audio_extn_is_custom_stereo_enabled()
+{
+    return audio_extn_custom_stereo_feature_enabled;
+}
+
+void audio_extn_customstereo_set_parameters(struct audio_device *adev,
+                                           struct str_parms *parms)
+{
+    int ret = 0;
+    char value[32]={0};
+    bool custom_stereo_state = false;
+    const char *mixer_ctl_name = "Set Custom Stereo OnOff";
+    struct mixer_ctl *ctl;
+
+    ALOGV("%s", __func__);
+
+    if (audio_extn_custom_stereo_feature_enabled) {
+        ret = str_parms_get_str(parms, AUDIO_PARAMETER_CUSTOM_STEREO, value,
+                            sizeof(value));
+        if (ret >= 0) {
+            if (!strncmp("true", value, sizeof("true")) || atoi(value))
+                custom_stereo_state = true;
+
+            if (custom_stereo_state == aextnmod.custom_stereo_enabled)
+                return;
+
+            ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+            if (!ctl) {
+                ALOGE("%s: Could not get ctl for mixer cmd - %s",
+                      __func__, mixer_ctl_name);
+                return;
+            }
+            if (mixer_ctl_set_value(ctl, 0, custom_stereo_state) < 0) {
+                ALOGE("%s: Could not set custom stereo state %d",
+                      __func__, custom_stereo_state);
+                return;
+            }
+            aextnmod.custom_stereo_enabled = custom_stereo_state;
+            ALOGV("%s: Setting custom stereo state success", __func__);
+        }
+    }
+}
+
+void audio_extn_send_dual_mono_mixing_coefficients(struct stream_out *out)
+{
+    struct audio_device *adev = out->dev;
+    struct mixer_ctl *ctl;
+    char mixer_ctl_name[128];
+    int cust_ch_mixer_cfg[128], len = 0;
+    int ip_channel_cnt = audio_channel_count_from_out_mask(out->channel_mask);
+    int pcm_device_id = platform_get_pcm_device_id(out->usecase, PCM_PLAYBACK);
+    int op_channel_cnt= 2;
+    int i, j, err;
+
+    ALOGV("%s", __func__);
+
+    if (audio_extn_custom_stereo_feature_enabled) {
+        if (!out->started) {
+        out->set_dual_mono = true;
+        goto exit;
+        }
+
+        ALOGD("%s: i/p channel count %d, o/p channel count %d, pcm id %d", __func__,
+               ip_channel_cnt, op_channel_cnt, pcm_device_id);
+
+        snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+                 "Audio Stream %d Channel Mix Cfg", pcm_device_id);
+        ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+        if (!ctl) {
+            ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
+            __func__, mixer_ctl_name);
+            goto exit;
+        }
+
+        /* Output channel count corresponds to backend configuration channels.
+         * Input channel count corresponds to ASM session channels.
+         * Set params is called with channels that need to be selected from
+         * input to generate output.
+         * ex: "8,2" to downmix from 8 to 2 i.e. to downmix from 8 to 2,
+         *
+         * This mixer control takes values in the following sequence:
+         * - input channel count(m)
+         * - output channel count(n)
+         * - weight coeff for [out ch#1, in ch#1]
+         * ....
+         * - weight coeff for [out ch#1, in ch#m]
+         *
+         * - weight coeff for [out ch#2, in ch#1]
+         * ....
+         * - weight coeff for [out ch#2, in ch#m]
+         *
+         * - weight coeff for [out ch#n, in ch#1]
+         * ....
+         * - weight coeff for [out ch#n, in ch#m]
+         *
+         * To get dualmono ouptu weightage coeff is calculated as Unity gain
+         * divided by number of input channels.
+         */
+        cust_ch_mixer_cfg[len++] = ip_channel_cnt;
+        cust_ch_mixer_cfg[len++] = op_channel_cnt;
+        for (i = 0; i < op_channel_cnt; i++) {
+             for (j = 0; j < ip_channel_cnt; j++) {
+                  cust_ch_mixer_cfg[len++] = Q14_GAIN_UNITY/ip_channel_cnt;
+             }
+        }
+
+        err = mixer_ctl_set_array(ctl, cust_ch_mixer_cfg, len);
+        if (err)
+            ALOGE("%s: ERROR. Mixer ctl set failed", __func__);
+
+    }
+exit:
+    return;
+}
+//END: CUSTOM_STEREO =============================================================================
+// START: A2DP_OFFLOAD ===================================================================
+#ifdef __LP64__
+#define A2DP_OFFLOAD_LIB_PATH "/vendor/lib64/liba2dpoffload.so"
+#else
+#define A2DP_OFFLOAD_LIB_PATH "/vendor/lib/liba2dpoffload.so"
+#endif
+
+static void *a2dp_lib_handle = NULL;
+
+typedef void (*a2dp_init_t)(void *, a2dp_offload_init_config_t *);
+static a2dp_init_t a2dp_init;
+
+typedef int (*a2dp_start_playback_t)();
+static a2dp_start_playback_t a2dp_start_playback;
+
+typedef int (*a2dp_stop_playback_t)();
+static a2dp_stop_playback_t a2dp_stop_playback;
+
+typedef int (*a2dp_set_parameters_t)(struct str_parms *,
+                                     bool *);
+static a2dp_set_parameters_t a2dp_set_parameters;
+
+typedef int (*a2dp_get_parameters_t)(struct str_parms *,
+                                   struct str_parms *);
+static a2dp_get_parameters_t a2dp_get_parameters;
+
+typedef bool (*a2dp_is_force_device_switch_t)();
+static a2dp_is_force_device_switch_t a2dp_is_force_device_switch;
+
+typedef void (*a2dp_set_handoff_mode_t)(bool);
+static a2dp_set_handoff_mode_t a2dp_set_handoff_mode;
+
+typedef void (*a2dp_get_enc_sample_rate_t)(int *);
+static a2dp_get_enc_sample_rate_t a2dp_get_enc_sample_rate;
+
+typedef void (*a2dp_get_dec_sample_rate_t)(int *);
+static a2dp_get_dec_sample_rate_t a2dp_get_dec_sample_rate;
+
+typedef uint32_t (*a2dp_get_encoder_latency_t)();
+static a2dp_get_encoder_latency_t a2dp_get_encoder_latency;
+
+typedef bool (*a2dp_sink_is_ready_t)();
+static a2dp_sink_is_ready_t a2dp_sink_is_ready;
+
+typedef bool (*a2dp_source_is_ready_t)();
+static a2dp_source_is_ready_t a2dp_source_is_ready;
+
+typedef bool (*a2dp_source_is_suspended_t)();
+static a2dp_source_is_suspended_t a2dp_source_is_suspended;
+
+typedef int (*a2dp_start_capture_t)();
+static a2dp_start_capture_t a2dp_start_capture;
+
+typedef int (*a2dp_stop_capture_t)();
+static a2dp_stop_capture_t a2dp_stop_capture;
+
+int a2dp_offload_feature_init(bool is_feature_enabled)
+{
+    ALOGD("%s: Called with feature %s", __func__,
+                  is_feature_enabled ? "Enabled" : "NOT Enabled");
+    if (is_feature_enabled) {
+        // dlopen lib
+        a2dp_lib_handle = dlopen(A2DP_OFFLOAD_LIB_PATH, RTLD_NOW);
+
+        if (!a2dp_lib_handle) {
+            ALOGE("%s: dlopen failed", __func__);
+            goto feature_disabled;
+        }
+
+        if (!(a2dp_init = (a2dp_init_t)dlsym(a2dp_lib_handle, "a2dp_init")) ||
+            !(a2dp_start_playback =
+                 (a2dp_start_playback_t)dlsym(a2dp_lib_handle, "a2dp_start_playback")) ||
+            !(a2dp_stop_playback =
+                 (a2dp_stop_playback_t)dlsym(a2dp_lib_handle, "a2dp_stop_playback")) ||
+            !(a2dp_set_parameters =
+                 (a2dp_set_parameters_t)dlsym(a2dp_lib_handle, "a2dp_set_parameters")) ||
+            !(a2dp_get_parameters =
+                 (a2dp_get_parameters_t)dlsym(a2dp_lib_handle, "a2dp_get_parameters")) ||
+            !(a2dp_is_force_device_switch =
+                 (a2dp_is_force_device_switch_t)dlsym(
+                                    a2dp_lib_handle, "a2dp_is_force_device_switch")) ||
+            !(a2dp_set_handoff_mode =
+                 (a2dp_set_handoff_mode_t)dlsym(
+                                          a2dp_lib_handle, "a2dp_set_handoff_mode")) ||
+            !(a2dp_get_enc_sample_rate =
+                 (a2dp_get_enc_sample_rate_t)dlsym(
+                                       a2dp_lib_handle, "a2dp_get_enc_sample_rate")) ||
+            !(a2dp_get_dec_sample_rate =
+                 (a2dp_get_dec_sample_rate_t)dlsym(
+                                       a2dp_lib_handle, "a2dp_get_dec_sample_rate")) ||
+            !(a2dp_get_encoder_latency =
+                 (a2dp_get_encoder_latency_t)dlsym(
+                                       a2dp_lib_handle, "a2dp_get_encoder_latency")) ||
+            !(a2dp_sink_is_ready =
+                 (a2dp_sink_is_ready_t)dlsym(a2dp_lib_handle, "a2dp_sink_is_ready")) ||
+            !(a2dp_source_is_ready =
+                 (a2dp_source_is_ready_t)dlsym(a2dp_lib_handle, "a2dp_source_is_ready")) ||
+            !(a2dp_source_is_suspended =
+                 (a2dp_source_is_suspended_t)dlsym(
+                                       a2dp_lib_handle, "a2dp_source_is_suspended")) ||
+            !(a2dp_start_capture =
+                 (a2dp_start_capture_t)dlsym(a2dp_lib_handle, "a2dp_start_capture")) ||
+            !(a2dp_stop_capture =
+                 (a2dp_stop_capture_t)dlsym(a2dp_lib_handle, "a2dp_stop_capture"))) {
+            ALOGE("%s: dlsym failed", __func__);
+            goto feature_disabled;
+        }
+        ALOGD("%s:: ---- Feature A2DP_OFFLOAD is Enabled ----", __func__);
+        return 0;
+    }
+
+feature_disabled:
+    if (a2dp_lib_handle) {
+        dlclose(a2dp_lib_handle);
+        a2dp_lib_handle = NULL;
+    }
+
+    a2dp_init = NULL;
+    a2dp_start_playback= NULL;
+    a2dp_stop_playback = NULL;
+    a2dp_set_parameters = NULL;
+    a2dp_get_parameters = NULL;
+    a2dp_is_force_device_switch = NULL;
+    a2dp_set_handoff_mode = NULL;
+    a2dp_get_enc_sample_rate = NULL;
+    a2dp_get_dec_sample_rate = NULL;
+    a2dp_get_encoder_latency = NULL;
+    a2dp_sink_is_ready = NULL;
+    a2dp_source_is_ready = NULL;
+    a2dp_source_is_suspended = NULL;
+    a2dp_start_capture = NULL;
+    a2dp_stop_capture = NULL;
+
+    ALOGW(":: %s: ---- Feature A2DP_OFFLOAD is disabled ----", __func__);
+    return -ENOSYS;
+}
+
+void audio_extn_a2dp_init(void *adev)
+{
+    if (a2dp_init) {
+        a2dp_offload_init_config_t *a2dp_init_config = NULL;
+        a2dp_init_config->fp_platform_get_pcm_device_id = platform_get_pcm_device_id;
+        a2dp_init_config->fp_check_a2dp_restore = check_a2dp_restore;
+
+        a2dp_init(adev, a2dp_init_config);
+    }
+}
+
+int audio_extn_a2dp_start_playback()
+{
+    return (a2dp_start_playback ? a2dp_start_playback() : 0);
+}
+
+int audio_extn_a2dp_stop_playback()
+{
+    return (a2dp_stop_playback ? a2dp_stop_playback() : 0);
+}
+
+int audio_extn_a2dp_set_parameters(struct str_parms *parms,
+                                   bool *reconfig)
+{
+    return (a2dp_set_parameters ?
+                    a2dp_set_parameters(parms, reconfig) : 0);
+}
+
+int audio_extn_a2dp_get_parameters(struct str_parms *query,
+                                   struct str_parms *reply)
+{
+    return (a2dp_get_parameters ?
+                    a2dp_get_parameters(query, reply) : 0);
+}
+
+bool audio_extn_a2dp_is_force_device_switch()
+{
+    return (a2dp_is_force_device_switch ?
+                a2dp_is_force_device_switch() : false);
+}
+
+void audio_extn_a2dp_set_handoff_mode(bool is_on)
+{
+    if (a2dp_set_handoff_mode)
+        a2dp_set_handoff_mode(is_on);
+}
+
+void audio_extn_a2dp_get_enc_sample_rate(int *sample_rate)
+{
+    if (a2dp_get_enc_sample_rate)
+        a2dp_get_enc_sample_rate(sample_rate);
+}
+
+void audio_extn_a2dp_get_dec_sample_rate(int *sample_rate)
+{
+    if (a2dp_get_dec_sample_rate)
+        a2dp_get_dec_sample_rate(sample_rate);
+}
+
+uint32_t audio_extn_a2dp_get_encoder_latency()
+{
+    return (a2dp_get_encoder_latency ?
+                a2dp_get_encoder_latency() : 0);
+}
+
+bool audio_extn_a2dp_sink_is_ready()
+{
+    return (a2dp_sink_is_ready ?
+                a2dp_sink_is_ready() : false);
+}
+
+bool audio_extn_a2dp_source_is_ready()
+{
+    return (a2dp_source_is_ready ?
+                a2dp_source_is_ready() : false);
+}
+
+bool audio_extn_a2dp_source_is_suspended()
+{
+    return (a2dp_source_is_suspended ?
+                a2dp_source_is_suspended() : false);
+}
+
+int audio_extn_a2dp_start_capture()
+{
+    return (a2dp_start_capture ? a2dp_start_capture() : 0);
+}
+
+int audio_extn_a2dp_stop_capture()
+{
+    return (a2dp_stop_capture ? a2dp_stop_capture() : 0);
+}
+
+// END: A2DP_OFFLOAD =====================================================================
+void audio_extn_feature_init()
+{
+    for(int index = 0; index < VOICE_START; index++)
+    {
+        bool enable = audio_feature_manager_is_feature_enabled(index);
+        switch (index) {
+            case SND_MONITOR:
+                snd_mon_feature_init(enable);
+                break;
+            case COMPRESS_CAPTURE:
+                compr_cap_feature_init(enable);
+                break;
+            case DSM_FEEDBACK:
+                dsm_feedback_feature_init(enable);
+                break;
+            case SSREC:
+                ssrec_feature_init(enable);
+                break;
+            case SOURCE_TRACK:
+                src_trkn_feature_init(enable);
+            case HDMI_EDID:
+                hdmi_edid_feature_init(enable);
+                break;
+            case KEEP_ALIVE:
+                keep_alive_feature_init(enable);
+                break;
+            case HIFI_AUDIO:
+                hifi_audio_feature_init(enable);
+                break;
+            case RECEIVER_AIDED_STEREO:
+                ras_feature_init(enable);
+                break;
+            case KPI_OPTIMIZE:
+                kpi_optimize_feature_init(enable);
+            case USB_OFFLOAD:
+                usb_offload_feature_init(enable);
+                break;
+            case USB_OFFLOAD_BURST_MODE:
+                usb_offload_burst_mode_feature_init(enable);
+                break;
+            case USB_OFFLOAD_SIDETONE_VOLM:
+                usb_offload_sidetone_volume_feature_init(enable);
+                break;
+            case A2DP_OFFLOAD:
+                a2dp_offload_feature_init(enable);
+                break;
+            case COMPRESS_METADATA_NEEDED:
+                compress_meta_data_feature_init(enable);
+                break;
+            case VBAT:
+                vbat_feature_init(enable);
+                break;
+            case DISPLAY_PORT:
+                display_port_feature_init(enable);
+                break;
+            case FLUENCE:
+                fluence_feature_init(enable);
+                break;
+             case CUSTOM_STEREO:
+                custom_stereo_feature_init(enable);
+                break;
+            case ANC_HEADSET:
+                anc_headset_feature_init(enable);
+                break;
+            default:
+                break;
+        }
+    }
+}
+
+void audio_extn_set_parameters(struct audio_device *adev,
+                               struct str_parms *parms)
+{
+   bool a2dp_reconfig = false;
+
+   audio_extn_set_aanc_noise_level(adev, parms);
+   audio_extn_set_anc_parameters(adev, parms);
+   audio_extn_set_fluence_parameters(adev, parms);
+   audio_extn_set_afe_proxy_parameters(adev, parms);
+   audio_extn_fm_set_parameters(adev, parms);
+   audio_extn_sound_trigger_set_parameters(adev, parms);
+   audio_extn_listen_set_parameters(adev, parms);
+   audio_extn_ssr_set_parameters(adev, parms);
+   audio_extn_hfp_set_parameters(adev, parms);
+   audio_extn_dts_eagle_set_parameters(adev, parms);
+   audio_extn_a2dp_set_parameters(parms, &a2dp_reconfig);
+   audio_extn_ddp_set_parameters(adev, parms);
+   audio_extn_ds2_set_parameters(adev, parms);
+   audio_extn_customstereo_set_parameters(adev, parms);
+   audio_extn_hpx_set_parameters(adev, parms);
+   audio_extn_pm_set_parameters(parms);
+   audio_extn_source_track_set_parameters(adev, parms);
+   audio_extn_fbsp_set_parameters(parms);
+   audio_extn_keep_alive_set_parameters(adev, parms);
+   audio_extn_passthru_set_parameters(adev, parms);
+   audio_extn_ext_disp_set_parameters(adev, parms);
+   audio_extn_qaf_set_parameters(adev, parms);
+   if (adev->offload_effects_set_parameters != NULL)
+       adev->offload_effects_set_parameters(parms);
+   audio_extn_set_aptx_dec_bt_addr(adev, parms);
+   audio_extn_ffv_set_parameters(adev, parms);
+   audio_extn_ext_hw_plugin_set_parameters(adev->ext_hw_plugin, parms);
+}
+
+void audio_extn_get_parameters(const struct audio_device *adev,
+                              struct str_parms *query,
+                              struct str_parms *reply)
+{
+    char *kv_pairs = NULL;
+    audio_extn_get_afe_proxy_parameters(adev, query, reply);
+    audio_extn_get_fluence_parameters(adev, query, reply);
+    audio_extn_ssr_get_parameters(adev, query, reply);
+    get_active_offload_usecases(adev, query, reply);
+    audio_extn_dts_eagle_get_parameters(adev, query, reply);
+    audio_extn_hpx_get_parameters(query, reply);
+    audio_extn_source_track_get_parameters(adev, query, reply);
+    audio_extn_fbsp_get_parameters(query, reply);
+    audio_extn_sound_trigger_get_parameters(adev, query, reply);
+    audio_extn_fm_get_parameters(query, reply);
+    if (adev->offload_effects_get_parameters != NULL)
+        adev->offload_effects_get_parameters(query, reply);
+    audio_extn_ext_hw_plugin_get_parameters(adev->ext_hw_plugin, query, reply);
+
+    kv_pairs = str_parms_to_str(reply);
+    ALOGD_IF(kv_pairs != NULL, "%s: returns %s", __func__, kv_pairs);
+    free(kv_pairs);
+}
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index ce04d85..0c6bee5 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -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
@@ -40,15 +40,15 @@
 
 #include <cutils/str_parms.h>
 #include "adsp_hdlr.h"
+#include "audio_hidl.h"
 #include "ip_hdlr_intf.h"
 #include "battery_listener.h"
+#include "platform_api.h"
+#include "edid.h"
+
 
 #define AUDIO_PARAMETER_DUAL_MONO  "dual_mono"
 
-#ifndef AFE_PROXY_ENABLED
-#define AUDIO_DEVICE_OUT_PROXY 0x40000
-#endif
-
 #ifndef AUDIO_DEVICE_IN_PROXY
 #define AUDIO_DEVICE_IN_PROXY (AUDIO_DEVICE_BIT_IN | 0x1000000)
 #endif
@@ -65,6 +65,8 @@
 #define AUDIO_DEVICE_OUT_FM_TX 0x8000000
 #endif
 
+#if 0
+// these formats should have been enabled by default now
 #ifndef FLAC_OFFLOAD_ENABLED
 #define AUDIO_FORMAT_FLAC 0x1B000000UL
 #endif
@@ -91,6 +93,7 @@
 #define AUDIO_FORMAT_AAC_ADTS_HE_V2  (AUDIO_FORMAT_AAC_ADTS |\
                                       AUDIO_FORMAT_AAC_SUB_HE_V2)
 #endif
+#endif
 
 #ifndef AUDIO_FORMAT_AAC_LATM
 #define AUDIO_FORMAT_AAC_LATM 0x80000000UL
@@ -130,12 +133,8 @@
 #define AUDIO_OUTPUT_FLAG_INTERACTIVE 0x4000000
 #endif
 
-#ifndef COMPRESS_METADATA_NEEDED
-#define audio_extn_parse_compress_metadata(out, parms) (0)
-#else
 int audio_extn_parse_compress_metadata(struct stream_out *out,
                                        struct str_parms *parms);
-#endif
 
 #ifdef AUDIO_EXTN_FORMATS_ENABLED
 #define AUDIO_OUTPUT_BIT_WIDTH ((config->offload_info.bit_width == 32) ? 24\
@@ -151,6 +150,107 @@
 #endif
 
 #define MAX_LENGTH_MIXER_CONTROL_IN_INT                  (128)
+#define HW_INFO_ARRAY_MAX_SIZE 32
+
+struct snd_card_split {
+    char device[HW_INFO_ARRAY_MAX_SIZE];
+    char snd_card[HW_INFO_ARRAY_MAX_SIZE];
+    char form_factor[HW_INFO_ARRAY_MAX_SIZE];
+};
+
+struct snd_card_split *audio_extn_get_snd_card_split();
+
+// -- function pointers needed for audio extn
+typedef void (*fp_platform_make_cal_cfg_t)(acdb_audio_cal_cfg_t *, int, int,
+                                         int, int, int, uint32_t, uint16_t,
+                                         uint32_t, bool);
+typedef int (*fp_platform_send_audio_cal_t)(void *, acdb_audio_cal_cfg_t *,
+                                            void *, int, bool);
+typedef int (*fp_platform_get_audio_cal_t)(void *, acdb_audio_cal_cfg_t *,
+                                           void *, int *, bool);
+typedef int (*fp_platform_store_audio_cal_t)(void *, acdb_audio_cal_cfg_t *,
+                                             void *, int);
+typedef int (*fp_platform_retrieve_audio_cal_t)(void *, acdb_audio_cal_cfg_t *,
+                                             void *, int *);
+
+typedef struct gef_init_config {
+    fp_platform_make_cal_cfg_t         fp_platform_make_cal_cfg;
+    fp_platform_send_audio_cal_t       fp_platform_send_audio_cal;
+    fp_platform_get_audio_cal_t        fp_platform_get_audio_cal;
+    fp_platform_store_audio_cal_t      fp_platform_store_audio_cal;
+    fp_platform_retrieve_audio_cal_t   fp_platform_retrieve_audio_cal;
+} gef_init_config_t;
+
+typedef int (*fp_read_line_from_file_t)(const char *, char *, size_t);
+typedef struct audio_usecase *(*fp_get_usecase_from_list_t)(const struct audio_device *,
+                                            audio_usecase_t);
+typedef int (*fp_enable_disable_snd_device_t)(struct audio_device *, snd_device_t);
+typedef int (*fp_enable_disable_audio_route_t)(struct audio_device *, struct audio_usecase *);
+typedef int (*fp_platform_set_snd_device_backend_t)(snd_device_t, const char *,
+                                    const char *);
+typedef int (*fp_platform_get_snd_device_name_extn_t)(void *platform, snd_device_t snd_device,
+                                      char *device_name);
+typedef int (*fp_platform_get_default_app_type_v2_t)(void *, usecase_type_t);
+typedef int (*fp_platform_send_audio_calibration_t)(void *, struct audio_usecase *,
+                                                   int, int);
+typedef int (*fp_platform_get_pcm_device_id_t)(audio_usecase_t, int);
+typedef const char *(*fp_platform_get_snd_device_name_t)(snd_device_t);
+typedef int (*fp_platform_spkr_prot_is_wsa_analog_mode_t)(void *);
+typedef int (*fp_platform_get_snd_device_t)(snd_device_t);
+typedef bool(*fp_platform_check_and_set_codec_backend_cfg_t)(struct audio_device*,
+                                      struct audio_usecase *, snd_device_t);
+
+typedef struct snd_card_split *(*fp_audio_extn_get_snd_card_split_t)();
+typedef bool (*fp_audio_extn_is_vbat_enabled_t)(void);
+
+struct spkr_prot_init_config {
+    fp_read_line_from_file_t                       fp_read_line_from_file;
+    fp_get_usecase_from_list_t                     fp_get_usecase_from_list;
+    fp_enable_disable_snd_device_t                 fp_disable_snd_device;
+    fp_enable_disable_snd_device_t                 fp_enable_snd_device;
+    fp_enable_disable_audio_route_t                fp_disable_audio_route;
+    fp_enable_disable_audio_route_t                fp_enable_audio_route;
+    fp_platform_set_snd_device_backend_t           fp_platform_set_snd_device_backend;
+    fp_platform_get_snd_device_name_extn_t         fp_platform_get_snd_device_name_extn;
+    fp_platform_get_default_app_type_v2_t          fp_platform_get_default_app_type_v2;
+    fp_platform_send_audio_calibration_t           fp_platform_send_audio_calibration;
+    fp_platform_get_pcm_device_id_t                fp_platform_get_pcm_device_id;
+    fp_platform_get_snd_device_name_t              fp_platform_get_snd_device_name;
+    fp_platform_spkr_prot_is_wsa_analog_mode_t     fp_platform_spkr_prot_is_wsa_analog_mode;
+    fp_platform_get_snd_device_t                   fp_platform_get_vi_feedback_snd_device;
+    fp_platform_get_snd_device_t                   fp_platform_get_spkr_prot_snd_device;
+    fp_platform_check_and_set_codec_backend_cfg_t  fp_platform_check_and_set_codec_backend_cfg;
+    fp_audio_extn_get_snd_card_split_t             fp_audio_extn_get_snd_card_split;
+    fp_audio_extn_is_vbat_enabled_t                fp_audio_extn_is_vbat_enabled;
+};
+
+typedef struct spkr_prot_init_config spkr_prot_init_config_t;
+
+// call at adev init
+void audio_extn_init(struct audio_device *adev);
+void audio_extn_feature_init();
+//START: SND_MONITOR_FEATURE ===========================================
+void snd_mon_feature_init (bool is_feature_enabled);
+typedef void (* snd_mon_cb)(void * stream, struct str_parms * parms);
+
+int audio_extn_snd_mon_init();
+int audio_extn_snd_mon_deinit();
+int audio_extn_snd_mon_register_listener(void *stream, snd_mon_cb cb);
+int audio_extn_snd_mon_unregister_listener(void *stream);
+//END: SND_MONITOR_FEATURE   ===========================================
+
+//START: EXTN_QDSP_PLUGIN    ===========================================
+
+void audio_extn_qdsp_init(void *platform);
+void audio_extn_qdsp_deinit();
+bool audio_extn_qdsp_set_state(struct audio_device *adev, int stream_type,
+                             float vol, bool active);
+void audio_extn_qdsp_set_device(struct audio_usecase *usecase);
+void audio_extn_qdsp_set_parameters(struct audio_device *adev,
+                                  struct str_parms *parms);
+bool audio_extn_qdsp_supported_usb();
+
+//END: EXTN_QDSP_PLUGIN      ===========================================
 
 void audio_extn_set_parameters(struct audio_device *adev,
                                struct str_parms *parms);
@@ -159,87 +259,35 @@
                                struct str_parms *query,
                                struct str_parms *reply);
 
-#ifndef ANC_HEADSET_ENABLED
-#define audio_extn_get_anc_enabled()                     (0)
-#define audio_extn_should_use_fb_anc()                   (0)
-#define audio_extn_should_use_handset_anc(in_channels)   (0)
-#define audio_extn_set_aanc_noise_level(adev, parms)     (0)
-#else
+
 bool audio_extn_get_anc_enabled(void);
 bool audio_extn_should_use_fb_anc(void);
 bool audio_extn_should_use_handset_anc(int in_channels);
 void audio_extn_set_aanc_noise_level(struct audio_device *adev,
                                      struct str_parms *parms);
-#endif
 
-#ifndef VBAT_MONITOR_ENABLED
-#define audio_extn_is_vbat_enabled()                     (0)
-#define audio_extn_can_use_vbat()                        (0)
-#define audio_extn_is_bcl_enabled()                     (0)
-#define audio_extn_can_use_bcl()                        (0)
-#else
 bool audio_extn_is_vbat_enabled(void);
 bool audio_extn_can_use_vbat(void);
 bool audio_extn_is_bcl_enabled(void);
 bool audio_extn_can_use_bcl(void);
-#endif
 
-#ifndef RAS_ENABLED
-#define audio_extn_is_ras_enabled()                      (0)
-#define audio_extn_can_use_ras()                         (0)
-#else
+void ras_feature_init(bool is_feature_enabled);
 bool audio_extn_is_ras_enabled(void);
 bool audio_extn_can_use_ras(void);
-#endif
 
-#ifndef HIFI_AUDIO_ENABLED
-#define audio_extn_is_hifi_audio_enabled()               (0)
-#define audio_extn_is_hifi_audio_supported()             (0)
-#else
+
+bool audio_extn_is_hifi_audio_enabled(void);
 bool audio_extn_is_hifi_audio_enabled(void);
 bool audio_extn_is_hifi_audio_supported(void);
-#endif
 
-#ifndef FLUENCE_ENABLED
-#define audio_extn_set_fluence_parameters(adev, parms) (0)
-#define audio_extn_get_fluence_parameters(adev, query, reply) (0)
-#else
-void audio_extn_set_fluence_parameters(struct audio_device *adev,
-                                           struct str_parms *parms);
-int audio_extn_get_fluence_parameters(const struct audio_device *adev,
-                  struct str_parms *query, struct str_parms *reply);
-#endif
-
-#ifndef AFE_PROXY_ENABLED
-#define audio_extn_set_afe_proxy_channel_mixer(adev,channel_count)     (0)
-#define audio_extn_read_afe_proxy_channel_masks(out)                   (0)
-#define audio_extn_get_afe_proxy_channel_count()                       (0)
-#else
+//START: AFE_PROXY_FEATURE
 int32_t audio_extn_set_afe_proxy_channel_mixer(struct audio_device *adev,
-                                                    int channel_count);
+                                               int channel_count);
 int32_t audio_extn_read_afe_proxy_channel_masks(struct stream_out *out);
 int32_t audio_extn_get_afe_proxy_channel_count();
+//END: AFE_PROXY_FEATURE
 
-#endif
-
-#ifndef USB_HEADSET_ENABLED
-#define audio_extn_usb_init(adev)                                      (0)
-#define audio_extn_usb_deinit()                                        (0)
-#define audio_extn_usb_add_device(device, card)                        (0)
-#define audio_extn_usb_remove_device(device, card)                     (0)
-#define audio_extn_usb_is_config_supported(bit_width, sample_rate, ch, pb) \
-                        (*bit_width=0, *sample_rate=0, *ch=0, 0)
-#define audio_extn_usb_enable_sidetone(device, enable)                 (0)
-#define audio_extn_usb_set_sidetone_gain(parms, value, len)            (0)
-#define audio_extn_usb_is_capture_supported()                          (0)
-#define audio_extn_usb_get_max_channels(p)                             (0)
-#define audio_extn_usb_get_max_bit_width(p)                            (0)
-#define audio_extn_usb_get_sup_sample_rates(t, s, l)                   (0)
-#define audio_extn_usb_is_tunnel_supported()                           (0)
-#define audio_extn_usb_alive(adev)                                     (false)
-#define audio_extn_usb_connected(parms)                                (0)
-#undef USB_BURST_MODE_ENABLED
-#else
+/// ---- USB feature ---------------------------------------------------------------
 void audio_extn_usb_init(void *adev);
 void audio_extn_usb_deinit();
 void audio_extn_usb_add_device(audio_devices_t device, int card);
@@ -249,26 +297,15 @@
                                         unsigned int *ch,
                                         bool is_playback);
 int audio_extn_usb_enable_sidetone(int device, bool enable);
-int audio_extn_usb_set_sidetone_gain(struct str_parms *parms,
+void audio_extn_usb_set_sidetone_gain(struct str_parms *parms,
                                      char *value, int len);
 bool audio_extn_usb_is_capture_supported();
 int audio_extn_usb_get_max_channels(bool playback);
 int audio_extn_usb_get_max_bit_width(bool playback);
-int audio_extn_usb_get_sup_sample_rates(int type, uint32_t *sr, uint32_t l);
+int audio_extn_usb_get_sup_sample_rates(bool type, uint32_t *sr, uint32_t l);
 bool audio_extn_usb_is_tunnel_supported();
 bool audio_extn_usb_alive(int card);
 bool audio_extn_usb_connected(struct str_parms *parms);
-#endif
-
-#ifndef USB_BURST_MODE_ENABLED
-#define audio_extn_usb_find_service_interval(m, p)                     (0)
-#define audio_extn_usb_altset_for_service_interval(p, si, bw, sr, ch)  (-1)
-#define audio_extn_usb_set_service_interval(p, si, recfg)              (-1)
-#define audio_extn_usb_get_service_interval(p, si)                     (-1)
-#define audio_extn_usb_check_and_set_svc_int(uc,ss)                    (0)
-#define audio_extn_usb_is_reconfig_req()                               (0)
-#define audio_extn_usb_set_reconfig(isreq)                             (0)
-#else
 unsigned long audio_extn_usb_find_service_interval(bool min, bool playback);
 int audio_extn_usb_altset_for_service_interval(bool is_playback,
                                                unsigned long service_interval,
@@ -284,28 +321,17 @@
                                          bool starting_output_stream);
 bool audio_extn_usb_is_reconfig_req();
 void audio_extn_usb_set_reconfig(bool is_required);
-#endif
+bool audio_extn_usb_is_sidetone_volume_enabled();
+//------------------------------------------------------------------------------------
 
-#ifndef SPLIT_A2DP_ENABLED
-#define audio_extn_a2dp_init(adev)                       (0)
-#define audio_extn_a2dp_start_playback()                 (0)
-#define audio_extn_a2dp_stop_playback()                  (0)
-#define audio_extn_a2dp_set_parameters(parms)            (0)
-#define audio_extn_a2dp_is_force_device_switch()         (0)
-#define audio_extn_a2dp_set_handoff_mode(is_on)          (0)
-#define audio_extn_a2dp_get_enc_sample_rate(sample_rate) (0)
-#define audio_extn_a2dp_get_dec_sample_rate(sample_rate) (0)
-#define audio_extn_a2dp_get_encoder_latency()            (0)
-#define audio_extn_a2dp_sink_is_ready()                  (0)
-#define audio_extn_a2dp_source_is_ready()                (0)
-#define audio_extn_a2dp_source_is_suspended()            (0)
-#define audio_extn_a2dp_start_capture()                  (0)
-#define audio_extn_a2dp_stop_capture()                   (0)
-#else
+// START: A2DP_OFFLOAD FEATURE ==================================================
+int a2dp_offload_feature_init(bool is_feature_enabled);
 void audio_extn_a2dp_init(void *adev);
 int audio_extn_a2dp_start_playback();
 int audio_extn_a2dp_stop_playback();
-void audio_extn_a2dp_set_parameters(struct str_parms *parms);
+int audio_extn_a2dp_set_parameters(struct str_parms *parms, bool *reconfig);
+int audio_extn_a2dp_get_parameters(struct str_parms *query,
+                                   struct str_parms *reply);
 bool audio_extn_a2dp_is_force_device_switch();
 void audio_extn_a2dp_set_handoff_mode(bool is_on);
 void audio_extn_a2dp_get_enc_sample_rate(int *sample_rate);
@@ -316,20 +342,18 @@
 bool audio_extn_a2dp_source_is_suspended();
 int audio_extn_a2dp_start_capture();
 int audio_extn_a2dp_stop_capture();
-#endif
 
-#ifndef SSR_ENABLED
-#define audio_extn_ssr_check_usecase(in)                                  (0)
-#define audio_extn_ssr_set_usecase(in, config, channel_mask_updated)      (0)
-#define audio_extn_ssr_init(in, num_out_chan)                             (0)
-#define audio_extn_ssr_deinit()                                           (0)
-#define audio_extn_ssr_update_enabled()                                   (0)
-#define audio_extn_ssr_get_enabled()                                      (0)
-#define audio_extn_ssr_read(stream, buffer, bytes)                        (0)
-#define audio_extn_ssr_set_parameters(adev, parms)                        (0)
-#define audio_extn_ssr_get_parameters(adev, parms, reply)                 (0)
-#define audio_extn_ssr_get_stream()                                       (0)
-#else
+// --- Function pointers from audio_extn needed by A2DP_OFFLOAD
+typedef int (*fp_check_a2dp_restore_t)(struct audio_device *,
+                                       struct stream_out *, bool);
+struct a2dp_offload_init_config {
+    fp_platform_get_pcm_device_id_t fp_platform_get_pcm_device_id;
+    fp_check_a2dp_restore_t fp_check_a2dp_restore;
+};
+typedef struct a2dp_offload_init_config a2dp_offload_init_config_t;
+// END: A2DP_OFFLOAD FEATURE ====================================================
+
+//START: SSRRC_FEATURE ==========================================================
 bool audio_extn_ssr_check_usecase(struct stream_in *in);
 int audio_extn_ssr_set_usecase(struct stream_in *in,
                                          struct audio_config *config,
@@ -347,7 +371,8 @@
                                    struct str_parms *query,
                                    struct str_parms *reply);
 struct stream_in *audio_extn_ssr_get_stream();
-#endif
+//END: SSREC_FEATURE ============================================================
+
 int audio_extn_check_and_set_multichannel_usecase(struct audio_device *adev,
                                                   struct stream_in *in,
                                                   struct audio_config *config,
@@ -435,6 +460,16 @@
 #endif
 
 #ifndef AUXPCM_BT_ENABLED
+
+#define HW_INFO_ARRAY_MAX_SIZE 32
+
+void audio_extn_set_snd_card_split(const char* in_snd_card_name);
+void *audio_extn_extspk_init(struct audio_device *adev);
+void audio_extn_extspk_deinit(void *extn);
+void audio_extn_extspk_update(void* extn);
+void audio_extn_extspk_set_mode(void* extn, audio_mode_t mode);
+void audio_extn_extspk_set_voice_vol(void* extn, float vol);
+
 #define audio_extn_read_xml(adev, mixer_card, MIXER_XML_PATH, \
                             MIXER_XML_PATH_AUXPCM)               (-ENOSYS)
 #else
@@ -442,17 +477,7 @@
                             const char* mixer_xml_path,
                             const char* mixer_xml_path_auxpcm);
 #endif /* AUXPCM_BT_ENABLED */
-#ifndef SPKR_PROT_ENABLED
-#define audio_extn_spkr_prot_init(adev)       (0)
-#define audio_extn_spkr_prot_deinit()         (0)
-#define audio_extn_spkr_prot_start_processing(snd_device)    (-EINVAL)
-#define audio_extn_spkr_prot_calib_cancel(adev) (0)
-#define audio_extn_spkr_prot_stop_processing(snd_device)     (0)
-#define audio_extn_spkr_prot_is_enabled() (false)
-#define audio_extn_spkr_prot_set_parameters(parms, value, len)   (0)
-#define audio_extn_fbsp_set_parameters(parms)   (0)
-#define audio_extn_fbsp_get_parameters(query, reply)   (0)
-#else
+
 void audio_extn_spkr_prot_init(void *adev);
 int audio_extn_spkr_prot_deinit();
 int audio_extn_spkr_prot_start_processing(snd_device_t snd_device);
@@ -464,17 +489,11 @@
 int audio_extn_fbsp_set_parameters(struct str_parms *parms);
 int audio_extn_fbsp_get_parameters(struct str_parms *query,
                                    struct str_parms *reply);
-#endif
+int audio_extn_get_spkr_prot_snd_device(snd_device_t snd_device);
 
-#ifndef COMPRESS_CAPTURE_ENABLED
-#define audio_extn_compr_cap_init(in)                     (0)
-#define audio_extn_compr_cap_enabled()                    (0)
-#define audio_extn_compr_cap_format_supported(format)     (0)
-#define audio_extn_compr_cap_usecase_supported(usecase)   (0)
-#define audio_extn_compr_cap_get_buffer_size(format)      (0)
-#define audio_extn_compr_cap_read(in, buffer, bytes)      (0)
-#define audio_extn_compr_cap_deinit()                     (0)
-#else
+
+// START: COMPRESS_CAPTURE FEATURE =========================
+void compr_cap_feature_init(bool is_feature_enabled);
 void audio_extn_compr_cap_init(struct stream_in *in);
 bool audio_extn_compr_cap_enabled();
 bool audio_extn_compr_cap_format_supported(audio_format_t format);
@@ -483,7 +502,7 @@
 size_t audio_extn_compr_cap_read(struct stream_in *in,
                                         void *buffer, size_t bytes);
 void audio_extn_compr_cap_deinit();
-#endif
+// END: COMPRESS_CAPTURE FEATURE =========================
 
 #ifndef DTS_EAGLE
 #define audio_extn_dts_eagle_set_parameters(adev, parms)     (0)
@@ -620,14 +639,31 @@
 #define audio_extn_hfp_get_usecase()                    (-1)
 #define hfp_set_mic_mute(dev, state)                    (0)
 #define audio_extn_hfp_set_parameters(adev, parms)      (0)
+#define audio_extn_hfp_set_mic_mute(adev, state)        (0)
 #else
 bool audio_extn_hfp_is_active(struct audio_device *adev);
 audio_usecase_t audio_extn_hfp_get_usecase();
 int hfp_set_mic_mute(struct audio_device *dev, bool state);
 void audio_extn_hfp_set_parameters(struct audio_device *adev,
                                            struct str_parms *parms);
+int audio_extn_hfp_set_mic_mute(struct audio_device *adev, bool state);
 #endif
 
+int audio_extn_utils_send_app_type_gain(struct audio_device *adev,
+                                        int app_type,
+                                        int *gain);
+
+void audio_extn_dsm_feedback_enable(struct audio_device *adev,
+                         snd_device_t snd_device,
+                         bool benable);
+void dsm_feedback_feature_init (bool is_feature_enabled);
+
+int audio_extn_utils_send_app_type_gain(struct audio_device *adev,
+                                        int app_type,
+                                        int *gain);
+
+void audio_extn_hwdep_cal_send(int snd_card, void *acdb_handle);
+
 #ifndef DEV_ARBI_ENABLED
 #define audio_extn_dev_arbi_init()                  (0)
 #define audio_extn_dev_arbi_deinit()                (0)
@@ -687,6 +723,9 @@
 void audio_extn_utils_update_stream_app_type_cfg_for_usecase(
                                   struct audio_device *adev,
                                   struct audio_usecase *usecase);
+bool audio_extn_utils_resolve_config_file(char[]);
+int audio_extn_utils_get_platform_info(const char* snd_card_name,
+                                       char* platform_info_file);
 int audio_extn_utils_get_snd_card_num();
 int audio_extn_utils_open_snd_mixer(struct mixer **mixer_handle);
 void audio_extn_utils_close_snd_mixer(struct mixer *mixer);
@@ -755,17 +794,13 @@
 size_t audio_extn_utils_convert_format_24_8_to_8_24(void *buf, size_t bytes);
 int get_snd_codec_id(audio_format_t format);
 
-#ifndef KPI_OPTIMIZE_ENABLED
-#define audio_extn_perf_lock_init() (0)
-#define audio_extn_perf_lock_acquire(handle, duration, opts, size) (0)
-#define audio_extn_perf_lock_release(handle) (0)
-#else
+void kpi_optimize_feature_init(bool is_feature_enabled);
 int audio_extn_perf_lock_init(void);
 void audio_extn_perf_lock_acquire(int *handle, int duration,
                                  int *opts, int size);
 void audio_extn_perf_lock_release(int *handle);
 
-#endif /* KPI_OPTIMIZE_ENABLED */
+
 
 #ifndef AUDIO_EXTERNAL_HDMI_ENABLED
 #define audio_utils_set_hdmi_channel_status(out, buffer, bytes) (0)
@@ -826,14 +861,6 @@
 #define audio_extn_bt_hal_get_device(...)             NULL
 #endif
 
-#ifndef KEEP_ALIVE_ENABLED
-#define audio_extn_keep_alive_init(adev) do {} while(0)
-#define audio_extn_keep_alive_deinit() do {} while(0)
-#define audio_extn_keep_alive_start(ka_mode) do {} while(0)
-#define audio_extn_keep_alive_stop(ka_mode) do {} while(0)
-#define audio_extn_keep_alive_is_active() (false)
-#define audio_extn_keep_alive_set_parameters(adev, parms) (0)
-#else
 void audio_extn_keep_alive_init(struct audio_device *adev);
 void audio_extn_keep_alive_deinit();
 void audio_extn_keep_alive_start(ka_mode_t ka_mode);
@@ -841,7 +868,7 @@
 bool audio_extn_keep_alive_is_active();
 int audio_extn_keep_alive_set_parameters(struct audio_device *adev,
                                          struct str_parms *parms);
-#endif
+
 
 #ifndef AUDIO_GENERIC_EFFECT_FRAMEWORK_ENABLED
 
@@ -910,19 +937,6 @@
 
 #endif /* AUDIO_GENERIC_EFFECT_FRAMEWORK_ENABLED */
 
-typedef void (* snd_mon_cb)(void * stream, struct str_parms * parms);
-#ifndef SND_MONITOR_ENABLED
-#define audio_extn_snd_mon_init()           (0)
-#define audio_extn_snd_mon_deinit()         (0)
-#define audio_extn_snd_mon_register_listener(stream, cb) (0)
-#define audio_extn_snd_mon_unregister_listener(stream) (0)
-#else
-int audio_extn_snd_mon_init();
-int audio_extn_snd_mon_deinit();
-int audio_extn_snd_mon_register_listener(void *stream, snd_mon_cb cb);
-int audio_extn_snd_mon_unregister_listener(void *stream);
-#endif
-
 #ifdef COMPRESS_INPUT_ENABLED
 bool audio_extn_cin_applicable_stream(struct stream_in *in);
 bool audio_extn_cin_attached_usecase(audio_usecase_t uc_id);
@@ -946,42 +960,23 @@
 #define audio_extn_cin_configure_input_stream(in) (0)
 #endif
 
-#ifndef SOURCE_TRACKING_ENABLED
-static int __unused audio_extn_get_soundfocus_data(
-                                   const struct audio_device *adev __unused,
-                                   struct sound_focus_param *payload __unused)
-{
-    return -ENOSYS;
-}
-static int __unused audio_extn_get_sourcetrack_data(
-                                   const struct audio_device *adev __unused,
-                                   struct source_tracking_param *payload __unused)
-{
-    return -ENOSYS;
-}
-static int __unused audio_extn_set_soundfocus_data(
-                                   struct audio_device *adev __unused,
-                                   struct sound_focus_param *payload __unused)
-{
-    return -ENOSYS;
-}
-#else
+//START: SOURCE_TRACKING_FEATURE ==============================================
 int audio_extn_get_soundfocus_data(const struct audio_device *adev,
                                    struct sound_focus_param *payload);
 int audio_extn_get_sourcetrack_data(const struct audio_device *adev,
                                     struct source_tracking_param *payload);
 int audio_extn_set_soundfocus_data(struct audio_device *adev,
                                    struct sound_focus_param *payload);
-#endif
+void audio_extn_source_track_set_parameters(struct audio_device *adev,
+                                            struct str_parms *parms);
+void audio_extn_source_track_get_parameters(const struct audio_device *adev,
+                                            struct str_parms *query,
+                                            struct str_parms *reply);
+//END: SOURCE_TRACKING_FEATURE ================================================
 
-#ifndef FM_POWER_OPT
-#define audio_extn_fm_set_parameters(adev, parms) (0)
-#define audio_extn_fm_get_parameters(query, reply) (0)
-#else
 void audio_extn_fm_set_parameters(struct audio_device *adev,
                                    struct str_parms *parms);
 void audio_extn_fm_get_parameters(struct str_parms *query, struct str_parms *reply);
-#endif
 
 #ifndef APTX_DECODER_ENABLED
 #define audio_extn_aptx_dec_set_license(adev); (0)
@@ -1145,11 +1140,6 @@
 void audio_extn_ffv_append_ec_ref_dev_name(char *device_name);
 #endif
 
-#ifndef CUSTOM_STEREO_ENABLED
-#define audio_extn_send_dual_mono_mixing_coefficients(out) (0)
-#else
-void audio_extn_send_dual_mono_mixing_coefficients(struct stream_out *out);
-#endif
 int audio_extn_utils_get_license_params(const struct audio_device *adev,  struct audio_license_params *lic_params);
 
 #ifndef EXT_HW_PLUGIN_ENABLED
@@ -1176,4 +1166,20 @@
 int audio_extn_ext_hw_plugin_set_audio_gain(void *plugin,
             struct audio_usecase *usecase, uint32_t gain);
 #endif
+
+bool audio_extn_edid_is_supported_sr(edid_audio_info* info, int sr);
+bool audio_extn_edid_is_supported_bps(edid_audio_info* info, int bps);
+int audio_extn_edid_get_highest_supported_sr(edid_audio_info* info);
+bool audio_extn_edid_get_sink_caps(edid_audio_info* info, char *edid_data);
+
+bool audio_extn_is_display_port_enabled();
+
+bool audio_extn_is_fluence_enabled();
+void audio_extn_set_fluence_parameters(struct audio_device *adev,
+                                           struct str_parms *parms);
+int audio_extn_get_fluence_parameters(const struct audio_device *adev,
+                  struct str_parms *query, struct str_parms *reply);
+
+bool audio_extn_is_custom_stereo_enabled();
+void audio_extn_send_dual_mono_mixing_coefficients(struct stream_out *out);
 #endif /* AUDIO_EXTN_H */
diff --git a/hal/audio_extn/audio_feature_manager.c b/hal/audio_extn/audio_feature_manager.c
new file mode 100644
index 0000000..23de0eb
--- /dev/null
+++ b/hal/audio_extn/audio_feature_manager.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 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
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "audio_feature_manager"
+
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <cutils/properties.h>
+#include <log/log.h>
+#include <unistd.h>
+#include <vndfwk-detect.h>
+#include "audio_feature_manager.h"
+
+extern AHalValues* confValues;
+
+void audio_feature_manager_init()
+{
+    ALOGV("%s: Enter", __func__);
+    audio_extn_ahal_config_helper_init(
+                isRunningWithVendorEnhancedFramework());
+    confValues = audio_extn_get_feature_values();
+}
+
+bool audio_feature_manager_is_feature_enabled(audio_ext_feature feature)
+{
+    ALOGV("%s: Enter", __func__);
+
+#ifdef AHAL_EXT_ENABLED
+    if (!audio_extn_is_config_from_remote())
+        confValues = audio_extn_get_feature_values();
+#endif /* AHAL_EXT_ENABLED */
+
+    if (!confValues)
+        return false;
+
+    switch (feature) {
+        case SND_MONITOR:
+            return confValues->snd_monitor_enabled;
+        case COMPRESS_CAPTURE:
+            return confValues->compress_capture_enabled;
+        case SOURCE_TRACK:
+            return confValues->source_track_enabled;
+        case SSREC:
+            return confValues->ssrec_enabled;
+        case AUDIOSPHERE:
+            return confValues->audiosphere_enabled;
+        case AFE_PROXY:
+            return confValues->afe_proxy_enabled;
+        case USE_DEEP_BUFFER_AS_PRIMARY_OUTPUT:
+            return confValues->use_deep_buffer_as_primary_output;
+        case HDMI_EDID:
+            return confValues->hdmi_edid_enabled;
+        case KEEP_ALIVE:
+            return confValues->keep_alive_enabled;
+        case HIFI_AUDIO:
+            return confValues->hifi_audio_enabled;
+        case RECEIVER_AIDED_STEREO:
+            return confValues->receiver_aided_stereo;
+        case KPI_OPTIMIZE:
+            return confValues->kpi_optimize_enabled;
+        case DISPLAY_PORT:
+            return confValues->display_port_enabled;
+        case FLUENCE:
+            return confValues->fluence_enabled;
+        case CUSTOM_STEREO:
+            return confValues->custom_stereo_enabled;
+        case ANC_HEADSET:
+            return confValues->anc_headset_enabled;
+        case DSM_FEEDBACK:
+            return confValues->dsm_feedback_enabled;
+        case USB_OFFLOAD:
+            return confValues->usb_offload_enabled;
+        case USB_OFFLOAD_BURST_MODE:
+            return confValues->usb_offload_burst_mode;
+        case USB_OFFLOAD_SIDETONE_VOLM:
+            return confValues->usb_offload_sidetone_vol_enabled;
+        case A2DP_OFFLOAD:
+            return confValues->a2dp_offload_enabled;
+        case VBAT:
+            return confValues->vbat_enabled;
+        case COMPRESS_METADATA_NEEDED:
+            return confValues->compress_metadata_needed;
+        case COMPRESS_VOIP:
+            return confValues->compress_voip_enabled;
+        case DYNAMIC_ECNS:
+            return confValues->dynamic_ecns_enabled;
+        default:
+            return false;
+    }
+}
diff --git a/hal/audio_extn/audio_feature_manager.h b/hal/audio_extn/audio_feature_manager.h
new file mode 100644
index 0000000..8433db0
--- /dev/null
+++ b/hal/audio_extn/audio_feature_manager.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 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
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AUDIO_FEATURE_MANAGER_H
+#define AUDIO_FEATURE_MANAGER_H
+
+#include <ahal_config_helper.h>
+
+enum audio_ext_feature_t {
+    SND_MONITOR = 0,
+    COMPRESS_CAPTURE,
+    SOURCE_TRACK,
+    SSREC,
+    AUDIOSPHERE,
+    AFE_PROXY,
+    USE_DEEP_BUFFER_AS_PRIMARY_OUTPUT,
+    HDMI_EDID,
+    KEEP_ALIVE,
+    HIFI_AUDIO,
+    RECEIVER_AIDED_STEREO,
+    KPI_OPTIMIZE,
+    DISPLAY_PORT,
+    FLUENCE,
+    CUSTOM_STEREO,
+    ANC_HEADSET,
+    DSM_FEEDBACK,
+    USB_OFFLOAD,
+    USB_OFFLOAD_BURST_MODE,
+    USB_OFFLOAD_SIDETONE_VOLM,
+    A2DP_OFFLOAD,
+    VBAT,
+    COMPRESS_METADATA_NEEDED,
+    VOICE_START = COMPRESS_METADATA_NEEDED,
+    COMPRESS_VOIP,
+    DYNAMIC_ECNS,
+    MAX_SUPPORTED_FEATURE
+};
+
+typedef enum audio_ext_feature_t audio_ext_feature;
+
+void audio_feature_manager_init();
+bool audio_feature_manager_is_feature_enabled(audio_ext_feature feature);
+
+#endif /* AUDIO_FEATURE_MANAGER_H */
diff --git a/hal/audio_extn/audio_hidl.cpp b/hal/audio_extn/audio_hidl.cpp
new file mode 100644
index 0000000..4d549db
--- /dev/null
+++ b/hal/audio_extn/audio_hidl.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 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
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "audio_hw_hidl"
+
+#include "audio_hidl.h"
+#include <cutils/properties.h>
+#include <log/log.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/LegacySupport.h>
+
+#ifdef AHAL_EXT_ENABLED
+#include <vendor/qti/hardware/audiohalext/1.0/IAudioHalExt.h>
+using vendor::qti::hardware::audiohalext::V1_0::IAudioHalExt;
+#endif
+
+using namespace android::hardware;
+using android::OK;
+
+extern "C" {
+int audio_extn_hidl_init() {
+
+#ifdef AHAL_EXT_ENABLED
+    if (!property_get_bool("vendor.audio.hal.ext.disabled", false)) {
+        /* register audio HAL extension */
+        bool fail = registerPassthroughServiceImplementation<IAudioHalExt>()!= OK;
+        ALOGW_IF(fail, "Could not register AHAL extension");
+    }
+#endif
+
+    /* to register other hidls */
+
+    return 0;
+}
+}
+
diff --git a/hal/audio_extn/audio_hidl.h b/hal/audio_extn/audio_hidl.h
new file mode 100644
index 0000000..92eb147
--- /dev/null
+++ b/hal/audio_extn/audio_hidl.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 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
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _AUDIO_HIDL_H_
+#define _AUDIO_HIDL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+int audio_extn_hidl_init();
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _AUDIO_HIDL_H_ */
diff --git a/hal/audio_extn/cirrus_playback.c b/hal/audio_extn/cirrus_playback.c
new file mode 100644
index 0000000..f1b46d9
--- /dev/null
+++ b/hal/audio_extn/cirrus_playback.c
@@ -0,0 +1,963 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "audio_hw_cirrus_playback"
+/*#define LOG_NDEBUG 0*/
+
+#include <errno.h>
+#include <math.h>
+#include <log/log.h>
+#include <fcntl.h>
+#include "../audio_hw.h"
+#include "platform.h"
+#include "platform_api.h"
+#include <sys/stat.h>
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <dlfcn.h>
+#include <math.h>
+#include <pthread.h>
+#include <time.h>
+#include <unistd.h>
+#include <cutils/properties.h>
+#include "audio_extn.h"
+
+// - external function dependency -
+static fp_platform_get_snd_device_name_t fp_platform_get_snd_device_name;
+static fp_platform_get_pcm_device_id_t fp_platform_get_pcm_device_id;
+static fp_get_usecase_from_list_t fp_get_usecase_from_list;
+static fp_enable_disable_snd_device_t fp_disable_snd_device;
+static fp_enable_disable_snd_device_t  fp_enable_snd_device;
+static fp_enable_disable_audio_route_t fp_disable_audio_route;
+static fp_enable_disable_audio_route_t fp_enable_audio_route;
+static fp_audio_extn_get_snd_card_split_t fp_audio_extn_get_snd_card_split;
+
+struct cirrus_playback_session {
+    void *adev_handle;
+    pthread_mutex_t fb_prot_mutex;
+    pthread_t calibration_thread;
+#ifdef ENABLE_CIRRUS_DETECTION
+    pthread_t failure_detect_thread;
+#endif
+    struct pcm *pcm_rx;
+    struct pcm *pcm_tx;
+    volatile int32_t state;
+};
+
+enum cirrus_playback_state {
+    INIT = 0,
+    CALIBRATING = 1,
+    IDLE = 2,
+    PLAYBACK = 3
+};
+
+struct crus_sp_ioctl_header {
+    uint32_t size;
+    uint32_t module_id;
+    uint32_t param_id;
+    uint32_t data_length;
+    void *data;
+};
+
+/* Payload struct for getting calibration result from DSP module */
+struct cirrus_cal_result_t {
+    int32_t status_l;
+    int32_t checksum_l;
+    int32_t z_l;
+    int32_t status_r;
+    int32_t checksum_r;
+    int32_t z_r;
+};
+
+/* Payload struct for setting the RX and TX use cases */
+struct crus_rx_run_case_ctrl_t {
+    int32_t value;
+    int32_t status_l;
+    int32_t checksum_l;
+    int32_t z_l;
+    int32_t status_r;
+    int32_t checksum_r;
+    int32_t z_r;
+};
+
+#define CRUS_SP_FILE "/dev/msm_cirrus_playback"
+#define CRUS_CAL_FILE "/persist/audio/audio.cal"
+#define CRUS_TX_CONF_FILE "vendor/firmware/crus_sp_config_%s_tx.bin"
+#define CRUS_RX_CONF_FILE "vendor/firmware/crus_sp_config_%s_rx.bin"
+#define CONFIG_FILE_SIZE 128
+
+#define CRUS_SP_USECASE_MIXER   "Cirrus SP Usecase"
+#define CRUS_SP_LOAD_CONF_MIXER "Cirrus SP Load Config"
+#define CRUS_SP_FAIL_DET_MIXER  "Cirrus SP Failure Detection"
+
+#define CIRRUS_SP 0x10027053
+
+#define CRUS_MODULE_ID_TX 0x00000002
+#define CRUS_MODULE_ID_RX 0x00000001
+
+#define CRUS_PARAM_RX_SET_USECASE 0x00A1AF02
+#define CRUS_PARAM_TX_SET_USECASE 0x00A1BF0A
+
+#define CRUS_PARAM_RX_SET_CALIB 0x00A1AF03
+#define CRUS_PARAM_TX_SET_CALIB 0x00A1BF03
+
+#define CRUS_PARAM_RX_SET_EXT_CONFIG 0x00A1AF05
+#define CRUS_PARAM_TX_SET_EXT_CONFIG 0x00A1BF08
+
+#define CRUS_PARAM_RX_GET_TEMP 0x00A1AF07
+#define CRUS_PARAM_TX_GET_TEMP_CAL 0x00A1BF06
+// variables based on CSPL tuning file, max parameter length is 96 integers (384 bytes)
+#define CRUS_PARAM_TEMP_MAX_LENGTH 384
+
+#define CRUS_AFE_PARAM_ID_ENABLE 0x00010203
+
+#define FAIL_DETECT_INIT_WAIT_US 500000
+#define FAIL_DETECT_LOOP_WAIT_US 300000
+
+#define CRUS_DEFAULT_CAL_L 0x2A11
+#define CRUS_DEFAULT_CAL_R 0x29CB
+
+#define CRUS_SP_IOCTL_MAGIC 'a'
+
+#define CRUS_SP_IOCTL_GET _IOWR(CRUS_SP_IOCTL_MAGIC, 219, void *)
+#define CRUS_SP_IOCTL_SET _IOWR(CRUS_SP_IOCTL_MAGIC, 220, void *)
+#define CRUS_SP_IOCTL_GET_CALIB _IOWR(CRUS_SP_IOCTL_MAGIC, 221, void *)
+#define CRUS_SP_IOCTL_SET_CALIB _IOWR(CRUS_SP_IOCTL_MAGIC, 222, void *)
+
+
+struct pcm_config pcm_config_cirrus_rx = {
+    .channels = 8,
+    .rate = 48000,
+    .period_size = 320,
+    .period_count = 4,
+    .format = PCM_FORMAT_S32_LE,
+    .start_threshold = 0,
+    .stop_threshold = INT_MAX,
+    .avail_min = 0,
+};
+
+struct pcm_config pcm_config_cirrus_tx = {
+    .channels = 2,
+    .rate = 48000,
+    .period_size = 320,
+    .period_count = 4,
+    .format = PCM_FORMAT_S16_LE,
+    .start_threshold = 0,
+    .stop_threshold = INT_MAX,
+    .avail_min = 0,
+};
+
+static struct cirrus_playback_session handle;
+
+#ifdef CIRRUS_FACTORY_CALIBRATION
+static void *audio_extn_cirrus_calibration_thread();
+#else
+static void *audio_extn_cirrus_config_thread();
+#endif
+
+#ifdef ENABLE_CIRRUS_DETECTION
+static void *audio_extn_cirrus_failure_detect_thread();
+#endif
+
+void spkr_prot_init(void *adev, spkr_prot_init_config_t spkr_prot_init_config_val) {
+    ALOGI("%s: Initialize Cirrus Logic Playback module", __func__);
+
+    memset(&handle, 0, sizeof(handle));
+    if (!adev) {
+        ALOGE("%s: Invalid params", __func__);
+        return;
+    }
+
+    handle.adev_handle = adev;
+    handle.state = INIT;
+
+    // init function pointers
+    fp_platform_get_snd_device_name = spkr_prot_init_config_val.fp_platform_get_snd_device_name;
+    fp_platform_get_pcm_device_id = spkr_prot_init_config_val.fp_platform_get_pcm_device_id;
+    fp_get_usecase_from_list =  spkr_prot_init_config_val.fp_get_usecase_from_list;
+    fp_disable_snd_device = spkr_prot_init_config_val.fp_disable_snd_device;
+    fp_enable_snd_device = spkr_prot_init_config_val.fp_enable_snd_device;
+    fp_disable_audio_route = spkr_prot_init_config_val.fp_disable_audio_route;
+    fp_enable_audio_route = spkr_prot_init_config_val.fp_enable_audio_route;
+    fp_audio_extn_get_snd_card_split = spkr_prot_init_config_val.fp_audio_extn_get_snd_card_split;
+
+    pthread_mutex_init(&handle.fb_prot_mutex, NULL);
+
+#ifdef CIRRUS_FACTORY_CALIBRATION
+    (void)pthread_create(&handle.calibration_thread,
+                (const pthread_attr_t *) NULL,
+                audio_extn_cirrus_calibration_thread, &handle);
+#else
+    (void)pthread_create(&handle.calibration_thread,
+                (const pthread_attr_t *) NULL,
+                audio_extn_cirrus_config_thread, &handle);
+#endif
+}
+
+int spkr_prot_deinit() {
+    ALOGV("%s: Entry", __func__);
+
+#ifdef ENABLE_CIRRUS_DETECTION
+    pthread_join(handle.failure_detect_thread, NULL);
+#endif
+    pthread_join(handle.calibration_thread, NULL);
+    pthread_mutex_destroy(&handle.fb_prot_mutex);
+
+    ALOGV("%s: Exit", __func__);
+    return 0;
+}
+
+#ifdef CIRRUS_FACTORY_CALIBRATION
+static int audio_extn_cirrus_run_calibration() {
+    struct audio_device *adev = handle.adev_handle;
+    struct crus_sp_ioctl_header header;
+    struct cirrus_cal_result_t result;
+    struct mixer_ctl *ctl = NULL;
+    FILE *cal_file = NULL;
+    int ret = 0, dev_file = -1;
+    char *buffer = NULL;
+    uint32_t option = 1;
+
+    ALOGI("%s: Running speaker calibration", __func__);
+
+    dev_file = open(CRUS_SP_FILE, O_RDWR | O_NONBLOCK);
+    if (dev_file < 0) {
+        ALOGE("%s: Failed to open Cirrus Playback IOCTL (%d)",
+              __func__, dev_file);
+        ret = -EINVAL;
+        goto exit;
+    }
+
+    buffer = calloc(1, CRUS_PARAM_TEMP_MAX_LENGTH);
+    if (!buffer) {
+        ALOGE("%s: allocate memory failed", __func__);
+        ret = -ENOMEM;
+        goto exit;
+    }
+
+    cal_file = fopen(CRUS_CAL_FILE, "r");
+    if (cal_file) {
+        ret = fread(&result, sizeof(result), 1, cal_file);
+        if (ret != 1) {
+            ALOGE("%s: Cirrus SP calibration file cannot be read , read size: %lu file error: %d",
+                  __func__, (unsigned long)ret * sizeof(result), ferror(cal_file));
+            ret = -EINVAL;
+            fclose(cal_file);
+            goto exit;
+        }
+
+        fclose(cal_file);
+    } else {
+
+        ALOGV("%s: Calibrating...", __func__);
+
+        header.size = sizeof(header);
+        header.module_id = CRUS_MODULE_ID_RX;
+        header.param_id = CRUS_PARAM_RX_SET_CALIB;
+        header.data_length = sizeof(option);
+        header.data = &option;
+
+        ret = ioctl(dev_file, CRUS_SP_IOCTL_SET, &header);
+        if (ret < 0) {
+            ALOGE("%s: Cirrus SP calibration IOCTL failure (%d)",
+                  __func__, ret);
+            ret = -EINVAL;
+            goto exit;
+        }
+
+        header.size = sizeof(header);
+        header.module_id = CRUS_MODULE_ID_TX;
+        header.param_id = CRUS_PARAM_TX_SET_CALIB;
+        header.data_length = sizeof(option);
+        header.data = &option;
+
+        ret = ioctl(dev_file, CRUS_SP_IOCTL_SET, &header);
+        if (ret < 0) {
+            ALOGE("%s: Cirrus SP calibration IOCTL failure (%d)",
+                  __func__, ret);
+            ret = -EINVAL;
+            goto exit;
+        }
+
+        sleep(2);
+
+        header.size = sizeof(header);
+        header.module_id = CRUS_MODULE_ID_TX;
+        header.param_id = CRUS_PARAM_TX_GET_TEMP_CAL;
+        header.data_length = sizeof(result);
+        header.data = &result;
+
+        ret = ioctl(dev_file, CRUS_SP_IOCTL_GET, &header);
+        if (ret < 0) {
+            ALOGE("%s: Cirrus SP calibration IOCTL failure (%d)",
+                  __func__, ret);
+            ret = -EINVAL;
+            goto exit;
+        }
+
+        if (result.status_l != 1) {
+            ALOGE("%s: Left calibration failure. Please check speakers",
+                    __func__);
+            ret = -EINVAL;
+        }
+
+        if (result.status_r != 1) {
+            ALOGE("%s: Right calibration failure. Please check speakers",
+                    __func__);
+            ret = -EINVAL;
+        }
+
+        if (ret < 0)
+            goto exit;
+
+        cal_file = fopen(CRUS_CAL_FILE, "wb");
+        if (cal_file == NULL) {
+            ALOGE("%s: Cannot create Cirrus SP calibration file (%s)",
+                  __func__, strerror(errno));
+            ret = -EINVAL;
+            goto exit;
+        }
+
+        ret = fwrite(&result, sizeof(result), 1, cal_file);
+
+        if (ret != 1) {
+            ALOGE("%s: Unable to save Cirrus SP calibration data, write size %lu, file error %d",
+                  __func__, (unsigned long)ret * sizeof(result), ferror(cal_file));
+            fclose(cal_file);
+            ret = -EINVAL;
+            goto exit;
+        }
+
+        fclose(cal_file);
+
+        ALOGI("%s: Cirrus calibration file successfully written",
+              __func__);
+    }
+
+    header.size = sizeof(header);
+    header.module_id = CRUS_MODULE_ID_TX;
+    header.param_id = 0;
+    header.data_length = sizeof(result);
+    header.data = &result;
+
+    ret = ioctl(dev_file, CRUS_SP_IOCTL_SET_CALIB, &header);
+
+    if (ret < 0) {
+        ALOGE("%s: Cirrus SP calibration IOCTL failure (%d)", __func__, ret);
+        ret = -EINVAL;
+        goto exit;
+    }
+
+    ctl = mixer_get_ctl_by_name(adev->mixer,
+                    CRUS_SP_USECASE_MIXER);
+    if (!ctl) {
+        ALOGE("%s: Could not get ctl for mixer cmd - %s",
+             __func__, CRUS_SP_USECASE_MIXER);
+        ret = -EINVAL;
+        goto exit;
+    }
+
+    ret = mixer_ctl_set_value(ctl, 0, 0); // Set RX external firmware config
+    if (ret < 0) {
+        ALOGE("%s: set default usecase failed", __func__);
+        goto exit;
+    }
+
+    sleep(1);
+
+    header.size = sizeof(header);
+    header.module_id = CRUS_MODULE_ID_RX;
+    header.param_id = CRUS_PARAM_RX_GET_TEMP;
+    header.data_length = CRUS_PARAM_TEMP_MAX_LENGTH;
+    header.data = buffer;
+
+    ret = ioctl(dev_file, CRUS_SP_IOCTL_GET, &header);
+    if (ret < 0) {
+        ALOGE("%s: Cirrus SP temperature IOCTL failure (%d)", __func__, ret);
+        ret = -EINVAL;
+        goto exit;
+    }
+
+    ALOGI("%s: Cirrus SP successfully calibrated", __func__);
+
+exit:
+    if (dev_file >= 0)
+        close(dev_file);
+    free(buffer);
+    ALOGV("%s: Exit", __func__);
+
+    return ret;
+}
+
+static int audio_extn_cirrus_load_usecase_configs(void) {
+    struct audio_device *adev = handle.adev_handle;
+    struct mixer_ctl *ctl_uc = NULL, *ctl_config = NULL;
+    char *filename = NULL;
+    int ret = 0, default_uc = 0;
+    struct snd_card_split *snd_split_handle = NULL;
+
+    snd_split_handle = fp_audio_extn_get_snd_card_split();
+
+    ALOGI("%s: Loading usecase tuning configs", __func__);
+
+    ctl_uc = mixer_get_ctl_by_name(adev->mixer, CRUS_SP_USECASE_MIXER);
+    ctl_config = mixer_get_ctl_by_name(adev->mixer,
+                    CRUS_SP_LOAD_CONF_MIXER);
+    if (!ctl_uc || !ctl_config) {
+        ALOGE("%s: Could not get ctl for mixer commands", __func__);
+        ret = -EINVAL;
+        goto exit;
+    }
+
+    filename = calloc(1 , CONFIG_FILE_SIZE);
+    if (!filename) {
+        ALOGE("%s: allocate memory failed", __func__);
+        ret = -ENOMEM;
+        goto exit;
+    }
+
+    default_uc = mixer_ctl_get_value(ctl_uc, 0);
+
+    ret = mixer_ctl_set_value(ctl_uc, 0, default_uc);
+    if (ret < 0) {
+        ALOGE("%s set uscase %d failed", __func__, default_uc);
+        goto exit;
+    }
+
+    /* Load TX Tuning Config (if available) */
+    snprintf(filename, CONFIG_FILE_SIZE, CRUS_TX_CONF_FILE, snd_split_handle->form_factor);
+    if (access(filename, R_OK) == 0) {
+        ret = mixer_ctl_set_value(ctl_config, 0, 2);
+        if (ret < 0) {
+            ALOGE("%s set tx config failed", __func__);
+            goto exit;
+        }
+    } else {
+        ALOGE("%s: Tuning file not found (%s)", __func__,
+              filename);
+        ret = -EINVAL;
+        goto exit;
+    }
+    /* Load RX Tuning Config (if available) */
+    snprintf(filename, CONFIG_FILE_SIZE, CRUS_RX_CONF_FILE, snd_split_handle->form_factor);
+    if (access(filename, R_OK) == 0) {
+        ret = mixer_ctl_set_value(ctl_config, 0, 1);
+        if (ret < 0) {
+            ALOGE("%s set rx config failed", __func__);
+            goto exit;
+        }
+    } else {
+        ALOGE("%s: Tuning file not found (%s)", __func__,
+              filename);
+        ret = -EINVAL;
+        goto exit;
+    }
+
+    ALOGI("%s: Cirrus SP loaded available usecase configs", __func__);
+exit:
+    free(filename);
+    ALOGI("%s: Exit", __func__);
+
+    return ret;
+}
+
+static void *audio_extn_cirrus_calibration_thread() {
+    struct audio_device *adev = handle.adev_handle;
+    struct audio_usecase *uc_info_rx = NULL;
+    int ret = 0;
+    int32_t pcm_dev_rx_id, prev_state;
+    uint32_t retries = 5;
+
+    ALOGI("%s: PCM Stream thread", __func__);
+
+    while (!adev->platform && retries) {
+        sleep(1);
+        ALOGI("%s: Waiting...", __func__);
+        retries--;
+    }
+
+    prev_state = handle.state;
+    handle.state = CALIBRATING;
+
+    uc_info_rx = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
+    if (!uc_info_rx) {
+        ALOGE("%s: rx usecase can not be found", __func__);
+        goto exit;
+    }
+    pthread_mutex_lock(&adev->lock);
+
+    uc_info_rx->id = USECASE_AUDIO_PLAYBACK_DEEP_BUFFER;
+    uc_info_rx->type = PCM_PLAYBACK;
+    uc_info_rx->in_snd_device = SND_DEVICE_NONE;
+    uc_info_rx->stream.out = adev->primary_output;
+    uc_info_rx->out_snd_device = SND_DEVICE_OUT_SPEAKER;
+    list_add_tail(&adev->usecase_list, &uc_info_rx->list);
+
+    fp_enable_snd_device(adev, SND_DEVICE_OUT_SPEAKER);
+    fp_enable_audio_route(adev, uc_info_rx);
+    pcm_dev_rx_id = fp_platform_get_pcm_device_id(uc_info_rx->id, PCM_PLAYBACK);
+
+    if (pcm_dev_rx_id < 0) {
+        ALOGE("%s: Invalid pcm device for usecase (%d)",
+              __func__, uc_info_rx->id);
+        pthread_mutex_unlock(&adev->lock);
+        goto exit;
+    }
+
+    handle.pcm_rx = pcm_open(adev->snd_card, pcm_dev_rx_id,
+                PCM_OUT, &pcm_config_cirrus_rx);
+
+    if (handle.pcm_rx && !pcm_is_ready(handle.pcm_rx)) {
+        ALOGE("%s: PCM device not ready: %s", __func__,
+              pcm_get_error(handle.pcm_rx));
+        pthread_mutex_unlock(&adev->lock);
+        goto close_stream;
+    }
+
+    if (pcm_start(handle.pcm_rx) < 0) {
+        ALOGE("%s: pcm start for RX failed; error = %s", __func__,
+              pcm_get_error(handle.pcm_rx));
+        pthread_mutex_unlock(&adev->lock);
+        goto close_stream;
+    }
+    pthread_mutex_unlock(&adev->lock);
+    ALOGI("%s: PCM thread streaming", __func__);
+
+    ret = audio_extn_cirrus_run_calibration();
+    ALOGE_IF(ret < 0, "%s: Calibration procedure failed (%d)", __func__, ret);
+
+    ret = audio_extn_cirrus_load_usecase_configs();
+    ALOGE_IF(ret < 0, "%s: Set tuning configs failed (%d)", __func__, ret);
+
+close_stream:
+    pthread_mutex_lock(&adev->lock);
+    if (handle.pcm_rx) {
+        ALOGI("%s: pcm_rx_close", __func__);
+        pcm_close(handle.pcm_rx);
+        handle.pcm_rx = NULL;
+    }
+
+    fp_disable_audio_route(adev, uc_info_rx);
+    fp_disable_snd_device(adev, SND_DEVICE_OUT_SPEAKER);
+    list_remove(&uc_info_rx->list);
+    free(uc_info_rx);
+    pthread_mutex_unlock(&adev->lock);
+exit:
+    handle.state = (prev_state == PLAYBACK) ? PLAYBACK : IDLE;
+
+#ifdef ENABLE_CIRRUS_DETECTION
+    if (handle.state == PLAYBACK)
+        (void)pthread_create(&handle.failure_detect_thread,
+                    (const pthread_attr_t *) NULL,
+                    audio_extn_cirrus_failure_detect_thread,
+                    &handle);
+#endif
+
+    ALOGV("%s: Exit", __func__);
+
+    pthread_exit(0);
+    return NULL;
+}
+
+#else
+static void *audio_extn_cirrus_config_thread(void) {
+    struct audio_device *adev = handle.adev_handle;
+    struct crus_sp_ioctl_header header;
+    struct cirrus_cal_result_t result;
+    struct mixer_ctl *ctl_config = NULL;
+    FILE *cal_file = NULL;
+    int ret = 0, dev_file = -1;
+
+    ALOGI("%s: ++", __func__);
+
+    memset(&result, 0, sizeof(result));
+
+    dev_file = open(CRUS_SP_FILE, O_RDWR | O_NONBLOCK);
+    if (dev_file < 0) {
+        ALOGE("%s: Failed to open Cirrus Playback IOCTL (%d)",
+              __func__, dev_file);
+        ret = -EINVAL;
+        goto exit;
+    }
+
+    cal_file = fopen(CRUS_CAL_FILE, "r");
+    if (cal_file) {
+        ret = fread(&result, sizeof(result), 1, cal_file);
+
+        if (ret != 1) {
+            ALOGE("%s: Cirrus SP calibration file cannot be read , read size: %lu file error: %d",
+                 __func__, (unsigned long)ret * sizeof(result), ferror(cal_file));
+            ret = -EINVAL;
+            goto exit;
+        }
+    }
+
+    header.size = sizeof(header);
+    header.module_id = CRUS_MODULE_ID_TX;
+    header.param_id = 0;
+    header.data_length = sizeof(result);
+    header.data = &result;
+
+    ret = ioctl(dev_file, CRUS_SP_IOCTL_SET_CALIB, &header);
+
+    if (ret < 0) {
+        ALOGE("%s: Cirrus SP calibration IOCTL failure", __func__);
+        goto exit;
+    }
+
+    ctl_config = mixer_get_ctl_by_name(adev->mixer,
+                       CRUS_SP_LOAD_CONF_MIXER);
+    if (!ctl_config) {
+        ALOGE("%s: Could not get ctl for mixer commands", __func__);
+        ret = -EINVAL;
+        goto exit;
+    }
+
+    ret = mixer_ctl_set_value(ctl_config, 0, 2);
+    if (ret < 0) {
+        ALOGE("%s load tx config failed", __func__);
+        goto exit;
+    }
+
+    ret = mixer_ctl_set_value(ctl_config, 0, 1);
+    if (ret < 0) {
+        ALOGE("%s load rx config failed", __func__);
+        goto exit;
+    }
+
+    ret = mixer_ctl_set_value(ctl_config, 0, 0);
+    if (ret < 0) {
+        ALOGE("%s set idle state failed", __func__);
+        goto exit;
+    }
+
+exit:
+    if (dev_file >= 0)
+        close(dev_file);
+    if (cal_file)
+        fclose(cal_file);
+
+    ALOGI("%s: ret: %d --", __func__, ret);
+    return NULL;
+}
+#endif
+
+#ifdef ENABLE_CIRRUS_DETECTION
+void *audio_extn_cirrus_failure_detect_thread() {
+    struct audio_device *adev = handle.adev_handle;
+    struct crus_sp_ioctl_header header;
+    struct mixer_ctl *ctl = NULL;
+    const int32_t r_scale_factor = 100000000;
+    const int32_t t_scale_factor = 100000;
+    const int32_t r_err_range = 70000000;
+    const int32_t t_err_range = 210000;
+    const int32_t amp_factor = 71498;
+    const int32_t material = 250;
+    int32_t *buffer = NULL;
+    int ret = 0, dev_file = -1, out_cal0 = 0, out_cal1 = 0;
+    int rL = 0, rR = 0, zL = 0, zR = 0, tL = 0, tR = 0;
+    int rdL = 0, rdR = 0, tdL = 0, tdR = 0, ambL = 0, ambR = 0;
+    bool left_cal_done = false, right_cal_done = false;
+    bool det_en = false;
+
+    ALOGI("%s: Entry", __func__);
+
+    ctl = mixer_get_ctl_by_name(adev->mixer, CRUS_SP_FAIL_DET_MIXER);
+    det_en = mixer_ctl_get_value(ctl, 0);
+
+    if (!det_en)
+        goto exit;
+
+    dev_file = open(CRUS_SP_FILE, O_RDWR | O_NONBLOCK);
+    if (dev_file < 0) {
+        ALOGE("%s: Failed to open Cirrus Playback IOCTL (%d)",
+                __func__, dev_file);
+        goto exit;
+    }
+
+    buffer = calloc(1, CRUS_PARAM_TEMP_MAX_LENGTH);
+    if (!buffer) {
+        ALOGE("%s: allocate memory failed", __func__);
+        goto exit;
+    }
+
+    header.size = sizeof(header);
+    header.module_id = CRUS_MODULE_ID_RX;
+    header.param_id = CRUS_PARAM_RX_GET_TEMP;
+    header.data_length = CRUS_PARAM_TEMP_MAX_LENGTH;
+    header.data = buffer;
+
+    usleep(FAIL_DETECT_INIT_WAIT_US);
+
+    pthread_mutex_lock(&handle.fb_prot_mutex);
+    ret = ioctl(dev_file, CRUS_SP_IOCTL_GET, &header);
+    pthread_mutex_unlock(&handle.fb_prot_mutex);
+    if (ret < 0) {
+        ALOGE("%s: Cirrus SP IOCTL failure (%d)",
+               __func__, ret);
+        goto exit;
+    }
+
+    zL = buffer[2] * amp_factor;
+    zR = buffer[4] * amp_factor;
+
+    ambL = buffer[10];
+    ambR = buffer[6];
+
+    out_cal0 = buffer[12];
+    out_cal1 = buffer[13];
+
+    left_cal_done = (out_cal0 == 2) && (out_cal1 == 2) &&
+                    (buffer[2] != CRUS_DEFAULT_CAL_L);
+
+    out_cal0 = buffer[14];
+    out_cal1 = buffer[15];
+
+    right_cal_done = (out_cal0 == 2) && (out_cal1 == 2) &&
+                     (buffer[4] != CRUS_DEFAULT_CAL_R);
+
+    if (left_cal_done) {
+        ALOGI("%s: L Speaker Impedance: %d.%08d ohms", __func__,
+              zL / r_scale_factor, abs(zL) % r_scale_factor);
+        ALOGI("%s: L Calibration Temperature: %d C", __func__, ambL);
+    } else
+        ALOGE("%s: Left speaker uncalibrated", __func__);
+
+    if (right_cal_done) {
+        ALOGI("%s: R Speaker Impedance: %d.%08d ohms", __func__,
+               zR / r_scale_factor, abs(zR) % r_scale_factor);
+        ALOGI("%s: R Calibration Temperature: %d C", __func__, ambR);
+    } else
+        ALOGE("%s: Right speaker uncalibrated", __func__);
+
+    if (!left_cal_done && !right_cal_done)
+        goto exit;
+
+    ALOGI("%s: Monitoring speaker impedance & temperature...", __func__);
+
+    while ((handle.state == PLAYBACK) && det_en) {
+        pthread_mutex_lock(&handle.fb_prot_mutex);
+        ret = ioctl(dev_file, CRUS_SP_IOCTL_GET, &header);
+        pthread_mutex_unlock(&handle.fb_prot_mutex);
+        if (ret < 0) {
+            ALOGE("%s: Cirrus SP IOCTL failure (%d)",
+                  __func__, ret);
+            goto loop;
+        }
+
+        rL = buffer[3];
+        rR = buffer[1];
+
+        zL = buffer[2];
+        zR = buffer[4];
+
+        if ((zL == 0) || (zR == 0))
+            goto loop;
+
+        tdL = (material * t_scale_factor * (rL-zL) / zL);
+        tdR = (material * t_scale_factor * (rR-zR) / zR);
+
+        rL *= amp_factor;
+        rR *= amp_factor;
+
+        zL *= amp_factor;
+        zR *= amp_factor;
+
+        tL = tdL + (ambL * t_scale_factor);
+        tR = tdR + (ambR * t_scale_factor);
+
+        rdL = abs(zL - rL);
+        rdR = abs(zR - rR);
+
+        if (left_cal_done && (rL != 0) && (rdL > r_err_range))
+            ALOGI("%s: Left speaker impedance out of range (%d.%08d ohms)",
+                  __func__, rL / r_scale_factor,
+                  abs(rL % r_scale_factor));
+
+        if (right_cal_done && (rR != 0) && (rdR > r_err_range))
+            ALOGI("%s: Right speaker impedance out of range (%d.%08d ohms)",
+                  __func__, rR / r_scale_factor,
+                  abs(rR % r_scale_factor));
+
+        if (left_cal_done && (rL != 0) && (tdL > t_err_range))
+            ALOGI("%s: Left speaker temperature out of range (%d.%05d C)",
+                  __func__, tL / t_scale_factor,
+                  abs(tL % t_scale_factor));
+
+        if (right_cal_done && (rR != 0) && (tdR > t_err_range))
+            ALOGI("%s: Right speaker temperature out of range (%d.%05d C)",
+                  __func__, tR / t_scale_factor,
+                  abs(tR % t_scale_factor));
+
+loop:
+        det_en = mixer_ctl_get_value(ctl, 0);
+        usleep(FAIL_DETECT_LOOP_WAIT_US);
+    }
+
+exit:
+    if (dev_file >= 0)
+        close(dev_file);
+    free(buffer);
+    ALOGI("%s: Exit ", __func__);
+
+    pthread_exit(0);
+    return NULL;
+}
+#endif
+
+int spkr_prot_start_processing(snd_device_t snd_device) {
+    struct audio_usecase *uc_info_tx;
+    struct audio_device *adev = handle.adev_handle;
+    int32_t pcm_dev_tx_id = -1, ret = 0;
+
+    ALOGV("%s: Entry", __func__);
+
+    if (!adev) {
+        ALOGE("%s: Invalid params", __func__);
+        return -EINVAL;
+    }
+
+    uc_info_tx = (struct audio_usecase *)calloc(1, sizeof(*uc_info_tx));
+    if (!uc_info_tx) {
+        ALOGE("%s: allocate memory failed", __func__);
+        return -ENOMEM;
+    }
+
+    audio_route_apply_and_update_path(adev->audio_route,
+                                      fp_platform_get_snd_device_name(snd_device));
+
+    pthread_mutex_lock(&handle.fb_prot_mutex);
+    uc_info_tx->id = USECASE_AUDIO_SPKR_CALIB_TX;
+    uc_info_tx->type = PCM_CAPTURE;
+    uc_info_tx->in_snd_device = SND_DEVICE_IN_CAPTURE_VI_FEEDBACK;
+    uc_info_tx->out_snd_device = SND_DEVICE_NONE;
+    handle.pcm_tx = NULL;
+
+    list_add_tail(&adev->usecase_list, &uc_info_tx->list);
+
+    fp_enable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK);
+    fp_enable_audio_route(adev, uc_info_tx);
+
+    pcm_dev_tx_id = fp_platform_get_pcm_device_id(uc_info_tx->id, PCM_CAPTURE);
+
+    if (pcm_dev_tx_id < 0) {
+        ALOGE("%s: Invalid pcm device for usecase (%d)",
+              __func__, uc_info_tx->id);
+        ret = -ENODEV;
+        goto exit;
+    }
+
+    handle.pcm_tx = pcm_open(adev->snd_card,
+                             pcm_dev_tx_id,
+                             PCM_IN, &pcm_config_cirrus_tx);
+
+    if (handle.pcm_tx && !pcm_is_ready(handle.pcm_tx)) {
+        ALOGE("%s: PCM device not ready: %s", __func__, pcm_get_error(handle.pcm_tx));
+        ret = -EIO;
+        goto exit;
+    }
+
+    if (pcm_start(handle.pcm_tx) < 0) {
+        ALOGE("%s: pcm start for TX failed; error = %s", __func__,
+              pcm_get_error(handle.pcm_tx));
+        ret = -EINVAL;
+        goto exit;
+    }
+
+#ifdef ENABLE_CIRRUS_DETECTION
+    if (handle.state == IDLE)
+        (void)pthread_create(&handle.failure_detect_thread,
+                    (const pthread_attr_t *) NULL,
+                    audio_extn_cirrus_failure_detect_thread,
+                    &handle);
+#endif
+
+    handle.state = PLAYBACK;
+exit:
+    if (ret) {
+        handle.state = IDLE;
+        if (handle.pcm_tx) {
+            ALOGI("%s: pcm_tx_close", __func__);
+            pcm_close(handle.pcm_tx);
+            handle.pcm_tx = NULL;
+        }
+
+        fp_disable_audio_route(adev, uc_info_tx);
+        fp_disable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK);
+        list_remove(&uc_info_tx->list);
+        free(uc_info_tx);
+    }
+
+    pthread_mutex_unlock(&handle.fb_prot_mutex);
+    ALOGV("%s: Exit", __func__);
+    return ret;
+}
+
+void spkr_prot_stop_processing(snd_device_t snd_device) {
+    struct audio_usecase *uc_info_tx;
+    struct audio_device *adev = handle.adev_handle;
+
+    ALOGV("%s: Entry", __func__);
+
+    pthread_mutex_lock(&handle.fb_prot_mutex);
+
+    handle.state = IDLE;
+    uc_info_tx = fp_get_usecase_from_list(adev, USECASE_AUDIO_SPKR_CALIB_TX);
+
+    if (uc_info_tx) {
+        if (handle.pcm_tx) {
+            ALOGI("%s: pcm_tx_close", __func__);
+            pcm_close(handle.pcm_tx);
+            handle.pcm_tx = NULL;
+        }
+
+        fp_disable_audio_route(adev, uc_info_tx);
+        fp_disable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK);
+        list_remove(&uc_info_tx->list);
+        free(uc_info_tx);
+
+        audio_route_reset_path(adev->audio_route,
+                               fp_platform_get_snd_device_name(snd_device));
+    }
+
+    pthread_mutex_unlock(&handle.fb_prot_mutex);
+
+    ALOGV("%s: Exit", __func__);
+}
+
+bool spkr_prot_is_enabled() {
+    return true;
+}
+
+int get_spkr_prot_snd_device(snd_device_t snd_device) {
+    switch(snd_device) {
+    case SND_DEVICE_OUT_SPEAKER:
+    case SND_DEVICE_OUT_SPEAKER_REVERSE:
+        return SND_DEVICE_OUT_SPEAKER_PROTECTED;
+    case SND_DEVICE_OUT_SPEAKER_SAFE:
+        return SND_DEVICE_OUT_SPEAKER_SAFE;
+    case SND_DEVICE_OUT_VOICE_SPEAKER:
+        return SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED;
+    default:
+        return snd_device;
+    }
+}
+
+void spkr_prot_calib_cancel(__unused void *adev) {
+    // FIXME: wait or cancel audio_extn_cirrus_run_calibration
+}
diff --git a/hal/audio_extn/compress_capture.c b/hal/audio_extn/compress_capture.c
index 671796c..f0aeec2 100644
--- a/hal/audio_extn/compress_capture.c
+++ b/hal/audio_extn/compress_capture.c
@@ -29,8 +29,8 @@
 #include <cutils/log.h>
 
 #include "audio_hw.h"
-#include "platform.h"
-#include "platform_api.h"
+//#include "platform.h"
+//#include "platform_api.h"
 
 #include "sound/compress_params.h"
 #include "sound/compress_offload.h"
@@ -57,7 +57,7 @@
 };
 
 
-void audio_extn_compr_cap_init(struct stream_in *in)
+void compr_cap_init(struct stream_in *in)
 {
     in->usecase = USECASE_AUDIO_RECORD_COMPRESS;
     in->config.channels = COMPRESS_IN_CONFIG_CHANNELS;
@@ -67,7 +67,7 @@
     c_in_mod.in_buf = (uint8_t*)calloc(1, in->config.period_size*2);
 }
 
-void audio_extn_compr_cap_deinit()
+void compr_cap_deinit()
 {
     if (c_in_mod.in_buf) {
         free(c_in_mod.in_buf);
@@ -75,7 +75,7 @@
     }
 }
 
-bool audio_extn_compr_cap_enabled()
+bool compr_cap_enabled()
 {
     char prop_value[PROPERTY_VALUE_MAX] = {0};
     bool tunnel_encode = false;
@@ -87,7 +87,7 @@
         return false;
 }
 
-bool audio_extn_compr_cap_format_supported(audio_format_t format)
+bool compr_cap_format_supported(audio_format_t format)
 {
     if (format == AUDIO_FORMAT_AMR_WB)
         return true;
@@ -96,7 +96,7 @@
 }
 
 
-bool audio_extn_compr_cap_usecase_supported(audio_usecase_t usecase)
+bool compr_cap_usecase_supported(audio_usecase_t usecase)
 {
     if ((usecase == USECASE_AUDIO_RECORD_COMPRESS) ||
         (usecase == USECASE_INCALL_REC_UPLINK_COMPRESS) ||
@@ -108,7 +108,7 @@
 }
 
 
-size_t audio_extn_compr_cap_get_buffer_size(audio_format_t format)
+size_t compr_cap_get_buffer_size(audio_format_t format)
 {
     if (format == AUDIO_FORMAT_AMR_WB)
         /*One AMR WB frame is 61 bytes. Return that to the caller.
@@ -118,7 +118,7 @@
         return 0;
 }
 
-size_t audio_extn_compr_cap_read(struct stream_in * in,
+size_t compr_cap_read(struct stream_in * in,
     void *buffer, size_t bytes)
 {
     int ret;
diff --git a/hal/edid.c b/hal/audio_extn/edid.c
similarity index 100%
rename from hal/edid.c
rename to hal/audio_extn/edid.c
diff --git a/hal/edid.h b/hal/audio_extn/edid.h
similarity index 92%
rename from hal/edid.h
rename to hal/audio_extn/edid.h
index a7578e6..7c71ab4 100644
--- a/hal/edid.h
+++ b/hal/audio_extn/edid.h
@@ -113,30 +113,8 @@
     unsigned int  channel_mask;
 } edid_audio_info;
 
-#ifdef HDMI_EDID
 bool edid_is_supported_sr(edid_audio_info* info, int sr);
 bool edid_is_supported_bps(edid_audio_info* info, int bps);
 int edid_get_highest_supported_sr(edid_audio_info* info);
 bool edid_get_sink_caps(edid_audio_info* info, char *edid_data);
-#else
-static bool __unused edid_is_supported_sr(edid_audio_info* info __unused, int sr __unused)
-{
-    return false;
-}
-static bool __unused edid_is_supported_bps(edid_audio_info* info __unused, int bps __unused)
-{
-    return false;
-}
-
-static bool __unused edid_get_sink_caps(edid_audio_info* info __unused, char* edid_data __unused)
-{
-    return false;
-}
-
-static int __unused edid_get_highest_supported_sr(edid_audio_info* info __unused)
-{
-    return 0;
-}
-#endif
-
 #endif /* EDID_H */
diff --git a/hal/audio_extn/fm.c b/hal/audio_extn/fm.c
index d08d498..3c1ec68 100644
--- a/hal/audio_extn/fm.c
+++ b/hal/audio_extn/fm.c
@@ -38,7 +38,6 @@
 #include <log_utils.h>
 #endif
 
-#ifdef FM_POWER_OPT
 #define AUDIO_PARAMETER_KEY_HANDLE_FM "handle_fm"
 #define AUDIO_PARAMETER_KEY_FM_VOLUME "fm_volume"
 #define AUDIO_PARAMETER_KEY_REC_PLAY_CONC "rec_play_conc_on"
@@ -251,7 +250,7 @@
     return ret;
 }
 
-void audio_extn_fm_get_parameters(struct str_parms *query, struct str_parms *reply)
+void fm_get_parameters(struct str_parms *query, struct str_parms *reply)
 {
     int ret, val;
     char value[32]={0};
@@ -264,7 +263,7 @@
     }
 }
 
-void audio_extn_fm_set_parameters(struct audio_device *adev,
+void fm_set_parameters(struct audio_device *adev,
                                   struct str_parms *parms)
 {
     int ret, val;
@@ -387,4 +386,3 @@
 exit:
     ALOGV("%s: exit", __func__);
 }
-#endif /* FM_POWER_OPT end */
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index 89c42c8..57a3841 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -31,7 +31,7 @@
 
 #include <errno.h>
 #include <math.h>
-#include <cutils/log.h>
+#include <log/log.h>
 
 #include "audio_hw.h"
 #include "platform.h"
@@ -52,13 +52,21 @@
 #define AUDIO_PARAMETER_KEY_HFP_VOLUME "hfp_volume"
 #define AUDIO_PARAMETER_HFP_PCM_DEV_ID "hfp_pcm_dev_id"
 
+#define AUDIO_PARAMETER_KEY_HFP_MIC_VOLUME "hfp_mic_volume"
+#define PLAYBACK_VOLUME_MAX 0x2000
+#define CAPTURE_VOLUME_DEFAULT                (15.0)
+
 #ifdef PLATFORM_MSM8994
 #define HFP_RX_VOLUME     "SEC AUXPCM LOOPBACK Volume"
-#elif defined PLATFORM_MSM8996
+#elif defined (PLATFORM_MSM8996) || defined (EXTERNAL_BT_SUPPORTED)
 #define HFP_RX_VOLUME     "PRI AUXPCM LOOPBACK Volume"
 #elif defined PLATFORM_AUTO
 #define HFP_RX_VOLUME     "Playback 36 Volume"
-#elif defined (PLATFORM_MSM8998) || defined (PLATFORM_MSMFALCON) || defined (PLATFORM_SDM845) || defined (PLATFORM_SDM710) || defined (PLATFORM_QCS605) || defined (PLATFORM_MSMNILE) || defined (PLATFORM_MSMSTEPPE) || defined (PLATFORM_QCS405)
+#elif defined (PLATFORM_MSM8998) || defined (PLATFORM_MSMFALCON) || \
+      defined (PLATFORM_SDM845) || defined (PLATFORM_SDM710) || \
+      defined (PLATFORM_QCS605) || defined (PLATFORM_MSMNILE) || \
+      defined (PLATFORM_KONA) || defined (PLATFORM_MSMSTEPPE) || \
+      defined (PLATFORM_QCS405)
 #define HFP_RX_VOLUME     "SLIMBUS_7 LOOPBACK Volume"
 #else
 #define HFP_RX_VOLUME     "Internal HFP RX Volume"
@@ -78,6 +86,8 @@
     float hfp_volume;
     int32_t hfp_pcm_dev_id;
     audio_usecase_t ucid;
+    float mic_volume;
+    bool mic_mute;
 };
 
 static struct hfp_module hfpmod = {
@@ -89,7 +99,10 @@
     .hfp_volume = 0,
     .hfp_pcm_dev_id = HFP_ASM_RX_TX,
     .ucid = USECASE_AUDIO_HFP_SCO,
+    .mic_volume = CAPTURE_VOLUME_DEFAULT,
+    .mic_mute = 0,
 };
+
 static struct pcm_config pcm_config_hfp = {
     .channels = 1,
     .rate = 8000,
@@ -111,6 +124,7 @@
     ALOGD("%s: (%f)\n", __func__, value);
 
     hfpmod.hfp_volume = value;
+
     if (value < 0.0) {
         ALOGW("%s: (%f) Under 0.0, assuming 0.0\n", __func__, value);
         value = 0.0;
@@ -141,6 +155,114 @@
     return ret;
 }
 
+/*Set mic volume to value.
+*
+* This interface is used for mic volume control, set mic volume as value(range 0 ~ 15).
+*/
+static int hfp_set_mic_volume(struct audio_device *adev, float value)
+{
+    int volume, ret = 0;
+    char mixer_ctl_name[128];
+    struct mixer_ctl *ctl;
+    int pcm_device_id = HFP_ASM_RX_TX;
+
+    if (!hfpmod.is_hfp_running) {
+        ALOGE("%s: HFP not active, ignoring set_hfp_mic_volume call", __func__);
+        return -EIO;
+    }
+
+    if (value < 0.0) {
+        ALOGW("%s: (%f) Under 0.0, assuming 0.0\n", __func__, value);
+        value = 0.0;
+    } else if (value > CAPTURE_VOLUME_DEFAULT) {
+        value = CAPTURE_VOLUME_DEFAULT;
+        ALOGW("%s: Volume brought within range (%f)\n", __func__, value);
+    }
+
+    value = value / CAPTURE_VOLUME_DEFAULT;
+    memset(mixer_ctl_name, 0, sizeof(mixer_ctl_name));
+    snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+             "Playback %d Volume", pcm_device_id);
+    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+    if (!ctl) {
+        ALOGE("%s: Could not get ctl for mixer cmd - %s",
+              __func__, mixer_ctl_name);
+        return -EINVAL;
+    }
+    volume = (int)(value * PLAYBACK_VOLUME_MAX);
+
+    ALOGD("%s: Setting volume to %d (%s)\n", __func__, volume, mixer_ctl_name);
+    if (mixer_ctl_set_value(ctl, 0, volume) < 0) {
+        ALOGE("%s: Couldn't set HFP Volume: [%d]", __func__, volume);
+        return -EINVAL;
+    }
+
+    return ret;
+}
+
+static float hfp_get_mic_volume(struct audio_device *adev)
+{
+    int volume;
+    char mixer_ctl_name[128];
+    struct mixer_ctl *ctl;
+    int pcm_device_id = HFP_ASM_RX_TX;
+    float value = 0.0;
+
+    if (!hfpmod.is_hfp_running) {
+        ALOGE("%s: HFP not active, ignoring set_hfp_mic_volume call", __func__);
+        return -EIO;
+    }
+
+    memset(mixer_ctl_name, 0, sizeof(mixer_ctl_name));
+    snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+             "Playback %d Volume", pcm_device_id);
+    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+    if (!ctl) {
+        ALOGE("%s: Could not get ctl for mixer cmd - %s",
+              __func__, mixer_ctl_name);
+        return -EINVAL;
+    }
+
+    volume = mixer_ctl_get_value(ctl, 0);
+    if ( volume < 0) {
+        ALOGE("%s: Couldn't set HFP Volume: [%d]", __func__, volume);
+        return -EINVAL;
+    }
+    ALOGD("%s: getting mic volume %d \n", __func__, volume);
+
+    value = (volume / PLAYBACK_VOLUME_MAX) * CAPTURE_VOLUME_DEFAULT;
+    if (value < 0.0) {
+        ALOGW("%s: (%f) Under 0.0, assuming 0.0\n", __func__, value);
+        value = 0.0;
+    } else if (value > CAPTURE_VOLUME_DEFAULT) {
+        value = CAPTURE_VOLUME_DEFAULT;
+        ALOGW("%s: Volume brought within range (%f)\n", __func__, value);
+    }
+
+    return value;
+}
+
+/*Set mic mute state.
+*
+* This interface is used for mic mute state control
+*/
+int audio_extn_hfp_set_mic_mute(struct audio_device *adev, bool state)
+{
+    int rc = 0;
+
+    if (state == hfpmod.mic_mute)
+        return rc;
+
+    if (state == true) {
+        hfpmod.mic_volume = hfp_get_mic_volume(adev);
+    }
+    rc = hfp_set_mic_volume(adev, (state == true) ? 0.0 : hfpmod.mic_volume);
+    adev->voice.mic_mute = state;
+    hfpmod.mic_mute = state;
+    ALOGD("%s: Setting mute state %d, rc %d\n", __func__, state, rc);
+    return rc;
+}
+
 static int32_t start_hfp(struct audio_device *adev,
                          struct str_parms *parms __unused)
 {
@@ -150,6 +272,13 @@
 
     ALOGD("%s: enter", __func__);
 
+    if (adev->enable_hfp == true) {
+        ALOGD("%s: HFP is already active!\n", __func__);
+        return 0;
+    }
+    adev->enable_hfp = true;
+    platform_set_mic_mute(adev->platform, false);
+
     uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
 
     if (!uc_info)
@@ -197,8 +326,8 @@
     }
 
     hfpmod.hfp_pcm_rx = pcm_open(adev->snd_card,
-                                   pcm_dev_rx_id,
-                                   PCM_OUT, &pcm_config_hfp);
+                                 pcm_dev_rx_id,
+                                 PCM_OUT, &pcm_config_hfp);
     if (hfpmod.hfp_pcm_rx && !pcm_is_ready(hfpmod.hfp_pcm_rx)) {
         ALOGE("%s: %s", __func__, pcm_get_error(hfpmod.hfp_pcm_rx));
         ret = -EIO;
@@ -215,8 +344,8 @@
     }
 
     hfpmod.hfp_pcm_tx = pcm_open(adev->snd_card,
-                                   pcm_dev_tx_id,
-                                   PCM_IN, &pcm_config_hfp);
+                                 pcm_dev_tx_id,
+                                 PCM_IN, &pcm_config_hfp);
     if (hfpmod.hfp_pcm_tx && !pcm_is_ready(hfpmod.hfp_pcm_tx)) {
         ALOGE("%s: %s", __func__, pcm_get_error(hfpmod.hfp_pcm_tx));
         ret = -EIO;
@@ -233,6 +362,7 @@
         ret = -EINVAL;
         goto exit;
     }
+
     if (pcm_start(hfpmod.hfp_pcm_rx) < 0) {
         ALOGE("%s: pcm start for hfp pcm rx failed", __func__);
         ret = -EINVAL;
@@ -247,6 +377,10 @@
     hfpmod.is_hfp_running = true;
     hfp_set_volume(adev, hfpmod.hfp_volume);
 
+    /* Set mic volume by mute status, we don't provide set mic volume in phone app, only
+    provide mute and unmute. */
+    audio_extn_hfp_set_mic_mute(adev, adev->mic_muted);
+
     ALOGD("%s: exit: status(%d)", __func__, ret);
     return 0;
 
@@ -305,6 +439,13 @@
     disable_snd_device(adev, uc_info->out_snd_device);
     disable_snd_device(adev, uc_info->in_snd_device);
 
+    /* Set the unmute Tx mixer control */
+    if (voice_get_mic_mute(adev)) {
+        platform_set_mic_mute(adev->platform, false);
+        ALOGD("%s: unMute HFP Tx", __func__);
+    }
+    adev->enable_hfp = false;
+
     list_remove(&uc_info->list);
     free(uc_info);
 
@@ -413,6 +554,19 @@
         str_parms_del(parms, AUDIO_PARAMETER_HFP_PCM_DEV_ID);
     }
 
+    memset(value, 0, sizeof(value));
+    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HFP_MIC_VOLUME,
+                            value, sizeof(value));
+    if (ret >= 0) {
+        if (sscanf(value, "%f", &vol) != 1){
+            ALOGE("%s: error in retrieving hfp mic volume", __func__);
+            ret = -EIO;
+            goto exit;
+        }
+        ALOGD("%s: set_hfp_mic_volume usecase, Vol: [%f]", __func__, vol);
+        hfp_set_mic_volume(adev, vol);
+    }
+
 exit:
     ALOGV("%s Exit",__func__);
 }
diff --git a/hal/audio_extn/keep_alive.c b/hal/audio_extn/keep_alive.c
index 90875d9..20214aa 100644
--- a/hal/audio_extn/keep_alive.c
+++ b/hal/audio_extn/keep_alive.c
@@ -37,6 +37,7 @@
 #include "audio_extn.h"
 #include "platform_api.h"
 #include <platform.h>
+#include <pthread.h>
 
 #ifdef DYNAMIC_LOG_ENABLED
 #include <log_xml_parser.h>
@@ -114,7 +115,7 @@
     pthread_cond_signal(&ka.cond);
 }
 
-void audio_extn_keep_alive_init(struct audio_device *adev)
+void keep_alive_init(struct audio_device *adev)
 {
     ka.userdata = adev;
     ka.state = STATE_IDLE;
@@ -146,7 +147,7 @@
     ALOGV("%s init done", __func__);
 }
 
-void audio_extn_keep_alive_deinit()
+void keep_alive_deinit()
 {
     if (ka.state == STATE_DEINIT || ka.state == STATE_DISABLED)
         return;
@@ -191,7 +192,7 @@
     return out_device;
 }
 
-void audio_extn_keep_alive_start(ka_mode_t ka_mode)
+void keep_alive_start(ka_mode_t ka_mode)
 {
     struct audio_device * adev = (struct audio_device *)ka.userdata;
     audio_devices_t out_devices = AUDIO_DEVICE_NONE;
@@ -300,7 +301,7 @@
     return rc;
 }
 
-void audio_extn_keep_alive_stop(ka_mode_t ka_mode)
+void keep_alive_stop(ka_mode_t ka_mode)
 {
     struct audio_device * adev = (struct audio_device *)ka.userdata;
     audio_devices_t out_devices;
@@ -365,7 +366,7 @@
     return 0;
 }
 
-int audio_extn_keep_alive_set_parameters(struct audio_device *adev __unused,
+int keep_alive_set_parameters(struct audio_device *adev __unused,
                                          struct str_parms *parms __unused)
 {
     char value[32];
diff --git a/hal/audio_extn/maxxaudio.c b/hal/audio_extn/maxxaudio.c
new file mode 100644
index 0000000..5f2a7f0
--- /dev/null
+++ b/hal/audio_extn/maxxaudio.c
@@ -0,0 +1,727 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "audio_hw_waves"
+/*#define LOG_NDEBUG 0*/
+
+#include <audio_hw.h>
+#include <cutils/str_parms.h>
+#include <dlfcn.h>
+#include <log/log.h>
+#include <math.h>
+#include <platform_api.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <system/audio.h>
+#include <unistd.h>
+
+#include "audio_extn.h"
+#include "maxxaudio.h"
+
+#define LIB_MA_PARAM "libmaxxaudioqdsp.so"
+#define LIB_MA_PATH "vendor/lib/"
+#define PRESET_PATH "/vendor/etc"
+#define MPS_BASE_STRING "default"
+#define USER_PRESET_PATH ""
+#define CONFIG_BASE_STRING "maxx_conf"
+#define CAL_PRESIST_STR "cal_persist"
+#define CAL_SAMPLERATE_STR "cal_samplerate"
+
+#define MA_QDSP_PARAM_INIT      "maxxaudio_qdsp_initialize"
+#define MA_QDSP_PARAM_DEINIT    "maxxaudio_qdsp_uninitialize"
+#define MA_QDSP_SET_LR_SWAP     "maxxaudio_qdsp_set_lr_swap"
+#define MA_QDSP_SET_MODE        "maxxaudio_qdsp_set_sound_mode"
+#define MA_QDSP_SET_VOL         "maxxaudio_qdsp_set_volume"
+#define MA_QDSP_SET_VOLT        "maxxaudio_qdsp_set_volume_table"
+#define MA_QDSP_SET_PARAM       "maxxaudio_qdsp_set_parameter"
+
+#define SUPPORT_DEV "18d1:5033" // Blackbird usbid
+#define SUPPORTED_USB 0x01
+
+typedef unsigned int effective_scope_flag_t;
+const effective_scope_flag_t EFFECTIVE_SCOPE_RTC = 1 << 0;   /* RTC  */
+const effective_scope_flag_t EFFECTIVE_SCOPE_ACDB = 1 << 1;  /* ACDB */
+const effective_scope_flag_t EFFECTIVE_SCOPE_ALL = EFFECTIVE_SCOPE_RTC | EFFECTIVE_SCOPE_ACDB;
+const effective_scope_flag_t EFFECTIVE_SCOPE_NONE = 0;
+const effective_scope_flag_t EFFECTIVE_SCOPE_DEFAULT = EFFECTIVE_SCOPE_NONE;
+
+const unsigned int AUDIO_CAL_SETTINGS_VERSION_MAJOR = 2;
+const unsigned int AUDIO_CAL_SETTINGS_VERSION_MINOR = 0;
+const unsigned int AUDIO_CAL_SETTINGS_VERSION_MAJOR_DEFAULT = AUDIO_CAL_SETTINGS_VERSION_MAJOR;
+const unsigned int AUDIO_CAL_SETTINGS_VERSION_MINOR_DEFAULT = AUDIO_CAL_SETTINGS_VERSION_MINOR;
+
+const unsigned int VALUE_AUTO = 0xFFFFFFFF;
+const unsigned int APP_TYPE_AUTO = VALUE_AUTO;
+const unsigned int APP_TYPE_DEFAULT = APP_TYPE_AUTO;
+const unsigned int DEVICE_AUTO = VALUE_AUTO;
+const unsigned int DEVICE_DEFAULT = DEVICE_AUTO;
+
+const unsigned int MAAP_OUTPUT_GAIN = 27;
+
+typedef enum MA_STREAM_TYPE {
+    STREAM_MIN_TYPES = 0,
+    STREAM_VOICE = STREAM_MIN_TYPES,
+    STREAM_SYSTEM,
+    STREAM_RING,
+    STREAM_MUSIC,
+    STREAM_ALARM,
+    STREAM_NOTIFICATION ,
+    STREAM_MAX_TYPES,
+} ma_stream_type_t;
+
+typedef enum MA_CMD {
+    MA_CMD_VOL,
+    MA_CMD_SWAP_ENABLE,
+    MA_CMD_SWAP_DISABLE,
+    MA_CMD_SOFT_MUTE_ENABLE,
+    MA_CMD_SOFT_MUTE_DISABLE,
+} ma_cmd_t;
+
+typedef struct ma_audio_cal_version {
+    unsigned int major;
+    unsigned int minor;
+} ma_audio_cal_version_t;
+
+typedef struct ma_audio_cal_common_settings {
+    unsigned int app_type;
+    unsigned int device;
+} ma_audio_cal_common_settings_t;
+
+struct ma_audio_cal_settings {
+    ma_audio_cal_version_t version;
+    ma_audio_cal_common_settings_t common;
+    effective_scope_flag_t effect_scope_flag;
+};
+
+struct ma_state {
+    float vol;
+    bool active;
+};
+
+typedef void *ma_audio_cal_handle_t;
+typedef int (*set_audio_cal_t)(const char *);
+
+typedef bool (*ma_param_init_t)(ma_audio_cal_handle_t *, const char *,
+                                const char *, const char *, set_audio_cal_t);
+
+typedef bool (*ma_param_deinit_t)(ma_audio_cal_handle_t *);
+
+typedef bool (*ma_set_lr_swap_t)(ma_audio_cal_handle_t,
+                                 const struct ma_audio_cal_settings *, bool);
+
+typedef bool (*ma_set_sound_mode_t)(ma_audio_cal_handle_t,
+                                    const struct ma_audio_cal_settings *,
+                                    unsigned int);
+
+typedef bool (*ma_set_volume_t)(ma_audio_cal_handle_t,
+                                const struct ma_audio_cal_settings *, double);
+
+typedef bool (*ma_set_volume_table_t)(ma_audio_cal_handle_t,
+                                      const struct ma_audio_cal_settings *,
+                                      size_t, struct ma_state *);
+
+typedef bool (*ma_set_param_t)(ma_audio_cal_handle_t,
+                               const struct ma_audio_cal_settings *,
+                               unsigned int, double);
+
+struct ma_platform_data {
+    void *waves_handle;
+    void *platform;
+    pthread_mutex_t lock;
+    ma_param_init_t          ma_param_init;
+    ma_param_deinit_t        ma_param_deinit;
+    ma_set_lr_swap_t         ma_set_lr_swap;
+    ma_set_sound_mode_t      ma_set_sound_mode;
+    ma_set_volume_t          ma_set_volume;
+    ma_set_volume_table_t    ma_set_volume_table;
+    ma_set_param_t           ma_set_param;
+    bool speaker_lr_swap;
+};
+
+ma_audio_cal_handle_t g_ma_audio_cal_handle = NULL;
+static uint16_t g_supported_dev = 0;
+static struct ma_state ma_cur_state_table[STREAM_MAX_TYPES];
+static struct ma_platform_data *my_data = NULL;
+
+static int set_audio_cal(const char *audio_cal)
+{
+    ALOGV("set_audio_cal: %s", audio_cal);
+
+    return platform_set_parameters(my_data->platform,
+                                   str_parms_create_str(audio_cal));
+}
+
+static bool ma_set_lr_swap_l(
+    const struct ma_audio_cal_settings *audio_cal_settings, bool swap)
+{
+    return my_data->ma_set_lr_swap(g_ma_audio_cal_handle,
+                                   audio_cal_settings, swap);
+}
+
+static bool ma_set_volume_table_l(
+    const struct ma_audio_cal_settings *audio_cal_settings,
+    size_t num_streams, struct ma_state *volume_table)
+{
+    return my_data->ma_set_volume_table(g_ma_audio_cal_handle,
+                                        audio_cal_settings, num_streams,
+                                        volume_table);
+}
+
+static bool ma_set_param_l(
+    const struct ma_audio_cal_settings *audio_cal_settings,
+    unsigned int index, double value)
+{
+    return my_data->ma_set_param(g_ma_audio_cal_handle,
+                                 audio_cal_settings, index, value);
+}
+
+static inline bool valid_usecase(struct audio_usecase *usecase)
+{
+    if ((usecase->type == PCM_PLAYBACK) &&
+        /* supported usecases */
+        ((usecase->id == USECASE_AUDIO_PLAYBACK_DEEP_BUFFER) ||
+         (usecase->id == USECASE_AUDIO_PLAYBACK_LOW_LATENCY) ||
+         (usecase->id == USECASE_AUDIO_PLAYBACK_OFFLOAD)) &&
+        /* support devices */
+        ((usecase->devices & AUDIO_DEVICE_OUT_SPEAKER) ||
+         (usecase->devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
+         (audio_is_usb_out_device(usecase->devices) &&
+          audio_extn_ma_supported_usb())))
+        /* TODO: enable A2DP when it is ready */
+
+        return true;
+
+    ALOGV("%s: not support type %d usecase %d device %d",
+           __func__, usecase->type, usecase->id, usecase->devices);
+
+    return false;
+}
+
+// already hold lock
+static inline bool is_active()
+{
+    ma_stream_type_t i = 0;
+
+    for (i = 0; i < STREAM_MAX_TYPES; i++)
+        if (ma_cur_state_table[i].active)
+            return true;
+
+    return false;
+}
+
+static void ma_cal_init(struct ma_audio_cal_settings *ma_cal)
+{
+    ma_cal->version.major = AUDIO_CAL_SETTINGS_VERSION_MAJOR_DEFAULT;
+    ma_cal->version.minor = AUDIO_CAL_SETTINGS_VERSION_MINOR_DEFAULT;
+    ma_cal->common.app_type = APP_TYPE_DEFAULT;
+    ma_cal->common.device = DEVICE_DEFAULT;
+    ma_cal->effect_scope_flag = EFFECTIVE_SCOPE_ALL;
+}
+
+static bool check_and_send_all_audio_cal(struct audio_device *adev, ma_cmd_t cmd)
+{
+    int i = 0;
+    bool ret = false;
+    struct listnode *node;
+    struct audio_usecase *usecase;
+    struct ma_audio_cal_settings ma_cal;
+
+    ma_cal_init(&ma_cal);
+
+    list_for_each(node, &adev->usecase_list) {
+        usecase = node_to_item(node, struct audio_usecase, list);
+        if (valid_usecase(usecase)) {
+            ma_cal.common.app_type = usecase->stream.out->app_type_cfg.app_type;
+            ma_cal.common.device = usecase->stream.out->devices;
+            ALOGV("%s: send usecase(%d) app_type(%d) device(%d)",
+                      __func__, usecase->id, ma_cal.common.app_type,
+                      ma_cal.common.device);
+
+            switch (cmd) {
+                case MA_CMD_VOL:
+                    ret = ma_set_volume_table_l(&ma_cal, STREAM_MAX_TYPES,
+                                                ma_cur_state_table);
+                    if (ret)
+                        ALOGV("ma_set_volume_table_l success");
+                    else
+                        ALOGE("ma_set_volume_table_l returned with error.");
+
+                    ALOGV("%s: send volume table === Start", __func__);
+                    for (i = 0; i < STREAM_MAX_TYPES; i++)
+                        ALOGV("%s: stream(%d) volume(%f) active(%s)", __func__,
+                              i, ma_cur_state_table[i].vol,
+                              ma_cur_state_table[i].active ? "T" : "F");
+                    ALOGV("%s: send volume table === End", __func__);
+                    break;
+
+                case MA_CMD_SWAP_ENABLE:
+                    /* lr swap only enable for speaker path */
+                    if (ma_cal.common.device & AUDIO_DEVICE_OUT_SPEAKER) {
+                        ret = ma_set_lr_swap_l(&ma_cal, true);
+                        if (ret)
+                            ALOGV("ma_set_lr_swap_l enable returned with success.");
+                        else
+                            ALOGE("ma_set_lr_swap_l enable returned with error.");
+                    }
+                    break;
+
+                case MA_CMD_SWAP_DISABLE:
+                    ret = ma_set_lr_swap_l(&ma_cal, false);
+                    if (ret)
+                        ALOGV("ma_set_lr_swap_l disable returned with success.");
+                    else
+                        ALOGE("ma_set_lr_swap_l disable returned with error.");
+                    break;
+
+                case MA_CMD_SOFT_MUTE_ENABLE:
+                    if (usecase->id == USECASE_AUDIO_PLAYBACK_LOW_LATENCY) break;
+
+                    ma_cal.effect_scope_flag = EFFECTIVE_SCOPE_RTC;
+                    ret = ma_set_param_l(&ma_cal, MAAP_OUTPUT_GAIN, -96);
+                    if (!ret)
+                        ALOGE("soft mute enable returned with error.");
+                    break;
+
+                case MA_CMD_SOFT_MUTE_DISABLE:
+                    if (usecase->id == USECASE_AUDIO_PLAYBACK_LOW_LATENCY) break;
+
+                    ma_cal.effect_scope_flag = EFFECTIVE_SCOPE_RTC;
+                    ret = ma_set_param_l(&ma_cal, MAAP_OUTPUT_GAIN, 0);
+                    if (!ret)
+                        ALOGE("soft mute disable returned with error.");
+                    break;
+
+                default:
+                    ALOGE("%s: unsupported cmd %d", __func__, cmd);
+            }
+        }
+    }
+
+    return ret;
+}
+
+static bool find_sup_dev(char *name)
+{
+    char *token;
+    const char s[2] = ",";
+    bool ret = false;
+    char sup_devs[128];
+
+    // the rule of comforming suppored dev's name
+    // 1. Both string len are equal
+    // 2. Both string content are equal
+
+    strncpy(sup_devs, SUPPORT_DEV, sizeof(sup_devs));
+    token = strtok(sup_devs, s);
+    while (token != NULL) {
+        if (strncmp(token, name, strlen(token)) == 0 &&
+            strlen(token) == strlen(name)) {
+            ALOGD("%s: support dev %s", __func__, token);
+            ret = true;
+            break;
+        }
+        token = strtok(NULL, s);
+    }
+
+    return ret;
+}
+
+static void ma_set_swap_l(struct audio_device *adev, bool enable)
+{
+    if (enable)
+        check_and_send_all_audio_cal(adev, MA_CMD_SWAP_ENABLE);
+    else
+        check_and_send_all_audio_cal(adev, MA_CMD_SWAP_DISABLE);
+}
+
+static void ma_support_usb(bool enable, int card)
+{
+    char path[128];
+    char id[32];
+    int ret = 0;
+    int32_t fd = -1;
+    char *idd;
+
+    if (enable) {
+        ret = snprintf(path, sizeof(path), "/proc/asound/card%u/usbid", card);
+        if (ret < 0) {
+            ALOGE("%s: failed on snprintf (%d) to path %s\n",
+                  __func__, ret, path);
+            goto done;
+        }
+        fd = open(path, O_RDONLY);
+        if (fd < 0) {
+            ALOGE("%s: error failed to open id file %s error: %d\n",
+                  __func__, path, errno);
+            goto done;
+        }
+        if (read(fd, id, sizeof(id)) < 0) {
+            ALOGE("%s: file read error", __func__);
+            goto done;
+        }
+        //replace '\n' to '\0'
+        idd = strtok(id, "\n");
+
+        if (find_sup_dev(idd)) {
+            ALOGV("%s: support usbid is %s", __func__, id);
+            g_supported_dev |= SUPPORTED_USB;
+        } else
+            ALOGV("%s: usbid %s isn't found from %s", __func__, id, SUPPORT_DEV);
+    } else {
+        g_supported_dev &= ~SUPPORTED_USB;
+    }
+
+done:
+    if (fd >= 0) close(fd);
+}
+
+// adev_init lock held
+void audio_extn_ma_init(void *platform)
+{
+    ma_stream_type_t i = 0;
+    int ret = 0;
+    char lib_path[128] = {0};
+    char mps_path[128] = {0};
+    char cnf_path[128] = {0};
+    struct snd_card_split *snd_split_handle = NULL;
+    snd_split_handle = audio_extn_get_snd_card_split();
+
+    if (platform == NULL) {
+        ALOGE("%s: platform is NULL", __func__);
+        goto error;
+    }
+
+    if (my_data) { free(my_data); }
+    my_data = calloc(1, sizeof(struct ma_platform_data));
+    if (my_data == NULL) {
+        ALOGE("%s: ma_cal alloct fail", __func__);
+        goto error;
+    }
+
+    pthread_mutex_init(&my_data->lock, NULL);
+
+    my_data->platform = platform;
+    ret = snprintf(lib_path, sizeof(lib_path), "%s/%s", LIB_MA_PATH, LIB_MA_PARAM);
+    if (ret < 0) {
+        ALOGE("%s: snprintf failed for lib %s, ret %d", __func__, LIB_MA_PARAM, ret);
+        goto error;
+    }
+
+    my_data->waves_handle = dlopen(lib_path, RTLD_NOW);
+    if (my_data->waves_handle == NULL) {
+         ALOGE("%s: DLOPEN failed for %s", __func__, LIB_MA_PARAM);
+         goto error;
+    } else {
+         ALOGV("%s: DLOPEN successful for %s", __func__, LIB_MA_PARAM);
+
+         my_data->ma_param_init = (ma_param_init_t)dlsym(my_data->waves_handle,
+                                   MA_QDSP_PARAM_INIT);
+         if (!my_data->ma_param_init) {
+             ALOGE("%s: dlsym error %s for ma_param_init", __func__, dlerror());
+             goto error;
+         }
+
+         my_data->ma_param_deinit = (ma_param_deinit_t)dlsym(
+                                     my_data->waves_handle, MA_QDSP_PARAM_DEINIT);
+         if (!my_data->ma_param_deinit) {
+             ALOGE("%s: dlsym error %s for ma_param_deinit", __func__, dlerror());
+             goto error;
+         }
+
+         my_data->ma_set_lr_swap = (ma_set_lr_swap_t)dlsym(my_data->waves_handle,
+                                    MA_QDSP_SET_LR_SWAP);
+         if (!my_data->ma_set_lr_swap) {
+             ALOGE("%s: dlsym error %s for ma_set_lr_swap", __func__, dlerror());
+             goto error;
+         }
+
+         my_data->ma_set_sound_mode = (ma_set_sound_mode_t)dlsym(
+                                       my_data->waves_handle, MA_QDSP_SET_MODE);
+         if (!my_data->ma_set_sound_mode) {
+             ALOGE("%s: dlsym error %s for ma_set_sound_mode", __func__, dlerror());
+             goto error;
+         }
+
+         my_data->ma_set_volume = (ma_set_volume_t)dlsym(my_data->waves_handle,
+                                   MA_QDSP_SET_VOL);
+         if (!my_data->ma_set_volume) {
+             ALOGE("%s: dlsym error %s for ma_set_volume", __func__, dlerror());
+             goto error;
+         }
+
+         my_data->ma_set_volume_table = (ma_set_volume_table_t)dlsym(
+                                         my_data->waves_handle, MA_QDSP_SET_VOLT);
+         if (!my_data->ma_set_volume_table) {
+             ALOGE("%s: dlsym error %s for ma_set_volume_table", __func__, dlerror());
+             goto error;
+         }
+
+         my_data->ma_set_param = (ma_set_param_t)dlsym(
+                                  my_data->waves_handle, MA_QDSP_SET_PARAM);
+         if (!my_data->ma_set_param) {
+             ALOGE("%s: dlsym error %s for ma_set_param", __func__, dlerror());
+             goto error;
+         }
+    }
+
+    /* get preset table */
+    if (snd_split_handle == NULL) {
+        snprintf(mps_path, sizeof(mps_path), "%s/%s.mps",
+                 PRESET_PATH, MPS_BASE_STRING);
+    } else {
+        snprintf(mps_path, sizeof(mps_path), "%s/%s_%s.mps",
+                 PRESET_PATH, MPS_BASE_STRING, snd_split_handle->form_factor);
+    }
+
+    /* get config files */
+    if (snd_split_handle == NULL) {
+        snprintf(cnf_path, sizeof(cnf_path), "%s/%s.ini",
+                 PRESET_PATH, CONFIG_BASE_STRING);
+    } else {
+        snprintf(cnf_path, sizeof(cnf_path), "%s/%s_%s.ini",
+                 PRESET_PATH, CONFIG_BASE_STRING, snd_split_handle->form_factor);
+    }
+
+    /* check file */
+    if (access(mps_path, R_OK) < 0) {
+        ALOGW("%s: file %s isn't existed.", __func__, mps_path);
+        goto error;
+    } else
+        ALOGD("%s: Loading mps file: %s", __func__, mps_path);
+
+    /* TODO: check user preset table once the feature is enabled
+    if (access(USER_PRESET_PATH, F_OK) < 0 ){
+        ALOGW("%s: file %s isn't existed.", __func__, USER_PRESET_PATH);
+        goto error;
+    }
+    */
+
+    if (access(cnf_path, R_OK) < 0) {
+        ALOGW("%s: file %s isn't existed.", __func__, cnf_path);
+        goto error;
+    } else
+        ALOGD("%s: Loading ini file: %s", __func__, cnf_path);
+
+    /* init ma parameter */
+    if (my_data->ma_param_init(&g_ma_audio_cal_handle,
+                               mps_path,
+                               USER_PRESET_PATH, /* unused */
+                               cnf_path,
+                               &set_audio_cal)) {
+        if (!g_ma_audio_cal_handle) {
+            ALOGE("%s: ma parameters initialize failed", __func__);
+            my_data->ma_param_deinit(&g_ma_audio_cal_handle);
+            goto error;
+        }
+        ALOGD("%s: ma parameters initialize successful", __func__);
+    } else {
+        ALOGE("%s: ma parameters initialize failed", __func__);
+        goto error;
+    }
+
+    /* init volume table */
+    for (i = 0; i < STREAM_MAX_TYPES; i++) {
+        ma_cur_state_table[i].vol = 0.0;
+        ma_cur_state_table[i].active = false;
+    }
+
+    my_data->speaker_lr_swap = false;
+
+    return;
+
+error:
+    if (my_data) { free(my_data); }
+    my_data = NULL;
+}
+
+//adev_init lock held
+void audio_extn_ma_deinit()
+{
+    if (my_data) {
+        /* deinit ma parameter */
+        if (my_data->ma_param_deinit &&
+            my_data->ma_param_deinit(&g_ma_audio_cal_handle))
+            ALOGD("%s: ma parameters uninitialize successful", __func__);
+        else
+            ALOGD("%s: ma parameters uninitialize failed", __func__);
+
+        pthread_mutex_destroy(&my_data->lock);
+        free(my_data);
+        my_data = NULL;
+    }
+}
+
+// adev_init and adev lock held
+bool audio_extn_ma_set_state(struct audio_device *adev, int stream_type,
+                             float vol, bool active)
+{
+    bool ret = false;
+    bool first_enable = false;
+    struct ma_state pr_mstate;
+
+    if (stream_type >= STREAM_MAX_TYPES ||
+        stream_type < STREAM_MIN_TYPES) {
+        ALOGE("%s: stream_type %d out of range.", __func__, stream_type);
+        return ret;
+    }
+
+    if (!my_data) {
+        ALOGV("%s: maxxaudio isn't initialized.", __func__);
+        return ret;
+    }
+
+    ALOGV("%s: stream[%d] vol[%f] active[%s]",
+          __func__, stream_type, vol, active ? "true" : "false");
+
+    pr_mstate.vol = ma_cur_state_table[(ma_stream_type_t)stream_type].vol;
+    pr_mstate.active = ma_cur_state_table[(ma_stream_type_t)stream_type].active;
+
+    // update condition: vol or active state changes
+    if (pr_mstate.vol != vol || pr_mstate.active != active) {
+
+        pthread_mutex_lock(&my_data->lock);
+        // get active state before updating
+        first_enable = (!is_active()) && active;
+
+        ma_cur_state_table[(ma_stream_type_t)stream_type].vol = vol;
+        ma_cur_state_table[(ma_stream_type_t)stream_type].active = active;
+
+        if (first_enable) //all F -> one of T
+            ret = check_and_send_all_audio_cal(adev, MA_CMD_SOFT_MUTE_DISABLE);
+        else if (!is_active()) // all F
+            ret = check_and_send_all_audio_cal(adev, MA_CMD_SOFT_MUTE_ENABLE);
+
+        ret = check_and_send_all_audio_cal(adev, MA_CMD_VOL);
+
+        pthread_mutex_unlock(&my_data->lock);
+    }
+
+    return ret;
+}
+
+void audio_extn_ma_set_device(struct audio_usecase *usecase)
+{
+    int i = 0;
+    struct ma_audio_cal_settings ma_cal;
+
+    if (!my_data) {
+        ALOGV("%s: maxxaudio isn't initialized.", __func__);
+        return;
+    }
+
+    if (!valid_usecase(usecase)) {
+        ALOGV("%s: %d is not supported usecase", __func__, usecase->id);
+        return;
+    }
+
+    ma_cal_init(&ma_cal);
+
+    /* update audio_cal and send it */
+    ma_cal.common.app_type = usecase->stream.out->app_type_cfg.app_type;
+    ma_cal.common.device = usecase->stream.out->devices;
+    ALOGV("%s: send usecase(%d) app_type(%d) device(%d)",
+              __func__, usecase->id, ma_cal.common.app_type,
+              ma_cal.common.device);
+
+    pthread_mutex_lock(&my_data->lock);
+
+    if (is_active()) {
+        if (ma_cal.common.device & AUDIO_DEVICE_OUT_SPEAKER)
+            ma_set_swap_l(usecase->stream.out->dev, my_data->speaker_lr_swap);
+        else
+            ma_set_swap_l(usecase->stream.out->dev, false);
+
+        ALOGV("%s: send volume table === Start", __func__);
+        for (i = 0; i < STREAM_MAX_TYPES; i++)
+            ALOGV("%s: stream(%d) volume(%f) active(%s)", __func__, i,
+                   ma_cur_state_table[i].vol,
+                   ma_cur_state_table[i].active ? "T" : "F");
+        ALOGV("%s: send volume table === End", __func__);
+
+        if (!ma_set_volume_table_l(&ma_cal,
+                                   STREAM_MAX_TYPES,
+                                   ma_cur_state_table))
+            ALOGE("ma_set_volume_table_l returned with error.");
+        else
+            ALOGV("ma_set_volume_table_l success");
+
+    }
+    pthread_mutex_unlock(&my_data->lock);
+}
+
+void audio_extn_ma_set_parameters(struct audio_device *adev,
+                                  struct str_parms *parms)
+{
+    int ret;
+    int val;
+    char value[128];
+
+    // do LR swap and usb recognition
+    ret = str_parms_get_int(parms, "rotation", &val);
+    if (ret >= 0) {
+        if (!my_data) {
+            ALOGV("%s: maxxaudio isn't initialized.", __func__);
+            return;
+        }
+
+        switch (val) {
+        case 270:
+            my_data->speaker_lr_swap = true;
+            break;
+        case 0:
+        case 90:
+        case 180:
+            my_data->speaker_lr_swap = false;
+            break;
+        }
+        ma_set_swap_l(adev, my_data->speaker_lr_swap);
+    }
+
+    // check connect status
+    ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value,
+                            sizeof(value));
+    if (ret >= 0) {
+        audio_devices_t device = (audio_devices_t)strtoul(value, NULL, 10);
+        if (audio_is_usb_out_device(device)) {
+            ret = str_parms_get_str(parms, "card", value, sizeof(value));
+            if (ret >= 0) {
+                const int card = atoi(value);
+                ma_support_usb(true, card);
+            }
+        }
+    }
+
+    // check disconnect status
+    ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_DISCONNECT, value,
+                            sizeof(value));
+    if (ret >= 0) {
+        audio_devices_t device = (audio_devices_t)strtoul(value, NULL, 10);
+        if (audio_is_usb_out_device(device)) {
+            ret = str_parms_get_str(parms, "card", value, sizeof(value));
+            if (ret >= 0) {
+                const int card = atoi(value);
+                ma_support_usb(false, card /*useless*/);
+            }
+        }
+    }
+}
+
+bool audio_extn_ma_supported_usb()
+{
+    ALOGV("%s: current support 0x%x", __func__, g_supported_dev);
+    return (g_supported_dev & SUPPORTED_USB) ? true : false;
+}
diff --git a/hal/audio_extn/maxxaudio.h b/hal/audio_extn/maxxaudio.h
new file mode 100644
index 0000000..4c91107
--- /dev/null
+++ b/hal/audio_extn/maxxaudio.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MAXXAUDIO_H_
+#define MAXXAUDIO_H_
+
+#ifndef MAXXAUDIO_QDSP_ENABLED
+#define audio_extn_ma_init(platform)                                (0)
+#define audio_extn_ma_deinit()                                      (0)
+#define audio_extn_ma_set_state(adev, type, vol, active)            (false)
+#define audio_extn_ma_set_device(usecase)                           (0)
+#define audio_extn_ma_set_parameters(adev, param)                   (0)
+#define audio_extn_ma_supported_usb()                               (false)
+#else
+void audio_extn_ma_init(void *platform);
+void audio_extn_ma_deinit();
+bool audio_extn_ma_set_state(struct audio_device *adev, int stream_type,
+                             float vol, bool active);
+void audio_extn_ma_set_device(struct audio_usecase *usecase);
+void audio_extn_ma_set_parameters(struct audio_device *adev,
+                                  struct str_parms *parms);
+bool audio_extn_ma_supported_usb();
+#endif /* MAXXAUDIO_QDSP_ENABLED */
+
+#endif /* MAXXAUDIO_H_ */
+
diff --git a/hal/audio_extn/qaf.c b/hal/audio_extn/qaf.c
index ced137f..4ec524e 100644
--- a/hal/audio_extn/qaf.c
+++ b/hal/audio_extn/qaf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 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
@@ -104,7 +104,7 @@
 #include <sys/prctl.h>
 #include <cutils/properties.h>
 #include <cutils/str_parms.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <cutils/atomic.h>
 #include "audio_utils/primitives.h"
 #include "audio_hw.h"
@@ -2350,7 +2350,7 @@
      */
     out->devices = val;
 
-#ifndef SPLIT_A2DP_ENABLED
+#ifndef A2DP_OFFLOAD_ENABLED
     if (val == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) {
         //If device is BT then open the BT stream if not already opened.
         if ( audio_extn_bt_hal_get_output_stream(qaf_mod->bt_hdl) == NULL
@@ -2919,7 +2919,7 @@
         } else if (val & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) {
             p_qaf->bt_connect = 1;
             set_bt_configuration_to_module();
-#ifndef SPLIT_A2DP_ENABLED
+#ifndef A2DP_OFFLOAD_ENABLED
             for (k = 0; k < MAX_MM_MODULE_TYPE; k++) {
                 if (!p_qaf->qaf_mod[k].bt_hdl) {
                     DEBUG_MSG("Opening a2dp output...");
@@ -2970,7 +2970,7 @@
         //reconfig HDMI as end device (if connected)
         if(p_qaf->hdmi_connect)
             set_hdmi_configuration_to_module();
-#ifndef SPLIT_A2DP_ENABLED
+#ifndef A2DP_OFFLOAD_ENABLED
             DEBUG_MSG("Closing a2dp output...");
             for (k = 0; k < MAX_MM_MODULE_TYPE; k++) {
                 if (p_qaf->qaf_mod[k].bt_hdl) {
diff --git a/hal/audio_extn/sndmonitor.c b/hal/audio_extn/sndmonitor.c
index ba30d2d..b0495ea 100644
--- a/hal/audio_extn/sndmonitor.c
+++ b/hal/audio_extn/sndmonitor.c
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 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
@@ -47,11 +47,12 @@
 #include <dirent.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <pthread.h>
 #include <sys/stat.h>
 #include <sys/poll.h>
 #include <cutils/list.h>
 #include <cutils/hashmap.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <cutils/str_parms.h>
 #include <ctype.h>
 
@@ -69,6 +70,11 @@
 #define MAX_CPE_SLEEP_RETRY 2
 #define CPE_SLEEP_WAIT 100
 
+#define SPLI_STATE_PATH "/proc/wcd-spi-ac/svc-state"
+#define SLPI_MAGIC_NUM 0x3000
+#define MAX_SLPI_SLEEP_RETRY 2
+#define SLPI_SLEEP_WAIT_MS 100
+
 #define MAX_SLEEP_RETRY 100
 #define AUDIO_INIT_SLEEP_WAIT 100 /* 100 ms */
 
@@ -270,6 +276,31 @@
     if (line)
         free(line);
     fclose(fp);
+
+    /* Add fd to query for SLPI status */
+    if (access(SPLI_STATE_PATH, R_OK) < 0) {
+        ALOGV("access to %s failed: %s", SPLI_STATE_PATH, strerror(errno));
+    } else {
+        tries = MAX_SLPI_SLEEP_RETRY;
+        ALOGV("Open %s", SPLI_STATE_PATH);
+        while (tries--) {
+            if ((fd = open(SPLI_STATE_PATH, O_RDONLY)) < 0) {
+                ALOGW("Open %s failed %s, retry", SPLI_STATE_PATH,
+                      strerror(errno));
+                usleep(SLPI_SLEEP_WAIT_MS * 1000);
+                continue;
+            }
+            break;
+        }
+        if (fd >= 0) {
+            ret = add_new_sndcard(SLPI_MAGIC_NUM, fd);
+            if (ret != 0)
+                close(fd);
+            else
+                num_cards++;
+        }
+    }
+
     ALOGV("sndmonitor registerer num_cards %d", num_cards);
     sndmonitor.num_cards = num_cards;
     return num_cards ? 0 : -1;
@@ -410,7 +441,6 @@
 
     ALOGV("card num %d, new state %s", s->card, rd_buf);
 
-    bool is_cpe = (s->card >= CPE_MAGIC_NUM);
     if (strstr(rd_buf, "OFFLINE"))
         status = CARD_STATUS_OFFLINE;
     else if (strstr(rd_buf, "ONLINE"))
@@ -431,12 +461,18 @@
         return -1;
 
     char val[32] = {0};
-    // cpe actual card num is (card - MAGIC_NUM). so subtract accordingly
-    snprintf(val, sizeof(val), "%d,%s", s->card - (is_cpe ? CPE_MAGIC_NUM : 0),
-                 status == CARD_STATUS_ONLINE ? "ONLINE" : "OFFLINE");
-
-    if (str_parms_add_str(params, is_cpe ? "CPE_STATUS" : "SND_CARD_STATUS",
-                          val) < 0)
+    bool is_cpe = ((s->card >= CPE_MAGIC_NUM) && (s->card < SLPI_MAGIC_NUM));
+    bool is_slpi = (s->card == SLPI_MAGIC_NUM);
+    /*
+     * cpe actual card num is (card - CPE_MAGIC_NUM), so subtract accordingly.
+     * SLPI actual fd num is (card - SLPI_MAGIC_NUM), so subtract accordingly.
+     */
+    snprintf(val, sizeof(val), "%d,%s",
+        s->card - (is_cpe ? CPE_MAGIC_NUM : (is_slpi ? SLPI_MAGIC_NUM : 0)),
+                status == CARD_STATUS_ONLINE ? "ONLINE" : "OFFLINE");
+    if (str_parms_add_str(params,
+            is_cpe ? "CPE_STATUS" : (is_slpi ? "SLPI_STATUS" : "SND_CARD_STATUS"),
+                            val) < 0)
         return -1;
 
     int ret = notify(params);
@@ -623,7 +659,7 @@
 
 // --- public APIs --- //
 
-int audio_extn_snd_mon_deinit()
+int snd_mon_deinit()
 {
     if (!sndmonitor.initcheck)
         return -1;
@@ -639,7 +675,7 @@
     return 0;
 }
 
-int audio_extn_snd_mon_init()
+int snd_mon_init()
 {
     sndmonitor.notify = snd_mon_update;
     sndmonitor.target = NULL; // unused for now
@@ -681,7 +717,7 @@
     return -ENODEV;
 }
 
-int audio_extn_snd_mon_register_listener(void *stream, snd_mon_cb cb)
+int snd_mon_register_listener(void *stream, snd_mon_cb cb)
 {
     if (!sndmonitor.initcheck) {
         ALOGW("sndmonitor initcheck failed, cannot register");
@@ -691,7 +727,7 @@
     return add_listener(stream, cb);
 }
 
-int audio_extn_snd_mon_unregister_listener(void *stream)
+int snd_mon_unregister_listener(void *stream)
 {
     if (!sndmonitor.initcheck) {
         ALOGW("sndmonitor initcheck failed, cannot deregister");
diff --git a/hal/audio_extn/soundtrigger.c b/hal/audio_extn/soundtrigger.c
index aa1f7c0..e01b23b 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
@@ -34,7 +34,8 @@
 #include <stdbool.h>
 #include <stdlib.h>
 #include <dlfcn.h>
-#include <cutils/log.h>
+#include <pthread.h>
+#include <log/log.h>
 #include <unistd.h>
 #include "audio_hw.h"
 #include "audio_extn.h"
@@ -95,7 +96,9 @@
     SND_CARD_STATUS_OFFLINE,
     SND_CARD_STATUS_ONLINE,
     CPE_STATUS_OFFLINE,
-    CPE_STATUS_ONLINE
+    CPE_STATUS_ONLINE,
+    SLPI_STATUS_OFFLINE,
+    SLPI_STATUS_ONLINE
 } ssr_event_status_t;
 
 struct sound_trigger_session_info {
@@ -620,6 +623,18 @@
         strlcpy(event.u.str_value, value, sizeof(event.u.str_value));
         st_dev->st_callback(AUDIO_EVENT_SVA_EXEC_MODE, &event);
     }
+
+    ret = str_parms_get_str(params, "SLPI_STATUS", value, sizeof(value));
+    if (ret > 0) {
+        if (strstr(value, "OFFLINE")) {
+            event.u.status = SLPI_STATUS_OFFLINE;
+            st_dev->st_callback(AUDIO_EVENT_SSR, &event);
+        } else if (strstr(value, "ONLINE")) {
+            event.u.status = SLPI_STATUS_ONLINE;
+            st_dev->st_callback(AUDIO_EVENT_SSR, &event);
+        } else
+            ALOGE("%s: unknown SLPI status", __func__);
+    }
 }
 
 static int extract_sm_handle(const char *keys, char *paramstr) {
diff --git a/hal/audio_extn/source_track.c b/hal/audio_extn/source_track.c
index 2a9ba57..064fad8 100644
--- a/hal/audio_extn/source_track.c
+++ b/hal/audio_extn/source_track.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-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
@@ -32,7 +32,7 @@
 
 #include <errno.h>
 #include <math.h>
-#include <cutils/log.h>
+#include <log/log.h>
 
 #include "audio_hw.h"
 #include "platform.h"
@@ -47,7 +47,6 @@
 #include <log_utils.h>
 #endif
 
-#ifdef SOURCE_TRACKING_ENABLED
 /* Audio Paramater Key to identify the list of start angles.
  * Starting angle (in degrees) defines the boundary starting angle for each sector.
  */
@@ -143,7 +142,7 @@
     case SND_DEVICE_IN_HANDSET_DMIC_AEC:
     case SND_DEVICE_IN_HANDSET_DMIC_NS:
     case SND_DEVICE_IN_HANDSET_DMIC_AEC_NS:
-    case SND_DEVICE_IN_HANDSET_STEREO_DMIC:
+    case SND_DEVICE_IN_HANDSET_DMIC_STEREO:
     case SND_DEVICE_IN_HANDSET_QMIC:
     case SND_DEVICE_IN_HANDSET_TMIC_FLUENCE_PRO:
     case SND_DEVICE_IN_VOICE_DMIC:
@@ -500,7 +499,7 @@
     }
 }
 
-int audio_extn_get_soundfocus_data(const struct audio_device *adev,
+int get_soundfocus_data(const struct audio_device *adev,
                                    struct sound_focus_param *payload)
 {
     int ret = 0;
@@ -515,7 +514,7 @@
     return ret ;
 }
 
-int audio_extn_get_sourcetrack_data(const struct audio_device *adev,
+int get_sourcetrack_data(const struct audio_device *adev,
                               struct source_tracking_param *payload)
 {
     int ret = 0;
@@ -530,7 +529,7 @@
     return ret ;
 }
 
-void audio_extn_source_track_get_parameters(const struct audio_device *adev,
+void source_track_get_parameters(const struct audio_device *adev,
                                             struct str_parms *query,
                                             struct str_parms *reply)
 {
@@ -605,7 +604,7 @@
     return ret;
 }
 
-int audio_extn_set_soundfocus_data(struct audio_device *adev,
+int set_soundfocus_data(struct audio_device *adev,
                               struct sound_focus_param *payload)
 {
     int ret = 0;
@@ -616,7 +615,7 @@
     return ret ;
 }
 
-void audio_extn_source_track_set_parameters(struct audio_device *adev,
+void source_track_set_parameters(struct audio_device *adev,
                                             struct str_parms *parms)
 {
     int len, ret;
@@ -695,4 +694,3 @@
         free(value);
     return;
 }
-#endif /* SOURCE_TRACKING_ENABLED end */
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index 4067055..d123dd1 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.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.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -33,9 +33,10 @@
 
 #include <errno.h>
 #include <math.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <fcntl.h>
 #include <dirent.h>
+#include <pthread.h>
 #include "audio_hw.h"
 #include "platform.h"
 #include "platform_api.h"
@@ -116,7 +117,8 @@
 
 /*If calibration is in progress wait for 200 msec before querying
   for status again*/
-#define WAIT_FOR_GET_CALIB_STATUS (200 * 1000)
+#define WAIT_FOR_GET_CALIB_STATUS (200)
+#define GET_SPKR_PROT_CAL_TIMEOUT_MSEC (5000)
 
 /*Speaker states*/
 #define SPKR_NOT_CALIBRATED -1
@@ -144,6 +146,25 @@
 #define AUDIO_PARAMETER_KEY_FBSP_CFG_FTM_TIME       "fbsp_cfg_ftm_time"
 #define AUDIO_PARAMETER_KEY_FBSP_GET_FTM_PARAM      "get_ftm_param"
 
+// - external function dependency -
+static fp_read_line_from_file_t fp_read_line_from_file;
+static fp_get_usecase_from_list_t fp_get_usecase_from_list;
+static fp_enable_disable_snd_device_t fp_disable_snd_device;
+static fp_enable_disable_snd_device_t  fp_enable_snd_device;
+static fp_enable_disable_audio_route_t fp_disable_audio_route;
+static fp_enable_disable_audio_route_t fp_enable_audio_route;
+static fp_platform_set_snd_device_backend_t fp_platform_set_snd_device_backend;
+static fp_platform_get_snd_device_name_extn_t fp_platform_get_snd_device_name_extn;
+static fp_platform_get_default_app_type_v2_t fp_platform_get_default_app_type_v2;
+static fp_platform_send_audio_calibration_t fp_platform_send_audio_calibration;
+static fp_platform_get_pcm_device_id_t fp_platform_get_pcm_device_id;
+static fp_platform_get_snd_device_name_t fp_platform_get_snd_device_name;
+static fp_platform_spkr_prot_is_wsa_analog_mode_t fp_platform_spkr_prot_is_wsa_analog_mode;
+static fp_platform_get_snd_device_t fp_platform_get_vi_feedback_snd_device;
+static fp_platform_get_snd_device_t fp_platform_get_spkr_prot_snd_device;
+static fp_platform_check_and_set_codec_backend_cfg_t fp_platform_check_and_set_codec_backend_cfg;
+static fp_audio_extn_is_vbat_enabled_t fp_audio_extn_is_vbat_enabled;
+
 /*Modes of Speaker Protection*/
 enum speaker_protection_mode {
     SPKR_PROTECTION_DISABLED = -1,
@@ -294,6 +315,10 @@
 static int vi_feed_no_channels;
 static struct spkr_tz_names tz_names;
 
+int get_spkr_prot_snd_device(snd_device_t snd_device) {
+    return snd_device;
+}
+
 /*===========================================================================
 FUNCTION get_tzn
 
@@ -342,7 +367,7 @@
                 continue;
             snprintf(name, MAX_PATH, TZ_TYPE, tzn);
             ALOGV("Opening %s\n", name);
-            read_line_from_file(name, buf, sizeof(buf));
+            fp_read_line_from_file(name, buf, sizeof(buf));
             if (strlen(buf) > 0)
                 buf[strlen(buf) - 1] = '\0';
             if (!strcmp(buf, sensor_name)) {
@@ -375,7 +400,7 @@
    }
 }
 
-void audio_extn_spkr_prot_calib_cancel(void *adev)
+void spkr_prot_calib_cancel(void *adev)
 {
     pthread_t threadid;
     struct audio_usecase *uc_info;
@@ -385,7 +410,7 @@
         ALOGE("%s: Invalid params", __func__);
         return;
     }
-    uc_info = get_usecase_from_list(adev, USECASE_AUDIO_SPKR_CALIB_RX);
+    uc_info = fp_get_usecase_from_list(adev, USECASE_AUDIO_SPKR_CALIB_RX);
     if (uc_info) {
             pthread_mutex_lock(&handle.mutex_spkr_prot);
             pthread_mutex_lock(&handle.spkr_calib_cancelack_mutex);
@@ -500,8 +525,14 @@
         ALOGD("%s: quick calibration enabled", __func__);
         cal_data.cal_type.cal_info.quick_calib_flag = 1;
     } else {
-        ALOGD("%s: quick calibration disabled", __func__);
-        cal_data.cal_type.cal_info.quick_calib_flag = 0;
+        property_get("persist.spkr.cal.duration", value, "0");
+        if (atoi(value) > 0) {
+            ALOGD("%s: quick calibration enabled", __func__);
+            cal_data.cal_type.cal_info.quick_calib_flag = 1;
+        } else {
+            ALOGD("%s: quick calibration disabled", __func__);
+            cal_data.cal_type.cal_info.quick_calib_flag = 0;
+        }
     }
 
     cal_data.cal_type.cal_data.mem_handle = -1;
@@ -558,12 +589,12 @@
         pthread_cond_destroy(&handle.spkr_prot_thermalsync);
     }
 }
-static void audio_extn_check_wsa(struct audio_device *adev,
+static void check_wsa(struct audio_device *adev,
                 unsigned int num_of_spkrs, bool *wsa_is_8815)
 {
     unsigned int i = 0;
     if (!handle.wsa_found ||
-        platform_spkr_prot_is_wsa_analog_mode(adev)){
+        fp_platform_spkr_prot_is_wsa_analog_mode(adev)){
         for (i = 0; i < num_of_spkrs; i++)
             wsa_is_8815[i] = false;
 
@@ -579,7 +610,7 @@
         wsa_is_8815[SP_V2_SPKR_2] = true;
 }
 
-int audio_extn_set_wcd_boost_max_state(struct audio_device *adev,
+int set_wcd_boost_max_state(struct audio_device *adev,
                 int boost_max_state, int wsa_num)
 {
     struct mixer_ctl *ctl = NULL;
@@ -605,7 +636,7 @@
     return 0;
 }
 
-int audio_extn_set_wsa_boost_level(struct audio_device *adev,
+int set_wsa_boost_level(struct audio_device *adev,
                 int wsa_num, int boost_table_index)
 {
     struct mixer_ctl *ctl;
@@ -635,7 +666,7 @@
     return 0;
 }
 
-static int audio_extn_spkr_boost_update(struct audio_device *adev,
+static int spkr_boost_update(struct audio_device *adev,
                 unsigned int wsa_num, unsigned int *index, bool spkr2_is_mono)
 {
     float dcr = 0;
@@ -672,14 +703,14 @@
     if (spkr2_is_mono)
         wsa_to_set = SP_V2_SPKR_2;
 
-    ret = audio_extn_set_wcd_boost_max_state(adev, boost_max_state, wsa_to_set);
+    ret = set_wcd_boost_max_state(adev, boost_max_state, wsa_to_set);
     if (ret < 0) {
         ALOGE("%s: failed to set wcd max boost state.",
             __func__);
         return -EINVAL;
     }
 
-    ret = audio_extn_set_wsa_boost_level(adev, wsa_to_set, r0_index);
+    ret = set_wsa_boost_level(adev, wsa_to_set, r0_index);
     if (ret < 0) {
         ALOGE("%s: failed to set wsa boost level.",
             __func__);
@@ -691,7 +722,7 @@
     return 0;
 }
 
-static void audio_extn_set_boost_and_limiter(struct audio_device *adev,
+static void set_boost_and_limiter(struct audio_device *adev,
                 bool spv3_enable, unsigned int afe_api_version)
 {
     int chn = 0;
@@ -707,7 +738,7 @@
      * follow lookup table based on R0 impediance regardless
      * of spv2 or spv3.
      */
-    audio_extn_check_wsa(adev, vi_feed_no_channels, wsa_is_8815);
+    check_wsa(adev, vi_feed_no_channels, wsa_is_8815);
     if (vi_feed_no_channels == 1 && wsa_is_8815[SP_V2_SPKR_2])
         spkr2_is_mono_speaker = true;
     /*
@@ -720,7 +751,7 @@
         if (spkr2_is_mono_speaker)
             chn_in_use = SP_V2_SPKR_2;
         if (wsa_is_8815[chn_in_use] &&
-            !audio_extn_spkr_boost_update(adev, chn,
+            !spkr_boost_update(adev, chn,
                                     &r0_index, spkr2_is_mono_speaker)) {
             handle.limiter_th[chn] = spv3_limiter_th_q27_table[r0_index];
             handle.sp_version = SP_V3;
@@ -749,6 +780,8 @@
     int32_t pcm_dev_rx_id = -1, pcm_dev_tx_id = -1;
     struct timespec ts;
     bool acquire_device = false;
+    int retry_duration;
+    int app_type = 0;
 
     memset(&status, 0, sizeof(status));
     memset(&protCfg, 0, sizeof(protCfg));
@@ -783,21 +816,21 @@
     uc_info_rx->type = PCM_PLAYBACK;
     uc_info_rx->in_snd_device = SND_DEVICE_NONE;
     uc_info_rx->stream.out = adev->primary_output;
-    if (audio_extn_is_vbat_enabled())
+    if (fp_audio_extn_is_vbat_enabled())
         uc_info_rx->out_snd_device = SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT;
     else
         uc_info_rx->out_snd_device = SND_DEVICE_OUT_SPEAKER_PROTECTED;
     disable_rx = true;
     list_add_tail(&adev->usecase_list, &uc_info_rx->list);
-    platform_check_and_set_codec_backend_cfg(adev, uc_info_rx,
+    fp_platform_check_and_set_codec_backend_cfg(adev, uc_info_rx,
                                              uc_info_rx->out_snd_device);
-    if (audio_extn_is_vbat_enabled())
-         enable_snd_device(adev, SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT);
+    if (fp_audio_extn_is_vbat_enabled())
+         fp_enable_snd_device(adev, SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT);
     else
-         enable_snd_device(adev, SND_DEVICE_OUT_SPEAKER_PROTECTED);
-    enable_audio_route(adev, uc_info_rx);
+         fp_enable_snd_device(adev, SND_DEVICE_OUT_SPEAKER_PROTECTED);
+    fp_enable_audio_route(adev, uc_info_rx);
 
-    pcm_dev_rx_id = platform_get_pcm_device_id(uc_info_rx->id, PCM_PLAYBACK);
+    pcm_dev_rx_id = fp_platform_get_pcm_device_id(uc_info_rx->id, PCM_PLAYBACK);
     ALOGV("%s: pcm device id %d", __func__, pcm_dev_rx_id);
     if (pcm_dev_rx_id < 0) {
         ALOGE("%s: Invalid pcm device for usecase (%d)",
@@ -827,10 +860,10 @@
 
     disable_tx = true;
     list_add_tail(&adev->usecase_list, &uc_info_tx->list);
-    enable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK);
-    enable_audio_route(adev, uc_info_tx);
+    fp_enable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK);
+    fp_enable_audio_route(adev, uc_info_tx);
 
-    pcm_dev_tx_id = platform_get_pcm_device_id(uc_info_tx->id, PCM_CAPTURE);
+    pcm_dev_tx_id = fp_platform_get_pcm_device_id(uc_info_tx->id, PCM_CAPTURE);
     ALOGV("%s: pcm device id %d", __func__, pcm_dev_tx_id);
     if (pcm_dev_tx_id < 0) {
         ALOGE("%s: Invalid pcm device for usecase (%d)",
@@ -873,7 +906,9 @@
     }
     if (acdb_fd > 0) {
         status.status = -EINVAL;
-        while (!get_spkr_prot_cal(acdb_fd, &status)) {
+        retry_duration = 0;
+        while (!get_spkr_prot_cal(acdb_fd, &status) &&
+                retry_duration < GET_SPKR_PROT_CAL_TIMEOUT_MSEC) {
             /*sleep for 200 ms to check for status check*/
             if (!status.status) {
                 ALOGD("%s: spkr_prot_thread calib Success R0 %d %d",
@@ -896,7 +931,8 @@
                 break;
             } else if (status.status == -EAGAIN) {
                   ALOGV("%s: spkr_prot_thread try again", __func__);
-                  usleep(WAIT_FOR_GET_CALIB_STATUS);
+                  usleep(WAIT_FOR_GET_CALIB_STATUS * 1000);
+                  retry_duration += WAIT_FOR_GET_CALIB_STATUS;
             } else {
                 ALOGE("%s: spkr_prot_thread get failed status %d",
                 __func__, status.status);
@@ -910,6 +946,17 @@
         if (handle.pcm_tx)
             pcm_close(handle.pcm_tx);
         handle.pcm_tx = NULL;
+        /* Clear TX calibration to handset mic */
+        if (uc_info_tx != NULL) {
+            ALOGD("%s: UC Info TX is not NULL, updating and sending calibration",
+                  __func__);
+            uc_info_tx->in_snd_device = SND_DEVICE_IN_HANDSET_MIC;
+            uc_info_tx->out_snd_device = SND_DEVICE_NONE;
+            app_type = fp_platform_get_default_app_type_v2(adev->platform,
+                                                PCM_CAPTURE);
+            fp_platform_send_audio_calibration(adev->platform, uc_info_tx,
+                                                    app_type, 8000);
+        }
         if (!status.status) {
             protCfg.mode = MSM_SPKR_PROT_CALIBRATED;
             protCfg.r0[SP_V2_SPKR_1] = status.r0[SP_V2_SPKR_1];
@@ -935,16 +982,16 @@
         }
         if (disable_rx) {
             list_remove(&uc_info_rx->list);
-            if (audio_extn_is_vbat_enabled())
-                disable_snd_device(adev, SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT);
+            if (fp_audio_extn_is_vbat_enabled())
+                fp_disable_snd_device(adev, SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT);
             else
-                disable_snd_device(adev, SND_DEVICE_OUT_SPEAKER_PROTECTED);
-            disable_audio_route(adev, uc_info_rx);
+                fp_disable_snd_device(adev, SND_DEVICE_OUT_SPEAKER_PROTECTED);
+            fp_disable_audio_route(adev, uc_info_rx);
         }
         if (disable_tx) {
             list_remove(&uc_info_tx->list);
-            disable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK);
-            disable_audio_route(adev, uc_info_tx);
+            fp_disable_snd_device(adev, SND_DEVICE_IN_CAPTURE_VI_FEEDBACK);
+            fp_disable_audio_route(adev, uc_info_tx);
         }
         if (uc_info_rx) free(uc_info_rx);
         if (uc_info_tx) free(uc_info_tx);
@@ -1004,6 +1051,11 @@
     property_get("persist.vendor.audio.spkr.cal.duration", value, "0");
     if (atoi(value) > 0)
         min_idle_time = atoi(value);
+    else {
+        property_get("persist.spkr.cal.duration", value, "0");
+        if (atoi(value) > 0)
+            min_idle_time = atoi(value);
+    }
     handle.speaker_prot_threadid = pthread_self();
     ALOGD("spkr_prot_thread enable prot Entry");
     acdb_fd = open("/dev/msm_audio_cal",O_RDWR | O_NONBLOCK);
@@ -1065,7 +1117,7 @@
                 handle.spkr_prot_mode = MSM_SPKR_PROT_CALIBRATED;
             close(acdb_fd);
 
-            audio_extn_set_boost_and_limiter(adev, spv3_enable, afe_api_version);
+            set_boost_and_limiter(adev, spv3_enable, afe_api_version);
 
             pthread_exit(0);
             return NULL;
@@ -1249,7 +1301,7 @@
         dlclose(handle.thermal_handle);
     handle.thermal_handle = NULL;
 
-    audio_extn_set_boost_and_limiter(adev, spv3_enable, afe_api_version);
+    set_boost_and_limiter(adev, spv3_enable, afe_api_version);
 
     pthread_exit(0);
     return NULL;
@@ -1266,7 +1318,7 @@
     return 0;
 }
 
-void audio_extn_spkr_prot_set_parameters(struct str_parms *parms,
+void spkr_prot_set_parameters(struct str_parms *parms,
                                          char *value, int len)
 {
     int err;
@@ -1505,7 +1557,7 @@
     pthread_mutex_unlock(&handle.cal_wait_cond_mutex);
 }
 
-int audio_extn_fbsp_set_parameters(struct str_parms *parms)
+int fbsp_set_parameters(struct str_parms *parms)
 {
     int ret= 0 , err;
     char *value = NULL;
@@ -1594,7 +1646,7 @@
     return ret;
 }
 
-int audio_extn_fbsp_get_parameters(struct str_parms *query,
+int fbsp_get_parameters(struct str_parms *query,
                                    struct str_parms *reply)
 {
     int err = 0;
@@ -1620,7 +1672,7 @@
     return err;
 }
 
-void audio_extn_spkr_prot_init(void *adev)
+void spkr_prot_init(void *adev, spkr_prot_init_config_t spkr_prot_init_config_val)
 {
     char value[PROPERTY_VALUE_MAX];
     int result = 0;
@@ -1631,16 +1683,38 @@
         ALOGE("%s: Invalid params", __func__);
         return;
     }
-    property_get("persist.vendor.audio.speaker.prot.enable", value, "");
     handle.spkr_prot_enable = false;
+    if ((property_get("persist.vendor.audio.speaker.prot.enable",
+                      value, NULL) > 0) ||
+        (property_get("persist.speaker.prot.enable",
+                      value, NULL) > 0)) {
+        if (!strncmp("true", value, 4))
+             handle.spkr_prot_enable = true;
+    }
     handle.init_check = false;
     handle.thread_exit = false;
-    if (!strncmp("true", value, 4))
-       handle.spkr_prot_enable = true;
     if (!handle.spkr_prot_enable) {
         ALOGD("%s: Speaker protection disabled", __func__);
         return;
     }
+    // init function pointers
+    fp_read_line_from_file = spkr_prot_init_config_val.fp_read_line_from_file;
+    fp_get_usecase_from_list =  spkr_prot_init_config_val.fp_get_usecase_from_list;
+    fp_disable_snd_device = spkr_prot_init_config_val.fp_disable_snd_device;
+    fp_enable_snd_device = spkr_prot_init_config_val.fp_enable_snd_device;
+    fp_disable_audio_route = spkr_prot_init_config_val.fp_disable_audio_route;
+    fp_enable_audio_route = spkr_prot_init_config_val.fp_enable_audio_route;
+    fp_platform_set_snd_device_backend = spkr_prot_init_config_val.fp_platform_set_snd_device_backend;
+    fp_platform_get_snd_device_name_extn = spkr_prot_init_config_val.fp_platform_get_snd_device_name_extn;
+    fp_platform_get_default_app_type_v2 = spkr_prot_init_config_val.fp_platform_get_default_app_type_v2;
+    fp_platform_send_audio_calibration = spkr_prot_init_config_val.fp_platform_send_audio_calibration;
+    fp_platform_get_pcm_device_id = spkr_prot_init_config_val.fp_platform_get_pcm_device_id;
+    fp_platform_get_snd_device_name = spkr_prot_init_config_val.fp_platform_get_snd_device_name;
+    fp_platform_spkr_prot_is_wsa_analog_mode = spkr_prot_init_config_val.fp_platform_spkr_prot_is_wsa_analog_mode;
+    fp_platform_get_vi_feedback_snd_device = spkr_prot_init_config_val.fp_platform_get_vi_feedback_snd_device;
+    fp_platform_get_spkr_prot_snd_device = spkr_prot_init_config_val.fp_platform_get_spkr_prot_snd_device;
+    fp_platform_check_and_set_codec_backend_cfg = spkr_prot_init_config_val.fp_platform_check_and_set_codec_backend_cfg;
+    fp_audio_extn_is_vbat_enabled = spkr_prot_init_config_val.fp_audio_extn_is_vbat_enabled;
     handle.adev_handle = adev;
     handle.spkr_prot_mode = MSM_SPKR_PROT_DISABLED;
     handle.spkr_processing_state = SPKR_PROCESSING_IN_IDLE;
@@ -1648,6 +1722,11 @@
     handle.trigger_cal = false;
     /* HAL for speaker protection is always calibrating for stereo usecase*/
     vi_feed_no_channels = spkr_vi_channels(adev);
+    if (vi_feed_no_channels < 0) {
+        ALOGE("%s: no of channels negative !!", __func__);
+        /* limit the number of channels to 2*/
+        vi_feed_no_channels = 2;
+    }
 
     pthread_condattr_init(&attr);
     pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
@@ -1655,7 +1734,7 @@
     pthread_mutex_init(&handle.cal_wait_cond_mutex, NULL);
     pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
     if (handle.wsa_found) {
-        if (platform_spkr_prot_is_wsa_analog_mode(adev) == 1) {
+        if (fp_platform_spkr_prot_is_wsa_analog_mode(adev) == 1) {
             ALOGD("%s: WSA analog mode", __func__);
             pcm_config_skr_prot.channels = WSA_ANALOG_MODE_CHANNELS;
         }
@@ -1735,14 +1814,14 @@
         char platform[PROPERTY_VALUE_MAX];
         property_get("ro.board.platform", platform, "");
         if (!strncmp("apq8084", platform, sizeof("apq8084"))) {
-            platform_set_snd_device_backend(SND_DEVICE_OUT_VOICE_SPEAKER,
+            fp_platform_set_snd_device_backend(SND_DEVICE_OUT_VOICE_SPEAKER,
                                             "speaker-protected",
                                             "SLIMBUS_0_RX");
         }
     }
 }
 
-int audio_extn_spkr_prot_deinit()
+int spkr_prot_deinit()
 {
     int result = 0;
 
@@ -1763,7 +1842,7 @@
     return 0;
 }
 
-int audio_extn_select_spkr_prot_cal_data(snd_device_t snd_device)
+int select_spkr_prot_cal_data(snd_device_t snd_device)
 {
     struct audio_cal_info_spk_prot_cfg protCfg;
     int acdb_fd = -1;
@@ -1803,13 +1882,14 @@
     return ret;
 }
 
-int audio_extn_spkr_prot_start_processing(snd_device_t snd_device)
+int spkr_prot_start_processing(snd_device_t snd_device)
 {
     struct audio_usecase *uc_info_tx;
     struct audio_device *adev = handle.adev_handle;
     int32_t pcm_dev_tx_id = -1, ret = 0;
     snd_device_t in_snd_device;
     char device_name[DEVICE_NAME_MAX_SIZE] = {0};
+    int app_type = 0;
 
     ALOGV("%s: Entry", __func__);
     /* cancel speaker calibration */
@@ -1817,23 +1897,23 @@
        ALOGE("%s: Invalid params", __func__);
        return -EINVAL;
     }
-    snd_device = platform_get_spkr_prot_snd_device(snd_device);
+    snd_device = fp_platform_get_spkr_prot_snd_device(snd_device);
     if (handle.spkr_prot_mode == MSM_SPKR_PROT_CALIBRATED) {
-        ret = audio_extn_select_spkr_prot_cal_data(snd_device);
+        ret = select_spkr_prot_cal_data(snd_device);
         if (ret) {
             ALOGE("%s: Setting speaker protection cal data failed", __func__);
             return ret;
         }
     }
 
-    in_snd_device = platform_get_vi_feedback_snd_device(snd_device);
+    in_snd_device = fp_platform_get_vi_feedback_snd_device(snd_device);
     spkr_prot_set_spkrstatus(true);
     uc_info_tx = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
     if (!uc_info_tx) {
         return -ENOMEM;
     }
 
-    if (platform_get_snd_device_name_extn(adev->platform, snd_device, device_name) < 0) {
+    if (fp_platform_get_snd_device_name_extn(adev->platform, snd_device, device_name) < 0) {
         ALOGE("%s: Invalid sound device returned", __func__);
         return -EINVAL;
     }
@@ -1850,10 +1930,10 @@
         uc_info_tx->out_snd_device = SND_DEVICE_NONE;
         handle.pcm_tx = NULL;
         list_add_tail(&adev->usecase_list, &uc_info_tx->list);
-        enable_snd_device(adev, in_snd_device);
-        enable_audio_route(adev, uc_info_tx);
+        fp_enable_snd_device(adev, in_snd_device);
+        fp_enable_audio_route(adev, uc_info_tx);
 
-        pcm_dev_tx_id = platform_get_pcm_device_id(uc_info_tx->id, PCM_CAPTURE);
+        pcm_dev_tx_id = fp_platform_get_pcm_device_id(uc_info_tx->id, PCM_CAPTURE);
         if (pcm_dev_tx_id < 0) {
             ALOGE("%s: Invalid pcm device for usecase (%d)",
                   __func__, uc_info_tx->id);
@@ -1875,7 +1955,18 @@
     }
 
 exit:
-     if (ret) {
+    /* Clear VI feedback cal and replace with handset MIC  */
+    if (uc_info_tx != NULL) {
+        ALOGD("%s: UC Info TX is not NULL, updating and sending calibration",
+              __func__);
+        uc_info_tx->in_snd_device = SND_DEVICE_IN_HANDSET_MIC;
+        uc_info_tx->out_snd_device = SND_DEVICE_NONE;
+        app_type = fp_platform_get_default_app_type_v2(adev->platform,
+                                            PCM_CAPTURE);
+        fp_platform_send_audio_calibration(adev->platform, uc_info_tx,
+                                                app_type, 8000);
+    }
+    if (ret) {
         if (handle.pcm_tx)
             pcm_close(handle.pcm_tx);
         handle.pcm_tx = NULL;
@@ -1884,8 +1975,8 @@
         uc_info_tx->type = PCM_CAPTURE;
         uc_info_tx->in_snd_device = in_snd_device;
         uc_info_tx->out_snd_device = SND_DEVICE_NONE;
-        disable_snd_device(adev, in_snd_device);
-        disable_audio_route(adev, uc_info_tx);
+        fp_disable_snd_device(adev, in_snd_device);
+        fp_disable_audio_route(adev, uc_info_tx);
         free(uc_info_tx);
     } else
         handle.spkr_processing_state = SPKR_PROCESSING_IN_PROGRESS;
@@ -1894,27 +1985,27 @@
     return ret;
 }
 
-void audio_extn_spkr_prot_stop_processing(snd_device_t snd_device)
+void spkr_prot_stop_processing(snd_device_t snd_device)
 {
     struct audio_usecase *uc_info_tx;
     struct audio_device *adev = handle.adev_handle;
     snd_device_t in_snd_device;
 
     ALOGV("%s: Entry", __func__);
-    snd_device = platform_get_spkr_prot_snd_device(snd_device);
+    snd_device = fp_platform_get_spkr_prot_snd_device(snd_device);
     spkr_prot_set_spkrstatus(false);
-    in_snd_device = platform_get_vi_feedback_snd_device(snd_device);
+    in_snd_device = fp_platform_get_vi_feedback_snd_device(snd_device);
 
     pthread_mutex_lock(&handle.mutex_spkr_prot);
     if (adev && handle.spkr_processing_state == SPKR_PROCESSING_IN_PROGRESS) {
-        uc_info_tx = get_usecase_from_list(adev, USECASE_AUDIO_SPKR_CALIB_TX);
+        uc_info_tx = fp_get_usecase_from_list(adev, USECASE_AUDIO_SPKR_CALIB_TX);
         if (handle.pcm_tx)
             pcm_close(handle.pcm_tx);
         handle.pcm_tx = NULL;
-        disable_snd_device(adev, in_snd_device);
+        fp_disable_snd_device(adev, in_snd_device);
         if (uc_info_tx) {
             list_remove(&uc_info_tx->list);
-            disable_audio_route(adev, uc_info_tx);
+            fp_disable_audio_route(adev, uc_info_tx);
             free(uc_info_tx);
         }
     }
@@ -1922,12 +2013,18 @@
     pthread_mutex_unlock(&handle.mutex_spkr_prot);
     if (adev)
         audio_route_reset_and_update_path(adev->audio_route,
-                                      platform_get_snd_device_name(snd_device));
+                                      fp_platform_get_snd_device_name(snd_device));
     ALOGV("%s: Exit", __func__);
 }
 
-bool audio_extn_spkr_prot_is_enabled()
+bool spkr_prot_is_enabled()
 {
     return handle.spkr_prot_enable;
 }
+
+void spkr_prot_is_enabled_init()
+{
+
+}
+
 #endif /*SPKR_PROT_ENABLED*/
diff --git a/hal/audio_extn/ssr.c b/hal/audio_extn/ssr.c
index 15eaaef..d83b508 100644
--- a/hal/audio_extn/ssr.c
+++ b/hal/audio_extn/ssr.c
@@ -26,7 +26,7 @@
 #include <stdlib.h>
 #include <dlfcn.h>
 #include <cutils/str_parms.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <pthread.h>
 #include <cutils/sched_policy.h>
 #include <sys/resource.h>
@@ -44,7 +44,6 @@
 #include <log_utils.h>
 #endif
 
-#ifdef SSR_ENABLED
 #define COEFF_ARRAY_SIZE            4
 #define FILT_SIZE                   ((512+1)* 6)  /* # ((FFT bins)/2+1)*numOutputs */
 #define SSR_CHANNEL_OUTPUT_NUM      6
@@ -313,7 +312,7 @@
     return ret;
 }
 
-void audio_extn_ssr_update_enabled()
+void ssr_update_enabled()
 {
     char ssr_enabled[PROPERTY_VALUE_MAX] = "false";
 
@@ -327,7 +326,7 @@
     }
 }
 
-bool audio_extn_ssr_get_enabled()
+bool ssr_get_enabled()
 {
     ALOGV("%s: is_ssr_enabled:%d is_ssr_mode_on:%d ", __func__, ssrmod.is_ssr_enabled, ssrmod.is_ssr_mode_on);
 
@@ -337,13 +336,13 @@
     return false;
 }
 
-bool  audio_extn_ssr_check_usecase(struct stream_in *in) {
+bool  ssr_check_usecase(struct stream_in *in) {
     int ret = false;
     int channel_count = audio_channel_count_from_in_mask(in->channel_mask);
     audio_devices_t devices = in->device;
     audio_source_t source = in->source;
 
-    if ((audio_extn_ssr_get_enabled()) &&
+    if ((ssr_get_enabled()) &&
             ((channel_count == 2) || (channel_count == 6)) &&
             ((AUDIO_SOURCE_MIC == source) || (AUDIO_SOURCE_CAMCORDER == source)) &&
             ((AUDIO_DEVICE_IN_BUILTIN_MIC == devices) || (AUDIO_DEVICE_IN_BACK_MIC == devices)) &&
@@ -355,39 +354,6 @@
     return ret;
 }
 
-int audio_extn_ssr_set_usecase(struct stream_in *in,
-                               struct audio_config *config,
-                               bool *update_params)
-{
-    int ret = -EINVAL;
-    int channel_count = audio_channel_count_from_in_mask(in->channel_mask);
-    audio_channel_representation_t representation =
-                  audio_channel_mask_get_representation(in->channel_mask);
-    *update_params = false;
-
-    if (audio_extn_ssr_check_usecase(in)) {
-
-        if (representation == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
-            /* update params in case channel representation index.
-             * on returning error, flinger will retry with supported representation passed
-             */
-            ALOGD("%s: SSR supports only channel representation position, channel_mask(%#x)"
-                              ,__func__, config->channel_mask);
-            config->channel_mask = AUDIO_CHANNEL_IN_6;
-            ret = 0;
-            *update_params = true;
-        } else {
-            if (!audio_extn_ssr_init(in, channel_count)) {
-                ALOGD("%s: Created SSR session succesfully", __func__);
-                ret = 0;
-            } else {
-                ALOGE("%s: Unable to start SSR record session", __func__);
-            }
-        }
-    }
-    return ret;
-}
-
 static void pcm_buffer_queue_push(struct pcm_buffer_queue **queue,
                                   struct pcm_buffer_queue *node)
 {
@@ -440,12 +406,58 @@
     }
 }
 
-struct stream_in *audio_extn_ssr_get_stream()
+struct stream_in *ssr_get_stream()
 {
     return ssrmod.in;
 }
 
-int32_t audio_extn_ssr_init(struct stream_in *in, int num_out_chan)
+int32_t ssr_deinit()
+{
+    ALOGV("%s: entry", __func__);
+    deinit_ssr_process_thread();
+
+    if (ssrmod.drc_obj) {
+        ssrmod.drc_deinit(ssrmod.drc_obj);
+        ssrmod.drc_obj = NULL;
+    }
+
+    if (ssrmod.surround_obj) {
+
+        if (ssrmod.ssr_3mic) {
+            ssrmod.surround_rec_deinit(ssrmod.surround_obj);
+            ssrmod.surround_obj = NULL;
+        }
+        if (ssrmod.surround_raw_buffer) {
+            free(ssrmod.surround_raw_buffer);
+            ssrmod.surround_raw_buffer = NULL;
+        }
+        if (ssrmod.fp_input)
+            fclose(ssrmod.fp_input);
+        if (ssrmod.fp_output)
+            fclose(ssrmod.fp_output);
+    }
+
+    if(ssrmod.drc_handle) {
+        dlclose(ssrmod.drc_handle);
+        ssrmod.drc_handle = NULL;
+    }
+
+    if(ssrmod.surround_rec_handle) {
+        dlclose(ssrmod.surround_rec_handle);
+        ssrmod.surround_rec_handle = NULL;
+    }
+
+    ssrmod.in = NULL;
+    //SSR session can be closed due to device switch
+    //Do not force reset ssr mode
+
+    //ssrmod.is_ssr_mode_on = false;
+    ALOGV("%s: exit", __func__);
+
+    return 0;
+}
+
+int32_t ssr_init(struct stream_in *in, int num_out_chan)
 {
     uint32_t ret = -1;
     char c_multi_ch_dump[128] = {0};
@@ -455,10 +467,10 @@
 
     if (ssrmod.surround_obj != NULL) {
         ALOGV("%s: reinitializing surround sound library", __func__);
-        audio_extn_ssr_deinit();
+        ssr_deinit();
     }
 
-    if (audio_extn_ssr_get_enabled()) {
+    if (ssr_get_enabled()) {
         ssrmod.ssr_3mic = 1;
     } else {
         ALOGE(" Rejecting SSR -- init is called without enabling SSR");
@@ -577,54 +589,41 @@
     return 0;
 
 fail:
-    (void) audio_extn_ssr_deinit();
+    (void) ssr_deinit();
     return ret;
 }
 
-int32_t audio_extn_ssr_deinit()
+int ssr_set_usecase(struct stream_in *in,
+                               struct audio_config *config,
+                               bool *update_params)
 {
-    ALOGV("%s: entry", __func__);
-    deinit_ssr_process_thread();
+    int ret = -EINVAL;
+    int channel_count = audio_channel_count_from_in_mask(in->channel_mask);
+    audio_channel_representation_t representation =
+                  audio_channel_mask_get_representation(in->channel_mask);
+    *update_params = false;
 
-    if (ssrmod.drc_obj) {
-        ssrmod.drc_deinit(ssrmod.drc_obj);
-        ssrmod.drc_obj = NULL;
-    }
+    if (ssr_check_usecase(in)) {
 
-    if (ssrmod.surround_obj) {
-
-        if (ssrmod.ssr_3mic) {
-            ssrmod.surround_rec_deinit(ssrmod.surround_obj);
-            ssrmod.surround_obj = NULL;
+        if (representation == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
+            /* update params in case channel representation index.
+             * on returning error, flinger will retry with supported representation passed
+             */
+            ALOGD("%s: SSR supports only channel representation position, channel_mask(%#x)"
+                              ,__func__, config->channel_mask);
+            config->channel_mask = AUDIO_CHANNEL_IN_6;
+            ret = 0;
+            *update_params = true;
+        } else {
+            if (!ssr_init(in, channel_count)) {
+                ALOGD("%s: Created SSR session succesfully", __func__);
+                ret = 0;
+            } else {
+                ALOGE("%s: Unable to start SSR record session", __func__);
+            }
         }
-        if (ssrmod.surround_raw_buffer) {
-            free(ssrmod.surround_raw_buffer);
-            ssrmod.surround_raw_buffer = NULL;
-        }
-        if (ssrmod.fp_input)
-            fclose(ssrmod.fp_input);
-        if (ssrmod.fp_output)
-            fclose(ssrmod.fp_output);
     }
-
-    if(ssrmod.drc_handle) {
-        dlclose(ssrmod.drc_handle);
-        ssrmod.drc_handle = NULL;
-    }
-
-    if(ssrmod.surround_rec_handle) {
-        dlclose(ssrmod.surround_rec_handle);
-        ssrmod.surround_rec_handle = NULL;
-    }
-
-    ssrmod.in = NULL;
-    //SSR session can be closed due to device switch
-    //Do not force reset ssr mode
-
-    //ssrmod.is_ssr_mode_on = false;
-    ALOGV("%s: exit", __func__);
-
-    return 0;
+    return ret;
 }
 
 static void *ssr_process_thread(void *context __unused)
@@ -699,7 +698,7 @@
     pthread_exit(NULL);
 }
 
-int32_t audio_extn_ssr_read(struct audio_stream_in *stream,
+int32_t ssr_read(struct audio_stream_in *stream,
                        void *buffer, size_t bytes)
 {
     struct stream_in *in = (struct stream_in *)stream;
@@ -755,7 +754,7 @@
     return ret;
 }
 
-void audio_extn_ssr_set_parameters(struct audio_device *adev __unused,
+void ssr_set_parameters(struct audio_device *adev __unused,
                                    struct str_parms *parms)
 {
     int err;
@@ -791,7 +790,7 @@
     }
 }
 
-void audio_extn_ssr_get_parameters(const struct audio_device *adev __unused,
+void ssr_get_parameters(const struct audio_device *adev __unused,
                                    struct str_parms *parms,
                                    struct str_parms *reply)
 {
@@ -822,4 +821,3 @@
     }
 }
 
-#endif /* SSR_ENABLED */
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index 16b3e10..9981ef0 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2016-2019 The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -24,7 +24,7 @@
 #include <errno.h>
 #include <pthread.h>
 #include <stdlib.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <cutils/str_parms.h>
 #include <sys/ioctl.h>
 #include <fcntl.h>
@@ -36,6 +36,7 @@
 #include <ctype.h>
 #include <math.h>
 #include <unistd.h>
+#include "audio_extn.h"
 
 #ifdef DYNAMIC_LOG_ENABLED
 #include <log_xml_parser.h>
@@ -43,7 +44,6 @@
 #include <log_utils.h>
 #endif
 
-#ifdef USB_HEADSET_ENABLED
 #define USB_BUFF_SIZE           2048
 #define CHANNEL_NUMBER_STR      "Channels: "
 #define PLAYBACK_PROFILE_STR    "Playback:"
@@ -121,6 +121,57 @@
     "Mic Playback Volume",
 };
 
+static int usb_get_sidetone_gain(struct usb_card_config *card_info)
+{
+    int gain = card_info->usb_sidetone_vol_min + usbmod->sidetone_gain;
+    if (gain > card_info->usb_sidetone_vol_max)
+        gain = card_info->usb_sidetone_vol_max;
+    return gain;
+}
+
+static void usb_get_sidetone_volume(struct usb_card_config *usb_card_info)
+{
+    struct mixer_ctl *ctl;
+    unsigned int index;
+
+    if (!audio_extn_usb_is_sidetone_volume_enabled())
+        return;
+
+    for (index = 0;
+         index < sizeof(usb_sidetone_volume_str)/sizeof(usb_sidetone_volume_str[0]);
+         index++) {
+        ctl = mixer_get_ctl_by_name(usb_card_info->usb_snd_mixer,
+                                    usb_sidetone_volume_str[index]);
+        if (ctl) {
+            usb_card_info->usb_sidetone_index[USB_SIDETONE_VOLUME_INDEX] = index;
+            usb_card_info->usb_sidetone_vol_min = mixer_ctl_get_range_min(ctl);
+            usb_card_info->usb_sidetone_vol_max = mixer_ctl_get_range_max(ctl);
+            break;
+        }
+    }
+}
+
+static void usb_set_sidetone_volume(struct usb_card_config *usb_card_info,
+                                        bool enable, int index)
+{
+    struct mixer_ctl *ctl;
+
+    if (!audio_extn_usb_is_sidetone_volume_enabled())
+        return;
+
+    ctl = mixer_get_ctl_by_name(usb_card_info->usb_snd_mixer,
+                                usb_sidetone_volume_str[index]);
+
+    if (ctl == NULL)
+        ALOGV("%s: sidetone gain mixer command is not found",
+              __func__);
+    else if (enable)
+        mixer_ctl_set_value(ctl, 0,
+                            usb_get_sidetone_gain(usb_card_info));
+}
+
+
+
 static void usb_mixer_print_enum(struct mixer_ctl *ctl)
 {
     unsigned int num_enums;
@@ -324,7 +375,7 @@
     return 0;
 }
 
-static int usb_get_service_interval(const char *interval_str_start,
+static int get_usb_service_interval(const char *interval_str_start,
                                     struct usb_device_config *usb_device_info)
 {
     unsigned long interval = 0;
@@ -534,7 +585,7 @@
         interval_str_start = strstr(str_start, DATA_PACKET_INTERVAL_STR);
         if (interval_str_start != NULL) {
             interval_str_start += strlen(DATA_PACKET_INTERVAL_STR);
-            ret = usb_get_service_interval(interval_str_start, usb_device_info);
+            ret = get_usb_service_interval(interval_str_start, usb_device_info);
             if (ret < 0) {
                 ALOGE("%s: error unable to get service interval, assume default",
                       __func__);
@@ -605,21 +656,13 @@
             usb_card_info->usb_sidetone_index[USB_SIDETONE_ENABLE_INDEX] = index;
             /* Disable device sidetone by default */
             mixer_ctl_set_value(ctl, 0, false);
+            ALOGV("%s: sidetone mixer Control found(%s) ... disabling by default",
+                    __func__, usb_sidetone_enable_str[index]);
             break;
         }
     }
-    for (index = 0;
-         index < sizeof(usb_sidetone_volume_str)/sizeof(usb_sidetone_volume_str[0]);
-         index++) {
-        ctl = mixer_get_ctl_by_name(usb_card_info->usb_snd_mixer,
-                                    usb_sidetone_volume_str[index]);
-        if (ctl) {
-            usb_card_info->usb_sidetone_index[USB_SIDETONE_VOLUME_INDEX] = index;
-            usb_card_info->usb_sidetone_vol_min = mixer_ctl_get_range_min(ctl);
-            usb_card_info->usb_sidetone_vol_max = mixer_ctl_get_range_max(ctl);
-            break;
-        }
-    }
+
+    usb_get_sidetone_volume(usb_card_info);
 
     if ((usb_card_info->usb_snd_mixer != NULL) && (usb_audio_debug_enable))
         usb_soundcard_list_controls(usb_card_info->usb_snd_mixer);
@@ -910,15 +953,7 @@
     return is_usb_supported;
 }
 
-static int usb_get_sidetone_gain(struct usb_card_config *card_info)
-{
-    int gain = card_info->usb_sidetone_vol_min + usbmod->sidetone_gain;
-    if (gain > card_info->usb_sidetone_vol_max)
-        gain = card_info->usb_sidetone_vol_max;
-    return gain;
-}
-
-void audio_extn_usb_set_sidetone_gain(struct str_parms *parms,
+void usb_set_sidetone_gain(struct str_parms *parms,
                                 char *value, int len)
 {
     int err;
@@ -934,7 +969,7 @@
     return;
 }
 
-int audio_extn_usb_enable_sidetone(int device, bool enable)
+int usb_enable_sidetone(int device, bool enable)
 {
     int ret = -ENODEV;
     struct listnode *node_i;
@@ -958,16 +993,9 @@
                     break;
 
                 if ((i = card_info->usb_sidetone_index[USB_SIDETONE_VOLUME_INDEX]) != -1) {
-                    ctl = mixer_get_ctl_by_name(
-                                card_info->usb_snd_mixer,
-                                usb_sidetone_volume_str[i]);
-                    if (ctl == NULL)
-                        ALOGV("%s: sidetone gain mixer command is not found",
-                               __func__);
-                    else if (enable)
-                        mixer_ctl_set_value(ctl, 0,
-                                            usb_get_sidetone_gain(card_info));
+                    usb_set_sidetone_volume(card_info, enable, i);
                 }
+
                 ret = 0;
                 break;
             }
@@ -976,7 +1004,7 @@
     return ret;
 }
 
-bool audio_extn_usb_is_config_supported(unsigned int *bit_width,
+bool usb_is_config_supported(unsigned int *bit_width,
                                         unsigned int *sample_rate,
                                         unsigned int *ch,
                                         bool is_playback)
@@ -1009,7 +1037,7 @@
     return is_usb_supported;
 }
 
-int audio_extn_usb_get_max_channels(bool is_playback)
+int usb_get_max_channels(bool is_playback)
 {
     struct listnode *node_i, *node_j;
     struct usb_device_config *dev_info;
@@ -1031,7 +1059,7 @@
     return max_ch;
 }
 
-int audio_extn_usb_get_max_bit_width(bool is_playback)
+int usb_get_max_bit_width(bool is_playback)
 {
     struct listnode *node_i, *node_j;
     struct usb_device_config *dev_info;
@@ -1053,7 +1081,7 @@
     return max_bw;
 }
 
-int audio_extn_usb_get_sup_sample_rates(bool is_playback,
+int usb_get_sup_sample_rates(bool is_playback,
                                         uint32_t *sample_rates,
                                         uint32_t sample_rate_size)
 {
@@ -1073,7 +1101,7 @@
     return i;
 }
 
-bool audio_extn_usb_is_capture_supported()
+bool usb_is_capture_supported()
 {
     if (usbmod == NULL) {
         ALOGE("%s: USB device object is NULL", __func__);
@@ -1083,20 +1111,23 @@
     return usbmod->is_capture_supported;
 }
 
-bool audio_extn_usb_is_tunnel_supported()
+bool usb_is_tunnel_supported()
 {
     return true;
 }
 
-void audio_extn_usb_add_device(audio_devices_t device, int card)
+void usb_add_device(audio_devices_t device, int card)
 {
     struct usb_card_config *usb_card_info;
     char check_debug_enable[PROPERTY_VALUE_MAX];
     struct listnode *node_i;
 
-    property_get("vendor.audio.usb.enable.debug", check_debug_enable, NULL);
-    if (atoi(check_debug_enable)) {
-        usb_audio_debug_enable = true;
+    if ((property_get("vendor.audio.usb.enable.debug",
+                      check_debug_enable, NULL) > 0) ||
+        (property_get("audio.usb.enable.debug",
+                      check_debug_enable, NULL) > 0)) {
+        if (atoi(check_debug_enable))
+            usb_audio_debug_enable = true;
     }
 
     ALOGI_IF(usb_audio_debug_enable,
@@ -1158,7 +1189,7 @@
     return;
 }
 
-void audio_extn_usb_remove_device(audio_devices_t device, int card)
+void usb_remove_device(audio_devices_t device, int card)
 {
     struct listnode *node_i, *temp_i;
     struct listnode *node_j, *temp_j;
@@ -1211,20 +1242,20 @@
     return;
 }
 
-bool audio_extn_usb_alive(int card) {
+bool usb_alive(int card) {
     char path[PATH_MAX] = {0};
     // snprintf should never fail
     (void) snprintf(path, sizeof(path), "/proc/asound/card%u/stream0", card);
     return access(path, F_OK) == 0;
 }
 
-unsigned long audio_extn_usb_find_service_interval(bool min,
+unsigned long usb_find_service_interval(bool min,
                                                    bool playback) {
     struct usb_card_config *card_info = NULL;
     struct usb_device_config *dev_info = NULL;
     struct listnode *node_i = NULL;
     struct listnode *node_j = NULL;
-    unsigned long interval_us = min ? UINT_MAX : 0;
+    unsigned long interval_us = min ? ULONG_MAX : 0;
     list_for_each(node_i, &usbmod->usb_card_conf_list) {
         card_info = node_to_item(node_i, struct usb_card_config, list);
         list_for_each(node_j, &card_info->usb_device_conf_list) {
@@ -1242,16 +1273,16 @@
     return interval_us;
 }
 
-int audio_extn_usb_altset_for_service_interval(bool playback,
+int usb_altset_for_service_interval(bool playback,
                                                unsigned long service_interval,
                                                uint32_t *bit_width,
                                                uint32_t *sample_rate,
                                                uint32_t *channels)
 {
     struct usb_card_config *card_info = NULL;
-    struct usb_device_config *dev_info = NULL;;
-    struct listnode *node_i = NULL;;
-    struct listnode *node_j = NULL;;
+    struct usb_device_config *dev_info = NULL;
+    struct listnode *node_i = NULL;
+    struct listnode *node_j = NULL;
     uint32_t bw = 0;
     uint32_t ch = 0;
     uint32_t sr = 0;
@@ -1308,7 +1339,7 @@
 #undef SET_OR_RETURN_ON_ERROR
 }
 
-int audio_extn_usb_get_service_interval(bool playback,
+int usb_get_service_interval(bool playback,
                                         unsigned long *service_interval)
 {
     const char *ctl_name = "USB_AUDIO_RX service_interval";
@@ -1329,7 +1360,7 @@
     return 0;
 }
 
-int audio_extn_usb_set_service_interval(bool playback,
+int usb_set_service_interval(bool playback,
                                         unsigned long service_interval,
                                         bool *reconfig)
 {
@@ -1349,7 +1380,7 @@
         return -1;
     }
 
-    if (audio_extn_usb_get_service_interval(playback,
+    if (usb_get_service_interval(playback,
                                             &current_service_interval) != 0) {
         ALOGE("%s Unable to get current service interval", __func__);
         return -1;
@@ -1364,7 +1395,7 @@
     return 0;
 }
 
-int audio_extn_usb_check_and_set_svc_int(struct audio_usecase *uc_info,
+int usb_check_and_set_svc_int(struct audio_usecase *uc_info,
                                          bool starting_output_stream)
 {
     struct listnode *node = NULL;
@@ -1412,9 +1443,9 @@
     ALOGV("%s: burst mode(%d).", __func__,burst_mode);
 
     service_interval =
-            audio_extn_usb_find_service_interval(!burst_mode, true /*playback*/);
+            usb_find_service_interval(!burst_mode, true /*playback*/);
 
-    audio_extn_usb_set_service_interval(true /*playback*/,
+    usb_set_service_interval(true /*playback*/,
                                         service_interval,
                                         &reconfig);
 
@@ -1424,28 +1455,28 @@
     return 0;
 }
 
-bool audio_extn_usb_is_reconfig_req()
+bool usb_is_reconfig_req()
 {
     return usbmod->usb_reconfig;
 }
 
-void audio_extn_usb_set_reconfig(bool is_required)
+void usb_set_reconfig(bool is_required)
 {
     usbmod->usb_reconfig = is_required;
 }
 
-bool audio_extn_usb_connected(struct str_parms *parms) {
+bool usb_connected(struct str_parms *parms) {
     int card = -1;
     struct listnode *node_i = NULL;
     struct usb_card_config *usb_card_info = NULL;
     bool usb_connected = false;
 
     if ((parms != NULL) && str_parms_get_int(parms, "card", &card) >= 0) {
-        usb_connected = audio_extn_usb_alive(card);
+        usb_connected = usb_alive(card);
     } else {
         list_for_each(node_i, &usbmod->usb_card_conf_list) {
             usb_card_info = node_to_item(node_i, struct usb_card_config, list);
-            if (audio_extn_usb_alive(usb_card_info->usb_card)) {
+            if (usb_alive(usb_card_info->usb_card)) {
                 usb_connected = true;
                 break;
             }
@@ -1454,7 +1485,7 @@
     return usb_connected;
 }
 
-void audio_extn_usb_init(void *adev)
+void usb_init(void *adev)
 {
     if (usbmod == NULL) {
         usbmod = calloc(1, sizeof(struct usb_module));
@@ -1462,7 +1493,10 @@
             ALOGE("%s: error unable to allocate memory", __func__);
             goto exit;
         }
+    } else {
+        memset(usbmod, 0, sizeof(*usbmod));
     }
+
     list_init(&usbmod->usb_card_conf_list);
     usbmod->adev = (struct audio_device*)adev;
     usbmod->sidetone_gain = usb_sidetone_gain;
@@ -1472,11 +1506,10 @@
     return;
 }
 
-void audio_extn_usb_deinit(void)
+void usb_deinit(void)
 {
     if (NULL != usbmod){
         free(usbmod);
         usbmod = NULL;
     }
 }
-#endif /*USB_HEADSET_ENABLED end*/
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 7c5756b..0d43e02 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2014 The Android Open Source Project
@@ -27,7 +27,7 @@
 #include <stdlib.h>
 #include <dlfcn.h>
 #include <cutils/str_parms.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <cutils/misc.h>
 #include <unistd.h>
 
@@ -164,7 +164,6 @@
     STRING_TO_ENUM(AUDIO_FORMAT_DTS_HD),
     STRING_TO_ENUM(AUDIO_FORMAT_DOLBY_TRUEHD),
     STRING_TO_ENUM(AUDIO_FORMAT_IEC61937),
-#ifdef AUDIO_EXTN_FORMATS_ENABLED
     STRING_TO_ENUM(AUDIO_FORMAT_E_AC3_JOC),
     STRING_TO_ENUM(AUDIO_FORMAT_WMA),
     STRING_TO_ENUM(AUDIO_FORMAT_WMA_PRO),
@@ -179,7 +178,6 @@
     STRING_TO_ENUM(AUDIO_FORMAT_FLAC),
     STRING_TO_ENUM(AUDIO_FORMAT_ALAC),
     STRING_TO_ENUM(AUDIO_FORMAT_APE),
-    STRING_TO_ENUM(AUDIO_FORMAT_E_AC3_JOC),
     STRING_TO_ENUM(AUDIO_FORMAT_AAC_LC),
     STRING_TO_ENUM(AUDIO_FORMAT_AAC_HE_V1),
     STRING_TO_ENUM(AUDIO_FORMAT_AAC_HE_V2),
@@ -193,7 +191,6 @@
     STRING_TO_ENUM(AUDIO_FORMAT_AAC_LATM_HE_V1),
     STRING_TO_ENUM(AUDIO_FORMAT_AAC_LATM_HE_V2),
     STRING_TO_ENUM(AUDIO_FORMAT_APTX),
-#endif
 };
 
 /* payload structure avt_device drift query */
@@ -894,6 +891,132 @@
     }
 }
 
+static int set_stream_app_type_mixer_ctrl(struct audio_device *adev,
+                                          int pcm_device_id, int app_type,
+                                          int acdb_dev_id, int sample_rate,
+                                          int stream_type,
+                                          snd_device_t snd_device)
+{
+
+    char mixer_ctl_name[MAX_LENGTH_MIXER_CONTROL_IN_INT];
+    struct mixer_ctl *ctl;
+    int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT], len = 0, rc = 0;
+    int snd_device_be_idx = -1;
+
+    if (stream_type == PCM_PLAYBACK) {
+        snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+             "Audio Stream %d App Type Cfg", pcm_device_id);
+    } else if (stream_type == PCM_CAPTURE) {
+        snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+             "Audio Stream Capture %d App Type Cfg", pcm_device_id);
+    }
+
+    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+    if (!ctl) {
+        ALOGE("%s: Could not get ctl for mixer cmd - %s",
+             __func__, mixer_ctl_name);
+        rc = -EINVAL;
+        goto exit;
+    }
+    app_type_cfg[len++] = app_type;
+    app_type_cfg[len++] = acdb_dev_id;
+    app_type_cfg[len++] = sample_rate;
+
+    snd_device_be_idx = platform_get_snd_device_backend_index(snd_device);
+    if (snd_device_be_idx > 0)
+        app_type_cfg[len++] = snd_device_be_idx;
+    ALOGV("%s: stream type %d app_type %d, acdb_dev_id %d "
+          "sample rate %d, snd_device_be_idx %d",
+          __func__, stream_type, app_type, acdb_dev_id, sample_rate,
+          snd_device_be_idx);
+    mixer_ctl_set_array(ctl, app_type_cfg, len);
+
+exit:
+    return rc;
+}
+
+static int audio_extn_utils_send_app_type_cfg_hfp(struct audio_device *adev,
+                                       struct audio_usecase *usecase)
+{
+    int pcm_device_id, acdb_dev_id = 0, snd_device = usecase->out_snd_device;
+    int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+    int app_type = 0, rc = 0;
+
+    ALOGV("%s", __func__);
+
+    if (usecase->type != PCM_HFP_CALL) {
+        ALOGV("%s: not a playback or HFP path, no need to cfg app type", __func__);
+        rc = 0;
+        goto exit_send_app_type_cfg;
+    }
+    if ((usecase->id != USECASE_AUDIO_HFP_SCO) &&
+        (usecase->id != USECASE_AUDIO_HFP_SCO_WB)) {
+        ALOGV("%s: a playback path where app type cfg is not required", __func__);
+        rc = 0;
+        goto exit_send_app_type_cfg;
+    }
+
+    snd_device = usecase->out_snd_device;
+    pcm_device_id = platform_get_pcm_device_id(usecase->id, PCM_PLAYBACK);
+
+    acdb_dev_id = platform_get_snd_device_acdb_id(snd_device);
+    if (acdb_dev_id < 0) {
+        ALOGE("%s: Couldn't get the acdb dev id", __func__);
+        rc = -EINVAL;
+        goto exit_send_app_type_cfg;
+    }
+
+    if (usecase->type == PCM_HFP_CALL) {
+
+        /* config HFP session:1 playback path */
+        app_type = platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK);
+        sample_rate= CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+        rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
+                                            acdb_dev_id, sample_rate,
+                                            PCM_PLAYBACK,
+                                            SND_DEVICE_NONE); // use legacy behavior
+        if (rc < 0)
+            goto exit_send_app_type_cfg;
+
+        /* config HFP session:1 capture path */
+        app_type = platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE);
+        rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
+                                            acdb_dev_id, sample_rate,
+                                            PCM_CAPTURE,
+                                            SND_DEVICE_NONE);
+        if (rc < 0)
+            goto exit_send_app_type_cfg;
+
+        /* config HFP session:2 capture path */
+        pcm_device_id = HFP_ASM_RX_TX;
+        snd_device = usecase->in_snd_device;
+        acdb_dev_id = platform_get_snd_device_acdb_id(snd_device);
+        if (acdb_dev_id <= 0) {
+            ALOGE("%s: Couldn't get the acdb dev id", __func__);
+            rc = -EINVAL;
+            goto exit_send_app_type_cfg;
+        }
+        app_type = platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE);
+        rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
+                                            acdb_dev_id, sample_rate, PCM_CAPTURE,
+                                            SND_DEVICE_NONE);
+        if (rc < 0)
+            goto exit_send_app_type_cfg;
+
+        /* config HFP session:2 playback path */
+        app_type = platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK);
+        rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
+                                            acdb_dev_id, sample_rate,
+                                            PCM_PLAYBACK, SND_DEVICE_NONE);
+        if (rc < 0)
+            goto exit_send_app_type_cfg;
+    }
+
+    rc = 0;
+exit_send_app_type_cfg:
+    return rc;
+}
+
 static int send_app_type_cfg_for_device(struct audio_device *adev,
                                         struct audio_usecase *usecase,
                                         int split_snd_device)
@@ -1118,6 +1241,10 @@
     snd_device_t in_snd_device = usecase->in_snd_device;
     int rc = 0;
 
+    if (usecase->type == PCM_HFP_CALL) {
+        return audio_extn_utils_send_app_type_cfg_hfp(adev, usecase);
+    }
+
     switch (usecase->type) {
     case PCM_PLAYBACK:
     case TRANSCODE_LOOPBACK_RX:
@@ -2132,6 +2259,66 @@
 #define MAX_SND_CARD 8
 #define RETRY_US 1000000
 #define RETRY_NUMBER 40
+#define PLATFORM_INFO_XML_PATH          "audio_platform_info.xml"
+#define PLATFORM_INFO_XML_BASE_STRING   "audio_platform_info"
+
+#ifdef LINUX_ENABLED
+static const char *kConfigLocationList[] =
+        {"/etc"};
+#else
+static const char *kConfigLocationList[] =
+        {"/vendor/etc"};
+#endif
+static const int kConfigLocationListSize =
+        (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
+
+bool audio_extn_utils_resolve_config_file(char file_name[MIXER_PATH_MAX_LENGTH])
+{
+    char full_config_path[MIXER_PATH_MAX_LENGTH];
+    for (int i = 0; i < kConfigLocationListSize; i++) {
+        snprintf(full_config_path,
+                 MIXER_PATH_MAX_LENGTH,
+                 "%s/%s",
+                 kConfigLocationList[i],
+                 file_name);
+        if (F_OK == access(full_config_path, 0)) {
+            strcpy(file_name, full_config_path);
+            return true;
+        }
+    }
+    return false;
+}
+
+/* platform_info_file should be size 'MIXER_PATH_MAX_LENGTH' */
+int audio_extn_utils_get_platform_info(const char* snd_card_name, char* platform_info_file)
+{
+    if (NULL == snd_card_name) {
+        return -1;
+    }
+
+    struct snd_card_split *snd_split_handle = NULL;
+    int ret = 0;
+    audio_extn_set_snd_card_split(snd_card_name);
+    snd_split_handle = audio_extn_get_snd_card_split();
+
+    snprintf(platform_info_file, MIXER_PATH_MAX_LENGTH, "%s_%s_%s.xml",
+                     PLATFORM_INFO_XML_BASE_STRING, snd_split_handle->snd_card,
+                     snd_split_handle->form_factor);
+
+    if (!audio_extn_utils_resolve_config_file(platform_info_file)) {
+        memset(platform_info_file, 0, MIXER_PATH_MAX_LENGTH);
+        snprintf(platform_info_file, MIXER_PATH_MAX_LENGTH, "%s_%s.xml",
+                     PLATFORM_INFO_XML_BASE_STRING, snd_split_handle->snd_card);
+
+        if (!audio_extn_utils_resolve_config_file(platform_info_file)) {
+            memset(platform_info_file, 0, MIXER_PATH_MAX_LENGTH);
+            strlcpy(platform_info_file, PLATFORM_INFO_XML_PATH, MIXER_PATH_MAX_LENGTH);
+            ret = audio_extn_utils_resolve_config_file(platform_info_file) ? 0 : -1;
+        }
+    }
+
+    return ret;
+}
 
 int audio_extn_utils_get_snd_card_num()
 {
@@ -2544,3 +2731,24 @@
     return platform_get_license_by_product(adev->platform, (const char*)license_params->product, &license_params->key, license_params->license);
 }
 
+int audio_extn_utils_send_app_type_gain(struct audio_device *adev,
+                                        int app_type,
+                                        int *gain)
+{
+    int gain_cfg[4];
+    const char *mixer_ctl_name = "App Type Gain";
+    struct mixer_ctl *ctl;
+    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+    if (!ctl) {
+        ALOGE("%s: Could not get volume ctl mixer %s", __func__,
+              mixer_ctl_name);
+        return -EINVAL;
+    }
+    gain_cfg[0] = 0;
+    gain_cfg[1] = app_type;
+    gain_cfg[2] = gain[0];
+    gain_cfg[3] = gain[1];
+    ALOGV("%s app_type %d l(%d) r(%d)", __func__,  app_type, gain[0], gain[1]);
+    return mixer_ctl_set_array(ctl, gain_cfg,
+                               sizeof(gain_cfg)/sizeof(gain_cfg[0]));
+}
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 375f221..08a8fad 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
@@ -55,13 +55,12 @@
 #include <sys/resource.h>
 #include <sys/prctl.h>
 
-#include <cutils/log.h>
+#include <log/log.h>
 #include <cutils/trace.h>
 #include <cutils/str_parms.h>
 #include <cutils/properties.h>
 #include <cutils/atomic.h>
 #include <cutils/sched_policy.h>
-
 #include <hardware/audio_effect.h>
 #include <hardware/audio_alsaops.h>
 #include <system/thread_defs.h>
@@ -75,6 +74,7 @@
 #include "audio_extn.h"
 #include "voice_extn.h"
 #include "ip_hdlr_intf.h"
+#include "audio_feature_manager.h"
 
 #include "sound/compress_params.h"
 #include "sound/asound.h"
@@ -93,16 +93,21 @@
 #define PCM_PLAYBACK_VOLUME_MAX 0x2000
 #define DSD_VOLUME_MIN_DB (-110)
 
+#define RECORD_GAIN_MIN 0.0f
+#define RECORD_GAIN_MAX 1.0f
+#define RECORD_VOLUME_CTL_MAX 0x2000
+
+/* treat as unsigned Q1.13 */
+#define APP_TYPE_GAIN_DEFAULT         0x2000
+
 #define PROXY_OPEN_RETRY_COUNT           100
 #define PROXY_OPEN_WAIT_TIME             20
 
-#ifdef USE_LL_AS_PRIMARY_OUTPUT
-#define USECASE_AUDIO_PLAYBACK_PRIMARY USECASE_AUDIO_PLAYBACK_LOW_LATENCY
-#define PCM_CONFIG_AUDIO_PLAYBACK_PRIMARY pcm_config_low_latency
-#else
-#define USECASE_AUDIO_PLAYBACK_PRIMARY USECASE_AUDIO_PLAYBACK_DEEP_BUFFER
-#define PCM_CONFIG_AUDIO_PLAYBACK_PRIMARY pcm_config_deep_buffer
-#endif
+#define GET_USECASE_AUDIO_PLAYBACK_PRIMARY(db) \
+         (db)? USECASE_AUDIO_PLAYBACK_DEEP_BUFFER : \
+               USECASE_AUDIO_PLAYBACK_LOW_LATENCY
+#define GET_PCM_CONFIG_AUDIO_PLAYBACK_PRIMARY(db) \
+         (db)? pcm_config_deep_buffer : pcm_config_low_latency
 
 #define ULL_PERIOD_SIZE (DEFAULT_OUTPUT_SAMPLING_RATE/1000)
 #define DEFAULT_VOIP_BUF_DURATION_MS 20
@@ -125,6 +130,14 @@
 #define DEFAULT_CHANNEL_COUNT            2
 #define MAX_HIFI_CHANNEL_COUNT           8
 
+#ifndef MAX_TARGET_SPECIFIC_CHANNEL_CNT
+#define MAX_CHANNEL_COUNT 1
+#else
+#define MAX_CHANNEL_COUNT atoi(XSTR(MAX_TARGET_SPECIFIC_CHANNEL_CNT))
+#define XSTR(x) STR(x)
+#define STR(x) #x
+#endif
+
 static unsigned int configured_low_latency_capture_period_size =
         LOW_LATENCY_CAPTURE_PERIOD_SIZE;
 
@@ -133,6 +146,11 @@
 #define MMAP_PERIOD_COUNT_MAX 512
 #define MMAP_PERIOD_COUNT_DEFAULT (MMAP_PERIOD_COUNT_MAX)
 
+/* This constant enables extended precision handling.
+ * TODO The flag is off until more testing is done.
+ */
+static const bool k_enable_extended_precision = false;
+
 struct pcm_config pcm_config_deep_buffer = {
     .channels = 2,
     .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
@@ -210,19 +228,6 @@
     .format = PCM_FORMAT_S16_LE,
 };
 
-struct pcm_config pcm_config_audio_capture_rt = {
-    .channels = 2,
-    .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
-    .period_size = ULL_PERIOD_SIZE,
-    .period_count = 512,
-    .format = PCM_FORMAT_S16_LE,
-    .start_threshold = 0,
-    .stop_threshold = INT_MAX,
-    .silence_threshold = 0,
-    .silence_size = 0,
-    .avail_min = ULL_PERIOD_SIZE, //1 ms
-};
-
 struct pcm_config pcm_config_mmap_capture = {
     .channels = 2,
     .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
@@ -256,6 +261,19 @@
 #define AFE_PROXY_RECORD_PERIOD_SIZE  768
 #define AFE_PROXY_RECORD_PERIOD_COUNT 4
 
+struct pcm_config pcm_config_audio_capture_rt = {
+    .channels = 2,
+    .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
+    .period_size = ULL_PERIOD_SIZE,
+    .period_count = 512,
+    .format = PCM_FORMAT_S16_LE,
+    .start_threshold = 0,
+    .stop_threshold = AFE_PROXY_RECORD_PERIOD_SIZE * AFE_PROXY_RECORD_PERIOD_COUNT,
+    .silence_threshold = 0,
+    .silence_size = 0,
+    .avail_min = ULL_PERIOD_SIZE, //1 ms
+};
+
 struct pcm_config pcm_config_afe_proxy_record = {
     .channels = AFE_PROXY_CHANNEL_COUNT,
     .rate = AFE_PROXY_SAMPLING_RATE,
@@ -297,6 +315,7 @@
     [USECASE_AUDIO_PLAYBACK_FM] = "play-fm",
     [USECASE_AUDIO_PLAYBACK_MMAP] = "mmap-playback",
     [USECASE_AUDIO_PLAYBACK_HIFI] = "hifi-playback",
+    [USECASE_AUDIO_PLAYBACK_TTS] = "audio-tts-playback",
 
     [USECASE_AUDIO_RECORD] = "audio-record",
     [USECASE_AUDIO_RECORD_COMPRESS] = "audio-record-compress",
@@ -662,6 +681,25 @@
      return ret_val;
 }
 
+bool audio_hw_send_qdsp_parameter(int stream_type, float vol, bool active)
+{
+    bool ret = false;
+    ALOGV("%s: enter ...", __func__);
+
+    pthread_mutex_lock(&adev_init_lock);
+
+    if (adev != NULL && adev->platform != NULL) {
+        pthread_mutex_lock(&adev->lock);
+        ret = audio_extn_qdsp_set_state(adev, stream_type, vol, active);
+        pthread_mutex_unlock(&adev->lock);
+    }
+
+    pthread_mutex_unlock(&adev_init_lock);
+
+    ALOGV("%s: exit with ret %d", __func__, ret);
+    return ret;
+}
+
 static bool is_supported_format(audio_format_t format)
 {
     if (format == AUDIO_FORMAT_MP3 ||
@@ -836,7 +874,6 @@
     }
 }
 
-#ifdef DYNAMIC_ECNS_ENABLED
 static int send_effect_enable_disable_mixer_ctl(struct audio_device *adev,
                           struct audio_effect_config effect_config,
                           unsigned int param_value)
@@ -897,13 +934,16 @@
 }
 
 static int enable_disable_effect(struct audio_device *adev, int effect_type, bool enable)
-{
+{ 
     struct audio_effect_config effect_config;
     struct audio_usecase *usecase = NULL;
     int ret = 0;
     unsigned int param_value = 0;
     struct stream_in *in = adev->active_input;
 
+    if(!voice_extn_is_dynamic_ecns_enabled())
+        return ENOSYS;
+
     if (!in) {
         ALOGE("%s: Invalid input stream", __func__);
         return -EINVAL;
@@ -945,6 +985,8 @@
 
 static void check_and_enable_effect(struct audio_device *adev)
 {
+    if(!voice_extn_is_dynamic_ecns_enabled())
+        return;
 
     if (adev->active_input->enable_aec) {
         enable_disable_effect(adev, EFFECT_AEC, true);
@@ -955,10 +997,6 @@
         enable_disable_effect(adev, EFFECT_NS, true);
     }
 }
-#else
-#define enable_disable_effect(x, y, z) ENOSYS
-#define check_and_enable_effect(x) ENOSYS
-#endif
 
 int pcm_ioctl(struct pcm *pcm, int request, ...)
 {
@@ -1074,6 +1112,8 @@
     if (audio_extn_spkr_prot_is_enabled())
          audio_extn_spkr_prot_calib_cancel(adev);
 
+    audio_extn_dsm_feedback_enable(adev, snd_device, true);
+
     if (platform_can_enable_spkr_prot_on_device(snd_device) &&
          audio_extn_spkr_prot_is_enabled()) {
        if (platform_get_spkr_prot_acdb_id(snd_device) < 0) {
@@ -1093,6 +1133,7 @@
         for (i = 0; i < num_devices; i++) {
             enable_snd_device(adev, new_snd_devices[i]);
         }
+        platform_set_speaker_gain_in_combo(adev, snd_device, true);
     } else {
         ALOGD("%s: snd_device(%d: %s)", __func__, snd_device, device_name);
 
@@ -1172,6 +1213,8 @@
     if (adev->snd_dev_ref_cnt[snd_device] == 0) {
         ALOGD("%s: snd_device(%d: %s)", __func__, snd_device, device_name);
 
+        audio_extn_dsm_feedback_enable(adev, snd_device, false);
+
         if (platform_can_enable_spkr_prot_on_device(snd_device) &&
              audio_extn_spkr_prot_is_enabled()) {
             audio_extn_spkr_prot_stop_processing(snd_device);
@@ -1186,6 +1229,7 @@
             for (i = 0; i < num_devices; i++) {
                 disable_snd_device(adev, new_snd_devices[i]);
             }
+            platform_set_speaker_gain_in_combo(adev, snd_device, false);
         } else {
             audio_route_reset_and_update_path(adev->audio_route, device_name);
         }
@@ -2008,6 +2052,11 @@
     return ret;
 }
 
+static void stream_app_type_cfg_init(struct stream_app_type_cfg *cfg)
+{
+    cfg->gain[0] = cfg->gain[1] = APP_TYPE_GAIN_DEFAULT;
+}
+
 bool is_btsco_device(snd_device_t out_snd_device, snd_device_t in_snd_device)
 {
    bool ret=false;
@@ -2171,7 +2220,8 @@
                      voip_usecase != NULL &&
                      usecase->stream.out->usecase == voip_usecase->id) &&
                     adev->active_input &&
-                    adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
+                    (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
+                     adev->mode == AUDIO_MODE_IN_COMMUNICATION) &&
                     out_snd_device != usecase->out_snd_device) {
                     select_devices(adev, adev->active_input->usecase);
                 }
@@ -2216,9 +2266,37 @@
           return 0;
     }
 
-    ALOGD("%s: out_snd_device(%d: %s) in_snd_device(%d: %s)", __func__,
-          out_snd_device, platform_get_snd_device_name(out_snd_device),
-          in_snd_device,  platform_get_snd_device_name(in_snd_device));
+    if (out_snd_device != SND_DEVICE_NONE &&
+            out_snd_device != adev->last_logged_snd_device[uc_id][0]) {
+        ALOGD("%s: changing use case %s output device from(%d: %s, acdb %d) to (%d: %s, acdb %d)",
+              __func__,
+              use_case_table[uc_id],
+              adev->last_logged_snd_device[uc_id][0],
+              platform_get_snd_device_name(adev->last_logged_snd_device[uc_id][0]),
+              adev->last_logged_snd_device[uc_id][0] != SND_DEVICE_NONE ?
+                      platform_get_snd_device_acdb_id(adev->last_logged_snd_device[uc_id][0]) :
+                      -1,
+              out_snd_device,
+              platform_get_snd_device_name(out_snd_device),
+              platform_get_snd_device_acdb_id(out_snd_device));
+        adev->last_logged_snd_device[uc_id][0] = out_snd_device;
+    }
+    if (in_snd_device != SND_DEVICE_NONE &&
+            in_snd_device != adev->last_logged_snd_device[uc_id][1]) {
+        ALOGD("%s: changing use case %s input device from(%d: %s, acdb %d) to (%d: %s, acdb %d)",
+              __func__,
+              use_case_table[uc_id],
+              adev->last_logged_snd_device[uc_id][1],
+              platform_get_snd_device_name(adev->last_logged_snd_device[uc_id][1]),
+              adev->last_logged_snd_device[uc_id][1] != SND_DEVICE_NONE ?
+                      platform_get_snd_device_acdb_id(adev->last_logged_snd_device[uc_id][1]) :
+                      -1,
+              in_snd_device,
+              platform_get_snd_device_name(in_snd_device),
+              platform_get_snd_device_acdb_id(in_snd_device));
+        adev->last_logged_snd_device[uc_id][1] = in_snd_device;
+    }
+
 
     /*
      * Limitation: While in call, to do a device switch we need to disable
@@ -2244,10 +2322,14 @@
             voice_check_and_update_aanc_path(adev, usecase->out_snd_device, false);
     }
 
-    if ((out_snd_device == SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP) &&
+    if ((out_snd_device == SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP ||
+         out_snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP) &&
         (!audio_extn_a2dp_source_is_ready())) {
         ALOGW("%s: A2DP profile is not ready, routing to speaker only", __func__);
-        out_snd_device = SND_DEVICE_OUT_SPEAKER;
+        if (out_snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP)
+            out_snd_device = SND_DEVICE_OUT_SPEAKER_SAFE;
+        else
+            out_snd_device = SND_DEVICE_OUT_SPEAKER;
     }
 
     /* Disable current sound devices */
@@ -2329,6 +2411,8 @@
     }
     enable_audio_route(adev, usecase);
 
+    audio_extn_qdsp_set_device(usecase);
+
     /* If input stream is already running then effect needs to be
        applied on the new input device that's being enabled here.  */
     if ((in_snd_device != SND_DEVICE_NONE) && (adev->active_input != NULL) &&
@@ -2395,6 +2479,13 @@
         pthread_mutex_lock(&adev->lock);
     }
 
+    if (usecase == voip_usecase) {
+        struct stream_out *voip_out = voip_usecase->stream.out;
+        audio_extn_utils_send_app_type_gain(adev,
+                                            voip_out->app_type_cfg.app_type,
+                                            &voip_out->app_type_cfg.gain[0]);
+    }
+
     ALOGD("%s: done",__func__);
 
     return status;
@@ -2795,7 +2886,7 @@
     int ret = 0;
 
     setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
-    set_sched_policy(0, SP_FOREGROUND);
+    //set_sched_policy(0, SP_FOREGROUND);
     prctl(PR_SET_NAME, (unsigned long)"Offload Callback", 0, 0, 0);
 
     ALOGV("%s", __func__);
@@ -2944,6 +3035,8 @@
     int ret = 0;
     struct audio_usecase *uc_info;
     struct audio_device *adev = out->dev;
+    bool has_voip_usecase =
+        get_usecase_from_list(adev, USECASE_AUDIO_PLAYBACK_VOIP) != NULL;
 
     ALOGV("%s: enter: usecase(%d: %s)", __func__,
           out->usecase, use_case_table[out->usecase]);
@@ -2979,6 +3072,8 @@
     /* 2. Disable the rx device */
     disable_snd_device(adev, uc_info->out_snd_device);
 
+    audio_extn_extspk_update(adev->extspk);
+
     if (is_offload_usecase(out->usecase)) {
         audio_enable_asm_bit_width_enforce_mode(adev->mixer,
                                                 adev->dsp_bit_width_enforce_mode,
@@ -3016,6 +3111,22 @@
             ALOGE("%s: audio_extn_ip_hdlr_intf_close failed %d",__func__, ret);
     }
 
+    if (has_voip_usecase ||
+            out->devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
+        struct listnode *node;
+        struct audio_usecase *usecase;
+        list_for_each(node, &adev->usecase_list) {
+            usecase = node_to_item(node, struct audio_usecase, list);
+            if (usecase->type == PCM_CAPTURE || usecase == uc_info)
+                continue;
+
+            ALOGD("%s: select_devices at usecase(%d: %s) after removing the usecase(%d: %s)",
+                __func__, usecase->id, use_case_table[usecase->id],
+                out->usecase, use_case_table[out->usecase]);
+            select_devices(adev, usecase->id);
+        }
+    }
+
     free(uc_info);
     ALOGV("%s: exit: status(%d)", __func__, ret);
     return ret;
@@ -3050,7 +3161,8 @@
 
     if (out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
         if (!audio_extn_a2dp_source_is_ready()) {
-            if (out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
+            if (out->devices &
+                (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
                 a2dp_combo = true;
             } else {
                 if (!(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) {
@@ -3124,7 +3236,10 @@
             check_a2dp_restore_l(adev, out, false);
         } else {
             audio_devices_t dev = out->devices;
-            out->devices = AUDIO_DEVICE_OUT_SPEAKER;
+            if (dev & AUDIO_DEVICE_OUT_SPEAKER_SAFE)
+                out->devices = AUDIO_DEVICE_OUT_SPEAKER_SAFE;
+            else
+                out->devices = AUDIO_DEVICE_OUT_SPEAKER;
             select_devices(adev, out->usecase);
             out->devices = dev;
         }
@@ -3355,7 +3470,8 @@
 
 static int check_input_parameters(uint32_t sample_rate,
                                   audio_format_t format,
-                                  int channel_count)
+                                  int channel_count,
+                                  bool is_usb_hifi)
 {
     int ret = 0;
 
@@ -3367,6 +3483,13 @@
         !audio_extn_cin_format_supported(format))
             ret = -EINVAL;
 
+    int max_channel_count = is_usb_hifi ? MAX_HIFI_CHANNEL_COUNT : MAX_CHANNEL_COUNT;
+    if ((channel_count < MIN_CHANNEL_COUNT) || (channel_count > max_channel_count)) {
+        ALOGE("%s: unsupported channel count (%d) passed  Min / Max (%d / %d)", __func__,
+               channel_count, MIN_CHANNEL_COUNT, max_channel_count);
+        return -EINVAL;
+    }
+
     switch (channel_count) {
     case 1:
     case 2:
@@ -3480,23 +3603,21 @@
     return num;
 }
 
-static size_t get_input_buffer_size(uint32_t sample_rate,
-                                    audio_format_t format,
-                                    int channel_count,
-                                    bool is_low_latency)
+static size_t get_stream_buffer_size(size_t duration_ms,
+                                     uint32_t sample_rate,
+                                     audio_format_t format,
+                                     int channel_count,
+                                     bool is_low_latency)
 {
     size_t size = 0;
     uint32_t bytes_per_period_sample = 0;
 
-    if (check_input_parameters(sample_rate, format, channel_count) != 0)
-        return 0;
-
-    size = (sample_rate * AUDIO_CAPTURE_PERIOD_DURATION_MSEC) / 1000;
+    size = (sample_rate * duration_ms) / 1000;
     if (is_low_latency)
         size = configured_low_latency_capture_period_size;
 
     bytes_per_period_sample = audio_bytes_per_sample(format) * channel_count;
-    size *= bytes_per_period_sample;
+    size *= audio_bytes_per_sample(format) * channel_count;
 
     /* make sure the size is multiple of 32 bytes and additionally multiple of
      * the frame_size (required for 24bit samples and non-power-of-2 channel counts)
@@ -3510,6 +3631,23 @@
     return size;
 }
 
+static size_t get_input_buffer_size(uint32_t sample_rate,
+                                    audio_format_t format,
+                                    int channel_count,
+                                    bool is_low_latency)
+{
+    /* Don't know if USB HIFI in this context so use true to be conservative */
+    if (check_input_parameters(sample_rate, format, channel_count,
+                               true /*is_usb_hifi */) != 0)
+        return 0;
+
+    return get_stream_buffer_size(AUDIO_CAPTURE_PERIOD_DURATION_MSEC,
+                                  sample_rate,
+                                  format,
+                                  channel_count,
+                                  is_low_latency);
+}
+
 static size_t get_output_period_size(uint32_t sample_rate,
                                     audio_format_t format,
                                     int channel_count,
@@ -3764,9 +3902,25 @@
     return 0;
 }
 
-static int out_dump(const struct audio_stream *stream __unused,
-                    int fd __unused)
+static int out_dump(const struct audio_stream *stream, int fd)
 {
+    struct stream_out *out = (struct stream_out *)stream;
+
+    // We try to get the lock for consistency,
+    // but it isn't necessary for these variables.
+    // If we're not in standby, we may be blocked on a write.
+    const bool locked = (pthread_mutex_trylock(&out->lock) == 0);
+    dprintf(fd, "      Standby: %s\n", out->standby ? "yes" : "no");
+    dprintf(fd, "      Frames written: %lld\n", (long long)out->written);
+
+    if (locked) {
+        pthread_mutex_unlock(&out->lock);
+    }
+
+    // dump error info
+    (void)error_log_dump(
+            out->error_log, fd, "      " /* prefix */, 0 /* lines */, 0 /* limit_ns */);
+
     return 0;
 }
 
@@ -3912,7 +4066,8 @@
          */
         if (val & AUDIO_DEVICE_OUT_ALL_A2DP) {
             if (!audio_extn_a2dp_source_is_ready()) {
-                if (val & AUDIO_DEVICE_OUT_SPEAKER) {
+                if (val &
+                    (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
                     //combo usecase just by pass a2dp
                     ALOGW("%s: A2DP profile is not ready,routing to speaker only", __func__);
                     bypass_a2dp = true;
@@ -4000,7 +4155,10 @@
                 if (!bypass_a2dp) {
                     select_devices(adev, out->usecase);
                 } else {
-                    out->devices = AUDIO_DEVICE_OUT_SPEAKER;
+                    if (new_dev & AUDIO_DEVICE_OUT_SPEAKER_SAFE)
+                        out->devices = AUDIO_DEVICE_OUT_SPEAKER_SAFE;
+                    else
+                        out->devices = AUDIO_DEVICE_OUT_SPEAKER;
                     select_devices(adev, out->usecase);
                     out->devices = new_dev;
                 }
@@ -4026,6 +4184,9 @@
 
         pthread_mutex_unlock(&adev->lock);
         pthread_mutex_unlock(&out->lock);
+
+        /*handles device and call state changes*/
+        audio_extn_extspk_update(adev->extspk);
     }
     routing_fail:
 
@@ -4504,8 +4665,14 @@
             return ret;
         }
     } else if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP) {
-        if (!out->standby)
+        out->app_type_cfg.gain[0] = (int)(left * VOIP_PLAYBACK_VOLUME_MAX);
+        out->app_type_cfg.gain[1] = (int)(right * VOIP_PLAYBACK_VOLUME_MAX);
+        if (!out->standby) {
+            audio_extn_utils_send_app_type_gain(out->dev,
+                                                out->app_type_cfg.app_type,
+                                                &out->app_type_cfg.gain[0]);
             ret = out_set_voip_volume(stream, left, right);
+        }
         out->volume_l = left;
         out->volume_r = right;
         return ret;
@@ -4545,6 +4712,24 @@
     pthread_mutex_unlock(&out->position_query_lock);
 }
 
+#ifdef NO_AUDIO_OUT
+static ssize_t out_write_for_no_output(struct audio_stream_out *stream,
+                                       const void *buffer __unused, size_t bytes)
+{
+    struct stream_out *out = (struct stream_out *)stream;
+
+    /* No Output device supported other than BT for playback.
+     * Sleep for the amount of buffer duration
+     */
+    lock_output_stream(out);
+    usleep(bytes * 1000000 / audio_stream_out_frame_size(
+            (const struct audio_stream_out *)&out->stream) /
+            out_get_sample_rate(&out->stream.common));
+    pthread_mutex_unlock(&out->lock);
+    return bytes;
+}
+#endif
+
 static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
                          size_t bytes)
 {
@@ -4632,7 +4817,8 @@
 
     if ((out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) &&
         (audio_extn_a2dp_source_is_suspended())) {
-        if (!(out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
+        if (!(out->devices &
+            (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE))) {
             if (!(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) {
                 ret = -EIO;
                 goto exit;
@@ -4683,7 +4869,7 @@
             out->send_new_metadata = 0;
             if (out->send_next_track_params && out->is_compr_metadata_avail) {
                 ALOGD("copl(%p):send next track params in gapless", out);
-                compress_set_next_track_param(out->compr, &(out->compr_config.codec->options));
+                // compress_set_next_track_param(out->compr, &(out->compr_config.codec->options));
                 out->send_next_track_params = false;
                 out->is_compr_metadata_avail = false;
             }
@@ -4777,14 +4963,18 @@
             ALOGV("%s: frames=%zu, frame_size=%zu, bytes_to_write=%zu",
                      __func__, frames, frame_size, bytes_to_write);
 
-            if (out->usecase == USECASE_INCALL_MUSIC_UPLINK) {
+            if (out->usecase == USECASE_INCALL_MUSIC_UPLINK ||
+                (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP
+                    && !voice_extn_is_compress_voip_supported()) ||
+                out->usecase == USECASE_INCALL_MUSIC_UPLINK2) {
                 size_t channel_count = audio_channel_count_from_out_mask(out->channel_mask);
                 int16_t *src = (int16_t *)buffer;
                 int16_t *dst = (int16_t *)buffer;
 
                 LOG_ALWAYS_FATAL_IF(out->config.channels != 1 || channel_count != 2 ||
                                     out->format != AUDIO_FORMAT_PCM_16_BIT,
-                                    "out_write called for incall music use case with wrong properties");
+                                    "out_write called for %s use case with wrong properties",
+                                    use_case_table[out->usecase]);
 
                 /*
                  * FIXME: this can be removed once audio flinger mixer supports
@@ -5446,6 +5636,8 @@
                 ATRACE_END();
                 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);
@@ -5455,9 +5647,27 @@
     return status;
 }
 
-static int in_dump(const struct audio_stream *stream __unused,
-                   int fd __unused)
+static int in_dump(const struct audio_stream *stream,
+                   int fd)
 {
+    struct stream_in *in = (struct stream_in *)stream;
+
+    // We try to get the lock for consistency,
+    // but it isn't necessary for these variables.
+    // If we're not in standby, we may be blocked on a read.
+    const bool locked = (pthread_mutex_trylock(&in->lock) == 0);
+    dprintf(fd, "      Standby: %s\n", in->standby ? "yes" : "no");
+    dprintf(fd, "      Frames read: %lld\n", (long long)in->frames_read);
+    dprintf(fd, "      Frames muted: %lld\n", (long long)in->frames_muted);
+
+    if (locked) {
+        pthread_mutex_unlock(&in->lock);
+    }
+
+    // dump error info
+    (void)error_log_dump(
+            in->error_log, fd, "      " /* prefix */, 0 /* lines */, 0 /* limit_ns */);
+
     return 0;
 }
 
@@ -5622,9 +5832,40 @@
     return str;
 }
 
-static int in_set_gain(struct audio_stream_in *stream __unused,
-                       float gain __unused)
+static int in_set_gain(struct audio_stream_in *stream,
+                       float gain)
 {
+    struct stream_in *in = (struct stream_in *)stream;
+    char mixer_ctl_name[128];
+    struct mixer_ctl *ctl;
+    int ctl_value;
+
+    ALOGV("%s: gain %f", __func__, gain);
+
+    if (stream == NULL)
+        return -EINVAL;
+
+    /* in_set_gain() only used to silence MMAP capture for now */
+    if (in->usecase != USECASE_AUDIO_RECORD_MMAP)
+        return -ENOSYS;
+
+    snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "Capture %d Volume", in->pcm_device_id);
+
+    ctl = mixer_get_ctl_by_name(in->dev->mixer, mixer_ctl_name);
+    if (!ctl) {
+        ALOGW("%s: Could not get ctl for mixer cmd - %s",
+              __func__, mixer_ctl_name);
+        return -ENOSYS;
+    }
+
+    if (gain < RECORD_GAIN_MIN)
+        gain  = RECORD_GAIN_MIN;
+    else if (gain > RECORD_GAIN_MAX)
+         gain = RECORD_GAIN_MAX;
+    ctl_value = (int)(RECORD_VOLUME_CTL_MAX * gain);
+
+    mixer_ctl_set_value(ctl, 0, ctl_value);
+
     return 0;
 }
 
@@ -5747,6 +5988,38 @@
     return 0;
 }
 
+static int in_get_capture_position(const struct audio_stream_in *stream,
+                                   int64_t *frames, int64_t *time)
+{
+    if (stream == NULL || frames == NULL || time == NULL) {
+        return -EINVAL;
+    }
+    struct stream_in *in = (struct stream_in *)stream;
+    int ret = -ENOSYS;
+
+    lock_input_stream(in);
+    // note: ST sessions do not close the alsa pcm driver synchronously
+    // on standby. Therefore, we may return an error even though the
+    // pcm stream is still opened.
+    if (in->standby) {
+        ALOGE_IF(in->pcm != NULL && !in->is_st_session,
+                 "%s stream in standby but pcm not NULL for non ST session", __func__);
+        goto exit;
+    }
+    if (in->pcm) {
+        struct timespec timestamp;
+        unsigned int avail;
+        if (pcm_get_htimestamp(in->pcm, &avail, &timestamp) == 0) {
+            *frames = in->frames_read + avail;
+            *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec;
+            ret = 0;
+        }
+    }
+exit:
+    pthread_mutex_unlock(&in->lock);
+    return ret;
+}
+
 static int add_remove_audio_effect(const struct audio_stream *stream,
                                    effect_handle_t effect,
                                    bool enable)
@@ -5764,10 +6037,24 @@
     lock_input_stream(in);
     pthread_mutex_lock(&in->dev->lock);
     if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
+         in->source == AUDIO_SOURCE_VOICE_RECOGNITION ||
          in->dev->mode == AUDIO_MODE_IN_COMMUNICATION) &&
             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);
+        if (in->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
+            in->dev->mode == AUDIO_MODE_IN_COMMUNICATION) {
+            in->dev->enable_voicerx = enable;
+            struct audio_usecase *usecase;
+            struct listnode *node;
+            list_for_each(node, &in->dev->usecase_list) {
+                usecase = node_to_item(node, struct audio_usecase, list);
+                if (usecase->type == PCM_PLAYBACK)
+                    select_devices(in->dev, usecase->id);
+            }
+        }
         if (!in->standby) {
             if (enable_disable_effect(in->dev, EFFECT_AEC, enable) == ENOSYS)
                 select_devices(in->dev, in->usecase);
@@ -6015,6 +6302,8 @@
     bool is_usb_dev = audio_is_usb_out_device(devices) &&
                       (devices != AUDIO_DEVICE_OUT_USB_ACCESSORY);
     bool direct_dev = is_hdmi || is_usb_dev;
+    bool use_db_as_primary =
+                audio_feature_manager_is_feature_enabled(USE_DEEP_BUFFER_AS_PRIMARY_OUTPUT);
 
     if (is_usb_dev && (!audio_extn_usb_connected(NULL))) {
         is_usb_dev = false;
@@ -6069,13 +6358,25 @@
         (property_get_bool("vendor.audio.matrix.limiter.enable", false)))
         platform_set_device_params(out, DEVICE_PARAM_LIMITER_ID, 1);
 
-    if (audio_is_linear_pcm(out->format) &&
-        out->flags == AUDIO_OUTPUT_FLAG_NONE && direct_dev) {
-       pthread_mutex_lock(&adev->lock);
-       if (is_hdmi) {
-           ALOGV("AUDIO_DEVICE_OUT_AUX_DIGITAL and DIRECT|OFFLOAD, check hdmi caps");
-           ret = read_hdmi_sink_caps(out);
-       } else if (is_usb_dev) {
+    if (direct_dev &&
+        (audio_is_linear_pcm(out->format) ||
+         config->format == AUDIO_FORMAT_DEFAULT) &&
+        out->flags == AUDIO_OUTPUT_FLAG_NONE) {
+        audio_format_t req_format = config->format;
+        audio_channel_mask_t req_channel_mask = config->channel_mask;
+        uint32_t req_sample_rate = config->sample_rate;
+
+        pthread_mutex_lock(&adev->lock);
+        if (is_hdmi) {
+            ALOGV("AUDIO_DEVICE_OUT_AUX_DIGITAL and DIRECT|OFFLOAD, check hdmi caps");
+            ret = read_hdmi_sink_caps(out);
+            if (config->sample_rate == 0)
+                config->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+            if (config->channel_mask == AUDIO_CHANNEL_NONE)
+                config->channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
+            if (config->format == AUDIO_FORMAT_DEFAULT)
+                config->format = AUDIO_FORMAT_PCM_16_BIT;
+        } else if (is_usb_dev) {
             ret = read_usb_sup_params_and_compare(true /*is_playback*/,
                                                   &config->format,
                                                   &out->supported_formats[0],
@@ -6087,45 +6388,83 @@
                                                   &out->supported_sample_rates[0],
                                                   MAX_SUPPORTED_SAMPLE_RATES);
             ALOGV("plugged dev USB ret %d", ret);
-       } else {
-           ret = -1;
        }
+
        pthread_mutex_unlock(&adev->lock);
        if (ret != 0) {
             if (ret == -ENOSYS) {
                 /* ignore and go with default */
                 ret = 0;
-            } else {
+            }
+            // For MMAP NO IRQ, allow conversions in ADSP
+            else if (is_hdmi || (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) == 0)
+                goto error_open;
+            else {
                 ALOGE("error reading direct dev sink caps");
                 goto error_open;
             }
+
+            if (req_sample_rate != 0 && config->sample_rate != req_sample_rate)
+                config->sample_rate = req_sample_rate;
+            if (req_channel_mask != AUDIO_CHANNEL_NONE && config->channel_mask != req_channel_mask)
+                config->channel_mask = req_channel_mask;
+            if (req_format != AUDIO_FORMAT_DEFAULT && config->format != req_format)
+                config->format = req_format;
         }
+
+        out->sample_rate = config->sample_rate;
+        out->channel_mask = config->channel_mask;
+        out->format = config->format;
+        if (is_hdmi) {
+            out->usecase = USECASE_AUDIO_PLAYBACK_HIFI;
+            out->config = pcm_config_hdmi_multi;
+        } else if (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) {
+            out->usecase = USECASE_AUDIO_PLAYBACK_MMAP;
+            out->config = pcm_config_mmap_playback;
+            out->stream.start = out_start;
+            out->stream.stop = out_stop;
+            out->stream.create_mmap_buffer = out_create_mmap_buffer;
+            out->stream.get_mmap_position = out_get_mmap_position;
+        } else {
+            out->usecase = USECASE_AUDIO_PLAYBACK_HIFI;
+            out->config = pcm_config_hifi;
+        }
+
+        out->config.rate = out->sample_rate;
+        out->config.channels = audio_channel_count_from_out_mask(out->channel_mask);
+        if (is_hdmi) {
+            out->config.period_size = HDMI_MULTI_PERIOD_BYTES / (out->config.channels *
+                                                         audio_bytes_per_sample(out->format));
+        }
+        out->config.format = pcm_format_from_audio_format(out->format);
     }
 
-    /* Init use case and pcm_config */
-#ifndef COMPRESS_VOIP_ENABLED
-    if (out->flags == (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_VOIP_RX) &&
-        (out->sample_rate == 8000 || out->sample_rate == 16000 ||
-         out->sample_rate == 32000 || out->sample_rate == 48000)) {
-        out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_MONO;
-        out->channel_mask = AUDIO_CHANNEL_OUT_MONO;
-        out->usecase = USECASE_AUDIO_PLAYBACK_VOIP;
+    /* Check for VOIP usecase */
+    if(out->flags == (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_VOIP_RX)) {
+        if (!voice_extn_is_compress_voip_supported()) {
+            if (out->sample_rate == 8000 || out->sample_rate == 16000 ||
+             out->sample_rate == 32000 || out->sample_rate == 48000) {
+                //FIXME: add support for MONO stream configuration when audioflinger mixer supports it
+                out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+                out->usecase = USECASE_AUDIO_PLAYBACK_VOIP;
+                out->format = AUDIO_FORMAT_PCM_16_BIT;
 
-        out->config = default_pcm_config_voip_copp;
-        out->config.period_size = VOIP_IO_BUF_SIZE(out->sample_rate, DEFAULT_VOIP_BUF_DURATION_MS, DEFAULT_VOIP_BIT_DEPTH_BYTE)/2;
-        out->config.rate = out->sample_rate;
-
-#else
-    if ((out->dev->mode == AUDIO_MODE_IN_COMMUNICATION || voice_extn_compress_voip_is_active(out->dev)) &&
-               (out->flags == (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_VOIP_RX)) &&
-               (voice_extn_compress_voip_is_config_supported(config))) {
-        ret = voice_extn_compress_voip_open_output_stream(out);
-        if (ret != 0) {
-            ALOGE("%s: Compress voip output cannot be opened, error:%d",
-                  __func__, ret);
-            goto error_open;
+                out->config = default_pcm_config_voip_copp;
+                out->config.period_size = VOIP_IO_BUF_SIZE(out->sample_rate, DEFAULT_VOIP_BUF_DURATION_MS, DEFAULT_VOIP_BIT_DEPTH_BYTE)/2;
+                out->config.rate = out->sample_rate;
+            }
+        } else {
+                if ((out->dev->mode == AUDIO_MODE_IN_COMMUNICATION ||
+                    voice_extn_compress_voip_is_active(out->dev)) &&
+                       (voice_extn_compress_voip_is_config_supported(config))) {
+                    ret = voice_extn_compress_voip_open_output_stream(out);
+                    if (ret != 0) {
+                        ALOGE("%s: Compress voip output cannot be opened, error:%d",
+                              __func__, ret);
+                        goto error_open;
+                    }
+                }
         }
-#endif
     } else if (audio_is_linear_pcm(out->format) &&
         out->flags == AUDIO_OUTPUT_FLAG_NONE && is_usb_dev) {
         out->channel_mask = config->channel_mask;
@@ -6442,26 +6781,60 @@
             goto error_open;
         }
     } else if (out->devices == AUDIO_DEVICE_OUT_TELEPHONY_TX) {
-        if (config->sample_rate == 0)
-            config->sample_rate = AFE_PROXY_SAMPLING_RATE;
-        if (config->sample_rate != 48000 && config->sample_rate != 16000 &&
-                config->sample_rate != 8000) {
-            config->sample_rate = AFE_PROXY_SAMPLING_RATE;
-            ret = -EINVAL;
-            goto error_open;
+        switch (config->sample_rate) {
+            case 0:
+                out->sample_rate = AFE_PROXY_SAMPLING_RATE;
+                break;
+            case 8000:
+            case 16000:
+            case 48000:
+                out->sample_rate = config->sample_rate;
+                break;
+            default:
+                ALOGE("%s: Unsupported sampling rate %d for Telephony TX", __func__,
+                      config->sample_rate);
+                config->sample_rate = AFE_PROXY_SAMPLING_RATE;
+                ret = -EINVAL;
+                break;
         }
-        out->sample_rate = config->sample_rate;
-        out->config.rate = config->sample_rate;
-        if (config->format == AUDIO_FORMAT_DEFAULT)
-            config->format = AUDIO_FORMAT_PCM_16_BIT;
-        if (config->format != AUDIO_FORMAT_PCM_16_BIT) {
-            config->format = AUDIO_FORMAT_PCM_16_BIT;
-            ret = -EINVAL;
-            goto error_open;
+        //FIXME: add support for MONO stream configuration when audioflinger mixer supports it
+        switch (config->channel_mask) {
+            case AUDIO_CHANNEL_NONE:
+                out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+                break;
+            case AUDIO_CHANNEL_OUT_STEREO:
+                out->channel_mask = config->channel_mask;
+                break;
+            default:
+                ALOGE("%s: Unsupported channel mask %#x for Telephony TX", __func__,
+                      config->channel_mask);
+                config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+                ret = -EINVAL;
+                break;
         }
-        out->format = config->format;
+        switch (config->format) {
+            case AUDIO_FORMAT_DEFAULT:
+                out->format = AUDIO_FORMAT_PCM_16_BIT;
+                break;
+            case AUDIO_FORMAT_PCM_16_BIT:
+                out->format = config->format;
+                break;
+            default:
+                ALOGE("%s: Unsupported format %#x for Telephony TX", __func__,
+                      config->format);
+                config->format = AUDIO_FORMAT_PCM_16_BIT;
+                ret = -EINVAL;
+                break;
+        }
+        if (ret != 0)
+            goto error_open;
+
         out->usecase = USECASE_AUDIO_PLAYBACK_AFE_PROXY;
         out->config = pcm_config_afe_proxy_playback;
+        out->config.rate = out->sample_rate;
+        out->config.channels =
+                audio_channel_count_from_out_mask(out->channel_mask);
+        out->config.format = pcm_format_from_audio_format(out->format);
         adev->voice_tx_output = out;
     } else {
         unsigned int channels = 0;
@@ -6518,10 +6891,13 @@
                 ret = -EINVAL;
                 goto error_open;
             }
+        } else if (flags & AUDIO_OUTPUT_FLAG_TTS) {
+            out->usecase = USECASE_AUDIO_PLAYBACK_TTS;
+            out->config = pcm_config_deep_buffer;
         } else {
             /* primary path is the default path selected if no other outputs are available/suitable */
-            out->usecase = USECASE_AUDIO_PLAYBACK_PRIMARY;
-            out->config = PCM_CONFIG_AUDIO_PLAYBACK_PRIMARY;
+            out->usecase = GET_USECASE_AUDIO_PLAYBACK_PRIMARY(use_db_as_primary);
+            out->config = GET_PCM_CONFIG_AUDIO_PLAYBACK_PRIMARY(use_db_as_primary);
         }
         out->hal_ip_format = format = out->format;
         out->config.format = hal_format_to_pcm(out->hal_ip_format);
@@ -6556,7 +6932,7 @@
                                                 devices, out->flags, out->hal_op_format, out->sample_rate,
                                                 out->bit_width, out->channel_mask, out->profile,
                                                 &out->app_type_cfg);
-    if ((out->usecase == USECASE_AUDIO_PLAYBACK_PRIMARY) ||
+    if ((out->usecase == GET_USECASE_AUDIO_PLAYBACK_PRIMARY(use_db_as_primary)) ||
         (flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {
         /* Ensure the default output is not selected twice */
         if(adev->primary_output == NULL)
@@ -6594,7 +6970,11 @@
     out->stream.common.remove_audio_effect = out_remove_audio_effect;
     out->stream.get_latency = out_get_latency;
     out->stream.set_volume = out_set_volume;
+#ifdef NO_AUDIO_OUT
+    out->stream.write = out_write_for_no_output;
+#else
     out->stream.write = out_write;
+#endif
     out->stream.get_render_position = out_get_render_position;
     out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
     out->stream.get_presentation_position = out_get_presentation_position;
@@ -6615,6 +6995,10 @@
     register_channel_mask(out->channel_mask, out->supported_channel_masks);
     register_sample_rate(out->sample_rate, out->supported_sample_rates);
 
+    out->error_log = error_log_create(
+            ERROR_LOG_ENTRIES,
+            1000000000 /* aggregate consecutive identical errors within one second in ns */);
+
     /*
        By locking output stream before registering, we allow the callback
        to update stream's state only after stream's initial state is set to
@@ -6627,6 +7011,8 @@
     pthread_mutex_unlock(&adev->lock);
     pthread_mutex_unlock(&out->lock);
 
+    stream_app_type_cfg_init(&out->app_type_cfg);
+
     *stream_out = &out->stream;
     ALOGD("%s: Stream (%p) picks up usecase (%s)", __func__, &out->stream,
            use_case_table[out->usecase]);
@@ -6727,6 +7113,9 @@
     if (adev->voice_tx_output == out)
         adev->voice_tx_output = NULL;
 
+    error_log_destroy(out->error_log);
+    out->error_log = NULL;
+
     if (adev->primary_output == out)
         adev->primary_output = NULL;
 
@@ -6744,6 +7133,7 @@
     int val;
     int ret;
     int status = 0;
+    bool a2dp_reconfig = false;
 
     ALOGD("%s: enter: %s", __func__, kvpairs);
     parms = str_parms_create_str(kvpairs);
@@ -6786,6 +7176,7 @@
             adev->screen_off = true;
     }
 
+#ifndef MAXXAUDIO_QDSP_ENABLED
     ret = str_parms_get_int(parms, "rotation", &val);
     if (ret >= 0) {
         bool reverse_speakers = false;
@@ -6811,6 +7202,7 @@
             platform_check_and_set_swap_lr_channels(adev, reverse_speakers);
         }
     }
+#endif
 
     ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_SCO_WB, value, sizeof(value));
     if (ret >= 0) {
@@ -6874,8 +7266,11 @@
         }
     }
 
-    ret = str_parms_get_str(parms,"reconfigA2dp", value, sizeof(value));
-    if (ret >= 0) {
+    audio_extn_hfp_set_parameters(adev, parms);
+    audio_extn_qdsp_set_parameters(adev, parms);
+
+    status = audio_extn_a2dp_set_parameters(parms, &a2dp_reconfig);
+    if (ret >= 0 && a2dp_reconfig) {
         struct audio_usecase *usecase;
         struct listnode *node;
         list_for_each(node, &adev->usecase_list) {
@@ -6973,6 +7368,7 @@
     pthread_mutex_lock(&adev->lock);
     audio_extn_get_parameters(adev, query, reply);
     voice_get_parameters(adev, query, reply);
+    audio_extn_a2dp_get_parameters(query, reply);
     platform_get_parameters(adev->platform, query, reply);
     pthread_mutex_unlock(&adev->lock);
 
@@ -6994,6 +7390,9 @@
 {
     int ret;
     struct audio_device *adev = (struct audio_device *)dev;
+
+    audio_extn_extspk_set_voice_vol(adev->extspk, volume);
+
     pthread_mutex_lock(&adev->lock);
     /* cache volume */
     ret = voice_set_volume(adev, volume);
@@ -7066,12 +7465,16 @@
 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
 {
     int ret;
+    struct audio_device *adev = (struct audio_device *)dev;
 
     pthread_mutex_lock(&adev->lock);
     ALOGD("%s state %d\n", __func__, state);
     ret = voice_set_mic_mute((struct audio_device *)dev, state);
+
     if (adev->ext_hw_plugin)
         ret = audio_extn_ext_hw_plugin_set_mic_mute(adev->ext_hw_plugin, state);
+
+    adev->mic_muted = state;
     pthread_mutex_unlock(&adev->lock);
 
     return ret;
@@ -7088,6 +7491,11 @@
 {
     int channel_count = audio_channel_count_from_in_mask(config->channel_mask);
 
+    /* Don't know if USB HIFI in this context so use true to be conservative */
+    if (check_input_parameters(config->sample_rate, config->format, channel_count,
+                               true /*is_usb_hifi */) != 0)
+        return 0;
+
     return get_input_buffer_size(config->sample_rate, config->format, channel_count,
             false /* is_low_latency: since we don't know, be conservative */);
 }
@@ -7138,36 +7546,36 @@
                        config->sample_rate == 48000);
     bool valid_ch = audio_channel_count_from_in_mask(in->channel_mask) == 1;
 
-#ifndef COMPRESS_VOIP_ENABLED
-    if (valid_rate && valid_ch &&
+    if(!voice_extn_is_compress_voip_supported()) {
+        if (valid_rate && valid_ch &&
         in->dev->mode == AUDIO_MODE_IN_COMMUNICATION) {
         in->usecase = USECASE_AUDIO_RECORD_VOIP;
         in->config = default_pcm_config_voip_copp;
         in->config.period_size = VOIP_IO_BUF_SIZE(in->sample_rate,
                                                   DEFAULT_VOIP_BUF_DURATION_MS,
                                                   DEFAULT_VOIP_BIT_DEPTH_BYTE)/2;
-    } else {
-        ALOGW("%s No valid input in voip, use defaults"
-               "sample rate %u, channel mask 0x%X",
-               __func__, config->sample_rate, in->channel_mask);
-    }
-    in->config.rate = config->sample_rate;
-    in->sample_rate = config->sample_rate;
-#else
-    //XXX needed for voice_extn_compress_voip_open_input_stream
-    in->config.rate = config->sample_rate;
-    if ((in->dev->mode == AUDIO_MODE_IN_COMMUNICATION ||
-         voice_extn_compress_voip_is_active(in->dev)) &&
-        (voice_extn_compress_voip_is_format_supported(in->format)) &&
-        valid_rate && valid_ch) {
-        voice_extn_compress_voip_open_input_stream(in);
-        // update rate entries to match config from AF
+        } else {
+            ALOGW("%s No valid input in voip, use defaults"
+                   "sample rate %u, channel mask 0x%X",
+                   __func__, config->sample_rate, in->channel_mask);
+        }
         in->config.rate = config->sample_rate;
         in->sample_rate = config->sample_rate;
     } else {
-        ALOGW("%s compress voip not active, use defaults", __func__);
+        //XXX needed for voice_extn_compress_voip_open_input_stream
+        in->config.rate = config->sample_rate;
+        if ((in->dev->mode == AUDIO_MODE_IN_COMMUNICATION ||
+             voice_extn_compress_voip_is_active(in->dev)) &&
+            (voice_extn_compress_voip_is_format_supported(in->format)) &&
+            valid_rate && valid_ch) {
+            voice_extn_compress_voip_open_input_stream(in);
+            // update rate entries to match config from AF
+            in->config.rate = config->sample_rate;
+            in->sample_rate = config->sample_rate;
+        } else {
+            ALOGW("%s compress voip not active, use defaults", __func__);
+        }
     }
-#endif
     return 0;
 }
 
@@ -7211,7 +7619,8 @@
 
         channel_count = audio_channel_count_from_in_mask(config->channel_mask);
 
-        if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0)
+        if (check_input_parameters(config->sample_rate, config->format, channel_count,
+                                   false) != 0)
             return -EINVAL;
     }
 
@@ -7243,6 +7652,7 @@
     in->stream.set_gain = in_set_gain;
     in->stream.read = in_read;
     in->stream.get_input_frames_lost = in_get_input_frames_lost;
+    in->stream.get_capture_position = in_get_capture_position;
     in->stream.get_active_microphones = in_get_active_microphones;
 
     in->device = devices;
@@ -7254,6 +7664,18 @@
     in->bit_width = 16;
     in->af_period_multiplier = 1;
 
+    ALOGV("%s: source = %d, config->channel_mask = %d", __func__, source, config->channel_mask);
+    if (source == AUDIO_SOURCE_VOICE_UPLINK ||
+        source == AUDIO_SOURCE_VOICE_DOWNLINK) {
+        /* Force channel config requested to mono if incall
+           record is being requested for only uplink/downlink */
+        if (config->channel_mask != AUDIO_CHANNEL_IN_MONO) {
+            config->channel_mask = AUDIO_CHANNEL_IN_MONO;
+            ret = -EINVAL;
+            goto err_open;
+        }
+    }
+
     /* Update config params with the requested sample rate and channels */
     if ((in->device == AUDIO_DEVICE_IN_TELEPHONY_RX) &&
           (adev->mode != AUDIO_MODE_IN_CALL)) {
@@ -7329,6 +7751,21 @@
         in->usecase = USECASE_AUDIO_RECORD_LOW_LATENCY;
 #endif
         in->realtime = may_use_noirq_mode(adev, in->usecase, in->flags);
+        if (!in->realtime) {
+            in->config = pcm_config_audio_capture;
+            frame_size = audio_stream_in_frame_size(&in->stream);
+            buffer_size = get_input_buffer_size(config->sample_rate,
+                                                config->format,
+                                                channel_count,
+                                                is_low_latency);
+            in->config.period_size = buffer_size / frame_size;
+            in->config.rate = config->sample_rate;
+            in->af_period_multiplier = 1;
+        } else {
+            // period size is left untouched for rt mode playback
+            in->config = pcm_config_audio_capture_rt;
+            in->af_period_multiplier = af_period_multiplier;
+        }
     }
 
     if ((config->sample_rate == LOW_LATENCY_CAPTURE_SAMPLE_RATE) &&
@@ -7397,11 +7834,46 @@
         in->config.channels = channel_count;
         in->config.rate = config->sample_rate;
         in->sample_rate = config->sample_rate;
+        in->af_period_multiplier = 1;
+    } else if (in->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
+               in->flags & AUDIO_INPUT_FLAG_VOIP_TX &&
+               (config->sample_rate == 8000 ||
+                config->sample_rate == 16000 ||
+                config->sample_rate == 32000 ||
+                config->sample_rate == 48000) &&
+               channel_count == 1) {
+        in->usecase = USECASE_AUDIO_RECORD_VOIP;
+        in->config = pcm_config_audio_capture;
+        frame_size = audio_stream_in_frame_size(&in->stream);
+        buffer_size = get_stream_buffer_size(VOIP_CAPTURE_PERIOD_DURATION_MSEC,
+                                             config->sample_rate,
+                                             config->format,
+                                             channel_count, false /*is_low_latency*/);
+        in->config.period_size = buffer_size / frame_size;
+        in->config.period_count = VOIP_CAPTURE_PERIOD_COUNT;
+        in->config.rate = config->sample_rate;
+        in->af_period_multiplier = 1;
     } else {
         int ret_val;
         pthread_mutex_lock(&adev->lock);
         ret_val = audio_extn_check_and_set_multichannel_usecase(adev,
                in, config, &channel_mask_updated);
+#ifdef CONCURRENT_CAPTURE_ENABLED
+        /* Acquire lock to avoid two concurrent use cases initialized to
+            same pcm record use case*/
+
+        if(in->usecase == USECASE_AUDIO_RECORD) {
+            if (!(adev->pcm_record_uc_state)) {
+                ALOGV("%s: using USECASE_AUDIO_RECORD",__func__);
+                adev->pcm_record_uc_state = 1;
+            } else {
+                /* Assign compress record use case for second record */
+                in->usecase = USECASE_AUDIO_RECORD_COMPRESS2;
+                in->flags |= AUDIO_INPUT_FLAG_COMPRESS;
+                ALOGV("%s: overriding usecase with USECASE_AUDIO_RECORD_COMPRESS2 and appending compress flag", __func__);
+            }
+        }
+#endif
         pthread_mutex_unlock(&adev->lock);
 
         if (!ret_val) {
@@ -7441,6 +7913,7 @@
             }
 
             in->config.period_size = buffer_size / frame_size;
+            in->af_period_multiplier = 1;
 
             if (in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
                 /* optionally use VOIP usecase depending on config(s) */
@@ -7462,6 +7935,10 @@
     register_channel_mask(in->channel_mask, in->supported_channel_masks);
     register_sample_rate(in->sample_rate, in->supported_sample_rates);
 
+    in->error_log = error_log_create(
+            ERROR_LOG_ENTRIES,
+            1000000000 /* aggregate consecutive identical errors within one second */);
+
     /* This stream could be for sound trigger lab,
        get sound trigger pcm if present */
     audio_extn_sound_trigger_check_and_get_session(in);
@@ -7473,6 +7950,8 @@
     pthread_mutex_unlock(&adev->lock);
     pthread_mutex_unlock(&in->lock);
 
+    stream_app_type_cfg_init(&in->app_type_cfg);
+
     *stream_in = &in->stream;
     ALOGV("%s: exit", __func__);
     return ret;
@@ -7501,6 +7980,9 @@
     if (!adev->active_input && !audio_extn_hfp_is_active(adev))
         platform_set_echo_reference(adev, false, AUDIO_DEVICE_NONE);
 
+    error_log_destroy(in->error_log);
+    in->error_log = NULL;
+
     if (in == NULL) {
         ALOGE("%s: audio_stream_in ptr is NULL", __func__);
         return;
@@ -7517,6 +7999,10 @@
         in_standby(&stream->common);
 
     pthread_mutex_lock(&adev->lock);
+    if (in->usecase == USECASE_AUDIO_RECORD) {
+        adev->pcm_record_uc_state = 0;
+    }
+
     if (audio_extn_ssr_get_stream() == in) {
         audio_extn_ssr_deinit();
     }
@@ -7541,6 +8027,137 @@
     return;
 }
 
+/* verifies input and output devices and their capabilities.
+ *
+ * This verification is required when enabling extended bit-depth or
+ * sampling rates, as not all qcom products support it.
+ *
+ * Suitable for calling only on initialization such as adev_open().
+ * It fills the audio_device use_case_table[] array.
+ *
+ * Has a side-effect that it needs to configure audio routing / devices
+ * in order to power up the devices and read the device parameters.
+ * It does not acquire any hw device lock. Should restore the devices
+ * back to "normal state" upon completion.
+ */
+static int adev_verify_devices(struct audio_device *adev)
+{
+    /* enumeration is a bit difficult because one really wants to pull
+     * the use_case, device id, etc from the hidden pcm_device_table[].
+     * In this case there are the following use cases and device ids.
+     *
+     * [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {0, 0},
+     * [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {15, 15},
+     * [USECASE_AUDIO_PLAYBACK_HIFI] = {1, 1},
+     * [USECASE_AUDIO_PLAYBACK_OFFLOAD] = {9, 9},
+     * [USECASE_AUDIO_RECORD] = {0, 0},
+     * [USECASE_AUDIO_RECORD_LOW_LATENCY] = {15, 15},
+     * [USECASE_VOICE_CALL] = {2, 2},
+     *
+     * USECASE_AUDIO_PLAYBACK_OFFLOAD, USECASE_AUDIO_PLAYBACK_HIFI omitted.
+     * USECASE_VOICE_CALL omitted, but possible for either input or output.
+     */
+
+    /* should be the usecases enabled in adev_open_input_stream() */
+    static const int test_in_usecases[] = {
+             USECASE_AUDIO_RECORD,
+             USECASE_AUDIO_RECORD_LOW_LATENCY, /* does not appear to be used */
+    };
+    /* should be the usecases enabled in adev_open_output_stream()*/
+    static const int test_out_usecases[] = {
+            USECASE_AUDIO_PLAYBACK_DEEP_BUFFER,
+            USECASE_AUDIO_PLAYBACK_LOW_LATENCY,
+    };
+    static const usecase_type_t usecase_type_by_dir[] = {
+            PCM_PLAYBACK,
+            PCM_CAPTURE,
+    };
+    static const unsigned flags_by_dir[] = {
+            PCM_OUT,
+            PCM_IN,
+    };
+
+    size_t i;
+    unsigned dir;
+    const unsigned card_id = adev->snd_card;
+
+    for (dir = 0; dir < 2; ++dir) {
+        const usecase_type_t usecase_type = usecase_type_by_dir[dir];
+        const unsigned flags_dir = flags_by_dir[dir];
+        const size_t testsize =
+                dir ? ARRAY_SIZE(test_in_usecases) : ARRAY_SIZE(test_out_usecases);
+        const int *testcases =
+                dir ? test_in_usecases : test_out_usecases;
+        const audio_devices_t audio_device =
+                dir ? AUDIO_DEVICE_IN_BUILTIN_MIC : AUDIO_DEVICE_OUT_SPEAKER;
+
+        for (i = 0; i < testsize; ++i) {
+            const audio_usecase_t audio_usecase = testcases[i];
+            int device_id;
+            struct pcm_params **pparams;
+            struct stream_out out;
+            struct stream_in in;
+            struct audio_usecase uc_info;
+            int retval;
+
+            pparams = &adev->use_case_table[audio_usecase];
+            pcm_params_free(*pparams); /* can accept null input */
+            *pparams = NULL;
+
+            /* find the device ID for the use case (signed, for error) */
+            device_id = platform_get_pcm_device_id(audio_usecase, usecase_type);
+            if (device_id < 0)
+                continue;
+
+            /* prepare structures for device probing */
+            memset(&uc_info, 0, sizeof(uc_info));
+            uc_info.id = audio_usecase;
+            uc_info.type = usecase_type;
+            if (dir) {
+                adev->active_input = &in;
+                memset(&in, 0, sizeof(in));
+                in.device = audio_device;
+                in.source = AUDIO_SOURCE_VOICE_COMMUNICATION;
+                uc_info.stream.in = &in;
+            }  else {
+                adev->active_input = NULL;
+            }
+            memset(&out, 0, sizeof(out));
+            out.devices = audio_device; /* only field needed in select_devices */
+            uc_info.stream.out = &out;
+            uc_info.devices = audio_device;
+            uc_info.in_snd_device = SND_DEVICE_NONE;
+            uc_info.out_snd_device = SND_DEVICE_NONE;
+            list_add_tail(&adev->usecase_list, &uc_info.list);
+
+            /* select device - similar to start_(in/out)put_stream() */
+            retval = select_devices(adev, audio_usecase);
+            if (retval >= 0) {
+                *pparams = pcm_params_get(card_id, device_id, flags_dir);
+#if LOG_NDEBUG == 0
+                if (*pparams) {
+                    ALOGV("%s: (%s) card %d  device %d", __func__,
+                            dir ? "input" : "output", card_id, device_id);
+                    pcm_params_to_string(*pparams, info, ARRAY_SIZE(info));
+                } else {
+                    ALOGV("%s: cannot locate card %d  device %d", __func__, card_id, device_id);
+                }
+#endif
+            }
+
+            /* deselect device - similar to stop_(in/out)put_stream() */
+            /* 1. Get and set stream specific mixer controls */
+            retval = disable_audio_route(adev, &uc_info);
+            /* 2. Disable the rx device */
+            retval = disable_snd_device(adev,
+                    dir ? uc_info.in_snd_device : uc_info.out_snd_device);
+            list_remove(&uc_info.list);
+        }
+    }
+    adev->active_input = NULL; /* restore adev state */
+    return 0;
+}
+
 int adev_create_audio_patch(struct audio_hw_device *dev,
                             unsigned int num_sources,
                             const struct audio_port_config *sources,
@@ -7584,6 +8201,7 @@
 
 static int adev_close(hw_device_t *device)
 {
+    size_t i;
     struct audio_device *adev = (struct audio_device *)device;
 
     if (!adev)
@@ -7595,6 +8213,8 @@
         audio_extn_snd_mon_unregister_listener(adev);
         audio_extn_sound_trigger_deinit(adev);
         audio_extn_listen_deinit(adev);
+        audio_extn_qdsp_deinit();
+        audio_extn_extspk_deinit(adev->extspk);
         audio_extn_utils_release_streams_cfg_lists(
                       &adev->streams_output_cfg_list,
                       &adev->streams_input_cfg_list);
@@ -7604,6 +8224,9 @@
         audio_extn_gef_deinit();
         free(adev->snd_dev_ref_cnt);
         platform_deinit(adev->platform);
+        for (i = 0; i < ARRAY_SIZE(adev->use_case_table); ++i) {
+            pcm_params_free(adev->use_case_table[i]);
+        }
         if (adev->adm_deinit)
             adev->adm_deinit(adev->adm_data);
         qahwi_deinit(device);
@@ -7788,6 +8411,8 @@
 
     pthread_mutex_init(&adev->lock, (const pthread_mutexattr_t *) NULL);
 
+    // register audio ext hidl at the earliest
+    audio_extn_hidl_init();
 #ifdef DYNAMIC_LOG_ENABLED
     register_for_dynamic_logging("hal");
 #endif
@@ -7831,10 +8456,13 @@
     adev->bt_sco_on = false;
     /* adev->cur_hdmi_channels = 0;  by calloc() */
     adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
+    /* Init audio feature manager */
+    audio_feature_manager_init();
     voice_init(adev);
     list_init(&adev->usecase_list);
     adev->cur_wfd_channels = 2;
     adev->offload_usecases_state = 0;
+    adev->pcm_record_uc_state = 0;
     adev->is_channel_status_set = false;
     adev->perf_lock_opts[0] = 0x101;
     adev->perf_lock_opts[1] = 0x20E;
@@ -7854,6 +8482,8 @@
         return -EINVAL;
     }
 
+    adev->extspk = audio_extn_extspk_init(adev);
+
     if (audio_extn_qaf_is_enabled()) {
         ret = audio_extn_qaf_init(adev);
         if (ret < 0) {
@@ -7887,6 +8517,7 @@
         }
     }
     audio_extn_init(adev);
+    voice_extn_init(adev);
     audio_extn_listen_init(adev, adev->snd_card);
     audio_extn_gef_init(adev);
     audio_extn_hw_loopback_init(adev);
@@ -7950,6 +8581,7 @@
         }
     }
 
+    adev->enable_voicerx = false;
     adev->bt_wb_speech_enabled = false;
     //initialize this to false for now,
     //this will be set to true through set param
@@ -7957,6 +8589,10 @@
 
     audio_extn_ds2_enable(adev);
     *device = &adev->device.common;
+
+    if (k_enable_extended_precision)
+        adev_verify_devices(adev);
+
     adev->dsp_bit_width_enforce_mode =
         adev_init_dsp_bit_width_enforce_mode(adev->mixer);
 
@@ -7968,7 +8604,8 @@
 
     char value[PROPERTY_VALUE_MAX];
     int trial;
-    if (property_get("vendor.audio_hal.period_size", value, NULL) > 0) {
+    if ((property_get("vendor.audio_hal.period_size", value, NULL) > 0) ||
+        (property_get("audio_hal.period_size", value, NULL) > 0)) {
         trial = atoi(value);
         if (period_size_is_plausible_for_low_latency(trial)) {
             pcm_config_low_latency.period_size = trial;
@@ -7977,7 +8614,8 @@
             configured_low_latency_capture_period_size = trial;
         }
     }
-    if (property_get("vendor.audio_hal.in_period_size", value, NULL) > 0) {
+    if ((property_get("vendor.audio_hal.in_period_size", value, NULL) > 0) ||
+        (property_get("audio_hal.in_period_size", value, NULL) > 0)) {
         trial = atoi(value);
         if (period_size_is_plausible_for_low_latency(trial)) {
             configured_low_latency_capture_period_size = trial;
@@ -7986,7 +8624,8 @@
 
     adev->mic_break_enabled = property_get_bool("vendor.audio.mic_break", false);
 
-    if (property_get("vendor.audio_hal.period_multiplier", value, NULL) > 0) {
+    if ((property_get("vendor.audio_hal.period_multiplier",value,NULL) > 0) ||
+        (property_get("audio_hal.period_multiplier",value,NULL) > 0)) {
         af_period_multiplier = atoi(value);
         if (af_period_multiplier < 0)
             af_period_multiplier = 2;
@@ -7996,6 +8635,8 @@
         ALOGV("new period_multiplier = %d", af_period_multiplier);
     }
 
+    audio_extn_qdsp_init(adev->platform);
+
     adev->multi_offload_enable = property_get_bool("vendor.audio.offload.multiple.enabled", false);
     pthread_mutex_unlock(&adev_init_lock);
 
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 8ae84e8..4f93aa9 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -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
@@ -39,12 +39,14 @@
 #define QCOM_AUDIO_HW_H
 
 #include <stdlib.h>
+#include <cutils/str_parms.h>
 #include <cutils/list.h>
 #include <hardware/audio.h>
 #include <tinyalsa/asoundlib.h>
 #include <tinycompress/tinycompress.h>
 
 #include <audio_route/audio_route.h>
+#include <audio_utils/ErrorLog.h>
 #include "audio_defs.h"
 #include "voice.h"
 #include "audio_hw_extn_api.h"
@@ -83,13 +85,16 @@
 #define ACDB_DEV_TYPE_OUT 1
 #define ACDB_DEV_TYPE_IN 2
 
-#define MAX_SUPPORTED_CHANNEL_MASKS 14
+/* support positional and index masks to 8ch */
+#define MAX_SUPPORTED_CHANNEL_MASKS (2 * FCC_8)
 #define MAX_SUPPORTED_FORMATS 15
 #define MAX_SUPPORTED_SAMPLE_RATES 7
 #define DEFAULT_HDMI_OUT_CHANNELS   2
 #define DEFAULT_HDMI_OUT_SAMPLE_RATE 48000
 #define DEFAULT_HDMI_OUT_FORMAT AUDIO_FORMAT_PCM_16_BIT
 
+#define ERROR_LOG_ENTRIES 16
+
 #define SND_CARD_STATE_OFFLINE 0
 #define SND_CARD_STATE_ONLINE 1
 
@@ -142,6 +147,7 @@
     USECASE_AUDIO_PLAYBACK_ULL,
     USECASE_AUDIO_PLAYBACK_MMAP,
     USECASE_AUDIO_PLAYBACK_HIFI,
+    USECASE_AUDIO_PLAYBACK_TTS,
 
     /* FM usecase */
     USECASE_AUDIO_PLAYBACK_FM,
@@ -192,6 +198,7 @@
 
     USECASE_AUDIO_PLAYBACK_AFE_PROXY,
     USECASE_AUDIO_RECORD_AFE_PROXY,
+    USECASE_AUDIO_DSM_FEEDBACK,
 
     USECASE_AUDIO_PLAYBACK_SILENCE,
 
@@ -256,6 +263,7 @@
     int sample_rate;
     uint32_t bit_width;
     int app_type;
+    int gain[2];
 };
 
 struct stream_config {
@@ -363,6 +371,8 @@
     mix_matrix_params_t pan_scale_params;
     mix_matrix_params_t downmix_params;
     bool set_dual_mono;
+
+    error_log_t *error_log;
 };
 
 struct stream_in {
@@ -401,6 +411,11 @@
     audio_channel_mask_t supported_channel_masks[MAX_SUPPORTED_CHANNEL_MASKS + 1];
     audio_format_t supported_formats[MAX_SUPPORTED_FORMATS + 1];
     uint32_t supported_sample_rates[MAX_SUPPORTED_SAMPLE_RATES + 1];
+
+    int64_t frames_read; /* total frames read, not cleared when entering standby */
+    int64_t frames_muted; /* total frames muted, not cleared when entering standby */
+
+    error_log_t *error_log;
 };
 
 typedef enum {
@@ -410,7 +425,8 @@
     VOIP_CALL,
     PCM_HFP_CALL,
     TRANSCODE_LOOPBACK_RX,
-    TRANSCODE_LOOPBACK_TX
+    TRANSCODE_LOOPBACK_TX,
+    USECASE_TYPE_MAX
 } usecase_type_t;
 
 union stream_ptr {
@@ -498,6 +514,9 @@
     bool allow_afe_proxy_usage;
     bool is_charging; // from battery listener
     bool mic_break_enabled;
+    bool enable_hfp;
+    bool mic_muted;
+    bool enable_voicerx;
 
     int snd_card;
     card_status_t card_status;
@@ -505,7 +524,9 @@
     unsigned int cur_codec_backend_bit_width;
     bool is_channel_status_set;
     void *platform;
+    void *extspk;
     unsigned int offload_usecases_state;
+    unsigned int pcm_record_uc_state;
     void *visualizer_lib;
     int (*visualizer_start_output)(audio_io_handle_t, int);
     int (*visualizer_stop_output)(audio_io_handle_t, int);
@@ -547,6 +568,17 @@
     unsigned int interactive_usecase_state;
     bool dp_allowed_for_voice;
     void *ext_hw_plugin;
+
+    /* logging */
+    snd_device_t last_logged_snd_device[AUDIO_USECASE_MAX][2]; /* [out, in] */
+
+    /* The pcm_params use_case_table is loaded by adev_verify_devices() upon
+     * calling adev_open().
+     *
+     * If an entry is not NULL, it can be used to determine if extended precision
+     * or other capabilities are present for the device corresponding to that usecase.
+     */
+    struct pcm_params *use_case_table[AUDIO_USECASE_MAX];
 };
 
 int select_devices(struct audio_device *adev,
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index eb2cecc..d5ae0fb 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -4044,26 +4044,27 @@
          return my_data->ext_disp_type;
     }
 
-#ifdef DISPLAY_PORT_ENABLED
-    struct audio_device *adev = my_data->adev;
-    struct mixer_ctl *ctl;
-    char *mixer_ctl_name = "External Display Type";
+    if (audio_extn_is_display_port_enabled()) {
+        struct audio_device *adev = my_data->adev;
+        struct mixer_ctl *ctl;
+        char *mixer_ctl_name = "External Display Type";
 
-    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
-    if (!ctl) {
-        ALOGE("%s: Could not get ctl for mixer cmd - %s",
-              __func__, mixer_ctl_name);
-        return -EINVAL;
+        ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+        if (!ctl) {
+            ALOGE("%s: Could not get ctl for mixer cmd - %s",
+                  __func__, mixer_ctl_name);
+            return -EINVAL;
+        }
+
+        disp_type = mixer_ctl_get_value(ctl, 0);
+        if (disp_type == EXT_DISPLAY_TYPE_NONE) {
+             ALOGE("%s: Invalid external display type: %d", __func__, disp_type);
+             return -EINVAL;
+        }
+    }else {
+            disp_type = EXT_DISPLAY_TYPE_HDMI;
     }
 
-    disp_type = mixer_ctl_get_value(ctl, 0);
-    if (disp_type == EXT_DISPLAY_TYPE_NONE) {
-         ALOGE("%s: Invalid external display type: %d", __func__, disp_type);
-         return -EINVAL;
-    }
-#else
-    disp_type = EXT_DISPLAY_TYPE_HDMI;
-#endif
     my_data->ext_disp_type = disp_type;
     ALOGD("%s: ext disp type:%s", __func__, (disp_type == EXT_DISPLAY_TYPE_DP) ? "DisplayPort" : "HDMI");
     return disp_type;
@@ -4395,8 +4396,7 @@
     return snd_device;
 }
 
-#ifdef DYNAMIC_ECNS_ENABLED
-static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
+static snd_device_t get_snd_device_for_voice_comm_ecns_enabled(struct platform_data *my_data,
                                                   audio_devices_t out_device,
                                                   audio_devices_t in_device)
 {
@@ -4435,8 +4435,8 @@
 
     return snd_device;
 }
-#else
-static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
+
+static snd_device_t get_snd_device_for_voice_comm_ecns_disabled(struct platform_data *my_data,
                                                   audio_devices_t out_device,
                                                   audio_devices_t in_device)
 {
@@ -4543,7 +4543,16 @@
 
     return snd_device;
 }
-#endif //DYNAMIC_ECNS_ENABLED
+
+static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
+                                                  audio_devices_t out_device,
+                                                  audio_devices_t in_device)
+{
+    if(voice_extn_is_dynamic_ecns_enabled())
+        return get_snd_device_for_voice_comm_ecns_enabled(my_data, out_device, in_device);
+    else
+        return get_snd_device_for_voice_comm_ecns_disabled(my_data, out_device, in_device);
+}
 
 snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
 {
@@ -6206,17 +6215,17 @@
         max_supported_channels = platform_edid_get_max_channels(my_data);
 
         //Check EDID info for supported samplerate
-        if (!edid_is_supported_sr(edid_info,sample_rate)) {
+        if (!audio_extn_edid_is_supported_sr(edid_info,sample_rate)) {
             //check to see if current BE sample rate is supported by EDID
             //else assign the highest sample rate supported by EDID
-            if (edid_is_supported_sr(edid_info,my_data->current_backend_cfg[backend_idx].sample_rate))
+            if (audio_extn_edid_is_supported_sr(edid_info,my_data->current_backend_cfg[backend_idx].sample_rate))
                 sample_rate = my_data->current_backend_cfg[backend_idx].sample_rate;
             else
-                sample_rate = edid_get_highest_supported_sr(edid_info);
+                sample_rate = audio_extn_edid_get_highest_supported_sr(edid_info);
         }
 
         //Check EDID info for supported bit width
-        if (!edid_is_supported_bps(edid_info,bit_width)) {
+        if (!audio_extn_edid_is_supported_bps(edid_info,bit_width)) {
             //reset to current sample rate
             bit_width = my_data->current_backend_cfg[backend_idx].bit_width;
         }
@@ -7211,7 +7220,7 @@
     edid_data[0] = count;
     memcpy(&edid_data[1], block, count);
 
-    if (!edid_get_sink_caps(info, edid_data)) {
+    if (!audio_extn_edid_get_sink_caps(info, edid_data)) {
         ALOGE("%s: Failed to get extn disp sink capabilities", __func__);
         goto fail;
     }
@@ -7420,7 +7429,7 @@
     ret = platform_get_edid_info(platform);
     info = (edid_audio_info *)my_data->edid_info;
     if (ret == 0 && info != NULL) {
-        return edid_is_supported_sr(info, sample_rate);
+        return audio_extn_edid_is_supported_sr(info, sample_rate);
     }
 
     return false;
diff --git a/hal/msm8974/hw_info.c b/hal/msm8974/hw_info.c
index 5d06483..477a5c3 100755
--- a/hal/msm8974/hw_info.c
+++ b/hal/msm8974/hw_info.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.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -33,7 +33,7 @@
 
 #include <stdlib.h>
 #include <dlfcn.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <cutils/str_parms.h>
 #include "audio_hw.h"
 #include "platform.h"
@@ -85,8 +85,8 @@
     SND_DEVICE_IN_VOICE_REC_DMIC_STEREO,
     SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE,
     SND_DEVICE_IN_QUAD_MIC,
-    SND_DEVICE_IN_HANDSET_STEREO_DMIC,
-    SND_DEVICE_IN_SPEAKER_STEREO_DMIC,
+    SND_DEVICE_IN_HANDSET_DMIC_STEREO,
+    SND_DEVICE_IN_SPEAKER_DMIC_STEREO,
 };
 
 static const snd_device_t tomtom_msm8994_CDP_variant_devices[] = {
@@ -106,8 +106,8 @@
     SND_DEVICE_IN_VOICE_REC_DMIC_STEREO,
     SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE,
     SND_DEVICE_IN_QUAD_MIC,
-    SND_DEVICE_IN_HANDSET_STEREO_DMIC,
-    SND_DEVICE_IN_SPEAKER_STEREO_DMIC,
+    SND_DEVICE_IN_HANDSET_DMIC_STEREO,
+    SND_DEVICE_IN_SPEAKER_DMIC_STEREO,
 };
 
 static const snd_device_t tomtom_stp_variant_devices[] = {
@@ -206,8 +206,8 @@
     SND_DEVICE_IN_VOICE_REC_DMIC_STEREO,
     SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE,
     SND_DEVICE_IN_QUAD_MIC,
-    SND_DEVICE_IN_HANDSET_STEREO_DMIC,
-    SND_DEVICE_IN_SPEAKER_STEREO_DMIC,
+    SND_DEVICE_IN_HANDSET_DMIC_STEREO,
+    SND_DEVICE_IN_SPEAKER_DMIC_STEREO,
 };
 
 
@@ -239,8 +239,8 @@
     SND_DEVICE_IN_HANDSET_DMIC_NS,
     SND_DEVICE_IN_HANDSET_DMIC_AEC,
     SND_DEVICE_IN_HANDSET_DMIC_AEC_NS,
-    SND_DEVICE_IN_HANDSET_STEREO_DMIC,
-    SND_DEVICE_IN_SPEAKER_STEREO_DMIC,
+    SND_DEVICE_IN_HANDSET_DMIC_STEREO,
+    SND_DEVICE_IN_SPEAKER_DMIC_STEREO,
     SND_DEVICE_IN_VOICE_SPEAKER_DMIC,
     SND_DEVICE_IN_SPEAKER_DMIC_AEC,
     SND_DEVICE_IN_SPEAKER_DMIC_NS,
@@ -504,6 +504,22 @@
     }
 }
 
+static void update_hardware_info_kona(
+          struct hardware_info *hw_info,
+          const char *snd_card_name)
+{
+    if (!strncmp(snd_card_name, "kona-mtp-snd-card",
+                 sizeof("kona-mtp-snd-card"))) {
+        strlcpy(hw_info->name, "kona", sizeof(hw_info->name));
+    } else if (!strncmp(snd_card_name, "kona-qrd-snd-card",
+                 sizeof("kona-qrd-snd-card"))) {
+        strlcpy(hw_info->name, "kona", sizeof(hw_info->name));
+        hw_info->is_stereo_spkr = false;
+    } else {
+        ALOGW("%s: Not a kona device", __func__);
+    }
+}
+
 static void  update_hardware_info_sda845(struct hardware_info *hw_info, const char *snd_card_name)
 {
     if (!strncmp(snd_card_name, "sda845-tavil-i2s-snd-card", sizeof("sda845-tavil-i2s-snd-card"))) {
@@ -728,6 +744,9 @@
     } else if (strstr(snd_card_name, "sda845")) {
         ALOGV("SDA845 - variant soundcard");
         update_hardware_info_sda845(hw_info, snd_card_name);
+    } else if (strstr(snd_card_name, "kona")) {
+        ALOGV("KONA - variant soundcard");
+        update_hardware_info_kona(hw_info, snd_card_name);
     } else {
         ALOGE("%s: Unsupported target %s:",__func__, snd_card_name);
         free(hw_info);
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 4cf0857..1ebffba 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.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
@@ -31,11 +31,12 @@
 #include <dlfcn.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <cutils/properties.h>
 #include <cutils/str_parms.h>
 #include <audio_hw.h>
 #include <platform_api.h>
+#include <pthread.h>
 #include <unistd.h>
 #include "platform.h"
 #include "audio_extn.h"
@@ -55,9 +56,10 @@
 #define MIXER_FILE_DELIMITER "_"
 #define MIXER_FILE_EXT ".xml"
 
+#define MIXER_XML_BASE_STRING "mixer_paths"
+#define MIXER_XML_DEFAULT_PATH "mixer_paths.xml"
+
 #ifdef LINUX_ENABLED
-#define MIXER_XML_BASE_STRING "/etc/mixer_paths"
-#define MIXER_XML_DEFAULT_PATH "/etc/mixer_paths.xml"
 #define PLATFORM_INFO_XML_PATH_INTCODEC  "/etc/audio_platform_info_intcodec.xml"
 #define PLATFORM_INFO_XML_PATH_SKUSH  "/etc/audio_platform_info_skush.xml"
 #define PLATFORM_INFO_XML_PATH_SKUW  "/etc/audio_platform_info_skuw.xml"
@@ -69,8 +71,6 @@
 #define PLATFORM_INFO_XML_PATH_WSA  "/etc/audio_platform_info_wsa.xml"
 #define PLATFORM_INFO_XML_PATH_TDM  "/etc/audio_platform_info_tdm.xml"
 #else
-#define MIXER_XML_BASE_STRING "/vendor/etc/mixer_paths"
-#define MIXER_XML_DEFAULT_PATH "/vendor/etc/mixer_paths.xml"
 #define PLATFORM_INFO_XML_PATH_INTCODEC  "/vendor/etc/audio_platform_info_intcodec.xml"
 #define PLATFORM_INFO_XML_PATH_SKUSH "/vendor/etc/audio_platform_info_skush.xml"
 #define PLATFORM_INFO_XML_PATH_SKUW "/vendor/etc/audio_platform_info_skuw.xml"
@@ -84,10 +84,20 @@
 #endif
 
 #include <linux/msm_audio.h>
-#if defined (PLATFORM_MSM8998) || (PLATFORM_SDM845) || (PLATFORM_SDM710) || defined (PLATFORM_QCS605) || defined (PLATFORM_MSMNILE) || defined (PLATFORM_MSMSTEPPE) || defined (PLATFORM_QCS405)
+#if defined (PLATFORM_MSM8998) || (PLATFORM_SDM845) || (PLATFORM_SDM710) || \
+    defined (PLATFORM_QCS605) || defined (PLATFORM_MSMNILE) || \
+    defined (PLATFORM_KONA) || defined (PLATFORM_MSMSTEPPE) || \
+    defined (PLATFORM_QCS405)
 #include <sound/devdep_params.h>
 #endif
 
+#include <resolv.h>
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
+#define TOSTRING_(x) #x
+#define TOSTRING(x) TOSTRING_(x)
+
 #define LIB_ACDB_LOADER "libacdbloader.so"
 #define CVD_VERSION_MIXER_CTL "CVD Version"
 
@@ -115,8 +125,8 @@
 #define EDID_FORMAT_LPCM    1
 
 /* fallback app type if the default app type from acdb loader fails */
-#define DEFAULT_APP_TYPE_RX_PATH  0x11130
-#define DEFAULT_APP_TYPE_TX_PATH  0x11132
+#define DEFAULT_APP_TYPE_RX_PATH  69936
+#define DEFAULT_APP_TYPE_TX_PATH  69938
 
 #define SAMPLE_RATE_8KHZ  8000
 #define SAMPLE_RATE_16KHZ 16000
@@ -207,6 +217,24 @@
     CAL_MODE_RTAC           = 0x4
 };
 
+#define PLATFORM_CONFIG_KEY_OPERATOR_INFO "operator_info"
+
+struct operator_info {
+    struct listnode list;
+    char *name;
+    char *mccmnc;
+};
+
+struct operator_specific_device {
+    struct listnode list;
+    char *operator;
+    char *mixer_path;
+    int acdb_id;
+};
+
+static struct listnode operator_info_list;
+static struct listnode *operator_specific_device_table[SND_DEVICE_MAX];
+
 acdb_loader_get_calibration_t acdb_loader_get_calibration;
 
 typedef struct codec_backend_cfg {
@@ -234,6 +262,7 @@
     struct audio_device *adev;
     bool fluence_in_spkr_mode;
     bool fluence_in_voice_call;
+    bool fluence_in_voice_comm;
     bool fluence_in_voice_rec;
     bool fluence_in_audio_rec;
     bool fluence_in_hfp_call;
@@ -289,6 +318,7 @@
     int hw_dep_fd;
     char cvd_version[MAX_CVD_VERSION_STRING_SIZE];
     char snd_card_name[MAX_SND_CARD_STRING_SIZE];
+    int max_vol_index;
     int source_mic_type;
     int max_mic_count;
     bool is_dsd_supported;
@@ -319,6 +349,8 @@
                                          MULTIMEDIA2_PCM_DEVICE},
     [USECASE_AUDIO_PLAYBACK_HIFI] = {MULTIMEDIA2_PCM_DEVICE,
                                      MULTIMEDIA2_PCM_DEVICE},
+    [USECASE_AUDIO_PLAYBACK_TTS] = {MULTIMEDIA2_PCM_DEVICE,
+                                        MULTIMEDIA2_PCM_DEVICE},
     [USECASE_AUDIO_PLAYBACK_OFFLOAD] =
                      {PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
     [USECASE_AUDIO_PLAYBACK_OFFLOAD2] =
@@ -392,6 +424,7 @@
                                           AFE_PROXY_RECORD_PCM_DEVICE},
     [USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
                                         AFE_PROXY_RECORD_PCM_DEVICE},
+    [USECASE_AUDIO_DSM_FEEDBACK] = {QUAT_MI2S_PCM_DEVICE, QUAT_MI2S_PCM_DEVICE},
     [USECASE_AUDIO_PLAYBACK_SILENCE] = {MULTIMEDIA9_PCM_DEVICE, -1},
     [USECASE_AUDIO_TRANSCODE_LOOPBACK_RX] = {TRANSCODE_LOOPBACK_RX_DEV_ID, -1},
     [USECASE_AUDIO_TRANSCODE_LOOPBACK_TX] = {-1, TRANSCODE_LOOPBACK_TX_DEV_ID},
@@ -427,15 +460,19 @@
     [SND_DEVICE_OUT_SPEAKER_EXTERNAL_2] = "speaker-ext-2",
     [SND_DEVICE_OUT_SPEAKER_VBAT] = "speaker-vbat",
     [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
+    [SND_DEVICE_OUT_SPEAKER_SAFE] = "speaker-safe",
     [SND_DEVICE_OUT_HEADPHONES] = "headphones",
     [SND_DEVICE_OUT_HEADPHONES_DSD] = "headphones-dsd",
     [SND_DEVICE_OUT_HEADPHONES_44_1] = "headphones-44.1",
     [SND_DEVICE_OUT_LINE] = "line",
     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
+    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES] = "speaker-safe-and-headphones",
     [SND_DEVICE_OUT_SPEAKER_AND_LINE] = "speaker-and-line",
+    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE] = "speaker-safe-and-line",
     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = "speaker-and-headphones-ext-1",
     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = "speaker-and-headphones-ext-2",
     [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
+    [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = "voice-hac-handset",
     [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
     [SND_DEVICE_OUT_VOICE_SPEAKER_STEREO] = "voice-speaker-stereo",
     [SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = "voice-speaker-vbat",
@@ -451,18 +488,23 @@
     [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
     [SND_DEVICE_OUT_BT_A2DP] = "bt-a2dp",
     [SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = "speaker-and-bt-a2dp",
+    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP] = "speaker-safe-and-bt-a2dp",
+    [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = "voice-handset-tmus",
     [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
     [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
     [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
     [SND_DEVICE_OUT_VOICE_TTY_FULL_USB] = "voice-tty-full-usb",
     [SND_DEVICE_OUT_VOICE_TTY_VCO_USB] = "voice-tty-vco-usb",
     [SND_DEVICE_OUT_VOICE_TX] = "voice-tx",
+    [SND_DEVICE_OUT_VOICE_MUSIC_TX] = "voice-music-tx",
     [SND_DEVICE_OUT_AFE_PROXY] = "afe-proxy",
     [SND_DEVICE_OUT_USB_HEADSET] = "usb-headset",
     [SND_DEVICE_OUT_VOICE_USB_HEADSET] = "usb-headset",
     [SND_DEVICE_OUT_USB_HEADPHONES] = "usb-headphones",
+    [SND_DEVICE_OUT_USB_HEADSET_SPEC] = "usb-headset",
     [SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = "usb-headphones",
     [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = "speaker-and-usb-headphones",
+    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_USB_HEADSET] = "speaker-safe-and-usb-headphones",
     [SND_DEVICE_OUT_TRANSMISSION_FM] = "transmission-fm",
     [SND_DEVICE_OUT_ANC_HEADSET] = "anc-headphones",
     [SND_DEVICE_OUT_ANC_FB_HEADSET] = "anc-fb-headphones",
@@ -479,6 +521,7 @@
     [SND_DEVICE_OUT_ANC_HANDSET] = "anc-handset",
     [SND_DEVICE_OUT_SPEAKER_PROTECTED] = "speaker-protected",
     [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = "voice-speaker-protected",
+    [SND_DEVICE_OUT_VOICE_SPEAKER_HFP] = "voice-speaker-hfp",
     [SND_DEVICE_OUT_VOICE_SPEAKER_STEREO_PROTECTED] = "voice-speaker-stereo-protected",
     [SND_DEVICE_OUT_VOICE_SPEAKER_2_PROTECTED] = "voice-speaker-2-protected",
     [SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT] = "speaker-protected-vbat",
@@ -487,7 +530,9 @@
     [SND_DEVICE_OUT_SPEAKER_PROTECTED_RAS] = "speaker-protected",
     [SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT_RAS] = "speaker-protected-vbat",
     [SND_DEVICE_OUT_SPEAKER_AND_BT_SCO] = "speaker-and-bt-sco",
+    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO] = "speaker-safe-and-bt-sco",
     [SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB] = "speaker-and-bt-sco-wb",
+    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB] = "speaker-safe-and-bt-sco-wb",
 
     /* Capture sound devices */
     [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
@@ -508,6 +553,7 @@
     [SND_DEVICE_IN_SPEAKER_DMIC_NS] = "speaker-dmic-endfire",
     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = "speaker-dmic-endfire",
     [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
+    [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
     [SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = "headset-mic",
     [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
     [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
@@ -521,9 +567,11 @@
     [SND_DEVICE_IN_BT_A2DP] = "bt-a2dp-cap",
     [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
     [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
+    [SND_DEVICE_IN_VOICE_DMIC_TMUS] = "voice-dmic-ef-tmus",
     [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
     [SND_DEVICE_IN_VOICE_SPEAKER_TMIC] = "voice-speaker-tmic",
     [SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = "voice-speaker-qmic",
+    [SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP] = "voice-speaker-mic-hfp",
     [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
     [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
     [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
@@ -533,6 +581,8 @@
 
     [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
     [SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic",
+    [SND_DEVICE_IN_VOICE_REC_MIC_AEC] = "voice-rec-mic",
+    [SND_DEVICE_IN_VOICE_REC_MIC_AEC_NS] = "voice-rec-mic",
     [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef",
     [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = "voice-rec-dmic-ef-fluence",
     [SND_DEVICE_IN_USB_HEADSET_MIC] = "usb-headset-mic",
@@ -540,6 +590,7 @@
     [SND_DEVICE_IN_USB_HEADSET_MIC_AEC] = "usb-headset-mic",
     [SND_DEVICE_IN_UNPROCESSED_USB_HEADSET_MIC] = "usb-headset-mic",
     [SND_DEVICE_IN_VOICE_RECOG_USB_HEADSET_MIC] = "usb-headset-mic",
+    [SND_DEVICE_IN_VOICE_REC_HEADSET_MIC] = "headset-mic",
     [SND_DEVICE_IN_USB_HEADSET_MULTI_CHANNEL_MIC] = "usb-headset-mic",
     [SND_DEVICE_IN_VOICE_RECOG_USB_HEADSET_MULTI_CHANNEL_MIC] = "usb-headset-mic",
     [SND_DEVICE_IN_USB_HEADSET_MULTI_CHANNEL_MIC_AEC] = "usb-headset-mic",
@@ -548,8 +599,8 @@
     [SND_DEVICE_IN_AANC_HANDSET_MIC] = "aanc-handset-mic",
     [SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC] = "aanc-handset-mic",
     [SND_DEVICE_IN_QUAD_MIC] = "quad-mic",
-    [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = "handset-stereo-dmic-ef",
-    [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = "speaker-stereo-dmic-ef",
+    [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = "handset-stereo-dmic-ef",
+    [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = "speaker-stereo-dmic-ef",
     [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = "vi-feedback",
     [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_1] = "vi-feedback-mono-1",
     [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_2] = "vi-feedback-mono-2",
@@ -562,6 +613,7 @@
     [SND_DEVICE_IN_SPEAKER_QMIC_AEC] = "quad-mic",
     [SND_DEVICE_IN_SPEAKER_QMIC_NS] = "quad-mic",
     [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = "quad-mic",
+    [SND_DEVICE_IN_HANDSET_QMIC_AEC] = "quad-mic",
     [SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE] = "quad-mic",
     [SND_DEVICE_IN_THREE_MIC] = "three-mic",
     [SND_DEVICE_IN_HANDSET_TMIC_FLUENCE_PRO] = "three-mic",
@@ -618,12 +670,15 @@
     [SND_DEVICE_OUT_SPEAKER_EXTERNAL_2] = 130,
     [SND_DEVICE_OUT_SPEAKER_VBAT] = 14,
     [SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
+    [SND_DEVICE_OUT_SPEAKER_SAFE] = 14,
     [SND_DEVICE_OUT_LINE] = 10,
     [SND_DEVICE_OUT_HEADPHONES] = 10,
     [SND_DEVICE_OUT_HEADPHONES_DSD] = 10,
     [SND_DEVICE_OUT_HEADPHONES_44_1] = 10,
     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
+    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES] = 10,
     [SND_DEVICE_OUT_SPEAKER_AND_LINE] = 10,
+    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE] = 10,
     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = 130,
     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = 130,
     [SND_DEVICE_OUT_VOICE_HANDSET] = 7,
@@ -632,6 +687,7 @@
     [SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = 14,
     [SND_DEVICE_OUT_VOICE_SPEAKER_2] = 14,
     [SND_DEVICE_OUT_VOICE_SPEAKER_2_VBAT] = 14,
+    [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = 53,
     [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
     [SND_DEVICE_OUT_VOICE_LINE] = 10,
     [SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_HEADPHONES] = 10,
@@ -645,21 +701,28 @@
     [SND_DEVICE_OUT_DISPLAY_PORT] = 18,
     [SND_DEVICE_OUT_SPEAKER_AND_DISPLAY_PORT] = 14,
     [SND_DEVICE_OUT_BT_SCO] = 22,
+    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO] = 14,
     [SND_DEVICE_OUT_BT_SCO_WB] = 39,
+    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB] = 14,
     [SND_DEVICE_OUT_BT_A2DP] = 20,
     [SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = 14,
+    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP] = 14,
+    [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = 88,
     [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
     [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
     [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
     [SND_DEVICE_OUT_VOICE_TTY_FULL_USB] = 17,
     [SND_DEVICE_OUT_VOICE_TTY_VCO_USB] = 17,
     [SND_DEVICE_OUT_VOICE_TX] = 45,
+    [SND_DEVICE_OUT_VOICE_MUSIC_TX] = 3,
     [SND_DEVICE_OUT_AFE_PROXY] = 0,
     [SND_DEVICE_OUT_USB_HEADSET] = 45,
     [SND_DEVICE_OUT_VOICE_USB_HEADSET] = 45,
     [SND_DEVICE_OUT_USB_HEADPHONES] = 45,
+    [SND_DEVICE_OUT_USB_HEADSET_SPEC] = 45,
     [SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = 45,
     [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = 14,
+    [SND_DEVICE_OUT_SPEAKER_SAFE_AND_USB_HEADSET] = 14,
     [SND_DEVICE_OUT_TRANSMISSION_FM] = 0,
     [SND_DEVICE_OUT_ANC_HEADSET] = 26,
     [SND_DEVICE_OUT_ANC_FB_HEADSET] = 27,
@@ -669,6 +732,7 @@
     [SND_DEVICE_OUT_SPEAKER_AND_ANC_FB_HEADSET] = 27,
     [SND_DEVICE_OUT_ANC_HANDSET] = 103,
     [SND_DEVICE_OUT_SPEAKER_PROTECTED] = 124,
+    [SND_DEVICE_OUT_VOICE_SPEAKER_HFP] = 14,
     [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = 101,
     [SND_DEVICE_OUT_VOICE_SPEAKER_2_PROTECTED] = 101,
     [SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT] = 124,
@@ -695,8 +759,10 @@
     [SND_DEVICE_IN_SPEAKER_DMIC_NS] = 116,
     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = 117,
     [SND_DEVICE_IN_HEADSET_MIC] = 8,
+    [SND_DEVICE_IN_HEADSET_MIC_AEC] = 8,
     [SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = 47,
     [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
+    [SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP] = 11,
     [SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
     [SND_DEVICE_IN_SPDIF] = 143,
     [SND_DEVICE_IN_HDMI_MIC] = 143,
@@ -708,6 +774,7 @@
     [SND_DEVICE_IN_BT_A2DP] = 21,
     [SND_DEVICE_IN_CAMCORDER_MIC] = 4,
     [SND_DEVICE_IN_VOICE_DMIC] = 41,
+    [SND_DEVICE_IN_VOICE_DMIC_TMUS] = 89,
     [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
     [SND_DEVICE_IN_VOICE_SPEAKER_TMIC] = 161,
     [SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = 19,
@@ -720,8 +787,11 @@
 
     [SND_DEVICE_IN_VOICE_REC_MIC] = 4,
     [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 107,
+    [SND_DEVICE_IN_VOICE_REC_MIC_AEC] = 112,
+    [SND_DEVICE_IN_VOICE_REC_MIC_AEC_NS] = 114,
     [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 34,
     [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = 41,
+    [SND_DEVICE_IN_VOICE_REC_HEADSET_MIC] = 8,
     [SND_DEVICE_IN_USB_HEADSET_MIC] = 44,
     [SND_DEVICE_IN_VOICE_USB_HEADSET_MIC] = 44,
     [SND_DEVICE_IN_UNPROCESSED_USB_HEADSET_MIC] = 44,
@@ -735,8 +805,8 @@
     [SND_DEVICE_IN_AANC_HANDSET_MIC] = 104,
     [SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC] = 105,
     [SND_DEVICE_IN_QUAD_MIC] = 46,
-    [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = 34,
-    [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = 35,
+    [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = 34,
+    [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = 35,
     [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = 102,
     [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_1] = 102,
     [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_2] = 102,
@@ -746,6 +816,7 @@
     [SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE] = 121,
     [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE] = 120,
     [SND_DEVICE_IN_HANDSET_QMIC] = 125,
+    [SND_DEVICE_IN_HANDSET_QMIC_AEC] = 125,
     [SND_DEVICE_IN_SPEAKER_QMIC_AEC] = 126,
     [SND_DEVICE_IN_SPEAKER_QMIC_NS] = 127,
     [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = 129,
@@ -784,16 +855,20 @@
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_EXTERNAL_2)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_VBAT)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES_DSD)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES_44_1)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_LINE)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_LINE)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_HFP)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_VBAT)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_2)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_2_VBAT)},
@@ -804,9 +879,14 @@
     {TO_NAME_INDEX(SND_DEVICE_OUT_DISPLAY_PORT)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_DISPLAY_PORT)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_BT_A2DP)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET_TMUS)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HAC_HANDSET)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
@@ -821,6 +901,8 @@
     {TO_NAME_INDEX(SND_DEVICE_OUT_USB_HEADPHONES)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_USB_HEADPHONES)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_USB_HEADSET)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_USB_HEADSET_SPEC)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_TRANSMISSION_FM)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_ANC_HEADSET)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_ANC_FB_HEADSET)},
@@ -855,9 +937,12 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS)},
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_STEREO)},
     {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC_AEC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC_FLUENCE)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_SPDIF)},
     {TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
@@ -869,6 +954,7 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_BT_A2DP)},
     {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC_TMUS)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_TMIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_QMIC)},
@@ -879,8 +965,11 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_USB_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_NS)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_AEC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_AEC_NS)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_STEREO)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_HEADSET_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_RX)},
     {TO_NAME_INDEX(SND_DEVICE_IN_USB_HEADSET_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_USB_HEADSET_MIC)},
@@ -895,8 +984,8 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_AANC_HANDSET_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_QUAD_MIC)},
-    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_STEREO_DMIC)},
-    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_STEREO_DMIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_STEREO)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_STEREO)},
     {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK)},
     {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_1)},
     {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_2)},
@@ -906,6 +995,7 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE)},
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE)},
     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC_AEC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_NS)},
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)},
@@ -938,6 +1028,8 @@
 static struct name_to_index usecase_name_index[AUDIO_USECASE_MAX] = {
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_DEEP_BUFFER)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
+    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_HIFI)},
+    {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_TTS)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_ULL)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MULTI_CH)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
@@ -959,6 +1051,7 @@
     {TO_NAME_INDEX(USECASE_AUDIO_RECORD_COMPRESS6)},
     {TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
     {TO_NAME_INDEX(USECASE_AUDIO_RECORD_MMAP)},
+    {TO_NAME_INDEX(USECASE_AUDIO_RECORD_HIFI)},
     {TO_NAME_INDEX(USECASE_VOICE_CALL)},
     {TO_NAME_INDEX(USECASE_VOICE2_CALL)},
     {TO_NAME_INDEX(USECASE_VOLTE_CALL)},
@@ -977,6 +1070,7 @@
     {TO_NAME_INDEX(USECASE_AUDIO_SPKR_CALIB_TX)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_AFE_PROXY)},
     {TO_NAME_INDEX(USECASE_AUDIO_RECORD_AFE_PROXY)},
+    {TO_NAME_INDEX(USECASE_AUDIO_DSM_FEEDBACK)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_SILENCE)},
     {TO_NAME_INDEX(USECASE_INCALL_MUSIC_UPLINK)},
     {TO_NAME_INDEX(USECASE_AUDIO_A2DP_ABR_FEEDBACK)},
@@ -987,6 +1081,24 @@
 
 };
 
+static const struct name_to_index usecase_type_index[USECASE_TYPE_MAX] = {
+    {TO_NAME_INDEX(PCM_PLAYBACK)},
+    {TO_NAME_INDEX(PCM_CAPTURE)},
+    {TO_NAME_INDEX(VOICE_CALL)},
+    {TO_NAME_INDEX(PCM_HFP_CALL)},
+};
+
+struct app_type_entry {
+    int uc_type;
+    int bit_width;
+    int app_type;
+    int max_rate;
+    char *mode;
+    struct listnode node; // membership in app_type_entry_list;
+};
+
+static struct listnode app_type_entry_list;
+
 #define NO_COLS 2
 #ifdef PLATFORM_APQ8084
 static int msm_device_to_be_id [][NO_COLS] = {
@@ -1106,11 +1218,115 @@
 #define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
 #define PCM_OFFLOAD_PLATFORM_DELAY (30*1000LL)
 #define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
-#define ULL_PLATFORM_DELAY         (6*1000LL)
+#define ULL_PLATFORM_DELAY         (3*1000LL)
 #define MMAP_PLATFORM_DELAY        (3*1000LL)
 
-static void update_codec_type_and_interface(struct platform_data * my_data, const char *snd_card_name) {
+static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT;
+static bool is_tmus = false;
 
+static void check_operator()
+{
+    char value[PROPERTY_VALUE_MAX];
+    int mccmnc;
+    property_get("gsm.sim.operator.numeric",value,"0");
+    mccmnc = atoi(value);
+    ALOGD("%s: tmus mccmnc %d", __func__, mccmnc);
+    switch(mccmnc) {
+    /* TMUS MCC(310), MNC(490, 260, 026) */
+    case 310490:
+    case 310260:
+    case 310026:
+    /* Add new TMUS MNC(800, 660, 580, 310, 270, 250, 240, 230, 220, 210, 200, 160) */
+    case 310800:
+    case 310660:
+    case 310580:
+    case 310310:
+    case 310270:
+    case 310250:
+    case 310240:
+    case 310230:
+    case 310220:
+    case 310210:
+    case 310200:
+    case 310160:
+        is_tmus = true;
+        break;
+    }
+}
+
+bool is_operator_tmus()
+{
+    pthread_once(&check_op_once_ctl, check_operator);
+    return is_tmus;
+}
+
+static char *get_current_operator()
+{
+    struct listnode *node;
+    struct operator_info *info_item;
+    char mccmnc[PROPERTY_VALUE_MAX];
+    char *ret = NULL;
+
+    property_get("gsm.sim.operator.numeric",mccmnc,"00000");
+
+    list_for_each(node, &operator_info_list) {
+        info_item = node_to_item(node, struct operator_info, list);
+        if (strstr(info_item->mccmnc, mccmnc) != NULL) {
+            ret = info_item->name;
+        }
+    }
+
+    return ret;
+}
+
+static struct operator_specific_device *get_operator_specific_device(snd_device_t snd_device)
+{
+    struct listnode *node;
+    struct operator_specific_device *ret = NULL;
+    struct operator_specific_device *device_item;
+    char *operator_name;
+
+    operator_name = get_current_operator();
+    if (operator_name == NULL)
+        return ret;
+
+    list_for_each(node, operator_specific_device_table[snd_device]) {
+        device_item = node_to_item(node, struct operator_specific_device, list);
+        if (strcmp(operator_name, device_item->operator) == 0) {
+            ret = device_item;
+        }
+    }
+
+    return ret;
+}
+
+static int get_operator_specific_device_acdb_id(snd_device_t snd_device)
+{
+    struct operator_specific_device *device;
+    int ret = acdb_device_table[snd_device];
+
+    device = get_operator_specific_device(snd_device);
+    if (device != NULL)
+        ret = device->acdb_id;
+
+    return ret;
+}
+
+static const char *get_operator_specific_device_mixer_path(snd_device_t snd_device)
+{
+    struct operator_specific_device *device;
+    const char *ret = device_table[snd_device];
+
+    device = get_operator_specific_device(snd_device);
+    if (device != NULL)
+        ret = device->mixer_path;
+
+    return ret;
+}
+
+static void update_codec_type_and_interface(struct platform_data * my_data,
+     const char *snd_card_name)
+{
      if (!strncmp(snd_card_name, "sdm670-skuw-snd-card",
                   sizeof("sdm670-skuw-snd-card")) ||
          !strncmp(snd_card_name, "sdm660-snd-card-skush",
@@ -1126,8 +1342,12 @@
          !strncmp(snd_card_name, "sm6150-idp-snd-card",
                    sizeof("sm6150-idp-snd-card")) ||
          !strncmp(snd_card_name, "qcs605-lc-snd-card",
-                   sizeof("qcs605-lc-snd-card"))) {
-         ALOGI("%s: snd_card_name: %s",__func__,snd_card_name);
+                   sizeof("qcs605-lc-snd-card")) ||
+         !strncmp(snd_card_name, "kona-mtp-snd-card",
+                   sizeof("kona-mtp-snd-card")) ||
+         !strncmp(snd_card_name, "kona-qrd-snd-card",
+                   sizeof("kona-qrd-snd-card"))) {
+         ALOGI("%s: snd_card_name: %s", __func__, snd_card_name);
          my_data->is_internal_codec = true;
          my_data->is_slimbus_interface = false;
      }
@@ -1202,7 +1422,7 @@
 
                 ALOGV("%s: out device is %d", __func__,  usecase->out_snd_device);
                 app_type = usecase->stream.out->app_type_cfg.app_type;
-                acdb_dev_id = acdb_device_table[usecase->out_snd_device];
+                acdb_dev_id = platform_get_snd_device_acdb_id(usecase->out_snd_device);
 
                 if (platform_split_snd_device(my_data, usecase->out_snd_device,
                                               &num_devices, new_snd_device) < 0)
@@ -1265,10 +1485,10 @@
     }
 
     if (enable) {
-#ifndef COMPRESS_VOIP_ENABLED
-        if (adev->mode == AUDIO_MODE_IN_COMMUNICATION)
-            strlcat(ec_ref_mixer_path, "-voip", MIXER_PATH_MAX_LENGTH);
-#endif
+        if (!voice_extn_is_compress_voip_supported()) {
+            if (adev->mode == AUDIO_MODE_IN_COMMUNICATION)
+                strlcat(ec_ref_mixer_path, "-voip", MIXER_PATH_MAX_LENGTH);    
+        }        
         /*
          * If native audio device reference count > 0, then apply codec EC otherwise
          * fallback to Speakers with VBat if enabled or default
@@ -1477,6 +1697,7 @@
     for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
         backend_tag_table[dev] = NULL;
         hw_interface_table[dev] = NULL;
+        operator_specific_device_table[dev] = NULL;
     }
     for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
         backend_bit_width_table[dev] = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
@@ -1507,6 +1728,12 @@
     backend_tag_table[SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = strdup("usb-headphones");
     backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] =
         strdup("speaker-and-usb-headphones");
+    backend_tag_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_USB_HEADSET] =
+        strdup("speaker-safe-and-usb-headphones");
+    backend_tag_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO] =
+        strdup("speaker-safe-and-bt-sco");
+    backend_tag_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB] =
+        strdup("speaker-safe-and-bt-sco-wb");
     backend_tag_table[SND_DEVICE_IN_VOICE_TTY_FULL_USB_MIC] = strdup("usb-headset-mic");
     backend_tag_table[SND_DEVICE_IN_VOICE_TTY_HCO_USB_MIC] = strdup("usb-headset-mic");
     backend_tag_table[SND_DEVICE_IN_USB_HEADSET_MIC] = strdup("usb-headset-mic");
@@ -1527,6 +1754,8 @@
     backend_tag_table[SND_DEVICE_OUT_BT_A2DP] = strdup("bt-a2dp");
     backend_tag_table[SND_DEVICE_IN_BT_A2DP] = strdup("bt-a2dp-cap");
     backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = strdup("speaker-and-bt-a2dp");
+    backend_tag_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP] = strdup("speaker-safe-and-bt-a2dp");
+    backend_tag_table[SND_DEVICE_OUT_USB_HEADSET_SPEC] = strdup("usb-headset");
     backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_HEADPHONES] = strdup("speaker-and-headphones");
     backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_ANC_HEADSET] = strdup("speaker-and-headphones");
     backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_ANC_FB_HEADSET] = strdup("speaker-and-headphones");
@@ -1539,12 +1768,14 @@
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_EXTERNAL_1] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_EXTERNAL_2] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_REVERSE] = strdup("SLIMBUS_0_RX");
+    hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_VBAT] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_LINE] = strdup("SLIMBUS_6_RX");
     hw_interface_table[SND_DEVICE_OUT_HEADPHONES] = strdup("SLIMBUS_6_RX");
     hw_interface_table[SND_DEVICE_OUT_HEADPHONES_DSD] = strdup("SLIMBUS_2_RX");
     hw_interface_table[SND_DEVICE_OUT_HEADPHONES_44_1] = strdup("SLIMBUS_5_RX");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
+    hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_HEADPHONES] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_ANC_HEADSET] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_ANC_FB_HEADSET] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
@@ -1552,14 +1783,17 @@
     hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_STEREO_AND_VOICE_ANC_HEADSET] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_STEREO_AND_VOICE_ANC_FB_HEADSET] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_LINE] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
+    hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_HANDSET] = strdup("SLIMBUS_0_RX");
+    hw_interface_table[SND_DEVICE_OUT_VOICE_HAC_HANDSET] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_2] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_2_VBAT] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_HEADPHONES] = strdup("SLIMBUS_6_RX");
+    hw_interface_table[SND_DEVICE_OUT_VOICE_MUSIC_TX] = strdup("VOICE_PLAYBACK_TX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_LINE] = strdup("SLIMBUS_6_RX");
     hw_interface_table[SND_DEVICE_OUT_HDMI] = strdup("HDMI");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("SLIMBUS_0_RX-and-HDMI");
@@ -1569,6 +1803,9 @@
     hw_interface_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("SLIMBUS_7_RX");
     hw_interface_table[SND_DEVICE_OUT_BT_A2DP] = strdup("SLIMBUS_7_RX");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = strdup("SLIMBUS_0_RX-and-SLIMBUS_7_RX");
+    hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP] =
+        strdup("SLIMBUS_0_RX-and-SLIMBUS_7_RX");
+    hw_interface_table[SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = strdup("SLIMBUS_6_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = strdup("SLIMBUS_6_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = strdup("SLIMBUS_0_RX");
@@ -1579,6 +1816,9 @@
     hw_interface_table[SND_DEVICE_OUT_USB_HEADSET] = strdup("USB_AUDIO_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_USB_HEADSET] = strdup("USB_AUDIO_RX");
     hw_interface_table[SND_DEVICE_OUT_USB_HEADPHONES] = strdup("USB_AUDIO_RX");
+    hw_interface_table[SND_DEVICE_OUT_USB_HEADSET_SPEC] = strdup("USB_AUDIO_RX");
+    hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_USB_HEADSET] =
+        strdup("SLIMBUS_0_RX-and-USB_AUDIO_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = strdup("USB_AUDIO_RX");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = strdup("SLIMBUS_0_RX-and-USB_AUDIO_RX");
     hw_interface_table[SND_DEVICE_OUT_TRANSMISSION_FM] = strdup("SLIMBUS_8_TX");
@@ -1591,6 +1831,11 @@
     hw_interface_table[SND_DEVICE_OUT_ANC_HANDSET] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_PROTECTED] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = strdup("SLIMBUS_0_RX");
+    hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_HFP] = strdup("SLIMBUS_0_RX");
+    hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_BT_SCO] = strdup("SLIMBUS_0_RX-and-SEC_AUX_PCM_RX");
+    hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB] = strdup("SLIMBUS_0_RX-and-SEC_AUX_PCM_RX");
+    hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO] = strdup("QUAT_TDM_RX_0-and-SLIMBUS_7_RX");
+    hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB] = strdup("QUAT_TDM_RX_0-and-SLIMBUS_7_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_2_PROTECTED] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_STEREO_PROTECTED] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT] = strdup("SLIMBUS_0_RX");
@@ -1608,6 +1853,8 @@
     hw_interface_table[SND_DEVICE_IN_HANDSET_DMIC_AEC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_HANDSET_DMIC_NS] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_HANDSET_DMIC_STEREO] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_HEADSET_MIC_AEC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_SPEAKER_MIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_SPEAKER_MIC_AEC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_SPEAKER_MIC_NS] = strdup("SLIMBUS_0_TX");
@@ -1616,6 +1863,7 @@
     hw_interface_table[SND_DEVICE_IN_SPEAKER_DMIC_AEC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_SPEAKER_DMIC_NS] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_HEADSET_MIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_SPEAKER_MIC] = strdup("SLIMBUS_0_TX");
@@ -1630,26 +1878,35 @@
     hw_interface_table[SND_DEVICE_IN_BT_A2DP] = strdup("SLIMBUS_7_TX");
     hw_interface_table[SND_DEVICE_IN_CAMCORDER_MIC] = 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_VOICE_SPEAKER_DMIC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_SPEAKER_TMIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_VOICE_REC_HEADSET_MIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_TTY_FULL_USB_MIC] = strdup("USB_AUDIO_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_TTY_HCO_USB_MIC] = strdup("USB_AUDIO_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_REC_MIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_REC_MIC_NS] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_VOICE_REC_MIC_AEC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_VOICE_REC_MIC_AEC_NS] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_RX] = strdup("RT_PROXY_DAI_002_TX");
     hw_interface_table[SND_DEVICE_IN_USB_HEADSET_MIC] = strdup("USB_AUDIO_TX");
+    hw_interface_table[SND_DEVICE_IN_VOICE_USB_HEADSET_MIC] = strdup("USB_AUDIO_TX");
+    hw_interface_table[SND_DEVICE_IN_USB_HEADSET_MIC_AEC] =  strdup("USB_AUDIO_TX");
+    hw_interface_table[SND_DEVICE_IN_UNPROCESSED_USB_HEADSET_MIC] = strdup("USB_AUDIO_TX");
+    hw_interface_table[SND_DEVICE_IN_VOICE_RECOG_USB_HEADSET_MIC] = strdup("USB_AUDIO_TX");
     hw_interface_table[SND_DEVICE_IN_USB_HEADSET_MULTI_CHANNEL_MIC] = strdup("USB_AUDIO_TX");
     hw_interface_table[SND_DEVICE_IN_CAPTURE_FM] = strdup("SLIMBUS_8_TX");
     hw_interface_table[SND_DEVICE_IN_AANC_HANDSET_MIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_QUAD_MIC] = strdup("SLIMBUS_0_TX");
-    hw_interface_table[SND_DEVICE_IN_HANDSET_STEREO_DMIC] = strdup("SLIMBUS_0_TX");
-    hw_interface_table[SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_HANDSET_DMIC_STEREO] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = strdup("SLIMBUS_4_TX");
     hw_interface_table[SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_1] = strdup("SLIMBUS_4_TX");
     hw_interface_table[SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_2] = strdup("SLIMBUS_4_TX");
@@ -1660,6 +1917,7 @@
     hw_interface_table[SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_HANDSET_QMIC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_HANDSET_QMIC_AEC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_SPEAKER_QMIC_AEC] = 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");
@@ -1723,7 +1981,7 @@
 
     count = mixer_ctl_get_num_values(ctl);
     if (count > MAX_CVD_VERSION_STRING_SIZE)
-        count = MAX_CVD_VERSION_STRING_SIZE;
+        count = MAX_CVD_VERSION_STRING_SIZE - 1;
 
     ret = mixer_ctl_get_array(ctl, cvd_version, count);
     if (ret != 0) {
@@ -2074,20 +2332,64 @@
     return ret;
 }
 
+#ifdef FLICKER_SENSOR_INPUT
+static void configure_flicker_sensor_input(struct mixer *mixer)
+{
+    struct mixer_ctl *ctl;
+    const char* ctl1 = "AIF3_CAP Mixer SLIM TX2";
+    int setting1 = 1;
+    const char* ctl2 = "CDC_IF TX2 MUX";
+    const char* setting2 = "DEC2";
+    const char* ctl3 = "SLIM_1_TX Channels";
+    const char* setting3 = "One";
+    const char* ctl4 = "ADC MUX2";
+    const char* setting4 = "AMIC";
+    const char* ctl5 = "AMIC MUX2";
+    const char* setting5 = "ADC1";
+    const char* ctl6 = "DEC2 Volume";
+    int setting6 = 84;
+    const char* ctl7 = "MultiMedia9 Mixer SLIM_1_TX";
+    int setting7 = 1;
+    const char* ctl8 = "SLIM_1_TX SampleRate";
+    const char* setting8 = "KHZ_8";
+
+    ctl = mixer_get_ctl_by_name(mixer, ctl1);
+    mixer_ctl_set_value(ctl, 0, setting1);
+    ctl = mixer_get_ctl_by_name(mixer, ctl2);
+    mixer_ctl_set_enum_by_string(ctl, setting2);
+    ctl = mixer_get_ctl_by_name(mixer, ctl3);
+    mixer_ctl_set_enum_by_string(ctl, setting3);
+    ctl = mixer_get_ctl_by_name(mixer, ctl4);
+    mixer_ctl_set_enum_by_string(ctl, setting4);
+    ctl = mixer_get_ctl_by_name(mixer, ctl5);
+    mixer_ctl_set_enum_by_string(ctl, setting5);
+    ctl = mixer_get_ctl_by_name(mixer, ctl6);
+    mixer_ctl_set_value(ctl, 0, setting6);
+    ctl = mixer_get_ctl_by_name(mixer, ctl7);
+    mixer_ctl_set_value(ctl, 0, setting7);
+    ctl = mixer_get_ctl_by_name(mixer, ctl8);
+    mixer_ctl_set_enum_by_string(ctl, setting8);
+}
+#endif
+
 void *platform_init(struct audio_device *adev)
 {
     char platform[PROPERTY_VALUE_MAX];
     char baseband[PROPERTY_VALUE_MAX];
     char value[PROPERTY_VALUE_MAX];
     struct platform_data *my_data = NULL;
-    char *snd_card_name = NULL, *snd_card_name_t = NULL;
-    char *snd_internal_name = NULL;
-    char *tmp = NULL;
+    char *snd_card_name = NULL;
     char mixer_xml_file[MIXER_PATH_MAX_LENGTH]= {0};
+    char platform_info_file[MIXER_PATH_MAX_LENGTH]= {0};
     int idx;
     struct mixer_ctl *ctl = NULL;
     const char *id_string = NULL;
     int cfg_value = -1;
+    bool dual_mic_config = false;
+    struct snd_card_split *snd_split_handle = NULL;
+
+    list_init(&operator_info_list);
+    list_init(&app_type_entry_list);
 
     adev->snd_card = audio_extn_utils_open_snd_mixer(&adev->mixer);
     if (adev->snd_card < 0) {
@@ -2103,6 +2405,9 @@
         return NULL;
     }
 
+    audio_extn_set_snd_card_split(snd_card_name);
+    snd_split_handle = audio_extn_get_snd_card_split();
+
     my_data = calloc(1, sizeof(struct platform_data));
     if (!my_data) {
         ALOGE("failed to allocate platform data");
@@ -2145,40 +2450,26 @@
          * done to preserve backward compatibility but not mandatory as
          * long as the mixer files are named as per above assumption.
         */
-        snd_card_name_t = strdup(snd_card_name);
-        snd_internal_name = strtok_r(snd_card_name_t, "-", &tmp);
+        snprintf(mixer_xml_file, sizeof(mixer_xml_file), "%s_%s_%s.xml",
+                         MIXER_XML_BASE_STRING, snd_split_handle->snd_card,
+                         snd_split_handle->form_factor);
+        if (!audio_extn_utils_resolve_config_file(mixer_xml_file)) {
+            memset(mixer_xml_file, 0, sizeof(mixer_xml_file));
+            snprintf(mixer_xml_file, sizeof(mixer_xml_file), "%s_%s.xml",
+                         MIXER_XML_BASE_STRING, snd_split_handle->snd_card);
 
-        if (snd_internal_name != NULL) {
-            snd_internal_name = strtok_r(NULL, "-", &tmp);
-        }
-        if (snd_internal_name != NULL) {
-            strlcpy(mixer_xml_file, MIXER_XML_BASE_STRING,
-                MIXER_PATH_MAX_LENGTH);
-            strlcat(mixer_xml_file, MIXER_FILE_DELIMITER,
-                MIXER_PATH_MAX_LENGTH);
-            strlcat(mixer_xml_file, snd_internal_name,
-                MIXER_PATH_MAX_LENGTH);
-            strlcat(mixer_xml_file, MIXER_FILE_EXT,
-                MIXER_PATH_MAX_LENGTH);
-        } else {
-            strlcpy(mixer_xml_file, MIXER_XML_DEFAULT_PATH,
-                MIXER_PATH_MAX_LENGTH);
+            if (!audio_extn_utils_resolve_config_file(mixer_xml_file)) {
+                memset(mixer_xml_file, 0, sizeof(mixer_xml_file));
+                strlcpy(mixer_xml_file, MIXER_XML_DEFAULT_PATH, MIXER_PATH_MAX_LENGTH);
+                audio_extn_utils_resolve_config_file(mixer_xml_file);
+            }
         }
 
-        if (F_OK == access(mixer_xml_file, 0)) {
-            ALOGD("%s: Loading mixer file: %s", __func__, mixer_xml_file);
-            if (audio_extn_read_xml(adev, adev->snd_card, mixer_xml_file,
-                            MIXER_XML_PATH_AUXPCM) == -ENOSYS)
-                adev->audio_route = audio_route_init(adev->snd_card,
-                                               mixer_xml_file);
-                update_codec_type_and_interface(my_data, snd_card_name);
-        } else {
-            ALOGD("%s: Loading default mixer file", __func__);
-            if (audio_extn_read_xml(adev, adev->snd_card, MIXER_XML_DEFAULT_PATH,
-                            MIXER_XML_PATH_AUXPCM) == -ENOSYS)
-                adev->audio_route = audio_route_init(adev->snd_card,
-                                               MIXER_XML_DEFAULT_PATH);
-                update_codec_type_and_interface(my_data, snd_card_name);
+        ALOGD("%s: Loading mixer file: %s", __func__, mixer_xml_file);
+        if (audio_extn_read_xml(adev, adev->snd_card, mixer_xml_file,
+                                MIXER_XML_PATH_AUXPCM) == -ENOSYS) {
+            adev->audio_route = audio_route_init(adev->snd_card, mixer_xml_file);
+            update_codec_type_and_interface(my_data, snd_card_name);
         }
     }
     if (!adev->audio_route) {
@@ -2188,8 +2479,6 @@
             free(my_data);
         if (snd_card_name)
             free(snd_card_name);
-        if (snd_card_name_t)
-            free(snd_card_name_t);
         audio_extn_utils_close_snd_mixer(adev->mixer);
         return NULL;
     }
@@ -2221,34 +2510,58 @@
     my_data->declared_mic_count = 0;
     my_data->spkr_ch_map = NULL;
     my_data->use_sprk_default_sample_rate = true;
+    my_data->fluence_in_voice_comm = false;
+
+    //set max volume step for voice call
+    property_get("ro.config.vc_call_vol_steps", value, TOSTRING(MAX_VOL_INDEX));
+    my_data->max_vol_index = atoi(value);
+
     be_dai_name_table = NULL;
 
-    property_get("ro.vendor.audio.sdk.fluencetype", my_data->fluence_cap, "");
-    if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro"))) {
-        my_data->fluence_type = FLUENCE_QUAD_MIC | FLUENCE_DUAL_MIC;
+    property_get("persist.audio.dualmic.config",value,"");
+    if (!strcmp("endfire", value)) {
+        dual_mic_config = true;
+    }
 
-        if (property_get_bool("persist.vendor.audio.fluence.tmic.enabled",false)) {
-            my_data->fluence_type |= FLUENCE_TRI_MIC;
-        }
-    } else if (!strncmp("fluence", my_data->fluence_cap, sizeof("fluence"))) {
-        my_data->fluence_type = FLUENCE_DUAL_MIC;
+    my_data->fluence_type = FLUENCE_NONE;
+    if ((property_get("ro.vendor.audio.sdk.fluencetype",
+                      my_data->fluence_cap, NULL) > 0) ||
+        (property_get("ro.qc.sdk.audio.fluencetype",
+                      my_data->fluence_cap, NULL) > 0)) {
+        if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro"))) {
+            my_data->fluence_type = FLUENCE_QUAD_MIC | FLUENCE_DUAL_MIC;
 
-        if (property_get_bool("persist.vendor.audio.fluence.tmic.enabled",false)) {
-            my_data->fluence_type |= FLUENCE_TRI_MIC;
+            if (property_get_bool("persist.vendor.audio.fluence.tmic.enabled",false)) {
+                my_data->fluence_type |= FLUENCE_TRI_MIC;
+            }
+        } else if (!strncmp("fluence", my_data->fluence_cap, sizeof("fluence")) ||
+                   dual_mic_config) {
+            my_data->fluence_type = FLUENCE_DUAL_MIC;
+
+            if (property_get_bool("persist.vendor.audio.fluence.tmic.enabled",false)) {
+                my_data->fluence_type |= FLUENCE_TRI_MIC;
+            }
         }
-    } else {
-        my_data->fluence_type = FLUENCE_NONE;
     }
 
     if (my_data->fluence_type != FLUENCE_NONE) {
-        property_get("persist.vendor.audio.fluence.voicecall",value,"");
-        if (!strncmp("true", value, sizeof("true"))) {
-            my_data->fluence_in_voice_call = true;
+        if ((property_get("persist.vendor.audio.fluence.voicecall",
+                          value,NULL) > 0) ||
+            (property_get("persist.audio.fluence.voicecall",value,NULL) > 0)) {
+            if (!strncmp("true", value, sizeof("true")))
+                my_data->fluence_in_voice_call = true;
         }
 
-        property_get("persist.vendor.audio.fluence.voicerec",value,"");
+        if ((property_get("persist.vendor.audio.fluence.voicerec",
+                          value,NULL) > 0) ||
+            (property_get("persist.audio.fluence.voicerec",value,NULL) > 0)) {
+            if (!strncmp("true", value, sizeof("true")))
+                my_data->fluence_in_voice_rec = true;
+        }
+
+        property_get("persist.audio.fluence.voicecomm",value,"");
         if (!strncmp("true", value, sizeof("true"))) {
-            my_data->fluence_in_voice_rec = true;
+            my_data->fluence_in_voice_comm = true;
         }
 
         property_get("persist.vendor.audio.fluence.audiorec",value,"");
@@ -2256,9 +2569,12 @@
             my_data->fluence_in_audio_rec = true;
         }
 
-        property_get("persist.vendor.audio.fluence.speaker",value,"");
-        if (!strncmp("true", value, sizeof("true"))) {
-            my_data->fluence_in_spkr_mode = true;
+        if ((property_get("persist.vendor.audio.fluence.speaker",
+                          value,NULL) > 0) ||
+            (property_get("persist.audio.fluence.speaker",value,NULL) > 0)) {
+            if (!strncmp("true", value, sizeof("true"))) {
+                my_data->fluence_in_spkr_mode = true;
+            }
         }
 
         property_get("persist.vendor.audio.fluence.mode",value,"");
@@ -2308,6 +2624,9 @@
     else if (!strncmp(snd_card_name, "sm6150-qrd-snd-card",
                sizeof("sm6150-qrd-snd-card")))
         platform_info_init(PLATFORM_INFO_XML_PATH_QRD, my_data, PLATFORM);
+    else if (!strncmp(snd_card_name, "kona-qrd-snd-card",
+               sizeof("kona-qrd-snd-card")))
+        platform_info_init(PLATFORM_INFO_XML_PATH_QRD, my_data, PLATFORM);
     else if (!strncmp(snd_card_name, "qcs405-wsa-snd-card",
                sizeof("qcs405-wsa-snd-card")))
         platform_info_init(PLATFORM_INFO_XML_PATH_WSA, my_data, PLATFORM);
@@ -2316,8 +2635,11 @@
         platform_info_init(PLATFORM_INFO_XML_PATH_TDM, my_data, PLATFORM);
     else if (my_data->is_internal_codec)
         platform_info_init(PLATFORM_INFO_XML_PATH_INTCODEC, my_data, PLATFORM);
-    else
-        platform_info_init(PLATFORM_INFO_XML_PATH, my_data, PLATFORM);
+    else {
+        // Try to load pixel or default
+        audio_extn_utils_get_platform_info(snd_card_name, platform_info_file);
+        platform_info_init(platform_info_file, my_data, PLATFORM);
+    }
 
     /* CSRA devices support multiple sample rates via I2S at spkr out */
     if (!strncmp(snd_card_name, "qcs405-csra", strlen("qcs405-csra"))) {
@@ -2448,6 +2770,11 @@
     }
     /* init keep-alive for compress passthru */
     audio_extn_keep_alive_init(adev);
+
+#ifdef FLICKER_SENSOR_INPUT
+    configure_flicker_sensor_input(adev->mixer);
+#endif
+
 #ifdef DYNAMIC_LOG_ENABLED
     log_utils_init();
 #endif
@@ -2509,6 +2836,7 @@
     audio_extn_ssr_update_enabled();
     audio_extn_spkr_prot_init(adev);
 
+    audio_extn_hwdep_cal_send(adev->snd_card, my_data->acdb_handle);
 
     /* init audio device arbitration */
     audio_extn_dev_arbi_init();
@@ -2547,7 +2875,8 @@
 
     if (!my_data->is_slimbus_interface) {
         //TODO:: make generic interfaceface to check Slimbus/I2S/CDC_DMA
-        if (!strncmp(snd_card_name, "sm6150", strlen("sm6150"))) {
+        if (!strncmp(snd_card_name, "sm6150", strlen("sm6150")) ||
+            !strncmp(snd_card_name, "kona", strlen("kona"))) {
             my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].bitwidth_mixer_ctl =
                 strdup("WSA_CDC_DMA_RX_0 Format");
             my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].samplerate_mixer_ctl =
@@ -2757,7 +3086,6 @@
 
     my_data->edid_info = NULL;
     free(snd_card_name);
-    free(snd_card_name_t);
     return my_data;
 }
 
@@ -2775,6 +3103,10 @@
 void platform_deinit(void *platform)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
+    struct operator_info *info_item;
+    struct operator_specific_device *device_item;
+    struct app_type_entry *ap;
+    struct listnode *node;
 
     audio_extn_keep_alive_deinit();
 
@@ -2804,8 +3136,54 @@
             free(backend_tag_table[dev]);
             backend_tag_table[dev]= NULL;
         }
+
+        if (hw_interface_table[dev]) {
+            free(hw_interface_table[dev]);
+            hw_interface_table[dev] = NULL;
+        }
+
+        if (operator_specific_device_table[dev]) {
+            while (!list_empty(operator_specific_device_table[dev])) {
+                node = list_head(operator_specific_device_table[dev]);
+                list_remove(node);
+                device_item = node_to_item(node,
+                               struct operator_specific_device, list);
+                free(device_item->operator);
+                device_item->operator = NULL;
+                free(device_item->mixer_path);
+                device_item->mixer_path = NULL;
+                free(device_item);
+                device_item = NULL;
+            }
+            free(operator_specific_device_table[dev]);
+            operator_specific_device_table[dev] = NULL;
+        }
     }
 
+    while (!list_empty(&operator_info_list)) {
+        node = list_head(&operator_info_list);
+        list_remove(node);
+        info_item = node_to_item(node, struct operator_info, list);
+        free(info_item->name);
+        info_item->name = NULL;
+        free(info_item->mccmnc);
+        info_item->mccmnc = NULL;
+        free(info_item);
+        info_item = NULL;
+    }
+
+    while (!list_empty(&app_type_entry_list)) {
+        node = list_head(&app_type_entry_list);
+        list_remove(node);
+        ap = node_to_item(node, struct app_type_entry, node);
+        if (ap->mode) {
+            free(ap->mode);
+            ap->mode = NULL;
+        }
+        free(ap);
+        ap = NULL;
+     }
+
     /* deinit audio device arbitration */
     audio_extn_dev_arbi_deinit();
 
@@ -2885,9 +3263,12 @@
 
 const char *platform_get_snd_device_name(snd_device_t snd_device)
 {
-    if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
+    if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
+        if (operator_specific_device_table[snd_device] != NULL) {
+            return get_operator_specific_device_mixer_path(snd_device);
+        }
         return device_table[snd_device];
-    else
+    } else
         return "";
 }
 
@@ -2897,7 +3278,11 @@
     struct platform_data *my_data = (struct platform_data *)platform;
 
     if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
-        strlcpy(device_name, device_table[snd_device], DEVICE_NAME_MAX_SIZE);
+        if (operator_specific_device_table[snd_device] != NULL) {
+            strlcpy(device_name, get_operator_specific_device_mixer_path(snd_device),
+                    DEVICE_NAME_MAX_SIZE);
+        } else
+            strlcpy(device_name, device_table[snd_device], DEVICE_NAME_MAX_SIZE);
         hw_info_append_hw_type(my_data->hw_info, snd_device, device_name);
     } else {
         strlcpy(device_name, "", DEVICE_NAME_MAX_SIZE);
@@ -3090,6 +3475,32 @@
     return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
 }
 
+void platform_add_operator_specific_device(snd_device_t snd_device,
+                                           const char *operator,
+                                           const char *mixer_path,
+                                           unsigned int acdb_id)
+{
+    struct operator_specific_device *device;
+
+    if (operator_specific_device_table[snd_device] == NULL) {
+        operator_specific_device_table[snd_device] =
+            (struct listnode *)calloc(1, sizeof(struct listnode));
+        list_init(operator_specific_device_table[snd_device]);
+    }
+
+    device = (struct operator_specific_device *)calloc(1, sizeof(struct operator_specific_device));
+
+    device->operator = strdup(operator);
+    device->mixer_path = strdup(mixer_path);
+    device->acdb_id = acdb_id;
+
+    list_add_tail(operator_specific_device_table[snd_device], &device->list);
+
+    ALOGD("%s: device[%s] -> operator[%s] mixer_path[%s] acdb_id[%d]", __func__,
+            platform_get_snd_device_name(snd_device), operator, mixer_path, acdb_id);
+
+}
+
 int platform_get_effect_config_data(snd_device_t snd_device,
                                       struct audio_effect_config *effect_config,
                                       effect_type_t effect_type)
@@ -3225,7 +3636,17 @@
         ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
         return -EINVAL;
     }
-    return acdb_device_table[snd_device];
+
+    /*
+     * If speaker protection is enabled, function returns supported
+     * sound device for speaker. Else same sound device is returned.
+     */
+    snd_device = platform_get_spkr_prot_snd_device(snd_device);
+
+    if (operator_specific_device_table[snd_device] != NULL)
+        return get_operator_specific_device_acdb_id(snd_device);
+    else
+        return acdb_device_table[snd_device];
 }
 
 int platform_set_snd_device_bit_width(snd_device_t snd_device, unsigned int bit_width)
@@ -3567,9 +3988,9 @@
         else
             acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED];
     } else
-        acdb_rx_id = acdb_device_table[out_snd_device];
+        acdb_rx_id = platform_get_snd_device_acdb_id(out_snd_device);
 
-    acdb_tx_id = acdb_device_table[in_snd_device];
+    acdb_tx_id = platform_get_snd_device_acdb_id(in_snd_device);
 
     if (acdb_rx_id > 0 && acdb_tx_id > 0) {
         ret = my_data->csd->enable_device_config(acdb_rx_id, acdb_tx_id);
@@ -3608,8 +4029,8 @@
                 out_snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_2_PROTECTED_VBAT;
         }
 
-        acdb_rx_id = acdb_device_table[out_snd_device];
-        acdb_tx_id = acdb_device_table[in_snd_device];
+        acdb_rx_id = platform_get_snd_device_acdb_id(out_snd_device);
+        acdb_tx_id = platform_get_snd_device_acdb_id(in_snd_device);
 
         if (acdb_rx_id > 0 && acdb_tx_id > 0)
             my_data->acdb_send_voice_cal(acdb_rx_id, acdb_tx_id);
@@ -3642,9 +4063,9 @@
          else
             acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED];
     } else
-        acdb_rx_id = acdb_device_table[out_snd_device];
+        acdb_rx_id = platform_get_snd_device_acdb_id(out_snd_device);
 
-    acdb_tx_id = acdb_device_table[in_snd_device];
+    acdb_tx_id = platform_get_snd_device_acdb_id(in_snd_device);
 
     if (acdb_rx_id > 0 && acdb_tx_id > 0) {
         ret = my_data->csd->enable_device(acdb_rx_id, acdb_tx_id,
@@ -3722,12 +4143,50 @@
     return ret;
 }
 
+void platform_set_speaker_gain_in_combo(struct audio_device *adev,
+                                        snd_device_t snd_device,
+                                        bool enable)
+{
+    const char* name;
+    switch (snd_device) {
+        case SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES:
+            if (enable)
+                name = "spkr-gain-in-headphone-combo";
+            else
+                name = "speaker-gain-default";
+            break;
+        case SND_DEVICE_OUT_SPEAKER_AND_LINE:
+            if (enable)
+                name = "spkr-gain-in-line-combo";
+            else
+                name = "speaker-gain-default";
+            break;
+        case SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES:
+            if (enable)
+                name = "spkr-safe-gain-in-headphone-combo";
+            else
+                name = "speaker-safe-gain-default";
+            break;
+        case SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE:
+            if (enable)
+                name = "spkr-safe-gain-in-line-combo";
+            else
+                name = "speaker-safe-gain-default";
+            break;
+        default:
+            return;
+    }
+
+    audio_route_apply_and_update_path(adev->audio_route, name);
+}
+
 int platform_set_voice_volume(void *platform, int volume)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
     struct audio_device *adev = my_data->adev;
     struct mixer_ctl *ctl;
     const char *mixer_ctl_name = "Voice Rx Gain";
+    const char *mute_mixer_ctl_name = "Voice Rx Device Mute";
     int vol_index = 0, ret = 0;
     long set_values[ ] = {0,
                           ALL_SESSION_VSID,
@@ -3736,18 +4195,33 @@
     // Voice volume levels are mapped to adsp volume levels as follows.
     // 100 -> 5, 80 -> 4, 60 -> 3, 40 -> 2, 20 -> 1  0 -> 0
     // But this values don't changed in kernel. So, below change is need.
-    vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, MAX_VOL_INDEX);
+    vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, my_data->max_vol_index);
     set_values[0] = vol_index;
 
     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
     if (!ctl) {
         ALOGE("%s: Could not get ctl for mixer cmd - %s",
               __func__, mixer_ctl_name);
-        ret = -EINVAL;
-    } else {
-        ALOGV("%s: Setting voice volume index: %ld", __func__, set_values[0]);
-        mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
+        return -EINVAL;
     }
+    ALOGV("%s: Setting voice volume index: %ld", __func__, set_values[0]);
+    mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
+
+    // Send mute command in case volume index is max since indexes are inverted
+    // for mixer controls.
+    if (vol_index == my_data->max_vol_index)
+        set_values[0] = 1;
+    else
+        set_values[0] = 0;
+
+    ctl = mixer_get_ctl_by_name(adev->mixer, mute_mixer_ctl_name);
+    if (!ctl) {
+        ALOGE("%s: Could not get ctl for mixer cmd - %s",
+              __func__, mute_mixer_ctl_name);
+        return -EINVAL;
+    }
+    ALOGV("%s: Setting RX Device Mute to: %ld", __func__, set_values[0]);
+    mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
 
     if (my_data->csd != NULL) {
         ret = my_data->csd->volume(ALL_SESSION_VSID, volume,
@@ -3770,6 +4244,13 @@
                           ALL_SESSION_VSID,
                           DEFAULT_MUTE_RAMP_DURATION_MS};
 
+    if (adev->mode != AUDIO_MODE_IN_CALL &&
+        adev->mode != AUDIO_MODE_IN_COMMUNICATION)
+        return 0;
+
+    if (adev->enable_hfp)
+        mixer_ctl_name = "HFP Tx Mute";
+
     set_values[0] = state;
     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
     if (!ctl) {
@@ -3852,6 +4333,24 @@
         new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
         new_snd_devices[1] = SND_DEVICE_OUT_HEADPHONES;
         ret = 0;
+    } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_LINE &&
+               !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_LINE)) {
+        *num_devices = 2;
+        new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
+        new_snd_devices[1] = SND_DEVICE_OUT_LINE;
+        ret = 0;
+    } else if (snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES &&
+               !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER_SAFE, SND_DEVICE_OUT_HEADPHONES)) {
+        *num_devices = 2;
+        new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER_SAFE;
+        new_snd_devices[1] = SND_DEVICE_OUT_HEADPHONES;
+        ret = 0;
+    } else if (snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE &&
+               !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER_SAFE, SND_DEVICE_OUT_LINE)) {
+        *num_devices = 2;
+        new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER_SAFE;
+        new_snd_devices[1] = SND_DEVICE_OUT_LINE;
+        ret = 0;
     } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET &&
                !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_ANC_HEADSET)) {
         *num_devices = 2;
@@ -3924,17 +4423,44 @@
         new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
         new_snd_devices[1] = SND_DEVICE_OUT_BT_SCO;
         ret = 0;
+    } else if (snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO &&
+               !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER_SAFE,
+                                              SND_DEVICE_OUT_BT_SCO)) {
+        *num_devices = 2;
+        new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER_SAFE;
+        new_snd_devices[1] = SND_DEVICE_OUT_BT_SCO;
+        ret = 0;
     } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB &&
                !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_BT_SCO_WB)) {
         *num_devices = 2;
         new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
         new_snd_devices[1] = SND_DEVICE_OUT_BT_SCO_WB;
         ret = 0;
+    } else if (snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB &&
+               !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER_SAFE,
+                                              SND_DEVICE_OUT_BT_SCO_WB)) {
+        *num_devices = 2;
+        new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER_SAFE;
+        new_snd_devices[1] = SND_DEVICE_OUT_BT_SCO_WB;
+        ret = 0;
+    } else if (snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_USB_HEADSET &&
+               !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER_SAFE, SND_DEVICE_OUT_USB_HEADSET)) {
+        *num_devices = 2;
+        new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER_SAFE;
+        new_snd_devices[1] = SND_DEVICE_OUT_USB_HEADSET;
+        ret = 0;
     } else if (SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP == snd_device) {
         *num_devices = 2;
         new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
         new_snd_devices[1] = SND_DEVICE_OUT_BT_A2DP;
         ret = 0;
+    } else if (SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP == snd_device &&
+               !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER_SAFE,
+                                              SND_DEVICE_OUT_BT_A2DP)) {
+        *num_devices = 2;
+        new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER_SAFE;
+        new_snd_devices[1] = SND_DEVICE_OUT_BT_A2DP;
+        ret = 0;
     } else if (SND_DEVICE_IN_INCALL_REC_RX_TX == snd_device) {
         *num_devices = 2;
         new_snd_devices[0] = SND_DEVICE_IN_INCALL_REC_RX;
@@ -3959,27 +4485,26 @@
          return my_data->ext_disp_type;
     }
 
-#ifdef DISPLAY_PORT_ENABLED
-    struct audio_device *adev = my_data->adev;
-    struct mixer_ctl *ctl;
-    char *mixer_ctl_name = "External Display Type";
+    if (audio_extn_is_display_port_enabled()) {
+        struct audio_device *adev = my_data->adev;
+        struct mixer_ctl *ctl;
+        char *mixer_ctl_name = "External Display Type";
 
-    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
-    if (!ctl) {
-        ALOGE("%s: Could not get ctl for mixer cmd - %s",
-              __func__, mixer_ctl_name);
-        return -EINVAL;
+        ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+        if (!ctl) {
+            ALOGE("%s: Could not get ctl for mixer cmd - %s",
+                  __func__, mixer_ctl_name);
+            return -EINVAL;
+        }
+
+        disp_type = mixer_ctl_get_value(ctl, 0);
+        if (disp_type == EXT_DISPLAY_TYPE_NONE) {
+             ALOGE("%s: Invalid external display type: %d", __func__, disp_type);
+             return -EINVAL;
+        }
+    } else {
+        disp_type = EXT_DISPLAY_TYPE_HDMI;
     }
-
-    disp_type = mixer_ctl_get_value(ctl, 0);
-    if (disp_type == EXT_DISPLAY_TYPE_NONE) {
-         ALOGE("%s: Invalid external display type: %d", __func__, disp_type);
-         return -EINVAL;
-    }
-#else
-    disp_type = EXT_DISPLAY_TYPE_HDMI;
-#endif
-
     my_data->ext_disp_type = disp_type;
     ALOGD("%s: ext disp type:%s", __func__, (disp_type == EXT_DISPLAY_TYPE_DP) ? "DisplayPort" : "HDMI");
     return disp_type;
@@ -4056,6 +4581,14 @@
         } else if (devices == (AUDIO_DEVICE_OUT_LINE |
                                AUDIO_DEVICE_OUT_SPEAKER)) {
             snd_device = SND_DEVICE_OUT_SPEAKER_AND_LINE;
+        } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
+                               AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
+                   devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
+                               AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
+            snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES;
+        } else if (devices == (AUDIO_DEVICE_OUT_LINE |
+                               AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
+            snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE;
         } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
                                AUDIO_DEVICE_OUT_SPEAKER)) {
             switch(my_data->ext_disp_type) {
@@ -4080,11 +4613,24 @@
         } else if ((devices & AUDIO_DEVICE_OUT_SPEAKER) &&
                    (devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
             snd_device = SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP;
+        }  else if ((devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) &&
+                   (devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
+            snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP;
         } else if ((devices & AUDIO_DEVICE_OUT_ALL_SCO) &&
                    ((devices & ~AUDIO_DEVICE_OUT_ALL_SCO) == AUDIO_DEVICE_OUT_SPEAKER)) {
             snd_device = adev->bt_wb_speech_enabled ?
                     SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB :
                     SND_DEVICE_OUT_SPEAKER_AND_BT_SCO;
+        } else if ((devices & AUDIO_DEVICE_OUT_ALL_SCO) &&
+                         ((devices & ~AUDIO_DEVICE_OUT_ALL_SCO) == AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
+            snd_device = adev->bt_wb_speech_enabled ?
+                    SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB :
+                    SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO;
+        } else if ((devices == (AUDIO_DEVICE_OUT_USB_DEVICE |
+                               AUDIO_DEVICE_OUT_SPEAKER_SAFE)) ||
+                (devices == (AUDIO_DEVICE_OUT_USB_HEADSET |
+                                               AUDIO_DEVICE_OUT_SPEAKER_SAFE))) {
+            snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_USB_HEADSET;
         } else {
             ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
             goto exit;
@@ -4101,7 +4647,9 @@
 
     if ((mode == AUDIO_MODE_IN_CALL) ||
         voice_is_in_call(adev) ||
-        voice_extn_compress_voip_is_active(adev)) {
+        voice_extn_compress_voip_is_active(adev) ||
+        adev->enable_voicerx ||
+        audio_extn_hfp_is_active(adev)) {
         if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
             devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
             devices & AUDIO_DEVICE_OUT_LINE) {
@@ -4163,6 +4711,12 @@
                 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
             else
                 snd_device = SND_DEVICE_OUT_BT_SCO;
+        } else if (devices & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
+            if (!adev->enable_hfp) {
+                snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
+            } else {
+                snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_HFP;
+            }
         } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
                 if (my_data->is_vbat_speaker || my_data->is_bcl_speaker) {
                     if (hw_info_is_stereo_spkr(my_data->hw_info)) {
@@ -4204,7 +4758,11 @@
         } else if (devices & AUDIO_DEVICE_OUT_FM_TX) {
             snd_device = SND_DEVICE_OUT_TRANSMISSION_FM;
         } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
-            if (audio_extn_should_use_handset_anc(channel_count))
+            if(adev->voice.hac)
+                snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
+            else if (is_operator_tmus())
+                snd_device = SND_DEVICE_OUT_VOICE_HANDSET_TMUS;
+            else if (audio_extn_should_use_handset_anc(channel_count))
                 snd_device = SND_DEVICE_OUT_ANC_HANDSET;
             else
                 snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
@@ -4238,14 +4796,26 @@
                 snd_device = SND_DEVICE_OUT_HEADPHONES;
     } else if (devices & AUDIO_DEVICE_OUT_LINE) {
         snd_device = SND_DEVICE_OUT_LINE;
+    } else if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
+        snd_device = SND_DEVICE_OUT_SPEAKER_SAFE;
     } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
         if (my_data->external_spk_1)
             snd_device = SND_DEVICE_OUT_SPEAKER_EXTERNAL_1;
         else if (my_data->external_spk_2)
             snd_device = SND_DEVICE_OUT_SPEAKER_EXTERNAL_2;
-        else if (adev->speaker_lr_swap)
-            snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
-        else if (my_data->is_vbat_speaker || my_data->is_bcl_speaker)
+        else if (adev->speaker_lr_swap) {
+            /*
+             * Perform device switch only if acdb tuning is
+             * different between SPEAKER & SPEAKER_REVERSE,
+             * Or there will be a small pause while performing
+             * device switch.
+            */
+            if (acdb_device_table[SND_DEVICE_OUT_SPEAKER] !=
+                acdb_device_table[SND_DEVICE_OUT_SPEAKER_REVERSE])
+                snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
+            else
+                snd_device = SND_DEVICE_OUT_SPEAKER;
+        } else if (my_data->is_vbat_speaker || my_data->is_bcl_speaker)
             snd_device = SND_DEVICE_OUT_SPEAKER_VBAT;
         else
             snd_device = SND_DEVICE_OUT_SPEAKER;
@@ -4276,14 +4846,20 @@
     } else if (devices &
                 (AUDIO_DEVICE_OUT_USB_DEVICE |
                  AUDIO_DEVICE_OUT_USB_HEADSET)) {
-        if (audio_extn_usb_is_capture_supported())
+        if (audio_extn_qdsp_supported_usb())
+            snd_device = SND_DEVICE_OUT_USB_HEADSET_SPEC;
+        else if (audio_extn_usb_is_capture_supported())
             snd_device = SND_DEVICE_OUT_USB_HEADSET;
         else
             snd_device = SND_DEVICE_OUT_USB_HEADPHONES;
     } else if (devices & AUDIO_DEVICE_OUT_FM_TX) {
         snd_device = SND_DEVICE_OUT_TRANSMISSION_FM;
     } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
-        snd_device = SND_DEVICE_OUT_HANDSET;
+        /*HAC support for voice-ish audio (eg visual voicemail)*/
+        if(adev->voice.hac)
+            snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
+        else
+            snd_device = SND_DEVICE_OUT_HANDSET;
     } else if (devices & AUDIO_DEVICE_OUT_PROXY) {
         channel_count = audio_extn_get_afe_proxy_channel_count();
         ALOGD("%s: setting sink capability(%d) for Proxy", __func__, channel_count);
@@ -4297,8 +4873,7 @@
     return snd_device;
 }
 
-#ifdef DYNAMIC_ECNS_ENABLED
-static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
+static snd_device_t get_snd_device_for_voice_comm_ecns_enabled(struct platform_data *my_data,
                                                   audio_devices_t out_device,
                                                   audio_devices_t in_device)
 {
@@ -4341,8 +4916,8 @@
 
     return snd_device;
 }
-#else
-static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
+
+static snd_device_t get_snd_device_for_voice_comm_ecns_disabled(struct platform_data *my_data,
                                                   audio_devices_t out_device,
                                                   audio_devices_t in_device)
 {
@@ -4360,7 +4935,8 @@
                            (my_data->source_mic_type & SOURCE_THREE_MIC)) {
                         snd_device = SND_DEVICE_IN_SPEAKER_TMIC_AEC_NS;
                 } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
-                           (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+                           (my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+                           my_data->fluence_in_voice_comm) {
                     if (my_data->fluence_mode == FLUENCE_BROADSIDE)
                         snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
                     else
@@ -4375,7 +4951,8 @@
                 snd_device = SND_DEVICE_IN_HANDSET_TMIC_AEC_NS;
                 adev->acdb_settings |= TMIC_FLAG;
             } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
-                (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+                (my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+                my_data->fluence_in_voice_comm) {
                 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
                 adev->acdb_settings |= DMIC_FLAG;
             } else
@@ -4396,7 +4973,8 @@
                            (my_data->source_mic_type & SOURCE_THREE_MIC)) {
                         snd_device = SND_DEVICE_IN_SPEAKER_TMIC_AEC;
                 } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
-                           (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+                           (my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+                           my_data->fluence_in_voice_comm) {
                     if (my_data->fluence_mode == FLUENCE_BROADSIDE)
                         snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE;
                     else
@@ -4411,7 +4989,8 @@
                 snd_device = SND_DEVICE_IN_HANDSET_TMIC_AEC;
                 adev->acdb_settings |= TMIC_FLAG;
             } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
-                (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+                (my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+                my_data->fluence_in_voice_comm) {
                 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
                 adev->acdb_settings |= DMIC_FLAG;
             } else
@@ -4432,7 +5011,8 @@
                            (my_data->source_mic_type & SOURCE_THREE_MIC)) {
                         snd_device = SND_DEVICE_IN_SPEAKER_TMIC_NS;
                 } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
-                           (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+                           (my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+                           my_data->fluence_in_voice_comm) {
                     if (my_data->fluence_mode == FLUENCE_BROADSIDE)
                         snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE;
                     else
@@ -4447,7 +5027,8 @@
                 snd_device = SND_DEVICE_IN_HANDSET_TMIC_NS;
                 adev->acdb_settings |= TMIC_FLAG;
             } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
-                (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+                (my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+                my_data->fluence_in_voice_comm) {
                 snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
                 adev->acdb_settings |= DMIC_FLAG;
             } else
@@ -4461,7 +5042,16 @@
 
     return snd_device;
 }
-#endif //DYNAMIC_ECNS_ENABLED
+
+static snd_device_t get_snd_device_for_voice_comm(struct platform_data *my_data,
+                                                  audio_devices_t out_device,
+                                                  audio_devices_t in_device)
+{
+    if(voice_extn_is_dynamic_ecns_enabled())
+        return get_snd_device_for_voice_comm_ecns_enabled(my_data, out_device, in_device);
+    else
+        return get_snd_device_for_voice_comm_ecns_disabled(my_data, out_device, in_device);
+}
 
 snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
 {
@@ -4573,7 +5163,9 @@
                     (my_data->source_mic_type & SOURCE_THREE_MIC)) {
                     snd_device = SND_DEVICE_IN_HANDSET_TMIC;
                     adev->acdb_settings |= TMIC_FLAG;
-                } else { /* for FLUENCE_DUAL_MIC and SOURCE_DUAL_MIC */
+                } else if (is_operator_tmus())
+                    snd_device = SND_DEVICE_IN_VOICE_DMIC_TMUS;
+                else { /* for FLUENCE_DUAL_MIC and SOURCE_DUAL_MIC */
                     snd_device = SND_DEVICE_IN_VOICE_DMIC;
                     adev->acdb_settings |= DMIC_FLAG;
                 }
@@ -4603,7 +5195,10 @@
 
             if (voice_is_in_call(adev))
                 platform_set_echo_reference(adev, true, out_device);
-        } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
+        } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
+                   out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
+                   out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+                   out_device & AUDIO_DEVICE_OUT_LINE) {
             if (my_data->fluence_type != FLUENCE_NONE &&
                 (my_data->fluence_in_voice_call ||
                  my_data->fluence_in_hfp_call) &&
@@ -4626,18 +5221,29 @@
                 if (audio_extn_hfp_is_active(adev))
                     platform_set_echo_reference(adev, true, out_device);
             } else {
-                snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
-                if (audio_extn_hfp_is_active(adev))
+                if (adev->enable_hfp) {
+                    snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP;
                     platform_set_echo_reference(adev, true, out_device);
+                } else {
+                    snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
+                    if (audio_extn_hfp_is_active(adev))
+                        platform_set_echo_reference(adev, true, out_device);
+                }
             }
         } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX) {
             snd_device = SND_DEVICE_IN_VOICE_RX;
         } else if (out_device &
                     (AUDIO_DEVICE_OUT_USB_DEVICE |
                      AUDIO_DEVICE_OUT_USB_HEADSET)) {
-          if (audio_extn_usb_is_capture_supported()) {
-              snd_device = SND_DEVICE_IN_VOICE_USB_HEADSET_MIC;
-          }
+            if (audio_extn_usb_is_capture_supported()) {
+                snd_device = SND_DEVICE_IN_VOICE_USB_HEADSET_MIC;
+            } else if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode) {
+                if (my_data->source_mic_type & SOURCE_DUAL_MIC) {
+                    snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
+                } else {
+                    snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
+                }
+            }
         }
     } else if (my_data->use_generic_handset == true &&  //     system prop is enabled
                (my_data->source_mic_type & SOURCE_QUAD_MIC) &&  // AND 4mic is available
@@ -4687,7 +5293,7 @@
                 if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
                     (my_data->source_mic_type & SOURCE_DUAL_MIC) &&
                     (channel_count == 2))
-                    snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
+                    snd_device = SND_DEVICE_IN_HANDSET_DMIC_STEREO;
                 else
                     snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
             }
@@ -4716,13 +5322,22 @@
             if (my_data->fluence_in_voice_rec && channel_count == 1) {
                 if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
                     (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
-                     snd_device = SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE;
+                    if (adev->active_input->enable_aec)
+                        snd_device = SND_DEVICE_IN_HANDSET_QMIC_AEC;
+                    else
+                        snd_device = SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE;
                 } else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
                     (my_data->source_mic_type & SOURCE_THREE_MIC)) {
-                    snd_device = SND_DEVICE_IN_VOICE_REC_TMIC;
+                    if (adev->active_input->enable_aec)
+                        snd_device = SND_DEVICE_IN_HANDSET_TMIC_AEC;
+                    else
+                        snd_device = SND_DEVICE_IN_VOICE_REC_TMIC;
                 } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
                     (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
-                    snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
+                    if (adev->active_input->enable_aec)
+                        snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
+                    else
+                        snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
                 }
                 platform_set_echo_reference(adev, true, out_device);
             } else if (((channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK) ||
@@ -4737,11 +5352,20 @@
                 snd_device = SND_DEVICE_IN_QUAD_MIC;
             }
             if (snd_device == SND_DEVICE_NONE) {
-                if (adev->active_input->enable_ns)
+                if (adev->active_input->enable_aec) {
+                    if (adev->active_input->enable_ns) {
+                        snd_device = SND_DEVICE_IN_VOICE_REC_MIC_AEC_NS;
+                    } else {
+                        snd_device = SND_DEVICE_IN_VOICE_REC_MIC_AEC;
+                    }
+                    platform_set_echo_reference(adev, true, out_device);
+                } else if (adev->active_input->enable_ns)
                     snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
                 else
                     snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
             }
+        } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+            snd_device = SND_DEVICE_IN_VOICE_REC_HEADSET_MIC;
         } else if (audio_is_usb_in_device(in_device | AUDIO_DEVICE_BIT_IN)) {
             snd_device = fixup_usb_headset_mic_snd_device(platform,
                                       SND_DEVICE_IN_VOICE_RECOG_USB_HEADSET_MIC,
@@ -4771,7 +5395,10 @@
          }
     } else if ((source == AUDIO_SOURCE_VOICE_COMMUNICATION) ||
               (mode == AUDIO_MODE_IN_COMMUNICATION)) {
-        if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
+        if (out_device & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
+            out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+            (out_device & (AUDIO_DEVICE_OUT_USB_DEVICE | AUDIO_DEVICE_OUT_USB_HEADSET) &&
+            !audio_extn_usb_is_capture_supported()))
             in_device = AUDIO_DEVICE_IN_BACK_MIC;
         else if (out_device & AUDIO_DEVICE_OUT_EARPIECE)
             in_device = AUDIO_DEVICE_IN_BUILTIN_MIC;
@@ -4824,15 +5451,24 @@
             !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
             !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
-            if (adev->active_input && (audio_extn_ssr_get_stream() == adev->active_input))
+            if ((adev->active_input && (audio_extn_ssr_get_stream() == adev->active_input)) ||
+                ((my_data->source_mic_type & SOURCE_QUAD_MIC) &&
+                 channel_mask == AUDIO_CHANNEL_INDEX_MASK_4))
                 snd_device = SND_DEVICE_IN_QUAD_MIC;
+            else if ((my_data->source_mic_type & SOURCE_THREE_MIC) &&
+                       channel_mask == AUDIO_CHANNEL_INDEX_MASK_3)
+                snd_device = SND_DEVICE_IN_THREE_MIC;
             else if ((my_data->fluence_type & (FLUENCE_DUAL_MIC | FLUENCE_TRI_MIC | FLUENCE_QUAD_MIC)) &&
                     (channel_count == 2) && (my_data->source_mic_type & SOURCE_DUAL_MIC))
-                snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
+                snd_device = SND_DEVICE_IN_HANDSET_DMIC_STEREO;
             else
                 snd_device = SND_DEVICE_IN_HANDSET_MIC;
         } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
-            snd_device = SND_DEVICE_IN_SPEAKER_MIC;
+            if ((my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+                    channel_count == 2)
+                snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
+            else
+                snd_device = SND_DEVICE_IN_SPEAKER_MIC;
         } else if (in_device & AUDIO_DEVICE_IN_LINE) {
             snd_device = SND_DEVICE_IN_LINE;
         } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
@@ -4876,10 +5512,11 @@
             snd_device = SND_DEVICE_IN_HANDSET_MIC;
         } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
             snd_device = SND_DEVICE_IN_HEADSET_MIC;
-        } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
+        } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
+                   out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
             if ((my_data->source_mic_type & SOURCE_DUAL_MIC) &&
                 (channel_count == 2)) {
-                snd_device = SND_DEVICE_IN_SPEAKER_STEREO_DMIC;
+                snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
             } else if ((my_data->source_mic_type & SOURCE_MONO_MIC) &&
                        (channel_count == 1)) {
                  snd_device = SND_DEVICE_IN_SPEAKER_MIC;
@@ -5190,7 +5827,7 @@
             ALOGE("[%s] memory allocation failed for %d",__func__, dlen);
             goto done_key_audcal;
         }
-        dlen = b64decode(value, strlen(value), dptr);
+        dlen = b64_pton(value, dptr, dlen);
         if(dlen<=0) {
             ALOGE("[%s] data decoding failed %d", __func__, dlen);
             goto done_key_audcal;
@@ -5418,7 +6055,6 @@
 int platform_set_parameters(void *platform, struct str_parms *parms)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
-    struct audio_device *adev = my_data->adev;
     char *value=NULL;
     int len;
     int ret = 0, err;
@@ -5540,6 +6176,23 @@
         update_external_device_status(my_data, event_name, status);
     }
 
+    err = str_parms_get_str(parms, PLATFORM_CONFIG_KEY_OPERATOR_INFO,
+                            value, len);
+    if (err >= 0) {
+        struct operator_info *info;
+        char *str = value;
+        char *name;
+
+        str_parms_del(parms, PLATFORM_CONFIG_KEY_OPERATOR_INFO);
+        info = (struct operator_info *)calloc(1, sizeof(struct operator_info));
+        name = strtok(str, ";");
+        info->name = strdup(name);
+        info->mccmnc = strdup(str + strlen(name) + 1);
+
+        list_add_tail(&operator_info_list, &info->list);
+        ALOGV("%s: add operator[%s] mccmnc[%s]", __func__, info->name, info->mccmnc);
+    }
+
     err = str_parms_get_str(parms, PLATFORM_MAX_MIC_COUNT,
                             value, sizeof(value));
     if (err >= 0) {
@@ -5555,7 +6208,7 @@
     native_audio_set_params(platform, parms, value, len);
     audio_extn_spkr_prot_set_parameters(parms, value, len);
     audio_extn_usb_set_sidetone_gain(parms, value, len);
-    audio_extn_hfp_set_parameters(adev, parms);
+    audio_extn_hfp_set_parameters(my_data->adev, parms);
     perf_lock_set_params(platform, parms, value, len);
     true_32_bit_set_params(parms, value, len);
     platform_spkr_device_set_params(platform, parms, value, len);
@@ -5606,6 +6259,37 @@
     return ret;
 }
 
+#ifdef INCALL_STEREO_CAPTURE_ENABLED
+int platform_set_incall_recording_session_channels(void *platform,
+                                             uint32_t channel_count)
+{
+    int ret = 0;
+    struct platform_data *my_data = (struct platform_data *)platform;
+    struct audio_device *adev = my_data->adev;
+    const char *mixer_ctl_name = "Voc Rec Config";
+    int num_ctl_values;
+    int i;
+    struct mixer_ctl *ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+
+    if (!ctl) {
+        ALOGE("%s: Could not get ctl for mixer cmd - %s",
+              __func__, mixer_ctl_name);
+        ret = -EINVAL;
+    } else {
+        num_ctl_values = mixer_ctl_get_num_values(ctl);
+        for (i = 0; i < num_ctl_values; i++) {
+            if (mixer_ctl_set_value(ctl, i, channel_count)) {
+                ALOGE("Error: invalid channel count: %x", channel_count);
+                ret = -EINVAL;
+                break;
+            }
+        }
+    }
+
+    return ret;
+}
+#endif /* INCALL_STEREO_CAPTURE_ENABLED end */
+
 int platform_stop_incall_recording_usecase(void *platform)
 {
     int ret = 0;
@@ -6433,17 +7117,17 @@
         max_supported_channels = platform_edid_get_max_channels(my_data);
 
         //Check EDID info for supported samplerate
-        if (!edid_is_supported_sr(edid_info,sample_rate)) {
+        if (!audio_extn_edid_is_supported_sr(edid_info,sample_rate)) {
             //check to see if current BE sample rate is supported by EDID
             //else assign the highest sample rate supported by EDID
-            if (edid_is_supported_sr(edid_info,my_data->current_backend_cfg[backend_idx].sample_rate))
+            if (audio_extn_edid_is_supported_sr(edid_info,my_data->current_backend_cfg[backend_idx].sample_rate))
                 sample_rate = my_data->current_backend_cfg[backend_idx].sample_rate;
             else
-                sample_rate = edid_get_highest_supported_sr(edid_info);
+                sample_rate = audio_extn_edid_get_highest_supported_sr(edid_info);
         }
 
         //Check EDID info for supported bit width
-        if (!edid_is_supported_bps(edid_info,bit_width)) {
+        if (!audio_extn_edid_is_supported_bps(edid_info,bit_width)) {
             //reset to current sample rate
             bit_width = my_data->current_backend_cfg[backend_idx].bit_width;
         }
@@ -7463,7 +8147,7 @@
     edid_data[0] = count;
     memcpy(&edid_data[1], block, count);
 
-    if (!edid_get_sink_caps(info, edid_data)) {
+    if (!audio_extn_edid_get_sink_caps(info, edid_data)) {
         ALOGE("%s: Failed to get extn disp sink capabilities", __func__);
         goto fail;
     }
@@ -7677,6 +8361,41 @@
 
 }
 
+// called from info parser
+void platform_add_app_type(const char *uc_type,
+                           const char *mode,
+                           int bw,
+                           int app_type, int max_rate) {
+    struct app_type_entry *ap =
+            (struct app_type_entry *)calloc(1, sizeof(struct app_type_entry));
+
+    if (!ap) {
+        ALOGE("%s failed to allocate mem for app type", __func__);
+        return;
+    }
+
+    ap->uc_type = -1;
+    for (int i=0; i<USECASE_TYPE_MAX; i++) {
+        if (!strcmp(uc_type, usecase_type_index[i].name)) {
+            ap->uc_type = usecase_type_index[i].index;
+            break;
+        }
+    }
+
+    if (ap->uc_type == -1) {
+        free(ap);
+        return;
+    }
+
+    ALOGI("%s uc %s mode %s bw %d app_type %d max_rate %d",
+          __func__, uc_type, mode, bw, app_type, max_rate);
+    ap->bit_width = bw;
+    ap->app_type = app_type;
+    ap->max_rate = max_rate;
+    ap->mode = strdup(mode);
+    list_add_tail(&app_type_entry_list, &ap->node);
+}
+
 void platform_reset_edid_info(void *platform) {
 
     ALOGV("%s:", __func__);
@@ -7733,7 +8452,7 @@
     ret = platform_get_edid_info(platform);
     info = (edid_audio_info *)my_data->edid_info;
     if (ret == 0 && info != NULL) {
-        return edid_is_supported_sr(info, sample_rate);
+        return audio_extn_edid_is_supported_sr(info, sample_rate);
     }
 
     return false;
@@ -7748,7 +8467,7 @@
     ret = platform_get_edid_info(platform);
     info = (edid_audio_info *)my_data->edid_info;
     if (ret == 0 && info != NULL) {
-        return edid_get_highest_supported_sr(info);
+        return audio_extn_edid_get_highest_supported_sr(info);
     }
 
     return 0;
@@ -7988,7 +8707,10 @@
 
     switch(snd_device) {
         case SND_DEVICE_OUT_SPEAKER:
+        case SND_DEVICE_OUT_SPEAKER_REVERSE:
              return SND_DEVICE_OUT_SPEAKER_PROTECTED;
+        case SND_DEVICE_OUT_SPEAKER_SAFE:
+             return SND_DEVICE_OUT_SPEAKER_SAFE;
         case SND_DEVICE_OUT_VOICE_SPEAKER:
              return SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED;
         case SND_DEVICE_OUT_VOICE_SPEAKER_2:
@@ -8087,7 +8809,8 @@
 {
     int ret;
     if ((out_snd_device == SND_DEVICE_OUT_USB_HEADSET) ||
-            (out_snd_device == SND_DEVICE_OUT_USB_HEADPHONES)) {
+        (out_snd_device == SND_DEVICE_OUT_USB_HEADPHONES) ||
+        (out_snd_device == SND_DEVICE_OUT_VOICE_USB_HEADSET)) {
         if (property_get_bool("vendor.audio.usb.disable.sidetone", 0)) {
             ALOGI("Debug: Disable sidetone");
         } else {
@@ -8363,6 +9086,7 @@
 {
     const char *mixer_ctl_name = "Swap channel";
     struct mixer_ctl *ctl;
+    const char *mixer_path;
     struct platform_data *my_data = (struct platform_data *)adev->platform;
 
     // forced to set to swap, but device not rotated ... ignore set
@@ -8371,6 +9095,14 @@
 
     ALOGV("%s:", __func__);
 
+    if (swap_channels) {
+        mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_REVERSE);
+        audio_route_apply_and_update_path(adev->audio_route, mixer_path);
+    } else {
+        mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER);
+        audio_route_apply_and_update_path(adev->audio_route, mixer_path);
+    }
+
     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
     if (!ctl) {
         ALOGE("%s: Could not get ctl for mixer cmd - %s",__func__, mixer_ctl_name);
@@ -8546,7 +9278,10 @@
     return sample_rate;
 }
 
-#if defined (PLATFORM_MSM8998) || (PLATFORM_SDM845) || (PLATFORM_SDM710) || defined (PLATFORM_QCS605) || defined (PLATFORM_MSMNILE) || defined (PLATFORM_MSMSTEPPE) || defined (PLATFORM_QCS405)
+#if defined (PLATFORM_MSM8998) || (PLATFORM_SDM845) || (PLATFORM_SDM710) || \
+    defined (PLATFORM_QCS605) || defined (PLATFORM_MSMNILE) || \
+    defined (PLATFORM_KONA) || defined (PLATFORM_MSMSTEPPE) || \
+    defined (PLATFORM_QCS405)
 
 int platform_get_mmap_data_fd(void *platform, int fe_dev, int dir, int *fd,
                               uint32_t *size)
@@ -8710,3 +9445,4 @@
 {
     return -ENOSYS;
 }
+
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 60e6581..78470fd 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -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
@@ -58,6 +58,7 @@
  */
 #define AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND \
     (AUDIO_DEVICE_OUT_EARPIECE | AUDIO_DEVICE_OUT_SPEAKER | \
+     AUDIO_DEVICE_OUT_SPEAKER_SAFE | \
      AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE | \
      AUDIO_DEVICE_OUT_LINE)
 
@@ -85,13 +86,16 @@
     SND_DEVICE_OUT_SPEAKER_EXTERNAL_1,
     SND_DEVICE_OUT_SPEAKER_EXTERNAL_2,
     SND_DEVICE_OUT_SPEAKER_REVERSE,
+    SND_DEVICE_OUT_SPEAKER_SAFE,
     SND_DEVICE_OUT_SPEAKER_VBAT,
     SND_DEVICE_OUT_LINE,
     SND_DEVICE_OUT_HEADPHONES,
     SND_DEVICE_OUT_HEADPHONES_DSD,
     SND_DEVICE_OUT_HEADPHONES_44_1,
     SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
+    SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES,
     SND_DEVICE_OUT_SPEAKER_AND_LINE,
+    SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE,
     SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1,
     SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2,
     SND_DEVICE_OUT_VOICE_HANDSET,
@@ -110,20 +114,29 @@
     SND_DEVICE_OUT_BT_SCO_WB,
     SND_DEVICE_OUT_BT_A2DP,
     SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP,
+    SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP,
+    SND_DEVICE_OUT_VOICE_HANDSET_TMUS,
     SND_DEVICE_OUT_SPEAKER_AND_BT_SCO,
+    SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO,
     SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB,
+    SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB,
     SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES,
     SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES,
     SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET,
     SND_DEVICE_OUT_VOICE_TTY_FULL_USB,
     SND_DEVICE_OUT_VOICE_TTY_VCO_USB,
+    SND_DEVICE_OUT_VOICE_HAC_HANDSET,
     SND_DEVICE_OUT_VOICE_TX,
+    SND_DEVICE_OUT_VOICE_MUSIC_TX,
+    SND_DEVICE_OUT_VOICE_SPEAKER_HFP,
     SND_DEVICE_OUT_AFE_PROXY,
     SND_DEVICE_OUT_USB_HEADSET,
     SND_DEVICE_OUT_USB_HEADPHONES,
     SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET,
+    SND_DEVICE_OUT_SPEAKER_SAFE_AND_USB_HEADSET,
     SND_DEVICE_OUT_VOICE_USB_HEADPHONES,
     SND_DEVICE_OUT_VOICE_USB_HEADSET,
+    SND_DEVICE_OUT_USB_HEADSET_SPEC,
     SND_DEVICE_OUT_TRANSMISSION_FM,
     SND_DEVICE_OUT_ANC_HEADSET,
     SND_DEVICE_OUT_ANC_FB_HEADSET,
@@ -176,8 +189,10 @@
     SND_DEVICE_IN_SPEAKER_DMIC_NS,
     SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS,
     SND_DEVICE_IN_HEADSET_MIC,
+    SND_DEVICE_IN_HEADSET_MIC_AEC,
     SND_DEVICE_IN_HEADSET_MIC_FLUENCE,
     SND_DEVICE_IN_VOICE_SPEAKER_MIC,
+    SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP,
     SND_DEVICE_IN_VOICE_HEADSET_MIC,
     SND_DEVICE_IN_SPDIF,
     SND_DEVICE_IN_HDMI_MIC,
@@ -189,6 +204,7 @@
     SND_DEVICE_IN_BT_A2DP,
     SND_DEVICE_IN_CAMCORDER_MIC,
     SND_DEVICE_IN_VOICE_DMIC,
+    SND_DEVICE_IN_VOICE_DMIC_TMUS,
     SND_DEVICE_IN_VOICE_SPEAKER_DMIC,
     SND_DEVICE_IN_VOICE_SPEAKER_TMIC,
     SND_DEVICE_IN_VOICE_SPEAKER_QMIC,
@@ -199,8 +215,11 @@
     SND_DEVICE_IN_VOICE_TTY_HCO_USB_MIC,
     SND_DEVICE_IN_VOICE_REC_MIC,
     SND_DEVICE_IN_VOICE_REC_MIC_NS,
+    SND_DEVICE_IN_VOICE_REC_MIC_AEC,
+    SND_DEVICE_IN_VOICE_REC_MIC_AEC_NS,
     SND_DEVICE_IN_VOICE_REC_DMIC_STEREO,
     SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE,
+    SND_DEVICE_IN_VOICE_REC_HEADSET_MIC,
     SND_DEVICE_IN_VOICE_RX,
     SND_DEVICE_IN_USB_HEADSET_MIC,
     SND_DEVICE_IN_USB_HEADSET_MIC_AEC,
@@ -214,8 +233,8 @@
     SND_DEVICE_IN_CAPTURE_FM,
     SND_DEVICE_IN_AANC_HANDSET_MIC,
     SND_DEVICE_IN_QUAD_MIC,
-    SND_DEVICE_IN_HANDSET_STEREO_DMIC,
-    SND_DEVICE_IN_SPEAKER_STEREO_DMIC,
+    SND_DEVICE_IN_HANDSET_DMIC_STEREO,
+    SND_DEVICE_IN_SPEAKER_DMIC_STEREO,
     SND_DEVICE_IN_CAPTURE_VI_FEEDBACK,
     SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_1,
     SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_2,
@@ -226,6 +245,7 @@
     SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE,
     SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC,
     SND_DEVICE_IN_HANDSET_QMIC,
+    SND_DEVICE_IN_HANDSET_QMIC_AEC,
     SND_DEVICE_IN_SPEAKER_QMIC_AEC,
     SND_DEVICE_IN_SPEAKER_QMIC_NS,
     SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS,
@@ -349,6 +369,12 @@
 #define AUDIO_CAPTURE_PERIOD_DURATION_MSEC 20
 #define AUDIO_CAPTURE_PERIOD_COUNT 2
 
+#define VOIP_CAPTURE_PERIOD_DURATION_MSEC 20
+#define VOIP_CAPTURE_PERIOD_COUNT 2
+
+#define VOIP_PLAYBACK_PERIOD_DURATION_MSEC 20
+#define VOIP_PLAYBACK_PERIOD_COUNT 2
+
 #define LOW_LATENCY_CAPTURE_SAMPLE_RATE 48000
 #define LOW_LATENCY_CAPTURE_PERIOD_SIZE 240
 #define LOW_LATENCY_CAPTURE_USE_CASE 1
@@ -390,13 +416,24 @@
 #define SPKR_PROT_CALIB_TX_PCM_DEVICE 25
 #endif
 #define PLAYBACK_OFFLOAD_DEVICE 9
+#define QUAT_MI2S_PCM_DEVICE    44
 
 // Direct_PCM
-#if defined (PLATFORM_MSM8994) || defined (PLATFORM_MSM8996) || defined (PLATFORM_APQ8084) || defined (PLATFORM_MSM8998) || defined (PLATFORM_SDM845) || defined (PLATFORM_SDM710) ||defined (PLATFORM_QCS605) ||defined (PLATFORM_SDX24) || defined (PLATFORM_MSMNILE) || defined (PLATFORM_MSMSTEPPE) || defined (PLATFORM_QCS405)
+#if defined (PLATFORM_MSM8994) || defined (PLATFORM_MSM8996) || \
+    defined (PLATFORM_APQ8084) || defined (PLATFORM_MSM8998) || \
+    defined (PLATFORM_SDM845) || defined (PLATFORM_SDM710) || \
+    defined (PLATFORM_QCS605) ||defined (PLATFORM_SDX24) || \
+    defined (PLATFORM_MSMNILE) || defined (PLATFORM_KONA) || \
+    defined (PLATFORM_MSMSTEPPE) || defined (PLATFORM_QCS405)
 #define PLAYBACK_OFFLOAD_DEVICE2 17
 #endif
 
-#if defined (PLATFORM_APQ8084) || defined (PLATFORM_MSM8996) || defined (PLATFORM_MSM8998) || defined (PLATFORM_SDM845) || defined (PLATFORM_SDM710) || defined(PLATFORM_QCS605) || defined (PLATFORM_SDX24) || defined (PLATFORM_MSMNILE) || defined (PLATFORM_MSMSTEPPE) || defined (PLATFORM_QCS405)
+#if defined (PLATFORM_APQ8084) || defined (PLATFORM_MSM8996) || \
+    defined (PLATFORM_MSM8998) || defined (PLATFORM_SDM845) || \
+    defined (PLATFORM_SDM710) || defined(PLATFORM_QCS605) || \
+    defined (PLATFORM_SDX24) || defined (PLATFORM_MSMNILE) || \
+    defined (PLATFORM_KONA) || defined (PLATFORM_MSMSTEPPE) || \
+    defined (PLATFORM_QCS405)
 #define PLAYBACK_OFFLOAD_DEVICE3 18
 #define PLAYBACK_OFFLOAD_DEVICE4 34
 #define PLAYBACK_OFFLOAD_DEVICE5 35
@@ -443,7 +480,7 @@
 #define VOLTE_CALL_PCM_DEVICE 17
 #define QCHAT_CALL_PCM_DEVICE 18
 #define VOWLAN_CALL_PCM_DEVICE 30
-#elif PLATFORM_APQ8084
+#elif defined (PLATFORM_APQ8084) || defined (PLATFORM_MSM8084)
 #define VOICE_CALL_PCM_DEVICE 20
 #define VOICE2_CALL_PCM_DEVICE 25
 #define VOLTE_CALL_PCM_DEVICE 21
@@ -493,7 +530,11 @@
 #define AFE_PROXY_RECORD_PCM_DEVICE 8
 
 #ifdef PLATFORM_MSM8x26
+#ifdef EXTERNAL_BT_SUPPORTED
+#define HFP_SCO_RX 10 // AUXPCM Hostless
+#else
 #define HFP_SCO_RX 28
+#endif
 #define HFP_ASM_RX_TX 29
 #elif PLATFORM_BEAR_FAMILY
 #define HFP_SCO_RX 17
@@ -522,7 +563,7 @@
 #define FM_RX_VOLUME "Quat MI2S FM RX Volume"
 #elif PLATFORM_MSM8994
 #define FM_RX_VOLUME "PRI MI2S LOOPBACK Volume"
-#elif PLATFORM_MSM8996
+#elif defined (PLATFORM_MSM8996) || defined (PLATFORM_KONA)
 #define FM_RX_VOLUME "Tert MI2S LOOPBACK Volume"
 #elif defined (PLATFORM_MSM8998) || defined (PLATFORM_SDM845) || defined (PLATFORM_MSMFALCON) || defined (PLATFORM_SDM710) || defined (PLATFORM_QCS605) || defined (PLATFORM_MSMNILE) || defined (PLATFORM_MSMSTEPPE) || defined (PLATFORM_QCS405)
 #define FM_RX_VOLUME "SLIMBUS_8 LOOPBACK Volume"
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 21f3e72..2244634 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -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
@@ -156,6 +156,9 @@
 int platform_stop_voice_call(void *platform, uint32_t vsid);
 int platform_set_mic_break_det(void *platform, bool enable);
 int platform_set_voice_volume(void *platform, int volume);
+void platform_set_speaker_gain_in_combo(struct audio_device *adev,
+                                        snd_device_t snd_device,
+                                        bool enable);
 int platform_set_mic_mute(void *platform, bool state);
 int platform_get_sample_rate(void *platform, uint32_t *rate);
 int platform_set_device_mute(void *platform, bool state, char *dir);
@@ -163,11 +166,21 @@
 snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device);
 int platform_set_hdmi_channels(void *platform, int channel_count);
 int platform_edid_get_max_channels(void *platform);
+void platform_add_operator_specific_device(snd_device_t snd_device,
+                                           const char *operator,
+                                           const char *mixer_path,
+                                           unsigned int acdb_id);
 void platform_get_parameters(void *platform, struct str_parms *query,
                              struct str_parms *reply);
 int platform_set_parameters(void *platform, struct str_parms *parms);
 int platform_set_incall_recording_session_id(void *platform, uint32_t session_id,
                                              int rec_mode);
+#ifndef INCALL_STEREO_CAPTURE_ENABLED
+#define platform_set_incall_recording_session_channels(p, sc)  (0)
+#else
+int platform_set_incall_recording_session_channels(void *platform,
+                                                   uint32_t session_channels);
+#endif
 int platform_stop_incall_recording_usecase(void *platform);
 int platform_start_incall_music_usecase(void *platform);
 int platform_stop_incall_music_usecase(void *platform);
@@ -187,6 +200,9 @@
                                     const char * hw_interface);
 int platform_get_snd_device_backend_index(snd_device_t device);
 const char * platform_get_snd_device_backend_interface(snd_device_t device);
+void platform_add_app_type(const char *uc_type,
+                           const char *mode,
+                           int bw, int app_type, int max_sr);
 
 /* From platform_info.c */
 int platform_info_init(const char *filename, void *, caller_t);
diff --git a/hal/platform_info.c b/hal/platform_info.c
index 3341f20..f8a78d8 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-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
@@ -33,7 +33,7 @@
 #include <errno.h>
 #include <stdio.h>
 #include <expat.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <cutils/str_parms.h>
 #include <audio_hw.h>
 #include "acdb.h"
@@ -60,7 +60,9 @@
     BACKEND_NAME,
     INTERFACE_NAME,
     CONFIG_PARAMS,
+    OPERATOR_SPECIFIC,
     GAIN_LEVEL_MAPPING,
+    APP_TYPE,
     ACDB_METAINFO_KEY,
     MICROPHONE_CHARACTERISTIC,
     SND_DEVICES,
@@ -82,7 +84,9 @@
 static void process_interface_name(const XML_Char **attr);
 static void process_config_params(const XML_Char **attr);
 static void process_root(const XML_Char **attr);
+static void process_operator_specific(const XML_Char **attr);
 static void process_gain_db_to_level_map(const XML_Char **attr);
+static void process_app_type(const XML_Char **attr);
 static void process_acdb_metainfo_key(const XML_Char **attr);
 static void process_microphone_characteristic(const XML_Char **attr);
 static void process_snd_dev(const XML_Char **attr);
@@ -98,6 +102,8 @@
     [BACKEND_NAME] = process_backend_name,
     [INTERFACE_NAME] = process_interface_name,
     [CONFIG_PARAMS] = process_config_params,
+    [OPERATOR_SPECIFIC] = process_operator_specific,
+    [APP_TYPE] = process_app_type,
     [GAIN_LEVEL_MAPPING] = process_gain_db_to_level_map,
     [ACDB_METAINFO_KEY] = process_acdb_metainfo_key,
     [MICROPHONE_CHARACTERISTIC] = process_microphone_characteristic,
@@ -236,9 +242,18 @@
  * </interface_names>
  * <config_params>
  *      <param key="snd_card_name" value="msm8994-tomtom-mtp-snd-card"/>
+ *      <param key="operator_info" value="tmus;aa;bb;cc"/>
+ *      <param key="operator_info" value="sprint;xx;yy;zz"/>
  *      ...
  *      ...
  * </config_params>
+ *
+ * <operator_specific>
+ *      <device name="???" operator="???" mixer_path="???" acdb_id="???"/>
+ *      ...
+ *      ...
+ * </operator_specific>
+ *
  * </audio_platform_info>
  */
 
@@ -355,6 +370,9 @@
     tbl_entry.amp = exp(tbl_entry.db * 0.115129f);
     tbl_entry.level = atoi(attr[3]);
 
+    //custome level should be > 0. Level 0 is fixed for default
+    CHECK(tbl_entry.level > 0);
+
     ALOGV("%s: amp [%f]  db [%f] level [%d]", __func__,
            tbl_entry.amp, tbl_entry.db, tbl_entry.level);
     platform_add_gain_level_mapping(&tbl_entry);
@@ -396,6 +414,43 @@
     return;
 }
 
+static void process_operator_specific(const XML_Char **attr)
+{
+    snd_device_t snd_device = SND_DEVICE_NONE;
+
+    if (strcmp(attr[0], "name") != 0) {
+        ALOGE("%s: 'name' not found", __func__);
+        goto done;
+    }
+
+    snd_device = platform_get_snd_device_index((char *)attr[1]);
+    if (snd_device < 0) {
+        ALOGE("%s: Device %s in %s not found, no ACDB ID set!",
+              __func__, (char *)attr[3], PLATFORM_INFO_XML_PATH);
+        goto done;
+    }
+
+    if (strcmp(attr[2], "operator") != 0) {
+        ALOGE("%s: 'operator' not found", __func__);
+        goto done;
+    }
+
+    if (strcmp(attr[4], "mixer_path") != 0) {
+        ALOGE("%s: 'mixer_path' not found", __func__);
+        goto done;
+    }
+
+    if (strcmp(attr[6], "acdb_id") != 0) {
+        ALOGE("%s: 'acdb_id' not found", __func__);
+        goto done;
+    }
+
+    platform_add_operator_specific_device(snd_device, (char *)attr[3], (char *)attr[5], atoi((char *)attr[7]));
+
+done:
+    return;
+}
+
 static void process_audio_effect(const XML_Char **attr, effect_type_t effect_type)
 {
     int index;
@@ -551,6 +606,39 @@
     return;
 }
 
+static void process_app_type(const XML_Char **attr)
+{
+    if (strcmp(attr[0], "uc_type")) {
+        ALOGE("%s: uc_type not found", __func__);
+        goto done;
+    }
+
+    if (strcmp(attr[2], "mode")) {
+        ALOGE("%s: mode not found", __func__);
+        goto done;
+    }
+
+    if (strcmp(attr[4], "bit_width")) {
+        ALOGE("%s: bit_width not found", __func__);
+        goto done;
+    }
+
+    if (strcmp(attr[6], "id")) {
+        ALOGE("%s: id not found", __func__);
+        goto done;
+    }
+
+    if (strcmp(attr[8], "max_rate")) {
+        ALOGE("%s: max rate not found", __func__);
+        goto done;
+    }
+
+    platform_add_app_type(attr[1], attr[3], atoi(attr[5]), atoi(attr[7]),
+                          atoi(attr[9]));
+done:
+    return;
+}
+
 static void process_microphone_characteristic(const XML_Char **attr) {
     struct audio_microphone_characteristic_t microphone;
     uint32_t curIdx = 0;
@@ -899,10 +987,14 @@
             section = BACKEND_NAME;
         } else if (strcmp(tag_name, "config_params") == 0) {
             section = CONFIG_PARAMS;
+        } else if (strcmp(tag_name, "operator_specific") == 0) {
+            section = OPERATOR_SPECIFIC;
         } else if (strcmp(tag_name, "interface_names") == 0) {
             section = INTERFACE_NAME;
         } else if (strcmp(tag_name, "gain_db_to_level_mapping") == 0) {
             section = GAIN_LEVEL_MAPPING;
+        } else if (strcmp(tag_name, "app_types") == 0) {
+            section = APP_TYPE;
         } else if(strcmp(tag_name, "acdb_metainfo_key") == 0) {
             section = ACDB_METAINFO_KEY;
         } else if (strcmp(tag_name, "microphone_characteristics") == 0) {
@@ -912,7 +1004,7 @@
         } else if (strcmp(tag_name, "device") == 0) {
             if ((section != ACDB) && (section != AEC) && (section != NS) &&
                 (section != BACKEND_NAME) && (section != BITWIDTH) &&
-                (section != INTERFACE_NAME)) {
+                (section != INTERFACE_NAME) && (section != OPERATOR_SPECIFIC)) {
                 ALOGE("device tag only supported for acdb/backend names/bitwitdh/interface names");
                 return;
             }
@@ -956,6 +1048,22 @@
                 return;
             }
             section = NS;
+        } else if (strcmp(tag_name, "gain_level_map") == 0) {
+            if (section != GAIN_LEVEL_MAPPING) {
+                ALOGE("gain_level_map tag only supported with GAIN_LEVEL_MAPPING section");
+                return;
+            }
+
+            section_process_fn fn = section_table[GAIN_LEVEL_MAPPING];
+            fn(attr);
+        } else if (!strcmp(tag_name, "app")) {
+            if (section != APP_TYPE) {
+                ALOGE("app tag only valid in section APP_TYPE");
+                return;
+            }
+
+            section_process_fn fn = section_table[APP_TYPE];
+            fn(attr);
         } else if (strcmp(tag_name, "microphone") == 0) {
             if (section != MICROPHONE_CHARACTERISTIC) {
                 ALOGE("microphone tag only supported with MICROPHONE_CHARACTERISTIC section");
@@ -995,7 +1103,17 @@
             fn(attr);
       }
     } else {
-            ALOGE("%s: unknown caller!", __func__);
+        if(strcmp(tag_name, "config_params") == 0) {
+            section = CONFIG_PARAMS;
+        } else if (strcmp(tag_name, "param") == 0) {
+            if (section != CONFIG_PARAMS) {
+                ALOGE("param tag only supported with CONFIG_PARAMS section");
+                return;
+            }
+
+            section_process_fn fn = section_table[section];
+            fn(attr);
+        }
     }
     return;
 }
@@ -1021,10 +1139,14 @@
         if (my_data.caller == PLATFORM) {
             platform_set_parameters(my_data.platform, my_data.kvpairs);
         }
+    } else if (strcmp(tag_name, "operator_specific") == 0) {
+        section = ROOT;
     } else if (strcmp(tag_name, "interface_names") == 0) {
         section = ROOT;
     } else if (strcmp(tag_name, "gain_db_to_level_mapping") == 0) {
         section = ROOT;
+    } else if (strcmp(tag_name, "app_types") == 0) {
+        section = ROOT;
     } else if (strcmp(tag_name, "acdb_metainfo_key") == 0) {
         section = ROOT;
     } else if (strcmp(tag_name, "microphone_characteristics") == 0) {
@@ -1045,13 +1167,23 @@
     int             ret = 0;
     int             bytes_read;
     void            *buf;
+    char            platform_info_file_name[MIXER_PATH_MAX_LENGTH]= {0};
 
-    file = fopen(filename, "r");
+    if (filename == NULL)
+        strlcpy(platform_info_file_name, PLATFORM_INFO_XML_PATH,
+                MIXER_PATH_MAX_LENGTH);
+    else
+        strlcpy(platform_info_file_name, filename, MIXER_PATH_MAX_LENGTH);
+
+    ALOGV("%s: platform info file name is %s", __func__,
+          platform_info_file_name);
+
+    file = fopen(platform_info_file_name, "r");
     section = ROOT;
 
     if (!file) {
         ALOGD("%s: Failed to open %s, using defaults.",
-            __func__, filename);
+            __func__, platform_info_file_name);
         ret = -ENODEV;
         goto done;
     }
@@ -1087,7 +1219,7 @@
         if (XML_ParseBuffer(parser, bytes_read,
                             bytes_read == 0) == XML_STATUS_ERROR) {
             ALOGE("%s: XML_ParseBuffer failed, for %s",
-                __func__, filename);
+                __func__, platform_info_file_name);
             ret = -EINVAL;
             goto err_free_parser;
         }
diff --git a/hal/voice.c b/hal/voice.c
index 7b93cfd..26116c6 100644
--- a/hal/voice.c
+++ b/hal/voice.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
@@ -24,7 +24,7 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <math.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <cutils/str_parms.h>
 
 #include "audio_hw.h"
@@ -78,10 +78,14 @@
         is_sidetone_dev = true;
         strlcpy(mixer_path, "sidetone-headphones", MIXER_PATH_MAX_LENGTH);
         break;
+    case SND_DEVICE_OUT_VOICE_USB_HEADSET:
     case SND_DEVICE_OUT_USB_HEADSET:
+        // USB does not use a QC mixer.
+        mixer_path[0] = '\0';
         is_sidetone_dev = true;
         break;
     default:
+        ALOGW("%s: %d is not a sidetone device", __func__, out_device);
         is_sidetone_dev = false;
         break;
     }
@@ -405,6 +409,8 @@
         session_id = voice_get_active_session_id(adev);
         ret = platform_set_incall_recording_session_id(adev->platform,
                                                        session_id, rec_mode);
+        ret = platform_set_incall_recording_session_channels(adev->platform,
+                                                        in->config.channels);
         ALOGV("%s: Update usecase to %d",__func__, in->usecase);
     } else {
         /*
@@ -578,6 +584,9 @@
     int ret = 0;
 
     adev->voice.in_call = true;
+
+    voice_set_mic_mute(adev, adev->voice.mic_mute);
+
     ret = voice_extn_start_call(adev);
     if (ret == -ENOSYS) {
         ret = voice_start_usecase(adev, USECASE_VOICE_CALL);
@@ -655,6 +664,21 @@
         }
     }
 
+    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HAC,
+                            value, sizeof(value));
+    if (err >= 0) {
+        bool hac = false;
+        str_parms_del(parms, AUDIO_PARAMETER_KEY_HAC);
+        if (strcmp(value, AUDIO_PARAMETER_VALUE_HAC_ON) == 0)
+            hac = true;
+
+        if (hac != adev->voice.hac) {
+            adev->voice.hac = hac;
+            if (voice_is_in_call(adev))
+                voice_update_devices_for_all_voice_usecases(adev);
+        }
+    }
+
     err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_INCALLMUSIC,
                             value, sizeof(value));
     if (err >= 0) {
@@ -677,6 +701,7 @@
 
     memset(&adev->voice, 0, sizeof(adev->voice));
     adev->voice.tty_mode = TTY_MODE_OFF;
+    adev->voice.hac = false;
     adev->voice.volume = 1.0f;
     adev->voice.mic_mute = false;
     adev->voice.in_call = false;
diff --git a/hal/voice.h b/hal/voice.h
index bc9aa21..9612edd 100644
--- a/hal/voice.h
+++ b/hal/voice.h
@@ -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
@@ -23,11 +23,7 @@
 #define BASE_SESS_IDX       0
 #define VOICE_SESS_IDX     (BASE_SESS_IDX)
 
-#ifdef MULTI_VOICE_SESSION_ENABLED
 #define MAX_VOICE_SESSIONS 7
-#else
-#define MAX_VOICE_SESSIONS 1
-#endif
 
 #define BASE_CALL_STATE     1
 #define CALL_INACTIVE       (BASE_CALL_STATE)
@@ -60,6 +56,7 @@
 struct voice {
     struct voice_session session[MAX_VOICE_SESSIONS];
     int tty_mode;
+    bool hac;
     bool mic_mute;
     bool use_device_mute;
     float volume;
diff --git a/hal/voice_extn/compress_voip.c b/hal/voice_extn/compress_voip.c
index 890f508..003a3ed 100644
--- a/hal/voice_extn/compress_voip.c
+++ b/hal/voice_extn/compress_voip.c
@@ -250,6 +250,404 @@
     return 0;
 }
 
+int compress_voip_set_parameters(struct audio_device *adev,
+                                             struct str_parms *parms)
+{
+    char value[32]={0};
+    int ret = 0, err, rate;
+    bool flag;
+    char *kv_pairs = str_parms_to_str(parms);
+
+    ALOGV_IF(kv_pairs != NULL, "%s: enter: %s", __func__, kv_pairs);
+
+    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOIP_RATE,
+                            value, sizeof(value));
+    if (err >= 0) {
+        rate = atoi(value);
+        voip_set_rate(adev, rate);
+    }
+
+    memset(value, 0, sizeof(value));
+    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOIP_DTX_MODE,
+                            value, sizeof(value));
+    if (err >= 0) {
+        flag = false;
+        if (strcmp(value, AUDIO_PARAMETER_VALUE_VOIP_TRUE) == 0)
+            flag = true;
+        voip_set_dtx(adev, flag);
+    }
+
+    ALOGV("%s: exit", __func__);
+    free(kv_pairs);
+    return ret;
+}
+
+void compress_voip_get_parameters(struct str_parms *query,
+                                             struct str_parms *reply)
+{
+    int ret;
+    char value[32]={0};
+
+    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_VOIP_OUT_STREAM_COUNT,
+                            value, sizeof(value));
+    if (ret >= 0) {
+        str_parms_add_int(reply, AUDIO_PARAMETER_KEY_VOIP_OUT_STREAM_COUNT,
+                          voip_data.out_stream_count);
+    }
+
+    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_VOIP_SAMPLE_RATE,
+                            value, sizeof(value));
+    if (ret >= 0) {
+        str_parms_add_int(reply, AUDIO_PARAMETER_KEY_VOIP_SAMPLE_RATE,
+                          voip_data.sample_rate);
+    }
+}
+
+void compress_voip_out_get_parameters(struct stream_out *out,
+                                                 struct str_parms *query,
+                                                 struct str_parms *reply)
+{
+    int ret;
+    char value[32]={0};
+
+    ALOGD("%s: enter", __func__);
+
+    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_VOIP_CHECK, value, sizeof(value));
+
+    if (ret >= 0) {
+        if (out->usecase == USECASE_COMPRESS_VOIP_CALL)
+            str_parms_add_int(reply, AUDIO_PARAMETER_KEY_VOIP_CHECK, true);
+        else
+            str_parms_add_int(reply, AUDIO_PARAMETER_KEY_VOIP_CHECK, false);
+    }
+
+    ALOGV("%s: exit", __func__);
+}
+
+void compress_voip_in_get_parameters(struct stream_in *in,
+                                                struct str_parms *query,
+                                                struct str_parms *reply)
+{
+    int ret;
+    char value[32]={0};
+    char *kv_pairs = NULL;
+
+    ALOGV("%s: enter", __func__);
+
+    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_VOIP_CHECK, value, sizeof(value));
+
+    if (ret >= 0) {
+        if (in->usecase == USECASE_COMPRESS_VOIP_CALL)
+            str_parms_add_int(reply, AUDIO_PARAMETER_KEY_VOIP_CHECK, true);
+        else
+            str_parms_add_int(reply, AUDIO_PARAMETER_KEY_VOIP_CHECK, false);
+    }
+
+    kv_pairs = str_parms_to_str(reply);
+    ALOGD_IF(kv_pairs != NULL, "%s: exit: return - %s", __func__, kv_pairs);
+    free(kv_pairs);
+}
+
+int compress_voip_out_get_buffer_size(struct stream_out *out)
+{
+    if (out->config.rate == 48000)
+        return COMPRESS_VOIP_IO_BUF_SIZE_FB;
+    else if (out->config.rate== 32000)
+        return COMPRESS_VOIP_IO_BUF_SIZE_SWB;
+    else if (out->config.rate == 16000)
+        return COMPRESS_VOIP_IO_BUF_SIZE_WB;
+    else
+        return COMPRESS_VOIP_IO_BUF_SIZE_NB;
+
+}
+
+int compress_voip_in_get_buffer_size(struct stream_in *in)
+{
+    if (in->config.rate == 48000)
+        return COMPRESS_VOIP_IO_BUF_SIZE_FB;
+    else if (in->config.rate== 32000)
+        return COMPRESS_VOIP_IO_BUF_SIZE_SWB;
+    else if (in->config.rate == 16000)
+        return COMPRESS_VOIP_IO_BUF_SIZE_WB;
+    else
+        return COMPRESS_VOIP_IO_BUF_SIZE_NB;
+}
+
+int compress_voip_open_output_stream(struct stream_out *out)
+{
+    int ret;
+
+    ALOGD("%s: enter", __func__);
+
+    out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_MONO;
+    out->channel_mask = AUDIO_CHANNEL_OUT_MONO;
+    out->usecase = USECASE_COMPRESS_VOIP_CALL;
+    if (out->sample_rate == 48000)
+        out->config = pcm_config_voip_fb;
+    else if (out->sample_rate == 32000)
+        out->config = pcm_config_voip_swb;
+    else if (out->sample_rate == 16000)
+        out->config = pcm_config_voip_wb;
+    else
+        out->config = pcm_config_voip_nb;
+
+    voip_data.out_stream = out;
+    voip_data.out_stream_count++;
+    voip_data.sample_rate = out->sample_rate;
+    ret = voip_set_mode(out->dev, out->format);
+
+    ALOGV("%s: exit", __func__);
+    return ret;
+}
+
+int compress_voip_open_input_stream(struct stream_in *in)
+{
+    int ret;
+
+    ALOGD("%s: enter", __func__);
+
+    if ((voip_data.sample_rate != 0) &&
+        (voip_data.sample_rate != in->config.rate)) {
+        ret = -ENOTSUP;
+        goto done;
+    } else {
+        voip_data.sample_rate = in->config.rate;
+    }
+
+    ret = voip_set_mode(in->dev, in->format);
+    if (ret < 0)
+        goto done;
+
+    in->usecase = USECASE_COMPRESS_VOIP_CALL;
+    if (in->config.rate == 48000)
+        in->config = pcm_config_voip_fb;
+    else if (in->config.rate == 32000)
+        in->config = pcm_config_voip_swb;
+    else if (in->config.rate == 16000)
+        in->config = pcm_config_voip_wb;
+    else
+        in->config = pcm_config_voip_nb;
+
+    voip_data.in_stream_count++;
+
+done:
+    ALOGV("%s: exit, ret=%d", __func__, ret);
+    return ret;
+}
+
+int compress_voip_start_output_stream(struct stream_out *out)
+{
+    int ret = 0;
+    struct audio_device *adev = out->dev;
+    struct audio_usecase *uc_info;
+
+    ALOGD("%s: enter", __func__);
+
+    if (CARD_STATUS_OFFLINE == out->card_status ||
+        CARD_STATUS_OFFLINE == adev->card_status) {
+        ret = -ENETRESET;
+        ALOGE("%s: sound card is not active/SSR returning error %d ", __func__, ret);
+        goto error;
+    }
+
+    if (out->devices & AUDIO_DEVICE_OUT_ALL_SCO) {
+         if (!adev->bt_sco_on) {
+             ALOGE("%s: SCO profile is not ready, return error", __func__);
+             ret = -EAGAIN;
+             goto error;
+         }
+    }
+
+    if (!voip_data.out_stream_count)
+        ret = compress_voip_open_output_stream(out);
+
+    ret = voip_start_call(adev, &out->config);
+    out->pcm = voip_data.pcm_rx;
+    uc_info = get_usecase_from_list(adev, USECASE_COMPRESS_VOIP_CALL);
+    if (uc_info) {
+        uc_info->stream.out = out;
+        uc_info->devices = out->devices;
+    } else {
+        ret = -EINVAL;
+        ALOGE("%s: exit(%d): failed to get use case info", __func__, ret);
+        goto error;
+    }
+
+error:
+    ALOGV("%s: exit: status(%d)", __func__, ret);
+    return ret;
+}
+
+int compress_voip_start_input_stream(struct stream_in *in)
+{
+    int ret = 0;
+    struct audio_device *adev = in->dev;
+
+    ALOGD("%s: enter", __func__);
+
+    if (CARD_STATUS_OFFLINE == in->card_status ||
+        CARD_STATUS_OFFLINE == adev->card_status) {
+        ret = -ENETRESET;
+        ALOGE("%s: sound card is not active/SSR returning error %d ", __func__, ret);
+        goto error;
+    }
+
+    if (audio_is_bluetooth_sco_device(in->device) && !adev->bt_sco_on) {
+        ret = -EIO;
+        ALOGE("%s SCO is not ready return error %d", __func__,ret);
+        goto error;
+    }
+
+    if (!voip_data.in_stream_count)
+        ret = compress_voip_open_input_stream(in);
+
+    adev->active_input = in;
+    ret = voip_start_call(adev, &in->config);
+    in->pcm = voip_data.pcm_tx;
+
+error:
+    ALOGV("%s: exit: status(%d)", __func__, ret);
+    return ret;
+}
+
+int compress_voip_close_output_stream(struct audio_stream *stream)
+{
+    struct stream_out *out = (struct stream_out *)stream;
+    struct audio_device *adev = out->dev;
+    int ret = 0;
+
+    ALOGD("%s: enter", __func__);
+    if (voip_data.out_stream_count > 0) {
+        voip_data.out_stream_count--;
+        ret = voip_stop_call(adev);
+        voip_data.out_stream = NULL;
+        out->pcm = NULL;
+    }
+
+    ALOGV("%s: exit: status(%d)", __func__, ret);
+    return ret;
+}
+
+int compress_voip_close_input_stream(struct audio_stream *stream)
+{
+    struct stream_in *in = (struct stream_in *)stream;
+    struct audio_device *adev = in->dev;
+    int status = 0;
+
+    ALOGD("%s: enter", __func__);
+
+    if(voip_data.in_stream_count > 0) {
+       voip_data.in_stream_count--;
+       status = voip_stop_call(adev);
+       adev->active_input = get_next_active_input(adev);
+       in->pcm = NULL;
+    }
+
+    ALOGV("%s: exit: status(%d)", __func__, status);
+    return status;
+}
+
+
+int compress_voip_set_volume(struct audio_device *adev, float volume)
+{
+    int vol, err = 0;
+
+    ALOGV("%s: enter", __func__);
+
+    if (volume < 0.0) {
+        volume = 0.0;
+    } else if (volume > 1.0) {
+        volume = 1.0;
+    }
+
+    vol = lrint(volume * 100.0);
+
+    /* Voice volume levels from android are mapped to driver volume levels as follows.
+     * 0 -> 5, 20 -> 4, 40 ->3, 60 -> 2, 80 -> 1, 100 -> 0
+     * So adjust the volume to get the correct volume index in driver
+     */
+    vol = 100 - vol;
+
+    err = voip_set_volume(adev, vol);
+
+    ALOGV("%s: exit: status(%d)", __func__, err);
+
+    return err;
+}
+
+int compress_voip_set_mic_mute(struct audio_device *adev, bool state)
+{
+    int err = 0;
+
+    ALOGV("%s: enter", __func__);
+
+    err = voip_set_mic_mute(adev, state);
+
+    ALOGV("%s: exit: status(%d)", __func__, err);
+    return err;
+}
+
+bool compress_voip_pcm_prop_check()
+{
+    char prop_value[PROPERTY_VALUE_MAX] = {0};
+
+    property_get("vendor.voice.path.for.pcm.voip", prop_value, "0");
+    if (!strncmp("true", prop_value, sizeof("true")))
+    {
+        ALOGD("%s: VoIP PCM property is enabled", __func__);
+        return true;
+    }
+    else
+        return false;
+}
+
+bool compress_voip_is_active(const struct audio_device *adev)
+{
+    struct audio_usecase *voip_usecase = NULL;
+    voip_usecase = get_usecase_from_list(adev, USECASE_COMPRESS_VOIP_CALL);
+
+    if (voip_usecase != NULL)
+        return true;
+    else
+        return false;
+}
+
+bool compress_voip_is_format_supported(audio_format_t format)
+{
+    if (format == AUDIO_FORMAT_PCM_16_BIT &&
+       compress_voip_pcm_prop_check())
+       return true;
+    else
+       return false;
+}
+
+bool compress_voip_is_config_supported(struct audio_config *config)
+{
+    bool ret = false;
+
+    ret = compress_voip_is_format_supported(config->format);
+    if (ret) {
+        if ((popcount(config->channel_mask) == 1) &&
+            (config->sample_rate == 8000 || config->sample_rate == 16000 ||
+             config->sample_rate == 32000 || config->sample_rate == 48000))
+            ret = ((voip_data.sample_rate == 0) ? true:
+                    (voip_data.sample_rate == config->sample_rate));
+        else
+            ret = false;
+    }
+    return ret;
+}
+
+bool compress_voip_is_started(struct audio_device *adev)
+{
+    bool ret = false;
+    if (compress_voip_is_active(adev) &&
+        voip_data.pcm_tx && voip_data.pcm_rx)
+        ret = true;
+
+    return ret;
+}
+
 static int voip_stop_call(struct audio_device *adev)
 {
     int ret = 0;
@@ -401,7 +799,7 @@
         pcm_start(voip_data.pcm_rx);
 
         voice_set_sidetone(adev, uc_info->out_snd_device, true);
-        voice_extn_compress_voip_set_volume(adev, adev->voice.volume);
+        compress_voip_set_volume(adev, adev->voice.volume);
     } else {
         ALOGV("%s: voip usecase is already enabled", __func__);
         if (voip_data.out_stream)
@@ -418,401 +816,4 @@
 
     ALOGV("%s: exit: status(%d)", __func__, ret);
     return ret;
-}
-
-int voice_extn_compress_voip_set_parameters(struct audio_device *adev,
-                                             struct str_parms *parms)
-{
-    char value[32]={0};
-    int ret = 0, err, rate;
-    bool flag;
-    char *kv_pairs = str_parms_to_str(parms);
-
-    ALOGV_IF(kv_pairs != NULL, "%s: enter: %s", __func__, kv_pairs);
-
-    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOIP_RATE,
-                            value, sizeof(value));
-    if (err >= 0) {
-        rate = atoi(value);
-        voip_set_rate(adev, rate);
-    }
-
-    memset(value, 0, sizeof(value));
-    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOIP_DTX_MODE,
-                            value, sizeof(value));
-    if (err >= 0) {
-        flag = false;
-        if (strcmp(value, AUDIO_PARAMETER_VALUE_VOIP_TRUE) == 0)
-            flag = true;
-        voip_set_dtx(adev, flag);
-    }
-
-    ALOGV("%s: exit", __func__);
-    free(kv_pairs);
-    return ret;
-}
-
-void voice_extn_compress_voip_get_parameters(struct str_parms *query,
-                                             struct str_parms *reply)
-{
-    int ret;
-    char value[32]={0};
-
-    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_VOIP_OUT_STREAM_COUNT,
-                            value, sizeof(value));
-    if (ret >= 0) {
-        str_parms_add_int(reply, AUDIO_PARAMETER_KEY_VOIP_OUT_STREAM_COUNT,
-                          voip_data.out_stream_count);
-    }
-
-    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_VOIP_SAMPLE_RATE,
-                            value, sizeof(value));
-    if (ret >= 0) {
-        str_parms_add_int(reply, AUDIO_PARAMETER_KEY_VOIP_SAMPLE_RATE,
-                          voip_data.sample_rate);
-    }
-}
-
-void voice_extn_compress_voip_out_get_parameters(struct stream_out *out,
-                                                 struct str_parms *query,
-                                                 struct str_parms *reply)
-{
-    int ret;
-    char value[32]={0};
-
-    ALOGD("%s: enter", __func__);
-
-    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_VOIP_CHECK, value, sizeof(value));
-
-    if (ret >= 0) {
-        if (out->usecase == USECASE_COMPRESS_VOIP_CALL)
-            str_parms_add_int(reply, AUDIO_PARAMETER_KEY_VOIP_CHECK, true);
-        else
-            str_parms_add_int(reply, AUDIO_PARAMETER_KEY_VOIP_CHECK, false);
-    }
-
-    ALOGV("%s: exit", __func__);
-}
-
-void voice_extn_compress_voip_in_get_parameters(struct stream_in *in,
-                                                struct str_parms *query,
-                                                struct str_parms *reply)
-{
-    int ret;
-    char value[32]={0};
-    char *kv_pairs = NULL;
-
-    ALOGV("%s: enter", __func__);
-
-    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_VOIP_CHECK, value, sizeof(value));
-
-    if (ret >= 0) {
-        if (in->usecase == USECASE_COMPRESS_VOIP_CALL)
-            str_parms_add_int(reply, AUDIO_PARAMETER_KEY_VOIP_CHECK, true);
-        else
-            str_parms_add_int(reply, AUDIO_PARAMETER_KEY_VOIP_CHECK, false);
-    }
-
-    kv_pairs = str_parms_to_str(reply);
-    ALOGD_IF(kv_pairs != NULL, "%s: exit: return - %s", __func__, kv_pairs);
-    free(kv_pairs);
-}
-
-int voice_extn_compress_voip_out_get_buffer_size(struct stream_out *out)
-{
-    if (out->config.rate == 48000)
-        return COMPRESS_VOIP_IO_BUF_SIZE_FB;
-    else if (out->config.rate== 32000)
-        return COMPRESS_VOIP_IO_BUF_SIZE_SWB;
-    else if (out->config.rate == 16000)
-        return COMPRESS_VOIP_IO_BUF_SIZE_WB;
-    else
-        return COMPRESS_VOIP_IO_BUF_SIZE_NB;
-
-}
-
-int voice_extn_compress_voip_in_get_buffer_size(struct stream_in *in)
-{
-    if (in->config.rate == 48000)
-        return COMPRESS_VOIP_IO_BUF_SIZE_FB;
-    else if (in->config.rate== 32000)
-        return COMPRESS_VOIP_IO_BUF_SIZE_SWB;
-    else if (in->config.rate == 16000)
-        return COMPRESS_VOIP_IO_BUF_SIZE_WB;
-    else
-        return COMPRESS_VOIP_IO_BUF_SIZE_NB;
-}
-
-int voice_extn_compress_voip_start_output_stream(struct stream_out *out)
-{
-    int ret = 0;
-    struct audio_device *adev = out->dev;
-    struct audio_usecase *uc_info;
-
-    ALOGD("%s: enter", __func__);
-
-    if (CARD_STATUS_OFFLINE == out->card_status ||
-        CARD_STATUS_OFFLINE == adev->card_status) {
-        ret = -ENETRESET;
-        ALOGE("%s: sound card is not active/SSR returning error %d ", __func__, ret);
-        goto error;
-    }
-
-    if (out->devices & AUDIO_DEVICE_OUT_ALL_SCO) {
-         if (!adev->bt_sco_on) {
-             ALOGE("%s: SCO profile is not ready, return error", __func__);
-             ret = -EAGAIN;
-             goto error;
-         }
-    }
-
-    if (!voip_data.out_stream_count)
-        ret = voice_extn_compress_voip_open_output_stream(out);
-
-    ret = voip_start_call(adev, &out->config);
-    out->pcm = voip_data.pcm_rx;
-    uc_info = get_usecase_from_list(adev, USECASE_COMPRESS_VOIP_CALL);
-    if (uc_info) {
-        uc_info->stream.out = out;
-        uc_info->devices = out->devices;
-    } else {
-        ret = -EINVAL;
-        ALOGE("%s: exit(%d): failed to get use case info", __func__, ret);
-        goto error;
-    }
-
-error:
-    ALOGV("%s: exit: status(%d)", __func__, ret);
-    return ret;
-}
-
-int voice_extn_compress_voip_start_input_stream(struct stream_in *in)
-{
-    int ret = 0;
-    struct audio_device *adev = in->dev;
-
-    ALOGD("%s: enter", __func__);
-
-    if (CARD_STATUS_OFFLINE == in->card_status ||
-        CARD_STATUS_OFFLINE == adev->card_status) {
-        ret = -ENETRESET;
-        ALOGE("%s: sound card is not active/SSR returning error %d ", __func__, ret);
-        goto error;
-    }
-
-    if (audio_is_bluetooth_sco_device(in->device) && !adev->bt_sco_on) {
-        ret = -EIO;
-        ALOGE("%s SCO is not ready return error %d", __func__,ret);
-        goto error;
-    }
-
-    if (!voip_data.in_stream_count)
-        ret = voice_extn_compress_voip_open_input_stream(in);
-
-    adev->active_input = in;
-    ret = voip_start_call(adev, &in->config);
-    in->pcm = voip_data.pcm_tx;
-
-error:
-    ALOGV("%s: exit: status(%d)", __func__, ret);
-    return ret;
-}
-
-int voice_extn_compress_voip_close_output_stream(struct audio_stream *stream)
-{
-    struct stream_out *out = (struct stream_out *)stream;
-    struct audio_device *adev = out->dev;
-    int ret = 0;
-
-    ALOGD("%s: enter", __func__);
-    if (voip_data.out_stream_count > 0) {
-        voip_data.out_stream_count--;
-        ret = voip_stop_call(adev);
-        voip_data.out_stream = NULL;
-        out->pcm = NULL;
-    }
-
-    ALOGV("%s: exit: status(%d)", __func__, ret);
-    return ret;
-}
-
-int voice_extn_compress_voip_open_output_stream(struct stream_out *out)
-{
-    int ret;
-
-    ALOGD("%s: enter", __func__);
-
-    out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_MONO;
-    out->channel_mask = AUDIO_CHANNEL_OUT_MONO;
-    out->usecase = USECASE_COMPRESS_VOIP_CALL;
-    if (out->sample_rate == 48000)
-        out->config = pcm_config_voip_fb;
-    else if (out->sample_rate == 32000)
-        out->config = pcm_config_voip_swb;
-    else if (out->sample_rate == 16000)
-        out->config = pcm_config_voip_wb;
-    else
-        out->config = pcm_config_voip_nb;
-
-    voip_data.out_stream = out;
-    voip_data.out_stream_count++;
-    voip_data.sample_rate = out->sample_rate;
-    ret = voip_set_mode(out->dev, out->format);
-
-    ALOGV("%s: exit", __func__);
-    return ret;
-}
-
-int voice_extn_compress_voip_close_input_stream(struct audio_stream *stream)
-{
-    struct stream_in *in = (struct stream_in *)stream;
-    struct audio_device *adev = in->dev;
-    int status = 0;
-
-    ALOGD("%s: enter", __func__);
-
-    if(voip_data.in_stream_count > 0) {
-       voip_data.in_stream_count--;
-       status = voip_stop_call(adev);
-       adev->active_input = get_next_active_input(adev);
-       in->pcm = NULL;
-    }
-
-    ALOGV("%s: exit: status(%d)", __func__, status);
-    return status;
-}
-
-int voice_extn_compress_voip_open_input_stream(struct stream_in *in)
-{
-    int ret;
-
-    ALOGD("%s: enter", __func__);
-
-    if ((voip_data.sample_rate != 0) &&
-        (voip_data.sample_rate != in->config.rate)) {
-        ret = -ENOTSUP;
-        goto done;
-    } else {
-        voip_data.sample_rate = in->config.rate;
-    }
-
-    ret = voip_set_mode(in->dev, in->format);
-    if (ret < 0)
-        goto done;
-
-    in->usecase = USECASE_COMPRESS_VOIP_CALL;
-    if (in->config.rate == 48000)
-        in->config = pcm_config_voip_fb;
-    else if (in->config.rate == 32000)
-        in->config = pcm_config_voip_swb;
-    else if (in->config.rate == 16000)
-        in->config = pcm_config_voip_wb;
-    else
-        in->config = pcm_config_voip_nb;
-
-    voip_data.in_stream_count++;
-
-done:
-    ALOGV("%s: exit, ret=%d", __func__, ret);
-    return ret;
-}
-
-int voice_extn_compress_voip_set_volume(struct audio_device *adev, float volume)
-{
-    int vol, err = 0;
-
-    ALOGV("%s: enter", __func__);
-
-    if (volume < 0.0) {
-        volume = 0.0;
-    } else if (volume > 1.0) {
-        volume = 1.0;
-    }
-
-    vol = lrint(volume * 100.0);
-
-    /* Voice volume levels from android are mapped to driver volume levels as follows.
-     * 0 -> 5, 20 -> 4, 40 ->3, 60 -> 2, 80 -> 1, 100 -> 0
-     * So adjust the volume to get the correct volume index in driver
-     */
-    vol = 100 - vol;
-
-    err = voip_set_volume(adev, vol);
-
-    ALOGV("%s: exit: status(%d)", __func__, err);
-
-    return err;
-}
-
-int voice_extn_compress_voip_set_mic_mute(struct audio_device *adev, bool state)
-{
-    int err = 0;
-
-    ALOGV("%s: enter", __func__);
-
-    err = voip_set_mic_mute(adev, state);
-
-    ALOGV("%s: exit: status(%d)", __func__, err);
-    return err;
-}
-
-bool voice_extn_compress_voip_pcm_prop_check()
-{
-    char prop_value[PROPERTY_VALUE_MAX] = {0};
-
-    property_get("vendor.voice.path.for.pcm.voip", prop_value, "0");
-    if (!strncmp("true", prop_value, sizeof("true")))
-    {
-        ALOGD("%s: VoIP PCM property is enabled", __func__);
-        return true;
-    }
-    else
-        return false;
-}
-
-bool voice_extn_compress_voip_is_active(const struct audio_device *adev)
-{
-    struct audio_usecase *voip_usecase = NULL;
-    voip_usecase = get_usecase_from_list(adev, USECASE_COMPRESS_VOIP_CALL);
-
-    if (voip_usecase != NULL)
-        return true;
-    else
-        return false;
-}
-
-bool voice_extn_compress_voip_is_format_supported(audio_format_t format)
-{
-    if (format == AUDIO_FORMAT_PCM_16_BIT &&
-       voice_extn_compress_voip_pcm_prop_check())
-       return true;
-    else
-       return false;
-}
-
-bool voice_extn_compress_voip_is_config_supported(struct audio_config *config)
-{
-    bool ret = false;
-
-    ret = voice_extn_compress_voip_is_format_supported(config->format);
-    if (ret) {
-        if ((popcount(config->channel_mask) == 1) &&
-            (config->sample_rate == 8000 || config->sample_rate == 16000 ||
-             config->sample_rate == 32000 || config->sample_rate == 48000))
-            ret = ((voip_data.sample_rate == 0) ? true:
-                    (voip_data.sample_rate == config->sample_rate));
-        else
-            ret = false;
-    }
-    return ret;
-}
-
-bool voice_extn_compress_voip_is_started(struct audio_device *adev)
-{
-    bool ret = false;
-    if (voice_extn_compress_voip_is_active(adev) &&
-        voip_data.pcm_tx && voip_data.pcm_rx)
-        ret = true;
-
-    return ret;
-}
+}
\ No newline at end of file
diff --git a/hal/voice_extn/voice_extn.c b/hal/voice_extn/voice_extn.c
index ec85259..b6a1879 100644
--- a/hal/voice_extn/voice_extn.c
+++ b/hal/voice_extn/voice_extn.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
@@ -35,6 +35,7 @@
 #include "platform.h"
 #include "platform_api.h"
 #include "voice_extn.h"
+#include "audio_feature_manager.h"
 
 #ifdef DYNAMIC_LOG_ENABLED
 #include <log_xml_parser.h>
@@ -83,8 +84,37 @@
     .avail_min = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
 };
 
+static bool voice_extn_compress_voip_enabled = false;
+static bool voice_extn_dynamic_ecns_feature_enabled = false;
+
 int voice_extn_is_call_state_active(struct audio_device *adev, bool *is_call_active);
 
+int compress_voip_set_parameters(struct audio_device *adev,
+                                             struct str_parms *parms);
+void compress_voip_get_parameters(struct str_parms *query,
+                                             struct str_parms *reply);
+void compress_voip_out_get_parameters(struct stream_out *out,
+                                                 struct str_parms *query,
+                                                 struct str_parms *reply);
+void compress_voip_in_get_parameters(struct stream_in *in,
+                                                struct str_parms *query,
+                                                struct str_parms *reply);
+int compress_voip_out_get_buffer_size(struct stream_out *out);
+int compress_voip_in_get_buffer_size(struct stream_in *in);
+int compress_voip_start_output_stream(struct stream_out *out);
+int compress_voip_start_input_stream(struct stream_in *in);
+int compress_voip_close_output_stream(struct audio_stream *stream);
+int compress_voip_open_output_stream(struct stream_out *out);
+int compress_voip_close_input_stream(struct audio_stream *stream);
+int compress_voip_open_input_stream(struct stream_in *in);
+int compress_voip_set_volume(struct audio_device *adev, float volume);
+int compress_voip_set_mic_mute(struct audio_device *adev, bool state);
+bool compress_voip_pcm_prop_check();
+bool compress_voip_is_active(const struct audio_device *adev);
+bool compress_voip_is_format_supported(audio_format_t format);
+bool compress_voip_is_config_supported(struct audio_config *config);
+bool compress_voip_is_started(struct audio_device *adev);
+
 static bool is_valid_call_state(int call_state)
 {
     if (call_state < CALL_INACTIVE || call_state > CALL_LOCAL_HOLD)
@@ -360,6 +390,36 @@
     return 0;
 }
 
+void dynamic_ecns_feature_init(bool is_feature_enabled)
+{
+    voice_extn_dynamic_ecns_feature_enabled = is_feature_enabled;
+    ALOGD(":: %s: ---- Feature DYNAMIC_ECNS is %s ----", __func__,
+                            is_feature_enabled? "ENABLED": " NOT ENABLED");
+}
+
+bool voice_extn_is_dynamic_ecns_enabled()
+{
+    return voice_extn_dynamic_ecns_feature_enabled;
+}
+
+void voice_extn_feature_init()
+{
+    for(int index = VOICE_START; index < MAX_SUPPORTED_FEATURE; index++)
+    {
+        bool enable = audio_feature_manager_is_feature_enabled(index);
+        switch (index) {
+            case COMPRESS_VOIP:
+                compr_voip_feature_init(enable);
+                break;
+            case DYNAMIC_ECNS:
+                dynamic_ecns_feature_init(enable);
+                break;
+            default:
+                break;
+        }
+    }
+}
+
 void voice_extn_init(struct audio_device *adev)
 {
     adev->voice.session[VOICE_SESS_IDX].vsid =  VOICE_VSID;
@@ -369,6 +429,18 @@
     adev->voice.session[VOWLAN_SESS_IDX].vsid = VOWLAN_VSID;
     adev->voice.session[MMODE1_SESS_IDX].vsid = VOICEMMODE1_VSID;
     adev->voice.session[MMODE2_SESS_IDX].vsid = VOICEMMODE2_VSID;
+    voice_extn_feature_init();
+}
+
+void compr_voip_feature_init(bool is_feature_enabled)
+{
+    voice_extn_compress_voip_enabled = is_feature_enabled;
+    ALOGD("%s:: ---- Feature COMPRESS_VOIP is %s ----", __func__, is_feature_enabled?"ENABLED":"NOT ENABLED");
+}
+
+bool voice_extn_is_compress_voip_supported()
+{
+    return voice_extn_compress_voip_enabled;
 }
 
 int voice_extn_get_session_from_use_case(struct audio_device *adev,
@@ -436,12 +508,15 @@
      * set routing with device BT A2DP profile. Hence end all voice calls when
      * set_mode(AUDIO_MODE_NORMAL) before BT A2DP profile is selected.
      */
-    ALOGD("%s: end all calls", __func__);
-    for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
-        adev->voice.session[i].state.new = CALL_INACTIVE;
+    if (adev->mode == AUDIO_MODE_NORMAL) {
+        ALOGD("%s: end all calls", __func__);
+        for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
+            adev->voice.session[i].state.new = CALL_INACTIVE;
+        }
+
+        ret = update_calls(adev);
     }
 
-    ret = update_calls(adev);
     return ret;
 }
 
@@ -573,7 +648,10 @@
         }
         str_parms_add_str(reply, AUDIO_PARAMETER_KEY_ALL_CALL_STATES, value);
     }
-    voice_extn_compress_voip_get_parameters(query, reply);
+    if(voice_extn_compress_voip_enabled)
+        voice_extn_compress_voip_get_parameters(query, reply);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
 
     str = str_parms_to_str(reply);
     ALOGV_IF(str != NULL, "%s: exit: returns \"%s\"", __func__, str);
@@ -584,16 +662,24 @@
                                    struct str_parms *query,
                                    struct str_parms *reply)
 {
-    voice_extn_compress_voip_out_get_parameters(out, query, reply);
+    if(voice_extn_compress_voip_enabled)
+        voice_extn_compress_voip_out_get_parameters(out, query, reply);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
 }
 
 void voice_extn_in_get_parameters(struct stream_in *in,
                                   struct str_parms *query,
                                   struct str_parms *reply)
 {
-    voice_extn_compress_voip_in_get_parameters(in, query, reply);
+    if(voice_extn_compress_voip_enabled)
+        voice_extn_compress_voip_in_get_parameters(in, query, reply);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+    
 }
 
+#ifdef INCALL_MUSIC_ENABLED
 int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev,
                                                   struct stream_out *out)
 {
@@ -607,3 +693,200 @@
     ALOGV("%s: mode=%d, usecase id=%d", __func__, adev->mode, out->usecase);
     return 0;
 }
+#endif
+
+int voice_extn_compress_voip_set_parameters(struct audio_device *adev,
+                                             struct str_parms *parms) 
+{
+    int ret = -1;
+    if(voice_extn_compress_voip_enabled)
+        ret = compress_voip_set_parameters(adev, parms);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+    return ret;
+}
+
+void voice_extn_compress_voip_get_parameters(struct str_parms *query,
+                                             struct str_parms *reply)
+{
+    if(voice_extn_compress_voip_enabled)
+        compress_voip_get_parameters(query, reply);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+}
+
+
+void voice_extn_compress_voip_out_get_parameters(struct stream_out *out,
+                                                 struct str_parms *query,
+                                                 struct str_parms *reply)
+{
+    if(voice_extn_compress_voip_enabled)
+        compress_voip_out_get_parameters(out, query, reply);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+}
+
+void voice_extn_compress_voip_in_get_parameters(struct stream_in *in,
+                                                struct str_parms *query,
+                                                struct str_parms *reply)
+{
+    if(voice_extn_compress_voip_enabled)
+        compress_voip_in_get_parameters(in, query, reply);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+}
+
+int voice_extn_compress_voip_out_get_buffer_size(struct stream_out *out)
+{
+    int ret = -1;
+    if(voice_extn_compress_voip_enabled)
+        ret = compress_voip_out_get_buffer_size(out);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+    return ret;
+}
+
+int voice_extn_compress_voip_in_get_buffer_size(struct stream_in *in)
+{
+    int ret = -1;
+    if(voice_extn_compress_voip_enabled)
+        ret = compress_voip_in_get_buffer_size(in);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+    return ret;
+}
+
+
+int voice_extn_compress_voip_start_output_stream(struct stream_out *out)
+{
+    int ret = -1;
+    if(voice_extn_compress_voip_enabled)
+        ret = compress_voip_start_output_stream(out);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+    return ret;
+}
+
+
+int voice_extn_compress_voip_start_input_stream(struct stream_in *in)
+{
+    int ret = -1;
+    if(voice_extn_compress_voip_enabled)
+        ret = compress_voip_start_input_stream(in);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+    return ret;
+}
+
+int voice_extn_compress_voip_close_output_stream(struct audio_stream *stream)
+{
+    int ret = -1;
+    if(voice_extn_compress_voip_enabled)
+        ret = compress_voip_close_output_stream(stream);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+    return ret;
+}
+
+
+int voice_extn_compress_voip_close_input_stream(struct audio_stream *stream)
+{
+    int ret = -1;
+    if(voice_extn_compress_voip_enabled)
+        ret = compress_voip_close_input_stream(stream);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+    return ret;
+}
+
+int voice_extn_compress_voip_open_output_stream(struct stream_out *out)
+{
+    int ret = -1;
+    if(voice_extn_compress_voip_enabled)
+        ret = compress_voip_open_output_stream(out);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+    return ret;
+}
+
+
+int voice_extn_compress_voip_open_input_stream(struct stream_in *in)
+{
+    int ret = -1;
+    if(voice_extn_compress_voip_enabled)
+        ret = compress_voip_open_input_stream(in);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+    return ret;
+}
+
+int voice_extn_compress_voip_set_volume(struct audio_device *adev, float volume)
+{
+    int ret = -1;
+    if(voice_extn_compress_voip_enabled)
+        ret = compress_voip_set_volume(adev, volume);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+    return ret;
+}
+
+int voice_extn_compress_voip_set_mic_mute(struct audio_device *adev, bool state)
+{
+    int ret = -1;
+    if(voice_extn_compress_voip_enabled)
+        ret = compress_voip_set_mic_mute(adev, state);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+    return ret;
+}
+
+bool voice_extn_compress_voip_pcm_prop_check()
+{
+    bool ret = false;
+    if(voice_extn_compress_voip_enabled)
+        ret = compress_voip_pcm_prop_check();
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+    return ret;
+}
+
+bool voice_extn_compress_voip_is_active(const struct audio_device *adev)
+{
+    bool ret = false;
+    if(voice_extn_compress_voip_enabled)
+        ret = compress_voip_is_active(adev);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+    return ret;
+}
+
+bool voice_extn_compress_voip_is_format_supported(audio_format_t format)
+{
+    bool ret = false;
+    if(voice_extn_compress_voip_enabled)
+        ret = compress_voip_is_format_supported(format);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+    return ret;
+}
+
+bool voice_extn_compress_voip_is_config_supported(struct audio_config *config)
+{
+    bool ret = false;
+    if(voice_extn_compress_voip_enabled)
+        ret = compress_voip_is_config_supported(config);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+    return ret;
+}
+
+bool voice_extn_compress_voip_is_started(struct audio_device *adev)
+{
+    bool ret = false;
+    if(voice_extn_compress_voip_enabled)
+        ret = compress_voip_is_started(adev);
+    else
+        ALOGE("%s: COMPRESS_VOIP feature is not enabled", __func__);
+    return ret;
+}
+
diff --git a/hal/voice_extn/voice_extn.h b/hal/voice_extn/voice_extn.h
index 5d1cac3..51afe47 100644
--- a/hal/voice_extn/voice_extn.h
+++ b/hal/voice_extn/voice_extn.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014, 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, 2016-2019, The Linux Foundation. All rights reserved.
  * Not a contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -20,13 +20,12 @@
 #ifndef VOICE_EXTN_H
 #define VOICE_EXTN_H
 
-#ifdef MULTI_VOICE_SESSION_ENABLED
+void voice_extn_init(struct audio_device *adev);
 int voice_extn_start_call(struct audio_device *adev);
 int voice_extn_stop_call(struct audio_device *adev);
 int voice_extn_get_session_from_use_case(struct audio_device *adev,
                                          const audio_usecase_t usecase_id,
                                          struct voice_session **session);
-void voice_extn_init(struct audio_device *adev);
 int voice_extn_set_parameters(struct audio_device *adev,
                               struct str_parms *parms);
 void voice_extn_get_parameters(const struct audio_device *adev,
@@ -42,68 +41,20 @@
 void voice_extn_out_get_parameters(struct stream_out *out,
                                    struct str_parms *query,
                                    struct str_parms *reply);
+#ifdef INCALL_MUSIC_ENABLED
+int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev,
+                                                  struct stream_out *out);
 #else
-static int __unused voice_extn_start_call(struct audio_device *adev __unused)
+static int __unused voice_extn_check_and_set_incall_music_usecase(
+                                          struct audio_device *adev __unused,
+                                          struct stream_out *out __unused)
 {
     return -ENOSYS;
 }
-
-static int __unused voice_extn_stop_call(struct audio_device *adev __unused)
-{
-    return -ENOSYS;
-}
-
-static int __unused voice_extn_get_session_from_use_case(struct audio_device *adev __unused,
-                                                const audio_usecase_t usecase_id __unused,
-                                                struct voice_session **session __unused)
-{
-    return -ENOSYS;
-}
-
-static void __unused voice_extn_init(struct audio_device *adev __unused)
-{
-}
-
-static int __unused voice_extn_set_parameters(struct audio_device *adev __unused,
-                                     struct str_parms *parms __unused)
-{
-    return -ENOSYS;
-}
-
-static void __unused voice_extn_get_parameters(const struct audio_device *adev __unused,
-                                      struct str_parms *query __unused,
-                                      struct str_parms *reply __unused)
-{
-}
-
-static int __unused voice_extn_is_call_state_active(struct audio_device *adev __unused,
-                                           bool *is_call_active __unused)
-{
-    return -ENOSYS;
-}
-
-static int __unused voice_extn_get_active_session_id(struct audio_device *adev __unused,
-                                            uint32_t *session_id __unused)
-{
-    return -ENOSYS;
-}
-
-static void __unused voice_extn_in_get_parameters(struct stream_in *in __unused,
-                                         struct str_parms *query __unused,
-                                         struct str_parms *reply __unused)
-{
-}
-
-static void __unused voice_extn_out_get_parameters(struct stream_out *out __unused,
-                                          struct str_parms *query __unused,
-                                          struct str_parms *reply __unused)
-{
-}
 #endif
 
 int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev,
                                                   struct stream_out *out);
-#ifdef COMPRESS_VOIP_ENABLED
 int voice_extn_compress_voip_close_output_stream(struct audio_stream *stream);
 int voice_extn_compress_voip_open_output_stream(struct stream_out *out);
 
@@ -137,153 +88,11 @@
 bool voice_extn_compress_voip_is_format_supported(audio_format_t format);
 bool voice_extn_compress_voip_is_config_supported(struct audio_config *config);
 bool voice_extn_compress_voip_is_started(struct audio_device *adev);
-#else
-static int __unused voice_extn_compress_voip_close_output_stream(
-                                     struct audio_stream *stream __unused)
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-    return -ENOSYS;
-}
+void voice_extn_feature_init();
+void compr_voip_feature_init(bool is_feature_enabled);
+bool voice_extn_is_compress_voip_supported();
+void dynamic_ecns_feature_init(bool is_feature_enabled);
+bool voice_extn_is_dynamic_ecns_enabled();
 
-static int __unused voice_extn_compress_voip_open_output_stream(
-                                         struct stream_out *out __unused)
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-    return -ENOSYS;
-}
-
-static int __unused voice_extn_compress_voip_close_input_stream(
-                                    struct audio_stream *stream __unused)
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-    return -ENOSYS;
-}
-
-static int __unused voice_extn_compress_voip_open_input_stream(
-                                          struct stream_in *in __unused)
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-    return -ENOSYS;
-}
-
-static int __unused voice_extn_compress_voip_out_get_buffer_size(
-                                       struct stream_out *stream __unused)
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-    return -ENOSYS;
-}
-
-static int __unused voice_extn_compress_voip_in_get_buffer_size(
-                                           struct stream_in *in __unused)
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-    return -ENOSYS;
-}
-
-static int __unused voice_extn_compress_voip_start_input_stream(
-                                           struct stream_in *in __unused)
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-    return -ENOSYS;
-}
-
-static int __unused voice_extn_compress_voip_start_output_stream(
-                                          struct stream_out *out __unused)
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-    return -ENOSYS;
-}
-
-static int __unused voice_extn_compress_voip_set_mic_mute(
-                                struct audio_device *adev __unused,
-                                bool state __unused)
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-    return 0;
-}
-
-static int __unused voice_extn_compress_voip_set_volume(
-                              struct audio_device *adev __unused,
-                              float volume __unused)
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-    return 0;
-}
-
-static int __unused voice_extn_compress_voip_select_devices(
-                                  struct audio_device *adev __unused,
-                                  snd_device_t *out_snd_device __unused,
-                                  snd_device_t *in_snd_device __unused)
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-    return -ENOSYS;
-}
-
-static int __unused voice_extn_compress_voip_set_parameters(
-                                  struct audio_device *adev __unused,
-                                  struct str_parms *parms __unused)
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-    return -ENOSYS;
-}
-
-static void __unused voice_extn_compress_voip_get_parameters(
-                                     struct str_parms *query __unused,
-                                     struct str_parms *reply __unused)
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-}
-
-static void __unused voice_extn_compress_voip_out_get_parameters(
-                                          struct stream_out *out __unused,
-                                          struct str_parms *query __unused,
-                                          struct str_parms *reply __unused)
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-}
-
-static void __unused voice_extn_compress_voip_in_get_parameters(
-                                           struct stream_in *in __unused,
-                                           struct str_parms *query __unused,
-                                           struct str_parms *reply __unused)
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-}
-
-static bool __unused voice_extn_compress_voip_pcm_prop_check()
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-    return false;
-}
-
-static bool __unused  voice_extn_compress_voip_is_active(
-                         const struct audio_device *adev __unused)
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-    return false;
-}
-
-static bool __unused voice_extn_compress_voip_is_format_supported(
-                                            audio_format_t format __unused)
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-    return true;
-}
-
-static bool __unused voice_extn_compress_voip_is_config_supported(
-                                      struct audio_config *config __unused)
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-    return true;
-}
-
-static bool __unused voice_extn_compress_voip_is_started(
-                               struct audio_device *adev __unused)
-{
-    ALOGV("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
-    return false;
-}
-
-#endif
 
 #endif //VOICE_EXTN_H
diff --git a/post_proc/Android.mk b/post_proc/Android.mk
index 637a1f3..c68a861 100644
--- a/post_proc/Android.mk
+++ b/post_proc/Android.mk
@@ -3,6 +3,7 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_CFLAGS := -DLIB_AUDIO_HAL="/vendor/lib/hw/audio.primary."$(TARGET_BOARD_PLATFORM)".so"
 LOCAL_CFLAGS += -Wno-unused-variable
 LOCAL_CFLAGS += -Wno-sign-compare
 LOCAL_CFLAGS += -Wno-unused-parameter
@@ -15,6 +16,8 @@
 LOCAL_CFLAGS += -Wno-unused-local-typedef
 LOCAL_CFLAGS += -Wno-format
 LOCAL_CFLAGS += -Wno-unused-value
+LOCAL_CFLAGS += -Wall
+LOCAL_CFLAGS += -Werror
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_PROXY_DEVICE)),true)
     LOCAL_CFLAGS += -DAFE_PROXY_ENABLED
@@ -27,17 +30,13 @@
         virtualizer.c \
         reverb.c \
         effect_api.c \
-        effect_util.c
+        effect_util.c \
+        asphere.c
 
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_HW_ACCELERATED_EFFECTS)),true)
-    LOCAL_CFLAGS += -DHW_ACCELERATED_EFFECTS
-    LOCAL_SRC_FILES += hw_accelerator.c
-endif
-
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_AUDIOSPHERE)),true)
-    LOCAL_CFLAGS += -DAUDIOSPHERE_ENABLED
-    LOCAL_SRC_FILES += asphere.c
-endif
+# HW_ACCELERATED has been disabled by default since msm8996. File doesn't
+# compile cleanly on tip so don't want to include it, but keeping this
+# as a reference.
+# LOCAL_SRC_FILES += hw_accelerator.c
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_INSTANCE_ID)), true)
     LOCAL_CFLAGS += -DINSTANCE_ID_ENABLED
@@ -74,14 +73,17 @@
 LOCAL_MODULE_RELATIVE_PATH := soundfx
 LOCAL_MODULE:= libqcompostprocbundle
 LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_OWNER := qti
 
 LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
 
 LOCAL_C_INCLUDES := \
         external/tinyalsa/include \
+        vendor/qcom/opensource/audio-hal/primary-hal/hal \
         $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include \
 	$(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/techpack/audio/include \
-        $(call include-path-for, audio-effects)
+        $(call include-path-for, audio-effects) \
+        vendor/qcom/opensource/audio-hal/primary-hal/hal/audio_extn/
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DLKM)),true)
   LOCAL_HEADER_LIBRARIES += audio_kernel_headers
@@ -142,7 +144,7 @@
 
 ################################################################################
 
-ifneq ($(filter msm8992 msm8994 msm8996 msm8998 sdm660 sdm845 apq8098_latv sdm710 msm8953 msm8937 qcs605 msmnile $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter msm8992 msm8994 msm8996 msm8998 sdm660 sdm845 apq8098_latv sdm710 msm8953 msm8937 qcs605 msmnile kona $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
 
 include $(CLEAR_VARS)
 
@@ -158,6 +160,8 @@
 LOCAL_CFLAGS += -Wno-unused-function
 LOCAL_CFLAGS += -Wno-unused-local-typedef
 LOCAL_CFLAGS += -Wno-format
+LOCAL_CFLAGS += -Wall
+LOCAL_CFLAGS += -Werror
 
 LOCAL_SRC_FILES:= \
         volume_listener.c
@@ -171,23 +175,26 @@
 LOCAL_SHARED_LIBRARIES := \
         libcutils \
         liblog \
-        libdl
+        libdl \
+        libaudioutils
 
 LOCAL_MODULE_RELATIVE_PATH := soundfx
 LOCAL_MODULE:= libvolumelistener
 LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_OWNER := qti
 
 LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
 
 LOCAL_C_INCLUDES := \
-        hardware/qcom/audio/hal \
+        vendor/qcom/opensource/audio-hal/primary-hal/hal \
         $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include \
         $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/techpack/audio/include \
         external/tinyalsa/include \
         $(call include-path-for, audio-effects) \
         $(call include-path-for, audio-route) \
-        hardware/qcom/audio/hal/audio_extn \
-        external/tinycompress/include
+        vendor/qcom/opensource/audio-hal/primary-hal/hal/audio_extn \
+        external/tinycompress/include \
+        system/media/audio_utils/include
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DLKM)),true)
   LOCAL_HEADER_LIBRARIES += audio_kernel_headers
@@ -203,4 +210,37 @@
 include $(BUILD_SHARED_LIBRARY)
 
 endif
+
+################################################################################
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_MAXX_AUDIO)), true)
+
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS := -D HAL_LIB_NAME=\"audio.primary."$(TARGET_BOARD_PLATFORM)".so\"
+
+LOCAL_SRC_FILES:= \
+    ma_listener.c
+
+LOCAL_CFLAGS += $(qcom_post_proc_common_cflags)
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    liblog \
+    libdl
+
+LOCAL_MODULE_RELATIVE_PATH := soundfx
+LOCAL_MODULE:= libmalistener
+LOCAL_MODULE_OWNER := google
+LOCAL_PROPRIETARY_MODULE := true
+
+LOCAL_C_INCLUDES := \
+    hardware/qcom/audio/hal \
+    system/media/audio/include/system \
+    $(call include-path-for, audio-effects)
+
+LOCAL_HEADER_LIBRARIES += libhardware_headers
+LOCAL_HEADER_LIBRARIES += libsystem_headers
+include $(BUILD_SHARED_LIBRARY)
+
+endif
 endif
diff --git a/post_proc/Makefile.am b/post_proc/Makefile.am
index 54602a2..bd29473 100644
--- a/post_proc/Makefile.am
+++ b/post_proc/Makefile.am
@@ -20,7 +20,6 @@
 endif
 
 if AUDIOSPHERE
-AM_CFLAGS += -DAUDIOSPHERE_ENABLED
 c_sources += asphere.c
 endif
 
diff --git a/post_proc/asphere.c b/post_proc/asphere.c
index 82bb496..0ff55e5 100644
--- a/post_proc/asphere.c
+++ b/post_proc/asphere.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, 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
@@ -33,14 +33,16 @@
 #include <fcntl.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <dlfcn.h>
 #include <stdbool.h>
 #include <sys/stat.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <cutils/list.h>
 #include <cutils/str_parms.h>
 #include <cutils/properties.h>
 #include <hardware/audio_effect.h>
 #include <pthread.h>
+#include <audio_feature_manager.h>
 #include "bundle.h"
 #include "equalizer.h"
 #include "bass_boost.h"
@@ -56,6 +58,10 @@
 
 #define AUDIO_ASPHERE_EVENT_NODE "/data/misc/audio_pp/event_node"
 
+#define PRIMARY_HAL_PATH XSTR(LIB_AUDIO_HAL)
+#define XSTR(x) STR(x)
+#define STR(x) #x
+
 enum {
     ASPHERE_ACTIVE = 0,
     ASPHERE_SUSPENDED,
@@ -84,6 +90,7 @@
 
 static struct asphere_module asphere;
 pthread_once_t asphere_once = PTHREAD_ONCE_INIT;
+static bool (*is_feature_enabled)(audio_ext_feature);
 
 static int asphere_create_app_notification_node(void)
 {
@@ -130,7 +137,7 @@
         asphere.enabled = (val[0] == 0) ? false : true;
         asphere.strength = val[1];
     }
-    ALOGD("%s: returned %d, enabled:%d, strength:%d",
+    ALOGD("%s: returned %d, enabled:%ld, strength:%ld",
           __func__, ret, val[0], val[1]);
 
     return ret;
@@ -153,7 +160,7 @@
     val[1] = asphere.strength;
 
     ret = mixer_ctl_set_array(ctl, val, sizeof(val)/sizeof(val[0]));
-    ALOGD("%s: returned %d, enabled:%d, strength:%d",
+    ALOGD("%s: returned %d, enabled:%ld, strength:%ld",
           __func__, ret, val[0], val[1]);
 
     return ret;
@@ -162,9 +169,26 @@
 static void asphere_init_once() {
     ALOGD("%s", __func__);
     pthread_mutex_init(&asphere.lock, NULL);
-    asphere.init_status = 1;
-    asphere_get_values_from_mixer();
-    asphere_create_app_notification_node();
+
+    if (access(PRIMARY_HAL_PATH, R_OK) == 0) {
+        void *hal_lib_pointer = dlopen(PRIMARY_HAL_PATH, RTLD_NOW);
+        if (hal_lib_pointer == NULL)
+            ALOGE("%s: DLOPEN failed for %s", __func__, PRIMARY_HAL_PATH);
+        else if ((is_feature_enabled = (bool (*)(audio_ext_feature))dlsym(hal_lib_pointer,
+                                     "audio_feature_manager_is_feature_enable")) != NULL) {
+            if (is_feature_enabled(AUDIOSPHERE)) {
+                asphere.init_status = 1;
+                asphere_get_values_from_mixer();
+                asphere_create_app_notification_node();
+                return;
+            } else
+                ALOGW("%s: asphere feature not enabled", __func__);
+        } else
+            ALOGE("%s: dlsym failed", __func__);
+    } else
+        ALOGE("%s: not able to acces lib %s ", __func__, PRIMARY_HAL_PATH);
+
+    asphere.init_status = 0;
 }
 
 static int asphere_init() {
@@ -179,14 +203,8 @@
     bool enable = false;
     int strength = -1;
     char value[32] = {0};
-    char propValue[PROPERTY_VALUE_MAX] = {0};
     bool set_enable = false, set_strength = false;
 
-    if (!property_get("vendor.audio.pp.asphere.enabled", propValue, "false") ||
-        (strncmp("true", propValue, 4) != 0)) {
-        ALOGV("%s: property not set!!! not doing anything", __func__);
-        return;
-    }
     if (asphere_init() != 1) {
         ALOGW("%s: init check failed!!!", __func__);
         return;
@@ -221,14 +239,8 @@
                                       struct str_parms *reply)
 {
     char value[32] = {0};
-    char propValue[PROPERTY_VALUE_MAX] = {0};
-    int get_status, get_enable, get_strength, ret;
+    int ret;
 
-    if (!property_get("vendor.audio.pp.asphere.enabled", propValue, "false") ||
-        (strncmp("true", propValue, 4) != 0)) {
-        ALOGV("%s: property not set!!! not doing anything", __func__);
-        return;
-    }
     if (asphere_init() != 1) {
         ALOGW("%s: init check failed!!!", __func__);
         return;
@@ -278,14 +290,8 @@
                                       struct listnode *created_effects)
 {
     struct listnode *node;
-    char propValue[PROPERTY_VALUE_MAX] = {0};
 
     ALOGV("%s: effect %0x", __func__, context->desc->type.timeLow);
-    if (!property_get("vendor.audio.pp.asphere.enabled", propValue, "false") ||
-        (strncmp("true", propValue, 4) != 0)) {
-        ALOGV("%s: property not set!!! not doing anything", __func__);
-        return;
-    }
     if (asphere_init() != 1) {
         ALOGW("%s: init check failed!!!", __func__);
         return;
diff --git a/post_proc/asphere.h b/post_proc/asphere.h
index d0e6830..3babd1d 100644
--- a/post_proc/asphere.h
+++ b/post_proc/asphere.h
@@ -34,17 +34,11 @@
 #include <cutils/list.h>
 #include "bundle.h"
 
-#ifdef AUDIOSPHERE_ENABLED
 void asphere_get_parameters(struct str_parms *query,
                             struct str_parms *reply);
 void asphere_set_parameters(struct str_parms *reply);
 void handle_asphere_on_effect_enabled(bool enable,
                                       effect_context_t *context,
                                       struct listnode *created_effects);
-#else
-#define asphere_get_parameters(query, reply) (0)
-#define asphere_set_parameters(parms)  (0)
-#define handle_asphere_on_effect_enabled(enable, context, created_effects) (0)
-#endif /* AUDIOSPHERE_ENABLED */
 
 #endif /* OFFLOAD_ASPHERE_H_ */
diff --git a/post_proc/bass_boost.c b/post_proc/bass_boost.c
index 15945b6..1ce1c21 100644
--- a/post_proc/bass_boost.c
+++ b/post_proc/bass_boost.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015, 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, 2017-2019, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -21,7 +21,7 @@
 //#define LOG_NDEBUG 0
 
 #include <cutils/list.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <cutils/properties.h>
 #include <tinyalsa/asoundlib.h>
 #include <sound/audio_effects.h>
@@ -98,7 +98,6 @@
     int32_t *param_tmp = (int32_t *)p->data;
     int32_t param = *param_tmp++;
     void *value = p->data + voffset;
-    int i;
 
     ALOGV("%s", __func__);
 
@@ -384,18 +383,16 @@
     return 0;
 }
 
-int bassboost_reset(effect_context_t *context)
+int bassboost_reset(effect_context_t *context __unused)
 {
-    bassboost_context_t *bass_ctxt = (bassboost_context_t *)context;
-
     return 0;
 }
 
 int bassboost_init(effect_context_t *context)
 {
     bassboost_context_t *bass_ctxt = (bassboost_context_t *)context;
-
     ALOGV("%s: ctxt %p", __func__, bass_ctxt);
+
     context->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
     context->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
     context->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
@@ -574,10 +571,8 @@
     return 0;
 }
 
-int pbe_reset(effect_context_t *context)
+int pbe_reset(effect_context_t *context __unused)
 {
-    pbe_context_t *pbe_ctxt = (pbe_context_t *)context;
-
     return 0;
 }
 
diff --git a/post_proc/bundle.c b/post_proc/bundle.c
index ce0d0ec..1e6b91d 100644
--- a/post_proc/bundle.c
+++ b/post_proc/bundle.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, 2019, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -40,7 +40,7 @@
 
 #include <stdlib.h>
 #include <cutils/list.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <system/thread_defs.h>
 #include <tinyalsa/asoundlib.h>
 #include <hardware/audio_effect.h>
@@ -290,7 +290,6 @@
 int offload_effects_bundle_hal_stop_output(audio_io_handle_t output, int pcm_id)
 {
     int ret = -1;
-    struct listnode *node;
     struct listnode *fx_node;
     output_context_t *out_ctxt;
 
@@ -450,7 +449,6 @@
         }
     }
 
-exit:
     pthread_mutex_unlock(&lock);
     return ret;
 }
@@ -768,7 +766,6 @@
 {
 
     effect_context_t * context = (effect_context_t *)self;
-    int retsize;
     int status = 0;
 
     pthread_mutex_lock(&lock);
diff --git a/post_proc/effect_api.c b/post_proc/effect_api.c
index 3098850..cff4be3 100644
--- a/post_proc/effect_api.c
+++ b/post_proc/effect_api.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, 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
@@ -56,7 +56,7 @@
 
 #include <stdbool.h>
 #include <errno.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <tinyalsa/asoundlib.h>
 #include <sound/audio_effects.h>
 #include <sound/devdep_params.h>
@@ -860,7 +860,6 @@
 {
     long param_values[128] = {0};
     long *p_param_values = param_values;
-    uint32_t i;
 
     ALOGV("%s", __func__);
     *p_param_values++ = SOFT_VOLUME_MODULE;
@@ -926,7 +925,6 @@
 {
     long param_values[128] = {0};
     long *p_param_values = param_values;
-    uint32_t i;
 
     ALOGV("%s", __func__);
     *p_param_values++ = SOFT_VOLUME2_MODULE;
@@ -969,7 +967,6 @@
 {
     long param_values[128] = {0};
     long *p_param_values = param_values;
-    uint32_t i;
 
     ALOGV("%s", __func__);
     if (!ctl) {
diff --git a/post_proc/equalizer.c b/post_proc/equalizer.c
index 3096eb9..ed16f12 100644
--- a/post_proc/equalizer.c
+++ b/post_proc/equalizer.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014, 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, 2017-2019, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -21,7 +21,7 @@
 //#define LOG_NDEBUG 0
 
 #include <cutils/list.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <tinyalsa/asoundlib.h>
 #include <sound/audio_effects.h>
 #include <audio_effects/effect_equalizer.h>
@@ -358,6 +358,13 @@
                 }
                 break;
         }
+
+        if (p->vsize < 1) {
+            p->status = -EINVAL;
+            android_errorWriteLog(0x534e4554, "37536407");
+            break;
+        }
+
         name = (char *)value;
         strlcpy(name, equalizer_get_preset_name(eq_ctxt, param2), p->vsize - 1);
         name[p->vsize - 1] = 0;
@@ -450,7 +457,7 @@
             if (vsize < (2 + NUM_EQ_BANDS) * sizeof(int16_t)) {
                 android_errorWriteLog(0x534e4554, "37563371");
                 ALOGE("\tERROR EQ_PARAM_PROPERTIES valueSize %d < %d",
-                                  vsize, (2 + NUM_EQ_BANDS) * sizeof(int16_t));
+                      vsize, (int) ((2 + NUM_EQ_BANDS) * sizeof(int16_t)));
                 p->status = -EINVAL;
                 break;
             }
@@ -480,10 +487,8 @@
     return 0;
 }
 
-int equalizer_reset(effect_context_t *context)
+int equalizer_reset(effect_context_t *context __unused)
 {
-    equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
-
     return 0;
 }
 
diff --git a/post_proc/ma_listener.c b/post_proc/ma_listener.c
new file mode 100644
index 0000000..04a9047
--- /dev/null
+++ b/post_proc/ma_listener.c
@@ -0,0 +1,630 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ma_listener"
+/*#define LOG_NDEBUG 0*/
+
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <math.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <cutils/list.h>
+#include <cutils/log.h>
+#include <hardware/audio_effect.h>
+#include <audio-base.h>
+
+#define MA_FLAG ( EFFECT_FLAG_TYPE_INSERT | \
+                   EFFECT_FLAG_VOLUME_IND | \
+                   EFFECT_FLAG_DEVICE_IND | \
+                   EFFECT_FLAG_OFFLOAD_SUPPORTED | \
+                   EFFECT_FLAG_NO_PROCESS)
+
+#define PRINT_STREAM_TYPE(i) ALOGV("descriptor found and is of stream type %s ",\
+                                                            i == AUDIO_STREAM_MUSIC ? "MUSIC": \
+                                                            i == AUDIO_STREAM_RING ? "RING": \
+                                                            i == AUDIO_STREAM_ALARM ? "ALARM": \
+                                                            i == AUDIO_STREAM_VOICE_CALL ? "Voice_call": \
+                                                            i == AUDIO_STREAM_SYSTEM ? "SYSTEM":       \
+                                                            i == AUDIO_STREAM_NOTIFICATION ? "Notification":\
+                                                            "--INVALID--"); \
+
+
+#define MA_SET_STATE "audio_hw_send_qdsp_parameter"
+#define HAL_VENDOR_PATH "/vendor/lib/hw"
+
+enum {
+    MA_LISTENER_STATE_UNINITIALIZED,
+    MA_LISTENER_STATE_INITIALIZED,
+    MA_LISTENER_STATE_ACTIVE,
+};
+
+typedef struct ma_listener_context_s ma_listener_context_t;
+static const struct effect_interface_s effect_interface;
+
+struct ma_state {
+    float vol;
+    bool active;
+};
+
+static const audio_stream_type_t MIN_STREAM_TYPES = AUDIO_STREAM_VOICE_CALL;
+static const audio_stream_type_t MAX_STREAM_TYPES = AUDIO_STREAM_NOTIFICATION;
+static struct ma_state g_cur_state[MAX_STREAM_TYPES + 1];
+
+struct ma_listener_context_s {
+    const struct effect_interface_s *itfe;
+    struct listnode effect_list_node;
+    effect_config_t config;
+    const effect_descriptor_t *desc;
+    uint32_t stream_type;
+    uint32_t session_id;
+    uint32_t state;
+    uint32_t dev_id;
+    float left_vol;
+    float right_vol;
+};
+
+/* voice UUID: 4ece09c2-3728-11e8-a9f9-fc4dd4486b6d */
+const effect_descriptor_t ma_listener_voice_descriptor = {
+    { 0x46f924ed, 0x25c3, 0x4272, 0x85b1, { 0x41, 0x78, 0x3f, 0x0d, 0xc6, 0x38 } },  // type
+    { 0x4ece09c2, 0x3728, 0x11e8, 0xa9f9, { 0xfc, 0x4d, 0xd4, 0x48, 0x6b, 0x6d } },  // uuid
+    EFFECT_CONTROL_API_VERSION,
+    MA_FLAG,
+    0, /* TODO */
+    1,
+    "MAXXAUDIO listener for Voice",
+    "The Android Open Source Project",
+};
+
+/* system UUID: 4f705ff6-3728-11e8-a0c6-fc4dd4486b6d */
+const effect_descriptor_t ma_listener_system_descriptor = {
+    { 0x8bd0f979, 0x5266, 0x4791, 0x9213, { 0x11, 0x3a, 0xbc, 0xf7, 0xd3, 0xdc } },  // type
+    { 0x4f705ff6, 0x3728, 0x11e8, 0xa0c6, { 0xfc, 0x4d, 0xd4, 0x48, 0x6b, 0x6d } },  // uuid
+    EFFECT_CONTROL_API_VERSION,
+    MA_FLAG,
+    0, /* TODO */
+    1,
+    "MAXXAUDIO listener for System",
+    "The Android Open Source Project",
+};
+
+/* ring UUID: 4fd6e5c8-3728-11e8-8303-fc4dd4486b6d */
+const effect_descriptor_t ma_listener_ring_descriptor = {
+    { 0x5380692a, 0x872e, 0x4697, 0x8e38, { 0xcd, 0xd1, 0x09, 0xf6, 0xcb, 0x87 } },  // type
+    { 0x4fd6e5c8, 0x3728, 0x11e8, 0x8303, { 0xfc, 0x4d, 0xd4, 0x48, 0x6b, 0x6d } },  // uuid
+    EFFECT_CONTROL_API_VERSION,
+    MA_FLAG,
+    0, /* TODO */
+    1,
+    "MAXXAUDIO listener for Ring",
+    "The Android Open Source Project",
+};
+/* music UUID: 5036194e-3728-11e8-8db9-fc4dd4486b6d */
+const effect_descriptor_t ma_listener_music_descriptor = {
+    { 0x3a3a19b2, 0x62b1, 0x4785, 0xb55e, { 0xb2, 0x8f, 0xd4, 0x1b, 0x83, 0x58 } },  // type
+    { 0x5036194e, 0x3728, 0x11e8, 0x8db9, { 0xfc, 0x4d, 0xd4, 0x48, 0x6b, 0x6d } },  // uuid
+    EFFECT_CONTROL_API_VERSION,
+    MA_FLAG,
+    0, /* TODO */
+    1,
+    "MAXXAUDIO listener for Music",
+    "The Android Open Source Project",
+};
+/* alarm UUID: 50b9f084-3728-11e8-9225-fc4dd4486b6d */
+const effect_descriptor_t ma_listener_alarm_descriptor = {
+    { 0x8d08d30f, 0xb4c3, 0x4600, 0x8f99, { 0xfc, 0xbb, 0x5d, 0x05, 0x8b, 0x60 } },  // type
+    { 0x50b9f084, 0x3728, 0x11e8, 0x9225, { 0xfc, 0x4d, 0xd4, 0x48, 0x6b, 0x6d } },  // uuid
+    EFFECT_CONTROL_API_VERSION,
+    MA_FLAG,
+    0, /* TODO */
+    1,
+    "MAXXAUDIO listener for Alarm",
+    "The Android Open Source Project",
+};
+/* notification UUID: 50fe4d56-3728-11e8-ac73-fc4dd4486b6d */
+const effect_descriptor_t ma_listener_notification_descriptor = {
+    { 0x513d09f5, 0xae7f, 0x483d, 0x922a, { 0x5c, 0x72, 0xc5, 0xe5, 0x68, 0x4c } },  // type
+    { 0x50fe4d56, 0x3728, 0x11e8, 0xac73, { 0xfc, 0x4d, 0xd4, 0x48, 0x6b, 0x6d } },  // uuid
+    EFFECT_CONTROL_API_VERSION,
+    MA_FLAG,
+    0, /* TODO */
+    1,
+    "MAXXAUDIO listener for Notification",
+    "The Android Open Source Project",
+};
+
+static const effect_descriptor_t *descriptors[] = {
+    &ma_listener_voice_descriptor,
+    &ma_listener_system_descriptor,
+    &ma_listener_ring_descriptor,
+    &ma_listener_music_descriptor,
+    &ma_listener_alarm_descriptor,
+    &ma_listener_notification_descriptor,
+    NULL,
+};
+
+/* function of sending state to HAL */
+static bool (*send_ma_parameter)(int, float, bool);
+
+static int init_state = -1;
+pthread_once_t once = PTHREAD_ONCE_INIT;
+
+struct listnode ma_effect_list;
+pthread_mutex_t ma_listner_init_lock;
+
+/*
+ *  Local functions
+ */
+static inline bool valid_dev_in_context(struct ma_listener_context_s *context)
+{
+    /* check device */
+    if ((context->dev_id & AUDIO_DEVICE_OUT_SPEAKER) ||
+        (context->dev_id & AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
+        /* TODO: it should be dynamic if hybird split A2SP is implemented. */
+        (context->dev_id & AUDIO_DEVICE_OUT_ALL_A2DP) ||
+        (context->dev_id & AUDIO_DEVICE_OUT_ALL_USB)) {
+        return true;
+    }
+
+    return false;
+}
+
+static void check_and_set_ma_parameter(uint32_t stream_type)
+{
+    bool active = false;
+    float temp_vol = 0.0;
+    float max_vol = 0.0;
+    struct listnode *node = NULL;
+    ma_listener_context_t *context = NULL;
+
+    ALOGV("%s .. called ..", __func__);
+    // get maximum volume for the active session with same strem type
+    list_for_each(node, &ma_effect_list) {
+        context = node_to_item(node, struct ma_listener_context_s, effect_list_node);
+        if (context->stream_type == stream_type &&
+            valid_dev_in_context(context)) {
+            if (context->state == MA_LISTENER_STATE_ACTIVE) {
+                active = true;
+                temp_vol = fmax(context->left_vol, context->right_vol);
+                if (max_vol < temp_vol)
+                    max_vol = temp_vol;
+                ALOGV("%s: check session(%d) volume(%f) for stream(%d)",
+                       __func__, context->session_id, temp_vol, stream_type);
+            }
+        }
+    }
+
+    // check volume
+    if (max_vol < 0.0) max_vol = 0;
+    else if (max_vol > 1.0) max_vol = 1.0;
+
+    if (send_ma_parameter != NULL &&
+        stream_type >= MIN_STREAM_TYPES &&
+        stream_type <= MAX_STREAM_TYPES &&
+        (g_cur_state[stream_type].vol != max_vol ||
+         g_cur_state[stream_type].active != active)) {
+
+        ALOGV("%s: set stream(%d) active(%s->%s) volume(%f->%f)",
+              __func__, stream_type,
+              g_cur_state[stream_type].active ? "T" : "F", active ? "T" : "F",
+              g_cur_state[stream_type].vol, max_vol);
+
+        // update changes to hal
+        send_ma_parameter(stream_type, max_vol, active);
+        g_cur_state[stream_type].vol = max_vol;
+        g_cur_state[stream_type].active = active;
+    }
+
+    return;
+}
+
+/*
+ * Effect Control Interface Implementation
+ */
+static int ma_effect_command(effect_handle_t self,
+                              uint32_t cmd_code, uint32_t cmd_size,
+                              void *p_cmd_data, uint32_t *reply_size,
+                              void *p_reply_data)
+{
+    ma_listener_context_t *context = (ma_listener_context_t *)self;
+    int status = 0;
+
+    ALOGV("%s .. called ..", __func__);
+    pthread_mutex_lock(&ma_listner_init_lock);
+
+    if (context == NULL || context->state == MA_LISTENER_STATE_UNINITIALIZED) {
+        ALOGE("%s: %s is NULL", __func__, (context == NULL) ?
+              "context" : "context->state");
+        status = -EINVAL;
+        goto exit;
+    }
+
+    switch (cmd_code) {
+    case EFFECT_CMD_INIT:
+        ALOGV("%s :: cmd called EFFECT_CMD_INIT", __func__);
+        if (p_reply_data == NULL || *reply_size != sizeof(int)) {
+            ALOGE("%s: EFFECT_CMD_INIT: %s, sending -EINVAL", __func__,
+                  (p_reply_data == NULL) ? "p_reply_data is NULL" :
+                  "*reply_size != sizeof(int)");
+            status = -EINVAL;
+            goto exit;
+        }
+        *(int *)p_reply_data = 0;
+        break;
+
+    case EFFECT_CMD_SET_CONFIG:
+        ALOGV("%s :: cmd called EFFECT_CMD_SET_CONFIG", __func__);
+        if (p_cmd_data == NULL || cmd_size != sizeof(effect_config_t)
+                || p_reply_data == NULL || reply_size == NULL || *reply_size != sizeof(int)) {
+            status = -EINVAL;
+            goto exit;
+        }
+        context->config = *(effect_config_t *)p_cmd_data;
+        *(int *)p_reply_data = 0;
+        break;
+
+    case EFFECT_CMD_GET_CONFIG:
+        ALOGV("%s :: cmd called EFFECT_CMD_GET_CONFIG", __func__);
+        break;
+
+    case EFFECT_CMD_RESET:
+        ALOGV("%s :: cmd called EFFECT_CMD_RESET", __func__);
+        break;
+
+    case EFFECT_CMD_SET_AUDIO_MODE:
+        ALOGV("%s :: cmd called EFFECT_CMD_SET_AUDIO_MODE", __func__);
+        break;
+
+    case EFFECT_CMD_OFFLOAD:
+        ALOGV("%s :: cmd called EFFECT_CMD_OFFLOAD", __func__);
+        if (p_reply_data == NULL || *reply_size != sizeof(int)) {
+            ALOGE("%s: EFFECT_CMD_OFFLOAD: %s, sending -EINVAL", __func__,
+                  (p_reply_data == NULL) ? "p_reply_data is NULL" :
+                  "*reply_size != sizeof(int)");
+            status = -EINVAL;
+            goto exit;
+        }
+        *(int *)p_reply_data = 0;
+        break;
+
+    case EFFECT_CMD_ENABLE:
+        ALOGV("%s :: cmd called EFFECT_CMD_ENABLE", __func__);
+        if (p_reply_data == NULL || *reply_size != sizeof(int)) {
+            ALOGE("%s: EFFECT_CMD_ENABLE: %s, sending -EINVAL", __func__,
+                   (p_reply_data == NULL) ? "p_reply_data is NULL" :
+                   "*reply_size != sizeof(int)");
+            status = -EINVAL;
+            goto exit;
+        }
+
+        if (context->state != MA_LISTENER_STATE_INITIALIZED) {
+            ALOGE("%s: EFFECT_CMD_ENABLE : state not INITIALIZED", __func__);
+            status = -ENOSYS;
+            goto exit;
+        }
+
+        context->state = MA_LISTENER_STATE_ACTIVE;
+        *(int *)p_reply_data = 0;
+
+        // After changing the state and if device is valid
+        // check and send state
+        if (valid_dev_in_context(context)) {
+            check_and_set_ma_parameter(context->stream_type);
+        }
+
+        break;
+
+    case EFFECT_CMD_DISABLE:
+        ALOGV("%s :: cmd called EFFECT_CMD_DISABLE", __func__);
+        if (p_reply_data == NULL || *reply_size != sizeof(int)) {
+            ALOGE("%s: EFFECT_CMD_DISABLE: %s, sending -EINVAL", __func__,
+                  (p_reply_data == NULL) ? "p_reply_data is NULL" :
+                  "*reply_size != sizeof(int)");
+            status = -EINVAL;
+            goto exit;
+        }
+
+        if (context->state != MA_LISTENER_STATE_ACTIVE) {
+            ALOGE("%s: EFFECT_CMD_ENABLE : state not ACTIVE", __func__);
+            status = -ENOSYS;
+            goto exit;
+        }
+
+        context->state = MA_LISTENER_STATE_INITIALIZED;
+        *(int *)p_reply_data = 0;
+
+        // After changing the state and if device is valid
+        // check and send state
+        if (valid_dev_in_context(context)) {
+            check_and_set_ma_parameter(context->stream_type);
+        }
+
+        break;
+
+    case EFFECT_CMD_GET_PARAM:
+        ALOGV("%s :: cmd called EFFECT_CMD_GET_PARAM", __func__);
+        break;
+
+    case EFFECT_CMD_SET_PARAM:
+        ALOGV("%s :: cmd called EFFECT_CMD_SET_PARAM", __func__);
+        break;
+
+    case EFFECT_CMD_SET_DEVICE:
+    {
+        uint32_t new_device;
+
+        if (p_cmd_data == NULL) {
+            ALOGE("%s: EFFECT_CMD_SET_DEVICE: cmd data NULL", __func__);
+            status = -EINVAL;
+            goto exit;
+        }
+
+        new_device = *(uint32_t *)p_cmd_data;
+        ALOGV("%s :: EFFECT_CMD_SET_DEVICE: (current/new) device (0x%x / 0x%x)",
+               __func__, context->dev_id, new_device);
+
+        context->dev_id = new_device;
+        // After changing the state and if device is valid
+        // check and send parameter
+        if (valid_dev_in_context(context)) {
+            check_and_set_ma_parameter(context->stream_type);
+        }
+    }
+    break;
+
+    case EFFECT_CMD_SET_VOLUME:
+    {
+        float left_vol = 0, right_vol = 0;
+
+        ALOGV("cmd called EFFECT_CMD_SET_VOLUME");
+        if (p_cmd_data == NULL || cmd_size != 2 * sizeof(uint32_t)) {
+            ALOGE("%s: EFFECT_CMD_SET_VOLUME: %s", __func__, (p_cmd_data == NULL) ?
+                  "p_cmd_data is NULL" : "cmd_size issue");
+            status = -EINVAL;
+            goto exit;
+        }
+
+        left_vol = (float)(*(uint32_t *)p_cmd_data) / (1 << 24);
+        right_vol = (float)(*((uint32_t *)p_cmd_data + 1)) / (1 << 24);
+        ALOGV("Current Volume (%f / %f ) new Volume (%f / %f)", context->left_vol,
+              context->right_vol, left_vol, right_vol);
+
+        context->left_vol = left_vol;
+        context->right_vol = right_vol;
+
+        // After changing the state and if device is valid
+        // check and send volume
+        if (valid_dev_in_context(context)) {
+            check_and_set_ma_parameter(context->stream_type);
+        }
+    }
+    break;
+
+    default:
+        ALOGW("%s: unknow command %d", __func__, cmd_code);
+        status = -ENOSYS;
+        break;
+    }
+
+exit:
+    pthread_mutex_unlock(&ma_listner_init_lock);
+    return status;
+}
+
+/* Effect Control Interface Implementation: get_descriptor */
+static int ma_effect_get_descriptor(effect_handle_t   self,
+                                     effect_descriptor_t *descriptor)
+{
+    ma_listener_context_t *context = (ma_listener_context_t *)self;
+    ALOGV("%s .. called ..", __func__);
+
+    if (descriptor == NULL) {
+        ALOGE("%s: descriptor is NULL", __func__);
+        return -EINVAL;
+    }
+
+    *descriptor = *context->desc;
+    return 0;
+}
+
+static void init_once()
+{
+    int ret = 0;
+    void *handle = NULL;
+    char lib_path[PATH_MAX] = {0};
+
+    if (init_state == 0) {
+        ALOGD("%s : already init ... do nothing", __func__);
+        return;
+    }
+
+    ALOGV("%s .. called ..", __func__);
+
+    send_ma_parameter = NULL;
+
+    ret = snprintf(lib_path, PATH_MAX, "%s/%s", HAL_VENDOR_PATH, HAL_LIB_NAME);
+    if (ret < 0) {
+        ALOGE("%s: snprintf failed for lib %s ret %d", __func__, HAL_LIB_NAME, ret);
+        return;
+    }
+
+    handle = dlopen(lib_path, RTLD_NOW);
+    if (handle == NULL) {
+        ALOGE("%s: DLOPEN failed for %s", __func__, HAL_LIB_NAME);
+        return;
+    } else {
+        ALOGV("%s: DLOPEN successful for %s", __func__, HAL_LIB_NAME);
+        send_ma_parameter = (bool (*)(int, float, bool))dlsym(handle, MA_SET_STATE);
+
+        if (!send_ma_parameter) {
+            ALOGE("%s: dlsym error %s for send_ma_parameter", __func__, dlerror());
+            return;
+        }
+    }
+
+    pthread_mutex_init(&ma_listner_init_lock, NULL);
+    list_init(&ma_effect_list);
+    init_state = 0;
+
+    ALOGD("%s: exit ret %d", __func__, init_state);
+}
+
+static bool lib_init()
+{
+    pthread_once(&once, init_once);
+    return init_state;
+}
+
+static int ma_prc_lib_create(const effect_uuid_t *uuid,
+                              int32_t session_id,
+                              int32_t io_id __unused,
+                              effect_handle_t *p_handle)
+{
+    int itt = 0;
+    ma_listener_context_t *context = NULL;
+
+    ALOGV("%s .. called ..", __func__);
+
+    if (lib_init() != 0) {
+        return init_state;
+    }
+
+    if (p_handle == NULL || uuid == NULL) {
+        ALOGE("%s: %s is NULL", __func__, (p_handle == NULL) ? "p_handle" : "uuid");
+        return -EINVAL;
+    }
+
+    context = (ma_listener_context_t *)calloc(1, sizeof(ma_listener_context_t));
+
+    if (context == NULL) {
+        ALOGE("%s: failed to allocate for context .. oops !!", __func__);
+        return -EINVAL;
+    }
+
+    // check if UUID is supported
+    for (itt = 0; descriptors[itt] != NULL; itt++) {
+        if (memcmp(uuid, &descriptors[itt]->uuid, sizeof(effect_uuid_t)) == 0) {
+            context->desc = descriptors[itt];
+            context->stream_type = itt;
+            PRINT_STREAM_TYPE(itt)
+            break;
+        }
+    }
+
+    if (descriptors[itt] == NULL) {
+        ALOGE("%s .. couldnt find passed uuid, something wrong", __func__);
+        free(context);
+        return -EINVAL;
+    }
+
+    ALOGV("%s CREATED_CONTEXT %p", __func__, context);
+
+    context->itfe = &effect_interface;
+    context->state = MA_LISTENER_STATE_INITIALIZED;
+    context->dev_id = AUDIO_DEVICE_NONE;
+    context->session_id = session_id;
+
+    // Add this to master list
+    pthread_mutex_lock(&ma_listner_init_lock);
+    list_add_tail(&ma_effect_list, &context->effect_list_node);
+
+    pthread_mutex_unlock(&ma_listner_init_lock);
+
+    *p_handle = (effect_handle_t)context;
+    return 0;
+}
+
+static int ma_prc_lib_release(effect_handle_t handle)
+{
+    struct listnode *node, *temp_node_next;
+    ma_listener_context_t *context = NULL;
+    ma_listener_context_t *recv_contex = (ma_listener_context_t *)handle;
+    int status = -EINVAL;
+
+    ALOGV("%s: context %p", __func__, handle);
+
+    if (recv_contex == NULL) {
+        return status;
+    }
+
+    pthread_mutex_lock(&ma_listner_init_lock);
+    // check if the handle/context provided is valid
+    list_for_each_safe(node, temp_node_next, &ma_effect_list) {
+        context = node_to_item(node, struct ma_listener_context_s, effect_list_node);
+        if (context == recv_contex) {
+            ALOGV("--- Found something to remove ---");
+            list_remove(node);
+            PRINT_STREAM_TYPE(context->stream_type);
+            free(context);
+            status = 0;
+        }
+    }
+
+    if (status != 0) {
+        ALOGE("%s: nothing to remove, ret %d", __func__, status);
+        pthread_mutex_unlock(&ma_listner_init_lock);
+        return status;
+    }
+
+    pthread_mutex_unlock(&ma_listner_init_lock);
+    return status;
+}
+
+static int ma_prc_lib_get_descriptor(const effect_uuid_t *uuid,
+                                      effect_descriptor_t *descriptor)
+{
+    int i = 0;
+
+    ALOGV("%s .. called ..", __func__);
+    if (lib_init() != 0) {
+        return init_state;
+    }
+
+    if (descriptor == NULL || uuid == NULL) {
+        ALOGE("%s: %s is NULL", __func__, (descriptor == NULL) ? "descriptor" : "uuid");
+        return -EINVAL;
+    }
+
+    for (i = 0; descriptors[i] != NULL; i++) {
+        if (memcmp(uuid, &descriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) {
+            *descriptor = *descriptors[i];
+            return 0;
+        }
+    }
+
+    ALOGE("%s: couldnt found uuid passed, oops", __func__);
+    return -EINVAL;
+}
+
+
+/* effect_handle_t interface implementation for volume listener effect */
+static const struct effect_interface_s effect_interface = {
+    NULL,
+    ma_effect_command,
+    ma_effect_get_descriptor,
+    NULL,
+};
+
+__attribute__((visibility("default")))
+audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
+    .tag = AUDIO_EFFECT_LIBRARY_TAG,
+    .version = EFFECT_LIBRARY_API_VERSION,
+    .name = "MAXXAUDIO Listener Effect Library",
+    .implementor = "The Android Open Source Project",
+    .create_effect = ma_prc_lib_create,
+    .release_effect = ma_prc_lib_release,
+    .get_descriptor = ma_prc_lib_get_descriptor,
+};
diff --git a/post_proc/reverb.c b/post_proc/reverb.c
index be15480..a2fc4fd 100644
--- a/post_proc/reverb.c
+++ b/post_proc/reverb.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 - 2014, 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, 2017-2019, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -21,7 +21,7 @@
 //#define LOG_NDEBUG 0
 
 #include <cutils/list.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <tinyalsa/asoundlib.h>
 #include <sound/audio_effects.h>
 #include <audio_effects/effect_environmentalreverb.h>
@@ -467,7 +467,6 @@
     int32_t param = *param_tmp++;
     void *value = p->data + voffset;
     reverb_settings_t *reverb_settings;
-    int i;
 
     ALOGV("%s: ctxt %p, param %d", __func__, reverb_ctxt, param);
 
@@ -697,10 +696,8 @@
     return 0;
 }
 
-int reverb_reset(effect_context_t *context)
+int reverb_reset(effect_context_t *context __unused)
 {
-    reverb_context_t *reverb_ctxt = (reverb_context_t *)context;
-
     return 0;
 }
 
diff --git a/post_proc/virtualizer.c b/post_proc/virtualizer.c
index 18aaeec..f8a488f 100644
--- a/post_proc/virtualizer.c
+++ b/post_proc/virtualizer.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015, 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, 2017-2019, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -21,16 +21,25 @@
 //#define LOG_NDEBUG 0
 
 #include <cutils/list.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <tinyalsa/asoundlib.h>
 #include <sound/audio_effects.h>
 #include <audio_effects/effect_virtualizer.h>
+#include <audio_feature_manager.h>
+#include <dlfcn.h>
+#include <unistd.h>
 
 #include "effect_api.h"
 #include "virtualizer.h"
 
 #define VIRUALIZER_MAX_LATENCY 30
 
+#define PRIMARY_HAL_PATH XSTR(LIB_AUDIO_HAL)
+#define XSTR(x) STR(x)
+#define STR(x) #x
+
+static bool (*is_feature_enabled)(audio_ext_feature);
+
 #ifdef AUDIO_FEATURE_ENABLED_GCOV
 extern void  __gcov_flush();
 static void enable_gcov()
@@ -104,13 +113,16 @@
  *  true      device is applicable for effect
  */
 bool virtualizer_is_device_supported(audio_devices_t device) {
+    if (is_feature_enabled != NULL &&
+        is_feature_enabled(AFE_PROXY)) {
+        if (device == AUDIO_DEVICE_OUT_PROXY)
+            return false;
+    }
+
     switch (device) {
     case AUDIO_DEVICE_OUT_SPEAKER:
     case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
     case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
-#ifdef AFE_PROXY_ENABLED
-    case AUDIO_DEVICE_OUT_PROXY:
-#endif
     case AUDIO_DEVICE_OUT_AUX_DIGITAL:
     case AUDIO_DEVICE_OUT_USB_ACCESSORY:
     case AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET:
@@ -292,7 +304,6 @@
     int32_t *param_tmp = (int32_t *)p->data;
     int32_t param = *param_tmp++;
     void *value = p->data + voffset;
-    int i;
 
     ALOGV("%s: ctxt %p, param %d", __func__, virt_ctxt, param);
 
@@ -461,10 +472,8 @@
     return 0;
 }
 
-int virtualizer_reset(effect_context_t *context)
+int virtualizer_reset(effect_context_t *context __unused)
 {
-    virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)context;
-
     return 0;
 }
 
@@ -473,6 +482,20 @@
     ALOGV("%s: ctxt %p", __func__, context);
     virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)context;
 
+    if (access(PRIMARY_HAL_PATH, R_OK) == 0) {
+        void *hal_lib_pointer = dlopen(PRIMARY_HAL_PATH, RTLD_NOW);
+        if (hal_lib_pointer == NULL)
+            ALOGE("%s: DLOPEN failed for %s", __func__, PRIMARY_HAL_PATH);
+        else {
+            is_feature_enabled =
+                     (bool (*)(audio_ext_feature))dlsym(hal_lib_pointer,
+                               "audio_feature_manager_is_feature_enable");
+            if (is_feature_enabled == NULL)
+                ALOGE("%s: dlsym failed", __func__);
+        }
+    } else
+        ALOGE("%s: not able to acces lib %s ", __func__, PRIMARY_HAL_PATH);
+
     context->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
     context->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
     context->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
diff --git a/post_proc/volume_listener.c b/post_proc/volume_listener.c
index d4c3753..7372020 100644
--- a/post_proc/volume_listener.c
+++ b/post_proc/volume_listener.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-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
@@ -31,11 +31,12 @@
 //#define LOG_NDEBUG 0
 #include <stdlib.h>
 #include <dlfcn.h>
+#include <math.h>
 #include <unistd.h>
 #include <pthread.h>
 
 #include <cutils/list.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <hardware/audio_effect.h>
 #include <cutils/properties.h>
 #include <platform_api.h>
@@ -62,6 +63,7 @@
 
 #define AHAL_GAIN_DEPENDENT_INTERFACE_FUNCTION "audio_hw_send_gain_dep_calibration"
 #define AHAL_GAIN_GET_MAPPING_TABLE "audio_hw_get_gain_level_mapping"
+#define DEFAULT_CAL_STEP 0
 
 #ifdef AUDIO_FEATURE_ENABLED_GCOV
 extern void  __gcov_flush();
@@ -224,15 +226,22 @@
 /* lock must be held when modifying or accessing created_effects_list */
 pthread_mutex_t vol_listner_init_lock;
 
+static bool headset_cal_enabled;
+
 /*
  *  Local functions
  */
 static bool verify_context(vol_listener_context_t *context)
 {
-    if (context->stream_type == VC_CALL)
+    if (context->stream_type == VC_CALL &&
+        headset_cal_enabled &&
+        (context->dev_id == AUDIO_DEVICE_OUT_EARPIECE ||
+        context->dev_id == AUDIO_DEVICE_OUT_WIRED_HEADSET ||
+        context->dev_id == AUDIO_DEVICE_OUT_WIRED_HEADPHONE))
         return true;
     else {
-        if (context->dev_id & AUDIO_DEVICE_OUT_SPEAKER)
+        if (context->dev_id & AUDIO_DEVICE_OUT_SPEAKER ||
+            context->dev_id & AUDIO_DEVICE_OUT_SPEAKER_SAFE)
             return true;
         else
             return false;
@@ -266,12 +275,13 @@
 {
     // iterate through list and make decision to set new gain dep cal level for speaker device
     // 1. find all usecase active on speaker
-    // 2. find average of left and right for each usecase
+    // 2. find energy sum for each usecase
     // 3. find the highest of all the active usecase
     // 4. if new value is different than the current value then load new calibration
 
     struct listnode *node = NULL;
-    float new_vol = 0.0;
+    float new_vol = -1.0, sum_energy = 0.0, temp_vol = 0.0;
+    bool sum_energy_used = false;
     int max_level = 0;
     vol_listener_context_t *context = NULL;
     if (dumping_enabled) {
@@ -280,16 +290,21 @@
 
     ALOGV("%s ==> Start ...", __func__);
 
-    // select the highest volume on speaker device
+    // compute energy sum for the active speaker device (pick loudest of both channels)
     list_for_each(node, &vol_effect_list) {
         context = node_to_item(node, struct vol_listener_context_s, effect_list_node);
         if ((context->state == VOL_LISTENER_STATE_ACTIVE) &&
-            verify_context(context) &&
-            (new_vol < (context->left_vol + context->right_vol) / 2)) {
-            new_vol = (context->left_vol + context->right_vol) / 2;
+            verify_context(context)) {
+            sum_energy_used = true;
+            temp_vol = fmax(context->left_vol, context->right_vol);
+            sum_energy += temp_vol * temp_vol;
         }
     }
 
+    if (sum_energy_used) {
+        new_vol = fmin(sqrt(sum_energy), 1.0);
+    }
+
     if (new_vol != current_vol) {
         ALOGV("%s:: Change in decision :: current volume is %f new volume is %f",
               __func__, current_vol, new_vol);
@@ -300,7 +315,9 @@
 
             if (new_vol >= 1 && total_volume_cal_step > 0) { // max amplitude, use highest DRC level
                 gain_dep_cal_level = volume_curve_gain_mapping_table[total_volume_cal_step - 1].level;
-            } else if (new_vol <= 0) {
+            } else if (new_vol == -1) {
+                gain_dep_cal_level = DEFAULT_CAL_STEP;
+            } else if (new_vol == 0) {
                 gain_dep_cal_level = volume_curve_gain_mapping_table[0].level;
             } else {
                 for (max_level = 0; max_level + 1 < total_volume_cal_step; max_level++) {
@@ -430,7 +447,9 @@
             ALOGE("%s: EFFECT_CMD_INIT: %s, sending -EINVAL", __func__,
                   (p_reply_data == NULL) ? "p_reply_data is NULL" :
                   "*reply_size != sizeof(int)");
-            return -EINVAL;
+            android_errorWriteLog(0x534e4554, "32669549");
+            status = -EINVAL;
+            goto exit;
         }
         *(int *)p_reply_data = 0;
         break;
@@ -439,7 +458,9 @@
         ALOGV("%s :: cmd called EFFECT_CMD_SET_CONFIG", __func__);
         if (p_cmd_data == NULL || cmd_size != sizeof(effect_config_t)
                 || p_reply_data == NULL || reply_size == NULL || *reply_size != sizeof(int)) {
-            return -EINVAL;
+            android_errorWriteLog(0x534e4554, "32669549");
+            status = -EINVAL;
+            goto exit;
         }
         context->config = *(effect_config_t *)p_cmd_data;
         *(int *)p_reply_data = 0;
@@ -463,7 +484,9 @@
             ALOGE("%s: EFFECT_CMD_OFFLOAD: %s, sending -EINVAL", __func__,
                   (p_reply_data == NULL) ? "p_reply_data is NULL" :
                   "*reply_size != sizeof(int)");
-            return -EINVAL;
+            android_errorWriteLog(0x534e4554, "32669549");
+            status = -EINVAL;
+            goto exit;
         }
         *(int *)p_reply_data = 0;
         break;
@@ -547,13 +570,10 @@
                    __func__, context->dev_id, new_device);
 
             // check if old or new device is speaker for playback usecase
-            if (context->stream_type == VC_CALL)
+            if (verify_context(context) ||
+                new_device & AUDIO_DEVICE_OUT_SPEAKER ||
+                new_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE)
                 recompute_gain_dep_cal_Level = true;
-            else {
-                if (context->dev_id & AUDIO_DEVICE_OUT_SPEAKER ||
-                    new_device & AUDIO_DEVICE_OUT_SPEAKER)
-                    recompute_gain_dep_cal_Level = true;
-            }
 
             context->dev_id = new_device;
 
@@ -692,9 +712,15 @@
     // check system property to see if dumping is required
     char check_dump_val[PROPERTY_VALUE_MAX];
     property_get("vendor.audio.volume.listener.dump", check_dump_val, "0");
-    if (atoi(check_dump_val)) {
+    if (atoi(check_dump_val))
         dumping_enabled = true;
+    else {
+        property_get("audio.volume.listener.dump", check_dump_val, "0");
+        if (atoi(check_dump_val))
+            dumping_enabled = true;
     }
+    headset_cal_enabled = property_get_bool(
+                            "audio.volume.headset.gain.depcal", false);
 
     init_status = 0;
     list_init(&vol_effect_list);
@@ -773,7 +799,7 @@
 
 static int vol_prc_lib_release(effect_handle_t handle)
 {
-    struct listnode *node = NULL;
+    struct listnode *node = NULL, *temp_node_next;
     vol_listener_context_t *context = NULL;
     vol_listener_context_t *recv_contex = (vol_listener_context_t *)handle;
     int status = -EINVAL;
@@ -791,10 +817,18 @@
     pthread_mutex_lock(&vol_listner_init_lock);
     session_id = recv_contex->session_id;
     stream_type = recv_contex->stream_type;
+
+    if (recv_contex->desc == NULL) {
+        ALOGE("%s: Got NULL descriptor, session %u, stream type %u",
+                __func__, session_id, stream_type);
+        dump_list_l();
+        pthread_mutex_unlock(&vol_listner_init_lock);
+        return status;
+    }
     uuid = recv_contex->desc->uuid;
 
     // check if the handle/context provided is valid
-    list_for_each(node, &vol_effect_list) {
+    list_for_each_safe(node, temp_node_next, &vol_effect_list) {
         context = node_to_item(node, struct vol_listener_context_s, effect_list_node);
         if ((memcmp(&(context->desc->uuid), &uuid, sizeof(effect_uuid_t)) == 0)
             && (context->session_id == session_id)
diff --git a/visualizer/Android.mk b/visualizer/Android.mk
index 5c663bd..3d0f734 100644
--- a/visualizer/Android.mk
+++ b/visualizer/Android.mk
@@ -1,4 +1,4 @@
-# Copyright 2013 The Android Open Source Project
+# Copyright 2013, 2019 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -18,11 +18,18 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-	offload_visualizer.c
+    offload_visualizer.c
 
 LOCAL_CFLAGS+= -O2 -fvisibility=hidden
 
-LOCAL_CFLAGS += -Wno-unused-variable -Wno-unused-parameter -Wno-gnu-designator -Wno-unused-value -Wno-typedef-redefinition
+LOCAL_CFLAGS += \
+    -Wall \
+    -Werror \
+    -Wno-unused-variable \
+    -Wno-unused-parameter \
+    -Wno-gnu-designator \
+    -Wno-unused-value \
+    -Wno-typedef-redefinition
 
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_GCOV)),true)
 LOCAL_CFLAGS += --coverage -fprofile-arcs -ftest-coverage
@@ -30,25 +37,25 @@
 LOCAL_STATIC_LIBRARIES += libprofile_rt
 endif
 
-ifneq ($(filter sdm660 sdm845 msm8998 apq8098_latv sdm710 qcs605 msmnile $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter sdm660 sdm845 msm8998 apq8098_latv sdm710 qcs605 msmnile kona $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
     LOCAL_CFLAGS += -DCAPTURE_DEVICE=7
 endif
 
 LOCAL_HEADER_LIBRARIES := libsystem_headers \
                           libhardware_headers
 LOCAL_SHARED_LIBRARIES := \
-	libcutils \
-	liblog \
-	libdl \
-	libtinyalsa
+    libcutils \
+    liblog \
+    libdl \
+    libtinyalsa
 
 LOCAL_MODULE_RELATIVE_PATH := soundfx
 LOCAL_MODULE:= libqcomvisualizer
 LOCAL_VENDOR_MODULE := true
 
 LOCAL_C_INCLUDES := \
-	external/tinyalsa/include \
-	$(call include-path-for, audio-effects)
+    external/tinyalsa/include \
+    $(call include-path-for, audio-effects)
 
 LOCAL_CFLAGS += -Wno-unused-variable
 LOCAL_CFLAGS += -Wno-sign-compare
diff --git a/visualizer/offload_visualizer.c b/visualizer/offload_visualizer.c
index 9ad8fea..f268ab8 100644
--- a/visualizer/offload_visualizer.c
+++ b/visualizer/offload_visualizer.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2013, 2019 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@
 #include <unistd.h>
 
 #include <cutils/list.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <system/thread_defs.h>
 #include <tinyalsa/asoundlib.h>
 #include <audio_effects/effect_visualizer.h>
diff --git a/voice_processing/Android.mk b/voice_processing/Android.mk
index 820684a..56a3abd 100644
--- a/voice_processing/Android.mk
+++ b/voice_processing/Android.mk
@@ -4,12 +4,19 @@
 # audio preprocessing wrapper
 include $(CLEAR_VARS)
 
-LOCAL_CFLAGS += -Wno-unused-variable -Wno-gnu-designator -Wno-unused-value -Wno-unused-function
+LOCAL_CFLAGS += \
+    -Wall \
+    -Werror \
+    -Wno-unused-variable \
+    -Wno-gnu-designator \
+    -Wno-unused-value \
+    -Wno-unused-function
 
 LOCAL_MODULE:= libqcomvoiceprocessing
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_RELATIVE_PATH := soundfx
 LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_OWNER := qti
 
 LOCAL_SRC_FILES:= \
     voice_processing.c
diff --git a/voice_processing/voice_processing.c b/voice_processing/voice_processing.c
index 32b76a5..f237108 100644
--- a/voice_processing/voice_processing.c
+++ b/voice_processing/voice_processing.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2013, 2019 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@
 #include <stdlib.h>
 #include <dlfcn.h>
 #include <stdlib.h>
-#include <cutils/log.h>
+#include <log/log.h>
 #include <cutils/list.h>
 #include <unistd.h>
 #include <hardware/audio_effect.h>