Merge "hal: Update HAL to handle offload format with AAC profile info."
diff --git a/hal/Android.mk b/hal/Android.mk
index 25bf66f..32b9275 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -141,6 +141,11 @@
LOCAL_CFLAGS += -DQTI_FLAC_DECODER
endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DEV_ARBI)),true)
+ LOCAL_CFLAGS += -DDEV_ARBI_ENABLED
+ LOCAL_SRC_FILES += audio_extn/dev_arbi.c
+endif
+
LOCAL_SHARED_LIBRARIES := \
liblog \
libcutils \
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 7ce1c3a..5eb650c 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -192,7 +192,7 @@
#define audio_extn_spkr_prot_stop_processing() (0)
#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_OUT_SPEAKER)
+#define audio_extn_get_spkr_prot_snd_device(snd_device) (snd_device)
#else
void audio_extn_spkr_prot_init(void *adev);
int audio_extn_spkr_prot_start_processing(snd_device_t snd_device);
@@ -260,6 +260,18 @@
audio_usecase_t audio_extn_hfp_get_usecase();
#endif
+#ifndef DEV_ARBI_ENABLED
+#define audio_extn_dev_arbi_init() (0)
+#define audio_extn_dev_arbi_deinit() (0)
+#define audio_extn_dev_arbi_acquire(snd_device) (0)
+#define audio_extn_dev_arbi_release(snd_device) (0)
+#else
+int audio_extn_dev_arbi_init();
+int audio_extn_dev_arbi_deinit();
+int audio_extn_dev_arbi_acquire(snd_device_t snd_device);
+int audio_extn_dev_arbi_release(snd_device_t snd_device);
+#endif
+
void audio_extn_utils_update_streams_output_cfg_list(void *platform,
struct mixer *mixer,
struct listnode *streams_output_cfg_list);
diff --git a/hal/audio_extn/dev_arbi.c b/hal/audio_extn/dev_arbi.c
new file mode 100644
index 0000000..d3c01c5
--- /dev/null
+++ b/hal/audio_extn/dev_arbi.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2014, 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 "audio_hw_dev_arbi"
+/*#define LOG_NDEBUG 0*/
+#define LOG_NDDEBUG 0
+
+#include <errno.h>
+#include <cutils/log.h>
+#include <fcntl.h>
+#include "audio_hw.h"
+#include "platform.h"
+#include "platform_api.h"
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <cutils/properties.h>
+#include "audio_extn.h"
+
+#ifdef DEV_ARBI_ENABLED
+
+typedef int (init_fn_t)();
+typedef int (deinit_fn_t)();
+typedef int (acquire_fn_t)(audio_devices_t aud_dev);
+typedef int (release_fn_t)(audio_devices_t aud_dev);
+
+typedef struct {
+ snd_device_t snd_device;
+ audio_devices_t aud_device;
+} snd_aud_dev_mapping_t;
+
+static void* lib_handle = NULL;
+
+static init_fn_t *init_fp = NULL;
+static deinit_fn_t *deinit_fp = NULL;
+static acquire_fn_t *acquire_fp = NULL;
+static release_fn_t *release_fp = NULL;
+
+static int load_dev_arbi_lib()
+{
+ int rc = -EINVAL;
+
+ if (lib_handle != NULL) {
+ ALOGE("%s: library already loaded", __func__);
+ return rc;
+ }
+
+ lib_handle = dlopen("libaudiodevarb.so", RTLD_NOW);
+ if (lib_handle != NULL) {
+ init_fp = (init_fn_t*)dlsym(lib_handle, "aud_dev_arbi_server_init");
+ deinit_fp = (deinit_fn_t*)dlsym(lib_handle, "aud_dev_arbi_server_deinit");
+ acquire_fp = (acquire_fn_t*)dlsym(lib_handle, "aud_dev_arbi_server_acquire");
+ release_fp = (release_fn_t*)dlsym(lib_handle, "aud_dev_arbi_server_release");
+
+ if ((init_fp == NULL) ||
+ (deinit_fp == NULL) ||
+ (acquire_fp == NULL) ||
+ (release_fp == NULL)) {
+
+ ALOGE("%s: error loading symbols from library", __func__);
+
+ init_fp = NULL;
+ deinit_fp = NULL;
+ acquire_fp = NULL;
+ release_fp = NULL;
+ } else
+ return 0;
+ }
+
+ return rc;
+}
+
+int audio_extn_dev_arbi_init()
+{
+ int rc = load_dev_arbi_lib();
+ if (!rc)
+ rc = init_fp();
+
+ return rc;
+}
+
+int audio_extn_dev_arbi_deinit()
+{
+ int rc = -EINVAL;
+
+ if(deinit_fp != NULL) {
+ rc = deinit_fp();
+
+ init_fp = NULL;
+ deinit_fp = NULL;
+ acquire_fp = NULL;
+ release_fp = NULL;
+
+ dlclose(lib_handle);
+ lib_handle = NULL;
+ }
+
+ return rc;
+}
+
+static audio_devices_t get_audio_device(snd_device_t snd_device)
+{
+ static snd_aud_dev_mapping_t snd_aud_dev_map[] = {
+ {SND_DEVICE_OUT_HANDSET, AUDIO_DEVICE_OUT_EARPIECE},
+ {SND_DEVICE_OUT_VOICE_HANDSET, AUDIO_DEVICE_OUT_EARPIECE}
+ };
+
+ audio_devices_t aud_device = AUDIO_DEVICE_NONE;
+ uint32_t ind = 0;
+
+ for (ind = 0; ind < ARRAY_SIZE(snd_aud_dev_map); ++ind) {
+ if (snd_device == snd_aud_dev_map[ind].snd_device) {
+ aud_device = snd_aud_dev_map[ind].aud_device;
+ break;
+ }
+ }
+
+ return aud_device;
+}
+
+int audio_extn_dev_arbi_acquire(snd_device_t snd_device)
+{
+ int rc = -EINVAL;
+ audio_devices_t audio_device = get_audio_device(snd_device);
+
+ if ((acquire_fp != NULL) && (audio_device != AUDIO_DEVICE_NONE))
+ rc = acquire_fp(audio_device);
+
+ return rc;
+}
+
+int audio_extn_dev_arbi_release(snd_device_t snd_device)
+{
+ int rc = -EINVAL;
+ audio_devices_t audio_device = get_audio_device(snd_device);
+
+ if ((release_fp != NULL) && (audio_device != AUDIO_DEVICE_NONE))
+ rc = release_fp(audio_device);
+
+ return rc;
+}
+
+#endif /*DEV_ARBI_ENABLED*/
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 20862e7..e58c954 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -380,6 +380,7 @@
LISTEN_EVENT_SND_DEVICE_FREE);
return -EINVAL;
}
+ audio_extn_dev_arbi_acquire(snd_device);
audio_route_apply_and_update_path(adev->audio_route, device_name);
}
return 0;
@@ -423,9 +424,10 @@
snd_device == SND_DEVICE_OUT_VOICE_SPEAKER) &&
audio_extn_spkr_prot_is_enabled()) {
audio_extn_spkr_prot_stop_processing();
- } else
+ } else {
audio_route_reset_and_update_path(adev->audio_route, device_name);
-
+ audio_extn_dev_arbi_release(snd_device);
+ }
audio_extn_listen_update_device_status(snd_device,
LISTEN_EVENT_SND_DEVICE_FREE);
}
@@ -1807,6 +1809,8 @@
}
ret = compress_write(out->compr, buffer, bytes);
+ if (ret < 0)
+ ret = -errno;
ALOGVV("%s: writing buffer (%d bytes) to compress device returned %d", __func__, bytes, ret);
if (ret >= 0 && ret < (ssize_t)bytes) {
ALOGD("No space available in compress driver, post msg to cb thread");
@@ -1831,7 +1835,9 @@
memset((void *)buffer, 0, bytes);
ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
ret = pcm_write(out->pcm, (void *)buffer, bytes);
- if (ret == 0)
+ if (ret < 0)
+ ret = -errno;
+ else if (ret == 0)
out->written += bytes / (out->config.channels * sizeof(short));
}
}
@@ -1849,7 +1855,9 @@
if (out->pcm)
ALOGE("%s: error %d - %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);
+ pthread_mutex_unlock(&adev->lock);
out->standby = true;
}
out_standby(&out->stream.common);
@@ -1871,6 +1879,8 @@
if (out->compr != NULL) {
ret = compress_get_tstamp(out->compr, (unsigned long *)dsp_frames,
&out->sample_rate);
+ if (ret < 0)
+ ret = -errno;
ALOGVV("%s rendered frames %d sample_rate %d",
__func__, *dsp_frames, out->sample_rate);
}
@@ -2245,6 +2255,8 @@
ret = audio_extn_compr_cap_read(in, buffer, bytes);
else
ret = pcm_read(in->pcm, buffer, bytes);
+ if (ret < 0)
+ ret = -errno;
}
/*
@@ -2265,7 +2277,9 @@
if (ret != 0) {
if (in->usecase == USECASE_COMPRESS_VOIP_CALL) {
+ pthread_mutex_lock(&adev->lock);
voice_extn_compress_voip_close_input_stream(&in->stream.common);
+ pthread_mutex_unlock(&adev->lock);
in->standby = true;
}
in_standby(&in->stream.common);
@@ -2602,7 +2616,9 @@
ALOGD("%s: enter:stream_handle(%p)",__func__, out);
if (out->usecase == USECASE_COMPRESS_VOIP_CALL) {
+ pthread_mutex_lock(&adev->lock);
ret = voice_extn_compress_voip_close_output_stream(&stream->common);
+ pthread_mutex_unlock(&adev->lock);
if(ret != 0)
ALOGE("%s: Compress voip output cannot be closed, error:%d",
__func__, ret);
@@ -2673,9 +2689,7 @@
err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
if (err >= 0) {
- /* When set to false, HAL should disable EC and NS
- * But it is currently not supported.
- */
+ /* When set to false, HAL should disable EC and NS */
if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
adev->bluetooth_nrec = true;
else
@@ -2952,10 +2966,14 @@
{
int ret;
struct stream_in *in = (struct stream_in *)stream;
+ struct audio_device *adev = in->dev;
+
ALOGD("%s: enter:stream_handle(%p)",__func__, in);
if (in->usecase == USECASE_COMPRESS_VOIP_CALL) {
+ pthread_mutex_lock(&adev->lock);
ret = voice_extn_compress_voip_close_input_stream(&stream->common);
+ pthread_mutex_unlock(&adev->lock);
if (ret != 0)
ALOGE("%s: Compress voip input cannot be closed, error:%d",
__func__, ret);
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index f1ceedc..e9f7af7 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -61,7 +61,7 @@
* Each usecase is mapped to a specific PCM device.
* Refer to pcm_device_table[].
*/
-typedef enum {
+enum {
USECASE_INVALID = -1,
/* Playback usecases */
USECASE_AUDIO_PLAYBACK_DEEP_BUFFER = 0,
@@ -115,7 +115,9 @@
USECASE_AUDIO_SPKR_CALIB_RX,
USECASE_AUDIO_SPKR_CALIB_TX,
AUDIO_USECASE_MAX
-} audio_usecase_t;
+};
+
+const char * const use_case_table[AUDIO_USECASE_MAX];
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 6cf0f65..ae7b18a 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -42,6 +42,7 @@
#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
#define MIXER_XML_PATH_WCD9306 "/system/etc/mixer_paths_wcd9306.xml"
+#define MIXER_XML_PATH_WCD9330 "/system/etc/mixer_paths_wcd9330.xml"
#define PLATFORM_INFO_XML_PATH "/system/etc/audio_platform_info.xml"
#define LIB_ACDB_LOADER "libacdbloader.so"
#define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
@@ -231,7 +232,9 @@
[SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
[SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
[SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
+ [SND_DEVICE_IN_BT_SCO_MIC_NREC] = "bt-sco-mic",
[SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
+ [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = "bt-sco-mic-wb",
[SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
[SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
[SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
@@ -309,7 +312,9 @@
[SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
[SND_DEVICE_IN_HDMI_MIC] = 4,
[SND_DEVICE_IN_BT_SCO_MIC] = 21,
+ [SND_DEVICE_IN_BT_SCO_MIC_NREC] = 122,
[SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
+ [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = 123,
[SND_DEVICE_IN_CAMCORDER_MIC] = 4,
[SND_DEVICE_IN_VOICE_DMIC] = 41,
[SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
@@ -392,7 +397,9 @@
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_NREC)},
{TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB_NREC)},
{TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
@@ -451,6 +458,10 @@
sizeof("msm8939-tapan9302-snd-card"))) {
strlcpy(mixer_xml_path, MIXER_XML_PATH_WCD9306,
sizeof(MIXER_XML_PATH_WCD9306));
+ } else if (!strncmp(snd_card_name, "msm8939-tomtom9330-snd-card",
+ sizeof("msm8939-tomtom9330-snd-card"))) {
+ strlcpy(mixer_xml_path, MIXER_XML_PATH_WCD9330,
+ sizeof(MIXER_XML_PATH_WCD9330));
} else {
strlcpy(mixer_xml_path, MIXER_XML_PATH,
sizeof(MIXER_XML_PATH));
@@ -819,9 +830,11 @@
void platform_add_backend_name(char *mixer_path, snd_device_t snd_device)
{
- if (snd_device == SND_DEVICE_IN_BT_SCO_MIC)
+ if ((snd_device == SND_DEVICE_IN_BT_SCO_MIC) ||
+ (snd_device == SND_DEVICE_IN_BT_SCO_MIC_NREC))
strlcat(mixer_path, " bt-sco", MIXER_PATH_MAX_LENGTH);
- else if (snd_device == SND_DEVICE_IN_BT_SCO_MIC_WB)
+ else if ((snd_device == SND_DEVICE_IN_BT_SCO_MIC_WB) ||
+ (snd_device == SND_DEVICE_IN_BT_SCO_MIC_WB_NREC))
strlcat(mixer_path, " bt-sco-wb", MIXER_PATH_MAX_LENGTH);
else if(snd_device == SND_DEVICE_OUT_BT_SCO)
strlcat(mixer_path, " bt-sco", MIXER_PATH_MAX_LENGTH);
@@ -1428,10 +1441,17 @@
snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
set_echo_reference(adev->mixer, EC_REF_RX);
} else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
- if (adev->bt_wb_speech_enabled)
- snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
- else
- snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+ if (adev->bt_wb_speech_enabled) {
+ if (adev->bluetooth_nrec)
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
+ else
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
+ } else {
+ if (adev->bluetooth_nrec)
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
+ else
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+ }
} else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
if (my_data->fluence_type != FLUENCE_NONE &&
my_data->fluence_in_voice_call &&
@@ -1580,10 +1600,17 @@
} else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
snd_device = SND_DEVICE_IN_HEADSET_MIC;
} else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
- if (adev->bt_wb_speech_enabled)
- snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
- else
- snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+ if (adev->bt_wb_speech_enabled) {
+ if (adev->bluetooth_nrec)
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
+ else
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
+ } else {
+ if (adev->bluetooth_nrec)
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
+ else
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+ }
} else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
snd_device = SND_DEVICE_IN_HDMI_MIC;
} else if (in_device & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET ||
@@ -1609,10 +1636,17 @@
} else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
snd_device = SND_DEVICE_IN_HANDSET_MIC;
} else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
- if (adev->bt_wb_speech_enabled)
- snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
- else
- snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+ if (adev->bt_wb_speech_enabled) {
+ if (adev->bluetooth_nrec)
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
+ else
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
+ } else {
+ if (adev->bluetooth_nrec)
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
+ else
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+ }
} else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
snd_device = SND_DEVICE_IN_HDMI_MIC;
} else if (out_device & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index 3fc8fbf..dec9eda 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -107,7 +107,9 @@
SND_DEVICE_IN_VOICE_HEADSET_MIC,
SND_DEVICE_IN_HDMI_MIC,
SND_DEVICE_IN_BT_SCO_MIC,
+ SND_DEVICE_IN_BT_SCO_MIC_NREC,
SND_DEVICE_IN_BT_SCO_MIC_WB,
+ SND_DEVICE_IN_BT_SCO_MIC_WB_NREC,
SND_DEVICE_IN_CAMCORDER_MIC,
SND_DEVICE_IN_VOICE_DMIC,
SND_DEVICE_IN_VOICE_SPEAKER_DMIC,
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 298089e..949753d 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -43,6 +43,7 @@
#define LIB_ACDB_LOADER "libacdbloader.so"
#define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
+#define CVD_VERSION_MIXER_CTL "CVD Version"
#define MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE (256 * 1024)
#define MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE (2 * 1024)
@@ -71,6 +72,8 @@
#define MAX_SAD_BLOCKS 10
#define SAD_BLOCK_SIZE 3
+#define MAX_CVD_VERSION_STRING_SIZE 100
+
/* EDID format ID for LPCM audio */
#define EDID_FORMAT_LPCM 1
@@ -108,7 +111,7 @@
/* Audio calibration related functions */
typedef void (*acdb_deallocate_t)();
-typedef int (*acdb_init_t)(char *);
+typedef int (*acdb_init_t)(char *, char *);
typedef void (*acdb_send_audio_cal_t)(int, int, int , int);
typedef void (*acdb_send_voice_cal_t)(int, int);
typedef int (*acdb_reload_vocvoltable_t)(int);
@@ -263,7 +266,9 @@
[SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
[SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
[SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
+ [SND_DEVICE_IN_BT_SCO_MIC_NREC] = "bt-sco-mic",
[SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
+ [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = "bt-sco-mic-wb",
[SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
[SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
[SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
@@ -346,7 +351,9 @@
[SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
[SND_DEVICE_IN_HDMI_MIC] = 4,
[SND_DEVICE_IN_BT_SCO_MIC] = 21,
+ [SND_DEVICE_IN_BT_SCO_MIC_NREC] = 122,
[SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
+ [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = 123,
[SND_DEVICE_IN_CAMCORDER_MIC] = 4,
[SND_DEVICE_IN_VOICE_DMIC] = 41,
[SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
@@ -434,7 +441,9 @@
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_NREC)},
{TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB_NREC)},
{TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
{TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
@@ -673,6 +682,8 @@
// will help in avoiding strdups here
backend_table[SND_DEVICE_IN_BT_SCO_MIC] = strdup("bt-sco");
backend_table[SND_DEVICE_IN_BT_SCO_MIC_WB] = strdup("bt-sco-wb");
+ backend_table[SND_DEVICE_IN_BT_SCO_MIC_NREC] = strdup("bt-sco");
+ backend_table[SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = strdup("bt-sco-wb");
backend_table[SND_DEVICE_OUT_BT_SCO] = strdup("bt-sco");
backend_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("bt-sco-wb");
backend_table[SND_DEVICE_OUT_HDMI] = strdup("hdmi");
@@ -686,6 +697,33 @@
backend_table[SND_DEVICE_OUT_TRANSMISSION_FM] = strdup("transmission-fm");
}
+void get_cvd_version(char *cvd_version, struct audio_device *adev)
+{
+ struct mixer_ctl *ctl;
+ int count;
+ int ret = 0;
+
+ ctl = mixer_get_ctl_by_name(adev->mixer, CVD_VERSION_MIXER_CTL);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s", __func__, CVD_VERSION_MIXER_CTL);
+ goto done;
+ }
+ mixer_ctl_update(ctl);
+
+ count = mixer_ctl_get_num_values(ctl);
+ if (count > MAX_CVD_VERSION_STRING_SIZE)
+ count = MAX_CVD_VERSION_STRING_SIZE;
+
+ ret = mixer_ctl_get_array(ctl, cvd_version, count);
+ if (ret != 0) {
+ ALOGE("%s: ERROR! mixer_ctl_get_array() failed to get CVD Version", __func__);
+ goto done;
+ }
+
+done:
+ return;
+}
+
void *platform_init(struct audio_device *adev)
{
char platform[PROPERTY_VALUE_MAX];
@@ -694,6 +732,7 @@
struct platform_data *my_data = NULL;
int retry_num = 0, snd_card_num = 0;
const char *snd_card_name;
+ char *cvd_version = NULL;
my_data = calloc(1, sizeof(struct platform_data));
@@ -842,12 +881,24 @@
my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
"acdb_loader_init_v2");
- if (my_data->acdb_init == NULL)
+ if (my_data->acdb_init == NULL) {
ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
+ goto acdb_init_fail;
+ }
+
+ cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
+ if (!cvd_version)
+ ALOGE("failed to allocate cvd_version");
else
- my_data->acdb_init(snd_card_name);
+ get_cvd_version(cvd_version, adev);
+
+ my_data->acdb_init(snd_card_name, cvd_version);
+ if (cvd_version)
+ free(cvd_version);
}
+acdb_init_fail:
+
set_platform_defaults(my_data);
/* Initialize ACDB ID's */
@@ -880,6 +931,9 @@
audio_extn_dolby_set_license(adev);
+ /* init audio device arbitration */
+ audio_extn_dev_arbi_init();
+
return my_data;
}
@@ -898,6 +952,9 @@
}
}
+ /* deinit audio device arbitration */
+ audio_extn_dev_arbi_deinit();
+
free(platform);
/* deinit usb */
audio_extn_usb_deinit();
@@ -1600,10 +1657,17 @@
snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
set_echo_reference(adev, true);
} else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
- if (adev->bt_wb_speech_enabled)
- snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
- else
- snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+ if (adev->bt_wb_speech_enabled) {
+ if (adev->bluetooth_nrec)
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
+ else
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
+ } else {
+ if (adev->bluetooth_nrec)
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
+ else
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+ }
} else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
if (my_data->fluence_type != FLUENCE_NONE &&
my_data->fluence_in_voice_call &&
@@ -1751,10 +1815,17 @@
} else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
snd_device = SND_DEVICE_IN_HEADSET_MIC;
} else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
- if (adev->bt_wb_speech_enabled)
- snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
- else
- snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+ if (adev->bt_wb_speech_enabled) {
+ if (adev->bluetooth_nrec)
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
+ else
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
+ } else {
+ if (adev->bluetooth_nrec)
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
+ else
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+ }
} else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
snd_device = SND_DEVICE_IN_HDMI_MIC;
} else if (in_device & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET ||
@@ -1780,10 +1851,17 @@
} else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
snd_device = SND_DEVICE_IN_HANDSET_MIC;
} else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
- if (adev->bt_wb_speech_enabled)
- snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
- else
- snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+ if (adev->bt_wb_speech_enabled) {
+ if (adev->bluetooth_nrec)
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
+ else
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
+ } else {
+ if (adev->bluetooth_nrec)
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
+ else
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+ }
} else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
snd_device = SND_DEVICE_IN_HDMI_MIC;
} else if (out_device & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 19f37c7..6f430cc 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -112,7 +112,9 @@
SND_DEVICE_IN_VOICE_HEADSET_MIC,
SND_DEVICE_IN_HDMI_MIC,
SND_DEVICE_IN_BT_SCO_MIC,
+ SND_DEVICE_IN_BT_SCO_MIC_NREC,
SND_DEVICE_IN_BT_SCO_MIC_WB,
+ SND_DEVICE_IN_BT_SCO_MIC_WB_NREC,
SND_DEVICE_IN_CAMCORDER_MIC,
SND_DEVICE_IN_VOICE_DMIC,
SND_DEVICE_IN_VOICE_SPEAKER_DMIC,
diff --git a/hal/voice.c b/hal/voice.c
index 33e0d2c..71fee64 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -41,8 +41,6 @@
.format = PCM_FORMAT_S16_LE,
};
-extern const char * const use_case_table[AUDIO_USECASE_MAX];
-
static struct voice_session *voice_get_session_from_use_case(struct audio_device *adev,
audio_usecase_t usecase_id)
{
@@ -57,7 +55,7 @@
return session;
}
-int stop_call(struct audio_device *adev, audio_usecase_t usecase_id)
+int voice_stop_usecase(struct audio_device *adev, audio_usecase_t usecase_id)
{
int i, ret = 0;
struct audio_usecase *uc_info;
@@ -108,7 +106,7 @@
return ret;
}
-int start_call(struct audio_device *adev, audio_usecase_t usecase_id)
+int voice_start_usecase(struct audio_device *adev, audio_usecase_t usecase_id)
{
int i, ret = 0;
struct audio_usecase *uc_info;
@@ -195,7 +193,7 @@
goto done;
error_start_voice:
- stop_call(adev, usecase_id);
+ voice_stop_usecase(adev, usecase_id);
done:
ALOGD("%s: exit: status(%d)", __func__, ret);
@@ -372,7 +370,7 @@
ret = voice_extn_start_call(adev);
if (ret == -ENOSYS) {
- ret = start_call(adev, USECASE_VOICE_CALL);
+ ret = voice_start_usecase(adev, USECASE_VOICE_CALL);
}
adev->voice.in_call = true;
@@ -386,7 +384,7 @@
adev->voice.in_call = false;
ret = voice_extn_stop_call(adev);
if (ret == -ENOSYS) {
- ret = stop_call(adev, USECASE_VOICE_CALL);
+ ret = voice_stop_usecase(adev, USECASE_VOICE_CALL);
}
return ret;
@@ -410,12 +408,20 @@
ALOGV_IF(kv_pairs != NULL, "%s: enter: %s", __func__, kv_pairs);
ret = voice_extn_set_parameters(adev, parms);
- if (ret != 0)
- goto done;
+ if (ret != 0) {
+ if (ret == -ENOSYS)
+ ret = 0;
+ else
+ goto done;
+ }
ret = voice_extn_compress_voip_set_parameters(adev, parms);
- if (ret != 0)
- goto done;
+ if (ret != 0) {
+ if (ret == -ENOSYS)
+ ret = 0;
+ else
+ goto done;
+ }
err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_TTY_MODE, value, sizeof(value));
if (err >= 0) {
@@ -450,7 +456,7 @@
platform_start_incall_music_usecase(adev->platform);
else
platform_stop_incall_music_usecase(adev->platform);
- }
+ }
done:
ALOGV("%s: exit with code(%d)", __func__, ret);
diff --git a/hal/voice.h b/hal/voice.h
index 5d1ae40..95609b3 100644
--- a/hal/voice.h
+++ b/hal/voice.h
@@ -42,6 +42,7 @@
struct str_parms;
struct stream_in;
struct stream_out;
+typedef int audio_usecase_t;
struct call_state {
int current;
@@ -71,6 +72,9 @@
INCALL_REC_UPLINK_AND_DOWNLINK,
};
+int voice_start_usecase(struct audio_device *adev, audio_usecase_t usecase_id);
+int voice_stop_usecase(struct audio_device *adev, audio_usecase_t usecase_id);
+
int voice_start_call(struct audio_device *adev);
int voice_stop_call(struct audio_device *adev);
int voice_set_parameters(struct audio_device *adev, struct str_parms *parms);
diff --git a/hal/voice_extn/voice_extn.c b/hal/voice_extn/voice_extn.c
index 89abc3a..dcbe825 100644
--- a/hal/voice_extn/voice_extn.c
+++ b/hal/voice_extn/voice_extn.c
@@ -71,8 +71,6 @@
.avail_min = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
};
-extern int start_call(struct audio_device *adev, audio_usecase_t usecase_id);
-extern int stop_call(struct audio_device *adev, audio_usecase_t usecase_id);
int voice_extn_is_call_state_active(struct audio_device *adev, bool *is_call_active);
static bool is_valid_call_state(int call_state)
@@ -169,9 +167,9 @@
{
case CALL_INACTIVE:
ALOGD("%s: INACTIVE -> ACTIVE vsid:%x", __func__, session->vsid);
- ret = start_call(adev, usecase_id);
+ ret = voice_start_usecase(adev, usecase_id);
if(ret < 0) {
- ALOGE("%s: voice_start_call() failed for usecase: %d\n",
+ ALOGE("%s: voice_start_usecase() failed for usecase: %d\n",
__func__, usecase_id);
} else {
session->state.current = session->state.new;
@@ -207,9 +205,9 @@
case CALL_HOLD:
case CALL_LOCAL_HOLD:
ALOGD("%s: ACTIVE/HOLD/LOCAL_HOLD -> INACTIVE vsid:%x", __func__, session->vsid);
- ret = stop_call(adev, usecase_id);
+ ret = voice_stop_usecase(adev, usecase_id);
if(ret < 0) {
- ALOGE("%s: voice_end_call() failed for usecase: %d\n",
+ ALOGE("%s: voice_stop_usecase() failed for usecase: %d\n",
__func__, usecase_id);
} else {
session->state.current = session->state.new;