IOPlatformStateSensor.cpp [plain text]
#include "IOPlatformPluginDefs.h"
#include "IOPlatformPluginSymbols.h"
#include "IOPlatformCtrlLoop.h"
#include "IOPlatformStateSensor.h"
#define super IOPlatformSensor
OSDefineMetaClassAndStructors(IOPlatformStateSensor, IOPlatformSensor)
bool IOPlatformStateSensor::init( void )
{
if (!super::init()) return(false);
return true;
}
void IOPlatformStateSensor::free( void )
{
super::free();
}
SensorValue IOPlatformStateSensor::applyCurrentValueInverseTransform( SensorValue pluginReading ) const
{
return pluginReading;
}
IOReturn IOPlatformStateSensor::initPlatformSensor( const OSDictionary *dict )
{
IOReturn status;
OSArray * array;
if ((status = super::initPlatformSensor(dict)) != kIOReturnSuccess)
return status;
if ((array = OSDynamicCast(OSArray, dict->getObject(kIOPPluginThermalThresholdsKey))) != NULL)
{
infoDict->setObject(kIOPPluginThermalThresholdsKey, array);
}
else
{
SENSOR_DLOG("IOPlatformStateSensor::initPlatformSensor no thresholds found\n");
}
setSensorState( gIOPPluginZero );
return(status);
}
IOReturn IOPlatformStateSensor::registerDriver( IOService * driver, const OSDictionary * dict, bool notify )
{
IOReturn status;
const OSDictionary * thisState;
const OSNumber * tmpHigh, * tmpLow, *tmpNumber;
UInt32 tryState, nStates;
SensorValue curValue, highThreshold, lowThreshold;
SENSOR_DLOG("IOPlatformStateSensor::registerDriver ID 0x%08lX\n", getSensorID()->unsigned32BitValue());
if ((status = super::registerDriver(driver, dict, false)) != kIOReturnSuccess)
return (status);
curValue = getCurrentValue();
if ((nStates = getNumSensorStates()) == 0xFFFFFFFF)
{
SENSOR_DLOG("IOPlatformStateSensor::registerDriver bad threshold dictionary sensor id %08lX\n",
getSensorID()->unsigned32BitValue());
return(kIOReturnError);
}
status = kIOReturnError; tryState = 0;
while ( tryState < nStates )
{
if ((thisState = getThresholdsForState( tryState )) == NULL ||
(tmpHigh = getHighThresholdForState( thisState )) == NULL ||
(tmpLow = getLowThresholdForState( thisState )) == NULL)
{
SENSOR_DLOG("IOPlatformStateSensor::registerDriver bad threshold dictionary sensor id %08lX!\n",
getSensorID()->unsigned32BitValue());
return(kIOReturnError);
}
highThreshold.sensValue = (SInt32)tmpHigh->unsigned32BitValue();
lowThreshold.sensValue = (SInt32)tmpLow->unsigned32BitValue();
if (curValue.sensValue >= lowThreshold.sensValue && curValue.sensValue < highThreshold.sensValue)
{
tmpNumber = OSNumber::withNumber( tryState, 32 );
setSensorState( tmpNumber );
tmpNumber->release();
status = kIOReturnSuccess;
break;
}
tryState++;
}
if (status == kIOReturnSuccess &&
(status = sendThresholdsToSensor()) == kIOReturnSuccess)
{
if (notify) notifyCtrlLoops();
}
return(status);
}
UInt32 IOPlatformStateSensor::getNumSensorStates( void )
{
const OSArray * thresholds;
if ((thresholds = OSDynamicCast(OSArray, infoDict->getObject(kIOPPluginThermalThresholdsKey))) != NULL)
{
return (UInt32)thresholds->getCount();
}
else
{
return(0xFFFFFFFF);
}
}
const OSNumber *IOPlatformStateSensor::getSensorState( void )
{
return OSDynamicCast(OSNumber, infoDict->getObject(gIOPPluginCurrentStateKey));
}
UInt32 IOPlatformStateSensor::getSensorStateUInt32( void )
{
const OSNumber * state;
if ((state = getSensorState()) != NULL)
{
return state->unsigned32BitValue();
}
else
{
return(0xFFFFFFFF);
}
}
void IOPlatformStateSensor::setSensorState( const OSNumber * state )
{
if (state)
infoDict->setObject(gIOPPluginCurrentStateKey, state);
}
const OSNumber *IOPlatformStateSensor::getHighThresholdForState( const OSDictionary * state )
{
if (!state) return(NULL);
return OSDynamicCast(OSNumber, state->getObject(gIOPPluginHighThresholdKey));
}
const OSNumber *IOPlatformStateSensor::getLowThresholdForState( const OSDictionary * state )
{
if (!state) return(NULL);
return OSDynamicCast(OSNumber, state->getObject(gIOPPluginLowThresholdKey));
}
const OSDictionary *IOPlatformStateSensor::getThresholdsForState( UInt32 state )
{
const OSArray * thresholdArray;
const OSDictionary * thisState;
if ((thresholdArray = OSDynamicCast(OSArray, infoDict->getObject(kIOPPluginThermalThresholdsKey))) == NULL)
{
SENSOR_DLOG("IOPlatformStateSensor::getThresholdsForState - no threshold dictionary!\n");
return(NULL);
}
if ((thisState = OSDynamicCast(OSDictionary, thresholdArray->getObject( state ))) == NULL)
{
SENSOR_DLOG("IOPlatformStateSensor::getThresholdsForState - no thresholds for current state!\n");
}
return thisState;
}
IOReturn IOPlatformStateSensor::thresholdHit( bool low, OSDictionary * msgDict )
{
const OSNumber * newState;
UInt32 oldState;
int i, count;
IOPlatformCtrlLoop * loop;
SENSOR_DLOG("IOPlatformStateSensor::thresholdHit ID 0x%08lX\n", getSensorID()->unsigned32BitValue());
oldState = getSensorStateUInt32();
if (low)
{
if (oldState != 0)
{
newState = OSNumber::withNumber( oldState - 1, 32 );
setSensorState( newState );
newState->release();
}
}
else {
if ( (oldState + 1) < getNumSensorStates() )
{
newState = OSNumber::withNumber( oldState + 1, 32 );
setSensorState( newState );
newState->release();
}
}
if (sendThresholdsToSensor() != kIOReturnSuccess)
{
SENSOR_DLOG("IOPlatformStateSensor::thresholdHit failed to send thresholds\n");
}
if (ctrlLoops)
{
count = ctrlLoops->getCount();
for (i=0; i<count; i++)
{
if ((loop = OSDynamicCast(IOPlatformCtrlLoop, ctrlLoops->getObject(i))) != NULL)
{
loop->adjustControls();
}
}
}
return(kIOReturnSuccess);
}
IOReturn IOPlatformStateSensor::sendThresholdsToSensor( void )
{
IOReturn status;
const OSDictionary * thisState;
OSDictionary * cmdDict;
const OSNumber * high, * low;
SensorValue reading;
if ((thisState = getThresholdsForState( getSensorStateUInt32() )) == NULL)
{
SENSOR_DLOG("IOPlatformStateSensor::sendThresoldsToSensor - no thresholds for current state!\n");
return(kIOReturnError);
}
low = OSDynamicCast(OSNumber, thisState->getObject(gIOPPluginLowThresholdKey));
reading.sensValue = (SInt32)low->unsigned32BitValue();
reading = applyCurrentValueInverseTransform( reading );
low = OSNumber::withNumber( (UInt32)reading.sensValue, 32 );
high = OSDynamicCast(OSNumber, thisState->getObject(gIOPPluginHighThresholdKey));
reading.sensValue = (SInt32)high->unsigned32BitValue();
reading = applyCurrentValueInverseTransform( reading );
high = OSNumber::withNumber( (UInt32)reading.sensValue, 32 );
cmdDict = OSDictionary::withCapacity(3);
cmdDict->setObject(gIOPPluginSensorIDKey, getSensorID());
cmdDict->setObject(gIOPPluginLowThresholdKey, low);
cmdDict->setObject(gIOPPluginHighThresholdKey, high);
status = sendMessage( cmdDict );
low->release();
high->release();
cmdDict->release();
return(status);
}