1/* 2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 1.1 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22 23#include <IOKit/IOLib.h> 24#include <IOKit/IOUserClient.h> 25#include <IOKit/IOTimerEventSource.h> 26 27#define IOFRAMEBUFFER_PRIVATE 28#include <IOKit/IOHibernatePrivate.h> 29#include <IOKit/graphics/IOGraphicsPrivate.h> 30#include <IOKit/graphics/IODisplay.h> 31#include <IOKit/ndrvsupport/IOMacOSVideo.h> 32#include <IOKit/pwr_mgt/RootDomain.h> 33#include <IOKit/pwr_mgt/IOPM.h> 34 35/* 36 We further divide the actual display panel brightness levels into four 37 IOKit power states which we export to our superclass. 38 39 In the lowest state, the display is off. This state consists of only one 40 of the brightness levels, the lowest. In the next state it is in the dimmest 41 usable state. The highest state consists of all the brightness levels. 42 43 The display has no state or configuration or programming that would be 44 saved/restored over power state changes, and the driver does not register 45 with the superclass as an interested driver. 46 47 This driver doesn't have much to do. It changes between the four power state 48 brightnesses on command from the superclass, and it notices which brightness 49 level the user has set. 50 51 The only smart thing it does is keep track of which of the brightness levels 52 the user has selected, and it never exceeds that on command from the display 53 device object. 54*/ 55 56/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 57 58#define super IODisplay 59 60OSDefineMetaClassAndStructors(IOBacklightDisplay, IODisplay) 61 62/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 63 64OSMetaClassDefineReservedUnused(IOBacklightDisplay, 0); 65OSMetaClassDefineReservedUnused(IOBacklightDisplay, 1); 66OSMetaClassDefineReservedUnused(IOBacklightDisplay, 2); 67OSMetaClassDefineReservedUnused(IOBacklightDisplay, 3); 68OSMetaClassDefineReservedUnused(IOBacklightDisplay, 4); 69OSMetaClassDefineReservedUnused(IOBacklightDisplay, 5); 70OSMetaClassDefineReservedUnused(IOBacklightDisplay, 6); 71OSMetaClassDefineReservedUnused(IOBacklightDisplay, 7); 72OSMetaClassDefineReservedUnused(IOBacklightDisplay, 8); 73OSMetaClassDefineReservedUnused(IOBacklightDisplay, 9); 74 75/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 76 77class AppleBacklightDisplay : public IOBacklightDisplay 78{ 79 OSDeclareDefaultStructors(AppleBacklightDisplay) 80 81protected: 82 // User preferred brightness level 83// SInt32 fCurrentUserBrightness; 84 UInt32 fCurrentPowerState; 85 SInt32 fMinBrightness; 86 SInt32 fMaxBrightness; 87 88 IOInterruptEventSource * fDeferredEvents; 89 90 IOTimerEventSource * fFadeTimer; 91 AbsoluteTime fFadeDeadline; 92 AbsoluteTime fFadeInterval; 93 uint32_t fFadeState; 94 uint32_t fFadeStateEnd; 95 uint32_t fFadeStateFadeMin; 96 uint32_t fFadeStateFadeDelta; 97 uint8_t fClamshellSlept; 98 uint8_t fDisplayDims; 99 uint8_t fProviderPower; 100 uint8_t fFadeBacklight; 101 uint8_t fFadeGamma; 102 uint8_t fFadeDown; 103 uint8_t fFadeAbort; 104 105public: 106 107 // IOService overrides 108 virtual IOService * probe( IOService *, SInt32 * ); 109 virtual bool start( IOService * provider ); 110 virtual void stop( IOService * provider ); 111 112 virtual IOReturn setPowerState( unsigned long, IOService * ); 113 virtual unsigned long maxCapabilityForDomainState( IOPMPowerFlags ); 114 virtual unsigned long initialPowerStateForDomainState( IOPMPowerFlags ); 115 virtual unsigned long powerStateForDomainState( IOPMPowerFlags ); 116 117 // IODisplay overrides 118 virtual void initPowerManagement( IOService * ); 119 virtual bool doIntegerSet( OSDictionary * params, 120 const OSSymbol * paramName, UInt32 value ); 121 virtual bool doUpdate( void ); 122 virtual void makeDisplayUsable( void ); 123 virtual IOReturn framebufferEvent( IOFramebuffer * framebuffer, 124 IOIndex event, void * info ); 125 126private: 127 bool updatePowerParam(void); 128 void handlePMSettingCallback(const OSSymbol *, OSObject *, uintptr_t); 129 static void _deferredEvent( OSObject * target, 130 IOInterruptEventSource * evtSrc, int intCount ); 131 void fadeAbort(void); 132 void fadeWork(IOTimerEventSource * sender); 133}; 134 135/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 136 137#undef super 138#define super IOBacklightDisplay 139 140OSDefineMetaClassAndStructors(AppleBacklightDisplay, IOBacklightDisplay) 141 142/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 143 144//#define kIOBacklightUserBrightnessKey "IOBacklightUserBrightness" 145#define fPowerUsesBrightness fMaxBrightness 146 147#define IOG_FADE 1 148 149enum 150{ 151 // fFadeState 152 kFadeIdle = (1 << 24), 153 kFadePostDelay = (2 << 24), 154 kFadeUpdatePower = (3 << 24), 155 156 kFadeDimLevel = ((uint32_t) (0.75f * 1024)), 157 kFadeMidLevel = ((uint32_t) (0.50f * 1024)), 158}; 159 160/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 161// probe 162// 163 164IOService * AppleBacklightDisplay::probe( IOService * provider, SInt32 * score ) 165{ 166 IOFramebuffer * framebuffer; 167 IOService * ret = 0; 168 UInt32 displayType; 169 uintptr_t connectFlags; 170 171 do 172 { 173 if (!gIOFBHaveBacklight) 174 continue; 175 176 if (!super::probe(provider, score)) 177 continue; 178 179 framebuffer = (IOFramebuffer *) getConnection()->getFramebuffer(); 180 181 for (IOItemCount idx = 0; idx < framebuffer->getConnectionCount(); idx++) 182 { 183 if (kIOReturnSuccess != framebuffer->getAttributeForConnection(idx, 184 kConnectionFlags, &connectFlags)) 185 continue; 186 if (0 == (kIOConnectionBuiltIn & connectFlags)) 187 continue; 188 if (kIOReturnSuccess != framebuffer->getAppleSense(idx, NULL, NULL, NULL, &displayType)) 189 continue; 190 if ((kPanelTFTConnect != displayType) 191 && (kGenericLCD != displayType) 192 && (kPanelFSTNConnect != displayType)) 193 continue; 194 195 ret = this; // yes, we will control the panel 196 break; 197 } 198 } 199 while (false); 200 201 return (ret); 202} 203 204bool AppleBacklightDisplay::start( IOService * provider ) 205{ 206 IOFramebuffer * fb; 207 if (!super::start(provider)) return (false); 208 209 fClamshellSlept = gIOFBCurrentClamshellState; 210 fb = getConnection()->getFramebuffer(); 211 212 fDeferredEvents = IOInterruptEventSource::interruptEventSource(this, _deferredEvent); 213 if (fDeferredEvents) fb->getControllerWorkLoop()->addEventSource(fDeferredEvents); 214 215 fFadeTimer = IOTimerEventSource::timerEventSource(this, 216 OSMemberFunctionCast(IOTimerEventSource::Action, this, 217 &AppleBacklightDisplay::fadeWork)); 218 if (fFadeTimer) fb->getControllerWorkLoop()->addEventSource(fFadeTimer); 219 220 fFadeState = kFadeIdle; 221 222 fb->setProperty(kIOFBBuiltInKey, this, 0); 223 224 return (true); 225} 226 227void AppleBacklightDisplay::stop( IOService * provider ) 228{ 229 if (fDeferredEvents) 230 { 231 getConnection()->getFramebuffer()->getControllerWorkLoop()->removeEventSource(fDeferredEvents); 232 fDeferredEvents->release(); 233 fDeferredEvents = 0; 234 } 235 236 fadeAbort(); 237 if (fFadeTimer) 238 { 239 fFadeTimer->disable(); 240 getConnection()->getFramebuffer()->getControllerWorkLoop()->removeEventSource(fFadeTimer); 241 fFadeTimer->release(); 242 fFadeTimer = 0; 243 } 244 245 return (super::stop(provider)); 246} 247 248 249/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 250// initForPM 251// 252// This method overrides the one in IODisplay to do PowerBook-only 253// power management of the display. 254 255void AppleBacklightDisplay::initPowerManagement( IOService * provider ) 256{ 257 OSDictionary * displayParams; 258 OSObject * obj; 259 OSNumber * num; 260 261 static const IOPMPowerState ourPowerStates[kIODisplayNumPowerStates] = { 262 // version, 263 // capabilityFlags, outputPowerCharacter, inputPowerRequirement, 264 { 1, 0, 0, 0, 0,0,0,0,0,0,0,0 }, 265 { 1, 0, 0, 0, 0,0,0,0,0,0,0,0 }, 266 { 1, IOPMDeviceUsable, 0, kIOPMPowerOn, 0,0,0,0,0,0,0,0 }, 267 { 1, IOPMDeviceUsable | IOPMMaxPerformance, 0, kIOPMPowerOn, 0,0,0,0,0,0,0,0 } 268 // staticPower, unbudgetedPower, powerToAttain, timeToAttain, settleUpTime, 269 // timeToLower, settleDownTime, powerDomainBudget 270 }; 271 272 // Check initial state of "DisplaySleepUsesDim" 273 obj = getPMRootDomain()->copyPMSetting( 274 const_cast<OSSymbol *>(gIOFBPMSettingDisplaySleepUsesDimKey)); 275 fDisplayDims = (!(num = OSDynamicCast(OSNumber, obj)) || (num->unsigned32BitValue())); 276 if (obj) obj->release(); 277 278 fCurrentPowerState = -1U; 279 280 displayParams = OSDynamicCast(OSDictionary, copyProperty(gIODisplayParametersKey)); 281 if (displayParams) 282 { 283 SInt32 value, min, max; 284 285 if (getIntegerRange(displayParams, gIODisplayPowerStateKey, 286 &value, &min, &max)) 287 { 288 } 289 else 290 { 291 fMinBrightness = 0; 292 fMaxBrightness = 255; 293 } 294#if IOG_FADE 295 OSDictionary * newParams; 296 newParams = OSDictionary::withDictionary(displayParams); 297 addParameter(newParams, gIODisplayFadeTime1Key, 0, 10000); 298 setParameter(newParams, gIODisplayFadeTime1Key, 500); 299 addParameter(newParams, gIODisplayFadeTime2Key, 0, 10000); 300 setParameter(newParams, gIODisplayFadeTime2Key, 4000); 301 addParameter(newParams, gIODisplayFadeTime3Key, 0, 10000); 302 setParameter(newParams, gIODisplayFadeTime3Key, 500); 303 addParameter(newParams, gIODisplayFadeStyleKey, 0, 10); 304 setParameter(newParams, gIODisplayFadeStyleKey, 0); 305 setProperty(gIODisplayParametersKey, newParams); 306 newParams->release(); 307#endif 308 displayParams->release(); 309 } 310 311 // initialize superclass variables 312 PMinit(); 313 // attach into the power management hierarchy 314 provider->joinPMtree(this); 315 316 // register ourselves with policy-maker (us) 317 registerPowerDriver(this, (IOPMPowerState *) ourPowerStates, kIODisplayNumPowerStates); 318} 319 320/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 321// setPowerState 322// 323 324//#define DEBGFADE(fmt, args...) do { kprintf(fmt, ## args); } while(false) 325#define DEBGFADE(fmt, args...) do {} while(false) 326 327IOReturn AppleBacklightDisplay::setPowerState( unsigned long powerState, IOService * whatDevice ) 328{ 329 IOReturn ret = IOPMAckImplied; 330 UInt32 fromPowerState; 331 332 if (powerState >= kIODisplayNumPowerStates) 333 return (IOPMAckImplied); 334 335 IOFramebuffer * framebuffer = (IOFramebuffer *) getConnection()->getFramebuffer(); 336 337 framebuffer->fbLock(); 338 339 if (isInactive() || (fCurrentPowerState == powerState)) 340 { 341 framebuffer->fbUnlock(); 342 return (IOPMAckImplied); 343 } 344 fromPowerState = fCurrentPowerState; 345 fCurrentPowerState = powerState; 346 if (fCurrentPowerState) fProviderPower = true; 347 348 OSObject * obj; 349 if ((!powerState) && (obj = copyProperty(kIOHibernatePreviewActiveKey, gIOServicePlane))) 350 { 351 obj->release(); 352 } 353 else 354 { 355#if IOG_FADE 356 SInt32 current, min, max, steps; 357 OSDictionary * displayParams; 358 uint32_t fadeTime; 359 uint32_t dimFade; 360 bool doFadeDown, doFadeGamma, doFadeBacklight; 361 362 displayParams = OSDynamicCast(OSDictionary, copyProperty(gIODisplayParametersKey)); 363 fadeTime = 0; 364 doFadeDown = true; 365 doFadeGamma = false; 366 doFadeBacklight = true; 367 368 DEBGFADE("AppleBacklight: ps [%d->%ld]\n", fromPowerState, powerState); 369 370 if (gIOGFades 371 && displayParams 372 && (getIntegerRange(displayParams, gIODisplayBrightnessFadeKey, NULL, &min, &max)) 373 && (getIntegerRange(displayParams, gIODisplayBrightnessKey, ¤t, NULL, NULL)) 374 && current 375 && !fFadeAbort) 376 { 377 if (current < ((kFadeMidLevel * max) / 1024)) dimFade = max; 378 else dimFade = (kFadeDimLevel * max) / 1024; 379 380 if (-1U == fromPowerState) { /* boot */ } 381 else if ((powerState > fromPowerState) && (1 >= fromPowerState)) 382 { 383 // fade up from off 384 fadeTime = gIODisplayFadeTime3*1000; 385 doFadeGamma = true; 386 doFadeDown = false; 387 } 388 if ((3 == powerState) && (1 >= fromPowerState)) 389 { 390 // fade up from off 391 fadeTime = gIODisplayFadeTime3*1000; 392 doFadeDown = false; 393 } 394 if ((3 == powerState) && (2 == fromPowerState)) 395 { 396 // fade up from dim 397 fadeTime = gIODisplayFadeTime3*1000; 398 max = dimFade; 399 doFadeDown = false; 400 } 401 else if ((0 == powerState) && (3 == fromPowerState)) 402 { 403 // user initiated -> off 404 fadeTime = gIODisplayFadeTime1*1000; 405 doFadeGamma = true; 406 } 407 else if (1 != gIODisplayFadeStyle) 408 { 409 if ((2 == powerState) && (3 == fromPowerState)) 410 { 411 // idle initiated -> dim 412 fadeTime = gIODisplayFadeTime1*1000; 413 max = dimFade; 414 } 415 if ((1 == powerState) && (2 == fromPowerState)) 416 { 417 // idle initiated -> off 418 fadeTime = gIODisplayFadeTime1*1000; 419 doFadeBacklight = (dimFade != max); 420 if (doFadeBacklight) current = max - dimFade; 421 doFadeGamma = true; 422 } 423 } 424 else if (1 == gIODisplayFadeStyle) 425 { 426 if ((2 == powerState) && (3 == fromPowerState)) 427 { 428 // idle initiated 429 fCurrentPowerState = 1; 430 fadeTime = gIODisplayFadeTime2*1000; 431 doFadeGamma = true; 432 }; 433 } 434 DEBGFADE("AppleBacklight: fadeTime %d style %d abort %d\n", fadeTime, gIODisplayFadeStyle, fFadeAbort); 435 } 436 437 if (fadeTime) 438 { 439 steps = fadeTime / 16667; 440 441 DEBGFADE("AppleBacklight: p %d -> %ld, c %d -> m %d\n", fromPowerState, powerState, current, max); 442 443 if (current > max) current = max; 444 445 fFadeStateFadeMin = max - current; 446 fFadeStateFadeDelta = current; 447 if (steps > fFadeStateFadeDelta) steps = fFadeStateFadeDelta; 448 449 fFadeDown = doFadeDown; 450 fFadeGamma = doFadeGamma; 451 fFadeBacklight = doFadeBacklight; 452 453 DEBGFADE("AppleBacklight: %d -> %d\n", fFadeStateFadeMin, fFadeStateFadeDelta); 454 455 fFadeState = 0; 456 if (!fFadeDown) updatePowerParam(); 457 458 fFadeDeadline = mach_absolute_time(); 459 fadeTime /= steps; 460 fFadeStateEnd = (steps - 1); 461 if (framebuffer->isWakingFromHibernateGfxOn()) fFadeState = fFadeStateEnd; 462 clock_interval_to_absolutetime_interval(fadeTime, kMicrosecondScale, &fFadeInterval); 463 fadeWork(fFadeTimer); 464 if (fFadeDown) ret = 20 * 1000 * 1000; 465 } 466 else 467 { 468 updatePowerParam(); 469 fFadeAbort = false; 470 } 471#else 472 updatePowerParam(); 473#endif 474 } 475 476 if (!fCurrentPowerState) fProviderPower = false; 477 478 framebuffer->fbUnlock(); 479 480 return (ret); 481} 482 483/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 484 485void AppleBacklightDisplay::fadeAbort(void) 486{ 487 OSDictionary * displayParams; 488 489 if (kFadeIdle == fFadeState) return; 490 displayParams = OSDynamicCast(OSDictionary, copyProperty(gIODisplayParametersKey)); 491 if (!displayParams) return; 492 493 // abort 494 DEBGFADE("AppleBacklight: fadeAbort\n"); 495 doIntegerSet(displayParams, gIODisplayBrightnessFadeKey, 0); 496 if (fFadeGamma) 497 { 498 doIntegerSet(displayParams, gIODisplayGammaScaleKey, 65536); 499 doIntegerSet(displayParams, gIODisplayParametersFlushKey, 0); 500 } 501 displayParams->release(); 502 if (fFadeDown) acknowledgeSetPowerState(); 503 fFadeState = kFadeIdle; 504} 505 506void AppleBacklightDisplay::fadeWork(IOTimerEventSource * sender) 507{ 508 OSDictionary * displayParams; 509 SInt32 fade, gamma, point; 510 511 DEBGFADE("AppleBacklight: fadeWork(fFadeStateEnd %d, fFadeState %d, %d, fFadeStateEnd %d)\n", 512 fFadeStateEnd, fFadeState & 0xffff, fFadeState >> 24, fFadeStateEnd); 513 514 if (kFadeIdle == fFadeState) return; 515 displayParams = OSDynamicCast(OSDictionary, copyProperty(gIODisplayParametersKey)); 516 if (!displayParams) return; 517 518 fFadeAbort = (fFadeDown && !fDisplayPMVars->displayIdle); 519 520 if (fFadeAbort) fadeAbort(); 521 else if (fFadeState <= fFadeStateEnd) 522 { 523 point = fFadeState; 524 if (!fFadeDown) point = (fFadeStateEnd - point); 525 if (fFadeBacklight) 526 { 527 if (!fFadeDown && !point) fade = 0; 528 else 529 { 530 fade = ((point * fFadeStateFadeDelta) / fFadeStateEnd); 531 fade = fFadeStateFadeMin + fade; 532 } 533 DEBGFADE("AppleBacklight: backlight: %d\n", fade); 534 doIntegerSet(displayParams, gIODisplayBrightnessFadeKey, fade); 535 } 536 if (fFadeGamma) 537 { 538 gamma = 65536 - ((point * 65536) / fFadeStateEnd); 539 DEBGFADE("AppleBacklight: gamma: %d\n", gamma); 540 doIntegerSet(displayParams, gIODisplayGammaScaleKey, gamma); 541 doIntegerSet(displayParams, gIODisplayParametersFlushKey, 0); 542 } 543 544 fFadeState++; 545 if (fFadeState > fFadeStateEnd) 546 { 547 if (fFadeDown) updatePowerParam(); 548 fFadeState = kFadePostDelay; 549 clock_interval_to_absolutetime_interval(500, kMillisecondScale, &fFadeInterval); 550 } 551 } 552 else if (kFadePostDelay == fFadeState) 553 { 554 fFadeState = kFadeIdle; 555 } 556 557 if (kFadeIdle == fFadeState) 558 { 559 DEBGFADE("AppleBacklight: fadeWork ack\n"); 560 if (fFadeDown) acknowledgeSetPowerState(); 561 } 562 else 563 { 564 ADD_ABSOLUTETIME(&fFadeDeadline, &fFadeInterval); 565 fFadeTimer->wakeAtTime(fFadeDeadline); 566 } 567} 568 569/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 570 571void AppleBacklightDisplay::makeDisplayUsable( void ) 572{ 573 if (kIODisplayMaxPowerState == fCurrentPowerState) 574 setPowerState(fCurrentPowerState, this); 575 super::makeDisplayUsable(); 576} 577 578/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 579// maxCapabilityForDomainState 580// 581// This simple device needs only power. If the power domain is supplying 582// power, the display can go to its highest state. If there is no power 583// it can only be in its lowest state, which is off. 584 585unsigned long AppleBacklightDisplay::maxCapabilityForDomainState( IOPMPowerFlags domainState ) 586{ 587 if (domainState & IOPMPowerOn) 588 return (kIODisplayMaxPowerState); 589 else 590 return (0); 591} 592 593/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 594// initialPowerStateForDomainState 595// 596// The power domain may be changing state. If power is on in the new 597// state, that will not affect our state at all. If domain power is off, 598// we can attain only our lowest state, which is off. 599 600unsigned long AppleBacklightDisplay::initialPowerStateForDomainState( IOPMPowerFlags domainState ) 601{ 602 if (domainState & IOPMPowerOn) 603 return (kIODisplayMaxPowerState); 604 else 605 return (0); 606} 607 608/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 609// powerStateForDomainState 610// 611// The power domain may be changing state. If power is on in the new 612// state, that will not affect our state at all. If domain power is off, 613// we can attain only our lowest state, which is off. 614 615unsigned long AppleBacklightDisplay::powerStateForDomainState( IOPMPowerFlags domainState ) 616{ 617 if (domainState & IOPMPowerOn) 618 return (kIODisplayMaxPowerState); 619 else 620 return (0); 621} 622 623/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 624 625// Alter the backlight brightness by user request. 626 627bool AppleBacklightDisplay::doIntegerSet( OSDictionary * params, 628 const OSSymbol * paramName, UInt32 value ) 629{ 630 if ((paramName == gIODisplayParametersCommitKey) 631 && (kIODisplayMaxPowerState != fCurrentPowerState)) 632 return (true); 633 634 if (paramName == gIODisplayBrightnessKey) 635 { 636#if 0 637 fCurrentUserBrightness = value; 638 getPMRootDomain()->setProperty(kIOBacklightUserBrightnessKey, fCurrentUserBrightness, 32); 639#endif 640 if (fPowerUsesBrightness && fClamshellSlept) 641 value = 0; 642 } 643 644 return (super::doIntegerSet(params, paramName, value)); 645} 646 647bool AppleBacklightDisplay::doUpdate( void ) 648{ 649 bool ok; 650 651 ok = super::doUpdate(); 652 653#if 0 654 OSDictionary * displayParams; 655 if (fDisplayPMVars 656 && (displayParams = OSDynamicCast(OSDictionary, copyProperty(gIODisplayParametersKey)))) 657 { 658 setParameter(displayParams, gIODisplayBrightnessKey, fCurrentUserBrightness); 659 displayParams->release(); 660 } 661#endif 662 663 return (ok); 664} 665 666/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 667 668bool AppleBacklightDisplay::updatePowerParam(void) 669{ 670 OSDictionary * displayParams; 671 SInt32 value, current; 672 bool ret; 673 674#if DEBUG 675 IOLog("brightness[%d,%d] %d\n", (int) fCurrentPowerState, (int) gIOFBLastClamshellState, (int) value); 676 if (!getControllerWorkLoop()->inGate()) 677 OSReportWithBacktrace("AppleBacklightDisplay::updatePowerParam !inGate\n"); 678#endif 679 680 DEBG1("B", " fProviderPower %d, fClamshellSlept %d, fCurrentPowerState %d\n", 681 fProviderPower, fClamshellSlept, fCurrentPowerState); 682 683 if (!fProviderPower) return (false); 684 685 displayParams = OSDynamicCast(OSDictionary, copyProperty(gIODisplayParametersKey)); 686 if (!displayParams) return (false); 687 688 value = fClamshellSlept ? 0 : fCurrentPowerState; 689 690 if (fPowerUsesBrightness) 691 { 692 switch (value) 693 { 694 case 0: 695 value = 0; 696 break; 697 case 1: 698 value = fMinBrightness; 699 break; 700 case 2: 701 value = fDisplayDims ? (fMinBrightness + 1) : fMaxBrightness; 702 break; 703 case 3: 704 value = fMaxBrightness; 705 break; 706 } 707 if (getIntegerRange(displayParams, gIODisplayBrightnessKey, ¤t, NULL, NULL) 708 && (value > current)) 709 value = current; 710 //if(gIOFBSystemPower) 711 if (value <= fMinBrightness) 712 value = 0; 713 ret = super::doIntegerSet(displayParams, gIODisplayBrightnessKey, value); 714 } 715 else 716 { 717 switch (value) 718 { 719 case 0: 720 value = kIODisplayPowerStateOff; 721 break; 722 case 1: 723 value = kIODisplayPowerStateOff; 724 break; 725 case 2: 726 value = (fDisplayDims && (kFadeIdle == fFadeState)) ? kIODisplayPowerStateMinUsable : kIODisplayPowerStateOn; 727 break; 728 case 3: 729 value = kIODisplayPowerStateOn; 730 break; 731 } 732 DEBG1("B", " dsyp %d\n", value); 733 ret = super::doIntegerSet(displayParams, gIODisplayPowerStateKey, value); 734#if IOG_FADE2 735 if (kIODisplayPowerStateOff == value) IOSleep(700); 736#endif 737 } 738 739 displayParams->release(); 740 741 return (ret); 742} 743 744/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 745 746void AppleBacklightDisplay::_deferredEvent( OSObject * target, 747 IOInterruptEventSource * evtSrc, int intCount ) 748{ 749 AppleBacklightDisplay * self = (AppleBacklightDisplay *) target; 750 751 self->updatePowerParam(); 752} 753 754IOReturn AppleBacklightDisplay::framebufferEvent( IOFramebuffer * framebuffer, 755 IOIndex event, void * info ) 756{ 757 if ((kIOFBNotifyDidWake == event) && (info)) 758 { 759 fProviderPower = true; 760// fCurrentPowerState = kIODisplayMaxPowerState; 761// updatePowerParam(); 762 } 763 else if (kIOFBNotifyClamshellChange == event) 764 { 765 if (kOSBooleanTrue == info) 766 { 767#if LCM_HWSLEEP 768 fConnection->getFramebuffer()->changePowerStateTo(0); 769#endif 770 fClamshellSlept = true; 771 } 772 else if (fClamshellSlept) 773 { 774 fClamshellSlept = false; 775 } 776 // may be in the right power state already, but wrong brightness because 777 // of the clamshell state at setPowerState time. 778 if (fDeferredEvents) 779 fDeferredEvents->interruptOccurred(0, 0, 0); 780 } 781 else if (kIOFBNotifyProbed == event) 782 { 783 if (fDeferredEvents) 784 fDeferredEvents->interruptOccurred(0, 0, 0); 785 } 786 else if (kIOFBNotifyDisplayDimsChange == event) 787 { 788 UInt8 newValue = (info != NULL); 789 if (newValue != fDisplayDims) 790 { 791 fDisplayDims = newValue; 792 if (fDeferredEvents) 793 fDeferredEvents->interruptOccurred(0, 0, 0); 794 } 795 } 796 797 return (super::framebufferEvent( framebuffer, event, info )); 798} 799 800 801