Merge "st-hal: fix restarting detection after buffer overflow"
diff --git a/sound_trigger_hw.c b/sound_trigger_hw.c
index 11b7274..9a81ec9 100644
--- a/sound_trigger_hw.c
+++ b/sound_trigger_hw.c
@@ -746,7 +746,7 @@
 {
     struct listnode *p_ses_node = NULL;
     st_session_t *p_ses = NULL;
-    bool conc_allowed = false;
+    bool conc_allowed = false, lpi_changed = false, barge_in_mode = false;
     unsigned int num_sessions = 0;
 
     ALOGV_IF(config != NULL, "%s: Enter, event type = %d, audio device = %d",
@@ -836,6 +836,8 @@
                 p_ses = node_to_item(p_ses_node, st_session_t, list_node);
                 st_session_pause(p_ses);
             }
+            pthread_mutex_unlock(&stdev->lock);
+            return;
         } else {
             if (event_type == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE) {
                 list_for_each(p_ses_node, &stdev->sound_model_list) {
@@ -863,26 +865,49 @@
      * configuration which will be used during device backend setting as part
      * of session's start/resume.
      */
-    stdev->lpi_enable = st_hw_check_lpi_support(stdev, p_ses);
+    barge_in_mode = stdev->barge_in_mode;
+    st_hw_check_and_update_lpi(stdev, p_ses);
+    lpi_changed = stdev->lpi_enable != platform_get_lpi_mode(stdev->platform);
     stdev->vad_enable = st_hw_check_vad_support(stdev, p_ses, stdev->lpi_enable);
 
-    if (stdev->lpi_enable != platform_get_lpi_mode(stdev->platform) &&
+    /*
+     * Usecase 1: Playback enabled without display on/battery charging:
+     *            lpi_changed = true, so transition occurs.
+     * Usecase 2: Playback enabled with display on/battery charging:
+     *            lpi_changed = false, and barge_in_mode changes from false to
+     *            true. Dynamic EC update or transition will occur depending
+     *            on the flag.
+     * Usecase 3: Playback disabled without display on/battery charging:
+     *            lpi_changed = true, so transition occurs.
+     * Usecase 4: Playback disabled with display on/battery charging:
+     *            lpi_changed = false, and barge_in_mode changes from true to
+     *            false. Dynamic EC update or transition will occur depending
+     *            on the flag.
+     */
+    if ((lpi_changed || barge_in_mode != stdev->barge_in_mode) &&
         !is_any_session_buffering()) {
-        list_for_each(p_ses_node, &stdev->sound_model_list) {
-            p_ses = node_to_item(p_ses_node, st_session_t, list_node);
-            if (p_ses && p_ses->exec_mode == ST_EXEC_MODE_ADSP) {
-                ALOGD("%s:[%d] LPI: pause SVA session",
-                    __func__, p_ses->sm_handle);
-                st_session_pause(p_ses);
+        if (!lpi_changed && stdev->support_dynamic_ec_update) {
+            platform_stdev_update_ec_effect(stdev->platform,
+                stdev->barge_in_mode);
+        } else {
+            list_for_each(p_ses_node, &stdev->sound_model_list) {
+                p_ses = node_to_item(p_ses_node, st_session_t, list_node);
+                if (p_ses && p_ses->exec_mode == ST_EXEC_MODE_ADSP) {
+                    ALOGD("%s:[%d] LPI: pause SVA session",
+                        __func__, p_ses->sm_handle);
+                    st_session_pause(p_ses);
+                }
             }
-        }
-        platform_stdev_reset_backend_cfg(stdev->platform);
-        list_for_each(p_ses_node, &stdev->sound_model_list) {
-            p_ses = node_to_item(p_ses_node, st_session_t, list_node);
-            if (p_ses && p_ses->exec_mode == ST_EXEC_MODE_ADSP) {
-                ALOGD("%s:[%d] LPI: resume SVA session",
-                    __func__, p_ses->sm_handle);
-                st_session_resume(p_ses);
+
+            platform_stdev_reset_backend_cfg(stdev->platform);
+
+            list_for_each(p_ses_node, &stdev->sound_model_list) {
+                p_ses = node_to_item(p_ses_node, st_session_t, list_node);
+                if (p_ses && p_ses->exec_mode == ST_EXEC_MODE_ADSP) {
+                    ALOGD("%s:[%d] LPI: resume SVA session",
+                        __func__, p_ses->sm_handle);
+                    st_session_resume(p_ses);
+                }
             }
         }
     }
@@ -1088,6 +1113,50 @@
     ALOGV("%s: Exit", __func__);
 }
 
+static void handle_screen_status_change(audio_event_info_t* config)
+{
+    unsigned int num_sessions = 0;
+    struct listnode *p_ses_node = NULL;
+    st_session_t *p_ses = NULL;
+
+    pthread_mutex_lock(&stdev->lock);
+    stdev->screen_off = config->u.value;
+    ALOGD("%s: screen %s", __func__, stdev->screen_off ? "off" : "on");
+
+    num_sessions = get_num_sessions();
+    if (!num_sessions) {
+        pthread_mutex_unlock(&stdev->lock);
+        return;
+    }
+
+    st_hw_check_and_update_lpi(stdev, p_ses);
+
+    if (stdev->lpi_enable != platform_get_lpi_mode(stdev->platform) &&
+        !is_any_session_buffering()) {
+        list_for_each(p_ses_node, &stdev->sound_model_list) {
+            p_ses = node_to_item(p_ses_node, st_session_t, list_node);
+            if (p_ses && p_ses->exec_mode == ST_EXEC_MODE_ADSP) {
+                ALOGD("%s:[%d] LPI: pause SVA session",
+                    __func__, p_ses->sm_handle);
+                st_session_pause(p_ses);
+            }
+        }
+
+        platform_stdev_reset_backend_cfg(stdev->platform);
+
+        list_for_each(p_ses_node, &stdev->sound_model_list) {
+            p_ses = node_to_item(p_ses_node, st_session_t, list_node);
+            if (p_ses && p_ses->exec_mode == ST_EXEC_MODE_ADSP) {
+                ALOGD("%s:[%d] LPI: resume SVA session",
+                    __func__, p_ses->sm_handle);
+                st_session_resume(p_ses);
+            }
+        }
+    }
+    pthread_mutex_unlock(&stdev->lock);
+    ALOGV("%s: Exit", __func__);
+}
+
 static void handle_battery_status_change(audio_event_info_t* config)
 {
     unsigned int num_sessions;
@@ -1112,7 +1181,7 @@
      * So check and update the lpi/vad configuration which will be used during
      * device backend setting as part of session's start/resume.
      */
-    stdev->lpi_enable = st_hw_check_lpi_support(stdev, p_ses);
+    st_hw_check_and_update_lpi(stdev, p_ses);
     stdev->vad_enable = st_hw_check_vad_support(stdev, p_ses,
         stdev->lpi_enable);
     if (stdev->lpi_enable != platform_get_lpi_mode(stdev->platform) &&
@@ -1126,7 +1195,9 @@
                 st_session_pause(p_ses);
             }
         }
+
         platform_stdev_reset_backend_cfg(stdev->platform);
+
         list_for_each(p_ses_node, &stdev->sound_model_list) {
             p_ses = node_to_item(p_ses_node, st_session_t, list_node);
             if (p_ses && p_ses->exec_mode == ST_EXEC_MODE_ADSP) {
@@ -2000,7 +2071,7 @@
     }
 
     st_session->sm_type = sound_model->type;
-    stdev->lpi_enable = st_hw_check_lpi_support(stdev, NULL);
+    st_hw_check_and_update_lpi(stdev, NULL);
     st_hw_check_and_set_lpi_mode(st_session);
 
     /* CPE DRAM can only be accessed by single client, i.e. Apps or CPE,
@@ -2169,7 +2240,7 @@
         }
     }
 
-    stdev->lpi_enable = st_hw_check_lpi_support(stdev, NULL);
+    st_hw_check_and_update_lpi(stdev, NULL);
     stdev->vad_enable = st_hw_check_vad_support(stdev, best_ses,
                                                 stdev->lpi_enable);
 
@@ -2406,7 +2477,7 @@
 
     if (ST_EXEC_MODE_ADSP == st_session->exec_mode ||
         ST_EXEC_MODE_ARM == st_session->exec_mode) {
-        stdev->lpi_enable = st_hw_check_lpi_support(stdev, st_session);
+        st_hw_check_and_update_lpi(stdev, st_session);
         stdev->vad_enable = st_hw_check_vad_support(stdev, st_session,
                                                     stdev->lpi_enable);
         int vad_preroll = st_session_get_preroll(st_session);
@@ -3012,6 +3083,15 @@
         handle_battery_status_change(config);
         break;
 
+    case AUDIO_EVENT_SCREEN_STATUS_CHANGED:
+        if (!config) {
+            ALOGE("%s: NULL config for AUDIO_EVENT_SCREEN_STATUS_CHANGED", __func__);
+            ret = -EINVAL;
+            break;
+        }
+        handle_screen_status_change(config);
+        break;
+
     default:
         ALOGW("%s: Unknown event %d", __func__, event);
         break;
diff --git a/sound_trigger_hw.h b/sound_trigger_hw.h
index f241111..4117d32 100644
--- a/sound_trigger_hw.h
+++ b/sound_trigger_hw.h
@@ -260,6 +260,11 @@
     bool ssr_offline_received;
     int lpma_handle;
     bool is_charging;
+    bool enable_debug_dumps;
+    bool support_barge_in_mode;
+    bool support_dynamic_ec_update;
+    bool screen_off;
+    bool barge_in_mode;
 };
 
 typedef struct sound_trigger_device sound_trigger_device_t;
@@ -272,11 +277,7 @@
 
 void update_hw_mad_exec_mode(st_exec_mode_t mode, st_profile_type_t profile_type);
 
-/* Debug helper macros */
-/* #define ST_DEBUG_DUMP */
 #define ST_DEBUG_DUMP_LOCATION "/data/vendor/audio"
-
-#ifdef ST_DEBUG_DUMP
 #define ST_DBG_DECLARE(args...) args
 
 #define ST_DBG_FILE_OPEN_WR(fptr, fpath, fname, fextn, fcount) \
@@ -307,12 +308,6 @@
         fflush(fptr);\
     }\
 } while (0)
-#else
-#define ST_DBG_DECLARE(args...)
-#define ST_DBG_FILE_OPEN_WR(fptr, path, fname, fextn, fcount) (0)
-#define ST_DBG_FILE_CLOSE(fptr) (0)
-#define ST_DBG_FILE_WRITE(fptr, buf, buf_size) (0)
-#endif
 
 int dbg_trace_max_lab_reads;
 #define ST_DBG_ATRACE_ASYNC_BEGIN_IF(cond, name, cookie)\
diff --git a/sound_trigger_platform.c b/sound_trigger_platform.c
index c5b7189..1f16826 100644
--- a/sound_trigger_platform.c
+++ b/sound_trigger_platform.c
@@ -140,6 +140,8 @@
 #define ST_PARAM_KEY_TRANSIT_TO_NON_LPI_ON_BATTERY_CHARGING \
     "transit_to_non_lpi_on_battery_charging"
 #define ST_PARAM_KEY_PLATFORM_LPI_ENABLE "platform_lpi_enable"
+#define ST_PARAM_KEY_SUPPORT_BARGE_IN_MODE \
+    "support_non_lpi_without_ec"
 #define ST_PARAM_KEY_TRANSIT_WAIT_TIME "transit_wait_time"
 #define ST_PARAM_KEY_SPLIT_EC_REF_DATA "split_ec_ref_data"
 #define ST_PARAM_KEY_EC_REF_CHANNEL_COUNT "ec_ref_channel_count"
@@ -151,6 +153,7 @@
 #define ST_PARAM_KEY_VAD_ENABLE "vad_enable"
 #define ST_PARAM_KEY_DEDICATED_SVA_PATH "dedicated_sva_path"
 #define ST_PARAM_KEY_DEDICATED_HEADSET_PATH "dedicated_headset_path"
+#define ST_PARAM_KEY_ENABLE_DEBUG_DUMPS "enable_debug_dumps"
 #define ST_PARAM_KEY_DAM_TOKEN_ID "dam_token_id"
 
 #ifndef Q6AFE_HWDEP_NODE
@@ -399,7 +402,6 @@
 
     char backend_port[ST_BACKEND_PORT_NAME_MAX_SIZE];
     st_codec_backend_cfg_t codec_backend_cfg;
-    bool ec_ref_enabled;
     char ec_ref_mixer_path[ST_MAX_LENGTH_MIXER_CONTROL];
     int bad_mic_channel_index;
 
@@ -738,10 +740,11 @@
     stdev->dedicated_headset_path = true;
     stdev->disable_hwmad = false;
     stdev->platform_lpi_enable = ST_PLATFORM_LPI_NONE;
+    stdev->screen_off = true;
+    stdev->support_dynamic_ec_update = true;
 
     platform->cpe_fe_to_be_fixed = true;
     platform->bad_mic_channel_index = 0;
-    platform->ec_ref_enabled = false;
     platform->be_dai_name_table = NULL;
     platform->max_be_dai_names = 0;
     platform->lpma_cfg.num_bb_ids = 0;
@@ -1058,6 +1061,14 @@
             ST_PLATFORM_LPI_DISABLE;
     }
 
+    err = str_parms_get_str(parms, ST_PARAM_KEY_SUPPORT_BARGE_IN_MODE,
+                            str_value, sizeof(str_value));
+    if (err >= 0) {
+        str_parms_del(parms, ST_PARAM_KEY_SUPPORT_BARGE_IN_MODE);
+        stdev->support_barge_in_mode =
+            !strncasecmp(str_value, "true", 4) ? true : false;
+    }
+
     err = str_parms_get_int(parms, ST_PARAM_KEY_TRANSIT_WAIT_TIME, &value);
     if (err >= 0) {
         str_parms_del(parms, ST_PARAM_KEY_TRANSIT_WAIT_TIME);
@@ -1147,6 +1158,14 @@
             !strncasecmp(str_value, "true", 4) ? true : false;
     }
 
+    err = str_parms_get_str(parms, ST_PARAM_KEY_ENABLE_DEBUG_DUMPS,
+                            str_value, sizeof(str_value));
+    if (err >= 0) {
+        str_parms_del(parms, ST_PARAM_KEY_ENABLE_DEBUG_DUMPS);
+        stdev->enable_debug_dumps =
+            !strncasecmp(str_value, "true", 4) ? true : false;
+    }
+
     return 0;
 }
 
@@ -2223,12 +2242,28 @@
                                 str_value, sizeof(str_value));
         if (err >= 0) {
             str_parms_del(parms, ST_PARAM_KEY_LPI_MODE);
-            if (!strncasecmp(str_value, "NON_LPI", sizeof("NON_LPI")))
+            /*
+             * The default setting will have 2 lsm_usecases in the xml -
+             * lpi_mode LPI and NON_LPI_BARGE_IN. With this configuration,
+             * dynamic EC updates are supported when barge_in_mode is enabled
+             * or disabled. If a third lsm_usecase is present in the xml with
+             * lpi_mode NON_LPI, then transitions will occur when barge_in_mode
+             * is enabled or disabled. This allows for different number of MICs
+             * between non-LPI with barge-in and non-LPI without barge-in.
+             */
+            if (!strncasecmp(str_value, "NON_LPI",
+                sizeof("NON_LPI"))) {
                 lsm_params->lpi_enable = ST_PLATFORM_LPI_DISABLE;
-            else if (!strncasecmp(str_value, "LPI", sizeof("LPI")))
+                my_data->stdev->support_dynamic_ec_update = false;
+            } else if (!strncasecmp(str_value, "NON_LPI_BARGE_IN",
+                sizeof("NON_LPI_BARGE_IN"))) {
+                lsm_params->lpi_enable = ST_PLATFORM_LPI_DISABLE_AND_BARGE_IN;
+            } else if (!strncasecmp(str_value, "LPI", sizeof("LPI"))) {
                 lsm_params->lpi_enable = ST_PLATFORM_LPI_ENABLE;
-            else
+            } else {
                 ALOGE("%s: invalid lpi_mode set: %s", __func__, str_value);
+                goto err_exit;
+            }
         }
     }
 
@@ -4996,6 +5031,7 @@
     struct platform_data *my_data = (struct platform_data *)platform;
     audio_devices_t capture_device =
         platform_stdev_get_capture_device(platform);
+    sound_trigger_device_t *stdev = my_data->stdev;
 
     ALOGV("%s: Enter", __func__);
 
@@ -5014,12 +5050,32 @@
         usecase = node_to_item(lsm_node, struct st_lsm_params, list_node);
         if (usecase->exec_mode == exec_mode) {
             if (my_data->xml_version >= PLATFORM_XML_VERSION_0x0105) {
+                /*
+                 * When the capture device matches, the lsm_usecase with the
+                 * following lpi_mode will be selected:
+                 *
+                 * ST_PLATFORM_LPI_NONE, when no lpi_mode is present.
+                 *
+                 * ST_PLATFORM_LPI_ENABLE, when lpi_enable is true.
+                 *
+                 * ST_PLATFORM_LPI_DISABLE_AND_BARGE_IN, when lpi_enable is
+                 * false and either no lsm_usecase with ST_PLATFORM_LPI_DISABLE
+                 * is present or barge_in_mode is active.
+                 *
+                 * ST_PLATFORM_LPI_DISABLE, when lpi_enable is false and an
+                 * lsm_usecase with this lpi_mode is present and barge_in_mode
+                 * is inactive.
+                 */
                 if (capture_device == usecase->capture_device &&
                     (usecase->lpi_enable == ST_PLATFORM_LPI_NONE ||
-                     (lpi_enable && usecase->lpi_enable ==
-                      ST_PLATFORM_LPI_ENABLE) ||
-                     (!lpi_enable && usecase->lpi_enable ==
-                      ST_PLATFORM_LPI_DISABLE))) {
+                     (usecase->lpi_enable == ST_PLATFORM_LPI_ENABLE &&
+                      lpi_enable) ||
+                     (usecase->lpi_enable ==
+                      ST_PLATFORM_LPI_DISABLE_AND_BARGE_IN && !lpi_enable &&
+                      (stdev->support_dynamic_ec_update ||
+                       stdev->barge_in_mode)) ||
+                     (usecase->lpi_enable == ST_PLATFORM_LPI_DISABLE &&
+                      !lpi_enable && !stdev->barge_in_mode))) {
                     *lsm_usecase = usecase;
                     v_info->in_channels = usecase->in_channels;
                     v_info->fluence_type = usecase->fluence_type;
@@ -5373,6 +5429,38 @@
         strlcat(ec_ref_mixer_path, " line",  DEVICE_NAME_MAX_SIZE);
 }
 
+int platform_stdev_update_ec_effect
+(
+    void *platform,
+    bool enable_ec
+)
+{
+    struct platform_data *my_data = (struct platform_data *)platform;
+    sound_trigger_device_t *stdev = my_data->stdev;
+    struct mixer_ctl *ctl = NULL;
+    const char *mixer_ctl_name = "FFECNS Effect";
+    int status = 0;
+
+    ALOGD("%s: Turning %s EC effect", __func__, enable_ec ? "on" : "off");
+
+    ctl = mixer_get_ctl_by_name(stdev->mixer, mixer_ctl_name);
+    if (!ctl) {
+        ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
+        __func__, mixer_ctl_name);
+        return -EINVAL;
+    }
+
+    if (enable_ec)
+        status = mixer_ctl_set_enum_by_string(ctl, "ECNS");
+    else
+        status = mixer_ctl_set_enum_by_string(ctl, "NS_ONLY");
+
+    if (status)
+        ALOGE("%s: ERROR. Mixer ctl set failed", __func__);
+
+    return status;
+}
+
 void platform_stdev_send_ec_ref_cfg
 (
    void *platform,
@@ -5382,13 +5470,12 @@
 {
     struct platform_data *my_data = (struct platform_data *)platform;
     sound_trigger_device_t *stdev = my_data->stdev;
-    struct sound_trigger_event_info event_info;
+    struct sound_trigger_event_info event_info = {{0}, 0};
 
     if (is_ec_profile(profile_type)) {
         event_info.st_ec_ref_enabled = enable;
         if (enable) {
             stdev->audio_hal_cb(ST_EVENT_UPDATE_ECHO_REF, &event_info);
-            my_data->ec_ref_enabled = enable;
             strlcpy(my_data->ec_ref_mixer_path, "echo-reference",
                     sizeof(my_data->ec_ref_mixer_path));
 
@@ -5403,15 +5490,10 @@
             stdev->audio_hal_cb(ST_EVENT_UPDATE_ECHO_REF, &event_info);
             /* avoid disabling echo if audio hal has enabled echo ref */
             if (!stdev->audio_ec_enabled) {
-                if (my_data->ec_ref_enabled) {
-                    ALOGD("%s: reset echo ref %s", __func__,
-                            my_data->ec_ref_mixer_path);
-                    audio_route_reset_and_update_path(stdev->audio_route,
-                            my_data->ec_ref_mixer_path);
-                    my_data->ec_ref_enabled = enable;
-                } else {
-                    ALOGD("%s: EC Reference is already disabled", __func__);
-                }
+                ALOGD("%s: reset echo ref %s", __func__,
+                    my_data->ec_ref_mixer_path);
+                audio_route_reset_and_update_path(stdev->audio_route,
+                        my_data->ec_ref_mixer_path);
             } else {
                 ALOGD("%s: audio hal has already enabled EC", __func__);
             }
diff --git a/sound_trigger_platform.h b/sound_trigger_platform.h
index cd415ac..4d976cf 100644
--- a/sound_trigger_platform.h
+++ b/sound_trigger_platform.h
@@ -279,7 +279,8 @@
 typedef enum {
     ST_PLATFORM_LPI_NONE,
     ST_PLATFORM_LPI_ENABLE,
-    ST_PLATFORM_LPI_DISABLE
+    ST_PLATFORM_LPI_DISABLE,
+    ST_PLATFORM_LPI_DISABLE_AND_BARGE_IN
 } st_platform_lpi_enable_t;
 
 struct st_lsm_params {
@@ -616,6 +617,12 @@
    st_profile_type_t profile_type
 );
 
+int platform_stdev_update_ec_effect
+(
+    void *platform,
+    bool enable_ec
+);
+
 void platform_stdev_send_ec_ref_cfg
 (
    void *platform,
diff --git a/sound_trigger_prop_intf.h b/sound_trigger_prop_intf.h
index 6d8f039..7ad34dc 100644
--- a/sound_trigger_prop_intf.h
+++ b/sound_trigger_prop_intf.h
@@ -73,7 +73,8 @@
     AUDIO_EVENT_CAPTURE_STREAM_ACTIVE,
     AUDIO_EVENT_BATTERY_STATUS_CHANGED,
     AUDIO_EVENT_GET_PARAM,
-    AUDIO_EVENT_UPDATE_ECHO_REF
+    AUDIO_EVENT_UPDATE_ECHO_REF,
+    AUDIO_EVENT_SCREEN_STATUS_CHANGED
 };
 typedef enum audio_event_type audio_event_type_t;
 
diff --git a/st_hw_common.c b/st_hw_common.c
index 14230c4..3c31a2c 100644
--- a/st_hw_common.c
+++ b/st_hw_common.c
@@ -180,7 +180,7 @@
     return true;
 }
 
-bool st_hw_check_lpi_support
+void st_hw_check_and_update_lpi
 (
     struct sound_trigger_device *stdev,
     st_session_t *st_ses
@@ -189,29 +189,34 @@
     st_session_t *ses = NULL;
     struct listnode *ses_node = NULL;
 
+    stdev->lpi_enable = false;
+    stdev->barge_in_mode = true;
     /*
      * ST_PLATFORM_LPI_NONE is used for backward compatibility. With this
      * setting, the st_vendor_uuid->lpi_enable flag will be used.
      */
     if (stdev->platform_lpi_enable == ST_PLATFORM_LPI_DISABLE) {
         ALOGD("%s: lpi NOT enabled in platform setting", __func__);
-        return false;
+        return;
     } else if ((stdev->platform_lpi_enable == ST_PLATFORM_LPI_NONE) &&
                st_ses && !st_ses->vendor_uuid_info->lpi_enable) {
         ALOGD("%s: lpi NOT enabled for ses %d", __func__, st_ses->sm_handle);
-        return false;
+        return;
     }
 
-    if (stdev->rx_concurrency_active || stdev->tx_concurrency_active) {
+    if (stdev->rx_concurrency_active || stdev->conc_voice_active ||
+        stdev->conc_voip_active) {
         ALOGD("%s: lpi NOT supported due to concurrency", __func__);
-        return false;
+        return;
     }
 
     if (stdev->is_charging &&
         stdev->transit_to_non_lpi_on_battery_charging) {
         ALOGD("%s: lpi NOT supported. battery status %d", __func__,
             stdev->is_charging);
-        return false;
+        if (stdev->support_barge_in_mode)
+            stdev->barge_in_mode = false;
+        return;
     }
 
     list_for_each(ses_node, &stdev->sound_model_list) {
@@ -220,14 +225,23 @@
         if (ses->client_req_det_mode == ST_DET_HIGH_PERF_MODE) {
             ALOGD("%s:[%d] lpi NOT supported due to high perf mode", __func__,
                 ses->sm_handle);
-            return false;
+            if (stdev->support_barge_in_mode)
+                stdev->barge_in_mode = false;
+            return;
         }
     }
 
+    if (!stdev->screen_off && stdev->support_barge_in_mode) {
+        ALOGD("%s: lpi NOT supported. Screen is on", __func__);
+        stdev->barge_in_mode = false;
+        return;
+    }
+
     if (stdev->platform_lpi_enable == ST_PLATFORM_LPI_NONE)
-        return is_projected_lpi_budget_available(stdev, st_ses);
+        stdev->lpi_enable = is_projected_lpi_budget_available(stdev, st_ses);
     else
-        return true;
+        stdev->lpi_enable = true;
+    stdev->barge_in_mode = !stdev->lpi_enable;
 }
 
 bool st_hw_check_vad_support
@@ -295,6 +309,8 @@
                 is_projected_lpi_budget_available(st_ses->stdev, stc_ses));
         } else {
             st_ses->hw_ses_adsp->lpi_enable = st_ses->stdev->lpi_enable;
+            st_ses->hw_ses_adsp->barge_in_mode =
+                st_ses->stdev->barge_in_mode;
         }
     }
     pthread_mutex_unlock(&st_ses->lock);
diff --git a/st_hw_common.h b/st_hw_common.h
index 6fb9548..6f822ea 100644
--- a/st_hw_common.h
+++ b/st_hw_common.h
@@ -35,7 +35,7 @@
 #include "st_session.h"
 
 bool st_hw_check_ses_ss_usecase_allowed(st_session_t *st_ses);
-bool st_hw_check_lpi_support(struct sound_trigger_device *stdev, st_session_t *st_ses);
+void st_hw_check_and_update_lpi(struct sound_trigger_device *stdev, st_session_t *st_ses);
 bool st_hw_check_vad_support(struct sound_trigger_device *stdev, st_session_t *st_ses, bool lpi_enable);
 void st_hw_check_and_set_lpi_mode(st_session_t *st_ses);
 bool st_hw_check_multi_stage_lsm_support();
diff --git a/st_hw_session.h b/st_hw_session.h
index 6c61bee..4a8218d 100644
--- a/st_hw_session.h
+++ b/st_hw_session.h
@@ -106,6 +106,7 @@
     bool is_generic_event;
     struct listnode lsm_ss_cfg_list;
     bool lpi_enable;
+    bool barge_in_mode;
     bool lab_enabled;
 
     int rc_config_update_counter;
diff --git a/st_hw_session_gcs.c b/st_hw_session_gcs.c
index 83c84ff..53037b7 100644
--- a/st_hw_session_gcs.c
+++ b/st_hw_session_gcs.c
@@ -308,7 +308,8 @@
     buff_sz = hdr->size_in_bytes - sizeof(struct gcs_cmd_readrsp_payload_t);
     buff = (uint8_t *)payload + sizeof(struct gcs_cmd_readrsp_payload_t);
 
-    ST_DBG_FILE_WRITE(p_gcs_ses->lab_fp_gcs, buff, buff_sz);
+    if (p_ses->stdev->enable_debug_dumps)
+        ST_DBG_FILE_WRITE(p_gcs_ses->lab_fp_gcs, buff, buff_sz);
 
     if (buff_sz > ST_GCS_READ_BUF_SIZE) {
         ALOGW("%s: received size %d more than requested %d, truncate",
@@ -434,12 +435,15 @@
         p_ses->detection_signaled = false;
         p_det = (struct gcs_det_engine_event *)p_ses->detect_payload;
 
-        ST_DBG_DECLARE(FILE *detect_fd = NULL; static int detect_fd_cnt = 0);
-        ST_DBG_FILE_OPEN_WR(detect_fd, ST_DEBUG_DUMP_LOCATION,
-                            "gcs_detection_event", "bin", detect_fd_cnt++);
-        ST_DBG_FILE_WRITE(detect_fd, p_ses->detect_payload,
-                          p_ses->detect_payload_size);
-        ST_DBG_FILE_CLOSE(detect_fd);
+        if (p_ses->common.stdev->enable_debug_dumps) {
+            ST_DBG_DECLARE(FILE *detect_fd = NULL;
+                static int detect_fd_cnt = 0);
+            ST_DBG_FILE_OPEN_WR(detect_fd, ST_DEBUG_DUMP_LOCATION,
+                                "gcs_detection_event", "bin", detect_fd_cnt++);
+            ST_DBG_FILE_WRITE(detect_fd, p_ses->detect_payload,
+                              p_ses->detect_payload_size);
+            ST_DBG_FILE_CLOSE(detect_fd);
+        }
 
         if (p_ses->start_engine_cal) {
             p_det_ext = (struct gcs_det_engine_extended_event *)p_det;
@@ -597,11 +601,13 @@
     memcpy(load_sm_msg + sizeof(struct graphite_cal_header),
         (uint8_t *)sm_data, sm_size);
 
-
-    ST_DBG_DECLARE(FILE *load_fd = NULL; static int load_fd_cnt = 0);
-    ST_DBG_FILE_OPEN_WR(load_fd, ST_DEBUG_DUMP_LOCATION, "load_sm", "bin", load_fd_cnt++);
-    ST_DBG_FILE_WRITE(load_fd, load_sm_msg, load_sm_msg_sz);
-    ST_DBG_FILE_CLOSE(load_fd);
+    if (p_ses->stdev->enable_debug_dumps) {
+        ST_DBG_DECLARE(FILE *load_fd = NULL; static int load_fd_cnt = 0);
+        ST_DBG_FILE_OPEN_WR(load_fd, ST_DEBUG_DUMP_LOCATION, "load_sm", "bin",
+            load_fd_cnt++);
+        ST_DBG_FILE_WRITE(load_fd, load_sm_msg, load_sm_msg_sz);
+        ST_DBG_FILE_CLOSE(load_fd);
+    }
 
     ALOGD("%s:[%d] calling gcs_load_data with graph_handle %d, load_sm_msg %p, "
         "load_sm_msg_sz %d", __func__, p_ses->sm_handle, p_gcs_ses->graph_handle,
@@ -1055,12 +1061,15 @@
     int status = 0;
     st_hw_session_gcs_t *p_gcs_ses = (st_hw_session_gcs_t *)p_ses;
 
-    ST_DBG_DECLARE(FILE *nonpersist_fd = NULL; static int nonpersist_fd_cnt = 0);
-    ST_DBG_FILE_OPEN_WR(nonpersist_fd, ST_DEBUG_DUMP_LOCATION, "nonpersist_params",
-        "bin", nonpersist_fd_cnt++);
-    ST_DBG_FILE_WRITE(nonpersist_fd, p_gcs_ses->nonpersistent_cal,
-        p_gcs_ses->nonpersistent_cal_size);
-    ST_DBG_FILE_CLOSE(nonpersist_fd);
+    if (p_ses->stdev->enable_debug_dumps) {
+        ST_DBG_DECLARE(FILE *nonpersist_fd = NULL;
+            static int nonpersist_fd_cnt = 0);
+        ST_DBG_FILE_OPEN_WR(nonpersist_fd, ST_DEBUG_DUMP_LOCATION,
+            "nonpersist_params", "bin", nonpersist_fd_cnt++);
+        ST_DBG_FILE_WRITE(nonpersist_fd, p_gcs_ses->nonpersistent_cal,
+            p_gcs_ses->nonpersistent_cal_size);
+        ST_DBG_FILE_CLOSE(nonpersist_fd);
+    }
 
     p_gcs_ses->exit_buffering = false;
     /* During start and stop of VA engines update enable param.
@@ -1476,11 +1485,15 @@
 
     read_cmd.payload.read.size_in_bytes = ST_GCS_READ_BUF_SIZE;
 
-    ST_DBG_DECLARE(FILE *read_fp = NULL; static int read_fp_cnt = 0);
-    ST_DBG_FILE_OPEN_WR(read_fp, ST_DEBUG_DUMP_LOCATION, "read_msg", "bin", read_fp_cnt++);
-    ST_DBG_FILE_WRITE(read_fp, (char *)&read_cmd, sizeof(struct graphite_data_cmd_hdr) +
-        sizeof(struct gcs_cmd_read_payload_t));
-    ST_DBG_FILE_CLOSE(read_fp);
+    if (p_ses->stdev->enable_debug_dumps) {
+        ST_DBG_DECLARE(FILE *read_fp = NULL; static int read_fp_cnt = 0);
+        ST_DBG_FILE_OPEN_WR(read_fp, ST_DEBUG_DUMP_LOCATION, "read_msg", "bin",
+            read_fp_cnt++);
+        ST_DBG_FILE_WRITE(read_fp, (char *)&read_cmd,
+            sizeof(struct graphite_data_cmd_hdr) +
+            sizeof(struct gcs_cmd_read_payload_t));
+        ST_DBG_FILE_CLOSE(read_fp);
+    }
 
     ALOGV("%s:[%d] read_cmd module_id 0x%x, instance_id 0x%x, cmd_id 0x%x, "
         "read_sz %d", __func__, p_ses->sm_handle, read_cmd.hdr.module_id,
@@ -1601,10 +1614,12 @@
         return;
     }
 
-    ST_DBG_FILE_OPEN_WR(p_hw_ses->lab_fp_gcs, ST_DEBUG_DUMP_LOCATION, "lab_gcs_to_sthal",
-        "bin", lab_fp_gcs_cnt++);
-    ST_DBG_FILE_OPEN_WR(p_hw_ses->lab_fp_client, ST_DEBUG_DUMP_LOCATION, "lab_sthal_to_client",
-        "bin", lab_fp_client_cnt++);
+    if (p_ses->stdev->enable_debug_dumps) {
+        ST_DBG_FILE_OPEN_WR(p_hw_ses->lab_fp_gcs, ST_DEBUG_DUMP_LOCATION,
+            "lab_gcs_to_sthal", "bin", lab_fp_gcs_cnt++);
+        ST_DBG_FILE_OPEN_WR(p_hw_ses->lab_fp_client, ST_DEBUG_DUMP_LOCATION,
+            "lab_sthal_to_client", "bin", lab_fp_client_cnt++);
+    }
 
     while (p_hw_ses->read_rsp_cnt && !p_hw_ses->exit_buffering) {
 
@@ -1669,8 +1684,10 @@
         wdsp_debug_dump(gcs_data.sysfs_fd);
     }
 
-    ST_DBG_FILE_CLOSE(p_hw_ses->lab_fp_gcs);
-    ST_DBG_FILE_CLOSE(p_hw_ses->lab_fp_client);
+    if (p_ses->stdev->enable_debug_dumps) {
+        ST_DBG_FILE_CLOSE(p_hw_ses->lab_fp_gcs);
+        ST_DBG_FILE_CLOSE(p_hw_ses->lab_fp_client);
+    }
 
     /*
      * Signal back to thread calling stop_buffering that
@@ -1749,7 +1766,8 @@
 
             p_gcs_ses->unread_bytes -= copy_bytes;
 
-            ST_DBG_FILE_WRITE(p_gcs_ses->lab_fp_client, client_buf, copy_bytes);
+            if (p_ses->stdev->enable_debug_dumps)
+                ST_DBG_FILE_WRITE(p_gcs_ses->lab_fp_client, client_buf, copy_bytes);
 
             bytes -= copy_bytes;
             client_buf += copy_bytes;
@@ -1777,11 +1795,14 @@
         params[REQUEST_DETECTION].param_id;
     cal_hdr.size = 0;
 
-    ST_DBG_DECLARE(FILE *req_event_fd = NULL; static int req_event_cnt = 0);
-    ST_DBG_FILE_OPEN_WR(req_event_fd, ST_DEBUG_DUMP_LOCATION,
-        "requested_event_gcs", "bin", req_event_cnt++);
-    ST_DBG_FILE_WRITE(req_event_fd, &cal_hdr, cal_hdr_size);
-    ST_DBG_FILE_CLOSE(req_event_fd);
+    if (p_ses->stdev->enable_debug_dumps) {
+        ST_DBG_DECLARE(FILE *req_event_fd = NULL;
+            static int req_event_cnt = 0);
+        ST_DBG_FILE_OPEN_WR(req_event_fd, ST_DEBUG_DUMP_LOCATION,
+            "requested_event_gcs", "bin", req_event_cnt++);
+        ST_DBG_FILE_WRITE(req_event_fd, &cal_hdr, cal_hdr_size);
+        ST_DBG_FILE_CLOSE(req_event_fd);
+    }
 
     ALOGD("%s:[%d] calling gcs_set_config with graph_handle %d, msg_size %d",
         __func__, p_ses->sm_handle, p_gcs_ses->graph_handle, cal_hdr_size);
diff --git a/st_hw_session_lsm.c b/st_hw_session_lsm.c
index a49adb5..ec2a63b 100644
--- a/st_hw_session_lsm.c
+++ b/st_hw_session_lsm.c
@@ -998,8 +998,10 @@
     uint64_t frame_read_time = 0;
 
     ST_DBG_DECLARE(FILE *fptr_drv = NULL; static int file_cnt = 0);
-    ST_DBG_FILE_OPEN_WR(fptr_drv, ST_DEBUG_DUMP_LOCATION,
-                        "st_lab_drv_data_cpe", "pcm", file_cnt++);
+    if (p_lsm_ses->common.stdev->enable_debug_dumps) {
+        ST_DBG_FILE_OPEN_WR(fptr_drv, ST_DEBUG_DUMP_LOCATION,
+                            "st_lab_drv_data_cpe", "pcm", file_cnt++);
+    }
 
     p_lsm_ses->lab_processing_active = true;
     p_lsm_ses->unread_bytes = 0;
@@ -1058,7 +1060,14 @@
                     st_sec_stage->ss_session->buf_end = kw_duration_bytes +
                         cnn_append_bytes;
                 }
-                st_sec_stage->ss_session->buff_sz = p_lsm_ses->lab_drv_buf_size;
+                /*
+                 * The first second-stage keyword buffer frame needs to contain
+                 * ((kwd_start_idx - kwd_start_tolerance) - kwd_end_idx) from
+                 * the first stage keyword.
+                 */
+                st_sec_stage->ss_session->buff_sz = (p_lsm_ses->common.kw_end_idx -
+                    st_sec_stage->ss_session->buf_start);
+                st_sec_stage->ss_session->lab_buf_sz = p_lsm_ses->lab_drv_buf_size;
                 st_sec_stage->ss_session->det_status = KEYWORD_DETECTION_PENDING;
             } else if (st_sec_stage->ss_info->sm_detection_type ==
                 ST_SM_TYPE_USER_VERIFICATION) {
@@ -1109,8 +1118,10 @@
 
         ALOGVV("%s: pcm_read done", __func__);
 
-        ST_DBG_FILE_WRITE(fptr_drv, p_lsm_ses->lab_drv_buf,
-            p_lsm_ses->lab_drv_buf_size);
+        if (p_lsm_ses->common.stdev->enable_debug_dumps) {
+            ST_DBG_FILE_WRITE(fptr_drv, p_lsm_ses->lab_drv_buf,
+                p_lsm_ses->lab_drv_buf_size);
+        }
 
         if (status) {
             ALOGE("%s: pcm read failed status %d - %s", __func__, status,
@@ -1142,7 +1153,8 @@
     }
 
     p_lsm_ses->lab_processing_active = false;
-    ST_DBG_FILE_CLOSE(fptr_drv);
+    if (p_lsm_ses->common.stdev->enable_debug_dumps)
+        ST_DBG_FILE_CLOSE(fptr_drv);
     ALOGVV("%s: Exit status=%d", __func__, status);
 }
 
@@ -1164,12 +1176,14 @@
     unsigned int hdr_size = sizeof(struct cpe_packet_hdr);
     unsigned int hdr_buf_idx = 0;
 
-    ST_DBG_DECLARE(FILE *fptr_drv = NULL, *fptr_pcm = NULL, *fptr_dec = NULL;
-                   static int fcnt = 0, dec_fcnt = 0;);
-    ST_DBG_FILE_OPEN_WR(fptr_drv, ST_DEBUG_DUMP_LOCATION,
-                        "st_lab_drv_data_cpe", "bin", fcnt);
-    ST_DBG_FILE_OPEN_WR(fptr_pcm, ST_DEBUG_DUMP_LOCATION,
-                        "st_lab_output", "pcm", fcnt++);
+    ST_DBG_DECLARE(FILE *fptr_drv = NULL, *fptr_pcm = NULL,
+        *fptr_dec = NULL; static int fcnt = 0, dec_fcnt = 0;);
+    if (p_ses->common.stdev->enable_debug_dumps) {
+        ST_DBG_FILE_OPEN_WR(fptr_drv, ST_DEBUG_DUMP_LOCATION,
+            "st_lab_drv_data_cpe", "bin", fcnt);
+        ST_DBG_FILE_OPEN_WR(fptr_pcm, ST_DEBUG_DUMP_LOCATION,
+            "st_lab_output", "pcm", fcnt++);
+    }
 
     p_ses->lab_processing_active = true;
     p_ses->unread_bytes = 0;
@@ -1197,7 +1211,8 @@
                                     "sthal:lsm:cpe: lsm_buffer_read", p_ses->common.sm_handle);
         ALOGVV("%s: pcm_read done", __func__);
 
-        ST_DBG_FILE_WRITE(fptr_drv, driver_rd_buf, driver_rd_bytes);
+        if (p_ses->common.stdev->enable_debug_dumps)
+            ST_DBG_FILE_WRITE(fptr_drv, driver_rd_buf, driver_rd_bytes);
 
         if (status) {
             ALOGE("%s: pcm read failed status %d - %s", __func__, status,
@@ -1232,8 +1247,10 @@
                                __func__, dec_status);
                         goto exit;
                     }
-                    ST_DBG_FILE_OPEN_WR(fptr_dec, ST_DEBUG_DUMP_LOCATION,
-                                        "st_lab_adpcm_input", "bin", dec_fcnt++);
+                    if (p_ses->common.stdev->enable_debug_dumps) {
+                        ST_DBG_FILE_OPEN_WR(fptr_dec, ST_DEBUG_DUMP_LOCATION,
+                                            "st_lab_adpcm_input", "bin", dec_fcnt++);
+                    }
                 }
             }
         }
@@ -1278,8 +1295,8 @@
                     status = write_pcm_data_cpe(p_ses, &ftrt_buf_ptr[ftrt_buf_idx], copy_bytes);
                     if (status)
                         goto exit;
-
-                    ST_DBG_FILE_WRITE(fptr_pcm, &ftrt_buf_ptr[ftrt_buf_idx], copy_bytes);
+                    if (p_ses->common.stdev->enable_debug_dumps)
+                        ST_DBG_FILE_WRITE(fptr_pcm, &ftrt_buf_ptr[ftrt_buf_idx], copy_bytes);
                     ftrt_buf_idx += copy_bytes;
                     prev_packet->size -= copy_bytes;
                 } else if (prev_packet->format == CPE_PACKET_FORMAT_ADPCM) {
@@ -1308,7 +1325,8 @@
                         ftrt_buf_idx += dec_bytes;
                         prev_packet->size -= dec_bytes;
 
-                        ST_DBG_FILE_WRITE(fptr_dec, frame_buf_ptr, frame_buf_idx);
+                        if (p_ses->common.stdev->enable_debug_dumps)
+                            ST_DBG_FILE_WRITE(fptr_dec, frame_buf_ptr, frame_buf_idx);
                         if (!prev_packet->size || (frame_buf_idx == ADPCM_MAX_IN_FRAME_SIZE)) {
                             /* if packet size is zero, we may have partial frame to be decoded */
                             ALOGVV("%s: enter for decode- frame_buf_idx=%d ftrt_buf_idx=%d prev_packet->size=%d",
@@ -1329,7 +1347,8 @@
                             ALOGVV("%s: adpcm_dec_process done. frame_buf_idx=%d out_samples=%d",
                                    __func__, frame_buf_idx, out_samples);
                             if (out_samples) {
-                                ST_DBG_FILE_WRITE(fptr_pcm, dec_out_buf, out_samples << 1);
+                                if (p_ses->common.stdev->enable_debug_dumps)
+                                    ST_DBG_FILE_WRITE(fptr_pcm, dec_out_buf, out_samples << 1);
                                 status = write_pcm_data_cpe(p_ses, dec_out_buf, out_samples << 1);
                                 if (status)
                                     goto exit;
@@ -1363,9 +1382,11 @@
         p_ses->common.fptrs->stop_buffering(&p_ses->common);
     }
 
-    ST_DBG_FILE_CLOSE(fptr_drv);
-    ST_DBG_FILE_CLOSE(fptr_dec);
-    ST_DBG_FILE_CLOSE(fptr_pcm);
+    if (p_ses->common.stdev->enable_debug_dumps) {
+        ST_DBG_FILE_CLOSE(fptr_drv);
+        ST_DBG_FILE_CLOSE(fptr_dec);
+        ST_DBG_FILE_CLOSE(fptr_pcm);
+    }
 
     ALOGVV("%s: Exit status=%d", __func__, status);
 }
@@ -1382,8 +1403,10 @@
     uint64_t frame_read_time = 0, buffering_start_time = 0;
 
     ST_DBG_DECLARE(FILE *fptr_drv = NULL; static int file_cnt = 0);
-    ST_DBG_FILE_OPEN_WR(fptr_drv, ST_DEBUG_DUMP_LOCATION,
-                        "st_lab_drv_data_ape", "pcm", file_cnt++);
+    if (p_lsm_ses->common.stdev->enable_debug_dumps) {
+        ST_DBG_FILE_OPEN_WR(fptr_drv, ST_DEBUG_DUMP_LOCATION,
+                            "st_lab_drv_data_ape", "pcm", file_cnt++);
+    }
 
     pthread_mutex_lock(&p_lsm_ses->lock);
     p_lsm_ses->lab_processing_active = true;
@@ -1446,7 +1469,14 @@
                     st_sec_stage->ss_session->buf_end = kw_duration_bytes +
                         cnn_append_bytes;
                 }
-                st_sec_stage->ss_session->buff_sz = p_lsm_ses->lab_drv_buf_size;
+                /*
+                 * The first second-stage keyword buffer frame needs to contain
+                 * ((kwd_start_idx - kwd_start_tolerance) - kwd_end_idx) from
+                 * the first stage keyword.
+                 */
+                st_sec_stage->ss_session->buff_sz = (p_lsm_ses->common.kw_end_idx -
+                    st_sec_stage->ss_session->buf_start);
+                st_sec_stage->ss_session->lab_buf_sz = p_lsm_ses->lab_drv_buf_size;
                 st_sec_stage->ss_session->det_status = KEYWORD_DETECTION_PENDING;
             } else if (st_sec_stage->ss_info->sm_detection_type ==
                 ST_SM_TYPE_USER_VERIFICATION) {
@@ -1471,6 +1501,7 @@
             st_sec_stage->ss_session->exit_buffering = false;
             st_sec_stage->ss_session->bytes_processed = 0;
             st_sec_stage->ss_session->start_processing = false;
+            st_sec_stage->ss_session->confidence_score = 0;
             pthread_mutex_unlock(&st_sec_stage->ss_session->lock);
         }
 
@@ -1496,8 +1527,10 @@
         frame_receive_time = get_current_time_ns();
 
         ALOGVV("%s: pcm_read done", __func__);
-        ST_DBG_FILE_WRITE(fptr_drv, p_lsm_ses->lab_drv_buf,
-            p_lsm_ses->lab_drv_buf_size);
+        if (p_lsm_ses->common.stdev->enable_debug_dumps) {
+            ST_DBG_FILE_WRITE(fptr_drv, p_lsm_ses->lab_drv_buf,
+                p_lsm_ses->lab_drv_buf_size);
+        }
 
         if (status) {
             ALOGE("%s: pcm read failed status %d - %s", __func__, status,
@@ -1534,7 +1567,8 @@
     p_lsm_ses->lab_processing_active = false;
     pthread_cond_broadcast(&p_lsm_ses->cond);
     pthread_mutex_unlock(&p_lsm_ses->lock);
-    ST_DBG_FILE_CLOSE(fptr_drv);
+    if (p_lsm_ses->common.stdev->enable_debug_dumps)
+        ST_DBG_FILE_CLOSE(fptr_drv);
     ALOGVV("%s: Exit status=%d", __func__, status);
 }
 
@@ -1658,12 +1692,16 @@
         if (p_lsm_ses->common.lab_enabled)
             p_lsm_ses->lab_on_detection = true;
 
-        ST_DBG_DECLARE(FILE *detect_fd = NULL; static int detect_fd_cnt = 0);
-        ST_DBG_FILE_OPEN_WR(detect_fd, ST_DEBUG_DUMP_LOCATION,
-                            "lsm_detection_event", "bin", detect_fd_cnt++);
-        ST_DBG_FILE_WRITE(detect_fd, hw_sess_event.payload.detected.detect_payload,
-                          hw_sess_event.payload.detected.payload_size);
-        ST_DBG_FILE_CLOSE(detect_fd);
+        if (p_lsm_ses->common.stdev->enable_debug_dumps) {
+            ST_DBG_DECLARE(FILE *detect_fd = NULL;
+                static int detect_fd_cnt = 0);
+            ST_DBG_FILE_OPEN_WR(detect_fd, ST_DEBUG_DUMP_LOCATION,
+                "lsm_detection_event", "bin", detect_fd_cnt++);
+            ST_DBG_FILE_WRITE(detect_fd,
+                hw_sess_event.payload.detected.detect_payload,
+                hw_sess_event.payload.detected.payload_size);
+            ST_DBG_FILE_CLOSE(detect_fd);
+        }
 
         pthread_mutex_unlock(&p_lsm_ses->callback_thread_lock);
         p_lsm_ses->common.callback_to_st_session(&hw_sess_event,
@@ -2397,7 +2435,7 @@
     unsigned char *lab_dam_payload = NULL;
     struct st_vendor_info *v_info = p_lsm_ses->common.vendor_uuid_info;
     struct snd_lsm_module_params lsm_params;
-    lsm_param_info_t param_info[LSM_SM_PARAMS_INFO_IDX];
+    lsm_param_info_t param_info[LSM_SM_PARAMS_INFO_MAX];
     lsm_param_info_t *cfl_params;
     lsm_param_info_t *op_params;
     lsm_param_info_t *cus_params;
@@ -2467,6 +2505,16 @@
         goto error_exit;
     }
 
+    if (!p_ses->stdev->lpi_enable && !p_ses->stdev->barge_in_mode) {
+        status = platform_stdev_update_ec_effect(p_ses->stdev->platform,
+            false);
+        if (status) {
+            ALOGE("%s: ERROR. Failed to update EC ref, returned status %d",
+                  __func__, status);
+            goto error_exit_1;
+        }
+    }
+
     /* SVA doesn't support per keyword recogntion mode.
        Use the per soundmodel recognition mode */
     if (recognition_mode & RECOGNITION_MODE_VOICE_TRIGGER){
@@ -2679,11 +2727,15 @@
         lsm_params.data_size =
              lsm_params.num_params * sizeof(lsm_param_info_t);
 
-        ST_DBG_DECLARE(FILE *lsm_params_fd = NULL; static int lsm_params_cnt = 0);
-        ST_DBG_FILE_OPEN_WR(lsm_params_fd, ST_DEBUG_DUMP_LOCATION,
-                            "lsm_params_data", "bin", lsm_params_cnt++);
-        ST_DBG_FILE_WRITE(lsm_params_fd, lsm_params.params, lsm_params.data_size);
-        ST_DBG_FILE_CLOSE(lsm_params_fd);
+        if (p_lsm_ses->common.stdev->enable_debug_dumps) {
+            ST_DBG_DECLARE(FILE *lsm_params_fd = NULL;
+                static int lsm_params_cnt = 0);
+            ST_DBG_FILE_OPEN_WR(lsm_params_fd, ST_DEBUG_DUMP_LOCATION,
+                "lsm_params_data", "bin", lsm_params_cnt++);
+            ST_DBG_FILE_WRITE(lsm_params_fd, lsm_params.params,
+                lsm_params.data_size);
+            ST_DBG_FILE_CLOSE(lsm_params_fd);
+        }
 
         status = lsm_set_module_params(p_lsm_ses, &lsm_params);
         if (status) {
@@ -2799,11 +2851,15 @@
             lsm_params.data_size =
                lsm_params.num_params * sizeof(lsm_param_info_t);
 
-            ST_DBG_DECLARE(FILE *lsm_params_fd = NULL; static int lsm_params_cnt = 0);
-            ST_DBG_FILE_OPEN_WR(lsm_params_fd, ST_DEBUG_DUMP_LOCATION,
-                            "lsm_params_data", "bin", lsm_params_cnt++);
-            ST_DBG_FILE_WRITE(lsm_params_fd, lsm_params.params, lsm_params.data_size);
-            ST_DBG_FILE_CLOSE(lsm_params_fd);
+            if (p_lsm_ses->common.stdev->enable_debug_dumps) {
+                ST_DBG_DECLARE(FILE *lsm_params_fd = NULL;
+                    static int lsm_params_cnt = 0);
+                ST_DBG_FILE_OPEN_WR(lsm_params_fd, ST_DEBUG_DUMP_LOCATION,
+                    "lsm_params_data", "bin", lsm_params_cnt++);
+                ST_DBG_FILE_WRITE(lsm_params_fd, lsm_params.params,
+                    lsm_params.data_size);
+                ST_DBG_FILE_CLOSE(lsm_params_fd);
+            }
 
             status = lsm_set_module_params(p_lsm_ses, &lsm_params);
             if (status) {
@@ -3816,6 +3872,11 @@
 
     ALOGD("%s: Enter", __func__);
 
+    if (!p_lsm_ses->pcm) {
+        ALOGE("%s: pcm NULL", __func__);
+        return -ENODEV;
+    }
+
     capture_device = platform_stdev_get_capture_device(p_ses->stdev->platform);
 
     platform_get_lsm_usecase(p_ses->stdev->platform, v_info,
@@ -3876,6 +3937,16 @@
         goto exit_1;
     }
 
+    if (!p_ses->stdev->lpi_enable && !p_ses->stdev->barge_in_mode) {
+        status = platform_stdev_update_ec_effect(p_ses->stdev->platform,
+            false);
+        if (status) {
+            ALOGE("%s: ERROR. Failed to update EC ref, %d",
+                  __func__, status);
+            goto exit_2;
+        }
+    }
+
     status = ape_start(p_ses);
     if (status)
         goto exit_2;
@@ -4080,13 +4151,15 @@
     lsm_params.num_params = 1;
     lsm_params.data_size = sizeof(lsm_param_info_t);
 
-    ST_DBG_DECLARE(FILE *req_event_fd = NULL;
-        static int req_event_cnt = 0);
-    ST_DBG_FILE_OPEN_WR(req_event_fd, ST_DEBUG_DUMP_LOCATION,
-                        "requested_event_lsm", "bin", req_event_cnt++);
-    ST_DBG_FILE_WRITE(req_event_fd, param_info.param_data,
-                      param_info.param_size);
-    ST_DBG_FILE_CLOSE(req_event_fd);
+    if (p_ses->stdev->enable_debug_dumps) {
+        ST_DBG_DECLARE(FILE *req_event_fd = NULL;
+            static int req_event_cnt = 0);
+        ST_DBG_FILE_OPEN_WR(req_event_fd, ST_DEBUG_DUMP_LOCATION,
+            "requested_event_lsm", "bin", req_event_cnt++);
+        ST_DBG_FILE_WRITE(req_event_fd, param_info.param_data,
+            param_info.param_size);
+        ST_DBG_FILE_CLOSE(req_event_fd);
+    }
 
     status = lsm_set_module_params(p_lsm_ses, &lsm_params);
     if (status)
diff --git a/st_hw_session_lsm.h b/st_hw_session_lsm.h
index 652b1bc..fa1378b 100644
--- a/st_hw_session_lsm.h
+++ b/st_hw_session_lsm.h
@@ -39,7 +39,9 @@
 struct sound_trigger_device;
 
 #define SOUND_TRIGGER_MAX_EVNT_PAYLOAD_SIZE (256)
-#define LSM_SM_PARAMS_INFO_IDX (5)
+
+/* Add extra to accomodate multiple LSM_CUSTOM_PARAMS */
+#define LSM_SM_PARAMS_INFO_MAX (LSM_PARAMS_MAX + 4)
 
 #define SOUND_TRIGGER_PCM_MAX_RETRY (10)
 #define SOUND_TRIGGER_PCM_SLEEP_WAIT (1000)
diff --git a/st_hw_session_pcm.c b/st_hw_session_pcm.c
index a8592e8..f429bc2 100644
--- a/st_hw_session_pcm.c
+++ b/st_hw_session_pcm.c
@@ -505,17 +505,19 @@
         return NULL;
     }
 
-    ST_DBG_DECLARE(FILE *fptr_cap = NULL; static int file_cnt = 0);
-    ST_DBG_FILE_OPEN_WR(fptr_cap, ST_DEBUG_DUMP_LOCATION,
-                        "ffv_capture_data", "pcm", file_cnt++);
+    if (p_pcm_ses->common.stdev->enable_debug_dumps) {
+        ST_DBG_DECLARE(FILE *fptr_cap = NULL; static int file_cnt = 0);
+        ST_DBG_FILE_OPEN_WR(fptr_cap, ST_DEBUG_DUMP_LOCATION,
+                            "ffv_capture_data", "pcm", file_cnt++);
 
-    ST_DBG_DECLARE(FILE *fptr_ec = NULL; static int file_cnt_2 = 0);
-    ST_DBG_FILE_OPEN_WR(fptr_ec, ST_DEBUG_DUMP_LOCATION,
-                        "ffv_ec_ref_data", "pcm", file_cnt_2++);
+        ST_DBG_DECLARE(FILE *fptr_ec = NULL; static int file_cnt_2 = 0);
+        ST_DBG_FILE_OPEN_WR(fptr_ec, ST_DEBUG_DUMP_LOCATION,
+                            "ffv_ec_ref_data", "pcm", file_cnt_2++);
 
-    ST_DBG_DECLARE(FILE *fptr_out = NULL; static int file_cnt_3 = 0);
-    ST_DBG_FILE_OPEN_WR(fptr_out, ST_DEBUG_DUMP_LOCATION,
-                        "ffv_out_data", "pcm", file_cnt_3++);
+        ST_DBG_DECLARE(FILE *fptr_out = NULL; static int file_cnt_3 = 0);
+        ST_DBG_FILE_OPEN_WR(fptr_out, ST_DEBUG_DUMP_LOCATION,
+                            "ffv_out_data", "pcm", file_cnt_3++);
+    }
 
     setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
     prctl(PR_SET_NAME, (unsigned long)"sound trigger process", 0, 0, 0);
@@ -539,13 +541,17 @@
         process_ec_ref_ptr = p_buf->buffer.ec_ref_buf_ptr;
         process_out_ptr = p_buf->buffer.out_buf_ptr;
 
-        ST_DBG_FILE_WRITE(fptr_cap, process_in_ptr, in_buf_size);
-        ST_DBG_FILE_WRITE(fptr_ec, process_ec_ref_ptr,
-                          p_pcm_ses->ec_ref_buf_size);
+        if (p_pcm_ses->common.stdev->enable_debug_dumps) {
+            ST_DBG_FILE_WRITE(fptr_cap, process_in_ptr, in_buf_size);
+            ST_DBG_FILE_WRITE(fptr_ec, process_ec_ref_ptr,
+                              p_pcm_ses->ec_ref_buf_size);
+        }
         ffv_process_fn(p_pcm_ses->handle, process_in_ptr,
             process_out_ptr, process_ec_ref_ptr);
-        ST_DBG_FILE_WRITE(fptr_out, process_out_ptr,
-                          p_pcm_ses->out_buf_size);
+        if (p_pcm_ses->common.stdev->enable_debug_dumps) {
+            ST_DBG_FILE_WRITE(fptr_out, process_out_ptr,
+                              p_pcm_ses->out_buf_size);
+        }
         pthread_mutex_lock(&p_pcm_ses->st_ffv_process_lock);
         process_buf_queue_push(&p_pcm_ses->process_buf_free, p_buf);
         pthread_cond_signal(&p_pcm_ses->st_ffv_capture_cond);
@@ -555,9 +561,11 @@
     p_pcm_ses->st_ffv_process_thread_started = false;
     deinit_process_buffers(p_pcm_ses);
     pthread_mutex_unlock(&p_pcm_ses->st_ffv_process_lock);
-    ST_DBG_FILE_CLOSE(fptr_cap);
-    ST_DBG_FILE_CLOSE(fptr_ec);
-    ST_DBG_FILE_CLOSE(fptr_out);
+    if (p_pcm_ses->common.stdev->enable_debug_dumps) {
+        ST_DBG_FILE_CLOSE(fptr_cap);
+        ST_DBG_FILE_CLOSE(fptr_ec);
+        ST_DBG_FILE_CLOSE(fptr_out);
+    }
     ALOGD("%s: Exit", __func__);
     return NULL;
 }
@@ -614,31 +622,35 @@
     int total_in_ch, in_ch, ec_ref_ch;
     unsigned int in_buf_size;
     static bool write_1 = true;
-    ST_DBG_DECLARE(FILE *fptr_cap = NULL; static int file_cnt = 0);
-    ST_DBG_DECLARE(FILE *fptr_ec = NULL; static int file_cnt_2 = 0);
-    ST_DBG_DECLARE(FILE *fptr_split = NULL; static int file_cnt_3 = 0);
-    ST_DBG_DECLARE(FILE *fptr_out = NULL; static int file_cnt_4 = 0);
-    ST_DBG_DECLARE(FILE *fptr_bsp_out = NULL; static int file_cnt_5 = 0);
+    if (p_pcm_ses->common.stdev->enable_debug_dumps) {
+        ST_DBG_DECLARE(FILE *fptr_cap = NULL; static int file_cnt = 0);
+        ST_DBG_DECLARE(FILE *fptr_ec = NULL; static int file_cnt_2 = 0);
+        ST_DBG_DECLARE(FILE *fptr_split = NULL; static int file_cnt_3 = 0);
+        ST_DBG_DECLARE(FILE *fptr_out = NULL; static int file_cnt_4 = 0);
+        ST_DBG_DECLARE(FILE *fptr_bsp_out = NULL; static int file_cnt_5 = 0);
+    }
 
     if (p_pcm_ses == NULL) {
         ALOGE("%s: ERROR: invalid context", __func__);
         goto exit;
     }
 
-    ST_DBG_FILE_OPEN_WR(fptr_cap, ST_DEBUG_DUMP_LOCATION,
-                        "st_capture_data", "pcm", file_cnt++);
+    if (p_pcm_ses->common.stdev->enable_debug_dumps) {
+        ST_DBG_FILE_OPEN_WR(fptr_cap, ST_DEBUG_DUMP_LOCATION,
+                            "st_capture_data", "pcm", file_cnt++);
 
-    ST_DBG_FILE_OPEN_WR(fptr_ec, ST_DEBUG_DUMP_LOCATION,
-                        "st_ec_ref_data", "pcm", file_cnt_2++);
+        ST_DBG_FILE_OPEN_WR(fptr_ec, ST_DEBUG_DUMP_LOCATION,
+                            "st_ec_ref_data", "pcm", file_cnt_2++);
 
-    ST_DBG_FILE_OPEN_WR(fptr_split, ST_DEBUG_DUMP_LOCATION,
-                        "st_split_capture_data", "pcm", file_cnt_3++);
+        ST_DBG_FILE_OPEN_WR(fptr_split, ST_DEBUG_DUMP_LOCATION,
+                            "st_split_capture_data", "pcm", file_cnt_3++);
 
-    ST_DBG_FILE_OPEN_WR(fptr_out, ST_DEBUG_DUMP_LOCATION,
-                        "st_out_data", "pcm", file_cnt_4++);
+        ST_DBG_FILE_OPEN_WR(fptr_out, ST_DEBUG_DUMP_LOCATION,
+                            "st_out_data", "pcm", file_cnt_4++);
 
-    ST_DBG_FILE_OPEN_WR(fptr_bsp_out, ST_DEBUG_DUMP_LOCATION,
-                        "st_bsp_out_data", "pcm", file_cnt_5++);
+        ST_DBG_FILE_OPEN_WR(fptr_bsp_out, ST_DEBUG_DUMP_LOCATION,
+                            "st_bsp_out_data", "pcm", file_cnt_5++);
+    }
 
     st_cpu_affinity_set(p_pcm_ses);
     setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
@@ -653,8 +665,10 @@
         status = pcm_read(p_pcm_ses->pcm, p_pcm_ses->in_buf, p_pcm_ses->in_buf_size);
         ALOGVV("%s: pcm_read done", __func__);
 
-        ST_DBG_FILE_WRITE(fptr_cap, p_pcm_ses->in_buf,
-            p_pcm_ses->in_buf_size);
+        if (p_pcm_ses->common.stdev->enable_debug_dumps) {
+            ST_DBG_FILE_WRITE(fptr_cap, p_pcm_ses->in_buf,
+                p_pcm_ses->in_buf_size);
+        }
 
         if (status) {
             ALOGE("%s: pcm read failed status %d - %s", __func__, status,
@@ -669,8 +683,10 @@
             status = pcm_read(p_pcm_ses->ec_ref_pcm, p_pcm_ses->ec_ref_buf, p_pcm_ses->ec_ref_buf_size);
             ALOGVV("%s: pcm_read done", __func__);
 
-            ST_DBG_FILE_WRITE(fptr_ec, p_pcm_ses->ec_ref_buf,
-                              p_pcm_ses->ec_ref_buf_size);
+            if (p_pcm_ses->common.stdev->enable_debug_dumps) {
+                ST_DBG_FILE_WRITE(fptr_ec, p_pcm_ses->ec_ref_buf,
+                                  p_pcm_ses->ec_ref_buf_size);
+            }
 
             if (status) {
                 ALOGE("%s: ec ref pcm read failed status %d - %s", __func__, status,
@@ -699,10 +715,12 @@
                               in_ptr[i*total_in_ch+in_ch+ch];
                 }
             }
-            ST_DBG_FILE_WRITE(fptr_split, p_pcm_ses->split_in_buf,
-                              p_pcm_ses->split_in_buf_size);
-            ST_DBG_FILE_WRITE(fptr_ec, p_pcm_ses->ec_ref_buf,
-                              p_pcm_ses->ec_ref_buf_size);
+            if (p_pcm_ses->common.stdev->enable_debug_dumps) {
+                ST_DBG_FILE_WRITE(fptr_split, p_pcm_ses->split_in_buf,
+                                  p_pcm_ses->split_in_buf_size);
+                ST_DBG_FILE_WRITE(fptr_ec, p_pcm_ses->ec_ref_buf,
+                                  p_pcm_ses->ec_ref_buf_size);
+            }
             in_buf_size = p_pcm_ses->split_in_buf_size;
         }
         process_out_ptr = (int16_t *)p_pcm_ses->out_buf;
@@ -736,10 +754,12 @@
             write_1 = false;
         }
 
-        ST_DBG_FILE_WRITE(fptr_out, process_out_ptr,
-                          p_pcm_ses->out_buf_size);
-        ST_DBG_FILE_WRITE(fptr_bsp_out, process_bsp_out_ptr,
-                          p_pcm_ses->bsp_out_buf_size);
+        if (p_pcm_ses->common.stdev->enable_debug_dumps) {
+            ST_DBG_FILE_WRITE(fptr_out, process_out_ptr,
+                              p_pcm_ses->out_buf_size);
+            ST_DBG_FILE_WRITE(fptr_bsp_out, process_bsp_out_ptr,
+                              p_pcm_ses->bsp_out_buf_size);
+        }
 #endif
         pthread_mutex_lock(&p_pcm_ses->capture_thread_lock);
     }
@@ -749,11 +769,13 @@
     ALOGD("%s: Exit status=%d", __func__, status);
     p_pcm_ses->capture_thread_started = false;
     write_1 = true;
-    ST_DBG_FILE_CLOSE(fptr_cap);
-    ST_DBG_FILE_CLOSE(fptr_ec);
-    ST_DBG_FILE_CLOSE(fptr_split);
-    ST_DBG_FILE_CLOSE(fptr_out);
-    ST_DBG_FILE_CLOSE(fptr_bsp_out);
+    if (p_pcm_ses->common.stdev->enable_debug_dumps) {
+        ST_DBG_FILE_CLOSE(fptr_cap);
+        ST_DBG_FILE_CLOSE(fptr_ec);
+        ST_DBG_FILE_CLOSE(fptr_split);
+        ST_DBG_FILE_CLOSE(fptr_out);
+        ST_DBG_FILE_CLOSE(fptr_bsp_out);
+    }
     return NULL;
 }
 
@@ -1847,9 +1869,11 @@
     p_pcm_ses->exit_lab_processing = false;
     pthread_mutex_unlock(&p_pcm_ses->lab_out_buf_lock);
 
-    ST_DBG_DECLARE(FILE *fptr_lab = NULL; static int file_cnt = 0);
-    ST_DBG_FILE_OPEN_WR(fptr_lab, ST_DEBUG_DUMP_LOCATION,
-                        "st_lab_capture_data", "pcm", file_cnt++);
+    if (p_ses->stdev->enable_debug_dumps) {
+        ST_DBG_DECLARE(FILE *fptr_lab = NULL; static int file_cnt = 0);
+        ST_DBG_FILE_OPEN_WR(fptr_lab, ST_DEBUG_DUMP_LOCATION,
+                            "st_lab_capture_data", "pcm", file_cnt++);
+    }
 
     /* Initialize pcm output buffer pointers */
     p_pcm_ses->lab_out_buf_start_ptr = p_pcm_ses->lab_out_buf;
@@ -1869,14 +1893,16 @@
             p_pcm_ses->common.fptrs->stop_buffering(&p_pcm_ses->common, true);
             break;
         }
