Merge f47c649bf0e3f6315737a73c5609d3a072b8a629 on remote branch

Change-Id: I73ad3b2a1a68f18d6f8e509ac12186ae89d7b85a
diff --git a/configs/msmnile_au/msmnile_au.mk b/configs/msmnile_au/msmnile_au.mk
index 2d47885..502315e 100644
--- a/configs/msmnile_au/msmnile_au.mk
+++ b/configs/msmnile_au/msmnile_au.mk
@@ -49,6 +49,9 @@
 
 USE_XML_AUDIO_POLICY_CONF := 1
 BOARD_SUPPORTS_SOUND_TRIGGER := true
+BOARD_SUPPORTS_OPENSOURCE_STHAL := true
+AUDIO_FEATURE_ENABLED_SVA_CHANNEL_IDX := true
+AUDIO_FEATURE_QSSI_COMPLIANCE := true
 AUDIO_FEATURE_ENABLED_INSTANCE_ID := true
 ifeq ($(TARGET_HAS_GENERIC_KERNEL_HEADERS), true)
 AUDIO_FEATURE_ENABLED_GKI := true
diff --git a/configs/msmnile_au/sound_trigger_platform_info.xml b/configs/msmnile_au/sound_trigger_platform_info.xml
index 6efdcdd..a7d0459 100644
--- a/configs/msmnile_au/sound_trigger_platform_info.xml
+++ b/configs/msmnile_au/sound_trigger_platform_info.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
-<!--- Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.       -->
+<!--- Copyright (c) 2013-2021, 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    -->
@@ -26,18 +26,20 @@
 <!--- 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="0x0103" /> <!-- this must be the first param -->
+    <param version="0x0106" /> <!-- 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>                                                     -->
+<!--- 0x0104: instance id support for both WDSP<CPE> and ADSP lsm usecases      -->
+<!--- 0x0105: Select <lsm_usecase> based on capture device                      -->
+<!--- 0x0106: Add module_params tag to support multiple module and param ids    -->
+<!--- per <lsm_usecase>                                                         -->
 
     <common_config>
-        <param implementer_version="0x0100" />
-        <param max_cpe_sessions="1" />
-        <param max_wdsp_sessions="2" />
+        <param implementer_version="0x0102" />
         <param max_ape_sessions="8" />
         <param enable_failure_detection="false" />
         <param support_device_switch="false" />
@@ -51,6 +53,7 @@
         <param backend_dai_name="TERT_TDM_TX_0" />
         <!-- Param used to indicate if SVA has dedicated SLIM ports -->
         <param dedicated_sva_path="true" />
+        <param platform_lpi_enable="false" />
         <param concurrent_capture="true" />
         <param concurrent_voice_call="false" />
         <param concurrent_voip_call="false" />
@@ -76,27 +79,16 @@
     <!-- QTI SVA -->
     <sound_model_config>
         <param vendor_uuid="68ab2d40-e860-11e3-95ef-0002a5d5c51b" />
-        <param execution_type="ADSP" /> <!-- value: "WDSP" "ADSP" "DYNAMIC" -->
-        <param library="libsmwrapper.so" />
-        <param max_cpe_phrases="6" />
-        <param max_cpe_users="3" />
+        <param execution_type="ADSP" />
+        <param merge_first_stage_sound_models="false"/>
         <param max_ape_phrases="20" />
         <param max_ape_users="10" />
         <!-- Profile specific data which the algorithm can support -->
         <param sample_rate="16000" />
         <param bit_width="16" />
         <param out_channels="1"/> <!-- Module output channels -->
+        <param dam_token_id="1"/>
 
-        <!-- 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="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_QMIC" />
-        <!-- wdsp_fluence_type: fluence disabled: "NONE" -->
-        <!-- fluence enabled: "FLUENCE_DMIC", "FLUENCE_TMIC", "FLUENCE_QMIC" -->
-        <param wdsp_fluence_type="NONE" />
         <arm_ss_usecase>
             <!-- Options are "KEYWORD_DETECTION", "USER_VERIFICATION", "CUSTOM_DETECTION"  -->
             <param sm_detection_type= "KEYWORD_DETECTION" />
@@ -114,66 +106,58 @@
             <param bit_wdith="16"/>
             <param channel_count="1"/>
         </arm_ss_usecase>
-        <gcs_usecase>
-            <param uid="0x1" />
-            <param acdb_devices="DEVICE_HANDSET_MIC_CPE, DEVICE_HANDSET_TMIC_CPE, DEVICE_HEADSET_MIC_CPE" />
-            <!-- module_id, instance_id, param_id -->
-            <param load_sound_model_ids="0x00012C0D, 0x2, 0x00012C14" />
-            <param confidence_levels_ids="0x00012C0D, 0x2, 0x00012C28" />
-            <param detection_event_ids="0x00012C0D, 0x2, 0x00012B05" />
-            <param read_cmd_ids="0x00020013, 0x2, 0x00020015" />
-            <param read_rsp_ids="0x00020013, 0x2, 0x00020016" />
-            <param custom_config_ids="0x00012C0D, 0x2, 0x00012C20" />
-            <param det_event_type_ids="0x00012C0D, 0x2, 0x00012C2A" />
-        </gcs_usecase>
-        <gcs_usecase>
-            <param uid="0x2" />
-            <param acdb_devices="DEVICE_HANDSET_MIC_CPE, DEVICE_HANDSET_TMIC_CPE, DEVICE_HEADSET_MIC_CPE" />
-            <param load_sound_model_ids="0x00012C0D, 0x3, 0x00012C14" />
-            <param confidence_levels_ids="0x00012C0D, 0x3, 0x00012C28" />
-            <param detection_event_ids="0x00012C0D, 0x3, 0x00012B05" />
-            <param read_cmd_ids="0x00020013, 0x3, 0x00020015" />
-            <param read_rsp_ids="0x00020013, 0x3, 0x00020016" />
-            <param custom_config_ids="0x00012C0D, 0x3, 0x00012C20" />
-            <param det_event_type_ids="0x00012C0D, 0x3, 0x00012C2A" />
-        </gcs_usecase>
-        <gcs_usecase>
-            <param uid="0x7" />
-            <param acdb_devices="DEVICE_HANDSET_DMIC_CPE" />
-            <param load_sound_model_ids="0x00012C0D, 0x7, 0x00012C14" />
-            <param confidence_levels_ids="0x00012C0D, 0x7, 0x00012C28" />
-            <param detection_event_ids="0x00012C0D, 0x7, 0x00012B05" />
-            <param read_cmd_ids="0x00020013, 0x7, 0x00020015" />
-            <param read_rsp_ids="0x00020013, 0x7, 0x00020016" />
-            <param custom_config_ids="0x00012C0D, 0x7, 0x00012C20" />
-            <param det_event_type_ids="0x00012C0D, 0x7, 0x00012C2A" />
-        </gcs_usecase>
-        <gcs_usecase>
-            <param uid="0x8" />
-            <param acdb_devices="DEVICE_HANDSET_DMIC_CPE" />
-            <param load_sound_model_ids="0x00012C0D, 0x8, 0x00012C14" />
-            <param confidence_levels_ids="0x00012C0D, 0x8, 0x00012C28" />
-            <param detection_event_ids="0x00012C0D, 0x8, 0x00012B05" />
-            <param read_cmd_ids="0x00020013, 0x8, 0x00020015" />
-            <param read_rsp_ids="0x00020013, 0x8, 0x00020016" />
-            <param custom_config_ids="0x00012C0D, 0x8, 0x00012C20" />
-            <param det_event_type_ids="0x00012C0D, 0x8, 0x00012C2A" />
-        </gcs_usecase>
+        <arm_ss_usecase>
+            <param sm_detection_type= "KEYWORD_DETECTION" />
+            <param sm_id="0x8" />
+            <param module_lib="libcapiv2svarnn.so"/>
+            <param sample_rate="16000"/>
+            <param bit_wdith="16"/>
+            <param channel_count="1"/>
+        </arm_ss_usecase>
         <!-- Module and param ids with which the algorithm is integrated
             in non-graphite firmware (note these must come after gcs params)
             Extends flexibility to have different ids based on execution type.
             valid execution_type values: "WDSP" "ADSP" -->
         <lsm_usecase>
+            <param capture_device="HANDSET" />
+            <!-- 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="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_QMIC" />
             <param execution_mode="ADSP" />
+            <!-- lpi_mode: "NON_LPI_BARGE_IN", "NON_LPI", "LPI" -->
+            <!-- NON_LPI_BARGE_IN: Default non-LPI mode type. lsm_usecase -->
+            <!-- must be present with this mode type to handle barge-in. -->
+            <!-- NON_LPI: If another lsm_usecase is present with this mode -->
+            <!-- type, it will be used for non-LPI non-barge-in usecases. -->
+            <!-- If not present, NON_LPI_BARGE_IN mode type will be used. -->
+            <!-- LPI: This mode type will be used for LPI usecases. -->
             <param app_type="2" /> <!-- app type used in ACDB -->
+            <param pdk5_app_type="1" />
             <param in_channels="4"/> <!-- Module input channels -->
