/******************************************************************************* * Function Name : CODEC_ControlVolume * Description : Controls the audio volume. * Input : - Volume: the volume level to be set. * Output : None * Return : 0-> correct communication, else wrong communication *******************************************************************************/ uint32_t CODEC_ControlVolume(uint8_t Volume) { uint32_t counter = 0; /* Max = 0xFF --> 0x18, Mean = 0x7F --> 0x00 Min = 0x00 --> 0x19 */ if (Volume > 0xE6) { /* Set the Master volume */ counter += CODEC_WriteRegister(0x20, Volume - 0xE7); counter += CODEC_WriteRegister(0x21, Volume - 0xE7); } else { /* Set the Master volume */ counter += CODEC_WriteRegister(0x20, Volume + 0x19); counter += CODEC_WriteRegister(0x21, Volume + 0x19); } return counter; }
/******************************************************************************* * Function Name : CODEC_PowerDown * Description : Power down the Audio Codec. * Input : - CodecPowerDown_Mode: could be CodecPowerDown_SW for software * power down (by register writing), CodecPowerDown_HW just shut * down the codec physically. * Output : None * Return : None *******************************************************************************/ void CODEC_PowerDown(uint32_t CodecPowerDown_Mode) { #if 0 if (CodecPowerDown_Mode == CodecPowerDown_SW) { /* Power down the DAC and the speaker (PMDAC and PMSPK bits)*/ CODEC_WriteRegister(0x02, 0x9F); } else /* CodecPowerDown_HW */ { /* Mute the output first */ CODEC_WriteRegister(0x1A, 0x80); CODEC_WriteRegister(0x1B, 0x80); /* Power down the DAC components */ CODEC_WriteRegister(0x02, 0x9F); /* Wait at least 100µs */ Delay(1); /* Reset The pin */ //IOE_WriteIOPin(AUDIO_RESET_PIN, BitReset); } #endif }
/******************************************************************************* * Function Name : CODEC_Mute * Description : Enable or disable the MUTE mode by software * Input : - Command: could be MUTE_ON to mute sound or MUTE_OFF to restore volume * Output : None. * Return : None. *******************************************************************************/ void CODEC_Mute(uint32_t Command) { /* Set the Mute mode */ if (Command == MUTE_ON) { CODEC_WriteRegister(0x0D, 0x63); CODEC_WriteRegister(0x0F, 0xF8); } else /* MUTE_OFF Disable the Mute */ { CODEC_WriteRegister(0x0D, 0x60); CODEC_WriteRegister(0x0F, 0x08); } }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void AppleTopazPluginCS8420::setRunMode ( UInt8 mode ) { CODEC_WriteRegister ( map_CS8420_CLOCK_SOURCE_CTRL, mode ); if ( ( mode & ( 1 << baCS8420_RUN ) ) == ( 1 << baCS8420_RUN ) ) { // [3669626] setChannelStatus ( &mChanStatusStruct ); // [3669626] Flush channel status buffer } }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UInt8 AppleTopazPluginCS8420::setStopMode ( void ) { UInt8 data; // Stop the device during recovery while preserving the original run state data = mShadowRegs[map_CS8420_CLOCK_SOURCE_CTRL]; CODEC_WriteRegister ( map_CS8420_CLOCK_SOURCE_CTRL, data & ~( 1 << baCS8420_RUN ) ); return data; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void AppleTopazPluginCS8420::useInternalCLK ( void ) { // If the recovered clock is derived from an external source and there is no external source // then switch the recovered clock to derive from the I2S I/O Module LRCLK. mShadowRegs[map_CS8420_CLOCK_SOURCE_CTRL] &= ~( kCS84XX_TWO_BIT_MASK << baCS8420_RXD ); mShadowRegs[map_CS8420_CLOCK_SOURCE_CTRL] |= ( bvCS8420_rxd256fsiILRCLK << baCS8420_RXD ); CODEC_WriteRegister( map_CS8420_CLOCK_SOURCE_CTRL, mShadowRegs[map_CS8420_CLOCK_SOURCE_CTRL] ); return; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IOReturn AppleTopazPluginCS8420::performDeviceSleep ( void ) { IOReturn result; debugIOLog (3, "+ AppleTopazPluginCS8420::performDeviceSleep()"); mShadowRegs[map_CS8420_DATA_FLOW_CTRL] &= ~( kCS84XX_BIT_MASK << baCS8420_TXOFF ); mShadowRegs[map_CS8420_DATA_FLOW_CTRL] |= ( bvCS8420_aes3TX0v << baCS8420_TXOFF ); result = CODEC_WriteRegister ( map_CS8420_DATA_FLOW_CTRL, mShadowRegs[map_CS8420_DATA_FLOW_CTRL] ); FailIf ( kIOReturnSuccess != result, Exit ); mShadowRegs[map_CS8420_CLOCK_SOURCE_CTRL] &= ~( kCS84XX_BIT_MASK << baCS8420_RUN ); mShadowRegs[map_CS8420_CLOCK_SOURCE_CTRL] |= ( bvCS8420_runSTOP << baCS8420_RUN ); result = CODEC_WriteRegister ( map_CS8420_CLOCK_SOURCE_CTRL, mShadowRegs[map_CS8420_CLOCK_SOURCE_CTRL] ); FailIf ( kIOReturnSuccess != result, Exit ); Exit: debugIOLog (3, "- AppleTopazPluginCS8420::performDeviceSleep()"); return result; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IOReturn AppleTopazPluginCS8420::flushControlRegisters ( void ) { IOReturn result = kIOReturnSuccess; for ( UInt32 regAddr = map_CS8420_MISC_CNTRL_1; regAddr <= map_CS8420_BUFFER_23; regAddr++ ) { if ( kIOReturnSuccess == CODEC_IsControlRegister ( regAddr ) ) { result = CODEC_WriteRegister ( regAddr, mShadowRegs[regAddr] ); FailIf ( kIOReturnSuccess != result, Exit ); } } Exit: return result; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IOReturn AppleTopazPluginCS8420::performDeviceWake ( void ) { IOReturn result; debugIOLog (3, "+ AppleTopazPluginCS8420::performDeviceWake()" ); flushControlRegisters (); mShadowRegs[map_CS8420_DATA_FLOW_CTRL] &= ~( kCS84XX_BIT_MASK << baCS8420_TXOFF ); mShadowRegs[map_CS8420_DATA_FLOW_CTRL] |= ( bvCS8420_aes3TXNormal << baCS8420_TXOFF ); result = CODEC_WriteRegister ( map_CS8420_DATA_FLOW_CTRL, mShadowRegs[map_CS8420_DATA_FLOW_CTRL] ); FailIf ( kIOReturnSuccess != result, Exit ); mShadowRegs[map_CS8420_CLOCK_SOURCE_CTRL] &= ~( kCS84XX_BIT_MASK << baCS8420_RUN ); mShadowRegs[map_CS8420_CLOCK_SOURCE_CTRL] |= ( bvCS8420_runNORMAL << baCS8420_RUN ); result = CODEC_WriteRegister ( map_CS8420_CLOCK_SOURCE_CTRL, mShadowRegs[map_CS8420_CLOCK_SOURCE_CTRL] ); FailIf ( kIOReturnSuccess != result, Exit ); setChannelStatus ( &mChanStatusStruct ); // [3669626] Flush channel status buffer Exit: debugIOLog (3, "- AppleTopazPluginCS8420::performDeviceWake()" ); return result; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bool AppleTopazPluginCS8420::preDMAEngineInit ( void ) { bool result = false; IOReturn err; // Place device into power down state prior to initialization err = CODEC_WriteRegister ( map_CS8420_CLOCK_SOURCE_CTRL, kCS8420_CLOCK_SOURCE_CTRL_INIT_STOP ); FailIf ( kIOReturnSuccess != err, Exit ); err = CODEC_WriteRegister ( map_CS8420_MISC_CNTRL_1, kCS8420_MISC_CNTRL_1_INIT ); FailIf ( kIOReturnSuccess != err, Exit ); err = CODEC_WriteRegister ( map_CS8420_MISC_CNTRL_2, kCS8420_MISC_CNTRL_2_INIT ); FailIf ( kIOReturnSuccess != err, Exit ); err = CODEC_WriteRegister ( map_CS8420_DATA_FLOW_CTRL, kCS8420_DATA_FLOW_CTRL_INIT ); FailIf ( kIOReturnSuccess != err, Exit ); err = CODEC_WriteRegister ( map_CS8420_SERIAL_INPUT_FMT, kCS8420_SERIAL_AUDIO_INPUT_FORMAT_INIT ); FailIf ( kIOReturnSuccess != err, Exit ); err = CODEC_WriteRegister ( map_CS8420_SERIAL_OUTPUT_FMT, kCS8420_SERIAL_AUDIO_OUTPUT_FORMAT_INIT ); FailIf ( kIOReturnSuccess != err, Exit ); // Enable receiver error (i.e. RERR) interrupts err = CODEC_WriteRegister ( map_CS8420_RX_ERROR_MASK, kCS8420_RX_ERROR_MASK_ENABLE_RERR ); FailIf ( kIOReturnSuccess != err, Exit ); // Clear any pending error interrupt err = CODEC_ReadRegister ( map_CS8420_RX_ERROR, NULL, 1 ); FailIf ( kIOReturnSuccess != err, Exit ); err = CODEC_WriteRegister ( map_CS8420_CLOCK_SOURCE_CTRL, kCS8420_CLOCK_SOURCE_CTRL_INIT ); FailIf ( kIOReturnSuccess != err, Exit ); err = CODEC_WriteRegister ( map_CS8420_USER_DATA_BUF_CTRL, bvCS8420_ubmBlock << baCS8420_UBM ); FailIf ( kIOReturnSuccess != err, Exit ); result = true; Exit: return result; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IOReturn AppleTopazPluginCS8420::setMute ( bool muteState ) { UInt8 data; IOReturn result = kIOReturnError; debugIOLog (3, "+ AppleTopazPluginCS8420::setMute (%d)", muteState); data = kCS8420_MISC_CNTRL_1_INIT; data &= ~( 1 << baCS8420_MuteAES ); data |= muteState ? ( bvCS8420_muteAES3 << baCS8420_MuteAES ) : ( bvCS8420_normalAES3 << baCS8420_MuteAES ) ; result = CODEC_WriteRegister ( map_CS8420_MISC_CNTRL_1, data ); FailIf ( kIOReturnSuccess != result, Exit ); mMuteState = muteState; Exit: debugIOLog (3, "- AppleTopazPluginCS8420::setMute (%d) returns %X", muteState, result); return result; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IOReturn AppleTopazPluginCS8420::setPluginState ( HardwarePluginDescriptorPtr inState ) { IOReturn result = kIOReturnBadArgument; FailIf ( NULL == inState, Exit ); FailIf ( sizeof ( mShadowRegs ) != inState->registerCacheSize, Exit ); result = kIOReturnSuccess; for ( UInt32 registerAddress = map_CS8420_MISC_CNTRL_1; ( registerAddress < map_ID_VERSION ) && ( kIOReturnSuccess == result ); registerAddress++ ) { if ( inState->registerCache[registerAddress] != mShadowRegs[registerAddress] ) { if ( kIOReturnSuccess == CODEC_IsControlRegister ( (UInt8)registerAddress ) ) { result = CODEC_WriteRegister ( registerAddress, inState->registerCache[registerAddress] ); } } } Exit: return result; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IOReturn AppleTopazPluginCS8420::makeClockSelectPreLock ( UInt32 clockSource ) { IOReturn result; UInt8 data; debugIOLog (5, "+ AppleTopazPluginCS8420::makeClockSelect ( %d )", (unsigned int)clockSource ); // Clear any pending error interrupt status and re-enable error interrupts after completing clock source selection result = CODEC_ReadRegister ( map_CS8420_RX_ERROR, &data, 1 ); FailIf ( kIOReturnSuccess != result, Exit ); // Enable error (i.e. RERR) interrupts ONLY IF C28420 IS CLOCK MASTER if ( kTRANSPORT_SLAVE_CLOCK == clockSource ) { result = CODEC_WriteRegister ( map_CS8420_RX_ERROR_MASK, kCS8420_RX_ERROR_MASK_ENABLE_RERR ); FailIf ( kIOReturnSuccess != result, Exit ); } switch ( clockSource ) { case kTRANSPORT_MASTER_CLOCK: data = mShadowRegs[map_CS8420_DATA_FLOW_CTRL]; data &= ~( bvCS8420_spdMASK << baCS8420_SPD ); data |= ( bvCS8420_spdSrcOut << baCS8420_SPD ); result = CODEC_WriteRegister ( map_CS8420_DATA_FLOW_CTRL, data ); data = mShadowRegs[map_CS8420_CLOCK_SOURCE_CTRL]; data &= ~( 1 << baCS8420_OUTC ); data |= ( bvCS8420_outcOmckXbaCLK << baCS8420_OUTC ); result = CODEC_WriteRegister ( map_CS8420_CLOCK_SOURCE_CTRL, data ); break; case kTRANSPORT_SLAVE_CLOCK: data = mShadowRegs[map_CS8420_DATA_FLOW_CTRL]; data &= ~( bvCS8420_spdMASK << baCS8420_SPD ); data |= ( bvCS8420_spdAES3 << baCS8420_SPD ); result = CODEC_WriteRegister ( map_CS8420_DATA_FLOW_CTRL, data ); data = mShadowRegs[map_CS8420_CLOCK_SOURCE_CTRL]; data &= ~( 1 << baCS8420_OUTC ); data |= ( bvCS8420_outcRecIC << baCS8420_OUTC ); result = CODEC_WriteRegister ( map_CS8420_CLOCK_SOURCE_CTRL, data ); break; } // restart the codec after switching clocks data = mShadowRegs[map_CS8420_CLOCK_SOURCE_CTRL]; data &= ~( 1 << baCS8420_RUN ); data |= ( bvCS8420_runNORMAL << baCS8420_RUN ); result = CODEC_WriteRegister ( map_CS8420_CLOCK_SOURCE_CTRL, data ); setChannelStatus ( &mChanStatusStruct ); // [3669626] Flush channel status buffer Exit: debugIOLog (5, "- AppleTopazPluginCS8420::makeClockSelect ( %d ) returns %d", (unsigned int)clockSource, (unsigned int)result ); return result; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IOReturn AppleTopazPluginCS8420::makeClockSelectPostLock ( UInt32 clockSource ) { IOReturn result; UInt8 data; debugIOLog (5, "+ AppleTopazPluginCS8420::makeClockSelectPostLock ( %d )", (unsigned int)clockSource ); // Unmute the coded output data = mShadowRegs[map_CS8420_MISC_CNTRL_1]; data &= ~( kCS84XX_BIT_MASK << baCS8420_MuteAES ); data |= mMuteState ? ( bvCS8420_muteAES3 << baCS8420_MuteAES ) : ( bvCS8420_normalAES3 << baCS8420_MuteAES ) ; result = CODEC_WriteRegister ( map_CS8420_MISC_CNTRL_1, data ); FailIf ( result != kIOReturnSuccess, Exit ); if ( kTRANSPORT_SLAVE_CLOCK == clockSource ) { mLockStatus = TRUE; mUnlockErrorCount = 0; } Exit: debugIOLog (5, "- AppleTopazPluginCS8420::makeClockSelectPostLock ( %d ) returns %d", (unsigned int)clockSource, (unsigned int)result ); return result; }
/******************************************************************************* * Function Name : CODEC_Config * Description : Configure the Codec in Headphone mode. * Input : - OutputDevice: OutputDeviceHEADPHONE or OutputDeviceSPEAKER * : - I2S_Standard: I2S communication standard could be I2S_Standard_Phillips * : I2S_Standard_MSB or I2S_Standard_LSB. * : - I2S_MCLKOutput: could be I2S_MCLKOutput_ * : - Volume: * Output : None * Return : 0-> correct communication, else wrong communication *******************************************************************************/ uint32_t CODEC_Config(uint16_t OutputDevice, uint16_t I2S_Standard, uint16_t I2S_MCLKOutput, uint8_t Volume) { uint32_t Standard = 0, counter = 0; /* Configure the IO Expander (Codec Reset pin) */ IOE_Config(); /* Configure the Codec related IOs */ CODEC_GPIO_Config(); /* Reset the Codec Registers */ CODEC_Reset(); /* Determine the I2S standard used */ switch (I2S_Standard) { case I2S_Standard_Phillips: Standard = 0x04; break; case I2S_Standard_MSB: Standard = 0x00; break; default : Standard = 0x08; break; } /* Initialization phase --------------------------------------*/ /* Keep Codec powered OFF */ counter += CODEC_WriteRegister(0x02, 0x01); switch (OutputDevice) { case OutputDevice_SPEAKER: counter += CODEC_WriteRegister(0x04, 0xFA); // SPK always ON & HP always OFF break; case OutputDevice_HEADPHONE: counter += CODEC_WriteRegister(0x04, 0xAF); // SPK always OFF & HP always ON break; case OutputDevice_BOTH: counter += CODEC_WriteRegister(0x04, 0xAA); // SPK always ON & HP always ON break; case OutputDevice_AUTO: counter += CODEC_WriteRegister(0x04, 0x05);// Detect the HP or the SPK automatically break; } /* Clock configuration: Auto detection */ counter += CODEC_WriteRegister(0x05, 0x81); //Auto speed detection /* Config the Slave Mode and the audio Standard */ counter += CODEC_WriteRegister(0x06, Standard); /* Set the Master volume */ CODEC_ControlVolume(Volume); /* Power on the Codec */ counter += CODEC_WriteRegister(0x02, 0x9E); /* Return the counter value */ return counter; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IOReturn AppleTopazPluginCS8420::setChannelStatus ( ChanStatusStructPtr channelStatus ) { UInt8 data; IOReturn result = kIOReturnError; FailIf ( NULL == channelStatus, Exit ); if ( 0 != channelStatus->sampleRate ) { mChanStatusStruct.sampleRate = channelStatus->sampleRate; // [3669626] } if ( 0 != channelStatus->sampleDepth ) { mChanStatusStruct.sampleDepth = channelStatus->sampleDepth; // [3669626] } mChanStatusStruct.nonAudio = channelStatus->nonAudio; // [3669626] mChanStatusStruct.consumerMode = channelStatus->consumerMode; // [3669626] // Assumes consumer mode data = ( ( kCopyPermited << ( 7 - kBACopyright ) ) | ( kConsumer << ( 7 - kBAProConsumer ) ) ); if ( mChanStatusStruct.nonAudio ) { data |= ( kConsumerMode_nonAudio << ( 7 - kBANonAudio ) ); // consumer mode encoded } else { data |= ( kConsumerMode_audio << ( 7 - kBANonAudio ) ); // consumer mode linear PCM } result = CODEC_WriteRegister ( map_CS8420_BUFFER_0, data ); // [0� consumer/format/copyright/pre-emphasis/ FailIf ( kIOReturnSuccess != result, Exit ); if ( mChanStatusStruct.nonAudio ) { result = CODEC_WriteRegister ( map_CS8420_BUFFER_1, kIEC60958_CategoryCode_DVD ); // [8�] category code is not valid FailIf ( kIOReturnSuccess != result, Exit ); result = CODEC_WriteRegister ( map_CS8420_BUFFER_2, 0 ); // [16�] source & channel are not valid FailIf ( kIOReturnSuccess != result, Exit ); result = CODEC_WriteRegister ( map_CS8420_BUFFER_3, cSampleFrequency_NotIndicated ); // [24�] sample frequency not indicated FailIf ( kIOReturnSuccess != result, Exit ); result = CODEC_WriteRegister ( map_CS8420_BUFFER_4, cWordLength_20Max_16bits ); // [32�] word length & original sample frequency FailIf ( kIOReturnSuccess != result, Exit ); } else { result = CODEC_WriteRegister ( map_CS8420_BUFFER_1, kIEC60958_CategoryCode_CD ); // [8�] category code is CD FailIf ( kIOReturnSuccess != result, Exit ); result = CODEC_WriteRegister ( map_CS8420_BUFFER_2, 0 ); // [16�] source & channel are not specified FailIf ( kIOReturnSuccess != result, Exit ); switch ( mChanStatusStruct.sampleRate ) { // [24�] sample frequency case 24000: result = CODEC_WriteRegister ( map_CS8420_BUFFER_3, cSampleFrequency_24Khz ); break; case 32000: result = CODEC_WriteRegister ( map_CS8420_BUFFER_3, cSampleFrequency_32Khz ); break; case 44100: result = CODEC_WriteRegister ( map_CS8420_BUFFER_3, cSampleFrequency_44Khz ); break; case 48000: result = CODEC_WriteRegister ( map_CS8420_BUFFER_3, cSampleFrequency_48Khz ); break; case 88200: result = CODEC_WriteRegister ( map_CS8420_BUFFER_3, cSampleFrequency_88Khz ); break; case 96000: result = CODEC_WriteRegister ( map_CS8420_BUFFER_3, cSampleFrequency_96Khz ); break; case 176400: result = CODEC_WriteRegister ( map_CS8420_BUFFER_3, cSampleFrequency_176Khz ); break; case 192000: result = CODEC_WriteRegister ( map_CS8420_BUFFER_3, cSampleFrequency_192Khz ); break; default: result = CODEC_WriteRegister ( map_CS8420_BUFFER_3, cSampleFrequency_44Khz ); break; } FailIf ( kIOReturnSuccess != result, Exit ); switch ( mChanStatusStruct.sampleDepth ) { // [32�] word length & original sample frequency case 16: result = CODEC_WriteRegister ( map_CS8420_BUFFER_4, cWordLength_20Max_16bits ); break; case 24: result = CODEC_WriteRegister ( map_CS8420_BUFFER_4, cWordLength_24Max_24bits ); break; default: result = CODEC_WriteRegister ( map_CS8420_BUFFER_4, cWordLength_20Max_16bits ); break; } FailIf ( kIOReturnSuccess != result, Exit ); } Exit: return result; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void AppleTopazPluginCS8420::disableReceiverError ( void ) { CODEC_WriteRegister ( map_CS8420_RX_ERROR_MASK, kCS8420_RX_ERROR_MASK_DISABLE_RERR ); }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IOReturn AppleTopazPluginCS8420::breakClockSelect ( UInt32 clockSource ) { UInt8 data; IOReturn result; debugIOLog (5, "+ AppleTopazPluginCS8420::breakClockSelect ( %d )", (unsigned int)clockSource ); // Disable error interrupts during completing clock source selection result = CODEC_WriteRegister ( map_CS8420_RX_ERROR_MASK, kCS8420_RX_ERROR_MASK_DISABLE_RERR ); FailIf ( kIOReturnSuccess != result, Exit ); // Mute the output port data = mShadowRegs[map_CS8420_MISC_CNTRL_1]; data &= ~( kCS84XX_BIT_MASK << baCS8420_MuteAES ); data |= ( bvCS8420_muteAES3 << baCS8420_MuteAES ); result = CODEC_WriteRegister ( map_CS8420_MISC_CNTRL_1, data ); FailIf ( result != kIOReturnSuccess, Exit ); // STOP the codec while switching clocks data = mShadowRegs[map_CS8420_CLOCK_SOURCE_CTRL]; data &= ~( 1 << baCS8420_RUN ); data |= ( bvCS8420_runSTOP << baCS8420_RUN ); result = CODEC_WriteRegister ( map_CS8420_CLOCK_SOURCE_CTRL, data ); switch ( clockSource ) { case kTRANSPORT_MASTER_CLOCK: // Set input data source for SRC to serial audio input port data = mShadowRegs[map_CS8420_DATA_FLOW_CTRL]; data &= ~( bvCS8420_spdMASK << baCS8420_SPD ); data |= ( bvCS8420_spdSAI << baCS8420_SPD ); result = CODEC_WriteRegister ( map_CS8420_DATA_FLOW_CTRL, data ); FailIf ( result != kIOReturnSuccess, Exit ); // Set the input time base to the OMCK input pin data = mShadowRegs[map_CS8420_CLOCK_SOURCE_CTRL]; data &= ~( kCS84XX_BIT_MASK << baCS8420_OUTC ); data |= ( bvCS8420_outcOmckXbaCLK << baCS8420_OUTC ); result = CODEC_WriteRegister ( map_CS8420_CLOCK_SOURCE_CTRL, data ); FailIf ( result != kIOReturnSuccess, Exit ); // Set the input port data format to slave mode data = mShadowRegs[map_CS8420_SERIAL_INPUT_FMT]; data &= ~( kCS84XX_BIT_MASK << baCS8420_SIMS ); data |= ( bvCS8420_inputSlave << baCS8420_SIMS ); result = CODEC_WriteRegister ( map_CS8420_SERIAL_INPUT_FMT, data ); FailIf ( result != kIOReturnSuccess, Exit ); // Set the output port data format to slave mode data = mShadowRegs[map_CS8420_SERIAL_OUTPUT_FMT]; data &= ~( kCS84XX_BIT_MASK << baCS8420_SOMS ); data |= ( bvCS8420_somsSlave << baCS8420_SOMS ); result = CODEC_WriteRegister ( map_CS8420_SERIAL_OUTPUT_FMT, data ); FailIf ( result != kIOReturnSuccess, Exit ); break; case kTRANSPORT_SLAVE_CLOCK: // Set input data source for SRC to AES3 receiver data = mShadowRegs[map_CS8420_DATA_FLOW_CTRL]; data &= ~( bvCS8420_spdMASK << baCS8420_SPD ); data |= ( bvCS8420_spdSrcOut << baCS8420_SPD ); result = CODEC_WriteRegister ( map_CS8420_DATA_FLOW_CTRL, data ); FailIf ( result != kIOReturnSuccess, Exit ); // Set the input time base to the OMCK input pin data = mShadowRegs[map_CS8420_CLOCK_SOURCE_CTRL]; data &= ~( kCS84XX_BIT_MASK << baCS8420_OUTC ); data |= ( bvCS8420_outcRecIC << baCS8420_OUTC ); result = CODEC_WriteRegister ( map_CS8420_CLOCK_SOURCE_CTRL, data ); FailIf ( result != kIOReturnSuccess, Exit ); // Set the input port data format to slave mode data = mShadowRegs[map_CS8420_SERIAL_INPUT_FMT]; data &= ~( kCS84XX_BIT_MASK << baCS8420_SIMS ); data |= ( bvCS8420_inputSlave << baCS8420_SIMS ); result = CODEC_WriteRegister ( map_CS8420_SERIAL_INPUT_FMT, data ); FailIf ( result != kIOReturnSuccess, Exit ); // Set the output port data format to master mode data = mShadowRegs[map_CS8420_SERIAL_OUTPUT_FMT]; data &= ~( kCS84XX_BIT_MASK << baCS8420_SOMS ); data |= ( bvCS8420_somsMaster << baCS8420_SOMS ); result = CODEC_WriteRegister ( map_CS8420_SERIAL_OUTPUT_FMT, data ); FailIf ( result != kIOReturnSuccess, Exit ); break; default: result = kIOReturnBadArgument; break; } Exit: debugIOLog (5, "- AppleTopazPluginCS8420::breakClockSelect ( %d ) returns %d", (unsigned int)clockSource, (unsigned int)result ); return result; }