-        ST_DBG_FILE_WRITE(fptr_lab, p_pcm_ses->lab_cap_buf, bytes);
+        if (p_ses->stdev->enable_debug_dumps)
+            ST_DBG_FILE_WRITE(fptr_lab, p_pcm_ses->lab_cap_buf, bytes);
 
         status = write_pcm_data(p_pcm_ses, p_pcm_ses->lab_cap_buf, p_pcm_ses->lab_cap_buf_size);
         if (status)
                 break;
     }
 
-    ST_DBG_FILE_CLOSE(fptr_lab);
+    if (p_ses->stdev->enable_debug_dumps)
+        ST_DBG_FILE_CLOSE(fptr_lab);
     ALOGVV("%s: Exit status=%d", __func__, status);
     return;
 }
diff --git a/st_second_stage.c b/st_second_stage.c
index 6a5c0ca..d3b81ae 100644
--- a/st_second_stage.c
+++ b/st_second_stage.c
@@ -107,8 +107,8 @@
             CNN_FRAME_SIZE) + ss_session->buf_start;
         ss_session->kw_end_idx = (result_cfg_ptr->end_position *
             CNN_FRAME_SIZE) + ss_session->buf_start;
-        ss_session->confidence_score = result_cfg_ptr->best_confidence;
     }
