AppleHWControl.cpp [plain text]
#include <sys/cdefs.h>
#include <IOKit/IODeviceTreeSupport.h>
#include "AppleHWControl.h"
static const OSSymbol *sControlID;
static const OSSymbol *sCurrentValue;
static const OSSymbol *sGetCurrentValue;
static const OSSymbol *sTargetValue;
static const OSSymbol *sGetTargetValue;
static const OSSymbol *sSetTargetValue;
static const OSSymbol *sForceUpdate;
static const OSSymbol *sMinValue;
static const OSSymbol *sMaxValue;
static const OSSymbol *sSafeValue;
OSDefineMetaClassAndStructors(IOHWControl,IOHWMonitor)
bool IOHWControl::start(IOService *provider)
{
OSDictionary *dict;
IOReturn ret;
if ( !(IOHWMonitor::start(provider)) )
return false;
DLOG("IOHWControl::start(%s) - entered\n", fDebugID);
if(!sControlID)
sControlID = OSSymbol::withCString("control-id");
if(!sCurrentValue)
sCurrentValue = OSSymbol::withCString("current-value");
if(!sGetCurrentValue)
sGetCurrentValue = OSSymbol::withCString("getCurrentValue");
if(!sTargetValue)
sTargetValue = OSSymbol::withCString("target-value");
if(!sGetTargetValue)
sGetTargetValue = OSSymbol::withCString("getTargetValue");
if(!sSetTargetValue)
sSetTargetValue = OSSymbol::withCString("setTargetValue");
if(!sForceUpdate)
sForceUpdate = OSSymbol::withCString("force-update");
if(!sMinValue)
sMinValue = OSSymbol::withCString("min-value");
if(!sMaxValue)
sMaxValue = OSSymbol::withCString("max-value");
if(!sSafeValue)
sSafeValue = OSSymbol::withCString("safe-value");
DLOG("IOHWControl::start(%s) - parsing Control nub properties\n", fDebugID);
bool parseSuccess = FALSE;
OSNumber *num;
OSData *data;
do {
data = OSDynamicCast(OSData, provider->getProperty(sControlID));
if (!data)
#if defined( __ppc__ )
{
IOLog("IOHWControl - no Control ID !!\n");
break;
}
fID = *(UInt32 *)data->getBytesNoCopy();
#else
{
if (num = OSDynamicCast (OSNumber, provider->getProperty(sControlID)))
fID = num->unsigned32BitValue();
else {
IOLog("IOHWControl - no Control ID !!\n");
break;
}
} else {
fID = OSReadBigInt32(data->getBytesNoCopy(), 0);
}
#endif
num = OSNumber::withNumber(fID, 32);
if (!num)
{
IOLog("IOHWControl - can't set Control ID !!\n");
break;
}
setProperty(sControlID, num);
num->release();
if ( ( data = OSDynamicCast(OSData, provider->getProperty( sMinValue ) ) ) != NULL )
{
UInt32 minValue;
minValue = *( UInt32 * ) data->getBytesNoCopy();
if ( ( num = OSNumber::withNumber( minValue, 32 ) ) == NULL )
break;
setProperty( sMinValue, num );
num->release();
}
#if !defined( __ppc__ )
else {
if ( ( num = OSDynamicCast(OSNumber, provider->getProperty( sMinValue ) ) ) != NULL )
{
UInt32 minValue;
minValue = num->unsigned32BitValue();
if ( ( num = OSNumber::withNumber( minValue, 32 ) ) == NULL )
break;
setProperty( sMinValue, num );
num->release();
}
}
#endif
if ( ( data = OSDynamicCast(OSData, provider->getProperty( sMaxValue ) ) ) != NULL )
{
UInt32 maxValue;
maxValue = *( UInt32 * ) data->getBytesNoCopy();
if ( ( num = OSNumber::withNumber( maxValue, 32 ) ) == NULL )
break;
setProperty( sMaxValue, num );
num->release();
}
#if !defined( __ppc__ )
else
{
if ( ( num = OSDynamicCast(OSNumber, provider->getProperty( sMaxValue ) ) ) != NULL )
{
UInt32 maxValue;
maxValue = num->unsigned32BitValue();
if ( ( num = OSNumber::withNumber( maxValue, 32 ) ) == NULL )
break;
setProperty( sMaxValue, num );
num->release();
}
}
#endif
if ( ( data = OSDynamicCast(OSData, provider->getProperty( sSafeValue ) ) ) != NULL )
{
UInt32 safeValue;
safeValue = *( UInt32 * ) data->getBytesNoCopy();
if ( ( num = OSNumber::withNumber( safeValue, 32 ) ) == NULL )
break;
setProperty( sSafeValue, num );
num->release();
}
#if !defined( __ppc__ )
else
{
if ( ( num = OSDynamicCast(OSNumber, provider->getProperty( sSafeValue ) ) ) != NULL )
{
UInt32 safeValue;
safeValue = num->unsigned32BitValue();
if ( ( num = OSNumber::withNumber( safeValue, 32 ) ) == NULL )
break;
setProperty( sSafeValue, num );
num->release();
}
}
#endif
num = (OSNumber *)getProperty("version");
if (num->unsigned32BitValue() == 1)
{
fChannel = fID;
}
else if (num->unsigned32BitValue() == 2)
{
data = OSDynamicCast(OSData, provider->getProperty("reg"));
if (!data)
#if defined( __ppc__ )
{
IOLog("IOHWControl - version 2 but no reg property !!\n");
break;
}
fChannel = *(UInt32 *)data->getBytesNoCopy();
#else
{
if (num = OSDynamicCast (OSNumber, provider->getProperty("reg")))
fChannel = num->unsigned32BitValue();
else {
IOLog("IOHWControl - version 2 but no reg property !!\n");
break;
}
} else {
fChannel = OSReadBigInt32(data->getBytesNoCopy(), 0);
}
#endif
}
else {
IOLog("IOHWControl - unrecognized version %d !!\n", num->unsigned32BitValue());
break;
}
parseSuccess = TRUE;
} while (0);
if (parseSuccess == FALSE)
{
return(false);
}
DLOG("IOHWControl::start(%s) - polling initial current value\n", fDebugID);
ret = updateCurrentValue();
if(ret != kIOReturnSuccess)
{
IOLog("IOHWControl::start failed to read initial current value: 0x%x!\n", ret);
return(false);
}
ret = updateTargetValue();
if(ret != kIOReturnSuccess)
{
IOLog("IOHWControl::start failed to read initial target value!\n");
return(false);
}
DLOG("IOHWControl::start(%s) - messaging pmon\n", fDebugID);
dict = OSDictionary::withDictionary(getPropertyTable());
if(fIOPMon)
messageClient(kRegisterControl, fIOPMon, dict);
dict->release();
registerService();
DLOG("IOHWControl::start(%s) - done\n", fDebugID);
return true;
}
IOReturn IOHWControl::setProperties( OSObject * properties )
{
OSDictionary * dict = OSDynamicCast(OSDictionary, properties);
OSNumber *num;
if(!dict)
return kIOReturnBadArgument;
if (sleeping)
return(kIOReturnOffline);
if(dict->getObject(sCurrentValue) || dict->getObject(sForceUpdate))
updateCurrentValue();
num = OSDynamicCast(OSNumber, dict->getObject(sTargetValue));
if(num)
setTargetValue(num);
return kIOReturnSuccess;
}
IOReturn IOHWControl::updateCurrentValue()
{
return updateValue(sGetCurrentValue, sCurrentValue);
}
IOReturn IOHWControl::updateTargetValue()
{
return updateValue(sGetTargetValue, sTargetValue);
}
IOReturn IOHWControl::setTargetValue(OSNumber *val)
{
IOReturn ret;
#if !defined( __ppc__ )
lastValue = val->unsigned32BitValue();
#endif
if (sleeping || systemIsRestarting)
return kIOReturnOffline;
busy = true;
ret = callPlatformFunction(sSetTargetValue, FALSE,
(void *)fChannel, (void *)val->unsigned32BitValue(), NULL, NULL);
busy = false;
if (sleeping && powerPolicyMaker)
powerPolicyMaker->acknowledgeSetPowerState ();
if(ret == kIOReturnSuccess)
setNumber(sTargetValue, val->unsigned32BitValue());
return ret;
}
#if !defined( __ppc__ )
IOReturn IOHWControl::setPowerState(unsigned long whatState, IOService *policyMaker)
{
IOReturn ret;
bool goingToSleep;
ret = IOHWMonitor::setPowerState (whatState, policyMaker);
goingToSleep = (whatState == kIOHWMonitorOffState);
if ((ret == IOPMAckImplied) && !goingToSleep) {
OSNumber *lastNum;
lastNum = OSNumber::withNumber (lastValue, 32);
if (lastNum) {
DLOG ("IOHWControl::setPowerState - resending target value 0x%x on wake\n", lastNum->unsigned32BitValue());
setTargetValue (lastNum);
}
}
return ret;
}
#endif