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)
{
IOLog("IOHWControl - no Control ID !!\n");
break;
}
fID = *(UInt32 *)data->getBytesNoCopy();
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 ( ( 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 ( ( 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();
}
num = (OSNumber *)getProperty("version");
if (num->unsigned32BitValue() == 1)
{
fChannel = fID;
}
else if (num->unsigned32BitValue() == 2)
{
data = OSDynamicCast(OSData, provider->getProperty("reg"));
if (!data) break;
fChannel = *(UInt32 *)data->getBytesNoCopy();
}
else
{
IOLog("IOHWControl - version 2 but no reg property !!\n");
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("AppleHWControl::start failed to read initial current value: 0x%x!\n", ret);
return(false);
}
ret = updateTargetValue();
if(ret != kIOReturnSuccess)
{
IOLog("AppleHWControl::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 (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;
}