audio: unify hal
Unify audio hal components
CRs-Fixed: 2380934
Change-Id: Iacafdc44d935de5f343240421a1572a0a3241bd0
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 7c5756b..ad4e4b8 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2014 The Android Open Source Project
@@ -27,7 +27,7 @@
#include <stdlib.h>
#include <dlfcn.h>
#include <cutils/str_parms.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <cutils/misc.h>
#include <unistd.h>
@@ -894,6 +894,132 @@
}
}
+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,
+ int stream_type,
+ snd_device_t snd_device)
+{
+
+ char mixer_ctl_name[MAX_LENGTH_MIXER_CONTROL_IN_INT];
+ struct mixer_ctl *ctl;
+ int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT], len = 0, rc = 0;
+ int snd_device_be_idx = -1;
+
+ if (stream_type == PCM_PLAYBACK) {
+ snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+ "Audio Stream %d App Type Cfg", pcm_device_id);
+ } else if (stream_type == PCM_CAPTURE) {
+ snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+ "Audio Stream Capture %d App Type Cfg", pcm_device_id);
+ }
+
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s",
+ __func__, mixer_ctl_name);
+ rc = -EINVAL;
+ goto exit;
+ }
+ app_type_cfg[len++] = app_type;
+ app_type_cfg[len++] = acdb_dev_id;
+ app_type_cfg[len++] = sample_rate;
+
+ snd_device_be_idx = platform_get_snd_device_backend_index(snd_device);
+ if (snd_device_be_idx > 0)
+ app_type_cfg[len++] = snd_device_be_idx;
+ ALOGV("%s: stream type %d app_type %d, acdb_dev_id %d "
+ "sample rate %d, snd_device_be_idx %d",
+ __func__, stream_type, app_type, acdb_dev_id, sample_rate,
+ snd_device_be_idx);
+ mixer_ctl_set_array(ctl, app_type_cfg, len);
+
+exit:
+ return rc;
+}
+
+static int audio_extn_utils_send_app_type_cfg_hfp(struct audio_device *adev,
+ struct audio_usecase *usecase)
+{
+ 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;
+
+ ALOGV("%s", __func__);
+
+ if (usecase->type != PCM_HFP_CALL) {
+ ALOGV("%s: not a playback or 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__);
+ rc = 0;
+ goto exit_send_app_type_cfg;
+ }
+
+ snd_device = usecase->out_snd_device;
+ pcm_device_id = platform_get_pcm_device_id(usecase->id, PCM_PLAYBACK);
+
+ 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;
+ }
+
+ 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;
+ 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
+ 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);
+ rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
+ acdb_dev_id, sample_rate,
+ PCM_CAPTURE,
+ SND_DEVICE_NONE);
+ if (rc < 0)
+ 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;
+ 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 = 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);
+ if (rc < 0)
+ goto exit_send_app_type_cfg;
+
+ /* config HFP session:2 playback path */
+ app_type = platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK);
+ rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
+ acdb_dev_id, sample_rate,
+ PCM_PLAYBACK, SND_DEVICE_NONE);
+ if (rc < 0)
+ goto exit_send_app_type_cfg;
+ }
+
+ rc = 0;
+exit_send_app_type_cfg:
+ return rc;
+}
+
static int send_app_type_cfg_for_device(struct audio_device *adev,
struct audio_usecase *usecase,
int split_snd_device)
@@ -1118,6 +1244,10 @@
snd_device_t in_snd_device = usecase->in_snd_device;
int rc = 0;
+ if (usecase->type == PCM_HFP_CALL) {
+ return audio_extn_utils_send_app_type_cfg_hfp(adev, usecase);
+ }
+
switch (usecase->type) {
case PCM_PLAYBACK:
case TRANSCODE_LOOPBACK_RX:
@@ -2132,6 +2262,66 @@
#define MAX_SND_CARD 8
#define RETRY_US 1000000
#define RETRY_NUMBER 40
+#define PLATFORM_INFO_XML_PATH "audio_platform_info.xml"
+#define PLATFORM_INFO_XML_BASE_STRING "audio_platform_info"
+
+#ifdef LINUX_ENABLED
+static const char *kConfigLocationList[] =
+ {"/etc"};
+#else
+static const char *kConfigLocationList[] =
+ {"/vendor/etc"};
+#endif
+static const int kConfigLocationListSize =
+ (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
+
+bool audio_extn_utils_resolve_config_file(char file_name[MIXER_PATH_MAX_LENGTH])
+{
+ char full_config_path[MIXER_PATH_MAX_LENGTH];
+ for (int i = 0; i < kConfigLocationListSize; i++) {
+ snprintf(full_config_path,
+ MIXER_PATH_MAX_LENGTH,
+ "%s/%s",
+ kConfigLocationList[i],
+ file_name);
+ if (F_OK == access(full_config_path, 0)) {
+ strcpy(file_name, full_config_path);
+ return true;
+ }
+ }
+ return false;
+}
+
+/* platform_info_file should be size 'MIXER_PATH_MAX_LENGTH' */
+int audio_extn_utils_get_platform_info(const char* snd_card_name, char* platform_info_file)
+{
+ if (NULL == snd_card_name) {
+ return -1;
+ }
+
+ struct snd_card_split *snd_split_handle = NULL;
+ int ret = 0;
+ audio_extn_set_snd_card_split(snd_card_name);
+ snd_split_handle = audio_extn_get_snd_card_split();
+
+ snprintf(platform_info_file, MIXER_PATH_MAX_LENGTH, "%s_%s_%s.xml",
+ PLATFORM_INFO_XML_BASE_STRING, snd_split_handle->snd_card,
+ snd_split_handle->form_factor);
+
+ if (!audio_extn_utils_resolve_config_file(platform_info_file)) {
+ memset(platform_info_file, 0, MIXER_PATH_MAX_LENGTH);
+ snprintf(platform_info_file, MIXER_PATH_MAX_LENGTH, "%s_%s.xml",
+ PLATFORM_INFO_XML_BASE_STRING, snd_split_handle->snd_card);
+
+ if (!audio_extn_utils_resolve_config_file(platform_info_file)) {
+ memset(platform_info_file, 0, MIXER_PATH_MAX_LENGTH);
+ strlcpy(platform_info_file, PLATFORM_INFO_XML_PATH, MIXER_PATH_MAX_LENGTH);
+ ret = audio_extn_utils_resolve_config_file(platform_info_file) ? 0 : -1;
+ }
+ }
+
+ return ret;
+}
int audio_extn_utils_get_snd_card_num()
{
@@ -2544,3 +2734,24 @@
return platform_get_license_by_product(adev->platform, (const char*)license_params->product, &license_params->key, license_params->license);
}
+int audio_extn_utils_send_app_type_gain(struct audio_device *adev,
+ int app_type,
+ int *gain)
+{
+ int gain_cfg[4];
+ const char *mixer_ctl_name = "App Type Gain";
+ struct mixer_ctl *ctl;
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get volume ctl mixer %s", __func__,
+ mixer_ctl_name);
+ return -EINVAL;
+ }
+ gain_cfg[0] = 0;
+ gain_cfg[1] = app_type;
+ gain_cfg[2] = gain[0];
+ gain_cfg[3] = gain[1];
+ ALOGV("%s app_type %d l(%d) r(%d)", __func__, app_type, gain[0], gain[1]);
+ return mixer_ctl_set_array(ctl, gain_cfg,
+ sizeof(gain_cfg)/sizeof(gain_cfg[0]));
+}