Audio: Bear(8916) Audio HAL bringup changes
- Added 8916 audio HAL spacific changes
Merged 8916 BU changes to mainline
Change-Id: I8bfb06f328f1851d924d1b1219bc7317afa38b0d
diff --git a/hal/Android.mk b/hal/Android.mk
index 32a9ee9..d3d909d 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -8,7 +8,7 @@
AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
-ifneq ($(filter msm8974 msm8226 msm8610 apq8084 msm8916,$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter msm8974 msm8226 msm8610 apq8084,$(TARGET_BOARD_PLATFORM)),)
# B-family platform uses msm8974 code base
AUDIO_PLATFORM = msm8974
MULTIPLE_HW_VARIANTS_ENABLED := true
@@ -23,6 +23,11 @@
endif
endif
+ifneq ($(filter msm8916,$(TARGET_BOARD_PLATFORM)),)
+ AUDIO_PLATFORM = msm8916
+ MULTIPLE_HW_VARIANTS_ENABLED := true
+ LOCAL_CFLAGS := -DPLATFORM_MSM8916
+endif
LOCAL_SRC_FILES := \
audio_hw.c \
diff --git a/hal/msm8916/hw_info.c b/hal/msm8916/hw_info.c
index 4dafa4f..d002a3f 100644
--- a/hal/msm8916/hw_info.c
+++ b/hal/msm8916/hw_info.c
@@ -51,11 +51,6 @@
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-#define LITERAL_TO_STRING(x) #x
-#define CHECK(condition) LOG_ALWAYS_FATAL_IF(!(condition), "%s",\
- __FILE__ ":" LITERAL_TO_STRING(__LINE__)\
- " ASSERT_FATAL(" #condition ") failed.")
-
static const snd_device_t taiko_fluid_variant_devices[] = {
SND_DEVICE_OUT_SPEAKER,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
@@ -66,6 +61,11 @@
SND_DEVICE_OUT_SPEAKER,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET,
+ SND_DEVICE_IN_QUAD_MIC,
+};
+
+static const snd_device_t taiko_apq8084_CDP_variant_devices[] = {
+ SND_DEVICE_IN_HANDSET_MIC,
};
static const snd_device_t taiko_liquid_variant_devices[] = {
@@ -74,6 +74,13 @@
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 const snd_device_t taiko_DB_variant_devices[] = {
@@ -81,28 +88,33 @@
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_QUAD_MIC,
};
static const snd_device_t tapan_lite_variant_devices[] = {
SND_DEVICE_OUT_SPEAKER,
+ SND_DEVICE_OUT_HEADPHONES,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
- SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET,
+ SND_DEVICE_OUT_VOICE_HEADPHONES,
+ SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES,
+ SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES,
};
static const snd_device_t tapan_skuf_variant_devices[] = {
SND_DEVICE_OUT_SPEAKER,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET,
+ /*SND_DEVICE_OUT_SPEAKER_AND_ANC_FB_HEADSET,*/
};
static const snd_device_t tapan_lite_skuf_variant_devices[] = {
SND_DEVICE_OUT_SPEAKER,
- SND_DEVICE_OUT_ANC_HANDSET,
- SND_DEVICE_OUT_ANC_HEADSET,
- SND_DEVICE_OUT_ANC_FB_HEADSET,
+ SND_DEVICE_OUT_HEADPHONES,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
- SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET,
- SND_DEVICE_IN_AANC_HANDSET_MIC,
+ SND_DEVICE_OUT_VOICE_HEADPHONES,
+ SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES,
+ SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES,
};
static const snd_device_t helicon_skuab_variant_devices[] = {
@@ -111,121 +123,28 @@
SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET,
};
-static void update_hardware_info_8084(struct hardware_info *hw_info, const char *snd_card_name)
+static void update_hardware_info_8x16(struct hardware_info *hw_info, const char *snd_card_name)
{
- if (!strcmp(snd_card_name, "apq8084-taiko-mtp-snd-card")) {
- strlcpy(hw_info->type, "mtp", sizeof(hw_info->type));
- strlcpy(hw_info->name, "apq8084", 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, "apq8084-taiko-cdp-snd-card")) {
- strlcpy(hw_info->type, " cdp", sizeof(hw_info->type));
- strlcpy(hw_info->name, "apq8084", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *)taiko_CDP_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(taiko_CDP_variant_devices);
- strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "apq8084-taiko-liquid-snd-card")) {
- strlcpy(hw_info->type , " liquid", sizeof(hw_info->type));
- strlcpy(hw_info->name, "apq8084", sizeof(hw_info->type));
- hw_info->snd_devices = (snd_device_t *)taiko_liquid_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(taiko_liquid_variant_devices);
- strlcpy(hw_info->dev_extn, "", sizeof(hw_info->dev_extn));
- } else {
- ALOGW("%s: Not an 8084 device", __func__);
- }
-}
-
-static void update_hardware_info_8974(struct hardware_info *hw_info, const char *snd_card_name)
-{
- if (!strcmp(snd_card_name, "msm8974-taiko-mtp-snd-card")) {
- strlcpy(hw_info->type, " mtp", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8974", 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, "msm8974-taiko-cdp-snd-card")) {
- strlcpy(hw_info->type, " cdp", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8974", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *)taiko_CDP_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(taiko_CDP_variant_devices);
- strlcpy(hw_info->dev_extn, "-fluid", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "msm8974-taiko-fluid-snd-card")) {
- strlcpy(hw_info->type, " fluid", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8974", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *) taiko_fluid_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(taiko_fluid_variant_devices);
- strlcpy(hw_info->dev_extn, "-fluid", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "msm8974-taiko-liquid-snd-card")) {
- strlcpy(hw_info->type, " liquid", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8974", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *)taiko_liquid_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(taiko_liquid_variant_devices);
- strlcpy(hw_info->dev_extn, "-liquid", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "apq8074-taiko-db-snd-card")) {
- strlcpy(hw_info->type, " dragon-board", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8974", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *)taiko_DB_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(taiko_DB_variant_devices);
- strlcpy(hw_info->dev_extn, "-DB", sizeof(hw_info->dev_extn));
- } else {
- ALOGW("%s: Not an 8974 device", __func__);
- }
-}
-
-static void update_hardware_info_8610(struct hardware_info *hw_info, const char *snd_card_name)
-{
- if (!strcmp(snd_card_name, "msm8x10-snd-card")) {
+ if (!strcmp(snd_card_name, "msm8x16-snd-card")) {
strlcpy(hw_info->type, "", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8x10", sizeof(hw_info->name));
+ strlcpy(hw_info->name, "msm8x16", 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, "msm8x10-skuab-snd-card")) {
+ } else if (!strcmp(snd_card_name, "msm8x16-skuab-snd-card")) {
strlcpy(hw_info->type, "skuab", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8x10", sizeof(hw_info->name));
+ strlcpy(hw_info->name, "msm8x16", sizeof(hw_info->name));
hw_info->snd_devices = (snd_device_t *)helicon_skuab_variant_devices;
hw_info->num_snd_devices = ARRAY_SIZE(helicon_skuab_variant_devices);
strlcpy(hw_info->dev_extn, "-skuab", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "msm8x10-skuaa-snd-card")) {
+ } else if (!strcmp(snd_card_name, "msm8x16-skuaa-snd-card")) {
strlcpy(hw_info->type, " skuaa", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8x10", sizeof(hw_info->name));
+ strlcpy(hw_info->name, "msm8x16", 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 8x10 device", __func__);
- }
-}
-
-static void update_hardware_info_8226(struct hardware_info *hw_info, const char *snd_card_name)
-{
- if (!strcmp(snd_card_name, "msm8226-tapan-snd-card")) {
- strlcpy(hw_info->type, "", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8226", 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, "msm8226-tapan9302-snd-card")) {
- strlcpy(hw_info->type, "tapan_lite", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8226", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *)tapan_lite_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(tapan_lite_variant_devices);
- strlcpy(hw_info->dev_extn, "-lite", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "msm8226-tapan-skuf-snd-card")) {
- strlcpy(hw_info->type, " skuf", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8226", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *) tapan_skuf_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(tapan_skuf_variant_devices);
- strlcpy(hw_info->dev_extn, "-skuf", sizeof(hw_info->dev_extn));
- } else if (!strcmp(snd_card_name, "msm8226-tapan9302-skuf-snd-card")) {
- strlcpy(hw_info->type, " tapan9302-skuf", sizeof(hw_info->type));
- strlcpy(hw_info->name, "msm8226", sizeof(hw_info->name));
- hw_info->snd_devices = (snd_device_t *)tapan_lite_skuf_variant_devices;
- hw_info->num_snd_devices = ARRAY_SIZE(tapan_lite_skuf_variant_devices);
- strlcpy(hw_info->dev_extn, "-skuf-lite", sizeof(hw_info->dev_extn));
- } else {
- ALOGW("%s: Not an 8x26 device", __func__);
+ ALOGW("%s: Not an 8x16 device", __func__);
}
}
@@ -235,22 +154,11 @@
hw_info = malloc(sizeof(struct hardware_info));
- if(strstr(snd_card_name, "msm8974") ||
- strstr(snd_card_name, "apq8074")) {
- ALOGV("8974 - variant soundcard");
- update_hardware_info_8974(hw_info, snd_card_name);
- } else if(strstr(snd_card_name, "msm8226")) {
- ALOGV("8x26 - variant soundcard");
- update_hardware_info_8226(hw_info, snd_card_name);
- } else if(strstr(snd_card_name, "msm8x10")) {
- ALOGV("8x10 - variant soundcard");
- update_hardware_info_8610(hw_info, snd_card_name);
- } else if(strstr(snd_card_name, "apq8084")) {
- ALOGV("8084 - variant soundcard");
- update_hardware_info_8084(hw_info, snd_card_name);
+ if(strstr(snd_card_name, "msm8x16")) {
+ ALOGV("8x16 - variant soundcard");
+ update_hardware_info_8x16(hw_info, snd_card_name);
} else {
- ALOGE("%s: Unupported target %s:",__func__, snd_card_name);
- CHECK(0);
+ ALOGE("%s: Unsupported target %s:",__func__, snd_card_name);
free(hw_info);
hw_info = NULL;
}
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index d563288..546b1fd 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,7 +17,7 @@
* limitations under the License.
*/
-#define LOG_TAG "msm8974_platform"
+#define LOG_TAG "msm8916_platform"
/*#define LOG_NDEBUG 0*/
#define LOG_NDDEBUG 0
@@ -22,21 +25,35 @@
#include <dlfcn.h>
#include <cutils/log.h>
#include <cutils/properties.h>
+#include <cutils/str_parms.h>
#include <audio_hw.h>
#include <platform_api.h>
#include "platform.h"
+#include "audio_extn.h"
+#include "voice_extn.h"
+#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
+#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.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"
-#define DUALMIC_CONFIG_NONE 0 /* Target does not contain 2 mics */
-#define DUALMIC_CONFIG_ENDFIRE 1
-#define DUALMIC_CONFIG_BROADSIDE 2
+#define MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE (256 * 1024)
+#define MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE (2 * 1024)
+#define COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING (2 * 1024)
+#define COMPRESS_OFFLOAD_FRAGMENT_SIZE (32 * 1024)
+/* Used in calculating fragment size for pcm offload */
+#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV 2000 /* 2 secs */
+#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING 100 /* 100 millisecs */
-/*
- * This is the sysfs path for the HDMI audio data block
+/* MAX PCM fragment size cannot be increased further due
+ * to flinger's cblk size of 1mb,and it has to be a multiple of
+ * 24 - lcm of channels supported by DSP
*/
-#define AUDIO_DATA_BLOCK_PATH "/sys/class/graphics/fb1/audio_data_block"
+#define MAX_PCM_OFFLOAD_FRAGMENT_SIZE (240 * 1024)
+#define MIN_PCM_OFFLOAD_FRAGMENT_SIZE (32 * 1024)
+#define ALIGN( num, to ) (((num) + (to-1)) & (~(to-1)))
/*
* This file will have a maximum of 38 bytes:
*
@@ -50,39 +67,100 @@
/* EDID format ID for LPCM audio */
#define EDID_FORMAT_LPCM 1
+/* Retry for delay in FW loading*/
+#define RETRY_NUMBER 20
+#define RETRY_US 500000
+#define MAX_SND_CARD 8
+
+#define SAMPLE_RATE_8KHZ 8000
+#define SAMPLE_RATE_16KHZ 16000
+
+#define AUDIO_PARAMETER_KEY_FLUENCE_TYPE "fluence"
+#define AUDIO_PARAMETER_KEY_BTSCO "bt_samplerate"
+#define AUDIO_PARAMETER_KEY_SLOWTALK "st_enable"
+#define AUDIO_PARAMETER_KEY_VOLUME_BOOST "volume_boost"
+
+enum {
+ VOICE_FEATURE_SET_DEFAULT,
+ VOICE_FEATURE_SET_VOLUME_BOOST
+};
+
struct audio_block_header
{
int reserved;
int length;
};
+/* Audio calibration related functions */
typedef void (*acdb_deallocate_t)();
-typedef int (*acdb_init_t)();
+typedef int (*acdb_init_t)(char *);
typedef void (*acdb_send_audio_cal_t)(int, int);
typedef void (*acdb_send_voice_cal_t)(int, int);
+typedef int (*acdb_reload_vocvoltable_t)(int);
-/* Audio calibration related functions */
struct platform_data {
struct audio_device *adev;
bool fluence_in_spkr_mode;
bool fluence_in_voice_call;
bool fluence_in_voice_rec;
- int dualmic_config;
+ bool fluence_in_audio_rec;
+ int fluence_type;
+ int btsco_sample_rate;
+ bool slowtalk;
+ /* Audio calibration related functions */
+ void *acdb_handle;
+ int voice_feature_set;
+ acdb_init_t acdb_init;
+ acdb_deallocate_t acdb_deallocate;
+ acdb_send_audio_cal_t acdb_send_audio_cal;
+ acdb_send_voice_cal_t acdb_send_voice_cal;
+ acdb_reload_vocvoltable_t acdb_reload_vocvoltable;
- void *acdb_handle;
- acdb_init_t acdb_init;
- acdb_deallocate_t acdb_deallocate;
- acdb_send_audio_cal_t acdb_send_audio_cal;
- acdb_send_voice_cal_t acdb_send_voice_cal;
+ void *hw_info;
+ struct csd_data *csd;
};
static const int pcm_device_table[AUDIO_USECASE_MAX][2] = {
- [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {0, 0},
- [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {15, 15},
- [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {1, 1},
- [USECASE_AUDIO_RECORD] = {0, 0},
- [USECASE_AUDIO_RECORD_LOW_LATENCY] = {15, 15},
- [USECASE_VOICE_CALL] = {2, 2},
+ [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {DEEP_BUFFER_PCM_DEVICE,
+ DEEP_BUFFER_PCM_DEVICE},
+ [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
+ LOWLATENCY_PCM_DEVICE},
+ [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {MULTIMEDIA2_PCM_DEVICE,
+ MULTIMEDIA2_PCM_DEVICE},
+ [USECASE_AUDIO_PLAYBACK_OFFLOAD] =
+ {PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
+ [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,
+ LOWLATENCY_PCM_DEVICE},
+ [USECASE_AUDIO_RECORD_FM_VIRTUAL] = {MULTIMEDIA2_PCM_DEVICE,
+ MULTIMEDIA2_PCM_DEVICE},
+ [USECASE_AUDIO_PLAYBACK_FM] = {FM_PLAYBACK_PCM_DEVICE, FM_CAPTURE_PCM_DEVICE},
+ [USECASE_AUDIO_HFP_SCO] = {HFP_PCM_RX, HFP_SCO_RX},
+ [USECASE_AUDIO_HFP_SCO_WB] = {HFP_PCM_RX, HFP_SCO_RX},
+ [USECASE_VOICE_CALL] = {VOICE_CALL_PCM_DEVICE, VOICE_CALL_PCM_DEVICE},
+ [USECASE_VOICE2_CALL] = {VOICE2_CALL_PCM_DEVICE, VOICE2_CALL_PCM_DEVICE},
+ [USECASE_VOLTE_CALL] = {VOLTE_CALL_PCM_DEVICE, VOLTE_CALL_PCM_DEVICE},
+ [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE, QCHAT_CALL_PCM_DEVICE},
+ [USECASE_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},
+ [USECASE_INCALL_REC_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
+ AUDIO_RECORD_PCM_DEVICE},
+ [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
+ AUDIO_RECORD_PCM_DEVICE},
+ [USECASE_INCALL_REC_UPLINK_COMPRESS] = {COMPRESS_CAPTURE_DEVICE,
+ COMPRESS_CAPTURE_DEVICE},
+ [USECASE_INCALL_REC_DOWNLINK_COMPRESS] = {COMPRESS_CAPTURE_DEVICE,
+ COMPRESS_CAPTURE_DEVICE},
+ [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK_COMPRESS] = {COMPRESS_CAPTURE_DEVICE,
+ COMPRESS_CAPTURE_DEVICE},
+ [USECASE_INCALL_MUSIC_UPLINK] = {INCALL_MUSIC_UPLINK_PCM_DEVICE,
+ INCALL_MUSIC_UPLINK_PCM_DEVICE},
+ [USECASE_INCALL_MUSIC_UPLINK2] = {INCALL_MUSIC_UPLINK2_PCM_DEVICE,
+ INCALL_MUSIC_UPLINK2_PCM_DEVICE},
+ [USECASE_AUDIO_SPKR_CALIB_RX] = {SPKR_PROT_CALIB_RX_PCM_DEVICE, -1},
+ [USECASE_AUDIO_SPKR_CALIB_TX] = {-1, SPKR_PROT_CALIB_TX_PCM_DEVICE},
};
/* Array to store sound devices */
@@ -100,109 +178,219 @@
[SND_DEVICE_OUT_HDMI] = "hdmi",
[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
[SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
- [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = "voice-handset-tmus",
+ [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
[SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
[SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
+ [SND_DEVICE_OUT_AFE_PROXY] = "afe-proxy",
+ [SND_DEVICE_OUT_USB_HEADSET] = "usb-headphones",
+ [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = "speaker-and-usb-headphones",
+ [SND_DEVICE_OUT_TRANSMISSION_FM] = "transmission-fm",
+ [SND_DEVICE_OUT_ANC_HEADSET] = "anc-headphones",
+ [SND_DEVICE_OUT_ANC_FB_HEADSET] = "anc-fb-headphones",
+ [SND_DEVICE_OUT_VOICE_ANC_HEADSET] = "voice-anc-headphones",
+ [SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET] = "voice-anc-fb-headphones",
+ [SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET] = "speaker-and-anc-headphones",
+ [SND_DEVICE_OUT_ANC_HANDSET] = "anc-handset",
+ [SND_DEVICE_OUT_SPEAKER_PROTECTED] = "speaker-protected",
/* Capture sound devices */
[SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
- [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
- [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
[SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic",
- [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "voice-speaker-mic",
- [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
+ [SND_DEVICE_IN_HANDSET_MIC_NS] = "handset-mic",
+ [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = "handset-mic",
+ [SND_DEVICE_IN_HANDSET_DMIC] = "dmic-endfire",
+ [SND_DEVICE_IN_HANDSET_DMIC_AEC] = "dmic-endfire",
+ [SND_DEVICE_IN_HANDSET_DMIC_NS] = "dmic-endfire",
+ [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = "dmic-endfire",
+ [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
+ [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "speaker-mic",
+ [SND_DEVICE_IN_SPEAKER_MIC_NS] = "speaker-mic",
+ [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = "speaker-mic",
+ [SND_DEVICE_IN_SPEAKER_DMIC] = "speaker-dmic-endfire",
+ [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = "speaker-dmic-endfire",
+ [SND_DEVICE_IN_SPEAKER_DMIC_NS] = "speaker-dmic-endfire",
+ [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = "speaker-dmic-endfire",
+ [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
+ [SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = "headset-mic",
[SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
[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_WB] = "bt-sco-mic-wb",
[SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
- [SND_DEVICE_IN_VOICE_DMIC_EF] = "voice-dmic-ef",
- [SND_DEVICE_IN_VOICE_DMIC_BS] = "voice-dmic-bs",
- [SND_DEVICE_IN_VOICE_DMIC_EF_TMUS] = "voice-dmic-ef-tmus",
- [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_EF] = "voice-speaker-dmic-ef",
- [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BS] = "voice-speaker-dmic-bs",
+ [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
+ [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
+ [SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = "voice-speaker-qmic",
[SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
[SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
[SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
[SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
- [SND_DEVICE_IN_VOICE_REC_DMIC_EF] = "voice-rec-dmic-ef",
- [SND_DEVICE_IN_VOICE_REC_DMIC_BS] = "voice-rec-dmic-bs",
- [SND_DEVICE_IN_VOICE_REC_DMIC_EF_FLUENCE] = "voice-rec-dmic-ef-fluence",
- [SND_DEVICE_IN_VOICE_REC_DMIC_BS_FLUENCE] = "voice-rec-dmic-bs-fluence",
+ [SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic",
+ [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef",
+ [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = "voice-rec-dmic-ef-fluence",
+ [SND_DEVICE_IN_USB_HEADSET_MIC] = "usb-headset-mic",
+ [SND_DEVICE_IN_CAPTURE_FM] = "capture-fm",
+ [SND_DEVICE_IN_AANC_HANDSET_MIC] = "aanc-handset-mic",
+ [SND_DEVICE_IN_QUAD_MIC] = "quad-mic",
+ [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = "handset-stereo-dmic-ef",
+ [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = "speaker-stereo-dmic-ef",
+ [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = "vi-feedback",
};
/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
-static const int acdb_device_table[SND_DEVICE_MAX] = {
+static int acdb_device_table[SND_DEVICE_MAX] = {
[SND_DEVICE_NONE] = -1,
[SND_DEVICE_OUT_HANDSET] = 7,
- [SND_DEVICE_OUT_SPEAKER] = 15,
- [SND_DEVICE_OUT_SPEAKER_REVERSE] = 15,
+ [SND_DEVICE_OUT_SPEAKER] = 14,
+ [SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
[SND_DEVICE_OUT_HEADPHONES] = 10,
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
[SND_DEVICE_OUT_VOICE_HANDSET] = 7,
- [SND_DEVICE_OUT_VOICE_SPEAKER] = 15,
+ [SND_DEVICE_OUT_VOICE_SPEAKER] = 14,
[SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
[SND_DEVICE_OUT_HDMI] = 18,
- [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 15,
+ [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14,
[SND_DEVICE_OUT_BT_SCO] = 22,
- [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = 81,
+ [SND_DEVICE_OUT_BT_SCO_WB] = 39,
[SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
[SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
[SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
+ [SND_DEVICE_OUT_AFE_PROXY] = 0,
+ [SND_DEVICE_OUT_USB_HEADSET] = 45,
+ [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = 14,
+ [SND_DEVICE_OUT_TRANSMISSION_FM] = 0,
+ [SND_DEVICE_OUT_ANC_HEADSET] = 26,
+ [SND_DEVICE_OUT_ANC_FB_HEADSET] = 27,
+ [SND_DEVICE_OUT_VOICE_ANC_HEADSET] = 26,
+ [SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET] = 27,
+ [SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET] = 26,
+ [SND_DEVICE_OUT_ANC_HANDSET] = 103,
+ [SND_DEVICE_OUT_SPEAKER_PROTECTED] = 101,
[SND_DEVICE_IN_HANDSET_MIC] = 4,
- [SND_DEVICE_IN_SPEAKER_MIC] = 4, /* ToDo: Check if this needs to changed to 11 */
+ [SND_DEVICE_IN_HANDSET_MIC_AEC] = 106,
+ [SND_DEVICE_IN_HANDSET_MIC_NS] = 107,
+ [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = 108,
+ [SND_DEVICE_IN_HANDSET_DMIC] = 41,
+ [SND_DEVICE_IN_HANDSET_DMIC_AEC] = 109,
+ [SND_DEVICE_IN_HANDSET_DMIC_NS] = 110,
+ [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = 111,
+ [SND_DEVICE_IN_SPEAKER_MIC] = 11,
+ [SND_DEVICE_IN_SPEAKER_MIC_AEC] = 112,
+ [SND_DEVICE_IN_SPEAKER_MIC_NS] = 113,
+ [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = 114,
+ [SND_DEVICE_IN_SPEAKER_DMIC] = 43,
+ [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = 115,
+ [SND_DEVICE_IN_SPEAKER_DMIC_NS] = 116,
+ [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = 117,
[SND_DEVICE_IN_HEADSET_MIC] = 8,
- [SND_DEVICE_IN_HANDSET_MIC_AEC] = 40,
- [SND_DEVICE_IN_SPEAKER_MIC_AEC] = 42,
- [SND_DEVICE_IN_HEADSET_MIC_AEC] = 47,
+ [SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = 47,
[SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
[SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
[SND_DEVICE_IN_HDMI_MIC] = 4,
[SND_DEVICE_IN_BT_SCO_MIC] = 21,
- [SND_DEVICE_IN_CAMCORDER_MIC] = 61,
- [SND_DEVICE_IN_VOICE_DMIC_EF] = 41,
- [SND_DEVICE_IN_VOICE_DMIC_BS] = 5,
- [SND_DEVICE_IN_VOICE_DMIC_EF_TMUS] = 91,
- [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_EF] = 43,
- [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BS] = 12,
+ [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
+ [SND_DEVICE_IN_CAMCORDER_MIC] = 4,
+ [SND_DEVICE_IN_VOICE_DMIC] = 41,
+ [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
+ [SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = 19,
[SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
[SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36,
[SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16,
- [SND_DEVICE_IN_VOICE_REC_MIC] = 62,
- /* TODO: Update with proper acdb ids */
- [SND_DEVICE_IN_VOICE_REC_DMIC_EF] = 62,
- [SND_DEVICE_IN_VOICE_REC_DMIC_BS] = 62,
- [SND_DEVICE_IN_VOICE_REC_DMIC_EF_FLUENCE] = 6,
- [SND_DEVICE_IN_VOICE_REC_DMIC_BS_FLUENCE] = 5,
+ [SND_DEVICE_IN_VOICE_REC_MIC] = 4,
+ [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 107,
+ [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 34,
+ [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = 41,
+ [SND_DEVICE_IN_USB_HEADSET_MIC] = 44,
+ [SND_DEVICE_IN_CAPTURE_FM] = 0,
+ [SND_DEVICE_IN_AANC_HANDSET_MIC] = 104,
+ [SND_DEVICE_IN_QUAD_MIC] = 46,
+ [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = 34,
+ [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = 35,
+ [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = 102,
};
-static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT;
-static bool is_tmus = false;
+struct snd_device_index {
+ char name[100];
+ unsigned int index;
+};
-static void check_operator()
-{
- char value[PROPERTY_VALUE_MAX];
- int mccmnc;
- property_get("gsm.sim.operator.numeric",value,"0");
- mccmnc = atoi(value);
- ALOGD("%s: tmus mccmnc %d", __func__, mccmnc);
- switch(mccmnc) {
- /* TMUS MCC(310), MNC(490, 260, 026) */
- case 310490:
- case 310260:
- case 310026:
- is_tmus = true;
- break;
- }
-}
+#define TO_NAME_INDEX(X) #X, X
-bool is_operator_tmus()
-{
- pthread_once(&check_op_once_ctl, check_operator);
- return is_tmus;
-}
+/* Used to get index from parsed sting */
+struct snd_device_index snd_device_name_index[SND_DEVICE_MAX] = {
+ {TO_NAME_INDEX(SND_DEVICE_OUT_HANDSET)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_AFE_PROXY)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_USB_HEADSET)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_TRANSMISSION_FM)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_ANC_HEADSET)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_ANC_FB_HEADSET)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_ANC_HEADSET)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_ANC_HANDSET)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_PROTECTED)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_NS)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_NS)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_NS)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC_FLUENCE)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_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_WB)},
+ {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)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_QMIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_NS)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_STEREO)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_USB_HEADSET_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_FM)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_AANC_HANDSET_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_QUAD_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_STEREO_DMIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_STEREO_DMIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK)},
+};
+
+#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
+#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
static int set_echo_reference(struct mixer *mixer, const char* ec_ref)
{
@@ -220,45 +408,235 @@
return 0;
}
+static struct csd_data *open_csd_client()
+{
+ struct csd_data *csd = calloc(1, sizeof(struct csd_data));
+
+ csd->csd_client = dlopen(LIB_CSD_CLIENT, RTLD_NOW);
+ if (csd->csd_client == NULL) {
+ ALOGE("%s: DLOPEN failed for %s", __func__, LIB_CSD_CLIENT);
+ goto error;
+ } else {
+ ALOGV("%s: DLOPEN successful for %s", __func__, LIB_CSD_CLIENT);
+
+ csd->deinit = (deinit_t)dlsym(csd->csd_client,
+ "csd_client_deinit");
+ if (csd->deinit == NULL) {
+ ALOGE("%s: dlsym error %s for csd_client_deinit", __func__,
+ dlerror());
+ goto error;
+ }
+ csd->disable_device = (disable_device_t)dlsym(csd->csd_client,
+ "csd_client_disable_device");
+ if (csd->disable_device == NULL) {
+ ALOGE("%s: dlsym error %s for csd_client_disable_device",
+ __func__, dlerror());
+ goto error;
+ }
+ csd->enable_device_config = (enable_device_config_t)dlsym(csd->csd_client,
+ "csd_client_enable_device_config");
+ if (csd->enable_device_config == NULL) {
+ ALOGE("%s: dlsym error %s for csd_client_enable_device_config",
+ __func__, dlerror());
+ goto error;
+ }
+ csd->enable_device = (enable_device_t)dlsym(csd->csd_client,
+ "csd_client_enable_device");
+ if (csd->enable_device == NULL) {
+ ALOGE("%s: dlsym error %s for csd_client_enable_device",
+ __func__, dlerror());
+ goto error;
+ }
+ csd->start_voice = (start_voice_t)dlsym(csd->csd_client,
+ "csd_client_start_voice");
+ if (csd->start_voice == NULL) {
+ ALOGE("%s: dlsym error %s for csd_client_start_voice",
+ __func__, dlerror());
+ goto error;
+ }
+ csd->stop_voice = (stop_voice_t)dlsym(csd->csd_client,
+ "csd_client_stop_voice");
+ if (csd->stop_voice == NULL) {
+ ALOGE("%s: dlsym error %s for csd_client_stop_voice",
+ __func__, dlerror());
+ goto error;
+ }
+ csd->volume = (volume_t)dlsym(csd->csd_client,
+ "csd_client_volume");
+ if (csd->volume == NULL) {
+ ALOGE("%s: dlsym error %s for csd_client_volume",
+ __func__, dlerror());
+ goto error;
+ }
+ csd->mic_mute = (mic_mute_t)dlsym(csd->csd_client,
+ "csd_client_mic_mute");
+ if (csd->mic_mute == NULL) {
+ ALOGE("%s: dlsym error %s for csd_client_mic_mute",
+ __func__, dlerror());
+ goto error;
+ }
+ csd->slow_talk = (slow_talk_t)dlsym(csd->csd_client,
+ "csd_client_slow_talk");
+ if (csd->slow_talk == NULL) {
+ ALOGE("%s: dlsym error %s for csd_client_slow_talk",
+ __func__, dlerror());
+ goto error;
+ }
+ csd->start_playback = (start_playback_t)dlsym(csd->csd_client,
+ "csd_client_start_playback");
+ if (csd->start_playback == NULL) {
+ ALOGE("%s: dlsym error %s for csd_client_start_playback",
+ __func__, dlerror());
+ goto error;
+ }
+ csd->stop_playback = (stop_playback_t)dlsym(csd->csd_client,
+ "csd_client_stop_playback");
+ if (csd->stop_playback == NULL) {
+ ALOGE("%s: dlsym error %s for csd_client_stop_playback",
+ __func__, dlerror());
+ goto error;
+ }
+ csd->start_record = (start_record_t)dlsym(csd->csd_client,
+ "csd_client_start_record");
+ if (csd->start_record == NULL) {
+ ALOGE("%s: dlsym error %s for csd_client_start_record",
+ __func__, dlerror());
+ goto error;
+ }
+ csd->stop_record = (stop_record_t)dlsym(csd->csd_client,
+ "csd_client_stop_record");
+ if (csd->stop_record == NULL) {
+ ALOGE("%s: dlsym error %s for csd_client_stop_record",
+ __func__, dlerror());
+ goto error;
+ }
+ csd->init = (init_t)dlsym(csd->csd_client, "csd_client_init");
+
+ if (csd->init == NULL) {
+ ALOGE("%s: dlsym error %s for csd_client_init",
+ __func__, dlerror());
+ goto error;
+ } else {
+ csd->init();
+ }
+ }
+ return csd;
+
+error:
+ free(csd);
+ csd = NULL;
+ return csd;
+}
+
+void close_csd_client(struct csd_data *csd)
+{
+ if (csd != NULL) {
+ csd->deinit();
+ dlclose(csd->csd_client);
+ free(csd);
+ csd = NULL;
+ }
+}
+
void *platform_init(struct audio_device *adev)
{
+ char platform[PROPERTY_VALUE_MAX];
+ char baseband[PROPERTY_VALUE_MAX];
char value[PROPERTY_VALUE_MAX];
- struct platform_data *my_data;
+ struct platform_data *my_data = NULL;
+ int retry_num = 0, snd_card_num = 0;
+ const char *snd_card_name;
my_data = calloc(1, sizeof(struct platform_data));
+ while (snd_card_num < MAX_SND_CARD) {
+ adev->mixer = mixer_open(snd_card_num);
+
+ while (!adev->mixer && retry_num < RETRY_NUMBER) {
+ usleep(RETRY_US);
+ adev->mixer = mixer_open(snd_card_num);
+ retry_num++;
+ }
+
+ if (!adev->mixer) {
+ ALOGE("%s: Unable to open the mixer card: %d", __func__,
+ snd_card_num);
+ retry_num = 0;
+ snd_card_num++;
+ continue;
+ }
+
+ snd_card_name = mixer_get_name(adev->mixer);
+ ALOGV("%s: snd_card_name: %s", __func__, snd_card_name);
+
+ my_data->hw_info = hw_info_init(snd_card_name);
+ if (!my_data->hw_info) {
+ ALOGE("%s: Failed to init hardware info", __func__);
+ } else {
+ if (audio_extn_read_xml(adev, snd_card_num, MIXER_XML_PATH,
+ MIXER_XML_PATH_AUXPCM) == -ENOSYS)
+ adev->audio_route = audio_route_init(snd_card_num,
+ MIXER_XML_PATH);
+ if (!adev->audio_route) {
+ ALOGE("%s: Failed to init audio route controls, aborting.",
+ __func__);
+ free(my_data);
+ return NULL;
+ }
+ adev->snd_card = snd_card_num;
+ ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
+ break;
+ }
+ retry_num = 0;
+ snd_card_num++;
+ }
+
+ if (snd_card_num >= MAX_SND_CARD) {
+ ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
+ free(my_data);
+ return NULL;
+ }
+
my_data->adev = adev;
- my_data->dualmic_config = DUALMIC_CONFIG_NONE;
+ my_data->btsco_sample_rate = SAMPLE_RATE_8KHZ;
my_data->fluence_in_spkr_mode = false;
my_data->fluence_in_voice_call = false;
my_data->fluence_in_voice_rec = false;
+ my_data->fluence_in_audio_rec = false;
+ my_data->fluence_type = FLUENCE_NONE;
- property_get("persist.audio.dualmic.config",value,"");
- if (!strcmp("broadside", value)) {
- my_data->dualmic_config = DUALMIC_CONFIG_BROADSIDE;
- adev->acdb_settings |= DMIC_FLAG;
- } else if (!strcmp("endfire", value)) {
- my_data->dualmic_config = DUALMIC_CONFIG_ENDFIRE;
- adev->acdb_settings |= DMIC_FLAG;
+ property_get("ro.qc.sdk.audio.fluencetype", value, "");
+ if (!strncmp("fluencepro", value, sizeof("fluencepro"))) {
+ my_data->fluence_type = FLUENCE_QUAD_MIC | FLUENCE_DUAL_MIC;
+ } else if (!strncmp("fluence", value, sizeof("fluence"))) {
+ my_data->fluence_type = FLUENCE_DUAL_MIC;
+ } else {
+ my_data->fluence_type = FLUENCE_NONE;
}
- if (my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
+ if (my_data->fluence_type != FLUENCE_NONE) {
property_get("persist.audio.fluence.voicecall",value,"");
- if (!strcmp("true", value)) {
+ if (!strncmp("true", value, sizeof("true"))) {
my_data->fluence_in_voice_call = true;
}
property_get("persist.audio.fluence.voicerec",value,"");
- if (!strcmp("true", value)) {
+ if (!strncmp("true", value, sizeof("true"))) {
my_data->fluence_in_voice_rec = true;
}
+ property_get("persist.audio.fluence.audiorec",value,"");
+ if (!strncmp("true", value, sizeof("true"))) {
+ my_data->fluence_in_audio_rec = true;
+ }
+
property_get("persist.audio.fluence.speaker",value,"");
- if (!strcmp("true", value)) {
+ if (!strncmp("true", value, sizeof("true"))) {
my_data->fluence_in_spkr_mode = 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) {
ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
@@ -266,27 +644,60 @@
ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
my_data->acdb_deallocate = (acdb_deallocate_t)dlsym(my_data->acdb_handle,
"acdb_loader_deallocate_ACDB");
+ if (!my_data->acdb_deallocate)
+ ALOGE("%s: Could not find the symbol acdb_loader_deallocate_ACDB from %s",
+ __func__, LIB_ACDB_LOADER);
+
my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle,
"acdb_loader_send_audio_cal");
if (!my_data->acdb_send_audio_cal)
- ALOGW("%s: Could not find the symbol acdb_send_audio_cal from %s",
+ ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
__func__, LIB_ACDB_LOADER);
+
my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle,
"acdb_loader_send_voice_cal");
+ if (!my_data->acdb_send_voice_cal)
+ ALOGE("%s: Could not find the symbol acdb_loader_send_voice_cal from %s",
+ __func__, LIB_ACDB_LOADER);
+
+ my_data->acdb_reload_vocvoltable = (acdb_reload_vocvoltable_t)dlsym(my_data->acdb_handle,
+ "acdb_loader_reload_vocvoltable");
+ if (!my_data->acdb_reload_vocvoltable)
+ ALOGE("%s: Could not find the symbol acdb_loader_reload_vocvoltable from %s",
+ __func__, LIB_ACDB_LOADER);
+
my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
- "acdb_loader_init_ACDB");
+ "acdb_loader_init_v2");
if (my_data->acdb_init == NULL)
- ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror());
+ ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
else
- my_data->acdb_init();
+ my_data->acdb_init(snd_card_name);
}
+ /* Initialize ACDB ID's */
+ platform_info_init(PLATFORM_INFO_XML_PATH);
+
+ /* init usb */
+ audio_extn_usb_init(adev);
+ /* update sound cards appropriately */
+ audio_extn_usb_set_proxy_sound_card(adev->snd_card);
+
+ /* Read one time ssr property */
+ audio_extn_ssr_update_enabled();
+ audio_extn_spkr_prot_init(adev);
return my_data;
}
void platform_deinit(void *platform)
{
+ struct platform_data *my_data = (struct platform_data *)platform;
+
+ hw_info_deinit(my_data->hw_info);
+ close_csd_client(my_data->csd);
+
free(platform);
+ /* deinit usb */
+ audio_extn_usb_deinit();
}
const char *platform_get_snd_device_name(snd_device_t snd_device)
@@ -297,16 +708,49 @@
return "";
}
+int platform_get_snd_device_name_extn(void *platform, snd_device_t snd_device,
+ char *device_name)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+
+ if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
+ strlcpy(device_name, device_table[snd_device], DEVICE_NAME_MAX_SIZE);
+ hw_info_append_hw_type(my_data->hw_info, snd_device, device_name);
+ } else {
+ strlcpy(device_name, "", DEVICE_NAME_MAX_SIZE);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
void platform_add_backend_name(char *mixer_path, snd_device_t snd_device)
{
if (snd_device == SND_DEVICE_IN_BT_SCO_MIC)
- strcat(mixer_path, " bt-sco");
+ strlcat(mixer_path, " bt-sco", MIXER_PATH_MAX_LENGTH);
+ else if (snd_device == SND_DEVICE_IN_BT_SCO_MIC_WB)
+ strlcat(mixer_path, " bt-sco-wb", MIXER_PATH_MAX_LENGTH);
else if(snd_device == SND_DEVICE_OUT_BT_SCO)
- strcat(mixer_path, " bt-sco");
+ strlcat(mixer_path, " bt-sco", MIXER_PATH_MAX_LENGTH);
+ else if(snd_device == SND_DEVICE_OUT_BT_SCO_WB)
+ strlcat(mixer_path, " bt-sco-wb", MIXER_PATH_MAX_LENGTH);
else if (snd_device == SND_DEVICE_OUT_HDMI)
- strcat(mixer_path, " hdmi");
+ strlcat(mixer_path, " hdmi", MIXER_PATH_MAX_LENGTH);
else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HDMI)
- strcat(mixer_path, " speaker-and-hdmi");
+ strlcat(mixer_path, " speaker-and-hdmi", MIXER_PATH_MAX_LENGTH);
+ else if (snd_device == SND_DEVICE_OUT_AFE_PROXY)
+ strlcat(mixer_path, " afe-proxy", MIXER_PATH_MAX_LENGTH);
+ else if (snd_device == SND_DEVICE_OUT_USB_HEADSET)
+ strlcat(mixer_path, " usb-headphones", MIXER_PATH_MAX_LENGTH);
+ else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET)
+ strlcat(mixer_path, " speaker-and-usb-headphones",
+ MIXER_PATH_MAX_LENGTH);
+ else if (snd_device == SND_DEVICE_IN_USB_HEADSET_MIC)
+ strlcat(mixer_path, " usb-headset-mic", MIXER_PATH_MAX_LENGTH);
+ else if (snd_device == SND_DEVICE_IN_CAPTURE_FM)
+ strlcat(mixer_path, " capture-fm", MIXER_PATH_MAX_LENGTH);
+ else if (snd_device == SND_DEVICE_OUT_TRANSMISSION_FM)
+ strlcat(mixer_path, " transmission-fm", MIXER_PATH_MAX_LENGTH);
}
int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
@@ -319,6 +763,46 @@
return device_id;
}
+int platform_get_snd_device_index(char *snd_device_index_name)
+{
+ int ret = 0;
+ int i;
+
+ if (snd_device_index_name == NULL) {
+ ALOGE("%s: snd_device_index_name is NULL", __func__);
+ ret = -ENODEV;
+ goto done;
+ }
+
+ for (i=0; i < SND_DEVICE_MAX; i++) {
+ if(strcmp(snd_device_name_index[i].name, snd_device_index_name) == 0) {
+ ret = snd_device_name_index[i].index;
+ goto done;
+ }
+ }
+ ALOGE("%s: Could not find index for snd_device_index_name = %s",
+ __func__, snd_device_index_name);
+ ret = -ENODEV;
+done:
+ return ret;
+}
+
+int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
+{
+ int ret = 0;
+
+ if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
+ ALOGE("%s: Invalid snd_device = %d",
+ __func__, snd_device);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ acdb_device_table[snd_device] = acdb_id;
+done:
+ return ret;
+}
+
int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
{
struct platform_data *my_data = (struct platform_data *)platform;
@@ -331,7 +815,7 @@
return -EINVAL;
}
if (my_data->acdb_send_audio_cal) {
- ALOGD("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
+ ("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
__func__, snd_device, acdb_dev_id);
if (snd_device >= SND_DEVICE_OUT_BEGIN &&
snd_device < SND_DEVICE_OUT_END)
@@ -345,8 +829,46 @@
int platform_switch_voice_call_device_pre(void *platform)
{
- return 0;
+ struct platform_data *my_data = (struct platform_data *)platform;
+ int ret = 0;
+
+ if (my_data->csd != NULL &&
+ my_data->adev->mode == AUDIO_MODE_IN_CALL) {
+ /* This must be called before disabling mixer controls on APQ side */
+ ret = my_data->csd->disable_device();
+ if (ret < 0) {
+ ALOGE("%s: csd_client_disable_device, failed, error %d",
+ __func__, ret);
+ }
+ }
+ return ret;
}
+int platform_switch_voice_call_enable_device_config(void *platform,
+ snd_device_t out_snd_device,
+ snd_device_t in_snd_device)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ int acdb_rx_id, acdb_tx_id;
+ int ret = 0;
+
+ acdb_rx_id = acdb_device_table[out_snd_device];
+ acdb_tx_id = acdb_device_table[in_snd_device];
+
+ if (my_data->csd != NULL) {
+ if (acdb_rx_id > 0 && acdb_tx_id > 0) {
+ ret = my_data->csd->enable_device_config(acdb_rx_id, acdb_tx_id);
+ if (ret < 0) {
+ ALOGE("%s: csd_enable_device_config, failed, error %d",
+ __func__, ret);
+ }
+ } else {
+ ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
+ acdb_rx_id, acdb_tx_id);
+ }
+ }
+ return ret;
+}
+
int platform_switch_voice_call_device_post(void *platform,
snd_device_t out_snd_device,
@@ -371,12 +893,61 @@
return 0;
}
-int platform_start_voice_call(void *platform)
+int platform_switch_voice_call_usecase_route_post(void *platform,
+ snd_device_t out_snd_device,
+ snd_device_t in_snd_device)
{
- return 0;
+ struct platform_data *my_data = (struct platform_data *)platform;
+ int acdb_rx_id, acdb_tx_id;
+ int ret = 0;
+
+ acdb_rx_id = acdb_device_table[out_snd_device];
+ acdb_tx_id = acdb_device_table[in_snd_device];
+
+ if (my_data->csd != NULL) {
+ if (acdb_rx_id > 0 && acdb_tx_id > 0) {
+ ret = my_data->csd->enable_device(acdb_rx_id, acdb_tx_id,
+ my_data->adev->acdb_settings);
+ if (ret < 0) {
+ ALOGE("%s: csd_enable_device, failed, error %d",
+ __func__, ret);
+ }
+ } else {
+ ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
+ acdb_rx_id, acdb_tx_id);
+ }
+ }
+ return ret;
}
-int platform_stop_voice_call(void *platform)
+int platform_start_voice_call(void *platform, uint32_t vsid)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ int ret = 0;
+
+ if (my_data->csd != NULL) {
+ ret = my_data->csd->start_voice(vsid);
+ if (ret < 0) {
+ ALOGE("%s: csd_start_voice error %d\n", __func__, ret);
+ }
+ }
+ return ret;
+}
+
+int platform_stop_voice_call(void *platform, uint32_t vsid)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ int ret = 0;
+
+ if (my_data->csd != NULL) {
+ ret = my_data->csd->stop_voice(vsid);
+ if (ret < 0) {
+ ALOGE("%s: csd_stop_voice error %d\n", __func__, ret);
+ }
+ }
+ return ret;
+}
+int platform_get_sample_rate(void *platform, uint32_t *rate)
{
return 0;
}
@@ -386,12 +957,17 @@
struct platform_data *my_data = (struct platform_data *)platform;
struct audio_device *adev = my_data->adev;
struct mixer_ctl *ctl;
- const char *mixer_ctl_name = "Voice Rx Volume";
+ const char *mixer_ctl_name = "Voice Rx Gain";
+ int vol_index = 0, ret = 0;
+ uint32_t set_values[ ] = {0,
+ ALL_SESSION_VSID,
+ DEFAULT_VOLUME_RAMP_DURATION_MS};
// Voice volume levels are mapped to adsp volume levels as follows.
// 100 -> 5, 80 -> 4, 60 -> 3, 40 -> 2, 20 -> 1 0 -> 0
// But this values don't changed in kernel. So, below change is need.
- volume = volume / 20;
+ vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, MAX_VOL_INDEX);
+ set_values[0] = vol_index;
ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
if (!ctl) {
@@ -399,10 +975,16 @@
__func__, mixer_ctl_name);
return -EINVAL;
}
- ALOGV("Setting voice volume: %d", volume);
- mixer_ctl_set_value(ctl, 0, volume);
+ ALOGV("Setting voice volume index: %d", set_values[0]);
+ mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
- return 0;
+ if (my_data->csd != NULL) {
+ ret = my_data->csd->volume(ALL_SESSION_VSID, volume);
+ if (ret < 0) {
+ ALOGE("%s: csd_volume error %d", __func__, ret);
+ }
+ }
+ return ret;
}
int platform_set_mic_mute(void *platform, bool state)
@@ -411,19 +993,28 @@
struct audio_device *adev = my_data->adev;
struct mixer_ctl *ctl;
const char *mixer_ctl_name = "Voice Tx Mute";
+ int ret = 0;
+ uint32_t set_values[ ] = {0,
+ ALL_SESSION_VSID,
+ DEFAULT_VOLUME_RAMP_DURATION_MS};
- if (adev->mode == AUDIO_MODE_IN_CALL) {
- ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
- if (!ctl) {
- ALOGE("%s: Could not get ctl for mixer cmd - %s",
- __func__, mixer_ctl_name);
- return -EINVAL;
- }
- ALOGV("Setting mic mute: %d", state);
- mixer_ctl_set_value(ctl, 0, state);
+ set_values[0] = state;
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s",
+ __func__, mixer_ctl_name);
+ return -EINVAL;
}
+ ALOGV("Setting voice mute state: %d", state);
+ mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
- return 0;
+ if (my_data->csd != NULL) {
+ ret = my_data->csd->mic_mute(ALL_SESSION_VSID, state);
+ if (ret < 0) {
+ ALOGE("%s: csd_mic_mute error %d", __func__, ret);
+ }
+ }
+ return ret;
}
snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
@@ -433,6 +1024,10 @@
audio_mode_t mode = adev->mode;
snd_device_t snd_device = SND_DEVICE_NONE;
+ audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
+ AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
+ int channel_count = popcount(channel_mask);
+
ALOGV("%s: enter: output devices(%#x)", __func__, devices);
if (devices == AUDIO_DEVICE_NONE ||
devices & AUDIO_DEVICE_BIT_IN) {
@@ -440,42 +1035,22 @@
goto exit;
}
- if (mode == AUDIO_MODE_IN_CALL) {
- if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
- devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
- if (adev->tty_mode == TTY_MODE_FULL)
- snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
- else if (adev->tty_mode == TTY_MODE_VCO)
- snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
- else if (adev->tty_mode == TTY_MODE_HCO)
- snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
- else
- snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
- } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
- snd_device = SND_DEVICE_OUT_BT_SCO;
- } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
- snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
- } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
- if (is_operator_tmus())
- snd_device = SND_DEVICE_OUT_VOICE_HANDSET_TMUS;
- else
- snd_device = SND_DEVICE_OUT_HANDSET;
- }
- if (snd_device != SND_DEVICE_NONE) {
- goto exit;
- }
- }
-
if (popcount(devices) == 2) {
if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
AUDIO_DEVICE_OUT_SPEAKER)) {
snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
} else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
AUDIO_DEVICE_OUT_SPEAKER)) {
- snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
+ if (audio_extn_get_anc_enabled())
+ snd_device = SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET;
+ else
+ snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
} else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
AUDIO_DEVICE_OUT_SPEAKER)) {
snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
+ } else if (devices == (AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
+ AUDIO_DEVICE_OUT_SPEAKER)) {
+ snd_device = SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET;
} else {
ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
goto exit;
@@ -490,20 +1065,91 @@
goto exit;
}
+ 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) {
+ if ((adev->voice.tty_mode != TTY_MODE_OFF) &&
+ !voice_extn_compress_voip_is_active(adev)) {
+ switch (adev->voice.tty_mode) {
+ case TTY_MODE_FULL:
+ snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
+ break;
+ case TTY_MODE_VCO:
+ snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
+ break;
+ case TTY_MODE_HCO:
+ snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
+ break;
+ default:
+ ALOGE("%s: Invalid TTY mode (%#x)",
+ __func__, adev->voice.tty_mode);
+ }
+ } else if (audio_extn_get_anc_enabled()) {
+ if (audio_extn_should_use_fb_anc())
+ snd_device = SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET;
+ else
+ snd_device = SND_DEVICE_OUT_VOICE_ANC_HEADSET;
+ } else {
+ snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
+ }
+ } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
+ if (my_data->btsco_sample_rate == SAMPLE_RATE_16KHZ)
+ snd_device = SND_DEVICE_OUT_BT_SCO_WB;
+ else
+ snd_device = SND_DEVICE_OUT_BT_SCO;
+ } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
+ 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;
+ } else if (devices & AUDIO_DEVICE_OUT_FM_TX) {
+ snd_device = SND_DEVICE_OUT_TRANSMISSION_FM;
+ } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
+ if (audio_extn_should_use_handset_anc(channel_count))
+ snd_device = SND_DEVICE_OUT_ANC_HANDSET;
+ else
+ snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
+ }
+ if (snd_device != SND_DEVICE_NONE) {
+ goto exit;
+ }
+ }
+
if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
- snd_device = SND_DEVICE_OUT_HEADPHONES;
+ if (devices & AUDIO_DEVICE_OUT_WIRED_HEADSET
+ && audio_extn_get_anc_enabled()) {
+ if (audio_extn_should_use_fb_anc())
+ snd_device = SND_DEVICE_OUT_ANC_FB_HEADSET;
+ else
+ snd_device = SND_DEVICE_OUT_ANC_HEADSET;
+ }
+ else
+ snd_device = SND_DEVICE_OUT_HEADPHONES;
} else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
if (adev->speaker_lr_swap)
snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
else
snd_device = SND_DEVICE_OUT_SPEAKER;
} else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
- snd_device = SND_DEVICE_OUT_BT_SCO;
+ if (my_data->btsco_sample_rate == SAMPLE_RATE_16KHZ)
+ snd_device = SND_DEVICE_OUT_BT_SCO_WB;
+ else
+ snd_device = SND_DEVICE_OUT_BT_SCO;
} else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
snd_device = SND_DEVICE_OUT_HDMI ;
+ } else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
+ devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
+ snd_device = SND_DEVICE_OUT_USB_HEADSET;
+ } else if (devices & AUDIO_DEVICE_OUT_FM_TX) {
+ snd_device = SND_DEVICE_OUT_TRANSMISSION_FM;
} else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
snd_device = SND_DEVICE_OUT_HANDSET;
+ } else if (devices & AUDIO_DEVICE_OUT_PROXY) {
+ ALOGD("%s: setting sink capability for Proxy", __func__);
+ audio_extn_set_afe_proxy_channel_mixer(adev);
+ snd_device = SND_DEVICE_OUT_AFE_PROXY;
} else {
ALOGE("%s: Unknown device(s) %#x", __func__, devices);
}
@@ -526,18 +1172,17 @@
audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
snd_device_t snd_device = SND_DEVICE_NONE;
+ int channel_count = popcount(channel_mask);
ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
__func__, out_device, in_device);
- if (mode == AUDIO_MODE_IN_CALL) {
- if (out_device == AUDIO_DEVICE_NONE) {
- ALOGE("%s: No output device set for voice call", __func__);
- goto exit;
- }
- if (adev->tty_mode != TTY_MODE_OFF) {
+ if ((out_device != AUDIO_DEVICE_NONE) && ((mode == AUDIO_MODE_IN_CALL) ||
+ voice_extn_compress_voip_is_active(adev))) {
+ 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) {
- switch (adev->tty_mode) {
+ switch (adev->voice.tty_mode) {
case TTY_MODE_FULL:
snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
break;
@@ -548,37 +1193,43 @@
snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
break;
default:
- ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->tty_mode);
+ ALOGE("%s: Invalid TTY mode (%#x)",
+ __func__, adev->voice.tty_mode);
}
goto exit;
}
}
if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
- if (my_data->fluence_in_voice_call == false) {
+ if (out_device & AUDIO_DEVICE_OUT_EARPIECE &&
+ audio_extn_should_use_handset_anc(channel_count)) {
+ snd_device = SND_DEVICE_IN_AANC_HANDSET_MIC;
+ } else if (my_data->fluence_type == FLUENCE_NONE ||
+ my_data->fluence_in_voice_call == false) {
snd_device = SND_DEVICE_IN_HANDSET_MIC;
+ set_echo_reference(adev->mixer, EC_REF_RX);
} else {
- if (my_data->dualmic_config == DUALMIC_CONFIG_ENDFIRE) {
- if (is_operator_tmus())
- snd_device = SND_DEVICE_IN_VOICE_DMIC_EF_TMUS;
- else
- snd_device = SND_DEVICE_IN_VOICE_DMIC_EF;
- } else if(my_data->dualmic_config == DUALMIC_CONFIG_BROADSIDE)
- snd_device = SND_DEVICE_IN_VOICE_DMIC_BS;
- else
- snd_device = SND_DEVICE_IN_HANDSET_MIC;
+ snd_device = SND_DEVICE_IN_VOICE_DMIC;
+ adev->acdb_settings |= DMIC_FLAG;
}
} else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
} else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
- snd_device = SND_DEVICE_IN_BT_SCO_MIC ;
+ if (my_data->btsco_sample_rate == SAMPLE_RATE_16KHZ)
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
+ else
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC;
} else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
- if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode &&
- my_data->dualmic_config == DUALMIC_CONFIG_ENDFIRE) {
- snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC_EF;
- } else if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode &&
- my_data->dualmic_config == DUALMIC_CONFIG_BROADSIDE) {
- snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BS;
+ if (my_data->fluence_type != FLUENCE_NONE &&
+ my_data->fluence_in_voice_call &&
+ my_data->fluence_in_spkr_mode) {
+ if(my_data->fluence_type & FLUENCE_QUAD_MIC) {
+ adev->acdb_settings |= QMIC_FLAG;
+ snd_device = SND_DEVICE_IN_VOICE_SPEAKER_QMIC;
+ } else {
+ adev->acdb_settings |= DMIC_FLAG;
+ snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
+ }
} else {
snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
}
@@ -590,19 +1241,16 @@
}
} else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (my_data->dualmic_config == DUALMIC_CONFIG_ENDFIRE) {
- if (channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK)
- snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_EF;
- else if (my_data->fluence_in_voice_rec)
- snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_EF_FLUENCE;
- } else if (my_data->dualmic_config == DUALMIC_CONFIG_BROADSIDE) {
- if (channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK)
- snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_BS;
- else if (my_data->fluence_in_voice_rec)
- snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_BS_FLUENCE;
- }
-
- if (snd_device == SND_DEVICE_NONE) {
+ if (channel_count == 2) {
+ snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else if (adev->active_input->enable_ns)
+ snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
+ else if (my_data->fluence_type != FLUENCE_NONE &&
+ my_data->fluence_in_voice_rec) {
+ snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else {
snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
}
}
@@ -610,18 +1258,72 @@
if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
in_device = AUDIO_DEVICE_IN_BACK_MIC;
if (adev->active_input) {
- if (adev->active_input->enable_aec) {
+ if (adev->active_input->enable_aec &&
+ adev->active_input->enable_ns) {
if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
+ if (my_data->fluence_type & FLUENCE_DUAL_MIC &&
+ my_data->fluence_in_spkr_mode) {
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
} else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
+ if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
} else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
- snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
+ snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
}
- set_echo_reference(adev->mixer, "SLIM_RX");
+ set_echo_reference(adev->mixer, EC_REF_RX);
+ } else if (adev->active_input->enable_aec) {
+ if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
+ } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
+ } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
+ }
+ set_echo_reference(adev->mixer, EC_REF_RX);
+ } else if (adev->active_input->enable_ns) {
+ if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
+ if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
+ } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+ if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
+ adev->acdb_settings |= DMIC_FLAG;
+ } else
+ snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
+ } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+ snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
+ }
+ set_echo_reference(adev->mixer, "NONE");
} else
set_echo_reference(adev->mixer, "NONE");
}
+ } else if (source == AUDIO_SOURCE_MIC) {
+ if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&
+ channel_count == 1 ) {
+ if(my_data->fluence_type & FLUENCE_DUAL_MIC &&
+ my_data->fluence_in_audio_rec)
+ snd_device = SND_DEVICE_IN_HANDSET_DMIC;
+ }
+ } else if (source == AUDIO_SOURCE_FM_RX ||
+ source == AUDIO_SOURCE_FM_RX_A2DP) {
+ snd_device = SND_DEVICE_IN_CAPTURE_FM;
} else if (source == AUDIO_SOURCE_DEFAULT) {
goto exit;
}
@@ -635,15 +1337,28 @@
!(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
!(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- snd_device = SND_DEVICE_IN_HANDSET_MIC;
+ if (audio_extn_ssr_get_enabled() && channel_count == 6)
+ snd_device = SND_DEVICE_IN_QUAD_MIC;
+ else if (channel_count == 2)
+ snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
+ else
+ snd_device = SND_DEVICE_IN_HANDSET_MIC;
} else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
snd_device = SND_DEVICE_IN_SPEAKER_MIC;
} 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) {
- snd_device = SND_DEVICE_IN_BT_SCO_MIC ;
+ if (my_data->btsco_sample_rate == SAMPLE_RATE_16KHZ)
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
+ 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 ||
+ in_device & AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET) {
+ snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
+ } else if (in_device & AUDIO_DEVICE_IN_FM_RX) {
+ snd_device = SND_DEVICE_IN_CAPTURE_FM;
} else {
ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
ALOGW("%s: Using default handset-mic", __func__);
@@ -655,13 +1370,22 @@
} else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
snd_device = SND_DEVICE_IN_HEADSET_MIC;
} else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
- snd_device = SND_DEVICE_IN_SPEAKER_MIC;
+ if (channel_count > 1)
+ 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) {
snd_device = SND_DEVICE_IN_HANDSET_MIC;
} else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
- snd_device = SND_DEVICE_IN_BT_SCO_MIC;
+ if (my_data->btsco_sample_rate == SAMPLE_RATE_16KHZ)
+ snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
+ 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 ||
+ out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
+ snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
} else {
ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
ALOGW("%s: Using default handset-mic", __func__);
@@ -707,40 +1431,49 @@
return 0;
}
-int platform_edid_get_max_channels(void)
+int platform_edid_get_max_channels(void *platform)
{
- FILE *file;
- struct audio_block_header header;
+ struct platform_data *my_data = (struct platform_data *)platform;
+ struct audio_device *adev = my_data->adev;
char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE];
char *sad = block;
int num_audio_blocks;
int channel_count;
int max_channels = 0;
- int i;
+ int i, ret, count;
- file = fopen(AUDIO_DATA_BLOCK_PATH, "rb");
- if (file == NULL) {
- ALOGE("Unable to open '%s'", AUDIO_DATA_BLOCK_PATH);
+ struct mixer_ctl *ctl;
+
+ ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_DATA_BLOCK_MIXER_CTL);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s",
+ __func__, AUDIO_DATA_BLOCK_MIXER_CTL);
return 0;
}
- /* Read audio block header */
- fread(&header, 1, sizeof(header), file);
+ mixer_ctl_update(ctl);
+
+ count = mixer_ctl_get_num_values(ctl);
/* Read SAD blocks, clamping the maximum size for safety */
- if (header.length > (int)sizeof(block))
- header.length = (int)sizeof(block);
- fread(&block, header.length, 1, file);
+ if (count > (int)sizeof(block))
+ count = (int)sizeof(block);
- fclose(file);
+ ret = mixer_ctl_get_array(ctl, block, count);
+ if (ret != 0) {
+ ALOGE("%s: mixer_ctl_get_array() failed to get EDID info", __func__);
+ return 0;
+ }
/* Calculate the number of SAD blocks */
- num_audio_blocks = header.length / SAD_BLOCK_SIZE;
+ num_audio_blocks = count / SAD_BLOCK_SIZE;
for (i = 0; i < num_audio_blocks; i++) {
/* Only consider LPCM blocks */
- if ((sad[0] >> 3) != EDID_FORMAT_LPCM)
+ if ((sad[0] >> 3) != EDID_FORMAT_LPCM) {
+ sad += 3;
continue;
+ }
channel_count = (sad[0] & 0x7) + 1;
if (channel_count > max_channels)
@@ -752,3 +1485,321 @@
return max_channels;
}
+
+static int platform_set_slowtalk(struct platform_data *my_data, bool state)
+{
+ int ret = 0;
+ struct audio_device *adev = my_data->adev;
+ struct mixer_ctl *ctl;
+ const char *mixer_ctl_name = "Slowtalk Enable";
+ uint32_t set_values[ ] = {0,
+ ALL_SESSION_VSID};
+
+ set_values[0] = state;
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s",
+ __func__, mixer_ctl_name);
+ ret = -EINVAL;
+ } else {
+ ALOGV("Setting slowtalk state: %d", state);
+ ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
+ my_data->slowtalk = state;
+ }
+
+ if (my_data->csd != NULL) {
+ ret = my_data->csd->slow_talk(ALL_SESSION_VSID, state);
+ if (ret < 0) {
+ ALOGE("%s: csd_client_disable_device, failed, error %d",
+ __func__, ret);
+ }
+ }
+ return ret;
+}
+
+int platform_set_parameters(void *platform, struct str_parms *parms)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ char *str;
+ char value[256] = {0};
+ int val;
+ int ret = 0, err;
+
+ ALOGV("%s: enter: %s", __func__, str_parms_to_str(parms));
+
+ err = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_BTSCO, &val);
+ if (err >= 0) {
+ str_parms_del(parms, AUDIO_PARAMETER_KEY_BTSCO);
+ my_data->btsco_sample_rate = val;
+ if (val == SAMPLE_RATE_16KHZ) {
+ audio_route_apply_path(my_data->adev->audio_route,
+ "bt-sco-wb-samplerate");
+ audio_route_update_mixer(my_data->adev->audio_route);
+ }
+ }
+
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SLOWTALK, value, sizeof(value));
+ if (err >= 0) {
+ bool state = false;
+ if (!strncmp("true", value, sizeof("true"))) {
+ state = true;
+ }
+
+ str_parms_del(parms, AUDIO_PARAMETER_KEY_SLOWTALK);
+ ret = platform_set_slowtalk(my_data, state);
+ if (ret)
+ ALOGE("%s: Failed to set slow talk err: %d", __func__, ret);
+ }
+
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOLUME_BOOST,
+ value, sizeof(value));
+ if (err >= 0) {
+ str_parms_del(parms, AUDIO_PARAMETER_KEY_VOLUME_BOOST);
+
+ if (my_data->acdb_reload_vocvoltable == NULL) {
+ ALOGE("%s: acdb_reload_vocvoltable is NULL", __func__);
+ } else if (!strcmp(value, "on")) {
+ if (!my_data->acdb_reload_vocvoltable(VOICE_FEATURE_SET_VOLUME_BOOST)) {
+ my_data->voice_feature_set = 1;
+ }
+ } else {
+ if (!my_data->acdb_reload_vocvoltable(VOICE_FEATURE_SET_DEFAULT)) {
+ my_data->voice_feature_set = 0;
+ }
+ }
+ }
+
+ ALOGV("%s: exit with code(%d)", __func__, ret);
+ return ret;
+}
+
+int platform_set_incall_recording_session_id(void *platform,
+ uint32_t session_id, int rec_mode)
+{
+ int ret = 0;
+ struct platform_data *my_data = (struct platform_data *)platform;
+ struct audio_device *adev = my_data->adev;
+ struct mixer_ctl *ctl;
+ const char *mixer_ctl_name = "Voc VSID";
+ int num_ctl_values;
+ int i;
+
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s",
+ __func__, mixer_ctl_name);
+ ret = -EINVAL;
+ } else {
+ num_ctl_values = mixer_ctl_get_num_values(ctl);
+ for (i = 0; i < num_ctl_values; i++) {
+ if (mixer_ctl_set_value(ctl, i, session_id)) {
+ ALOGV("Error: invalid session_id: %x", session_id);
+ ret = -EINVAL;
+ break;
+ }
+ }
+ }
+
+ if (my_data->csd != NULL) {
+ ret = my_data->csd->start_record(ALL_SESSION_VSID, rec_mode);
+ if (ret < 0) {
+ ALOGE("%s: csd_client_start_record failed, error %d",
+ __func__, ret);
+ }
+ }
+
+ return ret;
+}
+
+int platform_stop_incall_recording_usecase(void *platform)
+{
+ int ret = 0;
+ struct platform_data *my_data = (struct platform_data *)platform;
+
+ if (my_data->csd != NULL) {
+ ret = my_data->csd->stop_record(ALL_SESSION_VSID);
+ if (ret < 0) {
+ ALOGE("%s: csd_client_stop_record failed, error %d",
+ __func__, ret);
+ }
+ }
+
+ return ret;
+}
+
+int platform_start_incall_music_usecase(void *platform)
+{
+ int ret = 0;
+ struct platform_data *my_data = (struct platform_data *)platform;
+
+ if (my_data->csd != NULL) {
+ ret = my_data->csd->start_playback(ALL_SESSION_VSID);
+ if (ret < 0) {
+ ALOGE("%s: csd_client_start_playback failed, error %d",
+ __func__, ret);
+ }
+ }
+
+ return ret;
+}
+
+int platform_stop_incall_music_usecase(void *platform)
+{
+ int ret = 0;
+ struct platform_data *my_data = (struct platform_data *)platform;
+
+ if (my_data->csd != NULL) {
+ ret = my_data->csd->stop_playback(ALL_SESSION_VSID);
+ if (ret < 0) {
+ ALOGE("%s: csd_client_stop_playback failed, error %d",
+ __func__, ret);
+ }
+ }
+
+ return ret;
+}
+
+void platform_get_parameters(void *platform,
+ struct str_parms *query,
+ struct str_parms *reply)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ char *str = NULL;
+ char value[256] = {0};
+ int ret;
+ int fluence_type;
+
+ ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_FLUENCE_TYPE,
+ value, sizeof(value));
+ if (ret >= 0) {
+ if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
+ strlcpy(value, "fluencepro", sizeof(value));
+ } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ strlcpy(value, "fluence", sizeof(value));
+ } else {
+ strlcpy(value, "none", sizeof(value));
+ }
+
+ str_parms_add_str(reply, AUDIO_PARAMETER_KEY_FLUENCE_TYPE, value);
+ }
+
+ memset(value, 0, sizeof(value));
+ ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_SLOWTALK,
+ value, sizeof(value));
+ if (ret >= 0) {
+ str_parms_add_str(reply, AUDIO_PARAMETER_KEY_SLOWTALK,
+ my_data->slowtalk?"true":"false");
+ }
+
+ ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_VOLUME_BOOST,
+ value, sizeof(value));
+ if (ret >= 0) {
+ if (my_data->voice_feature_set == VOICE_FEATURE_SET_VOLUME_BOOST) {
+ strlcpy(value, "on", sizeof(value));
+ } else {
+ strlcpy(value, "off", sizeof(value));
+ }
+
+ str_parms_add_str(reply, AUDIO_PARAMETER_KEY_VOLUME_BOOST, value);
+ }
+
+ ALOGV("%s: exit: returns - %s", __func__, str_parms_to_str(reply));
+}
+
+/* Delay in Us */
+int64_t platform_render_latency(audio_usecase_t usecase)
+{
+ switch (usecase) {
+ case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
+ return DEEP_BUFFER_PLATFORM_DELAY;
+ case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
+ return LOW_LATENCY_PLATFORM_DELAY;
+ default:
+ return 0;
+ }
+}
+
+int platform_update_usecase_from_source(int source, int usecase)
+{
+ ALOGV("%s: input source :%d", __func__, source);
+ if(source == AUDIO_SOURCE_FM_RX_A2DP)
+ usecase = USECASE_AUDIO_RECORD_FM_VIRTUAL;
+ return usecase;
+}
+
+bool platform_listen_update_status(snd_device_t snd_device)
+{
+ if ((snd_device >= SND_DEVICE_IN_BEGIN) &&
+ (snd_device < SND_DEVICE_IN_END) &&
+ (snd_device != SND_DEVICE_IN_CAPTURE_FM) &&
+ (snd_device != SND_DEVICE_IN_CAPTURE_VI_FEEDBACK))
+ return true;
+ else
+ return false;
+}
+
+/* Read offload buffer size from a property.
+ * If value is not power of 2 round it to
+ * power of 2.
+ */
+uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info)
+{
+ char value[PROPERTY_VALUE_MAX] = {0};
+ uint32_t fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
+ if((property_get("audio.offload.buffer.size.kb", value, "")) &&
+ atoi(value)) {
+ fragment_size = atoi(value) * 1024;
+ }
+
+ if (info != NULL && info->has_video && info->is_streaming) {
+ fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING;
+ ALOGV("%s: offload fragment size reduced for AV streaming to %d",
+ __func__, out->compr_config.fragment_size);
+ }
+
+ fragment_size = ALIGN( fragment_size, 1024);
+
+ if(fragment_size < MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE)
+ fragment_size = MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
+ else if(fragment_size > MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE)
+ fragment_size = MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
+ ALOGV("%s: fragment_size %d", __func__, fragment_size);
+ return fragment_size;
+}
+
+uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info)
+{
+ uint32_t fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE;
+ uint32_t bits_per_sample = 16;
+
+ if (info->format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD) {
+ bits_per_sample = 32;
+ }
+
+ if (!info->has_video) {
+ fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE;
+
+ } else if (info->has_video && info->is_streaming) {
+ fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING
+ * info->sample_rate
+ * bits_per_sample
+ * popcount(info->channel_mask))/1000;
+
+ } else if (info->has_video) {
+ fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV
+ * info->sample_rate
+ * bits_per_sample
+ * popcount(info->channel_mask))/1000;
+ }
+
+ fragment_size = ALIGN( fragment_size, 1024);
+
+ if(fragment_size < MIN_PCM_OFFLOAD_FRAGMENT_SIZE)
+ fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE;
+ else if(fragment_size > MAX_PCM_OFFLOAD_FRAGMENT_SIZE)
+ fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE;
+
+ ALOGV("%s: fragment_size %d", __func__, fragment_size);
+ return fragment_size;
+}
+
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index 9b97648..cad5198 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -1,4 +1,7 @@
/*
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,6 +20,12 @@
#ifndef QCOM_AUDIO_PLATFORM_H
#define QCOM_AUDIO_PLATFORM_H
+enum {
+ FLUENCE_NONE,
+ FLUENCE_DUAL_MIC = 0x1,
+ FLUENCE_QUAD_MIC = 0x2,
+};
+
/*
* Below are the devices for which is back end is same, SLIMBUS_0_RX.
* All these devices are handled by the internal HW codec. We can
@@ -47,10 +56,21 @@
SND_DEVICE_OUT_HDMI,
SND_DEVICE_OUT_SPEAKER_AND_HDMI,
SND_DEVICE_OUT_BT_SCO,
- SND_DEVICE_OUT_VOICE_HANDSET_TMUS,
+ SND_DEVICE_OUT_BT_SCO_WB,
SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES,
SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES,
SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET,
+ SND_DEVICE_OUT_AFE_PROXY,
+ SND_DEVICE_OUT_USB_HEADSET,
+ SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET,
+ SND_DEVICE_OUT_TRANSMISSION_FM,
+ SND_DEVICE_OUT_ANC_HEADSET,
+ SND_DEVICE_OUT_ANC_FB_HEADSET,
+ SND_DEVICE_OUT_VOICE_ANC_HEADSET,
+ SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET,
+ SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET,
+ SND_DEVICE_OUT_ANC_HANDSET,
+ SND_DEVICE_OUT_SPEAKER_PROTECTED,
SND_DEVICE_OUT_END,
/*
@@ -60,40 +80,64 @@
/* Capture devices */
SND_DEVICE_IN_BEGIN = SND_DEVICE_OUT_END,
SND_DEVICE_IN_HANDSET_MIC = SND_DEVICE_IN_BEGIN,
- SND_DEVICE_IN_SPEAKER_MIC,
- SND_DEVICE_IN_HEADSET_MIC,
SND_DEVICE_IN_HANDSET_MIC_AEC,
+ SND_DEVICE_IN_HANDSET_MIC_NS,
+ SND_DEVICE_IN_HANDSET_MIC_AEC_NS,
+ SND_DEVICE_IN_HANDSET_DMIC,
+ SND_DEVICE_IN_HANDSET_DMIC_AEC,
+ SND_DEVICE_IN_HANDSET_DMIC_NS,
+ SND_DEVICE_IN_HANDSET_DMIC_AEC_NS,
+ SND_DEVICE_IN_SPEAKER_MIC,
SND_DEVICE_IN_SPEAKER_MIC_AEC,
- SND_DEVICE_IN_HEADSET_MIC_AEC,
+ SND_DEVICE_IN_SPEAKER_MIC_NS,
+ SND_DEVICE_IN_SPEAKER_MIC_AEC_NS,
+ SND_DEVICE_IN_SPEAKER_DMIC,
+ SND_DEVICE_IN_SPEAKER_DMIC_AEC,
+ SND_DEVICE_IN_SPEAKER_DMIC_NS,
+ SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS,
+ SND_DEVICE_IN_HEADSET_MIC,
+ SND_DEVICE_IN_HEADSET_MIC_FLUENCE,
SND_DEVICE_IN_VOICE_SPEAKER_MIC,
SND_DEVICE_IN_VOICE_HEADSET_MIC,
SND_DEVICE_IN_HDMI_MIC,
SND_DEVICE_IN_BT_SCO_MIC,
+ SND_DEVICE_IN_BT_SCO_MIC_WB,
SND_DEVICE_IN_CAMCORDER_MIC,
- SND_DEVICE_IN_VOICE_DMIC_EF,
- SND_DEVICE_IN_VOICE_DMIC_BS,
- SND_DEVICE_IN_VOICE_DMIC_EF_TMUS,
- SND_DEVICE_IN_VOICE_SPEAKER_DMIC_EF,
- SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BS,
+ SND_DEVICE_IN_VOICE_DMIC,
+ SND_DEVICE_IN_VOICE_SPEAKER_DMIC,
+ SND_DEVICE_IN_VOICE_SPEAKER_QMIC,
SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC,
SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC,
SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC,
SND_DEVICE_IN_VOICE_REC_MIC,
- SND_DEVICE_IN_VOICE_REC_DMIC_EF,
- SND_DEVICE_IN_VOICE_REC_DMIC_BS,
- SND_DEVICE_IN_VOICE_REC_DMIC_EF_FLUENCE,
- SND_DEVICE_IN_VOICE_REC_DMIC_BS_FLUENCE,
+ SND_DEVICE_IN_VOICE_REC_MIC_NS,
+ SND_DEVICE_IN_VOICE_REC_DMIC_STEREO,
+ SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE,
+ SND_DEVICE_IN_USB_HEADSET_MIC,
+ SND_DEVICE_IN_CAPTURE_FM,
+ SND_DEVICE_IN_AANC_HANDSET_MIC,
+ SND_DEVICE_IN_QUAD_MIC,
+ SND_DEVICE_IN_HANDSET_STEREO_DMIC,
+ SND_DEVICE_IN_SPEAKER_STEREO_DMIC,
+ SND_DEVICE_IN_CAPTURE_VI_FEEDBACK,
SND_DEVICE_IN_END,
SND_DEVICE_MAX = SND_DEVICE_IN_END,
};
-#define MIXER_CARD 0
-#define SOUND_CARD 0
-
#define DEFAULT_OUTPUT_SAMPLING_RATE 48000
+#define ALL_SESSION_VSID 0xFFFFFFFF
+#define DEFAULT_MUTE_RAMP_DURATION 500
+#define DEFAULT_VOLUME_RAMP_DURATION_MS 20
+#define MIXER_PATH_MAX_LENGTH 100
+
+#define MAX_VOL_INDEX 5
+#define MIN_VOL_INDEX 0
+#define percent_to_index(val, min, max) \
+ ((val) * ((max) - (min)) * 0.01 + (min) + .5)
+
/*
* tinyAlsa library interprets period size as number of frames
* one frame = channel_count * sizeof (pcm sample)
@@ -102,9 +146,9 @@
* 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 1024
-#define DEEP_BUFFER_OUTPUT_PERIOD_COUNT 8
-#define LOW_LATENCY_OUTPUT_PERIOD_SIZE 256
+#define DEEP_BUFFER_OUTPUT_PERIOD_SIZE 960
+#define DEEP_BUFFER_OUTPUT_PERIOD_COUNT 4
+#define LOW_LATENCY_OUTPUT_PERIOD_SIZE 240
#define LOW_LATENCY_OUTPUT_PERIOD_COUNT 2
#define HDMI_MULTI_PERIOD_SIZE 336
@@ -112,7 +156,71 @@
#define HDMI_MULTI_DEFAULT_CHANNEL_COUNT 6
#define HDMI_MULTI_PERIOD_BYTES (HDMI_MULTI_PERIOD_SIZE * HDMI_MULTI_DEFAULT_CHANNEL_COUNT * 2)
-#define AUDIO_CAPTURE_PERIOD_SIZE 512
-#define AUDIO_CAPTURE_PERIOD_COUNT 16
+#define AUDIO_CAPTURE_PERIOD_DURATION_MSEC 20
+#define AUDIO_CAPTURE_PERIOD_COUNT 2
+
+#define DEVICE_NAME_MAX_SIZE 128
+#define HW_INFO_ARRAY_MAX_SIZE 32
+
+#define DEEP_BUFFER_PCM_DEVICE 0
+#define AUDIO_RECORD_PCM_DEVICE 0
+#define MULTIMEDIA2_PCM_DEVICE 1
+#define FM_PLAYBACK_PCM_DEVICE 5
+#define FM_CAPTURE_PCM_DEVICE 6
+#define HFP_PCM_RX 5
+#define HFP_SCO_RX 23
+#define HFP_ASM_RX_TX 24
+
+#define INCALL_MUSIC_UPLINK_PCM_DEVICE 1
+#define INCALL_MUSIC_UPLINK2_PCM_DEVICE 16
+#define SPKR_PROT_CALIB_RX_PCM_DEVICE 5
+#define SPKR_PROT_CALIB_TX_PCM_DEVICE 22
+#define PLAYBACK_OFFLOAD_DEVICE 9
+#define COMPRESS_VOIP_CALL_PCM_DEVICE 3
+
+
+#define LOWLATENCY_PCM_DEVICE 12
+#define EC_REF_RX "I2S_RX"
+#define COMPRESS_CAPTURE_DEVICE 19
+
+#define VOICE_CALL_PCM_DEVICE 2
+#define VOICE2_CALL_PCM_DEVICE 13
+#define VOLTE_CALL_PCM_DEVICE 15
+#define QCHAT_CALL_PCM_DEVICE 14
+
+#define LIB_CSD_CLIENT "libcsd-client.so"
+/* CSD-CLIENT related functions */
+typedef int (*init_t)();
+typedef int (*deinit_t)();
+typedef int (*disable_device_t)();
+typedef int (*enable_device_config_t)(int, int);
+typedef int (*enable_device_t)(int, int, uint32_t);
+typedef int (*volume_t)(uint32_t, int);
+typedef int (*mic_mute_t)(uint32_t, int);
+typedef int (*slow_talk_t)(uint32_t, uint8_t);
+typedef int (*start_voice_t)(uint32_t);
+typedef int (*stop_voice_t)(uint32_t);
+typedef int (*start_playback_t)(uint32_t);
+typedef int (*stop_playback_t)(uint32_t);
+typedef int (*start_record_t)(uint32_t, int);
+typedef int (*stop_record_t)(uint32_t);
+/* CSD Client structure */
+struct csd_data {
+ void *csd_client;
+ init_t init;
+ deinit_t deinit;
+ disable_device_t disable_device;
+ enable_device_config_t enable_device_config;
+ enable_device_t enable_device;
+ volume_t volume;
+ mic_mute_t mic_mute;
+ slow_talk_t slow_talk;
+ start_voice_t start_voice;
+ stop_voice_t stop_voice;
+ start_playback_t start_playback;
+ stop_playback_t stop_playback;
+ start_record_t start_record;
+ stop_record_t stop_record;
+};
#endif // QCOM_AUDIO_PLATFORM_H