Merge "policy_hal: add bitrate restriction for wma/wma_pro/wma_lossless" into audio-userspace.lnx.2.1-dev
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/msmcobalt/audio_policy_configuration.xml b/configs/msmcobalt/audio_policy_configuration.xml
index b7da238..4bde15c 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>
@@ -143,10 +141,6 @@
                              samplingRates="2822400,5644800"
                              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>
                 <mixPort name="voip_rx" role="source"
                          flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_VOIP_RX">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
@@ -174,10 +168,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>
@@ -218,10 +208,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"/>
@@ -246,6 +232,10 @@
                     <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"
@@ -271,9 +261,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 -->
@@ -296,16 +288,14 @@
                        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"
@@ -339,7 +329,24 @@
         </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/mixer_paths_tasha.xml b/configs/msmcobalt/mixer_paths_tasha.xml
index eb5a150..d096d1f 100644
--- a/configs/msmcobalt/mixer_paths_tasha.xml
+++ b/configs/msmcobalt/mixer_paths_tasha.xml
@@ -1641,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" />
@@ -1668,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" />
@@ -1768,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>
 
@@ -1825,7 +1825,7 @@
     </path>
 
     <path name="handset-mic">
-        <path name="dmic1" />
+        <path name="dmic3" />
     </path>
 
     <path name="handset-mic-db">
@@ -1852,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">
@@ -1867,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>
@@ -2159,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>
 
@@ -2175,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>
 
@@ -2187,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>
 
@@ -2262,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" />
@@ -2286,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">
@@ -2373,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">
diff --git a/configs/msmcobalt/mixer_paths_tavil.xml b/configs/msmcobalt/mixer_paths_tavil.xml
index 98b9bbf..dab6cac 100644
--- a/configs/msmcobalt/mixer_paths_tavil.xml
+++ b/configs/msmcobalt/mixer_paths_tavil.xml
@@ -45,6 +45,22 @@
     <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="DEC5 Volume" value="84" />
+    <ctl name="DEC6 Volume" value="84" />
+    <ctl name="DEC7 Volume" value="84" />
+    <ctl name="DEC8 Volume" value="84" />
+    <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="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" />
@@ -92,36 +108,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" />
@@ -147,9 +173,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" />
@@ -289,12 +319,22 @@
     <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" />
@@ -309,6 +349,16 @@
     <ctl name="SpkrRight VISENSE Switch" value="0" />
     <ctl name="SpkrLeft SWR DAC_Port Switch" value="0" />
     <ctl name="SpkrRight SWR DAC_Port Switch" 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" />
@@ -316,6 +366,10 @@
     <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="AIF1_CAP Mixer SLIM TX0" value="0" />
@@ -565,6 +619,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" />
@@ -613,6 +671,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" />
@@ -661,6 +723,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" />
@@ -709,6 +775,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" />
@@ -757,6 +827,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" />
@@ -805,6 +879,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" />
@@ -853,6 +931,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" />
@@ -901,6 +983,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" />
@@ -949,6 +1035,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" />
@@ -1297,33 +1387,51 @@
 
     <!-- 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">
@@ -1385,11 +1493,11 @@
     </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">
@@ -1438,7 +1546,7 @@
     </path>
 
     <path name="handset-mic">
-        <path name="dmic1" />
+        <path name="dmic3" />
     </path>
 
     <path name="handset-mic-db">
@@ -1452,6 +1560,19 @@
     </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">
@@ -1461,11 +1582,38 @@
         <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" />
     </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">
@@ -1618,9 +1766,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">
@@ -1684,6 +1850,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">
@@ -1696,6 +1871,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">
diff --git a/configs/msmcobalt/msmcobalt.mk b/configs/msmcobalt/msmcobalt.mk
index 43aeb1a..9b74162 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
@@ -200,4 +200,9 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 use.qti.sw.alac.decoder=true
 PRODUCT_PROPERTY_OVERRIDES += \
-use.qti.sw.ape.decoder=true
\ No newline at end of file
+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..3c75b8e
--- /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" "DMIC0" />
+        <ctl name="MAD_SEL MUX" "SPE" />
+        <ctl name="MAD_INP MUX" "MAD" />
+        <ctl name="MAD_CPE1 Switch" 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..1f90bd5 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,18 @@
         <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>
+
+        <!-- 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 +73,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 adee78b..705e5e8 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -285,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
@@ -307,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/audio_extn.h b/hal/audio_extn/audio_extn.h
index d186a5f..0fd7d3a 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -401,6 +401,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)
@@ -419,8 +423,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);
@@ -586,4 +588,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/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/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 af399a1..b617407 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -82,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
@@ -501,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)
@@ -541,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;
@@ -616,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;
@@ -767,7 +802,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;
 }
@@ -824,6 +860,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);
@@ -895,7 +936,9 @@
             ((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_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));
@@ -1166,6 +1209,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)
 {
@@ -2537,6 +2602,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)
 {
@@ -2555,6 +2628,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;
@@ -3666,12 +3753,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);
@@ -3681,6 +3780,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) {
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index ee28157..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 {
@@ -389,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,
@@ -410,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 738df09..9c6cc6f 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -2448,7 +2448,7 @@
     return ret;
 }
 
-static int platform_get_backend_index(snd_device_t snd_device)
+int platform_get_backend_index(snd_device_t snd_device)
 {
     int32_t port = DEFAULT_CODEC_BACKEND;
 
@@ -5408,3 +5408,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 dcd351a..6c89d0a 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -198,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
@@ -208,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,
@@ -356,7 +361,8 @@
 enum {
     LEGACY_PCM = 0,
     PASSTHROUGH,
-    PASSTHROUGH_CONVERT
+    PASSTHROUGH_CONVERT,
+    PASSTHROUGH_DSD
 };
 /*
  * ID for setting mute and lateny on the device side
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 e42af8c..07060b6 100644
--- a/hal/msm8960/platform.h
+++ b/hal/msm8960/platform.h
@@ -112,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 fc706f8..7d6f02b 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -247,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] = {
@@ -334,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",
@@ -451,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,
@@ -568,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)},
@@ -1102,11 +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");
@@ -1715,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 =
@@ -1745,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 =
@@ -1907,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;
@@ -2092,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__,
@@ -2107,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;
@@ -2159,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",
@@ -2238,7 +2298,7 @@
     return ret;
 }
 
-static int platform_get_backend_index(snd_device_t snd_device)
+int platform_get_backend_index(snd_device_t snd_device)
 {
     int32_t port = DEFAULT_CODEC_BACKEND;
 
@@ -2247,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;
@@ -2764,6 +2827,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) {
@@ -4070,14 +4139,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;
@@ -4096,14 +4157,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;
@@ -4180,6 +4251,17 @@
         }
     }
 
+    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;
 }
 
@@ -4400,6 +4482,24 @@
             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);
 
@@ -4440,6 +4540,17 @@
     /*this is populated by check_codec_backend_cfg hence set default value to false*/
     backend_cfg.passthrough_enabled = false;
 
+    /* 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,
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 48bfb2b..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,
@@ -192,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,
@@ -447,7 +453,8 @@
 enum {
     LEGACY_PCM = 0,
     PASSTHROUGH,
-    PASSTHROUGH_CONVERT
+    PASSTHROUGH_CONVERT,
+    PASSTHROUGH_DSD
 };
 /*
  * ID for setting mute and lateny on the device side
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