Merge "configs: bengal: Update decimator volume for voip use cases"
diff --git a/configs/atoll/atoll.mk b/configs/atoll/atoll.mk
index a267eaa..3c2bcd4 100644
--- a/configs/atoll/atoll.mk
+++ b/configs/atoll/atoll.mk
@@ -300,6 +300,10 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.use.sw.ape.decoder=true
 
+#enable software decoder for MPEG-H
+PRODUCT_PROPERTY_OVERRIDES += \
+vendor.audio.use.sw.mpegh.decoder=true
+
 #enable hw aac encoder by default
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.hw.aac.encoder=true
diff --git a/configs/bengal/audio_policy_configuration.xml b/configs/bengal/audio_policy_configuration.xml
index 9a384e8..67f5d9d 100644
--- a/configs/bengal/audio_policy_configuration.xml
+++ b/configs/bengal/audio_policy_configuration.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<!-- Copyright (c) 2016-2019, The Linux Foundation. All rights reserved
+<!-- Copyright (c) 2016-2020, The Linux Foundation. All rights reserved
      Not a Contribution.
 -->
 <!-- Copyright (C) 2015 The Android Open Source Project
@@ -21,7 +21,7 @@
     <!-- version section contains a “version” tag in the form “major.minor” e.g version=”1.0” -->
 
     <!-- Global configuration Decalaration -->
-    <globalConfiguration speaker_drc_enabled="true"/>
+    <globalConfiguration speaker_drc_enabled="true" call_screen_mode_supported="true"/>
 
 
     <!-- Modules section:
diff --git a/configs/bengal/bengal.mk b/configs/bengal/bengal.mk
index 5f08986..a9218fe 100644
--- a/configs/bengal/bengal.mk
+++ b/configs/bengal/bengal.mk
@@ -312,6 +312,10 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.use.sw.ape.decoder=true
 
+#enable software decoder for MPEG-H
+PRODUCT_PROPERTY_OVERRIDES += \
+vendor.audio.use.sw.mpegh.decoder=true
+
 #enable hw aac encoder by default
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.hw.aac.encoder=true
diff --git a/configs/bengal/mixer_paths.xml b/configs/bengal/mixer_paths.xml
index 8e22d99..7b851a0 100644
--- a/configs/bengal/mixer_paths.xml
+++ b/configs/bengal/mixer_paths.xml
@@ -188,6 +188,9 @@
     <ctl name="VoiceMMode1_Tx Mixer USB_AUDIO_TX_MMode1" value="0" />
     <!-- Multimode Voice1 Display-Port -->
     <ctl name="DISPLAY_PORT_RX_Voice Mixer VoiceMMode1" value="0" />
+    <!-- Multimode Voice1 proxy-Port -->
+    <ctl name="PROXY_RX_Voice Mixer VoiceMMode1" value="0" />
+    <ctl name="VoiceMMode1_Tx Mixer PROXY_TX_MMode1" value="0" />
     <!-- Miltimode Voice1 end-->
 
     <!-- Multimode Voice2 -->
@@ -205,6 +208,9 @@
     <ctl name="VoiceMMode2_Tx Mixer USB_AUDIO_TX_MMode2" value="0" />
     <!-- Multimode Voice2 Display-Port -->
     <ctl name="DISPLAY_PORT_RX_Voice Mixer VoiceMMode2" value="0" />
+    <!-- Multimode Voice2 proxy-Port -->
+    <ctl name="PROXY_RX_Voice Mixer VoiceMMode2" value="0" />
+    <ctl name="VoiceMMode2_Tx Mixer PROXY_TX_MMode2" value="0" />
     <!-- Multimode Voice2 end-->
 
     <!-- Voice external ec. reference -->
@@ -1981,6 +1987,10 @@
         <path name="incall-rec-uplink" />
     </path>
 
+    <path name="incall-rec-uplink call-proxy-in">
+        <path name="incall-rec-uplink" />
+    </path>
+
     <path name="incall-rec-uplink-compress">
         <ctl name="MultiMedia8 Mixer VOC_REC_UL" value="1" />
     </path>
@@ -2029,6 +2039,10 @@
         <path name="incall-rec-downlink" />
     </path>
 
+   <path name="incall-rec-downlink call-proxy-in">
+        <path name="incall-rec-downlink" />
+   </path>
+
     <path name="incall-rec-downlink-compress">
         <ctl name="MultiMedia8 Mixer VOC_REC_DL" value="1" />
     </path>
@@ -2078,6 +2092,10 @@
         <path name="incall-rec-uplink-and-downlink" />
     </path>
 
+    <path name="incall-rec-uplink-and-downlink call-proxy-in">
+        <path name="incall-rec-uplink-and-downlink" />
+    </path>
+
     <path name="incall-rec-uplink-and-downlink-compress">
         <path name="incall-rec-uplink-compress" />
         <path name="incall-rec-downlink-compress" />
@@ -2176,6 +2194,11 @@
         <ctl name="VoiceMMode1_Tx Mixer TX_CDC_DMA_TX_3_MMode1" value="1" />
     </path>
 
+    <path name="voicemmode1-call call-proxy">
+        <ctl name="PROXY_RX_Voice Mixer VoiceMMode1" value="1" />
+        <ctl name="VoiceMMode1_Tx Mixer PROXY_TX_MMode1" value="1" />
+    </path>
+
     <path name="voicemmode1-call handset">
         <ctl name="RX_CDC_DMA_RX_0_Voice Mixer VoiceMMode1" value="1" />
         <ctl name="VoiceMMode1_Tx Mixer TX_CDC_DMA_TX_3_MMode1" value="1" />
@@ -2289,6 +2312,11 @@
         <ctl name="VoiceMMode2_Tx Mixer TX_CDC_DMA_TX_3_MMode2" value="1" />
     </path>
 
+    <path name="voicemmode2-call call-proxy">
+        <ctl name="PROXY_RX_Voice Mixer VoiceMMode2" value="1" />
+        <ctl name="VoiceMMode2_Tx Mixer PROXY_TX_MMode2" value="1" />
+    </path>
+
     <!-- VoIP Rx settings -->
     <path name="audio-playback-voip">
         <ctl name="RX_CDC_DMA_RX_1 Audio Mixer MultiMedia10" value="1" />
@@ -3377,4 +3405,14 @@
     <path name="incall_music_uplink afe-proxy">
         <path name="incall_music_uplink" />
     </path>
+
+    <path name="incall_music_uplink call-proxy">
+        <path name="incall_music_uplink" />
+    </path>
+
+    <path name="call-proxy">
+    </path>
+
+    <path name="call-proxy-in">
+    </path>
 </mixer>
diff --git a/configs/bengal/mixer_paths_qrd.xml b/configs/bengal/mixer_paths_qrd.xml
index 5247501..f5b92cc 100644
--- a/configs/bengal/mixer_paths_qrd.xml
+++ b/configs/bengal/mixer_paths_qrd.xml
@@ -185,6 +185,10 @@
     <ctl name="VoiceMMode1_Tx Mixer USB_AUDIO_TX_MMode1" value="0" />
     <!-- Multimode Voice1 Display-Port -->
     <ctl name="DISPLAY_PORT_RX_Voice Mixer VoiceMMode1" value="0" />
+    <!-- Multimode Voice1 proxy-Port -->
+    <ctl name="PROXY_RX_Voice Mixer VoiceMMode1" value="0" />
+    <ctl name="VoiceMMode1_Tx Mixer PROXY_TX_MMode1" value="0" />
+
     <!-- Miltimode Voice1 end-->
 
     <!-- Multimode Voice2 -->
@@ -201,6 +205,9 @@
     <ctl name="VoiceMMode2_Tx Mixer USB_AUDIO_TX_MMode2" value="0" />
     <!-- Multimode Voice2 Display-Port -->
     <ctl name="DISPLAY_PORT_RX_Voice Mixer VoiceMMode2" value="0" />
+    <!-- Multimode Voice2 proxy-Port -->
+    <ctl name="PROXY_RX_Voice Mixer VoiceMMode2" value="0" />
+    <ctl name="VoiceMMode2_Tx Mixer PROXY_TX_MMode2" value="0" />
     <!-- Multimode Voice2 end-->
 
     <!-- Voice external ec. reference -->
@@ -1882,6 +1889,10 @@
         <path name="incall-rec-uplink" />
     </path>
 
+    <path name="incall-rec-uplink call-proxy-in">
+        <path name="incall-rec-uplink" />
+    </path>
+
     <path name="incall-rec-uplink-compress">
         <ctl name="MultiMedia8 Mixer VOC_REC_UL" value="1" />
     </path>
@@ -1930,6 +1941,10 @@
         <path name="incall-rec-downlink" />
     </path>
 
+    <path name="incall-rec-downlink call-proxy-in">
+        <path name="incall-rec-downlink" />
+    </path>
+
     <path name="incall-rec-downlink-compress">
         <ctl name="MultiMedia8 Mixer VOC_REC_DL" value="1" />
     </path>
@@ -1979,6 +1994,10 @@
         <path name="incall-rec-uplink-and-downlink" />
     </path>
 
+    <path name="incall-rec-uplink-and-downlink call-proxy-in">
+        <path name="incall-rec-uplink-and-downlink" />
+    </path>
+
     <path name="incall-rec-uplink-and-downlink-compress">
         <path name="incall-rec-uplink-compress" />
         <path name="incall-rec-downlink-compress" />
@@ -2077,6 +2096,11 @@
         <ctl name="VoiceMMode1_Tx Mixer TX_CDC_DMA_TX_3_MMode1" value="1" />
     </path>
 
+    <path name="voicemmode1-call call-proxy">
+        <ctl name="PROXY_RX_Voice Mixer VoiceMMode1" value="1" />
+        <ctl name="VoiceMMode1_Tx Mixer PROXY_TX_MMode1" value="1" />
+    </path>
+
     <path name="voicemmode1-call headphones">
         <ctl name="RX_CDC_DMA_RX_0_Voice Mixer VoiceMMode1" value="1" />
         <ctl name="VoiceMMode1_Tx Mixer TX_CDC_DMA_TX_3_MMode1" value="1" />
@@ -2175,6 +2199,11 @@
         <ctl name="VoiceMMode2_Tx Mixer TX_CDC_DMA_TX_3_MMode2" value="1" />
     </path>
 
