Merge "hal: enable audio zoom feature dynamically"
diff --git a/configs/kona/audio_platform_info.xml b/configs/kona/audio_platform_info.xml
index 09cb923..5b12029 100644
--- a/configs/kona/audio_platform_info.xml
+++ b/configs/kona/audio_platform_info.xml
@@ -56,10 +56,10 @@
             <device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS" module_id="0x10F31" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
             <device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS" module_id="0x10F33" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
             <device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS" module_id="0x10F31" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
-            <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_SB" module_id="0x10F33" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
-            <device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS_SB" module_id="0x10F31" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
-            <device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS_SB" module_id="0x10F33" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
-            <device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS_SB" module_id="0x10F31" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_SB" module_id="0x10F39" instance_id="0x8000" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS_SB" module_id="0x10F38" instance_id="0x8000" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS_SB" module_id="0x10F39" instance_id="0x8000" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS_SB" module_id="0x10F38" instance_id="0x8000" param_id="0x10EAF" param_value="0x01"/>
         </aec>
         <ns>
             <device name="SND_DEVICE_IN_SPEAKER_TMIC_AEC_NS" module_id="0x10F35" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
@@ -68,10 +68,10 @@
             <device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS" module_id="0x10F31" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
             <device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS" module_id="0x10F33" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
             <device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS" module_id="0x10F31" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
-            <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_SB" module_id="0x10F33" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
-            <device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS_SB" module_id="0x10F31" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
-            <device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS_SB" module_id="0x10F33" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
-            <device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS_SB" module_id="0x10F31" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_SB" module_id="0x10F39" instance_id="0x8000" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS_SB" module_id="0x10F38" instance_id="0x8000" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS_SB" module_id="0x10F39" instance_id="0x8000" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS_SB" module_id="0x10F38" instance_id="0x8000" param_id="0x10EAF" param_value="0x02"/>
         </ns>
     </module_ids>
 
diff --git a/configs/kona/audio_platform_info_intcodec.xml b/configs/kona/audio_platform_info_intcodec.xml
index cf271a6..03e0e39 100644
--- a/configs/kona/audio_platform_info_intcodec.xml
+++ b/configs/kona/audio_platform_info_intcodec.xml
@@ -32,6 +32,34 @@
         <device name="AUDIO_DEVICE_IN_BUILTIN_MIC" interface="TX_CDC_DMA_TX_3" codec_type="internal"/>
         <device name="AUDIO_DEVICE_IN_BACK_MIC" interface="TX_CDC_DMA_TX_3" codec_type="internal"/>
     </interface_names>
+
+    <module_ids>
+        <aec>
+            <device name="SND_DEVICE_IN_SPEAKER_TMIC_AEC_NS" module_id="0x10F35" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE" module_id="0x10F34" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS" module_id="0x10F33" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS" module_id="0x10F31" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS" module_id="0x10F33" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS" module_id="0x10F31" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_SB" module_id="0x10F39" instance_id="0x8000" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS_SB" module_id="0x10F38" instance_id="0x8000" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS_SB" module_id="0x10F39" instance_id="0x8000" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS_SB" module_id="0x10F38" instance_id="0x8000" param_id="0x10EAF" param_value="0x01"/>
+        </aec>
+        <ns>
+            <device name="SND_DEVICE_IN_SPEAKER_TMIC_AEC_NS" module_id="0x10F35" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE" module_id="0x10F34" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS" module_id="0x10F33" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS" module_id="0x10F31" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS" module_id="0x10F33" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS" module_id="0x10F31" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_SB" module_id="0x10F39" instance_id="0x8000" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS_SB" module_id="0x10F38" instance_id="0x8000" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS_SB" module_id="0x10F39" instance_id="0x8000" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS_SB" module_id="0x10F38" instance_id="0x8000" param_id="0x10EAF" param_value="0x02"/>
+        </ns>
+    </module_ids>
+
     <pcm_ids>
         <usecase name="USECASE_AUDIO_PLAYBACK_LOW_LATENCY" type="out" id="9"/>
         <usecase name="USECASE_AUDIO_PLAYBACK_OFFLOAD" type="out" id="7"/>
diff --git a/configs/kona/audio_platform_info_qrd.xml b/configs/kona/audio_platform_info_qrd.xml
index 4008c1c..607f650 100644
--- a/configs/kona/audio_platform_info_qrd.xml
+++ b/configs/kona/audio_platform_info_qrd.xml
@@ -32,6 +32,32 @@
         <device name="AUDIO_DEVICE_IN_BUILTIN_MIC" interface="TX_CDC_DMA_TX_3" codec_type="internal"/>
         <device name="AUDIO_DEVICE_IN_BACK_MIC" interface="TX_CDC_DMA_TX_3" codec_type="internal"/>
     </interface_names>
+    <module_ids>
+        <aec>
+            <device name="SND_DEVICE_IN_SPEAKER_TMIC_AEC_NS" module_id="0x10F35" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE" module_id="0x10F34" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS" module_id="0x10F33" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS" module_id="0x10F31" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS" module_id="0x10F33" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS" module_id="0x10F31" instance_id="0x0" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_SB" module_id="0x10F39" instance_id="0x8000" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS_SB" module_id="0x10F38" instance_id="0x8000" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS_SB" module_id="0x10F39" instance_id="0x8000" param_id="0x10EAF" param_value="0x01"/>
+            <device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS_SB" module_id="0x10F38" instance_id="0x8000" param_id="0x10EAF" param_value="0x01"/>
+        </aec>
+        <ns>
+            <device name="SND_DEVICE_IN_SPEAKER_TMIC_AEC_NS" module_id="0x10F35" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE" module_id="0x10F34" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS" module_id="0x10F33" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS" module_id="0x10F31" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS" module_id="0x10F33" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS" module_id="0x10F31" instance_id="0x0" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_SB" module_id="0x10F39" instance_id="0x8000" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_SPEAKER_MIC_AEC_NS_SB" module_id="0x10F38" instance_id="0x8000" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_HANDSET_DMIC_AEC_NS_SB" module_id="0x10F39" instance_id="0x8000" param_id="0x10EAF" param_value="0x02"/>
+            <device name="SND_DEVICE_IN_HANDSET_MIC_AEC_NS_SB" module_id="0x10F38" instance_id="0x8000" param_id="0x10EAF" param_value="0x02"/>
+        </ns>
+    </module_ids>
     <pcm_ids>
         <usecase name="USECASE_AUDIO_PLAYBACK_LOW_LATENCY" type="out" id="9"/>
         <usecase name="USECASE_AUDIO_PLAYBACK_OFFLOAD" type="out" id="7"/>
@@ -71,7 +97,7 @@
         <!-- In the below value string, the value indicates default mono -->
         <!-- speaker. It can be set to either left or right              -->
         <param key="mono_speaker" value="right"/>
-        <param key="spkr_1_tz_name" value="wsatz.13"/>
+        <param key="spkr_2_tz_name" value="wsatz.14"/>
         <param key="true_32_bit" value="true"/>
         <param key="native_audio_mode" value="true"/>
         <param key="hfp_pcm_dev_id" value="39"/>
diff --git a/configs/kona/audio_policy_configuration.xml b/configs/kona/audio_policy_configuration.xml
index 50920b3..829f181 100644
--- a/configs/kona/audio_policy_configuration.xml
+++ b/configs/kona/audio_policy_configuration.xml
@@ -263,17 +263,17 @@
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
                 </devicePort>
                 <devicePort tagName="BT A2DP Out" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP" role="sink"
-                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE">
+                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE AUDIO_FORMAT_APTX_TWSP">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                 </devicePort>
                 <devicePort tagName="BT A2DP Headphones" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES" role="sink"
-                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE">
+                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE AUDIO_FORMAT_APTX_TWSP">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                 </devicePort>
                 <devicePort tagName="BT A2DP Speaker" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER" role="sink"
-                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE">
+                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE AUDIO_FORMAT_APTX_TWSP">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                 </devicePort>
diff --git a/configs/lito/sound_trigger_mixer_paths.xml b/configs/lito/sound_trigger_mixer_paths.xml
index 3ab9c0f..4db6412 100644
--- a/configs/lito/sound_trigger_mixer_paths.xml
+++ b/configs/lito/sound_trigger_mixer_paths.xml
@@ -213,7 +213,7 @@
     <path name="listen-ape-handset-mic">
         <ctl name="VA_AIF1_CAP Mixer DEC0" value="1" />
         <ctl name="VA DEC0 MUX" value="MSM_DMIC" />
-        <ctl name="VA DMIC MUX0" value="DMIC0" />
+        <ctl name="VA DMIC MUX0" value="DMIC4" />
     </path>
 
     <path name="listen-ape-handset-mic-preproc">
@@ -226,8 +226,8 @@
         <ctl name="VA_AIF1_CAP Mixer DEC1" value="1" />
         <ctl name="VA DEC0 MUX" value="MSM_DMIC" />
         <ctl name="VA DEC1 MUX" value="MSM_DMIC" />
-        <ctl name="VA DMIC MUX0" value="DMIC0" />
-        <ctl name="VA DMIC MUX1" value="DMIC1" />
+        <ctl name="VA DMIC MUX0" value="DMIC4" />
+        <ctl name="VA DMIC MUX1" value="DMIC0" />
     </path>
 
     <path name="listen-ape-handset-tmic">
@@ -238,9 +238,9 @@
         <ctl name="VA DEC0 MUX" value="MSM_DMIC" />
         <ctl name="VA DEC1 MUX" value="MSM_DMIC" />
         <ctl name="VA DEC2 MUX" value="MSM_DMIC" />
-        <ctl name="VA DMIC MUX0" value="DMIC0" />
-        <ctl name="VA DMIC MUX1" value="DMIC1" />
-        <ctl name="VA DMIC MUX2" value="DMIC4" />
+        <ctl name="VA DMIC MUX0" value="DMIC4" />
+        <ctl name="VA DMIC MUX1" value="DMIC0" />
+        <ctl name="VA DMIC MUX2" value="DMIC1" />
     </path>
 
     <path name="listen-ape-handset-qmic">
@@ -253,10 +253,10 @@
         <ctl name="VA DEC1 MUX" value="MSM_DMIC" />
         <ctl name="VA DEC2 MUX" value="MSM_DMIC" />
         <ctl name="VA DEC3 MUX" value="MSM_DMIC" />
-        <ctl name="VA DMIC MUX0" value="DMIC0" />
-        <ctl name="VA DMIC MUX1" value="DMIC1" />
-        <ctl name="VA DMIC MUX2" value="DMIC2" />
-        <ctl name="VA DMIC MUX3" value="DMIC4" />
+        <ctl name="VA DMIC MUX0" value="DMIC4" />
+        <ctl name="VA DMIC MUX1" value="DMIC0" />
+        <ctl name="VA DMIC MUX2" value="DMIC1" />
+        <ctl name="VA DMIC MUX3" value="DMIC2" />
     </path>
 
     <path name="listen-ape-headset-mic">
diff --git a/configs/msmnile/audio_policy_configuration.xml b/configs/msmnile/audio_policy_configuration.xml
index 50920b3..829f181 100644
--- a/configs/msmnile/audio_policy_configuration.xml
+++ b/configs/msmnile/audio_policy_configuration.xml
@@ -263,17 +263,17 @@
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
                 </devicePort>
                 <devicePort tagName="BT A2DP Out" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP" role="sink"
