hal: support calibration for hfp with dual asm loopback
Add support TX and RX calibration for HFP call
on both uplink and downlink ASM loopback path.
Change-Id: I66dec9ec01e0645ba6f5c21a4e64aabd10e2b6a5
Signed-off-by: Derek Chen <chenche@codeaurora.org>
Signed-off-by: Guodong Hu <guodhu@codeaurora.org>
diff --git a/hal/audio_extn/Android.mk b/hal/audio_extn/Android.mk
index 56d9179..4d3784c 100644
--- a/hal/audio_extn/Android.mk
+++ b/hal/audio_extn/Android.mk
@@ -475,6 +475,10 @@
MULTIPLE_HW_VARIANTS_ENABLED := true
endif
+ifeq ($(TARGET_BOARD_AUTO),true)
+ LOCAL_CFLAGS += -DPLATFORM_AUTO
+endif
+
LOCAL_SRC_FILES:= \
hfp.c
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 8512a4e..c0784d3 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -4509,6 +4509,10 @@
init_config.fp_disable_audio_route = disable_audio_route;
init_config.fp_disable_snd_device = disable_snd_device;
init_config.fp_voice_get_mic_mute = voice_get_mic_mute;
+ init_config.fp_audio_extn_auto_hal_start_hfp_downlink =
+ audio_extn_auto_hal_start_hfp_downlink;
+ init_config.fp_audio_extn_auto_hal_stop_hfp_downlink =
+ audio_extn_auto_hal_stop_hfp_downlink;
hfp_init(init_config);
ALOGD("%s:: ---- Feature HFP is Enabled ----", __func__);
@@ -5477,6 +5481,14 @@
struct str_parms*);
static auto_hal_set_parameters_t auto_hal_set_parameters;
+typedef int (*auto_hal_start_hfp_downlink_t)(struct audio_device*,
+ struct audio_usecase*);
+static auto_hal_start_hfp_downlink_t auto_hal_start_hfp_downlink;
+
+typedef int (*auto_hal_stop_hfp_downlink_t)(struct audio_device*,
+ struct audio_usecase*);
+static auto_hal_stop_hfp_downlink_t auto_hal_stop_hfp_downlink;
+
int auto_hal_feature_init(bool is_feature_enabled)
{
ALOGD("%s: Called with feature %s", __func__,
@@ -5520,7 +5532,13 @@
auto_hal_lib_handle, "auto_hal_set_audio_port_config")) ||
!(auto_hal_set_parameters =
(auto_hal_set_parameters_t)dlsym(
- auto_hal_lib_handle, "auto_hal_set_parameters"))) {
+ auto_hal_lib_handle, "auto_hal_set_parameters")) ||
+ !(auto_hal_start_hfp_downlink =
+ (auto_hal_start_hfp_downlink_t)dlsym(
+ 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"))) {
ALOGE("%s: dlsym failed", __func__);
goto feature_disabled;
}
@@ -5545,6 +5563,8 @@
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;
ALOGW(":: %s: ---- Feature AUTO_HAL is disabled ----", __func__);
return -ENOSYS;
@@ -5561,6 +5581,9 @@
auto_hal_init_config.fp_get_usecase_from_list = get_usecase_from_list;
auto_hal_init_config.fp_get_output_period_size = get_output_period_size;
auto_hal_init_config.fp_audio_extn_ext_hw_plugin_set_audio_gain = audio_extn_ext_hw_plugin_set_audio_gain;
+ 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;
return auto_hal_init(adev, auto_hal_init_config);
}
else
@@ -5640,6 +5663,20 @@
if (auto_hal_set_parameters)
auto_hal_set_parameters(adev, parms);
}
+
+int audio_extn_auto_hal_start_hfp_downlink(struct audio_device *adev,
+ struct audio_usecase *uc_info)
+{
+ return ((auto_hal_start_hfp_downlink) ?
+ auto_hal_start_hfp_downlink(adev, uc_info): 0);
+}
+
+int audio_extn_auto_hal_stop_hfp_downlink(struct audio_device *adev,
+ struct audio_usecase *uc_info)
+{
+ return ((auto_hal_stop_hfp_downlink) ?
+ auto_hal_stop_hfp_downlink(adev, uc_info): 0);
+}
// 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 91204a7..36d2367 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -682,6 +682,10 @@
struct audio_usecase *);
typedef int (*fp_disable_snd_device_t)(struct audio_device *, snd_device_t);
typedef bool (*fp_voice_get_mic_mute_t)(struct audio_device *);
+typedef int (*fp_audio_extn_auto_hal_start_hfp_downlink_t)(struct audio_device *,
+ struct audio_usecase *);
+typedef int (*fp_audio_extn_auto_hal_stop_hfp_downlink_t)(struct audio_device *,
+ struct audio_usecase *);
typedef struct hfp_init_config {
fp_platform_set_mic_mute_t fp_platform_set_mic_mute;
@@ -694,6 +698,8 @@
fp_disable_audio_route_t fp_disable_audio_route;
fp_disable_snd_device_t fp_disable_snd_device;
fp_voice_get_mic_mute_t fp_voice_get_mic_mute;
+ fp_audio_extn_auto_hal_start_hfp_downlink_t fp_audio_extn_auto_hal_start_hfp_downlink;
+ fp_audio_extn_auto_hal_stop_hfp_downlink_t fp_audio_extn_auto_hal_stop_hfp_downlink;
} hfp_init_config_t;
@@ -1316,6 +1322,10 @@
const struct audio_port_config *config);
void audio_extn_auto_hal_set_parameters(struct audio_device *adev,
struct str_parms *parms);
+int audio_extn_auto_hal_start_hfp_downlink(struct audio_device *adev,
+ struct audio_usecase *uc_info);
+int audio_extn_auto_hal_stop_hfp_downlink(struct audio_device *adev,
+ struct audio_usecase *uc_info);
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);
@@ -1330,6 +1340,9 @@
fp_get_usecase_from_list_t fp_get_usecase_from_list;
fp_get_output_period_size_t fp_get_output_period_size;
fp_audio_extn_ext_hw_plugin_set_audio_gain_t fp_audio_extn_ext_hw_plugin_set_audio_gain;
+ 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;
} 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 c18b55f..df0fcca 100644
--- a/hal/audio_extn/auto_hal.c
+++ b/hal/audio_extn/auto_hal.c
@@ -54,12 +54,17 @@
static fp_get_usecase_from_list_t fp_get_usecase_from_list;
static fp_get_output_period_size_t fp_get_output_period_size;
static fp_audio_extn_ext_hw_plugin_set_audio_gain_t fp_audio_extn_ext_hw_plugin_set_audio_gain;
+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;
/* Auto hal module struct */
static struct auto_hal_module *auto_hal = NULL;
int auto_hal_release_audio_patch(struct audio_hw_device *dev,
audio_patch_handle_t handle);
+int auto_hal_stop_hfp_downlink(struct audio_device *adev,
+ struct audio_usecase *uc_info);
static struct audio_patch_record *get_patch_from_list(struct audio_device *adev,
audio_patch_handle_t patch_id)
@@ -677,6 +682,97 @@
ALOGV("%s: exit", __func__);
}
+int auto_hal_start_hfp_downlink(struct audio_device *adev,
+ struct audio_usecase *uc_info)
+{
+ int32_t ret = 0;
+ struct audio_usecase *uc_downlink_info;
+
+ ALOGD("%s: enter", __func__);
+
+ uc_downlink_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
+
+ if (!uc_downlink_info)
+ return -ENOMEM;
+
+ uc_downlink_info->type = PCM_HFP_CALL;
+ uc_downlink_info->stream.out = adev->primary_output;
+ uc_downlink_info->devices = adev->primary_output->devices;
+ uc_downlink_info->in_snd_device = SND_DEVICE_NONE;
+ uc_downlink_info->out_snd_device = SND_DEVICE_NONE;
+
+ switch (uc_info->id) {
+ case USECASE_AUDIO_HFP_SCO:
+ uc_downlink_info->id = USECASE_AUDIO_HFP_SCO_DOWNLINK;
+ break;
+ case USECASE_AUDIO_HFP_SCO_WB:
+ uc_downlink_info->id = USECASE_AUDIO_HFP_SCO_WB_DOWNLINK;
+ break;
+ default:
+ ALOGE("%s: Invalid usecase %d", __func__, uc_info->id);
+ free(uc_downlink_info);
+ return -EINVAL;
+ }
+
+ list_add_tail(&adev->usecase_list, &uc_downlink_info->list);
+
+ ret = fp_select_devices(adev, uc_downlink_info->id);
+ if (ret) {
+ ALOGE("%s: Select devices failed %d", __func__, ret);
+ goto exit;
+ }
+
+ ALOGD("%s: exit: status(%d)", __func__, ret);
+ return 0;
+
+exit:
+ auto_hal_stop_hfp_downlink(adev, uc_info);
+ ALOGE("%s: Problem in start hfp downlink: status(%d)", __func__, ret);
+ return ret;
+}
+
+int auto_hal_stop_hfp_downlink(struct audio_device *adev,
+ struct audio_usecase *uc_info)
+{
+ int32_t ret = 0;
+ struct audio_usecase *uc_downlink_info;
+ audio_usecase_t ucid;
+
+ ALOGD("%s: enter", __func__);
+
+ switch (uc_info->id) {
+ case USECASE_AUDIO_HFP_SCO:
+ ucid = USECASE_AUDIO_HFP_SCO_DOWNLINK;
+ break;
+ case USECASE_AUDIO_HFP_SCO_WB:
+ ucid = USECASE_AUDIO_HFP_SCO_WB_DOWNLINK;
+ break;
+ default:
+ ALOGE("%s: Invalid usecase %d", __func__, uc_info->id);
+ return -EINVAL;
+ }
+
+ uc_downlink_info = fp_get_usecase_from_list(adev, ucid);
+ if (uc_downlink_info == NULL) {
+ ALOGE("%s: Could not find the usecase (%d) in the list",
+ __func__, ucid);
+ return -EINVAL;
+ }
+
+ /* Get and set stream specific mixer controls */
+ fp_disable_audio_route(adev, uc_downlink_info);
+
+ /* Disable the rx and tx devices */
+ fp_disable_snd_device(adev, uc_downlink_info->out_snd_device);
+ fp_disable_snd_device(adev, uc_downlink_info->in_snd_device);
+
+ list_remove(&uc_downlink_info->list);
+ free(uc_downlink_info);
+
+ ALOGD("%s: exit: status(%d)", __func__, ret);
+ return ret;
+}
+
int auto_hal_init(struct audio_device *adev, auto_hal_init_config_t init_config)
{
int ret = 0;
@@ -704,6 +800,9 @@
fp_get_usecase_from_list = init_config.fp_get_usecase_from_list;
fp_get_output_period_size = init_config.fp_get_output_period_size;
fp_audio_extn_ext_hw_plugin_set_audio_gain = init_config.fp_audio_extn_ext_hw_plugin_set_audio_gain;
+ 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;
return ret;
}
diff --git a/hal/audio_extn/ext_hw_plugin.c b/hal/audio_extn/ext_hw_plugin.c
index 7460caa..6e784cb 100644
--- a/hal/audio_extn/ext_hw_plugin.c
+++ b/hal/audio_extn/ext_hw_plugin.c
@@ -182,6 +182,8 @@
break;
case USECASE_AUDIO_HFP_SCO:
case USECASE_AUDIO_HFP_SCO_WB:
+ case USECASE_AUDIO_HFP_SCO_DOWNLINK:
+ case USECASE_AUDIO_HFP_SCO_WB_DOWNLINK:
*plugin_usecase = AUDIO_HAL_PLUGIN_USECASE_HFP_VOICE_CALL;
break;
case USECASE_VOICE_CALL:
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index 1088a0c..9b60083 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -125,6 +125,8 @@
static fp_disable_audio_route_t fp_disable_audio_route;
static fp_disable_snd_device_t fp_disable_snd_device;
static fp_voice_get_mic_mute_t fp_voice_get_mic_mute;
+static fp_audio_extn_auto_hal_start_hfp_downlink_t fp_audio_extn_auto_hal_start_hfp_downlink;
+static fp_audio_extn_auto_hal_stop_hfp_downlink_t fp_audio_extn_auto_hal_stop_hfp_downlink;
static int32_t hfp_set_volume(struct audio_device *adev, float value)
{
@@ -332,15 +334,6 @@
ALOGD("%s: HFP PCM devices (rx: %d tx: %d pcm dev id: %d) usecase(%d)",
__func__, pcm_dev_rx_id, pcm_dev_tx_id, hfpmod.hfp_pcm_dev_id, uc_info->id);
- hfpmod.hfp_sco_rx = pcm_open(adev->snd_card,
- pcm_dev_asm_rx_id,
- PCM_OUT, &pcm_config_hfp);
- if (hfpmod.hfp_sco_rx && !pcm_is_ready(hfpmod.hfp_sco_rx)) {
- ALOGE("%s: %s", __func__, pcm_get_error(hfpmod.hfp_sco_rx));
- ret = -EIO;
- goto exit;
- }
-
hfpmod.hfp_pcm_rx = pcm_open(adev->snd_card,
pcm_dev_rx_id,
PCM_OUT, &pcm_config_hfp);
@@ -350,15 +343,6 @@
goto exit;
}
- hfpmod.hfp_sco_tx = pcm_open(adev->snd_card,
- pcm_dev_asm_tx_id,
- PCM_IN, &pcm_config_hfp);
- if (hfpmod.hfp_sco_tx && !pcm_is_ready(hfpmod.hfp_sco_tx)) {
- ALOGE("%s: %s", __func__, pcm_get_error(hfpmod.hfp_sco_tx));
- ret = -EIO;
- goto exit;
- }
-
hfpmod.hfp_pcm_tx = pcm_open(adev->snd_card,
pcm_dev_tx_id,
PCM_IN, &pcm_config_hfp);
@@ -368,17 +352,6 @@
goto exit;
}
- if (pcm_start(hfpmod.hfp_sco_rx) < 0) {
- ALOGE("%s: pcm start for hfp sco rx failed", __func__);
- ret = -EINVAL;
- goto exit;
- }
- if (pcm_start(hfpmod.hfp_sco_tx) < 0) {
- ALOGE("%s: pcm start for hfp sco tx failed", __func__);
- ret = -EINVAL;
- goto exit;
- }
-
if (pcm_start(hfpmod.hfp_pcm_rx) < 0) {
ALOGE("%s: pcm start for hfp pcm rx failed", __func__);
ret = -EINVAL;
@@ -390,6 +363,38 @@
goto exit;
}
+ if (fp_audio_extn_auto_hal_start_hfp_downlink(adev, uc_info))
+ ALOGE("%s: start hfp downlink failed", __func__);
+
+ hfpmod.hfp_sco_rx = pcm_open(adev->snd_card,
+ pcm_dev_asm_rx_id,
+ PCM_OUT, &pcm_config_hfp);
+ if (hfpmod.hfp_sco_rx && !pcm_is_ready(hfpmod.hfp_sco_rx)) {
+ ALOGE("%s: %s", __func__, pcm_get_error(hfpmod.hfp_sco_rx));
+ ret = -EIO;
+ goto exit;
+ }
+
+ hfpmod.hfp_sco_tx = pcm_open(adev->snd_card,
+ pcm_dev_asm_tx_id,
+ PCM_IN, &pcm_config_hfp);
+ if (hfpmod.hfp_sco_tx && !pcm_is_ready(hfpmod.hfp_sco_tx)) {
+ ALOGE("%s: %s", __func__, pcm_get_error(hfpmod.hfp_sco_tx));
+ ret = -EIO;
+ goto exit;
+ }
+
+ if (pcm_start(hfpmod.hfp_sco_rx) < 0) {
+ ALOGE("%s: pcm start for hfp sco rx failed", __func__);
+ ret = -EINVAL;
+ goto exit;
+ }
+ if (pcm_start(hfpmod.hfp_sco_tx) < 0) {
+ ALOGE("%s: pcm start for hfp sco tx failed", __func__);
+ ret = -EINVAL;
+ goto exit;
+ }
+
hfpmod.is_hfp_running = true;
hfp_set_volume(adev, hfpmod.hfp_volume);
@@ -455,6 +460,9 @@
fp_disable_snd_device(adev, uc_info->out_snd_device);
fp_disable_snd_device(adev, uc_info->in_snd_device);
+ if (fp_audio_extn_auto_hal_stop_hfp_downlink(adev, uc_info))
+ ALOGE("%s: stop hfp downlink failed", __func__);
+
/* Set the unmute Tx mixer control */
if (fp_voice_get_mic_mute(adev)) {
fp_platform_set_mic_mute(adev->platform, false);
@@ -483,6 +491,10 @@
fp_disable_audio_route = init_config.fp_disable_audio_route;
fp_disable_snd_device = init_config.fp_disable_snd_device;
fp_voice_get_mic_mute = init_config.fp_voice_get_mic_mute;
+ fp_audio_extn_auto_hal_start_hfp_downlink =
+ init_config.fp_audio_extn_auto_hal_start_hfp_downlink;
+ fp_audio_extn_auto_hal_stop_hfp_downlink =
+ init_config.fp_audio_extn_auto_hal_stop_hfp_downlink;
}
bool hfp_is_active(struct audio_device *adev)
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index a29b6e5..b25fe3c 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -832,6 +832,25 @@
return adev->vr_audio_mode_enabled;
}
+static void audio_extn_btsco_get_sample_rate(int snd_device, int *sample_rate)
+{
+ switch (snd_device) {
+ case SND_DEVICE_OUT_BT_SCO:
+ case SND_DEVICE_IN_BT_SCO_MIC:
+ case SND_DEVICE_IN_BT_SCO_MIC_NREC:
+ *sample_rate = 8000;
+ break;
+ case SND_DEVICE_OUT_BT_SCO_WB:
+ case SND_DEVICE_IN_BT_SCO_MIC_WB:
+ case SND_DEVICE_IN_BT_SCO_MIC_WB_NREC:
+ *sample_rate = 16000;
+ break;
+ default:
+ ALOGD("%s:Not a BT SCO device, need not update sampling rate\n", __func__);
+ break;
+ }
+}
+
void audio_extn_utils_update_stream_app_type_cfg_for_usecase(
struct audio_device *adev,
struct audio_usecase *usecase)
@@ -880,31 +899,46 @@
&usecase->stream.inout->out_app_type_cfg);
ALOGV("%s Selected apptype: %d", __func__, usecase->stream.inout->out_app_type_cfg.app_type);
break;
+ case PCM_HFP_CALL:
+ switch (usecase->id) {
+ case USECASE_AUDIO_HFP_SCO:
+ case USECASE_AUDIO_HFP_SCO_WB:
+ audio_extn_btsco_get_sample_rate(usecase->out_snd_device,
+ &usecase->out_app_type_cfg.sample_rate);
+ usecase->in_app_type_cfg.sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ break;
+ case USECASE_AUDIO_HFP_SCO_DOWNLINK:
+ case USECASE_AUDIO_HFP_SCO_WB_DOWNLINK:
+ audio_extn_btsco_get_sample_rate(usecase->in_snd_device,
+ &usecase->in_app_type_cfg.sample_rate);
+ usecase->out_app_type_cfg.sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ break;
+ default:
+ ALOGE("%s: usecase id (%d) not supported, use default sample rate",
+ __func__, usecase->id);
+ usecase->in_app_type_cfg.sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ usecase->out_app_type_cfg.sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ break;
+ }
+ /* update out_app_type_cfg */
+ usecase->out_app_type_cfg.bit_width =
+ platform_get_snd_device_bit_width(usecase->out_snd_device);
+ usecase->out_app_type_cfg.app_type =
+ platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK);
+ /* update in_app_type_cfg */
+ usecase->in_app_type_cfg.bit_width =
+ platform_get_snd_device_bit_width(usecase->in_snd_device);
+ usecase->in_app_type_cfg.app_type =
+ platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE);
+ ALOGV("%s Selected apptype: playback %d capture %d",
+ __func__, usecase->out_app_type_cfg.app_type, usecase->in_app_type_cfg.app_type);
+ break;
default:
ALOGE("%s: app type cfg not supported for usecase type (%d)",
__func__, usecase->type);
}
}
-void audio_extn_btsco_get_sample_rate(int snd_device, int *sample_rate)
-{
- switch (snd_device) {
- case SND_DEVICE_OUT_BT_SCO:
- case SND_DEVICE_IN_BT_SCO_MIC:
- case SND_DEVICE_IN_BT_SCO_MIC_NREC:
- *sample_rate = 8000;
- break;
- case SND_DEVICE_OUT_BT_SCO_WB:
- case SND_DEVICE_IN_BT_SCO_MIC_WB:
- case SND_DEVICE_IN_BT_SCO_MIC_WB_NREC:
- *sample_rate = 16000;
- break;
- default:
- ALOGD("%s:Not a BT SCO device, need not update sampling rate\n", __func__);
- break;
- }
-}
-
static int set_stream_app_type_mixer_ctrl(struct audio_device *adev,
int pcm_device_id, int app_type,
int acdb_dev_id, int sample_rate,
@@ -955,21 +989,27 @@
int pcm_device_id, acdb_dev_id = 0, snd_device = usecase->out_snd_device;
int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
int app_type = 0, rc = 0;
+ bool is_bus_dev_usecase = false;
ALOGV("%s", __func__);
if (usecase->type != PCM_HFP_CALL) {
- ALOGV("%s: not a playback or HFP path, no need to cfg app type", __func__);
+ ALOGV("%s: not a HFP path, no need to cfg app type", __func__);
rc = 0;
goto exit_send_app_type_cfg;
}
if ((usecase->id != USECASE_AUDIO_HFP_SCO) &&
- (usecase->id != USECASE_AUDIO_HFP_SCO_WB)) {
- ALOGV("%s: a playback path where app type cfg is not required", __func__);
+ (usecase->id != USECASE_AUDIO_HFP_SCO_WB) &&
+ (usecase->id != USECASE_AUDIO_HFP_SCO_DOWNLINK) &&
+ (usecase->id != USECASE_AUDIO_HFP_SCO_WB_DOWNLINK)) {
+ ALOGV("%s: a usecase where app type cfg is not required", __func__);
rc = 0;
goto exit_send_app_type_cfg;
}
+ if (usecase->devices & AUDIO_DEVICE_OUT_BUS)
+ is_bus_dev_usecase = true;
+
snd_device = usecase->out_snd_device;
pcm_device_id = platform_get_pcm_device_id(usecase->id, PCM_PLAYBACK);
@@ -983,24 +1023,47 @@
if (usecase->type == PCM_HFP_CALL) {
/* config HFP session:1 playback path */
- app_type = platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK);
- sample_rate= CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ if (is_bus_dev_usecase) {
+ app_type = usecase->out_app_type_cfg.app_type;
+ sample_rate= usecase->out_app_type_cfg.sample_rate;
+ } else {
+ snd_device = SND_DEVICE_NONE; // use legacy behavior
+ app_type = platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK);
+ sample_rate= CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ }
rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
acdb_dev_id, sample_rate,
PCM_PLAYBACK,
- SND_DEVICE_NONE); // use legacy behavior
+ snd_device);
if (rc < 0)
goto exit_send_app_type_cfg;
/* config HFP session:1 capture path */
- app_type = platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE);
+ if (is_bus_dev_usecase) {
+ snd_device = usecase->in_snd_device;
+ pcm_device_id = platform_get_pcm_device_id(usecase->id, PCM_CAPTURE);
+ acdb_dev_id = platform_get_snd_device_acdb_id(snd_device);
+ if (acdb_dev_id < 0) {
+ ALOGE("%s: Couldn't get the acdb dev id", __func__);
+ rc = -EINVAL;
+ goto exit_send_app_type_cfg;
+ }
+ app_type = usecase->in_app_type_cfg.app_type;
+ sample_rate= usecase->in_app_type_cfg.sample_rate;
+ } else {
+ snd_device = SND_DEVICE_NONE; // use legacy behavior
+ app_type = platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE);
+ }
rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
acdb_dev_id, sample_rate,
PCM_CAPTURE,
- SND_DEVICE_NONE);
+ snd_device);
if (rc < 0)
goto exit_send_app_type_cfg;
+ if (is_bus_dev_usecase)
+ goto exit_send_app_type_cfg;
+
/* config HFP session:2 capture path */
pcm_device_id = HFP_ASM_RX_TX;
snd_device = usecase->in_snd_device;