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 */