-                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE">
+                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE AUDIO_FORMAT_APTX_TWSP">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                 </devicePort>
                 <devicePort tagName="BT A2DP Headphones" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES" role="sink"
-                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE">
+                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE AUDIO_FORMAT_APTX_TWSP">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                 </devicePort>
                 <devicePort tagName="BT A2DP Speaker" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER" role="sink"
-                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE">
+                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_CELT AUDIO_FORMAT_APTX_ADAPTIVE AUDIO_FORMAT_APTX_TWSP">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                 </devicePort>
diff --git a/configs/msmsteppe/audio_policy_configuration.xml b/configs/msmsteppe/audio_policy_configuration.xml
index 5435fad..61ea4e1 100644
--- a/configs/msmsteppe/audio_policy_configuration.xml
+++ b/configs/msmsteppe/audio_policy_configuration.xml
@@ -257,17 +257,17 @@
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
                 </devicePort>
                 <devicePort tagName="BT A2DP Out" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP" role="sink"
-                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC">
+                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_APTX_TWSP">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                 </devicePort>
                 <devicePort tagName="BT A2DP Headphones" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES" role="sink"
-                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC">
+                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_APTX_TWSP">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                 </devicePort>
                 <devicePort tagName="BT A2DP Speaker" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER" role="sink"
-                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC">
+                            encodedFormats="AUDIO_FORMAT_SBC AUDIO_FORMAT_AAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_LDAC AUDIO_FORMAT_APTX_TWSP">
                     <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                              samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                 </devicePort>
diff --git a/hal/acdb.c b/hal/acdb.c
index 7394906..9b43303 100644
--- a/hal/acdb.c
+++ b/hal/acdb.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -28,6 +28,8 @@
 #include <time.h>
 #include "acdb.h"
 #include "platform_api.h"
+#include "audio_extn.h"
+#include <platform.h>
 
 #ifdef INSTANCE_ID_ENABLED
 int check_and_set_instance_id_support(struct mixer* mixer, bool acdb_support)
@@ -57,6 +59,22 @@
 #define check_and_set_instance_id_support(x, y) -ENOSYS
 #endif
 
+void get_platform_file_for_device(struct mixer *mixer, char* platform_info_file)
+{
+    const char *snd_card_name = NULL;
+
+    if (mixer != NULL) {
+        /* Get Sound card name */
+        snd_card_name = mixer_get_name(mixer);
+        if (!snd_card_name) {
+            ALOGE("failed to allocate memory for snd_card_name");
+            return;
+        }
+        /* Get platform info file for target */
+        audio_extn_utils_get_platform_info(snd_card_name, platform_info_file);
+    }
+}
+
 int acdb_init(int snd_card_num)
 {
 
@@ -84,7 +102,7 @@
 
     int result = -1;
     char *cvd_version = NULL;
-
+    char platform_info_file[MIXER_PATH_MAX_LENGTH] = PLATFORM_INFO_XML_PATH;
     const char *snd_card_name = NULL;
     struct acdb_platform_data *my_data = NULL;
 
@@ -100,9 +118,9 @@
     }
 
     list_init(&my_data->acdb_meta_key_list);
-
+    get_platform_file_for_device(mixer, platform_info_file);
     /* Extract META KEY LIST INFO */