+    <path name="voicemmode2-call call-proxy">
+        <ctl name="PROXY_RX_Voice Mixer VoiceMMode2" value="1" />
+        <ctl name="VoiceMMode2_Tx Mixer PROXY_TX_MMode2" value="1" />
+    </path>
+
     <!-- VoIP Rx settings -->
     <path name="audio-playback-voip">
         <ctl name="RX_CDC_DMA_RX_1 Audio Mixer MultiMedia10" value="1" />
@@ -2657,6 +2686,10 @@
         <path name="incall_music_uplink" />
     </path>
 
+    <path name="incall_music_uplink call-proxy">
+        <path name="incall_music_uplink" />
+    </path>
+
    <path name="spkr-rx-calib">
         <ctl name="RX_CDC_DMA_RX_1_DL_HL Switch"  value="1" />
     </path>
@@ -2904,6 +2937,12 @@
     <path name="display-port">
     </path>
 
+    <path name="call-proxy">
+    </path>
+
+    <path name="call-proxy-in">
+    </path>
+
     <path name="speaker-and-usb-headphones">
         <path name="speaker" />
         <path name="usb-headphones" />
diff --git a/configs/bengal/mixer_paths_scubaidp.xml b/configs/bengal/mixer_paths_scubaidp.xml
index 09846c5..7ffefea 100644
--- a/configs/bengal/mixer_paths_scubaidp.xml
+++ b/configs/bengal/mixer_paths_scubaidp.xml
@@ -201,6 +201,9 @@
     <ctl name="VoiceMMode1_Tx Mixer USB_AUDIO_TX_MMode1" value="0" />
     <!-- Multimode Voice1 Display-Port -->
     <ctl name="DISPLAY_PORT_RX_Voice Mixer VoiceMMode1" value="0" />
+    <!-- Multimode Voice1 proxy-Port -->
+    <ctl name="PROXY_RX_Voice Mixer VoiceMMode1" value="0" />
+    <ctl name="VoiceMMode1_Tx Mixer PROXY_TX_MMode1" value="0" />
     <!-- Miltimode Voice1 end-->
 
     <!-- Multimode Voice2 -->
@@ -218,6 +221,9 @@
     <ctl name="VoiceMMode2_Tx Mixer USB_AUDIO_TX_MMode2" value="0" />
     <!-- Multimode Voice2 Display-Port -->
     <ctl name="DISPLAY_PORT_RX_Voice Mixer VoiceMMode2" value="0" />
+    <!-- Multimode Voice2 proxy-Port -->
+    <ctl name="PROXY_RX_Voice Mixer VoiceMMode2" value="0" />
+    <ctl name="VoiceMMode2_Tx Mixer PROXY_TX_MMode2" value="0" />
     <!-- Multimode Voice2 end-->
 
     <!-- Voice external ec. reference -->
@@ -2023,6 +2029,10 @@
         <path name="incall-rec-uplink" />
     </path>
 
+    <path name="incall-rec-uplink call-proxy-in">
+        <path name="incall-rec-uplink" />
+    </path>
+
     <path name="incall-rec-uplink-compress">
         <ctl name="MultiMedia8 Mixer VOC_REC_UL" value="1" />
     </path>
@@ -2075,6 +2085,10 @@
         <path name="incall-rec-downlink" />
     </path>
 
+    <path name="incall-rec-downlink call-proxy-in">
+        <path name="incall-rec-downlink" />
+    </path>
+
     <path name="incall-rec-downlink headset-mic">
         <path name="incall-rec-downlink" />
     </path>
@@ -2132,6 +2146,10 @@
         <path name="incall-rec-uplink-and-downlink" />
     </path>
 
+    <path name="incall-rec-uplink-and-downlink call-proxy-in">
+        <path name="incall-rec-uplink-and-downlink" />
+    </path>
+
     <path name="incall-rec-uplink-and-downlink headset-mic">
         <path name="incall-rec-uplink-and-downlink" />
     </path>
@@ -2243,6 +2261,11 @@
         <ctl name="VoiceMMode1_Tx Mixer TX_CDC_DMA_TX_3_MMode1" value="1" />
     </path>
 
+    <path name="voicemmode1-call call-proxy">
+        <ctl name="PROXY_RX_Voice Mixer VoiceMMode1" value="1" />
+        <ctl name="VoiceMMode1_Tx Mixer PROXY_TX_MMode1" value="1" />
+    </path>
+
     <path name="voicemmode1-call headphones">
         <ctl name="RX_CDC_DMA_RX_0_Voice Mixer VoiceMMode1" value="1" />
         <ctl name="VoiceMMode1_Tx Mixer TX_CDC_DMA_TX_3_MMode1" value="1" />
@@ -2351,6 +2374,11 @@
         <ctl name="VoiceMMode2_Tx Mixer TX_CDC_DMA_TX_3_MMode2" value="1" />
     </path>
 
+    <path name="voicemmode2-call call-proxy">
+        <ctl name="PROXY_RX_Voice Mixer VoiceMMode2" value="1" />
+        <ctl name="VoiceMMode2_Tx Mixer PROXY_TX_MMode2" value="1" />
+    </path>
+
     <!-- VoIP Rx settings -->
     <path name="audio-playback-voip">
         <ctl name="RX_CDC_DMA_RX_0 Audio Mixer MultiMedia10" value="1" />
@@ -3488,4 +3516,14 @@
     <path name="incall_music_uplink afe-proxy">
         <path name="incall_music_uplink" />
     </path>
+
+    <path name="incall_music_uplink call-proxy">
+        <path name="incall_music_uplink" />
+    </path>
+
+    <path name="call-proxy">
+    </path>
+
+    <path name="call-proxy-in">
+    </path>
 </mixer>
diff --git a/configs/bengal/mixer_paths_scubaqrd.xml b/configs/bengal/mixer_paths_scubaqrd.xml
index faaebca..6c983ce 100644
--- a/configs/bengal/mixer_paths_scubaqrd.xml
+++ b/configs/bengal/mixer_paths_scubaqrd.xml
@@ -187,6 +187,9 @@
     <ctl name="VoiceMMode1_Tx Mixer USB_AUDIO_TX_MMode1" value="0" />
     <!-- Multimode Voice1 Display-Port -->
     <ctl name="DISPLAY_PORT_RX_Voice Mixer VoiceMMode1" value="0" />
+    <!-- Multimode Voice1 proxy-Port -->
+    <ctl name="PROXY_RX_Voice Mixer VoiceMMode1" value="0" />
+    <ctl name="VoiceMMode1_Tx Mixer PROXY_TX_MMode1" value="0" />
     <!-- Miltimode Voice1 end-->
 
     <!-- Multimode Voice2 -->
@@ -204,6 +207,9 @@
     <ctl name="VoiceMMode2_Tx Mixer USB_AUDIO_TX_MMode2" value="0" />
     <!-- Multimode Voice2 Display-Port -->
     <ctl name="DISPLAY_PORT_RX_Voice Mixer VoiceMMode2" value="0" />
+    <!-- Multimode Voice2 proxy-Port -->
+    <ctl name="PROXY_RX_Voice Mixer VoiceMMode2" value="0" />
+    <ctl name="VoiceMMode2_Tx Mixer PROXY_TX_MMode2" value="0" />
     <!-- Multimode Voice2 end-->
 
     <!-- Voice external ec. reference -->
@@ -2007,6 +2013,10 @@
         <path name="incall-rec-uplink" />
     </path>
 
+    <path name="incall-rec-uplink call-proxy-in">
+        <path name="incall-rec-uplink" />
+    </path>
+
     <path name="incall-rec-uplink-compress">
         <ctl name="MultiMedia8 Mixer VOC_REC_UL" value="1" />
     </path>
@@ -2059,6 +2069,10 @@
         <path name="incall-rec-downlink" />
     </path>
 
+    <path name="incall-rec-downlink call-proxy-in">
+        <path name="incall-rec-downlink" />
+    </path>
+
     <path name="incall-rec-downlink headset-mic">
         <path name="incall-rec-downlink" />
     </path>
@@ -2116,6 +2130,10 @@
         <path name="incall-rec-uplink-and-downlink" />
     </path>
 
+    <path name="incall-rec-uplink-and-downlink call-proxy-in">
+        <path name="incall-rec-uplink-and-downlink" />
+    </path>
+
     <path name="incall-rec-uplink-and-downlink headset-mic">
         <path name="incall-rec-uplink-and-downlink" />
     </path>
@@ -2227,6 +2245,11 @@
         <ctl name="VoiceMMode1_Tx Mixer TX_CDC_DMA_TX_3_MMode1" value="1" />
     </path>
 
+    <path name="voicemmode1-call call-proxy">
+        <ctl name="PROXY_RX_Voice Mixer VoiceMMode1" value="1" />
+        <ctl name="VoiceMMode1_Tx Mixer PROXY_TX_MMode1" value="1" />
+    </path>
+
     <path name="voicemmode1-call headphones">
         <ctl name="RX_CDC_DMA_RX_0_Voice Mixer VoiceMMode1" value="1" />
         <ctl name="VoiceMMode1_Tx Mixer TX_CDC_DMA_TX_3_MMode1" value="1" />
@@ -2335,6 +2358,11 @@
         <ctl name="VoiceMMode2_Tx Mixer TX_CDC_DMA_TX_3_MMode2" value="1" />
     </path>
 
+    <path name="voicemmode2-call call-proxy">
+        <ctl name="PROXY_RX_Voice Mixer VoiceMMode2" value="1" />
+        <ctl name="VoiceMMode2_Tx Mixer PROXY_TX_MMode2" value="1" />
+    </path>
+
     <!-- VoIP Rx settings -->
     <path name="audio-playback-voip">
         <ctl name="RX_CDC_DMA_RX_0 Audio Mixer MultiMedia10" value="1" />
@@ -3404,4 +3432,13 @@
         <path name="incall_music_uplink" />
     </path>
 
+    <path name="incall_music_uplink call-proxy">
+        <path name="incall_music_uplink" />
+    </path>
+
+    <path name="call-proxy">
+    </path>
+
+    <path name="call-proxy-in">
+    </path>
 </mixer>
diff --git a/configs/kona/kona.mk b/configs/kona/kona.mk
index 6f5c3b5..548ef3d 100644
--- a/configs/kona/kona.mk
+++ b/configs/kona/kona.mk
@@ -311,6 +311,10 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.use.sw.ape.decoder=true
 
