hal : native DSD concurrency support over headphone.
-Enable ASRC mode for headphone backend if headphone 44.1 or
native DSD backend is active.
-Disable headphone backend and reopen it with ASRC mode for upcoming
use case over headphone 44.1 or native DSD backend
Change-Id: Ic8fb0ab9f254d3472fda49dbb824f622d518a451
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 70909f5..b617407 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -621,6 +621,36 @@
return 0;
}
+/*
+ * Enable ASRC mode if native or DSD stream is active.
+ */
+static void audio_check_and_set_asrc_mode(struct audio_device *adev, snd_device_t snd_device)
+{
+ if (SND_DEVICE_OUT_HEADPHONES == snd_device &&
+ !adev->asrc_mode_enabled) {
+ struct listnode *node = NULL;
+ struct audio_usecase *uc = NULL;
+ struct stream_out *curr_out = NULL;
+
+ 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) {
+ if((platform_get_backend_index(uc->out_snd_device) == HEADPHONE_44_1_BACKEND) ||
+ (platform_get_backend_index(uc->out_snd_device) == DSD_NATIVE_BACKEND)) {
+ ALOGD("%s:DSD or native stream detected enabling asrcmode in hardware",
+ __func__);
+ audio_route_apply_and_update_path(adev->audio_route,
+ "asrc-mode");
+ adev->asrc_mode_enabled = true;
+ break;
+ }
+ }
+ }
+ }
+}
+
int pcm_ioctl(struct pcm *pcm, int request, ...)
{
va_list ap;
@@ -772,7 +802,8 @@
audio_route_apply_and_update_path(adev->audio_route,
"true-native-mode");
adev->native_playback_enabled = true;
- }
+ } else
+ audio_check_and_set_asrc_mode(adev, snd_device);
}
return 0;
}
@@ -829,6 +860,11 @@
audio_route_reset_and_update_path(adev->audio_route,
"true-native-mode");
adev->native_playback_enabled = false;
+ } else if (SND_DEVICE_OUT_HEADPHONES == snd_device &&
+ adev->asrc_mode_enabled) {
+ ALOGD("%s: %d: disabling asrc mode in hardware", __func__, __LINE__);
+ audio_route_reset_and_update_path(adev->audio_route, "asrc-mode");
+ adev->asrc_mode_enabled = false;
}
audio_extn_dev_arbi_release(snd_device);
@@ -900,7 +936,9 @@
((usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) ||
(usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) ||
(force_restart_session)) &&
- platform_check_backends_match(snd_device, usecase->out_snd_device)) {
+ (platform_check_backends_match(snd_device, usecase->out_snd_device)||
+ (platform_check_codec_asrc_support(adev->platform) && !adev->asrc_mode_enabled &&
+ platform_check_if_backend_has_to_be_disabled(snd_device,usecase->out_snd_device)))) {
ALOGD("%s:becf: check_usecases (%s) is active on (%s) - disabling ..",
__func__, use_case_table[usecase->id],
platform_get_snd_device_name(usecase->out_snd_device));
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 1b5c6c9..197807c 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -389,6 +389,7 @@
int perf_lock_opts[MAX_PERF_LOCK_OPTS];
int perf_lock_opts_size;
bool native_playback_enabled;
+ bool asrc_mode_enabled;
};
int select_devices(struct audio_device *adev,
@@ -411,6 +412,7 @@
bool audio_is_true_native_stream_active(struct audio_device *adev);
bool audio_is_dsd_native_stream_active(struct audio_device *adev);
+
int pcm_ioctl(struct pcm *pcm, int request, ...);
int get_snd_card_state(struct audio_device *adev);
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 8894b2f..9c6cc6f 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -5413,3 +5413,14 @@
{
return false;
}
+
+bool platform_check_codec_asrc_support(void *platform __unused)
+{
+ return false;
+}
+
+bool platform_check_if_backend_has_to_be_disabled(snd_device_t new_snd_device __unused,
+ snd_device_t cuurent_snd_device __unused)
+{
+ return false;
+}
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index 1b47e7d..e5d42bd 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1266,4 +1266,15 @@
int platform_get_backend_index(snd_device_t snd_device __unused);
{
return 0;
-}
\ No newline at end of file
+}
+
+bool platform_check_codec_asrc_support(void *platform __unused)
+{
+ return false;
+}
+
+bool platform_check_if_backend_has_to_be_disabled(snd_device_t new_snd_device __unused,
+ snd_device_t cuurent_snd_device __unused)
+{
+ return false;
+}
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 9c85d10..f12114a 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -248,6 +248,7 @@
int source_mic_type;
int max_mic_count;
bool is_dsd_supported;
+ bool is_asrc_supported;
};
static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
@@ -1759,6 +1760,7 @@
if(strstr(snd_card_name, "tavil")) {
ALOGD("%s:DSD playback is supported", __func__);
my_data->is_dsd_supported = true;
+ my_data->is_asrc_supported = true;
platform_set_native_support(NATIVE_AUDIO_MODE_MULTIPLE_44_1);
}
@@ -1924,6 +1926,32 @@
return result;
}
+bool platform_check_if_backend_has_to_be_disabled(snd_device_t new_snd_device,
+ snd_device_t cuurent_snd_device)
+{
+ bool result = false;
+
+ ALOGV("%s: current snd device = %s, new snd device = %s", __func__,
+ platform_get_snd_device_name(cuurent_snd_device),
+ platform_get_snd_device_name(new_snd_device));
+
+ if ((new_snd_device < SND_DEVICE_MIN) || (new_snd_device >= SND_DEVICE_OUT_END) ||
+ (cuurent_snd_device < SND_DEVICE_MIN) || (cuurent_snd_device >= SND_DEVICE_OUT_END)) {
+ ALOGE("%s: Invalid snd_device",__func__);
+ return false;
+ }
+
+ if (cuurent_snd_device == SND_DEVICE_OUT_HEADPHONES &&
+ (new_snd_device == SND_DEVICE_OUT_HEADPHONES_44_1 ||
+ new_snd_device == SND_DEVICE_OUT_HEADPHONES_DSD)) {
+ result = true;
+ }
+
+ ALOGV("%s: Need to disable current backend %s, %d",
+ __func__, platform_get_snd_device_name(cuurent_snd_device), result);
+ return result;
+}
+
int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
{
int device_id;
@@ -2131,6 +2159,12 @@
return my_data->is_dsd_supported;
}
+bool platform_check_codec_asrc_support(void *platform)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ return my_data->is_asrc_supported;
+}
+
int platform_get_native_support()
{
int ret = NATIVE_AUDIO_MODE_INVALID;
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 60e46f1..625f4eb 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -152,6 +152,8 @@
bool enable,
char * str);
bool platform_supports_true_32bit();
+bool platform_check_if_backend_has_to_be_disabled(snd_device_t new_snd_device, snd_device_t cuurent_snd_device);
bool platform_check_codec_dsd_support(void *platform);
+bool platform_check_codec_asrc_support(void *platform);
int platform_get_backend_index(snd_device_t snd_device);
#endif // AUDIO_PLATFORM_API_H