Merge tag 'android-7.1.2_r5' of https://android.googlesource.com/platform/hardware/qcom/audio into HEAD
Android 7.1.2 Release 5 (N2G47J)
Change-Id: Ic8c1180a568dde687a79e580eb3db59f08d6061a
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index ebc0fd2..07d5469 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -27,6 +27,7 @@
#include "platform_api.h"
#include <stdlib.h>
#include <cutils/str_parms.h>
+#include "audio_extn/tfa_98xx.h"
#define AUDIO_PARAMETER_HFP_ENABLE "hfp_enable"
#define AUDIO_PARAMETER_HFP_SET_SAMPLING_RATE "hfp_set_sampling_rate"
@@ -34,6 +35,10 @@
#define AUDIO_PARAMETER_HFP_VOL_MIXER_CTL "hfp_vol_mixer_ctl"
#define AUDIO_PARAMATER_HFP_VALUE_MAX 128
+#define AUDIO_PARAMETER_KEY_HFP_MIC_VOLUME "hfp_mic_volume"
+#define PLAYBACK_VOLUME_MAX 0x2000
+#define CAPTURE_VOLUME_DEFAULT (15.0)
+
static int32_t start_hfp(struct audio_device *adev,
struct str_parms *parms);
@@ -45,8 +50,10 @@
struct pcm *hfp_pcm_rx;
struct pcm *hfp_pcm_tx;
float hfp_volume;
+ float mic_volume;
char hfp_vol_mixer_ctl[AUDIO_PARAMATER_HFP_VALUE_MAX];
bool is_hfp_running;
+ bool mic_mute;
audio_usecase_t ucid;
};
@@ -56,8 +63,10 @@
.hfp_pcm_rx = NULL,
.hfp_pcm_tx = NULL,
.hfp_volume = 0,
+ .mic_volume = CAPTURE_VOLUME_DEFAULT,
.hfp_vol_mixer_ctl = {0, },
.is_hfp_running = 0,
+ .mic_mute = 0,
.ucid = USECASE_AUDIO_HFP_SCO,
};
static struct pcm_config pcm_config_hfp = {
@@ -79,6 +88,9 @@
ALOGV("%s: entry", __func__);
ALOGD("%s: (%f)\n", __func__, value);
+ hfpmod.hfp_volume = value;
+ audio_extn_tfa_98xx_set_voice_vol(value);
+
if (value < 0.0) {
ALOGW("%s: (%f) Under 0.0, assuming 0.0\n", __func__, value);
value = 0.0;
@@ -87,7 +99,6 @@
ALOGW("%s: Volume brought with in range (%f)\n", __func__, value);
}
vol = lrint((value * 0x2000) + 0.5);
- hfpmod.hfp_volume = value;
if (!hfpmod.is_hfp_running) {
ALOGV("%s: HFP not active, ignoring set_hfp_volume call", __func__);
@@ -119,6 +130,115 @@
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, ret = 0;
+ 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)
{
@@ -140,6 +260,8 @@
list_add_tail(&adev->usecase_list, &uc_info->list);
+ audio_extn_tfa_98xx_set_mode_bt();
+
select_devices(adev, hfpmod.ucid);
pcm_dev_rx_id = platform_get_pcm_device_id(uc_info->id, PCM_PLAYBACK);
@@ -169,13 +291,16 @@
}
ALOGD("%s: Opening PCM capture device card_id(%d) device_id(%d)",
__func__, adev->snd_card, pcm_dev_tx_id);
- hfpmod.hfp_pcm_rx = pcm_open(adev->snd_card,
- 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;
- goto exit;
+
+ if (audio_extn_tfa_98xx_is_supported() == false) {
+ hfpmod.hfp_pcm_rx = pcm_open(adev->snd_card,
+ 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;
+ goto exit;
+ }
}
hfpmod.hfp_sco_tx = pcm_open(adev->snd_card,
pcm_dev_asm_tx_id,
@@ -187,22 +312,33 @@
}
ALOGV("%s: Opening PCM capture device card_id(%d) device_id(%d)",
__func__, adev->snd_card, pcm_dev_tx_id);
- hfpmod.hfp_pcm_tx = pcm_open(adev->snd_card,
- 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;
- goto exit;
+
+ if (audio_extn_tfa_98xx_is_supported() == false) {
+ hfpmod.hfp_pcm_tx = pcm_open(adev->snd_card,
+ 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;
+ goto exit;
+ }
}
pcm_start(hfpmod.hfp_sco_rx);
pcm_start(hfpmod.hfp_sco_tx);
- pcm_start(hfpmod.hfp_pcm_rx);
- pcm_start(hfpmod.hfp_pcm_tx);
+ if (audio_extn_tfa_98xx_is_supported() == false) {
+ pcm_start(hfpmod.hfp_pcm_rx);
+ pcm_start(hfpmod.hfp_pcm_tx);
+ }
+
+ audio_extn_tfa_98xx_enable_speaker();
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;
@@ -348,6 +484,20 @@
ALOGD("%s: set_hfp_volume usecase, Vol: [%f]", __func__, vol);
hfp_set_volume(adev, vol);
}
+
+ 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__);
}