hal: Add support to set island cfg and power mode for voice usecase
Add new APIs to set/reset island cfg and power mode in rx and tx
port separately during voice call usecase.
Change-Id: I01dae7c1e16a4c995e49bb81a534371af5f886fd
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 979781e..2c90c62 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -1291,6 +1291,31 @@
snd_device = usecase->in_snd_device;
else
snd_device = usecase->out_snd_device;
+
+ /* disable island and power mode on supported device for voice call */
+ if (usecase->type == VOICE_CALL) {
+ if (usecase->in_snd_device != SND_DEVICE_NONE) {
+ if (platform_get_island_cfg_on_device(adev->platform, usecase->in_snd_device) &&
+ platform_get_power_mode_on_device(adev->platform, usecase->in_snd_device)) {
+ platform_set_island_cfg_on_device(adev, usecase->in_snd_device, false);
+ platform_set_power_mode_on_device(adev, usecase->in_snd_device, false);
+ platform_reset_island_power_status(adev->platform, usecase->in_snd_device);
+ ALOGD("%s: disable island cfg and power mode in voice tx path",
+ __func__);
+ }
+ }
+ if (usecase->out_snd_device != SND_DEVICE_NONE) {
+ if (platform_get_island_cfg_on_device(adev->platform, usecase->out_snd_device) &&
+ platform_get_power_mode_on_device(adev->platform, usecase->out_snd_device)) {
+ platform_set_island_cfg_on_device(adev, usecase->out_snd_device, false);
+ platform_set_power_mode_on_device(adev, usecase->out_snd_device, false);
+ platform_reset_island_power_status(adev->platform, usecase->out_snd_device);
+ ALOGD("%s: disable island cfg and power mode in voice rx path",
+ __func__);
+ }
+ }
+ }
+
// we shouldn't truncate mixer_path
ALOGW_IF(strlcpy(mixer_path, use_case_table[usecase->id], sizeof(mixer_path))
>= sizeof(mixer_path), "%s: truncation on mixer path", __func__);
@@ -1385,6 +1410,14 @@
} else {
ALOGD("%s: snd_device(%d: %s)", __func__, snd_device, device_name);
+ /* enable island and power mode on supported device */
+ if (platform_get_island_cfg_on_device(adev->platform, snd_device) &&
+ platform_get_power_mode_on_device(adev->platform, snd_device)) {
+ platform_set_island_cfg_on_device(adev, snd_device, true);
+ platform_set_power_mode_on_device(adev, snd_device, true);
+ ALOGD("%s: enable island cfg and power mode on: %s",
+ __func__, device_name);
+ }
if ((SND_DEVICE_OUT_BT_A2DP == snd_device) &&
(audio_extn_a2dp_start_playback() < 0)) {
@@ -1707,6 +1740,20 @@
force_routing = true;
force_restart_session = true;
}
+
+ /*
+ * Island cfg and power mode config needs to set before AFE port start.
+ * Set force routing in case of voice device was enable before.
+ */
+ if (uc_info->type == VOICE_CALL &&
+ voice_extn_is_voice_power_mode_supported() &&
+ platform_check_and_update_island_power_status(adev->platform,
+ uc_info,
+ snd_device)) {
+ force_routing = true;
+ ALOGD("%s:becf: force routing %d for power mode supported device",
+ __func__, force_routing);
+ }
ALOGD("%s:becf: force routing %d", __func__, force_routing);
/* Disable all the usecases on the shared backend other than the
@@ -1851,6 +1898,22 @@
*/
if (uc_info->type == PCM_CAPTURE)
backend_check_cond = is_codec_backend_in_device_type(&uc_info->device_list);
+
+ /*
+ * Island cfg and power mode config needs to set before AFE port start.
+ * Set force routing in case of voice device was enable before.
+ */
+
+ if (uc_info->type == VOICE_CALL &&
+ voice_extn_is_voice_power_mode_supported() &&
+ platform_check_and_update_island_power_status(adev->platform,
+ uc_info,
+ snd_device)) {
+ force_routing = true;
+ ALOGD("%s:becf: force routing %d for power mode supported device",
+ __func__, force_routing);
+ }
+
/*
* This function is to make sure that all the active capture usecases
* are always routed to the same input sound device.
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 6267200..aee2179 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -386,6 +386,8 @@
bool is_multiple_sample_rate_combo_supported;
struct listnode custom_mtmx_params_list;
struct listnode custom_mtmx_in_params_list;
+ struct power_mode_cfg power_mode_cfg[SND_DEVICE_MAX];
+ struct island_cfg island_cfg[SND_DEVICE_MAX];
};
struct spkr_device_chmap {
@@ -2224,6 +2226,11 @@
operator_specific_device_table[dev] = NULL;
external_specific_device_table[dev] = NULL;
snd_device_delay_ms[dev] = 0;
+ /* Init island cfg and power mode */
+ my_data->island_cfg[dev].mixer_ctl = NULL;
+ my_data->power_mode_cfg[dev].mixer_ctl = NULL;
+ my_data->island_cfg[dev].enable = false;
+ my_data->power_mode_cfg[dev].enable = false;
}
for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
backend_bit_width_table[dev] = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
@@ -9026,6 +9033,154 @@
return backend_idx;
}
+bool platform_get_power_mode_on_device(void *platform, snd_device_t snd_device) {
+ struct platform_data *my_data = (struct platform_data *)platform;
+
+ ALOGD("%s:power mode status on snd_device = (%s %d)", __func__,
+ platform_get_snd_device_name(snd_device),
+ my_data->power_mode_cfg[snd_device].enable);
+ return my_data->power_mode_cfg[snd_device].enable;
+
+}
+
+bool platform_get_island_cfg_on_device(void *platform, snd_device_t snd_device) {
+ struct platform_data *my_data = (struct platform_data *)platform;
+
+ ALOGD("%s:island cfg status on snd_device = (%s %d)", __func__,
+ platform_get_snd_device_name(snd_device),
+ my_data->island_cfg[snd_device].enable);
+ return my_data->island_cfg[snd_device].enable;
+}
+
+int platform_set_power_mode_on_device(struct audio_device* adev,
+ snd_device_t snd_device,
+ bool enable)
+{
+ int ret = 0;
+ struct mixer_ctl *ctl;
+ struct platform_data *my_data = (struct platform_data *)adev->platform;
+
+ ctl = mixer_get_ctl_by_name(adev->mixer,
+ my_data->power_mode_cfg[snd_device].mixer_ctl);
+
+ if (ctl) {
+ ALOGD("%s:set power mode to %s",
+ __func__, (enable == true) ? "true" : "false");
+ mixer_ctl_set_value(ctl, 0, (int)enable);
+ } else {
+ ALOGE("%s:Could not get ctl for power mode mixer", __func__);
+ ret = -EINVAL;
+ goto error;
+ }
+ return ret;
+
+error:
+ my_data->power_mode_cfg[snd_device].enable = false;
+ my_data->power_mode_cfg[snd_device].mixer_ctl = NULL;
+ return ret;
+}
+
+int platform_set_island_cfg_on_device(struct audio_device* adev,
+ snd_device_t snd_device,
+ bool enable)
+{
+ int ret = 0;
+ struct mixer_ctl *ctl;
+ struct platform_data *my_data = (struct platform_data *)adev->platform;
+
+ ctl = mixer_get_ctl_by_name(adev->mixer,
+ my_data->island_cfg[snd_device].mixer_ctl);
+
+ if (ctl) {
+ ALOGD("%s:set island cfg to %s",
+ __func__, (enable == true) ? "true" : "false");
+ mixer_ctl_set_value(ctl, 0, (int)enable);
+ } else {
+ ALOGE("%s:Could not get ctl for island cfg mixer", __func__);
+ return -EINVAL;
+ goto error;
+ }
+ return ret;
+
+error:
+ my_data->island_cfg[snd_device].enable = false;
+ my_data->island_cfg[snd_device].mixer_ctl = NULL;
+ return ret;
+}
+
+char * platform_update_power_mode_mixer_ctrl(snd_device_t snd_device)
+{
+ char mixer_ctl[MIXER_PATH_MAX_LENGTH];
+ char *power_mode_mixer_ctrl = NULL;
+ char * be_itf = hw_interface_table[snd_device];
+
+ if (be_itf != NULL) {
+ snprintf(mixer_ctl, sizeof(mixer_ctl),
+ "%s Power Mode", be_itf);
+ power_mode_mixer_ctrl = strdup(mixer_ctl);
+ ALOGD("%s: power mode mixer ctrl %s\n",
+ __func__, power_mode_mixer_ctrl);
+ }
+
+ return power_mode_mixer_ctrl;
+}
+
+char * platform_update_island_cfg_mixer_ctrl(snd_device_t snd_device)
+{
+ char mixer_ctl[MIXER_PATH_MAX_LENGTH];
+ char *island_cfg_mixer_ctrl = NULL;
+ char * be_itf = hw_interface_table[snd_device];
+
+ if (be_itf != NULL) {
+ snprintf(mixer_ctl, sizeof(mixer_ctl),
+ "%s Island Config", be_itf);
+ island_cfg_mixer_ctrl = strdup(mixer_ctl);
+ ALOGD("%s: island cfg mixer ctrl %s\n",
+ __func__, island_cfg_mixer_ctrl);
+ }
+
+ return island_cfg_mixer_ctrl;
+}
+
+bool platform_check_and_update_island_power_status(void *platform,
+ struct audio_usecase* usecase,
+ snd_device_t snd_device)
+{
+ bool ret = false;
+ struct platform_data *my_data = (struct platform_data *)platform;
+
+ if (compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_EARPIECE) ||
+ compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_WIRED_HEADSET) ||
+ compare_device_type(&usecase->device_list, AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) {
+ if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
+ /* update island and power mode in current device */
+ my_data->island_cfg[snd_device].mixer_ctl =
+ platform_update_island_cfg_mixer_ctrl(snd_device);
+ my_data->power_mode_cfg[snd_device].mixer_ctl =
+ platform_update_power_mode_mixer_ctrl(snd_device);
+ if (my_data->island_cfg[snd_device].mixer_ctl != NULL &&
+ my_data->power_mode_cfg[snd_device].mixer_ctl != NULL) {
+ /* enable island and power mode in current device */
+ my_data->island_cfg[snd_device].enable = true;
+ my_data->power_mode_cfg[snd_device].enable = true;
+ ret = true;
+ }
+ }
+ }
+
+ return ret;
+}
+
+void platform_reset_island_power_status(void *platform, snd_device_t snd_device)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+
+ my_data->island_cfg[snd_device].mixer_ctl = NULL;
+ my_data->power_mode_cfg[snd_device].mixer_ctl = NULL;
+ my_data->island_cfg[snd_device].enable = false;
+ my_data->power_mode_cfg[snd_device].enable = false;
+}
+
/*
* configures afe with bit width and Sample Rate
*/
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 9a50946..c3efd3c 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -423,5 +423,14 @@
void platform_set_audio_source_delay(audio_source_t audio_source, int delay_ms);
int platform_get_audio_source_index(const char *audio_source_name);
-
+bool platform_check_and_update_island_power_status(void *platform,
+ struct audio_usecase* usecase,
+ snd_device_t snd_device);
+bool platform_get_power_mode_on_device(void *platform, snd_device_t snd_device);
+bool platform_get_island_cfg_on_device(void *platform, snd_device_t snd_device);
+int platform_set_power_mode_on_device(struct audio_device* adev, snd_device_t snd_device,
+ bool enable);
+int platform_set_island_cfg_on_device(struct audio_device* adev, snd_device_t snd_device,
+ bool enable);
+void platform_reset_island_power_status(void *platform, snd_device_t snd_device);
#endif // AUDIO_PLATFORM_API_H
diff --git a/hal/voice.h b/hal/voice.h
index 94782b8..1f0978a 100644
--- a/hal/voice.h
+++ b/hal/voice.h
@@ -63,6 +63,16 @@
bool in_call;
};
+struct power_mode_cfg {
+ bool enable;
+ char *mixer_ctl;
+};
+
+struct island_cfg {
+ bool enable;
+ char *mixer_ctl;
+};
+
enum {
INCALL_REC_NONE = -1,
INCALL_REC_UPLINK,
diff --git a/hal/voice_extn/voice_extn.c b/hal/voice_extn/voice_extn.c
index c2e419a..1882f11 100644
--- a/hal/voice_extn/voice_extn.c
+++ b/hal/voice_extn/voice_extn.c
@@ -88,6 +88,7 @@
static bool voice_extn_dynamic_ecns_feature_enabled = false;
static bool voice_extn_incall_music_enabled = false;
static bool voice_extn_multi_session_enabled = false;
+static bool voice_extn_power_mode_enabled = false;
int voice_extn_is_call_state_active(struct audio_device *adev, bool *is_call_active);
@@ -456,6 +457,18 @@
return voice_extn_multi_session_enabled;
}
+void voice_power_mode_feature_init(bool is_feature_enabled)
+{
+ voice_extn_power_mode_enabled = is_feature_enabled;
+ ALOGV("%s:: ---- Feature POWER MODE is %s ----", __func__,
+ is_feature_enabled ? "ENABLED" : "NOT ENABLED");
+}
+
+bool voice_extn_is_voice_power_mode_supported()
+{
+ return voice_extn_power_mode_enabled;
+}
+
void voice_extn_feature_init()
{
// Register feature function here
@@ -472,6 +485,9 @@
multi_voice_session_feature_init(
property_get_bool("vendor.audio.feature.multi_voice_session.enable",
false));
+ voice_power_mode_feature_init(
+ property_get_bool("vendor.audio.feature.power_mode.enable",
+ false));
}
void voice_extn_init(struct audio_device *adev)
diff --git a/hal/voice_extn/voice_extn.h b/hal/voice_extn/voice_extn.h
index b2aab7e..09d5414 100644
--- a/hal/voice_extn/voice_extn.h
+++ b/hal/voice_extn/voice_extn.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014, 2016-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, 2016-2020, The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -86,6 +86,8 @@
bool voice_extn_is_compress_voip_supported();
void multi_voice_session_feature_init(bool is_feature_enabled);
bool voice_extn_is_multi_session_supported();
+void voice_power_mode_feature_init(bool is_feature_enabled);
+bool voice_extn_is_voice_power_mode_supported();
#endif //VOICE_EXTN_H