+    ss_session->confidence_score = result_cfg_ptr->best_confidence;
 
 exit:
     return ret;
@@ -126,6 +126,7 @@
     unsigned int det_status = KEYWORD_DETECTION_PENDING;
     uint64_t start_time = 0, end_time = 0;
     uint32_t bytes_processed_ms = 0;
+    bool first_frame_processed = false;
 
     ALOGV("%s: Enter", __func__);
 
@@ -196,8 +197,10 @@
         }
         ss_session->unread_bytes -= ss_session->buff_sz;
 
-        ST_DBG_FILE_WRITE(st_sec_stage->dump_fp, process_input_buff,
-            ss_session->buff_sz);
+        if (st_sec_stage->stdev->enable_debug_dumps) {
+            ST_DBG_FILE_WRITE(st_sec_stage->dump_fp, process_input_buff,
+                ss_session->buff_sz);
+        }
         pthread_mutex_unlock(&ss_session->lock);
         ret = process_frame_keyword_detection(ss_session, process_input_buff,
             stream_input, result_cfg_ptr, &det_status);
@@ -207,6 +210,16 @@
             break;
         }
         ss_session->bytes_processed += ss_session->buff_sz;
+        /*
+         * The CNN algorithm requires the first frame to contain the buf_start
+         * up to the kwd_end_idx, followed by any variable size for subsequent
+         * frames. Reset the subsequent frame sizes to the driver requested
+         * buffer size (ex. 120ms)
+         */
+        if (!first_frame_processed) {
+            ss_session->buff_sz = ss_session->lab_buf_sz;
+            first_frame_processed = true;
+        }
     }
 
 exit:
