Merge 9c4ba54b3ecb1ee854763970b3057220994dad8a on remote branch
Change-Id: I5a80c57243eda5a4fdd98a233766cd622b4ef9a3
diff --git a/Android.mk b/Android.mk
index 6e129a1..6d8a9f9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,4 +1,4 @@
-ifneq ($(filter mpq8092 msm8960 msm8226 msm8x26 msm8610 msm8974 msm8x74 apq8084 msm8916 msm8994 msm8992 msm8909 msm8996 msm8952,$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter mpq8092 msm8960 msm8226 msm8x26 msm8610 msm8974 msm8x74 apq8084 msm8916 msm8994 msm8992 msm8909 msm8996 msm8952 msm8937 thorium,$(TARGET_BOARD_PLATFORM)),)
MY_LOCAL_PATH := $(call my-dir)
diff --git a/audiod/Android.mk b/audiod/Android.mk
index 2092620..c89b3cd 100644
--- a/audiod/Android.mk
+++ b/audiod/Android.mk
@@ -2,6 +2,10 @@
include $(CLEAR_VARS)
+ifneq (,$(findstring $(PLATFORM_VERSION), 5.0 5.1 5.1.1))
+include external/stlport/libstlport.mk
+endif
+
LOCAL_SRC_FILES:= \
audiod_main.cpp \
AudioDaemon.cpp \
@@ -14,6 +18,10 @@
libbinder \
libmedia
+ifneq (,$(findstring $(PLATFORM_VERSION), 5.0 5.1 5.1.1))
+LOCAL_SHARED_LIBRARIES += libstlport
+endif
+
LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_MODULE:= audiod
diff --git a/hal/Android.mk b/hal/Android.mk
index 4e6bf91..4bd87f9 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -32,7 +32,7 @@
endif
endif
-ifneq ($(filter msm8916 msm8909 msm8952,$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter msm8916 msm8909 msm8952 msm8937 thorium,$(TARGET_BOARD_PLATFORM)),)
AUDIO_PLATFORM = msm8916
MULTIPLE_HW_VARIANTS_ENABLED := true
LOCAL_CFLAGS := -DPLATFORM_MSM8916
@@ -53,8 +53,8 @@
LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_HDMI_EDID)),true)
- LOCAL_SRC_FILES += edid.c
LOCAL_CFLAGS += -DHDMI_EDID
+ LOCAL_SRC_FILES += edid.c
endif
ifeq ($(strip $(AUDIO_USE_LL_AS_PRIMARY_OUTPUT)),true)
@@ -161,10 +161,6 @@
endif
endif
-ifeq ($(strip $(AUDIO_FEATURE_ENABLED_MULTIPLE_TUNNEL)), true)
- LOCAL_CFLAGS += -DMULTIPLE_OFFLOAD_ENABLED
-endif
-
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_FLAC_DECODER)),true)
LOCAL_CFLAGS += -DFLAC_OFFLOAD_ENABLED
LOCAL_CFLAGS += -DCOMPRESS_METADATA_NEEDED
@@ -258,9 +254,11 @@
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXT_HDMI)),true)
LOCAL_CFLAGS += -DAUDIO_EXTERNAL_HDMI_ENABLED
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_HDMI_PASSTHROUGH)),true)
LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/audio-parsers
LOCAL_SHARED_LIBRARIES += libaudioparsers
endif
+endif
ifeq ($(strip $(BOARD_SUPPORTS_SOUND_TRIGGER)),true)
LOCAL_CFLAGS += -DSOUND_TRIGGER_ENABLED
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 7154ab0..fe959be 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -874,9 +874,7 @@
static perf_lock_acquire_t perf_lock_acq;
static perf_lock_release_t perf_lock_rel;
-static int perf_lock_handle;
char opt_lib_path[512] = {0};
-int perf_lock_opts[1] = {0x20E};
int audio_extn_perf_lock_init(void)
{
@@ -914,19 +912,30 @@
return ret;
}
-void audio_extn_perf_lock_acquire(void)
+void audio_extn_perf_lock_acquire(int *handle, int duration,
+ int *perf_lock_opts, int size)
{
- if (perf_lock_acq)
- perf_lock_handle = perf_lock_acq(perf_lock_handle, 0, perf_lock_opts, 1);
- else
- ALOGE("%s: Perf lock acquire error \n", __func__);
+
+ if (!perf_lock_opts || !size || !perf_lock_acq || !handle)
+ return -EINVAL;
+ /*
+ * Acquire performance lock for 1 sec during device path bringup.
+ * Lock will be released either after 1 sec or when perf_lock_release
+ * function is executed.
+ */
+ *handle = perf_lock_acq(*handle, duration, perf_lock_opts, size);
+ if (*handle <= 0)
+ ALOGE("%s: Failed to acquire perf lock, err: %d\n",
+ __func__, *handle);
}
-void audio_extn_perf_lock_release(void)
+void audio_extn_perf_lock_release(int *handle)
{
- if (perf_lock_rel && perf_lock_handle)
- perf_lock_rel(perf_lock_handle);
- else
+ if (perf_lock_rel && handle && (*handle > 0)) {
+ perf_lock_rel(*handle);
+ *handle = 0;
+ } else {
ALOGE("%s: Perf lock release error \n", __func__);
+ }
}
#endif /* KPI_OPTIMIZE_ENABLED */
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index d87d407..5231e93 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -48,7 +48,7 @@
#define audio_is_offload_pcm(format) (0)
#define OFFLOAD_USE_SMALL_BUFFER false
#else
-#define OFFLOAD_USE_SMALL_BUFFER ((info->format & AUDIO_FORMAT_PCM_OFFLOAD) == AUDIO_FORMAT_PCM_OFFLOAD)
+#define OFFLOAD_USE_SMALL_BUFFER ((info->format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM_OFFLOAD)
#endif
#ifndef AFE_PROXY_ENABLED
@@ -275,6 +275,7 @@
#define audio_extn_spkr_prot_is_enabled() (false)
#define audio_extn_spkr_prot_get_acdb_id(snd_device) (-EINVAL)
#define audio_extn_get_spkr_prot_snd_device(snd_device) (snd_device)
+#define audio_extn_spkr_prot_set_parameters(parms, value, len) (0)
#else
void audio_extn_spkr_prot_init(void *adev);
int audio_extn_spkr_prot_start_processing(snd_device_t snd_device);
@@ -283,6 +284,8 @@
int audio_extn_spkr_prot_get_acdb_id(snd_device_t snd_device);
int audio_extn_get_spkr_prot_snd_device(snd_device_t snd_device);
void audio_extn_spkr_prot_calib_cancel(void *adev);
+void audio_extn_spkr_prot_set_parameters(struct str_parms *parms,
+ char *value, int len);
#endif
#ifndef COMPRESS_CAPTURE_ENABLED
@@ -308,6 +311,7 @@
#define audio_extn_dts_eagle_set_parameters(adev, parms) (0)
#define audio_extn_dts_eagle_get_parameters(adev, query, reply) (0)
#define audio_extn_dts_eagle_fade(adev, fade_in, out) (0)
+#define audio_extn_dts_eagle_send_lic() (0)
#define audio_extn_dts_create_state_notifier_node(stream_out) (0)
#define audio_extn_dts_notify_playback_state(stream_out, has_video, sample_rate, \
channels, is_playing) (0)
@@ -319,6 +323,7 @@
int audio_extn_dts_eagle_get_parameters(const struct audio_device *adev,
struct str_parms *query, struct str_parms *reply);
int audio_extn_dts_eagle_fade(const struct audio_device *adev, bool fade_in, const struct stream_out *out);
+void audio_extn_dts_eagle_send_lic();
void audio_extn_dts_create_state_notifier_node(int stream_out);
void audio_extn_dts_notify_playback_state(int stream_out, int has_video, int sample_rate,
int channels, int is_playing);
@@ -443,7 +448,8 @@
uint32_t bit_width,
audio_channel_mask_t channel_mask,
struct stream_app_type_cfg *app_type_cfg);
-int audio_extn_utils_send_app_type_cfg(struct audio_usecase *usecase);
+int audio_extn_utils_send_app_type_cfg(struct audio_device *adev,
+ struct audio_usecase *usecase);
void audio_extn_utils_send_audio_calibration(struct audio_device *adev,
struct audio_usecase *usecase);
#ifdef DS2_DOLBY_DAP_ENABLED
@@ -495,17 +501,19 @@
#ifndef KPI_OPTIMIZE_ENABLED
#define audio_extn_perf_lock_init() (0)
-#define audio_extn_perf_lock_acquire() (0)
-#define audio_extn_perf_lock_release() (0)
+#define audio_extn_perf_lock_acquire(handle, duration, opts, size) (0)
+#define audio_extn_perf_lock_release(handle) (0)
#else
int audio_extn_perf_lock_init(void);
-void audio_extn_perf_lock_acquire(void);
-void audio_extn_perf_lock_release(void);
+void audio_extn_perf_lock_acquire(int *handle, int duration,
+ int *opts, int size);
+void audio_extn_perf_lock_release(int *handle);
+
#endif /* KPI_OPTIMIZE_ENABLED */
#ifndef AUDIO_EXTERNAL_HDMI_ENABLED
-#define setChannelStatus(out, buffer, bytes) (0)
+#define audio_utils_set_hdmi_channel_status(out, buffer, bytes) (0)
#else
-void setChannelStatus(struct stream_out *out, char * buffer, size_t bytes);
+void audio_utils_set_hdmi_channel_status(struct stream_out *out, char * buffer, size_t bytes);
#endif
#endif /* AUDIO_EXTN_H */
diff --git a/hal/audio_extn/dts_eagle.c b/hal/audio_extn/dts_eagle.c
index 7608a61..71bfea6 100644
--- a/hal/audio_extn/dts_eagle.c
+++ b/hal/audio_extn/dts_eagle.c
@@ -39,6 +39,7 @@
#define STATE_NOTIFY_FILE "/data/misc/dts/stream"
#define FADE_NOTIFY_FILE "/data/misc/dts/fade"
#define DTS_EAGLE_KEY "DTS_EAGLE"
+#define DEVICE_NODE "/dev/snd/hwC0D3"
#define MAX_LENGTH_OF_INTEGER_IN_STRING 13
#define PARAM_GET_MAX_SIZE 512
@@ -116,7 +117,7 @@
}
if (!sent) {
- int fd = open(GENERIC_AUDIO_DEVICE_NODE, O_RDWR);
+ int fd = open(DEVICE_NODE, O_RDWR);
if (get) {
ALOGD("DTS_EAGLE_HAL (%s): no stream opened, attempting to retrieve directly from cache", __func__);
@@ -136,7 +137,7 @@
}
close(fd);
} else {
- ALOGE("DTS_EAGLE_HAL (%s): couldn't open device %s\n", __func__, GENERIC_AUDIO_DEVICE_NODE);
+ ALOGE("DTS_EAGLE_HAL (%s): couldn't open device %s\n", __func__, DEVICE_NODE);
ret = -EINVAL;
}
}
@@ -189,6 +190,28 @@
return 0;
}
+void audio_extn_dts_eagle_send_lic() {
+ char prop[PROPERTY_VALUE_MAX] = {0};
+ bool enabled;
+ property_get("use.dts_eagle", prop, "0");
+ enabled = !strncmp("true", prop, sizeof("true")) || atoi(prop);
+ if (!enabled)
+ return;
+ int fd = open(DEVICE_NODE, O_RDWR);
+ int index = 1;
+ if (fd >= 0) {
+ if (ioctl(fd, DTS_EAGLE_IOCTL_SEND_LICENSE, &index) < 0) {
+ ALOGE("DTS_EAGLE_HAL: error sending license after adsp ssr");
+ } else {
+ ALOGD("DTS_EAGLE_HAL: sent license after adsp ssr");
+ }
+ close(fd);
+ } else {
+ ALOGE("DTS_EAGLE_HAL: error opening eagle");
+ }
+ return;
+}
+
void audio_extn_dts_eagle_set_parameters(struct audio_device *adev, struct str_parms *parms) {
int ret, val;
char value[32] = { 0 }, prop[PROPERTY_VALUE_MAX];
diff --git a/hal/audio_extn/fm.c b/hal/audio_extn/fm.c
index fcf5eb0..6381e68 100644
--- a/hal/audio_extn/fm.c
+++ b/hal/audio_extn/fm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index a73dfa1..3e09e55 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -47,6 +47,8 @@
#ifdef PLATFORM_MSM8994
#define HFP_RX_VOLUME "SEC AUXPCM LOOPBACK Volume"
+#elif defined PLATFORM_MSM8996
+#define HFP_RX_VOLUME "PRI AUXPCM LOOPBACK Volume"
#else
#define HFP_RX_VOLUME "Internal HFP RX Volume"
#endif
diff --git a/hal/audio_extn/soundtrigger.c b/hal/audio_extn/soundtrigger.c
index c13c2f3..3c16c88 100644
--- a/hal/audio_extn/soundtrigger.c
+++ b/hal/audio_extn/soundtrigger.c
@@ -334,18 +334,6 @@
event.u.value = val;
st_dev->st_callback(AUDIO_EVENT_NUM_ST_SESSIONS, &event);
}
-
- ret = str_parms_get_int(params, AUDIO_PARAMETER_DEVICE_CONNECT, &val);
- if ((ret >= 0) && audio_is_input_device(val)) {
- event.u.value = val;
- st_dev->st_callback(AUDIO_EVENT_DEVICE_CONNECT, &event);
- }
-
- ret = str_parms_get_int(params, AUDIO_PARAMETER_DEVICE_DISCONNECT, &val);
- if ((ret >= 0) && audio_is_input_device(val)) {
- event.u.value = val;
- st_dev->st_callback(AUDIO_EVENT_DEVICE_DISCONNECT, &event);
- }
}
int audio_extn_sound_trigger_init(struct audio_device *adev)
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index 040b140..efa885e 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -95,15 +95,20 @@
#define SPKR_PROCESSING_IN_PROGRESS 1
#define SPKR_PROCESSING_IN_IDLE 0
-#ifdef PLATFORM_MSM8916
-#define ACDB_DEVICE_SPKR_PROT_WSA_ANALOG 136
-#define ACDB_DEVICE_VI_FEEDBACK_WSA_ANALOG 137
-#endif
-
#define MAX_PATH (256)
#define THERMAL_SYSFS "/sys/class/thermal"
#define TZ_TYPE "/sys/class/thermal/thermal_zone%d/type"
#define TZ_WSA "/sys/class/thermal/thermal_zone%d/temp"
+
+#define AUDIO_PARAMETER_KEY_SPKR_TZ_1 "spkr_1_tz_name"
+#define AUDIO_PARAMETER_KEY_SPKR_TZ_2 "spkr_2_tz_name"
+
+#define SPKR_TZ_1 "wsatz.12"
+#define SPKR_TZ_2 "wsatz.11"
+#define SPKR_TZ_3 "wsatz.14"
+#define SPKR_TZ_4 "wsatz.13"
+
+
/*Modes of Speaker Protection*/
enum speaker_protection_mode {
SPKR_PROTECTION_DISABLED = -1,
@@ -137,8 +142,6 @@
bool spkr_in_use;
struct timespec spkr_last_time_used;
bool wsa_found;
- char *spkr_1_tz_name;
- char *spkr_2_tz_name;
int spkr_1_tzn;
int spkr_2_tzn;
};
@@ -154,8 +157,14 @@
.avail_min = 0,
};
+struct spkr_tz_names {
+ char *spkr_1_name;
+ char *spkr_2_name;
+};
+
static struct speaker_prot_session handle;
static int vi_feed_no_channels;
+static struct spkr_tz_names tz_names;
/*===========================================================================
FUNCTION get_tzn
@@ -753,7 +762,7 @@
continue;
}
if (goahead) {
- if (spk_1_tzn > 0) {
+ if (spk_1_tzn >= 0) {
snprintf(wsa_path, MAX_PATH, TZ_WSA, spk_1_tzn);
ALOGV("%s: wsa_path: %s\n", __func__, wsa_path);
thermal_fd = -1;
@@ -796,7 +805,7 @@
continue;
}
}
- if (spk_2_tzn > 0) {
+ if (spk_2_tzn >= 0) {
snprintf(wsa_path, MAX_PATH, TZ_WSA, spk_2_tzn);
ALOGV("%s: wsa_path: %s\n", __func__, wsa_path);
thermal_fd = open(wsa_path, O_RDONLY);
@@ -923,15 +932,42 @@
static bool is_wsa_present(void)
{
- handle.spkr_1_tz_name = platform_get_spkr_1_tz_name(SND_DEVICE_OUT_SPEAKER);
- handle.spkr_2_tz_name = platform_get_spkr_2_tz_name(SND_DEVICE_OUT_SPEAKER);
- handle.spkr_1_tzn = get_tzn(handle.spkr_1_tz_name);
- handle.spkr_2_tzn = get_tzn(handle.spkr_2_tz_name);
+ ALOGD("%s: tz1: %s, tz2: %s", __func__,
+ tz_names.spkr_1_name, tz_names.spkr_2_name);
+ handle.spkr_1_tzn = get_tzn(tz_names.spkr_1_name);
+ handle.spkr_2_tzn = get_tzn(tz_names.spkr_2_name);
if ((handle.spkr_1_tzn >= 0) || (handle.spkr_2_tzn >= 0))
handle.wsa_found = true;
return handle.wsa_found;
}
+void audio_extn_spkr_prot_set_parameters(struct str_parms *parms,
+ char *value, int len)
+{
+ int err;
+
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SPKR_TZ_1,
+ value, len);
+ if (err >= 0) {
+ if ((!strncmp(SPKR_TZ_1, value, sizeof(SPKR_TZ_1)) ||
+ (!strncmp(SPKR_TZ_3, value, sizeof(SPKR_TZ_3)))))
+ tz_names.spkr_1_name = strdup(value);
+ str_parms_del(parms, AUDIO_PARAMETER_KEY_SPKR_TZ_1);
+ }
+
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SPKR_TZ_2,
+ value, len);
+ if (err >= 0) {
+ if ((!strncmp(SPKR_TZ_2, value, sizeof(SPKR_TZ_2)) ||
+ (!strncmp(SPKR_TZ_4, value, sizeof(SPKR_TZ_4)))))
+ tz_names.spkr_2_name = strdup(value);
+ str_parms_del(parms, AUDIO_PARAMETER_KEY_SPKR_TZ_2);
+ }
+
+ ALOGV("%s: tz1: %s, tz2: %s", __func__,
+ tz_names.spkr_1_name, tz_names.spkr_2_name);
+}
+
void audio_extn_spkr_prot_init(void *adev)
{
char value[PROPERTY_VALUE_MAX];
@@ -955,24 +991,6 @@
handle.spkr_prot_t0 = -1;
if (is_wsa_present()) {
-#ifdef PLATFORM_MSM8916
- if (platform_get_wsa_mode(adev) == 1) {
- ALOGD("%s: WSA analog mode", __func__);
- platform_set_snd_device_backend(SND_DEVICE_OUT_VOICE_SPEAKER_WSA,
- "speaker-protected");
- platform_set_snd_device_acdb_id(SND_DEVICE_OUT_SPEAKER_PROTECTED,
- ACDB_DEVICE_SPKR_PROT_WSA_ANALOG);
- platform_set_snd_device_acdb_id(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED,
- ACDB_DEVICE_SPKR_PROT_WSA_ANALOG);
- platform_set_snd_device_acdb_id(SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT,
- ACDB_DEVICE_SPKR_PROT_WSA_ANALOG);
- platform_set_snd_device_acdb_id(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED_VBAT,
- ACDB_DEVICE_SPKR_PROT_WSA_ANALOG);
- platform_set_snd_device_acdb_id(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK,
- ACDB_DEVICE_VI_FEEDBACK_WSA_ANALOG);
- pcm_config_skr_prot.channels = 2;
- }
-#endif
pthread_cond_init(&handle.spkr_calib_cancel, NULL);
pthread_cond_init(&handle.spkr_calibcancel_ack, NULL);
pthread_mutex_init(&handle.mutex_spkr_prot, NULL);
@@ -981,6 +999,8 @@
(void)pthread_create(&handle.spkr_calibration_thread,
(const pthread_attr_t *) NULL, spkr_calibration_thread, &handle);
return;
+ } else {
+ ALOGD("%s: WSA spkr calibration thread is not created", __func__);
}
pthread_cond_init(&handle.spkr_prot_thermalsync, NULL);
pthread_cond_init(&handle.spkr_calib_cancel, NULL);
@@ -1047,9 +1067,7 @@
switch(snd_device) {
case SND_DEVICE_OUT_SPEAKER:
-#ifdef PLATFORM_MSM8916
case SND_DEVICE_OUT_SPEAKER_WSA:
-#endif
acdb_id = platform_get_snd_device_acdb_id(SND_DEVICE_OUT_SPEAKER_PROTECTED);
break;
case SND_DEVICE_OUT_SPEAKER_VBAT:
@@ -1059,9 +1077,9 @@
acdb_id = platform_get_snd_device_acdb_id(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED_VBAT);
break;
case SND_DEVICE_OUT_VOICE_SPEAKER:
-#ifdef PLATFORM_MSM8916
+
case SND_DEVICE_OUT_VOICE_SPEAKER_WSA:
-#endif
+
acdb_id = platform_get_snd_device_acdb_id(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED);
break;
default:
@@ -1078,18 +1096,14 @@
switch(snd_device) {
case SND_DEVICE_OUT_SPEAKER:
-#ifdef PLATFORM_MSM8916
case SND_DEVICE_OUT_SPEAKER_WSA:
-#endif
return SND_DEVICE_OUT_SPEAKER_PROTECTED;
case SND_DEVICE_OUT_SPEAKER_VBAT:
return SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT;
case SND_DEVICE_OUT_VOICE_SPEAKER_VBAT:
return SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED_VBAT;
case SND_DEVICE_OUT_VOICE_SPEAKER:
-#ifdef PLATFORM_MSM8916
case SND_DEVICE_OUT_VOICE_SPEAKER_WSA:
-#endif
return SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED;
default:
return snd_device;
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index e917367..9ec4243 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -36,8 +36,10 @@
#include "voice.h"
#ifdef AUDIO_EXTERNAL_HDMI_ENABLED
+#ifdef HDMI_PASSTHROUGH_ENABLED
#include "audio_parsers.h"
#endif
+#endif
#define AUDIO_OUTPUT_POLICY_VENDOR_CONFIG_FILE "/vendor/etc/audio_output_policy.conf"
@@ -57,18 +59,18 @@
#define MAX_BASEINDEX_LEN 256
#ifdef AUDIO_EXTERNAL_HDMI_ENABLED
-#define PROFESSIONAL (1<<0) /* 0 = consumer, 1 = professional */
-#define NON_LPCM (1<<1) /* 0 = audio, 1 = non-audio */
-#define SR_44100 (0<<0) /* 44.1kHz */
-#define SR_NOTID (1<<0) /* non indicated */
-#define SR_48000 (2<<0) /* 48kHz */
-#define SR_32000 (3<<0) /* 32kHz */
-#define SR_22050 (4<<0) /* 22.05kHz */
-#define SR_24000 (6<<0) /* 24kHz */
-#define SR_88200 (8<<0) /* 88.2kHz */
-#define SR_96000 (10<<0) /* 96kHz */
-#define SR_176400 (12<<0) /* 176.4kHz */
-#define SR_192000 (14<<0) /* 192kHz */
+#define PROFESSIONAL (1<<0) /* 0 = consumer, 1 = professional */
+#define NON_LPCM (1<<1) /* 0 = audio, 1 = non-audio */
+#define SR_44100 (0<<0) /* 44.1kHz */
+#define SR_NOTID (1<<0) /* non indicated */
+#define SR_48000 (2<<0) /* 48kHz */
+#define SR_32000 (3<<0) /* 32kHz */
+#define SR_22050 (4<<0) /* 22.05kHz */
+#define SR_24000 (6<<0) /* 24kHz */
+#define SR_88200 (8<<0) /* 88.2kHz */
+#define SR_96000 (10<<0) /* 96kHz */
+#define SR_176400 (12<<0) /* 176.4kHz */
+#define SR_192000 (14<<0) /* 192kHz */
#endif
struct string_to_enum {
@@ -88,7 +90,9 @@
#ifdef INCALL_MUSIC_ENABLED
STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_INCALL_MUSIC),
#endif
+#ifdef HDMI_PASSTHROUGH_ENABLED
STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH),
+#endif
};
const struct string_to_enum s_format_name_to_enum_table[] = {
@@ -103,7 +107,6 @@
STRING_TO_ENUM(AUDIO_FORMAT_E_AC3),
#ifdef AUDIO_EXTN_FORMATS_ENABLED
STRING_TO_ENUM(AUDIO_FORMAT_DTS),
- STRING_TO_ENUM(AUDIO_FORMAT_DTS_LBR),
STRING_TO_ENUM(AUDIO_FORMAT_WMA),
STRING_TO_ENUM(AUDIO_FORMAT_WMA_PRO),
STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADIF),
@@ -540,12 +543,11 @@
app_type_cfg->bit_width = 16;
}
-int audio_extn_utils_send_app_type_cfg(struct audio_usecase *usecase)
+int audio_extn_utils_send_app_type_cfg(struct audio_device *adev,
+ struct audio_usecase *usecase)
{
char mixer_ctl_name[MAX_LENGTH_MIXER_CONTROL_IN_INT];
int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT], len = 0, rc;
- struct stream_out *out;
- struct audio_device *adev;
struct mixer_ctl *ctl;
int pcm_device_id, acdb_dev_id, snd_device = usecase->out_snd_device;
int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
@@ -553,25 +555,27 @@
ALOGV("%s", __func__);
- if (usecase->type != PCM_PLAYBACK) {
- ALOGV("%s: not a playback path, no need to cfg app type", __func__);
+ if (usecase->type != PCM_PLAYBACK && usecase->type != PCM_CAPTURE) {
+ ALOGE("%s: not a playback or capture path, no need to cfg app type", __func__);
rc = 0;
goto exit_send_app_type_cfg;
}
if ((usecase->id != USECASE_AUDIO_PLAYBACK_DEEP_BUFFER) &&
(usecase->id != USECASE_AUDIO_PLAYBACK_LOW_LATENCY) &&
(usecase->id != USECASE_AUDIO_PLAYBACK_MULTI_CH) &&
- (!is_offload_usecase(usecase->id))) {
- ALOGV("%s: a playback path where app type cfg is not required %d", __func__, usecase->id);
+ (!is_offload_usecase(usecase->id)) &&
+ (usecase->type != PCM_CAPTURE)) {
+ ALOGV("%s: a rx/tx path where app type cfg is not required %d", __func__, usecase->id);
rc = 0;
goto exit_send_app_type_cfg;
}
- out = usecase->stream.out;
- adev = out->dev;
-
- snd_device = usecase->out_snd_device;
-
- pcm_device_id = platform_get_pcm_device_id(out->usecase, PCM_PLAYBACK);
+ if (usecase->type == PCM_PLAYBACK) {
+ snd_device = usecase->out_snd_device;
+ pcm_device_id = platform_get_pcm_device_id(usecase->id, PCM_PLAYBACK);
+ } else if (usecase->type == PCM_CAPTURE) {
+ snd_device = usecase->in_snd_device;
+ pcm_device_id = platform_get_pcm_device_id(usecase->id, PCM_CAPTURE);
+ }
snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
"Audio Stream %d App Type Cfg", pcm_device_id);
@@ -591,37 +595,33 @@
rc = -EINVAL;
goto exit_send_app_type_cfg;
}
-
if ((24 == usecase->stream.out->bit_width) &&
(usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
- out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+ usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
} else if ((snd_device != SND_DEVICE_OUT_HEADPHONES_44_1 &&
usecase->stream.out->sample_rate == OUTPUT_SAMPLING_RATE_44100) ||
(usecase->stream.out->sample_rate < OUTPUT_SAMPLING_RATE_44100)) {
- out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+ usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
}
- sample_rate = out->app_type_cfg.sample_rate;
+ sample_rate = usecase->stream.out->app_type_cfg.sample_rate;
property_get("audio.playback.mch.downsample",value,"");
if (!strncmp("true", value, sizeof("true"))) {
- if ((popcount(out->channel_mask) > 2) &&
- (out->sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
- !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH))
+ if ((popcount(usecase->stream.out->channel_mask) > 2) &&
+ (usecase->stream.out->app_type_cfg.sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
+ !(usecase->stream.out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH))
sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
}
- app_type_cfg[len++] = out->app_type_cfg.app_type;
+ app_type_cfg[len++] = usecase->stream.out->app_type_cfg.app_type;
app_type_cfg[len++] = acdb_dev_id;
- if (((out->format == AUDIO_FORMAT_E_AC3) ||
- (out->format == AUDIO_FORMAT_E_AC3_JOC)) &&
- (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH))
+ if (((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
+ (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC)) &&
+ (usecase->stream.out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH))
app_type_cfg[len++] = sample_rate * 4;
else
app_type_cfg[len++] = sample_rate;
-
mixer_ctl_set_array(ctl, app_type_cfg, len);
- ALOGI("%s app_type %d, acdb_dev_id %d, sample_rate %d",
- __func__, out->app_type_cfg.app_type, acdb_dev_id, sample_rate);
rc = 0;
exit_send_app_type_cfg:
return rc;
@@ -660,13 +660,13 @@
audio_extn_get_spkr_prot_snd_device(snd_device) : snd_device;
platform_send_audio_calibration(adev->platform, usecase,
out->app_type_cfg.app_type,
- out->app_type_cfg.sample_rate);
+ usecase->stream.out->app_type_cfg.sample_rate);
}
if ((type == PCM_HFP_CALL) || (type == PCM_CAPTURE)) {
/* when app type is default. the sample rate is not used to send cal */
platform_send_audio_calibration(adev->platform, usecase,
- platform_get_default_app_type(adev->platform),
- 48000);
+ platform_get_default_app_type_v2(adev->platform, usecase->type),
+ 48000);
}
}
@@ -830,6 +830,7 @@
channel_status[3] |= SR_48000;
}
+#ifdef HDMI_PASSTHROUGH_ENABLED
int32_t get_compressed_channel_status(void *audio_stream_data,
uint32_t audio_frame_size,
unsigned char *channel_status,
@@ -837,9 +838,9 @@
// codec_type - AUDIO_PARSER_CODEC_AC3
// - AUDIO_PARSER_CODEC_DTS
{
- unsigned char *streamPtr;
+ unsigned char *stream;
int ret = 0;
- streamPtr = (unsigned char *)audio_stream_data;
+ stream = (unsigned char *)audio_stream_data;
if (audio_stream_data == NULL || audio_frame_size == 0) {
ALOGW("no buffer to get channel status, return default for compress");
@@ -848,7 +849,7 @@
}
memset(channel_status,0,24);
- if(init_audio_parser(streamPtr, audio_frame_size, codec_type) == -1)
+ if(init_audio_parser(stream, audio_frame_size, codec_type) == -1)
{
ALOGE("init audio parser failed");
return -1;
@@ -858,7 +859,9 @@
}
-void get_linearpcm_channel_status(uint32_t sampleRate,
+#endif
+
+void get_lpcm_channel_status(uint32_t sampleRate,
unsigned char *channel_status)
{
int32_t status = 0;
@@ -876,6 +879,7 @@
case 16000:
case 22050:
channel_status[3] |= SR_NOTID;
+ break;
case 24000:
channel_status[3] |= SR_24000;
break;
@@ -907,21 +911,24 @@
}
}
-void setChannelStatus(struct stream_out *out, char * buffer, size_t bytes)
+void audio_utils_set_hdmi_channel_status(struct stream_out *out, char * buffer, size_t bytes)
{
unsigned char channel_status[24]={0};
struct snd_aes_iec958 iec958;
const char *mixer_ctl_name = "IEC958 Playback PCM Stream";
struct mixer_ctl *ctl;
int i=0;
+#ifdef HDMI_PASSTHROUGH_ENABLED
if (audio_extn_is_dolby_format(out->format) &&
/*TODO:Extend code to support DTS passthrough*/
/*set compressed channel status bits*/
audio_extn_dolby_is_passthrough_stream(out->flags)){
get_compressed_channel_status(buffer, bytes, channel_status, AUDIO_PARSER_CODEC_AC3);
- } else {
+ } else
+#endif
+ {
/*set channel status bit for LPCM*/
- get_linearpcm_channel_status(out->sample_rate, channel_status);
+ get_lpcm_channel_status(out->sample_rate, channel_status);
}
memcpy(iec958.status, channel_status,sizeof(iec958.status));
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
old mode 100755
new mode 100644
index 711b1f4..a0f9206
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -165,9 +165,10 @@
const char * const use_case_table[AUDIO_USECASE_MAX] = {
[USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = "deep-buffer-playback",
[USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = "low-latency-playback",
- [USECASE_AUDIO_PLAYBACK_MULTI_CH] = "multi-channel-playback",
+ [USECASE_AUDIO_PLAYBACK_ULL] = "audio-ull-playback",
+ [USECASE_AUDIO_PLAYBACK_MULTI_CH] = "multi-channel-playback",
[USECASE_AUDIO_PLAYBACK_OFFLOAD] = "compress-offload-playback",
-#ifdef MULTIPLE_OFFLOAD_ENABLED
+ //Enabled for Direct_PCM
[USECASE_AUDIO_PLAYBACK_OFFLOAD2] = "compress-offload-playback2",
[USECASE_AUDIO_PLAYBACK_OFFLOAD3] = "compress-offload-playback3",
[USECASE_AUDIO_PLAYBACK_OFFLOAD4] = "compress-offload-playback4",
@@ -176,9 +177,6 @@
[USECASE_AUDIO_PLAYBACK_OFFLOAD7] = "compress-offload-playback7",
[USECASE_AUDIO_PLAYBACK_OFFLOAD8] = "compress-offload-playback8",
[USECASE_AUDIO_PLAYBACK_OFFLOAD9] = "compress-offload-playback9",
-#endif
- [USECASE_AUDIO_PLAYBACK_ULL] = "audio-ull-playback",
- [USECASE_AUDIO_DIRECT_PCM_OFFLOAD] = "compress-offload-playback2",
[USECASE_AUDIO_RECORD] = "audio-record",
[USECASE_AUDIO_RECORD_COMPRESS] = "audio-record-compress",
@@ -214,7 +212,6 @@
static const audio_usecase_t offload_usecases[] = {
USECASE_AUDIO_PLAYBACK_OFFLOAD,
-#ifdef MULTIPLE_OFFLOAD_ENABLED
USECASE_AUDIO_PLAYBACK_OFFLOAD2,
USECASE_AUDIO_PLAYBACK_OFFLOAD3,
USECASE_AUDIO_PLAYBACK_OFFLOAD4,
@@ -223,8 +220,6 @@
USECASE_AUDIO_PLAYBACK_OFFLOAD7,
USECASE_AUDIO_PLAYBACK_OFFLOAD8,
USECASE_AUDIO_PLAYBACK_OFFLOAD9,
-#endif
- USECASE_AUDIO_DIRECT_PCM_OFFLOAD,
};
#define STRING_TO_ENUM(string) { #string, string }
@@ -256,6 +251,26 @@
static int set_voice_volume_l(struct audio_device *adev, float volume);
+__attribute__ ((visibility ("default")))
+bool audio_hw_send_gain_dep_calibration(int level) {
+ bool ret_val = false;
+ ALOGV("%s: called ... ", __func__);
+
+ pthread_mutex_lock(&adev_init_lock);
+
+ if (adev != NULL && adev->platform != NULL) {
+ pthread_mutex_lock(&adev->lock);
+ ret_val = platform_send_gain_dep_cal(adev->platform, level);
+ pthread_mutex_unlock(&adev->lock);
+ } else {
+ ALOGE("%s: %s is NULL", __func__, adev == NULL ? "adev" : "adev->platform");
+ }
+
+ pthread_mutex_unlock(&adev_init_lock);
+
+ return ret_val;
+}
+
static int check_and_set_gapless_mode(struct audio_device *adev) {
@@ -369,7 +384,10 @@
return -ENOSYS;
pthread_mutex_lock(&adev->snd_card_status.lock);
- adev->snd_card_status.state = snd_scard_state;
+ if (adev->snd_card_status.state != snd_scard_state) {
+ adev->snd_card_status.state = snd_scard_state;
+ platform_snd_card_update(adev->platform, snd_scard_state);
+ }
pthread_mutex_unlock(&adev->snd_card_status.lock);
return 0;
@@ -430,7 +448,7 @@
audio_extn_dolby_ds2_set_endpoint(adev);
audio_extn_sound_trigger_update_stream_status(usecase, ST_EVENT_STREAM_BUSY);
audio_extn_listen_update_stream_status(usecase, LISTEN_EVENT_STREAM_BUSY);
- audio_extn_utils_send_app_type_cfg(usecase);
+ audio_extn_utils_send_app_type_cfg(adev, usecase);
audio_extn_utils_send_audio_calibration(adev, usecase);
strlcpy(mixer_path, use_case_table[usecase->id], MIXER_PATH_MAX_LENGTH);
platform_add_backend_name(mixer_path, snd_device, usecase);
@@ -498,7 +516,7 @@
if(SND_DEVICE_IN_USB_HEADSET_MIC == snd_device)
audio_extn_usb_start_capture(adev);
- if ((snd_device == SND_DEVICE_OUT_SPEAKER || snd_device == SND_DEVICE_OUT_SPEAKER_WSA ||
+ if ((snd_device == SND_DEVICE_OUT_SPEAKER || snd_device == SND_DEVICE_OUT_SPEAKER_WSA ||
snd_device == SND_DEVICE_OUT_SPEAKER_VBAT || snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_VBAT ||
snd_device == SND_DEVICE_OUT_VOICE_SPEAKER) &&
audio_extn_spkr_prot_is_enabled()) {
@@ -566,7 +584,6 @@
/* exit usb capture thread */
if(SND_DEVICE_IN_USB_HEADSET_MIC == snd_device)
audio_extn_usb_stop_capture();
-
if ((snd_device == SND_DEVICE_OUT_SPEAKER || snd_device == SND_DEVICE_OUT_SPEAKER_WSA ||
snd_device == SND_DEVICE_OUT_SPEAKER_VBAT || snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_VBAT ||
snd_device == SND_DEVICE_OUT_VOICE_SPEAKER) &&
@@ -577,10 +594,7 @@
}
if (snd_device == SND_DEVICE_OUT_HDMI)
- adev->mChannelStatusSet = false;
-
- if (snd_device == SND_DEVICE_OUT_HDMI)
- adev->mChannelStatusSet = false;
+ adev->is_channel_status_set = false;
audio_extn_dev_arbi_release(snd_device);
audio_extn_sound_trigger_update_device_status(snd_device,
@@ -676,10 +690,9 @@
specified usecase to new snd devices */
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
- /* Update the out_snd_device only before enabling the audio route */
- if (switch_device[usecase->id] ) {
- usecase->out_snd_device = snd_device;
- if (usecase->type != VOICE_CALL)
+ /* Update the out_snd_device only for the usecases that are enabled here */
+ if (switch_device[usecase->id] && (usecase->type != VOICE_CALL)) {
+ usecase->out_snd_device = snd_device;
enable_audio_route(adev, usecase);
}
}
@@ -714,8 +727,7 @@
usecase != uc_info &&
usecase->in_snd_device != snd_device &&
((uc_info->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) &&
- (((usecase->devices & ~AUDIO_DEVICE_BIT_IN) & AUDIO_DEVICE_IN_ALL_CODEC_BACKEND) ||
- (usecase->type == VOICE_CALL))) &&
+ ((usecase->devices & ~AUDIO_DEVICE_BIT_IN) & AUDIO_DEVICE_IN_ALL_CODEC_BACKEND)) &&
(usecase->id != USECASE_AUDIO_SPKR_CALIB_TX)) {
ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
__func__, use_case_table[usecase->id],
@@ -915,8 +927,6 @@
if (out_snd_device == usecase->out_snd_device &&
in_snd_device == usecase->in_snd_device) {
- audio_extn_dolby_set_endpoint(adev);
- audio_extn_dolby_ds2_set_endpoint(adev);
return 0;
}
@@ -1112,7 +1122,9 @@
uc_info->out_snd_device = SND_DEVICE_NONE;
list_add_tail(&adev->usecase_list, &uc_info->list);
- audio_extn_perf_lock_acquire();
+ audio_extn_perf_lock_acquire(&adev->perf_lock_handle, 0,
+ adev->perf_lock_opts,
+ adev->perf_lock_opts_size);
select_devices(adev, in->usecase);
ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d",
@@ -1154,16 +1166,14 @@
goto error_open;
}
- audio_extn_perf_lock_release();
-
+ audio_extn_perf_lock_release(&adev->perf_lock_handle);
ALOGD("%s: exit", __func__);
return ret;
error_open:
+ audio_extn_perf_lock_release(&adev->perf_lock_handle);
stop_input_stream(in);
- audio_extn_perf_lock_release();
-
error_config:
adev->active_input = NULL;
/*
@@ -1232,35 +1242,50 @@
return false;
}
-static audio_usecase_t get_offload_usecase(struct audio_device *adev)
+static audio_usecase_t get_offload_usecase(struct audio_device *adev, bool is_direct_pcm)
{
- audio_usecase_t ret = USECASE_AUDIO_PLAYBACK_OFFLOAD;
- unsigned int i, num_usecase = sizeof(offload_usecases)/sizeof(offload_usecases[0]);
- char value[PROPERTY_VALUE_MAX] = {0};
+ audio_usecase_t ret_uc = USECASE_INVALID;
+ unsigned int offload_uc_index;
+ int num_usecase = sizeof(offload_usecases)/sizeof(offload_usecases[0]);
+ if (!adev->multi_offload_enable) {
+ if (is_direct_pcm)
+ ret_uc = USECASE_AUDIO_PLAYBACK_OFFLOAD2;
+ else
+ ret_uc = USECASE_AUDIO_PLAYBACK_OFFLOAD;
- property_get("audio.offload.multiple.enabled", value, NULL);
- if (!(atoi(value) || !strncmp("true", value, 4)))
- num_usecase = 1; /* If prop is not set, limit the num of offload usecases to 1 */
+ pthread_mutex_lock(&adev->lock);
+ if (get_usecase_from_list(adev, ret_uc) != NULL)
+ ret_uc = USECASE_INVALID;
+ pthread_mutex_unlock(&adev->lock);
+
+ return ret_uc;
+ }
ALOGV("%s: num_usecase: %d", __func__, num_usecase);
- for (i = 0; i < num_usecase; i++) {
- if (!(adev->offload_usecases_state & (0x1<<i))) {
- adev->offload_usecases_state |= 0x1 << i;
- ret = offload_usecases[i];
+ for (offload_uc_index = 0; offload_uc_index < num_usecase; offload_uc_index++) {
+ if (!(adev->offload_usecases_state & (0x1 << offload_uc_index))) {
+ adev->offload_usecases_state |= 0x1 << offload_uc_index;
+ ret_uc = offload_usecases[offload_uc_index];
break;
}
}
- ALOGV("%s: offload usecase is %d", __func__, ret);
- return ret;
+
+ ALOGV("%s: offload usecase is %d", __func__, ret_uc);
+ return ret_uc;
}
static void free_offload_usecase(struct audio_device *adev,
audio_usecase_t uc_id)
{
- unsigned int i;
- for (i = 0; i < sizeof(offload_usecases)/sizeof(offload_usecases[0]); i++) {
- if (offload_usecases[i] == uc_id) {
- adev->offload_usecases_state &= ~(0x1<<i);
+ unsigned int offload_uc_index;
+ int num_usecase = sizeof(offload_usecases)/sizeof(offload_usecases[0]);
+
+ if (!adev->multi_offload_enable)
+ return;
+
+ for (offload_uc_index = 0; offload_uc_index < num_usecase; offload_uc_index++) {
+ if (offload_usecases[offload_uc_index] == uc_id) {
+ adev->offload_usecases_state &= ~(0x1 << offload_uc_index);
break;
}
}
@@ -1617,6 +1642,9 @@
}
list_add_tail(&adev->usecase_list, &uc_info->list);
+ audio_extn_perf_lock_acquire(&adev->perf_lock_handle, 0,
+ adev->perf_lock_opts,
+ adev->perf_lock_opts_size);
select_devices(adev, out->usecase);
ALOGV("%s: Opening PCM device card_id(%d) device_id(%d) format(%#x)",
@@ -1707,11 +1735,12 @@
audio_extn_check_and_set_dts_hpx_state(adev);
}
}
-
+ audio_extn_perf_lock_release(&adev->perf_lock_handle);
ALOGD("%s: exit", __func__);
return 0;
error_open:
+ audio_extn_perf_lock_release(&adev->perf_lock_handle);
stop_output_stream(out);
error_config:
/*
@@ -1975,8 +2004,13 @@
if (val != 0) {
out->devices = val;
- if (!out->standby)
+ if (!out->standby) {
+ audio_extn_perf_lock_acquire(&adev->perf_lock_handle, 0,
+ adev->perf_lock_opts,
+ adev->perf_lock_opts_size);
select_devices(adev, out->usecase);
+ audio_extn_perf_lock_release(&adev->perf_lock_handle);
+ }
if (output_drives_call(adev, out)) {
if(!voice_is_in_call(adev)) {
@@ -2063,6 +2097,21 @@
}
}
+
+ ret = str_parms_get_str(query, "is_direct_pcm_track", value, sizeof(value));
+ if (ret >= 0) {
+ value[0] = '\0';
+ if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM) {
+ ALOGV("in direct_pcm");
+ strlcat(value, "true", strlen("true"));
+ } else {
+ ALOGV("not in direct_pcm");
+ strlcat(value, "false", strlen("false"));
+ }
+ str_parms_add_str(reply, "is_direct_pcm_track", value);
+ str = str_parms_to_str(reply);
+ }
+
ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_FORMATS, value, sizeof(value));
if (ret >= 0) {
value[0] = '\0';
@@ -2190,13 +2239,13 @@
out->standby = true;
goto exit;
}
- if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD && adev->adm_register_output_stream)
+ if (!is_offload_usecase(out->usecase) && adev->adm_register_output_stream)
adev->adm_register_output_stream(adev->adm_data, out->handle, out->flags);
}
- if (adev->mChannelStatusSet == false && (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)){
- setChannelStatus(out, buffer, bytes);
- adev->mChannelStatusSet = true;
+ if (adev->is_channel_status_set == false && (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)){
+ audio_utils_set_hdmi_channel_status(out, buffer, bytes);
+ adev->is_channel_status_set = true;
}
if (is_offload_usecase(out->usecase)) {
@@ -2275,7 +2324,7 @@
if (ret != 0) {
if (out->pcm)
- ALOGE("%s: error %ld - %s", __func__, ret, pcm_get_error(out->pcm));
+ ALOGE("%s: error %zu - %s", __func__, ret, pcm_get_error(out->pcm));
if (out->usecase == USECASE_COMPRESS_VOIP_CALL) {
pthread_mutex_lock(&adev->lock);
voice_extn_compress_voip_close_output_stream(&out->stream.common);
@@ -2882,6 +2931,7 @@
out->bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
out->non_blocking = 0;
out->use_small_bufs = false;
+
/* Init use case and pcm_config */
if ((out->flags & AUDIO_OUTPUT_FLAG_DIRECT) &&
!(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
@@ -2956,18 +3006,24 @@
}
if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM) {
- ALOGV("%s:: inserting DIRECT_PCM _USECASE", __func__);
- out->usecase = USECASE_AUDIO_DIRECT_PCM_OFFLOAD;
+ out->usecase = get_offload_usecase(adev, true);
+ ALOGV("DIRECT_PCM usecase ... usecase selected %d ", out->usecase);
} else {
- ALOGV("%s:: inserting OFFLOAD_USECASE", __func__);
- out->usecase = get_offload_usecase(adev);
-
out->stream.set_callback = out_set_callback;
out->stream.pause = out_pause;
out->stream.resume = out_resume;
out->stream.drain = out_drain;
out->stream.flush = out_flush;
+ out->usecase = get_offload_usecase(adev, false);
+ ALOGV("Compress Offload usecase .. usecase selected %d", out->usecase);
}
+
+ if (out->usecase == USECASE_INVALID) {
+ ALOGE("%s: Max allowed OFFLOAD usecase reached ... ");
+ ret = -EEXIST;
+ goto error_open;
+ }
+
if (config->offload_info.channel_mask)
out->channel_mask = config->offload_info.channel_mask;
else if (config->channel_mask) {
@@ -3269,12 +3325,8 @@
} else if (strstr(snd_card_status, "ONLINE")) {
ALOGD("Received sound card ONLINE status");
set_snd_card_state(adev,SND_CARD_STATE_ONLINE);
- if (!platform_is_acdb_initialized(adev->platform)) {
- ret = platform_acdb_init(adev->platform);
- if(ret)
- ALOGE("acdb initialization is failed");
-
- }
+ //send dts hpx license if enabled
+ audio_extn_dts_eagle_send_lic();
}
}
@@ -3632,7 +3684,6 @@
/* This stream could be for sound trigger lab,
get sound trigger pcm if present */
audio_extn_sound_trigger_check_and_get_session(in);
- audio_extn_perf_lock_init();
*stream_in = &in->stream;
ALOGV("%s: exit", __func__);
@@ -3792,7 +3843,10 @@
list_init(&adev->usecase_list);
adev->cur_wfd_channels = 2;
adev->offload_usecases_state = 0;
- adev->mChannelStatusSet = false;
+ adev->is_channel_status_set = false;
+ adev->perf_lock_opts[0] = 0x101;
+ adev->perf_lock_opts[1] = 0x20E;
+ adev->perf_lock_opts_size = 2;
pthread_mutex_init(&adev->snd_card_status.lock, (const pthread_mutexattr_t *) NULL);
adev->snd_card_status.state = SND_CARD_STATE_OFFLINE;
@@ -3904,11 +3958,13 @@
}
}
+ adev->multi_offload_enable = property_get_bool("audio.offload.multiple.enabled", false);
pthread_mutex_unlock(&adev_init_lock);
if (adev->adm_init)
adev->adm_data = adev->adm_init();
+ audio_extn_perf_lock_init();
ALOGV("%s: exit", __func__);
return 0;
}
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 85be217..fd19211 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -38,6 +38,7 @@
#ifndef QCOM_AUDIO_HW_H
#define QCOM_AUDIO_HW_H
+#include <stdlib.h>
#include <cutils/list.h>
#include <hardware/audio.h>
#include <tinyalsa/asoundlib.h>
@@ -73,6 +74,8 @@
#define SND_CARD_STATE_OFFLINE 0
#define SND_CARD_STATE_ONLINE 1
+#define MAX_PERF_LOCK_OPTS 20
+
/* These are the supported use cases by the hardware.
* Each usecase is mapped to a specific PCM device.
* Refer to pcm_device_table[].
@@ -84,7 +87,6 @@
USECASE_AUDIO_PLAYBACK_LOW_LATENCY,
USECASE_AUDIO_PLAYBACK_MULTI_CH,
USECASE_AUDIO_PLAYBACK_OFFLOAD,
-#ifdef MULTIPLE_OFFLOAD_ENABLED
USECASE_AUDIO_PLAYBACK_OFFLOAD2,
USECASE_AUDIO_PLAYBACK_OFFLOAD3,
USECASE_AUDIO_PLAYBACK_OFFLOAD4,
@@ -93,11 +95,8 @@
USECASE_AUDIO_PLAYBACK_OFFLOAD7,
USECASE_AUDIO_PLAYBACK_OFFLOAD8,
USECASE_AUDIO_PLAYBACK_OFFLOAD9,
-#endif
USECASE_AUDIO_PLAYBACK_ULL,
- USECASE_AUDIO_DIRECT_PCM_OFFLOAD,
-
/* FM usecase */
USECASE_AUDIO_PLAYBACK_FM,
@@ -328,7 +327,7 @@
int snd_card;
unsigned int cur_codec_backend_samplerate;
unsigned int cur_codec_backend_bit_width;
- bool mChannelStatusSet;
+ bool is_channel_status_set;
void *platform;
unsigned int offload_usecases_state;
void *visualizer_lib;
@@ -340,9 +339,6 @@
struct sound_card_status snd_card_status;
int (*offload_effects_set_hpx_state)(bool);
- void (*offload_effects_get_parameters)(struct str_parms *,
- struct str_parms *);
- void (*offload_effects_set_parameters)(struct str_parms *);
void *adm_data;
void *adm_lib;
@@ -353,6 +349,15 @@
adm_deregister_stream_t adm_deregister_stream;
adm_request_focus_t adm_request_focus;
adm_abandon_focus_t adm_abandon_focus;
+
+ void (*offload_effects_get_parameters)(struct str_parms *,
+ struct str_parms *);
+ void (*offload_effects_set_parameters)(struct str_parms *);
+
+ bool multi_offload_enable;
+ int perf_lock_handle;
+ int perf_lock_opts[MAX_PERF_LOCK_OPTS];
+ int perf_lock_opts_size;
};
int select_devices(struct audio_device *adev,
diff --git a/hal/edid.h b/hal/edid.h
index aa945bd..0d7fbe6 100644
--- a/hal/edid.h
+++ b/hal/edid.h
@@ -92,7 +92,6 @@
int channel_allocation;
} edid_audio_info;
-
#ifndef HDMI_EDID
#define edid_get_sink_caps(info, edid_data) (0)
#else
diff --git a/hal/msm8916/hw_info.c b/hal/msm8916/hw_info.c
index 613c1a7..d04c69c 100644
--- a/hal/msm8916/hw_info.c
+++ b/hal/msm8916/hw_info.c
@@ -239,15 +239,15 @@
hw_info->snd_devices = NULL;
hw_info->num_snd_devices = 0;
strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "msm8976-tasha-snd-card")) {
+ } else if (!strcmp(snd_card_name, "msm8952-tasha-snd-card")) {
strlcpy(hw_info->type, "", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8976", sizeof(hw_info->name));
+ strlcpy(hw_info->name, "msm8952", sizeof(hw_info->name));
hw_info->snd_devices = NULL;
hw_info->num_snd_devices = 0;
strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "msm8976-tasha-skun-snd-card")) {
+ } else if (!strcmp(snd_card_name, "msm8952-tashalite-snd-card")) {
strlcpy(hw_info->type, "", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8976", sizeof(hw_info->name));
+ strlcpy(hw_info->name, "msm8952", sizeof(hw_info->name));
hw_info->snd_devices = NULL;
hw_info->num_snd_devices = 0;
strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
@@ -257,12 +257,30 @@
hw_info->snd_devices = NULL;
hw_info->num_snd_devices = 0;
strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "msm8976-skun-snd-card")) {
+ } else if (!strcmp(snd_card_name, "msm8952-sku1-snd-card")) {
+ strlcpy(hw_info->type, "", sizeof(hw_info->type));
+ strlcpy(hw_info->name, "msm8952", sizeof(hw_info->name));
+ hw_info->snd_devices = NULL;
+ hw_info->num_snd_devices = 0;
+ strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
+ } else if (!strcmp(snd_card_name, "msm8952-sku2-snd-card")) {
+ strlcpy(hw_info->type, "", sizeof(hw_info->type));
+ strlcpy(hw_info->name, "msm8952", sizeof(hw_info->name));
+ hw_info->snd_devices = NULL;
+ hw_info->num_snd_devices = 0;
+ strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
+ } else if (!strcmp(snd_card_name, "msm8976-tasha-snd-card")) {
strlcpy(hw_info->type, "", sizeof(hw_info->type));
strlcpy(hw_info->name, "msm8976", sizeof(hw_info->name));
hw_info->snd_devices = NULL;
hw_info->num_snd_devices = 0;
strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
+ } else if (!strcmp(snd_card_name, "msm8976-tashalite-snd-card")) {
+ strlcpy(hw_info->type, "", sizeof(hw_info->type));
+ strlcpy(hw_info->name, "msm8976", sizeof(hw_info->name));
+ hw_info->snd_devices = NULL;
+ hw_info->num_snd_devices = 0;
+ strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
} else {
ALOGW("%s: Not an 8x16/8939/8909/8952 device", __func__);
}
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index dfdb6d6..463dc77 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -52,6 +52,8 @@
#define MIXER_XML_PATH_SKUE "/system/etc/mixer_paths_skue.xml"
#define MIXER_XML_PATH_SKUL "/system/etc/mixer_paths_skul.xml"
#define MIXER_XML_PATH_SKUM "/system/etc/mixer_paths_qrd_skum.xml"
+#define MIXER_XML_PATH_SKU1 "/system/etc/mixer_paths_qrd_sku1.xml"
+#define MIXER_XML_PATH_SKU2 "/system/etc/mixer_paths_qrd_sku2.xml"
#define MIXER_XML_PATH_SKUN_CAJON "/system/etc/mixer_paths_qrd_skun_cajon.xml"
#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
@@ -145,8 +147,6 @@
#define AUDIO_PARAMETER_IS_HW_DECODER_SESSION_AVAILABLE "is_hw_dec_session_available"
-#define MAX_DSP_ONLY_DECODERS 6
-
char * dsp_only_decoders_mime[] = {
"audio/x-ms-wma" /* wma*/ ,
"audio/x-ms-wma-lossless" /* wma lossless */ ,
@@ -191,6 +191,7 @@
acdb_loader_get_calibration_t acdb_loader_get_calibration;
typedef int (*acdb_set_audio_cal_t) (void *, void *, uint32_t);
typedef int (*acdb_get_audio_cal_t) (void *, void *, uint32_t*);
+typedef int (*acdb_send_common_top_t) (void);
typedef int (*acdb_set_codec_data_t) (void *, char *);
typedef struct codec_backend_cfg {
@@ -238,6 +239,7 @@
acdb_send_voice_cal_t acdb_send_voice_cal;
acdb_reload_vocvoltable_t acdb_reload_vocvoltable;
acdb_get_default_app_type_t acdb_get_default_app_type;
+ acdb_send_common_top_t acdb_send_common_top;
acdb_set_codec_data_t acdb_set_codec_data;
#ifdef RECORD_PLAY_CONCURRENCY
bool rec_play_conc_set;
@@ -252,11 +254,17 @@
static bool is_external_codec = false;
static const int pcm_device_table_of_ext_codec[AUDIO_USECASE_MAX][2] = {
- [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE_OF_EXT_CODEC, QCHAT_CALL_PCM_DEVICE_OF_EXT_CODEC}
+ [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE_OF_EXT_CODEC, QCHAT_CALL_PCM_DEVICE_OF_EXT_CODEC},
+ [USECASE_VOICEMMODE1_CALL] = {VOICEMMODE1_CALL_PCM_DEVICE_OF_EXT_CODEC,
+ VOICEMMODE1_CALL_PCM_DEVICE_OF_EXT_CODEC},
+ [USECASE_VOICEMMODE2_CALL] = {VOICEMMODE2_CALL_PCM_DEVICE_OF_EXT_CODEC,
+ VOICEMMODE2_CALL_PCM_DEVICE_OF_EXT_CODEC},
};
/* List of use cases that has different PCM device ID's for internal and external codecs */
-static const int misc_usecase[AUDIO_USECASE_MAX] = { USECASE_QCHAT_CALL };
+static const int misc_usecase[AUDIO_USECASE_MAX] = {USECASE_QCHAT_CALL,
+ USECASE_VOICEMMODE1_CALL,
+ USECASE_VOICEMMODE2_CALL};
int pcm_device_table[AUDIO_USECASE_MAX][2] = {
[USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {DEEP_BUFFER_PCM_DEVICE,
@@ -267,7 +275,6 @@
MULTIMEDIA2_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_OFFLOAD] =
{PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
-#ifdef MULTIPLE_OFFLOAD_ENABLED
/* Below entries are initialized with invalid values
* Valid values should be updated from fnc platform_info_init()
* based on pcm ids defined in audio_platform_info.xml.
@@ -280,10 +287,7 @@
[USECASE_AUDIO_PLAYBACK_OFFLOAD7] = {-1, -1},
[USECASE_AUDIO_PLAYBACK_OFFLOAD8] = {-1, -1},
[USECASE_AUDIO_PLAYBACK_OFFLOAD9] = {-1, -1},
-#endif
[USECASE_AUDIO_PLAYBACK_ULL] = {MULTIMEDIA3_PCM_DEVICE, MULTIMEDIA3_PCM_DEVICE},
- [USECASE_AUDIO_DIRECT_PCM_OFFLOAD] =
- {PLAYBACK_OFFLOAD_DEVICE2, PLAYBACK_OFFLOAD_DEVICE2},
[USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
[USECASE_AUDIO_RECORD_COMPRESS] = {COMPRESS_CAPTURE_DEVICE, COMPRESS_CAPTURE_DEVICE},
[USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
@@ -298,8 +302,10 @@
[USECASE_VOLTE_CALL] = {VOLTE_CALL_PCM_DEVICE, VOLTE_CALL_PCM_DEVICE},
[USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE, QCHAT_CALL_PCM_DEVICE},
[USECASE_VOWLAN_CALL] = {VOWLAN_CALL_PCM_DEVICE, VOWLAN_CALL_PCM_DEVICE},
- [USECASE_VOICEMMODE1_CALL] = {-1, -1}, /* pcm ids updated from platform info file */
- [USECASE_VOICEMMODE2_CALL] = {-1, -1}, /* pcm ids updated from platform info file */
+ [USECASE_VOICEMMODE1_CALL] = {VOICEMMODE1_CALL_PCM_DEVICE,
+ VOICEMMODE1_CALL_PCM_DEVICE},
+ [USECASE_VOICEMMODE2_CALL] = {VOICEMMODE2_CALL_PCM_DEVICE,
+ VOICEMMODE2_CALL_PCM_DEVICE},
[USECASE_COMPRESS_VOIP_CALL] = {COMPRESS_VOIP_CALL_PCM_DEVICE, COMPRESS_VOIP_CALL_PCM_DEVICE},
[USECASE_INCALL_REC_UPLINK] = {AUDIO_RECORD_PCM_DEVICE,
AUDIO_RECORD_PCM_DEVICE},
@@ -666,7 +672,6 @@
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MULTI_CH)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
-#ifdef MULTIPLE_OFFLOAD_ENABLED
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD2)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD3)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD4)},
@@ -675,9 +680,7 @@
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD7)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD8)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD9)},
-#endif
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_ULL)},
- {TO_NAME_INDEX(USECASE_AUDIO_DIRECT_PCM_OFFLOAD)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
{TO_NAME_INDEX(USECASE_VOICE_CALL)},
@@ -774,11 +777,17 @@
if (!strncmp(snd_card_name, "msm8939-tapan-snd-card",
sizeof("msm8939-tapan-snd-card")) ||
!strncmp(snd_card_name, "msm8939-tapan9302-snd-card",
- sizeof("msm8939-tapan9302-snd-card"))||
+ sizeof("msm8939-tapan9302-snd-card")) ||
!strncmp(snd_card_name, "msm8939-tomtom9330-snd-card",
sizeof("msm8939-tomtom9330-snd-card")) ||
!strncmp(snd_card_name, "msm8952-tomtom-snd-card",
sizeof("msm8952-tomtom-snd-card")) ||
+ !strncmp(snd_card_name, "msm8952-tasha-snd-card",
+ sizeof("msm8952-tasha-snd-card")) ||
+ !strncmp(snd_card_name, "msm8952-tashalite-snd-card",
+ sizeof("msm8952-tashalite-snd-card")) ||
+ !strncmp(snd_card_name, "msm8952-tasha-skun-snd-card",
+ sizeof("msm8952-tasha-skun-snd-card")) ||
!strncmp(snd_card_name, "msm8976-tasha-snd-card",
sizeof("msm8976-tasha-snd-card")) ||
!strncmp(snd_card_name, "msm8976-tashalite-snd-card",
@@ -945,7 +954,7 @@
msm_be_id_array_len =
sizeof(msm_device_to_be_id_external_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
} else if (!strncmp(snd_card_name, "msm8952-snd-card-mtp",
- sizeof("msm8952-snd-card-mtpmsm8952-snd-card-mtp"))) {
+ sizeof("msm8952-snd-card-mtp"))) {
strlcpy(mixer_xml_path, MIXER_XML_PATH_MTP,
sizeof(MIXER_XML_PATH_MTP));
msm_device_to_be_id = msm_device_to_be_id_internal_codec;
@@ -958,6 +967,20 @@
msm_device_to_be_id = msm_device_to_be_id_external_codec;
msm_be_id_array_len =
sizeof(msm_device_to_be_id_external_codec) / sizeof(msm_device_to_be_id_external_codec[0]);
+ } else if (!strncmp(snd_card_name, "msm8952-sku1-snd-card",
+ sizeof("msm8952-sku1-snd-card"))) {
+ strlcpy(mixer_xml_path, MIXER_XML_PATH_SKU1,
+ sizeof(MIXER_XML_PATH_SKU1));
+ msm_device_to_be_id = msm_device_to_be_id_internal_codec;
+ msm_be_id_array_len =
+ sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
+ } else if (!strncmp(snd_card_name, "msm8952-sku2-snd-card",
+ sizeof("msm8952-sku2-snd-card"))) {
+ strlcpy(mixer_xml_path, MIXER_XML_PATH_SKU2,
+ sizeof(MIXER_XML_PATH_SKU2));
+ msm_device_to_be_id = msm_device_to_be_id_internal_codec;
+ msm_be_id_array_len =
+ sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
} else if (!strncmp(snd_card_name, "msm8952-skum-snd-card",
sizeof("msm8952-skum-snd-card"))) {
strlcpy(mixer_xml_path, MIXER_XML_PATH_SKUM,
@@ -965,6 +988,21 @@
msm_device_to_be_id = msm_device_to_be_id_internal_codec;
msm_be_id_array_len =
sizeof(msm_device_to_be_id_internal_codec) / sizeof(msm_device_to_be_id_internal_codec[0]);
+ } else if (!strncmp(snd_card_name, "msm8952-tasha-snd-card",
+ sizeof("msm8952-tasha-snd-card"))) {
+ strlcpy(mixer_xml_path, MIXER_XML_PATH_WCD9335,
+ sizeof(MIXER_XML_PATH_WCD9335));
+ msm_device_to_be_id = msm_device_to_be_id_external_codec;
+ msm_be_id_array_len =
+ sizeof(msm_device_to_be_id_external_codec) / sizeof(msm_device_to_be_id_external_codec[0]);
+
+ } else if (!strncmp(snd_card_name, "msm8952-tashalite-snd-card",
+ sizeof("msm8952-tashalite-snd-card"))) {
+ strlcpy(mixer_xml_path, MIXER_XML_PATH_WCD9326,
+ MAX_MIXER_XML_PATH);
+ msm_device_to_be_id = msm_device_to_be_id_external_codec;
+ msm_be_id_array_len =
+ sizeof(msm_device_to_be_id_external_codec) / sizeof(msm_device_to_be_id_external_codec[0]);
} else if (!strncmp(snd_card_name, "msm8976-skun-snd-card",
sizeof("msm8976-skun-snd-card"))) {
strlcpy(mixer_xml_path, MIXER_XML_PATH_SKUN_CAJON,
@@ -1299,7 +1337,8 @@
return ret;
}
-static int send_codec_cal(acdb_loader_get_calibration_t acdb_loader_get_calibration, struct platform_data *plat_data, int fd)
+static int send_codec_cal(acdb_loader_get_calibration_t acdb_loader_get_calibration,
+ struct platform_data *plat_data, int fd)
{
int ret = 0, type;
@@ -1307,15 +1346,15 @@
struct wcdcal_ioctl_buffer codec_buffer;
struct param_data calib;
+ /* MAD calibration is handled by sound trigger HAL, skip here */
+ if (type == WCD9XXX_MAD_CAL)
+ continue;
+
if((plat_data->is_vbat_speaker) && (WCD9XXX_VBAT_CAL == type)) {
ret = send_vbat_adc_data_to_acdb(plat_data, cal_name_info[type]);
if (ret < 0)
ALOGE("%s error in sending vbat adc data to acdb", __func__);
- }
-
- /* MAD calibration is handled by sound trigger HAL, skip here */
- if (type == WCD9XXX_MAD_CAL)
- continue;
+ }
calib.get_size = 1;
ret = acdb_loader_get_calibration(cal_name_info[type], sizeof(struct param_data),
@@ -1503,6 +1542,7 @@
int wsaCount =0;
my_data = calloc(1, sizeof(struct platform_data));
+
if (!my_data) {
ALOGE("failed to allocate platform data");
return NULL;
@@ -1686,6 +1726,13 @@
ALOGE("%s: Could not find the symbol acdb_get_default_app_type from %s",
__func__, LIB_ACDB_LOADER);
+ my_data->acdb_send_common_top = (acdb_send_common_top_t)dlsym(
+ my_data->acdb_handle,
+ "acdb_loader_send_common_custom_topology");
+ if (!my_data->acdb_send_common_top)
+ ALOGE("%s: Could not find the symbol acdb_get_default_app_type from %s",
+ __func__, LIB_ACDB_LOADER);
+
my_data->acdb_set_codec_data = (acdb_set_codec_data_t)dlsym(
my_data->acdb_handle,
"acdb_loader_set_codec_data");
@@ -1717,9 +1764,9 @@
/* Initialize ACDB and PCM ID's */
if (is_external_codec)
- platform_info_init(PLATFORM_INFO_XML_PATH_EXTCODEC);
+ platform_info_init(PLATFORM_INFO_XML_PATH_EXTCODEC, my_data);
else
- platform_info_init(PLATFORM_INFO_XML_PATH);
+ platform_info_init(PLATFORM_INFO_XML_PATH, my_data);
/* init usb */
audio_extn_usb_init(adev);
@@ -1776,8 +1823,6 @@
(platform_get_native_support() ? "enabled" : "disabled"),
snd_card_name);
-
-
my_data->edid_info = NULL;
return my_data;
}
@@ -1816,13 +1861,27 @@
audio_extn_dap_hal_deinit();
}
-int platform_is_acdb_initialized(void *platform)
+static int platform_is_acdb_initialized(void *platform)
{
struct platform_data *my_data = (struct platform_data *)platform;
ALOGD("%s: acdb initialized %d\n", __func__, my_data->is_acdb_initialized);
return my_data->is_acdb_initialized;
}
+void platform_snd_card_update(void *platform, int snd_scard_state)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+
+ if (snd_scard_state == SND_CARD_STATE_ONLINE) {
+ if (!platform_is_acdb_initialized(my_data)) {
+ if(platform_acdb_init(my_data))
+ ALOGE("%s: acdb initialization is failed", __func__);
+ } else if (my_data->acdb_send_common_top() < 0) {
+ ALOGD("%s: acdb did not set common topology", __func__);
+ }
+ }
+}
+
const char *platform_get_snd_device_name(snd_device_t snd_device)
{
if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
@@ -2015,6 +2074,14 @@
return DEFAULT_APP_TYPE;
}
+int platform_get_default_app_type_v2(void *platform, usecase_type_t type)
+{
+ if(type == PCM_CAPTURE)
+ return DEFAULT_APP_TYPE_TX_PATH;
+ else
+ return DEFAULT_APP_TYPE_RX_PATH;
+}
+
int platform_get_snd_device_acdb_id(snd_device_t snd_device)
{
if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
@@ -2168,6 +2235,9 @@
if (usecase->type == PCM_PLAYBACK)
snd_device = usecase->out_snd_device;
+ else if ((usecase->type == PCM_CAPTURE) &&
+ voice_is_in_call_rec_stream(usecase->stream.in))
+ snd_device = voice_get_incall_rec_snd_device(usecase->in_snd_device);
else if ((usecase->type == PCM_HFP_CALL) || (usecase->type == PCM_CAPTURE))
snd_device = usecase->in_snd_device;
acdb_dev_id = acdb_device_table[audio_extn_get_spkr_prot_snd_device(snd_device)];
@@ -2224,8 +2294,9 @@
if (my_data->csd == NULL)
return ret;
- if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
- audio_extn_spkr_prot_is_enabled()) {
+ if ((out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER ||
+ out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_VBAT) &&
+ audio_extn_spkr_prot_is_enabled()) {
if (my_data->is_vbat_speaker)
acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT];
else
@@ -2287,8 +2358,9 @@
if (my_data->csd == NULL)
return ret;
- if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
- audio_extn_spkr_prot_is_enabled()) {
+ if ((out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER ||
+ out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_VBAT) &&
+ audio_extn_spkr_prot_is_enabled()) {
if (my_data->is_vbat_speaker)
acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT];
else
@@ -3634,7 +3706,7 @@
int platform_update_usecase_from_source(int source, int usecase)
{
ALOGV("%s: input source :%d", __func__, source);
- if(source == AUDIO_SOURCE_FM_TUNER)
+ if (source == AUDIO_SOURCE_FM_TUNER)
usecase = USECASE_AUDIO_RECORD_FM_VIRTUAL;
return usecase;
}
@@ -3661,7 +3733,6 @@
case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
case USECASE_AUDIO_PLAYBACK_MULTI_CH:
case USECASE_AUDIO_PLAYBACK_OFFLOAD:
- case USECASE_AUDIO_DIRECT_PCM_OFFLOAD:
needs_event = true;
break;
/* concurrent playback in low latency allowed */
@@ -3725,7 +3796,6 @@
case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
case USECASE_AUDIO_PLAYBACK_MULTI_CH:
case USECASE_AUDIO_PLAYBACK_OFFLOAD:
- case USECASE_AUDIO_DIRECT_PCM_OFFLOAD:
needs_event = true;
break;
/* concurrent playback in low latency allowed */
@@ -3842,11 +3912,22 @@
return fragment_size;
}
+bool platform_use_small_buffer(audio_offload_info_t* info)
+{
+ return OFFLOAD_USE_SMALL_BUFFER;
+}
+
int platform_is_external_codec (char *snd_card_name)
{
if (!strncmp(snd_card_name, "msm8952-tomtom-snd-card",
sizeof("msm8952-tomtom-snd-card")) ||
+ !strncmp(snd_card_name, "msm8952-tasha-snd-card",
+ sizeof("msm8952-tasha-snd-card")) ||
+ !strncmp(snd_card_name, "msm8952-tashalite-snd-card",
+ sizeof("msm8952-tashalite-snd-card")) ||
+ !strncmp(snd_card_name, "msm8952-tasha-skun-snd-card",
+ sizeof("msm8952-tasha-skun-snd-card")) ||
!strncmp(snd_card_name, "msm8976-tasha-snd-card",
sizeof("msm8976-tasha-snd-card")) ||
!strncmp(snd_card_name, "msm8976-tashalite-snd-card",
@@ -4082,7 +4163,6 @@
}
-
ALOGI("%s Codec selected backend: %d updated bit width: %d and sample rate: %d",
__func__, backend_idx, bit_width, sample_rate);
// Force routing if the expected bitwdith or samplerate
@@ -4162,10 +4242,6 @@
done:
return ret;
}
-bool platform_use_small_buffer(audio_offload_info_t* info)
-{
- return OFFLOAD_USE_SMALL_BUFFER;
-}
void platform_get_device_to_be_id_map(int **device_to_be_id, int *length)
{
@@ -4313,12 +4389,10 @@
}
edid_data[0] = count;
memcpy(&edid_data[1], block, count);
-
if (!edid_get_sink_caps(info, edid_data)) {
ALOGE("%s: Failed to get HDMI sink capabilities", __func__);
goto fail;
}
-
my_data->edid_valid = true;
return 0;
fail:
@@ -4745,7 +4819,7 @@
return ret;
}
-/*
+ /*
* This is a lookup table to map names of speaker device with respective left and right TZ names.
* Also the tz names for a particular left or right speaker can be overriden by adding
* corresponding entry in audio_platform_info.xml file.
@@ -4814,3 +4888,9 @@
else
return 0;
}
+
+bool platform_send_gain_dep_cal(void *platform __unused,
+ int level __unused)
+{
+ return 0;
+}
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index 40b34bc..c4d0b59 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -253,8 +253,6 @@
#define SPKR_PROT_CALIB_TX_PCM_DEVICE 26
#define PLAYBACK_OFFLOAD_DEVICE 9
#define PLAYBACK_OFFLOAD_DEVICE2 24
-
-
#define COMPRESS_VOIP_CALL_PCM_DEVICE 3
/* Define macro for Internal FM volume mixer */
@@ -271,6 +269,12 @@
#define QCHAT_CALL_PCM_DEVICE_OF_EXT_CODEC 28
#define VOWLAN_CALL_PCM_DEVICE 16
+#define VOICEMMODE1_CALL_PCM_DEVICE 26
+#define VOICEMMODE2_CALL_PCM_DEVICE 27
+
+#define VOICEMMODE1_CALL_PCM_DEVICE_OF_EXT_CODEC 29
+#define VOICEMMODE2_CALL_PCM_DEVICE_OF_EXT_CODEC 30
+
#define AFE_PROXY_PLAYBACK_PCM_DEVICE 7
#define AFE_PROXY_RECORD_PCM_DEVICE 8
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index d8801ab..23e3095 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -382,7 +382,8 @@
return 0;
}
-void platform_add_backend_name(char *mixer_path, snd_device_t snd_device, struct audio_usecase *usecase)
+void platform_add_backend_name(char *mixer_path, snd_device_t snd_device,
+ struct audio_usecase *usecase __unused)
{
if (snd_device == SND_DEVICE_IN_BT_SCO_MIC)
strlcat(mixer_path, " bt-sco", MIXER_PATH_MAX_LENGTH);
@@ -497,6 +498,9 @@
if (usecase->type == PCM_PLAYBACK)
snd_device = platform_get_output_snd_device(adev->platform,
usecase->stream.out->devices);
+ else if ((usecase->type == PCM_CAPTURE) &&
+ voice_is_in_call_rec_stream(usecase->stream.in))
+ snd_device = voice_get_incall_rec_snd_device(usecase->in_snd_device);
else if ((usecase->type == PCM_HFP_CALL) || (usecase->type == PCM_CAPTURE))
snd_device = platform_get_input_snd_device(adev->platform,
adev->primary_output->devices);
@@ -1175,13 +1179,13 @@
return -ENOSYS;
}
-int platform_set_spkr_device_tz_names(snd_device_t index,
- const char *spkr_1_tz_name, const char *spkr_2_tz_name)
-{
- return -ENOSYS;
-}
-
-int platform_get_wsa_mode(void *adev)
+bool platform_send_gain_dep_cal(void *platform __unused,
+ int level __unused)
{
return 0;
}
+
+void platform_set_gsm_mode(void *platform __unused, bool enable __unused)
+{
+ ALOGE("%s: Not implemented", __func__);
+}
diff --git a/hal/msm8974/hw_info.c b/hal/msm8974/hw_info.c
index c96d11e..5bf6ae4 100644
--- a/hal/msm8974/hw_info.c
+++ b/hal/msm8974/hw_info.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, 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
@@ -87,9 +87,6 @@
SND_DEVICE_IN_HANDSET_MIC,
};
-static const snd_device_t tomtom_8996_CDP_variant_devices[] = {
-};
-
static const snd_device_t tomtom_liquid_variant_devices[] = {
SND_DEVICE_OUT_SPEAKER,
SND_DEVICE_OUT_SPEAKER_EXTERNAL_1,
@@ -134,6 +131,10 @@
SND_DEVICE_IN_HANDSET_MIC_EXTERNAL
};
+static const snd_device_t tasha_DB_variant_devices[] = {
+ SND_DEVICE_OUT_SPEAKER
+};
+
static const snd_device_t taiko_apq8084_sbc_variant_devices[] = {
SND_DEVICE_IN_HANDSET_MIC,
SND_DEVICE_IN_SPEAKER_MIC,
@@ -171,6 +172,34 @@
SND_DEVICE_OUT_VOICE_SPEAKER,
};
+static const snd_device_t tasha_fluid_variant_devices[] = {
+ SND_DEVICE_OUT_SPEAKER,
+ SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
+ SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET,
+ SND_DEVICE_OUT_VOICE_SPEAKER,
+ SND_DEVICE_OUT_SPEAKER_AND_HDMI,
+ SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET,
+ SND_DEVICE_OUT_SPEAKER_PROTECTED,
+ SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED,
+};
+
+static const snd_device_t tasha_liquid_variant_devices[] = {
+ SND_DEVICE_OUT_SPEAKER,
+ SND_DEVICE_OUT_SPEAKER_EXTERNAL_1,
+ SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1,
+ SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
+ SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET,
+ SND_DEVICE_IN_SPEAKER_MIC,
+ SND_DEVICE_IN_HEADSET_MIC,
+ SND_DEVICE_IN_VOICE_DMIC,
+ SND_DEVICE_IN_VOICE_SPEAKER_DMIC,
+ 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,
+};
+
static void update_hardware_info_8084(struct hardware_info *hw_info, const char *snd_card_name)
{
if (!strcmp(snd_card_name, "apq8084-taiko-mtp-snd-card") ||
@@ -254,30 +283,24 @@
static void update_hardware_info_8996(struct hardware_info *hw_info, const char *snd_card_name)
{
- if (!strcmp(snd_card_name, "msm8996-tomtom-mtp-snd-card")) {
- strlcpy(hw_info->type, " mtp", sizeof(hw_info->type));
+ if (!strcmp(snd_card_name, "msm8996-tasha-fluid-snd-card")) {
+ strlcpy(hw_info->type, " fluid", sizeof(hw_info->type));
strlcpy(hw_info->name, "msm8996", sizeof(hw_info->name));
- hw_info->snd_devices = NULL;
- hw_info->num_snd_devices = 0;
- strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "msm8996-tomtom-cdp-snd-card")) {
- strlcpy(hw_info->type, " cdp", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8996", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *)tomtom_8996_CDP_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(tomtom_8996_CDP_variant_devices);
- strlcpy(hw_info->dev_extn, "-cdp", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "msm8996-tomtom-stp-snd-card")) {
- strlcpy(hw_info->type, " stp", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8996", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *)tomtom_stp_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(tomtom_stp_variant_devices);
- strlcpy(hw_info->dev_extn, "-stp", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "msm8996-tomtom-liquid-snd-card")) {
+ hw_info->snd_devices = (snd_device_t *)tasha_fluid_variant_devices;
+ hw_info->num_snd_devices = ARRAY_SIZE(tasha_fluid_variant_devices);
+ strlcpy(hw_info->dev_extn, "-fluid", sizeof(hw_info->dev_extn));
+ } else if (!strcmp(snd_card_name, "msm8996-tasha-liquid-snd-card")) {
strlcpy(hw_info->type, " liquid", sizeof(hw_info->type));
strlcpy(hw_info->name, "msm8996", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *)tomtom_liquid_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(tomtom_liquid_variant_devices);
+ hw_info->snd_devices = (snd_device_t *)tasha_liquid_variant_devices;
+ hw_info->num_snd_devices = ARRAY_SIZE(tasha_liquid_variant_devices);
strlcpy(hw_info->dev_extn, "-liquid", sizeof(hw_info->dev_extn));
+ } else if (!strcmp(snd_card_name, "msm8996-tasha-db-snd-card")) {
+ strlcpy(hw_info->type, " dragon-board", sizeof(hw_info->type));
+ strlcpy(hw_info->name, "msm8996", sizeof(hw_info->name));
+ hw_info->snd_devices = (snd_device_t *)tasha_DB_variant_devices;
+ hw_info->num_snd_devices = ARRAY_SIZE(tasha_DB_variant_devices);
+ strlcpy(hw_info->dev_extn, "-db", sizeof(hw_info->dev_extn));
} else {
ALOGW("%s: Not a 8996 device", __func__);
}
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 6f48828..d4cdf2e 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -54,6 +54,7 @@
#define PLATFORM_INFO_XML_PATH "/system/etc/audio_platform_info.xml"
#define PLATFORM_INFO_XML_PATH_I2S "/system/etc/audio_platform_info_i2s.xml"
+#include <linux/msm_audio.h>
#define LIB_ACDB_LOADER "libacdbloader.so"
#define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
@@ -98,7 +99,8 @@
#define EDID_FORMAT_LPCM 1
/* fallback app type if the default app type from acdb loader fails */
-#define DEFAULT_APP_TYPE 0x11130
+#define DEFAULT_APP_TYPE_RX_PATH 0x11130
+#define DEFAULT_APP_TYPE_TX_PATH 0x11132
/* Retry for delay in FW loading*/
#define RETRY_NUMBER 10
@@ -117,6 +119,7 @@
#define AUDIO_PARAMETER_KEY_AUD_CALDATA "cal_data"
#define AUDIO_PARAMETER_KEY_AUD_CALRESULT "cal_result"
+#define AUDIO_PARAMETER_KEY_PERF_LOCK_OPTS "perf_lock_opts"
/* Query external audio device connection status */
#define AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE "ext_audio_device"
@@ -129,6 +132,7 @@
char cal_name_info[WCD9XXX_MAX_CAL][MAX_CAL_NAME] = {
[WCD9XXX_ANC_CAL] = "anc_cal",
[WCD9XXX_MBHC_CAL] = "mbhc_cal",
+ [WCD9XXX_VBAT_CAL] = "vbat_cal",
};
#define AUDIO_PARAMETER_IS_HW_DECODER_SESSION_ALLOWED "is_hw_dec_session_allowed"
@@ -167,6 +171,12 @@
uint32_t param_id;
} acdb_audio_cal_cfg_t;
+enum {
+ CAL_MODE_SEND = 0x1,
+ CAL_MODE_PERSIST = 0x2,
+ CAL_MODE_RTAC = 0x4
+};
+
/* Audio calibration related functions */
typedef void (*acdb_deallocate_t)();
typedef int (*acdb_init_t)(const char *, char *, int);
@@ -178,6 +188,8 @@
acdb_loader_get_calibration_t acdb_loader_get_calibration;
typedef int (*acdb_set_audio_cal_t) (void *, void *, uint32_t);
typedef int (*acdb_get_audio_cal_t) (void *, void *, uint32_t*);
+typedef int (*acdb_send_common_top_t) (void);
+typedef int (*acdb_set_codec_data_t) (void *, char *);
typedef struct codec_backend_cfg {
uint32_t sample_rate;
@@ -190,8 +202,8 @@
bool platform_na_prop_enabled;
bool ui_na_prop_enabled;
} native_audio_prop;
-
static native_audio_prop na_props = {0, 0};
+typedef int (*acdb_send_gain_dep_cal_t)(int, int, int, int, int);
struct platform_data {
struct audio_device *adev;
@@ -210,6 +222,9 @@
bool ec_ref_enabled;
bool is_i2s_ext_modem;
bool is_acdb_initialized;
+ /* Vbat monitor related flags */
+ bool is_vbat_speaker;
+ bool gsm_mode_enabled;
/* Audio calibration related functions */
void *acdb_handle;
int voice_feature_set;
@@ -221,8 +236,11 @@
acdb_send_voice_cal_t acdb_send_voice_cal;
acdb_reload_vocvoltable_t acdb_reload_vocvoltable;
acdb_get_default_app_type_t acdb_get_default_app_type;
+ acdb_send_common_top_t acdb_send_common_top;
+ acdb_set_codec_data_t acdb_set_codec_data;
void *hw_info;
+ acdb_send_gain_dep_cal_t acdb_send_gain_dep_cal;
struct csd_data *csd;
void *edid_info;
bool edid_valid;
@@ -235,11 +253,12 @@
DEEP_BUFFER_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
LOWLATENCY_PCM_DEVICE},
+ [USECASE_AUDIO_PLAYBACK_ULL] = {MULTIMEDIA3_PCM_DEVICE,
+ MULTIMEDIA3_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_MULTI_CH] = {MULTIMEDIA2_PCM_DEVICE,
MULTIMEDIA2_PCM_DEVICE},
[USECASE_AUDIO_PLAYBACK_OFFLOAD] =
{PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
-#ifdef MULTIPLE_OFFLOAD_ENABLED
[USECASE_AUDIO_PLAYBACK_OFFLOAD2] =
{PLAYBACK_OFFLOAD_DEVICE2, PLAYBACK_OFFLOAD_DEVICE2},
[USECASE_AUDIO_PLAYBACK_OFFLOAD3] =
@@ -256,12 +275,7 @@
{PLAYBACK_OFFLOAD_DEVICE8, PLAYBACK_OFFLOAD_DEVICE8},
[USECASE_AUDIO_PLAYBACK_OFFLOAD9] =
{PLAYBACK_OFFLOAD_DEVICE9, PLAYBACK_OFFLOAD_DEVICE9},
-#endif
- [USECASE_AUDIO_PLAYBACK_ULL] = {MULTIMEDIA3_PCM_DEVICE,
- MULTIMEDIA3_PCM_DEVICE},
- [USECASE_AUDIO_DIRECT_PCM_OFFLOAD] =
- {PLAYBACK_OFFLOAD_DEVICE2, PLAYBACK_OFFLOAD_DEVICE2},
[USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
[USECASE_AUDIO_RECORD_COMPRESS] = {COMPRESS_CAPTURE_DEVICE, COMPRESS_CAPTURE_DEVICE},
@@ -316,15 +330,20 @@
[SND_DEVICE_OUT_SPEAKER] = "speaker",
[SND_DEVICE_OUT_SPEAKER_EXTERNAL_1] = "speaker-ext-1",
[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_HEADPHONES] = "headphones",
[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_AND_LINE] = "speaker-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_SPEAKER] = "voice-speaker",
+ [SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = "voice-speaker-vbat",
[SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
+ [SND_DEVICE_OUT_VOICE_LINE] = "voice-line",
[SND_DEVICE_OUT_HDMI] = "hdmi",
[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
[SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
@@ -345,6 +364,8 @@
[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_SPEAKER_PROTECTED_VBAT] = "speaker-protected-vbat",
+ [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED_VBAT] = "voice-speaker-protected-vbat",
/* Capture sound devices */
[SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
@@ -414,15 +435,20 @@
[SND_DEVICE_OUT_SPEAKER] = 14,
[SND_DEVICE_OUT_SPEAKER_EXTERNAL_1] = 130,
[SND_DEVICE_OUT_SPEAKER_EXTERNAL_2] = 130,
+ [SND_DEVICE_OUT_SPEAKER_VBAT] = 14,
[SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
+ [SND_DEVICE_OUT_LINE] = 10,
[SND_DEVICE_OUT_HEADPHONES] = 10,
[SND_DEVICE_OUT_HEADPHONES_44_1] = 10,
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
+ [SND_DEVICE_OUT_SPEAKER_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,
[SND_DEVICE_OUT_VOICE_SPEAKER] = 14,
+ [SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = 14,
[SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
+ [SND_DEVICE_OUT_VOICE_LINE] = 10,
[SND_DEVICE_OUT_HDMI] = 18,
[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14,
[SND_DEVICE_OUT_BT_SCO] = 22,
@@ -443,6 +469,8 @@
[SND_DEVICE_OUT_ANC_HANDSET] = 103,
[SND_DEVICE_OUT_SPEAKER_PROTECTED] = 124,
[SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = 101,
+ [SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT] = 124,
+ [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED_VBAT] = 101,
[SND_DEVICE_IN_HANDSET_MIC] = 4,
[SND_DEVICE_IN_HANDSET_MIC_EXTERNAL] = 4,
@@ -514,15 +542,20 @@
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_EXTERNAL_1)},
{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_HEADPHONES)},
{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_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_VBAT)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_LINE)},
{TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
{TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
@@ -542,6 +575,8 @@
{TO_NAME_INDEX(SND_DEVICE_OUT_ANC_HANDSET)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_PROTECTED)},
{TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED_VBAT)},
{TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_EXTERNAL)},
{TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC)},
@@ -602,9 +637,9 @@
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_ULL)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MULTI_CH)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
-#ifdef MULTIPLE_OFFLOAD_ENABLED
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD2)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD3)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD4)},
@@ -613,9 +648,6 @@
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD7)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD8)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD9)},
-#endif
- {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_ULL)},
- {TO_NAME_INDEX(USECASE_AUDIO_DIRECT_PCM_OFFLOAD)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
{TO_NAME_INDEX(USECASE_VOICE_CALL)},
@@ -719,8 +751,80 @@
#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
+bool platform_send_gain_dep_cal(void *platform, int level) {
+ bool ret_val = false;
+ struct platform_data *my_data = (struct platform_data *)platform;
+ struct audio_device *adev = my_data->adev;
+ int acdb_dev_id, app_type;
+ int acdb_dev_type = MSM_SNDDEV_CAP_RX;
+ int mode = CAL_MODE_RTAC;
+ struct listnode *node;
+ struct audio_usecase *usecase;
+
+ if (my_data->acdb_send_gain_dep_cal == NULL) {
+ ALOGE("%s: dlsym error for acdb_send_gain_dep_cal", __func__);
+ return ret_val;
+ }
+
+ if (!voice_is_in_call(adev)) {
+ ALOGV("%s: Not Voice call usecase, apply new cal for level %d",
+ __func__, level);
+
+ // find the current active sound device
+ list_for_each(node, &adev->usecase_list) {
+ usecase = node_to_item(node, struct audio_usecase, list);
+
+ if (usecase != NULL &&
+ usecase->type == PCM_PLAYBACK &&
+ usecase->stream.out->devices == AUDIO_DEVICE_OUT_SPEAKER) {
+
+ ALOGV("%s: out device is %d", __func__, usecase->out_snd_device);
+ app_type = usecase->stream.out->app_type_cfg.app_type;
+
+ if (audio_extn_spkr_prot_is_enabled()) {
+ acdb_dev_id = audio_extn_spkr_prot_get_acdb_id(usecase->out_snd_device);
+ } else {
+ acdb_dev_id = acdb_device_table[usecase->out_snd_device];
+ }
+
+ if (!my_data->acdb_send_gain_dep_cal(acdb_dev_id, app_type,
+ acdb_dev_type, mode, level)) {
+ // set ret_val true if at least one calibration is set successfully
+ ret_val = true;
+ } else {
+ ALOGE("%s: my_data->acdb_send_gain_dep_cal failed ", __func__);
+ }
+ } else {
+ ALOGW("%s: Usecase list is empty", __func__);
+ }
+ }
+ } else {
+ ALOGW("%s: Voice call in progress .. ignore setting new cal",
+ __func__);
+ }
+ return ret_val;
+}
+
+void platform_set_gsm_mode(void *platform, bool enable)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ struct audio_device *adev = my_data->adev;
+
+ if (my_data->gsm_mode_enabled) {
+ my_data->gsm_mode_enabled = false;
+ ALOGV("%s: disabling gsm mode", __func__);
+ audio_route_reset_and_update_path(adev->audio_route, "gsm-mode");
+ }
+
+ if (enable) {
+ my_data->gsm_mode_enabled = true;
+ ALOGD("%s: enabling gsm mode", __func__);
+ audio_route_apply_and_update_path(adev->audio_route, "gsm-mode");
+ }
+}
+
void platform_set_echo_reference(struct audio_device *adev, bool enable,
- audio_devices_t out_device)
+ audio_devices_t out_device)
{
struct platform_data *my_data = (struct platform_data *)adev->platform;
snd_device_t snd_device = SND_DEVICE_NONE;
@@ -731,26 +835,29 @@
if (strcmp(my_data->ec_ref_mixer_path, "")) {
ALOGV("%s: disabling %s", __func__, my_data->ec_ref_mixer_path);
audio_route_reset_and_update_path(adev->audio_route,
- my_data->ec_ref_mixer_path);
+ my_data->ec_ref_mixer_path);
}
if (enable) {
- strlcpy(my_data->ec_ref_mixer_path, "echo-reference",
- sizeof(my_data->ec_ref_mixer_path));
snd_device = platform_get_output_snd_device(adev->platform, &out);
+
/*
* If native audio device reference count > 0, then apply codec EC otherwise
- * fallback to headphones if so or default
+ * fallback to Speakers with VBat if enabled or default
*/
if (adev->snd_dev_ref_cnt[SND_DEVICE_OUT_HEADPHONES_44_1] > 0)
- platform_add_backend_name(my_data->ec_ref_mixer_path,
- SND_DEVICE_OUT_HEADPHONES_44_1);
+ strlcpy(my_data->ec_ref_mixer_path, "echo-reference headphones-44.1",
+ sizeof(my_data->ec_ref_mixer_path));
+ else if ((snd_device == SND_DEVICE_OUT_SPEAKER_VBAT) ||
+ (snd_device == SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT))
+ strlcpy(my_data->ec_ref_mixer_path, "echo-reference speaker-vbat",
+ sizeof(my_data->ec_ref_mixer_path));
else
- platform_add_backend_name(my_data->ec_ref_mixer_path, snd_device);
+ strlcpy(my_data->ec_ref_mixer_path, "echo-reference",
+ sizeof(my_data->ec_ref_mixer_path));
ALOGD("%s: enabling %s", __func__, my_data->ec_ref_mixer_path);
- audio_route_apply_and_update_path(adev->audio_route,
- my_data->ec_ref_mixer_path);
+ audio_route_apply_and_update_path(adev->audio_route, my_data->ec_ref_mixer_path);
}
}
@@ -955,6 +1062,7 @@
backend_table[SND_DEVICE_OUT_TRANSMISSION_FM] = strdup("transmission-fm");
backend_table[SND_DEVICE_OUT_HEADPHONES] = strdup("headphones");
backend_table[SND_DEVICE_OUT_HEADPHONES_44_1] = strdup("headphones-44.1");
+ backend_table[SND_DEVICE_OUT_VOICE_SPEAKER_VBAT] = strdup("voice-speaker-vbat");
}
void get_cvd_version(char *cvd_version, struct audio_device *adev)
@@ -1010,44 +1118,97 @@
void *buff;
};
-static int send_codec_cal(acdb_loader_get_calibration_t acdb_loader_get_calibration, int fd)
+static int send_vbat_adc_data_to_acdb(struct platform_data *plat_data, char *cal_type)
{
- int ret = 0, type;
+ int ret = 0;
+ struct mixer_ctl *ctl;
+ uint16_t vbat_adc_data[2];
+ struct platform_data *my_data = plat_data;
+ struct audio_device *adev = my_data->adev;
+
+ const char *mixer_ctl_name = "Vbat ADC data";
+
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer ctl name - %s",
+ __func__, mixer_ctl_name);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ vbat_adc_data[0] = mixer_ctl_get_value(ctl, 0);
+ vbat_adc_data[1] = mixer_ctl_get_value(ctl, 1);
+
+ ALOGD("%s: Vbat ADC output values: Dcp1: %d , Dcp2: %d",
+ __func__, vbat_adc_data[0], vbat_adc_data[1]);
+
+ ret = my_data->acdb_set_codec_data(&vbat_adc_data[0], cal_type);
+
+done:
+ return ret;
+}
+
+static void send_codec_cal(acdb_loader_get_calibration_t acdb_loader_get_calibration,
+ struct platform_data *plat_data, int fd)
+{
+ int type;
for (type = WCD9XXX_ANC_CAL; type < WCD9XXX_MAX_CAL; type++) {
struct wcdcal_ioctl_buffer codec_buffer;
struct param_data calib;
+ int ret;
/* MAD calibration is handled by sound trigger HAL, skip here */
if (type == WCD9XXX_MAD_CAL)
continue;
- calib.get_size = 1;
- ret = acdb_loader_get_calibration(cal_name_info[type], sizeof(struct param_data),
- &calib);
- if (ret < 0) {
- ALOGE("%s get_calibration failed\n", __func__);
- return ret;
+ ret = 0;
+
+ if ((plat_data->is_vbat_speaker) && (WCD9XXX_VBAT_CAL == type)) {
+ ret = send_vbat_adc_data_to_acdb(plat_data, cal_name_info[type]);
+ if (ret < 0)
+ ALOGE("%s error in sending vbat adc data to acdb", __func__);
}
+
+ calib.get_size = 1;
+ ret = acdb_loader_get_calibration(cal_name_info[type],
+ sizeof(struct param_data),
+ &calib);
+ if (ret < 0) {
+ ALOGE("%s: %s get_calibration size failed, err = %d\n",
+ __func__, cal_name_info[type], ret);
+ continue;
+ }
+
calib.get_size = 0;
calib.buff = malloc(calib.buff_size);
+ if (!calib.buff) {
+ ALOGE("%s: %s: No Memory for size = %d\n",
+ __func__, cal_name_info[type], calib.buff_size);
+ continue;
+ }
+
ret = acdb_loader_get_calibration(cal_name_info[type],
sizeof(struct param_data), &calib);
if (ret < 0) {
- ALOGE("%s get_calibration failed\n", __func__);
+ ALOGE("%s: %s get_calibration failed, err = %d\n",
+ __func__, cal_name_info[type], ret);
free(calib.buff);
- return ret;
+ continue;
}
+
codec_buffer.buffer = calib.buff;
codec_buffer.size = calib.data_size;
codec_buffer.cal_type = type;
if (ioctl(fd, SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE, &codec_buffer) < 0)
- ALOGE("Failed to call ioctl for %s err=%d",
- cal_name_info[type], errno);
- ALOGD("%s cal sent for %s", __func__, cal_name_info[type]);
+ ALOGE("%s: %s Failed to call ioctl, err=%d",
+ __func__, cal_name_info[type], errno);
+ else
+ ALOGD("%s: %s cal sent successfully\n",
+ __func__, cal_name_info[type]);
+
free(calib.buff);
}
- return ret;
}
static void audio_hwdep_send_cal(struct platform_data *plat_data)
@@ -1068,11 +1229,11 @@
dlerror());
return;
}
- if (send_codec_cal(acdb_loader_get_calibration, fd) < 0)
- ALOGE("%s: Could not send anc cal", __FUNCTION__);
+
+ send_codec_cal(acdb_loader_get_calibration, plat_data, fd);
}
-int platform_acdb_init(void *platform)
+static int platform_acdb_init(void *platform)
{
struct platform_data *my_data = (struct platform_data *)platform;
char *cvd_version = NULL;
@@ -1109,14 +1270,12 @@
char baseband[PROPERTY_VALUE_MAX];
char value[PROPERTY_VALUE_MAX];
struct platform_data *my_data = NULL;
- int retry_num = 0, snd_card_num = 0, key = 0, ret = 0;
- const char *snd_card_name;
+ int retry_num = 0, snd_card_num = 0, key = 0;
+ const char *snd_card_name = NULL;
char *cvd_version = NULL;
char *snd_internal_name = NULL;
char *tmp = NULL;
char mixer_xml_file[MIXER_PATH_MAX_LENGTH]= {0};
- const char *mixer_ctl_name = "Set HPX ActiveBe";
- struct mixer_ctl *ctl = NULL;
int idx;
my_data = calloc(1, sizeof(struct platform_data));
@@ -1143,7 +1302,12 @@
continue;
}
- snd_card_name = mixer_get_name(adev->mixer);
+ snd_card_name = strdup(mixer_get_name(adev->mixer));
+ if (!snd_card_name) {
+ ALOGE("failed to allocate memory for snd_card_name\n");
+ free(my_data);
+ return NULL;
+ }
ALOGV("%s: snd_card_name: %s", __func__, snd_card_name);
my_data->hw_info = hw_info_init(snd_card_name);
@@ -1205,6 +1369,7 @@
ALOGE("%s: Failed to init audio route controls, aborting.",
__func__);
free(my_data);
+ free(snd_card_name);
return NULL;
}
adev->snd_card = snd_card_num;
@@ -1218,6 +1383,8 @@
if (snd_card_num >= MAX_SND_CARD) {
ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
free(my_data);
+ if (snd_card_name)
+ free(snd_card_name);
return NULL;
}
@@ -1271,6 +1438,12 @@
}
}
+ /* Check if Vbat speaker enabled property is set, this should be done before acdb init */
+ bool ret = false;
+ ret = audio_extn_can_use_vbat();
+ if (ret)
+ my_data->is_vbat_speaker = true;
+
my_data->voice_feature_set = VOICE_FEATURE_SET_DEFAULT;
my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
if (my_data->acdb_handle == NULL) {
@@ -1320,6 +1493,27 @@
ALOGE("%s: Could not find the symbol acdb_get_default_app_type from %s",
__func__, LIB_ACDB_LOADER);
+ my_data->acdb_send_gain_dep_cal = (acdb_send_gain_dep_cal_t)dlsym(my_data->acdb_handle,
+ "acdb_loader_send_gain_dep_cal");
+ if (!my_data->acdb_send_gain_dep_cal)
+ ALOGV("%s: Could not find the symbol acdb_loader_send_gain_dep_cal from %s",
+ __func__, LIB_ACDB_LOADER);
+
+ my_data->acdb_send_common_top = (acdb_send_common_top_t)dlsym(
+ my_data->acdb_handle,
+ "acdb_loader_send_common_custom_topology");
+ if (!my_data->acdb_send_common_top)
+ ALOGE("%s: Could not find the symbol acdb_get_default_app_type from %s",
+ __func__, LIB_ACDB_LOADER);
+
+ my_data->acdb_set_codec_data = (acdb_set_codec_data_t)dlsym(
+ my_data->acdb_handle,
+ "acdb_loader_set_codec_data");
+ if (!my_data->acdb_set_codec_data)
+ ALOGE("%s: Could not find the symbol acdb_get_default_app_type from %s",
+ __func__, LIB_ACDB_LOADER);
+
+
my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
"acdb_loader_init_v2");
if (my_data->acdb_init == NULL) {
@@ -1330,22 +1524,15 @@
platform_acdb_init(my_data);
}
- /* Configure active back end for HPX*/
- ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
- if (ctl) {
- ALOGI(" sending HPX Active BE information ");
- mixer_ctl_set_value(ctl, 0, true);
- }
-
acdb_init_fail:
set_platform_defaults();
/* Initialize ACDB ID's */
if (my_data->is_i2s_ext_modem)
- platform_info_init(PLATFORM_INFO_XML_PATH_I2S);
+ platform_info_init(PLATFORM_INFO_XML_PATH_I2S, my_data);
else
- platform_info_init(PLATFORM_INFO_XML_PATH);
+ platform_info_init(PLATFORM_INFO_XML_PATH, my_data);
/* If platform is apq8084 and baseband is MDM, load CSD Client specific
* symbols. Voice call is handled by MDM and apps processor talks to
@@ -1373,7 +1560,6 @@
audio_extn_spkr_prot_init(adev);
audio_extn_dolby_set_license(adev);
- audio_hwdep_send_cal(my_data);
/* init audio device arbitration */
audio_extn_dev_arbi_init();
@@ -1397,6 +1583,7 @@
strdup("SLIM_5_RX SampleRate");
my_data->edid_info = NULL;
+ free(snd_card_name);
return my_data;
}
@@ -1434,13 +1621,27 @@
audio_extn_dap_hal_deinit();
}
-int platform_is_acdb_initialized(void *platform)
+static int platform_is_acdb_initialized(void *platform)
{
struct platform_data *my_data = (struct platform_data *)platform;
ALOGD("%s: acdb initialized %d\n", __func__, my_data->is_acdb_initialized);
return my_data->is_acdb_initialized;
}
+void platform_snd_card_update(void *platform, int snd_scard_state)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+
+ if (snd_scard_state == SND_CARD_STATE_ONLINE) {
+ if (!platform_is_acdb_initialized(my_data)) {
+ if(platform_acdb_init(my_data))
+ ALOGE("%s: acdb initialization is failed", __func__);
+ } else if (my_data->acdb_send_common_top() < 0) {
+ ALOGD("%s: acdb did not set common topology", __func__);
+ }
+ }
+}
+
const char *platform_get_snd_device_name(snd_device_t snd_device)
{
if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
@@ -1449,22 +1650,6 @@
return "";
}
-const char *platform_get_spkr_1_tz_name(snd_device_t snd_device)
-{
- if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
- return speaker_device_tz_names.spkr_1_tz_name;
- else
- return "";
-}
-
-const char *platform_get_spkr_2_tz_name(snd_device_t snd_device)
-{
- if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
- return speaker_device_tz_names.spkr_2_tz_name;
- else
- return "";
-}
-
int platform_get_snd_device_name_extn(void *platform, snd_device_t snd_device,
char *device_name)
{
@@ -1481,13 +1666,20 @@
return 0;
}
-void platform_add_backend_name(char *mixer_path, snd_device_t snd_device, struct audio_usecase *usecase)
+void platform_add_backend_name(char *mixer_path, snd_device_t snd_device,
+ struct audio_usecase *usecase)
{
if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
return;
}
+ if ((snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_VBAT) &&
+ !(usecase->type == VOICE_CALL || usecase->type == VOIP_CALL)) {
+ ALOGI("%s: Not adding vbat speaker device to non voice use cases", __func__);
+ return;
+ }
+
const char * suffix = backend_table[snd_device];
if (suffix != NULL) {
@@ -1631,7 +1823,15 @@
if (my_data->acdb_get_default_app_type)
return my_data->acdb_get_default_app_type();
else
- return DEFAULT_APP_TYPE;
+ return DEFAULT_APP_TYPE_RX_PATH;
+}
+
+int platform_get_default_app_type_v2(void *platform, usecase_type_t type)
+{
+ if(type == PCM_CAPTURE)
+ return DEFAULT_APP_TYPE_TX_PATH;
+ else
+ return DEFAULT_APP_TYPE_RX_PATH;
}
int platform_get_snd_device_acdb_id(snd_device_t snd_device)
@@ -1670,11 +1870,12 @@
int platform_set_native_support(bool codec_support)
{
+ int ret = 0;
na_props.platform_na_prop_enabled = na_props.ui_na_prop_enabled
= codec_support;
ALOGD("%s: na_props.platform_na_prop_enabled: %d", __func__,
na_props.platform_na_prop_enabled);
- return 0;
+ return ret;
}
int platform_get_native_support()
@@ -1788,11 +1989,13 @@
int snd_device = SND_DEVICE_OUT_SPEAKER;
if (usecase->type == PCM_PLAYBACK)
- snd_device = platform_get_output_snd_device(adev->platform,
- usecase->stream.out);
+ snd_device = usecase->out_snd_device;
+ else if ((usecase->type == PCM_CAPTURE) &&
+ voice_is_in_call_rec_stream(usecase->stream.in))
+ snd_device = voice_get_incall_rec_snd_device(usecase->in_snd_device);
else if ((usecase->type == PCM_HFP_CALL) || (usecase->type == PCM_CAPTURE))
- snd_device = platform_get_input_snd_device(adev->platform,
- adev->primary_output->devices);
+ snd_device = usecase->in_snd_device;
+
acdb_dev_id = acdb_device_table[audio_extn_get_spkr_prot_snd_device(snd_device)];
if (acdb_dev_id < 0) {
ALOGE("%s: Could not find acdb id for device(%d)",
@@ -1841,10 +2044,14 @@
if (my_data->csd == NULL)
return ret;
- if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
- audio_extn_spkr_prot_is_enabled())
- acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED];
- else
+ if ((out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER ||
+ out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_VBAT) &&
+ audio_extn_spkr_prot_is_enabled()) {
+ if (my_data->is_vbat_speaker)
+ acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT];
+ else
+ acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED];
+ } else
acdb_rx_id = acdb_device_table[out_snd_device];
acdb_tx_id = acdb_device_table[in_snd_device];
@@ -1901,10 +2108,14 @@
if (my_data->csd == NULL)
return ret;
- if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
- audio_extn_spkr_prot_is_enabled())
- acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED];
- else
+ if ((out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER ||
+ out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER_VBAT) &&
+ audio_extn_spkr_prot_is_enabled()) {
+ if (my_data->is_vbat_speaker)
+ acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT];
+ else
+ acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED];
+ } else
acdb_rx_id = acdb_device_table[out_snd_device];
acdb_tx_id = acdb_device_table[in_snd_device];
@@ -2109,6 +2320,9 @@
snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2;
else
snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
+ } 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_AUX_DIGITAL |
AUDIO_DEVICE_OUT_SPEAKER)) {
snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
@@ -2132,7 +2346,8 @@
if ((mode == AUDIO_MODE_IN_CALL) ||
voice_extn_compress_voip_is_active(adev)) {
if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
+ devices & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
+ devices & AUDIO_DEVICE_OUT_LINE) {
if ((adev->voice.tty_mode != TTY_MODE_OFF) &&
!voice_extn_compress_voip_is_active(adev)) {
switch (adev->voice.tty_mode) {
@@ -2149,6 +2364,8 @@
ALOGE("%s: Invalid TTY mode (%#x)",
__func__, adev->voice.tty_mode);
}
+ } else if (devices & AUDIO_DEVICE_OUT_LINE) {
+ snd_device = SND_DEVICE_OUT_VOICE_LINE;
} else if (audio_extn_get_anc_enabled()) {
if (audio_extn_should_use_fb_anc())
snd_device = SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET;
@@ -2163,7 +2380,10 @@
else
snd_device = SND_DEVICE_OUT_BT_SCO;
} else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
- snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
+ if (my_data->is_vbat_speaker)
+ snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_VBAT;
+ else
+ snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
} else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
snd_device = SND_DEVICE_OUT_USB_HEADSET;
@@ -2195,6 +2415,8 @@
snd_device = SND_DEVICE_OUT_HEADPHONES_44_1;
else
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) {
if (my_data->external_spk_1)
snd_device = SND_DEVICE_OUT_SPEAKER_EXTERNAL_1;
@@ -2202,6 +2424,8 @@
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)
+ snd_device = SND_DEVICE_OUT_SPEAKER_VBAT;
else
snd_device = SND_DEVICE_OUT_SPEAKER;
} else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
@@ -2272,7 +2496,8 @@
if ((adev->voice.tty_mode != TTY_MODE_OFF) &&
!voice_extn_compress_voip_is_active(adev)) {
if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
+ out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET ||
+ out_device & AUDIO_DEVICE_OUT_LINE) {
switch (adev->voice.tty_mode) {
case TTY_MODE_FULL:
snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
@@ -2290,7 +2515,8 @@
}
}
if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
- out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
+ out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+ out_device & AUDIO_DEVICE_OUT_LINE) {
if (out_device & AUDIO_DEVICE_OUT_EARPIECE &&
audio_extn_should_use_handset_anc(channel_count)) {
snd_device = SND_DEVICE_IN_AANC_HANDSET_MIC;
@@ -2503,7 +2729,8 @@
snd_device = SND_DEVICE_IN_SPEAKER_STEREO_DMIC;
else
snd_device = SND_DEVICE_IN_SPEAKER_MIC;
- } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
+ } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+ out_device & AUDIO_DEVICE_OUT_LINE) {
snd_device = SND_DEVICE_IN_HANDSET_MIC;
} else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
if (adev->bt_wb_speech_enabled) {
@@ -2804,6 +3031,44 @@
free(dptr);
}
+static void perf_lock_set_params(struct platform_data *platform,
+ struct str_parms *parms,
+ char *value, int len)
+{
+ int err = 0, i = 0, num_opts = 0;
+ char *test_r = NULL;
+ char *opts = NULL;
+ char *opts_size = NULL;
+
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_PERF_LOCK_OPTS,
+ value, len);
+ if (err >= 0) {
+ opts_size = strtok_r(value, ", ", &test_r);
+ if (opts_size == NULL) {
+ ALOGE("%s: incorrect perf lock opts\n", __func__);
+ return;
+ }
+ num_opts = atoi(opts_size);
+ if (num_opts > 0) {
+ if (num_opts > MAX_PERF_LOCK_OPTS) {
+ ALOGD("%s: num_opts %d exceeds max %d, setting to max\n",
+ __func__, num_opts, MAX_PERF_LOCK_OPTS);
+ num_opts = MAX_PERF_LOCK_OPTS;
+ }
+ for (i = 0; i < num_opts; i++) {
+ opts = strtok_r(NULL, ", ", &test_r);
+ if (opts == NULL) {
+ ALOGE("%s: incorrect perf lock opts\n", __func__);
+ break;
+ }
+ platform->adev->perf_lock_opts[i] = strtoul(opts, NULL, 16);
+ }
+ platform->adev->perf_lock_opts_size = i;
+ }
+ str_parms_del(parms, AUDIO_PARAMETER_KEY_PERF_LOCK_OPTS);
+ }
+}
+
int platform_set_parameters(void *platform, struct str_parms *parms)
{
struct platform_data *my_data = (struct platform_data *)platform;
@@ -2901,6 +3166,8 @@
/* handle audio calibration parameters */
set_audiocal(platform, parms, value, len);
native_audio_set_params(platform, parms, value, len);
+ audio_extn_spkr_prot_set_parameters(parms, value, len);
+ perf_lock_set_params(platform, parms, value, len);
done:
ALOGV("%s: exit with code(%d)", __func__, ret);
if(kv_pairs != NULL)
@@ -3114,6 +3381,8 @@
char value[512] = {0};
int ret;
char *kv_pairs = NULL;
+ char propValue[PROPERTY_VALUE_MAX]={0};
+ bool prop_playback_enabled = false;
ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_SLOWTALK,
value, sizeof(value));
@@ -3197,7 +3466,7 @@
int platform_update_usecase_from_source(int source, int usecase)
{
ALOGV("%s: input source :%d", __func__, source);
- if(source == AUDIO_SOURCE_FM_TUNER)
+ if (source == AUDIO_SOURCE_FM_TUNER)
usecase = USECASE_AUDIO_RECORD_FM_VIRTUAL;
return usecase;
}
@@ -3421,7 +3690,6 @@
struct stream_out *out = NULL;
unsigned int bit_width;
unsigned int sample_rate;
- char value[PROPERTY_VALUE_MAX] = {0};
int backend_idx = DEFAULT_CODEC_BACKEND;
int usecase_backend_idx = DEFAULT_CODEC_BACKEND;
struct platform_data *my_data = (struct platform_data *)adev->platform;
@@ -3476,6 +3744,7 @@
}
}
}
+
if (backend_idx != HEADPHONE_44_1_BACKEND) {
// 16 bit playbacks are allowed through 16 bit/48 khz backend only for
// all non-native streams
@@ -3484,20 +3753,6 @@
ALOGD("%s: resetting sample_rate back to default, "
"backend_idx: %d", __func__, backend_idx);
}
-
- //check if mulitchannel clip needs to be down sampled to 48k
- property_get("audio.playback.mch.downsample",value,"");
- if (!strncmp("true", value, sizeof("true"))) {
- out = usecase->stream.out;
- if ((popcount(out->channel_mask) > 2) &&
- (out->sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
- !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)) {
- /* update out sample rate to reflect current backend sample rate */
- sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
- ALOGD("%s: MCH session defaulting sample rate to %d",
- __func__, sample_rate);
- }
- }
// 24 bit playback on speakers is allowed through 48 khz backend only
// bit width re-configured based on platform info
if ((24 == bit_width) &&
@@ -4093,15 +4348,6 @@
}
/*
- * This is a lookup table to map names of speaker device with respective left and right TZ names.
- * Also the tz names for a particular left or right speaker can be overriden by adding
- * corresponding entry in audio_platform_info.xml file.
- */
-struct speaker_device_to_tz_names speaker_device_tz_names = {
- {SND_DEVICE_OUT_SPEAKER, "", ""},
-};
-
-/*
* This is a lookup table to map android audio input device to audio h/w interface (backend).
* The table can be extended for other input devices by adding appropriate entries.
* Also the audio interface for a particular input device can be overriden by adding
@@ -4153,37 +4399,4 @@
return ret;
}
-int platform_set_spkr_device_tz_names(snd_device_t index,
- const char *spkr_1_tz_name, const char *spkr_2_tz_name)
-{
- int ret = 0;
- int i;
- if (spkr_1_tz_name == NULL && spkr_2_tz_name == NULL) {
- ALOGE("%s: Invalid input", __func__);
- ret = -EINVAL;
- goto done;
- }
- if (index != speaker_device_tz_names.snd_device) {
- ALOGE("%s: not matching speaker device\n");
- ret = -EINVAL;
- goto done;
- }
- ALOGD("%s: Enter, spkr_1_tz_name :%s, spkr_2_tz_name:%s",
- __func__, spkr_1_tz_name, spkr_2_tz_name);
-
- if (spkr_1_tz_name != NULL)
- strlcpy(speaker_device_tz_names.spkr_1_tz_name, spkr_1_tz_name,
- sizeof(speaker_device_tz_names.spkr_1_tz_name));
-
- if (spkr_2_tz_name != NULL)
- strlcpy(speaker_device_tz_names.spkr_2_tz_name, spkr_2_tz_name,
- sizeof(speaker_device_tz_names.spkr_2_tz_name));
-done:
- return ret;
-}
-
-int platform_get_wsa_mode (void *adev)
-{
- return 0;
-}
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index fdf3400..c98d1af 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -43,7 +43,8 @@
*/
#define AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND \
(AUDIO_DEVICE_OUT_EARPIECE | AUDIO_DEVICE_OUT_SPEAKER | \
- AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE)
+ AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE | \
+ AUDIO_DEVICE_OUT_LINE)
/*
* Below are the input devices for which back end is same, SLIMBUS_0_TX.
@@ -69,14 +70,19 @@
SND_DEVICE_OUT_SPEAKER_EXTERNAL_1,
SND_DEVICE_OUT_SPEAKER_EXTERNAL_2,
SND_DEVICE_OUT_SPEAKER_REVERSE,
+ SND_DEVICE_OUT_SPEAKER_VBAT,
+ SND_DEVICE_OUT_LINE,
SND_DEVICE_OUT_HEADPHONES,
SND_DEVICE_OUT_HEADPHONES_44_1,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
+ SND_DEVICE_OUT_SPEAKER_AND_LINE,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2,
SND_DEVICE_OUT_VOICE_HANDSET,
SND_DEVICE_OUT_VOICE_SPEAKER,
+ SND_DEVICE_OUT_VOICE_SPEAKER_VBAT,
SND_DEVICE_OUT_VOICE_HEADPHONES,
+ SND_DEVICE_OUT_VOICE_LINE,
SND_DEVICE_OUT_HDMI,
SND_DEVICE_OUT_SPEAKER_AND_HDMI,
SND_DEVICE_OUT_BT_SCO,
@@ -97,6 +103,10 @@
SND_DEVICE_OUT_ANC_HANDSET,
SND_DEVICE_OUT_SPEAKER_PROTECTED,
SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED,
+ SND_DEVICE_OUT_SPEAKER_PROTECTED_VBAT,
+ SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED_VBAT,
+ SND_DEVICE_OUT_SPEAKER_WSA,
+ SND_DEVICE_OUT_VOICE_SPEAKER_WSA,
SND_DEVICE_OUT_END,
/*
@@ -194,8 +204,8 @@
* We should take care of returning proper size when AudioFlinger queries for
* the buffer size of an input/output stream
*/
-#define DEEP_BUFFER_OUTPUT_PERIOD_SIZE 960
-#define DEEP_BUFFER_OUTPUT_PERIOD_COUNT 5
+#define DEEP_BUFFER_OUTPUT_PERIOD_SIZE 1920
+#define DEEP_BUFFER_OUTPUT_PERIOD_COUNT 2
#define LOW_LATENCY_OUTPUT_PERIOD_SIZE 240
#define LOW_LATENCY_OUTPUT_PERIOD_COUNT 2
@@ -237,14 +247,19 @@
#define SPKR_PROT_CALIB_RX_PCM_DEVICE 5
#ifdef PLATFORM_APQ8084
#define SPKR_PROT_CALIB_TX_PCM_DEVICE 35
+#elif PLATFORM_MSM8996
+#define SPKR_PROT_CALIB_TX_PCM_DEVICE 42
#else
#define SPKR_PROT_CALIB_TX_PCM_DEVICE 25
#endif
#define PLAYBACK_OFFLOAD_DEVICE 9
-#ifdef MULTIPLE_OFFLOAD_ENABLED
-#ifdef PLATFORM_APQ8084
+// Direct_PCM
+#if defined (PLATFORM_MSM8994) || defined (PLATFORM_MSM8996) || defined (PLATFORM_APQ8084)
#define PLAYBACK_OFFLOAD_DEVICE2 17
+#endif
+
+#ifdef PLATFORM_APQ8084
#define PLAYBACK_OFFLOAD_DEVICE3 18
#define PLAYBACK_OFFLOAD_DEVICE4 34
#define PLAYBACK_OFFLOAD_DEVICE5 35
@@ -254,7 +269,6 @@
#define PLAYBACK_OFFLOAD_DEVICE9 39
#endif
#if defined (PLATFORM_MSM8994) || defined (PLATFORM_MSM8996)
-#define PLAYBACK_OFFLOAD_DEVICE2 17
#define PLAYBACK_OFFLOAD_DEVICE3 18
#define PLAYBACK_OFFLOAD_DEVICE4 37
#define PLAYBACK_OFFLOAD_DEVICE5 38
@@ -263,10 +277,6 @@
#define PLAYBACK_OFFLOAD_DEVICE8 41
#define PLAYBACK_OFFLOAD_DEVICE9 42
#endif
-#endif
-
-// for DIRECT_PCM
-#define PLAYBACK_OFFLOAD_DEVICE2 17
#define COMPRESS_VOIP_CALL_PCM_DEVICE 3
@@ -409,10 +419,4 @@
char device_name[100];
char interface_name[100];
};
-
-struct speaker_device_to_tz_names {
- snd_device_t snd_device;
- char spkr_1_tz_name[100];
- char spkr_2_tz_name[100];
-};
#endif // QCOM_AUDIO_PLATFORM_H
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 9430721..a89c267 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -26,12 +26,12 @@
void *platform_init(struct audio_device *adev);
void platform_deinit(void *platform);
-int platform_is_acdb_initialized(void *platform);
-int platform_acdb_init(void *platform);
const char *platform_get_snd_device_name(snd_device_t snd_device);
int platform_get_snd_device_name_extn(void *platform, snd_device_t snd_device,
char *device_name);
-void platform_add_backend_name(char *mixer_path, snd_device_t snd_device, struct audio_usecase *usecase);
+void platform_add_backend_name(char *mixer_path, snd_device_t snd_device,
+ struct audio_usecase *usecase);
+bool platform_send_gain_dep_cal(void *platform, int level);
int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type);
int platform_get_snd_device_index(char *snd_device_index_name);
int platform_set_fluence_type(void *platform, char *value);
@@ -46,6 +46,7 @@
int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase,
int app_type, int sample_rate);
int platform_get_default_app_type(void *platform);
+int platform_get_default_app_type_v2(void *platform, usecase_type_t type);
int platform_switch_voice_call_device_pre(void *platform);
int platform_switch_voice_call_enable_device_config(void *platform,
snd_device_t out_snd_device,
@@ -88,8 +89,10 @@
int platform_set_snd_device_backend(snd_device_t snd_device, const char * backend);
-/* From platform_info_parser.c */
-int platform_info_init(const char *filename);
+/* From platform_info.c */
+int platform_info_init(const char *filename, void *);
+
+void platform_snd_card_update(void *platform, int snd_scard_state);
struct audio_offload_info_t;
uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info);
@@ -118,10 +121,5 @@
int platform_set_device_params(struct stream_out *out, int param, int value);
int platform_set_audio_device_interface(const char * device_name, const char *intf_name,
const char * codec_type);
-int platform_set_spkr_device_tz_names(snd_device_t index,
- const char *spkr_1_tz_name, const char *spkr_2_tz_name);
-const char *platform_get_spkr_1_tz_name(snd_device_t snd_device);
-const char *platform_get_spkr_2_tz_name(snd_device_t snd_device);
-int platform_get_wsa_mode(void *adev);
void platform_set_gsm_mode(void *platform, bool enable);
#endif // AUDIO_PLATFORM_API_H
diff --git a/hal/platform_info.c b/hal/platform_info.c
index 50e19c6..6514cb3 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -34,6 +34,7 @@
#include <stdio.h>
#include <expat.h>
#include <cutils/log.h>
+#include <cutils/str_parms.h>
#include <audio_hw.h>
#include "platform_api.h"
#include <platform.h>
@@ -48,6 +49,7 @@
PCM_ID,
BACKEND_NAME,
INTERFACE_NAME,
+ CONFIG_PARAMS,
TZ_NAME,
} section_t;
@@ -59,6 +61,7 @@
static void process_pcm_id(const XML_Char **attr);
static void process_backend_name(const XML_Char **attr);
static void process_interface_name(const XML_Char **attr);
+static void process_config_params(const XML_Char **attr);
static void process_tz_name(const XML_Char **attr);
static void process_root(const XML_Char **attr);
@@ -70,11 +73,19 @@
[PCM_ID] = process_pcm_id,
[BACKEND_NAME] = process_backend_name,
[INTERFACE_NAME] = process_interface_name,
+ [CONFIG_PARAMS] = process_config_params,
[TZ_NAME] = process_tz_name,
};
static section_t section;
+struct platform_info {
+ void *platform;
+ struct str_parms *kvpairs;
+};
+
+static struct platform_info my_data;
+
/*
* <audio_platform_info>
* <acdb_ids>
@@ -97,6 +108,12 @@
* ...
* ...
* </interface_names>
+ * <config_params>
+ * <param key="snd_card_name" value="msm8994-tomtom-mtp-snd-card"/>
+ * ...
+ * ...
+ * </config_params>
+ *
* <tz_names>
* <device name="???" spkr_1_tz_name="???" spkr_2_tz_name="???"/>
* ...
@@ -115,7 +132,7 @@
int index;
if (strcmp(attr[0], "name") != 0) {
- ALOGE("%s: 'name' not found, no ACDB ID set!", __func__);
+ ALOGE("%s: 'name' not found, no pcm_id set!", __func__);
goto done;
}
@@ -341,16 +358,34 @@
__func__, attr[1]);
}
- ret = platform_set_spkr_device_tz_names(index, (char *)attr[3], (char *)attr[5]);
+ /* ret = platform_set_spkr_device_tz_names(index, (char *)attr[3], (char *)attr[5]);
if (ret < 0) {
ALOGE("%s: Audio Interface not set!", __func__);
goto done;
}
+ */
done:
return;
}
+static void process_config_params(const XML_Char **attr)
+{
+ if (strcmp(attr[0], "key") != 0) {
+ ALOGE("%s: 'key' not found", __func__);
+ goto done;
+ }
+
+ if (strcmp(attr[2], "value") != 0) {
+ ALOGE("%s: 'value' not found", __func__);
+ goto done;
+ }
+
+ str_parms_add_str(my_data.kvpairs, (char*)attr[1], (char*)attr[3]);
+done:
+ return;
+}
+
static void start_tag(void *userdata __unused, const XML_Char *tag_name,
const XML_Char **attr)
{
@@ -366,6 +401,8 @@
section = PCM_ID;
} else if (strcmp(tag_name, "backend_names") == 0) {
section = BACKEND_NAME;
+ } else if (strcmp(tag_name, "config_params") == 0) {
+ section = CONFIG_PARAMS;
} else if (strcmp(tag_name, "interface_names") == 0) {
section = INTERFACE_NAME;
} else if (strcmp(tag_name, "tz_names") == 0) {
@@ -398,6 +435,14 @@
section_process_fn fn = section_table[NATIVESUPPORT];
fn(attr);
+ } 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;
@@ -413,6 +458,9 @@
section = ROOT;
} else if (strcmp(tag_name, "backend_names") == 0) {
section = ROOT;
+ } else if (strcmp(tag_name, "config_params") == 0) {
+ section = ROOT;
+ platform_set_parameters(my_data.platform, my_data.kvpairs);
} else if (strcmp(tag_name, "interface_names") == 0) {
section = ROOT;
} else if (strcmp(tag_name, "native_configs") == 0) {
@@ -420,7 +468,7 @@
}
}
-int platform_info_init(const char *filename)
+int platform_info_init(const char *filename, void *platform)
{
XML_Parser parser;
FILE *file;
@@ -445,6 +493,9 @@
goto err_close_file;
}
+ my_data.platform = platform;
+ my_data.kvpairs = str_parms_create();
+
XML_SetElementHandler(parser, start_tag, end_tag);
while (1) {
diff --git a/hal/voice.c b/hal/voice.c
index bc9d5c7..4824d35 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -131,7 +131,8 @@
}
session->state.current = CALL_INACTIVE;
- adev->voice.is_in_call = false;
+ if (adev->mode == AUDIO_MODE_NORMAL)
+ adev->voice.is_in_call = false;
/* Disable sidetone only when no calls are active */
if (!voice_is_call_state_active(adev))
diff --git a/hal/voice_extn/compress_voip.c b/hal/voice_extn/compress_voip.c
index bb1caf9..1dcf865 100644
--- a/hal/voice_extn/compress_voip.c
+++ b/hal/voice_extn/compress_voip.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -93,7 +93,7 @@
static int audio_format_to_voip_mode(int format)
{
- int mode = 0;
+ int mode = AUDIO_FORMAT_INVALID;
if (format == AUDIO_FORMAT_PCM_16_BIT) {
mode = MODE_PCM;
@@ -702,15 +702,11 @@
bool voice_extn_compress_voip_is_format_supported(audio_format_t format)
{
- switch (format) {
- case AUDIO_FORMAT_PCM_16_BIT:
- if (voice_extn_compress_voip_pcm_prop_check())
- return true;
- else
- return false;
- default:
- return false;
- }
+ if (format == AUDIO_FORMAT_PCM_16_BIT &&
+ voice_extn_compress_voip_pcm_prop_check())
+ return true;
+ else
+ return false;
}
bool voice_extn_compress_voip_is_config_supported(struct audio_config *config)
diff --git a/mm-audio/aenc-aac/qdsp6/inc/omx_aac_aenc.h b/mm-audio/aenc-aac/qdsp6/inc/omx_aac_aenc.h
index a87717b..7f0a2cb 100644
--- a/mm-audio/aenc-aac/qdsp6/inc/omx_aac_aenc.h
+++ b/mm-audio/aenc-aac/qdsp6/inc/omx_aac_aenc.h
@@ -414,8 +414,8 @@
unsigned int offset_to_frame;
unsigned int frame_size;
unsigned int encoded_pcm_samples;
- unsigned int msw_ts;
unsigned int lsw_ts;
+ unsigned int msw_ts;
unsigned int nflags;
} __attribute__ ((packed))ENC_META_OUT;
diff --git a/mm-audio/aenc-amrnb/qdsp6/inc/omx_amr_aenc.h b/mm-audio/aenc-amrnb/qdsp6/inc/omx_amr_aenc.h
index ed7f758..2d72eb2 100644
--- a/mm-audio/aenc-amrnb/qdsp6/inc/omx_amr_aenc.h
+++ b/mm-audio/aenc-amrnb/qdsp6/inc/omx_amr_aenc.h
@@ -341,8 +341,8 @@
unsigned int offset_to_frame;
unsigned int frame_size;
unsigned int encoded_pcm_samples;
- unsigned int msw_ts;
unsigned int lsw_ts;
+ unsigned int msw_ts;
unsigned int nflags;
} __attribute__ ((packed))ENC_META_OUT;
diff --git a/mm-audio/aenc-evrc/qdsp6/inc/omx_evrc_aenc.h b/mm-audio/aenc-evrc/qdsp6/inc/omx_evrc_aenc.h
index 09ffb2d..f107789 100644
--- a/mm-audio/aenc-evrc/qdsp6/inc/omx_evrc_aenc.h
+++ b/mm-audio/aenc-evrc/qdsp6/inc/omx_evrc_aenc.h
@@ -342,8 +342,8 @@
unsigned int offset_to_frame;
unsigned int frame_size;
unsigned int encoded_pcm_samples;
- unsigned int msw_ts;
unsigned int lsw_ts;
+ unsigned int msw_ts;
unsigned int nflags;
} __attribute__ ((packed))ENC_META_OUT;
diff --git a/mm-audio/aenc-qcelp13/qdsp6/inc/omx_qcelp13_aenc.h b/mm-audio/aenc-qcelp13/qdsp6/inc/omx_qcelp13_aenc.h
index 22cc9ed..83e129c 100644
--- a/mm-audio/aenc-qcelp13/qdsp6/inc/omx_qcelp13_aenc.h
+++ b/mm-audio/aenc-qcelp13/qdsp6/inc/omx_qcelp13_aenc.h
@@ -342,8 +342,8 @@
unsigned int offset_to_frame;
unsigned int frame_size;
unsigned int encoded_pcm_samples;
- unsigned int msw_ts;
unsigned int lsw_ts;
+ unsigned int msw_ts;
unsigned int nflags;
} __attribute__ ((packed))ENC_META_OUT;
diff --git a/policy_hal/Android.mk b/policy_hal/Android.mk
index 9fb49ac..70814d8 100644
--- a/policy_hal/Android.mk
+++ b/policy_hal/Android.mk
@@ -52,11 +52,11 @@
endif
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_HDMI_SPK)),true)
-LOCAL_CFLAGS += -DAUDIO_EXTN_HDMI_SPK_ENABLED
+ LOCAL_CFLAGS += -DAUDIO_EXTN_HDMI_SPK_ENABLED
endif
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_PROXY_DEVICE)),true)
-LOCAL_CFLAGS += -DAUDIO_EXTN_AFE_PROXY_ENABLED
+ LOCAL_CFLAGS += -DAUDIO_EXTN_AFE_PROXY_ENABLED
endif
ifeq ($(strip $(AUDIO_FEATURE_ENABLED_FM_POWER_OPT)),true)
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index 878c024..e48de6d 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -15,6 +15,24 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
+ *
+ * This file was modified by Dolby Laboratories, Inc. The portions of the
+ * code that are surrounded by "DOLBY..." are copyrighted and
+ * licensed separately, as follows:
+ *
+ * (C) 2015 Dolby Laboratories, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
#define LOG_TAG "AudioPolicyManagerCustom"
@@ -46,6 +64,9 @@
#include <soundtrigger/SoundTrigger.h>
#include "AudioPolicyManager.h"
#include <policy.h>
+#ifdef DOLBY_ENABLE
+#include "DolbyAudioPolicy_impl.h"
+#endif // DOLBY_END
namespace android {
#ifdef VOICE_CONCURRENCY
@@ -246,6 +267,11 @@
}
updateDevicesAndOutputs();
+#ifdef DOLBY_ENABLE
+ // Before closing the opened outputs, update endpoint property with device capabilities
+ audio_devices_t audioOutputDevice = getDeviceForStrategy(getStrategy(AUDIO_STREAM_MUSIC), true);
+ mDolbyAudioPolicy.setEndpointSystemProperty(audioOutputDevice, mHwModules);
+#endif // DOLBY_END
if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
updateCallRouting(newDevice);
@@ -410,6 +436,13 @@
return false;
}
+ // Check if offload has been disabled
+ bool offloadDisabled = property_get_bool("audio.offload.disable", false);
+ if (offloadDisabled) {
+ ALOGI("offload disabled by audio.offload.disable=%d", offloadDisabled);
+ return false;
+ }
+
char propValue[PROPERTY_VALUE_MAX];
bool pcmOffload = false;
#ifdef PCM_OFFLOAD_ENABLED
@@ -439,13 +472,13 @@
}
#endif
if (!pcmOffload) {
- // Check if offload has been disabled
- if (property_get("audio.offload.disable", propValue, "0")) {
- if (atoi(propValue) != 0) {
- ALOGV("offload disabled by audio.offload.disable=%s", propValue );
- return false;
- }
+
+ bool compressedOffloadDisabled = property_get_bool("audio.offload.compress.disable", false);
+ if (compressedOffloadDisabled) {
+ ALOGI("compressed offload disabled by audio.offload.compress.disable=%d", compressedOffloadDisabled);
+ return false;
}
+
//check if it's multi-channel AAC (includes sub formats) and FLAC format
if ((popcount(offloadInfo.channel_mask) > 2) &&
(((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AAC) ||
@@ -617,7 +650,7 @@
/// Opens: can these line be executed after the switch of volume curves???
// if leaving call state, handle special case of active streams
// pertaining to sonification strategy see handleIncallSonification()
- if (isStateInCall(oldState)) {
+ if (isInCall()) {
ALOGV("setPhoneState() in call state management: new state is %d", state);
for (size_t j = 0; j < mOutputs.size(); j++) {
audio_io_handle_t curOutput = mOutputs.keyAt(j);
@@ -1281,7 +1314,17 @@
{
audio_offload_info_t tOffloadInfo = AUDIO_INFO_INITIALIZER;
- bool pcmOffloadEnabled = property_get_bool("audio.offload.track.enable", false);
+ bool offloadDisabled = property_get_bool("audio.offload.disable", false);
+ bool pcmOffloadEnabled = false;
+
+ if (offloadDisabled) {
+ ALOGI("offload disabled by audio.offload.disable=%d", offloadDisabled);
+ }
+
+ //read track offload property only if the global offload switch is off.
+ if (!offloadDisabled) {
+ pcmOffloadEnabled = property_get_bool("audio.offload.track.enable", false);
+ }
if (offloadInfo == NULL && pcmOffloadEnabled) {
tOffloadInfo.sample_rate = samplingRate;
@@ -1293,7 +1336,7 @@
ALOGV("found attribute .. setting usage %d ", attr->usage);
tOffloadInfo.usage = attr->usage;
} else {
- ALOGD("%s:: attribute is NULL .. no usage set", __func__);
+ ALOGI("%s:: attribute is NULL .. no usage set", __func__);
}
offloadInfo = &tOffloadInfo;
}
@@ -1404,8 +1447,8 @@
property_get("use.voice.path.for.pcm.voip", propValue, "0");
bool voipPcmSysPropEnabled = !strncmp("true", propValue, sizeof("true"));
if (voipPcmSysPropEnabled && (format == AUDIO_FORMAT_PCM_16_BIT)) {
- flags = (audio_output_flags_t)((flags &~AUDIO_OUTPUT_FLAG_FAST) |
- AUDIO_OUTPUT_FLAG_VOIP_RX | AUDIO_OUTPUT_FLAG_DIRECT);
+ flags = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_VOIP_RX |
+ AUDIO_OUTPUT_FLAG_DIRECT);
ALOGD("Set VoIP and Direct output flags for PCM format");
}
}
@@ -1543,6 +1586,7 @@
flags = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
forced_deep = true;
}
+
if (stream == AUDIO_STREAM_TTS) {
flags = AUDIO_OUTPUT_FLAG_TTS;
}
@@ -1551,7 +1595,7 @@
if (((flags == AUDIO_OUTPUT_FLAG_NONE) || forced_deep) &&
(stream == AUDIO_STREAM_MUSIC) && (offloadInfo != NULL) &&
((offloadInfo->usage == AUDIO_USAGE_MEDIA) || (offloadInfo->usage == AUDIO_USAGE_GAME))) {
- flags = (audio_output_flags_t)(flags|AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_DIRECT_PCM);
+ flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
ALOGD("AudioCustomHAL --> Force Direct Flag .. flag (0x%x)", flags);
}
@@ -1584,23 +1628,29 @@
if (profile != 0) {
sp<SwAudioOutputDescriptor> outputDesc = NULL;
- for (size_t i = 0; i < mOutputs.size(); i++) {
- sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
- if (!desc->isDuplicated() && (profile == desc->mProfile)) {
- outputDesc = desc;
- // reuse direct output if currently open and configured with same parameters
- if ((samplingRate == outputDesc->mSamplingRate) &&
- (format == outputDesc->mFormat) &&
- (channelMask == outputDesc->mChannelMask)) {
- outputDesc->mDirectOpenCount++;
- ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
- return mOutputs.keyAt(i);
+ // if multiple concurrent offload decode is supported
+ // do no check for reuse and also don't close previous output if its offload
+ // previous output will be closed during track destruction
+ if (!(property_get_bool("audio.offload.multiple.enabled", false) &&
+ ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0))) {
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ if (!desc->isDuplicated() && (profile == desc->mProfile)) {
+ outputDesc = desc;
+ // reuse direct output if currently open and configured with same parameters
+ if ((samplingRate == outputDesc->mSamplingRate) &&
+ (format == outputDesc->mFormat) &&
+ (channelMask == outputDesc->mChannelMask)) {
+ outputDesc->mDirectOpenCount++;
+ ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
+ return mOutputs.keyAt(i);
+ }
}
}
- }
- // close direct output if currently open and configured with different parameters
- if (outputDesc != NULL) {
- closeOutput(outputDesc->mIoHandle);
+ // close direct output if currently open and configured with different parameters
+ if (outputDesc != NULL) {
+ closeOutput(outputDesc->mIoHandle);
+ }
}
// if the selected profile is offloaded and no offload info was specified,
@@ -1667,7 +1717,23 @@
addOutput(output, outputDesc);
audio_io_handle_t dstOutput = getOutputForEffect();
if (dstOutput == output) {
+#ifdef DOLBY_ENABLE
+ status_t status = mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput);
+ if (status == NO_ERROR) {
+ for (size_t i = 0; i < mEffects.size(); i++) {
+ sp<EffectDescriptor> desc = mEffects.valueAt(i);
+ if (desc->mSession == AUDIO_SESSION_OUTPUT_MIX) {
+ // update the mIo member of EffectDescriptor for the global effect
+ ALOGV("%s updating mIo", __FUNCTION__);
+ desc->mIo = dstOutput;
+ }
+ }
+ } else {
+ ALOGW("%s moveEffects from %d to %d failed", __FUNCTION__, srcOutput, dstOutput);
+ }
+#else // DOLBY_END
mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput);
+#endif // LINE_ADDED_BY_DOLBY
}
mPreviousOutputs = mOutputs;
ALOGV("getOutput() returns new direct output %d", output);
@@ -1971,31 +2037,31 @@
mHdmiAudioEvent(false),
mPrevPhoneState(0)
{
+ char ssr_enabled[PROPERTY_VALUE_MAX] = {0};
+ bool prop_ssr_enabled = false;
+
+ if (property_get("ro.qc.sdk.audio.ssr", ssr_enabled, NULL)) {
+ prop_ssr_enabled = atoi(ssr_enabled) || !strncmp("true", ssr_enabled, 4);
+ }
for (size_t i = 0; i < mHwModules.size(); i++) {
ALOGV("Hw module %d", i);
for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) {
const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j];
- ALOGV("\t Input profile ", j);
+ ALOGV("Input profile ", j);
for (size_t k = 0; k < inProfile->mChannelMasks.size(); k++) {
audio_channel_mask_t channelMask =
inProfile->mChannelMasks.itemAt(k);
- ALOGV("\t\tChannel Mask %x size %d", channelMask,
+ ALOGV("Channel Mask %x size %d", channelMask,
inProfile->mChannelMasks.size());
if (AUDIO_CHANNEL_IN_5POINT1 == channelMask) {
- char ssr_enabled[PROPERTY_VALUE_MAX]={0};
- if ((property_get("ro.qc.sdk.audio.ssr",
- ssr_enabled, NULL) > 0) &&
- (!strncmp("true", ssr_enabled, 4))) {
- ALOGV("\t\t SSR supported, retain 5.1 channel"
- " in input profile");
- } else {
- ALOGE("\t\t removing AUDIO_CHANNEL_IN_5POINT1 from"
- " input profile as SSR(surround sound record)"
- " is not supported on this chipset variant");
- inProfile->mChannelMasks.removeItemsAt(k, 1);
- ALOGV("\t\t Channel Mask size now %d",
- inProfile->mChannelMasks.size());
+ if (!prop_ssr_enabled) {
+ ALOGI("removing AUDIO_CHANNEL_IN_5POINT1 from"
+ " input profile as SSR(surround sound record)"
+ " is not supported on this chipset variant");
+ inProfile->mChannelMasks.removeItemsAt(k, 1);
+ ALOGV("Channel Mask size now %d",
+ inProfile->mChannelMasks.size());
}
}
}
diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h
index 437e3b9..55d59ac 100644
--- a/policy_hal/AudioPolicyManager.h
+++ b/policy_hal/AudioPolicyManager.h
@@ -75,6 +75,7 @@
// indicates to the audio policy manager that the input stops being used.
virtual status_t stopInput(audio_io_handle_t input,
audio_session_t session);
+
virtual void closeAllInputs();
protected:
diff --git a/post_proc/Android.mk b/post_proc/Android.mk
index 3b9787c..28445f3 100644
--- a/post_proc/Android.mk
+++ b/post_proc/Android.mk
@@ -77,3 +77,32 @@
include $(BUILD_STATIC_LIBRARY)
endif
+
+
+################################################################################
+
+ifneq ($(filter msm8992 msm8994 msm8996 msm8952 msm8937 thorium,$(TARGET_BOARD_PLATFORM)),)
+
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS := -DLIB_AUDIO_HAL="/system/lib/hw/audio.primary."$(TARGET_BOARD_PLATFORM)".so"
+
+LOCAL_SRC_FILES:= \
+ volume_listener.c
+
+LOCAL_CFLAGS+= -O2 -fvisibility=hidden
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+ liblog \
+ libdl
+
+LOCAL_MODULE_RELATIVE_PATH := soundfx
+LOCAL_MODULE:= libvolumelistener
+
+LOCAL_C_INCLUDES := \
+ $(call include-path-for, audio-effects)
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif
diff --git a/post_proc/bundle.c b/post_proc/bundle.c
index 8df93cb..2bc7fad 100644
--- a/post_proc/bundle.c
+++ b/post_proc/bundle.c
@@ -38,12 +38,13 @@
#define LOG_TAG "offload_effect_bundle"
//#define LOG_NDEBUG 0
+#include <stdlib.h>
#include <cutils/list.h>
#include <cutils/log.h>
#include <system/thread_defs.h>
#include <tinyalsa/asoundlib.h>
#include <hardware/audio_effect.h>
-#include <stdlib.h>
+
#include "bundle.h"
#include "hw_accelerator.h"
#include "equalizer.h"
diff --git a/post_proc/effect_api.c b/post_proc/effect_api.c
index 7aef997..ab8576f 100644
--- a/post_proc/effect_api.c
+++ b/post_proc/effect_api.c
@@ -55,6 +55,7 @@
#endif
#include <stdbool.h>
+#include <errno.h>
#include <cutils/log.h>
#include <tinyalsa/asoundlib.h>
#include <sound/audio_effects.h>
diff --git a/post_proc/effect_util.c b/post_proc/effect_util.c
index b401f6a..02911c1 100644
--- a/post_proc/effect_util.c
+++ b/post_proc/effect_util.c
@@ -16,6 +16,7 @@
#include <utils/Log.h>
#include <stdlib.h>
+#include <string.h>
#include "effect_util.h"
#include <string.h>
diff --git a/post_proc/reverb.c b/post_proc/reverb.c
index 450ce81..2e97f68 100644
--- a/post_proc/reverb.c
+++ b/post_proc/reverb.c
@@ -230,6 +230,72 @@
OFFLOAD_SEND_REVERB_LEVEL);
}
+uint32_t reverb_get_reverb_delay(reverb_context_t *context)
+{
+ ALOGV("%s: ctxt %p, reverb delay: %d", __func__, context,
+ context->reverb_settings.reverbDelay);
+ return context->reverb_settings.reverbDelay;
+}
+
+void reverb_set_reverb_delay(reverb_context_t *context, uint32_t delay)
+{
+ ALOGV("%s: ctxt %p, reverb delay: %d", __func__, context, delay);
+ context->reverb_settings.reverbDelay = delay;
+ offload_reverb_set_delay(&(context->offload_reverb), delay);
+ if (context->ctl)
+ offload_reverb_send_params(context->ctl, &context->offload_reverb,
+ OFFLOAD_SEND_REVERB_ENABLE_FLAG |
+ OFFLOAD_SEND_REVERB_DELAY);
+ if (context->hw_acc_fd > 0)
+ hw_acc_reverb_send_params(context->hw_acc_fd, &context->offload_reverb,
+ OFFLOAD_SEND_REVERB_ENABLE_FLAG |
+ OFFLOAD_SEND_REVERB_DELAY);
+}
+
+int16_t reverb_get_reflections_level(reverb_context_t *context)
+{
+ ALOGV("%s: ctxt %p, reflection level: %d", __func__, context,
+ context->reverb_settings.reflectionsLevel);
+ return context->reverb_settings.reflectionsLevel;
+}
+
+void reverb_set_reflections_level(reverb_context_t *context, int16_t level)
+{
+ ALOGV("%s: ctxt %p, reflection level: %d", __func__, context, level);
+ context->reverb_settings.reflectionsLevel = level;
+ offload_reverb_set_reflections_level(&(context->offload_reverb), level);
+ if (context->ctl)
+ offload_reverb_send_params(context->ctl, &context->offload_reverb,
+ OFFLOAD_SEND_REVERB_ENABLE_FLAG |
+ OFFLOAD_SEND_REVERB_REFLECTIONS_LEVEL);
+ if (context->hw_acc_fd > 0)
+ hw_acc_reverb_send_params(context->hw_acc_fd, &context->offload_reverb,
+ OFFLOAD_SEND_REVERB_ENABLE_FLAG |
+ OFFLOAD_SEND_REVERB_REFLECTIONS_LEVEL);
+}
+
+uint32_t reverb_get_reflections_delay(reverb_context_t *context)
+{
+ ALOGV("%s: ctxt %p, reflection delay: %d", __func__, context,
+ context->reverb_settings.reflectionsDelay);
+ return context->reverb_settings.reflectionsDelay;
+}
+
+void reverb_set_reflections_delay(reverb_context_t *context, uint32_t delay)
+{
+ ALOGV("%s: ctxt %p, reflection delay: %d", __func__, context, delay);
+ context->reverb_settings.reflectionsDelay = delay;
+ offload_reverb_set_reflections_delay(&(context->offload_reverb), delay);
+ if (context->ctl)
+ offload_reverb_send_params(context->ctl, &context->offload_reverb,
+ OFFLOAD_SEND_REVERB_ENABLE_FLAG |
+ OFFLOAD_SEND_REVERB_REFLECTIONS_DELAY);
+ if (context->hw_acc_fd > 0)
+ hw_acc_reverb_send_params(context->hw_acc_fd, &context->offload_reverb,
+ OFFLOAD_SEND_REVERB_ENABLE_FLAG |
+ OFFLOAD_SEND_REVERB_REFLECTIONS_DELAY);
+}
+
int16_t reverb_get_diffusion(reverb_context_t *context)
{
ALOGV("%s: ctxt %p, diffusion: %d", __func__, context,
@@ -305,8 +371,33 @@
context->reverb_settings.decayTime = reverb_settings->decayTime;
context->reverb_settings.decayHFRatio = reverb_settings->decayHFRatio;
context->reverb_settings.reverbLevel = reverb_settings->reverbLevel;
+ context->reverb_settings.reverbDelay = reverb_settings->reverbDelay;
+ context->reverb_settings.reflectionsLevel = reverb_settings->reflectionsLevel;
+ context->reverb_settings.reflectionsDelay = reverb_settings->reflectionsDelay;
context->reverb_settings.diffusion = reverb_settings->diffusion;
context->reverb_settings.density = reverb_settings->density;
+
+ offload_reverb_set_room_level(&(context->offload_reverb),
+ reverb_settings->roomLevel);
+ offload_reverb_set_room_hf_level(&(context->offload_reverb),
+ reverb_settings->roomHFLevel);
+ offload_reverb_set_decay_time(&(context->offload_reverb),
+ reverb_settings->decayTime);
+ offload_reverb_set_decay_hf_ratio(&(context->offload_reverb),
+ reverb_settings->decayHFRatio);
+ offload_reverb_set_reverb_level(&(context->offload_reverb),
+ reverb_settings->reverbLevel);
+ offload_reverb_set_delay(&(context->offload_reverb),
+ reverb_settings->reverbDelay);
+ offload_reverb_set_reflections_level(&(context->offload_reverb),
+ reverb_settings->reflectionsLevel);
+ offload_reverb_set_reflections_delay(&(context->offload_reverb),
+ reverb_settings->reflectionsDelay);
+ offload_reverb_set_diffusion(&(context->offload_reverb),
+ reverb_settings->diffusion);
+ offload_reverb_set_density(&(context->offload_reverb),
+ reverb_settings->density);
+
if (context->ctl)
offload_reverb_send_params(context->ctl, &context->offload_reverb,
OFFLOAD_SEND_REVERB_ENABLE_FLAG |
@@ -315,6 +406,9 @@
OFFLOAD_SEND_REVERB_DECAY_TIME |
OFFLOAD_SEND_REVERB_DECAY_HF_RATIO |
OFFLOAD_SEND_REVERB_LEVEL |
+ OFFLOAD_SEND_REVERB_DELAY |
+ OFFLOAD_SEND_REVERB_REFLECTIONS_LEVEL |
+ OFFLOAD_SEND_REVERB_REFLECTIONS_DELAY |
OFFLOAD_SEND_REVERB_DIFFUSION |
OFFLOAD_SEND_REVERB_DENSITY);
if (context->hw_acc_fd > 0)
@@ -325,6 +419,9 @@
OFFLOAD_SEND_REVERB_DECAY_TIME |
OFFLOAD_SEND_REVERB_DECAY_HF_RATIO |
OFFLOAD_SEND_REVERB_LEVEL |
+ OFFLOAD_SEND_REVERB_DELAY |
+ OFFLOAD_SEND_REVERB_REFLECTIONS_LEVEL |
+ OFFLOAD_SEND_REVERB_REFLECTIONS_DELAY |
OFFLOAD_SEND_REVERB_DIFFUSION |
OFFLOAD_SEND_REVERB_DENSITY);
}
@@ -388,16 +485,6 @@
p->status = -EINVAL;
p->vsize = sizeof(uint16_t);
break;
- case REVERB_PARAM_REFLECTIONS_LEVEL:
- if (p->vsize < sizeof(uint16_t))
- p->status = -EINVAL;
- p->vsize = sizeof(uint16_t);
- break;
- case REVERB_PARAM_REFLECTIONS_DELAY:
- if (p->vsize < sizeof(uint32_t))
- p->status = -EINVAL;
- p->vsize = sizeof(uint32_t);
- break;
case REVERB_PARAM_REVERB_LEVEL:
if (p->vsize < sizeof(uint16_t))
p->status = -EINVAL;
@@ -408,6 +495,16 @@
p->status = -EINVAL;
p->vsize = sizeof(uint32_t);
break;
+ case REVERB_PARAM_REFLECTIONS_LEVEL:
+ if (p->vsize < sizeof(uint16_t))
+ p->status = -EINVAL;
+ p->vsize = sizeof(uint16_t);
+ break;
+ case REVERB_PARAM_REFLECTIONS_DELAY:
+ if (p->vsize < sizeof(uint32_t))
+ p->status = -EINVAL;
+ p->vsize = sizeof(uint32_t);
+ break;
case REVERB_PARAM_DIFFUSION:
if (p->vsize < sizeof(uint16_t))
p->status = -EINVAL;
@@ -433,19 +530,6 @@
return 0;
switch (param) {
- case REVERB_PARAM_PROPERTIES:
- reverb_settings = (reverb_settings_t *)value;
- reverb_settings->roomLevel = reverb_get_room_level(reverb_ctxt);
- reverb_settings->roomHFLevel = reverb_get_room_hf_level(reverb_ctxt);
- reverb_settings->decayTime = reverb_get_decay_time(reverb_ctxt);
- reverb_settings->decayHFRatio = reverb_get_decay_hf_ratio(reverb_ctxt);
- reverb_settings->reflectionsLevel = 0;
- reverb_settings->reflectionsDelay = 0;
- reverb_settings->reverbDelay = 0;
- reverb_settings->reverbLevel = reverb_get_reverb_level(reverb_ctxt);
- reverb_settings->diffusion = reverb_get_diffusion(reverb_ctxt);
- reverb_settings->density = reverb_get_density(reverb_ctxt);
- break;
case REVERB_PARAM_ROOM_LEVEL:
*(int16_t *)value = reverb_get_room_level(reverb_ctxt);
break;
@@ -461,20 +545,33 @@
case REVERB_PARAM_REVERB_LEVEL:
*(int16_t *)value = reverb_get_reverb_level(reverb_ctxt);
break;
+ case REVERB_PARAM_REVERB_DELAY:
+ *(uint32_t *)value = reverb_get_reverb_delay(reverb_ctxt);
+ break;
+ case REVERB_PARAM_REFLECTIONS_LEVEL:
+ *(int16_t *)value = reverb_get_reflections_level(reverb_ctxt);
+ break;
+ case REVERB_PARAM_REFLECTIONS_DELAY:
+ *(uint32_t *)value = reverb_get_reflections_delay(reverb_ctxt);
+ break;
case REVERB_PARAM_DIFFUSION:
*(int16_t *)value = reverb_get_diffusion(reverb_ctxt);
break;
case REVERB_PARAM_DENSITY:
*(int16_t *)value = reverb_get_density(reverb_ctxt);
break;
- case REVERB_PARAM_REFLECTIONS_LEVEL:
- *(uint16_t *)value = 0;
- break;
- case REVERB_PARAM_REFLECTIONS_DELAY:
- *(uint32_t *)value = 0;
- break;
- case REVERB_PARAM_REVERB_DELAY:
- *(uint32_t *)value = 0;
+ case REVERB_PARAM_PROPERTIES:
+ reverb_settings = (reverb_settings_t *)value;
+ reverb_settings->roomLevel = reverb_get_room_level(reverb_ctxt);
+ reverb_settings->roomHFLevel = reverb_get_room_hf_level(reverb_ctxt);
+ reverb_settings->decayTime = reverb_get_decay_time(reverb_ctxt);
+ reverb_settings->decayHFRatio = reverb_get_decay_hf_ratio(reverb_ctxt);
+ reverb_settings->reverbLevel = reverb_get_reverb_level(reverb_ctxt);
+ reverb_settings->reverbDelay = reverb_get_reverb_delay(reverb_ctxt);
+ reverb_settings->reflectionsLevel = reverb_get_reflections_level(reverb_ctxt);
+ reverb_settings->reflectionsDelay = reverb_get_reflections_delay(reverb_ctxt);
+ reverb_settings->diffusion = reverb_get_diffusion(reverb_ctxt);
+ reverb_settings->density = reverb_get_density(reverb_ctxt);
break;
default:
p->status = -EINVAL;
@@ -496,6 +593,7 @@
int16_t level;
int16_t ratio;
uint32_t time;
+ uint32_t delay;
ALOGV("%s: ctxt %p, param %d", __func__, reverb_ctxt, param);
@@ -515,6 +613,7 @@
switch (param) {
case REVERB_PARAM_PROPERTIES:
reverb_settings = (reverb_settings_t *)value;
+ reverb_set_all_properties(reverb_ctxt, reverb_settings);
break;
case REVERB_PARAM_ROOM_LEVEL:
level = *(int16_t *)value;
@@ -536,6 +635,18 @@
level = *(int16_t *)value;
reverb_set_reverb_level(reverb_ctxt, level);
break;
+ case REVERB_PARAM_REVERB_DELAY:
+ delay = *(uint32_t *)value;
+ reverb_set_reverb_delay(reverb_ctxt, delay);
+ break;
+ case REVERB_PARAM_REFLECTIONS_LEVEL:
+ level = *(int16_t *)value;
+ reverb_set_reflections_level(reverb_ctxt, level);
+ break;
+ case REVERB_PARAM_REFLECTIONS_DELAY:
+ delay = *(uint32_t *)value;
+ reverb_set_reflections_delay(reverb_ctxt, delay);
+ break;
case REVERB_PARAM_DIFFUSION:
ratio = *(int16_t *)value;
reverb_set_diffusion(reverb_ctxt, ratio);
@@ -544,10 +655,6 @@
ratio = *(int16_t *)value;
reverb_set_density(reverb_ctxt, ratio);
break;
- case REVERB_PARAM_REFLECTIONS_LEVEL:
- case REVERB_PARAM_REFLECTIONS_DELAY:
- case REVERB_PARAM_REVERB_DELAY:
- break;
default:
p->status = -EINVAL;
break;
diff --git a/post_proc/reverb.h b/post_proc/reverb.h
index 1a5ca0d..3bdd9af 100644
--- a/post_proc/reverb.h
+++ b/post_proc/reverb.h
@@ -40,7 +40,7 @@
uint32_t reverbDelay;
int16_t diffusion;
int16_t density;
-} reverb_settings_t;
+} __attribute__((packed)) reverb_settings_t;
typedef struct reverb_context_s {
effect_context_t common;
diff --git a/post_proc/volume_listener.c b/post_proc/volume_listener.c
new file mode 100644
index 0000000..e1dd026
--- /dev/null
+++ b/post_proc/volume_listener.c
@@ -0,0 +1,795 @@
+/*
+ * Copyright (c) 2015, 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
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * 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 "volume_listener"
+//#define LOG_NDEBUG 0
+#include <stdlib.h>
+#include <dlfcn.h>
+
+#include <cutils/list.h>
+#include <cutils/log.h>
+#include <hardware/audio_effect.h>
+#include <cutils/properties.h>
+
+#define PRIMARY_HAL_PATH XSTR(LIB_AUDIO_HAL)
+#define XSTR(x) STR(x)
+#define STR(x) #x
+
+#define VOL_FLAG ( EFFECT_FLAG_TYPE_INSERT | \
+ EFFECT_FLAG_VOLUME_IND | \
+ EFFECT_FLAG_DEVICE_IND | \
+ EFFECT_FLAG_OFFLOAD_SUPPORTED)
+
+#define PRINT_STREAM_TYPE(i) ALOGV("descriptor found and is of stream type %s ",\
+ i == MUSIC?"MUSIC": \
+ i == RING?"RING": \
+ i == ALARM?"ALARM": \
+ i == VOICE_CALL?"Voice_call": \
+ i == NOTIFICATION?"Notification":\
+ "--INVALID--"); \
+
+#define MAX_GAIN_LEVELS 5
+
+#define AHAL_GAIN_DEPENDENT_INTERFACE_FUNCTION "audio_hw_send_gain_dep_calibration"
+
+enum {
+ VOL_LISTENER_STATE_UNINITIALIZED,
+ VOL_LISTENER_STATE_INITIALIZED,
+ VOL_LISTENER_STATE_ACTIVE,
+};
+
+typedef struct vol_listener_context_s vol_listener_context_t;
+static const struct effect_interface_s effect_interface;
+
+/* flag to avoid multiple initialization */
+static bool initialized = false;
+
+/* current gain dep cal level that was pushed succesfully */
+static int current_gain_dep_cal_level = -1;
+
+enum STREAM_TYPE {
+ MUSIC,
+ RING,
+ ALARM,
+ VOICE_CALL,
+ NOTIFICATION,
+ MAX_STREAM_TYPES,
+};
+
+struct vol_listener_context_s {
+ const struct effect_interface_s *itfe;
+ struct listnode effect_list_node;
+ effect_config_t config;
+ const effect_descriptor_t *desc;
+ uint32_t stream_type;
+ uint32_t session_id;
+ uint32_t state;
+ uint32_t dev_id;
+ float left_vol;
+ float right_vol;
+};
+
+/* volume listener, music UUID: 08b8b058-0590-11e5-ac71-0025b32654a0 */
+const effect_descriptor_t vol_listener_music_descriptor = {
+ { 0x08b8b058, 0x0590, 0x11e5, 0xac71, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } }, // type
+ { 0x08b8b058, 0x0590, 0x11e5, 0xac71, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } }, // uuid
+ EFFECT_CONTROL_API_VERSION,
+ VOL_FLAG,
+ 0, /* TODO */
+ 1,
+ "Volume listener for Music",
+ "Qualcomm Technologies Inc.",
+};
+
+/* volume listener, ring UUID: 0956df94-0590-11e5-bdbe-0025b32654a0 */
+const effect_descriptor_t vol_listener_ring_descriptor = {
+ { 0x0956df94, 0x0590, 0x11e5, 0xbdbe, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } }, // type
+ { 0x0956df94, 0x0590, 0x11e5, 0xbdbe, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } }, // uuid
+ EFFECT_CONTROL_API_VERSION,
+ VOL_FLAG,
+ 0, /* TODO */
+ 1,
+ "Volume listener for ring",
+ "Qualcomm Technologies Inc",
+};
+
+/* volume listener, alarm UUID: 09f303e2-0590-11e5-8fdb-0025b32654a0 */
+const effect_descriptor_t vol_listener_alarm_descriptor = {
+ { 0x09f303e2, 0x0590, 0x11e5, 0x8fdb, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } }, // type
+ { 0x09f303e2, 0x0590, 0x11e5, 0x8fdb, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } }, // uuid
+ EFFECT_CONTROL_API_VERSION,
+ VOL_FLAG,
+ 0, /* TODO */
+ 1,
+ "Volume listener for alarm",
+ "Qualcomm Technologies Inc",
+};
+
+/* volume listener, voice call UUID: 0ace5c08-0590-11e5-ae9e-0025b32654a0 */
+const effect_descriptor_t vol_listener_voice_call_descriptor = {
+ { 0x0ace5c08, 0x0590, 0x11e5, 0xae9e, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } }, // type
+ { 0x0ace5c08, 0x0590, 0x11e5, 0xae9e, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } }, // uuid
+ EFFECT_CONTROL_API_VERSION,
+ VOL_FLAG,
+ 0, /* TODO */
+ 1,
+ "Volume listener for voice call",
+ "Qualcomm Technologies Inc",
+};
+
+/* volume listener, notification UUID: 0b776dde-0590-11e5-81ba-0025b32654a0 */
+const effect_descriptor_t vol_listener_notification_descriptor = {
+ { 0x0b776dde, 0x0590, 0x11e5, 0x81ba, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } }, // type
+ { 0x0b776dde, 0x0590, 0x11e5, 0x81ba, { 0x00, 0x25, 0xb3, 0x26, 0x54, 0xa0 } }, // uuid
+ EFFECT_CONTROL_API_VERSION,
+ VOL_FLAG,
+ 0, /* TODO */
+ 1,
+ "Volume listener for notification",
+ "Qualcomm Technologies Inc",
+};
+
+struct amp_db_and_gain_table {
+ float amp;
+ float db;
+ uint32_t level;
+} amp_to_dBLevel_table;
+
+// using gain level for non-drc volume curve
+static const struct amp_db_and_gain_table volume_curve_gain_mapping_table[MAX_GAIN_LEVELS] = {
+ /* Level 0 in the calibration database contains default calibration */
+ { 0.001774, -55, 5 },
+ { 0.501187, -6, 4 },
+ { 0.630957, -4, 3 },
+ { 0.794328, -2, 2 },
+ { 1.0, 0, 1 },
+};
+
+static const effect_descriptor_t *descriptors[] = {
+ &vol_listener_music_descriptor,
+ &vol_listener_ring_descriptor,
+ &vol_listener_alarm_descriptor,
+ &vol_listener_voice_call_descriptor,
+ &vol_listener_notification_descriptor,
+ NULL,
+};
+
+pthread_once_t once = PTHREAD_ONCE_INIT;
+/* flag to indicate if init was success */
+static int init_status;
+
+/* current volume level for which gain dep cal level was selected */
+static float current_vol = 0.0;
+
+/* HAL interface to send calibration */
+static bool (*send_gain_dep_cal)(int);
+
+/* if dumping allowed */
+static bool dumping_enabled = false;
+
+/* list of created effects. */
+struct listnode vol_effect_list;
+
+/* lock must be held when modifying or accessing created_effects_list */
+pthread_mutex_t vol_listner_init_lock;
+
+/*
+ * Local functions
+ */
+static void dump_list_l()
+{
+ struct listnode *node;
+ vol_listener_context_t *context;
+
+ ALOGW("DUMP_START :: ===========");
+
+ list_for_each(node, &vol_effect_list) {
+ context = node_to_item(node, struct vol_listener_context_s, effect_list_node);
+ // dump stream_type / Device / session_id / left / righ volume
+ ALOGW("%s: streamType [%s] Device [%d] state [%d] sessionID [%d] volume (L/R) [%f / %f] ",
+ __func__,
+ context->stream_type == MUSIC ? "MUSIC" :
+ context->stream_type == RING ? "RING" :
+ context->stream_type == ALARM ? "ALARM" :
+ context->stream_type == VOICE_CALL ? "VOICE_CALL" :
+ context->stream_type == NOTIFICATION ? "NOTIFICATION" : "--INVALID--",
+ context->dev_id, context->state, context->session_id, context->left_vol,context->right_vol);
+ }
+
+ ALOGW("DUMP_END :: ===========");
+}
+
+static void check_and_set_gain_dep_cal()
+{
+ // 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
+ // 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;
+ int max_level = 0;
+ vol_listener_context_t *context = NULL;
+ if (dumping_enabled) {
+ dump_list_l();
+ }
+
+ ALOGV("%s ==> Start ...", __func__);
+
+ // select the highest volume on speaker device
+ 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) &&
+ (context->dev_id & AUDIO_DEVICE_OUT_SPEAKER) &&
+ (new_vol < (context->left_vol + context->right_vol) / 2)) {
+ new_vol = (context->left_vol + context->right_vol) / 2;
+ }
+ }
+
+ if (new_vol != current_vol) {
+ ALOGV("%s:: Change in decision :: current volume is %f new volume is %f",
+ __func__, current_vol, new_vol);
+
+ if (send_gain_dep_cal != NULL) {
+ // send Gain dep cal level
+ int gain_dep_cal_level = -1;
+
+ if (new_vol >= 1) { // max amplitude, use highest DRC level
+ gain_dep_cal_level = volume_curve_gain_mapping_table[MAX_GAIN_LEVELS - 1].level;
+ } else if (new_vol <= 0) {
+ gain_dep_cal_level = volume_curve_gain_mapping_table[0].level;
+ } else {
+ for (max_level = 0; max_level + 1 < MAX_GAIN_LEVELS; max_level++) {
+ if (new_vol < volume_curve_gain_mapping_table[max_level + 1].amp &&
+ new_vol >= volume_curve_gain_mapping_table[max_level].amp) {
+ gain_dep_cal_level = volume_curve_gain_mapping_table[max_level].level;
+ ALOGV("%s: volume(%f), gain dep cal selcetd %d ",
+ __func__, current_vol, gain_dep_cal_level);
+ break;
+ }
+ }
+ }
+
+ // check here if previous gain dep cal level was not same
+ if (gain_dep_cal_level != -1) {
+ if (gain_dep_cal_level != current_gain_dep_cal_level) {
+ // decision made .. send new level now
+ if (!send_gain_dep_cal(gain_dep_cal_level)) {
+ ALOGE("%s: Failed to set gain dep cal level", __func__);
+ } else {
+ // Success in setting the gain dep cal level, store new level and Volume
+ if (dumping_enabled) {
+ ALOGW("%s: (old/new) Volume (%f/%f) (old/new) level (%d/%d)",
+ __func__, current_vol, new_vol, current_gain_dep_cal_level,
+ gain_dep_cal_level);
+ } else {
+ ALOGV("%s: Change in Cal::(old/new) Volume (%f/%f) (old/new) level (%d/%d)",
+ __func__, current_vol, new_vol, current_gain_dep_cal_level,
+ gain_dep_cal_level);
+ }
+ current_gain_dep_cal_level = gain_dep_cal_level;
+ current_vol = new_vol;
+ }
+ } else {
+ if (dumping_enabled) {
+ ALOGW("%s: volume changed but gain dep cal level is still the same",
+ __func__);
+ } else {
+ ALOGV("%s: volume changed but gain dep cal level is still the same",
+ __func__);
+ }
+ }
+ } else {
+ ALOGW("%s: Failed to find gain dep cal level for volume %f", __func__, new_vol);
+ }
+ } else {
+ ALOGE("%s: not able to send calibration, NULL function pointer",
+ __func__);
+ }
+ } else {
+ ALOGV("%s:: volume not changed, stick to same config ..... ", __func__);
+ }
+
+ ALOGV("check_and_set_gain_dep_cal ==> End ");
+}
+
+/*
+ * Effect Control Interface Implementation
+ */
+
+static inline int16_t clamp16(int32_t sample)
+{
+ if ((sample>>15) ^ (sample>>31))
+ sample = 0x7FFF ^ (sample>>31);
+ return sample;
+}
+
+static int vol_effect_process(effect_handle_t self,
+ audio_buffer_t *in_buffer,
+ audio_buffer_t *out_buffer)
+{
+ int status = 0;
+ ALOGV("%s Called ", __func__);
+
+ vol_listener_context_t *context = (vol_listener_context_t *)self;
+ pthread_mutex_lock(&vol_listner_init_lock);
+
+ if (context->state != VOL_LISTENER_STATE_ACTIVE) {
+ ALOGE("%s: state is not active .. return error", __func__);
+ status = -EINVAL;
+ goto exit;
+ }
+
+ // calculation based on channel count 2
+ if (in_buffer->raw != out_buffer->raw) {
+ if (context->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
+ size_t i;
+ for (i = 0; i < out_buffer->frameCount*2; i++) {
+ out_buffer->s16[i] = clamp16(out_buffer->s16[i] + in_buffer->s16[i]);
+ }
+ } else {
+ memcpy(out_buffer->raw, in_buffer->raw, out_buffer->frameCount * 2 * sizeof(int16_t));
+ }
+ } else {
+ ALOGV("%s: something wrong, didn't handle in_buffer and out_buffer same address case",
+ __func__);
+ }
+
+exit:
+ pthread_mutex_unlock(&vol_listner_init_lock);
+ return status;
+}
+
+
+static int vol_effect_command(effect_handle_t self,
+ uint32_t cmd_code, uint32_t cmd_size,
+ void *p_cmd_data, uint32_t *reply_size,
+ void *p_reply_data)
+{
+ vol_listener_context_t *context = (vol_listener_context_t *)self;
+ int status = 0;
+
+ ALOGV("%s Called ", __func__);
+ pthread_mutex_lock(&vol_listner_init_lock);
+
+ if (context == NULL || context->state == VOL_LISTENER_STATE_UNINITIALIZED) {
+ ALOGE("%s: %s is NULL", __func__, (context == NULL) ?
+ "context" : "context->state");
+ status = -EINVAL;
+ goto exit;
+ }
+
+ switch (cmd_code) {
+ case EFFECT_CMD_INIT:
+ ALOGV("%s :: cmd called EFFECT_CMD_INIT", __func__);
+ if (p_reply_data == NULL || *reply_size != sizeof(int)) {
+ ALOGE("%s: EFFECT_CMD_INIT: %s, sending -EINVAL", __func__,
+ (p_reply_data == NULL) ? "p_reply_data is NULL" :
+ "*reply_size != sizeof(int)");
+ return -EINVAL;
+ }
+ *(int *)p_reply_data = 0;
+ break;
+
+ case EFFECT_CMD_SET_CONFIG:
+ 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;
+ }
+ context->config = *(effect_config_t *)p_cmd_data;
+ *(int *)p_reply_data = 0;
+ break;
+
+ case EFFECT_CMD_GET_CONFIG:
+ ALOGV("%s :: cmd called EFFECT_CMD_GET_CONFIG", __func__);
+ break;
+
+ case EFFECT_CMD_RESET:
+ ALOGV("%s :: cmd called EFFECT_CMD_RESET", __func__);
+ break;
+
+ case EFFECT_CMD_SET_AUDIO_MODE:
+ ALOGV("%s :: cmd called EFFECT_CMD_SET_AUDIO_MODE", __func__);
+ break;
+
+ case EFFECT_CMD_OFFLOAD:
+ ALOGV("%s :: cmd called EFFECT_CMD_OFFLOAD", __func__);
+ if (p_reply_data == NULL || *reply_size != sizeof(int)) {
+ ALOGE("%s: EFFECT_CMD_OFFLOAD: %s, sending -EINVAL", __func__,
+ (p_reply_data == NULL) ? "p_reply_data is NULL" :
+ "*reply_size != sizeof(int)");
+ return -EINVAL;
+ }
+ *(int *)p_reply_data = 0;
+ break;
+
+ case EFFECT_CMD_ENABLE:
+ ALOGV("%s :: cmd called EFFECT_CMD_ENABLE", __func__);
+ if (p_reply_data == NULL || *reply_size != sizeof(int)) {
+ ALOGE("%s: EFFECT_CMD_ENABLE: %s, sending -EINVAL", __func__,
+ (p_reply_data == NULL) ? "p_reply_data is NULL" :
+ "*reply_size != sizeof(int)");
+ status = -EINVAL;
+ goto exit;
+ }
+
+ if (context->state != VOL_LISTENER_STATE_INITIALIZED) {
+ ALOGE("%s: EFFECT_CMD_ENABLE : state not INITIALIZED", __func__);
+ status = -ENOSYS;
+ goto exit;
+ }
+
+ context->state = VOL_LISTENER_STATE_ACTIVE;
+ *(int *)p_reply_data = 0;
+
+ // After changing the state and if device is speaker
+ // recalculate gain dep cal level
+ if (context->dev_id == AUDIO_DEVICE_OUT_SPEAKER) {
+ check_and_set_gain_dep_cal();
+ }
+
+ break;
+
+ case EFFECT_CMD_DISABLE:
+ ALOGV("%s :: cmd called EFFECT_CMD_DISABLE", __func__);
+ if (p_reply_data == NULL || *reply_size != sizeof(int)) {
+ ALOGE("%s: EFFECT_CMD_DISABLE: %s, sending -EINVAL", __func__,
+ (p_reply_data == NULL) ? "p_reply_data is NULL" :
+ "*reply_size != sizeof(int)");
+ status = -EINVAL;
+ goto exit;
+ }
+
+ if (context->state != VOL_LISTENER_STATE_ACTIVE) {
+ ALOGE("%s: EFFECT_CMD_ENABLE : state not ACTIVE", __func__);
+ status = -ENOSYS;
+ goto exit;
+ }
+
+ context->state = VOL_LISTENER_STATE_INITIALIZED;
+ *(int *)p_reply_data = 0;
+
+ // After changing the state and if device is speaker
+ // recalculate gain dep cal level
+ if (context->dev_id == AUDIO_DEVICE_OUT_SPEAKER) {
+ check_and_set_gain_dep_cal();
+ }
+
+ break;
+
+ case EFFECT_CMD_GET_PARAM:
+ ALOGV("%s :: cmd called EFFECT_CMD_GET_PARAM", __func__);
+ break;
+
+ case EFFECT_CMD_SET_PARAM:
+ ALOGV("%s :: cmd called EFFECT_CMD_SET_PARAM", __func__);
+ break;
+
+ case EFFECT_CMD_SET_DEVICE:
+ {
+ uint32_t new_device;
+ bool recompute_gain_dep_cal_Level = false;
+ ALOGV("cmd called EFFECT_CMD_SET_DEVICE ");
+
+ if (p_cmd_data == NULL) {
+ ALOGE("%s: EFFECT_CMD_SET_DEVICE: cmd data NULL", __func__);
+ status = -EINVAL;
+ goto exit;
+ }
+
+ new_device = *(uint32_t *)p_cmd_data;
+ ALOGV("%s :: EFFECT_CMD_SET_DEVICE: (current/new) device (0x%x / 0x%x)",
+ __func__, context->dev_id, new_device);
+
+ // check if old or new device is speaker
+ 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;
+
+ if (recompute_gain_dep_cal_Level) {
+ check_and_set_gain_dep_cal();
+ }
+ }
+ break;
+
+ case EFFECT_CMD_SET_VOLUME:
+ {
+ float left_vol = 0, right_vol = 0;
+ bool recompute_gain_dep_cal_Level = false;
+
+ ALOGV("cmd called EFFECT_CMD_SET_VOLUME");
+ if (p_cmd_data == NULL || cmd_size != 2 * sizeof(uint32_t)) {
+ ALOGE("%s: EFFECT_CMD_SET_VOLUME: %s", __func__, (p_cmd_data == NULL) ?
+ "p_cmd_data is NULL" : "cmd_size issue");
+ status = -EINVAL;
+ goto exit;
+ }
+
+ if (context->dev_id == AUDIO_DEVICE_OUT_SPEAKER) {
+ recompute_gain_dep_cal_Level = true;
+ }
+
+ left_vol = (float)(*(uint32_t *)p_cmd_data) / (1 << 24);
+ right_vol = (float)(*((uint32_t *)p_cmd_data + 1)) / (1 << 24);
+ ALOGV("Current Volume (%f / %f ) new Volume (%f / %f)", context->left_vol,
+ context->right_vol, left_vol, right_vol);
+
+ context->left_vol = left_vol;
+ context->right_vol = right_vol;
+
+ // recompute gan dep cal level only if volume changed on speaker device
+ if (recompute_gain_dep_cal_Level) {
+ check_and_set_gain_dep_cal();
+ }
+ }
+ break;
+
+ default:
+ ALOGW("volume_listener_command invalid command %d", cmd_code);
+ status = -ENOSYS;
+ break;
+ }
+
+exit:
+ pthread_mutex_unlock(&vol_listner_init_lock);
+ return status;
+}
+
+/* Effect Control Interface Implementation: get_descriptor */
+static int vol_effect_get_descriptor(effect_handle_t self,
+ effect_descriptor_t *descriptor)
+{
+ vol_listener_context_t *context = (vol_listener_context_t *)self;
+ ALOGV("%s Called ", __func__);
+
+ if (descriptor == NULL) {
+ ALOGE("%s: descriptor is NULL", __func__);
+ return -EINVAL;
+ }
+
+ *descriptor = *context->desc;
+ return 0;
+}
+
+static void init_once()
+{
+ int i = 0;
+ if (initialized) {
+ ALOGV("%s : already init .. do nothing", __func__);
+ return;
+ }
+
+ ALOGD("%s Called ", __func__);
+ pthread_mutex_init(&vol_listner_init_lock, NULL);
+
+ // get hal function pointer
+ if (access(PRIMARY_HAL_PATH, R_OK) == 0) {
+ void *hal_lib_pointer = dlopen(PRIMARY_HAL_PATH, RTLD_NOW);
+ if (hal_lib_pointer == NULL) {
+ ALOGE("%s: DLOPEN failed for %s", __func__, PRIMARY_HAL_PATH);
+ send_gain_dep_cal = NULL;
+ } else {
+ ALOGV("%s: DLOPEN of %s Succes .. next get HAL entry function", __func__, PRIMARY_HAL_PATH);
+ send_gain_dep_cal = (bool (*)(int))dlsym(hal_lib_pointer, AHAL_GAIN_DEPENDENT_INTERFACE_FUNCTION);
+ if (send_gain_dep_cal == NULL) {
+ ALOGE("Couldnt able to get the function symbol");
+ }
+ }
+ } else {
+ ALOGE("%s: not able to acces lib %s ", __func__, PRIMARY_HAL_PATH);
+ send_gain_dep_cal = NULL;
+ }
+
+ // check system property to see if dumping is required
+ char check_dump_val[PROPERTY_VALUE_MAX];
+ property_get("audio.volume.listener.dump", check_dump_val, "0");
+ if (atoi(check_dump_val)) {
+ dumping_enabled = true;
+ }
+
+ init_status = 0;
+ list_init(&vol_effect_list);
+ initialized = true;
+}
+
+static int lib_init()
+{
+ pthread_once(&once, init_once);
+ ALOGV("%s Called ", __func__);
+ return init_status;
+}
+
+static int vol_prc_lib_create(const effect_uuid_t *uuid,
+ int32_t session_id,
+ int32_t io_id __unused,
+ effect_handle_t *p_handle)
+{
+ int itt = 0;
+ vol_listener_context_t *context = NULL;
+
+ ALOGV("volume_prc_lib_create .. called ..");
+
+ if (lib_init() != 0) {
+ return init_status;
+ }
+
+ if (p_handle == NULL || uuid == NULL) {
+ ALOGE("%s: %s is NULL", __func__, (p_handle == NULL) ? "p_handle" : "uuid");
+ return -EINVAL;
+ }
+
+ context = (vol_listener_context_t *)calloc(1, sizeof(vol_listener_context_t));
+
+ if (context == NULL) {
+ ALOGE("%s: failed to allocate for context .. oops !!", __func__);
+ return -EINVAL;
+ }
+
+ // check if UUID is supported
+ for (itt = 0; descriptors[itt] != NULL; itt++) {
+ if (memcmp(uuid, &descriptors[itt]->uuid, sizeof(effect_uuid_t)) == 0) {
+ // check if this correct .. very imp
+ context->desc = descriptors[itt];
+ context->stream_type = itt;
+ PRINT_STREAM_TYPE(itt)
+ break;
+ }
+ }
+
+ if (descriptors[itt] == NULL) {
+ ALOGE("%s .. couldnt find passed uuid, something wrong", __func__);
+ free(context);
+ return -EINVAL;
+ }
+
+ ALOGV("%s CREATED_CONTEXT %p", __func__, context);
+
+ context->itfe = &effect_interface;
+ context->state = VOL_LISTENER_STATE_INITIALIZED;
+ context->dev_id = AUDIO_DEVICE_NONE;
+ context->session_id = session_id;
+
+ // Add this to master list
+ pthread_mutex_lock(&vol_listner_init_lock);
+ list_add_tail(&vol_effect_list, &context->effect_list_node);
+ if (dumping_enabled) {
+ dump_list_l();
+ }
+ pthread_mutex_unlock(&vol_listner_init_lock);
+
+ *p_handle = (effect_handle_t)context;
+ return 0;
+}
+
+static int vol_prc_lib_release(effect_handle_t handle)
+{
+ struct listnode *node = NULL;
+ vol_listener_context_t *context = NULL;
+ vol_listener_context_t *recv_contex = (vol_listener_context_t *)handle;
+ int status = -1;
+ bool recompute_flag = false;
+ int active_stream_count = 0;
+ ALOGV("%s context %p", __func__, handle);
+ if (recv_contex == NULL || recv_contex->desc == NULL) {
+ ALOGE("%s: Got invalid handle while release, DO NOTHING ", __func__);
+ return status;
+ }
+
+ pthread_mutex_lock(&vol_listner_init_lock);
+
+ // check if the handle/context provided is valid
+ list_for_each(node, &vol_effect_list) {
+ context = node_to_item(node, struct vol_listener_context_s, effect_list_node);
+ if ((memcmp(&(context->desc->uuid), &(recv_contex->desc->uuid), sizeof(effect_uuid_t)) == 0)
+ && (context->session_id == recv_contex->session_id)
+ && (context->stream_type == recv_contex->stream_type)) {
+ ALOGV("--- Found something to remove ---");
+ PRINT_STREAM_TYPE(context->stream_type);
+ if (context->dev_id == AUDIO_DEVICE_OUT_SPEAKER) {
+ recompute_flag = true;
+ }
+ list_remove(&context->effect_list_node);
+ free(context);
+ status = 0;
+ break;
+ } else {
+ ++active_stream_count;
+ }
+ }
+
+ if (status != 0) {
+ ALOGE("something wrong ... <<<--- Found NOTHING to remove ... ???? --->>>>>");
+ }
+
+ // if there are no active streams, reset cal and volume level
+ if (active_stream_count == 0) {
+ current_gain_dep_cal_level = -1;
+ current_vol = 0.0;
+ }
+
+ if (recompute_flag) {
+ check_and_set_gain_dep_cal();
+ }
+
+ if (dumping_enabled) {
+ dump_list_l();
+ }
+ pthread_mutex_unlock(&vol_listner_init_lock);
+ return status;
+}
+
+static int vol_prc_lib_get_descriptor(const effect_uuid_t *uuid,
+ effect_descriptor_t *descriptor)
+{
+ int i = 0;
+ ALOGV("%s Called ", __func__);
+ if (lib_init() != 0) {
+ return init_status;
+ }
+
+ if (descriptor == NULL || uuid == NULL) {
+ ALOGE("%s: %s is NULL", __func__, (descriptor == NULL) ? "descriptor" : "uuid");
+ return -EINVAL;
+ }
+
+ for (i = 0; descriptors[i] != NULL; i++) {
+ if (memcmp(uuid, &descriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) {
+ *descriptor = *descriptors[i];
+ return 0;
+ }
+ }
+
+ ALOGE("%s: couldnt found uuid passed, oops", __func__);
+ return -EINVAL;
+}
+
+
+/* effect_handle_t interface implementation for volume listener effect */
+static const struct effect_interface_s effect_interface = {
+ vol_effect_process,
+ vol_effect_command,
+ vol_effect_get_descriptor,
+ NULL,
+};
+
+__attribute__((visibility("default")))
+audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
+ .tag = AUDIO_EFFECT_LIBRARY_TAG,
+ .version = EFFECT_LIBRARY_API_VERSION,
+ .name = "Volume Listener Effect Library",
+ .implementor = "Qualcomm Technologies Inc.",
+ .create_effect = vol_prc_lib_create,
+ .release_effect = vol_prc_lib_release,
+ .get_descriptor = vol_prc_lib_get_descriptor,
+};
diff --git a/voice_processing/voice_processing.c b/voice_processing/voice_processing.c
index bb9bf3b..1e1e123 100644
--- a/voice_processing/voice_processing.c
+++ b/voice_processing/voice_processing.c
@@ -16,6 +16,7 @@
#define LOG_TAG "voice_processing"
/*#define LOG_NDEBUG 0*/
+#include <stdlib.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <cutils/log.h>