Merge "policy_hal: allow direct output only for music streams"
diff --git a/configs/msm8909/mixer_paths.xml b/configs/msm8909/mixer_paths.xml
index 13da80e..0f5b333 100644
--- a/configs/msm8909/mixer_paths.xml
+++ b/configs/msm8909/mixer_paths.xml
@@ -78,7 +78,7 @@
     <ctl name="EAR_S" value="ZERO" />
     <ctl name="HPHL" value="ZERO" />
     <ctl name="HPHR" value="ZERO" />
-    <ctl name="SPK DAC Switch" value="0" />
+    <ctl name="SPK" value="ZERO" />
     <ctl name="EAR PA Gain" value="POS_1P5_DB" />
     <ctl name="MI2S_RX Channels" value="One" />
     <ctl name="MI2S_TX Channels" value="One" />
diff --git a/configs/msm8909/mixer_paths_msm8909_pm8916.xml b/configs/msm8909/mixer_paths_msm8909_pm8916.xml
index 5dbeaa7..559a5bf 100644
--- a/configs/msm8909/mixer_paths_msm8909_pm8916.xml
+++ b/configs/msm8909/mixer_paths_msm8909_pm8916.xml
@@ -78,7 +78,7 @@
     <ctl name="EAR_S" value="ZERO" />
     <ctl name="HPHL" value="ZERO" />
     <ctl name="HPHR" value="ZERO" />
-    <ctl name="SPK DAC Switch" value="0" />
+    <ctl name="SPK" value="ZERO" />
     <ctl name="Speaker Boost" value="ENABLE" />
     <ctl name="MICBIAS CAPLESS Switch" value="0" />
     <ctl name="EAR PA Boost" value="ENABLE" />
@@ -604,7 +604,7 @@
 
     <path name="speaker">
         <ctl name="RX3 MIX1 INP1" value="RX1" />
-        <ctl name="SPK DAC Switch" value="1" />
+        <ctl name="SPK" value="Switch" />
     </path>
 
     <path name="speaker-mic">
diff --git a/configs/msm8909/mixer_paths_qrd_skuh.xml b/configs/msm8909/mixer_paths_qrd_skuh.xml
index 067d316..d3b232c 100644
--- a/configs/msm8909/mixer_paths_qrd_skuh.xml
+++ b/configs/msm8909/mixer_paths_qrd_skuh.xml
@@ -80,7 +80,7 @@
     <ctl name="EAR_S Switch" value="0" />
     <ctl name="HPHL" value="ZERO" />
     <ctl name="HPHR" value="ZERO" />
-    <ctl name="SPK DAC Switch" value="0" />
+    <ctl name="SPK" value="ZERO" />
     <ctl name="Speaker Boost" value="DISABLE" />
     <ctl name="EAR PA Boost" value="DISABLE" />
     <ctl name="EAR PA Gain" value="POS_6_DB" />
@@ -589,7 +589,7 @@
 
     <path name="speaker">
         <ctl name="RX3 MIX1 INP1" value="RX1" />
-        <ctl name="SPK DAC Switch" value="1" />
+        <ctl name="SPK" value="Switch" />
         <ctl name="Speaker Boost" value="ENABLE" />
     </path>
 
diff --git a/configs/msm8909/mixer_paths_qrd_skui.xml b/configs/msm8909/mixer_paths_qrd_skui.xml
index 067d316..d3b232c 100644
--- a/configs/msm8909/mixer_paths_qrd_skui.xml
+++ b/configs/msm8909/mixer_paths_qrd_skui.xml
@@ -80,7 +80,7 @@
     <ctl name="EAR_S Switch" value="0" />
     <ctl name="HPHL" value="ZERO" />
     <ctl name="HPHR" value="ZERO" />
-    <ctl name="SPK DAC Switch" value="0" />
+    <ctl name="SPK" value="ZERO" />
     <ctl name="Speaker Boost" value="DISABLE" />
     <ctl name="EAR PA Boost" value="DISABLE" />
     <ctl name="EAR PA Gain" value="POS_6_DB" />
@@ -589,7 +589,7 @@
 
     <path name="speaker">
         <ctl name="RX3 MIX1 INP1" value="RX1" />
-        <ctl name="SPK DAC Switch" value="1" />
+        <ctl name="SPK" value="Switch" />
         <ctl name="Speaker Boost" value="ENABLE" />
     </path>
 
diff --git a/configs/msm8909/mixer_paths_qrd_skut.xml b/configs/msm8909/mixer_paths_qrd_skut.xml
index 45c4581..60c79b7 100644
--- a/configs/msm8909/mixer_paths_qrd_skut.xml
+++ b/configs/msm8909/mixer_paths_qrd_skut.xml
@@ -80,7 +80,7 @@
     <ctl name="EAR_S" value="ZERO" />
     <ctl name="HPHL" value="ZERO" />
     <ctl name="HPHR" value="ZERO" />
-    <ctl name="SPK DAC Switch" value="0" />
+    <ctl name="SPK" value="ZERO" />
     <ctl name="EAR PA Gain" value="POS_1P5_DB" />
     <ctl name="MI2S_RX Channels" value="One" />
     <ctl name="MI2S_TX Channels" value="One" />
@@ -603,7 +603,7 @@
 
     <path name="speaker">
         <ctl name="RX3 MIX1 INP1" value="RX1" />
-        <ctl name="SPK DAC Switch" value="1" />
+        <ctl name="SPK" value="Switch" />
     </path>
 
     <path name="speaker-mic">
diff --git a/configs/msm8909/mixer_paths_skua.xml b/configs/msm8909/mixer_paths_skua.xml
index 0ed2211..33efc0b 100644
--- a/configs/msm8909/mixer_paths_skua.xml
+++ b/configs/msm8909/mixer_paths_skua.xml
@@ -80,7 +80,7 @@
     <ctl name="EAR_S" value="ZERO" />
     <ctl name="HPHL" value="ZERO" />
     <ctl name="HPHR" value="ZERO" />
-    <ctl name="SPK DAC Switch" value="0" />
+    <ctl name="SPK" value="ZERO" />
     <ctl name="EAR PA Gain" value="POS_1P5_DB" />
     <ctl name="MI2S_RX Channels" value="One" />
     <ctl name="MI2S_TX Channels" value="One" />
@@ -603,7 +603,7 @@
 
     <path name="speaker">
         <ctl name="RX3 MIX1 INP1" value="RX1" />
-        <ctl name="SPK DAC Switch" value="1" />
+        <ctl name="SPK" value="Switch" />
     </path>
 
     <path name="speaker-mic">
diff --git a/configs/msm8909/mixer_paths_skuc.xml b/configs/msm8909/mixer_paths_skuc.xml
index e35788b..1bdb050 100644
--- a/configs/msm8909/mixer_paths_skuc.xml
+++ b/configs/msm8909/mixer_paths_skuc.xml
@@ -80,7 +80,7 @@
     <ctl name="EAR_S" value="ZERO" />
     <ctl name="HPHL" value="ZERO" />
     <ctl name="HPHR" value="ZERO" />
-    <ctl name="SPK DAC Switch" value="0" />
+    <ctl name="SPK" value="ZERO" />
     <ctl name="EAR PA Gain" value="POS_1P5_DB" />
     <ctl name="MI2S_RX Channels" value="One" />
     <ctl name="MI2S_TX Channels" value="One" />
@@ -603,7 +603,7 @@
 
     <path name="speaker">
         <ctl name="RX3 MIX1 INP1" value="RX1" />
-        <ctl name="SPK DAC Switch" value="1" />
+        <ctl name="SPK" value="Switch" />
     </path>
 
     <path name="speaker-mic">
diff --git a/configs/msm8909/mixer_paths_skue.xml b/configs/msm8909/mixer_paths_skue.xml
index 86c47ae..e35ddef 100644
--- a/configs/msm8909/mixer_paths_skue.xml
+++ b/configs/msm8909/mixer_paths_skue.xml
@@ -80,7 +80,7 @@
     <ctl name="EAR_S" value="ZERO" />
     <ctl name="HPHL" value="ZERO" />
     <ctl name="HPHR" value="ZERO" />
-    <ctl name="SPK DAC Switch" value="0" />
+    <ctl name="SPK" value="ZERO" />
     <ctl name="MICBIAS CAPLESS Switch" value="0" />
     <ctl name="EAR PA Gain" value="POS_1P5_DB" />
     <ctl name="MI2S_RX Channels" value="One" />
@@ -604,7 +604,7 @@
 
     <path name="speaker">
         <ctl name="RX3 MIX1 INP1" value="RX1" />
-        <ctl name="SPK DAC Switch" value="1" />
+        <ctl name="SPK" value="Switch" />
     </path>
 
     <path name="speaker-mic">
diff --git a/configs/msm8909/msm8909.mk b/configs/msm8909/msm8909.mk
index cfd71ef..3405db7 100755
--- a/configs/msm8909/msm8909.mk
+++ b/configs/msm8909/msm8909.mk
@@ -32,6 +32,7 @@
 AUDIO_FEATURE_ENABLED_MULTI_VOICE_SESSIONS := true
 AUDIO_FEATURE_ENABLED_KPI_OPTIMIZE := true
 AUDIO_FEATURE_ENABLED_ACDB_LICENSE := true
+AUDIO_FEATURE_ENABLED_DYNAMIC_LOG := true
 MM_AUDIO_ENABLED_FTM := true
 TARGET_USES_QCOM_MM_AUDIO := true
 
@@ -47,11 +48,10 @@
     device/qcom/common/media/audio_policy.conf:system/etc/audio_policy.conf
 else
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msm8909/audio_policy.conf:system/etc/audio_policy.conf
+    hardware/qcom/audio/configs/msm8909/audio_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy.conf
 endif
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msm8909/audio_policy.conf:system/etc/audio_policy.conf \
-    hardware/qcom/audio/configs/msm8909/audio_effects.conf:system/vendor/etc/audio_effects.conf \
+    hardware/qcom/audio/configs/msm8909/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
     hardware/qcom/audio/configs/msm8909/mixer_paths_qrd_skuh.xml:system/etc/mixer_paths_qrd_skuh.xml \
     hardware/qcom/audio/configs/msm8909/mixer_paths_qrd_skui.xml:system/etc/mixer_paths_qrd_skui.xml \
     hardware/qcom/audio/configs/msm8909/mixer_paths.xml:system/etc/mixer_paths.xml \
diff --git a/configs/msm8937/msm8937.mk b/configs/msm8937/msm8937.mk
index d2aab65..4b26d6c 100644
--- a/configs/msm8937/msm8937.mk
+++ b/configs/msm8937/msm8937.mk
@@ -55,6 +55,7 @@
 TARGET_USES_QCOM_MM_AUDIO := true
 AUDIO_FEATURE_ENABLED_SOURCE_TRACKING := true
 BOARD_SUPPORTS_QAHW := true
+AUDIO_FEATURE_ENABLED_DYNAMIC_LOG := true
 ##AUDIO_FEATURE_FLAGS
 
 #Audio Specific device overlays
diff --git a/configs/msm8953/msm8953.mk b/configs/msm8953/msm8953.mk
index cd1b62e..1adc471 100644
--- a/configs/msm8953/msm8953.mk
+++ b/configs/msm8953/msm8953.mk
@@ -55,6 +55,7 @@
 TARGET_USES_QCOM_MM_AUDIO := true
 AUDIO_FEATURE_ENABLED_SOURCE_TRACKING := true
 BOARD_SUPPORTS_QAHW := true
+AUDIO_FEATURE_ENABLED_DYNAMIC_LOG := true
 ##AUDIO_FEATURE_FLAGS
 
 #Audio Specific device overlays
diff --git a/configs/msm8996/msm8996.mk b/configs/msm8996/msm8996.mk
index 7591168..7f8d6ec 100644
--- a/configs/msm8996/msm8996.mk
+++ b/configs/msm8996/msm8996.mk
@@ -54,6 +54,7 @@
 AUDIO_FEATURE_ENABLED_SOURCE_TRACKING := true
 AUDIO_FEATURE_ENABLED_GEF_SUPPORT := true
 BOARD_SUPPORTS_QAHW := true
+AUDIO_FEATURE_ENABLED_DYNAMIC_LOG := true
 ##AUDIO_FEATURE_FLAGS
 
 #Audio Specific device overlays
diff --git a/configs/msm8998/mixer_paths_tavil.xml b/configs/msm8998/mixer_paths_tavil.xml
index 47f6fd1..27ef9b3 100644
--- a/configs/msm8998/mixer_paths_tavil.xml
+++ b/configs/msm8998/mixer_paths_tavil.xml
@@ -2465,6 +2465,31 @@
         <path name="unprocessed-handset-mic" />
     </path>
 
+    <!-- USB TTY start -->
+
+    <!-- full: both end tty -->
+    <path name="voice-tty-full-usb">
+        <ctl name="TTY Mode" value="FULL" />
+        <path name="usb-headphones" />
+    </path>
+
+    <path name="voice-tty-full-usb-mic">
+        <path name="usb-headset-mic" />
+    </path>
+
+    <!-- vco, in: handset mic use existing, out: tty -->
+    <path name="voice-tty-vco-usb">
+        <ctl name="TTY Mode" value="VCO" />
+        <path name="usb-headphones" />
+    </path>
+
+    <!-- hco, in: tty, out: speaker, use existing handset -->
+    <path name="voice-tty-hco-usb-mic">
+        <path name="voice-tty-full-usb-mic" />
+    </path>
+
+    <!-- USB TTY end   -->
+
     <!-- Added for ADSP testfwk -->
     <path name="ADSP testfwk">
         <ctl name="SLIMBUS_DL_HL Switch" value="1" />
diff --git a/configs/msm8998/msm8998.mk b/configs/msm8998/msm8998.mk
index 90dfc0f..524582a 100644
--- a/configs/msm8998/msm8998.mk
+++ b/configs/msm8998/msm8998.mk
@@ -29,7 +29,7 @@
 AUDIO_FEATURE_ENABLED_HW_ACCELERATED_EFFECTS := false
 AUDIO_FEATURE_ENABLED_AUDIOSPHERE := true
 AUDIO_FEATURE_ENABLED_USB_TUNNEL_AUDIO := true
-AUDIO_FEATURE_ENABLED_SPLIT_A2DP := false
+AUDIO_FEATURE_ENABLED_SPLIT_A2DP := true
 AUDIO_FEATURE_ENABLED_3D_AUDIO := false
 AUDIO_FEATURE_ENABLED_VOICE_PRINT := false
 USE_LEGACY_AUDIO_DAEMON := false
@@ -62,6 +62,7 @@
 AUDIO_FEATURE_ENABLED_GEF_SUPPORT := true
 BOARD_SUPPORTS_QAHW := true
 AUDIO_FEATURE_ENABLED_RAS := true
+AUDIO_FEATURE_ENABLED_DYNAMIC_LOG := true
 ##AUDIO_FEATURE_FLAGS
 
 #Audio Specific device overlays
@@ -79,22 +80,22 @@
 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:system/etc/mixer_paths.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths_tasha.xml:system/etc/mixer_paths_tasha.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths_tavil.xml:system/etc/mixer_paths_tavil.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths_skuk.xml:system/etc/mixer_paths_skuk.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths_skuk.xml:system/etc/mixer_paths_qvr.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths_dtp.xml:system/etc/mixer_paths_dtp.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths_i2s.xml:system/etc/mixer_paths_i2s.xml \
-    hardware/qcom/audio/configs/msm8998/audio_tuning_mixer.txt:system/etc/audio_tuning_mixer.txt \
-    hardware/qcom/audio/configs/msm8998/audio_tuning_mixer_tavil.txt:system/etc/audio_tuning_mixer_tavil.txt \
-    hardware/qcom/audio/configs/msm8998/audio_platform_info_i2s.xml:system/etc/audio_platform_info_i2s.xml \
-    hardware/qcom/audio/configs/msm8998/sound_trigger_mixer_paths.xml:system/etc/sound_trigger_mixer_paths.xml \
-    hardware/qcom/audio/configs/msm8998/sound_trigger_mixer_paths_wcd9330.xml:system/etc/sound_trigger_mixer_paths_wcd9330.xml \
-    hardware/qcom/audio/configs/msm8998/sound_trigger_mixer_paths_wcd9340.xml:system/etc/sound_trigger_mixer_paths_wcd9340.xml \
-    hardware/qcom/audio/configs/msm8998/sound_trigger_platform_info.xml:system/etc/sound_trigger_platform_info.xml \
-    hardware/qcom/audio/configs/msm8998/graphite_ipc_platform_info.xml:system/etc/graphite_ipc_platform_info.xml \
-    hardware/qcom/audio/configs/msm8998/audio_platform_info.xml:system/etc/audio_platform_info.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
 
 #XML Audio configuration files
 ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
@@ -115,7 +116,7 @@
 
 # Listen configuration file
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msm8998/listen_platform_info.xml:system/etc/listen_platform_info.xml
+    hardware/qcom/audio/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 += \
diff --git a/configs/sdm660/mixer_paths_skush.xml b/configs/sdm660/mixer_paths_skush.xml
index 546a9c4..df864b8 100644
--- a/configs/sdm660/mixer_paths_skush.xml
+++ b/configs/sdm660/mixer_paths_skush.xml
@@ -297,7 +297,7 @@
     <ctl name="HPHL Volume" value="9" />
     <ctl name="HPHR Volume" value="9" />
     <ctl name="EAR PA Gain" value="POS_1P5_DB" />
-    <ctl name="EAR PA Boost" value="ENABLE" />
+    <ctl name="EAR PA Boost" value="DISABLE" />
 
     <ctl name="RX1 Digital Volume" value="84" />
     <ctl name="RX2 Digital Volume" value="84" />
@@ -1790,7 +1790,7 @@
 
     <path name="handset">
         <ctl name="INT0_MI2S_RX Channels" value="One" />
-        <ctl name="EAR PA Boost" value="ENABLE" />
+        <ctl name="EAR PA Boost" value="DISABLE" />
 	<ctl name="RX1 MIX1 INP1" value="RX1" />
 	<ctl name="RDAC2 MUX" value="RX1" />
 	<ctl name="EAR_S" value="Switch" />
diff --git a/configs/sdm660/sdm660.mk b/configs/sdm660/sdm660.mk
index c0bbd86..62fe5c8 100644
--- a/configs/sdm660/sdm660.mk
+++ b/configs/sdm660/sdm660.mk
@@ -29,7 +29,7 @@
 AUDIO_FEATURE_ENABLED_HW_ACCELERATED_EFFECTS := false
 AUDIO_FEATURE_ENABLED_AUDIOSPHERE := true
 AUDIO_FEATURE_ENABLED_USB_TUNNEL_AUDIO := true
-AUDIO_FEATURE_ENABLED_SPLIT_A2DP := false
+AUDIO_FEATURE_ENABLED_SPLIT_A2DP := true
 AUDIO_FEATURE_ENABLED_3D_AUDIO := false
 AUDIO_FEATURE_ENABLED_VOICE_PRINT := false
 USE_LEGACY_AUDIO_DAEMON := false
@@ -79,26 +79,26 @@
 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/mixer_paths.xml:system/etc/mixer_paths.xml \
-    hardware/qcom/audio/configs/sdm660/mixer_paths_mtp.xml:system/etc/mixer_paths_mtp.xml \
-    hardware/qcom/audio/configs/sdm660/mixer_paths_wcd9335.xml:system/etc/mixer_paths_wcd9335.xml \
-    hardware/qcom/audio/configs/sdm660/mixer_paths_wcd9340.xml:system/etc/mixer_paths_wcd9340.xml \
-    hardware/qcom/audio/configs/sdm660/mixer_paths_wcd9326.xml:system/etc/mixer_paths_wcd9326.xml \
-    hardware/qcom/audio/configs/sdm660/mixer_paths_skus.xml:system/etc/mixer_paths_skus.xml \
-    hardware/qcom/audio/configs/sdm660/mixer_paths_skush.xml:system/etc/mixer_paths_skush.xml \
-    hardware/qcom/audio/configs/sdm660/mixer_paths_i2s.xml:system/etc/mixer_paths_i2s.xml \
-    hardware/qcom/audio/configs/sdm660/audio_tuning_mixer.txt:system/etc/audio_tuning_mixer.txt \
-    hardware/qcom/audio/configs/sdm660/audio_tuning_mixer_tavil.txt:system/etc/audio_tuning_mixer_tavil.txt \
-    hardware/qcom/audio/configs/sdm660/audio_tuning_mixer_tasha.txt:system/etc/audio_tuning_mixer_tasha.txt \
-    hardware/qcom/audio/configs/sdm660/audio_platform_info_extcodec.xml:system/etc/audio_platform_info_extcodec.xml \
-    hardware/qcom/audio/configs/sdm660/audio_platform_info.xml:system/etc/audio_platform_info.xml \
-    hardware/qcom/audio/configs/sdm660/audio_platform_info_skush.xml:system/etc/audio_platform_info_skush.xml \
-    hardware/qcom/audio/configs/sdm660/sound_trigger_mixer_paths.xml:system/etc/sound_trigger_mixer_paths.xml \
-    hardware/qcom/audio/configs/sdm660/sound_trigger_mixer_paths_wcd9330.xml:system/etc/sound_trigger_mixer_paths_wcd9330.xml \
-    hardware/qcom/audio/configs/sdm660/sound_trigger_mixer_paths_wcd9335.xml:system/etc/sound_trigger_mixer_paths_wcd9335.xml \
-    hardware/qcom/audio/configs/sdm660/sound_trigger_mixer_paths_wcd9340.xml:system/etc/sound_trigger_mixer_paths_wcd9340.xml \
-    hardware/qcom/audio/configs/sdm660/sound_trigger_platform_info.xml:system/etc/sound_trigger_platform_info.xml \
-    hardware/qcom/audio/configs/sdm660/graphite_ipc_platform_info.xml:system/etc/graphite_ipc_platform_info.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
 
 #XML Audio configuration files
 ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
@@ -119,7 +119,7 @@
 
 # Listen configuration file
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/sdm660/listen_platform_info.xml:system/etc/listen_platform_info.xml
+    hardware/qcom/audio/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 += \
diff --git a/configs/sdm660/sound_trigger_mixer_paths_wcd9335.xml b/configs/sdm660/sound_trigger_mixer_paths_wcd9335.xml
index 0b381cf..691b2e3 100644
--- a/configs/sdm660/sound_trigger_mixer_paths_wcd9335.xml
+++ b/configs/sdm660/sound_trigger_mixer_paths_wcd9335.xml
@@ -103,7 +103,7 @@
         <ctl name="MADONOFF Switch" value="1" />
         <ctl name="TX13 INP MUX" value="CPE_TX_PP" />
         <ctl name="AIF4_MAD Mixer SLIM TX13" value="1" />
-        <ctl name="MAD Input" value="DMIC0" />
+        <ctl name="MAD Input" value="DMIC2" />
         <ctl name="CPE AFE MAD Enable" value="1"/>
     </path>
 
@@ -111,14 +111,14 @@
         <ctl name="CLK MODE" value="INTERNAL" />
         <ctl name="EC BUF MUX INP" value="DEC1" />
         <ctl name="ADC MUX1" value="DMIC" />
-        <ctl name="DMIC MUX1" value="DMIC0" />
+        <ctl name="DMIC MUX1" value="DMIC2" />
     </path>
 
     <!-- path name used for low bandwidth FTRT codec interface -->
     <path name="listen-cpe-handset-mic low-speed-intf">
         <ctl name="MADONOFF Switch" value="1" />
         <ctl name="AIF4_MAD Mixer SLIM TX12" value="1" />
-        <ctl name="MAD Input" value="DMIC0" />
+        <ctl name="MAD Input" value="DMIC2" />
         <ctl name="CPE AFE MAD Enable" value="1"/>
     </path>
 
@@ -126,7 +126,7 @@
         <ctl name="MAD_BROADCAST Switch" value="1" />
         <ctl name="TX13 INP MUX" value="MAD_BRDCST" />
         <ctl name="AIF4_MAD Mixer SLIM TX13" value="1" />
-        <ctl name="MAD Input" value="DMIC0" />
+        <ctl name="MAD Input" value="DMIC2" />
     </path>
 
 </mixer>
diff --git a/configs/sdm660/sound_trigger_mixer_paths_wcd9340.xml b/configs/sdm660/sound_trigger_mixer_paths_wcd9340.xml
index 545f46b..f328bd6 100644
--- a/configs/sdm660/sound_trigger_mixer_paths_wcd9340.xml
+++ b/configs/sdm660/sound_trigger_mixer_paths_wcd9340.xml
@@ -171,7 +171,7 @@
     </path>
 
     <path name="listen-cpe-handset-mic">
-        <ctl name="MAD Input" value="DMIC0" />
+        <ctl name="MAD Input" value="DMIC2" />
         <ctl name="MAD_SEL MUX" value="SPE" />
         <ctl name="MAD_INP MUX" value="MAD" />
         <ctl name="MAD_CPE1 Switch" value="1" />
@@ -181,19 +181,19 @@
         <ctl name="CLK MODE" value="INTERNAL" />
         <ctl name="EC BUF MUX INP" value="DEC1" />
         <ctl name="ADC MUX1" value="DMIC" />
-        <ctl name="DMIC MUX1" value="DMIC0" />
+        <ctl name="DMIC MUX1" value="DMIC2" />
     </path>
 
     <!-- path name used for low bandwidth FTRT codec interface -->
     <path name="listen-cpe-handset-mic low-speed-intf">
         <ctl name="MADONOFF Switch" value="1" />
         <ctl name="AIF4_MAD Mixer SLIM TX12" value="1" />
-        <ctl name="MAD Input" value="DMIC0" />
+        <ctl name="MAD Input" value="DMIC2" />
         <ctl name="CPE AFE MAD Enable" value="1"/>
     </path>
 
     <path name="listen-ape-handset-mic">
-        <ctl name="MAD Input" value="DMIC0" />
+        <ctl name="MAD Input" value="DMIC2" />
         <ctl name="MAD_SEL MUX" value="MSM" />
         <ctl name="MAD_INP MUX" value="MAD" />
         <ctl name="MAD_BROADCAST Switch" value="1" />
diff --git a/configs/sdm845/mixer_paths_tavil.xml b/configs/sdm845/mixer_paths_tavil.xml
index fbe3976..18a9073 100644
--- a/configs/sdm845/mixer_paths_tavil.xml
+++ b/configs/sdm845/mixer_paths_tavil.xml
@@ -2234,6 +2234,31 @@
         <path name="unprocessed-handset-mic" />
     </path>
 
+    <!-- USB TTY start -->
+
+    <!-- full: both end tty -->
+    <path name="voice-tty-full-usb">
+        <ctl name="TTY Mode" value="FULL" />
+        <path name="usb-headphones" />
+    </path>
+
+    <path name="voice-tty-full-usb-mic">
+        <path name="usb-headset-mic" />
+    </path>
+
+    <!-- vco, in: handset mic use existing, out: tty -->
+    <path name="voice-tty-vco-usb">
+        <ctl name="TTY Mode" value="VCO" />
+        <path name="usb-headphones" />
+    </path>
+
+    <!-- hco, in: tty, out: speaker, use existing handset -->
+    <path name="voice-tty-hco-usb-mic">
+        <path name="voice-tty-full-usb-mic" />
+    </path>
+
+    <!-- USB TTY end   -->
+
     <!-- Added for ADSP testfwk -->
     <path name="ADSP testfwk">
         <ctl name="SLIMBUS_DL_HL Switch" value="1" />
diff --git a/configs/sdm845/sdm845.mk b/configs/sdm845/sdm845.mk
index d69a6fd..19802b4 100644
--- a/configs/sdm845/sdm845.mk
+++ b/configs/sdm845/sdm845.mk
@@ -29,7 +29,7 @@
 AUDIO_FEATURE_ENABLED_HW_ACCELERATED_EFFECTS := false
 AUDIO_FEATURE_ENABLED_AUDIOSPHERE := true
 AUDIO_FEATURE_ENABLED_USB_TUNNEL_AUDIO := true
-AUDIO_FEATURE_ENABLED_SPLIT_A2DP := false
+AUDIO_FEATURE_ENABLED_SPLIT_A2DP := true
 AUDIO_FEATURE_ENABLED_3D_AUDIO := false
 DOLBY_ENABLE := false
 endif
@@ -76,15 +76,15 @@
 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/mixer_paths_tavil.xml:system/etc/mixer_paths_tavil.xml \
-    hardware/qcom/audio/configs/msm8998/mixer_paths_skuk.xml:system/etc/mixer_paths_skuk.xml \
-    hardware/qcom/audio/configs/sdm845/mixer_paths_i2s.xml:system/etc/mixer_paths_i2s.xml \
-    hardware/qcom/audio/configs/sdm845/aanc_tuning_mixer_tavil.txt:system/etc/aanc_tuning_mixer_tavil.txt \
-    hardware/qcom/audio/configs/sdm845/audio_platform_info_i2s.xml:system/etc/audio_platform_info_i2s.xml \
-    hardware/qcom/audio/configs/sdm845/sound_trigger_mixer_paths_wcd9340.xml:system/etc/sound_trigger_mixer_paths_wcd9340.xml \
-    hardware/qcom/audio/configs/sdm845/sound_trigger_platform_info.xml:system/etc/sound_trigger_platform_info.xml \
-    hardware/qcom/audio/configs/sdm845/graphite_ipc_platform_info.xml:system/etc/graphite_ipc_platform_info.xml \
-    hardware/qcom/audio/configs/sdm845/audio_platform_info.xml:system/etc/audio_platform_info.xml
+    hardware/qcom/audio/configs/sdm845/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/sdm845/mixer_paths_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_i2s.xml \
+    hardware/qcom/audio/configs/sdm845/aanc_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/aanc_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
 
 #XML Audio configuration files
 ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
@@ -105,7 +105,7 @@
 
 # Listen configuration file
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/sdm845/listen_platform_info.xml:system/etc/listen_platform_info.xml
+    hardware/qcom/audio/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 += \
diff --git a/configure.ac b/configure.ac
index 6695b7e..6302ea9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -108,6 +108,8 @@
 AM_CONDITIONAL([GEF], [test x$AUDIO_FEATURE_ENABLED_GEF_SUPPORT = xtrue])
 AM_CONDITIONAL([APTX_DECODER], [test x$AUDIO_FEATURE_ENABLED_APTX_DECODER = xtrue])
 AM_CONDITIONAL([ADSP_HDLR], [test x$AUDIO_FEATURE_ADSP_HDLR_ENABLED = xtrue])
+AM_CONDITIONAL([AUDIO_IP_HDLR], [test x$AUDIO_FEATURE_IP_HDLR_ENABLED = xtrue])
+AM_CONDITIONAL([SPLIT_A2DP], [test x$AUDIO_FEATURE_ENABLED_SPLIT_A2DP = xtrue])
 
 AC_CONFIG_FILES([ \
         Makefile \
diff --git a/hal/Android.mk b/hal/Android.mk
index 9a8d27c..c79cf1b 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -54,7 +54,8 @@
 	audio_hw.c \
 	voice.c \
 	platform_info.c \
-	$(AUDIO_PLATFORM)/platform.c
+	$(AUDIO_PLATFORM)/platform.c \
+        acdb.c
 
 LOCAL_SRC_FILES += audio_extn/audio_extn.c \
                    audio_extn/utils.c
@@ -351,6 +352,17 @@
     LOCAL_SRC_FILES += audio_extn/adsp_hdlr.c
 endif
 
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DYNAMIC_LOG)), true)
+    LOCAL_CFLAGS += -DDYNAMIC_LOG_ENABLED
+    LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/audio-log-utils
+    LOCAL_SHARED_LIBRARIES += libaudio_log_utils
+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
+
 LOCAL_CFLAGS += -Wall -Werror
 
 LOCAL_COPY_HEADERS_TO   := mm-audio
@@ -363,10 +375,14 @@
 
 LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM)
 
+LOCAL_MODULE_OWNER := qti
+
 LOCAL_MODULE_RELATIVE_PATH := hw
 
 LOCAL_MODULE_TAGS := optional
 
+LOCAL_PROPRIETARY_MODULE := true
+
 include $(BUILD_SHARED_LIBRARY)
 
 endif
diff --git a/hal/Makefile.am b/hal/Makefile.am
index cbce291..cb01e79 100644
--- a/hal/Makefile.am
+++ b/hal/Makefile.am
@@ -11,7 +11,8 @@
             platform_info.c \
             ${TARGET_PLATFORM}/platform.c \
             audio_extn/audio_extn.c \
-            audio_extn/utils.c
+            audio_extn/utils.c \
+            acdb.c
 
 if HDMI_EDID
 AM_CFLAGS += -DHDMI_EDID
@@ -161,6 +162,16 @@
 c_sources += audio_extn/adsp_hdlr.c
 endif
 
+if SPLIT_A2DP
+AM_CFLAGS += -DSPLIT_A2DP_ENABLED
+c_sources += audio_extn/a2dp.c
+endif
+
+if AUDIO_IP_HDLR
+AM_CFLAGS += -DAUDIO_EXTN_IP_HDLR_ENABLED
+c_sources += audio_extn/ip_hdlr_intf.c
+endif
+
 h_sources = audio_extn/audio_defs.h \
             audio_extn/audio_extn.h \
             audio_hw.h \
