1/*cc -o /tmp/i2cexample i2cexample.c -framework IOKit -framework ApplicationServices -Wall -g 2*/ 3 4 5#include <IOKit/IOKitLib.h> 6#include <ApplicationServices/ApplicationServices.h> 7#include <IOKit/i2c/IOI2CInterface.h> 8 9#include <assert.h> 10#include <stdio.h> 11#include <unistd.h> 12 13/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 14 15SInt32 EDIDSum( const UInt8 * bytes, IOByteCount len ) 16{ 17 int i,j; 18 UInt8 sum; 19 20 for (j=0; j < len; j += 128) 21 { 22 sum = 0; 23 for (i=0; i < 128; i++) 24 sum += bytes[j+i]; 25 if(sum) 26 return (j/128); 27 } 28 return (-1); 29} 30 31void EDIDDump( const UInt8 * bytes, IOByteCount len ) 32{ 33 int i; 34 35 fprintf(stderr, "/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */"); 36 for (i = 0; i < len; i++) 37 { 38 if( 0 == (i & 15)) 39 fprintf(stderr, "\n "); 40 fprintf(stderr, "0x%02x,", bytes[i]); 41 } 42 fprintf(stderr, "\n"); 43} 44 45void EDIDRead( IOI2CConnectRef connect, Boolean save ) 46{ 47 kern_return_t kr; 48 IOI2CRequest request; 49 UInt8 data[128]; 50 int i; 51 52 bzero( &request, sizeof(request) ); 53 54 request.commFlags = 0; 55 56 request.sendAddress = 0xA0; 57 request.sendTransactionType = kIOI2CSimpleTransactionType; 58 request.sendBuffer = (vm_address_t) &data[0]; 59 request.sendBytes = 0x01; 60 data[0] = 0x00; 61 62 request.replyAddress = 0xA1; 63 request.replyTransactionType = kIOI2CSimpleTransactionType; 64 request.replyBuffer = (vm_address_t) &data[0]; 65 request.replyBytes = sizeof(data); 66 bzero( &data[0], request.replyBytes ); 67 68 kr = IOI2CSendRequest( connect, kNilOptions, &request ); 69 assert( kIOReturnSuccess == kr ); 70 fprintf(stderr, "/* Read result 0x%x, 0x%lx bytes */\n", request.result, request.replyBytes); 71 if( kIOReturnSuccess != request.result) 72 return; 73 74 EDIDDump( data, request.replyBytes ); 75 76 i = EDIDSum( &data[0], request.replyBytes ); 77 78 if( i >= 0) 79 fprintf(stderr, "/* Block %d checksum bad */\n", i); 80 else 81 fprintf(stderr, "/* Checksums ok */\n"); 82 83 if( save) 84 write( STDOUT_FILENO, data, request.replyBytes ); 85} 86 87/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 88 89int main( int argc, char * argv[] ) 90{ 91 kern_return_t kr; 92 io_service_t framebuffer, interface; 93 io_string_t path; 94 IOOptionBits bus; 95 IOItemCount busCount; 96 Boolean save; 97 98 framebuffer = CGDisplayIOServicePort(CGMainDisplayID()); 99 100 { 101 kr = IORegistryEntryGetPath(framebuffer, kIOServicePlane, path); 102 assert( KERN_SUCCESS == kr ); 103 fprintf(stderr, "\n/* Using device: %s */\n", path); 104 105 kr = IOFBGetI2CInterfaceCount( framebuffer, &busCount ); 106 assert( kIOReturnSuccess == kr ); 107 108 for( bus = 0; bus < busCount; bus++ ) 109 { 110 IOI2CConnectRef connect; 111 112 fprintf(stderr, "/* Bus %ld: */\n", bus); 113 114 kr = IOFBCopyI2CInterfaceForBus(framebuffer, bus, &interface); 115 if( kIOReturnSuccess != kr) 116 continue; 117 118 kr = IOI2CInterfaceOpen( interface, kNilOptions, &connect ); 119 120 IOObjectRelease(interface); 121 assert( kIOReturnSuccess == kr ); 122 if( kIOReturnSuccess != kr) 123 continue; 124 125 save = (argc > 1) && (argv[1][0] == 's'); 126 127 EDIDRead( connect, save ); 128 129 IOI2CInterfaceClose( connect, kNilOptions ); 130 } 131 } 132 133 exit(0); 134 return(0); 135} 136 137