Merge "pal : add check in ipc_pal_stream_set_volume to avoid OOB"
diff --git a/Android.mk b/Android.mk
index 232daab..2253871 100644
--- a/Android.mk
+++ b/Android.mk
@@ -33,8 +33,14 @@
 endif
 LOCAL_CPPFLAGS      += -fexceptions -frtti
 
+# Define A2DP_SINK_SUPPORTED for targets other than anorak, and
+# for anorak target that uses Android U
 ifneq ($(TARGET_BOARD_PLATFORM), anorak)
 LOCAL_CFLAGS        += -DA2DP_SINK_SUPPORTED
+else
+ifneq ($(filter 14 U, $(PLATFORM_VERSION)),)
+LOCAL_CFLAGS        += -DA2DP_SINK_SUPPORTED
+endif
 endif
 
 LOCAL_C_INCLUDES := \
diff --git a/Pal.cpp b/Pal.cpp
index 71d94ed..46f8682 100644
--- a/Pal.cpp
+++ b/Pal.cpp
@@ -256,14 +256,13 @@
         return status;
     }
 
-    rm->lockActiveStream();
+    rm->lockValidStreamMutex();
     if (!rm->isActiveStream(stream_handle)) {
         status = -EINVAL;
-        rm->unlockActiveStream();
+        rm->unlockValidStreamMutex();
         return status;
     }
-
-    rm->unlockActiveStream();
+    rm->unlockValidStreamMutex();
 
     s = reinterpret_cast<Stream *>(stream_handle);
     s->setCachedState(STREAM_IDLE);
