Merge "hal: add tri-mic device definitions to source tracking"
diff --git a/configs/msm8909/audio_policy_configuration.xml b/configs/msm8909/audio_policy_configuration.xml
index 8690288..8abf817 100644
--- a/configs/msm8909/audio_policy_configuration.xml
+++ b/configs/msm8909/audio_policy_configuration.xml
@@ -100,7 +100,7 @@
                     <profile name="" format="AUDIO_FORMAT_EVRCNW"
                              samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
                 </mixPort>
-                <mixPort name="primary input" role="sink">
+                <mixPort name="primary input" role="sink" maxOpenCount="2" maxActiveCount="2">
                      <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
                              channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
diff --git a/configs/msm8909/msm8909.mk b/configs/msm8909/msm8909.mk
index efe1d32..527533d 100755
--- a/configs/msm8909/msm8909.mk
+++ b/configs/msm8909/msm8909.mk
@@ -136,11 +136,8 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 vendor.audio.dolby.ds2.enabled=true
 
-ifneq ($(strip $(TARGET_HAS_LOW_RAM)),true)
-PRODUCT_PACKAGES += android.hardware.audio@2.0-service
-endif
-
 PRODUCT_PACKAGES += \
+    android.hardware.audio@2.0-service \
     android.hardware.audio@2.0-impl \
     android.hardware.audio.effect@2.0-impl \
     android.hardware.soundtrigger@2.0-impl
diff --git a/configs/msm8937/audio_policy_configuration.xml b/configs/msm8937/audio_policy_configuration.xml
index b2b26a2..b4b0358 100644
--- a/configs/msm8937/audio_policy_configuration.xml
+++ b/configs/msm8937/audio_policy_configuration.xml
@@ -137,7 +137,7 @@
                              samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
                 </mixPort>
 
-                <mixPort name="primary input" role="sink">
+                <mixPort name="primary input" role="sink" maxOpenCount="2" maxActiveCount="2">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
                              channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
diff --git a/configs/msm8953/audio_policy_configuration.xml b/configs/msm8953/audio_policy_configuration.xml
index 424a436..f54d6b4 100644
--- a/configs/msm8953/audio_policy_configuration.xml
+++ b/configs/msm8953/audio_policy_configuration.xml
@@ -137,7 +137,7 @@
                              samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
                 </mixPort>
 
-                <mixPort name="primary input" role="sink">
+                <mixPort name="primary input" role="sink" maxOpenCount="2" maxActiveCount="2">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
                              channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
diff --git a/configs/msm8953/mixer_paths.xml b/configs/msm8953/mixer_paths.xml
index a20c6cf..2e3f46d 100644
--- a/configs/msm8953/mixer_paths.xml
+++ b/configs/msm8953/mixer_paths.xml
@@ -376,6 +376,11 @@
         <ctl name="INTERNAL_BT_SCO_RX Audio Mixer MultiMedia7" value="1" />
     </path>
 
+    <path name="compress-offload-playback2 bt-sco-wb">
+        <ctl name="Internal BTSCO SampleRate" value="BTSCO_RATE_16KHZ" />
+        <path name="compress-offload-playback2 bt-sco" />
+    </path>
+
     <path name="compress-offload-playback transmission-fm">
         <ctl name="INTERNAL_FM_RX Audio Mixer MultiMedia4" value="1" />
     </path>
diff --git a/configs/msm8953/mixer_paths_mtp.xml b/configs/msm8953/mixer_paths_mtp.xml
index 616b31a..7fd1fc5 100644
--- a/configs/msm8953/mixer_paths_mtp.xml
+++ b/configs/msm8953/mixer_paths_mtp.xml
@@ -439,6 +439,11 @@
         <ctl name="INTERNAL_BT_SCO_RX Audio Mixer MultiMedia7" value="1" />
     </path>
 
+    <path name="compress-offload-playback2 bt-sco-wb">
+        <ctl name="Internal BTSCO SampleRate" value="BTSCO_RATE_16KHZ" />
+        <path name="compress-offload-playback2 bt-sco" />
+    </path>
+
     <path name="compress-offload-playback2 hdmi">
         <ctl name="QUIN_MI2S_RX Audio Mixer MultiMedia7" value="1" />
     </path>
diff --git a/configs/msm8953/mixer_paths_qrd_skum.xml b/configs/msm8953/mixer_paths_qrd_skum.xml
index d504456..536debc 100644
--- a/configs/msm8953/mixer_paths_qrd_skum.xml
+++ b/configs/msm8953/mixer_paths_qrd_skum.xml
@@ -362,6 +362,11 @@
         <ctl name="INTERNAL_BT_SCO_RX Audio Mixer MultiMedia7" value="1" />
     </path>
 
+    <path name="compress-offload-playback2 bt-sco-wb">
+        <ctl name="Internal BTSCO SampleRate" value="BTSCO_RATE_16KHZ" />
+        <path name="compress-offload-playback2 bt-sco" />
+    </path>
+
     <path name="compress-offload-playback transmission-fm">
         <ctl name="INTERNAL_FM_RX Audio Mixer MultiMedia4" value="1" />
     </path>
diff --git a/configs/msm8996/audio_policy_configuration.xml b/configs/msm8996/audio_policy_configuration.xml
index 815f071..9b0234b 100644
--- a/configs/msm8996/audio_policy_configuration.xml
+++ b/configs/msm8996/audio_policy_configuration.xml
@@ -137,7 +137,7 @@
                              samplingRates="8000,16000,32000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
                 </mixPort>
 
-                <mixPort name="primary input" role="sink">
+                <mixPort name="primary input" role="sink" maxOpenCount="2" maxActiveCount="2">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
                              channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
diff --git a/configs/msm8998/audio_policy_configuration.xml b/configs/msm8998/audio_policy_configuration.xml
index 929e8f2..6c14ce4 100644
--- a/configs/msm8998/audio_policy_configuration.xml
+++ b/configs/msm8998/audio_policy_configuration.xml
@@ -171,7 +171,7 @@
                              samplingRates="8000,16000,32000,48000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
                 </mixPort>
 
-                <mixPort name="primary input" role="sink">
+                <mixPort name="primary input" role="sink" maxOpenCount="2" maxActiveCount="2">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
                              channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
diff --git a/configs/msmnile/audio_policy_configuration.xml b/configs/msmnile/audio_policy_configuration.xml
index 25ac786..a86b5da 100644
--- a/configs/msmnile/audio_policy_configuration.xml
+++ b/configs/msmnile/audio_policy_configuration.xml
@@ -171,7 +171,7 @@
                              samplingRates="8000,16000,32000,48000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
                 </mixPort>
 
-                <mixPort name="primary input" role="sink">
+                <mixPort name="primary input" role="sink" maxOpenCount="2" maxActiveCount="2">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
                              channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
@@ -272,11 +272,11 @@
                 </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"/>
+                             samplingRates="44100,48000,64000,88200,96000,128000,176400,192000" channelMasks="dynamic"/>
                 </devicePort>
                 <devicePort tagName="USB Headset Out" type="AUDIO_DEVICE_OUT_USB_HEADSET" 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"/>
+                             samplingRates="44100,48000,64000,88200,96000,128000,176400,192000" channelMasks="dynamic"/>
                 </devicePort>
 
                 <!-- Input devices declaration, i.e. Source DEVICE PORT -->
diff --git a/configs/msmnile/mixer_paths_tavil.xml b/configs/msmnile/mixer_paths_tavil.xml
old mode 100644
new mode 100755
index b0d6caf..2e0f9c5
--- a/configs/msmnile/mixer_paths_tavil.xml
+++ b/configs/msmnile/mixer_paths_tavil.xml
@@ -2007,10 +2007,26 @@
         <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="DMIC MUX5" value="DMIC2" />
         <ctl name="CDC_IF TX6 MUX" value="DEC6" />
         <ctl name="ADC MUX6" value="DMIC" />
-        <ctl name="DMIC MUX6" value="DMIC2" />
+        <ctl name="DMIC MUX6" value="DMIC0" />
+        <ctl name="CDC_IF TX8 MUX" value="DEC8" />
+        <ctl name="ADC MUX8" value="DMIC" />
+        <ctl name="DMIC MUX8" value="DMIC5" />
+    </path>
+
+    <path name="three-mic-qrd">
+        <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="DMIC2" />
+        <ctl name="CDC_IF TX6 MUX" value="DEC6" />
+        <ctl name="ADC MUX6" value="DMIC" />
+        <ctl name="DMIC MUX6" value="DMIC3" />
         <ctl name="CDC_IF TX8 MUX" value="DEC8" />
         <ctl name="ADC MUX8" value="DMIC" />
         <ctl name="DMIC MUX8" value="DMIC5" />
@@ -2145,6 +2161,10 @@
         <path name="speaker-mic" />
     </path>
 
+    <path name="voice-speaker-mic-qrd">
+        <path name="speaker-mic-qrd" />
+    </path>
+
     <path name="voice-headphones">
         <path name="headphones" />
     </path>
@@ -2298,6 +2318,24 @@
         <ctl name="IIR0 INP0 MUX" value="DEC6" />
     </path>
 
+    <path name="aanc-handset-mic-qrd">
+        <ctl name="AIF1_CAP Mixer SLIM TX6" value="1" />
+        <ctl name="AIF1_CAP Mixer SLIM TX8" value="1" />
+        <ctl name="AIF1_CAP Mixer SLIM TX9" value="1" />
+        <ctl name="SLIM_0_TX Channels" value="Three" />
+        <ctl name="AANC_SLIM_0_RX MUX" value="SLIMBUS_0_TX" />
+        <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="DMIC0" />
+        <ctl name="CDC_IF TX9 MUX" value="DEC7" />
+        <ctl name="ADC MUX7" value="DMIC" />
+        <ctl name="DMIC MUX7" value="DMIC5" />
+        <ctl name="IIR0 INP0 MUX" value="DEC6" />
+    </path>
+
     <!-- Dual MIC devices -->
     <path name="handset-dmic-endfire">
         <ctl name="AIF1_CAP Mixer SLIM TX7" value="1" />
@@ -2323,6 +2361,30 @@
         <ctl name="SLIM_0_TX Channels" value="Two" />
     </path>
 
+    <path name="handset-dmic-endfire-qrd">
+        <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="DMIC5" />
+        <ctl name="SLIM_0_TX Channels" value="Two" />
+    </path>
+
+    <path name="speaker-dmic-endfire-qrd">
+        <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="DMIC0" />
+        <ctl name="SLIM_0_TX Channels" value="Two" />
+    </path>
+
     <path name="dmic-endfire">
         <path name="handset-dmic-endfire" />
         <ctl name="IIR0 INP0 MUX" value="DEC7" />
@@ -2333,6 +2395,10 @@
         <ctl name="IIR0 INP0 MUX" value="DEC7" />
     </path>
 
+    <path name="dmic-endfire-qrd">
+        <path name="handset-dmic-endfire-qrd" />
+    </path>
+
     <path name="handset-stereo-dmic-ef">
         <path name="handset-dmic-endfire" />
     </path>
@@ -2385,6 +2451,22 @@
         <path name="dmic-endfire-liquid" />
     </path>
 
+    <path name="handset-stereo-dmic-ef-qrd">
+        <path name="handset-dmic-endfire-qrd" />
+    </path>
+
+    <path name="speaker-stereo-dmic-ef-qrd">
+        <path name="speaker-dmic-endfire-qrd" />
+    </path>
+
+    <path name="voice-dmic-ef-qrd">
+        <path name="dmic-endfire-qrd" />
+    </path>
+
+    <path name="voice-speaker-dmic-ef-qrd">
+        <path name="speaker-dmic-endfire-qrd" />
+    </path>
+
     <path name="speaker-dmic-broadside">
         <ctl name="AIF1_CAP Mixer SLIM TX7" value="1" />
         <ctl name="AIF1_CAP Mixer SLIM TX8" value="1" />
@@ -2423,10 +2505,30 @@
         <ctl name="DMIC MUX7" value="DMIC5" />
     </path>
 