-            <param load_sound_model_ids="0x00012C1C, 0x00012C14" />
-            <param unload_sound_model_ids="0x00012C1C, 0x00012C15" />
-            <param confidence_levels_ids="0x00012C1C, 0x00012C07" />
-            <param operation_mode_ids="0x00012C1C, 0x00012C02" />
-            <param polling_enable_ids="0x00012C1C, 0x00012C1B" />
-            <param custom_config_ids="0x00012C1C, 0x00012C20" />
-            <param det_event_type_ids="0x00012C1C, 0x00012C2C" />
+            <module_params>
+                <param module_type="GMM" />
+                <param load_sound_model_ids="0x00012C1C, 0x0, 0x00012C14" />
+                <param unload_sound_model_ids="0x00012C1C, 0x0, 0x00012C15" />
+                <param confidence_levels_ids="0x00012C1C, 0x0, 0x00012C07" />
+                <param operation_mode_ids="0x00012C1C, 0x0, 0x00012C02" />
+                <param polling_enable_ids="0x00012C1C, 0x0, 0x00012C1B" />
+                <param custom_config_ids="0x00012C1C, 0x0, 0x00012C20" />
+                <param det_event_type_ids="0x00012C1C, 0x0, 0x00012C2C" />
+                <param lab_dam_cfg_ids="0x00012C08, 0x0, 0x000102C4" />
+            </module_params>
+            <module_params>
+                <param module_type="PDK5" />
+                <param load_sound_model_ids="0x00012C35, 0x0, 0x00012C36" />
+                <param unload_sound_model_ids="0x00012C35, 0x0, 0x00012C37" />
+                <param confidence_levels_ids="0x00012C35, 0x0, 0x00012C38" />
+                <param custom_config_ids="0x00012C35, 0x0, 0x00012C20" />
+                <param det_event_type_ids="0x00012C35, 0x0, 0x00012C2C" />
+                <param lab_dam_cfg_ids="0x00012C08, 0x0, 0x000102C4" />
+            </module_params>
         </lsm_usecase>
 
         <!-- format: "ADPCM_packet" or "PCM_packet" !-->
@@ -182,17 +166,12 @@
             transfer mode -->
         <param capture_keyword="PCM_packet, RT, 2000" />
         <param client_capture_read_delay="2000" />
-        <param lpi_enable="false" />
-        <param concurrent_capture="true" />
-        <param concurrent_voice_call="false" />
-        <param concurrent_voip_call="false" />
     </sound_model_config>
 
-    <!-- QTI Music Detection !-->
+ <!-- QTI Music Detection !-->
     <sound_model_config>
         <param vendor_uuid="876c1b46-9d4d-40cc-a4fd-4d5ec7a80e47" />
         <param execution_type="WDSP" /> <!-- value: "WDSP" "ADSP" "DYNAMIC" -->
-        <param library="libsmwrapper.so" />
         <param max_cpe_phrases="1" />
         <param max_cpe_users="1" />
         <param max_ape_phrases="1" />
@@ -211,18 +190,6 @@
         <!-- wdsp_fluence_type: fluence disabled: "NONE" -->
         <!-- fluence enabled: "FLUENCE_DMIC", "FLUENCE_TMIC", "FLUENCE_QMIC" -->
         <param wdsp_fluence_type="NONE" />
-        <gcs_usecase>
-            <param uid="0x5" />
-            <param acdb_devices="DEVICE_HANDSET_MIC_CPE, DEVICE_HANDSET_TMIC_CPE, DEVICE_HEADSET_MIC_CPE" />
-            <!-- module_id, instance_id, param_id -->
-            <param load_sound_model_ids="0x00012C2E, 0x6, 0x00012C14" />
-            <param confidence_levels_ids="0x00012C2E, 0x6, 0x00012C28" />
-            <param detection_event_ids="0x00012C2E, 0x6, 0x00012B05" />
-            <param read_cmd_ids="0x00020013, 0x6, 0x00020015" />
-            <param read_rsp_ids="0x00020013, 0x6, 0x00020016" />
-            <param custom_config_ids="0x00012C2E, 0x6, 0x00012C2D" />
-            <param det_event_type_ids="0x00012C2E, 0x6, 0x00012C2C" />
-        </gcs_usecase>
         <!-- Module and param ids with which the algorithm is integrated
             in non-graphite firmware (note these must come after gcs params)
             Extends flexibility to have different ids based on execution type.
@@ -231,11 +198,13 @@
             <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" />
-            <param det_event_type_ids="0x00012C22, 0x00012C2C" />
-            <param custom_config_ids="0x00012C22, 0x00012C30" />
+            <module_params>
+                <param load_sound_model_ids="0x00012C22, 0x0, 0x00012C14" />
+                <param unload_sound_model_ids="0x00012C22, 0x0, 0x00012C15" />
+                <param confidence_levels_ids="0x00012C22, 0x0, 0x00012C07" />
+                <param det_event_type_ids="0x00012C22, 0x0, 0x00012C2C" />
+                <param custom_config_ids="0x00012C22, 0x0, 0x00012C30" />
+            </module_params>
         </lsm_usecase>
 
         <!-- format: "ADPCM_packet" or "PCM_packet" !-->
@@ -250,7 +219,6 @@
     <sound_model_config>
         <param vendor_uuid="7038ddc8-30f2-11e6-b0ac-40a8f03d3f15" />
         <param execution_type="WDSP" /> <!-- value: "WDSP" "ADSP" "DYNAMIC" -->
-        <param library="none" />
         <param max_cpe_phrases="1" />
         <param max_cpe_users="1" />
         <param max_ape_phrases="1" />
@@ -269,39 +237,18 @@
         <!-- wdsp_fluence_type: fluence disabled: "NONE" -->
         <!-- fluence enabled: "FLUENCE_DMIC", "FLUENCE_QMIC" -->
         <param wdsp_fluence_type="NONE" />
-        <gcs_usecase>
-            <param uid="0x3" />
-            <param acdb_devices="DEVICE_HANDSET_MIC_CPE" />
-            <param load_sound_model_ids="0x18000001, 0x4, 0x18000100" />
-            <param start_engine_ids="0x18000001, 0x4, 0x18000101" />
-            <param confidence_levels_ids="0x18000001, 0x4, 0x00012C28" />
-            <param detection_event_ids="0x18000001, 0x4, 0x00012C29" />
-            <param custom_config_ids="0x18000001, 0x4, 0x00012C20" />
-            <param read_cmd_ids="0x00020013, 0x4, 0x00020015" />
-            <param read_rsp_ids="0x00020013, 0x4, 0x00020016" />
-        </gcs_usecase>
-        <gcs_usecase>
-            <param uid="0x4" />
-            <param acdb_devices="DEVICE_HANDSET_DMIC_CPE" />
-            <param load_sound_model_ids="0x18000001, 0x5, 0x18000100" />
-            <param start_engine_ids="0x18000001, 0x5, 0x18000101" />
-            <param confidence_levels_ids="0x18000001, 0x5, 0x00012C28" />
-            <param detection_event_ids="0x18000001, 0x5, 0x00012C29" />
-            <param custom_config_ids="0x18000001, 0x5, 0x00012C20" />
-            <param read_cmd_ids="0x00020013, 0x5, 0x00020015" />
-            <param read_rsp_ids="0x00020013, 0x5, 0x00020016" />
-        </gcs_usecase>
-
         <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" />
-            <param operation_mode_ids="0x18000001, 0x00012C02" />
-            <param polling_enable_ids="0x18000001, 0x00012C1B" />
-            <param custom_config_ids="0x18000001, 0x00012C20" />
+            <module_params>
+                <param load_sound_model_ids="0x18000001, 0x0, 0x00012C14" />
+                <param unload_sound_model_ids="0x18000001, 0x0, 0x00012C15" />
+                <param confidence_levels_ids="0x18000001, 0x0, 0x00012C07" />
+                <param operation_mode_ids="0x18000001, 0x0, 0x00012C02" />
+                <param polling_enable_ids="0x18000001, 0x0, 0x00012C1B" />
+                <param custom_config_ids="0x18000001, 0x0, 0x00012C20" />
+            </module_params>
         </lsm_usecase>
 
         <!-- format: "ADPCM_packet" or "PCM_packet" !-->
@@ -316,20 +263,31 @@
     <sound_model_config>
         <param vendor_uuid="9f6ad62a-1f0b-11e7-87c5-40a8f03d3f15" />
         <param execution_type="WDSP" /> <!-- value: "WDSP" "ADSP" "DYNAMIC" -->
-        <param library="none" />
+        <param max_ape_phrases="1" />
+        <param max_ape_users="1" />
+        <!-- Profile specific data which the algorithm can support -->
+        <param sample_rate="16000" />
+        <param bit_width="16" />
+        <param out_channels="1"/> <!-- Module output channels -->
         <!-- fluence enabled: "FLUENCE_DMIC", "FLUENCE_QMIC" -->
         <param wdsp_fluence_type="NONE" />
-        <gcs_usecase>
-            <param uid="0x6" />
-            <param acdb_devices="DEVICE_HANDSET_MIC_CPE" />
-            <param load_sound_model_ids="0x18000001, 0x4, 0x18000102" />
-            <param start_engine_ids="0x18000001, 0x4, 0x18000103" />
-            <param confidence_levels_ids="0x18000001, 0x4, 0x00012C28" />
-            <param detection_event_ids="0x18000001, 0x4, 0x00012C29" />
-            <param custom_config_ids="0x18000001, 0x4, 0x00012C20" />
-            <param read_cmd_ids="0x00020013, 0x7, 0x00020015" />
-            <param read_rsp_ids="0x00020013, 0x7, 0x00020016" />
-        </gcs_usecase>
+        <!-- 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" />
+        <param fluence_type="FLUENCE_DMIC" />
+        <lsm_usecase>
+            <param execution_mode="ADSP" />
+            <param app_type="3" /> <!-- app type used in ACDB -->
+            <param in_channels="1"/> <!-- Module input channels -->
+            <module_params>
+                <param load_sound_model_ids="0x18000001, 0x0, 0x00012C14" />
+                <param unload_sound_model_ids="0x18000001, 0x0, 0x00012C15" />
+                <param confidence_levels_ids="0x18000001, 0x0, 0x00012C07" />
+                <param operation_mode_ids="0x18000001, 0x0, 0x00012C02" />
+                <param polling_enable_ids="0x18000001, 0x0, 0x00012C1B" />
+                <param custom_config_ids="0x18000001, 0x0, 0x00012C20" />
+            </module_params>
+        </lsm_usecase>
         <!--  kw_duration is in milli seconds. It is valid only for FTRT
             transfer mode -->
         <param capture_keyword="MULAW_raw, FTRT, 5000" />
diff --git a/configs/msmsteppe_au/msmsteppe_au.mk b/configs/msmsteppe_au/msmsteppe_au.mk
index 9d990a5..fcddc55 100644
--- a/configs/msmsteppe_au/msmsteppe_au.mk
+++ b/configs/msmsteppe_au/msmsteppe_au.mk
@@ -39,6 +39,9 @@
 USE_XML_AUDIO_POLICY_CONF := 1
 AUDIO_FEATURE_ENABLED_DLKM := true
 BOARD_SUPPORTS_SOUND_TRIGGER := true
