Merge "DO NOT MERGE Fix AudioEffect reply overflow" into audio-userspace.lnx.2.1-dev
diff --git a/configs/msm8937/msm8937.mk b/configs/msm8937/msm8937.mk
index 1202aba..735aa35 100644
--- a/configs/msm8937/msm8937.mk
+++ b/configs/msm8937/msm8937.mk
@@ -219,3 +219,7 @@
 #Enable HW AAC Encoder by default
 PRODUCT_PROPERTY_OVERRIDES += \
 qcom.hw.aac.encoder=true
+
+#flac sw decoder 24 bit decode capability
+PRODUCT_PROPERTY_OVERRIDES += \
+flac.sw.decoder.24bit.support=true
diff --git a/configs/msm8953/audio_platform_info_extcodec.xml b/configs/msm8953/audio_platform_info_extcodec.xml
index cf68190..ac0eabc 100644
--- a/configs/msm8953/audio_platform_info_extcodec.xml
+++ b/configs/msm8953/audio_platform_info_extcodec.xml
@@ -47,10 +47,13 @@
         <usecase name="USECASE_VOICEMMODE1_CALL" type="out" id="35"/>
         <usecase name="USECASE_VOICEMMODE2_CALL" type="in" id="36"/>
         <usecase name="USECASE_VOICEMMODE2_CALL" type="out" id="36"/>
+        <usecase name="USECASE_AUDIO_SPKR_CALIB_TX" type="in" id="37"/>
         <usecase name="USECASE_QCHAT_CALL" type="in" id="42"/>
         <usecase name="USECASE_QCHAT_CALL" type="out" id="42"/>
     </pcm_ids>
     <config_params>
+        <param key="spkr_1_tz_name" value="wsatz.11"/>
+        <param key="spkr_2_tz_name" value="wsatz.12"/>
         <param key="native_audio_mode" value="src"/>
         <param key="input_mic_max_count" value="4"/>
     </config_params>
diff --git a/configs/msm8953/mixer_paths_mtp.xml b/configs/msm8953/mixer_paths_mtp.xml
index 42a9e68..b9fc59a 100644
--- a/configs/msm8953/mixer_paths_mtp.xml
+++ b/configs/msm8953/mixer_paths_mtp.xml
@@ -442,13 +442,22 @@
         <ctl name="QUIN_MI2S_RX Audio Mixer MultiMedia7" value="1" />
     </path>
 
+    <path name="compress-offload-playback2 afe-proxy">
+        <ctl name="AFE_PCM_RX Audio Mixer MultiMedia7" value="1" />
+    </path>
+
+    <path name="compress-offload-playback2 usb-headphones">
+        <path name="compress-offload-playback2 afe-proxy" />
+    </path>
+
     <path name="compress-offload-playback2 speaker-and-hdmi">
         <path name="compress-offload-playback2 hdmi" />
         <path name="compress-offload-playback2" />
     </path>
 
-    <path name="compress-offload-playback2 afe-proxy">
-        <ctl name="AFE_PCM_RX Audio Mixer MultiMedia7" value="1" />
+    <path name="compress-offload-playback2 speaker-and-usb-headphones">
+        <path name="compress-offload-playback2 usb-headphones" />
+        <path name="compress-offload-playback2" />
     </path>
 
     <path name="compress-offload-playback transmission-fm">
@@ -1105,6 +1114,11 @@
         <path name="headphones" />
     </path>
 
+    <path name="wsa-speaker-and-headphones">
+        <path name="wsa-speaker" />
+        <path name="headphones" />
+    </path>
+
     <path name="usb-headphones">
     </path>
 
@@ -1119,6 +1133,11 @@
         <path name="usb-headphones" />
     </path>
 
+    <path name="wsa-speaker-and-usb-headphones">
+        <path name="wsa-speaker" />
+        <path name="usb-headphones" />
+    </path>
+
     <path name="voice-rec-mic">
         <path name="handset-mic" />
     </path>
@@ -1270,4 +1289,8 @@
           <path name="speaker-and-headphones" />
     </path>
 
+    <path name="wsa-speaker-and-line">
+          <path name="wsa-speaker-and-headphones" />
+    </path>
+
 </mixer>
diff --git a/configs/msm8953/mixer_paths_qrd_sku3.xml b/configs/msm8953/mixer_paths_qrd_sku3.xml
index 0d68a71..486f49a 100644
--- a/configs/msm8953/mixer_paths_qrd_sku3.xml
+++ b/configs/msm8953/mixer_paths_qrd_sku3.xml
@@ -2028,6 +2028,11 @@
         <ctl name="SpkrLeft SWR DAC_Port Switch" value="1" />
     </path>
 
+    <path name="wsa-speaker-and-headphones">
+        <path name="wsa-speaker" />
+        <path name="headphones" />
+    </path>
+
     <path name="usb-headphones">
     </path>
 
@@ -2045,6 +2050,11 @@
         <path name="usb-headphones" />
     </path>
 
+    <path name="wsa-speaker-and-usb-headphones">
+        <path name="wsa-speaker" />
+        <path name="usb-headphones" />
+    </path>
+
     <path name="speaker-and-hdmi">
         <path name="wsa-speaker" />
         <path name="hdmi" />
@@ -2248,4 +2258,9 @@
     <path name="speaker-and-line">
         <path name="speaker-and-headphones" />
     </path>
+
+    <path name="wsa-speaker-and-line">
+        <path name="wsa-speaker" />
+        <path name="headphones" />
+    </path>
 </mixer>
diff --git a/configs/msm8953/mixer_paths_qrd_skum.xml b/configs/msm8953/mixer_paths_qrd_skum.xml
index 8343847..6aa8e1e 100644
--- a/configs/msm8953/mixer_paths_qrd_skum.xml
+++ b/configs/msm8953/mixer_paths_qrd_skum.xml
@@ -366,6 +366,28 @@
         <ctl name="INTERNAL_FM_RX Audio Mixer MultiMedia4" value="1" />
     </path>
 
+    <path name="compress-offload-playback2 hdmi">
+        <ctl name="QUIN_MI2S_RX Audio Mixer MultiMedia7" value="1" />
+    </path>
+
+    <path name="compress-offload-playback2 afe-proxy">
+        <ctl name="AFE_PCM_RX Audio Mixer MultiMedia7" value="1" />
+    </path>
+
+    <path name="compress-offload-playback2 usb-headphones">
+        <path name="compress-offload-playback2 afe-proxy" />
+    </path>
+
+    <path name="compress-offload-playback2 speaker-and-hdmi">
+        <path name="compress-offload-playback2 hdmi" />
+        <path name="compress-offload-playback2" />
+    </path>
+
+    <path name="compress-offload-playback2 speaker-and-usb-headphones">
+        <path name="compress-offload-playback2 usb-headphones" />
+        <path name="compress-offload-playback2" />
+    </path>
+
     <path name="compress-offload-playback3">
         <ctl name="PRI_MI2S_RX Audio Mixer MultiMedia10" value="1" />
     </path>
@@ -795,6 +817,11 @@
         <path name="headphones" />
     </path>
 
+    <path name="wsa-speaker-and-headphones">
+        <path name="wsa-speaker" />
+        <path name="headphones" />
+    </path>
+
     <path name="usb-headphones">
     </path>
 
@@ -809,6 +836,11 @@
         <path name="usb-headphones" />
     </path>
 
+    <path name="wsa-speaker-and-usb-headphones">
+        <path name="wsa-speaker" />
+        <path name="usb-headphones" />
+    </path>
+
     <path name="voice-rec-mic">
         <path name="handset-mic" />
     </path>
@@ -934,4 +966,8 @@
           <path name="speaker-and-headphones" />
     </path>
 
+    <path name="wsa-speaker-and-line">
+          <path name="wsa-speaker-and-headphones" />
+    </path>
+
 </mixer>
diff --git a/configs/msm8953/msm8953.mk b/configs/msm8953/msm8953.mk
index e646646..7da4800 100644
--- a/configs/msm8953/msm8953.mk
+++ b/configs/msm8953/msm8953.mk
@@ -219,3 +219,7 @@
 #Enable HW AAC Encoder by default
 PRODUCT_PROPERTY_OVERRIDES += \
 qcom.hw.aac.encoder=true
+
+#flac sw decoder 24 bit decode capability
+PRODUCT_PROPERTY_OVERRIDES += \
+flac.sw.decoder.24bit.support=true
diff --git a/configs/msm8996/msm8996.mk b/configs/msm8996/msm8996.mk
index 3b83c24..71705cb 100644
--- a/configs/msm8996/msm8996.mk
+++ b/configs/msm8996/msm8996.mk
@@ -196,3 +196,7 @@
 use.qti.sw.alac.decoder=true
 PRODUCT_PROPERTY_OVERRIDES += \
 use.qti.sw.ape.decoder=true
+
+#flac sw decoder 24 bit decode capability
+PRODUCT_PROPERTY_OVERRIDES += \
+flac.sw.decoder.24bit.support=true
diff --git a/configs/msmcobalt/audio_output_policy.conf b/configs/msmcobalt/audio_output_policy.conf
index 67d79bf..1bbaad2 100644
--- a/configs/msmcobalt/audio_output_policy.conf
+++ b/configs/msmcobalt/audio_output_policy.conf
@@ -48,8 +48,8 @@
   }
   compress_passthrough_16 {
     flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING|AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH
-    formats AUDIO_FORMAT_AC3|AUDIO_FORMAT_E_AC3|AUDIO_FORMAT_E_AC3_JOC|AUDIO_FORMAT_DTS|AUDIO_FORMAT_DTS_HD
-    sampling_rates 32000|44100|48000|88200|96000|176400|192000
+    formats AUDIO_FORMAT_AC3|AUDIO_FORMAT_E_AC3|AUDIO_FORMAT_E_AC3_JOC|AUDIO_FORMAT_DTS|AUDIO_FORMAT_DTS_HD|AUDIO_FORMAT_DSD
+    sampling_rates 32000|44100|48000|88200|96000|176400|192000|352800
     bit_width 16
     app_type 69941
   }
diff --git a/configs/msmcobalt/audio_platform_info.xml b/configs/msmcobalt/audio_platform_info.xml
index 512e8ee..f5547dc 100644
--- a/configs/msmcobalt/audio_platform_info.xml
+++ b/configs/msmcobalt/audio_platform_info.xml
@@ -55,6 +55,8 @@
         <usecase name="USECASE_AUDIO_SPKR_CALIB_TX" type="in" id="35"/>
         <usecase name="USECASE_AUDIO_PLAYBACK_AFE_PROXY" type="out" id="6"/>
         <usecase name="USECASE_AUDIO_RECORD_AFE_PROXY" type="in" id="7"/>
+        <usecase name="USECASE_AUDIO_RECORD_LOW_LATENCY" type="in" id="17" />
+        <usecase name="USECASE_AUDIO_PLAYBACK_ULL" type="out" id="17" />
     </pcm_ids>
     <config_params>
         <param key="spkr_1_tz_name" value="wsatz.13"/>
@@ -70,9 +72,12 @@
     <backend_names>
         <device name="SND_DEVICE_OUT_HEADPHONES" backend="headphones" interface="SLIMBUS_6_RX"/>
         <device name="SND_DEVICE_OUT_LINE" backend="headphones" interface="SLIMBUS_6_RX"/>
+        <device name="SND_DEVICE_OUT_ANC_HEADSET" backend="headphones" interface="SLIMBUS_6_RX"/>
         <device name="SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES" backend="speaker-and-headphones" interface="SLIMBUS_0_RX-and-SLIMBUS_6_RX"/>
         <device name="SND_DEVICE_OUT_SPEAKER_AND_LINE" backend="speaker-and-headphones" interface="SLIMBUS_0_RX-and-SLIMBUS_6_RX"/>
+        <device name="SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET" backend="speaker-and-headphones" interface="SLIMBUS_0_RX-and-SLIMBUS_6_RX"/>
         <device name="SND_DEVICE_OUT_VOICE_HEADPHONES" backend="headphones" interface="SLIMBUS_6_RX"/>
+        <device name="SND_DEVICE_OUT_VOICE_ANC_HEADSET" backend="headphones" interface="SLIMBUS_6_RX"/>
         <device name="SND_DEVICE_OUT_VOICE_LINE" backend="headphones" interface="SLIMBUS_6_RX"/>
         <device name="SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES" backend="headphones" interface="SLIMBUS_6_RX"/>
         <device name="SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES" backend="headphones" interface="SLIMBUS_6_RX"/>
diff --git a/configs/msmcobalt/audio_policy.conf b/configs/msmcobalt/audio_policy.conf
index dd827fe..166b9b6 100644
--- a/configs/msmcobalt/audio_policy.conf
+++ b/configs/msmcobalt/audio_policy.conf
@@ -26,21 +26,21 @@
         sampling_rates 44100|48000
         channel_masks AUDIO_CHANNEL_OUT_STEREO
         formats AUDIO_FORMAT_PCM_16_BIT
