[Feature][ZXW-179]merge P52U02 version

Only Configure: No
Affected branch: master
Affected module: unknow
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: Yes
Doc Update: No

Change-Id: I4fa8f86757e71388ae88400914dae8b50cd00338
diff --git a/cp/ps/driver/inc/misc/drvs_voiceprocess.h b/cp/ps/driver/inc/misc/drvs_voiceprocess.h
index a5ab9f4..570a460 100755
--- a/cp/ps/driver/inc/misc/drvs_voiceprocess.h
+++ b/cp/ps/driver/inc/misc/drvs_voiceprocess.h
@@ -184,6 +184,41 @@
 	UINT32 sampfs;

 

 } T_HalAudioLoopTestPra;

+

+#ifdef ECALL_SUPPORT

+typedef enum

+{

+    ECALL_ST_INIT = 0,

+	ECALL_ST_OPEN,				

+	ECALL_ST_START,		

+    ECALL_ST_IDLE,

+    ECALL_ST_RX_IDLE,

+    ECALL_ST_TX_IDLE,

+    ECALL_ST_INUSE,

+    ECALL_ST_RX_INUSE,

+    ECALL_ST_TX_INUSE,     

+	ECALL_ST_STOP,

+	ECALL_ST_CLOSE,	

+    ECALL_ST_MAX

+} T_Ecall_State;

+

+ 

+typedef struct

+{

+	T_DrvEcall_Opt	opt;

+	ZOSS_TIMER_ID timerId ;

+	ZOSS_SEMAPHORE_ID wrSemaphore; 

+	ZOSS_SEMAPHORE_ID rdSemaphore;

+	T_Ecall_State ecallSta;

+    T_Ecall_State ecallRxSta;

+	T_Ecall_State ecallTxSta;	

+	unsigned char* rxDataBuf;

+	unsigned char* txDataBuf;

+	int dataBufSize;

+

+} T_Hal_EcallData; 

+#endif

+

 typedef struct

 {

 	//use for vp data process

@@ -248,6 +283,9 @@
     BOOL vpLoopBkRunning;//23 

 	BOOL rxMuteEn; //24

 	BOOL firstRegZCATFlag; //25

+#ifdef ECALL_SUPPORT	

+	T_Hal_EcallData	ecallData;//26

+#endif	

 } T_zDrvVoice_GbVar; //T_zDrvVoice_GbVar

 

 typedef struct

diff --git a/cp/ps/driver/inc/misc/drvs_volte.h b/cp/ps/driver/inc/misc/drvs_volte.h
index fd31c2d..980e0e3 100755
--- a/cp/ps/driver/inc/misc/drvs_volte.h
+++ b/cp/ps/driver/inc/misc/drvs_volte.h
@@ -60,6 +60,17 @@
 

 } T_DrvVoice_3G_Opt;

 

+#ifdef ECALL_SUPPORT

+ typedef struct 

+ {

+	 

+	 SINT32 (*drv_Get_Ecall_State)(VOID); 		   

+	 SINT32 (*drv_Ecall_Read)(UINT8 *pBuf,UINT32 *inSize);			

+	 SINT32 (*drv_Ecall_Write)(UINT8 *pBuf,UINT32 inSize);		

+ 

+ } T_DrvEcall_Opt;

+#endif

+

  typedef struct 

  {

      void (*drv_dtmfrx_report_cb)(char *dtmf_string, unsigned char string_len);

@@ -82,5 +93,8 @@
 SINT32 zDrvVolte_AmrDecoder(UINT8 *pInputBuf,UINT32 inSize,UINT8 *pOutputBuf,UINT32* pPutSize);

 VOID zDrvVolte_AmrEncoderDeinit(VOID);

 VOID zDrvVolte_AmrDecoderDeinit(VOID);

+#ifdef ECALL_SUPPORT

+VOID zDrvEcall_SetCallbacks(T_DrvEcall_Opt ecallObj);

+#endif

 #endif

 

diff --git a/cp/ps/driver/src/chipsets/src/audio_base/audio_lib/amr/lib/armv7-a/GCC/amr.a b/cp/ps/driver/src/chipsets/src/audio_base/audio_lib/amr/lib/armv7-a/GCC/amr.a
index df1f587..f84072c 100755
--- a/cp/ps/driver/src/chipsets/src/audio_base/audio_lib/amr/lib/armv7-a/GCC/amr.a
+++ b/cp/ps/driver/src/chipsets/src/audio_base/audio_lib/amr/lib/armv7-a/GCC/amr.a
Binary files differ
diff --git a/cp/ps/driver/src/chipsets/src/audio_base/i2s/hal_i2s.c b/cp/ps/driver/src/chipsets/src/audio_base/i2s/hal_i2s.c
index dfd7946..983a92a 100755
--- a/cp/ps/driver/src/chipsets/src/audio_base/i2s/hal_i2s.c
+++ b/cp/ps/driver/src/chipsets/src/audio_base/i2s/hal_i2s.c
@@ -2755,6 +2755,21 @@
 	i2sDmaState[tId][I2S_RX].channel = (tId == I2S_1) ? (DMA_CH_I2S0_RX0) : (DMA_CH_I2S1_RX0);

 	i2sDmaState[tId][I2S_RX].ch = dma_request_channel(mask, zx29_dma_filter_fn, (void*)(i2sDmaState[tId][I2S_RX].channel));

 

+    if(i2sDmaState[tId][I2S_RX].ch == NULL){

+        for(i = 0; i <= 5; i++){

+            zOss_Sleep(1);

+            i2sDmaState[tId][I2S_RX].ch = dma_request_channel(mask, zx29_dma_filter_fn, (void*)(i2sDmaState[tId][I2S_RX].channel));

+            

+            if(i2sDmaState[tId][I2S_RX].ch != NULL){

+                break;

+            }

+            else if(i == 5){

+                zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "i2s_DmaRxInit error, i2sDmaState[%d][%d].ch is NULL\n", tId, I2S_RX);

+                return DRV_ERROR;

+            }

+        }

+    }