+BOARD_SUPPORTS_OPENSOURCE_STHAL := true
+AUDIO_FEATURE_ENABLED_SVA_CHANNEL_IDX
+AUDIO_FEATURE_QSSI_COMPLIANCE := true
 AUDIO_FEATURE_ENABLED_INSTANCE_ID := true
 ifeq ($(TARGET_HAS_GENERIC_KERNEL_HEADERS), true)
 AUDIO_FEATURE_ENABLED_GKI := true
diff --git a/configs/msmsteppe_au/sound_trigger_platform_info.xml b/configs/msmsteppe_au/sound_trigger_platform_info.xml
index 1545922..a7d0459 100644
--- a/configs/msmsteppe_au/sound_trigger_platform_info.xml
+++ b/configs/msmsteppe_au/sound_trigger_platform_info.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
-<!--- Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.       -->
+<!--- Copyright (c) 2013-2021, 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    -->
@@ -26,17 +26,20 @@
 <!--- 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="0x0103" /> <!-- this must be the first param -->
+    <param version="0x0106" /> <!-- 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>                                                     -->
+<!--- 0x0104: instance id support for both WDSP<CPE> and ADSP lsm usecases      -->
+<!--- 0x0105: Select <lsm_usecase> based on capture device                      -->
+<!--- 0x0106: Add module_params tag to support multiple module and param ids    -->
+<!--- per <lsm_usecase>                                                         -->
+
     <common_config>
-        <param implementer_version="0x0100" />
-        <param max_cpe_sessions="1" />
-        <param max_wdsp_sessions="2" />
+        <param implementer_version="0x0102" />
         <param max_ape_sessions="8" />
         <param enable_failure_detection="false" />
         <param support_device_switch="false" />
@@ -45,55 +48,47 @@
         <param transit_to_adsp_on_battery_charging="false" />
         <!-- Below backend params must match with port used in mixer path file -->
         <!-- param used to configure backend sample rate, format and channels -->
-        <!-- uncomment TX_CDC_DMA_TX_3 values for internal codec and comment SLIM_0_TX values -->
         <param backend_port_name="TERT_TDM_TX_0" />
-        <!-- param backend_port_name="TX_CDC_DMA_TX_3" /-->
         <!-- Param used to match and obtain device backend index -->
         <param backend_dai_name="TERT_TDM_TX_0" />
-        <!-- param backend_dai_name="TX_CDC_DMA_TX_3" /-->
+        <!-- Param used to indicate if SVA has dedicated SLIM ports -->
+        <param dedicated_sva_path="true" />
+        <param platform_lpi_enable="false" />
         <param concurrent_capture="true" />
         <param concurrent_voice_call="false" />
         <param concurrent_voip_call="false" />
     </common_config>
     <acdb_ids>
-        <!--For internal codec please enable below device-->
-        <!--param DEVICE_HANDSET_MIC_APE="130" /-->
         <param DEVICE_HANDSET_MIC_APE="100" />
         <param DEVICE_HANDSET_MIC_CPE="128" />
         <param DEVICE_HANDSET_MIC_ECPP_CPE="128" />
         <param DEVICE_HANDSET_TMIC_CPE="130" />
+        <param DEVICE_HANDSET_TMIC_APE="157" />
         <param DEVICE_HANDSET_MIC_PP_APE="135" />
         <param DEVICE_HANDSET_QMIC_APE="132" />
         <param DEVICE_HEADSET_MIC_CPE="139" />
+        <param DEVICE_HEADSET_MIC_APE="141" />
         <param DEVICE_HANDSET_DMIC_APE="149" />
-        <param DEVICE_HANDSET_DMIC_CPE="153" />
-        <param DEVICE_HANDSET_TMIC_APE="157" />
+        <param DEVICE_HANDSET_DMIC_CPE="148" />
     </acdb_ids>
+
     <!-- Multiple sound_model_config tags can be listed, each with unique   -->
     <!-- vendor_uuid. The below tag represents QTI SVA engine sound model   -->
     <!-- configuration. ISV must use their own unique vendor_uuid.          -->
+
+    <!-- QTI SVA -->
     <sound_model_config>
         <param vendor_uuid="68ab2d40-e860-11e3-95ef-0002a5d5c51b" />
-        <param execution_type="ADSP" /> <!-- value: "WDSP" "ADSP" "DYNAMIC" -->
-        <param library="libsmwrapper.so" />
-        <param max_cpe_phrases="6" />
-        <param max_cpe_users="3" />
+        <param execution_type="ADSP" />
+        <param merge_first_stage_sound_models="false"/>
         <param max_ape_phrases="20" />
         <param max_ape_users="10" />
         <!-- Profile specific data which the algorithm can support -->
         <param sample_rate="16000" />
         <param bit_width="16" />
         <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="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_QMIC" />
-        <!-- wdsp_fluence_type: fluence disabled: "NONE" -->
-        <!-- fluence enabled: "FLUENCE_DMIC", "FLUENCE_TMIC", "FLUENCE_QMIC" -->
-        <param wdsp_fluence_type="NONE" />
+        <param dam_token_id="1"/>
+
         <arm_ss_usecase>
             <!-- Options are "KEYWORD_DETECTION", "USER_VERIFICATION", "CUSTOM_DETECTION"  -->
             <param sm_detection_type= "KEYWORD_DETECTION" />
@@ -111,72 +106,58 @@
             <param bit_wdith="16"/>
             <param channel_count="1"/>
         </arm_ss_usecase>
-        <gcs_usecase>
-            <param uid="0x1" />
-            <param acdb_devices="DEVICE_HANDSET_MIC_CPE, DEVICE_HANDSET_TMIC_CPE, DEVICE_HEADSET_MIC_CPE" />
-            <!-- module_id, instance_id, param_id -->
-            <param load_sound_model_ids="0x00012C0D, 0x2, 0x00012C14" />
-            <param confidence_levels_ids="0x00012C0D, 0x2, 0x00012C28" />
-            <param detection_event_ids="0x00012C0D, 0x2, 0x00012C29" />
-            <param read_cmd_ids="0x00020013, 0x2, 0x00020015" />
-            <param read_rsp_ids="0x00020013, 0x2, 0x00020016" />
-            <param custom_config_ids="0x00012C0D, 0x2, 0x00012C20" />
-        </gcs_usecase>
-        <gcs_usecase>
-            <param uid="0x2" />
-            <param acdb_devices="DEVICE_HANDSET_MIC_CPE, DEVICE_HANDSET_TMIC_CPE, DEVICE_HEADSET_MIC_CPE" />
-            <param load_sound_model_ids="0x00012C0D, 0x3, 0x00012C14" />
-            <param confidence_levels_ids="0x00012C0D, 0x3, 0x00012C28" />
-            <param detection_event_ids="0x00012C0D, 0x3, 0x00012C29" />
-            <param read_cmd_ids="0x00020013, 0x3, 0x00020015" />
-            <param read_rsp_ids="0x00020013, 0x3, 0x00020016" />
-            <param custom_config_ids="0x00012C0D, 0x3, 0x00012C20" />
-        </gcs_usecase>
-        <gcs_usecase>
-            <param uid="0x7" />
-            <param acdb_devices="DEVICE_HANDSET_DMIC_CPE" />
-            <param load_sound_model_ids="0x00012C0D, 0x7, 0x00012C14" />
-            <param confidence_levels_ids="0x00012C0D, 0x7, 0x00012C28" />
-            <param detection_event_ids="0x00012C0D, 0x7, 0x00012B05" />
-            <param read_cmd_ids="0x00020013, 0x7, 0x00020015" />
-            <param read_rsp_ids="0x00020013, 0x7, 0x00020016" />
-            <param custom_config_ids="0x00012C0D, 0x7, 0x00012C20" />
-            <param det_event_type_ids="0x00012C0D, 0x7, 0x00012C2A" />
-        </gcs_usecase>
-        <gcs_usecase>
-            <param uid="0x8" />
-            <param acdb_devices="DEVICE_HANDSET_DMIC_CPE" />
-            <param load_sound_model_ids="0x00012C0D, 0x8, 0x00012C14" />
-            <param confidence_levels_ids="0x00012C0D, 0x8, 0x00012C28" />
-            <param detection_event_ids="0x00012C0D, 0x8, 0x00012B05" />
-            <param read_cmd_ids="0x00020013, 0x8, 0x00020015" />
-            <param read_rsp_ids="0x00020013, 0x8, 0x00020016" />
-            <param custom_config_ids="0x00012C0D, 0x8, 0x00012C20" />
-            <param det_event_type_ids="0x00012C0D, 0x8, 0x00012C2A" />
-        </gcs_usecase>
+        <arm_ss_usecase>
+            <param sm_detection_type= "KEYWORD_DETECTION" />
+            <param sm_id="0x8" />
+            <param module_lib="libcapiv2svarnn.so"/>
+            <param sample_rate="16000"/>
+            <param bit_wdith="16"/>
+            <param channel_count="1"/>
+        </arm_ss_usecase>
         <!-- Module and param ids with which the algorithm is integrated
             in non-graphite firmware (note these must come after gcs params)
             Extends flexibility to have different ids based on execution type.
             valid execution_type values: "WDSP" "ADSP" -->
         <lsm_usecase>
+            <param capture_device="HANDSET" />
+            <!-- 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="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_QMIC" />
             <param execution_mode="ADSP" />
+            <!-- lpi_mode: "NON_LPI_BARGE_IN", "NON_LPI", "LPI" -->
+            <!-- NON_LPI_BARGE_IN: Default non-LPI mode type. lsm_usecase -->
+            <!-- must be present with this mode type to handle barge-in. -->
+            <!-- NON_LPI: If another lsm_usecase is present with this mode -->
+            <!-- type, it will be used for non-LPI non-barge-in usecases. -->
+            <!-- If not present, NON_LPI_BARGE_IN mode type will be used. -->
+            <!-- LPI: This mode type will be used for LPI usecases. -->
             <param app_type="2" /> <!-- app type used in ACDB -->