-        devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_FM|AUDIO_DEVICE_OUT_USB_DEVICE
+        devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_FM|AUDIO_DEVICE_OUT_USB_DEVICE|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER
         flags AUDIO_OUTPUT_FLAG_FAST|AUDIO_OUTPUT_FLAG_PRIMARY
       }
       raw {
         sampling_rates 48000
         channel_masks AUDIO_CHANNEL_OUT_STEREO
         formats AUDIO_FORMAT_PCM_16_BIT
-        devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_USB_DEVICE
+        devices AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_USB_DEVICE|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER
         flags AUDIO_OUTPUT_FLAG_FAST|AUDIO_OUTPUT_FLAG_RAW
       }
       deep_buffer {
          sampling_rates 44100|48000
          channel_masks AUDIO_CHANNEL_OUT_STEREO
          formats AUDIO_FORMAT_PCM_16_BIT
-         devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_FM|AUDIO_DEVICE_OUT_USB_DEVICE
+         devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_FM|AUDIO_DEVICE_OUT_USB_DEVICE|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER
          flags AUDIO_OUTPUT_FLAG_DEEP_BUFFER
       }
       compress_passthrough {
@@ -61,14 +61,21 @@
         sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000|64000|88200|96000|176400|192000
         channel_masks AUDIO_CHANNEL_OUT_MONO|AUDIO_CHANNEL_OUT_STEREO|AUDIO_CHANNEL_OUT_2POINT1|AUDIO_CHANNEL_OUT_QUAD|AUDIO_CHANNEL_OUT_PENTA|AUDIO_CHANNEL_OUT_5POINT1|AUDIO_CHANNEL_OUT_6POINT1|AUDIO_CHANNEL_OUT_7POINT1
         formats AUDIO_FORMAT_PCM_16_BIT|AUDIO_FORMAT_PCM_24_BIT_PACKED|AUDIO_FORMAT_PCM_8_24_BIT
-        devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_USB_DEVICE
+        devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_USB_DEVICE|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER
         flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_DIRECT_PCM
       }
       compress_offload {
         sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000|64000|88200|96000|176400|192000
         channel_masks AUDIO_CHANNEL_OUT_MONO|AUDIO_CHANNEL_OUT_STEREO|AUDIO_CHANNEL_OUT_2POINT1|AUDIO_CHANNEL_OUT_QUAD|AUDIO_CHANNEL_OUT_PENTA|AUDIO_CHANNEL_OUT_5POINT1|AUDIO_CHANNEL_OUT_6POINT1|AUDIO_CHANNEL_OUT_7POINT1
         formats AUDIO_FORMAT_MP3|AUDIO_FORMAT_FLAC|AUDIO_FORMAT_ALAC|AUDIO_FORMAT_APE|AUDIO_FORMAT_AAC_LC|AUDIO_FORMAT_AAC_HE_V1|AUDIO_FORMAT_AAC_HE_V2|AUDIO_FORMAT_WMA|AUDIO_FORMAT_WMA_PRO|AUDIO_FORMAT_VORBIS|AUDIO_FORMAT_AAC_ADTS_LC|AUDIO_FORMAT_AAC_ADTS_HE_V1|AUDIO_FORMAT_AAC_ADTS_HE_V2
-        devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_USB_DEVICE
+        devices AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_EARPIECE|AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE|AUDIO_DEVICE_OUT_ALL_SCO|AUDIO_DEVICE_OUT_AUX_DIGITAL|AUDIO_DEVICE_OUT_PROXY|AUDIO_DEVICE_OUT_USB_DEVICE|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES|AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER
+        flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING
+      }
+      dsd_compress_passthrough {
+        sampling_rates 2822400|5644800
+        channel_masks AUDIO_CHANNEL_OUT_MONO|AUDIO_CHANNEL_OUT_STEREO
+        formats AUDIO_FORMAT_DSD
+        devices AUDIO_DEVICE_OUT_WIRED_HEADSET|AUDIO_DEVICE_OUT_WIRED_HEADPHONE|AUDIO_DEVICE_OUT_LINE
         flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING
       }
       incall_music {
@@ -108,14 +115,6 @@
     }
   }
   a2dp {
-    outputs {
-      a2dp {
-        sampling_rates 44100
-        channel_masks AUDIO_CHANNEL_OUT_STEREO
-        formats AUDIO_FORMAT_PCM_16_BIT
-        devices AUDIO_DEVICE_OUT_ALL_A2DP
-      }
-    }
     inputs {
       a2dp {
         sampling_rates 44100|48000
diff --git a/configs/msmcobalt/audio_policy_configuration.xml b/configs/msmcobalt/audio_policy_configuration.xml
index 235c157..451c85e 100644
--- a/configs/msmcobalt/audio_policy_configuration.xml
+++ b/configs/msmcobalt/audio_policy_configuration.xml
@@ -51,11 +51,9 @@
             <attachedDevices>
                 <item>Earpiece</item>
                 <item>Speaker</item>
-                <item>Telephony Tx</item>
                 <item>Built-In Mic</item>
                 <item>Built-In Back Mic</item>
                 <item>FM Tuner</item>
-                <item>Telephony Rx</item>
             </attachedDevices>
             <defaultOutputDevice>Speaker</defaultOutputDevice>
             <mixPorts>
@@ -118,6 +116,21 @@
                     <profile name="" format="AUDIO_FORMAT_AAC_HE_V2"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
                              channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
+                    <profile name="" format="AUDIO_FORMAT_AC3"
+                             samplingRates="32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1"/>
+                    <profile name="" format="AUDIO_FORMAT_E_AC3"
+                             samplingRates="32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+                    <profile name="" format="AUDIO_FORMAT_E_AC3_JOC"
+                             samplingRates="32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
+                    <profile name="" format="AUDIO_FORMAT_DTS"
+                             samplingRates="32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1"/>
+                    <profile name="" format="AUDIO_FORMAT_DTS_HD"
+                             samplingRates="32000,44100,48000,64000,88200,96000,128000,176400,192000"
+                             channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
                     <profile name="" format="AUDIO_FORMAT_WMA"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
                              channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
@@ -137,9 +150,11 @@
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
                              channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
                 </mixPort>
-                <mixPort name="voice_tx" role="source">
-                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
-                             samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
+                <mixPort name="dsd_compress_passthrough" role="source"
+                         flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING">
+                    <profile name="" format="AUDIO_FORMAT_DSD"
+                             samplingRates="2822400,5644800"
+                             channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
                 </mixPort>
                 <mixPort name="voip_rx" role="source"
                          flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_VOIP_RX">
@@ -168,10 +183,6 @@
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,96000,192000"
                              channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4"/>
                 </mixPort>
-                <mixPort name="voice_rx" role="sink">
-                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
-                             samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
-                </mixPort>
             </mixPorts>
 
             <devicePorts>
@@ -212,10 +223,6 @@
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
                 </devicePort>
-                <devicePort tagName="Telephony Tx" type="AUDIO_DEVICE_OUT_TELEPHONY_TX" role="sink">
-                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
-                             samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
-                </devicePort>
                 <devicePort tagName="HDMI" type="AUDIO_DEVICE_OUT_AUX_DIGITAL" role="sink">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,11025,16000,22050,32000,44100,48000,64000,88200,96000,128000,176400,192000" channelMasks="dynamic"/>
@@ -228,6 +235,22 @@
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
                 </devicePort>
+                <devicePort tagName="BT A2DP Out" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="BT A2DP Headphones" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="BT A2DP Speaker" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+                <devicePort tagName="USB Device Out" type="AUDIO_DEVICE_OUT_USB_DEVICE" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100,48000,64000,88200,96000,128000,176400,192000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
 
                 <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
@@ -253,9 +276,11 @@
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
                 </devicePort>
-                <devicePort tagName="Telephony Rx" type="AUDIO_DEVICE_IN_TELEPHONY_RX" role="source">
+                <devicePort tagName="USB Device In" type="AUDIO_DEVICE_IN_USB_DEVICE" role="source">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
-                             samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
+                             samplingRates="44100,48000,64000,88200,96000,128000,176400,192000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
+                    <profile name="" format="AUDIO_FORMAT_PCM_8_24_BIT"
+                             samplingRates="44100,48000,64000,88200,96000,128000,176400,192000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
                 </devicePort>
             </devicePorts>
             <!-- route declaration, i.e. list all available sources for a given sink -->
@@ -265,11 +290,11 @@
                 <route type="mix" sink="Speaker"
                        sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx"/>
                 <route type="mix" sink="Wired Headset"
-                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx"/>
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,dsd_compress_passthrough,voip_rx"/>
                 <route type="mix" sink="Wired Headphones"
-                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx"/>
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,dsd_compress_passthrough,voip_rx"/>
                 <route type="mix" sink="Line"
-                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx"/>
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,dsd_compress_passthrough,voip_rx"/>
                 <route type="mix" sink="HDMI"
                        sources="primary output,raw,deep_buffer,multichannel,direct_pcm,compressed_offload,compress_passthrough"/>
                 <route type="mix" sink="Proxy"
@@ -278,25 +303,65 @@
                        sources="primary output"/>
                 <route type="mix" sink="BT SCO All"
                        sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx"/>
-                <route type="mix" sink="Telephony Tx"
-                       sources="voice_tx"/>
+                <route type="mix" sink="USB Device Out"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx"/>
                 <route type="mix" sink="primary input"
-                       sources="Wired Headset Mic,BT SCO Headset Mic,FM Tuner,Telephony Rx"/>
+                       sources="Wired Headset Mic,BT SCO Headset Mic,FM Tuner,USB Device In"/>
                 <route type="mix" sink="surround_sound"
                        sources="Built-In Mic,Built-In Back Mic"/>
                 <route type="mix" sink="record_24"
                        sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic"/>
-                <route type="mix" sink="voice_rx"
-                       sources="Telephony Rx"/>
+                <route type="mix" sink="BT A2DP Out"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload"/>
+                <route type="mix" sink="BT A2DP Headphones"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload"/>
+                <route type="mix" sink="BT A2DP Speaker"
+                       sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload"/>
             </routes>
 
         </module>
 
-        <!-- A2dp Audio HAL -->
-        <xi:include href="a2dp_audio_policy_configuration.xml"/>
+        <!-- A2DP Audio HAL -->
+        <module name="a2dp" halVersion="2.0">
+            <mixPorts>
+                <mixPort name="a2dp input" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+                </mixPort>
+            </mixPorts>
+
+            <devicePorts>
+                <devicePort tagName="BT A2DP In" type="AUDIO_DEVICE_IN_BLUETOOTH_A2DP" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
+                </devicePort>
+            </devicePorts>
+
+            <routes>
+                <route type="mix" sink="a2dp input"
+                       sources="BT A2DP In"/>
+            </routes>
+        </module>
 
         <!-- Usb Audio HAL -->
-        <xi:include href="usb_audio_policy_configuration.xml"/>
+        <module name="usb" halVersion="2.0">
+            <mixPorts>
+                <mixPort name="usb_accessory output" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+            </mixPorts>
+            <devicePorts>
+                <devicePort tagName="USB Host Out" type="AUDIO_DEVICE_OUT_USB_ACCESSORY" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="44100" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </devicePort>
+            </devicePorts>
+            <routes>
+                <route type="mix" sink="USB Host Out"
+                       sources="usb_accessory output"/>
+            </routes>
+        </module>
 
         <!-- Remote Submix Audio HAL -->
         <xi:include href="r_submix_audio_policy_configuration.xml"/>
diff --git a/configs/msmcobalt/graphite_ipc_platform_info.xml b/configs/msmcobalt/graphite_ipc_platform_info.xml
new file mode 100644
index 0000000..f6775be
--- /dev/null
+++ b/configs/msmcobalt/graphite_ipc_platform_info.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--- Copyright (c) 2016, 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.                             -->
+<graphite_ipc_platform_info>
+    <no_of_glink_channels value="4">
+    </no_of_glink_channels>
+    <!-- channel 1 configuration -->
+    <glink_channel name="g_glink_ctrl" latency_in_us="5000"
+        no_of_intents="1" intents_size="1024">
+    </glink_channel>
+    <!-- channel 2 configuration -->
+    <glink_channel name="g_glink_persistent_data_ild" latency_in_us="30000"
+        no_of_intents="0">
+    </glink_channel>
+    <!-- channel 3 configuration -->
+    <glink_channel name="g_glink_persistent_data_nild" latency_in_us="30000"
+        no_of_intents="0">
+    </glink_channel>
+    <!-- channel 4 configuration -->
+    <glink_channel name="g_glink_audio_data" latency_in_us="10000"
+        no_of_intents="2" intents_size="4096, 4096">
+    </glink_channel>
+</graphite_ipc_platform_info>
diff --git a/configs/msmcobalt/mixer_paths_dtp.xml b/configs/msmcobalt/mixer_paths_dtp.xml
index 9bcf15b..a6c61e4 100644
--- a/configs/msmcobalt/mixer_paths_dtp.xml
+++ b/configs/msmcobalt/mixer_paths_dtp.xml
@@ -138,6 +138,8 @@
     <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia5" value="0" />
     <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia7" value="0" />
     <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia7" value="0" />
+    <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia8" value="0" />
+    <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia8" value="0" />
     <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia10" value="0" />
     <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia10" value="0" />
     <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia11" value="0" />
@@ -617,7 +619,7 @@
     </path>
 
     <path name="audio-ull-playback">
-        <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia3" value="1" />
+        <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia8" value="1" />
     </path>
 
     <path name="audio-ull-playback speaker-protected">
@@ -634,11 +636,11 @@
     </path>
 
     <path name="audio-ull-playback hdmi">
-        <ctl name="HDMI Mixer MultiMedia3" value="1" />
+        <ctl name="HDMI Mixer MultiMedia8" value="1" />
     </path>
 
     <path name="audio-ull-playback bt-sco">
-        <ctl name="AUX_PCM_RX Audio Mixer MultiMedia3" value="1" />
+        <ctl name="AUX_PCM_RX Audio Mixer MultiMedia8" value="1" />
     </path>
 
     <path name="audio-ull-playback bt-sco-wb">
@@ -652,7 +654,7 @@
     </path>
 
     <path name="audio-ull-playback afe-proxy">
-        <ctl name="AFE_PCM_RX Audio Mixer MultiMedia3" value="1" />
+        <ctl name="AFE_PCM_RX Audio Mixer MultiMedia8" value="1" />
     </path>
     <path name="multi-channel-playback hdmi">
         <ctl name="HDMI Mixer MultiMedia2" value="1" />
@@ -1103,11 +1105,11 @@
     </path>
 
     <path name="low-latency-record">
-      <ctl name="MultiMedia5 Mixer SLIM_0_TX" value="1" />
+      <ctl name="MultiMedia8 Mixer SLIM_0_TX" value="1" />
     </path>
 
     <path name="low-latency-record bt-sco">
-      <ctl name="MultiMedia5 Mixer AUX_PCM_UL_TX" value="1" />
+      <ctl name="MultiMedia8 Mixer AUX_PCM_UL_TX" value="1" />
     </path>
 
     <path name="low-latency-record bt-sco-wb">
@@ -1116,11 +1118,11 @@
     </path>
 
     <path name="low-latency-record usb-headset-mic">
-        <ctl name="MultiMedia5 Mixer AFE_PCM_TX" value="1" />
+        <ctl name="MultiMedia8 Mixer AFE_PCM_TX" value="1" />
     </path>
 
     <path name="low-latency-record capture-fm">
-      <ctl name="MultiMedia5 Mixer TERT_MI2S_TX" value="1" />
+      <ctl name="MultiMedia8 Mixer TERT_MI2S_TX" value="1" />
     </path>
 
     <path name="fm-virtual-record capture-fm">
diff --git a/configs/msmcobalt/mixer_paths_tasha.xml b/configs/msmcobalt/mixer_paths_tasha.xml
index 860d014..d096d1f 100644
--- a/configs/msmcobalt/mixer_paths_tasha.xml
+++ b/configs/msmcobalt/mixer_paths_tasha.xml
@@ -548,6 +548,11 @@
     <ctl name="LSM8 MUX" value="None" />
     <ctl name="SLIMBUS_5_TX LSM Function" value="None" />
     <!-- listen end-->
+    <!-- split a2dp -->
+    <ctl name="BT SampleRate" value="KHZ_8" />
+    <ctl name="AFE Input Channels" value="Zero" />
+    <ctl name="SLIM7_RX ADM Channels" value="Zero" />
+    <!-- split a2dp end-->
 
     <!-- ADSP testfwk -->
     <ctl name="SLIMBUS_DL_HL Switch" value="0" />
@@ -614,7 +619,7 @@
     </path>
 
     <path name="deep-buffer-playback bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="deep-buffer-playback bt-sco" />
     </path>
 
@@ -657,7 +662,7 @@
     </path>
 
     <path name="low-latency-playback bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="low-latency-playback bt-sco" />
     </path>
 
@@ -689,7 +694,7 @@
     </path>
 
     <path name="audio-ull-playback">
-        <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia3" value="1" />
+        <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia8" value="1" />
     </path>
 
     <path name="audio-ull-playback speaker-protected">
@@ -697,7 +702,7 @@
     </path>
 
     <path name="audio-ull-playback headphones">
-        <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia3" value="1" />
+        <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia8" value="1" />
     </path>
 
     <path name="audio-ull-playback speaker-and-headphones">
@@ -706,15 +711,15 @@
     </path>
 
     <path name="audio-ull-playback hdmi">
-        <ctl name="HDMI Mixer MultiMedia3" value="1" />
+        <ctl name="HDMI Mixer MultiMedia8" value="1" />
     </path>
 
     <path name="audio-ull-playback bt-sco">
-        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia3" value="1" />
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia8" value="1" />
     </path>
 
     <path name="audio-ull-playback bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="audio-ull-playback bt-sco" />
     </path>
 
@@ -724,11 +729,11 @@
     </path>
 
     <path name="audio-ull-playback afe-proxy">
-        <ctl name="AFE_PCM_RX Audio Mixer MultiMedia3" value="1" />
+        <ctl name="AFE_PCM_RX Audio Mixer MultiMedia8" value="1" />
     </path>
 
     <path name="audio-ull-playback usb-headphones">
-        <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia3" value="1" />
+        <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia8" value="1" />
     </path>
 
     <path name="multi-channel-playback hdmi">
@@ -760,7 +765,7 @@
     </path>
 
     <path name="compress-offload-playback bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-offload-playback bt-sco" />
     </path>
 
@@ -808,7 +813,7 @@
     </path>
 
     <path name="compress-offload-playback2 bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-offload-playback2 bt-sco" />
     </path>
 
@@ -856,7 +861,7 @@
     </path>
 
     <path name="compress-offload-playback3 bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-offload-playback3 bt-sco" />
     </path>
 
@@ -904,7 +909,7 @@
     </path>
 
     <path name="compress-offload-playback4 bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-offload-playback4 bt-sco" />
     </path>
 
@@ -952,7 +957,7 @@
     </path>
 
     <path name="compress-offload-playback5 bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-offload-playback5 bt-sco" />
     </path>
 
@@ -1000,7 +1005,7 @@
     </path>
 
     <path name="compress-offload-playback6 bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-offload-playback6 bt-sco" />
     </path>
 
@@ -1048,7 +1053,7 @@
     </path>
 
     <path name="compress-offload-playback7 bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-offload-playback7 bt-sco" />
     </path>
 
@@ -1096,7 +1101,7 @@
     </path>
 
     <path name="compress-offload-playback8 bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-offload-playback8 bt-sco" />
     </path>
 
@@ -1144,7 +1149,7 @@
     </path>
 
     <path name="compress-offload-playback9 bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-offload-playback9 bt-sco" />
     </path>
 
@@ -1192,7 +1197,7 @@
     </path>
 
     <path name="audio-record bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="audio-record bt-sco" />
     </path>
 
@@ -1209,7 +1214,7 @@
     </path>
 
     <path name="audio-record-compress bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="audio-record-compress bt-sco" />
     </path>
 
@@ -1218,24 +1223,24 @@
     </path>
 
     <path name="low-latency-record">
-      <ctl name="MultiMedia5 Mixer SLIM_0_TX" value="1" />
+      <ctl name="MultiMedia8 Mixer SLIM_0_TX" value="1" />
     </path>
 
     <path name="low-latency-record bt-sco">
-      <ctl name="MultiMedia5 Mixer SLIM_7_TX" value="1" />
+      <ctl name="MultiMedia8 Mixer SLIM_7_TX" value="1" />
     </path>
 
     <path name="low-latency-record bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="low-latency-record bt-sco" />
     </path>
 
     <path name="low-latency-record usb-headset-mic">
-        <ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="1" />
+        <ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="1" />
     </path>
 
     <path name="low-latency-record capture-fm">
-      <ctl name="MultiMedia5 Mixer SLIM_8_TX" value="1" />
+      <ctl name="MultiMedia8 Mixer SLIM_8_TX" value="1" />
     </path>
 
     <path name="fm-virtual-record capture-fm">
@@ -1393,12 +1398,12 @@
     </path>
 
    <path name="hfp-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="hfp-sco" />
    </path>
 
     <path name="hfp-sco-wb headphones">
-        <ctl name="AUX PCM SampleRate" value="16000" />
+        <ctl name="AUX PCM SampleRate" value="KHZ_16" />
         <path name="hfp-sco headphones" />
     </path>
 
@@ -1419,7 +1424,7 @@
     </path>
 
     <path name="compress-voip-call bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-voip-call bt-sco" />
     </path>
 
@@ -1459,7 +1464,7 @@
     </path>
 
     <path name="vowlan-call bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="vowlan-call bt-sco" />
     </path>
 
@@ -1499,7 +1504,7 @@
     </path>
 
     <path name="voicemmode1-call bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="voicemmode1-call bt-sco" />
     </path>
 
@@ -1539,7 +1544,7 @@
     </path>
 
     <path name="voicemmode2-call bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="voicemmode2-call bt-sco" />
     </path>
 
@@ -1636,15 +1641,6 @@
     </path>
 
     <!-- For Tasha, DMIC numbered from 0 to 5 -->
-    <path name="dmic3">
-        <ctl name="AIF1_CAP Mixer SLIM TX7" value="1"/>
-        <ctl name="SLIM_0_TX Channels" value="One" />
-        <ctl name="SLIM TX7 MUX" value="DEC7" />
-        <ctl name="ADC MUX7" value="DMIC" />
-        <ctl name="DMIC MUX7" value="DMIC2" />
-        <ctl name="IIR0 INP0 MUX" value="DEC7" />
-    </path>
-
     <path name="dmic1">
         <ctl name="AIF1_CAP Mixer SLIM TX7" value="1"/>
         <ctl name="SLIM_0_TX Channels" value="One" />
@@ -1663,6 +1659,15 @@
         <ctl name="IIR0 INP0 MUX" value="DEC7" />
     </path>
 
+    <path name="dmic3">
+        <ctl name="AIF1_CAP Mixer SLIM TX7" value="1"/>
+        <ctl name="SLIM_0_TX Channels" value="One" />
+        <ctl name="SLIM TX7 MUX" value="DEC7" />
+        <ctl name="ADC MUX7" value="DMIC" />
+        <ctl name="DMIC MUX7" value="DMIC2" />
+        <ctl name="IIR0 INP0 MUX" value="DEC7" />
+    </path>
+
     <path name="dmic4">
         <ctl name="AIF1_CAP Mixer SLIM TX7" value="1"/>
         <ctl name="SLIM_0_TX Channels" value="One" />
@@ -1763,11 +1768,11 @@
     </path>
 
     <path name="speaker-mic">
-        <path name="dmic3" />
+        <path name="dmic2" />
     </path>
 
     <path name="speaker-mic-liquid">
-        <path name="dmic3" />
+        <path name="dmic2" />
         <ctl name="DEC7 Volume" value="111" />
     </path>
 
@@ -1820,7 +1825,7 @@
     </path>
 
     <path name="handset-mic">
-        <path name="dmic1" />
+        <path name="dmic3" />
     </path>
 
     <path name="handset-mic-db">
@@ -1847,10 +1852,10 @@
         <ctl name="DMIC MUX5" value="DMIC0" />
         <ctl name="SLIM TX6 MUX" value="DEC6" />
         <ctl name="ADC MUX6" value="DMIC" />
-        <ctl name="DMIC MUX6" value="DMIC4" />
+        <ctl name="DMIC MUX6" value="DMIC2" />
         <ctl name="SLIM TX8 MUX" value="DEC8" />
         <ctl name="ADC MUX8" value="DMIC" />
-        <ctl name="DMIC MUX8" value="DMIC3" />
+        <ctl name="DMIC MUX8" value="DMIC5" />
     </path>
 
     <path name="anc-handset">
@@ -1862,7 +1867,7 @@
         <ctl name="RX0 Digital Volume" value="81" />
         <ctl name="ANC Slot" value="6" />
         <ctl name="ADC MUX10" value="DMIC" />
-        <ctl name="DMIC MUX10" value="DMIC3" />
+        <ctl name="DMIC MUX10" value="DMIC2" />
         <ctl name="ANC0 FB MUX" value="ANC_IN_EAR" />
         <ctl name="ANC EAR Enable Switch" value="1" />
     </path>
@@ -1871,8 +1876,8 @@
         <ctl name="SLIM RX2 MUX" value="AIF4_PB" />
         <ctl name="SLIM RX3 MUX" value="AIF4_PB" />
         <ctl name="SLIM_6_RX Channels" value="Two" />
-        <ctl name= "RX INT1_1 MIX1 INP0" value="RX2" />
-        <ctl name= "RX INT2_1 MIX1 INP0" value="RX3" />
+        <ctl name= "RX INT1_2 MUX" value="RX2" />
+        <ctl name= "RX INT2_2 MUX" value="RX3" />
         <ctl name="RX INT1 DEM MUX" value="CLSH_DSM_OUT" />
         <ctl name="RX INT2 DEM MUX" value="CLSH_DSM_OUT" />
     </path>
@@ -1902,6 +1907,14 @@
         <ctl name= "RX INT2 SPLINE MIX HPHR Native Switch" value="1" />
     </path>
 
+    <path name="hph-highquality-mode">
+        <ctl name="RX HPH Mode" value="CLS_H_LOHIFI" />
+    </path>
+
+    <path name="hph-lowpower-mode">
+        <ctl name="RX HPH Mode" value="CLS_H_LP" />
+    </path>
+
     <path name="line">
         <path name="headphones" />
     </path>
@@ -2146,13 +2159,13 @@
         <ctl name="AANC_SLIM_0_RX MUX" value="SLIMBUS_0_TX" />
         <ctl name="SLIM TX6 MUX" value="DEC6" />
         <ctl name="ADC MUX6" value="DMIC" />
-        <ctl name="DMIC MUX6" value="DMIC0" />
+        <ctl name="DMIC MUX6" value="DMIC2" />
         <ctl name="SLIM TX8 MUX" value="DEC8" />
         <ctl name="ADC MUX8" value="DMIC" />
-        <ctl name="DMIC MUX8" value="DMIC3" />
+        <ctl name="DMIC MUX8" value="DMIC4" />
         <ctl name="SLIM TX9 MUX" value="DEC7" />
         <ctl name="ADC MUX7" value="DMIC" />
-        <ctl name="DMIC MUX7" value="DMIC2" />
+        <ctl name="DMIC MUX7" value="DMIC0" />
         <ctl name="IIR0 INP0 MUX" value="DEC6" />
     </path>
 
@@ -2162,10 +2175,10 @@
         <ctl name="AIF1_CAP Mixer SLIM TX8" value="1" />
         <ctl name="SLIM TX7 MUX" value="DEC7" />
         <ctl name="ADC MUX7" value="DMIC" />
-        <ctl name="DMIC MUX7" value="DMIC0" />
+        <ctl name="DMIC MUX7" value="DMIC2" />
         <ctl name="SLIM TX8 MUX" value="DEC8" />
         <ctl name="ADC MUX8" value="DMIC" />
-        <ctl name="DMIC MUX8" value="DMIC3" />
+        <ctl name="DMIC MUX8" value="DMIC4" />
         <ctl name="SLIM_0_TX Channels" value="Two" />
     </path>
 
@@ -2174,10 +2187,10 @@
         <ctl name="AIF1_CAP Mixer SLIM TX8" value="1" />
         <ctl name="SLIM TX7 MUX" value="DEC7" />
         <ctl name="ADC MUX7" value="DMIC" />
-        <ctl name="DMIC MUX7" value="DMIC2" />
+        <ctl name="DMIC MUX7" value="DMIC1" />
         <ctl name="SLIM TX8 MUX" value="DEC8" />
         <ctl name="ADC MUX8" value="DMIC" />
-        <ctl name="DMIC MUX8" value="DMIC3" />
+        <ctl name="DMIC MUX8" value="DMIC5" />
         <ctl name="SLIM_0_TX Channels" value="Two" />
     </path>
 
@@ -2249,7 +2262,7 @@
         <ctl name="SLIM_0_TX Channels" value="Two" />
         <ctl name="SLIM TX7 MUX" value="DEC7" />
         <ctl name="ADC MUX7" value="DMIC" />
-        <ctl name="DMIC MUX7" value="DMIC0" />
+        <ctl name="DMIC MUX7" value="DMIC1" />
         <ctl name="SLIM TX8 MUX" value="DEC8" />
         <ctl name="ADC MUX8" value="DMIC" />
         <ctl name="DMIC MUX8" value="DMIC2" />
@@ -2273,16 +2286,16 @@
         <ctl name="SLIM_0_TX Channels" value="Four" />
         <ctl name="SLIM TX5 MUX" value="DEC5" />
         <ctl name="ADC MUX5" value="DMIC" />
-        <ctl name="DMIC MUX5" value="DMIC0" />
+        <ctl name="DMIC MUX5" value="DMIC1" />
         <ctl name="SLIM TX6 MUX" value="DEC6" />
         <ctl name="ADC MUX6" value="DMIC" />
-        <ctl name="DMIC MUX6" value="DMIC2" />
+        <ctl name="DMIC MUX6" value="DMIC0" />
         <ctl name="SLIM TX7 MUX" value="DEC7" />
         <ctl name="ADC MUX7" value="DMIC" />
-        <ctl name="DMIC MUX7" value="DMIC1" />
+        <ctl name="DMIC MUX7" value="DMIC2" />
         <ctl name="SLIM TX8 MUX" value="DEC8" />
         <ctl name="ADC MUX8" value="DMIC" />
-        <ctl name="DMIC MUX8" value="DMIC3" />
+        <ctl name="DMIC MUX8" value="DMIC5" />
     </path>
 
     <path name="speaker-qmic-liquid">
@@ -2360,7 +2373,7 @@
 
     <path name="listen-handset-mic">
         <ctl name="MADONOFF Switch" value="1" />
-        <ctl name="MAD Input" value="DMIC0" />
+        <ctl name="MAD Input" value="DMIC2" />
     </path>
 
     <path name="unprocessed-handset-mic">
@@ -2376,4 +2389,122 @@
         <ctl name="SLIMBUS_DL_HL Switch" value="1" />
     </path>
 
+    <path name="bt-a2dp">
+        <ctl name="BT SampleRate" value="KHZ_48" />
+        <ctl name="AFE Input Channels" value="Two" />
+        <ctl name="SLIM7_RX ADM Channels" value="Two" />
+    </path>
+
+    <path name="speaker-and-bt-a2dp">
+        <path name="speaker" />
+        <path name="bt-a2dp" />
+    </path>
+
+    <path name="deep-buffer-playback bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia1" value="1" />
+    </path>
+
+    <path name="low-latency-playback bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia5" value="1" />
+    </path>
+
+    <path name="compress-offload-playback bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia4" value="1" />
+    </path>
+
+    <path name="compress-offload-playback2 bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia7" value="1" />
+    </path>
+
+    <path name="compress-offload-playback3 bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia10" value="1" />
+    </path>
+
+    <path name="compress-offload-playback4 bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia11" value="1" />
+    </path>
+
+    <path name="compress-offload-playback5 bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia12" value="1" />
+    </path>
+
+    <path name="compress-offload-playback6 bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia13" value="1" />
+    </path>
+
+    <path name="compress-offload-playback7 bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia14" value="1" />
+    </path>
+
+    <path name="compress-offload-playback8 bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia15" value="1" />
+    </path>
+
+    <path name="compress-offload-playback9 bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia16" value="1" />
+    </path>
+
+    <path name="audio-ull-playback bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia3" value="1" />
+    </path>
+
+    <path name="deep-buffer-playback speaker-and-bt-a2dp">
+        <path name="deep-buffer-playback bt-a2dp" />
+        <path name="deep-buffer-playback" />
+    </path>
+
+    <path name="compress-offload-playback speaker-and-bt-a2dp">
+        <path name="compress-offload-playback bt-a2dp" />
+        <path name="compress-offload-playback" />
+    </path>
+
+    <path name="low-latency-playback speaker-and-bt-a2dp">
+        <path name="low-latency-playback bt-a2dp" />
+        <path name="low-latency-playback" />
+    </path>
+
+    <path name="compress-offload-playback2 speaker-and-bt-a2dp">
+        <path name="compress-offload-playback2 bt-a2dp" />
+        <path name="compress-offload-playback2" />
+    </path>
+
+    <path name="compress-offload-playback3 speaker-and-bt-a2dp">
+        <path name="compress-offload-playback3 bt-a2dp" />
+        <path name="compress-offload-playback3" />
+    </path>
+
+    <path name="compress-offload-playback4 speaker-and-bt-a2dp">
+        <path name="compress-offload-playback4 bt-a2dp" />
+        <path name="compress-offload-playback4" />
+    </path>
+
+    <path name="compress-offload-playback5 speaker-and-bt-a2dp">
+        <path name="compress-offload-playback5 bt-a2dp" />
+        <path name="compress-offload-playback5" />
+    </path>
+
+    <path name="compress-offload-playback6 speaker-and-bt-a2dp">
+        <path name="compress-offload-playback6 bt-a2dp" />
+        <path name="compress-offload-playback6" />
+    </path>
+
+    <path name="compress-offload-playback7 speaker-and-bt-a2dp">
+        <path name="compress-offload-playback7 bt-a2dp" />
+        <path name="compress-offload-playback7" />
+    </path>
+
+    <path name="compress-offload-playback8 speaker-and-bt-a2dp">
+        <path name="compress-offload-playback8 bt-a2dp" />
+        <path name="compress-offload-playback8" />
+    </path>
+
+    <path name="compress-offload-playback9 speaker-and-bt-a2dp">
+        <path name="compress-offload-playback9 bt-a2dp" />
+        <path name="compress-offload-playback9" />
+    </path>
+
+    <path name="audio-ull-playback speaker-and-bt-a2dp">
+        <path name="audio-ull-playback bt-a2dp" />
+        <path name="audio-ull-playback" />
+    </path>
 </mixer>
diff --git a/configs/msmcobalt/mixer_paths_tavil.xml b/configs/msmcobalt/mixer_paths_tavil.xml
index 1c92421..b9b0b03 100644
--- a/configs/msmcobalt/mixer_paths_tavil.xml
+++ b/configs/msmcobalt/mixer_paths_tavil.xml
@@ -45,11 +45,34 @@
     <ctl name="Voip Evrc Min Max Rate Config" id="1" value="4" />
     <ctl name="Voip Dtx Mode" value="0" />
     <ctl name="TTY Mode" value="OFF" />
+    <ctl name="DEC0 Volume" value="84" />
+    <ctl name="DEC2 Volume" value="84" />
+    <ctl name="DEC5 Volume" value="84" />
+    <ctl name="DEC6 Volume" value="84" />
+    <ctl name="DEC7 Volume" value="84" />
+    <ctl name="DEC8 Volume" value="84" />
+    <ctl name="ADC1 Volume" value="12" />
+    <ctl name="ADC2 Volume" value="12" />
+    <ctl name="CDC_IF TX5 MUX" value="ZERO" />
+    <ctl name="CDC_IF TX6 MUX" value="ZERO" />
+    <ctl name="CDC_IF TX7 MUX" value="ZERO" />
+    <ctl name="CDC_IF TX8 MUX" value="ZERO" />
+    <ctl name="ADC MUX5" value="AMIC" />
+    <ctl name="ADC MUX6" value="AMIC" />
+    <ctl name="ADC MUX7" value="AMIC" />
+    <ctl name="ADC MUX8" value="AMIC" />
+    <ctl name="DMIC MUX5" value="ZERO" />
+    <ctl name="DMIC MUX6" value="ZERO" />
+    <ctl name="DMIC MUX7" value="ZERO" />
+    <ctl name="DMIC MUX8" value="ZERO" />
+    <ctl name="AMIC MUX0" value="ZERO" />
+    <ctl name="AMIC MUX6" value="ZERO" />
     <ctl name="SLIMBUS_0_RX Port Mixer SLIM_0_TX" value="0" />
     <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia1" value="0" />
     <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia4" value="0" />
     <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia5" value="0" />
     <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia7" value="0" />
+    <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia8" value="0" />
     <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia10" value="0" />
     <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia11" value="0" />
     <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia12" value="0" />
@@ -67,6 +90,9 @@
     <ctl name="MultiMedia1 Mixer SLIM_0_TX" value="0" />
     <ctl name="MultiMedia1 Mixer SLIM_4_TX" value="0" />
     <ctl name="MultiMedia1 Mixer SLIM_7_TX" value="0" />
+    <ctl name="MultiMedia8 Mixer SLIM_0_TX" value="0" />
+    <ctl name="MultiMedia8 Mixer SLIM_4_TX" value="0" />
+    <ctl name="MultiMedia8 Mixer SLIM_7_TX" value="0" />
     <ctl name="HDMI Mixer MultiMedia1" value="0" />
     <ctl name="HDMI Mixer MultiMedia2" value="0" />
     <ctl name="HDMI Mixer MultiMedia3" value="0" />
@@ -88,33 +114,46 @@
     <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia3" value="0" />
     <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia3" value="0" />
     <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia4" value="0" />
+    <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia4" value="0" />
     <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia4" value="0" />
     <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia4" value="0" />
     <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia5" value="0" />
+    <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia5" value="0" />
     <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia5" value="0" />
     <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia7" value="0" />
     <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia7" value="0" />
+    <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia7" value="0" />
     <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia7" value="0" />
+    <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia8" value="0" />
+    <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia8" value="0" />
+    <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia8" value="0" />
     <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia10" value="0" />
     <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia10" value="0" />
+    <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia10" value="0" />
     <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia10" value="0" />
     <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia11" value="0" />
     <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia11" value="0" />
+    <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia11" value="0" />
     <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia11" value="0" />
     <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia12" value="0" />
     <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia12" value="0" />
+    <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia12" value="0" />
     <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia12" value="0" />
     <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia13" value="0" />
     <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia13" value="0" />
+    <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia13" value="0" />
     <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia13" value="0" />
     <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia14" value="0" />
     <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia14" value="0" />
+    <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia14" value="0" />
     <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia14" value="0" />
     <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia15" value="0" />
     <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia15" value="0" />
+    <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia15" value="0" />
     <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia15" value="0" />
     <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia16" value="0" />
     <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia16" value="0" />
+    <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia16" value="0" />
     <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia16" value="0" />
     <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia1" value="0" />
     <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia2" value="0" />
@@ -122,6 +161,7 @@
     <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia4" value="0" />
     <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia5" value="0" />
     <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia7" value="0" />
+    <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia8" value="0" />
     <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia10" value="0" />
     <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia11" value="0" />
     <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia12" value="0" />
@@ -139,8 +179,13 @@
     <ctl name="USB_AUDIO_TX SampleRate" value="KHZ_48" />
     <ctl name="USB_AUDIO_TX Format" value="S16_LE" />
     <ctl name="MultiMedia6 Mixer SLIM_0_TX" value="0" />
+    <ctl name="SLIM_2_RX Format" value="UNPACKED" />
+    <ctl name="SLIM_2_RX SampleRate" value="KHZ_48" />
+    <ctl name="SLIM_5_RX SampleRate" value="KHZ_44P1" />
     <ctl name="SLIM_0_RX Channels" value="One" />
     <ctl name="SLIM_5_RX Channels" value="One" />
+    <ctl name="SLIM_6_RX Channels" value="One" />
+    <ctl name="SLIM_2_RX Channels" value="One" />
     <ctl name="SLIM_0_TX Channels" value="One" />
     <ctl name="SLIM_1_TX Channels" value="One" />
     <ctl name="AIF1_CAP Mixer SLIM TX7" value="0" />
@@ -262,6 +307,12 @@
     <ctl name="MultiMedia8 Mixer AFE_PCM_TX" value="0" />
     <!-- audio record compress end-->
 
+    <!-- split a2dp -->
+    <ctl name="BT SampleRate" value="KHZ_8" />
+    <ctl name="AFE Input Channels" value="Zero" />
+    <ctl name="SLIM7_RX ADM Channels" value="0" />
+    <!-- split a2dp end-->
+
     <!-- ADSP testfwk -->
     <ctl name="SLIMBUS_DL_HL Switch" value="0" />
     <ctl name="SLIMBUS6_DL_HL Switch" value="0" />
@@ -272,10 +323,28 @@
     <!-- Codec controls -->
     <ctl name="SLIM RX0 MUX" value="ZERO" />
     <ctl name="SLIM RX1 MUX" value="ZERO" />
+    <ctl name="SLIM RX2 MUX" value="ZERO" />
+    <ctl name="SLIM RX3 MUX" value="ZERO" />
+    <ctl name="SLIM RX4 MUX" value="ZERO" />
+    <ctl name="SLIM RX5 MUX" value="ZERO" />
+    <ctl name="SLIM RX6 MUX" value="ZERO" />
+    <ctl name="SLIM RX7 MUX" value="ZERO" />
     <ctl name="CDC_IF RX0 MUX" value="SLIM RX0" />
     <ctl name="CDC_IF RX1 MUX" value="SLIM RX1" />
+    <ctl name="CDC_IF RX2 MUX" value="SLIM RX2" />
+    <ctl name="CDC_IF RX3 MUX" value="SLIM RX3" />
+    <ctl name="CDC_IF RX4 MUX" value="SLIM RX4" />
+    <ctl name="CDC_IF RX5 MUX" value="SLIM RX5" />
+    <ctl name="CDC_IF RX6 MUX" value="SLIM RX6" />
+    <ctl name="CDC_IF RX7 MUX" value="SLIM RX7" />
+    <ctl name="RX INT1_1 MIX1 INP0" value="ZERO" />
+    <ctl name="RX INT2_1 MIX1 INP0" value="ZERO" />
+    <ctl name="RX INT1_2 MUX" value="ZERO" />
+    <ctl name="RX INT2_2 MUX" value="ZERO" />
     <ctl name="RX INT7_1 MIX1 INP0" value="ZERO" />
     <ctl name="RX INT8_1 MIX1 INP0" value="ZERO" />
+    <ctl name="COMP1 Switch" value="1" />
+    <ctl name="COMP2 Switch" value="1" />
     <ctl name="COMP7 Switch" value="0" />
     <ctl name="COMP8 Switch" value="0" />
     <ctl name="SpkrLeft COMP Switch" value="0" />
@@ -287,8 +356,28 @@
     <ctl name="SpkrLeft SWR DAC_Port Switch" value="0" />
     <ctl name="SpkrRight SWR DAC_Port Switch" value="0" />
 
-    <ctl name="AIF1_CAP Mixer SLIM TX0" value="0" />
-    <ctl name="AIF1_CAP Mixer SLIM TX2" value="0" />
+    <ctl name="RX INT1_1 NATIVE MUX" value="OFF" />
+    <ctl name="RX INT2_1 NATIVE MUX" value="OFF" />
+    <ctl name="RX INT1_2 NATIVE MUX" value="OFF" />
+    <ctl name="RX INT2_2 NATIVE MUX" value="OFF" />
+
+    <ctl name="ASRC0 MUX" value="ZERO" />
+    <ctl name="RX INT1 SEC MIX HPHL Switch" value="0" />
+    <ctl name="ASRC1 MUX" value="ZERO" />
+    <ctl name="RX INT2 SEC MIX HPHR Switch" value="0" />
+    <ctl name="SLIM0_RX_VI_FB_LCH_MUX" value="ZERO" />
+    <ctl name="SLIM0_RX_VI_FB_RCH_MUX" value="ZERO" />
+    <ctl name="VI_FEED_TX Channels" value="Two" />
+    <ctl name="AIF4_VI Mixer SPKR_VI_1" value="0" />
+    <ctl name="AIF4_VI Mixer SPKR_VI_2" value="0" />
+    <ctl name="SLIM_4_TX Format" value="UNPACKED" />
+
+    <ctl name="DSD_L IF MUX" value="ZERO" />
+    <ctl name="DSD_R IF MUX" value="ZERO" />
+    <ctl name="RX INT1 MIX3 DSD HPHL Switch" value="0" />
+    <ctl name="RX INT2 MIX3 DSD HPHR Switch" value="0" />
+    <ctl name="RX INT1 DEM MUX" value="CLSH_DSM_OUT" />
+    <ctl name="RX INT2 DEM MUX" value="CLSH_DSM_OUT" />
     <ctl name="CDC_IF TX0 MUX" value="ZERO" />
     <ctl name="CDC_IF TX2 MUX" value="ZERO" />
     <ctl name="ADC MUX0" value="ZERO" />
@@ -296,8 +385,6 @@
     <ctl name="DMIC MUX0" value="ZERO" />
     <ctl name="DMIC MUX2" value="ZERO" />
 
-    <ctl name="DEC0 Volume" value="0" />
-    <ctl name="DEC2 Volume" value="0" />
     <ctl name="RX7 Digital Volume" value="84" />
     <ctl name="RX8 Digital Volume" value="84" />
 
@@ -330,6 +417,7 @@
     </path>
 
     <path name="echo-reference headphones">
+        <ctl name="AUDIO_REF_EC_UL1 MUX" value="SLIM_6_RX" />
     </path>
 
     <path name="echo-reference headphones-44.1">
@@ -357,7 +445,7 @@
     </path>
 
     <path name="deep-buffer-playback bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="deep-buffer-playback bt-sco" />
     </path>
 
@@ -400,7 +488,7 @@
     </path>
 
     <path name="low-latency-playback bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="low-latency-playback bt-sco" />
     </path>
 
@@ -432,7 +520,7 @@
     </path>
 
     <path name="audio-ull-playback">
-        <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia3" value="1" />
+        <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia8" value="1" />
     </path>
 
     <path name="audio-ull-playback speaker-protected">
@@ -440,7 +528,7 @@
     </path>
 
     <path name="audio-ull-playback headphones">
-        <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia3" value="1" />
+        <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia8" value="1" />
     </path>
 
     <path name="audio-ull-playback speaker-and-headphones">
@@ -449,15 +537,15 @@
     </path>
 
     <path name="audio-ull-playback hdmi">
-        <ctl name="HDMI Mixer MultiMedia3" value="1" />
+        <ctl name="HDMI Mixer MultiMedia8" value="1" />
     </path>
 
     <path name="audio-ull-playback bt-sco">
-        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia3" value="1" />
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia8" value="1" />
     </path>
 
     <path name="audio-ull-playback bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="audio-ull-playback bt-sco" />
     </path>
 
@@ -467,11 +555,11 @@
     </path>
 
     <path name="audio-ull-playback afe-proxy">
-        <ctl name="AFE_PCM_RX Audio Mixer MultiMedia3" value="1" />
+        <ctl name="AFE_PCM_RX Audio Mixer MultiMedia8" value="1" />
     </path>
 
     <path name="audio-ull-playback usb-headphones">
-        <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia3" value="1" />
+        <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia8" value="1" />
     </path>
 
     <path name="multi-channel-playback hdmi">
@@ -503,7 +591,7 @@
     </path>
 
     <path name="compress-offload-playback bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-offload-playback bt-sco" />
     </path>
 
@@ -533,6 +621,10 @@
         <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia4" value="1" />
     </path>
 
+    <path name="compress-offload-playback headphones-dsd">
+        <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia4" value="1" />
+    </path>
+
     <path name="compress-offload-playback speaker-and-headphones">
         <path name="compress-offload-playback headphones" />
         <path name="compress-offload-playback" />
@@ -551,7 +643,7 @@
     </path>
 
     <path name="compress-offload-playback2 bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-offload-playback2 bt-sco" />
     </path>
 
@@ -581,6 +673,10 @@
         <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia7" value="1" />
     </path>
 
+    <path name="compress-offload-playback2 headphones-dsd">
+        <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia7" value="1" />
+    </path>
+
     <path name="compress-offload-playback2 speaker-and-headphones">
         <path name="compress-offload-playback2 headphones" />
         <path name="compress-offload-playback2" />
@@ -599,7 +695,7 @@
     </path>
 
     <path name="compress-offload-playback3 bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-offload-playback3 bt-sco" />
     </path>
 
@@ -629,6 +725,10 @@
         <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia10" value="1" />
     </path>
 
+    <path name="compress-offload-playback3 headphones-dsd">
+        <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia10" value="1" />
+    </path>
+
     <path name="compress-offload-playback3 speaker-and-headphones">
         <path name="compress-offload-playback3 headphones" />
         <path name="compress-offload-playback3" />
@@ -647,7 +747,7 @@
     </path>
 
     <path name="compress-offload-playback4 bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-offload-playback4 bt-sco" />
     </path>
 
@@ -677,6 +777,10 @@
         <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia11" value="1" />
     </path>
 
+    <path name="compress-offload-playback4 headphones-dsd">
+        <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia11" value="1" />
+    </path>
+
     <path name="compress-offload-playback4 speaker-and-headphones">
         <path name="compress-offload-playback4 headphones" />
         <path name="compress-offload-playback4" />
@@ -695,7 +799,7 @@
     </path>
 
     <path name="compress-offload-playback5 bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-offload-playback5 bt-sco" />
     </path>
 
@@ -725,6 +829,10 @@
         <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia12" value="1" />
     </path>
 
+    <path name="compress-offload-playback5 headphones-dsd">
+        <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia12" value="1" />
+    </path>
+
     <path name="compress-offload-playback5 speaker-and-headphones">
         <path name="compress-offload-playback5 headphones" />
         <path name="compress-offload-playback5" />
@@ -743,7 +851,7 @@
     </path>
 
     <path name="compress-offload-playback6 bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-offload-playback6 bt-sco" />
     </path>
 
@@ -773,6 +881,10 @@
         <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia13" value="1" />
     </path>
 
+    <path name="compress-offload-playback6 headphones-dsd">
+        <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia13" value="1" />
+    </path>
+
     <path name="compress-offload-playback6 speaker-and-headphones">
         <path name="compress-offload-playback6 headphones" />
         <path name="compress-offload-playback6" />
@@ -791,7 +903,7 @@
     </path>
 
     <path name="compress-offload-playback7 bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-offload-playback7 bt-sco" />
     </path>
 
@@ -821,6 +933,10 @@
         <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia14" value="1" />
     </path>
 
+    <path name="compress-offload-playback7 headphones-dsd">
+        <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia14" value="1" />
+    </path>
+
     <path name="compress-offload-playback7 speaker-and-headphones">
         <path name="compress-offload-playback7 headphones" />
         <path name="compress-offload-playback7" />
@@ -839,7 +955,7 @@
     </path>
 
     <path name="compress-offload-playback8 bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-offload-playback8 bt-sco" />
     </path>
 
@@ -869,6 +985,10 @@
         <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia15" value="1" />
     </path>
 
+    <path name="compress-offload-playback8 headphones-dsd">
+        <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia15" value="1" />
+    </path>
+
     <path name="compress-offload-playback8 speaker-and-headphones">
         <path name="compress-offload-playback8 headphones" />
         <path name="compress-offload-playback8" />
@@ -887,7 +1007,7 @@
     </path>
 
     <path name="compress-offload-playback9 bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-offload-playback9 bt-sco" />
     </path>
 
@@ -917,6 +1037,10 @@
         <ctl name="SLIMBUS_5_RX Audio Mixer MultiMedia16" value="1" />
     </path>
 
+    <path name="compress-offload-playback9 headphones-dsd">
+        <ctl name="SLIMBUS_2_RX Audio Mixer MultiMedia16" value="1" />
+    </path>
+
     <path name="compress-offload-playback9 speaker-and-headphones">
         <path name="compress-offload-playback9 headphones" />
         <path name="compress-offload-playback9" />
@@ -935,7 +1059,7 @@
     </path>
 
     <path name="audio-record bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="audio-record bt-sco" />
     </path>
 
@@ -952,7 +1076,7 @@
     </path>
 
     <path name="audio-record-compress bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="audio-record-compress bt-sco" />
     </path>
 
@@ -961,24 +1085,24 @@
     </path>
 
     <path name="low-latency-record">
-      <ctl name="MultiMedia5 Mixer SLIM_0_TX" value="1" />
+      <ctl name="MultiMedia8 Mixer SLIM_0_TX" value="1" />
     </path>
 
     <path name="low-latency-record bt-sco">
-      <ctl name="MultiMedia5 Mixer SLIM_7_TX" value="1" />
+      <ctl name="MultiMedia8 Mixer SLIM_7_TX" value="1" />
     </path>
 
     <path name="low-latency-record bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="low-latency-record bt-sco" />
     </path>
 
     <path name="low-latency-record usb-headset-mic">
-        <ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="1" />
+        <ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="1" />
     </path>
 
     <path name="low-latency-record capture-fm">
-      <ctl name="MultiMedia5 Mixer SLIM_8_TX" value="1" />
+      <ctl name="MultiMedia8 Mixer SLIM_8_TX" value="1" />
     </path>
 
     <path name="fm-virtual-record capture-fm">
@@ -1150,7 +1274,7 @@
     </path>
 
     <path name="compress-voip-call bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="compress-voip-call bt-sco" />
     </path>
 
@@ -1190,7 +1314,7 @@
     </path>
 
     <path name="voicemmode1-call bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="voicemmode1-call bt-sco" />
     </path>
 
@@ -1230,7 +1354,7 @@
     </path>
 
     <path name="voicemmode2-call bt-sco-wb">
-        <ctl name="BT_SCO SampleRate" value="16000" />
+        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="voicemmode2-call bt-sco" />
     </path>
 
@@ -1258,40 +1382,68 @@
 
     <!-- These are actual sound device specific mixer settings -->
     <path name="amic1">
+        <ctl name="AIF1_CAP Mixer SLIM TX6" value="1"/>
+        <ctl name="SLIM_0_TX Channels" value="One" />
+        <ctl name="CDC_IF TX6 MUX" value="DEC6" />
+        <ctl name="ADC MUX6" value="AMIC" />
+        <ctl name="AMIC MUX6" value="ADC1" />
     </path>
 
     <path name="amic2">
+        <ctl name="AIF1_CAP Mixer SLIM TX0" value="1"/>
+        <ctl name="SLIM_0_TX Channels" value="One" />
+        <ctl name="CDC_IF TX0 MUX" value="DEC0" />
+        <ctl name="ADC MUX0" value="AMIC" />
+        <ctl name="AMIC MUX0" value="ADC2" />
     </path>
 
     <!-- For Tavil, DMIC numbered from 0 to 5 -->
     <path name="dmic1">
-        <ctl name="AIF1_CAP Mixer SLIM TX0" value="1" />
-        <ctl name="CDC_IF TX0 MUX" value="DEC0" />
+        <ctl name="AIF1_CAP Mixer SLIM TX7" value="1" />
+        <ctl name="CDC_IF TX7 MUX" value="DEC7" />
         <ctl name="SLIM_0_TX Channels" value="One" />
-        <ctl name="ADC MUX0" value="DMIC" />
-        <ctl name="DMIC MUX0" value="DMIC0" />
-        <ctl name="DEC0 Volume" value="84" />
+        <ctl name="ADC MUX7" value="DMIC" />
+        <ctl name="DMIC MUX7" value="DMIC0" />
     </path>
 
     <path name="dmic2">
+        <ctl name="AIF1_CAP Mixer SLIM TX7" value="1"/>
+        <ctl name="CDC_IF TX7 MUX" value="DEC7" />
+        <ctl name="SLIM_0_TX Channels" value="One" />
+        <ctl name="ADC MUX7" value="DMIC" />
+        <ctl name="DMIC MUX7" value="DMIC1" />
     </path>
 
     <path name="dmic3">
-        <ctl name="AIF1_CAP Mixer SLIM TX2" value="1" />
-        <ctl name="CDC_IF TX2 MUX" value="DEC2" />
+        <ctl name="AIF1_CAP Mixer SLIM TX7" value="1" />
+        <ctl name="CDC_IF TX7 MUX" value="DEC7" />
         <ctl name="SLIM_0_TX Channels" value="One" />
-        <ctl name="ADC MUX2" value="DMIC" />
-        <ctl name="DMIC MUX2" value="DMIC2" />
-        <ctl name="DEC2 Volume" value="84" />
+        <ctl name="ADC MUX7" value="DMIC" />
+        <ctl name="DMIC MUX7" value="DMIC2" />
     </path>
 
     <path name="dmic4">
+        <ctl name="AIF1_CAP Mixer SLIM TX7" value="1" />
+        <ctl name="CDC_IF TX7 MUX" value="DEC7" />
+        <ctl name="SLIM_0_TX Channels" value="One" />
+        <ctl name="ADC MUX7" value="DMIC" />
+        <ctl name="DMIC MUX7" value="DMIC3" />
     </path>
 
     <path name="dmic5">
+        <ctl name="AIF1_CAP Mixer SLIM TX7" value="1" />
+        <ctl name="CDC_IF TX7 MUX" value="DEC7" />
+        <ctl name="SLIM_0_TX Channels" value="One" />
+        <ctl name="ADC MUX7" value="DMIC" />
+        <ctl name="DMIC MUX7" value="DMIC4" />
     </path>
 
     <path name="dmic6">
+        <ctl name="AIF1_CAP Mixer SLIM TX7" value="1" />
+        <ctl name="CDC_IF TX7 MUX" value="DEC7" />
+        <ctl name="SLIM_0_TX Channels" value="One" />
+        <ctl name="ADC MUX7" value="DMIC" />
+        <ctl name="DMIC MUX7" value="DMIC5" />
     </path>
 
     <path name="speaker">
@@ -1353,22 +1505,32 @@
     </path>
 
     <path name="speaker-mic">
-        <path name="dmic3" />
+        <path name="dmic2" />
     </path>
 
     <path name="speaker-mic-liquid">
-        <path name="dmic3" />
+        <path name="dmic2" />
     </path>
 
     <path name="speaker-mic-sbc">
     </path>
 
     <path name="speaker-protected">
+        <ctl name="AIF4_VI Mixer SPKR_VI_1" value="1" />
+        <ctl name="AIF4_VI Mixer SPKR_VI_2" value="1" />
+        <ctl name="SLIM_4_TX Format" value="PACKED_16B" />
         <path name="speaker" />
+        <ctl name="VI_FEED_TX Channels" value="Two" />
+        <ctl name="SLIM0_RX_VI_FB_LCH_MUX" value="SLIM4_TX" />
+        <ctl name="SLIM0_RX_VI_FB_RCH_MUX" value="SLIM4_TX" />
     </path>
 
     <path name="voice-speaker-protected">
+        <ctl name="AIF4_VI Mixer SPKR_VI_1" value="1" />
+        <ctl name="SLIM_4_TX Format" value="PACKED_16B" />
         <path name="speaker-mono" />
+        <ctl name="VI_FEED_TX Channels" value="One" />
+        <ctl name="SLIM0_RX_VI_FB_LCH_MUX" value="SLIM4_TX" />
     </path>
 
     <path name="vi-feedback">
@@ -1396,7 +1558,7 @@
     </path>
 
     <path name="handset-mic">
-        <path name="dmic1" />
+        <path name="dmic3" />
     </path>
 
     <path name="handset-mic-db">
@@ -1410,15 +1572,60 @@
     </path>
 
     <path name="three-mic">
+        <ctl name="AIF1_CAP Mixer SLIM TX5" value="1" />
+        <ctl name="AIF1_CAP Mixer SLIM TX6" value="1" />
+        <ctl name="AIF1_CAP Mixer SLIM TX8" value="1" />
+        <ctl name="SLIM_0_TX Channels" value="Three" />
+        <ctl name="CDC_IF TX5 MUX" value="DEC5" />
+        <ctl name="ADC MUX5" value="DMIC" />
+        <ctl name="DMIC MUX5" value="DMIC0" />
+        <ctl name="CDC_IF TX6 MUX" value="DEC6" />
+        <ctl name="ADC MUX6" value="DMIC" />
+        <ctl name="DMIC MUX6" value="DMIC2" />
+        <ctl name="CDC_IF TX8 MUX" value="DEC8" />
+        <ctl name="ADC MUX8" value="DMIC" />
+        <ctl name="DMIC MUX8" value="DMIC5" />
     </path>
 
     <path name="anc-handset">
     </path>
 
     <path name="headphones">
+        <ctl name="SLIM RX2 MUX" value="AIF4_PB" />
+        <ctl name="SLIM RX3 MUX" value="AIF4_PB" />
+        <ctl name="SLIM_6_RX Channels" value="Two" />
+        <ctl name="RX INT1_2 MUX" value="RX2" />
+        <ctl name="RX INT2_2 MUX" value="RX3" />
     </path>
 
     <path name="headphones-44.1">
+        <ctl name="SLIM RX4 MUX" value="AIF3_PB" />
+        <ctl name="SLIM RX5 MUX" value="AIF3_PB" />
+        <ctl name="SLIM_5_RX Channels" value="Two" />
+        <ctl name="RX INT1_1 MIX1 INP0" value="RX4" />
+        <ctl name="RX INT2_1 MIX1 INP0" value="RX5" />
+        <ctl name="RX INT1_1 NATIVE MUX" value="ON" />
+        <ctl name="RX INT2_1 NATIVE MUX" value="ON" />
+    </path>
+
+    <path name="asrc-mode">
+        <ctl name="RX INT1_2 NATIVE MUX" value="ON" />
+        <ctl name="RX INT2_2 NATIVE MUX" value="ON" />
+        <ctl name="ASRC0 MUX" value="ASRC_IN_HPHL" />
+        <ctl name="RX INT1 SEC MIX HPHL Switch" value="1" />
+        <ctl name="ASRC1 MUX" value="ASRC_IN_HPHR" />
+        <ctl name="RX INT2 SEC MIX HPHR Switch" value="1" />
+    </path>
+
+    <path name="headphones-dsd">
+        <ctl name="SLIM RX6 MUX" value="AIF2_PB" />
+        <ctl name="SLIM RX7 MUX" value="AIF2_PB" />
+        <ctl name="SLIM_2_RX Channels" value="Two" />
+        <ctl name="DSD_L IF MUX" value="RX6" />
+        <ctl name="DSD_R IF MUX" value="RX7" />
+        <ctl name="RX INT1 MIX3 DSD HPHL Switch" value="1" />
+        <ctl name="RX INT2 MIX3 DSD HPHR Switch" value="1" />
+        <ctl name="SLIM_2_RX Format" value="DSD_DOP" />
     </path>
 
     <path name="true-native-mode">
@@ -1571,9 +1778,27 @@
 
     <!-- Dual MIC devices -->
     <path name="handset-dmic-endfire">
+        <ctl name="AIF1_CAP Mixer SLIM TX7" value="1" />
+        <ctl name="AIF1_CAP Mixer SLIM TX8" value="1" />
+        <ctl name="CDC_IF TX7 MUX" value="DEC7" />
+        <ctl name="ADC MUX7" value="DMIC" />
+        <ctl name="DMIC MUX7" value="DMIC2" />
+        <ctl name="CDC_IF TX8 MUX" value="DEC8" />
+        <ctl name="ADC MUX8" value="DMIC" />
+        <ctl name="DMIC MUX8" value="DMIC4" />
+        <ctl name="SLIM_0_TX Channels" value="Two" />
     </path>
 
     <path name="speaker-dmic-endfire">
+        <ctl name="AIF1_CAP Mixer SLIM TX7" value="1" />
+        <ctl name="AIF1_CAP Mixer SLIM TX8" value="1" />
+        <ctl name="CDC_IF TX7 MUX" value="DEC7" />
+        <ctl name="ADC MUX7" value="DMIC" />
+        <ctl name="DMIC MUX7" value="DMIC1" />
+        <ctl name="CDC_IF TX8 MUX" value="DEC8" />
+        <ctl name="ADC MUX8" value="DMIC" />
+        <ctl name="DMIC MUX8" value="DMIC5" />
+        <ctl name="SLIM_0_TX Channels" value="Two" />
     </path>
 
     <path name="dmic-endfire">
@@ -1637,6 +1862,15 @@
     </path>
 
     <path name="speaker-dmic-broadside">
+        <ctl name="AIF1_CAP Mixer SLIM TX7" value="1" />
+        <ctl name="AIF1_CAP Mixer SLIM TX8" value="1" />
+        <ctl name="SLIM_0_TX Channels" value="Two" />
+        <ctl name="CDC_IF TX7 MUX" value="DEC7" />
+        <ctl name="ADC MUX7" value="DMIC" />
+        <ctl name="DMIC MUX7" value="DMIC1" />
+        <ctl name="CDC_IF TX8 MUX" value="DEC8" />
+        <ctl name="ADC MUX8" value="DMIC" />
+        <ctl name="DMIC MUX8" value="DMIC2" />
     </path>
 
     <path name="dmic-broadside">
@@ -1649,6 +1883,23 @@
 
     <!-- Quad MIC devices -->
     <path name="speaker-qmic">
+        <ctl name="AIF1_CAP Mixer SLIM TX5" value="1" />
+        <ctl name="AIF1_CAP Mixer SLIM TX6" value="1" />
+        <ctl name="AIF1_CAP Mixer SLIM TX7" value="1" />
+        <ctl name="AIF1_CAP Mixer SLIM TX8" value="1" />
+        <ctl name="SLIM_0_TX Channels" value="Four" />
+        <ctl name="CDC_IF TX5 MUX" value="DEC5" />
+        <ctl name="ADC MUX5" value="DMIC" />
+        <ctl name="DMIC MUX5" value="DMIC1" />
+        <ctl name="CDC_IF TX6 MUX" value="DEC6" />
+        <ctl name="ADC MUX6" value="DMIC" />
+        <ctl name="DMIC MUX6" value="DMIC0" />
+        <ctl name="CDC_IF TX7 MUX" value="DEC7" />
+        <ctl name="ADC MUX7" value="DMIC" />
+        <ctl name="DMIC MUX7" value="DMIC2" />
+        <ctl name="CDC_IF TX8 MUX" value="DEC8" />
+        <ctl name="ADC MUX8" value="DMIC" />
+        <ctl name="DMIC MUX8" value="DMIC5" />
     </path>
 
     <path name="speaker-qmic-liquid">
@@ -1715,4 +1966,122 @@
         <ctl name="SLIMBUS_DL_HL Switch" value="1" />
     </path>
 
+    <path name="bt-a2dp">
+        <ctl name="BT SampleRate" value="KHZ_48" />
+        <ctl name="AFE Input Channels" value="Two" />
+        <ctl name="SLIM7_RX ADM Channels" value="2" />
+    </path>
+
+    <path name="speaker-and-bt-a2dp">
+        <path name="speaker" />
+        <path name="bt-a2dp" />
+    </path>
+
+    <path name="deep-buffer-playback bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia1" value="1" />
+    </path>
+
+    <path name="low-latency-playback bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia5" value="1" />
+    </path>
+
+    <path name="compress-offload-playback bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia4" value="1" />
+    </path>
+
+    <path name="compress-offload-playback2 bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia7" value="1" />
+    </path>
+
+    <path name="compress-offload-playback3 bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia10" value="1" />
+    </path>
+
+    <path name="compress-offload-playback4 bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia11" value="1" />
+    </path>
+
+    <path name="compress-offload-playback5 bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia12" value="1" />
+    </path>
+
+    <path name="compress-offload-playback6 bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia13" value="1" />
+    </path>
+
+    <path name="compress-offload-playback7 bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia14" value="1" />
+    </path>
+
+    <path name="compress-offload-playback8 bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia15" value="1" />
+    </path>
+
+    <path name="compress-offload-playback9 bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia16" value="1" />
+    </path>
+
+    <path name="audio-ull-playback bt-a2dp">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia3" value="1" />
+    </path>
+
+    <path name="deep-buffer-playback speaker-and-bt-a2dp">
+        <path name="deep-buffer-playback bt-a2dp" />
+        <path name="deep-buffer-playback" />
+    </path>
+
+    <path name="compress-offload-playback speaker-and-bt-a2dp">
+        <path name="compress-offload-playback bt-a2dp" />
+        <path name="compress-offload-playback" />
+    </path>
+
+    <path name="low-latency-playback speaker-and-bt-a2dp">
+        <path name="low-latency-playback bt-a2dp" />
+        <path name="low-latency-playback" />
+    </path>
+
+    <path name="compress-offload-playback2 speaker-and-bt-a2dp">
+        <path name="compress-offload-playback2 bt-a2dp" />
+        <path name="compress-offload-playback2" />
+    </path>
+
+    <path name="compress-offload-playback3 speaker-and-bt-a2dp">
+        <path name="compress-offload-playback3 bt-a2dp" />
+        <path name="compress-offload-playback3" />
+    </path>
+
+    <path name="compress-offload-playback4 speaker-and-bt-a2dp">
+        <path name="compress-offload-playback4 bt-a2dp" />
+        <path name="compress-offload-playback4" />
+    </path>
+
+    <path name="compress-offload-playback5 speaker-and-bt-a2dp">
+        <path name="compress-offload-playback5 bt-a2dp" />
+        <path name="compress-offload-playback5" />
+    </path>
+
+    <path name="compress-offload-playback6 speaker-and-bt-a2dp">
+        <path name="compress-offload-playback6 bt-a2dp" />
+        <path name="compress-offload-playback6" />
+    </path>
+
+    <path name="compress-offload-playback7 speaker-and-bt-a2dp">
+        <path name="compress-offload-playback7 bt-a2dp" />
+        <path name="compress-offload-playback7" />
+    </path>
+
+    <path name="compress-offload-playback8 speaker-and-bt-a2dp">
+        <path name="compress-offload-playback8 bt-a2dp" />
+        <path name="compress-offload-playback8" />
+    </path>
+
+    <path name="compress-offload-playback9 speaker-and-bt-a2dp">
+        <path name="compress-offload-playback9 bt-a2dp" />
+        <path name="compress-offload-playback9" />
+    </path>
+
+    <path name="audio-ull-playback speaker-and-bt-a2dp">
+        <path name="audio-ull-playback bt-a2dp" />
+        <path name="audio-ull-playback" />
+    </path>
 </mixer>
diff --git a/configs/msmcobalt/msmcobalt.mk b/configs/msmcobalt/msmcobalt.mk
index 05be352..bb6ee95 100644
--- a/configs/msmcobalt/msmcobalt.mk
+++ b/configs/msmcobalt/msmcobalt.mk
@@ -4,7 +4,7 @@
 BOARD_USES_ALSA_AUDIO := true
 USE_CUSTOM_AUDIO_POLICY := 1
 USE_XML_AUDIO_POLICY_CONF := 1
-BOARD_SUPPORTS_SOUND_TRIGGER := true
+BOARD_SUPPORTS_SOUND_TRIGGER_HAL := true
 AUDIO_USE_LL_AS_PRIMARY_OUTPUT := true
 
 AUDIO_FEATURE_ENABLED_VBAT_MONITOR := true
@@ -19,7 +19,7 @@
 AUDIO_FEATURE_ENABLED_FLUENCE := true
 AUDIO_FEATURE_ENABLED_HDMI_SPK := true
 AUDIO_FEATURE_ENABLED_HDMI_EDID := true
-#AUDIO_FEATURE_ENABLED_HDMI_PASSTHROUGH := true
+AUDIO_FEATURE_ENABLED_HDMI_PASSTHROUGH := true
 #AUDIO_FEATURE_ENABLED_KEEP_ALIVE := true
 #AUDIO_FEATURE_ENABLED_DS2_DOLBY_DAP := true
 #DOLBY_DDP := true
@@ -52,6 +52,7 @@
 AUDIO_FEATURE_ENABLED_SOURCE_TRACKING := true
 AUDIO_FEATURE_ENABLED_AUDIOSPHERE := true
 AUDIO_FEATURE_ENABLED_USB_TUNNEL_AUDIO := true
+AUDIO_FEATURE_ENABLED_SPLIT_A2DP := true
 ##AUDIO_FEATURE_FLAGS
 
 #Audio Specific device overlays
@@ -78,7 +79,9 @@
     hardware/qcom/audio/configs/msmcobalt/audio_platform_info_i2s.xml:system/etc/audio_platform_info_i2s.xml \
     hardware/qcom/audio/configs/msmcobalt/sound_trigger_mixer_paths.xml:system/etc/sound_trigger_mixer_paths.xml \
     hardware/qcom/audio/configs/msmcobalt/sound_trigger_mixer_paths_wcd9330.xml:system/etc/sound_trigger_mixer_paths_wcd9330.xml \
+    hardware/qcom/audio/configs/msmcobalt/sound_trigger_mixer_paths_wcd9340.xml:system/etc/sound_trigger_mixer_paths_wcd9340.xml \
     hardware/qcom/audio/configs/msmcobalt/sound_trigger_platform_info.xml:system/etc/sound_trigger_platform_info.xml \
+    hardware/qcom/audio/configs/msmcobalt/graphite_ipc_platform_info.xml:system/etc/graphite_ipc_platform_info.xml \
     hardware/qcom/audio/configs/msmcobalt/audio_platform_info.xml:system/etc/audio_platform_info.xml
 
 #XML Audio configuration files
@@ -166,9 +169,9 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 audio.offload.multiple.enabled=false
 
-#Disable Compress passthrough playback
+#Enable Compress passthrough playback
 PRODUCT_PROPERTY_OVERRIDES += \
-audio.offload.passthrough=false
+audio.offload.passthrough=true
 
 #Disable surround sound recording
 PRODUCT_PROPERTY_OVERRIDES += \
@@ -186,3 +189,21 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 audio.parser.ip.buffer.size=262144
 
+#flac sw decoder 24 bit decode capability
+PRODUCT_PROPERTY_OVERRIDES += \
+flac.sw.decoder.24bit.support=true
+
+#split a2dp DSP supported encoder list
+PRODUCT_PROPERTY_OVERRIDES += \
+persist.bt.a2dp_offload_cap=sbc-aptx
+
+#enable software decoders for ALAC and APE
+PRODUCT_PROPERTY_OVERRIDES += \
+use.qti.sw.alac.decoder=true
+PRODUCT_PROPERTY_OVERRIDES += \
+use.qti.sw.ape.decoder=true
+
+#enable hw aac encoder by default
+PRODUCT_PROPERTY_OVERRIDES += \
+qcom.hw.aac.encoder=true
+
diff --git a/configs/msmcobalt/sound_trigger_mixer_paths_wcd9340.xml b/configs/msmcobalt/sound_trigger_mixer_paths_wcd9340.xml
new file mode 100755
index 0000000..d12b62f
--- /dev/null
+++ b/configs/msmcobalt/sound_trigger_mixer_paths_wcd9340.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--- Copyright (c) 2014-2016, 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.                             -->
+
+<mixer>
+    <!-- These are the initial mixer settings -->
+    <ctl name="LSM1 MUX" value="None" />
+    <ctl name="LSM2 MUX" value="None" />
+    <ctl name="LSM3 MUX" value="None" />
+    <ctl name="LSM4 MUX" value="None" />
+    <ctl name="LSM5 MUX" value="None" />
+    <ctl name="LSM6 MUX" value="None" />
+    <ctl name="LSM7 MUX" value="None" />
+    <ctl name="LSM8 MUX" value="None" />
+    <ctl name="SLIMBUS_5_TX LSM Function" value="None" />
+    <ctl name="MADONOFF Switch" value="0" />
+    <ctl name="MAD Input" value="DMIC1" />
+    <ctl name="MAD_BROADCAST Switch" value="0" />
+    <ctl name="TX13 INP MUX" value="CDC_DEC_5" />
+    <ctl name="AIF4_MAD Mixer SLIM TX12" value="0" />
+    <ctl name="AIF4_MAD Mixer SLIM TX13" value="0" />
+    <ctl name="CPE AFE MAD Enable" value="0"/>
+    <ctl name="CLK MODE" value="EXTERNAL" />
+    <ctl name="EC BUF MUX INP" value="ZERO" />
+    <ctl name="ADC MUX1" value="DMIC" />
+    <ctl name="DMIC MUX1" value="ZERO" />
+
+    <path name="listen-voice-wakeup-1">
+        <ctl name="SLIMBUS_5_TX LSM Function" value="AUDIO" />
+        <ctl name="LSM1 MUX" value="SLIMBUS_5_TX" />
+    </path>
+
+    <path name="listen-voice-wakeup-2">
+        <ctl name="SLIMBUS_5_TX LSM Function" value="AUDIO" />
+        <ctl name="LSM2 MUX" value="SLIMBUS_5_TX" />
+    </path>
+    <path name="listen-voice-wakeup-3">
+        <ctl name="SLIMBUS_5_TX LSM Function" value="AUDIO" />
+        <ctl name="LSM3 MUX" value="SLIMBUS_5_TX" />
+    </path>
+    <path name="listen-voice-wakeup-4">
+        <ctl name="SLIMBUS_5_TX LSM Function" value="AUDIO" />
+        <ctl name="LSM4 MUX" value="SLIMBUS_5_TX" />
+    </path>
+    <path name="listen-voice-wakeup-5">
+        <ctl name="SLIMBUS_5_TX LSM Function" value="AUDIO" />
+        <ctl name="LSM5 MUX" value="SLIMBUS_5_TX" />
+    </path>
+    <path name="listen-voice-wakeup-6">
+        <ctl name="SLIMBUS_5_TX LSM Function" value="AUDIO" />
+        <ctl name="LSM6 MUX" value="SLIMBUS_5_TX" />
+    </path>
+    <path name="listen-voice-wakeup-7">
+        <ctl name="SLIMBUS_5_TX LSM Function" value="AUDIO" />
+        <ctl name="LSM7 MUX" value="SLIMBUS_5_TX" />
+    </path>
+    <path name="listen-voice-wakeup-8">
+        <ctl name="SLIMBUS_5_TX LSM Function" value="AUDIO" />
+        <ctl name="LSM8 MUX" value="SLIMBUS_5_TX" />
+    </path>
+
+    <path name="listen-cpe-handset-mic">
+        <ctl name="MAD Input" value="DMIC0" />
+        <ctl name="MAD_SEL MUX" value="SPE" />
+        <ctl name="MAD_INP MUX" value="MAD" />
+        <ctl name="MAD_CPE1 Switch" value="1" />
+    </path>
+
+    <path name="listen-cpe-handset-mic-ecpp">
+        <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" />
+    </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="CPE AFE MAD Enable" value="1"/>
+    </path>
+
+    <path name="listen-ape-handset-mic">
+        <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" />
+    </path>
+
+</mixer>
diff --git a/configs/msmcobalt/sound_trigger_platform_info.xml b/configs/msmcobalt/sound_trigger_platform_info.xml
index b92ea48..7ce74aa 100644
--- a/configs/msmcobalt/sound_trigger_platform_info.xml
+++ b/configs/msmcobalt/sound_trigger_platform_info.xml
@@ -29,8 +29,7 @@
     <param version="0x0101" /> <!-- this must be the first param -->
 
     <common_config>
-        <param execution_type="CPE" /> <!-- value: "CPE" "APE" -->
-        <param max_cpe_sessions="1" />
+        <param max_cpe_sessions="2" />
         <param max_ape_sessions="8" />
         <param enable_failure_detection="false" />
     </common_config>
@@ -41,11 +40,12 @@
         <param DEVICE_HANDSET_CPE_ECPP_ACDB_ID="128" />
     </acdb_ids>
 
-    <!-- Multiple sound_model_config tags can be listed, each with unique    -->
-    <!-- vendor_uuid. The below tag represents QTI SVA engine sound model    -->
-    <!-- configuration. ISV must use their own unique vendor_uuid.           -->
+    <!-- Multiple sound_model_config tags can be listed, each with unique   -->
+    <!-- vendor_uuid. The below tag represents QTI SVA engine sound model   -->
+    <!-- configuration. ISV must use their own unique vendor_uuid.          -->
     <sound_model_config>
         <param vendor_uuid="68ab2d40-e860-11e3-95ef-0002a5d5c51b" />
+        <param execution_type="WDSP" /> <!-- value: "WDSP" "ADSP" "DYNAMIC" -->
         <param app_type="2" /> <!-- app type used in ACDB -->
         <param library="libsmwrapper.so" />
         <param max_cpe_phrases="6" />
@@ -54,7 +54,27 @@
         <param max_ape_users="10" />
         <param sample_rate="16000" />
 
-        <!-- Module and param ids with which the algorithm is integrated in firmware -->
+        <gcs_uid>
+            <param uid="0x1" />
+            <param did="0x4" />
+            <param load_sound_model_ids="0x00012C0D, 0x0, 0x00012C14" />
+            <param confidence_levels_ids="0x00012C0D, 0x0, 0x00012C28" />
+            <param operation_mode_ids="0x00012C0D, 0x0, 0x00012C28" />
+            <param detection_event_ids="0x00012C0D, 0x0, 0x00012C29" />
+            <param capture_event_ids="0x00020013, 0x0,0x00020015" />
+        </gcs_uid>
+        <gcs_uid>
+            <param uid="0x2" />
+            <param did="0x4" />
+            <param load_sound_model_ids="0x00012C0D, 0x1, 0x00012C14" />
+            <param confidence_levels_ids="0x00012C0D, 0x1, 0x00012C28" />
+            <param operation_mode_ids="0x00012C0D, 0x1 0x00012C28" />
+            <param detection_event_ids="0x00012C0D, 0x1, 0x00012C29" />
+            <param capture_event_ids="0x00020013, 0x1,0x00020015" />
+        </gcs_uid>
+
+        <!-- Module and param ids with which the algorithm is integrated
+            in non-graphite firmware (note these must come after gcs params) -->
         <param load_sound_model_ids="0x00012C0D, 0x00012C14" />
         <param unload_sound_model_ids="0x00012C0D, 0x00012C15" />
         <param confidence_levels_ids="0x00012C0D, 0x00012C07" />
@@ -62,7 +82,8 @@
 
         <!-- format: "ADPCM_packet" or "PCM_packet" !-->
         <!-- transfer_mode: "FTRT" or "RT" -->
-        <!--  kw_duration is in milli seconds. It is valid only for FTRT transfer mode -->
+        <!--  kw_duration is in milli seconds. It is valid only for FTRT
+            transfer mode -->
         <param capture_keyword="PCM_packet, RT, 2000" />
         <param client_capture_read_delay="2000" />
     </sound_model_config>
diff --git a/hal/Android.mk b/hal/Android.mk
index 83787e3..705e5e8 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -243,6 +243,11 @@
     LOCAL_SRC_FILES += audio_extn/source_track.c
 endif
 
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_SPLIT_A2DP)),true)
+    LOCAL_CFLAGS += -DSPLIT_A2DP_ENABLED
+    LOCAL_SRC_FILES += audio_extn/a2dp.c
+endif
+
 LOCAL_SHARED_LIBRARIES := \
 	liblog \
 	libcutils \