+#enable software decoder for MPEG-H
+PRODUCT_PROPERTY_OVERRIDES += \
+vendor.audio.use.sw.mpegh.decoder=true
+
 #enable hw aac encoder by default
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.hw.aac.encoder=true
@@ -362,6 +366,10 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 persist.vendor.bt.aac_frm_ctl.enabled=true
 
+#enable VBR frame ctl
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.vendor.bt.aac_vbr_frm_ctl.enabled=true
+
 #add dynamic feature flags here
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.feature.a2dp_offload.enable=true \
diff --git a/configs/lahaina/audio_policy_configuration.xml b/configs/lahaina/audio_policy_configuration.xml
old mode 100755
new mode 100644
index b019195..2572854
--- a/configs/lahaina/audio_policy_configuration.xml
+++ b/configs/lahaina/audio_policy_configuration.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<!-- Copyright (c) 2016-2019, The Linux Foundation. All rights reserved
+<!-- Copyright (c) 2016-2020, The Linux Foundation. All rights reserved
      Not a Contribution.
 -->
 <!-- Copyright (C) 2015 The Android Open Source Project
@@ -173,6 +173,11 @@
                               samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
                               channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
                 </mixPort>
+                <mixPort name="quad mic" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                        samplingRates="48000"
+                        channelMasks="AUDIO_CHANNEL_INDEX_MASK_4"/>
+                </mixPort>
                 <mixPort name="voip_tx" role="sink"
                          flags="AUDIO_INPUT_FLAG_VOIP_TX">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
@@ -359,6 +364,8 @@
                        sources="USB Device In,USB Headset In"/>
                 <route type="mix" sink="fast input"
                        sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,USB Device In,USB Headset In,Wired Headset Mic"/>
+                <route type="mix" sink="quad mic"
+                       sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,USB Device In,USB Headset In,Wired Headset Mic"/>
                 <route type="mix" sink="voip_tx"
                        sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,USB Device In,USB Headset In,Wired Headset Mic"/>
                 <route type="mix" sink="record_24"
diff --git a/configs/lahaina/lahaina.mk b/configs/lahaina/lahaina.mk
index 1febffb..0471f38 100644
--- a/configs/lahaina/lahaina.mk
+++ b/configs/lahaina/lahaina.mk
@@ -275,6 +275,10 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.use.sw.ape.decoder=true
 
+#enable software decoder for MPEG-H
+PRODUCT_PROPERTY_OVERRIDES += \
+vendor.audio.use.sw.mpegh.decoder=true
+
 #enable hw aac encoder by default
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.hw.aac.encoder=true
diff --git a/configs/lito/lito.mk b/configs/lito/lito.mk
index 3bc4e47..fcf0a96 100644
--- a/configs/lito/lito.mk
+++ b/configs/lito/lito.mk
@@ -215,7 +215,7 @@
     $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/lito/audio_policy_configuration_odm.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml
 else
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)frameworks/av/services/audiopolicy/config/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml
 endif
 
 PRODUCT_COPY_FILES += \
@@ -330,6 +330,10 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.use.sw.ape.decoder=true
 
+#enable software decoder for MPEG-H
+PRODUCT_PROPERTY_OVERRIDES += \
+vendor.audio.use.sw.mpegh.decoder=true
+
 #enable hw aac encoder by default
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.hw.aac.encoder=true
diff --git a/configs/msmnile/audio_platform_info.xml b/configs/msmnile/audio_platform_info.xml
index 042f081..2b09b92 100644
--- a/configs/msmnile/audio_platform_info.xml
+++ b/configs/msmnile/audio_platform_info.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
-<!-- Copyright (c) 2014, 2016-2019, The Linux Foundation. All rights reserved. -->
+<!-- Copyright (c) 2014, 2016-2020, 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 -->
@@ -103,6 +103,9 @@
         <usecase name="USECASE_INCALL_MUSIC_UPLINK" type="out" id="27" />
         <usecase name="USECASE_INCALL_MUSIC_UPLINK2" type="out" id="27" />
         <usecase name="USECASE_AUDIO_RECORD_COMPRESS2" type="in" id="41" />
+        <usecase name="USECASE_INCALL_REC_UPLINK" type="in" id="27" />
+        <usecase name="USECASE_INCALL_REC_DOWNLINK" type="in" id="27" />
+        <usecase name="USECASE_INCALL_REC_UPLINK_AND_DOWNLINK" type="in" id="27" />
     </pcm_ids>
     <config_params>
         <param key="spkr_1_tz_name" value="wsatz.13"/>
diff --git a/configs/msmnile/audio_platform_info_qrd.xml b/configs/msmnile/audio_platform_info_qrd.xml
index 764ffcb..e60219e 100644
--- a/configs/msmnile/audio_platform_info_qrd.xml
+++ b/configs/msmnile/audio_platform_info_qrd.xml
@@ -103,6 +103,9 @@
         <usecase name="USECASE_INCALL_MUSIC_UPLINK" type="out" id="27" />
         <usecase name="USECASE_INCALL_MUSIC_UPLINK2" type="out" id="27" />
         <usecase name="USECASE_AUDIO_RECORD_COMPRESS2" type="in" id="41" />
+        <usecase name="USECASE_INCALL_REC_UPLINK" type="in" id="27" />
+        <usecase name="USECASE_INCALL_REC_DOWNLINK" type="in" id="27" />
+        <usecase name="USECASE_INCALL_REC_UPLINK_AND_DOWNLINK" type="in" id="27" />
     </pcm_ids>
     <config_params>
         <param key="spkr_1_tz_name" value="wsatz.13"/>
diff --git a/configs/msmnile/mixer_paths_pahu.xml b/configs/msmnile/mixer_paths_pahu.xml
index 845def9..e3ad0bf 100644
--- a/configs/msmnile/mixer_paths_pahu.xml
+++ b/configs/msmnile/mixer_paths_pahu.xml
@@ -263,8 +263,8 @@
     <!-- RT Proxy Cal end -->
 
     <!-- Incall Recording -->
-    <ctl name="MultiMedia1 Mixer VOC_REC_UL" value="0" />
-    <ctl name="MultiMedia1 Mixer VOC_REC_DL" value="0" />
+    <ctl name="MultiMedia9 Mixer VOC_REC_UL" value="0" />
+    <ctl name="MultiMedia9 Mixer VOC_REC_DL" value="0" />
     <ctl name="MultiMedia8 Mixer VOC_REC_UL" value="0" />
     <ctl name="MultiMedia8 Mixer VOC_REC_DL" value="0" />
     <!-- Incall Recording End -->
@@ -1337,7 +1337,7 @@
     </path>
 
     <path name="incall-rec-uplink">
-        <ctl name="MultiMedia1 Mixer VOC_REC_UL" value="1" />
+        <ctl name="MultiMedia9 Mixer VOC_REC_UL" value="1" />
     </path>
 
     <path name="incall-rec-uplink bt-sco">
@@ -1381,7 +1381,7 @@
     </path>
 
     <path name="incall-rec-downlink">
-        <ctl name="MultiMedia1 Mixer VOC_REC_DL"  value="1" />
+        <ctl name="MultiMedia9 Mixer VOC_REC_DL"  value="1" />
     </path>
 
     <path name="incall-rec-downlink bt-sco">
diff --git a/configs/msmnile/mixer_paths_tavil.xml b/configs/msmnile/mixer_paths_tavil.xml
index 1892018..c54c467 100644
--- a/configs/msmnile/mixer_paths_tavil.xml
+++ b/configs/msmnile/mixer_paths_tavil.xml
@@ -284,8 +284,8 @@
     <!-- RT Proxy Cal end -->
 
     <!-- Incall Recording -->
-    <ctl name="MultiMedia1 Mixer VOC_REC_UL" value="0" />
-    <ctl name="MultiMedia1 Mixer VOC_REC_DL" value="0" />
+    <ctl name="MultiMedia9 Mixer VOC_REC_UL" value="0" />
+    <ctl name="MultiMedia9 Mixer VOC_REC_DL" value="0" />
     <ctl name="MultiMedia8 Mixer VOC_REC_UL" value="0" />
     <ctl name="MultiMedia8 Mixer VOC_REC_DL" value="0" />
     <ctl name="MultiMedia17 Mixer VOC_REC_UL" value="0" />
@@ -1670,7 +1670,7 @@
     </path>
 
     <path name="incall-rec-uplink">
-        <ctl name="MultiMedia1 Mixer VOC_REC_UL" value="1" />
+        <ctl name="MultiMedia9 Mixer VOC_REC_UL" value="1" />
     </path>
 
     <path name="incall-rec-uplink bt-sco">
@@ -1722,7 +1722,7 @@
     </path>
 
     <path name="incall-rec-downlink">
-        <ctl name="MultiMedia1 Mixer VOC_REC_DL"  value="1" />
+        <ctl name="MultiMedia9 Mixer VOC_REC_DL"  value="1" />
     </path>
 
     <path name="incall-rec-downlink bt-sco">
diff --git a/configs/msmnile/msmnile.mk b/configs/msmnile/msmnile.mk
index 5a6796b..fa9c210 100644
--- a/configs/msmnile/msmnile.mk
+++ b/configs/msmnile/msmnile.mk
@@ -193,7 +193,7 @@
     $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/msmnile/audio_policy_configuration_odm.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml
 else
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)frameworks/av/services/audiopolicy/config/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml
 endif
 
 PRODUCT_COPY_FILES += \
diff --git a/configs/msmnile_au/msmnile_au.mk b/configs/msmnile_au/msmnile_au.mk
index b77c43f..3786432 100644
--- a/configs/msmnile_au/msmnile_au.mk
+++ b/configs/msmnile_au/msmnile_au.mk
@@ -11,6 +11,7 @@
 BOARD_USES_ALSA_AUDIO := true
 
 ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
+USE_CUSTOM_AUDIO_POLICY := 1
 AUDIO_FEATURE_QSSI_COMPLIANCE := true
 AUDIO_FEATURE_ENABLED_COMPRESS_CAPTURE := false
 AUDIO_FEATURE_ENABLED_COMPRESS_INPUT := true
@@ -43,6 +44,7 @@
 AUDIO_FEATURE_ENABLED_3D_AUDIO := false
 AUDIO_FEATURE_ENABLED_AHAL_EXT := false
 DOLBY_ENABLE := false
+AUDIO_FEATURE_ENABLED_EXTENDED_COMPRESS_FORMAT := true
 endif
 
 USE_XML_AUDIO_POLICY_CONF := 1