+    <path name="speaker-tmic-qrd">
+        <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="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="DMIC2" />
+        <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="DMIC5" />
+    </path>
+
     <path name="voice-speaker-tmic">
         <path name="speaker-tmic" />
     </path>
 
+    <path name="voice-speaker-tmic-qrd">
+        <path name="speaker-tmic-qrd" />
+    </path>
+
     <!-- Quad MIC devices -->
     <path name="speaker-qmic">
         <ctl name="AIF1_CAP Mixer SLIM TX5" value="1" />
@@ -2436,13 +2538,33 @@
         <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="DMIC MUX5" value="DMIC2" />
         <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="DMIC MUX7" value="DMIC5" />
+        <ctl name="CDC_IF TX8 MUX" value="DEC8" />
+        <ctl name="ADC MUX8" value="DMIC" />
+        <ctl name="DMIC MUX8" value="DMIC4" />
+    </path>
+
+    <path name="speaker-qmic-qrd">
+        <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="DMIC2" />
+        <ctl name="CDC_IF TX6 MUX" value="DEC6" />
+        <ctl name="ADC MUX6" value="DMIC" />
+        <ctl name="DMIC MUX6" value="DMIC3" />
+        <ctl name="CDC_IF TX7 MUX" value="DEC7" />
+        <ctl name="ADC MUX7" value="DMIC" />
+        <ctl name="DMIC MUX7" value="DMIC0" />
         <ctl name="CDC_IF TX8 MUX" value="DEC8" />
         <ctl name="ADC MUX8" value="DMIC" />
         <ctl name="DMIC MUX8" value="DMIC5" />
@@ -2467,6 +2589,14 @@
         <path name="speaker-qmic-liquid" />
     </path>
 
+    <path name="quad-mic-qrd">
+        <path name="speaker-qmic-qrd" />
+    </path>
+
+    <path name="voice-speaker-qmic-qrd">
+        <path name="speaker-qmic-qrd" />
+    </path>
+
     <!-- TTY devices -->
 
     <path name="tty-headphones">
diff --git a/configs/msmnile/msmnile.mk b/configs/msmnile/msmnile.mk
index 84387b7..f89e498 100644
--- a/configs/msmnile/msmnile.mk
+++ b/configs/msmnile/msmnile.mk
@@ -66,6 +66,7 @@
 AUDIO_FEATURE_ENABLED_SND_MONITOR := true
 AUDIO_FEATURE_ENABLED_DLKM := true
 AUDIO_FEATURE_ENABLED_USB_BURST_MODE := true
+AUDIO_FEATURE_ENABLED_SVA_MULTI_STAGE := true
 ##AUDIO_FEATURE_FLAGS
 
 ifneq ($(strip $(TARGET_USES_QSSI)), true)
@@ -240,4 +241,10 @@
     android.hardware.audio@2.0-service \
     android.hardware.audio@2.0-impl \
     android.hardware.audio.effect@2.0-impl \
-    android.hardware.soundtrigger@2.1-impl
+    android.hardware.soundtrigger@2.1-impl \
+    android.hardware.audio@4.0 \
+    android.hardware.audio.common@4.0 \
+    android.hardware.audio.common@4.0-util \
+    android.hardware.audio@4.0-impl \
+    android.hardware.audio.effect@4.0 \
+    android.hardware.audio.effect@4.0-impl
diff --git a/configs/msmnile/sound_trigger_platform_info.xml b/configs/msmnile/sound_trigger_platform_info.xml
index 3f14715..27a6c04 100644
--- a/configs/msmnile/sound_trigger_platform_info.xml
+++ b/configs/msmnile/sound_trigger_platform_info.xml
@@ -26,11 +26,14 @@
 <!--- OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN    -->
 <!--- IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                             -->
 <sound_trigger_platform_info>
-    <param version="0x0102" /> <!-- this must be the first param -->
+    <param version="0x0103" /> <!-- this must be the first param -->
 <!--- Version History:                                                          -->
 <!--- 0x0101: Legacy version.                                                   -->
 <!--- 0x0102: Includes acdb_ids param with the gcs_usecase tag. This matches    -->
 <!--- the gcs_usecase with the acdb device that uses it.                        -->
+<!--- 0x0103: app_type and in_channels added to <lsm usecase> and out_channels  -->
+<!--- added to <adm_config>                                                     -->
+
     <common_config>
         <param max_cpe_sessions="1" />
         <param max_wdsp_sessions="2" />
@@ -65,8 +68,7 @@
     <!-- QTI SVA -->
     <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 execution_type="DYNAMIC" /> <!-- value: "WDSP" "ADSP" "DYNAMIC" -->
         <param library="libsmwrapper.so" />
         <param max_cpe_phrases="6" />
         <param max_cpe_users="3" />
@@ -75,13 +77,15 @@
         <!-- Profile specific data which the algorithm can support -->
         <param sample_rate="16000" />
         <param bit_width="16" />
-        <param channel_count="1"/>
+        <param out_channels="1"/> <!-- Module output channels -->
+
         <!-- adm_cfg_profile should match with the one defined under adm_config -->
         <!-- Set it to NONE if LSM directly connects to AFE -->
-        <param adm_cfg_profile="NONE" />
-        <!-- fluence_type: "FLUENCE", "FLUENCE_DMIC", "FLUENCE_TMIC", -->
-        <!-- "FLUENCE_QMIC". param value is valid when adm_cfg_profile="FLUENCE"-->
-        <param fluence_type="FLUENCE_DMIC" />
+        <param adm_cfg_profile="FFECNS" />
+        <!-- fluence_type: "FLUENCE", "FLUENCE_DMIC", "FLUENCE_TMIC"   -->
+        <!-- "FLUENCE_QMIC". Param value is valid when adm_cfg_profile -->
+        <!-- is one of FLUENCE, FLUENCE_STEREO, FFECNS values          -->
+        <param fluence_type="FLUENCE_TMIC" />
         <!-- wdsp_fluence_type: fluence disabled: "NONE" -->
         <!-- fluence enabled: "FLUENCE_DMIC", "FLUENCE_TMIC", "FLUENCE_QMIC" -->
         <param wdsp_fluence_type="NONE" />
@@ -153,6 +157,8 @@
             valid execution_type values: "WDSP" "ADSP" -->
         <lsm_usecase>
             <param execution_mode="ADSP" />
+            <param app_type="2" /> <!-- app type used in ACDB -->
+            <param in_channels="5"/> <!-- Module input channels -->
             <param load_sound_model_ids="0x00012C1C, 0x00012C14" />
             <param unload_sound_model_ids="0x00012C1C, 0x00012C15" />
             <param confidence_levels_ids="0x00012C1C, 0x00012C07" />
@@ -161,15 +167,6 @@
             <param custom_config_ids="0x00012C1C, 0x00012C20" />
         </lsm_usecase>
 
-        <lsm_usecase>
-            <param execution_mode="WDSP" />
-            <param load_sound_model_ids="0x00012C0D, 0x00012C14" />
-            <param unload_sound_model_ids="0x00012C0D, 0x00012C15" />
-            <param confidence_levels_ids="0x00012C0D, 0x00012C07" />
-            <param operation_mode_ids="0x00012C0D, 0x00012C02" />
-            <param custom_config_ids="0x00012C0D, 0x00012C20" />
-        </lsm_usecase>
-
         <!-- format: "ADPCM_packet" or "PCM_packet" !-->
         <!-- transfer_mode: "FTRT" or "RT" -->
         <!--  kw_duration is in milli seconds. It is valid only for FTRT
@@ -182,7 +179,6 @@
     <sound_model_config>
         <param vendor_uuid="876c1b46-9d4d-40cc-a4fd-4d5ec7a80e47" />
         <param execution_type="WDSP" /> <!-- value: "WDSP" "ADSP" "DYNAMIC" -->
-        <param app_type="4" /> <!-- app type for MD used in ACDB -->
         <param library="libsmwrapper.so" />
         <param max_cpe_phrases="1" />
         <param max_cpe_users="1" />
@@ -191,12 +187,13 @@
         <!-- Profile specific data which the algorithm can support -->
         <param sample_rate="16000" />
         <param bit_width="16" />
-        <param channel_count="1"/>
+        <param out_channels="1"/> <!-- Module output channels -->
         <!-- adm_cfg_profile should match with the one defined under adm_config -->
         <!-- Set it to NONE if LSM directly connects to AFE -->
         <param adm_cfg_profile="NONE" />
-        <!-- fluence_type: "FLUENCE", "FLUENCE_DMIC", "FLUENCE_TMIC", -->
-        <!-- "FLUENCE_QMIC". param value is valid when adm_cfg_profile="FLUENCE"-->
+        <!-- fluence_type: "FLUENCE", "FLUENCE_DMIC", "FLUENCE_TMIC"   -->
+        <!-- "FLUENCE_QMIC". Param value is valid when adm_cfg_profile -->
+        <!-- is one of FLUENCE, FLUENCE_STEREO, FFECNS values          -->
         <param fluence_type="FLUENCE_DMIC" />
         <!-- wdsp_fluence_type: fluence disabled: "NONE" -->
         <!-- fluence enabled: "FLUENCE_DMIC", "FLUENCE_TMIC", "FLUENCE_QMIC" -->
@@ -219,6 +216,8 @@
             valid execution_type values: only "ADSP" -->
         <lsm_usecase>
             <param execution_mode="ADSP" />
+            <param app_type="4" /> <!-- app type for MD used in ACDB -->
+            <param in_channels="1"/> <!-- Module input channels -->
             <param load_sound_model_ids="0x00012C22, 0x00012C14" />
             <param unload_sound_model_ids="0x00012C22, 0x00012C15" />
             <param confidence_levels_ids="0x00012C22, 0x00012C07" />
@@ -238,7 +237,6 @@
     <sound_model_config>
         <param vendor_uuid="7038ddc8-30f2-11e6-b0ac-40a8f03d3f15" />
         <param execution_type="WDSP" /> <!-- value: "WDSP" "ADSP" "DYNAMIC" -->
-        <param app_type="3" /> <!-- app type used in ACDB -->
         <param library="none" />
         <param max_cpe_phrases="1" />
         <param max_cpe_users="1" />
@@ -247,12 +245,13 @@
         <!-- Profile specific data which the algorithm can support -->
         <param sample_rate="16000" />
         <param bit_width="16" />
-        <param channel_count="1"/>
+        <param out_channels="1"/> <!-- Module output channels -->
         <!-- adm_cfg_profile should match with the one defined under adm_config -->
         <!-- Set it to NONE if LSM directly connects to AFE -->
         <param adm_cfg_profile="NONE" />
-        <!-- fluence_type: "FLUENCE", "FLUENCE_DMIC" -->
-        <!-- "FLUENCE_QMIC". param value is valid when adm_cfg_profile="FLUENCE"-->
+        <!-- fluence_type: "FLUENCE", "FLUENCE_DMIC", "FLUENCE_TMIC"   -->
+        <!-- "FLUENCE_QMIC". Param value is valid when adm_cfg_profile -->
+        <!-- is one of FLUENCE, FLUENCE_STEREO, FFECNS values          -->
         <param fluence_type="FLUENCE_DMIC" />
         <!-- wdsp_fluence_type: fluence disabled: "NONE" -->
         <!-- fluence enabled: "FLUENCE_DMIC", "FLUENCE_QMIC" -->
@@ -282,6 +281,8 @@
 
         <lsm_usecase>
             <param execution_mode="ADSP" />
+            <param app_type="3" /> <!-- app type used in ACDB -->
+            <param in_channels="1"/> <!-- Module input channels -->
             <param load_sound_model_ids="0x18000001, 0x00012C14" />
             <param unload_sound_model_ids="0x18000001, 0x00012C15" />
             <param confidence_levels_ids="0x18000001, 0x00012C07" />
@@ -290,15 +291,6 @@
             <param custom_config_ids="0x18000001, 0x00012C20" />
         </lsm_usecase>
 