diff --git a/hal/acdb.c b/hal/acdb.c
new file mode 100644
index 0000000..cbb96bd
--- /dev/null
+++ b/hal/acdb.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2013 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_acdb"
+//#define LOG_NDEBUG 0
+#define LOG_NDDEBUG 0
+
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <cutils/log.h>
+#include <cutils/list.h>
+#include "acdb.h"
+#include "platform_api.h"
+
+int acdb_init(int snd_card_num)
+{
+
+    int result = -1;
+    char *cvd_version = NULL;
+
+    char *snd_card_name = NULL;
+    struct mixer *mixer = NULL;
+    struct acdb_platform_data *my_data = NULL;
+
+    if(snd_card_num < 0) {
+        ALOGE("invalid sound card number");
+        return result;
+    }
+
+    mixer = mixer_open(snd_card_num);
+    if (!mixer) {
+        ALOGE("%s: Unable to open the mixer card: %d", __func__,
+               snd_card_num);
+        goto cleanup;
+    }
+
+    my_data = calloc(1, sizeof(struct acdb_platform_data));
+    if (!my_data) {
+        ALOGE("failed to allocate acdb platform data");
+        goto cleanup;
+    }
+
+    list_init(&my_data->acdb_meta_key_list);
+
+    /* Extract META KEY LIST INFO */
+    platform_info_init(PLATFORM_INFO_XML_PATH, my_data, ACDB_EXTN);
+
+    my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
+    if (my_data->acdb_handle == NULL) {
+        ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
+        goto cleanup;
+    }
+
+    ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
+
+    my_data->acdb_init_v3 = (acdb_init_v3_t)dlsym(my_data->acdb_handle,
+                                                     "acdb_loader_init_v3");
+    if (my_data->acdb_init_v3 == NULL)
+        ALOGE("%s: dlsym error %s for acdb_loader_init_v3", __func__, dlerror());
+
+    my_data->acdb_init_v2 = (acdb_init_v2_t)dlsym(my_data->acdb_handle,
+                                                     "acdb_loader_init_v2");
+    if (my_data->acdb_init_v2 == NULL)
+        ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
+
+    my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
+                                                 "acdb_loader_init_ACDB");
+    if (my_data->acdb_init == NULL && my_data->acdb_init_v2 == NULL
+                                                 && my_data->acdb_init_v3 == NULL) {
+        ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror());
+        goto cleanup;
+    }
+
+    /* Get CVD version */
+    cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
+    if (!cvd_version) {
+        ALOGE("%s: Failed to allocate cvd version", __func__);
+        goto cleanup;
+    } else {
+        struct mixer_ctl *ctl = NULL;
+        int count = 0;
+
+        ctl = mixer_get_ctl_by_name(mixer, CVD_VERSION_MIXER_CTL);
+        if (!ctl) {
+            ALOGE("%s: Could not get ctl for mixer cmd - %s",  __func__, CVD_VERSION_MIXER_CTL);
+            goto cleanup;
+        }
+        mixer_ctl_update(ctl);
+
+        count = mixer_ctl_get_num_values(ctl);
+        if (count > MAX_CVD_VERSION_STRING_SIZE)
+            count = MAX_CVD_VERSION_STRING_SIZE;
+
+        result = mixer_ctl_get_array(ctl, cvd_version, count);
+        if (result != 0) {
+            ALOGE("%s: ERROR! mixer_ctl_get_array() failed to get CVD Version", __func__);
+            goto cleanup;
+        }
+    }
+
+    /* Get Sound card name */
+    snd_card_name = strdup(mixer_get_name(mixer));
+    if (!snd_card_name) {
+        ALOGE("failed to allocate memory for snd_card_name");
+        result = -1;
+        goto cleanup;
+    }
+
+    int key = 0;
+    struct listnode *node = NULL;
+    struct meta_key_list *key_info = NULL;
+
+    if (my_data->acdb_init_v3) {
+        result = my_data->acdb_init_v3(snd_card_name, cvd_version,
+                                       &my_data->acdb_meta_key_list);
+    } else if (my_data->acdb_init_v2) {
+        node = list_head(&my_data->acdb_meta_key_list);
+        key_info = node_to_item(node, struct meta_key_list, list);
+        key = key_info->cal_info.nKey;
+        result = my_data->acdb_init_v2(snd_card_name, cvd_version, key);
+    } else {
+        result = my_data->acdb_init();
+    }
+
+cleanup:
+    if (NULL != my_data) {
+        if (my_data->acdb_handle)
+            dlclose(my_data->acdb_handle);
+
+        struct listnode *node;
+        struct meta_key_list *key_info;
+        list_for_each(node, &my_data->acdb_meta_key_list) {
+            key_info = node_to_item(node, struct meta_key_list, list);
+            free(key_info);
+        }
+        free(my_data);
+    }
+
+    if (mixer)
+        mixer_close(mixer);
+
+    if (cvd_version)
+        free(cvd_version);
+
+    if (snd_card_name)
+        free(snd_card_name);
+
+    return result;
+}
+
+int acdb_set_metainfo_key(void *platform, char *name, int key) {
+
+    struct meta_key_list *key_info = (struct meta_key_list *)
+                                        calloc(1, sizeof(struct meta_key_list));
+    struct acdb_platform_data *pdata = (struct acdb_platform_data *)platform;
+    if (!key_info) {
+        ALOGE("%s: Could not allocate memory for key %d", __func__, key);
+        return -ENOMEM;
+    }
+
+    key_info->cal_info.nKey = key;
+    strlcpy(key_info->name, name, sizeof(key_info->name));
+    list_add_tail(&pdata->acdb_meta_key_list, &key_info->list);
+
+    ALOGD("%s: successfully added module %s and key %d to the list", __func__,
+               key_info->name, key_info->cal_info.nKey);
+
+    return 0;
+}
diff --git a/hal/acdb.h b/hal/acdb.h
new file mode 100644
index 0000000..d1f863b
--- /dev/null
+++ b/hal/acdb.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2013 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 ACDB_H
+#define ACDB_H
+
+#include <linux/msm_audio_calibration.h>
+
+#define MAX_CVD_VERSION_STRING_SIZE 100
+#define LIB_ACDB_LOADER "libacdbloader.so"
+#define CVD_VERSION_MIXER_CTL "CVD Version"
+#define ACDB_METAINFO_KEY_MODULE_NAME_LEN 100
+
+#ifdef LINUX_ENABLED
+#define PLATFORM_INFO_XML_PATH "/etc/audio_platform_info.xml"
+#else
+#define PLATFORM_INFO_XML_PATH "/vendor/etc/audio_platform_info.xml"
+#endif
+
+/* Audio calibration related functions */
+typedef void (*acdb_deallocate_t)();
+typedef int  (*acdb_init_t)();
+typedef int  (*acdb_init_v2_t)(const char *, char *, int);
+typedef int  (*acdb_init_v3_t)(const char *, char *, struct listnode *);
+typedef void (*acdb_send_audio_cal_t)(int, int, int , int);
+typedef void (*acdb_send_audio_cal_v3_t)(int, int, int, int, int);
+typedef void (*acdb_send_voice_cal_t)(int, int);
+typedef int (*acdb_reload_vocvoltable_t)(int);
+typedef int  (*acdb_get_default_app_type_t)(void);
+typedef int (*acdb_loader_get_calibration_t)(char *attr, int size, void *data);
+typedef int (*acdb_set_audio_cal_t) (void *, void *, uint32_t);
+typedef int (*acdb_get_audio_cal_t) (void *, void *, uint32_t*);
+typedef int (*acdb_send_common_top_t) (void);
+typedef int (*acdb_set_codec_data_t) (void *, char *);
+typedef int (*acdb_reload_t) (char *, char *, char *, int);
+typedef int (*acdb_reload_v2_t) (char *, char *, char *, struct listnode *);
+typedef int (*acdb_send_gain_dep_cal_t)(int, int, int, int, int);
+
+struct meta_key_list {
+    struct listnode list;
+    struct audio_cal_info_metainfo cal_info;
+    char name[ACDB_METAINFO_KEY_MODULE_NAME_LEN];
+};
+
+struct acdb_platform_data {
+    /* Audio calibration related functions */
+    void                       *acdb_handle;
+    acdb_init_t                acdb_init;
+    acdb_init_v2_t             acdb_init_v2;
+    acdb_init_v3_t             acdb_init_v3;
+    struct listnode acdb_meta_key_list;
+};
+
+int acdb_init(int);
+
+int acdb_set_metainfo_key(void *platform, char *name, int key);
+#endif //ACDB_H
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index fba7e6c..1ffa968 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -41,6 +41,12 @@
 #include <hardware/hardware.h>
 #include <cutils/properties.h>
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_A2DP
+#include <log_utils.h>
+#endif
+
 #ifdef SPLIT_A2DP_ENABLED
 #define AUDIO_PARAMETER_A2DP_STARTED "A2dpStarted"
 #define BT_IPC_LIB_NAME  "libbthost_if.so"
@@ -69,7 +75,6 @@
 #define MIXER_ENC_FMT_APTXHD       "APTXHD"
 #define MIXER_ENC_FMT_NONE         "NONE"
 
-
 typedef int (*audio_stream_open_t)(void);
 typedef int (*audio_stream_close_t)(void);
 typedef int (*audio_start_stream_t)(void);
@@ -172,6 +177,46 @@
     uint32_t      custom_size;
 };
 
+/* TODO: Define the following structures only for O using PLATFORM_VERSION */
+/* Information about BT SBC encoder configuration
+ * This data is used between audio HAL module and
+ * BT IPC library to configure DSP encoder
+ */
+typedef struct {
+    uint32_t subband;    /* 4, 8 */
+    uint32_t blk_len;    /* 4, 8, 12, 16 */
+    uint16_t sampling_rate; /*44.1khz,48khz*/
+    uint8_t  channels;      /*0(Mono),1(Dual_mono),2(Stereo),3(JS)*/
+    uint8_t  alloc;         /*0(Loudness),1(SNR)*/
+    uint8_t  min_bitpool;   /* 2 */
+    uint8_t  max_bitpool;   /*53(44.1khz),51 (48khz) */
+    uint32_t bitrate;      /* 320kbps to 512kbps */
+} audio_sbc_encoder_config;
+
+
+/* Information about BT APTX encoder configuration
+ * This data is used between audio HAL module and
+ * BT IPC library to configure DSP encoder
+ */
+typedef struct {
+    uint16_t sampling_rate;
+    uint8_t  channels;
+    uint32_t bitrate;
+} audio_aptx_encoder_config;
+
+
+/* Information about BT AAC encoder configuration
+ * This data is used between audio HAL module and
+ * BT IPC library to configure DSP encoder
+ */
+typedef struct {
+    uint32_t enc_mode; /* LC, SBR, PS */
+    uint16_t format_flag; /* RAW, ADTS */
+    uint16_t channels; /* 1-Mono, 2-Stereo */
+    uint32_t sampling_rate;
+    uint32_t bitrate;
+} audio_aac_encoder_config;
+
 /*********** END of DSP configurable structures ********************/
 
 /* API to identify DSP encoder captabilities */
diff --git a/hal/audio_extn/adsp_hdlr.c b/hal/audio_extn/adsp_hdlr.c
index 08313a6..436da96 100644
--- a/hal/audio_extn/adsp_hdlr.c
+++ b/hal/audio_extn/adsp_hdlr.c
@@ -45,6 +45,8 @@
 #include <cutils/log.h>
 #include <cutils/sched_policy.h>
 #include <system/thread_defs.h>
+#include <sound/asound.h>
+#include <linux/msm_audio.h>
 
 #include "audio_hw.h"
 #include "audio_defs.h"
@@ -57,40 +59,29 @@
 
 #define MIXER_MAX_BYTE_LENGTH 512
 
-struct adsp_hdlr_inst {
-    bool binit;
-    struct mixer *mixer;
-};
-
-enum {
-    EVENT_CMD_EXIT,             /* event thread exit command loop*/
-    EVENT_CMD_WAIT,             /* event thread wait on mixer control */
-    EVENT_CMD_GET               /* event thread get param data from mixer */
-};
-
-struct event_cmd {
-    struct listnode list;
-    int opcode;
-};
-
-enum {
-    ADSP_HDLR_STREAM_STATE_OPENED = 0,
-    ADSP_HDLR_STREAM_STATE_EVENT_REGISTERED,
-    ADSP_HDLR_STREAM_STATE_EVENT_DEREGISTERED,
-    ADSP_HDLR_STREAM_STATE_CLOSED
-};
-
-static struct adsp_hdlr_inst *adsp_hdlr_inst = NULL;
-
-static void *event_wait_thread_loop(void *context);
-static void *event_callback_thread_loop(void *context);
-
 struct adsp_hdlr_stream_data {
     struct adsp_hdlr_stream_cfg config;
     stream_callback_t client_callback;
     void *client_cookie;
-    int state;
+};
 
+struct adsp_hdlr_event_info {
+    struct listnode list;
+    void *stream_handle;
+    char mixer_ctl_name[MIXER_PATH_MAX_LENGTH];
+    char cb_mixer_ctl_name[MIXER_PATH_MAX_LENGTH];
+    adsp_event_callback_t cb;
+    void *cookie;
+    int event_type;
+};
+
+struct adsp_hdlr_inst {
+    struct listnode event_list;
+    bool binit;
+    struct mixer *mixer;
+    pthread_mutex_t event_list_lock;
+
+    struct listnode list;
     pthread_cond_t event_wait_cond;
     pthread_t event_wait_thread;
     struct listnode event_wait_cmd_list;
@@ -104,7 +95,24 @@
     bool event_callback_thread_active;
 };
 
-static int send_cmd_event_wait_thread(struct adsp_hdlr_stream_data *stream_data, int opcode)
+enum {
+    EVENT_CMD_EXIT,             /* event thread exit command loop*/
+    EVENT_CMD_WAIT,             /* event thread wait on mixer control */
+    EVENT_CMD_GET               /* event thread get param data from mixer */
+};
+
+struct event_cmd {
+    struct listnode list;
+    int opcode;
+    char cb_mixer_ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+};
+
+static struct adsp_hdlr_inst *adsp_hdlr_inst = NULL;
+
+static void *event_wait_thread_loop(void *context);
+static void *event_callback_thread_loop(void *context);
+
+static int send_cmd_event_wait_thread(struct adsp_hdlr_inst *adsp_hdlr_inst, int opcode)
 {
     struct event_cmd *cmd = calloc(1, sizeof(*cmd));
 
@@ -117,16 +125,16 @@
 
     cmd->opcode = opcode;
 
-    pthread_mutex_lock(&stream_data->event_wait_lock);
-    list_add_tail(&stream_data->event_wait_cmd_list, &cmd->list);
-    pthread_cond_signal(&stream_data->event_wait_cond);
-    pthread_mutex_unlock(&stream_data->event_wait_lock);
+    pthread_mutex_lock(&adsp_hdlr_inst->event_wait_lock);
+    list_add_tail(&adsp_hdlr_inst->event_wait_cmd_list, &cmd->list);
+    pthread_cond_signal(&adsp_hdlr_inst->event_wait_cond);
+    pthread_mutex_unlock(&adsp_hdlr_inst->event_wait_lock);
 
     return 0;
 }
 
-static int send_cmd_event_callback_thread(struct adsp_hdlr_stream_data *stream_data,
-                                          int opcode)
+static int send_cmd_event_callback_thread(struct adsp_hdlr_inst *adsp_hdlr_inst,
+                                          int opcode, char *mixer_ctl_name)
 {
     struct event_cmd *cmd = calloc(1, sizeof(*cmd));
 
@@ -135,66 +143,68 @@
         return -ENOMEM;
     }
 
-    ALOGVV("%s %d", __func__, opcode);
+    ALOGVV("%s opcode %d, name = %s", __func__, opcode, mixer_ctl_name);
 
     cmd->opcode = opcode;
+    if (mixer_ctl_name)
+        strlcpy(cmd->cb_mixer_ctl_name, mixer_ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
 
-    pthread_mutex_lock(&stream_data->event_callback_lock);
-    list_add_tail(&stream_data->event_callback_cmd_list, &cmd->list);
-    pthread_cond_signal(&stream_data->event_callback_cond);
-    pthread_mutex_unlock(&stream_data->event_callback_lock);
+    pthread_mutex_lock(&adsp_hdlr_inst->event_callback_lock);
+    list_add_tail(&adsp_hdlr_inst->event_callback_cmd_list, &cmd->list);
+    pthread_cond_signal(&adsp_hdlr_inst->event_callback_cond);
+    pthread_mutex_unlock(&adsp_hdlr_inst->event_callback_lock);
 
     return 0;
 }
 
-static void create_event_wait_thread(struct adsp_hdlr_stream_data *stream_data)
+static void create_event_wait_thread(struct adsp_hdlr_inst *adsp_hdlr_inst)
 {
-    pthread_cond_init(&stream_data->event_wait_cond,
+    pthread_cond_init(&adsp_hdlr_inst->event_wait_cond,
                         (const pthread_condattr_t *) NULL);
-    list_init(&stream_data->event_wait_cmd_list);
-    pthread_create(&stream_data->event_wait_thread, (const pthread_attr_t *) NULL,
-                    event_wait_thread_loop, stream_data);
-    stream_data->event_wait_thread_active = true;
+    list_init(&adsp_hdlr_inst->event_wait_cmd_list);
+    pthread_create(&adsp_hdlr_inst->event_wait_thread, (const pthread_attr_t *) NULL,
+                    event_wait_thread_loop, adsp_hdlr_inst);
+    adsp_hdlr_inst->event_wait_thread_active = true;
 }
 
-static void create_event_callback_thread(struct adsp_hdlr_stream_data *stream_data)
+static void create_event_callback_thread(struct adsp_hdlr_inst *adsp_hdlr_inst)
 {
-    pthread_cond_init(&stream_data->event_callback_cond,
+    pthread_cond_init(&adsp_hdlr_inst->event_callback_cond,
                       (const pthread_condattr_t *) NULL);
-    list_init(&stream_data->event_callback_cmd_list);
-    pthread_create(&stream_data->event_callback_thread, (const pthread_attr_t *) NULL,
-                   event_callback_thread_loop, stream_data);
-    stream_data->event_callback_thread_active = true;
+    list_init(&adsp_hdlr_inst->event_callback_cmd_list);
+    pthread_create(&adsp_hdlr_inst->event_callback_thread, (const pthread_attr_t *) NULL,
+                   event_callback_thread_loop, adsp_hdlr_inst);
+    adsp_hdlr_inst->event_callback_thread_active = true;
 }
 
-static void destroy_event_wait_thread(struct adsp_hdlr_stream_data *stream_data)
+static void destroy_event_wait_thread(struct adsp_hdlr_inst *adsp_hdlr_inst)
 {
-    send_cmd_event_wait_thread(stream_data, EVENT_CMD_EXIT);
-    pthread_join(stream_data->event_wait_thread, (void **) NULL);
+    send_cmd_event_wait_thread(adsp_hdlr_inst, EVENT_CMD_EXIT);
+    pthread_join(adsp_hdlr_inst->event_wait_thread, (void **) NULL);
 
-    pthread_mutex_lock(&stream_data->event_wait_lock);
-    pthread_cond_destroy(&stream_data->event_wait_cond);
-    stream_data->event_wait_thread_active = false;
-    pthread_mutex_unlock(&stream_data->event_wait_lock);
+    pthread_mutex_lock(&adsp_hdlr_inst->event_wait_lock);
+    pthread_cond_destroy(&adsp_hdlr_inst->event_wait_cond);
+    adsp_hdlr_inst->event_wait_thread_active = false;
+    pthread_mutex_unlock(&adsp_hdlr_inst->event_wait_lock);
 }
 
-static void destroy_event_callback_thread(struct adsp_hdlr_stream_data *stream_data)
+static void destroy_event_callback_thread(struct adsp_hdlr_inst *adsp_hdlr_inst)
 {
-    send_cmd_event_callback_thread(stream_data, EVENT_CMD_EXIT);
-    pthread_join(stream_data->event_callback_thread, (void **) NULL);
+    send_cmd_event_callback_thread(adsp_hdlr_inst, EVENT_CMD_EXIT, NULL);
+    pthread_join(adsp_hdlr_inst->event_callback_thread, (void **) NULL);
 
-    pthread_mutex_lock(&stream_data->event_callback_lock);
-    pthread_cond_destroy(&stream_data->event_callback_cond);
-    stream_data->event_callback_thread_active = false;
-    pthread_mutex_unlock(&stream_data->event_callback_lock);
+    pthread_mutex_lock(&adsp_hdlr_inst->event_callback_lock);
+    pthread_cond_destroy(&adsp_hdlr_inst->event_callback_cond);
+    adsp_hdlr_inst->event_callback_thread_active = false;
+    pthread_mutex_unlock(&adsp_hdlr_inst->event_callback_lock);
 }
 
-static void destroy_event_threads(struct adsp_hdlr_stream_data *stream_data)
+static void destroy_event_threads(struct adsp_hdlr_inst *adsp_hdlr_inst)
 {
-    if (stream_data->event_wait_thread_active)
-        destroy_event_wait_thread(stream_data);
-    if (stream_data->event_callback_thread_active)
-        destroy_event_callback_thread(stream_data);
+    if (adsp_hdlr_inst->event_wait_thread_active)
+        destroy_event_wait_thread(adsp_hdlr_inst);
+    if (adsp_hdlr_inst->event_callback_thread_active)
+        destroy_event_callback_thread(adsp_hdlr_inst);
 }
 
 static void *event_wait_thread_loop(void *context)
@@ -202,53 +212,35 @@
     int ret = 0;
     int opcode = 0;
     bool wait = false;
-    struct adsp_hdlr_stream_data *stream_data =
-                        (struct adsp_hdlr_stream_data *) context;
-    struct adsp_hdlr_stream_cfg *config = &stream_data->config;
-    char mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0};
-    struct mixer_ctl *ctl = NULL;
+    struct adsp_hdlr_inst *adsp_hdlr_inst =
+                        (struct adsp_hdlr_inst *) context;
     struct event_cmd *cmd;
-    struct listnode *node;
+    struct listnode *node, *tempnode;
+    struct snd_ctl_event mixer_event = {0};
 
     setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
     set_sched_policy(0, SP_BACKGROUND);
     prctl(PR_SET_NAME, (unsigned long)"Event Wait", 0, 0, 0);
 
-    ret = snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
-            "ADSP Stream Callback Event %d", config->pcm_device_id);
-    if (ret < 0) {
-        ALOGE("%s: snprintf failed",__func__);
-        ret = -EINVAL;
-        goto done;
-    }
-
-    ctl = mixer_get_ctl_by_name(adsp_hdlr_inst->mixer, mixer_ctl_name);
-    if (!ctl) {
-        ALOGE("%s: Could not get ctl for mixer cmd - %s", __func__,
-              mixer_ctl_name);
-        ret = -EINVAL;
-        goto done;
-    }
-
     ret = mixer_subscribe_events(adsp_hdlr_inst->mixer, 1);
     if (ret < 0) {
-        ALOGE("%s: Could not subscribe for mixer cmd - %s, ret %d",
-              __func__, mixer_ctl_name, ret);
+        ALOGE("%s: Could not subscribe for mixer events, ret %d",
+              __func__, ret);
         goto done;
     }
 
-    pthread_mutex_lock(&stream_data->event_wait_lock);
+    pthread_mutex_lock(&adsp_hdlr_inst->event_wait_lock);
     while (1) {
-        if (list_empty(&stream_data->event_wait_cmd_list) && !wait) {
+        if (list_empty(&adsp_hdlr_inst->event_wait_cmd_list) && !wait) {
             ALOGVV("%s SLEEPING", __func__);
-            pthread_cond_wait(&stream_data->event_wait_cond, &stream_data->event_wait_lock);
+            pthread_cond_wait(&adsp_hdlr_inst->event_wait_cond, &adsp_hdlr_inst->event_wait_lock);
             ALOGVV("%s RUNNING", __func__);
         }
         /* execute command if available */
-        if (!list_empty(&stream_data->event_wait_cmd_list)) {
-            node = list_head(&stream_data->event_wait_cmd_list);
+        if (!list_empty(&adsp_hdlr_inst->event_wait_cmd_list)) {
+            node = list_head(&adsp_hdlr_inst->event_wait_cmd_list);
             list_remove(node);
-            pthread_mutex_unlock(&stream_data->event_wait_lock);
+            pthread_mutex_unlock(&adsp_hdlr_inst->event_wait_lock);
             cmd = node_to_item(node, struct event_cmd, list);
             opcode = cmd->opcode;
        /* wait if no command avialable */
@@ -265,30 +257,20 @@
             goto thread_exit;
         case EVENT_CMD_WAIT:
             ret = mixer_wait_event(adsp_hdlr_inst->mixer, WAIT_EVENT_POLL_TIMEOUT);
-            if (ret < 0)
-                ALOGE("%s: mixer_wait_event err! mixer %s, ret = %d",
-                      __func__, mixer_ctl_name, ret);
-            else if (ret > 0) {
-                send_cmd_event_callback_thread(stream_data, EVENT_CMD_GET);
-
-                /* Resubscribe to clear flag checked by mixer_wait_event */
-                ret = mixer_subscribe_events(adsp_hdlr_inst->mixer, 0);
-                if (ret < 0) {
-                    ALOGE("%s: Could not unsubscribe for mixer cmd - %s, ret %d",
-                          __func__, mixer_ctl_name, ret);
-                    goto done;
-                }
-                ret = mixer_subscribe_events(adsp_hdlr_inst->mixer, 1);
-                if (ret < 0) {
-                     ALOGE("%s: Could not unsubscribe for mixer cmd - %s, ret %d",
-                          __func__, mixer_ctl_name, ret);
-                    goto done;
-                }
+            ALOGVV("%s: mixer_wait_event unblocked!, ret = %d", __func__, ret);
+            if (ret < 0) {
+                ALOGE("%s: mixer_wait_event err!, ret = %d", __func__, ret);
+            } else if (ret > 0) {
+                ret = mixer_read(adsp_hdlr_inst->mixer, &mixer_event);
+                if (ret >= 0)
+                    send_cmd_event_callback_thread(adsp_hdlr_inst, EVENT_CMD_GET, mixer_event.data.elem.id.name);
+                else
+                    ALOGE("%s: mixer_read failed, ret = %d", __func__, ret);
             }
             /* Once wait command has been sent continue to wait for
                events unless something else is in the command que */
             wait = true;
-        break;
+            break;
         default:
             ALOGE("%s unknown command received: %d", __func__, opcode);
             break;
@@ -300,12 +282,18 @@
         }
     }
 thread_exit:
-    pthread_mutex_lock(&stream_data->event_wait_lock);
-    list_for_each(node, &stream_data->event_wait_cmd_list) {
+    ret = mixer_subscribe_events(adsp_hdlr_inst->mixer, 0);
+    if (ret < 0) {
+        ALOGE("%s: Could not un-subscribe for mixer events, ret %d",
+              __func__, ret);
+        goto done;
+    }
+    pthread_mutex_lock(&adsp_hdlr_inst->event_wait_lock);
+    list_for_each_safe(node, tempnode, &adsp_hdlr_inst->event_wait_cmd_list) {
         list_remove(node);
         free(node);
     }
-    pthread_mutex_unlock(&stream_data->event_wait_lock);
+    pthread_mutex_unlock(&adsp_hdlr_inst->event_wait_lock);
 done:
     return NULL;
 }
@@ -314,47 +302,32 @@
 {
     int ret = 0;
     size_t count = 0;
-    struct adsp_hdlr_stream_data *stream_data =
-                            (struct adsp_hdlr_stream_data *)context;
-    struct adsp_hdlr_stream_cfg *config = &stream_data->config;
-    char mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0};
+    struct adsp_hdlr_inst *adsp_hdlr_inst =
+                            (struct adsp_hdlr_inst *)context;
     struct mixer_ctl *ctl = NULL;
     uint8_t param[MAX_EVENT_PAYLOAD] = {0};
     struct event_cmd *cmd;
-    struct listnode *node;
+    struct listnode *node, *tempnode;
+    struct adsp_hdlr_event_info *event_info;
+    bool param_avail = false;
+    struct msm_adsp_event_data *received_evt;
 
     setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
     set_sched_policy(0, SP_BACKGROUND);
     prctl(PR_SET_NAME, (unsigned long)"Event Callback", 0, 0, 0);
 
-    ret = snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
-            "ADSP Stream Callback Event %d", config->pcm_device_id);
-    if (ret < 0) {
-        ALOGE("%s: snprintf failed",__func__);
-        ret = -EINVAL;
-        goto done;
-    }
-
-    ctl = mixer_get_ctl_by_name(adsp_hdlr_inst->mixer, mixer_ctl_name);
-    if (!ctl) {
-        ALOGE("%s: Could not get ctl for mixer cmd - %s", __func__,
-              mixer_ctl_name);
-        ret = -EINVAL;
-        goto done;
-    }
-
-    pthread_mutex_lock(&stream_data->event_callback_lock);
+    pthread_mutex_lock(&adsp_hdlr_inst->event_callback_lock);
     while (1) {
-        if (list_empty(&stream_data->event_callback_cmd_list)) {
+        if (list_empty(&adsp_hdlr_inst->event_callback_cmd_list)) {
             ALOGVV("%s SLEEPING", __func__);
-            pthread_cond_wait(&stream_data->event_callback_cond,
-                              &stream_data->event_callback_lock);
+            pthread_cond_wait(&adsp_hdlr_inst->event_callback_cond,
+                              &adsp_hdlr_inst->event_callback_lock);
             ALOGVV("%s RUNNING", __func__);
             continue;
         }
-        node = list_head(&stream_data->event_callback_cmd_list);
+        node = list_head(&adsp_hdlr_inst->event_callback_cmd_list);
         list_remove(node);
-        pthread_mutex_unlock(&stream_data->event_callback_lock);
+        pthread_mutex_unlock(&adsp_hdlr_inst->event_callback_lock);
         cmd = node_to_item(node, struct event_cmd, list);
 
         ALOGVV("%s command received: %d", __func__, cmd->opcode);
@@ -363,30 +336,60 @@
             free(cmd);
             goto thread_exit;
         case EVENT_CMD_GET:
-            mixer_ctl_update(ctl);
-
-            count = mixer_ctl_get_num_values(ctl);
-            if ((count > MAX_EVENT_PAYLOAD) || (count <= 0)) {
-                ALOGE("%s mixer - %s, count is %d",
-                      __func__, mixer_ctl_name, count);
-                break;
+            param_avail = false;
+            pthread_mutex_lock(&adsp_hdlr_inst->event_list_lock);
+            /* Find the mixer control for which event is triggered */
+            list_for_each(node, &adsp_hdlr_inst->event_list) {
+                event_info = node_to_item(node, struct adsp_hdlr_event_info, list);
+                ALOGVV("%s: cmd mixer name: %s, event list mixer name: %s", __func__,
+                       cmd->cb_mixer_ctl_name, event_info->cb_mixer_ctl_name);
+                if (!strcmp(cmd->cb_mixer_ctl_name, event_info->cb_mixer_ctl_name)) {
+                    if (!param_avail) {
+                        ctl = mixer_get_ctl_by_name(adsp_hdlr_inst->mixer, cmd->cb_mixer_ctl_name);
+                        if (!ctl) {
+                            ALOGE("%s: Could not get ctl for mixer cmd - %s", __func__,
+                                  cmd->cb_mixer_ctl_name);
+                            break;
+                        }
+                        mixer_ctl_update(ctl);
+                        count = mixer_ctl_get_num_values(ctl);
+                        if ((count > MAX_EVENT_PAYLOAD) || (count <= 0)) {
+                            ALOGE("%s: count is %d greater than allowed for %s mixer cmd",
+                                  __func__, count, cmd->cb_mixer_ctl_name);
+                            break;
+                        }
+                        ret = mixer_ctl_get_array(ctl, param, count);
+                        if (ret < 0) {
+                            ALOGE("%s: mixer_ctl_get_array failed! mixer - %s, ret = %d",
+                                  __func__, cmd->cb_mixer_ctl_name, ret);
+                            break;
+                        }
+                        param_avail = true;
+                        received_evt = (struct msm_adsp_event_data *)param;
+                        ALOGD("%s: event type = %d", __func__, received_evt->event_type);
+                    }
+                    /* Call appropriate event type client callback */
+                    if (param_avail && event_info->event_type == received_evt->event_type) {
+                        struct adsp_hdlr_stream_data *stream_data = event_info->stream_handle;
+                        if (event_info->cb != NULL) {
+                            ALOGVV("%s: calling event callback function", __func__);
+                            event_info->cb(event_info->stream_handle,
+                                           received_evt->payload,
+                                           event_info->cookie);
+                        } else if (stream_data->client_callback != NULL) {
+                            ALOGVV("%s: sending client callback event %d", __func__,
+                                   AUDIO_EXTN_STREAM_CBK_EVENT_ADSP);
+                            stream_data->client_callback((stream_callback_event_t)
+                                                         AUDIO_EXTN_STREAM_CBK_EVENT_ADSP,
+                                                         received_evt,
+                                                         stream_data->client_cookie);
+                        }
+                        break;
+                    }
+                }
             }
+            pthread_mutex_unlock(&adsp_hdlr_inst->event_list_lock);
 
-            ret = mixer_ctl_get_array(ctl, param, count);
-            if (ret < 0) {
-                ALOGE("%s: mixer_ctl_get_array failed! mixer - %s, ret = %d",
-                      __func__, mixer_ctl_name, ret);
-                break;
-            }
-
-            if (stream_data->client_callback != NULL) {
-                ALOGVV("%s: sending client callback event %d", __func__,
-                       AUDIO_EXTN_STREAM_CBK_EVENT_ADSP);
-                stream_data->client_callback((stream_callback_event_t)
-                                             AUDIO_EXTN_STREAM_CBK_EVENT_ADSP,
-                                             param,
-                                             stream_data->client_cookie);
-            }
         break;
         default:
             ALOGE("%s unknown command received: %d", __func__, cmd->opcode);
@@ -395,39 +398,101 @@
         free(cmd);
     }
 thread_exit:
-    pthread_mutex_lock(&stream_data->event_callback_lock);
-    list_for_each(node, &stream_data->event_callback_cmd_list) {
+    pthread_mutex_lock(&adsp_hdlr_inst->event_callback_lock);
+    list_for_each_safe(node, tempnode, &adsp_hdlr_inst->event_callback_cmd_list) {
         list_remove(node);
         free(node);
     }
-    pthread_mutex_unlock(&stream_data->event_callback_lock);
+    pthread_mutex_unlock(&adsp_hdlr_inst->event_callback_lock);
 done:
     return NULL;
 }
 
-static int adsp_hdlr_stream_deregister_event(
-                struct adsp_hdlr_stream_data *stream_data)
+int audio_extn_adsp_hdlr_stream_deregister_event(void *handle, void *data)
 {
-    destroy_event_threads((struct adsp_hdlr_stream_data *)stream_data);
-    stream_data->state = ADSP_HDLR_STREAM_STATE_EVENT_DEREGISTERED;
+    struct listnode *node, *tempnode;
+    struct adsp_hdlr_stream_data *stream_data = (struct adsp_hdlr_stream_data *)handle;
+    struct adsp_hdlr_event_info *event_info;
+    struct audio_adsp_event *param = (struct audio_adsp_event *)data;
+
+    if (!handle) {
+        ALOGE("%s: Invalid handle", __func__);
+        return -EINVAL;
+    }
+
+    pthread_mutex_lock(&adsp_hdlr_inst->event_list_lock);
+    if (list_empty(&adsp_hdlr_inst->event_list)) {
+        ALOGD("%s: event list is empty", __func__);
+        return 0;
+    }
+    list_for_each_safe(node, tempnode, &adsp_hdlr_inst->event_list) {
+        event_info = node_to_item(node, struct adsp_hdlr_event_info, list);
+        if (param && event_info->stream_handle == stream_data) {
+            /* if the type of event is avaliable to dereg then dereg only that event */
+            if (event_info->event_type == param->event_type) {
+                ALOGD("%s: Deregister event type = %d", __func__, event_info->event_type);
+                list_remove(node);
+                free(event_info);
+            }
+        } else if (event_info->stream_handle == stream_data) {
+            /* Dereg all the events related to that stream */
+            ALOGD("%s: Deregister all stream events", __func__);
+            list_remove(node);
+            free(event_info);
+        }
+    }
+    pthread_mutex_unlock(&adsp_hdlr_inst->event_list_lock);
+
+    if (list_empty(&adsp_hdlr_inst->event_list)) {
+        ALOGD("%s: Closing event threads", __func__);
+        destroy_event_threads(adsp_hdlr_inst);
+        pthread_mutex_destroy(&adsp_hdlr_inst->event_wait_lock);
+        pthread_mutex_destroy(&adsp_hdlr_inst->event_callback_lock);
+        pthread_mutex_destroy(&adsp_hdlr_inst->event_list_lock);
+    }
+
     return 0;
 }
 
-static int adsp_hdlr_stream_register_event(
-                struct adsp_hdlr_stream_data *stream_data,
-                struct audio_adsp_event *param)
+int audio_extn_adsp_hdlr_stream_register_event(void *handle, void *data,
+                                               adsp_event_callback_t cb,
+                                               void *cookie)
 {
     int ret = 0;
     char mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0};
+    char cb_mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0};
     struct mixer_ctl *ctl = NULL;
     uint8_t payload[AUDIO_MAX_ADSP_STREAM_CMD_PAYLOAD_LEN] = {0};
+    struct adsp_hdlr_stream_data *stream_data = (struct adsp_hdlr_stream_data *)handle;
     struct adsp_hdlr_stream_cfg *config = &stream_data->config;
+    struct adsp_hdlr_event_info *event_info;
+    struct audio_adsp_event *param = (struct audio_adsp_event *)data;
+
+    if (!param || !handle) {
+        ret = -EINVAL;
+        ALOGE("%s: Invalid input arguments", __func__);
+        goto done;
+    }
 
     /* check if param size exceeds max size supported by mixer */
     if (param->payload_length > AUDIO_MAX_ADSP_STREAM_CMD_PAYLOAD_LEN) {
         ALOGE("%s: Invalid payload_length %d",__func__, param->payload_length);
         return -EINVAL;
     }
+    ret = snprintf(cb_mixer_ctl_name, sizeof(cb_mixer_ctl_name),
+            "ADSP Stream Callback Event %d", config->pcm_device_id);
+    if (ret < 0) {
+        ALOGE("%s: snprintf failed",__func__);
+        ret = -EINVAL;
+        goto done;
+    }
+    ctl = mixer_get_ctl_by_name(adsp_hdlr_inst->mixer, cb_mixer_ctl_name);
+    if (!ctl) {
+        ALOGE("%s: Could not get ctl for mixer cmd - %s", __func__,
+              cb_mixer_ctl_name);
+        ret = -EINVAL;
+        goto done;
+    }
 
     ret = snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
             "ADSP Stream Cmd %d", config->pcm_device_id);
@@ -444,36 +509,63 @@
         ret = -EINVAL;
         goto done;
     }
+    ALOGD("%s: event = %d, payload_length %d", __func__, param->event_type, param->payload_length);
 
-    ALOGD("%s: payload_length %d",__func__, param->payload_length);
-
-    /*copy payload size and param */
-    memcpy(payload, &param->payload_length,
+    /* copy event_type, payload size and payload */
+    memcpy(payload, &param->event_type,
+                    sizeof(param->event_type));
+    memcpy(payload + sizeof(param->event_type), &param->payload_length,
                     sizeof(param->payload_length));
-    memcpy(payload + sizeof(param->payload_length),
+    memcpy(payload + sizeof(param->event_type) + sizeof(param->payload_length),
            param->payload, param->payload_length);
-    ret = mixer_ctl_set_array(ctl, payload,
-                 sizeof(param->payload_length) + param->payload_length);
+    ret = mixer_ctl_set_array(ctl, payload, (sizeof(param->event_type) +
+                               sizeof(param->payload_length) + param->payload_length));
     if (ret < 0) {
         ALOGE("%s: Could not set ctl for mixer cmd - %s, ret %d", __func__,
               mixer_ctl_name, ret);
         goto done;
     }
 
-    pthread_mutex_lock(&stream_data->event_wait_lock);
-    if (!stream_data->event_wait_thread_active)
-        create_event_wait_thread(stream_data);
-    pthread_mutex_unlock(&stream_data->event_wait_lock);
+    if (list_empty(&adsp_hdlr_inst->event_list)) {
+        pthread_mutex_init(&adsp_hdlr_inst->event_wait_lock,
+                           (const pthread_mutexattr_t *) NULL);
+        pthread_mutex_init(&adsp_hdlr_inst->event_callback_lock,
+                           (const pthread_mutexattr_t *) NULL);
+        pthread_mutex_init(&adsp_hdlr_inst->event_list_lock,
+                           (const pthread_mutexattr_t *) NULL);
 
-    pthread_mutex_lock(&stream_data->event_callback_lock);
-    if (!stream_data->event_callback_thread_active)
-        create_event_callback_thread(stream_data);
-    pthread_mutex_unlock(&stream_data->event_callback_lock);
+        /* create event threads during first event registration */
+        pthread_mutex_lock(&adsp_hdlr_inst->event_wait_lock);
+        if (!adsp_hdlr_inst->event_wait_thread_active)
+            create_event_wait_thread(adsp_hdlr_inst);
+        pthread_mutex_unlock(&adsp_hdlr_inst->event_wait_lock);
 
-    send_cmd_event_wait_thread(stream_data, EVENT_CMD_WAIT);
-    stream_data->state = ADSP_HDLR_STREAM_STATE_EVENT_REGISTERED;
+        pthread_mutex_lock(&adsp_hdlr_inst->event_callback_lock);
+        if (!adsp_hdlr_inst->event_callback_thread_active)
+            create_event_callback_thread(adsp_hdlr_inst);
+        pthread_mutex_unlock(&adsp_hdlr_inst->event_callback_lock);
+
+        send_cmd_event_wait_thread(adsp_hdlr_inst, EVENT_CMD_WAIT);
+    }
+    event_info = (struct adsp_hdlr_event_info *) calloc(1,
+                                   sizeof(struct adsp_hdlr_event_info));
+    if (event_info == NULL) {
+        ret = -ENOMEM;
+        goto done;
+    }
+    event_info->event_type = param->event_type;
+    event_info->cb = cb;
+    event_info->cookie = cookie;
+    event_info->stream_handle = stream_data;
+    strlcpy(event_info->mixer_ctl_name, mixer_ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
+    strlcpy(event_info->cb_mixer_ctl_name, cb_mixer_ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN);
+    pthread_mutex_lock(&adsp_hdlr_inst->event_list_lock);
+    list_add_tail(&adsp_hdlr_inst->event_list, &event_info->list);
+    ALOGD("%s: event_info type %d added from the list", __func__, event_info->event_type);
+    pthread_mutex_unlock(&adsp_hdlr_inst->event_list_lock);
+
 done:
-        return ret;
+    return ret;
 }
 
 int audio_extn_adsp_hdlr_stream_set_param(void *handle,
@@ -481,28 +573,21 @@
                     void *param)
 {
     int ret = 0;
-    struct adsp_hdlr_stream_data *stream_data;
 
     if (handle == NULL) {
         ALOGE("%s: Invalid handle",__func__);
         return -EINVAL;
     }
 
-    stream_data = (struct adsp_hdlr_stream_data *)handle;
     switch (cmd) {
         case ADSP_HDLR_STREAM_CMD_REGISTER_EVENT :
-            if (!param) {
-                ret = -EINVAL;
-                ALOGE("%s: Invalid handle",__func__);
-                break;
-            }
-            ret = adsp_hdlr_stream_register_event(stream_data, param);
+            ret = audio_extn_adsp_hdlr_stream_register_event(handle, param, NULL, NULL);
             if (ret)
                 ALOGE("%s:adsp_hdlr_stream_register_event failed error %d",
                        __func__, ret);
             break;
         case ADSP_HDLR_STREAM_CMD_DEREGISTER_EVENT:
-            ret = adsp_hdlr_stream_deregister_event(stream_data);
+            ret = audio_extn_adsp_hdlr_stream_deregister_event(handle, param);
             if (ret)
                 ALOGE("%s:adsp_hdlr_stream_deregister_event failed error %d",
                        __func__, ret);
@@ -546,15 +631,10 @@
         ret = -EINVAL;
     } else {
         stream_data = (struct adsp_hdlr_stream_data *)handle;
-        if (stream_data->state == ADSP_HDLR_STREAM_STATE_EVENT_REGISTERED) {
-            ret = adsp_hdlr_stream_deregister_event(stream_data);
-            if (ret)
-                ALOGE("%s:adsp_hdlr_stream_deregister_event failed error %d",
-                        __func__, ret);
-        }
-        stream_data->state = ADSP_HDLR_STREAM_STATE_CLOSED;
-        pthread_mutex_destroy(&stream_data->event_wait_lock);
-        pthread_mutex_destroy(&stream_data->event_wait_lock);
+        ret = audio_extn_adsp_hdlr_stream_deregister_event(stream_data, NULL);
+        if (ret)
+            ALOGE("%s:adsp_hdlr_stream_deregister_event failed error %d",
+                  __func__, ret);
         free(stream_data);
         stream_data = NULL;
     }
@@ -588,15 +668,9 @@
     if (stream_data == NULL) {
         ret = -ENOMEM;
     }
-
     stream_data->config = *config;
-    pthread_mutex_init(&stream_data->event_wait_lock,
-                       (const pthread_mutexattr_t *) NULL);
-    pthread_mutex_init(&stream_data->event_callback_lock,
-                       (const pthread_mutexattr_t *) NULL);
-    stream_data->state = ADSP_HDLR_STREAM_STATE_OPENED;
-
     *handle = (void **)stream_data;
+
     return ret;
 }
 
@@ -614,14 +688,15 @@
         return 0;
     }
     adsp_hdlr_inst = (struct adsp_hdlr_inst *)calloc(1,
-                                  sizeof(struct adsp_hdlr_inst *));
+                                  sizeof(struct adsp_hdlr_inst));
     if (!adsp_hdlr_inst) {
         ALOGE("%s: calloc failed for adsp_hdlr_inst", __func__);
         return -EINVAL;
     }
     adsp_hdlr_inst->mixer = mixer;
+    list_init(&adsp_hdlr_inst->event_list);
 
-   return 0;
+    return 0;
 }
 
 int audio_extn_adsp_hdlr_deinit(void)