@@ -251,6 +256,7 @@
 	libaudioroute \
 	libdl \
 	libaudioutils \
+	libhardware \
 	libexpat
 
 LOCAL_C_INCLUDES += \
@@ -279,6 +285,14 @@
 endif
 
 ifeq ($(strip $(BOARD_SUPPORTS_SOUND_TRIGGER)),true)
+    ST_FEATURE_ENABLE := true
+endif
+
+ifeq ($(strip $(BOARD_SUPPORTS_SOUND_TRIGGER_HAL)),true)
+    ST_FEATURE_ENABLE := true
+endif
+
+ifeq ($(ST_FEATURE_ENABLE), true)
     LOCAL_CFLAGS += -DSOUND_TRIGGER_ENABLED
     LOCAL_CFLAGS += -DSOUND_TRIGGER_PLATFORM_NAME=$(TARGET_BOARD_PLATFORM)
     LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/sound_trigger
@@ -301,6 +315,11 @@
 LOCAL_COPY_HEADERS_TO   := mm-audio
 LOCAL_COPY_HEADERS      := audio_extn/audio_defs.h
 
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_SND_MONITOR)), true)
+    LOCAL_CFLAGS += -DSND_MONITOR_ENABLED
+    LOCAL_SRC_FILES += audio_extn/sndmonitor.c
+endif
+
 LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM)
 
 LOCAL_MODULE_RELATIVE_PATH := hw
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
new file mode 100644
index 0000000..7293ded
--- /dev/null
+++ b/hal/audio_extn/a2dp.c
@@ -0,0 +1,705 @@
+/*
+* Copyright (c) 2015-16, 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 "split_a2dp"
+/*#define LOG_NDEBUG 0*/
+#define LOG_NDDEBUG 0
+#include <errno.h>
+#include <cutils/log.h>
+#include <dlfcn.h>
+#include "audio_hw.h"
+#include "platform.h"
+#include "platform_api.h"
+#include <stdlib.h>
+#include <cutils/str_parms.h>
+#include <hardware/audio.h>
+#include <hardware/hardware.h>
+#include <cutils/properties.h>
+
+#ifdef SPLIT_A2DP_ENABLED
+#define AUDIO_PARAMETER_A2DP_STARTED "A2dpStarted"
+#define BT_IPC_LIB_NAME  "libbthost_if.so"
+#define ENC_MEDIA_FMT_NONE                                     0
+#define ENC_MEDIA_FMT_AAC                                  0x00010DA6
+#define ENC_MEDIA_FMT_APTX                                 0x000131ff
+#define ENC_MEDIA_FMT_APTX_HD                              0x00013200
+#define ENC_MEDIA_FMT_SBC                                  0x00010BF2
+#define MEDIA_FMT_AAC_AOT_LC                               2
+#define MEDIA_FMT_AAC_AOT_SBR                              5
+#define MEDIA_FMT_AAC_AOT_PS                               29
+#define MEDIA_FMT_AAC_FORMAT_FLAG_ADTS                     0
+#define MEDIA_FMT_AAC_FORMAT_FLAG_RAW                      3
+#define PCM_CHANNEL_L                                      1
+#define PCM_CHANNEL_R                                      2
+#define PCM_CHANNEL_C                                      3
+#define MEDIA_FMT_SBC_CHANNEL_MODE_MONO                    1
+#define MEDIA_FMT_SBC_CHANNEL_MODE_STEREO                  2
+#define MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO               8
+#define MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO            9
+#define MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS           0
+#define MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR                1
+#define MIXER_ENC_CONFIG_BLOCK     "SLIM_7_RX Encoder Config"
+#define MIXER_ENC_FMT_SBC          "SBC"
+#define MIXER_ENC_FMT_AAC          "AAC"
+#define MIXER_ENC_FMT_APTX         "APTX"
+#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);
+typedef int (*audio_stop_stream_t)(void);
+typedef int (*audio_suspend_stream_t)(void);
+typedef void (*audio_handoff_triggered_t)(void);
+typedef void (*clear_a2dpsuspend_flag_t)(void);
+typedef void * (*audio_get_codec_config_t)(uint8_t *multicast_status,uint8_t *num_dev,
+                               audio_format_t *codec_type);
+
+enum A2DP_STATE {
+    A2DP_STATE_CONNECTED,
+    A2DP_STATE_STARTED,
+    A2DP_STATE_STOPPED,
+    A2DP_STATE_DISCONNECTED,
+};
+
+/* structure used to  update a2dp state machine
+ * to communicate IPC library
+ * to store DSP encoder configuration information
+ */
+struct a2dp_data {
+    struct audio_device *adev;
+    void *bt_lib_handle;
+    audio_stream_open_t audio_stream_open;
+    audio_stream_close_t audio_stream_close;
+    audio_start_stream_t audio_start_stream;
+    audio_stop_stream_t audio_stop_stream;
+    audio_suspend_stream_t audio_suspend_stream;
+    audio_handoff_triggered_t audio_handoff_triggered;
+    clear_a2dpsuspend_flag_t clear_a2dpsuspend_flag;
+    audio_get_codec_config_t audio_get_codec_config;
+    enum A2DP_STATE bt_state;
+    audio_format_t bt_encoder_format;
+    void *enc_config_data;
+    bool a2dp_started;
+    bool a2dp_suspended;
+    int  a2dp_total_active_session_request;
+    bool is_a2dp_offload_supported;
+    bool is_handoff_in_progress;
+};
+
+struct a2dp_data a2dp;
+
+/* START of DSP configurable structures
+ * These values should match with DSP interface defintion
+ */
+
+/* AAC encoder configuration structure. */
+typedef struct aac_enc_cfg_t aac_enc_cfg_t;
+
+/* supported enc_mode are AAC_LC, AAC_SBR, AAC_PS
+ * supported aac_fmt_flag are ADTS/RAW
+ * supported channel_cfg are Native mode, Mono , Stereo
+ */
+struct aac_enc_cfg_t {
+    uint32_t      enc_format;
+    uint32_t      bit_rate;
+    uint32_t      enc_mode;
+    uint16_t      aac_fmt_flag;
+    uint32_t      channel_cfg;
+    uint32_t      sample_rate;
+} ;
+
+/* SBC encoder configuration structure. */
+typedef struct sbc_enc_cfg_t sbc_enc_cfg_t;
+
+/* supported num_subbands are 4/8
+ * supported blk_len are 4, 8, 12, 16
+ * supported channel_mode are MONO, STEREO, DUAL_MONO, JOINT_STEREO
+ * supported alloc_method are LOUNDNESS/SNR
+ * supported bit_rate for mono channel is max 320kbps
+ * supported bit rate for stereo channel is max 512 kbps
+ */
+struct sbc_enc_cfg_t{
+    uint32_t      enc_format;
+    uint32_t      num_subbands;
+    uint32_t      blk_len;
+    uint32_t      channel_mode;
+    uint32_t      alloc_method;
+    uint32_t      bit_rate;
+    uint32_t      sample_rate;
+};
+
+
+/* supported num_channels are Mono/Stereo
+ * supported channel_mapping for mono is CHANNEL_C
+ * supported channel mapping for stereo is CHANNEL_L and CHANNEL_R
+ * custom size and reserved are not used(for future enhancement)
+  */
+struct custom_enc_cfg_aptx_t
+{
+    uint32_t      enc_format;
+    uint32_t      sample_rate;
+    uint16_t      num_channels;
+    uint16_t      reserved;
+    uint8_t       channel_mapping[8];
+    uint32_t      custom_size;
+};
+
+/*********** END of DSP configurable structures ********************/
+
+/* API to identify DSP encoder captabilities */
+static void a2dp_offload_codec_cap_parser(char *value)
+{
+    char *tok = NULL,*saveptr;
+
+    tok = strtok_r(value, "-", &saveptr);
+    while (tok != NULL) {
+        if (strcmp(tok, "sbc") == 0) {
+            ALOGD("%s: SBC offload supported\n",__func__);
+            a2dp.is_a2dp_offload_supported = true;
+            break;
+        } else if (strcmp(tok, "aptx") == 0) {
+            ALOGD("%s: aptx offload supported\n",__func__);
+            a2dp.is_a2dp_offload_supported = true;
+            break;
+        }
+        tok = strtok_r(NULL, "-", &saveptr);
+    };
+}
+
+static void update_offload_codec_capabilities()
+{
+    char value[PROPERTY_VALUE_MAX] = {'\0'};
+
+    property_get("persist.bt.a2dp_offload_cap", value, "false");
+    ALOGD("get_offload_codec_capabilities = %s",value);
+    a2dp.is_a2dp_offload_supported =
+            property_get_bool("persist.bt.a2dp_offload_cap", false);
+    if (strcmp(value, "false") != 0)
+        a2dp_offload_codec_cap_parser(value);
+    ALOGD("%s: codec cap = %s",__func__,value);
+}
+
+/* API to open BT IPC library to start IPC communication */
+static void open_a2dp_output()
+{
+    int ret = 0;
+
+    ALOGD(" Open A2DP output start ");
+    if (a2dp.bt_lib_handle == NULL){
+        ALOGD(" Requesting for BT lib handle");
+        a2dp.bt_lib_handle = dlopen(BT_IPC_LIB_NAME, RTLD_NOW);
+
+        if (a2dp.bt_lib_handle == NULL) {
+            ALOGE("%s: DLOPEN failed for %s", __func__, BT_IPC_LIB_NAME);
+            ret = -ENOSYS;
+            goto init_fail;
+        } else {
+            a2dp.audio_stream_open = (audio_stream_open_t)
+                          dlsym(a2dp.bt_lib_handle, "audio_stream_open");
+            a2dp.audio_start_stream = (audio_start_stream_t)
+                          dlsym(a2dp.bt_lib_handle, "audio_start_stream");
+            a2dp.audio_get_codec_config = (audio_get_codec_config_t)
+                          dlsym(a2dp.bt_lib_handle, "audio_get_codec_config");
+            a2dp.audio_suspend_stream = (audio_suspend_stream_t)
+                          dlsym(a2dp.bt_lib_handle, "audio_suspend_stream");
+            a2dp.audio_handoff_triggered = (audio_handoff_triggered_t)
+                          dlsym(a2dp.bt_lib_handle, "audio_handoff_triggered");
+            a2dp.clear_a2dpsuspend_flag = (clear_a2dpsuspend_flag_t)
+                          dlsym(a2dp.bt_lib_handle, "clear_a2dpsuspend_flag");
+            a2dp.audio_stop_stream = (audio_stop_stream_t)
+                          dlsym(a2dp.bt_lib_handle, "audio_stop_stream");
+            a2dp.audio_stream_close = (audio_stream_close_t)
+                          dlsym(a2dp.bt_lib_handle, "audio_stream_close");
+        }
+    }
+
+    if (a2dp.bt_lib_handle && a2dp.audio_stream_open) {
+        if (a2dp.bt_state == A2DP_STATE_DISCONNECTED) {
+            ALOGD("calling BT stream open");
+            ret = a2dp.audio_stream_open();
+            if(ret != 0) {
+                ALOGE("Failed to open output stream for a2dp: status %d", ret);
+                goto init_fail;
+            }
+            a2dp.bt_state = A2DP_STATE_CONNECTED;
+        } else {
+            ALOGD("Called a2dp open with improper state, Ignoring request state %d", a2dp.bt_state);
+        }
+    } else {
+        ALOGE("a2dp handle is not identified, Ignoring open request");
+        a2dp.bt_state = A2DP_STATE_DISCONNECTED;
+        goto init_fail;
+    }
+
+init_fail:
+    if(ret != 0 && (a2dp.bt_lib_handle != NULL)) {
+        dlclose(a2dp.bt_lib_handle);
+        a2dp.bt_lib_handle = NULL;
+    }
+}
+
+static int close_a2dp_output()
+{
+    ALOGV("%s\n",__func__);
+    if (!(a2dp.bt_lib_handle && a2dp.audio_stream_close)) {
+        ALOGE("a2dp handle is not identified, Ignoring close request");
+        return -ENOSYS;
+    }
+    if ((a2dp.bt_state == A2DP_STATE_CONNECTED) &&
+        (a2dp.bt_state == A2DP_STATE_STARTED) &&
+        (a2dp.bt_state == A2DP_STATE_STOPPED)) {
+        ALOGD("calling BT stream close");
+        if(a2dp.audio_stream_close() == false)
+            ALOGE("failed close a2dp control path from BT library");
+        a2dp.a2dp_started = false;
+        a2dp.a2dp_total_active_session_request = 0;
+        a2dp.a2dp_suspended = false;
+        a2dp.bt_encoder_format = AUDIO_FORMAT_INVALID;
+        a2dp.enc_config_data = NULL;
+        a2dp.bt_state = A2DP_STATE_DISCONNECTED;
+    } else {
+        ALOGD("close a2dp called in improper state");
+        a2dp.a2dp_started = false;
+        a2dp.a2dp_total_active_session_request = 0;
+        a2dp.a2dp_suspended = false;
+        a2dp.bt_encoder_format = AUDIO_FORMAT_INVALID;
+        a2dp.enc_config_data = NULL;
+        a2dp.bt_state = A2DP_STATE_DISCONNECTED;
+    }
+
+    return 0;
+}
+
+/* API to configure SBC DSP encoder */
+bool configure_sbc_enc_format(audio_sbc_encoder_config *sbc_bt_cfg)
+{
+    struct mixer_ctl *ctl_enc_data;
+    struct sbc_enc_cfg_t sbc_dsp_cfg;
+    bool is_configured = false;
+    int ret = 0;
+
+    if(sbc_bt_cfg == NULL)
+        return false;
+
+   ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
+    if (!ctl_enc_data) {
+        ALOGE(" ERROR  a2dp encoder CONFIG data mixer control not identifed");
+        is_configured = false;
+        goto fail;
+    }
+    a2dp.bt_encoder_format = AUDIO_FORMAT_SBC;
+    memset(&sbc_dsp_cfg, 0x0, sizeof(struct sbc_enc_cfg_t));
+    sbc_dsp_cfg.enc_format = ENC_MEDIA_FMT_SBC;
+    sbc_dsp_cfg.num_subbands = sbc_bt_cfg->subband;
+    sbc_dsp_cfg.blk_len = sbc_bt_cfg->blk_len;
+    switch(sbc_bt_cfg->channels) {
+        case 0:
+            sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_MONO;
+            break;
+        case 1:
+            sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO;
+            break;
+        case 3:
+            sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO;
+            break;
+        case 2:
+        default:
+            sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_STEREO;
+            break;
+    }
+    if (sbc_bt_cfg->alloc)
+        sbc_dsp_cfg.alloc_method = MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS;
+    else
+        sbc_dsp_cfg.alloc_method = MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR;
+    sbc_dsp_cfg.bit_rate = sbc_bt_cfg->bitrate;
+    sbc_dsp_cfg.sample_rate = sbc_bt_cfg->sampling_rate;
+    ret = mixer_ctl_set_array(ctl_enc_data, (void *)&sbc_dsp_cfg,
+                                    sizeof(struct sbc_enc_cfg_t));
+    if (ret != 0) {
+        ALOGE("%s: failed to set SBC encoder config", __func__);
+        is_configured = false;
+    } else
+        is_configured = true;
+fail:
+    return is_configured;
+}
+
+/* API to configure APTX DSP encoder */
+bool configure_aptx_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
+{
+    struct mixer_ctl *ctl_enc_data;
+    struct custom_enc_cfg_aptx_t aptx_dsp_cfg;
+    bool is_configured = false;
+    int ret = 0;
+
+    if(aptx_bt_cfg == NULL)
+        return false;
+
+    ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
+    if (!ctl_enc_data) {
+        ALOGE(" ERROR  a2dp encoder CONFIG data mixer control not identifed");
+        is_configured = false;
+        goto fail;
+    }
+    a2dp.bt_encoder_format = AUDIO_FORMAT_APTX;
+    memset(&aptx_dsp_cfg, 0x0, sizeof(struct custom_enc_cfg_aptx_t));
+    aptx_dsp_cfg.enc_format = ENC_MEDIA_FMT_APTX;
+    aptx_dsp_cfg.sample_rate = aptx_bt_cfg->sampling_rate;
+    aptx_dsp_cfg.num_channels = aptx_bt_cfg->channels;
+    switch(aptx_dsp_cfg.num_channels) {
+        case 1:
+            aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_C;
+            break;
+        case 2:
+        default:
+            aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_L;
+            aptx_dsp_cfg.channel_mapping[1] = PCM_CHANNEL_R;
+            break;
+    }
+    ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
+                              sizeof(struct custom_enc_cfg_aptx_t));
+    if (ret != 0) {
+        ALOGE("%s: Failed to set APTX encoder config", __func__);
+        is_configured = false;
+        goto fail;
+    }
+    is_configured = true;
+fail:
+    return is_configured;
+}
+
+/* API to configure APTX HD DSP encoder
+ * TODO: ADD 24 bit configuration support
+ */
+bool configure_aptx_hd_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
+{
+    struct mixer_ctl *ctl_enc_data;
+    struct custom_enc_cfg_aptx_t aptx_dsp_cfg;
+    bool is_configured = false;
+    int ret = 0;
+
+    if(aptx_bt_cfg == NULL)
+        return false;
+
+    ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
+    if (!ctl_enc_data) {
+        ALOGE(" ERROR  a2dp encoder CONFIG data mixer control not identifed");
+        is_configured = false;
+        goto fail;
+    }
+    a2dp.bt_encoder_format = AUDIO_FORMAT_APTX_HD;
+    memset(&aptx_dsp_cfg, 0x0, sizeof(struct custom_enc_cfg_aptx_t));
+    aptx_dsp_cfg.enc_format = ENC_MEDIA_FMT_APTX_HD;
+    aptx_dsp_cfg.sample_rate = aptx_bt_cfg->sampling_rate;
+    aptx_dsp_cfg.num_channels = aptx_bt_cfg->channels;
+    switch(aptx_dsp_cfg.num_channels) {
+        case 1:
+            aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_C;
+            break;
+        case 2:
+        default:
+            aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_L;
+            aptx_dsp_cfg.channel_mapping[1] = PCM_CHANNEL_R;
+            break;
+    }
+    ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
+                              sizeof(struct custom_enc_cfg_aptx_t));
+    if (ret != 0) {
+        ALOGE("%s: Failed to set APTX HD encoder config", __func__);
+        is_configured = false;
+        goto fail;
+    }
+    is_configured = true;
+fail:
+    return is_configured;
+}
+
+/* API to configure AAC DSP encoder */
+bool configure_aac_enc_format(audio_aac_encoder_config *aac_bt_cfg)
+{
+    struct mixer_ctl *ctl_enc_data;
+    struct aac_enc_cfg_t aac_dsp_cfg;
+    bool is_configured = false;
+    int ret = 0;
+
+    if(aac_bt_cfg == NULL)
+        return false;
+
+    ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
+    if (!ctl_enc_data) {
+        ALOGE(" ERROR  a2dp encoder CONFIG data mixer control not identifed");
+        is_configured = false;
+        goto fail;
+    }
+    a2dp.bt_encoder_format = AUDIO_FORMAT_AAC;
+    memset(&aac_dsp_cfg, 0x0, sizeof(struct aac_enc_cfg_t));
+    aac_dsp_cfg.enc_format = ENC_MEDIA_FMT_AAC;
+    aac_dsp_cfg.bit_rate = aac_bt_cfg->bitrate;
+    switch(aac_bt_cfg->enc_mode) {
+        case 0:
+            aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_LC;
+            break;
+        case 2:
+            aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_PS;
+            break;
+        case 1:
+        default:
+            aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_SBR;
+            break;
+    }
+    if (aac_bt_cfg->format_flag)
+        aac_dsp_cfg.aac_fmt_flag = MEDIA_FMT_AAC_FORMAT_FLAG_RAW;
+    else
+        aac_dsp_cfg.aac_fmt_flag = MEDIA_FMT_AAC_FORMAT_FLAG_ADTS;
+    aac_dsp_cfg.channel_cfg = aac_bt_cfg->channels;
+    ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aac_dsp_cfg,
+                              sizeof(struct aac_enc_cfg_t));
+    if (ret != 0) {
+        ALOGE("%s: failed to set SBC encoder config", __func__);
+        is_configured = false;
+    } else
+        is_configured = true;
+fail:
+    return is_configured;
+}
+
+bool configure_a2dp_encoder_format()
+{
+    void *codec_info = NULL;
+    uint8_t multi_cast = 0, num_dev = 1;
+    audio_format_t codec_type = AUDIO_FORMAT_INVALID;
+    bool is_configured = false;
+
+    if (!a2dp.audio_get_codec_config) {
+        ALOGE(" a2dp handle is not identified, ignoring a2dp encoder config");
+        return false;
+    }
+    ALOGD("configure_a2dp_encoder_format start");
+    codec_info = a2dp.audio_get_codec_config(&multi_cast, &num_dev,
+                               &codec_type);
+
+    switch(codec_type) {
+        case AUDIO_FORMAT_SBC:
+            ALOGD(" Received SBC encoder supported BT device");
+            is_configured =
+               configure_sbc_enc_format((audio_sbc_encoder_config *)codec_info);
+            break;
+        case AUDIO_FORMAT_APTX:
+            ALOGD(" Received APTX encoder supported BT device");
+            is_configured =
+              configure_aptx_enc_format((audio_aptx_encoder_config *)codec_info);
+            break;
+        case AUDIO_FORMAT_APTX_HD:
+            ALOGD(" Received APTX HD encoder supported BT device");
+            is_configured =
+             configure_aptx_hd_enc_format((audio_aptx_encoder_config *)codec_info);
+            break;
+        case AUDIO_FORMAT_AAC:
+            ALOGD(" Received AAC encoder supported BT device");
+            is_configured =
+              configure_aac_enc_format((audio_aac_encoder_config *)codec_info);
+            break;
+        default:
+            ALOGD(" Received Unsupported encoder formar");
+            is_configured = false;
+            break;
+    }
+    return is_configured;
+}
+
+int audio_extn_a2dp_start_playback()
+{
+    int ret = 0;
+
+    ALOGD("audio_extn_a2dp_start_playback start");
+
+    if(!(a2dp.bt_lib_handle && a2dp.audio_start_stream
+       && a2dp.audio_get_codec_config)) {
+        ALOGE("a2dp handle is not identified, Ignoring start request");
+        return -ENOSYS;
+    }
+
+    if(a2dp.a2dp_suspended == true) {
+        //session will be restarted after suspend completion
+        ALOGD("a2dp start requested during suspend state");
+        return -ENOSYS;
+    }
+
+    if (!a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
+        ALOGD("calling BT module stream start");
+        /* This call indicates BT IPC lib to start playback */
+        ret =  a2dp.audio_start_stream();
+        ALOGE("BT controller start return = %d",ret);
+        if (ret != 0 ) {
+           ALOGE("BT controller start failed");
+           a2dp.a2dp_started = false;
+           ret = -ETIMEDOUT;
+        } else {
+           if(configure_a2dp_encoder_format() == true) {
+                a2dp.a2dp_started = true;
+                ret = 0;
+                ALOGD("Start playback successful to BT library");
+           } else {
+                ALOGD(" unable to configure DSP encoder");
+                a2dp.a2dp_started = false;
+                ret = -ETIMEDOUT;
+           }
+        }
+    }
+
+    if (a2dp.a2dp_started)
+        a2dp.a2dp_total_active_session_request++;
+
+    ALOGD("start A2DP playback total active sessions :%d",
+          a2dp.a2dp_total_active_session_request);
+    return ret;
+}
+
+int audio_extn_a2dp_stop_playback()
+{
+    int ret =0;
+
+    ALOGV("audio_extn_a2dp_stop_playback start");
+    if(!(a2dp.bt_lib_handle && a2dp.audio_stop_stream)) {
+        ALOGE("a2dp handle is not identified, Ignoring start request");
+        return -ENOSYS;
+    }
+
+    if (a2dp.a2dp_started && (a2dp.a2dp_total_active_session_request > 0))
+        a2dp.a2dp_total_active_session_request--;
+
+    if ( a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
+        struct mixer_ctl *ctl_enc_config;
+        struct sbc_enc_cfg_t dummy_reset_config;
+
+        ALOGV("calling BT module stream stop");
+        ret = a2dp.audio_stop_stream();
+        if (ret < 0)
+            ALOGE("stop stream to BT IPC lib failed");
+        else
+            ALOGV("stop steam to BT IPC lib successful");
+         memset(&dummy_reset_config, 0x0, sizeof(struct sbc_enc_cfg_t));
+        ctl_enc_config = mixer_get_ctl_by_name(a2dp.adev->mixer,
+                                               MIXER_ENC_CONFIG_BLOCK);
+        if (!ctl_enc_config) {
+            ALOGE(" ERROR  a2dp encoder format mixer control not identifed");
+        } else {
+            ret = mixer_ctl_set_array(ctl_enc_config, (void *)&dummy_reset_config,
+                                            sizeof(struct sbc_enc_cfg_t));
+             a2dp.bt_encoder_format = ENC_MEDIA_FMT_NONE;
+        }
+    }
+    if(!a2dp.a2dp_total_active_session_request)
+       a2dp.a2dp_started = false;
+    ALOGD("Stop A2DP playback total active sessions :%d",
+          a2dp.a2dp_total_active_session_request);
+    return 0;
+}
+
+void audio_extn_a2dp_set_parameters(struct str_parms *parms)
+{
+     int ret, val;
+     char value[32]={0};
+
+     if(a2dp.is_a2dp_offload_supported == false) {
+        ALOGV("no supported encoders identified,ignoring a2dp setparam");
+        return;
+     }
+
+     ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value,
+                            sizeof(value));
+     if( ret >= 0) {
+         val = atoi(value);
+         if (val & AUDIO_DEVICE_OUT_ALL_A2DP) {
+             ALOGV("Received device connect request for A2DP");
+             open_a2dp_output();
+         }
+         goto param_handled;
+     }
+
+     ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_DISCONNECT, value,
+                         sizeof(value));
+
+     if( ret >= 0) {
+         val = atoi(value);
+         if (val & AUDIO_DEVICE_OUT_ALL_A2DP) {
+             ALOGV("Received device dis- connect request");
+             close_a2dp_output();
+         }
+         goto param_handled;
+     }
+
+     ret = str_parms_get_str(parms, "A2dpSuspended", value, sizeof(value));
+     if (ret >= 0) {
+         if (a2dp.bt_lib_handle && (a2dp.bt_state != A2DP_STATE_DISCONNECTED) ) {
+             if ((!strncmp(value,"true",sizeof(value)))) {
+                ALOGD("Setting a2dp to suspend state");
+                a2dp.a2dp_suspended = true;
+                if(a2dp.audio_suspend_stream)
+                   a2dp.audio_suspend_stream();
+            } else if (a2dp.a2dp_suspended == true) {
+                ALOGD("Resetting a2dp suspend state");
+                if(a2dp.clear_a2dpsuspend_flag)
+                    a2dp.clear_a2dpsuspend_flag();
+                a2dp.a2dp_suspended = false;
+            }
+        }
+        goto param_handled;
+     }
+param_handled:
+     ALOGV("end of a2dp setparam");
+}
+
+void audio_extn_a2dp_set_handoff_mode(bool is_on)
+{
+    a2dp.is_handoff_in_progress = is_on;
+}
+
+bool audio_extn_a2dp_is_force_device_switch()
+{
+    //During encoder reconfiguration mode, force a2dp device switch
+    return a2dp.is_handoff_in_progress;
+}
+
+void audio_extn_a2dp_init (void *adev)
+{
+  a2dp.adev = (struct audio_device*)adev;
+  a2dp.bt_lib_handle = NULL;
+  a2dp.a2dp_started = false;
+  a2dp.bt_state = A2DP_STATE_DISCONNECTED;
+  a2dp.a2dp_total_active_session_request = 0;
+  a2dp.a2dp_suspended = false;
+  a2dp.bt_encoder_format = AUDIO_FORMAT_INVALID;
+  a2dp.enc_config_data = NULL;
+  a2dp.is_a2dp_offload_supported = false;
+  a2dp.is_handoff_in_progress = false;
+  update_offload_codec_capabilities();
+}
+#endif // SPLIT_A2DP_ENABLED
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 49e649c..569b4b2 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -755,6 +755,7 @@
    audio_extn_ssr_set_parameters(adev, parms);
    audio_extn_hfp_set_parameters(adev, parms);
    audio_extn_dts_eagle_set_parameters(adev, parms);
