Merge "hal: Fix device selection at start of the voice call"
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 3e38d2b..c0b6de1 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -421,7 +421,6 @@
audio_format_t format,
uint32_t sample_rate,
uint32_t bit_width,
- audio_channel_mask_t channel_mask,
struct stream_app_type_cfg *app_type_cfg);
int audio_extn_utils_send_app_type_cfg(struct audio_usecase *usecase);
void audio_extn_utils_send_audio_calibration(struct audio_device *adev,
diff --git a/hal/audio_extn/dts_eagle.c b/hal/audio_extn/dts_eagle.c
index 52d7abb..7608a61 100644
--- a/hal/audio_extn/dts_eagle.c
+++ b/hal/audio_extn/dts_eagle.c
@@ -39,7 +39,6 @@
#define STATE_NOTIFY_FILE "/data/misc/dts/stream"
#define FADE_NOTIFY_FILE "/data/misc/dts/fade"
#define DTS_EAGLE_KEY "DTS_EAGLE"
-#define DEVICE_NODE "/dev/snd/hwC0D3"
#define MAX_LENGTH_OF_INTEGER_IN_STRING 13
#define PARAM_GET_MAX_SIZE 512
@@ -117,7 +116,7 @@
}
if (!sent) {
- int fd = open(DEVICE_NODE, O_RDWR);
+ int fd = open(GENERIC_AUDIO_DEVICE_NODE, O_RDWR);
if (get) {
ALOGD("DTS_EAGLE_HAL (%s): no stream opened, attempting to retrieve directly from cache", __func__);
@@ -137,7 +136,7 @@
}
close(fd);
} else {
- ALOGE("DTS_EAGLE_HAL (%s): couldn't open device %s\n", __func__, DEVICE_NODE);
+ ALOGE("DTS_EAGLE_HAL (%s): couldn't open device %s\n", __func__, GENERIC_AUDIO_DEVICE_NODE);
ret = -EINVAL;
}
}
diff --git a/hal/audio_extn/fm.c b/hal/audio_extn/fm.c
index ed3776c..efc2307 100644
--- a/hal/audio_extn/fm.c
+++ b/hal/audio_extn/fm.c
@@ -243,7 +243,20 @@
if (ret >= 0) {
val = atoi(value);
if(val > 0)
- select_devices(adev, USECASE_AUDIO_PLAYBACK_FM);
+ /*
+ * Only when wsa does present and is in analog mode,
+ * fm will stop/start here.
+ * To-do: when the kernel codec type query change
+ * is ready, enum of wsa mode should be checked here.
+ * Currently, platform_get_wsa_mode will directly return
+ * 1 when wsa is in analog mode.
+ */
+ if (platform_get_wsa_mode(adev->platform) == 1) {
+ fm_stop(adev);
+ fm_start(adev);
+ } else {
+ select_devices(adev, USECASE_AUDIO_PLAYBACK_FM);
+ }
}
}
if (fmmod.restart_fm && (fmmod.scard_state == SND_CARD_STATE_ONLINE)) {
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index dee9d44..75bb336 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -459,14 +459,12 @@
audio_format_t format,
uint32_t sample_rate,
uint32_t bit_width,
- audio_channel_mask_t channel_mask,
struct stream_app_type_cfg *app_type_cfg)
{
struct listnode *node_i, *node_j, *node_k;
struct streams_output_cfg *so_info;
struct stream_format *sf_info;
struct stream_sample_rate *ss_info;
- char value[PROPERTY_VALUE_MAX] = {0};
if ((24 == bit_width) &&
(devices & AUDIO_DEVICE_OUT_SPEAKER)) {
@@ -477,16 +475,6 @@
ALOGI("%s Allowing 24-bit playback on speaker ONLY at default sampling rate", __func__);
}
- property_get("audio.playback.mch.downsample",value,"");
- if (!strncmp("true", value, sizeof("true"))) {
- if ((popcount(channel_mask) > 2) &&
- (sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
- !(flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)) {
- sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
- ALOGD("%s: MCH session defaulting sample rate to %d",
- __func__, sample_rate);
- }
- }
ALOGV("%s: flags: %x, format: %x sample_rate %d",
__func__, flags, format, sample_rate);
list_for_each(node_i, streams_output_cfg_list) {
@@ -528,7 +516,6 @@
struct mixer_ctl *ctl;
int pcm_device_id, acdb_dev_id, snd_device = usecase->out_snd_device;
int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
- char value[PROPERTY_VALUE_MAX] = {0};
ALOGV("%s", __func__);
@@ -582,14 +569,6 @@
sample_rate = out->app_type_cfg.sample_rate;
}
- property_get("audio.playback.mch.downsample",value,"");
- if (!strncmp("true", value, sizeof("true"))) {
- if ((popcount(out->channel_mask) > 2) &&
- (out->sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
- !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH))
- sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
- }
-
app_type_cfg[len++] = out->app_type_cfg.app_type;
app_type_cfg[len++] = acdb_dev_id;
if (((out->format == AUDIO_FORMAT_E_AC3) ||
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 206fc22..f105007 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -912,6 +912,9 @@
(usecase->in_snd_device != SND_DEVICE_NONE) &&
(usecase->out_snd_device != SND_DEVICE_NONE)) {
status = platform_switch_voice_call_device_pre(adev->platform);
+ /* Disable sidetone only if voice call already exists */
+ if (voice_is_call_state_active(adev))
+ voice_set_sidetone(adev, usecase->out_snd_device, false);
}
/* Disable current sound devices */
@@ -954,6 +957,9 @@
out_snd_device,
in_snd_device);
enable_audio_route_for_voice_usecases(adev, usecase);
+ /* Enable sidetone only if voice call already exists */
+ if (voice_is_call_state_active(adev))
+ voice_set_sidetone(adev, out_snd_device, true);
}
usecase->in_snd_device = in_snd_device;
@@ -967,7 +973,6 @@
usecase->stream.out->format,
usecase->stream.out->sample_rate,
usecase->stream.out->bit_width,
- usecase->stream.out->channel_mask,
&usecase->stream.out->app_type_cfg);
ALOGI("%s Selected apptype: %d", __func__, usecase->stream.out->app_type_cfg.app_type);
}
@@ -2992,8 +2997,7 @@
audio_extn_utils_update_stream_app_type_cfg(adev->platform,
&adev->streams_output_cfg_list,
devices, flags, format, out->sample_rate,
- out->bit_width, out->channel_mask,
- &out->app_type_cfg);
+ out->bit_width, &out->app_type_cfg);
if ((out->usecase == USECASE_AUDIO_PLAYBACK_PRIMARY) ||
(flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {
/* Ensure the default output is not selected twice */
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 02e9aac..645edcd 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -2191,7 +2191,7 @@
goto exit;
}
- if (popcount(devices) == 2) {
+ if (popcount(devices) == 2 && !voice_is_in_call(adev)) {
if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
AUDIO_DEVICE_OUT_SPEAKER)) {
if (my_data->external_spk_1)
@@ -4026,10 +4026,15 @@
ALOGE("%s: Invalid channel mapping used", __func__);
return -EINVAL;
}
- strlcpy(mixer_ctl_name, "Playback Channel Map", sizeof(mixer_ctl_name));
+
+ /*
+ * If snd_id is greater than 0, stream channel mapping
+ * If snd_id is below 0, typically -1, device channel mapping
+ */
if (snd_id >= 0) {
- snprintf(device_num, sizeof(device_num), "%d", snd_id);
- strlcat(mixer_ctl_name, device_num, sizeof(device_num));
+ snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "Playback Channel Map%d", snd_id);
+ } else {
+ strlcpy(mixer_ctl_name, "Playback Device Channel Map", sizeof(mixer_ctl_name));
}
ALOGD("%s mixer_ctl_name:%s", __func__, mixer_ctl_name);
@@ -4445,3 +4450,16 @@
done:
return ret;
}
+
+int platform_get_wsa_mode(void *platform)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ char *snd_card_name;
+
+ snd_card_name = mixer_get_name(my_data->adev->mixer);
+ if ((!strcmp(snd_card_name, "msm8952-skum-snd-card")) ||
+ (!strcmp(snd_card_name, "msm8952-snd-card-mtp")))
+ return 1;
+ else
+ return 0;
+}
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index 7b86739..6212f23 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1175,3 +1175,8 @@
{
return -ENOSYS;
}
+
+int platform_get_wsa_mode(void *platform)
+{
+ return 0;
+}
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 45a5621..8119e52 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -2020,7 +2020,7 @@
goto exit;
}
- if (popcount(devices) == 2) {
+ if (popcount(devices) == 2 && !voice_is_in_call(adev)) {
if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
AUDIO_DEVICE_OUT_SPEAKER)) {
if (my_data->external_spk_1)
@@ -3333,7 +3333,6 @@
ALOGI("%s Codec selected backend: %d current bit width: %d and sample rate: %d",
__func__, backend_idx, bit_width, sample_rate);
-
// For voice calls use default configuration
// force routing is not required here, caller will do it anyway
if (voice_is_in_call(adev) || adev->mode == AUDIO_MODE_IN_COMMUNICATION) {
@@ -4076,3 +4075,8 @@
done:
return ret;
}
+
+int platform_get_wsa_mode (void *platform)
+{
+ return 0;
+}
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 5542a6d..dbcfec7 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -119,4 +119,5 @@
const char *spkr_1_tz_name, const char *spkr_2_tz_name);
const char *platform_get_spkr_1_tz_name(snd_device_t snd_device);
const char *platform_get_spkr_2_tz_name(snd_device_t snd_device);
+int platform_get_wsa_mode(void *platform);
#endif // AUDIO_PLATFORM_API_H
diff --git a/hal/voice.c b/hal/voice.c
index 9fc1081..95c4e21 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -55,6 +55,59 @@
return session;
}
+static bool voice_is_sidetone_device(snd_device_t out_device,
+ char *mixer_path)
+{
+ bool is_sidetone_dev;
+
+ switch (out_device) {
+ case SND_DEVICE_OUT_VOICE_HANDSET:
+ is_sidetone_dev = true;
+ strlcpy(mixer_path, "sidetone-handset", MIXER_PATH_MAX_LENGTH);
+ break;
+ case SND_DEVICE_OUT_VOICE_HEADPHONES:
+ case SND_DEVICE_OUT_VOICE_ANC_HEADSET:
+ case SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET:
+ is_sidetone_dev = true;
+ strlcpy(mixer_path, "sidetone-headphones", MIXER_PATH_MAX_LENGTH);
+ break;
+ default:
+ is_sidetone_dev = false;
+ break;
+ }
+
+ return is_sidetone_dev;
+}
+
+void voice_set_sidetone(struct audio_device *adev,
+ snd_device_t out_snd_device, bool enable)
+{
+ char mixer_path[MIXER_PATH_MAX_LENGTH];
+ bool is_sidetone_dev;
+
+ ALOGD("%s: %s, out_snd_device: %d\n",
+ __func__, (enable ? "enable" : "disable"),
+ out_snd_device);
+
+ is_sidetone_dev = voice_is_sidetone_device(out_snd_device, mixer_path);
+
+ if (!is_sidetone_dev) {
+ ALOGD("%s: device %d does not support sidetone\n",
+ __func__, out_snd_device);
+ return;
+ }
+
+ ALOGD("%s: sidetone out device = %s\n",
+ __func__, mixer_path);
+
+ if (enable)
+ audio_route_apply_and_update_path(adev->audio_route, mixer_path);
+ else
+ audio_route_reset_and_update_path(adev->audio_route, mixer_path);
+
+ return;
+}
+
int voice_stop_usecase(struct audio_device *adev, audio_usecase_t usecase_id)
{
int i, ret = 0;
@@ -69,10 +122,21 @@
return -EINVAL;
}
+ uc_info = get_usecase_from_list(adev, usecase_id);
+ if (uc_info == NULL) {
+ ALOGE("%s: Could not find the usecase (%d) in the list",
+ __func__, usecase_id);
+ return -EINVAL;
+ }
+
session->state.current = CALL_INACTIVE;
if (adev->mode == AUDIO_MODE_NORMAL)
adev->voice.is_in_call = false;
+ /* Disable sidetone only when no calls are active */
+ if (!voice_is_call_state_active(adev))
+ voice_set_sidetone(adev, uc_info->out_snd_device, false);
+
ret = platform_stop_voice_call(adev->platform, session->vsid);
/* 1. Close the PCM devices */
@@ -85,13 +149,6 @@
session->pcm_tx = NULL;
}
- uc_info = get_usecase_from_list(adev, usecase_id);
- if (uc_info == NULL) {
- ALOGE("%s: Could not find the usecase (%d) in the list",
- __func__, usecase_id);
- return -EINVAL;
- }
-
/* 2. Get and set stream specific mixer controls */
disable_audio_route(adev, uc_info);
@@ -159,6 +216,17 @@
voice_set_mic_mute(adev, adev->voice.mic_mute);
+ ALOGV("%s: Opening PCM capture device card_id(%d) device_id(%d)",
+ __func__, adev->snd_card, pcm_dev_tx_id);
+ session->pcm_tx = pcm_open(adev->snd_card,
+ pcm_dev_tx_id,
+ PCM_IN, &voice_config);
+ if (session->pcm_tx && !pcm_is_ready(session->pcm_tx)) {
+ ALOGE("%s: %s", __func__, pcm_get_error(session->pcm_tx));
+ ret = -EIO;
+ goto error_start_voice;
+ }
+
ALOGV("%s: Opening PCM playback device card_id(%d) device_id(%d)",
__func__, adev->snd_card, pcm_dev_rx_id);
session->pcm_rx = pcm_open(adev->snd_card,
@@ -170,18 +238,12 @@
goto error_start_voice;
}
- ALOGV("%s: Opening PCM capture device card_id(%d) device_id(%d)",
- __func__, adev->snd_card, pcm_dev_tx_id);
- session->pcm_tx = pcm_open(adev->snd_card,
- pcm_dev_tx_id,
- PCM_IN, &voice_config);
- if (session->pcm_tx && !pcm_is_ready(session->pcm_tx)) {
- ALOGE("%s: %s", __func__, pcm_get_error(session->pcm_tx));
- ret = -EIO;
- goto error_start_voice;
- }
- pcm_start(session->pcm_rx);
pcm_start(session->pcm_tx);
+ pcm_start(session->pcm_rx);
+
+ /* Enable sidetone only when no calls are already active */
+ if (!voice_is_call_state_active(adev))
+ voice_set_sidetone(adev, uc_info->out_snd_device, true);
voice_set_volume(adev, adev->voice.volume);
diff --git a/hal/voice.h b/hal/voice.h
index 5a9cce1..139a8c8 100644
--- a/hal/voice.h
+++ b/hal/voice.h
@@ -95,4 +95,8 @@
struct stream_in *in);
void voice_update_devices_for_all_voice_usecases(struct audio_device *adev);
snd_device_t voice_get_incall_rec_snd_device(snd_device_t in_snd_device);
+void voice_set_sidetone(struct audio_device *adev,
+ snd_device_t out_snd_device,
+ bool enable);
+bool voice_is_call_state_active(struct audio_device *adev);
#endif //VOICE_H
diff --git a/post_proc/bundle.c b/post_proc/bundle.c
index e38a41c..bb21f7e 100644
--- a/post_proc/bundle.c
+++ b/post_proc/bundle.c
@@ -302,9 +302,6 @@
goto exit;
}
- if (out_ctxt->mixer)
- mixer_close(out_ctxt->mixer);
-
list_for_each(fx_node, &out_ctxt->effects_list) {
effect_context_t *fx_ctxt = node_to_item(fx_node,
effect_context_t,
@@ -313,6 +310,9 @@
fx_ctxt->ops.stop(fx_ctxt, out_ctxt);
}
+ if (out_ctxt->mixer)
+ mixer_close(out_ctxt->mixer);
+
list_remove(&out_ctxt->outputs_list_node);
#ifdef DTS_EAGLE