diff --git a/hal/audio_extn/adsp_hdlr.h b/hal/audio_extn/adsp_hdlr.h
index 7499917..b265e42 100644
--- a/hal/audio_extn/adsp_hdlr.h
+++ b/hal/audio_extn/adsp_hdlr.h
@@ -42,6 +42,9 @@
 };
 
 #ifdef AUDIO_EXTN_ADSP_HDLR_ENABLED
+
+typedef int (*adsp_event_callback_t)(void *handle, void *payload, void *cookie);
+
 int audio_extn_adsp_hdlr_init(struct mixer *mixer);
 int audio_extn_adsp_hdlr_deinit(void);
 int audio_extn_adsp_hdlr_stream_open(void **handle,
@@ -53,6 +56,9 @@
 int audio_extn_adsp_hdlr_stream_set_param(void *handle,
                     adsp_hdlr_cmd_t cmd,
                     void *param);
+int audio_extn_adsp_hdlr_stream_register_event(void *handle,
+                void *param, adsp_event_callback_t cb, void *cookie);
+int audio_extn_adsp_hdlr_stream_deregister_event(void *handle, void *param);
 #else
 #define audio_extn_adsp_hdlr_init(mixer)                                     (0)
 #define audio_extn_adsp_hdlr_deinit()                                        (0)
@@ -60,6 +66,8 @@
 #define audio_extn_adsp_hdlr_stream_close(handle)                            (0)
 #define audio_extn_adsp_hdlr_stream_set_callback(handle, callback, cookie)   (0)
 #define audio_extn_adsp_hdlr_stream_set_param(handle, cmd, param)            (0)
+#define audio_extn_adsp_hdlr_stream_register_event(stream_data, param, cb)   (0)
+#define audio_extn_adsp_hdlr_stream_deregister_event(handle, param)          (0)
 #endif
 
 #endif
diff --git a/hal/audio_extn/audio_defs.h b/hal/audio_extn/audio_defs.h
index 06b4fb9..6bedc25 100644
--- a/hal/audio_extn/audio_defs.h
+++ b/hal/audio_extn/audio_defs.h
@@ -177,25 +177,50 @@
    uint64_t        start_delay; /* session start delay in microseconds*/
 };
 
+struct audio_out_enable_drift_correction {
+   bool        enable; /* enable drift correction*/
+};
+
+struct audio_out_correct_drift {
+    /*
+     * adjust time in microseconds, a positive value
+     * to advance the clock or a negative value to
+     * delay the clock.
+     */
+    int64_t        adjust_time;
+};
+
 /* type of asynchronous write callback events. Mutually exclusive
  * event enums append those defined for stream_callback_event_t in audio.h */
 typedef enum {
+    AUDIO_EXTN_STREAM_CBK_EVENT_ERROR = 0x2,  /* Remove this enum if its already in audio.h */
     AUDIO_EXTN_STREAM_CBK_EVENT_ADSP = 0x100      /* callback event from ADSP PP,
                                                  * corresponding payload will be
                                                  * sent as is to the client
                                                  */
 } audio_extn_callback_id;
 
-#define AUDIO_MAX_ADSP_STREAM_CMD_PAYLOAD_LEN 508
+#define AUDIO_MAX_ADSP_STREAM_CMD_PAYLOAD_LEN 504
+
+typedef enum {
+    AUDIO_STREAM_PP_EVENT = 0,
+    AUDIO_STREAM_ENCDEC_EVENT = 1,
+} audio_event_id;
 
 /* payload format for HAL parameter
  * AUDIO_EXTN_PARAM_ADSP_STREAM_CMD
  */
 struct audio_adsp_event {
+ audio_event_id event_type;                  /* type of the event */
  uint32_t payload_length;                    /* length in bytes of the payload */
  void    *payload;                           /* the actual payload */
 };
 
+struct audio_out_channel_map_param {
+   uint8_t       channels;                              /* Input Channels */
+   uint8_t       channel_map[AUDIO_CHANNEL_COUNT_MAX];  /* Input Channel Map */
+};
+
 typedef union {
     struct source_tracking_param st_params;
     struct sound_focus_param sf_params;
@@ -203,7 +228,10 @@
     struct audio_avt_device_drift_param drift_params;
     struct audio_out_render_window_param render_window_param;
     struct audio_out_start_delay_param start_delay;
+    struct audio_out_enable_drift_correction drift_enable_param;
+    struct audio_out_correct_drift drift_correction_param;
     struct audio_adsp_event adsp_event_params;
+    struct audio_out_channel_map_param channel_map_param;
 } audio_extn_param_payload;
 
 typedef enum {
@@ -213,7 +241,13 @@
     AUDIO_EXTN_PARAM_AVT_DEVICE_DRIFT,
     AUDIO_EXTN_PARAM_OUT_RENDER_WINDOW, /* PARAM to set render window */
     AUDIO_EXTN_PARAM_OUT_START_DELAY,
-    AUDIO_EXTN_PARAM_ADSP_STREAM_CMD
+    /* enable adsp drift correction this must be called before out_write */
+    AUDIO_EXTN_PARAM_OUT_ENABLE_DRIFT_CORRECTION,
+    /* param to set drift value to be adjusted by dsp */
+    AUDIO_EXTN_PARAM_OUT_CORRECT_DRIFT,
+    AUDIO_EXTN_PARAM_ADSP_STREAM_CMD,
+    /* param to set input channel map for playback stream */
+    AUDIO_EXTN_PARAM_OUT_CHANNEL_MAP
 } audio_extn_param_id;
 
 #endif /* AUDIO_DEFS_H */
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 4573ecc..62b661e 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -55,6 +55,12 @@
 
 #include "sound/compress_params.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_AUDIO_EXTN
+#include <log_utils.h>
+#endif
+
 #define MAX_SLEEP_RETRY 100
 #define WIFI_INIT_WAIT_SLEEP 50
 
@@ -1361,12 +1367,24 @@
             ret = audio_extn_utils_compress_set_start_delay(out,
                     (struct audio_out_start_delay_param *)(payload));
             break;
+        case AUDIO_EXTN_PARAM_OUT_ENABLE_DRIFT_CORRECTION:
+            ret = audio_extn_utils_compress_enable_drift_correction(out,
+                    (struct audio_out_enable_drift_correction *)(payload));
+            break;
+        case AUDIO_EXTN_PARAM_OUT_CORRECT_DRIFT:
+            ret = audio_extn_utils_compress_correct_drift(out,
+                    (struct audio_out_correct_drift *)(payload));
+            break;
         case AUDIO_EXTN_PARAM_ADSP_STREAM_CMD:
             ret = audio_extn_adsp_hdlr_stream_set_param(out->adsp_hdlr_stream_handle,
                     ADSP_HDLR_STREAM_CMD_REGISTER_EVENT,
                     (void *)&payload->adsp_event_params);
             break;
-         default:
+        case AUDIO_EXTN_PARAM_OUT_CHANNEL_MAP:
+            ret = audio_extn_utils_set_channel_map(out,
+                    (struct audio_out_channel_map_param *)(payload));
+            break;
+        default:
             ALOGE("%s:: unsupported param_id %d", __func__, param_id);
             break;
     }
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index bdb039f..42719f4 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -40,6 +40,7 @@
 
 #include <cutils/str_parms.h>
 #include "adsp_hdlr.h"
+#include "ip_hdlr_intf.h"
 
 #ifndef AFE_PROXY_ENABLED
 #define AUDIO_DEVICE_OUT_PROXY 0x40000
@@ -224,7 +225,7 @@
 #else
 void audio_extn_a2dp_init(void *adev);
 int audio_extn_a2dp_start_playback();
-void audio_extn_a2dp_stop_playback();
+int audio_extn_a2dp_stop_playback();
 void audio_extn_a2dp_set_parameters(struct str_parms *parms);
 bool audio_extn_a2dp_is_force_device_switch();
 void audio_extn_a2dp_set_handoff_mode(bool is_on);
@@ -473,6 +474,9 @@
     EXT_DISPLAY_TYPE_DP
 };
 
+/* Used to limit sample rate for TrueHD & EC3 */
+#define HDMI_PASSTHROUGH_MAX_SAMPLE_RATE 192000
+
 #ifndef HDMI_PASSTHROUGH_ENABLED
 #define audio_extn_passthru_update_stream_configuration(adev, out)            (0)
 #define audio_extn_passthru_is_convert_supported(adev, out)                   (0)
@@ -587,6 +591,8 @@
 void audio_extn_utils_update_stream_app_type_cfg_for_usecase(
                                   struct audio_device *adev,
                                   struct audio_usecase *usecase);
+int audio_extn_utils_get_snd_card_num();
+
 #ifdef DS2_DOLBY_DAP_ENABLED
 #define LIB_DS2_DAP_HAL "vendor/lib/libhwdaphal.so"
 #define SET_HW_INFO_FUNC "dap_hal_set_hw_info"
@@ -862,4 +868,13 @@
 int audio_extn_utils_compress_set_start_delay(
             struct stream_out *out,
             struct audio_out_start_delay_param *start_delay_param);
+int audio_extn_utils_compress_enable_drift_correction(
+            struct stream_out *out,
+            struct audio_out_enable_drift_correction *drift_enable);
+int audio_extn_utils_compress_correct_drift(
+            struct stream_out *out,
+            struct audio_out_correct_drift *drift_correction_param);
+int audio_extn_utils_set_channel_map(
+            struct stream_out *out,
+            struct audio_out_channel_map_param *channel_map_param);
 #endif /* AUDIO_EXTN_H */
diff --git a/hal/audio_extn/bt_hal.c b/hal/audio_extn/bt_hal.c
index 21baa9c..6441bef 100644
--- a/hal/audio_extn/bt_hal.c
+++ b/hal/audio_extn/bt_hal.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, 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
@@ -41,6 +41,12 @@
 #include <../../../../system/bt/audio_a2dp_hw/bthost_ipc.h>
 #include <dlfcn.h>
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_BT_HAL
+#include <log_utils.h>
+#endif
+
 #define DEFAULT_BUF_SIZE 6144
 
 #define UNUSED(x) (void)(x)
diff --git a/hal/audio_extn/compress_capture.c b/hal/audio_extn/compress_capture.c
index 47e6a9d..2d43446 100644
--- a/hal/audio_extn/compress_capture.c
+++ b/hal/audio_extn/compress_capture.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 - 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013 - 2014, 2017, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -35,6 +35,12 @@
 #include "sound/compress_params.h"
 #include "sound/compress_offload.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_COMPR_CAP
+#include <log_utils.h>
+#endif
+
 #ifdef COMPRESS_CAPTURE_ENABLED
 
 #define COMPRESS_IN_CONFIG_CHANNELS 1
diff --git a/hal/audio_extn/compress_in.c b/hal/audio_extn/compress_in.c
index 6b1f6e4..156e3bc 100644
--- a/hal/audio_extn/compress_in.c
+++ b/hal/audio_extn/compress_in.c
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2016-2017, 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
@@ -51,6 +51,11 @@
 #include "audio_defs.h"
 #include "sound/compress_params.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_COMPR_IN
+#include <log_utils.h>
+#endif
 /* default timestamp metadata definition if not defined in kernel*/
 #ifndef COMPRESSED_TIMESTAMP_FLAG
 #define COMPRESSED_TIMESTAMP_FLAG 0
diff --git a/hal/audio_extn/dev_arbi.c b/hal/audio_extn/dev_arbi.c
index 69d8568..9c5382a 100644
--- a/hal/audio_extn/dev_arbi.c
+++ b/hal/audio_extn/dev_arbi.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, 2016-2017 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
@@ -43,6 +43,12 @@
 #include <cutils/properties.h>
 #include "audio_extn.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_DEV_ARBI
+#include <log_utils.h>
+#endif
+
 #ifdef DEV_ARBI_ENABLED
 
 typedef int (init_fn_t)();
diff --git a/hal/audio_extn/dolby.c b/hal/audio_extn/dolby.c
index fee0543..a0f17be 100644
--- a/hal/audio_extn/dolby.c
+++ b/hal/audio_extn/dolby.c
@@ -34,6 +34,12 @@
 #include "sound/compress_params.h"
 #include "sound/devdep_params.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_DOLBY
+#include <log_utils.h>
+#endif
+
 #ifdef DS1_DOLBY_DDP_ENABLED
 
 #define AUDIO_PARAMETER_DDP_DEV          "ddp_device"
diff --git a/hal/audio_extn/dts_eagle.c b/hal/audio_extn/dts_eagle.c
index 71bfea6..b8de2ca 100644
--- a/hal/audio_extn/dts_eagle.c
+++ b/hal/audio_extn/dts_eagle.c
@@ -33,6 +33,12 @@
 #include "platform.h"
 #include "platform_api.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_DTS_EAGLE
+#include <log_utils.h>
+#endif
+
 #ifdef DTS_EAGLE
 
 #define AUDIO_PARAMETER_KEY_DTS_EAGLE   "DTS_EAGLE"
diff --git a/hal/audio_extn/fm.c b/hal/audio_extn/fm.c
index a28d52f..5da494d 100644
--- a/hal/audio_extn/fm.c
+++ b/hal/audio_extn/fm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -31,6 +31,12 @@
 #include <stdlib.h>
 #include <cutils/str_parms.h>
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_FM
+#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"
diff --git a/hal/audio_extn/gef.c b/hal/audio_extn/gef.c
index d5e090a..19f9dfb 100644
--- a/hal/audio_extn/gef.c
+++ b/hal/audio_extn/gef.c
@@ -47,6 +47,12 @@
 #include "audio_extn.h"
 #include "audio_hw.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_GEF
+#include <log_utils.h>
+#endif
+
 #ifdef AUDIO_GENERIC_EFFECT_FRAMEWORK_ENABLED
 
 #if LINUX_ENABLED
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index 3c1d0ef..685078b 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -39,6 +39,12 @@
 #include <stdlib.h>
 #include <cutils/str_parms.h>
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_HFP
+#include <log_utils.h>
+#endif
+
 #ifdef HFP_ENABLED
 #define AUDIO_PARAMETER_HFP_ENABLE      "hfp_enable"
 #define AUDIO_PARAMETER_HFP_SET_SAMPLING_RATE "hfp_set_sampling_rate"
diff --git a/hal/audio_extn/ip_hdlr_intf.c b/hal/audio_extn/ip_hdlr_intf.c
new file mode 100644
index 0000000..411b16f
--- /dev/null
+++ b/hal/audio_extn/ip_hdlr_intf.c
@@ -0,0 +1,394 @@
+/*
+ * Copyright (c) 2017, 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_TAG "ip_hdlr_intf"
+/*#define LOG_NDEBUG 0*/
+/*#define VERY_VERY_VERBOSE_LOGGING*/
+#ifdef VERY_VERY_VERBOSE_LOGGING
+#define ALOGVV ALOGV
+#else
+#define ALOGVV(a...) do { } while(0)
+#endif
+
+#ifdef LINUX_ENABLED
+#define LIB_PATH "/usr/lib/libaudio_ip_handler.so"
+#else
+#define LIB_PATH "/system/vendor/lib/libaudio_ip_handler.so"
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <cutils/log.h>
+#include <sound/asound.h>
+
+#include "audio_hw.h"
+#include "audio_defs.h"
+#include "platform.h"
+
+/* These values defined by ADSP */
+#define ADSP_DEC_SERVICE_ID 1
+#define ADSP_EVENT_ID_RTIC            0x00013239
+#define ADSP_EVENT_ID_RTIC_FAIL       0x0001323A
+
+struct ip_hdlr_intf {
+    void *lib_hdl;
+    int (*init)(void **handle, char *lib_path, void **lib_handle);
+    int (*deinit)(void *handle);
+    int (*open)(void *handle, bool is_dsp_decode, void *aud_sess_handle);
+    int (*shm_info)(void *handle, int *fd);
+    int (*close)(void *handle);
+    int (*event)(void *handle, void *payload);
+    int (*reg_cb)(void *handle, void *ack_cb, void *fail_cb);
+
+    int ref_cnt;
+};
+static struct ip_hdlr_intf *ip_hdlr = NULL;
+
+/* RTIC ack information */
+struct rtic_ack_info {
+    uint32_t token;
+    uint32_t status;
+};
+
+/* RTIC ack format sent to ADSP */
+struct rtic_ack_param {
+    uint32_t param_size;
+    struct rtic_ack_info rtic_ack;
+};
+
+/* each event payload format */
+struct reg_ev_pl {
+    uint32_t event_id;
+    uint32_t cfg_mask;
+};
+
+/* event registration format */
+struct reg_event {
+    uint16_t version;
+    uint16_t service_id;
+    uint32_t num_reg_events;
+    struct reg_ev_pl rtic;
+    struct reg_ev_pl rtic_fail;
+};
+
+/* event received from ADSP is in this format */
+struct rtic_event {
+    uint16_t service_id;
+    uint16_t reserved;
+    uint32_t event_id;
+    uint32_t payload_size;
+    uint8_t payload[0];
+};
+
+bool audio_extn_ip_hdlr_intf_supported(audio_format_t format)
+{
+    if ((format & AUDIO_FORMAT_MAIN_MASK == AUDIO_FORMAT_AC3) ||
+        (format & AUDIO_FORMAT_MAIN_MASK == AUDIO_FORMAT_E_AC3) ||
+        (format & AUDIO_FORMAT_MAIN_MASK == AUDIO_FORMAT_DOLBY_TRUEHD))
+        return true;
+    else
+        return false;
+}
+
+int audio_extn_ip_hdlr_intf_event(void *stream_handle, void *payload, void *ip_hdlr_handle)
+{
+    ALOGVV("%s:[%d] handle = %p",__func__, ip_hdlr->ref_cnt, ip_hdlr_handle);
+
+    return ip_hdlr->event(ip_hdlr_handle, payload);
+}
+
+int audio_extn_ip_hdlr_intf_rtic_ack(void *aud_sess_handle, struct rtic_ack_info *info)
+{
+    char mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0};
+    int ret = 0;
+    int pcm_device_id = 0;
+    struct mixer_ctl *ctl = NULL;
+    struct stream_out *out = (struct stream_out *)aud_sess_handle;
+    struct rtic_ack_param param;
+
+    pcm_device_id = platform_get_pcm_device_id(out->usecase, PCM_PLAYBACK);
+
+    ALOGVV("%s:[%d] token = %d, info->status = %d, pcm_id = %d",__func__,
+          ip_hdlr->ref_cnt, info->token, info->status, pcm_device_id);
+
+    /* set mixer control to send RTIC done information */
+    ret = snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+                   "Playback Event Ack %d", pcm_device_id);
+    if (ret < 0) {
+        ALOGE("%s:[%d] snprintf failed",__func__, ip_hdlr->ref_cnt);
+        ret = -EINVAL;
+        goto done;
+    }
+    ctl = mixer_get_ctl_by_name(out->dev->mixer, mixer_ctl_name);
+    if (!ctl) {
+        ALOGE("%s:[%d] Could not get ctl for mixer cmd - %s", __func__,
+              ip_hdlr->ref_cnt, mixer_ctl_name);
+        ret = -EINVAL;
+        goto done;
+    }
+
+    param.param_size = sizeof(struct rtic_ack_info);
+    memcpy(&param.rtic_ack, info, sizeof(struct rtic_ack_info));
+    ret = mixer_ctl_set_array(ctl, (void *)&param, sizeof(param));
+    if (ret < 0) {
+        ALOGE("%s:[%d] Could not set ctl for mixer cmd - %s, ret %d", __func__, ip_hdlr->ref_cnt,
+              mixer_ctl_name, ret);
+        goto done;
+    }
+
+done:
+    return ret;
+}
+
+/* Acquire Mutex lock on output stream */
+static void lock_output_stream(struct stream_out *out)
+{
+    pthread_mutex_lock(&out->pre_lock);
+    pthread_mutex_lock(&out->lock);
+    pthread_mutex_unlock(&out->pre_lock);
+}
+
+int audio_extn_ip_hdlr_intf_rtic_fail(void *aud_sess_handle)
+{
+    struct stream_out *out = (struct stream_out *)aud_sess_handle;
+
+    ALOGD("%s:[%d] sess_handle = %p",__func__, ip_hdlr->ref_cnt, aud_sess_handle);
+
+    /* send the error if rtic fail notifcation is received */
+    lock_output_stream(out);
+    if (out && out->client_callback)
+        out->client_callback(AUDIO_EXTN_STREAM_CBK_EVENT_ERROR, NULL, out->client_cookie);
+    pthread_mutex_unlock(&out->lock);
+
+    return 0;
+}
+
+static int audio_extn_ip_hdlr_intf_open_dsp(void *handle, void *stream_handle)
+{
+    int ret = 0, fd = 0, pcm_device_id = 0;
+    struct audio_adsp_event *param;
+    struct reg_event *reg_ev;
+    size_t shm_size;
+    void  *shm_buf;;
+    struct stream_out *out = (struct stream_out *)stream_handle;
+    struct mixer_ctl *ctl = NULL;
+    char mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0};
+
+    param = (struct audio_adsp_event *)calloc(1, sizeof(struct audio_adsp_event));
+    if (!param)
+        return -ENOMEM;
+
+    reg_ev = (struct reg_event *)calloc(1, sizeof(struct reg_event));
+    if (!reg_ev)
+        return -ENOMEM;
+
+    reg_ev->service_id = ADSP_DEC_SERVICE_ID;
+    reg_ev->num_reg_events = 2;
+    reg_ev->rtic.event_id = ADSP_EVENT_ID_RTIC;
+    reg_ev->rtic.cfg_mask = 1; /* event enabled */
+    reg_ev->rtic_fail.event_id = ADSP_EVENT_ID_RTIC_FAIL;
+    reg_ev->rtic_fail.cfg_mask = 1; /* event enabled */
+
+    param->event_type = AUDIO_STREAM_ENCDEC_EVENT;
+    param->payload_length = sizeof(struct reg_event);
+    param->payload = reg_ev;
+
+    /* Register for event and its callback */
+    ret = audio_extn_adsp_hdlr_stream_register_event(out->adsp_hdlr_stream_handle, param,
+                                                     audio_extn_ip_hdlr_intf_event,
+                                                     handle);
+    if (ret < 0) {
+        ALOGE("%s:[%d] failed to register event",__func__, ip_hdlr->ref_cnt, ret);
+        goto done;
+    }
+
+    ip_hdlr->reg_cb(handle, &audio_extn_ip_hdlr_intf_rtic_ack, &audio_extn_ip_hdlr_intf_rtic_fail);
+    ip_hdlr->shm_info(handle, &fd);
+    ALOGV("%s: fd = %d", __func__, fd);
+
+    pcm_device_id = platform_get_pcm_device_id(out->usecase, PCM_PLAYBACK);
+    ret = snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+                   "Playback ION FD %d", pcm_device_id);
+    if (ret < 0) {
+        ALOGE("%s:[%d] snprintf failed",__func__, ip_hdlr->ref_cnt, ret);
+        goto done;
+    }
+    ctl = mixer_get_ctl_by_name(out->dev->mixer, mixer_ctl_name);
+    if (!ctl) {
+        ALOGE("%s:[%d] Could not get ctl for mixer cmd - %s", __func__,
+              ip_hdlr->ref_cnt, mixer_ctl_name);
+        ret = -EINVAL;
+        goto done;
+    }
+    ret = mixer_ctl_set_array(ctl, &fd, sizeof(fd));
+    if (ret < 0) {
+        ALOGE("%s:[%d] Could not set ctl for mixer cmd - %s, ret %d", __func__, ip_hdlr->ref_cnt,
+              mixer_ctl_name, ret);
+        goto done;
+    }
+
+done:
+    free(param);
+    free(reg_ev);
+    return ret;
+}
+
+int audio_extn_ip_hdlr_intf_open(void *handle, bool is_dsp_decode, void *aud_sess_handle)
+{
+    int ret = 0;
+
+    if (!handle || !aud_sess_handle) {
+        ALOGE("%s:[%d] Invalid arguments, handle %p", __func__, ip_hdlr->ref_cnt, handle);
+        return -EINVAL;
+    }
+
+    ret = ip_hdlr->open(handle, is_dsp_decode, aud_sess_handle);
+    if (ret < 0) {
+        ALOGE("%s:[%d] open failed", __func__, ip_hdlr->ref_cnt);
+        return -EINVAL;
+    }
+    ALOGD("%s:[%d] handle = %p, sess_handle = %p, is_dsp_decode = %d",__func__,
+          ip_hdlr->ref_cnt, handle, aud_sess_handle, is_dsp_decode);
+    if (is_dsp_decode) {
+        ret = audio_extn_ip_hdlr_intf_open_dsp(handle, aud_sess_handle);
+        if (ret < 0)
+            ip_hdlr->close(handle);
+    }
+
+done:
+    return ret;
+}
+
+int audio_extn_ip_hdlr_intf_close(void *handle, bool is_dsp_decode, void *aud_sess_handle)
+{
+    struct audio_adsp_event param;
+    int ret = 0;
+
+    if (!handle) {
+        ALOGE("%s:[%d] handle is NULL", __func__, ip_hdlr->ref_cnt);
+        return -EINVAL;
+    }
+    ALOGD("%s:[%d] handle = %p",__func__, ip_hdlr->ref_cnt, handle);
+
+    ret = ip_hdlr->close(handle);
+    if (ret < 0)
+        ALOGE("%s:[%d] close failed", __func__, ip_hdlr->ref_cnt);
+
+    if (is_dsp_decode) {
+        struct stream_out *out = (struct stream_out *)aud_sess_handle;
+        param.event_type = AUDIO_STREAM_ENCDEC_EVENT;
+        param.payload_length = 0;
+        /* Deregister the event */
+        ret = audio_extn_adsp_hdlr_stream_deregister_event(out->adsp_hdlr_stream_handle, &param);
+        if (ret < 0)
+            ALOGE("%s:[%d] event deregister failed", __func__, ip_hdlr->ref_cnt);
+    }
+
+    return ret;
+}
+
+int audio_extn_ip_hdlr_intf_init(void **handle, char *lib_path, void **lib_handle)
+{
+    int ret = 0;
+
+    if (!ip_hdlr) {
+        ip_hdlr = (struct ip_hdlr_intf *)calloc(1, sizeof(struct ip_hdlr_intf));
+        if (!ip_hdlr)
+            return -ENOMEM;
+
+        ip_hdlr->lib_hdl = dlopen(LIB_PATH, RTLD_NOW);
+        if (ip_hdlr->lib_hdl == NULL) {
+             ALOGE("%s: DLOPEN failed, %s", __func__, dlerror());
+             ret = -EINVAL;
+             goto err;
+        }
+        ip_hdlr->init =(int (*)(void **handle, char *lib_path,
+                                void **lib_handle))dlsym(ip_hdlr->lib_hdl, "audio_ip_hdlr_init");
+        ip_hdlr->deinit = (int (*)(void *handle))dlsym(ip_hdlr->lib_hdl, "audio_ip_hdlr_deinit");
+        ip_hdlr->open = (int (*)(void *handle, bool is_dsp_decode,
+                                 void *sess_handle))dlsym(ip_hdlr->lib_hdl, "audio_ip_hdlr_open");
+        ip_hdlr->close =(int (*)(void *handle))dlsym(ip_hdlr->lib_hdl, "audio_ip_hdlr_close");
+        ip_hdlr->reg_cb =(int (*)(void *handle, void *ack_cb,
+                                  void *fail_cb))dlsym(ip_hdlr->lib_hdl, "audio_ip_hdlr_reg_cb");
+        ip_hdlr->shm_info =(int (*)(void *handle, int *fd))dlsym(ip_hdlr->lib_hdl,
+                                                                 "audio_ip_hdlr_shm_info");
+        ip_hdlr->event =(int (*)(void *handle, void *payload))dlsym(ip_hdlr->lib_hdl,
+                                                                    "audio_ip_hdlr_event");
+        if (!ip_hdlr->init || !ip_hdlr->deinit || !ip_hdlr->open ||
+            !ip_hdlr->close || !ip_hdlr->reg_cb || !ip_hdlr->shm_info ||
+            !ip_hdlr->event) {
+            ALOGE("%s: failed to get symbols", __func__);
+            ret = -EINVAL;
+            goto dlclose;
+
+        }
+    }
+
+    ret = ip_hdlr->init(handle, lib_path, lib_handle);
+    if (ret < 0) {
+        ALOGE("%s:[%d] init failed ret = %d", __func__, ip_hdlr->ref_cnt, ret);
+        ret = -EINVAL;
+        goto dlclose;
+    }
+    ip_hdlr->ref_cnt++;
+    ALOGD("%s:[%d] init done", __func__, ip_hdlr->ref_cnt);
+
+    return 0;
+
+dlclose:
+    dlclose(ip_hdlr->lib_hdl);
+err:
+    free(ip_hdlr);
+    ip_hdlr = NULL;
+    return ret;
+}
+
+int audio_extn_ip_hdlr_intf_deinit(void *handle)
+{
+    int ret = 0;
+
+    if (!handle) {
+        ALOGE("%s:[%d] handle is NULL", __func__, ip_hdlr->ref_cnt);
+        return -EINVAL;
+    }
+    ALOGD("%s:[%d] handle = %p",__func__, ip_hdlr->ref_cnt, handle);
+    ret = ip_hdlr->deinit(handle);
+    if (ret < 0)
+        ALOGE("%s:[%d] deinit failed ret = %d", __func__, ip_hdlr->ref_cnt, ret);
+
+    if (--ip_hdlr->ref_cnt == 0) {
+        if (ip_hdlr->lib_hdl)
+            dlclose(ip_hdlr->lib_hdl);
+
+        free(ip_hdlr);
+        ip_hdlr == NULL;
+    }
+    return ret;
+}
diff --git a/hal/audio_extn/ip_hdlr_intf.h b/hal/audio_extn/ip_hdlr_intf.h
new file mode 100644
index 0000000..01d0b7b
--- /dev/null
+++ b/hal/audio_extn/ip_hdlr_intf.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017, 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_HW_EXTN_IP_HDLR_H
+#define AUDIO_HW_EXTN_IP_HDLR_H
+
+#ifdef AUDIO_EXTN_IP_HDLR_ENABLED
+
+int audio_extn_ip_hdlr_intf_open(void *handle, bool is_dsp_decode, void *aud_sess_handle);
+int audio_extn_ip_hdlr_intf_close(void *handle, bool is_dsp_decode, void *aud_sess_handle);
+int audio_extn_ip_hdlr_intf_init(void **handle, char *lib_path, void **lib_handle);
+int audio_extn_ip_hdlr_intf_deinit(void *handle);
+bool audio_extn_ip_hdlr_intf_supported(audio_format_t format);
+
+#else
+
+#define audio_extn_ip_hdlr_intf_open(handle, is_dsp_decode, aud_sess_handle)  (0)
+#define audio_extn_ip_hdlr_intf_close(handle, is_dsp_decode, aud_sess_handle) (0)
+#define audio_extn_ip_hdlr_intf_init(handle, lib_path, lib_handle)            (0)
+#define audio_extn_ip_hdlr_intf_deinit(handle)                                (0)
+#define audio_extn_ip_hdlr_intf_supported(format)                             (0)
+
+#endif
+
+#endif
diff --git a/hal/audio_extn/keep_alive.c b/hal/audio_extn/keep_alive.c
index bcc12d4..87cb122 100644
--- a/hal/audio_extn/keep_alive.c
+++ b/hal/audio_extn/keep_alive.c
@@ -29,6 +29,7 @@
 
 #define LOG_TAG "keep_alive"
 /*#define LOG_NDEBUG 0*/
