summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRavi Kumar Alamanda <ralama@codeaurora.org>2014-09-05 13:51:35 -0700
committerVidyakumar Athota <vathota@codeaurora.org>2014-10-14 14:55:19 -0700
commit27b87f55c3dab858f8448c4003a7da5522255172 (patch)
tree71e8b49ac4df2978dc2cb5d2bc542d246f7ac781
parentf2fadd4b6782930ed6b46439e2acec361845dd4a (diff)
downloadandroid_hardware_qcom_audio-27b87f55c3dab858f8448c4003a7da5522255172.tar.gz
android_hardware_qcom_audio-27b87f55c3dab858f8448c4003a7da5522255172.tar.bz2
android_hardware_qcom_audio-27b87f55c3dab858f8448c4003a7da5522255172.zip
hal: add support to send/receive voice call TX/RX audio
Add support for routing voice calls to devices in other audio HALs by allowing playback and capture to/from AFE proxy Change-Id: I2c6a1ddec072e1d5f1a8b7ded874e9c082a7b810
-rw-r--r--hal/audio_hw.c214
-rw-r--r--hal/audio_hw.h8
-rw-r--r--hal/msm8974/platform.c21
-rw-r--r--hal/msm8974/platform.h5
-rw-r--r--hal/voice.c10
-rw-r--r--hal/voice.h1
-rw-r--r--hal/voice_extn/voice_extn.c3
7 files changed, 212 insertions, 50 deletions
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 0fd0aaeb..f1f2b389 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -60,6 +60,8 @@
#define COMPRESS_OFFLOAD_PLAYBACK_LATENCY 96
#define COMPRESS_PLAYBACK_VOLUME_MAX 0x2000
+#define PROXY_OPEN_RETRY_COUNT 100
+#define PROXY_OPEN_WAIT_TIME 20
#define USECASE_AUDIO_PLAYBACK_PRIMARY USECASE_AUDIO_PLAYBACK_DEEP_BUFFER
@@ -102,6 +104,37 @@ struct pcm_config pcm_config_audio_capture = {
.format = PCM_FORMAT_S16_LE,
};
+#define AFE_PROXY_CHANNEL_COUNT 2
+#define AFE_PROXY_SAMPLING_RATE 48000
+
+#define AFE_PROXY_PLAYBACK_PERIOD_SIZE 768
+#define AFE_PROXY_PLAYBACK_PERIOD_COUNT 4
+
+struct pcm_config pcm_config_afe_proxy_playback = {
+ .channels = AFE_PROXY_CHANNEL_COUNT,
+ .rate = AFE_PROXY_SAMPLING_RATE,
+ .period_size = AFE_PROXY_PLAYBACK_PERIOD_SIZE,
+ .period_count = AFE_PROXY_PLAYBACK_PERIOD_COUNT,
+ .format = PCM_FORMAT_S16_LE,
+ .start_threshold = AFE_PROXY_PLAYBACK_PERIOD_SIZE,
+ .stop_threshold = INT_MAX,
+ .avail_min = AFE_PROXY_PLAYBACK_PERIOD_SIZE,
+};
+
+#define AFE_PROXY_RECORD_PERIOD_SIZE 768
+#define AFE_PROXY_RECORD_PERIOD_COUNT 4
+
+struct pcm_config pcm_config_afe_proxy_record = {
+ .channels = AFE_PROXY_CHANNEL_COUNT,
+ .rate = AFE_PROXY_SAMPLING_RATE,
+ .period_size = AFE_PROXY_RECORD_PERIOD_SIZE,
+ .period_count = AFE_PROXY_RECORD_PERIOD_COUNT,
+ .format = PCM_FORMAT_S16_LE,
+ .start_threshold = AFE_PROXY_RECORD_PERIOD_SIZE,
+ .stop_threshold = INT_MAX,
+ .avail_min = AFE_PROXY_RECORD_PERIOD_SIZE,
+};
+
const char * const use_case_table[AUDIO_USECASE_MAX] = {
[USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = "deep-buffer-playback",
[USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = "low-latency-playback",
@@ -133,6 +166,9 @@ const char * const use_case_table[AUDIO_USECASE_MAX] = {
[USECASE_INCALL_MUSIC_UPLINK2] = "incall_music_uplink2",
[USECASE_AUDIO_SPKR_CALIB_RX] = "spkr-rx-calib",
[USECASE_AUDIO_SPKR_CALIB_TX] = "spkr-vi-record",
+
+ [USECASE_AUDIO_PLAYBACK_AFE_PROXY] = "afe-proxy-playback",
+ [USECASE_AUDIO_RECORD_AFE_PROXY] = "afe-proxy-record",
};
static const audio_usecase_t offload_usecases[] = {
@@ -612,7 +648,7 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id)
* usecase. This is to avoid switching devices for voice call when
* check_usecases_codec_backend() is called below.
*/
- if (adev->voice.in_call && adev->mode == AUDIO_MODE_IN_CALL) {
+ if (voice_is_in_call(adev)) {
vc_usecase = get_usecase_from_list(adev,
get_voice_usecase_id_from_list(adev));
if ((vc_usecase) && ((vc_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) ||
@@ -649,14 +685,14 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id)
usecase->devices = usecase->stream.in->device;
out_snd_device = SND_DEVICE_NONE;
if (in_snd_device == SND_DEVICE_NONE) {
+ audio_devices_t out_device = AUDIO_DEVICE_NONE;
if (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
adev->primary_output && !adev->primary_output->standby) {
- in_snd_device = platform_get_input_snd_device(adev->platform,
- adev->primary_output->devices);
- } else {
- in_snd_device = platform_get_input_snd_device(adev->platform,
- AUDIO_DEVICE_NONE);
+ out_device = adev->primary_output->devices;
+ } else if (usecase->id == USECASE_AUDIO_RECORD_AFE_PROXY) {
+ out_device = AUDIO_DEVICE_OUT_TELEPHONY_TX;
}
+ in_snd_device = platform_get_input_snd_device(adev->platform, out_device);
}
}
}
@@ -808,16 +844,33 @@ int start_input_stream(struct stream_in *in)
select_devices(adev, in->usecase);
ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d",
- __func__, adev->snd_card,
- in->pcm_device_id, in->config.channels);
- in->pcm = pcm_open(adev->snd_card,
- in->pcm_device_id, PCM_IN, &in->config);
- if (in->pcm && !pcm_is_ready(in->pcm)) {
- ALOGE("%s: %s", __func__, pcm_get_error(in->pcm));
- pcm_close(in->pcm);
- in->pcm = NULL;
- ret = -EIO;
- goto error_open;
+ __func__, adev->snd_card, in->pcm_device_id, in->config.channels);
+
+ unsigned int flags = PCM_IN;
+ unsigned int pcm_open_retry_count = 0;
+
+ if (in->usecase == USECASE_AUDIO_RECORD_AFE_PROXY) {
+ flags |= PCM_MMAP | PCM_NOIRQ;
+ pcm_open_retry_count = PROXY_OPEN_RETRY_COUNT;
+ }
+
+ while (1) {
+ in->pcm = pcm_open(adev->snd_card, in->pcm_device_id,
+ flags, &in->config);
+ if (in->pcm == NULL || !pcm_is_ready(in->pcm)) {
+ ALOGE("%s: %s", __func__, pcm_get_error(in->pcm));
+ if (in->pcm != NULL) {
+ pcm_close(in->pcm);
+ in->pcm = NULL;
+ }
+ if (pcm_open_retry_count-- == 0) {
+ ret = -EIO;
+ goto error_open;
+ }
+ usleep(PROXY_OPEN_WAIT_TIME * 1000);
+ continue;
+ }
+ break;
}
ALOGV("%s: exit", __func__);
return ret;
@@ -1217,18 +1270,34 @@ int start_output_stream(struct stream_out *out)
select_devices(adev, out->usecase);
- ALOGV("%s: Opening PCM device card_id(%d) device_id(%d)",
- __func__, 0, out->pcm_device_id);
+ ALOGV("%s: Opening PCM device card_id(%d) device_id(%d) format(%#x)",
+ __func__, adev->snd_card, out->pcm_device_id, out->config.format);
if (!is_offload_usecase(out->usecase)) {
- out->pcm = pcm_open(adev->snd_card,
- out->pcm_device_id,
- PCM_OUT | PCM_MONOTONIC, &out->config);
- if (out->pcm && !pcm_is_ready(out->pcm)) {
- ALOGE("%s: %s", __func__, pcm_get_error(out->pcm));
- pcm_close(out->pcm);
- out->pcm = NULL;
- ret = -EIO;
- goto error_open;
+ unsigned int flags = PCM_OUT;
+ unsigned int pcm_open_retry_count = 0;
+ if (out->usecase == USECASE_AUDIO_PLAYBACK_AFE_PROXY) {
+ flags |= PCM_MMAP | PCM_NOIRQ;
+ pcm_open_retry_count = PROXY_OPEN_RETRY_COUNT;
+ } else
+ flags |= PCM_MONOTONIC;
+
+ while (1) {
+ out->pcm = pcm_open(adev->snd_card, out->pcm_device_id,
+ flags, &out->config);
+ if (out->pcm == NULL || !pcm_is_ready(out->pcm)) {
+ ALOGE("%s: %s", __func__, pcm_get_error(out->pcm));
+ if (out->pcm != NULL) {
+ pcm_close(out->pcm);
+ out->pcm = NULL;
+ }
+ if (pcm_open_retry_count-- == 0) {
+ ret = -EIO;
+ goto error_open;
+ }
+ usleep(PROXY_OPEN_WAIT_TIME * 1000);
+ continue;
+ }
+ break;
}
platform_set_default_channel_map(adev->platform, out->config.channels,
out->pcm_device_id);
@@ -1472,6 +1541,10 @@ static int parse_compress_metadata(struct stream_out *out, struct str_parms *par
return 0;
}
+static bool output_drives_call(struct audio_device *adev, struct stream_out *out)
+{
+ return out == adev->primary_output || out == adev->voice_tx_output;
+}
static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
{
@@ -1531,22 +1604,15 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
select_devices(adev, out->usecase);
if ((adev->mode == AUDIO_MODE_IN_CALL) &&
- !adev->voice.in_call &&
- (out == adev->primary_output)) {
- ret = voice_start_call(adev);
- } else if ((adev->mode == AUDIO_MODE_IN_CALL) &&
- adev->voice.in_call &&
- (out == adev->primary_output)) {
- voice_update_devices_for_all_voice_usecases(adev);
+ output_drives_call(adev, out)) {
+ adev->current_call_output = out;
+ if (!voice_is_in_call(adev))
+ ret = voice_start_call(adev);
+ else
+ voice_update_devices_for_all_voice_usecases(adev);
}
}
- if ((adev->mode == AUDIO_MODE_NORMAL) &&
- adev->voice.in_call &&
- (out == adev->primary_output)) {
- ret = voice_stop_call(adev);
- }
-
pthread_mutex_unlock(&adev->lock);
pthread_mutex_unlock(&out->lock);
}
@@ -1752,8 +1818,13 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
if (out->muted)
memset((void *)buffer, 0, bytes);
ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
- ret = pcm_write(out->pcm, (void *)buffer, bytes);
- if (ret == 0)
+ if (out->usecase == USECASE_AUDIO_PLAYBACK_AFE_PROXY)
+ ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes);
+ else
+ ret = pcm_write(out->pcm, (void *)buffer, bytes);
+ if (ret < 0)
+ ret = -errno;
+ else if (ret == 0)
out->written += bytes / (out->config.channels * sizeof(short));
}
}
@@ -2053,7 +2124,7 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
err = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
if (err >= 0) {
val = atoi(value);
- if ((in->device != val) && (val != 0)) {
+ if (((int)in->device != val) && (val != 0)) {
in->device = val;
/* If recording is in progress, change the tx device to new device */
if (!in->standby)
@@ -2129,6 +2200,8 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
ret = audio_extn_ssr_read(stream, buffer, bytes);
else if (audio_extn_compr_cap_usecase_supported(in->usecase))
ret = audio_extn_compr_cap_read(in, buffer, bytes);
+ else if (in->usecase == USECASE_AUDIO_RECORD_AFE_PROXY)
+ ret = pcm_mmap_read(in->pcm, buffer, bytes);
else
ret = pcm_read(in->pcm, buffer, bytes);
}
@@ -2378,6 +2451,28 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
__func__, ret);
goto error_open;
}
+ } else if (out->devices == AUDIO_DEVICE_OUT_TELEPHONY_TX) {
+ if (config->sample_rate == 0)
+ config->sample_rate = AFE_PROXY_SAMPLING_RATE;
+ if (config->sample_rate != 48000 && config->sample_rate != 16000 &&
+ config->sample_rate != 8000) {
+ config->sample_rate = AFE_PROXY_SAMPLING_RATE;
+ ret = -EINVAL;
+ goto error_open;
+ }
+ out->sample_rate = config->sample_rate;
+ out->config.rate = config->sample_rate;
+ if (config->format == AUDIO_FORMAT_DEFAULT)
+ config->format = AUDIO_FORMAT_PCM_16_BIT;
+ if (config->format != AUDIO_FORMAT_PCM_16_BIT) {
+ config->format = AUDIO_FORMAT_PCM_16_BIT;
+ ret = -EINVAL;
+ goto error_open;
+ }
+ out->format = config->format;
+ out->usecase = USECASE_AUDIO_PLAYBACK_AFE_PROXY;
+ out->config = pcm_config_afe_proxy_playback;
+ adev->voice_tx_output = out;
} else if (out->flags & AUDIO_OUTPUT_FLAG_FAST) {
out->usecase = USECASE_AUDIO_PLAYBACK_LOW_LATENCY;
out->config = pcm_config_low_latency;
@@ -2475,6 +2570,10 @@ static void adev_close_output_stream(struct audio_hw_device *dev __unused,
if (out->compr_config.codec != NULL)
free(out->compr_config.codec);
}
+
+ if (adev->voice_tx_output == out)
+ adev->voice_tx_output = NULL;
+
pthread_cond_destroy(&out->cond);
pthread_mutex_destroy(&out->lock);
free(stream);
@@ -2640,10 +2739,16 @@ static int adev_get_master_mute(struct audio_hw_device *dev __unused,
static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
{
struct audio_device *adev = (struct audio_device *)dev;
+
pthread_mutex_lock(&adev->lock);
if (adev->mode != mode) {
ALOGD("%s mode %d\n", __func__, mode);
adev->mode = mode;
+ if ((mode == AUDIO_MODE_NORMAL || mode == AUDIO_MODE_IN_COMMUNICATION) &&
+ voice_is_in_call(adev)) {
+ voice_stop_call(adev);
+ adev->current_call_output = NULL;
+ }
}
pthread_mutex_unlock(&adev->lock);
return 0;
@@ -2726,7 +2831,28 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
in->config.rate = config->sample_rate;
in->format = config->format;
- if (channel_count == 6) {
+ if (in->device == AUDIO_DEVICE_IN_TELEPHONY_RX) {
+ if (config->sample_rate == 0)
+ config->sample_rate = AFE_PROXY_SAMPLING_RATE;
+ if (config->sample_rate != 48000 && config->sample_rate != 16000 &&
+ config->sample_rate != 8000) {
+ config->sample_rate = AFE_PROXY_SAMPLING_RATE;
+ ret = -EINVAL;
+ goto err_open;
+ }
+ if (config->format == AUDIO_FORMAT_DEFAULT)
+ config->format = AUDIO_FORMAT_PCM_16_BIT;
+ if (config->format != AUDIO_FORMAT_PCM_16_BIT) {
+ config->format = AUDIO_FORMAT_PCM_16_BIT;
+ ret = -EINVAL;
+ goto err_open;
+ }
+
+ in->usecase = USECASE_AUDIO_RECORD_AFE_PROXY;
+ in->config = pcm_config_afe_proxy_record;
+ in->config.channels = channel_count;
+ in->config.rate = config->sample_rate;
+ } else if (channel_count == 6) {
if(audio_extn_ssr_get_enabled()) {
if(audio_extn_ssr_init(in)) {
ALOGE("%s: audio_extn_ssr_init failed", __func__);
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index a7033e6c..024960f3 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -105,6 +105,10 @@ typedef enum {
USECASE_AUDIO_SPKR_CALIB_RX,
USECASE_AUDIO_SPKR_CALIB_TX,
+
+ USECASE_AUDIO_PLAYBACK_AFE_PROXY,
+ USECASE_AUDIO_RECORD_AFE_PROXY,
+
AUDIO_USECASE_MAX
} audio_usecase_t;
@@ -185,7 +189,7 @@ struct stream_in {
int standby;
int source;
int pcm_device_id;
- int device;
+ audio_devices_t device;
audio_channel_mask_t channel_mask;
audio_usecase_t usecase;
bool enable_aec;
@@ -226,6 +230,8 @@ struct audio_device {
audio_devices_t out_device;
struct stream_in *active_input;
struct stream_out *primary_output;
+ struct stream_out *voice_tx_output;
+ struct stream_out *current_call_output;
bool bluetooth_nrec;
bool screen_off;
int *snd_dev_ref_cnt;
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 702e7aa2..8a9079cd 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -190,6 +190,12 @@ static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
INCALL_MUSIC_UPLINK2_PCM_DEVICE},
[USECASE_AUDIO_SPKR_CALIB_RX] = {SPKR_PROT_CALIB_RX_PCM_DEVICE, -1},
[USECASE_AUDIO_SPKR_CALIB_TX] = {-1, SPKR_PROT_CALIB_TX_PCM_DEVICE},
+
+ [USECASE_AUDIO_PLAYBACK_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
+ AFE_PROXY_RECORD_PCM_DEVICE},
+ [USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
+ AFE_PROXY_RECORD_PCM_DEVICE},
+
};
/* Array to store sound devices */
@@ -211,6 +217,7 @@ static const char * const device_table[SND_DEVICE_MAX] = {
[SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
[SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
+ [SND_DEVICE_OUT_VOICE_TX] = "voice-tx",
[SND_DEVICE_OUT_AFE_PROXY] = "afe-proxy",
[SND_DEVICE_OUT_USB_HEADSET] = "usb-headphones",
[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = "speaker-and-usb-headphones",
@@ -254,6 +261,8 @@ static const char * const device_table[SND_DEVICE_MAX] = {
[SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
[SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
[SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
+ [SND_DEVICE_IN_VOICE_RX] = "voice-rx",
+
[SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
[SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic",
[SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef",
@@ -290,6 +299,7 @@ static int acdb_device_table[SND_DEVICE_MAX] = {
[SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
[SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
+ [SND_DEVICE_OUT_VOICE_TX] = 45,
[SND_DEVICE_OUT_AFE_PROXY] = 0,
[SND_DEVICE_OUT_USB_HEADSET] = 45,
[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = 14,
@@ -332,6 +342,8 @@ static int acdb_device_table[SND_DEVICE_MAX] = {
[SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
[SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36,
[SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16,
+ [SND_DEVICE_IN_VOICE_RX] = 44,
+
[SND_DEVICE_IN_VOICE_REC_MIC] = 4,
[SND_DEVICE_IN_VOICE_REC_MIC_NS] = 107,
[SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 34,
@@ -665,6 +677,8 @@ static void set_platform_defaults()
backend_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("bt-sco-wb");
backend_table[SND_DEVICE_OUT_HDMI] = strdup("hdmi");
backend_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("speaker-and-hdmi");
+ backend_table[SND_DEVICE_OUT_VOICE_TX] = strdup("afe-proxy");
+ backend_table[SND_DEVICE_IN_VOICE_RX] = strdup("afe-proxy");
backend_table[SND_DEVICE_OUT_AFE_PROXY] = strdup("afe-proxy");
backend_table[SND_DEVICE_OUT_USB_HEADSET] = strdup("usb-headphones");
backend_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] =
@@ -1409,7 +1423,9 @@ snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devi
snd_device = SND_DEVICE_OUT_ANC_HANDSET;
else
snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
- }
+ } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX)
+ snd_device = SND_DEVICE_OUT_VOICE_TX;
+
if (snd_device != SND_DEVICE_NONE) {
goto exit;
}
@@ -1534,7 +1550,8 @@ snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_d
} else {
snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
}
- }
+ } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX)
+ snd_device = SND_DEVICE_IN_VOICE_RX;
} else if (source == AUDIO_SOURCE_CAMCORDER) {
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
in_device & AUDIO_DEVICE_IN_BACK_MIC) {
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 5800848c..d6d3e538 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -66,6 +66,7 @@ enum {
SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES,
SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES,
SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET,
+ SND_DEVICE_OUT_VOICE_TX,
SND_DEVICE_OUT_AFE_PROXY,
SND_DEVICE_OUT_USB_HEADSET,
SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET,
@@ -119,6 +120,7 @@ enum {
SND_DEVICE_IN_VOICE_REC_MIC_NS,
SND_DEVICE_IN_VOICE_REC_DMIC_STEREO,
SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE,
+ SND_DEVICE_IN_VOICE_RX,
SND_DEVICE_IN_USB_HEADSET_MIC,
SND_DEVICE_IN_CAPTURE_FM,
SND_DEVICE_IN_AANC_HANDSET_MIC,
@@ -234,6 +236,9 @@ enum {
#define VOWLAN_CALL_PCM_DEVICE 36
#endif
+#define AFE_PROXY_PLAYBACK_PCM_DEVICE 7
+#define AFE_PROXY_RECORD_PCM_DEVICE 8
+
#ifdef PLATFORM_MSM8x26
#define HFP_SCO_RX 28
#define HFP_ASM_RX_TX 29
diff --git a/hal/voice.c b/hal/voice.c
index 8dd04bc8..94afa47c 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -116,8 +116,8 @@ int start_call(struct audio_device *adev, audio_usecase_t usecase_id)
uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
uc_info->id = usecase_id;
uc_info->type = VOICE_CALL;
- uc_info->stream.out = adev->primary_output;
- uc_info->devices = adev->primary_output->devices;
+ uc_info->stream.out = adev->current_call_output ;
+ uc_info->devices = adev->current_call_output ->devices;
uc_info->in_snd_device = SND_DEVICE_NONE;
uc_info->out_snd_device = SND_DEVICE_NONE;
@@ -198,6 +198,11 @@ bool voice_is_call_state_active(struct audio_device *adev)
return call_state;
}
+bool voice_is_in_call(struct audio_device *adev)
+{
+ return adev->voice.in_call;
+}
+
uint32_t voice_get_active_session_id(struct audio_device *adev)
{
int ret = 0;
@@ -458,6 +463,7 @@ void voice_update_devices_for_all_voice_usecases(struct audio_device *adev)
if (usecase->type == VOICE_CALL) {
ALOGV("%s: updating device for usecase:%s", __func__,
use_case_table[usecase->id]);
+ usecase->stream.out = adev->current_call_output;
select_devices(adev, usecase->id);
}
}
diff --git a/hal/voice.h b/hal/voice.h
index abb8c559..1f4f35ed 100644
--- a/hal/voice.h
+++ b/hal/voice.h
@@ -76,6 +76,7 @@ int voice_set_parameters(struct audio_device *adev, struct str_parms *parms);
void voice_get_parameters(struct audio_device *adev, struct str_parms *query,
struct str_parms *reply);
void voice_init(struct audio_device *adev);
+bool voice_is_in_call(struct audio_device *adev);
bool voice_is_call_state_active(struct audio_device *adev);
int voice_set_mic_mute(struct audio_device *dev, bool state);
bool voice_get_mic_mute(struct audio_device *dev);
diff --git a/hal/voice_extn/voice_extn.c b/hal/voice_extn/voice_extn.c
index a0c4706f..bdf6b414 100644
--- a/hal/voice_extn/voice_extn.c
+++ b/hal/voice_extn/voice_extn.c
@@ -300,7 +300,8 @@ static int update_call_states(struct audio_device *adev,
* occured, otherwise voice calls will be started unintendedly on
* speaker.
*/
- if (is_call_active || adev->voice.in_call) {
+ if (is_call_active ||
+ (adev->voice.in_call && adev->mode == AUDIO_MODE_IN_CALL)) {
/* Device routing is not triggered for voice calls on the subsequent
* subs, Hence update the call states if voice call is already
* active on other sub.