Merge "Pal: support FTM mode for four ch speaker protection"
diff --git a/configs/crow/mixer_paths_crow_qrd.xml b/configs/crow/mixer_paths_crow_qrd.xml
index afcf9d3..e74e0f1 100755
--- a/configs/crow/mixer_paths_crow_qrd.xml
+++ b/configs/crow/mixer_paths_crow_qrd.xml
@@ -276,11 +276,11 @@
 
     <path name="amic2">
         <ctl name="TX DEC0 MUX" value="SWR_MIC" />
-        <ctl name="TX SMIC MUX0" value="SWR_MIC5" />
+        <ctl name="TX SMIC MUX0" value="SWR_MIC4" />
         <ctl name="DEC0_BCS Switch" value="1" />
         <ctl name="TX_AIF1_CAP Mixer DEC0" value="1" />
         <ctl name="ADC2 MUX" value="INP2" />
-        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH2" />
+        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH1" />
         <ctl name="MBHC ChMap" value="SWRM_TX1_CH3" />
         <ctl name="BCS Channel" value="CH2" />
         <ctl name="ADC2_MIXER Switch" value="1" />
@@ -288,18 +288,18 @@
 
     <path name="amic3">
         <ctl name="TX DEC2 MUX" value="SWR_MIC" />
-        <ctl name="TX SMIC MUX2" value="SWR_MIC6" />
+        <ctl name="TX SMIC MUX2" value="SWR_MIC4" />
         <ctl name="TX_AIF1_CAP Mixer DEC2" value="1" />
-        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH3" />
+        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH1" />
         <ctl name="ADC2 MUX" value="INP3" />
         <ctl name="ADC2_MIXER Switch" value="1" />
     </path>
 
     <path name="amic4">
         <ctl name="TX DEC5 MUX" value="SWR_MIC" />
-        <ctl name="TX SMIC MUX5" value="SWR_MIC8" />
+        <ctl name="TX SMIC MUX5" value="SWR_MIC5" />
         <ctl name="TX_AIF1_CAP Mixer DEC5" value="1" />
-        <ctl name="ADC3 ChMap" value="SWRM_TX3_CH1" />
+        <ctl name="ADC3 ChMap" value="SWRM_TX2_CH2" />
         <ctl name="ADC3_MIXER Switch" value="1" />
     </path>
 
@@ -822,10 +822,10 @@
     </path>
 
     <path name="va-mic-mono">
-        <ctl name="VA_AIF1_CAP Mixer DEC2" value="1" />
-        <ctl name="VA DEC2 MUX" value="SWR_MIC" />
-        <ctl name="VA SMIC MUX2" value="SWR_MIC6" />
-        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH3" />
+        <ctl name="VA_AIF1_CAP Mixer DEC0" value="1" />
+        <ctl name="VA DEC0 MUX" value="SWR_MIC" />
+        <ctl name="VA SMIC MUX0" value="SWR_MIC4" />
+        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH1" />
         <ctl name="ADC2 MUX" value="INP3" />
         <ctl name="ADC2_MIXER Switch" value="1" />
     </path>
@@ -837,14 +837,13 @@
         <ctl name="VA DEC1 MUX" value="SWR_MIC" />
         <ctl name="VA_DEC0 MODE" value="ADC_LOW_PWR" />
         <ctl name="VA_DEC1 MODE" value="ADC_LOW_PWR" />
-        <ctl name="ADC2_BCS Disable" value="1" />
         <ctl name="ADC2 MUX" value="INP3" />
-        <ctl name="VA SMIC MUX0" value="SWR_MIC0" />
-        <ctl name="VA SMIC MUX1" value="SWR_MIC6" />
-        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH3" />
-        <ctl name="ADC1 ChMap" value="SWRM_TX1_CH1" />
+        <ctl name="VA SMIC MUX0" value="SWR_MIC4" />
+        <ctl name="VA SMIC MUX1" value="SWR_MIC5" />
+        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH1" />
+        <ctl name="ADC3 ChMap" value="SWRM_TX2_CH2" />
         <ctl name="ADC2_MIXER Switch" value="1" />
-        <ctl name="ADC1_MIXER Switch" value="1" />
+        <ctl name="ADC3_MIXER Switch" value="1" />
     </path>
 
     <path name="va-mic-tmic">
@@ -857,27 +856,16 @@
         <ctl name="VA_DEC0 MODE" value="ADC_LOW_PWR" />
         <ctl name="VA_DEC1 MODE" value="ADC_LOW_PWR" />
         <ctl name="VA_DEC2 MODE" value="ADC_LOW_PWR" />
-        <ctl name="VA SMIC MUX0" value="SWR_MIC9" />
-        <ctl name="VA SMIC MUX1" value="SWR_MIC4" />
-        <ctl name="VA SMIC MUX2" value="SWR_MIC5" />
-        <ctl name="TX0 MODE" value="ADC_LP" />
-        <ctl name="TX1 MODE" value="ADC_LP" />
-        <ctl name="TX2 MODE" value="ADC_LP" />
-        <ctl name="ADC2_BCS Disable" value="1" />
-        <ctl name="ADC4 MUX" value="INP5" />
+        <ctl name="VA SMIC MUX0" value="SWR_MIC4" />
+        <ctl name="VA SMIC MUX1" value="SWR_MIC5" />
+        <ctl name="VA SMIC MUX2" value="SWR_MIC0" />
         <ctl name="ADC2 MUX" value="INP3" />
