Merge "hal: audio_extn: fix speaker protection initial cal issue"
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index e443f06..8c893c6 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -224,6 +224,7 @@
#define audio_extn_sound_trigger_set_parameters(adev, parms) (0)
#define audio_extn_sound_trigger_check_and_get_session(in) (0)
#define audio_extn_sound_trigger_stop_lab(in) (0)
+#define audio_extn_sound_trigger_read(in, buffer, bytes) (0)
#else
enum st_event_type {
@@ -244,6 +245,8 @@
struct str_parms *parms);
void audio_extn_sound_trigger_check_and_get_session(struct stream_in *in);
void audio_extn_sound_trigger_stop_lab(struct stream_in *in);
+int audio_extn_sound_trigger_read(struct stream_in *in, void *buffer,
+ size_t bytes);
#endif
#ifndef AUXPCM_BT_ENABLED
diff --git a/hal/audio_extn/soundtrigger.c b/hal/audio_extn/soundtrigger.c
index 9051334..3c16c88 100644
--- a/hal/audio_extn/soundtrigger.c
+++ b/hal/audio_extn/soundtrigger.c
@@ -30,6 +30,7 @@
/* #define LOG_NDEBUG 0 */
#define LOG_NDDEBUG 0
+#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include <dlfcn.h>
@@ -64,7 +65,7 @@
{
struct sound_trigger_info *st_ses_info = NULL;
struct listnode *node;
- ALOGD("%s: list %d capture_handle %d", __func__,
+ ALOGV("%s: list empty %d capture_handle %d", __func__,
list_empty(&st_dev->st_ses_list), capture_handle);
list_for_each(node, &st_dev->st_ses_list) {
st_ses_info = node_to_item(node, struct sound_trigger_info , list);
@@ -128,6 +129,45 @@
return status;
}
+int audio_extn_sound_trigger_read(struct stream_in *in, void *buffer,
+ size_t bytes)
+{
+ int ret = -1;
+ struct sound_trigger_info *st_info = NULL;
+ audio_event_info_t event;
+
+ if (!st_dev)
+ return ret;
+
+ if (!in->is_st_session_active) {
+ ALOGE(" %s: Sound trigger is not active", __func__);
+ goto exit;
+ }
+ if(in->standby)
+ in->standby = false;
+
+ pthread_mutex_lock(&st_dev->lock);
+ st_info = get_sound_trigger_info(in->capture_handle);
+ pthread_mutex_unlock(&st_dev->lock);
+ if (st_info) {
+ event.u.aud_info.ses_info = &st_info->st_ses;
+ event.u.aud_info.buf = buffer;
+ event.u.aud_info.num_bytes = bytes;
+ ret = st_dev->st_callback(AUDIO_EVENT_READ_SAMPLES, &event);
+ }
+
+exit:
+ if (ret) {
+ if (-ENETRESET == ret)
+ in->is_st_session_active = false;
+ memset(buffer, 0, bytes);
+ ALOGV("%s: read failed status %d - sleep", __func__, ret);
+ usleep((bytes * 1000000) / (audio_stream_in_frame_size((struct audio_stream_in *)in) *
+ in->config.rate));
+ }
+ return ret;
+}
+
void audio_extn_sound_trigger_stop_lab(struct stream_in *in)
{
int status = 0;
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 62d3cc9..4bc6b59 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -377,7 +377,10 @@
return -ENOSYS;
pthread_mutex_lock(&adev->snd_card_status.lock);
- adev->snd_card_status.state = snd_scard_state;
+ if (adev->snd_card_status.state != snd_scard_state) {
+ adev->snd_card_status.state = snd_scard_state;
+ platform_snd_card_update(adev->platform, snd_scard_state);
+ }
pthread_mutex_unlock(&adev->snd_card_status.lock);
return 0;
@@ -2623,31 +2626,29 @@
pthread_mutex_lock(&in->lock);
- if (in->pcm) {
- if(SND_CARD_STATE_OFFLINE == snd_scard_state) {
- ALOGD(" %s: sound card is not active/SSR state", __func__);
- ret= -EIO;;
- goto exit;
- } else {
- if (in->is_st_session && !in->is_st_session_active) {
- ALOGD(" %s: Sound trigger is not active/SSR", __func__);
- ret= -EIO;;
- goto exit;
- }
- }
+ if (in->is_st_session) {
+ ALOGVV(" %s: reading on st session bytes=%zu", __func__, bytes);
+ /* Read from sound trigger HAL */
+ audio_extn_sound_trigger_read(in, buffer, bytes);
+ pthread_mutex_unlock(&in->lock);
+ return bytes;
+ }
+
+ if (in->pcm && (SND_CARD_STATE_OFFLINE == snd_scard_state)) {
+ ALOGD(" %s: sound card is not active/SSR state", __func__);
+ ret= -EIO;;
+ goto exit;
}
if (in->standby) {
- if (!in->is_st_session) {
- pthread_mutex_lock(&adev->lock);
- if (in->usecase == USECASE_COMPRESS_VOIP_CALL)
- ret = voice_extn_compress_voip_start_input_stream(in);
- else
- ret = start_input_stream(in);
- pthread_mutex_unlock(&adev->lock);
- if (ret != 0) {
- goto exit;
- }
+ pthread_mutex_lock(&adev->lock);
+ if (in->usecase == USECASE_COMPRESS_VOIP_CALL)
+ ret = voice_extn_compress_voip_start_input_stream(in);
+ else
+ ret = start_input_stream(in);
+ pthread_mutex_unlock(&adev->lock);
+ if (ret != 0) {
+ goto exit;
}
in->standby = 0;
}
@@ -2677,17 +2678,9 @@
exit:
/* ToDo: There may be a corner case when SSR happens back to back during
start/stop. Need to post different error to handle that. */
- if (-ENETRESET == ret) {
- /* CPE SSR results in kernel returning ENETRESET for sound trigger
- session reading on LAB data. In this case do not set sound card state
- offline, instead mark this sound trigger session inactive to avoid
- further reading of LAB data from CPE driver. Marking the session
- inactive handles both CPE and ADSP SSR for sound trigger session */
- if (!in->is_st_session)
- set_snd_card_state(adev,SND_CARD_STATE_OFFLINE);
- else
- in->is_st_session_active = false;
- }
+ if (-ENETRESET == ret)
+ set_snd_card_state(adev,SND_CARD_STATE_OFFLINE);
+
pthread_mutex_unlock(&in->lock);
if (ret != 0) {
@@ -3402,7 +3395,7 @@
}
static int adev_open_input_stream(struct audio_hw_device *dev,
- audio_io_handle_t handle __unused,
+ audio_io_handle_t handle,
audio_devices_t devices,
struct audio_config *config,
struct audio_stream_in **stream_in,
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index ed293e1..3a8f314 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -172,6 +172,7 @@
acdb_loader_get_calibration_t acdb_loader_get_calibration;
typedef int (*acdb_set_audio_cal_t) (void *, void *, uint32_t);
typedef int (*acdb_get_audio_cal_t) (void *, void *, uint32_t*);
+typedef int (*acdb_send_common_top_t) (void);
typedef struct codec_backend_cfg {
uint32_t sample_rate;
@@ -203,6 +204,7 @@
bool hd_voice;
bool ec_ref_enabled;
bool is_wsa_speaker;
+ bool is_acdb_initialized;
/* Audio calibration related functions */
void *acdb_handle;
int voice_feature_set;
@@ -214,6 +216,7 @@
acdb_send_voice_cal_t acdb_send_voice_cal;
acdb_reload_vocvoltable_t acdb_reload_vocvoltable;
acdb_get_default_app_type_t acdb_get_default_app_type;
+ acdb_send_common_top_t acdb_send_common_top;
#ifdef RECORD_PLAY_CONCURRENCY
bool rec_play_conc_set;
#endif
@@ -1193,6 +1196,37 @@
ALOGE("%s: Could not send anc cal", __FUNCTION__);
}
+static int platform_acdb_init(void *platform)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ char *cvd_version = NULL;
+ int key = 0;
+ const char *snd_card_name;
+ int result;
+ char value[PROPERTY_VALUE_MAX];
+ cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
+ if (!cvd_version)
+ ALOGE("Failed to allocate cvd version");
+ else
+ get_cvd_version(cvd_version, my_data->adev);
+
+ property_get("audio.ds1.metainfo.key",value,"0");
+ key = atoi(value);
+ snd_card_name = mixer_get_name(my_data->adev->mixer);
+ result = my_data->acdb_init(snd_card_name, cvd_version, key);
+ if (cvd_version)
+ free(cvd_version);
+ if (!result) {
+ my_data->is_acdb_initialized = true;
+ ALOGD("ACDB initialized");
+ audio_hwdep_send_cal(my_data);
+ } else {
+ my_data->is_acdb_initialized = false;
+ ALOGD("ACDB initialization failed");
+ }
+ return result;
+}
+
void *platform_init(struct audio_device *adev)
{
char platform[PROPERTY_VALUE_MAX];
@@ -1319,8 +1353,6 @@
acdb_device_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 131;
acdb_device_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = 131;
}
- property_get("audio.ds1.metainfo.key",value,"0");
- key = atoi(value);
my_data->voice_feature_set = VOICE_FEATURE_SET_DEFAULT;
my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
@@ -1371,21 +1403,20 @@
ALOGE("%s: Could not find the symbol acdb_get_default_app_type from %s",
__func__, LIB_ACDB_LOADER);
+ my_data->acdb_send_common_top = (acdb_send_common_top_t)dlsym(
+ my_data->acdb_handle,
+ "acdb_loader_send_common_custom_topology");
+ if (!my_data->acdb_send_common_top)
+ ALOGE("%s: Could not find the symbol acdb_get_default_app_type from %s",
+ __func__, LIB_ACDB_LOADER);
+
my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
"acdb_loader_init_v2");
if (my_data->acdb_init == NULL) {
ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
goto acdb_init_fail;
}
-
- cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
- if (!cvd_version)
- ALOGE("Failed to allocate cvd version");
- else
- get_cvd_version(cvd_version, adev);
- my_data->acdb_init(snd_card_name, cvd_version, key);
- if (cvd_version)
- free(cvd_version);
+ platform_acdb_init(my_data);
}
audio_extn_pm_vote();
@@ -1494,6 +1525,27 @@
audio_extn_dap_hal_deinit();
}
+static int platform_is_acdb_initialized(void *platform)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ ALOGD("%s: acdb initialized %d\n", __func__, my_data->is_acdb_initialized);
+ return my_data->is_acdb_initialized;
+}
+
+void platform_snd_card_update(void *platform, int snd_scard_state)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+
+ if (snd_scard_state == SND_CARD_STATE_ONLINE) {
+ if (!platform_is_acdb_initialized(my_data)) {
+ if(platform_acdb_init(my_data))
+ ALOGE("%s: acdb initialization is failed", __func__);
+ } else if (my_data->acdb_send_common_top() < 0) {
+ ALOGD("%s: acdb did not set common topology", __func__);
+ }
+ }
+}
+
const char *platform_get_snd_device_name(snd_device_t snd_device)
{
if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 3c90a8e..875cc2c 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -173,6 +173,7 @@
acdb_loader_get_calibration_t acdb_loader_get_calibration;
typedef int (*acdb_set_audio_cal_t) (void *, void *, uint32_t);
typedef int (*acdb_get_audio_cal_t) (void *, void *, uint32_t*);
+typedef int (*acdb_send_common_top_t) (void);
typedef struct codec_backend_cfg {
uint32_t sample_rate;
@@ -204,6 +205,7 @@
bool hd_voice;
bool ec_ref_enabled;
bool is_i2s_ext_modem;
+ bool is_acdb_initialized;
/* Audio calibration related functions */
void *acdb_handle;
int voice_feature_set;
@@ -215,6 +217,7 @@
acdb_send_voice_cal_t acdb_send_voice_cal;
acdb_reload_vocvoltable_t acdb_reload_vocvoltable;
acdb_get_default_app_type_t acdb_get_default_app_type;
+ acdb_send_common_top_t acdb_send_common_top;
void *hw_info;
acdb_send_gain_dep_cal_t acdb_send_gain_dep_cal;
@@ -1095,6 +1098,37 @@
ALOGE("%s: Could not send anc cal", __FUNCTION__);
}
+static int platform_acdb_init(void *platform)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ char *cvd_version = NULL;
+ int key = 0;
+ const char *snd_card_name;
+ int result;
+ char value[PROPERTY_VALUE_MAX];
+ cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
+ if (!cvd_version)
+ ALOGE("Failed to allocate cvd version");
+ else
+ get_cvd_version(cvd_version, my_data->adev);
+
+ property_get("audio.ds1.metainfo.key",value,"0");
+ key = atoi(value);
+ snd_card_name = mixer_get_name(my_data->adev->mixer);
+ result = my_data->acdb_init(snd_card_name, cvd_version, key);
+ if (cvd_version)
+ free(cvd_version);
+ if (!result) {
+ my_data->is_acdb_initialized = true;
+ ALOGD("ACDB initialized");
+ audio_hwdep_send_cal(my_data);
+ } else {
+ my_data->is_acdb_initialized = false;
+ ALOGD("ACDB initialization failed");
+ }
+ return result;
+}
+
void *platform_init(struct audio_device *adev)
{
char platform[PROPERTY_VALUE_MAX];
@@ -1260,8 +1294,6 @@
my_data->fluence_mode = FLUENCE_BROADSIDE;
}
}
- property_get("audio.ds1.metainfo.key",value,"0");
- key = atoi(value);
my_data->voice_feature_set = VOICE_FEATURE_SET_DEFAULT;
my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
@@ -1318,6 +1350,13 @@
ALOGV("%s: Could not find the symbol acdb_loader_send_gain_dep_cal from %s",
__func__, LIB_ACDB_LOADER);
+ my_data->acdb_send_common_top = (acdb_send_common_top_t)dlsym(
+ my_data->acdb_handle,
+ "acdb_loader_send_common_custom_topology");
+ if (!my_data->acdb_send_common_top)
+ ALOGE("%s: Could not find the symbol acdb_get_default_app_type from %s",
+ __func__, LIB_ACDB_LOADER);
+
my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
"acdb_loader_init_v2");
if (my_data->acdb_init == NULL) {
@@ -1325,15 +1364,7 @@
goto acdb_init_fail;
}
- cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
- if (!cvd_version)
- ALOGE("failed to allocate cvd_version");
- else
- get_cvd_version(cvd_version, adev);
-
- my_data->acdb_init(snd_card_name, cvd_version, key);
- if (cvd_version)
- free(cvd_version);
+ platform_acdb_init(my_data);
}
acdb_init_fail:
@@ -1433,6 +1464,27 @@
audio_extn_dap_hal_deinit();
}
+static int platform_is_acdb_initialized(void *platform)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ ALOGD("%s: acdb initialized %d\n", __func__, my_data->is_acdb_initialized);
+ return my_data->is_acdb_initialized;
+}
+
+void platform_snd_card_update(void *platform, int snd_scard_state)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+
+ if (snd_scard_state == SND_CARD_STATE_ONLINE) {
+ if (!platform_is_acdb_initialized(my_data)) {
+ if(platform_acdb_init(my_data))
+ ALOGE("%s: acdb initialization is failed", __func__);
+ } else if (my_data->acdb_send_common_top() < 0) {
+ ALOGD("%s: acdb did not set common topology", __func__);
+ }
+ }
+}
+
const char *platform_get_snd_device_name(snd_device_t snd_device)
{
if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
diff --git a/hal/platform_api.h b/hal/platform_api.h
index f8749e7..921ff0b 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -90,6 +90,8 @@
/* From platform_info_parser.c */
int platform_info_init(const char *filename);
+void platform_snd_card_update(void *platform, int snd_scard_state);
+
struct audio_offload_info_t;
uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info);
uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info);