IOBacklightDisplay.cpp [plain text]
#include <IOKit/IOLib.h>
#include <IOKit/graphics/IODisplay.h>
#include <IOKit/ndrvsupport/IOMacOSVideo.h>
#include <IOKit/pwr_mgt/RootDomain.h>
#define super IODisplay
OSDefineMetaClassAndStructors(IOBacklightDisplay, IODisplay)
enum {
kIOBacklightDisplayMaxUsableState = kIODisplayMaxPowerState - 1
};
IOService * IOBacklightDisplay::probe( IOService * provider, SInt32 * score )
{
IOFramebuffer * framebuffer;
IOService * ret = 0;
UInt32 displayType;
UInt32 connectFlags;
bool haveBacklight = false;
do {
if( !super::probe( provider, score ))
continue;
framebuffer = (IOFramebuffer *) getConnection()->getFramebuffer();
for( IOItemCount idx = 0; idx < framebuffer->getConnectionCount(); idx++) {
if( kIOReturnSuccess != framebuffer->getAttributeForConnection( idx,
kConnectionFlags, &connectFlags))
continue;
if( 0 == (kIOConnectionBuiltIn & connectFlags))
continue;
if( kIOReturnSuccess != framebuffer->getAppleSense( idx, NULL, NULL, NULL, &displayType))
continue;
if( (kPanelTFTConnect != displayType)
&& (kGenericLCD != displayType)
&& (kPanelFSTNConnect != displayType))
continue;
OSIterator * iter = getMatchingServices( nameMatching("backlight") );
if( iter) {
haveBacklight = (0 != iter->getNextObject());
iter->release();
}
if( !haveBacklight)
continue;
ret = this; break;
}
} while( false );
return( ret );
}
void IOBacklightDisplay::stop( IOService * provider )
{
getPMRootDomain()->receivePowerNotification( kIOPMDisableClamshell );
return( super::stop( provider ));
}
void IOBacklightDisplay::initPowerManagement( IOService * provider )
{
static const IOPMPowerState ourPowerStates[kIODisplayNumPowerStates] = {
{ 1, 0, 0, 0, 0,0,0,0,0,0,0,0 },
{ 1, 0, 0, IOPMPowerOn, 0,0,0,0,0,0,0,0 },
{ 1, IOPMDeviceUsable, 0, IOPMPowerOn, 0,0,0,0,0,0,0,0 },
{ 1, IOPMDeviceUsable | IOPMMaxPerformance, 0, IOPMPowerOn, 0,0,0,0,0,0,0,0 }
};
if( !fDisplayParams
|| !getIntegerRange( fDisplayParams, gIODisplayBrightnessKey,
&fCurrentBrightness, &fMinBrightness, &fMaxBrightness )) {
fMinBrightness = 0;
fMaxBrightness = 255;
fCurrentBrightness = fMaxBrightness;
}
fCurrentUserBrightness = fCurrentBrightness;
fMaxBrightnessLevel[0] = 0;
fMaxBrightnessLevel[1] = fMinBrightness;
fMaxBrightnessLevel[2] = fMinBrightness + 1;
fMaxBrightnessLevel[3] = fMaxBrightness;
fDisplayPMVars->currentState = kIODisplayMaxPowerState;
PMinit();
provider->joinPMtree(this);
registerPowerDriver(this, (IOPMPowerState *) ourPowerStates, kIODisplayNumPowerStates);
getPMRootDomain()->receivePowerNotification( kIOPMEnableClamshell );
}
IOReturn IOBacklightDisplay::setPowerState( unsigned long powerState, IOService * whatDevice )
{
IOReturn ret = IOPMAckImplied;
SInt32 value;
if( powerState >= kIODisplayNumPowerStates)
return( IOPMAckImplied );
fCurrentPowerState = powerState;
value = fMaxBrightnessLevel[fCurrentPowerState];
if( value > fCurrentUserBrightness)
value = fCurrentUserBrightness;
setBrightness( value );
powerState |= (powerState >= kIOBacklightDisplayMaxUsableState) ? kFBDisplayUsablePowerState : 0;
if( fConnection)
fConnection->setAttributeForConnection( kConnectionPower, powerState );
return( ret );
}
bool IOBacklightDisplay::doIntegerSet( OSDictionary * params,
const OSSymbol * paramName, UInt32 value )
{
if( paramName != gIODisplayBrightnessKey)
return( super::doIntegerSet( params, paramName, value));
else {
fCurrentUserBrightness = value;
return( setBrightness( value ));
}
}
bool IOBacklightDisplay::setBrightness( SInt32 value )
{
UInt32 newState;
bool ret = true;
if( !fDisplayParams)
return( false );
for( newState = 0; newState < kIODisplayNumPowerStates; newState++ ) {
if( value <= fMaxBrightnessLevel[newState] )
break;
}
if( newState >= kIODisplayNumPowerStates)
return( false );
if( newState != fCurrentPowerState) {
if( IOPMNoErr != changePowerStateToPriv( newState ))
value = fCurrentBrightness;
}
if( value != fCurrentBrightness) {
fCurrentBrightness = value;
ret = super::doIntegerSet( fDisplayParams, gIODisplayBrightnessKey, value);
}
return( ret );
}
unsigned long IOBacklightDisplay::maxCapabilityForDomainState( IOPMPowerFlags domainState )
{
if( domainState & IOPMPowerOn )
return( kIODisplayMaxPowerState );
else
return( 0 );
}
unsigned long IOBacklightDisplay::initialPowerStateForDomainState( IOPMPowerFlags domainState )
{
UInt32 newState;
if( domainState & IOPMPowerOn ) {
for( newState = 0; newState < kIODisplayNumPowerStates; newState++ ) {
if( fCurrentBrightness <= fMaxBrightnessLevel[newState] )
return( newState );
}
}
return( 0 );
}
unsigned long IOBacklightDisplay::powerStateForDomainState( IOPMPowerFlags domainState )
{
UInt32 newState;
if( domainState & IOPMPowerOn ) {
for( newState = 0; newState < kIODisplayNumPowerStates; newState++ ) {
if( fCurrentBrightness <= fMaxBrightnessLevel[newState] )
return( newState );
}
}
return( 0 );
}
class AppleBacklightDisplay : public IOBacklightDisplay
{
OSDeclareDefaultStructors(AppleBacklightDisplay)
};
#undef super
#define super IODisplay
OSDefineMetaClassAndStructors(AppleBacklightDisplay, IOBacklightDisplay)
OSMetaClassDefineReservedUnused(IOBacklightDisplay, 0);
OSMetaClassDefineReservedUnused(IOBacklightDisplay, 1);
OSMetaClassDefineReservedUnused(IOBacklightDisplay, 2);
OSMetaClassDefineReservedUnused(IOBacklightDisplay, 3);
OSMetaClassDefineReservedUnused(IOBacklightDisplay, 4);
OSMetaClassDefineReservedUnused(IOBacklightDisplay, 5);
OSMetaClassDefineReservedUnused(IOBacklightDisplay, 6);
OSMetaClassDefineReservedUnused(IOBacklightDisplay, 7);
OSMetaClassDefineReservedUnused(IOBacklightDisplay, 8);
OSMetaClassDefineReservedUnused(IOBacklightDisplay, 9);