-        <ctl name="ADC4 ChMap" value="SWRM_TX3_CH2" />
-        <ctl name="ADC1 ChMap" value="SWRM_TX2_CH1" />
-        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH2" />
-        <ctl name="ADC4_MIXER Switch" value="1" />
+        <ctl name="ADC1 ChMap" value="SWRM_TX1_CH1" />
+        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH1" />
+        <ctl name="ADC3 ChMap" value="SWRM_TX2_CH2" />
         <ctl name="ADC1_MIXER Switch" value="1" />
         <ctl name="ADC2_MIXER Switch" value="1" />
-        <ctl name="ADC1 Volume" value="10" />
-        <ctl name="ADC2 Volume" value="10" />
-        <ctl name="ADC4 Volume" value="10" />
-        <ctl name="VA_AMIC5_MIXER Switch" value="1" />
-        <ctl name="VA_AMIC1_MIXER Switch" value="1" />
-        <ctl name="VA_AMIC3_MIXER Switch" value="1" />
+        <ctl name="ADC3_MIXER Switch" value="1" />
     </path>
 
     <path name="va-mic-qmic">
@@ -940,35 +928,8 @@
     </path>
 
     <path name="va-mic-tmic-lpi">
-        <ctl name="VA_DEC0 Volume" value="96" />
-        <ctl name="VA_DEC1 Volume" value="96" />
-        <ctl name="VA_DEC2 Volume" value="96" />
-        <ctl name="VA_AIF1_CAP Mixer DEC0" value="1" />
-        <ctl name="VA_AIF1_CAP Mixer DEC1" value="1" />
-        <ctl name="VA_AIF1_CAP Mixer DEC2" value="1" />
-        <ctl name="VA DEC0 MUX" value="SWR_MIC" />
-        <ctl name="VA DEC1 MUX" value="SWR_MIC" />
-        <ctl name="VA DEC2 MUX" value="SWR_MIC" />
-        <ctl name="VA_DEC0 MODE" value="ADC_LOW_PWR" />
-        <ctl name="VA_DEC1 MODE" value="ADC_LOW_PWR" />
-        <ctl name="VA_DEC2 MODE" value="ADC_LOW_PWR" />
-        <ctl name="VA SMIC MUX0" value="SWR_MIC4" />
-        <ctl name="VA SMIC MUX1" value="SWR_MIC9" />
-        <ctl name="VA SMIC MUX2" value="SWR_MIC8" />
-        <ctl name="TX0 MODE" value="ADC_LP" />
-        <ctl name="TX1 MODE" value="ADC_LP" />
-        <ctl name="TX2 MODE" value="ADC_LP" />
-        <ctl name="ADC4 MUX" value="INP5" />
-        <ctl name="ADC3 MUX" value="INP4" />
-        <ctl name="ADC1 ChMap" value="SWRM_TX2_CH1" />
-        <ctl name="ADC4 ChMap" value="SWRM_TX3_CH2" />
-        <ctl name="ADC3 ChMap" value="SWRM_TX3_CH1" />
-        <ctl name="ADC1_MIXER Switch" value="1" />
-        <ctl name="ADC4_MIXER Switch" value="1" />
-        <ctl name="ADC3_MIXER Switch" value="1" />
-        <ctl name="VA_AMIC1_MIXER Switch" value="1" />
-        <ctl name="VA_AMIC5_MIXER Switch" value="1" />
-        <ctl name="VA_AMIC4_MIXER Switch" value="1" />
+        <ctl name="LPI Enable" value="1" />
+        <path name="va-mic-tmic" />
     </path>
 
     <path name="va-mic-qmic-lpi">
@@ -1024,10 +985,10 @@
         <ctl name="LPI Enable" value="1" />
         <ctl name="VA_AIF1_CAP Mixer DEC0" value="1" />
         <ctl name="VA DEC0 MUX" value="SWR_MIC" />
-        <ctl name="VA SMIC MUX0" value="SWR_MIC5" />
+        <ctl name="VA SMIC MUX0" value="SWR_MIC4" />
         <ctl name="ADC2 MUX" value="INP2" />
         <ctl name="VA_DEC0 MODE" value="ADC_LOW_PWR" />
-        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH2" />
+        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH1" />
         <ctl name="ADC2_BCS Disable" value="1" />
         <ctl name="ADC2_MIXER Switch" value="1" />
     </path>
@@ -1035,10 +996,10 @@
     <path name="headset-va-mic">
         <ctl name="VA_AIF1_CAP Mixer DEC0" value="1" />
         <ctl name="VA DEC0 MUX" value="SWR_MIC" />