+   audio_extn_a2dp_set_parameters(parms);
    audio_extn_ddp_set_parameters(adev, parms);
    audio_extn_ds2_set_parameters(adev, parms);
    audio_extn_customstereo_set_parameters(adev, parms);
@@ -762,6 +763,7 @@
    audio_extn_pm_set_parameters(parms);
    audio_extn_source_track_set_parameters(adev, parms);
    audio_extn_fbsp_set_parameters(parms);
+   audio_extn_keep_alive_set_parameters(adev, parms);
    check_and_set_hdmi_connection_status(parms);
    if (adev->offload_effects_set_parameters != NULL)
        adev->offload_effects_set_parameters(parms);
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index fe3fe95..e8caeee 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -171,6 +171,22 @@
                                      char *value, int len);
 #endif
 
+#ifndef SPLIT_A2DP_ENABLED
+#define audio_extn_a2dp_init(adev)                       (0)
+#define audio_extn_a2dp_start_playback()                 (0)
+#define audio_extn_a2dp_stop_playback()                  (0)
+#define audio_extn_a2dp_set_parameters(parms)            (0)
+#define audio_extn_a2dp_is_force_device_switch()         (0)
+#define audio_extn_a2dp_set_handoff_mode(is_on)          (0)
+#else
+void audio_extn_a2dp_init(void *adev);
+int audio_extn_a2dp_start_playback();
+void 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);
+#endif
+
 #ifndef SSR_ENABLED
 #define audio_extn_ssr_check_and_set_usecase(in)      (0)
 #define audio_extn_ssr_init(in, num_out_chan)         (0)
@@ -387,6 +403,10 @@
 
 #endif
 
+#ifndef AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH
+#define AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH  0x10000
+#endif
+
 #ifndef HDMI_PASSTHROUGH_ENABLED
 #define audio_extn_passthru_update_stream_configuration(adev, out)            (0)
 #define audio_extn_passthru_is_convert_supported(adev, out)                   (0)
@@ -405,8 +425,6 @@
 #define audio_extn_passthru_set_parameters(a, p) (-ENOSYS)
 #define audio_extn_passthru_init(a) do {} while(0)
 #define audio_extn_passthru_should_standby(o) (1)
-
-#define AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH  0x1000
 #else
 bool audio_extn_passthru_is_convert_supported(struct audio_device *adev,
                                                  struct stream_out *out);
@@ -572,4 +590,17 @@
 #endif
 
 
+typedef void (* snd_mon_cb)(void * stream, struct str_parms * parms);
+#ifndef SND_MONITOR_ENABLED
+#define audio_extn_snd_mon_init()           (0)
+#define audio_extn_snd_mon_deinit()         (0)
+#define audio_extn_snd_mon_register_listener(stream, cb) (0)
+#define audio_extn_snd_mon_unregister_listener(stream) (0)
+#else
+int audio_extn_snd_mon_init();
+int audio_extn_snd_mon_deinit();
+int audio_extn_snd_mon_register_listener(void *stream, snd_mon_cb cb);
+int audio_extn_snd_mon_unregister_listener(void *stream);
+#endif
+
 #endif /* AUDIO_EXTN_H */
diff --git a/hal/audio_extn/keep_alive.c b/hal/audio_extn/keep_alive.c
index 1a4f135..60e7eef 100644
--- a/hal/audio_extn/keep_alive.c
+++ b/hal/audio_extn/keep_alive.c
@@ -38,7 +38,7 @@
 
 #define SILENCE_MIXER_PATH "silence-playback hdmi"
 #define SILENCE_DEV_ID 32           /* index into machine driver */