+

 	for (i = 0; i < I2S_OUT_BUF_NUM; i++) {

 		temp[i].dest_addr 	= i2sDmaState[tId][I2S_RX].dma_phyaddr  + (i2sStream->rxLen) * i;

 		temp[i].src_addr	= (tId == I2S_1) ? (ZX29_I2S0_PHYS + 0x1c) : (ZX29_I2S1_PHYS + 0x1c);

@@ -2825,6 +2840,21 @@
 	i2sDmaState[tId][I2S_TX].channel = (tId == I2S_1) ? (DMA_CH_I2S0_TX) : (DMA_CH_I2S1_TX);

 	i2sDmaState[tId][I2S_TX].ch = dma_request_channel(mask, zx29_dma_filter_fn, (void*)(i2sDmaState[tId][I2S_TX].channel));

 

+    if(i2sDmaState[tId][I2S_TX].ch == NULL){

+        for(i = 0; i <= 5; i++){

+            zOss_Sleep(1);

+            i2sDmaState[tId][I2S_TX].ch = dma_request_channel(mask, zx29_dma_filter_fn, (void*)(i2sDmaState[tId][I2S_TX].channel));

+            

+            if(i2sDmaState[tId][I2S_TX].ch != NULL){

+                break;

+            }

+            else if(i == 5){

+                zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "i2s_DmaTxInit error, i2sDmaState[%d][%d].ch is NULL\n", tId, I2S_TX);

+                return DRV_ERROR;

+            }

+        }

+    }

+

 	for (i = 0; i < I2S_OUT_BUF_NUM; i++) {

 		temp[i].src_addr 	= i2sDmaState[tId][I2S_TX].dma_phyaddr + (txStream->txLen) * i;

 		temp[i].dest_addr	= (tId == I2S_1) ? (ZX29_I2S0_PHYS + 0x1c) : (ZX29_I2S1_PHYS + 0x1c);

diff --git a/cp/ps/driver/src/chipsets/src/audio_base/voiceprocess/hal_voiceprocess.c b/cp/ps/driver/src/chipsets/src/audio_base/voiceprocess/hal_voiceprocess.c
index 0acd415..8193de0 100755
--- a/cp/ps/driver/src/chipsets/src/audio_base/voiceprocess/hal_voiceprocess.c
+++ b/cp/ps/driver/src/chipsets/src/audio_base/voiceprocess/hal_voiceprocess.c
@@ -60,7 +60,20 @@
 /****************************************************************************

 * 	                                           Local Types

 ****************************************************************************/

+	typedef enum

+	{

+		VBUF_SEM = 0,//voice buffer

+		ECALL_SEM,		

+		SEM_MAX

+	} T_Sem_Owner;

 

+	typedef enum

+	{

+		DIR_RX,

+		DIR_TX, 	

+		DIR_ALL,

+		DIR_MAX

+	} T_Data_Dir_Type;

 

 /****************************************************************************

 * 	                                           Local Constants

@@ -72,6 +85,11 @@
 SINT32 voice_ToneMixerStop(VOID);//xiu gai chu sheng ming

 SINT32 zDrvI2S_Read_Start_Do(T_ZDrvI2S_Id tId, T_ZDrvI2s_Params *params);//xiu gai chu sheng ming

 SINT32 zDrvI2S_Write_Start_Do(T_ZDrvI2S_Id tId, T_ZDrvI2s_Params *params);//xiu gai chu sheng ming

+#ifdef ECALL_SUPPORT

+SINT32 drv_Get_Ecall_State(VOID);	

+SINT32 drv_Ecall_Read(UINT8 *pBuf,UINT32 *inSize);

+SINT32 drv_Ecall_Write(UINT8 *pBuf,UINT32 inSize);	   

+#endif

 /****************************************************************************

 * 	                                          Global Constants

 ****************************************************************************/

@@ -110,6 +128,9 @@
     FALSE, //23 vpLoopBkRunning

 	FALSE, //24 rxMuteEn

 	FALSE, //25 firstRegZCATFlag

+#ifdef ECALL_SUPPORT	

+	0 //26 ecallData

+#endif

 };

 

 static T_zDrvVp_State s_vpState =

@@ -155,6 +176,15 @@
 static UINT32 s_TxAllDataSaveLen = 0;

 #endif

 */

+#ifdef ECALL_SUPPORT

+//extern T_DrvEcall_Opt  gDrvEcall_Obj; 

+T_DrvEcall_Opt t_ecallObj ={

+	drv_Get_Ecall_State,		  

+	drv_Ecall_Read,		   

+	drv_Ecall_Write,  

+

+};

+#endif

 

 extern T_ZDrv_VpInOutBuffer vpInOutBuffer;

 

@@ -224,6 +254,8 @@
 SINT32 voice_RcdStart(T_ZDrvRcd_InfoParam *pParam);//xiu gai chu sheng ming

 SINT32 zDrvI2S_Read_Start(T_ZDrvI2S_Id tId, T_ZDrvI2s_Params *params, T_ZDrvI2S_Cfg *ptCfg);//xiu gai chu sheng ming

 SINT32 zDrvI2S_Write_Start(T_ZDrvI2S_Id tId, T_ZDrvI2s_Params *params, T_ZDrvI2S_Cfg *ptCfg);//xiu gai chu sheng ming

+SINT32 zDrvExtAudio_GetBuf(UINT8 **pBuf, UINT32 *uiLen);

+

 /****************************************************************************

 * 	                                          Function Definitions

 ****************************************************************************/

@@ -290,6 +322,387 @@
 #endif

 

 

+#ifdef ECALL_SUPPORT

+SINT32 rdsem_count_Init(T_Sem_Owner owner)

+{

+	UINT32 i = 0;

+	UINT32 semCount = 0;

+	SINT32 Count = 0;

+    ZOSS_SEMAPHORE_ID rdSem;	

+    if(owner == ECALL_SEM){

+	    rdSem = g_voiceVar.ecallData.rdSemaphore;		

+		semCount = zOss_GetSemaphoreCount(rdSem);

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "rdsem_count_Init owner=%d, rxSem count=%d\n",owner,semCount);

+

+		Count = semCount;

+		if(Count > 0)  {

+			for(i = 0; i < Count; i++) {

+				zOss_GetSemaphore(rdSem, ZOSS_NO_WAIT);

+			}

+		}

+    }

+	return DRV_SUCCESS;

+}

+

+SINT32 wrsem_count_Init(T_Sem_Owner owner)

+{

+	UINT32 i = 0;

+	UINT32 semCount = 0;

+	SINT32 Count = 0;

+

+    ZOSS_SEMAPHORE_ID wrSem;	

+    if(owner == ECALL_SEM){

+		wrSem = g_voiceVar.ecallData.wrSemaphore;

+

+		semCount = zOss_GetSemaphoreCount(wrSem);

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "wrsem_count_Init owner=%d, txSem count=%d \n",owner,semCount);

+

+		

+		Count = 3 - semCount;	

+		if(Count > 0) {

+			for(i = 0; i < Count; i++) {

+				zOss_PutSemaphore(wrSem);

+			}

+		} else if(Count < 0) {

+			Count = 0 - Count;

+			for(i = 0; i < Count; i++) {

+				zOss_GetSemaphore(wrSem, ZOSS_NO_WAIT);

+			}

+		}

+    }

+ 

+	return DRV_SUCCESS;

+}

+void ecallTimerCallBack(SINT32 para)

+{

+//	complete_all(&s_voice_completion);

+	zOss_PutSemaphore(g_voiceVar.ecallData.wrSemaphore);

+	zOss_PutSemaphore(g_voiceVar.ecallData.rdSemaphore);

+//	zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecallTimerCallBack timer=%u\n", cpu_clock(0)>>10);

+}

+SINT32 ecall_Init(VOID)

+{

+

+	g_voiceVar.ecallData.rdSemaphore = zOss_CreateSemaphore("ecall_rd_sem", 0);

+	if(NULL == g_voiceVar.ecallData.rdSemaphore) {

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "create ecall_rd_sem err \n");

+		return DRV_ERROR;

+	}

+

+	g_voiceVar.ecallData.wrSemaphore  = zOss_CreateSemaphore("ecall_wr_sem", 0);

+	if(NULL == g_voiceVar.ecallData.wrSemaphore) {

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "create ecall_wr_sem err \n");

+	    zOss_DeleteSemaphore(g_voiceVar.ecallData.rdSemaphore);

+    	g_voiceVar.ecallData.rdSemaphore = ZOSS_NULL;		

+		return DRV_ERROR;

+	}

+	

+	 g_voiceVar.ecallData.timerId  = zOss_CreateTimer("ecall_frameTimer", ecallTimerCallBack, 0, TRUE);

+	 zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall TimerId=%p\n", g_voiceVar.ecallData.timerId);

+	if(!g_voiceVar.ecallData.timerId)

+	{

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_frameTimer  failed\n");

+	    zOss_DeleteSemaphore(g_voiceVar.ecallData.rdSemaphore);

+    	g_voiceVar.ecallData.rdSemaphore = ZOSS_NULL;	

+	    zOss_DeleteSemaphore(g_voiceVar.ecallData.wrSemaphore);

+    	g_voiceVar.ecallData.wrSemaphore = ZOSS_NULL;			

+		return DRV_ERROR;

+	}

+	g_voiceVar.ecallData.ecallSta = ECALL_ST_INIT;	

+	zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_Init success. \r\n");

+

+

+

+

+	

+	return DRV_SUCCESS;	

+}

+#define ECALL_NB_MEM_SIZE		320

+#define ECALL_WB_MEM_SIZE		640

+

+SINT32 ecall_Open(UINT32 fs)

+{

+	SINT32 ret = DRV_SUCCESS;

+	int bufsize;

+	

+	zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_Open  start \n" );

+

+	if ((g_voiceVar.ecallData.ecallSta !=  ECALL_ST_CLOSE)&&(g_voiceVar.ecallData.ecallSta !=  ECALL_ST_INIT))

+	{

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_Open error: ecallSta =%d\n", g_voiceVar.ecallData.ecallSta);

+		return DRV_ERR_OPEN_TIMES;

+	}

+

+	if(fs == 8000)

+	{

+		bufsize = ECALL_NB_MEM_SIZE;

+

+	}

+	else if(fs == 16000)

+	{

+		bufsize = ECALL_WB_MEM_SIZE;

+

+	}

+	else

+	{

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_Open error: fs =%d\n", fs);

+		return DRV_ERR_INVALID_PARAM;

+

+	}

+

+

+	g_voiceVar.ecallData.rxDataBuf = zOss_Malloc(bufsize);

+	if (g_voiceVar.ecallData.rxDataBuf == NULL)

+	{

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall Failed to allocate rxDataBuf\n");

+		return DRV_ERROR;

+	}

+	g_voiceVar.ecallData.txDataBuf = zOss_Malloc(bufsize);

+	if (g_voiceVar.ecallData.txDataBuf == NULL)

+	{

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall Failed to allocate txDataBuf\n");

+	    zOss_Free(g_voiceVar.ecallData.rxDataBuf);		

+		return DRV_ERROR;

+	}

+	g_voiceVar.ecallData.dataBufSize = bufsize;

+

+	g_voiceVar.ecallData.ecallSta = ECALL_ST_OPEN;

+	g_voiceVar.ecallData.ecallRxSta = ECALL_ST_RX_IDLE;

+	g_voiceVar.ecallData.ecallTxSta = ECALL_ST_TX_IDLE;

+

+	

+	zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_Open  end!\n");

+

+	return DRV_SUCCESS;

+

+}

+

+

+SINT32 ecall_Close(VOID)

+{

+	SINT32 ret = DRV_SUCCESS;

+

+	if (g_voiceVar.ecallData.ecallSta ==  ECALL_ST_CLOSE)

+	{

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_Close error: ecallSta =%d\n", g_voiceVar.ecallData.ecallSta);

+		return DRV_ERR_NOT_OPENED;

+	}

+

+	if ((g_voiceVar.ecallData.txDataBuf == NULL)||(g_voiceVar.ecallData.txDataBuf == NULL) || (g_voiceVar.ecallData.dataBufSize  == 0)) 

+	{

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_Close buf para is null !\n");

+		return DRV_ERROR;

+	}

+

+	zOss_Free(g_voiceVar.ecallData.rxDataBuf);

+	zOss_Free(g_voiceVar.ecallData.txDataBuf);

+

+	g_voiceVar.ecallData.dataBufSize = 0;

+	g_voiceVar.ecallData.rxDataBuf = NULL;

+	g_voiceVar.ecallData.txDataBuf = NULL;

+	g_voiceVar.ecallData.ecallSta = ECALL_ST_CLOSE;

+

+	

+	zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_Close  end!\n");

+

+	return DRV_SUCCESS;

+

+

+

+}

+

+

+SINT32 ecall_Start(VOID)

+{

+	SINT32 ret = DRV_SUCCESS;

+

+	zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_Start start\n");

+	if((g_voiceVar.ecallData.ecallSta != ECALL_ST_OPEN)&&(g_voiceVar.ecallData.ecallSta != ECALL_ST_STOP))

+	{

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_Start not support ecallSta=%d\n",g_voiceVar.ecallData.ecallSta);

+		ret = DRV_ERR_START_TIMES;

+	}

+

+

+	zOss_StartTimer(g_voiceVar.ecallData.timerId, 20, ecallTimerCallBack, 0);

+	zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_Start zOss_StartTimer start\n");

+	g_voiceVar.ecallData.ecallSta = ECALL_ST_START;	

+	

+	zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO,  "ecall_Start end \n");

+

+	return DRV_SUCCESS;

+}

+

+SINT32 ecall_Stop(VOID)

+{

+	SINT32  ret = DRV_SUCCESS;

+	if(g_voiceVar.ecallData.ecallSta != ECALL_ST_STOP)

+	{

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_Stop not support ecallSta=%d\n",g_voiceVar.ecallData.ecallSta);

+		ret = DRV_ERR_START_TIMES;

+	}  

+

+	zOss_PutSemaphore(g_voiceVar.ecallData.rdSemaphore);

+	zOss_PutSemaphore(g_voiceVar.ecallData.wrSemaphore);

+	zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_Stop put rd wr sem\n");	

+	zOss_StopTimer(g_voiceVar.ecallData.timerId);

+	zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_Stop zOss_StopTimer\n");

+

+	g_voiceVar.ecallData.ecallSta = ECALL_ST_STOP;	

+

+	zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_Stop end\n");

+	return ret;

+}

+

+SINT32 update_ecall_state(T_Data_Dir_Type dir)

+{

+	int ret = DRV_SUCCESS;

+

+	

+	if(g_voiceVar.ecallData.opt.drv_Get_Ecall_State == NULL)

+	{	

+		return DRV_ERR_NOT_SUPPORTED;

+	}

+

+	if(g_voiceVar.ecallData.opt.drv_Get_Ecall_State() == 1)	

+	{						

+		if((dir == DIR_RX)&&(g_voiceVar.ecallData.ecallRxSta != ECALL_ST_RX_INUSE))

+		{

+			wrsem_count_Init(ECALL_SEM);

+			g_voiceVar.ecallData.ecallRxSta = ECALL_ST_RX_INUSE;

+			zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "update_ecall_state rx state change old ecallRxSta = %d\n", g_voiceVar.ecallData.ecallRxSta);

+			

+		}

+		else if((dir == DIR_TX)&&(g_voiceVar.ecallData.ecallTxSta != ECALL_ST_TX_INUSE))

+		{

+

+			rdsem_count_Init(ECALL_SEM);			

+			g_voiceVar.ecallData.ecallTxSta = ECALL_ST_TX_INUSE;	

+			zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "update_ecall_state tx state change old ecallTxSta = %d\n", g_voiceVar.ecallData.ecallTxSta);

+			

+		}

+		else

+		{

+			zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "update_ecall_state return 1,but dir not support dir = %d\n",dir);

+			ret = DRV_ERR_NOT_SUPPORTED;			

+		}	

+		

+

+	}

+	else

+	{

+	    if(dir == DIR_RX)

+		{

+			g_voiceVar.ecallData.ecallRxSta = ECALL_ST_RX_IDLE;	

+		

+	    }

+		else if(dir == DIR_TX)

+		{

+			g_voiceVar.ecallData.ecallTxSta = ECALL_ST_TX_IDLE;

+

+		}

+		else

+		{

+			zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "update_ecall_state return 0,but dir not support dir = %d\n",dir);

+			ret = DRV_ERR_NOT_SUPPORTED;

+

+		}		

+

+	}	

+	if((g_voiceVar.ecallData.ecallRxSta == ECALL_ST_RX_IDLE)&&(g_voiceVar.ecallData.ecallTxSta == ECALL_ST_TX_IDLE))

+	{

+		if(g_voiceVar.ecallData.ecallSta == ECALL_ST_START)

+		{

+	    	ret = ecall_Stop();	

+			if (ret != DRV_SUCCESS)

+			{

+				zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "update_ecall_state ecall_Start err\n");

+			}

+		}

+		

+	}

+	else

+	{

+		if(g_voiceVar.ecallData.ecallSta != ECALL_ST_START)

+		{

+			ret = ecall_Start();

+			if (ret != DRV_SUCCESS)

+			{

+				zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "update_ecall_state ecall_Stop err\n");

+			}		

+		}

+	}

+	

+	return ret;

+}

+

+

+SINT32 ecall_GetRxBuf(UINT8 **pBuf, UINT32 *uiLen)

+{

+

+	SINT32 ret = DRV_SUCCESS;

+

+	if ((NULL == pBuf) || (NULL == uiLen))

+	{

+

+	    zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_GetRxBuf error, ipara is null \n");

+		//zDrv_ASSERT(0);		

+		return DRV_ERR_INVALID_PARAM;

+	}

+

+	if ((g_voiceVar.ecallData.ecallSta == ECALL_ST_INIT)||(g_voiceVar.ecallData.ecallSta == ECALL_ST_CLOSE) ) 

+	{

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_GetRxBuf error, invalid ecallSta = %d\n", g_voiceVar.ecallData.ecallSta);

+	

+		return DRV_ERR_NOT_OPENED;

+	}

+	if ((g_voiceVar.ecallData.txDataBuf == NULL) || (g_voiceVar.ecallData.dataBufSize == 0)) 

+	{

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_GetRxBuf error, return para is null !\n");

+		return DRV_ERROR;

+	}

+

+

+	*pBuf = g_voiceVar.ecallData.rxDataBuf;

+	*uiLen = g_voiceVar.ecallData.dataBufSize;

+	

+

+	return ret;

+}

+

+SINT32 ecall_GetTxBuf(UINT8 **pBuf, UINT32 *uiLen)

+{

+

+	SINT32 ret = DRV_SUCCESS;

+

+	if ((NULL == pBuf) || (NULL == uiLen) )

+	{

+		//zDrv_ASSERT(0);

+	    zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_GetTxBuf error, ipara is null \n");

+		//zDrv_ASSERT(0);				

+		return DRV_ERR_INVALID_PARAM;

+	}

+

+	if ((g_voiceVar.ecallData.ecallSta == ECALL_ST_INIT)||(g_voiceVar.ecallData.ecallSta == ECALL_ST_CLOSE) ) 

+	{

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_GetTxBuf error, invalid ecallSta = %d\n", g_voiceVar.ecallData.ecallSta);

+	

+		return DRV_ERR_NOT_OPENED;

+	}

+	if ((g_voiceVar.ecallData.txDataBuf == NULL)||(g_voiceVar.ecallData.txDataBuf == NULL) || (g_voiceVar.ecallData.dataBufSize  == 0)) 

+	{

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_GetTxBuf error, return para is null !\n");

+		return DRV_ERROR;

+	}

+

+

+	*pBuf = g_voiceVar.ecallData.txDataBuf;

+	*uiLen = g_voiceVar.ecallData.dataBufSize;

+

+	return ret;

+}

+#endif

+

 SINT32 zDrv_Init(VOID)

 {

 	if (g_voiceVar.g_isUseTdm != 1)

@@ -489,6 +902,48 @@
 #endif	

 	return ret;

 }

+#ifdef ECALL_SUPPORT

+SINT32 ecall_Write(const UINT8 *pBuf, UINT32 uiLen)

+{

+	int ret = 0;

+	if(g_voiceVar.ecallData.opt.drv_Ecall_Write == NULL)

+	{	

+		return DRV_ERR_NOT_SUPPORTED;

+	}

+	if( g_voiceVar.ecallData.ecallRxSta == ECALL_ST_RX_INUSE)

+	{

+		zOss_GetSemaphore(g_voiceVar.ecallData.wrSemaphore, 60);

+		ret = g_voiceVar.ecallData.opt.drv_Ecall_Write(pBuf, uiLen);

+	}

+	else

+	{

+		ret = g_voiceVar.ecallData.opt.drv_Ecall_Write(pBuf, uiLen);		

+		

+	}	

+	return ret;

+}

+SINT32 ecall_Read(const UINT8 **pBuf, UINT32 *uiLen)

+{

+	int ret = 0;

+

+	if(g_voiceVar.ecallData.opt.drv_Ecall_Read == NULL)

+	{	

+		return DRV_ERR_NOT_SUPPORTED;

+	}

+	if( g_voiceVar.ecallData.ecallTxSta == ECALL_ST_TX_INUSE)

+	{

+	    zOss_GetSemaphore(g_voiceVar.ecallData.rdSemaphore,  60);

+		ret = g_voiceVar.ecallData.opt.drv_Ecall_Read(*pBuf, uiLen);

+	}

+	else

+	{

+		ret = zDrvExtAudio_Read(pBuf, uiLen);

+	}

+

+

+	return ret;

+}

+#endif

 SINT32 zDrvExtAudio_Write_Stop()

 {

 	int ret = 0;

@@ -771,7 +1226,14 @@
 	vp_rxsem_count_Init();

 	vp_txsem_count_Init();

 #endif

-	

+#ifdef ECALL_SUPPORT

+	if(g_voiceVar.audio_ctrlFlag.isUseEcall == 1)

+	{

+		rdsem_count_Init(ECALL_SEM);

+		wrsem_count_Init(ECALL_SEM);

+        //zDrvEcall_SetCallbacks(t_ecallObj);//for test

+	}

+#endif		

 	g_voiceVar.muteCount = 0;

 	s_speechState.txSaveLen = 0;

 	s_speechState.rxSaveLen = 0;

@@ -867,7 +1329,27 @@
         }

         zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp_CfgParam zDrvVp_DtmfSoftwareStart end\n");

     }

-    

+#ifdef ECALL_SUPPORT	

+	if(g_voiceVar.audio_ctrlFlag.isUseEcall == 1)

+	{

+

+	   if(g_voiceVar.volteIsWb == 1)

+	   {

+	   	   ret = ecall_Open(16000);

+	   }

+	   else

+	   {

+		   ret = ecall_Open(8000);

+

+	   }

+	   if (ret != DRV_SUCCESS)

+	   {

+		   zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_Open error,ret=%d", ret);

+	   }

+	   

+	

+	}

+#endif	

 	return ret;

 }

 

@@ -1455,7 +1937,16 @@
         g_voiceVar.dtmfDirSel = DTMF_IDLE;

         zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp_Close zDrvVp_DtmfSoftwareStop end\n");

     }

-

+#ifdef ECALL_SUPPORT

+	if(g_voiceVar.audio_ctrlFlag.isUseEcall == 1)

+	{

+		ret = ecall_Close();

+		if (ret != DRV_SUCCESS)

+		{

+		   zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_Open error,ret=%d", ret);

+		}	

+	}

+#endif	

 	g_voiceVar.vpI2sStatus = VP_I2S_IDLE;

 	g_voiceVar.voiceMode = MAX_VOICE_MODE;

 	zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp_Close,g_voiceVar.vpI2sStatus=%d\n", g_voiceVar.vpI2sStatus);

@@ -1507,7 +1998,7 @@
 	}

 	

 	zOss_StartTimer(s_voiceTimerId, 20, voiceTimerCallBack, 0);

-	zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp_VoiceI2sStart zOss_StartTimer\n");

+	zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp_VoiceI2sStart VB zOss_StartTimer\n");

 

 	ret = zDrvI2S_Write_Start(I2S_2, &s_speechState.i2sWriteParam, s_vpState.pVpInnerI2sCfg);

 

@@ -1523,6 +2014,19 @@
 	{

 		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp_VoiceI2sStart error12:zDrvI2S_Write I2S_2 ret=%d", ret);

 	}

+	

+	ret += zDrvI2S_GetBuf(I2S_2, &write_buf, &write_len);

+	if (ret != DRV_SUCCESS)

+	{

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp_VoiceI2sStart error13:zDrvI2S_GetBuf I2S_2 ret=%d", ret);

+		return DRV_ERROR;

+	}

+	zOss_Memset(write_buf, 0, write_len);

+	ret = zDrvI2S_Write(I2S_2, write_buf, write_len);

+	if (ret != DRV_SUCCESS)

+	{

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp_VoiceI2sStart error14:zDrvI2S_Write I2S_2 ret=%d", ret);

+	}

 

 	voicebuffer_dlqueue_write(s_speechState.pVpTempRxOutPutBuffer, s_speechState.totalFrameBufSize);

 #else	

@@ -1792,6 +2296,16 @@
 	//zDrvI2s_TxRlsSemaBeforeStop(I2S_1);

 	zDrvExtAudio_RlsAllSemaBeforeStop();

 #endif

+#ifdef ECALL_SUPPORT

+	if(g_voiceVar.audio_ctrlFlag.isUseEcall == 1)

+	{

+    	ret = ecall_Stop();	

+		if (ret != DRV_SUCCESS)

+		{

+			zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "zDrvVp_VoiceWorkStop ecall_Stop err\n");

+		}

+	}

+#endif	

 	zDrvI2s_RxRlsSemaBeforeStop(I2S_2);

 	zDrvI2s_TxRlsSemaBeforeStop(I2S_2);

 

@@ -1909,7 +2423,16 @@
 		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp_VolteReadStop zOss_StopTimer\n");

 #endif

 	}

-

+#ifdef ECALL_SUPPORT	

+	if(g_voiceVar.audio_ctrlFlag.isUseEcall == 1)

+	{

+    	ret = ecall_Stop();	

+		if (ret != DRV_SUCCESS)

+		{

+			zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "zDrvVolte_ReadStop ecall_Stop err\n");

+		}

+	}

+#endif

 	zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "zDrvVolte_ReadStop\n");

 	return ret;

 }

@@ -2070,8 +2593,10 @@
 	SINT32  ret = DRV_SUCCESS;

 	UINT8 *write_buf = NULL;

 	UINT32 write_len = 0;

+	UINT8 *e_write_buf = NULL;

+	UINT32 e_write_len = 0;

 	UINT32 i = 0, j = 0;

-

+    UINT8 e_reg_flag = 0;

 #ifdef TEST_WHITE_NOISE

 	// UINT32 tempCount = 0;

 	//zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "test the white noise");

@@ -2090,7 +2615,27 @@
 		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp_WriteDataToCodec write data length err,count=%d,writebuffersize=%d \n", count, s_speechState.i2sWriteParam.buffersize);

 		return DRV_ERR_INVALID_PARAM;

 	}

+#ifdef ECALL_SUPPORT	

+	if((g_voiceVar.audio_ctrlFlag.isUseEcall == 1)&&(g_voiceVar.ecallData.opt.drv_Get_Ecall_State != NULL))

+	{

+	 	e_reg_flag = 1;

+	}

+	else

+	{

+		e_reg_flag = 0;

 

+	}

+	

+	if(e_reg_flag == 1)

+	{		

+		ret = update_ecall_state(DIR_RX); 

+		if (ret == DRV_ERR_NOT_SUPPORTED)

+		{

+			zOss_Printf(SUBMDL_HAL, PRINT_LEVEL_NORMAL, "vp_WriteDataToCodec get__ecall_state fun not register or invalid para !\n");

+	

+		}	

+	}	

+#endif

 

 #ifdef  CONFIG_VOICE_BUFFER_DRV  	

 

@@ -2154,7 +2699,24 @@
 	}

 

 #else

-	ret = zDrvExtAudio_GetBuf(&write_buf, &write_len);

+	if (e_reg_flag == 1)

+	{

+#ifdef ECALL_SUPPORT	

+		ret = ecall_GetRxBuf(&e_write_buf,&e_write_len);

+		if ((ret == DRV_SUCCESS) && (e_write_buf != NULL) && (e_write_len == s_speechState.i2sWriteParam.buffersize))

+		{

+

+			zOss_Memcpy(e_write_buf, pBuf, s_speechState.totalFrameBufSize);

+

+		}

+#endif		

+		ret = zDrvExtAudio_GetBuf(&write_buf, &write_len);

+

+	}

+	else

+	{

+		ret = zDrvExtAudio_GetBuf(&write_buf, &write_len);

+	}

 	if ((ret == DRV_SUCCESS) && (write_buf != NULL) && (write_len == s_speechState.i2sWriteParam.buffersize))

 	{

 		if (pBuf !=  s_speechState.pVpTempRxInBuffer)

@@ -2226,8 +2788,12 @@
     		}

         }

         #endif

-        

+

+#ifdef ECALL_SUPPORT

+        if ((g_voiceVar.vProcIsNormal == TRUE)&&(g_voiceVar.ecallData.ecallRxSta != ECALL_ST_RX_INUSE))

+#else        

 		if (g_voiceVar.vProcIsNormal == TRUE)

+#endif		

 		{

 

 			ret = VoiceProc_RxProcess(& s_speechState.pVpTempRxInBuffer, & s_speechState.pVpTempRxOutPutBuffer, s_speechState.frameCount);

@@ -2306,7 +2872,31 @@
 		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp_WriteDataToCodec zDrvI2S_GetBuf:I2S1:ret=%d,write_buf = %p,write_len = %d.\n", ret, write_buf, write_len);

 		return DRV_ERROR;

 	}

-	ret = zDrvExtAudio_Write(write_buf, write_len);

+	if(e_reg_flag == 1)

+	{	

+#ifdef ECALL_SUPPORT

+		ret = ecall_Write(e_write_buf, e_write_len);

+		if (ret != DRV_SUCCESS)

+		{

+			zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "ecall_Write err ret=%d !\n", ret);

+

+		}		

+		if( g_voiceVar.ecallData.ecallRxSta == ECALL_ST_RX_INUSE)

+		{

+		    zOss_Memset(write_buf, 0, write_len);//need  mute rx		

+		}

+#endif		

+		ret = zDrvExtAudio_Write(write_buf, write_len);

+

+

+

+

+

+	}

+	else

+	{

+		ret = zDrvExtAudio_Write(write_buf, write_len);

+	}

 

 #endif

 

@@ -2330,6 +2920,8 @@
 	UINT8 temp8bit = 0;

 	UINT8 *ptemp8bit = NULL;

 #endif

+	UINT8 e_reg_flag = 0;

+

 	if (pBuf == NULL)

 	{

 		return DRV_ERR_INVALID_PARAM;

@@ -2340,6 +2932,31 @@
 		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp_ReadDataFromCodec read data length err,count=%d,readbuffersize=%d \n", count, s_speechState.i2sReadParam.buffersize);

 		return DRV_ERR_INVALID_PARAM;

 	}

+#ifdef ECALL_SUPPORT	

+	if((g_voiceVar.audio_ctrlFlag.isUseEcall == 1)&&(g_voiceVar.ecallData.opt.drv_Get_Ecall_State != NULL))

+	{

+		e_reg_flag = 1;

+	}

+	else

+	{

+		e_reg_flag = 0;

+

+	}

+

+

+	

+

+	if(e_reg_flag == 1)

+	{		

+		ret = update_ecall_state(DIR_TX); 

+		if (ret == DRV_ERR_NOT_SUPPORTED)

+		{

+			zOss_Printf(SUBMDL_HAL, PRINT_LEVEL_NORMAL, "vp_ReadDataFromCodec get__ecall_state fun not register !\n");

+	

+		}	

+	}	

+#endif

+	

 #ifdef  CONFIG_VOICE_BUFFER_DRV  

 

 //	wait_for_completion_timeout(&s_voice_completion, 60);

@@ -2372,7 +2989,28 @@
 	}

 	

 #else 

-	ret = zDrvExtAudio_Read(&read_buf, &read_len);

+#ifdef ECALL_SUPPORT

+	if ((e_reg_flag == 1)&&(g_voiceVar.ecallData.ecallTxSta == ECALL_ST_TX_INUSE))		

+	{	

+

+

+		ret = ecall_GetTxBuf(&read_buf,&read_len);

+		if(ret != DRV_SUCCESS)

+		{

+			zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp vp_ReadDataFromCodec ecall_GetRxBuf err ret=%d\n", ret);

+			return DRV_ERROR;

+		}

+		

+		ret = ecall_Read(&read_buf, &read_len);

+

+	}

+	else

+	{

+		ret = zDrvExtAudio_Read(&read_buf, &read_len);

+	}	

+#else

+    ret = zDrvExtAudio_Read(&read_buf, &read_len);

+#endif	

 	if ((ret == DRV_SUCCESS) && (read_buf != NULL) && (read_len == s_speechState.i2sReadParam.buffersize))

 	{

 		if ((s_speechState.pVpI2sCfg->tClkMode == PCM_TIME_MODE) && (s_speechState.pVpI2sCfg->tPcmSlotNum != PCM_1TIME_SLOT))

@@ -2426,11 +3064,14 @@
 		        pVpTxInAllDataBuffer=(UINT8 *)0x25500000+s_TxAllDataSaveLen;

 		#endif

 		*/

-		ret = zDrvExtAudio_FreeBuf(read_buf);

-		if (ret  != DRV_SUCCESS)

+		if (e_reg_flag != 1)

 		{

-			zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp vp_ReadDataFromCodec err ret=%d\n", ret);

-			return DRV_ERROR;

+			ret = zDrvExtAudio_FreeBuf(read_buf);

+			if (ret  != DRV_SUCCESS)

+			{

+				zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp vp_ReadDataFromCodec err ret=%d\n", ret);

+				return DRV_ERROR;

+			}

 		}

 	#ifdef CONFIG_CP_USE_SOFT_DTMF_DETECT

 		for (i = 0; i < (s_speechState.vpCfgParam.samples_per_frame / 80); )

@@ -2484,8 +3125,11 @@
     			voice_MixerDataTx(s_speechState.pVpTempTxInBuffer, 320,  s_speechState.pVpTempTxInBuffer);

     		}

         }