@@ -265,7 +267,9 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.hw.aac.encoder=true
 
-#enable hardware decoders for WMA & APE by default
+#force offload using hardware decoders for FLAC, WMA & APE
+PRODUCT_PROPERTY_OVERRIDES += \
+vendor.audio.use.hw.flac.decoder=true
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.use.hw.wma.decoder=true
 PRODUCT_PROPERTY_OVERRIDES += \
diff --git a/configs/msmsteppe/msmsteppe.mk b/configs/msmsteppe/msmsteppe.mk
index 512f378..5b53343 100644
--- a/configs/msmsteppe/msmsteppe.mk
+++ b/configs/msmsteppe/msmsteppe.mk
@@ -193,7 +193,7 @@
     $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/msmsteppe/audio_policy_configuration_odm.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml
 else
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)frameworks/av/services/audiopolicy/config/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml
+    $(TOPDIR)vendor/qcom/opensource/audio-hal/primary-hal/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml
 endif
 
 PRODUCT_COPY_FILES += \
diff --git a/configs/msmsteppe_au/msmsteppe_au.mk b/configs/msmsteppe_au/msmsteppe_au.mk
index 6b6e8e3..3c64129 100644
--- a/configs/msmsteppe_au/msmsteppe_au.mk
+++ b/configs/msmsteppe_au/msmsteppe_au.mk
@@ -4,6 +4,7 @@
 BOARD_USES_ALSA_AUDIO := true
 
 ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
+USE_CUSTOM_AUDIO_POLICY := 1
 AUDIO_FEATURE_ENABLED_COMPRESS_CAPTURE := false
 AUDIO_FEATURE_ENABLED_COMPRESS_VOIP := false
 AUDIO_FEATURE_ENABLED_DYNAMIC_ECNS := true
@@ -32,6 +33,7 @@
 AUDIO_FEATURE_ENABLED_A2DP_OFFLOAD := true
 AUDIO_FEATURE_ENABLED_3D_AUDIO := false
 DOLBY_ENABLE := false
+AUDIO_FEATURE_ENABLED_EXTENDED_COMPRESS_FORMAT := true
 endif
 
 USE_XML_AUDIO_POLICY_CONF := 1
@@ -255,7 +257,9 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.hw.aac.encoder=true
 
-#enable hardware decoders for WMA & APE by default
+#force offload using hardware decoders for FLAC, WMA & APE
+PRODUCT_PROPERTY_OVERRIDES += \
+vendor.audio.use.hw.flac.decoder=true
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.use.hw.wma.decoder=true
 PRODUCT_PROPERTY_OVERRIDES += \
diff --git a/configs/trinket/audio_platform_info.xml b/configs/trinket/audio_platform_info.xml
index 1022f0b..9bc7b25 100644
--- a/configs/trinket/audio_platform_info.xml
+++ b/configs/trinket/audio_platform_info.xml
@@ -103,6 +103,9 @@
         <usecase name="USECASE_AUDIO_RECORD_MMAP" type="in" id="33" />
         <usecase name="USECASE_AUDIO_A2DP_ABR_FEEDBACK" type="in" id="12" />
         <usecase name="USECASE_INCALL_MUSIC_UPLINK" type="out" id="27" />
+        <usecase name="USECASE_INCALL_REC_UPLINK" type="in" id="27" />
+        <usecase name="USECASE_INCALL_REC_DOWNLINK" type="in" id="27" />
+        <usecase name="USECASE_INCALL_REC_UPLINK_AND_DOWNLINK" type="in" id="27" />
     </pcm_ids>
     <config_params>
         <param key="spkr_1_tz_name" value="wsatz.11"/>
diff --git a/configs/trinket/audio_platform_info_intcodec.xml b/configs/trinket/audio_platform_info_intcodec.xml
index 84d1d45..f840006 100644
--- a/configs/trinket/audio_platform_info_intcodec.xml
+++ b/configs/trinket/audio_platform_info_intcodec.xml
@@ -65,6 +65,9 @@
         <usecase name="USECASE_AUDIO_RECORD_VOIP" type="in" id="16" />
         <usecase name="USECASE_AUDIO_A2DP_ABR_FEEDBACK" type="in" id="12" />
         <usecase name="USECASE_INCALL_MUSIC_UPLINK" type="out" id="27" />
+        <usecase name="USECASE_INCALL_REC_UPLINK" type="in" id="27" />
+        <usecase name="USECASE_INCALL_REC_DOWNLINK" type="in" id="27" />
+        <usecase name="USECASE_INCALL_REC_UPLINK_AND_DOWNLINK" type="in" id="27" />
     </pcm_ids>
     <config_params>
         <!-- In the below value string, the value indicates default mono -->
diff --git a/configs/trinket/audio_platform_info_qrd.xml b/configs/trinket/audio_platform_info_qrd.xml
index 81dce87..5878964 100644
--- a/configs/trinket/audio_platform_info_qrd.xml
+++ b/configs/trinket/audio_platform_info_qrd.xml
@@ -65,6 +65,9 @@
         <usecase name="USECASE_AUDIO_RECORD_VOIP" type="in" id="16" />
         <usecase name="USECASE_AUDIO_A2DP_ABR_FEEDBACK" type="in" id="12" />
         <usecase name="USECASE_INCALL_MUSIC_UPLINK" type="out" id="27" />
+        <usecase name="USECASE_INCALL_REC_UPLINK" type="in" id="27" />
+        <usecase name="USECASE_INCALL_REC_DOWNLINK" type="in" id="27" />
+        <usecase name="USECASE_INCALL_REC_UPLINK_AND_DOWNLINK" type="in" id="27" />
     </pcm_ids>
     <config_params>
         <!-- In the below value string, the value indicates default mono -->
diff --git a/configs/trinket/mixer_paths_idp.xml b/configs/trinket/mixer_paths_idp.xml
index 80e2bdb..f6096fe 100644
--- a/configs/trinket/mixer_paths_idp.xml
+++ b/configs/trinket/mixer_paths_idp.xml
@@ -219,8 +219,8 @@
     <!-- RT Proxy Cal end -->
 
     <!-- Incall Recording -->
-    <ctl name="MultiMedia1 Mixer VOC_REC_UL" value="0" />
-    <ctl name="MultiMedia1 Mixer VOC_REC_DL" value="0" />
+    <ctl name="MultiMedia9 Mixer VOC_REC_UL" value="0" />
+    <ctl name="MultiMedia9 Mixer VOC_REC_DL" value="0" />
     <ctl name="MultiMedia8 Mixer VOC_REC_UL" value="0" />
     <ctl name="MultiMedia8 Mixer VOC_REC_DL" value="0" />
     <!-- Incall Recording End -->
@@ -1686,7 +1686,7 @@
     </path>
 
     <path name="incall-rec-uplink">
-        <ctl name="MultiMedia1 Mixer VOC_REC_UL" value="1" />
+        <ctl name="MultiMedia9 Mixer VOC_REC_UL" value="1" />
     </path>
 
     <path name="incall-rec-uplink bt-sco">
@@ -1730,7 +1730,7 @@
     </path>
 
     <path name="incall-rec-downlink">
-        <ctl name="MultiMedia1 Mixer VOC_REC_DL"  value="1" />
+        <ctl name="MultiMedia9 Mixer VOC_REC_DL"  value="1" />
     </path>
 
     <path name="incall-rec-downlink bt-sco">
diff --git a/configs/trinket/mixer_paths_qrd.xml b/configs/trinket/mixer_paths_qrd.xml
index 6a740a4..ac0c73f 100644
--- a/configs/trinket/mixer_paths_qrd.xml
+++ b/configs/trinket/mixer_paths_qrd.xml
@@ -219,8 +219,8 @@
     <!-- RT Proxy Cal end -->
 
     <!-- Incall Recording -->
-    <ctl name="MultiMedia1 Mixer VOC_REC_UL" value="0" />
-    <ctl name="MultiMedia1 Mixer VOC_REC_DL" value="0" />
+    <ctl name="MultiMedia9 Mixer VOC_REC_UL" value="0" />
+    <ctl name="MultiMedia9 Mixer VOC_REC_DL" value="0" />
     <ctl name="MultiMedia8 Mixer VOC_REC_UL" value="0" />
     <ctl name="MultiMedia8 Mixer VOC_REC_DL" value="0" />
     <!-- Incall Recording End -->
@@ -1678,7 +1678,7 @@
     </path>
 
     <path name="incall-rec-uplink">
-        <ctl name="MultiMedia1 Mixer VOC_REC_UL" value="1" />
+        <ctl name="MultiMedia9 Mixer VOC_REC_UL" value="1" />
     </path>
 
     <path name="incall-rec-uplink bt-sco">
@@ -1722,7 +1722,7 @@
     </path>
 
     <path name="incall-rec-downlink">
-        <ctl name="MultiMedia1 Mixer VOC_REC_DL"  value="1" />
+        <ctl name="MultiMedia9 Mixer VOC_REC_DL"  value="1" />
     </path>
 
     <path name="incall-rec-downlink bt-sco">
diff --git a/configs/trinket/mixer_paths_tasha.xml b/configs/trinket/mixer_paths_tasha.xml
index fa11aac..a1dfbb1 100644
--- a/configs/trinket/mixer_paths_tasha.xml
+++ b/configs/trinket/mixer_paths_tasha.xml
@@ -448,8 +448,8 @@
     <!-- RT Proxy Cal end -->
 
     <!-- Incall Recording -->
-    <ctl name="MultiMedia1 Mixer VOC_REC_UL" value="0" />
-    <ctl name="MultiMedia1 Mixer VOC_REC_DL" value="0" />
+    <ctl name="MultiMedia9 Mixer VOC_REC_UL" value="0" />
+    <ctl name="MultiMedia9 Mixer VOC_REC_DL" value="0" />
     <ctl name="MultiMedia8 Mixer VOC_REC_UL" value="0" />
     <ctl name="MultiMedia8 Mixer VOC_REC_DL" value="0" />
     <!-- Incall Recording End -->
@@ -1901,7 +1901,7 @@
     </path>
 
     <path name="incall-rec-uplink">
-        <ctl name="MultiMedia1 Mixer VOC_REC_UL" value="1" />
+        <ctl name="MultiMedia9 Mixer VOC_REC_UL" value="1" />
     </path>
 
     <path name="incall-rec-uplink bt-sco">
