AppleOnboardAudio.cpp [plain text]
#include <IOKit/IOCommandGate.h>
#include <IOKit/IOMessage.h>
#include <IOKit/pwr_mgt/RootDomain.h>
#include <IOKit/IOTimerEventSource.h>
#include "IOKit/audio/IOAudioDevice.h"
#include "AppleOnboardAudio.h"
#include "AudioHardwareUtilities.h"
#include "AudioHardwareObjectInterface.h"
#include "PlatformInterface.h"
#include "TransportFactory.h"
OSDefineMetaClassAndStructors(AppleOnboardAudio, IOAudioDevice)
UInt32 AppleOnboardAudio::sInstanceCount = 0;
UInt32 AppleOnboardAudio::sTotalNumAOAEnginesRunning = 0;
#define super IOAudioDevice
#define DualKeyLargo_WORKAROUND 1
#pragma mark +UNIX LIKE FUNCTIONS
bool AppleOnboardAudio::init (OSDictionary *properties)
{
debugIOLog ( 3, "+ AppleOnboardAudio[%p]::init", this);
if (!super::init(properties)) return false;
currentDevices = 0xFFFF;
mHasHardwareInputGain = true;
mInternalMicDualMonoMode = e_Mode_Disabled;
mNumberOfAOAPowerParents = 0;
mSampleRateSelectInProcessSemaphore = false;
mClockSelectInProcessSemaphore = false;
mCurrentProcessingOutputString = OSString::withCString ("none");
mCurrentProcessingInputString = OSString::withCString ("none");
mUCState.ucPowerState = kIOAudioDeviceActive;
debugIOLog ( 6, " setting mCurrentAggressivenessLevel to %ld", kIOPMExternalPower );
mCurrentAggressivenessLevel = kIOPMExternalPower;
mOutputSelectorLastValue=0; mHasSPDIFControl=false;
debugIOLog ( 3, "- AppleOnboardAudio[%p]::init", this);
return true;
}
bool AppleOnboardAudio::start (IOService * provider) {
OSArray * layouts;
OSArray * multipleDevicesArray;
OSDictionary * layoutEntry;
OSNumber * layoutIDNumber;
UInt32 * layoutID;
UInt32 layoutIDInt;
UInt32 layoutsCount;
UInt32 index;
OSData * tmpData;
bool result;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::start (%p)", mInstanceIndex, provider);
result = FALSE;
AppleOnboardAudio::sInstanceCount++;
mInstanceIndex = AppleOnboardAudio::sInstanceCount;
mProvider = provider;
provider->open (this);
#ifdef THREAD_POWER_MANAGEMENT
mPowerThread = thread_call_allocate ((thread_call_func_t)AppleOnboardAudio::performPowerStateChangeThread, (thread_call_param_t)this);
FailIf (0 == mPowerThread, Exit);
#endif
mInitHardwareThread = thread_call_allocate ((thread_call_func_t)AppleOnboardAudio::initHardwareThread, (thread_call_param_t)this);
FailIf (0 == mInitHardwareThread, Exit);
tmpData = OSDynamicCast (OSData, provider->getProperty ( kLayoutID ) );
layoutID = (UInt32 *)tmpData->getBytesNoCopy ();
FailIf ( 0 == layoutID, Exit )
mLayoutID = *layoutID;
layouts = OSDynamicCast ( OSArray, getProperty ( kLayouts ) );
debugIOLog ( 3, " layout array = %p", layouts );
FailIf ( 0 == layouts, Exit );
layoutsCount = layouts->getCount ();
debugIOLog ( 3, " layouts->getCount () returns %ld", layoutsCount );
layoutEntry = 0;
index = 0;
mMatchingIndex = 0xFFFFFFFF;
layoutIDInt = 0;
debugIOLog ( 6, " AppleOnboardAudio[%ld]::mLayoutID 0x%lX = #%ld (from provider node)", mInstanceIndex, mLayoutID, mLayoutID);
while ( layoutsCount-- )
{
layoutEntry = OSDynamicCast (OSDictionary, layouts->getObject (index));
FailIf (0 == layoutEntry, Exit);
layoutIDNumber = OSDynamicCast (OSNumber, layoutEntry->getObject (kLayoutIDInfoPlist));
FailIf (0 == layoutIDNumber, Exit);
layoutIDInt = layoutIDNumber->unsigned32BitValue ();
if ( layoutIDInt == mLayoutID )
{
debugIOLog ( 6, " AppleOnboardAudio[%ld] found machine layout id 0x%lX @ index %ld", mInstanceIndex, layoutIDInt, index);
mMatchingIndex = index;
break;
}
else
{
index++;
}
}
FailIf (0xFFFFFFFF == mMatchingIndex, Exit);
layoutEntry = OSDynamicCast (OSDictionary, layouts->getObject (mMatchingIndex));
debugIOLog ( 6, " layoutEntry = %p", layoutEntry);
FailIf (0 == layoutEntry, Exit);
multipleDevicesArray = OSDynamicCast (OSArray, layoutEntry->getObject (kMultipleDevices));
debugIOLog ( 3, " AOA[%d] is %p->multipleDevicesArray = %p", mInstanceIndex, this, multipleDevicesArray);
if ( multipleDevicesArray )
{
mJoinAOAPMTree = TRUE;
}
debugIOLog ( 5, " about to setFamilyManagePower ( FALSE ) due to mJoinAOAPMTree %d", mInstanceIndex, mJoinAOAPMTree );
setFamilyManagePower ( FALSE );
result = super::start (provider); FailIf ( !result, Exit );
debugIOLog ( 5, " mNumberOfAOAPowerParents %ld", mNumberOfAOAPowerParents );
if ( !mJoinAOAPMTree ) {
static IOPMPowerState aoaPowerParentPowerStates[2] = {{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{1, IOPMDeviceUsable, IOPMPowerOn, IOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0}};
PMinit ();
debugIOLog ( 6, " %p newService->about to joinPMtree ( %p )", provider, this );
provider->joinPMtree ( this );
if ( pm_vars != NULL )
{
duringStartup = TRUE;
debugIOLog ( 6, " about to registerPowerDriver ( %p, %p, Td)", this, aoaPowerParentPowerStates, 2 );
registerPowerDriver ( this, aoaPowerParentPowerStates, 2 );
changePowerStateTo ( 1 );
duringStartup = FALSE;
}
mNumberOfAOAPowerParents = 1;
}
debugIOLog ( 3, " [%ld] addNotification (gIOPublishNotification, serviceMatching (AppleOnboardAudio), (IOServiceNotificationHandler)&aoaPublished=%p, this=%p )", mInstanceIndex, &aoaPublished, this );
aoaNotifier = addNotification ( gIOPublishNotification, serviceMatching ( "AppleOnboardAudio" ), (IOServiceNotificationHandler)&aoaPublished, this );
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::start (%p) returns %d while mNumberOfAOAPowerParents = %d", mInstanceIndex, provider, result, mNumberOfAOAPowerParents );
return result;
}
bool AppleOnboardAudio::handleOpen (IOService * forClient, IOOptionBits options, void * arg )
{
bool result;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::handleOpen(%p)", mInstanceIndex, forClient);
if (kFamilyOption_OpenMultiple == options) {
result = true;
} else {
result = super::handleOpen ( forClient, options, arg );
FailIf (!result, Exit);
}
registerPlugin ( (AudioHardwareObjectInterface *)forClient );
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::handleOpen(%p) returns %s", mInstanceIndex, forClient, result == true ? "true" : "false");
return result;
}
void AppleOnboardAudio::handleClose (IOService * forClient, IOOptionBits options )
{
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::handleClose(%p)", mInstanceIndex, forClient);
unRegisterPlugin ( (AudioHardwareObjectInterface *)forClient );
if (options != kFamilyOption_OpenMultiple) {
super::handleClose ( forClient, options );
}
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::handleClose(%p)", mInstanceIndex, forClient);
return;
}
bool AppleOnboardAudio::willTerminate ( IOService * provider, IOOptionBits options )
{
bool result;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::willTerminate(%p)", mInstanceIndex, provider);
result = super::willTerminate ( provider, options );
provider->close(this);
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::willTerminate(%p) returns %d", mInstanceIndex, provider, result);
return result;
}
void AppleOnboardAudio::registerPlugin (AudioHardwareObjectInterface *thePlugin) {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::registerPlugin (%p)", mInstanceIndex, thePlugin);
FailIf ( 0 == mPluginObjects, Exit );
mPluginObjects->setObject (thePlugin);
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::registerPlugin (%p)", mInstanceIndex, thePlugin);
return;
}
void AppleOnboardAudio::stop (IOService * provider) {
if ( mJoinAOAPMTree ) {
PMstop();
}
if ( 0 != aoaNotifier ) {
aoaNotifier->remove();
}
FailIf ( mProvider != provider, Exit );
if (0 != mSysPowerDownNotifier) {
mSysPowerDownNotifier->remove ();
mSysPowerDownNotifier = 0;
}
mTerminating = TRUE;
if (idleTimer) {
if (workLoop) {
workLoop->removeEventSource (idleTimer);
}
idleTimer->release ();
idleTimer = 0;
}
if (mSoftwareInterruptHandler) {
if (workLoop) {
workLoop->removeEventSource (mSoftwareInterruptHandler);
mSoftwareInterruptHandler->release ();
}
}
if ( pollTimer ) {
if ( workLoop ) {
workLoop->removeEventSource ( pollTimer );
}
pollTimer->release ();
pollTimer = 0;
}
callPluginsInOrder ( kSetMuteState, TRUE );
#ifdef THREAD_POWER_MANAGEMENT
if (mPowerThread) {
thread_call_cancel (mPowerThread);
}
#endif
debugIOLog ( 3, "AppleOnboardAudio[%ld]::stop(), audioEngines = %p, isInactive() = %d", mInstanceIndex, audioEngines, isInactive());
Exit:
super::stop (provider);
}
void AppleOnboardAudio::unRegisterPlugin (AudioHardwareObjectInterface *inPlugin) {
AudioHardwareObjectInterface * thePluginObject;
UInt32 index;
UInt32 count;
debugIOLog ( 3, "AppleOnboardAudio[%ld]::unRegisterPlugin (%p)", mInstanceIndex, inPlugin);
if (0 != mPluginObjects) {
count = mPluginObjects->getCount ();
for (index = 0; index < count; index++) {
thePluginObject = getIndexedPluginObject (index);
if ((0 != thePluginObject) && (inPlugin == thePluginObject)) {
mPluginObjects->removeObject(index);
debugIOLog ( 3, " removed plugin (%p)", inPlugin);
}
}
}
return;
}
IOReturn AppleOnboardAudio::registerPluginAction (OSObject *owner, void *arg1, void *arg2, void *arg3, void *arg4) {
AppleOnboardAudio * device;
IOReturn result = kIOReturnError;
device = OSDynamicCast (AppleOnboardAudio, owner);
FailIf ( 0 == device, Exit );
debugIOLog ( 3, "AppleOnboardAudio[%ld]::plugin %p registering", device->mInstanceIndex, arg1);
if (0 == device->mPluginObjects) {
device->mPluginObjects = OSArray::withCapacity (1);
}
FailIf (0 == device->mPluginObjects, Exit);
device->mPluginObjects->setObject ((AudioHardwareObjectInterface *)arg1);
result = kIOReturnSuccess;
Exit:
return result;
}
OSObject * AppleOnboardAudio::getLayoutEntry (const char * entryID, AppleOnboardAudio * theAOA) {
OSArray * layouts;
OSDictionary * layoutEntry;
OSObject * entry;
entry = 0;
layouts = OSDynamicCast (OSArray, theAOA->getProperty (kLayouts));
FailIf (0 == layouts, Exit);
layoutEntry = OSDynamicCast (OSDictionary, layouts->getObject (theAOA->mMatchingIndex));
FailIf (0 == layoutEntry, Exit);
entry = OSDynamicCast (OSObject, layoutEntry->getObject (entryID));
Exit:
return entry;
}
bool AppleOnboardAudio::hasMasterVolumeControl (const UInt32 inCode) {
char * connectionString;
connectionString = getConnectionKeyFromCharCode (inCode, kIOAudioStreamDirectionOutput);
return hasMasterVolumeControl (connectionString);
}
bool AppleOnboardAudio::hasMasterVolumeControl (const char * outputEntry) {
OSDictionary * dictEntry;
OSArray * controlsArray;
OSString * controlString;
UInt32 controlsCount;
UInt32 index;
bool hasMasterVolControl = FALSE;
if ( 0 != outputEntry ) {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::hasMasterVolumeControl( %p->'%4s' )", mInstanceIndex, outputEntry, outputEntry );
dictEntry = OSDynamicCast (OSDictionary, getLayoutEntry (outputEntry, this));
FailIf (0 == dictEntry, Exit);
controlsArray = OSDynamicCast (OSArray, dictEntry->getObject (kControls));
FailIf (0 == controlsArray, Exit);
controlsCount = controlsArray->getCount ();
for (index = 0; index < controlsCount; index++) {
controlString = OSDynamicCast (OSString, controlsArray->getObject (index));
if ((0 != controlString) && controlString->isEqualTo (kMasterVolControlString)) {
hasMasterVolControl = TRUE;
}
}
} else {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::hasMasterVolumeControl(%p)", mInstanceIndex, outputEntry );
}
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::hasMasterVolumeControl(%p) returns %d", mInstanceIndex, outputEntry, hasMasterVolControl );
return hasMasterVolControl;
}
bool AppleOnboardAudio::hasLeftVolumeControl (const UInt32 inCode) {
char * connectionString;
connectionString = getConnectionKeyFromCharCode (inCode, kIOAudioStreamDirectionOutput);
return hasLeftVolumeControl (connectionString);
}
bool AppleOnboardAudio::hasLeftVolumeControl (const char * outputEntry) {
OSDictionary * dictEntry;
OSArray * controlsArray;
OSString * controlString;
UInt32 controlsCount;
UInt32 index;
bool hasLeftVolControl = FALSE;
if ( 0 != outputEntry ) {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::hasLeftVolumeControl( %p->'%4s' )", mInstanceIndex, outputEntry, outputEntry );
dictEntry = OSDynamicCast (OSDictionary, getLayoutEntry (outputEntry, this));
FailIf (0 == dictEntry, Exit);
controlsArray = OSDynamicCast (OSArray, dictEntry->getObject (kControls));
FailIf (0 == controlsArray, Exit);
controlsCount = controlsArray->getCount ();
for (index = 0; index < controlsCount; index++) {
controlString = OSDynamicCast (OSString, controlsArray->getObject (index));
if ((0 != controlString) && controlString->isEqualTo (kLeftVolControlString)) {
hasLeftVolControl = TRUE;
}
}
} else {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::hasLeftVolumeControl(%p)", mInstanceIndex, outputEntry );
}
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::hasLeftVolumeControl(%p) returns %d", mInstanceIndex, outputEntry, hasLeftVolControl );
return hasLeftVolControl;
}
bool AppleOnboardAudio::hasRightVolumeControl (const UInt32 inCode) {
char * connectionString;
connectionString = getConnectionKeyFromCharCode (inCode, kIOAudioStreamDirectionOutput);
return hasRightVolumeControl (connectionString);
}
bool AppleOnboardAudio::hasRightVolumeControl (const char * outputEntry) {
OSDictionary * dictEntry;
OSArray * controlsArray;
OSString * controlString;
UInt32 controlsCount;
UInt32 index;
bool hasRightVolControl = FALSE;
if ( 0 != outputEntry ) {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::hasRightVolumeControl( %p->'%4s' )", mInstanceIndex, outputEntry, outputEntry );
dictEntry = OSDynamicCast (OSDictionary, getLayoutEntry (outputEntry, this));
FailIf (0 == dictEntry, Exit);
controlsArray = OSDynamicCast (OSArray, dictEntry->getObject (kControls));
FailIf (0 == controlsArray, Exit);
controlsCount = controlsArray->getCount ();
for (index = 0; index < controlsCount; index++) {
controlString = OSDynamicCast (OSString, controlsArray->getObject (index));
if ((0 != controlString) && controlString->isEqualTo (kRightVolControlString)) {
hasRightVolControl = TRUE;
}
}
} else {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::hasRightVolumeControl(%p)", mInstanceIndex, outputEntry );
}
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::hasRightVolumeControl(%p) returns %d", mInstanceIndex, outputEntry, hasRightVolControl );
return hasRightVolControl;
}
void AppleOnboardAudio::setUseInputGainControls (const char * inputEntry) {
OSDictionary * dictEntry;
OSArray * controlsArray;
OSString * controlString;
UInt32 controlsCount;
UInt32 index;
if ( 0 != inputEntry ) {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::setUseInputGainControls( %p->'%4s' )", mInstanceIndex, inputEntry, inputEntry);
mUseInputGainControls = kNoInputGainControls;
dictEntry = OSDynamicCast (OSDictionary, getLayoutEntry (inputEntry, this));
FailIf (0 == dictEntry, Exit);
controlsArray = OSDynamicCast (OSArray, dictEntry->getObject (kControls));
if (NULL != controlsArray) {
controlsCount = controlsArray->getCount ();
for (index = 0; index < controlsCount; index++) {
controlString = OSDynamicCast (OSString, controlsArray->getObject (index));
if ((0 != controlString) && (controlString->isEqualTo (kLeftVolControlString) || controlString->isEqualTo (kRightVolControlString))) {
mUseInputGainControls = kStereoInputGainControls;
debugIOLog ( 3, " mUseInputGainControls = kStereoInputGainControls");
} else if ((0 != controlString) && (controlString->isEqualTo (kMasterVolControlString))) {
mUseInputGainControls = kMonoInputGainControl;
debugIOLog ( 3, " mUseInputGainControls = kMonoInputGainControl");
}
}
}
}
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::setUseInputGainControls( %p )", mInstanceIndex, inputEntry);
return;
}
void AppleOnboardAudio::setUsePlaythroughControl (const char * inputEntry) {
OSDictionary * dictEntry;
OSBoolean * playthroughOSBoolean;
if ( 0 != inputEntry ) {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::setUsePlaythroughControl( %p->'%4s' )", mInstanceIndex, inputEntry, inputEntry );
mUsePlaythroughControl = FALSE;
dictEntry = OSDynamicCast ( OSDictionary, getLayoutEntry ( inputEntry, this) );
FailIf ( 0 == dictEntry, Exit );
playthroughOSBoolean = OSDynamicCast ( OSBoolean, dictEntry->getObject ( kPlaythroughControlString ) );
FailIf ( 0 == playthroughOSBoolean, Exit );
mUsePlaythroughControl = playthroughOSBoolean->getValue ();
} else {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::setUsePlaythroughControl( %p )", mInstanceIndex, inputEntry);
}
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::setUsePlaythroughControl(%p), mUsePlaythroughControl = %d", mInstanceIndex, inputEntry, mUsePlaythroughControl );
return;
}
IOReturn AppleOnboardAudio::validateOutputFormatChangeRequest (const IOAudioStreamFormat * inFormat, const IOAudioSampleRate * inRate) {
IOReturn result;
result = kIOReturnSuccess;
if (kIOAudioStreamSampleFormat1937AC3 == inFormat->fSampleFormat) {
if (0 != mOutputSelector) {
if (!(kGPIO_Unknown == mPlatformInterface->getComboOutJackTypeConnected() || kGPIO_Connected == mPlatformInterface->getDigitalOutConnected())) {
debugIOLog ( 3, "~ AppleOnboardAudio::validateOutputFormatChangeRequest found invalid encoded format request");
result = kIOReturnError;
}
}
}
if ((NULL != inRate) && (kClockSourceSelectionExternal == mCurrentClockSelector)) {
debugIOLog(3, "AppleOnboardAudio::validateOutputFormatChangeRequest - attempt to change sampling rate while external clock selected...returning error");
result = kIOReturnNotPermitted;
}
return result;
}
IOReturn AppleOnboardAudio::validateInputFormatChangeRequest (const IOAudioStreamFormat * inFormat, const IOAudioSampleRate * inRate) {
IOReturn result = kIOReturnSuccess;
if ((NULL != inRate) && (kClockSourceSelectionExternal == mCurrentClockSelector)) {
debugIOLog(3, "AppleOnboardAudio::validateInputFormatChangeRequest - attempt to change sampling rate while external clock selected...returning error");
result = kIOReturnNotPermitted;
}
return result;
}
IOReturn AppleOnboardAudio::formatChangeRequest (const IOAudioStreamFormat * inFormat, const IOAudioSampleRate * inRate) {
IOReturn result;
OSNumber * connectionCodeNumber;
bool needsUpdate = FALSE;
result = kIOReturnSuccess;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::formatChangeRequest (%p, %p)", mInstanceIndex, inFormat, inRate);
FailIf ( 0 == mPlatformInterface, Exit );
if ( 0 != inFormat ) {
needsUpdate = TRUE;
}
if ( 0 != inRate ) {
if ( kTransportInterfaceType_I2S_Slave_Only != mTransportInterface->transportGetTransportInterfaceType() ) { needsUpdate = TRUE;
}
}
if ( needsUpdate ) { result = kIOReturnError; if (mMuteAmpWhenClockInterrupted) { muteAllAmps ();
}
callPluginsInOrder (kBeginFormatChange, 0);
if (0 != inFormat) {
debugIOLog ( 3, " AppleOnboardAudio[%ld]::formatChangeRequest with bit width %d", mInstanceIndex, inFormat->fBitWidth);
result = mTransportInterface->transportSetSampleWidth (inFormat->fBitDepth, inFormat->fBitWidth);
callPluginsInOrder (kSetSampleBitDepth, inFormat->fBitDepth);
if (kIOAudioStreamSampleFormat1937AC3 == inFormat->fSampleFormat) {
if (0 != mOutputSelector) {
debugIOLog ( 3, " mPlatformInterface->getComboOutJackTypeConnected() = %ld", mPlatformInterface->getComboOutJackTypeConnected());
debugIOLog ( 3, " mPlatformInterface->getDigitalOutConnected() = %ld", mPlatformInterface->getDigitalOutConnected());
if (kGPIO_Unknown == mPlatformInterface->getComboOutJackTypeConnected() || kGPIO_Connected == mPlatformInterface->getDigitalOutConnected()) {
connectionCodeNumber = OSNumber::withNumber (kIOAudioOutputPortSubTypeSPDIF, 32);
mOutputSelector->setValue (connectionCodeNumber);
connectionCodeNumber->release ();
mEncodedOutputFormat = true;
debugIOLog ( 3, " encoded format request honored");
} else {
debugIOLog ( 3, " encoded format requested, but no digital hardware is connected");
callPluginsInOrder (kEndFormatChange, 0);
selectCodecOutputWithMuteState (mIsMute);
result = kIOReturnError;
goto Exit;
}
}
} else {
mEncodedOutputFormat = false;
debugIOLog ( 5, " non-encoded format");
}
result = callPluginsInOrder ( kSetSampleType, inFormat->fSampleFormat );
}
if (0 != inRate) {
mSampleRateSelectInProcessSemaphore = true;
debugIOLog ( 3, " AppleOnboardAudio[%ld]::formatChangeRequest with rate %ld", mInstanceIndex, inRate->whole);
result = mTransportInterface->transportSetSampleRate (inRate->whole);
FailIf ( kIOReturnSuccess != result, Exit ); result = callPluginsInOrder (kSetSampleRate, inRate->whole);
FailIf ( kIOReturnSuccess != result, Exit );
if ( kIOReturnSuccess == result ) {
mTransportSampleRate.whole = inRate->whole;
mTransportSampleRate.fraction = inRate->fraction;
mSampleRateSelectInProcessSemaphore = false;
}
}
callPluginsInOrder (kEndFormatChange, 0); selectCodecOutputWithMuteState (mIsMute);
if ( 0 != mOutputSelector ) {
selectOutputAmplifiers (mOutputSelector->getIntValue (), mIsMute);
}
}
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::formatChangeRequest returns %d", mInstanceIndex, result);
return result;
}
IOReturn AppleOnboardAudio::callPluginsInReverseOrder (UInt32 inSelector, UInt32 newValue) {
AudioHardwareObjectInterface * thePluginObject;
OSArray * pluginOrderArray;
OSString * pluginName;
SInt32 index;
UInt32 pluginOrderArrayCount;
IOReturn result;
debugIOLog ( 7, "+ AppleOnboardAudio[%ld]::callPluginsInReverseOrder (%lX, %lX)", mInstanceIndex, inSelector, newValue);
result = kIOReturnBadArgument;
pluginOrderArray = OSDynamicCast (OSArray, getLayoutEntry (kPluginRecoveryOrder, this));
FailIf (0 == pluginOrderArray, Exit);
pluginOrderArrayCount = pluginOrderArray->getCount ();
for (index = pluginOrderArrayCount - 1; index >= 0; index--) {
pluginName = OSDynamicCast(OSString, pluginOrderArray->getObject(index));
if (0 == pluginName) {
debugIOLog ( 3, " Corrupt %s entry in AppleOnboardAudio[%ld] Info.plist", kPluginRecoveryOrder, mInstanceIndex);
continue;
}
thePluginObject = getPluginObjectWithName (pluginName);
if (0 == thePluginObject) {
debugIOLog ( 3, " Can't find required AppleOnboardAudio plugin from %s entry loaded", kPluginRecoveryOrder);
continue;
}
switch (inSelector) {
case kRequestCodecRecoveryStatus:
result = thePluginObject->recoverFromFatalError ((FatalRecoverySelector)newValue);
break;
case kBreakClockSelect:
result = thePluginObject->breakClockSelect (newValue);
break;
case kMakeClockSelect:
result = thePluginObject->makeClockSelect (newValue);
break;
case kSetSampleRate:
result = thePluginObject->setSampleRate (newValue);
break;
case kSetSampleBitDepth:
result = thePluginObject->setSampleDepth (newValue);
break;
case kPowerStateChange:
result = thePluginObject->performSetPowerState ( ( newValue >> 16 ), ( newValue & 0x0000FFFF ) );
break;
default:
break;
}
}
Exit:
debugIOLog ( 7, "- AppleOnboardAudio[%ld]::callPluginsInReverseOrder (%lX, %lX) returns %lX", mInstanceIndex, inSelector, newValue, result);
return result;
}
IOReturn AppleOnboardAudio::callPluginsInOrder (UInt32 inSelector, UInt32 newValue) {
AudioHardwareObjectInterface * thePluginObject;
OSArray * pluginOrderArray;
OSString * pluginName;
UInt32 index;
UInt32 pluginOrderArrayCount;
IOReturn tempResult;
IOReturn result;
bool boolResult;
debugIOLog ( 7, "+ AppleOnboardAudio[%ld]::callPluginsInOrder (%lX, %lX)", mInstanceIndex, inSelector, newValue);
result = kIOReturnBadArgument;
pluginOrderArray = OSDynamicCast (OSArray, getLayoutEntry (kPluginRecoveryOrder, this));
FailIf (0 == pluginOrderArray, Exit);
pluginOrderArrayCount = pluginOrderArray->getCount ();
result = kIOReturnSuccess;
for (index = 0; index < pluginOrderArrayCount; index++) {
pluginName = OSDynamicCast(OSString, pluginOrderArray->getObject(index));
if (0 == pluginName) {
debugIOLog ( 3, " Corrupt %s entry in AppleOnboardAudio[%ld] Info.plist", kPluginRecoveryOrder, mInstanceIndex);
continue;
}
thePluginObject = getPluginObjectWithName (pluginName);
if (0 == thePluginObject) {
debugIOLog ( 3, " Can't find required AppleOnboardAudio plugin from %s entry loaded", kPluginRecoveryOrder);
continue;
}
tempResult = kIOReturnSuccess;
switch (inSelector) {
case kRequestCodecRecoveryStatus:
tempResult = thePluginObject->recoverFromFatalError ((FatalRecoverySelector)newValue);
break;
case kClockInterruptedRecovery:
tempResult = thePluginObject->recoverFromFatalError ((FatalRecoverySelector)newValue);
break;
case kBreakClockSelect:
tempResult = thePluginObject->breakClockSelect (newValue);
break;
case kMakeClockSelect:
tempResult = thePluginObject->makeClockSelect (newValue);
break;
case kSetSampleRate:
tempResult = thePluginObject->setSampleRate (newValue);
break;
case kSetSampleBitDepth:
tempResult = thePluginObject->setSampleDepth (newValue);
break;
case kSetSampleType:
tempResult = thePluginObject->setSampleType ( newValue );
break;
case kSetEnableSPDIFOut:
tempResult = thePluginObject->setSPDIFOutEnable ( newValue );
break;
case kPreDMAEngineInit:
boolResult = thePluginObject->preDMAEngineInit ( newValue );
if ( !boolResult ) {
debugIOLog (1, " AppleOnboardAudio[%ld]::callPluginsInOrder: preDMAEngineInit on thePluginObject %p failed!", mInstanceIndex, thePluginObject);
mPluginObjects->removeObject ( index );
index--;
tempResult = kIOReturnError;
}
break;
case kPostDMAEngineInit:
boolResult = thePluginObject->postDMAEngineInit ();
if ( !boolResult ) {
debugIOLog (1, " AppleOnboardAudio[%ld]::callPluginsInOrder: postDMAEngineInit on thePluginObject %p failed!", mInstanceIndex, thePluginObject);
mPluginObjects->removeObject ( index );
index--;
tempResult = kIOReturnError;
}
break;
case kPowerStateChange:
{
tempResult = thePluginObject->performSetPowerState ( ( newValue >> 16 ), ( newValue & 0x0000FFFF ) );
}
break;
case kDigitalInStatus:
thePluginObject->notifyHardwareEvent ( inSelector, newValue ); break;
case kCodecErrorInterruptStatus:
debugIOLog ( 6, " AppleOnboardAudio[%d]::callPluginsInOrder INVOKES thePluginObject->notifyHardwareEvent ( kCodecErrorInterruptStatus, %d )", mInstanceIndex, newValue );
thePluginObject->notifyHardwareEvent ( inSelector, newValue );
break;
case kCodecInterruptStatus:
debugIOLog ( 6, " AppleOnboardAudio[%d]::callPluginsInOrder INVOKES thePluginObject->notifyHardwareEvent ( kCodecInterruptStatus, %d )", mInstanceIndex, newValue );
thePluginObject->notifyHardwareEvent ( inSelector, newValue );
break;
case kRunPollTask:
thePluginObject->poll ();
break;
case kSetMuteState:
debugIOLog ( 3, " callPluginsInOrder calls thePluginObject->setMute ( %ld )", newValue );
tempResult = thePluginObject->setMute ( newValue );
break;
case kSetAnalogMuteState: debugIOLog ( 3, " callPluginsInOrder calls thePluginObject->setMute ( %ld, kAnalogAudioSelector )", newValue );
tempResult = thePluginObject->setMute ( newValue, kAnalogAudioSelector );
break;
case kSetDigitalMuteState: debugIOLog ( 3, " callPluginsInOrder calls thePluginObject->setMute ( %ld, kDigitalAudioSelector )", newValue );
tempResult = thePluginObject->setMute ( newValue, kDigitalAudioSelector );
break;
case kBeginFormatChange: debugIOLog ( 3, " callPluginsInOrder calls thePluginObject->beginFormatChange ()");
tempResult = thePluginObject->beginFormatChange ();
break;
case kEndFormatChange: debugIOLog ( 3, " callPluginsInOrder calls thePluginObject->endFormatChange ()");
tempResult = thePluginObject->endFormatChange ();
break;
case kRequestSleepTime:
debugIOLog ( 6, " kRequestSleepTime before plugin: %p->%ld", (UInt32*)newValue, *(UInt32*)newValue );
tempResult = thePluginObject->requestSleepTime ( (UInt32*)newValue );
debugIOLog ( 6, " kRequestSleepTime after plugin: %p->%ld", (UInt32*)newValue, *(UInt32*)newValue );
break;
default:
tempResult = kIOReturnBadArgument;
break;
}
if ( kIOReturnSuccess != tempResult ) {
result = tempResult;
}
}
Exit:
debugIOLog ( 7, "- AppleOnboardAudio[%ld]::callPluginsInOrder (%lX, %lX) returns %lX", mInstanceIndex, inSelector, newValue, result);
return result;
}
AudioHardwareObjectInterface * AppleOnboardAudio::findPluginForType ( HardwarePluginType pluginType ) {
AudioHardwareObjectInterface * thePluginObject;
AudioHardwareObjectInterface * result;
OSArray * pluginOrderArray;
OSString * pluginName;
UInt32 index;
UInt32 pluginOrderArrayCount;
result = 0;
pluginOrderArray = OSDynamicCast (OSArray, getLayoutEntry (kPluginRecoveryOrder, this));
FailIf (0 == pluginOrderArray, Exit);
pluginOrderArrayCount = pluginOrderArray->getCount ();
for (index = 0; index < pluginOrderArrayCount && 0 == result; index++) {
thePluginObject = 0;
pluginName = OSDynamicCast(OSString, pluginOrderArray->getObject(index));
if ( 0 != pluginName ) {
thePluginObject = getPluginObjectWithName (pluginName);
if ( 0 != thePluginObject ) {
if ( pluginType == thePluginObject->getPluginType() ) {
result = thePluginObject;
}
}
}
}
Exit:
return result;
}
void AppleOnboardAudio::setPollTimer () {
AbsoluteTime fireTime;
UInt64 nanos;
if ( pollTimer ) {
debugIOLog ( 6, "± AppleOnboardAudio::setPollTimer () starting timer" );
clock_get_uptime (&fireTime);
absolutetime_to_nanoseconds (fireTime, &nanos);
nanos += NSEC_PER_SEC;
nanoseconds_to_absolutetime (nanos, &fireTime);
pollTimer->wakeAtTime (fireTime);
}
}
void AppleOnboardAudio::pollTimerCallback ( OSObject *owner, IOTimerEventSource *device ) {
AppleOnboardAudio * audioDevice;
audioDevice = OSDynamicCast ( AppleOnboardAudio, owner );
FailIf ( 0 == audioDevice, Exit );
audioDevice->runPollTasksEventHandler ();
Exit:
return;
}
void AppleOnboardAudio::runPollTasksEventHandler ( void ) {
IOCommandGate * cg;
cg = getCommandGate ();
if (0 != cg) {
cg->runAction ( runPolledTasks, (void*)0, (void*)0 );
}
return;
}
IOReturn AppleOnboardAudio::runPolledTasks (OSObject * owner, void * arg1, void * arg2, void * arg3, void * arg4) {
FailIf ( 0 == owner, Exit );
((AppleOnboardAudio*)owner)->protectedRunPolledTasks();
Exit:
return kIOReturnSuccess;
}
void AppleOnboardAudio::protectedRunPolledTasks ( void ) {
IOReturn err;
UInt32 errorCount = 0;
UInt32 transportType;
debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::runPolledTasks(), mDelayPollAfterWakeFromSleep %d", mInstanceIndex, mDelayPollAfterWakeFromSleep );
if ( 0 != mDelayPollAfterWakeFromSleep ) { mDelayPollAfterWakeFromSleep--; }
if ( 0 == mDelayPollAfterWakeFromSleep ) { transportType = mTransportInterface->transportGetTransportInterfaceType();
if ( kIOAudioDeviceActive == getPowerState () ) {
if ( !mClockSelectInProcessSemaphore && !mSampleRateSelectInProcessSemaphore ) {
IOAudioSampleRate transportSampleRate;
transportSampleRate.whole = mTransportInterface->transportGetSampleRate ();
transportSampleRate.fraction = 0;
if ( 0 != transportSampleRate.whole ) {
if ( mTransportSampleRate.whole != transportSampleRate.whole || mTransportSampleRate.fraction != transportSampleRate.fraction ) {
do {
err = callPluginsInOrder ( kSetSampleRate, transportSampleRate.whole );
if ( kIOReturnSuccess != err ) {
IOSleep(1);
errorCount++;
}
} while ( ( errorCount < kMiniumumPollsToAquireClockLock ) && ( kIOReturnSuccess != err ) );
if ( kIOReturnSuccess == err ) {
mTransportSampleRate.whole = transportSampleRate.whole;
mTransportSampleRate.fraction = transportSampleRate.fraction;
debugIOLog ( 4, " *#* about to [%ld]mDriverDMAEngine->hardwareSampleRateChanged ( %d )", mInstanceIndex, mTransportSampleRate.whole ); mDriverDMAEngine->hardwareSampleRateChanged ( &mTransportSampleRate );
mDriverDMAEngine->updateDSPForSampleRate(mTransportSampleRate.whole); } else {
if ( ( kTransportInterfaceType_I2S_Slave_Only != transportType ) && !mAutoSelectClock ) { debugIOLog ( 5, " ** AppleOnboardAudio[%ld]::runPolledTasks switching to INTERNAL CLOCK", mInstanceIndex );
mCodecLockStatus = kClockUnLockStatus; clockSelectorChanged ( kClockSourceSelectionInternal );
if ( 0 != mExternalClockSelector ) {
OSNumber * clockSourceSelector;
clockSourceSelector = OSNumber::withNumber (kClockSourceSelectionInternal, 32);
mExternalClockSelector->hardwareValueChanged (clockSourceSelector);
clockSourceSelector->release ();
transportSampleRate.whole = mTransportInterface->transportGetSampleRate (); err = callPluginsInOrder ( kSetSampleRate, mTransportSampleRate.whole );
}
}
}
}
}
if ( mDriverDMAEngine->engineDied() ) {
debugIOLog ( 5, " ** AppleOnboardAudio[%ld]::runPolledTasks invoking 'ConfigChangeHelper' to recover from 'DEAD' DMA", mInstanceIndex );
ConfigChangeHelper theConfigeChangeHelper(mDriverDMAEngine);
if ( ( kTransportInterfaceType_I2S_Slave_Only != transportType ) && ( kTransportInterfaceType_I2S_Opaque_Slave_Only != transportType ) ) {
if ( kTRANSPORT_MASTER_CLOCK != mTransportInterface->transportGetClockSelect() ) {
UInt32 currentBitDepth = mTransportInterface->transportGetSampleWidth();
mTransportInterface->transportSetSampleWidth ( currentBitDepth, mTransportInterface->transportGetDMAWidth() );
callPluginsInOrder ( kSetSampleBitDepth, currentBitDepth );
}
}
}
}
callPluginsInOrder ( kRunPollTask, 0 );
mPlatformInterface->poll ();
mTransportInterface->poll ();
} } else { if ( kIOAudioDeviceActive == getPowerState () ) {
callPluginsInOrder ( kRunPollTask, 0 );
}
}
setPollTimer ();
debugIOLog ( 5, "- AppleOnboardAudio[%ld]::runPolledTasks()", mInstanceIndex );
}
UInt32 AppleOnboardAudio::parseOutputDetectCollection ( void ) {
UInt32 result;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::ParseDetectCollection() detectCollection 0x%lX", mInstanceIndex, mDetectCollection );
if ( kGPIO_Selector_NotAssociated == mPlatformInterface->getComboOutAssociation() ) { if ( mDetectCollection & kSndHWLineOutput ) {
result = kIOAudioOutputPortSubTypeLine;
} else if ( mDetectCollection & kSndHWDigitalOutput ) {
result = kIOAudioOutputPortSubTypeSPDIF;
} else if ( mDetectCollection & kSndHWCPUHeadphone ) {
result = kIOAudioOutputPortSubTypeHeadphones;
} else if ( mDetectCollection & kSndHWCPUExternalSpeaker ) {
result = kIOAudioOutputPortSubTypeExternalSpeaker;
} else {
result = kIOAudioOutputPortSubTypeInternalSpeaker;
}
} else {
if ( mDetectCollection & kSndHWLineOutput ) {
result = kIOAudioOutputPortSubTypeLine;
} else if ( mDetectCollection & kSndHWCPUHeadphone ) {
result = kIOAudioOutputPortSubTypeHeadphones;
} else if ( mDetectCollection & kSndHWCPUExternalSpeaker ) {
result = kIOAudioOutputPortSubTypeExternalSpeaker;
} else {
result = kIOAudioOutputPortSubTypeInternalSpeaker;
}
}
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::ParseDetectCollection returns %4s", mInstanceIndex, (char*)&result );
return result;
}
UInt32 AppleOnboardAudio::parseInputDetectCollection ( void ) {
UInt32 result;
if ( mDetectCollection & kSndHWLineInput ) {
result = kIOAudioOutputPortSubTypeLine;
} else {
result = kIOAudioInputPortSubTypeInternalMicrophone;
}
debugIOLog ( 3, "± AppleOnboardAudio[%ld]::parseInputDetectCollection returns'%4s' from mDetectCollection = 0x%lX", mInstanceIndex, (char*)&result, mDetectCollection );
return result;
}
void AppleOnboardAudio::initializeDetectCollection ( void ) {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::initializeDetectCollection() ", mInstanceIndex);
mDetectCollection = getValueForDetectCollection ( mDetectCollection );
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::initializeDetectCollection(), mDetectCollection = 0x%lX", mInstanceIndex, mDetectCollection );
return;
}
UInt32 AppleOnboardAudio::getValueForDetectCollection ( UInt32 currentDetectCollection )
{
UInt32 result = currentDetectCollection;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::getValueForDetectCollection ( 0x%X )", mInstanceIndex, currentDetectCollection );
if ( kGPIO_Connected == mPlatformInterface->getHeadphoneConnected() ) {
if ( kGPIO_Selector_HeadphoneDetect == mPlatformInterface->getComboOutAssociation() ) {
if ( kGPIO_Unknown == mPlatformInterface->getComboOutJackTypeConnected () ) {
result |= kSndHWCPUHeadphone;
debugIOLog ( 3, " AppleOnboardAudio[%ld]::getValueForDetectCollection() - headphones are connected.", mInstanceIndex);
} else {
if ( kGPIO_TypeIsAnalog == mPlatformInterface->getComboOutJackTypeConnected () ) {
result |= kSndHWCPUHeadphone;
debugIOLog ( 3, " AppleOnboardAudio[%ld]::getValueForDetectCollection() - headphones are connected.", mInstanceIndex);
} else {
result |= kSndHWDigitalOutput;
debugIOLog ( 3, " AppleOnboardAudio[%ld]::getValueForDetectCollection() - digital output is connected.", mInstanceIndex);
}
}
} else {
result |= kSndHWCPUHeadphone;
debugIOLog ( 3, " AppleOnboardAudio[%ld]::getValueForDetectCollection() - headphones are connected.", mInstanceIndex);
}
}
if ( kGPIO_Connected == mPlatformInterface->getLineOutConnected() ) {
if ( kGPIO_Selector_LineOutDetect == mPlatformInterface->getComboOutAssociation() ) {
if ( kGPIO_Unknown == mPlatformInterface->getComboOutJackTypeConnected () ) {
result |= kSndHWLineOutput;
debugIOLog ( 3, " AppleOnboardAudio[%ld]::getValueForDetectCollection() - line output is connected.", mInstanceIndex);
} else {
if ( kGPIO_TypeIsAnalog == mPlatformInterface->getComboOutJackTypeConnected () ) {
result |= kSndHWLineOutput;
debugIOLog ( 3, " AppleOnboardAudio[%ld]::getValueForDetectCollection() - line output is connected.", mInstanceIndex);
} else {
result |= kSndHWDigitalOutput;
debugIOLog ( 3, " AppleOnboardAudio[%ld]::getValueForDetectCollection() - digital output is connected.", mInstanceIndex);
}
}
} else {
result |= kSndHWLineOutput;
debugIOLog ( 3, " AppleOnboardAudio[%ld]::getValueForDetectCollection() - line output is connected.", mInstanceIndex);
}
}
if ( kGPIO_Connected == mPlatformInterface->getDigitalOutConnected() ) {
debugIOLog ( 3, " AppleOnboardAudio[%ld]::getValueForDetectCollection() - digital out is connected.", mInstanceIndex);
result |= kSndHWDigitalOutput;
}
if ( kGPIO_Connected == mPlatformInterface->getLineInConnected() ) {
if ( kGPIO_Selector_LineInDetect == mPlatformInterface->getComboInAssociation() ) {
if ( kGPIO_Unknown == mPlatformInterface->getComboInJackTypeConnected () ) {
result |= kSndHWLineInput;
}
else {
if ( kGPIO_TypeIsAnalog == mPlatformInterface->getComboInJackTypeConnected () ) {
result |= kSndHWLineInput;
}
else {
result |= kSndHWDigitalInput;
}
}
}
else {
result |= kSndHWLineInput;
}
}
if ( kGPIO_Connected == mPlatformInterface->getDigitalInConnected() ) {
result |= kSndHWDigitalInput;
}
if ( kGPIO_Connected == mPlatformInterface->getSpeakerConnected() ) { debugIOLog ( 3, " AppleOnboardAudio[%ld]::getValueForDetectCollection() - external speakers are connected.", mInstanceIndex);
result |= kSndHWCPUExternalSpeaker;
result &= ~kSndHWInternalSpeaker;
} else {
debugIOLog ( 3, " AppleOnboardAudio[%ld]::getValueForDetectCollection() - in internal speakers are connected.", mInstanceIndex);
result |= kSndHWInternalSpeaker;
result &= ~kSndHWCPUExternalSpeaker;
}
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::getValueForDetectCollection ( 0x%X ) returns 0x%lX", mInstanceIndex, currentDetectCollection );
return result;
}
void AppleOnboardAudio::updateAllDetectCollection (UInt32 statusSelector, UInt32 newValue) {
debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::updateAllDetectCollection ( %ld, %ld )", mInstanceIndex, statusSelector, newValue );
switch (statusSelector)
{
case kHeadphoneStatus:
debugIOLog ( 6, " kHeadphoneStatus mDetectCollection prior to modification %lX", mDetectCollection );
if (newValue == kInserted)
{
mDetectCollection |= kSndHWCPUHeadphone;
mDetectCollection &= ~kSndHWInternalSpeaker;
debugIOLog ( 6, " headphones inserted, mDetectCollection = %lX", mDetectCollection);
ConfigChangeHelper theConfigeChangeHelper(mDriverDMAEngine);
if ( kGPIO_Selector_HeadphoneDetect == mPlatformInterface->getComboOutAssociation() )
{
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeSPDIF );
debugIOLog ( 6, " removed SPDIF from output selector due to headphone insert **");
mDetectCollection &= ~kSndHWDigitalOutput;
}
debugIOLog ( 6, " add headphones to output selector *");
mOutputSelector->addAvailableSelection ( kIOAudioOutputPortSubTypeHeadphones, mHeadphoneOutputString );
debugIOLog ( 6, " remove internal speaker from output selector *");
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeInternalSpeaker );
}
else if (newValue == kRemoved)
{
mDetectCollection &= ~kSndHWCPUHeadphone;
mDetectCollection |= kSndHWInternalSpeaker;
debugIOLog ( 6, " headphones removed, mDetectCollection = %lX", mDetectCollection);
ConfigChangeHelper theConfigeChangeHelper(mDriverDMAEngine);
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeHeadphones );
debugIOLog ( 6, " headphones removed, mDetectCollection = %lX", mDetectCollection);
if ( 0 == ( mDetectCollection & kSndHWLineOutput ) )
{
mOutputSelector->addAvailableSelection ( kIOAudioOutputPortSubTypeInternalSpeaker, mInternalSpeakerOutputString );
debugIOLog ( 6, " add internal speaker to output selector *");
}
}
else
{
debugIOLog ( 6, " Unknown headphone jack status, mDetectCollection = %lX", mDetectCollection);
}
break;
case kLineOutStatus:
debugIOLog ( 6, " kLineOutStatus mDetectCollection prior to modification %lX", mDetectCollection );
if (newValue == kInserted)
{
mDetectCollection |= kSndHWLineOutput;
mDetectCollection &= ~kSndHWInternalSpeaker;
debugIOLog ( 6, " line out inserted.");
ConfigChangeHelper theConfigeChangeHelper(mDriverDMAEngine);
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeInternalSpeaker );
debugIOLog ( 6, " removed internal speaker from output selector **");
if ( kGPIO_Selector_LineOutDetect == mPlatformInterface->getComboOutAssociation() )
{
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeSPDIF );
debugIOLog ( 6, " removed SPDIF from output selector **");
mDetectCollection &= ~kSndHWDigitalOutput;
}
debugIOLog ( 6, " add LineOut from output selector");
mOutputSelector->addAvailableSelection (kIOAudioOutputPortSubTypeLine, mLineOutputString);
}
else if (newValue == kRemoved)
{
mDetectCollection &= ~kSndHWLineOutput;
mDetectCollection |= kSndHWInternalSpeaker;
debugIOLog ( 6, " line out removed.");
ConfigChangeHelper theConfigeChangeHelper(mDriverDMAEngine);
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeLine );
debugIOLog ( 6, " removed Line from output selector");
if ( 0 == ( mDetectCollection & kSndHWCPUHeadphone ) )
{
mOutputSelector->addAvailableSelection ( kIOAudioOutputPortSubTypeInternalSpeaker, mInternalSpeakerOutputString );
debugIOLog ( 6, " added internal speaker to output selector *");
}
}
else
{
debugIOLog ( 6, " Unknown line out jack status.");
}
break;
case kDigitalOutStatus:
debugIOLog ( 6, " kDigitalOutStatus mDetectCollection prior to modification %lX", mDetectCollection );
if (newValue == kInserted)
{
mDetectCollection |= kSndHWDigitalOutput;
mDetectCollection &= ~kSndHWInternalSpeaker;
debugIOLog ( 6, " digital out inserted, mDigitalOutputString = %p, getComboOutJackTypeConnected = %ld", mDigitalOutputString, mPlatformInterface->getComboOutJackTypeConnected ());
debugIOLog ( 6, " mPlatformInterface->getComboOutJackTypeConnected () returns 0x%0.2X", mPlatformInterface->getComboOutJackTypeConnected () );
if ( kGPIO_Unknown != mPlatformInterface->getComboOutJackTypeConnected () )
{
ConfigChangeHelper theConfigeChangeHelper(mDriverDMAEngine);
if ( kGPIO_Selector_LineOutDetect == mPlatformInterface->getComboOutAssociation() )
{
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeInternalSpeaker );
debugIOLog ( 6, " removed internal speaker from output selector *");
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeLine );
debugIOLog ( 6, " removed line output from output selector");
mDetectCollection &= ~kSndHWLineOutput;
}
else if ( kGPIO_Selector_HeadphoneDetect == mPlatformInterface->getComboOutAssociation() )
{
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeInternalSpeaker );
debugIOLog ( 6, " removed internal speaker from output selector **");
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeHeadphones );
debugIOLog ( 6, " removed headphone from output selector");
mDetectCollection &= ~kSndHWCPUHeadphone;
}
mOutputSelector->addAvailableSelection (kIOAudioOutputPortSubTypeSPDIF, mDigitalOutputString);
debugIOLog ( 6, " added SPDIF to output selector");
}
}
else if (newValue == kRemoved)
{
mDetectCollection &= ~kSndHWDigitalOutput;
mDetectCollection |= kSndHWInternalSpeaker;
debugIOLog ( 6, "digital out removed.");
if ( (kGPIO_Unknown != mPlatformInterface->getComboOutJackTypeConnected ()) )
{
debugIOLog ( 5, " ** AppleOnboardAudio[%ld]::updateDetectCollection invoking 'ConfigChangeHelper'", mInstanceIndex );
ConfigChangeHelper theConfigeChangeHelper(mDriverDMAEngine);
if ( kGPIO_Selector_LineOutDetect == mPlatformInterface->getComboOutAssociation() )
{
mOutputSelector->addAvailableSelection (kIOAudioOutputPortSubTypeInternalSpeaker, mInternalSpeakerOutputString);
debugIOLog ( 6, " added internal speaker to output selector");
if ( kGPIO_Connected == mPlatformInterface->getLineOutConnected () )
{
debugIOLog ( 6, " add LineOut from output selector");
mOutputSelector->addAvailableSelection (kIOAudioOutputPortSubTypeLine, mLineOutputString);
mDetectCollection |= kSndHWLineOutput;
}
else
{
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeLine );
debugIOLog ( 6, " removed Line from output selector");
}
}
else if ( kGPIO_Selector_HeadphoneDetect == mPlatformInterface->getComboOutAssociation() )
{
mOutputSelector->addAvailableSelection (kIOAudioOutputPortSubTypeInternalSpeaker, mInternalSpeakerOutputString);
debugIOLog ( 6, " added internal speaker to output selector");
if ( kGPIO_Connected == mPlatformInterface->getHeadphoneConnected () )
{
debugIOLog ( 6, " added headphones to output selector *");
mOutputSelector->addAvailableSelection ( kIOAudioOutputPortSubTypeHeadphones, mHeadphoneOutputString );
mDetectCollection |= kSndHWCPUHeadphone;
}
else
{
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeHeadphones );
debugIOLog ( 6, " removed headphone from output selector");
}
}
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeSPDIF );
debugIOLog ( 6, " removed SPDIF from output selector");
}
}
else
{
debugIOLog ( 6, " Unknown digital out jack status.");
}
break;
case kLineInStatus:
debugIOLog ( 6, " kLineInStatus mDetectCollection prior to modification %lX", mDetectCollection );
if (newValue == kInserted)
{
mDetectCollection |= kSndHWLineInput;
if (TRUE == mAutoSelectInput) {
ConfigChangeHelper theConfigChangeHelper(mDriverDMAEngine);
if (kGPIO_Unknown != mPlatformInterface->getComboInJackTypeConnected()) {
if (TRUE == mInputSelector->valueExists(kIOAudioInputPortSubTypeSPDIF)) {
mInputSelector->removeAvailableSelection(kIOAudioInputPortSubTypeSPDIF);
debugIOLog ( 6, " AppleOnboardAudio[%ld]::updateAllDetectCollection() - kLineInStatus-kInserted - Removed digital input from input selector due to auto input selection", mInstanceIndex);
}
mDetectCollection &= ~kSndHWDigitalInput;
}
if (NULL != mInternalMicrophoneInputString) {
if (FALSE == mInputSelector->valueExists(kIOAudioInputPortSubTypeInternalMicrophone)) {
mInputSelector->addAvailableSelection (kIOAudioInputPortSubTypeInternalMicrophone, mInternalMicrophoneInputString);
debugIOLog ( 6, " AppleOnboardAudio[%ld]::updateAllDetectCollection() - kLineInStatus-kInserted - Added internal microphone to input selector due to auto input selection", mInstanceIndex);
}
mDetectCollection |= kSndHWInternalMicrophone;
}
if (NULL != mLineInputString) {
if (FALSE == mInputSelector->valueExists(kIOAudioInputPortSubTypeLine)) {
mInputSelector->addAvailableSelection (kIOAudioInputPortSubTypeLine, mLineInputString);
debugIOLog ( 6, " AppleOnboardAudio[%ld]::updateAllDetectCollection() - kLineInStatus-kInserted - Added line input to input selector due to auto input selection", mInstanceIndex);
}
}
}
}
else if (newValue == kRemoved)
{
mDetectCollection &= ~kSndHWLineInput;
}
else
{
debugIOLog ( 6, " Unknown line in status.");
}
break;
case kDigitalInStatus:
debugIOLog ( 6, " kDigitalInStatus mDetectCollection prior to modification %lX", mDetectCollection );
if (newValue == kInserted)
{
mDetectCollection |= kSndHWDigitalInput;
if (TRUE == mAutoSelectInput) {
ConfigChangeHelper theConfigChangeHelper(mDriverDMAEngine);
if (kGPIO_Unknown != mPlatformInterface->getComboInJackTypeConnected()) {
if (TRUE == mInputSelector->valueExists(kIOAudioInputPortSubTypeLine)) {
mInputSelector->removeAvailableSelection(kIOAudioInputPortSubTypeLine);
debugIOLog ( 6, " AppleOnboardAudio[%ld]::updateAllDetectCollection() - kDigitalInStatus-kInserted - Removed line input from input selector due to auto input selection", mInstanceIndex);
}
mDetectCollection &= ~kSndHWLineInput;
}
if (TRUE == mInputSelector->valueExists(kIOAudioInputPortSubTypeInternalMicrophone)) {
mInputSelector->removeAvailableSelection ( kIOAudioInputPortSubTypeInternalMicrophone );
debugIOLog ( 6, " AppleOnboardAudio[%ld]::updateAllDetectCollection() - kDigitalInStatus-kInserted - Removed internal microphone from input selector due to auto input selection", mInstanceIndex);
}
mDetectCollection &= ~kSndHWInternalMicrophone;
if (NULL != mDigitalInputString) {
if (FALSE == mInputSelector->valueExists(kIOAudioInputPortSubTypeSPDIF)) {
mInputSelector->addAvailableSelection (kIOAudioInputPortSubTypeSPDIF, mDigitalInputString);
debugIOLog ( 6, " AppleOnboardAudio[%ld]::updateAllDetectCollection() - kDigitalInStatus-kInserted - Added digital input to input selector due to auto input selection", mInstanceIndex);
}
}
}
}
else if (newValue == kRemoved)
{
mDetectCollection &= ~kSndHWDigitalInput;
if (TRUE == mAutoSelectInput) {
ConfigChangeHelper theConfigChangeHelper(mDriverDMAEngine);
if (TRUE == mInputSelector->valueExists(kIOAudioInputPortSubTypeSPDIF)) {
mInputSelector->removeAvailableSelection ( kIOAudioInputPortSubTypeSPDIF );
debugIOLog ( 6, " AppleOnboardAudio[%ld]::updateAllDetectCollection() - kDigitalInStatus-kRemoved - Removed digital input from input selector due to auto input selection", mInstanceIndex);
}
if (NULL != mInternalMicrophoneInputString) {
if (FALSE == mInputSelector->valueExists(kIOAudioInputPortSubTypeInternalMicrophone)) {
mInputSelector->addAvailableSelection ( kIOAudioInputPortSubTypeInternalMicrophone, mInternalMicrophoneInputString );
debugIOLog ( 6, " AppleOnboardAudio[%ld]::updateAllDetectCollection() - kDigitalInStatus-kRemoved - Added internal microphone to input selector due to auto input selection", mInstanceIndex);
}
mDetectCollection |= kSndHWInternalMicrophone;
}
if (NULL != mLineInputString) {
if (FALSE == mInputSelector->valueExists(kIOAudioInputPortSubTypeLine)) {
mInputSelector->addAvailableSelection (kIOAudioInputPortSubTypeLine, mLineInputString);
debugIOLog ( 6, " AppleOnboardAudio[%ld]::updateAllDetectCollection() - kLineInStatus-kInserted - Added line input to input selector due to auto input selection", mInstanceIndex);
}
}
}
}
else
{
debugIOLog ( 6, " Unknown digital in status.");
}
break;
case kExtSpeakersStatus: debugIOLog ( 6, " kExtSpeakersStatus mDetectCollection prior to modification %lX", mDetectCollection );
if (newValue == kInserted)
{
mDetectCollection &= ~kSndHWInternalSpeaker;
mDetectCollection |= kSndHWCPUExternalSpeaker;
if ( ( 0 != mInternalSpeakerOutputString ) && ( 0 != mExternalSpeakerOutputString ) )
{
debugIOLog ( 5, " ** AppleOnboardAudio[%ld]::updateDetectCollection invoking 'ConfigChangeHelper'", mInstanceIndex );
ConfigChangeHelper theConfigeChangeHelper(mDriverDMAEngine);
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeInternalSpeaker );
debugIOLog ( 6, " removed internal speaker from output selector ***");
mOutputSelector->addAvailableSelection (kIOAudioOutputPortSubTypeExternalSpeaker, mExternalSpeakerOutputString);
}
debugIOLog ( 6, " external speakers inserted, mDetectCollection = %lX", mDetectCollection);
}
else if (newValue == kRemoved)
{
mDetectCollection &= ~kSndHWCPUExternalSpeaker;
mDetectCollection |= kSndHWInternalSpeaker;
if ( ( 0 != mInternalSpeakerOutputString ) && ( 0 != mExternalSpeakerOutputString ) )
{
debugIOLog ( 5, " ** AppleOnboardAudio[%ld]::updateDetectCollection invoking 'ConfigChangeHelper'", mInstanceIndex );
ConfigChangeHelper theConfigeChangeHelper(mDriverDMAEngine);
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeExternalSpeaker );
debugIOLog ( 6, " removed External Speaker from output selector");
mOutputSelector->addAvailableSelection (kIOAudioOutputPortSubTypeInternalSpeaker, mInternalSpeakerOutputString);
}
debugIOLog ( 6, " external speakers removed, mDetectCollection = %lX", mDetectCollection);
}
else
{
debugIOLog ( 6, " Unknown external speakers jack status, mDetectCollection = %lX", mDetectCollection);
}
break; }
debugIOLog ( 5, "- AppleOnboardAudio[%ld]::updateAllDetectCollection ( %ld, %ld ), mDetectCollection = %lX", mInstanceIndex, statusSelector, newValue, mDetectCollection );
}
UInt32 AppleOnboardAudio::getSelectorCodeForOutputEvent (UInt32 eventSelector) {
UInt32 selectorCode;
selectorCode = kIOAudioOutputPortSubTypeInternalSpeaker;
if (kLineOutStatus == eventSelector) {
if ( mDetectCollection & kSndHWLineOutput ) {
selectorCode = kIOAudioOutputPortSubTypeLine;
} else if ( mDetectCollection & kSndHWCPUHeadphone ) {
selectorCode = kIOAudioOutputPortSubTypeHeadphones;
} else if ( mDetectCollection & kSndHWDigitalOutput ) {
selectorCode = kIOAudioOutputPortSubTypeSPDIF;
} else if ( mDetectCollection & kSndHWCPUExternalSpeaker ) { selectorCode = kIOAudioOutputPortSubTypeExternalSpeaker;
} else if ( mDetectCollection & kSndHWInternalSpeaker ) {
selectorCode = kIOAudioOutputPortSubTypeInternalSpeaker;
} else {
debugIOLog ( 3, " UNKNOWN device so selecting INTERNAL SPEAKER" );
selectorCode = kIOAudioOutputPortSubTypeInternalSpeaker;
mDetectCollection |= kSndHWInternalSpeaker;
} } else if (kHeadphoneStatus == eventSelector) {
if ( mDetectCollection & kSndHWCPUHeadphone ) {
selectorCode = kIOAudioOutputPortSubTypeHeadphones;
} else if ( mDetectCollection & kSndHWLineOutput ) {
selectorCode = kIOAudioOutputPortSubTypeLine;
} else if ( mDetectCollection & kSndHWDigitalOutput ) {
selectorCode = kIOAudioOutputPortSubTypeSPDIF;
} else if ( mDetectCollection & kSndHWCPUExternalSpeaker ) { selectorCode = kIOAudioOutputPortSubTypeExternalSpeaker;
} else if ( mDetectCollection & kSndHWInternalSpeaker ) {
selectorCode = kIOAudioOutputPortSubTypeInternalSpeaker;
} else { debugIOLog ( 3, " UNKNOWN device so selecting INTERNAL SPEAKER" );
selectorCode = kIOAudioOutputPortSubTypeInternalSpeaker;
mDetectCollection |= kSndHWInternalSpeaker;
}
} else if (kExtSpeakersStatus == eventSelector) { if ( mDetectCollection & kSndHWLineOutput ) {
selectorCode = kIOAudioOutputPortSubTypeLine;
} else if ( mDetectCollection & kSndHWCPUHeadphone ) {
selectorCode = kIOAudioOutputPortSubTypeHeadphones;
} else if ( mDetectCollection & kSndHWDigitalOutput ) {
selectorCode = kIOAudioOutputPortSubTypeSPDIF;
} else if ( mDetectCollection & kSndHWCPUExternalSpeaker ) {
selectorCode = kIOAudioOutputPortSubTypeExternalSpeaker;
} else if ( mDetectCollection & kSndHWInternalSpeaker ) {
selectorCode = kIOAudioOutputPortSubTypeInternalSpeaker;
} else {
debugIOLog ( 3, " UNKNOWN device so selecting INTERNAL SPEAKER" );
selectorCode = kIOAudioOutputPortSubTypeInternalSpeaker;
mDetectCollection |= kSndHWInternalSpeaker;
}
} else if (kDigitalOutStatus == eventSelector) {
if ( mDetectCollection & kSndHWDigitalOutput ) {
selectorCode = kIOAudioOutputPortSubTypeSPDIF;
} else if ( mDetectCollection & kSndHWLineOutput ) {
selectorCode = kIOAudioOutputPortSubTypeLine;
} else if ( mDetectCollection & kSndHWCPUHeadphone ) {
selectorCode = kIOAudioOutputPortSubTypeHeadphones;
} else if ( mDetectCollection & kSndHWCPUExternalSpeaker ) {
selectorCode = kIOAudioOutputPortSubTypeExternalSpeaker;
} else if ( mDetectCollection & kSndHWInternalSpeaker ) {
selectorCode = kIOAudioOutputPortSubTypeInternalSpeaker;
} else {
debugIOLog ( 3, "UNKNOWN device so selecting INTERNAL SPEAKER" );
selectorCode = kIOAudioOutputPortSubTypeInternalSpeaker;
mDetectCollection |= kSndHWInternalSpeaker;
}
}
switch ( eventSelector ) {
case kLineOutStatus: debugIOLog ( 5, "± AppleOnboardAudio[%ld]::getSelectorCodeForOutputEvent ( %ld kLineOutStatus ), mDetectCollection %lX, returns '%4s'", mInstanceIndex, eventSelector, mDetectCollection, (char*)&selectorCode ); break;
case kHeadphoneStatus: debugIOLog ( 5, "± AppleOnboardAudio[%ld]::getSelectorCodeForOutputEvent ( %ld kHeadphoneStatus ), mDetectCollection %lX, returns '%4s'", mInstanceIndex, eventSelector, mDetectCollection, (char*)&selectorCode ); break;
case kExtSpeakersStatus: debugIOLog ( 5, "± AppleOnboardAudio[%ld]::getSelectorCodeForOutputEvent ( %ld kExtSpeakersStatus ), mDetectCollection %lX, returns '%4s'", mInstanceIndex, eventSelector, mDetectCollection, (char*)&selectorCode ); break;
case kDigitalOutStatus: debugIOLog ( 5, "± AppleOnboardAudio[%ld]::getSelectorCodeForOutputEvent ( %ld kDigitalOutStatus ), mDetectCollection %lX, returns '%4s'", mInstanceIndex, eventSelector, mDetectCollection, (char*)&selectorCode ); break;
case kInternalSpeakerStatus: debugIOLog ( 5, "± AppleOnboardAudio[%ld]::getSelectorCodeForOutputEvent ( %ld kInternalSpeakerStatus ), mDetectCollection %lX, returns '%4s'", mInstanceIndex, eventSelector, mDetectCollection, (char*)&selectorCode ); break;
default: debugIOLog ( 5, "± AppleOnboardAudio[%ld]::getSelectorCodeForOutputEvent ( %ld ), mDetectCollection %lX, returns '%4s'", mInstanceIndex, eventSelector, mDetectCollection, (char*)&selectorCode ); break;
}
return selectorCode;
}
void AppleOnboardAudio::selectOutputAmplifiers (const UInt32 inSelection, const bool inMuteState, const bool inUpdateAll)
{
bool needToWaitForAmps;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::selectOutputAmplifiers '%4s', inMuteState = %d", mInstanceIndex, (char *)&(inSelection), inMuteState );
needToWaitForAmps = true;
if (FALSE == inMuteState) {
switch (inSelection) {
case kIOAudioOutputPortSubTypeHeadphones:
debugIOLog ( 3, " [AOA] switching amps to headphones. mEncodedOutputFormat %d", mEncodedOutputFormat );
mPlatformInterface->setSpeakerMuteState ( kGPIO_Muted );
if (!mEncodedOutputFormat) {
mPlatformInterface->setHeadphoneMuteState ( kGPIO_Unmuted );
}
if ((mDetectCollection & kSndHWLineOutput) && !mEncodedOutputFormat) {
mPlatformInterface->setLineOutMuteState ( kGPIO_Unmuted );
}
break;
case kIOAudioOutputPortSubTypeLine:
debugIOLog ( 3, " [AOA] switching amps to line output. mEncodedOutputFormat %d", mEncodedOutputFormat );
mPlatformInterface->setSpeakerMuteState ( kGPIO_Muted );
if (!mEncodedOutputFormat) {
mPlatformInterface->setLineOutMuteState ( kGPIO_Unmuted );
}
if ((mDetectCollection & kSndHWCPUHeadphone) && !mEncodedOutputFormat) {
mPlatformInterface->setHeadphoneMuteState ( kGPIO_Unmuted );
}
break;
case kIOAudioOutputPortSubTypeExternalSpeaker: case kIOAudioOutputPortSubTypeInternalSpeaker:
debugIOLog ( 3, " [AOA] switching amps to speakers. mEncodedOutputFormat %d", mEncodedOutputFormat );
if (!mEncodedOutputFormat) {
mPlatformInterface->setSpeakerMuteState ( kGPIO_Unmuted );
mPlatformInterface->setLineOutMuteState ( kGPIO_Muted );
mPlatformInterface->setHeadphoneMuteState ( kGPIO_Muted );
}
break;
case kIOAudioOutputPortSubTypeSPDIF:
debugIOLog ( 3, " [AOA] switching to S/PDIF Digital Output. mEncodedOutputFormat %d", mEncodedOutputFormat );
mPlatformInterface->setSpeakerMuteState ( kGPIO_Muted );
if (mEncodedOutputFormat) {
mPlatformInterface->setLineOutMuteState ( kGPIO_Muted );
mPlatformInterface->setHeadphoneMuteState ( kGPIO_Muted );
} else {
if (inUpdateAll) {
if ((mDetectCollection & kSndHWCPUHeadphone) && !inMuteState) {
mPlatformInterface->setHeadphoneMuteState ( kGPIO_Unmuted );
if ( mDetectCollection & kSndHWLineOutput ) {
mPlatformInterface->setLineOutMuteState ( kGPIO_Unmuted );
}
} else if (mDetectCollection & kSndHWLineOutput && !inMuteState) {
mPlatformInterface->setLineOutMuteState ( kGPIO_Unmuted );
}
}
}
break;
default:
debugIOLog ( 3, " Amplifier not changed, selection = %ld", inSelection);
needToWaitForAmps = false;
break;
}
}
if (needToWaitForAmps) {
IOSleep (mAmpRecoveryMuteDuration);
}
mCurrentOutputSelection = inSelection;
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::selectOutputAmplifiers '%4s', inMuteState = %d, mCurrentOutputSelection '%4s'", mInstanceIndex, (char *)&(inSelection), inMuteState, &mCurrentOutputSelection );
return;
}
void AppleOnboardAudio::muteAllAmps() {
mPlatformInterface->setHeadphoneMuteState ( kGPIO_Muted );
mPlatformInterface->setLineOutMuteState ( kGPIO_Muted );
mPlatformInterface->setSpeakerMuteState ( kGPIO_Muted );
IOSleep (mAmpRecoveryMuteDuration);
debugIOLog ( 3, "± AppleOnboardAudio::muteAllAmps ()");
}
void AppleOnboardAudio::free()
{
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::free", mInstanceIndex);
removeTimerEvent ( this );
if (mDriverDMAEngine) {
debugIOLog ( 3, " AppleOnboardAudio[%ld]::free - mDriverDMAEngine retain count = %d", mInstanceIndex, mDriverDMAEngine->getRetainCount());
mDriverDMAEngine->release();
mDriverDMAEngine = 0;
}
#ifdef THREAD_POWER_MANAGEMENT
if (0 != mPowerThread) {
thread_call_free (mPowerThread);
}
#endif
CLEAN_RELEASE(mOutMuteControl);
CLEAN_RELEASE(mHeadphoneConnected);
CLEAN_RELEASE(mOutLeftVolumeControl);
CLEAN_RELEASE(mOutRightVolumeControl);
CLEAN_RELEASE(mOutMasterVolumeControl);
CLEAN_RELEASE(mInLeftGainControl);
CLEAN_RELEASE(mInRightGainControl);
CLEAN_RELEASE(mInMasterGainControl);
CLEAN_RELEASE(mOutputSelector);
CLEAN_RELEASE(mInputSelector);
CLEAN_RELEASE(mPluginObjects);
CLEAN_RELEASE(mTransportInterface);
CLEAN_RELEASE(mPlatformInterface);
CLEAN_RELEASE(mSignal);
super::free();
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::free, (void)", mInstanceIndex);
}
#pragma mark +PORT HANDLER FUNCTIONS
void AppleOnboardAudio::setCurrentDevices(UInt32 devices){
UInt32 odevice;
odevice = 0;
if (devices != currentDevices) {
odevice = currentDevices;
currentDevices = devices;
}
debugIOLog ( 3, "± AppleOnboardAudio[%ld]::setCurrentDevices ( %ld ), currentDevices = %ld", mInstanceIndex, devices, currentDevices);
if (devices & kSndHWInputDevices || odevice & kSndHWInputDevices) {
if (0 != mInputConnectionControl) {
OSNumber * inputState;
UInt32 active;
active = devices & kSndHWInputDevices ? 1 : 0; inputState = OSNumber::withNumber ((long long unsigned int)active, 32);
(void)mInputConnectionControl->hardwareValueChanged (inputState);
inputState->release ();
}
}
}
AudioHardwareObjectInterface * AppleOnboardAudio::getIndexedPluginObject (UInt32 index) {
AudioHardwareObjectInterface * thePluginObject;
OSObject * theObject;
thePluginObject = 0;
theObject = mPluginObjects->getObject(index);
if (0 != theObject) {
thePluginObject = (AudioHardwareObjectInterface *)(theObject->metaCast("AudioHardwareObjectInterface"));
}
return thePluginObject;
}
PlatformInterface * AppleOnboardAudio::getPlatformInterfaceObject () {
return mPlatformInterface;
}
#pragma mark +INTERRUPTS
void AppleOnboardAudio::softwareInterruptHandler (OSObject *object, IOInterruptEventSource *source, int count) {
AppleOnboardAudio * aoa;
UInt16 cachedProducerCount;
aoa = OSDynamicCast (AppleOnboardAudio, object);
FailIf ( 0 == aoa, Exit );
for ( UInt32 index = 0; index < kNumberOfActionSelectors; index++ ) {
cachedProducerCount = aoa->mInterruptProduced[index];
if ( 0 != cachedProducerCount - aoa->mInterruptConsumed[index] ) {
aoa->interruptEventHandler ( index, 0 ); aoa->mInterruptConsumed[index] = cachedProducerCount;
}
}
Exit:
return;
}
void AppleOnboardAudio::interruptEventHandler (UInt32 statusSelector, UInt32 newValue) {
IOCommandGate * cg;
debugIOLog ( 6, "+ AppleOnboardAudio::interruptEventHandler ( %d, %d )", statusSelector, newValue );
cg = getCommandGate ();
debugIOLog ( 6, " cg %p", cg );
if (0 != cg) {
cg->runAction (interruptEventHandlerAction, (void *)statusSelector, (void *)newValue);
}
debugIOLog ( 6, "- AppleOnboardAudio::interruptEventHandler ( %d, %d )", statusSelector, newValue );
return;
}
IOReturn AppleOnboardAudio::interruptEventHandlerAction (OSObject * owner, void * arg1, void * arg2, void * arg3, void * arg4) {
IOReturn result;
AppleOnboardAudio * aoa;
result = kIOReturnError;
aoa = (AppleOnboardAudio *)owner;
FailIf (0 == aoa, Exit);
aoa->protectedInterruptEventHandler ((UInt32)arg1, (UInt32)arg2);
result = kIOReturnSuccess;
Exit:
return result;
}
bool AppleOnboardAudio::isTargetForMessage ( UInt32 actionSelector, AppleOnboardAudio * theAOA ) {
OSArray * swInterruptsArray;
OSString * theInterruptString;
UInt32 interruptCount;
bool result = FALSE;
swInterruptsArray = OSDynamicCast ( OSArray, getLayoutEntry ( kSWInterrupts, theAOA ) );
FailIf (0 == swInterruptsArray, Exit);
interruptCount = swInterruptsArray->getCount ();
for ( UInt32 index = 0; index < interruptCount; index++ ) {
theInterruptString = OSDynamicCast ( OSString, swInterruptsArray->getObject ( index ) );
if ( 0 != theInterruptString ) {
switch ( actionSelector ) {
case kClockLockStatus:
if ( !strcmp ( kClockLockIntMessage, theInterruptString->getCStringNoCopy() ) ) {
debugIOLog ( 5, "± AppleOnboardAudio[%ld]::isTargetForMessage ( 0x%0.8X, %p ) is for kClockLockStatus", mInstanceIndex, actionSelector, theAOA);
result = TRUE;
}
break;
case kClockUnLockStatus:
if ( !strcmp ( kClockUnLockIntMessage, theInterruptString->getCStringNoCopy() ) ) {
debugIOLog ( 5, "± AppleOnboardAudio[%ld]::isTargetForMessage ( 0x%0.8X, %p ) is for kClockUnLockStatus", mInstanceIndex, actionSelector, theAOA);
result = TRUE;
}
break;
case kDigitalInInsertStatus:
if ( !strcmp ( kDigitalInInsertIntMessage, theInterruptString->getCStringNoCopy() ) ) {
debugIOLog ( 5, "± AppleOnboardAudio[%ld]::isTargetForMessage ( 0x%0.8X, %p ) is for kDigitalInInsertStatus", mInstanceIndex, actionSelector, theAOA);
result = TRUE;
}
break;
case kDigitalInRemoveStatus:
if ( !strcmp ( kDigitalInRemoveIntMessage, theInterruptString->getCStringNoCopy() ) ) {
debugIOLog ( 5, "± AppleOnboardAudio[%ld]::isTargetForMessage ( 0x%0.8X, %p ) is for kDigitalInRemoveStatus", mInstanceIndex, actionSelector, theAOA);
result = TRUE;
}
break;
case kRemoteActive: if ( !strcmp ( kRemoteActiveMessage, theInterruptString->getCStringNoCopy() ) ) {
debugIOLog ( 5, "± AppleOnboardAudio[%ld]::isTargetForMessage ( 0x%0.8X, %p ) is for kRemoteActive", mInstanceIndex, actionSelector, theAOA);
result = TRUE;
}
break;
case kRemoteIdle: if ( !strcmp ( kRemoteIdleMessage, theInterruptString->getCStringNoCopy() ) ) {
debugIOLog ( 5, "± AppleOnboardAudio[%ld]::isTargetForMessage ( 0x%0.8X, %p ) is for kRemoteIdle", mInstanceIndex, actionSelector, theAOA);
result = TRUE;
}
break;
case kRemoteSleep: if ( !strcmp ( kRemoteSleepMessage, theInterruptString->getCStringNoCopy() ) ) {
debugIOLog ( 5, "± AppleOnboardAudio[%ld]::isTargetForMessage ( 0x%0.8X, %p ) is for kRemoteSleep", mInstanceIndex, actionSelector, theAOA);
result = TRUE;
}
break;
case kRemoteChildSleep: if ( !strcmp ( kRemoteChildSleepMessage, theInterruptString->getCStringNoCopy() ) ) {
debugIOLog ( 5, "± AppleOnboardAudio[%ld]::isTargetForMessage ( 0x%0.8X, %p ) is for kRemoteChildSleep", mInstanceIndex, actionSelector, theAOA);
result = TRUE;
}
break;
case kRemoteChildIdle: if ( !strcmp ( kRemoteChildIdleMessage, theInterruptString->getCStringNoCopy() ) ) {
debugIOLog ( 5, "± AppleOnboardAudio[%ld]::isTargetForMessage ( 0x%0.8X, %p ) is for kRemoteChildIdle", mInstanceIndex, actionSelector, theAOA);
result = TRUE;
}
break;
case kRemoteChildActive: if ( !strcmp ( kRemoteChildActiveMessage, theInterruptString->getCStringNoCopy() ) ) {
debugIOLog ( 5, "± AppleOnboardAudio[%ld]::isTargetForMessage ( 0x%0.8X, %p ) is for kRemoteChildActive", mInstanceIndex, actionSelector, theAOA);
result = TRUE;
}
break;
case kAOAPowerParent: if ( !strcmp ( kAOAPowerParentMessage, theInterruptString->getCStringNoCopy() ) ) {
debugIOLog ( 5, "± AppleOnboardAudio[%ld]::isTargetForMessage ( 0x%0.8X, %p ) is for kAOAPowerParent", mInstanceIndex, actionSelector, theAOA);
result = TRUE;
}
break;
default:
debugIOLog ( 5, "± AppleOnboardAudio[%ld]::isTargetForMessage ( 0x%0.8X, %p ) is USELESS!", mInstanceIndex, actionSelector, theAOA);
FailMessage ( TRUE );
break;
}
}
}
Exit:
return result;
}
void AppleOnboardAudio::protectedInterruptEventHandler (UInt32 statusSelector, UInt32 newValue) {
AudioHardwareObjectInterface * thePlugin;
OSNumber * connectionCodeNumber;
char * pluginString;
UInt32 selectorCode;
switch ( statusSelector ) {
case kInternalSpeakerStatus: debugIOLog ( 7, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kInternalSpeakerStatus, %ld )", mInstanceIndex, newValue); break;
case kHeadphoneStatus: debugIOLog ( 6, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kHeadphoneStatus, %ld )", mInstanceIndex, newValue); break;
case kExtSpeakersStatus: debugIOLog ( 6, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kExtSpeakersStatus, %ld )", mInstanceIndex, newValue); break;
case kLineOutStatus: debugIOLog ( 6, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kLineOutStatus, %ld )", mInstanceIndex, newValue); break;
case kDigitalInStatus: debugIOLog ( 6, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kDigitalInStatus, %ld )", mInstanceIndex, newValue); break;
case kDigitalOutStatus: debugIOLog ( 6, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kDigitalOutStatus, %ld )", mInstanceIndex, newValue); break;
case kLineInStatus: debugIOLog ( 6, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kLineInStatus, %ld )", mInstanceIndex, newValue); break;
case kInputMicStatus: debugIOLog ( 7, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kInputMicStatus, %ld )", mInstanceIndex, newValue); break;
case kExternalMicInStatus: debugIOLog ( 7, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kExternalMicInStatus, %ld )", mInstanceIndex, newValue); break;
case kDigitalInInsertStatus: debugIOLog ( 6, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kDigitalInInsertStatus, %ld )", mInstanceIndex, newValue); break;
case kDigitalInRemoveStatus: debugIOLog ( 6, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kDigitalInRemoveStatus, %ld )", mInstanceIndex, newValue); break;
case kRequestCodecRecoveryStatus: debugIOLog ( 7, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kRequestCodecRecoveryStatus, %ld )", mInstanceIndex, newValue); break;
case kClockInterruptedRecovery: debugIOLog ( 7, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kClockInterruptedRecovery, %ld )", mInstanceIndex, newValue); break;
case kClockUnLockStatus: debugIOLog ( 6, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kClockUnLockStatus, %ld )", mInstanceIndex, newValue); break;
case kClockLockStatus: debugIOLog ( 6, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kClockLockStatus, %ld )", mInstanceIndex, newValue); break;
case kAES3StreamErrorStatus: debugIOLog ( 7, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kAES3StreamErrorStatus, %ld )", mInstanceIndex, newValue); break;
case kCodecErrorInterruptStatus: debugIOLog ( 6, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kCodecErrorInterruptStatus, %ld )", mInstanceIndex, newValue); break;
case kCodecInterruptStatus: debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kCodecInterruptStatus, %ld )", mInstanceIndex, newValue); break;
case kBreakClockSelect: debugIOLog ( 7, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kBreakClockSelect, %ld )", mInstanceIndex, newValue); break;
case kMakeClockSelect: debugIOLog ( 7, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kMakeClockSelect, %ld )", mInstanceIndex, newValue); break;
case kSetSampleRate: debugIOLog ( 7, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kSetSampleRate, %ld )", mInstanceIndex, newValue); break;
case kSetSampleBitDepth: debugIOLog ( 7, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kSetSampleBitDepth, %ld )", mInstanceIndex, newValue); break;
case kPowerStateChange: debugIOLog ( 7, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kPreDMAEngineInit, %ld )", mInstanceIndex, newValue); break;
case kPreDMAEngineInit: debugIOLog ( 7, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kPreDMAEngineInit, %ld )", mInstanceIndex, newValue); break;
case kPostDMAEngineInit: debugIOLog ( 7, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kPostDMAEngineInit, %ld )", mInstanceIndex, newValue); break;
case kRestartTransport: debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kRestartTransport, %ld )", mInstanceIndex, newValue); break;
case kRemoteActive: debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kRemoteActive, %ld )", mInstanceIndex, newValue); break; case kRemoteSleep: debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kRemoteSleep, %ld )", mInstanceIndex, newValue); break; case kRemoteIdle: debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kRemoteIdle, %ld )", mInstanceIndex, newValue); break; case kRemoteChildSleep: debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kRemoteChildSleep, %ld )", mInstanceIndex, newValue); break; case kRemoteChildIdle: debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kRemoteChildIdle, %ld )", mInstanceIndex, newValue); break; case kRemoteChildActive: debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kRemoteChildActive, %ld )", mInstanceIndex, newValue); break; default: debugIOLog ( 7, "+ AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( 0x%0.8X, %ld )", mInstanceIndex, statusSelector, newValue); break; }
if ( !executeProtectedInterruptEventHandlerWhenInactive ( statusSelector ) )
{
goto Exit; }
selectorCode = getCharCodeForIntCode (statusSelector);
switch (statusSelector) {
case kDigitalOutStatus:
startDetectInterruptService (); mDriverDMAEngine->updateOutputStreamFormats ();
if (TRUE == mEncodedOutputFormat && TRUE == mDriverDMAEngine->isMixable ()) {
mEncodedOutputFormat = FALSE;
}
case kInternalSpeakerStatus:
case kHeadphoneStatus:
case kLineOutStatus:
case kExtSpeakersStatus: if ( kDigitalOutStatus != statusSelector )
{
startDetectInterruptService (); }
updateAllDetectCollection (statusSelector, newValue);
selectorCode = getSelectorCodeForOutputEvent (statusSelector);
if (kGPIO_Unknown == mPlatformInterface->getComboOutJackTypeConnected()) {
if (mCurrentOutputSelection == kIOAudioOutputPortSubTypeSPDIF && mEncodedOutputFormat && selectorCode != kIOAudioOutputPortSubTypeSPDIF) {
goto Exit;
}
}
if ( mCurrentOutputSelection != selectorCode ) {
connectionCodeNumber = OSNumber::withNumber (selectorCode, 32);
debugIOLog ( 5, " selectorCode = '%4s', connectionCodeNumber = %ld", &selectorCode, connectionCodeNumber );
pluginString = getConnectionKeyFromCharCode (selectorCode, kIOAudioStreamDirectionOutput);
debugIOLog ( 3, " pluginString updated to '%s'.", pluginString);
thePlugin = getPluginObjectForConnection (pluginString);
FailWithAction (0 == thePlugin, endDetectInterruptService (), Exit);
cacheOutputVolumeLevels (mCurrentOutputPlugin);
mCurrentOutputPlugin = thePlugin;
setClipRoutineForOutput (pluginString);
selectCodecOutputWithMuteState( mIsMute );
selectOutputAmplifiers (selectorCode, mIsMute);
if (0 == mOutputSelector) debugIOLog ( 3, "\n!!! mOutputSelector = 0!!!");
FailWithAction (0 == mOutputSelector, endDetectInterruptService (), Exit);
mOutputSelector->hardwareValueChanged (connectionCodeNumber);
setSoftwareOutputDSP (pluginString);
connectionCodeNumber->release();
AdjustOutputVolumeControls (thePlugin, selectorCode);
OSNumber * headphoneState;
if (mDetectCollection & kSndHWCPUHeadphone) {
headphoneState = OSNumber::withNumber (1, 32);
} else {
headphoneState = OSNumber::withNumber ((long long unsigned int)0, 32);
}
mHeadphoneConnected->hardwareValueChanged (headphoneState);
headphoneState->release ();
}
endDetectInterruptService (); break;
case kExternalMicInStatus:
startDetectInterruptService (); updateAllDetectCollection (statusSelector, newValue);
endDetectInterruptService (); break;
case kLineInStatus:
startDetectInterruptService (); updateAllDetectCollection (statusSelector, newValue);
pluginString = getConnectionKeyFromCharCode (selectorCode, kIOAudioStreamDirectionInput);
thePlugin = getPluginObjectForConnection (pluginString);
FailIf (0 == thePlugin, Exit);
FailIf (0 == mInputSelector, Exit);
selectorCode = mInputSelector->getIntValue ();
if ((mDetectCollection & kSndHWLineInput) && (kIOAudioInputPortSubTypeLine == selectorCode)) {
thePlugin->setInputMute (FALSE);
} else if (!(mDetectCollection & kSndHWLineInput) && (kIOAudioInputPortSubTypeLine == selectorCode)) {
thePlugin->setInputMute (TRUE);
}
if ( mAutoSelectInput ) {
if (!(mDetectCollection & kSndHWLineInput) && (kIOAudioInputPortSubTypeLine == selectorCode)) {
debugIOLog(6, "AppleOnboardAudio[%ld]::protectedInterruptEventHandler - kLineInStatus posted...line in disconnected while selected (mAutoSelectInput = %d)", mInstanceIndex, mAutoSelectInput);
}
else if (mDetectCollection & kSndHWLineInput) {
debugIOLog(6, "AppleOnboardAudio[%ld]::protectedInterruptEventHandler - kLineInStatus posted...line in connected (mAutoSelectInput = %d)", mInstanceIndex, mAutoSelectInput);
if (kIOReturnSuccess == inputSelectorChanged(kIOAudioInputPortSubTypeLine)) {
connectionCodeNumber = OSNumber::withNumber (kIOAudioInputPortSubTypeLine, 32);
mInputSelector->hardwareValueChanged (connectionCodeNumber);
connectionCodeNumber->release();
}
}
else {
debugIOLog(6, "AppleOnboardAudio[%ld]::protectedInterruptEventHandler - kLineInStatus posted...line in disconnected while not selected (mAutoSelectInput = %d)", mInstanceIndex, mAutoSelectInput);
}
}
endDetectInterruptService (); break;
case kDigitalInStatus:
startDetectInterruptService ();
if ( mAutoSelectClock && ( kClockLockStatus == mCodecLockStatus ) && ( kClockSourceSelectionExternal == mCurrentClockSelector ) && ( kRemoved == newValue ) ) {
muteAllAmps();
}
else if ( mAutoSelectClock && ( kClockLockStatus == mCodecLockStatus ) && ( kInserted == newValue ) ) { selectCodecOutputWithMuteState (mIsMute);
if ( 0 != mOutputSelector ) {
selectOutputAmplifiers (mOutputSelector->getIntValue (), mIsMute);
}
}
updateAllDetectCollection (statusSelector, newValue);
mDigitalInsertStatus = ( kInserted == newValue ) ? kGPIO_Connected : kGPIO_Disconnected;
if ( mAutoSelectClock ) {
if ( kInserted == newValue ) {
debugIOLog( 5, "AppleOnboardAudio[%ld]::protectedInterruptEventHandler - digital-in inserted...enabling auto clock selection", mInstanceIndex );
mDisableAutoSelectClock = FALSE;
}
else if ( kRemoved == newValue ) {
debugIOLog( 5, "AppleOnboardAudio[%ld]::protectedInterruptEventHandler - digital-in removed...disabling auto clock selection", mInstanceIndex );
mDisableAutoSelectClock = TRUE;
}
else {
debugIOLog( 5, "AppleOnboardAudio[%ld]::protectedInterruptEventHandler - unknown digital-in status", mInstanceIndex );
}
}
if ( mAutoSelectInput ) {
if ( kInserted == newValue ) {
debugIOLog(6, "AppleOnboardAudio[%ld]::protectedInterruptEventHandler - kDigitalInStatus posted...digital in connected (mAutoSelectInput = %d)", mInstanceIndex, mAutoSelectInput);
if (kIOReturnSuccess == inputSelectorChanged(kIOAudioInputPortSubTypeSPDIF)) {
connectionCodeNumber = OSNumber::withNumber (kIOAudioInputPortSubTypeSPDIF, 32);
mInputSelector->hardwareValueChanged (connectionCodeNumber);
connectionCodeNumber->release();
}
}
else {
debugIOLog(6, "AppleOnboardAudio[%ld]::protectedInterruptEventHandler - kDigitalInStatus posted...digital in disconnected (mAutoSelectInput = %d)", mInstanceIndex, mAutoSelectInput);
if (kIOReturnSuccess == inputSelectorChanged(kIOAudioInputPortSubTypeLine)) {
connectionCodeNumber = OSNumber::withNumber (kIOAudioInputPortSubTypeLine, 32);
mInputSelector->hardwareValueChanged (connectionCodeNumber);
connectionCodeNumber->release();
}
}
}
endDetectInterruptService (); break;
case kDigitalInInsertStatus:
case kDigitalInRemoveStatus:
startDetectInterruptService (); updateAllDetectCollection (kDigitalInStatus, newValue);
mDigitalInsertStatus = ( kDigitalInInsertStatus == statusSelector ) ? kGPIO_Connected : kGPIO_Disconnected;
callPluginsInOrder ( kDigitalInStatus, mDigitalInsertStatus );
endDetectInterruptService (); break;
case kRequestCodecRecoveryStatus:
callPluginsInOrder (kRequestCodecRecoveryStatus, newValue);
break;
case kRestartTransport:
if (0 != mTransportInterface) {
mTransportInterface->restartTransport (); }
break;
case kCodecErrorInterruptStatus:
callPluginsInOrder ( kCodecErrorInterruptStatus, 0 );
break;
case kCodecInterruptStatus:
callPluginsInOrder ( kCodecInterruptStatus, 0 );
break;
case kClockUnLockStatus:
case kClockLockStatus:
if ( mRemoteNonDetectInterruptEnabled ) {
if ( mCodecLockStatus != statusSelector ) { if ( kClockLockStatus == statusSelector ) { if ( mAutoSelectClock && ( FALSE == mDisableAutoSelectClock ) ) {
if ( !mClockSelectInProcessSemaphore ) {
if ( kClockSourceSelectionExternal != mCurrentClockSelector ) {
muteAllAmps ();
callPluginsInOrder ( kSetMuteState, TRUE );
if (NULL != mExternalClockSelector) {
ConfigChangeHelper theConfigChangeHelper(mDriverDMAEngine);
OSNumber * clockSourceSelector = OSNumber::withNumber ( kClockSourceSelectionExternal, 32 );
debugIOLog(5, "AppleOnboardAudio::protectedInterruptEventHandler - Auto Clock Select - changing clock source selection to external");
mExternalClockSelector->removeAvailableSelection(kClockSourceSelectionInternal);
mExternalClockSelector->addAvailableSelection(kClockSourceSelectionExternal, kExternalClockString);
mExternalClockSelector->hardwareValueChanged (clockSourceSelector);
clockSourceSelector->release ();
}
clockSelectorChanged ( kClockSourceSelectionExternal );
}
}
}
debugIOLog ( 5, " ===== AppleOnboardAudio[%ld] CLOCK STATUS changed to kClockLockStatus, mClockSelectInProcessSemaphore = %d", mInstanceIndex, mClockSelectInProcessSemaphore );
UInt32 tempSampleRateWhole = mTransportInterface->transportGetSampleRate ();
if ( mTransportSampleRate.whole != tempSampleRateWhole ) {
mTransportSampleRate.whole = mTransportInterface->transportGetSampleRate (); debugIOLog ( 4, " *** about to [%ld]mDriverDMAEngine->hardwareSampleRateChanged ( %d )", mInstanceIndex, mTransportSampleRate.whole ); mDriverDMAEngine->hardwareSampleRateChanged ( &mTransportSampleRate ); mDriverDMAEngine->updateDSPForSampleRate(mTransportSampleRate.whole); }
} else if ( kClockUnLockStatus == statusSelector ) {
debugIOLog ( 5, " ===== AppleOnboardAudio[%ld] CLOCK STATUS changed to kClockUnLockStatus, mClockSelectInProcessSemaphore = %d", mInstanceIndex, mClockSelectInProcessSemaphore );
}
UInt32 transportType = mTransportInterface->transportGetTransportInterfaceType();
if ( kTransportInterfaceType_I2S_Slave_Only != transportType ) {
mCodecLockStatus = statusSelector;
if ( 0 != mExternalClockSelector ) {
if ( mAutoSelectClock ) { if ( !mClockSelectInProcessSemaphore ) {
if ( kClockUnLockStatus == statusSelector ) {
if ( kClockSourceSelectionInternal != mCurrentClockSelector ) {
ConfigChangeHelper theConfigChangeHelper(mDriverDMAEngine);
OSNumber * clockSourceSelector = OSNumber::withNumber ( kClockSourceSelectionInternal, 32 );
muteAllAmps ();
callPluginsInOrder ( kSetMuteState, TRUE );
debugIOLog(5, "AppleOnboardAudio::protectedInterruptEventHandler - Auto Clock Select - changing clock source selection to internal");
if ( kAutoClockLockStatePendingRelock == newValue ) {
mRelockToExternalClockInProgress = TRUE;
}
mExternalClockSelector->removeAvailableSelection(kClockSourceSelectionExternal);
mExternalClockSelector->addAvailableSelection(kClockSourceSelectionInternal, kInternalClockString);
mExternalClockSelector->hardwareValueChanged (clockSourceSelector);
clockSourceSelector->release ();
clockSelectorChanged ( kClockSourceSelectionInternal );
}
} else {
callPluginsInOrder ( kSetMuteState, mIsMute );
}
} else {
if ( kClockLockStatus == statusSelector ) {
debugIOLog ( 3, " Attempted to post kClockLockStatus blocked by 'mClockSelectInProcessSemaphore' semaphore" );
} else if ( kClockUnLockStatus == statusSelector ) {
debugIOLog ( 3, " Attempted to post kClockUnLockStatus blocked by 'mClockSelectInProcessSemaphore' semaphore" );
}
}
}
}
}
} else {
if ( kClockLockStatus == statusSelector ) {
debugIOLog ( 5, " ===== AppleOnboardAudio[%ld] CLOCK STATUS redundant post of kClockLockStatus, mClockSelectInProcessSemaphore = %d", mInstanceIndex, mClockSelectInProcessSemaphore );
if ( mAutoSelectClock && ( 0 == ( kSndHWDigitalInput & mDetectCollection ) ) && ( kClockSourceSelectionExternal == mCurrentClockSelector ) && ( !mClockSelectInProcessSemaphore ) ) {
ConfigChangeHelper theConfigChangeHelper(mDriverDMAEngine);
OSNumber * clockSourceSelector = OSNumber::withNumber ( kClockSourceSelectionInternal, 32 );
mDisableAutoSelectClock = TRUE;
muteAllAmps ();
callPluginsInOrder ( kSetMuteState, TRUE );
debugIOLog(5, "AppleOnboardAudio::protectedInterruptEventHandler - Auto Clock Select - changing clock source selection to internal due to lock message with non-existent digital-in");
mExternalClockSelector->removeAvailableSelection(kClockSourceSelectionExternal);
mExternalClockSelector->addAvailableSelection(kClockSourceSelectionInternal, kInternalClockString);
mExternalClockSelector->hardwareValueChanged (clockSourceSelector);
clockSourceSelector->release ();
clockSelectorChanged ( kClockSourceSelectionInternal );
}
} else if ( kClockUnLockStatus == statusSelector ) {
debugIOLog ( 5, " ===== AppleOnboardAudio[%ld] CLOCK STATUS redundant post of kClockUnLockStatus, mClockSelectInProcessSemaphore = %d", mInstanceIndex, mClockSelectInProcessSemaphore );
if ( mAutoSelectClock && mRelockToExternalClockInProgress ) {
mRelockToExternalClockPollCount++;
if ( ( kRelockToExternalClockMaxNumPolls == mRelockToExternalClockPollCount ) || ( kAutoClockLockStateNormal == newValue ) ) {
mRelockToExternalClockInProgress = FALSE;
mRelockToExternalClockPollCount = 0;
selectCodecOutputWithMuteState (mIsMute);
if ( 0 != mOutputSelector ) {
selectOutputAmplifiers ( mOutputSelector->getIntValue (), mIsMute);
}
}
}
}
}
broadcastSoftwareInterruptMessage ( statusSelector );
if ( mNeedsLockStatusUpdateToUnmute ) { debugIOLog ( 4, " *** [%ld] about to unmute from mNeedsLockStatusUpdateToUnmute", mInstanceIndex );
mNeedsLockStatusUpdateToUnmute = FALSE;
selectCodecOutputWithMuteState (mIsMute);
if ( 0 != mOutputSelector ) {
selectOutputAmplifiers (mOutputSelector->getIntValue (), mIsMute); }
if (0 != mOutMuteControl) {
mOutMuteControl->flushValue (); }
}
}
else
{
switch ( statusSelector )
{
case kClockUnLockStatus:
debugIOLog ( 6, " ##### kClockUnLockStatus IGNORED - INTERRUPT DISABLED" );
break;
case kClockLockStatus:
debugIOLog ( 6, " ##### kClockLockStatus IGNORED - INTERRUPT DISABLED" );
break;
}
}
break;
case kAES3StreamErrorStatus:
debugIOLog ( 7, " ... kAES3StreamErrorStatus %d", (unsigned int)newValue );
if ( newValue ) {
}
break;
case kRemoteActive: pendingPowerState = kIOAudioDeviceActive;
performPowerStateChangeAction ( (void*)kIOAudioDeviceActive ); break;
case kRemoteIdle: pendingPowerState = kIOAudioDeviceIdle;
performPowerStateChangeAction ( (void*)kIOAudioDeviceIdle ); break;
case kRemoteSleep: pendingPowerState = kIOAudioDeviceSleep;
performPowerStateChangeAction ( (void*)kIOAudioDeviceSleep ); break;
case kRemoteChildSleep:
pendingPowerState = kIOAudioDeviceSleep;
performPowerStateChangeAction ( (void*)kIOAudioDeviceSleep ); break;
case kRemoteChildIdle:
pendingPowerState = kIOAudioDeviceIdle;
performPowerStateChangeAction ( (void*)kIOAudioDeviceIdle ); break;
case kRemoteChildActive:
pendingPowerState = kIOAudioDeviceActive;
performPowerStateChangeAction ( (void*)kIOAudioDeviceActive ); break;
default:
break;
}
Exit:
switch ( statusSelector ) {
case kInternalSpeakerStatus: debugIOLog ( 7, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kInternalSpeakerStatus, %ld )", mInstanceIndex, newValue); break;
case kHeadphoneStatus: debugIOLog ( 6, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kHeadphoneStatus, %ld )", mInstanceIndex, newValue); break;
case kExtSpeakersStatus: debugIOLog ( 6, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kExtSpeakersStatus, %ld )", mInstanceIndex, newValue); break;
case kLineOutStatus: debugIOLog ( 6, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kLineOutStatus, %ld )", mInstanceIndex, newValue); break;
case kDigitalInStatus: debugIOLog ( 6, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kDigitalInStatus, %ld )", mInstanceIndex, newValue); break;
case kDigitalOutStatus: debugIOLog ( 6, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kDigitalOutStatus, %ld )", mInstanceIndex, newValue); break;
case kLineInStatus: debugIOLog ( 6, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kLineInStatus, %ld )", mInstanceIndex, newValue); break;
case kInputMicStatus: debugIOLog ( 7, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kInputMicStatus, %ld )", mInstanceIndex, newValue); break;
case kExternalMicInStatus: debugIOLog ( 7, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kExternalMicInStatus, %ld )", mInstanceIndex, newValue); break;
case kDigitalInInsertStatus: debugIOLog ( 6, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kDigitalInInsertStatus, %ld )", mInstanceIndex, newValue); break;
case kDigitalInRemoveStatus: debugIOLog ( 6, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kDigitalInRemoveStatus, %ld )", mInstanceIndex, newValue); break;
case kRequestCodecRecoveryStatus: debugIOLog ( 7, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kRequestCodecRecoveryStatus, %ld )", mInstanceIndex, newValue); break;
case kClockInterruptedRecovery: debugIOLog ( 7, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kClockInterruptedRecovery, %ld )", mInstanceIndex, newValue); break;
case kClockUnLockStatus: debugIOLog ( 6, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kClockUnLockStatus, %ld )", mInstanceIndex, newValue); break;
case kClockLockStatus: debugIOLog ( 6, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kClockLockStatus, %ld )", mInstanceIndex, newValue); break;
case kAES3StreamErrorStatus: debugIOLog ( 7, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kAES3StreamErrorStatus, %ld )", mInstanceIndex, newValue); break;
case kCodecErrorInterruptStatus: debugIOLog ( 6, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kCodecErrorInterruptStatus, %ld )", mInstanceIndex, newValue); break;
case kCodecInterruptStatus: debugIOLog ( 5, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kCodecInterruptStatus, %ld )", mInstanceIndex, newValue); break;
case kBreakClockSelect: debugIOLog ( 7, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kBreakClockSelect, %ld )", mInstanceIndex, newValue); break;
case kMakeClockSelect: debugIOLog ( 7, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kMakeClockSelect, %ld )", mInstanceIndex, newValue); break;
case kSetSampleRate: debugIOLog ( 7, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kSetSampleRate, %ld )", mInstanceIndex, newValue); break;
case kSetSampleBitDepth: debugIOLog ( 7, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kSetSampleBitDepth, %ld )", mInstanceIndex, newValue); break;
case kPowerStateChange: debugIOLog ( 7, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kPreDMAEngineInit, %ld )", mInstanceIndex, newValue); break;
case kPreDMAEngineInit: debugIOLog ( 7, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kPreDMAEngineInit, %ld )", mInstanceIndex, newValue); break;
case kPostDMAEngineInit: debugIOLog ( 7, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kPostDMAEngineInit, %ld )", mInstanceIndex, newValue); break;
case kRestartTransport: debugIOLog ( 5, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kRestartTransport, %ld )", mInstanceIndex, newValue); break;
case kRemoteActive: debugIOLog ( 5, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kRemoteActive, %ld )", mInstanceIndex, newValue); break; case kRemoteSleep: debugIOLog ( 5, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kRemoteSleep, %ld )", mInstanceIndex, newValue); break; case kRemoteIdle: debugIOLog ( 5, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kRemoteIdle, %ld )", mInstanceIndex, newValue); break; case kRemoteChildSleep: debugIOLog ( 5, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kRemoteChildSleep, %ld )", mInstanceIndex, newValue); break; case kRemoteChildIdle: debugIOLog ( 5, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kRemoteChildIdle, %ld )", mInstanceIndex, newValue); break; case kRemoteChildActive: debugIOLog ( 5, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( kRemoteChildActive, %ld )", mInstanceIndex, newValue); break; default: debugIOLog ( 7, "- AppleOnboardAudio[%ld]::protectedInterruptEventHandler ( 0x%0.8X, %ld )", mInstanceIndex, statusSelector, newValue); break; }
return;
}
bool AppleOnboardAudio::executeProtectedInterruptEventHandlerWhenInactive ( UInt32 selector )
{
bool result = FALSE;
debugIOLog ( 6, "+ AppleOnboardAudio::executeProtectedInterruptEventHandlerWhenInactive (%lx)", selector );
debugIOLog ( 6, " getPowerState () = %ld, pendingPowerState = %ld", getPowerState (), pendingPowerState );
if ( kIOAudioDeviceSleep == getPowerState () && kIOAudioDeviceSleep == pendingPowerState )
{
debugIOLog ( 6, " power state = SLEEP" );
switch ( selector )
{
case kRemoteActive: case kRemoteSleep: case kRemoteIdle: case kRemoteChildSleep: case kRemoteChildIdle: case kRemoteChildActive:
result = TRUE;
break;
}
}
else
{
result = TRUE;
}
debugIOLog ( 6, "- AppleOnboardAudio::executeProtectedInterruptEventHandlerWhenInactive () returns %d", result );
return result;
}
#pragma mark +INTERRUPT POWER MANAGMENT SUPPORT
void AppleOnboardAudio::startDetectInterruptService ( void )
{
debugIOLog ( 6, "+ AppleOnboardAudio::startDetectInterruptService" );
if ( kIOAudioDeviceActive != getPowerState () )
{
if ( mDetectCollection != getValueForDetectCollection ( mDetectCollection ) ) {
if ( mDoKPrintfPowerState )
{
IOLog ( "AppleOnboardAudio[%ld]::protectedInterruptEventHandler setting power state to ACTIVE\n", mInstanceIndex );
}
FailMessage ( kIOReturnSuccess != doLocalChangeToActiveState ( FALSE, 0 ) );
}
}
debugIOLog ( 6, "- AppleOnboardAudio::startDetectInterruptService" );
}
void AppleOnboardAudio::endDetectInterruptService ( void )
{
debugIOLog ( 6, "+ AppleOnboardAudio::endDetectInterruptService" );
debugIOLog ( 6, " mCurrentAggressivenessLevel %ld", mCurrentAggressivenessLevel );
if ( ( 0 == sTotalNumAOAEnginesRunning ) && ( kIOPMInternalPower == mCurrentAggressivenessLevel ) ) {
if ( mDoKPrintfPowerState )
{
IOLog ( "AppleOnboardAudio[%ld]::endDetectInterruptService scheduling deferred IDLE\n", mInstanceIndex );
}
setIdleAudioSleepTime ( kBatteryPowerDownDelayTime );
debugIOLog ( 6, " asyncPowerStateChangeInProgress %d", asyncPowerStateChangeInProgress );
#ifdef THREAD_POWER_MANAGEMENT
if ( asyncPowerStateChangeInProgress )
{
waitForPendingPowerStateChange ();
}
#endif
debugIOLog ( 6, " setting pendingPowerState to kIOAudioDeviceIdle" );
pendingPowerState = kIOAudioDeviceIdle;
}
debugIOLog ( 6, "- AppleOnboardAudio::endDetectInterruptService" );
}
bool AppleOnboardAudio::broadcastSoftwareInterruptMessage ( UInt32 actionSelector )
{
AppleOnboardAudio * theAOA;
OSObject * theObject;
UInt32 numInstances;
bool result = FALSE;
switch ( actionSelector ) {
case kDigitalInInsertStatus: debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::broadcastSoftwareInterruptMessage ( 0x%0.8X kDigitalInInsertStatus )", mInstanceIndex, actionSelector ); break;
case kDigitalInRemoveStatus: debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::broadcastSoftwareInterruptMessage ( 0x%0.8X kDigitalInRemoveStatus )", mInstanceIndex, actionSelector ); break;
case kClockLockStatus: debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::broadcastSoftwareInterruptMessage ( 0x%0.8X kClockLockStatus )", mInstanceIndex, actionSelector ); break;
case kClockUnLockStatus: debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::broadcastSoftwareInterruptMessage ( 0x%0.8X kClockUnLockStatus )", mInstanceIndex, actionSelector ); break;
case kRemoteActive: debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::broadcastSoftwareInterruptMessage ( 0x%0.8X kRemoteActive )", mInstanceIndex, actionSelector ); break;
case kRemoteIdle: debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::broadcastSoftwareInterruptMessage ( 0x%0.8X kRemoteIdle )", mInstanceIndex, actionSelector ); break;
case kRemoteSleep: debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::broadcastSoftwareInterruptMessage ( 0x%0.8X kRemoteSleep )", mInstanceIndex, actionSelector ); break;
case kRemoteChildActive: debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::broadcastSoftwareInterruptMessage ( 0x%0.8X kRemoteChildActive )", mInstanceIndex, actionSelector ); break;
case kRemoteChildIdle: debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::broadcastSoftwareInterruptMessage ( 0x%0.8X kRemoteChildIdle )", mInstanceIndex, actionSelector ); break;
case kRemoteChildSleep: debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::broadcastSoftwareInterruptMessage ( 0x%0.8X kRemoteChildSleep )", mInstanceIndex, actionSelector ); break;
default: debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::broadcastSoftwareInterruptMessage ( 0x%0.8X UNKNOWN )", mInstanceIndex, actionSelector ); break;
}
if ( 0 != mAOAInstanceArray ) {
numInstances = mAOAInstanceArray->getCount();
for ( UInt32 index = 0; index < numInstances; index++ ) {
theObject = mAOAInstanceArray->getObject ( index );
if ( 0 != theObject ) {
theAOA = OSDynamicCast ( AppleOnboardAudio, theObject );
debugIOLog ( 5, " numInstances = %d, mAOAInstanceArray->getObject ( %d ) returns %p", numInstances, index, theAOA );
if ( 0 != theAOA ) {
if ( isTargetForMessage ( actionSelector, theAOA ) ) {
switch ( actionSelector ) {
case kRemoteActive:
case kRemoteIdle:
case kRemoteSleep:
case kRemoteChildActive:
case kRemoteChildIdle:
case kRemoteChildSleep:
debugIOLog ( 6, " %p AOA[%ld] calls %p->interruptEventHandler ( %d, 0 )", this, getAOAInstanceIndex (), theAOA, actionSelector );
theAOA->interruptEventHandler ( actionSelector, 0 );
debugIOLog ( 6, " %p AOA[%ld] returns from %p->interruptEventHandler ( %d, 0 )", this, getAOAInstanceIndex (), theAOA, actionSelector );
result = TRUE;
break;
default:
debugIOLog ( 5, " theAOA %p is target for 0x%0.8X", theAOA, actionSelector );
if (theAOA->mSoftwareInterruptHandler) {
theAOA->mInterruptProduced[actionSelector]++;
theAOA->mSoftwareInterruptHandler->interruptOccurred (0, 0, 0);
result = TRUE;
}
break;
}
}
}
}
}
}
debugIOLog ( 5, "- AppleOnboardAudio[%ld]::broadcastSoftwareInterruptMessage ( 0x%0.8X ) returns %ld", mInstanceIndex, actionSelector, result );
return result;
}
#pragma mark +IOAUDIO INIT
bool AppleOnboardAudio::initHardware ( IOService * provider ) {
bool result = FALSE;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::initHardware", mInstanceIndex);
mSignal = IOSyncer::create (FALSE);
FailIf (0 == mInitHardwareThread, Exit);
if ( kIOReturnSuccess == protectedInitHardware ( provider ) )
{
result = TRUE;
}
else
{
AppleOnboardAudio::sInstanceCount--;
mInstanceIndex = AppleOnboardAudio::sInstanceCount;
debugIOLog ( 3, " AppleOnboardAudio[%ld]::initHardware FAILED !!!! bumping down instance count now to %d", mInstanceIndex, mInstanceIndex );
}
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::initHardware returns %d", mInstanceIndex, result );
return result;
}
void AppleOnboardAudio::initHardwareThread (AppleOnboardAudio * aoa, void * provider) {
IOCommandGate * cg;
IOReturn result;
FailIf (0 == aoa, Exit);
FailIf (TRUE == aoa->mTerminating, Exit);
cg = aoa->getCommandGate ();
if (cg) {
result = cg->runAction (aoa->initHardwareThreadAction, provider);
}
Exit:
return;
}
IOReturn AppleOnboardAudio::initHardwareThreadAction (OSObject * owner, void * provider, void * arg2, void * arg3, void * arg4) {
AppleOnboardAudio * aoa;
IOReturn result;
result = kIOReturnError;
aoa = (AppleOnboardAudio *)owner;
FailIf (0 == aoa, Exit);
result = aoa->protectedInitHardware ((IOService *)provider);
Exit:
return result;
}
IOReturn AppleOnboardAudio::protectedInitHardware (IOService * provider) {
OSArray * layouts;
OSArray * hardwareObjectsList;
OSArray * multipleDevicesArray;
OSDictionary * layoutEntry;
OSNumber * layoutIDNumber;
OSNumber * ampRecoveryNumber;
OSNumber * microsecsToSleepNumber;
OSNumber * headphoneState;
OSString * transportObjectString;
OSString * comboInAssociationString;
OSString * comboOutAssociationString;
OSData * tmpData;
UInt32 * layoutID;
UInt32 layoutIDInt;
OSNumber * transportIndexPtr; OSNumber * platformInterfaceSupportPtr;
UInt32 timeWaited;
UInt32 layoutsCount;
UInt32 index;
UInt32 numPlugins;
bool done;
AudioHardwareObjectInterface * thePluginObject;
OSDictionary * AOAprop;
IOWorkLoop * workLoop;
OSBoolean * softwareInputGainBoolean;
OSNumber * inputLatencyNumber;
OSNumber * outputLatencyNumber;
OSNumber * connectionCodeNumber;
OSNumber * volumeNumber;
OSNumber * usesAOAPowerManagement; OSNumber * theInputsBitmap;
OSNumber * theOutputsBitmap;
OSBoolean * uiMutesAmpsBoolean;
OSBoolean * comboInNoIrqProperty;
OSBoolean * comboOutNoIrqProperty;
OSBoolean * autoSelectInputBoolean;
OSBoolean * autoSelectClockBoolean;
OSBoolean * muteAmpWhenClockInterrupted;
OSBoolean * supressBootChimeLevelControl; bool comboInNoIrq; bool comboOutNoIrq; UInt32 irqEnableMask; char * connectionString;
UInt32 connectionCode;
UInt32 tempLatency;
UInt32 inputLatency;
UInt32 selectorCode;
UInt32 count;
IOReturn result;
char deviceName[256];
char num[4];
result = kIOReturnError;
selectorCode = (UInt32)((SInt32)-1);
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::protectedInitHardware", mInstanceIndex );
debugIOLog ( 3, " provider's name is: '%s'", provider->getName () );
connectionString = 0;
tmpData = OSDynamicCast (OSData, provider->getProperty ( kLayoutID ) );
workLoop = getWorkLoop();
FailIf (0 == workLoop, Exit);
mSoftwareInterruptHandler = IOInterruptEventSource::interruptEventSource ( this, softwareInterruptHandler );
FailIf ( 0 == mSoftwareInterruptHandler, Exit );
workLoop->addEventSource ( mSoftwareInterruptHandler );
mSoftwareInterruptHandler->enable ();
FailIf ( 0 == tmpData, Exit );
layoutID = (UInt32 *)tmpData->getBytesNoCopy ();
FailIf ( 0 == layoutID, Exit )
mCodecLockStatus = kClockUnLockStatus;
mRelockToExternalClockInProgress = FALSE; mRelockToExternalClockPollCount = 0;
mLayoutID = *layoutID;
mUCState.ucLayoutID = mLayoutID;
debugIOLog ( 3, " ...:%s:layout-id = 0x%lX = #%d", provider->getName (), mLayoutID, mLayoutID );
mDigitalInsertStatus = kGPIO_Connected;
layouts = OSDynamicCast ( OSArray, getProperty ( kLayouts ) );
debugIOLog ( 3, " layout array = %p", layouts );
FailIf ( 0 == layouts, Exit );
layoutsCount = layouts->getCount ();
debugIOLog ( 3, " layouts->getCount () returns %ld", layoutsCount );
layoutEntry = 0;
index = 0;
mMatchingIndex = 0xFFFFFFFF;
layoutIDInt = 0;
debugIOLog ( 6, " AppleOnboardAudio[%ld]::mLayoutID 0x%lX = #%ld (from provider node)", mInstanceIndex, mLayoutID, mLayoutID);
while ( layoutsCount-- )
{
layoutEntry = OSDynamicCast (OSDictionary, layouts->getObject (index));
FailIf (0 == layoutEntry, Exit);
layoutIDNumber = OSDynamicCast (OSNumber, layoutEntry->getObject (kLayoutIDInfoPlist));
FailIf (0 == layoutIDNumber, Exit);
layoutIDInt = layoutIDNumber->unsigned32BitValue ();
debugIOLog ( 6, " found layoutIDInt %d in XML layout entry dictionary", layoutIDInt );
if ( layoutIDInt == mLayoutID )
{
debugIOLog ( 6, " AppleOnboardAudio[%ld] found machine layout id 0x%lX @ index %ld", mInstanceIndex, layoutIDInt, index);
mMatchingIndex = index;
break;
}
else
{
index++;
}
}
FailIf (0xFFFFFFFF == mMatchingIndex, Exit);
layoutEntry = OSDynamicCast (OSDictionary, layouts->getObject (mMatchingIndex));
debugIOLog ( 6, " layoutEntry = %p", layoutEntry);
FailIf (0 == layoutEntry, Exit);
mAmpRecoveryMuteDuration = 1;
ampRecoveryNumber = OSDynamicCast ( OSNumber, layoutEntry->getObject (kAmpRecoveryTime) );
if ( 0 != ampRecoveryNumber )
{
mAmpRecoveryMuteDuration = ampRecoveryNumber->unsigned32BitValue();
}
debugIOLog ( 6, " AppleOnboardAudio[%ld]::protectedInitHardware - mAmpRecoveryMuteDuration = %ld", mInstanceIndex, mAmpRecoveryMuteDuration);
autoSelectInputBoolean = OSDynamicCast ( OSBoolean, layoutEntry->getObject ( kInputAutoSelect ) );
if ( 0 != autoSelectInputBoolean ) {
mAutoSelectInput = autoSelectInputBoolean->getValue ();
}
else {
mAutoSelectInput = FALSE;
}
autoSelectClockBoolean = OSDynamicCast ( OSBoolean, layoutEntry->getObject ( kExternalClockAutoSelect ) );
if ( 0 != autoSelectClockBoolean ) {
mAutoSelectClock = autoSelectClockBoolean->getValue ();
}
else {
mAutoSelectClock = FALSE;
}
mDisableAutoSelectClock = TRUE;
microsecsToSleepNumber = OSDynamicCast ( OSNumber, layoutEntry->getObject ( kMicrosecsToSleep ) );
if ( 0 != microsecsToSleepNumber )
{
mMicrosecsToSleep = microsecsToSleepNumber->unsigned32BitValue();
}
debugIOLog ( 6, " AppleOnboardAudio[%ld]::protectedInitHardware - mMicrosecsToSleep = %ld", mInstanceIndex, mMicrosecsToSleep);
comboInNoIrq = FALSE;
comboInNoIrqProperty = OSDynamicCast ( OSBoolean, layoutEntry->getObject ( kComboInNoIrq ) );
if ( 0 != comboInNoIrqProperty ) {
comboInNoIrq = comboInNoIrqProperty->getValue ();
}
comboOutNoIrq = FALSE;
comboOutNoIrqProperty = OSDynamicCast ( OSBoolean, layoutEntry->getObject ( kComboOutNoIrq ) );
if ( 0 != comboOutNoIrqProperty ) {
comboOutNoIrq = comboOutNoIrqProperty->getValue ();
}
platformInterfaceSupportPtr = OSDynamicCast ( OSNumber, layoutEntry->getObject ( kPlatformInterfaceSupport ) );
FailIf ( 0 == platformInterfaceSupportPtr, Exit );
mPlatformInterfaceSupport = platformInterfaceSupportPtr->unsigned32BitValue ();
mPlatformInterface = new PlatformInterface ();
FailIf (0 == mPlatformInterface, Exit);
debugIOLog ( 6, " AppleOnboardAudio[%ld]::protectedInitHardware - mPlatformInterface = %p", mInstanceIndex, mPlatformInterface);
irqEnableMask = 0xFFFFFFFF;
if ( comboInNoIrq )
{
irqEnableMask &= ~( 1 << gpioMessage_ComboInJackType_bitAddress );
}
if ( comboOutNoIrq )
{
irqEnableMask &= ~( 1 << gpioMessage_ComboOutJackType_bitAddress );
}
FailIf (!mPlatformInterface->init ( provider, this, AppleDBDMAAudio::kDBDMADeviceIndex, mPlatformInterfaceSupport, irqEnableMask ), Exit);
if ( kGPIO_IsAlternate == mPlatformInterface->getInternalMicrophoneID() ) {
mInternalMicrophoneID = 1;
} else {
mInternalMicrophoneID = 0;
}
transportIndexPtr = OSDynamicCast ( OSNumber, layoutEntry->getObject ( kTransportIndex ) );
if ( 0 != transportIndexPtr ) {
debugIOLog ( 6, " transportIndexPtr = %p", transportIndexPtr);
mTransportInterfaceIndex = transportIndexPtr->unsigned32BitValue ();
} else {
debugIOLog ( 3, " <key>TransportIndex</key> NOT FOUND!!!" );
}
debugIOLog ( 6, " AppleOnboardAudio[%ld]::mTransportInterfaceIndex = %d", mInstanceIndex, mTransportInterfaceIndex);
mUIMutesAmps = FALSE;
uiMutesAmpsBoolean = OSDynamicCast ( OSBoolean, layoutEntry->getObject ( kUIMutesAmps ) );
if ( 0 != uiMutesAmpsBoolean ) {
mUIMutesAmps = uiMutesAmpsBoolean->getValue ();
}
mMuteAmpWhenClockInterrupted = FALSE;
muteAmpWhenClockInterrupted = OSDynamicCast ( OSBoolean, layoutEntry->getObject ( kMuteAmpWhenClockInterrupted ) );
if ( 0 != muteAmpWhenClockInterrupted ) {
mMuteAmpWhenClockInterrupted = muteAmpWhenClockInterrupted->getValue ();
}
usesAOAPowerManagement = OSDynamicCast ( OSNumber, layoutEntry->getObject ( kUsesAOAPowerManagement ) ); if ( 0 != usesAOAPowerManagement ) {
mUsesAOAPowerManagement = usesAOAPowerManagement->unsigned32BitValue();
}
supressBootChimeLevelControl = OSDynamicCast ( OSBoolean, layoutEntry->getObject ( kSuppressBootChimeLevelCtrl ) ); if ( 0 != supressBootChimeLevelControl ) {
mSpressBootChimeLevelControl = supressBootChimeLevelControl->getValue();
}
comboInAssociationString = OSDynamicCast ( OSString, layoutEntry->getObject ( kComboInObject ) );
if ( 0 != comboInAssociationString ) {
debugIOLog ( 6, " comboInAssociationString = %s", comboInAssociationString->getCStringNoCopy ());
if ( comboInAssociationString->isEqualTo ("LineInDetect") ) {
mPlatformInterface->setAssociateComboInTo ( kGPIO_Selector_LineInDetect );
} else if ( comboInAssociationString->isEqualTo ("ExternalMicDetect") ) {
mPlatformInterface->setAssociateComboInTo ( kGPIO_Selector_ExternalMicDetect );
}
}
comboOutAssociationString = OSDynamicCast ( OSString, layoutEntry->getObject ( kComboOutObject ) );
if ( 0 != comboOutAssociationString ) {
debugIOLog ( 6, " comboOutAssociationString = %s", comboOutAssociationString->getCStringNoCopy ());
if ( comboOutAssociationString->isEqualTo ("LineOutDetect") ) {
mPlatformInterface->setAssociateComboOutTo ( kGPIO_Selector_LineOutDetect );
} else if ( comboOutAssociationString->isEqualTo ("HeadphonesDetect") ) {
mPlatformInterface->setAssociateComboOutTo ( kGPIO_Selector_HeadphoneDetect );
} else if ( comboOutAssociationString->isEqualTo ("ExtSpeakersDetect") ) {
mPlatformInterface->setAssociateComboOutTo ( kGPIO_Selector_SpeakerDetect );
}
}
debugIOLog ( 3, " AppleOnboardAudio[%ld]::protectedInitHardware - about to mute all amps.", mInstanceIndex );
if (mMuteAmpWhenClockInterrupted) {
muteAllAmps();
}
if ( kGPIO_Unknown != mPlatformInterface->getCodecReset ( kCODEC_RESET_Analog ) )
{
mPlatformInterface->setCodecReset ( kCODEC_RESET_Analog, kGPIO_Reset );
}
transportObjectString = OSDynamicCast ( OSString, layoutEntry->getObject ( kTransportObject ) );
FailIf ( 0 == transportObjectString, Exit );
debugIOLog ( 6, " AppleOnboardAudio[%ld]::protectedInitHardware - transportObjectString = %s", mInstanceIndex, transportObjectString->getCStringNoCopy());
mTransportInterface = TransportFactory::createTransport ( transportObjectString );
debugIOLog ( 6, " AppleOnboardAudio[%ld]::protectedInitHardware - mTransportInterface = %p", mInstanceIndex, mTransportInterface);
FailIf (0 == mTransportInterface, Exit);
FailIf (!mTransportInterface->init ( mPlatformInterface ), Exit);
hardwareObjectsList = OSDynamicCast (OSArray, layoutEntry->getObject (kHardwareObjects));
if ( 0 == hardwareObjectsList ) { debugIOLog ( 3, " 0 == hardwareObjectsList" ); }
FailIf (0 == hardwareObjectsList, Exit);
numPlugins = hardwareObjectsList->getCount ();
debugIOLog ( 5, " AppleOnboardAudio[%ld] numPlugins to load = %ld", mInstanceIndex, numPlugins);
if (0 == mPluginObjects) {
mPluginObjects = OSArray::withCapacity (0);
}
FailIf (0 == mPluginObjects, Exit);
for (index = 0; index < numPlugins; index++) {
setProperty (((OSString *)hardwareObjectsList->getObject(index))->getCStringNoCopy(), "YES");
debugIOLog ( 5, " set property %s", ((OSString *)hardwareObjectsList->getObject(index))->getCStringNoCopy());
}
registerService ();
timeWaited = 0;
done = FALSE;
while (!done) {
if (0 == mPluginObjects) {
IOSleep (10);
} else {
if (mPluginObjects->getCount () != numPlugins) {
IOSleep (10);
} else {
done = TRUE;
}
}
timeWaited++;
}
#if 0 // begin { This section was commented out. It may have broken the DEBUG build???
if ((0 == timeout) && (FALSE == done)) {
debugIOLog ( 3, "$$$$$$ timeout and not enough plugins $$$$$$");
setProperty ("Plugin load failed", "TRUE");
}
#if DEBUGLOG
loadTimeNumber = OSNumber::withNumber ((unsigned long long)timeWaited * 10, 32);
setProperty ("Plugin load time (ms)", loadTimeNumber);
loadTimeNumber->release ();
#endif
#endif // } end
volumeNumber = OSNumber::withNumber((long long unsigned int)0, 32);
FailIf ( !super::initHardware (provider), Exit);
debugIOLog ( 3, " A: about to set work loop");
mPlatformInterface->setWorkLoop (workLoop);
FailIf (0 == mPluginObjects, Exit);
count = mPluginObjects->getCount ();
FailIf (0 == count, Exit);
debugIOLog ( 3, " AppleOnboardAudio[%ld] about to init %ld plugins", mInstanceIndex, count);
for (index = 0; index < count; index++) {
thePluginObject = getIndexedPluginObject (index);
FailIf (0 == thePluginObject, Exit);
thePluginObject->setWorkLoop (workLoop);
thePluginObject->initPlugin ( mPlatformInterface );
mCurrentOutputPlugin = thePluginObject;
mCurrentInputPlugin = thePluginObject;
}
volumeNumber->release ();
callPluginsInOrder (kPreDMAEngineInit, (UInt32) mAutoSelectClock);
sprintf ( deviceName, "%s", "DeviceName");
if (mInstanceIndex > 1) {
sprintf (num, "%d", mInstanceIndex);
strcat (deviceName, num);
}
setDeviceName (deviceName);
sprintf ( deviceName, "%s", "DeviceShortName");
if (mInstanceIndex > 1) {
sprintf (num, "%d", mInstanceIndex);
strcat (deviceName, num);
}
setDeviceShortName (deviceName);
setManufacturerName ("ManufacturerName");
setProperty (kIOAudioDeviceLocalizedBundleKey, "AppleOnboardAudio.kext");
setDeviceTransportType (kIOAudioDeviceTransportTypeBuiltIn);
setProperty (kIOAudioEngineCoreAudioPlugInKey, "IOAudioFamily.kext/Contents/PlugIns/AOAHALPlugin.bundle");
configureDMAEngines (provider);
debugIOLog ( 6, " AppleOnboardAudio[%ld] finished configure DMA engine (%p) ", mInstanceIndex, mDriverDMAEngine);
FailIf (0 == mDriverDMAEngine, Exit);
theInputsBitmap = OSDynamicCast (OSNumber, layoutEntry->getObject (kInputsBitmap));
if (theInputsBitmap) {
mDriverDMAEngine->setProperty ("InputsBitmap", theInputsBitmap);
}
theOutputsBitmap = OSDynamicCast (OSNumber, layoutEntry->getObject (kOutputsBitmap));
if (theOutputsBitmap) {
mDriverDMAEngine->setProperty ("OutputsBitmap", theOutputsBitmap);
}
mAutoUpdatePRAM = FALSE; result = createDefaultControls ();
FailIf (kIOReturnSuccess != result, Exit);
debugIOLog ( 3, " AppleOnboardAudio[%ld]::initHardware - mDriverDMAEngine retain count before activateAudioEngine = %d", mInstanceIndex, mDriverDMAEngine->getRetainCount());
if (kIOReturnSuccess != activateAudioEngine (mDriverDMAEngine)) {
mDriverDMAEngine->release ();
mDriverDMAEngine = 0;
goto Exit;
}
debugIOLog ( 3, " AppleOnboardAudio[%ld]::initHardware - mDriverDMAEngine retain count after activateAudioEngine = %d", mInstanceIndex, mDriverDMAEngine->getRetainCount());
pollTimer = IOTimerEventSource::timerEventSource ( this, pollTimerCallback );
if ( pollTimer ) {
workLoop->addEventSource ( pollTimer );
}
mUCState.ucPowerState = getPowerState ();
setProperty ("IOAudioPowerState", getPowerState (), 32);
setIdleAudioSleepTime ( kNoIdleAudioPowerDown );
mAutoUpdatePRAM = FALSE; if (0 != mOutMasterVolumeControl) {
UInt32 volume;
volume = (mOutMasterVolumeControl->getMaxValue () - mOutMasterVolumeControl->getMinValue () + 1) * 90 / 100;
mOutMasterVolumeControl->setValue (volume);
}
if (0 != mOutLeftVolumeControl) {
UInt32 volume;
volume = (mOutLeftVolumeControl->getMaxValue () - mOutLeftVolumeControl->getMinValue () + 1) * 65 / 100;
mOutLeftVolumeControl->setValue (volume);
}
if (0 != mOutRightVolumeControl) {
UInt32 volume;
volume = (mOutRightVolumeControl->getMaxValue () - mOutRightVolumeControl->getMinValue () + 1) * 65 / 100;
mOutRightVolumeControl->setValue (volume);
}
debugIOLog (6, " Internal microphone ID is %ld", mInternalMicrophoneID);
if ( kGPIO_IsAlternate == mPlatformInterface->getInternalSpeakerID() ) {
mInternalSpeakerID = 1;
} else {
mInternalSpeakerID = 0;
}
debugIOLog ( 6, " Internal speaker ID is %ld", mInternalSpeakerID);
mSiliconVersion = mCurrentInputPlugin->getSiliconVersion();
debugIOLog ( 3, " Silicon version is %ld", mSiliconVersion);
initializeDetectCollection();
connectionCode = parseOutputDetectCollection ();
connectionCodeNumber = OSNumber::withNumber(connectionCode, 32);
if ( mHeadphoneConnected ) {
if (mDetectCollection & kSndHWCPUHeadphone) {
headphoneState = OSNumber::withNumber (1, 32);
} else {
headphoneState = OSNumber::withNumber ((long long unsigned int)0, 32);
}
mHeadphoneConnected->hardwareValueChanged (headphoneState);
headphoneState->release ();
}
{
UInt32 comboOutJackTypeState = mPlatformInterface->getComboOutJackTypeConnected ();
if ( kGPIO_Unknown != comboOutJackTypeState ) {
GpioAttributes theAnalogState = kGPIO_Unknown;
switch ( (UInt32)mPlatformInterface->getComboOutAssociation () ) {
case kGPIO_Selector_HeadphoneDetect: theAnalogState = mPlatformInterface->getHeadphoneConnected (); break;
case kGPIO_Selector_LineOutDetect: theAnalogState = mPlatformInterface->getLineOutConnected (); break;
case kGPIO_Selector_SpeakerDetect: theAnalogState = mPlatformInterface->getSpeakerConnected (); break;
}
if ( kGPIO_Connected == theAnalogState && kGPIO_TypeIsDigital == comboOutJackTypeState ) {
callPluginsInOrder ( kSetDigitalMuteState, FALSE );
} else {
callPluginsInOrder ( kSetDigitalMuteState, TRUE );
}
} else {
callPluginsInOrder ( kSetDigitalMuteState, FALSE );
}
}
if ( 0 != mOutputSelector ) {
mOutputSelector->hardwareValueChanged (connectionCodeNumber);
}
connectionCodeNumber->release();
if ( 0 != mOutputSelector ) {
selectorCode = mOutputSelector->getIntValue ();
debugIOLog ( 6, " mOutputSelector->getIntValue () returns %lX", selectorCode);
if (0 != selectorCode) {
connectionString = getConnectionKeyFromCharCode (selectorCode, kIOAudioStreamDirectionOutput);
debugIOLog ( 6, " mOutputSelector->getIntValue () char code is %s", connectionString);
if (0 != connectionString) {
AudioHardwareObjectInterface* theHWObject;
theHWObject = getPluginObjectForConnection (connectionString);
if (0 != theHWObject) {
mCurrentOutputPlugin = theHWObject;
} else {
debugIOLog (1, " *** Can't find hardware plugin for output %s", connectionString);
}
}
}
debugIOLog ( 6, " AppleOnboardAudio[%ld] mCurrentOutputPlugin = %p", mInstanceIndex, mCurrentOutputPlugin);
}
connectionString = 0;
if ( 0 != mInputSelector ) {
selectorCode = mInputSelector->getIntValue ();
debugIOLog ( 6, " mInputSelector->getIntValue () returns '%4s'", (char *)&selectorCode);
if (0 != selectorCode) {
connectionString = getConnectionKeyFromCharCode (selectorCode, kIOAudioStreamDirectionInput);
debugIOLog ( 6, " mInputSelector->getIntValue () char code is %s", connectionString);
if (0 != connectionString) {
AudioHardwareObjectInterface* theHWObject;
theHWObject = getPluginObjectForConnection (connectionString);
if (0 != theHWObject) {
mCurrentInputPlugin = theHWObject;
} else {
debugIOLog (1, " *** Can't find hardware plugin for input %s", connectionString);
}
}
}
}
debugIOLog ( 6, " AppleOnboardAudio[%ld] mCurrentInputPlugin = %p", mInstanceIndex, mCurrentInputPlugin);
mCurrentInputPlugin->setActiveInput (selectorCode);
AOAprop = OSDynamicCast (OSDictionary, mCurrentInputPlugin->getProperty (kPluginPListAOAAttributes));
FailIf (0 == AOAprop, Exit);
softwareInputGainBoolean = OSDynamicCast (OSBoolean, AOAprop->getObject (kPluginPListSoftwareInputGain));
if (0 != softwareInputGainBoolean) {
mDriverDMAEngine->setUseSoftwareInputGain (softwareInputGainBoolean->getValue ());
mCurrentPluginNeedsSoftwareInputGain = softwareInputGainBoolean->getValue ();
} else {
mDriverDMAEngine->setUseSoftwareInputGain (false);
mCurrentPluginNeedsSoftwareInputGain = false;
}
if (0 != connectionString) {
setSoftwareInputDSP (connectionString);
}
inputLatency = 0; inputLatencyNumber = OSDynamicCast (OSNumber, AOAprop->getObject (kPluginPListInputLatency));
if (0 != inputLatencyNumber) {
inputLatency = inputLatencyNumber->unsigned32BitValue();
}
mOutputLatency = 0;
count = mPluginObjects->getCount ();
for (index = 0; index < count; index++) {
thePluginObject = getIndexedPluginObject (index);
FailIf (0 == thePluginObject, Exit);
AOAprop = OSDynamicCast (OSDictionary, thePluginObject->getProperty (kPluginPListAOAAttributes));
FailIf (0 == AOAprop, Exit);
outputLatencyNumber = OSDynamicCast (OSNumber, AOAprop->getObject (kPluginPListOutputLatency));
if (0 != outputLatencyNumber) {
tempLatency = outputLatencyNumber->unsigned32BitValue();
if (tempLatency > mOutputLatency) {
mOutputLatency = tempLatency;
}
}
}
mDriverDMAEngine->setSampleLatencies (mOutputLatency, inputLatency);
mSysPowerDownNotifier = registerPrioritySleepWakeInterest (&sysPowerDownHandler, this, 0);
setPollTimer ();
multipleDevicesArray = OSDynamicCast (OSArray, layoutEntry->getObject (kMultipleDevices));
debugIOLog ( 3, " multipleDevicesArray = %p", multipleDevicesArray);
if ( 0 != multipleDevicesArray )
{
if ( 1 == mInstanceIndex )
{
UInt32 deviceIndex;
UInt32 devicesToLoad;
mach_timespec_t timeout;
timeout.tv_sec = 5;
timeout.tv_nsec = 0;
devicesToLoad = 0;
devicesToLoad = multipleDevicesArray->getCount();
debugIOLog ( 6, " devicesToLoad = %ld", devicesToLoad);
for (deviceIndex = 0; deviceIndex < devicesToLoad; deviceIndex++) {
OSDictionary * deviceDict;
OSString * i2sNodeString;
OSString * soundNodePathString;
OSString * matchPropertyString;
IOService * i2sService;
IORegistryEntry * soundRegEntry;
IOService * sound;
deviceDict = OSDynamicCast (OSDictionary, multipleDevicesArray->getObject(deviceIndex));
debugIOLog ( 6, " deviceDict = %p", deviceDict);
FailIf (0 == deviceDict, Exit);
i2sNodeString = OSDynamicCast (OSString, deviceDict->getObject(kI2SNode)); debugIOLog ( 6, " i2sNodeString = %p", i2sNodeString);
FailIf (0 == i2sNodeString, Exit);
debugIOLog ( 6, " i2sNodeString = %s", i2sNodeString->getCStringNoCopy());
soundNodePathString = OSDynamicCast (OSString, deviceDict->getObject(kSoundNodePath)); debugIOLog ( 6, " soundNodePathString = %p", soundNodePathString);
FailIf (0 == soundNodePathString, Exit);
debugIOLog ( 6, " soundNodePathString = %s", soundNodePathString->getCStringNoCopy());
matchPropertyString = OSDynamicCast (OSString, deviceDict->getObject(kMatchProperty)); debugIOLog ( 6, " matchPropertyString = %p", matchPropertyString);
FailIf (0 == matchPropertyString, Exit);
debugIOLog ( 6, " matchPropertyString = %s", matchPropertyString->getCStringNoCopy());
i2sService = IOService::waitForService (IOService::nameMatching(i2sNodeString->getCStringNoCopy()), &timeout);
debugIOLog ( 6, " i2sService = %p i2sNodeString=%s", deviceDict,i2sNodeString->getCStringNoCopy());
#ifndef DualKeyLargo_WORKAROUND
FailIf (0 == i2sService, Exit);
#endif
if (0 != i2sService) {
soundRegEntry = i2sService->childFromPath (soundNodePathString->getCStringNoCopy(), gIOServicePlane);
debugIOLog ( 6, " soundRegEntry = %p soundNodePathString=%s", soundRegEntry,soundNodePathString->getCStringNoCopy());
} else {
soundRegEntry = 0;
}
#ifdef DualKeyLargo_WORKAROUND
if (soundRegEntry == 0) {
OSIterator* iter;
IOService* parent = (IOService*)i2sService->getParentEntry(gIOServicePlane);
if (parent) {
debugIOLog ( 6, " soundRegEntry = %p ", parent);
iter = parent->getChildIterator(gIOServicePlane);
if (iter) {
IORegistryEntry* node;
while ((node = OSDynamicCast (IORegistryEntry,iter->getNextObject())) != 0 ) {
tmpData = OSDynamicCast (OSData, node->getProperty (kLayoutID));
if (tmpData) {
UInt32* layoutID = (UInt32 *)tmpData->getBytesNoCopy ();
UInt32 tempLayout = *layoutID;
debugIOLog ( 3, " provider tempLayout(%lu) mLayoutID (%lu)", tempLayout, mLayoutID);
if (tempLayout != mLayoutID) {
soundRegEntry = node;
soundRegEntry->retain();
break;
}
}
}
}
}
}
#endif
FailIf (0 == soundRegEntry, Exit);
sound = OSDynamicCast (IOService, soundRegEntry);
FailIf (0 == sound, Exit);
debugIOLog ( 6, " sound = %p", sound);
sound->setProperty (matchPropertyString->getCStringNoCopy(), "YES");
sound->registerService ();
}
} else {
debugIOLog ( 3, " 0 == multipleDevicesArray on instance %ld", mInstanceIndex );
}
}
mSignal->signal (kIOReturnSuccess, FALSE);
result = kIOReturnSuccess;
mAutoUpdatePRAM = TRUE;
{
UInt32 transportType = mTransportInterface->transportGetTransportInterfaceType();
if ( ( kTransportInterfaceType_I2S_Slave_Only == transportType ) && ( kTransportInterfaceType_I2S_Opaque_Slave_Only == transportType ) ) { debugIOLog ( 3, " Selecting external clock for 'SLAVE ONLY' device" );
mTransportInterface->transportBreakClockSelect ( kTRANSPORT_SLAVE_CLOCK );
callPluginsInOrder ( kBreakClockSelect, kTRANSPORT_SLAVE_CLOCK );
mTransportInterface->transportMakeClockSelect ( kTRANSPORT_SLAVE_CLOCK );
callPluginsInOrder ( kMakeClockSelect, kTRANSPORT_SLAVE_CLOCK );
}
}
callPluginsInOrder (kPostDMAEngineInit, 0);
callPluginsInOrder (kEndFormatChange, 0);
debugIOLog (1, " about to sleep after postDMAEngineInit"); IOSleep (3000);
mCurrentOutputSelection = 0x3F3F3F3F;
mPlatformInterface->enableAmplifierMuteRelease(); mAllowDetectIrqDispatchesOnWake = TRUE;
if (0 != mOutputSelector)
{
mOutputSelector->flushValue ();
}
if (0 != mInputSelector)
{
mInputSelector->flushValue ();
}
flushAudioControls ();
if (0 != mExternalClockSelector)
{
mExternalClockSelector->flushValue (); }
mPlatformInterface->registerDetectInterrupts ( (IOService*)mPlatformInterface );
mRemoteDetectInterruptEnabled = TRUE;
mPlatformInterface->registerNonDetectInterrupts ( (IOService*)mPlatformInterface );
mRemoteNonDetectInterruptEnabled = TRUE;
debugIOLog ( 6, " AOA[%ld] where mRemoteDetectInterruptEnabled = %d, mRemoteNonDetectInterruptEnabled = %d", mInstanceIndex, mRemoteDetectInterruptEnabled, mRemoteNonDetectInterruptEnabled );
Exit:
if (0 != mInitHardwareThread) {
thread_call_free (mInitHardwareThread);
}
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::protectedInitHardware returns 0x%x", mInstanceIndex, result);
return (result);
}
bool AppleOnboardAudio::aoaPublished ( AppleOnboardAudio * aoaObject, void * refCon, IOService * newService )
{
bool result = FALSE;
debugIOLog ( 3, "+ AppleOnboardAudio::aoaPublished ( %p, %p, %p )", aoaObject, refCon, newService );
if ( aoaObject )
{
if ( aoaObject != newService )
{
result = aoaObject->aoaPublishedAction ( refCon, newService );
}
}
debugIOLog ( 3, "- AppleOnboardAudio::aoaPublished ( %p, %p, %p ) returns %d", aoaObject, refCon, newService, result );
return result;
}
bool AppleOnboardAudio::aoaPublishedAction ( void * refCon, IOService * newService )
{
bool result = FALSE;
bool found = FALSE;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::aoaPublishedAction ( %p, %p )", mInstanceIndex, refCon, newService );
if ( 0 == mAOAInstanceArray )
{
debugIOLog ( 3, " aoaObject->mAOAInstanceArray = OSArray::withObjects ( (const OSObject**)&newService=%p, 1);", newService );
mAOAInstanceArray = OSArray::withObjects ( (const OSObject**)&newService, 1 );
FailIf ( 0 == mAOAInstanceArray, Exit );
result = TRUE;
}
else
{
for ( UInt32 index = 0; index < mAOAInstanceArray->getCount() && !found; index++ )
{
if ( newService == mAOAInstanceArray->getObject ( index ) )
{
found = TRUE;
}
}
if ( !found )
{
debugIOLog ( 3, " mAOAInstanceArray->setObject ( %p );", newService );
mAOAInstanceArray->setObject ( newService );
result = TRUE;
}
}
if ( result )
{
debugIOLog ( 6, " AOA[%ld] where mJoinAOAPMTree %d, mNumberOfAOAPowerParents %ld", mInstanceIndex, mJoinAOAPMTree, mNumberOfAOAPowerParents );
if ( mJoinAOAPMTree && ( 0 == mNumberOfAOAPowerParents ) )
{
static IOPMPowerState aoaPowerStates[2] = {{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{1, IOPMDeviceUsable, IOPMPowerOn, IOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0}};
PMinit ();
debugIOLog ( 6, " %p newService->about to joinPMtree ( %p )", newService, this );
newService->joinPMtree ( this );
if ( pm_vars != NULL )
{
duringStartup = TRUE;
debugIOLog ( 6, " about to registerPowerDriver ( %p, %p, Td)", this, aoaPowerStates, 2 );
registerPowerDriver ( this, aoaPowerStates, 2 );
changePowerStateTo ( 1 );
duringStartup = FALSE;
}
mNumberOfAOAPowerParents++;
}
}
for ( UInt32 index = 0; index < mAOAInstanceArray->getCount(); index++ )
{
debugIOLog ( 3, " %p = mAOAInstanceArray->getObject ( %d )", mAOAInstanceArray->getObject ( index ) );
}
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::aoaPublishedAction ( %p, %p ) returns %d", mInstanceIndex, refCon, newService, result );
return result;
}
IOReturn AppleOnboardAudio::configureDMAEngines(IOService *provider) {
IOReturn result;
bool hasInput;
bool hasOutput;
OSArray * formatsArray;
OSArray * inputListArray;
OSArray * outputListArray;
result = kIOReturnError;
inputListArray = OSDynamicCast (OSArray, getLayoutEntry (kInputsList, this));
hasInput = (0 != inputListArray);
outputListArray = OSDynamicCast (OSArray, getLayoutEntry (kOutputsList, this));
hasOutput = ( 0 != outputListArray );
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::configureDMAEngines (%p)", mInstanceIndex, provider);
mDriverDMAEngine = new AppleDBDMAAudio;
FailIf (0 == mDriverDMAEngine, Exit);
formatsArray = OSDynamicCast (OSArray, getLayoutEntry (kFormats, this));
if (!mDriverDMAEngine->init (0, mPlatformInterface, (IOService *)provider->getParentEntry (gIODTPlane), hasInput, hasOutput, formatsArray)) {
mDriverDMAEngine->release ();
mDriverDMAEngine = 0;
goto Exit;
}
result = kIOReturnSuccess;
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::configureDMAEngines (%p) returns %x", mInstanceIndex, provider, result);
return result;
}
UInt16 AppleOnboardAudio::getTerminalTypeForCharCode (UInt32 outputSelection) {
UInt16 terminalType;
switch (outputSelection) {
case kIOAudioSelectorControlSelectionValueInternalSpeaker:
terminalType = OUTPUT_SPEAKER;
break;
case kIOAudioSelectorControlSelectionValueHeadphones:
terminalType = OUTPUT_HEADPHONES;
break;
case kIOAudioSelectorControlSelectionValueLine:
terminalType = EXTERNAL_LINE_CONNECTOR;
break;
case kIOAudioSelectorControlSelectionValueSPDIF:
terminalType = EXTERNAL_SPDIF_INTERFACE;
break;
case kIOAudioSelectorControlSelectionValueInternalMicrophone:
terminalType = INPUT_MICROPHONE;
break;
case kIOAudioSelectorControlSelectionValueExternalMicrophone:
terminalType = INPUT_DESKTOP_MICROPHONE;
break;
default:
terminalType = OUTPUT_UNDEFINED;
}
return terminalType;
}
UInt32 AppleOnboardAudio::getCharCodeForString (OSString * string) {
UInt32 charCode;
if (string->isEqualTo (kInternalSpeakers)) {
charCode = kIOAudioOutputPortSubTypeInternalSpeaker;
} else if (string->isEqualTo (kExternalSpeakers)) {
charCode = kIOAudioOutputPortSubTypeExternalSpeaker;
} else if (string->isEqualTo (kHeadphones)) {
charCode = kIOAudioOutputPortSubTypeHeadphones;
} else if (string->isEqualTo (kLineOut)) {
charCode = kIOAudioOutputPortSubTypeLine;
} else if (string->isEqualTo (kDigitalOut)) {
charCode = kIOAudioOutputPortSubTypeSPDIF;
} else if (string->isEqualTo (kInternalMic)) {
charCode = kIOAudioInputPortSubTypeInternalMicrophone;
} else if (string->isEqualTo (kExternalMic)) {
charCode = kIOAudioInputPortSubTypeExternalMicrophone;
} else if (string->isEqualTo (kLineIn)) {
charCode = kIOAudioInputPortSubTypeLine;
} else if (string->isEqualTo (kDigitalIn)) {
charCode = kIOAudioInputPortSubTypeSPDIF;
} else {
charCode = 0x3F3F3F3F; }
return charCode;
}
UInt32 AppleOnboardAudio::getCharCodeForIntCode (UInt32 inCode) {
UInt32 charCode;
if (kInternalSpeakerStatus == inCode) {
charCode = kIOAudioOutputPortSubTypeInternalSpeaker;
} else if (kExtSpeakersStatus == inCode) {
charCode = kIOAudioOutputPortSubTypeExternalSpeaker;
} else if (kHeadphoneStatus == inCode) {
charCode = kIOAudioOutputPortSubTypeHeadphones;
} else if (kLineOutStatus == inCode) {
charCode = kIOAudioOutputPortSubTypeLine;
} else if (kInputMicStatus == inCode) {
charCode = kIOAudioInputPortSubTypeInternalMicrophone;
} else if (kExternalMicInStatus == inCode) {
charCode = kIOAudioInputPortSubTypeExternalMicrophone;
} else if (kLineInStatus == inCode) {
charCode = kIOAudioInputPortSubTypeLine;
} else if ((kDigitalInInsertStatus == inCode) || (kDigitalInRemoveStatus == inCode)) {
charCode = kIOAudioInputPortSubTypeSPDIF;
} else if (kDigitalOutStatus == inCode) {
charCode = kIOAudioOutputPortSubTypeSPDIF;
} else {
charCode = 0x3F3F3F3F; }
return charCode;
}
OSString * AppleOnboardAudio::getStringForCharCode (UInt32 charCode) {
OSString * theString;
switch (charCode) {
case kIOAudioOutputPortSubTypeInternalSpeaker:
theString = OSString::withCString ("Internal Speakers");
break;
case kIOAudioOutputPortSubTypeExternalSpeaker:
theString = OSString::withCString ("External Speakers");
break;
case kIOAudioOutputPortSubTypeHeadphones:
theString = OSString::withCString ("Headphones");
break;
case kIOAudioOutputPortSubTypeLine:
theString = OSString::withCString ("Line");
break;
case kIOAudioOutputPortSubTypeSPDIF:
theString = OSString::withCString ("Digital");
break;
case kIOAudioInputPortSubTypeInternalMicrophone:
theString = OSString::withCString ("Internal Microphone");
break;
case kIOAudioInputPortSubTypeExternalMicrophone:
theString = OSString::withCString ("External Microphone");
break;
default:
theString = 0;
break;
}
return theString;
}
char * AppleOnboardAudio::getConnectionKeyFromCharCode (const SInt32 inSelection, const UInt32 inDirection) {
char * selectedOutput;
switch (inSelection) {
case kIOAudioOutputPortSubTypeInternalSpeaker:
selectedOutput = kInternalSpeakers;
break;
case kIOAudioOutputPortSubTypeExternalSpeaker:
selectedOutput = kExternalSpeakers;
break;
case kIOAudioOutputPortSubTypeHeadphones:
selectedOutput = kHeadphones;
break;
case kIOAudioInputPortSubTypeInternalMicrophone:
selectedOutput = kInternalMic;
break;
case kIOAudioInputPortSubTypeExternalMicrophone:
selectedOutput = kExternalMic;
break;
case kIOAudioOutputPortSubTypeSPDIF:
if (kIOAudioStreamDirectionOutput == inDirection) {
selectedOutput = kDigitalOut;
} else {
selectedOutput = kDigitalIn;
}
break;
case kIOAudioOutputPortSubTypeLine:
if (kIOAudioStreamDirectionOutput == inDirection) {
selectedOutput = kLineOut;
} else {
selectedOutput = kLineIn;
}
break;
default:
selectedOutput = 0;
break;
}
return selectedOutput;
}
IOReturn AppleOnboardAudio::createInputSelectorControl (void) {
OSString * inputString;
OSArray * inputsList;
IOReturn result;
UInt32 inputsCount;
UInt32 inputSelection;
UInt32 index;
UInt32 temp;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::createInputSelectorControl()", mInstanceIndex );
mInternalMicrophoneInputString = NULL;
mExternalMicrophoneInputString = NULL;
mLineInputString = NULL;
mDigitalInputString = NULL;
result = kIOReturnError;
inputsList = OSDynamicCast (OSArray, getLayoutEntry (kInputsList, this));
if ( 0 != inputsList ) {
inputsCount = inputsList->getCount ();
inputString = OSDynamicCast (OSString, inputsList->getObject (0));
FailIf (0 == inputString, Exit);
inputSelection = getCharCodeForString (inputString);
mInputSelector = IOAudioSelectorControl::createInputSelector (inputSelection, kIOAudioControlChannelIDAll);
if ( 0 == mInputSelector ) { debugIOLog ( 3, "createInputSelector for '%4s' FAILED", (char*)&inputSelection ); }
FailIf (0 == mInputSelector, Exit);
mDriverDMAEngine->addDefaultAudioControl (mInputSelector);
mInputSelector->setValueChangeHandler ((IOAudioControl::IntValueChangeHandler)inputControlChangeHandler, this);
for (index = 0; index < inputsCount; index++) {
inputString = OSDynamicCast (OSString, inputsList->getObject (index));
FailIf (0 == inputString, Exit);
inputSelection = getCharCodeForString (inputString);
switch (inputSelection) {
case kIOAudioInputPortSubTypeInternalMicrophone:
mInternalMicrophoneInputString = inputString;
temp = kIOAudioInputPortSubTypeInternalMicrophone;
debugIOLog ( 3, " add input selection of '%4s'", &temp);
break;
case kIOAudioInputPortSubTypeExternalMicrophone:
mExternalMicrophoneInputString = inputString;
temp = kIOAudioInputPortSubTypeExternalMicrophone;
debugIOLog ( 3, " add input selection of '%4s'", &temp);
break;
case kIOAudioInputPortSubTypeLine:
mLineInputString = inputString;
temp = kIOAudioInputPortSubTypeLine;
debugIOLog ( 3, " add input selection of '%4s'", &temp);
break;
case kIOAudioInputPortSubTypeSPDIF:
mDigitalInputString = inputString;
temp = kIOAudioInputPortSubTypeSPDIF;
debugIOLog ( 3, " add input selection of '%4s'", &temp);
break;
default:
debugIOLog (2, " AppleOnboardAudio[%ld]::createInputSelectorControl: unknown input selection", mInstanceIndex);
}
debugIOLog ( 3, " mInputSelector->addAvailableSelection ( '%4s', %p )", (char*)&inputSelection, inputString );
mInputSelector->addAvailableSelection (inputSelection, inputString);
}
if (mAutoSelectInput) {
if (TRUE == mInputSelector->valueExists(kIOAudioInputPortSubTypeSPDIF)) {
mInputSelector->removeAvailableSelection(kIOAudioInputPortSubTypeSPDIF);
}
}
}
debugIOLog ( 3, " AppleOnboardAudio[%ld]::createInputSelectorControl - mInputSelector = %p cur selector=%lx", mInstanceIndex, mInputSelector, mInputSelector->getIntValue());
result = kIOReturnSuccess;
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::createInputSelectorControl() returns %lX", mInstanceIndex, result );
return result;
}
IOReturn AppleOnboardAudio::createOutputSelectorControl (void) {
char outputSelectionCString[5];
OSDictionary * theDictionary;
OSNumber * terminalTypeNum;
OSString * outputString;
OSString * outputSelectionString;
OSArray * outputsList;
IOReturn result;
UInt32 outputsCount;
UInt32 outputSelection;
UInt32 index;
UInt16 terminalType;
UInt32 temp;
result = kIOReturnError;
outputsList = OSDynamicCast (OSArray, getLayoutEntry (kOutputsList, this));
if ( 0 != outputsList ) {
outputsCount = outputsList->getCount ();
outputString = OSDynamicCast (OSString, outputsList->getObject (0));
FailIf (0 == outputString, Exit);
theDictionary = OSDictionary::withCapacity (outputsCount);
FailIf (0 == theDictionary, Exit);
outputSelection = getCharCodeForString (outputString);
mOutputSelector = IOAudioSelectorControl::createOutputSelector (outputSelection, kIOAudioControlChannelIDAll);
if ( 0 == mOutputSelector ) { debugIOLog ( 3, "createOutputSelector for '%4s' FAILED", (char*)&outputSelection ); }
FailIf (0 == mOutputSelector, Exit);
mDriverDMAEngine->addDefaultAudioControl (mOutputSelector);
mOutputSelector->setValueChangeHandler ((IOAudioControl::IntValueChangeHandler)outputControlChangeHandler, this);
for (index = 0; index < outputsCount; index++) {
outputString = OSDynamicCast (OSString, outputsList->getObject (index));
FailIf (0 == outputString, Exit);
outputSelection = getCharCodeForString (outputString);
switch (outputSelection) {
case kIOAudioOutputPortSubTypeInternalSpeaker:
mInternalSpeakerOutputString = outputString;
temp = kIOAudioOutputPortSubTypeInternalSpeaker;
debugIOLog ( 3, " add output selection of '%4s'", &temp);
break;
case kIOAudioOutputPortSubTypeExternalSpeaker:
mExternalSpeakerOutputString = outputString;
temp = kIOAudioOutputPortSubTypeExternalSpeaker;
debugIOLog ( 3, " add output selection of '%4s'", &temp);
break;
case kIOAudioOutputPortSubTypeLine:
mLineOutputString = outputString;
temp = kIOAudioOutputPortSubTypeLine;
debugIOLog ( 3, " add output selection of '%4s'", &temp);
break;
case kIOAudioOutputPortSubTypeSPDIF:
mHasSPDIFControl = true; mDigitalOutputString = outputString;
temp = kIOAudioOutputPortSubTypeSPDIF;
debugIOLog ( 3, " add output selection of '%4s'", &temp);
break;
case kIOAudioOutputPortSubTypeHeadphones:
mHeadphoneOutputString = outputString;
temp = kIOAudioOutputPortSubTypeHeadphones;
debugIOLog ( 3, " add output selection of '%4s'", &temp);
break;
default:
debugIOLog (2, " AppleOnboardAudio[%ld]::createOutputSelectorControl: unknown output selection", mInstanceIndex);
}
terminalType = getTerminalTypeForCharCode (outputSelection);
terminalTypeNum = OSNumber::withNumber (terminalType, 16);
FailIf (0 == terminalTypeNum, Exit);
*(UInt32 *)outputSelectionCString = outputSelection;
outputSelectionCString[4] = 0;
outputSelectionString = OSString::withCString (outputSelectionCString);
FailIf (0 == outputSelectionString, Exit);
theDictionary->setObject (outputSelectionString, terminalTypeNum);
terminalTypeNum->release ();
outputSelectionString->release ();
debugIOLog ( 3, " mOutputSelector->addAvailableSelection ( '%4s', %p )", (char*)&outputSelection, outputString );
mOutputSelector->addAvailableSelection (outputSelection, outputString);
}
if ( ( 0 != mInternalSpeakerOutputString ) && ( 0 != mExternalSpeakerOutputString ) ) {
if ( kGPIO_Connected == mPlatformInterface->getSpeakerConnected() ) {
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeInternalSpeaker );
debugIOLog ( 6, " removed internal speaker from output selector ****");
} else {
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeExternalSpeaker );
debugIOLog ( 6, " removed External Speaker from output selector");
}
}
if ( (kGPIO_Unknown != mPlatformInterface->getComboOutJackTypeConnected ()) ) {
if ( kGPIO_Connected == mPlatformInterface->getLineOutConnected () ) {
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeSPDIF );
debugIOLog ( 6, " removed SPDIF from output selector");
} else if ( kGPIO_Connected == mPlatformInterface->getDigitalOutConnected () ) {
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeLine );
debugIOLog ( 6, " removed Line from output selector");
} else {
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeSPDIF );
debugIOLog ( 6, " removed SPDIF from output selector");
mOutputSelector->removeAvailableSelection ( kIOAudioOutputPortSubTypeLine );
debugIOLog ( 6, " removed Line from output selector");
}
}
mDriverDMAEngine->setProperty ("MappingDictionary", theDictionary);
debugIOLog ( 3, " AppleOnboardAudio[%ld]::createOutputSelectorControl - mOutputSelector = %p cur selector=%lx", mInstanceIndex, mOutputSelector,mOutputSelector->getIntValue());
}
result = kIOReturnSuccess;
Exit:
return result;
}
AudioHardwareObjectInterface * AppleOnboardAudio::getPluginObjectForConnection (const char * entry) {
AudioHardwareObjectInterface * thePluginObject;
OSDictionary * dictEntry;
OSString * pluginIDMatch;
if ( 0 != entry ) {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::getPluginObjectForConnection ( %p->'%s' )", mInstanceIndex, entry, entry );
} else {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::getPluginObjectForConnection ( %p )", mInstanceIndex, entry );
}
thePluginObject = 0;
pluginIDMatch = 0;
dictEntry = 0;
dictEntry = OSDynamicCast (OSDictionary, getLayoutEntry (entry, this));
FailIf (0 == dictEntry, Exit);
pluginIDMatch = OSDynamicCast (OSString, dictEntry->getObject (kPluginID));
FailIf (0 == pluginIDMatch, Exit);
thePluginObject = getPluginObjectWithName (pluginIDMatch);
debugIOLog ( 3, " pluginID = %s", pluginIDMatch->getCStringNoCopy());
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::getPluginObjectForConnection ( %p ) returns %p", mInstanceIndex, entry, thePluginObject );
return thePluginObject;
}
GpioAttributes AppleOnboardAudio::getInputDataMuxForConnection (const char * entry)
{
OSDictionary * dictEntry;
OSNumber * inputDataMuxOSNumber;
GpioAttributes result;
dictEntry = 0;
result = kGPIO_Unknown;
dictEntry = OSDynamicCast (OSDictionary, getLayoutEntry (entry, this));
FailIf (0 == dictEntry, Exit);
inputDataMuxOSNumber = OSDynamicCast ( OSNumber, dictEntry->getObject ( kInputDataMux ) );
if ( 0 != inputDataMuxOSNumber )
{
if ( 0 == inputDataMuxOSNumber->unsigned32BitValue() )
{
result = kGPIO_MuxSelectDefault;
}
else
{
result = kGPIO_MuxSelectAlternate;
}
}
Exit:
debugIOLog ( 3, "± AppleOnboardAudio[%ld]::getInputDataMuxForConnection returns GpioAttributes = %d", mInstanceIndex, result);
return result;
}
AudioHardwareObjectInterface * AppleOnboardAudio::getPluginObjectWithName (OSString * inName) {
AudioHardwareObjectInterface * thePluginObject;
OSDictionary * AOAprop;
OSString * thePluginID;
UInt32 index;
UInt32 count;
Boolean found;
thePluginObject = 0;
FailIf (NULL == mPluginObjects, Exit);
count = mPluginObjects->getCount ();
found = FALSE;
index = 0;
while (!found && index < count) {
thePluginObject = getIndexedPluginObject (index);
FailIf (0 == thePluginObject, Exit);
AOAprop = OSDynamicCast (OSDictionary, thePluginObject->getProperty (kPluginPListAOAAttributes));
FailIf (0 == AOAprop, Exit);
thePluginID = OSDynamicCast (OSString, AOAprop->getObject (kPluginID));
FailIf (0 == thePluginID, Exit);
if (thePluginID->isEqualTo (inName)) {
debugIOLog ( 7, "± AppleOnboardAudio[%ld]::getPluginObjectWithName ( %p ) found matching plugin with ID '%s'", mInstanceIndex, inName, thePluginID->getCStringNoCopy());
found = TRUE;
}
index++;
}
Exit:
return thePluginObject;
}
IOReturn AppleOnboardAudio::createInputGainControls () {
AudioHardwareObjectInterface * thePluginObject;
char * selectedInput;
IOReturn result;
IOFixed mindBGain = 0;
IOFixed maxdBGain = 0;
UInt32 curSelection = 0;
SInt32 minGain = 0;
SInt32 maxGain = 0;
SInt32 defaultInputGain = 0;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::createInputGainControls()", mInstanceIndex );
result = kIOReturnError;
curSelection = mInputSelector->getIntValue ();
selectedInput = getConnectionKeyFromCharCode (curSelection, kIOAudioStreamDirectionInput);
setUseInputGainControls (selectedInput);
if ( kNoInputGainControls != mUseInputGainControls ) {
thePluginObject = getPluginObjectForConnection (selectedInput);
FailIf (0 == thePluginObject, Exit);
debugIOLog ( 3, " creating input gain controls for input %s", selectedInput);
mindBGain = thePluginObject->getMinimumdBGain ();
maxdBGain = thePluginObject->getMaximumdBGain ();
minGain = thePluginObject->getMinimumGain ();
maxGain = thePluginObject->getMaximumGain ();
defaultInputGain = thePluginObject->getDefaultInputGain ();
}
if ( kStereoInputGainControls == mUseInputGainControls ) {
debugIOLog ( 3, " mInLeftGainControl = IOAudioLevelControl::createVolumeControl( %ld, %ld, %ld, %lX, %lX, %ld, %p, 0, %lX )", defaultInputGain, minGain, maxGain, mindBGain, maxdBGain, kIOAudioControlChannelIDDefaultLeft, kIOAudioControlChannelNameLeft, 0, kIOAudioControlUsageInput);
mInLeftGainControl = IOAudioLevelControl::createVolumeControl (defaultInputGain, minGain, maxGain, mindBGain, maxdBGain, kIOAudioControlChannelIDDefaultLeft, kIOAudioControlChannelNameLeft, 0, kIOAudioControlUsageInput);
if (0 != mInLeftGainControl) {
mDriverDMAEngine->addDefaultAudioControl (mInLeftGainControl);
mInLeftGainControl->setValueChangeHandler ((IOAudioControl::IntValueChangeHandler)inputControlChangeHandler, this);
}
debugIOLog ( 3, " mInRightGainControl = IOAudioLevelControl::createVolumeControl( %ld, %ld, %ld, %lX, %lX, %ld, %p, 0, %lX )", defaultInputGain, minGain, maxGain, mindBGain, maxdBGain, kIOAudioControlChannelIDDefaultRight, kIOAudioControlChannelNameRight, 0, kIOAudioControlUsageInput);
mInRightGainControl = IOAudioLevelControl::createVolumeControl (defaultInputGain, minGain, maxGain, mindBGain, maxdBGain, kIOAudioControlChannelIDDefaultRight, kIOAudioControlChannelNameRight, 0, kIOAudioControlUsageInput);
if (0 != mInRightGainControl) {
mDriverDMAEngine->addDefaultAudioControl (mInRightGainControl);
mInRightGainControl->setValueChangeHandler ((IOAudioControl::IntValueChangeHandler)inputControlChangeHandler, this);
}
} else if ( kMonoInputGainControl == mUseInputGainControls ){
debugIOLog ( 3, " mInMasterGainControl = IOAudioLevelControl::createVolumeControl( %ld, %ld, %ld, %lX, %lX, %ld, %p, 0, %lX )", defaultInputGain, minGain, maxGain, mindBGain, maxdBGain, kIOAudioControlChannelIDAll, kIOAudioControlChannelNameAll, 0, kIOAudioControlUsageInput);
mInMasterGainControl = IOAudioLevelControl::createVolumeControl (defaultInputGain, minGain, maxGain, mindBGain, maxdBGain, kIOAudioControlChannelIDAll, kIOAudioControlChannelNameAll, 0, kIOAudioControlUsageInput);
if (0 != mInMasterGainControl) {
mDriverDMAEngine->addDefaultAudioControl ( mInMasterGainControl );
mInMasterGainControl->setValueChangeHandler ( (IOAudioControl::IntValueChangeHandler)inputControlChangeHandler, this );
}
}
removePlayThruControl ();
setUsePlaythroughControl ( selectedInput );
if ( mUsePlaythroughControl ) {
createPlayThruControl ();
}
result = kIOReturnSuccess;
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::createInputGainControls() returns %lX", mInstanceIndex, result );
return result;
}
OSArray * AppleOnboardAudio::getControlsArray (const char * inSelectedOutput) {
OSArray * theArray;
OSDictionary * theOutput;
theArray = 0;
theOutput = OSDynamicCast(OSDictionary, getLayoutEntry(inSelectedOutput, this));
FailIf (0 == theOutput, Exit);
theArray = OSDynamicCast(OSArray, theOutput->getObject(kControls));
Exit:
return theArray;
}
UInt32 AppleOnboardAudio::getNumHardwareEQBandsForCurrentOutput () {
OSDictionary * AOApropOutput;
OSNumber * numBandsNumber;
UInt32 numBands;
numBands = 0;
AOApropOutput = OSDynamicCast (OSDictionary, mCurrentOutputPlugin->getProperty (kPluginPListAOAAttributes));
if (0 != AOApropOutput) {
numBandsNumber = OSDynamicCast (OSNumber, AOApropOutput->getObject (kPluginPListNumHardwareEQBands));
if (0 != numBandsNumber) {
numBands = numBandsNumber->unsigned32BitValue();
}
}
return numBands;
}
UInt32 AppleOnboardAudio::getMaxVolumeOffsetForOutput (const UInt32 inCode) {
char * connectionString;
connectionString = getConnectionKeyFromCharCode (inCode, kIOAudioStreamDirectionOutput);
return getMaxVolumeOffsetForOutput (connectionString);
}
UInt32 AppleOnboardAudio::getMaxVolumeOffsetForOutput (const char * inSelectedOutput) {
OSDictionary * theSpeakerIDDict;
OSDictionary * theSignalProcessingDict;
OSDictionary * theOutput;
OSNumber * theMaxVolumeNumber;
OSString * speakerIDString;
char speakerIDCString[32];
UInt32 maxVolumeOffset;
maxVolumeOffset = 0;
theOutput = OSDynamicCast(OSDictionary, getLayoutEntry (inSelectedOutput, this));
FailIf (0 == theOutput, Exit);
theSignalProcessingDict = OSDynamicCast (OSDictionary, theOutput->getObject (kSignalProcessing));
if ( 0 != theSignalProcessingDict ) {
sprintf (speakerIDCString, "%s_%ld", kSpeakerID, mInternalSpeakerID);
speakerIDString = OSString::withCString (speakerIDCString);
FailIf (0 == speakerIDString, Exit);
theSpeakerIDDict = OSDynamicCast (OSDictionary, theSignalProcessingDict->getObject (speakerIDString));
speakerIDString->release ();
FailIf (0 == theSpeakerIDDict, Exit);
theMaxVolumeNumber = OSDynamicCast (OSNumber, theSpeakerIDDict->getObject (kMaxVolumeOffset));
if (0 != theMaxVolumeNumber) {
maxVolumeOffset = theMaxVolumeNumber->unsigned32BitValue ();
}
}
Exit:
return maxVolumeOffset;
}
void AppleOnboardAudio::setSoftwareOutputDSP (const char * inSelectedOutput) {
OSDictionary * theSpeakerIDDict;
OSDictionary * theSignalProcessingDict;
OSDictionary * theOutput;
OSDictionary * theSoftwareDSPDict;
OSString * speakerIDString;
char speakerIDCString[32];
if ( 0 == inSelectedOutput ) {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::setSoftwareOutputDSP (%p).", mInstanceIndex, inSelectedOutput);
} else {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::setSoftwareOutputDSP ('%s').", mInstanceIndex, inSelectedOutput);
}
FailIf ( 0 == inSelectedOutput, Exit );
if (mCurrentProcessingOutputString->isEqualTo (inSelectedOutput)) {
debugIOLog ( 3, " Enabling DSP");
mDriverDMAEngine->enableOutputProcessing ();
debugIOLog ( 3, " mCurrentProcessingOutputString is '%s', coefficients not updated.", mCurrentProcessingOutputString->getCStringNoCopy ());
} else {
mDriverDMAEngine->disableOutputProcessing ();
debugIOLog ( 3, " processing disabled.");
theOutput = OSDynamicCast(OSDictionary, getLayoutEntry (inSelectedOutput, this));
FailIf (0 == theOutput, Exit);
theSignalProcessingDict = OSDynamicCast (OSDictionary, theOutput->getObject (kSignalProcessing));
if ( 0 != theSignalProcessingDict ) {
sprintf (speakerIDCString, "%s_%ld", kSpeakerID, mInternalSpeakerID);
debugIOLog ( 3, " setSoftwareOutputDSP: speakerIDString = '%s'", speakerIDCString);
speakerIDString = OSString::withCString (speakerIDCString);
FailIf (0 == speakerIDString, Exit);
theSpeakerIDDict = OSDynamicCast (OSDictionary, theSignalProcessingDict->getObject (speakerIDString));
speakerIDString->release ();
FailIf (0 == theSpeakerIDDict, Exit);
debugIOLog ( 3, " setSoftwareOutputDSP: theSpeakerIDDict = %p", theSpeakerIDDict);
theSoftwareDSPDict = OSDynamicCast (OSDictionary, theSpeakerIDDict->getObject (kSoftwareDSP));
if (0 != theSoftwareDSPDict) {
debugIOLog ( 3, " setSoftwareOutputDSP: theSoftwareDSPDict = %p", theSoftwareDSPDict);
mDriverDMAEngine->setOutputSignalProcessing (theSoftwareDSPDict);
debugIOLog ( 3, " Processing set");
debugIOLog ( 3, " mCurrentProcessingOutputString is '%s'", mCurrentProcessingOutputString->getCStringNoCopy ());
mCurrentProcessingOutputString->initWithCString (inSelectedOutput);
debugIOLog ( 3, " mCurrentProcessingOutputString set to '%s', coefficients will be updated.", mCurrentProcessingOutputString->getCStringNoCopy ());
}
}
}
Exit:
if ( 0 == inSelectedOutput ) {
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::setSoftwareOutputDSP (%p).", mInstanceIndex, inSelectedOutput);
} else {
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::setSoftwareOutputDSP ('%s').", mInstanceIndex, inSelectedOutput);
}
return;
}
void AppleOnboardAudio::setSoftwareInputDSP (const char * inSelectedInput) {
OSDictionary * theSignalProcessingDict;
OSDictionary * theMicrophoneIDDict;
OSDictionary * theSiliconVersionDict;
OSDictionary * theSoftwareDSPDict;
OSDictionary * theInput;
OSString * microphoneIDString;
char microphoneIDCString[32];
OSString * siliconVersionString;
char siliconVersionCString[32];
if ( 0 == inSelectedInput ) {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::setSoftwareInputDSP ( %p )", mInstanceIndex, inSelectedInput );
} else {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::setSoftwareInputDSP ( %p->'%s' )", mInstanceIndex, inSelectedInput, inSelectedInput );
}
FailIf ( 0 == inSelectedInput, Exit );
if (mCurrentProcessingInputString->isEqualTo (inSelectedInput)) {
debugIOLog ( 3, " Enabling input DSP");
mDriverDMAEngine->enableInputProcessing ();
debugIOLog ( 3, " mCurrentProcessingInputString is '%s', coefficients not updated.", mCurrentProcessingInputString->getCStringNoCopy ());
} else {
debugIOLog ( 3, " Disabling input DSP");
mDriverDMAEngine->disableInputProcessing ();
debugIOLog ( 3, " input processing disabled.");
theInput = OSDynamicCast(OSDictionary, getLayoutEntry (inSelectedInput, this));
FailIf (0 == theInput, Exit);
theSignalProcessingDict = OSDynamicCast (OSDictionary, theInput->getObject (kSignalProcessing));
if (0 != theSignalProcessingDict) {
sprintf (microphoneIDCString, "%s_%ld", kMicrophoneID, mInternalMicrophoneID);
debugIOLog ( 3, " setSoftwareInputDSP: inputDeviceIDString = %s", microphoneIDCString);
microphoneIDString = OSString::withCString (microphoneIDCString);
FailIf (0 == microphoneIDString, Exit);
theMicrophoneIDDict = OSDynamicCast (OSDictionary, theSignalProcessingDict->getObject (microphoneIDString));
microphoneIDString->release ();
FailIf (0 == theMicrophoneIDDict, Exit);
debugIOLog ( 3, " setSoftwareInputDSP: theMicrophoneIDDict = %p", theMicrophoneIDDict);
sprintf (siliconVersionCString, "%s_%ld", kSiliconVersion, mSiliconVersion);
debugIOLog ( 3, " setSoftwareInputDSP: siliconVersionString = %s", siliconVersionCString);
siliconVersionString = OSString::withCString (siliconVersionCString);
FailIf (0 == siliconVersionString, Exit);
theSiliconVersionDict = OSDynamicCast (OSDictionary, theMicrophoneIDDict->getObject (siliconVersionString));
siliconVersionString->release ();
FailIf (0 == theSiliconVersionDict, Exit);
debugIOLog ( 3, " setSoftwareInputDSP: theSiliconVersionDict = %p", theSiliconVersionDict);
theSoftwareDSPDict = OSDynamicCast (OSDictionary, theSiliconVersionDict->getObject (kSoftwareDSP));
FailIf (0 == theSoftwareDSPDict, Exit);
debugIOLog ( 3, " setSoftwareInputDSP: theSoftwareDSPDict = %p", theSoftwareDSPDict);
mDriverDMAEngine->setInputSignalProcessing (theSoftwareDSPDict);
debugIOLog ( 3, " Input processing set");
debugIOLog ( 3, " mCurrentProcessingInputString is '%s'", mCurrentProcessingInputString->getCStringNoCopy ());
mCurrentProcessingInputString->initWithCString (inSelectedInput);
debugIOLog ( 3, " mCurrentProcessingInputString set to '%s', coefficients will be updated.", mCurrentProcessingInputString->getCStringNoCopy ());
}
}
Exit:
if ( 0 == inSelectedInput ) {
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::setSoftwareInputDSP ( %p )", mInstanceIndex, inSelectedInput );
} else {
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::setSoftwareInputDSP ( %p->'%s' )", mInstanceIndex, inSelectedInput, inSelectedInput );
}
return;
}
UInt32 AppleOnboardAudio::setClipRoutineForOutput (const char * inSelectedOutput) {
OSDictionary * theOutput;
OSString * clipRoutineString;
OSArray * theArray;
IOReturn result = kIOReturnError;
UInt32 arrayCount;
UInt32 index;
if ( 0 == inSelectedOutput ) {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::setClipRoutineForOutput ( %p )", mInstanceIndex, inSelectedOutput);
} else {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::setClipRoutineForOutput ( %p->'%4s' )", mInstanceIndex, inSelectedOutput, inSelectedOutput );
}
FailIf ( 0 == inSelectedOutput, Exit );
theArray = 0;
theOutput = OSDynamicCast(OSDictionary, getLayoutEntry(inSelectedOutput, this));
FailIf (0 == theOutput, Exit);
theArray = OSDynamicCast(OSArray, theOutput->getObject(kClipRoutines));
FailIf (0 == theArray, Exit);
arrayCount = theArray->getCount();
mDriverDMAEngine->resetOutputClipOptions();
for (index = 0; index < arrayCount; index++) {
clipRoutineString = OSDynamicCast(OSString, theArray->getObject(index));
debugIOLog ( 3, " clip routine[%ld] = %s", index, clipRoutineString->getCStringNoCopy());
if (clipRoutineString->isEqualTo (kStereoToRightChanClipString)) {
mDriverDMAEngine->setRightChanMixed (true);
} else {
mDriverDMAEngine->resetOutputClipOptions();
}
}
result = kIOReturnSuccess;
Exit:
if ( 0 == inSelectedOutput ) {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::setClipRoutineForOutput ( %p ) returns 0x%lX", mInstanceIndex, inSelectedOutput, result);
} else {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::setClipRoutineForOutput ( %p->'%4s' ) returns 0x%lX", mInstanceIndex, inSelectedOutput, inSelectedOutput, result );
}
return result;
}
UInt32 AppleOnboardAudio::setClipRoutineForInput (const char * inSelectedInput) {
OSDictionary * theInput;
OSString * clipRoutineString;
OSArray * theArray;
IOReturn result = kIOReturnError;
UInt32 arrayCount;
UInt32 index;
if ( 0 == inSelectedInput ) {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::setClipRoutineForInput ( %p )", mInstanceIndex, inSelectedInput);
} else {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::setClipRoutineForInput ( %p->'%4s' )", mInstanceIndex, inSelectedInput, inSelectedInput );
}
FailIf ( 0 == inSelectedInput, Exit );
theArray = 0;
theInput = OSDynamicCast(OSDictionary, getLayoutEntry(inSelectedInput, this));
FailIf (0 == theInput, Exit);
theArray = OSDynamicCast(OSArray, theInput->getObject(kClipRoutines));
FailIf (0 == theArray, Exit);
arrayCount = theArray->getCount();
mDriverDMAEngine->resetInputClipOptions();
for (index = 0; index < arrayCount; index++) {
clipRoutineString = OSDynamicCast(OSString, theArray->getObject(index));
debugIOLog ( 3, " clip routine[%ld] = %s", index, clipRoutineString->getCStringNoCopy());
if (clipRoutineString->isEqualTo (kCopyLeftToRight)) {
mDriverDMAEngine->setDualMonoMode (e_Mode_CopyLeftToRight);
} else if (clipRoutineString->isEqualTo (kCopyRightToLeft)) {
mDriverDMAEngine->setDualMonoMode (e_Mode_CopyRightToLeft);
}
}
result = kIOReturnSuccess;
Exit:
if ( 0 == inSelectedInput ) {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::setClipRoutineForInput ( %p ) returns 0x%lX", mInstanceIndex, inSelectedInput, result);
} else {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::setClipRoutineForInput ( %p->'%4s' ) returns 0x%lX", mInstanceIndex, inSelectedInput, inSelectedInput, result);
}
return result;
}
void AppleOnboardAudio::cacheOutputVolumeLevels (AudioHardwareObjectInterface * thePluginObject) {
if (0 != mOutMasterVolumeControl) {
mCurrentOutputPlugin->setProperty(kPluginPListMasterVol, mOutMasterVolumeControl->getValue ());
} else {
OSNumber * theNumber;
theNumber = OSNumber::withNumber ((unsigned long long)-1, 32);
if (0 != mOutLeftVolumeControl) {
mCurrentOutputPlugin->setProperty(kPluginPListLeftVol, mOutLeftVolumeControl->getValue ());
mCurrentOutputPlugin->setProperty(kPluginPListMasterVol, theNumber);
}
if (0 != mOutRightVolumeControl) {
mCurrentOutputPlugin->setProperty(kPluginPListRightVol, mOutRightVolumeControl->getValue ());
mCurrentOutputPlugin->setProperty(kPluginPListMasterVol, theNumber);
}
theNumber->release ();
}
return;
}
void AppleOnboardAudio::cacheInputGainLevels (AudioHardwareObjectInterface * thePluginObject) {
if (0 != mInLeftGainControl) {
mCurrentInputPlugin->setProperty(kPluginPListLeftGain, mInLeftGainControl->getValue ());
}
if (0 != mInRightGainControl) {
mCurrentInputPlugin->setProperty(kPluginPListRightGain, mInRightGainControl->getValue ());
}
if ( 0 != mInMasterGainControl ) {
mCurrentInputPlugin->setProperty ( kPluginPListMasterGain, mInMasterGainControl->getValue () );
}
return;
}
IOReturn AppleOnboardAudio::createOutputVolumeControls (void) {
AudioHardwareObjectInterface * thePluginObject;
OSArray * controlsArray;
OSString * controlString;
char * selectedOutput;
IOReturn result;
UInt32 curSelection;
UInt32 count;
UInt32 index;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::createOutputVolumeControls()", mInstanceIndex);
result = kIOReturnError;
if ( 0 != mOutputSelector ) {
curSelection = mOutputSelector->getIntValue ();
selectedOutput = getConnectionKeyFromCharCode(curSelection, kIOAudioStreamDirectionOutput);
thePluginObject = getPluginObjectForConnection (selectedOutput);
FailIf (0 == thePluginObject, Exit);
AdjustOutputVolumeControls (thePluginObject, curSelection);
controlsArray = getControlsArray (selectedOutput);
FailIf (0 == controlsArray, Exit);
count = controlsArray->getCount ();
for (index = 0; index < count; index++) {
controlString = OSDynamicCast (OSString, controlsArray->getObject (index));
if (controlString->isEqualTo (kMuteControlString)) {
mOutMuteControl = IOAudioToggleControl::createMuteControl (false, kIOAudioControlChannelIDAll, kIOAudioControlChannelNameAll, 0, kIOAudioControlUsageOutput);
if (0 != mOutMuteControl) {
mDriverDMAEngine->addDefaultAudioControl(mOutMuteControl);
mOutMuteControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)outputControlChangeHandler, this);
}
break; }
}
} else {
result = kIOReturnSuccess;
}
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::createOutputVolumeControls()", mInstanceIndex);
return result;
}
IOReturn AppleOnboardAudio::createDefaultControls () {
AudioHardwareObjectInterface * thePluginObject;
OSDictionary * AOAprop;
OSBoolean * clockSelectBoolean;
OSArray * inputListArray;
UInt32 index;
UInt32 count;
IOReturn result;
Boolean hasPlaythrough;
Boolean hasInput;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::createDefaultControls()", mInstanceIndex);
hasPlaythrough = FALSE;
result = kIOReturnError;
FailIf (0 == mDriverDMAEngine, Exit);
count = mPluginObjects->getCount ();
for (index = 0; index < count; index++) {
thePluginObject = getIndexedPluginObject (index);
FailIf (0 == thePluginObject, Exit);
AOAprop = OSDynamicCast (OSDictionary, thePluginObject->getProperty (kPluginPListAOAAttributes));
FailIf (0 == AOAprop, Exit);
}
result = createOutputSelectorControl ();
FailIf (kIOReturnSuccess != result, Exit);
createOutputVolumeControls ();
if ( !mSpressBootChimeLevelControl ) { mPRAMVolumeControl = IOAudioLevelControl::create (PRAMToVolumeValue (), 0, 7, 0x00120000, 0, kIOAudioControlChannelIDAll, "BootBeepVolume", 0, kIOAudioLevelControlSubTypePRAMVolume, kIOAudioControlUsageOutput);
if (0 != mPRAMVolumeControl) {
mDriverDMAEngine->addDefaultAudioControl (mPRAMVolumeControl);
mPRAMVolumeControl->setValueChangeHandler ((IOAudioControl::IntValueChangeHandler)outputControlChangeHandler, this);
mPRAMVolumeControl->release ();
mPRAMVolumeControl = 0;
}
}
mHeadphoneConnected = IOAudioToggleControl::create (FALSE, kIOAudioControlChannelIDAll, kIOAudioControlChannelNameAll, 0, kIOAudioControlTypeJack, kIOAudioControlUsageOutput);
if (0 != mHeadphoneConnected) {
mDriverDMAEngine->addDefaultAudioControl (mHeadphoneConnected);
mHeadphoneConnected->setReadOnlyFlag (); }
inputListArray = OSDynamicCast (OSArray, getLayoutEntry (kInputsList, this));
hasInput = (0 != inputListArray);
if (hasInput) {
createInputSelectorControl ();
createInputGainControls ();
}
clockSelectBoolean = OSDynamicCast ( OSBoolean, getLayoutEntry (kExternalClockSelect, this) );
if (0 != clockSelectBoolean) {
if (TRUE == clockSelectBoolean->getValue ()) {
mExternalClockSelector = IOAudioSelectorControl::create (kClockSourceSelectionInternal, kIOAudioControlChannelIDAll, kIOAudioControlChannelNameAll, 0, kIOAudioSelectorControlSubTypeClockSource, kIOAudioControlUsageInput);
FailIf (0 == mExternalClockSelector, Exit);
mDriverDMAEngine->addDefaultAudioControl (mExternalClockSelector);
mExternalClockSelector->setValueChangeHandler ((IOAudioControl::IntValueChangeHandler)inputControlChangeHandler, this);
mExternalClockSelector->addAvailableSelection (kClockSourceSelectionInternal, kInternalClockString);
mExternalClockSelector->addAvailableSelection (kClockSourceSelectionExternal, kExternalClockString);
}
}
else { if ( mAutoSelectClock ) {
mExternalClockSelector = IOAudioSelectorControl::create (kClockSourceSelectionInternal, kIOAudioControlChannelIDAll, kIOAudioControlChannelNameAll, 0, kIOAudioSelectorControlSubTypeClockSource, kIOAudioControlUsageInput);
FailIf (0 == mExternalClockSelector, Exit);
mDriverDMAEngine->addDefaultAudioControl (mExternalClockSelector);
mExternalClockSelector->setValueChangeHandler ((IOAudioControl::IntValueChangeHandler)inputControlChangeHandler, this);
mExternalClockSelector->addAvailableSelection (kClockSourceSelectionInternal, kInternalClockString);
}
}
result = kIOReturnSuccess;
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::createDefaultControls() returns 0x%lX", mInstanceIndex, result);
return result;
}
AppleOnboardAudio* AppleOnboardAudio::findAOAInstanceWithLayoutID ( UInt32 layoutID ) {
AppleOnboardAudio * theAOA;
AppleOnboardAudio * result = 0;
UInt32 numInstances;
if ( 0 != mAOAInstanceArray ) {
numInstances = mAOAInstanceArray->getCount();
for ( UInt32 index = 0; index < numInstances && ( 0 == result ); index++ ) {
theAOA = OSDynamicCast ( AppleOnboardAudio, mAOAInstanceArray->getObject ( index ) );
if ( theAOA->getLayoutID() == layoutID ) {
result = theAOA;
}
}
}
debugIOLog ( 3, "± AppleOnboardAudio[%ld]::findAOAInstanceWithLayoutID ( %d ), this = %p, returns %p", mInstanceIndex, layoutID, this, result );
return result;
}
#pragma mark +IOAUDIO CONTROL HANDLERS
IOReturn AppleOnboardAudio::AdjustOutputVolumeControls (AudioHardwareObjectInterface * thePluginObject, UInt32 selectionCode) {
IOFixed mindBVol;
IOFixed maxdBVol;
SInt32 minVolume;
SInt32 maxVolume;
UInt32 engineState;
Boolean hasMaster;
Boolean hasLeft;
Boolean hasRight;
Boolean stereoOutputConnected;
FailIf (0 == mDriverDMAEngine, Exit);
mindBVol = thePluginObject->getMinimumdBVolume ();
maxdBVol = thePluginObject->getMaximumdBVolume ();
minVolume = thePluginObject->getMinimumVolume ();
maxVolume = thePluginObject->getMaximumVolume ();
maxVolume += getMaxVolumeOffsetForOutput (selectionCode);
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::AdjustOutputVolumeControls( %p, '%4s' ) - mindBVol %lX, maxdBVol %lX, minVolume %ld, maxVolume %ld",
mInstanceIndex, thePluginObject, (char*)&selectionCode, mindBVol, maxdBVol, minVolume, maxVolume);
engineState = mDriverDMAEngine->getState();
debugIOLog (5, "AppleOnboardAudio[%ld]::AdjustOutputVolumeControls - about to try to mDriverDMAEngine->pauseAudioEngine...engine state = %lu", mInstanceIndex, engineState);
if ( ( kIOAudioEngineRunning == engineState ) || ( kIOAudioEngineResumed == engineState ) ) {
mDriverDMAEngine->pauseAudioEngine ();
}
mDriverDMAEngine->beginConfigurationChange ();
if ( ((kIOAudioOutputPortSubTypeSPDIF == selectionCode) && (kGPIO_Unknown == mPlatformInterface->getComboOutJackTypeConnected())) || (kIOAudioOutputPortSubTypeSPDIF != selectionCode) ) {
debugIOLog ( 3, " output is not exclusive digital output!" );
hasMaster = hasMasterVolumeControl (selectionCode);
hasLeft = hasLeftVolumeControl (selectionCode);
hasRight = hasRightVolumeControl (selectionCode);
if ((hasMaster || hasLeft || hasRight) && (FALSE == thePluginObject->hasHardwareVolume ())) {
debugIOLog ( 3, " have volume controls and need software implementation.");
mCurrentPluginNeedsSoftwareOutputVolume = TRUE;
mDriverDMAEngine->setUseSoftwareOutputVolume (TRUE, minVolume, maxVolume, mindBVol, maxdBVol);
} else {
debugIOLog ( 3, " no volume controls or don't need software implementation.");
mCurrentPluginNeedsSoftwareOutputVolume = FALSE;
mDriverDMAEngine->setUseSoftwareOutputVolume (FALSE);
}
if ((kGPIO_Connected == mPlatformInterface->getHeadphoneConnected ()) ||
(kGPIO_Connected == mPlatformInterface->getSpeakerConnected ()) ||
(kGPIO_Connected == mPlatformInterface->getLineOutConnected ()) ||
(kGPIO_Connected == mPlatformInterface->getDigitalOutConnected ())) {
stereoOutputConnected = true;
} else {
stereoOutputConnected = false;
}
if ((TRUE == hasMaster && 0 == mOutMasterVolumeControl) || (FALSE == hasMaster && 0 != mOutMasterVolumeControl) ||
(0 != mOutMasterVolumeControl && mOutMasterVolumeControl->getMinValue () != minVolume) ||
(0 != mOutMasterVolumeControl && mOutMasterVolumeControl->getMaxValue () != maxVolume)) {
if (TRUE == hasMaster) {
if (0 != mOutMasterVolumeControl) {
mOutMasterVolumeControl->setMinValue (minVolume);
mOutMasterVolumeControl->setMinDB (mindBVol);
mOutMasterVolumeControl->setMaxValue (maxVolume);
mOutMasterVolumeControl->setMaxDB (maxdBVol);
if (mOutMasterVolumeControl->getIntValue () > maxVolume) {
mOutMasterVolumeControl->setValue (maxVolume);
}
mOutMasterVolumeControl->flushValue ();
} else {
createMasterVolumeControl (mindBVol, maxdBVol, minVolume, maxVolume);
}
} else {
removeMasterVolumeControl();
}
}
if ((TRUE == hasLeft && 0 == mOutLeftVolumeControl) || (FALSE == hasLeft && 0 != mOutLeftVolumeControl) ||
(0 != mOutLeftVolumeControl && mOutLeftVolumeControl->getMinValue () != minVolume) ||
(0 != mOutLeftVolumeControl && mOutLeftVolumeControl->getMaxValue () != maxVolume)) {
if (TRUE == hasLeft) {
if (0 != mOutLeftVolumeControl) {
mOutLeftVolumeControl->setMinValue (minVolume);
mOutLeftVolumeControl->setMinDB (mindBVol);
mOutLeftVolumeControl->setMaxValue (maxVolume);
mOutLeftVolumeControl->setMaxDB (maxdBVol);
if (mOutLeftVolumeControl->getIntValue () > maxVolume) {
mOutLeftVolumeControl->setValue (maxVolume);
}
mOutLeftVolumeControl->flushValue ();
} else {
createLeftVolumeControl(mindBVol, maxdBVol, minVolume, maxVolume);
}
} else {
if (!stereoOutputConnected) {
removeLeftVolumeControl();
}
}
}
if ((TRUE == hasRight && 0 == mOutRightVolumeControl) || (FALSE == hasRight && 0 != mOutRightVolumeControl) ||
(0 != mOutRightVolumeControl && mOutRightVolumeControl->getMinValue () != minVolume) ||
(0 != mOutRightVolumeControl && mOutRightVolumeControl->getMaxValue () != maxVolume)) {
if (TRUE == hasRight) {
if (0 != mOutRightVolumeControl) {
mOutRightVolumeControl->setMinValue (minVolume);
mOutRightVolumeControl->setMinDB (mindBVol);
mOutRightVolumeControl->setMaxValue (maxVolume);
mOutRightVolumeControl->setMaxDB (maxdBVol);
if (mOutRightVolumeControl->getIntValue () > maxVolume) {
mOutRightVolumeControl->setValue (maxVolume);
}
mOutRightVolumeControl->flushValue ();
} else {
createRightVolumeControl(mindBVol, maxdBVol, minVolume, maxVolume);
}
} else {
if (!stereoOutputConnected) {
removeRightVolumeControl ();
}
}
}
} else {
debugIOLog ( 3, " output is exclusive digital output- removing all level controls!" );
mCurrentPluginNeedsSoftwareOutputVolume = FALSE;
mDriverDMAEngine->setUseSoftwareOutputVolume (FALSE);
removeMasterVolumeControl();
removeLeftVolumeControl();
removeRightVolumeControl ();
}
mDriverDMAEngine->completeConfigurationChange ();
engineState = mDriverDMAEngine->getState();
debugIOLog (5, "AppleOnboardAudio[%ld]::AdjustOutputVolumeControls - about to try to mDriverDMAEngine->resumeAudioEngine...engine state = %lu", mInstanceIndex, engineState);
if ( kIOAudioEnginePaused == engineState ) {
mDriverDMAEngine->resumeAudioEngine ();
if ( kIOAudioEngineResumed == mDriverDMAEngine->getState() ) {
mDriverDMAEngine->startAudioEngine ();
}
}
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::AdjustOutputVolumeControls( %p, '%4s' )", mInstanceIndex, thePluginObject, (char*)&selectionCode );
return kIOReturnSuccess;
}
IOReturn AppleOnboardAudio::AdjustInputGainControls (AudioHardwareObjectInterface * thePluginObject) {
IOFixed mindBGain;
IOFixed maxdBGain;
SInt32 minGain;
SInt32 maxGain;
UInt32 engineState;
FailIf (0 == mDriverDMAEngine, Exit);
mindBGain = thePluginObject->getMinimumdBGain ();
maxdBGain = thePluginObject->getMaximumdBGain ();
minGain = thePluginObject->getMinimumGain ();
maxGain = thePluginObject->getMaximumGain ();
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::AdjustInputGainControls ( %p )", mInstanceIndex, thePluginObject );
debugIOLog ( 3, " mindBGain %lX, maxdBGain %lX, minGain %ld, maxGain %ld", mInstanceIndex, mindBGain, maxdBGain, minGain, maxGain);
engineState = mDriverDMAEngine->getState();
debugIOLog (5, "AppleOnboardAudio[%ld]::AdjustInputGainControls - about to try to mDriverDMAEngine->pauseAudioEngine...engine state = %lu", mInstanceIndex, engineState);
if ( ( kIOAudioEngineRunning == engineState ) || ( kIOAudioEngineResumed == engineState ) ) {
mDriverDMAEngine->pauseAudioEngine ();
}
mDriverDMAEngine->beginConfigurationChange ();
removePlayThruControl ();
if ( mUsePlaythroughControl ) {
createPlayThruControl ();
}
if ( kStereoInputGainControls == mUseInputGainControls ) {
debugIOLog ( 3, " AdjustInputGainControls - creating input gain controls.");
if (0 != mInLeftGainControl) {
mInLeftGainControl->setMinValue (minGain);
mInLeftGainControl->setMinDB (mindBGain);
mInLeftGainControl->setMaxValue (maxGain);
mInLeftGainControl->setMaxDB (maxdBGain);
if (mInLeftGainControl->getIntValue () > maxGain) {
mInLeftGainControl->setValue (maxGain);
}
mInLeftGainControl->flushValue ();
} else {
createLeftGainControl(mindBGain, maxdBGain, minGain, maxGain);
}
if (0 != mInRightGainControl) {
mInRightGainControl->setMinValue (minGain);
mInRightGainControl->setMinDB (mindBGain);
mInRightGainControl->setMaxValue (maxGain);
mInRightGainControl->setMaxDB (maxdBGain);
if (mInRightGainControl->getIntValue () > maxGain) {
mInRightGainControl->setValue (maxGain);
}
mInRightGainControl->flushValue ();
} else {
createRightGainControl(mindBGain, maxdBGain, minGain, maxGain);
}
removeMasterGainControl();
} else if ( kMonoInputGainControl == mUseInputGainControls ) {
if (0 != mInMasterGainControl) {
mInMasterGainControl->setMinValue (minGain);
mInMasterGainControl->setMinDB (mindBGain);
mInMasterGainControl->setMaxValue (maxGain);
mInMasterGainControl->setMaxDB (maxdBGain);
if (mInMasterGainControl->getIntValue () > maxGain) {
mInMasterGainControl->setValue (maxGain);
}
mInMasterGainControl->flushValue ();
} else {
createMasterGainControl(mindBGain, maxdBGain, minGain, maxGain);
}
removeLeftGainControl();
removeRightGainControl();
} else {
debugIOLog ( 3, " AdjustInputGainControls - removing input gain controls.");
removeLeftGainControl();
removeRightGainControl();
removeMasterGainControl();
}
mDriverDMAEngine->completeConfigurationChange ();
engineState = mDriverDMAEngine->getState();
debugIOLog (5, "AppleOnboardAudio[%ld]::AdjustInputGainControls - about to try to mDriverDMAEngine->resumeAudioEngine...engine state = %lu", mInstanceIndex, engineState);
if ( kIOAudioEnginePaused == engineState ) {
mDriverDMAEngine->resumeAudioEngine ();
if ( kIOAudioEngineResumed == mDriverDMAEngine->getState() ) {
mDriverDMAEngine->startAudioEngine ();
}
}
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::AdjustInputGainControls ( %p ) returns kIOReturnSuccess", mInstanceIndex, thePluginObject );
return kIOReturnSuccess;
}
IORegistryEntry * AppleOnboardAudio::FindEntryByNameAndProperty (const IORegistryEntry * start, const char * name, const char * key, UInt32 value) {
OSIterator *iterator;
IORegistryEntry *theEntry;
IORegistryEntry *tmpReg;
OSNumber *tmpNumber;
theEntry = 0;
iterator = 0;
FailIf (0 == start, Exit);
iterator = start->getChildIterator (gIOServicePlane);
FailIf (0 == iterator, Exit);
while (0 == theEntry && (tmpReg = OSDynamicCast (IORegistryEntry, iterator->getNextObject ())) != 0) {
if (strcmp (tmpReg->getName (), name) == 0) {
tmpNumber = OSDynamicCast (OSNumber, tmpReg->getProperty (key));
if (0 != tmpNumber && tmpNumber->unsigned32BitValue () == value) {
theEntry = tmpReg;
}
}
}
Exit:
if (0 != iterator) {
iterator->release ();
}
return theEntry;
}
void AppleOnboardAudio::createLeftVolumeControl (IOFixed mindBVol, IOFixed maxdBVol, SInt32 minVolume, SInt32 maxVolume) {
OSNumber * theNumber;
SInt32 leftVol;
leftVol = 0;
theNumber = OSDynamicCast(OSNumber, mCurrentOutputPlugin->getProperty(kPluginPListLeftVol));
if (0 != theNumber) {
leftVol = theNumber->unsigned32BitValue();
}
debugIOLog ( 3, " AppleOnboardAudio::createLeftVolumeControl - leftVol initially = %ld, theNumber = %p", leftVol, theNumber);
if (0 == theNumber || leftVol == 0) {
theNumber = OSDynamicCast(OSNumber, mCurrentOutputPlugin->getProperty(kPluginPListMasterVol));
if (0 != theNumber) {
leftVol = theNumber->unsigned32BitValue();
debugIOLog ( 6, " createLeftVolumeControl - leftVol from master = %ld", leftVol);
if (leftVol == -1) {
leftVol = maxVolume / 2;
debugIOLog ( 6, " createLeftVolumeControl - leftVol from max/2 = %ld", leftVol);
}
} else {
leftVol = mCurrentOutputPlugin->getDefaultOutputVolume ();
debugIOLog ( 6, " createLeftVolumeControl - leftVol from default = %ld", leftVol);
}
}
debugIOLog ( 3, " createLeftVolumeControl - leftVol = %ld", leftVol);
mOutLeftVolumeControl = IOAudioLevelControl::createVolumeControl (leftVol, minVolume, maxVolume, mindBVol, maxdBVol,
kIOAudioControlChannelIDDefaultLeft,
kIOAudioControlChannelNameLeft,
0,
kIOAudioControlUsageOutput);
if (0 != mOutLeftVolumeControl) {
mDriverDMAEngine->addDefaultAudioControl (mOutLeftVolumeControl);
mOutLeftVolumeControl->setValueChangeHandler ((IOAudioControl::IntValueChangeHandler)outputControlChangeHandler, this);
mOutLeftVolumeControl->flushValue ();
}
}
void AppleOnboardAudio::createRightVolumeControl (IOFixed mindBVol, IOFixed maxdBVol, SInt32 minVolume, SInt32 maxVolume) {
OSNumber * theNumber;
SInt32 rightVol;
rightVol = 0;
theNumber = OSDynamicCast(OSNumber, mCurrentOutputPlugin->getProperty(kPluginPListRightVol));
if (0 != theNumber) {
rightVol = theNumber->unsigned32BitValue();
}
if (0 == theNumber || rightVol == 0) {
theNumber = OSDynamicCast(OSNumber, mCurrentOutputPlugin->getProperty(kPluginPListMasterVol));
if (0 != theNumber) {
rightVol = theNumber->unsigned32BitValue();
if (rightVol == -1) {
rightVol = maxVolume / 2;
}
} else {
rightVol = mCurrentOutputPlugin->getDefaultOutputVolume ();
}
}
debugIOLog ( 3, " createRightVolumeControl - rightVol = %ld", rightVol);
mOutRightVolumeControl = IOAudioLevelControl::createVolumeControl (rightVol, minVolume, maxVolume, mindBVol, maxdBVol,
kIOAudioControlChannelIDDefaultRight,
kIOAudioControlChannelNameRight,
0,
kIOAudioControlUsageOutput);
if (0 != mOutRightVolumeControl) {
mDriverDMAEngine->addDefaultAudioControl (mOutRightVolumeControl);
mOutRightVolumeControl->setValueChangeHandler ((IOAudioControl::IntValueChangeHandler)outputControlChangeHandler, this);
mOutRightVolumeControl->flushValue ();
}
}
void AppleOnboardAudio::createMasterVolumeControl (IOFixed mindBVol, IOFixed maxdBVol, SInt32 minVolume, SInt32 maxVolume) {
OSNumber * theNumber;
SInt32 masterVol;
masterVol = 0;
theNumber = OSDynamicCast(OSNumber, mCurrentOutputPlugin->getProperty(kPluginPListMasterVol));
if (0 != theNumber) {
masterVol = theNumber->unsigned32BitValue();
}
debugIOLog ( 3, "AppleOnboardAudio::createMasterVolumeControl - masterVol initially = %ld, theNumber = %p", masterVol, theNumber);
if (-1 == masterVol || 0 == theNumber) {
OSNumber * theLeftNumber;
OSNumber * theRightNumber;
theLeftNumber = OSDynamicCast(OSNumber, mCurrentOutputPlugin->getProperty(kPluginPListLeftVol));
theRightNumber = OSDynamicCast(OSNumber, mCurrentOutputPlugin->getProperty(kPluginPListRightVol));
if (0 == theLeftNumber && 0 == theRightNumber && 0 == theNumber) {
masterVol = mCurrentOutputPlugin->getDefaultOutputVolume ();
debugIOLog ( 6, "createMasterVolumeControl - masterVol from default = %ld", masterVol);
} else {
if (0 == theLeftNumber) {
masterVol = maxVolume;
debugIOLog ( 6,"createMasterVolumeControl - masterVol from max = %ld", masterVol);
} else {
masterVol = theLeftNumber->unsigned32BitValue();
debugIOLog ( 6,"createMasterVolumeControl - masterVol from left = %ld", masterVol);
}
if (0 != theRightNumber) {
masterVol += theRightNumber->unsigned32BitValue();
debugIOLog ( 6,"createMasterVolumeControl - masterVol from right = %ld", masterVol);
}
masterVol >>= 1;
debugIOLog ( 6,"createMasterVolumeControl - masterVol after shift = %ld", masterVol);
}
}
debugIOLog ( 3, "createMasterVolumeControl - masterVol = %ld", masterVol);
mOutMasterVolumeControl = IOAudioLevelControl::createVolumeControl (masterVol, minVolume, maxVolume, mindBVol, maxdBVol,
kIOAudioControlChannelIDAll,
kIOAudioControlChannelNameAll,
0,
kIOAudioControlUsageOutput);
if (0 != mOutMasterVolumeControl) {
mDriverDMAEngine->addDefaultAudioControl(mOutMasterVolumeControl);
mOutMasterVolumeControl->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)outputControlChangeHandler, this);
mOutMasterVolumeControl->flushValue ();
}
}
void AppleOnboardAudio::createLeftGainControl (IOFixed mindBGain, IOFixed maxdBGain, SInt32 minGain, SInt32 maxGain) {
OSNumber * theNumber;
SInt32 leftGain;
theNumber = OSDynamicCast(OSNumber, mCurrentInputPlugin->getProperty(kPluginPListLeftGain));
if (0 == theNumber) {
leftGain = 0;
} else {
leftGain = theNumber->unsigned32BitValue();
}
debugIOLog ( 3, "createLeftGainControl - leftVol = %ld", leftGain);
mInLeftGainControl = IOAudioLevelControl::createVolumeControl (leftGain, minGain, maxGain, mindBGain, maxdBGain,
kIOAudioControlChannelIDDefaultLeft,
kIOAudioControlChannelNameLeft,
0,
kIOAudioControlUsageInput);
if (0 != mInLeftGainControl) {
mDriverDMAEngine->addDefaultAudioControl (mInLeftGainControl);
mInLeftGainControl->setValueChangeHandler ((IOAudioControl::IntValueChangeHandler)inputControlChangeHandler, this);
mInLeftGainControl->flushValue ();
}
}
void AppleOnboardAudio::createRightGainControl (IOFixed mindBGain, IOFixed maxdBGain, SInt32 minGain, SInt32 maxGain) {
OSNumber * theNumber;
SInt32 rightGain;
theNumber = OSDynamicCast(OSNumber, mCurrentInputPlugin->getProperty(kPluginPListRightGain));
if (0 == theNumber) {
rightGain = 0;
} else {
rightGain = theNumber->unsigned32BitValue();
}
debugIOLog ( 3, "createRightGainControl - rightVol = %ld", rightGain);
mInRightGainControl = IOAudioLevelControl::createVolumeControl (rightGain, minGain, maxGain, mindBGain, maxdBGain,
kIOAudioControlChannelIDDefaultRight,
kIOAudioControlChannelNameRight,
0,
kIOAudioControlUsageInput);
if (0 != mInRightGainControl) {
mDriverDMAEngine->addDefaultAudioControl (mInRightGainControl);
mInRightGainControl->setValueChangeHandler ((IOAudioControl::IntValueChangeHandler)inputControlChangeHandler, this);
mInRightGainControl->flushValue ();
}
}
void AppleOnboardAudio::createMasterGainControl (IOFixed mindBGain, IOFixed maxdBGain, SInt32 minGain, SInt32 maxGain) {
OSNumber * theNumber;
SInt32 masterGain;
theNumber = OSDynamicCast(OSNumber, mCurrentInputPlugin->getProperty("master-gain"));
if (0 == theNumber) {
masterGain = 0;
} else {
masterGain = theNumber->unsigned32BitValue();
}
debugIOLog ( 3, "createMasterGainControl - masterVol = %ld", masterGain);
mInMasterGainControl = IOAudioLevelControl::createVolumeControl (masterGain, minGain, maxGain, mindBGain, maxdBGain,
kIOAudioControlChannelIDAll,
kIOAudioControlChannelNameAll,
0,
kIOAudioControlUsageInput);
if (0 != mInMasterGainControl) {
mDriverDMAEngine->addDefaultAudioControl (mInMasterGainControl);
mInMasterGainControl->setValueChangeHandler ((IOAudioControl::IntValueChangeHandler)inputControlChangeHandler, this);
mInMasterGainControl->flushValue ();
}
}
void AppleOnboardAudio::removeLeftVolumeControl() {
if (0 != mOutLeftVolumeControl) {
mDriverDMAEngine->removeDefaultAudioControl (mOutLeftVolumeControl);
mOutLeftVolumeControl = 0;
}
}
void AppleOnboardAudio::removeRightVolumeControl() {
if (0 != mOutRightVolumeControl) {
mDriverDMAEngine->removeDefaultAudioControl (mOutRightVolumeControl);
mOutRightVolumeControl = 0;
}
}
void AppleOnboardAudio::removeMasterVolumeControl() {
if (0 != mOutMasterVolumeControl) {
mDriverDMAEngine->removeDefaultAudioControl (mOutMasterVolumeControl);
mOutMasterVolumeControl = 0;
}
}
void AppleOnboardAudio::removeLeftGainControl() {
if (0 != mInLeftGainControl) {
mDriverDMAEngine->removeDefaultAudioControl (mInLeftGainControl);
mInLeftGainControl = 0;
}
}
void AppleOnboardAudio::removeRightGainControl() {
if (0 != mInRightGainControl) {
mDriverDMAEngine->removeDefaultAudioControl (mInRightGainControl);
mInRightGainControl = 0;
}
}
void AppleOnboardAudio::removeMasterGainControl() {
if ( 0 != mInMasterGainControl ) {
mDriverDMAEngine->removeDefaultAudioControl ( mInMasterGainControl );
mInMasterGainControl = 0;
}
}
IOReturn AppleOnboardAudio::outputControlChangeHandler (IOService *target, IOAudioControl *control, SInt32 oldValue, SInt32 newValue)
{
IOReturn result = kIOReturnError;
AppleOnboardAudio * audioDevice;
audioDevice = OSDynamicCast (AppleOnboardAudio, target);
FailIf ( 0 == audioDevice, Exit );
result = audioDevice->outputControlChangeHandlerAction ( target, control, oldValue, newValue );
Exit:
return result;
}
IOReturn AppleOnboardAudio::outputControlChangeHandlerAction ( IOService *target, IOAudioControl *control, SInt32 oldValue, SInt32 newValue )
{
IOReturn result;
IOAudioLevelControl * levelControl;
IODTPlatformExpert * platform;
UInt32 leftVol;
UInt32 rightVol;
Boolean wasPoweredDown;
UInt32 subType;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::outputControlChangeHandlerAction (%p, %p, %lX, %lX), currentPowerState %ld", mInstanceIndex, target, control, oldValue, newValue, getPowerState ());
result = kIOReturnError;
wasPoweredDown = FALSE;
debugIOLog ( 6, " getPowerState () is %d", getPowerState () );
if ( kIOAudioDeviceActive != getPowerState () )
{
if ( mDoKPrintfPowerState )
{
IOLog ( "AppleOnboardAudio[%ld]::outputControlChangeHandlerAction setting ACTIVE\n", mInstanceIndex );
}
FailIf ( kIOReturnSuccess != doLocalChangeToActiveState ( TRUE, &wasPoweredDown ), Exit );
}
switch ( control->getType () )
{
case kIOAudioControlTypeLevel:
debugIOLog ( 5, " control->getType () is a kIOAudioControlTypeLevel" );
switch ( control->getSubType () )
{
case kIOAudioLevelControlSubTypeVolume:
debugIOLog ( 5, " control->getSubType () is a kIOAudioLevelControlSubTypeVolume" );
levelControl = OSDynamicCast (IOAudioLevelControl, control);
switch ( control->getChannelID () )
{
case kIOAudioControlChannelIDAll:
result = volumeMasterChange (newValue);
if ( newValue == levelControl->getMinValue () )
{
OSNumber * muteState;
muteState = OSNumber::withNumber ((long long unsigned int)1, 32);
if (0 != mOutMuteControl) {
mOutMuteControl->hardwareValueChanged (muteState);
debugIOLog ( 3, " volume control change calling callPluginsInOrder ( kSetAnalogMuteState, TRUE )");
result = callPluginsInOrder ( kSetAnalogMuteState, TRUE );
}
muteState->release();
}
else if (oldValue == levelControl->getMinValue () && FALSE == mIsMute)
{
OSNumber * muteState;
muteState = OSNumber::withNumber ((long long unsigned int)0, 32);
if (0 != mOutMuteControl) {
mOutMuteControl->hardwareValueChanged (muteState);
debugIOLog ( 3, " volume control change calling callPluginsInOrder ( kSetAnalogMuteState, FALSE )");
result = callPluginsInOrder ( kSetAnalogMuteState, FALSE );
}
muteState->release();
}
break;
case kIOAudioControlChannelIDDefaultLeft:
result = volumeLeftChange (newValue);
break;
case kIOAudioControlChannelIDDefaultRight:
result = volumeRightChange (newValue);
break;
}
break;
case kIOAudioLevelControlSubTypePRAMVolume:
debugIOLog ( 5, " control->getSubType () is a kIOAudioLevelControlSubTypePRAMVolume" );
platform = OSDynamicCast (IODTPlatformExpert, getPlatform());
if (platform) {
UInt8 curPRAMVol;
result = platform->readXPRAM ((IOByteCount)kPRamVolumeAddr, &curPRAMVol, (IOByteCount)1);
curPRAMVol = (curPRAMVol & 0xF8) | newValue;
result = platform->writeXPRAM ((IOByteCount)kPRamVolumeAddr, &curPRAMVol, (IOByteCount) 1);
mUCState.ucPramData = (UInt32)curPRAMVol;
mUCState.ucPramVolume = mUCState.ucPramData & 0x00000007;
}
break;
default:
result = kIOReturnBadArgument;
}
break;
case kIOAudioControlTypeToggle:
debugIOLog ( 5, " control->getType () is a kIOAudioControlTypeToggle" );
subType = control->getSubType ();
switch (control->getSubType ()) {
case kIOAudioToggleControlSubTypeMute:
debugIOLog ( 5, " control->getSubType() is a kIOAudioToggleControlSubTypeMute" );
if (FALSE == newValue) { volumeLeftChange(mVolLeft, TRUE);
volumeRightChange(mVolRight, TRUE);
}
selectCodecOutputWithMuteState( newValue );
selectOutputAmplifiers ( mOutputSelector->getIntValue (), newValue );
if ( mUIMutesAmps ) { if ( FALSE != newValue ) { muteAllAmps(); } } mIsMute = newValue;
result = kIOReturnSuccess;
break;
default:
result = kIOReturnBadArgument;
break;
}
break;
case kIOAudioControlTypeSelector:
result = outputSelectorChanged (newValue);
break;
default:
break;
}
if (control->getSubType () == kIOAudioLevelControlSubTypeVolume) {
levelControl = OSDynamicCast (IOAudioLevelControl, control);
if (mOutRightVolumeControl && mOutLeftVolumeControl) {
if (mOutRightVolumeControl->getMinValue () == mVolRight &&
mOutLeftVolumeControl->getMinValue () == mVolLeft) {
OSNumber * muteState;
muteState = OSNumber::withNumber ((long long unsigned int)1, 32);
if (0 != mOutMuteControl) {
mOutMuteControl->hardwareValueChanged (muteState);
debugIOLog ( 3, " right volume control change updating mute state");
}
muteState->release ();
} else if (newValue != levelControl->getMinValue () && oldValue == levelControl->getMinValue () && FALSE == mIsMute) {
OSNumber * muteState;
muteState = OSNumber::withNumber ((long long unsigned int)0, 32);
if (0 != mOutMuteControl) {
mOutMuteControl->hardwareValueChanged (muteState);
debugIOLog ( 3, " left volume control change updating mute state");
}
muteState->release ();
}
}
}
if (mIsMute) {
leftVol = 0;
rightVol = 0;
} else {
leftVol = mVolLeft;
rightVol = mVolRight;
}
if (TRUE == mAutoUpdatePRAM) { WritePRAMVol (leftVol, rightVol);
}
Exit:
result = doLocalChangeScheduleIdle ( wasPoweredDown );
FailMessage ( kIOReturnSuccess != result );
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::outputControlChangeHandlerAction (%p, %p, %lX, %lX) returns %X", mInstanceIndex, target, control, oldValue, newValue, result);
return result;
}
void AppleOnboardAudio::createPlayThruControl (void) {
OSDictionary * AOAprop;
AOAprop = OSDynamicCast (OSDictionary, mCurrentInputPlugin->getProperty (kPluginPListAOAAttributes));
FailIf (0 == AOAprop, Exit);
if (kOSBooleanTrue == OSDynamicCast (OSBoolean, AOAprop->getObject ("Playthrough"))) {
mPlaythruToggleControl = IOAudioToggleControl::createMuteControl (TRUE, kIOAudioControlChannelIDAll, kIOAudioControlChannelNameAll, 0, kIOAudioControlUsagePassThru);
if (0 != mPlaythruToggleControl) {
mDriverDMAEngine->addDefaultAudioControl (mPlaythruToggleControl);
mPlaythruToggleControl->setValueChangeHandler ((IOAudioControl::IntValueChangeHandler)inputControlChangeHandler, this);
}
}
Exit:
return;
}
void AppleOnboardAudio::removePlayThruControl (void) {
if (0 != mPlaythruToggleControl) {
mDriverDMAEngine->removeDefaultAudioControl (mPlaythruToggleControl);
mPlaythruToggleControl->release ();
mPlaythruToggleControl = 0;
}
}
IOReturn AppleOnboardAudio::outputSelectorChanged (SInt32 newValue) {
AudioHardwareObjectInterface * thePluginObject;
IOAudioStream * outputStream;
const IOAudioStreamFormat * theFormat;
char * connectionString;
IOReturn result;
UInt32 inputLatency;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::outputSelectorChanged( '%4s' )", mInstanceIndex, (char *)&newValue);
result = kIOReturnSuccess;
inputLatency = 0;
if (kIOAudioOutputPortSubTypeLine == newValue) {
if ( !(mDetectCollection & kSndHWLineOutput) ) {
result = kIOReturnError;
}
} else if (kIOAudioOutputPortSubTypeHeadphones == newValue) {
if ( !(mDetectCollection & kSndHWCPUHeadphone) ) {
result = kIOReturnError;
}
} else if ((kIOAudioOutputPortSubTypeSPDIF == newValue) && (kGPIO_Unknown != mPlatformInterface->getComboOutJackTypeConnected ())) {
if ( !(mDetectCollection & kSndHWDigitalOutput) ) {
result = kIOReturnError;
}
}
if ( (kIOAudioOutputPortSubTypeInternalSpeaker == newValue) || (kIOAudioOutputPortSubTypeExternalSpeaker == newValue) ) { if ( (mDetectCollection & kSndHWLineOutput) || (mDetectCollection & kSndHWCPUHeadphone) ) {
result = kIOReturnError;
}
}
if ( kIOReturnSuccess == result ) {
connectionString = getConnectionKeyFromCharCode (newValue, kIOAudioStreamDirectionOutput);
FailIf (0 == connectionString, Exit);
thePluginObject = getPluginObjectForConnection (connectionString);
FailIf (0 == thePluginObject, Exit);
outputStream = mDriverDMAEngine->getAudioStream (kIOAudioStreamDirectionOutput, 1);
FailIf (0 == outputStream, Exit);
theFormat = outputStream->getFormat ();
FailWithAction (kIOAudioStreamSampleFormat1937AC3 == theFormat->fSampleFormat, result = kIOReturnNotPermitted, Exit);
outputStream->setTerminalType (getTerminalTypeForCharCode (newValue));
cacheOutputVolumeLevels (mCurrentOutputPlugin);
setClipRoutineForOutput (connectionString);
if (mCurrentOutputPlugin != thePluginObject) {
mCurrentOutputPlugin = thePluginObject;
}
setSoftwareOutputDSP (connectionString);
AdjustOutputVolumeControls(mCurrentOutputPlugin, newValue);
selectCodecOutputWithMuteState( mIsMute );
selectOutputAmplifiers(newValue, mIsMute, FALSE);
mOutputSelectorLastValue=newValue;
} else {
debugIOLog ( 3, " AppleOnboardAudio[%ld]::outputSelectorChanged disallowing selection of '%4s'", mInstanceIndex, (char *)&newValue );
}
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::outputSelectorChanged( '%4s' ) returns %X", mInstanceIndex, (char *)&newValue, result);
return result;
}
IOReturn AppleOnboardAudio::volumeMasterChange (SInt32 newValue) {
IOReturn result;
result = volumeLeftChange (newValue);
result = volumeRightChange (newValue);
result = kIOReturnSuccess;
debugIOLog ( 3, "± AppleOnboardAudio[%ld]::volumeMasterChange ( %ld )0x%x", mInstanceIndex, newValue, result);
return result;
}
IOReturn AppleOnboardAudio::volumeLeftChange (SInt32 newValue, bool ignoreMuteState) {
UInt32 count;
UInt32 index;
AudioHardwareObjectInterface* thePluginObject;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::volumeLeftChange ( %ld, %d )", mInstanceIndex, newValue, ignoreMuteState);
if ( mIsMute && FALSE == ignoreMuteState) { if (0 != mPluginObjects) {
count = mPluginObjects->getCount ();
for (index = 0; index < count; index++) {
thePluginObject = getIndexedPluginObject (index);
if((0 != thePluginObject)) {
thePluginObject->setMute (mIsMute);
}
}
}
} else {
if (TRUE == mCurrentPluginNeedsSoftwareOutputVolume) { mDriverDMAEngine->setOutputVolumeLeft (newValue);
if (0 != mPluginObjects) {
count = mPluginObjects->getCount ();
for (index = 0; index < count; index++) {
thePluginObject = getIndexedPluginObject (index);
if((0 != thePluginObject)) {
thePluginObject->setVolume (thePluginObject->getMaximumVolume (), thePluginObject->getMaximumVolume ());
}
}
}
} else {
if (0 != mPluginObjects) {
count = mPluginObjects->getCount ();
for (index = 0; index < count; index++) {
thePluginObject = getIndexedPluginObject (index);
if((0 != thePluginObject)) {
thePluginObject->setVolume (newValue, mVolRight);
}
}
}
}
}
mVolLeft = newValue;
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::volumeLeftChange ( %ld, %d )", mInstanceIndex, newValue, ignoreMuteState);
return kIOReturnSuccess;
}
IOReturn AppleOnboardAudio::volumeRightChange (SInt32 newValue, bool ignoreMuteState) {
UInt32 count;
UInt32 index;
AudioHardwareObjectInterface* thePluginObject;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::volumeRightChange ( %ld, %d )", mInstanceIndex, newValue, ignoreMuteState);
if ( mIsMute && FALSE == ignoreMuteState ) { if (0 != mPluginObjects) {
count = mPluginObjects->getCount ();
for (index = 0; index < count; index++) {
thePluginObject = getIndexedPluginObject (index);
if((0 != thePluginObject)) {
thePluginObject->setMute (mIsMute);
}
}
}
} else {
if (TRUE == mCurrentPluginNeedsSoftwareOutputVolume) { mDriverDMAEngine->setOutputVolumeRight (newValue);
if (0 != mPluginObjects) {
count = mPluginObjects->getCount ();
for (index = 0; index < count; index++) {
thePluginObject = getIndexedPluginObject (index);
if((0 != thePluginObject)) {
thePluginObject->setVolume (thePluginObject->getMaximumVolume (), thePluginObject->getMaximumVolume ());
}
}
}
} else {
if (0 != mPluginObjects) {
count = mPluginObjects->getCount ();
for (index = 0; index < count; index++) {
thePluginObject = getIndexedPluginObject (index);
if((0 != thePluginObject)) {
thePluginObject->setVolume (mVolLeft, newValue);
}
}
}
}
}
mVolRight = newValue;
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::volumeRightChange ( %ld, %d )", mInstanceIndex, newValue, ignoreMuteState);
return kIOReturnSuccess;
}
IOReturn AppleOnboardAudio::selectCodecOutputWithMuteState ( SInt32 newValue ) {
UInt32 comboOutJackTypeState;
IOReturn result = kIOReturnError;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::selectCodecOutputWithMuteState (%ld)", mInstanceIndex, newValue);
FailIf ( 0 == mPlatformInterface, Exit );
comboOutJackTypeState = mPlatformInterface->getComboOutJackTypeConnected ();
if ( kGPIO_Unknown == comboOutJackTypeState ) {
debugIOLog ( 3, " comboOutJackTypeState is unknown");
if ( !mEncodedOutputFormat ) {
debugIOLog ( 3, " selectCodecOutputWithMuteState calling callPluginsInOrder ( kSetMuteState, %ld ) non-exclusive dig", newValue);
result = callPluginsInOrder ( kSetMuteState, newValue );
FailMessage ( kIOReturnSuccess != result );
} else {
debugIOLog ( 3, " selectCodecOutputWithMuteState calling callPluginsInOrder ( kSetAnalogMuteState, %ld ) exclusive dig", TRUE);
result = callPluginsInOrder ( kSetAnalogMuteState, TRUE );
FailMessage ( kIOReturnSuccess != result );
if ( kIOReturnSuccess == result ) {
debugIOLog ( 3, " selectCodecOutputWithMuteState calling callPluginsInOrder ( kSetDigitalMuteState, %ld ) exclusive dig", newValue);
result = callPluginsInOrder ( kSetDigitalMuteState, newValue );
}
}
result = callPluginsInOrder ( kSetEnableSPDIFOut, TRUE ); } else {
debugIOLog ( 3, " comboOutJackTypeState is %s", comboOutJackTypeState == kGPIO_TypeIsDigital ? "digital" : "analog");
GpioAttributes theAnalogState = kGPIO_Unknown;
switch ( (UInt32)mPlatformInterface->getComboOutAssociation () ) {
case kGPIO_Selector_HeadphoneDetect: theAnalogState = mPlatformInterface->getHeadphoneConnected (); break;
case kGPIO_Selector_LineOutDetect: theAnalogState = mPlatformInterface->getLineOutConnected (); break;
case kGPIO_Selector_SpeakerDetect: theAnalogState = mPlatformInterface->getSpeakerConnected (); break;
}
debugIOLog ( 3, " (UInt32)mPlatformInterface->getComboOutAssociation () returns 0x%lx", (UInt32)mPlatformInterface->getComboOutAssociation ());
debugIOLog ( 3, " theAnalogState = 0x%lx, comboOutJackTypeState = 0x%lx", theAnalogState, comboOutJackTypeState);
if ( !mEncodedOutputFormat ) {
if ( kGPIO_Connected == theAnalogState && kGPIO_TypeIsDigital == comboOutJackTypeState ) {
debugIOLog ( 3, " selectCodecOutputWithMuteState calling callPluginsInOrder ( kSetAnalogMuteState, %ld ) exclusive dig", TRUE);
result = callPluginsInOrder ( kSetAnalogMuteState, TRUE );
if ( kIOReturnSuccess == result ) {
debugIOLog ( 3, " selectCodecOutputWithMuteState calling callPluginsInOrder ( kSetDigitalMuteState, %ld ) exclusive dig", newValue);
result = callPluginsInOrder ( kSetDigitalMuteState, newValue );
}
result = callPluginsInOrder ( kSetEnableSPDIFOut, TRUE );
} else {
debugIOLog ( 3, " selectCodecOutputWithMuteState calling callPluginsInOrder ( kSetAnalogMuteState, %ld ) non-exclusive dig", newValue);
result = callPluginsInOrder ( kSetAnalogMuteState, newValue );
if ( kIOReturnSuccess == result ) {
debugIOLog ( 3, " selectCodecOutputWithMuteState calling callPluginsInOrder ( kSetDigitalMuteState, %ld ) non-exclusive dig", TRUE);
result = callPluginsInOrder ( kSetDigitalMuteState, TRUE );
}
result = callPluginsInOrder ( kSetEnableSPDIFOut, FALSE );
}
} else {
debugIOLog ( 3, "encoded format");
result = callPluginsInOrder ( kSetEnableSPDIFOut, TRUE );
debugIOLog ( 3, " selectCodecOutputWithMuteState calling callPluginsInOrder ( kSetAnalogMuteState, TRUE ) for encoded format");
result = callPluginsInOrder ( kSetAnalogMuteState, TRUE );
if ( kIOReturnSuccess == result ) {
if (!( kGPIO_Connected == theAnalogState && kGPIO_TypeIsDigital == comboOutJackTypeState )) {
newValue = TRUE;
}
debugIOLog ( 3, " selectCodecOutputWithMuteState calling callPluginsInOrder ( kSetDigitalMuteState, %ld ) exclusive dig", newValue);
result = callPluginsInOrder ( kSetDigitalMuteState, newValue );
}
}
}
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::selectCodecOutputWithMuteState ( %ld ) returns 0x%lX", mInstanceIndex, newValue, result);
return result;
}
IOReturn AppleOnboardAudio::inputControlChangeHandler (IOService *target, IOAudioControl *control, SInt32 oldValue, SInt32 newValue)
{
IOReturn result = kIOReturnError;
AppleOnboardAudio * audioDevice;
audioDevice = OSDynamicCast (AppleOnboardAudio, target);
FailIf ( 0 == audioDevice, Exit );
result = audioDevice->inputControlChangeHandlerAction ( target, control, oldValue, newValue );
Exit:
return result;
}
IOReturn AppleOnboardAudio::inputControlChangeHandlerAction ( IOService *target, IOAudioControl *control, SInt32 oldValue, SInt32 newValue )
{
IOReturn result = kIOReturnError;
IOAudioLevelControl * levelControl;
Boolean wasPoweredDown;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::inputControlChangeHandlerAction (%p, %p, %lX, %lX)", mInstanceIndex, target, control, oldValue, newValue);
wasPoweredDown = FALSE;
debugIOLog ( 6, " getPowerState () is %d, pendingPowerState = %d", getPowerState (), pendingPowerState );
if ( kIOAudioDeviceActive != getPowerState () )
{
if ( mDoKPrintfPowerState )
{
IOLog ( "AppleOnboardAudio[%ld]::inputControlChangeHandlerAction setting ACTIVE\n", mInstanceIndex );
}
FailIf ( kIOReturnSuccess != doLocalChangeToActiveState ( TRUE, &wasPoweredDown ), Exit );
}
switch ( control->getType () )
{
case kIOAudioControlTypeLevel:
debugIOLog ( 3, " control type = kIOAudioControlTypeLevel" );
levelControl = OSDynamicCast (IOAudioLevelControl, control);
switch (control->getChannelID ()) {
case kIOAudioControlChannelIDDefaultLeft:
debugIOLog ( 3, " channel ID = kIOAudioControlChannelIDDefaultLeft" );
result = gainLeftChanged (newValue);
break;
case kIOAudioControlChannelIDDefaultRight:
debugIOLog ( 3, " channel ID = kIOAudioControlChannelIDDefaultRight" );
result = gainRightChanged (newValue);
break;
case kIOAudioControlChannelIDAll:
debugIOLog ( 3, " channel ID = kIOAudioControlChannelIDAll" );
result = gainRightChanged (newValue);
break;
}
break;
case kIOAudioControlTypeToggle:
debugIOLog ( 3, " control type = kIOAudioControlTypeToggle" );
result = passThruChanged (newValue);
break;
case kIOAudioControlTypeSelector:
debugIOLog ( 3, " control->getType() = kIOAudioControlTypeSelector" );
switch ( control->getSubType () )
{
case kIOAudioSelectorControlSubTypeInput:
debugIOLog ( 3, " control->getSubType() = kIOAudioSelectorControlSubTypeInput" );
result = inputSelectorChanged (newValue);
break;
case kIOAudioSelectorControlSubTypeClockSource:
debugIOLog ( 3, " control->getSubType() = kIOAudioSelectorControlSubTypeClockSource" );
if ( kClockSourceSelectionExternal == newValue )
{
broadcastSoftwareInterruptMessage ( kRemoteActive );
}
result = clockSelectorChanged (newValue);
break;
default:
debugIOLog ( 3, " unknown control type in input selector change handler");
break;
}
default:
break;
}
Exit:
result = doLocalChangeScheduleIdle ( wasPoweredDown );
FailMessage ( kIOReturnSuccess != result );
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::inputControlChangeHandlerAction (%p, %p, oldValue %lX, newValue %lX) returns %lX", mInstanceIndex, target, control, oldValue, newValue, result);
return result;
}
IOReturn AppleOnboardAudio::gainLeftChanged (SInt32 newValue) {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::gainLeftChanged ( %ld )", mInstanceIndex, newValue);
if (mCurrentPluginNeedsSoftwareInputGain) {
mDriverDMAEngine->setInputGainL (newValue);
} else {
mCurrentInputPlugin->setInputGain (newValue, mGainRight);
}
mGainLeft = newValue;
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::gainLeftChanged ( %ld )", mInstanceIndex, newValue );
return kIOReturnSuccess;
}
IOReturn AppleOnboardAudio::gainRightChanged (SInt32 newValue) {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::gainRightChanged ( %ld )", mInstanceIndex, newValue);
if (mCurrentPluginNeedsSoftwareInputGain) {
mDriverDMAEngine->setInputGainR (newValue);
} else {
mCurrentInputPlugin->setInputGain (newValue, mGainRight);
}
mGainRight = newValue;
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::gainRightChanged ( %ld )", mInstanceIndex, newValue );
return kIOReturnSuccess;
}
IOReturn AppleOnboardAudio::gainMasterChanged (SInt32 newValue) {
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::gainMasterChanged ( %ld )", mInstanceIndex, newValue);
if (mCurrentPluginNeedsSoftwareInputGain) {
mDriverDMAEngine->setInputGainR (newValue);
mDriverDMAEngine->setInputGainL (newValue);
} else {
mCurrentInputPlugin->setInputGain (newValue, newValue);
}
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::gainMasterChanged ( %ld )", mInstanceIndex, newValue );
return kIOReturnSuccess;
}
IOReturn AppleOnboardAudio::passThruChanged (SInt32 newValue) {
IOReturn result;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::passThruChanged ( %ld )", mInstanceIndex, newValue);
result = kIOReturnError;
mCurrentInputPlugin->setPlayThrough (!newValue);
result = kIOReturnSuccess;
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::passThruChanged ( %ld )", mInstanceIndex, newValue );
return kIOReturnSuccess;
}
IOReturn AppleOnboardAudio::inputSelectorChanged (SInt32 newValue) {
AudioHardwareObjectInterface * thePluginObject;
IOAudioStream * inputStream;
OSDictionary * AOApropInput;
OSBoolean * softwareInputGainBoolean;
OSNumber * inputLatencyNumber;
char * connectionString;
IOReturn result;
UInt32 inputLatency;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::inputSelectorChanged (%4s)", mInstanceIndex, (char *)&newValue);
result = kIOReturnError;
inputLatency = 0;
connectionString = getConnectionKeyFromCharCode (newValue, kIOAudioStreamDirectionInput);
FailIf (0 == connectionString, Exit);
thePluginObject = getPluginObjectForConnection (connectionString);
if ( 0 != thePluginObject )
{
inputStream = mDriverDMAEngine->getAudioStream (kIOAudioStreamDirectionInput, 1);
FailIf (0 == inputStream, Exit);
inputStream->setTerminalType (getTerminalTypeForCharCode (newValue));
setUseInputGainControls (connectionString);
setUsePlaythroughControl (connectionString);
setClipRoutineForInput (connectionString);
setSoftwareInputDSP (connectionString);
mCurrentInputPlugin->setInputMute (TRUE);
setInputDataMuxForConnection ( connectionString );
if (mCurrentInputPlugin != thePluginObject) {
thePluginObject->setInputMute (TRUE);
cacheInputGainLevels (mCurrentInputPlugin);
ConfigChangeHelper theConfigeChangeHelper(mDriverDMAEngine);
AOApropInput = OSDynamicCast (OSDictionary, thePluginObject->getProperty (kPluginPListAOAAttributes));
if (0 != AOApropInput) {
softwareInputGainBoolean = OSDynamicCast (OSBoolean, AOApropInput->getObject (kPluginPListSoftwareInputGain));
if (0 != softwareInputGainBoolean) {
mDriverDMAEngine->setUseSoftwareInputGain (softwareInputGainBoolean->getValue ());
mCurrentPluginNeedsSoftwareInputGain = softwareInputGainBoolean->getValue ();
} else {
mDriverDMAEngine->setUseSoftwareInputGain (false);
mCurrentPluginNeedsSoftwareInputGain = false;
}
}
if (0 != AOApropInput) {
inputLatencyNumber = OSDynamicCast (OSNumber, AOApropInput->getObject (kPluginPListInputLatency));
if (0 != inputLatencyNumber) {
inputLatency = inputLatencyNumber->unsigned32BitValue();
}
}
mDriverDMAEngine->setSampleLatencies (mOutputLatency, inputLatency);
mCurrentInputPlugin = thePluginObject;
debugIOLog ( 3, " AppleOnboardAudio[%ld]::inputSelectorChanged - mCurrentInputPlugin updated to %p", mInstanceIndex, mCurrentInputPlugin);
}
mCurrentInputPlugin->setActiveInput (newValue);
AdjustInputGainControls (mCurrentInputPlugin);
if ((mDetectCollection & kSndHWLineInput) && (kIOAudioInputPortSubTypeLine == newValue)) {
mCurrentInputPlugin->setInputMute (FALSE);
} else if (!(mDetectCollection & kSndHWLineInput) && (kIOAudioInputPortSubTypeLine == newValue)) {
mCurrentInputPlugin->setInputMute (TRUE);
}
result = kIOReturnSuccess;
}
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::inputSelectorChanged (%4s) returns 0x%lX", mInstanceIndex, (char *)&newValue, result);
return result;
}
IOReturn AppleOnboardAudio::clockSelectorChanged (SInt32 newValue) {
IOReturn result;
UInt32 transportType;
debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::clockSelectorChanged ('%4s')", mInstanceIndex, (char *)&newValue);
result = kIOReturnError;
mClockSelectInProcessSemaphore = true;
FailIf ( 0 == mDriverDMAEngine, Exit );
FailIf ( 0 == mTransportInterface, Exit );
debugIOLog ( 5, " mCodecLockStatus = %s", kClockLockStatus == mCodecLockStatus ? "kClockLockStatus" : "kClockUnlockStatus" );
transportType = mTransportInterface->transportGetTransportInterfaceType(); if ( kTransportInterfaceType_I2S_Slave_Only != transportType ) { if ( ( kClockSourceSelectionExternal == newValue ) || ( kClockSourceSelectionInternal == newValue ) ) {
switch ( newValue ) {
case kClockSourceSelectionExternal:
if ( kTRANSPORT_SLAVE_CLOCK != mTransportInterface->transportGetClockSelect () ) {
debugIOLog ( 4, " *-*** updating mCurrentClockSelector from 0x%0.8X to 0x%0.8X to FORCE UPDATE to kClockSourceSelectionExternal", mCurrentClockSelector, kClockSourceSelectionInternal );
mCurrentClockSelector = kClockSourceSelectionInternal;
}
break;
case kClockSourceSelectionInternal:
if ( kTRANSPORT_MASTER_CLOCK != mTransportInterface->transportGetClockSelect () ) {
debugIOLog ( 4, " ***-* updating mCurrentClockSelector from 0x%0.8X to 0x%0.8X to FORCE UPDATE to kClockSourceSelectionInternal", mCurrentClockSelector, kClockSourceSelectionExternal );
mCurrentClockSelector = kClockSourceSelectionExternal;
}
break;
}
if ( mCurrentClockSelector != newValue ) {
muteAllAmps (); callPluginsInOrder ( kSetMuteState, TRUE ); if ( kClockSourceSelectionInternal == newValue ) {
ConfigChangeHelper theConfigeChangeHelper(mDriverDMAEngine, 10);
if ( kTransportInterfaceType_I2S_Opaque_Slave_Only == transportType ) { mTransportInterface->transportBreakClockSelect ( kTRANSPORT_SLAVE_CLOCK );
callPluginsInOrder ( kBreakClockSelect, kTRANSPORT_MASTER_CLOCK );
mTransportInterface->transportMakeClockSelect ( kTRANSPORT_SLAVE_CLOCK );
callPluginsInOrder ( kMakeClockSelect, kTRANSPORT_MASTER_CLOCK );
} else {
mTransportInterface->transportBreakClockSelect ( kTRANSPORT_MASTER_CLOCK );
callPluginsInOrder ( kBreakClockSelect, kTRANSPORT_MASTER_CLOCK );
mTransportInterface->transportMakeClockSelect ( kTRANSPORT_MASTER_CLOCK );
callPluginsInOrder ( kMakeClockSelect, kTRANSPORT_MASTER_CLOCK );
}
if ( ( FALSE == mAutoSelectClock ) || ( FALSE == mRelockToExternalClockInProgress ) ) {
selectCodecOutputWithMuteState (mIsMute);
if ( 0 != mOutputSelector ) {
selectOutputAmplifiers ( mOutputSelector->getIntValue (), mIsMute);
}
}
} else if ( kClockSourceSelectionExternal == newValue ) {
ConfigChangeHelper theConfigeChangeHelper(mDriverDMAEngine, 10); mTransportInterface->transportBreakClockSelect ( kTRANSPORT_SLAVE_CLOCK );
callPluginsInOrder ( kBreakClockSelect, kTRANSPORT_SLAVE_CLOCK );
mTransportInterface->transportMakeClockSelect ( kTRANSPORT_SLAVE_CLOCK );
callPluginsInOrder ( kMakeClockSelect, kTRANSPORT_SLAVE_CLOCK );
selectCodecOutputWithMuteState (mIsMute);
if ( 0 != mOutputSelector ) {
selectOutputAmplifiers ( mOutputSelector->getIntValue (), mIsMute);
}
if ( mAutoSelectClock && mRelockToExternalClockInProgress ) {
mRelockToExternalClockInProgress = FALSE;
mRelockToExternalClockPollCount = 0;
}
} else {
debugIOLog ( 3, " ** Unknown clock source selection." );
FailIf (TRUE, Exit);
}
debugIOLog ( 4, " ***** updating mCurrentClockSelector from 0x%0.8X to 0x%0.8X", mCurrentClockSelector, newValue );
mCurrentClockSelector = newValue;
if (kClockSourceSelectionInternal == newValue) {
mTransportSampleRate.whole = mTransportInterface->transportGetSampleRate ();
mTransportSampleRate.fraction = 0;
}
debugIOLog ( 4, " *-* about to mDriverDMAEngine->hardwareSampleRateChanged ( %d )", mTransportSampleRate.whole ); mDriverDMAEngine->hardwareSampleRateChanged ( &mTransportSampleRate );
mDriverDMAEngine->updateDSPForSampleRate(mTransportSampleRate.whole); }
result = kIOReturnSuccess;
}
}
Exit:
mClockSelectInProcessSemaphore = false; debugIOLog ( 5, "- AppleOnboardAudio[%ld]::clockSelectorChanged ('%4s') returns 0x%lX", mInstanceIndex, (char *)&newValue, result);
return result;
}
UInt32 AppleOnboardAudio::getCurrentSampleFrame (void) {
return mPlatformInterface->getFrameCount ();
}
void AppleOnboardAudio::setCurrentSampleFrame (UInt32 inValue) {
mPlatformInterface->setFrameCount (inValue);
return;
}
void AppleOnboardAudio::setInputDataMuxForConnection ( char * connectionString ) {
GpioAttributes theMuxSelect;
theMuxSelect = getInputDataMuxForConnection ( connectionString );
if ( kGPIO_Unknown != theMuxSelect ) {
debugIOLog ( 3, "± AppleOnboardAudio[%ld]::setInputDataMuxForConnection ( %p ) setting input data mux to %d", mInstanceIndex, connectionString, (unsigned int)theMuxSelect );
mPlatformInterface->setInputDataMux ( theMuxSelect );
}
}
void AppleOnboardAudio::notifyStreamFormatsPublished ( void ) {
IOReturn result = kIOReturnSuccess;
if ( 0 != mInputSelector ) {
result = mInputSelector->flushValue ();
debugIOLog ( 3, " mInputSelector->flushValue () returns 0x%lX", result );
}
}
#pragma mark +POWER MANAGEMENT
IOReturn AppleOnboardAudio::setAggressiveness ( unsigned long type, unsigned long newLevel )
{
UInt32 time = 0;
IOReturn result = kIOReturnSuccess;
if (type == kPMPowerSource)
{
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::setAggressiveness ( 0x%0.8X = kPMPowerSource, %ld )", mInstanceIndex, type, newLevel );
switch ( newLevel ) {
case kIOPMInternalPower: mCurrentAggressivenessLevel = newLevel; if ( mDoKPrintfPowerState )
{
IOLog ( "AppleOnboardAudio[%ld]::setAggressiveness now on BATTERY POWER\n", mInstanceIndex );
}
if ( 0 == sTotalNumAOAEnginesRunning ) {
debugIOLog ( 3, " setting power aggressivness state to kIOPMInternalPower" );
setIdleAudioSleepTime ( kBatteryPowerDownDelayTime ); debugIOLog ( 6, " asyncPowerStateChangeInProgress %d", asyncPowerStateChangeInProgress );
debugIOLog ( 6, " setting pendingPowerState to kIOAudioDeviceIdle" );
pendingPowerState = kIOAudioDeviceIdle;
}
debugIOLog ( 6, " setting mCurrentAggressivenessLevel to %ld", newLevel );
break;
case kIOPMExternalPower: mCurrentAggressivenessLevel = newLevel; if ( mDoKPrintfPowerState )
{
IOLog ( "AppleOnboardAudio[%ld]::setAggressiveness now on EXTERNAL POWER\n", mInstanceIndex );
}
debugIOLog ( 3, " setting power aggressivness state to kIOPMExternalPower" );
setIdleAudioSleepTime ( kNoIdleAudioPowerDown ); debugIOLog ( 6, " asyncPowerStateChangeInProgress %d", asyncPowerStateChangeInProgress );
#ifdef THREAD_POWER_MANAGEMENT
if ( asyncPowerStateChangeInProgress )
{
waitForPendingPowerStateChange ();
}
#endif
debugIOLog ( 6, " setting pendingPowerState to kIOAudioDeviceActive" );
pendingPowerState = kIOAudioDeviceActive;
FailMessage ( kIOReturnSuccess != performPowerStateChange ( getPowerState (), kIOAudioDeviceActive, &time ) );
debugIOLog ( 6, " setting mCurrentAggressivenessLevel to %ld", newLevel );
break;
default:
debugIOLog ( 3, " setting power aggressivness state to %ld", newLevel );
break;
}
debugIOLog ( 6, " about to super::setAggressiveness ( %d, %d )", type, newLevel );
result = super::setAggressiveness ( type, newLevel );
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::setAggressiveness ( 0x%0.8X = kPMPowerSource, %ld ) returns 0x%lX", mInstanceIndex, type, newLevel, result );
}
else
{
result = super::setAggressiveness (type, newLevel);
}
return result;
}
IOReturn AppleOnboardAudio::performPowerStateChange ( IOAudioDevicePowerState oldPowerState, IOAudioDevicePowerState newPowerState, UInt32 *microsecondsUntilComplete )
{
IOReturn result = kIOReturnError;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::performPowerStateChange ( oldPowerState %d, newPowerState %d, microsecondsUntilComplete %p )", mInstanceIndex, oldPowerState, newPowerState, microsecondsUntilComplete );
debugIOLog ( 3, " currentPowerState = %d", getPowerState ());
FailIf ( 0 == microsecondsUntilComplete, Exit );
if ( 0 == mMicrosecsToSleep )
{
if ( 0 != mAmpRecoveryMuteDuration )
{
*microsecondsUntilComplete = ( mAmpRecoveryMuteDuration * 1000 ); }
else
{
*microsecondsUntilComplete = 1000;
}
debugIOLog ( 6, " seed microsecondsUntilComplete = %ld", *microsecondsUntilComplete );
callPluginsInOrder ( kRequestSleepTime, (UInt32)microsecondsUntilComplete );
*microsecondsUntilComplete = ( *microsecondsUntilComplete * 3 );
if ( 0 != mAOAInstanceArray )
{
*microsecondsUntilComplete = ( *microsecondsUntilComplete * 3 ); }
}
else
{
*microsecondsUntilComplete = mMicrosecsToSleep;
}
debugIOLog ( 6, " total microsecondsUntilComplete = %ld", *microsecondsUntilComplete );
result = super::performPowerStateChange ( oldPowerState, newPowerState, microsecondsUntilComplete );
FailMessage ( kIOReturnSuccess != result );
#ifdef THREAD_POWER_MANAGEMENT
if ( ( kIOAudioDeviceIdle == getPowerState () ) && ( kIOAudioDeviceActive == newPowerState ) )
{
result = performPowerStateChangeThreadAction ( this, (void*)newPowerState, 0, 0, 0 );
FailMessage ( kIOReturnSuccess != result );
}
else
{
if ( mPowerThread )
{
thread_call_enter1 ( mPowerThread, (thread_call_param_t)newPowerState );
}
}
#else
performPowerStateChangeThread ( this, (void*)newPowerState );
#endif
Exit:
debugIOLog ( 3, " currentPowerState = %d", getPowerState ());
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::performPowerStateChange ( oldPowerState %d, newPowerState %d, microsecondsUntilComplete %p ) returns 0x%lX", mInstanceIndex, oldPowerState, newPowerState, microsecondsUntilComplete, result );
return result;
}
void AppleOnboardAudio::performPowerStateChangeThread (AppleOnboardAudio * aoa, void * newPowerState) {
IOCommandGate * cg;
IOReturn result;
FailIf (0 == aoa, Exit);
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::performPowerStateChangeThread (%p, %ld)", aoa->mInstanceIndex, aoa, (UInt32)newPowerState);
aoa->mSignal->wait (FALSE);
FailWithAction ( TRUE == aoa->mTerminating, aoa->completePowerStateChange (), Exit );
cg = aoa->getCommandGate ();
if (cg)
{
result = cg->runAction ( aoa->performPowerStateChangeThreadAction, newPowerState, (void *)aoa );
FailMessage ( kIOReturnSuccess != result );
}
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::performPowerStateChangeThread (%p, %ld)", aoa->mInstanceIndex, aoa, (UInt32)newPowerState );
Exit:
return;
}
IOReturn AppleOnboardAudio::performPowerStateChangeThreadAction ( OSObject * owner, void * newPowerState, void * arg2, void * arg3, void * arg4 )
{
AppleOnboardAudio * aoa;
IOReturn result = kIOReturnError;
debugIOLog ( 6, "+ AppleOnboardAudio::performPowerStateChangeThreadAction ( %p, %p, %d, %d, %d )", owner, newPowerState, arg2, arg3, arg4 );
aoa = OSDynamicCast ( AppleOnboardAudio, (OSObject *)owner );
FailIf ( 0 == aoa, Exit );
result = aoa->performPowerStateAction ( owner, newPowerState, arg2, arg3, arg4 );
Exit:
debugIOLog ( 6, "- AppleOnboardAudio::performPowerStateChangeThreadAction ( %p, %p, %d, %d, %d ) returns 0x%X", owner, newPowerState, arg2, arg3, arg4, result );
return result;
}
IOReturn AppleOnboardAudio::performPowerStateAction ( OSObject * owner, void * newPowerState, void * arg2, void * arg3, void * arg4 )
{
IOReturn result = kIOReturnError;
unsigned long currentAggressivenessLevel = 0;
debugIOLog ( 6, "+ AppleOnboardAudio[%ld]::performPowerStateAction ( %p, %p, %d, %d, %d )", mInstanceIndex, owner, newPowerState, arg2, arg3, arg4 );
debugIOLog ( 6, " AOA[%ld] getPowerState () = %d, pendingPowerState = %d, newPowerState = %lu, sTotalNumAOAEnginesRunning = %lu", mInstanceIndex, getPowerState (), pendingPowerState, (UInt32) newPowerState, sTotalNumAOAEnginesRunning );
FailIf ( 0 == mTransportInterface, Exit );
FailIf ( 0 == mPlatformInterface, Exit );
if ( kIOAudioDeviceIdle == (UInt32)newPowerState )
{
if ( 0 != sTotalNumAOAEnginesRunning )
{
newPowerState = (void*)kIOAudioDeviceActive;
if (1 == sInstanceCount) {
pendingPowerState = kIOAudioDeviceActive; debugIOLog(3, "AppleOnboardAudio[%ld]::performPowerStateAction - forcing pending power state from idle to active due to 0 != sTotalNumAOAEnginesRunning", mInstanceIndex);
}
}
else if ( kIOReturnSuccess == getAggressiveness ( kPMPowerSource, ¤tAggressivenessLevel ) )
{
if ( kIOPMExternalPower == currentAggressivenessLevel )
{
newPowerState = (void*)kIOAudioDeviceActive;
if (1 == sInstanceCount) {
pendingPowerState = kIOAudioDeviceActive;
debugIOLog(3, "AppleOnboardAudio[%ld]::performPowerStateAction - forcing pending power state from idle to active due to presence of external power", mInstanceIndex);
}
}
}
}
if ( 0 != mUsesAOAPowerManagement )
{
switch ( (UInt32)newPowerState )
{
case kIOAudioDeviceSleep: broadcastSoftwareInterruptMessage ( kRemoteChildSleep ); break;
case kIOAudioDeviceIdle: broadcastSoftwareInterruptMessage ( kRemoteChildIdle ); break;
case kIOAudioDeviceActive: broadcastSoftwareInterruptMessage ( kRemoteChildActive ); break;
}
result = kIOReturnSuccess;
}
else
{
result = performPowerStateChangeAction ( newPowerState ); FailMessage ( kIOReturnSuccess != result );
}
Exit:
debugIOLog ( 6, " AOA[%ld] getPowerState () = %d, pendingPowerState = %d, about to protectedCompletePowerStateChange ()", mInstanceIndex, getPowerState (), pendingPowerState );
protectedCompletePowerStateChange ();
acknowledgeSetPowerState ();
debugIOLog ( 6, " AOA[%ld] getPowerState () = %d, pendingPowerState = %d", mInstanceIndex, getPowerState (), pendingPowerState );
debugIOLog ( 6, "- AppleOnboardAudio[%ld]::performPowerStateAction ( %p, %p, %d, %d, %d ) returns 0x%X", mInstanceIndex, owner, newPowerState, arg2, arg3, arg4, result );
return result;
}
IOReturn AppleOnboardAudio::performPowerStateChangeAction ( void * newPowerState )
{
IOReturn result = kIOReturnError;
logPerformPowerStateChangeAction ( mInstanceIndex, (UInt32)newPowerState, getPowerState (), kLOG_ENTRY_TO_AOA_METHOD, 0 );
FailIf ( 0 == mTransportInterface, Exit );
FailIf ( 0 == mPlatformInterface, Exit );
mNeedsLockStatusUpdateToUnmute = FALSE;
switch ( (UInt32)newPowerState ) {
case kIOAudioDeviceActive:
result = performPowerStateChangeAction_requestActive ( TRUE );
FailIf ( kIOReturnSuccess != result, Exit );
protectedCompletePowerStateChange ();
setProperty ( "IOAudioPowerState", kIOAudioDeviceActive, 32 );
mUCState.ucPowerState = getPowerState ();
FailMessage(kIOAudioDeviceActive != getPowerState());
if ( 0 != mExternalClockSelector )
{
debugIOLog ( 4, " ... [%ld] about to mExternalClockSelector->flushValue ()", mInstanceIndex );
mExternalClockSelector->flushValue ();
}
if ( !mNeedsLockStatusUpdateToUnmute )
{ FailMessage ( kIOReturnSuccess != selectCodecOutputWithMuteState ( mIsMute ) );
if ( 0 != mOutputSelector )
{
selectOutputAmplifiers ( mOutputSelector->getIntValue (), mIsMute ); }
if ( 0 != mOutMuteControl )
{
mOutMuteControl->flushValue (); }
}
if ( mDoKPrintfPowerState )
{
IOLog ( "AppleOnboardAudio[%ld] power state is ACTIVE\n", mInstanceIndex );
}
break;
case kIOAudioDeviceIdle:
debugIOLog ( 6, " AOA[%ld] about to performPowerStateChangeAction_requestIdle", mInstanceIndex );
result = performPowerStateChangeAction_requestIdle ();
debugIOLog ( 6, " AOA[%ld] completed performPowerStateChangeAction_requestIdle, pending %d, current %d", mInstanceIndex, pendingPowerState, getPowerState () );
FailIf ( kIOReturnSuccess != result, Exit );
if ( mDoKPrintfPowerState )
{
IOLog ( "AppleOnboardAudio[%ld] power state is IDLE\n", mInstanceIndex );
}
protectedCompletePowerStateChange ();
setProperty ( "IOAudioPowerState", kIOAudioDeviceIdle, 32 );
mUCState.ucPowerState = getPowerState ();
break;
case kIOAudioDeviceSleep:
result = performPowerStateChangeAction_requestSleep ();
FailIf ( kIOReturnSuccess != result, Exit );
if ( mDoKPrintfPowerState )
{
IOLog ( "AppleOnboardAudio[%ld] power state is SLEEP\n", mInstanceIndex );
}
protectedCompletePowerStateChange ();
setProperty ( "IOAudioPowerState", kIOAudioDeviceSleep, 32 );
mUCState.ucPowerState = getPowerState ();
break;
}
FailIf ( kIOReturnSuccess != result, Exit );
Exit:
logPerformPowerStateChangeAction ( mInstanceIndex, (UInt32)newPowerState, getPowerState (), kLOG_EXIT_FROM_AOA_METHOD, result );
return result;
}
IOReturn AppleOnboardAudio::performPowerStateChangeAction_requestActive ( bool allowDetectIRQDispatch )
{
IOReturn result = kIOReturnError;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::performPowerStateChangeAction_requestActive () - currentPowerState = %d, pendingPowerState = %d", mInstanceIndex, getPowerState(), pendingPowerState );
FailIf ( 0 == mTransportInterface, Exit );
FailIf ( 0 == mPlatformInterface, Exit );
if ( kIOAudioDeviceActive != getPowerState () )
{
result = mTransportInterface->performTransportWake ();
FailIf ( kIOReturnSuccess != result, Exit );
if ( broadcastSoftwareInterruptMessage ( kRemoteActive ) )
{ if ( mCurrentClockSelector == kClockSourceSelectionExternal )
{
mNeedsLockStatusUpdateToUnmute = TRUE;
}
}
result = callPluginsInOrder ( kPowerStateChange, ( ( getPowerState () << 16 ) | kIOAudioDeviceActive ) );
FailIf ( kIOReturnSuccess != result, Exit );
selectOutputAmplifiers ( mCurrentOutputSelection, mIsMute );
FailMessage ( kIOReturnSuccess != selectCodecOutputWithMuteState ( mIsMute ) );
if ((1 == sInstanceCount) && (TRUE == mAutoSelectClock)) {
mDelayPollAfterWakeFromSleep = kDelayPollAfterWakeFromSleep >> 1;
debugIOLog(4, "AppleOnboardAudio::performPowerStateChangeAction_requestActive() - number of AOA instances = 1, auto clock select = 1...setting delay poll after wake counter to %lu", mDelayPollAfterWakeFromSleep);
}
else {
mDelayPollAfterWakeFromSleep = kDelayPollAfterWakeFromSleep; debugIOLog(4, "AppleOnboardAudio::performPowerStateChangeAction_requestActive() - number of AOA instances = %lu, auto clock select = %d...setting delay poll after wake counter to %lu", sInstanceCount, mAutoSelectClock, mDelayPollAfterWakeFromSleep);
}
if ( mAllowDetectIrqDispatchesOnWake && allowDetectIRQDispatch )
{
mPlatformInterface->performPowerStateChange ( (IOService*)mPlatformInterface, getPowerState (), pendingPowerState );
}
if (TRUE == mAutoSelectClock) {
mDisableAutoSelectClock = TRUE; }
mCodecLockStatus = kClockUnLockStatus;
if( (kGPIO_Unknown == mPlatformInterface->getDigitalOutConnected ()) && mHasSPDIFControl) mOutputSelector->setValue(mOutputSelectorLastValue);
setPollTimer(); setIdleAudioSleepTime ( kNoIdleAudioPowerDown );
mRemoteDetectInterruptEnabled = TRUE; mRemoteNonDetectInterruptEnabled = TRUE; debugIOLog ( 3, " AOA[%ld] where mRemoteDetectInterruptEnabled = %d, mRemoteNonDetectInterruptEnabled = %d", mInstanceIndex, mRemoteDetectInterruptEnabled, mRemoteNonDetectInterruptEnabled );
}
else
{
result = kIOReturnSuccess;
}
Exit:
debugIOLog ( 4, "- AppleOnboardAudio[%ld]::performPowerStateChangeAction_requestActive () returns 0x%lX", mInstanceIndex, result );
return result;
}
IOReturn AppleOnboardAudio::performPowerStateChangeAction_requestIdle ( void )
{
IOReturn result = kIOReturnError;
debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::performPowerStateChangeAction_requestIdle ()", mInstanceIndex );
FailIf ( 0 == mTransportInterface, Exit );
FailIf ( 0 == mPlatformInterface, Exit );
mRemoteNonDetectInterruptEnabled = FALSE; debugIOLog ( 6, " AOA[%ld] where mRemoteDetectInterruptEnabled = %d, mRemoteNonDetectInterruptEnabled = %d", mInstanceIndex, mRemoteDetectInterruptEnabled, mRemoteNonDetectInterruptEnabled );
if ( kIOAudioDeviceActive == getPowerState () )
{
debugIOLog ( 3, " going from kIOAudioDeviceActive to kAudioDeviceIdle about to stop the 'pollTimer'" );
pollTimer->cancelTimeout ();
if ( mMuteAmpWhenClockInterrupted ) {
muteAllAmps();
}
FailMessage ( kIOReturnSuccess != selectCodecOutputWithMuteState ( TRUE ) );
if ( !mMuteAmpWhenClockInterrupted )
{
muteAllAmps();
}
if ( kClockSourceSelectionExternal == mCurrentClockSelector )
{
if (NULL != mExternalClockSelector) {
OSNumber * clockSourceSelector = OSNumber::withNumber ( kClockSourceSelectionInternal, 32 );
if (NULL != clockSourceSelector) {
ConfigChangeHelper theConfigChangeHelper(mDriverDMAEngine);
if (TRUE == mAutoSelectClock) {
mExternalClockSelector->removeAvailableSelection(kClockSourceSelectionExternal);
mExternalClockSelector->addAvailableSelection(kClockSourceSelectionInternal, kInternalClockString);
mExternalClockSelector->hardwareValueChanged(clockSourceSelector);
}
else {
mExternalClockSelector->setValue(clockSourceSelector);
}
clockSourceSelector->release();
}
}
clockSelectorChanged ( kClockSourceSelectionInternal );
if (TRUE == mAutoSelectClock) {
mDisableAutoSelectClock = TRUE;
mCodecLockStatus = kClockUnLockStatus;
}
}
result = callPluginsInReverseOrder ( kPowerStateChange, ( ( getPowerState () << 16 ) | kIOAudioDeviceIdle ) );
FailIf ( kIOReturnSuccess != result, Exit );
broadcastSoftwareInterruptMessage ( kRemoteIdle );
result = mTransportInterface->performTransportSleep ();
FailIf ( kIOReturnSuccess != result, Exit );
}
else
{
result = callPluginsInReverseOrder ( kPowerStateChange, ( ( getPowerState () << 16 ) | kIOAudioDeviceIdle ) );
FailIf ( kIOReturnSuccess != result, Exit );
broadcastSoftwareInterruptMessage ( kRemoteIdle );
}
result = mPlatformInterface->performPowerStateChange ( (IOService*)mPlatformInterface, getPowerState (), pendingPowerState );
FailIf ( kIOReturnSuccess != result, Exit );
mRemoteDetectInterruptEnabled = TRUE; debugIOLog ( 6, " AOA[%ld] where mRemoteDetectInterruptEnabled = %d, mRemoteNonDetectInterruptEnabled = %d", mInstanceIndex, mRemoteDetectInterruptEnabled, mRemoteNonDetectInterruptEnabled );
Exit:
debugIOLog ( 5, "- AppleOnboardAudio[%ld]::performPowerStateChangeAction_requestIdle () returns 0x%lX", mInstanceIndex, result );
return result;
}
IOReturn AppleOnboardAudio::performPowerStateChangeAction_requestSleep ( void )
{
IOReturn result = kIOReturnError;
debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::performPowerStateChangeAction_requestSleep ()", mInstanceIndex );
debugIOLog ( 3, " about to stop the 'pollTimer'" );
FailIf ( 0 == mTransportInterface, Exit );
FailIf ( 0 == mPlatformInterface, Exit );
mRemoteDetectInterruptEnabled = FALSE; mRemoteNonDetectInterruptEnabled = FALSE; debugIOLog ( 6, " AOA[%ld] where mRemoteDetectInterruptEnabled = %d, mRemoteNonDetectInterruptEnabled = %d", mInstanceIndex, mRemoteDetectInterruptEnabled, mRemoteNonDetectInterruptEnabled );
pollTimer->cancelTimeout ();
result = mPlatformInterface->performPowerStateChange ( (IOService*)mPlatformInterface, getPowerState (), pendingPowerState ); FailIf ( kIOReturnSuccess != result, Exit );
if ( kIOAudioDeviceActive == getPowerState () ) {
if ( mMuteAmpWhenClockInterrupted )
{
muteAllAmps();
}
FailMessage ( kIOReturnSuccess != selectCodecOutputWithMuteState ( TRUE ) );
if ( !mMuteAmpWhenClockInterrupted )
{
muteAllAmps();
}
if ( kClockSourceSelectionExternal == mCurrentClockSelector )
{
if (NULL != mExternalClockSelector) {
OSNumber * clockSourceSelector = OSNumber::withNumber ( kClockSourceSelectionInternal, 32 );
if (NULL != clockSourceSelector) {
ConfigChangeHelper theConfigChangeHelper(mDriverDMAEngine);
if (TRUE == mAutoSelectClock) {
mExternalClockSelector->removeAvailableSelection(kClockSourceSelectionExternal);
mExternalClockSelector->addAvailableSelection(kClockSourceSelectionInternal, kInternalClockString);
mExternalClockSelector->hardwareValueChanged(clockSourceSelector);
}
else {
mExternalClockSelector->setValue(clockSourceSelector);
}
clockSourceSelector->release();
}
}
clockSelectorChanged ( kClockSourceSelectionInternal );
if (TRUE == mAutoSelectClock) {
mDisableAutoSelectClock = TRUE;
mCodecLockStatus = kClockUnLockStatus;
}
muteAllAmps();
selectCodecOutputWithMuteState ( TRUE );
}
}
result = callPluginsInReverseOrder ( kPowerStateChange, ( ( getPowerState () << 16 ) | kIOAudioDeviceSleep ) );
FailIf ( kIOReturnSuccess != result, Exit );
broadcastSoftwareInterruptMessage ( kRemoteSleep );
if ( kIOAudioDeviceActive == getPowerState () ) {
result = mTransportInterface->performTransportSleep ();
FailIf ( kIOReturnSuccess != result, Exit );
}
Exit:
debugIOLog ( 5, "- AppleOnboardAudio[%ld]::performPowerStateChangeAction_requestSleep () returns 0x%lX", mInstanceIndex, result );
return result;
}
IOReturn AppleOnboardAudio::sysPowerDownHandler (void * target, void * refCon, UInt32 messageType, IOService * provider, void * messageArgument, vm_size_t argSize)
{
AppleOnboardAudio * appleOnboardAudio;
IOReturn result = kIOReturnUnsupported;
appleOnboardAudio = OSDynamicCast (AppleOnboardAudio, (OSObject *)target);
FailIf (0 == appleOnboardAudio, Exit);
result = appleOnboardAudio->sysPowerDownHandlerAction ( messageType );
Exit:
return result;
}
IOReturn AppleOnboardAudio::sysPowerDownHandlerAction ( UInt32 messageType )
{
IOReturn result = kIOReturnSuccess;
debugIOLog ( 6, "+ AppleOnboardAudio[%ld]::sysPowerDownHandlerAction ( %d )", mInstanceIndex, messageType );
switch ( messageType ) {
case kIOMessageSystemWillPowerOff:
case kIOMessageSystemWillRestart:
if ( mDoKPrintfPowerState )
{
IOLog ( "AppleOnboardAudio[%ld]::sysPowerDownHandlerAction setting SLEEP\n", mInstanceIndex );
}
pendingPowerState = kIOAudioDeviceSleep;
result = performPowerStateChangeAction_requestSleep ();
FailIf ( kIOReturnSuccess != result, Exit );
protectedCompletePowerStateChange ();
setProperty ( "IOAudioPowerState", getPowerState (), 32 );
mUCState.ucPowerState = getPowerState ();
break;
default:
break;
}
Exit:
debugIOLog ( 6, "- AppleOnboardAudio[%ld]::sysPowerDownHandlerAction ( %d ) return 0x%X", mInstanceIndex, messageType, result );
return result;
}
IOReturn AppleOnboardAudio::doLocalChangeToActiveState ( bool allowDetectIRQDispatch, Boolean * wasPoweredDown )
{
IOReturn result;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::doLocalChangeToActiveState ( %d, %p )", mInstanceIndex, wasPoweredDown );
if (kIOAudioDeviceActive != pendingPowerState) {
debugIOLog ( 3, " about to call performPowerStateChangeAction_requestActive" );
pendingPowerState = kIOAudioDeviceActive;
result = performPowerStateChangeAction_requestActive ( allowDetectIRQDispatch ); FailIf ( kIOReturnSuccess != result, Exit );
protectedCompletePowerStateChange ();
setProperty ( "IOAudioPowerState", getPowerState (), 32 );
mUCState.ucPowerState = getPowerState ();
FailMessage ( kIOReturnSuccess != selectCodecOutputWithMuteState ( mIsMute ) );
if ( wasPoweredDown )
{
*wasPoweredDown = TRUE;
}
setPollTimer(); } else {
debugIOLog ( 3, " pendingPowerState already = active" );
result = kIOReturnSuccess;
}
Exit:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::doLocalChangeToActiveState ( ) return 0x%X", mInstanceIndex, result );
return result;
}
IOReturn AppleOnboardAudio::doLocalChangeScheduleIdle ( Boolean wasPoweredDown )
{
IOReturn result = kIOReturnSuccess;
if ( TRUE == wasPoweredDown )
{
if ( ( kIOPMInternalPower == mCurrentAggressivenessLevel ) && ( 0 == sTotalNumAOAEnginesRunning ) )
{
if ( mDoKPrintfPowerState )
{
IOLog ( "AppleOnboardAudio[%ld]::doLocalChangeScheduleIdle ( %d ) priming timer for IDLE\n", mInstanceIndex, wasPoweredDown );
}
setIdleAudioSleepTime ( kBatteryPowerDownDelayTime ); debugIOLog ( 6, " asyncPowerStateChangeInProgress %d", asyncPowerStateChangeInProgress );
#ifdef THREAD_POWER_MANAGEMENT
if ( asyncPowerStateChangeInProgress ) {
waitForPendingPowerStateChange ();
}
#endif
debugIOLog ( 6, " setting pendingPowerState to kIOAudioDeviceIdle" );
pendingPowerState = kIOAudioDeviceIdle;
}
}
return result;
}
void AppleOnboardAudio::audioEngineStopped ()
{
debugIOLog ( 6, "+ AppleOnboardAudio[%ld]::audioEngineStopped (), sTotalNumAOAEnginesRunning %d", mInstanceIndex, sTotalNumAOAEnginesRunning );
if ( ( kIOPMInternalPower == mCurrentAggressivenessLevel ) && ( 1 == sTotalNumAOAEnginesRunning ) ) {
if ( mDoKPrintfPowerState )
{
IOLog ( "AppleOnboardAudio[%ld]::audioEngineStopped scheduling deferred IDLE\n", mInstanceIndex );
}
setIdleAudioSleepTime ( kBatteryPowerDownDelayTime );
debugIOLog ( 6, " asyncPowerStateChangeInProgress %d", asyncPowerStateChangeInProgress );
#ifdef THREAD_POWER_MANAGEMENT
if ( asyncPowerStateChangeInProgress )
{
waitForPendingPowerStateChange ();
}
#endif
debugIOLog ( 6, " setting pendingPowerState to kIOAudioDeviceIdle" );
pendingPowerState = kIOAudioDeviceIdle;
}
super::audioEngineStopped ();
if ( 0 != sTotalNumAOAEnginesRunning )
{
sTotalNumAOAEnginesRunning--;
}
debugIOLog ( 6, "- AppleOnboardAudio[%ld]::audioEngineStopped (), sTotalNumAOAEnginesRunning %d", mInstanceIndex, sTotalNumAOAEnginesRunning );
}
void AppleOnboardAudio::audioEngineStarting ()
{
debugIOLog ( 6, "+ AppleOnboardAudio[%ld]::audioEngineStarting (), sTotalNumAOAEnginesRunning %d", mInstanceIndex, sTotalNumAOAEnginesRunning );
sTotalNumAOAEnginesRunning++;
if ( 1 == sTotalNumAOAEnginesRunning )
{
pendingPowerState = kIOAudioDeviceActive;
if (2 == mInstanceIndex) {
broadcastSoftwareInterruptMessage ( kRemoteChildActive );
}
else {
broadcastSoftwareInterruptMessage ( kRemoteActive );
}
}
super::audioEngineStarting ();
debugIOLog ( 6, "- AppleOnboardAudio[%ld]::audioEngineStarting (), sTotalNumAOAEnginesRunning %d", mInstanceIndex, sTotalNumAOAEnginesRunning );
}
#pragma mark +PRAM VOLUME
UInt8 AppleOnboardAudio::VolumeToPRAMValue (UInt32 inLeftVol, UInt32 inRightVol) {
UInt32 pramVolume; UInt32 averageVolume; UInt32 volumeRange;
UInt32 volumeSteps;
UInt32 leftVol;
UInt32 rightVol;
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::VolumeToPRAMValue ( 0x%X, 0x%X )", mInstanceIndex, (unsigned int)inLeftVol, (unsigned int)inRightVol );
pramVolume = 0; if ( ( 0 != inLeftVol ) || ( 0 != inRightVol ) ) { leftVol = inLeftVol;
rightVol = inRightVol;
if ( 0 != mOutLeftVolumeControl) {
leftVol -= mOutLeftVolumeControl->getMinValue ();
}
if (0 != mOutRightVolumeControl) {
rightVol -= mOutRightVolumeControl->getMinValue ();
}
debugIOLog ( 3, " ... leftVol = 0x%X, rightVol = 0x%X", (unsigned int)leftVol, (unsigned int)rightVol );
if (0 != mOutMasterVolumeControl) {
volumeRange = (mOutMasterVolumeControl->getMaxValue () - mOutMasterVolumeControl->getMinValue () + 1);
debugIOLog ( 3, " ... mOutMasterVolumeControl volumeRange = 0x%X", (unsigned int)volumeRange );
} else if (0 != mOutLeftVolumeControl) {
volumeRange = (mOutLeftVolumeControl->getMaxValue () - mOutLeftVolumeControl->getMinValue () + 1);
debugIOLog ( 3, " ... mOutLeftVolumeControl volumeRange = 0x%X", (unsigned int)volumeRange );
} else if (0 != mOutRightVolumeControl) {
volumeRange = (mOutRightVolumeControl->getMaxValue () - mOutRightVolumeControl->getMinValue () + 1);
debugIOLog ( 3, " ... mOutRightVolumeControl volumeRange = 0x%X", (unsigned int)volumeRange );
} else {
volumeRange = kMaximumPRAMVolume;
debugIOLog ( 3, " ... volumeRange = 0x%X **** NO AUDIO LEVEL CONTROLS!", (unsigned int)volumeRange );
}
averageVolume = (leftVol + rightVol) >> 1; debugIOLog ( 3, " ... averageVolume = 0x%X", (unsigned int)volumeRange );
debugIOLog ( 3, " ... volumeRange %X, kMaximumPRAMVolume %X", (unsigned int)volumeRange, (unsigned int)kMaximumPRAMVolume );
volumeSteps = volumeRange / kMaximumPRAMVolume; pramVolume = averageVolume / volumeSteps;
if ((pramVolume == 0) && (leftVol != 0 || rightVol !=0 )) {
pramVolume = 1;
}
}
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::VolumeToPRAMValue ( 0x%X, 0x%X ) returns 0x%X", mInstanceIndex, (unsigned int)inLeftVol, (unsigned int)inRightVol, (unsigned int)(pramVolume & 0x07) );
return (pramVolume & 0x07);
}
UInt32 AppleOnboardAudio::PRAMToVolumeValue (void) {
UInt32 volumeRange;
UInt32 volumeSteps;
if ( 0 != mOutMasterVolumeControl ) {
volumeRange = (mOutMasterVolumeControl->getMaxValue () - mOutMasterVolumeControl->getMinValue () + 1);
} else if ( 0 != mOutLeftVolumeControl ) {
volumeRange = (mOutLeftVolumeControl->getMaxValue () - mOutLeftVolumeControl->getMinValue () + 1);
} else if ( 0 != mOutRightVolumeControl ) {
volumeRange = (mOutRightVolumeControl->getMaxValue () - mOutRightVolumeControl->getMinValue () + 1);
} else {
volumeRange = kMaximumPRAMVolume;
}
volumeSteps = volumeRange / KNumPramVolumeSteps;
return (volumeSteps * ReadPRAMVol ());
}
void AppleOnboardAudio::WritePRAMVol (UInt32 leftVol, UInt32 rightVol) {
UInt8 pramVolume;
UInt8 curPRAMVol;
IODTPlatformExpert * platform;
IOReturn err;
platform = OSDynamicCast(IODTPlatformExpert,getPlatform());
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::WritePRAMVol ( leftVol=%lu, rightVol=%lu )", mInstanceIndex, leftVol, rightVol);
if (platform) {
pramVolume = VolumeToPRAMValue (leftVol, rightVol);
err = platform->readXPRAM((IOByteCount)kPRamVolumeAddr, &curPRAMVol, (IOByteCount)1);
if ( kIOReturnSuccess == err ) {
if (pramVolume != (curPRAMVol & 0x07)) {
curPRAMVol = (curPRAMVol & 0xF8) | pramVolume;
err = platform->writeXPRAM((IOByteCount)kPRamVolumeAddr, &curPRAMVol,(IOByteCount) 1);
if ( kIOReturnSuccess != err ) {
debugIOLog ( 3, " 0x%X = platform->writeXPRAM( 0x%X, & 0x%X, 1 ), value = 0x%X", err, (unsigned int)kPRamVolumeAddr, (unsigned int)&curPRAMVol, (unsigned int)curPRAMVol );
} else {
mUCState.ucPramData = (UInt32)curPRAMVol;
mUCState.ucPramVolume = mUCState.ucPramData & 0x00000007;
}
} else {
debugIOLog ( 3, " PRAM write request is to current value: no I/O" );
}
} else {
debugIOLog ( 3, " Could not readXPRAM prior to write! Error 0x%X", err );
}
} else {
debugIOLog ( 3, " ... no platform" );
}
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::WritePRAMVol ( leftVol=%lu, rightVol=%lu )", mInstanceIndex, leftVol, rightVol);
}
UInt8 AppleOnboardAudio::ReadPRAMVol (void) {
UInt8 curPRAMVol;
IODTPlatformExpert * platform;
curPRAMVol = 0;
platform = OSDynamicCast(IODTPlatformExpert,getPlatform());
if (platform) {
platform->readXPRAM((IOByteCount)kPRamVolumeAddr, &curPRAMVol, (IOByteCount)1);
curPRAMVol &= 0x07;
}
return curPRAMVol;
}
#pragma mark +USER CLIENT
IOReturn AppleOnboardAudio::newUserClient( task_t inOwningTask,
void * inSecurityID,
UInt32 inType,
IOUserClient ** outHandler )
{
#pragma unused( inType )
IOUserClient * userClientPtr;
IOReturn err;
bool result;
err = kIOReturnError;
result = false;
userClientPtr = AppleOnboardAudioUserClient::Create( this, inOwningTask );
FailIf ( 0 == userClientPtr, Exit );
err = kIOReturnError;
result = userClientPtr->attach( this );
FailIf (!result, Exit);
result = userClientPtr->start( this );
FailIf (!result, Exit);
*outHandler = userClientPtr;
err = kIOReturnSuccess;
Exit:
if( err != kIOReturnSuccess )
{
if( userClientPtr )
{
userClientPtr->detach( this );
userClientPtr->release();
}
}
return( err );
}
IOReturn AppleOnboardAudio::getPlatformState ( UInt32 arg2, void * outState ) {
#pragma unused ( arg2 )
IOReturn result = kIOReturnError;
FailIf ( 0 == outState, Exit );
FailIf ( 0 == mPlatformInterface, Exit );
result = mPlatformInterface->getPlatformState ( (PlatformStateStructPtr)outState );
Exit:
return result;
}
IOReturn AppleOnboardAudio::getPluginState ( HardwarePluginType thePluginType, void * outState ) {
AudioHardwareObjectInterface * thePluginObject;
IOReturn result = kIOReturnError;
debugIOLog ( 7, "+ AppleOnboardAudio[%ld]::getPluginState ( %d, %p )", mInstanceIndex, thePluginType, outState);
FailIf ( 0 == outState, Exit );
thePluginObject = findPluginForType ( thePluginType );
if ( 0 != thePluginObject ) {
result = thePluginObject->getPluginState ( (HardwarePluginDescriptorPtr)outState );
}
Exit:
debugIOLog ( 7, "- AppleOnboardAudio[%ld]::getPluginState ( %d, %p ) returns 0x%lX", mInstanceIndex, thePluginType, outState, result );
return result;
}
IOReturn AppleOnboardAudio::getDMAStateAndFormat ( UInt32 arg2, void * outState ) {
IOReturn result;
switch ( (DMA_STATE_SELECTOR)arg2 ) {
case kGetDMAStateAndFormat: result = mDriverDMAEngine->copyDMAStateAndFormat ( (DBDMAUserClientStructPtr)outState ); break;
case kGetDMAInputChannelCommands: result = mDriverDMAEngine->copyInputChannelCommands ( outState ); break;
case kGetDMAInputChannelCommands1: result = mDriverDMAEngine->copyInputChannelCommands1 ( outState ); break;
case kGetDMAOutputChannelCommands: result = mDriverDMAEngine->copyOutputChannelCommands ( outState ); break;
case kGetDMAOutputChannelCommands1: result = mDriverDMAEngine->copyOutputChannelCommands1 ( outState ); break;
case kGetInputChannelRegisters: result = mDriverDMAEngine->copyInputChannelRegisters ( outState ); break;
case kGetOutputChannelRegisters: result = mDriverDMAEngine->copyOutputChannelRegisters ( outState ); break;
default: result = kIOReturnBadArgument; break;
}
return result;
}
IOReturn AppleOnboardAudio::setDMAStateAndFormat ( UInt32 arg2, void * inState ) {
IOReturn result;
debugIOLog ( 5, "+ AppleOnboardAudio[%ld]::setDMAStateAndFormat( %d, %p )", mInstanceIndex, arg2, inState );
switch ( (DMA_STATE_SELECTOR)arg2 ) {
case kSetInputChannelRegisters: result = mDriverDMAEngine->setInputChannelRegisters ( inState ); break;
case kSetOutputChannelRegisters: result = mDriverDMAEngine->setOutputChannelRegisters ( inState ); break;
case kSetDMAStateAndFormat: result = mDriverDMAEngine->setDMAStateAndFormat ( (DBDMAUserClientStructPtr)inState ); break;
default: result = kIOReturnBadArgument; break;
}
debugIOLog ( 5, "- AppleOnboardAudio[%ld]::setDMAStateAndFormat( %d, %p ) returns %lX", mInstanceIndex, arg2, inState, result );
return result;
}
IOReturn AppleOnboardAudio::getSoftwareProcessingState ( UInt32 arg2, void * outState ) {
#pragma unused ( arg2 )
IOReturn result = kIOReturnError;
return result;
}
IOReturn AppleOnboardAudio::getRealTimeCPUUsage ( UInt32 arg2, void * outState ) {
#pragma unused ( arg2 )
return kIOReturnError;
}
IOReturn AppleOnboardAudio::getAOAState ( UInt32 arg2, void * outState ) {
#pragma unused ( arg2 )
IOReturn result;
const IOAudioEngineStatus * engineStatusPtr;
result = kIOReturnError;
FailIf ( 0 != arg2, Exit );
FailIf (0 == outState, Exit );
debugIOLog ( 7, "AppleOnboardAudio[%ld]::getAOAState for type %ld", mInstanceIndex, arg2 );
engineStatusPtr = mDriverDMAEngine->getStatus();
if ( engineStatusPtr ) {
((AOAStateUserClientStructPtr)outState)->uc_fVersion = engineStatusPtr->fVersion;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioEngineStatus_fCurrentLoopCount = engineStatusPtr->fCurrentLoopCount;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioEngineStatus_fLastLoopTime_hi = engineStatusPtr->fLastLoopTime.hi;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioEngineStatus_fLastLoopTime_lo = engineStatusPtr->fLastLoopTime.lo;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioEngineStatus_fEraseHeadSampleFrame = engineStatusPtr->fEraseHeadSampleFrame;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioEngineState = mDriverDMAEngine->state;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioEngine_sampleOffset = mDriverDMAEngine->sampleOffset;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioStreamFormatExtension_fVersion = 0;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioStreamFormatExtension_fFlags = 0;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioStreamFormatExtension_fFramesPerPacket = 0;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioStreamFormatExtension_fBytesPerPacket = 0;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioEngine_sampleOffset = mDriverDMAEngine->sampleOffset;
} else {
((AOAStateUserClientStructPtr)outState)->uc_fVersion = 0;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioEngineStatus_fCurrentLoopCount = 0;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioEngineStatus_fLastLoopTime_hi = 0;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioEngineStatus_fLastLoopTime_lo = 0;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioEngineStatus_fEraseHeadSampleFrame = 0;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioEngineState = 0;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioEngine_sampleOffset = 0;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioStreamFormatExtension_fVersion = 0;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioStreamFormatExtension_fFlags = 0;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioStreamFormatExtension_fFramesPerPacket = 0;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioStreamFormatExtension_fBytesPerPacket = 0;
((AOAStateUserClientStructPtr)outState)->uc_IOAudioEngine_sampleOffset = 0;
}
((AOAStateUserClientStructPtr)outState)->ucPramData = mUCState.ucPramData;
((AOAStateUserClientStructPtr)outState)->ucPramVolume = mUCState.ucPramVolume;
((AOAStateUserClientStructPtr)outState)->ucPowerState = mUCState.ucPowerState;
((AOAStateUserClientStructPtr)outState)->ucLayoutID = mLayoutID;
((AOAStateUserClientStructPtr)outState)->uc_mDoKPrintfPowerState = (UInt32)mDoKPrintfPowerState;
((AOAStateUserClientStructPtr)outState)->uc_sTotalNumAOAEnginesRunning = sTotalNumAOAEnginesRunning;
((AOAStateUserClientStructPtr)outState)->uc_numRunningAudioEngines = numRunningAudioEngines;
((AOAStateUserClientStructPtr)outState)->uc_currentAggressivenessLevel = mCurrentAggressivenessLevel;
result = kIOReturnSuccess;
Exit:
return result;
}
IOReturn AppleOnboardAudio::getTransportInterfaceState ( UInt32 arg2, void * outState ) {
#pragma unused ( arg2 )
IOReturn result = kIOReturnError;
if ( 0 != mTransportInterface ) {
result = mTransportInterface->getTransportInterfaceState ( (TransportStateStructPtr)outState );
}
return result;
}
IOReturn AppleOnboardAudio::setPlatformState ( UInt32 arg2, void * inState ) {
#pragma unused ( arg2 )
IOReturn result = kIOReturnError;
FailIf ( 0 == inState, Exit );
FailIf ( 0 == mPlatformInterface, Exit );
result = mPlatformInterface->setPlatformState ( (PlatformStateStructPtr)inState );
Exit:
return result;
}
IOReturn AppleOnboardAudio::setPluginState ( HardwarePluginType thePluginType, void * inState ) {
AudioHardwareObjectInterface * thePluginObject;
IOReturn result = kIOReturnError;
FailIf ( 0 == inState, Exit );
thePluginObject = findPluginForType ( thePluginType );
FailIf ( 0 == thePluginObject, Exit );
result = thePluginObject->setPluginState ( (HardwarePluginDescriptorPtr)inState );
Exit:
return result;
}
IOReturn AppleOnboardAudio::setDMAState ( UInt32 arg2, void * inState ) {
#pragma unused ( arg2 )
return kIOReturnError;
}
IOReturn AppleOnboardAudio::setSoftwareProcessingState ( UInt32 arg2, void * inState ) {
#pragma unused ( arg2 )
return kIOReturnError;
}
IOReturn AppleOnboardAudio::setAOAState ( UInt32 arg2, void * inState ) {
#pragma unused ( arg2 )
mDoKPrintfPowerState = (bool)(((AOAStateUserClientStructPtr)inState)->uc_mDoKPrintfPowerState);
if ( mDoKPrintfPowerState )
{
switch ( getPowerState () )
{
case kIOAudioDeviceSleep: IOLog ( "AppleOnboardAudio[%ld] is currently SLEEP\n", mInstanceIndex ); break;
case kIOAudioDeviceIdle: IOLog ( "AppleOnboardAudio[%ld] is currently IDLE\n", mInstanceIndex ); break;
case kIOAudioDeviceActive: IOLog ( "AppleOnboardAudio[%ld] is currently ACTIVE\n", mInstanceIndex ); break;
}
}
return kIOReturnSuccess;
}
IOReturn AppleOnboardAudio::setTransportInterfaceState ( UInt32 arg2, void * inState ) {
#pragma unused ( arg2 )
IOReturn result = kIOReturnError;
if ( 0 != mTransportInterface ) {
result = mTransportInterface->setTransportInterfaceState ( (TransportStateStructPtr)inState );
}
return result;
}
ConfigChangeHelper::ConfigChangeHelper (IOAudioEngine * inEngine, UInt32 inSleep) {
mDriverDMAEngine = inEngine;
if (0 != mDriverDMAEngine) {
UInt32 engineState = mDriverDMAEngine->getState();
debugIOLog (5, " ConfigChangeHelper (%p, %ld) - about to try to mDriverDMAEngine->pauseAudioEngine...engine state = %lu", inEngine, inSleep, engineState);
if ( ( kIOAudioEngineRunning == engineState ) || ( kIOAudioEngineResumed == engineState ) ) {
mDriverDMAEngine->pauseAudioEngine ();
}
if (0 != inSleep) {
debugIOLog ( 4, " waiting %d ms between pause and begin", inSleep);
IOSleep ( 10 );
}
mDriverDMAEngine->beginConfigurationChange ();
}
}
ConfigChangeHelper::~ConfigChangeHelper () {
if (0 != mDriverDMAEngine) {
UInt32 engineState;
mDriverDMAEngine->completeConfigurationChange ();
engineState = mDriverDMAEngine->getState();
debugIOLog (5, " ~ConfigChangeHelper - about to try to mDriverDMAEngine->resumeAudioEngine...engine state = %lu", engineState);
if ( kIOAudioEnginePaused == engineState ) {
mDriverDMAEngine->resumeAudioEngine ();
if ( kIOAudioEngineResumed == mDriverDMAEngine->getState() ) {
mDriverDMAEngine->startAudioEngine ();
}
}
}
}
#pragma mark +LOGGING UTILITIES
void AppleOnboardAudio::logPerformPowerStateChangeAction ( UInt32 mInstanceIndex, UInt32 newPowerState, UInt32 curPowerState, bool flag, IOReturn resultCode )
{
if ( kLOG_ENTRY_TO_AOA_METHOD == flag )
{
switch ( (UInt32)newPowerState ) {
case kIOAudioDeviceActive:
switch ( curPowerState ) {
case kIOAudioDeviceActive:
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceActive ), currentPowerState = %d kIOAudioDeviceActive", mInstanceIndex, (UInt32)newPowerState, getPowerState () );
break;
case kIOAudioDeviceIdle:
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceActive ), currentPowerState = %d kIOAudioDeviceIdle", mInstanceIndex, (UInt32)newPowerState, getPowerState () );
break;
case kIOAudioDeviceSleep:
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceActive ), currentPowerState = %d kIOAudioDeviceSleep", mInstanceIndex, (UInt32)newPowerState, getPowerState () );
break;
default:
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceActive ), currentPowerState = %d", mInstanceIndex, (UInt32)newPowerState, getPowerState () );
break;
}
break;
case kIOAudioDeviceIdle:
switch ( getPowerState () ) {
case kIOAudioDeviceActive:
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceIdle ), currentPowerState = %d kIOAudioDeviceActive", mInstanceIndex, (UInt32)newPowerState, getPowerState () );
break;
case kIOAudioDeviceIdle:
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceIdle ), currentPowerState = %d kIOAudioDeviceIdle", mInstanceIndex, (UInt32)newPowerState, getPowerState () );
break;
case kIOAudioDeviceSleep:
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceIdle ), currentPowerState = %d kIOAudioDeviceSleep", mInstanceIndex, (UInt32)newPowerState, getPowerState () );
break;
default:
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceIdle ), currentPowerState = %d", mInstanceIndex, (UInt32)newPowerState, getPowerState () );
break;
}
break;
case kIOAudioDeviceSleep:
switch ( getPowerState () ) {
case kIOAudioDeviceActive:
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceSleep ), currentPowerState = %d kIOAudioDeviceActive", mInstanceIndex, (UInt32)newPowerState, getPowerState () );
break;
case kIOAudioDeviceIdle:
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceSleep ), currentPowerState = %d kIOAudioDeviceIdle", mInstanceIndex, (UInt32)newPowerState, getPowerState () );
break;
case kIOAudioDeviceSleep:
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceSleep ), currentPowerState = %d kIOAudioDeviceSleep", mInstanceIndex, (UInt32)newPowerState, getPowerState () );
break;
default:
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceSleep ), currentPowerState = %d", mInstanceIndex, (UInt32)newPowerState, getPowerState () );
break;
}
break;
default:
switch ( currentPowerState ) {
case kIOAudioDeviceActive:
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld ), currentPowerState = %d kIOAudioDeviceActive", mInstanceIndex, (UInt32)newPowerState, currentPowerState);
break;
case kIOAudioDeviceIdle:
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld ), currentPowerState = %d kIOAudioDeviceIdle", mInstanceIndex, (UInt32)newPowerState, currentPowerState);
break;
case kIOAudioDeviceSleep:
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld ), currentPowerState = %d kIOAudioDeviceSleep", mInstanceIndex, (UInt32)newPowerState, currentPowerState);
break;
default:
debugIOLog ( 3, "+ AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld ), currentPowerState = %d", mInstanceIndex, (UInt32)newPowerState, currentPowerState);
break;
}
break;
}
}
else if ( kLOG_EXIT_FROM_AOA_METHOD == flag )
{
switch ( (UInt32)newPowerState ) {
case kIOAudioDeviceActive:
switch ( currentPowerState ) {
case kIOAudioDeviceActive:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceActive ), currentPowerState = %d kIOAudioDeviceActive, returns 0x%0.8X", mInstanceIndex, (UInt32)newPowerState, currentPowerState, resultCode);
break;
case kIOAudioDeviceIdle:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceActive ), currentPowerState = %d kIOAudioDeviceIdle, returns 0x%0.8X", mInstanceIndex, (UInt32)newPowerState, currentPowerState, resultCode);
break;
case kIOAudioDeviceSleep:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceActive ), currentPowerState = %d kIOAudioDeviceSleep, returns 0x%0.8X", mInstanceIndex, (UInt32)newPowerState, currentPowerState, resultCode);
break;
default:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceActive ), currentPowerState = %d, returns 0x%0.8X", mInstanceIndex, (UInt32)newPowerState, currentPowerState, resultCode);
break;
}
break;
case kIOAudioDeviceIdle:
switch ( currentPowerState ) {
case kIOAudioDeviceActive:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceIdle ), currentPowerState = %d kIOAudioDeviceActive, returns 0x%0.8X", mInstanceIndex, (UInt32)newPowerState, currentPowerState, resultCode);
break;
case kIOAudioDeviceIdle:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceIdle ), currentPowerState = %d kIOAudioDeviceIdle, returns 0x%0.8X", mInstanceIndex, (UInt32)newPowerState, currentPowerState, resultCode);
break;
case kIOAudioDeviceSleep:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceIdle ), currentPowerState = %d kIOAudioDeviceSleep, returns 0x%0.8X", mInstanceIndex, (UInt32)newPowerState, currentPowerState, resultCode);
break;
default:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceIdle ), currentPowerState = %d, returns 0x%0.8X", mInstanceIndex, (UInt32)newPowerState, currentPowerState, resultCode);
break;
}
break;
case kIOAudioDeviceSleep:
switch ( currentPowerState ) {
case kIOAudioDeviceActive:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceSleep ), currentPowerState = %d kIOAudioDeviceActive, returns 0x%0.8X", mInstanceIndex, (UInt32)newPowerState, currentPowerState, resultCode);
break;
case kIOAudioDeviceIdle:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceSleep ), currentPowerState = %d kIOAudioDeviceIdle, returns 0x%0.8X", mInstanceIndex, (UInt32)newPowerState, currentPowerState, resultCode);
break;
case kIOAudioDeviceSleep:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceSleep ), currentPowerState = %d kIOAudioDeviceSleep, returns 0x%0.8X", mInstanceIndex, (UInt32)newPowerState, currentPowerState, resultCode);
break;
default:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld = kIOAudioDeviceSleep ), currentPowerState = %d, returns 0x%0.8X", mInstanceIndex, (UInt32)newPowerState, currentPowerState, resultCode);
break;
}
break;
default:
switch ( currentPowerState ) {
case kIOAudioDeviceActive:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld ), currentPowerState = %d kIOAudioDeviceActive, returns 0x%0.8X", mInstanceIndex, (UInt32)newPowerState, currentPowerState, resultCode);
break;
case kIOAudioDeviceIdle:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld ), currentPowerState = %d kIOAudioDeviceIdle, returns 0x%0.8X", mInstanceIndex, (UInt32)newPowerState, currentPowerState, resultCode);
break;
case kIOAudioDeviceSleep:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld ), currentPowerState = %d kIOAudioDeviceSleep, returns 0x%0.8X", mInstanceIndex, (UInt32)newPowerState, currentPowerState, resultCode);
break;
default:
debugIOLog ( 3, "- AppleOnboardAudio[%ld]::performPowerStateChangeAction ( %ld ), currentPowerState = %d, returns 0x%0.8X", mInstanceIndex, (UInt32)newPowerState, currentPowerState, resultCode);
break;
}
break;
}
}
}