+
 #include <stdlib.h>
 #include <cutils/log.h>
 #include "audio_hw.h"
@@ -36,6 +37,12 @@
 #include "platform_api.h"
 #include <platform.h>
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_KEEP_ALIVE
+#include <log_utils.h>
+#endif
+
 #define SILENCE_INTERVAL 2 /*In secs*/
 
 typedef enum {
diff --git a/hal/audio_extn/listen.c b/hal/audio_extn/listen.c
index 4cb2d2d..b98a429 100644
--- a/hal/audio_extn/listen.c
+++ b/hal/audio_extn/listen.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 2017, 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
@@ -41,6 +41,11 @@
 #include "platform.h"
 #include "platform_api.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_AUDIO_LISTEN
+#include <log_utils.h>
+#endif
 
 #ifdef AUDIO_LISTEN_ENABLED
 
diff --git a/hal/audio_extn/passthru.c b/hal/audio_extn/passthru.c
index dd4d4d4..61575dd 100644
--- a/hal/audio_extn/passthru.c
+++ b/hal/audio_extn/passthru.c
@@ -40,6 +40,11 @@
 #include <cutils/properties.h>
 
 #include "sound/compress_params.h"
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_PASSTH
+#include <log_utils.h>
+#endif
 
 static const audio_format_t audio_passthru_formats[] = {
     AUDIO_FORMAT_AC3,
@@ -47,7 +52,8 @@
     AUDIO_FORMAT_E_AC3_JOC,
     AUDIO_FORMAT_DTS,
     AUDIO_FORMAT_DTS_HD,
-    AUDIO_FORMAT_DOLBY_TRUEHD
+    AUDIO_FORMAT_DOLBY_TRUEHD,
+    AUDIO_FORMAT_IEC61937
 };
 
 /*
@@ -264,9 +270,12 @@
     if (audio_extn_passthru_is_passt_supported(adev, out)) {
         ALOGV("%s:PASSTHROUGH", __func__);
         out->compr_config.codec->compr_passthr = PASSTHROUGH;
-    } else if (audio_extn_passthru_is_convert_supported(adev, out)){
+    } else if (audio_extn_passthru_is_convert_supported(adev, out)) {
         ALOGV("%s:PASSTHROUGH CONVERT", __func__);
         out->compr_config.codec->compr_passthr = PASSTHROUGH_CONVERT;
+    } else if (out->format == AUDIO_FORMAT_IEC61937) {
+        ALOGV("%s:PASSTHROUGH IEC61937", __func__);
+        out->compr_config.codec->compr_passthr = PASSTHROUGH_IEC61937;
     } else {
         ALOGV("%s:NO PASSTHROUGH", __func__);
         out->compr_config.codec->compr_passthr = LEGACY_PCM;
diff --git a/hal/audio_extn/pm.c b/hal/audio_extn/pm.c
index 69e19cb..65aa1fe 100644
--- a/hal/audio_extn/pm.c
+++ b/hal/audio_extn/pm.c
@@ -34,6 +34,12 @@
 #include <cutils/log.h>
 #include <cutils/str_parms.h>
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_PM
+#include <log_utils.h>
+#endif
+
 /* Device state*/
 #define AUDIO_PARAMETER_KEY_DEV_SHUTDOWN "dev_shutdown"
 
diff --git a/hal/audio_extn/qaf.c b/hal/audio_extn/qaf.c
index f16c365..bf731f6 100644
--- a/hal/audio_extn/qaf.c
+++ b/hal/audio_extn/qaf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, 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
@@ -117,6 +117,12 @@
 #include <qti_audio.h>
 #include "sound/compress_params.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_QAF
+#include <log_utils.h>
+#endif
+
 //TODO: Need to remove this.
 #define QAF_OUTPUT_SAMPLING_RATE 48000
 
@@ -364,7 +370,8 @@
                 case AUDIO_FORMAT_E_AC3:
                 case AUDIO_FORMAT_DTS:
                 case AUDIO_FORMAT_DTS_HD:
-                case AUDIO_FORMAT_DOLBY_TRUEHD: {
+                case AUDIO_FORMAT_DOLBY_TRUEHD:
+                case AUDIO_FORMAT_IEC61937: {
                     is_enabled = true;
                     break;
                 }
@@ -1785,7 +1792,7 @@
                 ERROR_MSG("Stream Open FAILED !!!");
             }
         }
-    } else if ((flags & AUDIO_OUTPUT_FLAG_MAIN) || (!((flags & AUDIO_OUTPUT_FLAG_MAIN) && (flags & AUDIO_OUTPUT_FLAG_ASSOCIATED)))) {
+    } else if ((flags & AUDIO_OUTPUT_FLAG_MAIN) || ((!(flags & AUDIO_OUTPUT_FLAG_MAIN)) && (!(flags & AUDIO_OUTPUT_FLAG_ASSOCIATED)))) {
         /* Assume Main if no flag is set */
         if (is_dual_main_active(qaf_mod)) {
             ERROR_MSG("Dual Main already active. So, Cannot open main stream");
diff --git a/hal/audio_extn/sndmonitor.c b/hal/audio_extn/sndmonitor.c
index 89a6670..b560c9d 100644
--- a/hal/audio_extn/sndmonitor.c
+++ b/hal/audio_extn/sndmonitor.c
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2016-2017, 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
@@ -58,6 +58,12 @@
 #include "audio_hw.h"
 #include "audio_extn.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_SND_MONITOR
+#include <log_utils.h>
+#endif
+
 //#define MONITOR_DEVICE_EVENTS
 #define CPE_MAGIC_NUM 0x2000
 #define MAX_CPE_SLEEP_RETRY 2
diff --git a/hal/audio_extn/soundtrigger.c b/hal/audio_extn/soundtrigger.c
index cecc843..94a8a2b 100644
--- a/hal/audio_extn/soundtrigger.c
+++ b/hal/audio_extn/soundtrigger.c
@@ -41,6 +41,12 @@
 #include "platform_api.h"
 #include "sound_trigger_prop_intf.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_SND_TRIGGER
+#include <log_utils.h>
+#endif
+
 #define XSTR(x) STR(x)
 #define STR(x) #x
 #define MAX_LIBRARY_PATH 100
diff --git a/hal/audio_extn/source_track.c b/hal/audio_extn/source_track.c
index 5bced66..e5e6c06 100644
--- a/hal/audio_extn/source_track.c
+++ b/hal/audio_extn/source_track.c
@@ -41,6 +41,12 @@
 #include <stdlib.h>
 #include <cutils/str_parms.h>
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_SRC_TRACK
+#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.
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index 52bf3a6..710fd31 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 - 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013 - 2017, 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,6 +47,12 @@
 #include "audio_extn.h"
 #include <linux/msm_audio_calibration.h>
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_SPKR_PROT
+#include <log_utils.h>
+#endif
+
 #ifdef SPKR_PROT_ENABLED
 
 /*Range of spkr temparatures -30C to 80C*/
diff --git a/hal/audio_extn/ssr.c b/hal/audio_extn/ssr.c
index f64a861..65fe2b7 100644
--- a/hal/audio_extn/ssr.c
+++ b/hal/audio_extn/ssr.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -38,6 +38,12 @@
 #include "platform_api.h"
 #include "surround_rec_interface.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_SSR
+#include <log_utils.h>
+#endif
+
 #ifdef SSR_ENABLED
 #define COEFF_ARRAY_SIZE            4
 #define FILT_SIZE                   ((512+1)* 6)  /* # ((FFT bins)/2+1)*numOutputs */
@@ -191,9 +197,9 @@
 
     /* TO DO: different config files for different sample rates */
     if (num_chan == 6) {
-        cfgFileName = "/system/etc/drc/drc_cfg_5.1.txt";
+        cfgFileName = "/vendor/etc/drc/drc_cfg_5.1.txt";
     } else if (num_chan == 2) {
-        cfgFileName = "/system/etc/drc/drc_cfg_AZ.txt";
+        cfgFileName = "/vendor/etc/drc/drc_cfg_AZ.txt";
     }
 
     ALOGV("%s: Calling drc_init: num ch: %d, period: %d, cfg file: %s", __func__, num_chan, SSR_PERIOD_SIZE, cfgFileName);
@@ -272,9 +278,9 @@
     ssrmod.num_out_chan = num_out_chan;
 
     if (num_out_chan == 6) {
-        cfgFileName = "/system/etc/surround_sound_3mic/surround_sound_rec_5.1.cfg";
+        cfgFileName = "/vendor/etc/surround_sound_3mic/surround_sound_rec_5.1.cfg";
     } else if (num_out_chan == 2) {
-        cfgFileName = "/system/etc/surround_sound_3mic/surround_sound_rec_AZ.cfg";
+        cfgFileName = "/vendor/etc/surround_sound_3mic/surround_sound_rec_AZ.cfg";
     } else {
         ALOGE("%s: No cfg file for num_out_chan: %d", __func__, num_out_chan);
     }
@@ -546,16 +552,16 @@
           otherwise, fopen may fail */
         if ( !ssrmod.fp_input) {
             ALOGD("%s: Opening ssr input dump file \n", __func__);
-            ssrmod.fp_input = fopen("/data/misc/audio/ssr_input_3ch.pcm", "wb");
+            ssrmod.fp_input = fopen("/data/vendor/misc/audio/ssr_input_3ch.pcm", "wb");
         }
 
         if ( !ssrmod.fp_output) {
             if(ssrmod.num_out_chan == 6) {
                 ALOGD("%s: Opening ssr input dump file for 6 channel\n", __func__);
-                ssrmod.fp_output = fopen("/data/misc/audio/ssr_output_6ch.pcm", "wb");
+                ssrmod.fp_output = fopen("/data/vendor/misc/audio/ssr_output_6ch.pcm", "wb");
             } else {
                 ALOGD("%s: Opening ssr input dump file for 2 channel\n", __func__);
-                ssrmod.fp_output = fopen("/data/misc/audio/ssr_output_2ch.pcm", "wb");
+                ssrmod.fp_output = fopen("/data/vendor/misc/audio/ssr_output_2ch.pcm", "wb");
             }
         }
 
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index 456382e..5c397a7 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -36,6 +36,12 @@
 #include <ctype.h>
 #include <math.h>
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_USB
+#include <log_utils.h>
+#endif
+
 #ifdef USB_HEADSET_ENABLED
 #define USB_BUFF_SIZE           2048
 #define CHANNEL_NUMBER_STR      "Channels: "
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 27bbae8..e22cd1f 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -39,6 +39,13 @@
 #include <sound/compress_params.h>
 #include <sound/compress_offload.h>
 #include <tinycompress/tinycompress.h>
+
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_UTILS
+#include <log_utils.h>
+#endif
+
 #ifdef AUDIO_EXTERNAL_HDMI_ENABLED
 #ifdef HDMI_PASSTHROUGH_ENABLED
 #include "audio_parsers.h"
@@ -111,6 +118,7 @@
     STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_INCALL_MUSIC),
 #endif
     STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH),
+    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_TIMESTAMP),
     STRING_TO_ENUM(AUDIO_INPUT_FLAG_NONE),
     STRING_TO_ENUM(AUDIO_INPUT_FLAG_FAST),
     STRING_TO_ENUM(AUDIO_INPUT_FLAG_HW_HOTWORD),
@@ -135,6 +143,7 @@
     STRING_TO_ENUM(AUDIO_FORMAT_DTS),
     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),
@@ -908,10 +917,13 @@
             (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC) ||
             (usecase->stream.out->format == AUDIO_FORMAT_DOLBY_TRUEHD))
             && audio_extn_passthru_is_passthrough_stream(usecase->stream.out)) {
-            app_type_cfg[len++] = sample_rate * 4;
-        } else {
-            app_type_cfg[len++] = sample_rate;
+
+            sample_rate = sample_rate * 4;
+            if (sample_rate > HDMI_PASSTHROUGH_MAX_SAMPLE_RATE)
+                sample_rate = HDMI_PASSTHROUGH_MAX_SAMPLE_RATE;
         }
+        app_type_cfg[len++] = sample_rate;
+
         if (snd_device_be_idx > 0)
             app_type_cfg[len++] = snd_device_be_idx;
 
@@ -1255,6 +1267,9 @@
     case AUDIO_FORMAT_DOLBY_TRUEHD:
         id = SND_AUDIOCODEC_TRUEHD;
         break;
+    case AUDIO_FORMAT_IEC61937:
+        id = SND_AUDIOCODEC_IEC61937;
+        break;
     case AUDIO_FORMAT_DSD:
         id = SND_AUDIOCODEC_DSD;
         break;
@@ -1601,36 +1616,39 @@
 {
     int ret = 0, count = 0;
     char avt_device_drift_mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0};
+    const char *backend = NULL;
     struct mixer_ctl *ctl = NULL;
     struct audio_avt_device_drift_stats drift_stats;
     struct audio_device *adev = NULL;
 
     if (usecase != NULL && usecase->type == PCM_PLAYBACK) {
-        adev = usecase->stream.out->dev;
-        switch(usecase->out_snd_device) {
-            case SND_DEVICE_OUT_HDMI:
-                strlcpy(avt_device_drift_mixer_ctl_name,
-                        "HDMI RX Drift",
-                        MIXER_PATH_MAX_LENGTH);
-                break;
-            case SND_DEVICE_OUT_DISPLAY_PORT:
-                strlcpy(avt_device_drift_mixer_ctl_name,
-                        "DISPLAY Port RX Drift",
-                        MIXER_PATH_MAX_LENGTH);
-                break;
-            default :
-                ALOGE("%s: Unsupported device %d",__func__,
-                        usecase->stream.out->devices);
-                ret = -EINVAL;
+        backend = platform_get_snd_device_backend_interface(usecase->out_snd_device);
+        if (!backend) {
+            ALOGE("%s: Unsupported device %d", __func__,
+                   usecase->stream.out->devices);
+            ret = -EINVAL;
+            goto done;
+        }
+        strlcpy(avt_device_drift_mixer_ctl_name,
+                backend,
+                MIXER_PATH_MAX_LENGTH);
+
+        count = strlen(backend);
+        if (MIXER_PATH_MAX_LENGTH - count > 0) {
+            strlcat(&avt_device_drift_mixer_ctl_name[count],
+                    " DRIFT",
+                    MIXER_PATH_MAX_LENGTH - count);
+        } else {
+            ret = -EINVAL;
+            goto done;
         }
     } else {
-        ALOGE("%s: Invalid usecase %d ",__func__, usecase->type);
+        ALOGE("%s: Invalid usecase",__func__);
         ret = -EINVAL;
+        goto done;
     }
 
-    if(ret)
-        goto done;
-
+    adev = usecase->stream.out->dev;
     ctl = mixer_get_ctl_by_name(adev->mixer, avt_device_drift_mixer_ctl_name);
     if (!ctl) {
         ALOGE("%s: Could not get ctl for mixer cmd - %s",
@@ -1760,7 +1778,7 @@
     struct stream_out *out = NULL;
     int ret = -EINVAL;
 
-    if (usecase != NULL && usecase->type != PCM_PLAYBACK) {
+    if (usecase == NULL || usecase->type != PCM_PLAYBACK) {
         ALOGE("%s:: Invalid use case", __func__);
         goto exit;
     }
@@ -1828,24 +1846,21 @@
     struct snd_compr_metadata metadata;
     int ret = -EINVAL;
 
-    ALOGD("%s:: render window start 0x%"PRIx64" end 0x%"PRIx64"",
-          __func__,render_window->render_ws, render_window->render_we);
-
     if(render_window == NULL) {
         ALOGE("%s:: Invalid render_window", __func__);
         goto exit;
     }
 
+    ALOGD("%s:: render window start 0x%"PRIx64" end 0x%"PRIx64"",
+          __func__,render_window->render_ws, render_window->render_we);
+
     if (!is_offload_usecase(out->usecase)) {
         ALOGE("%s:: not supported for non offload session", __func__);
         goto exit;
     }
 
-    if ((out->render_mode == RENDER_MODE_AUDIO_MASTER) ||
-        (out->render_mode == RENDER_MODE_AUDIO_STC_MASTER)) {
-        memcpy(&out->render_window, render_window,
-               sizeof(struct audio_out_render_window_param));
-    } else {
+    if ((out->render_mode != RENDER_MODE_AUDIO_MASTER) &&
+        (out->render_mode != RENDER_MODE_AUDIO_STC_MASTER)) {
         ALOGD("%s:: only supported in timestamp mode, current "
               "render mode mode %d", __func__, out->render_mode);
         goto exit;
@@ -1907,11 +1922,8 @@
         goto exit;
     }
 
-   if ((out->render_mode == RENDER_MODE_AUDIO_MASTER) ||
-       (out->render_mode == RENDER_MODE_AUDIO_STC_MASTER)) {
-        /* store it to reconfigure in start_output_stream() */
-        out->delay_param.start_delay = delay_param->start_delay;
-    } else {
+   if ((out->render_mode != RENDER_MODE_AUDIO_MASTER) &&
+       (out->render_mode != RENDER_MODE_AUDIO_STC_MASTER)) {
         ALOGD("%s:: only supported in timestamp mode, current "
               "render mode mode %d", __func__, out->render_mode);
         goto exit;
@@ -1945,3 +1957,194 @@
     return 0;
 }
 #endif
+
+#define MAX_SND_CARD 8
+#define RETRY_US 500000
+#define RETRY_NUMBER 10
+
+int audio_extn_utils_get_snd_card_num()
+{
+
+    void *hw_info = NULL;
+    struct mixer *mixer = NULL;
+    int retry_num = 0;
+    int snd_card_num = 0;
+    char* snd_card_name = NULL;
+
+    while (snd_card_num < MAX_SND_CARD) {
+        mixer = mixer_open(snd_card_num);
+
+        while (!mixer && retry_num < RETRY_NUMBER) {
+            usleep(RETRY_US);
+            mixer = mixer_open(snd_card_num);
+            retry_num++;
+        }
+
+        if (!mixer) {
+            ALOGE("%s: Unable to open the mixer card: %d", __func__,
+                   snd_card_num);
+            retry_num = 0;
+            snd_card_num++;
+            continue;
+        }
+
+        snd_card_name = strdup(mixer_get_name(mixer));
+        if (!snd_card_name) {
+            ALOGE("failed to allocate memory for snd_card_name\n");
+            mixer_close(mixer);
+            return -1;
+        }
+        ALOGD("%s: snd_card_name: %s", __func__, snd_card_name);
+
+        hw_info = hw_info_init(snd_card_name);
+        if (hw_info) {
+            ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
+            break;
+        }
+        ALOGE("%s: Failed to init hardware info", __func__);
+        retry_num = 0;
+        snd_card_num++;
+        free(snd_card_name);
+        mixer_close(mixer);
+    }
+
+    mixer_close(mixer);
+    hw_info_deinit(hw_info);
+    if (snd_card_name)
+        free(snd_card_name);
+
+    if (snd_card_num >= MAX_SND_CARD) {
+        ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
+        return -1;
+    }
+
+    return snd_card_num;
+}
+
+#ifdef SNDRV_COMPRESS_ENABLE_ADJUST_SESSION_CLOCK
+int audio_extn_utils_compress_enable_drift_correction(
+        struct stream_out *out,
+        struct audio_out_enable_drift_correction *drift)
+{
+    struct snd_compr_metadata metadata;
+    int ret = -EINVAL;
+
+    if(drift == NULL) {
+        ALOGE("%s:: Invalid param", __func__);
+        goto exit;
+    }
+
+    ALOGD("%s:: drift enable %d", __func__,drift->enable);
+
+    if (!is_offload_usecase(out->usecase)) {
+        ALOGE("%s:: not supported for non offload session", __func__);
+        goto exit;
+    }
+
+    if (!out->compr) {
+        ALOGW("%s:: offload session not yet opened,"
+                "start delay will be configure later", __func__);
+        goto exit;
+    }
+
+    metadata.key = SNDRV_COMPRESS_ENABLE_ADJUST_SESSION_CLOCK;
+    metadata.value[0] = drift->enable;
+    out->drift_correction_enabled = drift->enable;
+
+    ret = compress_set_metadata(out->compr, &metadata);
+    if(ret) {
+        ALOGE("%s::error %s", __func__, compress_get_error(out->compr));
+        out->drift_correction_enabled = false;
+    }
+
+exit:
+    return ret;
+}
+#else
+int audio_extn_utils_compress_enable_drift_correction(
+        struct stream_out *out __unused,
+        struct audio_out_enable_drift_correction *drift __unused)
+{
+    ALOGD("%s:: configuring drift enablement not supported", __func__);
+    return 0;
+}
+#endif
+
+#ifdef SNDRV_COMPRESS_ADJUST_SESSION_CLOCK
+int audio_extn_utils_compress_correct_drift(
+        struct stream_out *out,
+        struct audio_out_correct_drift *drift_param)
+{
+    struct snd_compr_metadata metadata;
+    int ret = -EINVAL;
+
+    if (drift_param == NULL) {
+        ALOGE("%s:: Invalid drift_param", __func__);
+        goto exit;
+    }
+
+    ALOGD("%s:: adjust time 0x%"PRIx64" ", __func__,
+            drift_param->adjust_time);
+
+    if (!is_offload_usecase(out->usecase)) {
+        ALOGE("%s:: not supported for non offload session", __func__);
+        goto exit;
+    }
+
+    if (!out->compr) {
+        ALOGW("%s:: offload session not yet opened", __func__);
+        goto exit;
+    }
+
+    if (!out->drift_correction_enabled) {
+        ALOGE("%s:: drift correction not enabled", __func__);
+        goto exit;
+    }
+
+    metadata.key = SNDRV_COMPRESS_ADJUST_SESSION_CLOCK;
+    metadata.value[0] = 0xFFFFFFFF & drift_param->adjust_time; /* lsb */
+    metadata.value[1] = \
+             (0xFFFFFFFF00000000 & drift_param->adjust_time) >> 32; /* msb*/
+
+    ret = compress_set_metadata(out->compr, &metadata);
+    if(ret)
+        ALOGE("%s::error %s", __func__, compress_get_error(out->compr));
+exit:
+    return ret;
+}
+#else
+int audio_extn_utils_compress_correct_drift(
+        struct stream_out *out __unused,
+        struct audio_out_correct_drift *drift_param __unused)
+{
+    ALOGD("%s:: setting adjust clock not supported", __func__);
+    return 0;
+}
+#endif
+
+int audio_extn_utils_set_channel_map(
+            struct stream_out *out,
+            struct audio_out_channel_map_param *channel_map_param)
+{
+    int ret = -EINVAL, i = 0;
+    int channels = audio_channel_count_from_out_mask(out->channel_mask);
+
+    if (channel_map_param == NULL) {
+        ALOGE("%s:: Invalid channel_map", __func__);
+        goto exit;
+    }
+
+    if (channel_map_param->channels != channels) {
+        ALOGE("%s:: Channels(%d) does not match stream channels(%d)",
+                                __func__, channel_map_param->channels, channels);
+        goto exit;
+    }
+
+    for ( i = 0; i < channels; i++) {
+        ALOGV("%s:: channel_map[%d]- %d", __func__, i, channel_map_param->channel_map[i]);
+        out->channel_map_param.channel_map[i] = channel_map_param->channel_map[i];
+    }
+    ret = 0;
+exit:
+    return ret;
+}
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 4fa42e8..1b818b1 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -76,6 +76,12 @@
 #include "sound/compress_params.h"
 #include "sound/asound.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_AUDIO_HW
+#include <log_utils.h>
+#endif
+
 #define COMPRESS_OFFLOAD_NUM_FRAGMENTS 4
 /*DIRECT PCM has same buffer sizes as DEEP Buffer*/
 #define DIRECT_PCM_NUM_FRAGMENTS 2
@@ -296,6 +302,7 @@
     STRING_TO_ENUM(AUDIO_FORMAT_DOLBY_TRUEHD),
     STRING_TO_ENUM(AUDIO_FORMAT_DTS),
     STRING_TO_ENUM(AUDIO_FORMAT_DTS_HD),
+    STRING_TO_ENUM(AUDIO_FORMAT_IEC61937)
 };
 
 //list of all supported sample rates by HDMI specification.
@@ -522,7 +529,8 @@
         format == AUDIO_FORMAT_VORBIS ||
         format == AUDIO_FORMAT_WMA ||
         format == AUDIO_FORMAT_WMA_PRO ||
-        format == AUDIO_FORMAT_APTX)
+        format == AUDIO_FORMAT_APTX ||
+        format == AUDIO_FORMAT_IEC61937)
            return true;
 
     return false;
@@ -1330,6 +1338,11 @@
         out->supported_formats[i++] = AUDIO_FORMAT_DTS_HD;
     }
 
+    if (platform_is_edid_supported_format(out->dev->platform, AUDIO_FORMAT_IEC61937)) {
+        ALOGV(":%s HDMI supports IEC61937 format", __func__);
+        out->supported_formats[i++] = AUDIO_FORMAT_IEC61937;
+    }
+
 
     // check sample rate caps
     i = 0;
@@ -1535,7 +1548,9 @@
         } else if (voice_extn_compress_voip_is_active(adev)) {
             bool out_snd_device_backend_match = true;
             voip_usecase = get_usecase_from_list(adev, USECASE_COMPRESS_VOIP_CALL);
-            if (usecase->stream.out != NULL) {
+            if ((voip_usecase != NULL) &&
+                (usecase->type == PCM_PLAYBACK) &&
+                (usecase->stream.out != NULL)) {
                 out_snd_device_backend_match = platform_check_backends_match(
                                                    voip_usecase->out_snd_device,
                                                    platform_get_output_snd_device(
@@ -2200,8 +2215,11 @@
     if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
         audio_extn_keep_alive_start();
 
-    /*reset delay_param to 0*/
-    out->delay_param.start_delay = 0;
+    if (audio_extn_ip_hdlr_intf_supported(out->format) && out->ip_hdlr_handle) {
+        ret = audio_extn_ip_hdlr_intf_close(out->ip_hdlr_handle, true, out);
+        if (ret < 0)
+            ALOGE("%s: audio_extn_ip_hdlr_intf_close failed %d",__func__, ret);
+    }
 
     ALOGV("%s: exit: status(%d)", __func__, ret);
     return ret;
@@ -2337,9 +2355,6 @@
             break;
         }
 
-        platform_set_stream_channel_map(adev->platform, out->channel_mask,
-                                    out->pcm_device_id);
-
         ALOGV("%s: pcm_prepare", __func__);
         if (pcm_is_ready(out->pcm)) {
             ret = pcm_prepare(out->pcm);
@@ -2351,10 +2366,11 @@
             }
         }
         platform_set_stream_channel_map(adev->platform, out->channel_mask,
-                                    out->pcm_device_id);
+                   out->pcm_device_id, &out->channel_map_param.channel_map[0]);
+
     } else {
         platform_set_stream_channel_map(adev->platform, out->channel_mask,
-                                    out->pcm_device_id);
+                   out->pcm_device_id, &out->channel_map_param.channel_map[0]);
         out->pcm = NULL;
         out->compr = compress_open(adev->snd_card,
                                    out->pcm_device_id,
@@ -2382,11 +2398,6 @@
 
         audio_extn_utils_compress_set_render_mode(out);
         audio_extn_utils_compress_set_clk_rec_mode(uc_info);
-        /* set render window if it was set before compress_open() */
-        if (out->render_window.render_ws != 0 && out->render_window.render_we != 0)
-            audio_extn_utils_compress_set_render_window(out,
-                                            &out->render_window);
-        audio_extn_utils_compress_set_start_delay(out, &out->delay_param);
 
         audio_extn_dts_create_state_notifier_node(out->usecase);
         audio_extn_dts_notify_playback_state(out->usecase, 0, out->sample_rate,
@@ -2419,6 +2430,12 @@
     audio_extn_perf_lock_release(&adev->perf_lock_handle);
     ALOGD("%s: exit", __func__);
 
+    if (audio_extn_ip_hdlr_intf_supported(out->format) && out->ip_hdlr_handle) {
+        ret = audio_extn_ip_hdlr_intf_open(out->ip_hdlr_handle, true, out);
+        if (ret < 0)
+            ALOGE("%s: audio_extn_ip_hdlr_intf_open failed %d",__func__, ret);
+    }
+
     return ret;
 error_open:
     audio_extn_perf_lock_release(&adev->perf_lock_handle);
@@ -2579,9 +2596,12 @@
 {
     struct stream_out *out = (struct stream_out *)stream;
 
-    if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
-        return out->compr_config.fragment_size;
-    else if(out->usecase == USECASE_COMPRESS_VOIP_CALL)
+    if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
+        if (out->flags & AUDIO_OUTPUT_FLAG_TIMESTAMP)
+            return out->compr_config.fragment_size - sizeof(struct snd_codec_metadata);
+        else
+            return out->compr_config.fragment_size;
+    } else if(out->usecase == USECASE_COMPRESS_VOIP_CALL)
         return voice_extn_compress_voip_out_get_buffer_size(out);
     else if (is_offload_usecase(out->usecase) &&
              out->flags == AUDIO_OUTPUT_FLAG_DIRECT)
@@ -4097,6 +4117,11 @@
          */
         if (!audio_extn_passthru_is_passthrough_stream(out))
             out->bit_width = AUDIO_OUTPUT_BIT_WIDTH;
+
+        if (out->flags & AUDIO_OUTPUT_FLAG_TIMESTAMP)
+            out->compr_config.codec->flags |= COMPRESSED_TIMESTAMP_FLAG;
+        ALOGVV("%s : out->compr_config.codec->flags -> (%#x) ", __func__, out->compr_config.codec->flags);
+
         /*TODO: Do we need to change it for passthrough */
         out->compr_config.codec->format = SND_AUDIOSTREAMFORMAT_RAW;
 
@@ -4159,6 +4184,9 @@
             out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
         }
 
+        if (out->flags & AUDIO_OUTPUT_FLAG_TIMESTAMP) {
+            out->compr_config.fragment_size += sizeof(struct snd_codec_metadata);
+        }
         if (config->offload_info.format == AUDIO_FORMAT_FLAC)
             out->compr_config.codec->options.flac_dec.sample_size = AUDIO_OUTPUT_BIT_WIDTH;
 
@@ -4178,8 +4206,8 @@
             out->render_mode = RENDER_MODE_AUDIO_NO_TIMESTAMP;
         }
 
-        memset(&out->render_window, 0,
-                sizeof(struct audio_out_render_window_param));
+        memset(&out->channel_map_param, 0,
+                sizeof(struct audio_out_channel_map_param));
 
         out->send_new_metadata = 1;
         out->send_next_track_params = false;
@@ -4211,6 +4239,7 @@
          */
         if (audio_extn_passthru_is_passthrough_stream(out) ||
                 (config->format == AUDIO_FORMAT_DSD) ||
+                (config->format == AUDIO_FORMAT_IEC61937) ||
                 config->offload_info.has_video ||
                 !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) {
             check_and_set_gapless_mode(adev, false);
@@ -4385,7 +4414,8 @@
                                              popcount(out->channel_mask), out->playback_started);
     /* setup a channel for client <--> adsp communication for stream events */
     if ((out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) ||
-            (out->flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM)) {
+            (out->flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM) ||
+            (audio_extn_ip_hdlr_intf_supported(config->format))) {
         hdlr_stream_cfg.pcm_device_id = platform_get_pcm_device_id(
                 out->usecase, PCM_PLAYBACK);
         hdlr_stream_cfg.flags = out->flags;
@@ -4397,6 +4427,13 @@
             out->adsp_hdlr_stream_handle = NULL;
         }
     }
+    if (audio_extn_ip_hdlr_intf_supported(config->format)) {
+        ret = audio_extn_ip_hdlr_intf_init(&out->ip_hdlr_handle, NULL, NULL);
+        if (ret < 0) {
+            ALOGE("%s: audio_extn_ip_hdlr_intf_init failed %d",__func__, ret);
+            out->ip_hdlr_handle = NULL;
+        }
+    }
     ALOGV("%s: exit", __func__);
     return 0;
 
@@ -4426,6 +4463,11 @@
         out->adsp_hdlr_stream_handle = NULL;
     }
 