@@ -1945,7 +1945,7 @@
     </path>
 
     <path name="incall-rec-downlink">
-        <ctl name="MultiMedia1 Mixer VOC_REC_DL"  value="1" />
+        <ctl name="MultiMedia9 Mixer VOC_REC_DL"  value="1" />
     </path>
 
     <path name="incall-rec-downlink bt-sco">
diff --git a/configs/trinket/mixer_paths_tashalite.xml b/configs/trinket/mixer_paths_tashalite.xml
index 4284152..f08b9b9 100644
--- a/configs/trinket/mixer_paths_tashalite.xml
+++ b/configs/trinket/mixer_paths_tashalite.xml
@@ -448,8 +448,8 @@
     <!-- RT Proxy Cal end -->
 
     <!-- Incall Recording -->
-    <ctl name="MultiMedia1 Mixer VOC_REC_UL" value="0" />
-    <ctl name="MultiMedia1 Mixer VOC_REC_DL" value="0" />
+    <ctl name="MultiMedia9 Mixer VOC_REC_UL" value="0" />
+    <ctl name="MultiMedia9 Mixer VOC_REC_DL" value="0" />
     <ctl name="MultiMedia8 Mixer VOC_REC_UL" value="0" />
     <ctl name="MultiMedia8 Mixer VOC_REC_DL" value="0" />
     <!-- Incall Recording End -->
@@ -1900,7 +1900,7 @@
     </path>
 
     <path name="incall-rec-uplink">
-        <ctl name="MultiMedia1 Mixer VOC_REC_UL" value="1" />
+        <ctl name="MultiMedia9 Mixer VOC_REC_UL" value="1" />
     </path>
 
     <path name="incall-rec-uplink bt-sco">
@@ -1944,7 +1944,7 @@
     </path>
 
     <path name="incall-rec-downlink">
-        <ctl name="MultiMedia1 Mixer VOC_REC_DL"  value="1" />
+        <ctl name="MultiMedia9 Mixer VOC_REC_DL"  value="1" />
     </path>
 
     <path name="incall-rec-downlink bt-sco">
diff --git a/configs/trinket/mixer_paths_tavil.xml b/configs/trinket/mixer_paths_tavil.xml
index 5074f7a..643ff03 100644
--- a/configs/trinket/mixer_paths_tavil.xml
+++ b/configs/trinket/mixer_paths_tavil.xml
@@ -268,8 +268,8 @@
     <!-- RT Proxy Cal end -->
 
     <!-- Incall Recording -->
-    <ctl name="MultiMedia1 Mixer VOC_REC_UL" value="0" />
-    <ctl name="MultiMedia1 Mixer VOC_REC_DL" value="0" />
+    <ctl name="MultiMedia9 Mixer VOC_REC_UL" value="0" />
+    <ctl name="MultiMedia9 Mixer VOC_REC_DL" value="0" />
     <ctl name="MultiMedia8 Mixer VOC_REC_UL" value="0" />
     <ctl name="MultiMedia8 Mixer VOC_REC_DL" value="0" />
     <!-- Incall Recording End -->
@@ -1696,7 +1696,7 @@
     </path>
 
     <path name="incall-rec-uplink">
-        <ctl name="MultiMedia1 Mixer VOC_REC_UL" value="1" />
+        <ctl name="MultiMedia9 Mixer VOC_REC_UL" value="1" />
     </path>
 
     <path name="incall-rec-uplink bt-sco">
@@ -1740,7 +1740,7 @@
     </path>
 
     <path name="incall-rec-downlink">
-        <ctl name="MultiMedia1 Mixer VOC_REC_DL"  value="1" />
+        <ctl name="MultiMedia9 Mixer VOC_REC_DL"  value="1" />
     </path>
 
     <path name="incall-rec-downlink bt-sco">
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index 00e581f..8422846 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -2875,8 +2875,10 @@
                     goto param_handled;
                 list_for_each(node, &a2dp.adev->usecase_list) {
                     uc_info = node_to_item(node, struct audio_usecase, list);
-                    if (uc_info->stream.out && uc_info->type == PCM_PLAYBACK &&
-                        is_a2dp_out_device_type(&uc_info->stream.out->device_list)) {
+                    if (uc_info->type == PCM_PLAYBACK &&
+                        (uc_info->out_snd_device == SND_DEVICE_OUT_BT_A2DP ||
+                         uc_info->out_snd_device == SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP ||
+                         uc_info->out_snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP)) {
                         pthread_mutex_unlock(&a2dp.adev->lock);
                         fp_check_a2dp_restore(a2dp.adev, uc_info->stream.out, false);
                         pthread_mutex_lock(&a2dp.adev->lock);
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 786b7181..24dd068 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -5485,6 +5485,11 @@
                                   struct str_parms *);
 static maxxaudio_set_parameters_t maxxaudio_set_parameters;
 
+typedef void (*maxxaudio_get_parameters_t)(struct audio_device *,
+                                  struct str_parms *,
+                                  struct str_parms *);
+static maxxaudio_get_parameters_t maxxaudio_get_parameters;
+
 typedef bool (*maxxaudio_supported_usb_t)();
 static maxxaudio_supported_usb_t maxxaudio_supported_usb;
 
@@ -5512,6 +5517,8 @@
                  (maxxaudio_set_device_t)dlsym(maxxaudio_lib_handle, "ma_set_device")) ||
             !(maxxaudio_set_parameters =
                  (maxxaudio_set_parameters_t)dlsym(maxxaudio_lib_handle, "ma_set_parameters")) ||
+            !(maxxaudio_get_parameters =
+                 (maxxaudio_get_parameters_t)dlsym(maxxaudio_lib_handle, "ma_get_parameters")) ||
             !(maxxaudio_supported_usb =
                  (maxxaudio_supported_usb_t)dlsym(
                                     maxxaudio_lib_handle, "ma_supported_usb"))) {
@@ -5533,6 +5540,7 @@
     maxxaudio_set_state = NULL;
     maxxaudio_set_device = NULL;
     maxxaudio_set_parameters = NULL;
+    maxxaudio_get_parameters = NULL;
     maxxaudio_supported_usb = NULL;
     ALOGW(":: %s: ---- Feature MAXX_AUDIO is disabled ----", __func__);
     return -ENOSYS;
@@ -5580,6 +5588,14 @@
         maxxaudio_set_parameters(adev, parms);
 }
 
+void audio_extn_ma_get_parameters(struct audio_device *adev,
+                                  struct str_parms *query,
+                                  struct str_parms *reply)
+{
+    if (maxxaudio_get_parameters)
+        maxxaudio_get_parameters(adev, query, reply);
+}
+
 bool audio_extn_ma_supported_usb()
 {
     return (maxxaudio_supported_usb ? maxxaudio_supported_usb(): false);
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index c71fbc3..c01954d 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -361,6 +361,9 @@
 void audio_extn_ma_set_device(struct audio_usecase *usecase);
 void audio_extn_ma_set_parameters(struct audio_device *adev,
                                   struct str_parms *parms);
+void audio_extn_ma_get_parameters(struct audio_device *adev,
+                                  struct str_parms *query,
+                                  struct str_parms *reply);
 bool audio_extn_ma_supported_usb();
 bool audio_extn_is_maxx_audio_enabled();
 // --- Function pointers from audio_extn needed by MAXX_AUDIO
diff --git a/hal/audio_extn/maxxaudio.c b/hal/audio_extn/maxxaudio.c
index 88de2f2..f1393f6 100644
--- a/hal/audio_extn/maxxaudio.c
+++ b/hal/audio_extn/maxxaudio.c
@@ -50,10 +50,14 @@
 #define MA_QDSP_SET_VOL         "maxxaudio_qdsp_set_volume"
 #define MA_QDSP_SET_VOLT        "maxxaudio_qdsp_set_volume_table"
 #define MA_QDSP_SET_PARAM       "maxxaudio_qdsp_set_parameter"
+#define MA_QDSP_SET_COMMAND     "maxxaudio_qdsp_set_command"
+#define MA_QDSP_GET_COMMAND     "maxxaudio_qdsp_get_command"
 
 #define SUPPORT_DEV "18d1:5033" // Blackbird usbid
 #define SUPPORTED_USB 0x01
 
+#define WAVES_COMMAND_SIZE 10240
+
 typedef unsigned int effective_scope_flag_t;
 const effective_scope_flag_t EFFECTIVE_SCOPE_RTC = 1 << 0;   /* RTC  */
 const effective_scope_flag_t EFFECTIVE_SCOPE_ACDB = 1 << 1;  /* ACDB */
@@ -145,6 +149,16 @@
                                const struct ma_audio_cal_settings *,
                                unsigned int, double);
 