+            <param pdk5_app_type="1" />
             <param in_channels="4"/> <!-- Module input channels -->
-            <param load_sound_model_ids="0x00012C1C, 0x00012C14" />
-            <param unload_sound_model_ids="0x00012C1C, 0x00012C15" />
-            <param confidence_levels_ids="0x00012C1C, 0x00012C07" />
-            <param operation_mode_ids="0x00012C1C, 0x00012C02" />
-            <param polling_enable_ids="0x00012C1C, 0x00012C1B" />
-            <param custom_config_ids="0x00012C1C, 0x00012C20" />
-            <param det_event_type_ids="0x00012C1C, 0x00012C2C" />
-        </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" />
+            <module_params>
+                <param module_type="GMM" />
+                <param load_sound_model_ids="0x00012C1C, 0x0, 0x00012C14" />
+                <param unload_sound_model_ids="0x00012C1C, 0x0, 0x00012C15" />
+                <param confidence_levels_ids="0x00012C1C, 0x0, 0x00012C07" />
+                <param operation_mode_ids="0x00012C1C, 0x0, 0x00012C02" />
+                <param polling_enable_ids="0x00012C1C, 0x0, 0x00012C1B" />
+                <param custom_config_ids="0x00012C1C, 0x0, 0x00012C20" />
+                <param det_event_type_ids="0x00012C1C, 0x0, 0x00012C2C" />
+                <param lab_dam_cfg_ids="0x00012C08, 0x0, 0x000102C4" />
+            </module_params>
+            <module_params>
+                <param module_type="PDK5" />
+                <param load_sound_model_ids="0x00012C35, 0x0, 0x00012C36" />
+                <param unload_sound_model_ids="0x00012C35, 0x0, 0x00012C37" />
+                <param confidence_levels_ids="0x00012C35, 0x0, 0x00012C38" />
+                <param custom_config_ids="0x00012C35, 0x0, 0x00012C20" />
+                <param det_event_type_ids="0x00012C35, 0x0, 0x00012C2C" />
+                <param lab_dam_cfg_ids="0x00012C08, 0x0, 0x000102C4" />
+            </module_params>
         </lsm_usecase>
 
         <!-- format: "ADPCM_packet" or "PCM_packet" !-->
@@ -185,17 +166,12 @@
             transfer mode -->
         <param capture_keyword="PCM_packet, RT, 2000" />
         <param client_capture_read_delay="2000" />
-        <param lpi_enable="false" />
-        <param concurrent_capture="true" />
-        <param concurrent_voice_call="false" />
-        <param concurrent_voip_call="false" />
     </sound_model_config>
 
-    <!-- QTI Music Detection !-->
+ <!-- QTI Music Detection !-->
     <sound_model_config>
         <param vendor_uuid="876c1b46-9d4d-40cc-a4fd-4d5ec7a80e47" />
-        <param execution_type="ADSP" /> <!-- value: "WDSP" "ADSP" "DYNAMIC" -->
-        <param library="libsmwrapper.so" />
+        <param execution_type="WDSP" /> <!-- value: "WDSP" "ADSP" "DYNAMIC" -->
         <param max_cpe_phrases="1" />
         <param max_cpe_users="1" />
         <param max_ape_phrases="1" />
@@ -214,18 +190,6 @@
         <!-- wdsp_fluence_type: fluence disabled: "NONE" -->
         <!-- fluence enabled: "FLUENCE_DMIC", "FLUENCE_TMIC", "FLUENCE_QMIC" -->
         <param wdsp_fluence_type="NONE" />
-        <gcs_usecase>
-            <param uid="0x5" />
-            <param acdb_devices="DEVICE_HANDSET_MIC_CPE, DEVICE_HANDSET_TMIC_CPE, DEVICE_HEADSET_MIC_CPE" />
-            <!-- module_id, instance_id, param_id -->
-            <param load_sound_model_ids="0x00012C2E, 0x6, 0x00012C14" />
-            <param confidence_levels_ids="0x00012C2E, 0x6, 0x00012C28" />
-            <param detection_event_ids="0x00012C2E, 0x6, 0x00012B05" />
-            <param read_cmd_ids="0x00020013, 0x6, 0x00020015" />
-            <param read_rsp_ids="0x00020013, 0x6, 0x00020016" />
-            <param custom_config_ids="0x00012C2E, 0x6, 0x00012C2D" />
-            <param det_event_type_ids="0x00012C2E, 0x6, 0x00012C2C" />
-        </gcs_usecase>
         <!-- Module and param ids with which the algorithm is integrated
             in non-graphite firmware (note these must come after gcs params)
             Extends flexibility to have different ids based on execution type.
@@ -234,11 +198,13 @@
             <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" />
-            <param det_event_type_ids="0x00012C22, 0x00012C2C" />
-            <param custom_config_ids="0x00012C22, 0x00012C30" />
+            <module_params>
+                <param load_sound_model_ids="0x00012C22, 0x0, 0x00012C14" />
+                <param unload_sound_model_ids="0x00012C22, 0x0, 0x00012C15" />
+                <param confidence_levels_ids="0x00012C22, 0x0, 0x00012C07" />
+                <param det_event_type_ids="0x00012C22, 0x0, 0x00012C2C" />
+                <param custom_config_ids="0x00012C22, 0x0, 0x00012C30" />
+            </module_params>
         </lsm_usecase>
 
         <!-- format: "ADPCM_packet" or "PCM_packet" !-->
@@ -249,11 +215,10 @@
         <param client_capture_read_delay="2000" />
     </sound_model_config>
 
-<!-- Sound model config for Hotword !-->
+    <!-- Google Hotword -->
     <sound_model_config>
         <param vendor_uuid="7038ddc8-30f2-11e6-b0ac-40a8f03d3f15" />
         <param execution_type="WDSP" /> <!-- value: "WDSP" "ADSP" "DYNAMIC" -->
-        <param library="none" />
         <param max_cpe_phrases="1" />
         <param max_cpe_users="1" />
         <param max_ape_phrases="1" />
@@ -265,62 +230,67 @@
         <!-- 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" -->
+        <!-- fluence enabled: "FLUENCE_DMIC", "FLUENCE_QMIC" -->
         <param wdsp_fluence_type="NONE" />
-        <gcs_usecase>
-            <param uid="0x3" />
-            <param acdb_devices="DEVICE_HANDSET_MIC_CPE, DEVICE_HANDSET_TMIC_CPE" />
-            <param load_sound_model_ids="0x18000001, 0x4, 0x00012C14" />
-            <param confidence_levels_ids="0x18000001, 0x4, 0x00012C28" />
-            <param detection_event_ids="0x18000001, 0x4, 0x00012C29" />
-            <param read_cmd_ids="0x00020013, 0x4, 0x00020015" />
-            <param read_rsp_ids="0x00020013, 0x4, 0x00020016" />
-            <param custom_config_ids="0x18000001, 0x4, 0x00012C20" />
-        </gcs_usecase>
-        <gcs_usecase>
-            <param uid="0x4" />
-            <param acdb_devices="DEVICE_HANDSET_DMIC_CPE" />
-            <param load_sound_model_ids="0x18000001, 0x5, 0x00012C14" />
-            <param confidence_levels_ids="0x18000001, 0x5, 0x00012C28" />
-            <param detection_event_ids="0x18000001, 0x5, 0x00012C29" />
-            <param read_cmd_ids="0x00020013, 0x5, 0x00020015" />
-            <param read_rsp_ids="0x00020013, 0x5, 0x00020016" />
-            <param custom_config_ids="0x18000001, 0x5, 0x00012C20" />
-        </gcs_usecase>
-        <!-- Module and param ids with which the algorithm is integrated
-            in non-graphite firmware (note these must come after gcs params)
-            Extends flexibility to have different ids based on execution type.
-            valid execution_type values: "WDSP" "ADSP" -->
         <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" />
-            <param operation_mode_ids="0x18000001, 0x00012C02" />
-            <param polling_enable_ids="0x18000001, 0x00012C1B" />
-            <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" />
+            <module_params>
+                <param load_sound_model_ids="0x18000001, 0x0, 0x00012C14" />
+                <param unload_sound_model_ids="0x18000001, 0x0, 0x00012C15" />
+                <param confidence_levels_ids="0x18000001, 0x0, 0x00012C07" />
+                <param operation_mode_ids="0x18000001, 0x0, 0x00012C02" />
+                <param polling_enable_ids="0x18000001, 0x0, 0x00012C1B" />
+                <param custom_config_ids="0x18000001, 0x0, 0x00012C20" />
+            </module_params>
         </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
             transfer mode -->
-        <param capture_keyword="PCM_packet, RT, 2000" />
+        <param capture_keyword="PCM_raw, FTRT, 2000" />
+        <param client_capture_read_delay="2000" />
+    </sound_model_config>
+
+    <!-- Google Music Detection -->
+    <sound_model_config>
+        <param vendor_uuid="9f6ad62a-1f0b-11e7-87c5-40a8f03d3f15" />
+        <param execution_type="WDSP" /> <!-- value: "WDSP" "ADSP" "DYNAMIC" -->
+        <param max_ape_phrases="1" />
+        <param max_ape_users="1" />
+        <!-- Profile specific data which the algorithm can support -->
+        <param sample_rate="16000" />
+        <param bit_width="16" />
+        <param out_channels="1"/> <!-- Module output channels -->
+        <!-- fluence enabled: "FLUENCE_DMIC", "FLUENCE_QMIC" -->
+        <param wdsp_fluence_type="NONE" />
+        <!-- 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" />
+        <param fluence_type="FLUENCE_DMIC" />
+        <lsm_usecase>
+            <param execution_mode="ADSP" />
+            <param app_type="3" /> <!-- app type used in ACDB -->
+            <param in_channels="1"/> <!-- Module input channels -->
+            <module_params>
+                <param load_sound_model_ids="0x18000001, 0x0, 0x00012C14" />
+                <param unload_sound_model_ids="0x18000001, 0x0, 0x00012C15" />
+                <param confidence_levels_ids="0x18000001, 0x0, 0x00012C07" />
+                <param operation_mode_ids="0x18000001, 0x0, 0x00012C02" />
+                <param polling_enable_ids="0x18000001, 0x0, 0x00012C1B" />
+                <param custom_config_ids="0x18000001, 0x0, 0x00012C20" />
+            </module_params>
+        </lsm_usecase>
+        <!--  kw_duration is in milli seconds. It is valid only for FTRT
+            transfer mode -->
+        <param capture_keyword="MULAW_raw, FTRT, 5000" />
         <param client_capture_read_delay="2000" />
     </sound_model_config>
 
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index 148f53d..4a0f964 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -91,6 +91,7 @@
 #define MIXER_SET_FEEDBACK_CHANNEL "BT set feedback channel"
 #define MIXER_SINK_SAMPLE_RATE     "BT_TX SampleRate"
 #define MIXER_AFE_SINK_CHANNELS    "AFE Output Channels"