+    if (audio_extn_ip_hdlr_intf_supported(out->format) && out->ip_hdlr_handle) {
+        audio_extn_ip_hdlr_intf_deinit(out->ip_hdlr_handle);
+        out->ip_hdlr_handle = NULL;
+    }
+
     if (out->usecase == USECASE_COMPRESS_VOIP_CALL) {
         pthread_mutex_lock(&adev->lock);
         ret = voice_extn_compress_voip_close_output_stream(&stream->common);
@@ -4644,7 +4686,10 @@
             if ((usecase->type == PCM_PLAYBACK) &&
                 (usecase->devices & AUDIO_DEVICE_OUT_ALL_A2DP)){
                 ALOGD("reconfigure a2dp... forcing device switch");
+
+                pthread_mutex_unlock(&adev->lock);
                 lock_output_stream(usecase->stream.out);
+                pthread_mutex_lock(&adev->lock);
                 audio_extn_a2dp_set_handoff_mode(true);
                 //force device switch to re configure encoder
                 select_devices(adev, usecase->id);
@@ -5173,6 +5218,10 @@
 
     pthread_mutex_init(&adev->lock, (const pthread_mutexattr_t *) NULL);
 
+#ifdef DYNAMIC_LOG_ENABLED
+    register_for_dynamic_logging("hal");
+#endif
+
     adev->device.common.tag = HARDWARE_DEVICE_TAG;
     adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
     adev->device.common.module = (struct hw_module_t *)module;
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index ff9149f..5044551 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -243,6 +243,7 @@
     bool offload_thread_blocked;
 
     void *adsp_hdlr_stream_handle;
+    void *ip_hdlr_handle;
 
     stream_callback_t client_callback;
     void *client_cookie;
@@ -266,10 +267,11 @@
     struct listnode qaf_offload_cmd_list;
     uint32_t platform_latency;
     render_mode_t render_mode;
-    struct audio_out_render_window_param render_window; /*render winodw*/
-    struct audio_out_start_delay_param delay_param; /*start delay*/
+    bool drift_correction_enabled;
 
+    struct audio_out_channel_map_param channel_map_param; /* input channel map */
     audio_offload_info_t info;
+    qahwi_stream_out_t qahwi_out;
 };
 
 struct stream_in {
diff --git a/hal/audio_hw_extn_api.c b/hal/audio_hw_extn_api.c
index a1bd04d..0ee927e 100644
--- a/hal/audio_hw_extn_api.c
+++ b/hal/audio_hw_extn_api.c
@@ -31,6 +31,7 @@
 /*#define LOG_NDEBUG 0*/
 #define LOG_NDDEBUG 0
 
+#include <inttypes.h>
 #include <errno.h>
 #include <cutils/log.h>
 
@@ -40,6 +41,12 @@
 #include "audio_extn.h"
 #include "audio_hw_extn_api.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_AUDIO_HW_EXTN_API
+#include <log_utils.h>
+#endif
+
 /* default timestamp metadata definition if not defined in kernel*/
 #ifndef COMPRESSED_TIMESTAMP_FLAG
 #define COMPRESSED_TIMESTAMP_FLAG 0
@@ -69,7 +76,7 @@
         if (ret)
             ALOGE("%s::qaf_out_set_param_data failed error %d", __func__ , ret);
     } else {
-        if (out->standby)
+        if (out->standby && (param_id != AUDIO_EXTN_PARAM_OUT_CHANNEL_MAP))
             out->stream.write(&out->stream, NULL, 0);
         lock_output_stream(out);
         ret = audio_extn_out_set_param_data(out, param_id, payload);
@@ -286,6 +293,117 @@
     return ret;
 }
 
+ssize_t qahwi_out_write_v2(struct audio_stream_out *stream, const void* buffer,
+                          size_t bytes, int64_t* timestamp)
+{
+    struct stream_out *out = (struct stream_out *)stream;
+    struct snd_codec_metadata *mdata = NULL;
+    size_t mdata_size = 0, bytes_written = 0;
+    char *buf = NULL;
+    ssize_t ret = 0;
+
+    if (!out->qahwi_out.is_inititalized) {
+        ALOGE("%s: invalid state!", __func__);
+        return -EINVAL;
+    }
+    if (COMPRESSED_TIMESTAMP_FLAG &&
+        (out->flags & AUDIO_OUTPUT_FLAG_TIMESTAMP)) {
+
+        mdata_size = sizeof(struct snd_codec_metadata);
+        buf = (char *) out->qahwi_out.obuf;
+        if (timestamp) {
+            mdata = (struct snd_codec_metadata *) buf;
+            mdata->length = bytes;
+            mdata->offset = mdata_size;
+            mdata->timestamp = *timestamp;
+        }
+        memcpy(buf + mdata_size, buffer, bytes);
+        ret = out->qahwi_out.base.write(&out->stream, (void *)buf, out->qahwi_out.buf_size);
+        if (ret <= 0) {
+            ALOGE("%s: error! write returned %zd", __func__, ret);
+        } else {
+            bytes_written = bytes;
+        }
+        ALOGV("%s: flag 0x%x, bytes %zd, read %zd, ret %zd timestamp 0x%"PRIx64"",
+              __func__, out->flags, bytes, bytes_written, ret, *timestamp);
+    } else {
+        bytes_written = out->qahwi_out.base.write(&out->stream, buffer, bytes);
+        ALOGV("%s: flag 0x%x, bytes %zd, read %zd, ret %zd",
+              __func__, out->flags, bytes, bytes_written, ret);
+    }
+    return bytes_written;
+}
+
+static void qahwi_close_output_stream(struct audio_hw_device *dev,
+                               struct audio_stream_out *stream_out)
+{
+    struct audio_device *adev = (struct audio_device *) dev;
+    struct stream_out *out = (struct stream_out *)stream_out;
+
+    ALOGV("%s", __func__);
+    if (!adev->qahwi_dev.is_inititalized || !out->qahwi_out.is_inititalized) {
+        ALOGE("%s: invalid state!", __func__);
+        return;
+    }
+    if (out->qahwi_out.obuf)
+        free(out->qahwi_out.obuf);
+    out->qahwi_out.buf_size = 0;
+    adev->qahwi_dev.base.close_output_stream(dev, stream_out);
+}
+
+static int qahwi_open_output_stream(struct audio_hw_device *dev,
+                             audio_io_handle_t handle,
+                             audio_devices_t devices,
+                             audio_output_flags_t flags,
+                             struct audio_config *config,
+                             struct audio_stream_out **stream_out,
+                             const char *address)
+{
+    struct audio_device *adev = (struct audio_device *) dev;
+    struct stream_out *out = NULL;
+    size_t buf_size = 0, mdata_size = 0;
+    int ret = 0;
+
+    ALOGV("%s: dev_init %d, flags 0x%x", __func__,
+              adev->qahwi_dev.is_inititalized, flags);
+    if (!adev->qahwi_dev.is_inititalized) {
+        ALOGE("%s: invalid state!", __func__);
+        return -EINVAL;
+    }
+
+    ret = adev->qahwi_dev.base.open_output_stream(dev, handle, devices, flags,
+                                                 config, stream_out, address);
+    if (ret)
+        return ret;
+
+    out = (struct stream_out *)*stream_out;
+    // keep adev fptrs before overriding
+    out->qahwi_out.base = out->stream;
+
+    out->qahwi_out.is_inititalized = true;
+
+    if (COMPRESSED_TIMESTAMP_FLAG &&
+        (flags & AUDIO_OUTPUT_FLAG_TIMESTAMP)) {
+        // set write to NULL as this is not supported in timestamp mode
+        out->stream.write = NULL;
+
+        mdata_size = sizeof(struct snd_codec_metadata);
+        buf_size = out->qahwi_out.base.common.get_buffer_size(&out->stream.common);
+        buf_size += mdata_size;
+        out->qahwi_out.buf_size = buf_size;
+        out->qahwi_out.obuf = malloc(buf_size);
+        if (!out->qahwi_out.obuf) {
+            ALOGE("%s: allocation failed for timestamp metadata!", __func__);
+            qahwi_close_output_stream(dev, &out->stream);
+            *stream_out = NULL;
+            ret = -ENOMEM;
+        }
+        ALOGD("%s: obuf %p, buff_size %zd",
+              __func__, out->qahwi_out.obuf, buf_size);
+    }
+    return ret;
+}
+
 void qahwi_init(hw_device_t *device)
 {
     struct audio_device *adev = (struct audio_device *) device;
@@ -299,6 +417,9 @@
     adev->device.open_input_stream = qahwi_open_input_stream;
     adev->device.close_input_stream = qahwi_close_input_stream;
 
+    adev->device.open_output_stream = qahwi_open_output_stream;
+    adev->device.close_output_stream = qahwi_close_output_stream;
+
     adev->qahwi_dev.is_inititalized = true;
 }
 void qahwi_deinit(hw_device_t *device)
diff --git a/hal/audio_hw_extn_api.h b/hal/audio_hw_extn_api.h
index e5fa9ec..4123461 100644
--- a/hal/audio_hw_extn_api.h
+++ b/hal/audio_hw_extn_api.h
@@ -33,6 +33,7 @@
 #ifdef AUDIO_HW_EXTN_API_ENABLED
 #include <hardware/audio.h>
 typedef struct qahwi_stream_in qahwi_stream_in_t;
+typedef struct qahwi_stream_out qahwi_stream_out_t;
 typedef struct qahwi_device qahwi_device_t;
 
 struct qahwi_stream_in {
@@ -41,6 +42,13 @@
     void *ibuf;
 };
 
+struct qahwi_stream_out {
+    struct audio_stream_out base;
+    bool is_inititalized;
+    size_t buf_size;
+    void *obuf;
+};
+
 struct qahwi_device {
     struct audio_hw_device base;
     bool is_inititalized;
@@ -50,6 +58,7 @@
 void qahwi_deinit(hw_device_t *device);
 #else
 typedef void *qahwi_stream_in_t;
+typedef void *qahwi_stream_out_t;
 typedef void *qahwi_device_t;
 
 #define qahwi_init(device) (0)
diff --git a/hal/edid.c b/hal/edid.c
index e889530..f7259c7 100644
--- a/hal/edid.c
+++ b/hal/edid.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, 2016-2017, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2014 The Android Open Source Project
@@ -33,6 +33,12 @@
 #include "platform_api.h"
 #include "edid.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_EDID
+#include <log_utils.h>
+#endif
+
 static const char * edid_format_to_str(unsigned char format)
 {
     char * format_str = "??";
@@ -798,4 +804,4 @@
     ALOGV("%s: returns [%d] for highest supported sr",
         __func__, highest_sr);
     return highest_sr;
-}
\ No newline at end of file
+}
diff --git a/hal/msm8916/hw_info.c b/hal/msm8916/hw_info.c
index 652afab..a384827 100644
--- a/hal/msm8916/hw_info.c
+++ b/hal/msm8916/hw_info.c
@@ -39,6 +39,11 @@
 #include "platform.h"
 #include "platform_api.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_HW_INFO
+#include <log_utils.h>
+#endif
 
 struct hardware_info {
     char name[HW_INFO_ARRAY_MAX_SIZE];
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 79f6bc5..c20cd3d 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -32,37 +32,43 @@
 #include <platform_api.h>
 #include "platform.h"
 #include "audio_extn.h"
+#include "acdb.h"
 #include "voice_extn.h"
 #include "edid.h"
 #include "sound/compress_params.h"
 #include "sound/msmcal-hwdep.h"
 #include <dirent.h>
 #include <linux/msm_audio.h>
-#include "linux/msm_audio_calibration.h"
+
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_PLATFORM
+#include <log_utils.h>
+#endif
 
 #define SOUND_TRIGGER_DEVICE_HANDSET_MONO_LOW_POWER_ACDB_ID (100)
 #define MAX_MIXER_XML_PATH  100
-#define MIXER_XML_PATH_QRD_SKUH "/system/etc/mixer_paths_qrd_skuh.xml"
-#define MIXER_XML_PATH_QRD_SKUI "/system/etc/mixer_paths_qrd_skui.xml"
-#define MIXER_XML_PATH_QRD_SKUHF "/system/etc/mixer_paths_qrd_skuhf.xml"
-#define MIXER_XML_PATH_SKUK "/system/etc/mixer_paths_skuk.xml"
-#define MIXER_XML_PATH_SKUA "/system/etc/mixer_paths_skua.xml"
-#define MIXER_XML_PATH_SKUC "/system/etc/mixer_paths_skuc.xml"
-#define MIXER_XML_PATH_SKUE "/system/etc/mixer_paths_skue.xml"
-#define MIXER_XML_PATH_SKUL "/system/etc/mixer_paths_skul.xml"
-#define MIXER_XML_PATH_SKUS "/system/etc/mixer_paths_skus.xml"
-#define MIXER_XML_PATH_SKUSH "/system/etc/mixer_paths_skush.xml"
-#define MIXER_XML_PATH_QRD_SKUT "/system/etc/mixer_paths_qrd_skut.xml"
-#define MIXER_XML_PATH_SKUM "/system/etc/mixer_paths_qrd_skum.xml"
-#define MIXER_XML_PATH_SKU1 "/system/etc/mixer_paths_qrd_sku1.xml"
-#define MIXER_XML_PATH_SKUN_CAJON "/system/etc/mixer_paths_qrd_skun_cajon.xml"
-#define MIXER_XML_PATH_SKU3 "/system/etc/mixer_paths_qrd_sku3.xml"
-#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
-#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
-#define MIXER_XML_PATH_I2S "/system/etc/mixer_paths_i2s.xml"
-#define MIXER_XML_PATH_WCD9306 "/system/etc/mixer_paths_wcd9306.xml"
-#define MIXER_XML_PATH_WCD9330 "/system/etc/mixer_paths_wcd9330.xml"
-#define MIXER_XML_PATH_WCD9340 "/system/etc/mixer_paths_wcd9340.xml"
+#define MIXER_XML_PATH_QRD_SKUH "/vendor/etc/mixer_paths_qrd_skuh.xml"
+#define MIXER_XML_PATH_QRD_SKUI "/vendor/etc/mixer_paths_qrd_skui.xml"
+#define MIXER_XML_PATH_QRD_SKUHF "/vendor/etc/mixer_paths_qrd_skuhf.xml"
+#define MIXER_XML_PATH_SKUK "/vendor/etc/mixer_paths_skuk.xml"
+#define MIXER_XML_PATH_SKUA "/vendor/etc/mixer_paths_skua.xml"
+#define MIXER_XML_PATH_SKUC "/vendor/etc/mixer_paths_skuc.xml"
+#define MIXER_XML_PATH_SKUE "/vendor/etc/mixer_paths_skue.xml"
+#define MIXER_XML_PATH_SKUL "/vendor/etc/mixer_paths_skul.xml"
+#define MIXER_XML_PATH_SKUS "/vendor/etc/mixer_paths_skus.xml"
+#define MIXER_XML_PATH_SKUSH "/vendor/etc/mixer_paths_skush.xml"
+#define MIXER_XML_PATH_QRD_SKUT "/vendor/etc/mixer_paths_qrd_skut.xml"
+#define MIXER_XML_PATH_SKUM "/vendor/etc/mixer_paths_qrd_skum.xml"
+#define MIXER_XML_PATH_SKU1 "/vendor/etc/mixer_paths_qrd_sku1.xml"
+#define MIXER_XML_PATH_SKUN_CAJON "/vendor/etc/mixer_paths_qrd_skun_cajon.xml"
+#define MIXER_XML_PATH_SKU3 "/vendor/etc/mixer_paths_qrd_sku3.xml"
+#define MIXER_XML_PATH_AUXPCM "/vendor/etc/mixer_paths_auxpcm.xml"
+#define MIXER_XML_PATH_AUXPCM "/vendor/etc/mixer_paths_auxpcm.xml"
+#define MIXER_XML_PATH_I2S "/vendor/etc/mixer_paths_i2s.xml"
+#define MIXER_XML_PATH_WCD9306 "/vendor/etc/mixer_paths_wcd9306.xml"
+#define MIXER_XML_PATH_WCD9330 "/vendor/etc/mixer_paths_wcd9330.xml"
+#define MIXER_XML_PATH_WCD9340 "/vendor/etc/mixer_paths_wcd9340.xml"
 #ifdef LINUX_ENABLED
 /* For LE platforms */
 #define MIXER_XML_PATH "/etc/mixer_paths.xml"
@@ -79,22 +85,22 @@
 #define MIXER_XML_PATH_WCD9335_I2S "/etc/mixer_paths_wcd9335_i2s.xml"
 #define MIXER_XML_PATH_SBC "/etc/mixer_paths_sbc.xml"
 #else
-#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
-#define MIXER_XML_PATH_MSM8909_PM8916 "/system/etc/mixer_paths_msm8909_pm8916.xml"
-#define MIXER_XML_PATH_MTP "/system/etc/mixer_paths_mtp.xml"
-#define MIXER_XML_PATH_SKU2 "/system/etc/mixer_paths_qrd_sku2.xml"
-#define PLATFORM_INFO_XML_PATH_EXTCODEC  "/system/etc/audio_platform_info_extcodec.xml"
-#define PLATFORM_INFO_XML_PATH_SKUSH "/system/etc/audio_platform_info_skush.xml"
-#define MIXER_XML_PATH_WCD9326 "/system/etc/mixer_paths_wcd9326.xml"
-#define MIXER_XML_PATH_WCD9335 "/system/etc/mixer_paths_wcd9335.xml"
-#define MIXER_XML_PATH_SKUN "/system/etc/mixer_paths_qrd_skun.xml"
-#define PLATFORM_INFO_XML_PATH      "/system/etc/audio_platform_info.xml"
-#define MIXER_XML_PATH_WCD9326_I2S "/system/etc/mixer_paths_wcd9326_i2s.xml"
-#define MIXER_XML_PATH_WCD9330_I2S "/system/etc/mixer_paths_wcd9330_i2s.xml"
-#define MIXER_XML_PATH_WCD9335_I2S "/system/etc/mixer_paths_wcd9335_i2s.xml"
-#define MIXER_XML_PATH_SBC "/system/etc/mixer_paths_sbc.xml"
+#define MIXER_XML_PATH "/vendor/etc/mixer_paths.xml"
+#define MIXER_XML_PATH_MSM8909_PM8916 "/vendor/etc/mixer_paths_msm8909_pm8916.xml"
+#define MIXER_XML_PATH_MTP "/vendor/etc/mixer_paths_mtp.xml"
+#define MIXER_XML_PATH_SKU2 "/vendor/etc/mixer_paths_qrd_sku2.xml"
+#define PLATFORM_INFO_XML_PATH_EXTCODEC  "/vendor/etc/audio_platform_info_extcodec.xml"
+#define PLATFORM_INFO_XML_PATH_SKUSH "/vendor/etc/audio_platform_info_skush.xml"
+#define MIXER_XML_PATH_WCD9326 "/vendor/etc/mixer_paths_wcd9326.xml"
+#define MIXER_XML_PATH_WCD9335 "/vendor/etc/mixer_paths_wcd9335.xml"
+#define MIXER_XML_PATH_SKUN "/vendor/etc/mixer_paths_qrd_skun.xml"
+#define PLATFORM_INFO_XML_PATH      "/vendor/etc/audio_platform_info.xml"
+#define MIXER_XML_PATH_WCD9326_I2S "/vendor/etc/mixer_paths_wcd9326_i2s.xml"
+#define MIXER_XML_PATH_WCD9330_I2S "/vendor/etc/mixer_paths_wcd9330_i2s.xml"
+#define MIXER_XML_PATH_WCD9335_I2S "/vendor/etc/mixer_paths_wcd9335_i2s.xml"
+#define MIXER_XML_PATH_SBC "/vendor/etc/mixer_paths_sbc.xml"
 #endif
-#define MIXER_XML_PATH_SKUN "/system/etc/mixer_paths_qrd_skun.xml"
+#define MIXER_XML_PATH_SKUN "/vendor/etc/mixer_paths_qrd_skun.xml"
 
 #define LIB_ACDB_LOADER "libacdbloader.so"
 #define CVD_VERSION_MIXER_CTL "CVD Version"
@@ -132,11 +138,6 @@
 #define DEFAULT_APP_TYPE_RX_PATH  0x11130
 #define DEFAULT_APP_TYPE_TX_PATH 0x11132
 
-/* Retry for delay in FW loading*/
-#define RETRY_NUMBER 20
-#define RETRY_US 500000
-#define MAX_SND_CARD 8
-
 #define SAMPLE_RATE_8KHZ  8000
 #define SAMPLE_RATE_16KHZ 16000
 
@@ -178,6 +179,11 @@
 
 static char *default_rx_backend = NULL;
 
+#ifdef DYNAMIC_LOG_ENABLED
+extern void log_utils_init(void);
+extern void log_utils_deinit(void);
+#endif
+
 char dsp_only_decoders_mime[][MAX_MIME_TYPE_LENGTH] = {
     "audio/x-ms-wma" /* wma*/ ,
     "audio/x-ms-wma-lossless" /* wma lossless */ ,
@@ -217,24 +223,7 @@
     CAL_MODE_RTAC           = 0x4
 };
 
-/* Audio calibration related functions */
-typedef void (*acdb_deallocate_t)();
-typedef int  (*acdb_init_t)(const char *, char *, int);
-typedef int  (*acdb_init_v3_t)(const char *, char *, struct listnode *);
-typedef void (*acdb_send_audio_cal_t)(int, int, int , int);
-typedef void (*acdb_send_audio_cal_v3_t)(int, int, int, int, int);
-typedef void (*acdb_send_voice_cal_t)(int, int);
-typedef int (*acdb_reload_vocvoltable_t)(int);
-typedef int  (*acdb_get_default_app_type_t)(void);
-typedef int (*acdb_loader_get_calibration_t)(char *attr, int size, void *data);
 acdb_loader_get_calibration_t acdb_loader_get_calibration;
-typedef int (*acdb_set_audio_cal_t) (void *, void *, uint32_t);
-typedef int (*acdb_get_audio_cal_t) (void *, void *, uint32_t*);
-typedef int (*acdb_send_common_top_t) (void);
-typedef int (*acdb_set_codec_data_t) (void *, char *);
-typedef int (*acdb_reload_t) (char *, char *, char *, int);
-typedef int (*acdb_send_gain_dep_cal_t)(int, int, int, int, int);
-typedef int (*acdb_reload_v2_t) (char *, char *, char *, struct listnode *);
 
 typedef struct codec_backend_cfg {
     uint32_t sample_rate;
@@ -248,12 +237,6 @@
 static native_audio_prop na_props = {0, 0, NATIVE_AUDIO_MODE_INVALID};
 static bool supports_true_32_bit = false;
 
-struct meta_key_list {
-    struct listnode list;
-    struct audio_cal_info_metainfo cal_info;
-    char name[ACDB_METAINFO_KEY_MODULE_NAME_LEN];
-};
-
 static int max_be_dai_names = 0;
 static const struct be_dai_name_struct *be_dai_name_table;
 
@@ -2061,7 +2044,7 @@
 {
     char value[PROPERTY_VALUE_MAX];
     struct platform_data *my_data = NULL;
-    int retry_num = 0, snd_card_num = 0;
+    int snd_card_num = 0;
     const char *snd_card_name;
     char mixer_xml_path[MAX_MIXER_XML_PATH],ffspEnable[PROPERTY_VALUE_MAX];
     const char *mixer_ctl_name = "Set HPX ActiveBe";
@@ -2070,6 +2053,25 @@
     int wsaCount =0;
     bool is_wsa_combo_supported = false;
 
+    snd_card_num = audio_extn_utils_get_snd_card_num();
+    if(snd_card_num < 0) {
+        ALOGE("%s: Unable to find correct sound card", __func__);
+        return NULL;
+    }
+
+    adev->snd_card = snd_card_num;
+    ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
+
+    adev->mixer = mixer_open(snd_card_num);
+    if (!adev->mixer) {
+        ALOGE("%s: Unable to open the mixer card: %d", __func__,
+               snd_card_num);
+        return NULL;
+    }
+
+    snd_card_name = mixer_get_name(adev->mixer);
+    ALOGD("%s: snd_card_name: %s", __func__, snd_card_name);
+
     my_data = calloc(1, sizeof(struct platform_data));
 
     if (!my_data) {
@@ -2077,62 +2079,31 @@
         return NULL;
     }
 
-    while (snd_card_num < MAX_SND_CARD) {
-        adev->mixer = mixer_open(snd_card_num);
-
-        while (!adev->mixer && retry_num < RETRY_NUMBER) {
-            usleep(RETRY_US);
-            adev->mixer = mixer_open(snd_card_num);
-            retry_num++;
-        }
-
-        if (!adev->mixer) {
-            ALOGE("%s: Unable to open the mixer card: %d", __func__,
-                   snd_card_num);
-            retry_num = 0;
-            snd_card_num++;
-            continue;
-        }
-
-        snd_card_name = mixer_get_name(adev->mixer);
-        ALOGD("%s: snd_card_name: %s", __func__, snd_card_name);
-
-        my_data->hw_info = hw_info_init(snd_card_name);
-        if (!my_data->hw_info) {
-            ALOGE("%s: Failed to init hardware info", __func__);
-        } else {
-            query_platform(snd_card_name, mixer_xml_path);
-            ALOGD("%s: mixer path file is %s", __func__,
-                                    mixer_xml_path);
-            if (audio_extn_read_xml(adev, snd_card_num, mixer_xml_path,
-                                    MIXER_XML_PATH_AUXPCM) == -ENOSYS) {
-                adev->audio_route = audio_route_init(snd_card_num,
-                                                 mixer_xml_path);
-            }
-            if (!adev->audio_route) {
-                ALOGE("%s: Failed to init audio route controls, aborting.",
-                       __func__);
-                free(my_data);
-                mixer_close(adev->mixer);
-                return NULL;
-            }
-            adev->snd_card = snd_card_num;
-            update_codec_type(snd_card_name);
-            update_interface(snd_card_name);
-            ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
-            break;
-        }
-        retry_num = 0;
-        snd_card_num++;
-        mixer_close(adev->mixer);
-    }
-
-    if (snd_card_num >= MAX_SND_CARD) {
-        ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
+    my_data->hw_info = hw_info_init(snd_card_name);
+    if (!my_data->hw_info) {
+        ALOGE("%s: Failed to init hardware info", __func__);
         free(my_data);
         return NULL;
     }
 
+    query_platform(snd_card_name, mixer_xml_path);
+    ALOGD("%s: mixer path file is %s", __func__,
+                            mixer_xml_path);
+    if (audio_extn_read_xml(adev, snd_card_num, mixer_xml_path,
+                            MIXER_XML_PATH_AUXPCM) == -ENOSYS) {
+        adev->audio_route = audio_route_init(snd_card_num,
+                                         mixer_xml_path);
+    }
+    if (!adev->audio_route) {
+        ALOGE("%s: Failed to init audio route controls, aborting.",
+               __func__);
+        free(my_data);
+        mixer_close(adev->mixer);
+        return NULL;
+    }
+    update_codec_type(snd_card_name);
+    update_interface(snd_card_name);
+
     my_data->adev = adev;
     my_data->fluence_in_spkr_mode = false;
     my_data->fluence_in_voice_call = false;
@@ -2239,12 +2210,12 @@
 
     /* Initialize ACDB and PCM ID's */
     if (is_external_codec)
-        platform_info_init(PLATFORM_INFO_XML_PATH_EXTCODEC, my_data);
+        platform_info_init(PLATFORM_INFO_XML_PATH_EXTCODEC, my_data, PLATFORM);
     else if (!strncmp(snd_card_name, "sdm660-snd-card-skush",
                sizeof("sdm660-snd-card-skush")))
-        platform_info_init(PLATFORM_INFO_XML_PATH_SKUSH, my_data);
+        platform_info_init(PLATFORM_INFO_XML_PATH_SKUSH, my_data, PLATFORM);
     else
-        platform_info_init(PLATFORM_INFO_XML_PATH, my_data);
+        platform_info_init(PLATFORM_INFO_XML_PATH, my_data, PLATFORM);
 
     my_data->voice_feature_set = VOICE_FEATURE_SET_DEFAULT;
     my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
@@ -2347,10 +2318,20 @@
             goto acdb_init_fail;
         }
 
-        platform_acdb_init(my_data);
+        int result = acdb_init(adev->snd_card);
+        if (!result) {
+            my_data->is_acdb_initialized = true;
+            ALOGD("ACDB initialized");
+            audio_hwdep_send_cal(my_data);
+        } else {
+            my_data->is_acdb_initialized = false;
+            ALOGD("ACDB initialization failed");
+        }
     }
     audio_extn_pm_vote();
-
+#ifdef DYNAMIC_LOG_ENABLED
+    log_utils_init();
+#endif
     /* Configure active back end for HPX*/
     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
     if (ctl) {
@@ -2586,6 +2567,9 @@
     /* deinit usb */
     audio_extn_usb_deinit();
     audio_extn_dap_hal_deinit();
+#ifdef DYNAMIC_LOG_ENABLED
+    log_utils_deinit();
+#endif
 }
 
 static int platform_is_acdb_initialized(void *platform)
@@ -5465,11 +5449,12 @@
 
         if ((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
             (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC) ||
-            (usecase->stream.out->format == AUDIO_FORMAT_DOLBY_TRUEHD))
-            sample_rate = sample_rate * 4 ;
+            (usecase->stream.out->format == AUDIO_FORMAT_DOLBY_TRUEHD)) {
 
-        if (!edid_is_supported_sr(edid_info, sample_rate))
-                sample_rate = edid_get_highest_supported_sr(edid_info);
+            sample_rate = sample_rate * 4;
+            if (sample_rate > HDMI_PASSTHROUGH_MAX_SAMPLE_RATE)
+                sample_rate = HDMI_PASSTHROUGH_MAX_SAMPLE_RATE;
+        }
 
         bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
         /* We force route so that the BE format can be set to Compr */
@@ -5944,6 +5929,27 @@
     return ret;
 }
 
+const char *platform_get_snd_device_backend_interface(snd_device_t device)
+{
+    const char *hw_interface_name = NULL;
+
+    if ((device < SND_DEVICE_MIN) || (device >= SND_DEVICE_MAX)) {
+        ALOGE("%s: Invalid snd_device = %d",
+            __func__, device);
+        goto done;
+    }
+
+    /* Get string value of necessary backend for device */
+    hw_interface_name = hw_interface_table[device];
+    if (hw_interface_name == NULL)
+        ALOGE("%s: no hw_interface set for device %d\n", __func__, device);
+    else
+        ALOGD("%s: hw_interface set for device %s\n", __func__, hw_interface_name);
+done:
+    return hw_interface_name;
+}
+
+
 int platform_get_snd_device_backend_index(snd_device_t device)
 {
     int i, be_dai_id;
@@ -6013,94 +6019,101 @@
      *device_to_be_id = (int*) msm_device_to_be_id;
      *length = msm_be_id_array_len;
 }
-int platform_set_stream_channel_map(void *platform, audio_channel_mask_t channel_mask, int snd_id)
+
+int platform_set_stream_channel_map(void *platform, audio_channel_mask_t channel_mask,
+                                               int snd_id, uint8_t *input_channel_map)
 {
-    int ret = 0;
+    int ret = 0, i = 0;
     int channels = audio_channel_count_from_out_mask(channel_mask);
 
-    char channel_map[8];
+    char channel_map[AUDIO_CHANNEL_COUNT_MAX];
     memset(channel_map, 0, sizeof(channel_map));
-    /* Following are all most common standard WAV channel layouts
-       overridden by channel mask if its allowed and different */
-    switch (channels) {
-        case 1:
-            /* AUDIO_CHANNEL_OUT_MONO */
-            channel_map[0] = PCM_CHANNEL_FC;
-            break;
-        case 2:
-            /* AUDIO_CHANNEL_OUT_STEREO */
-            channel_map[0] = PCM_CHANNEL_FL;
-            channel_map[1] = PCM_CHANNEL_FR;
-            break;
-        case 3:
-            /* AUDIO_CHANNEL_OUT_2POINT1 */
-            channel_map[0] = PCM_CHANNEL_FL;
-            channel_map[1] = PCM_CHANNEL_FR;
-            channel_map[2] = PCM_CHANNEL_FC;
-            break;
-        case 4:
-            /* AUDIO_CHANNEL_OUT_QUAD_SIDE */
-            channel_map[0] = PCM_CHANNEL_FL;
-            channel_map[1] = PCM_CHANNEL_FR;
-            channel_map[2] = PCM_CHANNEL_LS;
-            channel_map[3] = PCM_CHANNEL_RS;
-            if (channel_mask == AUDIO_CHANNEL_OUT_QUAD_BACK)
-            {
-                channel_map[2] = PCM_CHANNEL_LB;
-                channel_map[3] = PCM_CHANNEL_RB;
-            }
-            if (channel_mask == AUDIO_CHANNEL_OUT_SURROUND)
-            {
+    if (*input_channel_map) {
+        for (i = 0; i < channels; i++) {
+             ALOGV("%s:: Channel Map channel_map[%d] - %d", __func__, i, *input_channel_map);
+             channel_map[i] = *input_channel_map;
+             input_channel_map++;
+        }
+    } else {
+        /* Following are all most common standard WAV channel layouts
+           overridden by channel mask if its allowed and different */
+        switch (channels) {
+            case 1:
+                /* AUDIO_CHANNEL_OUT_MONO */
+                channel_map[0] = PCM_CHANNEL_FC;
+                break;
+            case 2:
+                /* AUDIO_CHANNEL_OUT_STEREO */
+                channel_map[0] = PCM_CHANNEL_FL;
+                channel_map[1] = PCM_CHANNEL_FR;
+                break;
+            case 3:
+                /* AUDIO_CHANNEL_OUT_2POINT1 */
+                channel_map[0] = PCM_CHANNEL_FL;
+                channel_map[1] = PCM_CHANNEL_FR;
                 channel_map[2] = PCM_CHANNEL_FC;
-                channel_map[3] = PCM_CHANNEL_CS;
-            }
-            break;
-        case 5:
-            /* AUDIO_CHANNEL_OUT_PENTA */
-            channel_map[0] = PCM_CHANNEL_FL;
-            channel_map[1] = PCM_CHANNEL_FR;
-            channel_map[2] = PCM_CHANNEL_FC;
-            channel_map[3] = PCM_CHANNEL_LB;
-            channel_map[4] = PCM_CHANNEL_RB;
-            break;
-        case 6:
-            /* AUDIO_CHANNEL_OUT_5POINT1 */
-            channel_map[0] = PCM_CHANNEL_FL;
-            channel_map[1] = PCM_CHANNEL_FR;
-            channel_map[2] = PCM_CHANNEL_FC;
-            channel_map[3] = PCM_CHANNEL_LFE;
-            channel_map[4] = PCM_CHANNEL_LB;
-            channel_map[5] = PCM_CHANNEL_RB;
-            if (channel_mask == AUDIO_CHANNEL_OUT_5POINT1_SIDE)
-            {
-                channel_map[4] = PCM_CHANNEL_LS;
-                channel_map[5] = PCM_CHANNEL_RS;
-            }
-            break;
-        case 7:
-            /* AUDIO_CHANNEL_OUT_6POINT1 */
-            channel_map[0] = PCM_CHANNEL_FL;
-            channel_map[1] = PCM_CHANNEL_FR;
-            channel_map[2] = PCM_CHANNEL_FC;
-            channel_map[3] = PCM_CHANNEL_LFE;
-            channel_map[4] = PCM_CHANNEL_LB;
-            channel_map[5] = PCM_CHANNEL_RB;
-            channel_map[6] = PCM_CHANNEL_CS;
-            break;
-        case 8:
-            /* AUDIO_CHANNEL_OUT_7POINT1 */
-            channel_map[0] = PCM_CHANNEL_FL;
-            channel_map[1] = PCM_CHANNEL_FR;
-            channel_map[2] = PCM_CHANNEL_FC;
-            channel_map[3] = PCM_CHANNEL_LFE;
-            channel_map[4] = PCM_CHANNEL_LB;
-            channel_map[5] = PCM_CHANNEL_RB;
-            channel_map[6] = PCM_CHANNEL_LS;
-            channel_map[7] = PCM_CHANNEL_RS;
-            break;
-        default:
-            ALOGE("unsupported channels %d for setting channel map", channels);
-            return -1;
+                break;
+            case 4:
+                /* AUDIO_CHANNEL_OUT_QUAD_SIDE */
+                channel_map[0] = PCM_CHANNEL_FL;
+                channel_map[1] = PCM_CHANNEL_FR;
+                channel_map[2] = PCM_CHANNEL_LS;
+                channel_map[3] = PCM_CHANNEL_RS;
+                if (channel_mask == AUDIO_CHANNEL_OUT_QUAD_BACK) {
+                    channel_map[2] = PCM_CHANNEL_LB;
+                    channel_map[3] = PCM_CHANNEL_RB;
+                }
+                if (channel_mask == AUDIO_CHANNEL_OUT_SURROUND) {
+                    channel_map[2] = PCM_CHANNEL_FC;
+                    channel_map[3] = PCM_CHANNEL_CS;
+                }
+                break;
+            case 5:
+                /* AUDIO_CHANNEL_OUT_PENTA */
+                channel_map[0] = PCM_CHANNEL_FL;
+                channel_map[1] = PCM_CHANNEL_FR;
+                channel_map[2] = PCM_CHANNEL_FC;
+                channel_map[3] = PCM_CHANNEL_LB;
+                channel_map[4] = PCM_CHANNEL_RB;
+                break;
+            case 6:
+                /* AUDIO_CHANNEL_OUT_5POINT1 */
+                channel_map[0] = PCM_CHANNEL_FL;
+                channel_map[1] = PCM_CHANNEL_FR;
+                channel_map[2] = PCM_CHANNEL_FC;
+                channel_map[3] = PCM_CHANNEL_LFE;
+                channel_map[4] = PCM_CHANNEL_LB;
+                channel_map[5] = PCM_CHANNEL_RB;
+                if (channel_mask == AUDIO_CHANNEL_OUT_5POINT1_SIDE) {
+                    channel_map[4] = PCM_CHANNEL_LS;
+                    channel_map[5] = PCM_CHANNEL_RS;
+                }
+                break;
+            case 7:
+                /* AUDIO_CHANNEL_OUT_6POINT1 */
+                channel_map[0] = PCM_CHANNEL_FL;
+                channel_map[1] = PCM_CHANNEL_FR;
+                channel_map[2] = PCM_CHANNEL_FC;
+                channel_map[3] = PCM_CHANNEL_LFE;
+                channel_map[4] = PCM_CHANNEL_LB;
+                channel_map[5] = PCM_CHANNEL_RB;
+                channel_map[6] = PCM_CHANNEL_CS;
+                break;
+            case 8:
+                /* AUDIO_CHANNEL_OUT_7POINT1 */
+                channel_map[0] = PCM_CHANNEL_FL;
+                channel_map[1] = PCM_CHANNEL_FR;
+                channel_map[2] = PCM_CHANNEL_FC;
+                channel_map[3] = PCM_CHANNEL_LFE;
+                channel_map[4] = PCM_CHANNEL_LB;
+                channel_map[5] = PCM_CHANNEL_RB;
+                channel_map[6] = PCM_CHANNEL_LS;
+                channel_map[7] = PCM_CHANNEL_RS;
+                break;
+            default:
+                ALOGE("unsupported channels %d for setting channel map", channels);
+                return -1;
+        }
     }
     ret = platform_set_channel_map(platform, channels, channel_map, snd_id);
     return ret;
@@ -6327,9 +6340,13 @@
         ALOGV("%s:PCM", __func__);
         format = LPCM;
         break;
+    case AUDIO_FORMAT_IEC61937:
+        ALOGV("%s:IEC61937", __func__);
+        format = 0;
+        break;
     default:
         format =  -1;
-        ALOGE("%s:invalid format:%d", __func__,format);
+        ALOGE("%s:invalid format:0x%x", __func__, audio_format);
         break;
     }
     return format;
@@ -6372,6 +6389,9 @@
     int i, ret;
     unsigned char format_id = platform_map_to_edid_format(format);
 
+    if (format == AUDIO_FORMAT_IEC61937)
+        return true;
+
     if (format_id <= 0) {
         ALOGE("%s invalid edid format mappting for :%x" ,__func__, format);
         return false;
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index 76f9d78..28fe62b 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -392,7 +392,10 @@
     LEGACY_PCM = 0,
     PASSTHROUGH,
     PASSTHROUGH_CONVERT,
-    PASSTHROUGH_DSD
+    PASSTHROUGH_DSD,
+    LISTEN,
+    PASSTHROUGH_GEN,
+    PASSTHROUGH_IEC61937
 };
 /*
  * ID for setting mute and lateny on the device side
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index c2ffd4a..3d50488 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1148,7 +1148,8 @@
 
 int platform_set_stream_channel_map(void *platform __unused,
                                     audio_channel_mask_t channel_mask __unused,
-                                    int snd_id __unused)
+                                    int snd_id __unused
+                                    uint8_t *input_channel_map __unused)
 {
     return -ENOSYS;
 }
diff --git a/hal/msm8974/hw_info.c b/hal/msm8974/hw_info.c
index dd74877..1187f4b 100644
--- a/hal/msm8974/hw_info.c
+++ b/hal/msm8974/hw_info.c
@@ -39,6 +39,11 @@
 #include "platform.h"
 #include "platform_api.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_HW_INFO
+#include <log_utils.h>
+#endif
 
 struct hardware_info {
     char name[HW_INFO_ARRAY_MAX_SIZE];
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 47fce0e..f4d1b03 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -38,11 +38,17 @@
 #include <platform_api.h>
 #include "platform.h"
 #include "audio_extn.h"
+#include "acdb.h"
 #include "voice_extn.h"
 #include "edid.h"
 #include "sound/compress_params.h"
 #include "sound/msmcal-hwdep.h"
-#include <linux/msm_audio_calibration.h>
+
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_PLATFORM
+#include <log_utils.h>
+#endif
 
 #define SOUND_TRIGGER_DEVICE_HANDSET_MONO_LOW_POWER_ACDB_ID (100)
 #define MIXER_FILE_DELIMITER "_"
@@ -56,12 +62,12 @@
 #define MIXER_XML_PATH_I2S "/etc/mixer_paths_i2s.xml"
 #define PLATFORM_INFO_XML_PATH_I2S "/etc/audio_platform_info_i2s.xml"
 #else
-#define MIXER_XML_BASE_STRING "/system/etc/mixer_paths"
-#define MIXER_XML_DEFAULT_PATH "/system/etc/mixer_paths.xml"
-#define PLATFORM_INFO_XML_PATH "/system/etc/audio_platform_info.xml"
-#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
-#define MIXER_XML_PATH_I2S "/system/etc/mixer_paths_i2s.xml"
-#define PLATFORM_INFO_XML_PATH_I2S "/system/etc/audio_platform_info_i2s.xml"
+#define MIXER_XML_BASE_STRING "/vendor/etc/mixer_paths"
+#define MIXER_XML_DEFAULT_PATH "/vendor/etc/mixer_paths.xml"
+#define PLATFORM_INFO_XML_PATH "/vendor/etc/audio_platform_info.xml"
+#define MIXER_XML_PATH_AUXPCM "/vendor/etc/mixer_paths_auxpcm.xml"
+#define MIXER_XML_PATH_I2S "/vendor/etc/mixer_paths_i2s.xml"
+#define PLATFORM_INFO_XML_PATH_I2S "/vendor/etc/audio_platform_info_i2s.xml"
 #endif
 
 #include <linux/msm_audio.h>
@@ -103,11 +109,6 @@
 #define DEFAULT_APP_TYPE_RX_PATH  0x11130
 #define DEFAULT_APP_TYPE_TX_PATH  0x11132
 
-/* Retry for delay in FW loading*/
-#define RETRY_NUMBER 10
-#define RETRY_US 500000
-#define MAX_SND_CARD 8
-
 #define SAMPLE_RATE_8KHZ  8000
 #define SAMPLE_RATE_16KHZ 16000
 
@@ -139,6 +140,11 @@
 #define MAX_CAL_NAME 20
 #define MAX_MIME_TYPE_LENGTH 30
 
+#ifdef DYNAMIC_LOG_ENABLED
+extern void log_utils_init(void);
+extern void log_utils_deinit(void);
+#endif
+
 char cal_name_info[WCD9XXX_MAX_CAL][MAX_CAL_NAME] = {
         [WCD9XXX_ANC_CAL] = "anc_cal",
         [WCD9XXX_MBHC_CAL] = "mbhc_cal",
@@ -187,23 +193,7 @@
     CAL_MODE_RTAC           = 0x4
 };
 
-/* Audio calibration related functions */
-typedef void (*acdb_deallocate_t)();
-typedef int  (*acdb_init_t)(const char *, char *, int);
-typedef int  (*acdb_init_v3_t)(const char *, char *, struct listnode *);
-typedef void (*acdb_send_audio_cal_t)(int, int, int , int);
-typedef void (*acdb_send_audio_cal_v3_t)(int, int, int, int, int);
-typedef void (*acdb_send_voice_cal_t)(int, int);
-typedef int (*acdb_reload_vocvoltable_t)(int);
-typedef int  (*acdb_get_default_app_type_t)(void);
-typedef int (*acdb_loader_get_calibration_t)(char *attr, int size, void *data);
 acdb_loader_get_calibration_t acdb_loader_get_calibration;
-typedef int (*acdb_set_audio_cal_t) (void *, void *, uint32_t);
-typedef int (*acdb_get_audio_cal_t) (void *, void *, uint32_t*);
-typedef int (*acdb_send_common_top_t) (void);
-typedef int (*acdb_set_codec_data_t) (void *, char *);
-typedef int (*acdb_reload_t) (char *, char *, char *, int);
-typedef int (*acdb_reload_v2_t) (char *, char *, char *, struct listnode *);
 
 typedef struct codec_backend_cfg {
     uint32_t sample_rate;
@@ -216,13 +206,6 @@
 
 static native_audio_prop na_props = {0, 0, NATIVE_AUDIO_MODE_INVALID};
 static bool supports_true_32_bit = false;
-typedef int (*acdb_send_gain_dep_cal_t)(int, int, int, int, int);
-
-struct meta_key_list {
-    struct listnode list;
-    struct audio_cal_info_metainfo cal_info;
-    char name[ACDB_METAINFO_KEY_MODULE_NAME_LEN];
-};
 
 static int max_be_dai_names = 0;
 static const struct be_dai_name_struct *be_dai_name_table;
@@ -399,6 +382,8 @@
     [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_AFE_PROXY] = "afe-proxy",
     [SND_DEVICE_OUT_USB_HEADSET] = "usb-headset",
@@ -458,6 +443,8 @@
     [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",
+    [SND_DEVICE_IN_VOICE_TTY_FULL_USB_MIC] = "voice-tty-full-usb-mic",
+    [SND_DEVICE_IN_VOICE_TTY_HCO_USB_MIC] = "voice-tty-hco-usb-mic",
     [SND_DEVICE_IN_VOICE_RX] = "voice-rx",
 
     [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
@@ -535,6 +522,8 @@
     [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_AFE_PROXY] = 0,
     [SND_DEVICE_OUT_USB_HEADSET] = 45,
@@ -589,6 +578,8 @@
     [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
     [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36,
     [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16,
+    [SND_DEVICE_IN_VOICE_TTY_FULL_USB_MIC] = 16,
+    [SND_DEVICE_IN_VOICE_TTY_HCO_USB_MIC] = 16,
     [SND_DEVICE_IN_VOICE_RX] = 44,
 
     [SND_DEVICE_IN_VOICE_REC_MIC] = 4,
@@ -666,6 +657,8 @@
     {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)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_USB)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_USB)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_AFE_PROXY)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_USB_HEADSET)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_USB_HEADPHONES)},
@@ -719,6 +712,8 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_USB_MIC)},
+    {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_DMIC_STEREO)},
@@ -1752,125 +1747,109 @@
     char baseband[PROPERTY_VALUE_MAX];
     char value[PROPERTY_VALUE_MAX];
     struct platform_data *my_data = NULL;