-        <lsm_usecase>
-            <param execution_mode="WDSP" />
-            <param load_sound_model_ids="0x18000001, 0x00012C14" />
-            <param unload_sound_model_ids="0x18000001, 0x00012C15" />
-            <param confidence_levels_ids="0x18000001, 0x00012C07" />
-            <param operation_mode_ids="0x18000001, 0x00012C02" />
-            <param custom_config_ids="0x18000001, 0x00012C20" />
-        </lsm_usecase>
-
         <!-- format: "ADPCM_packet" or "PCM_packet" !-->
         <!-- transfer_mode: "FTRT" or "RT" -->
         <!--  kw_duration is in milli seconds. It is valid only for FTRT
@@ -354,6 +346,14 @@
         <param bit_width="16" />
     </adm_config>
 
+    <adm_config>
+        <param adm_cfg_profile="FFECNS" />
+        <param app_type="69947" />
+        <param sample_rate="16000" />
+        <param bit_width="16" />
+        <param out_channels="5"/>
+    </adm_config>
+
     <!-- backend_type tag defines backend type for each device -->
     <!-- Default value is assumed for devices that are not listed here -->
     <backend_type>
diff --git a/configs/msmnile_au/audio_policy_configuration.xml b/configs/msmnile_au/audio_policy_configuration.xml
index 25ac786..d71904e 100644
--- a/configs/msmnile_au/audio_policy_configuration.xml
+++ b/configs/msmnile_au/audio_policy_configuration.xml
@@ -171,7 +171,7 @@
                              samplingRates="8000,16000,32000,48000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
                 </mixPort>
 
-                <mixPort name="primary input" role="sink">
+                <mixPort name="primary input" role="sink" maxOpenCount="2" maxActiveCount="2">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
                              channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
diff --git a/configs/msmsteppe/audio_policy_configuration.xml b/configs/msmsteppe/audio_policy_configuration.xml
index 25ac786..d71904e 100644
--- a/configs/msmsteppe/audio_policy_configuration.xml
+++ b/configs/msmsteppe/audio_policy_configuration.xml
@@ -171,7 +171,7 @@
                              samplingRates="8000,16000,32000,48000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
                 </mixPort>
 
-                <mixPort name="primary input" role="sink">
+                <mixPort name="primary input" role="sink" maxOpenCount="2" maxActiveCount="2">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
                              channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
diff --git a/configs/sdm660/audio_policy_configuration.xml b/configs/sdm660/audio_policy_configuration.xml
index f0528c6..d7a338b 100644
--- a/configs/sdm660/audio_policy_configuration.xml
+++ b/configs/sdm660/audio_policy_configuration.xml
@@ -167,7 +167,7 @@
                              samplingRates="8000,16000,32000,48000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
                 </mixPort>
 
-                <mixPort name="primary input" role="sink">
+                <mixPort name="primary input" role="sink" maxOpenCount="2" maxActiveCount="2">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
                              channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
diff --git a/configs/sdm710/audio_output_policy.conf b/configs/sdm710/audio_output_policy.conf
index d66782e..72003e2 100644
--- a/configs/sdm710/audio_output_policy.conf
+++ b/configs/sdm710/audio_output_policy.conf
@@ -87,7 +87,7 @@
   primary {
     flags AUDIO_INPUT_FLAG_NONE
     formats AUDIO_FORMAT_PCM_16_BIT
-    sampling_rates 8000|11025|12000|16000|22050|24000|32000|44100|48000
+    sampling_rates 8000|16000|32000|48000
     bit_width 16
     app_type 69938
   }
diff --git a/configs/sdm710/audio_policy_configuration.xml b/configs/sdm710/audio_policy_configuration.xml
index 99f2eaf..b7c76ad 100644
--- a/configs/sdm710/audio_policy_configuration.xml
+++ b/configs/sdm710/audio_policy_configuration.xml
@@ -171,7 +171,7 @@
                              samplingRates="8000,16000,32000,48000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
                 </mixPort>
 
-                <mixPort name="primary input" role="sink">
+                <mixPort name="primary input" role="sink" maxOpenCount="2" maxActiveCount="2">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
                              channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
@@ -272,11 +272,11 @@
                 </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"/>
+                             samplingRates="44100,48000,64000,88200,96000,128000,176400,192000" channelMasks="dynamic"/>
                 </devicePort>
                 <devicePort tagName="USB Headset Out" type="AUDIO_DEVICE_OUT_USB_HEADSET" 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"/>
+                             samplingRates="44100,48000,64000,88200,96000,128000,176400,192000" channelMasks="dynamic"/>
                 </devicePort>
 
                 <!-- Input devices declaration, i.e. Source DEVICE PORT -->
diff --git a/configs/sdm845/audio_platform_info.xml b/configs/sdm845/audio_platform_info.xml
old mode 100755
new mode 100644
index 9a3d84c..9b2e4ef
--- a/configs/sdm845/audio_platform_info.xml
+++ b/configs/sdm845/audio_platform_info.xml
@@ -140,5 +140,165 @@
         <device name="SND_DEVICE_OUT_SPEAKER_AND_BT_SCO" backend="speaker-and-bt-sco" interface="SLIMBUS_0_RX-and-SLIMBUS_7_RX"/>
         <device name="SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB" backend="speaker-and-bt-sco-wb" interface="SLIMBUS_0_RX-and-SLIMBUS_7_RX"/>
     </backend_names>
+    <!-- below values are for ref purpose to OEM, doesn't contain actual hardware info on MTP -->
+    <microphone_characteristics>
+        <microphone valid_mask="31" device_id="builtin_mic_1" type="AUDIO_DEVICE_IN_BUILTIN_MIC" address="bottom" location="AUDIO_MICROPHONE_LOCATION_MAINBODY"
+            group="0" index_in_the_group="0" directionality="AUDIO_MICROPHONE_DIRECTIONALITY_OMNI" num_frequency_responses="93"
+            frequencies="100.00 106.00 112.00 118.00 125.00 132.00 140.00 150.00 160.00 170.00 180.00 190.00 200.00 212.00 224.00 236.00 250.00 265.00 280.00 300.00 315.00 335.00 355.00 375.00 400.00 425.00 450.00 475.00 500.00 530.00 560.00 600.00 630.00 670.00 710.00 750.00 800.00 850.00 900.00 950.00 1000.00 1060.00 1120.00 1180.00 1250.00 1320.00 1400.00 1500.00 1600.00 1700.00 1800.00 1900.00 2000.00 2120.00 2240.00 2360.00 2500.00 2650.00 2800.00 3000.00 3150.00 3350.00 3550.00 3750.00 4000.00 4250.00 4500.00 4750.00 5000.00 5300.00 5600.00 6000.00 6300.00 6700.00 7100.00 7500.00 8000.00 8500.00 9000.00 9500.00 10000.00 10600.00 11200.00 11800.00 12500.00 13200.00 14000.00 15000.00 16000.00 17000.00 18000.00 19000.00 20000.00"
+            responses="-0.78 -0.71 -0.64 -0.60 -0.55 -0.50 -0.47 -0.42 -0.39 -0.36 -0.34 -0.33 -0.32 -0.29 -0.28 -0.28 -0.27 -0.25 -0.25 -0.24 -0.23 -0.23 -0.22 -0.22 -0.19 -0.17 -0.15 -0.15 -0.14 -0.14 -0.12 -0.11 -0.10 -0.10 -0.08 -0.07 -0.07 -0.04 -0.03 -0.01 0.00 0.04 0.06 0.07 0.08 0.13 0.09 0.14 0.19 0.23 0.28 0.29 0.31 0.37 0.88 0.86 0.77 0.78 0.84 0.86 1.05 1.12 1.18 1.25 1.43 1.66 1.83 2.02 2.23 2.59 2.84 3.35 4.01 6.82 6.62 6.42 7.30 8.23 7.54 12.68 13.76 18.69 19.68 20.90 23.70 25.10 21.65 16.18 18.84 25.44 23.48 23.22 24.89"
+            sensitivity="-37.0" max_spl="132.5" min_spl="28.5" orientation="0.0 0.0 1.0" geometric_location="0.0269 0.0058 0.0079" />
+        <microphone valid_mask="31" device_id="builtin_mic_2" type="AUDIO_DEVICE_IN_BACK_MIC" address="back" location="AUDIO_MICROPHONE_LOCATION_MAINBODY"
+            group="0" index_in_the_group="1" directionality="AUDIO_MICROPHONE_DIRECTIONALITY_OMNI" num_frequency_responses="92"
+            frequencies="106.00 112.00 118.00 125.00 132.00 140.00 150.00 160.00 170.00 180.00 190.00 200.00 212.00 224.00 236.00 250.00 265.00 280.00 300.00 315.00 335.00 355.00 375.00 400.00 425.00 450.00 475.00 500.00 530.00 560.00 600.00 630.00 670.00 710.00 750.00 800.00 850.00 900.00 950.00 1000.00 1060.00 1120.00 1180.00 1250.00 1320.00 1400.00 1500.00 1600.00 1700.00 1800.00 1900.00 2000.00 2120.00 2240.00 2360.00 2500.00 2650.00 2800.00 3000.00 3150.00 3350.00 3550.00 3750.00 4000.00 4250.00 4500.00 4750.00 5000.00 5300.00 5600.00 6000.00 6300.00 6700.00 7100.00 7500.00 8000.00 8500.00 9000.00 9500.00 10000.00 10600.00 11200.00 11800.00 12500.00 13200.00 14000.00 15000.00 16000.00 17000.00 18000.00 19000.00 20000.00"
+            responses="-0.75 -0.74 -0.69 -0.65 -0.62 -0.61 -0.56 -0.53 -0.50 -0.47 -0.43 -0.40 -0.37 -0.36 -0.33 -0.30 -0.28 -0.25 -0.24 -0.24 -0.24 -0.25 -0.24 -0.12 -0.10 -0.08 -0.09 -0.07 -0.07 -0.06 -0.06 -0.06 -0.05 -0.04 -0.05 -0.04 -0.01 0.02 0.02 0.00 0.02 0.03 0.07 0.10 0.10 0.13 0.01 0.01 0.10 0.11 0.19 0.24 0.38 0.46 0.26 0.27 0.43 0.76 0.75 1.09 1.09 0.94 1.06 1.21 1.47 1.45 1.36 2.07 2.85 2.90 3.85 4.65 5.84 5.46 6.15 7.50 8.30 10.62 12.70 16.65 20.95 25.41 26.32 20.20 16.60 11.24 7.85 7.62 20.19 7.32 2.87 5.18"
+            sensitivity="-37.0" max_spl="132.5" min_spl="28.5" orientation="0.0 1.0 0.0" geometric_location="0.0546 0.1456 0.00415" />
+        <microphone valid_mask="31" device_id="builtin_mic_3" type="AUDIO_DEVICE_IN_BUILTIN_MIC" address="top" location="AUDIO_MICROPHONE_LOCATION_MAINBODY"
+            group="0" index_in_the_group="2" directionality="AUDIO_MICROPHONE_DIRECTIONALITY_OMNI" num_frequency_responses="92"
+            frequencies="100.00 106.00 112.00 118.00 125.00 132.00 140.00 150.00 160.00 170.00 180.00 190.00 200.00 212.00 224.00 236.00 250.00 265.00 280.00 300.00 315.00 335.00 355.00 375.00 400.00 425.00 450.00 475.00 500.00 530.00 560.00 600.00 630.00 670.00 710.00 750.00 800.00 850.00 900.00 950.00 1000.00 1060.00 1120.00 1180.00 1250.00 1320.00 1400.00 1500.00 1600.00 1700.00 1800.00 1900.00 2000.00 2120.00 2240.00 2360.00 2500.00 2650.00 2800.00 3000.00 3150.00 3350.00 3550.00 3750.00 4000.00 4250.00 4500.00 4750.00 5000.00 5300.00 5600.00 6000.00 6300.00 6700.00 7100.00 7500.00 8000.00 8500.00 9000.00 9500.00 10000.00 10600.00 11200.00 11800.00 12500.00 13200.00 14000.00 15000.00 16000.00 17000.00 18000.00 19000.00"
+            responses="-9.24 -9.31 -9.39 -9.45 -9.46 -9.47 -9.50 -9.52 -9.51 -9.52 -9.51 -9.50 -9.49 -9.47 -9.48 -9.49 -9.48 -9.50 -9.51 -9.53 -9.55 -9.59 -9.63 -9.67 -9.58 -9.57 -9.65 -9.68 -9.71 -9.75 -9.79 -9.84 -9.87 -9.87 -9.90 -9.90 -9.91 -9.97 -10.01 -10.05 -9.85 -9.93 -9.94 -9.98 -10.04 -10.12 -10.28 -10.25 -10.01 -9.86 -9.81 -9.82 -9.61 -9.46 -8.27 -8.42 -8.98 -8.99 -8.82 -9.21 -8.92 -8.97 -9.30 -9.44 -9.52 -9.28 -9.09 -8.81 -7.02 -5.72 -5.30 -7.26 -8.39 -12.28 -8.23 -6.99 -5.52 -4.87 -3.82 -6.09 0.00 -2.15 -0.26 1.48 5.22 10.92 6.41 9.55 12.96 3.35 22.00 19.75"
+            sensitivity="-37.0" max_spl="132.5" min_spl="28.5" orientation="0.0 0.0 1.0" geometric_location="0.0274 0.14065 0.0079" />
+    </microphone_characteristics>
+    <snd_devices>
+        <input_snd_device>
+            <input_snd_device_mic_mapping>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_CAMCORDER_MIC">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_2"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_3"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_VOICE_REC_MIC_AEC_NS">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_VOICE_REC_MIC_AEC">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_VOICE_REC_MIC_NS">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_VOICE_REC_MIC">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_MIC">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_VOICE_DMIC">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_2"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_VOICE_DMIC_TMUS">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_2"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_VOICE_SPEAKER_DMIC">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_2"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_3"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_2"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_DMIC_AEC">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_2"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_DMIC_NS">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_2"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_DMIC">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_2"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_2"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_3"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_SPEAKER_DMIC_AEC">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_2"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_3"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_SPEAKER_DMIC_NS">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_2"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_3"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_SPEAKER_MIC">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_2"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_3"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_UNPROCESSED_MIC">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_UNPROCESSED_STEREO_MIC">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED"/>
+                        <mic_info mic_device_id="builtin_mic_2"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_UNPROCESSED_THREE_MIC">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED"/>
+                        <mic_info mic_device_id="builtin_mic_2"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED"/>
+                        <mic_info mic_device_id="builtin_mic_3"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_HANDSET_DMIC_STEREO">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED"/>
+                        <mic_info mic_device_id="builtin_mic_2"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                    </snd_dev>
+                    <snd_dev in_snd_device="SND_DEVICE_IN_SPEAKER_DMIC_STEREO">
+                        <mic_info mic_device_id="builtin_mic_1"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_2"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                        <mic_info mic_device_id="builtin_mic_3"
+                            channel_mapping="AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED"/>
+                    </snd_dev>
+            </input_snd_device_mic_mapping>
+        </input_snd_device>
+    </snd_devices>
 </audio_platform_info>
 
