audio: unify hal
Unify audio hal components
CRs-Fixed: 2380934
Change-Id: Iacafdc44d935de5f343240421a1572a0a3241bd0
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index 89c42c8..3eb96d6 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -31,7 +31,7 @@
#include <errno.h>
#include <math.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include "audio_hw.h"
#include "platform.h"
@@ -52,9 +52,13 @@
#define AUDIO_PARAMETER_KEY_HFP_VOLUME "hfp_volume"
#define AUDIO_PARAMETER_HFP_PCM_DEV_ID "hfp_pcm_dev_id"
+#define AUDIO_PARAMETER_KEY_HFP_MIC_VOLUME "hfp_mic_volume"
+#define PLAYBACK_VOLUME_MAX 0x2000
+#define CAPTURE_VOLUME_DEFAULT (15.0)
+
#ifdef PLATFORM_MSM8994
#define HFP_RX_VOLUME "SEC AUXPCM LOOPBACK Volume"
-#elif defined PLATFORM_MSM8996
+#elif defined (PLATFORM_MSM8996) || defined (EXTERNAL_BT_SUPPORTED)
#define HFP_RX_VOLUME "PRI AUXPCM LOOPBACK Volume"
#elif defined PLATFORM_AUTO
#define HFP_RX_VOLUME "Playback 36 Volume"
@@ -78,6 +82,8 @@
float hfp_volume;
int32_t hfp_pcm_dev_id;
audio_usecase_t ucid;
+ float mic_volume;
+ bool mic_mute;
};
static struct hfp_module hfpmod = {
@@ -89,7 +95,10 @@
.hfp_volume = 0,
.hfp_pcm_dev_id = HFP_ASM_RX_TX,
.ucid = USECASE_AUDIO_HFP_SCO,
+ .mic_volume = CAPTURE_VOLUME_DEFAULT,
+ .mic_mute = 0,
};
+
static struct pcm_config pcm_config_hfp = {
.channels = 1,
.rate = 8000,
@@ -111,6 +120,7 @@
ALOGD("%s: (%f)\n", __func__, value);
hfpmod.hfp_volume = value;
+
if (value < 0.0) {
ALOGW("%s: (%f) Under 0.0, assuming 0.0\n", __func__, value);
value = 0.0;
@@ -141,6 +151,114 @@
return ret;
}
+/*Set mic volume to value.
+*
+* This interface is used for mic volume control, set mic volume as value(range 0 ~ 15).
+*/
+static int hfp_set_mic_volume(struct audio_device *adev, float value)
+{
+ int volume, ret = 0;
+ char mixer_ctl_name[128];
+ struct mixer_ctl *ctl;
+ int pcm_device_id = HFP_ASM_RX_TX;
+
+ if (!hfpmod.is_hfp_running) {
+ ALOGE("%s: HFP not active, ignoring set_hfp_mic_volume call", __func__);
+ return -EIO;
+ }
+
+ if (value < 0.0) {
+ ALOGW("%s: (%f) Under 0.0, assuming 0.0\n", __func__, value);
+ value = 0.0;
+ } else if (value > CAPTURE_VOLUME_DEFAULT) {
+ value = CAPTURE_VOLUME_DEFAULT;
+ ALOGW("%s: Volume brought within range (%f)\n", __func__, value);
+ }
+
+ value = value / CAPTURE_VOLUME_DEFAULT;
+ memset(mixer_ctl_name, 0, sizeof(mixer_ctl_name));
+ snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+ "Playback %d Volume", 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);
+ return -EINVAL;
+ }
+ volume = (int)(value * PLAYBACK_VOLUME_MAX);
+
+ ALOGD("%s: Setting volume to %d (%s)\n", __func__, volume, mixer_ctl_name);
+ if (mixer_ctl_set_value(ctl, 0, volume) < 0) {
+ ALOGE("%s: Couldn't set HFP Volume: [%d]", __func__, volume);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static float hfp_get_mic_volume(struct audio_device *adev)
+{
+ int volume;
+ char mixer_ctl_name[128];
+ struct mixer_ctl *ctl;
+ int pcm_device_id = HFP_ASM_RX_TX;
+ float value = 0.0;
+
+ if (!hfpmod.is_hfp_running) {
+ ALOGE("%s: HFP not active, ignoring set_hfp_mic_volume call", __func__);
+ return -EIO;
+ }
+
+ memset(mixer_ctl_name, 0, sizeof(mixer_ctl_name));
+ snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+ "Playback %d Volume", 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);
+ return -EINVAL;
+ }
+
+ volume = mixer_ctl_get_value(ctl, 0);
+ if ( volume < 0) {
+ ALOGE("%s: Couldn't set HFP Volume: [%d]", __func__, volume);
+ return -EINVAL;
+ }
+ ALOGD("%s: getting mic volume %d \n", __func__, volume);
+
+ value = (volume / PLAYBACK_VOLUME_MAX) * CAPTURE_VOLUME_DEFAULT;
+ if (value < 0.0) {
+ ALOGW("%s: (%f) Under 0.0, assuming 0.0\n", __func__, value);
+ value = 0.0;
+ } else if (value > CAPTURE_VOLUME_DEFAULT) {
+ value = CAPTURE_VOLUME_DEFAULT;
+ ALOGW("%s: Volume brought within range (%f)\n", __func__, value);
+ }
+
+ return value;
+}
+
+/*Set mic mute state.
+*
+* This interface is used for mic mute state control
+*/
+int audio_extn_hfp_set_mic_mute(struct audio_device *adev, bool state)
+{
+ int rc = 0;
+
+ if (state == hfpmod.mic_mute)
+ return rc;
+
+ if (state == true) {
+ hfpmod.mic_volume = hfp_get_mic_volume(adev);
+ }
+ rc = hfp_set_mic_volume(adev, (state == true) ? 0.0 : hfpmod.mic_volume);
+ adev->voice.mic_mute = state;
+ hfpmod.mic_mute = state;
+ ALOGD("%s: Setting mute state %d, rc %d\n", __func__, state, rc);
+ return rc;
+}
+
static int32_t start_hfp(struct audio_device *adev,
struct str_parms *parms __unused)
{
@@ -150,6 +268,13 @@
ALOGD("%s: enter", __func__);
+ if (adev->enable_hfp == true) {
+ ALOGD("%s: HFP is already active!\n", __func__);
+ return 0;
+ }
+ adev->enable_hfp = true;
+ platform_set_mic_mute(adev->platform, false);
+
uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
if (!uc_info)
@@ -197,8 +322,8 @@
}
hfpmod.hfp_pcm_rx = pcm_open(adev->snd_card,
- pcm_dev_rx_id,
- PCM_OUT, &pcm_config_hfp);
+ pcm_dev_rx_id,
+ PCM_OUT, &pcm_config_hfp);
if (hfpmod.hfp_pcm_rx && !pcm_is_ready(hfpmod.hfp_pcm_rx)) {
ALOGE("%s: %s", __func__, pcm_get_error(hfpmod.hfp_pcm_rx));
ret = -EIO;
@@ -215,8 +340,8 @@
}
hfpmod.hfp_pcm_tx = pcm_open(adev->snd_card,
- pcm_dev_tx_id,
- PCM_IN, &pcm_config_hfp);
+ pcm_dev_tx_id,
+ PCM_IN, &pcm_config_hfp);
if (hfpmod.hfp_pcm_tx && !pcm_is_ready(hfpmod.hfp_pcm_tx)) {
ALOGE("%s: %s", __func__, pcm_get_error(hfpmod.hfp_pcm_tx));
ret = -EIO;
@@ -233,6 +358,7 @@
ret = -EINVAL;
goto exit;
}
+
if (pcm_start(hfpmod.hfp_pcm_rx) < 0) {
ALOGE("%s: pcm start for hfp pcm rx failed", __func__);
ret = -EINVAL;
@@ -247,6 +373,10 @@
hfpmod.is_hfp_running = true;
hfp_set_volume(adev, hfpmod.hfp_volume);
+ /* Set mic volume by mute status, we don't provide set mic volume in phone app, only
+ provide mute and unmute. */
+ audio_extn_hfp_set_mic_mute(adev, adev->mic_muted);
+
ALOGD("%s: exit: status(%d)", __func__, ret);
return 0;
@@ -305,6 +435,13 @@
disable_snd_device(adev, uc_info->out_snd_device);
disable_snd_device(adev, uc_info->in_snd_device);
+ /* Set the unmute Tx mixer control */
+ if (voice_get_mic_mute(adev)) {
+ platform_set_mic_mute(adev->platform, false);
+ ALOGD("%s: unMute HFP Tx", __func__);
+ }
+ adev->enable_hfp = false;
+
list_remove(&uc_info->list);
free(uc_info);
@@ -413,6 +550,19 @@
str_parms_del(parms, AUDIO_PARAMETER_HFP_PCM_DEV_ID);
}
+ memset(value, 0, sizeof(value));
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HFP_MIC_VOLUME,
+ value, sizeof(value));
+ if (ret >= 0) {
+ if (sscanf(value, "%f", &vol) != 1){
+ ALOGE("%s: error in retrieving hfp mic volume", __func__);
+ ret = -EIO;
+ goto exit;
+ }
+ ALOGD("%s: set_hfp_mic_volume usecase, Vol: [%f]", __func__, vol);
+ hfp_set_mic_volume(adev, vol);
+ }
+
exit:
ALOGV("%s Exit",__func__);
}