-#define SILENCE_INTERVAL_US 2000000
+#define SILENCE_INTERVAL 2 /*In secs*/
 
 typedef enum {
     STATE_DEINIT = -1,
@@ -52,7 +52,9 @@
 
 typedef struct {
     pthread_mutex_t lock;
+    pthread_mutex_t sleep_lock;
     pthread_cond_t  cond;
+    pthread_cond_t  wake_up_cond;
     pthread_t thread;
     state_t state;
     struct listnode cmd_list;
@@ -88,6 +90,8 @@
     ka.pcm = NULL;
     pthread_mutex_init(&ka.lock, (const pthread_mutexattr_t *) NULL);
     pthread_cond_init(&ka.cond, (const pthread_condattr_t *) NULL);
+    pthread_cond_init(&ka.wake_up_cond, (const pthread_condattr_t *) NULL);
+    pthread_mutex_init(&ka.sleep_lock, (const pthread_mutexattr_t *) NULL);
     list_init(&ka.cmd_list);
     if (pthread_create(&ka.thread,  (const pthread_attr_t *) NULL,
                        keep_alive_loop, NULL) < 0) {
@@ -143,6 +147,27 @@
     return 0;
 }
 
+
+static int set_mixer_control(struct mixer *mixer,
+                             const char * mixer_ctl_name,
+                             const char *mixer_val)
+{
+    struct mixer_ctl *ctl;
+    if ((mixer == NULL) || (mixer_ctl_name == NULL) || (mixer_val == NULL)) {
+       ALOGE("%s: Invalid input", __func__);
+       return -EINVAL;
+    }
+    ALOGD("setting mixer ctl %s with value %s", mixer_ctl_name, mixer_val);
+    ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
+    if (!ctl) {
+        ALOGE("%s: could not get ctl for mixer cmd - %s",
+              __func__, mixer_ctl_name);
+        return -EINVAL;
+    }
+
+    return mixer_ctl_set_enum_by_string(ctl, mixer_val);
+}
+
 /* must be called with adev lock held */
 void audio_extn_keep_alive_start()
 {
@@ -151,18 +176,20 @@
     int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT], len = 0, rc;
     struct mixer_ctl *ctl;
     int acdb_dev_id, snd_device;
+    struct listnode *node;
+    struct audio_usecase *usecase;
     int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
 
     pthread_mutex_lock(&ka.lock);
 
     if (ka.state == STATE_DEINIT) {
         ALOGE(" %s : Invalid state ",__func__);
-        return;
+        goto exit;
     }
 
     if (audio_extn_passthru_is_active()) {
         ALOGE(" %s : Pass through is already active", __func__);
-        return;
+        goto exit;
     }
 
     if (ka.state == STATE_ACTIVE) {
@@ -170,6 +197,14 @@
         goto exit;
     }
 
+    /* Dont start keep_alive if any other PCM session is routed to HDMI*/
+    list_for_each(node, &adev->usecase_list) {
+         usecase = node_to_item(node, struct audio_usecase, list);
+         if (usecase->type == PCM_PLAYBACK &&
+                 usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
+             goto exit;
+    }
+
     ka.done = false;
 
     /*configure app type */
@@ -202,9 +237,15 @@
           platform_get_default_app_type(adev->platform),
           acdb_dev_id, sample_rate);
     mixer_ctl_set_array(ctl, app_type_cfg, len);
+    /*Configure HDMI Backend with default values, this as well
+     *helps reconfigure HDMI backend after passthrough
+     */
+    set_mixer_control(adev->mixer, "HDMI RX Format", "LPCM");
+    set_mixer_control(adev->mixer, "HDMI_RX SampleRate", "KHZ_48");
+    set_mixer_control(adev->mixer, "HDMI_RX Channels", "Two");
 
     /*send calibration*/
-    struct audio_usecase *usecase = calloc(1, sizeof(struct audio_usecase));
+    usecase = calloc(1, sizeof(struct audio_usecase));
     usecase->type = PCM_PLAYBACK;
     usecase->out_snd_device = SND_DEVICE_OUT_HDMI;
 
@@ -232,13 +273,13 @@
 
     pthread_mutex_lock(&ka.lock);
 
-    if (ka.state == STATE_DEINIT)
-        return;
-
-    if (ka.state == STATE_IDLE)
+    if ((ka.state == STATE_DEINIT) || (ka.state == STATE_IDLE))
         goto exit;
 
+    pthread_mutex_lock(&ka.sleep_lock);
     ka.done = true;
+    pthread_cond_signal(&ka.wake_up_cond);
+    pthread_mutex_unlock(&ka.sleep_lock);
     while (ka.state != STATE_IDLE) {
         pthread_cond_wait(&ka.cond, &ka.lock);
     }
@@ -290,6 +331,7 @@
     struct listnode *item;
     uint8_t * silence = NULL;
     int32_t bytes = 0;
+    struct timespec ts;
 
     while (true) {
         pthread_mutex_lock(&ka.lock);
@@ -328,9 +370,17 @@
              * Just something to keep the connection alive is sufficient.
              * Hence a short burst of silence periodically.
              */
-            usleep(SILENCE_INTERVAL_US);
-        }
+            pthread_mutex_lock(&ka.sleep_lock);
+            clock_gettime(CLOCK_REALTIME, &ts);
+            ts.tv_sec += SILENCE_INTERVAL;
+            ts.tv_nsec = 0;
 
+            if (!ka.done)
+              pthread_cond_timedwait(&ka.wake_up_cond,
+                            &ka.sleep_lock, &ts);
+
+            pthread_mutex_unlock(&ka.sleep_lock);
+        }
         pthread_mutex_lock(&ka.lock);
         ka.state = STATE_IDLE;
         pthread_cond_signal(&ka.cond);
diff --git a/hal/audio_extn/passthru.c b/hal/audio_extn/passthru.c
index e6ac4dd..eaa8c0a 100644
--- a/hal/audio_extn/passthru.c
+++ b/hal/audio_extn/passthru.c
@@ -82,8 +82,14 @@
  */
 bool audio_extn_passthru_should_drop_data(struct stream_out * out)
 {
-
-    if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+    /*Drop data only
+     *stream is routed to HDMI and
+     *stream has PCM format or
+     *if a compress offload (DSP decode) session
+     */
+    if ((out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
+        (((out->format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM) ||
+        ((out->compr_config.codec != NULL) && (out->compr_config.codec->compr_passthr == LEGACY_PCM)))) {
         if (android_atomic_acquire_load(&compress_passthru_active) > 0) {
             ALOGI("drop data as pass thru is active");
             return true;
@@ -112,9 +118,6 @@
     ALOGV("inc pass thru count to notify other streams");
     android_atomic_inc(&compress_passthru_active);
 
-    ALOGV("keep_alive_stop");
-    audio_extn_keep_alive_stop();
-
     while (true) {
         /* find max period time among active playback use cases */
         list_for_each(node, &adev->usecase_list) {
diff --git a/hal/audio_extn/sndmonitor.c b/hal/audio_extn/sndmonitor.c
new file mode 100644
index 0000000..eecc448
--- /dev/null
+++ b/hal/audio_extn/sndmonitor.c
@@ -0,0 +1,684 @@
+/*
+* Copyright (c) 2016, 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 "audio_hw_sndmonitor"
+/*#define LOG_NDEBUG 0*/
+#define LOG_NDDEBUG 0
+
+/* monitor sound card, cpe state
+
+   audio_dev registers for a callback from this module in adev_open
+   Each stream in audio_hal registers for a callback in
+   adev_open_*_stream.
+
+   A thread is spawned to poll() on sound card state files in /proc.
+   On observing a sound card state change, this thread invokes the
+   callbacks registered.
+
+   Callbacks are deregistered in adev_close_*_stream and adev_close
+*/
+#include <stdlib.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/poll.h>
+#include <cutils/list.h>
+#include <cutils/hashmap.h>
+#include <cutils/log.h>
+#include <cutils/str_parms.h>
+#include <ctype.h>
+
+#include "audio_hw.h"
+#include "audio_extn.h"
+
+//#define MONITOR_DEVICE_EVENTS
+#define CPE_MAGIC_NUM 0x2000
+#define MAX_CPE_SLEEP_RETRY 2
+#define CPE_SLEEP_WAIT 100
+
+#define MAX_SLEEP_RETRY 100
+#define AUDIO_INIT_SLEEP_WAIT 100 /* 100 ms */
+
+#define AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE "ext_audio_device"
+#define INIT_MAP_SIZE 5
+
+typedef enum {
+    audio_event_on,
+    audio_event_off
+} audio_event_status;
+
+typedef struct {
+    int card;
+    int fd;
+    struct listnode node; // membership in sndcards list
+    card_status_t status;
+} sndcard_t;
+
+typedef struct {
+    char *dev;
+    int fd;
+    int status;
+    struct listnode node; // membership in deviceevents list;
+} dev_event_t;
+
+typedef void (*notifyfn)(const void *target, const char *msg);
+
+typedef struct {
+    const void *target;
+    notifyfn notify;
+    struct listnode cards;
+    unsigned int num_cards;
+    struct listnode dev_events;
+    unsigned int num_dev_events;
+    pthread_t monitor_thread;
+    int intpipe[2];
+    Hashmap *listeners; // from stream * -> callback func
+    bool initcheck;
+} sndmonitor_state_t;
+
+static sndmonitor_state_t sndmonitor;
+
+static char *read_state(int fd)
+{
+    struct stat buf;
+    if (fstat(fd, &buf) < 0)
+        return NULL;
+
+    off_t pos = lseek(fd, 0, SEEK_CUR);
+    off_t avail = buf.st_size - pos;
+    if (avail <= 0) {
+        ALOGE("avail %ld", avail);
+        return NULL;
+    }
+
+    char *state = (char *)calloc(avail+1, sizeof(char));
+    if (!state)
+        return NULL;
+
+    ssize_t bytes = read(fd, state, avail);
+    if (bytes <= 0)
+        return NULL;
+
+    // trim trailing whitespace
+    while (bytes && isspace(*(state+bytes-1))) {
+        *(state + bytes - 1) = '\0';
+        --bytes;
+    }
+    lseek(fd, 0, SEEK_SET);
+    return state;
+}
+
+static int add_new_sndcard(int card, int fd)
+{
+    sndcard_t *s = (sndcard_t *)calloc(sizeof(sndcard_t), 1);
+
+    if (!s)
+        return -1;
+
+    s->card = card;
+    s->fd = fd; // dup?
+
+    char *state = read_state(fd);
+
+    if (!state)
+        return -1;
+
+    bool online = state && !strcmp(state, "ONLINE");
+
+    ALOGV("card %d initial state %s %d", card, state, online);
+
+    if (state)
+        free(state);
+
+    s->status = online ? CARD_STATUS_ONLINE : CARD_STATUS_OFFLINE;
+    list_add_tail(&sndmonitor.cards, &s->node);
+    return 0;
+}
+
+static int validate_snd_card(const char *id)
+{
+    return !strncasecmp(id, "msm", 3) ? 0 : -1;
+}
+
+static int enum_sndcards()
+{
+    const char *cards = "/proc/asound/cards";
+    int tries = 10;
+    char *line = NULL;
+    size_t len = 0;
+    ssize_t bytes_read = -1;
+    char path[128] = {0};
+    char *ptr = NULL, *saveptr = NULL, *card_id = NULL;
+    int line_no=0;
+    unsigned int num_cards=0, num_cpe=0;
+    FILE *fp = NULL;
+    int fd = -1, ret = -1;
+
+    while (--tries) {
+        if ((fp = fopen(cards, "r")) == NULL) {
+            ALOGE("Cannot open %s file to get list of sound cards", cards);
+            usleep(100000);
+            continue;
+        }
+        break;
+    }
+
+    if (!tries)
+        return -ENODEV;
+
+    while ((bytes_read = getline(&line, &len, fp) != -1)) {
+        // skip every other line to to match
+        // the output format of /proc/asound/cards
+        if (line_no++ % 2)
+            continue;
+
+        ptr = strtok_r(line, " [", &saveptr);
+        if (!ptr)
+            continue;
+
+        card_id = strtok_r(saveptr+1, "]", &saveptr);
+        if (!card_id)
+            continue;
+
+        // Only consider sound cards associated with ADSP
+        if (validate_snd_card((const char *)card_id) < 0) {
+            ALOGW("Skip over non-ADSP snd card %s", card_id);
+            continue;
+        }
+
+        snprintf(path, sizeof(path), "/proc/asound/card%s/state", ptr);
+        ALOGV("Opening sound card state : %s", path);
+
+        fd = open(path, O_RDONLY);
+        if (fd == -1) {
+            ALOGE("Open %s failed : %s", path, strerror(errno));
+            continue;
+        }
+
+        ret = add_new_sndcard(atoi(ptr), fd);
+        if (ret != 0)
+            continue;
+
+        num_cards++;
+
+        // query cpe state for this card as well
+        tries = MAX_CPE_SLEEP_RETRY;
+        snprintf(path, sizeof(path), "/proc/asound/card%s/cpe0_state", ptr);
+
+        if (access(path, R_OK) < 0) {
+            ALOGW("access %s failed w/ err %s", path, strerror(errno));
+            continue;
+        }
+
+        ALOGV("Open cpe state card state %s", path);
+        while (--tries) {
+            if ((fd = open(path, O_RDONLY)) < 0) {
+                ALOGW("Open cpe state card state failed, retry : %s", path);
+                usleep(CPE_SLEEP_WAIT*1000);
+                continue;
+            }
+            break;
+        }
+
+        if (!tries)
+            continue;
+
+        ret = add_new_sndcard(CPE_MAGIC_NUM+num_cpe, fd);
+        if (ret != 0)
+            continue;
+
+        num_cpe++;
+        num_cards++;
+    }
+    if (line)
+        free(line);
+    fclose(fp);
+    ALOGV("sndmonitor registerer num_cards %d", num_cards);
+    sndmonitor.num_cards = num_cards;
+    return num_cards ? 0 : -1;
+}
+
+static void free_sndcards()
+{
+    while (!list_empty(&sndmonitor.cards)) {
+        struct listnode *n = list_head(&sndmonitor.cards);
+        sndcard_t *s = node_to_item(n, sndcard_t, node);
+        list_remove(n);
+        close(s->fd);
+        free(s);
+    }
+}
+
+#ifdef MONITOR_DEVICE_EVENTS
+static int add_new_dev_event(char *d_name, int fd)
+{
+    dev_event_t *d = (dev_event_t *)calloc(sizeof(dev_event_t), 1);
+
+    if (!d)
+        return -1;
+
+    d->dev = strdup(d_name);
+    d->fd = fd;
+    list_add_tail(&sndmonitor.dev_events, &d->node);
+    return 0;
+}
+
+static int enum_dev_events()
+{
+    const char *events_dir = "/sys/class/switch/";
+    DIR *dp;
+    struct dirent *in_file;
+    int fd;
+    char path[128] = {0};
+    unsigned int num_dev_events = 0;
+
+    if ((dp = opendir(events_dir)) == NULL) {
+        ALOGE("Cannot open switch directory %s err %s",
+              events_dir, strerror(errno));
+        return -1;
+    }
+
+    while ((in_file = readdir(dp)) != NULL) {
+        if (!strstr(in_file->d_name, "qc_"))
+            continue;
+
+        snprintf(path, sizeof(path), "%s/%s/state",
+                 events_dir, in_file->d_name);
+
+        ALOGV("Opening audio dev event state : %s ", path);
+        fd = open(path, O_RDONLY);
+        if (fd == -1) {
+            ALOGE("Open %s failed : %s", path, strerror(errno));
+        } else {
+            if (!add_new_dev_event(in_file->d_name, fd))
+                num_dev_events++;
+        }
+    }
+    closedir(dp);
+    sndmonitor.num_dev_events = num_dev_events;
+    return num_dev_events ? 0 : -1;
+}
+#endif
+
+static void free_dev_events()
+{
+    while (!list_empty(&sndmonitor.dev_events)) {
+        struct listnode *n = list_head(&sndmonitor.dev_events);
+        dev_event_t *d = node_to_item(n, dev_event_t, node);
+        list_remove(n);
+        close(d->fd);
+        free(d->dev);
+        free(d);
+    }
+}
+
+static int notify(const struct str_parms *params)
+{
+    if (!params)
+        return -1;
+
+    char *str = str_parms_to_str((struct str_parms *)params);
+
+    if (!str)
+        return -1;
+
+    if (sndmonitor.notify)
+        sndmonitor.notify(sndmonitor.target, str);
+
+    ALOGV("%s", str);
+    free(str);
+    return 0;
+}
+
+int on_dev_event(dev_event_t *dev_event)
+{
+    char state_buf[2];
+    if (read(dev_event->fd, state_buf, 1) <= 0)
+        return -1;
+
+    lseek(dev_event->fd, 0, SEEK_SET);
+    state_buf[1]='\0';
+    if (atoi(state_buf) == dev_event->status)
+        return 0;
+
+    dev_event->status = atoi(state_buf);
+
+    struct str_parms *params = str_parms_create();
+
+    if (!params)
+        return -1;
+
+    char val[32] = {0};
+    snprintf(val, sizeof(val), "%s,%s", dev_event->dev,
+             dev_event->status ? "ON" : "OFF");
+
+    if (str_parms_add_str(params, AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE, val) < 0)
+        return -1;
+
+    int ret = notify(params);
+    str_parms_destroy(params);
+    return ret;
+}
+
+bool on_sndcard_state_update(sndcard_t *s)
+{
+    char rd_buf[9]={0};
+    card_status_t status;
+
+    if (read(s->fd, rd_buf, 8) <= 0)
+        return -1;
+
+    rd_buf[8] = '\0';
+    lseek(s->fd, 0, SEEK_SET);
+
+    ALOGV("card num %d, new state %s", s->card, rd_buf);
+
+    bool is_cpe = (s->card >= CPE_MAGIC_NUM);
+    if (strstr(rd_buf, "OFFLINE"))
+        status = CARD_STATUS_OFFLINE;
+    else if (strstr(rd_buf, "ONLINE"))
+        status = CARD_STATUS_ONLINE;
+    else {
+        ALOGE("unknown state");
+        return 0;
+    }
+
+    if (status == s->status) // no change
+        return 0;
+
+    s->status = status;
+
+    struct str_parms *params = str_parms_create();
+
+    if (!params)
+        return -1;
+
+    char val[32] = {0};
+    // cpe actual card num is (card - MAGIC_NUM). so subtract accordingly
+    snprintf(val, sizeof(val), "%d,%s", s->card - (is_cpe ? CPE_MAGIC_NUM : 0),
+                 status == CARD_STATUS_ONLINE ? "ONLINE" : "OFFLINE");
+
+    if (str_parms_add_str(params, is_cpe ? "CPE_STATUS" : "SND_CARD_STATUS",
+                          val) < 0)
+        return -1;
+
+    int ret = notify(params);
+    str_parms_destroy(params);
+    return ret;
+}
+
+void *monitor_thread_loop(void *args __unused)
+{
+    ALOGV("Start threadLoop()");
+    unsigned int num_poll_fds = sndmonitor.num_cards +
+                                sndmonitor.num_dev_events + 1/*pipe*/;
+    struct pollfd *pfd = (struct pollfd *)calloc(sizeof(struct pollfd),
+                                                  num_poll_fds);
+    if (!pfd)
+        return NULL;
+
+    pfd[0].fd = sndmonitor.intpipe[0];
+    pfd[0].events = POLLPRI|POLLIN;
+
+    int i = 1;
+    struct listnode *node;
+    list_for_each(node, &sndmonitor.cards) {
+        sndcard_t *s = node_to_item(node, sndcard_t, node);
+        pfd[i].fd = s->fd;
+        pfd[i].events = POLLPRI;
+        ++i;
+    }
+
+    list_for_each(node, &sndmonitor.dev_events) {
+        dev_event_t *d = node_to_item(node, dev_event_t, node);
+        pfd[i].fd = d->fd;
+        pfd[i].events = POLLPRI;
+        ++i;
+    }
+
+    while (1) {
+        if (poll(pfd, num_poll_fds, -1) < 0) {
+            int errno_ = errno;
+            ALOGE("poll() failed w/ err %s", strerror(errno_));
+            switch (errno_) {
+                case EINTR:
+                case ENOMEM:
+                    sleep(2);
+                    continue;
+                default:
+                    /* above errors can be caused due to current system
+                       state .. any other error is not expected */
+                    LOG_ALWAYS_FATAL("unxpected poll() system call failure");
+                    break;
+            }
+        }
+        ALOGV("out of poll()");
+
+#define READY_TO_READ(p) ((p)->revents & (POLLIN|POLLPRI))
+#define ERROR_IN_FD(p) ((p)->revents & (POLLERR|POLLHUP|POLLNVAL))
+
+        // check if requested to exit
+        if (READY_TO_READ(&pfd[0])) {
+            char buf[2]={0};
+            read(pfd[0].fd, buf, 1);
+            if (!strcmp(buf, "Q"))
+                break;
+        } else if (ERROR_IN_FD(&pfd[0])) {
+            // do not consider for poll again
+            // POLLERR - can this happen?
+            // POLLHUP - adev must not close pipe
+            // POLLNVAL - fd is valid
+            LOG_ALWAYS_FATAL("unxpected error in pipe poll fd 0x%x",
+                             pfd[0].revents);
+            // FIXME: If not fatal, then need some logic to close
+            // these fds on error
+            pfd[0].fd *= -1;
+        }
+
+        i = 1;
+        list_for_each(node, &sndmonitor.cards) {
+            sndcard_t *s = node_to_item(node, sndcard_t, node);
+            if (READY_TO_READ(&pfd[i]))
+                on_sndcard_state_update(s);
+            else if (ERROR_IN_FD(&pfd[i])) {
+                // do not consider for poll again
+                // POLLERR - can this happen as we are reading from a fs?
+                // POLLHUP - not valid for cardN/state
+                // POLLNVAL - fd is valid
+                LOG_ALWAYS_FATAL("unxpected error in card poll fd 0x%x",
+                                 pfd[i].revents);
+                // FIXME: If not fatal, then need some logic to close
+                // these fds on error
+                pfd[i].fd *= -1;
+            }
+            ++i;
+        }
+
+        list_for_each(node, &sndmonitor.dev_events) {
+            dev_event_t *d = node_to_item(node, dev_event_t, node);
+            if (READY_TO_READ(&pfd[i]))
+                on_dev_event(d);
+            else if (ERROR_IN_FD(&pfd[i])) {
+                // do not consider for poll again
+                // POLLERR - can this happen as we are reading from a fs?
+                // POLLHUP - not valid for switch/state
+                // POLLNVAL - fd is valid
+                LOG_ALWAYS_FATAL("unxpected error in dev poll fd 0x%x",
+                                 pfd[i].revents);
+                // FIXME: If not fatal, then need some logic to close
+                // these fds on error
+                pfd[i].fd *= -1;
+            }
+            ++i;
+        }
+    }
+
+    return NULL;
+}
+
+// ---- listener static APIs ---- //
+static int hashfn(void *key)
+{
+    return (int)key;
+}
+
+static bool hasheq(void *key1, void *key2)
+{
+    return key1 == key2;
+}
+
+static bool snd_cb(void *key, void *value, void *context)
+{
+    snd_mon_cb cb = (snd_mon_cb)value;
+    cb(key, context);
+    return true;
+}
+
+static void snd_mon_update(const void *target __unused, const char *msg)
+{
+    // target can be used to check if this message is intended for the
+    // recipient or not. (using some statically saved state)
+
+    struct str_parms *parms = str_parms_create_str(msg);
+
+    if (!parms)
+        return;
+
+    hashmapLock(sndmonitor.listeners);
+    hashmapForEach(sndmonitor.listeners, snd_cb, parms);
+    hashmapUnlock(sndmonitor.listeners);
+
+    str_parms_destroy(parms);
+}
+
+static int listeners_init()
+{
+    sndmonitor.listeners = hashmapCreate(INIT_MAP_SIZE, hashfn, hasheq);
+    if (!sndmonitor.listeners)
+        return -1;
+    return 0;
+}
+
+static int listeners_deinit()
+{
+    // XXX TBD
+    return -1;
+}
+
+static int add_listener(void *stream, snd_mon_cb cb)
+{
+    Hashmap *map = sndmonitor.listeners;
+    hashmapLock(map);
+    hashmapPut(map, stream, cb);
+    hashmapUnlock(map);
+    return 0;
+}
+
+static int del_listener(void * stream)
+{
+    Hashmap *map = sndmonitor.listeners;
+    hashmapLock(map);
+    hashmapRemove(map, stream);
+    hashmapUnlock(map);
+    return 0;
+}
+
+// --- public APIs --- //
+
+int audio_extn_snd_mon_deinit()
+{
+    if (!sndmonitor.initcheck)
+        return -1;
+
+    write(sndmonitor.intpipe[1], "Q", 1);
+    pthread_join(sndmonitor.monitor_thread, (void **) NULL);
+    listeners_deinit();
+    free_sndcards();
+    free_dev_events();
+    sndmonitor.initcheck = 0;
+    return 0;
+}
+
+int audio_extn_snd_mon_init()
+{
+    sndmonitor.notify = snd_mon_update;
+    sndmonitor.target = NULL; // unused for now
+    list_init(&sndmonitor.cards);
+    list_init(&sndmonitor.dev_events);
+    sndmonitor.initcheck = false;
+
+    if (pipe(sndmonitor.intpipe) < 0)
+        return -ENODEV;
+
+    if (enum_sndcards() < 0)
+        return -ENODEV;
+
+    if (listeners_init() < 0)
+        return -ENODEV;
+
+#ifdef MONITOR_DEVICE_EVENTS
+    enum_dev_events(); // failure here isn't fatal
+#endif
+
+    int ret = pthread_create(&sndmonitor.monitor_thread,
+                             (const pthread_attr_t *) NULL,
+                             monitor_thread_loop, NULL);
+
+    if (ret) {
+        free_sndcards();
+        free_dev_events();
+        close(sndmonitor.intpipe[0]);
+        close(sndmonitor.intpipe[1]);
+        return -ENODEV;
+    }
+    sndmonitor.initcheck = true;
+    return 0;
+}
+
+int audio_extn_snd_mon_register_listener(void *stream, snd_mon_cb cb)
+{
+    if (!sndmonitor.initcheck) {
+        ALOGW("sndmonitor initcheck failed, cannot register");
+        return -1;
+    }
+
+    return add_listener(stream, cb);
+}
+
+int audio_extn_snd_mon_unregister_listener(void *stream)
+{
+    if (!sndmonitor.initcheck) {
+        ALOGW("sndmonitor initcheck failed, cannot deregister");
+        return -1;
+    }
+
+    ALOGV("deregister listener for stream %p ", stream);
+    return del_listener(stream);
+}
diff --git a/hal/audio_extn/soundtrigger.c b/hal/audio_extn/soundtrigger.c
index 7e37efc..6142e86 100644
--- a/hal/audio_extn/soundtrigger.c
+++ b/hal/audio_extn/soundtrigger.c
@@ -98,9 +98,9 @@
             status = -ENOMEM;
             break;
         }
-        memcpy(&st_ses_info->st_ses, &config->st_ses, sizeof (config->st_ses));
-        ALOGV("%s: add capture_handle %d pcm %p", __func__,
-              st_ses_info->st_ses.capture_handle, st_ses_info->st_ses.pcm);
+        memcpy(&st_ses_info->st_ses, &config->st_ses, sizeof (struct sound_trigger_session_info));
+        ALOGV("%s: add capture_handle %d st session opaque ptr %p", __func__,
+              st_ses_info->st_ses.capture_handle, st_ses_info->st_ses.p_ses);
         list_add_tail(&st_dev->st_ses_list, &st_ses_info->list);
         break;
 
@@ -112,12 +112,12 @@
         }
         st_ses_info = get_sound_trigger_info(config->st_ses.capture_handle);
         if (!st_ses_info) {
-            ALOGE("%s: pcm %p not in the list!", __func__, config->st_ses.pcm);
+            ALOGE("%s: st session opaque ptr %p not in the list!", __func__, config->st_ses.p_ses);
             status = -EINVAL;
             break;
         }
-        ALOGV("%s: remove capture_handle %d pcm %p", __func__,
-              st_ses_info->st_ses.capture_handle, st_ses_info->st_ses.pcm);
+        ALOGV("%s: remove capture_handle %d st session opaque ptr %p", __func__,
+              st_ses_info->st_ses.capture_handle, st_ses_info->st_ses.p_ses);
         list_remove(&st_ses_info->list);
         free(st_ses_info);
         break;
@@ -181,7 +181,7 @@
     pthread_mutex_unlock(&st_dev->lock);
     if (st_ses_info) {
         event.u.ses_info = st_ses_info->st_ses;
-        ALOGV("%s: AUDIO_EVENT_STOP_LAB pcm %p", __func__, st_ses_info->st_ses.pcm);
+        ALOGV("%s: AUDIO_EVENT_STOP_LAB st sess %p", __func__, st_ses_info->st_ses.p_ses);
         st_dev->st_callback(AUDIO_EVENT_STOP_LAB, &event);
         in->is_st_session_active = false;
     }
@@ -201,7 +201,6 @@
     list_for_each(node, &st_dev->st_ses_list) {
         st_ses_info = node_to_item(node, struct sound_trigger_info , list);
         if (st_ses_info->st_ses.capture_handle == in->capture_handle) {
-            in->pcm = st_ses_info->st_ses.pcm;
             in->config = st_ses_info->st_ses.config;
             in->channel_mask = audio_channel_in_mask_from_count(in->config.channels);
             in->is_st_session = true;
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index e3f1b6c..26c43b4 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -90,9 +90,7 @@
 #ifdef INCALL_MUSIC_ENABLED
     STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_INCALL_MUSIC),
 #endif
-#ifdef HDMI_PASSTHROUGH_ENABLED
     STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH),
-#endif
 };
 
 const struct string_to_enum s_format_name_to_enum_table[] = {
@@ -133,6 +131,7 @@
     STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_LC),
     STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_HE_V1),
     STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_HE_V2),
+    STRING_TO_ENUM(AUDIO_FORMAT_DSD),
 #endif
 };
 
@@ -515,6 +514,21 @@
                                __func__, sample_rate);
         }
     }
+
+    /* Set sampling rate to 176.4 for DSD64
+     * and 352.8Khz for DSD128.
+     * Set Bit Width to 16. output will be 16 bit
+     * post DoP in ASM.
+     */
+    if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH) &&
+        (format == AUDIO_FORMAT_DSD)) {
+        bit_width = 16;
+        if (sample_rate == INPUT_SAMPLING_RATE_DSD64)
+            sample_rate = OUTPUT_SAMPLING_RATE_DSD64;
+        else if (sample_rate == INPUT_SAMPLING_RATE_DSD128)
+            sample_rate = OUTPUT_SAMPLING_RATE_DSD128;
+    }
+
     ALOGV("%s: flags: %x, format: %x sample_rate %d",
            __func__, flags, format, sample_rate);
     list_for_each(node_i, streams_output_cfg_list) {
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 8660b5a..43c83de 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -36,6 +36,7 @@
  */
 
 #define LOG_TAG "audio_hw_primary"
+#define ATRACE_TAG (ATRACE_TAG_AUDIO|ATRACE_TAG_HAL)
 /*#define LOG_NDEBUG 0*/
 /*#define VERY_VERY_VERBOSE_LOGGING*/
 #ifdef VERY_VERY_VERBOSE_LOGGING
@@ -55,6 +56,7 @@
 #include <sys/prctl.h>
 
 #include <cutils/log.h>
+#include <cutils/trace.h>
 #include <cutils/str_parms.h>
 #include <cutils/properties.h>
 #include <cutils/atomic.h>
@@ -80,6 +82,7 @@
 /* ToDo: Check and update a proper value in msec */
 #define COMPRESS_OFFLOAD_PLAYBACK_LATENCY 50
 #define COMPRESS_PLAYBACK_VOLUME_MAX 0x2000
+#define DSD_VOLUME_MIN_DB (-110)
 
 #define PROXY_OPEN_RETRY_COUNT           100
 #define PROXY_OPEN_WAIT_TIME             20
@@ -92,6 +95,8 @@
 #define PCM_CONFIG_AUDIO_PLAYBACK_PRIMARY pcm_config_deep_buffer
 #endif
 
+#define ULL_PERIOD_SIZE (DEFAULT_OUTPUT_SAMPLING_RATE/1000)
+
 static unsigned int configured_low_latency_capture_period_size =
         LOW_LATENCY_CAPTURE_PERIOD_SIZE;
 
@@ -117,6 +122,20 @@
     .avail_min = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
 };
 
+static int af_period_multiplier = 4;
+struct pcm_config pcm_config_rt = {
+    .channels = 2,
+    .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
+    .period_size = ULL_PERIOD_SIZE, //1 ms
+    .period_count = 512, //=> buffer size is 512ms
+    .format = PCM_FORMAT_S16_LE,
+    .start_threshold = ULL_PERIOD_SIZE*8, //8ms
+    .stop_threshold = INT_MAX,
+    .silence_threshold = 0,
+    .silence_size = 0,
+    .avail_min = ULL_PERIOD_SIZE, //1 ms
+};
+
 struct pcm_config pcm_config_hdmi_multi = {
     .channels = HDMI_MULTI_DEFAULT_CHANNEL_COUNT, /* changed when the stream is opened */
     .rate = DEFAULT_OUTPUT_SAMPLING_RATE, /* changed when the stream is opened */
@@ -134,6 +153,19 @@
     .format = PCM_FORMAT_S16_LE,
 };
 
+struct pcm_config pcm_config_audio_capture_rt = {
+    .channels = 2,
+    .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
+    .period_size = ULL_PERIOD_SIZE,
+    .period_count = 512,
+    .format = PCM_FORMAT_S16_LE,
+    .start_threshold = 0,
+    .stop_threshold = INT_MAX,
+    .silence_threshold = 0,
+    .silence_size = 0,
+    .avail_min = ULL_PERIOD_SIZE, //1 ms
+};
+
 #define AFE_PROXY_CHANNEL_COUNT 2
 #define AFE_PROXY_SAMPLING_RATE 48000
 
@@ -284,6 +316,116 @@
 //cache last MBDRC cal step level
 static int last_known_cal_step = -1 ;
 
+static bool may_use_noirq_mode(struct audio_device *adev, audio_usecase_t uc_id,
+                               int flags __unused)
+{
+    int dir = 0;
+    switch (uc_id) {
+        case USECASE_AUDIO_RECORD_LOW_LATENCY:
+            dir = 1;
+        case USECASE_AUDIO_PLAYBACK_ULL:
+            break;
+        default:
+            return false;
+    }
+
+    int dev_id = platform_get_pcm_device_id(uc_id, dir == 0 ?
+                                            PCM_PLAYBACK : PCM_CAPTURE);
+    if (adev->adm_is_noirq_avail)
+        return adev->adm_is_noirq_avail(adev->adm_data,
+                                        adev->snd_card, dev_id, dir);
+    return false;
+}
+
+static void register_out_stream(struct stream_out *out)
+{
+    struct audio_device *adev = out->dev;
+    if (is_offload_usecase(out->usecase) ||
+        !adev->adm_register_output_stream)
+        return;
+
+    // register stream first for backward compatibility
+    adev->adm_register_output_stream(adev->adm_data,
+                                     out->handle,
+                                     out->flags);
+
+    if (!adev->adm_set_config)
+        return;
+
+    if (out->realtime)
+        adev->adm_set_config(adev->adm_data,
+                             out->handle,
+                             out->pcm, &out->config);
+}
+
+static void register_in_stream(struct stream_in *in)
+{
+    struct audio_device *adev = in->dev;
+    if (!adev->adm_register_input_stream)
+        return;
+
+    adev->adm_register_input_stream(adev->adm_data,
+                                    in->capture_handle,
+                                    in->flags);
+
+    if (!adev->adm_set_config)
+        return;
+
+    if (in->realtime)
+        adev->adm_set_config(adev->adm_data,
+                             in->capture_handle,
+                             in->pcm,
+                             &in->config);
+}
+
+static void request_out_focus(struct stream_out *out, long ns)
+{
+    struct audio_device *adev = out->dev;
+
+    if (out->routing_change) {
+        out->routing_change = false;
+        // must be checked for backward compatibility
+        if (adev->adm_on_routing_change)
+            adev->adm_on_routing_change(adev->adm_data, out->handle);
+    }
+
+    if (adev->adm_request_focus_v2)
+        adev->adm_request_focus_v2(adev->adm_data, out->handle, ns);
+    else if (adev->adm_request_focus)
+        adev->adm_request_focus(adev->adm_data, out->handle);
+}
+
+static void request_in_focus(struct stream_in *in, long ns)
+{
+    struct audio_device *adev = in->dev;
+
+    if (in->routing_change) {
+        in->routing_change = false;
+        if (adev->adm_on_routing_change)
+            adev->adm_on_routing_change(adev->adm_data, in->capture_handle);
+    }
+
+    if (adev->adm_request_focus_v2)
+        adev->adm_request_focus_v2(adev->adm_data, in->capture_handle, ns);
+    else if (adev->adm_request_focus)
+        adev->adm_request_focus(adev->adm_data, in->capture_handle);
+}
+
+static void release_out_focus(struct stream_out *out)
+{
+    struct audio_device *adev = out->dev;
+
+    if (adev->adm_abandon_focus)
+        adev->adm_abandon_focus(adev->adm_data, out->handle);
+}
+
+static void release_in_focus(struct stream_in *in)
+{
+    struct audio_device *adev = in->dev;
+    if (adev->adm_abandon_focus)
+        adev->adm_abandon_focus(adev->adm_data, in->capture_handle);
+}
+
 __attribute__ ((visibility ("default")))
 bool audio_hw_send_gain_dep_calibration(int level) {
     bool ret_val = false;
@@ -360,6 +502,7 @@
         format == AUDIO_FORMAT_FLAC ||
         format == AUDIO_FORMAT_ALAC ||
         format == AUDIO_FORMAT_APE ||
+        format == AUDIO_FORMAT_DSD ||
         format == AUDIO_FORMAT_VORBIS ||
         format == AUDIO_FORMAT_WMA ||
         format == AUDIO_FORMAT_WMA_PRO)
@@ -368,6 +511,12 @@
     return false;
 }
 
+static inline bool is_mmap_usecase(audio_usecase_t uc_id)
+{
+    return (uc_id == USECASE_AUDIO_RECORD_AFE_PROXY) ||
+           (uc_id == USECASE_AUDIO_PLAYBACK_AFE_PROXY);
+}
+
 static int get_snd_codec_id(audio_format_t format)
 {
     int id = 0;
@@ -394,6 +543,9 @@
     case AUDIO_FORMAT_APE:
         id = SND_AUDIOCODEC_APE;
         break;
+    case AUDIO_FORMAT_DSD:
+        id = SND_AUDIOCODEC_DSD;
+        break;
     case AUDIO_FORMAT_VORBIS:
         id = SND_AUDIOCODEC_VORBIS;
         break;
@@ -469,6 +621,36 @@
     return 0;
 }
 
+/*
+ * Enable ASRC mode if native or DSD stream is active.
+ */
+static void audio_check_and_set_asrc_mode(struct audio_device *adev, snd_device_t snd_device)
+{
+    if (SND_DEVICE_OUT_HEADPHONES == snd_device &&
+       !adev->asrc_mode_enabled) {
+        struct listnode *node = NULL;
+        struct audio_usecase *uc = NULL;
+        struct stream_out *curr_out = NULL;
+
+        list_for_each(node, &adev->usecase_list) {
+            uc = node_to_item(node, struct audio_usecase, list);
+            curr_out = (struct stream_out*) uc->stream.out;
+
+            if (curr_out && PCM_PLAYBACK == uc->type) {
+                if((platform_get_backend_index(uc->out_snd_device) == HEADPHONE_44_1_BACKEND) ||
+                      (platform_get_backend_index(uc->out_snd_device) == DSD_NATIVE_BACKEND)) {
+                    ALOGD("%s:DSD or native stream detected enabling asrcmode in hardware",
+                          __func__);
+                    audio_route_apply_and_update_path(adev->audio_route,
+                                                  "asrc-mode");
+                    adev->asrc_mode_enabled = true;
+                    break;
+                }
+            }
+        }
+    }
+}
+
 int pcm_ioctl(struct pcm *pcm, int request, ...)
 {
     va_list ap;
@@ -568,7 +750,6 @@
     if (audio_extn_spkr_prot_is_enabled())
          audio_extn_spkr_prot_calib_cancel(adev);
 
-
     if (platform_can_enable_spkr_prot_on_device(snd_device) &&
          audio_extn_spkr_prot_is_enabled()) {
        if (platform_get_spkr_prot_acdb_id(snd_device) < 0) {
@@ -588,6 +769,13 @@
         }
     } else {
         ALOGD("%s: snd_device(%d: %s)", __func__, snd_device, device_name);
+
+       if ((SND_DEVICE_OUT_BT_A2DP == snd_device) &&
+           (audio_extn_a2dp_start_playback() < 0)) {
+           ALOGE(" fail to configure A2dp control path ");
+           return -EINVAL;
+       }
+
         /* due to the possibility of calibration overwrite between listen
             and audio, notify listen hal before audio calibration is sent */
         audio_extn_sound_trigger_update_device_status(snd_device,
@@ -613,7 +801,8 @@
             audio_route_apply_and_update_path(adev->audio_route,
                                               "true-native-mode");
             adev->native_playback_enabled = true;
-        }
+        } else
+            audio_check_and_set_asrc_mode(adev, snd_device);
     }
     return 0;
 }
@@ -644,6 +833,7 @@
 
     if (adev->snd_dev_ref_cnt[snd_device] == 0) {
         ALOGD("%s: snd_device(%d: %s)", __func__, snd_device, device_name);
+
         if (platform_can_enable_spkr_prot_on_device(snd_device) &&
              audio_extn_spkr_prot_is_enabled()) {
             audio_extn_spkr_prot_stop_processing(snd_device);
@@ -656,6 +846,9 @@
             audio_route_reset_and_update_path(adev->audio_route, device_name);
         }
 
+        if (SND_DEVICE_OUT_BT_A2DP == snd_device)
+            audio_extn_a2dp_stop_playback();
+
         if (snd_device == SND_DEVICE_OUT_HDMI)
             adev->is_channel_status_set = false;
         else if (SND_DEVICE_OUT_HEADPHONES == snd_device &&
@@ -665,6 +858,11 @@
             audio_route_reset_and_update_path(adev->audio_route,
                                               "true-native-mode");
             adev->native_playback_enabled = false;
+        } else if (SND_DEVICE_OUT_HEADPHONES == snd_device &&
+                 adev->asrc_mode_enabled) {
+            ALOGD("%s: %d: disabling asrc mode in hardware", __func__, __LINE__);
+            audio_route_reset_and_update_path(adev->audio_route, "asrc-mode");
+            adev->asrc_mode_enabled = false;
         }
 
         audio_extn_dev_arbi_release(snd_device);
@@ -685,7 +883,7 @@
     struct audio_usecase *usecase;
     bool switch_device[AUDIO_USECASE_MAX];
     int i, num_uc_to_switch = 0;
-
+    bool force_restart_session = false;
     /*
      * This function is to make sure that all the usecases that are active on
      * the hardware codec backend are always routed to any one device that is
@@ -705,7 +903,15 @@
      */
     bool force_routing = platform_check_and_set_codec_backend_cfg(adev, uc_info,
                          snd_device);
-
+    /* For a2dp device reconfigure all active sessions
+     * with new AFE encoder format based on a2dp state
+     */
+    if ((SND_DEVICE_OUT_BT_A2DP == snd_device ||
+         SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP == snd_device) &&
+         audio_extn_a2dp_is_force_device_switch()) {
+         force_routing = true;
+         force_restart_session = true;
+    }
     ALOGD("%s:becf: force routing %d", __func__, force_routing);
 
     /* Disable all the usecases on the shared backend other than the
@@ -724,9 +930,13 @@
               platform_check_backends_match(snd_device, usecase->out_snd_device));
         if (usecase->type != PCM_CAPTURE &&
             usecase != uc_info &&
-            (usecase->out_snd_device != snd_device || force_routing)  &&
-            usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND &&
-            platform_check_backends_match(snd_device, usecase->out_snd_device)) {
+            (usecase->out_snd_device != snd_device || force_routing) &&
+            ((usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) ||
+             (usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) ||
+             (force_restart_session)) &&
+            (platform_check_backends_match(snd_device, usecase->out_snd_device)||
+             (platform_check_codec_asrc_support(adev->platform) && !adev->asrc_mode_enabled &&
+              platform_check_if_backend_has_to_be_disabled(snd_device,usecase->out_snd_device)))) {
                 ALOGD("%s:becf: check_usecases (%s) is active on (%s) - disabling ..",
                     __func__, use_case_table[usecase->id],
                       platform_get_snd_device_name(usecase->out_snd_device));
@@ -997,6 +1207,28 @@
     return active;
 }
 
+/*
+ * if native DSD playback active
+ */
+bool audio_is_dsd_native_stream_active(struct audio_device *adev)
+{
+    bool active = false;
+    struct listnode *node = NULL;
+    struct audio_usecase *uc = NULL;
+    struct stream_out *curr_out = NULL;
+
+    list_for_each(node, &adev->usecase_list) {
+        uc = node_to_item(node, struct audio_usecase, list);
+        curr_out = (struct stream_out*) uc->stream.out;
+
+        if (curr_out && PCM_PLAYBACK == uc->type &&
+               (DSD_NATIVE_BACKEND == platform_get_backend_index(uc->out_snd_device))) {
+            active = true;
+            ALOGV("%s:DSD playback is active", __func__);
+        }
+    }
+    return active;
+}
 
 static bool force_device_switch(struct audio_usecase *usecase)
 {
@@ -1016,6 +1248,14 @@
         }
     }
 
+    // Force all a2dp output devices to reconfigure for proper AFE encode format
+    if((usecase->stream.out) &&
+       (usecase->stream.out->devices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) &&
+       audio_extn_a2dp_is_force_device_switch()) {
+         ALOGD("Force a2dp device switch to update new encoder config");
+         ret = true;
+     }
+
     return ret;
 }
 
@@ -1060,6 +1300,8 @@
                                                get_usecase_id_from_usecase_type(adev, VOICE_CALL));
             if ((vc_usecase) && (((vc_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) &&
                                  (usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND)) ||
+                                 ((vc_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) &&
+                                 (usecase->devices & AUDIO_DEVICE_IN_ALL_CODEC_BACKEND)) ||
                                 (usecase->devices == AUDIO_DEVICE_IN_VOICE_CALL))) {
                 in_snd_device = vc_usecase->in_snd_device;
                 out_snd_device = vc_usecase->out_snd_device;
@@ -1067,7 +1309,8 @@
         } else if (voice_extn_compress_voip_is_active(adev)) {
             voip_usecase = get_usecase_from_list(adev, USECASE_COMPRESS_VOIP_CALL);
             if ((voip_usecase) && ((voip_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) &&
-                (usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) &&
+                ((usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) ||
+                  ((usecase->devices & ~AUDIO_DEVICE_BIT_IN) & AUDIO_DEVICE_IN_ALL_CODEC_BACKEND)) &&
                  (voip_usecase->stream.out != adev->primary_output))) {
                     in_snd_device = voip_usecase->in_snd_device;
                     out_snd_device = voip_usecase->out_snd_device;
@@ -1182,10 +1425,6 @@
                                                         out_snd_device,
                                                         in_snd_device);
         enable_audio_route_for_voice_usecases(adev, usecase);
-        /* Enable sidetone only if voice/voip call already exists */
-        if (voice_is_call_state_active(adev) ||
-            voice_extn_compress_voip_is_started(adev))
-            voice_set_sidetone(adev, out_snd_device, true);
     }
 
     usecase->in_snd_device = in_snd_device;
@@ -1206,6 +1445,13 @@
 
     enable_audio_route(adev, usecase);
 