-    int retry_num = 0, snd_card_num = 0;
     char *snd_card_name = NULL, *snd_card_name_t = NULL;
     char *snd_internal_name = NULL;
     char *tmp = NULL;
     char mixer_xml_file[MIXER_PATH_MAX_LENGTH]= {0};
     int idx;
 
-    my_data = calloc(1, sizeof(struct platform_data));
+    adev->snd_card = audio_extn_utils_get_snd_card_num();
+    if (adev->snd_card < 0) {
+        ALOGE("%s: Unable to find correct sound card", __func__);
+        return NULL;
+    }
+    ALOGD("%s: Opened sound card:%d", __func__, adev->snd_card);
 
-    if (!my_data) {
-        ALOGE("failed to allocate platform data");
+    adev->mixer = mixer_open(adev->snd_card);
+    if (!adev->mixer) {
+        ALOGE("%s: Unable to open the mixer card: %d", __func__,
+               adev->snd_card);
         return NULL;
     }
 
-    while (snd_card_num < MAX_SND_CARD) {
-        adev->mixer = mixer_open(snd_card_num);
-
-        while (!adev->mixer && retry_num < RETRY_NUMBER) {
-            usleep(RETRY_US);
-            adev->mixer = mixer_open(snd_card_num);
-            retry_num++;
-        }
-
-        if (!adev->mixer) {
-            ALOGE("%s: Unable to open the mixer card: %d", __func__,
-                   snd_card_num);
-            retry_num = 0;
-            snd_card_num++;
-            continue;
-        }
-
-        snd_card_name = strdup(mixer_get_name(adev->mixer));
-        if (!snd_card_name) {
-            ALOGE("failed to allocate memory for snd_card_name\n");
-            free(my_data);
-            mixer_close(adev->mixer);
-            return NULL;
-        }
-        ALOGD("%s: snd_card_name: %s", __func__, snd_card_name);
-
-        my_data->hw_info = hw_info_init(snd_card_name);
-        if (!my_data->hw_info) {
-            ALOGE("%s: Failed to init hardware info", __func__);
-        } else {
-            if (platform_is_i2s_ext_modem(snd_card_name, my_data)) {
-                ALOGD("%s: Call MIXER_XML_PATH_I2S", __func__);
-
-                adev->audio_route = audio_route_init(snd_card_num,
-                                                     MIXER_XML_PATH_I2S);
-            } else {
-                /* Get the codec internal name from the sound card name
-                 * and form the mixer paths file name dynamically. This
-                 * is generic way of picking any codec name based mixer
-                 * files in future with no code change. This code
-                 * assumes mixer files are formed with format as
-                 * mixer_paths_internalcodecname.xml
-
-                 * If this dynamically read mixer files fails to open then it
-                 * falls back to default mixer file i.e mixer_paths.xml. This is
-                 * 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);
-
-                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 (F_OK == access(mixer_xml_file, 0)) {
-                    ALOGD("%s: Loading mixer file: %s", __func__, mixer_xml_file);
-                    if (audio_extn_read_xml(adev, snd_card_num, mixer_xml_file,
-                                    MIXER_XML_PATH_AUXPCM) == -ENOSYS)
-                        adev->audio_route = audio_route_init(snd_card_num,
-                                                       mixer_xml_file);
-                } else {
-                    ALOGD("%s: Loading default mixer file", __func__);
-                    if(audio_extn_read_xml(adev, snd_card_num, MIXER_XML_DEFAULT_PATH,
-                                    MIXER_XML_PATH_AUXPCM) == -ENOSYS)
-                        adev->audio_route = audio_route_init(snd_card_num,
-                                                       MIXER_XML_DEFAULT_PATH);
-                }
-            }
-            if (!adev->audio_route) {
-                ALOGE("%s: Failed to init audio route controls, aborting.",
-                       __func__);
-                if (my_data)
-                    free(my_data);
-                if (snd_card_name)
-                    free(snd_card_name);
-                if (snd_card_name_t)
-                    free(snd_card_name_t);
-                mixer_close(adev->mixer);
-                return NULL;
-            }
-            adev->snd_card = snd_card_num;
-            ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
-            break;
-        }
-        retry_num = 0;
-        snd_card_num++;
+    snd_card_name = strdup(mixer_get_name(adev->mixer));
+    if (!snd_card_name) {
+        ALOGE("failed to allocate memory for snd_card_name\n");
         mixer_close(adev->mixer);
+        return NULL;
     }
 
-    if (snd_card_num >= MAX_SND_CARD) {
-        ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
+    my_data = calloc(1, sizeof(struct platform_data));
+    if (!my_data) {
+        ALOGE("failed to allocate platform data");
+        if (snd_card_name)
+            free(snd_card_name);
+        mixer_close(adev->mixer);
+        return NULL;
+    }
+
+    my_data->hw_info = hw_info_init(snd_card_name);
+    if (!my_data->hw_info) {
+        ALOGE("failed to init hw_info");
+        mixer_close(adev->mixer);
+        if (my_data)
+            free(my_data);
+
+        if (snd_card_name)
+            free(snd_card_name);
+        return NULL;
+    }
+
+    if (platform_is_i2s_ext_modem(snd_card_name, my_data)) {
+        ALOGD("%s: Call MIXER_XML_PATH_I2S", __func__);
+
+        adev->audio_route = audio_route_init(adev->snd_card,
+                                             MIXER_XML_PATH_I2S);
+    } else {
+        /* Get the codec internal name from the sound card name
+         * and form the mixer paths file name dynamically. This
+         * is generic way of picking any codec name based mixer
+         * files in future with no code change. This code
+         * assumes mixer files are formed with format as
+         * mixer_paths_internalcodecname.xml
+
+         * If this dynamically read mixer files fails to open then it
+         * falls back to default mixer file i.e mixer_paths.xml. This is
+         * 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);
+
+        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 (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);
+        } 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);
+        }
+    }
+    if (!adev->audio_route) {
+        ALOGE("%s: Failed to init audio route controls, aborting.",
+               __func__);
         if (my_data)
             free(my_data);
         if (snd_card_name)
@@ -1954,9 +1933,9 @@
 
     /* Initialize ACDB ID's */
     if (my_data->is_i2s_ext_modem)
-        platform_info_init(PLATFORM_INFO_XML_PATH_I2S, my_data);
+        platform_info_init(PLATFORM_INFO_XML_PATH_I2S, my_data, PLATFORM);
     else
-        platform_info_init(PLATFORM_INFO_XML_PATH, my_data);
+        platform_info_init(PLATFORM_INFO_XML_PATH, my_data, PLATFORM);
 
     my_data->voice_feature_set = VOICE_FEATURE_SET_DEFAULT;
     my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
@@ -2059,12 +2038,23 @@
             ALOGE("%s: dlsym error %s for acdb_loader_reload_acdb_files", __func__, dlerror());
             goto acdb_init_fail;
         }
-        platform_acdb_init(my_data);
+
+        int result = acdb_init(adev->snd_card);
+        if (!result) {
+            my_data->is_acdb_initialized = true;
+            ALOGD("ACDB initialized");
+            audio_hwdep_send_cal(my_data);
+        } else {
+            my_data->is_acdb_initialized = false;
+            ALOGD("ACDB initialization failed");
+        }
     }
 
     /* init keep-alive for compress passthru */
     audio_extn_keep_alive_init(adev);
-
+#ifdef DYNAMIC_LOG_ENABLED
+    log_utils_init();
+#endif
 acdb_init_fail:
 
 
@@ -2265,6 +2255,9 @@
     /* deinit usb */
     audio_extn_usb_deinit();
     audio_extn_dap_hal_deinit();
+#ifdef DYNAMIC_LOG_ENABLED
+    log_utils_deinit();
+#endif
 }
 
 static int platform_is_acdb_initialized(void *platform)
@@ -3388,6 +3381,24 @@
             } else {
                 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
             }
+        } else if (devices & AUDIO_DEVICE_OUT_USB_DEVICE) {
+            if (voice_is_in_call(adev)) {
+                switch (adev->voice.tty_mode) {
+                    case TTY_MODE_FULL:
+                        snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_USB;
+                        break;
+                    case TTY_MODE_VCO:
+                       snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_USB;
+                        break;
+                    case TTY_MODE_HCO:
+                        // since Hearing will be on handset\speaker, use existing device
+                        snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
+                        break;
+                    default:
+                        ALOGE("%s: Invalid TTY mode (%#x)",
+                              __func__, adev->voice.tty_mode);
+                }
+            }
         } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
             if (adev->bt_wb_speech_enabled)
                 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
@@ -3558,17 +3569,33 @@
                 out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
                 out_device & AUDIO_DEVICE_OUT_LINE) {
                 switch (adev->voice.tty_mode) {
-                case TTY_MODE_FULL:
-                    snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
-                    break;
-                case TTY_MODE_VCO:
-                    snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
-                    break;
-                case TTY_MODE_HCO:
-                    snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
-                    break;
-                default:
-                    ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode);
+                    case TTY_MODE_FULL:
+                        snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
+                        break;
+                    case TTY_MODE_VCO:
+                        snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
+                        break;
+                    case TTY_MODE_HCO:
+                        snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
+                        break;
+                    default:
+                        ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode);
+                }
+                goto exit;
+            } else if (out_device & AUDIO_DEVICE_OUT_USB_DEVICE) {
+                switch (adev->voice.tty_mode) {
+                    case TTY_MODE_FULL:
+                        snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_USB_MIC;
+                        break;
+                    case TTY_MODE_VCO:
+                        // since voice will be captured from handset mic, use existing device
+                        snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
+                        break;
+                    case TTY_MODE_HCO:
+                        snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_USB_MIC;
+                        break;
+                    default:
+                        ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode);
                 }
                 goto exit;
             }
@@ -5183,11 +5210,12 @@
 
         if ((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
             (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC) ||
-            (usecase->stream.out->format == AUDIO_FORMAT_DOLBY_TRUEHD))
-            sample_rate = sample_rate * 4 ;
+            (usecase->stream.out->format == AUDIO_FORMAT_DOLBY_TRUEHD)) {
 
-        if (!edid_is_supported_sr(edid_info, sample_rate))
-                sample_rate = edid_get_highest_supported_sr(edid_info);
+            sample_rate = sample_rate * 4;
+            if (sample_rate > HDMI_PASSTHROUGH_MAX_SAMPLE_RATE)
+                sample_rate = HDMI_PASSTHROUGH_MAX_SAMPLE_RATE;
+        }
 
         bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
         /* We force route so that the BE format can be set to Compr */
@@ -5637,6 +5665,26 @@
     return ret;
 }
 
+const char *platform_get_snd_device_backend_interface(snd_device_t device)
+{
+    const char *hw_interface_name = NULL;
+
+    if ((device < SND_DEVICE_MIN) || (device >= SND_DEVICE_MAX)) {
+        ALOGE("%s: Invalid snd_device = %d",
+            __func__, device);
+        goto done;
+    }
+
+    /* Get string value of necessary backend for device */
+    hw_interface_name = hw_interface_table[device];
+    if (hw_interface_name == NULL)
+        ALOGE("%s: no hw_interface set for device %d\n", __func__, device);
+    else
+        ALOGD("%s: hw_interface set for device %s\n", __func__, hw_interface_name);
+done:
+    return hw_interface_name;
+}
+
 int platform_get_snd_device_backend_index(snd_device_t device)
 {
     int i, be_dai_id;
@@ -5705,94 +5753,101 @@
      *device_to_be_id = (int*) msm_device_to_be_id;
      *length = msm_be_id_array_len;
 }
