st-hal: Support non-LPI without EC

This change adds support to turn off the EC effect when echo
reference is enabled. During playback usecases, the EC effect
will remain on. During car mode, display on, and high performance
mode, the EC effect will be turned off and only noise suppression
will remain active.

Change-Id: If33c53e480cc96f853f659480c0c5218482904b0
diff --git a/sound_trigger_hw.c b/sound_trigger_hw.c
index 0489eb8..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",
@@ -865,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);
+                }
             }
         }
     }
@@ -1090,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;
@@ -1114,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) &&
@@ -1128,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) {
@@ -2002,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,
@@ -2171,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);
 
@@ -2408,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);
@@ -3014,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 5780bc5..4117d32 100644
--- a/sound_trigger_hw.h
+++ b/sound_trigger_hw.h
@@ -261,6 +261,10 @@
     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;
diff --git a/sound_trigger_platform.c b/sound_trigger_platform.c
index fade7ad..5ccdd71 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"
@@ -739,6 +741,8 @@
     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;
@@ -1059,6 +1063,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);
@@ -2232,12 +2244,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;
+            }
         }
     }
 
@@ -5005,6 +5033,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__);
 
@@ -5023,12 +5052,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;
@@ -5382,6 +5431,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,
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 69d71f6..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,30 +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->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) {
@@ -221,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
@@ -296,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_lsm.c b/st_hw_session_lsm.c
index c6d0413..68c5355 100644
--- a/st_hw_session_lsm.c
+++ b/st_hw_session_lsm.c
@@ -2505,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){
@@ -3922,6 +3932,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;
diff --git a/st_session.c b/st_session.c
index 8dd1bae..209874f 100644
--- a/st_session.c
+++ b/st_session.c
@@ -2453,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);