@@ -306,11 +319,10 @@
         goto exit;
     }
 
-    if (result_cfg_ptr->is_detected) {
+    if (result_cfg_ptr->is_detected)
         *det_status = USER_VERIFICATION_SUCCESS;
-        ss_session->confidence_score =
-            (int32_t)result_cfg_ptr->combined_user_score;
-    }
+    ss_session->confidence_score =
+        (int32_t)result_cfg_ptr->combined_user_score;
 
 exit:
     return ret;
@@ -420,8 +432,10 @@
         }
         ss_session->unread_bytes -= ss_session->buff_sz;
 
-        ST_DBG_FILE_WRITE(st_sec_stage->dump_fp, process_input_buff,
-            ss_session->buff_sz);
+        if (st_sec_stage->stdev->enable_debug_dumps) {
+            ST_DBG_FILE_WRITE(st_sec_stage->dump_fp, process_input_buff,
+                ss_session->buff_sz);
+        }
         pthread_mutex_unlock(&ss_session->lock);
         ret = process_frame_user_verification(ss_session, process_input_buff,
             stream_input, result_cfg_ptr, &det_status);
@@ -531,15 +545,23 @@
 
         if (st_sec_stage->ss_info->sm_detection_type ==
             ST_SM_TYPE_KEYWORD_DETECTION) {
-            ST_DBG_FILE_OPEN_WR(st_sec_stage->dump_fp, ST_DEBUG_DUMP_LOCATION,
-                "ss_buf_kw_det", "bin", ss_fd_cnt_kw_det++);
+            if (st_sec_stage->stdev->enable_debug_dumps) {
+                ST_DBG_FILE_OPEN_WR(st_sec_stage->dump_fp,
+                    ST_DEBUG_DUMP_LOCATION, "ss_buf_kw_det", "bin",
+                    ss_fd_cnt_kw_det++);
+            }
             start_keyword_detection(st_sec_stage);
-            ST_DBG_FILE_CLOSE(st_sec_stage->dump_fp);
+            if (st_sec_stage->stdev->enable_debug_dumps)
+                ST_DBG_FILE_CLOSE(st_sec_stage->dump_fp);
         } else {
-            ST_DBG_FILE_OPEN_WR(st_sec_stage->dump_fp, ST_DEBUG_DUMP_LOCATION,
-                "ss_buf_user_ver", "bin", ss_fd_cnt_user_ver++);
+            if (st_sec_stage->stdev->enable_debug_dumps) {
+                ST_DBG_FILE_OPEN_WR(st_sec_stage->dump_fp,
+                    ST_DEBUG_DUMP_LOCATION, "ss_buf_user_ver", "bin",
+                    ss_fd_cnt_user_ver++);
+            }
             start_user_verification(st_sec_stage);
-            ST_DBG_FILE_CLOSE(st_sec_stage->dump_fp);
+            if (st_sec_stage->stdev->enable_debug_dumps)
+                ST_DBG_FILE_CLOSE(st_sec_stage->dump_fp);
         }
     }
     pthread_mutex_unlock(&ss_session->lock);