-        <ctl name="VA SMIC MUX0" value="SWR_MIC5" />
+        <ctl name="VA SMIC MUX0" value="SWR_MIC4" />
         <ctl name="ADC2 MUX" value="INP2" />
         <ctl name="VA_DEC0 MODE" value="ADC_LOW_PWR" />
-        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH2" />
+        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH1" />
         <ctl name="ADC2_BCS Disable" value="1" />
         <ctl name="ADC2_MIXER Switch" value="1" />
     </path>
@@ -1051,12 +1012,11 @@
     <path name="handset-dmic-endfire">
         <ctl name="TX DEC1 MUX" value="SWR_MIC" />
         <ctl name="TX DEC2 MUX" value="SWR_MIC" />
-        <ctl name="TX SMIC MUX1" value="SWR_MIC0" />
-        <ctl name="TX SMIC MUX2" value="SWR_MIC6" />
+        <ctl name="TX SMIC MUX2" value="SWR_MIC0" />
+        <ctl name="TX SMIC MUX1" value="SWR_MIC4" />
         <ctl name="ADC2 MUX" value="INP3" />
         <ctl name="ADC1 ChMap" value="SWRM_TX1_CH1" />
-        <ctl name="ADC2_BCS Disable" value="1" />
-        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH3" />
+        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH1" />
         <ctl name="TX_AIF1_CAP Mixer DEC1" value="1" />
         <ctl name="TX_AIF1_CAP Mixer DEC2" value="1" />
         <ctl name="ADC1_MIXER Switch" value="1" />
@@ -1064,18 +1024,17 @@
     </path>
 
     <path name="speaker-dmic-endfire">
-        <ctl name="TX DEC1 MUX" value="SWR_MIC" />
-        <ctl name="TX DEC2 MUX" value="SWR_MIC" />
-        <ctl name="TX SMIC MUX1" value="SWR_MIC0" />
-        <ctl name="TX SMIC MUX2" value="SWR_MIC6" />
-        <ctl name="ADC2 MUX" value="INP3" />
-        <ctl name="ADC1 ChMap" value="SWRM_TX1_CH1" />
-        <ctl name="ADC2_BCS Disable" value="1" />
-        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH3" />
         <ctl name="TX_AIF1_CAP Mixer DEC1" value="1" />
         <ctl name="TX_AIF1_CAP Mixer DEC2" value="1" />
-        <ctl name="ADC1_MIXER Switch" value="1" />
+        <ctl name="TX DEC1 MUX" value="SWR_MIC" />
+        <ctl name="TX DEC2 MUX" value="SWR_MIC" />
+        <ctl name="TX SMIC MUX1" value="SWR_MIC5" />
+        <ctl name="TX SMIC MUX2" value="SWR_MIC4" />
+        <ctl name="ADC2 MUX" value="INP3" />
+        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH1" />
+        <ctl name="ADC3 ChMap" value="SWRM_TX2_CH2" />
         <ctl name="ADC2_MIXER Switch" value="1" />
+        <ctl name="ADC3_MIXER Switch" value="1" />
     </path>
 
     <path name="dmic-endfire">
@@ -1174,57 +1133,41 @@
 
     <!-- Tri MIC devices -->
     <path name="three-mic">
-        <ctl name="TX_AIF1_CAP Mixer DEC1" value="1" />
-        <ctl name="TX_AIF1_CAP Mixer DEC2" value="1" />
-        <ctl name="TX_AIF1_CAP Mixer DEC3" value="1" />
         <ctl name="TX DEC1 MUX" value="SWR_MIC" />
         <ctl name="TX DEC2 MUX" value="SWR_MIC" />
-        <ctl name="TX DEC3 MUX" value="SWR_MIC" />
-        <ctl name="TX SMIC MUX1" value="SWR_MIC9" />
+        <ctl name="TX DEC5 MUX" value="SWR_MIC" />
+        <ctl name="TX SMIC MUX1" value="SWR_MIC0" />
         <ctl name="TX SMIC MUX2" value="SWR_MIC4" />
-        <ctl name="TX SMIC MUX3" value="SWR_MIC5" />
-        <ctl name="ADC4 MUX" value="INP5" />
+        <ctl name="TX SMIC MUX5" value="SWR_MIC5" />
         <ctl name="ADC2 MUX" value="INP3" />
-        <ctl name="HDR34 MUX" value="NO_HDR34" />
-        <ctl name="TX2 MODE" value="ADC_LP" />
-        <ctl name="TX0 MODE" value="ADC_LP" />
-        <ctl name="TX3 MODE" value="ADC_LP" />
-        <ctl name="ADC4 ChMap" value="SWRM_TX3_CH2" />
-        <ctl name="ADC1 ChMap" value="SWRM_TX2_CH1" />
-        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH2" />
-        <ctl name="ADC4_MIXER Switch" value="1" />
+        <ctl name="ADC1 ChMap" value="SWRM_TX1_CH1" />
+        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH1" />
+        <ctl name="ADC3 ChMap" value="SWRM_TX2_CH2" />
+        <ctl name="TX_AIF1_CAP Mixer DEC1" value="1" />
+        <ctl name="TX_AIF1_CAP Mixer DEC2" value="1" />
+        <ctl name="TX_AIF1_CAP Mixer DEC5" value="1" />
         <ctl name="ADC1_MIXER Switch" value="1" />
         <ctl name="ADC2_MIXER Switch" value="1" />