-int platform_set_stream_channel_map(void *platform, audio_channel_mask_t channel_mask, int snd_id)
+
+int platform_set_stream_channel_map(void *platform, audio_channel_mask_t channel_mask,
+                                               int snd_id, uint8_t *input_channel_map)
 {
-    int ret = 0;
+    int ret = 0, i = 0;
     int channels = audio_channel_count_from_out_mask(channel_mask);
 
-    char channel_map[8];
+    char channel_map[AUDIO_CHANNEL_COUNT_MAX];
     memset(channel_map, 0, sizeof(channel_map));
-    /* Following are all most common standard WAV channel layouts
-       overridden by channel mask if its allowed and different */
-    switch (channels) {
-        case 1:
-            /* AUDIO_CHANNEL_OUT_MONO */
-            channel_map[0] = PCM_CHANNEL_FC;
-            break;
-        case 2:
-            /* AUDIO_CHANNEL_OUT_STEREO */
-            channel_map[0] = PCM_CHANNEL_FL;
-            channel_map[1] = PCM_CHANNEL_FR;
-            break;
-        case 3:
-            /* AUDIO_CHANNEL_OUT_2POINT1 */
-            channel_map[0] = PCM_CHANNEL_FL;
-            channel_map[1] = PCM_CHANNEL_FR;
-            channel_map[2] = PCM_CHANNEL_FC;
-            break;
-        case 4:
-            /* AUDIO_CHANNEL_OUT_QUAD_SIDE */
-            channel_map[0] = PCM_CHANNEL_FL;
-            channel_map[1] = PCM_CHANNEL_FR;
-            channel_map[2] = PCM_CHANNEL_LS;
-            channel_map[3] = PCM_CHANNEL_RS;
-            if (channel_mask == AUDIO_CHANNEL_OUT_QUAD_BACK)
-            {
-                channel_map[2] = PCM_CHANNEL_LB;
-                channel_map[3] = PCM_CHANNEL_RB;
-            }
-            if (channel_mask == AUDIO_CHANNEL_OUT_SURROUND)
-            {
+    if (*input_channel_map) {
+        for (i = 0; i < channels; i++) {
+             ALOGV("%s:: Channel Map channel_map[%d] - %d", __func__, i, *input_channel_map);
+             channel_map[i] = *input_channel_map;
+             input_channel_map++;
+        }
+    } else {
+        /* Following are all most common standard WAV channel layouts
+           overridden by channel mask if its allowed and different */
+        switch (channels) {
+            case 1:
+                /* AUDIO_CHANNEL_OUT_MONO */
+                channel_map[0] = PCM_CHANNEL_FC;
+                break;
+            case 2:
+                /* AUDIO_CHANNEL_OUT_STEREO */
+                channel_map[0] = PCM_CHANNEL_FL;
+                channel_map[1] = PCM_CHANNEL_FR;
+                break;
+            case 3:
+                /* AUDIO_CHANNEL_OUT_2POINT1 */
+                channel_map[0] = PCM_CHANNEL_FL;
+                channel_map[1] = PCM_CHANNEL_FR;
                 channel_map[2] = PCM_CHANNEL_FC;
-                channel_map[3] = PCM_CHANNEL_CS;
-            }
-            break;
-        case 5:
-            /* AUDIO_CHANNEL_OUT_PENTA */
-            channel_map[0] = PCM_CHANNEL_FL;
-            channel_map[1] = PCM_CHANNEL_FR;
-            channel_map[2] = PCM_CHANNEL_FC;
-            channel_map[3] = PCM_CHANNEL_LB;
-            channel_map[4] = PCM_CHANNEL_RB;
-            break;
-        case 6:
-            /* AUDIO_CHANNEL_OUT_5POINT1 */
-            channel_map[0] = PCM_CHANNEL_FL;
-            channel_map[1] = PCM_CHANNEL_FR;
-            channel_map[2] = PCM_CHANNEL_FC;
-            channel_map[3] = PCM_CHANNEL_LFE;
-            channel_map[4] = PCM_CHANNEL_LB;
-            channel_map[5] = PCM_CHANNEL_RB;
-            if (channel_mask == AUDIO_CHANNEL_OUT_5POINT1_SIDE)
-            {
-                channel_map[4] = PCM_CHANNEL_LS;
-                channel_map[5] = PCM_CHANNEL_RS;
-            }
-            break;
-        case 7:
-            /* AUDIO_CHANNEL_OUT_6POINT1 */
-            channel_map[0] = PCM_CHANNEL_FL;
-            channel_map[1] = PCM_CHANNEL_FR;
-            channel_map[2] = PCM_CHANNEL_FC;
-            channel_map[3] = PCM_CHANNEL_LFE;
-            channel_map[4] = PCM_CHANNEL_LB;
-            channel_map[5] = PCM_CHANNEL_RB;
-            channel_map[6] = PCM_CHANNEL_CS;
-            break;
-        case 8:
-            /* AUDIO_CHANNEL_OUT_7POINT1 */
-            channel_map[0] = PCM_CHANNEL_FL;
-            channel_map[1] = PCM_CHANNEL_FR;
-            channel_map[2] = PCM_CHANNEL_FC;
-            channel_map[3] = PCM_CHANNEL_LFE;
-            channel_map[4] = PCM_CHANNEL_LB;
-            channel_map[5] = PCM_CHANNEL_RB;
-            channel_map[6] = PCM_CHANNEL_LS;
-            channel_map[7] = PCM_CHANNEL_RS;
-            break;
-        default:
-            ALOGE("unsupported channels %d for setting channel map", channels);
-            return -1;
+                break;
+            case 4:
+                /* AUDIO_CHANNEL_OUT_QUAD_SIDE */
+                channel_map[0] = PCM_CHANNEL_FL;
+                channel_map[1] = PCM_CHANNEL_FR;
+                channel_map[2] = PCM_CHANNEL_LS;
+                channel_map[3] = PCM_CHANNEL_RS;
+                if (channel_mask == AUDIO_CHANNEL_OUT_QUAD_BACK) {
+                    channel_map[2] = PCM_CHANNEL_LB;
+                    channel_map[3] = PCM_CHANNEL_RB;
+                }
+                if (channel_mask == AUDIO_CHANNEL_OUT_SURROUND) {
+                    channel_map[2] = PCM_CHANNEL_FC;
+                    channel_map[3] = PCM_CHANNEL_CS;
+                }
+                break;
+            case 5:
+                /* AUDIO_CHANNEL_OUT_PENTA */
+                channel_map[0] = PCM_CHANNEL_FL;
+                channel_map[1] = PCM_CHANNEL_FR;
+                channel_map[2] = PCM_CHANNEL_FC;
+                channel_map[3] = PCM_CHANNEL_LB;
+                channel_map[4] = PCM_CHANNEL_RB;
+                break;
+            case 6:
+                /* AUDIO_CHANNEL_OUT_5POINT1 */
+                channel_map[0] = PCM_CHANNEL_FL;
+                channel_map[1] = PCM_CHANNEL_FR;
+                channel_map[2] = PCM_CHANNEL_FC;
+                channel_map[3] = PCM_CHANNEL_LFE;
+                channel_map[4] = PCM_CHANNEL_LB;
+                channel_map[5] = PCM_CHANNEL_RB;
+                if (channel_mask == AUDIO_CHANNEL_OUT_5POINT1_SIDE) {
+                    channel_map[4] = PCM_CHANNEL_LS;
+                    channel_map[5] = PCM_CHANNEL_RS;
+                }
+                break;
+            case 7:
+                /* AUDIO_CHANNEL_OUT_6POINT1 */
+                channel_map[0] = PCM_CHANNEL_FL;
+                channel_map[1] = PCM_CHANNEL_FR;
+                channel_map[2] = PCM_CHANNEL_FC;
+                channel_map[3] = PCM_CHANNEL_LFE;
+                channel_map[4] = PCM_CHANNEL_LB;
+                channel_map[5] = PCM_CHANNEL_RB;
+                channel_map[6] = PCM_CHANNEL_CS;
+                break;
+            case 8:
+                /* AUDIO_CHANNEL_OUT_7POINT1 */
+                channel_map[0] = PCM_CHANNEL_FL;
+                channel_map[1] = PCM_CHANNEL_FR;
+                channel_map[2] = PCM_CHANNEL_FC;
+                channel_map[3] = PCM_CHANNEL_LFE;
+                channel_map[4] = PCM_CHANNEL_LB;
+                channel_map[5] = PCM_CHANNEL_RB;
+                channel_map[6] = PCM_CHANNEL_LS;
+                channel_map[7] = PCM_CHANNEL_RS;
+                break;
+            default:
+                ALOGE("unsupported channels %d for setting channel map", channels);
+                return -1;
+        }
     }
     ret = platform_set_channel_map(platform, channels, channel_map, snd_id);
     return ret;
@@ -5996,9 +6051,13 @@
         ALOGV("%s:PCM", __func__);
         format = LPCM;
         break;
+    case AUDIO_FORMAT_IEC61937:
+        ALOGV("%s:IEC61937", __func__);
+        format = 0;
+        break;
     default:
         format =  -1;
-        ALOGE("%s:invalid format:%d", __func__,format);
+        ALOGE("%s:invalid format: 0x%x", __func__, audio_format);
         break;
     }
     return format;
@@ -6067,6 +6126,9 @@
     int i, ret;
     unsigned char format_id = platform_map_to_edid_format(format);
 
+    if (format == AUDIO_FORMAT_IEC61937)
+        return true;
+
     if (format_id <= 0) {
         ALOGE("%s invalid edid format mappting for :%x" ,__func__, format);
         return false;
@@ -6108,6 +6170,20 @@
     return false;
 }
 
+int platform_edid_get_highest_supported_sr(void *platform)
+{
+    struct platform_data *my_data = (struct platform_data *)platform;
+    edid_audio_info *info = NULL;
+    int ret = 0;
+
+    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 0;
+}
 
 int platform_set_edid_channels_configuration(void *platform, int channels) {
 
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 93e41ed..ae50ce7 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -109,6 +109,8 @@
     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_TX,
     SND_DEVICE_OUT_AFE_PROXY,
     SND_DEVICE_OUT_USB_HEADSET,
@@ -177,6 +179,8 @@
     SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC,
     SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC,
     SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC,
+    SND_DEVICE_IN_VOICE_TTY_FULL_USB_MIC,
+    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_DMIC_STEREO,
@@ -490,7 +494,10 @@
     LEGACY_PCM = 0,
     PASSTHROUGH,
     PASSTHROUGH_CONVERT,
-    PASSTHROUGH_DSD
+    PASSTHROUGH_DSD,
+    LISTEN,
+    PASSTHROUGH_GEN,
+    PASSTHROUGH_IEC61937
 };
 /*
  * ID for setting mute and lateny on the device side
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 269aedc..a5ba7bf 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -31,7 +31,11 @@
 #define SAMPLE_RATE_11025 11025
 #define sample_rate_multiple(sr, base) ((sr % base)== 0?true:false)
 #define MAX_VOLUME_CAL_STEPS 15
-#define ACDB_METAINFO_KEY_MODULE_NAME_LEN 100
+
+typedef enum {
+    PLATFORM,
+    ACDB_EXTN,
+} caller_t;
 
 struct amp_db_and_gain_table {
     float amp;
@@ -140,9 +144,10 @@
 int platform_set_snd_device_backend(snd_device_t snd_device, const char * backend,
                                     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);
 
 /* From platform_info.c */
-int platform_info_init(const char *filename, void *);
+int platform_info_init(const char *filename, void *, caller_t);
 
 void platform_snd_card_update(void *platform, int snd_scard_state);
 
@@ -163,7 +168,8 @@
 int platform_get_edid_info(void *platform);
 int platform_set_channel_map(void *platform, int ch_count, char *ch_map,
                              int snd_id);
-int platform_set_stream_channel_map(void *platform, audio_channel_mask_t channel_mask, int snd_id);
+int platform_set_stream_channel_map(void *platform, audio_channel_mask_t channel_mask,
+                                   int snd_id, uint8_t *input_channel_map);
 int platform_set_edid_channels_configuration(void *platform, int channels);
 unsigned char platform_map_to_edid_format(int format);
 bool platform_is_edid_supported_format(void *platform, int format);
diff --git a/hal/platform_info.c b/hal/platform_info.c
index 6b64261..597d1f7 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -36,10 +36,17 @@
 #include <cutils/log.h>
 #include <cutils/str_parms.h>
 #include <audio_hw.h>
+#include "acdb.h"
 #include "platform_api.h"
 #include <platform.h>
 #include <math.h>
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_PLATFORM_INFO
+#include <log_utils.h>
+#endif
+
 #define BUF_SIZE                    1024
 
 typedef enum {
@@ -81,6 +88,7 @@
 static section_t section;
 
 struct platform_info {
+    caller_t          caller;
     void             *platform;
     struct str_parms *kvpairs;
 };
@@ -369,9 +377,21 @@
     }
 
     int key = atoi((char *)attr[3]);
-    if (platform_set_acdb_metainfo_key(my_data.platform, (char*)attr[1], key) < 0) {
-        ALOGE("%s: key %d was not set!", __func__, key);
-        goto done;
+    switch(my_data.caller) {
+        case ACDB_EXTN:
+                if(acdb_set_metainfo_key(my_data.platform, (char*)attr[1], key) < 0) {
+                    ALOGE("%s: key %d was not set!", __func__, key);
+                    goto done;
+                }
+                break;
+        case PLATFORM:
+                if(platform_set_acdb_metainfo_key(my_data.platform, (char*)attr[1], key) < 0) {
+                    ALOGE("%s: key %d was not set!", __func__, key);
+                    goto done;
+                }
+                break;
+        default:
+                ALOGE("%s: unknown caller!", __func__);
     }
 
 done:
@@ -381,58 +401,73 @@
 static void start_tag(void *userdata __unused, const XML_Char *tag_name,
                       const XML_Char **attr)
 {
-    if (strcmp(tag_name, "bit_width_configs") == 0) {
-        section = BITWIDTH;
-    } else if (strcmp(tag_name, "acdb_ids") == 0) {
-        section = ACDB;
-    } else if (strcmp(tag_name, "pcm_ids") == 0) {
-        section = PCM_ID;
-    } else if (strcmp(tag_name, "backend_names") == 0) {
-        section = BACKEND_NAME;
-    } else if (strcmp(tag_name, "config_params") == 0) {
-        section = CONFIG_PARAMS;
-    } 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, "acdb_metainfo_key") == 0) {
-        section = ACDB_METAINFO_KEY;
-    } else if (strcmp(tag_name, "device") == 0) {
-        if ((section != ACDB) && (section != BACKEND_NAME) && (section != BITWIDTH) &&
-            (section != INTERFACE_NAME)) {
-            ALOGE("device tag only supported for acdb/backend names/bitwitdh/interface names");
-            return;
-        }
+    if (my_data.caller == ACDB_EXTN) {
+        if(strcmp(tag_name, "acdb_metainfo_key") == 0) {
+            section = ACDB_METAINFO_KEY;
+        } else if (strcmp(tag_name, "param") == 0) {
+            if ((section != CONFIG_PARAMS) && (section != ACDB_METAINFO_KEY)) {
+                ALOGE("param tag only supported with CONFIG_PARAMS section");
+                return;
+            }
 
-        /* call into process function for the current section */
-        section_process_fn fn = section_table[section];
-        fn(attr);
-    } else if (strcmp(tag_name, "gain_level_map") == 0) {
-        if (section != GAIN_LEVEL_MAPPING) {
-            ALOGE("usecase tag only supported with GAIN_LEVEL_MAPPING section");
-            return;
+            section_process_fn fn = section_table[section];
+            fn(attr);
         }
+    } else if(my_data.caller == PLATFORM) {
+        if (strcmp(tag_name, "bit_width_configs") == 0) {
+            section = BITWIDTH;
+        } else if (strcmp(tag_name, "acdb_ids") == 0) {
+            section = ACDB;
+        } else if (strcmp(tag_name, "pcm_ids") == 0) {
+            section = PCM_ID;
+        } else if (strcmp(tag_name, "backend_names") == 0) {
+            section = BACKEND_NAME;
+        } else if (strcmp(tag_name, "config_params") == 0) {
+            section = CONFIG_PARAMS;
+        } 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, "acdb_metainfo_key") == 0) {
+            section = ACDB_METAINFO_KEY;
+        } else if (strcmp(tag_name, "device") == 0) {
+            if ((section != ACDB) && (section != BACKEND_NAME) && (section != BITWIDTH) &&
+                (section != INTERFACE_NAME)) {
+                ALOGE("device tag only supported for acdb/backend names/bitwitdh/interface names");
+                return;
+            }
 
-        section_process_fn fn = section_table[GAIN_LEVEL_MAPPING];
-        fn(attr);
-    } else if (strcmp(tag_name, "usecase") == 0) {
-        if (section != PCM_ID) {
-            ALOGE("usecase tag only supported with PCM_ID section");
-            return;
+            /* call into process function for the current section */
+            section_process_fn fn = section_table[section];
+            fn(attr);
+        } else if (strcmp(tag_name, "gain_level_map") == 0) {
+            if (section != GAIN_LEVEL_MAPPING) {
+                ALOGE("usecase 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, "usecase") == 0) {
+            if (section != PCM_ID) {
+                ALOGE("usecase tag only supported with PCM_ID section");
+                return;
+            }
+
+            section_process_fn fn = section_table[PCM_ID];
+            fn(attr);
+        } else if (strcmp(tag_name, "param") == 0) {
+            if ((section != CONFIG_PARAMS) && (section != ACDB_METAINFO_KEY)) {
+                ALOGE("param tag only supported with CONFIG_PARAMS section");
+                return;
+            }
+
+            section_process_fn fn = section_table[section];
+            fn(attr);
         }
-
-        section_process_fn fn = section_table[PCM_ID];
-        fn(attr);
-    } else if (strcmp(tag_name, "param") == 0) {
-        if ((section != CONFIG_PARAMS) && (section != ACDB_METAINFO_KEY)) {
-            ALOGE("param tag only supported with CONFIG_PARAMS section");
-            return;
-        }
-
-        section_process_fn fn = section_table[section];
-        fn(attr);
+    } else {
+            ALOGE("%s: unknown caller!", __func__);
     }
-
     return;
 }
 
@@ -448,7 +483,9 @@
         section = ROOT;
     } else if (strcmp(tag_name, "config_params") == 0) {
         section = ROOT;
-        platform_set_parameters(my_data.platform, my_data.kvpairs);
+        if (my_data.caller == PLATFORM) {
+            platform_set_parameters(my_data.platform, my_data.kvpairs);
+        }
     } else if (strcmp(tag_name, "interface_names") == 0) {
         section = ROOT;
     } else if (strcmp(tag_name, "gain_db_to_level_mapping") == 0) {
@@ -458,7 +495,7 @@
     }
 }
 
-int platform_info_init(const char *filename, void *platform)
+int platform_info_init(const char *filename, void *platform, caller_t caller_type)
 {
     XML_Parser      parser;
     FILE            *file;
@@ -483,6 +520,7 @@
         goto err_close_file;
     }
 
+    my_data.caller = caller_type;
     my_data.platform = platform;
     my_data.kvpairs = str_parms_create();
 
diff --git a/hal/voice.c b/hal/voice.c
index 852c3e6..5a3ff33 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
  * Not a contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -34,6 +34,12 @@
 #include "platform_api.h"
 #include "audio_extn.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_VOICE
+#include <log_utils.h>
+#endif
+
 struct pcm_config pcm_config_voice_call = {
     .channels = 1,
     .rate = 8000,
diff --git a/hal/voice_extn/compress_voip.c b/hal/voice_extn/compress_voip.c
index 43dedc5..6448b38 100644
--- a/hal/voice_extn/compress_voip.c
+++ b/hal/voice_extn/compress_voip.c
@@ -36,6 +36,12 @@
 #include "platform.h"
 #include "voice_extn.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_COMPR_VOIP
+#include <log_utils.h>
+#endif
+
 #define COMPRESS_VOIP_IO_BUF_SIZE_NB 320
 #define COMPRESS_VOIP_IO_BUF_SIZE_WB 640
 #define COMPRESS_VOIP_IO_BUF_SIZE_SWB 1280
diff --git a/hal/voice_extn/voice_extn.c b/hal/voice_extn/voice_extn.c
index 3cd3e78..8bc782d 100644
--- a/hal/voice_extn/voice_extn.c
+++ b/hal/voice_extn/voice_extn.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
  * Not a contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -35,6 +35,12 @@
 #include "platform_api.h"
 #include "voice_extn.h"
 
+#ifdef DYNAMIC_LOG_ENABLED
+#include <log_xml_parser.h>
+#define LOG_MASK HAL_MOD_FILE_VOICE_EXTN
+#include <log_utils.h>
+#endif
+
 #define AUDIO_PARAMETER_KEY_VSID                "vsid"
 #define AUDIO_PARAMETER_KEY_CALL_STATE          "call_state"
 #define AUDIO_PARAMETER_KEY_AUDIO_MODE          "audio_mode"
diff --git a/mm-audio/aenc-aac/qdsp6/Android.mk b/mm-audio/aenc-aac/qdsp6/Android.mk
index acc1fdb..fa679a8 100644
--- a/mm-audio/aenc-aac/qdsp6/Android.mk
+++ b/mm-audio/aenc-aac/qdsp6/Android.mk
@@ -25,8 +25,10 @@
 libOmxAacEnc-inc       := $(LOCAL_PATH)/inc
 libOmxAacEnc-inc       += $(TARGET_OUT_HEADERS)/mm-core/omxcore
 
-LOCAL_MODULE            := libOmxAacEnc
-LOCAL_MODULE_TAGS       := optional
+LOCAL_MODULE             := libOmxAacEnc
+LOCAL_MODULE_TAGS        := optional
+LOCAL_MODULE_OWNER       := qti
+LOCAL_PROPRIETARY_MODULE := true
 LOCAL_CFLAGS            := $(libOmxAacEnc-def)
 LOCAL_C_INCLUDES        := $(libOmxAacEnc-inc)
 LOCAL_PRELINK_MODULE    := false
diff --git a/mm-audio/aenc-amrnb/qdsp6/Android.mk b/mm-audio/aenc-amrnb/qdsp6/Android.mk
index 346602c..9aff667 100644
--- a/mm-audio/aenc-amrnb/qdsp6/Android.mk
+++ b/mm-audio/aenc-amrnb/qdsp6/Android.mk
@@ -25,8 +25,10 @@
 libOmxAmrEnc-inc       := $(LOCAL_PATH)/inc
 libOmxAmrEnc-inc       += $(TARGET_OUT_HEADERS)/mm-core/omxcore
 
-LOCAL_MODULE            := libOmxAmrEnc
-LOCAL_MODULE_TAGS       := optional
+LOCAL_MODULE             := libOmxAmrEnc
+LOCAL_MODULE_TAGS        := optional
+LOCAL_MODULE_OWNER       := qti
+LOCAL_PROPRIETARY_MODULE := true
 LOCAL_CFLAGS            := $(libOmxAmrEnc-def)
 LOCAL_C_INCLUDES        := $(libOmxAmrEnc-inc)
 LOCAL_PRELINK_MODULE    := false
diff --git a/mm-audio/aenc-evrc/qdsp6/Android.mk b/mm-audio/aenc-evrc/qdsp6/Android.mk
index 83f105e..eed53ba 100644
--- a/mm-audio/aenc-evrc/qdsp6/Android.mk
+++ b/mm-audio/aenc-evrc/qdsp6/Android.mk
@@ -25,8 +25,10 @@
 libOmxEvrcEnc-inc       := $(LOCAL_PATH)/inc
 libOmxEvrcEnc-inc       += $(TARGET_OUT_HEADERS)/mm-core/omxcore
 
-LOCAL_MODULE            := libOmxEvrcEnc
-LOCAL_MODULE_TAGS       := optional
+LOCAL_MODULE             := libOmxEvrcEnc
+LOCAL_MODULE_TAGS        := optional
+LOCAL_MODULE_OWNER       := qti
+LOCAL_PROPRIETARY_MODULE := true
 LOCAL_CFLAGS            := $(libOmxEvrcEnc-def)
 LOCAL_C_INCLUDES        := $(libOmxEvrcEnc-inc)
 LOCAL_PRELINK_MODULE    := false
diff --git a/mm-audio/aenc-g711/qdsp6/Android.mk b/mm-audio/aenc-g711/qdsp6/Android.mk
index b4e60d4..9c94612 100644
--- a/mm-audio/aenc-g711/qdsp6/Android.mk
+++ b/mm-audio/aenc-g711/qdsp6/Android.mk
@@ -25,8 +25,10 @@
 libOmxG711Enc-inc       := $(LOCAL_PATH)/inc
 libOmxG711Enc-inc       += $(TARGET_OUT_HEADERS)/mm-core/omxcore
 
-LOCAL_MODULE            := libOmxG711Enc
-LOCAL_MODULE_TAGS       := optional
+LOCAL_MODULE             := libOmxG711Enc
+LOCAL_MODULE_TAGS        := optional
+LOCAL_MODULE_OWNER       := qti
+LOCAL_PROPRIETARY_MODULE := true
 LOCAL_CFLAGS            := $(libOmxG711Enc-def)
 LOCAL_C_INCLUDES        := $(libOmxG711Enc-inc)
 LOCAL_PRELINK_MODULE    := false
diff --git a/mm-audio/aenc-qcelp13/qdsp6/Android.mk b/mm-audio/aenc-qcelp13/qdsp6/Android.mk
index b575d7f..ac2b5ff 100644
--- a/mm-audio/aenc-qcelp13/qdsp6/Android.mk
+++ b/mm-audio/aenc-qcelp13/qdsp6/Android.mk
@@ -25,8 +25,10 @@
 libOmxQcelp13Enc-inc       := $(LOCAL_PATH)/inc
 libOmxQcelp13Enc-inc       += $(TARGET_OUT_HEADERS)/mm-core/omxcore
 
-LOCAL_MODULE            := libOmxQcelp13Enc
-LOCAL_MODULE_TAGS       := optional
+LOCAL_MODULE             := libOmxQcelp13Enc
+LOCAL_MODULE_TAGS        := optional
+LOCAL_MODULE_OWNER       := qti
+LOCAL_PROPRIETARY_MODULE := true
 LOCAL_CFLAGS            := $(libOmxQcelp13Enc-def)
 LOCAL_C_INCLUDES        := $(libOmxQcelp13Enc-inc)
 LOCAL_PRELINK_MODULE    := false
diff --git a/post_proc/Android.mk b/post_proc/Android.mk
index 56c45a0..23fc14f 100644
--- a/post_proc/Android.mk
+++ b/post_proc/Android.mk
@@ -42,6 +42,8 @@
 
 LOCAL_MODULE_RELATIVE_PATH := soundfx
 LOCAL_MODULE:= libqcompostprocbundle
+LOCAL_MODULE_OWNER := qti
+LOCAL_PROPRIETARY_MODULE := true
 
 LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
 
@@ -74,6 +76,8 @@
 endif
 
 LOCAL_MODULE:= libhwacceffectswrapper
+LOCAL_MODULE_OWNER := qti
+LOCAL_PROPRIETARY_MODULE := true
 
 include $(BUILD_STATIC_LIBRARY)
 endif
@@ -85,7 +89,7 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_CFLAGS := -DLIB_AUDIO_HAL="/system/lib/hw/audio.primary."$(TARGET_BOARD_PLATFORM)".so"
+LOCAL_CFLAGS := -DLIB_AUDIO_HAL="/vendor/lib/hw/audio.primary."$(TARGET_BOARD_PLATFORM)".so"
 
 LOCAL_SRC_FILES:= \
         volume_listener.c
@@ -99,6 +103,8 @@
 
 LOCAL_MODULE_RELATIVE_PATH := soundfx
 LOCAL_MODULE:= libvolumelistener
+LOCAL_MODULE_OWNER := qti
+LOCAL_PROPRIETARY_MODULE := true
 
 LOCAL_C_INCLUDES := \
         hardware/qcom/audio/hal \
diff --git a/qahw_api/inc/qahw_defs.h b/qahw_api/inc/qahw_defs.h
index 7ae9475..3adddf1 100644
--- a/qahw_api/inc/qahw_defs.h
+++ b/qahw_api/inc/qahw_defs.h
@@ -181,6 +181,7 @@
 typedef enum {
     QAHW_STREAM_CBK_EVENT_WRITE_READY, /* non blocking write completed */
     QAHW_STREAM_CBK_EVENT_DRAIN_READY,  /* drain completed */
+    QAHW_STREAM_CBK_EVENT_ERROR,  /* stream hit some error */
 
     QAHW_STREAM_CBK_EVENT_ADSP = 0x100    /* callback event from ADSP PP,
                                            * corresponding payload will be
@@ -278,16 +279,40 @@
    uint64_t       start_delay; /* session start delay in microseconds*/
 };
 
+struct qahw_out_enable_drift_correction {
+   bool        enable; /* enable drift correction*/
+};
+
+struct qahw_out_correct_drift {
+    /*
+     * adjust time in microseconds, a positive value
+     * to advance the clock or a negative value to
+     * delay the clock.
+     */
+    int64_t        adjust_time;
+};
+
 #define QAHW_MAX_ADSP_STREAM_CMD_PAYLOAD_LEN 512
 
+typedef enum {
+    QAHW_STREAM_PP_EVENT = 0,
+    QAHW_STREAM_ENCDEC_EVENT = 1,
+} qahw_event_id;
+
 /* payload format for HAL parameter
  * QAHW_PARAM_ADSP_STREAM_CMD
  */
 struct qahw_adsp_event {
+    qahw_event_id event_type;      /* type of the event */
     uint32_t payload_length;       /* length in bytes of the payload */
     void *payload;                 /* the actual payload */
 };
 
+struct qahw_out_channel_map_param {
+   uint8_t       channels;                               /* Input Channels */
+   uint8_t       channel_map[AUDIO_CHANNEL_COUNT_MAX];   /* Input Channel Map */
+};
+
 typedef union {
     struct qahw_source_tracking_param st_params;
     struct qahw_sound_focus_param sf_params;
@@ -295,17 +320,25 @@
     struct qahw_avt_device_drift_param drift_params;
     struct qahw_out_render_window_param render_window_params;
     struct qahw_out_start_delay_param start_delay;
+    struct qahw_out_enable_drift_correction drift_enable_param;
+    struct qahw_out_correct_drift drift_correction_param;
     struct qahw_adsp_event adsp_event_params;
+    struct qahw_out_channel_map_param channel_map_params;
 } qahw_param_payload;
 
 typedef enum {
     QAHW_PARAM_SOURCE_TRACK,
     QAHW_PARAM_SOUND_FOCUS,
     QAHW_PARAM_APTX_DEC,
-    QAHW_PARAM_AVT_DEVICE_DRIFT, /* PARAM to query AV timer vs device drift */
+    QAHW_PARAM_AVT_DEVICE_DRIFT,  /* PARAM to query AV timer vs device drift */
     QAHW_PARAM_OUT_RENDER_WINDOW, /* PARAM to set render window */
     QAHW_PARAM_OUT_START_DELAY, /* PARAM to set session start delay*/
-    QAHW_PARAM_ADSP_STREAM_CMD
+    /* enable adsp drift correction this must be called before out_write */
+    QAHW_PARAM_OUT_ENABLE_DRIFT_CORRECTION,
+    /* param to set drift value to be adjusted by dsp */
+    QAHW_PARAM_OUT_CORRECT_DRIFT,
+    QAHW_PARAM_ADSP_STREAM_CMD,
+    QAHW_PARAM_OUT_CHANNEL_MAP    /* PARAM to set i/p channel map */
 } qahw_param_id;
 
 __END_DECLS
diff --git a/qahw_api/src/qahw.c b/qahw_api/src/qahw.c
index c5cd636..df69df5 100644
--- a/qahw_api/src/qahw.c
+++ b/qahw_api/src/qahw.c
@@ -47,6 +47,10 @@
  */
 #define QAHW_MODULE_API_VERSION_CURRENT QAHW_MODULE_API_VERSION_0_0
 
+
+typedef uint64_t (*qahwi_out_write_v2_t)(audio_stream_out_t *out, const void* buffer,
+                                       size_t bytes, int64_t* timestamp);
+
 typedef int (*qahwi_get_param_data_t) (const audio_hw_device_t *,
                               qahw_param_id, qahw_param_payload *);
 
@@ -90,6 +94,7 @@
     pthread_mutex_t lock;
     qahwi_out_set_param_data_t qahwi_out_get_param_data;
     qahwi_out_get_param_data_t qahwi_out_set_param_data;
+    qahwi_out_write_v2_t qahwi_out_write_v2;
 } qahw_stream_out_t;
 
 typedef struct {
@@ -535,10 +540,13 @@
     }
 
     /*TBD:: validate other meta data parameters */
-
     pthread_mutex_lock(&qahw_stream_out->lock);
     out = qahw_stream_out->stream;
-    if (out->write) {
+    if (qahw_stream_out->qahwi_out_write_v2) {
+        rc = qahw_stream_out->qahwi_out_write_v2(out, out_buf->buffer,
+                                         out_buf->bytes, out_buf->timestamp);
+        out_buf->offset = 0;
+    } else if (out->write) {
         rc = out->write(out, out_buf->buffer, out_buf->bytes);
     } else {
         rc = -ENOSYS;
@@ -1468,6 +1476,19 @@
         }
 }
 
+    /* dlsym qahwi_out_write_v2 */
+    if (!rc) {
+        const char *error;
+
+        /* clear any existing errors */
+        dlerror();
+        qahw_stream_out->qahwi_out_write_v2 = (qahwi_out_write_v2_t)dlsym(qahw_module->module->dso, "qahwi_out_write_v2");
+        if ((error = dlerror()) != NULL) {
+            ALOGI("%s: dlsym error %s for qahwi_out_write_v2", __func__, error);
+            qahw_stream_out->qahwi_out_write_v2 = NULL;
+        }
+    }
+
 exit:
     pthread_mutex_unlock(&qahw_module->lock);
     return rc;
diff --git a/qahw_api/test/Android.mk b/qahw_api/test/Android.mk
index 6ee6f4b..887f416 100644
--- a/qahw_api/test/Android.mk
+++ b/qahw_api/test/Android.mk
@@ -8,14 +8,17 @@
 LOCAL_MODULE := hal_play_test
 
 hal-play-inc     = $(TARGET_OUT_HEADERS)/mm-audio/qahw_api/inc
+hal-play-inc    += external/tinyalsa/include
 
 LOCAL_CFLAGS += -Wall -Werror -Wno-sign-compare
 
 LOCAL_SHARED_LIBRARIES := \
     libaudioutils\
     libqahw \
-    libutils
+    libutils \
+    libcutils
 
+LOCAL_LDLIBS := -lpthread
 LOCAL_32_BIT_ONLY := true
 
 LOCAL_C_INCLUDES += $(hal-play-inc)
diff --git a/qahw_api/test/qahw_effect_test.c b/qahw_api/test/qahw_effect_test.c
index 89c5d89..61b73a7 100644
--- a/qahw_api/test/qahw_effect_test.c
+++ b/qahw_api/test/qahw_effect_test.c
@@ -120,6 +120,9 @@
     int32_t                  rc;
     int                      reply_data;
     uint32_t                 reply_size = sizeof(int);
+    uint32_t array_size = sizeof(qahw_effect_param_t) + 2 * sizeof(int32_t);
+    uint32_t      buf32[array_size];
+    qahw_effect_param_t *values;
 
     pthread_mutex_lock(&thr_ctxt->mutex);
     while(!thr_ctxt->exit) {
@@ -154,6 +157,24 @@
             if (rc != 0) {
                 fprintf(stderr, "effect_command() returns %d\n", rc);
             }
+            if (thr_ctxt->default_flag && (thr_ctxt->cmd_code == QAHW_EFFECT_CMD_ENABLE)) {
+                if (thr_ctxt->default_value == -1)
+                    thr_ctxt->default_value = 600;
+
+                values = (qahw_effect_param_t *)buf32;
+                values->psize = sizeof(int32_t);
+                values->vsize = sizeof(int32_t);
+                *(int32_t *)values->data = BASSBOOST_PARAM_STRENGTH;
+                memcpy((values->data + values->psize), &thr_ctxt->default_value, values->vsize);
+                rc = qahw_effect_command(effect_handle, QAHW_EFFECT_CMD_SET_PARAM,
+                                     array_size, (void *)values,
+                                     thr_ctxt->reply_size, thr_ctxt->reply_data);
+                if (rc != 0) {
+                    fprintf(stderr, "effect_command() returns %d\n", rc);
+                }else {
+                     thr_ctxt->default_flag = false;
+                }
+            }
             break;
         case(EFFECT_PROC):
             //qahw_effect_process();
@@ -188,6 +209,9 @@
     int32_t                  rc;
     int                      reply_data;
     uint32_t                 reply_size = sizeof(int);
+    uint32_t array_size = sizeof(qahw_effect_param_t) + 2 * sizeof(int32_t);
+    uint32_t      buf32[array_size];
+    qahw_effect_param_t *values;
 
     pthread_mutex_lock(&thr_ctxt->mutex);
     while(!thr_ctxt->exit) {
@@ -222,6 +246,24 @@
             if (rc != 0) {
                 fprintf(stderr, "effect_command() returns %d\n", rc);
             }
+            if (thr_ctxt->default_flag && (thr_ctxt->cmd_code == QAHW_EFFECT_CMD_ENABLE)) {
+                if (thr_ctxt->default_value == -1)
+                    thr_ctxt->default_value = 600;
+
+                values = (qahw_effect_param_t *)buf32;
+                values->psize = sizeof(int32_t);
+                values->vsize = sizeof(int32_t);
+                *(int32_t *)values->data = VIRTUALIZER_PARAM_STRENGTH;
+                memcpy((values->data + values->psize), &thr_ctxt->default_value, values->vsize);
+                rc = qahw_effect_command(effect_handle, QAHW_EFFECT_CMD_SET_PARAM,
+                                     array_size, (void *)values,
+                                     thr_ctxt->reply_size, thr_ctxt->reply_data);
+                if (rc != 0) {
+                    fprintf(stderr, "effect_command() returns %d\n", rc);
+                }else {
+                     thr_ctxt->default_flag = false;
+                }
+            }
             break;
         case(EFFECT_PROC):
             //qahw_effect_process();
@@ -256,6 +298,9 @@
     int32_t                  rc;
     int                      reply_data;
     uint32_t                 reply_size = sizeof(int);
+    uint32_t array_size = sizeof(qahw_effect_param_t) + 2 * sizeof(int32_t);
+    uint32_t      buf32[array_size];
+    qahw_effect_param_t *values;
 
     pthread_mutex_lock(&thr_ctxt->mutex);
     while(!thr_ctxt->exit) {
@@ -290,6 +335,24 @@
             if (rc != 0) {
                 fprintf(stderr, "effect_command() returns %d\n", rc);
             }
+            if (thr_ctxt->default_flag && (thr_ctxt->cmd_code == QAHW_EFFECT_CMD_ENABLE)) {
+                if (thr_ctxt->default_value == -1)
+                    thr_ctxt->default_value = 2;
+
+                values = (qahw_effect_param_t *)buf32;
+                values->psize = sizeof(int32_t);
+                values->vsize = sizeof(int32_t);
+                *(int32_t *)values->data = EQ_PARAM_CUR_PRESET;
+                memcpy((values->data + values->psize), &thr_ctxt->default_value, values->vsize);
+                rc = qahw_effect_command(effect_handle, QAHW_EFFECT_CMD_SET_PARAM,
+                                     array_size, (void *)values,
+                                     thr_ctxt->reply_size, thr_ctxt->reply_data);
+                if (rc != 0) {
+                    fprintf(stderr, "effect_command() returns %d\n", rc);
+                }else {
+                     thr_ctxt->default_flag = false;
+                }
+            }
             break;
         case(EFFECT_PROC):
             //qahw_effect_process();
@@ -330,6 +393,9 @@
     int32_t                  rc;
     int                      reply_data;
     uint32_t                 reply_size = sizeof(int);
+    uint32_t array_size = sizeof(qahw_effect_param_t) + 2 * sizeof(int32_t);
+    uint32_t      buf32[array_size];
+    qahw_effect_param_t *values;
 
     pthread_mutex_lock(&thr_ctxt->mutex);
     while(!thr_ctxt->exit) {
@@ -364,6 +430,24 @@
             if (rc != 0) {
                 fprintf(stderr, "effect_command() returns %d\n", rc);
             }
+            if (thr_ctxt->default_flag && (thr_ctxt->cmd_code == QAHW_EFFECT_CMD_ENABLE)) {
+                if (thr_ctxt->default_value == -1)
+                    thr_ctxt->default_value = 2;
+
+                values = (qahw_effect_param_t *)buf32;
+                values->psize = sizeof(int32_t);
+                values->vsize = sizeof(int32_t);
+                *(int32_t *)values->data = REVERB_PARAM_PRESET;
+                memcpy((values->data + values->psize), &thr_ctxt->default_value, values->vsize);
+                rc = qahw_effect_command(effect_handle, QAHW_EFFECT_CMD_SET_PARAM,
+                                     array_size, (void *)values,
+                                     thr_ctxt->reply_size, thr_ctxt->reply_data);
+                if (rc != 0) {
+                    fprintf(stderr, "effect_command() returns %d\n", rc);
+                }else {
+                     thr_ctxt->default_flag = false;
+                }
+            }
             break;
         case(EFFECT_PROC):
             //qahw_effect_process();
@@ -402,7 +486,6 @@
     uint32_t      preset;
     int           level;
     uint16_t      band_idx;
-    int           enable;
     qahw_effect_param_t *param = (qahw_effect_param_t *)buf32;
     qahw_effect_param_t *param_2 = (qahw_effect_param_t *)buf32_2;
 
@@ -421,28 +504,10 @@
         cmd_key = get_key_from_name(fx_ctxt->who_am_i, cmd_str);
         switch (cmd_key) {
         case TTY_ENABLE:
-            enable = 1;
             notify_effect_command(fx_ctxt, EFFECT_CMD, QAHW_EFFECT_CMD_ENABLE, 0, NULL);
-            if (fx_ctxt->who_am_i == EFFECT_AUDIOSPHERE) {
-                param->psize = 2 * sizeof(int32_t);
-                *(int32_t *)param->data = ASPHERE_PARAM_ENABLE;
-                param->vsize = sizeof(int32_t);
-                memcpy((param->data + param->psize), &enable, param->vsize);
-
-                notify_effect_command(fx_ctxt, EFFECT_CMD, QAHW_EFFECT_CMD_SET_PARAM, size, param);
-            }
             break;
         case TTY_DISABLE:
-            enable = 0;
             notify_effect_command(fx_ctxt, EFFECT_CMD, QAHW_EFFECT_CMD_DISABLE, 0, NULL);
-            if (fx_ctxt->who_am_i == EFFECT_AUDIOSPHERE) {
-                param->psize = 2 * sizeof(int32_t);
-                *(int32_t *)param->data = ASPHERE_PARAM_ENABLE;
-                param->vsize = sizeof(int32_t);
-                memcpy((param->data + param->psize), &enable, param->vsize);
-
-                notify_effect_command(fx_ctxt, EFFECT_CMD, QAHW_EFFECT_CMD_SET_PARAM, size, param);
-            }
             break;
         case TTY_BB_SET_STRENGTH:
         case TTY_VT_SET_STRENGTH:
@@ -689,6 +754,10 @@
     int32_t                  rc;
     int                      reply_data;
     uint32_t                 reply_size = sizeof(int);
+    uint32_t array_size = sizeof(qahw_effect_param_t) + 2 * sizeof(int32_t);
+    uint32_t      buf32[array_size];
+    qahw_effect_param_t *values;
+    int enable;
 
     pthread_mutex_lock(&thr_ctxt->mutex);
     while(!thr_ctxt->exit) {
@@ -723,6 +792,37 @@
             if (rc != 0) {
                 fprintf(stderr, "effect_command() returns %d\n", rc);
             }
+            if (thr_ctxt->cmd_code == QAHW_EFFECT_CMD_ENABLE || thr_ctxt->cmd_code == QAHW_EFFECT_CMD_DISABLE) {
+                enable = ((thr_ctxt->cmd_code == QAHW_EFFECT_CMD_ENABLE) ? 1 : 0);
+                values->psize = 2 * sizeof(int32_t);
+                values->vsize = sizeof(int32_t);
+                *(int32_t *)values->data = ASPHERE_PARAM_ENABLE;
+                memcpy((values->data + values->psize), &enable, values->vsize);
+                rc = qahw_effect_command(effect_handle, QAHW_EFFECT_CMD_SET_PARAM,
+                                     array_size, (void *)values,
+                                     thr_ctxt->reply_size, thr_ctxt->reply_data);
+                if (rc != 0) {
+                    fprintf(stderr, "effect_command() returns %d\n", rc);
+                }
+            }
+            if (thr_ctxt->default_flag && (thr_ctxt->cmd_code == QAHW_EFFECT_CMD_ENABLE)) {
+                if (thr_ctxt->default_value == -1)
+                    thr_ctxt->default_value = 600;
+
+                values = (qahw_effect_param_t *)buf32;
+                values->psize = sizeof(int32_t);
+                values->vsize = sizeof(int32_t);
+                *(int32_t *)values->data = ASPHERE_PARAM_STRENGTH;
+                memcpy((values->data + values->psize), &thr_ctxt->default_value, values->vsize);
+                rc = qahw_effect_command(effect_handle, QAHW_EFFECT_CMD_SET_PARAM,
+                                     array_size, (void *)values,
+                                     thr_ctxt->reply_size, thr_ctxt->reply_data);
+                if (rc != 0) {
+                    fprintf(stderr, "effect_command() returns %d\n", rc);
+                }else {
+                     thr_ctxt->default_flag = false;
+                }
+            }
             break;
         case(EFFECT_PROC):
             //qahw_effect_process();
diff --git a/qahw_api/test/qahw_effect_test.h b/qahw_api/test/qahw_effect_test.h
index 07557a5..ede65df 100644
--- a/qahw_api/test/qahw_effect_test.h
+++ b/qahw_api/test/qahw_effect_test.h
@@ -68,6 +68,8 @@
     void              *cmd_data;
     uint32_t          *reply_size;
     void              *reply_data;
+    int               default_value;
+    bool              default_flag;
 } thread_data_t;
 
 typedef struct cmd_data {
diff --git a/qahw_api/test/qahw_multi_record_test.c b/qahw_api/test/qahw_multi_record_test.c
index c9f8b03..f0720f2 100644
--- a/qahw_api/test/qahw_multi_record_test.c
+++ b/qahw_api/test/qahw_multi_record_test.c
@@ -89,6 +89,40 @@
 static pthread_mutex_t sourcetrack_lock;
 struct qahw_sound_focus_param sound_focus_data;
 
+static bool request_wake_lock(bool wakelock_acquired, bool enable)
+{
+   int system_ret;
+
+   if (enable) {
+       if (!wakelock_acquired) {
+           system_ret = system("echo audio_services > /sys/power/wake_lock");
+           if (system_ret < 0) {
+               fprintf(stderr, "%s.Failed to acquire audio_service lock\n", __func__);
+               fprintf(log_file, "%s.Failed to acquire audio_service lock\n", __func__);
+           } else {
+               wakelock_acquired = true;
+               fprintf(log_file, "%s.Success to acquire audio_service lock\n", __func__);
+           }
+       } else
+            fprintf(log_file, "%s.Lock is already acquired\n", __func__);
+   }
+
+   if (!enable) {
+       if (wakelock_acquired) {
+           system_ret = system("echo audio_services > /sys/power/wake_unlock");
+           if (system_ret < 0) {
+               fprintf(stderr, "%s.Failed to release audio_service lock\n", __func__);
+               fprintf(log_file, "%s.Failed to release audio_service lock\n", __func__);
+           } else {
+               wakelock_acquired = false;
+               fprintf(log_file, "%s.Success to release audio_service lock\n", __func__);
+           }
+       } else
+            fprintf(log_file, "%s.No Lock is acquired to release\n", __func__);
+   }
+   return wakelock_acquired;
+}
+
 void stop_signal_handler(int signal __unused)
 {
    stop_record = true;
@@ -295,9 +329,12 @@
   strlcat(param, params->profile, sizeof(param));
   qahw_in_set_parameters(in_handle, param);
 
-  fprintf(log_file, "\n Please speak into the microphone for %lf seconds, handle(%d)\n", params->record_length, params->handle);
+  /* Caution: Below ADL log shouldnt be altered without notifying automation APT since it used for
+   * automation testing
+   */
+  fprintf(log_file, "\n ADL: Please speak into the microphone for %lf seconds, handle(%d)\n", params->record_length, params->handle);
   if (log_file != stdout)
-      fprintf(stdout, "\n Please speak into the microphone for %lf seconds, handle(%d)\n", params->record_length, params->handle);
+      fprintf(stdout, "\n ADL: Please speak into the microphone for %lf seconds, handle(%d)\n", params->record_length, params->handle);
 
   snprintf(file_name + name_len, sizeof(file_name) - name_len, "%d.wav", (0x99A - params->handle));
   FILE *fd = fopen(file_name,"w");
@@ -433,14 +470,17 @@
           fprintf(stdout, "could not close input stream %d, handle(%d)\n",rc, params->handle);
   }
 
-  /* Print instructions to access the file. */
-  fprintf(log_file, "\n\n The audio recording has been saved to %s. Please use adb pull to get "
+  /* Print instructions to access the file.
+   * Caution: Below ADL log shouldnt be altered without notifying automation APT since it used for
+   * automation testing
+   */
+  fprintf(log_file, "\n\n ADL: The audio recording has been saved to %s. Please use adb pull to get "
          "the file and play it using audacity. The audio data has the "
          "following characteristics:\n Sample rate: %i\n Format: %d\n "
          "Num channels: %i, handle(%d)\n\n",
          file_name, params->config.sample_rate, params->config.format, params->channels, params->handle);
   if (log_file != stdout)
-      fprintf(stdout, "\n\n The audio recording has been saved to %s. Please use adb pull to get "
+      fprintf(stdout, "\n\n ADL: The audio recording has been saved to %s. Please use adb pull to get "
          "the file and play it using audacity. The audio data has the "
          "following characteristics:\n Sample rate: %i\n Format: %d\n "
          "Num channels: %i, handle(%d)\n\n",
@@ -547,6 +587,7 @@
     bool interactive_mode = false, source_tracking = false;
     struct listnode param_list;
     char log_filename[256] = "stdout";
+    bool wakelock_acquired = false;
 
     log_file = stdout;
     list_init(&param_list);
@@ -624,6 +665,7 @@
          }
     }
 
+    wakelock_acquired = request_wake_lock(wakelock_acquired, true);
     qahw_mod_handle = qahw_load_module(mod_name);
     if(qahw_mod_handle == NULL) {
         fprintf(log_file, " qahw_load_module failed");
@@ -857,10 +899,14 @@
         fprintf(log_file, "could not unload hal %d \n",ret);
     }
 
-    fprintf(log_file, "\n Done with hal record test \n");
+    /* Caution: Below ADL log shouldnt be altered without notifying automation APT since it used
+     * for automation testing
+     */
+    fprintf(log_file, "\n ADL: Done with hal record test \n");
     if (log_file != stdout) {
-        fprintf(stdout, "\n Done with hal record test \n");
+        fprintf(stdout, "\n ADL: Done with hal record test \n");
         fclose(log_file);
     }
+    wakelock_acquired = request_wake_lock(wakelock_acquired, false);
     return 0;
 }
diff --git a/qahw_api/test/qahw_playback_test.c b/qahw_api/test/qahw_playback_test.c
index 8c6a4ce..cc0a6e2 100644
--- a/qahw_api/test/qahw_playback_test.c
+++ b/qahw_api/test/qahw_playback_test.c
@@ -52,14 +52,21 @@
 #define FORMAT_PCM 1
 #define WAV_HEADER_LENGTH_MAX 46
 
-#define MAX_PLAYBACK_STREAMS   2
+#define MAX_PLAYBACK_STREAMS   3
 #define PRIMARY_STREAM_INDEX   0
 
 #define KVPAIRS_MAX 100
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[1]))
 
+#define FORMAT_DESCRIPTOR_SIZE 12
+#define SUBCHUNK1_SIZE(x) ((8) + (x))
+#define SUBCHUNK2_SIZE 8
+
+#define DEFAULT_PRESET_STRENGTH -1
+
 static int get_wav_header_length (FILE* file_stream);
 static void init_streams(void);
+int pthread_cancel(pthread_t thread);
 
 
 enum {
@@ -78,7 +85,8 @@
     FILE_DTS,
     FILE_MP2,
     FILE_APTX,
-    FILE_TRUEHD
+    FILE_TRUEHD,
+    FILE_IEC61937
 };
 
 typedef enum {
@@ -134,6 +142,7 @@
 
 struct drift_data {
     qahw_module_handle_t *out_handle;
+    bool enable_drift_correction;
     volatile bool thread_exit;
 };
 
@@ -168,7 +177,10 @@
     bool flags_set;
     usb_mode_type_t usb_mode;
     int effect_index;
+    int effect_preset_strength;
     bool drift_query;
+    bool drift_correction;
+    bool play_later;
     char *device_url;
     thread_func_t ethread_func;
     thread_data_t *ethread_data;
@@ -179,6 +191,10 @@
     pthread_mutex_t drain_lock;
 }stream_config;
 
+/* Lock for dual main usecase */
+pthread_cond_t dual_main_cond;
+pthread_mutex_t dual_main_lock;
+bool is_dual_main = false;
 
 qahw_module_handle_t *primary_hal_handle = NULL;
 qahw_module_handle_t *usb_hal_handle = NULL;
@@ -238,6 +254,52 @@
                    "music_offload_wma_encode_option2=%d;" \
                    "music_offload_wma_format_tag=%d;"
 
+#ifndef AUDIO_OUTPUT_FLAG_ASSOCIATED
+#define AUDIO_OUTPUT_FLAG_ASSOCIATED 0x8000
+#endif
+
+
+static bool request_wake_lock(bool wakelock_acquired, bool enable)
+{
+   int system_ret;
+
+   if (enable) {
+       if (!wakelock_acquired) {
+           system_ret = system("echo audio_services > /sys/power/wake_lock");
+               fprintf(stderr, "%s.Failed to acquire audio_service lock\n", __func__);
+               fprintf(log_file, "%s.Failed to acquire audio_service lock\n", __func__);
+           } else {
+               wakelock_acquired = true;
+               fprintf(log_file, "%s.Success to acquire audio_service lock\n", __func__);
+           }
+       } else
+            fprintf(log_file, "%s.Lock is already acquired\n", __func__);
+   }
+
+   if (!enable) {
+       if (wakelock_acquired) {
+           system_ret = system("echo audio_services > /sys/power/wake_unlock");
+           if (system_ret < 0) {
+               fprintf(stderr, "%s.Failed to release audio_service lock\n", __func__);
+               fprintf(log_file, "%s.Failed to release audio_service lock\n", __func__);
+           } else {
+               wakelock_acquired = false;
+               fprintf(log_file, "%s.Success to release audio_service lock\n", __func__);
+           }
+       } else
+            fprintf(log_file, "%s.No Lock is acquired to release\n", __func__);
+   }
+   return wakelock_acquired;
+}
+
+#ifndef AUDIO_FORMAT_AAC_LATM
+#define AUDIO_FORMAT_AAC_LATM 0x23000000UL
+#define AUDIO_FORMAT_AAC_LATM_LC (AUDIO_FORMAT_AAC_LATM | AUDIO_FORMAT_AAC_SUB_LC)
+#define AUDIO_FORMAT_AAC_LATM_HE_V1 (AUDIO_FORMAT_AAC_LATM | AUDIO_FORMAT_AAC_SUB_HE_V1)
+#define AUDIO_FORMAT_AAC_LATM_HE_V2 (AUDIO_FORMAT_AAC_LATM | AUDIO_FORMAT_AAC_SUB_HE_V2)
+#endif
+
+
 void stop_signal_handler(int signal __unused)
 {
    stop_playback = true;
@@ -272,10 +334,12 @@
         stream_param[i].kvpair_values                       =   nullptr;
         stream_param[i].flags_set                           =   false;
         stream_param[i].usb_mode                            =   USB_MODE_DEVICE;
+        stream_param[i].effect_preset_strength              =   DEFAULT_PRESET_STRENGTH;
         stream_param[i].effect_index                        =   -1;
         stream_param[i].ethread_func                        =   nullptr;
         stream_param[i].ethread_data                        =   nullptr;
         stream_param[i].device_url                          =   "stream";
+        stream_param[i].play_later                          =   false;
 
         pthread_mutex_init(&stream_param[i].write_lock, (const pthread_mutexattr_t *)NULL);
         pthread_cond_init(&stream_param[i].write_cond, (const pthread_condattr_t *) NULL);
@@ -285,6 +349,8 @@
         stream_param[i].handle                              =   stream_handle;
         stream_handle--;
     }
+    pthread_mutex_init(&dual_main_lock, (const pthread_mutexattr_t *)NULL);
+    pthread_cond_init(&dual_main_cond, (const pthread_condattr_t *) NULL);
 }
 
 void read_kvpair(char *kvpair, char* kvpair_values, int filetype)
@@ -356,11 +422,16 @@
     case QAHW_STREAM_CBK_EVENT_ADSP:
         fprintf(log_file, "stream %d: received event - QAHW_STREAM_CBK_EVENT_ADSP\n", params->stream_index);
         if (payload != NULL) {
-            fprintf(log_file, "param_length %d\n", payload[0]);
-            for (i=1; i* sizeof(uint32_t) <= payload[0]; i++)
+            fprintf(log_file, "event_type %d\n", payload[0]);
+            fprintf(log_file, "param_length %d\n", payload[1]);
+            for (i=2; i* sizeof(uint32_t) <= payload[1]; i++)
                 fprintf(log_file, "param[%d] = 0x%x\n", i, payload[i]);
         }
         break;
+    case QAHW_STREAM_CBK_EVENT_ERROR:
+        fprintf(log_file, "stream %d: received event - QAHW_STREAM_CBK_EVENT_ERROR\n", params->stream_index);
+        stop_playback = true;
+        break;
     default:
         break;
     }
@@ -452,7 +523,7 @@
     struct qahw_avt_device_drift_param drift_param;
     int rc = -EINVAL;
 
-    printf("drift quried at 100ms interval \n");
+    printf("drift queried at 100ms interval\n");
     while (!(params->thread_exit)) {
         memset(&drift_param, 0, sizeof(struct qahw_avt_device_drift_param));
         rc = qahw_out_get_param_data(out_handle, QAHW_PARAM_AVT_DEVICE_DRIFT,
@@ -467,8 +538,23 @@
         }
 
         usleep(100000);
+        if (params->enable_drift_correction &&
+            drift_param.avt_device_drift_value) {
+            struct qahw_out_correct_drift param;
+            param.adjust_time = drift_param.avt_device_drift_value;
+            printf("sending drift correction value %dus\n",
+                    drift_param.avt_device_drift_value);
+            rc = qahw_out_set_param_data(out_handle,
+                          QAHW_PARAM_OUT_CORRECT_DRIFT,
+                         (qahw_param_payload *)&param);
+            if (rc < 0)
+                fprintf(log_file, "qahw_out_set_param_data failed with err %d %d\n",
+                        rc, __LINE__);
+        }
     }
+    return NULL;
 }
+
 static int is_eof(stream_config *stream) {
     if (stream->filename) {
         if (feof(stream->file_stream)) {
@@ -493,7 +579,59 @@
         in_buf.bytes = size;
         return qahw_in_read(stream->in_handle, &in_buf);
     }
+    return 0;
+}
 
+int write_to_hal(qahw_stream_handle_t* out_handle, char *data, size_t bytes, void *params_ptr)
+{
+    stream_config *stream_params = (stream_config*) params_ptr;
+
+    ssize_t ret;
+    pthread_mutex_lock(&stream_params->write_lock);
+    qahw_out_buffer_t out_buf;
+
+    memset(&out_buf,0, sizeof(qahw_out_buffer_t));
+    out_buf.buffer = data;
+    out_buf.bytes = bytes;
+
+    ret = qahw_out_write(out_handle, &out_buf);
+    if (ret < 0) {
+        fprintf(log_file, "stream %d: writing data to hal failed (ret = %zd)\n", stream_params->stream_index, ret);
+    } else if (ret != bytes) {
+        fprintf(log_file, "stream %d: provided bytes %zd, written bytes %d\n",stream_params->stream_index, bytes, ret);
+        fprintf(log_file, "stream %d: waiting for event write ready\n", stream_params->stream_index);
+        pthread_cond_wait(&stream_params->write_cond, &stream_params->write_lock);
+        fprintf(log_file, "stream %d: out of wait for event write ready\n", stream_params->stream_index);
+    }
+
+    pthread_mutex_unlock(&stream_params->write_lock);
+    return ret;
+}
+
+static bool is_assoc_active()
+{
+    int i = 0;
+    bool is_assoc_active = false;
+
+    for (i = 0; i < MAX_PLAYBACK_STREAMS; i++) {
+        if (stream_param[i].flags & AUDIO_OUTPUT_FLAG_ASSOCIATED) {
+            is_assoc_active = true;
+            break;
+        }
+    }
+    return is_assoc_active;
+}
+
+static int get_assoc_index()
+{
+    int i = 0;
+
+    for (i = 0; i < MAX_PLAYBACK_STREAMS; i++) {
+        if (stream_param[i].flags & AUDIO_OUTPUT_FLAG_ASSOCIATED) {
+            break;
+        }
+    }
+    return i;
 }
 
 /* Entry point function for stream playback
@@ -514,6 +652,17 @@
     pthread_t drift_query_thread;
     struct drift_data drift_params;
 
+    memset(&drift_params, 0, sizeof(struct drift_data));
+
+    fprintf(log_file, "stream %d: play_later %d \n", params->stream_index, params->play_later);
+
+    if(params->play_later) {
+            pthread_mutex_lock(&dual_main_lock);
+            fprintf(log_file, "stream %d: waiting for dual main signal\n", params->stream_index);
+            pthread_cond_wait(&dual_main_cond, &dual_main_lock);
+            fprintf(log_file, "stream %d: after the dual main signal\n", params->stream_index);
+            pthread_mutex_unlock(&dual_main_lock);
+    }
     rc = qahw_open_output_stream(params->qahw_out_hal_handle,
                              params->handle,
                              params->output_device,
@@ -534,10 +683,10 @@
         measure_kpi_values(params->out_handle, params->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
         rc = qahw_close_output_stream(params->out_handle);
         if (rc) {
-            fprintf(log_file, "stream %d: could not close output stream %d, error - %d \n", params->stream_index, rc);
-            fprintf(stderr, "stream %d: could not close output stream %d, error - %d \n", params->stream_index, rc);
+            fprintf(log_file, "stream %d: could not close output stream, error - %d \n", params->stream_index, rc);
+            fprintf(stderr, "stream %d: could not close output stream, error - %d \n", params->stream_index, rc);
         }
-        return;
+        return NULL;
     }
 
     switch(params->filetype) {
@@ -576,6 +725,7 @@
     bool exit = false;
     int32_t latency;
 
+
     if (is_offload) {
         fprintf(log_file, "stream %d: set callback for offload stream for playback usecase\n", params->stream_index);
         qahw_out_set_callback(params->out_handle, async_callback, params);
@@ -616,7 +766,9 @@
             // broadcast device info
             notify_effect_command(params->ethread_data, EFFECT_CMD, QAHW_EFFECT_CMD_SET_DEVICE, sizeof(audio_devices_t), &(params->output_device));
 
-            // enable effect
+            // Enable and Set default values
+            params->ethread_data->default_value = params->effect_preset_strength;
+            params->ethread_data->default_flag = true;
             notify_effect_command(params->ethread_data, EFFECT_CMD, QAHW_EFFECT_CMD_ENABLE, 0, NULL);
         }
     }
@@ -637,12 +789,24 @@
         rc = pthread_create(&proxy_thread, NULL, proxy_read, (void *)&proxy_params);
         if (!rc)
             proxy_thread_active = true;
-    } else if (params->drift_query &&
-              (params->output_device & AUDIO_DEVICE_OUT_HDMI) &&
-              !drift_thread_active) {
+    } else if (params->drift_query && !drift_thread_active) {
+        struct qahw_out_enable_drift_correction drift_enable_param;
+
         drift_params.out_handle = params->out_handle;
         drift_params.thread_exit = false;
-        fprintf(log_file, "create thread to read avtime vs hdmi drift\n");
+        fprintf(log_file, "create thread to read avtimer vs device drift\n");
+        if(params->drift_correction) {
+            drift_params.enable_drift_correction = true;
+            drift_enable_param.enable = true;
+            rc = qahw_out_set_param_data(params->out_handle,
+                    QAHW_PARAM_OUT_ENABLE_DRIFT_CORRECTION,
+                    (qahw_param_payload *)&drift_enable_param);
+            if (rc < 0) {
+                fprintf(log_file, "qahw_out_set_param_data failed with err %d %d\n",
+                        rc, __LINE__);
+                drift_enable_param.enable = false;
+            }
+        }
         rc = pthread_create(&drift_query_thread, NULL, drift_read, (void *)&drift_params);
         if (!rc)
             drift_thread_active = true;
@@ -684,9 +848,12 @@
                         qahw_out_drain(params->out_handle, QAHW_DRAIN_ALL);
                         pthread_cond_wait(&params->drain_cond, &params->drain_lock);
                         fprintf(log_file, "stream %d: out of compress drain\n", params->stream_index);
-                        fprintf(log_file, "stream %d: playback completed successfully\n", params->stream_index);
                         pthread_mutex_unlock(&params->drain_lock);
                     }
+            /* Caution: Below ADL log shouldnt be altered without notifying automation APT since
+             * it used for automation testing
+             */
+                    fprintf(log_file, "ADL: stream %d: playback completed successfully\n", params->stream_index);
                 }
                 exit = true;
                 continue;
@@ -698,6 +865,10 @@
         fprintf(log_file, "stream %d: writing to hal %zd bytes, offset %d, write length %zd\n",
                 params->stream_index, bytes_remaining, offset, write_length);
         bytes_written = write_to_hal(params->out_handle, data_ptr+offset, bytes_remaining, params);
+        if (bytes_written == -1) {
+            fprintf(stderr, "proxy_write failed in usb hal");
+            break;
+        }
         bytes_remaining -= bytes_written;
 
         latency = qahw_out_get_latency(params->out_handle);
@@ -754,6 +925,14 @@
         drift_params.thread_exit = true;
         pthread_join(drift_query_thread, NULL);
     }
