|
|
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: * Copyright (c) 1997-1998 Apple Computer, Inc. ! 24: * ! 25: * ! 26: * HISTORY ! 27: * ! 28: * sdouglas 22 Oct 97 - first checked in. ! 29: * sdouglas 23 Jul 98 - start IOKit ! 30: * sdouglas 08 Dec 98 - start cpp ! 31: */ ! 32: ! 33: #include <IOKit/graphics/IODisplay.h> ! 34: #include <libkern/c++/OSContainers.h> ! 35: #include <IOKit/IOLib.h> ! 36: ! 37: #include <IOKit/assert.h> ! 38: ! 39: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 40: ! 41: struct EDID { ! 42: UInt8 header[8]; ! 43: UInt8 vendorProduct[4]; ! 44: UInt8 serialNumber[4]; ! 45: UInt8 weekOfManufacture; ! 46: UInt8 yearOfManufacture; ! 47: UInt8 version; ! 48: UInt8 revision; ! 49: UInt8 displayParams[5]; ! 50: UInt8 colorCharacteristics[10]; ! 51: UInt8 establishedTimings[3]; ! 52: UInt16 standardTimings[8]; ! 53: UInt8 detailedTimings[72]; ! 54: UInt8 extension; ! 55: UInt8 checksum; ! 56: }; ! 57: ! 58: struct TimingToEDID { ! 59: UInt32 timingID; ! 60: UInt8 spare; ! 61: UInt8 establishedBit; ! 62: UInt16 standardTiming; ! 63: }; ! 64: ! 65: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 66: ! 67: class AppleDDCDisplay : public IODisplay ! 68: { ! 69: OSDeclareDefaultStructors(AppleDDCDisplay) ! 70: ! 71: private: ! 72: OSData * edidData; ! 73: OSData * additions; ! 74: TimingToEDID * timingToEDID; ! 75: int numEDIDEntries; ! 76: ! 77: public: ! 78: virtual IOService * probe( IOService * provider, ! 79: SInt32 * score ); ! 80: ! 81: virtual bool start( IOService * provider ); ! 82: ! 83: virtual IOReturn getConnectFlagsForDisplayMode( ! 84: IODisplayModeID mode, UInt32 * flags ); ! 85: }; ! 86: ! 87: #undef super ! 88: #define super IODisplay ! 89: ! 90: OSDefineMetaClassAndStructors(AppleDDCDisplay, IODisplay) ! 91: ! 92: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 93: ! 94: IOService * AppleDDCDisplay::probe( IOService * provider, ! 95: SInt32 * score ) ! 96: { ! 97: IODisplayConnect * connect; ! 98: IOFramebuffer * framebuffer; ! 99: IOService * ret = 0; ! 100: ! 101: do { ! 102: ! 103: if( 0 == super::probe( provider, score )) ! 104: continue; ! 105: ! 106: connect = getConnection(); ! 107: framebuffer = connect->getFramebuffer(); ! 108: assert( framebuffer ); ! 109: ! 110: if( kIOReturnSuccess != framebuffer->getAttributeForConnection( ! 111: connect->getConnection(), ! 112: kConnectionSupportsHLDDCSense, NULL )) ! 113: continue; ! 114: ! 115: if( framebuffer->hasDDCConnect( connect->getConnection())) ! 116: ret = this; ! 117: ! 118: } while( false); ! 119: ! 120: return( ret ); ! 121: } ! 122: ! 123: ! 124: bool AppleDDCDisplay::start( IOService * provider ) ! 125: { ! 126: IOReturn err; ! 127: IODisplayConnect * connect; ! 128: IOFramebuffer * framebuffer; ! 129: OSData * data; ! 130: OSArray * array; ! 131: OSDictionary * dict; ! 132: OSNumber * off; ! 133: IOByteCount length; ! 134: EDID readEDID; ! 135: UInt32 vendorProd; ! 136: UInt32 index; ! 137: ! 138: if (false == super::start( provider )) ! 139: return( false); ! 140: ! 141: connect = getConnection(); ! 142: framebuffer = connect->getFramebuffer(); ! 143: assert( framebuffer ); ! 144: ! 145: do { ! 146: length = sizeof( EDID); ! 147: err = framebuffer->getDDCBlock( connect->getConnection(), ! 148: 1, kIODDCBlockTypeEDID, 0, (UInt8 *) &readEDID, &length ); ! 149: if( err || (length != sizeof( EDID))) ! 150: continue; ! 151: ! 152: kprintf("%s EDID Version %d, Revision %d\n", framebuffer->getName(), ! 153: readEDID.version, readEDID.revision ); ! 154: if( readEDID.version != 1) ! 155: continue; ! 156: ! 157: if( (data = (OSData *) getProperty( "appleDDC" ))) { ! 158: timingToEDID = (TimingToEDID *) data->getBytesNoCopy(); ! 159: numEDIDEntries = data->getLength() / sizeof(TimingToEDID); ! 160: } else ! 161: continue; ! 162: ! 163: setProperty( kIODisplayEDIDKey, &readEDID, sizeof( readEDID)); ! 164: ! 165: vendorProd = (readEDID.vendorProduct[0] << 24) ! 166: | (readEDID.vendorProduct[1] << 16) ! 167: | (readEDID.vendorProduct[2] << 8) ! 168: | (readEDID.vendorProduct[3] << 0); ! 169: ! 170: #if 1 ! 171: kprintf("Vendor/product 0x%08x, ", vendorProd ); ! 172: kprintf("Est: "); ! 173: for( index = 0; index < 3; index++) ! 174: kprintf(" 0x%02x,", readEDID.establishedTimings[ index ] ); ! 175: kprintf("\nStd: " ); ! 176: for( index = 0; index < 8; index++) ! 177: kprintf(" 0x%04x,", readEDID.standardTimings[ index ] ); ! 178: kprintf("\n"); ! 179: #endif ! 180: ! 181: data = 0; ! 182: additions = 0; ! 183: if( (array = OSDynamicCast(OSArray, getProperty("overrides")))) { ! 184: for( index = 0; ! 185: (dict = OSDynamicCast(OSDictionary, array->getObject(index))); ! 186: index++ ) { ! 187: if( 0 == (off = OSDynamicCast(OSNumber, dict->getObject("ID")))) ! 188: continue; ! 189: if( vendorProd == off->unsigned32BitValue()) { ! 190: data = OSDynamicCast(OSData, ! 191: dict->getObject( "EDID")); ! 192: additions = OSDynamicCast(OSData, ! 193: dict->getObject("additions")); ! 194: break; ! 195: } ! 196: } ! 197: } ! 198: ! 199: if( !data) ! 200: data = (OSData *) getProperty( kIODisplayEDIDKey ); ! 201: if( !data) ! 202: continue; ! 203: edidData = data; ! 204: ! 205: return( true); ! 206: ! 207: } while( false); ! 208: ! 209: return( false); ! 210: } ! 211: ! 212: IOReturn AppleDDCDisplay::getConnectFlagsForDisplayMode( ! 213: IODisplayModeID mode, UInt32 * flags ) ! 214: { ! 215: IOReturn err; ! 216: IODisplayConnect * connect; ! 217: IOFramebuffer * framebuffer; ! 218: IOTimingInformation info; ! 219: const TimingToEDID * lookTiming; ! 220: UInt32 estBit, i; ! 221: EDID * edid; ! 222: UInt32 * addModes; ! 223: UInt32 numAdditions; ! 224: UInt32 appleTimingID; ! 225: bool supported = false; ! 226: enum { kSetFlags = (kDisplayModeValidFlag ! 227: | kDisplayModeSafeFlag) }; ! 228: ! 229: ! 230: connect = getConnection(); ! 231: framebuffer = connect->getFramebuffer(); ! 232: assert( framebuffer ); ! 233: ! 234: if( kIOReturnSuccess != framebuffer->connectFlags( connect->getConnection(), ! 235: mode, flags )) ! 236: *flags = 0; ! 237: ! 238: err = framebuffer->getTimingInfoForDisplayMode( mode, &info ); ! 239: if( err != kIOReturnSuccess) ! 240: return( err); ! 241: ! 242: appleTimingID = info.appleTimingID; ! 243: ! 244: if( additions) { ! 245: numAdditions = additions->getLength() / sizeof( UInt32); ! 246: addModes = (UInt32 *) additions->getBytesNoCopy(); ! 247: for( i = 0; (!supported) && (i < numAdditions); i++) ! 248: supported = (addModes[ i ] == appleTimingID); ! 249: } ! 250: ! 251: edid = (EDID *) edidData->getBytesNoCopy(); ! 252: assert( edid ); ! 253: for( lookTiming = timingToEDID; ! 254: (!supported) && ((lookTiming - timingToEDID) < numEDIDEntries); ! 255: lookTiming++ ) { ! 256: ! 257: if( lookTiming->timingID == appleTimingID) { ! 258: estBit = lookTiming->establishedBit; ! 259: if( estBit != 0xff) ! 260: supported = (0 != (edid->establishedTimings[ estBit / 8 ] ! 261: & (1 << (estBit % 8)))); ! 262: ! 263: for( i = 0; (!supported) && (i < 8); i++ ) ! 264: supported = (lookTiming->standardTiming ! 265: == edid->standardTimings[i] ); ! 266: } ! 267: } ! 268: ! 269: if( supported) ! 270: *flags = kSetFlags; ! 271: ! 272: // Pass the existing flags (from framebuffer) thru ! 273: return( err); ! 274: } ! 275:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.