-        <ctl name="AMIC5_MIXER Switch" value="1" />
-        <ctl name="AMIC1_MIXER Switch" value="1" />
-        <ctl name="AMIC3_MIXER Switch" value="1" />
+        <ctl name="ADC3_MIXER Switch" value="1" />
     </path>
 
     <path name="speaker-tmic">
-        <ctl name="TX_AIF1_CAP Mixer DEC1" value="1" />
-        <ctl name="TX_AIF1_CAP Mixer DEC2" value="1" />
-        <ctl name="TX_AIF1_CAP Mixer DEC3" value="1" />
         <ctl name="TX DEC1 MUX" value="SWR_MIC" />
         <ctl name="TX DEC2 MUX" value="SWR_MIC" />
-        <ctl name="TX DEC3 MUX" value="SWR_MIC" />
-        <ctl name="TX SMIC MUX1" value="SWR_MIC9" />
+        <ctl name="TX DEC5 MUX" value="SWR_MIC" />
+        <ctl name="TX SMIC MUX1" value="SWR_MIC0" />
         <ctl name="TX SMIC MUX2" value="SWR_MIC4" />
-        <ctl name="TX SMIC MUX3" value="SWR_MIC5" />
-        <ctl name="ADC4 MUX" value="INP5" />
+        <ctl name="TX SMIC MUX5" value="SWR_MIC5" />
         <ctl name="ADC2 MUX" value="INP3" />
-        <ctl name="HDR34 MUX" value="NO_HDR34" />
-        <ctl name="TX2 MODE" value="ADC_LP" />
-        <ctl name="TX0 MODE" value="ADC_LP" />
-        <ctl name="TX3 MODE" value="ADC_LP" />
-        <ctl name="ADC4 ChMap" value="SWRM_TX3_CH2" />
-        <ctl name="ADC1 ChMap" value="SWRM_TX2_CH1" />
-        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH2" />
-        <ctl name="ADC4_MIXER Switch" value="1" />
+        <ctl name="ADC1 ChMap" value="SWRM_TX1_CH1" />
+        <ctl name="ADC2 ChMap" value="SWRM_TX2_CH1" />
+        <ctl name="ADC3 ChMap" value="SWRM_TX2_CH2" />
+        <ctl name="TX_AIF1_CAP Mixer DEC1" value="1" />
+        <ctl name="TX_AIF1_CAP Mixer DEC2" value="1" />
+        <ctl name="TX_AIF1_CAP Mixer DEC5" value="1" />
         <ctl name="ADC1_MIXER Switch" value="1" />
         <ctl name="ADC2_MIXER Switch" value="1" />
-        <ctl name="AMIC5_MIXER Switch" value="1" />
-        <ctl name="AMIC1_MIXER Switch" value="1" />
-        <ctl name="AMIC3_MIXER Switch" value="1" />
+        <ctl name="ADC3_MIXER Switch" value="1" />
     </path>
 
     <path name="voice-speaker-tmic">
diff --git a/context_manager/inc/ContextManager.h b/context_manager/inc/ContextManager.h
index a9d4d04..677e7d2 100644
--- a/context_manager/inc/ContextManager.h
+++ b/context_manager/inc/ContextManager.h
@@ -141,6 +141,9 @@
     uint32_t see_id;
     std::map<uint32_t, Usecase*> usecases;
 
+protected:
+    static std::mutex see_client_mutex;
+
 public:
     see_client(uint32_t id);
     ~see_client();
@@ -148,6 +151,8 @@
     Usecase* Usecase_Get(uint32_t usecase_id);
     int32_t Usecase_Remove(uint32_t usecase_id);
     int32_t Usecase_Add(uint32_t usecase_id, Usecase* uc);
+    void lock_see_client() { see_client_mutex.lock(); };
+    void unlock_see_client() { see_client_mutex.unlock(); };
     void CloseAllUsecases();
 };
 
diff --git a/context_manager/src/ContextManager.cpp b/context_manager/src/ContextManager.cpp
index 97a5948..5b2d9a1 100644
--- a/context_manager/src/ContextManager.cpp
+++ b/context_manager/src/ContextManager.cpp
@@ -71,6 +71,8 @@
 #define ACKDATA_DEFAULT_SIZE 1024
 #define PAL_ALIGN_8BYTE(x) (((x) + 7) & (~7))
 
+std::mutex see_client::see_client_mutex;
+
 int32_t ContextManager::process_register_request(uint32_t see_id, uint32_t usecase_id, uint32_t size,
     void *payload)
 {
@@ -87,6 +89,8 @@
         goto exit;
     }
 