+    if ((params->flags & AUDIO_OUTPUT_FLAG_MAIN) && is_assoc_active()) {
+        fprintf(log_file, "Closing Associated as Main Stream reached EOF %d \n", params->stream_index, rc);
+        rc = qahw_close_output_stream(stream_param[get_assoc_index()].out_handle);
+        if (rc) {
+            fprintf(log_file, "stream %d: could not close output stream, error - %d \n", params->stream_index, rc);
+            fprintf(stderr, "stream %d: could not close output stream, error - %d \n", params->stream_index, rc);
+        }
+    }
     rc = qahw_out_standby(params->out_handle);
     if (rc) {
         fprintf(log_file, "stream %d: out standby failed %d \n", params->stream_index, rc);
@@ -771,34 +950,18 @@
         free(data_ptr);
 
     fprintf(log_file, "stream %d: stream closed\n", params->stream_index);
-    return;
-
-}
-
-int write_to_hal(qahw_stream_handle_t* out_handle, char *data, size_t bytes, void *params_ptr)
-{
-    stream_config *stream_params = (stream_config*) params_ptr;
-
-    ssize_t ret;
-    pthread_mutex_lock(&stream_params->write_lock);
-    qahw_out_buffer_t out_buf;
-
-    memset(&out_buf,0, sizeof(qahw_out_buffer_t));
-    out_buf.buffer = data;
-    out_buf.bytes = bytes;
-
-    ret = qahw_out_write(out_handle, &out_buf);
-    if (ret < 0) {
-        fprintf(log_file, "stream %d: writing data to hal failed (ret = %zd)\n", stream_params->stream_index, ret);
-    } else if (ret != bytes) {
-        fprintf(log_file, "stream %d: provided bytes %zd, written bytes %d\n",stream_params->stream_index, bytes, ret);
-        fprintf(log_file, "stream %d: waiting for event write ready\n", stream_params->stream_index);
-        pthread_cond_wait(&stream_params->write_cond, &stream_params->write_lock);
-        fprintf(log_file, "stream %d: out of wait for event write ready\n", stream_params->stream_index);
+    fprintf(log_file, "stream %d: is_dual_main- %d\n", params->stream_index,is_dual_main);
+    if (is_dual_main) {
+        usleep(500000);
+        pthread_mutex_lock(&dual_main_lock);
+        fprintf(log_file, "Dual main signal as we reached end of current running stream\n");
+        is_dual_main = false;
+        pthread_cond_signal(&dual_main_cond);
+        pthread_mutex_unlock(&dual_main_lock);
     }
 
-    pthread_mutex_unlock(&stream_params->write_lock);
-    return ret;
+    return NULL;
+
 }
 
 bool is_valid_aac_format_type(aac_format_type_t format_type)
@@ -970,6 +1133,9 @@
         case FILE_TRUEHD:
             stream_info->config.offload_info.format = AUDIO_FORMAT_DOLBY_TRUEHD;
             break;
+        case FILE_IEC61937:
+            stream_info->config.offload_info.format = AUDIO_FORMAT_IEC61937;
+            break;
         default:
            fprintf(log_file, "Does not support given filetype\n");
            fprintf(stderr, "Does not support given filetype\n");
@@ -978,7 +1144,7 @@
     }
     stream_info->config.sample_rate = stream_info->config.offload_info.sample_rate;
     stream_info->config.format = stream_info->config.offload_info.format;
-    stream_info->config.channel_mask = stream_info->config.offload_info.channel_mask = audio_channel_in_mask_from_count(stream_info->channels);
+    stream_info->config.channel_mask = stream_info->config.offload_info.channel_mask = audio_channel_out_mask_from_count(stream_info->channels);
     return;
 }
 
@@ -1078,6 +1244,7 @@
     event_payload.module_id = 0x10940;
     event_payload.config_mask = 1;
 
+    payload.adsp_event_params.event_type = QAHW_STREAM_PP_EVENT;
     payload.adsp_event_params.payload_length = sizeof(event_payload);
     payload.adsp_event_params.payload = &event_payload;
 
@@ -1149,6 +1316,9 @@
         return -1;
 
     parms = str_parms_create_str(kvpairs);
+    if (parms == NULL)
+        return -1;
+
     if (str_parms_get_str(parms, key, value, KVPAIRS_MAX) < 0)
         return -1;
 
@@ -1173,7 +1343,7 @@
    /*
     * for now we assume usb hal/pcm device announces suport for one format ONLY
     */
-    for (i = 0; i < sizeof(format_table); i++) {
+    for (i = 0; i < (sizeof(format_table)/sizeof(format_table[0])); i++) {
         if(!strncmp(format_table[i].string, value, sizeof(value))) {
             match = true;
             break;
@@ -1244,9 +1414,7 @@
 
 static int detect_stream_params(stream_config *stream) {
     bool detection_needed = false;
-    bool is_usb_loopback = false;
     int direction = PCM_OUT;
-    audio_devices_t dev = stream->input_device;
 
     int rc = 0;
     char *param_string = NULL;
@@ -1276,7 +1444,7 @@
                                 stream->input_device,
                                 &(stream->config),
                                 &(stream->in_handle),
-                                AUDIO_OUTPUT_FLAG_NONE,
+                                AUDIO_INPUT_FLAG_NONE,
                                 stream->device_url,
                                 AUDIO_SOURCE_DEFAULT);
     else
@@ -1311,8 +1479,8 @@
         param_string = qahw_out_get_parameters(stream->out_handle, QAHW_PARAMETER_STREAM_SUP_CHANNELS);
 
     if ((ch = get_channels(param_string)) <= 0) {
-        fprintf(log_file, "Unable to extract channels =(%d) string(%s)\n", ch, param_string);
-        fprintf(stderr, "Unable to extract channels =(%d) string(%s)\n", ch, param_string);
+        fprintf(log_file, "Unable to extract channels =(%d) string(%s)\n", ch, param_string == NULL ? "null":param_string);
+        fprintf(stderr, "Unable to extract channels =(%d) string(%s)\n", ch, param_string == NULL ? "null":param_string);
         return -1;
     }
     stream->config.channel_mask = audio_channel_in_mask_from_count(ch);
@@ -1389,8 +1557,11 @@
     printf(" -E  --event-trigger                       - Trigger DTMF event during playback\n");
     printf(" -e  --effect-type <effect type>           - Effect used for test\n");
     printf("                                             0:bassboost 1:virtualizer 2:equalizer 3:visualizer(NA) 4:reverb 5:audiosphere others:null\n\n");
+    printf(" -p  --effect-preset <effect preset type>  - Effect preset type for respective effect-type\n");
+    printf(" -S  --effect-strength <effect strength>   - Effect strength for respective effect-type\n");
     printf(" -A  --bt-addr <bt device addr>            - Required to set bt device adress for aptx decoder\n\n");
-    printf(" -q  --query drift                         - Required for querying avtime vs hdmi drift\n");
+    printf(" -q  --drift query                         - Required for querying avtime vs hdmi drift\n");
+    printf(" -Q  --drift query and correction          - Enable Drift query and correction\n");
     printf(" -P                                        - Argument to do multi-stream playback, currently 2 streams are supported to run concurrently\n");
     printf("                                             Put -P and mention required attributes for the next stream\n");
     printf("                                             0:bassboost 1:virtualizer 2:equalizer 3:visualizer(NA) 4:reverb 5:audiosphere others:null");
@@ -1483,20 +1654,7 @@
         fprintf(log_file, "This is not a valid wav file \n");
         fprintf(stderr, "This is not a valid wav file \n");
     } else {
-          switch (subchunk_size) {
-          case 16:
-              fprintf(log_file, "44-byte wav header \n");
-              wav_header_len = 44;
-              break;
-          case 18:
-              fprintf(log_file, "46-byte wav header \n");
-              wav_header_len = 46;
-              break;
-          default:
-              fprintf(log_file, "Header contains extra data and is larger than 46 bytes: subchunk_size=%d \n", subchunk_size);
-              wav_header_len = subchunk_size;
-              break;
-          }
+         wav_header_len = FORMAT_DESCRIPTOR_SIZE + SUBCHUNK1_SIZE(subchunk_size) + SUBCHUNK2_SIZE;
     }
     return wav_header_len;
 }
@@ -1582,9 +1740,9 @@
     struct qahw_aptx_dec_param aptx_params;
     int rc = 0;
     int i = 0;
-    int j = 0;
     kpi_mode = false;
     event_trigger = false;
+    bool wakelock_acquired = false;
 
     log_file = stdout;
     proxy_params.acp.file_name = "/data/pcm_dump.wav";
@@ -1615,8 +1773,11 @@
         {"effect-path",   required_argument,    0, 'e'},
         {"bt-addr",       required_argument,    0, 'A'},
         {"query drift",   no_argument,          0, 'q'},
+        {"drift correction",   no_argument,     0, 'Q'},
         {"device-nodeurl",required_argument,    0, 'u'},
         {"mode",          required_argument,    0, 'm'},
+        {"effect-preset",   required_argument,    0, 'p'},
+        {"effect-strength", required_argument,    0, 'S'},
         {"help",          no_argument,          0, 'h'},
         {0, 0, 0, 0}
     };
@@ -1640,7 +1801,7 @@
 
     while ((opt = getopt_long(argc,
                               argv,
-                              "-f:r:c:b:d:s:v:l:t:a:w:k:PD:KF:Ee:A:u:m:qh",
+                              "-f:r:c:b:d:s:v:l:t:a:w:k:PD:KF:Ee:A:u:m:S:p:qQh",
                               long_options,
                               &option_index)) != -1) {
 
@@ -1721,12 +1882,22 @@
                 stream_param[i].ethread_func = effect_thread_funcs[stream_param[i].effect_index];
             }
             break;
+        case 'p':
+            stream_param[i].effect_preset_strength = atoi(optarg);
+            break;
+        case 'S':
+            stream_param[i].effect_preset_strength = atoi(optarg);
+            break;
         case 'A':
             ba = optarg;
             break;
         case 'q':
              stream_param[i].drift_query = true;
              break;
+        case 'Q':
+             stream_param[i].drift_query = true;
+             stream_param[i].drift_correction = true;
+             break;
         case 'P':
             if(i >= MAX_PLAYBACK_STREAMS - 1) {
                 fprintf(log_file, "cannot have more than %d streams\n", MAX_PLAYBACK_STREAMS);
@@ -1750,8 +1921,12 @@
         }
     }
 
+    wakelock_acquired = request_wake_lock(wakelock_acquired, true);
     num_of_streams = i+1;
-    fprintf(log_file, "Starting audio hal tests for streams : %d\n", num_of_streams);
+    /* Caution: Below ADL log shouldnt be altered without notifying automation APT since it used
+     * for automation testing
+     */
+    fprintf(log_file, "ADL: Starting audio hal tests for streams : %d\n", num_of_streams);
 
     if (kpi_mode == true && num_of_streams > 1) {
         fprintf(log_file, "kpi-mode is not supported for multi-playback usecase\n");
@@ -1775,6 +1950,18 @@
         fprintf(stderr, "Failed to register SIGINT:%d\n",errno);
     }
 
+    /* Check for Dual main content */
+    if (num_of_streams >= 2) {
+         is_dual_main = true;
+
+         for(i = 0; i < num_of_streams; i++) {
+              fprintf(log_file, "is_dual_main - %d  stream_param[i].flags - %d\n", is_dual_main, stream_param[i].flags);
+              is_dual_main = is_dual_main && (stream_param[i].flags & AUDIO_OUTPUT_FLAG_MAIN);
+              fprintf(log_file, "is_dual_main - %d  stream_param[i].flags - %d\n", is_dual_main, stream_param[i].flags);
+         }
+
+    }
+
     for (i = 0; i < num_of_streams; i++) {
         stream = &stream_param[i];
 
@@ -1821,7 +2008,7 @@
                                     stream->input_device,
                                     &(stream->config),
                                     &(stream->in_handle),
-                                    AUDIO_OUTPUT_FLAG_NONE,
+                                    AUDIO_INPUT_FLAG_NONE,
                                     stream->device_url,
                                     AUDIO_SOURCE_UNPROCESSED);
             if (rc) {
@@ -1877,6 +2064,11 @@
                 goto exit;
             }
         }
+        if (is_dual_main && i >= 2 ) {
+            stream_param[i].play_later = true;
+            fprintf(log_file, "stream %d: play_later = %d\n", i, stream_param[i].play_later);
+        }
+
 
         rc = pthread_create(&playback_thread[i], NULL, start_stream_playback, (void *)&stream_param[i]);
         if (rc) {
@@ -1910,7 +2102,7 @@
         if (stream_param[i].file_stream != nullptr)
             fclose(stream_param[i].file_stream);
         else if (AUDIO_DEVICE_NONE != stream_param[i].input_device) {
-            if (stream->in_handle) {
+            if (stream != NULL && stream->in_handle) {
                 rc = qahw_close_input_stream(stream->in_handle);
                 if (rc) {
                     fprintf(log_file, "input stream could not be closed\n");
@@ -1926,6 +2118,10 @@
     if ((log_file != stdout) && (log_file != nullptr))
         fclose(log_file);
 
-    fprintf(log_file, "\nBYE BYE\n");
+    wakelock_acquired = request_wake_lock(wakelock_acquired, false);
+    /* Caution: Below ADL log shouldnt be altered without notifying automation APT since it used
+     * for automation testing
+     */
+    fprintf(log_file, "\nADL: BYE BYE\n");
     return 0;
 }
diff --git a/visualizer/Android.mk b/visualizer/Android.mk
index 622af33..8626163 100644
--- a/visualizer/Android.mk
+++ b/visualizer/Android.mk
@@ -21,7 +21,7 @@
 
 LOCAL_CFLAGS+= -O2 -fvisibility=hidden
 
-ifneq ($(filter sdm660 msm8998,$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter sdm660 sdm845 msm8998,$(TARGET_BOARD_PLATFORM)),)
     LOCAL_CFLAGS += -DCAPTURE_DEVICE=7
 endif
 
@@ -33,6 +33,8 @@
 
 LOCAL_MODULE_RELATIVE_PATH := soundfx
 LOCAL_MODULE:= libqcomvisualizer
+LOCAL_MODULE_OWNER := qti
+LOCAL_PROPRIETARY_MODULE := true
 
 LOCAL_C_INCLUDES := \
 	external/tinyalsa/include \
diff --git a/voice_processing/Android.mk b/voice_processing/Android.mk
index 73619c6..72ab1d3 100644
--- a/voice_processing/Android.mk
+++ b/voice_processing/Android.mk
@@ -6,6 +6,8 @@
 LOCAL_MODULE:= libqcomvoiceprocessing
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_RELATIVE_PATH := soundfx
+LOCAL_MODULE_OWNER := qti
+LOCAL_PROPRIETARY_MODULE := true
 
 LOCAL_SRC_FILES:= \
     voice_processing.c