+typedef bool (*ma_set_cmd_t)(ma_audio_cal_handle_t handle,
+                             const struct ma_audio_cal_settings *,
+                             const char*);
+
+typedef bool (*ma_get_cmd_t)(ma_audio_cal_handle_t handle,
+                             const struct ma_audio_cal_settings *,
+                             const char *,
+                             char *,
+                             uint32_t);
+
 struct ma_platform_data {
     void *waves_handle;
     void *platform;
@@ -158,6 +172,8 @@
     ma_set_volume_t          ma_set_volume;
     ma_set_volume_table_t    ma_set_volume_table;
     ma_set_param_t           ma_set_param;
+    ma_set_cmd_t             ma_set_cmd;
+    ma_get_cmd_t             ma_get_cmd;
     bool speaker_lr_swap;
     bool orientation_used;
     int dispaly_orientation;
@@ -167,6 +183,9 @@
 static uint16_t g_supported_dev = 0;
 static struct ma_state ma_cur_state_table[STREAM_MAX_TYPES];
 static struct ma_platform_data *my_data = NULL;
+static char ma_command_data[WAVES_COMMAND_SIZE];
+static char ma_reply_data[WAVES_COMMAND_SIZE];
+
 // --- external function dependency ---
 fp_platform_set_parameters_t fp_platform_set_parameters;
 fp_audio_extn_get_snd_card_split_t fp_audio_extn_get_snd_card_split;
@@ -276,7 +295,6 @@
 
 static bool check_and_send_all_audio_cal(struct audio_device *adev, ma_cmd_t cmd)
 {
-    int i = 0;
     bool ret = false;
     struct listnode *node;
     struct audio_usecase *usecase;
@@ -476,71 +494,78 @@
 
     my_data->waves_handle = dlopen(lib_path, RTLD_NOW);
     if (my_data->waves_handle == NULL) {
-         ALOGE("%s: DLOPEN failed for %s, %s", __func__, LIB_MA_PARAM, dlerror());
-         goto error;
+        ALOGE("%s: DLOPEN failed for %s, %s", __func__, LIB_MA_PARAM, dlerror());
+        goto error;
     } else {
-         ALOGV("%s: DLOPEN successful for %s", __func__, LIB_MA_PARAM);
+        ALOGV("%s: DLOPEN successful for %s", __func__, LIB_MA_PARAM);
 
-         my_data->ma_param_init = (ma_param_init_t)dlsym(my_data->waves_handle,
-                                   MA_QDSP_PARAM_INIT);
-         if (!my_data->ma_param_init) {
-             ALOGE("%s: dlsym error %s for ma_param_init", __func__, dlerror());
-             goto error;
-         }
+        my_data->ma_param_init = (ma_param_init_t)dlsym(my_data->waves_handle, MA_QDSP_PARAM_INIT);
+        if (!my_data->ma_param_init) {
+            ALOGE("%s: dlsym error %s for ma_param_init", __func__, dlerror());
+            goto error;
+        }
 
-         my_data->ma_param_deinit = (ma_param_deinit_t)dlsym(
-                                     my_data->waves_handle, MA_QDSP_PARAM_DEINIT);
-         if (!my_data->ma_param_deinit) {
-             ALOGE("%s: dlsym error %s for ma_param_deinit", __func__, dlerror());
-             goto error;
-         }
+        my_data->ma_param_deinit = (ma_param_deinit_t)dlsym(my_data->waves_handle,
+                                                            MA_QDSP_PARAM_DEINIT);
+        if (!my_data->ma_param_deinit) {
+            ALOGE("%s: dlsym error %s for ma_param_deinit", __func__, dlerror());
+            goto error;
+        }
 
         my_data->ma_is_feature_used = (ma_is_feature_used_t)dlsym(my_data->waves_handle,
-                                    MA_QDSP_IS_FEATURE_USED);
+                                                                  MA_QDSP_IS_FEATURE_USED);
         if (!my_data->ma_is_feature_used) {
             ALOGV("%s: dlsym error %s for ma_is_feature_used", __func__, dlerror());
         }
 
         my_data->ma_set_orientation = (ma_set_orientation_t)dlsym(my_data->waves_handle,
-                                        MA_QDSP_SET_ORIENTATION);
+                                                                  MA_QDSP_SET_ORIENTATION);
         if (!my_data->ma_set_orientation) {
             ALOGV("%s: dlsym error %s for ma_set_orientation", __func__, dlerror());
         }
 
-         my_data->ma_set_lr_swap = (ma_set_lr_swap_t)dlsym(my_data->waves_handle,
-                                    MA_QDSP_SET_LR_SWAP);
-         if (!my_data->ma_set_lr_swap) {
-             ALOGE("%s: dlsym error %s for ma_set_lr_swap", __func__, dlerror());
-             goto error;
-         }
+        my_data->ma_set_lr_swap = (ma_set_lr_swap_t)dlsym(my_data->waves_handle,
+                                                          MA_QDSP_SET_LR_SWAP);
+        if (!my_data->ma_set_lr_swap) {
+            ALOGE("%s: dlsym error %s for ma_set_lr_swap", __func__, dlerror());
+            goto error;
+        }
 
-         my_data->ma_set_sound_mode = (ma_set_sound_mode_t)dlsym(
-                                       my_data->waves_handle, MA_QDSP_SET_MODE);
-         if (!my_data->ma_set_sound_mode) {
-             ALOGE("%s: dlsym error %s for ma_set_sound_mode", __func__, dlerror());
-             goto error;
-         }
+        my_data->ma_set_sound_mode = (ma_set_sound_mode_t)dlsym(my_data->waves_handle,
+                                                                MA_QDSP_SET_MODE);
+        if (!my_data->ma_set_sound_mode) {
+            ALOGE("%s: dlsym error %s for ma_set_sound_mode", __func__, dlerror());
+            goto error;
+        }
 
-         my_data->ma_set_volume = (ma_set_volume_t)dlsym(my_data->waves_handle,
-                                   MA_QDSP_SET_VOL);
-         if (!my_data->ma_set_volume) {
-             ALOGE("%s: dlsym error %s for ma_set_volume", __func__, dlerror());
-             goto error;
-         }
+        my_data->ma_set_volume = (ma_set_volume_t)dlsym(my_data->waves_handle, MA_QDSP_SET_VOL);
+        if (!my_data->ma_set_volume) {
+            ALOGE("%s: dlsym error %s for ma_set_volume", __func__, dlerror());
+            goto error;
+        }
 
-         my_data->ma_set_volume_table = (ma_set_volume_table_t)dlsym(
-                                         my_data->waves_handle, MA_QDSP_SET_VOLT);
-         if (!my_data->ma_set_volume_table) {
-             ALOGE("%s: dlsym error %s for ma_set_volume_table", __func__, dlerror());
-             goto error;
-         }
+        my_data->ma_set_volume_table = (ma_set_volume_table_t)dlsym(my_data->waves_handle,
+                                                                    MA_QDSP_SET_VOLT);
+        if (!my_data->ma_set_volume_table) {
+            ALOGE("%s: dlsym error %s for ma_set_volume_table", __func__, dlerror());
+            goto error;
+        }
 
-         my_data->ma_set_param = (ma_set_param_t)dlsym(
-                                  my_data->waves_handle, MA_QDSP_SET_PARAM);
-         if (!my_data->ma_set_param) {
-             ALOGE("%s: dlsym error %s for ma_set_param", __func__, dlerror());
-             goto error;
-         }
+        my_data->ma_set_param = (ma_set_param_t)dlsym(my_data->waves_handle, MA_QDSP_SET_PARAM);
+        if (!my_data->ma_set_param) {
+            ALOGE("%s: dlsym error %s for ma_set_param", __func__, dlerror());
+            goto error;
+        }
+
+        my_data->ma_set_cmd = (ma_set_cmd_t)dlsym(my_data->waves_handle, MA_QDSP_SET_COMMAND);
+        if (!my_data->ma_set_cmd) {
+            ALOGE("%s: dlsym error %s for ma_set_cmd", __func__, dlerror());
+        }
+
+        my_data->ma_get_cmd = (ma_get_cmd_t)dlsym(my_data->waves_handle, MA_QDSP_GET_COMMAND);
+        if (!my_data->ma_get_cmd) {
+            ALOGE("%s: dlsym error %s for ma_get_cmd", __func__, dlerror());
+        }
     }
 
     /* get preset table */
@@ -679,7 +704,6 @@
 
 void ma_set_device(struct audio_usecase *usecase)
 {
-    int i = 0;
     struct ma_audio_cal_settings ma_cal;
 
     if (!my_data) {
@@ -731,8 +755,101 @@
     pthread_mutex_unlock(&my_data->lock);
 }
 
-void ma_set_parameters(struct audio_device *adev,
-                                  struct str_parms *parms)
+static bool ma_set_command(struct ma_audio_cal_settings *audio_cal_settings, char *cmd_data)
+{
+    if (my_data->ma_set_cmd)
+        return my_data->ma_set_cmd(g_ma_audio_cal_handle, audio_cal_settings, cmd_data);
+    return false;
+}
+
+static bool ma_get_command(struct ma_audio_cal_settings *audio_cal_settings, char *cmd_data,
+                           char *reply_data, uint32_t reply_size)
+{
+    if (my_data->ma_get_cmd)
+        return my_data->ma_get_cmd(g_ma_audio_cal_handle, audio_cal_settings, cmd_data, reply_data,
+                                   reply_size);
+    return false;
+}
+
+static bool ma_fill_apptype_and_device_from_params(struct str_parms *parms, uint32_t *app_type,
+                                                   struct listnode *devices)
+{
+    int ret;
+    char value[128];
+
+    ret = str_parms_get_str(parms, "cal_apptype", value, sizeof(value));
+
+    if (ret >= 0) {
+        *app_type = (uint32_t)atoi(value);
+        ret = str_parms_get_str(parms, "cal_devid", value, sizeof(value));
+        if (ret >= 0) {
+            update_device_list(devices, (uint32_t)atoi(value), "", true);
+            return true;
+        }
+    }
+    return false;
+}
+
+static bool ma_add_apptype_and_device_to_params(struct str_parms *parms, uint32_t app_type,
+                                                struct listnode *devices)
+{
+    if (0 <= str_parms_add_int(parms, "cal_apptype", app_type)) {
+        if (0 <= str_parms_add_int(parms, "cal_devid", get_device_types(devices))) {
+            return true;
+        }
+    }
+    return false;
+}
+
+static bool ma_get_command_parameters(struct str_parms *query, struct str_parms *reply)
+{
+    struct ma_audio_cal_settings ma_cal;
+    int ret;
+
+    ret = str_parms_get_str(query, "waves_data", ma_command_data, sizeof(ma_command_data));
+    if (ret >= 0) {
+        ma_cal_init(&ma_cal);
+        if (ma_fill_apptype_and_device_from_params(query, &ma_cal.common.app_type,
+                &ma_cal.common.devices)) {
+            ma_add_apptype_and_device_to_params(reply, ma_cal.common.app_type,
+                                                &ma_cal.common.devices);
+            ALOGV("%s: before - command=%s", __func__, (char *)ma_command_data);
+            if (ma_get_command(&ma_cal, ma_command_data, ma_reply_data, sizeof(ma_reply_data))) {
+                str_parms_add_str(reply, "waves_data", ma_reply_data);
+                ALOGV("%s: after - command=%s", __func__, (char *)ma_reply_data);
+                return true;
+            } else {
+                str_parms_add_str(reply, "waves_data", "");
+            }
+        }
+    }
+    return false;
+}
+
+static bool ma_set_command_parameters(struct str_parms *parms)
+{
+    struct ma_audio_cal_settings ma_cal;
+    int ret;
+
+    ret = str_parms_get_str(parms, "waves_data", ma_command_data, sizeof(ma_command_data));
+    if (ret >= 0) {
+        ma_cal_init(&ma_cal);
+        if (ma_fill_apptype_and_device_from_params(parms, &ma_cal.common.app_type,
+                &ma_cal.common.devices)) {
+            return ma_set_command(&ma_cal, ma_command_data);
+        }
+    }
+    return false;
+}
+
+void ma_get_parameters(struct audio_device *adev, struct str_parms *query,
+                       struct str_parms *reply)
+{
+    (void)adev;
+    ma_get_command_parameters(query, reply);
+}
+
+void ma_set_parameters(struct audio_device *adev, struct str_parms *parms)
 {
     int ret;
     int val;
@@ -791,6 +908,8 @@
             }
         }
     }