+    if (usecase->type == VOICE_CALL || usecase->type == VOIP_CALL) {
+        /* Enable sidetone only if other voice/voip call already exists */
+        if (voice_is_call_state_active(adev) ||
+            voice_extn_compress_voip_is_started(adev))
+            voice_set_sidetone(adev, out_snd_device, true);
+    }
+
     /* Applicable only on the targets that has external modem.
      * Enable device command should be sent to modem only after
      * enabling voice call mixer controls
@@ -1324,6 +1570,8 @@
     if (in->usecase == USECASE_AUDIO_RECORD_AFE_PROXY) {
         flags |= PCM_MMAP | PCM_NOIRQ;
         pcm_open_retry_count = PROXY_OPEN_RETRY_COUNT;
+    } else if (in->realtime) {
+        flags |= PCM_MMAP | PCM_NOIRQ;
     }
 
     while (1) {
@@ -1354,6 +1602,13 @@
         goto error_open;
     }
 
+    register_in_stream(in);
+    if (in->realtime) {
+        ret = pcm_start(in->pcm);
+        if (ret < 0)
+            goto error_open;
+    }
+
     audio_extn_perf_lock_release(&adev->perf_lock_handle);
     ALOGD("%s: exit", __func__);
 
@@ -1614,193 +1869,6 @@
     return 0;
 }
 
-static bool allow_hdmi_channel_config(struct audio_device *adev,
-                                      bool enable_passthru)
-{
-    struct listnode *node;
-    struct audio_usecase *usecase;
-    bool ret = true;
-
-    if (enable_passthru && !audio_extn_passthru_is_enabled()) {
-        ret = false;
-        goto exit;
-    }
-
-    if (audio_extn_passthru_is_active()) {
-        ALOGI("%s: Compress audio passthrough is active,"
-              "no HDMI config change allowed", __func__);
-        ret = false;
-        goto exit;
-    }
-
-    list_for_each(node, &adev->usecase_list) {
-        usecase = node_to_item(node, struct audio_usecase, list);
-        if (usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
-            /*
-             * If voice call is already existing, do not proceed further to avoid
-             * disabling/enabling both RX and TX devices, CSD calls, etc.
-             * Once the voice call done, the HDMI channels can be configured to
-             * max channels of remaining use cases.
-             */
-            if (usecase->id == USECASE_VOICE_CALL) {
-                ALOGV("%s: voice call is active, no change in HDMI channels",
-                      __func__);
-                ret = false;
-                break;
-            } else if (usecase->id == USECASE_AUDIO_PLAYBACK_MULTI_CH) {
-                if (!enable_passthru) {
-                    ALOGV("%s: multi channel playback is active, "
-                          "no change in HDMI channels", __func__);
-                    ret = false;
-                    break;
-                }
-            } else if (is_offload_usecase(usecase->id) &&
-                       audio_channel_count_from_out_mask(usecase->stream.out->channel_mask) > 2) {
-                if (!enable_passthru) {
-                    ALOGD("%s:multi-channel(%x) compress offload playback is active"
-                        ", no change in HDMI channels", __func__,
-                        usecase->stream.out->channel_mask);
-                    ret = false;
-                    break;
-                }
-            }
-        }
-    }
-    ALOGV("allow hdmi config %d", ret);
-exit:
-    return ret;
-}
-
-static int check_and_set_hdmi_config(struct audio_device *adev,
-                                     uint32_t channels,
-                                     uint32_t sample_rate,
-                                     audio_format_t format,
-                                     bool enable_passthru)
-{
-    struct listnode *node;
-    struct audio_usecase *usecase;
-    int32_t factor = 1;
-    bool config = false;
-
-    ALOGV("%s channels %d sample_rate %d format:%x enable_passthru:%d",
-         __func__, channels, sample_rate, format, enable_passthru);
-
-    if (channels != adev->cur_hdmi_channels) {
-        ALOGV("channel does not match current hdmi channels");
-        config = true;
-    }
-
-    if (sample_rate != adev->cur_hdmi_sample_rate) {
-        ALOGV("sample rate does not match current hdmi sample rate");
-        config = true;
-    }
-
-    if (format != adev->cur_hdmi_format) {
-        ALOGV("format does not match current hdmi format");
-        config = true;
-    }
-
-    /* TBD - add check for bit width */
-    if (!config) {
-        ALOGV("No need to config hdmi");
-        return 0;
-    }
-
-    if (enable_passthru &&
-        (format == AUDIO_FORMAT_E_AC3)) {
-        ALOGV("factor 4 for E_AC3 passthru");
-        factor = 4;
-    }
-
-    platform_set_hdmi_config(adev->platform, channels, factor * sample_rate,
-                             enable_passthru);
-    adev->cur_hdmi_channels = channels;
-    adev->cur_hdmi_format = format;
-    adev->cur_hdmi_sample_rate = sample_rate;
-
-    /*
-     * Deroute all the playback streams routed to HDMI so that
-     * the back end is deactivated. Note that backend will not
-     * be deactivated if any one stream is connected to it.
-     */
-    list_for_each(node, &adev->usecase_list) {
-        usecase = node_to_item(node, struct audio_usecase, list);
-        if (usecase->type == PCM_PLAYBACK &&
-                usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
-            disable_audio_route(adev, usecase);
-        }
-    }
-
-    bool was_active = audio_extn_keep_alive_is_active();
-    if (was_active)
-        audio_extn_keep_alive_stop();
-
-    /*
-     * Enable all the streams disabled above. Now the HDMI backend
-     * will be activated with new channel configuration
-     */
-    list_for_each(node, &adev->usecase_list) {
-        usecase = node_to_item(node, struct audio_usecase, list);
-        if (usecase->type == PCM_PLAYBACK &&
-                usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
-            enable_audio_route(adev, usecase);
-        }
-    }
-
-    if (was_active)
-        audio_extn_keep_alive_start();
-
-    return 0;
-}
-
-/* called with out lock taken */
-static int check_and_set_hdmi_backend(struct stream_out *out)
-{
-    struct audio_device *adev = out->dev;
-    int ret;
-    bool enable_passthru = false;
-
-    if (!(out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL))
-        return -1;
-
-    ALOGV("%s usecase %s out->format:%x out->bit_width:%d", __func__, use_case_table[out->usecase],out->format,out->bit_width);
-
-    if (is_offload_usecase(out->usecase) &&
-        audio_extn_passthru_is_passthrough_stream(out)) {
-        enable_passthru = true;
-        ALOGV("%s : enable_passthru is set to true", __func__);
-    }
-
-    /* Check if change in HDMI channel config is allowed */
-    if (!allow_hdmi_channel_config(adev, enable_passthru)) {
-        return -EPERM;
-    }
-
-    if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
-        uint32_t channels;
-        ALOGV("Offload usecase, enable passthru %d", enable_passthru);
-
-        if (enable_passthru) {
-            audio_extn_passthru_on_start(out);
-            audio_extn_passthru_update_stream_configuration(adev, out);
-        }
-
-        /* For pass through case, the backend should be configured as stereo */
-        channels = enable_passthru ? DEFAULT_HDMI_OUT_CHANNELS :
-                                     out->compr_config.codec->ch_in;
-
-        ret = check_and_set_hdmi_config(adev, channels,
-                                        out->sample_rate, out->format,
-                                        enable_passthru);
-    } else
-        ret = check_and_set_hdmi_config(adev, out->config.channels,
-                                        out->config.rate,
-                                        out->format,
-                                        false);
-    return ret;
-}
-
-
 static int stop_output_stream(struct stream_out *out)
 {
     int ret = 0;
@@ -1841,17 +1909,14 @@
         ALOGV("Disable passthrough , reset mixer to pcm");
         /* NO_PASSTHROUGH */
         out->compr_config.codec->compr_passthr = 0;
-
         audio_extn_passthru_on_stop(out);
         audio_extn_dolby_set_dap_bypass(adev, DAP_STATE_ON);
     }
 
     /* Must be called after removing the usecase from list */
     if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
-        check_and_set_hdmi_config(adev, DEFAULT_HDMI_OUT_CHANNELS,
-                                  DEFAULT_HDMI_OUT_SAMPLE_RATE,
-                                  DEFAULT_HDMI_OUT_FORMAT,
-                                  false);
+        audio_extn_keep_alive_start();
+
     ALOGV("%s: exit: status(%d)", __func__, ret);
     return ret;
 }
@@ -1893,12 +1958,6 @@
         goto error_config;
     }
 
-    /* This must be called before adding this usecase to the list */
-    if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
-        /* This call can fail if compress pass thru is already active */
-        check_and_set_hdmi_backend(out);
-    }
-
     uc_info->id = out->usecase;
     uc_info->type = PCM_PLAYBACK;
     uc_info->stream.out = out;
@@ -1910,6 +1969,16 @@
     audio_extn_perf_lock_acquire(&adev->perf_lock_handle, 0,
                                  adev->perf_lock_opts,
                                  adev->perf_lock_opts_size);
+
+    if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+        audio_extn_keep_alive_stop();
+        if (audio_extn_passthru_is_enabled() &&
+            audio_extn_passthru_is_passthrough_stream(out)) {
+            audio_extn_passthru_on_start(out);
+            audio_extn_passthru_update_stream_configuration(adev, out);
+        }
+    }
+
     select_devices(adev, out->usecase);
 
     ALOGV("%s: Opening PCM device card_id(%d) device_id(%d) format(%#x)",
@@ -1920,6 +1989,8 @@
         if (out->usecase == USECASE_AUDIO_PLAYBACK_AFE_PROXY) {
             flags |= PCM_MMAP | PCM_NOIRQ;
             pcm_open_retry_count = PROXY_OPEN_RETRY_COUNT;
+        } else if (out->realtime) {
+            flags |= PCM_MMAP | PCM_NOIRQ;
         } else
             flags |= PCM_MONOTONIC;
 
@@ -2000,10 +2071,20 @@
             audio_extn_check_and_set_dts_hpx_state(adev);
         }
     }
+
+    if (ret == 0) {
+        register_out_stream(out);
+        if (out->realtime) {
+            ret = pcm_start(out->pcm);
+            if (ret < 0)
+                goto error_open;
+        }
+    }
+
     audio_extn_perf_lock_release(&adev->perf_lock_handle);
     ALOGD("%s: exit", __func__);
 
-    return 0;
+    return ret;
 error_open:
     audio_extn_perf_lock_release(&adev->perf_lock_handle);
     stop_output_stream(out);
@@ -2141,7 +2222,7 @@
     else if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM)
         return out->hal_fragment_size;
 
-    return out->config.period_size *
+    return out->config.period_size * out->af_period_multiplier *
                 audio_stream_out_frame_size((const struct audio_stream_out *)stream);
 }
 
@@ -2172,13 +2253,6 @@
 
     ALOGD("%s: enter: stream (%p) usecase(%d: %s)", __func__,
           stream, out->usecase, use_case_table[out->usecase]);
-    if (out->usecase == USECASE_COMPRESS_VOIP_CALL) {
-        /* Ignore standby in case of voip call because the voip output
-         * stream is closed in adev_close_output_stream()
-         */
-        ALOGD("%s: Ignore Standby in VOIP call", __func__);
-        return 0;
-    }
 
     lock_output_stream(out);
     if (!out->standby) {
@@ -2190,7 +2264,13 @@
 
         pthread_mutex_lock(&adev->lock);
         out->standby = true;
-        if (!is_offload_usecase(out->usecase)) {
+        if (out->usecase == USECASE_COMPRESS_VOIP_CALL) {
+            voice_extn_compress_voip_close_output_stream(stream);
+            pthread_mutex_unlock(&adev->lock);
+            pthread_mutex_unlock(&out->lock);
+            ALOGD("VOIP output entered standby");
+            return 0;
+        } else if (!is_offload_usecase(out->usecase)) {
             if (out->pcm) {
                 pcm_close(out->pcm);
                 out->pcm = NULL;
@@ -2284,6 +2364,17 @@
                 (platform_get_edid_info(adev->platform) != 0) /* HDMI disconnected */) {
             val = AUDIO_DEVICE_OUT_SPEAKER;
         }
+        /*
+         * When A2DP is disconnected the
+         * music playback is paused and the policy manager sends routing=0
+         * But the audioflingercontinues to write data until standby time
+         * (3sec). As BT is turned off, the write gets blocked.
+         * Avoid this by routing audio to speaker until standby.
+         */
+        if ((out->devices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) &&
+                (val == AUDIO_DEVICE_NONE)) {
+                val = AUDIO_DEVICE_OUT_SPEAKER;
+        }
 
         /*
          * select_devices() call below switches all the usecases on the same
@@ -2304,7 +2395,9 @@
          *       playback to headset.
          */
         if (val != 0) {
-            out->devices = val;
+            audio_devices_t new_dev = val;
+            bool same_dev = out->devices == new_dev;
+            out->devices = new_dev;
 
             if (output_drives_call(adev, out)) {
                 if(!voice_is_in_call(adev)) {
@@ -2319,11 +2412,16 @@
             }
 
             if (!out->standby) {
-                audio_extn_perf_lock_acquire(&adev->perf_lock_handle, 0,
-                                             adev->perf_lock_opts,
-                                             adev->perf_lock_opts_size);
+                if (!same_dev) {
+                    ALOGV("update routing change");
+                    out->routing_change = true;
+                    audio_extn_perf_lock_acquire(&adev->perf_lock_handle, 0,
+                                                 adev->perf_lock_opts,
+                                                 adev->perf_lock_opts_size);
+                }
                 select_devices(adev, out->usecase);
-                audio_extn_perf_lock_release(&adev->perf_lock_handle);
+                if (!same_dev)
+                    audio_extn_perf_lock_release(&adev->perf_lock_handle);
             }
         }
 
@@ -2478,11 +2576,21 @@
 
 static uint32_t out_get_latency(const struct audio_stream_out *stream)
 {
+    uint32_t period_ms;
     struct stream_out *out = (struct stream_out *)stream;
     uint32_t latency = 0;
 
     if (is_offload_usecase(out->usecase)) {
         latency = COMPRESS_OFFLOAD_PLAYBACK_LATENCY;
+    } else if (out->realtime) {
+        // since the buffer won't be filled up faster than realtime,
+        // return a smaller number
+        if (out->config.rate)
+            period_ms = (out->af_period_multiplier * out->config.period_size *
+                         1000) / (out->config.rate);
+        else
+            period_ms = 0;
+        latency = period_ms + platform_render_latency(out->usecase)/1000;
     } else {
         latency = (out->config.period_count * out->config.period_size * 1000) /
            (out->config.rate);
@@ -2492,6 +2600,14 @@
     return latency;
 }
 
+static float AmpToDb(float amplification)
+{
+    if (amplification == 0) {
+        return DSD_VOLUME_MIN_DB;
+    }
+    return 20 * log10(amplification);
+}
+
 static int out_set_volume(struct audio_stream_out *stream, float left,
                           float right)
 {
@@ -2510,6 +2626,20 @@
              * Mute is 0 and unmute 1
              */
             audio_extn_passthru_set_volume(out, (left == 0.0f));
+        } else if (out->format == AUDIO_FORMAT_DSD){
+            char mixer_ctl_name[128] =  "DSD Volume";
+            struct audio_device *adev = out->dev;
+            struct mixer_ctl *ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+
+            if (!ctl) {
+                ALOGE("%s: Could not get ctl for mixer cmd - %s",
+                      __func__, mixer_ctl_name);
+                return -EINVAL;
+            }
+            volume[0] = (int)(AmpToDb(left));
+            volume[1] = (int)(AmpToDb(right));
+            mixer_ctl_set_array(ctl, volume, sizeof(volume)/sizeof(volume[0]));
+            return 0;
         } else {
             char mixer_ctl_name[128];
             struct audio_device *adev = out->dev;
@@ -2556,8 +2686,11 @@
             /* increase written size during SSR to avoid mismatch
              * with the written frames count in AF
              */
-            if (audio_bytes_per_sample(out->format) != 0)
-                out->written += bytes / (out->config.channels * audio_bytes_per_sample(out->format));
+            // bytes per frame
+            size_t bpf = audio_bytes_per_sample(out->format) *
+                         audio_channel_count_from_out_mask(out->channel_mask);
+            if (bpf != 0)
+                out->written += bytes / bpf;
             ALOGD(" %s: sound card is not active/SSR state", __func__);
             ret= -EIO;
             goto exit;
@@ -2565,9 +2698,10 @@
     }
 
     if (audio_extn_passthru_should_drop_data(out)) {
-        ALOGD(" %s : Drop data as compress passthrough session is going on", __func__);
-        usleep((uint64_t)bytes * 1000000 / audio_stream_out_frame_size(stream) /
-                        out_get_sample_rate(&out->stream.common));
+        ALOGV(" %s : Drop data as compress passthrough session is going on", __func__);
+        if (audio_bytes_per_sample(out->format) != 0)
+            out->written += bytes / (out->config.channels * audio_bytes_per_sample(out->format));
+        ret = -EIO;
         goto exit;
     }
 
@@ -2589,9 +2723,6 @@
             ALOGD("%s: retry previous failed cal level set", __func__);
             audio_hw_send_gain_dep_calibration(last_known_cal_step);
         }
-
-        if (!is_offload_usecase(out->usecase) && adev->adm_register_output_stream)
-            adev->adm_register_output_stream(adev->adm_data, out->handle, out->flags);
     }
 
     if (adev->is_channel_status_set == false && (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)){
@@ -2679,12 +2810,19 @@
 
             ALOGVV("%s: writing buffer (%zu bytes) to pcm device", __func__, bytes);
 
-            if (adev->adm_request_focus)
-                adev->adm_request_focus(adev->adm_data, out->handle);
+            long ns = 0;
 
-            if (out->usecase == USECASE_AUDIO_PLAYBACK_AFE_PROXY) {
+            if (out->config.rate)
+                ns = pcm_bytes_to_frames(out->pcm, bytes)*1000000000LL/
+                                                     out->config.rate;
+
+            bool use_mmap = is_mmap_usecase(out->usecase) || out->realtime;
+
+            request_out_focus(out, ns);
+
+            if (use_mmap)
                 ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes);
-            } else if (out->hal_op_format != out->hal_ip_format &&
+            else if (out->hal_op_format != out->hal_ip_format &&
                        out->convert_buffer != NULL) {
 
                 memcpy_by_audio_format(out->convert_buffer,
@@ -2701,15 +2839,14 @@
                 ret = pcm_write(out->pcm, (void *)buffer, bytes);
             }
 
+            release_out_focus(out);
+
             if (ret < 0)
                 ret = -errno;
             else if (ret == 0 && (audio_bytes_per_sample(out->format) != 0))
                 out->written += bytes / (out->config.channels * audio_bytes_per_sample(out->format));
             else
                 ret = -EINVAL;
-
-            if (adev->adm_abandon_focus)
-                adev->adm_abandon_focus(adev->adm_data, out->handle);
         }
     }
 
@@ -2939,7 +3076,6 @@
                 if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
                     pthread_mutex_lock(&out->dev->lock);
                     ALOGV("offload resume, check and set hdmi backend again");
-                    check_and_set_hdmi_backend(out);
                     pthread_mutex_unlock(&out->dev->lock);
                 }
                 status = compress_resume(out->compr);
@@ -3011,8 +3147,8 @@
     else if(audio_extn_compr_cap_usecase_supported(in->usecase))
         return audio_extn_compr_cap_get_buffer_size(in->config.format);
 
-    return in->config.period_size *
-                audio_stream_in_frame_size((const struct audio_stream_in *)stream);
+    return in->config.period_size * in->af_period_multiplier *
+        audio_stream_in_frame_size((const struct audio_stream_in *)stream);
 }
 
 static uint32_t in_get_channels(const struct audio_stream *stream)
@@ -3043,14 +3179,6 @@
     ALOGD("%s: enter: stream (%p) usecase(%d: %s)", __func__,
           stream, in->usecase, use_case_table[in->usecase]);
 
-    if (in->usecase == USECASE_COMPRESS_VOIP_CALL) {
-        /* Ignore standby in case of voip call because the voip input
-         * stream is closed in adev_close_input_stream()
-         */
-        ALOGV("%s: Ignore Standby in VOIP call", __func__);
-        return status;
-    }
-
     lock_input_stream(in);
     if (!in->standby && in->is_st_session) {
         ALOGD("%s: sound trigger pcm stop lab", __func__);
@@ -3064,11 +3192,16 @@
 
         pthread_mutex_lock(&adev->lock);
         in->standby = true;
-        if (in->pcm) {
-            pcm_close(in->pcm);
-            in->pcm = NULL;
+        if (in->usecase == USECASE_COMPRESS_VOIP_CALL) {
+            voice_extn_compress_voip_close_input_stream(stream);
+            ALOGD("VOIP input entered standby");
+        } else {
+            if (in->pcm) {
+                pcm_close(in->pcm);
+                in->pcm = NULL;
+            }
+            status = stop_input_stream(in);
         }
-        status = stop_input_stream(in);
         pthread_mutex_unlock(&adev->lock);
     }
     pthread_mutex_unlock(&in->lock);
@@ -3125,8 +3258,11 @@
         if (((int)in->device != val) && (val != 0)) {
             in->device = val;
             /* If recording is in progress, change the tx device to new device */
-            if (!in->standby && !in->is_st_session)
+            if (!in->standby && !in->is_st_session) {
+                ALOGV("update input routing change");
+                in->routing_change = true;
                 ret = select_devices(adev, in->usecase);
+            }
         }
     }
 
@@ -3212,19 +3348,24 @@
             goto exit;
         }
         in->standby = 0;
-        if (adev->adm_register_input_stream)
-            adev->adm_register_input_stream(adev->adm_data, in->capture_handle, in->flags);
     }
 
-    if (adev->adm_request_focus)
-        adev->adm_request_focus(adev->adm_data, in->capture_handle);
+    // what's the duration requested by the client?
+    long ns = 0;
+
+    if (in->config.rate)
+        ns = pcm_bytes_to_frames(in->pcm, bytes)*1000000000LL/
+                                             in->config.rate;
+
+    request_in_focus(in, ns);
+    bool use_mmap = is_mmap_usecase(in->usecase) || in->realtime;
 
     if (in->pcm) {
         if (audio_extn_ssr_get_stream() == in) {
             ret = audio_extn_ssr_read(stream, buffer, bytes);
         } else if (audio_extn_compr_cap_usecase_supported(in->usecase)) {
             ret = audio_extn_compr_cap_read(in, buffer, bytes);
-        } else if (in->usecase == USECASE_AUDIO_RECORD_AFE_PROXY) {
+        } else if (use_mmap) {
             ret = pcm_mmap_read(in->pcm, buffer, bytes);
         } else {
             ret = pcm_read(in->pcm, buffer, bytes);
@@ -3246,8 +3387,7 @@
         }
     }
 
-    if (adev->adm_abandon_focus)
-        adev->adm_abandon_focus(adev->adm_data, in->capture_handle);
+    release_in_focus(in);
 
     /*
      * Instead of writing zeroes here, we could trust the hardware
@@ -3514,7 +3654,12 @@
         else if (config->channel_mask) {
             out->channel_mask = config->channel_mask;
             config->offload_info.channel_mask = config->channel_mask;
+        } else {
+            ALOGE("out->channel_mask not set for OFFLOAD/DIRECT_PCM");
+            ret = -EINVAL;
+            goto error_open;
         }
+
         format = out->format = config->offload_info.format;
         out->sample_rate = config->offload_info.sample_rate;
 
@@ -3531,7 +3676,7 @@
         out->compr_config.codec->bit_rate =
                     config->offload_info.bit_rate;
         out->compr_config.codec->ch_in =
-                audio_channel_count_from_out_mask(config->channel_mask);
+                audio_channel_count_from_out_mask(out->channel_mask);
         out->compr_config.codec->ch_out = out->compr_config.codec->ch_in;
         out->bit_width = AUDIO_OUTPUT_BIT_WIDTH;
         /*TODO: Do we need to change it for passthrough */
@@ -3614,12 +3759,24 @@
                 __func__, config->offload_info.version,
                 config->offload_info.bit_rate);
 
