void AudioProj16PowerObject::setFullPowerState (void) { debugIOLog ( 3, "+ AudioProj16PowerObject::setFullPowerState()" ); if(audioPluginRef) { audioPluginRef->sndHWSetPowerState(kIOAudioDeviceActive); } debugIOLog ( 3, "- AudioProj16PowerObject::setFullPowerState()" ); }
IOReturn PAVirtualDeviceUserClient::clientMemoryForType(UInt32 type, UInt32 *flags, IOMemoryDescriptor **memory) { IOMemoryDescriptor *buf; debugIOLog("%s(%p)::%s clientMemoryForType %lu\n", getName(), this, __func__, (unsigned long) type); switch (type) { case kPAMemoryInputSampleData: buf = device->audioInputBuf; break; case kPAMemoryOutputSampleData: buf = device->audioOutputBuf; break; default: debugIOLog(" ... unsupported!\n"); return kIOReturnUnsupported; } if (buf) buf->retain(); *memory = buf; return kIOReturnSuccess; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // This state machine attempts to recover operation of the CS8420 output // after switching clock sources. void AppleTopazAudio::stateMachine2 ( void ) { switch ( mCurrentMachine2State ) { case kMachine2_idleState: debugIOLog ( 5, "± AppleTopazAudio::stateMachine2 remaining in kMachine2_idleState" ); break; case kMachine2_startState: debugIOLog ( 5, "± AppleTopazAudio::stateMachine2 advancing from kMachine2_startState to kMachine2_delay1State" ); mOptimizePollForUserClient_counter = kINITIAL_VALUE_FOR_POLL_FOR_USER_CLIENT_COUNT; // [3686032] initialize so log will show register dump a while longer mCurrentMachine2State = kMachine2_delay1State; break; case kMachine2_delay1State: debugIOLog ( 5, "± AppleTopazAudio::stateMachine2 advancing from kMachine2_delay1State to kMachine2_setRxd_ILRCK" ); mOptimizePollForUserClient_counter = kINITIAL_VALUE_FOR_POLL_FOR_USER_CLIENT_COUNT; // [3686032] initialize so log will show register dump a while longer mCurrentMachine2State = kMachine2_setRxd_ILRCK; break; case kMachine2_setRxd_ILRCK: debugIOLog ( 5, "± AppleTopazAudio::stateMachine2 advancing from kMachine2_setRxd_ILRCK to kMachine2_setRxd_AES3" ); mOptimizePollForUserClient_counter = kINITIAL_VALUE_FOR_POLL_FOR_USER_CLIENT_COUNT; // [3686032] initialize so log will show register dump a while longer mTopazPlugin->useInternalCLK(); mCurrentMachine2State = kMachine2_setRxd_AES3; break; case kMachine2_setRxd_AES3: debugIOLog ( 5, "± AppleTopazAudio::stateMachine2 advancing from kMachine2_setRxd_AES3 to kMachine2_idleState" ); mOptimizePollForUserClient_counter = kINITIAL_VALUE_FOR_POLL_FOR_USER_CLIENT_COUNT; // [3686032] initialize so log will show register dump a while longer mTopazPlugin->useExternalCLK(); mCurrentMachine2State = kMachine2_idleState; break; } }
IOReturn AudioProj7PowerObject::setHardwarePowerOn(){ debugIOLog (3, "+ AudioProj7PowerObject::setHardwarePowerOn"); IOReturn result = kIOReturnSuccess; UInt32 progOut; IOService *keyLargo = 0; keyLargo = IOService::waitForService(IOService::serviceMatching("KeyLargo")); if(keyLargo){ long gpioOffset = kPowerObjectOffset; UInt8 value = kPowerOn; keyLargo->callPlatformFunction("keyLargo_writeRegUInt8", false, (void *)&gpioOffset, (void *)(UInt32)value, 0, 0); } if(audioPluginRef) { IOSleep(300); // we need to wait to be sure that the antipop has the time to do his stuff progOut = audioPluginRef->sndHWGetProgOutput(); progOut |= kSndHWProgOutput0; audioPluginRef->sndHWSetProgOutput(progOut); } if(audioPluginRef) { audioPluginRef->sndHWSetPowerState(kIOAudioDeviceActive); audioPluginRef->setDeviceDetectionActive(); } debugIOLog (3, "- AudioProj7PowerObject::setHardwarePowerOn"); return result; }
IOReturn AudioProj7PowerObject::setHardwarePowerOff(){ IOReturn result = kIOReturnSuccess; UInt32 progOut; IOService *keyLargo = 0; debugIOLog (3, "+ AudioProj7PowerObject::setHardwarePowerOff"); progOut = audioPluginRef->sndHWGetProgOutput(); progOut &= ~kSndHWProgOutput0; audioPluginRef->sndHWSetProgOutput(progOut); IOSleep(200); audioPluginRef->sndHWSetPowerState(kIOAudioDeviceSleep); audioPluginRef->setDeviceDetectionInActive(); keyLargo = IOService::waitForService(IOService::serviceMatching("KeyLargo")); if(keyLargo){ long gpioOffset = kPowerObjectOffset; UInt8 value = kPowerOff; keyLargo->callPlatformFunction("keyLargo_writeRegUInt8", false, (void *)&gpioOffset, (void *)(UInt32)value, 0, 0); } debugIOLog (3, "- AudioProj7PowerObject::setHardwarePowerOff"); return result; }
bool AudioProj8PowerObject::init(Apple02Audio *pluginRef) { debugIOLog (3, "+ AudioProj8PowerObject::init"); mMicroSecondsRequired = 1000000; return (AudioPowerObject::init(pluginRef)); debugIOLog (3, "- AudioProj8PowerObject::init"); }
IOReturn AudioProj6PowerObject::setHardwarePowerOn(){ IOReturn result = kIOReturnSuccess; IOService *HeathRow = 0; UInt32 mask, data; UInt32 powerRegAdrr; debugIOLog (3, "+ AudioProj6PowerObject::setHardwarePowerOn"); HeathRow = IOService::waitForService(IOService::serviceMatching("Heathrow")); powerRegAdrr = kPowerObjectOffset; if(HeathRow) { mask = kPowerObjectMask; data = kPowerOn; HeathRow->callPlatformFunction(OSSymbol::withCString("heathrow_safeWriteRegUInt32"), false, (void *)powerRegAdrr, (void *)mask, (void *) data, 0); IOSleep(10); } if(audioPluginRef) { audioPluginRef->sndHWSetPowerState(kIOAudioDeviceActive); audioPluginRef->setDeviceDetectionActive(); } debugIOLog (3, "- AudioProj6PowerObject::setHardwarePowerOn, %d", kIOReturnSuccess == result); return result; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // call inherited free void AppleTopazAudio::free() { debugIOLog (3, "+ AppleTopazAudio::free" ); CLEAN_RELEASE ( mTopazPlugin ); super::free(); debugIOLog (3, "- AppleTopazAudio::free" ); }
bool AudioProj16PowerObject::init(Apple02Audio *pluginRef){ bool result; debugIOLog ( 3, "+ AudioProj16PowerObject::init ( %p )", pluginRef ); mMicroSecondsRequired = 2000000; result = (AudioPowerObject::init(pluginRef)); debugIOLog ( 3, "- AudioProj16PowerObject::init ( %p ) returns %d", pluginRef, result ); return result; }
IOReturn AudioProj16PowerObject::setHardwarePowerOn(){ IOReturn result = kIOReturnSuccess; debugIOLog ( 3, "+ AudioProj16PowerObject::setHardwarePowerOn()" ); if(audioPluginRef) { audioPluginRef->sndHWSetPowerState(kIOAudioDeviceActive); } debugIOLog ( 3, "- AudioProj16PowerObject::setHardwarePowerOn()" ); return result; }
// ------------------------------------------------------------------------------------------------------------------------------------ // Switching bewteen a system mastered clock and an external clock, such as a recovered clock from an S/PDIF AES3 stream, requires a // "BREAK BEFORE MAKE" sequence to avoid having two hardware drivers connected together. If selecting the master clock then the // external MUX must be disconnected prior to enabling the system master clock. If selecting an external MUX clock source then the // internal system master clock must be disconnected first. Sequences are: // // TRANSITION CYCLE ACTION // ----------------------------|-----------------------|------------------------------------------------------------------------------- // kTRANSPORT_MASTER_CLOCK to | 1 Transport Break | Set MUX to alternate clock source, set I2S to SLAVE (BCLKMaster = SLAVE). // kTRANSPORT_SLAVE_CLOCK | 2 Topaz Break | Stop CS84xx & mute TX. Set all registers to act as a clock master. // | | A. Data Flow Control Register: TXD = 01, SPD = 10, SRCD = 0 // | | B. Clock Source Control Register: OUTC = 1, INC = 0, RXD = 01 // | | C. Serial Input Control Register: SIMS = 0 // | | D. Serial Output Control Register: SOMS = 1 // | 3 TAS3004 Break | No Action. // | 4 Transport Make | No Action. // | 5 Topaz Make | Start CS84xx. Send request to restart transport hardware. // | 6 TAS3004 Make | Reset and flush register cache to hardware. // ----------------------------|-----------------------|------------------------------------------------------------------------------- // kTRANSPORT_SLAVE_CLOCK to | 1 Transport Break | No Action. // kTRANSPORT_MASTER_CLOCK | 2 Topaz Break | Stop CS84xx & disable TX. Set all registers to act as a clock slave. // | | A. Data Flow Control Register: TXD = 01, SPD = 00, SRCD = 1 // | | B. Clock Source Control Register: OUTC = 0, INC = 0, RXD = 01 // | | C. Serial Input Control Register: SIMS = 0 // | | D. Serial Output Control Register: SOMS = 0 // | 3 TAS3004 Break | No Action. // | 4 Transport Make | Set MUX to default clock source, set I2S to SLAVE (BCLKMaster = MASTER). // | 5 Topaz Make | Start CS84xx & unmute TX. Send request to restart transport hardware. // | | A. Clear pending receiver errors. // | | B. Enable receiver errors. // | | C. Set CS8420 to RUN. // | | D. Request a restart of the I2S transport. // | 6 TAS3004 Make | Reset and flush register cache to hardware. // ----------------------------|-----------------------|------------------------------------------------------------------------------- IOReturn AppleTopazAudio::breakClockSelect ( UInt32 clockSource ) { IOReturn result = kIOReturnError; switch ( mCodecID ) { case kCodec_CS8406: debugIOLog ( 5, "+ AppleTopazAudio::breakClockSelect ( %d ) using AppleTopazPluginCS8406", (unsigned int)clockSource ); break; case kCodec_CS8416: debugIOLog ( 5, "+ AppleTopazAudio::breakClockSelect ( %d ) using AppleTopazPluginCS8416", (unsigned int)clockSource ); break; case kCodec_CS8420: debugIOLog ( 5, "+ AppleTopazAudio::breakClockSelect ( %d ) using AppleTopazPluginCS8420", (unsigned int)clockSource ); break; default: debugIOLog ( 5, "+ AppleTopazAudio::breakClockSelect ( %d ) using AppleTopazPluginUNKNOWN", (unsigned int)clockSource ); break; } if (mAttemptingExternalLock) { mAttemptingExternalLock = false; } if ( 0 != mTopazPlugin ) { result = mTopazPlugin->breakClockSelect ( clockSource ); } else { debugIOLog ( 5, " AppleTopazAudio::breakClockSelect attempt to redirect clock source with no plugin present" ); } mUnlockErrorCount = 0; switch ( mCodecID ) { case kCodec_CS8406: debugIOLog ( 5, "- AppleTopazAudio::breakClockSelect ( %d ) using AppleTopazPluginCS8406 returns %lX", (unsigned int)clockSource, (unsigned int)result ); break; case kCodec_CS8416: debugIOLog ( 5, "- AppleTopazAudio::breakClockSelect ( %d ) using AppleTopazPluginCS8416 returns %lX", (unsigned int)clockSource, (unsigned int)result ); break; case kCodec_CS8420: debugIOLog ( 5, "- AppleTopazAudio::breakClockSelect ( %d ) using AppleTopazPluginCS8420 returns %lX", (unsigned int)clockSource, (unsigned int)result ); break; default: debugIOLog ( 5, "- AppleTopazAudio::breakClockSelect ( %d ) using AppleTopazPluginUNKNOWN returns %lX", (unsigned int)clockSource, (unsigned int)result ); break; } return result; }
// ---------------------------------------------------------------------------------------------------- void PlatformInterfaceDBDMA_Mapped::free() { debugIOLog (3, "+ PlatformInterfaceDBDMA_Mapped::free()"); if ( NULL != mIOBaseAddressMemory ) { mIOBaseAddressMemory->release(); } super::free(); debugIOLog (3, "- PlatformInterfaceDBDMA_Mapped::free()"); }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void AppleTopazAudio::initPlugin(PlatformInterface* inPlatformObject) { debugIOLog (3, "+ AppleTopazAudio::initPlugin inPlatformObject = %X", (unsigned int)inPlatformObject); mPlatformInterface = inPlatformObject; debugIOLog (3, "- AppleTopazAudio::initPlugin" ); return; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // This method is invoked from the 'codecErrorInterruptHandler' residing in the // platform interface object. The 'codecErrorInterruptHandler' may be invoked // through GPIO hardware interrupt dispatch services or throught timer polled // services. void AppleTopazAudio::notifyHardwareEvent ( UInt32 statusSelector, UInt32 newValue ) { UInt8 saveMAP = 0; switch ( mCodecID ) { case kCodec_CS8406: debugIOLog ( 5, "+ AppleTopazAudio::notifyHardwareEvent ( %d, %d ) using AppleTopazPluginCS8406", statusSelector, newValue ); break; case kCodec_CS8416: debugIOLog ( 5, "+ AppleTopazAudio::notifyHardwareEvent ( %d, %d ) using AppleTopazPluginCS8416", statusSelector, newValue ); break; case kCodec_CS8420: debugIOLog ( 5, "+ AppleTopazAudio::notifyHardwareEvent ( %d, %d ) using AppleTopazPluginCS8420", statusSelector, newValue ); break; default: debugIOLog ( 5, "+ AppleTopazAudio::notifyHardwareEvent ( %d, %d ) using AppleTopazPluginUNKNOWN", statusSelector, newValue ); break; } FailIf ( NULL == mTopazPlugin, Exit ); FailIf ( NULL == mAudioDeviceProvider, Exit ); FailIf ( NULL == mPlatformInterface, Exit ); saveMAP = (UInt8)mPlatformInterface->getSavedMAP ( mCodecID ); // Preserve illusion of atomic I2C register access outside of this interrupt handler // [3629501] If there is a digital input detect (either a dedicated detect or a combo jack detect) then indicate 'Unlock' when the detect // indicates that the digital plug is removed. If no digital input is located then the initial digital detect status that was written to // the 'mDigitalInStatus' member variable, which indicates that a device is connected to the digital input, will be used. NOTE: The digital // input detect may not be associated with this AppleOnboardAudio instance. It is necessary to receive notifications from the AppleOnboardAudio // object of the current digital input detect status and the source of these messages may be from a broadcast message conveyed from // another AppleOnboardAudio instance! if ( kDigitalInStatus == statusSelector ) { mDigitalInStatus = newValue; debugIOLog ( 6, " AppleTopazAudio::notifyHardwareEvent ( %d, %d ) updates mDigitalInStatus to %d", statusSelector, newValue, mDigitalInStatus ); } if ( ( kCodecErrorInterruptStatus == statusSelector ) || ( kCodecInterruptStatus == statusSelector ) ) { if ( kGPIO_Disconnected == mDigitalInStatus ) { // Override the CODEC status if the detect indicates that nothing is connected. mAudioDeviceProvider->interruptEventHandler ( kClockUnLockStatus, (UInt32)0 ); } else { mTopazPlugin->notifyHardwareEvent ( statusSelector, newValue ); } } if ( saveMAP != (UInt8)mPlatformInterface->getSavedMAP ( mCodecID ) ) { mPlatformInterface->setMAP ( mCodecID, saveMAP ); } Exit: switch ( mCodecID ) { case kCodec_CS8406: debugIOLog ( 5, "- AppleTopazAudio::notifyHardwareEvent ( %d, %d ) using AppleTopazPluginCS8406", statusSelector, newValue ); break; case kCodec_CS8416: debugIOLog ( 5, "- AppleTopazAudio::notifyHardwareEvent ( %d, %d ) using AppleTopazPluginCS8416", statusSelector, newValue ); break; case kCodec_CS8420: debugIOLog ( 5, "- AppleTopazAudio::notifyHardwareEvent ( %d, %d ) using AppleTopazPluginCS8420", statusSelector, newValue ); break; default: debugIOLog ( 5, "- AppleTopazAudio::notifyHardwareEvent ( %d, %d ) using AppleTopazPluginUNKNOWN", statusSelector, newValue ); break; } return; }
// -------------------------------------------------------------------------- // [3787193] IOReturn AppleTopazAudio::requestSleepTime ( UInt32 * microsecondsUntilComplete ) { IOReturn result = kIOReturnBadArgument; debugIOLog ( 6, "+ AppleTopazAudio::requestSleepTime ( %p->%ld )", microsecondsUntilComplete, *microsecondsUntilComplete ); if ( 0 != microsecondsUntilComplete ) { *microsecondsUntilComplete = *microsecondsUntilComplete + kTOPAZ_SLEEP_TIME_MICROSECONDS; result = kIOReturnSuccess; } debugIOLog ( 6, "- AppleTopazAudio::requestSleepTime ( %p->%ld ) returns 0x%lX", microsecondsUntilComplete, *microsecondsUntilComplete, result ); return result; }
bool EMUUSBMIDIDevice::MatchDevice( USBDevice * inUSBDevice) { const IOUSBDeviceDescriptor * devDesc = inUSBDevice->GetDeviceDescriptor(); debugIOLog("starting to match"); if (USBToHostWord(devDesc->idVendor) == kMyVendorID) { UInt16 devProduct = USBToHostWord(devDesc->idProduct); if (devProduct == kMyProductID) { debugIOLog("Found it"); return true; } } return false; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IOReturn AppleTopazAudio::setSampleType ( UInt32 sampleType ) { IOReturn result; switch ( mCodecID ) { case kCodec_CS8406: debugIOLog ( 5, "+ AppleTopazAudio::setSampleType ( %ld ) using AppleTopazPluginCS8406", sampleType ); break; case kCodec_CS8416: debugIOLog ( 5, "+ AppleTopazAudio::setSampleType ( %ld ) using AppleTopazPluginCS8416", sampleType ); break; case kCodec_CS8420: debugIOLog ( 5, "+ AppleTopazAudio::setSampleType ( %ld ) using AppleTopazPluginCS8420", sampleType ); break; default: debugIOLog ( 5, "+ AppleTopazAudio::setSampleType ( %ld ) using AppleTopazPluginUNKNOWN", sampleType ); break; } result = kIOReturnSuccess; switch ( sampleType ) { case kIOAudioStreamSampleFormat1937AC3: mChannelStatus.nonAudio = TRUE; break; case kIOAudioStreamSampleFormatLinearPCM: mChannelStatus.nonAudio = FALSE; break; default: result = kIOReturnBadArgument; break; } if ( kIOReturnSuccess == result ) { if ( 0 != mTopazPlugin ) { result = mTopazPlugin->setChannelStatus ( &mChannelStatus ); } } switch ( mCodecID ) { case kCodec_CS8406: debugIOLog ( 5, "- AppleTopazAudio::setSampleType ( %ld ) using AppleTopazPluginCS8406", sampleType ); break; case kCodec_CS8416: debugIOLog ( 5, "- AppleTopazAudio::setSampleType ( %ld ) using AppleTopazPluginCS8416", sampleType ); break; case kCodec_CS8420: debugIOLog ( 5, "- AppleTopazAudio::setSampleType ( %ld ) using AppleTopazPluginCS8420", sampleType ); break; default: debugIOLog ( 5, "- AppleTopazAudio::setSampleType ( %ld ) using AppleTopazPluginUNKNOWN", sampleType ); break; } return result; }
AudioProj10PowerObject* AudioProj10PowerObject::createAudioProj10PowerObject(Apple02Audio *pluginRef){ AudioProj10PowerObject *myAudioproj10PowerObject = 0; debugIOLog (3, "+ AudioProj10PowerObject::createAudioProj10PowerObject"); myAudioproj10PowerObject = new AudioProj10PowerObject; if(myAudioproj10PowerObject) { if(!(myAudioproj10PowerObject->init(pluginRef))){ myAudioproj10PowerObject->release(); myAudioproj10PowerObject = 0; } } debugIOLog (3, "+ AudioProj10PowerObject::createAudioProj10PowerObject"); return myAudioproj10PowerObject; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IOReturn AppleTopazAudio::setSampleDepth ( UInt32 sampleDepth ) { IOReturn result = kIOReturnBadArgument; switch ( mCodecID ) { case kCodec_CS8406: debugIOLog ( 5, "+ AppleTopazAudio::setSampleDepth ( %ld ) using AppleTopazPluginCS8406", sampleDepth ); break; case kCodec_CS8416: debugIOLog ( 5, "+ AppleTopazAudio::setSampleDepth ( %ld ) using AppleTopazPluginCS8416", sampleDepth ); break; case kCodec_CS8420: debugIOLog ( 5, "+ AppleTopazAudio::setSampleDepth ( %ld ) using AppleTopazPluginCS8420", sampleDepth ); break; default: debugIOLog ( 5, "+ AppleTopazAudio::setSampleDepth ( %ld ) using AppleTopazPluginUNKNOWN", sampleDepth ); break; } FailIf ( !( 16 == sampleDepth || 24 == sampleDepth ), Exit ); // Avoid general recovery when running on external clock as a reset // will set the clocks back to internal. Just indicate if the bit // depth is valid so that AppleOnboardAudio's poll method that validates // sample rate changes can operate correctly but leave the hardware alone! if ( kTRANSPORT_MASTER_CLOCK == mClockSource ) { generalRecovery(); } mChannelStatus.sampleDepth = sampleDepth; if ( 0 != mTopazPlugin ) { result = mTopazPlugin->setChannelStatus ( &mChannelStatus ); } Exit: switch ( mCodecID ) { case kCodec_CS8406: debugIOLog ( 5, "- AppleTopazAudio::setSampleDepth ( %ld ) using AppleTopazPluginCS8406", sampleDepth ); break; case kCodec_CS8416: debugIOLog ( 5, "- AppleTopazAudio::setSampleDepth ( %ld ) using AppleTopazPluginCS8416", sampleDepth ); break; case kCodec_CS8420: debugIOLog ( 5, "- AppleTopazAudio::setSampleDepth ( %ld ) using AppleTopazPluginCS8420", sampleDepth ); break; default: debugIOLog ( 5, "- AppleTopazAudio::setSampleDepth ( %ld ) using AppleTopazPluginUNKNOWN", sampleDepth ); break; } return result; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ UInt8 AppleTopazAudio::CODEC_ReadID ( void ) { UInt8 result = 0; debugIOLog ( 5, "+ AppleTopazAudio::CODEC_ReadID ()" ); FailIf ( NULL == mPlatformInterface, Exit ); // The codec reference in the following dispatch can be ambiguous because the CS8406, CS8416 or CS8420 all // share the same address assignment relative to the I2S I/O Module that is connected to the CODEC. FailIf ( kIOReturnSuccess != mPlatformInterface->readCodecRegister ( kCodec_CS8420, map_ID_VERSION, &result, 1 ), Exit ); Exit: debugIOLog ( 5, "- AppleTopazAudio::CODEC_ReadID () returns 0x%2X", result ); return result; }
// -------------------------------------------------------------------------- // Method: clockRun ::starts and stops the clock count: bool AudioI2SControl::clockRun(bool start) { bool success = true; if (start) { switch ( i2SInterfaceNumber ) { case kUseI2SCell0: KLSetRegister (kFCR1Offset, KLGetRegister (kFCR1Offset) | kI2S0InterfaceEnable); KLSetRegister (kFCR1Offset, KLGetRegister (kFCR1Offset) | kI2S0CellEnable); KLSetRegister (kFCR1Offset, KLGetRegister (kFCR1Offset) | kI2S0ClockEnable); break; case kUseI2SCell1: KLSetRegister (kFCR1Offset, KLGetRegister (kFCR1Offset) | kI2S1InterfaceEnable); KLSetRegister (kFCR1Offset, KLGetRegister (kFCR1Offset) | kI2S1CellEnable); KLSetRegister (kFCR1Offset, KLGetRegister (kFCR1Offset) | kI2S1ClockEnable); break; default: debugIOLog (1, "\n\n\n!!!!Wrong I2S interface number!!!!\n\n"); } } else { UInt16 loop = 50; switch ( i2SInterfaceNumber ) { case kUseI2SCell0: KLSetRegister (kFCR1Offset, KLGetRegister (kFCR1Offset) | kI2S0InterfaceEnable); KLSetRegister (kFCR1Offset, KLGetRegister (kFCR1Offset) | kI2S0CellEnable); KLSetRegister (kFCR1Offset, KLGetRegister (kFCR1Offset) & ~kI2S0ClockEnable); break; case kUseI2SCell1: KLSetRegister (kFCR1Offset, KLGetRegister (kFCR1Offset) | kI2S1InterfaceEnable); KLSetRegister (kFCR1Offset, KLGetRegister (kFCR1Offset) | kI2S1CellEnable); KLSetRegister (kFCR1Offset, KLGetRegister (kFCR1Offset) & ~kI2S1ClockEnable); break; default: debugIOLog (1, "\n\n\n!!!!Wrong I2S interface number!!!!\n\n"); } while (((GetIntCtlReg() & kClocksStoppedPending) == 0) && (loop--)) { // it does not do anything, jut waites for the clock // to stop IOSleep(10); } // we are successful if the clock actually stopped. success = ((GetIntCtlReg() & kClocksStoppedPending) != 0); } if (!success) debugIOLog (3, "PPCDACA::clockRun(%s) failed", (start ? "true" : "false")); return success; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bool AppleTopazAudio::willTerminate ( IOService * provider, IOOptionBits options ) { bool result = super::willTerminate( provider, options ); debugIOLog (3, "+ AppleTopazAudio::willTerminate(%p) returns %d, mAudioDeviceProvider = %p", provider, result, mAudioDeviceProvider); if (provider == mAudioDeviceProvider) { debugIOLog (3, "closing our provider" ); provider->close (this); } debugIOLog (3, "- AppleTopazAudio[%p]::willTerminate(%p) returns %s", this, provider, result == true ? "true" : "false" ); return result; }
// ------------------------------------------------------------------------------------------------------------------------------------ // Switching bewteen a system mastered clock and an external clock, such as a recovered clock from an S/PDIF AES3 stream, requires a // "BREAK BEFORE MAKE" sequence to avoid having two hardware drivers connected together. If selecting the master clock then the // external MUX must be disconnected prior to enabling the system master clock. If selecting an external MUX clock source then the // internal system master clock must be disconnected first. Sequences are: // // TRANSITION CYCLE ACTION // ----------------------------|-----------------------|------------------------------------------------------------------------------- // kTRANSPORT_MASTER_CLOCK to | 1 Transport Break | Set MUX to alternate clock source, set I2S to SLAVE (BCLKMaster = SLAVE). // kTRANSPORT_SLAVE_CLOCK | 2 Topaz Break | Stop CS84xx & mute TX. Set all registers to act as a clock master. // | | A. Data Flow Control Register: TXD = 01, SPD = 10, SRCD = 0 // | | B. Clock Source Control Register: OUTC = 1, INC = 0, RXD = 01 // | | C. Serial Input Control Register: SIMS = 0 // | | D. Serial Output Control Register: SOMS = 1 // | 3 TAS3004 Break | No Action. // | 4 Transport Make | No Action. // | 5 Topaz Make | Start CS84xx. Send request to restart transport hardware. // | 6 TAS3004 Make | Reset and flush register cache to hardware. // ----------------------------|-----------------------|------------------------------------------------------------------------------- // kTRANSPORT_SLAVE_CLOCK to | 1 Transport Break | No Action. // kTRANSPORT_MASTER_CLOCK | 2 Topaz Break | Stop CS84xx & disable TX. Set all registers to act as a clock slave. // | | A. Data Flow Control Register: TXD = 01, SPD = 00, SRCD = 1 // | | B. Clock Source Control Register: OUTC = 0, INC = 0, RXD = 01 // | | C. Serial Input Control Register: SIMS = 0 // | | D. Serial Output Control Register: SOMS = 0 // | 3 TAS3004 Break | No Action. // | 4 Transport Make | Set MUX to default clock source, set I2S to SLAVE (BCLKMaster = MASTER). // | 5 Topaz Make | Start CS84xx & unmute TX. Send request to restart transport hardware. // | | A. Clear pending receiver errors. // | | B. Enable receiver errors. // | | C. Set CS8420 to RUN. // | | D. Request a restart of the I2S transport. // | 6 TAS3004 Make | Reset and flush register cache to hardware. // ----------------------------|-----------------------|------------------------------------------------------------------------------- IOReturn AppleTopazAudio::makeClockSelect ( UInt32 clockSource ) { IOReturn result = kIOReturnError; switch ( mCodecID ) { case kCodec_CS8406: debugIOLog ( 5, "+ AppleTopazAudio::makeClockSelect ( %d ) using AppleTopazPluginCS8406", (unsigned int)clockSource ); break; case kCodec_CS8416: debugIOLog ( 5, "+ AppleTopazAudio::makeClockSelect ( %d ) using AppleTopazPluginCS8416", (unsigned int)clockSource ); break; case kCodec_CS8420: debugIOLog ( 5, "+ AppleTopazAudio::makeClockSelect ( %d ) using AppleTopazPluginCS8420", (unsigned int)clockSource ); break; default: debugIOLog ( 5, "+ AppleTopazAudio::makeClockSelect ( %d ) using AppleTopazPluginUNKNOWN", (unsigned int)clockSource ); break; } FailIf ( NULL == mTopazPlugin, Exit ); FailIf ( NULL == mAudioDeviceProvider, Exit ); result = mTopazPlugin->makeClockSelectPreLock ( clockSource ); if ( kTRANSPORT_SLAVE_CLOCK == clockSource && mTopazPlugin->supportsDigitalInput() ) { // It is necessary to restart the I2S cell here after the clocks have been // established using the CS8420 as the clock source. Ask AOA to restart // the I2S cell. This is only done if the CODEC can provide a clock source // and should not be done if the CODEC is an output only device such as the CS8406. debugIOLog ( 4, " *** AppleTopazAudio::makeClockSelect about to post kRestartTransport request" ); mAudioDeviceProvider->interruptEventHandler ( kRestartTransport, (UInt32)0 ); // [3253678], set flag to broadcast lock success to AOA so it can unmute analog part mAttemptingExternalLock = true; } result = mTopazPlugin->makeClockSelectPostLock ( clockSource ); mUnlockErrorCount = 0; if ( kTRANSPORT_MASTER_CLOCK == clockSource && mTopazPlugin->supportsDigitalInput() ) { if ( mUnlockStatus ) { mUnlockStatus = false; } if ( false == mDisableStateMachine2 ) { mCurrentMachine2State = kMachine2_startState; } else { mCurrentMachine2State = kMachine2_idleState; } } mClockSource = clockSource; Exit: mUnlockErrorCount = 0; switch ( mCodecID ) { case kCodec_CS8406: debugIOLog ( 5, "- AppleTopazAudio::makeClockSelect ( %d ) using AppleTopazPluginCS8406 returns %lX", (unsigned int)clockSource, (unsigned int)result ); break; case kCodec_CS8416: debugIOLog ( 5, "- AppleTopazAudio::makeClockSelect ( %d ) using AppleTopazPluginCS8416 returns %lX", (unsigned int)clockSource, (unsigned int)result ); break; case kCodec_CS8420: debugIOLog ( 5, "- AppleTopazAudio::makeClockSelect ( %d ) using AppleTopazPluginCS8420 returns %lX", (unsigned int)clockSource, (unsigned int)result ); break; default: debugIOLog ( 5, "- AppleTopazAudio::makeClockSelect ( %d ) using AppleTopazPluginUNKNOWN returns %lX", (unsigned int)clockSource, (unsigned int)result ); break; } return result; }
// -------------------------------------------------------------------------- AudioI2SControl *AudioI2SControl::create(AudioI2SInfo *theInfo) { debugIOLog (3, "+ AudioI2SControl::create"); AudioI2SControl *myAudioI2SControl; myAudioI2SControl = new AudioI2SControl; if(myAudioI2SControl) { if(!(myAudioI2SControl->init(theInfo))){ myAudioI2SControl->release(); myAudioI2SControl = 0; } } debugIOLog (3, "- AudioI2SControl::create"); return myAudioI2SControl; }
AudioProj16PowerObject* AudioProj16PowerObject::createAudioProj16PowerObject ( Apple02Audio *pluginRef ){ AudioProj16PowerObject* myAudioProj16PowerObject = NULL; debugIOLog ( 3, "+ AudioProj16PowerObject::createAudioProj16PowerObject ( %p )", pluginRef ); myAudioProj16PowerObject = new AudioProj16PowerObject; if(myAudioProj16PowerObject) { if(!(myAudioProj16PowerObject->init(pluginRef))){ myAudioProj16PowerObject->release(); myAudioProj16PowerObject = 0; } } debugIOLog ( 3, "- AudioProj16PowerObject::createAudioProj16PowerObject ( %p ) returns %p", pluginRef, myAudioProj16PowerObject ); return (myAudioProj16PowerObject); }
bool AudioPowerObject::init(Apple02Audio *pluginRef){ debugIOLog ( 3, "+ AudioPowerObject::init ( %p )", pluginRef ); mMicroSecondsRequired = 50000; if (!(OSObject::init())) return false; if(pluginRef) { audioPluginRef = pluginRef; audioPluginRef->retain(); } debugIOLog ( 3, "- AudioPowerObject::init ( %p ) returns %d", pluginRef, true ); return true; }
MIDIDeviceRef EMUUSBMIDIDevice::CreateDevice( USBDevice * inUSBDevice, USBInterface * inUSBInterface) { MIDIDeviceRef dev = NULL; MIDIEntityRef ent; //UInt16 devProduct = USBToHostWord(inUSBDevice->GetDeviceDescriptor()->idProduct); // get the product and manufacturer names from the box // get the number of ports the device supports const IOUSBDeviceDescriptor* desc = inUSBDevice->GetDeviceDescriptor(); if (desc) { CFStringRef manufacturerName = inUSBDevice->GetString(desc->iManufacturer); CFStringRef productName = inUSBDevice->GetString(desc->iProduct); MIDIDeviceCreate(Self(), productName, manufacturerName, // manufacturer name productName, &dev); const IOUSBInterfaceDescriptor* interfaceDesc = NULL; if (inUSBInterface) { interfaceDesc = inUSBInterface->GetInterfaceDescriptor(); }else { USBInterface *intf = inUSBDevice->FindInterface(kTheInterfaceToUse, 0); debugIOLog("FindInterface in CreateDevice, %x", intf); interfaceDesc = intf->GetInterfaceDescriptor(); } if (interfaceDesc) { // need to find out the number of EMBEDDED MIDI endpoints int portLimit = inUSBDevice->GetTotalMIDIPortCount() / 2; debugIOLog("portLimit is %d", portLimit); if (portLimit > 1) { for (int port = 1; port <= portLimit; ++port) { char portname[64]; sprintf(portname, "Port %d", port); CFStringRef str = CFStringCreateWithCString(NULL, portname, 0); MIDIDeviceAddEntity(dev, str, false, 1, 1, &ent); CFRelease(str); } } else { MIDIDeviceAddEntity(dev, productName, false, 1, 1, &ent); } } CFRelease(manufacturerName); CFRelease(productName); } return dev; }
bool AudioI2SControl::setSampleParameters(UInt32 sampleRate, UInt32 mclkToFsRatio, ClockSource *pClockSource, UInt32 *pMclkDivisor, UInt32 *pSclkDivisor, UInt32 newSerialFormat) { UInt32 mclkRatio; UInt32 reqMClkRate; mclkRatio = mclkToFsRatio; // remember the MClk ratio required if ( mclkRatio == 0 ) // or make one up if MClk not required mclkRatio = 64; // use 64 x ratio since that will give us the best characteristics reqMClkRate = sampleRate * mclkRatio; // this is the required MClk rate // look for a source clock that divides down evenly into the MClk if ((kClock18MHz % reqMClkRate) == 0) { // preferential source is 18 MHz clockSource = kClock18MHz; } else if ((kClock45MHz % reqMClkRate) == 0) { // next check 45 MHz clock (11.025, 22.050 & 44.100 KHz sample rates) clockSource = kClock45MHz; } else if ((kClock49MHz % reqMClkRate) == 0) { // last, try 49 Mhz clock (48.000 & 96.000 KHz sample rates) clockSource = kClock49MHz; } else { debugIOLog (3, "AppleDACAAudio::setSampleParameters Unable to find a suitable source clock (no globals changes take effect)"); return false; } *pClockSource = clockSource; // get the MClk divisor mclkDivisor = clockSource / reqMClkRate; *pMclkDivisor = mclkDivisor; switch (newSerialFormat) { // SClk depends on format [3060320] rbm 2 Oct 2002 case kSndIOFormatI2SSony: case kSndIOFormatI2S64x: sclkDivisor = mclkRatio / k64TicksPerFrame; // SClk divisor is MClk ratio/64 serialFormat = newSerialFormat; break; case kSndIOFormatI2S32x: sclkDivisor = mclkRatio / k32TicksPerFrame; // SClk divisor is MClk ratio/32 serialFormat = newSerialFormat; break; default: debugIOLog (3, "AppleDACAAudio::setSampleParameters Invalid serial format"); return false; break; } *pSclkDivisor = sclkDivisor; return true; }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bool AppleTopazAudio::requestTerminate ( IOService * provider, IOOptionBits options ) { bool result = super::requestTerminate( provider, options ); debugIOLog (3, "± AppleTopazAudio::requestTerminate(%p) returns %d, mAudioDeviceProvider = %p", provider, result, mAudioDeviceProvider); return result; }