[Feature]merge MTK MR3.0 release
Change-Id: I877d3bbcdacfa7d2ab902e6c4c8e740a67069038
diff --git a/src/multimedia/audio-misc/libmodem-afe-ctrl/LICENSE b/src/multimedia/audio-misc/libmodem-afe-ctrl/LICENSE
new file mode 100644
index 0000000..77f59ed
--- /dev/null
+++ b/src/multimedia/audio-misc/libmodem-afe-ctrl/LICENSE
@@ -0,0 +1,31 @@
+Copyright Statement:
+
+This software/firmware and related documentation ("MediaTek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+the prior written permission of MediaTek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of MediaTek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+MediaTek Inc. (C) 2015. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
diff --git a/src/multimedia/audio-misc/libmodem-afe-ctrl/Makefile b/src/multimedia/audio-misc/libmodem-afe-ctrl/Makefile
new file mode 100644
index 0000000..670173d
--- /dev/null
+++ b/src/multimedia/audio-misc/libmodem-afe-ctrl/Makefile
@@ -0,0 +1,34 @@
+#SPDX-License-Identifier: MediaTekProprietary
+$(warning !!!!! target platform=$(TARGET_PLATFORM) !!!!!)
+ifeq ($(strip $(TARGET_PLATFORM)), )
+ DIR_MAKEFILE = mt2635
+else
+ DIR_MAKEFILE = $(TARGET_PLATFORM)
+endif
+
+build:
+ $(warning ########## build libmodem ##########)
+ for i in $(DIR_MAKEFILE); do \
+ (cd $$i && make); \
+ if [ $$? != 0 ]; then \
+ exit 1; \
+ fi \
+ done
+
+install:
+ $(warning ########## install libmodem ##########)
+ for i in $(DIR_MAKEFILE); do \
+ (cd $$i && make install); \
+ if [ $$? != 0 ]; then \
+ exit 1; \
+ fi \
+ done
+
+clean:
+ for i in $(DIR_MAKEFILE); do \
+ (cd $$i && make clean); \
+ if [ $$? != 0 ]; then \
+ exit 1; \
+ fi \
+ done
+
diff --git a/src/multimedia/audio-misc/libmodem-afe-ctrl/mt2735/LICENSE b/src/multimedia/audio-misc/libmodem-afe-ctrl/mt2735/LICENSE
new file mode 100644
index 0000000..77f59ed
--- /dev/null
+++ b/src/multimedia/audio-misc/libmodem-afe-ctrl/mt2735/LICENSE
@@ -0,0 +1,31 @@
+Copyright Statement:
+
+This software/firmware and related documentation ("MediaTek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+the prior written permission of MediaTek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of MediaTek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+MediaTek Inc. (C) 2015. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
diff --git a/src/multimedia/audio-misc/libmodem-afe-ctrl/mt2735/Makefile b/src/multimedia/audio-misc/libmodem-afe-ctrl/mt2735/Makefile
new file mode 100644
index 0000000..423882f
--- /dev/null
+++ b/src/multimedia/audio-misc/libmodem-afe-ctrl/mt2735/Makefile
@@ -0,0 +1,43 @@
+#SPDX-License-Identifier: MediaTekProprietary
+PREFIX = ../install
+NAME = modemafectrl
+COMPILER = GNU
+CROSS = arm-linux-
+CROSS_SUP= arm-linux- arm-none-eabi- aarch64-linux-
+GCC = $(CROSS)gcc
+CC = $(GCC)
+CXX = $(CROSS)g++
+OBJDUMP = $(CROSS)objdump
+OBJCOPY = $(CROSS)objcopy
+AR = $(CROSS)ar
+
+OFLAGS ?= -g -O0 -fPIC -Wno-missing-braces
+
+ifeq ($(strip $(CROSS)), arm-linux-)
+ CFLAGS = -mthumb-interwork
+endif
+
+INIT = syss_init
+LDFLAGS = $(BB_LDFLAGS_ADD) -Wl,--hash-style=gnu -L. -L $(ROOT)/lib
+LOCAL_PATH = .
+
+
+all: libmodemafectrl.so
+
+INCLUDE = -Iinclude
+
+libmodemafectrl.so: pcm_ctrl.o
+ $(CC) $(OFLAGS) $(INCLUDE) ${LDFLAGS} -lasound -lmtk_audio_mixer_ctrl -shared -o $@ pcm_ctrl.o
+
+pcm_ctrl.o: include/
+ $(CC) $(OFLAGS) $(INCLUDE) ${CFLAGS} -c src/pcm_ctrl.c -o $@
+
+install:
+ mkdir -p ../include
+ cp -af include/* ../include/
+
+ mkdir -p $(ROOT)/${base_libdir}/
+ cp lib$(NAME).so $(ROOT)/${base_libdir}/
+
+clean:
+ rm -f libmodemafectrl.so
diff --git a/src/multimedia/audio-misc/libmodem-afe-ctrl/mt2735/include/dev_string.h b/src/multimedia/audio-misc/libmodem-afe-ctrl/mt2735/include/dev_string.h
new file mode 100644
index 0000000..d3541a3
--- /dev/null
+++ b/src/multimedia/audio-misc/libmodem-afe-ctrl/mt2735/include/dev_string.h
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: MediaTekProprietary
+#ifndef _DEV_STRING_H_
+#define _DEV_STRING_H_
+
+/* modem device name*/
+#define MODEM_DEV_NAME "hw:0,18" //"hw:0,15"
+#define MODEM_BT_DEV_NAME "hw:0,18"
+
+#endif
diff --git a/src/multimedia/audio-misc/libmodem-afe-ctrl/mt2735/include/modem_afe_ctrl.h b/src/multimedia/audio-misc/libmodem-afe-ctrl/mt2735/include/modem_afe_ctrl.h
new file mode 100644
index 0000000..f67a164
--- /dev/null
+++ b/src/multimedia/audio-misc/libmodem-afe-ctrl/mt2735/include/modem_afe_ctrl.h
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: MediaTekProprietary
+/*
+Copyright Statement:
+
+This software/firmware and related documentation ("MediaTek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+the prior written permission of MediaTek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of MediaTek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+MediaTek Inc. (C) 2016. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+
+Auther: Garlic Tseng <garlic.tseng@mediatek.com>
+*/
+
+/*
+usage:
+1. call get_default_device to get the system default phonecall device
+2. call enable_phone_call_AFE_path when phone call is enabled
+ (may or may not use default device)
+3. call disable_phone_call_AFE_path when phone call is disabled
+*/
+
+#ifndef _MODEM_ALSA_LIB_H_
+#define _MODEM_ALSA_LIB_H_
+
+typedef enum {
+ DEV_SPK,
+ DEV_SPK_EX,
+ DEV_DIRECT,
+ DEV_DIRECT_LO,
+ DEV_HP,
+ DEV_BT,
+ DEV_DEFAULT,
+ DEV_NUM = DEV_DEFAULT,
+ DEV_INVALID = -1,
+} Audio_device;
+
+/***********************************************
+ * The API below will make request to server. *
+ ***********************************************/
+
+//enable audio path for modem.
+//return value: 0 if success, or negitive error number
+int enable_phone_call_AFE_path(int audio_device);
+
+//close audio path for modem
+//return value: 0 if success, or negitive error number
+int disable_phone_call_AFE_path(void);
+
+//get default device.
+//return value: default device setting
+int get_default_device(void);
+
+//set UL analog gain
+//return value: 0 if success, or negitive error number
+int set_UL_analog_gain(int dB);
+
+//set DL analog gain
+//return value: 0 if success, or negitive error number
+int set_DL_analog_gain(int dB);
+
+//set BT WB on
+//return value: 0 if success, or negitive error number
+int set_BT_WB(int on);
+
+//change device when the phone call is enabled
+//return value: 0 if success, or negitive error number
+int dynamic_switch_phone_call_path(int audio_device);
+
+//set phonecall sample rate
+//return value: 0 if success, or negitive error number
+int set_phonecall_rate(int rate);
+
+
+/***********************************************
+ * IPC define. *
+ ***********************************************/
+
+#define FUNC_ENABLE_PHONE_CALL_AFE_PATH 0
+#define FUNC_DISABLE_PHONE_CALL_AFE_PATH 1
+#define FUNC_GET_DEFAULT_VALUE 2
+#define FUNC_SET_UL_ANALOG_GAIN 3
+#define FUNC_SET_DL_ANALOG_GAIN 4
+#define FUNC_SET_BT_WB 5
+#define FUNC_DYNAMIC_SWITCH_PHONE_CALL_PATH 6
+#define FUNC_SET_PHONE_CALL_SAMPLERATE 7
+
+/***********************************************
+ * default parameter *
+ ***********************************************/
+
+#define FUNC_SET_BT_WB_default 0 //default off
+
+/******************************************************************************
+ * The API below is for service to call. Please use API defined above if you *
+ * are not service. *
+ ******************************************************************************/
+int set_BT_wb(int on);
+int set_phonecall_rate_for_service(int rate);
+
+//enable audio path for modem.
+//return value: 0 if success, or negitive error number
+int enable_phone_call_AFE_path_for_service(int audio_device);
+
+//close audio path for modem
+//return value: 0 if success, or negitive error number
+int disable_phone_call_AFE_path_for_service(void);
+
+//get default device.
+//return value: default device setting
+int get_default_device_for_service(void);
+
+//set UL analog gain
+int set_UL_analog_gain_for_service(int dB);
+
+//set DL analog gain
+int set_DL_analog_gain_for_service(int dB);
+
+//change device when the phone call is enabled
+int dynamic_switch_phone_call_path_for_service(int audio_device);
+
+#endif //_MODEM_ALSA_LIB_H_
+
diff --git a/src/multimedia/audio-misc/libmodem-afe-ctrl/mt2735/src/pcm_ctrl.c b/src/multimedia/audio-misc/libmodem-afe-ctrl/mt2735/src/pcm_ctrl.c
new file mode 100644
index 0000000..cedf569
--- /dev/null
+++ b/src/multimedia/audio-misc/libmodem-afe-ctrl/mt2735/src/pcm_ctrl.c
@@ -0,0 +1,1053 @@
+// SPDX-License-Identifier: MediaTekProprietary
+/*
+Copyright Statement:
+
+This software/firmware and related documentation ("MediaTek Software") are
+protected under relevant copyright laws. The information contained herein is
+confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+the prior written permission of MediaTek inc. and/or its licensors, any
+reproduction, modification, use or disclosure of MediaTek Software, and
+information contained herein, in whole or in part, shall be strictly
+prohibited.
+
+MediaTek Inc. (C) 2016. All rights reserved.
+
+BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+
+Auther: Garlic Tseng <garlic.tseng@mediatek.com>
+*/
+#include <pthread.h>
+#include <error.h>
+#include <signal.h>
+#include <stdio.h>
+#include <alsa/asoundlib.h>
+#include <semaphore.h>
+#include "modem_afe_ctrl.h"
+#include "mixer_ctrl.h"
+#include "dev_string.h"
+
+#include <syslog.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "phonecall_pcm"
+
+#define STR_SIZE 128
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+//#define USE_MIC_0
+
+static int g_device = DEV_DEFAULT;
+static int g_afe_enabled;
+
+/* prevent disable when enable (or vice versa) */
+static pthread_mutex_t g_afe_enabled_lock = PTHREAD_MUTEX_INITIALIZER;
+
+static snd_pcm_t *g_pcm_playback_handle;
+static snd_pcm_t *g_pcm_capture_handle;
+
+static snd_pcm_t *g_pcm_playback_handle_bt;
+
+static int do_enable_AFE_l(void);
+static int do_disable_AFE_l(void);
+
+static int open_start_pcm(void);
+static void close_pcm(void);
+
+static int open_start_bt_pcm(void);
+static void close_bt_pcm(void);
+
+static void store_AFE_original_setting();
+static void restore_AFE_original_setting();
+
+static void do_AFE_open_sequence(int dev);
+static void do_AFE_close_sequence(int dev);
+static void do_bt_open_sequence(void);
+static void do_bt_close_sequence(void);
+static void do_internal_codec_open_sequence(int dev);
+static void do_internal_codec_close_sequence(int dev);
+static void do_ext_codec_open_sequence(int dev);
+static void do_ext_codec_close_sequence(int dev);
+static int is_using_internal_codec(void);
+
+static int do_IPC_call(const char* cmd);
+
+
+typedef enum {
+ MixerName,
+ MixerValue,
+ MixerPairSize,
+} MixerCtrlPair;
+
+typedef char Mixer_pair[MixerPairSize][STR_SIZE];
+typedef char String[STR_SIZE];
+
+/*now we fix playback & record to hs.*/
+/*will remove the constrain after codec reflection finish.*/
+static const String MIXER_BACKUP_LIST_NAME[] = {
+ "I2S0_HD_Mux",
+ "I2S3_HD_Mux",
+ "I2S3_Out_Mux",
+ "OUT1 MUX",
+ "AIN MUX",
+};
+
+static int MIXER_BACKUP_LIST_VALUE[ARRAY_SIZE(MIXER_BACKUP_LIST_NAME)];
+
+static const String INTERCONN_BACKUP_LIST_NAME[] = {
+ /*{mixer name, option name}*/
+ "PCM_2_PB_CH1 I2S0_CH1",
+ "I2S3_CH1 PCM_2_CAP_CH1",
+ "I2S3_CH2 PCM_2_CAP_CH2",
+ "I2S3_CH1 DL1_CH1",
+ "I2S3_CH2 DL1_CH2",
+ "UL2_CH1 I2S0_CH1",
+ "UL2_CH2 I2S0_CH2",
+};
+
+static int INTERCONN_BACKUP_LIST_VALUE[ARRAY_SIZE(INTERCONN_BACKUP_LIST_NAME)];
+
+static const Mixer_pair SPK_ENABLE_SEQ[] = {
+ /*{mixer name, option name}*/
+ {"I2S0_HD_Mux", "Low_Jitter"},
+ {"I2S3_HD_Mux", "Low_Jitter"},
+ {"I2S3_Out_Mux", "Output_Widget"},
+ {"OUT1 MUX", "DAC"},
+ {"Lineout Type", "Differential"},
+ {"BICK Frequency", "32fs"},
+ {"ADC Input Type", "Single-end"},
+ {"AIN MUX", "AIN1"},
+};
+
+static const Mixer_pair HP_ENABLE_SEQ[] = {
+ /*{mixer name, option name}*/
+ {"ETDM_HD_Mux", "Normal"},
+ {"ETDM_PCM1_MUX", "PCM"},
+};
+
+static const Mixer_pair DIRECT_ENABLE_SEQ[] = {
+ /*{mixer name, option name}*/
+ {"ETDM_HD_Mux", "Normal"},
+ {"ETDM_PCM1_MUX", "PCM"},
+};
+
+static const Mixer_pair DIRECT_LO_ENABLE_SEQ[] = {
+ {"ETDM_HD_Mux", "Normal"},
+ {"ETDM_PCM1_MUX", "PCM"},
+};
+
+//TBD
+static const Mixer_pair BT_ENABLE_SEQ[] = {
+ /*{mixer name, option name}*/
+ {"ETDM_HD_Mux", "Normal"},
+};
+
+static const Mixer_pair SPK_DISABLE_SEQ[] = {
+ /*{mixer name, option name}*/
+ {"I2S3_HD_Mux", "Normal"},
+ {"I2S0_HD_Mux", "Normal"},
+ {"I2S3_Out_Mux", "Normal"},
+ {"OUT1 MUX", "VCOM"},
+ {"Lineout Type", "Single-end"},
+};
+
+static const Mixer_pair HP_DISABLE_SEQ[] = {
+ /*{mixer name, option name}*/
+ {"ETDM_HD_Mux", "Normal"},
+ {"ETDM_PCM1_MUX", "PCM"},
+};
+
+static const Mixer_pair DIRECT_DISABLE_SEQ[] = {
+ /*{mixer name, option name}*/
+ {"ETDM_HD_Mux", "Normal"},
+ {"ETDM_PCM1_MUX", "PCM"},
+};
+
+static const Mixer_pair DIRECT_LO_DISABLE_SEQ[] = {
+ /*{mixer name, option name}*/
+ {"ETDM_HD_Mux", "Normal"},
+ {"ETDM_PCM1_MUX", "PCM"},
+};
+
+//TBD
+static const Mixer_pair BT_DISABLE_SEQ[] = {
+ /*{mixer name, option name}*/
+ {"ETDM_HD_Mux", "Normal"},
+};
+
+static const Mixer_pair INT_CODEC_INTERCONN_SEQ[] = {
+ /*{mixer name, option name}*/
+ {"PCM_2_PB_CH1 I2S0_CH1", "1"},
+ {"I2S3_CH1 PCM_2_CAP_CH1", "1"},
+ {"I2S3_CH2 PCM_2_CAP_CH1", "1"},
+};
+
+
+static const Mixer_pair BT_INTERCONN_SEQ[] = {
+ /*{mixer name, option name}*/
+};
+
+/*external codec seq, should modify if new codec applied*/
+static const Mixer_pair EXT_CODEC_ENABLE_SEQ[] = {
+ /*{mixer name, option name}*/
+ {"ETDM_PCM1_MUX", "PCM"},
+};
+
+static const Mixer_pair EXT_CODEC_DISABLE_SEQ[] = {
+ /*{mixer name, option name}*/
+ {"ETDM_HD_Mux", "Normal"},
+ {"ETDM_PCM1_MUX", "PCM"},
+};
+
+static const Mixer_pair EXT_CODEC_INTERCONN_SEQ[] = {
+ /*{mixer name, option name}*/
+ {"Ext_Speaker_Amp", "1"},
+ {"ETDM_PB_CH1 DL1_CH1", "1"},
+ {"ETDM_PB_CH1 DL1_CH2", "1"},
+ {"UL1_CH1 ETDM_CAP_CH1", "1"},
+ {"UL1_CH2 ETDM_CAP_CH1", "1"},
+};
+
+/*external codec seq end*/
+
+/* for BT WB */
+static pthread_mutex_t g_BT_WB_on_lock = PTHREAD_MUTEX_INITIALIZER;
+static int g_BT_WB_on = FUNC_SET_BT_WB_default;
+int set_BT_wb(int on){
+ pthread_mutex_lock(&g_BT_WB_on_lock);
+ g_BT_WB_on = !!on;
+ pthread_mutex_unlock(&g_BT_WB_on_lock);
+ return 0;
+}
+/* for BT WB end*/
+
+static int phonecall_rate = 16000;
+
+int set_phonecall_rate_for_service(int rate)
+{
+ phonecall_rate = rate;
+ return 0;
+}
+
+int enable_phone_call_AFE_path_for_service(int audio_device)
+{
+ int ret;
+
+ pthread_mutex_lock(&g_afe_enabled_lock);
+ if (g_afe_enabled) {
+ printf("%s, modem path already opened.\n", __func__);
+ pthread_mutex_unlock(&g_afe_enabled_lock);
+ return -EBUSY;
+ }
+ printf("%s.YR\n", __func__);
+
+ g_device = audio_device;
+ if (audio_device == DEV_DEFAULT)
+ g_device = get_default_device_for_service();
+
+ ret = do_enable_AFE_l();
+
+ if (ret)
+ printf("%s, pthread_create failed: %d\n", __func__, ret);
+
+ pthread_mutex_unlock(&g_afe_enabled_lock);
+
+ return ret;
+}
+
+int disable_phone_call_AFE_path_for_service(void)
+{
+ int ret;
+
+ pthread_mutex_lock(&g_afe_enabled_lock);
+ if (!g_afe_enabled) {
+ printf("%s, modem path not opened.\n", __func__);
+ pthread_mutex_unlock(&g_afe_enabled_lock);
+ return 0;
+ }
+
+ ret = do_disable_AFE_l();
+ if (ret)
+ printf("%s, do_disable_AFE_l failed: %d\n", __func__, ret);
+
+ pthread_mutex_unlock(&g_afe_enabled_lock);
+ return ret;
+}
+
+/*do enable sequence, need lock outside*/
+static int do_enable_AFE_l(void)
+{
+ int device;
+ int ret;
+
+ device = g_device;
+ do_AFE_open_sequence(device);
+ //ret = open_start_pcm(); //Garlic!!! tmp test BT
+ if (device != DEV_BT)
+ ret = open_start_pcm();
+ else
+ ret = open_start_bt_pcm();
+ if (ret) {
+ printf("%s, open_start_pcm failed: %d\n", __func__, ret);
+ close_pcm();
+ return ret;
+ }
+
+ g_afe_enabled = 1;
+
+ return 0;
+}
+
+/*do disable sequence, need lock outside*/
+static int do_disable_AFE_l(void){
+ int device;
+ device = g_device;
+
+ g_afe_enabled = 0;
+ //close_pcm(); //Garlic!!! tmp test BT
+ if (device != DEV_BT)
+ close_pcm();
+ else
+ close_bt_pcm();
+
+ do_AFE_close_sequence(device);
+ return 0;
+}
+
+int get_default_device_for_service(void)
+{
+ int mix_value;
+
+ mix_value = get_mixer_ctrl_interconn_value("Ext_Speaker_Amp");
+
+ printf("%s, mix_value %d\n", __func__, mix_value);
+
+ if (mix_value==1)
+ return DEV_SPK;
+ else if (mix_value < 0)
+ printf("get_mixer_ctrl_value_int for LOL Mux error!\n");
+
+ /* TODO: add BT device support */
+ printf("no available device, use spk for default\n");
+ return DEV_SPK;
+}
+
+static int open_start_pcm(void)
+{
+ int ret = 0;
+ snd_pcm_hw_params_t *hw_params = NULL;
+ snd_pcm_hw_params_t *hw_params_c = NULL;
+
+ /*pcm interface create*/
+ if ((ret = snd_pcm_open(&g_pcm_playback_handle, MODEM_DEV_NAME,
+ SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
+ printf ("cannot open audio device %s (%s)\n",
+ MODEM_DEV_NAME, snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_open(&g_pcm_capture_handle, MODEM_DEV_NAME,
+ SND_PCM_STREAM_CAPTURE, 0)) < 0) {
+ printf ("cannot open audio device %s (%s)\n",
+ MODEM_DEV_NAME, snd_strerror(ret));
+ return ret;
+ }
+
+ snd_pcm_hw_params_alloca(&hw_params);
+ if (hw_params == NULL) {
+ printf ("cannot allocate hardware parameter structure (%s)\n",
+ snd_strerror(ret));
+ return ret;
+ }
+
+ snd_pcm_hw_params_alloca(&hw_params_c);
+ if (hw_params_c == NULL) {
+ printf ("cannot allocate hardware parameter structure (%s)\n",
+ snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_hw_params_any(g_pcm_playback_handle, hw_params)) < 0) {
+ printf ("cannot initialize hardware parameter structure (%s)\n",
+ snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_hw_params_any(g_pcm_capture_handle, hw_params_c)) < 0) {
+ printf ("cannot initialize hardware parameter structure (%s)\n",
+ snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_hw_params_set_access(g_pcm_playback_handle, hw_params,
+ SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
+ printf ("cannot set access type (%s)\n", snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_hw_params_set_access(g_pcm_capture_handle, hw_params_c,
+ SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
+ printf ("cannot set access type (%s)\n", snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_hw_params_set_format(g_pcm_playback_handle, hw_params,
+ SND_PCM_FORMAT_S16_LE)) < 0) {
+ printf ("cannot set sample format (%s)\n", snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_hw_params_set_format(g_pcm_capture_handle, hw_params_c,
+ SND_PCM_FORMAT_S16_LE)) < 0) {
+ printf ("cannot set sample format (%s)\n", snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_hw_params_set_rate(g_pcm_playback_handle, hw_params, phonecall_rate, 0)) < 0) {
+ printf ("cannot set sample rate (%s)\n", snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_hw_params_set_rate(g_pcm_capture_handle, hw_params_c, phonecall_rate, 0)) < 0) {
+ printf ("cannot set sample rate (%s)\n", snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_hw_params_set_channels(g_pcm_playback_handle, hw_params, 2)) < 0) {
+ printf ("cannot set channel count (%s)\n", snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_hw_params_set_channels(g_pcm_capture_handle, hw_params_c, 2)) < 0) {
+ printf ("cannot set channel count (%s)\n", snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_hw_params (g_pcm_playback_handle, hw_params)) < 0) {
+ printf ("cannot set parameters(%s)\n", snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_hw_params (g_pcm_capture_handle, hw_params_c)) < 0) {
+ printf ("cannot set parameters(%s)\n", snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_prepare(g_pcm_playback_handle)) < 0) {
+ printf ("cannot prepare audio interface for use (%s)\n",
+ snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_prepare(g_pcm_capture_handle)) < 0) {
+ printf ("cannot prepare audio interface for use (%s)\n",
+ snd_strerror(ret));
+ return ret;
+ }
+
+ snd_pcm_start(g_pcm_playback_handle);
+ snd_pcm_start(g_pcm_capture_handle);
+
+ return ret;
+}
+
+
+static int open_start_bt_pcm(void)
+{
+ int ret;
+ snd_pcm_hw_params_t *hw_params = NULL;
+
+ pthread_mutex_lock(&g_BT_WB_on_lock);
+ /*pcm interface create*/
+ if ((ret = snd_pcm_open(&g_pcm_playback_handle_bt, MODEM_BT_DEV_NAME,
+ SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
+ printf ("cannot open audio device %s (%s)\n",
+ MODEM_BT_DEV_NAME, snd_strerror(ret));
+ return ret;
+ }
+
+ snd_pcm_hw_params_alloca(&hw_params);
+ if (hw_params == NULL) {
+ printf ("cannot allocate hardware parameter structure (%s)\n",
+ snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_hw_params_any(g_pcm_playback_handle_bt, hw_params)) < 0) {
+ printf ("cannot initialize hardware parameter structure (%s)\n",
+ snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_hw_params_set_access(g_pcm_playback_handle_bt, hw_params,
+ SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
+ printf ("cannot set access type (%s)\n", snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_hw_params_set_format(g_pcm_playback_handle_bt, hw_params,
+ SND_PCM_FORMAT_S16_LE)) < 0) {
+ printf ("cannot set sample format (%s)\n", snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_hw_params_set_rate(g_pcm_playback_handle_bt,
+ hw_params,
+ g_BT_WB_on? 16000: 8000, 0)) < 0) {
+ printf ("cannot set sample rate (%s)\n", snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_hw_params_set_channels(g_pcm_playback_handle_bt, hw_params, 1)) < 0) {
+ printf ("cannot set channel count (%s)\n", snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_hw_params (g_pcm_playback_handle_bt, hw_params)) < 0) {
+ printf ("cannot set parameters(%s)\n", snd_strerror(ret));
+ return ret;
+ }
+
+ if ((ret = snd_pcm_prepare(g_pcm_playback_handle_bt)) < 0) {
+ printf ("cannot prepare audio interface for use (%s)\n",
+ snd_strerror(ret));
+ return ret;
+ }
+
+ snd_pcm_start(g_pcm_playback_handle_bt);
+ pthread_mutex_unlock(&g_BT_WB_on_lock);
+
+ return ret;
+}
+
+
+static void close_pcm(void)
+{
+ if (g_pcm_playback_handle != NULL) {
+ snd_pcm_close(g_pcm_playback_handle);
+ g_pcm_playback_handle = NULL;
+ }
+ if (g_pcm_capture_handle != NULL) {
+ snd_pcm_close(g_pcm_capture_handle);
+ g_pcm_capture_handle = NULL;
+ }
+}
+
+static void close_bt_pcm(void)
+{
+ if (g_pcm_playback_handle_bt != NULL) {
+ snd_pcm_close(g_pcm_playback_handle_bt);
+ g_pcm_playback_handle_bt = NULL;
+ }
+}
+
+static void store_AFE_original_setting()
+{
+ int i;
+
+ for(i = 0;i < ARRAY_SIZE(INTERCONN_BACKUP_LIST_NAME); i++)
+ INTERCONN_BACKUP_LIST_VALUE[i] =
+ get_mixer_ctrl_interconn_value(INTERCONN_BACKUP_LIST_NAME[i]);
+
+ for(i = 0;i < ARRAY_SIZE(MIXER_BACKUP_LIST_NAME); i++)
+ MIXER_BACKUP_LIST_VALUE[i] =
+ get_mixer_ctrl_value_int(MIXER_BACKUP_LIST_NAME[i]);
+}
+
+
+
+static void restore_AFE_original_setting()
+{
+ int i, ret;
+ int device;
+
+ for(i = 0;i < ARRAY_SIZE(MIXER_BACKUP_LIST_NAME); i++) {
+ ret = set_mixer_ctrl_value_int(MIXER_BACKUP_LIST_NAME[i],
+ MIXER_BACKUP_LIST_VALUE[i]);
+ if(ret)
+ printf("%s, restore_AFE_original_setting error %d, %s, %d\n",
+ __func__, ret,
+ MIXER_BACKUP_LIST_NAME[i],
+ MIXER_BACKUP_LIST_VALUE[i]);
+ }
+
+ for(i = 0;i < ARRAY_SIZE(INTERCONN_BACKUP_LIST_NAME); i++) {
+ ret = set_mixer_ctrl_interconn_value(INTERCONN_BACKUP_LIST_NAME[i],
+ INTERCONN_BACKUP_LIST_VALUE[i]);
+ if(ret)
+ printf("%s, restore_AFE_original_setting error %d, %s, %d\n",
+ __func__, ret,
+ INTERCONN_BACKUP_LIST_NAME[i],
+ INTERCONN_BACKUP_LIST_VALUE[i]);
+ }
+}
+
+static void do_AFE_open_sequence(int dev)
+{
+ printf("YR %s, dev: %d\n", __func__, dev);
+
+ if (dev == DEV_BT) {
+ do_bt_open_sequence();
+ } else if (is_using_internal_codec()) {
+ store_AFE_original_setting();
+ do_internal_codec_open_sequence(dev);
+ } else {
+ do_ext_codec_open_sequence(dev);
+ }
+}
+
+static void do_AFE_close_sequence(int dev)
+{
+ if (dev == DEV_BT) {
+ do_bt_close_sequence();
+ } else if (is_using_internal_codec()) {
+ do_internal_codec_close_sequence(dev);
+ restore_AFE_original_setting();
+ } else {
+ do_ext_codec_close_sequence(dev);
+ }
+}
+
+static void do_bt_open_sequence(void)
+{
+ int i, ret;
+
+ for(i = 0;i < ARRAY_SIZE(BT_ENABLE_SEQ); i++){
+ ret = set_mixer_ctrl_value_string(BT_ENABLE_SEQ[i][MixerName],
+ BT_ENABLE_SEQ[i][MixerValue]);
+ if(ret)
+ printf("%s, set_mixer_ctrl_value_string error %d, %s, %s\n",
+ __func__, ret,
+ BT_ENABLE_SEQ[i][MixerName],
+ BT_ENABLE_SEQ[i][MixerValue]);
+ }
+
+ for(i = 0;i < ARRAY_SIZE(BT_INTERCONN_SEQ); i++){
+ ret = set_mixer_ctrl_interconn_value(BT_INTERCONN_SEQ[i][MixerName],
+ atoi(BT_INTERCONN_SEQ[i][MixerValue]));
+ if(ret)
+ printf("%s, set_mixer_ctrl_interconn_value error %d, %s, %s\n",
+ __func__, ret,
+ BT_INTERCONN_SEQ[i][MixerName],
+ BT_INTERCONN_SEQ[i][MixerValue]);
+ }
+}
+
+static void do_bt_close_sequence(void)
+{
+ int i, ret;
+
+ for(i = 0;i < ARRAY_SIZE(BT_INTERCONN_SEQ); i++){
+ ret = set_mixer_ctrl_interconn_value(BT_INTERCONN_SEQ[i][MixerName], 0);
+ if(ret)
+ printf("%s, set_mixer_ctrl_interconn_value error %d, %s, 0\n",
+ __func__, ret,
+ BT_INTERCONN_SEQ[i][MixerName]);
+ }
+
+ for(i = 0;i < ARRAY_SIZE(BT_DISABLE_SEQ); i++){
+ ret = set_mixer_ctrl_value_string(BT_DISABLE_SEQ[i][MixerName],
+ BT_DISABLE_SEQ[i][MixerValue]);
+ if(ret)
+ printf("%s, set_mixer_ctrl_value_string error %d, %s, %s\n",
+ __func__, ret,
+ BT_DISABLE_SEQ[i][MixerName],
+ BT_DISABLE_SEQ[i][MixerValue]);
+ }
+}
+
+static void do_internal_codec_open_sequence(int dev)
+{
+ int i, ret;
+ printf("YR %s, dev: %d\n", __func__, dev);
+
+ /*TODO: make it simpler*/
+ switch(dev) {
+ case DEV_SPK:
+ for(i = 0;i < ARRAY_SIZE(SPK_ENABLE_SEQ); i++){
+ ret = set_mixer_ctrl_value_string(SPK_ENABLE_SEQ[i][MixerName],
+ SPK_ENABLE_SEQ[i][MixerValue]);
+ //if(ret)
+ printf("%s,YR set_mixer_ctrl_value_string error %d, %s, %s\n",
+ __func__, ret,
+ SPK_ENABLE_SEQ[i][MixerName],
+ SPK_ENABLE_SEQ[i][MixerValue]);
+ }
+
+ for(i = 0;i < ARRAY_SIZE(INT_CODEC_INTERCONN_SEQ); i++){
+ ret = set_mixer_ctrl_interconn_value(INT_CODEC_INTERCONN_SEQ[i][MixerName],
+ atoi(INT_CODEC_INTERCONN_SEQ[i][MixerValue]));
+ //if(ret)
+ printf("%s,YR set_mixer_ctrl_interconn_value error %d, %s, %s\n",
+ __func__, ret,
+ INT_CODEC_INTERCONN_SEQ[i][MixerName],
+ INT_CODEC_INTERCONN_SEQ[i][MixerValue]);
+ }
+ break;
+ case DEV_HP:
+ for(i = 0;i < ARRAY_SIZE(HP_ENABLE_SEQ); i++){
+ ret = set_mixer_ctrl_value_string(HP_ENABLE_SEQ[i][MixerName],
+ HP_ENABLE_SEQ[i][MixerValue]);
+ if(ret)
+ printf("%s, set_mixer_ctrl_value_string error %d, %s, %s\n",
+ __func__, ret,
+ HP_ENABLE_SEQ[i][MixerName],
+ HP_ENABLE_SEQ[i][MixerValue]);
+ }
+ break;
+ case DEV_DIRECT:
+ for(i = 0;i < ARRAY_SIZE(DIRECT_ENABLE_SEQ); i++){
+ ret = set_mixer_ctrl_value_string(DIRECT_ENABLE_SEQ[i][MixerName],
+ DIRECT_ENABLE_SEQ[i][MixerValue]);
+ if(ret)
+ printf("%s, set_mixer_ctrl_value_string error %d, %s, %s\n",
+ __func__, ret,
+ DIRECT_ENABLE_SEQ[i][MixerName],
+ DIRECT_ENABLE_SEQ[i][MixerValue]);
+ }
+ break;
+ case DEV_DIRECT_LO:
+ for(i = 0;i < ARRAY_SIZE(DIRECT_LO_ENABLE_SEQ); i++){
+ ret = set_mixer_ctrl_value_string(DIRECT_LO_ENABLE_SEQ[i][MixerName],
+ DIRECT_LO_ENABLE_SEQ[i][MixerValue]);
+ if(ret)
+ printf("%s, set_mixer_ctrl_value_string error %d, %s, %s\n",
+ __func__, ret,
+ DIRECT_LO_ENABLE_SEQ[i][MixerName],
+ DIRECT_LO_ENABLE_SEQ[i][MixerValue]);
+ }
+ break;
+ default:
+ printf("%s, device error, device: %d", __func__, dev);
+ break;
+ }
+}
+
+static void do_internal_codec_close_sequence(int dev)
+{
+ int i, ret;
+
+ /*TODO: make it simpler*/
+ switch(dev) {
+ case DEV_SPK:
+ for(i = 0;i < ARRAY_SIZE(SPK_DISABLE_SEQ); i++){
+ ret = set_mixer_ctrl_value_string(SPK_DISABLE_SEQ[i][MixerName],
+ SPK_DISABLE_SEQ[i][MixerValue]);
+ if(ret)
+ printf("%s, set_mixer_ctrl_value_string error %d, %s, %s\n",
+ __func__, ret,
+ SPK_DISABLE_SEQ[i][MixerName],
+ SPK_DISABLE_SEQ[i][MixerValue]);
+ }
+
+ for(i = 0;i < ARRAY_SIZE(INT_CODEC_INTERCONN_SEQ); i++){
+ ret = set_mixer_ctrl_interconn_value(INT_CODEC_INTERCONN_SEQ[i][MixerName], 0);
+ if(ret)
+ printf("%s, set_mixer_ctrl_interconn_value error %d, %s, 0\n",
+ __func__, ret,
+ INT_CODEC_INTERCONN_SEQ[i][MixerName]);
+ }
+ break;
+ case DEV_HP:
+ for(i = 0;i < ARRAY_SIZE(HP_DISABLE_SEQ); i++){
+ ret = set_mixer_ctrl_value_string(HP_DISABLE_SEQ[i][MixerName],
+ HP_DISABLE_SEQ[i][MixerValue]);
+ if(ret)
+ printf("%s, set_mixer_ctrl_value_string error %d, %s, %s\n",
+ __func__, ret,
+ HP_DISABLE_SEQ[i][MixerName],
+ HP_DISABLE_SEQ[i][MixerValue]);
+ }
+ break;
+ case DEV_DIRECT:
+ for(i = 0;i < ARRAY_SIZE(DIRECT_DISABLE_SEQ); i++){
+ ret = set_mixer_ctrl_value_string(DIRECT_DISABLE_SEQ[i][MixerName],
+ DIRECT_DISABLE_SEQ[i][MixerValue]);
+ if(ret)
+ printf("%s, set_mixer_ctrl_value_string error %d, %s, %s\n",
+ __func__, ret,
+ DIRECT_DISABLE_SEQ[i][MixerName],
+ DIRECT_DISABLE_SEQ[i][MixerValue]);
+ }
+ break;
+ case DEV_DIRECT_LO:
+ for(i = 0;i < ARRAY_SIZE(DIRECT_LO_DISABLE_SEQ); i++){
+ ret = set_mixer_ctrl_value_string(DIRECT_LO_DISABLE_SEQ[i][MixerName],
+ DIRECT_LO_DISABLE_SEQ[i][MixerValue]);
+ if(ret)
+ printf("%s, set_mixer_ctrl_value_string error %d, %s, %s\n",
+ __func__, ret,
+ DIRECT_LO_DISABLE_SEQ[i][MixerName],
+ DIRECT_LO_DISABLE_SEQ[i][MixerValue]);
+ }
+ break;
+
+ default:
+ printf("%s, device error, device: %d", __func__, dev);
+ break;
+ }
+}
+
+static void do_ext_codec_open_sequence(int dev)
+{
+ int i, ret;
+
+ for(i = 0;i < ARRAY_SIZE(EXT_CODEC_INTERCONN_SEQ); i++){
+ ret = set_mixer_ctrl_interconn_value(EXT_CODEC_INTERCONN_SEQ[i][MixerName],
+ atoi(EXT_CODEC_INTERCONN_SEQ[i][MixerValue]));
+ if(ret)
+ printf("%s, set_mixer_ctrl_interconn_value error %d, %s, %s\n",
+ __func__, ret,
+ EXT_CODEC_INTERCONN_SEQ[i][MixerName],
+ EXT_CODEC_INTERCONN_SEQ[i][MixerValue]);
+ }
+
+ for(i = 0;i < ARRAY_SIZE(EXT_CODEC_ENABLE_SEQ); i++){
+ ret = set_mixer_ctrl_value_string(EXT_CODEC_ENABLE_SEQ[i][MixerName],
+ EXT_CODEC_ENABLE_SEQ[i][MixerValue]);
+ if(ret)
+ printf("%s, set_mixer_ctrl_value_string error %d, %s, %s\n",
+ __func__, ret,
+ EXT_CODEC_ENABLE_SEQ[i][MixerName],
+ EXT_CODEC_ENABLE_SEQ[i][MixerValue]);
+ }
+}
+
+static void do_ext_codec_close_sequence(int dev)
+{
+ int i, ret;
+
+ for(i = 0;i < ARRAY_SIZE(EXT_CODEC_INTERCONN_SEQ); i++){
+ ret = set_mixer_ctrl_interconn_value(EXT_CODEC_INTERCONN_SEQ[i][MixerName], 0);
+ if(ret)
+ printf("%s, set_mixer_ctrl_interconn_value error %d, %s, 0\n",
+ __func__, ret,
+ EXT_CODEC_INTERCONN_SEQ[i][MixerName]);
+ }
+
+ for(i = 0;i < ARRAY_SIZE(EXT_CODEC_DISABLE_SEQ); i++){
+ ret = set_mixer_ctrl_value_string(EXT_CODEC_DISABLE_SEQ[i][MixerName],
+ EXT_CODEC_DISABLE_SEQ[i][MixerValue]);
+ if(ret)
+ printf("%s, set_mixer_ctrl_value_string error %d, %s, %s\n",
+ __func__, ret,
+ EXT_CODEC_DISABLE_SEQ[i][MixerName],
+ EXT_CODEC_DISABLE_SEQ[i][MixerValue]);
+ }
+}
+
+static int is_using_internal_codec(void)
+{
+ int use_int_codec = get_mixer_ctrl_interconn_value("Ext_Speaker_Amp");
+
+ printf("%s, use_int_codec = %d\n",
+ __func__, use_int_codec);
+
+ return use_int_codec;
+}
+
+int set_UL_analog_gain_for_service(int dB)
+{
+ char ul_gain_char[16];
+
+ pthread_mutex_lock(&g_afe_enabled_lock);
+ if(!g_afe_enabled) {
+ printf("%s, phone call not start!\n", __func__);
+ pthread_mutex_unlock(&g_afe_enabled_lock);
+ return -EPERM;
+ }
+ sprintf(ul_gain_char, "%dDb", dB);
+ /* set_mixer_ctrl_value_string("Audio_PGA1_Setting", ul_gain_char); */
+ /* set_mixer_ctrl_value_string("Audio_PGA2_Setting", ul_gain_char); */
+ pthread_mutex_unlock(&g_afe_enabled_lock);
+
+ return 0;
+}
+
+int set_DL_analog_gain_for_service(int dB)
+{
+ char dl_gain_char[16];
+
+ pthread_mutex_lock(&g_afe_enabled_lock);
+ if(!g_afe_enabled) {
+ printf("%s, phone call not start!\n", __func__);
+ pthread_mutex_unlock(&g_afe_enabled_lock);
+ return -EPERM;
+ }
+ /* set spk gain (-9~8dB)*/
+ sprintf(dl_gain_char, "%dDb", dB-9);
+ /* set_mixer_ctrl_value_string("Lineout_PGAL_GAIN", dl_gain_char); */
+ /* set_mixer_ctrl_value_string("Lineout_PGAR_GAIN", dl_gain_char); */
+
+ /* set hp gain (-9~8dB)*/
+ /* we set hp gain for tuning purpose, not really use them */
+ sprintf(dl_gain_char, "%dDb", dB-9);
+ /* set_mixer_ctrl_value_string("Headset_PGAL_GAIN", dl_gain_char); */
+ /* set_mixer_ctrl_value_string("Headset_PGAR_GAIN", dl_gain_char); */
+ pthread_mutex_unlock(&g_afe_enabled_lock);
+
+ return 0;
+}
+
+int dynamic_switch_phone_call_path_for_service(int audio_device)
+{
+ int ret;
+
+ if (!g_afe_enabled) {
+ printf("%s, phone call not start! no device switch~\n", __func__);
+ return 0;
+ }
+
+ if (audio_device == DEV_DEFAULT) {
+ audio_device = get_default_device_for_service();
+ }
+
+ if (g_device == audio_device) {
+ printf("%s, device not change!\n", __func__);
+ return 0;
+ }
+
+ disable_phone_call_AFE_path_for_service();
+ ret = enable_phone_call_AFE_path_for_service(audio_device);
+ return ret;
+}
+
+/* for client calling */
+//enable audio path for modem.
+//return value: 0 if success, or negitive error number
+int enable_phone_call_AFE_path(int audio_device)
+{
+ char buf[256];
+
+ sprintf(buf, "%d,%d", FUNC_ENABLE_PHONE_CALL_AFE_PATH, audio_device);
+ return do_IPC_call(buf);
+}
+
+//close audio path for modem
+//return value: 0 if success, or negitive error number
+int disable_phone_call_AFE_path(void)
+{
+ char buf[256];
+
+ sprintf(buf, "%d", FUNC_DISABLE_PHONE_CALL_AFE_PATH);
+ return do_IPC_call(buf);
+}
+
+//get default device.
+//return value: default device setting
+int get_default_device(void)
+{
+ char buf[256];
+
+ sprintf(buf, "%d", FUNC_GET_DEFAULT_VALUE);
+ return do_IPC_call(buf);
+}
+
+//set UL analog gain
+//return value: 0 if success, or negitive error number
+int set_UL_analog_gain(int dB)
+{
+ char buf[256];
+ sprintf(buf, "%d,%d", FUNC_SET_UL_ANALOG_GAIN, dB);
+ return do_IPC_call(buf);
+}
+
+//set DL analog gain
+//return value: 0 if success, or negitive error number
+int set_DL_analog_gain(int dB)
+{
+ char buf[256];
+
+ sprintf(buf, "%d,%d", FUNC_SET_DL_ANALOG_GAIN, dB);
+ return do_IPC_call(buf);
+}
+
+//set BT WB on
+//return value: 0 if success, or negitive error number
+int set_BT_WB(int on)
+{
+ char buf[256];
+ sprintf(buf, "%d,%d", FUNC_SET_BT_WB, on);
+ return do_IPC_call(buf);
+}
+
+//change device when the phone call is enabled
+//return value: 0 if success, or negitive error number
+int dynamic_switch_phone_call_path(int audio_device)
+{
+ char buf[256];
+
+ sprintf(buf, "%d,%d", FUNC_DYNAMIC_SWITCH_PHONE_CALL_PATH, audio_device);
+ return do_IPC_call(buf);
+}
+
+//set phonecall sample rate
+//return value: 0 if success, or negitive error number
+int set_phonecall_rate(int rate)
+{
+ char buf[256];
+
+ sprintf(buf, "%d,%d", FUNC_SET_PHONE_CALL_SAMPLERATE, rate);
+ return do_IPC_call(buf);
+}
+
+#define LIBMODEM_AFE_CTRL_IPC_SEM "LIBMODEM_AFE_CTRL_IPC_SEM"
+static int do_IPC_call(const char* cmd)
+{
+ static char *send_cmd_node = "/tmp/libmodem-afe-ctrl/server_rcv";
+ static char *receive_cmd_node = "/tmp/libmodem-afe-ctrl/server_send";
+ int send_cmd_handler;
+ int receive_cmd_handler;
+ int read_size, call_result;
+ sem_t *sem_ipc;
+ char buf[256];
+
+#ifdef IPC_SEQ_DEBUG
+ int cmd_int;
+
+ cmd_int = atoi(cmd);
+ printf("%s_libmodem, cmd_int: %d\n", __func__, cmd_int);
+ fflush(stdout);
+#endif
+
+ sem_ipc = sem_open(LIBMODEM_AFE_CTRL_IPC_SEM, O_CREAT, 0644, 1);
+ if (sem_ipc == SEM_FAILED) {
+ printf("%s sem_open failed, WTF = = \n", __func__);
+ return errno;
+ }
+ sem_wait(sem_ipc);
+
+ send_cmd_handler = open(send_cmd_node, O_WRONLY);
+ receive_cmd_handler = open(receive_cmd_node, O_RDONLY);
+
+ write(send_cmd_handler, cmd, strlen(cmd));
+ read_size = read(receive_cmd_handler, buf, 256);
+
+ buf[read_size] = '\0';
+ call_result = atoi(buf);
+
+ close(send_cmd_handler);
+ close(receive_cmd_handler);
+
+ sem_post(sem_ipc);
+ return call_result;
+}
+