-    platform_info_init(PLATFORM_INFO_XML_PATH, my_data, ACDB_EXTN);
+    platform_info_init(platform_info_file, my_data, ACDB_EXTN);
 
     my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
     if (my_data->acdb_handle == NULL) {
diff --git a/hal/audio_extn/Android.mk b/hal/audio_extn/Android.mk
index f9e9c8a..255bc4e 100644
--- a/hal/audio_extn/Android.mk
+++ b/hal/audio_extn/Android.mk
@@ -63,7 +63,7 @@
 
 AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
 
-ifneq ($(filter sdm845 sdm710 qcs605 msmnile kona lito atoll sdm660 msm8937 $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter sdm845 sdm710 qcs605 msmnile kona lito atoll sdm660 msm8937 msm8998 $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
   # B-family platform uses msm8974 code base
   AUDIO_PLATFORM := msm8974
   MULTIPLE_HW_VARIANTS_ENABLED := true
@@ -121,7 +121,7 @@
 
 AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
 
-ifneq ($(filter sdm845 sdm710 msmnile kona lito atoll sdm660 msm8937 $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter sdm845 sdm710 msmnile kona lito atoll sdm660 msm8937 msm8998 $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
   # B-family platform uses msm8974 code base
   AUDIO_PLATFORM := msm8974
   MULTIPLE_HW_VARIANTS_ENABLED := true
@@ -182,7 +182,7 @@
 PRIMARY_HAL_PATH := vendor/qcom/opensource/audio-hal/primary-hal/hal
 AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
 
-ifneq ($(filter sdm845 sdm710 msmnile kona lito atoll sdm660 msm8937 $(MSMSTEPPE) $(TRINKET),$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter sdm845 sdm710 msmnile kona lito atoll sdm660 msm8937 msm8998 $(MSMSTEPPE) $(TRINKET),$(TARGET_BOARD_PLATFORM)),)
   # B-family platform uses msm8974 code base
   AUDIO_PLATFORM := msm8974
 endif
@@ -234,7 +234,7 @@
 #--------------------------------------------
 include $(CLEAR_VARS)
 
-ifneq ($(filter sdm845 sdm710 msmnile kona lito atoll sdm660 msm8937 $(MSMSTEPPE) $(TRINKET),$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter sdm845 sdm710 msmnile kona lito atoll sdm660 msm8937 msm8998 $(MSMSTEPPE) $(TRINKET),$(TARGET_BOARD_PLATFORM)),)
   # B-family platform uses msm8974 code base
   AUDIO_PLATFORM := msm8974
 endif
@@ -289,7 +289,7 @@
 
 include $(CLEAR_VARS)
 
-ifneq ($(filter sdm845 sdm710 msmnile kona lito atoll sdm660 msm8937 $(MSMSTEPPE) $(TRINKET),$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter sdm845 sdm710 msmnile kona lito atoll sdm660 msm8937 msm8998 $(MSMSTEPPE) $(TRINKET),$(TARGET_BOARD_PLATFORM)),)
   # B-family platform uses msm8974 code base
   AUDIO_PLATFORM := msm8974
 endif
@@ -350,7 +350,7 @@
 PRIMARY_HAL_PATH := vendor/qcom/opensource/audio-hal/primary-hal/hal
 AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
 
-ifneq ($(filter sdm845 sdm710 msmnile kona lito atoll sdm660 msm8937 $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter sdm845 sdm710 msmnile kona lito atoll sdm660 msm8937 msm8998 $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
   # B-family platform uses msm8974 code base
   AUDIO_PLATFORM := msm8974
   MULTIPLE_HW_VARIANTS_ENABLED := true
@@ -410,7 +410,7 @@
 PRIMARY_HAL_PATH := vendor/qcom/opensource/audio-hal/primary-hal/hal
 AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
 
-ifneq ($(filter sdm845 sdm710 msmnile kona lito sdm660 msm8937 $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter sdm845 sdm710 msmnile kona lito sdm660 msm8937 msm8998 $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
   # B-family platform uses msm8974 code base
   AUDIO_PLATFORM := msm8974
   MULTIPLE_HW_VARIANTS_ENABLED := true
@@ -469,7 +469,7 @@
 PRIMARY_HAL_PATH := vendor/qcom/opensource/audio-hal/primary-hal/hal
 AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
 
-ifneq ($(filter sdm845 sdm710 msmnile kona lito sdm660 msm8937 $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter sdm845 sdm710 msmnile kona lito sdm660 msm8937 msm8998 $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
   # B-family platform uses msm8974 code base
   AUDIO_PLATFORM := msm8974
   MULTIPLE_HW_VARIANTS_ENABLED := true
@@ -528,7 +528,7 @@
 PRIMARY_HAL_PATH := vendor/qcom/opensource/audio-hal/primary-hal/hal
 AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
 
-ifneq ($(filter sdm845 sdm710 msmnile kona lito sdm660 msm8937 $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter sdm845 sdm710 msmnile kona lito sdm660 msm8937 msm8998 $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
   # B-family platform uses msm8974 code base
   AUDIO_PLATFORM := msm8974
   MULTIPLE_HW_VARIANTS_ENABLED := true
@@ -590,7 +590,7 @@
 PRIMARY_HAL_PATH := vendor/qcom/opensource/audio-hal/primary-hal/hal
 AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
 
-ifneq ($(filter sdm845 sdm710 msmnile kona lito sdm660 msm8937 $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter sdm845 sdm710 msmnile kona lito sdm660 msm8937 msm8998 $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
   # B-family platform uses msm8974 code base
   AUDIO_PLATFORM := msm8974
   MULTIPLE_HW_VARIANTS_ENABLED := true
@@ -660,7 +660,7 @@
 PRIMARY_HAL_PATH := vendor/qcom/opensource/audio-hal/primary-hal/hal
 AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
 
-ifneq ($(filter sdm845 sdm710 msmnile kona lito sdm660 msm8937 $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter sdm845 sdm710 msmnile kona lito sdm660 msm8937 msm8998 $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
   # B-family platform uses msm8974 code base
   AUDIO_PLATFORM := msm8974
   MULTIPLE_HW_VARIANTS_ENABLED := true
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index 19c839c..c9ab383 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -678,7 +678,6 @@
     uint32_t sampling_rate;
     uint32_t bitrate;
     uint32_t bits_per_sample;
-    struct aac_frame_size_control_t frame_ctl;
 } audio_aac_encoder_config;
 #endif
 
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 981e0d7..58de600 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -46,6 +46,7 @@
 #include <cutils/properties.h>
 #include <log/log.h>
 #include <unistd.h>
+#include <sched.h>
 
 #include "audio_hw.h"
 #include "audio_extn.h"
@@ -1106,6 +1107,7 @@
 bool usb_is_tunnel_supported();
 bool usb_alive(int card);
 bool usb_connected(struct str_parms *parms);
+char *usb_usbid(void);
 unsigned long usb_find_service_interval(bool min, bool playback);
 int usb_altset_for_service_interval(bool is_playback,
                                                unsigned long service_interval,
@@ -1266,6 +1268,15 @@
     return ret_val;
 }
 
+char *audio_extn_usb_usbid(void)
+{
+    char *ret_val = NULL;
+    if (is_usb_offload_enabled)
+        ret_val = usb_usbid();
+
+    return ret_val;
+}
+
 unsigned long audio_extn_usb_find_service_interval(bool min, bool playback)
 {
     unsigned long ret_val = 0;
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 0bd8877..043ce48 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -283,6 +283,7 @@
                                                uint32_t *bit_width,
                                                uint32_t *sample_rate,
                                                uint32_t *channel_count);
+char *audio_extn_usb_usbid(void);
 int audio_extn_usb_set_service_interval(bool playback,
                                         unsigned long service_interval,
                                         bool *reconfig);
diff --git a/hal/audio_extn/maxxaudio.c b/hal/audio_extn/maxxaudio.c
index 8830486..d6329fa 100644
--- a/hal/audio_extn/maxxaudio.c
+++ b/hal/audio_extn/maxxaudio.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018-2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -43,7 +43,9 @@
 
 #define MA_QDSP_PARAM_INIT      "maxxaudio_qdsp_initialize"
 #define MA_QDSP_PARAM_DEINIT    "maxxaudio_qdsp_uninitialize"
+#define MA_QDSP_IS_FEATURE_USED "maxxaudio_qdsp_is_feature_supported"
 #define MA_QDSP_SET_LR_SWAP     "maxxaudio_qdsp_set_lr_swap"
+#define MA_QDSP_SET_ORIENTATION "maxxaudio_qdsp_set_orientation"
 #define MA_QDSP_SET_MODE        "maxxaudio_qdsp_set_sound_mode"
 #define MA_QDSP_SET_VOL         "maxxaudio_qdsp_set_volume"
 #define MA_QDSP_SET_VOLT        "maxxaudio_qdsp_set_volume_table"
@@ -87,8 +89,8 @@
     MA_CMD_VOL,
     MA_CMD_SWAP_ENABLE,
     MA_CMD_SWAP_DISABLE,
-    MA_CMD_SOFT_MUTE_ENABLE,
-    MA_CMD_SOFT_MUTE_DISABLE,
+    MA_CMD_ROTATE_ENABLE,
+    MA_CMD_ROTATE_DISABLE,
 } ma_cmd_t;
 
 typedef struct ma_audio_cal_version {
@@ -120,9 +122,14 @@
 
 typedef bool (*ma_param_deinit_t)(ma_audio_cal_handle_t *);
 
+typedef bool (*ma_is_feature_used_t)(ma_audio_cal_handle_t, const char *);
+
 typedef bool (*ma_set_lr_swap_t)(ma_audio_cal_handle_t,
                                  const struct ma_audio_cal_settings *, bool);
 
+typedef bool (*ma_set_orientation_t)(ma_audio_cal_handle_t,
+                                     const struct ma_audio_cal_settings *, int);
+
 typedef bool (*ma_set_sound_mode_t)(ma_audio_cal_handle_t,
                                     const struct ma_audio_cal_settings *,
                                     unsigned int);
@@ -144,12 +151,16 @@
     pthread_mutex_t lock;
     ma_param_init_t          ma_param_init;
     ma_param_deinit_t        ma_param_deinit;
+    ma_is_feature_used_t     ma_is_feature_used;
     ma_set_lr_swap_t         ma_set_lr_swap;
+    ma_set_orientation_t     ma_set_orientation;
     ma_set_sound_mode_t      ma_set_sound_mode;
     ma_set_volume_t          ma_set_volume;
     ma_set_volume_table_t    ma_set_volume_table;
     ma_set_param_t           ma_set_param;
     bool speaker_lr_swap;
+    bool orientation_used;
+    int dispaly_orientation;
 };
 
 ma_audio_cal_handle_t g_ma_audio_cal_handle = NULL;
@@ -175,6 +186,13 @@
                                    audio_cal_settings, swap);
 }
 
+static bool ma_set_orientation_l(
+    const struct ma_audio_cal_settings *audio_cal_settings, int orientation)
+{
+    return my_data->ma_set_orientation(g_ma_audio_cal_handle,
+                                   audio_cal_settings, orientation);
+}
+
 static bool ma_set_volume_table_l(
     const struct ma_audio_cal_settings *audio_cal_settings,
     size_t num_streams, struct ma_state *volume_table)
@@ -192,6 +210,25 @@
                                  audio_cal_settings, index, value);
 }
 
+static void print_state_log()
+{
+    ALOGD("%s: send volume table -(%i,%f,%s),(%i,%f,%s),(%i,%f,%s),(%i,%f,%s),"
+          "(%i,%f,%s),(%i,%f,%s)", __func__,
+          STREAM_VOICE, ma_cur_state_table[STREAM_VOICE].vol,
+          ma_cur_state_table[STREAM_VOICE].active ? "T" : "F",
+          STREAM_SYSTEM, ma_cur_state_table[STREAM_SYSTEM].vol,
+          ma_cur_state_table[STREAM_SYSTEM].active ? "T" : "F",
+          STREAM_RING, ma_cur_state_table[STREAM_RING].vol,
+          ma_cur_state_table[STREAM_RING].active ? "T" : "F",
+          STREAM_MUSIC, ma_cur_state_table[STREAM_MUSIC].vol,
+          ma_cur_state_table[STREAM_MUSIC].active ? "T" : "F",
+          STREAM_ALARM, ma_cur_state_table[STREAM_ALARM].vol,
+          ma_cur_state_table[STREAM_ALARM].active ? "T" : "F",
+          STREAM_NOTIFICATION, ma_cur_state_table[STREAM_NOTIFICATION].vol,
+          ma_cur_state_table[STREAM_NOTIFICATION].active ? "T" : "F");
+
+}
+
 static inline bool valid_usecase(struct audio_usecase *usecase)
 {
     if ((usecase->type == PCM_PLAYBACK) &&
@@ -262,13 +299,7 @@
                         ALOGV("ma_set_volume_table_l success");
                     else
                         ALOGE("ma_set_volume_table_l returned with error.");
-
-                    ALOGV("%s: send volume table === Start", __func__);
-                    for (i = 0; i < STREAM_MAX_TYPES; i++)
-                        ALOGV("%s: stream(%d) volume(%f) active(%s)", __func__,
-                              i, ma_cur_state_table[i].vol,
-                              ma_cur_state_table[i].active ? "T" : "F");
-                    ALOGV("%s: send volume table === End", __func__);
+                    print_state_log();
                     break;
 
                 case MA_CMD_SWAP_ENABLE:
@@ -290,22 +321,24 @@
                         ALOGE("ma_set_lr_swap_l disable returned with error.");
                     break;
 
-                case MA_CMD_SOFT_MUTE_ENABLE:
-                    if (usecase->id == USECASE_AUDIO_PLAYBACK_LOW_LATENCY) break;
-
-                    ma_cal.effect_scope_flag = EFFECTIVE_SCOPE_RTC;
-                    ret = ma_set_param_l(&ma_cal, MAAP_OUTPUT_GAIN, -96);
-                    if (!ret)
-                        ALOGE("soft mute enable returned with error.");
+                case MA_CMD_ROTATE_ENABLE:
+                    if (ma_cal.common.device & AUDIO_DEVICE_OUT_SPEAKER) {
+                        ret = ma_set_orientation_l(&ma_cal, my_data->dispaly_orientation);
+                        if (ret)
+                            ALOGV("ma_set_orientation_l %d returned with success.",
+                                  my_data->dispaly_orientation);
+                        else
+                            ALOGE("ma_set_orientation_l %d returned with error.",
+                                  my_data->dispaly_orientation);
+                    }
                     break;
 
-                case MA_CMD_SOFT_MUTE_DISABLE:
-                    if (usecase->id == USECASE_AUDIO_PLAYBACK_LOW_LATENCY) break;
-
-                    ma_cal.effect_scope_flag = EFFECTIVE_SCOPE_RTC;
-                    ret = ma_set_param_l(&ma_cal, MAAP_OUTPUT_GAIN, 0);
-                    if (!ret)
-                        ALOGE("soft mute disable returned with error.");
+                case MA_CMD_ROTATE_DISABLE:
+                    ret = ma_set_orientation_l(&ma_cal, 0);
+                    if (ret)
+                        ALOGV("ma_set_orientation_l 0 returned with success.");
+                    else
+                        ALOGE("ma_set_orientation_l 0 returned with error.");
                     break;
 
                 default:
@@ -351,6 +384,14 @@
         check_and_send_all_audio_cal(adev, MA_CMD_SWAP_DISABLE);
 }
 
+static void ma_set_rotation_l(struct audio_device *adev, int orientation)
+{
+    if (orientation != 0)
+        check_and_send_all_audio_cal(adev, MA_CMD_ROTATE_ENABLE);
+    else
+        check_and_send_all_audio_cal(adev, MA_CMD_ROTATE_DISABLE);
+}
+
 static void ma_support_usb(bool enable, int card)
 {
     char path[128];
@@ -430,7 +471,7 @@
 
     my_data->waves_handle = dlopen(lib_path, RTLD_NOW);
     if (my_data->waves_handle == NULL) {
-         ALOGE("%s: DLOPEN failed for %s", __func__, LIB_MA_PARAM);
+         ALOGE("%s: DLOPEN failed for %s, %s", __func__, LIB_MA_PARAM, dlerror());
          goto error;
     } else {
          ALOGV("%s: DLOPEN successful for %s", __func__, LIB_MA_PARAM);
@@ -449,6 +490,18 @@
              goto error;
          }
 
+        my_data->ma_is_feature_used = (ma_is_feature_used_t)dlsym(my_data->waves_handle,
+                                    MA_QDSP_IS_FEATURE_USED);
+        if (!my_data->ma_is_feature_used) {
+            ALOGV("%s: dlsym error %s for ma_is_feature_used", __func__, dlerror());
+        }
+
+        my_data->ma_set_orientation = (ma_set_orientation_t)dlsym(my_data->waves_handle,
+                                        MA_QDSP_SET_ORIENTATION);
+        if (!my_data->ma_set_orientation) {
+            ALOGV("%s: dlsym error %s for ma_set_orientation", __func__, dlerror());
+        }
+
          my_data->ma_set_lr_swap = (ma_set_lr_swap_t)dlsym(my_data->waves_handle,
                                     MA_QDSP_SET_LR_SWAP);
          if (!my_data->ma_set_lr_swap) {
@@ -547,6 +600,13 @@
     }
 
     my_data->speaker_lr_swap = false;
+    my_data->orientation_used = false;
+    my_data->dispaly_orientation = 0;
+
+    if (g_ma_audio_cal_handle && my_data->ma_is_feature_used) {
+        my_data->orientation_used = my_data->ma_is_feature_used(
+                g_ma_audio_cal_handle, "SET_ORIENTATION");
+    }
 
     return;
 
@@ -577,7 +637,6 @@
                              float vol, bool active)
 {
     bool ret = false;
-    bool first_enable = false;
     struct ma_state pr_mstate;
 
     if (stream_type >= STREAM_MAX_TYPES ||
@@ -601,17 +660,10 @@
     if (pr_mstate.vol != vol || pr_mstate.active != active) {
 
         pthread_mutex_lock(&my_data->lock);
-        // get active state before updating
-        first_enable = (!is_active()) && active;
 
         ma_cur_state_table[(ma_stream_type_t)stream_type].vol = vol;
         ma_cur_state_table[(ma_stream_type_t)stream_type].active = active;
 
-        if (first_enable) //all F -> one of T
-            ret = check_and_send_all_audio_cal(adev, MA_CMD_SOFT_MUTE_DISABLE);
-        else if (!is_active()) // all F
-            ret = check_and_send_all_audio_cal(adev, MA_CMD_SOFT_MUTE_ENABLE);
-
         ret = check_and_send_all_audio_cal(adev, MA_CMD_VOL);
 
         pthread_mutex_unlock(&my_data->lock);
@@ -647,17 +699,19 @@
     pthread_mutex_lock(&my_data->lock);
 
     if (is_active()) {
-        if (ma_cal.common.device & AUDIO_DEVICE_OUT_SPEAKER)
-            ma_set_swap_l(usecase->stream.out->dev, my_data->speaker_lr_swap);
-        else
-            ma_set_swap_l(usecase->stream.out->dev, false);
 
-        ALOGV("%s: send volume table === Start", __func__);
-        for (i = 0; i < STREAM_MAX_TYPES; i++)
-            ALOGV("%s: stream(%d) volume(%f) active(%s)", __func__, i,
-                   ma_cur_state_table[i].vol,
-                   ma_cur_state_table[i].active ? "T" : "F");
-        ALOGV("%s: send volume table === End", __func__);
+        if (ma_cal.common.device & AUDIO_DEVICE_OUT_SPEAKER) {
+            if (my_data->orientation_used)
+                ma_set_rotation_l(usecase->stream.out->dev,
+                                  my_data->dispaly_orientation);
+            else
+                ma_set_swap_l(usecase->stream.out->dev, my_data->speaker_lr_swap);
+        } else {
+            if (my_data->orientation_used)
+                ma_set_rotation_l(usecase->stream.out->dev, 0);
+            else
+                ma_set_swap_l(usecase->stream.out->dev, false);
+        }
 
         if (!ma_set_volume_table_l(&ma_cal,
                                    STREAM_MAX_TYPES,
@@ -665,6 +719,7 @@
             ALOGE("ma_set_volume_table_l returned with error.");
         else
             ALOGV("ma_set_volume_table_l success");
+        print_state_log();
 
     }
     pthread_mutex_unlock(&my_data->lock);
@@ -695,7 +750,12 @@
             my_data->speaker_lr_swap = false;
             break;
         }
-        ma_set_swap_l(adev, my_data->speaker_lr_swap);
+        my_data->dispaly_orientation = val;
+
+        if (my_data->orientation_used)
+            ma_set_rotation_l(adev, my_data->dispaly_orientation);
+        else
+            ma_set_swap_l(adev, my_data->speaker_lr_swap);
     }
 
     // check connect status
diff --git a/hal/audio_extn/maxxaudio.h b/hal/audio_extn/maxxaudio.h
index 1ab7f80..4f45f79 100644
--- a/hal/audio_extn/maxxaudio.h
+++ b/hal/audio_extn/maxxaudio.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018-2019 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -25,4 +25,4 @@
 void ma_set_parameters(struct audio_device *adev,
                                   struct str_parms *parms);
 bool ma_supported_usb();
-#endif /* MAXXAUDIO_H_ */
\ No newline at end of file
+#endif /* MAXXAUDIO_H_ */
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index 9981ef0..e6859fe 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -55,6 +55,7 @@
 #define SAMPLE_RATE_11025         11025
 #define SAMPLE_RATE_192000        192000
 // Supported sample rates for USB
+#define USBID_SIZE                16
 static uint32_t supported_sample_rates[] =
     {384000, 352800, 192000, 176400, 96000, 88200, 64000, 48000, 44100, 32000, 22050, 16000, 11025, 8000};
 static uint32_t supported_sample_rates_mask[2];
@@ -97,6 +98,7 @@
     int usb_sidetone_vol_min;
     int usb_sidetone_vol_max;
     int endian;
+    char usbid[USBID_SIZE];
 };
 
 struct usb_module {
@@ -620,6 +622,48 @@
     return ret;
 }
 
+static int usb_get_usbid(struct usb_card_config *usb_card_info,
+                              int card)
+{
+    int32_t fd=-1;
+    char path[128];
+    int ret = 0;
+
+    memset(usb_card_info->usbid, 0, sizeof(usb_card_info->usbid));
+
+    ret = snprintf(path, sizeof(path), "/proc/asound/card%u/usbid",
+             card);
+
+    if (ret < 0) {
+        ALOGE("%s: failed on snprintf (%d) to path %s\n",
+          __func__, ret, path);
+        goto done;
+    }
+
+    fd = open(path, O_RDONLY);
+    if (fd < 0) {
+        ALOGE("%s: error failed to open file %s error: %d\n",
+              __func__, path, errno);
+        ret = -EINVAL;
+        goto done;
+    }
+
+    if (read(fd, usb_card_info->usbid, USBID_SIZE - 1) < 0) {
+        ALOGE("file read error\n");
+        ret = -EINVAL;
+        usb_card_info->usbid[0] = '\0';
+        goto done;
+    }
+
+    strtok(usb_card_info->usbid, "\n");
+
+done:
+    if (fd >= 0)
+        close(fd);
+
+    return ret;
+}
+
 static int usb_get_device_cap_config(struct usb_card_config *usb_card_info,
                                       int card)
 {
@@ -1164,6 +1208,10 @@
     }
     list_init(&usb_card_info->usb_device_conf_list);
     if (usb_output_device(device)) {
+        if (usb_get_usbid(usb_card_info, card) < 0) {
+            ALOGE("parse card %d usbid fail", card);
+        }
+
         if (!usb_get_device_pb_config(usb_card_info, card)){
             usb_card_info->usb_card = card;
             usb_card_info->usb_device_type = device;
@@ -1172,6 +1220,10 @@
             goto exit;
         }
     } else if (usb_input_device(device)) {
+        if (usb_get_usbid(usb_card_info, card) < 0) {
+            ALOGE("parse card %d usbid fail", card);
+        }
+
         if (!usb_get_device_cap_config(usb_card_info, card)) {
             usb_card_info->usb_card = card;
             usb_card_info->usb_device_type = device;
@@ -1485,6 +1537,22 @@
     return usb_connected;
 }
 
+char *usb_usbid()
+{
+    struct usb_card_config *card_info;
+
+    if (usbmod == NULL)
+        return NULL;
+
+    if (list_empty(&usbmod->usb_card_conf_list))
+        return NULL;
+
+    card_info = node_to_item(list_head(&usbmod->usb_card_conf_list),\
+                             struct usb_card_config, list);
+
+    return strdup(card_info->usbid);
+}
+
 void usb_init(void *adev)
 {
     if (usbmod == NULL) {
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 5959101..41a3d5d 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -1068,6 +1068,8 @@
     audio_extn_sound_trigger_update_stream_status(usecase, ST_EVENT_STREAM_BUSY);
     audio_extn_listen_update_stream_status(usecase, LISTEN_EVENT_STREAM_BUSY);
     audio_extn_utils_send_app_type_cfg(adev, usecase);
+    if (audio_extn_is_maxx_audio_enabled())
+        audio_extn_ma_set_device(usecase);
     audio_extn_utils_send_audio_calibration(adev, usecase);
     if ((usecase->type == PCM_PLAYBACK) && is_offload_usecase(usecase->id)) {
         out = usecase->stream.out;
@@ -1076,7 +1078,10 @@
     }
     audio_extn_set_custom_mtmx_params(adev, usecase, true);
 
-    strlcpy(mixer_path, use_case_table[usecase->id], MIXER_PATH_MAX_LENGTH);
+    // we shouldn't truncate mixer_path
+    ALOGW_IF(strlcpy(mixer_path, use_case_table[usecase->id], sizeof(mixer_path))
+            >= sizeof(mixer_path), "%s: truncation on mixer path", __func__);
+    // this also appends to mixer_path
     platform_add_backend_name(mixer_path, snd_device, usecase);
     ALOGD("%s: apply mixer and update path: %s", __func__, mixer_path);
     ret = audio_route_apply_and_update_path(adev->audio_route, mixer_path);
@@ -1105,7 +1110,10 @@
         snd_device = usecase->in_snd_device;
     else
         snd_device = usecase->out_snd_device;
-    strlcpy(mixer_path, use_case_table[usecase->id], MIXER_PATH_MAX_LENGTH);
+    // we shouldn't truncate mixer_path
+    ALOGW_IF(strlcpy(mixer_path, use_case_table[usecase->id], sizeof(mixer_path))
+            >= sizeof(mixer_path), "%s: truncation on mixer path", __func__);
+    // this also appends to mixer_path
     platform_add_backend_name(mixer_path, snd_device, usecase);
     ALOGD("%s: reset and update mixer path: %s", __func__, mixer_path);
     audio_route_reset_and_update_path(adev->audio_route, mixer_path);
@@ -1665,6 +1673,10 @@
                 ((uc_info->devices & backend_check_cond) &&
                  (((usecase->devices & ~AUDIO_DEVICE_BIT_IN) & AUDIO_DEVICE_IN_ALL_CODEC_BACKEND) ||
                   (usecase->type == VOIP_CALL))) &&
+                ((uc_info->type == VOICE_CALL &&
+                  usecase->devices == AUDIO_DEVICE_IN_VOICE_CALL) ||
+                 platform_check_backends_match(snd_device,\
+                                              usecase->in_snd_device)) &&
                 (usecase->id != USECASE_AUDIO_SPKR_CALIB_TX)) {
             ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
                   __func__, use_case_table[usecase->id],
@@ -1846,8 +1858,14 @@
 
     for (channel_count = channels; ((channel_count >= DEFAULT_CHANNEL_COUNT) &&
                                     (num_masks < max_masks)); channel_count--) {
-            supported_channel_masks[num_masks++] =
-                    audio_channel_mask_for_index_assignment_from_count(channel_count);
+        const audio_channel_mask_t mask =
+                audio_channel_in_mask_from_count(channel_count);
+        supported_channel_masks[num_masks++] = mask;
+        const audio_channel_mask_t index_mask =
+                audio_channel_mask_for_index_assignment_from_count(channel_count);
+        if (mask != index_mask && num_masks < max_masks) { // ensure index mask added.
+            supported_channel_masks[num_masks++] = index_mask;
+        }
     }
 
     ALOGV("%s: %s supported ch %d supported_channel_masks[0] %08x num_masks %d", __func__,
@@ -2257,7 +2275,8 @@
                                  (usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND)) ||
                                  ((vc_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) &&
                                  (usecase->devices & AUDIO_DEVICE_IN_ALL_CODEC_BACKEND)) ||
-                                (usecase->devices == AUDIO_DEVICE_IN_VOICE_CALL))) {
+                                 (vc_usecase->devices == AUDIO_DEVICE_OUT_HEARING_AID) ||
+                                 (usecase->devices == AUDIO_DEVICE_IN_VOICE_CALL))) {
                 in_snd_device = vc_usecase->in_snd_device;
                 out_snd_device = vc_usecase->out_snd_device;
             }
@@ -2334,6 +2353,10 @@
                     platform_set_echo_reference(adev, false, AUDIO_DEVICE_NONE);
                 } else if (usecase->id == USECASE_AUDIO_RECORD_AFE_PROXY) {
                     out_device = AUDIO_DEVICE_OUT_TELEPHONY_TX;
+                } else {
+                    /* forcing speaker o/p device to get matching i/p pair
+                       in case o/p is not routed from same primary HAL */
+                    out_device = AUDIO_DEVICE_OUT_SPEAKER;
                 }
                 in_snd_device = platform_get_input_snd_device(adev->platform, out_device);
             }
@@ -2557,7 +2580,7 @@
          }
     }
 
-    if (usecase == voip_usecase) {
+    if (usecase->type != PCM_CAPTURE && usecase == voip_usecase) {
         struct stream_out *voip_out = voip_usecase->stream.out;
         audio_extn_utils_send_app_type_gain(adev,
                                             voip_out->app_type_cfg.app_type,
@@ -2967,6 +2990,8 @@
 
     ALOGV("%s", __func__);
     lock_output_stream(out);
+    out->offload_state = OFFLOAD_STATE_IDLE;
+    out->playback_started = 0;
     for (;;) {
         struct offload_cmd *cmd = NULL;
         stream_callback_event_t event;
@@ -3185,13 +3210,19 @@
             ALOGE("%s: audio_extn_ip_hdlr_intf_close failed %d",__func__, ret);
     }
 
+    /* 1) media + voip output routing to handset must route media back to
+          speaker when voip stops.
+       2) trigger voip input to reroute when voip output changes to
+          hearing aid. */
     if (has_voip_usecase ||
             out->devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
         struct listnode *node;
         struct audio_usecase *usecase;
         list_for_each(node, &adev->usecase_list) {
             usecase = node_to_item(node, struct audio_usecase, list);
-            if (usecase->type == PCM_CAPTURE || usecase == uc_info)
+            if ((usecase->type == PCM_CAPTURE &&
+                     usecase->id != USECASE_AUDIO_RECORD_VOIP)
+                || usecase == uc_info)
                 continue;
 
             ALOGD("%s: select_devices at usecase(%d: %s) after removing the usecase(%d: %s)",
@@ -5068,6 +5099,7 @@
                     pthread_mutex_lock(&adev->lock);
                     select_devices(adev, out->usecase);
                     if (!audio_extn_passthru_is_supported_backend_edid_cfg(adev, out)) {
+                        pthread_mutex_unlock(&adev->lock);
                         ret = -EINVAL;
                         goto exit;
                     }
@@ -5707,6 +5739,17 @@
     ALOGV("%s requested config.period_count = %d", __func__, config->period_count);
 }
 
+// Read offset for the positional timestamp from a persistent vendor property.
+// This is to workaround apparent inaccuracies in the timing information that
+// is used by the AAudio timing model. The inaccuracies can cause glitches.
+static int64_t get_mmap_out_time_offset() {
+    const int32_t kDefaultOffsetMicros = 0;
+    int32_t mmap_time_offset_micros = property_get_int32(
+        "persist.audio.out_mmap_delay_micros", kDefaultOffsetMicros);
+    ALOGI("mmap_time_offset_micros = %d for output", mmap_time_offset_micros);
+    return mmap_time_offset_micros * (int64_t)1000;
+}
+
 static int out_create_mmap_buffer(const struct audio_stream_out *stream,
                                   int32_t min_size_frames,
                                   struct audio_mmap_buffer_info *info)
@@ -5799,6 +5842,8 @@
         goto exit;
     }
 
+    out->mmap_time_offset_nanos = get_mmap_out_time_offset();
+
     out->standby = false;
     ret = 0;
 
@@ -5842,7 +5887,8 @@
         ALOGE("%s: %s", __func__, pcm_get_error(out->pcm));
         return ret;
     }
-    position->time_nanoseconds = ts.tv_sec*1000000000LL + ts.tv_nsec;
+    position->time_nanoseconds = ts.tv_sec*1000000000LL + ts.tv_nsec
+            + out->mmap_time_offset_nanos;
     return 0;
 }
 
@@ -6486,6 +6532,17 @@
     return ret;
 }
 
+// Read offset for the positional timestamp from a persistent vendor property.
+// This is to workaround apparent inaccuracies in the timing information that
+// is used by the AAudio timing model. The inaccuracies can cause glitches.
+static int64_t in_get_mmap_time_offset() {
+    const int32_t kDefaultOffsetMicros = 0;
+    int32_t mmap_time_offset_micros = property_get_int32(
+            "persist.audio.in_mmap_delay_micros", kDefaultOffsetMicros);
+    ALOGI("mmap_time_offset_micros = %d for input", mmap_time_offset_micros);
+    return mmap_time_offset_micros * (int64_t)1000;
+}
+
 static int in_create_mmap_buffer(const struct audio_stream_in *stream,
                                   int32_t min_size_frames,
                                   struct audio_mmap_buffer_info *info)
@@ -6581,6 +6638,8 @@
         goto exit;
     }
 
+    in->mmap_time_offset_nanos = in_get_mmap_time_offset();
+
     in->standby = false;
     ret = 0;
 
@@ -6621,7 +6680,8 @@
         ALOGE("%s: %s", __func__, pcm_get_error(in->pcm));
         return ret;
     }
-    position->time_nanoseconds = ts.tv_sec*1000000000LL + ts.tv_nsec;
+    position->time_nanoseconds = ts.tv_sec*1000000000LL + ts.tv_nsec
+            + in->mmap_time_offset_nanos;
     return 0;
 }
 
@@ -7642,34 +7702,39 @@
             adev->screen_off = true;
     }
 
-   if(!audio_extn_is_maxx_audio_enabled()) {
-        ret = str_parms_get_int(parms, "rotation", &val);
-        if (ret >= 0) {
-            bool reverse_speakers = false;
-            switch(val) {
-            // FIXME: note that the code below assumes that the speakers are
-            // in the correct placement relative to the user when the device
-            // is rotated 90deg from its default rotation. This assumption
-            // is device-specific, not platform-specific like this code.
-            case 270:
-                reverse_speakers = true;
-                break;
-            case 0:
-            case 90:
-            case 180:
-                break;
-            default:
-                ALOGE("%s: unexpected rotation of %d", __func__, val);
-                status = -EINVAL;
-            }
-            if (status == 0) {
-                // check and set swap
-                //   - check if orientation changed and speaker active
-                //   - set rotation and cache the rotation value
-                platform_check_and_set_swap_lr_channels(adev, reverse_speakers);
-            }
+    ret = str_parms_get_int(parms, "rotation", &val);
+    if (ret >= 0) {
+        bool reverse_speakers = false;
+        int camera_rotation = CAMERA_ROTATION_LANDSCAPE;
+        switch (val) {
+        // FIXME: note that the code below assumes that the speakers are in the correct placement
+        //   relative to the user when the device is rotated 90deg from its default rotation. This
+        //   assumption is device-specific, not platform-specific like this code.
+        case 270:
+            reverse_speakers = true;
+            camera_rotation = CAMERA_ROTATION_INVERT_LANDSCAPE;
+            break;
+        case 0:
+        case 180:
+            camera_rotation = CAMERA_ROTATION_PORTRAIT;
+            break;
+        case 90:
+            camera_rotation = CAMERA_ROTATION_LANDSCAPE;
+            break;
+        default:
+            ALOGE("%s: unexpected rotation of %d", __func__, val);
+            status = -EINVAL;
         }
-   }
+        if (status == 0) {
+            // check and set swap
+            //   - check if orientation changed and speaker active
+            //   - set rotation and cache the rotation value
+            adev->camera_orientation =
+                (adev->camera_orientation & ~CAMERA_ROTATION_MASK) | camera_rotation;
+            if (!audio_extn_is_maxx_audio_enabled())
+                platform_check_and_set_swap_lr_channels(adev, reverse_speakers);
+        }
+    }
 
     ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_SCO_WB, value, sizeof(value));
     if (ret >= 0) {
@@ -7781,6 +7846,32 @@
         }
     }
 
+    //FIXME: to be replaced by proper video capture properties API
+    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_CAMERA_FACING, value, sizeof(value));
+    if (ret >= 0) {
+        int camera_facing = CAMERA_FACING_BACK;
+        if (strcmp(value, AUDIO_PARAMETER_VALUE_FRONT) == 0)
+            camera_facing = CAMERA_FACING_FRONT;
+        else if (strcmp(value, AUDIO_PARAMETER_VALUE_BACK) == 0)
+            camera_facing = CAMERA_FACING_BACK;
+        else {
+            ALOGW("%s: invalid camera facing value: %s", __func__, value);
+            goto done;
+        }
+        adev->camera_orientation =
+                       (adev->camera_orientation & ~CAMERA_FACING_MASK) | camera_facing;
+        struct audio_usecase *usecase;
+        struct listnode *node;
+        list_for_each(node, &adev->usecase_list) {
+            usecase = node_to_item(node, struct audio_usecase, list);
+            struct stream_in *in = usecase->stream.in;
+            if (usecase->type == PCM_CAPTURE && in != NULL &&
+                    in->source == AUDIO_SOURCE_CAMCORDER && !in->standby) {
+                select_devices(adev, in->usecase);
+            }
+        }
+    }
+
     audio_extn_set_parameters(adev, parms);
 done:
     str_parms_destroy(parms);
@@ -8077,6 +8168,10 @@
                                                             devices,
                                                             flags,
                                                             source);
+    ALOGV("%s: enter: flags %#x, is_usb_dev %d, may_use_hifi_record %d,"
+            " sample_rate %u, channel_mask %#x, format %#x",
+            __func__, flags, is_usb_dev, may_use_hifi_record,
+            config->sample_rate, config->channel_mask, config->format);
 
     if (is_usb_dev && (!audio_extn_usb_connected(NULL))) {
         is_usb_dev = false;
@@ -8147,7 +8242,7 @@
     in->direction = MIC_DIRECTION_UNSPECIFIED;
     in->zoom = 0;
 
-    ALOGV("%s: source = %d, config->channel_mask = %d", __func__, source, config->channel_mask);
+    ALOGV("%s: source %d, config->channel_mask %#x", __func__, source, config->channel_mask);
     if (source == AUDIO_SOURCE_VOICE_UPLINK ||
         source == AUDIO_SOURCE_VOICE_DOWNLINK) {
         /* Force channel config requested to mono if incall
@@ -8159,13 +8254,6 @@
         }
     }
 
-    /* Update config params with the requested sample rate and channels */
-    if ((in->device == AUDIO_DEVICE_IN_TELEPHONY_RX) &&
-          (adev->mode != AUDIO_MODE_IN_CALL)) {
-        ret = -EINVAL;
-        goto err_open;
-    }
-
     if (is_usb_dev && may_use_hifi_record) {
         /* HiFi record selects an appropriate format, channel, rate combo
            depending on sink capabilities*/
@@ -9176,6 +9264,8 @@
 
     adev->mic_break_enabled = property_get_bool("vendor.audio.mic_break", false);
 
+    adev->camera_orientation = CAMERA_DEFAULT;
+
     if ((property_get("vendor.audio_hal.period_multiplier",value,NULL) > 0) ||
         (property_get("audio_hal.period_multiplier",value,NULL) > 0)) {
         af_period_multiplier = atoi(value);
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 1a04cff..0b904bd 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -245,6 +245,33 @@
     OFFLOAD_CMD_ERROR,              /* offload playback hit some error */
 };
 
+/*
+ * Camera selection indicated via set_parameters "cameraFacing=front|back and
+ * "rotation=0|90|180|270""
+ */
+enum {
+  CAMERA_FACING_BACK = 0x0,
+  CAMERA_FACING_FRONT = 0x1,
+  CAMERA_FACING_MASK = 0x0F,
+  CAMERA_ROTATION_LANDSCAPE = 0x0,
+  CAMERA_ROTATION_INVERT_LANDSCAPE = 0x10,
+  CAMERA_ROTATION_PORTRAIT = 0x20,
+  CAMERA_ROTATION_MASK = 0xF0,
+  CAMERA_BACK_LANDSCAPE = (CAMERA_FACING_BACK|CAMERA_ROTATION_LANDSCAPE),
+  CAMERA_BACK_INVERT_LANDSCAPE = (CAMERA_FACING_BACK|CAMERA_ROTATION_INVERT_LANDSCAPE),
+  CAMERA_BACK_PORTRAIT = (CAMERA_FACING_BACK|CAMERA_ROTATION_PORTRAIT),
+  CAMERA_FRONT_LANDSCAPE = (CAMERA_FACING_FRONT|CAMERA_ROTATION_LANDSCAPE),
+  CAMERA_FRONT_INVERT_LANDSCAPE = (CAMERA_FACING_FRONT|CAMERA_ROTATION_INVERT_LANDSCAPE),
+  CAMERA_FRONT_PORTRAIT = (CAMERA_FACING_FRONT|CAMERA_ROTATION_PORTRAIT),
+
+  CAMERA_DEFAULT = CAMERA_BACK_LANDSCAPE,
+};
+
+//FIXME: to be replaced by proper video capture properties API
+#define AUDIO_PARAMETER_KEY_CAMERA_FACING "cameraFacing"
+#define AUDIO_PARAMETER_VALUE_FRONT "front"
+#define AUDIO_PARAMETER_VALUE_BACK "back"
+
 enum {
     OFFLOAD_STATE_IDLE,
     OFFLOAD_STATE_PLAYING,
@@ -317,6 +344,7 @@
     uint32_t supported_sample_rates[MAX_SUPPORTED_SAMPLE_RATES+1];
     bool muted;
     uint64_t written; /* total frames written, not cleared when entering standby */
+    int64_t mmap_time_offset_nanos; /* fudge factor to correct inaccuracies in DSP */
     audio_io_handle_t handle;
     struct stream_app_type_cfg app_type_cfg;
 
@@ -396,6 +424,7 @@
     bool enable_aec;
     bool enable_ns;
     audio_format_t format;
+    int64_t mmap_time_offset_nanos; /* fudge factor to correct inaccuracies in DSP */
     audio_io_handle_t capture_handle;
     audio_input_flags_t flags;
     char profile[MAX_STREAM_PROFILE_STR_LEN];
@@ -505,6 +534,7 @@
 
 struct audio_device {
     struct audio_hw_device device;
+
     pthread_mutex_t lock; /* see note below on mutex acquisition order */
     pthread_mutex_t cal_lock;
     struct mixer *mixer;
@@ -609,6 +639,7 @@
     struct listnode active_inputs_list;
     struct listnode active_outputs_list;
     bool use_old_pspd_mix_ctrl;
+    int camera_orientation; /* CAMERA_BACK_LANDSCAPE ... CAMERA_FRONT_PORTRAIT */
 };
 
 int select_devices(struct audio_device *adev,
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 7b15f53..e199616 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -1993,6 +1993,10 @@
 
     snd_card_name = mixer_get_name(my_data->adev->mixer);
     snd_card_name = platform_get_snd_card_name_for_acdb_loader(snd_card_name);
+    if (!snd_card_name) {
+        ALOGE("Failed to get snd_card_name");
+        goto cleanup;
+    }
 
     my_data->acdb_init_data.cvd_version = cvd_version;
     my_data->acdb_init_data.snd_card_name = strdup(snd_card_name);
@@ -2014,6 +2018,7 @@
     strlcpy(my_data->snd_card_name, snd_card_name,
                                                MAX_SND_CARD_STRING_SIZE);
 
+cleanup:
     if (cvd_version)
         free(cvd_version);
     if (!result) {
@@ -3154,6 +3159,13 @@
     return ret;
 }
 
+void platform_add_external_specific_device(snd_device_t snd_device __unused,
+                                           const char *name __unused,
+                                           unsigned int acdb_id __unused)
+{
+    return;
+}
+
 int platform_get_snd_device_index(char *device_name)
 {
     return find_index(snd_device_name_index, SND_DEVICE_MAX, device_name);
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index f21602d..416c70b 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -454,6 +454,13 @@
     return -ENOSYS;
 }
 
+void platform_add_external_specific_device(snd_device_t snd_device __unused,
+                                           const char *name __unused,
+                                           unsigned int acdb_id __unused)
+{
+    return;
+}
+
 int platform_set_snd_device_bit_width(snd_device_t snd_device __unused,
                                       unsigned int bit_width __unused)
 {
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index efbd0ae..f5aa3c4 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -235,6 +235,12 @@
     int acdb_id;
 };
 
+struct external_specific_device {
+    struct listnode list;
+    char *usbid;
+    int acdb_id;
+};
+
 static struct listnode operator_info_list;
 static struct listnode *operator_specific_device_table[SND_DEVICE_MAX];
 
@@ -261,6 +267,8 @@
     size_t mic_count;
 };
 
+static struct listnode *external_specific_device_table[SND_DEVICE_MAX];
+
 struct platform_data {
     struct audio_device *adev;
     bool fluence_in_spkr_mode;
@@ -551,6 +559,7 @@
     [SND_DEVICE_OUT_SPEAKER_WSA_AND_BT_SCO] = "wsa-speaker-and-bt-sco",
     [SND_DEVICE_OUT_SPEAKER_WSA_AND_BT_SCO_WB] = "wsa-speaker-and-bt-sco-wb",
     [SND_DEVICE_OUT_SPEAKER_WSA_AND_BT_SCO_SWB] = "wsa-speaker-and-bt-sco-wb",
+    [SND_DEVICE_OUT_VOICE_HEARING_AID] = "hearing-aid",
 
     /* Capture sound devices */
     [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
@@ -600,7 +609,7 @@
     [SND_DEVICE_IN_BT_SCO_MIC_SWB] = "bt-sco-mic-swb",
     [SND_DEVICE_IN_BT_SCO_MIC_SWB_NREC] = "bt-sco-mic-swb",
     [SND_DEVICE_IN_BT_A2DP] = "bt-a2dp-cap",
-    [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
+    [SND_DEVICE_IN_CAMCORDER_LANDSCAPE] = "camcorder-mic",
     [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
     [SND_DEVICE_IN_VOICE_DMIC_SB] = "voice-dmic-ef",
     [SND_DEVICE_IN_VOICE_DMIC_TMUS] = "voice-dmic-ef-tmus",
@@ -674,9 +683,15 @@
     [SND_DEVICE_IN_LINE] = "line-in",
     [SND_DEVICE_IN_HANDSET_6MIC] = "handset-6mic",
     [SND_DEVICE_IN_HANDSET_8MIC] = "handset-8mic",
+    [SND_DEVICE_IN_CAMCORDER_INVERT_LANDSCAPE] = "camcorder-mic",
+    [SND_DEVICE_IN_CAMCORDER_PORTRAIT] = "camcorder-mic",
+    [SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE] = "camcorder-mic",
+    [SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE] = "camcorder-mic",
+    [SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = "camcorder-mic",
     [SND_DEVICE_OUT_VOIP_HANDSET] = "voip-handset",
     [SND_DEVICE_OUT_VOIP_SPEAKER] = "voip-speaker",
     [SND_DEVICE_OUT_VOIP_HEADPHONES] = "voip-headphones",
+    [SND_DEVICE_IN_VOICE_HEARING_AID] = "hearing-aid-mic",
 };
 
 // Platform specific backend bit width table
@@ -702,14 +717,14 @@
     [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_MIC)][EFFECT_AEC] = {TX_VOICE_SMECNS_V2, 0x0, 0x10EAF, 0x01},
     [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_MIC)][EFFECT_NS] = {TX_VOICE_SMECNS_V2, 0x0, 0x10EAF, 0x02},
 
-    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_SB)][EFFECT_AEC] = {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x01},
-    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_SB)][EFFECT_NS] = {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x02},
-    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_MIC_SB)][EFFECT_AEC] = {TX_VOICE_SMECNS_V2, 0x0, 0x10EAF, 0x01},
-    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_MIC_SB)][EFFECT_NS] = {TX_VOICE_SMECNS_V2, 0x0, 0x10EAF, 0x02},
-    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS_SB)][EFFECT_AEC] = {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x01},
-    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS_SB)][EFFECT_NS] = {TX_VOICE_FV5ECNS_DM, 0x0, 0x10EAF, 0x02},
-    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_MIC_SB)][EFFECT_AEC] = {TX_VOICE_SMECNS_V2, 0x0, 0x10EAF, 0x01},
-    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_MIC_SB)][EFFECT_NS] = {TX_VOICE_SMECNS_V2, 0x0, 0x10EAF, 0x02},
+    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_SB)][EFFECT_AEC] = {TX_VOICE_FLUENCE_SM_SB, 0x8000, 0x10EAF, 0x01},
+    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_SB)][EFFECT_NS] = {TX_VOICE_FLUENCE_SM_SB, 0x8000, 0x10EAF, 0x02},
+    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_MIC_SB)][EFFECT_AEC] = {TX_VOICE_FLUENCE_SM_SB, 0x8000, 0x10EAF, 0x01},
+    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_SPEAKER_MIC_SB)][EFFECT_NS] = {TX_VOICE_FLUENCE_SM_SB, 0x8000, 0x10EAF, 0x02},
+    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS_SB)][EFFECT_AEC] = {TX_VOICE_FLUENCE_SM_SB, 0x8000, 0x10EAF, 0x01},
+    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS_SB)][EFFECT_NS] = {TX_VOICE_FLUENCE_MM_SB, 0x8000, 0x10EAF, 0x02},
+    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_MIC_SB)][EFFECT_AEC] = {TX_VOICE_FLUENCE_SM_SB, 0x8000, 0x10EAF, 0x01},
+    [GET_IN_DEVICE_INDEX(SND_DEVICE_IN_HANDSET_MIC_SB)][EFFECT_NS] = {TX_VOICE_FLUENCE_SM_SB, 0x8000, 0x10EAF, 0x02},
 };
 
 /* ACDB IDs (audio DSP path configuration IDs) for each sound device */