diff --git a/st_second_stage.h b/st_second_stage.h
index 64662d8..fee487d 100644
--- a/st_second_stage.h
+++ b/st_second_stage.h
@@ -109,6 +109,7 @@
     unsigned int unread_bytes;
     bool exit_buffering;
     unsigned int buff_sz;
+    unsigned int lab_buf_sz;
     unsigned int bytes_processed;
     unsigned int buf_start;
     unsigned int buf_end;
diff --git a/st_session.c b/st_session.c
index 7e35255..7b44a64 100644
--- a/st_session.c
+++ b/st_session.c
@@ -1217,8 +1217,7 @@
     int hb_sz = 0, pr_sz = 0;
     bool active = false, enable_lab = false;
 
-    if (!st_ses->vendor_uuid_info->merge_fs_soundmodels ||
-        !st_ses->sm_info.sm_merged) {
+    if (!st_ses->vendor_uuid_info->merge_fs_soundmodels) {
         if (sthw_cfg->conf_levels) {
             ALOGV("%s: free hw conf_levels", __func__);
             free(sthw_cfg->conf_levels);
@@ -2163,14 +2162,16 @@
     int status = 0;
     bool enable_lab = false;
 
-
-    ST_DBG_DECLARE(FILE *rc_opaque_fd = NULL; static int rc_opaque_cnt = 0);
-    ST_DBG_FILE_OPEN_WR(rc_opaque_fd, ST_DEBUG_DUMP_LOCATION,
-                        "rc_config_opaque_data", "bin", rc_opaque_cnt++);
-    ST_DBG_FILE_WRITE(rc_opaque_fd,
-                      (uint8_t *)rc_config + rc_config->data_offset,
-                      rc_config->data_size);
-    ST_DBG_FILE_CLOSE(rc_opaque_fd);
+    if (st_ses->stdev->enable_debug_dumps) {
+        ST_DBG_DECLARE(FILE *rc_opaque_fd = NULL;
+            static int rc_opaque_cnt = 0);
+        ST_DBG_FILE_OPEN_WR(rc_opaque_fd, ST_DEBUG_DUMP_LOCATION,
+            "rc_config_opaque_data", "bin", rc_opaque_cnt++);
+        ST_DBG_FILE_WRITE(rc_opaque_fd,
+            (uint8_t *)rc_config + rc_config->data_offset,
+            rc_config->data_size);
+        ST_DBG_FILE_CLOSE(rc_opaque_fd);
+    }
 
     if (!st_hw_ses) {
         ALOGE("%s: NULL hw session !!!", __func__);
@@ -2452,10 +2453,14 @@
      * It is possible the BE LPI mode has been updated, but not the FE mode.
      * DSP requires both FE and BE to be in the same mode for any configuration
      * changes between LPI and non-LPI switch, so update the FE mode to the
-     * same as BE mode by re-opening LSM session.
+     * same as BE mode by re-opening LSM session. This is also used for
+     * other transition usecases which require dereg_sm and reg_sm.
      */
-    if (hw_ses->lpi_enable != hw_ses->stdev->lpi_enable) {
+    if (hw_ses->lpi_enable != hw_ses->stdev->lpi_enable ||
+        (hw_ses->barge_in_mode != hw_ses->stdev->barge_in_mode &&
+         !hw_ses->stdev->support_dynamic_ec_update)) {
         hw_ses->lpi_enable = hw_ses->stdev->lpi_enable;
+        hw_ses->barge_in_mode = hw_ses->stdev->barge_in_mode;
         if (!load_sm) {
             load_sm = true;
             status = hw_ses->fptrs->dereg_sm(hw_ses);
@@ -3214,11 +3219,14 @@
                 goto exit;
             }
 
-            ST_DBG_DECLARE(FILE *opaque_fd = NULL; static int opaque_cnt = 0);
-            ST_DBG_FILE_OPEN_WR(opaque_fd, ST_DEBUG_DUMP_LOCATION,
-                                "detection_opaque_data", "bin", opaque_cnt++);
-            ST_DBG_FILE_WRITE(opaque_fd, opaque_data, opaque_size);
-            ST_DBG_FILE_CLOSE(opaque_fd);
+            if (st_ses->stdev->enable_debug_dumps) {
+                ST_DBG_DECLARE(FILE *opaque_fd = NULL;
+                    static int opaque_cnt = 0);
+                ST_DBG_FILE_OPEN_WR(opaque_fd, ST_DEBUG_DUMP_LOCATION,
+                    "detection_opaque_data", "bin", opaque_cnt++);
+                ST_DBG_FILE_WRITE(opaque_fd, opaque_data, opaque_size);
+                ST_DBG_FILE_CLOSE(opaque_fd);
+            }
         } else {
             status = parse_generic_event_without_opaque_data(st_ses, payload,
                 payload_size, local_event);
@@ -3428,11 +3436,14 @@
                 st_hw_ses->second_stage_det_event_time;
         opaque_data += sizeof(struct st_timestamp_info);
 
-        ST_DBG_DECLARE(FILE *opaque_fd = NULL; static int opaque_cnt = 0);
-        ST_DBG_FILE_OPEN_WR(opaque_fd, ST_DEBUG_DUMP_LOCATION,
-                            "detection_opaque_data", "bin", opaque_cnt++);
-        ST_DBG_FILE_WRITE(opaque_fd, (opaque_data - opaque_size), opaque_size);
-        ST_DBG_FILE_CLOSE(opaque_fd);
+        if (st_ses->stdev->enable_debug_dumps) {
+            ST_DBG_DECLARE(FILE *opaque_fd = NULL; static int opaque_cnt = 0);
+            ST_DBG_FILE_OPEN_WR(opaque_fd, ST_DEBUG_DUMP_LOCATION,
+                                "detection_opaque_data", "bin", opaque_cnt++);
+            ST_DBG_FILE_WRITE(opaque_fd, (opaque_data - opaque_size),
+                              opaque_size);
+            ST_DBG_FILE_CLOSE(opaque_fd);
+        }
 
     } else {
         if (st_ses->vendor_uuid_info->is_qcva_uuid ||
@@ -4182,8 +4193,35 @@
 
     case ST_SES_EV_RESUME:
         stc_ses->paused = false;
-        if (!is_any_client_in_state(st_ses, ST_STATE_ACTIVE))
+        if (!is_any_client_in_state(st_ses, ST_STATE_ACTIVE)) {
+            /*
+             * When a transition is needed due to lpi mode or barge-in mode,
+             * call dereg_sm and reg_sm to select the updated lsm_usecase.
+             */
+            if (hw_ses->lpi_enable != hw_ses->stdev->lpi_enable ||
+                (hw_ses->barge_in_mode != hw_ses->stdev->barge_in_mode &&
+                 !hw_ses->stdev->support_dynamic_ec_update)) {
+
+                hw_ses->lpi_enable = hw_ses->stdev->lpi_enable;
+                hw_ses->barge_in_mode = hw_ses->stdev->barge_in_mode;
+
+                status = hw_ses->fptrs->dereg_sm(hw_ses);
+                if (status) {
+                    ALOGE("%s:[%d] failed to dereg_sm err %d", __func__,
+                        st_ses->sm_handle, status);
+                    break;
+                }
+
+                status = hw_ses->fptrs->reg_sm(hw_ses, st_ses->sm_info.sm_data,
+                    st_ses->sm_info.sm_size, st_ses->sm_info.sm_type);
+                if (status) {
+                    ALOGE("%s:[%d] failed to reg_sm err %d", __func__,
+                        st_ses->sm_handle, status);
+                    STATE_TRANSITION(st_ses, idle_state_fn);
+                }
+            }
             break;
+        }
         /* Fall through */
     case ST_SES_EV_START:
     case ST_SES_EV_RESTART:
@@ -4601,8 +4639,10 @@
         if (!status && st_ses->lab_enabled) {
             if (stc_ses->rc_config->capture_requested ||
                 !list_empty(&stc_ses->second_stage_list)) {
-                ST_DBG_FILE_OPEN_WR(st_ses->lab_fp, ST_DEBUG_DUMP_LOCATION,
-                    "lab_capture", "bin", file_cnt++);
+                if (st_ses->stdev->enable_debug_dumps) {
+                    ST_DBG_FILE_OPEN_WR(st_ses->lab_fp, ST_DEBUG_DUMP_LOCATION,
+                        "lab_capture", "bin", file_cnt++);
+                }
                 STATE_TRANSITION(st_ses, buffering_state_fn);
                 lab_enabled = true;
             } else {
@@ -4677,7 +4717,8 @@
          do {
              status = pthread_mutex_trylock(&st_ses->lock);
          } while (status && ((st_ses->current_state == detected_state_fn) ||
-                  (st_ses->current_state == buffering_state_fn)));
+                  (st_ses->current_state == buffering_state_fn)) &&
+                  !st_ses->stdev->ssr_offline_received);
 
         if (st_ses->current_state != detected_state_fn) {
             ALOGV("%s:[%d] client not in detected state, lock status %d",
@@ -5035,8 +5076,10 @@
         /* Note: this function may block if there is no PCM data ready*/
         hw_ses->fptrs->read_pcm(hw_ses, ev->payload.readpcm.out_buff,
             ev->payload.readpcm.out_buff_size);
-        ST_DBG_FILE_WRITE(st_ses->lab_fp, ev->payload.readpcm.out_buff,
-            ev->payload.readpcm.out_buff_size);
+        if (st_ses->stdev->enable_debug_dumps) {
+            ST_DBG_FILE_WRITE(st_ses->lab_fp, ev->payload.readpcm.out_buff,
+                ev->payload.readpcm.out_buff_size);
+        }
         break;
     case ST_SES_EV_END_BUFFERING:
         if (stc_ses == st_ses->det_stc_ses) {
@@ -5069,7 +5112,8 @@
         hw_ses->fptrs->stop_buffering(hw_ses);
         STATE_TRANSITION(st_ses, active_state_fn);
         DISPATCH_EVENT(st_ses, *ev, status);
-        ST_DBG_FILE_CLOSE(st_ses->lab_fp);
+        if (st_ses->stdev->enable_debug_dumps)
+            ST_DBG_FILE_CLOSE(st_ses->lab_fp);
         break;
 
     case ST_SES_EV_SET_DEVICE:
@@ -5643,9 +5687,9 @@
     st_proxy_session_t *st_ses = stc_ses->hw_proxy_ses;
     st_session_ev_t ev = { .ev_id = ST_SES_EV_PAUSE, .stc_ses = stc_ses };
 
-    pthread_mutex_lock(&stc_ses->lock);
+    pthread_mutex_lock(&st_ses->lock);
     DISPATCH_EVENT(st_ses, ev, status);
-    pthread_mutex_unlock(&stc_ses->lock);
+    pthread_mutex_unlock(&st_ses->lock);
     return status;
 }