+        /*Check if DSD audio format is supported in codec
+         *and there is no active native DSD use case
+         */
+
+        if ((config->format == AUDIO_FORMAT_DSD) &&
+               (!platform_check_codec_dsd_support(adev->platform) ||
+               audio_is_dsd_native_stream_active(adev))) {
+            ret = -EINVAL;
+            goto error_open;
+        }
+
         /* Disable gapless if any of the following is true
          * passthrough playback
          * AV playback
          * Direct PCM playback
          */
         if (audio_extn_passthru_is_passthrough_stream(out) ||
+            (config->format == AUDIO_FORMAT_DSD) ||
             config->offload_info.has_video ||
             out->flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM) {
             check_and_set_gapless_mode(adev, false);
@@ -3629,6 +3786,10 @@
         if (audio_extn_passthru_is_passthrough_stream(out)) {
             out->flags |= AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH;
         }
+        if (config->format == AUDIO_FORMAT_DSD) {
+            out->flags |= AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH;
+            out->compr_config.codec->compr_passthr = PASSTHROUGH_DSD;
+        }
     } else if (out->flags & AUDIO_OUTPUT_FLAG_INCALL_MUSIC) {
         ret = voice_extn_check_and_set_incall_music_usecase(adev, out);
         if (ret != 0) {
@@ -3661,7 +3822,9 @@
     } else {
         if (out->flags & AUDIO_OUTPUT_FLAG_RAW) {
             out->usecase = USECASE_AUDIO_PLAYBACK_ULL;
-            out->config = pcm_config_low_latency;
+            out->realtime = may_use_noirq_mode(adev, USECASE_AUDIO_PLAYBACK_ULL,
+                                               out->flags);
+            out->config = out->realtime ? pcm_config_rt : pcm_config_low_latency;
         } else if (out->flags & AUDIO_OUTPUT_FLAG_FAST) {
             out->usecase = USECASE_AUDIO_PLAYBACK_LOW_LATENCY;
             out->config = pcm_config_low_latency;
@@ -3748,6 +3911,7 @@
     out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
     out->stream.get_presentation_position = out_get_presentation_position;
 
+    out->af_period_multiplier  = out->realtime ? af_period_multiplier : 1;
     out->standby = 1;
     /* out->muted = false; by calloc() */
     /* out->written = 0; by calloc() */
@@ -3945,7 +4109,7 @@
             ALOGV("cache new edid");
             platform_cache_edid(adev->platform);
         } else if ((val & AUDIO_DEVICE_OUT_USB_DEVICE) ||
-                   (val & AUDIO_DEVICE_IN_USB_DEVICE)) {
+                   !(val ^ AUDIO_DEVICE_IN_USB_DEVICE)) {
             /*
              * Do not allow AFE proxy port usage by WFD source when USB headset is connected.
              * Per AudioPolicyManager, USB device is higher priority than WFD.
@@ -3969,7 +4133,7 @@
             ALOGV("invalidate cached edid");
             platform_invalidate_hdmi_config(adev->platform);
         } else if ((val & AUDIO_DEVICE_OUT_USB_DEVICE) ||
-                   (val & AUDIO_DEVICE_IN_USB_DEVICE)) {
+                   !(val ^ AUDIO_DEVICE_IN_USB_DEVICE)) {
             ret = str_parms_get_str(parms, "card", value, sizeof(value));
             if (ret >= 0) {
                 audio_extn_usb_remove_device(val, atoi(value));
@@ -3979,8 +4143,26 @@
         }
     }
 
+    ret = str_parms_get_str(parms,"reconfigA2dp", value, sizeof(value));
+    if (ret >= 0) {
+        struct audio_usecase *usecase;
+        struct listnode *node;
+        list_for_each(node, &adev->usecase_list) {
+            usecase = node_to_item(node, struct audio_usecase, list);
+            if ((usecase->type == PCM_PLAYBACK) &&
+                (usecase->devices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP)){
+                ALOGD("reconfigure a2dp... forcing device switch");
+                lock_output_stream(usecase->stream.out);
+                audio_extn_a2dp_set_handoff_mode(true);
+                //force device switch to re configure encoder
+                select_devices(adev, usecase->id);
+                audio_extn_a2dp_set_handoff_mode(false);
+                pthread_mutex_unlock(&usecase->stream.out->lock);
+                break;
+            }
+        }
+    }
     audio_extn_set_parameters(adev, parms);
-
 done:
     str_parms_destroy(parms);
     pthread_mutex_unlock(&adev->lock);
@@ -4188,12 +4370,21 @@
 #if LOW_LATENCY_CAPTURE_USE_CASE
         in->usecase = USECASE_AUDIO_RECORD_LOW_LATENCY;
 #endif
+        in->realtime = may_use_noirq_mode(adev, in->usecase, in->flags);
     }
-    in->config = pcm_config_audio_capture;
-    in->config.rate = config->sample_rate;
+
     in->format = config->format;
+    if (in->realtime) {
+        in->config = pcm_config_audio_capture_rt;
+        in->sample_rate = in->config.rate;
+        in->af_period_multiplier = af_period_multiplier;
+    } else {
+        in->config = pcm_config_audio_capture;
+        in->config.rate = config->sample_rate;
+        in->sample_rate = config->sample_rate;
+        in->af_period_multiplier = 1;
+    }
     in->bit_width = 16;
-    in->sample_rate = config->sample_rate;
 
     if (in->device == AUDIO_DEVICE_IN_TELEPHONY_RX) {
         if (adev->mode != AUDIO_MODE_IN_CALL) {
@@ -4269,14 +4460,17 @@
             }
         }
 
-        in->format = config->format;
         in->config.channels = channel_count;
-        frame_size = audio_stream_in_frame_size(&in->stream);
-        buffer_size = get_input_buffer_size(config->sample_rate,
-                                            config->format,
-                                            channel_count,
-                                            is_low_latency);
-        in->config.period_size = buffer_size / frame_size;
+        if (!in->realtime) {
+            in->format = config->format;
+            frame_size = audio_stream_in_frame_size(&in->stream);
+            buffer_size = get_input_buffer_size(config->sample_rate,
+                                                config->format,
+                                                channel_count,
+                                                is_low_latency);
+            in->config.period_size = buffer_size / frame_size;
+        }
+
         if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
                (in->dev->mode == AUDIO_MODE_IN_COMMUNICATION) &&
                (voice_extn_compress_voip_is_format_supported(in->format)) &&
@@ -4535,6 +4729,14 @@
                                     dlsym(adev->adm_lib, "adm_request_focus");
             adev->adm_abandon_focus = (adm_abandon_focus_t)
                                     dlsym(adev->adm_lib, "adm_abandon_focus");
+            adev->adm_set_config = (adm_set_config_t)
+                                    dlsym(adev->adm_lib, "adm_set_config");
+            adev->adm_request_focus_v2 = (adm_request_focus_v2_t)
+                                    dlsym(adev->adm_lib, "adm_request_focus_v2");
+            adev->adm_is_noirq_avail = (adm_is_noirq_avail_t)
+                                    dlsym(adev->adm_lib, "adm_is_noirq_avail");
+            adev->adm_on_routing_change = (adm_on_routing_change_t)
+                                    dlsym(adev->adm_lib, "adm_on_routing_change");
         }
     }
 
@@ -4566,6 +4768,16 @@
         }
     }
 
+    if (property_get("audio_hal.period_multiplier", value, NULL) > 0) {
+        af_period_multiplier = atoi(value);
+        if (af_period_multiplier < 0)
+            af_period_multiplier = 2;
+        else if (af_period_multiplier > 4)
+            af_period_multiplier = 4;
+
+        ALOGV("new period_multiplier = %d", af_period_multiplier);
+    }
+
     adev->multi_offload_enable = property_get_bool("audio.offload.multiple.enabled", false);
     pthread_mutex_unlock(&adev_init_lock);
 
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 8197fec..664d1fc 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -79,6 +79,11 @@
 
 #define MAX_PERF_LOCK_OPTS 20
 
+typedef enum card_status_t {
+    CARD_STATUS_OFFLINE,
+    CARD_STATUS_ONLINE
+} card_status_t;
+
 /* These are the supported use cases by the hardware.
  * Each usecase is mapped to a specific PCM device.
  * Refer to pcm_device_table[].
@@ -162,6 +167,7 @@
     OFFLOAD_CMD_DRAIN,              /* send a full drain request to DSP */
     OFFLOAD_CMD_PARTIAL_DRAIN,      /* send a partial drain request to DSP */
     OFFLOAD_CMD_WAIT_FOR_BUFFER,    /* wait for buffer released by DSP */
+    OFFLOAD_CMD_ERROR,              /* offload playback hit some error */
 };
 
 enum {
@@ -228,6 +234,10 @@
     audio_format_t hal_op_format;
     void *convert_buffer;
 
+    bool realtime;
+    int af_period_multiplier;
+    bool routing_change;
+
     struct audio_device *dev;
 };
 
@@ -252,6 +262,10 @@
     bool is_st_session_active;
     int sample_rate;
     int bit_width;
+    bool realtime;
+    int af_period_multiplier;
+    bool routing_change;
+
     struct audio_device *dev;
 };
 
@@ -308,6 +322,12 @@
 typedef void (*adm_deregister_stream_t)(void *, audio_io_handle_t);
 typedef void (*adm_request_focus_t)(void *, audio_io_handle_t);
 typedef void (*adm_abandon_focus_t)(void *, audio_io_handle_t);
+typedef void (*adm_set_config_t)(void *, audio_io_handle_t,
+                                         struct pcm *,
+                                         struct pcm_config *);
+typedef void (*adm_request_focus_v2_t)(void *, audio_io_handle_t, long);
+typedef bool (*adm_is_noirq_avail_t)(void *, int, int, int);
+typedef void (*adm_on_routing_change_t)(void *, audio_io_handle_t);
 
 struct audio_device {
     struct audio_hw_device device;
@@ -361,6 +381,10 @@
     adm_deregister_stream_t adm_deregister_stream;
     adm_request_focus_t adm_request_focus;
     adm_abandon_focus_t adm_abandon_focus;
+    adm_set_config_t adm_set_config;
+    adm_request_focus_v2_t adm_request_focus_v2;
+    adm_is_noirq_avail_t adm_is_noirq_avail;
+    adm_on_routing_change_t adm_on_routing_change;
 
     void (*offload_effects_get_parameters)(struct str_parms *,
                                            struct str_parms *);
@@ -371,6 +395,7 @@
     int perf_lock_opts[MAX_PERF_LOCK_OPTS];
     int perf_lock_opts_size;
     bool native_playback_enabled;
+    bool asrc_mode_enabled;
 };
 
 int select_devices(struct audio_device *adev,
@@ -392,6 +417,8 @@
 
 bool audio_is_true_native_stream_active(struct audio_device *adev);
 
+bool audio_is_dsd_native_stream_active(struct audio_device *adev);
+
 int pcm_ioctl(struct pcm *pcm, int request, ...);
 
 int get_snd_card_state(struct audio_device *adev);
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 500a28d..b41e040 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -192,8 +192,10 @@
 typedef struct codec_backend_cfg {
     uint32_t sample_rate;
     uint32_t bit_width;
+    uint32_t channels;
     char     *bitwidth_mixer_ctl;
     char     *samplerate_mixer_ctl;
+    char     *channels_mixer_ctl;
 } codec_backend_cfg_t;
 
 static native_audio_prop na_props = {0, 0, 0};
@@ -346,6 +348,8 @@
     [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
     [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
     [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
+    [SND_DEVICE_OUT_BT_A2DP] = "bt-a2dp",
+    [SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = "speaker-and-bt-a2dp",
     [SND_DEVICE_OUT_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",
@@ -465,6 +469,8 @@
     [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14,
     [SND_DEVICE_OUT_BT_SCO] = 22,
     [SND_DEVICE_OUT_BT_SCO_WB] = 39,
+    [SND_DEVICE_OUT_BT_A2DP] = 20,
+    [SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = 14,
     [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
     [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
     [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
@@ -586,6 +592,8 @@
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_BT_A2DP)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
@@ -767,6 +775,7 @@
 #define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
 #define PCM_OFFLOAD_PLATFORM_DELAY (30*1000LL)
 #define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
+#define ULL_PLATFORM_DELAY (6*1000LL)
 
 static void update_codec_type(const char *snd_card_name) {
 
@@ -1205,6 +1214,8 @@
     backend_tag_table[SND_DEVICE_OUT_TRANSMISSION_FM] = strdup("transmission-fm");
     backend_tag_table[SND_DEVICE_OUT_HEADPHONES_44_1] = strdup("headphones-44.1");
     backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = strdup("vbat-voice-speaker");
+    backend_tag_table[SND_DEVICE_OUT_BT_A2DP] = strdup("bt-a2dp");
+    backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = strdup("speaker-and-bt-a2dp");
 
     hw_interface_table[SND_DEVICE_OUT_HDMI] = strdup("HDMI_RX");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("SLIMBUS_0_RX-and-HDMI_RX");
@@ -1847,6 +1858,9 @@
     /* init usb */
     audio_extn_usb_init(adev);
 
+    /*init a2dp*/
+    audio_extn_a2dp_init(adev);
+
     /* Read one time ssr property */
     audio_extn_ssr_update_enabled();
     audio_extn_spkr_prot_init(adev);
@@ -1915,6 +1929,8 @@
         strdup("HDMI_RX Bit Format");
     my_data->current_backend_cfg[HDMI_RX_BACKEND].samplerate_mixer_ctl =
         strdup("HDMI_RX SampleRate");
+    my_data->current_backend_cfg[HDMI_RX_BACKEND].channels_mixer_ctl =
+        strdup("HDMI_RX Channels");
 
     ret = audio_extn_utils_get_codec_version(snd_card_name,
                                              my_data->adev->snd_card,
@@ -2420,8 +2436,19 @@
     return ret;
 }
 
+int check_44100_support_device(audio_devices_t out_device)
+{
+    int ret = true;
 
-static int platform_get_backend_index(snd_device_t snd_device)
+    if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+        out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
+        out_device & AUDIO_DEVICE_OUT_LINE)
+        ret = false;
+
+    return ret;
+}
+
+int platform_get_backend_index(snd_device_t snd_device)
 {
     int32_t port = DEFAULT_CODEC_BACKEND;
 
@@ -2803,6 +2830,10 @@
         new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
         new_snd_devices[1] = SND_DEVICE_OUT_USB_HEADSET;
         status = true;
+    } else if (SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP == snd_device) {
+        *num_devices = 2;
+        new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
+        new_snd_devices[1] = SND_DEVICE_OUT_BT_A2DP;
     }
 
     ALOGD("%s: snd_device(%d) num devices(%d) new_snd_devices(%d)", __func__,
@@ -2875,6 +2906,9 @@
         } else if (devices == (AUDIO_DEVICE_OUT_USB_DEVICE |
                                AUDIO_DEVICE_OUT_SPEAKER)) {
             snd_device = SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET;
+        } else if ((devices & AUDIO_DEVICE_OUT_SPEAKER) &&
+                   (devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
+            snd_device = SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP;
         } else {
             ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
             goto exit;
@@ -2925,6 +2959,8 @@
                 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
             else
                 snd_device = SND_DEVICE_OUT_BT_SCO;
+        } else if (devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+                snd_device = SND_DEVICE_OUT_BT_A2DP;
         } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
                 if (my_data->is_vbat_speaker)
                     snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_VBAT;
@@ -3008,6 +3044,8 @@
             snd_device = SND_DEVICE_OUT_BT_SCO;
     } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
         snd_device = SND_DEVICE_OUT_HDMI ;
+    } else if (devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+        snd_device = SND_DEVICE_OUT_BT_A2DP;
     } else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
                devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
         ALOGD("%s: setting USB hadset channel capability(2) for Proxy", __func__);
@@ -3787,8 +3825,8 @@
                 !strncmp("true", propValue, 4);
         }
 
-        if (prop_playback_enabled && (voice_is_in_call(my_data->adev) ||
-             (SND_CARD_STATE_OFFLINE == get_snd_card_state(my_data->adev)))) {
+        if ((prop_playback_enabled && (voice_is_in_call(my_data->adev))) ||
+             (SND_CARD_STATE_OFFLINE == get_snd_card_state(my_data->adev))) {
             char *decoder_mime_type = value;
 
             //check if unsupported mime type or not
@@ -3825,6 +3863,8 @@
         case USECASE_AUDIO_PLAYBACK_OFFLOAD:
         case USECASE_AUDIO_PLAYBACK_OFFLOAD2:
             return PCM_OFFLOAD_PLATFORM_DELAY;
+        case USECASE_AUDIO_PLAYBACK_ULL:
+            return ULL_PLATFORM_DELAY;
         default:
             return 0;
     }
@@ -4014,16 +4054,21 @@
  * configures afe with bit width and Sample Rate
  */
 static int platform_set_codec_backend_cfg(struct audio_device* adev,
-                         snd_device_t snd_device, unsigned int bit_width,
-                         unsigned int sample_rate, audio_format_t format)
+                         snd_device_t snd_device, struct audio_backend_cfg backend_cfg)
 {
     int ret = 0;
     int backend_idx = DEFAULT_CODEC_BACKEND;
     struct platform_data *my_data = (struct platform_data *)adev->platform;
+    unsigned int bit_width = backend_cfg.bit_width;
+    unsigned int sample_rate = backend_cfg.sample_rate;
+    unsigned int channels = backend_cfg.channels;
+    audio_format_t format = backend_cfg.format;
+    bool passthrough_enabled = backend_cfg.passthrough_enabled;
 
     backend_idx = platform_get_backend_index(snd_device);
-    ALOGI("%s:becf: afe: bitwidth %d, samplerate %d, backend_idx %d device (%s)",
-          __func__, bit_width, sample_rate, backend_idx,
+
+    ALOGI("%s:becf: afe: bitwidth %d, samplerate %d channels %d, backend_idx %d device (%s)",
+          __func__, bit_width, sample_rate, channels,backend_idx,
           platform_get_snd_device_name(snd_device));
 
     if (bit_width !=
@@ -4115,19 +4160,146 @@
             mixer_ctl_set_enum_by_string(ctl, rate_str);
             my_data->current_backend_cfg[backend_idx].sample_rate = sample_rate;
     }
+    if ((backend_idx == HDMI_RX_BACKEND) &&
+        (channels != my_data->current_backend_cfg[backend_idx].channels)) {
+        struct  mixer_ctl *ctl;
+        char *channel_cnt_str = NULL;
+
+        switch (channels) {
+        case 8:
+            channel_cnt_str = "Eight"; break;
+        case 7:
+            channel_cnt_str = "Seven"; break;
+        case 6:
+            channel_cnt_str = "Six"; break;
+        case 5:
+            channel_cnt_str = "Five"; break;
+        case 4:
+            channel_cnt_str = "Four"; break;
+        case 3:
+            channel_cnt_str = "Three"; break;
+        default:
+            channel_cnt_str = "Two"; break;
+        }
+
+        ctl = mixer_get_ctl_by_name(adev->mixer,
+           my_data->current_backend_cfg[backend_idx].channels_mixer_ctl);
+        if (!ctl) {
+            ALOGE("%s:becf: afe: Could not get ctl for mixer command - %s",
+                   __func__,
+                   my_data->current_backend_cfg[backend_idx].channels_mixer_ctl);
+            return -EINVAL;
+        }
+        mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
+        my_data->current_backend_cfg[backend_idx].channels = channels;
+        platform_set_edid_channels_configuration(adev->platform, channels);
+        ALOGD("%s:becf: afe: %s set to %s", __func__,
+               my_data->current_backend_cfg[backend_idx].channels_mixer_ctl, channel_cnt_str);
+    }
+
+    if (backend_idx == HDMI_RX_BACKEND) {
+        const char *hdmi_format_ctrl = "HDMI RX Format";
+        struct mixer_ctl *ctl;
+        ctl = mixer_get_ctl_by_name(adev->mixer,hdmi_format_ctrl);
+
+        if (!ctl) {
+            ALOGE("%s:becf: afe: Could not get ctl for mixer command - %s",
+                   __func__, hdmi_format_ctrl);
+            return -EINVAL;
+        }
+
+        if (passthrough_enabled) {
+            ALOGD("%s:HDMI compress format", __func__);
+            mixer_ctl_set_enum_by_string(ctl, "Compr");
+        } else {
+            ALOGD("%s: HDMI PCM format", __func__);
+            mixer_ctl_set_enum_by_string(ctl, "LPCM");
+        }
+    }
 
     return ret;
 }
 
 /*
+ *Validate the selected bit_width, sample_rate and channels using the edid
+ *of the connected sink device.
+ */
+static void platform_check_hdmi_backend_cfg(struct audio_device* adev,
+                                   struct audio_usecase* usecase,
+                                   struct audio_backend_cfg *hdmi_backend_cfg)
+{
+    unsigned int bit_width;
+    unsigned int sample_rate;
+    unsigned int channels, max_supported_channels = 0;
+    struct platform_data *my_data = (struct platform_data *)adev->platform;
+    edid_audio_info *edid_info = (edid_audio_info *)my_data->edid_info;
+    bool passthrough_enabled = false;
+
+    bit_width = hdmi_backend_cfg->bit_width;
+    sample_rate = hdmi_backend_cfg->sample_rate;
+    channels = hdmi_backend_cfg->channels;
+
+
+    ALOGI("%s:becf: HDMI: bitwidth %d, samplerate %d, channels %d"
+          ", usecase = %d", __func__, bit_width,
+          sample_rate, channels, usecase->id);
+
+    if (audio_extn_passthru_is_enabled() && audio_extn_passthru_is_active()
+        && (usecase->stream.out->compr_config.codec->compr_passthr != 0)) {
+        passthrough_enabled = true;
+        ALOGI("passthrough is enabled for this stream");
+    }
+
+    // For voice calls use default configuration i.e. 16b/48K, only applicable to
+    // default backend
+    if (!passthrough_enabled) {
+
+        max_supported_channels = platform_edid_get_max_channels(my_data);
+
+        //Check EDID info for supported samplerate
+        if (!edid_is_supported_sr(edid_info,sample_rate)) {
+            //reset to current sample rate
+            sample_rate = my_data->current_backend_cfg[HDMI_RX_BACKEND].sample_rate;
+        }
+
+        //Check EDID info for supported bit width
+        if (!edid_is_supported_bps(edid_info,bit_width)) {
+            //reset to current sample rate
+            bit_width = my_data->current_backend_cfg[HDMI_RX_BACKEND].bit_width;
+        }
+
+        if (channels > max_supported_channels)
+            channels = max_supported_channels;
+
+    } else {
+        /*During pass through set default bit width and channels*/
+        channels = DEFAULT_HDMI_OUT_CHANNELS;
+        if ((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
+            (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC))
+            sample_rate = sample_rate * 4 ;
+
+        bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
+        /* We force route so that the BE format can be set to Compr */
+    }
+
+    ALOGI("%s:becf: afe: HDMI backend: passthrough %d updated bit width: %d and sample rate: %d"
+           "channels %d", __func__, passthrough_enabled , bit_width,
+           sample_rate, channels);
+
+    hdmi_backend_cfg->bit_width = bit_width;
+    hdmi_backend_cfg->sample_rate = sample_rate;
+    hdmi_backend_cfg->channels = channels;
+    hdmi_backend_cfg->passthrough_enabled = passthrough_enabled;
+}
+
+/*
  * goes through all the current usecases and picks the highest
  * bitwidth & samplerate
  */
 static bool platform_check_codec_backend_cfg(struct audio_device* adev,
                                    struct audio_usecase* usecase,
                                    snd_device_t snd_device,
-                                   unsigned int* new_bit_width,
-                                   unsigned int* new_sample_rate)
+                                   struct audio_backend_cfg *backend_cfg)
 {
     bool backend_change = false;
     struct listnode *node;
@@ -4135,24 +4307,27 @@
     char value[PROPERTY_VALUE_MAX] = {0};
     unsigned int bit_width;
     unsigned int sample_rate;
+    unsigned int channels;
+    bool passthrough_enabled = false;
     int backend_idx = DEFAULT_CODEC_BACKEND;
     struct platform_data *my_data = (struct platform_data *)adev->platform;
     int na_mode = platform_get_native_support();
-    edid_audio_info *edid_info = (edid_audio_info *)my_data->edid_info;
+    bool channels_updated = false;
 
     backend_idx = platform_get_backend_index(snd_device);
 
-    bit_width = *new_bit_width;
-    sample_rate = *new_sample_rate;
+    bit_width = backend_cfg->bit_width;
+    sample_rate = backend_cfg->sample_rate;
+    channels = backend_cfg->channels;
 
-    ALOGI("%s:becf: afe: Codec selected backend: %d current bit width: %d and sample rate: %d",
-          __func__, backend_idx, bit_width, sample_rate);
+    ALOGI("%s:becf: afe: Codec selected backend: %d current bit width: %d sample rate: %d channels: %d",
+          __func__, backend_idx, bit_width, sample_rate, channels);
 
     // For voice calls use default configuration i.e. 16b/48K, only applicable to
     // default backend
     // force routing is not required here, caller will do it anyway
     if ((voice_is_in_call(adev) || adev->mode == AUDIO_MODE_IN_COMMUNICATION) &&
-        backend_idx == DEFAULT_CODEC_BACKEND) {
+        usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) {
         ALOGW("%s:becf: afe:Use default bw and sr for voice/voip calls ",
               __func__);
         bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
@@ -4173,11 +4348,12 @@
             uc = node_to_item(node, struct audio_usecase, list);
             struct stream_out *out = (struct stream_out*) uc->stream.out;
             if (uc->type == PCM_PLAYBACK && out && usecase != uc) {
+                unsigned int out_channels = audio_channel_count_from_out_mask(out->channel_mask);
 
                 ALOGD("%s:napb: (%d) - (%s)id (%d) sr %d bw "
-                      "(%d) device %s", __func__, i++, use_case_table[uc->id],
+                      "(%d) ch (%d) device %s", __func__, i++, use_case_table[uc->id],
                       uc->id, out->sample_rate,
-                      out->bit_width,
+                      out->bit_width, out_channels,
                       platform_get_snd_device_name(uc->out_snd_device));
 
                 if (platform_check_backends_match(snd_device, uc->out_snd_device)) {
@@ -4187,6 +4363,8 @@
                             sample_rate = out->sample_rate;
                         if (out->sample_rate < OUTPUT_SAMPLING_RATE_44100)
                             sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+                        if (channels < out_channels)
+                            channels = out_channels;
                 }
             }
         }
@@ -4215,14 +4393,12 @@
     }
 
     /*
-     * hifi playback not supported on spkr devices, limit the Sample Rate
+     * hifi playback not supported on non-44.1-support devices, limit the Sample Rate
      * to 48 khz.
      */
-    if (SND_DEVICE_OUT_SPEAKER == snd_device ||
-        SND_DEVICE_OUT_SPEAKER_WSA == snd_device ||
-        SND_DEVICE_OUT_SPEAKER_VBAT == snd_device) {
+    if (check_44100_support_device(usecase->devices)) {
         sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
-        ALOGD("%s:becf: afe: playback on speaker device Configure afe to "
+        ALOGD("%s:becf: afe: playback on non-44.1-support device Configure afe to "
             "default Sample Rate(48k)", __func__);
     }
 
@@ -4246,16 +4422,21 @@
     }
 
     if (backend_idx == HDMI_RX_BACKEND) {
-        //Check EDID info for supported samplerate
-        if (!edid_is_supported_sr(edid_info,sample_rate)) {
-            //reset to current sample rate
-            sample_rate = my_data->current_backend_cfg[backend_idx].sample_rate;
-        }
-        //Check EDID info for supported bit widhth
-        if (!edid_is_supported_bps(edid_info,bit_width)) {
-            //reset to current sample rate
-            bit_width = my_data->current_backend_cfg[backend_idx].bit_width;
-        }
+        struct audio_backend_cfg hdmi_backend_cfg;
+        hdmi_backend_cfg.bit_width = bit_width;
+        hdmi_backend_cfg.sample_rate = sample_rate;
+        hdmi_backend_cfg.channels = channels;
+        hdmi_backend_cfg.passthrough_enabled = false;
+
+        platform_check_hdmi_backend_cfg(adev, usecase, &hdmi_backend_cfg);
+
+        bit_width = hdmi_backend_cfg.bit_width;
+        sample_rate = hdmi_backend_cfg.sample_rate;
+        channels = hdmi_backend_cfg.channels;
+        passthrough_enabled = hdmi_backend_cfg.passthrough_enabled;
+
+        if (channels != my_data->current_backend_cfg[backend_idx].channels)
+            channels_updated = true;
     }
 
     //check if mulitchannel clip needs to be down sampled to 48k
@@ -4286,13 +4467,16 @@
     // Force routing if the expected bitwdith or samplerate
     // is not same as current backend comfiguration
     if ((bit_width != my_data->current_backend_cfg[backend_idx].bit_width) ||
-        (sample_rate != my_data->current_backend_cfg[backend_idx].sample_rate)) {
-        *new_bit_width = bit_width;
-        *new_sample_rate = sample_rate;
+        (sample_rate != my_data->current_backend_cfg[backend_idx].sample_rate) ||
+         passthrough_enabled || channels_updated) {
+        backend_cfg->bit_width = bit_width;
+        backend_cfg->sample_rate = sample_rate;
+        backend_cfg->channels = channels;
+        backend_cfg->passthrough_enabled = passthrough_enabled;
         backend_change = true;
-        ALOGI("%s:becf: afe: Codec backend needs to be updated. new bit width: %d new sample rate: %d",
-              __func__,
-             *new_bit_width, *new_sample_rate);
+        ALOGI("%s:becf: afe: Codec backend needs to be updated. new bit width: %d"
+              " new sample rate: %d new channels %d",__func__,
+               backend_cfg->bit_width, backend_cfg->sample_rate, backend_cfg->channels);
     }
 
     return backend_change;
@@ -4301,23 +4485,24 @@
 bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev,
     struct audio_usecase *usecase, snd_device_t snd_device)
 {
-    unsigned int new_bit_width;
-    unsigned int new_sample_rate;
     int backend_idx = DEFAULT_CODEC_BACKEND;
     int new_snd_devices[SND_DEVICE_OUT_END];
     int i, num_devices = 1;
+    struct audio_backend_cfg backend_cfg;
     bool ret = false;
-    audio_format_t format;
 
     backend_idx = platform_get_backend_index(snd_device);
 
-    new_bit_width = usecase->stream.out->bit_width;
-    new_sample_rate = usecase->stream.out->sample_rate;
-    format = usecase->stream.out->format;
+    backend_cfg.bit_width = usecase->stream.out->bit_width;
+    backend_cfg.sample_rate = usecase->stream.out->sample_rate;
+    backend_cfg.format = usecase->stream.out->format;
+    backend_cfg.channels = audio_channel_count_from_out_mask(usecase->stream.out->channel_mask);
+    /*this is populated by check_codec_backend_cfg hence set default value to false*/
+    backend_cfg.passthrough_enabled = false;
 
-    ALOGI("%s:becf: afe: bitwidth %d, samplerate %d"
-          ", backend_idx %d usecase = %d device (%s)", __func__, new_bit_width,
-          new_sample_rate, backend_idx, usecase->id,
+    ALOGI("%s:becf: afe: bitwidth %d, samplerate %d channels %d"
+          ", backend_idx %d usecase = %d device (%s)", __func__, backend_cfg.bit_width,
+          backend_cfg.sample_rate,  backend_cfg.channels, backend_idx, usecase->id,
           platform_get_snd_device_name(snd_device));
 
     if (!platform_can_split_snd_device(adev->platform, snd_device,
@@ -4328,9 +4513,9 @@
         ALOGI("%s: becf: new_snd_devices[%d] is %s", __func__, i,
             platform_get_snd_device_name(new_snd_devices[i]));
         if (platform_check_codec_backend_cfg(adev, usecase, new_snd_devices[i],
-                                             &new_bit_width, &new_sample_rate)) {
+                                             &backend_cfg)) {
                 platform_set_codec_backend_cfg(adev, new_snd_devices[i],
-                                               new_bit_width, new_sample_rate, format);
+                                               backend_cfg);
                 ret = true;
         }
     }
@@ -5000,6 +5185,7 @@
     //reset HDMI_RX_BACKEND to default values
     my_data->current_backend_cfg[HDMI_RX_BACKEND].sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
     my_data->current_backend_cfg[HDMI_RX_BACKEND].bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
+    my_data->current_backend_cfg[HDMI_RX_BACKEND].channels = DEFAULT_HDMI_OUT_CHANNELS;
 }
 
 int platform_set_mixer_control(struct stream_out *out, const char * mixer_ctl_name,
@@ -5018,91 +5204,6 @@
     return mixer_ctl_set_enum_by_string(ctl, mixer_val);
 }
 
-static int set_mixer_control(struct mixer *mixer,
-                             const char * mixer_ctl_name,
-                             const char *mixer_val)
-{
-    struct mixer_ctl *ctl;
-    ALOGD("setting mixer ctl %s with value %s", mixer_ctl_name, mixer_val);
-    ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
-    if (!ctl) {
-        ALOGE("%s: could not get ctl for mixer cmd - %s",
-              __func__, mixer_ctl_name);
-        return -EINVAL;
-    }
-
-    return mixer_ctl_set_enum_by_string(ctl, mixer_val);
-}
-
-int platform_set_hdmi_config(void *platform, uint32_t channel_count,
-                             uint32_t sample_rate, bool enable_passthrough)
-{
-    struct platform_data *my_data = (struct platform_data *)platform;
-    struct audio_device *adev = my_data->adev;
-    const char *hdmi_format_ctrl = "HDMI RX Format";
-    const char *hdmi_rate_ctrl   = "HDMI_RX SampleRate";
-    const char *hdmi_chans_ctrl  = "HDMI_RX Channels";
-    const char *channel_cnt_str  = NULL;
-
-    ALOGI("%s ch[%d] sr[%d], pthru[%d]", __func__,
-        channel_count, sample_rate, enable_passthrough);
-
-    switch (channel_count) {
-    case 8:
-        channel_cnt_str = "Eight"; break;
-    case 7:
-        channel_cnt_str = "Seven"; break;
-    case 6:
-        channel_cnt_str = "Six"; break;
-    case 5:
-        channel_cnt_str = "Five"; break;
-    case 4:
-        channel_cnt_str = "Four"; break;
-    case 3:
-        channel_cnt_str = "Three"; break;
-    default:
-        channel_cnt_str = "Two"; break;
-    }
-    ALOGV("%s: HDMI channel count: %s", __func__, channel_cnt_str);
-    set_mixer_control(adev->mixer, hdmi_chans_ctrl, channel_cnt_str);
-
-    if (enable_passthrough) {
-        ALOGD("%s:HDMI compress format", __func__);
-        set_mixer_control(adev->mixer, hdmi_format_ctrl, "Compr");
-    } else {
-        ALOGD("%s: HDMI PCM format", __func__);
-        set_mixer_control(adev->mixer, hdmi_format_ctrl, "LPCM");
-    }
-
-    switch (sample_rate) {
-    case 32000:
-        set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_32");
-        break;
-    case 44100:
-        set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_44P1");
-        break;
-    case 96000:
-        set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_96");
-        break;
-    case 128000:
-        set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_128");
-        break;
-    case 176400:
-        set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_176_4");
-        break;
-    case 192000:
-        set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_192");
-        break;
-    default:
-    case 48000:
-        set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_48");
-        break;
-    }
-
-    return 0;
-}
-
-
 int platform_set_device_params(struct stream_out *out, int param, int value)
 {
     struct audio_device *adev = out->dev;
@@ -5311,3 +5412,19 @@
     }
     return 0;
 }
+
+bool platform_check_codec_dsd_support(void *platform __unused)
+{
+    return false;
+}
+
+bool platform_check_codec_asrc_support(void *platform __unused)
+{
+    return false;
+}
+
+bool platform_check_if_backend_has_to_be_disabled(snd_device_t new_snd_device __unused,
+                                                  snd_device_t cuurent_snd_device __unused)
+{
+    return false;
+}
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index 756c749..6c89d0a 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -98,6 +98,8 @@
     SND_DEVICE_OUT_SPEAKER_AND_HDMI,
     SND_DEVICE_OUT_BT_SCO,
     SND_DEVICE_OUT_BT_SCO_WB,
+    SND_DEVICE_OUT_BT_A2DP,
+    SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP,
     SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES,
     SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES,
     SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET,
@@ -196,9 +198,12 @@
     SND_DEVICE_MAX = SND_DEVICE_IN_END,
 
 };
-
+#define INPUT_SAMPLING_RATE_DSD64       2822400
+#define INPUT_SAMPLING_RATE_DSD128      5644800
 #define DEFAULT_OUTPUT_SAMPLING_RATE 48000
 #define OUTPUT_SAMPLING_RATE_44100      44100
+#define OUTPUT_SAMPLING_RATE_DSD64       176400
+#define OUTPUT_SAMPLING_RATE_DSD128      352800
 #define MAX_PORT                        6
 #define ALL_CODEC_BACKEND_PORT          0
 #define HEADPHONE_44_1_BACKEND_PORT     5
@@ -206,6 +211,8 @@
 enum {
     DEFAULT_CODEC_BACKEND,
     SLIMBUS_0_RX = DEFAULT_CODEC_BACKEND,
+    DSD_NATIVE_BACKEND,
+    SLIMBUS_2_RX = DSD_NATIVE_BACKEND,
     HEADPHONE_44_1_BACKEND,
     SLIMBUS_5_RX = HEADPHONE_44_1_BACKEND,
     HEADPHONE_BACKEND,
@@ -354,7 +361,8 @@
 enum {
     LEGACY_PCM = 0,
     PASSTHROUGH,
-    PASSTHROUGH_CONVERT
+    PASSTHROUGH_CONVERT,
+    PASSTHROUGH_DSD
 };
 /*
  * ID for setting mute and lateny on the device side
@@ -370,4 +378,13 @@
     char device_name[100];
     char interface_name[100];
 };
+
+struct audio_backend_cfg {
+    unsigned int   sample_rate;
+    unsigned int   channels;
+    unsigned int   bit_width;
+    bool           passthrough_enabled;
+    audio_format_t format;
+};
+
 #endif // QCOM_AUDIO_PLATFORM_H
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index 2b6a1d7..e5d42bd 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1257,3 +1257,24 @@
     }
     return 0;
 }
+
+bool platform_check_codec_dsd_support(void *platform __unused)
+{
+    return false;
+}
+
+int platform_get_backend_index(snd_device_t snd_device __unused);
+{
+    return 0;
+}
+
+bool platform_check_codec_asrc_support(void *platform __unused)
+{
+    return false;
+}
+
+bool platform_check_if_backend_has_to_be_disabled(snd_device_t new_snd_device __unused,
+                                                  snd_device_t cuurent_snd_device __unused)
+{
+    return false;
+}
diff --git a/hal/msm8960/platform.h b/hal/msm8960/platform.h
index aab5436..07060b6 100644
--- a/hal/msm8960/platform.h
+++ b/hal/msm8960/platform.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2016 The Linux Foundation. All rights reserved.
  * Not a contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -64,6 +64,8 @@
     SND_DEVICE_OUT_HDMI,
     SND_DEVICE_OUT_SPEAKER_AND_HDMI,
     SND_DEVICE_OUT_BT_SCO,
+    SND_DEVICE_OUT_BT_A2DP,
+    SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP,
     SND_DEVICE_OUT_BT_SCO_WB,
     SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES,
     SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES,
@@ -110,6 +112,12 @@
 #define SOUND_CARD 0
 
 #define DEFAULT_OUTPUT_SAMPLING_RATE 48000
+#define INPUT_SAMPLING_RATE_DSD64       2822400
+#define INPUT_SAMPLING_RATE_DSD128      5644800
+#define OUTPUT_SAMPLING_RATE_DSD64       176400
+#define OUTPUT_SAMPLING_RATE_DSD128      352800
+#define DSD_NATIVE_BACKEND 1
+#define PASSTHROUGH_DSD 3
 
 #define ALL_SESSION_VSID                0xFFFFFFFF
 #define DEFAULT_MUTE_RAMP_DURATION_MS   20
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index b98cc73..24bee89 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -188,8 +188,10 @@
 typedef struct codec_backend_cfg {
     uint32_t sample_rate;
     uint32_t bit_width;
+    uint32_t channels;
     char     *bitwidth_mixer_ctl;
     char     *samplerate_mixer_ctl;
+    char     *channels_mixer_ctl;
 } codec_backend_cfg_t;
 
 static native_audio_prop na_props = {0, 0, 0};
@@ -245,6 +247,8 @@
     int metainfo_key;
     int source_mic_type;
     int max_mic_count;
+    bool is_dsd_supported;
+    bool is_asrc_supported;
 };
 
 static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
@@ -332,6 +336,7 @@
     [SND_DEVICE_OUT_SPEAKER_VBAT] = "speaker-vbat",
     [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
     [SND_DEVICE_OUT_HEADPHONES] = "headphones",
+    [SND_DEVICE_OUT_HEADPHONES_DSD] = "headphones-dsd",
     [SND_DEVICE_OUT_HEADPHONES_44_1] = "headphones-44.1",
     [SND_DEVICE_OUT_LINE] = "line",
     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
@@ -347,6 +352,8 @@
     [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
     [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
     [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
+    [SND_DEVICE_OUT_BT_A2DP] = "bt-a2dp",
+    [SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = "speaker-and-bt-a2dp",
     [SND_DEVICE_OUT_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",
@@ -423,6 +430,7 @@
     [SND_DEVICE_IN_SPEAKER_QMIC_AEC] = "quad-mic",
     [SND_DEVICE_IN_SPEAKER_QMIC_NS] = "quad-mic",
     [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = "quad-mic",
+    [SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE] = "quad-mic",
     [SND_DEVICE_IN_THREE_MIC] = "three-mic",
     [SND_DEVICE_IN_HANDSET_TMIC] = "three-mic",
     [SND_DEVICE_IN_UNPROCESSED_MIC] = "unprocessed-mic",
@@ -446,6 +454,7 @@
     [SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
     [SND_DEVICE_OUT_LINE] = 10,
     [SND_DEVICE_OUT_HEADPHONES] = 10,
+    [SND_DEVICE_OUT_HEADPHONES_DSD] = 10,
     [SND_DEVICE_OUT_HEADPHONES_44_1] = 10,
     [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
     [SND_DEVICE_OUT_SPEAKER_AND_LINE] = 10,
@@ -460,6 +469,8 @@
     [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14,
     [SND_DEVICE_OUT_BT_SCO] = 22,
     [SND_DEVICE_OUT_BT_SCO_WB] = 39,
+    [SND_DEVICE_OUT_BT_A2DP] = 20,
+    [SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = 14,
     [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
     [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
     [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
@@ -535,6 +546,7 @@
     [SND_DEVICE_IN_SPEAKER_QMIC_AEC] = 126,
     [SND_DEVICE_IN_SPEAKER_QMIC_NS] = 127,
     [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = 129,
+    [SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE] = 125,
     [SND_DEVICE_IN_THREE_MIC] = 46, /* for APSS Surround Sound Recording */
     [SND_DEVICE_IN_HANDSET_TMIC] = 125, /* for 3mic recording with fluence */
     [SND_DEVICE_IN_UNPROCESSED_MIC] = 143,
@@ -560,6 +572,7 @@
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_VBAT)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES_DSD)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES_44_1)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_LINE)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
@@ -575,6 +588,8 @@
     {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_BT_A2DP)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
@@ -646,6 +661,7 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_NS)},
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE)},
     {TO_NAME_INDEX(SND_DEVICE_IN_THREE_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_TMIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_MIC)},
@@ -783,6 +799,7 @@
 #define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
 #define PCM_OFFLOAD_PLATFORM_DELAY (30*1000LL)
 #define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
+#define ULL_PLATFORM_DELAY         (6*1000LL)
 
 bool platform_send_gain_dep_cal(void *platform, int level) {
     bool ret_val = false;
@@ -1051,7 +1068,8 @@
                  sizeof("apq8084-taiko-i2s-cdp-snd-card"))) {
         plat_data->is_i2s_ext_modem = true;
     }
-    ALOGV("%s, is_i2s_ext_modem:%d",__func__, plat_data->is_i2s_ext_modem);
+    ALOGV("%s, is_i2s_ext_modem:%d soundcard name is %s",__func__,
+           plat_data->is_i2s_ext_modem, snd_card_name);
 
     return plat_data->is_i2s_ext_modem;
 }
@@ -1089,9 +1107,13 @@
     backend_tag_table[SND_DEVICE_IN_USB_HEADSET_MIC] = strdup("usb-headset-mic");
     backend_tag_table[SND_DEVICE_IN_CAPTURE_FM] = strdup("capture-fm");
     backend_tag_table[SND_DEVICE_OUT_TRANSMISSION_FM] = strdup("transmission-fm");
+    backend_tag_table[SND_DEVICE_OUT_HEADPHONES_DSD] = strdup("headphones-dsd");
     backend_tag_table[SND_DEVICE_OUT_HEADPHONES_44_1] = strdup("headphones-44.1");
     backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = strdup("voice-speaker-vbat");
+    backend_tag_table[SND_DEVICE_OUT_BT_A2DP] = strdup("bt-a2dp");
+    backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = strdup("speaker-and-bt-a2dp");
 
+    hw_interface_table[SND_DEVICE_OUT_HEADPHONES_DSD] = strdup("SLIMBUS_2_RX");
     hw_interface_table[SND_DEVICE_OUT_HEADPHONES_44_1] = strdup("SLIMBUS_5_RX");
     hw_interface_table[SND_DEVICE_OUT_HDMI] = strdup("HDMI_RX");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("SLIMBUS_0_RX-and-HDMI_RX");
@@ -1672,6 +1694,9 @@
     /* init usb */
     audio_extn_usb_init(adev);
 
+    /*init a2dp*/
+    audio_extn_a2dp_init(adev);
+
     /* init dap hal */
     audio_extn_dap_hal_init(adev->snd_card);
 
@@ -1697,6 +1722,11 @@
     my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].samplerate_mixer_ctl =
         strdup("SLIM_0_RX SampleRate");
 
+    my_data->current_backend_cfg[DSD_NATIVE_BACKEND].bitwidth_mixer_ctl =
+        strdup("SLIM_2_RX Format");
+    my_data->current_backend_cfg[DSD_NATIVE_BACKEND].samplerate_mixer_ctl =
+        strdup("SLIM_2_RX SampleRate");
+
     my_data->current_backend_cfg[HEADPHONE_44_1_BACKEND].bitwidth_mixer_ctl =
         strdup("SLIM_5_RX Format");
     my_data->current_backend_cfg[HEADPHONE_44_1_BACKEND].samplerate_mixer_ctl =
@@ -1727,6 +1757,13 @@
         }
     }
 
+    if(strstr(snd_card_name, "tavil")) {
+        ALOGD("%s:DSD playback is supported", __func__);
+        my_data->is_dsd_supported = true;
+        my_data->is_asrc_supported = true;
+        platform_set_native_support(NATIVE_AUDIO_MODE_MULTIPLE_44_1);
+    }
+
     my_data->current_backend_cfg[HEADPHONE_BACKEND].bitwidth_mixer_ctl =
         strdup("SLIM_6_RX Format");
     my_data->current_backend_cfg[HEADPHONE_BACKEND].samplerate_mixer_ctl =
@@ -1735,6 +1772,8 @@
         strdup("HDMI_RX Bit Format");
     my_data->current_backend_cfg[HDMI_RX_BACKEND].samplerate_mixer_ctl =
         strdup("HDMI_RX SampleRate");
+    my_data->current_backend_cfg[HDMI_RX_BACKEND].channels_mixer_ctl =
+        strdup("HDMI_RX Channels");
 
     my_data->current_backend_cfg[USB_AUDIO_RX_BACKEND].bitwidth_mixer_ctl =
         strdup("USB_AUDIO_RX Format");
@@ -1887,6 +1926,32 @@
     return result;
 }
 