@@ -797,6 +812,7 @@
     [SND_DEVICE_OUT_VOICE_SPEAKER_STEREO_PROTECTED] = 124,
     [SND_DEVICE_OUT_SPEAKER_PROTECTED_RAS] = 134,
     [SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT_RAS] = 134,
+    [SND_DEVICE_OUT_VOICE_HEARING_AID] = 45,
     [SND_DEVICE_IN_HANDSET_MIC] = 4,
     [SND_DEVICE_IN_HANDSET_MIC_SB] = 163,
     [SND_DEVICE_IN_HANDSET_MIC_EXTERNAL] = 4,
@@ -845,7 +861,7 @@
     [SND_DEVICE_IN_BT_SCO_MIC_SWB] = 38,
     [SND_DEVICE_IN_BT_SCO_MIC_SWB_NREC] = 123,
     [SND_DEVICE_IN_BT_A2DP] = 21,
-    [SND_DEVICE_IN_CAMCORDER_MIC] = 4,
+    [SND_DEVICE_IN_CAMCORDER_LANDSCAPE] = 4,
     [SND_DEVICE_IN_VOICE_DMIC] = 41,
     [SND_DEVICE_IN_VOICE_DMIC_SB] = 167,
     [SND_DEVICE_IN_VOICE_DMIC_TMUS] = 89,