@@ -290,6 +289,7 @@
 int32_t pal_stream_start(pal_stream_handle_t *stream_handle)
 {
     Stream *s = NULL;
+    struct pal_stream_attributes sAttr;
     std::shared_ptr<ResourceManager> rm = NULL;
     int status;
     if (!stream_handle) {
@@ -313,9 +313,9 @@
         goto exit;
     }
 
-    rm->lockActiveStream();
+    rm->lockValidStreamMutex();
     if (!rm->isActiveStream(stream_handle)) {
-        rm->unlockActiveStream();
+        rm->unlockValidStreamMutex();
         status = -EINVAL;
         goto exit;
     }
@@ -323,16 +323,21 @@
     s = reinterpret_cast<Stream *>(stream_handle);
     status = rm->increaseStreamUserCounter(s);
     if (0 != status) {
-        rm->unlockActiveStream();
+        rm->unlockValidStreamMutex();
         PAL_ERR(LOG_TAG, "failed to increase stream user count");
         goto exit;
     }
-    rm->unlockActiveStream();
+    rm->unlockValidStreamMutex();
+
+    s->getStreamAttributes(&sAttr);
+    if (sAttr.type == PAL_STREAM_VOICE_UI)
+        rm->handleDeferredSwitch();
+
     status = s->start();
 
-    rm->lockActiveStream();
+    rm->lockValidStreamMutex();
     rm->decreaseStreamUserCounter(s);
-    rm->unlockActiveStream();
+    rm->unlockValidStreamMutex();
 
     if (0 != status) {
         PAL_ERR(LOG_TAG, "stream start failed. status %d", status);
@@ -363,9 +368,9 @@
         goto exit;
     }
 
-    rm->lockActiveStream();
+    rm->lockValidStreamMutex();
     if (!rm->isActiveStream(stream_handle)) {
-        rm->unlockActiveStream();
+        rm->unlockValidStreamMutex();
         status = -EINVAL;
         goto exit;
     }
@@ -373,17 +378,17 @@
     s = reinterpret_cast<Stream *>(stream_handle);
     status = rm->increaseStreamUserCounter(s);
     if (0 != status) {
-        rm->unlockActiveStream();
+        rm->unlockValidStreamMutex();
         PAL_ERR(LOG_TAG, "failed to increase stream user count");
         goto exit;
     }
-    rm->unlockActiveStream();
+    rm->unlockValidStreamMutex();
     s->setCachedState(STREAM_STOPPED);
     status = s->stop();
 
-    rm->lockActiveStream();
+    rm->lockValidStreamMutex();
     rm->decreaseStreamUserCounter(s);
-    rm->unlockActiveStream();
+    rm->unlockValidStreamMutex();
 
     if (0 != status) {
         PAL_ERR(LOG_TAG, "stream stop failed. status : %d", status);
@@ -399,18 +404,41 @@
 {
     Stream *s = NULL;
     int status;
-    if (!stream_handle || !buf) {
+    std::shared_ptr<ResourceManager> rm = NULL;
+
+    rm = ResourceManager::getInstance();
+    if (!rm) {
+        PAL_ERR(LOG_TAG, "Invalid resource manager");
+        status = -EINVAL;
+        return status;
+    }
+    rm->lockValidStreamMutex();
+    if (!stream_handle || !rm->isActiveStream(stream_handle) || !buf) {
+        rm->unlockValidStreamMutex();
         status = -EINVAL;
         PAL_ERR(LOG_TAG, "Invalid input parameters status %d", status);
         return status;
     }
+
     PAL_VERBOSE(LOG_TAG, "Enter. Stream handle :%pK", stream_handle);
     s =  reinterpret_cast<Stream *>(stream_handle);
+    status = rm->increaseStreamUserCounter(s);
+    if (0 != status) {
+        rm->unlockValidStreamMutex();
+        PAL_ERR(LOG_TAG, "failed to increase stream user count");
+        return status;
+    }
+    rm->unlockValidStreamMutex();
+
     status = s->write(buf);
     if (status < 0) {
         PAL_ERR(LOG_TAG, "stream write failed status %d", status);
-        return status;
     }
+
+    rm->lockValidStreamMutex();
+    rm->decreaseStreamUserCounter(s);
+    rm->unlockValidStreamMutex();
+
     PAL_VERBOSE(LOG_TAG, "Exit. status %d", status);
     return status;
 }
@@ -419,18 +447,40 @@
 {
     Stream *s = NULL;
     int status;
-    if (!stream_handle || !buf) {
+    std::shared_ptr<ResourceManager> rm = NULL;
+
+    rm = ResourceManager::getInstance();
+    if (!rm) {
+        PAL_ERR(LOG_TAG, "Invalid resource manager");
+        status = -EINVAL;
+        return status;
+    }
+    rm->lockValidStreamMutex();
+    if (!stream_handle || !rm->isActiveStream(stream_handle) || !buf) {
+        rm->unlockValidStreamMutex();
         status = -EINVAL;
         PAL_ERR(LOG_TAG, "Invalid input parameters status %d", status);
         return status;
     }
+
     PAL_VERBOSE(LOG_TAG, "Enter. Stream handle :%pK", stream_handle);
     s =  reinterpret_cast<Stream *>(stream_handle);
+    status = rm->increaseStreamUserCounter(s);
+    if (0 != status) {
+        rm->unlockValidStreamMutex();
+        PAL_ERR(LOG_TAG, "failed to increase stream user count");
+        return status;
+    }
+    rm->unlockValidStreamMutex();
+
     status = s->read(buf);
     if (status < 0) {
         PAL_ERR(LOG_TAG, "stream read failed status %d", status);
-        return status;
     }
+
+    rm->lockValidStreamMutex();
+    rm->decreaseStreamUserCounter(s);
+    rm->unlockValidStreamMutex();
     PAL_VERBOSE(LOG_TAG, "Exit. status %d", status);
     return status;
 }
@@ -440,18 +490,41 @@
 {
     Stream *s = NULL;
     int status;
-    if (!stream_handle) {
+    std::shared_ptr<ResourceManager> rm = NULL;
+
+    rm = ResourceManager::getInstance();
+    if (!rm) {
+        status = -EINVAL;
+        PAL_ERR(LOG_TAG, "Invalid resource manager");
+        return status;
+    }
+
+    rm->lockValidStreamMutex();
+    if (!stream_handle || !rm->isActiveStream(stream_handle)) {
+        rm->unlockValidStreamMutex();
         status = -EINVAL;
         PAL_ERR(LOG_TAG,  "Invalid input parameters status %d", status);
         return status;
     }
+
     PAL_DBG(LOG_TAG, "Enter. Stream handle :%pK", stream_handle);
     s =  reinterpret_cast<Stream *>(stream_handle);
+    status = rm->increaseStreamUserCounter(s);
+    if (0 != status) {
+        rm->unlockValidStreamMutex();
+        PAL_ERR(LOG_TAG, "failed to increase stream user count");
+        return status;
+    }
+    rm->unlockValidStreamMutex();
+
     status = s->getParameters(param_id, (void **)param_payload);
     if (0 != status) {
         PAL_ERR(LOG_TAG, "get parameters failed status %d param_id %u", status, param_id);
-        return status;
     }
+
+    rm->lockValidStreamMutex();
+    rm->decreaseStreamUserCounter(s);
+    rm->unlockValidStreamMutex();
     PAL_DBG(LOG_TAG, "Exit. status %d", status);
     return status;
 }
@@ -463,33 +536,51 @@
     int status;
     std::shared_ptr<ResourceManager> rm = NULL;
 
-    if (!stream_handle) {
-        status = -EINVAL;
-        PAL_ERR(LOG_TAG,  "Invalid stream handle, status %d", status);
-        return status;
-    }
-    PAL_DBG(LOG_TAG, "Enter. Stream handle :%pK param_id %d", stream_handle,
-            param_id);
-    s =  reinterpret_cast<Stream *>(stream_handle);
-    if (PAL_PARAM_ID_UIEFFECT == param_id) {
-        status = s->setEffectParameters((void *)param_payload);
-    } else {
-        status = s->setParameters(param_id, (void *)param_payload);
-    }
-    if (0 != status) {
-        PAL_ERR(LOG_TAG, "set parameters failed status %d param_id %u", status, param_id);
-        return status;
-    }
     rm = ResourceManager::getInstance();
     if (!rm) {
         status = -EINVAL;
         PAL_ERR(LOG_TAG, "Invalid resource manager");
         return status;
     }
+
+    rm->lockValidStreamMutex();
+    if (!stream_handle || !rm->isActiveStream(stream_handle)) {
+        rm->unlockValidStreamMutex();
+        status = -EINVAL;
+        PAL_ERR(LOG_TAG,  "Invalid stream handle, status %d", status);
+        return status;
+    }
+
+    PAL_DBG(LOG_TAG, "Enter. Stream handle :%pK param_id %d", stream_handle,
+            param_id);
+    s =  reinterpret_cast<Stream *>(stream_handle);
+    status = rm->increaseStreamUserCounter(s);
+    if (0 != status) {
+        rm->unlockValidStreamMutex();
+        PAL_ERR(LOG_TAG, "failed to increase stream user count");
+        return status;
+    }
+    rm->unlockValidStreamMutex();
+
+    if (PAL_PARAM_ID_UIEFFECT == param_id) {
+        status = s->setEffectParameters((void *)param_payload);
+    } else {
+        status = s->setParameters(param_id, (void *)param_payload);
+    }
+    rm->lockValidStreamMutex();
+    rm->decreaseStreamUserCounter(s);
+    rm->unlockValidStreamMutex();
+
+    if (0 != status) {
+        PAL_ERR(LOG_TAG, "set parameters failed status %d param_id %u", status, param_id);
+        return status;
+    }
+
     if (param_id == PAL_PARAM_ID_STOP_BUFFERING) {
         PAL_DBG(LOG_TAG, "Buffering stopped, handle deferred LPI<->NLPI switch");
         rm->handleDeferredSwitch();
     }
+
     PAL_DBG(LOG_TAG, "Exit. status %d", status);
     return status;
 }
@@ -514,9 +605,9 @@
     }
     PAL_DBG(LOG_TAG, "Enter. Stream handle :%pK", stream_handle);
 
-    rm->lockActiveStream();
+    rm->lockValidStreamMutex();
     if (!rm->isActiveStream(stream_handle)) {
-        rm->unlockActiveStream();
+        rm->unlockValidStreamMutex();
         status = -EINVAL;
         return status;
     }
@@ -524,19 +615,19 @@
     s =  reinterpret_cast<Stream *>(stream_handle);
     status = rm->increaseStreamUserCounter(s);
     if (0 != status) {
-        rm->unlockActiveStream();
+        rm->unlockValidStreamMutex();
         PAL_ERR(LOG_TAG, "failed to increase stream user count");
         return status;
     }
-    rm->unlockActiveStream();
+    rm->unlockValidStreamMutex();
 
     s->lockStreamMutex();
     status = s->setVolume(volume);
     s->unlockStreamMutex();
 
-    rm->lockActiveStream();
+    rm->lockValidStreamMutex();
     rm->decreaseStreamUserCounter(s);
-    rm->unlockActiveStream();
+    rm->unlockValidStreamMutex();
 
     if (0 != status) {
         PAL_ERR(LOG_TAG, "setVolume failed with status %d", status);
@@ -567,9 +658,9 @@
 
     PAL_DBG(LOG_TAG, "Enter. Stream handle :%pK", stream_handle);
 
-    rm->lockActiveStream();
+    rm->lockValidStreamMutex();
     if (!rm->isActiveStream(stream_handle)) {
-        rm->unlockActiveStream();
+        rm->unlockValidStreamMutex();
         status = -EINVAL;
         goto exit;
     }
@@ -577,16 +668,16 @@
     s =  reinterpret_cast<Stream *>(stream_handle);
     status = rm->increaseStreamUserCounter(s);
     if (0 != status) {
-        rm->unlockActiveStream();
+        rm->unlockValidStreamMutex();
         PAL_ERR(LOG_TAG, "failed to increase stream user count");
         goto exit;
     }
-    rm->unlockActiveStream();
+    rm->unlockValidStreamMutex();
     status = s->mute(state);
 
-    rm->lockActiveStream();
+    rm->lockValidStreamMutex();
     rm->decreaseStreamUserCounter(s);
-    rm->unlockActiveStream();
+    rm->unlockValidStreamMutex();
 
     if (0 != status) {
         PAL_ERR(LOG_TAG, "mute failed with status %d", status);
@@ -595,7 +686,6 @@
 
 exit:
     PAL_DBG(LOG_TAG, "Exit. status %d", status);
-
     return status;
 }
 
@@ -603,18 +693,40 @@
 {
     Stream *s = NULL;
     int status;
-    if (!stream_handle) {
+    std::shared_ptr<ResourceManager> rm = NULL;
+
+    rm = ResourceManager::getInstance();
+    if (!rm) {
+        PAL_ERR(LOG_TAG, "Invalid resource manager");
+        status = -EINVAL;
+        return status;
+    }
+
+    rm->lockValidStreamMutex();
+    if (!stream_handle || !rm->isActiveStream(stream_handle)) {
+        rm->unlockValidStreamMutex();
         status = -EINVAL;
         PAL_ERR(LOG_TAG, "Invalid stream handle status %d", status);
         return status;
     }
+
     PAL_DBG(LOG_TAG, "Enter. Stream handle :%pK", stream_handle);
     s =  reinterpret_cast<Stream *>(stream_handle);
+    status = rm->increaseStreamUserCounter(s);
+    if (0 != status) {
+        rm->unlockValidStreamMutex();
+        PAL_ERR(LOG_TAG, "failed to increase stream user count");
+        return status;
+    }
+    rm->unlockValidStreamMutex();
+
     status = s->pause();
     if (0 != status) {
         PAL_ERR(LOG_TAG, "pal_stream_pause failed with status %d", status);
-        return status;
     }
+    rm->lockValidStreamMutex();
+    rm->decreaseStreamUserCounter(s);
+    rm->unlockValidStreamMutex();
     PAL_DBG(LOG_TAG, "Exit. status %d", status);
     return status;
 }
@@ -623,8 +735,18 @@
 {
     Stream *s = NULL;
     int status;
+    std::shared_ptr<ResourceManager> rm = NULL;
 
-    if (!stream_handle) {
+    rm = ResourceManager::getInstance();
+    if (!rm) {
+        PAL_ERR(LOG_TAG, "Invalid resource manager");
+        status = -EINVAL;
+        return status;
+    }
+
+    rm->lockValidStreamMutex();
+    if (!stream_handle || !rm->isActiveStream(stream_handle)) {
+        rm->unlockValidStreamMutex();
         status = -EINVAL;
         PAL_ERR(LOG_TAG, "Invalid stream handle status %d", status);
         return status;
@@ -632,13 +754,21 @@
 
     PAL_DBG(LOG_TAG, "Enter. Stream handle :%pK", stream_handle);
     s =  reinterpret_cast<Stream *>(stream_handle);
+    status = rm->increaseStreamUserCounter(s);
+    if (0 != status) {
+        rm->unlockValidStreamMutex();
+        PAL_ERR(LOG_TAG, "failed to increase stream user count");
+        return status;
+    }
+    rm->unlockValidStreamMutex();
 
     status = s->resume();
     if (0 != status) {
         PAL_ERR(LOG_TAG, "resume failed with status %d", status);
-        return status;
     }
-
+    rm->lockValidStreamMutex();
+    rm->decreaseStreamUserCounter(s);
+    rm->unlockValidStreamMutex();
     PAL_DBG(LOG_TAG, "Exit. status %d", status);
     return status;
 }
@@ -664,9 +794,9 @@
         goto exit;
     }
 
-    rm->lockActiveStream();
+    rm->lockValidStreamMutex();
     if (!rm->isActiveStream(stream_handle)) {
-        rm->unlockActiveStream();
+        rm->unlockValidStreamMutex();
         status = -EINVAL;
         goto exit;
     }
@@ -674,17 +804,17 @@
     s =  reinterpret_cast<Stream *>(stream_handle);
     status = rm->increaseStreamUserCounter(s);
     if (0 != status) {
-        rm->unlockActiveStream();
+        rm->unlockValidStreamMutex();
         PAL_ERR(LOG_TAG, "failed to increase stream user count");
         goto exit;
     }
-    rm->unlockActiveStream();
+    rm->unlockValidStreamMutex();
 
     status = s->drain(type);
 
-    rm->lockActiveStream();
+    rm->lockValidStreamMutex();
     rm->decreaseStreamUserCounter(s);
-    rm->unlockActiveStream();
+    rm->unlockValidStreamMutex();
 
     if (0 != status) {
         PAL_ERR(LOG_TAG, "drain failed with status %d", status);
@@ -699,8 +829,18 @@
 {
     Stream *s = NULL;
     int status;
+    std::shared_ptr<ResourceManager> rm = NULL;
 
-    if (!stream_handle) {
+    rm = ResourceManager::getInstance();
+    if (!rm) {
+        PAL_ERR(LOG_TAG, "Invalid resource manager");
+        status = -EINVAL;
+        return status;
+    }
+
+    rm->lockValidStreamMutex();
+    if (!stream_handle || !rm->isActiveStream(stream_handle)) {
+        rm->unlockValidStreamMutex();
         status = -EINVAL;
         PAL_ERR(LOG_TAG, "Invalid stream handle status %d", status);
         return status;
@@ -708,13 +848,22 @@
 
     PAL_DBG(LOG_TAG, "Enter. Stream handle :%pK", stream_handle);
     s =  reinterpret_cast<Stream *>(stream_handle);
+    status = rm->increaseStreamUserCounter(s);
+    if (0 != status) {
+        rm->unlockValidStreamMutex();
+        PAL_ERR(LOG_TAG, "failed to increase stream user count");
+        return status;
+    }
+    rm->unlockValidStreamMutex();
 
     status = s->flush();
     if (0 != status) {
         PAL_ERR(LOG_TAG, "flush failed with status %d", status);
-        return status;
     }
 
+    rm->lockValidStreamMutex();
+    rm->decreaseStreamUserCounter(s);
+    rm->unlockValidStreamMutex();
     PAL_DBG(LOG_TAG, "Exit. status %d", status);
     return status;
 }
@@ -723,8 +872,18 @@
 {
     Stream *s = NULL;
     int status;
+    std::shared_ptr<ResourceManager> rm = NULL;
 
-    if (!stream_handle) {
+    rm = ResourceManager::getInstance();
+    if (!rm) {
+        PAL_ERR(LOG_TAG, "Invalid resource manager");
+        status = -EINVAL;
+        return status;
+    }
+
+    rm->lockValidStreamMutex();
+    if (!stream_handle || !rm->isActiveStream(stream_handle)) {
+        rm->unlockValidStreamMutex();
         status = -EINVAL;
         PAL_ERR(LOG_TAG, "Invalid stream handle status %d", status);
         return status;
@@ -732,12 +891,22 @@
 
     PAL_DBG(LOG_TAG, "Enter. Stream handle :%pK", stream_handle);
     s =  reinterpret_cast<Stream *>(stream_handle);
+    status = rm->increaseStreamUserCounter(s);
+    if (0 != status) {
+        rm->unlockValidStreamMutex();
+        PAL_ERR(LOG_TAG, "failed to increase stream user count");
+        return status;
+    }
+    rm->unlockValidStreamMutex();
 
     status = s->suspend();
     if (0 != status) {
         PAL_ERR(LOG_TAG, "suspend failed with status %d", status);
     }
 
+    rm->lockValidStreamMutex();
+    rm->decreaseStreamUserCounter(s);
+    rm->unlockValidStreamMutex();
     PAL_DBG(LOG_TAG, "Exit. status %d", status);
     return status;
 }
@@ -748,20 +917,40 @@
 {
     Stream *s = NULL;
     int status;
+    std::shared_ptr<ResourceManager> rm = NULL;
 
-    if (!stream_handle) {
+    rm = ResourceManager::getInstance();
+    if (!rm) {
+        PAL_ERR(LOG_TAG, "Invalid resource manager");
         status = -EINVAL;
-        PAL_ERR(LOG_TAG, "Invalid input parameters status %d", status);
         return status;
     }
+
+    rm->lockValidStreamMutex();
+    if (!stream_handle || !rm->isActiveStream(stream_handle)) {
+        rm->unlockValidStreamMutex();
+        status = -EINVAL;
+        PAL_ERR(LOG_TAG, "Invalid stream handle status %d", status);
+        return status;
+    }
+
     PAL_DBG(LOG_TAG, "Enter. Stream handle :%pK", stream_handle);
     s =  reinterpret_cast<Stream *>(stream_handle);
+    status = rm->increaseStreamUserCounter(s);
+    if (0 != status) {
+        rm->unlockValidStreamMutex();
+        PAL_ERR(LOG_TAG, "failed to increase stream user count");
+        return status;
+    }
+    rm->unlockValidStreamMutex();
 
     status = s->setBufInfo(in_buffer_cfg, out_buffer_cfg);
     if (0 != status) {
         PAL_ERR(LOG_TAG, "pal_stream_set_buffer_size failed with status %d", status);
-        return status;
     }
+    rm->lockValidStreamMutex();
+    rm->decreaseStreamUserCounter(s);
+    rm->unlockValidStreamMutex();
     PAL_DBG(LOG_TAG, "Exit. status %d", status);
     return status;
 }
@@ -772,11 +961,6 @@
     Stream *s = NULL;
     int status = -EINVAL;
     std::shared_ptr<ResourceManager> rm = NULL;
-
-    if (!stream_handle) {
-        PAL_ERR(LOG_TAG, "Invalid input parameters status %d\n", status);
-        return status;
-    }
     PAL_DBG(LOG_TAG, "Enter. Stream handle :%pK\n", stream_handle);
 
     rm = ResourceManager::getInstance();
@@ -785,14 +969,26 @@
         return status;
     }
 
-    rm->lockActiveStream();
-    if (rm->isActiveStream(stream_handle)) {
-        s =  reinterpret_cast<Stream *>(stream_handle);
-        status = s->getTimestamp(stime);
-    } else {
-        PAL_ERR(LOG_TAG, "stream handle in stale state.\n");
+    rm->lockValidStreamMutex();
+    if (!stream_handle || !rm->isActiveStream(stream_handle)) {
+        rm->unlockValidStreamMutex();
+        status = -EINVAL;
+        PAL_ERR(LOG_TAG, "Invalid stream handle status %d", status);
+        return status;
     }
-    rm->unlockActiveStream();
+    s =  reinterpret_cast<Stream *>(stream_handle);
+    status = rm->increaseStreamUserCounter(s);
+    if (0 != status) {
+        rm->unlockValidStreamMutex();
+        PAL_ERR(LOG_TAG, "failed to increase stream user count");
+        return status;
+    }
+    rm->unlockValidStreamMutex();
+    status = s->getTimestamp(stime);
+
+    rm->lockValidStreamMutex();
+    rm->decreaseStreamUserCounter(s);
+    rm->unlockValidStreamMutex();
 
     if (0 != status) {
         PAL_ERR(LOG_TAG, "pal_get_timestamp failed with status %d\n", status);
@@ -812,20 +1008,41 @@
 {
     Stream *s = NULL;
     int status = 0;
+    std::shared_ptr<ResourceManager> rm = NULL;
 
-    if (!stream_handle) {
+    rm = ResourceManager::getInstance();
+    if (!rm) {
+        PAL_ERR(LOG_TAG, "Invalid resource manager");
+        status = -EINVAL;
+        return status;
+    }
+
+    rm->lockValidStreamMutex();
+    if (!stream_handle || !rm->isActiveStream(stream_handle)) {
+        rm->unlockValidStreamMutex();
         status = -EINVAL;
         PAL_ERR(LOG_TAG, "Invalid stream handle status %d", status);
         return status;
     }
-    PAL_DBG(LOG_TAG, "Enter. Stream handle :%pK", stream_handle);
 
+    PAL_DBG(LOG_TAG, "Enter. Stream handle :%pK", stream_handle);
     s =  reinterpret_cast<Stream *>(stream_handle);
+    status = rm->increaseStreamUserCounter(s);
+    if (0 != status) {
+        rm->unlockValidStreamMutex();
+        PAL_ERR(LOG_TAG, "failed to increase stream user count");
+        return status;
+    }
+    rm->unlockValidStreamMutex();
+
     status = s->addRemoveEffect(effect, enable);
     if (0 != status) {
         PAL_ERR(LOG_TAG, "pal_add_effect failed with status %d", status);
-        return status;
     }
+
+    rm->lockValidStreamMutex();
+    rm->decreaseStreamUserCounter(s);
+    rm->unlockValidStreamMutex();
     PAL_DBG(LOG_TAG, "Exit. status %d", status);
     return status;
 
@@ -864,9 +1081,9 @@
         return status;
     }
 
-    rm->lockActiveStream();
+    rm->lockValidStreamMutex();
     if (!rm->isActiveStream(stream_handle)) {
-        rm->unlockActiveStream();
+        rm->unlockValidStreamMutex();
         status = -EINVAL;
         return status;
     }
@@ -876,11 +1093,11 @@
     s = reinterpret_cast<Stream *>(stream_handle);
     status = rm->increaseStreamUserCounter(s);
     if (0 != status) {
-        rm->unlockActiveStream();
+        rm->unlockValidStreamMutex();
         PAL_ERR(LOG_TAG, "failed to increase stream user count");
         return status;
     }
-    rm->unlockActiveStream();
+    rm->unlockValidStreamMutex();
 
     s->getStreamAttributes(&sattr);
 
@@ -926,22 +1143,23 @@
                 break;
         }
 
-      /*
-       * When USB headset is disconnected the music playback pauses
-       * and the policy manager sends routing=0. But if the USB is connected
-       * back before the standby time, it can not switch device to usb hs any more
-       * because current pal device is usb hs which equals new device when resuming playback.
-       * So routing to default device first during handling routing = 0 msg will guarantee
-       * the device switch to usb can be executed once USB is connected again.
-       */
-        bool curPalDevice_usb = curPalDevices.find(PAL_DEVICE_OUT_USB_DEVICE) != curPalDevices.end() ||
-                                curPalDevices.find(PAL_DEVICE_OUT_USB_HEADSET) != curPalDevices.end();
-        bool activeDevices_usb = activeDevices.find(PAL_DEVICE_OUT_USB_DEVICE) != activeDevices.end() ||
-                                 activeDevices.find(PAL_DEVICE_OUT_USB_HEADSET) != activeDevices.end();
-        bool usb_active = rm->isDeviceAvailable(PAL_DEVICE_OUT_USB_DEVICE) ||
-                          rm->isDeviceAvailable(PAL_DEVICE_OUT_USB_HEADSET);
+        /*
+        * When headset is disconnected the music playback pauses
+        * and the policy manager sends routing=0. But if the headset is connected
+        * back before the standby time, it can not switch device to headset any more
+        * because current pal device is headset which equals new device when resuming playback.
+        * So routing to default device first during handling routing = 0 msg will guarantee
+        * the device switch to headset can be executed once headset is connected again.
+        */
         if (devices[0].id == PAL_DEVICE_NONE &&
-            curPalDevice_usb && activeDevices_usb && !usb_active)
+            (rm->isDisconnectedDeviceStillActive(curPalDevices,activeDevices,
+            PAL_DEVICE_OUT_USB_DEVICE) ||
+            rm->isDisconnectedDeviceStillActive(curPalDevices,activeDevices,
+            PAL_DEVICE_OUT_USB_HEADSET) ||
+            rm->isDisconnectedDeviceStillActive(curPalDevices,activeDevices,
+            PAL_DEVICE_OUT_WIRED_HEADPHONE) ||
+            rm->isDisconnectedDeviceStillActive(curPalDevices,activeDevices,
+            PAL_DEVICE_OUT_WIRED_HEADSET)))
         {
             devices[0].id = PAL_DEVICE_OUT_SPEAKER;
         }
@@ -1003,9 +1221,9 @@
     }
 
 exit:
-    rm->lockActiveStream();
+    rm->lockValidStreamMutex();
     rm->decreaseStreamUserCounter(s);
-    rm->unlockActiveStream();
+    rm->unlockValidStreamMutex();
     if (pDevices)
         free(pDevices);
     PAL_INFO(LOG_TAG, "Exit. status %d", status);
@@ -1017,17 +1235,39 @@
 {
     int status = 0;
     Stream *s = NULL;
+    std::shared_ptr<ResourceManager> rm = NULL;
 
-    if (!stream_handle) {
+    rm = ResourceManager::getInstance();
+    if (!rm) {
+        status = -EINVAL;
+        PAL_ERR(LOG_TAG, "Invalid resource manager");
+        return status;
+    }
+
+    rm->lockValidStreamMutex();
+    if (!stream_handle || !rm->isActiveStream(stream_handle)) {
+        rm->unlockValidStreamMutex();
         status = -EINVAL;
         PAL_ERR(LOG_TAG, "Invalid stream handle status %d", status);
         return status;
     }
+
     PAL_DBG(LOG_TAG, "Enter. Stream handle :%pK", stream_handle);
 
     s =  reinterpret_cast<Stream *>(stream_handle);
+    status = rm->increaseStreamUserCounter(s);
+    if (0 != status) {
+        rm->unlockValidStreamMutex();
+        PAL_ERR(LOG_TAG, "failed to increase stream user count");
+        return status;
+    }
+    rm->unlockValidStreamMutex();
+
     status = s->getTagsWithModuleInfo(size, payload);
 
+    rm->lockValidStreamMutex();
+    rm->decreaseStreamUserCounter(s);
+    rm->unlockValidStreamMutex();
     PAL_DBG(LOG_TAG, "Exit. Stream handle: %pK, status %d", stream_handle, status);
     return status;
 }
@@ -1081,20 +1321,43 @@
 int32_t pal_stream_get_mmap_position(pal_stream_handle_t *stream_handle,
                               struct pal_mmap_position *position)
 {
-   Stream *s = NULL;
-   int status;
-    if (!stream_handle) {
+    Stream *s = NULL;
+    int status;
+    std::shared_ptr<ResourceManager> rm = NULL;
+
+    rm = ResourceManager::getInstance();
+    if (!rm) {
         status = -EINVAL;
-        PAL_ERR(LOG_TAG, "Invalid input parameters status %d", status);
+        PAL_ERR(LOG_TAG, "Invalid resource manager");
         return status;
     }
+
+    rm->lockValidStreamMutex();
+    if (!stream_handle || !rm->isActiveStream(stream_handle)) {
+        rm->unlockValidStreamMutex();
+        status = -EINVAL;
+        PAL_ERR(LOG_TAG, "Invalid stream handle status %d", status);
+        return status;
+    }
+
     PAL_DBG(LOG_TAG, "Enter. Stream handle :%pK", stream_handle);
     s =  reinterpret_cast<Stream *>(stream_handle);
+    status = rm->increaseStreamUserCounter(s);
+    if (0 != status) {
+        rm->unlockValidStreamMutex();
+        PAL_ERR(LOG_TAG, "failed to increase stream user count");
+        return status;
+    }
+    rm->unlockValidStreamMutex();
+
     status = s->GetMmapPosition(position);
     if (0 != status) {
         PAL_ERR(LOG_TAG, "pal_stream_get_mmap_position failed with status %d", status);
-        return status;
     }
+
+    rm->lockValidStreamMutex();
+    rm->decreaseStreamUserCounter(s);
+    rm->unlockValidStreamMutex();
     PAL_DBG(LOG_TAG, "Exit. status %d", status);
     return status;
 }
@@ -1105,18 +1368,41 @@
 {
     Stream *s = NULL;
     int status;
-    if (!stream_handle) {
+    std::shared_ptr<ResourceManager> rm = NULL;
+
+    rm = ResourceManager::getInstance();
+    if (!rm) {
         status = -EINVAL;
-        PAL_ERR(LOG_TAG, "Invalid input parameters status %d", status);
+        PAL_ERR(LOG_TAG, "Invalid resource manager");
         return status;
     }
+
+    rm->lockValidStreamMutex();
+    if (!stream_handle || !rm->isActiveStream(stream_handle)) {
+        rm->unlockValidStreamMutex();
+        status = -EINVAL;
+        PAL_ERR(LOG_TAG, "Invalid stream handle status %d", status);
+        return status;
+    }
+
     PAL_DBG(LOG_TAG, "Enter. Stream handle :%pK", stream_handle);
     s =  reinterpret_cast<Stream *>(stream_handle);
+    status = rm->increaseStreamUserCounter(s);
+    if (0 != status) {
+        rm->unlockValidStreamMutex();
+        PAL_ERR(LOG_TAG, "failed to increase stream user count");
+        return status;
+    }
+    rm->unlockValidStreamMutex();
+
     status = s->createMmapBuffer(min_size_frames, info);
     if (0 != status) {
         PAL_ERR(LOG_TAG, "pal_stream_create_mmap_buffer failed with status %d", status);
-        return status;
     }
+
+    rm->lockValidStreamMutex();
+    rm->decreaseStreamUserCounter(s);
+    rm->unlockValidStreamMutex();
     PAL_DBG(LOG_TAG, "Exit. status %d", status);
     return status;
 }
diff --git a/configs/anorak/usecaseKvManager.xml b/configs/anorak/usecaseKvManager.xml
index f57d31d..d9d6ace 100644
--- a/configs/anorak/usecaseKvManager.xml
+++ b/configs/anorak/usecaseKvManager.xml
@@ -28,7 +28,7 @@
 
 
 * Changes from Qualcomm Innovation Center are provided under the following license:
-* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
 * SPDX-License-Identifier: BSD-3-Clause-Clear
 *  -->
 
@@ -80,6 +80,15 @@
                 <graph_kv key="0xAB000000" value="0x2"/>
             </keys_and_values>
         </stream>
+        <!-- Spatial audio stream -->
+        <stream type="PAL_STREAM_SPATIAL_AUDIO">
+            <keys_and_values Direction="RX" Instance="1">
+                <!-- STREAMRX - SPATIAL_AUDIO_PLAYBACK  -->
+                <graph_kv key="0xA1000000" value="0xA1000018"/>
+                <!-- INSTANCE - INSTANCE_1 -->
+                <graph_kv key="0xAB000000" value="0x1"/>
+            </keys_and_values>
+        </stream>
         <stream type="PAL_STREAM_VOICE_RECOGNITION">
             <keys_and_values Direction="TX" Instance="1">
                 <!-- STREAMTX - PCM_RECORD -->
@@ -756,13 +765,13 @@
     <devicepps>
         <!-- OUT Speaker DevicePPs -->
         <devicepp id="PAL_DEVICE_OUT_SPEAKER">
-            <keys_and_values StreamType="PAL_STREAM_DEEP_BUFFER,PAL_STREAM_PCM_OFFLOAD,PAL_STREAM_COMPRESSED,PAL_STREAM_LOW_LATENCY,PAL_STREAM_GENERIC">
+            <keys_and_values StreamType="PAL_STREAM_DEEP_BUFFER,PAL_STREAM_PCM_OFFLOAD,PAL_STREAM_COMPRESSED,PAL_STREAM_LOW_LATENCY,PAL_STREAM_GENERIC,PAL_STREAM_SPATIAL_AUDIO">
                 <!-- DEVICERX - SPEAKER -->
                 <graph_kv key="0xA2000000" value="0xA2000001"/>
                 <!-- DEVICEPP_RX - DEVICEPP_RX_AUDIO_MBDRC -->
                 <graph_kv key="0xAC000000" value="0xAC000002"/>
             </keys_and_values>
-            <keys_and_values StreamType="PAL_STREAM_DEEP_BUFFER,PAL_STREAM_PCM_OFFLOAD,PAL_STREAM_COMPRESSED,PAL_STREAM_GENERIC,PAL_STREAM_LOW_LATENCY" CustomConfig="mspp">
+            <keys_and_values StreamType="PAL_STREAM_DEEP_BUFFER,PAL_STREAM_PCM_OFFLOAD,PAL_STREAM_COMPRESSED,PAL_STREAM_GENERIC,PAL_STREAM_LOW_LATENCY,PAL_STREAM_SPATIAL_AUDIO" CustomConfig="mspp">
                 <!-- DEVICERX - SPEAKER -->
                 <graph_kv key="0xA2000000" value="0xA2000001"/>
                 <!-- DEVICEPP_RX - DEVICEPP_RX_AUDIO_MSPP -->
@@ -858,7 +867,7 @@
         </devicepp>
         <!-- OUT Headset and Headphone Digital DevicePPs -->
         <devicepp id="PAL_DEVICE_OUT_WIRED_HEADSET,PAL_DEVICE_OUT_WIRED_HEADPHONE">
-            <keys_and_values StreamType="PAL_STREAM_DEEP_BUFFER,PAL_STREAM_PCM_OFFLOAD,PAL_STREAM_COMPRESSED,PAL_STREAM_LOW_LATENCY,PAL_STREAM_GENERIC">
+            <keys_and_values StreamType="PAL_STREAM_DEEP_BUFFER,PAL_STREAM_PCM_OFFLOAD,PAL_STREAM_COMPRESSED,PAL_STREAM_LOW_LATENCY,PAL_STREAM_GENERIC,PAL_STREAM_SPATIAL_AUDIO">
                 <!-- DEVICERX - HEADPHONES -->
                 <graph_kv key="0xA2000000" value="0xA2000002"/>
                 <!-- DEVICEPP_RX - DEVICEPP_RX_AUDIO_MBDRC -->
@@ -891,7 +900,7 @@
         </devicepp>
         <!-- OUT Bluetooth A2DP DevicePPs -->
         <devicepp id="PAL_DEVICE_OUT_BLUETOOTH_A2DP">
-            <keys_and_values StreamType="PAL_STREAM_COMPRESSED,PAL_STREAM_DEEP_BUFFER,PAL_STREAM_LOW_LATENCY,PAL_STREAM_PCM_OFFLOAD,PAL_STREAM_GENERIC">
+            <keys_and_values StreamType="PAL_STREAM_COMPRESSED,PAL_STREAM_DEEP_BUFFER,PAL_STREAM_LOW_LATENCY,PAL_STREAM_PCM_OFFLOAD,PAL_STREAM_GENERIC,PAL_STREAM_SPATIAL_AUDIO">
                 <!-- DEVICEPP_RX - DEVICEPP_RX_AUDIO_MBDRC -->
                 <graph_kv key="0xAC000000" value="0xAC000002"/>
             </keys_and_values>
@@ -902,7 +911,7 @@
         </devicepp>
         <!-- OUT Bluetooth BLE DevicePPs -->
         <devicepp id="PAL_DEVICE_OUT_BLUETOOTH_BLE">
-            <keys_and_values StreamType="PAL_STREAM_COMPRESSED,PAL_STREAM_DEEP_BUFFER,PAL_STREAM_LOW_LATENCY,PAL_STREAM_PCM_OFFLOAD">
+            <keys_and_values StreamType="PAL_STREAM_COMPRESSED,PAL_STREAM_DEEP_BUFFER,PAL_STREAM_LOW_LATENCY,PAL_STREAM_PCM_OFFLOAD,PAL_STREAM_SPATIAL_AUDIO">
                 <!-- DEVICEPP_RX - DEVICEPP_RX_AUDIO_MBDRC -->
                 <graph_kv key="0xAC000000" value="0xAC000002"/>
             </keys_and_values>
@@ -924,7 +933,7 @@
         </devicepp>
         <!-- OUT BT SCO DevicePPs -->
         <devicepp id="PAL_DEVICE_OUT_BLUETOOTH_SCO">
-            <keys_and_values StreamType="PAL_STREAM_DEEP_BUFFER,PAL_STREAM_PCM_OFFLOAD,PAL_STREAM_COMPRESSED,PAL_STREAM_LOW_LATENCY,PAL_STREAM_GENERIC">
+            <keys_and_values StreamType="PAL_STREAM_DEEP_BUFFER,PAL_STREAM_PCM_OFFLOAD,PAL_STREAM_COMPRESSED,PAL_STREAM_LOW_LATENCY,PAL_STREAM_GENERIC,PAL_STREAM_SPATIAL_AUDIO">
                 <!-- DEVICERX - BT_RX -->
                 <graph_kv key="0xA2000000" value="0xA2000003"/>
                 <!-- DEVICEPP_RX - DEVICEPP_RX_AUDIO_MBDRC -->
@@ -960,7 +969,7 @@
         </devicepp>
         <!-- OUT USB device and USB Headset DevicePPs -->
         <devicepp id="PAL_DEVICE_OUT_USB_DEVICE,PAL_DEVICE_OUT_USB_HEADSET">
-            <keys_and_values StreamType="PAL_STREAM_DEEP_BUFFER,PAL_STREAM_PCM_OFFLOAD,PAL_STREAM_COMPRESSED,PAL_STREAM_LOW_LATENCY,PAL_STREAM_GENERIC">
+            <keys_and_values StreamType="PAL_STREAM_DEEP_BUFFER,PAL_STREAM_PCM_OFFLOAD,PAL_STREAM_COMPRESSED,PAL_STREAM_LOW_LATENCY,PAL_STREAM_GENERIC,PAL_STREAM_SPATIAL_AUDIO">
                 <!-- DEVICERX - USB_RX -->
                 <graph_kv key="0xA2000000" value="0xA2000005"/>
                 <!-- DEVICEPP_RX - DEVICEPP_RX_AUDIO_MBDRC -->
diff --git a/configs/crow/mixer_paths_crow_idp_wcd9395_aatc.xml b/configs/crow/mixer_paths_crow_idp_wcd9395_aatc.xml
index e84eb8a..94a7715 100644
--- a/configs/crow/mixer_paths_crow_idp_wcd9395_aatc.xml
+++ b/configs/crow/mixer_paths_crow_idp_wcd9395_aatc.xml
@@ -580,12 +580,12 @@
     </path>
 
     <path name="handset-wcd">
-        <ctl name="RX_MACRO RX0 MUX" value="AIF1_PB" />
-        <ctl name="RX INT0_1 MIX1 INP0" value="RX0" />
-        <ctl name="RX INT0 DEM MUX" value="CLSH_DSM_OUT" />
+        <ctl name="RX_MACRO RX2 MUX" value="AIF2_PB" />
+        <ctl name="RX INT2_1 MIX1 INP0" value="RX2" />
         <ctl name="EAR_RDAC Switch" value="1" />
-        <ctl name="RDAC3_MUX" value="RX1" />
+        <ctl name="RDAC3_MUX" value="RX3" />
         <ctl name="RX_EAR Mode" value="ON" />
+        <ctl name="RX_RX2 Digital Volume" value="100" />
     </path>
 
     <path name="handset-vbat">
diff --git a/configs/crow/mixer_paths_crow_qrd.xml b/configs/crow/mixer_paths_crow_qrd.xml
old mode 100644
new mode 100755
index 44bc7ba..e74e0f1
--- 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>
 
@@ -562,7 +562,7 @@
         <ctl name="SpkrLeft COMP Switch" value="1" />
         <ctl name="SpkrLeft VISENSE Switch" value="1" />
         <ctl name="SpkrLeft SWR DAC_Port Switch" value="1" />
-        <ctl name="WSA_RX0 Digital Volume" value="70" />
+        <ctl name="WSA_RX0 Digital Volume" value="60" />
     </path>
 
     <path name="handset-vbat">
@@ -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/configs/crow/resourcemanager_crow_idp.xml b/configs/crow/resourcemanager_crow_idp.xml
index 87c99db..23c336b 100644
--- a/configs/crow/resourcemanager_crow_idp.xml
+++ b/configs/crow/resourcemanager_crow_idp.xml
@@ -1474,6 +1474,7 @@
                 <sound_model_info>
                     <first_stage_module_params>
                         <param module_type="GMM" />
+                        <param lpi_supported="false"/>
                         <param load_sound_model_ids="0xC0000008, 0x0800104C" />
                         <param wakeup_config_ids="0xC0000008, 0x08001049" />
                         <param buffering_config_ids="0xC0000008, 0x08001044" />
diff --git a/configs/crow/resourcemanager_crow_idp_wcd9395_aatc.xml b/configs/crow/resourcemanager_crow_idp_wcd9395_aatc.xml
index 524cc3f..4db17c2 100644
--- a/configs/crow/resourcemanager_crow_idp_wcd9395_aatc.xml
+++ b/configs/crow/resourcemanager_crow_idp_wcd9395_aatc.xml
@@ -561,10 +561,10 @@
             <id>PAL_DEVICE_IN_VI_FEEDBACK</id>
             <back_end_name>CODEC_DMA-LPAIF_WSA-TX-0</back_end_name>
             <max_channels>2</max_channels>
-            <channels>2</channels>
+            <channels>1</channels>
             <samplerate>48000</samplerate>
             <bit_width>32</bit_width>
-            <snd_device_name>vi-feedback</snd_device_name>
+            <snd_device_name>vi-feedback-mono-2</snd_device_name>
             <usecase>
                 <name>PAL_STREAM_VOICE_CALL</name>
                 <channels>1</channels>
@@ -575,10 +575,10 @@
             <id>PAL_DEVICE_IN_CPS_FEEDBACK</id>
             <back_end_name>CODEC_DMA-LPAIF_WSA-TX-2</back_end_name>
             <max_channels>2</max_channels>
-            <channels>2</channels>
+            <channels>1</channels>
             <samplerate>24000</samplerate>
             <bit_width>32</bit_width>
-            <snd_device_name>cps-feedback</snd_device_name>
+            <snd_device_name>cps-feedback-mono-2</snd_device_name>
             <usecase>
                 <name>PAL_STREAM_VOICE_CALL</name>
                 <channels>1</channels>
@@ -1474,6 +1474,7 @@
                 <sound_model_info>
                     <first_stage_module_params>
                         <param module_type="GMM" />
+                        <param lpi_supported="false"/>
                         <param load_sound_model_ids="0xC0000008, 0x0800104C" />
                         <param wakeup_config_ids="0xC0000008, 0x08001049" />
                         <param buffering_config_ids="0xC0000008, 0x08001044" />
diff --git a/configs/crow/resourcemanager_crow_idp_wcd9395_dmic.xml b/configs/crow/resourcemanager_crow_idp_wcd9395_dmic.xml
index 8c548df..3b033d2 100644
--- a/configs/crow/resourcemanager_crow_idp_wcd9395_dmic.xml
+++ b/configs/crow/resourcemanager_crow_idp_wcd9395_dmic.xml
@@ -1474,6 +1474,7 @@
                 <sound_model_info>
                     <first_stage_module_params>
                         <param module_type="GMM" />
+                        <param lpi_supported="false"/>
                         <param load_sound_model_ids="0xC0000008, 0x0800104C" />
                         <param wakeup_config_ids="0xC0000008, 0x08001049" />
                         <param buffering_config_ids="0xC0000008, 0x08001044" />
diff --git a/configs/crow/resourcemanager_crow_idp_wcd9395_wcd_dmic.xml b/configs/crow/resourcemanager_crow_idp_wcd9395_wcd_dmic.xml
index 8c548df..3b033d2 100644
--- a/configs/crow/resourcemanager_crow_idp_wcd9395_wcd_dmic.xml
+++ b/configs/crow/resourcemanager_crow_idp_wcd9395_wcd_dmic.xml
@@ -1474,6 +1474,7 @@
                 <sound_model_info>
                     <first_stage_module_params>
                         <param module_type="GMM" />
+                        <param lpi_supported="false"/>
                         <param load_sound_model_ids="0xC0000008, 0x0800104C" />
                         <param wakeup_config_ids="0xC0000008, 0x08001049" />
                         <param buffering_config_ids="0xC0000008, 0x08001044" />
diff --git a/configs/crow/resourcemanager_crow_qrd.xml b/configs/crow/resourcemanager_crow_qrd.xml
index 1fe922e..03cda18 100644
--- a/configs/crow/resourcemanager_crow_qrd.xml
+++ b/configs/crow/resourcemanager_crow_qrd.xml
@@ -1475,6 +1475,7 @@
                 <sound_model_info>
                     <first_stage_module_params>
                         <param module_type="GMM" />
+                        <param lpi_supported="false"/>
                         <param load_sound_model_ids="0xC0000008, 0x0800104C" />
                         <param wakeup_config_ids="0xC0000008, 0x08001049" />
                         <param buffering_config_ids="0xC0000008, 0x08001044" />
diff --git a/configs/kalama/resourcemanager_kalama_cdp.xml b/configs/kalama/resourcemanager_kalama_cdp.xml
index b706057..7f4744b 100644
--- a/configs/kalama/resourcemanager_kalama_cdp.xml
+++ b/configs/kalama/resourcemanager_kalama_cdp.xml
@@ -28,7 +28,7 @@
 
 * Changes from Qualcomm Innovation Center are provided under the following license:
 *
-* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted (subject to the limitations in the
@@ -77,6 +77,7 @@
         <param key="device_mux_config" value ="false" />
         <param key="upd_duty_cycle_enable" value="false" />
         <param key="upd_virtual_port" value ="false" />
+        <param key="spkr_xmax_tmax_logging_enable" value ="false" />
     </config_params>
     <config_gapless key="gapless_supported" value="1"/>
     <bt_codecs>
@@ -766,6 +767,7 @@
               <name>PAL_STREAM_ULTRASOUND</name>
               <priority>4</priority>
               <samplerate>96000</samplerate>
+              <bit_width>16</bit_width>
           </usecase>
         </out-device>
         <out-device>
diff --git a/configs/kalama/resourcemanager_kalama_cdp_apq.xml b/configs/kalama/resourcemanager_kalama_cdp_apq.xml
index 885b661..8239fee 100644
--- a/configs/kalama/resourcemanager_kalama_cdp_apq.xml
+++ b/configs/kalama/resourcemanager_kalama_cdp_apq.xml
@@ -28,7 +28,7 @@
 
 * Changes from Qualcomm Innovation Center are provided under the following license:
 *
-* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted (subject to the limitations in the
@@ -77,6 +77,7 @@
         <param key="device_mux_config" value ="false" />
         <param key="upd_duty_cycle_enable" value="false" />
         <param key="upd_virtual_port" value ="false" />
+        <param key="spkr_xmax_tmax_logging_enable" value ="false" />
     </config_params>
     <config_gapless key="gapless_supported" value="1"/>
     <bt_codecs>
@@ -761,6 +762,7 @@
               <name>PAL_STREAM_ULTRASOUND</name>
               <priority>4</priority>
               <samplerate>96000</samplerate>
+              <bit_width>16</bit_width>
           </usecase>
         </out-device>
         <out-device>
diff --git a/configs/kalama/resourcemanager_kalama_grd.xml b/configs/kalama/resourcemanager_kalama_grd.xml
index 665934f..6420508 100644
--- a/configs/kalama/resourcemanager_kalama_grd.xml
+++ b/configs/kalama/resourcemanager_kalama_grd.xml
@@ -28,7 +28,7 @@
 
 * Changes from Qualcomm Innovation Center are provided under the following license:
 *
-* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted (subject to the limitations in the
@@ -77,6 +77,7 @@
         <param key="device_mux_config" value ="false" />
         <param key="upd_duty_cycle_enable" value="false" />
         <param key="upd_virtual_port" value ="false" />
+        <param key="spkr_xmax_tmax_logging_enable" value ="false" />
     </config_params>
     <config_volume>
         <use_volume_set_param>0</use_volume_set_param>
@@ -764,6 +765,7 @@
               <name>PAL_STREAM_ULTRASOUND</name>
               <priority>4</priority>
               <samplerate>96000</samplerate>
+              <bit_width>16</bit_width>
           </usecase>
         </out-device>
         <out-device>
diff --git a/configs/kalama/resourcemanager_kalama_mtp.xml b/configs/kalama/resourcemanager_kalama_mtp.xml
index 7dffdc0..169c83c 100644
--- a/configs/kalama/resourcemanager_kalama_mtp.xml
+++ b/configs/kalama/resourcemanager_kalama_mtp.xml
@@ -28,7 +28,7 @@
 
 * Changes from Qualcomm Innovation Center are provided under the following license:
 *
-* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted (subject to the limitations in the
@@ -77,6 +77,7 @@
         <param key="signal_handler" value ="true" />
         <param key="device_mux_config" value ="false" />
         <param key="upd_virtual_port" value ="false" />
+        <param key="spkr_xmax_tmax_logging_enable" value ="false" />
     </config_params>
     <config_volume>
         <use_volume_set_param>0</use_volume_set_param>
@@ -781,6 +782,7 @@
               <name>PAL_STREAM_ULTRASOUND</name>
               <priority>4</priority>
               <samplerate>96000</samplerate>
+              <bit_width>16</bit_width>
           </usecase>
         </out-device>
         <out-device>
diff --git a/configs/kalama/resourcemanager_kalama_mtp_apq.xml b/configs/kalama/resourcemanager_kalama_mtp_apq.xml
index f596bdf..55e9c08 100644
--- a/configs/kalama/resourcemanager_kalama_mtp_apq.xml
+++ b/configs/kalama/resourcemanager_kalama_mtp_apq.xml
@@ -28,7 +28,7 @@
 
 * Changes from Qualcomm Innovation Center are provided under the following license:
 *
-* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted (subject to the limitations in the
@@ -77,6 +77,7 @@
         <param key="signal_handler" value ="true" />
         <param key="device_mux_config" value ="false" />
         <param key="upd_virtual_port" value ="false" />
+        <param key="spkr_xmax_tmax_logging_enable" value ="false" />
     </config_params>
     <config_volume>
         <use_volume_set_param>0</use_volume_set_param>
@@ -776,6 +777,7 @@
               <name>PAL_STREAM_ULTRASOUND</name>
               <priority>4</priority>
               <samplerate>96000</samplerate>
+              <bit_width>16</bit_width>
           </usecase>
         </out-device>
         <out-device>
diff --git a/configs/kalama/resourcemanager_kalama_qrd.xml b/configs/kalama/resourcemanager_kalama_qrd.xml
index d6c6f5f..f41696a 100644
--- a/configs/kalama/resourcemanager_kalama_qrd.xml
+++ b/configs/kalama/resourcemanager_kalama_qrd.xml
@@ -28,7 +28,7 @@
 
 * Changes from Qualcomm Innovation Center are provided under the following license:
 *
-* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted (subject to the limitations in the
@@ -77,6 +77,7 @@
         <param key="device_mux_config" value ="false" />
         <param key="upd_duty_cycle_enable" value="false" />
         <param key="upd_virtual_port" value ="false" />
+        <param key="spkr_xmax_tmax_logging_enable" value ="false" />
     </config_params>
     <config_volume>
         <use_volume_set_param>0</use_volume_set_param>
@@ -782,6 +783,7 @@
               <name>PAL_STREAM_ULTRASOUND</name>
               <priority>4</priority>
               <samplerate>96000</samplerate>
+              <bit_width>16</bit_width>
           </usecase>
         </out-device>
         <out-device>
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/SpeakerProtection.h b/device/inc/SpeakerProtection.h
index bf40718..94ac1aa 100644
--- a/device/inc/SpeakerProtection.h
+++ b/device/inc/SpeakerProtection.h
@@ -28,7 +28,7 @@
  *
  * Changes from Qualcomm Innovation Center are provided under the following license:
  *
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted (subject to the limitations in the
@@ -131,6 +131,7 @@
     spkr_prot_proc_state spkrProcessingState;
     int *spkerTempList;
     static bool isSpkrInUse;
+    static bool startXmaxLogging;
     static bool calThrdCreated;
     static bool isDynamicCalTriggered;
     static struct timespec spkrLastTimeUsed;
@@ -158,11 +159,13 @@
 
 public:
     static std::thread mCalThread;
+    static std::thread XmaxTmaxLogThread;
     static std::condition_variable cv;
     static std::mutex cvMutex;
     std::mutex deviceMutex;
     static std::mutex calibrationMutex;
     void spkrCalibrationThread();
+    void startSpkrXmaxTmaxLogging();
     int getSpeakerTemperature(int spkr_pos);
     void spkrCalibrateWait();
     int spkrStartCalibration();
@@ -194,6 +197,7 @@
     int getCpsDevNumber(std::string mixer);
     int32_t getCalibrationData(void **param);
     int32_t getFTMParameter(void **param);
+    int32_t getSpkrXmaxTmaxData();
     void disconnectFeandBe(std::vector<int> pcmDevIds, std::string backEndName);
 };
 
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..709143e 100644
--- a/device/src/Bluetooth.cpp
+++ b/device/src/Bluetooth.cpp
@@ -1734,11 +1734,17 @@
         // session will be restarted after suspend completion
         PAL_INFO(LOG_TAG, "a2dp start requested during suspend state");
         return -ENOSYS;
+    } else if (a2dpState == A2DP_STATE_DISCONNECTED) {
+        PAL_INFO(LOG_TAG, "a2dp start requested when a2dp source stream is failed to open");
+        return -ENOSYS;
     }
 
     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) {
@@ -2285,6 +2291,9 @@
             ((a2dpState != A2DP_STATE_STARTED) && (param_bt_a2dp.a2dp_suspended == true))) {
             param_bt_a2dp.is_force_switch = true;
             PAL_DBG(LOG_TAG, "a2dp reconfig or a2dp suspended/a2dpState is not started");
+        } else if (totalActiveSessionRequests == 0) {
+            param_bt_a2dp.is_force_switch = true;
+            PAL_DBG(LOG_TAG, "Force BT device switch for no total active BT sessions");
         } else {
             param_bt_a2dp.is_force_switch = false;
         }
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/SpeakerProtection.cpp b/device/src/SpeakerProtection.cpp
index a686e4e..30b3c92 100644
--- a/device/src/SpeakerProtection.cpp
+++ b/device/src/SpeakerProtection.cpp
@@ -63,10 +63,7 @@
 
 #define LOG_TAG "PAL: SpeakerProtection"
 
-
 #include "SpeakerProtection.h"
-#include "PalAudioRoute.h"
-#include "ResourceManager.h"
 #include "SessionAlsaUtils.h"
 #include "kvh2xml.h"
 #include <errno.h>
@@ -80,6 +77,8 @@
 #define PAL_SP_II_TEMP_PATH "/data/vendor/audio/audio_sp2.cal"
 #endif
 
+#define PAL_SP_XMAX_TMAX_DATA_PATH "/data/vendor/audio/spkr_xmax_tmax.txt"
+#define PAL_SP_XMAX_TMAX_LOG_PATH "/data/vendor/audio/log_spkr_xmax_tmax.cal"
 #define FEEDBACK_MONO_1 "-mono-1"
 
 #define MIN_SPKR_IDLE_SEC (60 * 30)
@@ -124,6 +123,7 @@
 #define CALIBRATION_STATUS_FAILURE 5
 
 std::thread SpeakerProtection::mCalThread;
+std::thread SpeakerProtection::XmaxTmaxLogThread;
 std::condition_variable SpeakerProtection::cv;
 std::mutex SpeakerProtection::cvMutex;
 std::mutex SpeakerProtection::calibrationMutex;
@@ -131,6 +131,7 @@
 bool SpeakerProtection::isSpkrInUse;
 bool SpeakerProtection::calThrdCreated;
 bool SpeakerProtection::isDynamicCalTriggered = false;
+bool SpeakerProtection::startXmaxLogging = false;
 struct timespec SpeakerProtection::spkrLastTimeUsed;
 struct mixer *SpeakerProtection::virtMixer;
 struct mixer *SpeakerProtection::hwMixer;
@@ -1400,6 +1401,189 @@
     customPayloadSize = 0;
 }
 
+int32_t SpeakerProtection::getSpkrXmaxTmaxData()
+{
+    const char* getParamControl = "getParam";
+    char* pcmDeviceName = NULL;
+    uint8_t* payload = NULL;
+    int ret = 0;
+    uint32_t miid = 0, num_ch = 0, stringLen =0;
+    int32_t pcmID = -EINVAL;
+    size_t payloadSize = 0, bytesWritten = -1;
+    struct mixer_ctl* ctl;
+    FILE* fp;
+    std::ostringstream cntrlName;
+    std::string backendName;
+    param_id_sp_tmax_xmax_logging_t sp_xmax_tmax;
+    param_id_sp_tmax_xmax_logging_t* sp_xmax_tmax_value;
+    PayloadBuilder* builder = new PayloadBuilder();
+
+    /* Frontend ID information for RX Session presents at SessionAlsaPCM/Compress
+     * In Kalama, there is no getter func for pcmDevIds (private attribute)
+     * Assuming there will be only one session. So hardcoded here*/
+
+    pcmID = 125;
+    pcmDeviceName = rm->getDeviceNameFromID(pcmID);
+
+    if (pcmDeviceName == NULL) {
+        /*To check for PAL_STREAM_COMPRESSED*/
+        pcmID = 105;
+        pcmDeviceName = rm->getDeviceNameFromID(pcmID);
+    }
+
+    if (pcmDeviceName) {
+        cntrlName << pcmDeviceName << " " << getParamControl;
+    }
+    else {
+        PAL_ERR(LOG_TAG, "Error: %d Unable to get Device name\n", -EINVAL);
+        ret = -EINVAL;
+        goto exit;
+    }
+
+    ctl = mixer_get_ctl_by_name(virtMixer, cntrlName.str().data());
+
+    if (!ctl) {
+        ret = -ENOENT;
+        PAL_ERR(LOG_TAG, "Error: %d Invalid mixer control: %s\n", ret, cntrlName.str().data());
+        goto exit;
+    }
+
+    rm->getBackendName(PAL_DEVICE_OUT_SPEAKER, backendName);
+
+    if (!strlen(backendName.c_str())) {
+        ret = -ENOENT;
+        PAL_ERR(LOG_TAG, "Error: %d Failed to obtain RX backend name", ret);
+        goto exit;
+    }
+
+    ret = SessionAlsaUtils::getModuleInstanceId(virtMixer, pcmID,
+        backendName.c_str(), MODULE_SP, &miid);
+
+    if (0 != ret) {
+        PAL_ERR(LOG_TAG, "Error: %d Failed to get tag info %x", ret, MODULE_SP);
+        goto exit;
+    }
+
+    sp_xmax_tmax.num_ch = vi_device.channels;
+    builder->payloadSPConfig(&payload, &payloadSize, miid,
+        PARAM_ID_SP_TMAX_XMAX_LOGGING, (void *) &sp_xmax_tmax);
+
+    if (!payloadSize) {
+        PAL_ERR(LOG_TAG, "Payload memory allocation failed");
+        ret = -EINVAL;
+        goto exit;
+    }
+
+    ret = mixer_ctl_set_array(ctl, payload, payloadSize);
+    if (0 != ret) {
+        PAL_ERR(LOG_TAG, "Set failed with return value = %d", ret);
+        goto exit;
+    }
+
+    memset(payload, 0, payloadSize);
+
+    ret = mixer_ctl_get_array(ctl, payload, payloadSize);
+    if (0 != ret) {
+        PAL_ERR(LOG_TAG, "Get failed with return value = %d", ret);
+        goto exit;
+    }
+    else {
+        sp_xmax_tmax_value = (param_id_sp_tmax_xmax_logging_t*)(payload +
+            sizeof(struct apm_module_param_data_t));
+        fp = fopen(PAL_SP_XMAX_TMAX_DATA_PATH, "a");
+
+        if (!fp) {
+            PAL_ERR(LOG_TAG, "Unable to open file for write");
+            ret = -EBADF;
+            goto exit;
+        }
+        else {
+            num_ch = sp_xmax_tmax_value->num_ch;
+            auto currentTime = std::chrono::system_clock::now();
+            std::time_t currentTimeT = std::chrono::system_clock::to_time_t(currentTime);
+            const char* currentTimeStr = std::ctime(&currentTimeT);
+            stringLen = std::strlen(currentTimeStr);
+
+            PAL_DBG(LOG_TAG, "Current Timestamp : %s and size of string : %d", currentTimeStr, stringLen);
+            bytesWritten = fprintf(fp, "%s ", currentTimeStr);
+
+            if (bytesWritten < 0) {
+                PAL_ERR(LOG_TAG, "Error in writing to file");
+                fclose(fp);
+                ret = -EBADF;
+                goto exit;
+            }
+
+            for (int i = 0; i < num_ch; i++) {
+                PAL_DBG(LOG_TAG, "Channel: %d, Max Excursion Value =%d",i, sp_xmax_tmax_value->tmax_xmax_params[i].max_excursion);
+                bytesWritten = fprintf(fp, "Ch: %d <Xmax> : %3.4f", i, (float)sp_xmax_tmax_value->tmax_xmax_params[i].max_excursion / (1 << 27));
+
+                if (bytesWritten < 0) {
+                    PAL_ERR(LOG_TAG, "Error in writing to file");
+                    fclose(fp);
+                    ret = -EBADF;
+                    goto exit;
+                }
+
+                PAL_DBG(LOG_TAG, "Channel: %d, Max Temperature Value =%d",i, sp_xmax_tmax_value->tmax_xmax_params[i].max_temperature);
+                bytesWritten = fprintf(fp, " <Tmax> : %3.4f ", (float)sp_xmax_tmax_value->tmax_xmax_params[i].max_temperature / (1 << 22));
+
+                if (bytesWritten < 0) {
+                    PAL_ERR(LOG_TAG, "Error in writing to file");
+                    fclose(fp);
+                    ret = -EBADF;
+                    goto exit;
+                }
+            }
+            bytesWritten = fprintf(fp, "\n");
+            if (bytesWritten < 0) {
+                PAL_ERR(LOG_TAG, "Error in writing to file");
+                fclose(fp);
+                ret = -EBADF;
+                goto exit;
+            }
+            fclose(fp);
+        }
+    }
+exit:
+    if (builder) {
+        delete builder;
+        builder = NULL;
+    }
+    return ret;
+
+}
+
+void SpeakerProtection::startSpkrXmaxTmaxLogging()
+{
+    FILE* log_fp = NULL;
+    int32_t ret = 0;
+
+    PAL_DBG(LOG_TAG, "Enter");
+
+    /* This condition is added to know if the Speaker_RX graph started or not.
+     * Assuming this file will be pushed to target after playback started
+     * That's how, we will be sure Speaker_RX graph has been started */
+
+    while (!log_fp) {
+        log_fp = fopen(PAL_SP_XMAX_TMAX_LOG_PATH, "rb");
+    }
+    fclose(log_fp);
+
+    if (remove(PAL_SP_XMAX_TMAX_LOG_PATH) == 0) {
+        PAL_DBG(LOG_TAG, "log_spkr_xmax_tmax file deleted successfully");
+    }
+
+    startXmaxLogging = true;
+    while (startXmaxLogging && (ret == 0)) {
+        ret = getSpkrXmaxTmaxData();
+        if (ret != 0) {
+            PAL_ERR(LOG_TAG, "Failed to get Param for spkr_xmax_tmax");
+        }
+        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
+    }
+}
+
 /*
  * CPS related custom payload
  */
@@ -2471,6 +2655,11 @@
                 }
             }
         }
+
+        if (ResourceManager::isSpkrXmaxTmaxLoggingEnabled) {
+            XmaxTmaxLogThread = std::thread(&SpeakerProtection::startSpkrXmaxTmaxLogging,
+                this);
+        }
         // Free up the local variables
         goto exit;
     }
@@ -2486,6 +2675,8 @@
         }
         spkrProtSetSpkrStatus(flag);
         // Speaker not in use anymore. Stop the processing mode
+        startXmaxLogging = false;
+
         PAL_DBG(LOG_TAG, "Closing VI path");
         if (txPcm) {
             rm = ResourceManager::getInstance();
@@ -2652,7 +2843,7 @@
     }
     stream = static_cast<Stream *>(activeStreams[0]);
     stream->getAssociatedSession(&session);
-    for (int ch = numberOfChannels; ch != 0; ch >> ch/CHANNELS_2) {
+    for (int ch = numberOfChannels; ch != 0; ch == ch >> CHANNELS_2) {
         if (ch == CHANNELS_4)
             tagid = MODULE_SP2;
         else {
@@ -2808,7 +2999,7 @@
         goto exit;
     }
 
-    for (int ch = numberOfChannels; ch != 0; ch >> ch/CHANNELS_2) {
+    for (int ch = numberOfChannels; ch != 0; ch == ch >> CHANNELS_2) {
 
         if (ch == CHANNELS_4)
             tagid = MODULE_VI2;
diff --git a/device/src/USBAudio.cpp b/device/src/USBAudio.cpp
index 5c40793..a27fd25 100644
--- a/device/src/USBAudio.cpp
+++ b/device/src/USBAudio.cpp
@@ -508,13 +508,13 @@
         check = true;
 
     while (str_start != NULL) {
-        str_start = strstr(str_start, "Altset");
+        str_start = strstr(str_start, "Altset ");
         if ((str_start == NULL) || (check  && (str_start >= str_end))) {
             PAL_VERBOSE(LOG_TAG,"done parsing %s\n", str_start);
             break;
         }
         PAL_VERBOSE(LOG_TAG,"remaining string %s\n", str_start);
-        str_start += sizeof("Altset");
+        str_start += sizeof("Altset ");
         std::shared_ptr<USBDeviceConfig> usb_device_info(new USBDeviceConfig());
         if (!usb_device_info) {
             PAL_ERR(LOG_TAG, "error unable to create usb device config object");
@@ -524,7 +524,7 @@
         usb_device_info->setType(type);
         /* Bit bit_width parsing */
         bit_width_start = strstr(str_start, "Format: ");
-        if (bit_width_start == NULL) {
+        if (bit_width_start == NULL || (check && (bit_width_start >= str_end))) {
             PAL_INFO(LOG_TAG, "Could not find bit_width string");
             continue;
         }
@@ -558,7 +558,7 @@
 
         /* channels parsing */
         channel_start = strstr(str_start, CHANNEL_NUMBER_STR);
-        if (channel_start == NULL) {
+        if (channel_start == NULL || (check && (channel_start >= str_end))) {
             PAL_INFO(LOG_TAG, "could not find Channels string");
             continue;
         }
@@ -567,7 +567,7 @@
 
         /* Sample rates parsing */
         rates_str_start = strstr(str_start, "Rates: ");
-        if (rates_str_start == NULL) {
+        if (rates_str_start == NULL || (check && (rates_str_start >= str_end))) {
             PAL_INFO(LOG_TAG, "cant find rates string");
             continue;
         }
@@ -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/ipc/HwBinders/pal_ipc_client/src/pal_client_wrapper.cpp b/ipc/HwBinders/pal_ipc_client/src/pal_client_wrapper.cpp
index 894da97..b0bf840 100644
--- a/ipc/HwBinders/pal_ipc_client/src/pal_client_wrapper.cpp
+++ b/ipc/HwBinders/pal_ipc_client/src/pal_client_wrapper.cpp
@@ -351,12 +351,11 @@
         if (pal_client == nullptr)
             return ret;
 
-        hidl_vec<PalStreamAttributes> attr_hidl;
+        hidl_vec<PalStreamAttributes> attr_hidl(1);
         hidl_vec<PalDevice> devs_hidl;
         hidl_vec<ModifierKV> modskv_hidl;
         uint16_t in_channels = 0;
         uint16_t out_channels = 0;
-        uint32_t dev_size = 0;
         int cnt = 0;
         uint8_t *temp = NULL;
         struct pal_stream_info info = attr->info.opt_stream_info;
@@ -367,8 +366,6 @@
             info.version, info.size, info.duration_us, info.has_video, info.is_streaming,
             info.loopback_type);
 
-        attr_hidl.resize(sizeof(::vendor::qti::hardware::pal::V1_0::PalStreamAttributes) + in_channels +
-                         out_channels);
         attr_hidl.data()->type = (PalStreamType)attr->type;
         attr_hidl.data()->info.version = info.version;
         attr_hidl.data()->info.size = info.size;
@@ -382,7 +379,8 @@
 
         if (in_channels) {
             attr_hidl.data()->in_media_config.ch_info.channels = attr->in_media_config.ch_info.channels;
-            attr_hidl.data()->in_media_config.ch_info.ch_map = attr->in_media_config.ch_info.ch_map;
+            memcpy(&attr_hidl.data()->in_media_config.ch_info.ch_map, &attr->in_media_config.ch_info.ch_map,
+                sizeof(uint8_t[64]));
         }
         attr_hidl.data()->in_media_config.aud_fmt_id = (PalAudioFmt)attr->in_media_config.aud_fmt_id;
 
@@ -394,26 +392,28 @@
         attr_hidl.data()->out_media_config.bit_width = attr->out_media_config.bit_width;
         if (out_channels) {
             attr_hidl.data()->out_media_config.ch_info.channels = attr->out_media_config.ch_info.channels;
-            attr_hidl.data()->out_media_config.ch_info.ch_map = attr->out_media_config.ch_info.ch_map;
+            memcpy(&attr_hidl.data()->out_media_config.ch_info.ch_map, &attr->out_media_config.ch_info.ch_map,
+                sizeof(uint8_t[64]));
         }
         attr_hidl.data()->out_media_config.aud_fmt_id = (PalAudioFmt)attr->out_media_config.aud_fmt_id;
         if (devices) {
-            dev_size = no_of_devices * sizeof(struct pal_device);
-            devs_hidl.resize(dev_size);
-            PalDevice *dev_hidl = devs_hidl.data();
+            devs_hidl.resize(no_of_devices);
             for ( cnt = 0; cnt < no_of_devices; cnt++) {
-                 dev_hidl->id =(PalDeviceId)devices[cnt].id;
-                 dev_hidl->config.sample_rate = devices[cnt].config.sample_rate;
-                 dev_hidl->config.bit_width = devices[cnt].config.bit_width;
-                 dev_hidl->config.ch_info.channels = devices[cnt].config.ch_info.channels;
-                 dev_hidl->config.ch_info.ch_map = devices[cnt].config.ch_info.ch_map;
-                 dev_hidl->config.aud_fmt_id = (PalAudioFmt)devices[cnt].config.aud_fmt_id;
-                 dev_hidl =  (PalDevice *)(devs_hidl.data() + sizeof(PalDevice));
+                 devs_hidl[cnt].id =(PalDeviceId)devices[cnt].id;
+                 devs_hidl[cnt].config.sample_rate = devices[cnt].config.sample_rate;
+                 devs_hidl[cnt].config.bit_width = devices[cnt].config.bit_width;
+                 devs_hidl[cnt].config.ch_info.channels = devices[cnt].config.ch_info.channels;
+                 memcpy(&devs_hidl[cnt].config.ch_info.ch_map, &devices[cnt].config.ch_info.ch_map,
+                 sizeof(uint8_t [64]));
+                 devs_hidl[cnt].config.aud_fmt_id = (PalAudioFmt)devices[cnt].config.aud_fmt_id;
             }
         }
         if (modifiers) {
-            modskv_hidl.resize(sizeof(struct modifier_kv) * no_of_modifiers);
-            memcpy(modskv_hidl.data(), modifiers, sizeof(struct modifier_kv) * no_of_modifiers);
+            modskv_hidl.resize(no_of_modifiers);
+            for ( cnt = 0; cnt < no_of_modifiers; cnt++) {
+                modskv_hidl[cnt].key = modifiers[cnt].key;
+                modskv_hidl[cnt].value = modifiers[cnt].value;
+            } 
         }
         pal_client->ipc_pal_stream_open(attr_hidl, no_of_devices, devs_hidl, no_of_modifiers,
                                         modskv_hidl, ClbkBinder, cookie,
@@ -713,8 +713,7 @@
         if (pal_client == nullptr)
             return ret;
 
-        hidl_vec<PalParamPayload> paramPayload;
-        paramPayload.resize(sizeof(PalParamPayload));
+        hidl_vec<PalParamPayload> paramPayload(1);
         paramPayload.data()->payload.resize(param_payload->payload_size);
         paramPayload.data()->size = param_payload->payload_size;
         memcpy(paramPayload.data()->payload.data(), param_payload->payload,
@@ -778,7 +777,6 @@
 {
     hidl_vec<PalDevice> devs_hidl;
     int32_t cnt = 0;
-    uint32_t dev_size = 0;
     int32_t ret = -EINVAL;
 
     if (!pal_server_died) {
@@ -789,18 +787,16 @@
 
 
         if (devices) {
-           dev_size = no_of_devices * sizeof(struct pal_device);
-           ALOGD("dev_size %d", dev_size);
-           devs_hidl.resize(dev_size);
-           PalDevice *dev_hidl = devs_hidl.data();
+           ALOGD("no_of_devices %d", no_of_devices);
+           devs_hidl.resize(no_of_devices);
            for (cnt = 0; cnt < no_of_devices; cnt++) {
-                dev_hidl->id =(PalDeviceId)devices[cnt].id;
-                dev_hidl->config.sample_rate = devices[cnt].config.sample_rate;
-                dev_hidl->config.bit_width = devices[cnt].config.bit_width;
-                dev_hidl->config.ch_info.channels = devices[cnt].config.ch_info.channels;
-                dev_hidl->config.ch_info.ch_map = devices[cnt].config.ch_info.ch_map;
-                dev_hidl->config.aud_fmt_id = (PalAudioFmt)devices[cnt].config.aud_fmt_id;
-                dev_hidl =  (PalDevice *)(devs_hidl.data() + sizeof(PalDevice));
+                devs_hidl[cnt].id =(PalDeviceId)devices[cnt].id;
+                devs_hidl[cnt].config.sample_rate = devices[cnt].config.sample_rate;
+                devs_hidl[cnt].config.bit_width = devices[cnt].config.bit_width;
+                devs_hidl[cnt].config.ch_info.channels = devices[cnt].config.ch_info.channels;
+                memcpy(&devs_hidl[cnt].config.ch_info.ch_map, &devices[cnt].config.ch_info.ch_map,
+                sizeof(uint8_t [64]));
+                devs_hidl[cnt].config.aud_fmt_id = (PalAudioFmt)devices[cnt].config.aud_fmt_id;
            }
            ret = pal_client->ipc_pal_stream_set_device((PalStreamHandle)stream_handle,
                                                        no_of_devices, devs_hidl);
@@ -820,7 +816,7 @@
 int32_t pal_stream_set_volume(pal_stream_handle_t *stream_handle,
                               struct pal_volume_data *volume)
 {
-    hidl_vec<PalVolumeData> vol;
+    hidl_vec<PalVolumeData> vol(1);
     int32_t ret = -EINVAL;
     if (volume == NULL) {
        ALOGE("Invalid volume");
@@ -833,8 +829,6 @@
             return ret;
 
         uint32_t noOfVolPair = volume->no_of_volpair;
-        uint32_t volSize = sizeof(PalVolumeData);
-        vol.resize(volSize);
         vol.data()->volPair.resize(sizeof(PalChannelVolKv) * noOfVolPair);
         vol.data()->noOfVolPairs = noOfVolPair;
         memcpy(vol.data()->volPair.data(), volume->volume_pair,
diff --git a/ipc/HwBinders/pal_ipc_server/src/pal_server_wrapper.cpp b/ipc/HwBinders/pal_ipc_server/src/pal_server_wrapper.cpp
index 31dddf4..ba2ee12 100644
--- a/ipc/HwBinders/pal_ipc_server/src/pal_server_wrapper.cpp
+++ b/ipc/HwBinders/pal_ipc_server/src/pal_server_wrapper.cpp
@@ -510,24 +510,22 @@
     }
 
     if (devs_hidl.size()) {
-        PalDevice *dev_hidl = NULL;
         devices = (struct pal_device *)calloc (1,
                                       sizeof(struct pal_device) * noOfDevices);
         if (!devices) {
             ALOGE("Not enough memory for devices");
             goto exit;
         }
-        dev_hidl = (PalDevice *)devs_hidl.data();
+
         for ( cnt = 0; cnt < noOfDevices; cnt++) {
-             devices[cnt].id = (pal_device_id_t)dev_hidl->id;
-             devices[cnt].config.sample_rate = dev_hidl->config.sample_rate;
-             devices[cnt].config.bit_width = dev_hidl->config.bit_width;
-             devices[cnt].config.ch_info.channels = dev_hidl->config.ch_info.channels;
-             memcpy(&devices[cnt].config.ch_info.ch_map, &dev_hidl->config.ch_info.ch_map,
+             devices[cnt].id = (pal_device_id_t)devs_hidl[cnt].id;
+             devices[cnt].config.sample_rate = devs_hidl[cnt].config.sample_rate;
+             devices[cnt].config.bit_width = devs_hidl[cnt].config.bit_width;
+             devices[cnt].config.ch_info.channels = devs_hidl[cnt].config.ch_info.channels;
+             memcpy(&devices[cnt].config.ch_info.ch_map, &devs_hidl[cnt].config.ch_info.ch_map,
                     sizeof(uint8_t [64]));
              devices[cnt].config.aud_fmt_id =
-                                  (pal_audio_fmt_t)dev_hidl->config.aud_fmt_id;
-             dev_hidl =  (PalDevice *)(dev_hidl + sizeof(PalDevice));
+                                  (pal_audio_fmt_t)devs_hidl[cnt].config.aud_fmt_id;
         }
     }
 
@@ -825,6 +823,14 @@
 {
     int32_t ret = 0;
     pal_param_payload *param_payload;
+    if (1 != paramPayload.size()) {
+        ALOGE("Invalid vector size");
+        return -EINVAL;
+    }
+    if (paramPayload.data()->size > paramPayload.data()->payload.size()) {
+        ALOGE("Invalid payload size");
+        return -EINVAL;
+    }
     param_payload = (pal_param_payload *)calloc (1,
                                     sizeof(pal_param_payload) + paramPayload.data()->size);
     if (!param_payload) {
@@ -873,25 +879,28 @@
     struct pal_device *devices = NULL;
     int cnt = 0;
     int32_t ret = -ENOMEM;
+
+    if (noOfDevices > devs_hidl.size()) {
+        ALOGE("Invalid noOfDevices");
+        return -EINVAL;
+    }
     if (devs_hidl.size()) {
-        PalDevice *dev_hidl = NULL;
         devices = (struct pal_device *)calloc (1,
                                     sizeof(struct pal_device) * noOfDevices);
         if (!devices) {
             ALOGE("Not enough memory for devices");
             goto exit;
         }
-        dev_hidl = (PalDevice *)devs_hidl.data();
+
         for (cnt = 0; cnt < noOfDevices; cnt++) {
-            devices[cnt].id = (pal_device_id_t)dev_hidl->id;
-            devices[cnt].config.sample_rate = dev_hidl->config.sample_rate;
-            devices[cnt].config.bit_width = dev_hidl->config.bit_width;
-            devices[cnt].config.ch_info.channels = dev_hidl->config.ch_info.channels;
-            memcpy(&devices[cnt].config.ch_info.ch_map, &dev_hidl->config.ch_info.ch_map,
+            devices[cnt].id = (pal_device_id_t)devs_hidl[cnt].id;
+            devices[cnt].config.sample_rate = devs_hidl[cnt].config.sample_rate;
+            devices[cnt].config.bit_width = devs_hidl[cnt].config.bit_width;
+            devices[cnt].config.ch_info.channels = devs_hidl[cnt].config.ch_info.channels;
+            memcpy(&devices[cnt].config.ch_info.ch_map, &devs_hidl[cnt].config.ch_info.ch_map,
                    sizeof(uint8_t [64]));
             devices[cnt].config.aud_fmt_id =
-                                (pal_audio_fmt_t)dev_hidl->config.aud_fmt_id;
-            dev_hidl = (PalDevice *)(dev_hidl + sizeof(PalDevice));
+                                (pal_audio_fmt_t)devs_hidl[cnt].config.aud_fmt_id;
         }
     }
 
diff --git a/resource_manager/inc/ResourceManager.h b/resource_manager/inc/ResourceManager.h
index a16e844..5e01198 100644
--- a/resource_manager/inc/ResourceManager.h
+++ b/resource_manager/inc/ResourceManager.h
@@ -45,6 +45,7 @@
 #include "PalCommon.h"
 #include <array>
 #include <map>
+#include <set>
 #include <expat.h>
 #include <stdio.h>
 #include <queue>
@@ -82,6 +83,7 @@
 #define AUDIO_PARAMETER_KEY_DEVICE_MUX "device_mux_config"
 #define AUDIO_PARAMETER_KEY_UPD_DUTY_CYCLE "upd_duty_cycle_enable"
 #define AUDIO_PARAMETER_KEY_UPD_VIRTUAL_PORT "upd_virtual_port"
+#define AUDIO_PARAMETER_KEY_SPKR_XMAX_TMAX_LOG "spkr_xmax_tmax_logging_enable"
 #define MAX_PCM_NAME_SIZE 50
 #define MAX_STREAM_INSTANCES (sizeof(uint64_t) << 3)
 #define MIN_USECASE_PRIORITY 0xFFFFFFFF
@@ -507,6 +509,7 @@
     static std::mutex mResourceManagerMutex;
     static std::mutex mGraphMutex;
     static std::mutex mActiveStreamMutex;
+    static std::mutex mValidStreamMutex;
     static std::mutex mSleepMonitorMutex;
     static std::mutex mListFrontEndsMutex;
     static int snd_virt_card;
@@ -621,6 +624,8 @@
     /* Variable to store which speaker side is being used for call audio.
      * Valid for Stereo case only
      */
+    /*Variable to check XmaxTmaxLogging Enabled or not*/
+    static bool isSpkrXmaxTmaxLoggingEnabled;
     static bool isMainSpeakerRight;
     /* Variable to store Quick calibration time for Speaker protection */
     static int spQuickCalTime;
@@ -913,6 +918,7 @@
     static int setDualMonoEnableParam(struct str_parms *parms,char *value, int len);
     static int setSignalHandlerEnableParam(struct str_parms *parms,char *value, int len);
     static int setMuxconfigEnableParam(struct str_parms *parms,char *value, int len);
+    static int setSpkrXmaxTmaxLoggingParam(struct str_parms* parms, char* value, int len);
     static bool isLpiLoggingEnabled();
     static void processConfigParams(const XML_Char **attr);
     static bool isValidDevId(int deviceId);
@@ -926,6 +932,7 @@
     bool isDeviceAvailable(pal_device_id_t id);
     bool isDeviceAvailable(std::vector<std::shared_ptr<Device>> devices, pal_device_id_t id);
     bool isDeviceAvailable(struct pal_device *devices, uint32_t devCount, pal_device_id_t id);
+    bool isDisconnectedDeviceStillActive(std::set<pal_device_id_t> &curPalDevices, std::set<pal_device_id_t> &activeDevices, pal_device_id_t id);
     bool isDeviceReady(pal_device_id_t id);
     static bool isBtScoDevice(pal_device_id_t id);
     static bool isBtDevice(pal_device_id_t id);
@@ -944,6 +951,8 @@
     void unlockGraph() { mGraphMutex.unlock(); };
     void lockActiveStream() { mActiveStreamMutex.lock(); };
     void unlockActiveStream() { mActiveStreamMutex.unlock(); };
+    void lockValidStreamMutex() { mValidStreamMutex.lock(); };
+    void unlockValidStreamMutex() { mValidStreamMutex.unlock(); };
     void lockResourceManagerMutex() {mResourceManagerMutex.lock();};
     void unlockResourceManagerMutex() {mResourceManagerMutex.unlock();};
     void getSharedBEActiveStreamDevs(std::vector <std::tuple<Stream *, uint32_t>> &activeStreamDevs,
diff --git a/resource_manager/src/ResourceManager.cpp b/resource_manager/src/ResourceManager.cpp
index 91352d7..45077e0 100644
--- a/resource_manager/src/ResourceManager.cpp
+++ b/resource_manager/src/ResourceManager.cpp
@@ -428,6 +428,7 @@
 std::mutex ResourceManager::mChargerBoostMutex;
 std::mutex ResourceManager::mGraphMutex;
 std::mutex ResourceManager::mActiveStreamMutex;
+std::mutex ResourceManager::mValidStreamMutex;
 std::mutex ResourceManager::mSleepMonitorMutex;
 std::mutex ResourceManager::mListFrontEndsMutex;
 std::vector <int> ResourceManager::listAllFrontEndIds = {0};
@@ -483,6 +484,7 @@
 int ResourceManager::wake_unlock_fd = -1;
 uint32_t ResourceManager::wake_lock_cnt = 0;
 static int max_session_num;
+bool ResourceManager::isSpkrXmaxTmaxLoggingEnabled = false;
 bool ResourceManager::isSpeakerProtectionEnabled = false;
 bool ResourceManager::isHandsetProtectionEnabled = false;
 bool ResourceManager::isChargeConcurrencyEnabled = false;
@@ -1295,7 +1297,9 @@
                 PAL_INFO(LOG_TAG, "%d state already handled", state);
             } else if (state == CARD_STATUS_OFFLINE) {
                 for (auto str: rm->mActiveStreams) {
+                    lockValidStreamMutex();
                     ret = increaseStreamUserCounter(str);
+                    unlockValidStreamMutex();
                     if (0 != ret) {
                         PAL_ERR(LOG_TAG, "Error incrementing the stream counter for the stream handle: %pK", str);
                         continue;
@@ -1311,7 +1315,9 @@
                         if (ret)
                             PAL_DBG(LOG_TAG, "Failed to unvote for stream type %d", type);
                     }
+                    lockValidStreamMutex();
                     ret = decreaseStreamUserCounter(str);
+                    unlockValidStreamMutex();
                     if (0 != ret) {
                         PAL_ERR(LOG_TAG, "Error decrementing the stream counter for the stream handle: %pK", str);
                     }
@@ -1337,7 +1343,9 @@
 
                 SoundTriggerCaptureProfile = GetCaptureProfileByPriority(nullptr);
                 for (auto str: rm->mActiveStreams) {
+                    lockValidStreamMutex();
                     ret = increaseStreamUserCounter(str);
+                    unlockValidStreamMutex();
                     if (0 != ret) {
                         PAL_ERR(LOG_TAG, "Error incrementing the stream counter for the stream handle: %pK", str);
                         continue;
@@ -1347,7 +1355,9 @@
                         PAL_ERR(LOG_TAG, "Ssr up handling failed for %pK ret %d",
                                           str, ret);
                     }
+                    lockValidStreamMutex();
                     ret = decreaseStreamUserCounter(str);
+                    unlockValidStreamMutex();
                     if (0 != ret) {
                         PAL_ERR(LOG_TAG, "Error decrementing the stream counter for the stream handle: %pK", str);
                     }
@@ -1762,8 +1772,10 @@
         return ret;
     }
 
-    lpi_stream = (sleep_monitor_vote_type_[type] == LPI_VOTE &&
-                 !IsTransitToNonLPIOnChargingSupported() && (!force_nlpi_vote));
+    if (sleep_monitor_vote_type_[type] == LPI_VOTE) {
+        lpi_stream = (!force_nlpi_vote && str->ConfigSupportLPI() &&
+                      !IsTransitToNonLPIOnChargingSupported());
+    }
 
     mSleepMonitorMutex.lock();
     if (vote) {
@@ -2683,8 +2695,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",
@@ -3073,6 +3085,7 @@
     }
     PAL_DBG(LOG_TAG, "stream type %d", type);
     mActiveStreamMutex.lock();
+    mValidStreamMutex.lock();
     switch (type) {
         case PAL_STREAM_LOW_LATENCY:
         case PAL_STREAM_VOIP_RX:
@@ -3213,7 +3226,7 @@
 
     mAllActiveStreams.push_back(s);
 #endif
-
+    mValidStreamMutex.unlock();
     mActiveStreamMutex.unlock();
     PAL_DBG(LOG_TAG, "Exit. ret %d", ret);
     return ret;
@@ -3252,6 +3265,7 @@
 #endif
     PAL_INFO(LOG_TAG, "stream type %d", type);
     mActiveStreamMutex.lock();
+    mValidStreamMutex.lock();
     switch (type) {
         case PAL_STREAM_LOW_LATENCY:
         case PAL_STREAM_VOIP_RX:
@@ -3382,6 +3396,7 @@
     }
 
     deregisterstream(s, mActiveStreams);
+    mValidStreamMutex.unlock();
     mActiveStreamMutex.unlock();
 exit:
     PAL_DBG(LOG_TAG, "Exit. ret %d", ret);
@@ -3415,30 +3430,30 @@
 
 int ResourceManager::initStreamUserCounter(Stream *s)
 {
-    lockActiveStream();
+    lockValidStreamMutex();
     mActiveStreamUserCounter.insert(std::make_pair(s, std::make_pair(0, true)));
     s->initStreamSmph();
-    unlockActiveStream();
+    unlockValidStreamMutex();
     return 0;
 }
 
 int ResourceManager::deactivateStreamUserCounter(Stream *s)
 {
     std::map<Stream*, std::pair<uint32_t, bool>>::iterator it;
-    lockActiveStream();
+    lockValidStreamMutex();
     printStreamUserCounter(s);
     it = mActiveStreamUserCounter.find(s);
     if (it != mActiveStreamUserCounter.end() && it->second.second == true) {
         PAL_DBG(LOG_TAG, "stream %p is to be deactivated.", s);
         it->second.second = false;
-        unlockActiveStream();
+        unlockValidStreamMutex();
         s->waitStreamSmph();
         PAL_DBG(LOG_TAG, "stream %p is inactive.", s);
         s->deinitStreamSmph();
         return 0;
     } else {
         PAL_ERR(LOG_TAG, "stream %p is not found or inactive", s);
-        unlockActiveStream();
+        unlockValidStreamMutex();
         return -EINVAL;
     }
 }
@@ -3446,16 +3461,16 @@
 int ResourceManager::eraseStreamUserCounter(Stream *s)
 {
     std::map<Stream*, std::pair<uint32_t, bool>>::iterator it;
-    lockActiveStream();
+    lockValidStreamMutex();
     it = mActiveStreamUserCounter.find(s);
     if (it != mActiveStreamUserCounter.end()) {
         mActiveStreamUserCounter.erase(it);
         PAL_DBG(LOG_TAG, "stream counter for %p is erased.", s);
-        unlockActiveStream();
+        unlockValidStreamMutex();
         return 0;
     } else {
         PAL_ERR(LOG_TAG, "stream counter for %p is not found.", s);
-        unlockActiveStream();
+        unlockValidStreamMutex();
         return -EINVAL;
     }
 }
@@ -4999,7 +5014,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;
         }
@@ -7815,6 +7830,7 @@
     ret = setMuxconfigEnableParam(parms, value, len);
     ret = setUpdDutyCycleEnableParam(parms, value, len);
     ret = setUpdVirtualPortParam(parms, value, len);
+    ret = setSpkrXmaxTmaxLoggingParam(parms, value, len);
 
     /* Not checking return value as this is optional */
     setLpiLoggingParams(parms, value, len);
@@ -7953,6 +7969,29 @@
     return ret;
 }
 
+int ResourceManager::setSpkrXmaxTmaxLoggingParam(struct str_parms* parms,
+    char* value, int len)
+{
+    int ret = -EINVAL;
+
+    if (!value || !parms) {
+        return ret;
+    }
+
+    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SPKR_XMAX_TMAX_LOG,
+        value, len);
+    PAL_VERBOSE(LOG_TAG, " value %s", value);
+
+    if (ret >= 0) {
+        if (value && !strncmp(value, "true", sizeof("true")))
+            ResourceManager::isSpkrXmaxTmaxLoggingEnabled = true;
+
+        str_parms_del(parms, AUDIO_PARAMETER_KEY_SPKR_XMAX_TMAX_LOG);
+    }
+
+    return ret;
+}
+
 int ResourceManager::setUpdVirtualPortParam(struct str_parms *parms, char *value, int len)
 {
     int ret = -EINVAL;
@@ -7962,8 +8001,7 @@
 
     ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_UPD_VIRTUAL_PORT,
                             value, len);
-
-    PAL_VERBOSE(LOG_TAG," value %s", value);
+    PAL_VERBOSE(LOG_TAG, " value %s", value);
 
     if (ret >= 0) {
         if (value && !strncmp(value, "true", sizeof("true")))
@@ -8718,82 +8756,29 @@
         case PAL_PARAM_ID_BT_A2DP_RECONFIG_SUPPORTED:
         case PAL_PARAM_ID_BT_A2DP_SUSPENDED:
         case PAL_PARAM_ID_BT_A2DP_ENCODER_LATENCY:
-        {
-            std::shared_ptr<Device> dev = nullptr;
-            struct pal_device dattr;
-            pal_param_bta2dp_t *param_bt_a2dp = nullptr;
-
-            if (isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_A2DP)) {
-                dattr.id = PAL_DEVICE_OUT_BLUETOOTH_A2DP;
-            } else if (isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_BLE)) {
-                dattr.id = PAL_DEVICE_OUT_BLUETOOTH_BLE;
-            } else if (isDeviceAvailable(PAL_DEVICE_OUT_BLUETOOTH_BLE_BROADCAST)) {
-                dattr.id = PAL_DEVICE_OUT_BLUETOOTH_BLE_BROADCAST;
-            } else {
-                goto exit;
-            }
-            dev = Device::getInstance(&dattr , rm);
-            if (dev) {
-                status = dev->getDeviceParameter(param_id, (void **)&param_bt_a2dp);
-                if (status) {
-                    PAL_ERR(LOG_TAG, "get Parameter %d failed\n", param_id);
-                    goto exit;
-                }
-                *param_payload = param_bt_a2dp;
-                *payload_size = sizeof(pal_param_bta2dp_t);
-            }
-            break;
-        }
         case PAL_PARAM_ID_BT_A2DP_CAPTURE_SUSPENDED:
-        {
-            std::shared_ptr<Device> dev = nullptr;
-            struct pal_device dattr;
-            pal_param_bta2dp_t *param_bt_a2dp = nullptr;
-
-            if (isDeviceAvailable(PAL_DEVICE_IN_BLUETOOTH_A2DP)) {
-                dattr.id = PAL_DEVICE_IN_BLUETOOTH_A2DP;
-            } else if (isDeviceAvailable(PAL_DEVICE_IN_BLUETOOTH_BLE)) {
-                dattr.id = PAL_DEVICE_IN_BLUETOOTH_BLE;
-            } else {
-                goto exit;
-            }
-            dev = Device::getInstance(&dattr , rm);
-            if (dev) {
-                status = dev->getDeviceParameter(param_id, (void **)&param_bt_a2dp);
-                if (status) {
-                    PAL_ERR(LOG_TAG, "get Parameter %d failed\n", param_id);
-                    goto exit;
-                }
-                *param_payload = param_bt_a2dp;
-                *payload_size = sizeof(pal_param_bta2dp_t);
-            }
-            break;
-        }
         case PAL_PARAM_ID_BT_A2DP_DECODER_LATENCY:
         {
             std::shared_ptr<Device> dev = nullptr;
             struct pal_device dattr;
             pal_param_bta2dp_t* param_bt_a2dp = nullptr;
 
-            if (isDeviceAvailable(PAL_DEVICE_IN_BLUETOOTH_A2DP)) {
-                dattr.id = PAL_DEVICE_IN_BLUETOOTH_A2DP;
-            } else if (isDeviceAvailable(PAL_DEVICE_IN_BLUETOOTH_BLE)) {
-                dattr.id = PAL_DEVICE_IN_BLUETOOTH_BLE;
+            if (isDeviceAvailable((*(pal_param_bta2dp_t**)param_payload)->dev_id)) {
+                dattr.id = (*(pal_param_bta2dp_t**)param_payload)->dev_id;
             } else {
                 goto exit;
             }
+
             dev = Device::getInstance(&dattr, rm);
-            if (!dev) {
-                PAL_ERR(LOG_TAG, "Failed to get device instance");
-                goto exit;
+            if (dev) {
+                status = dev->getDeviceParameter(param_id, (void**)&param_bt_a2dp);
+                if (status) {
+                    PAL_ERR(LOG_TAG, "get Parameter %d failed\n", param_id);
+                    goto exit;
+                }
+                *param_payload = param_bt_a2dp;
+                *payload_size = sizeof(pal_param_bta2dp_t);
             }
-            status = dev->getDeviceParameter(param_id, (void**)&param_bt_a2dp);
-            if (status) {
-                PAL_ERR(LOG_TAG, "get Parameter %d failed\n", param_id);
-                goto exit;
-            }
-            *param_payload = param_bt_a2dp;
-            *payload_size = sizeof(pal_param_bta2dp_t);
             break;
         }
         case PAL_PARAM_ID_GAIN_LVL_MAP:
@@ -8894,20 +8879,20 @@
         {
             bool match = false;
             std::list<Stream*>::iterator sIter;
-            lockActiveStream();
+            lockValidStreamMutex();
             for(sIter = mActiveStreams.begin(); sIter != mActiveStreams.end(); sIter++) {
                 match = (*sIter)->checkStreamMatch(pal_device_id, pal_stream_type);
                 if (match) {
                     if (increaseStreamUserCounter(*sIter) < 0)
                         continue;
-                    unlockActiveStream();
+                    unlockValidStreamMutex();
                     status = (*sIter)->getEffectParameters(param_payload);
-                    lockActiveStream();
+                    lockValidStreamMutex();
                     decreaseStreamUserCounter(*sIter);
                     break;
                 }
             }
-            unlockActiveStream();
+            unlockValidStreamMutex();
             break;
         }
         default:
@@ -9256,7 +9241,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) ||
@@ -9307,6 +9293,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) {
@@ -9503,7 +9505,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");
@@ -9822,7 +9825,7 @@
         case PAL_PARAM_ID_UIEFFECT:
         {
             bool match = false;
-            lockActiveStream();
+            lockValidStreamMutex();
             std::list<Stream*>::iterator sIter;
             for(sIter = mActiveStreams.begin(); sIter != mActiveStreams.end();
                     sIter++) {
@@ -9832,9 +9835,9 @@
                     if (match) {
                         if (increaseStreamUserCounter(*sIter) < 0)
                             continue;
-                        unlockActiveStream();
+                        unlockValidStreamMutex();
                         status = (*sIter)->setEffectParameters(param_payload);
-                        lockActiveStream();
+                        lockValidStreamMutex();
                         decreaseStreamUserCounter(*sIter);
                         if (status) {
                             PAL_ERR(LOG_TAG, "failed to set param for pal_device_id=%x stream_type=%x",
@@ -9845,7 +9848,7 @@
                     PAL_ERR(LOG_TAG, "There is no active stream.");
                 }
             }
-            unlockActiveStream();
+            unlockValidStreamMutex();
         }
         break;
         default:
@@ -10537,6 +10540,15 @@
     return isAvailable;
 }
 
+bool ResourceManager::isDisconnectedDeviceStillActive(
+    std::set<pal_device_id_t> &curPalDevices, std::set<pal_device_id_t> &activeDevices,
+    pal_device_id_t id)
+{
+    return (!isDeviceAvailable(id)) &&
+        (curPalDevices.find(id) != curPalDevices.end()) &&
+        (activeDevices.find(id) != activeDevices.end());
+}
+
 bool ResourceManager::isDeviceReady(pal_device_id_t id)
 {
     struct pal_device dAttr;
diff --git a/session/src/PayloadBuilder.cpp b/session/src/PayloadBuilder.cpp
index f995e99..9a8945a 100644
--- a/session/src/PayloadBuilder.cpp
+++ b/session/src/PayloadBuilder.cpp
@@ -27,7 +27,7 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Changes from Qualcomm Innovation Center are provided under the following license:
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted (subject to the limitations in the
@@ -3945,6 +3945,23 @@
                 }
             }
         break;
+        case PARAM_ID_SP_TMAX_XMAX_LOGGING:
+        {
+            param_id_sp_tmax_xmax_logging_t *data;
+            data = (param_id_sp_tmax_xmax_logging_t*)param;
+
+            payloadSize = sizeof(struct apm_module_param_data_t) +
+                sizeof(param_id_sp_tmax_xmax_logging_t) + (sizeof(sp_tmax_xmax_params_t) * data->num_ch);
+
+            padBytes = PAL_PADDING_8BYTE_ALIGN(payloadSize);
+            payloadInfo = (uint8_t*)calloc(1, payloadSize + padBytes);
+            if (!payloadInfo) {
+                PAL_ERR(LOG_TAG, "payloadInfo malloc failed %s", strerror(errno));
+                return;
+            }
+            header = (struct apm_module_param_data_t*)payloadInfo;
+        }
+        break;
         default:
             {
                 PAL_ERR(LOG_TAG, "unknown param id 0x%x", param_id);
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/inc/Stream.h b/stream/inc/Stream.h
index 6385a0e..e7f1b81 100644
--- a/stream/inc/Stream.h
+++ b/stream/inc/Stream.h
@@ -248,6 +248,7 @@
                                    struct pal_mmap_buffer *info __unused) {return -EINVAL;}
     virtual int32_t GetMmapPosition(struct pal_mmap_position *position __unused) {return -EINVAL;}
     virtual int32_t getTagsWithModuleInfo(size_t *size __unused, uint8_t *payload __unused) {return -EINVAL;};
+    virtual bool ConfigSupportLPI() {return true;}; //Only LPI streams can update their vote to NLPI
     int32_t getStreamAttributes(struct pal_stream_attributes *sattr);
     int32_t getModifiers(struct modifier_kv *modifiers,uint32_t *noOfModifiers);
     const std::string& getStreamSelector() const;
diff --git a/stream/inc/StreamSoundTrigger.h b/stream/inc/StreamSoundTrigger.h
index c8cef55..9da6d26 100644
--- a/stream/inc/StreamSoundTrigger.h
+++ b/stream/inc/StreamSoundTrigger.h
@@ -165,6 +165,7 @@
     int32_t EnableLPI(bool is_enable);
     int32_t setECRef(std::shared_ptr<Device> dev, bool is_enable) override;
     int32_t setECRef_l(std::shared_ptr<Device> dev, bool is_enable) override;
+    bool ConfigSupportLPI() override;
     void TransitTo(int32_t state_id);
 
     friend class PalRingBufferReader;
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 8ae6c4a..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;
@@ -3489,6 +3500,20 @@
 
     return status;
 }
+bool StreamSoundTrigger::ConfigSupportLPI() {
+
+    bool lpi = true;
+    bool config_support_lpi = true;
+
+    if (sm_cfg_ && sm_cfg_->GetVUIFirstStageConfig(model_type_))
+        config_support_lpi =
+               sm_cfg_->GetVUIFirstStageConfig(model_type_)->IsLpiSupported();
+
+    if (!config_support_lpi || !vui_ptfm_info_->GetLpiEnable())
+        lpi = false;
+
+    return lpi;
+}
 
 int32_t StreamSoundTrigger::ssrDownHandler() {
     int32_t status = 0;
diff --git a/utils/inc/VoiceUIPlatformInfo.h b/utils/inc/VoiceUIPlatformInfo.h
index a035ed2..dc68035 100644
--- a/utils/inc/VoiceUIPlatformInfo.h
+++ b/utils/inc/VoiceUIPlatformInfo.h
@@ -100,6 +100,7 @@
 
     st_module_type_t GetModuleType() const { return module_type_; }
     std::string GetModuleName() const { return module_name_; }
+    bool IsLpiSupported() const { return lpi_supported_; }
     uint32_t GetModuleTagId(st_param_id_type_t param_id) const {
         return module_tag_ids_[param_id];
     }
@@ -108,6 +109,7 @@
     }
 
 private:
+    bool lpi_supported_;
     st_module_type_t module_type_;
     std::string module_name_;
     uint32_t module_tag_ids_[MAX_PARAM_IDS];
diff --git a/utils/src/VoiceUIPlatformInfo.cpp b/utils/src/VoiceUIPlatformInfo.cpp
index 7fac943..6c70312 100644
--- a/utils/src/VoiceUIPlatformInfo.cpp
+++ b/utils/src/VoiceUIPlatformInfo.cpp
@@ -113,7 +113,8 @@
 
 VUIFirstStageConfig::VUIFirstStageConfig() :
     module_type_(ST_MODULE_TYPE_GMM),
-    module_name_("GMM")
+    module_name_("GMM"),
+    lpi_supported_(true)
 {
     for (int i = 0; i < MAX_PARAM_IDS; i++) {
         module_tag_ids_[i] = 0;
@@ -145,6 +146,8 @@
                 }
                 PAL_DBG(LOG_TAG, "Module name:%s, type:%d",
                         module_name_.c_str(), module_type_);
+            } else if (!strcmp(attribs[i], "lpi_supported")) {
+                lpi_supported_ = !strcmp(attribs[++i], "true");
             } else {
                 uint32_t index = 0;