hal: update snd device selection in auto hal
Use BUS device associated usecases for SND
device selection on automotive platform.
The criteria for SND device selection are
* HFP calls: usecase->id;
* NON HFP calls: out->car_audio_stream.
Change-Id: If5eb1283e6bfec074efceb4f545a28fdd3dbf601
Signed-off-by: Guodong Hu <guodhu@codeaurora.org>
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index c0784d3..70d9306 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -5465,10 +5465,6 @@
typedef bool (*auto_hal_is_bus_device_usecase_t)(audio_usecase_t);
static auto_hal_is_bus_device_usecase_t auto_hal_is_bus_device_usecase;
-typedef snd_device_t (*auto_hal_get_snd_device_for_car_audio_stream_t)(
- struct stream_out*);
-static auto_hal_get_snd_device_for_car_audio_stream_t auto_hal_get_snd_device_for_car_audio_stream;
-
typedef int (*auto_hal_get_audio_port_t)(struct audio_hw_device*,
struct audio_port*);
static auto_hal_get_audio_port_t auto_hal_get_audio_port;
@@ -5489,6 +5485,14 @@
struct audio_usecase*);
static auto_hal_stop_hfp_downlink_t auto_hal_stop_hfp_downlink;
+typedef snd_device_t (*auto_hal_get_input_snd_device_t)(struct audio_device*,
+ audio_usecase_t);
+static auto_hal_get_input_snd_device_t auto_hal_get_input_snd_device;
+
+typedef snd_device_t (*auto_hal_get_output_snd_device_t)(struct audio_device*,
+ audio_usecase_t);
+static auto_hal_get_output_snd_device_t auto_hal_get_output_snd_device;
+
int auto_hal_feature_init(bool is_feature_enabled)
{
ALOGD("%s: Called with feature %s", __func__,
@@ -5521,9 +5525,6 @@
!(auto_hal_is_bus_device_usecase =
(auto_hal_is_bus_device_usecase_t)dlsym(
auto_hal_lib_handle, "auto_hal_is_bus_device_usecase")) ||
- !(auto_hal_get_snd_device_for_car_audio_stream =
- (auto_hal_get_snd_device_for_car_audio_stream_t)dlsym(
- auto_hal_lib_handle, "auto_hal_get_snd_device_for_car_audio_stream")) ||
!(auto_hal_get_audio_port =
(auto_hal_get_audio_port_t)dlsym(
auto_hal_lib_handle, "auto_hal_get_audio_port")) ||
@@ -5538,7 +5539,13 @@
auto_hal_lib_handle, "auto_hal_start_hfp_downlink")) ||
!(auto_hal_stop_hfp_downlink =
(auto_hal_stop_hfp_downlink_t)dlsym(
- auto_hal_lib_handle, "auto_hal_stop_hfp_downlink"))) {
+ auto_hal_lib_handle, "auto_hal_stop_hfp_downlink")) ||
+ !(auto_hal_get_input_snd_device =
+ (auto_hal_get_input_snd_device_t)dlsym(
+ auto_hal_lib_handle, "auto_hal_get_input_snd_device")) ||
+ !(auto_hal_get_output_snd_device =
+ (auto_hal_get_output_snd_device_t)dlsym(
+ auto_hal_lib_handle, "auto_hal_get_output_snd_device"))) {
ALOGE("%s: dlsym failed", __func__);
goto feature_disabled;
}
@@ -5559,12 +5566,13 @@
auto_hal_get_car_audio_stream_from_address = NULL;
auto_hal_open_output_stream = NULL;
auto_hal_is_bus_device_usecase = NULL;
- auto_hal_get_snd_device_for_car_audio_stream = NULL;
auto_hal_get_audio_port = NULL;
auto_hal_set_audio_port_config = NULL;
auto_hal_set_parameters = NULL;
auto_hal_start_hfp_downlink = NULL;
auto_hal_stop_hfp_downlink = NULL;
+ auto_hal_get_input_snd_device = NULL;
+ auto_hal_get_output_snd_device = NULL;
ALOGW(":: %s: ---- Feature AUTO_HAL is disabled ----", __func__);
return -ENOSYS;
@@ -5584,6 +5592,8 @@
auto_hal_init_config.fp_select_devices = select_devices;
auto_hal_init_config.fp_disable_audio_route = disable_audio_route;
auto_hal_init_config.fp_disable_snd_device = disable_snd_device;
+ auto_hal_init_config.fp_adev_get_active_input = adev_get_active_input;
+ auto_hal_init_config.fp_platform_set_echo_reference = platform_set_echo_reference;
return auto_hal_init(adev, auto_hal_init_config);
}
else
@@ -5622,25 +5632,19 @@
int audio_extn_auto_hal_get_car_audio_stream_from_address(const char *address)
{
return ((auto_hal_get_car_audio_stream_from_address) ?
- auto_hal_get_car_audio_stream_from_address(address): 0);
+ auto_hal_get_car_audio_stream_from_address(address): -ENOSYS);
}
int audio_extn_auto_hal_open_output_stream(struct stream_out *out)
{
return ((auto_hal_open_output_stream) ?
- auto_hal_open_output_stream(out): 0);
+ auto_hal_open_output_stream(out): -ENOSYS);
}
bool audio_extn_auto_hal_is_bus_device_usecase(audio_usecase_t uc_id)
{
return ((auto_hal_is_bus_device_usecase) ?
- auto_hal_is_bus_device_usecase(uc_id): 0);
-}
-
-snd_device_t audio_extn_auto_hal_get_snd_device_for_car_audio_stream(struct stream_out *out)
-{
- return ((auto_hal_get_snd_device_for_car_audio_stream) ?
- auto_hal_get_snd_device_for_car_audio_stream(out): 0);
+ auto_hal_is_bus_device_usecase(uc_id): false);
}
int audio_extn_auto_hal_get_audio_port(struct audio_hw_device *dev,
@@ -5677,6 +5681,20 @@
return ((auto_hal_stop_hfp_downlink) ?
auto_hal_stop_hfp_downlink(adev, uc_info): 0);
}
+
+snd_device_t audio_extn_auto_hal_get_input_snd_device(struct audio_device *adev,
+ audio_usecase_t uc_id)
+{
+ return ((auto_hal_get_input_snd_device) ?
+ auto_hal_get_input_snd_device(adev, uc_id): SND_DEVICE_NONE);
+}
+
+snd_device_t audio_extn_auto_hal_get_output_snd_device(struct audio_device *adev,
+ audio_usecase_t uc_id)
+{
+ return ((auto_hal_get_output_snd_device) ?
+ auto_hal_get_output_snd_device(adev, uc_id): SND_DEVICE_NONE);
+}
// END: AUTO_HAL ===================================================================
void audio_extn_feature_init()
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 36d2367..5402b81 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -1315,7 +1315,6 @@
int audio_extn_auto_hal_get_car_audio_stream_from_address(const char *address);
int audio_extn_auto_hal_open_output_stream(struct stream_out *out);
bool audio_extn_auto_hal_is_bus_device_usecase(audio_usecase_t uc_id);
-snd_device_t audio_extn_auto_hal_get_snd_device_for_car_audio_stream(struct stream_out *out);
int audio_extn_auto_hal_get_audio_port(struct audio_hw_device *dev,
struct audio_port *config);
int audio_extn_auto_hal_set_audio_port_config(struct audio_hw_device *dev,
@@ -1326,11 +1325,16 @@
struct audio_usecase *uc_info);
int audio_extn_auto_hal_stop_hfp_downlink(struct audio_device *adev,
struct audio_usecase *uc_info);
+snd_device_t audio_extn_auto_hal_get_input_snd_device(struct audio_device *adev,
+ audio_usecase_t uc_id);
+snd_device_t audio_extn_auto_hal_get_output_snd_device(struct audio_device *adev,
+ audio_usecase_t uc_id);
typedef streams_input_ctxt_t* (*fp_in_get_stream_t)(struct audio_device*, audio_io_handle_t);
typedef streams_output_ctxt_t* (*fp_out_get_stream_t)(struct audio_device*, audio_io_handle_t);
typedef size_t (*fp_get_output_period_size_t)(uint32_t, audio_format_t, int, int);
typedef int (*fp_audio_extn_ext_hw_plugin_set_audio_gain_t)(void*, struct audio_usecase*, uint32_t);
+typedef struct stream_in* (*fp_adev_get_active_input_t)(const struct audio_device*);
typedef struct auto_hal_init_config {
fp_in_get_stream_t fp_in_get_stream;
@@ -1343,6 +1347,8 @@
fp_select_devices_t fp_select_devices;
fp_disable_audio_route_t fp_disable_audio_route;
fp_disable_snd_device_t fp_disable_snd_device;
+ fp_adev_get_active_input_t fp_adev_get_active_input;
+ fp_platform_set_echo_reference_t fp_platform_set_echo_reference;
} auto_hal_init_config_t;
// END: AUTO_HAL FEATURE ==================================================
diff --git a/hal/audio_extn/auto_hal.c b/hal/audio_extn/auto_hal.c
index df0fcca..739d564 100644
--- a/hal/audio_extn/auto_hal.c
+++ b/hal/audio_extn/auto_hal.c
@@ -57,6 +57,8 @@
static fp_select_devices_t fp_select_devices;
static fp_disable_audio_route_t fp_disable_audio_route;
static fp_disable_snd_device_t fp_disable_snd_device;
+static fp_adev_get_active_input_t fp_adev_get_active_input;
+static fp_platform_set_echo_reference_t fp_platform_set_echo_reference;
/* Auto hal module struct */
static struct auto_hal_module *auto_hal = NULL;
@@ -773,6 +775,145 @@
return ret;
}
+snd_device_t auto_hal_get_input_snd_device(struct audio_device *adev,
+ audio_usecase_t uc_id)
+{
+ snd_device_t snd_device = SND_DEVICE_NONE;
+ audio_devices_t out_device = AUDIO_DEVICE_NONE;
+ struct audio_usecase *usecase = NULL;
+ struct stream_in *in = fp_adev_get_active_input(adev);
+ audio_devices_t in_device = ((in == NULL) ?
+ AUDIO_DEVICE_NONE : in->device)
+ & ~AUDIO_DEVICE_BIT_IN;
+
+ if (uc_id == USECASE_INVALID) {
+ ALOGE("%s: Invalid usecase (%d)", __func__, uc_id);
+ return -EINVAL;
+ }
+
+ usecase = fp_get_usecase_from_list(adev, uc_id);
+ if (usecase == NULL) {
+ ALOGE("%s: Could not find the usecase (%d)", __func__, uc_id);
+ return -EINVAL;
+ }
+
+ if (usecase->stream.out == NULL) {
+ ALOGE("%s: stream.out is NULL", __func__);
+ return -EINVAL;
+ }
+
+ out_device = usecase->stream.out->devices;
+ if (out_device == AUDIO_DEVICE_NONE ||
+ out_device & AUDIO_DEVICE_BIT_IN) {
+ ALOGE("%s: Invalid output devices (%#x)", __func__, out_device);
+ return -EINVAL;
+ }
+
+ ALOGV("%s: output device(%#x), input device(%#x), usecase(%d)",
+ __func__, out_device, in_device, uc_id);
+
+ if (out_device & AUDIO_DEVICE_OUT_BUS) {
+ /* usecase->id is token as judgement for HFP calls */
+ switch (usecase->id) {
+ case USECASE_AUDIO_HFP_SCO:
+ case USECASE_AUDIO_HFP_SCO_WB:
+ snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP;
+ if (adev->enable_hfp)
+ fp_platform_set_echo_reference(adev, true, out_device);
+ break;
+ case USECASE_AUDIO_HFP_SCO_DOWNLINK:
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+ break;
+ case USECASE_AUDIO_HFP_SCO_WB_DOWNLINK:
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
+ break;
+ case USECASE_VOICE_CALL:
+ snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
+ break;
+ default:
+ ALOGE("%s: Usecase (%d) not supported", __func__, uc_id);
+ return -EINVAL;
+ }
+ } else {
+ ALOGE("%s: Output devices (%#x) not supported", __func__, out_device);
+ return -EINVAL;
+ }
+
+ return snd_device;
+}
+
+snd_device_t auto_hal_get_output_snd_device(struct audio_device *adev,
+ audio_usecase_t uc_id)
+{
+ snd_device_t snd_device = SND_DEVICE_NONE;
+ audio_devices_t devices = AUDIO_DEVICE_NONE;
+ struct audio_usecase *usecase = NULL;
+
+ if (uc_id == USECASE_INVALID) {
+ ALOGE("%s: Invalid usecase (%d)", __func__, uc_id);
+ return -EINVAL;
+ }
+
+ usecase = fp_get_usecase_from_list(adev, uc_id);
+ if (usecase == NULL) {
+ ALOGE("%s: Could not find the usecase (%d)", __func__, uc_id);
+ return -EINVAL;
+ }
+
+ if (usecase->stream.out == NULL) {
+ ALOGE("%s: stream.out is NULL", __func__);
+ return -EINVAL;
+ }
+
+ devices = usecase->stream.out->devices;
+ if (devices == AUDIO_DEVICE_NONE ||
+ devices & AUDIO_DEVICE_BIT_IN) {
+ ALOGE("%s: Invalid output devices (%#x)", __func__, devices);
+ return -EINVAL;
+ }
+
+ ALOGV("%s: output devices(%#x), usecase(%d)", __func__, devices, uc_id);
+
+ if (devices & AUDIO_DEVICE_OUT_BUS) {
+ /* usecase->id is token as judgement for HFP calls */
+ switch (usecase->id) {
+ case USECASE_AUDIO_HFP_SCO:
+ snd_device = SND_DEVICE_OUT_BT_SCO;
+ break;
+ case USECASE_AUDIO_HFP_SCO_WB:
+ snd_device = SND_DEVICE_OUT_BT_SCO_WB;
+ break;
+ case USECASE_AUDIO_HFP_SCO_DOWNLINK:
+ case USECASE_AUDIO_HFP_SCO_WB_DOWNLINK:
+ snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_HFP;
+ break;
+ case USECASE_VOICE_CALL:
+ snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
+ break;
+ case USECASE_AUDIO_PLAYBACK_MEDIA:
+ snd_device = SND_DEVICE_OUT_BUS_MEDIA;
+ break;
+ case USECASE_AUDIO_PLAYBACK_SYS_NOTIFICATION:
+ snd_device = SND_DEVICE_OUT_BUS_SYS;
+ break;
+ case USECASE_AUDIO_PLAYBACK_NAV_GUIDANCE:
+ snd_device = SND_DEVICE_OUT_BUS_NAV;
+ break;
+ case USECASE_AUDIO_PLAYBACK_PHONE:
+ snd_device = SND_DEVICE_OUT_BUS_PHN;
+ break;
+ default:
+ ALOGE("%s: Usecase (%d) not supported", __func__, uc_id);
+ return -EINVAL;
+ }
+ } else {
+ ALOGE("%s: Output devices (%#x) not supported", __func__, devices);
+ return -EINVAL;
+ }
+
+ return snd_device;
+}
+
int auto_hal_init(struct audio_device *adev, auto_hal_init_config_t init_config)
{
int ret = 0;
@@ -803,6 +944,8 @@
fp_select_devices = init_config.fp_select_devices;
fp_disable_audio_route = init_config.fp_disable_audio_route;
fp_disable_snd_device = init_config.fp_disable_snd_device;
+ fp_adev_get_active_input = init_config.fp_adev_get_active_input;
+ fp_platform_set_echo_reference = init_config.fp_platform_set_echo_reference;
return ret;
}
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 40cea6c..cea5e74 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -2432,11 +2432,18 @@
ALOGE("%s: stream.out is NULL", __func__);
return -EINVAL;
}
- out_snd_device = platform_get_output_snd_device(adev->platform,
- usecase->stream.out);
- in_snd_device = platform_get_input_snd_device(adev->platform,
- NULL,
- usecase->stream.out->devices);
+ if (usecase->devices & AUDIO_DEVICE_OUT_BUS) {
+ out_snd_device = audio_extn_auto_hal_get_output_snd_device(adev,
+ uc_id);
+ in_snd_device = audio_extn_auto_hal_get_input_snd_device(adev,
+ uc_id);
+ } else {
+ out_snd_device = platform_get_output_snd_device(adev->platform,
+ usecase->stream.out);
+ in_snd_device = platform_get_input_snd_device(adev->platform,
+ NULL,
+ usecase->stream.out->devices);
+ }
usecase->devices = usecase->stream.out->devices;
} else if (usecase->type == TRANSCODE_LOOPBACK_RX) {
if (usecase->stream.inout == NULL) {
@@ -2517,8 +2524,11 @@
if (out_snd_device == SND_DEVICE_NONE) {
struct stream_out *voip_out = adev->primary_output;
struct stream_in *voip_in = get_voice_communication_input(adev);
- out_snd_device = platform_get_output_snd_device(adev->platform,
- usecase->stream.out);
+ if (usecase->devices & AUDIO_DEVICE_OUT_BUS)
+ out_snd_device = audio_extn_auto_hal_get_output_snd_device(adev, uc_id);
+ else
+ out_snd_device = platform_get_output_snd_device(adev->platform,
+ usecase->stream.out);
voip_usecase = get_usecase_from_list(adev, USECASE_AUDIO_PLAYBACK_VOIP);
if (voip_usecase)
@@ -2580,10 +2590,11 @@
return 0;
}
- if ((is_btsco_device(out_snd_device,in_snd_device) && !adev->bt_sco_on) ||
- (is_a2dp_device(out_snd_device) && !audio_extn_a2dp_source_is_ready())) {
- ALOGD("SCO/A2DP is selected but they are not connected/ready hence dont route");
- return 0;
+ if (!(usecase->devices & AUDIO_DEVICE_OUT_BUS) &&
+ ((is_btsco_device(out_snd_device,in_snd_device) && !adev->bt_sco_on) ||
+ (is_a2dp_device(out_snd_device) && !audio_extn_a2dp_source_is_ready()))) {
+ ALOGD("SCO/A2DP is selected but they are not connected/ready hence dont route");
+ return 0;
}
if (out_snd_device != SND_DEVICE_NONE &&
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index f860df5..ab63925 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -6097,8 +6097,7 @@
snd_device = SND_DEVICE_OUT_BT_SCO_WB;
else
snd_device = SND_DEVICE_OUT_BT_SCO;
- } else if ((devices & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) ||
- (devices & AUDIO_DEVICE_OUT_BUS)) {
+ } else if (devices & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
if (my_data->is_vbat_speaker || my_data->is_bcl_speaker) {
if (hw_info_is_stereo_spkr(my_data->hw_info)) {
if (my_data->mono_speaker == SPKR_1)
@@ -6274,7 +6273,7 @@
snd_device = SND_DEVICE_OUT_AFE_PROXY;
audio_extn_set_afe_proxy_channel_mixer(adev, channel_count, snd_device);
} else if (devices & AUDIO_DEVICE_OUT_BUS) {
- snd_device = audio_extn_auto_hal_get_snd_device_for_car_audio_stream(out);
+ snd_device = audio_extn_auto_hal_get_output_snd_device(adev, out->usecase);
} else {
ALOGE("%s: Unknown device(s) %#x", __func__, devices);
}
@@ -6653,8 +6652,7 @@
} else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- out_device & AUDIO_DEVICE_OUT_LINE ||
- out_device & AUDIO_DEVICE_OUT_BUS) {
+ out_device & AUDIO_DEVICE_OUT_LINE) {
if (my_data->fluence_type != FLUENCE_NONE &&
(my_data->fluence_in_voice_call ||
my_data->fluence_in_hfp_call) &&