@@ -918,6 +934,12 @@
     [SND_DEVICE_OUT_VOIP_HANDSET] = 133,
     [SND_DEVICE_OUT_VOIP_SPEAKER] = 132,
     [SND_DEVICE_OUT_VOIP_HEADPHONES] = 134,
+    [SND_DEVICE_IN_CAMCORDER_INVERT_LANDSCAPE] = 4,
+    [SND_DEVICE_IN_CAMCORDER_PORTRAIT] = 4,
+    [SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE] = 4,
+    [SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE] = 4,
+    [SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = 4,
+    [SND_DEVICE_IN_VOICE_HEARING_AID] = 44,
 };
 
 struct name_to_index {
@@ -1012,6 +1034,7 @@
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOIP_HANDSET)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOIP_SPEAKER)},
     {TO_NAME_INDEX(SND_DEVICE_OUT_VOIP_HEADPHONES)},
+    {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEARING_AID)},
     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_SB)},
     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_EXTERNAL)},
@@ -1061,7 +1084,7 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_SWB)},
     {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_SWB_NREC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_BT_A2DP)},
-    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_LANDSCAPE)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC_SB)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC_TMUS)},
@@ -1108,6 +1131,7 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC_AEC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEARING_AID)},
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_NS)},
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)},
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE)},
@@ -1133,6 +1157,13 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_INCALL_REC_TX)},
     {TO_NAME_INDEX(SND_DEVICE_IN_INCALL_REC_RX_TX)},
     {TO_NAME_INDEX(SND_DEVICE_IN_LINE)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_INVERT_LANDSCAPE)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_PORTRAIT)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT)},