diff --git a/configs/sdm845/audio_policy_configuration.xml b/configs/sdm845/audio_policy_configuration.xml
index 25ac786..a86b5da 100644
--- a/configs/sdm845/audio_policy_configuration.xml
+++ b/configs/sdm845/audio_policy_configuration.xml
@@ -171,7 +171,7 @@
                              samplingRates="8000,16000,32000,48000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
                 </mixPort>
 
-                <mixPort name="primary input" role="sink">
+                <mixPort name="primary input" role="sink" maxOpenCount="2" maxActiveCount="2">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
                              channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
@@ -272,11 +272,11 @@
                 </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"/>
+                             samplingRates="44100,48000,64000,88200,96000,128000,176400,192000" channelMasks="dynamic"/>
                 </devicePort>
                 <devicePort tagName="USB Headset Out" type="AUDIO_DEVICE_OUT_USB_HEADSET" 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"/>
+                             samplingRates="44100,48000,64000,88200,96000,128000,176400,192000" channelMasks="dynamic"/>
                 </devicePort>
 
                 <!-- Input devices declaration, i.e. Source DEVICE PORT -->
diff --git a/configs/sdm845/sdm845.mk b/configs/sdm845/sdm845.mk
index 8fa4816..bcfe3af 100644
--- a/configs/sdm845/sdm845.mk
+++ b/configs/sdm845/sdm845.mk
@@ -62,6 +62,7 @@
 BOARD_SUPPORTS_QAHW := false
 AUDIO_FEATURE_ENABLED_RAS := true
 AUDIO_FEATURE_ENABLED_SND_MONITOR := true
+AUDIO_FEATURE_ENABLED_SVA_MULTI_STAGE := true
 ##AUDIO_FEATURE_FLAGS
 
 ifneq ($(strip $(TARGET_USES_QSSI)), true)
@@ -194,7 +195,7 @@
 
 #split a2dp DSP supported encoder list
 PRODUCT_PROPERTY_OVERRIDES += \
-persist.vendor.bt.a2dp_offload_cap=sbc-aptx-aptxtws-aptxhd-aac
+persist.vendor.bt.a2dp_offload_cap=sbc-aptx-aptxtws-aptxhd-aac-ldac
 
 #enable software decoders for ALAC and APE
 PRODUCT_PROPERTY_OVERRIDES += \
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index 858ade3..d228123 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -76,6 +76,7 @@
 #define MIXER_SCRAMBLER_MODE       "AFE Scrambler Mode"
 #define MIXER_SAMPLE_RATE_RX       "BT SampleRate RX"
 #define MIXER_SAMPLE_RATE_TX       "BT SampleRate TX"
+#define MIXER_SAMPLE_RATE_DEFAULT  "BT SampleRate"
 #define MIXER_AFE_IN_CHANNELS      "AFE Input Channels"
 #define MIXER_ABR_TX_FEEDBACK_PATH "A2DP_SLIM7_UL_HL Switch"
 #define MIXER_SET_FEEDBACK_CHANNEL "BT set feedback channel"
@@ -787,30 +788,43 @@
     ALOGD("%s: set backend rx sample rate = %s", __func__, rate_str);
     ctl_sample_rate = mixer_get_ctl_by_name(a2dp.adev->mixer,
                                         MIXER_SAMPLE_RATE_RX);
-    if (!ctl_sample_rate) {
-        ALOGE("%s: ERROR backend sample rate mixer control not identifed", __func__);
-        return -ENOSYS;
-    }
-    if (mixer_ctl_set_enum_by_string(ctl_sample_rate, rate_str) != 0) {
-        ALOGE("%s: Failed to set backend sample rate = %s", __func__, rate_str);
-        return -ENOSYS;
-    }
+    if (ctl_sample_rate) {
 
-    // Set Tx backend sample rate
-    if (a2dp.abr_config.is_abr_enabled)
+        if (mixer_ctl_set_enum_by_string(ctl_sample_rate, rate_str) != 0) {
+            ALOGE("%s: Failed to set backend sample rate = %s", __func__, rate_str);
+            return -ENOSYS;
+        }
+
+        /* Set Tx backend sample rate */
+        if (a2dp.abr_config.is_abr_enabled)
         rate_str = ABR_TX_SAMPLE_RATE;
 
-    ALOGD("%s: set backend tx sample rate = %s", __func__, rate_str);
-    ctl_sample_rate = mixer_get_ctl_by_name(a2dp.adev->mixer,
-                                        MIXER_SAMPLE_RATE_TX);
-    if (!ctl_sample_rate) {
-        ALOGE("%s: ERROR backend sample rate mixer control not identifed", __func__);
-        return -ENOSYS;
-    }
-    if (mixer_ctl_set_enum_by_string(ctl_sample_rate, rate_str) != 0) {
-        ALOGE("%s: Failed to set backend sample rate = %s",
-                                    __func__, rate_str);
-        return -ENOSYS;
+        ALOGD("%s: set backend tx sample rate = %s", __func__, rate_str);
+        ctl_sample_rate = mixer_get_ctl_by_name(a2dp.adev->mixer,
+                                            MIXER_SAMPLE_RATE_TX);
+        if (!ctl_sample_rate) {
+                ALOGE("%s: ERROR backend sample rate mixer control not identifed", __func__);
+                return -ENOSYS;
+        }
+
+        if (mixer_ctl_set_enum_by_string(ctl_sample_rate, rate_str) != 0) {
+            ALOGE("%s: Failed to set backend sample rate = %s", __func__, rate_str);
+            return -ENOSYS;
+        }
+    } else {
+        /* Fallback to legacy approch if MIXER_SAMPLE_RATE_RX and
+        MIXER_SAMPLE_RATE_TX is not supported */
+        ctl_sample_rate = mixer_get_ctl_by_name(a2dp.adev->mixer,
+                                        MIXER_SAMPLE_RATE_DEFAULT);
+        if (!ctl_sample_rate) {
+            ALOGE("%s: ERROR backend sample rate mixer control not identifed", __func__);
+            return -ENOSYS;
+        }
+
+        if (mixer_ctl_set_enum_by_string(ctl_sample_rate, rate_str) != 0) {
+            ALOGE("%s: Failed to set backend sample rate = %s", __func__, rate_str);
+            return -ENOSYS;
+        }
     }
 
     //Configure AFE input channels
@@ -849,24 +863,37 @@
     ALOGD("%s: reset backend sample rate = %s", __func__, rate_str);
     ctl_sample_rate_rx = mixer_get_ctl_by_name(a2dp.adev->mixer,
                                         MIXER_SAMPLE_RATE_RX);
-    if (!ctl_sample_rate_rx) {
-        ALOGE("%s: ERROR Rx backend sample rate mixer control not identifed", __func__);
-        return -ENOSYS;
-    }
-    if (mixer_ctl_set_enum_by_string(ctl_sample_rate_rx, rate_str) != 0) {
-        ALOGE("%s: Failed to reset Rx backend sample rate = %s", __func__, rate_str);
-        return -ENOSYS;
-    }
+    if (ctl_sample_rate_rx) {
 
-    ctl_sample_rate_tx = mixer_get_ctl_by_name(a2dp.adev->mixer,
+        if (mixer_ctl_set_enum_by_string(ctl_sample_rate_rx, rate_str) != 0) {
+            ALOGE("%s: Failed to reset Rx backend sample rate = %s", __func__, rate_str);
+            return -ENOSYS;
+        }
+
+        ctl_sample_rate_tx = mixer_get_ctl_by_name(a2dp.adev->mixer,
                                         MIXER_SAMPLE_RATE_TX);
-    if (!ctl_sample_rate_tx) {
-        ALOGE("%s: ERROR Tx backend sample rate mixer control not identifed", __func__);
-        return -ENOSYS;
-    }
-    if (mixer_ctl_set_enum_by_string(ctl_sample_rate_tx, rate_str) != 0) {
-        ALOGE("%s: Failed to reset Tx backend sample rate = %s", __func__, rate_str);
-        return -ENOSYS;
+        if (!ctl_sample_rate_tx) {
+                ALOGE("%s: ERROR Tx backend sample rate mixer control not identifed", __func__);
+                return -ENOSYS;
+        }
+
+        if (mixer_ctl_set_enum_by_string(ctl_sample_rate_tx, rate_str) != 0) {
+            ALOGE("%s: Failed to reset Tx backend sample rate = %s", __func__, rate_str);
+            return -ENOSYS;
+        }
+    } else {
+
+        ctl_sample_rate_rx = mixer_get_ctl_by_name(a2dp.adev->mixer,
+                                        MIXER_SAMPLE_RATE_DEFAULT);
+        if (!ctl_sample_rate_rx) {
+            ALOGE("%s: ERROR backend sample rate mixer control not identifed", __func__);
+            return -ENOSYS;
+        }
+
+        if (mixer_ctl_set_enum_by_string(ctl_sample_rate_rx, rate_str) != 0) {
+            ALOGE("%s: Failed to reset backend sample rate = %s", __func__, rate_str);
+            return -ENOSYS;
+        }
     }
 
     // Reset AFE input channels
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 090cd15..e7d2386 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -222,6 +222,7 @@
 #define audio_extn_usb_get_sup_sample_rates(t, s, l)                   (0)
 #define audio_extn_usb_is_tunnel_supported()                           (0)
 #define audio_extn_usb_alive(adev)                                     (false)
+#define audio_extn_usb_connected(parms)                                (0)
 #undef USB_BURST_MODE_ENABLED
 #else
 void audio_extn_usb_init(void *adev);
@@ -241,6 +242,7 @@
 int audio_extn_usb_get_sup_sample_rates(int type, uint32_t *sr, uint32_t l);
 bool audio_extn_usb_is_tunnel_supported();
 bool audio_extn_usb_alive(int card);
+bool audio_extn_usb_connected(struct str_parms *parms);
 #endif
 
 #ifndef USB_BURST_MODE_ENABLED
diff --git a/hal/audio_extn/soundtrigger.c b/hal/audio_extn/soundtrigger.c
index b7f5af7..0fa30d0 100644
--- a/hal/audio_extn/soundtrigger.c
+++ b/hal/audio_extn/soundtrigger.c
@@ -436,9 +436,6 @@
     if (!st_dev)
        return;
 
-    if (st_dev->sthal_prop_api_version >= STHAL_PROP_API_VERSION_1_0)
-        return;
-
     if (snd_device >= SND_DEVICE_OUT_BEGIN &&
         snd_device < SND_DEVICE_OUT_END)
         device_type = PCM_PLAYBACK;
@@ -481,14 +478,15 @@
     if (!st_dev)
        return;
 
-    if (st_dev->sthal_prop_api_version < STHAL_PROP_API_VERSION_1_0)
-        return;
-
     if (uc_info == NULL) {
         ALOGE("%s: usecase is NULL!!!", __func__);
         return;
     }
 
+    if ((st_dev->sthal_prop_api_version < STHAL_PROP_API_VERSION_1_0) &&
+        (uc_info->type != PCM_PLAYBACK))
+        return;
+
     if ((uc_info->in_snd_device >= SND_DEVICE_IN_BEGIN &&
         uc_info->in_snd_device < SND_DEVICE_IN_END)) {
         if (is_same_as_st_device(uc_info->in_snd_device))
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index 1f2f3db..197daf9 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -916,14 +916,6 @@
         if (handle.pcm_tx)
             pcm_close(handle.pcm_tx);
         handle.pcm_tx = NULL;
-        /* Clear TX calibration to handset mic */
-        if (disable_tx) {
-            uc_info_tx->in_snd_device = SND_DEVICE_IN_HANDSET_MIC;
-            uc_info_tx->out_snd_device = SND_DEVICE_NONE;
-            platform_send_audio_calibration(adev->platform,
-              uc_info_tx,
-              platform_get_default_app_type(adev->platform), 8000);
-        }
         if (!status.status) {
             protCfg.mode = MSM_SPKR_PROT_CALIBRATED;
             protCfg.r0[SP_V2_SPKR_1] = status.r0[SP_V2_SPKR_1];
@@ -1792,7 +1784,6 @@
     struct audio_usecase *uc_info_tx;
     struct audio_device *adev = handle.adev_handle;
     int32_t pcm_dev_tx_id = -1, ret = 0;
-    bool disable_tx = false;
     snd_device_t in_snd_device;
 
     ALOGV("%s: Entry", __func__);
@@ -1829,7 +1820,6 @@
         uc_info_tx->out_snd_device = SND_DEVICE_NONE;
         handle.pcm_tx = NULL;
         list_add_tail(&adev->usecase_list, &uc_info_tx->list);
-        disable_tx = true;
         enable_snd_device(adev, in_snd_device);
         enable_audio_route(adev, uc_info_tx);
 
@@ -1855,14 +1845,6 @@
     }
 
 exit:
-   /* Clear VI feedback cal and replace with handset MIC  */
-    if (disable_tx) {
-        uc_info_tx->in_snd_device = SND_DEVICE_IN_HANDSET_MIC;
-        uc_info_tx->out_snd_device = SND_DEVICE_NONE;
-        platform_send_audio_calibration(adev->platform,
-          uc_info_tx,
-          platform_get_default_app_type(adev->platform), 8000);
-     }
      if (ret) {
         if (handle.pcm_tx)
             pcm_close(handle.pcm_tx);
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index d96da2b..b7bf22a 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -1430,6 +1430,26 @@
     usbmod->usb_reconfig = is_required;
 }
 
+bool audio_extn_usb_connected(struct str_parms *parms) {
+    int card = -1;
+    struct listnode *node_i = NULL;
+    struct usb_card_config *usb_card_info = NULL;
+    bool usb_connected = false;
+
+    if (str_parms_get_int(parms, "card", &card) >= 0) {
+        usb_connected = audio_extn_usb_alive(card);
+    } else {
+        list_for_each(node_i, &usbmod->usb_card_conf_list) {
+            usb_card_info = node_to_item(node_i, struct usb_card_config, list);
+            if (audio_extn_usb_alive(usb_card_info->usb_card)) {
+                usb_connected = true;
+                break;
+            }
+        }
+    }
+    return usb_connected;
+}
+
 void audio_extn_usb_init(void *adev)
 {
     if (usbmod == NULL) {
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 45cf3ef..3152669 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -3278,6 +3278,51 @@
     return ret;
 }
 
+
+/** Add a value in a list if not already present.
+ * @return true if value was successfully inserted or already present,
+ *         false if the list is full and does not contain the value.
+ */
+static bool register_uint(uint32_t value, uint32_t* list, size_t list_length) {
+    for (size_t i = 0; i < list_length; i++) {
+        if (list[i] == value) return true; // value is already present
+        if (list[i] == 0) { // no values in this slot
+            list[i] = value;
+            return true; // value inserted
+        }
+    }
+    return false; // could not insert value
+}
+
+/** Add channel_mask in supported_channel_masks if not already present.
+ * @return true if channel_mask was successfully inserted or already present,
+ *         false if supported_channel_masks is full and does not contain channel_mask.
+ */
+static void register_channel_mask(audio_channel_mask_t channel_mask,
+            audio_channel_mask_t supported_channel_masks[static MAX_SUPPORTED_CHANNEL_MASKS]) {
+    ALOGE_IF(!register_uint(channel_mask, supported_channel_masks, MAX_SUPPORTED_CHANNEL_MASKS),
+        "%s: stream can not declare supporting its channel_mask %x", __func__, channel_mask);
+}
+
+/** Add format in supported_formats if not already present.
+ * @return true if format was successfully inserted or already present,
+ *         false if supported_formats is full and does not contain format.
+ */
+static void register_format(audio_format_t format,
+            audio_format_t supported_formats[static MAX_SUPPORTED_FORMATS]) {
+    ALOGE_IF(!register_uint(format, supported_formats, MAX_SUPPORTED_FORMATS),
+             "%s: stream can not declare supporting its format %x", __func__, format);
+}
+/** Add sample_rate in supported_sample_rates if not already present.
+ * @return true if sample_rate was successfully inserted or already present,
+ *         false if supported_sample_rates is full and does not contain sample_rate.
+ */
+static void register_sample_rate(uint32_t sample_rate,
+            uint32_t supported_sample_rates[static MAX_SUPPORTED_SAMPLE_RATES]) {
+    ALOGE_IF(!register_uint(sample_rate, supported_sample_rates, MAX_SUPPORTED_SAMPLE_RATES),
+             "%s: stream can not declare supporting its sample rate %x", __func__, sample_rate);
+}
+
 static size_t get_input_buffer_size(uint32_t sample_rate,
                                     audio_format_t format,
                                     int channel_count,
@@ -3682,6 +3727,18 @@
                 !audio_extn_a2dp_is_ready()) {
                 val = AUDIO_DEVICE_OUT_SPEAKER;
         }
+        /*
+        * When USB headset is disconnected the music platback paused
+        * and the policy manager send routing=0. But if the USB is connected
+        * back before the standby time, AFE is not closed and opened
+        * when USB is connected back. So routing to speker will guarantee
+        * AFE reconfiguration and AFE will be opend once USB is connected again
+        */
+        if ((out->devices & AUDIO_DEVICE_OUT_ALL_USB) &&
+                (val == AUDIO_DEVICE_NONE) &&
+                 !audio_extn_usb_connected(parms)) {
+                 val = AUDIO_DEVICE_OUT_SPEAKER;
+         }
         /* To avoid a2dp to sco overlapping / BT device improper state
          * check with BT lib about a2dp streaming support before routing
          */
@@ -5612,6 +5669,36 @@
     return 0;
 }
 
+static int in_get_active_microphones(const struct audio_stream_in *stream,
+                                     struct audio_microphone_characteristic_t *mic_array,
+                                     size_t *mic_count) {
+    struct stream_in *in = (struct stream_in *)stream;
+    struct audio_device *adev = in->dev;
+    ALOGVV("%s", __func__);
+
+    lock_input_stream(in);
+    pthread_mutex_lock(&adev->lock);
+    int ret = platform_get_active_microphones(adev->platform,
+                                              audio_channel_count_from_in_mask(in->channel_mask),
+                                              in->usecase, mic_array, mic_count);
+    pthread_mutex_unlock(&adev->lock);
+    pthread_mutex_unlock(&in->lock);
+
+    return ret;
+}
+
+static int adev_get_microphones(const struct audio_hw_device *dev,
+                                struct audio_microphone_characteristic_t *mic_array,
+                                size_t *mic_count) {
+    struct audio_device *adev = (struct audio_device *)dev;
+    ALOGVV("%s", __func__);
+
+    pthread_mutex_lock(&adev->lock);
+    int ret = platform_get_microphones(adev->platform, mic_array, mic_count);
+    pthread_mutex_unlock(&adev->lock);
+
+    return ret;
+}
 int adev_open_output_stream(struct audio_hw_device *dev,
                             audio_io_handle_t handle,
                             audio_devices_t devices,
@@ -6176,6 +6263,9 @@
     config->format = out->stream.common.get_format(&out->stream.common);
     config->channel_mask = out->stream.common.get_channels(&out->stream.common);
     config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common);
+    register_format(out->format, out->supported_formats);
+    register_channel_mask(out->channel_mask, out->supported_channel_masks);
+    register_sample_rate(out->sample_rate, out->supported_sample_rates);
 
     /*
        By locking output stream before registering, we allow the callback
@@ -6795,6 +6885,7 @@
     in->stream.set_gain = in_set_gain;
     in->stream.read = in_read;
     in->stream.get_input_frames_lost = in_get_input_frames_lost;
+    in->stream.get_active_microphones = in_get_active_microphones;
 
     in->device = devices;
     in->source = source;
@@ -6990,6 +7081,9 @@
                                                 devices, flags, in->format,
                                                 in->sample_rate, in->bit_width,
                                                 in->profile, &in->app_type_cfg);
+    register_format(in->format, in->supported_formats);
+    register_channel_mask(in->channel_mask, in->supported_channel_masks);
+    register_sample_rate(in->sample_rate, in->supported_sample_rates);
 
     /* This stream could be for sound trigger lab,
        get sound trigger pcm if present */
@@ -7334,6 +7428,7 @@
     adev->device.get_audio_port = adev_get_audio_port;
     adev->device.set_audio_port_config = adev_set_audio_port_config;
     adev->device.dump = adev_dump;
+    adev->device.get_microphones = adev_get_microphones;
 
     /* Set the default route before the PCM stream is opened */
     adev->mode = AUDIO_MODE_NORMAL;
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index ef5576f..41d6e6b 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -30,6 +30,7 @@
 #include <cutils/str_parms.h>
 #include <audio_hw.h>
 #include <platform_api.h>
+#include <unistd.h>
 #include "platform.h"
 #include "audio_extn.h"
 #include "acdb.h"
@@ -6158,6 +6159,11 @@
             ALOGD("%s:becf: afe: napb not active - set non fractional rate",
                        __func__);
         }
+        /*ensure AFE set to 48khz when sample rate less than 44.1khz*/
+        if (sample_rate < OUTPUT_SAMPLING_RATE_44100) {
+            sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+            ALOGD("%s:becf: afe: napb set sample rate to default Sample Rate(48k)",__func__);
+        }
     }
 
     /*
@@ -7912,7 +7918,6 @@
 {
     const char *mixer_ctl_name = "Swap channel";
     struct mixer_ctl *ctl;
-    const char *mixer_path;
     struct platform_data *my_data = (struct platform_data *)adev->platform;
 
     // forced to set to swap, but device not rotated ... ignore set
@@ -7921,13 +7926,6 @@
 
     ALOGV("%s:", __func__);
 
-    if (swap_channels)
-        mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_REVERSE);
-    else
-        mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER);
-
-    audio_route_apply_and_update_path(adev->audio_route, mixer_path);
-
     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
     if (!ctl) {
         ALOGE("%s: Could not get ctl for mixer cmd - %s",__func__, mixer_ctl_name);
@@ -7961,6 +7959,18 @@
     struct audio_usecase *usecase;
     struct listnode *node;
 
+    //swap channels only for stereo spkr
+    struct platform_data *my_data = (struct platform_data *)adev->platform;
+    if (my_data) {
+        if (!hw_info_is_stereo_spkr(my_data->hw_info)) {
+            ALOGV("%s: will not swap due to it is not stereo spkr", __func__);
+            return 0;
+        }
+    } else {
+        ALOGE("%s: failed to allocate platform data", __func__);
+        return -EINVAL;
+    }
+
     // do not swap channels in audio modes with concurrent capture and playback
     // as this may break the echo reference
     if ((adev->mode == AUDIO_MODE_IN_COMMUNICATION) || (adev->mode == AUDIO_MODE_IN_CALL)) {
@@ -7977,8 +7987,9 @@
              * to perform device switch to disable the current backend to
              * enable it with new acdb data.
              */
-            if (acdb_device_table[SND_DEVICE_OUT_SPEAKER] !=
-                acdb_device_table[SND_DEVICE_OUT_SPEAKER_REVERSE]) {
+            if (my_data->speaker_lr_swap &&
+                (acdb_device_table[SND_DEVICE_OUT_SPEAKER] !=
+                acdb_device_table[SND_DEVICE_OUT_SPEAKER_REVERSE])) {
                 const int initial_skpr_gain = ramp_speaker_gain(adev, false /*ramp_up*/, -1);
                 select_devices(adev, usecase->id);
                 if (initial_skpr_gain != -EINVAL)
@@ -8105,3 +8116,26 @@
 
     return id_string;
 }
+
+bool platform_set_microphone_characteristic(void *platform __unused,
+                                            struct audio_microphone_characteristic_t mic __unused) {
+    return -ENOSYS;
+}
+
+int platform_get_microphones(void *platform __unused,
+                             struct audio_microphone_characteristic_t *mic_array __unused,
+                             size_t *mic_count __unused) {
+    return -ENOSYS;
+}
+
+bool platform_set_microphone_map(void *platform __unused, snd_device_t in_snd_device __unused,
+                                 const struct mic_info *info __unused) {
+    return false;
+}
+
+int platform_get_active_microphones(void *platform __unused, unsigned int channels __unused,
+                                    audio_usecase_t usecase __unused,
+                                    struct audio_microphone_characteristic_t *mic_array __unused,
+                                    size_t *mic_count __unused) {
+    return -ENOSYS;
+}
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index 7ffd2a9..4acfde9 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -399,6 +399,8 @@
 #define TX_VOICE_FV5ECNS_SM 0x10F09
 #define TX_VOICE_FV5ECNS_DM 0x10F0A
 
+#define AUDIO_MAKE_STRING_FROM_ENUM(X)   { #X, X }
+
 #define LIB_CSD_CLIENT "libcsd-client.so"
 /* CSD-CLIENT related functions */
 typedef int (*init_t)();
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index 71090ca..480ef13 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
  * Not a contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -1363,3 +1363,21 @@
 {
     return -ENOSYS;
 }
+
+bool platform_set_microphone_characteristic(void *platform __unused,
+                                            struct audio_microphone_characteristic_t mic __unused) {
+    return -ENOSYS;
+}
+
+int platform_get_microphones(void *platform __unused,
+                             struct audio_microphone_characteristic_t *mic_array __unused,
+                             size_t *mic_count __unused) {
+    return -ENOSYS;
+}
+
+int platform_get_active_microphones(void *platform __unused, unsigned int channels __unused,
+                                    audio_usecase_t usecase __unused,
+                                    struct audio_microphone_characteristic_t *mic_array __unused,
+                                    size_t *mic_count __unused) {
+    return -ENOSYS;
+}
diff --git a/hal/msm8960/platform.h b/hal/msm8960/platform.h
index c9ac74a..727f906 100644
--- a/hal/msm8960/platform.h
+++ b/hal/msm8960/platform.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013 - 2018 The Linux Foundation. All rights reserved.
  * Not a contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -166,4 +166,7 @@
 
 #define DEVICE_NAME_MAX_SIZE 128
 
+#define AUDIO_MAKE_STRING_FROM_ENUM(X)   { #X, X }
+
+
 #endif // QCOM_AUDIO_PLATFORM_H
diff --git a/hal/msm8974/hw_info.c b/hal/msm8974/hw_info.c
index 062c104..ea6b7bf 100644
--- a/hal/msm8974/hw_info.c
+++ b/hal/msm8974/hw_info.c
@@ -226,6 +226,31 @@
     SND_DEVICE_OUT_VOICE_HANDSET,
     SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET,
     SND_DEVICE_IN_SPEAKER_MIC,
+    SND_DEVICE_IN_VOICE_SPEAKER_MIC,
+    SND_DEVICE_IN_VOICE_DMIC,
+    SND_DEVICE_IN_HANDSET_DMIC,
+    SND_DEVICE_IN_HANDSET_STEREO_DMIC,
+    SND_DEVICE_IN_SPEAKER_STEREO_DMIC,
+    SND_DEVICE_IN_VOICE_SPEAKER_DMIC,
+    SND_DEVICE_IN_THREE_MIC,
+    SND_DEVICE_IN_HANDSET_TMIC,
+    SND_DEVICE_IN_HANDSET_TMIC_FLUENCE_PRO,
+    SND_DEVICE_IN_HANDSET_TMIC_AEC,
+    SND_DEVICE_IN_HANDSET_TMIC_NS,
+    SND_DEVICE_IN_HANDSET_TMIC_AEC_NS,
+    SND_DEVICE_IN_VOICE_SPEAKER_TMIC,
+    SND_DEVICE_IN_SPEAKER_TMIC_AEC,
+    SND_DEVICE_IN_SPEAKER_TMIC_NS,
+    SND_DEVICE_IN_SPEAKER_TMIC_AEC_NS,
+    SND_DEVICE_IN_QUAD_MIC,
+    SND_DEVICE_IN_HANDSET_QMIC,
+    SND_DEVICE_IN_SPEAKER_QMIC_AEC,
+    SND_DEVICE_IN_SPEAKER_QMIC_NS,
+    SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS,
+    SND_DEVICE_IN_VOICE_SPEAKER_QMIC,
+    SND_DEVICE_IN_AANC_HANDSET_MIC,
+    SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET,
+    SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC,
 };
 
 
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 1edb3d6..42dfd95 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -210,6 +210,11 @@
 static int max_be_dai_names = 0;
 static const struct be_dai_name_struct *be_dai_name_table;
 
+struct snd_device_to_mic_map {
+    struct mic_info microphones[AUDIO_MICROPHONE_MAX_COUNT];
+    size_t mic_count;
+};
+
 struct platform_data {
     struct audio_device *adev;
     bool fluence_in_spkr_mode;
@@ -273,6 +278,10 @@
     struct listnode acdb_meta_key_list;
     bool use_generic_handset;
     struct acdb_init_data_v4 acdb_init_data;
+    uint32_t declared_mic_count;
+    struct audio_microphone_characteristic_t microphones[AUDIO_MICROPHONE_MAX_COUNT];
+    struct snd_device_to_mic_map mic_map[SND_DEVICE_MAX];
+
 };
 
 static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
@@ -2092,6 +2101,7 @@
     my_data->mono_speaker = SPKR_1;
     my_data->speaker_lr_swap = false;
     my_data->voice_speaker_stereo = false;
+    my_data->declared_mic_count = 0;
 
     be_dai_name_table = NULL;
 
@@ -6129,6 +6139,11 @@
             ALOGD("%s:becf: afe: napb not active - set non fractional rate",
                        __func__);
         }
+        /*ensure AFE set to 48khz when sample rate less than 44.1khz*/
+        if (sample_rate < OUTPUT_SAMPLING_RATE_44100) {
+            sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+            ALOGD("%s:becf: afe: napb set sample rate to default Sample Rate(48k)",__func__);
+        }
     }
 
     /*
@@ -7765,7 +7780,6 @@
 {
     const char *mixer_ctl_name = "Swap channel";
     struct mixer_ctl *ctl;
-    const char *mixer_path;
     struct platform_data *my_data = (struct platform_data *)adev->platform;
 
     // forced to set to swap, but device not rotated ... ignore set
@@ -7774,13 +7788,6 @@
 
     ALOGV("%s:", __func__);
 
-    if (swap_channels)
-        mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_REVERSE);
-    else
-        mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER);
-
-    audio_route_apply_and_update_path(adev->audio_route, mixer_path);
-
     ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
     if (!ctl) {
         ALOGE("%s: Could not get ctl for mixer cmd - %s",__func__, mixer_ctl_name);
@@ -7814,6 +7821,18 @@
     struct audio_usecase *usecase;
     struct listnode *node;
 
+    //swap channels only for stereo spkr
+    struct platform_data *my_data = (struct platform_data *)adev->platform;
+    if (my_data) {
+        if (!hw_info_is_stereo_spkr(my_data->hw_info)) {
+            ALOGV("%s: will not swap due to it is not stereo spkr", __func__);
+            return 0;
+        }
+    } else {
+        ALOGE("%s: failed to allocate platform data", __func__);
+        return -EINVAL;
+    }
+
     // do not swap channels in audio modes with concurrent capture and playback
     // as this may break the echo reference
     if ((adev->mode == AUDIO_MODE_IN_COMMUNICATION) || (adev->mode == AUDIO_MODE_IN_CALL)) {
@@ -7830,8 +7849,9 @@
              * to perform device switch to disable the current backend to
              * enable it with new acdb data.
              */
