audio: unify hal
Unify audio hal components
CRs-Fixed: 2380934
Change-Id: Iacafdc44d935de5f343240421a1572a0a3241bd0
diff --git a/hal/Android.mk b/hal/Android.mk
index 1ba715b..9485d6b 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -9,33 +9,54 @@
AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
-ifneq ($(filter msm8974 msm8226 msm8610 apq8084 msm8994 msm8992 msm8996 msm8998 apq8098_latv sdm845 sdm710 qcs605 msmnile $(MSMSTEPPE),$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter msm8974 msm8226 msm8084 msm8610 apq8084 msm8994 msm8992 msm8996 msm8998 apq8098_latv sdm845 sdm710 qcs605 msmnile $(MSMSTEPPE) $(TRINKET),$(TARGET_BOARD_PLATFORM)),)
# B-family platform uses msm8974 code base
AUDIO_PLATFORM = msm8974
MULTIPLE_HW_VARIANTS_ENABLED := true
+ifneq ($(filter msm8974,$(TARGET_BOARD_PLATFORM)),)
+ LOCAL_CFLAGS := -DPLATFORM_MSM8974
+ LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="2"
+endif
ifneq ($(filter msm8610,$(TARGET_BOARD_PLATFORM)),)
LOCAL_CFLAGS := -DPLATFORM_MSM8610
endif
ifneq ($(filter msm8226,$(TARGET_BOARD_PLATFORM)),)
LOCAL_CFLAGS := -DPLATFORM_MSM8x26
+ LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="2"
+endif
+ifneq ($(filter msm8084,$(TARGET_BOARD_PLATFORM)),)
+ LOCAL_CFLAGS := -DPLATFORM_MSM8084
+ LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="2"
endif
ifneq ($(filter apq8084,$(TARGET_BOARD_PLATFORM)),)
LOCAL_CFLAGS := -DPLATFORM_APQ8084
endif
ifneq ($(filter msm8994,$(TARGET_BOARD_PLATFORM)),)
LOCAL_CFLAGS := -DPLATFORM_MSM8994
+ LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4"
+ LOCAL_CFLAGS += -DKPI_OPTIMIZE_ENABLED
endif
ifneq ($(filter msm8992,$(TARGET_BOARD_PLATFORM)),)
LOCAL_CFLAGS := -DPLATFORM_MSM8994
+ LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4"
+ LOCAL_CFLAGS += -DKPI_OPTIMIZE_ENABLED
endif
ifneq ($(filter msm8996,$(TARGET_BOARD_PLATFORM)),)
LOCAL_CFLAGS := -DPLATFORM_MSM8996
+ LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4"
+ LOCAL_CFLAGS += -DKPI_OPTIMIZE_ENABLED
+ LOCAL_CFLAGS += -DINCALL_MUSIC_ENABLED
endif
ifneq ($(filter msm8998 apq8098_latv,$(TARGET_BOARD_PLATFORM)),)
LOCAL_CFLAGS := -DPLATFORM_MSM8998
+ LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4"
+ LOCAL_CFLAGS += -DINCALL_MUSIC_ENABLED
endif
ifneq ($(filter sdm845,$(TARGET_BOARD_PLATFORM)),)
LOCAL_CFLAGS := -DPLATFORM_SDM845
+ LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4"
+ LOCAL_CFLAGS += -DINCALL_MUSIC_ENABLED
+ LOCAL_CFLAGS += -DINCALL_STEREO_CAPTURE_ENABLED
endif
ifneq ($(filter sdm710,$(TARGET_BOARD_PLATFORM)),)
LOCAL_CFLAGS := -DPLATFORM_SDM710
@@ -45,6 +66,9 @@
endif
ifneq ($(filter msmnile,$(TARGET_BOARD_PLATFORM)),)
LOCAL_CFLAGS := -DPLATFORM_MSMNILE
+ LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="4"
+ LOCAL_CFLAGS += -DINCALL_MUSIC_ENABLED
+ LOCAL_CFLAGS += -DINCALL_STEREO_CAPTURE_ENABLED
endif
ifneq ($(filter $(MSMSTEPPE) ,$(TARGET_BOARD_PLATFORM)),)
LOCAL_CFLAGS := -DPLATFORM_MSMSTEPPE
@@ -55,6 +79,8 @@
AUDIO_PLATFORM = msm8916
MULTIPLE_HW_VARIANTS_ENABLED := true
LOCAL_CFLAGS := -DPLATFORM_MSM8916
+ LOCAL_CFLAGS += -DMAX_TARGET_SPECIFIC_CHANNEL_CNT="2"
+ LOCAL_CFLAGS += -DKPI_OPTIMIZE_ENABLED
ifneq ($(filter msm8909,$(TARGET_BOARD_PLATFORM)),)
LOCAL_CFLAGS := -DPLATFORM_MSM8909
endif
@@ -80,7 +106,6 @@
LOCAL_SRC_FILES += audio_extn/audio_extn.c \
audio_extn/utils.c
-LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/techpack/audio/include
LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
@@ -97,8 +122,8 @@
LOCAL_SRC_FILES += edid.c
endif
-ifeq ($(strip $(AUDIO_USE_LL_AS_PRIMARY_OUTPUT)),true)
- LOCAL_CFLAGS += -DUSE_LL_AS_PRIMARY_OUTPUT
+ifeq ($(strip $(AUDIO_USE_DEEP_AS_PRIMARY_OUTPUT)),true)
+ LOCAL_CFLAGS += -DUSE_DEEP_AS_PRIMARY_OUTPUT
endif
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_PCM_OFFLOAD)),true)
@@ -138,11 +163,15 @@
LOCAL_SRC_FILES += audio_extn/fm.c
endif
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_USB_TUNNEL_AUDIO)),true)
- LOCAL_CFLAGS += -DUSB_HEADSET_ENABLED
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_USB_TUNNEL)),true)
+ LOCAL_CFLAGS += -DUSB_TUNNEL_ENABLED
LOCAL_SRC_FILES += audio_extn/usb.c
endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_USB_SIDETONE_VOLUME)),true)
+ LOCAL_CFLAGS += -DUSB_SIDETONE_VOLUME
+endif
+
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_HFP)),true)
LOCAL_CFLAGS += -DHFP_ENABLED
LOCAL_SRC_FILES += audio_extn/hfp.c
@@ -174,12 +203,16 @@
endif
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_FORMATS)),true)
-LOCAL_CFLAGS += -DAUDIO_EXTN_FORMATS_ENABLED
+ LOCAL_CFLAGS += -DAUDIO_EXTN_FORMATS_ENABLED
endif
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_SPKR_PROTECTION)),true)
- LOCAL_CFLAGS += -DSPKR_PROT_ENABLED
- LOCAL_SRC_FILES += audio_extn/spkr_protection.c
+ LOCAL_CFLAGS += -DSPKR_PROT_ENABLED
+ LOCAL_SRC_FILES += audio_extn/spkr_protection.c
+endif
+
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_BG_CAL)),true)
+ LOCAL_CFLAGS += -DBG_CODEC_CAL
endif
ifdef MULTIPLE_HW_VARIANTS_ENABLED
@@ -281,8 +314,8 @@
LOCAL_SRC_FILES += audio_extn/source_track.c
endif
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_SPLIT_A2DP)),true)
- LOCAL_CFLAGS += -DSPLIT_A2DP_ENABLED
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_A2DP_OFFLOAD)),true)
+ LOCAL_CFLAGS += -DA2DP_OFFLOAD_ENABLED
LOCAL_SRC_FILES += audio_extn/a2dp.c
endif
@@ -313,25 +346,25 @@
endif
LOCAL_SHARED_LIBRARIES := \
- liblog \
- libcutils \
- libtinyalsa \
- libtinycompress_vendor \
- libaudioroute \
- libdl \
- libaudioutils \
- libexpat
+ liblog \
+ libcutils \
+ libtinyalsa \
+ libtinycompress_vendor \
+ libaudioroute \
+ libdl \
+ libaudioutils \
+ libexpat
LOCAL_C_INCLUDES += \
- external/tinyalsa/include \
- external/tinycompress/include \
- system/media/audio_utils/include \
- external/expat/lib \
- $(call include-path-for, audio-route) \
- $(call include-path-for, audio-effects) \
- $(LOCAL_PATH)/$(AUDIO_PLATFORM) \
- $(LOCAL_PATH)/audio_extn \
- $(LOCAL_PATH)/voice_extn
+ external/tinyalsa/include \
+ external/tinycompress/include \
+ system/media/audio_utils/include \
+ external/expat/lib \
+ $(call include-path-for, audio-route) \
+ $(call include-path-for, audio-effects) \
+ $(LOCAL_PATH)/$(AUDIO_PLATFORM) \
+ $(LOCAL_PATH)/audio_extn \
+ $(LOCAL_PATH)/voice_extn
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_LISTEN)),true)
LOCAL_CFLAGS += -DAUDIO_LISTEN_ENABLED
@@ -340,10 +373,23 @@
endif
ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
+ LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/techpack/audio/include
LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
endif
+ifeq ($(strip $(AUDIO_FEATURE_SUPPORTED_EXTERNAL_BT)),true)
+ LOCAL_CFLAGS += -DEXTERNAL_BT_SUPPORTED
+endif
+
+ifeq ($(strip $(AUDIO_FEATURE_FLICKER_SENSOR_INPUT)),true)
+ LOCAL_CFLAGS += -DFLICKER_SENSOR_INPUT
+endif
+
+ifeq ($(strip $(AUDIO_FEATURE_NO_AUDIO_OUT)),true)
+ LOCAL_CFLAGS += -DNO_AUDIO_OUT
+endif
+
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXT_HDMI)),true)
LOCAL_CFLAGS += -DAUDIO_EXTERNAL_HDMI_ENABLED
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_HDMI_PASSTHROUGH)),true)
@@ -365,6 +411,9 @@
LOCAL_CFLAGS += -DSOUND_TRIGGER_PLATFORM_NAME=$(TARGET_BOARD_PLATFORM)
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/sound_trigger
LOCAL_SRC_FILES += audio_extn/soundtrigger.c
+ifneq ($(filter msm8996,$(TARGET_BOARD_PLATFORM)),)
+ LOCAL_HEADER_LIBRARIES += sound_trigger.primary_headers
+endif
endif
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_AUXPCM_BT)),true)
@@ -456,6 +505,10 @@
LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_OWNER := qti
+
+LOCAL_PROPRIETARY_MODULE := true
+
LOCAL_VENDOR_MODULE := true
include $(BUILD_SHARED_LIBRARY)
diff --git a/hal/Makefile.am b/hal/Makefile.am
index aafc3e9..bdf1b9a 100644
--- a/hal/Makefile.am
+++ b/hal/Makefile.am
@@ -26,7 +26,7 @@
endif
if USBAUDIO
-AM_CFLAGS += -DUSB_HEADSET_ENABLED
+AM_CFLAGS += -DUSB_TUNNEL_ENABLED
c_sources += audio_extn/usb.c
endif
@@ -38,7 +38,7 @@
if SSR
AM_CFLAGS += -DSSR_ENABLED
c_sources += audio_extn/ssr.c
-AM_CFLAGS += -I ${WORKSPACE}/audio/mm-audio-noship/surround_sound_3mic/libsurround_3mic_proc/surround_rec_interface/inc/
+AM_CFLAGS += -I ${WORKSPACE}/audio/mm-audio-external-noship/surround_sound_3mic/libsurround_3mic_proc/surround_rec_interface/inc/
endif
if MULTI_VOICE_SESSIONS
@@ -93,11 +93,11 @@
c_sources += audio_extn/source_track.c
endif
-if LISTEN
-AM_CFLAGS += -DAUDIO_LISTEN_ENABLED
-AM_CFLAGS += -I ${WORKSPACE}/audio/mm-audio-noship/audio-listen
-c_sources += audio_extn/listen.c
-endif
+#if LISTEN
+#AM_CFLAGS += -DAUDIO_LISTEN_ENABLED
+#AM_CFLAGS += -I ${WORKSPACE}/audio/mm-audio-external-noship/audio-listen
+#c_sources += audio_extn/listen.c
+#endif
if SOUND_TRIGGER
AM_CFLAGS += -DSOUND_TRIGGER_ENABLED
@@ -170,8 +170,8 @@
c_sources += audio_extn/adsp_hdlr.c
endif
-if SPLIT_A2DP
-AM_CFLAGS += -DSPLIT_A2DP_ENABLED
+if A2DP_OFFLOAD
+AM_CFLAGS += -DA2DP_OFFLOAD_ENABLED
c_sources += audio_extn/a2dp.c
endif
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index f08f379..b193d67 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -26,12 +26,13 @@
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#define LOG_TAG "split_a2dp"
+#define LOG_TAG "a2dp_offload"
/*#define LOG_NDEBUG 0*/
#define LOG_NDDEBUG 0
#include <errno.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <dlfcn.h>
+#include <pthread.h>
#include "audio_hw.h"
#include "platform.h"
#include "platform_api.h"
@@ -48,7 +49,7 @@
#include <log_utils.h>
#endif
-#ifdef SPLIT_A2DP_ENABLED
+#ifdef A2DP_OFFLOAD_ENABLED
#define AUDIO_PARAMETER_A2DP_STARTED "A2dpStarted"
#define BT_IPC_SOURCE_LIB_NAME "libbthost_if.so"
#define BT_IPC_SINK_LIB_NAME "libbthost_if_sink.so"
@@ -93,6 +94,7 @@
#define MIXER_ENC_FMT_APTX "APTX"
#define MIXER_FMT_TWS_CHANNEL_MODE "TWS Channel Mode"
#define MIXER_ENC_FMT_APTXHD "APTXHD"
+#define MIXER_END_FMT_LDAC "LDAC"
#define MIXER_ENC_FMT_NONE "NONE"
#define ENCODER_LATENCY_SBC 10
#define ENCODER_LATENCY_APTX 40
@@ -101,6 +103,7 @@
//To Do: Fine Tune Encoder CELT/LDAC latency.
#define ENCODER_LATENCY_CELT 40
#define ENCODER_LATENCY_LDAC 40
+#define ENCODER_LATENCY_PCM 50
#define DEFAULT_SINK_LATENCY_SBC 140
#define DEFAULT_SINK_LATENCY_APTX 160
#define DEFAULT_SINK_LATENCY_APTX_HD 180
@@ -108,6 +111,17 @@
//To Do: Fine Tune Default CELT/LDAC Latency.
#define DEFAULT_SINK_LATENCY_CELT 180
#define DEFAULT_SINK_LATENCY_LDAC 180
+#define DEFAULT_SINK_LATENCY_PCM 140
+
+#define SYSPROP_A2DP_OFFLOAD_SUPPORTED "ro.bluetooth.a2dp_offload.supported"
+#define SYSPROP_A2DP_OFFLOAD_DISABLED "persist.bluetooth.a2dp_offload.disabled"
+#define SYSPROP_A2DP_CODEC_LATENCIES "vendor.audio.a2dp.codec.latency"
+
+// Default encoder bit width
+#define DEFAULT_ENCODER_BIT_FORMAT 16
+
+// Default encoder latency
+#define DEFAULT_ENCODER_LATENCY 200
// Slimbus Tx sample rate for ABR feedback channel
#define ABR_TX_SAMPLE_RATE "KHZ_8"
@@ -146,6 +160,7 @@
CODEC_TYPE_LDAC = AUDIO_FORMAT_LDAC, // 0x23000000UL
CODEC_TYPE_CELT = 603979776u, // 0x24000000UL
CODEC_TYPE_APTX_AD = 620756992u, // 0x25000000UL
+ CODEC_TYPE_PCM = AUDIO_FORMAT_PCM_16_BIT, // 0x1u
}codec_t;
/*
@@ -605,6 +620,7 @@
uint32_t sampling_rate;
uint32_t bitrate;
uint32_t bits_per_sample;
+ struct aac_frame_size_control_t frame_ctl;
} audio_aac_encoder_config;
#endif
@@ -667,60 +683,15 @@
/*********** END of DSP configurable structures ********************/
-/* API to identify DSP encoder captabilities */
-static void a2dp_offload_codec_cap_parser(char *value)
-{
- char *tok = NULL,*saveptr;
-
- tok = strtok_r(value, "-", &saveptr);
- while (tok != NULL) {
- if (strcmp(tok, "sbc") == 0) {
- ALOGD("%s: SBC offload supported\n",__func__);
- a2dp.is_a2dp_offload_supported = true;
- break;
- } else if (strcmp(tok, "aptx") == 0) {
- ALOGD("%s: aptx offload supported\n",__func__);
- a2dp.is_a2dp_offload_supported = true;
- break;
- } else if (strcmp(tok, "aptxtws") == 0) {
- ALOGD("%s: aptx dual mono offload supported\n",__func__);
- a2dp.is_a2dp_offload_supported = true;
- break;
- } else if (strcmp(tok, "aptxhd") == 0) {
- ALOGD("%s: aptx HD offload supported\n",__func__);
- a2dp.is_a2dp_offload_supported = true;
- break;
- } else if (strcmp(tok, "aac") == 0) {
- ALOGD("%s: aac offload supported\n",__func__);
- a2dp.is_a2dp_offload_supported = true;
- break;
- } else if (strcmp(tok, "celt") == 0) {
- ALOGD("%s: celt offload supported\n",__func__);
- a2dp.is_a2dp_offload_supported = true;
- break;
- } else if (strcmp(tok, "ldac") == 0) {
- ALOGD("%s: ldac offload supported\n",__func__);
- a2dp.is_a2dp_offload_supported = true;
- break;
- } else if( strcmp(tok, "aptxadaptive") == 0) {
- ALOGD("%s: aptx adaptive offload supported\n",__func__);
- a2dp.is_a2dp_offload_supported = true;
- }
- tok = strtok_r(NULL, "-", &saveptr);
- };
-}
-
static void update_offload_codec_capabilities()
{
- char value[PROPERTY_VALUE_MAX] = {'\0'};
- property_get("persist.vendor.bt.a2dp_offload_cap", value, "false");
- ALOGD("get_offload_codec_capabilities = %s",value);
a2dp.is_a2dp_offload_supported =
- property_get_bool("persist.vendor.bt.a2dp_offload_cap", false);
- if (strcmp(value, "false") != 0)
- a2dp_offload_codec_cap_parser(value);
- ALOGD("%s: codec cap = %s",__func__,value);
+ property_get_bool(SYSPROP_A2DP_OFFLOAD_SUPPORTED, false) &&
+ !property_get_bool(SYSPROP_A2DP_OFFLOAD_DISABLED, false);
+
+ ALOGD("%s: A2DP offload supported = %d",__func__,
+ a2dp.is_a2dp_offload_supported);
}
static int stop_abr()
@@ -852,17 +823,17 @@
a2dp.audio_source_open = (audio_source_open_t)
dlsym(a2dp.bt_lib_source_handle, "audio_stream_open");
a2dp.audio_source_start = (audio_source_start_t)
- dlsym(a2dp.bt_lib_source_handle, "audio_start_stream");
+ dlsym(a2dp.bt_lib_source_handle, "audio_stream_start");
a2dp.audio_get_enc_config = (audio_get_enc_config_t)
dlsym(a2dp.bt_lib_source_handle, "audio_get_codec_config");
a2dp.audio_source_suspend = (audio_source_suspend_t)
- dlsym(a2dp.bt_lib_source_handle, "audio_suspend_stream");
+ dlsym(a2dp.bt_lib_source_handle, "audio_stream_suspend");
a2dp.audio_source_handoff_triggered = (audio_source_handoff_triggered_t)
dlsym(a2dp.bt_lib_source_handle, "audio_handoff_triggered");
a2dp.clear_source_a2dpsuspend_flag = (clear_source_a2dpsuspend_flag_t)
dlsym(a2dp.bt_lib_source_handle, "clear_a2dpsuspend_flag");
a2dp.audio_source_stop = (audio_source_stop_t)
- dlsym(a2dp.bt_lib_source_handle, "audio_stop_stream");
+ dlsym(a2dp.bt_lib_source_handle, "audio_stream_stop");
a2dp.audio_source_close = (audio_source_close_t)
dlsym(a2dp.bt_lib_source_handle, "audio_stream_close");
a2dp.audio_source_check_a2dp_ready = (audio_source_check_a2dp_ready_t)
@@ -1026,6 +997,11 @@
sampling_rate = sampling_rate *2;
}
+ // No need to configure backend for PCM format.
+ if (a2dp.bt_encoder_format == CODEC_TYPE_PCM) {
+ return 0;
+ }
+
//Configure backend sampling rate
switch (sampling_rate) {
case 44100:
@@ -2168,6 +2144,11 @@
configure_a2dp_source_decoder_format(MEDIA_FMT_APTX_AD));
break;
#endif
+ case CODEC_TYPE_PCM:
+ ALOGD("Received PCM format for BT device");
+ a2dp.bt_encoder_format = CODEC_TYPE_PCM;
+ is_configured = true;
+ break;
default:
ALOGD(" Received Unsupported encoder formar");
is_configured = false;
@@ -2318,7 +2299,7 @@
{
int ret =0;
- struct mixer_ctl *ctl_enc_config, *ctrl_bit_format, *ctl_channel_mode;
+ struct mixer_ctl *ctl_enc_config, *ctl_channel_mode;
struct sbc_enc_cfg_t dummy_reset_config;
char* channel_mode;
@@ -2332,16 +2313,9 @@
sizeof(struct sbc_enc_cfg_t));
a2dp.bt_encoder_format = MEDIA_FMT_NONE;
}
- ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
- MIXER_ENC_BIT_FORMAT);
- if (!ctrl_bit_format) {
- ALOGE(" ERROR bit format CONFIG data mixer control not identified");
- } else {
- ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
- if (ret != 0) {
- ALOGE("%s: Failed to set bit format to encoder", __func__);
- }
- }
+
+ a2dp_set_bit_format(DEFAULT_ENCODER_BIT_FORMAT);
+
ctl_channel_mode = mixer_get_ctl_by_name(a2dp.adev->mixer,MIXER_FMT_TWS_CHANNEL_MODE);
if (!ctl_channel_mode) {
@@ -2420,6 +2394,8 @@
if (a2dp.a2dp_source_total_active_session_requests > 0)
a2dp.a2dp_source_total_active_session_requests--;
+ else
+ ALOGE("%s: No active playback session requests on A2DP", __func__);
if ( a2dp.a2dp_source_started && !a2dp.a2dp_source_total_active_session_requests) {
ALOGV("calling BT module stream stop");
@@ -2474,16 +2450,17 @@
return 0;
}
-void audio_extn_a2dp_set_parameters(struct str_parms *parms)
+int audio_extn_a2dp_set_parameters(struct str_parms *parms, bool *reconfig)
{
- int ret, val;
+ int ret = 0, val, status = 0;
char value[32]={0};
struct audio_usecase *uc_info;
struct listnode *node;
if(a2dp.is_a2dp_offload_supported == false) {
- ALOGV("no supported codecs identified,ignoring a2dp setparam");
- return;
+ ALOGV("no supported encoders identified,ignoring a2dp setparam");
+ status = -EINVAL;
+ goto param_handled;
}
ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value,
@@ -2532,6 +2509,10 @@
if (ret >= 0) {
if (a2dp.bt_lib_source_handle) {
if ((!strncmp(value,"true",sizeof(value)))) {
+ if (a2dp.a2dp_source_suspended) {
+ ALOGD("%s: A2DP is already suspended", __func__);
+ goto param_handled;
+ }
ALOGD("Setting a2dp to suspend state");
a2dp.a2dp_source_suspended = true;
if (a2dp.bt_state_source == A2DP_STATE_DISCONNECTED)
@@ -2590,8 +2571,20 @@
}
goto param_handled;
}
+
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_RECONFIG_A2DP, value,
+ sizeof(value));
+ if (ret >= 0) {
+ if (a2dp.is_a2dp_offload_supported &&
+ a2dp.bt_state_source != A2DP_STATE_DISCONNECTED) {
+ *reconfig = true;
+ }
+ goto param_handled;
+ }
+
param_handled:
ALOGV("end of a2dp setparam");
+ return status;
}
void audio_extn_a2dp_set_handoff_mode(bool is_on)
@@ -2688,7 +2681,7 @@
char value[PROPERTY_VALUE_MAX];
memset(value, '\0', sizeof(char)*PROPERTY_VALUE_MAX);
- avsync_runtime_prop = property_get("vendor.audio.a2dp.codec.latency", value, NULL);
+ avsync_runtime_prop = property_get(SYSPROP_A2DP_CODEC_LATENCIES, value, NULL);
if (avsync_runtime_prop > 0) {
if (sscanf(value, "%d/%d/%d/%d/%d%d",
&sbc_offset, &aptx_offset, &aptxhd_offset, &aac_offset, &celt_offset, &ldac_offset) != 6) {
@@ -2730,10 +2723,31 @@
case CODEC_TYPE_APTX_AD: // for aptx adaptive the latency depends on the mode (HQ/LL) and
latency = slatency; // BT IPC will take care of accomodating the mode factor and return latency
break;
+ case CODEC_TYPE_PCM:
+ latency = ENCODER_LATENCY_PCM;
+ latency += DEFAULT_SINK_LATENCY_PCM;
+ break;
default:
latency = 200;
break;
}
return latency;
}
-#endif // SPLIT_A2DP_ENABLED
+
+int audio_extn_a2dp_get_parameters(struct str_parms *query,
+ struct str_parms *reply)
+{
+ int ret, val = 0;
+ char value[32]={0};
+
+ ret = str_parms_get_str(query, AUDIO_PARAMETER_A2DP_RECONFIG_SUPPORTED,
+ value, sizeof(value));
+ if (ret >= 0) {
+ val = a2dp.is_a2dp_offload_supported;
+ str_parms_add_int(reply, AUDIO_PARAMETER_A2DP_RECONFIG_SUPPORTED, val);
+ ALOGV("%s: called ... isReconfigA2dpSupported %d", __func__, val);
+ }
+
+ return 0;
+}
+#endif // A2DP_OFFLOAD_ENABLED
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 2d2853d..2d18d96 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -44,7 +44,7 @@
#include <dlfcn.h>
#include <fcntl.h>
#include <cutils/properties.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <unistd.h>
#include "audio_hw.h"
@@ -67,6 +67,63 @@
#define MAX_NUM_CHANNELS 8
#define Q14_GAIN_UNITY 0x4000
+struct snd_card_split cur_snd_card_split = {
+ .device = {0},
+ .snd_card = {0},
+ .form_factor = {0},
+};
+
+struct snd_card_split *audio_extn_get_snd_card_split()
+{
+ return &cur_snd_card_split;
+}
+
+void audio_extn_set_snd_card_split(const char* in_snd_card_name)
+{
+ /* sound card name follows below mentioned convention
+ <target name>-<sound card name>-<form factor>-snd-card
+ parse target name, sound card name and form factor
+ */
+ char *snd_card_name = strdup(in_snd_card_name);
+ char *tmp = NULL;
+ char *device = NULL;
+ char *snd_card = NULL;
+ char *form_factor = NULL;
+
+ if (in_snd_card_name == NULL) {
+ ALOGE("%s: snd_card_name passed is NULL", __func__);
+ goto on_error;
+ }
+
+ device = strtok_r(snd_card_name, "-", &tmp);
+ if (device == NULL) {
+ ALOGE("%s: called on invalid snd card name", __func__);
+ goto on_error;
+ }
+ strlcpy(cur_snd_card_split.device, device, HW_INFO_ARRAY_MAX_SIZE);
+
+ snd_card = strtok_r(NULL, "-", &tmp);
+ if (snd_card == NULL) {
+ ALOGE("%s: called on invalid snd card name", __func__);
+ goto on_error;
+ }
+ strlcpy(cur_snd_card_split.snd_card, snd_card, HW_INFO_ARRAY_MAX_SIZE);
+
+ form_factor = strtok_r(NULL, "-", &tmp);
+ if (form_factor == NULL) {
+ ALOGE("%s: called on invalid snd card name", __func__);
+ goto on_error;
+ }
+ strlcpy(cur_snd_card_split.form_factor, form_factor, HW_INFO_ARRAY_MAX_SIZE);
+
+ ALOGI("%s: snd_card_name(%s) device(%s) snd_card(%s) form_factor(%s)",
+ __func__, in_snd_card_name, device, snd_card, form_factor);
+
+on_error:
+ if (snd_card_name)
+ free(snd_card_name);
+}
+
struct audio_extn_module {
bool anc_enabled;
bool aanc_enabled;
@@ -928,6 +985,8 @@
void audio_extn_set_parameters(struct audio_device *adev,
struct str_parms *parms)
{
+ bool a2dp_reconfig = false;
+
audio_extn_set_aanc_noise_level(adev, parms);
audio_extn_set_anc_parameters(adev, parms);
audio_extn_set_fluence_parameters(adev, parms);
@@ -938,7 +997,7 @@
audio_extn_ssr_set_parameters(adev, parms);
audio_extn_hfp_set_parameters(adev, parms);
audio_extn_dts_eagle_set_parameters(adev, parms);
- audio_extn_a2dp_set_parameters(parms);
+ audio_extn_a2dp_set_parameters(parms, &a2dp_reconfig);
audio_extn_ddp_set_parameters(adev, parms);
audio_extn_ds2_set_parameters(adev, parms);
audio_extn_customstereo_set_parameters(adev, parms);
@@ -1638,4 +1697,22 @@
return 0;
}
-
+// TODO: remove after ext spkr file added
+void *audio_extn_extspk_init(struct audio_device *adev __unused)
+{
+ return NULL;
+}
+void audio_extn_extspk_deinit(void *extn __unused)
+{
+}
+void audio_extn_extspk_update(void* extn __unused)
+{
+}
+void audio_extn_extspk_set_mode(void* extn __unused,
+ audio_mode_t mode __unused)
+{
+}
+void audio_extn_extspk_set_voice_vol(void* extn __unused,
+ float vol __unused)
+{
+}
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index ce04d85..92cd4a3 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -159,6 +159,33 @@
struct str_parms *query,
struct str_parms *reply);
+// TODO: remove once maxx audio file is added
+#ifndef MAXXAUDIO_QDSP_ENABLED
+#define audio_extn_ma_init(platform) (0)
+#define audio_extn_ma_deinit() (0)
+#define audio_extn_ma_set_device(usecase) (0)
+#define audio_extn_ma_set_parameters(adev, param) (0)
+#define audio_extn_ma_supported_usb() (false)
+#else
+void audio_extn_ma_init(void *platform __unused)
+{
+}
+void audio_extn_ma_deinit()
+{
+}
+void audio_extn_ma_set_device(struct audio_usecase *usecase __unused)
+{
+}
+void audio_extn_ma_set_parameters(struct audio_device *adev __unused,
+ struct str_parms *parms __unused)
+{
+}
+bool audio_extn_ma_supported_usb()
+{
+ return false;
+}
+#endif
+
#ifndef ANC_HEADSET_ENABLED
#define audio_extn_get_anc_enabled() (0)
#define audio_extn_should_use_fb_anc() (0)
@@ -222,7 +249,7 @@
#endif
-#ifndef USB_HEADSET_ENABLED
+#ifndef USB_TUNNEL_ENABLED
#define audio_extn_usb_init(adev) (0)
#define audio_extn_usb_deinit() (0)
#define audio_extn_usb_add_device(device, card) (0)
@@ -239,6 +266,7 @@
#define audio_extn_usb_alive(adev) (false)
#define audio_extn_usb_connected(parms) (0)
#undef USB_BURST_MODE_ENABLED
+#undef USB_SIDETONE_VOLUME
#else
void audio_extn_usb_init(void *adev);
void audio_extn_usb_deinit();
@@ -249,12 +277,12 @@
unsigned int *ch,
bool is_playback);
int audio_extn_usb_enable_sidetone(int device, bool enable);
-int audio_extn_usb_set_sidetone_gain(struct str_parms *parms,
+void audio_extn_usb_set_sidetone_gain(struct str_parms *parms,
char *value, int len);
bool audio_extn_usb_is_capture_supported();
int audio_extn_usb_get_max_channels(bool playback);
int audio_extn_usb_get_max_bit_width(bool playback);
-int audio_extn_usb_get_sup_sample_rates(int type, uint32_t *sr, uint32_t l);
+int audio_extn_usb_get_sup_sample_rates(bool type, uint32_t *sr, uint32_t l);
bool audio_extn_usb_is_tunnel_supported();
bool audio_extn_usb_alive(int card);
bool audio_extn_usb_connected(struct str_parms *parms);
@@ -286,11 +314,22 @@
void audio_extn_usb_set_reconfig(bool is_required);
#endif
-#ifndef SPLIT_A2DP_ENABLED
+#ifndef USB_SIDETONE_VOLUME
+#define audio_extn_usb_get_sidetone_volume(card_info) (0)
+#define audio_extn_usb_set_sidetone_volume(card_info, en, i) (0)
+#else
+void audio_extn_usb_get_sidetone_volume(struct usb_card_config *usb_card_info);
+void audio_extn_usb_set_sidetone_volume(struct usb_card_config *usb_card_info,
+ bool enable,
+ int index);
+#endif
+
+#ifndef A2DP_OFFLOAD_ENABLED
#define audio_extn_a2dp_init(adev) (0)
#define audio_extn_a2dp_start_playback() (0)
#define audio_extn_a2dp_stop_playback() (0)
-#define audio_extn_a2dp_set_parameters(parms) (0)
+#define audio_extn_a2dp_set_parameters(parms, reconfig) (0)
+#define audio_extn_a2dp_get_parameters(query, reply) (0)
#define audio_extn_a2dp_is_force_device_switch() (0)
#define audio_extn_a2dp_set_handoff_mode(is_on) (0)
#define audio_extn_a2dp_get_enc_sample_rate(sample_rate) (0)
@@ -305,7 +344,9 @@
void audio_extn_a2dp_init(void *adev);
int audio_extn_a2dp_start_playback();
int audio_extn_a2dp_stop_playback();
-void audio_extn_a2dp_set_parameters(struct str_parms *parms);
+int audio_extn_a2dp_set_parameters(struct str_parms *parms, bool *reconfig);
+int audio_extn_a2dp_get_parameters(struct str_parms *query,
+ struct str_parms *reply);
bool audio_extn_a2dp_is_force_device_switch();
void audio_extn_a2dp_set_handoff_mode(bool is_on);
void audio_extn_a2dp_get_enc_sample_rate(int *sample_rate);
@@ -435,6 +476,23 @@
#endif
#ifndef AUXPCM_BT_ENABLED
+
+#define HW_INFO_ARRAY_MAX_SIZE 32
+
+struct snd_card_split {
+ char device[HW_INFO_ARRAY_MAX_SIZE];
+ char snd_card[HW_INFO_ARRAY_MAX_SIZE];
+ char form_factor[HW_INFO_ARRAY_MAX_SIZE];
+};
+
+struct snd_card_split *audio_extn_get_snd_card_split();
+void audio_extn_set_snd_card_split(const char* in_snd_card_name);
+void *audio_extn_extspk_init(struct audio_device *adev);
+void audio_extn_extspk_deinit(void *extn);
+void audio_extn_extspk_update(void* extn);
+void audio_extn_extspk_set_mode(void* extn, audio_mode_t mode);
+void audio_extn_extspk_set_voice_vol(void* extn, float vol);
+
#define audio_extn_read_xml(adev, mixer_card, MIXER_XML_PATH, \
MIXER_XML_PATH_AUXPCM) (-ENOSYS)
#else
@@ -452,6 +510,7 @@
#define audio_extn_spkr_prot_set_parameters(parms, value, len) (0)
#define audio_extn_fbsp_set_parameters(parms) (0)
#define audio_extn_fbsp_get_parameters(query, reply) (0)
+#define audio_extn_get_spkr_prot_snd_device(snd_device) (snd_device)
#else
void audio_extn_spkr_prot_init(void *adev);
int audio_extn_spkr_prot_deinit();
@@ -464,6 +523,7 @@
int audio_extn_fbsp_set_parameters(struct str_parms *parms);
int audio_extn_fbsp_get_parameters(struct str_parms *query,
struct str_parms *reply);
+int audio_extn_get_spkr_prot_snd_device(snd_device_t snd_device);
#endif
#ifndef COMPRESS_CAPTURE_ENABLED
@@ -620,12 +680,32 @@
#define audio_extn_hfp_get_usecase() (-1)
#define hfp_set_mic_mute(dev, state) (0)
#define audio_extn_hfp_set_parameters(adev, parms) (0)
+#define audio_extn_hfp_set_mic_mute(adev, state) (0)
#else
bool audio_extn_hfp_is_active(struct audio_device *adev);
audio_usecase_t audio_extn_hfp_get_usecase();
int hfp_set_mic_mute(struct audio_device *dev, bool state);
void audio_extn_hfp_set_parameters(struct audio_device *adev,
struct str_parms *parms);
+int audio_extn_hfp_set_mic_mute(struct audio_device *adev, bool state);
+#endif
+
+#ifndef DSM_FEEDBACK_ENABLED
+#define audio_extn_dsm_feedback_enable(adev, snd_device, benable) (0)
+#else
+void audio_extn_dsm_feedback_enable(struct audio_device *adev,
+ snd_device_t snd_device,
+ bool benable);
+#endif
+
+int audio_extn_utils_send_app_type_gain(struct audio_device *adev,
+ int app_type,
+ int *gain);
+
+#ifndef HWDEP_CAL_ENABLED
+#define audio_extn_hwdep_cal_send(snd_card, acdb_handle) (0)
+#else
+void audio_extn_hwdep_cal_send(int snd_card, void *acdb_handle);
#endif
#ifndef DEV_ARBI_ENABLED
@@ -687,6 +767,9 @@
void audio_extn_utils_update_stream_app_type_cfg_for_usecase(
struct audio_device *adev,
struct audio_usecase *usecase);
+bool audio_extn_utils_resolve_config_file(char[]);
+int audio_extn_utils_get_platform_info(const char* snd_card_name,
+ char* platform_info_file);
int audio_extn_utils_get_snd_card_num();
int audio_extn_utils_open_snd_mixer(struct mixer **mixer_handle);
void audio_extn_utils_close_snd_mixer(struct mixer *mixer);
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index 89c42c8..3eb96d6 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -31,7 +31,7 @@
#include <errno.h>
#include <math.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include "audio_hw.h"
#include "platform.h"
@@ -52,9 +52,13 @@
#define AUDIO_PARAMETER_KEY_HFP_VOLUME "hfp_volume"
#define AUDIO_PARAMETER_HFP_PCM_DEV_ID "hfp_pcm_dev_id"
+#define AUDIO_PARAMETER_KEY_HFP_MIC_VOLUME "hfp_mic_volume"
+#define PLAYBACK_VOLUME_MAX 0x2000
+#define CAPTURE_VOLUME_DEFAULT (15.0)
+
#ifdef PLATFORM_MSM8994
#define HFP_RX_VOLUME "SEC AUXPCM LOOPBACK Volume"
-#elif defined PLATFORM_MSM8996
+#elif defined (PLATFORM_MSM8996) || defined (EXTERNAL_BT_SUPPORTED)
#define HFP_RX_VOLUME "PRI AUXPCM LOOPBACK Volume"
#elif defined PLATFORM_AUTO
#define HFP_RX_VOLUME "Playback 36 Volume"
@@ -78,6 +82,8 @@
float hfp_volume;
int32_t hfp_pcm_dev_id;
audio_usecase_t ucid;
+ float mic_volume;
+ bool mic_mute;
};
static struct hfp_module hfpmod = {
@@ -89,7 +95,10 @@
.hfp_volume = 0,
.hfp_pcm_dev_id = HFP_ASM_RX_TX,
.ucid = USECASE_AUDIO_HFP_SCO,
+ .mic_volume = CAPTURE_VOLUME_DEFAULT,
+ .mic_mute = 0,
};
+
static struct pcm_config pcm_config_hfp = {
.channels = 1,
.rate = 8000,
@@ -111,6 +120,7 @@
ALOGD("%s: (%f)\n", __func__, value);
hfpmod.hfp_volume = value;
+
if (value < 0.0) {
ALOGW("%s: (%f) Under 0.0, assuming 0.0\n", __func__, value);
value = 0.0;
@@ -141,6 +151,114 @@
return ret;
}
+/*Set mic volume to value.
+*
+* This interface is used for mic volume control, set mic volume as value(range 0 ~ 15).
+*/
+static int hfp_set_mic_volume(struct audio_device *adev, float value)
+{
+ int volume, ret = 0;
+ char mixer_ctl_name[128];
+ struct mixer_ctl *ctl;
+ int pcm_device_id = HFP_ASM_RX_TX;
+
+ if (!hfpmod.is_hfp_running) {
+ ALOGE("%s: HFP not active, ignoring set_hfp_mic_volume call", __func__);
+ return -EIO;
+ }
+
+ if (value < 0.0) {
+ ALOGW("%s: (%f) Under 0.0, assuming 0.0\n", __func__, value);
+ value = 0.0;
+ } else if (value > CAPTURE_VOLUME_DEFAULT) {
+ value = CAPTURE_VOLUME_DEFAULT;
+ ALOGW("%s: Volume brought within range (%f)\n", __func__, value);
+ }
+
+ value = value / CAPTURE_VOLUME_DEFAULT;
+ memset(mixer_ctl_name, 0, sizeof(mixer_ctl_name));
+ snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+ "Playback %d Volume", pcm_device_id);
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s",
+ __func__, mixer_ctl_name);
+ return -EINVAL;
+ }
+ volume = (int)(value * PLAYBACK_VOLUME_MAX);
+
+ ALOGD("%s: Setting volume to %d (%s)\n", __func__, volume, mixer_ctl_name);
+ if (mixer_ctl_set_value(ctl, 0, volume) < 0) {
+ ALOGE("%s: Couldn't set HFP Volume: [%d]", __func__, volume);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static float hfp_get_mic_volume(struct audio_device *adev)
+{
+ int volume;
+ char mixer_ctl_name[128];
+ struct mixer_ctl *ctl;
+ int pcm_device_id = HFP_ASM_RX_TX;
+ float value = 0.0;
+
+ if (!hfpmod.is_hfp_running) {
+ ALOGE("%s: HFP not active, ignoring set_hfp_mic_volume call", __func__);
+ return -EIO;
+ }
+
+ memset(mixer_ctl_name, 0, sizeof(mixer_ctl_name));
+ snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+ "Playback %d Volume", pcm_device_id);
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s",
+ __func__, mixer_ctl_name);
+ return -EINVAL;
+ }
+
+ volume = mixer_ctl_get_value(ctl, 0);
+ if ( volume < 0) {
+ ALOGE("%s: Couldn't set HFP Volume: [%d]", __func__, volume);
+ return -EINVAL;
+ }
+ ALOGD("%s: getting mic volume %d \n", __func__, volume);
+
+ value = (volume / PLAYBACK_VOLUME_MAX) * CAPTURE_VOLUME_DEFAULT;
+ if (value < 0.0) {
+ ALOGW("%s: (%f) Under 0.0, assuming 0.0\n", __func__, value);
+ value = 0.0;
+ } else if (value > CAPTURE_VOLUME_DEFAULT) {
+ value = CAPTURE_VOLUME_DEFAULT;
+ ALOGW("%s: Volume brought within range (%f)\n", __func__, value);
+ }
+
+ return value;
+}
+
+/*Set mic mute state.
+*
+* This interface is used for mic mute state control
+*/
+int audio_extn_hfp_set_mic_mute(struct audio_device *adev, bool state)
+{
+ int rc = 0;
+
+ if (state == hfpmod.mic_mute)
+ return rc;
+
+ if (state == true) {
+ hfpmod.mic_volume = hfp_get_mic_volume(adev);
+ }
+ rc = hfp_set_mic_volume(adev, (state == true) ? 0.0 : hfpmod.mic_volume);
+ adev->voice.mic_mute = state;
+ hfpmod.mic_mute = state;
+ ALOGD("%s: Setting mute state %d, rc %d\n", __func__, state, rc);
+ return rc;
+}
+
static int32_t start_hfp(struct audio_device *adev,
struct str_parms *parms __unused)
{
@@ -150,6 +268,13 @@
ALOGD("%s: enter", __func__);
+ if (adev->enable_hfp == true) {
+ ALOGD("%s: HFP is already active!\n", __func__);
+ return 0;
+ }
+ adev->enable_hfp = true;
+ platform_set_mic_mute(adev->platform, false);
+
uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
if (!uc_info)
@@ -197,8 +322,8 @@
}
hfpmod.hfp_pcm_rx = pcm_open(adev->snd_card,
- pcm_dev_rx_id,
- PCM_OUT, &pcm_config_hfp);
+ pcm_dev_rx_id,
+ PCM_OUT, &pcm_config_hfp);
if (hfpmod.hfp_pcm_rx && !pcm_is_ready(hfpmod.hfp_pcm_rx)) {
ALOGE("%s: %s", __func__, pcm_get_error(hfpmod.hfp_pcm_rx));
ret = -EIO;
@@ -215,8 +340,8 @@
}
hfpmod.hfp_pcm_tx = pcm_open(adev->snd_card,
- pcm_dev_tx_id,
- PCM_IN, &pcm_config_hfp);
+ pcm_dev_tx_id,
+ PCM_IN, &pcm_config_hfp);
if (hfpmod.hfp_pcm_tx && !pcm_is_ready(hfpmod.hfp_pcm_tx)) {
ALOGE("%s: %s", __func__, pcm_get_error(hfpmod.hfp_pcm_tx));
ret = -EIO;
@@ -233,6 +358,7 @@
ret = -EINVAL;
goto exit;
}
+
if (pcm_start(hfpmod.hfp_pcm_rx) < 0) {
ALOGE("%s: pcm start for hfp pcm rx failed", __func__);
ret = -EINVAL;
@@ -247,6 +373,10 @@
hfpmod.is_hfp_running = true;
hfp_set_volume(adev, hfpmod.hfp_volume);
+ /* Set mic volume by mute status, we don't provide set mic volume in phone app, only
+ provide mute and unmute. */
+ audio_extn_hfp_set_mic_mute(adev, adev->mic_muted);
+
ALOGD("%s: exit: status(%d)", __func__, ret);
return 0;
@@ -305,6 +435,13 @@
disable_snd_device(adev, uc_info->out_snd_device);
disable_snd_device(adev, uc_info->in_snd_device);
+ /* Set the unmute Tx mixer control */
+ if (voice_get_mic_mute(adev)) {
+ platform_set_mic_mute(adev->platform, false);
+ ALOGD("%s: unMute HFP Tx", __func__);
+ }
+ adev->enable_hfp = false;
+
list_remove(&uc_info->list);
free(uc_info);
@@ -413,6 +550,19 @@
str_parms_del(parms, AUDIO_PARAMETER_HFP_PCM_DEV_ID);
}
+ memset(value, 0, sizeof(value));
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HFP_MIC_VOLUME,
+ value, sizeof(value));
+ if (ret >= 0) {
+ if (sscanf(value, "%f", &vol) != 1){
+ ALOGE("%s: error in retrieving hfp mic volume", __func__);
+ ret = -EIO;
+ goto exit;
+ }
+ ALOGD("%s: set_hfp_mic_volume usecase, Vol: [%f]", __func__, vol);
+ hfp_set_mic_volume(adev, vol);
+ }
+
exit:
ALOGV("%s Exit",__func__);
}
diff --git a/hal/audio_extn/qaf.c b/hal/audio_extn/qaf.c
index ced137f..4ec524e 100644
--- a/hal/audio_extn/qaf.c
+++ b/hal/audio_extn/qaf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -104,7 +104,7 @@
#include <sys/prctl.h>
#include <cutils/properties.h>
#include <cutils/str_parms.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <cutils/atomic.h>
#include "audio_utils/primitives.h"
#include "audio_hw.h"
@@ -2350,7 +2350,7 @@
*/
out->devices = val;
-#ifndef SPLIT_A2DP_ENABLED
+#ifndef A2DP_OFFLOAD_ENABLED
if (val == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) {
//If device is BT then open the BT stream if not already opened.
if ( audio_extn_bt_hal_get_output_stream(qaf_mod->bt_hdl) == NULL
@@ -2919,7 +2919,7 @@
} else if (val & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) {
p_qaf->bt_connect = 1;
set_bt_configuration_to_module();
-#ifndef SPLIT_A2DP_ENABLED
+#ifndef A2DP_OFFLOAD_ENABLED
for (k = 0; k < MAX_MM_MODULE_TYPE; k++) {
if (!p_qaf->qaf_mod[k].bt_hdl) {
DEBUG_MSG("Opening a2dp output...");
@@ -2970,7 +2970,7 @@
//reconfig HDMI as end device (if connected)
if(p_qaf->hdmi_connect)
set_hdmi_configuration_to_module();
-#ifndef SPLIT_A2DP_ENABLED
+#ifndef A2DP_OFFLOAD_ENABLED
DEBUG_MSG("Closing a2dp output...");
for (k = 0; k < MAX_MM_MODULE_TYPE; k++) {
if (p_qaf->qaf_mod[k].bt_hdl) {
diff --git a/hal/audio_extn/sndmonitor.c b/hal/audio_extn/sndmonitor.c
index ba30d2d..3351e6f 100644
--- a/hal/audio_extn/sndmonitor.c
+++ b/hal/audio_extn/sndmonitor.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -47,11 +47,12 @@
#include <dirent.h>
#include <unistd.h>
#include <fcntl.h>
+#include <pthread.h>
#include <sys/stat.h>
#include <sys/poll.h>
#include <cutils/list.h>
#include <cutils/hashmap.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <cutils/str_parms.h>
#include <ctype.h>
@@ -69,6 +70,11 @@
#define MAX_CPE_SLEEP_RETRY 2
#define CPE_SLEEP_WAIT 100
+#define SPLI_STATE_PATH "/proc/wcd-spi-ac/svc-state"
+#define SLPI_MAGIC_NUM 0x3000
+#define MAX_SLPI_SLEEP_RETRY 2
+#define SLPI_SLEEP_WAIT_MS 100
+
#define MAX_SLEEP_RETRY 100
#define AUDIO_INIT_SLEEP_WAIT 100 /* 100 ms */
@@ -270,6 +276,31 @@
if (line)
free(line);
fclose(fp);
+
+ /* Add fd to query for SLPI status */
+ if (access(SPLI_STATE_PATH, R_OK) < 0) {
+ ALOGV("access to %s failed: %s", SPLI_STATE_PATH, strerror(errno));
+ } else {
+ tries = MAX_SLPI_SLEEP_RETRY;
+ ALOGV("Open %s", SPLI_STATE_PATH);
+ while (tries--) {
+ if ((fd = open(SPLI_STATE_PATH, O_RDONLY)) < 0) {
+ ALOGW("Open %s failed %s, retry", SPLI_STATE_PATH,
+ strerror(errno));
+ usleep(SLPI_SLEEP_WAIT_MS * 1000);
+ continue;
+ }
+ break;
+ }
+ if (fd >= 0) {
+ ret = add_new_sndcard(SLPI_MAGIC_NUM, fd);
+ if (ret != 0)
+ close(fd);
+ else
+ num_cards++;
+ }
+ }
+
ALOGV("sndmonitor registerer num_cards %d", num_cards);
sndmonitor.num_cards = num_cards;
return num_cards ? 0 : -1;
@@ -410,7 +441,6 @@
ALOGV("card num %d, new state %s", s->card, rd_buf);
- bool is_cpe = (s->card >= CPE_MAGIC_NUM);
if (strstr(rd_buf, "OFFLINE"))
status = CARD_STATUS_OFFLINE;
else if (strstr(rd_buf, "ONLINE"))
@@ -431,12 +461,18 @@
return -1;
char val[32] = {0};
- // cpe actual card num is (card - MAGIC_NUM). so subtract accordingly
- snprintf(val, sizeof(val), "%d,%s", s->card - (is_cpe ? CPE_MAGIC_NUM : 0),
- status == CARD_STATUS_ONLINE ? "ONLINE" : "OFFLINE");
-
- if (str_parms_add_str(params, is_cpe ? "CPE_STATUS" : "SND_CARD_STATUS",
- val) < 0)
+ bool is_cpe = ((s->card >= CPE_MAGIC_NUM) && (s->card < SLPI_MAGIC_NUM));
+ bool is_slpi = (s->card == SLPI_MAGIC_NUM);
+ /*
+ * cpe actual card num is (card - CPE_MAGIC_NUM), so subtract accordingly.
+ * SLPI actual fd num is (card - SLPI_MAGIC_NUM), so subtract accordingly.
+ */
+ snprintf(val, sizeof(val), "%d,%s",
+ s->card - (is_cpe ? CPE_MAGIC_NUM : (is_slpi ? SLPI_MAGIC_NUM : 0)),
+ status == CARD_STATUS_ONLINE ? "ONLINE" : "OFFLINE");
+ if (str_parms_add_str(params,
+ is_cpe ? "CPE_STATUS" : (is_slpi ? "SLPI_STATUS" : "SND_CARD_STATUS"),
+ val) < 0)
return -1;
int ret = notify(params);
diff --git a/hal/audio_extn/soundtrigger.c b/hal/audio_extn/soundtrigger.c
index aa1f7c0..e01b23b 100644
--- a/hal/audio_extn/soundtrigger.c
+++ b/hal/audio_extn/soundtrigger.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, 2016-2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 2016-2019 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -34,7 +34,8 @@
#include <stdbool.h>
#include <stdlib.h>
#include <dlfcn.h>
-#include <cutils/log.h>
+#include <pthread.h>
+#include <log/log.h>
#include <unistd.h>
#include "audio_hw.h"
#include "audio_extn.h"
@@ -95,7 +96,9 @@
SND_CARD_STATUS_OFFLINE,
SND_CARD_STATUS_ONLINE,
CPE_STATUS_OFFLINE,
- CPE_STATUS_ONLINE
+ CPE_STATUS_ONLINE,
+ SLPI_STATUS_OFFLINE,
+ SLPI_STATUS_ONLINE
} ssr_event_status_t;
struct sound_trigger_session_info {
@@ -620,6 +623,18 @@
strlcpy(event.u.str_value, value, sizeof(event.u.str_value));
st_dev->st_callback(AUDIO_EVENT_SVA_EXEC_MODE, &event);
}
+
+ ret = str_parms_get_str(params, "SLPI_STATUS", value, sizeof(value));
+ if (ret > 0) {
+ if (strstr(value, "OFFLINE")) {
+ event.u.status = SLPI_STATUS_OFFLINE;
+ st_dev->st_callback(AUDIO_EVENT_SSR, &event);
+ } else if (strstr(value, "ONLINE")) {
+ event.u.status = SLPI_STATUS_ONLINE;
+ st_dev->st_callback(AUDIO_EVENT_SSR, &event);
+ } else
+ ALOGE("%s: unknown SLPI status", __func__);
+ }
}
static int extract_sm_handle(const char *keys, char *paramstr) {
diff --git a/hal/audio_extn/source_track.c b/hal/audio_extn/source_track.c
index 2a9ba57..507aa7e 100644
--- a/hal/audio_extn/source_track.c
+++ b/hal/audio_extn/source_track.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -32,7 +32,7 @@
#include <errno.h>
#include <math.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include "audio_hw.h"
#include "platform.h"
@@ -143,7 +143,7 @@
case SND_DEVICE_IN_HANDSET_DMIC_AEC:
case SND_DEVICE_IN_HANDSET_DMIC_NS:
case SND_DEVICE_IN_HANDSET_DMIC_AEC_NS:
- case SND_DEVICE_IN_HANDSET_STEREO_DMIC:
+ case SND_DEVICE_IN_HANDSET_DMIC_STEREO:
case SND_DEVICE_IN_HANDSET_QMIC:
case SND_DEVICE_IN_HANDSET_TMIC_FLUENCE_PRO:
case SND_DEVICE_IN_VOICE_DMIC:
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index 4067055..08ecb7a 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 - 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013 - 2019, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -33,9 +33,10 @@
#include <errno.h>
#include <math.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <fcntl.h>
#include <dirent.h>
+#include <pthread.h>
#include "audio_hw.h"
#include "platform.h"
#include "platform_api.h"
@@ -116,7 +117,8 @@
/*If calibration is in progress wait for 200 msec before querying
for status again*/
-#define WAIT_FOR_GET_CALIB_STATUS (200 * 1000)
+#define WAIT_FOR_GET_CALIB_STATUS (200)
+#define GET_SPKR_PROT_CAL_TIMEOUT_MSEC (5000)
/*Speaker states*/
#define SPKR_NOT_CALIBRATED -1
@@ -500,8 +502,14 @@
ALOGD("%s: quick calibration enabled", __func__);
cal_data.cal_type.cal_info.quick_calib_flag = 1;
} else {
- ALOGD("%s: quick calibration disabled", __func__);
- cal_data.cal_type.cal_info.quick_calib_flag = 0;
+ property_get("persist.spkr.cal.duration", value, "0");
+ if (atoi(value) > 0) {
+ ALOGD("%s: quick calibration enabled", __func__);
+ cal_data.cal_type.cal_info.quick_calib_flag = 1;
+ } else {
+ ALOGD("%s: quick calibration disabled", __func__);
+ cal_data.cal_type.cal_info.quick_calib_flag = 0;
+ }
}
cal_data.cal_type.cal_data.mem_handle = -1;
@@ -749,6 +757,8 @@
int32_t pcm_dev_rx_id = -1, pcm_dev_tx_id = -1;
struct timespec ts;
bool acquire_device = false;
+ int retry_duration;
+ int app_type = 0;
memset(&status, 0, sizeof(status));
memset(&protCfg, 0, sizeof(protCfg));
@@ -873,7 +883,9 @@
}
if (acdb_fd > 0) {
status.status = -EINVAL;
- while (!get_spkr_prot_cal(acdb_fd, &status)) {
+ retry_duration = 0;
+ while (!get_spkr_prot_cal(acdb_fd, &status) &&
+ retry_duration < GET_SPKR_PROT_CAL_TIMEOUT_MSEC) {
/*sleep for 200 ms to check for status check*/
if (!status.status) {
ALOGD("%s: spkr_prot_thread calib Success R0 %d %d",
@@ -896,7 +908,8 @@
break;
} else if (status.status == -EAGAIN) {
ALOGV("%s: spkr_prot_thread try again", __func__);
- usleep(WAIT_FOR_GET_CALIB_STATUS);
+ usleep(WAIT_FOR_GET_CALIB_STATUS * 1000);
+ retry_duration += WAIT_FOR_GET_CALIB_STATUS;
} else {
ALOGE("%s: spkr_prot_thread get failed status %d",
__func__, status.status);
@@ -910,6 +923,17 @@
if (handle.pcm_tx)
pcm_close(handle.pcm_tx);
handle.pcm_tx = NULL;
+ /* Clear TX calibration to handset mic */
+ if (uc_info_tx != NULL) {
+ ALOGD("%s: UC Info TX is not NULL, updating and sending calibration",
+ __func__);
+ uc_info_tx->in_snd_device = SND_DEVICE_IN_HANDSET_MIC;
+ uc_info_tx->out_snd_device = SND_DEVICE_NONE;
+ app_type = platform_get_default_app_type_v2(adev->platform,
+ PCM_CAPTURE);
+ platform_send_audio_calibration(adev->platform, uc_info_tx,
+ app_type, 8000);
+ }
if (!status.status) {
protCfg.mode = MSM_SPKR_PROT_CALIBRATED;
protCfg.r0[SP_V2_SPKR_1] = status.r0[SP_V2_SPKR_1];
@@ -1004,6 +1028,11 @@
property_get("persist.vendor.audio.spkr.cal.duration", value, "0");
if (atoi(value) > 0)
min_idle_time = atoi(value);
+ else {
+ property_get("persist.spkr.cal.duration", value, "0");
+ if (atoi(value) > 0)
+ min_idle_time = atoi(value);
+ }
handle.speaker_prot_threadid = pthread_self();
ALOGD("spkr_prot_thread enable prot Entry");
acdb_fd = open("/dev/msm_audio_cal",O_RDWR | O_NONBLOCK);
@@ -1631,12 +1660,16 @@
ALOGE("%s: Invalid params", __func__);
return;
}
- property_get("persist.vendor.audio.speaker.prot.enable", value, "");
handle.spkr_prot_enable = false;
+ if ((property_get("persist.vendor.audio.speaker.prot.enable",
+ value, NULL) > 0) ||
+ (property_get("persist.speaker.prot.enable",
+ value, NULL) > 0)) {
+ if (!strncmp("true", value, 4))
+ handle.spkr_prot_enable = true;
+ }
handle.init_check = false;
handle.thread_exit = false;
- if (!strncmp("true", value, 4))
- handle.spkr_prot_enable = true;
if (!handle.spkr_prot_enable) {
ALOGD("%s: Speaker protection disabled", __func__);
return;
@@ -1648,6 +1681,11 @@
handle.trigger_cal = false;
/* HAL for speaker protection is always calibrating for stereo usecase*/
vi_feed_no_channels = spkr_vi_channels(adev);
+ if (vi_feed_no_channels < 0) {
+ ALOGE("%s: no of channels negative !!", __func__);
+ /* limit the number of channels to 2*/
+ vi_feed_no_channels = 2;
+ }
pthread_condattr_init(&attr);
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
@@ -1810,6 +1848,7 @@
int32_t pcm_dev_tx_id = -1, ret = 0;
snd_device_t in_snd_device;
char device_name[DEVICE_NAME_MAX_SIZE] = {0};
+ int app_type = 0;
ALOGV("%s: Entry", __func__);
/* cancel speaker calibration */
@@ -1875,7 +1914,18 @@
}
exit:
- if (ret) {
+ /* Clear VI feedback cal and replace with handset MIC */
+ if (uc_info_tx != NULL) {
+ ALOGD("%s: UC Info TX is not NULL, updating and sending calibration",
+ __func__);
+ uc_info_tx->in_snd_device = SND_DEVICE_IN_HANDSET_MIC;
+ uc_info_tx->out_snd_device = SND_DEVICE_NONE;
+ app_type = platform_get_default_app_type_v2(adev->platform,
+ PCM_CAPTURE);
+ platform_send_audio_calibration(adev->platform, uc_info_tx,
+ app_type, 8000);
+ }
+ if (ret) {
if (handle.pcm_tx)
pcm_close(handle.pcm_tx);
handle.pcm_tx = NULL;
@@ -1930,4 +1980,8 @@
{
return handle.spkr_prot_enable;
}
+
+int audio_extn_get_spkr_prot_snd_device(snd_device_t snd_device) {
+ return snd_device;
+}
#endif /*SPKR_PROT_ENABLED*/
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index 16b3e10..3b2f1b3 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2016-2019 The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -24,7 +24,7 @@
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <cutils/str_parms.h>
#include <sys/ioctl.h>
#include <fcntl.h>
@@ -36,6 +36,7 @@
#include <ctype.h>
#include <math.h>
#include <unistd.h>
+#include "audio_extn.h"
#ifdef DYNAMIC_LOG_ENABLED
#include <log_xml_parser.h>
@@ -43,7 +44,7 @@
#include <log_utils.h>
#endif
-#ifdef USB_HEADSET_ENABLED
+#ifdef USB_TUNNEL_ENABLED
#define USB_BUFF_SIZE 2048
#define CHANNEL_NUMBER_STR "Channels: "
#define PLAYBACK_PROFILE_STR "Playback:"
@@ -116,11 +117,6 @@
"Mic Playback Switch",
};
-static const char * const usb_sidetone_volume_str[] = {
- "Sidetone Playback Volume",
- "Mic Playback Volume",
-};
-
static void usb_mixer_print_enum(struct mixer_ctl *ctl)
{
unsigned int num_enums;
@@ -605,21 +601,13 @@
usb_card_info->usb_sidetone_index[USB_SIDETONE_ENABLE_INDEX] = index;
/* Disable device sidetone by default */
mixer_ctl_set_value(ctl, 0, false);
+ ALOGV("%s: sidetone mixer Control found(%s) ... disabling by default",
+ __func__, usb_sidetone_enable_str[index]);
break;
}
}
- for (index = 0;
- index < sizeof(usb_sidetone_volume_str)/sizeof(usb_sidetone_volume_str[0]);
- index++) {
- ctl = mixer_get_ctl_by_name(usb_card_info->usb_snd_mixer,
- usb_sidetone_volume_str[index]);
- if (ctl) {
- usb_card_info->usb_sidetone_index[USB_SIDETONE_VOLUME_INDEX] = index;
- usb_card_info->usb_sidetone_vol_min = mixer_ctl_get_range_min(ctl);
- usb_card_info->usb_sidetone_vol_max = mixer_ctl_get_range_max(ctl);
- break;
- }
- }
+
+ audio_extn_usb_get_sidetone_volume(usb_card_info);
if ((usb_card_info->usb_snd_mixer != NULL) && (usb_audio_debug_enable))
usb_soundcard_list_controls(usb_card_info->usb_snd_mixer);
@@ -910,14 +898,6 @@
return is_usb_supported;
}
-static int usb_get_sidetone_gain(struct usb_card_config *card_info)
-{
- int gain = card_info->usb_sidetone_vol_min + usbmod->sidetone_gain;
- if (gain > card_info->usb_sidetone_vol_max)
- gain = card_info->usb_sidetone_vol_max;
- return gain;
-}
-
void audio_extn_usb_set_sidetone_gain(struct str_parms *parms,
char *value, int len)
{
@@ -958,16 +938,9 @@
break;
if ((i = card_info->usb_sidetone_index[USB_SIDETONE_VOLUME_INDEX]) != -1) {
- ctl = mixer_get_ctl_by_name(
- card_info->usb_snd_mixer,
- usb_sidetone_volume_str[i]);
- if (ctl == NULL)
- ALOGV("%s: sidetone gain mixer command is not found",
- __func__);
- else if (enable)
- mixer_ctl_set_value(ctl, 0,
- usb_get_sidetone_gain(card_info));
+ audio_extn_usb_set_sidetone_volume(card_info, enable, i);
}
+
ret = 0;
break;
}
@@ -1094,9 +1067,12 @@
char check_debug_enable[PROPERTY_VALUE_MAX];
struct listnode *node_i;
- property_get("vendor.audio.usb.enable.debug", check_debug_enable, NULL);
- if (atoi(check_debug_enable)) {
- usb_audio_debug_enable = true;
+ if ((property_get("vendor.audio.usb.enable.debug",
+ check_debug_enable, NULL) > 0) ||
+ (property_get("audio.usb.enable.debug",
+ check_debug_enable, NULL) > 0)) {
+ if (atoi(check_debug_enable))
+ usb_audio_debug_enable = true;
}
ALOGI_IF(usb_audio_debug_enable,
@@ -1218,13 +1194,14 @@
return access(path, F_OK) == 0;
}
+#ifdef USB_BURST_MODE_ENABLED
unsigned long audio_extn_usb_find_service_interval(bool min,
bool playback) {
struct usb_card_config *card_info = NULL;
struct usb_device_config *dev_info = NULL;
struct listnode *node_i = NULL;
struct listnode *node_j = NULL;
- unsigned long interval_us = min ? UINT_MAX : 0;
+ unsigned long interval_us = min ? ULONG_MAX : 0;
list_for_each(node_i, &usbmod->usb_card_conf_list) {
card_info = node_to_item(node_i, struct usb_card_config, list);
list_for_each(node_j, &card_info->usb_device_conf_list) {
@@ -1249,9 +1226,9 @@
uint32_t *channels)
{
struct usb_card_config *card_info = NULL;
- struct usb_device_config *dev_info = NULL;;
- struct listnode *node_i = NULL;;
- struct listnode *node_j = NULL;;
+ struct usb_device_config *dev_info = NULL;
+ struct listnode *node_i = NULL;
+ struct listnode *node_j = NULL;
uint32_t bw = 0;
uint32_t ch = 0;
uint32_t sr = 0;
@@ -1433,6 +1410,7 @@
{
usbmod->usb_reconfig = is_required;
}
+#endif /* USB_BURST_MODE_ENABLED end */
bool audio_extn_usb_connected(struct str_parms *parms) {
int card = -1;
@@ -1462,7 +1440,10 @@
ALOGE("%s: error unable to allocate memory", __func__);
goto exit;
}
+ } else {
+ memset(usbmod, 0, sizeof(*usbmod));
}
+
list_init(&usbmod->usb_card_conf_list);
usbmod->adev = (struct audio_device*)adev;
usbmod->sidetone_gain = usb_sidetone_gain;
@@ -1479,4 +1460,54 @@
usbmod = NULL;
}
}
-#endif /*USB_HEADSET_ENABLED end*/
+
+#ifdef USB_SIDETONE_VOLUME
+static const char * const usb_sidetone_volume_str[] = {
+ "Sidetone Playback Volume",
+ "Mic Playback Volume",
+};
+
+static int usb_get_sidetone_gain(struct usb_card_config *card_info)
+{
+ int gain = card_info->usb_sidetone_vol_min + usbmod->sidetone_gain;
+ if (gain > card_info->usb_sidetone_vol_max)
+ gain = card_info->usb_sidetone_vol_max;
+ return gain;
+}
+
+void audio_extn_usb_get_sidetone_volume(struct usb_card_config *usb_card_info)
+{
+ struct mixer_ctl *ctl;
+ unsigned int index;
+
+ for (index = 0;
+ index < sizeof(usb_sidetone_volume_str)/sizeof(usb_sidetone_volume_str[0]);
+ index++) {
+ ctl = mixer_get_ctl_by_name(usb_card_info->usb_snd_mixer,
+ usb_sidetone_volume_str[index]);
+ if (ctl) {
+ usb_card_info->usb_sidetone_index[USB_SIDETONE_VOLUME_INDEX] = index;
+ usb_card_info->usb_sidetone_vol_min = mixer_ctl_get_range_min(ctl);
+ usb_card_info->usb_sidetone_vol_max = mixer_ctl_get_range_max(ctl);
+ break;
+ }
+ }
+}
+
+void audio_extn_usb_set_sidetone_volume(struct usb_card_config *usb_card_info,
+ bool enable, int index)
+{
+ struct mixer_ctl *ctl;
+
+ ctl = mixer_get_ctl_by_name(usb_card_info->usb_snd_mixer,
+ usb_sidetone_volume_str[index]);
+
+ if (ctl == NULL)
+ ALOGV("%s: sidetone gain mixer command is not found",
+ __func__);
+ else if (enable)
+ mixer_ctl_set_value(ctl, 0,
+ usb_get_sidetone_gain(usb_card_info));
+}
+#endif /* USB_SIDETONE_VOLUME end */
+#endif /* USB_TUNNEL_ENABLED end */
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 7c5756b..ad4e4b8 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2014 The Android Open Source Project
@@ -27,7 +27,7 @@
#include <stdlib.h>
#include <dlfcn.h>
#include <cutils/str_parms.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <cutils/misc.h>
#include <unistd.h>
@@ -894,6 +894,132 @@
}
}
+static int set_stream_app_type_mixer_ctrl(struct audio_device *adev,
+ int pcm_device_id, int app_type,
+ int acdb_dev_id, int sample_rate,
+ int stream_type,
+ snd_device_t snd_device)
+{
+
+ char mixer_ctl_name[MAX_LENGTH_MIXER_CONTROL_IN_INT];
+ struct mixer_ctl *ctl;
+ int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT], len = 0, rc = 0;
+ int snd_device_be_idx = -1;
+
+ if (stream_type == PCM_PLAYBACK) {
+ snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+ "Audio Stream %d App Type Cfg", pcm_device_id);
+ } else if (stream_type == PCM_CAPTURE) {
+ snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+ "Audio Stream Capture %d App Type Cfg", pcm_device_id);
+ }
+
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s",
+ __func__, mixer_ctl_name);
+ rc = -EINVAL;
+ goto exit;
+ }
+ app_type_cfg[len++] = app_type;
+ app_type_cfg[len++] = acdb_dev_id;
+ app_type_cfg[len++] = sample_rate;
+
+ snd_device_be_idx = platform_get_snd_device_backend_index(snd_device);
+ if (snd_device_be_idx > 0)
+ app_type_cfg[len++] = snd_device_be_idx;
+ ALOGV("%s: stream type %d app_type %d, acdb_dev_id %d "
+ "sample rate %d, snd_device_be_idx %d",
+ __func__, stream_type, app_type, acdb_dev_id, sample_rate,
+ snd_device_be_idx);
+ mixer_ctl_set_array(ctl, app_type_cfg, len);
+
+exit:
+ return rc;
+}
+
+static int audio_extn_utils_send_app_type_cfg_hfp(struct audio_device *adev,
+ struct audio_usecase *usecase)
+{
+ int pcm_device_id, acdb_dev_id = 0, snd_device = usecase->out_snd_device;
+ int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+ int app_type = 0, rc = 0;
+
+ ALOGV("%s", __func__);
+
+ if (usecase->type != PCM_HFP_CALL) {
+ ALOGV("%s: not a playback or HFP path, no need to cfg app type", __func__);
+ rc = 0;
+ goto exit_send_app_type_cfg;
+ }
+ if ((usecase->id != USECASE_AUDIO_HFP_SCO) &&
+ (usecase->id != USECASE_AUDIO_HFP_SCO_WB)) {
+ ALOGV("%s: a playback path where app type cfg is not required", __func__);
+ rc = 0;
+ goto exit_send_app_type_cfg;
+ }
+
+ snd_device = usecase->out_snd_device;
+ pcm_device_id = platform_get_pcm_device_id(usecase->id, PCM_PLAYBACK);
+
+ acdb_dev_id = platform_get_snd_device_acdb_id(snd_device);
+ if (acdb_dev_id < 0) {
+ ALOGE("%s: Couldn't get the acdb dev id", __func__);
+ rc = -EINVAL;
+ goto exit_send_app_type_cfg;
+ }
+
+ if (usecase->type == PCM_HFP_CALL) {
+
+ /* config HFP session:1 playback path */
+ app_type = platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK);
+ sample_rate= CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
+ acdb_dev_id, sample_rate,
+ PCM_PLAYBACK,
+ SND_DEVICE_NONE); // use legacy behavior
+ if (rc < 0)
+ goto exit_send_app_type_cfg;
+
+ /* config HFP session:1 capture path */
+ app_type = platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE);
+ rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
+ acdb_dev_id, sample_rate,
+ PCM_CAPTURE,
+ SND_DEVICE_NONE);
+ if (rc < 0)
+ goto exit_send_app_type_cfg;
+
+ /* config HFP session:2 capture path */
+ pcm_device_id = HFP_ASM_RX_TX;
+ snd_device = usecase->in_snd_device;
+ acdb_dev_id = platform_get_snd_device_acdb_id(snd_device);
+ if (acdb_dev_id <= 0) {
+ ALOGE("%s: Couldn't get the acdb dev id", __func__);
+ rc = -EINVAL;
+ goto exit_send_app_type_cfg;
+ }
+ app_type = platform_get_default_app_type_v2(adev->platform, PCM_CAPTURE);
+ rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
+ acdb_dev_id, sample_rate, PCM_CAPTURE,
+ SND_DEVICE_NONE);
+ if (rc < 0)
+ goto exit_send_app_type_cfg;
+
+ /* config HFP session:2 playback path */
+ app_type = platform_get_default_app_type_v2(adev->platform, PCM_PLAYBACK);
+ rc = set_stream_app_type_mixer_ctrl(adev, pcm_device_id, app_type,
+ acdb_dev_id, sample_rate,
+ PCM_PLAYBACK, SND_DEVICE_NONE);
+ if (rc < 0)
+ goto exit_send_app_type_cfg;
+ }
+
+ rc = 0;
+exit_send_app_type_cfg:
+ return rc;
+}
+
static int send_app_type_cfg_for_device(struct audio_device *adev,
struct audio_usecase *usecase,
int split_snd_device)
@@ -1118,6 +1244,10 @@
snd_device_t in_snd_device = usecase->in_snd_device;
int rc = 0;
+ if (usecase->type == PCM_HFP_CALL) {
+ return audio_extn_utils_send_app_type_cfg_hfp(adev, usecase);
+ }
+
switch (usecase->type) {
case PCM_PLAYBACK:
case TRANSCODE_LOOPBACK_RX:
@@ -2132,6 +2262,66 @@
#define MAX_SND_CARD 8
#define RETRY_US 1000000
#define RETRY_NUMBER 40
+#define PLATFORM_INFO_XML_PATH "audio_platform_info.xml"
+#define PLATFORM_INFO_XML_BASE_STRING "audio_platform_info"
+
+#ifdef LINUX_ENABLED
+static const char *kConfigLocationList[] =
+ {"/etc"};
+#else
+static const char *kConfigLocationList[] =
+ {"/vendor/etc"};
+#endif
+static const int kConfigLocationListSize =
+ (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
+
+bool audio_extn_utils_resolve_config_file(char file_name[MIXER_PATH_MAX_LENGTH])
+{
+ char full_config_path[MIXER_PATH_MAX_LENGTH];
+ for (int i = 0; i < kConfigLocationListSize; i++) {
+ snprintf(full_config_path,
+ MIXER_PATH_MAX_LENGTH,
+ "%s/%s",
+ kConfigLocationList[i],
+ file_name);
+ if (F_OK == access(full_config_path, 0)) {
+ strcpy(file_name, full_config_path);
+ return true;
+ }
+ }
+ return false;
+}
+
+/* platform_info_file should be size 'MIXER_PATH_MAX_LENGTH' */
+int audio_extn_utils_get_platform_info(const char* snd_card_name, char* platform_info_file)
+{
+ if (NULL == snd_card_name) {
+ return -1;
+ }
+
+ struct snd_card_split *snd_split_handle = NULL;
+ int ret = 0;
+ audio_extn_set_snd_card_split(snd_card_name);
+ snd_split_handle = audio_extn_get_snd_card_split();
+
+ snprintf(platform_info_file, MIXER_PATH_MAX_LENGTH, "%s_%s_%s.xml",
+ PLATFORM_INFO_XML_BASE_STRING, snd_split_handle->snd_card,
+ snd_split_handle->form_factor);
+
+ if (!audio_extn_utils_resolve_config_file(platform_info_file)) {
+ memset(platform_info_file, 0, MIXER_PATH_MAX_LENGTH);
+ snprintf(platform_info_file, MIXER_PATH_MAX_LENGTH, "%s_%s.xml",
+ PLATFORM_INFO_XML_BASE_STRING, snd_split_handle->snd_card);
+
+ if (!audio_extn_utils_resolve_config_file(platform_info_file)) {
+ memset(platform_info_file, 0, MIXER_PATH_MAX_LENGTH);
+ strlcpy(platform_info_file, PLATFORM_INFO_XML_PATH, MIXER_PATH_MAX_LENGTH);
+ ret = audio_extn_utils_resolve_config_file(platform_info_file) ? 0 : -1;
+ }
+ }
+
+ return ret;
+}
int audio_extn_utils_get_snd_card_num()
{
@@ -2544,3 +2734,24 @@
return platform_get_license_by_product(adev->platform, (const char*)license_params->product, &license_params->key, license_params->license);
}
+int audio_extn_utils_send_app_type_gain(struct audio_device *adev,
+ int app_type,
+ int *gain)
+{
+ int gain_cfg[4];
+ const char *mixer_ctl_name = "App Type Gain";
+ struct mixer_ctl *ctl;
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get volume ctl mixer %s", __func__,
+ mixer_ctl_name);
+ return -EINVAL;
+ }
+ gain_cfg[0] = 0;
+ gain_cfg[1] = app_type;
+ gain_cfg[2] = gain[0];
+ gain_cfg[3] = gain[1];
+ ALOGV("%s app_type %d l(%d) r(%d)", __func__, app_type, gain[0], gain[1]);
+ return mixer_ctl_set_array(ctl, gain_cfg,
+ sizeof(gain_cfg)/sizeof(gain_cfg[0]));
+}
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 375f221..f8c5563 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -55,7 +55,7 @@
#include <sys/resource.h>
#include <sys/prctl.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <cutils/trace.h>
#include <cutils/str_parms.h>
#include <cutils/properties.h>
@@ -93,10 +93,17 @@
#define PCM_PLAYBACK_VOLUME_MAX 0x2000
#define DSD_VOLUME_MIN_DB (-110)
+#define RECORD_GAIN_MIN 0.0f
+#define RECORD_GAIN_MAX 1.0f
+#define RECORD_VOLUME_CTL_MAX 0x2000
+
+/* treat as unsigned Q1.13 */
+#define APP_TYPE_GAIN_DEFAULT 0x2000
+
#define PROXY_OPEN_RETRY_COUNT 100
#define PROXY_OPEN_WAIT_TIME 20
-#ifdef USE_LL_AS_PRIMARY_OUTPUT
+#ifndef USE_DEEP_AS_PRIMARY_OUTPUT
#define USECASE_AUDIO_PLAYBACK_PRIMARY USECASE_AUDIO_PLAYBACK_LOW_LATENCY
#define PCM_CONFIG_AUDIO_PLAYBACK_PRIMARY pcm_config_low_latency
#else
@@ -125,6 +132,14 @@
#define DEFAULT_CHANNEL_COUNT 2
#define MAX_HIFI_CHANNEL_COUNT 8
+#ifndef MAX_TARGET_SPECIFIC_CHANNEL_CNT
+#define MAX_CHANNEL_COUNT 1
+#else
+#define MAX_CHANNEL_COUNT atoi(XSTR(MAX_TARGET_SPECIFIC_CHANNEL_CNT))
+#define XSTR(x) STR(x)
+#define STR(x) #x
+#endif
+
static unsigned int configured_low_latency_capture_period_size =
LOW_LATENCY_CAPTURE_PERIOD_SIZE;
@@ -133,6 +148,11 @@
#define MMAP_PERIOD_COUNT_MAX 512
#define MMAP_PERIOD_COUNT_DEFAULT (MMAP_PERIOD_COUNT_MAX)
+/* This constant enables extended precision handling.
+ * TODO The flag is off until more testing is done.
+ */
+static const bool k_enable_extended_precision = false;
+
struct pcm_config pcm_config_deep_buffer = {
.channels = 2,
.rate = DEFAULT_OUTPUT_SAMPLING_RATE,
@@ -210,19 +230,6 @@
.format = PCM_FORMAT_S16_LE,
};
-struct pcm_config pcm_config_audio_capture_rt = {
- .channels = 2,
- .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
- .period_size = ULL_PERIOD_SIZE,
- .period_count = 512,
- .format = PCM_FORMAT_S16_LE,
- .start_threshold = 0,
- .stop_threshold = INT_MAX,
- .silence_threshold = 0,
- .silence_size = 0,
- .avail_min = ULL_PERIOD_SIZE, //1 ms
-};
-
struct pcm_config pcm_config_mmap_capture = {
.channels = 2,
.rate = DEFAULT_OUTPUT_SAMPLING_RATE,
@@ -256,6 +263,19 @@
#define AFE_PROXY_RECORD_PERIOD_SIZE 768
#define AFE_PROXY_RECORD_PERIOD_COUNT 4
+struct pcm_config pcm_config_audio_capture_rt = {
+ .channels = 2,
+ .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
+ .period_size = ULL_PERIOD_SIZE,
+ .period_count = 512,
+ .format = PCM_FORMAT_S16_LE,
+ .start_threshold = 0,
+ .stop_threshold = AFE_PROXY_RECORD_PERIOD_SIZE * AFE_PROXY_RECORD_PERIOD_COUNT,
+ .silence_threshold = 0,
+ .silence_size = 0,
+ .avail_min = ULL_PERIOD_SIZE, //1 ms
+};
+
struct pcm_config pcm_config_afe_proxy_record = {
.channels = AFE_PROXY_CHANNEL_COUNT,
.rate = AFE_PROXY_SAMPLING_RATE,
@@ -297,6 +317,7 @@
[USECASE_AUDIO_PLAYBACK_FM] = "play-fm",
[USECASE_AUDIO_PLAYBACK_MMAP] = "mmap-playback",
[USECASE_AUDIO_PLAYBACK_HIFI] = "hifi-playback",
+ [USECASE_AUDIO_PLAYBACK_TTS] = "audio-tts-playback",
[USECASE_AUDIO_RECORD] = "audio-record",
[USECASE_AUDIO_RECORD_COMPRESS] = "audio-record-compress",
@@ -662,6 +683,29 @@
return ret_val;
}
+#ifdef MAXXAUDIO_QDSP_ENABLED
+bool audio_hw_send_ma_parameter(int stream_type, float vol, bool active)
+{
+ bool ret = false;
+ ALOGV("%s: enter ...", __func__);
+
+ pthread_mutex_lock(&adev_init_lock);
+
+ if (adev != NULL && adev->platform != NULL) {
+ pthread_mutex_lock(&adev->lock);
+ ret = audio_extn_ma_set_state(adev, stream_type, vol, active);
+ pthread_mutex_unlock(&adev->lock);
+ }
+
+ pthread_mutex_unlock(&adev_init_lock);
+
+ ALOGV("%s: exit with ret %d", __func__, ret);
+ return ret;
+}
+#else
+#define audio_hw_send_ma_parameter(stream_type, vol, active) (0)
+#endif
+
static bool is_supported_format(audio_format_t format)
{
if (format == AUDIO_FORMAT_MP3 ||
@@ -1074,6 +1118,8 @@
if (audio_extn_spkr_prot_is_enabled())
audio_extn_spkr_prot_calib_cancel(adev);
+ audio_extn_dsm_feedback_enable(adev, snd_device, true);
+
if (platform_can_enable_spkr_prot_on_device(snd_device) &&
audio_extn_spkr_prot_is_enabled()) {
if (platform_get_spkr_prot_acdb_id(snd_device) < 0) {
@@ -1093,6 +1139,7 @@
for (i = 0; i < num_devices; i++) {
enable_snd_device(adev, new_snd_devices[i]);
}
+ platform_set_speaker_gain_in_combo(adev, snd_device, true);
} else {
ALOGD("%s: snd_device(%d: %s)", __func__, snd_device, device_name);
@@ -1172,6 +1219,8 @@
if (adev->snd_dev_ref_cnt[snd_device] == 0) {
ALOGD("%s: snd_device(%d: %s)", __func__, snd_device, device_name);
+ audio_extn_dsm_feedback_enable(adev, snd_device, false);
+
if (platform_can_enable_spkr_prot_on_device(snd_device) &&
audio_extn_spkr_prot_is_enabled()) {
audio_extn_spkr_prot_stop_processing(snd_device);
@@ -1186,6 +1235,7 @@
for (i = 0; i < num_devices; i++) {
disable_snd_device(adev, new_snd_devices[i]);
}
+ platform_set_speaker_gain_in_combo(adev, snd_device, false);
} else {
audio_route_reset_and_update_path(adev->audio_route, device_name);
}
@@ -2008,6 +2058,11 @@
return ret;
}
+static void stream_app_type_cfg_init(struct stream_app_type_cfg *cfg)
+{
+ cfg->gain[0] = cfg->gain[1] = APP_TYPE_GAIN_DEFAULT;
+}
+
bool is_btsco_device(snd_device_t out_snd_device, snd_device_t in_snd_device)
{
bool ret=false;
@@ -2171,7 +2226,8 @@
voip_usecase != NULL &&
usecase->stream.out->usecase == voip_usecase->id) &&
adev->active_input &&
- adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
+ (adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
+ adev->mode == AUDIO_MODE_IN_COMMUNICATION) &&
out_snd_device != usecase->out_snd_device) {
select_devices(adev, adev->active_input->usecase);
}
@@ -2216,9 +2272,37 @@
return 0;
}
- ALOGD("%s: out_snd_device(%d: %s) in_snd_device(%d: %s)", __func__,
- out_snd_device, platform_get_snd_device_name(out_snd_device),
- in_snd_device, platform_get_snd_device_name(in_snd_device));
+ if (out_snd_device != SND_DEVICE_NONE &&
+ out_snd_device != adev->last_logged_snd_device[uc_id][0]) {
+ ALOGD("%s: changing use case %s output device from(%d: %s, acdb %d) to (%d: %s, acdb %d)",
+ __func__,
+ use_case_table[uc_id],
+ adev->last_logged_snd_device[uc_id][0],
+ platform_get_snd_device_name(adev->last_logged_snd_device[uc_id][0]),
+ adev->last_logged_snd_device[uc_id][0] != SND_DEVICE_NONE ?
+ platform_get_snd_device_acdb_id(adev->last_logged_snd_device[uc_id][0]) :
+ -1,
+ out_snd_device,
+ platform_get_snd_device_name(out_snd_device),
+ platform_get_snd_device_acdb_id(out_snd_device));
+ adev->last_logged_snd_device[uc_id][0] = out_snd_device;
+ }
+ if (in_snd_device != SND_DEVICE_NONE &&
+ in_snd_device != adev->last_logged_snd_device[uc_id][1]) {
+ ALOGD("%s: changing use case %s input device from(%d: %s, acdb %d) to (%d: %s, acdb %d)",
+ __func__,
+ use_case_table[uc_id],
+ adev->last_logged_snd_device[uc_id][1],
+ platform_get_snd_device_name(adev->last_logged_snd_device[uc_id][1]),
+ adev->last_logged_snd_device[uc_id][1] != SND_DEVICE_NONE ?
+ platform_get_snd_device_acdb_id(adev->last_logged_snd_device[uc_id][1]) :
+ -1,
+ in_snd_device,
+ platform_get_snd_device_name(in_snd_device),
+ platform_get_snd_device_acdb_id(in_snd_device));
+ adev->last_logged_snd_device[uc_id][1] = in_snd_device;
+ }
+
/*
* Limitation: While in call, to do a device switch we need to disable
@@ -2244,10 +2328,14 @@
voice_check_and_update_aanc_path(adev, usecase->out_snd_device, false);
}
- if ((out_snd_device == SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP) &&
+ if ((out_snd_device == SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP ||
+ out_snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP) &&
(!audio_extn_a2dp_source_is_ready())) {
ALOGW("%s: A2DP profile is not ready, routing to speaker only", __func__);
- out_snd_device = SND_DEVICE_OUT_SPEAKER;
+ if (out_snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP)
+ out_snd_device = SND_DEVICE_OUT_SPEAKER_SAFE;
+ else
+ out_snd_device = SND_DEVICE_OUT_SPEAKER;
}
/* Disable current sound devices */
@@ -2329,6 +2417,8 @@
}
enable_audio_route(adev, usecase);
+ audio_extn_ma_set_device(usecase);
+
/* If input stream is already running then effect needs to be
applied on the new input device that's being enabled here. */
if ((in_snd_device != SND_DEVICE_NONE) && (adev->active_input != NULL) &&
@@ -2395,6 +2485,13 @@
pthread_mutex_lock(&adev->lock);
}
+ if (usecase == voip_usecase) {
+ struct stream_out *voip_out = voip_usecase->stream.out;
+ audio_extn_utils_send_app_type_gain(adev,
+ voip_out->app_type_cfg.app_type,
+ &voip_out->app_type_cfg.gain[0]);
+ }
+
ALOGD("%s: done",__func__);
return status;
@@ -2944,6 +3041,8 @@
int ret = 0;
struct audio_usecase *uc_info;
struct audio_device *adev = out->dev;
+ bool has_voip_usecase =
+ get_usecase_from_list(adev, USECASE_AUDIO_PLAYBACK_VOIP) != NULL;
ALOGV("%s: enter: usecase(%d: %s)", __func__,
out->usecase, use_case_table[out->usecase]);
@@ -2979,6 +3078,8 @@
/* 2. Disable the rx device */
disable_snd_device(adev, uc_info->out_snd_device);
+ audio_extn_extspk_update(adev->extspk);
+
if (is_offload_usecase(out->usecase)) {
audio_enable_asm_bit_width_enforce_mode(adev->mixer,
adev->dsp_bit_width_enforce_mode,
@@ -3016,6 +3117,22 @@
ALOGE("%s: audio_extn_ip_hdlr_intf_close failed %d",__func__, ret);
}
+ if (has_voip_usecase ||
+ out->devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
+ 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 == PCM_CAPTURE || usecase == uc_info)
+ continue;
+
+ ALOGD("%s: select_devices at usecase(%d: %s) after removing the usecase(%d: %s)",
+ __func__, usecase->id, use_case_table[usecase->id],
+ out->usecase, use_case_table[out->usecase]);
+ select_devices(adev, usecase->id);
+ }
+ }
+
free(uc_info);
ALOGV("%s: exit: status(%d)", __func__, ret);
return ret;
@@ -3050,7 +3167,8 @@
if (out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) {
if (!audio_extn_a2dp_source_is_ready()) {
- if (out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
+ if (out->devices &
+ (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
a2dp_combo = true;
} else {
if (!(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) {
@@ -3124,7 +3242,10 @@
check_a2dp_restore_l(adev, out, false);
} else {
audio_devices_t dev = out->devices;
- out->devices = AUDIO_DEVICE_OUT_SPEAKER;
+ if (dev & AUDIO_DEVICE_OUT_SPEAKER_SAFE)
+ out->devices = AUDIO_DEVICE_OUT_SPEAKER_SAFE;
+ else
+ out->devices = AUDIO_DEVICE_OUT_SPEAKER;
select_devices(adev, out->usecase);
out->devices = dev;
}
@@ -3355,7 +3476,8 @@
static int check_input_parameters(uint32_t sample_rate,
audio_format_t format,
- int channel_count)
+ int channel_count,
+ bool is_usb_hifi)
{
int ret = 0;
@@ -3367,6 +3489,13 @@
!audio_extn_cin_format_supported(format))
ret = -EINVAL;
+ int max_channel_count = is_usb_hifi ? MAX_HIFI_CHANNEL_COUNT : MAX_CHANNEL_COUNT;
+ if ((channel_count < MIN_CHANNEL_COUNT) || (channel_count > max_channel_count)) {
+ ALOGE("%s: unsupported channel count (%d) passed Min / Max (%d / %d)", __func__,
+ channel_count, MIN_CHANNEL_COUNT, max_channel_count);
+ return -EINVAL;
+ }
+
switch (channel_count) {
case 1:
case 2:
@@ -3480,23 +3609,21 @@
return num;
}
-static size_t get_input_buffer_size(uint32_t sample_rate,
- audio_format_t format,
- int channel_count,
- bool is_low_latency)
+static size_t get_stream_buffer_size(size_t duration_ms,
+ uint32_t sample_rate,
+ audio_format_t format,
+ int channel_count,
+ bool is_low_latency)
{
size_t size = 0;
uint32_t bytes_per_period_sample = 0;
- if (check_input_parameters(sample_rate, format, channel_count) != 0)
- return 0;
-
- size = (sample_rate * AUDIO_CAPTURE_PERIOD_DURATION_MSEC) / 1000;
+ size = (sample_rate * duration_ms) / 1000;
if (is_low_latency)
size = configured_low_latency_capture_period_size;
bytes_per_period_sample = audio_bytes_per_sample(format) * channel_count;
- size *= bytes_per_period_sample;
+ size *= audio_bytes_per_sample(format) * channel_count;
/* make sure the size is multiple of 32 bytes and additionally multiple of
* the frame_size (required for 24bit samples and non-power-of-2 channel counts)
@@ -3510,6 +3637,23 @@
return size;
}
+static size_t get_input_buffer_size(uint32_t sample_rate,
+ audio_format_t format,
+ int channel_count,
+ bool is_low_latency)
+{
+ /* Don't know if USB HIFI in this context so use true to be conservative */
+ if (check_input_parameters(sample_rate, format, channel_count,
+ true /*is_usb_hifi */) != 0)
+ return 0;
+
+ return get_stream_buffer_size(AUDIO_CAPTURE_PERIOD_DURATION_MSEC,
+ sample_rate,
+ format,
+ channel_count,
+ is_low_latency);
+}
+
static size_t get_output_period_size(uint32_t sample_rate,
audio_format_t format,
int channel_count,
@@ -3764,9 +3908,25 @@
return 0;
}
-static int out_dump(const struct audio_stream *stream __unused,
- int fd __unused)
+static int out_dump(const struct audio_stream *stream, int fd)
{
+ struct stream_out *out = (struct stream_out *)stream;
+
+ // We try to get the lock for consistency,
+ // but it isn't necessary for these variables.
+ // If we're not in standby, we may be blocked on a write.
+ const bool locked = (pthread_mutex_trylock(&out->lock) == 0);
+ dprintf(fd, " Standby: %s\n", out->standby ? "yes" : "no");
+ dprintf(fd, " Frames written: %lld\n", (long long)out->written);
+
+ if (locked) {
+ pthread_mutex_unlock(&out->lock);
+ }
+
+ // dump error info
+ (void)error_log_dump(
+ out->error_log, fd, " " /* prefix */, 0 /* lines */, 0 /* limit_ns */);
+
return 0;
}
@@ -3912,7 +4072,8 @@
*/
if (val & AUDIO_DEVICE_OUT_ALL_A2DP) {
if (!audio_extn_a2dp_source_is_ready()) {
- if (val & AUDIO_DEVICE_OUT_SPEAKER) {
+ if (val &
+ (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
//combo usecase just by pass a2dp
ALOGW("%s: A2DP profile is not ready,routing to speaker only", __func__);
bypass_a2dp = true;
@@ -4000,7 +4161,10 @@
if (!bypass_a2dp) {
select_devices(adev, out->usecase);
} else {
- out->devices = AUDIO_DEVICE_OUT_SPEAKER;
+ if (new_dev & AUDIO_DEVICE_OUT_SPEAKER_SAFE)
+ out->devices = AUDIO_DEVICE_OUT_SPEAKER_SAFE;
+ else
+ out->devices = AUDIO_DEVICE_OUT_SPEAKER;
select_devices(adev, out->usecase);
out->devices = new_dev;
}
@@ -4026,6 +4190,9 @@
pthread_mutex_unlock(&adev->lock);
pthread_mutex_unlock(&out->lock);
+
+ /*handles device and call state changes*/
+ audio_extn_extspk_update(adev->extspk);
}
routing_fail:
@@ -4504,8 +4671,14 @@
return ret;
}
} else if (out->usecase == USECASE_AUDIO_PLAYBACK_VOIP) {
- if (!out->standby)
+ out->app_type_cfg.gain[0] = (int)(left * VOIP_PLAYBACK_VOLUME_MAX);
+ out->app_type_cfg.gain[1] = (int)(right * VOIP_PLAYBACK_VOLUME_MAX);
+ if (!out->standby) {
+ audio_extn_utils_send_app_type_gain(out->dev,
+ out->app_type_cfg.app_type,
+ &out->app_type_cfg.gain[0]);
ret = out_set_voip_volume(stream, left, right);
+ }
out->volume_l = left;
out->volume_r = right;
return ret;
@@ -4545,6 +4718,24 @@
pthread_mutex_unlock(&out->position_query_lock);
}
+#ifdef NO_AUDIO_OUT
+static ssize_t out_write_for_no_output(struct audio_stream_out *stream,
+ const void *buffer __unused, size_t bytes)
+{
+ struct stream_out *out = (struct stream_out *)stream;
+
+ /* No Output device supported other than BT for playback.
+ * Sleep for the amount of buffer duration
+ */
+ lock_output_stream(out);
+ usleep(bytes * 1000000 / audio_stream_out_frame_size(
+ (const struct audio_stream_out *)&out->stream) /
+ out_get_sample_rate(&out->stream.common));
+ pthread_mutex_unlock(&out->lock);
+ return bytes;
+}
+#endif
+
static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
size_t bytes)
{
@@ -4632,7 +4823,8 @@
if ((out->devices & AUDIO_DEVICE_OUT_ALL_A2DP) &&
(audio_extn_a2dp_source_is_suspended())) {
- if (!(out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
+ if (!(out->devices &
+ (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE))) {
if (!(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) {
ret = -EIO;
goto exit;
@@ -4777,14 +4969,19 @@
ALOGV("%s: frames=%zu, frame_size=%zu, bytes_to_write=%zu",
__func__, frames, frame_size, bytes_to_write);
- if (out->usecase == USECASE_INCALL_MUSIC_UPLINK) {
+ if (out->usecase == USECASE_INCALL_MUSIC_UPLINK ||
+#ifndef COMPRESS_VOIP_ENABLED
+ out->usecase == USECASE_AUDIO_PLAYBACK_VOIP ||
+#endif
+ out->usecase == USECASE_INCALL_MUSIC_UPLINK2) {
size_t channel_count = audio_channel_count_from_out_mask(out->channel_mask);
int16_t *src = (int16_t *)buffer;
int16_t *dst = (int16_t *)buffer;
LOG_ALWAYS_FATAL_IF(out->config.channels != 1 || channel_count != 2 ||
out->format != AUDIO_FORMAT_PCM_16_BIT,
- "out_write called for incall music use case with wrong properties");
+ "out_write called for %s use case with wrong properties",
+ use_case_table[out->usecase]);
/*
* FIXME: this can be removed once audio flinger mixer supports
@@ -5446,6 +5643,8 @@
ATRACE_END();
in->pcm = NULL;
}
+ adev->enable_voicerx = false;
+ platform_set_echo_reference(adev, false, AUDIO_DEVICE_NONE);
status = stop_input_stream(in);
}
pthread_mutex_unlock(&adev->lock);
@@ -5455,9 +5654,27 @@
return status;
}
-static int in_dump(const struct audio_stream *stream __unused,
- int fd __unused)
+static int in_dump(const struct audio_stream *stream,
+ int fd)
{
+ struct stream_in *in = (struct stream_in *)stream;
+
+ // We try to get the lock for consistency,
+ // but it isn't necessary for these variables.
+ // If we're not in standby, we may be blocked on a read.
+ const bool locked = (pthread_mutex_trylock(&in->lock) == 0);
+ dprintf(fd, " Standby: %s\n", in->standby ? "yes" : "no");
+ dprintf(fd, " Frames read: %lld\n", (long long)in->frames_read);
+ dprintf(fd, " Frames muted: %lld\n", (long long)in->frames_muted);
+
+ if (locked) {
+ pthread_mutex_unlock(&in->lock);
+ }
+
+ // dump error info
+ (void)error_log_dump(
+ in->error_log, fd, " " /* prefix */, 0 /* lines */, 0 /* limit_ns */);
+
return 0;
}
@@ -5622,9 +5839,40 @@
return str;
}
-static int in_set_gain(struct audio_stream_in *stream __unused,
- float gain __unused)
+static int in_set_gain(struct audio_stream_in *stream,
+ float gain)
{
+ struct stream_in *in = (struct stream_in *)stream;
+ char mixer_ctl_name[128];
+ struct mixer_ctl *ctl;
+ int ctl_value;
+
+ ALOGV("%s: gain %f", __func__, gain);
+
+ if (stream == NULL)
+ return -EINVAL;
+
+ /* in_set_gain() only used to silence MMAP capture for now */
+ if (in->usecase != USECASE_AUDIO_RECORD_MMAP)
+ return -ENOSYS;
+
+ snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "Capture %d Volume", in->pcm_device_id);
+
+ ctl = mixer_get_ctl_by_name(in->dev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGW("%s: Could not get ctl for mixer cmd - %s",
+ __func__, mixer_ctl_name);
+ return -ENOSYS;
+ }
+
+ if (gain < RECORD_GAIN_MIN)
+ gain = RECORD_GAIN_MIN;
+ else if (gain > RECORD_GAIN_MAX)
+ gain = RECORD_GAIN_MAX;
+ ctl_value = (int)(RECORD_VOLUME_CTL_MAX * gain);
+
+ mixer_ctl_set_value(ctl, 0, ctl_value);
+
return 0;
}
@@ -5747,6 +5995,38 @@
return 0;
}
+static int in_get_capture_position(const struct audio_stream_in *stream,
+ int64_t *frames, int64_t *time)
+{
+ if (stream == NULL || frames == NULL || time == NULL) {
+ return -EINVAL;
+ }
+ struct stream_in *in = (struct stream_in *)stream;
+ int ret = -ENOSYS;
+
+ lock_input_stream(in);
+ // note: ST sessions do not close the alsa pcm driver synchronously
+ // on standby. Therefore, we may return an error even though the
+ // pcm stream is still opened.
+ if (in->standby) {
+ ALOGE_IF(in->pcm != NULL && !in->is_st_session,
+ "%s stream in standby but pcm not NULL for non ST session", __func__);
+ goto exit;
+ }
+ if (in->pcm) {
+ struct timespec timestamp;
+ unsigned int avail;
+ if (pcm_get_htimestamp(in->pcm, &avail, ×tamp) == 0) {
+ *frames = in->frames_read + avail;
+ *time = timestamp.tv_sec * 1000000000LL + timestamp.tv_nsec;
+ ret = 0;
+ }
+ }
+exit:
+ pthread_mutex_unlock(&in->lock);
+ return ret;
+}
+
static int add_remove_audio_effect(const struct audio_stream *stream,
effect_handle_t effect,
bool enable)
@@ -5764,10 +6044,24 @@
lock_input_stream(in);
pthread_mutex_lock(&in->dev->lock);
if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
+ in->source == AUDIO_SOURCE_VOICE_RECOGNITION ||
in->dev->mode == AUDIO_MODE_IN_COMMUNICATION) &&
in->enable_aec != enable &&
(memcmp(&desc.type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0)) {
in->enable_aec = enable;
+ if (!enable)
+ platform_set_echo_reference(in->dev, enable, AUDIO_DEVICE_NONE);
+ if (in->source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
+ in->dev->mode == AUDIO_MODE_IN_COMMUNICATION) {
+ in->dev->enable_voicerx = enable;
+ struct audio_usecase *usecase;
+ struct listnode *node;
+ list_for_each(node, &in->dev->usecase_list) {
+ usecase = node_to_item(node, struct audio_usecase, list);
+ if (usecase->type == PCM_PLAYBACK)
+ select_devices(in->dev, usecase->id);
+ }
+ }
if (!in->standby) {
if (enable_disable_effect(in->dev, EFFECT_AEC, enable) == ENOSYS)
select_devices(in->dev, in->usecase);
@@ -6069,13 +6363,25 @@
(property_get_bool("vendor.audio.matrix.limiter.enable", false)))
platform_set_device_params(out, DEVICE_PARAM_LIMITER_ID, 1);
- if (audio_is_linear_pcm(out->format) &&
- out->flags == AUDIO_OUTPUT_FLAG_NONE && direct_dev) {
- pthread_mutex_lock(&adev->lock);
- if (is_hdmi) {
- ALOGV("AUDIO_DEVICE_OUT_AUX_DIGITAL and DIRECT|OFFLOAD, check hdmi caps");
- ret = read_hdmi_sink_caps(out);
- } else if (is_usb_dev) {
+ if (direct_dev &&
+ (audio_is_linear_pcm(out->format) ||
+ config->format == AUDIO_FORMAT_DEFAULT) &&
+ out->flags == AUDIO_OUTPUT_FLAG_NONE) {
+ audio_format_t req_format = config->format;
+ audio_channel_mask_t req_channel_mask = config->channel_mask;
+ uint32_t req_sample_rate = config->sample_rate;
+
+ pthread_mutex_lock(&adev->lock);
+ if (is_hdmi) {
+ ALOGV("AUDIO_DEVICE_OUT_AUX_DIGITAL and DIRECT|OFFLOAD, check hdmi caps");
+ ret = read_hdmi_sink_caps(out);
+ if (config->sample_rate == 0)
+ config->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+ if (config->channel_mask == AUDIO_CHANNEL_NONE)
+ config->channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
+ if (config->format == AUDIO_FORMAT_DEFAULT)
+ config->format = AUDIO_FORMAT_PCM_16_BIT;
+ } else if (is_usb_dev) {
ret = read_usb_sup_params_and_compare(true /*is_playback*/,
&config->format,
&out->supported_formats[0],
@@ -6087,19 +6393,55 @@
&out->supported_sample_rates[0],
MAX_SUPPORTED_SAMPLE_RATES);
ALOGV("plugged dev USB ret %d", ret);
- } else {
- ret = -1;
}
+
pthread_mutex_unlock(&adev->lock);
if (ret != 0) {
if (ret == -ENOSYS) {
/* ignore and go with default */
ret = 0;
- } else {
+ }
+ // For MMAP NO IRQ, allow conversions in ADSP
+ else if (is_hdmi || (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) == 0)
+ goto error_open;
+ else {
ALOGE("error reading direct dev sink caps");
goto error_open;
}
+
+ if (req_sample_rate != 0 && config->sample_rate != req_sample_rate)
+ config->sample_rate = req_sample_rate;
+ if (req_channel_mask != AUDIO_CHANNEL_NONE && config->channel_mask != req_channel_mask)
+ config->channel_mask = req_channel_mask;
+ if (req_format != AUDIO_FORMAT_DEFAULT && config->format != req_format)
+ config->format = req_format;
}
+
+ out->sample_rate = config->sample_rate;
+ out->channel_mask = config->channel_mask;
+ out->format = config->format;
+ if (is_hdmi) {
+ out->usecase = USECASE_AUDIO_PLAYBACK_HIFI;
+ out->config = pcm_config_hdmi_multi;
+ } else if (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) {
+ out->usecase = USECASE_AUDIO_PLAYBACK_MMAP;
+ out->config = pcm_config_mmap_playback;
+ out->stream.start = out_start;
+ out->stream.stop = out_stop;
+ out->stream.create_mmap_buffer = out_create_mmap_buffer;
+ out->stream.get_mmap_position = out_get_mmap_position;
+ } else {
+ out->usecase = USECASE_AUDIO_PLAYBACK_HIFI;
+ out->config = pcm_config_hifi;
+ }
+
+ out->config.rate = out->sample_rate;
+ out->config.channels = audio_channel_count_from_out_mask(out->channel_mask);
+ if (is_hdmi) {
+ out->config.period_size = HDMI_MULTI_PERIOD_BYTES / (out->config.channels *
+ audio_bytes_per_sample(out->format));
+ }
+ out->config.format = pcm_format_from_audio_format(out->format);
}
/* Init use case and pcm_config */
@@ -6107,9 +6449,10 @@
if (out->flags == (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_VOIP_RX) &&
(out->sample_rate == 8000 || out->sample_rate == 16000 ||
out->sample_rate == 32000 || out->sample_rate == 48000)) {
- out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_MONO;
- out->channel_mask = AUDIO_CHANNEL_OUT_MONO;
+ //FIXME: add support for MONO stream configuration when audioflinger mixer supports it
+ out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
out->usecase = USECASE_AUDIO_PLAYBACK_VOIP;
+ out->format = AUDIO_FORMAT_PCM_16_BIT;
out->config = default_pcm_config_voip_copp;
out->config.period_size = VOIP_IO_BUF_SIZE(out->sample_rate, DEFAULT_VOIP_BUF_DURATION_MS, DEFAULT_VOIP_BIT_DEPTH_BYTE)/2;
@@ -6442,26 +6785,60 @@
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;
+ switch (config->sample_rate) {
+ case 0:
+ out->sample_rate = AFE_PROXY_SAMPLING_RATE;
+ break;
+ case 8000:
+ case 16000:
+ case 48000:
+ out->sample_rate = config->sample_rate;
+ break;
+ default:
+ ALOGE("%s: Unsupported sampling rate %d for Telephony TX", __func__,
+ config->sample_rate);
+ config->sample_rate = AFE_PROXY_SAMPLING_RATE;
+ ret = -EINVAL;
+ break;
}
- 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;
+ //FIXME: add support for MONO stream configuration when audioflinger mixer supports it
+ switch (config->channel_mask) {
+ case AUDIO_CHANNEL_NONE:
+ out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ break;
+ case AUDIO_CHANNEL_OUT_STEREO:
+ out->channel_mask = config->channel_mask;
+ break;
+ default:
+ ALOGE("%s: Unsupported channel mask %#x for Telephony TX", __func__,
+ config->channel_mask);
+ config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ ret = -EINVAL;
+ break;
}
- out->format = config->format;
+ switch (config->format) {
+ case AUDIO_FORMAT_DEFAULT:
+ out->format = AUDIO_FORMAT_PCM_16_BIT;
+ break;
+ case AUDIO_FORMAT_PCM_16_BIT:
+ out->format = config->format;
+ break;
+ default:
+ ALOGE("%s: Unsupported format %#x for Telephony TX", __func__,
+ config->format);
+ config->format = AUDIO_FORMAT_PCM_16_BIT;
+ ret = -EINVAL;
+ break;
+ }
+ if (ret != 0)
+ goto error_open;
+
out->usecase = USECASE_AUDIO_PLAYBACK_AFE_PROXY;
out->config = pcm_config_afe_proxy_playback;
+ out->config.rate = out->sample_rate;
+ out->config.channels =
+ audio_channel_count_from_out_mask(out->channel_mask);
+ out->config.format = pcm_format_from_audio_format(out->format);
adev->voice_tx_output = out;
} else {
unsigned int channels = 0;
@@ -6518,6 +6895,9 @@
ret = -EINVAL;
goto error_open;
}
+ } else if (flags & AUDIO_OUTPUT_FLAG_TTS) {
+ out->usecase = USECASE_AUDIO_PLAYBACK_TTS;
+ out->config = pcm_config_deep_buffer;
} else {
/* primary path is the default path selected if no other outputs are available/suitable */
out->usecase = USECASE_AUDIO_PLAYBACK_PRIMARY;
@@ -6594,7 +6974,11 @@
out->stream.common.remove_audio_effect = out_remove_audio_effect;
out->stream.get_latency = out_get_latency;
out->stream.set_volume = out_set_volume;
+#ifdef NO_AUDIO_OUT
+ out->stream.write = out_write_for_no_output;
+#else
out->stream.write = out_write;
+#endif
out->stream.get_render_position = out_get_render_position;
out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
out->stream.get_presentation_position = out_get_presentation_position;
@@ -6615,6 +6999,10 @@
register_channel_mask(out->channel_mask, out->supported_channel_masks);
register_sample_rate(out->sample_rate, out->supported_sample_rates);
+ out->error_log = error_log_create(
+ ERROR_LOG_ENTRIES,
+ 1000000000 /* aggregate consecutive identical errors within one second in ns */);
+
/*
By locking output stream before registering, we allow the callback
to update stream's state only after stream's initial state is set to
@@ -6627,6 +7015,8 @@
pthread_mutex_unlock(&adev->lock);
pthread_mutex_unlock(&out->lock);
+ stream_app_type_cfg_init(&out->app_type_cfg);
+
*stream_out = &out->stream;
ALOGD("%s: Stream (%p) picks up usecase (%s)", __func__, &out->stream,
use_case_table[out->usecase]);
@@ -6727,6 +7117,9 @@
if (adev->voice_tx_output == out)
adev->voice_tx_output = NULL;
+ error_log_destroy(out->error_log);
+ out->error_log = NULL;
+
if (adev->primary_output == out)
adev->primary_output = NULL;
@@ -6744,6 +7137,7 @@
int val;
int ret;
int status = 0;
+ bool a2dp_reconfig = false;
ALOGD("%s: enter: %s", __func__, kvpairs);
parms = str_parms_create_str(kvpairs);
@@ -6786,6 +7180,7 @@
adev->screen_off = true;
}
+#ifndef MAXXAUDIO_QDSP_ENABLED
ret = str_parms_get_int(parms, "rotation", &val);
if (ret >= 0) {
bool reverse_speakers = false;
@@ -6811,6 +7206,7 @@
platform_check_and_set_swap_lr_channels(adev, reverse_speakers);
}
}
+#endif
ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_SCO_WB, value, sizeof(value));
if (ret >= 0) {
@@ -6874,8 +7270,11 @@
}
}
- ret = str_parms_get_str(parms,"reconfigA2dp", value, sizeof(value));
- if (ret >= 0) {
+ audio_extn_hfp_set_parameters(adev, parms);
+ audio_extn_ma_set_parameters(adev, parms);
+
+ status = audio_extn_a2dp_set_parameters(parms, &a2dp_reconfig);
+ if (ret >= 0 && a2dp_reconfig) {
struct audio_usecase *usecase;
struct listnode *node;
list_for_each(node, &adev->usecase_list) {
@@ -6973,6 +7372,7 @@
pthread_mutex_lock(&adev->lock);
audio_extn_get_parameters(adev, query, reply);
voice_get_parameters(adev, query, reply);
+ audio_extn_a2dp_get_parameters(query, reply);
platform_get_parameters(adev->platform, query, reply);
pthread_mutex_unlock(&adev->lock);
@@ -6994,6 +7394,9 @@
{
int ret;
struct audio_device *adev = (struct audio_device *)dev;
+
+ audio_extn_extspk_set_voice_vol(adev->extspk, volume);
+
pthread_mutex_lock(&adev->lock);
/* cache volume */
ret = voice_set_volume(adev, volume);
@@ -7066,12 +7469,16 @@
static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
{
int ret;
+ struct audio_device *adev = (struct audio_device *)dev;
pthread_mutex_lock(&adev->lock);
ALOGD("%s state %d\n", __func__, state);
ret = voice_set_mic_mute((struct audio_device *)dev, state);
+
if (adev->ext_hw_plugin)
ret = audio_extn_ext_hw_plugin_set_mic_mute(adev->ext_hw_plugin, state);
+
+ adev->mic_muted = state;
pthread_mutex_unlock(&adev->lock);
return ret;
@@ -7088,6 +7495,11 @@
{
int channel_count = audio_channel_count_from_in_mask(config->channel_mask);
+ /* Don't know if USB HIFI in this context so use true to be conservative */
+ if (check_input_parameters(config->sample_rate, config->format, channel_count,
+ true /*is_usb_hifi */) != 0)
+ return 0;
+
return get_input_buffer_size(config->sample_rate, config->format, channel_count,
false /* is_low_latency: since we don't know, be conservative */);
}
@@ -7211,7 +7623,8 @@
channel_count = audio_channel_count_from_in_mask(config->channel_mask);
- if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0)
+ if (check_input_parameters(config->sample_rate, config->format, channel_count,
+ false) != 0)
return -EINVAL;
}
@@ -7243,6 +7656,7 @@
in->stream.set_gain = in_set_gain;
in->stream.read = in_read;
in->stream.get_input_frames_lost = in_get_input_frames_lost;
+ in->stream.get_capture_position = in_get_capture_position;
in->stream.get_active_microphones = in_get_active_microphones;
in->device = devices;
@@ -7254,6 +7668,18 @@
in->bit_width = 16;
in->af_period_multiplier = 1;
+ ALOGV("%s: source = %d, config->channel_mask = %d", __func__, source, config->channel_mask);
+ if (source == AUDIO_SOURCE_VOICE_UPLINK ||
+ source == AUDIO_SOURCE_VOICE_DOWNLINK) {
+ /* Force channel config requested to mono if incall
+ record is being requested for only uplink/downlink */
+ if (config->channel_mask != AUDIO_CHANNEL_IN_MONO) {
+ config->channel_mask = AUDIO_CHANNEL_IN_MONO;
+ ret = -EINVAL;
+ goto err_open;
+ }
+ }
+
/* Update config params with the requested sample rate and channels */
if ((in->device == AUDIO_DEVICE_IN_TELEPHONY_RX) &&
(adev->mode != AUDIO_MODE_IN_CALL)) {
@@ -7329,6 +7755,21 @@
in->usecase = USECASE_AUDIO_RECORD_LOW_LATENCY;
#endif
in->realtime = may_use_noirq_mode(adev, in->usecase, in->flags);
+ if (!in->realtime) {
+ in->config = pcm_config_audio_capture;
+ frame_size = audio_stream_in_frame_size(&in->stream);
+ buffer_size = get_input_buffer_size(config->sample_rate,
+ config->format,
+ channel_count,
+ is_low_latency);
+ in->config.period_size = buffer_size / frame_size;
+ in->config.rate = config->sample_rate;
+ in->af_period_multiplier = 1;
+ } else {
+ // period size is left untouched for rt mode playback
+ in->config = pcm_config_audio_capture_rt;
+ in->af_period_multiplier = af_period_multiplier;
+ }
}
if ((config->sample_rate == LOW_LATENCY_CAPTURE_SAMPLE_RATE) &&
@@ -7397,6 +7838,25 @@
in->config.channels = channel_count;
in->config.rate = config->sample_rate;
in->sample_rate = config->sample_rate;
+ in->af_period_multiplier = 1;
+ } else if (in->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
+ in->flags & AUDIO_INPUT_FLAG_VOIP_TX &&
+ (config->sample_rate == 8000 ||
+ config->sample_rate == 16000 ||
+ config->sample_rate == 32000 ||
+ config->sample_rate == 48000) &&
+ channel_count == 1) {
+ in->usecase = USECASE_AUDIO_RECORD_VOIP;
+ in->config = pcm_config_audio_capture;
+ frame_size = audio_stream_in_frame_size(&in->stream);
+ buffer_size = get_stream_buffer_size(VOIP_CAPTURE_PERIOD_DURATION_MSEC,
+ config->sample_rate,
+ config->format,
+ channel_count, false /*is_low_latency*/);
+ in->config.period_size = buffer_size / frame_size;
+ in->config.period_count = VOIP_CAPTURE_PERIOD_COUNT;
+ in->config.rate = config->sample_rate;
+ in->af_period_multiplier = 1;
} else {
int ret_val;
pthread_mutex_lock(&adev->lock);
@@ -7441,6 +7901,7 @@
}
in->config.period_size = buffer_size / frame_size;
+ in->af_period_multiplier = 1;
if (in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
/* optionally use VOIP usecase depending on config(s) */
@@ -7462,6 +7923,10 @@
register_channel_mask(in->channel_mask, in->supported_channel_masks);
register_sample_rate(in->sample_rate, in->supported_sample_rates);
+ in->error_log = error_log_create(
+ ERROR_LOG_ENTRIES,
+ 1000000000 /* aggregate consecutive identical errors within one second */);
+
/* This stream could be for sound trigger lab,
get sound trigger pcm if present */
audio_extn_sound_trigger_check_and_get_session(in);
@@ -7473,6 +7938,8 @@
pthread_mutex_unlock(&adev->lock);
pthread_mutex_unlock(&in->lock);
+ stream_app_type_cfg_init(&in->app_type_cfg);
+
*stream_in = &in->stream;
ALOGV("%s: exit", __func__);
return ret;
@@ -7501,6 +7968,9 @@
if (!adev->active_input && !audio_extn_hfp_is_active(adev))
platform_set_echo_reference(adev, false, AUDIO_DEVICE_NONE);
+ error_log_destroy(in->error_log);
+ in->error_log = NULL;
+
if (in == NULL) {
ALOGE("%s: audio_stream_in ptr is NULL", __func__);
return;
@@ -7541,6 +8011,137 @@
return;
}
+/* verifies input and output devices and their capabilities.
+ *
+ * This verification is required when enabling extended bit-depth or
+ * sampling rates, as not all qcom products support it.
+ *
+ * Suitable for calling only on initialization such as adev_open().
+ * It fills the audio_device use_case_table[] array.
+ *
+ * Has a side-effect that it needs to configure audio routing / devices
+ * in order to power up the devices and read the device parameters.
+ * It does not acquire any hw device lock. Should restore the devices
+ * back to "normal state" upon completion.
+ */
+static int adev_verify_devices(struct audio_device *adev)
+{
+ /* enumeration is a bit difficult because one really wants to pull
+ * the use_case, device id, etc from the hidden pcm_device_table[].
+ * In this case there are the following use cases and device ids.
+ *
+ * [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {0, 0},
+ * [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {15, 15},
+ * [USECASE_AUDIO_PLAYBACK_HIFI] = {1, 1},
+ * [USECASE_AUDIO_PLAYBACK_OFFLOAD] = {9, 9},
+ * [USECASE_AUDIO_RECORD] = {0, 0},
+ * [USECASE_AUDIO_RECORD_LOW_LATENCY] = {15, 15},
+ * [USECASE_VOICE_CALL] = {2, 2},
+ *
+ * USECASE_AUDIO_PLAYBACK_OFFLOAD, USECASE_AUDIO_PLAYBACK_HIFI omitted.
+ * USECASE_VOICE_CALL omitted, but possible for either input or output.
+ */
+
+ /* should be the usecases enabled in adev_open_input_stream() */
+ static const int test_in_usecases[] = {
+ USECASE_AUDIO_RECORD,
+ USECASE_AUDIO_RECORD_LOW_LATENCY, /* does not appear to be used */
+ };
+ /* should be the usecases enabled in adev_open_output_stream()*/
+ static const int test_out_usecases[] = {
+ USECASE_AUDIO_PLAYBACK_DEEP_BUFFER,
+ USECASE_AUDIO_PLAYBACK_LOW_LATENCY,
+ };
+ static const usecase_type_t usecase_type_by_dir[] = {
+ PCM_PLAYBACK,
+ PCM_CAPTURE,
+ };
+ static const unsigned flags_by_dir[] = {
+ PCM_OUT,
+ PCM_IN,
+ };
+
+ size_t i;
+ unsigned dir;
+ const unsigned card_id = adev->snd_card;
+
+ for (dir = 0; dir < 2; ++dir) {
+ const usecase_type_t usecase_type = usecase_type_by_dir[dir];
+ const unsigned flags_dir = flags_by_dir[dir];
+ const size_t testsize =
+ dir ? ARRAY_SIZE(test_in_usecases) : ARRAY_SIZE(test_out_usecases);
+ const int *testcases =
+ dir ? test_in_usecases : test_out_usecases;
+ const audio_devices_t audio_device =
+ dir ? AUDIO_DEVICE_IN_BUILTIN_MIC : AUDIO_DEVICE_OUT_SPEAKER;
+
+ for (i = 0; i < testsize; ++i) {
+ const audio_usecase_t audio_usecase = testcases[i];
+ int device_id;
+ struct pcm_params **pparams;
+ struct stream_out out;
+ struct stream_in in;
+ struct audio_usecase uc_info;
+ int retval;
+
+ pparams = &adev->use_case_table[audio_usecase];
+ pcm_params_free(*pparams); /* can accept null input */
+ *pparams = NULL;
+
+ /* find the device ID for the use case (signed, for error) */
+ device_id = platform_get_pcm_device_id(audio_usecase, usecase_type);
+ if (device_id < 0)
+ continue;
+
+ /* prepare structures for device probing */
+ memset(&uc_info, 0, sizeof(uc_info));
+ uc_info.id = audio_usecase;
+ uc_info.type = usecase_type;
+ if (dir) {
+ adev->active_input = ∈
+ memset(&in, 0, sizeof(in));
+ in.device = audio_device;
+ in.source = AUDIO_SOURCE_VOICE_COMMUNICATION;
+ uc_info.stream.in = ∈
+ } else {
+ adev->active_input = NULL;
+ }
+ memset(&out, 0, sizeof(out));
+ out.devices = audio_device; /* only field needed in select_devices */
+ uc_info.stream.out = &out;
+ uc_info.devices = audio_device;
+ 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 device - similar to start_(in/out)put_stream() */
+ retval = select_devices(adev, audio_usecase);
+ if (retval >= 0) {
+ *pparams = pcm_params_get(card_id, device_id, flags_dir);
+#if LOG_NDEBUG == 0
+ if (*pparams) {
+ ALOGV("%s: (%s) card %d device %d", __func__,
+ dir ? "input" : "output", card_id, device_id);
+ pcm_params_to_string(*pparams, info, ARRAY_SIZE(info));
+ } else {
+ ALOGV("%s: cannot locate card %d device %d", __func__, card_id, device_id);
+ }
+#endif
+ }
+
+ /* deselect device - similar to stop_(in/out)put_stream() */
+ /* 1. Get and set stream specific mixer controls */
+ retval = disable_audio_route(adev, &uc_info);
+ /* 2. Disable the rx device */
+ retval = disable_snd_device(adev,
+ dir ? uc_info.in_snd_device : uc_info.out_snd_device);
+ list_remove(&uc_info.list);
+ }
+ }
+ adev->active_input = NULL; /* restore adev state */
+ return 0;
+}
+
int adev_create_audio_patch(struct audio_hw_device *dev,
unsigned int num_sources,
const struct audio_port_config *sources,
@@ -7584,6 +8185,7 @@
static int adev_close(hw_device_t *device)
{
+ size_t i;
struct audio_device *adev = (struct audio_device *)device;
if (!adev)
@@ -7595,6 +8197,8 @@
audio_extn_snd_mon_unregister_listener(adev);
audio_extn_sound_trigger_deinit(adev);
audio_extn_listen_deinit(adev);
+ audio_extn_ma_deinit();
+ audio_extn_extspk_deinit(adev->extspk);
audio_extn_utils_release_streams_cfg_lists(
&adev->streams_output_cfg_list,
&adev->streams_input_cfg_list);
@@ -7604,6 +8208,9 @@
audio_extn_gef_deinit();
free(adev->snd_dev_ref_cnt);
platform_deinit(adev->platform);
+ for (i = 0; i < ARRAY_SIZE(adev->use_case_table); ++i) {
+ pcm_params_free(adev->use_case_table[i]);
+ }
if (adev->adm_deinit)
adev->adm_deinit(adev->adm_data);
qahwi_deinit(device);
@@ -7854,6 +8461,8 @@
return -EINVAL;
}
+ adev->extspk = audio_extn_extspk_init(adev);
+
if (audio_extn_qaf_is_enabled()) {
ret = audio_extn_qaf_init(adev);
if (ret < 0) {
@@ -7950,6 +8559,7 @@
}
}
+ adev->enable_voicerx = false;
adev->bt_wb_speech_enabled = false;
//initialize this to false for now,
//this will be set to true through set param
@@ -7957,6 +8567,10 @@
audio_extn_ds2_enable(adev);
*device = &adev->device.common;
+
+ if (k_enable_extended_precision)
+ adev_verify_devices(adev);
+
adev->dsp_bit_width_enforce_mode =
adev_init_dsp_bit_width_enforce_mode(adev->mixer);
@@ -7968,7 +8582,8 @@
char value[PROPERTY_VALUE_MAX];
int trial;
- if (property_get("vendor.audio_hal.period_size", value, NULL) > 0) {
+ if ((property_get("vendor.audio_hal.period_size", value, NULL) > 0) ||
+ (property_get("audio_hal.period_size", value, NULL) > 0)) {
trial = atoi(value);
if (period_size_is_plausible_for_low_latency(trial)) {
pcm_config_low_latency.period_size = trial;
@@ -7977,7 +8592,8 @@
configured_low_latency_capture_period_size = trial;
}
}
- if (property_get("vendor.audio_hal.in_period_size", value, NULL) > 0) {
+ if ((property_get("vendor.audio_hal.in_period_size", value, NULL) > 0) ||
+ (property_get("audio_hal.in_period_size", value, NULL) > 0)) {
trial = atoi(value);
if (period_size_is_plausible_for_low_latency(trial)) {
configured_low_latency_capture_period_size = trial;
@@ -7986,7 +8602,8 @@
adev->mic_break_enabled = property_get_bool("vendor.audio.mic_break", false);
- if (property_get("vendor.audio_hal.period_multiplier", value, NULL) > 0) {
+ if ((property_get("vendor.audio_hal.period_multiplier",value,NULL) > 0) ||
+ (property_get("audio_hal.period_multiplier",value,NULL) > 0)) {
af_period_multiplier = atoi(value);
if (af_period_multiplier < 0)
af_period_multiplier = 2;
@@ -7996,6 +8613,8 @@
ALOGV("new period_multiplier = %d", af_period_multiplier);
}
+ audio_extn_ma_init(adev->platform);
+
adev->multi_offload_enable = property_get_bool("vendor.audio.offload.multiple.enabled", false);
pthread_mutex_unlock(&adev_init_lock);
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 8ae84e8..7b74d16 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -39,12 +39,14 @@
#define QCOM_AUDIO_HW_H
#include <stdlib.h>
+#include <cutils/str_parms.h>
#include <cutils/list.h>
#include <hardware/audio.h>
#include <tinyalsa/asoundlib.h>
#include <tinycompress/tinycompress.h>
#include <audio_route/audio_route.h>
+#include <audio_utils/ErrorLog.h>
#include "audio_defs.h"
#include "voice.h"
#include "audio_hw_extn_api.h"
@@ -83,13 +85,16 @@
#define ACDB_DEV_TYPE_OUT 1
#define ACDB_DEV_TYPE_IN 2
-#define MAX_SUPPORTED_CHANNEL_MASKS 14
+/* support positional and index masks to 8ch */
+#define MAX_SUPPORTED_CHANNEL_MASKS (2 * FCC_8)
#define MAX_SUPPORTED_FORMATS 15
#define MAX_SUPPORTED_SAMPLE_RATES 7
#define DEFAULT_HDMI_OUT_CHANNELS 2
#define DEFAULT_HDMI_OUT_SAMPLE_RATE 48000
#define DEFAULT_HDMI_OUT_FORMAT AUDIO_FORMAT_PCM_16_BIT
+#define ERROR_LOG_ENTRIES 16
+
#define SND_CARD_STATE_OFFLINE 0
#define SND_CARD_STATE_ONLINE 1
@@ -142,6 +147,7 @@
USECASE_AUDIO_PLAYBACK_ULL,
USECASE_AUDIO_PLAYBACK_MMAP,
USECASE_AUDIO_PLAYBACK_HIFI,
+ USECASE_AUDIO_PLAYBACK_TTS,
/* FM usecase */
USECASE_AUDIO_PLAYBACK_FM,
@@ -192,6 +198,7 @@
USECASE_AUDIO_PLAYBACK_AFE_PROXY,
USECASE_AUDIO_RECORD_AFE_PROXY,
+ USECASE_AUDIO_DSM_FEEDBACK,
USECASE_AUDIO_PLAYBACK_SILENCE,
@@ -256,6 +263,7 @@
int sample_rate;
uint32_t bit_width;
int app_type;
+ int gain[2];
};
struct stream_config {
@@ -363,6 +371,8 @@
mix_matrix_params_t pan_scale_params;
mix_matrix_params_t downmix_params;
bool set_dual_mono;
+
+ error_log_t *error_log;
};
struct stream_in {
@@ -401,6 +411,11 @@
audio_channel_mask_t supported_channel_masks[MAX_SUPPORTED_CHANNEL_MASKS + 1];
audio_format_t supported_formats[MAX_SUPPORTED_FORMATS + 1];
uint32_t supported_sample_rates[MAX_SUPPORTED_SAMPLE_RATES + 1];
+
+ int64_t frames_read; /* total frames read, not cleared when entering standby */
+ int64_t frames_muted; /* total frames muted, not cleared when entering standby */
+
+ error_log_t *error_log;
};
typedef enum {
@@ -410,7 +425,8 @@
VOIP_CALL,
PCM_HFP_CALL,
TRANSCODE_LOOPBACK_RX,
- TRANSCODE_LOOPBACK_TX
+ TRANSCODE_LOOPBACK_TX,
+ USECASE_TYPE_MAX
} usecase_type_t;
union stream_ptr {
@@ -498,6 +514,9 @@
bool allow_afe_proxy_usage;
bool is_charging; // from battery listener
bool mic_break_enabled;
+ bool enable_hfp;
+ bool mic_muted;
+ bool enable_voicerx;
int snd_card;
card_status_t card_status;
@@ -505,6 +524,7 @@
unsigned int cur_codec_backend_bit_width;
bool is_channel_status_set;
void *platform;
+ void *extspk;
unsigned int offload_usecases_state;
void *visualizer_lib;
int (*visualizer_start_output)(audio_io_handle_t, int);
@@ -547,6 +567,17 @@
unsigned int interactive_usecase_state;
bool dp_allowed_for_voice;
void *ext_hw_plugin;
+
+ /* logging */
+ snd_device_t last_logged_snd_device[AUDIO_USECASE_MAX][2]; /* [out, in] */
+
+ /* The pcm_params use_case_table is loaded by adev_verify_devices() upon
+ * calling adev_open().
+ *
+ * If an entry is not NULL, it can be used to determine if extended precision
+ * or other capabilities are present for the device corresponding to that usecase.
+ */
+ struct pcm_params *use_case_table[AUDIO_USECASE_MAX];
};
int select_devices(struct audio_device *adev,
diff --git a/hal/msm8974/hw_info.c b/hal/msm8974/hw_info.c
index 5d06483..3d91d84 100755
--- a/hal/msm8974/hw_info.c
+++ b/hal/msm8974/hw_info.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -33,7 +33,7 @@
#include <stdlib.h>
#include <dlfcn.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <cutils/str_parms.h>
#include "audio_hw.h"
#include "platform.h"
@@ -85,8 +85,8 @@
SND_DEVICE_IN_VOICE_REC_DMIC_STEREO,
SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE,
SND_DEVICE_IN_QUAD_MIC,
- SND_DEVICE_IN_HANDSET_STEREO_DMIC,
- SND_DEVICE_IN_SPEAKER_STEREO_DMIC,
+ SND_DEVICE_IN_HANDSET_DMIC_STEREO,
+ SND_DEVICE_IN_SPEAKER_DMIC_STEREO,
};
static const snd_device_t tomtom_msm8994_CDP_variant_devices[] = {
@@ -106,8 +106,8 @@
SND_DEVICE_IN_VOICE_REC_DMIC_STEREO,
SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE,
SND_DEVICE_IN_QUAD_MIC,
- SND_DEVICE_IN_HANDSET_STEREO_DMIC,
- SND_DEVICE_IN_SPEAKER_STEREO_DMIC,
+ SND_DEVICE_IN_HANDSET_DMIC_STEREO,
+ SND_DEVICE_IN_SPEAKER_DMIC_STEREO,
};
static const snd_device_t tomtom_stp_variant_devices[] = {
@@ -206,8 +206,8 @@
SND_DEVICE_IN_VOICE_REC_DMIC_STEREO,
SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE,
SND_DEVICE_IN_QUAD_MIC,
- SND_DEVICE_IN_HANDSET_STEREO_DMIC,
- SND_DEVICE_IN_SPEAKER_STEREO_DMIC,
+ SND_DEVICE_IN_HANDSET_DMIC_STEREO,
+ SND_DEVICE_IN_SPEAKER_DMIC_STEREO,
};
@@ -239,8 +239,8 @@
SND_DEVICE_IN_HANDSET_DMIC_NS,
SND_DEVICE_IN_HANDSET_DMIC_AEC,
SND_DEVICE_IN_HANDSET_DMIC_AEC_NS,
- SND_DEVICE_IN_HANDSET_STEREO_DMIC,
- SND_DEVICE_IN_SPEAKER_STEREO_DMIC,
+ SND_DEVICE_IN_HANDSET_DMIC_STEREO,
+ SND_DEVICE_IN_SPEAKER_DMIC_STEREO,
SND_DEVICE_IN_VOICE_SPEAKER_DMIC,
SND_DEVICE_IN_SPEAKER_DMIC_AEC,
SND_DEVICE_IN_SPEAKER_DMIC_NS,
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 4cf0857..37eae22 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -31,11 +31,12 @@
#include <dlfcn.h>
#include <fcntl.h>
#include <sys/ioctl.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <cutils/properties.h>
#include <cutils/str_parms.h>
#include <audio_hw.h>
#include <platform_api.h>
+#include <pthread.h>
#include <unistd.h>
#include "platform.h"
#include "audio_extn.h"
@@ -55,9 +56,10 @@
#define MIXER_FILE_DELIMITER "_"
#define MIXER_FILE_EXT ".xml"
+#define MIXER_XML_BASE_STRING "mixer_paths"
+#define MIXER_XML_DEFAULT_PATH "mixer_paths.xml"
+
#ifdef LINUX_ENABLED
-#define MIXER_XML_BASE_STRING "/etc/mixer_paths"
-#define MIXER_XML_DEFAULT_PATH "/etc/mixer_paths.xml"
#define PLATFORM_INFO_XML_PATH_INTCODEC "/etc/audio_platform_info_intcodec.xml"
#define PLATFORM_INFO_XML_PATH_SKUSH "/etc/audio_platform_info_skush.xml"
#define PLATFORM_INFO_XML_PATH_SKUW "/etc/audio_platform_info_skuw.xml"
@@ -69,8 +71,6 @@
#define PLATFORM_INFO_XML_PATH_WSA "/etc/audio_platform_info_wsa.xml"
#define PLATFORM_INFO_XML_PATH_TDM "/etc/audio_platform_info_tdm.xml"
#else
-#define MIXER_XML_BASE_STRING "/vendor/etc/mixer_paths"
-#define MIXER_XML_DEFAULT_PATH "/vendor/etc/mixer_paths.xml"
#define PLATFORM_INFO_XML_PATH_INTCODEC "/vendor/etc/audio_platform_info_intcodec.xml"
#define PLATFORM_INFO_XML_PATH_SKUSH "/vendor/etc/audio_platform_info_skush.xml"
#define PLATFORM_INFO_XML_PATH_SKUW "/vendor/etc/audio_platform_info_skuw.xml"
@@ -88,6 +88,13 @@
#include <sound/devdep_params.h>
#endif
+#include <resolv.h>
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
+#define TOSTRING_(x) #x
+#define TOSTRING(x) TOSTRING_(x)
+
#define LIB_ACDB_LOADER "libacdbloader.so"
#define CVD_VERSION_MIXER_CTL "CVD Version"
@@ -115,8 +122,8 @@
#define EDID_FORMAT_LPCM 1
/* fallback app type if the default app type from acdb loader fails */
-#define DEFAULT_APP_TYPE_RX_PATH 0x11130
-#define DEFAULT_APP_TYPE_TX_PATH 0x11132
+#define DEFAULT_APP_TYPE_RX_PATH 69936
+#define DEFAULT_APP_TYPE_TX_PATH 69938
#define SAMPLE_RATE_8KHZ 8000
#define SAMPLE_RATE_16KHZ 16000
@@ -207,6 +214,24 @@
CAL_MODE_RTAC = 0x4
};
+#define PLATFORM_CONFIG_KEY_OPERATOR_INFO "operator_info"
+
+struct operator_info {
+ struct listnode list;
+ char *name;
+ char *mccmnc;
+};
+
+struct operator_specific_device {
+ struct listnode list;
+ char *operator;
+ char *mixer_path;
+ int acdb_id;
+};
+
+static struct listnode operator_info_list;
+static struct listnode *operator_specific_device_table[SND_DEVICE_MAX];
+
acdb_loader_get_calibration_t acdb_loader_get_calibration;
typedef struct codec_backend_cfg {
@@ -234,6 +259,7 @@
struct audio_device *adev;
bool fluence_in_spkr_mode;
bool fluence_in_voice_call;
+ bool fluence_in_voice_comm;
bool fluence_in_voice_rec;
bool fluence_in_audio_rec;
bool fluence_in_hfp_call;
@@ -289,6 +315,7 @@
int hw_dep_fd;
char cvd_version[MAX_CVD_VERSION_STRING_SIZE];
char snd_card_name[MAX_SND_CARD_STRING_SIZE];
+ int max_vol_index;
int source_mic_type;
int max_mic_count;
bool is_dsd_supported;
@@ -319,6 +346,8 @@
MULTIMEDIA2_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_HIFI] = {MULTIMEDIA2_PCM_DEVICE,
MULTIMEDIA2_PCM_DEVICE},
+ [USECASE_AUDIO_PLAYBACK_TTS] = {MULTIMEDIA2_PCM_DEVICE,
+ MULTIMEDIA2_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_OFFLOAD] =
{PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
[USECASE_AUDIO_PLAYBACK_OFFLOAD2] =
@@ -392,6 +421,7 @@
AFE_PROXY_RECORD_PCM_DEVICE},
[USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
AFE_PROXY_RECORD_PCM_DEVICE},
+ [USECASE_AUDIO_DSM_FEEDBACK] = {QUAT_MI2S_PCM_DEVICE, QUAT_MI2S_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_SILENCE] = {MULTIMEDIA9_PCM_DEVICE, -1},
[USECASE_AUDIO_TRANSCODE_LOOPBACK_RX] = {TRANSCODE_LOOPBACK_RX_DEV_ID, -1},
[USECASE_AUDIO_TRANSCODE_LOOPBACK_TX] = {-1, TRANSCODE_LOOPBACK_TX_DEV_ID},
@@ -427,15 +457,19 @@
[SND_DEVICE_OUT_SPEAKER_EXTERNAL_2] = "speaker-ext-2",
[SND_DEVICE_OUT_SPEAKER_VBAT] = "speaker-vbat",
[SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
+ [SND_DEVICE_OUT_SPEAKER_SAFE] = "speaker-safe",
[SND_DEVICE_OUT_HEADPHONES] = "headphones",
[SND_DEVICE_OUT_HEADPHONES_DSD] = "headphones-dsd",
[SND_DEVICE_OUT_HEADPHONES_44_1] = "headphones-44.1",
[SND_DEVICE_OUT_LINE] = "line",
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
+ [SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES] = "speaker-safe-and-headphones",
[SND_DEVICE_OUT_SPEAKER_AND_LINE] = "speaker-and-line",
+ [SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE] = "speaker-safe-and-line",
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = "speaker-and-headphones-ext-1",
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = "speaker-and-headphones-ext-2",
[SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
+ [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = "voice-hac-handset",
[SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
[SND_DEVICE_OUT_VOICE_SPEAKER_STEREO] = "voice-speaker-stereo",
[SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = "voice-speaker-vbat",
@@ -451,18 +485,23 @@
[SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
[SND_DEVICE_OUT_BT_A2DP] = "bt-a2dp",
[SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = "speaker-and-bt-a2dp",
+ [SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP] = "speaker-safe-and-bt-a2dp",
+ [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = "voice-handset-tmus",
[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_TTY_FULL_USB] = "voice-tty-full-usb",
[SND_DEVICE_OUT_VOICE_TTY_VCO_USB] = "voice-tty-vco-usb",
[SND_DEVICE_OUT_VOICE_TX] = "voice-tx",
+ [SND_DEVICE_OUT_VOICE_MUSIC_TX] = "voice-music-tx",
[SND_DEVICE_OUT_AFE_PROXY] = "afe-proxy",
[SND_DEVICE_OUT_USB_HEADSET] = "usb-headset",
[SND_DEVICE_OUT_VOICE_USB_HEADSET] = "usb-headset",
[SND_DEVICE_OUT_USB_HEADPHONES] = "usb-headphones",
+ [SND_DEVICE_OUT_USB_HEADSET_SPEC] = "usb-headset",
[SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = "usb-headphones",
[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = "speaker-and-usb-headphones",
+ [SND_DEVICE_OUT_SPEAKER_SAFE_AND_USB_HEADSET] = "speaker-safe-and-usb-headphones",
[SND_DEVICE_OUT_TRANSMISSION_FM] = "transmission-fm",
[SND_DEVICE_OUT_ANC_HEADSET] = "anc-headphones",
[SND_DEVICE_OUT_ANC_FB_HEADSET] = "anc-fb-headphones",
@@ -479,6 +518,7 @@
[SND_DEVICE_OUT_ANC_HANDSET] = "anc-handset",
[SND_DEVICE_OUT_SPEAKER_PROTECTED] = "speaker-protected",
[SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = "voice-speaker-protected",
+ [SND_DEVICE_OUT_VOICE_SPEAKER_HFP] = "voice-speaker-hfp",
[SND_DEVICE_OUT_VOICE_SPEAKER_STEREO_PROTECTED] = "voice-speaker-stereo-protected",
[SND_DEVICE_OUT_VOICE_SPEAKER_2_PROTECTED] = "voice-speaker-2-protected",
[SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT] = "speaker-protected-vbat",
@@ -487,7 +527,9 @@
[SND_DEVICE_OUT_SPEAKER_PROTECTED_RAS] = "speaker-protected",
[SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT_RAS] = "speaker-protected-vbat",
[SND_DEVICE_OUT_SPEAKER_AND_BT_SCO] = "speaker-and-bt-sco",
+ [SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO] = "speaker-safe-and-bt-sco",
[SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB] = "speaker-and-bt-sco-wb",
+ [SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB] = "speaker-safe-and-bt-sco-wb",
/* Capture sound devices */
[SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
@@ -508,6 +550,7 @@
[SND_DEVICE_IN_SPEAKER_DMIC_NS] = "speaker-dmic-endfire",
[SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = "speaker-dmic-endfire",
[SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
+ [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
[SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = "headset-mic",
[SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
[SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
@@ -521,9 +564,11 @@
[SND_DEVICE_IN_BT_A2DP] = "bt-a2dp-cap",
[SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
[SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
+ [SND_DEVICE_IN_VOICE_DMIC_TMUS] = "voice-dmic-ef-tmus",
[SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
[SND_DEVICE_IN_VOICE_SPEAKER_TMIC] = "voice-speaker-tmic",
[SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = "voice-speaker-qmic",
+ [SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP] = "voice-speaker-mic-hfp",
[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",
@@ -533,6 +578,8 @@
[SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
[SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic",
+ [SND_DEVICE_IN_VOICE_REC_MIC_AEC] = "voice-rec-mic",
+ [SND_DEVICE_IN_VOICE_REC_MIC_AEC_NS] = "voice-rec-mic",
[SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef",
[SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = "voice-rec-dmic-ef-fluence",
[SND_DEVICE_IN_USB_HEADSET_MIC] = "usb-headset-mic",
@@ -540,6 +587,7 @@
[SND_DEVICE_IN_USB_HEADSET_MIC_AEC] = "usb-headset-mic",
[SND_DEVICE_IN_UNPROCESSED_USB_HEADSET_MIC] = "usb-headset-mic",
[SND_DEVICE_IN_VOICE_RECOG_USB_HEADSET_MIC] = "usb-headset-mic",
+ [SND_DEVICE_IN_VOICE_REC_HEADSET_MIC] = "headset-mic",
[SND_DEVICE_IN_USB_HEADSET_MULTI_CHANNEL_MIC] = "usb-headset-mic",
[SND_DEVICE_IN_VOICE_RECOG_USB_HEADSET_MULTI_CHANNEL_MIC] = "usb-headset-mic",
[SND_DEVICE_IN_USB_HEADSET_MULTI_CHANNEL_MIC_AEC] = "usb-headset-mic",
@@ -548,8 +596,8 @@
[SND_DEVICE_IN_AANC_HANDSET_MIC] = "aanc-handset-mic",
[SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC] = "aanc-handset-mic",
[SND_DEVICE_IN_QUAD_MIC] = "quad-mic",
- [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = "handset-stereo-dmic-ef",
- [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = "speaker-stereo-dmic-ef",
+ [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = "handset-stereo-dmic-ef",
+ [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = "speaker-stereo-dmic-ef",
[SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = "vi-feedback",
[SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_1] = "vi-feedback-mono-1",
[SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_2] = "vi-feedback-mono-2",
@@ -562,6 +610,7 @@
[SND_DEVICE_IN_SPEAKER_QMIC_AEC] = "quad-mic",
[SND_DEVICE_IN_SPEAKER_QMIC_NS] = "quad-mic",
[SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = "quad-mic",
+ [SND_DEVICE_IN_HANDSET_QMIC_AEC] = "quad-mic",
[SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE] = "quad-mic",
[SND_DEVICE_IN_THREE_MIC] = "three-mic",
[SND_DEVICE_IN_HANDSET_TMIC_FLUENCE_PRO] = "three-mic",
@@ -618,12 +667,15 @@
[SND_DEVICE_OUT_SPEAKER_EXTERNAL_2] = 130,
[SND_DEVICE_OUT_SPEAKER_VBAT] = 14,
[SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
+ [SND_DEVICE_OUT_SPEAKER_SAFE] = 14,
[SND_DEVICE_OUT_LINE] = 10,
[SND_DEVICE_OUT_HEADPHONES] = 10,
[SND_DEVICE_OUT_HEADPHONES_DSD] = 10,
[SND_DEVICE_OUT_HEADPHONES_44_1] = 10,
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
+ [SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES] = 10,
[SND_DEVICE_OUT_SPEAKER_AND_LINE] = 10,
+ [SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE] = 10,
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = 130,
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = 130,
[SND_DEVICE_OUT_VOICE_HANDSET] = 7,
@@ -632,6 +684,7 @@
[SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = 14,
[SND_DEVICE_OUT_VOICE_SPEAKER_2] = 14,
[SND_DEVICE_OUT_VOICE_SPEAKER_2_VBAT] = 14,
+ [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = 53,
[SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
[SND_DEVICE_OUT_VOICE_LINE] = 10,
[SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_HEADPHONES] = 10,
@@ -645,21 +698,28 @@
[SND_DEVICE_OUT_DISPLAY_PORT] = 18,
[SND_DEVICE_OUT_SPEAKER_AND_DISPLAY_PORT] = 14,
[SND_DEVICE_OUT_BT_SCO] = 22,
+ [SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO] = 14,
[SND_DEVICE_OUT_BT_SCO_WB] = 39,
+ [SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB] = 14,
[SND_DEVICE_OUT_BT_A2DP] = 20,
[SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = 14,
+ [SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP] = 14,
+ [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = 88,
[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_TTY_FULL_USB] = 17,
[SND_DEVICE_OUT_VOICE_TTY_VCO_USB] = 17,
[SND_DEVICE_OUT_VOICE_TX] = 45,
+ [SND_DEVICE_OUT_VOICE_MUSIC_TX] = 3,
[SND_DEVICE_OUT_AFE_PROXY] = 0,
[SND_DEVICE_OUT_USB_HEADSET] = 45,
[SND_DEVICE_OUT_VOICE_USB_HEADSET] = 45,
[SND_DEVICE_OUT_USB_HEADPHONES] = 45,
+ [SND_DEVICE_OUT_USB_HEADSET_SPEC] = 45,
[SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = 45,
[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = 14,
+ [SND_DEVICE_OUT_SPEAKER_SAFE_AND_USB_HEADSET] = 14,
[SND_DEVICE_OUT_TRANSMISSION_FM] = 0,
[SND_DEVICE_OUT_ANC_HEADSET] = 26,
[SND_DEVICE_OUT_ANC_FB_HEADSET] = 27,
@@ -669,6 +729,7 @@
[SND_DEVICE_OUT_SPEAKER_AND_ANC_FB_HEADSET] = 27,
[SND_DEVICE_OUT_ANC_HANDSET] = 103,
[SND_DEVICE_OUT_SPEAKER_PROTECTED] = 124,
+ [SND_DEVICE_OUT_VOICE_SPEAKER_HFP] = 14,
[SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = 101,
[SND_DEVICE_OUT_VOICE_SPEAKER_2_PROTECTED] = 101,
[SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT] = 124,
@@ -695,8 +756,10 @@
[SND_DEVICE_IN_SPEAKER_DMIC_NS] = 116,
[SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = 117,
[SND_DEVICE_IN_HEADSET_MIC] = 8,
+ [SND_DEVICE_IN_HEADSET_MIC_AEC] = 8,
[SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = 47,
[SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
+ [SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP] = 11,
[SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
[SND_DEVICE_IN_SPDIF] = 143,
[SND_DEVICE_IN_HDMI_MIC] = 143,
@@ -708,6 +771,7 @@
[SND_DEVICE_IN_BT_A2DP] = 21,
[SND_DEVICE_IN_CAMCORDER_MIC] = 4,
[SND_DEVICE_IN_VOICE_DMIC] = 41,
+ [SND_DEVICE_IN_VOICE_DMIC_TMUS] = 89,
[SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
[SND_DEVICE_IN_VOICE_SPEAKER_TMIC] = 161,
[SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = 19,
@@ -720,8 +784,11 @@
[SND_DEVICE_IN_VOICE_REC_MIC] = 4,
[SND_DEVICE_IN_VOICE_REC_MIC_NS] = 107,
+ [SND_DEVICE_IN_VOICE_REC_MIC_AEC] = 112,
+ [SND_DEVICE_IN_VOICE_REC_MIC_AEC_NS] = 114,
[SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 34,
[SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = 41,
+ [SND_DEVICE_IN_VOICE_REC_HEADSET_MIC] = 8,
[SND_DEVICE_IN_USB_HEADSET_MIC] = 44,
[SND_DEVICE_IN_VOICE_USB_HEADSET_MIC] = 44,
[SND_DEVICE_IN_UNPROCESSED_USB_HEADSET_MIC] = 44,
@@ -735,8 +802,8 @@
[SND_DEVICE_IN_AANC_HANDSET_MIC] = 104,
[SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC] = 105,
[SND_DEVICE_IN_QUAD_MIC] = 46,
- [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = 34,
- [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = 35,
+ [SND_DEVICE_IN_HANDSET_DMIC_STEREO] = 34,
+ [SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = 35,
[SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = 102,
[SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_1] = 102,
[SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_2] = 102,
@@ -746,6 +813,7 @@
[SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE] = 121,
[SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE] = 120,
[SND_DEVICE_IN_HANDSET_QMIC] = 125,
+ [SND_DEVICE_IN_HANDSET_QMIC_AEC] = 125,
[SND_DEVICE_IN_SPEAKER_QMIC_AEC] = 126,
[SND_DEVICE_IN_SPEAKER_QMIC_NS] = 127,
[SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = 129,
@@ -784,16 +852,20 @@
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_EXTERNAL_2)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_VBAT)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE)},
{TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
{TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES_DSD)},
{TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES_44_1)},
{TO_NAME_INDEX(SND_DEVICE_OUT_LINE)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_LINE)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_HFP)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_VBAT)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_2)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_2_VBAT)},
@@ -804,9 +876,14 @@
{TO_NAME_INDEX(SND_DEVICE_OUT_DISPLAY_PORT)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_DISPLAY_PORT)},
{TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO)},
{TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB)},
{TO_NAME_INDEX(SND_DEVICE_OUT_BT_A2DP)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET_TMUS)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HAC_HANDSET)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
@@ -821,6 +898,8 @@
{TO_NAME_INDEX(SND_DEVICE_OUT_USB_HEADPHONES)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_USB_HEADPHONES)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_SAFE_AND_USB_HEADSET)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_USB_HEADSET_SPEC)},
{TO_NAME_INDEX(SND_DEVICE_OUT_TRANSMISSION_FM)},
{TO_NAME_INDEX(SND_DEVICE_OUT_ANC_HEADSET)},
{TO_NAME_INDEX(SND_DEVICE_OUT_ANC_FB_HEADSET)},
@@ -855,9 +934,12 @@
{TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC)},
{TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS)},
{TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_STEREO)},
{TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC_AEC)},
{TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC_FLUENCE)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_SPDIF)},
{TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
@@ -869,6 +951,7 @@
{TO_NAME_INDEX(SND_DEVICE_IN_BT_A2DP)},
{TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC_TMUS)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_TMIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_QMIC)},
@@ -879,8 +962,11 @@
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_USB_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_NS)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_AEC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_AEC_NS)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_STEREO)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_HEADSET_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_RX)},
{TO_NAME_INDEX(SND_DEVICE_IN_USB_HEADSET_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_USB_HEADSET_MIC)},
@@ -895,8 +981,8 @@
{TO_NAME_INDEX(SND_DEVICE_IN_AANC_HANDSET_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC)},
{TO_NAME_INDEX(SND_DEVICE_IN_QUAD_MIC)},
- {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_STEREO_DMIC)},
- {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_STEREO_DMIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_STEREO)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_STEREO)},
{TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK)},
{TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_1)},
{TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_2)},
@@ -906,6 +992,7 @@
{TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE)},
{TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE)},
{TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC_AEC)},
{TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC)},
{TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_NS)},
{TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)},
@@ -938,6 +1025,8 @@
static struct name_to_index usecase_name_index[AUDIO_USECASE_MAX] = {
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_DEEP_BUFFER)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
+ {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_HIFI)},
+ {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_TTS)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_ULL)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MULTI_CH)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
@@ -959,6 +1048,7 @@
{TO_NAME_INDEX(USECASE_AUDIO_RECORD_COMPRESS6)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD_MMAP)},
+ {TO_NAME_INDEX(USECASE_AUDIO_RECORD_HIFI)},
{TO_NAME_INDEX(USECASE_VOICE_CALL)},
{TO_NAME_INDEX(USECASE_VOICE2_CALL)},
{TO_NAME_INDEX(USECASE_VOLTE_CALL)},
@@ -977,6 +1067,7 @@
{TO_NAME_INDEX(USECASE_AUDIO_SPKR_CALIB_TX)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_AFE_PROXY)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD_AFE_PROXY)},
+ {TO_NAME_INDEX(USECASE_AUDIO_DSM_FEEDBACK)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_SILENCE)},
{TO_NAME_INDEX(USECASE_INCALL_MUSIC_UPLINK)},
{TO_NAME_INDEX(USECASE_AUDIO_A2DP_ABR_FEEDBACK)},
@@ -987,6 +1078,24 @@
};
+static const struct name_to_index usecase_type_index[USECASE_TYPE_MAX] = {
+ {TO_NAME_INDEX(PCM_PLAYBACK)},
+ {TO_NAME_INDEX(PCM_CAPTURE)},
+ {TO_NAME_INDEX(VOICE_CALL)},
+ {TO_NAME_INDEX(PCM_HFP_CALL)},
+};
+
+struct app_type_entry {
+ int uc_type;
+ int bit_width;
+ int app_type;
+ int max_rate;
+ char *mode;
+ struct listnode node; // membership in app_type_entry_list;
+};
+
+static struct listnode app_type_entry_list;
+
#define NO_COLS 2
#ifdef PLATFORM_APQ8084
static int msm_device_to_be_id [][NO_COLS] = {
@@ -1106,9 +1215,112 @@
#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
#define PCM_OFFLOAD_PLATFORM_DELAY (30*1000LL)
#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
-#define ULL_PLATFORM_DELAY (6*1000LL)
+#define ULL_PLATFORM_DELAY (3*1000LL)
#define MMAP_PLATFORM_DELAY (3*1000LL)
+static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT;
+static bool is_tmus = false;
+
+static void check_operator()
+{
+ char value[PROPERTY_VALUE_MAX];
+ int mccmnc;
+ property_get("gsm.sim.operator.numeric",value,"0");
+ mccmnc = atoi(value);
+ ALOGD("%s: tmus mccmnc %d", __func__, mccmnc);
+ switch(mccmnc) {
+ /* TMUS MCC(310), MNC(490, 260, 026) */
+ case 310490:
+ case 310260:
+ case 310026:
+ /* Add new TMUS MNC(800, 660, 580, 310, 270, 250, 240, 230, 220, 210, 200, 160) */
+ case 310800:
+ case 310660:
+ case 310580:
+ case 310310:
+ case 310270:
+ case 310250:
+ case 310240:
+ case 310230:
+ case 310220:
+ case 310210:
+ case 310200:
+ case 310160:
+ is_tmus = true;
+ break;
+ }
+}
+
+bool is_operator_tmus()
+{
+ pthread_once(&check_op_once_ctl, check_operator);
+ return is_tmus;
+}
+
+static char *get_current_operator()
+{
+ struct listnode *node;
+ struct operator_info *info_item;
+ char mccmnc[PROPERTY_VALUE_MAX];
+ char *ret = NULL;
+
+ property_get("gsm.sim.operator.numeric",mccmnc,"00000");
+
+ list_for_each(node, &operator_info_list) {
+ info_item = node_to_item(node, struct operator_info, list);
+ if (strstr(info_item->mccmnc, mccmnc) != NULL) {
+ ret = info_item->name;
+ }
+ }
+
+ return ret;
+}
+
+static struct operator_specific_device *get_operator_specific_device(snd_device_t snd_device)
+{
+ struct listnode *node;
+ struct operator_specific_device *ret = NULL;
+ struct operator_specific_device *device_item;
+ char *operator_name;
+
+ operator_name = get_current_operator();
+ if (operator_name == NULL)
+ return ret;
+
+ list_for_each(node, operator_specific_device_table[snd_device]) {
+ device_item = node_to_item(node, struct operator_specific_device, list);
+ if (strcmp(operator_name, device_item->operator) == 0) {
+ ret = device_item;
+ }
+ }
+
+ return ret;
+}
+
+static int get_operator_specific_device_acdb_id(snd_device_t snd_device)
+{
+ struct operator_specific_device *device;
+ int ret = acdb_device_table[snd_device];
+
+ device = get_operator_specific_device(snd_device);
+ if (device != NULL)
+ ret = device->acdb_id;
+
+ return ret;
+}
+
+static const char *get_operator_specific_device_mixer_path(snd_device_t snd_device)
+{
+ struct operator_specific_device *device;
+ const char *ret = device_table[snd_device];
+
+ device = get_operator_specific_device(snd_device);
+ if (device != NULL)
+ ret = device->mixer_path;
+
+ return ret;
+}
+
static void update_codec_type_and_interface(struct platform_data * my_data, const char *snd_card_name) {
if (!strncmp(snd_card_name, "sdm670-skuw-snd-card",
@@ -1202,7 +1414,7 @@
ALOGV("%s: out device is %d", __func__, usecase->out_snd_device);
app_type = usecase->stream.out->app_type_cfg.app_type;
- acdb_dev_id = acdb_device_table[usecase->out_snd_device];
+ acdb_dev_id = platform_get_snd_device_acdb_id(usecase->out_snd_device);
if (platform_split_snd_device(my_data, usecase->out_snd_device,
&num_devices, new_snd_device) < 0)
@@ -1477,6 +1689,7 @@
for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
backend_tag_table[dev] = NULL;
hw_interface_table[dev] = NULL;
+ operator_specific_device_table[dev] = NULL;
}
for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
backend_bit_width_table[dev] = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
@@ -1507,6 +1720,12 @@
backend_tag_table[SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = strdup("usb-headphones");
backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] =
strdup("speaker-and-usb-headphones");
+ backend_tag_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_USB_HEADSET] =
+ strdup("speaker-safe-and-usb-headphones");
+ backend_tag_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO] =
+ strdup("speaker-safe-and-bt-sco");
+ backend_tag_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB] =
+ strdup("speaker-safe-and-bt-sco-wb");
backend_tag_table[SND_DEVICE_IN_VOICE_TTY_FULL_USB_MIC] = strdup("usb-headset-mic");
backend_tag_table[SND_DEVICE_IN_VOICE_TTY_HCO_USB_MIC] = strdup("usb-headset-mic");
backend_tag_table[SND_DEVICE_IN_USB_HEADSET_MIC] = strdup("usb-headset-mic");
@@ -1527,6 +1746,8 @@
backend_tag_table[SND_DEVICE_OUT_BT_A2DP] = strdup("bt-a2dp");
backend_tag_table[SND_DEVICE_IN_BT_A2DP] = strdup("bt-a2dp-cap");
backend_tag_table[SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = strdup("speaker-and-bt-a2dp");
+ backend_tag_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP] = strdup("speaker-safe-and-bt-a2dp");
+ backend_tag_table[SND_DEVICE_OUT_USB_HEADSET_SPEC] = strdup("usb-headset");
backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_HEADPHONES] = strdup("speaker-and-headphones");
backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_ANC_HEADSET] = strdup("speaker-and-headphones");
backend_tag_table[SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_ANC_FB_HEADSET] = strdup("speaker-and-headphones");
@@ -1539,12 +1760,14 @@
hw_interface_table[SND_DEVICE_OUT_SPEAKER_EXTERNAL_1] = strdup("SLIMBUS_0_RX");
hw_interface_table[SND_DEVICE_OUT_SPEAKER_EXTERNAL_2] = strdup("SLIMBUS_0_RX");
hw_interface_table[SND_DEVICE_OUT_SPEAKER_REVERSE] = strdup("SLIMBUS_0_RX");
+ hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE] = strdup("SLIMBUS_0_RX");
hw_interface_table[SND_DEVICE_OUT_SPEAKER_VBAT] = strdup("SLIMBUS_0_RX");
hw_interface_table[SND_DEVICE_OUT_LINE] = strdup("SLIMBUS_6_RX");
hw_interface_table[SND_DEVICE_OUT_HEADPHONES] = strdup("SLIMBUS_6_RX");
hw_interface_table[SND_DEVICE_OUT_HEADPHONES_DSD] = strdup("SLIMBUS_2_RX");
hw_interface_table[SND_DEVICE_OUT_HEADPHONES_44_1] = strdup("SLIMBUS_5_RX");
hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
+ hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_HEADPHONES] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_ANC_HEADSET] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_ANC_FB_HEADSET] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
@@ -1552,14 +1775,17 @@
hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_STEREO_AND_VOICE_ANC_HEADSET] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_STEREO_AND_VOICE_ANC_FB_HEADSET] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_LINE] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
+ hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = strdup("SLIMBUS_0_RX-and-SLIMBUS_6_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_HANDSET] = strdup("SLIMBUS_0_RX");
+ hw_interface_table[SND_DEVICE_OUT_VOICE_HAC_HANDSET] = strdup("SLIMBUS_0_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER] = strdup("SLIMBUS_0_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = strdup("SLIMBUS_0_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_2] = strdup("SLIMBUS_0_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_2_VBAT] = strdup("SLIMBUS_0_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_HEADPHONES] = strdup("SLIMBUS_6_RX");
+ hw_interface_table[SND_DEVICE_OUT_VOICE_MUSIC_TX] = strdup("VOICE_PLAYBACK_TX");
hw_interface_table[SND_DEVICE_OUT_VOICE_LINE] = strdup("SLIMBUS_6_RX");
hw_interface_table[SND_DEVICE_OUT_HDMI] = strdup("HDMI");
hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("SLIMBUS_0_RX-and-HDMI");
@@ -1569,6 +1795,9 @@
hw_interface_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("SLIMBUS_7_RX");
hw_interface_table[SND_DEVICE_OUT_BT_A2DP] = strdup("SLIMBUS_7_RX");
hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP] = strdup("SLIMBUS_0_RX-and-SLIMBUS_7_RX");
+ hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP] =
+ strdup("SLIMBUS_0_RX-and-SLIMBUS_7_RX");
+ hw_interface_table[SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = strdup("SLIMBUS_0_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = strdup("SLIMBUS_6_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = strdup("SLIMBUS_6_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = strdup("SLIMBUS_0_RX");
@@ -1579,6 +1808,9 @@
hw_interface_table[SND_DEVICE_OUT_USB_HEADSET] = strdup("USB_AUDIO_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_USB_HEADSET] = strdup("USB_AUDIO_RX");
hw_interface_table[SND_DEVICE_OUT_USB_HEADPHONES] = strdup("USB_AUDIO_RX");
+ hw_interface_table[SND_DEVICE_OUT_USB_HEADSET_SPEC] = strdup("USB_AUDIO_RX");
+ hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_USB_HEADSET] =
+ strdup("SLIMBUS_0_RX-and-USB_AUDIO_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = strdup("USB_AUDIO_RX");
hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = strdup("SLIMBUS_0_RX-and-USB_AUDIO_RX");
hw_interface_table[SND_DEVICE_OUT_TRANSMISSION_FM] = strdup("SLIMBUS_8_TX");
@@ -1591,6 +1823,11 @@
hw_interface_table[SND_DEVICE_OUT_ANC_HANDSET] = strdup("SLIMBUS_0_RX");
hw_interface_table[SND_DEVICE_OUT_SPEAKER_PROTECTED] = strdup("SLIMBUS_0_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = strdup("SLIMBUS_0_RX");
+ hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_HFP] = strdup("SLIMBUS_0_RX");
+ hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_BT_SCO] = strdup("SLIMBUS_0_RX-and-SEC_AUX_PCM_RX");
+ hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB] = strdup("SLIMBUS_0_RX-and-SEC_AUX_PCM_RX");
+ hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO] = strdup("QUAT_TDM_RX_0-and-SLIMBUS_7_RX");
+ hw_interface_table[SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB] = strdup("QUAT_TDM_RX_0-and-SLIMBUS_7_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_2_PROTECTED] = strdup("SLIMBUS_0_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_SPEAKER_STEREO_PROTECTED] = strdup("SLIMBUS_0_RX");
hw_interface_table[SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT] = strdup("SLIMBUS_0_RX");
@@ -1608,6 +1845,8 @@
hw_interface_table[SND_DEVICE_IN_HANDSET_DMIC_AEC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_HANDSET_DMIC_NS] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = strdup("SLIMBUS_0_TX");
+ hw_interface_table[SND_DEVICE_IN_HANDSET_DMIC_STEREO] = strdup("SLIMBUS_0_TX");
+ hw_interface_table[SND_DEVICE_IN_HEADSET_MIC_AEC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_SPEAKER_MIC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_SPEAKER_MIC_AEC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_SPEAKER_MIC_NS] = strdup("SLIMBUS_0_TX");
@@ -1616,6 +1855,7 @@
hw_interface_table[SND_DEVICE_IN_SPEAKER_DMIC_AEC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_SPEAKER_DMIC_NS] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = strdup("SLIMBUS_0_TX");
+ hw_interface_table[SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_HEADSET_MIC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_SPEAKER_MIC] = strdup("SLIMBUS_0_TX");
@@ -1630,26 +1870,35 @@
hw_interface_table[SND_DEVICE_IN_BT_A2DP] = strdup("SLIMBUS_7_TX");
hw_interface_table[SND_DEVICE_IN_CAMCORDER_MIC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_DMIC] = strdup("SLIMBUS_0_TX");
+ hw_interface_table[SND_DEVICE_IN_VOICE_DMIC_TMUS] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = strdup("SLIMBUS_0_TX");
+ hw_interface_table[SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_SPEAKER_TMIC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = strdup("SLIMBUS_0_TX");
+ hw_interface_table[SND_DEVICE_IN_VOICE_REC_HEADSET_MIC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_TTY_FULL_USB_MIC] = strdup("USB_AUDIO_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_TTY_HCO_USB_MIC] = strdup("USB_AUDIO_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_REC_MIC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_REC_MIC_NS] = strdup("SLIMBUS_0_TX");
+ hw_interface_table[SND_DEVICE_IN_VOICE_REC_MIC_AEC] = strdup("SLIMBUS_0_TX");
+ hw_interface_table[SND_DEVICE_IN_VOICE_REC_MIC_AEC_NS] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_RX] = strdup("RT_PROXY_DAI_002_TX");
hw_interface_table[SND_DEVICE_IN_USB_HEADSET_MIC] = strdup("USB_AUDIO_TX");
+ hw_interface_table[SND_DEVICE_IN_VOICE_USB_HEADSET_MIC] = strdup("USB_AUDIO_TX");
+ hw_interface_table[SND_DEVICE_IN_USB_HEADSET_MIC_AEC] = strdup("USB_AUDIO_TX");
+ hw_interface_table[SND_DEVICE_IN_UNPROCESSED_USB_HEADSET_MIC] = strdup("USB_AUDIO_TX");
+ hw_interface_table[SND_DEVICE_IN_VOICE_RECOG_USB_HEADSET_MIC] = strdup("USB_AUDIO_TX");
hw_interface_table[SND_DEVICE_IN_USB_HEADSET_MULTI_CHANNEL_MIC] = strdup("USB_AUDIO_TX");
hw_interface_table[SND_DEVICE_IN_CAPTURE_FM] = strdup("SLIMBUS_8_TX");
hw_interface_table[SND_DEVICE_IN_AANC_HANDSET_MIC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_QUAD_MIC] = strdup("SLIMBUS_0_TX");
- hw_interface_table[SND_DEVICE_IN_HANDSET_STEREO_DMIC] = strdup("SLIMBUS_0_TX");
- hw_interface_table[SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = strdup("SLIMBUS_0_TX");
+ hw_interface_table[SND_DEVICE_IN_HANDSET_DMIC_STEREO] = strdup("SLIMBUS_0_TX");
+ hw_interface_table[SND_DEVICE_IN_SPEAKER_DMIC_STEREO] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = strdup("SLIMBUS_4_TX");
hw_interface_table[SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_1] = strdup("SLIMBUS_4_TX");
hw_interface_table[SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_2] = strdup("SLIMBUS_4_TX");
@@ -1660,6 +1909,7 @@
hw_interface_table[SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_HANDSET_QMIC] = strdup("SLIMBUS_0_TX");
+ hw_interface_table[SND_DEVICE_IN_HANDSET_QMIC_AEC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_SPEAKER_QMIC_AEC] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_SPEAKER_QMIC_NS] = strdup("SLIMBUS_0_TX");
hw_interface_table[SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = strdup("SLIMBUS_0_TX");
@@ -1723,7 +1973,7 @@
count = mixer_ctl_get_num_values(ctl);
if (count > MAX_CVD_VERSION_STRING_SIZE)
- count = MAX_CVD_VERSION_STRING_SIZE;
+ count = MAX_CVD_VERSION_STRING_SIZE - 1;
ret = mixer_ctl_get_array(ctl, cvd_version, count);
if (ret != 0) {
@@ -2074,20 +2324,64 @@
return ret;
}
+#ifdef FLICKER_SENSOR_INPUT
+static void configure_flicker_sensor_input(struct mixer *mixer)
+{
+ struct mixer_ctl *ctl;
+ const char* ctl1 = "AIF3_CAP Mixer SLIM TX2";
+ int setting1 = 1;
+ const char* ctl2 = "CDC_IF TX2 MUX";
+ const char* setting2 = "DEC2";
+ const char* ctl3 = "SLIM_1_TX Channels";
+ const char* setting3 = "One";
+ const char* ctl4 = "ADC MUX2";
+ const char* setting4 = "AMIC";
+ const char* ctl5 = "AMIC MUX2";
+ const char* setting5 = "ADC1";
+ const char* ctl6 = "DEC2 Volume";
+ int setting6 = 84;
+ const char* ctl7 = "MultiMedia9 Mixer SLIM_1_TX";
+ int setting7 = 1;
+ const char* ctl8 = "SLIM_1_TX SampleRate";
+ const char* setting8 = "KHZ_8";
+
+ ctl = mixer_get_ctl_by_name(mixer, ctl1);
+ mixer_ctl_set_value(ctl, 0, setting1);
+ ctl = mixer_get_ctl_by_name(mixer, ctl2);
+ mixer_ctl_set_enum_by_string(ctl, setting2);
+ ctl = mixer_get_ctl_by_name(mixer, ctl3);
+ mixer_ctl_set_enum_by_string(ctl, setting3);
+ ctl = mixer_get_ctl_by_name(mixer, ctl4);
+ mixer_ctl_set_enum_by_string(ctl, setting4);
+ ctl = mixer_get_ctl_by_name(mixer, ctl5);
+ mixer_ctl_set_enum_by_string(ctl, setting5);
+ ctl = mixer_get_ctl_by_name(mixer, ctl6);
+ mixer_ctl_set_value(ctl, 0, setting6);
+ ctl = mixer_get_ctl_by_name(mixer, ctl7);
+ mixer_ctl_set_value(ctl, 0, setting7);
+ ctl = mixer_get_ctl_by_name(mixer, ctl8);
+ mixer_ctl_set_enum_by_string(ctl, setting8);
+}
+#endif
+
void *platform_init(struct audio_device *adev)
{
char platform[PROPERTY_VALUE_MAX];
char baseband[PROPERTY_VALUE_MAX];
char value[PROPERTY_VALUE_MAX];
struct platform_data *my_data = NULL;
- char *snd_card_name = NULL, *snd_card_name_t = NULL;
- char *snd_internal_name = NULL;
- char *tmp = NULL;
+ char *snd_card_name = NULL;
char mixer_xml_file[MIXER_PATH_MAX_LENGTH]= {0};
+ char platform_info_file[MIXER_PATH_MAX_LENGTH]= {0};
int idx;
struct mixer_ctl *ctl = NULL;
const char *id_string = NULL;
int cfg_value = -1;
+ bool dual_mic_config = false;
+ struct snd_card_split *snd_split_handle = NULL;
+
+ list_init(&operator_info_list);
+ list_init(&app_type_entry_list);
adev->snd_card = audio_extn_utils_open_snd_mixer(&adev->mixer);
if (adev->snd_card < 0) {
@@ -2103,6 +2397,9 @@
return NULL;
}
+ audio_extn_set_snd_card_split(snd_card_name);
+ snd_split_handle = audio_extn_get_snd_card_split();
+
my_data = calloc(1, sizeof(struct platform_data));
if (!my_data) {
ALOGE("failed to allocate platform data");
@@ -2145,40 +2442,26 @@
* done to preserve backward compatibility but not mandatory as
* long as the mixer files are named as per above assumption.
*/
- snd_card_name_t = strdup(snd_card_name);
- snd_internal_name = strtok_r(snd_card_name_t, "-", &tmp);
+ snprintf(mixer_xml_file, sizeof(mixer_xml_file), "%s_%s_%s.xml",
+ MIXER_XML_BASE_STRING, snd_split_handle->snd_card,
+ snd_split_handle->form_factor);
+ if (!audio_extn_utils_resolve_config_file(mixer_xml_file)) {
+ memset(mixer_xml_file, 0, sizeof(mixer_xml_file));
+ snprintf(mixer_xml_file, sizeof(mixer_xml_file), "%s_%s.xml",
+ MIXER_XML_BASE_STRING, snd_split_handle->snd_card);
- if (snd_internal_name != NULL) {
- snd_internal_name = strtok_r(NULL, "-", &tmp);
- }
- if (snd_internal_name != NULL) {
- strlcpy(mixer_xml_file, MIXER_XML_BASE_STRING,
- MIXER_PATH_MAX_LENGTH);
- strlcat(mixer_xml_file, MIXER_FILE_DELIMITER,
- MIXER_PATH_MAX_LENGTH);
- strlcat(mixer_xml_file, snd_internal_name,
- MIXER_PATH_MAX_LENGTH);
- strlcat(mixer_xml_file, MIXER_FILE_EXT,
- MIXER_PATH_MAX_LENGTH);
- } else {
- strlcpy(mixer_xml_file, MIXER_XML_DEFAULT_PATH,
- MIXER_PATH_MAX_LENGTH);
+ if (!audio_extn_utils_resolve_config_file(mixer_xml_file)) {
+ memset(mixer_xml_file, 0, sizeof(mixer_xml_file));
+ strlcpy(mixer_xml_file, MIXER_XML_DEFAULT_PATH, MIXER_PATH_MAX_LENGTH);
+ audio_extn_utils_resolve_config_file(mixer_xml_file);
+ }
}
- if (F_OK == access(mixer_xml_file, 0)) {
- ALOGD("%s: Loading mixer file: %s", __func__, mixer_xml_file);
- if (audio_extn_read_xml(adev, adev->snd_card, mixer_xml_file,
- MIXER_XML_PATH_AUXPCM) == -ENOSYS)
- adev->audio_route = audio_route_init(adev->snd_card,
- mixer_xml_file);
- update_codec_type_and_interface(my_data, snd_card_name);
- } else {
- ALOGD("%s: Loading default mixer file", __func__);
- if (audio_extn_read_xml(adev, adev->snd_card, MIXER_XML_DEFAULT_PATH,
- MIXER_XML_PATH_AUXPCM) == -ENOSYS)
- adev->audio_route = audio_route_init(adev->snd_card,
- MIXER_XML_DEFAULT_PATH);
- update_codec_type_and_interface(my_data, snd_card_name);
+ ALOGD("%s: Loading mixer file: %s", __func__, mixer_xml_file);
+ if (audio_extn_read_xml(adev, adev->snd_card, mixer_xml_file,
+ MIXER_XML_PATH_AUXPCM) == -ENOSYS) {
+ adev->audio_route = audio_route_init(adev->snd_card, mixer_xml_file);
+ update_codec_type_and_interface(my_data, snd_card_name);
}
}
if (!adev->audio_route) {
@@ -2188,8 +2471,6 @@
free(my_data);
if (snd_card_name)
free(snd_card_name);
- if (snd_card_name_t)
- free(snd_card_name_t);
audio_extn_utils_close_snd_mixer(adev->mixer);
return NULL;
}
@@ -2221,34 +2502,58 @@
my_data->declared_mic_count = 0;
my_data->spkr_ch_map = NULL;
my_data->use_sprk_default_sample_rate = true;
+ my_data->fluence_in_voice_comm = false;
+
+ //set max volume step for voice call
+ property_get("ro.config.vc_call_vol_steps", value, TOSTRING(MAX_VOL_INDEX));
+ my_data->max_vol_index = atoi(value);
+
be_dai_name_table = NULL;
- property_get("ro.vendor.audio.sdk.fluencetype", my_data->fluence_cap, "");
- if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro"))) {
- my_data->fluence_type = FLUENCE_QUAD_MIC | FLUENCE_DUAL_MIC;
+ property_get("persist.audio.dualmic.config",value,"");
+ if (!strcmp("endfire", value)) {
+ dual_mic_config = true;
+ }
- if (property_get_bool("persist.vendor.audio.fluence.tmic.enabled",false)) {
- my_data->fluence_type |= FLUENCE_TRI_MIC;
- }
- } else if (!strncmp("fluence", my_data->fluence_cap, sizeof("fluence"))) {
- my_data->fluence_type = FLUENCE_DUAL_MIC;
+ my_data->fluence_type = FLUENCE_NONE;
+ if ((property_get("ro.vendor.audio.sdk.fluencetype",
+ my_data->fluence_cap, NULL) > 0) ||
+ (property_get("ro.qc.sdk.audio.fluencetype",
+ my_data->fluence_cap, NULL) > 0)) {
+ if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro"))) {
+ my_data->fluence_type = FLUENCE_QUAD_MIC | FLUENCE_DUAL_MIC;
- if (property_get_bool("persist.vendor.audio.fluence.tmic.enabled",false)) {
- my_data->fluence_type |= FLUENCE_TRI_MIC;
+ if (property_get_bool("persist.vendor.audio.fluence.tmic.enabled",false)) {
+ my_data->fluence_type |= FLUENCE_TRI_MIC;
+ }
+ } else if (!strncmp("fluence", my_data->fluence_cap, sizeof("fluence")) ||
+ dual_mic_config) {
+ my_data->fluence_type = FLUENCE_DUAL_MIC;
+
+ if (property_get_bool("persist.vendor.audio.fluence.tmic.enabled",false)) {
+ my_data->fluence_type |= FLUENCE_TRI_MIC;
+ }
}
- } else {
- my_data->fluence_type = FLUENCE_NONE;
}
if (my_data->fluence_type != FLUENCE_NONE) {
- property_get("persist.vendor.audio.fluence.voicecall",value,"");
- if (!strncmp("true", value, sizeof("true"))) {
- my_data->fluence_in_voice_call = true;
+ if ((property_get("persist.vendor.audio.fluence.voicecall",
+ value,NULL) > 0) ||
+ (property_get("persist.audio.fluence.voicecall",value,NULL) > 0)) {
+ if (!strncmp("true", value, sizeof("true")))
+ my_data->fluence_in_voice_call = true;
}
- property_get("persist.vendor.audio.fluence.voicerec",value,"");
+ if ((property_get("persist.vendor.audio.fluence.voicerec",
+ value,NULL) > 0) ||
+ (property_get("persist.audio.fluence.voicerec",value,NULL) > 0)) {
+ if (!strncmp("true", value, sizeof("true")))
+ my_data->fluence_in_voice_rec = true;
+ }
+
+ property_get("persist.audio.fluence.voicecomm",value,"");
if (!strncmp("true", value, sizeof("true"))) {
- my_data->fluence_in_voice_rec = true;
+ my_data->fluence_in_voice_comm = true;
}
property_get("persist.vendor.audio.fluence.audiorec",value,"");
@@ -2256,9 +2561,12 @@
my_data->fluence_in_audio_rec = true;
}
- property_get("persist.vendor.audio.fluence.speaker",value,"");
- if (!strncmp("true", value, sizeof("true"))) {
- my_data->fluence_in_spkr_mode = true;
+ if ((property_get("persist.vendor.audio.fluence.speaker",
+ value,NULL) > 0) ||
+ (property_get("persist.audio.fluence.speaker",value,NULL) > 0)) {
+ if (!strncmp("true", value, sizeof("true"))) {
+ my_data->fluence_in_spkr_mode = true;
+ }
}
property_get("persist.vendor.audio.fluence.mode",value,"");
@@ -2316,8 +2624,11 @@
platform_info_init(PLATFORM_INFO_XML_PATH_TDM, my_data, PLATFORM);
else if (my_data->is_internal_codec)
platform_info_init(PLATFORM_INFO_XML_PATH_INTCODEC, my_data, PLATFORM);
- else
- platform_info_init(PLATFORM_INFO_XML_PATH, my_data, PLATFORM);
+ else {
+ // Try to load pixel or default
+ audio_extn_utils_get_platform_info(snd_card_name, platform_info_file);
+ platform_info_init(platform_info_file, my_data, PLATFORM);
+ }
/* CSRA devices support multiple sample rates via I2S at spkr out */
if (!strncmp(snd_card_name, "qcs405-csra", strlen("qcs405-csra"))) {
@@ -2448,6 +2759,11 @@
}
/* init keep-alive for compress passthru */
audio_extn_keep_alive_init(adev);
+
+#ifdef FLICKER_SENSOR_INPUT
+ configure_flicker_sensor_input(adev->mixer);
+#endif
+
#ifdef DYNAMIC_LOG_ENABLED
log_utils_init();
#endif
@@ -2509,6 +2825,7 @@
audio_extn_ssr_update_enabled();
audio_extn_spkr_prot_init(adev);
+ audio_extn_hwdep_cal_send(adev->snd_card, my_data->acdb_handle);
/* init audio device arbitration */
audio_extn_dev_arbi_init();
@@ -2757,7 +3074,6 @@
my_data->edid_info = NULL;
free(snd_card_name);
- free(snd_card_name_t);
return my_data;
}
@@ -2775,6 +3091,10 @@
void platform_deinit(void *platform)
{
struct platform_data *my_data = (struct platform_data *)platform;
+ struct operator_info *info_item;
+ struct operator_specific_device *device_item;
+ struct app_type_entry *ap;
+ struct listnode *node;
audio_extn_keep_alive_deinit();
@@ -2804,8 +3124,54 @@
free(backend_tag_table[dev]);
backend_tag_table[dev]= NULL;
}
+
+ if (hw_interface_table[dev]) {
+ free(hw_interface_table[dev]);
+ hw_interface_table[dev] = NULL;
+ }
+
+ if (operator_specific_device_table[dev]) {
+ while (!list_empty(operator_specific_device_table[dev])) {
+ node = list_head(operator_specific_device_table[dev]);
+ list_remove(node);
+ device_item = node_to_item(node,
+ struct operator_specific_device, list);
+ free(device_item->operator);
+ device_item->operator = NULL;
+ free(device_item->mixer_path);
+ device_item->mixer_path = NULL;
+ free(device_item);
+ device_item = NULL;
+ }
+ free(operator_specific_device_table[dev]);
+ operator_specific_device_table[dev] = NULL;
+ }
}
+ while (!list_empty(&operator_info_list)) {
+ node = list_head(&operator_info_list);
+ list_remove(node);
+ info_item = node_to_item(node, struct operator_info, list);
+ free(info_item->name);
+ info_item->name = NULL;
+ free(info_item->mccmnc);
+ info_item->mccmnc = NULL;
+ free(info_item);
+ info_item = NULL;
+ }
+
+ while (!list_empty(&app_type_entry_list)) {
+ node = list_head(&app_type_entry_list);
+ list_remove(node);
+ ap = node_to_item(node, struct app_type_entry, node);
+ if (ap->mode) {
+ free(ap->mode);
+ ap->mode = NULL;
+ }
+ free(ap);
+ ap = NULL;
+ }
+
/* deinit audio device arbitration */
audio_extn_dev_arbi_deinit();
@@ -2885,9 +3251,12 @@
const char *platform_get_snd_device_name(snd_device_t snd_device)
{
- if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
+ if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
+ if (operator_specific_device_table[snd_device] != NULL) {
+ return get_operator_specific_device_mixer_path(snd_device);
+ }
return device_table[snd_device];
- else
+ } else
return "";
}
@@ -2897,7 +3266,11 @@
struct platform_data *my_data = (struct platform_data *)platform;
if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
- strlcpy(device_name, device_table[snd_device], DEVICE_NAME_MAX_SIZE);
+ if (operator_specific_device_table[snd_device] != NULL) {
+ strlcpy(device_name, get_operator_specific_device_mixer_path(snd_device),
+ DEVICE_NAME_MAX_SIZE);
+ } else
+ strlcpy(device_name, device_table[snd_device], DEVICE_NAME_MAX_SIZE);
hw_info_append_hw_type(my_data->hw_info, snd_device, device_name);
} else {
strlcpy(device_name, "", DEVICE_NAME_MAX_SIZE);
@@ -3090,6 +3463,32 @@
return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
}
+void platform_add_operator_specific_device(snd_device_t snd_device,
+ const char *operator,
+ const char *mixer_path,
+ unsigned int acdb_id)
+{
+ struct operator_specific_device *device;
+
+ if (operator_specific_device_table[snd_device] == NULL) {
+ operator_specific_device_table[snd_device] =
+ (struct listnode *)calloc(1, sizeof(struct listnode));
+ list_init(operator_specific_device_table[snd_device]);
+ }
+
+ device = (struct operator_specific_device *)calloc(1, sizeof(struct operator_specific_device));
+
+ device->operator = strdup(operator);
+ device->mixer_path = strdup(mixer_path);
+ device->acdb_id = acdb_id;
+
+ list_add_tail(operator_specific_device_table[snd_device], &device->list);
+
+ ALOGD("%s: device[%s] -> operator[%s] mixer_path[%s] acdb_id[%d]", __func__,
+ platform_get_snd_device_name(snd_device), operator, mixer_path, acdb_id);
+
+}
+
int platform_get_effect_config_data(snd_device_t snd_device,
struct audio_effect_config *effect_config,
effect_type_t effect_type)
@@ -3225,7 +3624,17 @@
ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
return -EINVAL;
}
- return acdb_device_table[snd_device];
+
+ /*
+ * If speaker protection is enabled, function returns supported
+ * sound device for speaker. Else same sound device is returned.
+ */
+ snd_device = platform_get_spkr_prot_snd_device(snd_device);
+
+ if (operator_specific_device_table[snd_device] != NULL)
+ return get_operator_specific_device_acdb_id(snd_device);
+ else
+ return acdb_device_table[snd_device];
}
int platform_set_snd_device_bit_width(snd_device_t snd_device, unsigned int bit_width)
@@ -3567,9 +3976,9 @@
else
acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED];
} else
- acdb_rx_id = acdb_device_table[out_snd_device];
+ acdb_rx_id = platform_get_snd_device_acdb_id(out_snd_device);
- acdb_tx_id = acdb_device_table[in_snd_device];
+ acdb_tx_id = platform_get_snd_device_acdb_id(in_snd_device);
if (acdb_rx_id > 0 && acdb_tx_id > 0) {
ret = my_data->csd->enable_device_config(acdb_rx_id, acdb_tx_id);
@@ -3608,8 +4017,8 @@
out_snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_2_PROTECTED_VBAT;
}
- acdb_rx_id = acdb_device_table[out_snd_device];
- acdb_tx_id = acdb_device_table[in_snd_device];
+ acdb_rx_id = platform_get_snd_device_acdb_id(out_snd_device);
+ acdb_tx_id = platform_get_snd_device_acdb_id(in_snd_device);
if (acdb_rx_id > 0 && acdb_tx_id > 0)
my_data->acdb_send_voice_cal(acdb_rx_id, acdb_tx_id);
@@ -3642,9 +4051,9 @@
else
acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED];
} else
- acdb_rx_id = acdb_device_table[out_snd_device];
+ acdb_rx_id = platform_get_snd_device_acdb_id(out_snd_device);
- acdb_tx_id = acdb_device_table[in_snd_device];
+ acdb_tx_id = platform_get_snd_device_acdb_id(in_snd_device);
if (acdb_rx_id > 0 && acdb_tx_id > 0) {
ret = my_data->csd->enable_device(acdb_rx_id, acdb_tx_id,
@@ -3722,12 +4131,50 @@
return ret;
}
+void platform_set_speaker_gain_in_combo(struct audio_device *adev,
+ snd_device_t snd_device,
+ bool enable)
+{
+ const char* name;
+ switch (snd_device) {
+ case SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES:
+ if (enable)
+ name = "spkr-gain-in-headphone-combo";
+ else
+ name = "speaker-gain-default";
+ break;
+ case SND_DEVICE_OUT_SPEAKER_AND_LINE:
+ if (enable)
+ name = "spkr-gain-in-line-combo";
+ else
+ name = "speaker-gain-default";
+ break;
+ case SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES:
+ if (enable)
+ name = "spkr-safe-gain-in-headphone-combo";
+ else
+ name = "speaker-safe-gain-default";
+ break;
+ case SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE:
+ if (enable)
+ name = "spkr-safe-gain-in-line-combo";
+ else
+ name = "speaker-safe-gain-default";
+ break;
+ default:
+ return;
+ }
+
+ audio_route_apply_and_update_path(adev->audio_route, name);
+}
+
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";
+ const char *mute_mixer_ctl_name = "Voice Rx Device Mute";
int vol_index = 0, ret = 0;
long set_values[ ] = {0,
ALL_SESSION_VSID,
@@ -3736,18 +4183,33 @@
// 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);
+ vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, my_data->max_vol_index);
set_values[0] = vol_index;
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 {
- ALOGV("%s: Setting voice volume index: %ld", __func__, set_values[0]);
- mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
+ return -EINVAL;
}
+ ALOGV("%s: Setting voice volume index: %ld", __func__, set_values[0]);
+ mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
+
+ // Send mute command in case volume index is max since indexes are inverted
+ // for mixer controls.
+ if (vol_index == my_data->max_vol_index)
+ set_values[0] = 1;
+ else
+ set_values[0] = 0;
+
+ ctl = mixer_get_ctl_by_name(adev->mixer, mute_mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s",
+ __func__, mute_mixer_ctl_name);
+ return -EINVAL;
+ }
+ ALOGV("%s: Setting RX Device Mute to: %ld", __func__, set_values[0]);
+ mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
if (my_data->csd != NULL) {
ret = my_data->csd->volume(ALL_SESSION_VSID, volume,
@@ -3770,6 +4232,13 @@
ALL_SESSION_VSID,
DEFAULT_MUTE_RAMP_DURATION_MS};
+ if (adev->mode != AUDIO_MODE_IN_CALL &&
+ adev->mode != AUDIO_MODE_IN_COMMUNICATION)
+ return 0;
+
+ if (adev->enable_hfp)
+ mixer_ctl_name = "HFP Tx Mute";
+
set_values[0] = state;
ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
if (!ctl) {
@@ -3852,6 +4321,24 @@
new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
new_snd_devices[1] = SND_DEVICE_OUT_HEADPHONES;
ret = 0;
+ } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_LINE &&
+ !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_LINE)) {
+ *num_devices = 2;
+ new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
+ new_snd_devices[1] = SND_DEVICE_OUT_LINE;
+ ret = 0;
+ } else if (snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES &&
+ !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER_SAFE, SND_DEVICE_OUT_HEADPHONES)) {
+ *num_devices = 2;
+ new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER_SAFE;
+ new_snd_devices[1] = SND_DEVICE_OUT_HEADPHONES;
+ ret = 0;
+ } else if (snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE &&
+ !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER_SAFE, SND_DEVICE_OUT_LINE)) {
+ *num_devices = 2;
+ new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER_SAFE;
+ new_snd_devices[1] = SND_DEVICE_OUT_LINE;
+ ret = 0;
} else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET &&
!platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_ANC_HEADSET)) {
*num_devices = 2;
@@ -3924,17 +4411,44 @@
new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
new_snd_devices[1] = SND_DEVICE_OUT_BT_SCO;
ret = 0;
+ } else if (snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO &&
+ !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER_SAFE,
+ SND_DEVICE_OUT_BT_SCO)) {
+ *num_devices = 2;
+ new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER_SAFE;
+ new_snd_devices[1] = SND_DEVICE_OUT_BT_SCO;
+ ret = 0;
} else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB &&
!platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_BT_SCO_WB)) {
*num_devices = 2;
new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
new_snd_devices[1] = SND_DEVICE_OUT_BT_SCO_WB;
ret = 0;
+ } else if (snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB &&
+ !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER_SAFE,
+ SND_DEVICE_OUT_BT_SCO_WB)) {
+ *num_devices = 2;
+ new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER_SAFE;
+ new_snd_devices[1] = SND_DEVICE_OUT_BT_SCO_WB;
+ ret = 0;
+ } else if (snd_device == SND_DEVICE_OUT_SPEAKER_SAFE_AND_USB_HEADSET &&
+ !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER_SAFE, SND_DEVICE_OUT_USB_HEADSET)) {
+ *num_devices = 2;
+ new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER_SAFE;
+ new_snd_devices[1] = SND_DEVICE_OUT_USB_HEADSET;
+ ret = 0;
} else if (SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP == snd_device) {
*num_devices = 2;
new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
new_snd_devices[1] = SND_DEVICE_OUT_BT_A2DP;
ret = 0;
+ } else if (SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP == snd_device &&
+ !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER_SAFE,
+ SND_DEVICE_OUT_BT_A2DP)) {
+ *num_devices = 2;
+ new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER_SAFE;
+ new_snd_devices[1] = SND_DEVICE_OUT_BT_A2DP;
+ ret = 0;
} else if (SND_DEVICE_IN_INCALL_REC_RX_TX == snd_device) {
*num_devices = 2;
new_snd_devices[0] = SND_DEVICE_IN_INCALL_REC_RX;
@@ -4056,6 +4570,14 @@
} else if (devices == (AUDIO_DEVICE_OUT_LINE |
AUDIO_DEVICE_OUT_SPEAKER)) {
snd_device = SND_DEVICE_OUT_SPEAKER_AND_LINE;
+ } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
+ AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
+ devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
+ AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
+ snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES;
+ } else if (devices == (AUDIO_DEVICE_OUT_LINE |
+ AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
+ snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE;
} else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
AUDIO_DEVICE_OUT_SPEAKER)) {
switch(my_data->ext_disp_type) {
@@ -4080,11 +4602,24 @@
} else if ((devices & AUDIO_DEVICE_OUT_SPEAKER) &&
(devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
snd_device = SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP;
+ } else if ((devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) &&
+ (devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
+ snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP;
} else if ((devices & AUDIO_DEVICE_OUT_ALL_SCO) &&
((devices & ~AUDIO_DEVICE_OUT_ALL_SCO) == AUDIO_DEVICE_OUT_SPEAKER)) {
snd_device = adev->bt_wb_speech_enabled ?
SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB :
SND_DEVICE_OUT_SPEAKER_AND_BT_SCO;
+ } else if ((devices & AUDIO_DEVICE_OUT_ALL_SCO) &&
+ ((devices & ~AUDIO_DEVICE_OUT_ALL_SCO) == AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
+ snd_device = adev->bt_wb_speech_enabled ?
+ SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB :
+ SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO;
+ } else if ((devices == (AUDIO_DEVICE_OUT_USB_DEVICE |
+ AUDIO_DEVICE_OUT_SPEAKER_SAFE)) ||
+ (devices == (AUDIO_DEVICE_OUT_USB_HEADSET |
+ AUDIO_DEVICE_OUT_SPEAKER_SAFE))) {
+ snd_device = SND_DEVICE_OUT_SPEAKER_SAFE_AND_USB_HEADSET;
} else {
ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
goto exit;
@@ -4101,7 +4636,9 @@
if ((mode == AUDIO_MODE_IN_CALL) ||
voice_is_in_call(adev) ||
- voice_extn_compress_voip_is_active(adev)) {
+ voice_extn_compress_voip_is_active(adev) ||
+ adev->enable_voicerx ||
+ audio_extn_hfp_is_active(adev)) {
if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
devices & AUDIO_DEVICE_OUT_LINE) {
@@ -4163,6 +4700,12 @@
snd_device = SND_DEVICE_OUT_BT_SCO_WB;
else
snd_device = SND_DEVICE_OUT_BT_SCO;
+ } else if (devices & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
+ if (!adev->enable_hfp) {
+ snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
+ } else {
+ snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_HFP;
+ }
} else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
if (my_data->is_vbat_speaker || my_data->is_bcl_speaker) {
if (hw_info_is_stereo_spkr(my_data->hw_info)) {
@@ -4204,7 +4747,11 @@
} else if (devices & AUDIO_DEVICE_OUT_FM_TX) {
snd_device = SND_DEVICE_OUT_TRANSMISSION_FM;
} else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
- if (audio_extn_should_use_handset_anc(channel_count))
+ if(adev->voice.hac)
+ snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
+ else if (is_operator_tmus())
+ snd_device = SND_DEVICE_OUT_VOICE_HANDSET_TMUS;
+ else if (audio_extn_should_use_handset_anc(channel_count))
snd_device = SND_DEVICE_OUT_ANC_HANDSET;
else
snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
@@ -4238,14 +4785,26 @@
snd_device = SND_DEVICE_OUT_HEADPHONES;
} else if (devices & AUDIO_DEVICE_OUT_LINE) {
snd_device = SND_DEVICE_OUT_LINE;
+ } else if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
+ snd_device = SND_DEVICE_OUT_SPEAKER_SAFE;
} else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
if (my_data->external_spk_1)
snd_device = SND_DEVICE_OUT_SPEAKER_EXTERNAL_1;
else if (my_data->external_spk_2)
snd_device = SND_DEVICE_OUT_SPEAKER_EXTERNAL_2;
- else if (adev->speaker_lr_swap)
- snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
- else if (my_data->is_vbat_speaker || my_data->is_bcl_speaker)
+ else if (adev->speaker_lr_swap) {
+ /*
+ * Perform device switch only if acdb tuning is
+ * different between SPEAKER & SPEAKER_REVERSE,
+ * Or there will be a small pause while performing
+ * device switch.
+ */
+ if (acdb_device_table[SND_DEVICE_OUT_SPEAKER] !=
+ acdb_device_table[SND_DEVICE_OUT_SPEAKER_REVERSE])
+ snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
+ else
+ snd_device = SND_DEVICE_OUT_SPEAKER;
+ } else if (my_data->is_vbat_speaker || my_data->is_bcl_speaker)
snd_device = SND_DEVICE_OUT_SPEAKER_VBAT;
else
snd_device = SND_DEVICE_OUT_SPEAKER;
@@ -4276,14 +4835,20 @@
} else if (devices &
(AUDIO_DEVICE_OUT_USB_DEVICE |
AUDIO_DEVICE_OUT_USB_HEADSET)) {
- if (audio_extn_usb_is_capture_supported())
+ if (audio_extn_ma_supported_usb())
+ snd_device = SND_DEVICE_OUT_USB_HEADSET_SPEC;
+ else if (audio_extn_usb_is_capture_supported())
snd_device = SND_DEVICE_OUT_USB_HEADSET;
else
snd_device = SND_DEVICE_OUT_USB_HEADPHONES;
} else if (devices & AUDIO_DEVICE_OUT_FM_TX) {
snd_device = SND_DEVICE_OUT_TRANSMISSION_FM;
} else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
- snd_device = SND_DEVICE_OUT_HANDSET;
+ /*HAC support for voice-ish audio (eg visual voicemail)*/
+ if(adev->voice.hac)
+ snd_device = SND_DEVICE_OUT_VOICE_HAC_HANDSET;
+ else
+ snd_device = SND_DEVICE_OUT_HANDSET;
} else if (devices & AUDIO_DEVICE_OUT_PROXY) {
channel_count = audio_extn_get_afe_proxy_channel_count();
ALOGD("%s: setting sink capability(%d) for Proxy", __func__, channel_count);
@@ -4360,7 +4925,8 @@
(my_data->source_mic_type & SOURCE_THREE_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_TMIC_AEC_NS;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ (my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+ my_data->fluence_in_voice_comm) {
if (my_data->fluence_mode == FLUENCE_BROADSIDE)
snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
else
@@ -4375,7 +4941,8 @@
snd_device = SND_DEVICE_IN_HANDSET_TMIC_AEC_NS;
adev->acdb_settings |= TMIC_FLAG;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ (my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+ my_data->fluence_in_voice_comm) {
snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
adev->acdb_settings |= DMIC_FLAG;
} else
@@ -4396,7 +4963,8 @@
(my_data->source_mic_type & SOURCE_THREE_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_TMIC_AEC;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ (my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+ my_data->fluence_in_voice_comm) {
if (my_data->fluence_mode == FLUENCE_BROADSIDE)
snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE;
else
@@ -4411,7 +4979,8 @@
snd_device = SND_DEVICE_IN_HANDSET_TMIC_AEC;
adev->acdb_settings |= TMIC_FLAG;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ (my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+ my_data->fluence_in_voice_comm) {
snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
adev->acdb_settings |= DMIC_FLAG;
} else
@@ -4432,7 +5001,8 @@
(my_data->source_mic_type & SOURCE_THREE_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_TMIC_NS;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ (my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+ my_data->fluence_in_voice_comm) {
if (my_data->fluence_mode == FLUENCE_BROADSIDE)
snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE;
else
@@ -4447,7 +5017,8 @@
snd_device = SND_DEVICE_IN_HANDSET_TMIC_NS;
adev->acdb_settings |= TMIC_FLAG;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
- (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ (my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+ my_data->fluence_in_voice_comm) {
snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
adev->acdb_settings |= DMIC_FLAG;
} else
@@ -4573,7 +5144,9 @@
(my_data->source_mic_type & SOURCE_THREE_MIC)) {
snd_device = SND_DEVICE_IN_HANDSET_TMIC;
adev->acdb_settings |= TMIC_FLAG;
- } else { /* for FLUENCE_DUAL_MIC and SOURCE_DUAL_MIC */
+ } else if (is_operator_tmus())
+ snd_device = SND_DEVICE_IN_VOICE_DMIC_TMUS;
+ else { /* for FLUENCE_DUAL_MIC and SOURCE_DUAL_MIC */
snd_device = SND_DEVICE_IN_VOICE_DMIC;
adev->acdb_settings |= DMIC_FLAG;
}
@@ -4603,7 +5176,10 @@
if (voice_is_in_call(adev))
platform_set_echo_reference(adev, true, out_device);
- } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
+ } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
+ out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE ||
+ out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+ out_device & AUDIO_DEVICE_OUT_LINE) {
if (my_data->fluence_type != FLUENCE_NONE &&
(my_data->fluence_in_voice_call ||
my_data->fluence_in_hfp_call) &&
@@ -4626,18 +5202,29 @@
if (audio_extn_hfp_is_active(adev))
platform_set_echo_reference(adev, true, out_device);
} else {
- snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
- if (audio_extn_hfp_is_active(adev))
+ if (adev->enable_hfp) {
+ snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP;
platform_set_echo_reference(adev, true, out_device);
+ } else {
+ snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
+ if (audio_extn_hfp_is_active(adev))
+ platform_set_echo_reference(adev, true, out_device);
+ }
}
} else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX) {
snd_device = SND_DEVICE_IN_VOICE_RX;
} else if (out_device &
(AUDIO_DEVICE_OUT_USB_DEVICE |
AUDIO_DEVICE_OUT_USB_HEADSET)) {
- if (audio_extn_usb_is_capture_supported()) {
- snd_device = SND_DEVICE_IN_VOICE_USB_HEADSET_MIC;
- }
+ if (audio_extn_usb_is_capture_supported()) {
+ snd_device = SND_DEVICE_IN_VOICE_USB_HEADSET_MIC;
+ } else if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode) {
+ if (my_data->source_mic_type & SOURCE_DUAL_MIC) {
+ snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
+ } else {
+ snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
+ }
+ }
}
} else if (my_data->use_generic_handset == true && // system prop is enabled
(my_data->source_mic_type & SOURCE_QUAD_MIC) && // AND 4mic is available
@@ -4687,7 +5274,7 @@
if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_DUAL_MIC) &&
(channel_count == 2))
- snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_STEREO;
else
snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
}
@@ -4716,13 +5303,22 @@
if (my_data->fluence_in_voice_rec && channel_count == 1) {
if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
(my_data->source_mic_type & SOURCE_QUAD_MIC)) {
- snd_device = SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE;
+ if (adev->active_input->enable_aec)
+ snd_device = SND_DEVICE_IN_HANDSET_QMIC_AEC;
+ else
+ snd_device = SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE;
} else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
(my_data->source_mic_type & SOURCE_THREE_MIC)) {
- snd_device = SND_DEVICE_IN_VOICE_REC_TMIC;
+ if (adev->active_input->enable_aec)
+ snd_device = SND_DEVICE_IN_HANDSET_TMIC_AEC;
+ else
+ snd_device = SND_DEVICE_IN_VOICE_REC_TMIC;
} else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
(my_data->source_mic_type & SOURCE_DUAL_MIC)) {
- snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
+ if (adev->active_input->enable_aec)
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
+ else
+ snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
}
platform_set_echo_reference(adev, true, out_device);
} else if (((channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK) ||
@@ -4737,11 +5333,20 @@
snd_device = SND_DEVICE_IN_QUAD_MIC;
}
if (snd_device == SND_DEVICE_NONE) {
- if (adev->active_input->enable_ns)
+ if (adev->active_input->enable_aec) {
+ if (adev->active_input->enable_ns) {
+ snd_device = SND_DEVICE_IN_VOICE_REC_MIC_AEC_NS;
+ } else {
+ snd_device = SND_DEVICE_IN_VOICE_REC_MIC_AEC;
+ }
+ platform_set_echo_reference(adev, true, out_device);
+ } else if (adev->active_input->enable_ns)
snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
else
snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
}
+ } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ snd_device = SND_DEVICE_IN_VOICE_REC_HEADSET_MIC;
} else if (audio_is_usb_in_device(in_device | AUDIO_DEVICE_BIT_IN)) {
snd_device = fixup_usb_headset_mic_snd_device(platform,
SND_DEVICE_IN_VOICE_RECOG_USB_HEADSET_MIC,
@@ -4771,7 +5376,10 @@
}
} else if ((source == AUDIO_SOURCE_VOICE_COMMUNICATION) ||
(mode == AUDIO_MODE_IN_COMMUNICATION)) {
- if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
+ if (out_device & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_SPEAKER_SAFE) ||
+ out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+ (out_device & (AUDIO_DEVICE_OUT_USB_DEVICE | AUDIO_DEVICE_OUT_USB_HEADSET) &&
+ !audio_extn_usb_is_capture_supported()))
in_device = AUDIO_DEVICE_IN_BACK_MIC;
else if (out_device & AUDIO_DEVICE_OUT_EARPIECE)
in_device = AUDIO_DEVICE_IN_BUILTIN_MIC;
@@ -4824,15 +5432,24 @@
!(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
!(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (adev->active_input && (audio_extn_ssr_get_stream() == adev->active_input))
+ if ((adev->active_input && (audio_extn_ssr_get_stream() == adev->active_input)) ||
+ ((my_data->source_mic_type & SOURCE_QUAD_MIC) &&
+ channel_mask == AUDIO_CHANNEL_INDEX_MASK_4))
snd_device = SND_DEVICE_IN_QUAD_MIC;
+ else if ((my_data->source_mic_type & SOURCE_THREE_MIC) &&
+ channel_mask == AUDIO_CHANNEL_INDEX_MASK_3)
+ snd_device = SND_DEVICE_IN_THREE_MIC;
else if ((my_data->fluence_type & (FLUENCE_DUAL_MIC | FLUENCE_TRI_MIC | FLUENCE_QUAD_MIC)) &&
(channel_count == 2) && (my_data->source_mic_type & SOURCE_DUAL_MIC))
- snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_STEREO;
else
snd_device = SND_DEVICE_IN_HANDSET_MIC;
} else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- snd_device = SND_DEVICE_IN_SPEAKER_MIC;
+ if ((my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+ channel_count == 2)
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
+ else
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC;
} else if (in_device & AUDIO_DEVICE_IN_LINE) {
snd_device = SND_DEVICE_IN_LINE;
} else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
@@ -4876,10 +5493,11 @@
snd_device = SND_DEVICE_IN_HANDSET_MIC;
} else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
snd_device = SND_DEVICE_IN_HEADSET_MIC;
- } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
+ } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
+ out_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
if ((my_data->source_mic_type & SOURCE_DUAL_MIC) &&
(channel_count == 2)) {
- snd_device = SND_DEVICE_IN_SPEAKER_STEREO_DMIC;
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_STEREO;
} else if ((my_data->source_mic_type & SOURCE_MONO_MIC) &&
(channel_count == 1)) {
snd_device = SND_DEVICE_IN_SPEAKER_MIC;
@@ -5190,7 +5808,7 @@
ALOGE("[%s] memory allocation failed for %d",__func__, dlen);
goto done_key_audcal;
}
- dlen = b64decode(value, strlen(value), dptr);
+ dlen = b64_pton(value, dptr, dlen);
if(dlen<=0) {
ALOGE("[%s] data decoding failed %d", __func__, dlen);
goto done_key_audcal;
@@ -5418,7 +6036,6 @@
int platform_set_parameters(void *platform, struct str_parms *parms)
{
struct platform_data *my_data = (struct platform_data *)platform;
- struct audio_device *adev = my_data->adev;
char *value=NULL;
int len;
int ret = 0, err;
@@ -5540,6 +6157,23 @@
update_external_device_status(my_data, event_name, status);
}
+ err = str_parms_get_str(parms, PLATFORM_CONFIG_KEY_OPERATOR_INFO,
+ value, len);
+ if (err >= 0) {
+ struct operator_info *info;
+ char *str = value;
+ char *name;
+
+ str_parms_del(parms, PLATFORM_CONFIG_KEY_OPERATOR_INFO);
+ info = (struct operator_info *)calloc(1, sizeof(struct operator_info));
+ name = strtok(str, ";");
+ info->name = strdup(name);
+ info->mccmnc = strdup(str + strlen(name) + 1);
+
+ list_add_tail(&operator_info_list, &info->list);
+ ALOGV("%s: add operator[%s] mccmnc[%s]", __func__, info->name, info->mccmnc);
+ }
+
err = str_parms_get_str(parms, PLATFORM_MAX_MIC_COUNT,
value, sizeof(value));
if (err >= 0) {
@@ -5555,7 +6189,7 @@
native_audio_set_params(platform, parms, value, len);
audio_extn_spkr_prot_set_parameters(parms, value, len);
audio_extn_usb_set_sidetone_gain(parms, value, len);
- audio_extn_hfp_set_parameters(adev, parms);
+ audio_extn_hfp_set_parameters(my_data->adev, parms);
perf_lock_set_params(platform, parms, value, len);
true_32_bit_set_params(parms, value, len);
platform_spkr_device_set_params(platform, parms, value, len);
@@ -5606,6 +6240,37 @@
return ret;
}
+#ifdef INCALL_STEREO_CAPTURE_ENABLED
+int platform_set_incall_recording_session_channels(void *platform,
+ uint32_t channel_count)
+{
+ int ret = 0;
+ struct platform_data *my_data = (struct platform_data *)platform;
+ struct audio_device *adev = my_data->adev;
+ const char *mixer_ctl_name = "Voc Rec Config";
+ int num_ctl_values;
+ int i;
+ struct mixer_ctl *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, channel_count)) {
+ ALOGE("Error: invalid channel count: %x", channel_count);
+ ret = -EINVAL;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+#endif /* INCALL_STEREO_CAPTURE_ENABLED end */
+
int platform_stop_incall_recording_usecase(void *platform)
{
int ret = 0;
@@ -7677,6 +8342,41 @@
}
+// called from info parser
+void platform_add_app_type(const char *uc_type,
+ const char *mode,
+ int bw,
+ int app_type, int max_rate) {
+ struct app_type_entry *ap =
+ (struct app_type_entry *)calloc(1, sizeof(struct app_type_entry));
+
+ if (!ap) {
+ ALOGE("%s failed to allocate mem for app type", __func__);
+ return;
+ }
+
+ ap->uc_type = -1;
+ for (int i=0; i<USECASE_TYPE_MAX; i++) {
+ if (!strcmp(uc_type, usecase_type_index[i].name)) {
+ ap->uc_type = usecase_type_index[i].index;
+ break;
+ }
+ }
+
+ if (ap->uc_type == -1) {
+ free(ap);
+ return;
+ }
+
+ ALOGI("%s uc %s mode %s bw %d app_type %d max_rate %d",
+ __func__, uc_type, mode, bw, app_type, max_rate);
+ ap->bit_width = bw;
+ ap->app_type = app_type;
+ ap->max_rate = max_rate;
+ ap->mode = strdup(mode);
+ list_add_tail(&app_type_entry_list, &ap->node);
+}
+
void platform_reset_edid_info(void *platform) {
ALOGV("%s:", __func__);
@@ -7988,7 +8688,10 @@
switch(snd_device) {
case SND_DEVICE_OUT_SPEAKER:
+ case SND_DEVICE_OUT_SPEAKER_REVERSE:
return SND_DEVICE_OUT_SPEAKER_PROTECTED;
+ case SND_DEVICE_OUT_SPEAKER_SAFE:
+ return SND_DEVICE_OUT_SPEAKER_SAFE;
case SND_DEVICE_OUT_VOICE_SPEAKER:
return SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED;
case SND_DEVICE_OUT_VOICE_SPEAKER_2:
@@ -8087,7 +8790,8 @@
{
int ret;
if ((out_snd_device == SND_DEVICE_OUT_USB_HEADSET) ||
- (out_snd_device == SND_DEVICE_OUT_USB_HEADPHONES)) {
+ (out_snd_device == SND_DEVICE_OUT_USB_HEADPHONES) ||
+ (out_snd_device == SND_DEVICE_OUT_VOICE_USB_HEADSET)) {
if (property_get_bool("vendor.audio.usb.disable.sidetone", 0)) {
ALOGI("Debug: Disable sidetone");
} else {
@@ -8363,6 +9067,7 @@
{
const char *mixer_ctl_name = "Swap channel";
struct mixer_ctl *ctl;
+ const char *mixer_path;
struct platform_data *my_data = (struct platform_data *)adev->platform;
// forced to set to swap, but device not rotated ... ignore set
@@ -8371,6 +9076,14 @@
ALOGV("%s:", __func__);
+ if (swap_channels) {
+ mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_REVERSE);
+ audio_route_apply_and_update_path(adev->audio_route, mixer_path);
+ } else {
+ mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER);
+ audio_route_apply_and_update_path(adev->audio_route, mixer_path);
+ }
+
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);
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 60e6581..44d4a74 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -58,6 +58,7 @@
*/
#define AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND \
(AUDIO_DEVICE_OUT_EARPIECE | AUDIO_DEVICE_OUT_SPEAKER | \
+ AUDIO_DEVICE_OUT_SPEAKER_SAFE | \
AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE | \
AUDIO_DEVICE_OUT_LINE)
@@ -85,13 +86,16 @@
SND_DEVICE_OUT_SPEAKER_EXTERNAL_1,
SND_DEVICE_OUT_SPEAKER_EXTERNAL_2,
SND_DEVICE_OUT_SPEAKER_REVERSE,
+ SND_DEVICE_OUT_SPEAKER_SAFE,
SND_DEVICE_OUT_SPEAKER_VBAT,
SND_DEVICE_OUT_LINE,
SND_DEVICE_OUT_HEADPHONES,
SND_DEVICE_OUT_HEADPHONES_DSD,
SND_DEVICE_OUT_HEADPHONES_44_1,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
+ SND_DEVICE_OUT_SPEAKER_SAFE_AND_HEADPHONES,
SND_DEVICE_OUT_SPEAKER_AND_LINE,
+ SND_DEVICE_OUT_SPEAKER_SAFE_AND_LINE,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2,
SND_DEVICE_OUT_VOICE_HANDSET,
@@ -110,20 +114,29 @@
SND_DEVICE_OUT_BT_SCO_WB,
SND_DEVICE_OUT_BT_A2DP,
SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP,
+ SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_A2DP,
+ SND_DEVICE_OUT_VOICE_HANDSET_TMUS,
SND_DEVICE_OUT_SPEAKER_AND_BT_SCO,
+ SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO,
SND_DEVICE_OUT_SPEAKER_AND_BT_SCO_WB,
+ SND_DEVICE_OUT_SPEAKER_SAFE_AND_BT_SCO_WB,
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_TTY_FULL_USB,
SND_DEVICE_OUT_VOICE_TTY_VCO_USB,
+ SND_DEVICE_OUT_VOICE_HAC_HANDSET,
SND_DEVICE_OUT_VOICE_TX,
+ SND_DEVICE_OUT_VOICE_MUSIC_TX,
+ SND_DEVICE_OUT_VOICE_SPEAKER_HFP,
SND_DEVICE_OUT_AFE_PROXY,
SND_DEVICE_OUT_USB_HEADSET,
SND_DEVICE_OUT_USB_HEADPHONES,
SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET,
+ SND_DEVICE_OUT_SPEAKER_SAFE_AND_USB_HEADSET,
SND_DEVICE_OUT_VOICE_USB_HEADPHONES,
SND_DEVICE_OUT_VOICE_USB_HEADSET,
+ SND_DEVICE_OUT_USB_HEADSET_SPEC,
SND_DEVICE_OUT_TRANSMISSION_FM,
SND_DEVICE_OUT_ANC_HEADSET,
SND_DEVICE_OUT_ANC_FB_HEADSET,
@@ -176,8 +189,10 @@
SND_DEVICE_IN_SPEAKER_DMIC_NS,
SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS,
SND_DEVICE_IN_HEADSET_MIC,
+ SND_DEVICE_IN_HEADSET_MIC_AEC,
SND_DEVICE_IN_HEADSET_MIC_FLUENCE,
SND_DEVICE_IN_VOICE_SPEAKER_MIC,
+ SND_DEVICE_IN_VOICE_SPEAKER_MIC_HFP,
SND_DEVICE_IN_VOICE_HEADSET_MIC,
SND_DEVICE_IN_SPDIF,
SND_DEVICE_IN_HDMI_MIC,
@@ -189,6 +204,7 @@
SND_DEVICE_IN_BT_A2DP,
SND_DEVICE_IN_CAMCORDER_MIC,
SND_DEVICE_IN_VOICE_DMIC,
+ SND_DEVICE_IN_VOICE_DMIC_TMUS,
SND_DEVICE_IN_VOICE_SPEAKER_DMIC,
SND_DEVICE_IN_VOICE_SPEAKER_TMIC,
SND_DEVICE_IN_VOICE_SPEAKER_QMIC,
@@ -199,8 +215,11 @@
SND_DEVICE_IN_VOICE_TTY_HCO_USB_MIC,
SND_DEVICE_IN_VOICE_REC_MIC,
SND_DEVICE_IN_VOICE_REC_MIC_NS,
+ SND_DEVICE_IN_VOICE_REC_MIC_AEC,
+ SND_DEVICE_IN_VOICE_REC_MIC_AEC_NS,
SND_DEVICE_IN_VOICE_REC_DMIC_STEREO,
SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE,
+ SND_DEVICE_IN_VOICE_REC_HEADSET_MIC,
SND_DEVICE_IN_VOICE_RX,
SND_DEVICE_IN_USB_HEADSET_MIC,
SND_DEVICE_IN_USB_HEADSET_MIC_AEC,
@@ -214,8 +233,8 @@
SND_DEVICE_IN_CAPTURE_FM,
SND_DEVICE_IN_AANC_HANDSET_MIC,
SND_DEVICE_IN_QUAD_MIC,
- SND_DEVICE_IN_HANDSET_STEREO_DMIC,
- SND_DEVICE_IN_SPEAKER_STEREO_DMIC,
+ SND_DEVICE_IN_HANDSET_DMIC_STEREO,
+ SND_DEVICE_IN_SPEAKER_DMIC_STEREO,
SND_DEVICE_IN_CAPTURE_VI_FEEDBACK,
SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_1,
SND_DEVICE_IN_CAPTURE_VI_FEEDBACK_MONO_2,
@@ -226,6 +245,7 @@
SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE,
SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC,
SND_DEVICE_IN_HANDSET_QMIC,
+ SND_DEVICE_IN_HANDSET_QMIC_AEC,
SND_DEVICE_IN_SPEAKER_QMIC_AEC,
SND_DEVICE_IN_SPEAKER_QMIC_NS,
SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS,
@@ -349,6 +369,12 @@
#define AUDIO_CAPTURE_PERIOD_DURATION_MSEC 20
#define AUDIO_CAPTURE_PERIOD_COUNT 2
+#define VOIP_CAPTURE_PERIOD_DURATION_MSEC 20
+#define VOIP_CAPTURE_PERIOD_COUNT 2
+
+#define VOIP_PLAYBACK_PERIOD_DURATION_MSEC 20
+#define VOIP_PLAYBACK_PERIOD_COUNT 2
+
#define LOW_LATENCY_CAPTURE_SAMPLE_RATE 48000
#define LOW_LATENCY_CAPTURE_PERIOD_SIZE 240
#define LOW_LATENCY_CAPTURE_USE_CASE 1
@@ -390,6 +416,7 @@
#define SPKR_PROT_CALIB_TX_PCM_DEVICE 25
#endif
#define PLAYBACK_OFFLOAD_DEVICE 9
+#define QUAT_MI2S_PCM_DEVICE 44
// Direct_PCM
#if defined (PLATFORM_MSM8994) || defined (PLATFORM_MSM8996) || defined (PLATFORM_APQ8084) || defined (PLATFORM_MSM8998) || defined (PLATFORM_SDM845) || defined (PLATFORM_SDM710) ||defined (PLATFORM_QCS605) ||defined (PLATFORM_SDX24) || defined (PLATFORM_MSMNILE) || defined (PLATFORM_MSMSTEPPE) || defined (PLATFORM_QCS405)
@@ -443,7 +470,7 @@
#define VOLTE_CALL_PCM_DEVICE 17
#define QCHAT_CALL_PCM_DEVICE 18
#define VOWLAN_CALL_PCM_DEVICE 30
-#elif PLATFORM_APQ8084
+#elif defined (PLATFORM_APQ8084) || defined (PLATFORM_MSM8084)
#define VOICE_CALL_PCM_DEVICE 20
#define VOICE2_CALL_PCM_DEVICE 25
#define VOLTE_CALL_PCM_DEVICE 21
@@ -493,7 +520,11 @@
#define AFE_PROXY_RECORD_PCM_DEVICE 8
#ifdef PLATFORM_MSM8x26
+#ifdef EXTERNAL_BT_SUPPORTED
+#define HFP_SCO_RX 10 // AUXPCM Hostless
+#else
#define HFP_SCO_RX 28
+#endif
#define HFP_ASM_RX_TX 29
#elif PLATFORM_BEAR_FAMILY
#define HFP_SCO_RX 17
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 21f3e72..2244634 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -156,6 +156,9 @@
int platform_stop_voice_call(void *platform, uint32_t vsid);
int platform_set_mic_break_det(void *platform, bool enable);
int platform_set_voice_volume(void *platform, int volume);
+void platform_set_speaker_gain_in_combo(struct audio_device *adev,
+ snd_device_t snd_device,
+ bool enable);
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);
@@ -163,11 +166,21 @@
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);
int platform_edid_get_max_channels(void *platform);
+void platform_add_operator_specific_device(snd_device_t snd_device,
+ const char *operator,
+ const char *mixer_path,
+ unsigned int acdb_id);
void platform_get_parameters(void *platform, struct str_parms *query,
struct str_parms *reply);
int platform_set_parameters(void *platform, struct str_parms *parms);
int platform_set_incall_recording_session_id(void *platform, uint32_t session_id,
int rec_mode);
+#ifndef INCALL_STEREO_CAPTURE_ENABLED
+#define platform_set_incall_recording_session_channels(p, sc) (0)
+#else
+int platform_set_incall_recording_session_channels(void *platform,
+ uint32_t session_channels);
+#endif
int platform_stop_incall_recording_usecase(void *platform);
int platform_start_incall_music_usecase(void *platform);
int platform_stop_incall_music_usecase(void *platform);
@@ -187,6 +200,9 @@
const char * hw_interface);
int platform_get_snd_device_backend_index(snd_device_t device);
const char * platform_get_snd_device_backend_interface(snd_device_t device);
+void platform_add_app_type(const char *uc_type,
+ const char *mode,
+ int bw, int app_type, int max_sr);
/* From platform_info.c */
int platform_info_init(const char *filename, void *, caller_t);
diff --git a/hal/platform_info.c b/hal/platform_info.c
index 3341f20..f8a78d8 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -33,7 +33,7 @@
#include <errno.h>
#include <stdio.h>
#include <expat.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <cutils/str_parms.h>
#include <audio_hw.h>
#include "acdb.h"
@@ -60,7 +60,9 @@
BACKEND_NAME,
INTERFACE_NAME,
CONFIG_PARAMS,
+ OPERATOR_SPECIFIC,
GAIN_LEVEL_MAPPING,
+ APP_TYPE,
ACDB_METAINFO_KEY,
MICROPHONE_CHARACTERISTIC,
SND_DEVICES,
@@ -82,7 +84,9 @@
static void process_interface_name(const XML_Char **attr);
static void process_config_params(const XML_Char **attr);
static void process_root(const XML_Char **attr);
+static void process_operator_specific(const XML_Char **attr);
static void process_gain_db_to_level_map(const XML_Char **attr);
+static void process_app_type(const XML_Char **attr);
static void process_acdb_metainfo_key(const XML_Char **attr);
static void process_microphone_characteristic(const XML_Char **attr);
static void process_snd_dev(const XML_Char **attr);
@@ -98,6 +102,8 @@
[BACKEND_NAME] = process_backend_name,
[INTERFACE_NAME] = process_interface_name,
[CONFIG_PARAMS] = process_config_params,
+ [OPERATOR_SPECIFIC] = process_operator_specific,
+ [APP_TYPE] = process_app_type,
[GAIN_LEVEL_MAPPING] = process_gain_db_to_level_map,
[ACDB_METAINFO_KEY] = process_acdb_metainfo_key,
[MICROPHONE_CHARACTERISTIC] = process_microphone_characteristic,
@@ -236,9 +242,18 @@
* </interface_names>
* <config_params>
* <param key="snd_card_name" value="msm8994-tomtom-mtp-snd-card"/>
+ * <param key="operator_info" value="tmus;aa;bb;cc"/>
+ * <param key="operator_info" value="sprint;xx;yy;zz"/>
* ...
* ...
* </config_params>
+ *
+ * <operator_specific>
+ * <device name="???" operator="???" mixer_path="???" acdb_id="???"/>
+ * ...
+ * ...
+ * </operator_specific>
+ *
* </audio_platform_info>
*/
@@ -355,6 +370,9 @@
tbl_entry.amp = exp(tbl_entry.db * 0.115129f);
tbl_entry.level = atoi(attr[3]);
+ //custome level should be > 0. Level 0 is fixed for default
+ CHECK(tbl_entry.level > 0);
+
ALOGV("%s: amp [%f] db [%f] level [%d]", __func__,
tbl_entry.amp, tbl_entry.db, tbl_entry.level);
platform_add_gain_level_mapping(&tbl_entry);
@@ -396,6 +414,43 @@
return;
}
+static void process_operator_specific(const XML_Char **attr)
+{
+ snd_device_t snd_device = SND_DEVICE_NONE;
+
+ if (strcmp(attr[0], "name") != 0) {
+ ALOGE("%s: 'name' not found", __func__);
+ goto done;
+ }
+
+ snd_device = platform_get_snd_device_index((char *)attr[1]);
+ if (snd_device < 0) {
+ ALOGE("%s: Device %s in %s not found, no ACDB ID set!",
+ __func__, (char *)attr[3], PLATFORM_INFO_XML_PATH);
+ goto done;
+ }
+
+ if (strcmp(attr[2], "operator") != 0) {
+ ALOGE("%s: 'operator' not found", __func__);
+ goto done;
+ }
+
+ if (strcmp(attr[4], "mixer_path") != 0) {
+ ALOGE("%s: 'mixer_path' not found", __func__);
+ goto done;
+ }
+
+ if (strcmp(attr[6], "acdb_id") != 0) {
+ ALOGE("%s: 'acdb_id' not found", __func__);
+ goto done;
+ }
+
+ platform_add_operator_specific_device(snd_device, (char *)attr[3], (char *)attr[5], atoi((char *)attr[7]));
+
+done:
+ return;
+}
+
static void process_audio_effect(const XML_Char **attr, effect_type_t effect_type)
{
int index;
@@ -551,6 +606,39 @@
return;
}
+static void process_app_type(const XML_Char **attr)
+{
+ if (strcmp(attr[0], "uc_type")) {
+ ALOGE("%s: uc_type not found", __func__);
+ goto done;
+ }
+
+ if (strcmp(attr[2], "mode")) {
+ ALOGE("%s: mode not found", __func__);
+ goto done;
+ }
+
+ if (strcmp(attr[4], "bit_width")) {
+ ALOGE("%s: bit_width not found", __func__);
+ goto done;
+ }
+
+ if (strcmp(attr[6], "id")) {
+ ALOGE("%s: id not found", __func__);
+ goto done;
+ }
+
+ if (strcmp(attr[8], "max_rate")) {
+ ALOGE("%s: max rate not found", __func__);
+ goto done;
+ }
+
+ platform_add_app_type(attr[1], attr[3], atoi(attr[5]), atoi(attr[7]),
+ atoi(attr[9]));
+done:
+ return;
+}
+
static void process_microphone_characteristic(const XML_Char **attr) {
struct audio_microphone_characteristic_t microphone;
uint32_t curIdx = 0;
@@ -899,10 +987,14 @@
section = BACKEND_NAME;
} else if (strcmp(tag_name, "config_params") == 0) {
section = CONFIG_PARAMS;
+ } else if (strcmp(tag_name, "operator_specific") == 0) {
+ section = OPERATOR_SPECIFIC;
} else if (strcmp(tag_name, "interface_names") == 0) {
section = INTERFACE_NAME;
} else if (strcmp(tag_name, "gain_db_to_level_mapping") == 0) {
section = GAIN_LEVEL_MAPPING;
+ } else if (strcmp(tag_name, "app_types") == 0) {
+ section = APP_TYPE;
} else if(strcmp(tag_name, "acdb_metainfo_key") == 0) {
section = ACDB_METAINFO_KEY;
} else if (strcmp(tag_name, "microphone_characteristics") == 0) {
@@ -912,7 +1004,7 @@
} else if (strcmp(tag_name, "device") == 0) {
if ((section != ACDB) && (section != AEC) && (section != NS) &&
(section != BACKEND_NAME) && (section != BITWIDTH) &&
- (section != INTERFACE_NAME)) {
+ (section != INTERFACE_NAME) && (section != OPERATOR_SPECIFIC)) {
ALOGE("device tag only supported for acdb/backend names/bitwitdh/interface names");
return;
}
@@ -956,6 +1048,22 @@
return;
}
section = NS;
+ } else if (strcmp(tag_name, "gain_level_map") == 0) {
+ if (section != GAIN_LEVEL_MAPPING) {
+ ALOGE("gain_level_map tag only supported with GAIN_LEVEL_MAPPING section");
+ return;
+ }
+
+ section_process_fn fn = section_table[GAIN_LEVEL_MAPPING];
+ fn(attr);
+ } else if (!strcmp(tag_name, "app")) {
+ if (section != APP_TYPE) {
+ ALOGE("app tag only valid in section APP_TYPE");
+ return;
+ }
+
+ section_process_fn fn = section_table[APP_TYPE];
+ fn(attr);
} else if (strcmp(tag_name, "microphone") == 0) {
if (section != MICROPHONE_CHARACTERISTIC) {
ALOGE("microphone tag only supported with MICROPHONE_CHARACTERISTIC section");
@@ -995,7 +1103,17 @@
fn(attr);
}
} else {
- ALOGE("%s: unknown caller!", __func__);
+ if(strcmp(tag_name, "config_params") == 0) {
+ section = CONFIG_PARAMS;
+ } else if (strcmp(tag_name, "param") == 0) {
+ if (section != CONFIG_PARAMS) {
+ ALOGE("param tag only supported with CONFIG_PARAMS section");
+ return;
+ }
+
+ section_process_fn fn = section_table[section];
+ fn(attr);
+ }
}
return;
}
@@ -1021,10 +1139,14 @@
if (my_data.caller == PLATFORM) {
platform_set_parameters(my_data.platform, my_data.kvpairs);
}
+ } else if (strcmp(tag_name, "operator_specific") == 0) {
+ section = ROOT;
} else if (strcmp(tag_name, "interface_names") == 0) {
section = ROOT;
} else if (strcmp(tag_name, "gain_db_to_level_mapping") == 0) {
section = ROOT;
+ } else if (strcmp(tag_name, "app_types") == 0) {
+ section = ROOT;
} else if (strcmp(tag_name, "acdb_metainfo_key") == 0) {
section = ROOT;
} else if (strcmp(tag_name, "microphone_characteristics") == 0) {
@@ -1045,13 +1167,23 @@
int ret = 0;
int bytes_read;
void *buf;
+ char platform_info_file_name[MIXER_PATH_MAX_LENGTH]= {0};
- file = fopen(filename, "r");
+ if (filename == NULL)
+ strlcpy(platform_info_file_name, PLATFORM_INFO_XML_PATH,
+ MIXER_PATH_MAX_LENGTH);
+ else
+ strlcpy(platform_info_file_name, filename, MIXER_PATH_MAX_LENGTH);
+
+ ALOGV("%s: platform info file name is %s", __func__,
+ platform_info_file_name);
+
+ file = fopen(platform_info_file_name, "r");
section = ROOT;
if (!file) {
ALOGD("%s: Failed to open %s, using defaults.",
- __func__, filename);
+ __func__, platform_info_file_name);
ret = -ENODEV;
goto done;
}
@@ -1087,7 +1219,7 @@
if (XML_ParseBuffer(parser, bytes_read,
bytes_read == 0) == XML_STATUS_ERROR) {
ALOGE("%s: XML_ParseBuffer failed, for %s",
- __func__, filename);
+ __func__, platform_info_file_name);
ret = -EINVAL;
goto err_free_parser;
}
diff --git a/hal/voice.c b/hal/voice.c
index 7b93cfd..26116c6 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -24,7 +24,7 @@
#include <errno.h>
#include <stdlib.h>
#include <math.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <cutils/str_parms.h>
#include "audio_hw.h"
@@ -78,10 +78,14 @@
is_sidetone_dev = true;
strlcpy(mixer_path, "sidetone-headphones", MIXER_PATH_MAX_LENGTH);
break;
+ case SND_DEVICE_OUT_VOICE_USB_HEADSET:
case SND_DEVICE_OUT_USB_HEADSET:
+ // USB does not use a QC mixer.
+ mixer_path[0] = '\0';
is_sidetone_dev = true;
break;
default:
+ ALOGW("%s: %d is not a sidetone device", __func__, out_device);
is_sidetone_dev = false;
break;
}
@@ -405,6 +409,8 @@
session_id = voice_get_active_session_id(adev);
ret = platform_set_incall_recording_session_id(adev->platform,
session_id, rec_mode);
+ ret = platform_set_incall_recording_session_channels(adev->platform,
+ in->config.channels);
ALOGV("%s: Update usecase to %d",__func__, in->usecase);
} else {
/*
@@ -578,6 +584,9 @@
int ret = 0;
adev->voice.in_call = true;
+
+ voice_set_mic_mute(adev, adev->voice.mic_mute);
+
ret = voice_extn_start_call(adev);
if (ret == -ENOSYS) {
ret = voice_start_usecase(adev, USECASE_VOICE_CALL);
@@ -655,6 +664,21 @@
}
}
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HAC,
+ value, sizeof(value));
+ if (err >= 0) {
+ bool hac = false;
+ str_parms_del(parms, AUDIO_PARAMETER_KEY_HAC);
+ if (strcmp(value, AUDIO_PARAMETER_VALUE_HAC_ON) == 0)
+ hac = true;
+
+ if (hac != adev->voice.hac) {
+ adev->voice.hac = hac;
+ 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) {
@@ -677,6 +701,7 @@
memset(&adev->voice, 0, sizeof(adev->voice));
adev->voice.tty_mode = TTY_MODE_OFF;
+ adev->voice.hac = false;
adev->voice.volume = 1.0f;
adev->voice.mic_mute = false;
adev->voice.in_call = false;
diff --git a/hal/voice.h b/hal/voice.h
index bc9aa21..d257e1b 100644
--- a/hal/voice.h
+++ b/hal/voice.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -60,6 +60,7 @@
struct voice {
struct voice_session session[MAX_VOICE_SESSIONS];
int tty_mode;
+ bool hac;
bool mic_mute;
bool use_device_mute;
float volume;
diff --git a/hal/voice_extn/voice_extn.c b/hal/voice_extn/voice_extn.c
index ec85259..b170608 100644
--- a/hal/voice_extn/voice_extn.c
+++ b/hal/voice_extn/voice_extn.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -436,12 +436,15 @@
* set routing with device BT A2DP profile. Hence end all voice calls when
* set_mode(AUDIO_MODE_NORMAL) before BT A2DP profile is selected.
*/
- ALOGD("%s: end all calls", __func__);
- for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
- adev->voice.session[i].state.new = CALL_INACTIVE;
+ 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);
}
- ret = update_calls(adev);
return ret;
}
@@ -594,6 +597,7 @@
voice_extn_compress_voip_in_get_parameters(in, query, reply);
}
+#ifdef INCALL_MUSIC_ENABLED
int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev,
struct stream_out *out)
{
@@ -607,3 +611,4 @@
ALOGV("%s: mode=%d, usecase id=%d", __func__, adev->mode, out->usecase);
return 0;
}
+#endif
diff --git a/hal/voice_extn/voice_extn.h b/hal/voice_extn/voice_extn.h
index 5d1cac3..69ec3b7 100644
--- a/hal/voice_extn/voice_extn.h
+++ b/hal/voice_extn/voice_extn.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014, 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, 2016-2019, The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -42,6 +42,17 @@
void voice_extn_out_get_parameters(struct stream_out *out,
struct str_parms *query,
struct str_parms *reply);
+#ifdef INCALL_MUSIC_ENABLED
+int voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev,
+ struct stream_out *out);
+#else
+static int __unused voice_extn_check_and_set_incall_music_usecase(
+ struct audio_device *adev __unused,
+ struct stream_out *out __unused)
+{
+ return -ENOSYS;
+}
+#endif
#else
static int __unused voice_extn_start_call(struct audio_device *adev __unused)
{
diff --git a/post_proc/Android.mk b/post_proc/Android.mk
index 732c3a9..cc03b63 100644
--- a/post_proc/Android.mk
+++ b/post_proc/Android.mk
@@ -15,6 +15,8 @@
LOCAL_CFLAGS += -Wno-unused-local-typedef
LOCAL_CFLAGS += -Wno-format
LOCAL_CFLAGS += -Wno-unused-value
+LOCAL_CFLAGS += -Wall
+LOCAL_CFLAGS += -Werror
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_PROXY_DEVICE)),true)
LOCAL_CFLAGS += -DAFE_PROXY_ENABLED
@@ -74,6 +76,7 @@
LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_MODULE:= libqcompostprocbundle
LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_OWNER := qti
LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
@@ -158,6 +161,8 @@
LOCAL_CFLAGS += -Wno-unused-function
LOCAL_CFLAGS += -Wno-unused-local-typedef
LOCAL_CFLAGS += -Wno-format
+LOCAL_CFLAGS += -Wall
+LOCAL_CFLAGS += -Werror
LOCAL_SRC_FILES:= \
volume_listener.c
@@ -171,11 +176,13 @@
LOCAL_SHARED_LIBRARIES := \
libcutils \
liblog \
- libdl
+ libdl \
+ libaudioutils
LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_MODULE:= libvolumelistener
LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_OWNER := qti
LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
@@ -187,7 +194,8 @@
$(call include-path-for, audio-effects) \
$(call include-path-for, audio-route) \
vendor/qcom/opensource/audio-hal/primary-hal/hal/audio_extn \
- external/tinycompress/include
+ external/tinycompress/include \
+ system/media/audio_utils/include
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DLKM)),true)
LOCAL_HEADER_LIBRARIES += audio_kernel_headers
diff --git a/post_proc/asphere.c b/post_proc/asphere.c
index 82bb496..54555d3 100644
--- a/post_proc/asphere.c
+++ b/post_proc/asphere.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, 2017, 2019 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -35,7 +35,7 @@
#include <unistd.h>
#include <stdbool.h>
#include <sys/stat.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <cutils/list.h>
#include <cutils/str_parms.h>
#include <cutils/properties.h>
@@ -130,7 +130,7 @@
asphere.enabled = (val[0] == 0) ? false : true;
asphere.strength = val[1];
}
- ALOGD("%s: returned %d, enabled:%d, strength:%d",
+ ALOGD("%s: returned %d, enabled:%ld, strength:%ld",
__func__, ret, val[0], val[1]);
return ret;
@@ -153,7 +153,7 @@
val[1] = asphere.strength;
ret = mixer_ctl_set_array(ctl, val, sizeof(val)/sizeof(val[0]));
- ALOGD("%s: returned %d, enabled:%d, strength:%d",
+ ALOGD("%s: returned %d, enabled:%ld, strength:%ld",
__func__, ret, val[0], val[1]);
return ret;
@@ -222,7 +222,7 @@
{
char value[32] = {0};
char propValue[PROPERTY_VALUE_MAX] = {0};
- int get_status, get_enable, get_strength, ret;
+ int ret;
if (!property_get("vendor.audio.pp.asphere.enabled", propValue, "false") ||
(strncmp("true", propValue, 4) != 0)) {
diff --git a/post_proc/bass_boost.c b/post_proc/bass_boost.c
index 15945b6..1ce1c21 100644
--- a/post_proc/bass_boost.c
+++ b/post_proc/bass_boost.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, 2017-2019, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -21,7 +21,7 @@
//#define LOG_NDEBUG 0
#include <cutils/list.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <cutils/properties.h>
#include <tinyalsa/asoundlib.h>
#include <sound/audio_effects.h>
@@ -98,7 +98,6 @@
int32_t *param_tmp = (int32_t *)p->data;
int32_t param = *param_tmp++;
void *value = p->data + voffset;
- int i;
ALOGV("%s", __func__);
@@ -384,18 +383,16 @@
return 0;
}
-int bassboost_reset(effect_context_t *context)
+int bassboost_reset(effect_context_t *context __unused)
{
- bassboost_context_t *bass_ctxt = (bassboost_context_t *)context;
-
return 0;
}
int bassboost_init(effect_context_t *context)
{
bassboost_context_t *bass_ctxt = (bassboost_context_t *)context;
-
ALOGV("%s: ctxt %p", __func__, bass_ctxt);
+
context->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
context->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
context->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
@@ -574,10 +571,8 @@
return 0;
}
-int pbe_reset(effect_context_t *context)
+int pbe_reset(effect_context_t *context __unused)
{
- pbe_context_t *pbe_ctxt = (pbe_context_t *)context;
-
return 0;
}
diff --git a/post_proc/bundle.c b/post_proc/bundle.c
index ce0d0ec..1e6b91d 100644
--- a/post_proc/bundle.c
+++ b/post_proc/bundle.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, 2019, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -40,7 +40,7 @@
#include <stdlib.h>
#include <cutils/list.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <system/thread_defs.h>
#include <tinyalsa/asoundlib.h>
#include <hardware/audio_effect.h>
@@ -290,7 +290,6 @@
int offload_effects_bundle_hal_stop_output(audio_io_handle_t output, int pcm_id)
{
int ret = -1;
- struct listnode *node;
struct listnode *fx_node;
output_context_t *out_ctxt;
@@ -450,7 +449,6 @@
}
}
-exit:
pthread_mutex_unlock(&lock);
return ret;
}
@@ -768,7 +766,6 @@
{
effect_context_t * context = (effect_context_t *)self;
- int retsize;
int status = 0;
pthread_mutex_lock(&lock);
diff --git a/post_proc/effect_api.c b/post_proc/effect_api.c
index 3098850..cff4be3 100644
--- a/post_proc/effect_api.c
+++ b/post_proc/effect_api.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, 2019 The Linux Foundation. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -56,7 +56,7 @@
#include <stdbool.h>
#include <errno.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <tinyalsa/asoundlib.h>
#include <sound/audio_effects.h>
#include <sound/devdep_params.h>
@@ -860,7 +860,6 @@
{
long param_values[128] = {0};
long *p_param_values = param_values;
- uint32_t i;
ALOGV("%s", __func__);
*p_param_values++ = SOFT_VOLUME_MODULE;
@@ -926,7 +925,6 @@
{
long param_values[128] = {0};
long *p_param_values = param_values;
- uint32_t i;
ALOGV("%s", __func__);
*p_param_values++ = SOFT_VOLUME2_MODULE;
@@ -969,7 +967,6 @@
{
long param_values[128] = {0};
long *p_param_values = param_values;
- uint32_t i;
ALOGV("%s", __func__);
if (!ctl) {
diff --git a/post_proc/equalizer.c b/post_proc/equalizer.c
index 3096eb9..ed16f12 100644
--- a/post_proc/equalizer.c
+++ b/post_proc/equalizer.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014, 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, 2017-2019, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -21,7 +21,7 @@
//#define LOG_NDEBUG 0
#include <cutils/list.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <tinyalsa/asoundlib.h>
#include <sound/audio_effects.h>
#include <audio_effects/effect_equalizer.h>
@@ -358,6 +358,13 @@
}
break;
}
+
+ if (p->vsize < 1) {
+ p->status = -EINVAL;
+ android_errorWriteLog(0x534e4554, "37536407");
+ break;
+ }
+
name = (char *)value;
strlcpy(name, equalizer_get_preset_name(eq_ctxt, param2), p->vsize - 1);
name[p->vsize - 1] = 0;
@@ -450,7 +457,7 @@
if (vsize < (2 + NUM_EQ_BANDS) * sizeof(int16_t)) {
android_errorWriteLog(0x534e4554, "37563371");
ALOGE("\tERROR EQ_PARAM_PROPERTIES valueSize %d < %d",
- vsize, (2 + NUM_EQ_BANDS) * sizeof(int16_t));
+ vsize, (int) ((2 + NUM_EQ_BANDS) * sizeof(int16_t)));
p->status = -EINVAL;
break;
}
@@ -480,10 +487,8 @@
return 0;
}
-int equalizer_reset(effect_context_t *context)
+int equalizer_reset(effect_context_t *context __unused)
{
- equalizer_context_t *eq_ctxt = (equalizer_context_t *)context;
-
return 0;
}
diff --git a/post_proc/reverb.c b/post_proc/reverb.c
index be15480..a2fc4fd 100644
--- a/post_proc/reverb.c
+++ b/post_proc/reverb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 - 2014, 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, 2017-2019, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -21,7 +21,7 @@
//#define LOG_NDEBUG 0
#include <cutils/list.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <tinyalsa/asoundlib.h>
#include <sound/audio_effects.h>
#include <audio_effects/effect_environmentalreverb.h>
@@ -467,7 +467,6 @@
int32_t param = *param_tmp++;
void *value = p->data + voffset;
reverb_settings_t *reverb_settings;
- int i;
ALOGV("%s: ctxt %p, param %d", __func__, reverb_ctxt, param);
@@ -697,10 +696,8 @@
return 0;
}
-int reverb_reset(effect_context_t *context)
+int reverb_reset(effect_context_t *context __unused)
{
- reverb_context_t *reverb_ctxt = (reverb_context_t *)context;
-
return 0;
}
diff --git a/post_proc/virtualizer.c b/post_proc/virtualizer.c
index 18aaeec..0750052 100644
--- a/post_proc/virtualizer.c
+++ b/post_proc/virtualizer.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, 2017-2019, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -21,7 +21,7 @@
//#define LOG_NDEBUG 0
#include <cutils/list.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <tinyalsa/asoundlib.h>
#include <sound/audio_effects.h>
#include <audio_effects/effect_virtualizer.h>
@@ -292,7 +292,6 @@
int32_t *param_tmp = (int32_t *)p->data;
int32_t param = *param_tmp++;
void *value = p->data + voffset;
- int i;
ALOGV("%s: ctxt %p, param %d", __func__, virt_ctxt, param);
@@ -461,10 +460,8 @@
return 0;
}
-int virtualizer_reset(effect_context_t *context)
+int virtualizer_reset(effect_context_t *context __unused)
{
- virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)context;
-
return 0;
}
diff --git a/post_proc/volume_listener.c b/post_proc/volume_listener.c
index d4c3753..7372020 100644
--- a/post_proc/volume_listener.c
+++ b/post_proc/volume_listener.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2017, 2019 The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,11 +31,12 @@
//#define LOG_NDEBUG 0
#include <stdlib.h>
#include <dlfcn.h>
+#include <math.h>
#include <unistd.h>
#include <pthread.h>
#include <cutils/list.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <hardware/audio_effect.h>
#include <cutils/properties.h>
#include <platform_api.h>
@@ -62,6 +63,7 @@
#define AHAL_GAIN_DEPENDENT_INTERFACE_FUNCTION "audio_hw_send_gain_dep_calibration"
#define AHAL_GAIN_GET_MAPPING_TABLE "audio_hw_get_gain_level_mapping"
+#define DEFAULT_CAL_STEP 0
#ifdef AUDIO_FEATURE_ENABLED_GCOV
extern void __gcov_flush();
@@ -224,15 +226,22 @@
/* lock must be held when modifying or accessing created_effects_list */
pthread_mutex_t vol_listner_init_lock;
+static bool headset_cal_enabled;
+
/*
* Local functions
*/
static bool verify_context(vol_listener_context_t *context)
{
- if (context->stream_type == VC_CALL)
+ if (context->stream_type == VC_CALL &&
+ headset_cal_enabled &&
+ (context->dev_id == AUDIO_DEVICE_OUT_EARPIECE ||
+ context->dev_id == AUDIO_DEVICE_OUT_WIRED_HEADSET ||
+ context->dev_id == AUDIO_DEVICE_OUT_WIRED_HEADPHONE))
return true;
else {
- if (context->dev_id & AUDIO_DEVICE_OUT_SPEAKER)
+ if (context->dev_id & AUDIO_DEVICE_OUT_SPEAKER ||
+ context->dev_id & AUDIO_DEVICE_OUT_SPEAKER_SAFE)
return true;
else
return false;
@@ -266,12 +275,13 @@
{
// iterate through list and make decision to set new gain dep cal level for speaker device
// 1. find all usecase active on speaker
- // 2. find average of left and right for each usecase
+ // 2. find energy sum for each usecase
// 3. find the highest of all the active usecase
// 4. if new value is different than the current value then load new calibration
struct listnode *node = NULL;
- float new_vol = 0.0;
+ float new_vol = -1.0, sum_energy = 0.0, temp_vol = 0.0;
+ bool sum_energy_used = false;
int max_level = 0;
vol_listener_context_t *context = NULL;
if (dumping_enabled) {
@@ -280,16 +290,21 @@
ALOGV("%s ==> Start ...", __func__);
- // select the highest volume on speaker device
+ // compute energy sum for the active speaker device (pick loudest of both channels)
list_for_each(node, &vol_effect_list) {
context = node_to_item(node, struct vol_listener_context_s, effect_list_node);
if ((context->state == VOL_LISTENER_STATE_ACTIVE) &&
- verify_context(context) &&
- (new_vol < (context->left_vol + context->right_vol) / 2)) {
- new_vol = (context->left_vol + context->right_vol) / 2;
+ verify_context(context)) {
+ sum_energy_used = true;
+ temp_vol = fmax(context->left_vol, context->right_vol);
+ sum_energy += temp_vol * temp_vol;
}
}
+ if (sum_energy_used) {
+ new_vol = fmin(sqrt(sum_energy), 1.0);
+ }
+
if (new_vol != current_vol) {
ALOGV("%s:: Change in decision :: current volume is %f new volume is %f",
__func__, current_vol, new_vol);
@@ -300,7 +315,9 @@
if (new_vol >= 1 && total_volume_cal_step > 0) { // max amplitude, use highest DRC level
gain_dep_cal_level = volume_curve_gain_mapping_table[total_volume_cal_step - 1].level;
- } else if (new_vol <= 0) {
+ } else if (new_vol == -1) {
+ gain_dep_cal_level = DEFAULT_CAL_STEP;
+ } else if (new_vol == 0) {
gain_dep_cal_level = volume_curve_gain_mapping_table[0].level;
} else {
for (max_level = 0; max_level + 1 < total_volume_cal_step; max_level++) {
@@ -430,7 +447,9 @@
ALOGE("%s: EFFECT_CMD_INIT: %s, sending -EINVAL", __func__,
(p_reply_data == NULL) ? "p_reply_data is NULL" :
"*reply_size != sizeof(int)");
- return -EINVAL;
+ android_errorWriteLog(0x534e4554, "32669549");
+ status = -EINVAL;
+ goto exit;
}
*(int *)p_reply_data = 0;
break;
@@ -439,7 +458,9 @@
ALOGV("%s :: cmd called EFFECT_CMD_SET_CONFIG", __func__);
if (p_cmd_data == NULL || cmd_size != sizeof(effect_config_t)
|| p_reply_data == NULL || reply_size == NULL || *reply_size != sizeof(int)) {
- return -EINVAL;
+ android_errorWriteLog(0x534e4554, "32669549");
+ status = -EINVAL;
+ goto exit;
}
context->config = *(effect_config_t *)p_cmd_data;
*(int *)p_reply_data = 0;
@@ -463,7 +484,9 @@
ALOGE("%s: EFFECT_CMD_OFFLOAD: %s, sending -EINVAL", __func__,
(p_reply_data == NULL) ? "p_reply_data is NULL" :
"*reply_size != sizeof(int)");
- return -EINVAL;
+ android_errorWriteLog(0x534e4554, "32669549");
+ status = -EINVAL;
+ goto exit;
}
*(int *)p_reply_data = 0;
break;
@@ -547,13 +570,10 @@
__func__, context->dev_id, new_device);
// check if old or new device is speaker for playback usecase
- if (context->stream_type == VC_CALL)
+ if (verify_context(context) ||
+ new_device & AUDIO_DEVICE_OUT_SPEAKER ||
+ new_device & AUDIO_DEVICE_OUT_SPEAKER_SAFE)
recompute_gain_dep_cal_Level = true;
- else {
- if (context->dev_id & AUDIO_DEVICE_OUT_SPEAKER ||
- new_device & AUDIO_DEVICE_OUT_SPEAKER)
- recompute_gain_dep_cal_Level = true;
- }
context->dev_id = new_device;
@@ -692,9 +712,15 @@
// check system property to see if dumping is required
char check_dump_val[PROPERTY_VALUE_MAX];
property_get("vendor.audio.volume.listener.dump", check_dump_val, "0");
- if (atoi(check_dump_val)) {
+ if (atoi(check_dump_val))
dumping_enabled = true;
+ else {
+ property_get("audio.volume.listener.dump", check_dump_val, "0");
+ if (atoi(check_dump_val))
+ dumping_enabled = true;
}
+ headset_cal_enabled = property_get_bool(
+ "audio.volume.headset.gain.depcal", false);
init_status = 0;
list_init(&vol_effect_list);
@@ -773,7 +799,7 @@
static int vol_prc_lib_release(effect_handle_t handle)
{
- struct listnode *node = NULL;
+ struct listnode *node = NULL, *temp_node_next;
vol_listener_context_t *context = NULL;
vol_listener_context_t *recv_contex = (vol_listener_context_t *)handle;
int status = -EINVAL;
@@ -791,10 +817,18 @@
pthread_mutex_lock(&vol_listner_init_lock);
session_id = recv_contex->session_id;
stream_type = recv_contex->stream_type;
+
+ if (recv_contex->desc == NULL) {
+ ALOGE("%s: Got NULL descriptor, session %u, stream type %u",
+ __func__, session_id, stream_type);
+ dump_list_l();
+ pthread_mutex_unlock(&vol_listner_init_lock);
+ return status;
+ }
uuid = recv_contex->desc->uuid;
// check if the handle/context provided is valid
- list_for_each(node, &vol_effect_list) {
+ list_for_each_safe(node, temp_node_next, &vol_effect_list) {
context = node_to_item(node, struct vol_listener_context_s, effect_list_node);
if ((memcmp(&(context->desc->uuid), &uuid, sizeof(effect_uuid_t)) == 0)
&& (context->session_id == session_id)
diff --git a/visualizer/Android.mk b/visualizer/Android.mk
index 5c663bd..5ce31b6 100644
--- a/visualizer/Android.mk
+++ b/visualizer/Android.mk
@@ -1,4 +1,4 @@
-# Copyright 2013 The Android Open Source Project
+# Copyright 2013, 2019 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.
@@ -18,11 +18,18 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- offload_visualizer.c
+ offload_visualizer.c
LOCAL_CFLAGS+= -O2 -fvisibility=hidden
-LOCAL_CFLAGS += -Wno-unused-variable -Wno-unused-parameter -Wno-gnu-designator -Wno-unused-value -Wno-typedef-redefinition
+LOCAL_CFLAGS += \
+ -Wall \
+ -Werror \
+ -Wno-unused-variable \
+ -Wno-unused-parameter \
+ -Wno-gnu-designator \
+ -Wno-unused-value \
+ -Wno-typedef-redefinition
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_GCOV)),true)
LOCAL_CFLAGS += --coverage -fprofile-arcs -ftest-coverage
@@ -37,18 +44,18 @@
LOCAL_HEADER_LIBRARIES := libsystem_headers \
libhardware_headers
LOCAL_SHARED_LIBRARIES := \
- libcutils \
- liblog \
- libdl \
- libtinyalsa
+ libcutils \
+ liblog \
+ libdl \
+ libtinyalsa
LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_MODULE:= libqcomvisualizer
LOCAL_VENDOR_MODULE := true
LOCAL_C_INCLUDES := \
- external/tinyalsa/include \
- $(call include-path-for, audio-effects)
+ external/tinyalsa/include \
+ $(call include-path-for, audio-effects)
LOCAL_CFLAGS += -Wno-unused-variable
LOCAL_CFLAGS += -Wno-sign-compare
diff --git a/visualizer/offload_visualizer.c b/visualizer/offload_visualizer.c
index 9ad8fea..f268ab8 100644
--- a/visualizer/offload_visualizer.c
+++ b/visualizer/offload_visualizer.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2013, 2019 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.
@@ -27,7 +27,7 @@
#include <unistd.h>
#include <cutils/list.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <system/thread_defs.h>
#include <tinyalsa/asoundlib.h>
#include <audio_effects/effect_visualizer.h>
diff --git a/voice_processing/Android.mk b/voice_processing/Android.mk
index 820684a..56a3abd 100644
--- a/voice_processing/Android.mk
+++ b/voice_processing/Android.mk
@@ -4,12 +4,19 @@
# audio preprocessing wrapper
include $(CLEAR_VARS)
-LOCAL_CFLAGS += -Wno-unused-variable -Wno-gnu-designator -Wno-unused-value -Wno-unused-function
+LOCAL_CFLAGS += \
+ -Wall \
+ -Werror \
+ -Wno-unused-variable \
+ -Wno-gnu-designator \
+ -Wno-unused-value \
+ -Wno-unused-function
LOCAL_MODULE:= libqcomvoiceprocessing
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_OWNER := qti
LOCAL_SRC_FILES:= \
voice_processing.c
diff --git a/voice_processing/voice_processing.c b/voice_processing/voice_processing.c
index 32b76a5..f237108 100644
--- a/voice_processing/voice_processing.c
+++ b/voice_processing/voice_processing.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2013, 2019 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.
@@ -19,7 +19,7 @@
#include <stdlib.h>
#include <dlfcn.h>
#include <stdlib.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <cutils/list.h>
#include <unistd.h>
#include <hardware/audio_effect.h>