+    /* For legacy xml file parsing */
+    {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
 };
 
 static char * backend_tag_table[SND_DEVICE_MAX] = {0};
@@ -1401,6 +1432,27 @@
 static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT;
 static bool is_tmus = false;
 
+static bool is_usb_snd_dev(snd_device_t snd_device)
+{
+    if (snd_device < SND_DEVICE_IN_BEGIN) {
+        if (snd_device == SND_DEVICE_OUT_USB_HEADSET ||\
+            snd_device == SND_DEVICE_OUT_USB_HEADPHONES ||\
+            snd_device == SND_DEVICE_OUT_VOICE_USB_HEADPHONES ||\
+            snd_device == SND_DEVICE_OUT_VOICE_USB_HEADSET ||\
+            snd_device == SND_DEVICE_OUT_VOICE_TTY_FULL_USB ||\
+            snd_device == SND_DEVICE_OUT_VOICE_TTY_VCO_USB)
+            return true;
+    } else {
+        if (snd_device == SND_DEVICE_IN_USB_HEADSET_MIC ||\
+            snd_device == SND_DEVICE_IN_USB_HEADSET_MIC_AEC ||\
+            snd_device == SND_DEVICE_IN_VOICE_USB_HEADSET_MIC ||\
+            snd_device == SND_DEVICE_IN_UNPROCESSED_USB_HEADSET_MIC ||\
+            snd_device == SND_DEVICE_IN_VOICE_RECOG_USB_HEADSET_MIC)
+            return true;
+    }
+    return false;
+}
+
 static void check_operator()
 {
     char value[PROPERTY_VALUE_MAX];
@@ -1489,6 +1541,30 @@
     return ret;
 }
 
