/* STV 83xy Audio Driver API (DV_AUD) STMicroelectronics Confidential Version 1.12 Author: HDP Appli Lab 11/2006 */ // ****************************************************************** // CHIP SUPPORT // put in comment to remove corresponding patch for S/W space saving //#define INCLUDE_83x7 #define INCLUDE_83x8 #ifndef INCLUDE_83x7 #ifndef INCLUDE_83x8 ... // error: choose AT LEAST ONE patch! #endif #endif // ****************************************************************** // ****************************************************************** //#include "typedef.h" #include "dsthalcommon.h" typedef unsigned char U8; typedef unsigned short U16; typedef unsigned long U32; #include "STV83xy.h" #include "STV83xyPatch.h" #include "test_patch1.h" #include "dsthalsys.h" //#include "debug.h" U8 RegAddr = 0; U8 SAVED_I2CAddr = 0; int ST_SRS_COMP = SRS_DEFAULT_COMP; int ST_AVL_COMP = AVL_DEFAULT_COMP; // ****************************************************************** // ****************************************************************** // external I2C routines (low level H/W I2C access) // int DHL_SYS_I2cRead(unsigned char addr, int isSubAddress, int subAddress, unsigned char *buf, int len) U8 I2C_Read(U8 I2cAddr, U8 RegIndex){ int result; // U8 *SubAddr = (U8 *)((int)RegIndex); U8 DataBuf = 0; result = DHL_SYS_I2cReadEx(0,I2cAddr, 1, RegIndex,&DataBuf,1); if ( result < 0 ) printf("Audio I2C Read Error\n"); return DataBuf; } // #define I2C_Read(x,y) DHL_SYS_I2cRead(x,1,y,RegIndex,1) // int DHL_SYS_I2cWrite(unsigned char addr, int isSubAddress, int subAddress, unsigned char *buf, int len) U8 I2C_Write(U8 I2cAddr, U8 RegIndex, U8 RegValue){ // returns 0 if no error int result; U8 RegVal = RegValue; result = DHL_SYS_I2cWriteEx(0,I2cAddr,1,RegIndex,&RegVal,1); if( result < 0){ printf("Audio I2C Write Error\n"); return 1; } return 0; } // U8 I2C_WriteAddrIndex(U8 I2cAddr, U8 RegIndex){ // returns 0 if no error RegAddr = RegIndex; SAVED_I2CAddr = I2cAddr; return 0; } // U8 I2C_WriteData(U8 RegValue){ // returns 0 if no error U8 result; result = I2C_Write(SAVED_I2CAddr,RegAddr++,RegValue); if(result){ printf("WriteDataFail\n"); return 1; } return 0; // return I2C_Write(SAVED_I2CAddr,RegAddr++,RegValue); // writeÈÄ regAddrÀÌ Áõ°¡µÇ¸é¼­ writing } // U8 I2C_Stop(void){ return 0; // returns 0 if no error } int stv_r(U8 addr) { int c; c = I2C_Read(0x80,addr); printf("0x%x\n",c); return c; } int stv_w(U8 addr, U8 data) { stv_r(addr); I2C_Write(0x80,addr,data); stv_r(addr); return 1; } // external timer routine #define WAIT_Inms(x) OS_mDelay(x) // ****************************************************************** // ****************************************************************** // higher level I2C routines used by 83xy routines static void DVAUD_I2cClrBit(U16 Field); static void DVAUD_I2cSetBit(U16 Field); static void DVAUD_I2cWriteReg(U8 Reg, U8 RegValue); static void DVAUD_I2cWriteField(U16 Field, U8 Value); static U8 DVAUD_I2cReadReg(U8 Reg); static U8 DVAUD_I2cReadField(U16 Field); // ****************************************************************** // ****************************************************************** // NOTE: ALL variables below are local and MUST be "static" // "static" may be removed for test purposes only static DVAUD_DeviceType_t Dev_ID = DVAUD_kUnknown; // set by DVAUD_DeviceStart(), tested by every routine static DVAUD_Status_t I2C_Status; // updated by I2C routines static U8 I2cAddr83xy = 0x80; // by default, if ADR_SEL pin = 0 static DVAUD_DeviceCapability_t Dev_Capability; // for DVAUD_DeviceStart() and DVAUD_LowPowerExit() // ****************************************************************** // ****************************************************************** // ****************************************************************** // ****************************************************************** DVAUD_Status_t DVAUD_DACMuteSet ( const DVAUD_Output_t eOutput, const DVAUD_Enabled_t eNewStatus) { U16 Bit; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eOutput) { case DVAUD_kOutputSpeaker: Bit = F_MUTE_DAC_LR; break; case DVAUD_kOutputCenter: case DVAUD_kOutputSubwoofer: Bit = F_MUTE_DAC_CSUB; break; case DVAUD_kOutputHeadphone: case DVAUD_kOutputSurround: Bit = F_MUTE_DAC_SHP; break; case DVAUD_kOutputSCART1: case DVAUD_kOutputSCART2: case DVAUD_kOutputSCART3: Bit = F_MUTE_DAC_SCART; break; default: // parameter config not in list return DVAUD_kBadParameter; } switch (eNewStatus) { case DVAUD_kDisabled: DVAUD_I2cClrBit(Bit); // R_MUTE_DAC break; case DVAUD_kEnabled: DVAUD_I2cSetBit(Bit); // R_MUTE_DAC break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_SoftMuteSet ( const DVAUD_Output_t eOutput, const DVAUD_Enabled_t eNewStatus) { U16 Bit; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eOutput) { case DVAUD_kOutputHeadphone: Bit = F_MUTE_DIG_HP; break; case DVAUD_kOutputSPDIF: Bit = F_MUTE_DIG_SPDIF; break; case DVAUD_kOutputSCART1: case DVAUD_kOutputSCART2: case DVAUD_kOutputSCART3: Bit = F_MUTE_DIG_SCART; break; case DVAUD_kOutputSurround: Bit = F_MUTE_DIG_SRND; break; case DVAUD_kOutputSubwoofer: Bit = F_MUTE_DIG_SUB; break; case DVAUD_kOutputCenter: Bit = F_MUTE_DIG_C; break; case DVAUD_kOutputSpeaker: Bit = F_MUTE_DIG_LS; break; default: // parameter config not in list return DVAUD_kBadParameter; } switch (eNewStatus) { case DVAUD_kDisabled: DVAUD_I2cClrBit(Bit); // R_MUTE_DIGITAL break; case DVAUD_kEnabled: DVAUD_I2cSetBit(Bit); // R_MUTE_DIGITAL break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** static U16 DVAUD_VolumeConvertLR (S32 ValueInmdB) { // convert from [-108000(-108); +19875(+19.875db)] to [0; 1023] by steps of 125 (0.125dB) return (U16)((ValueInmdB+108000L)/125L); } static U8 DVAUD_VolumeConvertScart (S32 ValueInmdB) { // convert from [-108000(-108); +19500(+19.5)] to [0; 255] by steps of 500 (0.5dB) return (U8)((ValueInmdB+108000L)/500L); } static S8 DVAUD_VolumeConvertCenterSub (S16 ValueInmdB) { // convert from [-16000(-16); +15875(+15.875)] to [-128; +127] by steps of 125 (0.125dB) return (S8)(ValueInmdB/125L); } DVAUD_Status_t DVAUD_VolumeSet ( const DVAUD_Output_t eOutput, const S32 lValueInmdB) { U8 Val; U16 ValW; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; printf("%d 0x%x\n",__LINE__,(int)lValueInmdB); switch (eOutput) { case DVAUD_kOutputSpeaker: if (lValueInmdB<(-108000L) || lValueInmdB>19875L) return DVAUD_kBadParameter; // value out of range ValW = DVAUD_VolumeConvertLR(lValueInmdB); printf("%d 0x%x\n",__LINE__,(int)ValW); // volume in LS_L always DVAUD_I2cSetBit(F_VOLUME_MODE_LS); // volume/balance DVAUD_I2cWriteReg(R_VOLUME_LS_L_COARSE, (ValW>>2) & 0xFF); // whole register coarse = bits 9..2 DVAUD_I2cWriteField(F_VOLUME_LS_L_FINE, ValW & 0x03); // R_VOLUME_LS_L_FINE fine = bits 1..0 break; case DVAUD_kOutputCenter: if (lValueInmdB<(-16000L) || lValueInmdB>15875L) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteReg(R_VOLUME_LS_C, DVAUD_VolumeConvertCenterSub(lValueInmdB)); break; case DVAUD_kOutputSubwoofer: if (lValueInmdB<(-16000L) || lValueInmdB>15875L) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteReg(R_VOLUME_LS_SUB, DVAUD_VolumeConvertCenterSub(lValueInmdB)); break; case DVAUD_kOutputSurround: if (lValueInmdB<(-16000L) || lValueInmdB>15875L) return DVAUD_kBadParameter; // value out of range Val = DVAUD_VolumeConvertCenterSub(lValueInmdB); DVAUD_I2cWriteReg(R_VOLUME_LS_SL, Val); DVAUD_I2cWriteReg(R_VOLUME_LS_SR, Val); // treat Srnd L and R alike break; case DVAUD_kOutputHeadphone: if (lValueInmdB<(-108000L) || lValueInmdB>19875L) return DVAUD_kBadParameter; // value out of range ValW = DVAUD_VolumeConvertLR(lValueInmdB); // volume in HP_L always DVAUD_I2cSetBit(F_VOLUME_MODE_HP); // volume/balance DVAUD_I2cWriteReg(R_VOLUME_HP_L_COARSE, (ValW>>2) & 0xFF); // whole register coarse = bits 9..2 DVAUD_I2cWriteField(F_VOLUME_HP_L_FINE, ValW & 0x03); // R_VOLUME_HP_L_FINE fine = bits 1..0 break; case DVAUD_kOutputSCART1: case DVAUD_kOutputSCART2: case DVAUD_kOutputSCART3: if (lValueInmdB<(-108000L) || lValueInmdB>19500L) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteReg(R_VOLUME_SCART, DVAUD_VolumeConvertScart(lValueInmdB)); break; default: // parameter config not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_BalanceSet ( const DVAUD_Output_t eOutput, const DVAUD_Side_t eSide, const U8 ucValueInPercent) { S32 sCoeff; S32 slVal; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; if (ucValueInPercent>100) return DVAUD_kBadParameter; // value out of range // check if side parameter is correct switch (eSide) { case DVAUD_kLeft: sCoeff = (-511L); // -100% = full to the left break; case DVAUD_kRight: sCoeff = 511L; // 100% = full to the right break; default: return DVAUD_kBadParameter; // value out of range } slVal = ((S8)ucValueInPercent * sCoeff) / 100L; // full precision conversion to -511..+511 range (to avoid floats) // coarse = MSB = bits 9..2 // fine = LSB = bits 1..0 // sign bit 9 = 1 if negative switch (eOutput) { case DVAUD_kOutputSpeaker: // balance in LS_R always DVAUD_I2cWriteReg(R_VOLUME_LS_R_COARSE, (slVal >> 2) & 0xFF); // whole register = MSB DVAUD_I2cWriteField(F_VOLUME_LS_R_FINE, slVal & 0x03); // R_VOLUME_LS_R_FINE = LSB break; case DVAUD_kOutputHeadphone: // balance in HP_R always DVAUD_I2cWriteReg(R_VOLUME_HP_R_COARSE, (slVal >> 2) & 0xFF); // whole register DVAUD_I2cWriteField(F_VOLUME_HP_R_FINE, slVal & 0x03); // R_VOLUME_HP_R_FINE break; default: // parameter config not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_PrologicSetConfig ( const DVAUD_PrologicConfig_t* const pstConfig, const DVAUD_PrologicDownMixMode_t eNewMode) { U8 Val; S8 ValS; S32 ValLS; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; if ((Dev_Capability.ePrologicI != DVAUD_kImplemented) && (Dev_Capability.ePrologicII != DVAUD_kImplemented)) return DVAUD_kFeatureNotSupported; // neither Prologic I nor II supported // Mode Val = pstConfig->eMode; if (Val >= DVAUD_kNbOfPrologicMode) return DVAUD_kBadParameter; // value out of range if ((Val != DVAUD_kModePrologic1Emulation) && (Dev_Capability.ePrologicI == DVAUD_kImplemented)) return DVAUD_kFeatureNotSupported; // in Dolby Prologic 1, only Prologic 1 emulation supported DVAUD_I2cWriteField(F_PL2_MODES,Val); // R_PROLOGIC2_CONF1 // Autobalance switch (pstConfig->eAutoBalance) { case DVAUD_kFalse: DVAUD_I2cClrBit(F_PL2_AUTOBALANCE); // R_PROLOGIC2_CONF2 break; case DVAUD_kTrue: DVAUD_I2cSetBit(F_PL2_AUTOBALANCE); break; default: // parameter not in list return DVAUD_kBadParameter; } // Panorama switch (pstConfig->ePanorama) { case DVAUD_kFalse: DVAUD_I2cClrBit(F_PL2_PANORAMA); // R_PROLOGIC2_CONF2 break; case DVAUD_kTrue: DVAUD_I2cSetBit(F_PL2_PANORAMA); break; default: // parameter not in list return DVAUD_kBadParameter; } // RS Polarity switch (pstConfig->eRSPolarity) { case DVAUD_kFalse: DVAUD_I2cClrBit(F_PL2_SRND_COHERENCE); // R_PROLOGIC2_CONF2 break; case DVAUD_kTrue: DVAUD_I2cSetBit(F_PL2_SRND_COHERENCE); break; default: // parameter not in list return DVAUD_kBadParameter; } // LFE Bypass switch (pstConfig->eLFEBypass) { case DVAUD_kFalse: DVAUD_I2cClrBit(F_PL2_LFE_BYPASS); // R_PROLOGIC2_CONF1 break; case DVAUD_kTrue: DVAUD_I2cSetBit(F_PL2_LFE_BYPASS); break; default: // parameter not in list return DVAUD_kBadParameter; } // Surround Filter Val = pstConfig->eFilter; if (Val >= DVAUD_kNbOfPrologicSrndFilter) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_PL2_SRND_FILTER, Val); // R_PROLOGIC2_CONF2 // C Dimension ValS = pstConfig->cDimension; if (ValS<(-3) || ValS>3) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_PL2_DIMENSION, ValS+3); // R_PROLOGIC2_CONF3 // Center Width Val = pstConfig->eWidth; if (Val >= DVAUD_kNbOfPrologicCenterWidth) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_PL2_C_WIDTH, Val); // R_PROLOGIC2_CONF3 // Attenuation -127.5dB -> 0dB ValLS = pstConfig->lAttenuationInmdB; if (ValLS>0 || ValLS<(-127500)) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteReg(R_PROLOGIC2_LEVEL, (-ValLS)/500); // DownMix Mode if (eNewMode >= DVAUD_kNbOfPrologicDownMixMode) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_PL2_OUTPUT_DOWNMIX, eNewMode +3 ); // R_PROLOGIC2_CONF1 return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_PrologicSet ( const DVAUD_Enabled_t eNewStatus) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eNewStatus) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_PL2_ON); // R_PROLOGIC2_CONF1 break; case DVAUD_kEnabled: if ((Dev_Capability.ePrologicI != DVAUD_kImplemented) && (Dev_Capability.ePrologicII != DVAUD_kImplemented)) return DVAUD_kFeatureNotSupported; // neither Prologic I nor II supported else DVAUD_I2cSetBit(F_PL2_ON); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_BassManagementSetConfig ( const DVAUD_BassManagementConfig_t* const pstConfig) { U8 Val; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; // LFE switch (pstConfig->eLFEAdd) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_LFE_ADD); // R_BASS_MNGT_CONF2 break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_LFE_ADD); break; default: // parameter not in list return DVAUD_kBadParameter; } // level adjustment switch (pstConfig->eLevelAdjust) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_LEVEL_ADJUST); // R_BASS_MNGT_CONF2 break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_LEVEL_ADJUST); break; default: // parameter not in list return DVAUD_kBadParameter; } // subwoofer out switch (pstConfig->eSubwooferOut) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_SUBWOOFER_ON); // R_BASS_MNGT_CONF2 break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_SUBWOOFER_ON); break; default: // parameter not in list return DVAUD_kBadParameter; } // prologic surround switch (pstConfig->ePrologicSrnd) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_PROLOGIC_MODE); // R_BASS_MNGT_CONF2 break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_PROLOGIC_MODE); break; default: // parameter not in list return DVAUD_kBadParameter; } // bass config mode Val = pstConfig->eMode; if (Val >= DVAUD_kNbOfBassConfigMode) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_BASS_MNGT_CONF, Val); // R_BASS_MNGT_CONF2 // sub corner freq Val = pstConfig->eFreq; if (Val >= DVAUD_kNbOfSubCornerFreq) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_BASS_MNGT_CORNER_FREQ, Val); // R_BASS_MNGT_CONF1 return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_BassManagementSet ( const DVAUD_Enabled_t eNewStatus) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eNewStatus) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_BASS_MNGT_ON); // R_BASS_MNGT_CONF1 break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_BASS_MNGT_ON); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_PinkNoiseSetConfig ( const DVAUD_PinkNoiseConfig_t* const pstConfig) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; // left switch (pstConfig->eLeft) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_LEFT_NOISE); // R_NOISE_GENERATOR break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_LEFT_NOISE); break; default: // parameter not in list return DVAUD_kBadParameter; } // center switch (pstConfig->eCenter) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_CENTER_NOISE); // R_NOISE_GENERATOR break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_CENTER_NOISE); break; default: // parameter not in list return DVAUD_kBadParameter; } // right switch (pstConfig->eRight) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_RIGHT_NOISE); // R_NOISE_GENERATOR break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_RIGHT_NOISE); break; default: // parameter not in list return DVAUD_kBadParameter; } // surround left switch (pstConfig->eSrndLeft) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_SLEFT_NOISE); // R_NOISE_GENERATOR break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_SLEFT_NOISE); break; default: // parameter not in list return DVAUD_kBadParameter; } // surround right switch (pstConfig->eSrndRight) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_SRIGHT_NOISE); // R_NOISE_GENERATOR break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_SRIGHT_NOISE); break; default: // parameter not in list return DVAUD_kBadParameter; } // subwoofer switch (pstConfig->eSubwoofer) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_SUB_NOISE); // R_NOISE_GENERATOR break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_SUB_NOISE); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_PinkNoiseSet ( const DVAUD_Enabled_t eNewStatus) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eNewStatus) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_NOISE_ON); // R_NOISE_GENERATOR break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_NOISE_ON); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_AVDelaySetConfig ( const DVAUD_Output_t eOutput, const U8 ucValueInStep) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; if (ucValueInStep > 0x98) // greater than 100.32ms return DVAUD_kBadParameter; // value out of range switch (eOutput) { case DVAUD_kOutputSpeaker: DVAUD_I2cWriteReg(R_AV_DELAY_TIME_LS, ucValueInStep); break; case DVAUD_kOutputHeadphone: DVAUD_I2cWriteReg(R_AV_DELAY_TIME_HP, ucValueInStep); break; default: // parameter config not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_AVDelaySet ( const DVAUD_Enabled_t eNewStatus) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eNewStatus) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_AV_DELAY_ON); // R_AV_DELAY_CONF break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_AV_DELAY_ON); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_DolbyDelaySetConfig ( const U8 ucValueInStep) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; if (ucValueInStep > 25) return DVAUD_kBadParameter; DVAUD_I2cWriteField(F_SRND_DELAY_TIME, ucValueInStep); // R_SRND_DELAY return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_DolbyDelaySet ( const DVAUD_Enabled_t eNewStatus) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eNewStatus) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_SRND_DELAY_ON); // R_SRND_DELAY break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_SRND_DELAY_ON); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_DownMixSetConfig ( const DVAUD_DownMixConfig_t* const pstConfig) { U8 Val; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; // downmix mode switch (pstConfig->eDownMixModeAAC) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_DOWNMIX_MODE); // R_DOWNMIX_CONF break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_DOWNMIX_MODE); break; default: // parameter not in list return DVAUD_kBadParameter; } // surround factor Val = pstConfig->eSurroundFactor; if (Val >= DVAUD_kNbOfDownMixFactor) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_SRND_FACTOR, Val); // R_DOWNMIX_CONF // center factor Val = pstConfig->eCenterFactor; if (Val >= DVAUD_kNbOfDownMixFactor) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_CENTER_FACTOR, Val); // R_DOWNMIX_CONF return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_DownmixSet ( const DVAUD_Enabled_t eNewStatus) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eNewStatus) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_DOWNMIX_ON); // R_DOWNMIX_CONF break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_DOWNMIX_ON); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** static U8 DVAUD_GetMainAudioMatrixInput ( const DVAUD_Input_t eInput) { switch (eInput) { case DVAUD_kInputMute: return 0; case DVAUD_kInputSIF1_FMAMAB: case DVAUD_kInputSIF2_FMAMAB: return 1; case DVAUD_kInputSIF1_StereoAB: case DVAUD_kInputSIF2_StereoAB: return 2; case DVAUD_kInputSIF1_StereoA: case DVAUD_kInputSIF2_StereoA: return 3; case DVAUD_kInputSIF1_StereoB: case DVAUD_kInputSIF2_StereoB: return 4; case DVAUD_kInputI2S0: return 5; case DVAUD_kInputI2S1: return 6; case DVAUD_kInputI2S2: return 7; case DVAUD_kInputI2S3: return 8; case DVAUD_kInputMono: case DVAUD_kInputSCART1: case DVAUD_kInputSCART2: case DVAUD_kInputSCART3: case DVAUD_kInputSCART4: case DVAUD_kInputSCART5: return 9; default: return 0xFF; // bad value, including DirectMono and DirectScart } } static DVAUD_Status_t DVAUD_SetMainAudioMatrixOutput ( const DVAUD_Output_t eOutput, const U8 Matrix, const DVAUD_Input_t eInput) { U8 ScartInSelect; U16 FieldOut = 0; U16 FieldMute = 0; ScartInSelect = 0; // manage SIF1 or SIF2 switch (eInput) { case DVAUD_kInputSIF1_FMAMAB: case DVAUD_kInputSIF1_StereoAB: case DVAUD_kInputSIF1_StereoA: case DVAUD_kInputSIF1_StereoB: DVAUD_I2cClrBit(F_IF_SELECT); // SIF1 break; case DVAUD_kInputSIF2_FMAMAB: case DVAUD_kInputSIF2_StereoAB: case DVAUD_kInputSIF2_StereoA: case DVAUD_kInputSIF2_StereoB: DVAUD_I2cSetBit(F_IF_SELECT); // SIF2 break; case DVAUD_kInputMono: ScartInSelect = 5; // value to write + 1 break; case DVAUD_kInputSCART1: ScartInSelect = 1; // value to write + 1 break; case DVAUD_kInputSCART2: ScartInSelect = 2; // value to write + 1 break; case DVAUD_kInputSCART3: ScartInSelect = 3; // value to write + 1 break; case DVAUD_kInputSCART4: ScartInSelect = 4; // value to write + 1 break; case DVAUD_kInputSCART5: ScartInSelect = 7; // value to write + 1 break; default: break; } if (ScartInSelect) // if input from scart in select block DVAUD_I2cWriteField(F_ADC_INPUT_SEL, ScartInSelect-1); // preset this block first switch (eOutput) { case DVAUD_kOutputSpeaker: FieldOut = F_OUTPUT_LS_LR; break; case DVAUD_kOutputCenter: case DVAUD_kOutputSubwoofer: // same FieldOut = F_OUTPUT_LS_CSUB; break; case DVAUD_kOutputSurround: FieldOut = F_OUTPUT_LS_SRND; break; case DVAUD_kOutputHeadphone: FieldOut = F_OUTPUT_HP_LR; break; case DVAUD_kOutputI2SDelay: FieldOut = F_OUTPUT_DELAY_LR; break; case DVAUD_kOutputSPDIF: FieldOut = F_OUTPUT_SPDIF_LR; break; case DVAUD_kOutputSCART1: case DVAUD_kOutputSCART2: case DVAUD_kOutputSCART3: if (Matrix == 0) // DVAUD_kInputMute FieldOut = 0; // don't set "mute" in main audio matrix block for SCART else FieldOut = F_OUTPUT_SCART_LR; break; default: break; } // enable audio matrix config except if "mute" for SCART (done later) if (FieldOut) DVAUD_I2cWriteField(FieldOut, Matrix); // if out is SPDIF: deselect SPDIF bypass if (eOutput == DVAUD_kOutputSPDIF) DVAUD_I2cClrBit(F_SPDIF_BYPASS); FieldMute = 0; // if out = Scart1/2/3 // manage "mute" directly in scart out select block // need to set scart out select module too if (eOutput == DVAUD_kOutputSCART1) { FieldOut = F_SC1_OUTPUT_SEL; FieldMute = F_SC1_MUTE; } else if (eOutput == DVAUD_kOutputSCART2) { FieldOut = F_SC2_OUTPUT_SEL; FieldMute = F_SC2_MUTE; } else if (eOutput == DVAUD_kOutputSCART3) { FieldOut = F_SC3_OUTPUT_SEL; FieldMute = F_SC3_MUTE; } // mute or unmute corresponding output if (FieldMute) { if (Matrix == 0) // mute on SCARTn DVAUD_I2cSetBit(FieldMute); // mute output scart n else { DVAUD_I2cWriteField(FieldOut, 0); // select DAC SCART n DVAUD_I2cClrBit(FieldMute); // unmute output scart n } } return I2C_Status; } static DVAUD_Status_t DVAUD_ManageMainAudioMatrix( const DVAUD_Output_t eOutput, const DVAUD_Input_t eInput) { U8 AudioMatrix; // if IN = external SPDIF pin and OUT = SPDIF: enable bypass if (eInput == DVAUD_kInputExternalSPDIF) { if (eOutput == DVAUD_kOutputSPDIF) DVAUD_I2cSetBit(F_SPDIF_BYPASS); else // external SPDIF not allowed to any other output I2C_Status = DVAUD_kBadParameter; } else { // select proper input parameter for main audio matrix AudioMatrix = DVAUD_GetMainAudioMatrixInput(eInput); if (AudioMatrix == 0xFF) // wrong input parameter I2C_Status = DVAUD_kBadParameter; else DVAUD_SetMainAudioMatrixOutput(eOutput, AudioMatrix, eInput); // program output matrix including SIF1/2 switch } return I2C_Status; } static U8 DVAUD_CheckIfDirectScanIn( const DVAUD_Input_t eInput) { switch (eInput) { case DVAUD_kDirectMono: case DVAUD_kDirectSCART1: case DVAUD_kDirectSCART2: case DVAUD_kDirectSCART3: case DVAUD_kDirectSCART4: case DVAUD_kDirectSCART5: return 1; default: return 0; } } static DVAUD_Status_t DVAUD_ManageDirectScartOut ( const DVAUD_Output_t eOutput, const DVAUD_Input_t eInput) { U8 ScartOutSelect; U16 FieldOut, FieldMute; // select field to program input select & field to unmute depending on scart output if (eOutput == DVAUD_kOutputSCART1) { FieldOut = F_SC1_OUTPUT_SEL; FieldMute = F_SC1_MUTE; } else if (eOutput == DVAUD_kOutputSCART2) { FieldOut = F_SC2_OUTPUT_SEL; FieldMute = F_SC2_MUTE; } else // DVAUD_kOutputSCART3 { FieldOut = F_SC3_OUTPUT_SEL; FieldMute = F_SC3_MUTE; } // select input select value to program switch (eInput) { case DVAUD_kDirectMono: ScartOutSelect = 1; break; case DVAUD_kDirectSCART1: ScartOutSelect = 2; break; case DVAUD_kDirectSCART2: ScartOutSelect = 3; break; case DVAUD_kDirectSCART3: ScartOutSelect = 4; break; case DVAUD_kDirectSCART4: ScartOutSelect = 5; break; case DVAUD_kDirectSCART5: ScartOutSelect = 7; break; default: return DVAUD_kBadParameter; // should never occur thanks to DVAUD_CheckIfDirectScanIn() } DVAUD_I2cWriteField(FieldOut, ScartOutSelect); // R_SCART1_2_OUTPUT_CTRL or R_SCART3_OUT_SCAUX_CTRL DVAUD_I2cClrBit(FieldMute); // then unmute scart out return I2C_Status; } // everything except I2S DVAUD_Status_t DVAUD_SwitchConnect ( const DVAUD_Output_t eOutput, const DVAUD_Input_t eInput) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eOutput) { case DVAUD_kOutputSpeaker: case DVAUD_kOutputCenter: case DVAUD_kOutputSubwoofer: case DVAUD_kOutputSurround: case DVAUD_kOutputHeadphone: case DVAUD_kOutputI2SDelay: case DVAUD_kOutputSPDIF: return DVAUD_ManageMainAudioMatrix(eOutput, eInput); // manage main audio matrix select block case DVAUD_kOutputSCART1: case DVAUD_kOutputSCART2: case DVAUD_kOutputSCART3: if (DVAUD_CheckIfDirectScanIn(eInput)) // check if direct scart input select return DVAUD_ManageDirectScartOut(eOutput, eInput); // manage scart out select block (direct) else return DVAUD_ManageMainAudioMatrix(eOutput, eInput); // manage main audio matrix select block default: return DVAUD_kBadParameter; } } // ****************************************************************** // I2S only DVAUD_Status_t DVAUD_I2SSwitchConnect ( const DVAUD_I2SOutput_t eI2SOutput, const DVAUD_Output_t eOutput) { U8 I2SOutSelect; U16 FieldOut, FieldDir; FieldDir = 0; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch(eI2SOutput) { case DVAUD_kOutputI2SData0: FieldOut = F_I2S_DATA0_CTRL; FieldDir = F_I2S_DATA0_DIR; break; case DVAUD_kOutputI2SData1: FieldOut = F_I2S_DATA1_CTRL; FieldDir = F_I2S_DATA1_DIR; break; case DVAUD_kOutputI2SData2: FieldOut = F_I2S_DATA2_CTRL; FieldDir = F_I2S_DATA2_DIR; break; case DVAUD_kOutputI2SData3: FieldOut = F_I2S_DATA3_CTRL; FieldDir = F_I2S_DATA3_DIR; break; case DVAUD_kOutputI2SAData: FieldOut = F_I2SA_DATA_CTRL; FieldDir = F_I2SA_DATA_DIR; break; case DVAUD_kOutputI2SOData0: // TQFP100 only FieldOut = F_I2SO_DATA0_CTRL; // no direction bit break; case DVAUD_kOutputI2SOData1: // TQFP100 only FieldOut = F_I2SO_DATA1_CTRL; // no direction bit break; default: // parameter not in list return DVAUD_kBadParameter; } switch (eOutput) { case DVAUD_kOutputMuted: // specific parameter to mute I2Sx output (and also revert it to "in") I2SOutSelect = 0; break; case DVAUD_kOutputSpeaker: I2SOutSelect = 1; break; case DVAUD_kOutputSurround: case DVAUD_kOutputHeadphone: I2SOutSelect = 2; break; case DVAUD_kOutputCenter: case DVAUD_kOutputSubwoofer: I2SOutSelect = 3; break; case DVAUD_kOutputSCART1: case DVAUD_kOutputSCART2: case DVAUD_kOutputSCART3: I2SOutSelect = 4; break; case DVAUD_kOutputSPDIF: I2SOutSelect = 5; break; case DVAUD_kOutputI2SDelay: I2SOutSelect = 6; break; case DVAUD_kOutputPCMCLK: // only for I2S3 if (eI2SOutput == DVAUD_kOutputI2SData3) I2SOutSelect = 7; else return DVAUD_kFeatureNotSupported; break; default: // parameter not in list return DVAUD_kBadParameter; } // write I2S config DVAUD_I2cWriteField(FieldOut, I2SOutSelect); // if muted: also set direction to "in", otherwise to "out" if (FieldDir) // only for I2S 0 1 2 3 A { if (eOutput == DVAUD_kOutputMuted) DVAUD_I2cClrBit(FieldDir); else DVAUD_I2cSetBit(FieldDir); } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_IRQSetConfig ( const DVAUD_IRQConfig_t* const pstConfig) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; // IRQ0 new standard always enabled // IRQ1 sync lost switch (pstConfig->eIRQ1I2SSyncLost) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_IRQ1_ENABLE); // R_I2S_IN_CONF break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_IRQ1_ENABLE); break; default: // parameter not in list return DVAUD_kBadParameter; } // IRQ2 sync found switch (pstConfig->eIRQ2I2SSyncFound) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_IRQ2_ENABLE); // R_I2S_IN_CONF break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_IRQ2_ENABLE); break; default: // parameter not in list return DVAUD_kBadParameter; } // IRQ3 freq change switch (pstConfig->eIRQ3I2SFreqChange) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_IRQ3_ENABLE); // R_I2S_IN_CONF break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_IRQ3_ENABLE); break; default: // parameter not in list return DVAUD_kBadParameter; } // IRQ4 HP status change always enabled // IRQ5 HP unmute ready always enabled return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_IRQReset ( const DVAUD_IRQConfig_t* const pstConfig) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; // IRQ0 new standard switch (pstConfig->eIRQ0NewStandard) { case DVAUD_kDisabled: // do nothing break; case DVAUD_kEnabled: // reset H/W flag DVAUD_I2cClrBit(F_IRQ0); // R_IRQ_STATUS break; default: // parameter not in list return DVAUD_kBadParameter; } // IRQ1 sync lost switch (pstConfig->eIRQ1I2SSyncLost) { case DVAUD_kDisabled: // do nothing break; case DVAUD_kEnabled: // reset H/W flag DVAUD_I2cClrBit(F_IRQ1); // R_IRQ_STATUS break; default: // parameter not in list return DVAUD_kBadParameter; } // IRQ2 sync found switch (pstConfig->eIRQ2I2SSyncFound) { case DVAUD_kDisabled: // do nothing break; case DVAUD_kEnabled: // reset H/W flag DVAUD_I2cClrBit(F_IRQ2); // R_IRQ_STATUS break; default: // parameter not in list return DVAUD_kBadParameter; } // IRQ3 freq change switch (pstConfig->eIRQ3I2SFreqChange) { case DVAUD_kDisabled: // do nothing break; case DVAUD_kEnabled: // reset H/W flag DVAUD_I2cClrBit(F_IRQ3); // R_IRQ_STATUS break; default: // parameter not in list return DVAUD_kBadParameter; } // IRQ4 HP status change switch (pstConfig->eIRQ4HPStatusChange) { case DVAUD_kDisabled: // do nothing break; case DVAUD_kEnabled: // reset H/W flag DVAUD_I2cClrBit(F_IRQ4); // R_IRQ_STATUS break; default: // parameter not in list return DVAUD_kBadParameter; } // IRQ5 HP unmute ready switch (pstConfig->eIRQ5HPUnmuteReady) { case DVAUD_kDisabled: // do nothing break; case DVAUD_kEnabled: // reset H/W flag DVAUD_I2cClrBit(F_IRQ5); // R_IRQ_STATUS break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_IRQGet ( DVAUD_Bool_t* const peOneIRQIsSet, DVAUD_IRQConfig_t* const pstConfig) { U8 IrqStatus; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; IrqStatus = DVAUD_I2cReadReg(R_IRQ_STATUS) & 0x3F; // return true if at least 1 IRQ is found set *peOneIRQIsSet = (IrqStatus) ? DVAUD_kTrue : DVAUD_kFalse; // IRQ0 new standard set? pstConfig->eIRQ0NewStandard = (IrqStatus & 0x01) ? DVAUD_kEnabled : DVAUD_kDisabled; // IRQ1 sync lost set? pstConfig->eIRQ1I2SSyncLost = (IrqStatus & 0x02) ? DVAUD_kEnabled : DVAUD_kDisabled; // IRQ2 sync found set? pstConfig->eIRQ2I2SSyncFound = (IrqStatus & 0x04) ? DVAUD_kEnabled : DVAUD_kDisabled; // IRQ3 freq change set? pstConfig->eIRQ3I2SFreqChange = (IrqStatus & 0x08) ? DVAUD_kEnabled : DVAUD_kDisabled; // IRQ4 HP status change set? pstConfig->eIRQ4HPStatusChange = (IrqStatus & 0x10) ? DVAUD_kEnabled : DVAUD_kDisabled; // IRQ5 HP unmute ready set? pstConfig->eIRQ5HPUnmuteReady = (IrqStatus & 0x20) ? DVAUD_kEnabled : DVAUD_kDisabled; return I2C_Status; } // ****************************************************************** #define NBOFI2SCONFIGREG 5 static const U8 I2SPinConfigReg[NBOFI2SCONFIGREG] = { R_I2S_MATRIX_CTRL0, // 0x53 R_I2S_MATRIX_CTRL1, // 0x54 R_I2S_MATRIX_CTRL2, // 0x55 R_I2SO_DATA_CTRL, // 0x59 R_I2S_MATRIX_INPUT_CTRL // 0x5E }; static const U8 I2SPinConfig[DVAUD_kNbOfI2PinConfigPreset][NBOFI2SCONFIGREG] = { { 0x00, 0x00, 0x0A, 0x31, 0x00 }, // TQFP100 Conf 1: 4 * I2S in (@48kHz) + 3 * I2S out { 0xE0, 0xF0, 0x0A, 0x31, 0x01 }, // TQFP100 Conf 2: I2S SRC in + I2S delay loop (@48kHz) + 3 * I2S out { 0xE0, 0xF0, 0x10, 0x31, 0x53 }, // TQFP100 Conf 3: I2Saux SRC in + I2S delay loop (@48kHz) + 2 * I2S out { 0xE0, 0xF0, 0x1A, 0x31, 0x00 }, // TQFP100 Conf 4: I2S delay loop (@48kHz) + 3 * I2S out { 0x00, 0x00, 0xC0, 0x00, 0x00 }, // TQFP80 Conf 1: 4 * I2S in (@48kHz) + 0 * I2S out { 0x00, 0x09, 0x50, 0x01, 0xA0 } // TQFP80 Conf 2: I2S SRC in + 1 * I2S out }; DVAUD_Status_t DVAUD_I2SPinSetConfig ( const DVAUD_I2SPinConfig_t* const pstConfig) { U8 Index, Reg, Input_Conf, WaitLoop, FW_Version; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; if (pstConfig->eI2SPinConfigPreset >= DVAUD_kNbOfI2PinConfigPreset) return DVAUD_kBadParameter; Index = pstConfig->eI2SPinConfigPreset; // index in registers table and registers values table for (Reg=0; Reg < NBOFI2SCONFIGREG; Reg++) DVAUD_I2cWriteReg(I2SPinConfigReg[Reg], I2SPinConfig[Index][Reg]); // Restart device if needed Input_Conf = DVAUD_I2cReadField(F_INPUT_CONFIG); if ((pstConfig->eI2SPinConfigPreset == DVAUD_kTQFP100Conf1) || (pstConfig->eI2SPinConfigPreset == DVAUD_kTQFP80Conf1)) { // Multi 48 mode needed if (Input_Conf == 0) // SRC mode -> Restart needed { // Stop DSP F/W DVAUD_I2cClrBit(F_DSP_FW_RUN); // R_DSP_FW_CONF // wait until DSP ready WaitLoop = 10; while(WaitLoop) { // delay 1ms WAIT_Inms(1); if (DVAUD_I2cReadField(F_DSP_FW_READY)) // STAT_DSP_INIT if DSP ready break; // exit loop WaitLoop--; } if (!WaitLoop) // end of loop, DSP never ready return DVAUD_kUnknownError; // run DSP DVAUD_I2cWriteReg(R_DSP_FW_CONF, 0x05); // delay 2ms WAIT_Inms(2); // check STAT F/W version number (in IC ROM) specific to IC type // this is a data from design, specific to IC type switch (Dev_ID) { case DVAUD_k83x7: FW_Version = 0x15; break; case DVAUD_k83x8: FW_Version = 0x2F; break; default: // should never occur... FW_Version = 0x00; break; } if (DVAUD_I2cReadField(F_FW_VERSION) != FW_Version) // STAT_FW_VERSION return DVAUD_kUnknownError; } } else // pstConfig->eI2SPinConfigPreset == DVAUD_kTQFP100Conf2/3/4 DVAUD_kTQFP80Conf2 { // SRC mode needed if (Input_Conf == 1) // Mutli 48 mode -> Restart needed { // Stop DSP F/W DVAUD_I2cClrBit(F_DSP_FW_RUN); // R_DSP_FW_CONF // wait until DSP ready WaitLoop = 10; while(WaitLoop) { // delay 1ms WAIT_Inms(1); if (DVAUD_I2cReadField(F_DSP_FW_READY)) // STAT_DSP_INIT if DSP ready break; // exit loop WaitLoop--; } if (!WaitLoop) // end of loop, DSP never ready return DVAUD_kUnknownError; // run DSP DVAUD_I2cWriteReg(R_DSP_FW_CONF, 0x01); // delay 2ms WAIT_Inms(2); // check STAT F/W version number (in IC ROM) specific to IC type // this is a data from design, specific to IC type switch (Dev_ID) { case DVAUD_k83x8: FW_Version = 0x2F; break; case DVAUD_k83x7: FW_Version = 0x15; break; default: // should never occur... FW_Version = 0x00; break; } if (DVAUD_I2cReadField(F_FW_VERSION) != FW_Version) // STAT_FW_VERSION return DVAUD_kUnknownError; } } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_I2SHWSetConfig ( const DVAUD_I2SHWConfig_t* const pstConfig) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (pstConfig->eSyncSignIsPositive) { case DVAUD_kTrue: DVAUD_I2cSetBit(F_SYNC_SIGN); // R_I2S_CTRL break; case DVAUD_kFalse: DVAUD_I2cClrBit(F_SYNC_SIGN); break; default: // parameter not in list return DVAUD_kBadParameter; } if ((pstConfig->eLockThreshold) >= DVAUD_kNbOfI2SLockThreshold) return DVAUD_kBadParameter; DVAUD_I2cWriteField(F_LOCK_TH, pstConfig->eLockThreshold); // R_I2S_CTRL if ((pstConfig->eSyncConstant) >= DVAUD_kNbOfI2SSyncConstant) return DVAUD_kBadParameter; DVAUD_I2cWriteField(F_SYNC_CST, pstConfig->eSyncConstant); // R_I2S_CTRL return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_I2SSWSetConfig ( const DVAUD_I2SSWConfig_t* const pstConfig, const DVAUD_I2SSWConfig_t* const pstDelayConfig, const U8 ucShiftRight, const U8 ucWordMask) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; // main I2S configuration switch (pstConfig->eLRCLKStartIsRight) { case DVAUD_kTrue: DVAUD_I2cSetBit(F_LRCLK_START); // R_I2S_IN_CONF break; case DVAUD_kFalse: DVAUD_I2cClrBit(F_LRCLK_START); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstConfig->eLRCLKPolarityIsHigh) { case DVAUD_kTrue: DVAUD_I2cSetBit(F_LRCLK_POLARITY);// R_I2S_IN_CONF break; case DVAUD_kFalse: DVAUD_I2cClrBit(F_LRCLK_POLARITY); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstConfig->eSCLKPolarityIsRise) { case DVAUD_kTrue: DVAUD_I2cSetBit(F_SCLK_POLARITY); // R_I2S_IN_CONF break; case DVAUD_kFalse: DVAUD_I2cClrBit(F_SCLK_POLARITY); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstConfig->eMSBIsFirst) { case DVAUD_kTrue: DVAUD_I2cSetBit(F_DATA_CFG); // R_I2S_IN_CONF break; case DVAUD_kFalse: DVAUD_I2cClrBit(F_DATA_CFG); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstConfig->eUModeIsStandard) { case DVAUD_kTrue: DVAUD_I2cSetBit(F_I2S_MODE); // R_I2S_IN_CONF break; case DVAUD_kFalse: DVAUD_I2cClrBit(F_I2S_MODE); break; default: // parameter not in list return DVAUD_kBadParameter; } // I2S delay configuration switch (pstDelayConfig->eLRCLKStartIsRight) { case DVAUD_kTrue: DVAUD_I2cSetBit(F_DELAY_LRCLK_START); // R_I2S_IN_DELAY_CONF break; case DVAUD_kFalse: DVAUD_I2cClrBit(F_DELAY_LRCLK_START); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstDelayConfig->eLRCLKPolarityIsHigh) { case DVAUD_kTrue: DVAUD_I2cSetBit(F_DELAY_LRCLK_POLARITY); // R_I2S_IN_DELAY_CONF break; case DVAUD_kFalse: DVAUD_I2cClrBit(F_DELAY_LRCLK_POLARITY); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstDelayConfig->eSCLKPolarityIsRise) { case DVAUD_kTrue: DVAUD_I2cSetBit(F_DELAY_SCLK_POLARITY); // R_I2S_IN_DELAY_CONF break; case DVAUD_kFalse: DVAUD_I2cClrBit(F_DELAY_SCLK_POLARITY); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstDelayConfig->eMSBIsFirst) { case DVAUD_kTrue: DVAUD_I2cSetBit(F_DELAY_DATA_CFG); // R_I2S_IN_DELAY_CONF break; case DVAUD_kFalse: DVAUD_I2cClrBit(F_DELAY_DATA_CFG); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstDelayConfig->eUModeIsStandard) { case DVAUD_kTrue: DVAUD_I2cSetBit(F_DELAY_I2S_MODE); // R_I2S_IN_DELAY_CONF break; case DVAUD_kFalse: DVAUD_I2cClrBit(F_DELAY_I2S_MODE); break; default: // parameter not in list return DVAUD_kBadParameter; } if (ucShiftRight > 31) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_SHIFT_RIGHT_RANGE, ucShiftRight); // R_I2S_IN_SHIFT_RIGHT if (ucWordMask > 31) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_WORD_MASK, ucWordMask); // R_I2S_IN_MASK return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_I2SInputFrequencyGet ( DVAUD_I2SFrequency_t* const peI2SFreq) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; *peI2SFreq = (DVAUD_I2SFrequency_t) DVAUD_I2cReadField(F_I2S_INPUT_FREQ); // R_STAT_STD_HP_I2S_IN return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_SPDIFOutSetConfig ( const DVAUD_SPDIFConfig_t* const pstConfig) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (pstConfig->eNoCopyright) { case DVAUD_kTrue: DVAUD_I2cSetBit(F_SPDIF_NO_COPYRIGHT); // R_SPDIF_CONF break; case DVAUD_kFalse: DVAUD_I2cClrBit(F_SPDIF_NO_COPYRIGHT); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstConfig->eNoPCM) { case DVAUD_kTrue: DVAUD_I2cSetBit(F_SPDIF_NO_PCM); // R_SPDIF_CONF break; case DVAUD_kFalse: DVAUD_I2cClrBit(F_SPDIF_NO_PCM); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_ParametricEqSetConfig ( const DVAUD_ParametricEqConfig_t* const pstConfig) { U16 Freq; U32 ulVal; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; Freq = pstConfig->ucFrequencyInHz; switch (pstConfig->ucBandNumber) { case 1: if (Freq<40 || Freq>400) return DVAUD_kBadParameter; ulVal = ((Freq-40)*255L)/360L; break; case 2: if (Freq<400 || Freq>2000) return DVAUD_kBadParameter; ulVal = ((Freq-400)*255L)/1600L; break; case 3: if (Freq<2000 || Freq>10000) return DVAUD_kBadParameter; ulVal = ((Freq-2000)*255L)/8000L; break; default: return DVAUD_kBadParameter; } DVAUD_I2cWriteReg(R_PARAM_EQ_CONF2, (U8)ulVal); // previous computation already scaled value down to 8 bits if ((pstConfig->ucQ) > 31) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_PARAM_EQ_Q, pstConfig->ucQ); // R_PARAM_EQ_CONF3 // valid range is -12dB to +3dB if ((pstConfig->sGainInmdB)<(-12000) || (pstConfig->sGainInmdB)>3000) return DVAUD_kBadParameter; // value out of range ulVal = (pstConfig->sGainInmdB)/500; // range -24..+6 = -12..+3dB (step 0.5dB) DVAUD_I2cWriteField(F_PARAM_EQ_GAIN, (U8)ulVal); // R_PARAM_EQ_CONF1 // enable band only at the very end to write new set of parameters switch (pstConfig->ucBandNumber) { case 1: DVAUD_I2cSetBit(F_BAND1_VALID); // R_PARAM_EQ_CONF3 break; case 2: DVAUD_I2cSetBit(F_BAND2_VALID); // R_PARAM_EQ_CONF3 break; case 3: DVAUD_I2cSetBit(F_BAND3_VALID); // R_PARAM_EQ_CONF3 break; // no default, parameter was already checked before } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_ParametricEqSet ( const DVAUD_Enabled_t eNewStatus) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eNewStatus) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_PARAM_EQ_ON); // R_PARAM_EQ_CONF1 break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_PARAM_EQ_ON); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_AnticlippingSetConfig ( const DVAUD_AnticlippingMode_t eLSNewStatus, const DVAUD_AnticlippingMode_t eHPNewStatus, const DVAUD_AnticlippingMode_t eSCARTNewStatus, const DVAUD_AnticlippingMode_t eSPDIFNewStatus) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; if (eLSNewStatus >= DVAUD_kNbOfAnticlippingMode) return DVAUD_kBadParameter; DVAUD_I2cWriteField(F_CLAMP_LS, eLSNewStatus); // R_ANTICLIPPING if (eHPNewStatus >= DVAUD_kNbOfAnticlippingMode) return DVAUD_kBadParameter; DVAUD_I2cWriteField(F_CLAMP_HP, eHPNewStatus); // R_ANTICLIPPING if (eSCARTNewStatus >= DVAUD_kNbOfAnticlippingMode) return DVAUD_kBadParameter; DVAUD_I2cWriteField(F_CLAMP_SCART, eSCARTNewStatus); // R_ANTICLIPPING if (eSPDIFNewStatus >= DVAUD_kNbOfAnticlippingMode) return DVAUD_kBadParameter; DVAUD_I2cWriteField(F_CLAMP_SPDIF, eSPDIFNewStatus); // R_ANTICLIPPING return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_HPDetectSetConfig ( const DVAUD_HPDetectMode_t eNewStatus, const DVAUD_Enabled_t eLSAutoMute) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; if (eNewStatus >= DVAUD_kNbOfHPDetectMode) return DVAUD_kBadParameter; DVAUD_I2cWriteField(F_HP_MODE, eNewStatus); // R_HP_SCARTAUX_CONF switch (eLSAutoMute) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_LS_AUTO_MUTE); // R_HP_SCARTAUX_CONF break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_LS_AUTO_MUTE); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_HPDetectGet ( DVAUD_Enabled_t* const peNewState) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; *peNewState = DVAUD_I2cReadField(F_HP_DETECTED) ? DVAUD_kEnabled : DVAUD_kDisabled; // R_STAT_STD_HP_I2S_IN return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_BeeperSetConfig ( const DVAUD_BeeperConfig_t* const pstConfig) { U8 BeepPath; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; if ((pstConfig->eBeeperSound) >= DVAUD_kNbOfBeeperSound) return DVAUD_kBadParameter; DVAUD_I2cWriteField(F_SOUND_SELECT, pstConfig->eBeeperSound); // R_BEEPER_CONF1 if ((pstConfig->eBeeperNote) >= DVAUD_kNbOfBeeperNote) return DVAUD_kBadParameter; DVAUD_I2cWriteField(F_BEEP_NOTE, pstConfig->eBeeperNote); // R_BEEPER_CONF3 if ((pstConfig->ucBeeperOctave)==0 || (pstConfig->ucBeeperOctave)>6) // octave from 1 to 6 return DVAUD_kBadParameter; DVAUD_I2cWriteField(F_BEEP_OCTAVE, (pstConfig->ucBeeperOctave)-1); // R_BEEPER_CONF3 real value from 0 to 5 if ((pstConfig->eBeeperRelease) >= DVAUD_kNbOfBeeperRelease) return DVAUD_kBadParameter; DVAUD_I2cWriteField(F_BEEP_RELEASE, pstConfig->eBeeperRelease); // R_BEEPER_CONF4 BeepPath = 0; switch (pstConfig->eBeeperOnLS) { case DVAUD_kDisabled: break; case DVAUD_kEnabled: BeepPath |=1; break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstConfig->eBeeperOnHP) { case DVAUD_kDisabled: break; case DVAUD_kEnabled: BeepPath |=2; break; default: // parameter not in list return DVAUD_kBadParameter; } DVAUD_I2cWriteField(F_BEEP_PATH, BeepPath); // R_BEEPER_CONF2 switch (pstConfig->eBeeperContinuous) { case DVAUD_kTrue: DVAUD_I2cSetBit(F_CONTINUOUS_MODE); // R_BEEPER_CONF4 break; case DVAUD_kFalse: DVAUD_I2cClrBit(F_CONTINUOUS_MODE); break; default: // parameter not in list return DVAUD_kBadParameter; } if ((pstConfig->eBeeperDuration) >= DVAUD_kNbOfBeeperDuration) return DVAUD_kBadParameter; DVAUD_I2cWriteField(F_BEEP_DURATION, pstConfig->eBeeperDuration); // R_BEEPER_CONF4 if ((pstConfig->cBeeperVolumeIndB)<(-93) || (pstConfig->cBeeperVolumeIndB)>0) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_BEEP_VOLUME, ((pstConfig->cBeeperVolumeIndB)+93)/3); // R_BEEPER_CONF2,0x1F [-93;0] converts to [0;31] return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_BeeperSet ( const DVAUD_Enabled_t eNewStatus) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eNewStatus) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_BEEP_ON); // R_BEEPER_CONF1 break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_BEEP_ON); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_STOmniSurroundSetConfig ( const DVAUD_STOmniSurroundConfig_t* const pstConfig) // -> LS only { U16 Percent; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; if ((pstConfig->eSurroundMode) >= DVAUD_kNbOfOmniSurroundMode) return DVAUD_kBadParameter; DVAUD_I2cWriteField(F_OMNISRND_INPUT_MODE, pstConfig->eSurroundMode); // R_OMNISRND_CONF1 if ((pstConfig->eWideMode) >= DVAUD_kNbOfWideMode) return DVAUD_kBadParameter; DVAUD_I2cWriteField(F_WIDE_MODE, pstConfig->eWideMode); // R_OMNISRND_CONF2 if ((pstConfig->ucWideLevelInPercent) > 100) return DVAUD_kBadParameter; Percent = ((U16)(pstConfig->ucWideLevelInPercent)*(U16)63)/100; // range [0;100%] converts to [0;63] DVAUD_I2cWriteField(F_WIDE_LEVEL, (U8)Percent); // R_OMNISRND_CONF2 if ((pstConfig->eVoiceMode) >= DVAUD_kNbOfVoiceMode) return DVAUD_kBadParameter; DVAUD_I2cWriteField(F_ST_VOICE, pstConfig->eVoiceMode); // R_OMNISRND_CONF1 return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_STOmniSurroundSet ( const DVAUD_Enabled_t eNewStatus) // -> LS only { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eNewStatus) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_OMNISRND_ON); // R_OMNISRND_CONF1 break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_OMNISRND_ON); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_STDynamicBassSetConfig ( const DVAUD_Output_t eOutput, const DVAUD_STDynamicBassConfig_t* const pstConfig) // -> LS & HP { U8 Reg; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eOutput) { case DVAUD_kOutputSpeaker: // LS Reg = 1; // 1=LS break; case DVAUD_kOutputHeadphone: // HP Reg = 0; // 0=HP break; default: // parameter config not in list return DVAUD_kBadParameter; } if ((pstConfig->eFrequency) >= DVAUD_kNbOfDynamicBassFrequency) return DVAUD_kBadParameter; // R_DYNAMIC_BASS_LS or R_DYNAMIC_BASS_HP DVAUD_I2cWriteField((Reg)? F_DYN_BASS_LS_FREQ : F_DYN_BASS_HP_FREQ, pstConfig->eFrequency); if ((pstConfig->usGainInmdB)>15500) return DVAUD_kBadParameter; // value out of range // range 0..31 = 0..+15.5dB (step 0.5dB) // R_DYNAMIC_BASS_LS or R_DYNAMIC_BASS_HP DVAUD_I2cWriteField((Reg)? F_DYN_BASS_LS_LEVEL : F_DYN_BASS_HP_LEVEL, (pstConfig->usGainInmdB)/500); return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_STBynamicBassSet ( const DVAUD_Output_t eOutput, const DVAUD_Enabled_t eNewStatus) // -> LS & HP { U16 Field; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eOutput) { case DVAUD_kOutputSpeaker: // LS Field = F_DYN_BASS_LS_ON; // R_DYNAMIC_BASS_LS break; case DVAUD_kOutputHeadphone: // HP Field = F_DYN_BASS_HP_ON; // R_DYNAMIC_BASS_HP break; default: // parameter config not in list return DVAUD_kBadParameter; } switch (eNewStatus) { case DVAUD_kDisabled: DVAUD_I2cClrBit(Field); break; case DVAUD_kEnabled: DVAUD_I2cSetBit(Field); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_SRSTruSurroundXTSetConfig ( const DVAUD_SRSTruSurroundXTConfig_t* const pstConfig) // -> LS only { S32 ValLS; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; if ((Dev_Capability.eSRSTruSurroundXT != DVAUD_kImplemented) && (Dev_Capability.eSRSWOW != DVAUD_kImplemented)) return DVAUD_kFeatureNotSupported; // no SRS supported if (((pstConfig->eSurroundMode) != DVAUD_kTruSurroundMono) && ((pstConfig->eSurroundMode) != DVAUD_kTruSurroundStereo) && (Dev_Capability.eSRSWOW == DVAUD_kImplemented)) return DVAUD_kFeatureNotSupported; // only Mono and Stereo modes supported in SRS Wow (SRS=1) if ((pstConfig->eSurroundMode) >= DVAUD_kNbOfTruSurroundXTMode) return DVAUD_kBadParameter; DVAUD_I2cWriteField(F_TRUSRND_INPUT_MODE, pstConfig->eSurroundMode); // R_TRUSRND_CONF switch (pstConfig->eTruSurroundXTIsBypassed) { case DVAUD_kTrue: DVAUD_I2cSetBit(F_TRUSRND_BYPASS); // R_TRUSRND_CONF break; case DVAUD_kFalse: DVAUD_I2cClrBit(F_TRUSRND_BYPASS); break; default: // parameter not in list return DVAUD_kBadParameter; } // Attenuation -127.5dB -> 0dB ValLS = pstConfig->lTSXTAttenuationInmdB; if (ValLS>0 || ValLS<(-127500)) return DVAUD_kBadParameter; // value out of range // range -127.5dB..0 = 0..255 (step 0.5) DVAUD_I2cWriteReg(R_TRUSRND_LEVEL, (-ValLS)/500); switch (pstConfig->eDialogClarity) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_DC_ON); // R_TRUSRND_CONF break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_DC_ON); break; default: // parameter not in list return DVAUD_kBadParameter; } // Attenuation -127.5dB -> 0dB ValLS = pstConfig->lDCAttenuationInmdB; if (ValLS>0 || ValLS<(-127500)) return DVAUD_kBadParameter; // value out of range // range -127.5dB..0 = 0..255 (step 0.5) DVAUD_I2cWriteReg(R_TRUSRND_DC_LEVEL, (-ValLS)/500); return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_SRSTruSurroundXTSet ( const DVAUD_Enabled_t eNewStatus) // -> LS only { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; if ((Dev_Capability.eSRSTruSurroundXT != DVAUD_kImplemented) && (Dev_Capability.eSRSWOW != DVAUD_kImplemented)) return DVAUD_kFeatureNotSupported; // no SRS supported switch (eNewStatus) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_TRUSRND_ON); // R_TRUSRND_CONF break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_TRUSRND_ON); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_SRSTruBassSetConfig ( const DVAUD_Output_t eOutput, const DVAUD_SRSTruBassConfig_t* const pstConfig) // -> LS & HP { U8 Reg; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; if ((Dev_Capability.eSRSTruSurroundXT != DVAUD_kImplemented) && (Dev_Capability.eSRSWOW != DVAUD_kImplemented)) return DVAUD_kFeatureNotSupported; // no SRS supported switch (eOutput) { case DVAUD_kOutputSpeaker: // LS Reg = 1; // 1=LS break; case DVAUD_kOutputHeadphone: // HP Reg = 0; // 0=HP break; default: // parameter config not in list return DVAUD_kBadParameter; } if ((pstConfig->eFrequency) >= DVAUD_kNbOfTruBassFrequency) return DVAUD_kBadParameter; // R_TRUBASS_LS_CONF or R_TRUBASS_HP_CONF DVAUD_I2cWriteField((Reg)? F_TRUBASS_LS_SIZE : F_TRUBASS_HP_SIZE, pstConfig->eFrequency); if ((pstConfig->lAttenuationInmdB)<(-127500) || (pstConfig->lAttenuationInmdB)>0) return DVAUD_kBadParameter; // value out of range // range -127.5dB..0 = 0..255 (step 0.5) DVAUD_I2cWriteReg((Reg)? R_TRUBASS_LS_LEVEL : R_TRUBASS_HP_LEVEL, ((pstConfig->lAttenuationInmdB)/(-500))); return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_SRSTruBassSet ( const DVAUD_Output_t eOutput, const DVAUD_Enabled_t eNewStatus) // -> LS & HP { U16 Field; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; if ((Dev_Capability.eSRSTruSurroundXT != DVAUD_kImplemented) && (Dev_Capability.eSRSWOW != DVAUD_kImplemented)) return DVAUD_kFeatureNotSupported; // no SRS supported switch (eOutput) { case DVAUD_kOutputSpeaker: // LS Field = F_TRUBASS_LS_ON; // R_TRUBASS_LS_CONF break; case DVAUD_kOutputHeadphone: // HP Field = F_TRUBASS_HP_ON; // R_TRUBASS_HP_CONF break; default: // parameter config not in list return DVAUD_kBadParameter; } switch (eNewStatus) { case DVAUD_kDisabled: DVAUD_I2cClrBit(Field); break; case DVAUD_kEnabled: DVAUD_I2cSetBit(Field); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_SmartVolumeSetConfig ( const DVAUD_Output_t eOutput, const DVAUD_SmartVolumeConfig_t* const pstConfig) // -> LS & HP { U8 Reg; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eOutput) { case DVAUD_kOutputSpeaker: // LS Reg = 1; // 1=LS break; case DVAUD_kOutputHeadphone: // HP Reg = 0; // 0=HP break; default: // parameter config not in list return DVAUD_kBadParameter; } if (Reg == 1) // LS only { if ((pstConfig->ePeakDetection) >= DVAUD_kNbOfLSPeakDetectionMode) return DVAUD_kBadParameter; DVAUD_I2cWriteField(F_SVC_LS_INPUT, pstConfig->ePeakDetection); // R_SVC_CONF } if ((pstConfig->eReleaseTime) >= DVAUD_kNbOfReleaseTime) return DVAUD_kBadParameter; // R_SVC_LS_CONF or R_SVC_HP_CONF DVAUD_I2cWriteField((Reg) ? F_SVC_LS_TIME : F_SVC_HP_TIME, pstConfig->eReleaseTime); if (((pstConfig->cThresholdIndB) < (-31)) || ((pstConfig->cThresholdIndB) > 0)) return DVAUD_kBadParameter; // R_SVC_LS_CONF or R_SVC_HP_CONF DVAUD_I2cWriteField((Reg) ? F_SVC_LS_THRESHOLD : F_SVC_HP_THRESHOLD, -(pstConfig->cThresholdIndB)); if ((pstConfig->usMakeUpGainInmdB) > 24000) return DVAUD_kBadParameter; // R_SVC_LS_GAIN or R_SVC_HP_GAIN DVAUD_I2cWriteField((Reg) ? F_SVC_LS_MAKE_UP_GAIN : F_SVC_HP_MAKE_UP_GAIN, (pstConfig->usMakeUpGainInmdB)/500); return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_SmartVolumeSet ( const DVAUD_Output_t eOutput, const DVAUD_Enabled_t eNewStatus) // -> LS & HP { U16 Field; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eOutput) { case DVAUD_kOutputSpeaker: // LS Field = F_SVC_LS_ON; break; case DVAUD_kOutputHeadphone: // HP Field = F_SVC_HP_ON; break; default: // parameter config not in list return DVAUD_kBadParameter; } switch (eNewStatus) { case DVAUD_kDisabled: DVAUD_I2cClrBit(Field); // R_SVC_CONF break; case DVAUD_kEnabled: DVAUD_I2cSetBit(Field); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_EqualizerBassTrebleSetConfig ( const DVAUD_Output_t eOutput, const DVAUD_EQMode_t eEQMode, const S16* const psGainInmdB) // -> LS & HP // WARNING no out of boundary test is made on *psGainInmdB // it is up to the user to make sure that the pointer points onto an array of 2 or 5 "S16", depending on eEQMode value { U8 OutType; U8 EqType; const S16* GainArray; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eOutput) { case DVAUD_kOutputSpeaker: // LS OutType = 1; break; case DVAUD_kOutputHeadphone: // HP OutType = 0; break; default: // parameter config not in list return DVAUD_kBadParameter; } GainArray = psGainInmdB; // copy to temporary pointer if (OutType) // LS { switch (eEQMode) { case DVAUD_kModeEQ: // 5 band equalizer (LS only, HP is always bass/treble) EqType = 1; DVAUD_I2cClrBit(F_EQ_BT_LS_MODE); // R_EQ_BT_CONF break; case DVAUD_kModeBT: // 2 band bass/treble (LS only, HP is always like this) EqType = 0; DVAUD_I2cSetBit(F_EQ_BT_LS_MODE); break; default: // parameter config not in list return DVAUD_kBadParameter; } if ((*GainArray < (-12000)) || (*GainArray > 12000)) return DVAUD_kBadParameter; DVAUD_I2cWriteReg(R_EQ_BT_LS_BAND1, (*GainArray)/125); // LS Band 1 (=bass) GainArray++; // next data in array if (EqType) // 5 band mode { if ((*GainArray < (-12000)) || (*GainArray > 12000)) return DVAUD_kBadParameter; DVAUD_I2cWriteReg(R_EQ_BT_LS_BAND2, (*GainArray)/125); // LS Band 2 GainArray++; // next data in array if ((*GainArray < (-12000)) || (*GainArray > 12000)) return DVAUD_kBadParameter; DVAUD_I2cWriteReg(R_EQ_BT_LS_BAND3, (*GainArray)/125); // LS Band 3 GainArray++; // next data in array if ((*GainArray < (-12000)) || (*GainArray > 12000)) return DVAUD_kBadParameter; DVAUD_I2cWriteReg(R_EQ_BT_LS_BAND4, (*GainArray)/125); // LS Band 4 GainArray++; // next data in array } if ((*GainArray < (-12000)) || (*GainArray > 12000)) return DVAUD_kBadParameter; DVAUD_I2cWriteReg(R_EQ_BT_LS_BAND5, (*GainArray)/125); // LS Band 5 (=treble) } else // HP { switch (eEQMode) { case DVAUD_kModeBT: // 2 band bass/treble (LS only, HP is always like this) break; case DVAUD_kModeEQ: // 5 band equalizer (does not exist for HP) default: // parameter config not in list return DVAUD_kBadParameter; } if ((*GainArray < (-12000)) || (*GainArray > 12000)) return DVAUD_kBadParameter; DVAUD_I2cWriteReg(R_BT_HP_BASS, (*GainArray)/125); // HP Bass GainArray++; // next data in array if ((*GainArray < (-12000)) || (*GainArray > 12000)) return DVAUD_kBadParameter; DVAUD_I2cWriteReg(R_BT_HP_TREBLE, (*GainArray)/125); // HP Treble } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_EqualizerBassTrebleSet ( const DVAUD_Output_t eOutput, const DVAUD_Enabled_t eNewStatus) // -> LS & HP { U16 Field; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eOutput) { case DVAUD_kOutputSpeaker: // LS Field = F_EQ_BT_LS_ON; break; case DVAUD_kOutputHeadphone: // HP Field = F_BT_HP_ON; break; default: // parameter config not in list return DVAUD_kBadParameter; } switch (eNewStatus) { case DVAUD_kDisabled: DVAUD_I2cClrBit(Field); // R_EQ_BT_CONF break; case DVAUD_kEnabled: DVAUD_I2cSetBit(Field); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_LoudnessSetConfig ( const DVAUD_Output_t eOutput, const DVAUD_LoudnessConfig_t* const pstConfig) // -> LS & HP { U8 Reg; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eOutput) { case DVAUD_kOutputSpeaker: // LS Reg = 1; break; case DVAUD_kOutputHeadphone: // HP Reg = 0; break; default: // parameter config not in list return DVAUD_kBadParameter; } if (((pstConfig->cThresholdIndB) < (-42)) || ((pstConfig->cThresholdIndB) > 0)) return DVAUD_kBadParameter; DVAUD_I2cWriteField((Reg) ? F_LOUD_LS_THRESHOLD : F_LOUD_HP_THRESHOLD, (pstConfig->cThresholdIndB)/(-6)); if ((pstConfig->ucTrebleGainIndB) > 18) return DVAUD_kBadParameter; DVAUD_I2cWriteField((Reg) ? F_LOUD_LS_TREBLE : F_LOUD_HP_TREBLE, (pstConfig->ucTrebleGainIndB)/3); return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_LoudnessSet ( const DVAUD_Output_t eOutput, const DVAUD_Enabled_t eNewStatus) // -> LS & HP { U16 Field; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eOutput) { case DVAUD_kOutputSpeaker: // LS Field = F_LOUD_LS_ON; // R_LOUDNESS_LS break; case DVAUD_kOutputHeadphone: // HP Field = F_LOUD_HP_ON; // R_LOUDNESS_HP break; default: // parameter config not in list return DVAUD_kBadParameter; } switch (eNewStatus) { case DVAUD_kDisabled: DVAUD_I2cClrBit(Field); break; case DVAUD_kEnabled: DVAUD_I2cSetBit(Field); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_PrescalerSetConfig ( const DVAUD_Prescaler_t ePrescaler, const S16 iValueInmdB) { U16 Field; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (ePrescaler) { case DVAUD_kPrescalerAMEIAJMono: if ((Dev_Capability.eEIAJ != DVAUD_kImplemented) && (Dev_Capability.eDeviceType != DVAUD_k83x7)) return DVAUD_kFeatureNotSupported; Field = F_PRESCALE_AM_EIAJ; // R_PRESCALE_AM_EIAJ break; case DVAUD_kPrescalerFMBTSCMono: Field = F_PRESCALE_FM_BTSC; // R_PRESCALE_FM_BTSC break; case DVAUD_kPrescalerNICAM: if (Dev_Capability.eNICAM != DVAUD_kImplemented) return DVAUD_kFeatureNotSupported; Field = F_PRESCALE_NICAM; // R_PRESCALE_NICAM break; case DVAUD_kPrescalerBTSCStereo: Field = F_PRESCALE_BTSC_ST; // R_PRESCALE_BTSC_ST break; case DVAUD_kPrescalerBTSCSAP: Field = F_PRESCALE_BTSC_SAP; // R_PRESCALE_BTSC_SAP break; case DVAUD_kPrescalerEIAJStereo: if (Dev_Capability.eEIAJ != DVAUD_kImplemented) return DVAUD_kFeatureNotSupported; Field = F_PRESCALE_EIAJ_ST; // R_PRESCALE_EIAJ_ST break; case DVAUD_kPrescalerSCART: Field = F_PRESCALE_SCART; // R_PRESCALE_SCART break; case DVAUD_kPrescalerI2S0: Field = F_PRESCALE_I2S0; // R_PRESCALE_I2S0 break; case DVAUD_kPrescalerI2S1: Field = F_PRESCALE_I2S1; // R_PRESCALE_I2S1 break; case DVAUD_kPrescalerI2S2: Field = F_PRESCALE_I2S2; // R_PRESCALE_I2S2 break; case DVAUD_kPrescalerI2S3: Field = F_PRESCALE_I2S3; // R_PRESCALE_I2S3 break; default: // parameter config not in list return DVAUD_kBadParameter; } if (iValueInmdB<(-12000) || iValueInmdB>24000) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(Field, (U8)(iValueInmdB/500)); return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_PeakDetectorSetConfig ( const DVAUD_PeakDetectorConfig_t* const pstConfig, DVAUD_Bool_t const eLeftOverloadSet, // PJ DVAUD_Bool_t const eRightOverloadSet, // PJ DVAUD_Bool_t const eLROverloadSet) // PJ { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; if ((pstConfig->eSource) >= DVAUD_kNbOfPeakDetectorSource) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_PEAK_INPUT, pstConfig->eSource); // R_PEAK_DETECTOR if ((pstConfig->eLRRange) >= DVAUD_kNbOfPeakDetectorLRRange) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_PEAK_L_R_RANGE, pstConfig->eLRRange); // R_PEAK_DETECTOR switch (eLeftOverloadSet) { case DVAUD_kFalse: DVAUD_I2cClrBit(F_OVERLOAD_L); // R_STAT_PEAK_L break; case DVAUD_kTrue: DVAUD_I2cSetBit(F_OVERLOAD_L); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (eRightOverloadSet) { case DVAUD_kFalse: DVAUD_I2cClrBit(F_OVERLOAD_R); // R_STAT_PEAK_R break; case DVAUD_kTrue: DVAUD_I2cSetBit(F_OVERLOAD_R); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (eLROverloadSet) { case DVAUD_kFalse: DVAUD_I2cClrBit(F_OVERLOAD_L_R); // R_STAT_PEAK_L_R break; case DVAUD_kTrue: DVAUD_I2cSetBit(F_OVERLOAD_L_R); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_PeakDetectorSet ( const DVAUD_Enabled_t eNewStatus) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (eNewStatus) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_PEAK_ON); // R_PEAK_DETECTOR break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_PEAK_ON); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_PeakDetectorGet ( U8* const pucLeftLevelInDiv, U8* const pucRightLevelInDiv, U8* const pucLRLevelInDiv, DVAUD_Bool_t* peLeftOverload, DVAUD_Bool_t* peRightOverload, DVAUD_Bool_t* peLROverload) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; // levels over 7 bits *pucLeftLevelInDiv = DVAUD_I2cReadField(F_PEAK_L); // R_STAT_PEAK_L *pucRightLevelInDiv = DVAUD_I2cReadField(F_PEAK_R); // R_STAT_PEAK_R *pucLRLevelInDiv = DVAUD_I2cReadField(F_PEAK_L_R); // R_STAT_PEAK_L_R // test 8th bit (MSB) // R_STAT_PEAK_L *peLeftOverload = (DVAUD_I2cReadField(F_OVERLOAD_L)) ? DVAUD_kTrue : DVAUD_kFalse; // R_STAT_PEAK_R *peRightOverload = (DVAUD_I2cReadField(F_OVERLOAD_R)) ? DVAUD_kTrue : DVAUD_kFalse; // R_STAT_PEAK_L_R *peLROverload = (DVAUD_I2cReadField(F_OVERLOAD_L_R)) ? DVAUD_kTrue : DVAUD_kFalse; return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_AGCSetConfig ( const DVAUD_AGCConfig_t* const pstConfig) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; if ((pstConfig->usAGCGainAMInmdB) > 30000) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_AGC_ERR, (U8)((pstConfig->usAGCGainAMInmdB)/1500)); // R_AGC_GAIN return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_DemodSetConfig ( const DVAUD_DemodConfig_t* const pstConfig) { U16 ZwtData; if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; DVAUD_I2cWriteReg(R_SQTH1_MONO, pstConfig->ucFM1SquelchThMONO); DVAUD_I2cWriteReg(R_CETH1, pstConfig->ucFM1CarrierTh); DVAUD_I2cWriteReg(R_SQTH1, pstConfig->ucFM1SquelchTh); DVAUD_I2cWriteReg(R_CETH2, pstConfig->ucFM2CarrierTh); DVAUD_I2cWriteReg(R_SQTH2, pstConfig->ucFM2SquelchTh); switch (pstConfig->eNICAMErrorCounterIs64msec) { case DVAUD_kFalse: DVAUD_I2cClrBit(F_ECT); // R_NICAM_CTRL break; case DVAUD_kTrue: DVAUD_I2cSetBit(F_ECT); break; default: // parameter not in list return DVAUD_kBadParameter; } if ((pstConfig->eNICAMMaxError) >= DVAUD_kNbOfNICAMMaxError) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_MAE, pstConfig->eNICAMMaxError); // R_NICAM_CTRL if ((pstConfig->ucZweitonPilotThresoldInPercent) > 100) return DVAUD_kBadParameter; // value out of range if (pstConfig->ucZweitonPilotThresoldInPercent == 100) ZwtData = 15; // max value else ZwtData = (pstConfig->ucZweitonPilotThresoldInPercent)*4/25; // <-> /6.25 DVAUD_I2cWriteField(F_THRESH_PILOT, (U8)ZwtData); // R_ZWT_TH if ((pstConfig->ucZweitonToneThresoldInPercent) > 100) return DVAUD_kBadParameter; // value out of range if (pstConfig->ucZweitonToneThresoldInPercent == 100) ZwtData = 15; // max value else ZwtData = (pstConfig->ucZweitonToneThresoldInPercent)*4/25; // <-> /6.25 DVAUD_I2cWriteField(F_THRESH_TONE, (U8)ZwtData); // R_ZWT_TH if ((pstConfig->eZweitonErrorProbability) >= DVAUD_kNbOfZweitonErrorProbability) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_TSCTRL, pstConfig->eZweitonErrorProbability); // R_ZWT_CTRL DVAUD_I2cWriteReg(R_STEREO_LEVEL_H, pstConfig->ucBTSCStereoHighTh); DVAUD_I2cWriteReg(R_STEREO_LEVEL_L, pstConfig->ucBTSCStereoLowTh); DVAUD_I2cWriteReg(R_SAP_LEVEL_H, pstConfig->ucBTSCSAPHighTh); DVAUD_I2cWriteReg(R_SAP_LEVEL_L, pstConfig->ucBTSCSAPLowTh); DVAUD_I2cWriteReg(R_SAP_SQ_TH, pstConfig->ucBTSCSAPSquelchTh); return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_AutostandardSetConfig ( const DVAUD_AutostandardConfig_t* const pstConfig) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (pstConfig->eAutoMute) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_AUTO_MUTE); // R_AUTOSTD_CONF break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_AUTO_MUTE); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstConfig->eNICAMBackupForce) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_NICAM_BACKUP_FORCE); // R_AUTOSTD_CONF break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_NICAM_BACKUP_FORCE); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstConfig->eNICAMMonoIn) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_NICAM_MONO_IN); // R_AUTOSTD_CONF break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_NICAM_MONO_IN); break; default: // parameter not in list return DVAUD_kBadParameter; } if ((pstConfig->eFMTime) >= DVAUD_kNbOfFMTime) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_FM_TIME, pstConfig->eFMTime); // R_AUTOSTD_TIMES if ((pstConfig->eNICAMTime) >= DVAUD_kNbOfNICAMTime) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_NICAM_TIME, pstConfig->eNICAMTime); // R_AUTOSTD_TIMES if ((pstConfig->eZweitonTime) >= DVAUD_kNbOfZweitonTime) return DVAUD_kBadParameter; // value out of range DVAUD_I2cWriteField(F_ZWEITON_TIME, pstConfig->eZweitonTime); // R_AUTOSTD_TIMES switch (pstConfig->eWideMode) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_FM_WIDE_ENABLE); // R_AUTOSTD_CONF break; case DVAUD_kEnabled: DVAUD_I2cSetBit(F_FM_WIDE_ENABLE); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_AutostandardSetList ( const DVAUD_AutostandardList_t* const pstList) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; switch (pstList->eLLpStandardIsEnabled) { case DVAUD_kFalse: DVAUD_I2cClrBit(F_LDK_SW); // R_AMFM_MONO_STD_DET break; case DVAUD_kTrue: DVAUD_I2cSetBit(F_LDK_SW); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstList->eLDKMono) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_LDK); // R_AMFM_MONO_STD_DET break; case DVAUD_kEnabled: if (Dev_Capability.eDeviceType != DVAUD_k83x7) return DVAUD_kFeatureNotSupported; // only on 83x7 DVAUD_I2cSetBit(F_LDK); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstList->eDK1Zweiton) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_LDK_ZWT1); // R_NICAMZWT_ST_STD_DET break; case DVAUD_kEnabled: if (Dev_Capability.eDeviceType != DVAUD_k83x7) return DVAUD_kFeatureNotSupported; // only on 83x7 DVAUD_I2cSetBit(F_LDK_ZWT1); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstList->eDK2Zweiton) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_LDK_ZWT2); // R_NICAMZWT_ST_STD_DET break; case DVAUD_kEnabled: if (Dev_Capability.eDeviceType != DVAUD_k83x7) return DVAUD_kFeatureNotSupported; // only on 83x7 DVAUD_I2cSetBit(F_LDK_ZWT2); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstList->eDK3Zweiton) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_LDK_ZWT3); // R_NICAMZWT_ST_STD_DET break; case DVAUD_kEnabled: if (Dev_Capability.eDeviceType != DVAUD_k83x7) return DVAUD_kFeatureNotSupported; // only on 83x7 DVAUD_I2cSetBit(F_LDK_ZWT3); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstList->eLDKNICAM) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_LDK_NICAM); // R_NICAMZWT_ST_STD_DET break; case DVAUD_kEnabled: if (Dev_Capability.eNICAM != DVAUD_kImplemented) return DVAUD_kFeatureNotSupported; else DVAUD_I2cSetBit(F_LDK_NICAM); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstList->eIMono) { case DVAUD_kFalse: DVAUD_I2cClrBit(F_I); // R_AMFM_MONO_STD_DET break; case DVAUD_kTrue: if (Dev_Capability.eDeviceType != DVAUD_k83x7) return DVAUD_kFeatureNotSupported; // only on 83x7 DVAUD_I2cSetBit(F_I); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstList->eINICAM) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_I_NICAM); // R_NICAMZWT_ST_STD_DET break; case DVAUD_kEnabled: if (Dev_Capability.eNICAM != DVAUD_kImplemented) return DVAUD_kFeatureNotSupported; DVAUD_I2cSetBit(F_I_NICAM); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstList->eBGMono) { case DVAUD_kFalse: DVAUD_I2cClrBit(F_BG); // R_AMFM_MONO_STD_DET break; case DVAUD_kTrue: if (Dev_Capability.eDeviceType != DVAUD_k83x7) return DVAUD_kFeatureNotSupported; // only on 83x7 DVAUD_I2cSetBit(F_BG); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstList->eBGZweiton) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_BG_ZWT); // R_NICAMZWT_ST_STD_DET break; case DVAUD_kEnabled: if (Dev_Capability.eDeviceType != DVAUD_k83x7) return DVAUD_kFeatureNotSupported; // only on 83x7 DVAUD_I2cSetBit(F_BG_ZWT); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstList->eBGNICAM) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_BG_NICAM); // R_NICAMZWT_ST_STD_DET break; case DVAUD_kEnabled: if (Dev_Capability.eNICAM != DVAUD_kImplemented) return DVAUD_kFeatureNotSupported; else DVAUD_I2cSetBit(F_BG_NICAM); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstList->eMNMono) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_MN); // R_AMFM_MONO_STD_DET break; case DVAUD_kEnabled: if (Dev_Capability.eDeviceType != DVAUD_k83x7) return DVAUD_kFeatureNotSupported; // only on 83x7 DVAUD_I2cSetBit(F_MN); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstList->eMNZweiton) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_MN_ZWT); // R_NICAMZWT_ST_STD_DET break; case DVAUD_kEnabled: if (Dev_Capability.eDeviceType != DVAUD_k83x7) return DVAUD_kFeatureNotSupported; // only on 83x7 DVAUD_I2cSetBit(F_MN_ZWT); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstList->eMNBTSCMono) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_BTSC_MONO); // R_BTSCEIAJ_STD_DET break; case DVAUD_kEnabled: if (Dev_Capability.eDeviceType != DVAUD_k83x8) return DVAUD_kFeatureNotSupported; // only on 83x8 DVAUD_I2cSetBit(F_BTSC_MONO); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstList->eMNBTSCStereo) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_BTSC_STEREO); // R_BTSCEIAJ_STD_DET break; case DVAUD_kEnabled: if (Dev_Capability.eDeviceType != DVAUD_k83x8) return DVAUD_kFeatureNotSupported; // only on 83x8 DVAUD_I2cSetBit(F_BTSC_STEREO); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstList->eMNBTSCSAP) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_BTSC_SAP); // R_BTSCEIAJ_STD_DET break; case DVAUD_kEnabled: if (Dev_Capability.eDeviceType != DVAUD_k83x8) return DVAUD_kFeatureNotSupported; // only on 83x8 DVAUD_I2cSetBit(F_BTSC_SAP); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstList->eMNEIAJMono) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_EIAJ_MONO); // R_BTSCEIAJ_STD_DET break; case DVAUD_kEnabled: if (Dev_Capability.eEIAJ != DVAUD_kImplemented) return DVAUD_kFeatureNotSupported; else DVAUD_I2cSetBit(F_EIAJ_MONO); break; default: // parameter not in list return DVAUD_kBadParameter; } switch (pstList->eMNEIAJStereo) { case DVAUD_kDisabled: DVAUD_I2cClrBit(F_EIAJ_STEREO); // R_BTSCEIAJ_STD_DET break; case DVAUD_kEnabled: if (Dev_Capability.eEIAJ != DVAUD_kImplemented) return DVAUD_kFeatureNotSupported; else DVAUD_I2cSetBit(F_EIAJ_STEREO); break; default: // parameter not in list return DVAUD_kBadParameter; } return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_AutostandardGet ( DVAUD_Bool_t* const peMonoSquelchIsOK, DVAUD_Bool_t* const peMonoIsAvailable, DVAUD_Bool_t* const peStereoDualIsAvailable, DVAUD_Bool_t* const peSAPIsAvailable, DVAUD_StandardDetected_t* const pstCurrentStandard, DVAUD_StandardTypeDetected_t* const pstCurrentStandardType) { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; // R_DEMOD_STAT *peMonoSquelchIsOK = (DVAUD_I2cReadField(F_FM1_SQ_MONO)) ? DVAUD_kTrue : DVAUD_kFalse; // R_STAT_AUTOSTD *peMonoIsAvailable = (DVAUD_I2cReadField(F_MONO_DET)) ? DVAUD_kTrue : DVAUD_kFalse; *peStereoDualIsAvailable = (DVAUD_I2cReadField(F_STEREO_DUAL_DET)) ? DVAUD_kTrue : DVAUD_kFalse; *peSAPIsAvailable = (DVAUD_I2cReadField(F_BTSC_SAP_DET)) ? DVAUD_kTrue : DVAUD_kFalse; // spread over 2 fields *pstCurrentStandard = (DVAUD_StandardDetected_t) (DVAUD_I2cReadReg(R_STAT_AUTOSTD) & 0x1F); *pstCurrentStandardType = (DVAUD_StandardTypeDetected_t) DVAUD_I2cReadField(F_CURRENT_STANDARD); // R_STAT_STD_HP_I2S_IN return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_DeviceCapabilityGet ( DVAUD_DeviceCapability_t* const pstDeviceCapability) { // chip not yet initialized: don't check Dev_ID! // if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby // return DVAUD_kDeviceNotReady; Dev_ID = (DVAUD_DeviceType_t) DVAUD_I2cReadField(F_CHIP_VERSION); // R_CUT_ID pstDeviceCapability->eDeviceType = Dev_ID; switch (Dev_ID) { case DVAUD_k83x8: // do something specific to 83x8 here printf("DEVICE 83x8\n"); break; case DVAUD_k83x7: printf("DEVICE 83x7\n"); // do something specific to 83x7 here break; default: Dev_ID = DVAUD_kUnknown; pstDeviceCapability->eDeviceType = DVAUD_kUnknown; return DVAUD_kDeviceNotReady; } // R_STAT_ONCHIP_ALGOS // 10xxxxxx or 11xxxxxx OK pstDeviceCapability->eSRSTruSurroundXT = (DVAUD_I2cReadField(F_SRS) & 0x02) ? DVAUD_kImplemented : DVAUD_kNotImplemented; // 01xxxxxx OK pstDeviceCapability->eSRSWOW = (DVAUD_I2cReadField(F_SRS) == 0x01) ? DVAUD_kImplemented : DVAUD_kNotImplemented; // xx10xxxx or xx11xxxx OK pstDeviceCapability->ePrologicII = (DVAUD_I2cReadField(F_DOLBY) & 0x02) ? DVAUD_kImplemented : DVAUD_kNotImplemented; // xx01xxxx OK pstDeviceCapability->ePrologicI = (DVAUD_I2cReadField(F_DOLBY) == 0x01) ? DVAUD_kImplemented : DVAUD_kNotImplemented; pstDeviceCapability->eEIAJ = (DVAUD_I2cReadField(F_EIAJ)) ? DVAUD_kImplemented : DVAUD_kNotImplemented; pstDeviceCapability->eNICAM = (DVAUD_I2cReadField(F_NICAM)) ? DVAUD_kImplemented : DVAUD_kNotImplemented; pstDeviceCapability->eMultichannelOut = (DVAUD_I2cReadField(F_MULTICHANNEL_OUT)) ? DVAUD_kImplemented : DVAUD_kNotImplemented; pstDeviceCapability->eMultiI2SIn = (DVAUD_I2cReadField(F_MULTI_I2S_IN)) ? DVAUD_kImplemented : DVAUD_kNotImplemented; return I2C_Status; } // ****************************************************************** #define MAX_NB_OF_PATCH_RETRIES 3 static const U8 PatchConversion[15] = // 0..E, F = no access { 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x00, 0x75, 0x80 }; #if 0 static DVAUD_Status_t DVAUD_LoadPatch(U8 ChipID) { U32 uiPatchSize, uiCount = 0; U8 PatchVersion = 0; #if 0 DHL_SYS_SetGPIO(11,0); WAIT_Inms(1); DHL_SYS_SetGPIO(11,1); WAIT_Inms(1); #endif switch(ChipID) { #ifdef INCLUDE_83x7 case DVAUD_k83x7: for( uiPatchSize = 0; uiPatchSize < ( sizeof(ttucPatchV18h1) / 2 ); uiPatchSize++ ) { I2C_Write( I2cAddr83xy, ttucPatchV18h1[uiCount][0], ttucPatchV18h1[uiCount][1] ); uiCount += 1; } PatchVersion = PATCH_VERSION_83x7; return DVAUD_kNoError; break; #endif #ifdef INCLUDE_83x8 case DVAUD_k83x8: for( uiPatchSize = 0; uiPatchSize < ( sizeof(ttucPatchV18h1) / 2 ); uiPatchSize++ ) { I2C_Write( I2cAddr83xy, ttucPatchV18h1[uiCount][0], ttucPatchV18h1[uiCount][1] ); uiCount += 1; } PatchVersion = PATCH_VERSION_83x8; return DVAUD_kNoError; break; #endif default: return DVAUD_kUnknownError; } #if 0 if (DVAUD_I2cReadField(F_PATCH_FLAG) && // R_STATUS correct patch load (DVAUD_I2cReadField(F_PATCH_VERSION) == PatchVersion)) // R_STAT_PATCH_VERSION same patch version return DVAUD_kNoError; // OK no error during patch load #endif // load patch again until max # of reloads is reached return DVAUD_kUnknownError; // if patch could not be loaded } #else static DVAUD_Status_t DVAUD_LoadPatch(U8 ChipID) { U8 Retries; U16 PatchIndex; const U8 * Patch; U8 PatchReg = 0; U8 PatchRegSave = 0; U8 PatchVal = 0; U8 PatchVersion = 0; U8 PrevPatchReg = 0; U8 FirstTime = 0; U8 HalfPointer = 0; for (Retries = 0; Retries < MAX_NB_OF_PATCH_RETRIES; Retries++) { switch(ChipID) { #ifdef INCLUDE_83x7 case DVAUD_k83x7: Patch = &ttucPatch83x7V03h[0][0]; // point to beginning of 83x7 patch array PatchVersion = PATCH_VERSION_83x7; PatchIndex = kPatch83x7V03hSize; break; #endif #ifdef INCLUDE_83x8 case DVAUD_k83x8: Patch = &ttucPatch83x8V0Ah[0][0]; // point to beginning of 83x8 patch array PatchVersion = PATCH_VERSION_83x8; PatchIndex = kPatch83x8V0AhSize; break; #endif default: printf("|%s| LINE = %d\n",__FUNCTION__,__LINE__); return DVAUD_kUnknownError; } if (PatchIndex == 0){ // null size patch printf("|%s| LINE = %d\n",__FUNCTION__,__LINE__); return DVAUD_kBadParameter; } FirstTime = 1; // for smart patch loading HalfPointer = 0; // first data = MSB address nibble while (PatchIndex) // scan the whole list { if (!HalfPointer) // MSB address nibble to load { HalfPointer = 1; // next = LSB address nibble PatchRegSave = *Patch++; PatchReg = PatchRegSave >> 4; } else // LSB address nibble to load { HalfPointer = 0; // next = next MSB address nibble PatchReg = PatchRegSave & 0x0F; PatchIndex--; // next entry } PatchVal = *Patch++; // read data associated to current register address if (PatchReg >= 0x0F) continue; // 0x0F: skip data PatchReg = PatchConversion[PatchReg]; // 0x00..0x0E: convert from chart if (FirstTime) // very first loop { FirstTime = 0; PrevPatchReg = PatchReg; I2C_WriteAddrIndex(I2cAddr83xy, PatchReg); // send start + I2C addr + reg addr // I2C_Write(I2cAddr83xy,PatchReg,PatchVal); // send data } if (PatchReg != PrevPatchReg) // if new register address != old one + 1 (not consecutive addrs) { PrevPatchReg = PatchReg; // store new value I2C_Stop(); // stop bit I2C_WriteAddrIndex(I2cAddr83xy, PatchReg); // send start + I2C addr + reg addr } I2C_WriteData(PatchVal); PrevPatchReg++; // for successive register address comparison } I2C_Stop(); if (DVAUD_I2cReadField(F_PATCH_FLAG) && // R_STATUS correct patch load (DVAUD_I2cReadField(F_PATCH_VERSION) == PatchVersion)) // R_STAT_PATCH_VERSION same patch version return DVAUD_kNoError; // OK no error during patch load } // load patch again until max # of reloads is reached return DVAUD_kUnknownError; // if patch could not be loaded } #endif // ****************************************************************** DVAUD_Status_t DVAUD_DeviceStart(void) { U8 WaitLoop; U8 FW_Version; U8 test = 0; // **** // **** USER ACTION // **** // // hardware reset pin low // *** do it here *** // DHL_SYS_SetGPIO( 11, 0 ); // delay 100us or more WAIT_Inms(1); // hardware reset pin high // *** do it here *** // DHL_SYS_SetGPIO( 11, 1 ); // delay 2ms WAIT_Inms(2); // check if IC is here and responds to requests if (DVAUD_DeviceCapabilityGet(&Dev_Capability) != DVAUD_kNoError){ printf("|%s| LINE = %d\n",__FUNCTION__,__LINE__); return DVAUD_kUnknownError; } // load DSP F/W patch if(!test){ if (DVAUD_LoadPatch(Dev_Capability.eDeviceType) != DVAUD_kNoError){ // exit in error if any problem occured during patch load printf("|%s| LINE = %d\n",__FUNCTION__,__LINE__); return DVAUD_kUnknownError; } } // start DSP H/W DVAUD_I2cSetBit(F_DSP_HW_RUN); // R_DSP_HW_CONF // wait until DSP ready WaitLoop = 10; while(WaitLoop) { // delay 1ms WAIT_Inms(1); if (DVAUD_I2cReadField(F_DSP_FW_READY)) // STAT_DSP_INIT if DSP ready break; // exit loop WaitLoop--; } if (!WaitLoop){ // end of loop, DSP never ready printf("|%s| LINE = %d\n",__FUNCTION__,__LINE__); return DVAUD_kUnknownError; } // check F/W version if (DVAUD_I2cReadField(F_FW_VERSION) != 0xFF){ // STAT_FW_VERSION printf("|%s| LINE = %d\n",__FUNCTION__,__LINE__); return DVAUD_kUnknownError; } // run DSP DVAUD_I2cWriteReg(R_DSP_FW_CONF, 0x01); // delay 2ms WAIT_Inms(2); // get capability again to have the accurate registers values now that DSP is running if (DVAUD_DeviceCapabilityGet(&Dev_Capability) != DVAUD_kNoError){ printf("|%s| LINE = %d\n",__FUNCTION__,__LINE__); return DVAUD_kUnknownError; } // check STAT F/W version number (in IC ROM) specific to IC type // this is a data from design, specific to IC type switch (Dev_Capability.eDeviceType) { #ifdef INCLUDE_83x7 case DVAUD_k83x7: FW_Version = 0x15; break; #endif #ifdef INCLUDE_83x8 case DVAUD_k83x8: FW_Version = 0x2F; break; #endif default: // should never occur... FW_Version = 0x00; break; } if (DVAUD_I2cReadField(F_FW_VERSION) != FW_Version){ // STAT_FW_VERSION printf("|%s| LINE = %d\n",__FUNCTION__,__LINE__); return DVAUD_kUnknownError; } return DVAUD_kNoError; // everything OK } // ****************************************************************** DVAUD_Status_t DVAUD_LowPowerEnter () { if (Dev_ID==DVAUD_kUnknown || Dev_ID==DVAUD_kDeviceNotReady) // chip not initialized or in standby return DVAUD_kDeviceNotReady; // mute all outputs except SCART OUT (SCART path is kept) I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputSpeaker, DVAUD_kEnabled); if (I2C_Status != DVAUD_kNoError) return I2C_Status; I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputCenter, DVAUD_kEnabled); if (I2C_Status != DVAUD_kNoError) return I2C_Status; I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputSubwoofer, DVAUD_kEnabled); if (I2C_Status != DVAUD_kNoError) return I2C_Status; I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputSurround, DVAUD_kEnabled); if (I2C_Status != DVAUD_kNoError) return I2C_Status; I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputHeadphone, DVAUD_kEnabled); if (I2C_Status != DVAUD_kNoError) return I2C_Status; // delay 25ms WAIT_Inms(25); // enable SCART IN standby DVAUD_I2cSetBit(F_EN_STBY); // R_RESET if (I2C_Status != DVAUD_kNoError) return I2C_Status; // device in low power mode: no response from routines Dev_ID = (DVAUD_DeviceType_t) DVAUD_kDeviceNotReady; // **** // **** USER ACTION // all unneeded power supplies can now be switched off // **** // **** return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_LowPowerExit(void) { if (Dev_ID==DVAUD_kUnknown) // chip not initialized return DVAUD_kDeviceNotReady; // same sequence as LowPowerEnter() but in reverse order // **** // **** USER ACTION // all power supplies MUST now be switched on // **** // **** // delay 25ms WAIT_Inms(25); // re-check if IC is here and responds to requests if (DVAUD_DeviceCapabilityGet(&Dev_Capability) != DVAUD_kNoError) return DVAUD_kUnknownError; // disable SCART IN standby DVAUD_I2cClrBit(F_EN_STBY); // R_RESET if (I2C_Status != DVAUD_kNoError) return I2C_Status; // delay 25ms WAIT_Inms(25); // un-mute all outputs except SCART OUT I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputSpeaker, DVAUD_kDisabled); if (I2C_Status != DVAUD_kNoError) return I2C_Status; I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputCenter, DVAUD_kDisabled); if (I2C_Status != DVAUD_kNoError) return I2C_Status; I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputSubwoofer, DVAUD_kDisabled); if (I2C_Status != DVAUD_kNoError) return I2C_Status; I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputSurround, DVAUD_kDisabled); if (I2C_Status != DVAUD_kNoError) return I2C_Status; I2C_Status = DVAUD_DACMuteSet(DVAUD_kOutputHeadphone, DVAUD_kDisabled); return I2C_Status; } // ****************************************************************** DVAUD_Status_t DVAUD_DeviceI2CAddressSet ( const U8 ucChipAddr) { if ((ucChipAddr == 0x80) || (ucChipAddr == 0x84)) { I2cAddr83xy = ucChipAddr; // & 0xFE return DVAUD_kNoError; } else return DVAUD_kBadParameter; } // ****************************************************************** // // ****************************************************************** // ****************************************************************** // ****************************************************************** // ****************************************************************** // // I2C ROUTINES // // ****************************************************************** // ****************************************************************** // ****************************************************************** // ****************************************************************** // // FIELD LENGTH const unsigned char Field_Length[NBREG][8] = { {1,3,4,0,0,0,0,0}, /*Reg 0x00*/ {1,1,1,1,1,1,1,1}, {1,1,1,1,1,3,0,0}, {8,0,0,0,0,0,0,0}, {1,1,1,2,1,2,0,0}, {1,1,1,1,1,1,1,1}, {8,0,0,0,0,0,0,0}, {1,1,4,1,1,0,0,0}, {1,1,2,1,3,0,0,0}, {1,1,1,5,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {1,1,1,1,1,3,0,0}, {1,1,1,1,1,1,1,1}, {1,1,1,3,2,0,0,0}, {1,5,1,1,0,0,0,0}, {8,0,0,0,0,0,0,0}, /*Reg 0x10*/ {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, /*Reg 0x20*/ {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {1,3,1,1,2,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {1,1,1,1,1,3,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, /*Reg 0x30*/ {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {1,1,1,1,1,3,0,0}, {2,2,1,1,2,0,0,0}, {1,1,1,1,1,3,0,0}, {8,0,0,0,0,0,0,0}, {1,1,1,4,1,0,0,0}, {1,1,1,3,2,0,0,0}, /*Reg 0x40*/ {4,4,0,0,0,0,0,0}, {1,1,1,1,1,1,1,1}, {4,2,1,1,0,0,0,0}, {1,1,1,1,3,1,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {1,1,1,1,1,1,1,1}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {1,1,3,1,1,1,0,0}, {1,1,1,1,1,1,1,1}, {8,0,0,0,0,0,0,0}, {1,1,1,1,4,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, /*Reg 0x50*/ {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {1,3,1,3,0,0,0,0}, {1,3,1,3,0,0,0,0}, {1,1,1,1,1,3,0,0}, {4,1,3,0,0,0,0,0}, {1,3,1,3,0,0,0,0}, {1,3,1,3,0,0,0,0}, {1,3,1,3,0,0,0,0}, {1,3,1,3,0,0,0,0}, {1,1,1,5,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {2,2,3,1,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, /*Reg 0x60*/ {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, /*Reg 0x70*/ {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {1,1,1,1,1,1,1,1}, /*Reg 0x80*/ {1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {2,2,1,1,1,1,0,0}, {1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1}, {1,1,1,5,0,0,0,0}, {1,1,1,5,0,0,0,0}, {1,1,2,1,1,2,0,0}, {1,1,1,1,1,1,1,1}, {1,1,2,1,1,1,1,0}, {1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1}, /*Reg 0x90*/ {3,3,2,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {1,1,1,1,1,1,2,0}, {1,1,1,1,1,3,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {1,1,1,1,1,1,1,1}, {1,1,1,1,2,1,1,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {1,2,1,2,2,0,0,0}, {8,0,0,0,0,0,0,0}, {1,1,1,1,1,2,1,0}, {1,7,0,0,0,0,0,0}, {1,7,0,0,0,0,0,0}, {1,7,0,0,0,0,0,0}, /*Reg 0xA0*/ {1,7,0,0,0,0,0,0}, {1,7,0,0,0,0,0,0}, {1,7,0,0,0,0,0,0}, {1,7,0,0,0,0,0,0}, {1,7,0,0,0,0,0,0}, {1,7,0,0,0,0,0,0}, {1,7,0,0,0,0,0,0}, {1,7,0,0,0,0,0,0}, {1,3,3,1,0,0,0,0}, {3,3,1,1,0,0,0,0}, {1,1,1,1,4,0,0,0}, {4,4,0,0,0,0,0,0}, {4,4,0,0,0,0,0,0}, {4,4,0,0,0,0,0,0}, {4,4,0,0,0,0,0,0}, {1,1,1,1,1,3,0,0}, /*Reg 0xB0*/ {1,1,1,2,3,0,0,0}, {1,2,2,3,0,0,0,0}, {1,2,2,3,0,0,0,0}, {3,2,3,0,0,0,0,0}, {1,1,1,1,1,1,1,1}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {1,3,3,1,0,0,0,0}, {1,1,1,2,1,1,1,0}, {1,1,3,3,0,0,0,0}, {8,0,0,0,0,0,0,0}, {1,1,1,1,1,1,1,1}, {1,2,5,0,0,0,0,0}, {4,1,1,1,1,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, /*Reg 0xC0*/ {1,1,1,1,3,1,0,0}, {8,0,0,0,0,0,0,0}, {1,1,1,1,3,1,0,0}, {8,0,0,0,0,0,0,0}, {2,5,1,0,0,0,0,0}, {6,2,0,0,0,0,0,0}, {1,1,2,2,2,0,0,0}, {5,2,1,0,0,0,0,0}, {5,2,1,0,0,0,0,0}, {1,1,3,1,1,1,0,0}, {1,1,1,1,1,2,1,0}, {3,5,0,0,0,0,0,0}, {1,1,6,0,0,0,0,0}, {3,5,0,0,0,0,0,0}, {1,1,6,0,0,0,0,0}, {1,1,1,1,1,1,1,1}, /*Reg 0xD0*/ {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {1,3,3,1,0,0,0,0}, {1,3,3,1,0,0,0,0}, {1,1,1,1,1,2,1,0}, {1,2,5,0,0,0,0,0}, {1,3,4,0,0,0,0,0}, {1,1,3,3,0,0,0,0}, {1,1,1,1,3,1,0,0}, {1,1,1,1,1,3,0,0}, {2,2,2,2,0,0,0,0}, /*Reg 0xE0*/ {1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1}, {8,0,0,0,0,0,0,0}, {1,1,1,1,1,1,2,0}, {8,0,0,0,0,0,0,0}, {1,1,1,1,1,1,2,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {1,1,1,1,1,1,2,0}, {8,0,0,0,0,0,0,0}, {1,1,1,1,1,1,2,0}, {8,0,0,0,0,0,0,0}, /*Reg 0xF0*/ {8,0,0,0,0,0,0,0}, {1,1,6,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {1,1,1,5,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {1,1,1,1,1,1,1,1}, {1,1,1,5,0,0,0,0}, {8,0,0,0,0,0,0,0}, {8,0,0,0,0,0,0,0}, {3,1,1,3,0,0,0,0}, {1,1,1,1,4,0,0,0}, {1,7,0,0,0,0,0,0}, {1,7,0,0,0,0,0,0}, {1,7,0,0,0,0,0,0} /*Reg 0xff*/ }; // Data to write in field at register [RegIndex] = (Data & Mask) << Shift; static U16 RegIndex; // I2C register address static U8 Mask; // Mask for data static U8 Shift; // nb of left shifts to reach field pos in register DVAUD_Status_t ComputeRegMaskShift(U16 Field) { unsigned char pos; unsigned char index; unsigned char length; Mask = 0; for (RegIndex = 0; RegIndex < NBREG; RegIndex++) { pos = 0; index = 0; while (pos < 8) { length = Field_Length[RegIndex][index]; // field lenght in register at (7-pos) if (length==0) // null length: end of register break; // go to next one in list if (Field == 0) // found field { // example: 1,3,4,0,0,0,0 // 1st field: pos=0, length=1 gives Shift=7 and Mask=0x01(<<7=0x80) 1xxxxxxx // 2nd field: pos=1, length=3 gives Shift=4 and Mask=0x07(<<4=0x70) x111xxxx // 3rd field: pos=4, length=4 gives Shift=0 and Mask=0x0F(<<0=0x0F) xxxx1111 Shift = 8-pos-length; // compute nb of shifts to reach field from LSB while (length) // compute mask to AND data with { Mask<<=1; Mask+=1; length--; } return DVAUD_kNoError; // everything OK } index++; // next pos in array pos += length; // next field pos in register Field--; // go to next field in list } } return DVAUD_kBadParameter; // could not find field } //static void DVAUD_I2cClrBit(U8 Reg, U8 Bit) // Reg = register subaddress, Bit = bit # (0..7) static void DVAUD_I2cClrBit(U16 Field) // Field = field name in enum Field_List { // !! if Field is not a single bit, only the rightmost bit of the field will be written DVAUD_I2cWriteField(Field, 0); } //static void DVAUD_I2cSetBit(U8 Reg, U8 Bit) // Reg = register subaddress, Bit = bit # (0..7) static void DVAUD_I2cSetBit(U16 Field) // Field = field name in enum Field_List { // !! if Field is not a single bit, only the rightmost bit of the field will be written DVAUD_I2cWriteField(Field, 1); } static void DVAUD_I2cWriteReg(U8 Reg, U8 RegValue) // Reg = register subaddress, RegValue = 0..255 { if (I2C_Write(I2cAddr83xy, Reg, RegValue)) // low level H/W I2C access I2C_Status = DVAUD_kI2CProblem; else I2C_Status = DVAUD_kNoError; } //static void DVAUD_I2cWriteField(U8 Reg, U8 Field, U8 Value) // Reg = register subaddress, Field = bits to write, Value = 0..255 static void DVAUD_I2cWriteField(U16 Field, U8 Value) // Field = field name in enum Field_List, Value = 0..255 { U8 RegValue; I2C_Status = ComputeRegMaskShift(Field); // compute register address, mask and n# of left shifts if (I2C_Status != DVAUD_kNoError) // if bad register return; // quit in error Value &= Mask; // mask bits in data to write Value <<= Shift; // prepare data at proper position in register Mask <<= Shift; // shift mask to mask existing data in register RegValue = I2C_Read(I2cAddr83xy, RegIndex); // low level H/W I2C access RegValue &= ~Mask; // mask bits outside field RegValue |= Value; // fill bit(s) in if (I2C_Write(I2cAddr83xy, RegIndex, RegValue)) // low level H/W I2C access I2C_Status = DVAUD_kI2CProblem; else I2C_Status = DVAUD_kNoError; } static U8 DVAUD_I2cReadReg(U8 Reg) // Reg = register subaddress { return(I2C_Read(I2cAddr83xy, Reg)); // low level H/W I2C access } //static void DVAUD_I2cWriteField(U8 Reg, U8 Field, U8 Value) // Reg = register subaddress, Field = bits to write, Value = 0..255 static U8 DVAUD_I2cReadField(U16 Field) // Field = field name in enum Field_List, Value = 0..255 { U8 RegValue = 0; I2C_Status = ComputeRegMaskShift(Field); // compute register address, mask and n# of left shifts if (I2C_Status == DVAUD_kNoError) // if good register { RegValue = I2C_Read(I2cAddr83xy, RegIndex); // low level H/W I2C access RegValue >>= Shift; // shift data back from position in register RegValue &= Mask; // mask bits in data just read } return RegValue; } // added by bg.noh U8 DVAUD_I2cWriteReg_Mask(U8 RegIndex, U8 Data, U8 Mask) { U8 ucRegValue; U8 ucResult = 0; ucRegValue = I2C_Read( I2cAddr83xy, RegIndex ); ucRegValue &= ~Mask; ucRegValue |= Data; ucResult |= I2C_Write( I2cAddr83xy, RegIndex, ucRegValue ); return ( ucResult ); }