+    seeclient->lock_see_client();
+
     uc = seeclient->Usecase_Get(usecase_id);
     if (uc == NULL) {
         PAL_VERBOSE(LOG_TAG, "Creating new usecase:0x%x for see_id:%d", usecase_id, see_id);
@@ -154,6 +158,7 @@
     if (rc) {
         send_asps_basic_response(rc, EVENT_ID_ASPS_SENSOR_REGISTER_REQUEST, see_id);
     }
+    seeclient->unlock_see_client();
     PAL_VERBOSE(LOG_TAG, "Exit rc:%d", rc);
     return rc;
 }
@@ -246,6 +251,8 @@
         goto exit;
     }
 
+    seeclient->lock_see_client();
+
     uc = seeclient->Usecase_Get(usecase_id);
     if (uc == NULL) {
         rc = -EINVAL;
@@ -266,6 +273,7 @@
     }
 
 exit:
+    seeclient->unlock_see_client();
     PAL_VERBOSE(LOG_TAG, "Exit rc:%d", rc);
     return rc;
 }
@@ -915,6 +923,8 @@
 
     PAL_VERBOSE(LOG_TAG, "Enter:");
 
+    see_client_mutex.lock();
+
     for (auto it_uc = this->usecases.begin(); it_uc != this->usecases.cend();) {
         uc = it_uc->second;
         PAL_VERBOSE(LOG_TAG, "Calling StopAndClose on usecase_id:0x%x", uc->GetUseCaseID());
@@ -923,6 +933,8 @@
         delete uc;
     }
 
+    see_client_mutex.unlock();
+
     PAL_VERBOSE(LOG_TAG, "Exit:");
 }
 
diff --git a/device/inc/USBAudio.h b/device/inc/USBAudio.h
index 4928838..c6d80cd 100644
--- a/device/inc/USBAudio.h
+++ b/device/inc/USBAudio.h
@@ -146,9 +146,9 @@
     int getMaxBitWidth(bool is_playback);
     int getMaxChannels(bool is_playback);
     unsigned int getFormatByBitWidth(int bitwidth);