+
+    ma_set_command_parameters(parms);
 }
 
 bool ma_supported_usb()
diff --git a/hal/audio_extn/sndmonitor.c b/hal/audio_extn/sndmonitor.c
index 4f27db9..ff234fc 100644
--- a/hal/audio_extn/sndmonitor.c
+++ b/hal/audio_extn/sndmonitor.c
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+* Copyright (c) 2016-2020, 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
@@ -224,6 +224,7 @@
             (strncasecmp(card_id, "apq", 3) != 0) &&
             (strncasecmp(card_id, "sa", 2) != 0) &&
             (strncasecmp(card_id, "kona", 4) != 0) &&
+            (strncasecmp(card_id, "lahaina", 7) != 0) &&
             (strncasecmp(card_id, "atoll", 5) != 0) &&
             (strncasecmp(card_id, "bengal", 6) != 0) &&
             (strncasecmp(card_id, "lito", 4) != 0)) {
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index fc75fd1..13910f6 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -65,6 +65,7 @@
 #include <hardware/audio_alsaops.h>
 #include <system/thread_defs.h>
 #include <tinyalsa/asoundlib.h>
+#include <utils/Timers.h> // systemTime
 #include <audio_effects/effect_aec.h>
 #include <audio_effects/effect_ns.h>
 #include <audio_utils/format.h>
@@ -1957,9 +1958,10 @@
     reset_hdmi_sink_caps(out);
 
     /* Cache ext disp type */
-    if (platform_get_ext_disp_type_v2(adev->platform,
+    ret = platform_get_ext_disp_type_v2(adev->platform,
                                       out->extconn.cs.controller,
-                                      out->extconn.cs.stream <= 0)) {
+                                      out->extconn.cs.stream);
+    if(ret < 0) {
         ALOGE("%s: Failed to query disp type, ret:%d", __func__, ret);
         return -EINVAL;
     }
@@ -2642,7 +2644,11 @@
                                  is_single_device_type_equal(&vc_usecase->device_list,
                                                         AUDIO_DEVICE_OUT_HEARING_AID) ||
                                  is_single_device_type_equal(&usecase->device_list,
-                                                     AUDIO_DEVICE_IN_VOICE_CALL))) {
+                                                     AUDIO_DEVICE_IN_VOICE_CALL) ||
+                                 (is_single_device_type_equal(&usecase->device_list,
+                                                     AUDIO_DEVICE_IN_USB_HEADSET) &&
+                                 is_single_device_type_equal(&vc_usecase->device_list,
+                                                        AUDIO_DEVICE_OUT_USB_HEADSET)))) {
                 in_snd_device = vc_usecase->in_snd_device;
                 out_snd_device = vc_usecase->out_snd_device;
             }
@@ -4549,6 +4555,17 @@
     dprintf(fd, "      Standby: %s\n", out->standby ? "yes" : "no");
     dprintf(fd, "      Frames written: %lld\n", (long long)out->written);
 
+    char buffer[256]; // for statistics formatting
+    if (!is_offload_usecase(out->usecase)) {
+        simple_stats_to_string(&out->fifo_underruns, buffer, sizeof(buffer));
+        dprintf(fd, "      Fifo frame underruns: %s\n", buffer);
+    }
+
+    if (out->start_latency_ms.n > 0) {
+        simple_stats_to_string(&out->start_latency_ms, buffer, sizeof(buffer));
+        dprintf(fd, "      Start latency ms: %s\n", buffer);
+    }
+
     if (locked) {
         pthread_mutex_unlock(&out->lock);
     }
@@ -4870,7 +4887,7 @@
 
     err = platform_get_controller_stream_from_params(parms, &ext_controller,
                                                        &ext_stream);
-    if (err >= 0) {
+    if (err == 0) {
         out->extconn.cs.controller = ext_controller;
         out->extconn.cs.stream = ext_stream;
         ALOGD("%s: usecase(%s) new controller/stream (%d/%d)", __func__,
@@ -5705,6 +5722,8 @@
 
     if (out->standby) {
         out->standby = false;
+        const int64_t startNs = systemTime(SYSTEM_TIME_MONOTONIC);
+
         pthread_mutex_lock(&adev->lock);
         if (out->usecase == USECASE_COMPRESS_VOIP_CALL)
             ret = voice_extn_compress_voip_start_output_stream(out);
@@ -5717,6 +5736,7 @@
             goto exit;
         }
         out->started = 1;
+        out->last_fifo_valid = false; // we're coming out of standby, last_fifo isn't valid.
         if (last_known_cal_step != -1) {
             ALOGD("%s: retry previous failed cal level set", __func__);
             audio_hw_send_gain_dep_calibration(last_known_cal_step);
@@ -5731,6 +5751,10 @@
         }
         if (out->set_dual_mono)
             audio_extn_send_dual_mono_mixing_coefficients(out);
+
+        // log startup time in ms.
+        simple_stats_log(
+                &out->start_latency_ms, (systemTime(SYSTEM_TIME_MONOTONIC) - startNs) * 1e-6);
     }
 
     if (adev->is_channel_status_set == false &&
@@ -5885,6 +5909,30 @@
                     bytes_to_write /= 2;
                 }
             }
+
+            // Note: since out_get_presentation_position() is called alternating with out_write()
+            // by AudioFlinger, we can check underruns using the prior timestamp read.
+            // (Alternately we could check if the buffer is empty using pcm_get_htimestamp().
+            if (out->last_fifo_valid) {
+                // compute drain to see if there is an underrun.
+                const int64_t current_ns = systemTime(SYSTEM_TIME_MONOTONIC); // sys call
+                const int64_t frames_by_time =
+                        (current_ns - out->last_fifo_time_ns) * out->config.rate / NANOS_PER_SECOND;
+                const int64_t underrun = frames_by_time - out->last_fifo_frames_remaining;
+
+                if (underrun > 0) {
+                    simple_stats_log(&out->fifo_underruns, underrun);
+
+                    ALOGW("%s: underrun(%lld) "
+                            "frames_by_time(%lld) > out->last_fifo_frames_remaining(%lld)",
+                            __func__,
+                            (long long)out->fifo_underruns.n,
+                            (long long)frames_by_time,
+                            (long long)out->last_fifo_frames_remaining);
+                }
+                out->last_fifo_valid = false;  // we're writing below, mark fifo info as stale.
+            }
+
             ALOGVV("%s: writing buffer (%zu bytes) to pcm device", __func__, bytes);
 
             long ns = 0;
@@ -6114,15 +6162,26 @@
         if (out->pcm) {
             unsigned int avail;
             if (pcm_get_htimestamp(out->pcm, &avail, timestamp) == 0) {
-                size_t kernel_buffer_size = out->config.period_size * out->config.period_count;
-
                 uint64_t signed_frames = 0;
                 uint64_t frames_temp = 0;
 
-                frames_temp = (kernel_buffer_size > avail) ? (kernel_buffer_size - avail) : 0;
+                if (out->kernel_buffer_size > avail) {
+                    frames_temp = out->last_fifo_frames_remaining = out->kernel_buffer_size - avail;
+                } else {
+                    ALOGW("%s: avail:%u > kernel_buffer_size:%zu clamping!",
+                            __func__, avail, out->kernel_buffer_size);
+                    avail = out->kernel_buffer_size;
+                    frames_temp = out->last_fifo_frames_remaining = 0;
+                }
+                out->last_fifo_valid = true;
+                out->last_fifo_time_ns = audio_utils_ns_from_timespec(timestamp);
+
                 if (out->written >= frames_temp)
                     signed_frames = out->written - frames_temp;
 
+                ALOGVV("%s: frames:%lld  avail:%u  kernel_buffer_size:%zu",
+                        __func__, (long long)signed_frames, avail, out->kernel_buffer_size);
+
                 // This adjustment accounts for buffering after app processor.
                 // It is based on estimated DSP latency per use case, rather than exact.
                 frames_temp = platform_render_latency(out->usecase) * out->sample_rate / 1000000LL;
@@ -6141,7 +6200,9 @@
                 *frames = signed_frames;
                 ret = 0;
             }
-        } else if (out->card_status == CARD_STATUS_OFFLINE) {
+        } else if (out->card_status == CARD_STATUS_OFFLINE ||
+            // audioflinger still needs position updates when A2DP is suspended
+            (is_a2dp_out_device_type(&out->device_list) && audio_extn_a2dp_source_is_suspended())) {
             *frames = out->written;
             clock_gettime(CLOCK_MONOTONIC, timestamp);
             if (is_offload_usecase(out->usecase))
@@ -6609,6 +6670,12 @@
     dprintf(fd, "      Frames read: %lld\n", (long long)in->frames_read);
     dprintf(fd, "      Frames muted: %lld\n", (long long)in->frames_muted);
 
+    char buffer[256]; // for statistics formatting
+    if (in->start_latency_ms.n > 0) {
+        simple_stats_to_string(&in->start_latency_ms, buffer, sizeof(buffer));
+        dprintf(fd, "      Start latency ms: %s\n", buffer);
+    }
+
     if (locked) {
         pthread_mutex_unlock(&in->lock);
     }
@@ -6870,6 +6937,8 @@
     }
 
     if (in->standby) {
+        const int64_t startNs = systemTime(SYSTEM_TIME_MONOTONIC);
+
         pthread_mutex_lock(&adev->lock);
         if (in->usecase == USECASE_COMPRESS_VOIP_CALL)
             ret = voice_extn_compress_voip_start_input_stream(in);
@@ -6884,6 +6953,10 @@
             goto exit;
         }
         in->standby = 0;
+
+        // log startup time in ms.
+        simple_stats_log(
+                &in->start_latency_ms, (systemTime(SYSTEM_TIME_MONOTONIC) - startNs) * 1e-6);
     }
 
     /* Avoid read if capture_stopped is set */
@@ -8256,6 +8329,8 @@
     else
         out->af_period_multiplier = 1;
 
