Merge 47c34c8ea639c7e2ccf6b3b361473d5c534923e4 on remote branch
Change-Id: I363d75799c91e150aa82a4fd2bf0605e1f22da40
diff --git a/sound_trigger_hw.c b/sound_trigger_hw.c
index e4772cb..4a65991 100644
--- a/sound_trigger_hw.c
+++ b/sound_trigger_hw.c
@@ -793,6 +793,21 @@
if (!num_sessions) {
stdev->session_allowed = conc_allowed;
+ /*
+ * This is needed for the following usecase:
+ *
+ * 1. LPI and NLPI have different number of MICs (different devices).
+ * 2. ST session is stopped from app and unloaded while Tx active.
+ * 3. Tx stops.
+ * 4. ST session started again from app on LPI.
+ *
+ * The device disablement is missed in step 3 because the st_session was
+ * deinitialized. Thus, it is handled here.
+ */
+ if (event_type == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE &&
+ !platform_stdev_is_dedicated_sva_path(stdev->platform) &&
+ platform_stdev_backend_reset_allowed(stdev->platform))
+ platform_stdev_disable_stale_devices(stdev->platform);
pthread_mutex_unlock(&stdev->lock);
return;
}
@@ -849,12 +864,26 @@
}
} else {
if (event_type == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE) {
+ /*
+ * The reset_backend flag allows the backend device to be disabled. This should
+ * only be disallowed when in non-dedicated path mode and there is an active
+ * audio input stream.
+ */
+ stdev->reset_backend = platform_stdev_backend_reset_allowed(stdev->platform);
+ st_hw_check_and_update_lpi(stdev, p_ses);
+ stdev->vad_enable = st_hw_check_vad_support(stdev, p_ses, stdev->lpi_enable);
+
list_for_each(p_ses_node, &stdev->sound_model_list) {
p_ses = node_to_item(p_ses_node, st_session_t, list_node);
ALOGD("%s:[%d] Capture device is disabled, pause SVA session",
__func__, p_ses->sm_handle);
st_session_pause(p_ses);
}
+ /*
+ * This is needed when the session goes to loaded state, then
+ * LPI/NLPI switch happens due to Rx event.
+ */
+ platform_stdev_disable_stale_devices(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);
ALOGD("%s:[%d] Capture device is disabled, resume SVA session",
@@ -922,6 +951,15 @@
}
}
}
+ /*
+ * The device can be disabled within this thread upon reception of the device
+ * active event because audio hal does not enable the device until after returning
+ * from this callback. After this thread exits, device disablement will be
+ * disallowed until the device inactive event is received.
+ */
+ if (event_type == AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE &&
+ !platform_stdev_is_dedicated_sva_path(stdev->platform))
+ stdev->reset_backend = platform_stdev_backend_reset_allowed(stdev->platform);
pthread_mutex_unlock(&stdev->lock);
ALOGV("%s: Exit", __func__);
}
@@ -2041,11 +2079,13 @@
goto exit_1;
}
+ ALOGD("%s: second state detection %s",__func__,
+ st_session->vendor_uuid_info->second_stage_supported ? "supported" : "not supported");
/*
* Parse second stage sound models and populate the second stage list for
* this session.
*/
- if (sml_version == SML_MODEL_V3) {
+ if (sml_version == SML_MODEL_V3 && st_session->vendor_uuid_info->second_stage_supported) {
status = check_and_configure_second_stage_models(st_session, sm_payload,
num_models, phrase_sm->phrases[0].recognition_mode);
if (status) {
diff --git a/sound_trigger_platform.c b/sound_trigger_platform.c
index cefc47e..032617b 100644
--- a/sound_trigger_platform.c
+++ b/sound_trigger_platform.c
@@ -2,7 +2,7 @@
*
* This file contains the platform specific functionality.
*
- * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -128,6 +128,7 @@
#define ST_PARAM_KEY_KW_START_TOLERANCE "kw_start_tolerance"
#define ST_PARAM_KEY_KW_END_TOLERANCE "kw_end_tolerance"
#define ST_PARAM_KEY_EXECUTION_TYPE "execution_type"
+#define ST_PARAM_KEY_SECOND_STAGE_SUPPORTED "second_stage_supported"
#define ST_PARAM_KEY_EVENT_TIMESTAMP_MODE "event_timestamp_mode"
#define ST_PARAM_KEY_BACKEND_PORT_NAME "backend_port_name"
#define ST_PARAM_KEY_BACKEND_DAI_NAME "backend_dai_name"
@@ -2658,6 +2659,21 @@
}
}
+ err = str_parms_get_str(parms, ST_PARAM_KEY_SECOND_STAGE_SUPPORTED,
+ str_value, sizeof(str_value));
+ //By default set to true
+ sm_info->second_stage_supported = true;
+ if (err >= 0) {
+ str_parms_del(parms, ST_PARAM_KEY_SECOND_STAGE_SUPPORTED);
+ if (!strcmp(str_value, "true")) {
+ sm_info->second_stage_supported = true;
+ } else if (!strcmp(str_value, "false")) {
+ sm_info->second_stage_supported = false;
+ } else {
+ ALOGE("%s: invalid second stage support value set: %s", __func__, str_value);
+ }
+ }
+
err = str_parms_get_str(parms, ST_PARAM_KEY_APP_TYPE,
str_value, sizeof(str_value));
if (err >= 0) {
@@ -3797,6 +3813,22 @@
return true;
}
+bool platform_stdev_backend_reset_allowed
+(
+ void *platform
+)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ sound_trigger_device_t *stdev = my_data->stdev;
+
+ if (stdev->conc_capture_supported &&
+ stdev->tx_concurrency_active > 0 &&
+ !platform_stdev_is_dedicated_sva_path(platform))
+ return false;
+ else
+ return true;
+}
+
static int platform_stdev_get_device_sample_rate
(
struct platform_data *my_data,
@@ -4582,6 +4614,17 @@
return get_st_device(platform, v_info, device, exec_mode, false);
}
+int platform_stdev_get_device_for_cal
+(
+ void *platform,
+ struct st_vendor_info* v_info,
+ audio_devices_t device,
+ enum st_exec_mode exec_mode
+)
+{
+ return get_st_device(platform, v_info, device, exec_mode, true);
+}
+
audio_devices_t platform_stdev_get_capture_device
(
void *platform
@@ -5005,8 +5048,8 @@
if (event_type == AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE ||
event_type == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE) {
/* handle CAPTURE_DEVICE events */
- ALOGI("%s: Received DEVICE event, event type %d",
- __func__, event_type);
+ ALOGI("%s: Received DEVICE event, event type %d, usecase type %d",
+ __func__, event_type, config->u.usecase.type);
/*
* for device status events, if:
* 1. conc audio disabled - return with false to disable VA sessions
@@ -5016,10 +5059,30 @@
switch (event_type) {
case AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE:
stdev->tx_concurrency_active++;
+ switch (config->u.usecase.type) {
+ case USECASE_TYPE_VOICE_CALL:
+ stdev->conc_voice_active = true;
+ break;
+ case USECASE_TYPE_VOIP_CALL:
+ stdev->conc_voip_active = true;
+ break;
+ default:
+ break;
+ }
break;
case AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE:
if (stdev->tx_concurrency_active > 0)
stdev->tx_concurrency_active--;
+ switch (config->u.usecase.type) {
+ case USECASE_TYPE_VOICE_CALL:
+ stdev->conc_voice_active = false;
+ break;
+ case USECASE_TYPE_VOIP_CALL:
+ stdev->conc_voip_active = false;
+ break;
+ default:
+ break;
+ }
break;
default:
break;
@@ -5033,39 +5096,15 @@
ALOGI("%s: Received STREAM event, event type %d, usecase type %d",
__func__, event_type, config->u.usecase.type);
switch (event_type) {
- case AUDIO_EVENT_CAPTURE_STREAM_ACTIVE:
- switch (config->u.usecase.type) {
- case USECASE_TYPE_VOICE_CALL:
- stdev->conc_voice_active = true;
- break;
- case USECASE_TYPE_VOIP_CALL:
- stdev->conc_voip_active = true;
- break;
- default:
- break;
- }
- break;
- case AUDIO_EVENT_CAPTURE_STREAM_INACTIVE:
- switch (config->u.usecase.type) {
- case USECASE_TYPE_VOICE_CALL:
- stdev->conc_voice_active = false;
- break;
- case USECASE_TYPE_VOIP_CALL:
- stdev->conc_voip_active = false;
- break;
- default:
- break;
- }
- break;
- case AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE:
- stdev->rx_concurrency_active++;
- break;
- case AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE:
- if (stdev->rx_concurrency_active > 0)
- stdev->rx_concurrency_active--;
- break;
- default:
- break;
+ case AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE:
+ stdev->rx_concurrency_active++;
+ break;
+ case AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE:
+ if (stdev->rx_concurrency_active > 0)
+ stdev->rx_concurrency_active--;
+ break;
+ default:
+ break;
}
if (event_type == AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE ||
event_type == AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE) {
@@ -5085,15 +5124,20 @@
}
/*
- * Mark reset_backend as false to prevent disabling tx
- * device when pausing VA sessions.
+ * This disablement of VOIP/Voice flags is needed for the following usecase:
+ *
+ * 1. VOIP/Voice and AR active.
+ * 2. VOIP/Voice stops - AHAL sends stream inactive events for each stream,
+ * followed by the shared device inactive and device active events which
+ * both have VOIP/voice usecase, followed by one stream active event for AR.
+ * 3. AR stops - stream and device inactive events with pcm capture usecase.
+ *
+ * In this usecase the VOIP/voice flags get stuck set to true, so reset them here.
*/
- if (stdev->conc_capture_supported &&
- stdev->tx_concurrency_active > 0 &&
- (!platform_stdev_is_dedicated_sva_path(stdev->platform)))
- stdev->reset_backend = false;
- else
- stdev->reset_backend = true;
+ if (stdev->tx_concurrency_active == 0) {
+ stdev->conc_voice_active = false;
+ stdev->conc_voip_active = false;
+ }
ALOGD("%s: dedicated path %d, reset backend %d, tx %d, rx %d,"
" concurrency session%s allowed",
@@ -5893,6 +5937,45 @@
return app_type;
}
+void platform_stdev_disable_stale_devices
+(
+ void *platform
+)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ sound_trigger_device_t *stdev = my_data->stdev;
+ char st_device_name[DEVICE_NAME_MAX_SIZE] = {0};
+
+ /*
+ * There can be stale devices while exec_mode is NONE with the
+ * below usecase:
+ *
+ * 1. SVA is active in non-dedicated path mode.
+ * 2. Tx starts, transitioning SVA to NLPI.
+ * 3. SVA stops and unloads, but cannot disable the BE device.
+ * 4. Tx stops - this function will get called with exec_mode NONE.
+ */
+ if (stdev->exec_mode == ST_EXEC_MODE_ADSP ||
+ (stdev->exec_mode == ST_EXEC_MODE_NONE &&
+ !stdev->is_gcs)) {
+ pthread_mutex_lock(&stdev->ref_cnt_lock);
+ for (int i = ST_DEVICE_MIN; i < ST_DEVICE_MAX; i++) {
+ if (0 < stdev->dev_enable_cnt[i]) {
+ platform_stdev_get_device_name(stdev->platform,
+ ST_EXEC_MODE_ADSP, i, st_device_name);
+ ALOGD("%s: disable device (%x) = %s", __func__, i,
+ st_device_name);
+ ATRACE_BEGIN("sthal: audio_route_reset_and_update_path");
+ audio_route_reset_and_update_path(stdev->audio_route,
+ st_device_name);
+ ATRACE_END();
+ --(stdev->dev_enable_cnt[i]);
+ }
+ }
+ pthread_mutex_unlock(&stdev->ref_cnt_lock);
+ }
+}
+
static void check_and_append_ec_ref_device_name
(
void *platform,
diff --git a/sound_trigger_platform.h b/sound_trigger_platform.h
index 1ffda2a..0ec821d 100644
--- a/sound_trigger_platform.h
+++ b/sound_trigger_platform.h
@@ -1,6 +1,6 @@
/* sound_trigger_platform.h
*
- * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -377,6 +377,7 @@
unsigned int avail_transit_ape_phrases;
unsigned int avail_transit_ape_users;
st_exec_mode_config_t exec_mode_cfg;
+ bool second_stage_supported;
bool lpi_enable;
bool vad_enable;
struct lab_dam_cfg_payload lab_dam_cfg_payload;
@@ -450,6 +451,14 @@
st_exec_mode_t exec_mode
);
+int platform_stdev_get_device_for_cal
+(
+ void *platform,
+ struct st_vendor_info* v_info,
+ audio_devices_t device,
+ st_exec_mode_t exec_mode
+);
+
int platform_stdev_get_acdb_id
(
st_device_t st_device,
@@ -652,6 +661,11 @@
char *use_case
);
+void platform_stdev_disable_stale_devices
+(
+ void *platform
+);
+
void platform_stdev_check_and_update_ec_ref_config
(
void *platform,
@@ -711,6 +725,11 @@
void *platform
);
+bool platform_stdev_backend_reset_allowed
+(
+ void *platform
+);
+
int platform_stdev_derive_mixer_ctl_from_backend
(
void *platform,
diff --git a/st_hw_common.c b/st_hw_common.c
index 1255c43..97624cb 100644
--- a/st_hw_common.c
+++ b/st_hw_common.c
@@ -205,7 +205,8 @@
}
if (stdev->rx_concurrency_active || stdev->conc_voice_active ||
- stdev->conc_voip_active) {
+ stdev->conc_voip_active ||
+ !platform_stdev_backend_reset_allowed(stdev->platform)) {
ALOGD("%s: lpi NOT supported due to concurrency", __func__);
return;
}
diff --git a/st_hw_session_lsm.c b/st_hw_session_lsm.c
index 62f53d0..6198c20 100644
--- a/st_hw_session_lsm.c
+++ b/st_hw_session_lsm.c
@@ -574,6 +574,8 @@
st_hw_session_lsm_t *p_lsm_ses = (st_hw_session_lsm_t *)p_ses;
st_profile_type_t profile_type = get_profile_type(p_ses);
char use_case[USECASE_STRING_SIZE];
+ audio_devices_t capture_device = 0;
+ st_device_t st_device = 0;
if (enable) {
strlcpy(use_case,
@@ -582,8 +584,11 @@
platform_stdev_check_and_append_usecase(p_ses->stdev->platform,
use_case);
ALOGD("%s: enable use case = %s", __func__, use_case);
+ capture_device = platform_stdev_get_capture_device(p_ses->stdev->platform);
+ st_device = platform_stdev_get_device_for_cal(p_ses->stdev->platform,
+ p_ses->vendor_uuid_info, capture_device, p_ses->exec_mode);
platform_stdev_send_stream_app_type_cfg(p_ses->stdev->platform,
- p_lsm_ses->pcm_id, p_ses->st_device,
+ p_lsm_ses->pcm_id, st_device,
p_ses->exec_mode, profile_type);
platform_stdev_send_ec_ref_cfg(p_ses->stdev->platform, profile_type, true);
@@ -2174,8 +2179,10 @@
* Custom config is mandatory for adsp multi-stage session,
* Default config would be sent if not explicitly set from client applicaiton.
*/
- if ((p_ses->custom_data_size && !disable_custom_config) ||
- !list_empty(&p_ses->lsm_ss_cfg_list)) {
+ ALOGD("%s: second state detection %s",__func__,
+ p_ses->vendor_uuid_info->second_stage_supported ? "supported" : "not supported");
+ if (((p_ses->custom_data_size && !disable_custom_config) ||
+ !list_empty(&p_ses->lsm_ss_cfg_list)) && p_ses->vendor_uuid_info->second_stage_supported) {
/* fill opaque data as custom params */
cus_params = ¶m_info[param_count++];
if (param_tag_tracker & PARAM_CUSTOM_CONFIG_BIT) {