+static int get_external_specific_device_acdb_id(snd_device_t snd_device)
+{
+    struct external_specific_device *ext_dev;
+    int ret = acdb_device_table[snd_device];
+    char *usbid = NULL;
+    struct listnode *node;
+
+    if (is_usb_snd_dev(snd_device))
+        usbid = audio_extn_usb_usbid();
+
+    if (usbid) {
+        list_for_each(node, external_specific_device_table[snd_device]) {
+            ext_dev = node_to_item(node, struct external_specific_device, list);
+            if (ext_dev->usbid && !strcmp(usbid, ext_dev->usbid)) {
+                ret = ext_dev->acdb_id;
+                break;
+            }
+        }
+
+        free(usbid);
+    }
+    return ret;
+}
+
 static const char *get_operator_specific_device_mixer_path(snd_device_t snd_device)
 {
     struct operator_specific_device *device;
@@ -1906,6 +1982,7 @@
         backend_tag_table[dev] = NULL;
         hw_interface_table[dev] = NULL;
         operator_specific_device_table[dev] = NULL;
+        external_specific_device_table[dev] = NULL;
     }
     for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
         backend_bit_width_table[dev] = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
@@ -1975,6 +2052,7 @@
     backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_STEREO_AND_VOICE_HEADPHONES] = strdup("speaker-and-headphones");
     backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_STEREO_AND_VOICE_ANC_HEADSET] = strdup("speaker-and-headphones");
     backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_STEREO_AND_VOICE_ANC_FB_HEADSET] = strdup("speaker-and-headphones");
+    backend_tag_table[SND_DEVICE_OUT_VOICE_HEARING_AID] = strdup("hearing-aid");
 
     hw_interface_table[SND_DEVICE_OUT_HANDSET] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_SPEAKER] = strdup("SLIMBUS_0_RX");
@@ -2060,6 +2138,10 @@
     hw_interface_table[SND_DEVICE_OUT_SPEAKER_WSA] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_WSA] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_2_WSA] = strdup("SLIMBUS_0_RX");
+    /* So far, primary hal doesn't support hearing aid device.
+       Need snd_device to route voice call and use specific acdb tuning.
+       Also, BT_RX is a virtual port to indicate bluetooth hearing aid. */
+    hw_interface_table[SND_DEVICE_OUT_VOICE_HEARING_AID] = strdup("BT_RX"),
     hw_interface_table[SND_DEVICE_IN_HANDSET_MIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_HANDSET_MIC_SB] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_HANDSET_MIC_EXTERNAL] = strdup("SLIMBUS_0_TX");
@@ -2078,6 +2160,7 @@
     hw_interface_table[SND_DEVICE_IN_HANDSET_DMIC_AEC_NS_SB] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_HANDSET_DMIC_STEREO] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_HEADSET_MIC_AEC] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_CAMCORDER_LANDSCAPE] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_SPEAKER_MIC] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_SPEAKER_MIC_SB] = strdup("SLIMBUS_0_TX");
     hw_interface_table[SND_DEVICE_IN_SPEAKER_MIC_AEC] = strdup("SLIMBUS_0_TX");
@@ -2179,7 +2262,12 @@
     hw_interface_table[SND_DEVICE_OUT_VOIP_HANDSET] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_VOIP_SPEAKER] = strdup("SLIMBUS_0_RX");
     hw_interface_table[SND_DEVICE_OUT_VOIP_HEADPHONES] = strdup("SLIMBUS_6_RX");
-
+    hw_interface_table[SND_DEVICE_IN_CAMCORDER_INVERT_LANDSCAPE] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_CAMCORDER_PORTRAIT] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT] = strdup("SLIMBUS_0_TX");
+    hw_interface_table[SND_DEVICE_IN_VOICE_HEARING_AID] = strdup("SLIMBUS_0_TX");
     my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT;
 
      /*remove ALAC & APE from DSP decoder list based on software decoder availability*/
@@ -2426,11 +2514,11 @@
     }
 
     snd_card_name = mixer_get_name(my_data->adev->mixer);
+    snd_card_name = platform_get_snd_card_name_for_acdb_loader(snd_card_name);
     if (!snd_card_name) {
         ALOGE("Failed to get snd_card_name");
         goto cleanup;
     }
-    snd_card_name = platform_get_snd_card_name_for_acdb_loader(snd_card_name);
 
     my_data->acdb_init_data.cvd_version = cvd_version;
     my_data->acdb_init_data.snd_card_name = strdup(snd_card_name);
@@ -3361,10 +3449,19 @@
             my_data->current_backend_cfg[DEFAULT_CODEC_TX_BACKEND].samplerate_mixer_ctl =
                 strdup("SLIM_0_TX SampleRate");
         }
-        my_data->current_backend_cfg[HEADPHONE_BACKEND].bitwidth_mixer_ctl =
-            strdup("SLIM_6_RX Format");
-        my_data->current_backend_cfg[HEADPHONE_BACKEND].samplerate_mixer_ctl =
-            strdup("SLIM_6_RX SampleRate");
+
+        if (strstr(snd_card_name, "intcodec")) {
+            my_data->current_backend_cfg[HEADPHONE_BACKEND].bitwidth_mixer_ctl =
+                strdup("INT0_MI2S_RX Format");
+            my_data->current_backend_cfg[HEADPHONE_BACKEND].samplerate_mixer_ctl =
+                strdup("INT0_MI2S_RX SampleRate");
+        } else {
+            my_data->current_backend_cfg[HEADPHONE_BACKEND].bitwidth_mixer_ctl =
+                strdup("SLIM_6_RX Format");
+            my_data->current_backend_cfg[HEADPHONE_BACKEND].samplerate_mixer_ctl =
+                strdup("SLIM_6_RX SampleRate");
+        }
+
         //TODO: enable CONCURRENT_CAPTURE_ENABLED flag only if separate backend is defined
         //for headset-mic. This is to capture separate data from headset-mic and handset-mic.
         if(audio_extn_is_concurrent_capture_enabled())
@@ -3594,6 +3691,7 @@
     struct platform_data *my_data = (struct platform_data *)platform;
     struct operator_info *info_item;
     struct operator_specific_device *device_item;
+    struct external_specific_device *ext_dev;
     struct app_type_entry *ap;
     struct listnode *node;
 
@@ -3647,6 +3745,17 @@
             free(operator_specific_device_table[dev]);
             operator_specific_device_table[dev] = NULL;
         }
+
+        if (external_specific_device_table[dev]) {
+            while (!list_empty(external_specific_device_table[dev])) {
+                node = list_head(external_specific_device_table[dev]);
+                list_remove(node);
+                ext_dev = node_to_item(node, struct external_specific_device, list);
+                free(ext_dev->usbid);
+                free(ext_dev);
+            }
+            free(external_specific_device_table[dev]);
+        }
     }
 
     while (!list_empty(&operator_info_list)) {
@@ -4029,6 +4138,29 @@
     return ret;
 }
 
+void platform_add_external_specific_device(snd_device_t snd_device,
+                                           const char *usbid,
+                                           unsigned int acdb_id)
+{
+    struct external_specific_device *device;
+
+    if (external_specific_device_table[snd_device] == NULL) {
+        external_specific_device_table[snd_device] =
+            (struct listnode *)calloc(1, sizeof(struct listnode));
+        list_init(external_specific_device_table[snd_device]);
+    }
+
+    device = (struct external_specific_device *)calloc(1, sizeof(struct external_specific_device));
+
+    device->usbid = strdup(usbid);
+    device->acdb_id = acdb_id;
+
+    list_add_tail(external_specific_device_table[snd_device], &device->list);
+
+    ALOGD("%s: device[%s] usbid[%s] -> acdb_id[%d]", __func__,
+            platform_get_snd_device_name(snd_device), usbid, acdb_id);
+}
+
 int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
 {
     int ret = 0;
@@ -4144,6 +4276,8 @@
 
     if (operator_specific_device_table[snd_device] != NULL)
         return get_operator_specific_device_acdb_id(snd_device);
+    else if (external_specific_device_table[snd_device] != NULL)
+        return get_external_specific_device_acdb_id(snd_device);
     else
         return acdb_device_table[snd_device];
 }