+#define MIXER_AFE_SINK_CHANNELS_SLIM7    "AFE Output Channels SLIM7"
 #define MIXER_FMT_TWS_CHANNEL_MODE "TWS Channel Mode"
 #define MIXER_FMT_LC3_CHANNEL_MODE "LC3 Channel Mode"
 #define ENCODER_LATENCY_SBC        10
@@ -673,7 +674,7 @@
 struct lc3_stream_map_info_t
 {
     uint32_t stream_map_size;
-    struct lc3_stream_info_t streamMap[16];
+    struct lc3_stream_info_t streamMap[2];
 } __attribute__ ((packed));
 
 struct lc3_stream_map_ext_t
@@ -701,7 +702,7 @@
     struct lc3_config_ext_t fromAirConfig;
     uint32_t decoder_output_channel;
     uint32_t stream_map_size;
-    struct lc3_stream_map_ext_t streamMapIn[16];
+    struct lc3_stream_map_ext_t streamMapIn[2];
 } __attribute__ ((packed));
 
 struct lc3_enc_cfg_ext_t
@@ -713,7 +714,9 @@
 
 struct lc3_dec_codec_cfg_t
 {
+    struct lc3_dec_cfg_ext_t from_Air_cfg;
     struct lc3_stream_map_info_t streamMapToAir;
+    struct lc3_stream_map_info_t streamMapFromAir;
 } __attribute__ ((packed));
 
 struct lc3_dec_cfg_t
@@ -1062,7 +1065,8 @@
     }
 
     // Enable Slimbus 7 Rx feedback path for HD Voice use case