-            if (acdb_device_table[SND_DEVICE_OUT_SPEAKER] !=
-                acdb_device_table[SND_DEVICE_OUT_SPEAKER_REVERSE]) {
+            if (my_data->speaker_lr_swap &&
+                (acdb_device_table[SND_DEVICE_OUT_SPEAKER] !=
+                acdb_device_table[SND_DEVICE_OUT_SPEAKER_REVERSE])) {
                 const int initial_skpr_gain = ramp_speaker_gain(adev, false /*ramp_up*/, -1);
                 select_devices(adev, usecase->id);
                 if (initial_skpr_gain != -EINVAL)
@@ -7996,3 +8016,105 @@
 
     return id_string;
 }
+
+bool platform_set_microphone_characteristic(void *platform,
+                                            struct audio_microphone_characteristic_t mic) {
+    struct platform_data *my_data = (struct platform_data *)platform;
+    if (my_data->declared_mic_count >= AUDIO_MICROPHONE_MAX_COUNT) {
+        ALOGE("mic number is more than maximum number");
+        return false;
+    }
+    for (size_t ch = 0; ch < AUDIO_CHANNEL_COUNT_MAX; ch++) {
+        mic.channel_mapping[ch] = AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
+    }
+    my_data->microphones[my_data->declared_mic_count++] = mic;
+    return true;
+}
+
+int platform_get_microphones(void *platform,
+                             struct audio_microphone_characteristic_t *mic_array,
+                             size_t *mic_count) {
+    struct platform_data *my_data = (struct platform_data *)platform;
+    if (mic_count == NULL) {
+        return -EINVAL;
+    }
+    if (mic_array == NULL) {
+        return -EINVAL;
+    }
+
+    if (*mic_count == 0) {
+        *mic_count = my_data->declared_mic_count;
+        return 0;
+    }
+
+    size_t max_mic_count = *mic_count;
+    size_t actual_mic_count = 0;
+    for (size_t i = 0; i < max_mic_count && i < my_data->declared_mic_count; i++) {
+        mic_array[i] = my_data->microphones[i];
+        actual_mic_count++;
+    }
+    *mic_count = actual_mic_count;
+    return 0;
+}
+
+bool platform_set_microphone_map(void *platform, snd_device_t in_snd_device,
+                                 const struct mic_info *info) {
+    struct platform_data *my_data = (struct platform_data *)platform;
+    if (in_snd_device < SND_DEVICE_IN_BEGIN || in_snd_device >= SND_DEVICE_IN_END) {
+        ALOGE("%s: Sound device not valid", __func__);
+        return false;
+    }
+    size_t m_count = my_data->mic_map[in_snd_device].mic_count++;
+    if (m_count >= AUDIO_MICROPHONE_MAX_COUNT) {
+        ALOGE("%s: Microphone count is greater than max allowed value", __func__);
+        my_data->mic_map[in_snd_device].mic_count--;
+        return false;
+    }
+    my_data->mic_map[in_snd_device].microphones[m_count] = *info;
+    return true;
+}
+
+int platform_get_active_microphones(void *platform, unsigned int channels,
+                                    audio_usecase_t uc_id,
+                                    struct audio_microphone_characteristic_t *mic_array,
+                                    size_t *mic_count) {
+    struct platform_data *my_data = (struct platform_data *)platform;
+    struct audio_usecase *usecase = get_usecase_from_list(my_data->adev, uc_id);
+    if (mic_count == NULL || mic_array == NULL || usecase == NULL) {
+        return -EINVAL;
+    }
+    size_t max_mic_count = my_data->declared_mic_count;
+    size_t actual_mic_count = 0;
+
+    snd_device_t active_input_snd_device =
+            platform_get_input_snd_device(platform, usecase->stream.in->device);
+    if (active_input_snd_device == SND_DEVICE_NONE) {
+        ALOGI("%s: No active microphones found", __func__);
+        goto end;
+    }
+
+    size_t  active_mic_count = my_data->mic_map[active_input_snd_device].mic_count;
+    struct mic_info *m_info = my_data->mic_map[active_input_snd_device].microphones;
+
+    for (size_t i = 0; i < active_mic_count; i++) {
+        unsigned int channels_for_active_mic = channels;
+        if (channels_for_active_mic > m_info[i].channel_count) {
+            channels_for_active_mic = m_info[i].channel_count;
+        }
+        for (size_t j = 0; j < max_mic_count; j++) {
+            if (strcmp(my_data->microphones[j].device_id,
+                       m_info[i].device_id) == 0) {
+                mic_array[actual_mic_count] = my_data->microphones[j];
+                for (size_t ch = 0; ch < channels_for_active_mic; ch++) {
+                     mic_array[actual_mic_count].channel_mapping[ch] =
+                             m_info[i].channel_mapping[ch];
+                }
+                actual_mic_count++;
+                break;
+            }
+        }
+    }
+end:
+    *mic_count = actual_mic_count;
+    return 0;
+}
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index ccbc413..34ab9f6 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -521,6 +521,9 @@
 #define TX_VOICE_FV5ECNS_DM 0x10F0A
 
 #define LIB_CSD_CLIENT "libcsd-client.so"
+
+#define AUDIO_MAKE_STRING_FROM_ENUM(X)   { #X, X }
+
 /* CSD-CLIENT related functions */
 typedef int (*init_t)(bool);
 typedef int (*deinit_t)();
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 53a4888..226275e 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -51,6 +51,12 @@
     uint32_t level;
 };
 
