From a609e8ebdfeca875b6d35ccfb3fb8b87710f3499 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Wed, 18 Jun 2014 02:15:17 +0000 Subject: Revert "hal: Add support for IMS calls" This reverts commit cedf1ac3c00e331b5f51b077f26c1367544ddd65. Change-Id: I5f92f28c8b97265263a0bce5b38ff60d4655b68b --- hal/Android.mk | 9 +- hal/audio_extn/hfp.c | 14 +- hal/audio_hw.c | 306 ++++++++++++++++------- hal/audio_hw.h | 32 +-- hal/msm8960/platform.c | 43 +--- hal/msm8960/platform.h | 2 +- hal/msm8974/platform.c | 301 ++++++----------------- hal/msm8974/platform.h | 26 +- hal/platform_api.h | 14 +- hal/voice.c | 451 ---------------------------------- hal/voice.h | 88 ------- hal/voice_extn/voice_extn.c | 585 -------------------------------------------- hal/voice_extn/voice_extn.h | 99 -------- 13 files changed, 330 insertions(+), 1640 deletions(-) delete mode 100644 hal/voice.c delete mode 100644 hal/voice.h delete mode 100644 hal/voice_extn/voice_extn.c delete mode 100644 hal/voice_extn/voice_extn.h (limited to 'hal') diff --git a/hal/Android.mk b/hal/Android.mk index 30abdf31..910edbe6 100644 --- a/hal/Android.mk +++ b/hal/Android.mk @@ -20,7 +20,6 @@ endif LOCAL_SRC_FILES := \ audio_hw.c \ - voice.c \ $(AUDIO_PLATFORM)/platform.c LOCAL_SHARED_LIBRARIES := \ @@ -37,19 +36,13 @@ LOCAL_C_INCLUDES += \ $(call include-path-for, audio-route) \ $(call include-path-for, audio-effects) \ $(LOCAL_PATH)/$(AUDIO_PLATFORM) \ - $(LOCAL_PATH)/audio_extn \ - $(LOCAL_PATH)/voice_extn + $(LOCAL_PATH)/audio_extn ifneq ($(filter msm8084,$(TARGET_BOARD_PLATFORM)),) LOCAL_SHARED_LIBRARIES += libmdmdetect LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/libmdmdetect/inc endif -ifeq ($(strip $(AUDIO_FEATURE_ENABLED_MULTI_VOICE_SESSIONS)),true) - LOCAL_CFLAGS += -DMULTI_VOICE_SESSION_ENABLED - LOCAL_SRC_FILES += voice_extn/voice_extn.c -endif - ifeq ($(strip $(AUDIO_FEATURE_ENABLED_HFP)),true) LOCAL_CFLAGS += -DHFP_ENABLED LOCAL_SRC_FILES += audio_extn/hfp.c diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c index a1087309..aa5d2099 100644 --- a/hal/audio_extn/hfp.c +++ b/hal/audio_extn/hfp.c @@ -144,8 +144,8 @@ static int32_t start_hfp(struct audio_device *adev, __func__, pcm_dev_rx_id, pcm_dev_tx_id, uc_info->id); ALOGV("%s: Opening PCM playback device card_id(%d) device_id(%d)", - __func__, adev->snd_card, pcm_dev_rx_id); - hfpmod.hfp_sco_rx = pcm_open(adev->snd_card, + __func__, SOUND_CARD, pcm_dev_rx_id); + hfpmod.hfp_sco_rx = pcm_open(SOUND_CARD, pcm_dev_asm_rx_id, PCM_OUT, &pcm_config_hfp); if (hfpmod.hfp_sco_rx && !pcm_is_ready(hfpmod.hfp_sco_rx)) { @@ -154,8 +154,8 @@ static int32_t start_hfp(struct audio_device *adev, goto exit; } 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, + __func__, SOUND_CARD, pcm_dev_tx_id); + hfpmod.hfp_pcm_rx = pcm_open(SOUND_CARD, pcm_dev_rx_id, PCM_OUT, &pcm_config_hfp); if (hfpmod.hfp_pcm_rx && !pcm_is_ready(hfpmod.hfp_pcm_rx)) { @@ -163,7 +163,7 @@ static int32_t start_hfp(struct audio_device *adev, ret = -EIO; goto exit; } - hfpmod.hfp_sco_tx = pcm_open(adev->snd_card, + hfpmod.hfp_sco_tx = pcm_open(SOUND_CARD, pcm_dev_asm_tx_id, PCM_IN, &pcm_config_hfp); if (hfpmod.hfp_sco_tx && !pcm_is_ready(hfpmod.hfp_sco_tx)) { @@ -172,8 +172,8 @@ static int32_t start_hfp(struct audio_device *adev, goto exit; } 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, + __func__, SOUND_CARD, pcm_dev_tx_id); + hfpmod.hfp_pcm_tx = pcm_open(SOUND_CARD, pcm_dev_tx_id, PCM_IN, &pcm_config_hfp); if (hfpmod.hfp_pcm_tx && !pcm_is_ready(hfpmod.hfp_pcm_tx)) { diff --git a/hal/audio_hw.c b/hal/audio_hw.c index 55555f55..b8fe400e 100644 --- a/hal/audio_hw.c +++ b/hal/audio_hw.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2014 The Android Open Source Project + * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,7 +48,6 @@ #include "audio_extn.h" #include "platform_api.h" #include -#include "voice_extn.h" #include "sound/compress_params.h" @@ -105,23 +104,24 @@ struct pcm_config pcm_config_audio_capture = { .format = PCM_FORMAT_S16_LE, }; -const char * const use_case_table[AUDIO_USECASE_MAX] = { +struct pcm_config pcm_config_voice_call = { + .channels = 1, + .rate = 8000, + .period_size = 160, + .period_count = 2, + .format = PCM_FORMAT_S16_LE, +}; + +static 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", [USECASE_AUDIO_PLAYBACK_MULTI_CH] = "multi-channel-playback", - [USECASE_AUDIO_PLAYBACK_OFFLOAD] = "compress-offload-playback", - [USECASE_AUDIO_RECORD] = "audio-record", [USECASE_AUDIO_RECORD_LOW_LATENCY] = "low-latency-record", - [USECASE_AUDIO_HFP_SCO] = "hfp-sco", [USECASE_AUDIO_HFP_SCO_WB] = "hfp-sco-wb", - [USECASE_VOICE_CALL] = "voice-call", - [USECASE_VOICE2_CALL] = "voice2-call", - [USECASE_VOLTE_CALL] = "volte-call", - [USECASE_QCHAT_CALL] = "qchat-call", - [USECASE_VOWLAN_CALL] = "vowlan-call", + [USECASE_AUDIO_PLAYBACK_OFFLOAD] = "compress-offload-playback", }; @@ -167,19 +167,6 @@ static int get_snd_codec_id(audio_format_t format) return id; } -int pcm_ioctl(void *pcm, int request, ...) -{ - va_list ap; - void * arg; - int pcm_fd = *(int*)pcm; - - va_start(ap, request); - arg = va_arg(ap, void *); - va_end(ap); - - return ioctl(pcm_fd, request, arg); -} - int enable_audio_route(struct audio_device *adev, struct audio_usecase *usecase) { @@ -229,7 +216,7 @@ int disable_audio_route(struct audio_device *adev, } int enable_snd_device(struct audio_device *adev, - snd_device_t snd_device) + snd_device_t snd_device) { if (snd_device < SND_DEVICE_MIN || snd_device >= SND_DEVICE_MAX) { @@ -257,7 +244,7 @@ int enable_snd_device(struct audio_device *adev, } int disable_snd_device(struct audio_device *adev, - snd_device_t snd_device) + snd_device_t snd_device) { if (snd_device < SND_DEVICE_MIN || snd_device >= SND_DEVICE_MAX) { @@ -386,12 +373,6 @@ static void check_and_route_capture_usecases(struct audio_device *adev, usecase = node_to_item(node, struct audio_usecase, list); if (switch_device[usecase->id]) { disable_snd_device(adev, usecase->in_snd_device); - } - } - - list_for_each(node, &adev->usecase_list) { - usecase = node_to_item(node, struct audio_usecase, list); - if (switch_device[usecase->id]) { enable_snd_device(adev, snd_device); } } @@ -409,6 +390,7 @@ static void check_and_route_capture_usecases(struct audio_device *adev, } } + /* must be called with hw device mutex locked */ static int read_hdmi_channel_masks(struct stream_out *out) { @@ -483,10 +465,9 @@ int select_devices(struct audio_device *adev, * usecase. This is to avoid switching devices for voice call when * check_usecases_codec_backend() is called below. */ - if (voice_is_in_call(adev)) { + if (adev->in_call) { vc_usecase = get_usecase_from_list(adev, USECASE_VOICE_CALL); - if ((vc_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) || - (usecase->devices == AUDIO_DEVICE_IN_VOICE_CALL)) { + if (vc_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) { in_snd_device = vc_usecase->in_snd_device; out_snd_device = vc_usecase->out_snd_device; } @@ -657,8 +638,8 @@ 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, + __func__, SOUND_CARD, in->pcm_device_id, in->config.channels); + in->pcm = pcm_open(SOUND_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)); @@ -965,9 +946,9 @@ int start_output_stream(struct stream_out *out) select_devices(adev, out->usecase); ALOGV("%s: Opening PCM device card_id(%d) device_id(%d) format(%#x)", - __func__, adev->snd_card, out->pcm_device_id, out->config.format); + __func__, SOUND_CARD, out->pcm_device_id, out->config.format); if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) { - out->pcm = pcm_open(adev->snd_card, out->pcm_device_id, + out->pcm = pcm_open(SOUND_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)); @@ -978,7 +959,7 @@ int start_output_stream(struct stream_out *out) } } else { out->pcm = NULL; - out->compr = compress_open(adev->snd_card, out->pcm_device_id, + out->compr = compress_open(SOUND_CARD, out->pcm_device_id, COMPRESS_IN, &out->compr_config); if (out->compr && !is_compress_ready(out->compr)) { ALOGE("%s: %s", __func__, compress_get_error(out->compr)); @@ -1001,6 +982,120 @@ error_config: return ret; } +static int stop_voice_call(struct audio_device *adev) +{ + int i, ret = 0; + struct audio_usecase *uc_info; + + ALOGV("%s: enter", __func__); + adev->in_call = false; + + ret = platform_stop_voice_call(adev->platform); + + /* 1. Close the PCM devices */ + if (adev->voice_call_rx) { + pcm_close(adev->voice_call_rx); + adev->voice_call_rx = NULL; + } + if (adev->voice_call_tx) { + pcm_close(adev->voice_call_tx); + adev->voice_call_tx = NULL; + } + + uc_info = get_usecase_from_list(adev, USECASE_VOICE_CALL); + if (uc_info == NULL) { + ALOGE("%s: Could not find the usecase (%d) in the list", + __func__, USECASE_VOICE_CALL); + return -EINVAL; + } + + /* 2. Get and set stream specific mixer controls */ + disable_audio_route(adev, uc_info); + + /* 3. Disable the rx and tx devices */ + disable_snd_device(adev, uc_info->out_snd_device); + disable_snd_device(adev, uc_info->in_snd_device); + + list_remove(&uc_info->list); + free(uc_info); + + ALOGV("%s: exit: status(%d)", __func__, ret); + return ret; +} + +static int start_voice_call(struct audio_device *adev) +{ + int i, ret = 0; + struct audio_usecase *uc_info; + int pcm_dev_rx_id, pcm_dev_tx_id; + + ALOGV("%s: enter", __func__); + + uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase)); + uc_info->id = USECASE_VOICE_CALL; + uc_info->type = VOICE_CALL; + uc_info->stream.out = adev->primary_output; + uc_info->devices = adev->primary_output->devices; + uc_info->in_snd_device = SND_DEVICE_NONE; + uc_info->out_snd_device = SND_DEVICE_NONE; + + list_add_tail(&adev->usecase_list, &uc_info->list); + + select_devices(adev, USECASE_VOICE_CALL); + + pcm_dev_rx_id = platform_get_pcm_device_id(uc_info->id, PCM_PLAYBACK); + pcm_dev_tx_id = platform_get_pcm_device_id(uc_info->id, PCM_CAPTURE); + + if (pcm_dev_rx_id < 0 || pcm_dev_tx_id < 0) { + ALOGE("%s: Invalid PCM devices (rx: %d tx: %d) for the usecase(%d)", + __func__, pcm_dev_rx_id, pcm_dev_tx_id, uc_info->id); + ret = -EIO; + goto error_start_voice; + } + + ALOGV("%s: Opening PCM playback device card_id(%d) device_id(%d)", + __func__, SOUND_CARD, pcm_dev_rx_id); + adev->voice_call_rx = pcm_open(SOUND_CARD, + pcm_dev_rx_id, + PCM_OUT | PCM_MONOTONIC, &pcm_config_voice_call); + if (adev->voice_call_rx && !pcm_is_ready(adev->voice_call_rx)) { + ALOGE("%s: %s", __func__, pcm_get_error(adev->voice_call_rx)); + ret = -EIO; + goto error_start_voice; + } + + ALOGV("%s: Opening PCM capture device card_id(%d) device_id(%d)", + __func__, SOUND_CARD, pcm_dev_tx_id); + adev->voice_call_tx = pcm_open(SOUND_CARD, + pcm_dev_tx_id, + PCM_IN, &pcm_config_voice_call); + if (adev->voice_call_tx && !pcm_is_ready(adev->voice_call_tx)) { + ALOGE("%s: %s", __func__, pcm_get_error(adev->voice_call_tx)); + ret = -EIO; + goto error_start_voice; + } + + /* set cached volume */ + set_voice_volume_l(adev, adev->voice_volume); + + pcm_start(adev->voice_call_rx); + pcm_start(adev->voice_call_tx); + + ret = platform_start_voice_call(adev->platform); + if (ret < 0) { + ALOGE("%s: platform_start_voice_call error %d\n", __func__, ret); + goto error_start_voice; + } + adev->in_call = true; + return 0; + +error_start_voice: + stop_voice_call(adev); + + ALOGD("%s: exit: status(%d)", __func__, ret); + return ret; +} + static int check_input_parameters(uint32_t sample_rate, audio_format_t format, int channel_count) @@ -1225,21 +1320,18 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) if (!out->standby) select_devices(adev, out->usecase); - if ((adev->mode == AUDIO_MODE_IN_CALL) && - !voice_is_in_call(adev) && + if ((adev->mode == AUDIO_MODE_IN_CALL) && !adev->in_call && (out == adev->primary_output)) { - ret = voice_start_call(adev); - } else if ((adev->mode == AUDIO_MODE_IN_CALL) && - voice_is_in_call(adev) && - (out == adev->primary_output)) { - voice_update_devices_for_all_voice_usecases(adev); + start_voice_call(adev); + } else if ((adev->mode == AUDIO_MODE_IN_CALL) && adev->in_call && + (out == adev->primary_output)) { + select_devices(adev, USECASE_VOICE_CALL); } } - if ((adev->mode == AUDIO_MODE_NORMAL) && - voice_is_in_call(adev) && + if ((adev->mode == AUDIO_MODE_NORMAL) && adev->in_call && (out == adev->primary_output)) { - ret = voice_stop_call(adev); + stop_voice_call(adev); } pthread_mutex_unlock(&adev->lock); @@ -1702,7 +1794,7 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer, * Instead of writing zeroes here, we could trust the hardware * to always provide zeroes when muted. */ - if (ret == 0 && voice_get_mic_mute(adev) && !voice_is_in_call(adev)) + if (ret == 0 && adev->mic_mute) memset(buffer, 0, bytes); exit: @@ -1982,14 +2074,32 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) int ret; int status = 0; - ALOGD("%s: enter: %s", __func__, kvpairs); - - pthread_mutex_lock(&adev->lock); + ALOGV("%s: enter: %s", __func__, kvpairs); parms = str_parms_create_str(kvpairs); - status = voice_set_parameters(adev, parms); - if (status != 0) { - goto done; + ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_TTY_MODE, value, sizeof(value)); + if (ret >= 0) { + int tty_mode; + + if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_OFF) == 0) + tty_mode = TTY_MODE_OFF; + else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_VCO) == 0) + tty_mode = TTY_MODE_VCO; + else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_HCO) == 0) + tty_mode = TTY_MODE_HCO; + else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_FULL) == 0) + tty_mode = TTY_MODE_FULL; + else + return -EINVAL; + + pthread_mutex_lock(&adev->lock); + if (tty_mode != adev->tty_mode) { + adev->tty_mode = tty_mode; + adev->acdb_settings = (adev->acdb_settings & TTY_MODE_CLEAR) | tty_mode; + if (adev->in_call) + select_devices(adev, USECASE_VOICE_CALL); + } + pthread_mutex_unlock(&adev->lock); } ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value)); @@ -2030,6 +2140,7 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) status = -EINVAL; } if (status == 0) { + pthread_mutex_lock(&adev->lock); if (adev->speaker_lr_swap != reverse_speakers) { adev->speaker_lr_swap = reverse_speakers; // only update the selected device if there is active pcm playback @@ -2043,18 +2154,19 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) } } } + pthread_mutex_unlock(&adev->lock); } } ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_SCO_WB, value, sizeof(value)); if (ret >= 0) { + pthread_mutex_lock(&adev->lock); adev->bt_wb_speech_enabled = !strcmp(value, AUDIO_PARAMETER_VALUE_ON); + pthread_mutex_unlock(&adev->lock); } audio_extn_hfp_set_parameters(adev, parms); -done: str_parms_destroy(parms); - pthread_mutex_unlock(&adev->lock); ALOGV("%s: exit with code(%d)", __func__, status); return status; } @@ -2062,21 +2174,7 @@ done: static char* adev_get_parameters(const struct audio_hw_device *dev, const char *keys) { - struct audio_device *adev = (struct audio_device *)dev; - struct str_parms *reply = str_parms_create(); - struct str_parms *query = str_parms_create_str(keys); - char *str; - - pthread_mutex_lock(&adev->lock); - - voice_get_parameters(adev, query, reply); - str = str_parms_to_str(reply); - str_parms_destroy(query); - str_parms_destroy(reply); - - pthread_mutex_unlock(&adev->lock); - ALOGV("%s: exit: returns - %s", __func__, str); - return str; + return strdup(""); } static int adev_init_check(const struct audio_hw_device *dev __unused) @@ -2084,15 +2182,39 @@ static int adev_init_check(const struct audio_hw_device *dev __unused) return 0; } +/* always called with adev lock held */ +static int set_voice_volume_l(struct audio_device *adev, float volume) +{ + int vol, err = 0; + + if (adev->mode == AUDIO_MODE_IN_CALL) { + if (volume < 0.0) { + volume = 0.0; + } else if (volume > 1.0) { + volume = 1.0; + } + + vol = lrint(volume * 100.0); + + // Voice volume levels from android are mapped to driver volume levels as follows. + // 0 -> 5, 20 -> 4, 40 ->3, 60 -> 2, 80 -> 1, 100 -> 0 + // So adjust the volume to get the correct volume index in driver + vol = 100 - vol; + + err = platform_set_voice_volume(adev->platform, vol); + } + return err; +} + static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) { int ret; struct audio_device *adev = (struct audio_device *)dev; - pthread_mutex_lock(&adev->lock); - ret = voice_set_volume(adev, volume); + /* cache volume */ + adev->voice_volume = volume; + ret = set_voice_volume_l(adev, adev->voice_volume); pthread_mutex_unlock(&adev->lock); - return ret; } @@ -2123,7 +2245,6 @@ static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode) pthread_mutex_lock(&adev->lock); if (adev->mode != mode) { - ALOGD("%s: mode %d\n", __func__, mode); adev->mode = mode; } pthread_mutex_unlock(&adev->lock); @@ -2132,20 +2253,23 @@ static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode) static int adev_set_mic_mute(struct audio_hw_device *dev, bool state) { - int ret; struct audio_device *adev = (struct audio_device *)dev; + int err = 0; - ALOGD("%s: state %d\n", __func__, state); pthread_mutex_lock(&adev->lock); - ret = voice_set_mic_mute(adev, state); - pthread_mutex_unlock(&adev->lock); + adev->mic_mute = state; - return ret; + err = platform_set_mic_mute(adev->platform, state); + pthread_mutex_unlock(&adev->lock); + return err; } static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) { - *state = voice_get_mic_mute((struct audio_device *)dev); + struct audio_device *adev = (struct audio_device *)dev; + + *state = adev->mic_mute; + return 0; } @@ -2165,7 +2289,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev, { struct audio_device *adev = (struct audio_device *)dev; struct stream_in *in; - int ret = 0, buffer_size, frame_size; + int ret, buffer_size, frame_size; int channel_count = popcount(config->channel_mask); ALOGV("%s: enter", __func__); @@ -2175,8 +2299,6 @@ static int adev_open_input_stream(struct audio_hw_device *dev, in = (struct stream_in *)calloc(1, sizeof(struct stream_in)); - pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL); - in->stream.common.get_sample_rate = in_get_sample_rate; in->stream.common.set_sample_rate = in_set_sample_rate; in->stream.common.get_buffer_size = in_get_buffer_size; @@ -2293,7 +2415,7 @@ static int adev_verify_devices(struct audio_device *adev) size_t i; unsigned dir; - const unsigned card_id = adev->snd_card; + const unsigned card_id = SOUND_CARD; char info[512]; /* for possible debug info */ for (dir = 0; dir < 2; ++dir) { @@ -2417,8 +2539,6 @@ static int adev_open(const hw_module_t *module, const char *name, adev = calloc(1, sizeof(struct audio_device)); - pthread_mutex_init(&adev->lock, (const pthread_mutexattr_t *) NULL); - adev->device.common.tag = HARDWARE_DEVICE_TAG; adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0; adev->device.common.module = (struct hw_module_t *)module; @@ -2447,11 +2567,15 @@ static int adev_open(const hw_module_t *module, const char *name, adev->mode = AUDIO_MODE_NORMAL; adev->active_input = NULL; adev->primary_output = NULL; + adev->voice_call_rx = NULL; + adev->voice_call_tx = NULL; + adev->voice_volume = 1.0f; + adev->tty_mode = TTY_MODE_OFF; adev->bluetooth_nrec = true; + adev->in_call = false; adev->acdb_settings = TTY_MODE_OFF; /* adev->cur_hdmi_channels = 0; by calloc() */ adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int)); - voice_init(adev); list_init(&adev->usecase_list); pthread_mutex_unlock(&adev->lock); diff --git a/hal/audio_hw.h b/hal/audio_hw.h index 62bc100a..37805ab8 100644 --- a/hal/audio_hw.h +++ b/hal/audio_hw.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2014 The Android Open Source Project + * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ #include #include -#include "voice.h" #define VISUALIZER_LIBRARY_PATH "/system/lib/soundfx/libqcomvisualizer.so" @@ -66,15 +65,6 @@ typedef enum { USECASE_AUDIO_RECORD_LOW_LATENCY, USECASE_VOICE_CALL, - - /* Voice extension usecases */ - USECASE_VOICE2_CALL, - USECASE_VOLTE_CALL, - USECASE_QCHAT_CALL, - USECASE_VOWLAN_CALL, - USECASE_INCALL_REC_UPLINK, - USECASE_INCALL_REC_DOWNLINK, - USECASE_INCALL_REC_UPLINK_AND_DOWNLINK, AUDIO_USECASE_MAX } audio_usecase_t; @@ -191,18 +181,22 @@ struct audio_device { audio_mode_t mode; struct stream_in *active_input; struct stream_out *primary_output; + int in_call; + float voice_volume; + bool mic_mute; + int tty_mode; bool bluetooth_nrec; bool screen_off; + struct pcm *voice_call_rx; + struct pcm *voice_call_tx; int *snd_dev_ref_cnt; struct listnode usecase_list; struct audio_route *audio_route; int acdb_settings; bool speaker_lr_swap; - struct voice voice; unsigned int cur_hdmi_channels; bool bt_wb_speech_enabled; - int snd_card; void *platform; void *visualizer_lib; @@ -218,31 +212,19 @@ struct audio_device { struct pcm_params *use_case_table[AUDIO_USECASE_MAX]; }; -int pcm_ioctl(void *pcm, int request, ...); - int select_devices(struct audio_device *adev, audio_usecase_t uc_id); - int disable_audio_route(struct audio_device *adev, struct audio_usecase *usecase); - int disable_snd_device(struct audio_device *adev, snd_device_t snd_device); - int enable_snd_device(struct audio_device *adev, snd_device_t snd_device); - int enable_audio_route(struct audio_device *adev, struct audio_usecase *usecase); - struct audio_usecase *get_usecase_from_list(struct audio_device *adev, audio_usecase_t uc_id); -#define LITERAL_TO_STRING(x) #x -#define CHECK(condition) LOG_ALWAYS_FATAL_IF(!(condition), "%s",\ - __FILE__ ":" LITERAL_TO_STRING(__LINE__)\ - " ASSERT_FATAL(" #condition ") failed.") - /* * NOTE: when multiple mutexes have to be acquired, always take the * stream_in or stream_out mutex first, followed by the audio_device mutex. diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c index 87b18b24..ae551b97 100644 --- a/hal/msm8960/platform.c +++ b/hal/msm8960/platform.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2014 The Android Open Source Project + * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -481,7 +481,7 @@ int platform_switch_voice_call_device_post(void *platform, return ret; } -int platform_start_voice_call(void *platform, uint32_t vsid __unused) +int platform_start_voice_call(void *platform) { struct platform_data *my_data = (struct platform_data *)platform; int ret = 0; @@ -501,7 +501,7 @@ int platform_start_voice_call(void *platform, uint32_t vsid __unused) return ret; } -int platform_stop_voice_call(void *platform, uint32_t vsid __unused) +int platform_stop_voice_call(void *platform) { struct platform_data *my_data = (struct platform_data *)platform; int ret = 0; @@ -564,12 +564,6 @@ int platform_set_mic_mute(void *platform, bool state) return ret; } -int platform_set_device_mute(void *platform __unused, bool state __unused, char *dir __unused) -{ - LOGE("%s: Not implemented", __func__); - return -ENOSYS; -} - snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices) { struct platform_data *my_data = (struct platform_data *)platform; @@ -686,10 +680,10 @@ snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_d ALOGE("%s: No output device set for voice call", __func__); goto exit; } - if (adev->voice.tty_mode != TTY_MODE_OFF) { + if (adev->tty_mode != TTY_MODE_OFF) { if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE || out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) { - switch (adev->voice.tty_mode) { + switch (adev->tty_mode) { case TTY_MODE_FULL: snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC; break; @@ -700,7 +694,7 @@ snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_d snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC; break; default: - ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode); + ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->tty_mode); } goto exit; } @@ -917,31 +911,6 @@ int platform_edid_get_max_channels(void *platform) return max_channels; } -int platform_set_incall_recording_session_id(void *platform __unused, - uint32_t session_id __unused, int rec_mode __unused) -{ - LOGE("%s: Not implemented", __func__); - return -ENOSYS; -} - -int platform_stop_incall_recording_usecase(void *platform __unused) -{ - LOGE("%s: Not implemented", __func__); - return -ENOSYS; -} - -int platform_start_incall_music_usecase(void *platform __unused) -{ - LOGE("%s: Not implemented", __func__); - return -ENOSYS; -} - -int platform_stop_incall_music_usecase(void *platform __unused) -{ - LOGE("%s: Not implemented", __func__); - return -ENOSYS; -} - /* Delay in Us */ int64_t platform_render_latency(audio_usecase_t usecase) { diff --git a/hal/msm8960/platform.h b/hal/msm8960/platform.h index 4d137aa8..a2ae80f8 100644 --- a/hal/msm8960/platform.h +++ b/hal/msm8960/platform.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2014 The Android Open Source Project + * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c index ad861e23..b7acc85a 100644 --- a/hal/msm8974/platform.c +++ b/hal/msm8974/platform.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2014 The Android Open Source Project + * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,7 +54,11 @@ /* Retry for delay in FW loading*/ #define RETRY_NUMBER 10 #define RETRY_US 500000 -#define MAX_SND_CARD 8 + +#define MAX_VOL_INDEX 5 +#define MIN_VOL_INDEX 0 +#define percent_to_index(val, min, max) \ + ((val) * ((max) - (min)) * 0.01 + (min) + .5) struct audio_block_header { @@ -104,16 +108,6 @@ static const int pcm_device_table[AUDIO_USECASE_MAX][2] = { LOWLATENCY_PCM_DEVICE}, [USECASE_VOICE_CALL] = {VOICE_CALL_PCM_DEVICE, VOICE_CALL_PCM_DEVICE}, - [USECASE_VOICE2_CALL] = {VOICE2_CALL_PCM_DEVICE, VOICE2_CALL_PCM_DEVICE}, - [USECASE_VOLTE_CALL] = {VOLTE_CALL_PCM_DEVICE, VOLTE_CALL_PCM_DEVICE}, - [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE, QCHAT_CALL_PCM_DEVICE}, - [USECASE_VOWLAN_CALL] = {VOWLAN_CALL_PCM_DEVICE, VOWLAN_CALL_PCM_DEVICE}, - [USECASE_INCALL_REC_UPLINK] = {AUDIO_RECORD_PCM_DEVICE, - AUDIO_RECORD_PCM_DEVICE}, - [USECASE_INCALL_REC_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE, - AUDIO_RECORD_PCM_DEVICE}, - [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE, - AUDIO_RECORD_PCM_DEVICE}, [USECASE_AUDIO_HFP_SCO] = {HFP_PCM_RX, HFP_SCO_RX}, }; @@ -256,6 +250,24 @@ bool is_operator_tmus() return is_tmus; } +static int set_volume_values(int type, int volume, int* values) +{ + values[0] = volume; + values[1] = ALL_SESSION_VSID; + + switch(type) { + case VOLUME_SET: + values[2] = DEFAULT_VOLUME_RAMP_DURATION_MS; + break; + case MUTE_SET: + values[2] = DEFAULT_MUTE_RAMP_DURATION; + break; + default: + return -EINVAL; + } + return 0; +} + static int set_echo_reference(struct mixer *mixer, const char* ec_ref) { struct mixer_ctl *ctl; @@ -440,41 +452,28 @@ void *platform_init(struct audio_device *adev) { char value[PROPERTY_VALUE_MAX]; struct platform_data *my_data; - int retry_num = 0, snd_card_num = 0; + int retry_num = 0; const char *snd_card_name; - while (snd_card_num < MAX_SND_CARD) { - adev->mixer = mixer_open(snd_card_num); + adev->mixer = mixer_open(MIXER_CARD); - while (!adev->mixer && retry_num < RETRY_NUMBER) { - usleep(RETRY_US); - adev->mixer = mixer_open(snd_card_num); - retry_num++; - } - - if (!adev->mixer) { - ALOGE("%s: Unable to open the mixer card: %d", __func__, - snd_card_num); - retry_num = 0; - snd_card_num++; - continue; - } - - snd_card_name = mixer_get_name(adev->mixer); - ALOGD("%s: snd_card_name: %s", __func__, snd_card_name); + while (!adev->mixer && retry_num < RETRY_NUMBER) { + usleep(RETRY_US); + adev->mixer = mixer_open(MIXER_CARD); + retry_num++; + } - adev->audio_route = audio_route_init(snd_card_num, MIXER_XML_PATH); - if (!adev->audio_route) { - ALOGE("%s: Failed to init audio route controls, aborting.", __func__); - return NULL; - } - adev->snd_card = snd_card_num; - ALOGD("%s: Opened sound card:%d", __func__, snd_card_num); - break; + if (!adev->mixer) { + ALOGE("Unable to open the mixer, aborting."); + return NULL; } - if (snd_card_num >= MAX_SND_CARD) { - ALOGE("%s: Unable to find correct sound card, aborting.", __func__); + snd_card_name = mixer_get_name(adev->mixer); + ALOGD("%s: snd_card_name: %s", __func__, snd_card_name); + + adev->audio_route = audio_route_init(MIXER_CARD, MIXER_XML_PATH); + if (!adev->audio_route) { + ALOGE("%s: Failed to init audio route controls, aborting.", __func__); return NULL; } @@ -565,8 +564,6 @@ void *platform_init(struct audio_device *adev) void platform_deinit(void *platform) { - struct platform_data *my_data = (struct platform_data *)platform; - close_csd_client(my_data->csd); free(platform); } @@ -725,13 +722,13 @@ int platform_switch_voice_call_usecase_route_post(void *platform, return ret; } -int platform_start_voice_call(void *platform, uint32_t vsid) +int platform_start_voice_call(void *platform) { struct platform_data *my_data = (struct platform_data *)platform; int ret = 0; if (my_data->csd != NULL) { - ret = my_data->csd->start_voice(vsid); + ret = my_data->csd->start_voice(VOICE_VSID); if (ret < 0) { ALOGE("%s: csd_start_voice error %d\n", __func__, ret); } @@ -739,13 +736,13 @@ int platform_start_voice_call(void *platform, uint32_t vsid) return ret; } -int platform_stop_voice_call(void *platform, uint32_t vsid) +int platform_stop_voice_call(void *platform) { struct platform_data *my_data = (struct platform_data *)platform; int ret = 0; if (my_data->csd != NULL) { - ret = my_data->csd->stop_voice(vsid); + ret = my_data->csd->stop_voice(VOICE_VSID); if (ret < 0) { ALOGE("%s: csd_stop_voice error %d\n", __func__, ret); } @@ -753,36 +750,19 @@ int platform_stop_voice_call(void *platform, uint32_t vsid) return ret; } -int platform_get_sample_rate(void *platform, uint32_t *rate) -{ - struct platform_data *my_data = (struct platform_data *)platform; - int ret = 0; - - if (my_data->csd != NULL) { - ret = my_data->csd->get_sample_rate(rate); - if (ret < 0) { - ALOGE("%s: csd_get_sample_rate error %d\n", __func__, ret); - } - } - return ret; -} - int platform_set_voice_volume(void *platform, int volume) { struct platform_data *my_data = (struct platform_data *)platform; struct audio_device *adev = my_data->adev; struct mixer_ctl *ctl; const char *mixer_ctl_name = "Voice Rx Gain"; - int vol_index = 0, ret = 0; - uint32_t set_values[ ] = {0, - ALL_SESSION_VSID, - DEFAULT_VOLUME_RAMP_DURATION_MS}; + int values[VOLUME_CTL_PARAM_NUM]; + int ret = 0; // Voice volume levels are mapped to adsp volume levels as follows. // 100 -> 5, 80 -> 4, 60 -> 3, 40 -> 2, 20 -> 1 0 -> 0 // But this values don't changed in kernel. So, below change is need. - vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, MAX_VOL_INDEX); - set_values[0] = vol_index; + volume = (int)percent_to_index(volume, MIN_VOL_INDEX, MAX_VOL_INDEX); ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name); if (!ctl) { @@ -790,9 +770,16 @@ int platform_set_voice_volume(void *platform, int volume) __func__, mixer_ctl_name); return -EINVAL; } - ALOGV("Setting voice volume index: %d", set_values[0]); - mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values)); - + ret = set_volume_values(VOLUME_SET, volume, values); + if (ret < 0) { + ALOGV("%s: failed setting volume by incorrect type", __func__); + return -EINVAL; + } + ret = mixer_ctl_set_array(ctl, values, sizeof(values)/sizeof(int)); + if (ret < 0) { + ALOGV("%s: failed set mixer ctl by %d", __func__, ret); + return -EINVAL; + } if (my_data->csd != NULL) { ret = my_data->csd->volume(ALL_SESSION_VSID, volume, DEFAULT_VOLUME_RAMP_DURATION_MS); @@ -809,70 +796,30 @@ int platform_set_mic_mute(void *platform, bool state) struct audio_device *adev = my_data->adev; struct mixer_ctl *ctl; const char *mixer_ctl_name = "Voice Tx Mute"; + int values[VOLUME_CTL_PARAM_NUM]; int ret = 0; - uint32_t set_values[ ] = {0, - ALL_SESSION_VSID, - DEFAULT_MUTE_RAMP_DURATION_MS}; - - if (adev->mode != AUDIO_MODE_IN_CALL) - return 0; - - set_values[0] = state; - 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; - } - ALOGV("Setting voice mute state: %d", state); - mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values)); - if (my_data->csd != NULL) { - ret = my_data->csd->mic_mute(ALL_SESSION_VSID, state, - DEFAULT_MUTE_RAMP_DURATION_MS); + if (adev->mode == AUDIO_MODE_IN_CALL) { + 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; + } + ALOGV("Setting mic mute: %d", state); + ret = set_volume_values(MUTE_SET, state, values); if (ret < 0) { - ALOGE("%s: csd_mic_mute error %d", __func__, ret); + ALOGV("%s: failed setting mute by incorrect type", __func__); + return -EINVAL; + } + ret = mixer_ctl_set_array(ctl, values, sizeof(values)/sizeof(int)); + if (ret < 0) { + ALOGV("%s: failed set mixer ctl by %d", __func__, ret); + return -EINVAL; } - } - return ret; -} - -int platform_set_device_mute(void *platform, bool state, char *dir) -{ - struct platform_data *my_data = (struct platform_data *)platform; - struct audio_device *adev = my_data->adev; - struct mixer_ctl *ctl; - char *mixer_ctl_name = NULL; - int ret = 0; - uint32_t set_values[ ] = {0, - ALL_SESSION_VSID, - 0}; - if(dir == NULL) { - ALOGE("%s: Invalid direction:%s", __func__, dir); - return -EINVAL; - } - - if (!strncmp("rx", dir, sizeof("rx"))) { - mixer_ctl_name = "Voice Rx Device Mute"; - } else if (!strncmp("tx", dir, sizeof("tx"))) { - mixer_ctl_name = "Voice Tx Device Mute"; - } else { - return -EINVAL; - } - - set_values[0] = state; - 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; } - ALOGV("%s: Setting device mute state: %d, mixer ctrl:%s", - __func__,state, mixer_ctl_name); - mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values)); - - return ret; + return 0; } snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices) @@ -892,11 +839,11 @@ snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devi if (mode == AUDIO_MODE_IN_CALL) { if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE || devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) { - if (adev->voice.tty_mode == TTY_MODE_FULL) + if (adev->tty_mode == TTY_MODE_FULL) snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES; - else if (adev->voice.tty_mode == TTY_MODE_VCO) + else if (adev->tty_mode == TTY_MODE_VCO) snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES; - else if (adev->voice.tty_mode == TTY_MODE_HCO) + else if (adev->tty_mode == TTY_MODE_HCO) snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET; else snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES; @@ -991,10 +938,10 @@ snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_d ALOGE("%s: No output device set for voice call", __func__); goto exit; } - if (adev->voice.tty_mode != TTY_MODE_OFF) { + if (adev->tty_mode != TTY_MODE_OFF) { if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE || out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) { - switch (adev->voice.tty_mode) { + switch (adev->tty_mode) { case TTY_MODE_FULL: snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC; break; @@ -1005,7 +952,7 @@ snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_d snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC; break; default: - ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode); + ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->tty_mode); } goto exit; } @@ -1232,92 +1179,6 @@ int platform_edid_get_max_channels(void *platform) return max_channels; } -int platform_set_incall_recording_session_id(void *platform, - uint32_t session_id, int rec_mode) -{ - int ret = 0; - struct platform_data *my_data = (struct platform_data *)platform; - struct audio_device *adev = my_data->adev; - struct mixer_ctl *ctl; - const char *mixer_ctl_name = "Voc VSID"; - int num_ctl_values; - int i; - - 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); - ret = -EINVAL; - } else { - num_ctl_values = mixer_ctl_get_num_values(ctl); - for (i = 0; i < num_ctl_values; i++) { - if (mixer_ctl_set_value(ctl, i, session_id)) { - ALOGV("Error: invalid session_id: %x", session_id); - ret = -EINVAL; - break; - } - } - } - - if (my_data->csd != NULL) { - ret = my_data->csd->start_record(ALL_SESSION_VSID, rec_mode); - if (ret < 0) { - ALOGE("%s: csd_client_start_record failed, error %d", - __func__, ret); - } - } - - return ret; -} - -int platform_stop_incall_recording_usecase(void *platform) -{ - int ret = 0; - struct platform_data *my_data = (struct platform_data *)platform; - - if (my_data->csd != NULL) { - ret = my_data->csd->stop_record(ALL_SESSION_VSID); - if (ret < 0) { - ALOGE("%s: csd_client_stop_record failed, error %d", - __func__, ret); - } - } - - return ret; -} - -int platform_start_incall_music_usecase(void *platform) -{ - int ret = 0; - struct platform_data *my_data = (struct platform_data *)platform; - - if (my_data->csd != NULL) { - ret = my_data->csd->start_playback(ALL_SESSION_VSID); - if (ret < 0) { - ALOGE("%s: csd_client_start_playback failed, error %d", - __func__, ret); - } - } - - return ret; -} - -int platform_stop_incall_music_usecase(void *platform) -{ - int ret = 0; - struct platform_data *my_data = (struct platform_data *)platform; - - if (my_data->csd != NULL) { - ret = my_data->csd->stop_playback(ALL_SESSION_VSID); - if (ret < 0) { - ALOGE("%s: csd_client_stop_playback failed, error %d", - __func__, ret); - } - } - - return ret; -} - /* Delay in Us */ int64_t platform_render_latency(audio_usecase_t usecase) { diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h index 267f90f8..42bf8e5d 100644 --- a/hal/msm8974/platform.h +++ b/hal/msm8974/platform.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2014 The Android Open Source Project + * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -91,11 +91,17 @@ enum { }; +#define MIXER_CARD 0 +#define SOUND_CARD 0 + #define DEFAULT_OUTPUT_SAMPLING_RATE 48000 -#define ALL_SESSION_VSID 0xFFFFFFFF -#define DEFAULT_MUTE_RAMP_DURATION_MS 20 +#define ALL_SESSION_VSID 0xFFFFFFFF +#define DEFAULT_MUTE_RAMP_DURATION 20 #define DEFAULT_VOLUME_RAMP_DURATION_MS 20 +#define VOLUME_SET 0 +#define MUTE_SET 1 +#define VOLUME_CTL_PARAM_NUM 3 #ifdef MSM8084 #define ACDB_ID_VOICE_HANDSET_TMUS 88 @@ -104,12 +110,6 @@ enum { #define ACDB_ID_VOICE_HANDSET_TMUS 7 #define ACDB_ID_VOICE_DMIC_EF_TMUS 41 #endif - -#define MAX_VOL_INDEX 5 -#define MIN_VOL_INDEX 0 -#define percent_to_index(val, min, max) \ - ((val) * ((max) - (min)) * 0.01 + (min) + .5) - /* * tinyAlsa library interprets period size as number of frames * one frame = channel_count * sizeof (pcm sample) @@ -143,16 +143,8 @@ enum { #define VOICE_VSID 0x10C01000 #ifdef PLATFORM_MSM8084 #define VOICE_CALL_PCM_DEVICE 20 -#define VOICE2_CALL_PCM_DEVICE 25 -#define VOLTE_CALL_PCM_DEVICE 21 -#define QCHAT_CALL_PCM_DEVICE 33 -#define VOWLAN_CALL_PCM_DEVICE -1 #else #define VOICE_CALL_PCM_DEVICE 2 -#define VOICE2_CALL_PCM_DEVICE 22 -#define VOLTE_CALL_PCM_DEVICE 14 -#define QCHAT_CALL_PCM_DEVICE 20 -#define VOWLAN_CALL_PCM_DEVICE 36 #endif #define HFP_PCM_RX 5 diff --git a/hal/platform_api.h b/hal/platform_api.h index 6dd4f26a..7079e8c1 100644 --- a/hal/platform_api.h +++ b/hal/platform_api.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2014 The Android Open Source Project + * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,12 +33,10 @@ int platform_switch_voice_call_device_post(void *platform, int platform_switch_voice_call_usecase_route_post(void *platform, snd_device_t out_snd_device, snd_device_t in_snd_device); -int platform_start_voice_call(void *platform, uint32_t vsid); -int platform_stop_voice_call(void *platform, uint32_t vsid); +int platform_start_voice_call(void *platform); +int platform_stop_voice_call(void *platform); int platform_set_voice_volume(void *platform, int volume); int platform_set_mic_mute(void *platform, bool state); -int platform_get_sample_rate(void *platform, uint32_t *rate); -int platform_set_device_mute(void *platform, bool state, char *dir); snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices); snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device); int platform_set_hdmi_channels(void *platform, int channel_count); @@ -47,10 +45,4 @@ int platform_edid_get_max_channels(void *platform); /* returns the latency for a usecase in Us */ int64_t platform_render_latency(audio_usecase_t usecase); -int platform_set_incall_recording_session_id(void *platform, - uint32_t session_id, int rec_mode); -int platform_stop_incall_recording_usecase(void *platform); -int platform_start_incall_music_usecase(void *platform); -int platform_stop_incall_music_usecase(void *platform); - #endif // QCOM_AUDIO_PLATFORM_API_H diff --git a/hal/voice.c b/hal/voice.c deleted file mode 100644 index cc509af2..00000000 --- a/hal/voice.c +++ /dev/null @@ -1,451 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "voice" -/*#define LOG_NDEBUG 0*/ -#define LOG_NDDEBUG 0 - -#include -#include -#include -#include - -#include "audio_hw.h" -#include "voice.h" -#include "voice_extn/voice_extn.h" -#include "platform.h" -#include "platform_api.h" - -struct pcm_config pcm_config_voice_call = { - .channels = 1, - .rate = 8000, - .period_size = 160, - .period_count = 2, - .format = PCM_FORMAT_S16_LE, -}; - -extern const char * const use_case_table[AUDIO_USECASE_MAX]; - -static struct voice_session *voice_get_session_from_use_case(struct audio_device *adev, - audio_usecase_t usecase_id) -{ - struct voice_session *session = NULL; - int ret = 0; - - ret = voice_extn_get_session_from_use_case(adev, usecase_id, &session); - if (ret == -ENOSYS) { - session = &adev->voice.session[VOICE_SESS_IDX]; - } - - return session; -} - -int stop_call(struct audio_device *adev, audio_usecase_t usecase_id) -{ - int i, ret = 0; - struct audio_usecase *uc_info; - struct voice_session *session = NULL; - - ALOGD("%s: enter usecase:%s", __func__, use_case_table[usecase_id]); - - session = (struct voice_session *)voice_get_session_from_use_case(adev, usecase_id); - session->state.current = CALL_INACTIVE; - - ret = platform_stop_voice_call(adev->platform, session->vsid); - - /* 1. Close the PCM devices */ - if (session->pcm_rx) { - pcm_close(session->pcm_rx); - session->pcm_rx = NULL; - } - if (session->pcm_tx) { - pcm_close(session->pcm_tx); - 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); - - /* 3. Disable the rx and tx devices */ - disable_snd_device(adev, uc_info->out_snd_device); - disable_snd_device(adev, uc_info->in_snd_device); - - list_remove(&uc_info->list); - free(uc_info); - - ALOGD("%s: exit: status(%d)", __func__, ret); - return ret; -} - -int start_call(struct audio_device *adev, audio_usecase_t usecase_id) -{ - int i, ret = 0; - struct audio_usecase *uc_info; - int pcm_dev_rx_id, pcm_dev_tx_id; - uint32_t sample_rate = 8000; - struct voice_session *session = NULL; - struct pcm_config voice_config = pcm_config_voice_call; - - ALOGD("%s: enter usecase:%s", __func__, use_case_table[usecase_id]); - - session = (struct voice_session *)voice_get_session_from_use_case(adev, 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->in_snd_device = SND_DEVICE_NONE; - uc_info->out_snd_device = SND_DEVICE_NONE; - - list_add_tail(&adev->usecase_list, &uc_info->list); - - select_devices(adev, usecase_id); - - pcm_dev_rx_id = platform_get_pcm_device_id(uc_info->id, PCM_PLAYBACK); - pcm_dev_tx_id = platform_get_pcm_device_id(uc_info->id, PCM_CAPTURE); - - if (pcm_dev_rx_id < 0 || pcm_dev_tx_id < 0) { - ALOGE("%s: Invalid PCM devices (rx: %d tx: %d) for the usecase(%d)", - __func__, pcm_dev_rx_id, pcm_dev_tx_id, uc_info->id); - ret = -EIO; - goto error_start_voice; - } - ret = platform_get_sample_rate(adev->platform, &sample_rate); - if (ret < 0) { - ALOGE("platform_get_sample_rate error %d\n", ret); - } else { - voice_config.rate = sample_rate; - } - ALOGD("voice_config.rate %d\n", voice_config.rate); - - 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, - pcm_dev_rx_id, - PCM_OUT, &voice_config); - if (session->pcm_rx && !pcm_is_ready(session->pcm_rx)) { - ALOGE("%s: %s", __func__, pcm_get_error(session->pcm_rx)); - ret = -EIO; - 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); - - voice_set_volume(adev, adev->voice.volume); - - ret = platform_start_voice_call(adev->platform, session->vsid); - if (ret < 0) { - ALOGE("%s: platform_start_voice_call error %d\n", __func__, ret); - goto error_start_voice; - } - - session->state.current = CALL_ACTIVE; - return 0; - -error_start_voice: - stop_call(adev, usecase_id); - - ALOGD("%s: exit: status(%d)", __func__, ret); - return ret; -} - -bool voice_is_in_call(struct audio_device *adev) -{ - bool in_call = false; - int ret = 0; - - ret = voice_extn_is_in_call(adev, &in_call); - if (ret == -ENOSYS) { - in_call = (adev->voice.session[VOICE_SESS_IDX].state.current == CALL_ACTIVE) ? true : false; - } - - return in_call; -} - -bool voice_is_in_call_rec_stream(struct stream_in *in) -{ - bool in_call_rec = false; - int ret = 0; - - ret = voice_extn_is_in_call_rec_stream(in, &in_call_rec); - if (ret == -ENOSYS) { - in_call_rec = false; - } - - return in_call_rec; -} - -uint32_t voice_get_active_session_id(struct audio_device *adev) -{ - int ret = 0; - uint32_t session_id; - - ret = voice_extn_get_active_session_id(adev, &session_id); - if (ret == -ENOSYS) { - session_id = VOICE_VSID; - } - return session_id; -} - -int voice_check_and_set_incall_rec_usecase(struct audio_device *adev, - struct stream_in *in) -{ - int ret = 0; - uint32_t session_id; - int usecase_id; - int rec_mode = INCALL_REC_NONE; - - if (voice_is_in_call(adev)) { - switch (in->source) { - case AUDIO_SOURCE_VOICE_UPLINK: - in->usecase = USECASE_INCALL_REC_UPLINK; - rec_mode = INCALL_REC_UPLINK; - break; - case AUDIO_SOURCE_VOICE_DOWNLINK: - in->usecase = USECASE_INCALL_REC_DOWNLINK; - rec_mode = INCALL_REC_DOWNLINK; - break; - case AUDIO_SOURCE_VOICE_CALL: - in->usecase = USECASE_INCALL_REC_UPLINK_AND_DOWNLINK; - rec_mode = INCALL_REC_UPLINK_AND_DOWNLINK; - break; - default: - ALOGV("%s: Source type %d doesnt match incall recording criteria", - __func__, in->source); - return ret; - } - - session_id = voice_get_active_session_id(adev); - ret = platform_set_incall_recording_session_id(adev->platform, - session_id, rec_mode); - ALOGV("%s: Update usecase to %d",__func__, in->usecase); - } else { - ALOGV("%s: voice call not active", __func__); - } - - return ret; -} - -int voice_check_and_stop_incall_rec_usecase(struct audio_device *adev, - struct stream_in *in) -{ - int ret = 0; - - if (in->source == AUDIO_SOURCE_VOICE_UPLINK || - in->source == AUDIO_SOURCE_VOICE_DOWNLINK || - in->source == AUDIO_SOURCE_VOICE_CALL) { - ret = platform_stop_incall_recording_usecase(adev->platform); - ALOGV("%s: Stop In-call recording", __func__); - } - - return ret; -} - -int voice_check_and_set_incall_music_usecase(struct audio_device *adev, - struct stream_out *out) -{ - int ret = 0; - - ret = voice_extn_check_and_set_incall_music_usecase(adev, out); - if (ret == -ENOSYS) { - /* Incall music delivery is used only for LCH call state */ - ret = -EINVAL; - } - - return ret; -} - -int voice_set_mic_mute(struct audio_device *adev, bool state) -{ - int err = 0; - - adev->voice.mic_mute = state; - if (adev->mode == AUDIO_MODE_IN_CALL) - err = platform_set_mic_mute(adev->platform, state); - - return err; -} - -bool voice_get_mic_mute(struct audio_device *adev) -{ - return adev->voice.mic_mute; -} - -int voice_set_volume(struct audio_device *adev, float volume) -{ - int vol, err = 0; - - adev->voice.volume = volume; - if (adev->mode == AUDIO_MODE_IN_CALL) { - if (volume < 0.0) { - volume = 0.0; - } else if (volume > 1.0) { - volume = 1.0; - } - - vol = lrint(volume * 100.0); - - // Voice volume levels from android are mapped to driver volume levels as follows. - // 0 -> 5, 20 -> 4, 40 ->3, 60 -> 2, 80 -> 1, 100 -> 0 - // So adjust the volume to get the correct volume index in driver - vol = 100 - vol; - - err = platform_set_voice_volume(adev->platform, vol); - } - - return err; -} - -int voice_start_call(struct audio_device *adev) -{ - int ret = 0; - - ret = voice_extn_start_call(adev); - if (ret == -ENOSYS) { - ret = start_call(adev, USECASE_VOICE_CALL); - } - - return ret; -} - -int voice_stop_call(struct audio_device *adev) -{ - int ret = 0; - - ret = voice_extn_stop_call(adev); - if (ret == -ENOSYS) { - ret = stop_call(adev, USECASE_VOICE_CALL); - } - - return ret; -} - -void voice_get_parameters(struct audio_device *adev, - struct str_parms *query, - struct str_parms *reply) -{ - voice_extn_get_parameters(adev, query, reply); -} - -int voice_set_parameters(struct audio_device *adev, struct str_parms *parms) -{ - char *str; - char value[32]; - int val; - int ret = 0, err; - char *kv_pairs = str_parms_to_str(parms); - - ALOGV_IF(kv_pairs != NULL, "%s: enter: %s", __func__, kv_pairs); - - ret = voice_extn_set_parameters(adev, parms); - if (ret != 0) - goto done; - - err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_TTY_MODE, value, sizeof(value)); - if (err >= 0) { - int tty_mode; - str_parms_del(parms, AUDIO_PARAMETER_KEY_TTY_MODE); - if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_OFF) == 0) - tty_mode = TTY_MODE_OFF; - else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_VCO) == 0) - tty_mode = TTY_MODE_VCO; - else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_HCO) == 0) - tty_mode = TTY_MODE_HCO; - else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_FULL) == 0) - tty_mode = TTY_MODE_FULL; - else { - ret = -EINVAL; - goto done; - } - - if (tty_mode != adev->voice.tty_mode) { - adev->voice.tty_mode = tty_mode; - adev->acdb_settings = (adev->acdb_settings & TTY_MODE_CLEAR) | tty_mode; - if (voice_is_in_call(adev)) - voice_update_devices_for_all_voice_usecases(adev); - } - } - - err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_INCALLMUSIC, - value, sizeof(value)); - if (err >= 0) { - str_parms_del(parms, AUDIO_PARAMETER_KEY_INCALLMUSIC); - if (strcmp(value, AUDIO_PARAMETER_VALUE_TRUE) == 0) - platform_start_incall_music_usecase(adev->platform); - else - platform_stop_incall_music_usecase(adev->platform); - } - -done: - ALOGV("%s: exit with code(%d)", __func__, ret); - free(kv_pairs); - return ret; -} - -void voice_init(struct audio_device *adev) -{ - int i = 0; - - memset(&adev->voice, 0, sizeof(adev->voice)); - adev->voice.tty_mode = TTY_MODE_OFF; - adev->voice.volume = 1.0f; - adev->voice.mic_mute = false; - adev->voice.voice_device_set = false; - for (i = 0; i < MAX_VOICE_SESSIONS; i++) { - adev->voice.session[i].pcm_rx = NULL; - adev->voice.session[i].pcm_tx = NULL; - adev->voice.session[i].state.current = CALL_INACTIVE; - adev->voice.session[i].state.new = CALL_INACTIVE; - adev->voice.session[i].vsid = VOICE_VSID; - } - - voice_extn_init(adev); -} - -void voice_update_devices_for_all_voice_usecases(struct audio_device *adev) -{ - struct listnode *node; - struct audio_usecase *usecase; - - list_for_each(node, &adev->usecase_list) { - usecase = node_to_item(node, struct audio_usecase, list); - if (usecase->type == VOICE_CALL) { - ALOGV("%s: updating device for usecase:%s", __func__, - use_case_table[usecase->id]); - select_devices(adev, usecase->id); - } - } -} - - diff --git a/hal/voice.h b/hal/voice.h deleted file mode 100644 index ba2240c4..00000000 --- a/hal/voice.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef VOICE_H -#define VOICE_H - -#define BASE_SESS_IDX 0 -#define VOICE_SESS_IDX (BASE_SESS_IDX) - -#ifdef MULTI_VOICE_SESSION_ENABLED -#define MAX_VOICE_SESSIONS 5 -#else -#define MAX_VOICE_SESSIONS 1 -#endif - -#define BASE_CALL_STATE 1 -#define CALL_INACTIVE (BASE_CALL_STATE) -#define CALL_ACTIVE (BASE_CALL_STATE + 1) - -#define VOICE_VSID 0x10C01000 - -#define AUDIO_PARAMETER_KEY_INCALLMUSIC "incall_music_enabled" -#define AUDIO_PARAMETER_VALUE_TRUE "true" - -struct audio_device; -struct str_parms; -struct stream_in; -struct stream_out; - -struct call_state { - int current; - int new; -}; - -struct voice_session { - struct pcm *pcm_rx; - struct pcm *pcm_tx; - struct call_state state; - uint32_t vsid; -}; - -struct voice { - struct voice_session session[MAX_VOICE_SESSIONS]; - int tty_mode; - bool mic_mute; - float volume; - bool voice_device_set; -}; - -enum { - INCALL_REC_NONE = -1, - INCALL_REC_UPLINK, - INCALL_REC_DOWNLINK, - INCALL_REC_UPLINK_AND_DOWNLINK, -}; - -int voice_start_call(struct audio_device *adev); -int voice_stop_call(struct audio_device *adev); -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_in_call_rec_stream(struct stream_in *in); -int voice_set_mic_mute(struct audio_device *dev, bool state); -bool voice_get_mic_mute(struct audio_device *dev); -int voice_set_volume(struct audio_device *adev, float volume); -int voice_check_and_set_incall_rec_usecase(struct audio_device *adev, - struct stream_in *in); -int voice_check_and_set_incall_music_usecase(struct audio_device *adev, - struct stream_out *out); -int voice_check_and_stop_incall_rec_usecase(struct audio_device *adev, - struct stream_in *in); -void voice_update_devices_for_all_voice_usecases(struct audio_device *adev); -#endif //VOICE_H diff --git a/hal/voice_extn/voice_extn.c b/hal/voice_extn/voice_extn.c deleted file mode 100644 index 05c5fcbd..00000000 --- a/hal/voice_extn/voice_extn.c +++ /dev/null @@ -1,585 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "voice_extn" -/*#define LOG_NDEBUG 0*/ -#define LOG_NDDEBUG 0 - -#include -#include -#include -#include -#include -#include - -#include "audio_hw.h" -#include "voice.h" -#include "platform.h" -#include "platform_api.h" -#include "voice_extn.h" - -#define AUDIO_PARAMETER_KEY_VSID "vsid" -#define AUDIO_PARAMETER_KEY_CALL_STATE "call_state" -#define AUDIO_PARAMETER_KEY_AUDIO_MODE "audio_mode" -#define AUDIO_PARAMETER_KEY_ALL_CALL_STATES "all_call_states" -#define AUDIO_PARAMETER_KEY_DEVICE_MUTE "device_mute" -#define AUDIO_PARAMETER_KEY_DIRECTION "direction" - -#define VOICE_EXTN_PARAMETER_VALUE_MAX_LEN 256 - -#define VOICE2_VSID 0x10DC1000 -#define VOLTE_VSID 0x10C02000 -#define QCHAT_VSID 0x10803000 -#define VOWLAN_VSID 0x10002000 -#define ALL_VSID 0xFFFFFFFF - -/* Voice Session Indices */ -#define VOICE2_SESS_IDX (VOICE_SESS_IDX + 1) -#define VOLTE_SESS_IDX (VOICE_SESS_IDX + 2) -#define QCHAT_SESS_IDX (VOICE_SESS_IDX + 3) -#define VOWLAN_SESS_IDX (VOICE_SESS_IDX + 4) - -/* Call States */ -#define CALL_HOLD (BASE_CALL_STATE + 2) -#define CALL_LOCAL_HOLD (BASE_CALL_STATE + 3) - -struct pcm_config pcm_config_incall_music = { - .channels = 1, - .rate = DEFAULT_OUTPUT_SAMPLING_RATE, - .period_size = LOW_LATENCY_OUTPUT_PERIOD_SIZE, - .period_count = LOW_LATENCY_OUTPUT_PERIOD_COUNT, - .format = PCM_FORMAT_S16_LE, - .start_threshold = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4, - .stop_threshold = INT_MAX, - .avail_min = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4, -}; - -extern int start_call(struct audio_device *adev, audio_usecase_t usecase_id); -extern int stop_call(struct audio_device *adev, audio_usecase_t usecase_id); -int voice_extn_is_in_call(struct audio_device *adev, bool *in_call); - -static bool is_valid_call_state(int call_state) -{ - if (call_state < CALL_INACTIVE || call_state > CALL_LOCAL_HOLD) - return false; - else - return true; -} - -static bool is_valid_vsid(uint32_t vsid) -{ - if (vsid == VOICE_VSID || - vsid == VOICE2_VSID || - vsid == VOLTE_VSID || - vsid == QCHAT_VSID || - vsid == VOWLAN_VSID) - return true; - else - return false; -} - -static audio_usecase_t voice_extn_get_usecase_for_session_idx(const int index) -{ - audio_usecase_t usecase_id = -1; - - switch(index) { - case VOICE_SESS_IDX: - usecase_id = USECASE_VOICE_CALL; - break; - - case VOICE2_SESS_IDX: - usecase_id = USECASE_VOICE2_CALL; - break; - - case VOLTE_SESS_IDX: - usecase_id = USECASE_VOLTE_CALL; - break; - - case QCHAT_SESS_IDX: - usecase_id = USECASE_QCHAT_CALL; - break; - - case VOWLAN_SESS_IDX: - usecase_id = USECASE_VOWLAN_CALL; - break; - - default: - ALOGE("%s: Invalid voice session index\n", __func__); - } - - return usecase_id; -} - -static uint32_t get_session_id_with_state(struct audio_device *adev, - int call_state) -{ - struct voice_session *session = NULL; - int i = 0; - uint32_t session_id = 0; - - for (i = 0; i < MAX_VOICE_SESSIONS; i++) { - session = &adev->voice.session[i]; - if(session->state.current == call_state){ - session_id = session->vsid; - break; - } - } - - return session_id; -} - -static int update_calls(struct audio_device *adev) -{ - int i = 0; - audio_usecase_t usecase_id = 0; - enum voice_lch_mode lch_mode; - struct voice_session *session = NULL; - int fd = 0; - int ret = 0; - bool is_in_call = false; - - ALOGD("%s: enter:", __func__); - - for (i = 0; i < MAX_VOICE_SESSIONS; i++) { - usecase_id = voice_extn_get_usecase_for_session_idx(i); - session = &adev->voice.session[i]; - ALOGD("%s: cur_state=%d new_state=%d vsid=%x", - __func__, session->state.current, session->state.new, session->vsid); - - switch(session->state.new) - { - case CALL_ACTIVE: - switch(session->state.current) - { - case CALL_INACTIVE: - ALOGD("%s: INACTIVE -> ACTIVE vsid:%x", __func__, session->vsid); - ret = start_call(adev, usecase_id); - if(ret < 0) { - ALOGE("%s: voice_start_call() failed for usecase: %d\n", - __func__, usecase_id); - } else { - session->state.current = session->state.new; - } - break; - - case CALL_HOLD: - ALOGD("%s: HOLD -> ACTIVE vsid:%x", __func__, session->vsid); - session->state.current = session->state.new; - break; - - case CALL_LOCAL_HOLD: - ALOGD("%s: LOCAL_HOLD -> ACTIVE vsid:%x", __func__, session->vsid); - lch_mode = VOICE_LCH_STOP; - if (pcm_ioctl(session->pcm_tx, SNDRV_VOICE_IOCTL_LCH, &lch_mode) < 0) { - ALOGE("LOCAL_HOLD -> ACTIVE failed"); - } else { - session->state.current = session->state.new; - } - break; - - default: - ALOGV("%s: CALL_ACTIVE cannot be handled in state=%d vsid:%x", - __func__, session->state.current, session->vsid); - break; - } - break; - - case CALL_INACTIVE: - switch(session->state.current) - { - case CALL_ACTIVE: - case CALL_HOLD: - case CALL_LOCAL_HOLD: - ALOGD("%s: ACTIVE/HOLD/LOCAL_HOLD -> INACTIVE vsid:%x", __func__, session->vsid); - ret = stop_call(adev, usecase_id); - if(ret < 0) { - ALOGE("%s: voice_end_call() failed for usecase: %d\n", - __func__, usecase_id); - } else { - voice_extn_is_in_call(adev, &is_in_call); - if (!is_in_call) { - adev->voice.voice_device_set = false; - } - session->state.current = session->state.new; - } - break; - - default: - ALOGV("%s: CALL_INACTIVE cannot be handled in state=%d vsid:%x", - __func__, session->state.current, session->vsid); - break; - } - break; - - case CALL_HOLD: - switch(session->state.current) - { - case CALL_ACTIVE: - ALOGD("%s: CALL_ACTIVE -> HOLD vsid:%x", __func__, session->vsid); - session->state.current = session->state.new; - break; - - case CALL_LOCAL_HOLD: - ALOGD("%s: CALL_LOCAL_HOLD -> HOLD vsid:%x", __func__, session->vsid); - lch_mode = VOICE_LCH_STOP; - if (pcm_ioctl(session->pcm_tx, SNDRV_VOICE_IOCTL_LCH, &lch_mode) < 0) { - ALOGE("LOCAL_HOLD -> HOLD failed"); - } else { - session->state.current = session->state.new; - } - break; - - default: - ALOGV("%s: CALL_HOLD cannot be handled in state=%d vsid:%x", - __func__, session->state.current, session->vsid); - break; - } - break; - - case CALL_LOCAL_HOLD: - switch(session->state.current) - { - case CALL_ACTIVE: - case CALL_HOLD: - ALOGD("%s: ACTIVE/CALL_HOLD -> LOCAL_HOLD vsid:%x", __func__, - session->vsid); - lch_mode = VOICE_LCH_START; - if (pcm_ioctl(session->pcm_tx, SNDRV_VOICE_IOCTL_LCH, &lch_mode) < 0) { - ALOGE("LOCAL_HOLD -> HOLD failed"); - } else { - session->state.current = session->state.new; - } - break; - - default: - ALOGV("%s: CALL_LOCAL_HOLD cannot be handled in state=%d vsid:%x", - __func__, session->state.current, session->vsid); - break; - } - break; - - default: - break; - } //end out switch loop - } //end for loop - - return ret; -} - -static int update_call_states(struct audio_device *adev, - const uint32_t vsid, const int call_state) -{ - struct voice_session *session = NULL; - int i = 0; - bool is_in_call; - int no_of_calls_active = 0; - - for (i = 0; i < MAX_VOICE_SESSIONS; i++) { - if (vsid == adev->voice.session[i].vsid) { - session = &adev->voice.session[i]; - break; - } - } - - for (i = 0; i < MAX_VOICE_SESSIONS; i++) { - if (CALL_INACTIVE != adev->voice.session[i].state.current) - no_of_calls_active++; - } - - if (session) { - session->state.new = call_state; - voice_extn_is_in_call(adev, &is_in_call); - ALOGD("%s is_in_call:%d voice_device_set:%d, mode:%d\n", - __func__, is_in_call, adev->voice.voice_device_set, adev->mode); - /* Dont start voice call before device routing for voice usescases has - * occured, otherwise voice calls will be started unintendedly on - * speaker. - */ - if (is_in_call || adev->voice.voice_device_set) { - /* 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. - */ - update_calls(adev); - } - } else { - return -EINVAL; - } - - return 0; - -} - -int voice_extn_get_active_session_id(struct audio_device *adev, - uint32_t *session_id) -{ - *session_id = get_session_id_with_state(adev, CALL_ACTIVE); - return 0; -} - -int voice_extn_is_in_call(struct audio_device *adev, bool *in_call) -{ - struct voice_session *session = NULL; - int i = 0; - *in_call = false; - - for (i = 0; i < MAX_VOICE_SESSIONS; i++) { - session = &adev->voice.session[i]; - if(session->state.current != CALL_INACTIVE){ - *in_call = true; - break; - } - } - - return 0; -} - -int voice_extn_is_in_call_rec_stream(struct stream_in *in, bool *in_call_rec) -{ - *in_call_rec = false; - - if(in->source == AUDIO_SOURCE_VOICE_DOWNLINK || - in->source == AUDIO_SOURCE_VOICE_UPLINK || - in->source == AUDIO_SOURCE_VOICE_CALL) { - *in_call_rec = true; - } - - return 0; -} - -void voice_extn_init(struct audio_device *adev) -{ - adev->voice.session[VOICE_SESS_IDX].vsid = VOICE_VSID; - adev->voice.session[VOICE2_SESS_IDX].vsid = VOICE2_VSID; - adev->voice.session[VOLTE_SESS_IDX].vsid = VOLTE_VSID; - adev->voice.session[QCHAT_SESS_IDX].vsid = QCHAT_VSID; - adev->voice.session[VOWLAN_SESS_IDX].vsid = VOWLAN_VSID; -} - -int voice_extn_get_session_from_use_case(struct audio_device *adev, - const audio_usecase_t usecase_id, - struct voice_session **session) -{ - - switch(usecase_id) - { - case USECASE_VOICE_CALL: - *session = &adev->voice.session[VOICE_SESS_IDX]; - break; - - case USECASE_VOICE2_CALL: - *session = &adev->voice.session[VOICE2_SESS_IDX]; - break; - - case USECASE_VOLTE_CALL: - *session = &adev->voice.session[VOLTE_SESS_IDX]; - break; - - case USECASE_QCHAT_CALL: - *session = &adev->voice.session[QCHAT_SESS_IDX]; - break; - - case USECASE_VOWLAN_CALL: - *session = &adev->voice.session[VOWLAN_SESS_IDX]; - break; - - default: - ALOGE("%s: Invalid usecase_id:%d\n", __func__, usecase_id); - *session = NULL; - return -EINVAL; - } - - return 0; -} - -int voice_extn_start_call(struct audio_device *adev) -{ - /* Start voice calls on sessions whose call state has been - * udpated. - */ - ALOGV("%s: enter:", __func__); - adev->voice.voice_device_set = true; - return update_calls(adev); -} - -int voice_extn_stop_call(struct audio_device *adev) -{ - int i; - int ret = 0; - - ALOGV("%s: enter:", __func__); - - /* If BT device is enabled and voice calls are ended, telephony will call - * set_mode(AUDIO_MODE_NORMAL) which will trigger audio policy manager to - * set routing with device BT A2DP profile. Hence end all voice calls when - * set_mode(AUDIO_MODE_NORMAL) before BT A2DP profile is selected. - */ - if (adev->mode == AUDIO_MODE_NORMAL) { - ALOGD("%s: end all calls", __func__); - for (i = 0; i < MAX_VOICE_SESSIONS; i++) { - adev->voice.session[i].state.new = CALL_INACTIVE; - } - - ret = update_calls(adev); - } - - return ret; -} - -int voice_extn_set_parameters(struct audio_device *adev, - struct str_parms *parms) -{ - char *str; - int value; - int ret = 0, err; - char *kv_pairs = str_parms_to_str(parms); - char str_value[256] = {0}; - - ALOGV_IF(kv_pairs != NULL, "%s: enter: %s", __func__, kv_pairs); - - err = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_VSID, &value); - if (err >= 0) { - str_parms_del(parms, AUDIO_PARAMETER_KEY_VSID); - uint32_t vsid = value; - int call_state = -1; - err = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_CALL_STATE, &value); - if (err >= 0) { - call_state = value; - } else { - ALOGE("%s: call_state key not found", __func__); - ret = -EINVAL; - goto done; - } - - if (is_valid_vsid(vsid) && is_valid_call_state(call_state)) { - ret = update_call_states(adev, vsid, call_state); - } else { - ALOGE("%s: invalid vsid:%x or call_state:%d", - __func__, vsid, call_state); - ret = -EINVAL; - goto done; - } - } - - err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_DEVICE_MUTE, str_value, - sizeof(str_value)); - if (err >= 0) { - str_parms_del(parms, AUDIO_PARAMETER_KEY_DEVICE_MUTE); - bool mute = false; - - if (!strncmp("true", str_value, sizeof("true"))) { - mute = true; - } - - err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_DIRECTION, str_value, - sizeof(str_value)); - if (err >= 0) { - str_parms_del(parms, AUDIO_PARAMETER_KEY_DIRECTION); - } else { - ALOGE("%s: direction key not found", __func__); - ret = -EINVAL; - goto done; - } - - ret = platform_set_device_mute(adev->platform, mute, str_value); - if (ret != 0) { - ALOGE("%s: Failed to set mute err:%d", __func__, ret); - ret = -EINVAL; - goto done; - } - } - -done: - ALOGV("%s: exit with code(%d)", __func__, ret); - free(kv_pairs); - return ret; -} - -static int get_all_call_states_str(const struct audio_device *adev, - char *value) -{ - int ret = 0; - char *cur_ptr = value; - int i, len=0; - - for (i = 0; i < MAX_VOICE_SESSIONS; i++) { - snprintf(cur_ptr, VOICE_EXTN_PARAMETER_VALUE_MAX_LEN - len, - "%d:%d,",adev->voice.session[i].vsid, - adev->voice.session[i].state.current); - len = strlen(cur_ptr); - cur_ptr = cur_ptr + len; - } - ALOGV("%s:value=%s", __func__, value); - return ret; -} - -void voice_extn_get_parameters(const struct audio_device *adev, - struct str_parms *query, - struct str_parms *reply) -{ - int ret; - char value[VOICE_EXTN_PARAMETER_VALUE_MAX_LEN] = {0}; - char *str = str_parms_to_str(query); - - ALOGV_IF(str != NULL, "%s: enter %s", __func__, str); - free(str); - - ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_AUDIO_MODE, value, - sizeof(value)); - if (ret >= 0) { - str_parms_add_int(reply, AUDIO_PARAMETER_KEY_AUDIO_MODE, adev->mode); - } - - ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_ALL_CALL_STATES, - value, sizeof(value)); - if (ret >= 0) { - ret = get_all_call_states_str(adev, value); - if (ret) { - ALOGE("%s: Error fetching call states, err:%d", __func__, ret); - return; - } - str_parms_add_str(reply, AUDIO_PARAMETER_KEY_ALL_CALL_STATES, value); - } - - str = str_parms_to_str(reply); - ALOGV_IF(str != NULL, "%s: exit: returns \"%s\"", __func__, str); - free(str); -} - -#ifdef INCALL_MUSIC_ENABLED -int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev, - struct stream_out *out) -{ - uint32_t session_id = 0; - - session_id = get_session_id_with_state(adev, CALL_LOCAL_HOLD); - if (session_id == VOICE_VSID) { - out->usecase = USECASE_INCALL_MUSIC_UPLINK; - } else if (session_id == VOICE2_VSID) { - out->usecase = USECASE_INCALL_MUSIC_UPLINK2; - } else { - ALOGE("%s: Invalid session id %x", __func__, session_id); - return -EINVAL; - } - - out->config = pcm_config_incall_music; - out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_MONO; - out->channel_mask = AUDIO_CHANNEL_OUT_MONO; - - return 0; -} -#endif - diff --git a/hal/voice_extn/voice_extn.h b/hal/voice_extn/voice_extn.h deleted file mode 100644 index fcc16ec1..00000000 --- a/hal/voice_extn/voice_extn.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef VOICE_EXTN_H -#define VOICE_EXTN_H - -#ifdef MULTI_VOICE_SESSION_ENABLED -int voice_extn_start_call(struct audio_device *adev); -int voice_extn_stop_call(struct audio_device *adev); -int voice_extn_get_session_from_use_case(struct audio_device *adev, - const audio_usecase_t usecase_id, - struct voice_session **session); -void voice_extn_init(struct audio_device *adev); -int voice_extn_set_parameters(struct audio_device *adev, - struct str_parms *parms); -void voice_extn_get_parameters(const struct audio_device *adev, - struct str_parms *query, - struct str_parms *reply); -int voice_extn_is_in_call(struct audio_device *adev, bool *in_call); -int voice_extn_is_in_call_rec_stream(struct stream_in *in, bool *in_call_rec); -int voice_extn_get_active_session_id(struct audio_device *adev, - uint32_t *session_id); -#else -static int voice_extn_start_call(struct audio_device *adev __unused) -{ - return -ENOSYS; -} - -static int voice_extn_stop_call(struct audio_device *adev __unused) -{ - return -ENOSYS; -} - -static int voice_extn_get_session_from_use_case(struct audio_device *adev __unused, - const audio_usecase_t usecase_id __unused, - struct voice_session **session __unused) -{ - return -ENOSYS; -} - -static void voice_extn_init(struct audio_device *adev __unused) -{ -} - -static int voice_extn_set_parameters(struct audio_device *adev __unused, - struct str_parms *parms __unused) -{ - return -ENOSYS; -} - -static void voice_extn_get_parameters(const struct audio_device *adev __unused, - struct str_parms *query __unused, - struct str_parms *reply __unused) -{ -} - -static int voice_extn_is_in_call(struct audio_device *adev __unused, bool *in_call __unused) -{ - return -ENOSYS; -} - -static int voice_extn_is_in_call_rec_stream(struct stream_in *in __unused, bool *in_call_rec __unused) -{ - return -ENOSYS; -} - -static int voice_extn_get_active_session_id(struct audio_device *adev __unused, - uint32_t *session_id __unused) -{ - return -ENOSYS; -} - -#endif - -#ifdef INCALL_MUSIC_ENABLED -int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev, - struct stream_out *out); -#else -static int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev __unused, - struct stream_out *out __unused) -{ - return -ENOSYS; -} -#endif - -#endif //VOICE_EXTN_H -- cgit v1.2.3