-    if (a2dp.bt_encoder_format == CODEC_TYPE_APTX_AD_SPEECH) {
+    if ((a2dp.bt_encoder_format == CODEC_TYPE_APTX_AD_SPEECH)
+        || ((a2dp.a2dp_sink_started == true) && (a2dp.bt_decoder_format == CODEC_TYPE_LC3))) {
         ALOGV("%s: Enable ABR Rx feedback path", __func__);
         ctl_abr_rx_path = mixer_get_ctl_by_name(a2dp.adev->mixer,
                                             MIXER_ABR_RX_FEEDBACK_PATH);
@@ -1342,7 +1346,8 @@
         sampling_rate = sampling_rate *2;
     }
 
-    if (a2dp.bt_encoder_format == CODEC_TYPE_LC3)
+    if (a2dp.bt_encoder_format == CODEC_TYPE_LC3 ||
+        a2dp.bt_decoder_format == CODEC_TYPE_LC3)
         sampling_rate = SAMPLING_RATE_96K;
 
     // No need to configure backend for PCM format.
@@ -1369,8 +1374,12 @@
 
     if (direction == SINK) {
         ALOGD("%s: set sink backend sample rate =%s", __func__, rate_str);
-        ctl_sample_rate = mixer_get_ctl_by_name(a2dp.adev->mixer,
-                                            MIXER_SINK_SAMPLE_RATE);
+        if (a2dp.bt_decoder_format == CODEC_TYPE_LC3)
+            ctl_sample_rate = mixer_get_ctl_by_name(a2dp.adev->mixer,
+                                                MIXER_SOURCE_SAMPLE_RATE_TX);
+        else
+            ctl_sample_rate = mixer_get_ctl_by_name(a2dp.adev->mixer,
+                                                MIXER_SINK_SAMPLE_RATE);
     } else {
         ALOGD("%s: set source backend sample rate =%s", __func__, rate_str);
         ctl_sample_rate = mixer_get_ctl_by_name(a2dp.adev->mixer,
@@ -1408,6 +1417,24 @@
                     goto fail;
                 }
             }
+        } else {
+            /* LC3 needs to set RX sample rate as well */
+            if (a2dp.bt_decoder_format == CODEC_TYPE_LC3) {
+                ALOGD("%s: set rx backend 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__);
+                    is_configured = false;
+                    goto fail;
+                }
+
+                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);
+                    is_configured = false;
+                    goto fail;
+                }
+            }
         }
     } else {
         /* Fallback to legacy approch if MIXER_SAMPLE_RATE_RX and
@@ -1439,8 +1466,12 @@
         }
 
         ALOGD("%s: set afe dec channels =%s", __func__, channels);
-        ctrl_channels = mixer_get_ctl_by_name(a2dp.adev->mixer,
-                                            MIXER_AFE_SINK_CHANNELS);
+        if (a2dp.bt_decoder_format == CODEC_TYPE_LC3)
+            ctrl_channels = mixer_get_ctl_by_name(a2dp.adev->mixer,
+                                                MIXER_AFE_SINK_CHANNELS_SLIM7);
+        else
+            ctrl_channels = mixer_get_ctl_by_name(a2dp.adev->mixer,
+                                                MIXER_AFE_SINK_CHANNELS);
     } else {
         //Configure AFE enc channels
         switch (a2dp.enc_channels) {
@@ -1739,26 +1770,218 @@
     return is_configured;
 }
 
+uint64_t convert_channel_map(uint32_t audio_location)
+{
+    int i;
+    uint64_t channel_mask = (uint64_t) 0x00000000;
+
+    if (!audio_location) {
+        channel_mask |= 1ULL << PCM_CHANNEL_C;
+        return channel_mask;
+    }
+
+    for (i = 0; i < AUDIO_LOCATION_MAX; i++) {
+         if (audio_location & audio_location_map_array[i])
+             channel_mask |= 1ULL << channel_map_array[i];
+    }
+
+    return channel_mask;
+}
+
+bool configure_lc3_enc_format(audio_lc3_codec_config_t *lc3_bt_cfg) {
+    struct mixer_ctl *ctl_enc_data = NULL;
+    int mixer_size = 0;
+    int ret = 0;
+    int i;
+    bool is_configured = false;
+    struct lc3_enc_cfg_t lc3_dsp_cfg;
+    uint64_t channel_mask;
+
+    if (lc3_bt_cfg == NULL)
+        return false;
+
+    ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
+    if (!ctl_enc_data) {
+        ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identified");
+        return false;
+    }
+
+    /* Initialize dsp configuration params */
+    memset(&lc3_dsp_cfg, 0x0, sizeof(struct lc3_enc_cfg_t));
+
+    lc3_dsp_cfg.enc_format = MEDIA_FMT_LC3;
+    //encoder structure
+
+    if (lc3_bt_cfg->enc_config.stream_map_size != 0) {
+        if (!lc3_bt_cfg->enc_config.streamMapOut[0].audio_location)
+            a2dp.enc_channels = CH_MONO;
+        else
+            a2dp.enc_channels = CH_STEREO;
+    }
+
+    lc3_dsp_cfg.imc_info.direction = IMC_RECEIVE;
+    lc3_dsp_cfg.imc_info.enable = IMC_ENABLE;
+    lc3_dsp_cfg.imc_info.purpose = IMC_PURPOSE_ID_BT_INFO;
+    lc3_dsp_cfg.imc_info.comm_instance = a2dp.abr_config.imc_instance;
+    lc3_dsp_cfg.enc_codec.to_Air_cfg.toAirConfig.api_version = lc3_bt_cfg->enc_config.toAirConfig.api_version;
+    lc3_dsp_cfg.enc_codec.to_Air_cfg.toAirConfig.sampling_freq = lc3_bt_cfg->enc_config.toAirConfig.sampling_freq;
+    lc3_dsp_cfg.enc_codec.to_Air_cfg.toAirConfig.max_octets_per_frame = lc3_bt_cfg->enc_config.toAirConfig.max_octets_per_frame;
+    lc3_dsp_cfg.enc_codec.to_Air_cfg.toAirConfig.frame_duration = lc3_bt_cfg->enc_config.toAirConfig.frame_duration;
+    lc3_dsp_cfg.enc_codec.to_Air_cfg.toAirConfig.bit_depth = lc3_bt_cfg->enc_config.toAirConfig.bit_depth;
+    lc3_dsp_cfg.enc_codec.to_Air_cfg.toAirConfig.num_blocks = lc3_bt_cfg->enc_config.toAirConfig.num_blocks;
+    lc3_dsp_cfg.enc_codec.to_Air_cfg.toAirConfig.default_q_level = lc3_bt_cfg->enc_config.toAirConfig.default_q_level;
+    for (i = 0; i < 16; i++)
+         lc3_dsp_cfg.enc_codec.to_Air_cfg.toAirConfig.vendor_specific[i] = lc3_bt_cfg->enc_config.toAirConfig.vendor_specific[i];
+    lc3_dsp_cfg.enc_codec.to_Air_cfg.toAirConfig.mode = lc3_bt_cfg->enc_config.toAirConfig.mode;
+    lc3_dsp_cfg.enc_codec.to_Air_cfg.stream_map_size = lc3_bt_cfg->enc_config.stream_map_size;
+    lc3_dsp_cfg.enc_codec.streamMapToAir.stream_map_size =  lc3_bt_cfg->enc_config.stream_map_size;
+
+    for (i = 0; i < lc3_dsp_cfg.enc_codec.to_Air_cfg.stream_map_size; i++) {
+         // for encoder stream map info
+         lc3_dsp_cfg.enc_codec.to_Air_cfg.streamMapOut[i].audio_location = lc3_bt_cfg->enc_config.streamMapOut[i].audio_location;
+         lc3_dsp_cfg.enc_codec.to_Air_cfg.streamMapOut[i].stream_id = lc3_bt_cfg->enc_config.streamMapOut[i].stream_id;
+         lc3_dsp_cfg.enc_codec.to_Air_cfg.streamMapOut[i].direction = lc3_bt_cfg->enc_config.streamMapOut[i].direction;
+         // for packetizer stream map info
+         channel_mask = convert_channel_map(lc3_bt_cfg->enc_config.streamMapOut[i].audio_location);
+         lc3_dsp_cfg.enc_codec.streamMapToAir.streamMap[i].stream_id = lc3_bt_cfg->enc_config.streamMapOut[i].stream_id;
+         lc3_dsp_cfg.enc_codec.streamMapToAir.streamMap[i].direction = lc3_bt_cfg->enc_config.streamMapOut[i].direction;
+         lc3_dsp_cfg.enc_codec.streamMapToAir.streamMap[i].channel_mask_lsw = channel_mask  & 0x00000000FFFFFFFF;
+         lc3_dsp_cfg.enc_codec.streamMapToAir.streamMap[i].channel_mask_msw = (channel_mask & 0xFFFFFFFF00000000) >> 32;
+    }
+
+    /* Configure AFE DSP configuration */
+    mixer_size = sizeof(struct lc3_enc_cfg_t);
+    ret = mixer_ctl_set_array(ctl_enc_data, (void *)&lc3_dsp_cfg,
+                  mixer_size);
+    if (ret != 0) {
+        ALOGE("%s: Failed to set lc3 encoder config", __func__);
+        is_configured = false;
+        goto fail;
+    }
+
+    ret = a2dp_set_bit_format(ENCODER_BIT_FORMAT_PCM_24);
+    if (ret != 0) {
+        ALOGE("%s: Failed to set lc3 bit format", __func__);
+        is_configured = false;
+        goto fail;
+    }
+
+    is_configured = true;
+    a2dp.bt_encoder_format = CODEC_TYPE_LC3;
+
+fail:
+    return is_configured;
+}
+
+bool configure_lc3_dec_format(audio_lc3_codec_config_t *lc3_bt_cfg)
+{
+    struct mixer_ctl *ctl_dec_data = NULL;
+    struct lc3_dec_cfg_t lc3_dsp_cfg;
+    uint64_t channel_mask;
+    bool is_configured = false;
+    int ret = 0;
+    int i;
+
+    if (lc3_bt_cfg == NULL)
+        return false;
+
+    ctl_dec_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_SOURCE_DEC_CONFIG_BLOCK);
+    if (!ctl_dec_data) {
+        ALOGE(" ERROR  a2dp decoder CONFIG data mixer control not identified");
+        return false;
+    }
+
+    memset(&lc3_dsp_cfg, 0x0, sizeof(struct lc3_dec_cfg_t));
+
+    lc3_dsp_cfg.abr_cfg.dec_format = MEDIA_FMT_LC3;
+    lc3_dsp_cfg.abr_cfg.imc_info.direction  = IMC_TRANSMIT;
+    lc3_dsp_cfg.abr_cfg.imc_info.enable = IMC_ENABLE;
+    lc3_dsp_cfg.abr_cfg.imc_info.purpose = IMC_PURPOSE_ID_BT_INFO;
+
+    lc3_dsp_cfg.abr_cfg.imc_info.comm_instance = a2dp.abr_config.imc_instance;
+
+        /* To check whether decoder configuration is present or not*/
+    if (lc3_bt_cfg->dec_config.stream_map_size != 0) {
+        lc3_dsp_cfg.dec_codec.from_Air_cfg.fromAirConfig.api_version = lc3_bt_cfg->dec_config.fromAirConfig.api_version;
+        lc3_dsp_cfg.dec_codec.from_Air_cfg.fromAirConfig.sampling_freq = lc3_bt_cfg->dec_config.fromAirConfig.sampling_freq;
+        lc3_dsp_cfg.dec_codec.from_Air_cfg.fromAirConfig.max_octets_per_frame = lc3_bt_cfg->dec_config.fromAirConfig.max_octets_per_frame;
+        lc3_dsp_cfg.dec_codec.from_Air_cfg.fromAirConfig.frame_duration = lc3_bt_cfg->dec_config.fromAirConfig.frame_duration;
+        lc3_dsp_cfg.dec_codec.from_Air_cfg.fromAirConfig.bit_depth = lc3_bt_cfg->dec_config.fromAirConfig.bit_depth;
+        lc3_dsp_cfg.dec_codec.from_Air_cfg.fromAirConfig.num_blocks = lc3_bt_cfg->dec_config.fromAirConfig.num_blocks;
+        lc3_dsp_cfg.dec_codec.from_Air_cfg.fromAirConfig.default_q_level = lc3_bt_cfg->dec_config.fromAirConfig.default_q_level;
+        for (i = 0; i < 16; i++)
+        lc3_dsp_cfg.dec_codec.from_Air_cfg.fromAirConfig.vendor_specific[i] = lc3_bt_cfg->dec_config.fromAirConfig.vendor_specific[i];
+        lc3_dsp_cfg.dec_codec.from_Air_cfg.fromAirConfig.mode = lc3_bt_cfg->dec_config.fromAirConfig.mode;
+        lc3_dsp_cfg.dec_codec.from_Air_cfg.decoder_output_channel = lc3_bt_cfg->dec_config.decoder_output_channel;
+        lc3_dsp_cfg.dec_codec.from_Air_cfg.stream_map_size = lc3_bt_cfg->dec_config.stream_map_size;
+        lc3_dsp_cfg.dec_codec.streamMapFromAir.stream_map_size = lc3_bt_cfg->dec_config.stream_map_size;
+
+        //for depacketizer both fromAir and toAir streamMap needs to be sent.
+        for (i = 0; i < lc3_dsp_cfg.dec_codec.from_Air_cfg.stream_map_size; i++) {
+            // for decoder stream map info
+            lc3_dsp_cfg.dec_codec.from_Air_cfg.streamMapIn[i].audio_location = lc3_bt_cfg->dec_config.streamMapIn[i].audio_location;
+            lc3_dsp_cfg.dec_codec.from_Air_cfg.streamMapIn[i].stream_id = lc3_bt_cfg->dec_config.streamMapIn[i].stream_id;
+            lc3_dsp_cfg.dec_codec.from_Air_cfg.streamMapIn[i].direction = lc3_bt_cfg->dec_config.streamMapIn[i].direction;
+            // for depacketizer stream map fromAir info
+            channel_mask = convert_channel_map(lc3_bt_cfg->dec_config.streamMapIn[i].audio_location);
+            lc3_dsp_cfg.dec_codec.streamMapFromAir.streamMap[i].stream_id = lc3_bt_cfg->dec_config.streamMapIn[i].stream_id;
+            lc3_dsp_cfg.dec_codec.streamMapFromAir.streamMap[i].direction = lc3_bt_cfg->dec_config.streamMapIn[i].direction;
+            lc3_dsp_cfg.dec_codec.streamMapFromAir.streamMap[i].channel_mask_lsw = channel_mask & 0x00000000FFFFFFFF;
+            lc3_dsp_cfg.dec_codec.streamMapFromAir.streamMap[i].channel_mask_msw = (channel_mask & 0xFFFFFFFF00000000) >> 32;
+        }
+    }
+
+    lc3_dsp_cfg.dec_codec.streamMapToAir.stream_map_size =  lc3_bt_cfg->enc_config.stream_map_size;
+
+    for (i = 0; i < lc3_bt_cfg->enc_config.stream_map_size; i++) {
+         // for depacketizer stream map toAir info
+         channel_mask = convert_channel_map(lc3_bt_cfg->enc_config.streamMapOut[i].audio_location);
+         lc3_dsp_cfg.dec_codec.streamMapToAir.streamMap[i].stream_id = lc3_bt_cfg->enc_config.streamMapOut[i].stream_id;
+         lc3_dsp_cfg.dec_codec.streamMapToAir.streamMap[i].direction = lc3_bt_cfg->enc_config.streamMapOut[i].direction;
+         lc3_dsp_cfg.dec_codec.streamMapToAir.streamMap[i].channel_mask_lsw = channel_mask  & 0x00000000FFFFFFFF;
+         lc3_dsp_cfg.dec_codec.streamMapToAir.streamMap[i].channel_mask_msw = (channel_mask & 0xFFFFFFFF00000000) >> 32;
+    }
+
+    ret = mixer_ctl_set_array(ctl_dec_data, (void *)&lc3_dsp_cfg,
+                              sizeof(struct lc3_dec_cfg_t));
+    if (ret != 0) {
+        ALOGE("%s: failed to set LC3 decoder config", __func__);
+        is_configured = false;
+        goto fail;
+    }
+
+    is_configured = true;
+    a2dp.bt_decoder_format = CODEC_TYPE_LC3;
+    a2dp.dec_channels = CH_STEREO;
+
+fail:
+    return is_configured;
+}
+
 /* API to configure AFE decoder in DSP */
 static bool configure_a2dp_sink_decoder_format()
 {
     void *codec_info = NULL;
+    uint8_t multi_cast = 0, num_dev = 1;
     codec_t codec_type = CODEC_TYPE_INVALID;
     bool is_configured = false;
     struct mixer_ctl *ctl_dec_data = NULL;
 
-    if (!a2dp.audio_get_dec_config) {
+    if (a2dp.audio_get_dec_config) {
+        ctl_dec_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_SINK_DEC_CONFIG_BLOCK);
+        if (!ctl_dec_data) {
+            ALOGE(" ERROR  a2dp decoder CONFIG data mixer control not identified");
+            is_configured = false;
+            return false;
+        }
+        codec_info = a2dp.audio_get_dec_config(&codec_type);
+    } else if (a2dp.audio_get_enc_config) {
+        codec_info = a2dp.audio_get_enc_config(&multi_cast, &num_dev, &codec_type);
+    } else {
         ALOGE(" a2dp handle is not identified, ignoring a2dp decoder config");
         return false;
     }
 
-    ctl_dec_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_SINK_DEC_CONFIG_BLOCK);
-    if (!ctl_dec_data) {
-        ALOGE(" ERROR  a2dp decoder CONFIG data mixer control not identified");
-        is_configured = false;
-        return false;
-    }
-    codec_info = a2dp.audio_get_dec_config(&codec_type);
     switch(codec_type) {
         case CODEC_TYPE_SBC:
             ALOGD(" SBC decoder supported BT device");
@@ -1769,6 +1992,12 @@
             is_configured =
               configure_aac_dec_format((audio_aac_dec_config_t *)codec_info);
             break;
+        case CODEC_TYPE_LC3:
+            ALOGD(" LC3 decoder supported BT device");
+            is_configured =
+              (configure_lc3_enc_format((audio_lc3_codec_config_t *)codec_info) &&
+               configure_lc3_dec_format((audio_lc3_codec_config_t *)codec_info));
+            break;
         default:
             ALOGD(" Received Unsupported decoder format");
             is_configured = false;
@@ -2588,163 +2817,6 @@
     return is_configured;
 }
 