@@ -5351,8 +5485,11 @@
                 snd_device = SND_DEVICE_OUT_ANC_HANDSET;
             else
                 snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
-        } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX)
+        } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX) {
             snd_device = SND_DEVICE_OUT_VOICE_TX;
+        } else if (devices & AUDIO_DEVICE_OUT_HEARING_AID) {
+            snd_device = SND_DEVICE_OUT_VOICE_HEARING_AID;
+        }
 
         if (snd_device != SND_DEVICE_NONE) {
             goto exit;
@@ -5888,6 +6025,8 @@
             } else {
                 snd_device = SND_DEVICE_IN_HANDSET_MIC;
             }
+        } else if (out_device & AUDIO_DEVICE_OUT_HEARING_AID) {
+            snd_device = SND_DEVICE_IN_VOICE_HEARING_AID;
         }
     } else if (my_data->use_generic_handset == true &&  //     system prop is enabled
                (my_data->source_mic_type & SOURCE_QUAD_MIC) &&  // AND 4mic is available
@@ -5932,7 +6071,30 @@
     } else if (source == AUDIO_SOURCE_CAMCORDER) {
         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
             in_device & AUDIO_DEVICE_IN_BACK_MIC) {
-
+            switch (adev->camera_orientation) {
+            case CAMERA_BACK_LANDSCAPE:
+                snd_device = SND_DEVICE_IN_CAMCORDER_LANDSCAPE;
+                break;
+            case CAMERA_BACK_INVERT_LANDSCAPE:
+                snd_device = SND_DEVICE_IN_CAMCORDER_INVERT_LANDSCAPE;
+                break;
+            case CAMERA_BACK_PORTRAIT:
+                snd_device = SND_DEVICE_IN_CAMCORDER_PORTRAIT;
+                break;
+            case CAMERA_FRONT_LANDSCAPE:
+                snd_device = SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE;
+                break;
+            case CAMERA_FRONT_INVERT_LANDSCAPE:
+                snd_device = SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE;
+                break;
+            case CAMERA_FRONT_PORTRAIT:
+                snd_device = SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT;
+                break;
+            default:
+                ALOGW("%s: invalid camera orientation %08x", __func__, adev->camera_orientation);
+                snd_device = SND_DEVICE_IN_CAMCORDER_LANDSCAPE;
+                break;
+            }
             if (str_bitwidth == 16) {
                 if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
                     (my_data->source_mic_type & SOURCE_DUAL_MIC) &&
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 6203cf8..c23ea6d 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -173,6 +173,7 @@
     SND_DEVICE_OUT_VOICE_SPEAKER_STEREO_AND_VOICE_HEADPHONES,
     SND_DEVICE_OUT_VOICE_SPEAKER_STEREO_AND_VOICE_ANC_HEADSET,
     SND_DEVICE_OUT_VOICE_SPEAKER_STEREO_AND_VOICE_ANC_FB_HEADSET,
+    SND_DEVICE_OUT_VOICE_HEARING_AID,
     SND_DEVICE_OUT_END,
 
     /*
@@ -229,7 +230,7 @@
     SND_DEVICE_IN_BT_SCO_MIC_SWB,
     SND_DEVICE_IN_BT_SCO_MIC_SWB_NREC,
     SND_DEVICE_IN_BT_A2DP,
-    SND_DEVICE_IN_CAMCORDER_MIC,
+    SND_DEVICE_IN_CAMCORDER_LANDSCAPE,
     SND_DEVICE_IN_VOICE_DMIC,
     SND_DEVICE_IN_VOICE_DMIC_SB,
     SND_DEVICE_IN_VOICE_DMIC_TMUS,
@@ -303,10 +304,17 @@
     SND_DEVICE_IN_INCALL_REC_TX,
     SND_DEVICE_IN_INCALL_REC_RX_TX,
     SND_DEVICE_IN_LINE,
+    SND_DEVICE_IN_CAMCORDER_INVERT_LANDSCAPE,
+    SND_DEVICE_IN_CAMCORDER_PORTRAIT,
+    SND_DEVICE_IN_CAMCORDER_SELFIE_LANDSCAPE,
+    SND_DEVICE_IN_CAMCORDER_SELFIE_INVERT_LANDSCAPE,
+    SND_DEVICE_IN_CAMCORDER_SELFIE_PORTRAIT,
+    SND_DEVICE_IN_VOICE_HEARING_AID,
     SND_DEVICE_IN_END,
 
     SND_DEVICE_MAX = SND_DEVICE_IN_END,
-
+    /* For legacy xml file parsing */
+    SND_DEVICE_IN_CAMCORDER_MIC = SND_DEVICE_IN_CAMCORDER_LANDSCAPE,
 };
 #define INPUT_SAMPLING_RATE_DSD64       2822400
 #define INPUT_SAMPLING_RATE_DSD128      5644800
@@ -638,6 +646,8 @@
 #define TX_VOICE_FV5ECNS_SM 0x10F09
 #define TX_VOICE_SMECNS_V2 0x10F31
 #define TX_VOICE_FV5ECNS_DM 0x10F0A
+#define TX_VOICE_FLUENCE_SM_SB 0x10F38
+#define TX_VOICE_FLUENCE_MM_SB 0x10F39
 
 #define LIB_CSD_CLIENT "libcsd-client.so"
 
diff --git a/hal/platform_api.h b/hal/platform_api.h
index f4acf1f..f9e5f2a 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -185,6 +185,9 @@
                                            const char *operator,
                                            const char *mixer_path,
                                            unsigned int acdb_id);
+void platform_add_external_specific_device(snd_device_t snd_device,
+                                           const char *name,
+                                           unsigned int acdb_id);
 void platform_get_parameters(void *platform, struct str_parms *query,
                              struct str_parms *reply);
 int platform_set_parameters(void *platform, struct str_parms *parms);
diff --git a/hal/platform_info.c b/hal/platform_info.c
index da0223e..05ee9cd 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -72,6 +72,7 @@
     MIC_INFO,
     CUSTOM_MTMX_PARAMS,
     CUSTOM_MTMX_PARAM_COEFFS,
+    EXTERNAL_DEVICE_SPECIFIC,
 } section_t;
 
 typedef void (* section_process_fn)(const XML_Char **attr);
@@ -95,6 +96,7 @@
 static void process_mic_info(const XML_Char **attr);
 static void process_custom_mtmx_params(const XML_Char **attr);
 static void process_custom_mtmx_param_coeffs(const XML_Char **attr);
+static void process_external_dev(const XML_Char **attr);
 
 static section_process_fn section_table[] = {
     [ROOT] = process_root,
@@ -115,6 +117,7 @@
     [MIC_INFO] = process_mic_info,
     [CUSTOM_MTMX_PARAMS] = process_custom_mtmx_params,
     [CUSTOM_MTMX_PARAM_COEFFS] = process_custom_mtmx_param_coeffs,
+    [EXTERNAL_DEVICE_SPECIFIC] = process_external_dev,
 };
 
 static section_t section;
@@ -460,6 +463,38 @@
     return;
 }
 
+static void process_external_dev(const XML_Char **attr)
+{
+    snd_device_t snd_device = SND_DEVICE_NONE;
+
+    if (strcmp(attr[0], "name") != 0) {
+        ALOGE("%s: 'name' not found", __func__);
+        goto done;
+    }
+
+    snd_device = platform_get_snd_device_index((char *)attr[1]);
+    if (snd_device < 0) {
+        ALOGE("%s: Device %s in %s not found, no ACDB ID set!",
+              __func__, (char *)attr[3], PLATFORM_INFO_XML_PATH);
+        goto done;
+    }
+
+    if (strcmp(attr[2], "usbid") != 0) {
+        ALOGE("%s: 'usbid' not found", __func__);
+        goto done;
+    }
+
+    if (strcmp(attr[4], "acdb_id") != 0) {
+        ALOGE("%s: 'acdb_id' not found", __func__);
+        goto done;
+    }
+
+    platform_add_external_specific_device(snd_device, (char *)attr[3], atoi((char *)attr[5]));
+
+done:
+    return;
+}
+
 static void process_audio_effect(const XML_Char **attr, effect_type_t effect_type)
 {
     int index;
@@ -1204,6 +1239,11 @@
             section = CUSTOM_MTMX_PARAM_COEFFS;
             section_process_fn fn = section_table[section];
             fn(attr);
+        } else if (strcmp(tag_name, "external_specific_dev") == 0) {
+            section = EXTERNAL_DEVICE_SPECIFIC;
+        } else if (strcmp(tag_name, "ext_device") == 0) {
+            section_process_fn fn = section_table[section];
+            fn(attr);
         }
     } else {
         if(strcmp(tag_name, "config_params") == 0) {
@@ -1256,6 +1296,8 @@
         section = ROOT;
     } else if (strcmp(tag_name, "snd_devices") == 0) {
         section = ROOT;
+    } else if (strcmp(tag_name, "external_specific_dev") == 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) {
diff --git a/hal/voice.c b/hal/voice.c
index 847ce92..b0b75e5 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -289,8 +289,17 @@
     if(adev->mic_break_enabled)
         platform_set_mic_break_det(adev->platform, true);
 
-    pcm_start(session->pcm_tx);
-    pcm_start(session->pcm_rx);
+    ret = pcm_start(session->pcm_tx);
+    if (ret != 0) {
+        ALOGE("%s: %s", __func__, pcm_get_error(session->pcm_tx));
+        goto error_start_voice;
+    }
+
+    ret = pcm_start(session->pcm_rx);
+    if (ret != 0) {
+        ALOGE("%s: %s", __func__, pcm_get_error(session->pcm_rx));
+        goto error_start_voice;
+    }
 
     /* Enable aanc only when no calls are active */
     if (!voice_is_call_state_active(adev))
diff --git a/post_proc/ma_listener.c b/post_proc/ma_listener.c
index 9271dc7..e462646 100644
--- a/post_proc/ma_listener.c
+++ b/post_proc/ma_listener.c
@@ -28,7 +28,7 @@
 #include <audio-base.h>
 
 #define MA_FLAG ( EFFECT_FLAG_TYPE_INSERT | \
-                   EFFECT_FLAG_VOLUME_IND | \
+                   EFFECT_FLAG_VOLUME_MONITOR | \
                    EFFECT_FLAG_DEVICE_IND | \
                    EFFECT_FLAG_OFFLOAD_SUPPORTED | \
                    EFFECT_FLAG_NO_PROCESS)
diff --git a/voice_processing/voice_processing.c b/voice_processing/voice_processing.c
index 366adf7..50cb7af 100644
--- a/voice_processing/voice_processing.c
+++ b/voice_processing/voice_processing.c
@@ -414,7 +414,7 @@
 
     list_for_each(node, &session_list) {
         session = node_to_item(node, struct session_s, node);
-        if (session->io == ioId) {
+        if (session->id == sessionId) {
             if (session->created_msk & (1 << id)) {
                 ALOGV("get_session() effect %d already created", id);
                 return NULL;