Merge "st-hal: Fix pcm NULL dereference"
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 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..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"
@@ -400,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;
@@ -739,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;
@@ -1059,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);
@@ -2232,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;
+ }
}
}
@@ -5005,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__);
@@ -5023,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;
@@ -5382,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,
@@ -5391,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));
@@ -5412,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_lsm.c b/st_hw_session_lsm.c
index d68a662..ec2a63b 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){
@@ -3927,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;
diff --git a/st_session.c b/st_session.c
index 8dd1bae..b946f5f 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);
@@ -4188,8 +4192,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: