www.pudn.com > 6027_HD65.rar > ado_in.c
/*************** MTK CONFIDENTIAL & COPYRIGHTED ****************/
/*************** ****************/
/*************** $Modtime:: 04/04/19 3:01p $ ****************/
/*************** $Revision:: 1 $ ****************/
/*************** ****************/
/*************** Description : Audio ADC/SPDIF-IN ****************/
/*************** Module ****************/
/*************** ****************/
/*************** Company : MediaTek Inc. ****************/
/*************** Programmer : Alan Hsu ****************/
/**********************************************************************/
#include "general.h"
#pragma NOAREGS
#ifdef AUDIO_IN_EN /* for audio input */
#ifdef _AK4114_
BYTE xdata bRStatus;
/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
x AK4114 Digital Audio Interface Transceiver x
x--------------------------------------------------------------------x
x Device Addr : 0x10 x
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
/************************************************************************
Function : void vSpdifInit(void)
Description : SPDIF Transciver Initial Routine
Parameter : NONE
Return : NONE
************************************************************************/
void vSpdifInit(void) large
{
BYTE bData;
bData = 0x00; //Reset and pwn all registers
fgI2CByteWrite(0x10, 0x00, bData);
bData = 0x03; //Normal operation
fgI2CByteWrite(0x10, 0x00, bData);
// dummy call
bData = 0x01;
if (bData == 0)
{
vSpdifChgMCLK(0);
vSpdifDeEmphasisEN(0);
vSpdifPWN(0);
vSpdifClkMode(0);
}
}
/************************************************************************
Function : void vSpdifDataFormat(BYTE bDataFormat)
Description : Setting ADAC Data Format
Parameter :
Return : NONE
************************************************************************/
void vSpdifDataFormat(BYTE bDataFormat) large
{
BYTE bData;
fgI2CByteRead(0x10, 0x01, &bData);
bData = bData & 0x8F;
switch(bDataFormat)
{
case RTJ_16BIT:
bData = bData + 0;
break;
case RTJ_18BIT:
bData = bData + 0x10;
break;
case RTJ_20BIT:
bData = bData + 0x20;
break;
case RTJ_24BIT:
bData = bData + 0x30;
break;
case I2S_24BIT:
bData = bData + 0x05;
break;
case LTJ_24BIT:
bData = bData + 0x40;
break;
default:
bData = bData + 0x30; //24-bit, RTJ
break;
}
fgI2CByteWrite(0x10, 0x01, bData);
}
/************************************************************************
Function : void vSpdifChgMCLK(BYTE bSampleRate)
Description : Change master clk output with sampling rate
Parameter : bSampleRate : 0-> 48k, 1-> 96k, 2-> 192k
Return : NONE
************************************************************************/
void vSpdifChgMCLK(BYTE bSampleRate) large
{
BYTE bData;
fgI2CByteRead(0x10, 0x00, &bData);
bData = bData & 0xF3;
switch(bSampleRate)
{
case AFS512_48K: //Max fs :48kHz
bData = bData + 0x08;
break;
case AFS256_96K: //Max fs :96kHz
bData = bData + 0;
break;
case AFS128_192K: //Max fs :192kHz
bData = bData + 0x0C;
break;
default:
bData = bData + 0;
break;
}
fgI2CByteWrite(0x10, 0x00, bData);
}
/************************************************************************
Function : BYTE bSpdifDetSmpRate(void)
Description : Sample Rate Detection
Parameter : NONE
Return : 0:44.1k 1:48k 2:32k 3:88.2k 4:96k 5:176.4k 6:192k
************************************************************************/
BYTE bSpdifDetSmpRate(void) large
{
BYTE bData;
BYTE bRetVal;
if(fgI2CByteRead(0x10, 0x07, &bData)==FALSE)
{
return (DSP_AIN_FREQ44_1K);
}
bData = (bData & 0xf0) >> 4;
switch (bData)
{
case 2: //48kHz
bRetVal = DSP_AIN_FREQ48K;
break;
case 3: //32kHz
bRetVal = DSP_AIN_FREQ32K;
break;
case 8: //88.2kHz
bRetVal = DSP_AIN_FREQ88_2K;
break;
case 10: //96kHz
bRetVal = DSP_AIN_FREQ96K;
break;
case 12: //176.4kHz
bRetVal = DSP_AIN_FREQ176_4K;
break;
case 14: //192kHz
bRetVal = DSP_AIN_FREQ192K;
break;
case 0: //44.1kHz
case 1: //>192kHz, <32kHz, invalid
default:
bRetVal = DSP_AIN_FREQ44_1K;
break;
}
return (bRetVal);
}
/************************************************************************
Function : BOOL fgSpdifDetPreEmphasis(void)
Description : Pre-Emphasis Detection
Parameter : NONE
Return : TRUE/FALSE , ON/OFF
************************************************************************/
BOOL fgSpdifDetPreEmphasis(void) large
{
return (bRStatus& 0x04)?TRUE:FALSE;
}
/************************************************************************
Function : BOOL fgSpdifDetAudioBitOut(void);
Description : Audio Bit Detection
Parameter : NONE
Return : TRUE/FALSE , Audio/Non Audio
************************************************************************/
BOOL fgSpdifDetAudioBitOut(void) large
{
return (bRStatus& 0x02)? TRUE:FALSE;
}
/************************************************************************
Function : void vSpdifDeEmphasisEN(void)
Description : Enisable DeEmphasis
Parameter : NONE
Return : NONE
************************************************************************/
void vSpdifDeEmphasisEN(BYTE bEnable) large
{
if(bEnable)
{
BYTE bData;
fgI2CByteRead(0x10, 0x01, &bData);
bData = bData & 0xF7 + 0x08;
fgI2CByteWrite(0x10, 0x01, bData);
}
else
{
BYTE bData;
fgI2CByteRead(0x10, 0x01, &bData);
bData = bData & 0xF0 + 0x02;
fgI2CByteWrite(0x10, 0x01, bData);
}
}
/************************************************************************
Function : void vSpdifPWN(BYTE bEnable)
Description : SPDIF Transciver Power Down
Parameter : bEnable: 1-> Power down
Return : NONE
************************************************************************/
void vSpdifPWN(BYTE bEnable) large
{
BYTE bData;
fgI2CByteRead(0x10, 0x00, &bData);
bData = bData & 0xFD;
if(bEnable == 0) //PowerOn
{
bData = bData + 0x02;
}
fgI2CByteRead(0x10, 0x00, &bData);
}
/************************************************************************
Function : void vSpdifChInSel(BYTE bCh)
Description : Iutput Channel Selection
Parameter : bInputCh : 0->RX0, 1->RX1, 2->RX2, 3->RX3
Return : NONE
************************************************************************/
void vSpdifChInSel(BYTE bCh) large
{
BYTE bData;
fgI2CByteRead(0x10, 0x03, &bData);
bData = (bData & 0xF8) + bCh;
fgI2CByteWrite(0x10, 0x03, bData);
}
/************************************************************************
Function : void vSpdifClkMode(BYTE bClkMode)
Description : Clock Control Mode Selection(W/ data source selection)
Parameter : bClkMode : 0->PLL(RX), 1->X'tal(DAUX),
2->PLL(RX)/X'tal(DAUX) auto switch
Return : NONE
************************************************************************/
void vSpdifClkMode(BYTE bClkMode) large
{
BYTE bData;
fgI2CByteRead(0x10, 0x00, &bData);
bData = bData & 0xCF;
switch(bClkMode)
{
case 0: //Use PLL for clk source
bData = bData;
break;
case 1: //Use X'tal for clk source
bData = bData + 0x10;
break;
case 2: //Use PLL(X'tal when PLL unlock) for clk source
bData = bData + 0x20;
break;
default:
bData = bData;
break;
}
fgI2CByteWrite(0x10, 0x00, bData);
}
/************************************************************************
Function : void vSpdifINT0(BYTE bUlockEn , BYTE bPAREn)
Description : INT0 Enable
Parameter : bUlockEn : 1->Unlock Enable, bPAREn : 1->PAR Enable
Return : NONE
************************************************************************/
void vSpdifINT0(BYTE bUlockEn , BYTE bPAREn)
{
BYTE bData;
fgI2CByteRead(0x10, 0x04, &bData);
if(bUlockEn)
{
bData = bData & 0xEF;
}
else
{
bData = bData | 0x10;
}
if(bPAREn)
{
bData = bData & 0xFE;
}
else
{
bData = bData | 0x01;
}
fgI2CByteWrite(0x10, 0x04, bData);
}
/************************************************************************
Function : BOOL vSpdifLockChk(void)
Description :
Parameter :
Return :
************************************************************************/
BOOL fgSpdifLockChk(void) large
{
if (fgI2CByteRead(0x10, 0x06, &bRStatus) == FALSE)
{
// device busy or no ack
return (FALSE);
}
if (bRStatus & 0x11)
{
// unlocked
return (FALSE);
}
else
{
// locked
return (TRUE);
}
}
#endif //_AK4114_
/************************************************************************
Function : void vAinChSel(BYTE bCh)
Description :
Parameter :
Return :
************************************************************************/
void vAinChSel(BYTE bCh) large
{
switch (bCh)
{
case AIN_SEL_D0:
case AIN_SEL_D1:
case AIN_SEL_D2:
case AIN_SEL_D3:
// set flag for RISC
vSetSharedReg(SR_AIN_FLAG, DSP_AIN_DISABLE);
// select SPDIF in
_sFlagAin.fgSpdifChk = TRUE;
_sFlagAin.fgSpdifLock = FALSE;
// default is unlocked and input is disabled
WriteBIM(BIM_PCTL4, LINE_IN_SPDATA);
WriteAUD(AUD_SPLIN0, SPLIN_INV + SPLIN_RJ + SPLIN_24BIT);
WriteAUD(AUD_SPLIN1, SPDIF_IN + SPDIF_CYC32);
vSpdifInit(); // initialze 4114
vSpdifDataFormat(RTJ_24BIT); // set data format
vSpdifChInSel(bCh & 0x0f);
vSpdifChgMCLK(AFS128_192K);
WriteAUD(AUD_ACLKCFG, 0x21); //Setting 128fs
vSpdifINT0(TRUE, FALSE);
vSpdifClkMode(2);
break;
case AIN_SEL_L0:
case AIN_SEL_L1:
case AIN_SEL_L2:
case AIN_SEL_L3:
// select line in
_sFlagAin.fgSpdifChk = FALSE;
_sFlagAin.fgSpdifLock = FALSE;
// set flag for RISC
vSetSharedReg(SR_AIN_FLAG, DSP_AIN_DISABLE);
ClrBitBIM(BIM_IOENH, IOH_YUV7); // set YUV7 as input pin
WriteAUD(AUD_SPLIN0, SPLIN_INV + SPLIN_LJ + SPLIN_24BIT); // left aligned,left channel when lrck high
WriteAUD(AUD_SPLIN1, SPDIF_CYC32); // 32 cycle,line in
WriteBIM(BIM_PCTL4, LINE_IN_YUV7); // default we use YUV7 for line-in
vSpdifINT0(FALSE,FALSE);
WriteAUD(AUD_ACLKCFG, 0x42); //Setting 256fs
// set flag for RISC
vSetSharedReg(SR_AIN_FLAG, DSP_AIN_LINE);
break;
case AIN_SEL_OFF:
default:
// select audio in off
_sFlagAin.fgSpdifChk = FALSE;
_sFlagAin.fgSpdifLock = FALSE;
// set flag for RISC
vSetSharedReg(SR_AIN_FLAG, DSP_AIN_DISABLE);
vSpdifInit(); // reset 4114
vSpdifINT0(FALSE,FALSE);
WriteBIM(BIM_PCTL4, LINE_IN_SPDATA); // set spdif/line-in same pin
WriteAUD(AUD_SPLIN0, 0x00); // disable spdif/line in
WriteAUD(AUD_SPLIN1, 0x00); // disable spdif/line in
WriteAUD(AUD_ACLKCFG, 0x42); //Setting 256fs
break;
}
}
// *********************************************************************
// Function :
// Description :
// Parameter :
// Return :
// *********************************************************************
void vAinLockCheck(void) large
{
BYTE bTmp1;
if (fgSpdifLockChk() == TRUE)
{
_sFlagAin.fgAUDION=fgSpdifDetAudioBitOut();
_sFlagAin.fgPEM=fgSpdifDetPreEmphasis();
_sFlagAin.Freq = (bSpdifDetSmpRate() >> 4);
bTmp1 = 0x1;
bTmp1 |= (_sFlagAin.fgAUDION << 2);
bTmp1 |= (_sFlagAin.fgPEM << 3);
bTmp1 |= (_sFlagAin.Freq << 4);
if (bSharedReg(SR_AIN_FLAG) != bTmp1)
{
vSetSharedReg(SR_AIN_FLAG, bTmp1);
}
if (_sFlagAin.fgSpdifLock != TRUE)
{
_sFlagAin.fgSpdifLock = TRUE;
}
}
else
{
_sFlagAin.fgAUDION=fgSpdifDetAudioBitOut();
_sFlagAin.fgPEM=fgSpdifDetPreEmphasis();
_sFlagAin.Freq = (bSpdifDetSmpRate() >> 4);
if (bSharedReg(SR_AIN_FLAG) != DSP_AIN_DISABLE)
{
vSetSharedReg(SR_AIN_FLAG, DSP_AIN_DISABLE);
}
if (_sFlagAin.fgSpdifLock != FALSE)
{
_sFlagAin.fgSpdifLock = FALSE;
}
}
}
// *********************************************************************
// Function :
// Description :
// Parameter :
// Return :
// *********************************************************************
void vAinFsSelect(BYTE bUpsample, BYTE bClockFormat) large
{
if (_sFlagAin.fgSpdifChk == FALSE) // not in SPDIF input mode
{
//vSpdifChgMCLK(AFS256_96K);
//WriteAUD(AUD_ACLKCFG, 0x42); //Setting 256fs
return;
}
if (bClockFormat <= FS256_48K) // no upsampling available
{
bUpsample = UPSAMPLE_1X;
}
switch (bUpsample)
{
case UPSAMPLE_1X: // must support up to 192K
vSpdifChgMCLK(AFS128_192K);
WriteAUD(AUD_ACLKCFG, 0x21); //Setting 128fs
break;
case UPSAMPLE_2X:
// if (bClockFormat <= FS256_96K) //FS256_96K
// {
vSpdifChgMCLK(AFS256_96K);
WriteAUD(AUD_ACLKCFG, 0x21); //Setting 256fs
// }
// else // large than 96K
// {
// vSpdifChgMCLK(AFS512_48K);
// WriteAUD(AUD_ACLKCFG, 0x42); //Setting 256fs
// bLastACLK=AFS512_48K;
// }
break;
case UPSAMPLE_4X:
vSpdifChgMCLK(AFS512_48K);
WriteAUD(AUD_ACLKCFG, 0x21); //Setting 128fs
break;
case UPSAMPLE_OFF:
case UPSAMPLE_8X: /* not support */
default:
vSpdifChgMCLK(AFS256_96K);
WriteAUD(AUD_ACLKCFG, 0x42); //Setting 256fs
break;
}
}
#endif /* AUDIO_IN_EN, for audio input */