/* cc -o /tmp/itvview itvview.c -framework IOKit -framework ApplicationServices -Wall -g */ #include #include #include #include #include /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void EDIDTest( IOI2CConnectRef connect ) { kern_return_t kr; IOI2CRequest request; UInt8 data[128]; int i; bzero( &request, sizeof(request) ); request.commFlags = 0; request.sendAddress = 0xA0; request.sendTransactionType = kIOI2CSimpleTransactionType; request.sendBuffer = (vm_address_t) &data[0]; request.sendBytes = 0x01; data[0] = 0x00; request.replyAddress = 0xA1; request.replyTransactionType = kIOI2CSimpleTransactionType; request.replyBuffer = (vm_address_t) &data[0]; request.replyBytes = 128; bzero( &data[0], request.replyBytes ); kr = IOI2CSendRequest( connect, kNilOptions, &request ); assert( kIOReturnSuccess == kr ); printf("read result 0x%x, 0x%lx bytes\n", request.result, request.replyBytes); if( kIOReturnSuccess != request.result) return; printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F"); for( i = 0; i < request.replyBytes; i++) { if( 0 == (i & 15)) printf("\n%02x: ", i); printf("%02x ", data[i]); } printf("\n"); } void iTVTest( IOI2CConnectRef connect ) { kern_return_t kr; IOI2CRequest request; UInt8 outData[2]; UInt8 inData[2]; int i; bzero( &request, sizeof(request) ); request.commFlags = kIOI2CUseSubAddressCommFlag; request.minReplyDelay = 0; for( i = 0; i < 50; i++ ) { request.sendAddress = 0x94; request.sendSubAddress = 0x70; request.sendTransactionType = kIOI2CSimpleTransactionType; request.sendBuffer = (vm_address_t) &outData[0]; request.sendBytes = 0x02; outData[0] = i * 2; outData[1] = 256 - i; request.replyTransactionType = kIOI2CNoTransactionType; request.replyBytes = 0; kr = IOI2CSendRequest( connect, kNilOptions, &request ); assert( kIOReturnSuccess == kr ); if( 0 == i) printf("write result 0x%x\n", request.result); if( kIOReturnSuccess != request.result) return; request.sendTransactionType = kIOI2CNoTransactionType; request.sendBytes = 0; request.replyAddress = 0x95; request.replySubAddress = 0x70; request.replyTransactionType = kIOI2CCombinedTransactionType; request.replyBuffer = (vm_address_t) &inData[0]; request.replyBytes = 2; bzero( &inData[0], request.replyBytes ); kr = IOI2CSendRequest( connect, kNilOptions, &request ); assert( kIOReturnSuccess == kr ); if( 0 == i) printf("read result 0x%x, 0x%lx bytes\n", request.result, request.replyBytes); if( kIOReturnSuccess != request.result) return; // printf("%02x %02x\n", inData[0], inData[1]); if( (inData[0] != outData[0]) || (inData[1] != outData[1])) { printf("mismatch\n"); break; } } printf("compares OK\n"); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ int main( int argc, char * argv[] ) { kern_return_t kr; io_service_t framebuffer, interface; IOOptionBits bus; IOItemCount busCount; framebuffer = CGDisplayIOServicePort(CGMainDisplayID()); { io_string_t path; kr = IORegistryEntryGetPath(framebuffer, kIOServicePlane, path); assert( KERN_SUCCESS == kr ); printf("\nUsing device: %s\n", path); kr = IOFBGetI2CInterfaceCount( framebuffer, &busCount ); assert( kIOReturnSuccess == kr ); for( bus = 0; bus < busCount; bus++ ) { IOI2CConnectRef connect; kr = IOFBCopyI2CInterfaceForBus(framebuffer, bus, &interface); if( kIOReturnSuccess != kr) continue; kr = IOI2CInterfaceOpen( interface, kNilOptions, &connect ); IOObjectRelease(interface); assert( kIOReturnSuccess == kr ); if( kIOReturnSuccess != kr) continue; printf("\nEDID using bus %ld:\n", bus); EDIDTest( connect ); printf("\niTV using bus %ld:\n", bus); iTVTest( connect ); IOI2CInterfaceClose( connect, kNilOptions ); } } exit(0); return(0); }