+bool platform_check_if_backend_has_to_be_disabled(snd_device_t new_snd_device,
+                                                  snd_device_t cuurent_snd_device)
+{
+    bool result = false;
+
+    ALOGV("%s: current snd device = %s, new snd device = %s", __func__,
+                platform_get_snd_device_name(cuurent_snd_device),
+                platform_get_snd_device_name(new_snd_device));
+
+    if ((new_snd_device < SND_DEVICE_MIN) || (new_snd_device >= SND_DEVICE_OUT_END) ||
+            (cuurent_snd_device < SND_DEVICE_MIN) || (cuurent_snd_device >= SND_DEVICE_OUT_END)) {
+        ALOGE("%s: Invalid snd_device",__func__);
+        return false;
+    }
+
+    if (cuurent_snd_device == SND_DEVICE_OUT_HEADPHONES &&
+            (new_snd_device == SND_DEVICE_OUT_HEADPHONES_44_1 ||
+             new_snd_device == SND_DEVICE_OUT_HEADPHONES_DSD)) {
+        result = true;
+    }
+
+    ALOGV("%s: Need to disable current backend %s, %d",
+          __func__, platform_get_snd_device_name(cuurent_snd_device), result);
+    return result;
+}
+
 int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
 {
     int device_id;
@@ -2072,7 +2137,8 @@
 
 int platform_set_native_support(int na_mode)
 {
-    if (NATIVE_AUDIO_MODE_SRC == na_mode || NATIVE_AUDIO_MODE_TRUE_44_1 == na_mode) {
+    if (NATIVE_AUDIO_MODE_SRC == na_mode || NATIVE_AUDIO_MODE_TRUE_44_1 == na_mode
+        || NATIVE_AUDIO_MODE_MULTIPLE_44_1 == na_mode) {
         na_props.platform_na_prop_enabled = na_props.ui_na_prop_enabled = true;
         na_props.na_mode = na_mode;
         ALOGD("%s:napb: native audio playback enabled in (%s) mode v2.0", __func__,
@@ -2087,6 +2153,18 @@
     return 0;
 }
 
+bool platform_check_codec_dsd_support(void *platform)
+{
+    struct platform_data *my_data = (struct platform_data *)platform;
+    return my_data->is_dsd_supported;
+}
+
+bool platform_check_codec_asrc_support(void *platform)
+{
+    struct platform_data *my_data = (struct platform_data *)platform;
+    return my_data->is_asrc_supported;
+}
+
 int platform_get_native_support()
 {
     int ret = NATIVE_AUDIO_MODE_INVALID;
@@ -2139,6 +2217,8 @@
             mode = NATIVE_AUDIO_MODE_SRC;
         else if (value && !strncmp(value, "true", sizeof("true")))
             mode = NATIVE_AUDIO_MODE_TRUE_44_1;
+        else if (value && !strncmp(value, "multiple", sizeof("multiple")))
+            mode = NATIVE_AUDIO_MODE_MULTIPLE_44_1;
         else {
             mode = NATIVE_AUDIO_MODE_INVALID;
             ALOGE("%s:napb:native_audio_mode in platform info xml,invalid mode string",
@@ -2205,7 +2285,20 @@
 
     return ret;
 }
-static int platform_get_backend_index(snd_device_t snd_device)
+
+int check_44100_support_device(audio_devices_t out_device)
+{
+    int ret = true;
+
+    if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+        out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
+        out_device & AUDIO_DEVICE_OUT_LINE)
+        ret = false;
+
+    return ret;
+}
+
+int platform_get_backend_index(snd_device_t snd_device)
 {
     int32_t port = DEFAULT_CODEC_BACKEND;
 
@@ -2214,6 +2307,9 @@
                 if (strncmp(backend_tag_table[snd_device], "headphones-44.1",
                             sizeof("headphones-44.1")) == 0)
                         port = HEADPHONE_44_1_BACKEND;
+                else if (strncmp(backend_tag_table[snd_device], "headphones-dsd",
+                            sizeof("headphones-dsd")) == 0)
+                        port = DSD_NATIVE_BACKEND;
                 else if (strncmp(backend_tag_table[snd_device], "headphones",
                             sizeof("headphones")) == 0)
                         port = HEADPHONE_BACKEND;
@@ -2582,8 +2678,13 @@
         new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
         new_snd_devices[1] = SND_DEVICE_OUT_USB_HEADSET;
         status = true;
+    } else if (SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP == snd_device) {
+        *num_devices = 2;
+        new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
+        new_snd_devices[1] = SND_DEVICE_OUT_BT_A2DP;
     }
 
+
     ALOGD("%s: snd_device(%d) num devices(%d) new_snd_devices(%d)", __func__,
         snd_device, *num_devices, *new_snd_devices);
 
@@ -2642,6 +2743,9 @@
         } else if (devices == (AUDIO_DEVICE_OUT_USB_DEVICE |
                                AUDIO_DEVICE_OUT_SPEAKER)) {
             snd_device = SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET;
+        } else if ((devices & AUDIO_DEVICE_OUT_SPEAKER) &&
+                   (devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
+            snd_device = SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP;
         } else {
             ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
             goto exit;
@@ -2697,6 +2801,8 @@
                     snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_VBAT;
                 else
                     snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
+        } else if (devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+            snd_device = SND_DEVICE_OUT_BT_A2DP;
         } else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
                    devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
             snd_device = SND_DEVICE_OUT_USB_HEADSET;
@@ -2726,6 +2832,12 @@
         } else if (NATIVE_AUDIO_MODE_SRC == na_mode &&
                    OUTPUT_SAMPLING_RATE_44100 == sample_rate) {
                 snd_device = SND_DEVICE_OUT_HEADPHONES_44_1;
+        } else if (NATIVE_AUDIO_MODE_MULTIPLE_44_1 == na_mode &&
+                   (sample_rate % OUTPUT_SAMPLING_RATE_44100 == 0) &&
+                   (out->format != AUDIO_FORMAT_DSD)) {
+                snd_device = SND_DEVICE_OUT_HEADPHONES_44_1;
+        } else if (out->format == AUDIO_FORMAT_DSD) {
+                snd_device = SND_DEVICE_OUT_HEADPHONES_DSD;
         } else
             snd_device = SND_DEVICE_OUT_HEADPHONES;
     } else if (devices & AUDIO_DEVICE_OUT_LINE) {
@@ -2746,6 +2858,8 @@
             snd_device = SND_DEVICE_OUT_BT_SCO_WB;
         else
             snd_device = SND_DEVICE_OUT_BT_SCO;
+    } else if (devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
+        snd_device = SND_DEVICE_OUT_BT_A2DP;
     } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
         snd_device = SND_DEVICE_OUT_HDMI ;
     } else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
@@ -2896,7 +3010,7 @@
             if (my_data->fluence_in_voice_rec && channel_count == 1) {
                 if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
                     (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
-                     snd_device = SND_DEVICE_IN_HANDSET_QMIC;
+                     snd_device = SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE;
                 } else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
                     (my_data->source_mic_type & SOURCE_THREE_MIC)) {
                     snd_device = SND_DEVICE_IN_HANDSET_TMIC;
@@ -3850,8 +3964,8 @@
                 !strncmp("true", propValue, 4);
         }
 
-        if (prop_playback_enabled && (voice_is_in_call(my_data->adev) ||
-             (SND_CARD_STATE_OFFLINE == get_snd_card_state(my_data->adev)))) {
+        if ((prop_playback_enabled && (voice_is_in_call(my_data->adev))) ||
+             (SND_CARD_STATE_OFFLINE == get_snd_card_state(my_data->adev))) {
             char *decoder_mime_type = value;
 
             //check if unsupported mime type or not
@@ -3886,6 +4000,8 @@
         case USECASE_AUDIO_PLAYBACK_OFFLOAD:
         case USECASE_AUDIO_PLAYBACK_OFFLOAD2:
              return PCM_OFFLOAD_PLATFORM_DELAY;
+        case USECASE_AUDIO_PLAYBACK_ULL:
+             return ULL_PLATFORM_DELAY;
         default:
             return 0;
     }
@@ -3984,17 +4100,20 @@
  * configures afe with bit width and Sample Rate
  */
 static int platform_set_codec_backend_cfg(struct audio_device* adev,
-                         snd_device_t snd_device, unsigned int bit_width,
-                         unsigned int sample_rate, audio_format_t format)
+                         snd_device_t snd_device, struct audio_backend_cfg backend_cfg)
 {
     int ret = 0;
     int backend_idx = DEFAULT_CODEC_BACKEND;
     struct platform_data *my_data = (struct platform_data *)adev->platform;
-
     backend_idx = platform_get_backend_index(snd_device);
+    unsigned int bit_width = backend_cfg.bit_width;
+    unsigned int sample_rate = backend_cfg.sample_rate;
+    unsigned int channels = backend_cfg.channels;
+    audio_format_t format = backend_cfg.format;
+    bool passthrough_enabled = backend_cfg.passthrough_enabled;
 
-    ALOGI("%s:becf: afe: bitwidth %d, samplerate %d"
-          ", backend_idx %d device (%s)", __func__,  bit_width, sample_rate, backend_idx,
+    ALOGI("%s:becf: afe: bitwidth %d, samplerate %d channels %d"
+          ", backend_idx %d device (%s)", __func__,  bit_width, sample_rate, channels, backend_idx,
           platform_get_snd_device_name(snd_device));
 
     if (bit_width !=
@@ -4025,14 +4144,6 @@
               my_data->current_backend_cfg[backend_idx].bitwidth_mixer_ctl, bit_width, format);
     }
 
-    /*
-     * Backend sample rate configuration follows:
-     * 16 bit playback - 48khz for streams at any valid sample rate
-     * 24 bit playback - 48khz for stream sample rate less than 48khz
-     * 24 bit playback - 96khz for sample rate range of 48khz to 96khz
-     * 24 bit playback - 192khz for sample rate range of 96khz to 192 khz
-     * Upper limit is inclusive in the sample rate range.
-     */
     if (sample_rate !=
        my_data->current_backend_cfg[backend_idx].sample_rate) {
             char *rate_str = NULL;
@@ -4051,14 +4162,24 @@
                 rate_str = "KHZ_44P1";
                 break;
             case 64000:
-            case 88200:
             case 96000:
                 rate_str = "KHZ_96";
                 break;
+            case 88200:
+                rate_str = "KHZ_88P2";
+                break;
             case 176400:
+                rate_str = "KHZ_176P4";
+                break;
             case 192000:
                 rate_str = "KHZ_192";
                 break;
+            case 352800:
+                rate_str = "KHZ_352P8";
+                break;
+            case 384000:
+                rate_str = "KHZ_384";
+                break;
             default:
                 rate_str = "KHZ_48";
                 break;
@@ -4078,44 +4199,185 @@
             mixer_ctl_set_enum_by_string(ctl, rate_str);
             my_data->current_backend_cfg[backend_idx].sample_rate = sample_rate;
     }
+    if ((backend_idx == HDMI_RX_BACKEND) &&
+        (channels != my_data->current_backend_cfg[backend_idx].channels)) {
+        struct  mixer_ctl *ctl;
+        char *channel_cnt_str = NULL;
+
+        switch (channels) {
+        case 8:
+            channel_cnt_str = "Eight"; break;
+        case 7:
+            channel_cnt_str = "Seven"; break;
+        case 6:
+            channel_cnt_str = "Six"; break;
+        case 5:
+            channel_cnt_str = "Five"; break;
+        case 4:
+            channel_cnt_str = "Four"; break;
+        case 3:
+            channel_cnt_str = "Three"; break;
+        default:
+            channel_cnt_str = "Two"; break;
+        }
+
+        ctl = mixer_get_ctl_by_name(adev->mixer,
+           my_data->current_backend_cfg[backend_idx].channels_mixer_ctl);
+        if (!ctl) {
+            ALOGE("%s:becf: afe: Could not get ctl for mixer command - %s",
+                   __func__,
+                   my_data->current_backend_cfg[backend_idx].channels_mixer_ctl);
+            return -EINVAL;
+        }
+        mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
+        my_data->current_backend_cfg[backend_idx].channels = channels;
+        platform_set_edid_channels_configuration(adev->platform, channels);
+        ALOGD("%s:becf: afe: %s set to %s", __func__,
+               my_data->current_backend_cfg[backend_idx].channels_mixer_ctl, channel_cnt_str);
+    }
+
+    if (backend_idx == HDMI_RX_BACKEND) {
+        const char *hdmi_format_ctrl = "HDMI RX Format";
+        struct mixer_ctl *ctl;
+        ctl = mixer_get_ctl_by_name(adev->mixer,hdmi_format_ctrl);
+
+        if (!ctl) {
+            ALOGE("%s:becf: afe: Could not get ctl for mixer command - %s",
+                   __func__, hdmi_format_ctrl);
+            return -EINVAL;
+        }
+
+        if (passthrough_enabled) {
+            ALOGD("%s:HDMI compress format", __func__);
+            mixer_ctl_set_enum_by_string(ctl, "Compr");
+        } else {
+            ALOGD("%s: HDMI PCM format", __func__);
+            mixer_ctl_set_enum_by_string(ctl, "LPCM");
+        }
+    }
+
+    if (snd_device == SND_DEVICE_OUT_HEADPHONES || snd_device ==
+        SND_DEVICE_OUT_HEADPHONES_44_1) {
+        if (sample_rate > 48000 || (sample_rate == 48000 && bit_width >= 24)) {
+            ALOGV("%s: apply HPH HQ mode\n", __func__);
+            audio_route_apply_and_update_path(adev->audio_route, "hph-highquality-mode");
+        } else {
+            ALOGV("%s: apply HPH LP mode\n", __func__);
+            audio_route_apply_and_update_path(adev->audio_route, "hph-lowpower-mode");
+        }
+    }
 
     return ret;
 }
 
 /*
+ *Validate the selected bit_width, sample_rate and channels using the edid
+ *of the connected sink device.
+ */
+static void platform_check_hdmi_backend_cfg(struct audio_device* adev,
+                                   struct audio_usecase* usecase,
+                                   struct audio_backend_cfg *hdmi_backend_cfg)
+{
+    unsigned int bit_width;
+    unsigned int sample_rate;
+    unsigned int channels, max_supported_channels = 0;
+    struct platform_data *my_data = (struct platform_data *)adev->platform;
+    edid_audio_info *edid_info = (edid_audio_info *)my_data->edid_info;
+    bool passthrough_enabled = false;
+
+    bit_width = hdmi_backend_cfg->bit_width;
+    sample_rate = hdmi_backend_cfg->sample_rate;
+    channels = hdmi_backend_cfg->channels;
+
+
+    ALOGI("%s:becf: HDMI: bitwidth %d, samplerate %d, channels %d"
+          ", usecase = %d", __func__, bit_width,
+          sample_rate, channels, usecase->id);
+
+    if (audio_extn_passthru_is_enabled() && audio_extn_passthru_is_active()
+        && (usecase->stream.out->compr_config.codec->compr_passthr != 0)) {
+        passthrough_enabled = true;
+        ALOGI("passthrough is enabled for this stream");
+    }
+
+    // For voice calls use default configuration i.e. 16b/48K, only applicable to
+    // default backend
+    if (!passthrough_enabled) {
+
+        max_supported_channels = platform_edid_get_max_channels(my_data);
+
+        //Check EDID info for supported samplerate
+        if (!edid_is_supported_sr(edid_info,sample_rate)) {
+            //reset to current sample rate
+            sample_rate = my_data->current_backend_cfg[HDMI_RX_BACKEND].sample_rate;
+        }
+
+        //Check EDID info for supported bit width
+        if (!edid_is_supported_bps(edid_info,bit_width)) {
+            //reset to current sample rate
+            bit_width = my_data->current_backend_cfg[HDMI_RX_BACKEND].bit_width;
+        }
+
+        if (channels > max_supported_channels)
+            channels = max_supported_channels;
+
+    } else {
+        /*During pass through set default bit width and channels*/
+        channels = DEFAULT_HDMI_OUT_CHANNELS;
+        if ((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
+            (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC))
+            sample_rate = sample_rate * 4 ;
+
+        bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
+        /* We force route so that the BE format can be set to Compr */
+    }
+
+    ALOGI("%s:becf: afe: HDMI backend: passthrough %d updated bit width: %d and sample rate: %d"
+           "channels %d", __func__, passthrough_enabled , bit_width,
+           sample_rate, channels);
+
+    hdmi_backend_cfg->bit_width = bit_width;
+    hdmi_backend_cfg->sample_rate = sample_rate;
+    hdmi_backend_cfg->channels = channels;
+    hdmi_backend_cfg->passthrough_enabled = passthrough_enabled;
+}
+
+/*
  * goes through all the current usecases and picks the highest
  * bitwidth & samplerate
  */
 static bool platform_check_codec_backend_cfg(struct audio_device* adev,
                                    struct audio_usecase* usecase,
                                    snd_device_t snd_device,
-                                   unsigned int* new_bit_width,
-                                   unsigned int* new_sample_rate)
+                                   struct audio_backend_cfg *backend_cfg)
 {
     bool backend_change = false;
     struct listnode *node;
     unsigned int bit_width;
     unsigned int sample_rate;
+    unsigned int channels;
+    bool passthrough_enabled = false;
     int backend_idx = DEFAULT_CODEC_BACKEND;
     struct platform_data *my_data = (struct platform_data *)adev->platform;
     int na_mode = platform_get_native_support();
-    edid_audio_info *edid_info = (edid_audio_info *)my_data->edid_info;
+    bool channels_updated = false;
 
     backend_idx = platform_get_backend_index(snd_device);
 
-    bit_width = *new_bit_width;
-    sample_rate = *new_sample_rate;
+    bit_width = backend_cfg->bit_width;
+    sample_rate = backend_cfg->sample_rate;
+    channels = backend_cfg->channels;
 
-    ALOGI("%s:becf: afe: bitwidth %d, samplerate %d"
+    ALOGI("%s:becf: afe: bitwidth %d, samplerate %d channels %d"
           ", backend_idx %d usecase = %d device (%s)", __func__, bit_width,
-          sample_rate, backend_idx, usecase->id,
+          sample_rate, channels, backend_idx, usecase->id,
           platform_get_snd_device_name(snd_device));
 
     // For voice calls use default configuration i.e. 16b/48K, only applicable to
     // default backend
     // force routing is not required here, caller will do it anyway
     if ((voice_is_in_call(adev) || adev->mode == AUDIO_MODE_IN_COMMUNICATION) &&
-        backend_idx == DEFAULT_CODEC_BACKEND) {
+        usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) {
         ALOGW("%s:becf: afe:Use default bw and sr for voice/voip calls ",
               __func__);
         bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
@@ -4136,11 +4398,12 @@
             uc = node_to_item(node, struct audio_usecase, list);
             struct stream_out *out = (struct stream_out*) uc->stream.out;
             if (uc->type == PCM_PLAYBACK && out && usecase != uc) {
+                unsigned int out_channels = audio_channel_count_from_out_mask(out->channel_mask);
 
                 ALOGD("%s:napb: (%d) - (%s)id (%d) sr %d bw "
-                      "(%d) device %s", __func__, i++, use_case_table[uc->id],
+                      "(%d) ch (%d) device %s", __func__, i++, use_case_table[uc->id],
                       uc->id, out->sample_rate,
-                      out->bit_width,
+                      out->bit_width, out_channels,
                       platform_get_snd_device_name(uc->out_snd_device));
 
                 if (platform_check_backends_match(snd_device, uc->out_snd_device)) {
@@ -4150,6 +4413,8 @@
                             sample_rate = out->sample_rate;
                         if (out->sample_rate < OUTPUT_SAMPLING_RATE_44100)
                             sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+                        if (channels < out_channels)
+                            channels = out_channels;
                 }
             }
         }
@@ -4178,14 +4443,12 @@
     }
 
     /*
-     * hifi playback not supported on spkr devices, limit the Sample Rate
+     * hifi playback not supported on non-44.1-support devices, limit the Sample Rate
      * to 48 khz.
      */
-    if (SND_DEVICE_OUT_SPEAKER == snd_device ||
-        SND_DEVICE_OUT_SPEAKER_WSA == snd_device ||
-        SND_DEVICE_OUT_SPEAKER_VBAT == snd_device) {
+    if (check_44100_support_device(usecase->devices)) {
         sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
-        ALOGD("%s:becf: afe: playback on speaker device Configure afe to "
+        ALOGD("%s:becf: afe: playback on non-44.1-support device Configure afe to "
             "default Sample Rate(48k)", __func__);
     }
 
@@ -4207,29 +4470,57 @@
     }
 
     if (backend_idx == HDMI_RX_BACKEND) {
-        //Check EDID info for supported samplerate
-        if (!edid_is_supported_sr(edid_info,sample_rate)) {
-            //reset to current sample rate
-            sample_rate = my_data->current_backend_cfg[backend_idx].sample_rate;
-        }
-        //Check EDID info for supported bit widhth
-        if (!edid_is_supported_bps(edid_info,bit_width)) {
-            //reset to current sample rate
-            bit_width = my_data->current_backend_cfg[backend_idx].bit_width;
+        struct audio_backend_cfg hdmi_backend_cfg;
+        hdmi_backend_cfg.bit_width = bit_width;
+        hdmi_backend_cfg.sample_rate = sample_rate;
+        hdmi_backend_cfg.channels = channels;
+        hdmi_backend_cfg.passthrough_enabled = false;
+
+        platform_check_hdmi_backend_cfg(adev, usecase, &hdmi_backend_cfg);
+
+        bit_width = hdmi_backend_cfg.bit_width;
+        sample_rate = hdmi_backend_cfg.sample_rate;
+        channels = hdmi_backend_cfg.channels;
+        passthrough_enabled = hdmi_backend_cfg.passthrough_enabled;
+
+        if (channels != my_data->current_backend_cfg[backend_idx].channels)
+            channels_updated = true;
+    }
+
+    /*
+     * Map native sampling rates to upper limit range
+     * if multiple of native sampling rates are not supported.
+     */
+    if (NATIVE_AUDIO_MODE_MULTIPLE_44_1 != na_mode) {
+        switch (sample_rate) {
+            case 88200:
+                sample_rate = 96000;
+                break;
+            case 176400:
+                sample_rate = 192000;
+                break;
+            case 352800:
+                sample_rate = 192000;
+                break;
         }
     }
+
     ALOGI("%s:becf: afe: Codec selected backend: %d updated bit width: %d and sample rate: %d",
           __func__, backend_idx , bit_width, sample_rate);
 
     // Force routing if the expected bitwdith or samplerate
     // is not same as current backend comfiguration
     if ((bit_width != my_data->current_backend_cfg[backend_idx].bit_width) ||
-        (sample_rate != my_data->current_backend_cfg[backend_idx].sample_rate)) {
-        *new_bit_width = bit_width;
-        *new_sample_rate = sample_rate;
+        (sample_rate != my_data->current_backend_cfg[backend_idx].sample_rate) ||
+         passthrough_enabled || channels_updated) {
+        backend_cfg->bit_width = bit_width;
+        backend_cfg->sample_rate = sample_rate;
+        backend_cfg->channels = channels;
+        backend_cfg->passthrough_enabled = passthrough_enabled;
         backend_change = true;
-        ALOGI("%s:becf: afe: Codec backend needs to be updated. new bit width: %d new sample rate: %d",
-              __func__, *new_bit_width, *new_sample_rate);
+        ALOGI("%s:becf: afe: Codec backend needs to be updated. new bit width: %d"
+               "new sample rate: %d new channels: %d",
+              __func__, backend_cfg->bit_width, backend_cfg->sample_rate, backend_cfg->channels);
     }
 
     return backend_change;
@@ -4238,40 +4529,50 @@
 bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev,
     struct audio_usecase *usecase, snd_device_t snd_device)
 {
-    unsigned int new_bit_width;
-    unsigned int new_sample_rate;
     int backend_idx = DEFAULT_CODEC_BACKEND;
     int new_snd_devices[SND_DEVICE_OUT_END];
     int i, num_devices = 1;
     bool ret = false;
     struct platform_data *my_data = (struct platform_data *)adev->platform;
-    audio_format_t format;
+    struct audio_backend_cfg backend_cfg;
 
     backend_idx = platform_get_backend_index(snd_device);
 
-    new_bit_width = usecase->stream.out->bit_width;
-    new_sample_rate = usecase->stream.out->sample_rate;
-    format = usecase->stream.out->format;
+    backend_cfg.bit_width = usecase->stream.out->bit_width;
+    backend_cfg.sample_rate = usecase->stream.out->sample_rate;
+    backend_cfg.format = usecase->stream.out->format;
+    backend_cfg.channels = audio_channel_count_from_out_mask(usecase->stream.out->channel_mask);
+    /*this is populated by check_codec_backend_cfg hence set default value to false*/
+    backend_cfg.passthrough_enabled = false;
 
-    ALOGI("%s:becf: afe: bitwidth %d, samplerate %d"
-          ", backend_idx %d usecase = %d device (%s)", __func__, new_bit_width,
-          new_sample_rate, backend_idx, usecase->id,
+    /* Set Backend sampling rate to 176.4 for DSD64 and
+     * 352.8Khz for DSD128.
+     * Set Bit Width to 16
+     */
+    if ((backend_idx == DSD_NATIVE_BACKEND) && (backend_cfg.format == AUDIO_FORMAT_DSD)) {
+        backend_cfg.bit_width = 16;
+        if (backend_cfg.sample_rate == INPUT_SAMPLING_RATE_DSD64)
+            backend_cfg.sample_rate = OUTPUT_SAMPLING_RATE_DSD64;
+        else if (backend_cfg.sample_rate == INPUT_SAMPLING_RATE_DSD128)
+            backend_cfg.sample_rate = OUTPUT_SAMPLING_RATE_DSD128;
+    }
+    ALOGI("%s:becf: afe: bitwidth %d, samplerate %d channels %d"
+          ", backend_idx %d usecase = %d device (%s)", __func__, backend_cfg.bit_width,
+          backend_cfg.sample_rate, backend_cfg.channels, backend_idx, usecase->id,
           platform_get_snd_device_name(snd_device));
 
-
     if (!platform_can_split_snd_device(my_data, snd_device, &num_devices, new_snd_devices))
         new_snd_devices[0] = snd_device;
 
     for (i = 0; i < num_devices; i++) {
         ALOGI("%s: new_snd_devices[%d] is %d", __func__, i, new_snd_devices[i]);
-        if (platform_check_codec_backend_cfg(adev, usecase, new_snd_devices[i],
-                                             &new_bit_width, &new_sample_rate)) {
-                platform_set_codec_backend_cfg(adev, new_snd_devices[i],
-                                               new_bit_width, new_sample_rate, format);
-                ret = true;
+        if ((platform_check_codec_backend_cfg(adev, usecase, new_snd_devices[i],
+                                             &backend_cfg))) {
+            platform_set_codec_backend_cfg(adev, new_snd_devices[i],
+                                           backend_cfg);
+            ret = true;
         }
     }
-
     return ret;
 }
 
@@ -4936,6 +5237,7 @@
 
     //reset HDMI_RX_BACKEND to default values
     my_data->current_backend_cfg[HDMI_RX_BACKEND].sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+    my_data->current_backend_cfg[HDMI_RX_BACKEND].channels = DEFAULT_HDMI_OUT_CHANNELS;
     my_data->current_backend_cfg[HDMI_RX_BACKEND].bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
 }
 
@@ -4955,90 +5257,6 @@
     return mixer_ctl_set_enum_by_string(ctl, mixer_val);
 }
 
-static int set_mixer_control(struct mixer *mixer,
-                             const char * mixer_ctl_name,
-                             const char *mixer_val)
-{
-    struct mixer_ctl *ctl;
-    ALOGD("setting mixer ctl %s with value %s", mixer_ctl_name, mixer_val);
-    ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
-    if (!ctl) {
-        ALOGE("%s: could not get ctl for mixer cmd - %s",
-              __func__, mixer_ctl_name);
-        return -EINVAL;
-    }
-
-    return mixer_ctl_set_enum_by_string(ctl, mixer_val);
-}
-
-int platform_set_hdmi_config(void *platform, uint32_t channel_count,
-                             uint32_t sample_rate, bool enable_passthrough)
-{
-    struct platform_data *my_data = (struct platform_data *)platform;
-    struct audio_device *adev = my_data->adev;
-    const char *hdmi_format_ctrl = "HDMI RX Format";
-    const char *hdmi_rate_ctrl   = "HDMI_RX SampleRate";
-    const char *hdmi_chans_ctrl  = "HDMI_RX Channels";
-    const char *channel_cnt_str  = NULL;
-
-    ALOGI("%s ch[%d] sr[%d], pthru[%d]", __func__,
-        channel_count, sample_rate, enable_passthrough);
-
-    switch (channel_count) {
-    case 8:
-        channel_cnt_str = "Eight"; break;
-    case 7:
-        channel_cnt_str = "Seven"; break;
-    case 6:
-        channel_cnt_str = "Six"; break;
-    case 5:
-        channel_cnt_str = "Five"; break;
-    case 4:
-        channel_cnt_str = "Four"; break;
-    case 3:
-        channel_cnt_str = "Three"; break;
-    default:
-        channel_cnt_str = "Two"; break;
-    }
-    ALOGV("%s: HDMI channel count: %s", __func__, channel_cnt_str);
-    set_mixer_control(adev->mixer, hdmi_chans_ctrl, channel_cnt_str);
-
-    if (enable_passthrough) {
-        ALOGD("%s:HDMI compress format", __func__);
-        set_mixer_control(adev->mixer, hdmi_format_ctrl, "Compr");
-    } else {
-        ALOGD("%s: HDMI PCM format", __func__);
-        set_mixer_control(adev->mixer, hdmi_format_ctrl, "LPCM");
-    }
-
-    switch (sample_rate) {
-    case 32000:
-        set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_32");
-        break;
-    case 44100:
-        set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_44P1");
-        break;
-    case 96000:
-        set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_96");
-        break;
-    case 128000:
-        set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_128");
-        break;
-    case 176400:
-        set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_176_4");
-        break;
-    case 192000:
-        set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_192");
-        break;
-    default:
-    case 48000:
-        set_mixer_control(adev->mixer, hdmi_rate_ctrl, "KHZ_48");
-        break;
-    }
-
-    return 0;
-}
-
 int platform_set_device_params(struct stream_out *out, int param, int value)
 {
     struct audio_device *adev = out->dev;
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 019678a..9394ef8 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -80,6 +80,7 @@
     SND_DEVICE_OUT_SPEAKER_VBAT,
     SND_DEVICE_OUT_LINE,
     SND_DEVICE_OUT_HEADPHONES,
+    SND_DEVICE_OUT_HEADPHONES_DSD,
     SND_DEVICE_OUT_HEADPHONES_44_1,
     SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
     SND_DEVICE_OUT_SPEAKER_AND_LINE,
@@ -94,6 +95,8 @@
     SND_DEVICE_OUT_SPEAKER_AND_HDMI,
     SND_DEVICE_OUT_BT_SCO,
     SND_DEVICE_OUT_BT_SCO_WB,
+    SND_DEVICE_OUT_BT_A2DP,
+    SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP,
     SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES,
     SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES,
     SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET,
@@ -177,6 +180,7 @@
     SND_DEVICE_IN_SPEAKER_QMIC_AEC,
     SND_DEVICE_IN_SPEAKER_QMIC_NS,
     SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS,
+    SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE,
     SND_DEVICE_IN_THREE_MIC,
     SND_DEVICE_IN_HANDSET_TMIC,
     SND_DEVICE_IN_UNPROCESSED_MIC,
@@ -189,13 +193,18 @@
     SND_DEVICE_MAX = SND_DEVICE_IN_END,
 
 };
-
+#define INPUT_SAMPLING_RATE_DSD64       2822400
+#define INPUT_SAMPLING_RATE_DSD128      5644800
 #define DEFAULT_OUTPUT_SAMPLING_RATE    48000
 #define OUTPUT_SAMPLING_RATE_44100      44100
+#define OUTPUT_SAMPLING_RATE_DSD64       176400
+#define OUTPUT_SAMPLING_RATE_DSD128      352800
 #define MAX_CODEC_TX_BACKENDS           1
 enum {
     DEFAULT_CODEC_BACKEND,
     SLIMBUS_0_RX = DEFAULT_CODEC_BACKEND,
+    DSD_NATIVE_BACKEND,
+    SLIMBUS_2_RX = DSD_NATIVE_BACKEND,
     HEADPHONE_44_1_BACKEND,
     SLIMBUS_5_RX = HEADPHONE_44_1_BACKEND,
     HEADPHONE_BACKEND,
@@ -444,7 +453,8 @@
 enum {
     LEGACY_PCM = 0,
     PASSTHROUGH,
-    PASSTHROUGH_CONVERT
+    PASSTHROUGH_CONVERT,
+    PASSTHROUGH_DSD
 };
 /*
  * ID for setting mute and lateny on the device side
@@ -460,4 +470,13 @@
     char device_name[100];
     char interface_name[100];
 };
+
+struct audio_backend_cfg {
+    unsigned int   sample_rate;
+    unsigned int   channels;
+    unsigned int   bit_width;
+    bool           passthrough_enabled;
+    audio_format_t format;
+};
+
 #endif // QCOM_AUDIO_PLATFORM_H
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 0bb73f3..ec64206 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -27,6 +27,7 @@
 enum {
     NATIVE_AUDIO_MODE_SRC = 1,
     NATIVE_AUDIO_MODE_TRUE_44_1,
+    NATIVE_AUDIO_MODE_MULTIPLE_44_1,
     NATIVE_AUDIO_MODE_INVALID
 };
 
@@ -36,6 +37,8 @@
     int na_mode;
 } native_audio_prop;
 
+enum card_status_t;
+
 void *platform_init(struct audio_device *adev);
 void platform_deinit(void *platform);
 const char *platform_get_snd_device_name(snd_device_t snd_device);
@@ -151,4 +154,8 @@
                           bool enable,
                           char * str);
 bool platform_supports_true_32bit();
+bool platform_check_if_backend_has_to_be_disabled(snd_device_t new_snd_device, snd_device_t cuurent_snd_device);
+bool platform_check_codec_dsd_support(void *platform);
+bool platform_check_codec_asrc_support(void *platform);
+int platform_get_backend_index(snd_device_t snd_device);
 #endif // AUDIO_PLATFORM_API_H
diff --git a/hal/voice_extn/compress_voip.c b/hal/voice_extn/compress_voip.c
index 7293485..3222e0b 100644
--- a/hal/voice_extn/compress_voip.c
+++ b/hal/voice_extn/compress_voip.c
@@ -244,6 +244,7 @@
 {
     int ret = 0;
     struct audio_usecase *uc_info;
+    struct listnode *node;
 
     ALOGD("%s: enter, out_stream_count=%d, in_stream_count=%d",
            __func__, voip_data.out_stream_count, voip_data.in_stream_count);
@@ -277,6 +278,12 @@
 
         list_remove(&uc_info->list);
         free(uc_info);
+
+        // restore device for other active usecases
+        list_for_each(node, &adev->usecase_list) {
+            uc_info = node_to_item(node, struct audio_usecase, list);
+            select_devices(adev, uc_info->id);
+        }
     } else
         ALOGV("%s: NO-OP because out_stream_count=%d, in_stream_count=%d",
                __func__, voip_data.out_stream_count, voip_data.in_stream_count);
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index 122ac14..015ea25 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -511,6 +511,14 @@
             ALOGD("offload disabled for multi-channel FLAC/ALAC/WMA/AAC_ADTS clips with sample rate > 48kHz");
         return false;
     }
+
+    if ((((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_WMA) && (offloadInfo.bit_rate > MAX_BITRATE_WMA)) ||
+        (((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_WMA_PRO) && (offloadInfo.bit_rate > MAX_BITRATE_WMA_PRO)) ||
+        (((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_WMA_PRO) && (offloadInfo.bit_rate > MAX_BITRATE_WMA_LOSSLESS))){
+        //Safely choose the min bitrate as threshold and leave the restriction to NT decoder as we can't distinguish wma pro and wma lossless here.
+        ALOGD("offload disabled for WMA/WMA_PRO/WMA_LOSSLESS clips with bit rate over maximum supported value");
+        return false;
+    }
 #endif
     //TODO: enable audio offloading with video when ready
     const bool allowOffloadWithVideo =
diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h
index dfda1c9..deef57d 100644
--- a/policy_hal/AudioPolicyManager.h
+++ b/policy_hal/AudioPolicyManager.h
@@ -39,6 +39,10 @@
 #ifndef AUDIO_EXTN_AFE_PROXY_ENABLED
 #define AUDIO_DEVICE_OUT_PROXY 0x1000000
 #endif
+
+#define MAX_BITRATE_WMA          384000
+#define MAX_BITRATE_WMA_PRO      1536000
+#define MAX_BITRATE_WMA_LOSSLESS 1152000
 // ----------------------------------------------------------------------------
 
 class AudioPolicyManagerCustom: public AudioPolicyManager