Annotation of XNU/iokit/Families/IOGraphics/AppleG3SeriesDisplay.cpp, revision 1.1

1.1     ! root        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/graphics/IODisplay.h>
        !            25: #include <IOKit/ndrvsupport/IOMacOSVideo.h>
        !            26: 
        !            27: #include <Drivers/platform/drvApplePMU/pmupriv.h>
        !            28: #include <Drivers/hidsystem/drvAppleADBDevices/AppleADBButtons.h>
        !            29: 
        !            30: #define kNumber_of_power_states 4
        !            31: #define kNumber_of_power_levels 32
        !            32: 
        !            33: #define kScreenBit     0x01
        !            34: #define kPowerOn       0x80
        !            35: #define kPowerOff      0x00
        !            36: #define kDisplayOn     kScreenBit | kPowerOn
        !            37: #define kDisplayOff    kScreenBit | kPowerOff
        !            38: 
        !            39: class ApplePMU;
        !            40: 
        !            41: 
        !            42: class AppleG3SeriesDisplay : public AppleSenseDisplay
        !            43: {
        !            44:     OSDeclareDefaultStructors(AppleG3SeriesDisplay)
        !            45: 
        !            46: private:
        !            47:     
        !            48: int            current_user_brightness;        // 0-31.  The brightness level last selected via the brightness buttons.
        !            49: int            current_level;          // 0-31.  The current brightness level
        !            50: ApplePMU *     PMUdriver;              // points to PMU driver
        !            51: int *          rawTable;               // points to table of raw brightess levels
        !            52: 
        !            53: public:
        !            54:     IOService * probe ( IOService *, SInt32 * );
        !            55:     virtual void initForPM ( IOService* );
        !            56:     virtual IOReturn setPowerState ( unsigned long, IOService* );
        !            57:     virtual unsigned long maxCapabilityForDomainState ( IOPMPowerFlags );
        !            58:     virtual unsigned long initialPowerStateForDomainState ( IOPMPowerFlags );
        !            59:     virtual unsigned long powerStateForDomainState ( IOPMPowerFlags );
        !            60:     virtual void ourButtonHandler ( unsigned int );
        !            61:     virtual void setBrightness ( long );
        !            62: };
        !            63: 
        !            64: void upButtonHandler(AppleG3SeriesDisplay *);
        !            65: void downButtonHandler(AppleG3SeriesDisplay *);
        !            66: 
        !            67: 
        !            68: /*
        !            69:  The actual display panel has 128 power levels.  Copying the MacOS, we only implement 32 of them.
        !            70:  We further divide the 32 into four IOKit power states which we export to our superclass.
        !            71: 
        !            72:  In the lowest state, the display is off.  This state consists of only one of the 32 power levels, the lowest.
        !            73:  In the next state it is in the dimmest usable state.  This state also consists of only one of the 32 levels, the second lowest.
        !            74:  The next state is also dim and consists of seven of the 32 levels.
        !            75:  The highest state consists of the highest 23 levels.
        !            76: 
        !            77:  The display has no state or configuration or programming that would be saved/restored over power state changes,
        !            78:  and the driver does not register with the superclass as an interested driver.
        !            79: 
        !            80:  This driver doesn't have much to do.  It changes between the four power state brightnesses on command
        !            81:  from the superclass, and it raises and lowers the display brightness by one of the 32 brightness levels
        !            82:  when it receives a brightness-button interrupt from the ADB stack.
        !            83: 
        !            84:  The only smart thing it does is keep track of which of the 32 brightness levels the user has selected by button, and it
        !            85:   never exceeds that on command from the display device object.  It only raises above that on an brightness-up-button
        !            86:  interrupt.
        !            87: 
        !            88:   */
        !            89: 
        !            90: 
        !            91: static IOPMPowerState ourPowerStates[kNumber_of_power_states] = {
        !            92:     {1,0,0,0,0,0,0,0,0,0,0,0},
        !            93:     {1,IOPMDeviceUsable,0,IOPMPowerOn,0,0,0,0,0,0,0,0},
        !            94:     {1,IOPMDeviceUsable,0,IOPMPowerOn,0,0,0,0,0,0,0,0},
        !            95:     {1,IOPMDeviceUsable+IOPMMaxPerformance,0,IOPMPowerOn,0,0,0,0,0,0,0,0}
        !            96: };
        !            97: 
        !            98: static int  max_brightness_level[kNumber_of_power_states] = {0,1,8,31};
        !            99: 
        !           100: static int HooperTable[ ] = {127,71,69,67,65,63,61,59,
        !           101:                          58,56,54,52,50,48,46,44,
        !           102:                         42,40,38,37,35,33,31,29,
        !           103:                         27,25,23,21,19,18,16,14 };
        !           104: 
        !           105: bool ourNotificationHandler( OSObject *, void *, IOService * );
        !           106: 
        !           107: #define super AppleSenseDisplay
        !           108: 
        !           109: OSDefineMetaClassAndStructors(AppleG3SeriesDisplay, AppleSenseDisplay)
        !           110: 
        !           111: 
        !           112: // **********************************************************************************
        !           113: // probe
        !           114: //
        !           115: // **********************************************************************************
        !           116: IOService * AppleG3SeriesDisplay::probe ( IOService * provider, SInt32 * score )
        !           117: {
        !           118:     IOFramebuffer *    framebuffer;
        !           119:     IOService *                ret = 0;
        !           120:     UInt32                     displayType;
        !           121:     IOIndex            ourIndex;
        !           122:     
        !           123:     do {
        !           124:         if ( 0 == super::probe( provider, score ) ) {
        !           125:             continue;
        !           126:         }
        !           127: 
        !           128:         framebuffer =  (IOFramebuffer *)getConnection()->getFramebuffer();     // point to our framebuffer
        !           129:         ourIndex = getConnection()->getConnection();                           // get our connection index on this framebuffer
        !           130: 
        !           131:         if ( kIOReturnSuccess != framebuffer->getAppleSense(ourIndex,NULL,NULL,NULL,&displayType) ) {
        !           132:             continue;
        !           133:         }
        !           134: 
        !           135:         if ( !(displayType == kPanelTFTConnect) ) {                            // does it have a panel attached?       
        !           136:             continue;                                                          // no
        !           137:         }
        !           138:         ret = this;                                                            // yes, we will control the panel
        !           139: 
        !           140:     } while ( false );
        !           141:     
        !           142:     return ( ret );
        !           143: }
        !           144: 
        !           145: 
        !           146: // **********************************************************************************
        !           147: // initForPM
        !           148: //
        !           149: // This method overrides the one in IODisplay.h to do PowerBook-only
        !           150: // power management of the display.
        !           151: // **********************************************************************************
        !           152: void AppleG3SeriesDisplay::initForPM ( IOService * provider )
        !           153: {
        !           154:     IOByteCount                        unused;
        !           155:     const OSSymbol *   PMUname;
        !           156:     IOService *                service;
        !           157:     unsigned long              i;
        !           158:     UInt8                      PMUreceiveBuffer[10];   // (I think 1 is enough, but it scares me)
        !           159: 
        !           160: 
        !           161:     displayPMVars->powerControllable = true;
        !           162: 
        !           163:     PMinit();                                                  // initialize superclass variables
        !           164: 
        !           165:     PMUname = OSSymbol::withCStringNoCopy(kPMUname);           // find the PMU driver
        !           166:     service = waitForService(resourceMatching(PMUname));
        !           167:     PMUdriver = OSDynamicCast(ApplePMU, service->getProperty(PMUname));
        !           168: 
        !           169:     rawTable = HooperTable;
        !           170: 
        !           171:     PMUdriver->sendMiscCommand(kPMUpower1Read,0, NULL, &unused,PMUreceiveBuffer);
        !           172:     if ( PMUreceiveBuffer[0] & kScreenBit ) {                                                  // is the screen currently on?
        !           173:         PMUdriver->sendMiscCommand(kPMUReadBrightness,0, NULL, &unused,PMUreceiveBuffer);      // yes, figure out the brightness
        !           174:         current_user_brightness = kNumber_of_power_levels - 1;         // ( in case the for-loop doesn't break)
        !           175:         current_level = kNumber_of_power_levels - 1;
        !           176: 
        !           177:         for ( i = 0; i < kNumber_of_power_levels; i++ ) {
        !           178:             if ( PMUreceiveBuffer[0] >= rawTable[i] ) {
        !           179:                 current_user_brightness = i;
        !           180:                 current_level = i;
        !           181:                 break;
        !           182:             }
        !           183:         }
        !           184:     }
        !           185:     else {                                                     // no
        !           186:         current_user_brightness = 0;
        !           187:         current_level = 0;
        !           188:     }
        !           189: 
        !           190:     addNotification( gIOPublishNotification,serviceMatching("AppleADBButtons"),        // look for the button driver
        !           191:                      (IOServiceNotificationHandler)ourNotificationHandler, this, 0 );
        !           192:     
        !           193:     provider->joinPMtree(this);                                        // attach into the power management hierarchy
        !           194:     registerControllingDriver(this,ourPowerStates,kNumber_of_power_states);    // register with policy-maker (us)
        !           195: }
        !           196: 
        !           197: 
        !           198: // **********************************************************************************
        !           199: // ourNotificationHandler
        !           200: //
        !           201: // The ADB button driver has appeared.  Tell it we are interested in the
        !           202: // brightness-up button and the brightness-down button.
        !           203: // **********************************************************************************
        !           204: bool ourNotificationHandler( OSObject * us, void * ref, IOService * yourDevice )
        !           205: {
        !           206:     if ( yourDevice != NULL ) {
        !           207:         ((AppleADBButtons *)yourDevice)->registerForButton(kBrightness_up,(IOService *)us,(button_handler)upButtonHandler,true);
        !           208:         ((AppleADBButtons *)yourDevice)->registerForButton(kBrightness_down,(IOService *)us,(button_handler)downButtonHandler,true);
        !           209:     }
        !           210:     return true;
        !           211: }
        !           212: 
        !           213: 
        !           214: // **********************************************************************************
        !           215: // setPowerState
        !           216: //
        !           217: // All power state changes require a call to the PMU driver, which
        !           218: // blocks the thread till the command completes.
        !           219: // **********************************************************************************
        !           220: IOReturn AppleG3SeriesDisplay::setPowerState ( unsigned long powerStateOrdinal, IOService* whatDevice )
        !           221: {
        !           222:     UInt8              displayOn = kDisplayOn;
        !           223:     UInt8              displayOff = kDisplayOff;
        !           224:     IOByteCount                unused;
        !           225:     unsigned long      i;
        !           226: 
        !           227:     if ( powerStateOrdinal < kNumber_of_power_states ) {
        !           228:         if ( powerStateOrdinal > pm_vars->myCurrentState ) {                   // raising power
        !           229:             if ( pm_vars->myCurrentState == 0 ) {                                      // is it currently off?
        !           230:                 PMUdriver->sendMiscCommand(kPMUpower1Cntl,1, &displayOn, &unused,NULL);
        !           231:             }
        !           232:             current_level = max_brightness_level[powerStateOrdinal];
        !           233:             if ( current_user_brightness < current_level ) {
        !           234:                 current_level = current_user_brightness;                               // don't exceed what the user used to have it at
        !           235:             }
        !           236:             setBrightness(current_level);
        !           237:                                                                // If we are still higher than we need to be, request a lower state
        !           238:             for ( i = 0; i < kNumber_of_power_states; i++ ) {          // figure out what state we should be in
        !           239:                 if ( current_level <= max_brightness_level[i] ) {
        !           240:                     break;
        !           241:                 }
        !           242:             }
        !           243:             if ( pm_vars->myCurrentState > i ) {
        !           244:                 changeStateToPriv(i);
        !           245:             }
        !           246:         }
        !           247: 
        !           248:         if ( powerStateOrdinal < pm_vars->myCurrentState ) {                   // lowering power
        !           249:             if (powerStateOrdinal == 0 ) {                                                     // going all the way off?
        !           250:                 PMUdriver->sendMiscCommand(kPMUpower1Cntl,1, &displayOff, &unused,NULL);       // yes
        !           251:                 current_level = max_brightness_level[powerStateOrdinal];
        !           252:             }
        !           253:             else {
        !           254:                 if ( current_level > max_brightness_level[powerStateOrdinal] ) {                       // no
        !           255:                     current_level = max_brightness_level[powerStateOrdinal];
        !           256:                     setBrightness(current_level);
        !           257:                 }
        !           258:             }
        !           259:         }
        !           260:     }
        !           261:     return IOPMAckImplied;
        !           262: }
        !           263: 
        !           264: 
        !           265: // **********************************************************************************
        !           266: // maxCapabilityForDomainState
        !           267: //
        !           268: // This simple device needs only power.  If the power domain is supplying
        !           269: // power, the display can go to its highest state.  If there is no power
        !           270: // it can only be in its lowest state, which is off.
        !           271: // **********************************************************************************
        !           272: unsigned long  AppleG3SeriesDisplay::maxCapabilityForDomainState ( IOPMPowerFlags domainState )
        !           273: {
        !           274:     if ( domainState &  IOPMPowerOn ) {
        !           275:         return kNumber_of_power_states-1;
        !           276:     }
        !           277:     return 0;
        !           278: }
        !           279: 
        !           280: 
        !           281: // **********************************************************************************
        !           282: // initialPowerStateForDomainState
        !           283: //
        !           284: // The power domain may be changing state.  If power is on in the new
        !           285: // state, that will not affect our state at all.  If domain power is off,
        !           286: // we can attain only our lowest state, which is off.
        !           287: // **********************************************************************************
        !           288: unsigned long  AppleG3SeriesDisplay::initialPowerStateForDomainState ( IOPMPowerFlags domainState )
        !           289: {
        !           290:    long unsigned i;
        !           291: 
        !           292:    if ( domainState &  IOPMPowerOn ) {         // domain has power
        !           293:        for ( i = 0; i < kNumber_of_power_states; i++ ) {       // find power state that has our current
        !           294:            if ( current_level <= max_brightness_level[i] ) {   // brightness level
        !           295:                return i;
        !           296:                break;
        !           297:            }
        !           298:        }
        !           299:    }
        !           300:    return 0;                                   // domain is down, so display is off
        !           301: }
        !           302: 
        !           303: 
        !           304: // **********************************************************************************
        !           305: // powerStateForDomainState
        !           306: //
        !           307: // The power domain may be changing state.  If power is on in the new
        !           308: // state, that will not affect our state at all.  If domain power is off,
        !           309: // we can attain only our lowest state, which is off.
        !           310: // **********************************************************************************
        !           311: unsigned long  AppleG3SeriesDisplay::powerStateForDomainState ( IOPMPowerFlags domainState )
        !           312: {
        !           313:    long unsigned i;
        !           314: 
        !           315:    if ( domainState &  IOPMPowerOn ) {         // domain has power
        !           316:        for ( i = 0; i < kNumber_of_power_states; i++ ) {       // find power state that has our current
        !           317:            if ( current_level <= max_brightness_level[i] ) {   // brightness level
        !           318:                return i;
        !           319:            }
        !           320:        }
        !           321:    }
        !           322:    return 0;                                   // domain is down, so display is off
        !           323: }
        !           324: 
        !           325: 
        !           326: // **********************************************************************************
        !           327: // upButtonHandler
        !           328: //
        !           329: // The display-brightness-up button just went down.
        !           330: // We are running on a new thread made by the ADB Button driver
        !           331: // **********************************************************************************
        !           332: void upButtonHandler(AppleG3SeriesDisplay * us )
        !           333: {
        !           334:     ((AppleG3SeriesDisplay *)us)->ourButtonHandler(kBrightness_up);
        !           335: }
        !           336: 
        !           337: 
        !           338: // **********************************************************************************
        !           339: // downButtonHandler
        !           340: //
        !           341: // The display-brightness-down button just went down.
        !           342: // We are running on a new thread made by the ADB Button driver
        !           343: // **********************************************************************************
        !           344: void downButtonHandler(AppleG3SeriesDisplay * us )
        !           345: {
        !           346:     ((AppleG3SeriesDisplay *)us)->ourButtonHandler(kBrightness_down);
        !           347: }
        !           348: 
        !           349: 
        !           350: // **********************************************************************************
        !           351: // ourButtonHandler
        !           352: //
        !           353: // Alter the backlight brightness up or down by one increment.
        !           354: // This involves a call to the PMU driver, which will block the thread.
        !           355: // **********************************************************************************
        !           356: void AppleG3SeriesDisplay::ourButtonHandler ( unsigned int keycode )
        !           357: {                                                              // If we are idle, ignore the button.
        !           358:                                                                // The display will be made usable
        !           359:     if ( ! displayPMVars->displayIdle ) {                              // by the DisplayWrangler
        !           360:         switch (keycode) {
        !           361:             case kBrightness_up:                                               // The brightness-up button has just been pressed
        !           362:                                                                                // We make sure the brightness is not above the maximum
        !           363:                                                                                // brightness level of our current power state.  If it
        !           364:                                                                                 // is too high, we ask the device to raise power.
        !           365:                 if (current_level <  max_brightness_level[pm_vars->myCurrentState] ) {
        !           366:                     current_level++;
        !           367:                     current_user_brightness = current_level;
        !           368:                     setBrightness(current_level);
        !           369:                 }
        !           370:                 else {
        !           371:                     if ( pm_vars->myCurrentState < (kNumber_of_power_states-1) ) {
        !           372:                         current_user_brightness++;                                             // increment user's desire
        !           373:                         if ( changeStateToPriv(pm_vars->myCurrentState + 1) != IOPMNoErr ) {           // request higher power
        !           374:                             current_user_brightness--;                                         // can't
        !           375:                         }
        !           376:                     }
        !           377:                 }
        !           378:                 break;
        !           379: 
        !           380:             case kBrightness_down:                                     // The brightness-down button has just been pressed
        !           381:                                                                                // We lower the brightness, and if that takes us into a
        !           382:                                                                                // lower power state, we tell our parent about it.
        !           383:                 if ( pm_vars->myCurrentState > 0 ) {                           // don't lower if in lowest (off) state
        !           384:                     if ( current_level > 0 ) {
        !           385:                         current_level--;
        !           386:                         current_user_brightness = current_level;
        !           387:                         setBrightness(current_level);
        !           388:                         if (current_level <=  max_brightness_level[pm_vars->myCurrentState - 1] ) {    // if this takes us into the next lower state
        !           389:                             changeStateToPriv(pm_vars->myCurrentState - 1);                    // request lower power
        !           390:                         }
        !           391:                     }
        !           392:                 }
        !           393:                 break;
        !           394:         }
        !           395:     }
        !           396: }
        !           397: 
        !           398: 
        !           399: // **********************************************************************************
        !           400: // setBrightness
        !           401: //
        !           402: // Instruct PMU to set the display brightness.
        !           403: // This will block the thread while the command completes.
        !           404: // **********************************************************************************
        !           405: void AppleG3SeriesDisplay::setBrightness ( long brightness )
        !           406: {
        !           407:     IOByteCount unused;
        !           408:     UInt8      setBrightnessBuffer;
        !           409: 
        !           410:     setBrightnessBuffer = (UInt8)rawTable[brightness];
        !           411:     PMUdriver->sendMiscCommand(kPMUSetBrightness,1, &setBrightnessBuffer, &unused,NULL);
        !           412: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.