-    unsigned int readSupportedFormat(bool is_playback, uint32_t *format);
-    unsigned int readSupportedSampleRate(bool is_playback, uint32_t *sample_rate);
-    unsigned int readSupportedChannelMask(bool is_playback, uint32_t *channel);
+    void readSupportedFormat(bool is_playback, uint32_t *format);
+    void readSupportedSampleRate(bool is_playback, uint32_t *sample_rate);
+    void readSupportedChannelMask(bool is_playback, uint32_t *channel);
     int readSupportedConfig(dynamic_media_config_t *config, bool is_playback, int usb_card);
     int readBestConfig(struct pal_media_config *config,
                                     struct pal_stream_attributes *sattr,
diff --git a/device/src/Bluetooth.cpp b/device/src/Bluetooth.cpp
index a448e47..1d2a2fa 100644
--- a/device/src/Bluetooth.cpp
+++ b/device/src/Bluetooth.cpp
@@ -1738,7 +1738,10 @@
 
     if (a2dpState != A2DP_STATE_STARTED && !totalActiveSessionRequests) {
         codecFormat = CODEC_TYPE_INVALID;
-        isAbrEnabled = false;
+
+        if (!isConfigured)
+            isAbrEnabled = false;
+
         PAL_DBG(LOG_TAG, "calling BT module stream start");
         /* This call indicates BT IPC lib to start playback */
         if (audio_source_start_api) {
diff --git a/device/src/Device.cpp b/device/src/Device.cpp
index 5a75d7c..076a8a5 100644
--- a/device/src/Device.cpp
+++ b/device/src/Device.cpp
@@ -493,6 +493,8 @@
            disableDevice(audioRoute, mSndDeviceName);
            mCurrentPriority = MIN_USECASE_PRIORITY;
            deviceStartStopCount = 0;
+           if(rm->num_proxy_channels != 0)
+               rm->num_proxy_channels = 0;
        }
     }
     PAL_INFO(LOG_TAG, "Exit. deviceCount %d for device id %d (%s), exit status %d", deviceCount,
diff --git a/device/src/USBAudio.cpp b/device/src/USBAudio.cpp
index 5c40793..718ceb6 100644
--- a/device/src/USBAudio.cpp
+++ b/device/src/USBAudio.cpp
@@ -686,7 +686,7 @@
     return default_format;
 }
 
-unsigned int USBCardConfig::readSupportedFormat(bool is_playback, uint32_t *format) {
+void USBCardConfig::readSupportedFormat(bool is_playback, uint32_t *format) {
     int i = 0;
     unsigned int bw;
     unsigned int bitWidth[MAX_SUPPORTED_FORMATS + 1];
@@ -729,11 +729,9 @@
     /* convert bw to format */
     for (int j = 0; j < i; j++)
         format[j] = getFormatByBitWidth(bitWidth[j]);
-
-    return 0;
 }
 
-unsigned int USBCardConfig::readSupportedSampleRate(bool is_playback, uint32_t *sample_rate) {
+void USBCardConfig::readSupportedSampleRate(bool is_playback, uint32_t *sample_rate) {
     usb_usecase_type_t type = is_playback ? USB_PLAYBACK : USB_CAPTURE;
 
     typename std::vector<std::shared_ptr<USBDeviceConfig>>::iterator iter;
@@ -760,50 +758,34 @@
 
     for (int j = 0; j < i; j++)
         PAL_DBG(LOG_TAG, "%s %d", is_playback ? "P" : "C", sample_rate[j]);
-
-    return 0;
 }
 
-unsigned int USBCardConfig::readSupportedChannelMask(bool is_playback, uint32_t *channel) {
+void USBCardConfig::readSupportedChannelMask(bool is_playback, uint32_t *channel) {
 
     int channels = getMaxChannels(is_playback);
     int channel_count;
-    uint32_t num_masks = 0;
 
     if (channels > MAX_HIFI_CHANNEL_COUNT)
         channels = MAX_HIFI_CHANNEL_COUNT;
-
+     /* need to calculate the mask from channel count either because this is
+      * the query case or the specified mask isn't valid for this device,
+      * or is more than the FW can handle
+      */
     if (is_playback) {
-        channel[num_masks++] = channels <= 2
+        channel[0] = channels <= 2
                      /* position mask for mono and stereo*/
                      ? audio_channel_out_mask_from_count(channels)
                      /* otherwise indexed */
                      : audio_channel_mask_for_index_assignment_from_count(channels);
-        // TODO: needs to figure out the accurate match of channel mask
     } else {
-        // For capture we report all supported channel masks from 1 channel up.
-        channel_count = MIN_CHANNEL_COUNT;
-        // audio_channel_in_mask_from_count() does the right conversion to either positional or
-        // indexed mask
-        for ( ; channel_count <= channels && num_masks < MAX_SUPPORTED_CHANNEL_MASKS; channel_count++) {
-            audio_channel_mask_t mask = AUDIO_CHANNEL_NONE;
-            if (channel_count <= 2) {
-                mask = audio_channel_in_mask_from_count(channel_count);
-                channel[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_SUPPORTED_CHANNEL_MASKS) { // ensure index mask added.
-                channel[num_masks++] = index_mask;
-            }
-        }
+        channel[0] = channels <= 2
+             /* position mask for mono & stereo */
+             ? audio_channel_in_mask_from_count(channels)
+             /* otherwise indexed */
+             : audio_channel_mask_for_index_assignment_from_count(channels);
     }
-
-    for (size_t i = 0; i < num_masks; ++i) {
-        PAL_DBG(LOG_TAG, "%s supported ch %d channel[%zu] %08x num_masks %d",
-              is_playback ? "P" : "C", channels, i, channel[i], num_masks);
-    }
-    return num_masks;
+    PAL_DBG(LOG_TAG, "%s supported ch %d, channel mask: %08x ",
+            is_playback ? "P" : "C", channels, channel[0]);
 }
 
 bool USBCardConfig::readDefaultJackStatus(bool is_playback) {
diff --git a/resource_manager/src/ResourceManager.cpp b/resource_manager/src/ResourceManager.cpp
index d037720..eac4624 100644
--- a/resource_manager/src/ResourceManager.cpp
+++ b/resource_manager/src/ResourceManager.cpp
@@ -2685,8 +2685,8 @@
             {
                 PAL_INFO(LOG_TAG, "wfd TX is not in progress");
                 if (rm->num_proxy_channels) {
+                    PAL_INFO(LOG_TAG, "proxy device channel number: %d", rm->num_proxy_channels);
                     deviceattr->config.ch_info.channels = rm->num_proxy_channels;
-                    rm->num_proxy_channels = 0;
                 }
             }
             PAL_INFO(LOG_TAG, "PAL_DEVICE_OUT_PROXY sample rate %d bitwidth %d ch:%d",
@@ -5001,7 +5001,7 @@
                 in_type != PAL_STREAM_CONTEXT_PROXY  &&
                 in_type != PAL_STREAM_VOICE_UI)) {
         *tx_conc = true;
-        if (!audio_capture_conc_enable) {
+        if (!audio_capture_conc_enable && in_type != PAL_STREAM_PROXY) {
             PAL_DBG(LOG_TAG, "pause on audio capture concurrency");
             *conc_en = false;
         }
@@ -9205,7 +9205,8 @@
                          (sAttr.type == PAL_STREAM_PCM_OFFLOAD) ||
                          (sAttr.type == PAL_STREAM_SPATIAL_AUDIO) ||
                          (sAttr.type == PAL_STREAM_DEEP_BUFFER) ||
-                         (sAttr.type == PAL_STREAM_COMPRESSED))) {
+                         (sAttr.type == PAL_STREAM_COMPRESSED) ||
+                         (sAttr.type == PAL_STREAM_GENERIC))) {
                         str->getAssociatedDevices(associatedDevices);
                         for (int i = 0; i < associatedDevices.size(); i++) {
                             if (!isDeviceActive_l(associatedDevices[i], str) ||
@@ -9256,6 +9257,22 @@
 
                 SortAndUnique(rxDevices);
                 SortAndUnique(txDevices);
+
+                /*
+                 * If there a switch in SCO configurations and at the time of BT_SCO=on,
+                 * there are streams active with old SCO configs as well as on another
+                 * device. In this case, we need to disconnect streams over SCO first and
+                 * move them to new SCO configs, before we move streams on other devices
+                 * to SCO. This is ensured by moving SCO to the beginning of the disconnect
+                 * device list.
+                 */
+                {
+                    dAttr.id = PAL_DEVICE_OUT_BLUETOOTH_SCO;
+                    dev = Device::getInstance(&dAttr, rm);
+                    auto it = std::find(rxDevices.begin(),rxDevices.end(),dev);
+                    if ((it != rxDevices.end()) && (it != rxDevices.begin()))
+                        std::iter_swap(it, rxDevices.begin());
+                }
                 mActiveStreamMutex.unlock();
 
                 for (auto& device : rxDevices) {
@@ -9452,7 +9469,8 @@
                             (streamType == PAL_STREAM_PCM_OFFLOAD) ||
                             (streamType == PAL_STREAM_DEEP_BUFFER) ||
                             (streamType == PAL_STREAM_SPATIAL_AUDIO) ||
-                            (streamType == PAL_STREAM_COMPRESSED)) {
+                            (streamType == PAL_STREAM_COMPRESSED) ||
+                            (streamType == PAL_STREAM_GENERIC)) {
                             (*sIter)->suspendedDevIds.clear();
                             (*sIter)->suspendedDevIds.push_back(a2dp_dattr.id);
                             PAL_DBG(LOG_TAG, "a2dp resumed, mark sco streams as to route them later");
diff --git a/session/src/SessionAlsaCompress.cpp b/session/src/SessionAlsaCompress.cpp
index 25648a9..5778888 100644
--- a/session/src/SessionAlsaCompress.cpp
+++ b/session/src/SessionAlsaCompress.cpp
@@ -1707,6 +1707,9 @@
 
     switch (sAttr.direction) {
         case PAL_AUDIO_OUTPUT:
+            if (compress && playback_started) {
+                status = compress_stop(compress);
+            }
             // Deregister for callback for Soft Pause
             if (isPauseRegistrationDone) {
                 payload_size = sizeof(struct agm_event_reg_cfg);
@@ -1735,10 +1738,6 @@
                     status = 0;
                 }
             }
-
-            if (compress && playback_started) {
-                status = compress_stop(compress);
-            }
             break;
         case PAL_AUDIO_INPUT:
             if (compress) {
diff --git a/session/src/SessionAlsaPcm.cpp b/session/src/SessionAlsaPcm.cpp
index f3516e9..2adcfcc 100644
--- a/session/src/SessionAlsaPcm.cpp
+++ b/session/src/SessionAlsaPcm.cpp
@@ -2741,6 +2741,8 @@
             }
 
 skip_ultrasound_gain:
+            if (tagConfig)
+                free(tagConfig);
             if (status)
                 PAL_ERR(LOG_TAG, "Failed to set Ultrasound Gain %d", status);
             return 0;
diff --git a/stream/src/Stream.cpp b/stream/src/Stream.cpp
index 1f8f2c0..2637c53 100644
--- a/stream/src/Stream.cpp
+++ b/stream/src/Stream.cpp
@@ -904,8 +904,8 @@
                     rm->unlockGraph();
                     goto exit;
                 }
-                rm->unlockGraph();
                 iter = mDevices.erase(iter);
+                rm->unlockGraph();
             }
         } else {
             PAL_ERR(LOG_TAG, "BT SCO output device is not ready");
@@ -972,8 +972,8 @@
                     rm->unlockGraph();
                     goto exit;
                 }
-                rm->unlockGraph();
                 iter = mDevices.erase(iter);
+                rm->unlockGraph();
             }
         } else {
             // For non-combo device, mute the stream and route to speaker or handset
@@ -984,8 +984,8 @@
             suspendedDevIds.clear();
             suspendedDevIds.push_back(dattr.id);
 
+            rm->lockGraph();
             for (int i = 0; i < mDevices.size(); i++) {
-                rm->lockGraph();
                 status = session->disconnectSessionDevice(this, mStreamAttr->type, mDevices[i]);
                 if (0 != status) {
                     PAL_ERR(LOG_TAG, "disconnectSessionDevice failed:%d", status);
@@ -1009,9 +1009,9 @@
                     rm->unlockGraph();
                     goto exit;
                 }
-                rm->unlockGraph();
             }
             mDevices.clear();
+            rm->unlockGraph();
             clearOutPalDevices(this);
 
             /* Check whether there's active stream associated with handset or speaker
@@ -1141,14 +1141,15 @@
                     goto exit;
                 }
             }
-            rm->unlockGraph();
 
             status = mDevices[i]->close();
             if (0 != status) {
                 PAL_ERR(LOG_TAG, "device close failed with status %d", status);
+                rm->unlockGraph();
                 goto exit;
             }
             mDevices.erase(mDevices.begin() + i);
+            rm->unlockGraph();
             break;
         }
     }
diff --git a/stream/src/StreamCommon.cpp b/stream/src/StreamCommon.cpp
index 3c8c7e1..d9cf880 100644
--- a/stream/src/StreamCommon.cpp
+++ b/stream/src/StreamCommon.cpp
@@ -274,7 +274,6 @@
 
     rm->lockGraph();
     status = session->close(this);
-    rm->unlockGraph();
     if (0 != status) {
         PAL_ERR(LOG_TAG, "Error:session close failed with status %d", status);
     }
@@ -287,6 +286,7 @@
     }
     PAL_VERBOSE(LOG_TAG, "closed the devices successfully");
     currentState = STREAM_IDLE;
+    rm->unlockGraph();
     rm->checkAndSetDutyCycleParam();
 
     mStreamMutex.unlock();
diff --git a/stream/src/StreamCompress.cpp b/stream/src/StreamCompress.cpp
index 9fe128e..72a7ce1 100644
--- a/stream/src/StreamCompress.cpp
+++ b/stream/src/StreamCompress.cpp
@@ -238,7 +238,6 @@
     }
     rm->lockGraph();
     status = session->close(this);
-    rm->unlockGraph();
     if (0 != status) {
         PAL_ERR(LOG_TAG,"session close failed with status %d", status);
     }
@@ -254,6 +253,7 @@
     }
     PAL_VERBOSE(LOG_TAG,"closed the devices successfully");
     currentState = STREAM_IDLE;
+    rm->unlockGraph();
     rm->checkAndSetDutyCycleParam();
     mStreamMutex.unlock();
 
diff --git a/stream/src/StreamPCM.cpp b/stream/src/StreamPCM.cpp
index 5f2c5a3..4bb80b2 100644
--- a/stream/src/StreamPCM.cpp
+++ b/stream/src/StreamPCM.cpp
@@ -312,7 +312,6 @@
 
     rm->lockGraph();
     status = session->close(this);
-    rm->unlockGraph();
     if (0 != status) {
         PAL_ERR(LOG_TAG, "session close failed with status %d", status);
     }
@@ -325,6 +324,7 @@
     }
     PAL_VERBOSE(LOG_TAG, "closed the devices successfully");
     currentState = STREAM_IDLE;
+    rm->unlockGraph();
     rm->checkAndSetDutyCycleParam();
     mStreamMutex.unlock();
 
diff --git a/stream/src/StreamSoundTrigger.cpp b/stream/src/StreamSoundTrigger.cpp
index 2014c1d..fc32972 100644
--- a/stream/src/StreamSoundTrigger.cpp
+++ b/stream/src/StreamSoundTrigger.cpp
@@ -389,6 +389,21 @@
     }
 
     std::lock_guard<std::mutex> lck(mStreamMutex);
+    if (cur_state_ == st_buffering_) {
+        if (!this->force_nlpi_vote) {
+            rm->voteSleepMonitor(this, true, true);
+            this->force_nlpi_vote = true;
+
+            offset = vui_intf_->GetReadOffset();
+            if (offset) {
+                reader_->advanceReadOffset(offset);
+                vui_intf_->SetReadOffset(0);
+            }
+        }
+    } else {
+        PAL_ERR(LOG_TAG, "Invalid Stream Current State %d", GetCurrentStateId());
+        return size;
+    }
     if (vui_ptfm_info_->GetEnableDebugDumps() && !lab_fd_) {
         ST_DBG_FILE_OPEN_WR(lab_fd_, ST_DEBUG_DUMP_LOCATION,
             "lab_reading", "bin", lab_cnt);
@@ -396,16 +411,6 @@
             lab_cnt);
         lab_cnt++;
     }
-    if (cur_state_ == st_buffering_ && !this->force_nlpi_vote) {
-        rm->voteSleepMonitor(this, true, true);
-        this->force_nlpi_vote = true;
-
-        offset = vui_intf_->GetReadOffset();
-        if (offset) {
-            reader_->advanceReadOffset(offset);
-            vui_intf_->SetReadOffset(0);
-        }
-    }
 
     std::shared_ptr<StEventConfig> ev_cfg(
         new StReadBufferEventConfig((void *)buf));
@@ -1139,6 +1144,11 @@
         engine = HandleEngineLoad((uint8_t *)iter.second.first,
                                   iter.second.second,
                                   iter.first, model_type_);
+        if (!engine) {
+            PAL_ERR(LOG_TAG, "Failed to create engine");
+            status = -EINVAL;
+            goto error_exit;
+        }
         std::shared_ptr<EngineCfg> engine_cfg(new EngineCfg(
             engine_id, engine, (void *)iter.second.first, iter.second.second));
 
@@ -1173,6 +1183,7 @@
     }
     engines_.clear();
     gsl_engine_.reset();
+    rm->resetStreamInstanceID(this, mInstanceID);
     if (sm_config_) {
         free(sm_config_);
         sm_config_ = nullptr;