|
|
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: * suurballe 17 Nov 98 - ported to C++
31: */
32:
33: #include <assert.h>
34: #include <IOKit/IOLib.h>
35:
36: #include "AppleADBDisplay.h"
37:
38:
39: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
40:
41: #define super IODisplay
42: OSDefineMetaClassAndStructors( AppleADBDisplay, IODisplay )
43:
44: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
45:
46: IOReturn AppleADBDisplay::findADBDisplayInfoForType( UInt16 deviceType )
47: {
48: char stringBuf[ 32 ];
49: OSNumber * off;
50: OSString * key;
51: OSData * data;
52:
53: sprintf( stringBuf, "adb%dWiggle", deviceType);
54: if( (off = OSDynamicCast( OSNumber, getProperty( stringBuf ))))
55: wiggleLADAddr = off->unsigned32BitValue();
56: else
57: wiggleLADAddr = kWiggleLADAddr;
58:
59: sprintf( stringBuf, "adb%dModes", deviceType);
60: key = OSDynamicCast( OSString, getProperty( stringBuf ));
61:
62: if( key && (data = OSDynamicCast( OSData, getProperty( key )))) {
63: modeList = (UInt32 *) data->getBytesNoCopy();
64: numModes = data->getLength() / sizeof( UInt32);
65: }
66: if( modeList )
67: return(kIOReturnSuccess);
68: else
69: return( -49 );
70: }
71:
72:
73: IOReturn AppleADBDisplay::getConnectFlagsForDisplayMode(
74: IODisplayModeID mode, UInt32 * flags )
75: {
76: IOReturn err;
77: IODisplayConnect * connect;
78: IOFramebuffer * framebuffer;
79: int timingNum;
80: IOTimingInformation info;
81:
82: *flags = 0;
83:
84: connect = getConnection();
85: assert( connect );
86: framebuffer = connect->getFramebuffer();
87: assert( framebuffer );
88:
89: err = framebuffer->getTimingInfoForDisplayMode( mode, &info );
90:
91: if( kIOReturnSuccess == err) {
92: for( timingNum = 0; timingNum < numModes; timingNum++ ) {
93: if( info.appleTimingID == modeList[ timingNum ] ) {
94: *flags = timingNum
95: ? ( kDisplayModeValidFlag | kDisplayModeSafeFlag )
96: : ( kDisplayModeValidFlag | kDisplayModeSafeFlag
97: | kDisplayModeDefaultFlag );
98: break;
99: }
100: }
101: }
102:
103: return( err );
104: }
105:
106: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
107:
108: IOReturn AppleADBDisplay::doConnect( void )
109: {
110: IOReturn err;
111: UInt16 value;
112: UInt32 retries = 9;
113: IOByteCount length;
114:
115: while ( retries-- ) {
116:
117: value = 0x6000 | (adbDevice->address() << 8);
118: length = sizeof( value);
119: err = adbDevice->writeRegister( 3, (UInt8 *) &value, &length );
120: if( err)
121: continue;
122:
123: /* IOSleep(10); */
124: /* IODelay(1000); */
125: length = sizeof( value);
126: err = adbDevice->readRegister( 3, (UInt8 *) &value, &length );
127: if( err)
128: continue;
129:
130: if( (value & 0xf000) == 0x6000 )
131: break;
132: else
133: err = kIOReturnNotAttached;
134: }
135:
136: if( err)
137: kprintf("%s: %d\n", __FUNCTION__, err);
138:
139: return(err);
140: }
141:
142: static void autoPollHandler( IOService * self, UInt8 adbCommand,
143: IOByteCount length, UInt8 * data )
144: {
145: ((AppleADBDisplay *)self)->packet( adbCommand, length, data );
146: }
147:
148: void AppleADBDisplay::packet( UInt8 adbCommand,
149: IOByteCount length, UInt8 * data )
150: {
151: if( length && (*data == waitAckValue) )
152: waitAckValue = 0;
153: }
154:
155: IOReturn AppleADBDisplay::writeWithAcknowledge( UInt8 regNum,
156: UInt16 data, UInt8 ackValue )
157: {
158: IOReturn err;
159: enum { kTimeoutMS = 400 };
160: UInt32 timeout;
161: IOByteCount length;
162:
163: waitAckValue = ackValue;
164:
165: length = sizeof(data);
166: err = adbDevice->writeRegister( regNum, (UInt8 *) &data, &length );
167:
168: if( !err) {
169: timeout = kTimeoutMS / 50;
170: while( waitAckValue && timeout-- )
171: IOSleep( 50 );
172:
173: if( waitAckValue )
174: err = -3;
175: }
176: waitAckValue = 0;
177:
178: return( err );
179: }
180:
181: IOReturn AppleADBDisplay::setLogicalRegister( UInt16 address, UInt16 data )
182: {
183: IOReturn err = -1;
184: UInt32 reconnects = 3;
185:
186: while( err && reconnects-- ) {
187: err = writeWithAcknowledge( kADBReg1, address, kReg2DataRdy);
188: if( err == kIOReturnSuccess )
189: err = writeWithAcknowledge( kADBReg2, data, kReg2DataAck);
190:
191: if( err ) {
192: if( doConnect() )
193: break;
194: }
195: }
196: if( err)
197: kprintf( "%s: %x, %d\n", __FUNCTION__, address, err);
198:
199: return( err);
200: }
201:
202: IOReturn AppleADBDisplay::getLogicalRegister( UInt16 address, UInt16 * data )
203: {
204: IOReturn err = -1;
205: UInt32 reconnects = 3;
206: UInt16 value;
207: IOByteCount length;
208:
209: while ( err && reconnects--) {
210: err = writeWithAcknowledge( kADBReg1, address, kReg2DataRdy);
211: if( err == kIOReturnSuccess ) {
212: length = sizeof( value);
213: err = adbDevice->readRegister( 2, (UInt8 *)&value, &length);
214: *data = value & 0xff; // actually only 8 bits
215: }
216: if( err) {
217: if ( doConnect())
218: break;
219: }
220: }
221: if( err)
222: kprintf( "%s: %x=%x, %d\n", __FUNCTION__, address, *data, err);
223:
224: return err;
225: }
226:
227: void AppleADBDisplay::setWiggle( bool active )
228: {
229: setLogicalRegister( wiggleLADAddr, (active ? 1 : 0));
230: }
231:
232: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
233:
234: bool AppleADBDisplay::start( IOService * nub )
235: {
236: IOReturn err;
237: UInt16 data, deviceType;
238:
239: if( !super::start( nub))
240: return false;
241:
242: if( OSDynamicCast( IODisplayConnect, nub ))
243: return( true );
244:
245: assert( OSDynamicCast( IOADBDevice, nub ));
246: adbDevice = (IOADBDevice *) nub;
247:
248: if( !adbDevice->seizeForClient( this, &autoPollHandler) ) {
249: IOLog("%s: sieze failed\n", getName());
250: return( false);
251: }
252:
253: do {
254: err = doConnect();
255: if( err )
256: continue;
257:
258: err = setLogicalRegister( 0xff, 0xff);
259: if( err)
260: continue;
261:
262: err = getLogicalRegister( 0xff, &data);
263: if( err)
264: continue;
265:
266: err = getLogicalRegister( 0xff, &deviceType);
267: if( err)
268: continue;
269:
270: kprintf("%s: found AVType %d\n",
271: adbDevice->getName(), deviceType );
272:
273: err = findADBDisplayInfoForType( deviceType );
274: if( err)
275: continue;
276:
277: avDisplayID = deviceType;
278: setWiggle( false);
279:
280: registerService();
281: return( true );
282:
283: } while( false );
284:
285: adbDevice->releaseFromClient( this );
286: return( false );
287: }
288:
289:
290: bool AppleADBDisplay::tryAttach( IODisplayConnect * connect )
291: {
292: IOReturn err;
293: bool attached = false;
294: UInt32 sense, extSense;
295: IOFramebuffer * framebuffer;
296: IOIndex fbConnect;
297: UInt32 senseType;
298: enum {
299: kRSCFour = 4,
300: kRSCSix = 6,
301: kESCFourNTSC = 0x0A,
302: kESCSixStandard = 0x2B,
303: };
304:
305: do {
306:
307: framebuffer = connect->getFramebuffer();
308: fbConnect = connect->getConnection();
309: assert( framebuffer );
310:
311: if( kIOReturnSuccess != framebuffer->getAttributeForConnection(
312: fbConnect,
313: kConnectionSupportsAppleSense, NULL ))
314: continue;
315:
316: err = framebuffer->getAppleSense( fbConnect,
317: &senseType, &sense, &extSense, 0 );
318: if( err)
319: continue;
320: if( (sense != kRSCSix) || (extSense != kESCSixStandard) ) // straight-6
321: continue;
322:
323: setWiggle( true );
324: err = framebuffer->getAppleSense( fbConnect,
325: &senseType, &sense, &extSense, 0 );
326: setWiggle( false );
327: if( err)
328: continue;
329: if( (sense != kRSCFour) || (extSense != kESCFourNTSC) ) // straight-4
330: continue;
331:
332: kprintf( "%s: attached to %s\n",
333: adbDevice->getName(), framebuffer->getName() );
334:
335: attached = true;
336:
337: } while( false);
338:
339: return( attached);
340: }
341:
342:
343: IOService * AppleADBDisplay::probe( IOService * nub, SInt32 * score )
344: {
345: IODisplayConnect * connect;
346:
347: // both ADB device & display connections come here!
348:
349: do {
350: if( OSDynamicCast( IOADBDevice, nub))
351: continue;
352:
353: if( (connect = OSDynamicCast( IODisplayConnect, nub))
354: && tryAttach( connect))
355: continue;
356:
357: nub = 0;
358:
359: } while( false );
360:
361: if( nub)
362: return( super::probe( nub, score ));
363: else
364: return( 0 );
365: }
366:
367:
368:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.