+struct mic_info {
+    char device_id[AUDIO_MICROPHONE_ID_MAX_LEN];
+    size_t channel_count;
+    audio_microphone_channel_mapping_t channel_mapping[AUDIO_CHANNEL_COUNT_MAX];
+};
+
 enum {
     NATIVE_AUDIO_MODE_SRC = 1,
     NATIVE_AUDIO_MODE_TRUE_44_1,
@@ -285,4 +291,16 @@
                                int *fd, uint32_t *size);
 int platform_get_ec_ref_loopback_snd_device(int channel_count);
 const char * platform_get_snd_card_name_for_acdb_loader(const char *snd_card_name);
+
+bool platform_set_microphone_characteristic(void *platform,
+                                            struct audio_microphone_characteristic_t mic);
+bool platform_set_microphone_map(void *platform, snd_device_t in_snd_device,
+                                 const struct mic_info *info);
+int platform_get_microphones(void *platform,
+                             struct audio_microphone_characteristic_t *mic_array,
+                             size_t *mic_count);
+int platform_get_active_microphones(void *platform, unsigned int channels,
+                                    audio_usecase_t usecase,
+                                    struct audio_microphone_characteristic_t *mic_array,
+                                    size_t *mic_count);
 #endif // AUDIO_PLATFORM_API_H
diff --git a/hal/platform_info.c b/hal/platform_info.c
index 5140911..d27d689 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2018, 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
@@ -62,6 +62,12 @@
     CONFIG_PARAMS,
     GAIN_LEVEL_MAPPING,
     ACDB_METAINFO_KEY,
+    MICROPHONE_CHARACTERISTIC,
+    SND_DEVICES,
+    INPUT_SND_DEVICE,
+    INPUT_SND_DEVICE_TO_MIC_MAPPING,
+    SND_DEV,
+    MIC_INFO,
 } section_t;
 
 typedef void (* section_process_fn)(const XML_Char **attr);
@@ -78,6 +84,9 @@
 static void process_root(const XML_Char **attr);
 static void process_gain_db_to_level_map(const XML_Char **attr);
 static void process_acdb_metainfo_key(const XML_Char **attr);
+static void process_microphone_characteristic(const XML_Char **attr);
+static void process_snd_dev(const XML_Char **attr);
+static void process_mic_info(const XML_Char **attr);
 
 static section_process_fn section_table[] = {
     [ROOT] = process_root,
@@ -91,6 +100,9 @@
     [CONFIG_PARAMS] = process_config_params,
     [GAIN_LEVEL_MAPPING] = process_gain_db_to_level_map,
     [ACDB_METAINFO_KEY] = process_acdb_metainfo_key,
+    [MICROPHONE_CHARACTERISTIC] = process_microphone_characteristic,
+    [SND_DEV] = process_snd_dev,
+    [MIC_INFO] = process_mic_info,
 };
 
 static section_t section;
@@ -103,6 +115,98 @@
 
 static struct platform_info my_data;
 
