Annotation of XNU/iokit/Families/IOGraphics/AppleG3SeriesDisplay.cpp, revision 1.1.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.