-        

+#ifdef ECALL_SUPPORT

+        if ((g_voiceVar.vProcIsNormal == TRUE)&&(g_voiceVar.ecallData.ecallTxSta != ECALL_ST_TX_INUSE))

+#else    

 		if (g_voiceVar.vProcIsNormal == TRUE)

+#endif		

 		{

 			ret = VoiceProc_TxProcess(&s_speechState.pVpTempTxInBuffer, NULL, &s_speechState.pVpTempTxOutPutBuffer, s_speechState.frameCount);

 			if (ret != DRV_SUCCESS)

@@ -2925,13 +3569,13 @@
 //	init_completion(&s_voice_completion);

 	s_voiceRdSema = zOss_CreateSemaphore("voice_rx_sem", 0);

 	if(NULL == s_voiceRdSema) {

-		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "create iis1_rx_sem err \n");

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "create voice_rx_sem err \n");

 		return DRV_ERROR;

 	}

 

 	s_voiceWrSema  = zOss_CreateSemaphore("voice_tx_sem", 0);

 	if(NULL == s_voiceWrSema) {

-		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "create iis2_rx_sem err \n");

+		zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "create voice_tx_sem err \n");

 		return DRV_ERROR;

 	}

 	

@@ -2983,7 +3627,16 @@
 		return ZOSS_ERROR;

 	}

 	zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "zDrvVp_Init create success.\n");

-

+#ifdef ECALL_SUPPORT	

+	if(g_voiceVar.audio_ctrlFlag.isUseEcall == 1)

+	{

+    	ret = ecall_Init();	

+		if (ret != DRV_SUCCESS)

+		{

+			return ZOSS_ERROR;

+		}

+	}

+#endif

 	voice_InitCodec();

 

 	ret = voice_CreateRcdSemAndThread();

@@ -3380,6 +4033,38 @@
 		//  pVoiceLoopOutSaveBuffer =  s_speechState.pVpTempRxInBuffer;

 #endif

 

+        if (FALSE == g_voiceVar.firstRegZCATFlag) {

+            ret = zCatAgt_Audio_Reg(10,VP_INOUT_BAK_BUFFER_SIZE,(UINT32)vpInOutBuffer.p_voiceRxInBuffer);

+            if(ret != DRV_SUCCESS){

+                zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp_Open RXIN register zCatAgt_Audio_Reg err\n");

+            }

+            

+            ret = zCatAgt_Audio_Reg(12,VP_INOUT_BAK_BUFFER_SIZE,(UINT32)vpInOutBuffer.p_voiceTxInBuffer);

+            if(ret != DRV_SUCCESS){

+                zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp_Open TXIN register zCatAgt_Audio_Reg err\n");

+            }

+                

+    		ret = zCatAgt_Audio_Reg(13,VP_INOUT_BAK_BUFFER_SIZE,(UINT32)vpInOutBuffer.p_voiceTxOutPutBuffer);

+            if(ret != DRV_SUCCESS){

+                zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp_Open TXOUT register zCatAgt_Audio_Reg err\n");

+            }

+

+#ifdef _USE_VP_OUTPUT_RXOUT_DATA

+    		ret = zCatAgt_Audio_Reg(11, VP_INOUT_BAK_BUFFER_SIZE, (UINT32)vpInOutBuffer.p_voiceRxOutPutBuffer);

+            if(ret != DRV_SUCCESS){

+                zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp_Open RXOUT register zCatAgt_Audio_Reg err\n");

+            }

+

+#else

+    		ret = zCatAgt_Audio_Reg(11,VP_INOUT_NOBAK_BUFSIZE,(UINT32)vpInOutBuffer.p_voiceRxOutPutBuffer);

+            if(ret != DRV_SUCCESS){

+                zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "vp_Open RXOUT register zCatAgt_Audio_Reg err\n");

+            }

+#endif

+

+            g_voiceVar.firstRegZCATFlag = TRUE;   

+        }

+        

 		zOss_Sleep(500);

 		ret = zDrvVp_LoopStartDo();

 		if (ret != DRV_SUCCESS)

@@ -4617,5 +5302,43 @@
 	zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, " zDrvVp_GetVoiceState pVoiceState=%p.\n", *pVoiceState);

 	return DRV_SUCCESS;

 }

+#ifdef ECALL_SUPPORT

+/*******************************************************************************

+* Function: zDrvEcall_SetOperations

+* Description: This function is used to set the ecall callback function.

+* Parameters: 

+*   Input:

+*           VoiceObjPtr:The pointer to ecall callback function type. 

+*   Output:None

+*

+* Returns: none

+*

+* Others: 

+********************************************************************************/

+VOID zDrvEcall_SetCallbacks(T_DrvEcall_Opt ecallObj)

+{

+    g_voiceVar.ecallData.opt = ecallObj;

+}

 

 

+SINT32 drv_Get_Ecall_State(VOID)	

+{

+	SINT32 ret = DRV_SUCCESS;

+	//zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, " zDrvVp_GetVoiceState pVoiceState=%p.\n", *pVoiceState);

+	return 1;

+}

+

+SINT32 drv_Ecall_Read(UINT8 *pBuf,UINT32 *inSize)

+{

+	SINT32 ret = DRV_SUCCESS;

+	//zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, " drv_Ecall_Read\n");

+	return DRV_SUCCESS;

+}

+

+SINT32 drv_Ecall_Write(UINT8 *pBuf,UINT32 inSize)	   

+{

+	SINT32 ret = DRV_SUCCESS;

+	//zDrvRamlog_PRINTF(RAMLOG_MOD_AUDIO, "drv_Ecall_Write\n");

+	return DRV_SUCCESS;

+}

+#endif