AppleOnboardAudio.cpp [plain text]
#include "AppleOnboardAudio.h"
OSDefineMetaClassAndAbstractStructors(AppleOnboardAudio, IOAudioDevice)
#define super IOAudioDevice
#pragma mark +UNIX LIKE FUNCTIONS
bool AppleOnboardAudio::init(OSDictionary *properties)
{
OSDictionary *AOAprop;
DEBUG_IOLOG("+ AppleOnboardAudio::init\n");
if (!super::init(properties)) return false;
outMute =0;
playthruToggle =0;
outVolLeft =0;
outVolRight =0;
inGainLeft =0;
inGainRight =0;
inputSelector = 0;
gIsMute = false;
gIsPlayThroughActive = false;
gVolLeft =0;
gVolRight =0;
gGainLeft = 0;
gGainRight = 0;
gIsModemSoundActive = false;
gHasModemSound = false;
gLastInputSourceBeforeModem =0;
gExpertMode = false;
AudioDetects = 0;
AudioOutputs = 0;
AudioInputs = 0;
AudioSoftDSPFeatures = 0;
driverDMAEngine = 0;
currentDevices = 0xFFFF;
theAudioPowerObject = 0;
theAudioDeviceTreeParser = 0;
if ( AOAprop = OSDynamicCast(OSDictionary, properties->getObject("AOAAttributes"))) {
gHasModemSound =
(kOSBooleanTrue == OSDynamicCast(OSBoolean, AOAprop->getObject("analogModem")));
}
CLOG("- AppleOnboardAudio::init\n");
return true;
}
void AppleOnboardAudio::free()
{
DEBUG_IOLOG("+ AppleOnboardAudio::free\n");
if(driverDMAEngine)
driverDMAEngine->release();
CLEAN_RELEASE(outMute);
CLEAN_RELEASE(playthruToggle);
CLEAN_RELEASE(outVolLeft);
CLEAN_RELEASE(outVolRight);
CLEAN_RELEASE(inGainLeft);
CLEAN_RELEASE(inGainRight);
CLEAN_RELEASE(inputSelector);
CLEAN_RELEASE(theAudioPowerObject);
CLEAN_RELEASE(AudioDetects);
CLEAN_RELEASE(AudioOutputs);
CLEAN_RELEASE(AudioInputs);
CLEAN_RELEASE(theAudioDeviceTreeParser);
super::free();
DEBUG_IOLOG("- AppleOnboardAudio::free, (void)\n");
}
IOService* AppleOnboardAudio::probe(IOService* provider, SInt32* score)
{
DEBUG_IOLOG("+ AppleOnboardAudio::probe\n");
super::probe(provider, score);
DEBUG_IOLOG("- AppleOnboardAudio::probe\n");
return (0);
}
OSArray *AppleOnboardAudio::getDetectArray(){
return(AudioDetects);
}
bool AppleOnboardAudio::getMuteState(){
return(gIsMute);
}
void AppleOnboardAudio::setMuteState(bool newMuteState){
outMute->setValue(newMuteState);
}
#pragma mark +PORT HANDLER FUNCTIONS
IOReturn AppleOnboardAudio::configureAudioOutputs(IOService *provider) {
IOReturn result = kIOReturnSuccess;
AudioHardwareOutput *theOutput;
UInt16 idx;
DEBUG_IOLOG("+ AppleOnboardAudio::configureAudioOutputs\n");
if(!theAudioDeviceTreeParser)
goto BAIL;
AudioOutputs = theAudioDeviceTreeParser->createOutputsArray();
if(!AudioOutputs)
goto BAIL;
for(idx = 0; idx < AudioOutputs->getCount(); idx++) {
theOutput = OSDynamicCast(AudioHardwareOutput, AudioOutputs->getObject(idx));
if( theOutput) theOutput->attachAudioPluginRef((AppleOnboardAudio *) this);
}
EXIT:
DEBUG2_IOLOG("- AppleOnboardAudio::configureAudioOutputs, %d\n", (result == kIOReturnSuccess));
return(result);
BAIL:
result = kIOReturnError;
goto EXIT;
}
IOReturn AppleOnboardAudio::configureAudioDetects(IOService *provider) {
IOReturn result = kIOReturnSuccess;
DEBUG_IOLOG("+ AppleOnboardAudio::configureAudioDetects\n");
if(!theAudioDeviceTreeParser)
goto BAIL;
AudioDetects = theAudioDeviceTreeParser->createDetectsArray();
EXIT:
DEBUG2_IOLOG("- AppleOnboardAudio::configureAudioDetects, %d \n", (result == kIOReturnSuccess));
return(result);
BAIL:
result = kIOReturnError;
goto EXIT;
}
IOReturn AppleOnboardAudio::configureAudioInputs(IOService *provider) {
IOReturn result = kIOReturnSuccess;
UInt16 idx;
AudioHardwareInput *theInput;
AudioHardwareMux *theMux;
DEBUG_IOLOG("+ AppleOnboardAudio::configureAudioDetects\n");
if(!theAudioDeviceTreeParser)
goto BAIL;
AudioInputs = theAudioDeviceTreeParser->createInputsArrayWithMuxes();
if(!AudioInputs)
goto BAIL;
for(idx = 0; idx < AudioInputs->getCount(); idx++) {
theInput = OSDynamicCast(AudioHardwareInput, AudioInputs->getObject(idx));
if( theInput) {
theInput->attachAudioPluginRef((AppleOnboardAudio *) this);
} else {
theMux = OSDynamicCast(AudioHardwareMux, AudioInputs->getObject(idx));
if(theMux) theMux->attachAudioPluginRef((AppleOnboardAudio *) this);
}
}
EXIT:
DEBUG2_IOLOG("- AppleOnboardAudio::configureAudioDetects, %d \n", (result == kIOReturnSuccess));
return(result);
BAIL:
result = kIOReturnError;
goto EXIT;
}
IOReturn AppleOnboardAudio::parseAndActivateInit(IOService *provider){
IOReturn result = kIOReturnSuccess;
SInt16 initType = 0;
DEBUG_IOLOG("+ AppleOnboardAudio::parseAndActivateInit\n");
if(!theAudioDeviceTreeParser)
goto BAIL;
initType = theAudioDeviceTreeParser->getInitOperationType();
if(2 == initType)
sndHWSetProgOutput(kSndHWProgOutput0);
EXIT:
DEBUG2_IOLOG("- AppleOnboardAudio::parseAndActivateInit, %d\n", (result == kIOReturnSuccess));
return(result);
BAIL:
result = kIOReturnError;
goto EXIT;
}
UInt32 AppleOnboardAudio::getCurrentDevices(){
return(currentDevices);
}
void AppleOnboardAudio::setCurrentDevices(UInt32 devices){
UInt32 odevice;
if(devices != currentDevices) {
odevice = currentDevices;
currentDevices = devices;
changedDeviceHandler(odevice);
}
}
void AppleOnboardAudio::changedDeviceHandler(UInt32 olddevices){
UInt16 i;
AudioHardwareOutput *theOutput;
if(AudioOutputs) {
for(i = 0; i< AudioOutputs->getCount(); i++) {
theOutput = OSDynamicCast(AudioHardwareOutput, AudioOutputs->getObject(i));
if( theOutput) theOutput->deviceIntService(currentDevices);
}
}
}
#pragma mark +IOAUDIO INIT
bool AppleOnboardAudio::initHardware(IOService *provider){
bool result = true;
DEBUG_IOLOG("+ AppleOnboardAudio::initHardware\n");
if (!super::initHardware(provider)) {
goto BAIL;
}
sndHWInitialize(provider);
theAudioDeviceTreeParser = AudioDeviceTreeParser::createWithEntryProvider(provider);
setManufacturerName("Apple");
setDeviceName("Built-in audio controller");
parseAndActivateInit(provider);
configureAudioDetects(provider);
configureAudioOutputs(provider);
configureAudioInputs(provider);
configurePowerObject(provider);
configureDMAEngines(provider);
createDefaultsPorts();
if( kIOReturnSuccess != activateAudioEngine(driverDMAEngine)){
driverDMAEngine->release();
goto BAIL;
}
flushAudioControls();
publishResource("setModemSound", this);
EXIT:
DEBUG_IOLOG("- AppleOnboardAudio::initHardware\n");
return(result);
BAIL:
result = false;
goto EXIT;
}
IOReturn AppleOnboardAudio::configureDMAEngines(IOService *provider){
IOReturn result = kIOReturnSuccess;
bool hasInput;
if(!theAudioDeviceTreeParser)
goto BAIL;
if( theAudioDeviceTreeParser->getNumberOfInputs() > 0)
hasInput = true;
else
hasInput = false;
driverDMAEngine = new AppleDBDMAAudioDMAEngine;
if (!driverDMAEngine->init(0, provider, hasInput)) {
driverDMAEngine->release();
goto BAIL;
}
EXIT:
return result;
BAIL:
result = kIOReturnError;
goto EXIT;
}
IOReturn AppleOnboardAudio::createDefaultsPorts(){
IOAudioPort *outputPort = 0;
IOAudioPort *inputPort = 0;
IOReturn result = kIOReturnSuccess;
OSDictionary *AOAprop = 0, *theRange = 0;
OSNumber *theNumber;
OSData *theData;
SInt32 OutminLin, OutmaxLin, InminLin, InmaxLin;
IOFixed OutminDB, OutmaxDB, InminDB, InmaxDB;
bool hasIMic;
UInt32 idx;
DEBUG_IOLOG("+ AppleOnboardAudio::createDefaultsPorts\n");
if (!driverDMAEngine) goto BAIL;
outputPort = IOAudioPort::withAttributes(kIOAudioPortTypeOutput, "Main Output port");
if (!outputPort) {
return kIOReturnError;
}
if ( !(AOAprop = OSDynamicCast(OSDictionary, this->getProperty("AOAAttributes")))) {
return kIOReturnError;
}
if(!(theRange= OSDynamicCast(OSDictionary, AOAprop->getObject("RangeOut")))) {
return kIOReturnError;
}
theNumber = OSDynamicCast(OSNumber, theRange->getObject("minLin"));
OutminLin = (SInt32) theNumber->unsigned32BitValue();
theNumber = OSDynamicCast(OSNumber, theRange->getObject("maxLin"));
OutmaxLin = (SInt32) theNumber->unsigned32BitValue();
theData = OSDynamicCast(OSData, theRange->getObject("minLog"));
OutminDB = *((IOFixed*) theData->getBytesNoCopy());
theData = OSDynamicCast(OSData, theRange->getObject("maxLog"));
OutmaxDB = *((IOFixed*) theData->getBytesNoCopy());
fMaxVolume = OutmaxLin;
fMinVolume = OutminLin;
outVolLeft = IOAudioLevelControl::createVolumeControl(OutmaxLin, OutminLin, OutmaxLin, OutminDB, OutmaxDB,
kIOAudioControlChannelIDDefaultLeft,
kIOAudioControlChannelNameLeft,
kOutVolLeft,
kIOAudioControlUsageOutput);
if (!outVolLeft) {
return false;
}
driverDMAEngine->addDefaultAudioControl(outVolLeft);
outVolLeft->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)volumeLeftChangeHandler, this);
outVolRight = IOAudioLevelControl::createVolumeControl(OutmaxLin, OutminLin, OutmaxLin, OutminDB, OutmaxDB,
kIOAudioControlChannelIDDefaultRight,
kIOAudioControlChannelNameRight,
kOutVolRight,
kIOAudioControlUsageOutput);
if (!outVolRight) {
return false;
}
driverDMAEngine->addDefaultAudioControl(outVolRight);
outVolRight->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)volumeRightChangeHandler, this);
outMute = IOAudioToggleControl::createMuteControl(false,
kIOAudioControlChannelIDAll,
kIOAudioControlChannelNameAll,
kOutMute,
kIOAudioControlUsageOutput);
if (!outMute) {
return false;
}
driverDMAEngine->addDefaultAudioControl(outMute);
outMute->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)outputMuteChangeHandler, this);
if(!(theAudioDeviceTreeParser->getNumberOfInputs() > 0)) goto EXIT;
inputPort = IOAudioPort::withAttributes(kIOAudioPortTypeInput, "Main Input Port");
if (!inputPort) {
return false;
}
if(!(theRange= OSDynamicCast(OSDictionary, AOAprop->getObject("RangeIn")))) {
return kIOReturnError;
}
theNumber = OSDynamicCast(OSNumber, theRange->getObject("minLin"));
InminLin = (SInt32) theNumber->unsigned32BitValue();
theNumber = OSDynamicCast(OSNumber, theRange->getObject("maxLin"));
InmaxLin = (SInt32) theNumber->unsigned32BitValue();
theData = OSDynamicCast(OSData, theRange->getObject("minLog"));
InminDB = *((IOFixed*) theData->getBytesNoCopy());
theData = OSDynamicCast(OSData, theRange->getObject("maxLog"));
InmaxDB = *((IOFixed*) theData->getBytesNoCopy());
inGainLeft = IOAudioLevelControl::createVolumeControl((InmaxLin-InminLin)/2, InminLin, InmaxLin, InminDB, InmaxDB,
kIOAudioControlChannelIDDefaultLeft,
kIOAudioControlChannelNameLeft,
kInGainLeft,
kIOAudioControlUsageInput);
if (!inGainLeft) {
return false;
}
driverDMAEngine->addDefaultAudioControl(inGainLeft);
inGainLeft->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)gainRightChangeHandler, this);
inGainRight = IOAudioLevelControl::createVolumeControl((InmaxLin-InminLin)/2, InminLin, InmaxLin, InminDB, InmaxDB,
kIOAudioControlChannelIDDefaultRight,
kIOAudioControlChannelNameRight,
kInGainRight,
kIOAudioControlUsageInput);
if (!inGainRight) {
return false;
}
driverDMAEngine->addDefaultAudioControl(inGainRight);
inGainRight->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)gainRightChangeHandler, this);
hasIMic = false;
if(AudioInputs) {
AudioHardwareInput *theInput;
for(idx = 0; idx< AudioInputs->getCount(); idx++) {
theInput = OSDynamicCast(AudioHardwareInput, AudioInputs->getObject(idx));
if(theInput)
if( 'imic' == theInput->getInputPortType()) hasIMic = true;
}
}
if(hasIMic)
inputSelector = IOAudioSelectorControl::createInputSelector('imic',
kIOAudioControlChannelIDAll,
kIOAudioControlChannelNameAll,
kInputSelector);
else
inputSelector = IOAudioSelectorControl::createInputSelector('emic',
kIOAudioControlChannelIDAll,
kIOAudioControlChannelNameAll,
kInputSelector);
if(AudioInputs) {
AudioHardwareInput *theInput;
for(idx = 0; idx< AudioInputs->getCount(); idx++) {
theInput = OSDynamicCast(AudioHardwareInput, AudioInputs->getObject(idx));
if(theInput) {
switch(theInput->getInputPortType()) {
case 'imic' :
inputSelector->addAvailableSelection('imic', "Internal microphone");
break;
case 'emic' :
inputSelector->addAvailableSelection('emic', "External microphone/Line In");
break;
case 'zvpc' :
inputSelector->addAvailableSelection('zvpc', "Zoomed Video");
break;
case 'none' :
inputSelector->addAvailableSelection('none', "No input");
break;
default:
break;
}
}
}
}
driverDMAEngine->addDefaultAudioControl(inputSelector);
inputSelector->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)inputSelectorChangeHandler, this);
playthruToggle = IOAudioToggleControl::createMuteControl(true,
kIOAudioControlChannelIDAll,
kIOAudioControlChannelNameAll,
kPassThruToggle,
kIOAudioControlUsagePassThru);
if (!playthruToggle) {
return false;
}
driverDMAEngine->addDefaultAudioControl(playthruToggle);
playthruToggle->setValueChangeHandler((IOAudioControl::IntValueChangeHandler)passThruChangeHandler, this);
attachAudioPort(outputPort, driverDMAEngine, 0);
attachAudioPort(inputPort, 0, driverDMAEngine);
inputPort->release();
outputPort->release();
EXIT:
DEBUG2_IOLOG("- AppleOnboardAudio::createDefaultsPorts, %d\n", (result == kIOReturnSuccess));
return result;
BAIL:
result = kIOReturnError;
goto EXIT;
}
#pragma mark +IOAUDIO CONTROL HANDLERS
IORegistryEntry * AppleOnboardAudio::FindEntryByNameAndProperty (const IORegistryEntry * start, const char * name, const char * key, UInt32 value) {
OSIterator *iterator;
IORegistryEntry *theEntry;
IORegistryEntry *tmpReg;
OSNumber *tmpNumber;
theEntry = NULL;
iterator = NULL;
FAIL_IF (NULL == start, Exit);
iterator = start->getChildIterator (gIOServicePlane);
FAIL_IF (NULL == iterator, Exit);
while (NULL == theEntry && (tmpReg = OSDynamicCast (IORegistryEntry, iterator->getNextObject ())) != NULL) {
if (strcmp (tmpReg->getName (), name) == 0) {
tmpNumber = OSDynamicCast (OSNumber, tmpReg->getProperty (key));
if (NULL != tmpNumber && tmpNumber->unsigned32BitValue () == value) {
theEntry = tmpReg;
theEntry->retain();
}
}
}
Exit:
if (NULL != iterator) {
iterator->release ();
}
return theEntry;
}
IOReturn AppleOnboardAudio::volumeLeftChangeHandler(IOService *target,
IOAudioControl *volumeControl, SInt32 oldValue, SInt32 newValue){
IOReturn result = kIOReturnSuccess;
AppleOnboardAudio *audioDevice;
DEBUG_IOLOG("+ AppleOnboardAudio::volumeLeftChangeHandler\n");
audioDevice = (AppleOnboardAudio *)target;
if(!audioDevice)
goto BAIL;
result = audioDevice->volumeLeftChanged(volumeControl, oldValue, newValue);
EXIT:
DEBUG2_IOLOG("- AppleOnboardAudio::volumeLeftChangeHandler, %d\n",
(result == kIOReturnSuccess));
return result;
BAIL:
result = kIOReturnError;
goto EXIT;
}
IOReturn AppleOnboardAudio::volumeLeftChanged(IOAudioControl *volumeControl,
SInt32 oldValue, SInt32 newValue){
IOReturn result = kIOReturnSuccess;
AudioHardwareOutput *theOutput;
UInt16 idx;
SInt32 newiSubVolume;
IOAudioLevelControl * iSubLeftVolume;
IORegistryEntry * start;
DEBUG_IOLOG("+ AppleOnboardAudio::volumeLeftChanged\n");
if(!AudioOutputs)
goto BAIL;
gVolLeft = newValue;
for(idx = 0; idx< AudioOutputs->getCount(); idx++) {
theOutput = OSDynamicCast(AudioHardwareOutput, AudioOutputs->getObject(idx));
if( theOutput) theOutput->setVolume(newValue, gVolRight);
}
start = childFromPath ("AppleDBDMAAudioDMAEngine", gIOServicePlane);
FAIL_IF (NULL == start, Exit);
iSubLeftVolume = (IOAudioLevelControl *)FindEntryByNameAndProperty (start, "AppleUSBAudioLevelControl", kIOAudioControlSubTypeKey, 'subL');
start->release ();
FAIL_IF (NULL == iSubLeftVolume, Exit);
newiSubVolume = (newValue * 60) / ((IOAudioLevelControl *)volumeControl)->getMaxValue ();
iSubLeftVolume->setValue (newiSubVolume);
iSubLeftVolume->release();
Exit:
if(!gExpertMode) WritePRAMVol(gVolLeft,gVolRight);
EXIT:
DEBUG2_IOLOG("- AppleOnboardAudio::volumeLeftChanged, %d\n", (result == kIOReturnSuccess));
return result;
BAIL:
result = kIOReturnError;
goto EXIT;
}
IOReturn AppleOnboardAudio::volumeRightChangeHandler(IOService *target,
IOAudioControl *volumeControl, SInt32 oldValue, SInt32 newValue){
IOReturn result = kIOReturnSuccess;
AppleOnboardAudio *audioDevice;
DEBUG_IOLOG("+ AppleOnboardAudio::volumeRightChangeHandler\n");
audioDevice = (AppleOnboardAudio *)target;
if(!audioDevice)
goto BAIL;
result = audioDevice->volumeRightChanged(volumeControl, oldValue, newValue);
EXIT:
DEBUG2_IOLOG("- AppleOnboardAudio::volumeRightChangeHandler, %d\n",
(result == kIOReturnSuccess));
return result;
BAIL:
result = kIOReturnError;
goto EXIT;
}
IOReturn AppleOnboardAudio::volumeRightChanged(IOAudioControl *volumeControl, SInt32 oldValue, SInt32 newValue){
IOReturn result = kIOReturnSuccess;
AudioHardwareOutput *theOutput;
UInt16 idx;
SInt32 newiSubVolume;
IOAudioLevelControl * iSubRightVolume;
IORegistryEntry * start;
DEBUG_IOLOG("+ AppleOnboardAudio::volumeRightChanged\n");
if(!AudioOutputs)
goto BAIL;
gVolRight = newValue;
for(idx = 0; idx< AudioOutputs->getCount(); idx++) {
theOutput = OSDynamicCast(AudioHardwareOutput, AudioOutputs->getObject(idx));
if( theOutput) theOutput->setVolume(gVolLeft, newValue);
}
start = childFromPath ("AppleDBDMAAudioDMAEngine", gIOServicePlane);
FAIL_IF (NULL == start, Exit);
iSubRightVolume = (IOAudioLevelControl *)FindEntryByNameAndProperty (start, "AppleUSBAudioLevelControl", kIOAudioControlSubTypeKey, 'subR');
start->release ();
FAIL_IF (NULL == iSubRightVolume, Exit);
newiSubVolume = (newValue * 60) / ((IOAudioLevelControl *)volumeControl)->getMaxValue ();
iSubRightVolume->setValue (newiSubVolume);
iSubRightVolume->release();
Exit:
if(!gExpertMode) WritePRAMVol(gVolLeft,gVolRight);
EXIT:
DEBUG2_IOLOG("- AppleOnboardAudio::volumeRightChanged, %d\n", (result == kIOReturnSuccess));
return result;
BAIL:
result = kIOReturnError;
goto EXIT;
}
IOReturn AppleOnboardAudio::outputMuteChangeHandler(IOService *target, IOAudioControl *muteControl, SInt32 oldValue, SInt32 newValue){
IOReturn result = kIOReturnSuccess;
AppleOnboardAudio *audioDevice;
DEBUG_IOLOG("+ AppleOnboardAudio::outputMuteChangeHandler\n");
audioDevice = (AppleOnboardAudio *)target;
if(!audioDevice)
goto BAIL;
result = audioDevice->outputMuteChanged(muteControl, oldValue, newValue);
EXIT:
DEBUG2_IOLOG("- AppleOnboardAudio::outputMuteChangeHandler, %d\n", (result == kIOReturnSuccess));
return result;
BAIL:
result = kIOReturnError;
goto EXIT;
}
IOReturn AppleOnboardAudio::outputMuteChanged(IOAudioControl *muteControl, SInt32 oldValue, SInt32 newValue){
IOReturn result = kIOReturnSuccess;
UInt32 idx;
AudioHardwareOutput * theOutput;
IOAudioToggleControl * iSubMute;
IORegistryEntry * start;
DEBUG_IOLOG("+ AppleOnboardAudio::outputMuteChanged\n");
if(!AudioOutputs)
goto BAIL;
gIsMute = newValue;
for(idx = 0; idx< AudioOutputs->getCount(); idx++) {
theOutput = OSDynamicCast(AudioHardwareOutput, AudioOutputs->getObject(idx));
if( theOutput) theOutput->setMute(newValue);
}
if(!gExpertMode) {
if (newValue)
WritePRAMVol(0,0);
else
WritePRAMVol(gVolLeft,gVolRight);
}
start = childFromPath ("AppleDBDMAAudioDMAEngine", gIOServicePlane);
FAIL_IF (NULL == start, EXIT);
iSubMute = (IOAudioToggleControl *)FindEntryByNameAndProperty (start, "AppleUSBAudioMuteControl", kIOAudioControlSubTypeKey, 'subM');
start->release ();
FAIL_IF (NULL == iSubMute, EXIT);
iSubMute->setValue (newValue);
iSubMute->release();
EXIT:
DEBUG2_IOLOG("- AppleOnboardAudio::outputMuteChanged, %d\n", (result == kIOReturnSuccess));
return result;
BAIL:
result = kIOReturnError;
goto EXIT;
}
IOReturn AppleOnboardAudio::gainLeftChangeHandler(IOService *target, IOAudioControl *gainControl, SInt32 oldValue, SInt32 newValue){
IOReturn result = kIOReturnSuccess;
AppleOnboardAudio *audioDevice;
DEBUG_IOLOG("_ AppleOnboardAudio::gainLeftChangeHandler\n");
audioDevice = (AppleOnboardAudio *)target;
if(!audioDevice)
goto BAIL;
result = audioDevice->gainLeftChanged(gainControl, oldValue, newValue);
EXIT:
DEBUG2_IOLOG("- AppleOnboardAudio::gainLeftChangeHandler, %d\n", (result == kIOReturnSuccess));
return result;
BAIL:
result = kIOReturnError;
goto EXIT;
}
IOReturn AppleOnboardAudio::gainLeftChanged(IOAudioControl *gainControl, SInt32 oldValue, SInt32 newValue){
IOReturn result = kIOReturnSuccess;
UInt32 idx;
AudioHardwareInput *theInput;
DEBUG_IOLOG("+ AppleOnboardAudio::gainLeftChanged\n");
if(!AudioInputs)
goto BAIL;
gGainLeft = newValue;
for(idx = 0; idx< AudioInputs->getCount(); idx++) {
theInput = OSDynamicCast(AudioHardwareInput, AudioInputs->getObject(idx));
if( theInput) theInput->setInputGain(newValue, gGainRight);
}
EXIT:
DEBUG2_IOLOG("- AppleOnboardAudio::gainLeftChanged, %d\n", (result == kIOReturnSuccess));
return result;
BAIL:
result = kIOReturnError;
goto EXIT;
}
IOReturn AppleOnboardAudio::gainRightChangeHandler(IOService *target, IOAudioControl *gainControl, SInt32 oldValue, SInt32 newValue){
IOReturn result = kIOReturnSuccess;
AppleOnboardAudio *audioDevice;
DEBUG_IOLOG("+ AppleOnboardAudio::gainRightChangeHandler\n");
audioDevice = (AppleOnboardAudio *)target;
if(!audioDevice)
goto BAIL;
result = audioDevice->gainRightChanged(gainControl, oldValue, newValue);
EXIT:
DEBUG_IOLOG("- AppleOnboardAudio::gainRightChangeHandler\n");
return result;
BAIL:
result = kIOReturnError;
goto EXIT;
}
IOReturn AppleOnboardAudio::gainRightChanged(IOAudioControl *gainControl, SInt32 oldValue, SInt32 newValue){
IOReturn result = kIOReturnSuccess;
UInt32 idx;
AudioHardwareInput *theInput;
DEBUG_IOLOG("+ AppleOnboardAudio::gainRightChanged\n");
if(!AudioInputs)
goto BAIL;
gGainRight = newValue;
for(idx = 0; idx< AudioInputs->getCount(); idx++) {
theInput = OSDynamicCast(AudioHardwareInput, AudioInputs->getObject(idx));
if( theInput) theInput->setInputGain(gGainLeft, newValue);
}
EXIT:
DEBUG2_IOLOG("- AppleOnboardAudio::gainRightChanged, %d\n", (result == kIOReturnSuccess));
return result;
BAIL:
result = kIOReturnError;
goto EXIT;
}
IOReturn AppleOnboardAudio::passThruChangeHandler(IOService *target, IOAudioControl *passThruControl, SInt32 oldValue, SInt32 newValue){
IOReturn result = kIOReturnSuccess;
AppleOnboardAudio *audioDevice;
DEBUG_IOLOG("+ AppleOnboardAudio::passThruChangeHandler\n");
audioDevice = (AppleOnboardAudio *)target;
if(!audioDevice) goto BAIL;
result = audioDevice->passThruChanged(passThruControl, oldValue, newValue);
EXIT:
DEBUG_IOLOG("- AppleOnboardAudio::passThruChangeHandler\n");
return result;
BAIL:
result = kIOReturnError;
goto EXIT;
}
IOReturn AppleOnboardAudio::passThruChanged(IOAudioControl *passThruControl, SInt32 oldValue, SInt32 newValue){
IOReturn result = kIOReturnSuccess;
DEBUG_IOLOG("+ AppleOnboardAudio::passThruChanged\n");
gIsPlayThroughActive = newValue;
sndHWSetPlayThrough(!newValue);
DEBUG_IOLOG("- AppleOnboardAudio::passThruChanged\n");
return result;
}
IOReturn AppleOnboardAudio::inputSelectorChangeHandler(IOService *target, IOAudioControl *inputSelector, SInt32 oldValue, SInt32 newValue){
IOReturn result = kIOReturnSuccess;
AppleOnboardAudio *audioDevice;
DEBUG_IOLOG("+ AppleOnboardAudio::inputSelectorChangeHandler\n");
audioDevice = (AppleOnboardAudio *)target;
if(!audioDevice) goto BAIL;
result = audioDevice->inputSelectorChanged(inputSelector, oldValue, newValue);
EXIT:
DEBUG_IOLOG("- AppleOnboardAudio::inputSelectorChangeHandler\n");
return result;
BAIL:
result = kIOReturnError;
goto EXIT;
}
IOReturn AppleOnboardAudio::inputSelectorChanged(IOAudioControl *inputSelector, SInt32 oldValue, SInt32 newValue){
AudioHardwareInput *theInput;
UInt32 idx;
IOReturn result = kIOReturnSuccess;
DEBUG_IOLOG("+ AppleOnboardAudio::inputSelectorChanged\n");
if(AudioInputs) {
for(idx = 0; idx< AudioInputs->getCount(); idx++) {
theInput = OSDynamicCast(AudioHardwareInput, AudioInputs->getObject(idx));
if( theInput) theInput->forceActivation(newValue);
}
}
DEBUG_IOLOG("- AppleOnboardAudio::inputSelectorChanged\n");
return result;
}
#pragma mark +POWER MANAGEMENT
IOReturn AppleOnboardAudio::configurePowerObject(IOService *provider){
IOReturn result = kIOReturnSuccess;
DEBUG_IOLOG("+ AppleOnboardAudio::configurePowerObject\n");
switch (theAudioDeviceTreeParser->getPowerObjectType()) {
case kProj6PowerObject:
theAudioPowerObject = AudioProj6PowerObject::createAudioProj6PowerObject(this);
if(!theAudioPowerObject) goto BAIL;
break;
case kProj7PowerObject:
theAudioPowerObject = AudioProj7PowerObject::createAudioProj7PowerObject(this);
if(!theAudioPowerObject) goto BAIL;
break;
case kProj8PowerObject:
theAudioPowerObject = AudioProj8PowerObject::createAudioProj8PowerObject(this);
if(!theAudioPowerObject) goto BAIL;
break;
case kProj10PowerObject:
theAudioPowerObject = AudioProj10PowerObject::createAudioProj10PowerObject(this);
if(!theAudioPowerObject) goto BAIL;
break;
case kProj14PowerObject:
theAudioPowerObject = AudioProj14PowerObject::createAudioProj14PowerObject(this);
if(!theAudioPowerObject) goto BAIL;
break;
case kProj16PowerObject:
theAudioPowerObject = AudioProj16PowerObject::createAudioProj16PowerObject(this);
if(!theAudioPowerObject) goto BAIL;
break;
case kBasePowerObject:
default: theAudioPowerObject = AudioPowerObject::createAudioPowerObject(this);
if(!theAudioPowerObject) goto BAIL;
break;
}
EXIT:
DEBUG2_IOLOG("- AppleOnboardAudio::configurePowerObject result = %d\n", (result == kIOReturnSuccess));
return(result);
BAIL:
result = kIOReturnError;
goto EXIT;
}
IOReturn AppleOnboardAudio::performPowerStateChange(IOAudioDevicePowerState oldPowerState,
IOAudioDevicePowerState newPowerState,
UInt32 *microsecondsUntilComplete)
{
IOReturn result = kIOReturnSuccess;
DEBUG_IOLOG("+ AppleOnboardAudio::performPowerStateChange\n");
result = super::performPowerStateChange(oldPowerState, newPowerState, microsecondsUntilComplete);
if (result != kIOReturnSuccess) goto BAIL;
if (newPowerState == kIOAudioDeviceSleep) {
result = theAudioPowerObject->setHardwarePowerOff();
} else if (oldPowerState == kIOAudioDeviceSleep) {
result = theAudioPowerObject->setHardwarePowerOn();
}
EXIT:
DEBUG2_IOLOG("- AppleOnboardAudio::performPowerStateChange, result = %d\n", (result == kIOReturnSuccess));
return result;
BAIL:
goto EXIT;
}
#pragma mark +MODEM SOUND
IOReturn AppleOnboardAudio::setModemSound(bool state){
IOReturn result = kIOReturnSuccess;
AudioHardwareInput *theInput;
UInt32 idx;
DEBUG_IOLOG("+ AppleOnboardAudio::setModemSound\n");
theInput = NULL;
if(gIsModemSoundActive == state)
goto EXIT;
if(state) {
if(AudioInputs) {
for(idx = 0; idx< AudioInputs->getCount(); idx++) {
theInput = OSDynamicCast(AudioHardwareInput, AudioInputs->getObject(idx));
if (NULL != theInput) {
theInput->forceActivation('modm');
theInput->setInputGain(0,0);
}
}
}
sndHWSetPlayThrough(true);
} else {
sndHWSetPlayThrough(!gIsPlayThroughActive);
if(AudioInputs) {
for(idx = 0; idx< AudioInputs->getCount(); idx++) {
theInput = OSDynamicCast(AudioHardwareInput, AudioInputs->getObject(idx));
if (NULL != theInput){
theInput->forceActivation(inputSelector->getIntValue());
theInput->setInputGain(gGainLeft, gGainRight);
}
}
}
}
gIsModemSoundActive = state;
EXIT:
DEBUG_IOLOG("- AppleOnboardAudio::setModemSound\n");
return result;
}
IOReturn AppleOnboardAudio::callPlatformFunction( const OSSymbol * functionName, bool
waitForFunction,void *param1, void *param2, void *param3, void *param4 ){
DEBUG_IOLOG("+ AppleOnboardAudio::callPlatformFunction\n");
if(functionName->isEqualTo("setModemSound")) {
return(setModemSound((bool)param1));
}
DEBUG_IOLOG("- AppleOnboardAudio::callPlatformFunction\n");
return(super::callPlatformFunction(functionName,
waitForFunction,param1, param2, param3, param4));
}
#pragma mark +PRAM VOLUME
UInt8 AppleOnboardAudio::VolumeToPRAMValue( UInt32 leftVol, UInt32 rightVol )
{
UInt32 pramVolume; UInt32 averageVolume; const UInt32 volumeRange = (fMaxVolume - fMinVolume+1);
UInt32 volumeSteps;
averageVolume = (leftVol + rightVol) >> 1; volumeSteps = volumeRange / kMaximumPRAMVolume; pramVolume = averageVolume / volumeSteps;
if ((pramVolume == 0) && (leftVol != 0 || rightVol !=0 ))
pramVolume = 1;
return (pramVolume & 0x07);
}
void AppleOnboardAudio::WritePRAMVol( UInt32 leftVol, UInt32 rightVol )
{
UInt8 pramVolume;
UInt8 curPRAMVol;
IODTPlatformExpert * platform = NULL;
platform = OSDynamicCast(IODTPlatformExpert,getPlatform());
debug3IOLog("AppleOnboardAudio::WritePRAMVol leftVol=%lu, rightVol=%lu\n",leftVol, rightVol);
if (platform)
{
pramVolume = VolumeToPRAMValue(leftVol,rightVol);
platform->readXPRAM((IOByteCount)kPRamVolumeAddr,&curPRAMVol, (IOByteCount)1);
if (pramVolume != (curPRAMVol & 0x07))
{
curPRAMVol = (curPRAMVol & 0xF8) | pramVolume;
debug2IOLog("AppleOnboardAudio::WritePRAMVol curPRAMVol=0x%x\n",curPRAMVol);
platform->writeXPRAM((IOByteCount)kPRamVolumeAddr, &curPRAMVol,(IOByteCount) 1);
}
}
}