hal: fix for snd device mismatch during hph to hph 44.1 playback
-if native mode is enabled during run time when playback over
headphone is active, check_and_set asrc function disable and
re-enable headphone with asrc mode as usecase out snd device
is still headphone.
-In check_and_set_asrc function avoid disabling and re-enabling of
headphone backend for existing use case if it is same use case
for which new backend has to be enabled.
Also split snd device in check and set asrc function
for new use case with combo device.
CRs-Fixed: 2012582
Change-Id: Id02cf720c8e0ad98ef547c6f3ed48cb1f04836ce
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 1b0e1f1..627be8e 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -606,73 +606,90 @@
* ASRC mode for incoming Headphone 44.1 or Native DSD use case.
* e.g. Naitve DSD or Headphone 44.1 -> + 48
*/
-static void check_and_set_asrc_mode(struct audio_device *adev, snd_device_t snd_device)
+static void check_and_set_asrc_mode(struct audio_device *adev,
+ struct audio_usecase *uc_info,
+ snd_device_t snd_device)
{
ALOGV("%s snd device %d", __func__, snd_device);
- int new_backend_idx = platform_get_backend_index(snd_device);
+ int i, num_new_devices = 0;
+ snd_device_t split_new_snd_devices[SND_DEVICE_OUT_END];
+ /*
+ *Split snd device for new combo use case
+ *e.g. Headphopne 44.1-> + Ringtone (Headphone + Speaker)
+ */
+ if (platform_split_snd_device(adev->platform,
+ snd_device,
+ &num_new_devices,
+ split_new_snd_devices) == 0) {
+ for (i = 0; i < num_new_devices; i++)
+ check_and_set_asrc_mode(adev, uc_info, split_new_snd_devices[i]);
+ } else {
+ int new_backend_idx = platform_get_backend_index(snd_device);
+ if (((new_backend_idx == HEADPHONE_BACKEND) ||
+ (new_backend_idx == HEADPHONE_44_1_BACKEND) ||
+ (new_backend_idx == DSD_NATIVE_BACKEND)) &&
+ !adev->asrc_mode_enabled) {
+ struct listnode *node = NULL;
+ struct audio_usecase *uc = NULL;
+ struct stream_out *curr_out = NULL;
+ int usecase_backend_idx = DEFAULT_CODEC_BACKEND;
+ int i, num_devices, ret = 0;
+ snd_device_t split_snd_devices[SND_DEVICE_OUT_END];
- if (((new_backend_idx == HEADPHONE_BACKEND) ||
- (new_backend_idx == HEADPHONE_44_1_BACKEND) ||
- (new_backend_idx == DSD_NATIVE_BACKEND)) &&
- !adev->asrc_mode_enabled) {
- struct listnode *node = NULL;
- struct audio_usecase *uc = NULL;
- struct stream_out *curr_out = NULL;
- int usecase_backend_idx = DEFAULT_CODEC_BACKEND;
- int i, num_devices, ret = 0;
- snd_device_t split_snd_devices[SND_DEVICE_OUT_END];
-
- list_for_each(node, &adev->usecase_list) {
- uc = node_to_item(node, struct audio_usecase, list);
- curr_out = (struct stream_out*) uc->stream.out;
-
- if (curr_out && PCM_PLAYBACK == uc->type) {
- ret = platform_split_snd_device(adev->platform,
- uc->out_snd_device,
- &num_devices,
- split_snd_devices);
- if (ret < 0 || num_devices == 0) {
- ALOGV("%s: Unable to split uc->out_snd_device: %d",__func__, uc->out_snd_device);
- split_snd_devices[0] = uc->out_snd_device;
- num_devices = 1;
- }
- for (i = 0; i < num_devices; i++) {
- usecase_backend_idx = platform_get_backend_index(split_snd_devices[i]);
- ALOGD("%s:snd_dev %d usecase_backend_idx %d",__func__, split_snd_devices[i],usecase_backend_idx);
- if((new_backend_idx == HEADPHONE_BACKEND) &&
- ((usecase_backend_idx == HEADPHONE_44_1_BACKEND) ||
- (usecase_backend_idx == DSD_NATIVE_BACKEND))) {
- ALOGD("%s:DSD or native stream detected enabling asrcmode in hardware",
- __func__);
- enable_asrc_mode(adev);
- break;
- } else if(((new_backend_idx == HEADPHONE_44_1_BACKEND) ||
- (new_backend_idx == DSD_NATIVE_BACKEND)) &&
- (usecase_backend_idx == HEADPHONE_BACKEND)) {
- ALOGD("%s:48K stream detected, disabling and enabling it with asrcmode in hardware",
- __func__);
- disable_audio_route(adev, uc);
- disable_snd_device(adev, uc->out_snd_device);
- // Apply true-high-quality-mode if DSD or > 44.1KHz or >=24-bit
- if (new_backend_idx == DSD_NATIVE_BACKEND)
- audio_route_apply_and_update_path(adev->audio_route,
- "hph-true-highquality-mode");
- else if ((new_backend_idx == HEADPHONE_44_1_BACKEND) &&
- (curr_out->bit_width >= 24))
- audio_route_apply_and_update_path(adev->audio_route,
- "hph-highquality-mode");
- enable_asrc_mode(adev);
- enable_snd_device(adev, uc->out_snd_device);
- enable_audio_route(adev, uc);
- break;
+ list_for_each(node, &adev->usecase_list) {
+ uc = node_to_item(node, struct audio_usecase, list);
+ curr_out = (struct stream_out*) uc->stream.out;
+ if (curr_out && PCM_PLAYBACK == uc->type && uc != uc_info) {
+ /*
+ *Split snd device for existing combo use case
+ *e.g. Ringtone (Headphone + Speaker) + Headphopne 44.1
+ */
+ ret = platform_split_snd_device(adev->platform,
+ uc->out_snd_device,
+ &num_devices,
+ split_snd_devices);
+ if (ret < 0 || num_devices == 0) {
+ ALOGV("%s: Unable to split uc->out_snd_device: %d",__func__, uc->out_snd_device);
+ split_snd_devices[0] = uc->out_snd_device;
+ num_devices = 1;
}
+ for (i = 0; i < num_devices; i++) {
+ usecase_backend_idx = platform_get_backend_index(split_snd_devices[i]);
+ ALOGD("%s:snd_dev %d usecase_backend_idx %d",__func__, split_snd_devices[i],usecase_backend_idx);
+ if((new_backend_idx == HEADPHONE_BACKEND) &&
+ ((usecase_backend_idx == HEADPHONE_44_1_BACKEND) ||
+ (usecase_backend_idx == DSD_NATIVE_BACKEND))) {
+ ALOGD("%s:DSD or native stream detected enabling asrcmode in hardware",
+ __func__);
+ enable_asrc_mode(adev);
+ break;
+ } else if(((new_backend_idx == HEADPHONE_44_1_BACKEND) ||
+ (new_backend_idx == DSD_NATIVE_BACKEND)) &&
+ (usecase_backend_idx == HEADPHONE_BACKEND)) {
+ ALOGD("%s:48K stream detected, disabling and enabling it with asrcmode in hardware",
+ __func__);
+ disable_audio_route(adev, uc);
+ disable_snd_device(adev, uc->out_snd_device);
+ // Apply true-high-quality-mode if DSD or > 44.1KHz or >=24-bit
+ if (new_backend_idx == DSD_NATIVE_BACKEND)
+ audio_route_apply_and_update_path(adev->audio_route,
+ "hph-true-highquality-mode");
+ else if ((new_backend_idx == HEADPHONE_44_1_BACKEND) &&
+ (curr_out->bit_width >= 24))
+ audio_route_apply_and_update_path(adev->audio_route,
+ "hph-highquality-mode");
+ enable_asrc_mode(adev);
+ enable_snd_device(adev, uc->out_snd_device);
+ enable_audio_route(adev, uc);
+ break;
+ }
+ }
+ // reset split devices count
+ num_devices = 0;
}
- // reset split devices count
- num_devices = 0;
+ if (adev->asrc_mode_enabled)
+ break;
}
- if (adev->asrc_mode_enabled)
- break;
-
}
}
}
@@ -798,8 +815,6 @@
} else {
ALOGD("%s: snd_device(%d: %s)", __func__, snd_device, device_name);
- if (platform_check_codec_asrc_support(adev->platform))
- check_and_set_asrc_mode(adev, snd_device);
if ((SND_DEVICE_OUT_BT_A2DP == snd_device) &&
(audio_extn_a2dp_start_playback() < 0)) {
@@ -1620,6 +1635,8 @@
/* Enable new sound devices */
if (out_snd_device != SND_DEVICE_NONE) {
check_usecases_codec_backend(adev, usecase, out_snd_device);
+ if (platform_check_codec_asrc_support(adev->platform))
+ check_and_set_asrc_mode(adev, usecase, out_snd_device);
enable_snd_device(adev, out_snd_device);
}