|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: /* ! 25: * Copyright (c) 1997 Apple Computer, Inc. ! 26: * ! 27: * ! 28: * HISTORY ! 29: * ! 30: * Simon Douglas 22 Oct 97 ! 31: * - first checked in. ! 32: */ ! 33: ! 34: ! 35: ! 36: #import <driverkit/ppc/IOMacOSTypes.h> ! 37: #import "IOMacOSVideo.h" ! 38: #import <driverkit/ppc/IOSmartDisplay.h> ! 39: #import <mach/mach_types.h> ! 40: #import <mach/message.h> ! 41: #import <bsd/dev/ppc/busses.h> ! 42: #import <bsd/dev/ppc/adb.h> ! 43: ! 44: @interface IOSmartDisplay:Object <IOSmartDisplayExported> ! 45: { ! 46: // used to query the framebuffer controller ! 47: id attachedFramebuffer; ! 48: UInt32 attachedRefCon; ! 49: ! 50: @private ! 51: void * priv; ! 52: ! 53: /* Reserved for future expansion. */ ! 54: int _IOSmartDisplay_reserved[2]; ! 55: } ! 56: ! 57: @end ! 58: ! 59: struct AVDeviceInfo ! 60: { ! 61: UInt8 wiggleLADAddr; ! 62: UInt32 numTimings; ! 63: const UInt32 * timings; ! 64: }; ! 65: typedef struct AVDeviceInfo AVDeviceInfo; ! 66: ! 67: @interface IOSmartADBDisplay:IOSmartDisplay ! 68: { ! 69: @private ! 70: UInt8 adbAddr; ! 71: UInt8 waitAckValue; ! 72: SInt16 avDisplayID; ! 73: const AVDeviceInfo * deviceInfo; ! 74: } ! 75: ! 76: + probeADBForDisplays; // strictly temporary! ! 77: ! 78: @end ! 79: ! 80: struct EDID { ! 81: UInt8 header[8]; ! 82: UInt8 vendorProduct[10]; ! 83: UInt8 version; ! 84: UInt8 revision; ! 85: UInt8 displayParams[5]; ! 86: UInt8 colorCharacteristics[10]; ! 87: UInt8 establishedTimings[3]; ! 88: UInt16 standardTimings[8]; ! 89: UInt8 detailedTimings[72]; ! 90: UInt8 extension; ! 91: UInt8 checksum; ! 92: }; ! 93: typedef struct EDID EDID; ! 94: ! 95: @interface IOSmartDDCDisplay:IOSmartDisplay ! 96: { ! 97: @private ! 98: EDID edid1; ! 99: ! 100: } ! 101: ! 102: @end ! 103: ! 104: ! 105: static UInt32 smInited = 0; // why does +initialize get called twice? ! 106: static IOSmartADBDisplay * ADB2SmartDisplay[ ADB_DEVICE_COUNT ]; ! 107: ! 108: @implementation IOSmartDisplay ! 109: ! 110: + findForConnection:framebuffer refCon:(UInt32)refCon ! 111: { ! 112: IOSmartADBDisplay * try; ! 113: IOSmartDisplay * found = nil; ! 114: UInt32 i; ! 115: ! 116: if( !smInited) { ! 117: smInited = YES; ! 118: [IOSmartADBDisplay probeADBForDisplays]; ! 119: } ! 120: ! 121: if( [framebuffer conformsTo:@protocol( IOFBAppleSense)]) ! 122: { ! 123: for (i = 0; (found == nil) && (i < ADB_DEVICE_COUNT); i++ ) { ! 124: try = ADB2SmartDisplay[ i ]; ! 125: found = [try attach:framebuffer refCon:refCon]; ! 126: } ! 127: } ! 128: ! 129: if( (found == nil) && [framebuffer conformsTo:@protocol( IOFBHighLevelDDCSense)]) ! 130: { ! 131: found = [[[IOSmartDDCDisplay alloc] init] attach:framebuffer refCon:refCon]; ! 132: } ! 133: ! 134: if( found == nil) ! 135: found = [[[IOSmartDisplay alloc] init] attach:framebuffer refCon:refCon]; ! 136: ! 137: return( found); ! 138: } ! 139: ! 140: - attach:framebuffer refCon:(UInt32)refCon; ! 141: { ! 142: attachedFramebuffer = framebuffer; ! 143: attachedRefCon = refCon; ! 144: return( self); ! 145: } ! 146: ! 147: - detach ! 148: { ! 149: attachedFramebuffer = nil; ! 150: return( self); ! 151: } ! 152: ! 153: - (BOOL) attached ! 154: { ! 155: return( attachedFramebuffer != nil); ! 156: } ! 157: ! 158: - (IOReturn) getDisplayInfoForMode:(IOFBTimingInformation *)mode flags:(UInt32 *)flags ! 159: { ! 160: // Pass the existing flags (from framebuffer) thru ! 161: return( noErr); ! 162: } ! 163: ! 164: - (IOReturn) ! 165: getGammaTableByIndex: ! 166: (UInt32 *)channelCount dataCount:(UInt32 *)dataCount ! 167: dataWidth:(UInt32 *)dataWidth data:(void **)data ! 168: { ! 169: return( IO_R_UNSUPPORTED); ! 170: } ! 171: @end ! 172: ! 173: @implementation IOSmartDDCDisplay ! 174: ! 175: - attach:framebuffer refCon:(UInt32)refCon ! 176: { ! 177: IOReturn err; ! 178: IOByteCount length; ! 179: ! 180: do { ! 181: if( NO == [framebuffer hasDDCConnect:refCon]) ! 182: continue; ! 183: ! 184: length = sizeof( EDID); ! 185: err = [framebuffer getDDCBlock:refCon blockNumber:1 blockType:kIOFBDDCBlockTypeEDID ! 186: options:0 data:(UInt8 *)&edid1 length:&length]; ! 187: if( err || (length != sizeof( EDID))) ! 188: continue; ! 189: ! 190: kprintf("%s EDID Version %d, Revision %d\n", [framebuffer name], ! 191: edid1.version, edid1.revision ); ! 192: if( edid1.version != 1) ! 193: continue; ! 194: #if 1 ! 195: { ! 196: int i; ! 197: ! 198: kprintf("Est: "); ! 199: for( i=0; i<3; i++) ! 200: kprintf(" 0x%02x,", edid1.establishedTimings[i] ); ! 201: kprintf("\nStd: " ); ! 202: for( i=0; i<8; i++) ! 203: kprintf(" 0x%04x,", edid1.standardTimings[i] ); ! 204: kprintf("\n"); ! 205: } ! 206: #endif ! 207: ! 208: kprintf("IOSmartDDCDisplay attach on %s\n", [framebuffer name]); ! 209: return( [super attach:framebuffer refCon:refCon]); ! 210: ! 211: } while( false); ! 212: ! 213: return([self free]); ! 214: } ! 215: ! 216: ! 217: struct TimingToEDID { ! 218: UInt32 timingID; ! 219: UInt16 standardTiming; ! 220: UInt8 establishedBit; ! 221: UInt8 spare; ! 222: }; ! 223: typedef struct TimingToEDID TimingToEDID; ! 224: ! 225: #define MAKESTD(h,a,r) ( (((h/8)-31)<<8) | (a<<6) | (r-60) ) ! 226: ! 227: static const TimingToEDID timingToEDID[] = { ! 228: { timingApple_512x384_60hz, MAKESTD( 512,1,60), 0xff, 0 }, ! 229: { timingApple_640x480_67hz, MAKESTD( 640,1,67), 0x04, 0 }, ! 230: { timingVESA_640x480_60hz, MAKESTD( 640,1,60), 0x05, 0 }, ! 231: { timingVESA_640x480_72hz , MAKESTD( 640,1,72), 0x03, 0 }, ! 232: { timingVESA_640x480_75hz, MAKESTD( 640,1,75), 0x02, 0 }, ! 233: { timingVESA_640x480_85hz, MAKESTD( 640,1,85), 0xff, 0 }, ! 234: { timingApple_832x624_75hz, MAKESTD( 832,1,75), 0x0d, 0 }, ! 235: { timingVESA_800x600_56hz, MAKESTD( 800,1,56), 0x01, 0 }, ! 236: { timingVESA_800x600_60hz, MAKESTD( 800,1,60), 0x00, 0 }, ! 237: { timingVESA_800x600_72hz, MAKESTD( 800,1,72), 0x0f, 0 }, ! 238: { timingVESA_800x600_75hz, MAKESTD( 800,1,75), 0x0e, 0 }, ! 239: { timingVESA_800x600_85hz, MAKESTD( 800,1,85), 0xff, 0 }, ! 240: { timingVESA_1024x768_60hz, MAKESTD( 1024,1,60), 0x0b, 0 }, ! 241: { timingVESA_1024x768_70hz, MAKESTD( 1024,1,70), 0x0a, 0 }, ! 242: { timingVESA_1024x768_75hz, MAKESTD( 1024,1,75), 0x09, 0 }, ! 243: { timingVESA_1024x768_85hz, MAKESTD( 1024,1,85), 0xff, 0 }, ! 244: { timingApple_1024x768_75hz, MAKESTD( 1024,1,75), 0x09, 0 }, ! 245: { timingApple_1152x870_75hz, MAKESTD( 0000,0,00), 0x17, 0 }, ! 246: { timingVESA_1280x960_75hz, MAKESTD( 1280,1,75), 0xff, 0 }, ! 247: { timingVESA_1280x1024_60hz, MAKESTD( 1280,2,60), 0xff, 0 }, ! 248: { timingVESA_1280x1024_75hz, MAKESTD( 1280,2,75), 0x08, 0 }, ! 249: { timingVESA_1280x1024_85hz, MAKESTD( 1280,2,85), 0xff, 0 }, ! 250: { timingVESA_1600x1200_60hz, MAKESTD( 1600,1,60), 0xff, 0 }, ! 251: { timingVESA_1600x1200_65hz, MAKESTD( 1600,1,65), 0xff, 0 }, ! 252: { timingVESA_1600x1200_70hz, MAKESTD( 1600,1,70), 0xff, 0 }, ! 253: { timingVESA_1600x1200_75hz, MAKESTD( 1600,1,75), 0xff, 0 }, ! 254: { timingVESA_1600x1200_80hz, MAKESTD( 1600,1,80), 0xff, 0 } ! 255: }; ! 256: ! 257: - (IOReturn) getDisplayInfoForMode:(IOFBTimingInformation *)mode flags:(UInt32 *)flags ! 258: { ! 259: const TimingToEDID * lookTiming; ! 260: UInt32 estBit, i; ! 261: enum { kSetFlags = (kDisplayModeValidFlag | kDisplayModeSafeFlag) }; ! 262: ! 263: lookTiming = timingToEDID; ! 264: while( lookTiming < (timingToEDID + sizeof( timingToEDID) / sizeof( TimingToEDID))) { ! 265: ! 266: if( lookTiming->timingID == mode->standardTimingID) { ! 267: estBit = lookTiming->establishedBit; ! 268: if( estBit != 0xff) { ! 269: if( edid1.establishedTimings[ estBit / 8 ] & (1 << (estBit % 8))) ! 270: *flags = kSetFlags; ! 271: } ! 272: for( i = 0; i < 8; i++ ) { ! 273: if( lookTiming->standardTiming == edid1.standardTimings[ i ]) { ! 274: *flags = kSetFlags; ! 275: break; ! 276: } ! 277: } ! 278: break; ! 279: } ! 280: lookTiming++; ! 281: } ! 282: ! 283: // Pass the existing flags (from framebuffer) thru ! 284: return( noErr); ! 285: } ! 286: ! 287: @end ! 288: ! 289: ! 290: #define kOrgDisplayAddr 0x7 // Original display ADB address ! 291: ! 292: #define kTelecasterADBHandlerID 0x03 ! 293: #define kSmartDisplayADBHandlerID 0xc0 ! 294: ! 295: #define kADBReg0 0x0 // Device register zero ! 296: #define kADBReg1 0x1 // Device register one ! 297: #define kADBReg2 0x2 // Device register two ! 298: #define kADBReg3 0x3 // Device register three ! 299: ! 300: #define kReg2DataRdy 0xFD // data (to be read) ready ! 301: #define kReg2DataAck 0xFE // data (just written) OK ! 302: ! 303: #define kNoDevice -1 ! 304: #define kTelecaster 0 ! 305: #define kSousaSoundUnit 1 ! 306: #define kHammerhead 2 ! 307: #define kOrca 3 ! 308: #define kWhaler 4 ! 309: #define kWarriorEZ 5 ! 310: #define kManta 6 ! 311: #define kLastDeviceType kManta ! 312: ! 313: ! 314: #define kWiggleLADAddr 0x04 // 0x0f on Telecaster & Sousa? ! 315: #define kDisplayLocalRemoteLADAddr 0x02 // lad address used in SetDisplayRemoteMode ! 316: #define kAudioKeypadEnableLADAddr 0x7D ! 317: ! 318: #define kUnknown -1 ! 319: #define kLocal 0 ! 320: #define kRemote 1 ! 321: ! 322: static const UInt32 orcaTimings[] = { ! 323: timingApple_640x480_67hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 324: timingVESA_640x480_75hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 325: timingVESA_640x480_85hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 326: timingApple_832x624_75hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 327: timingApple_1024x768_75hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 328: timingVESA_1024x768_85hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 329: timingApple_1152x870_75hz, kDisplayModeValidFlag | kDisplayModeSafeFlag | kDisplayModeDefaultFlag, ! 330: timingVESA_1280x960_75hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 331: timingVESA_1280x1024_75hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 332: timingVESA_1280x1024_85hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 333: timingVESA_1600x1200_60hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 334: timingVESA_1600x1200_65hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 335: timingVESA_1600x1200_70hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 336: timingVESA_1600x1200_75hz, kDisplayModeValidFlag | kDisplayModeSafeFlag ! 337: }; ! 338: ! 339: static const UInt32 hammerheadTimings[] = { ! 340: timingApple_640x480_67hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 341: timingApple_832x624_75hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 342: timingApple_1024x768_75hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 343: timingApple_1152x870_75hz, kDisplayModeValidFlag | kDisplayModeSafeFlag | kDisplayModeDefaultFlag, ! 344: timingVESA_1280x960_75hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 345: timingVESA_1280x1024_75hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 346: timingVESA_1600x1200_60hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 347: }; ! 348: ! 349: static const UInt32 mantaTimings[] = { ! 350: timingApple_640x480_67hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 351: timingApple_832x624_75hz, kDisplayModeValidFlag | kDisplayModeSafeFlag, ! 352: timingApple_1024x768_75hz, kDisplayModeValidFlag | kDisplayModeSafeFlag | kDisplayModeDefaultFlag, ! 353: }; ! 354: ! 355: ! 356: static const AVDeviceInfo orcaInfo = ! 357: { ! 358: kWiggleLADAddr, ! 359: sizeof( orcaTimings) / sizeof( UInt32) / 2, orcaTimings ! 360: }; ! 361: ! 362: static const AVDeviceInfo hammerheadInfo = ! 363: { ! 364: kWiggleLADAddr, ! 365: sizeof( hammerheadTimings) / sizeof( UInt32) / 2, hammerheadTimings ! 366: }; ! 367: ! 368: static const AVDeviceInfo mantaInfo = ! 369: { ! 370: kWiggleLADAddr, ! 371: sizeof( mantaTimings) / sizeof( UInt32) / 2, mantaTimings ! 372: }; ! 373: ! 374: static const AVDeviceInfo * deviceInfoTable[ kLastDeviceType + 1 ] = ! 375: { ! 376: 0, 0, &hammerheadInfo, &orcaInfo, &orcaInfo, &hammerheadInfo, &mantaInfo ! 377: }; ! 378: ! 379: ! 380: @implementation IOSmartADBDisplay ! 381: ! 382: - (IOReturn) getDisplayInfoForMode:(IOFBTimingInformation *)mode flags:(UInt32 *)flags ! 383: { ! 384: IOReturn err = noErr; ! 385: UInt32 numTimings; ! 386: const UInt32 * timings = deviceInfo->timings; ! 387: ! 388: *flags = 0; ! 389: numTimings = deviceInfo->numTimings; ! 390: while( numTimings--) { ! 391: if( mode->standardTimingID == *(timings++)) { ! 392: *flags = *timings; ! 393: break; ! 394: } ! 395: timings++; ! 396: } ! 397: return( err); ! 398: } ! 399: ! 400: - (IOReturn) doConnect ! 401: { ! 402: IOReturn err; ! 403: UInt16 value; ! 404: UInt32 retries = 9; ! 405: ! 406: while( retries--) { ! 407: value = 0x6000 | (adbAddr << 8); ! 408: err = adb_writereg( adbAddr, kADBReg3, value); ! 409: if (err != ADB_RET_OK) ! 410: continue; ! 411: IOSleep(10); ! 412: /* IODelay(1000); */ ! 413: err = adb_readreg( adbAddr, kADBReg3, &value); ! 414: if (err != ADB_RET_OK) ! 415: continue; ! 416: ! 417: if( (value & 0xF000) == 0x6000) ! 418: break; ! 419: else ! 420: err = ADB_RET_UNEXPECTED_RESULT; ! 421: } ! 422: ! 423: if( err) ! 424: kprintf( "SMDoConnect %d\n", err); ! 425: ! 426: return( err); ! 427: } ! 428: ! 429: ! 430: void SMADBHandler( int number, unsigned char *buffer, int count, void * ssp) ! 431: { ! 432: IOSmartADBDisplay * sm; ! 433: ! 434: sm = ADB2SmartDisplay[ number ]; ! 435: if( sm && count) ! 436: if( *buffer == sm->waitAckValue) ! 437: sm->waitAckValue = 0; ! 438: } ! 439: ! 440: - (IOReturn) writeWithAcknowledge:(UInt8)regNum data:(UInt16)data ackValue:(UInt8)ackValue ! 441: { ! 442: IOReturn err; ! 443: enum { kTimeoutMS = 400 }; ! 444: UInt32 timeout; ! 445: ! 446: waitAckValue = ackValue; ! 447: ! 448: err = adb_writereg(adbAddr, regNum, data); ! 449: ! 450: if( !err) { ! 451: timeout = kTimeoutMS / 10; ! 452: while( waitAckValue && timeout--) ! 453: IOSleep( 10 ); ! 454: ! 455: if( waitAckValue) ! 456: err = -3; ! 457: } ! 458: waitAckValue = 0; ! 459: return( err); ! 460: } ! 461: ! 462: ! 463: - (IOReturn) setLogicalRegister:(UInt16)address data:(UInt16) data ! 464: { ! 465: IOReturn err = -1; ! 466: UInt32 reconnects = 3; ! 467: ! 468: while( err && reconnects--) ! 469: { ! 470: err = [self writeWithAcknowledge:kADBReg1 data:address ackValue:kReg2DataRdy]; ! 471: if( err == noErr) { ! 472: err = [self writeWithAcknowledge:kADBReg2 data:data ackValue:kReg2DataAck]; ! 473: } ! 474: if( err) ! 475: if( [self doConnect]) ! 476: break; ! 477: } ! 478: ! 479: if( err) ! 480: kprintf( "SMSetLogicalRegister %x, %d\n", address, err); ! 481: ! 482: return( err); ! 483: } ! 484: ! 485: ! 486: - (IOReturn) getLogicalRegister:(UInt16)address data:(UInt16 *) data ! 487: { ! 488: IOReturn err = -1; ! 489: UInt32 reconnects = 3; ! 490: UInt16 value; ! 491: ! 492: while( err && reconnects--) ! 493: { ! 494: err = [self writeWithAcknowledge:kADBReg1 data:address ackValue:kReg2DataRdy]; ! 495: if( err == noErr) { ! 496: err = adb_readreg( adbAddr, kADBReg2, &value); ! 497: *data = value & 0xff; // actually only 8 bit ! 498: } ! 499: if( err) ! 500: if( [self doConnect]) ! 501: break; ! 502: } ! 503: ! 504: if( err) ! 505: kprintf( "SMGetLogicalRegister %x=%x, %d\n", address, *data, err); ! 506: ! 507: return( err); ! 508: } ! 509: ! 510: - setWiggle:(BOOL) active ! 511: { ! 512: IOReturn err; ! 513: ! 514: err = [self setLogicalRegister:deviceInfo->wiggleLADAddr data:(active ? 1 : 0)]; ! 515: return( self); ! 516: } ! 517: ! 518: - initForADB:(UInt8)adbBusAddr ! 519: { ! 520: IOReturn err; ! 521: UInt16 data, deviceType; ! 522: ! 523: [super init]; ! 524: adbAddr = adbBusAddr; ! 525: ! 526: ADB2SmartDisplay[ adbAddr ] = self; ! 527: ! 528: do { ! 529: ! 530: err = [self doConnect]; ! 531: if( err) ! 532: continue; ! 533: adb_register_dev( adbAddr, SMADBHandler); ! 534: err = [self setLogicalRegister:0xff data:0xff]; ! 535: if( err) ! 536: continue; ! 537: err = [self getLogicalRegister:0xff data:&data]; ! 538: if( err) ! 539: continue; ! 540: err = [self getLogicalRegister:0xff data:&deviceType]; ! 541: if( err) ! 542: continue; ! 543: ! 544: kprintf("Found ADBDisplay@%d, AVType %d\n", adbAddr, deviceType ); ! 545: ! 546: if( (deviceType > kLastDeviceType) ! 547: || (deviceInfoTable[ deviceType ] == (const AVDeviceInfo *)0) ) { ! 548: err = -49; ! 549: continue; ! 550: } ! 551: ! 552: avDisplayID = deviceType; ! 553: deviceInfo = deviceInfoTable[ deviceType ]; ! 554: [self setWiggle:NO]; ! 555: ! 556: } while( false); ! 557: ! 558: if( err) { ! 559: return( [self free]); ! 560: } ! 561: return( self); ! 562: } ! 563: ! 564: - free ! 565: { ! 566: ! 567: // adb_register_dev( adbAddr, 0); // can't unregister! ! 568: ADB2SmartDisplay[ adbAddr ] = 0; ! 569: return( [super free]); ! 570: } ! 571: ! 572: //kprintf( "%s: sense %d, ext sense %d\n", [framebuffer name], info.primarySense, info.extendedSense); ! 573: ! 574: - attach:framebuffer refCon:(UInt32)refCon ! 575: { ! 576: IOReturn err; ! 577: IOFBAppleSenseInfo info; ! 578: id attached = nil; ! 579: ! 580: if( [self attached]) ! 581: return( nil); ! 582: ! 583: do { ! 584: err = [framebuffer getAppleSense:refCon info:&info]; ! 585: if( err) ! 586: continue; ! 587: if( (info.primarySense != kRSCSix) || (info.extendedSense != kESCSixStandard)) // straight-6 ! 588: continue; ! 589: ! 590: [self setWiggle:YES]; ! 591: err = [framebuffer getAppleSense:refCon info:&info]; ! 592: [self setWiggle:NO]; ! 593: if( err) ! 594: continue; ! 595: if( (info.primarySense != kRSCFour) || (info.extendedSense != kESCFourNTSC)) // straight-4 ! 596: continue; ! 597: ! 598: kprintf("ADBDisplay@%d attached to %s\n", adbAddr, [framebuffer name]); ! 599: attached = [super attach:framebuffer refCon:refCon]; ! 600: ! 601: } while( false); ! 602: ! 603: return( attached); ! 604: } ! 605: ! 606: + probeADBForDisplays ! 607: { ! 608: struct adb_device *devp; ! 609: int i; ! 610: ! 611: devp = adb_devices; ! 612: for (i = 0; i < ADB_DEVICE_COUNT; i++, devp++) { ! 613: ! 614: if ((devp->a_flags & ADB_FLAGS_PRESENT) == 0) ! 615: continue; ! 616: // no sense looking for telecaster since its fixed freq ! 617: // && (devp->a_dev_handler != kTelecasterADBHandlerID) ) ! 618: if( (devp->a_dev_handler != kSmartDisplayADBHandlerID) ) ! 619: continue; ! 620: ! 621: [[IOSmartADBDisplay alloc] initForADB:i]; ! 622: } ! 623: return( self); ! 624: } ! 625: ! 626: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.