|
|
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.