-uint64_t convert_channel_map(uint32_t audio_location)
-{
-    int i;
-    uint64_t channel_mask = (uint64_t) 0x00000000;
-
-    if (!audio_location) {
-        channel_mask |= 1ULL << PCM_CHANNEL_C;
-        return channel_mask;
-    }
-
-    for (i = 0; i < AUDIO_LOCATION_MAX; i++) {
-         if (audio_location & audio_location_map_array[i])
-             channel_mask |= 1ULL << channel_map_array[i];
-    }
-
-    return channel_mask;
-}
-
-bool configure_lc3_enc_format(audio_lc3_codec_config_t *lc3_bt_cfg) {
-    struct mixer_ctl *ctl_enc_data = NULL;
-    int mixer_size = 0;
-    int ret = 0;
-    int i;
-    bool is_configured = false;
-    struct lc3_enc_cfg_t lc3_dsp_cfg;
-    uint64_t channel_mask;
-
-    if (lc3_bt_cfg == NULL)
-        return false;
-
-    ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
-    if (!ctl_enc_data) {
-        ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identified");
-        return false;
-    }
-
-    /* Initialize dsp configuration params */
-    memset(&lc3_dsp_cfg, 0x0, sizeof(struct lc3_enc_cfg_t));
-
-    lc3_dsp_cfg.enc_format = MEDIA_FMT_LC3;
-    //encoder structure
-
-    if (lc3_bt_cfg->enc_config.stream_map_size != 0) {
-        if (!lc3_bt_cfg->enc_config.streamMapOut[0].audio_location)
-            a2dp.enc_channels = CH_MONO;
-        else
-            a2dp.enc_channels = CH_STEREO;
-    }
-
-    lc3_dsp_cfg.imc_info.direction = IMC_RECEIVE;
-    lc3_dsp_cfg.imc_info.enable = IMC_ENABLE;
-    lc3_dsp_cfg.imc_info.purpose = IMC_PURPOSE_ID_BT_INFO;
-    lc3_dsp_cfg.imc_info.comm_instance = a2dp.abr_config.imc_instance;
-    lc3_dsp_cfg.enc_codec.to_Air_cfg.toAirConfig.api_version = lc3_bt_cfg->enc_config.toAirConfig.api_version;
-    lc3_dsp_cfg.enc_codec.to_Air_cfg.toAirConfig.sampling_freq = lc3_bt_cfg->enc_config.toAirConfig.sampling_freq;
-    lc3_dsp_cfg.enc_codec.to_Air_cfg.toAirConfig.max_octets_per_frame = lc3_bt_cfg->enc_config.toAirConfig.max_octets_per_frame;
-    lc3_dsp_cfg.enc_codec.to_Air_cfg.toAirConfig.frame_duration = lc3_bt_cfg->enc_config.toAirConfig.frame_duration;
-    lc3_dsp_cfg.enc_codec.to_Air_cfg.toAirConfig.bit_depth = lc3_bt_cfg->enc_config.toAirConfig.bit_depth;
-    lc3_dsp_cfg.enc_codec.to_Air_cfg.toAirConfig.num_blocks = lc3_bt_cfg->enc_config.toAirConfig.num_blocks;
-    lc3_dsp_cfg.enc_codec.to_Air_cfg.toAirConfig.default_q_level = lc3_bt_cfg->enc_config.toAirConfig.default_q_level;
-    for (i = 0; i < 16; i++)
-         lc3_dsp_cfg.enc_codec.to_Air_cfg.toAirConfig.vendor_specific[i] = lc3_bt_cfg->enc_config.toAirConfig.vendor_specific[i];
-    lc3_dsp_cfg.enc_codec.to_Air_cfg.toAirConfig.mode = lc3_bt_cfg->enc_config.toAirConfig.mode;
-    lc3_dsp_cfg.enc_codec.to_Air_cfg.stream_map_size = lc3_bt_cfg->enc_config.stream_map_size;
-    lc3_dsp_cfg.enc_codec.streamMapToAir.stream_map_size =  lc3_bt_cfg->enc_config.stream_map_size;
-
-    for (i = 0; i < lc3_dsp_cfg.enc_codec.to_Air_cfg.stream_map_size; i++) {
-         // for encoder stream map info
-         lc3_dsp_cfg.enc_codec.to_Air_cfg.streamMapOut[i].audio_location = lc3_bt_cfg->enc_config.streamMapOut[i].audio_location;
-         lc3_dsp_cfg.enc_codec.to_Air_cfg.streamMapOut[i].stream_id = lc3_bt_cfg->enc_config.streamMapOut[i].stream_id;
-         lc3_dsp_cfg.enc_codec.to_Air_cfg.streamMapOut[i].direction = lc3_bt_cfg->enc_config.streamMapOut[i].direction;
-         // for packetizer stream map info
-         channel_mask = convert_channel_map(lc3_bt_cfg->enc_config.streamMapOut[i].audio_location);
-         lc3_dsp_cfg.enc_codec.streamMapToAir.streamMap[i].stream_id = lc3_bt_cfg->enc_config.streamMapOut[i].stream_id;
-         lc3_dsp_cfg.enc_codec.streamMapToAir.streamMap[i].direction = lc3_bt_cfg->enc_config.streamMapOut[i].direction;
-         lc3_dsp_cfg.enc_codec.streamMapToAir.streamMap[i].channel_mask_lsw = channel_mask  & 0x00000000FFFFFFFF;
-         lc3_dsp_cfg.enc_codec.streamMapToAir.streamMap[i].channel_mask_msw = (channel_mask & 0xFFFFFFFF00000000) >> 32;
-    }
-
-    /* Configure AFE DSP configuration */
-    mixer_size = sizeof(struct lc3_enc_cfg_t);
-    ret = mixer_ctl_set_array(ctl_enc_data, (void *)&lc3_dsp_cfg,
-                  mixer_size);
-    if (ret != 0) {
-        ALOGE("%s: Failed to set lc3 encoder config", __func__);
-        is_configured = false;
-        goto fail;
-    }
-
-    ret = a2dp_set_bit_format(ENCODER_BIT_FORMAT_PCM_24);
-    if (ret != 0) {
-        ALOGE("%s: Failed to set lc3 bit format", __func__);
-        is_configured = false;
-        goto fail;
-    }
-
-    is_configured = true;
-    a2dp.bt_encoder_format = CODEC_TYPE_LC3;
-
-fail:
-    return is_configured;
-}
-
-bool configure_lc3_dec_format(audio_lc3_codec_config_t *lc3_bt_cfg)
-{
-    struct mixer_ctl *ctl_dec_data = NULL;
-    struct lc3_dec_cfg_t lc3_dsp_cfg;
-    uint64_t channel_mask;
-    bool is_configured = false;
-    int ret = 0;
-    int i;
-
-    if (lc3_bt_cfg == NULL)
-        return false;
-
-    ctl_dec_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_SOURCE_DEC_CONFIG_BLOCK);
-    if (!ctl_dec_data) {
-        ALOGE(" ERROR  a2dp decoder CONFIG data mixer control not identified");
-        return false;
-    }
-
-    memset(&lc3_dsp_cfg, 0x0, sizeof(struct lc3_dec_cfg_t));
-
-    lc3_dsp_cfg.abr_cfg.dec_format = MEDIA_FMT_LC3;
-    lc3_dsp_cfg.abr_cfg.imc_info.direction  = IMC_TRANSMIT;
-    lc3_dsp_cfg.abr_cfg.imc_info.enable = IMC_ENABLE;
-    lc3_dsp_cfg.abr_cfg.imc_info.purpose = IMC_PURPOSE_ID_BT_INFO;
-
-    lc3_dsp_cfg.abr_cfg.imc_info.comm_instance = a2dp.abr_config.imc_instance;
-
-    //for depacketizer both fromAir and toAir streamMap needs to be sent.
-    lc3_dsp_cfg.dec_codec.streamMapToAir.stream_map_size =  lc3_bt_cfg->enc_config.stream_map_size;
-
-    for (i = 0; i < lc3_bt_cfg->enc_config.stream_map_size; i++) {
-         // for depacketizer stream map info
-         channel_mask = convert_channel_map(lc3_bt_cfg->enc_config.streamMapOut[i].audio_location);
-         lc3_dsp_cfg.dec_codec.streamMapToAir.streamMap[i].stream_id = lc3_bt_cfg->enc_config.streamMapOut[i].stream_id;
-         lc3_dsp_cfg.dec_codec.streamMapToAir.streamMap[i].direction = lc3_bt_cfg->enc_config.streamMapOut[i].direction;
-         lc3_dsp_cfg.dec_codec.streamMapToAir.streamMap[i].channel_mask_lsw = channel_mask  & 0x00000000FFFFFFFF;
-         lc3_dsp_cfg.dec_codec.streamMapToAir.streamMap[i].channel_mask_msw = (channel_mask & 0xFFFFFFFF00000000) >> 32;
-    }
-
-    ret = mixer_ctl_set_array(ctl_dec_data, (void *)&lc3_dsp_cfg,
-                              sizeof(struct lc3_dec_cfg_t));
-    if (ret != 0) {
-        ALOGE("%s: failed to set LC3 decoder config", __func__);
-        is_configured = false;
-        goto fail;
-    }
-
-    is_configured = true;
-    a2dp.bt_decoder_format = CODEC_TYPE_LC3;
-
-fail:
-    return is_configured;
-}
-
 bool configure_a2dp_encoder_format()
 {
     void *codec_info = NULL;
@@ -2968,14 +3040,16 @@
     int ret = 0;
 
     ALOGD("a2dp_start_capture start");
-
-    if (!(a2dp.bt_lib_sink_handle && a2dp.audio_sink_start
-       && a2dp.audio_get_dec_config)) {
+    /* checking for sink lib for mobile platform not available then using source lib */
+    if ((!(a2dp.bt_lib_sink_handle && a2dp.audio_sink_start
+       && a2dp.audio_get_dec_config)) && (!(a2dp.bt_lib_source_handle && a2dp.audio_source_start
+       && a2dp.audio_get_enc_config))) {
         ALOGE("a2dp handle is not identified, Ignoring start capture request");
         return -ENOSYS;
     }
 
-    if (!a2dp.a2dp_sink_started && !a2dp.a2dp_sink_total_active_session_requests) {
+    if (a2dp.bt_lib_sink_handle && !a2dp.a2dp_sink_started
+       && !a2dp.a2dp_sink_total_active_session_requests && a2dp.audio_sink_start) {
         ALOGD("calling BT module stream start");
         /* This call indicates BT IPC lib to start capture */
         ret =  a2dp.audio_sink_start();
@@ -3005,11 +3079,29 @@
                ret = -ETIMEDOUT;
            }
         }
+    } else if ((a2dp.bt_lib_source_handle) && (configure_a2dp_sink_decoder_format())) {
+        if (a2dp.audio_source_start) {
+            ret = a2dp.audio_source_start();
+            if (ret == 0) {
+                a2dp.a2dp_sink_started = true;
+                ALOGD("Start capture successful to BT library");
+            } else {
+                ALOGE("BT controller start failed");
+            }
+        }
+    } else {
+        ALOGD(" unable to configure DSP decoder");
+        a2dp.a2dp_sink_started = false;
+        ret = -ETIMEDOUT;
     }
 
     if (a2dp.a2dp_sink_started) {
-        if (a2dp_set_backend_cfg(SINK) == true) {
+        if (a2dp_set_backend_cfg(SINK) == true)
             a2dp.a2dp_sink_total_active_session_requests++;
+        /* Start abr for LC3 decoder*/
+        if (a2dp.bt_decoder_format == CODEC_TYPE_LC3) {
+            a2dp.abr_config.is_abr_enabled = true;
+            start_abr();
         }
     }
 
@@ -3069,6 +3161,9 @@
     struct abr_dec_cfg_t dummy_reset_cfg;
     int ret = 0;
 
+    if (a2dp.bt_decoder_format == CODEC_TYPE_LC3)
+        a2dp.bt_decoder_format = CODEC_TYPE_INVALID;
+
     ctl_dec_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_SOURCE_DEC_CONFIG_BLOCK);
     if (!ctl_dec_data) {
         ALOGE("%s: ERROR A2DP decoder config mixer control not identifed", __func__);
@@ -3162,7 +3257,8 @@
     int ret =0;
 
     ALOGV("a2dp_stop_capture start");
-    if (!(a2dp.bt_lib_sink_handle && a2dp.audio_sink_stop)) {
+    if ((!(a2dp.bt_lib_sink_handle && a2dp.audio_sink_stop))
+        && (!(a2dp.bt_lib_source_handle && a2dp.audio_source_stop))) {
         ALOGE("a2dp handle is not identified, Ignoring stop request");
         return -ENOSYS;
     }
@@ -3170,7 +3266,8 @@
     if (a2dp.a2dp_sink_total_active_session_requests > 0)
         a2dp.a2dp_sink_total_active_session_requests--;
 
-    if ( a2dp.a2dp_sink_started && !a2dp.a2dp_sink_total_active_session_requests) {
+    if (a2dp.bt_lib_sink_handle && a2dp.a2dp_sink_started
+        && !a2dp.a2dp_sink_total_active_session_requests && a2dp.audio_sink_stop) {
         ALOGV("calling BT module stream stop");
         ret = a2dp.audio_sink_stop();
         if (ret < 0)
@@ -3179,7 +3276,17 @@
             ALOGV("stop steam to BT IPC lib successful");
         reset_a2dp_sink_dec_config_params();
         a2dp_reset_backend_cfg(SINK);
+    } else if (a2dp.bt_lib_source_handle) {
+        ret = a2dp.audio_source_stop();
+        if (ret < 0)
+            ALOGE("stop stream to BT IPC lib failed");
+        else
+            ALOGV("stop steam to BT IPC lib successful");
+        a2dp.bt_decoder_format = CODEC_TYPE_INVALID;
+        reset_codec_config();
+        a2dp.a2dp_sink_started = false;
     }
+
     if (!a2dp.a2dp_sink_total_active_session_requests)
        a2dp.a2dp_source_started = false;
     ALOGD("Stop A2DP capture, total active sessions :%d",
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index d874656..c24d28f 100755
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -4817,6 +4817,12 @@
                 a2dp_get_encoder_latency() : 0);
 }
 
+uint32_t audio_extn_a2dp_get_decoder_latency()
+{
+    return (a2dp_get_encoder_latency ?
+                a2dp_get_encoder_latency() : 0);
+}
+
 bool audio_extn_a2dp_sink_is_ready()
 {
     return (a2dp_sink_is_ready ?
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index efba4bb..85502ad 100755
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -325,6 +325,7 @@
 void audio_extn_a2dp_get_enc_sample_rate(int *sample_rate);
 void audio_extn_a2dp_get_dec_sample_rate(int *sample_rate);
 uint32_t audio_extn_a2dp_get_encoder_latency();
+uint32_t audio_extn_a2dp_get_decoder_latency();
 bool audio_extn_a2dp_sink_is_ready();
 bool audio_extn_a2dp_source_is_ready();
 bool audio_extn_a2dp_source_is_suspended();
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 166cd15..278a3e5 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -3078,6 +3078,30 @@
     }
     enable_audio_route(adev, usecase);
 
+    if (uc_id == USECASE_AUDIO_PLAYBACK_VOIP) {
+        struct stream_in *voip_in = get_voice_communication_input(adev);
+        struct audio_usecase *voip_in_usecase = NULL;
+        voip_in_usecase = get_usecase_from_list(adev, USECASE_AUDIO_RECORD_VOIP);
+        if (voip_in != NULL &&
+            voip_in_usecase != NULL &&
+            !(out_snd_device == AUDIO_DEVICE_OUT_SPEAKER ||
+              out_snd_device == AUDIO_DEVICE_OUT_SPEAKER_SAFE) &&
+            (voip_in_usecase->in_snd_device ==
+            platform_get_input_snd_device(adev->platform, voip_in,
+                    &usecase->stream.out->device_list,usecase->type))) {
+            /*
+             * if VOIP TX is enabled before VOIP RX, needs to re-route the TX path
+             * for enabling echo-reference-voip with correct port
+             */
+            ALOGD("%s: VOIP TX is enabled before VOIP RX,needs to re-route the TX path",__func__);
+            disable_audio_route(adev, voip_in_usecase);
+            disable_snd_device(adev, voip_in_usecase->in_snd_device);
+            enable_snd_device(adev, voip_in_usecase->in_snd_device);
+            enable_audio_route(adev, voip_in_usecase);
+        }
+    }
+
+
     audio_extn_qdsp_set_device(usecase);
 
     /* If input stream is already running then effect needs to be
@@ -5466,7 +5490,9 @@
         latency = period_ms + platform_render_latency(out) / 1000;
     } else {
         latency = (out->config.period_count * out->config.period_size * 1000) /
-           (out->config.rate);
+                   (out->config.rate);
+        if (out->usecase == USECASE_AUDIO_PLAYBACK_DEEP_BUFFER)
+            latency += platform_render_latency(out)/1000;
     }
 
     if (!out->standby && is_a2dp_out_device_type(&out->device_list))
@@ -7325,6 +7351,10 @@
             *frames = in->frames_read + avail;
             *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec
                     - platform_capture_latency(in) * 1000LL;
+             //Adjustment accounts for A2dp decoder latency for recording usecase
+             // Note: decoder latency is returned in ms, while platform_capture_latency in ns.
+            if (is_a2dp_in_device_type(&in->device_list))
+                *time -= audio_extn_a2dp_get_decoder_latency() * 1000000LL;
             ret = 0;
         }
     }
@@ -10476,14 +10506,16 @@
             reassign_device_list(&out->device_list, AUDIO_DEVICE_OUT_SPEAKER, "");
             list_for_each(node, &adev->usecase_list) {
                 usecase = node_to_item(node, struct audio_usecase, list);
-                if ((usecase != uc_info) &&
-                        platform_check_backends_match(SND_DEVICE_OUT_SPEAKER,
-                                                      usecase->out_snd_device)) {
+                if ((usecase->type != PCM_CAPTURE) && (usecase != uc_info) &&
+                    !is_a2dp_out_device_type(&usecase->stream.out->device_list) &&
+                    platform_check_backends_match(SND_DEVICE_OUT_SPEAKER,
+                                                  usecase->out_snd_device)) {
                     assign_devices(&out->device_list, &usecase->stream.out->device_list);
                     break;
                 }
             }
-            if (uc_info->out_snd_device == SND_DEVICE_OUT_BT_A2DP) {
+            if (is_a2dp_out_device_type(&devices) &&
+                list_length(&devices) == 1) {
                 out->a2dp_muted = true;
                 if (is_offload_usecase(out->usecase)) {
                     if (out->offload_state == OFFLOAD_STATE_PLAYING)