+    out->kernel_buffer_size = out->config.period_size * out->config.period_count;
+
     out->standby = 1;
     /* out->muted = false; by calloc() */
     /* out->written = 0; by calloc() */
@@ -8772,6 +8847,7 @@
     voice_get_parameters(adev, query, reply);
     audio_extn_a2dp_get_parameters(query, reply);
     platform_get_parameters(adev->platform, query, reply);
+    audio_extn_ma_get_parameters(adev, query, reply);
     pthread_mutex_unlock(&adev->lock);
 
 exit:
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index cc9e602..5e3c1cb 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -48,6 +48,8 @@
 
 #include <audio_route/audio_route.h>
 #include <audio_utils/ErrorLog.h>
+#include <audio_utils/Statistics.h>
+#include <audio_utils/clock.h>
 #include "audio_defs.h"
 #include "voice.h"
 #include "audio_hw_extn_api.h"
@@ -454,6 +456,16 @@
             int stream;
         } cs;
     } extconn;
+
+    size_t kernel_buffer_size;  // cached value of the alsa buffer size, const after open().
+
+    // last out_get_presentation_position() cached info.
+    bool         last_fifo_valid;
+    unsigned int last_fifo_frames_remaining;
+    int64_t      last_fifo_time_ns;
+
+    simple_stats_t fifo_underruns;  // TODO: keep a list of the last N fifo underrun times.
+    simple_stats_t start_latency_ms;
 };
 
 struct stream_in {
@@ -507,6 +519,8 @@
     int64_t frames_muted; /* total frames muted, not cleared when entering standby */
 
     error_log_t *error_log;
+
+    simple_stats_t start_latency_ms;
 };
 
 typedef enum {
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 235ae1f..b1ba217 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -5269,13 +5269,13 @@
         goto done_key_audcal;
     }
 
-    memset(&cal, 0, sizeof(acdb_audio_cal_cfg_t));
-    /* parse audio calibration keys */
-    ret = parse_audiocal_cfg(parms, &cal);
-
     /* handle audio calibration data now */
     err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_AUD_CALDATA, value, len);
     if (err >= 0) {
+        memset(&cal, 0, sizeof(acdb_audio_cal_cfg_t));
+        /* parse audio calibration keys */
+        ret = parse_audiocal_cfg(parms, &cal);
+
         str_parms_del(parms, AUDIO_PARAMETER_KEY_AUD_CALDATA);
         dlen = strlen(value);
         if(dlen <= 0) {
@@ -5604,15 +5604,16 @@
         goto done;
     }
 
-    memset(&cal, 0, sizeof(acdb_audio_cal_cfg_t));
-    /* parse audiocal configuration keys */
-    ret = parse_audiocal_cfg(query, &cal);
-    if(ret == 0) {
-        /* No calibration keys found */
-        goto done;
-    }
     err = str_parms_get_str(query, AUDIO_PARAMETER_KEY_AUD_CALDATA, value, sizeof(value));
     if (err >= 0) {
+        memset(&cal, 0, sizeof(acdb_audio_cal_cfg_t));
+        /* parse audiocal configuration keys */
+        ret = parse_audiocal_cfg(query, &cal);
+        if (ret == 0) {
+            /* No calibration keys found */
+            goto done;
+        }
+
         str_parms_del(query, AUDIO_PARAMETER_KEY_AUD_CALDATA);
     } else {
         goto done;
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index a1fdc39..a8892f3 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -363,6 +363,7 @@
     struct snd_device_to_mic_map mic_map[SND_DEVICE_MAX];
     struct  spkr_device_chmap *spkr_ch_map;
     bool use_sprk_default_sample_rate;
+    bool is_multiple_sample_rate_combo_supported;
     struct listnode custom_mtmx_params_list;
     struct listnode custom_mtmx_in_params_list;
 };
@@ -1525,9 +1526,6 @@
 #define ULL_PLATFORM_DELAY         (3*1000LL)
 #define MMAP_PLATFORM_DELAY        (3*1000LL)
 
-static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT;
-static bool is_tmus = false;
-
 static bool is_usb_snd_dev(snd_device_t snd_device)
 {
     if (snd_device < SND_DEVICE_IN_BEGIN) {
@@ -1549,7 +1547,7 @@
     return false;
 }
 
-static void check_operator()
+bool is_operator_tmus()
 {
     char value[PROPERTY_VALUE_MAX];
     int mccmnc;
@@ -1574,17 +1572,12 @@
     case 310210:
     case 310200:
     case 310160:
-        is_tmus = true;
-        break;
+        return true;
+    default:
+        return false;
     }
 }
 
-bool is_operator_tmus()
-{
-    pthread_once(&check_op_once_ctl, check_operator);
-    return is_tmus;
-}
-
 static char *get_current_operator()
 {
     struct listnode *node;
@@ -1929,7 +1922,8 @@
         else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_EARPIECE))
             strlcat(ec_ref_mixer_path, " handset",
                     MIXER_PATH_MAX_LENGTH);
-        else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADPHONE))
+        else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADPHONE) ||
+                 compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADSET))
             strlcat(ec_ref_mixer_path, " headphones",
                     MIXER_PATH_MAX_LENGTH);
         else if (compare_device_type(out_devices, AUDIO_DEVICE_OUT_USB_HEADSET))
@@ -3092,6 +3086,7 @@
     my_data->use_sprk_default_sample_rate = true;
     my_data->fluence_in_voice_comm = false;
     my_data->ec_car_state = false;
+    my_data->is_multiple_sample_rate_combo_supported = true;
     platform_reset_edid_info(my_data);
 
     //set max volume step for voice call
@@ -3633,6 +3628,7 @@
                 my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].samplerate_mixer_ctl =
                         strdup("RX_CDC_DMA_RX_1 SampleRate");
                 default_rx_backend = strdup("RX_CDC_DMA_RX_1");
+                my_data->is_multiple_sample_rate_combo_supported = false;
             }
         } else if (!strncmp(snd_card_name, "sdm660", strlen("sdm660")) ||
                !strncmp(snd_card_name, "sdm670", strlen("sdm670")) ||
@@ -5087,6 +5083,23 @@
     return ret;
 }
 
+int is_hdset_combo_device(struct listnode *out_devices)
+{
+     int ret = false;
+
+     if ((compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADPHONE) &&
+          compare_device_type(out_devices, AUDIO_DEVICE_OUT_SPEAKER_SAFE)) ||
+         (compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADSET) &&
+          compare_device_type(out_devices, AUDIO_DEVICE_OUT_SPEAKER_SAFE)) ||
+         (compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADPHONE) &&
+          compare_device_type(out_devices, AUDIO_DEVICE_OUT_SPEAKER)) ||
+         (compare_device_type(out_devices, AUDIO_DEVICE_OUT_WIRED_HEADSET) &&
+          compare_device_type(out_devices, AUDIO_DEVICE_OUT_SPEAKER)))
+         ret = true;
+
+     return ret;
+}
+
 int platform_get_backend_index(snd_device_t snd_device)
 {
     int32_t port = DEFAULT_CODEC_BACKEND;
@@ -6007,7 +6020,7 @@
         }
 
         disp_type = mixer_ctl_get_value(ctl, 0);
-        if (disp_type == EXT_DISPLAY_TYPE_NONE) {
+        if (disp_type <= EXT_DISPLAY_TYPE_NONE) {
              ALOGE("%s: Invalid external display type: %d", __func__, disp_type);
              return -EINVAL;
         }
@@ -7731,13 +7744,13 @@
         goto done_key_audcal;
     }
 
-    memset(&cal, 0, sizeof(acdb_audio_cal_cfg_t));
-    /* parse audio calibration keys */
-    ret = parse_audiocal_cfg(parms, &cal);
-
     /* handle audio calibration data now */
     err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_AUD_CALDATA, value, len);
     if (err >= 0) {
+        memset(&cal, 0, sizeof(acdb_audio_cal_cfg_t));
+        /* parse audio calibration keys */
+        ret = parse_audiocal_cfg(parms, &cal);
+
         str_parms_del(parms, AUDIO_PARAMETER_KEY_AUD_CALDATA);
         dlen = strlen(value);
         if(dlen <= 0) {
@@ -8331,15 +8344,18 @@
         goto done;
     }
 
+    // init cal
     memset(&cal, 0, sizeof(acdb_audio_cal_cfg_t));
-    /* parse audiocal configuration keys */
-    ret = parse_audiocal_cfg(query, &cal);
-    if(ret == 0) {
-        /* No calibration keys found */
-        goto done;
-    }
+
     err = str_parms_get_str(query, AUDIO_PARAMETER_KEY_AUD_CALDATA, value, sizeof(value));
     if (err >= 0) {
+        /* parse audiocal configuration keys */
+        ret = parse_audiocal_cfg(query, &cal);
+        if (ret == 0) {
+            /* No calibration keys found */
+            goto done;
+        }
+
         str_parms_del(query, AUDIO_PARAMETER_KEY_AUD_CALDATA);
     } else {
         goto done;
@@ -9477,6 +9493,12 @@
             sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
             ALOGD("%s:becf: afe: set sample rate to default Sample Rate(48k)",__func__);
         }
+
+        /*set sample rate to 48khz if multiple sample rates are not supported in spkr and hdset*/
+        if (is_hdset_combo_device(&usecase->device_list) &&
+            !my_data->is_multiple_sample_rate_combo_supported)
+            sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+            ALOGD("%s:becf: afe: set default Sample Rate(48k) for combo device",__func__);
     }
 
     if (backend_idx != platform_get_voice_call_backend(adev)
diff --git a/hal/voice_extn/compress_voip.c b/hal/voice_extn/compress_voip.c
index dffe8ed..2ba1617 100644
--- a/hal/voice_extn/compress_voip.c
+++ b/hal/voice_extn/compress_voip.c
@@ -768,7 +768,7 @@
               __func__, adev->snd_card, pcm_dev_tx_id);
         voip_data.pcm_tx = pcm_open(adev->snd_card,
                                     pcm_dev_tx_id,
-                                    PCM_IN, voip_config);
+                                    PCM_IN|PCM_MONOTONIC, voip_config);
         if (voip_data.pcm_tx && !pcm_is_ready(voip_data.pcm_tx)) {
             ALOGE("%s: %s", __func__, pcm_get_error(voip_data.pcm_tx));
             pcm_close(voip_data.pcm_tx);