+
+struct audio_string_to_enum {
+    const char* name;
+    unsigned int value;
+};
+
+static snd_device_t in_snd_device;
+
+static const struct audio_string_to_enum mic_locations[AUDIO_MICROPHONE_LOCATION_CNT] = {
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_LOCATION_UNKNOWN),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_LOCATION_MAINBODY),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_LOCATION_MAINBODY_MOVABLE),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_LOCATION_PERIPHERAL),
+};
+
+static const struct audio_string_to_enum mic_directionalities[AUDIO_MICROPHONE_DIRECTIONALITY_CNT] = {
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_OMNI),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_BI_DIRECTIONAL),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_UNKNOWN),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_CARDIOID),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_HYPER_CARDIOID),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_DIRECTIONALITY_SUPER_CARDIOID),
+};
+
+static const struct audio_string_to_enum mic_channel_mapping[AUDIO_MICROPHONE_CHANNEL_MAPPING_CNT] = {
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED),
+};
+
+static const struct audio_string_to_enum device_in_types[] = {
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_AMBIENT),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_COMMUNICATION),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_HDMI),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_VOICE_CALL),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_TELEPHONY_RX),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BACK_MIC),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_DEVICE),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_FM_TUNER),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_TV_TUNER),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_LINE),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_SPDIF),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_A2DP),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_LOOPBACK),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_IP),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BUS),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_PROXY),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_HEADSET),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_BLE),
+    AUDIO_MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_DEFAULT),
+};
+
+enum {
+    AUDIO_MICROPHONE_CHARACTERISTIC_NONE = 0u, // 0x0
+    AUDIO_MICROPHONE_CHARACTERISTIC_SENSITIVITY = 1u, // 0x1
+    AUDIO_MICROPHONE_CHARACTERISTIC_MAX_SPL = 2u, // 0x2
+    AUDIO_MICROPHONE_CHARACTERISTIC_MIN_SPL = 4u, // 0x4
+    AUDIO_MICROPHONE_CHARACTERISTIC_ORIENTATION = 8u, // 0x8
+    AUDIO_MICROPHONE_CHARACTERISTIC_GEOMETRIC_LOCATION = 16u, // 0x10
+    AUDIO_MICROPHONE_CHARACTERISTIC_ALL = 31u, /* ((((SENSITIVITY | MAX_SPL) | MIN_SPL)
+                                                  | ORIENTATION) | GEOMETRIC_LOCATION) */
+};
+
+static bool find_enum_by_string(const struct audio_string_to_enum * table, const char * name,
+                                int32_t len, unsigned int *value)
+{
+    if (table == NULL) {
+        ALOGE("%s: table is NULL", __func__);
+        return false;
+    }
+
+    if (name == NULL) {
+        ALOGE("null key");
+        return false;
+    }
+
+    for (int i = 0; i < len; i++) {
+        if (!strcmp(table[i].name, name)) {
+            *value = table[i].value;
+            return true;
+        }
+    }
+    return false;
+}
 /*
  * <audio_platform_info>
  * <acdb_ids>
@@ -447,6 +551,291 @@
     return;
 }
 
+static void process_microphone_characteristic(const XML_Char **attr) {
+    struct audio_microphone_characteristic_t microphone;
+    uint32_t curIdx = 0;
+
+    if (strcmp(attr[curIdx++], "valid_mask")) {
+        ALOGE("%s: valid_mask not found", __func__);
+        goto done;
+    }
+    uint32_t valid_mask = atoi(attr[curIdx++]);
+
+    if (strcmp(attr[curIdx++], "device_id")) {
+        ALOGE("%s: device_id not found", __func__);
+        goto done;
+    }
+    if (strlen(attr[curIdx]) > AUDIO_MICROPHONE_ID_MAX_LEN) {
+        ALOGE("%s: device_id %s is too long", __func__, attr[curIdx]);
+        goto done;
+    }
+    strcpy(microphone.device_id, attr[curIdx++]);
+
+    if (strcmp(attr[curIdx++], "type")) {
+        ALOGE("%s: device not found", __func__);
+        goto done;
+    }
+    if (!find_enum_by_string(device_in_types, (char*)attr[curIdx++],
+            ARRAY_SIZE(device_in_types), &microphone.device)) {
+        ALOGE("%s: type %s in %s not found!",
+              __func__, attr[--curIdx], PLATFORM_INFO_XML_PATH);
+        goto done;
+    }
+
+    if (strcmp(attr[curIdx++], "address")) {
+        ALOGE("%s: address not found", __func__);
+        goto done;
+    }
+    if (strlen(attr[curIdx]) > AUDIO_DEVICE_MAX_ADDRESS_LEN) {
+        ALOGE("%s, address %s is too long", __func__, attr[curIdx]);
+        goto done;
+    }
+    strcpy(microphone.address, attr[curIdx++]);
+    if (strlen(microphone.address) == 0) {
+        // If the address is empty, populate the address according to device type.
+        if (microphone.device == AUDIO_DEVICE_IN_BUILTIN_MIC) {
+            strcpy(microphone.address, AUDIO_BOTTOM_MICROPHONE_ADDRESS);
+        } else if (microphone.device == AUDIO_DEVICE_IN_BACK_MIC) {
+            strcpy(microphone.address, AUDIO_BACK_MICROPHONE_ADDRESS);
+        }
+    }
+
+    if (strcmp(attr[curIdx++], "location")) {
+        ALOGE("%s: location not found", __func__);
+        goto done;
+    }
+    if (!find_enum_by_string(mic_locations, (char*)attr[curIdx++],
+            AUDIO_MICROPHONE_LOCATION_CNT, &microphone.location)) {
+        ALOGE("%s: location %s in %s not found!",
+              __func__, attr[--curIdx], PLATFORM_INFO_XML_PATH);
+        goto done;
+    }
+
+    if (strcmp(attr[curIdx++], "group")) {
+        ALOGE("%s: group not found", __func__);
+        goto done;
+    }
+    microphone.group = atoi(attr[curIdx++]);
+
+    if (strcmp(attr[curIdx++], "index_in_the_group")) {
+        ALOGE("%s: index_in_the_group not found", __func__);
+        goto done;
+    }
+    microphone.index_in_the_group = atoi(attr[curIdx++]);
+
+    if (strcmp(attr[curIdx++], "directionality")) {
+        ALOGE("%s: directionality not found", __func__);
+        goto done;
+    }
+    if (!find_enum_by_string(mic_directionalities, (char*)attr[curIdx++],
+                AUDIO_MICROPHONE_DIRECTIONALITY_CNT, &microphone.directionality)) {
+        ALOGE("%s: directionality %s in %s not found!",
+              __func__, attr[--curIdx], PLATFORM_INFO_XML_PATH);
+        goto done;
+    }
+
+    if (strcmp(attr[curIdx++], "num_frequency_responses")) {
+        ALOGE("%s: num_frequency_responses not found", __func__);
+        goto done;
+    }
+    microphone.num_frequency_responses = atoi(attr[curIdx++]);
+    if (microphone.num_frequency_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
+        ALOGE("%s: num_frequency_responses is too large", __func__);
+        goto done;
+    }
+    if (microphone.num_frequency_responses > 0) {
+        if (strcmp(attr[curIdx++], "frequencies")) {
+            ALOGE("%s: frequencies not found", __func__);
+            goto done;
+        }
+        char *token = strtok((char *)attr[curIdx++], " ");
+        uint32_t num_frequencies = 0;
+        while (token) {
+            microphone.frequency_responses[0][num_frequencies++] = atof(token);
+            if (num_frequencies > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
+                ALOGE("%s: num %u of frequency is too large", __func__, num_frequencies);
+                goto done;
+            }
+            token = strtok(NULL, " ");
+        }
+
+        if (strcmp(attr[curIdx++], "responses")) {
+            ALOGE("%s: responses not found", __func__);
+            goto done;
+        }
+        token = strtok((char *)attr[curIdx++], " ");
+        uint32_t num_responses = 0;
+        while (token) {
+            microphone.frequency_responses[1][num_responses++] = atof(token);
+            if (num_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
+                ALOGE("%s: num %u of response is too large", __func__, num_responses);
+                goto done;
+            }
+            token = strtok(NULL, " ");
+        }
+
+        if (num_frequencies != num_responses
+                || num_frequencies != microphone.num_frequency_responses) {
+            ALOGE("%s: num of frequency and response not match: %u, %u, %u",
+                  __func__, num_frequencies, num_responses, microphone.num_frequency_responses);
+            goto done;
+        }
+    }
+
+    if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_SENSITIVITY) {
+        if (strcmp(attr[curIdx++], "sensitivity")) {
+            ALOGE("%s: sensitivity not found", __func__);
+            goto done;
+        }
+        microphone.sensitivity = atof(attr[curIdx++]);
+    } else {
+        microphone.sensitivity = AUDIO_MICROPHONE_SENSITIVITY_UNKNOWN;
+    }
+
+    if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_MAX_SPL) {
+        if (strcmp(attr[curIdx++], "max_spl")) {
+            ALOGE("%s: max_spl not found", __func__);
+            goto done;
+        }
+        microphone.max_spl = atof(attr[curIdx++]);
+    } else {
+        microphone.max_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
+    }
+
+    if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_MIN_SPL) {
+        if (strcmp(attr[curIdx++], "min_spl")) {
+            ALOGE("%s: min_spl not found", __func__);
+            goto done;
+        }
+        microphone.min_spl = atof(attr[curIdx++]);
+    } else {
+        microphone.min_spl = AUDIO_MICROPHONE_SPL_UNKNOWN;
+    }
+
+    if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_ORIENTATION) {
+        if (strcmp(attr[curIdx++], "orientation")) {
+            ALOGE("%s: orientation not found", __func__);
+            goto done;
+        }
+        char *token = strtok((char *)attr[curIdx++], " ");
+        float orientation[3];
+        uint32_t idx = 0;
+        while (token) {
+            orientation[idx++] = atof(token);
+            if (idx > 3) {
+                ALOGE("%s: orientation invalid", __func__);
+                goto done;
+            }
+            token = strtok(NULL, " ");
+        }
+        if (idx != 3) {
+            ALOGE("%s: orientation invalid", __func__);
+            goto done;
+        }
+        microphone.orientation.x = orientation[0];
+        microphone.orientation.y = orientation[1];
+        microphone.orientation.z = orientation[2];
+    } else {
+        microphone.orientation.x = 0.0f;
+        microphone.orientation.y = 0.0f;
+        microphone.orientation.z = 0.0f;
+    }
+
+    if (valid_mask & AUDIO_MICROPHONE_CHARACTERISTIC_GEOMETRIC_LOCATION) {
+        if (strcmp(attr[curIdx++], "geometric_location")) {
+            ALOGE("%s: geometric_location not found", __func__);
+            goto done;
+        }
+        char *token = strtok((char *)attr[curIdx++], " ");
+        float geometric_location[3];
+        uint32_t idx = 0;
+        while (token) {
+            geometric_location[idx++] = atof(token);
+            if (idx > 3) {
+                ALOGE("%s: geometric_location invalid", __func__);
+                goto done;
+            }
+            token = strtok(NULL, " ");
+        }
+        if (idx != 3) {
+            ALOGE("%s: geometric_location invalid", __func__);
+            goto done;
+        }
+        microphone.geometric_location.x = geometric_location[0];
+        microphone.geometric_location.y = geometric_location[1];
+        microphone.geometric_location.z = geometric_location[2];
+    } else {
+        microphone.geometric_location.x = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
+        microphone.geometric_location.y = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
+        microphone.geometric_location.z = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
+    }
+
+    platform_set_microphone_characteristic(my_data.platform, microphone);
+done:
+    return;
+}
+
+static void process_snd_dev(const XML_Char **attr)
+{
+    uint32_t curIdx = 0;
+    in_snd_device = SND_DEVICE_NONE;
+
+    if (strcmp(attr[curIdx++], "in_snd_device")) {
+        ALOGE("%s: snd_device not found", __func__);
+        return;
+    }
+    in_snd_device = platform_get_snd_device_index((char *)attr[curIdx++]);
+    if (in_snd_device < SND_DEVICE_IN_BEGIN ||
+            in_snd_device >= SND_DEVICE_IN_END) {
+        ALOGE("%s: Sound device not valid", __func__);
+        in_snd_device = SND_DEVICE_NONE;
+    }
+
+    return;
+}
+
+static void process_mic_info(const XML_Char **attr)
+{
+    uint32_t curIdx = 0;
+    struct mic_info microphone;
+
+    memset(&microphone.channel_mapping, AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED,
+               sizeof(microphone.channel_mapping));
+
+    if (strcmp(attr[curIdx++], "mic_device_id")) {
+        ALOGE("%s: mic_device_id not found", __func__);
+        goto on_error;
+    }
+    strlcpy(microphone.device_id,
+                (char *)attr[curIdx++], AUDIO_MICROPHONE_ID_MAX_LEN);
+
+    if (strcmp(attr[curIdx++], "channel_mapping")) {
+        ALOGE("%s: channel_mapping not found", __func__);
+        goto on_error;
+    }
+    const char *token = strtok((char *)attr[curIdx++], " ");
+    uint32_t idx = 0;
+    while (token) {
+        if (!find_enum_by_string(mic_channel_mapping, token,
+                AUDIO_MICROPHONE_CHANNEL_MAPPING_CNT,
+                &microphone.channel_mapping[idx++])) {
+            ALOGE("%s: channel_mapping %s in %s not found!",
+                      __func__, attr[--curIdx], PLATFORM_INFO_XML_PATH);
+            goto on_error;
+        }
+        token = strtok(NULL, " ");
+    }
+    microphone.channel_count = idx;
+
+    platform_set_microphone_map(my_data.platform, in_snd_device,
+                                    &microphone);
+    return;
+on_error:
+    in_snd_device = SND_DEVICE_NONE;
+    return;
+}
+
+
 /* process acdb meta info key value */
 static void process_acdb_metainfo_key(const XML_Char **attr)
 {
@@ -516,6 +905,10 @@
             section = GAIN_LEVEL_MAPPING;
         } else if(strcmp(tag_name, "acdb_metainfo_key") == 0) {
             section = ACDB_METAINFO_KEY;
+        } else if (strcmp(tag_name, "microphone_characteristics") == 0) {
+            section = MICROPHONE_CHARACTERISTIC;
+        } else if (strcmp(tag_name, "snd_devices") == 0) {
+            section = SND_DEVICES;
         } else if (strcmp(tag_name, "device") == 0) {
             if ((section != ACDB) && (section != AEC) && (section != NS) &&
                 (section != BACKEND_NAME) && (section != BITWIDTH) &&
@@ -551,21 +944,56 @@
 
             section_process_fn fn = section_table[section];
             fn(attr);
-        }
-        else if (strcmp(tag_name, "aec") == 0) {
+        } else if (strcmp(tag_name, "aec") == 0) {
             if (section != MODULE) {
                 ALOGE("aec tag only supported with MODULE section");
                 return;
             }
             section = AEC;
-        }
-        else if (strcmp(tag_name, "ns") == 0) {
+        } else if (strcmp(tag_name, "ns") == 0) {
             if (section != MODULE) {
                 ALOGE("ns tag only supported with MODULE section");
                 return;
             }
             section = NS;
-        }
+        } else if (strcmp(tag_name, "microphone") == 0) {
+            if (section != MICROPHONE_CHARACTERISTIC) {
+                ALOGE("microphone tag only supported with MICROPHONE_CHARACTERISTIC section");
+                return;
+            }
+            section_process_fn fn = section_table[MICROPHONE_CHARACTERISTIC];
+            fn(attr);
+        } else if (strcmp(tag_name, "input_snd_device") == 0) {
+            if (section != SND_DEVICES) {
+                ALOGE("input_snd_device tag only supported with SND_DEVICES section");
+                return;
+            }
+            section = INPUT_SND_DEVICE;
+        } else if (strcmp(tag_name, "input_snd_device_mic_mapping") == 0) {
+            if (section != INPUT_SND_DEVICE) {
+                ALOGE("input_snd_device_mic_mapping tag only supported with INPUT_SND_DEVICE section");
+                return;
+            }
+            section = INPUT_SND_DEVICE_TO_MIC_MAPPING;
+        } else if (strcmp(tag_name, "snd_dev") == 0) {
+            if (section != INPUT_SND_DEVICE_TO_MIC_MAPPING) {
+                ALOGE("snd_dev tag only supported with INPUT_SND_DEVICE_TO_MIC_MAPPING section");
+                return;
+            }
+            section_process_fn fn = section_table[SND_DEV];
+            fn(attr);
+        } else if (strcmp(tag_name, "mic_info") == 0) {
+            if (section != INPUT_SND_DEVICE_TO_MIC_MAPPING) {
+                ALOGE("mic_info tag only supported with INPUT_SND_DEVICE_TO_MIC_MAPPING section");
+                return;
+            }
+            if (in_snd_device == SND_DEVICE_NONE) {
+                ALOGE("%s: Error in previous tags, do not process mic info", __func__);
+                return;
+            }
+            section_process_fn fn = section_table[MIC_INFO];
+            fn(attr);
+      }
     } else {
             ALOGE("%s: unknown caller!", __func__);
     }
@@ -599,6 +1027,14 @@
         section = ROOT;
     } else if (strcmp(tag_name, "acdb_metainfo_key") == 0) {
         section = ROOT;
+    } else if (strcmp(tag_name, "microphone_characteristics") == 0) {
+        section = ROOT;
+    } else if (strcmp(tag_name, "snd_devices") == 0) {
+        section = ROOT;
+    } else if (strcmp(tag_name, "input_snd_device") == 0) {
+        section = SND_DEVICES;
+    } else if (strcmp(tag_name, "input_snd_device_mic_mapping") == 0) {
+        section = INPUT_SND_DEVICE;
     }
 }