1/* cc -o /tmp/itvview itvview.c -framework IOKit -framework ApplicationServices -Wall -g
2*/
3
4#include <IOKit/IOKitLib.h>
5#include <ApplicationServices/ApplicationServices.h>
6#include <IOKit/i2c/IOI2CInterface.h>
7
8#include <assert.h>
9#include <stdio.h>
10
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13void EDIDTest( IOI2CConnectRef connect )
14{
15    kern_return_t kr;
16    IOI2CRequest        request;
17    UInt8               data[128];
18    int i;
19
20    bzero( &request, sizeof(request) );
21
22    request.commFlags                   = 0;
23
24    request.sendAddress                 = 0xA0;
25    request.sendTransactionType         = kIOI2CSimpleTransactionType;
26    request.sendBuffer                  = (vm_address_t) &data[0];
27    request.sendBytes                   = 0x01;
28    data[0]                             = 0x00;
29
30    request.replyAddress                = 0xA1;
31    request.replyTransactionType        = kIOI2CSimpleTransactionType;
32    request.replyBuffer                 = (vm_address_t) &data[0];
33    request.replyBytes                  = 128;
34    bzero( &data[0], request.replyBytes );
35
36    kr = IOI2CSendRequest( connect, kNilOptions, &request );
37    assert( kIOReturnSuccess == kr );
38    printf("read result 0x%x, 0x%lx bytes\n", request.result, request.replyBytes);
39    if( kIOReturnSuccess != request.result)
40        return;
41
42    printf("    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F");
43    for( i = 0; i < request.replyBytes; i++) {
44        if( 0 == (i & 15))
45            printf("\n%02x: ", i);
46        printf("%02x ", data[i]);
47    }
48    printf("\n");
49
50}
51
52void iTVTest( IOI2CConnectRef connect )
53{
54    kern_return_t       kr;
55    IOI2CRequest        request;
56    UInt8               outData[2];
57    UInt8               inData[2];
58    int                 i;
59
60    bzero( &request, sizeof(request) );
61
62    request.commFlags           = kIOI2CUseSubAddressCommFlag;
63    request.minReplyDelay       = 0;
64
65    for( i = 0; i < 50; i++ ) {
66
67        request.sendAddress             = 0x94;
68        request.sendSubAddress          = 0x70;
69        request.sendTransactionType     = kIOI2CSimpleTransactionType;
70        request.sendBuffer              = (vm_address_t) &outData[0];
71        request.sendBytes               = 0x02;
72        outData[0]                      = i * 2;
73        outData[1]                      = 256 - i;
74
75        request.replyTransactionType    = kIOI2CNoTransactionType;
76        request.replyBytes              = 0;
77
78        kr = IOI2CSendRequest( connect, kNilOptions, &request );
79        assert( kIOReturnSuccess == kr );
80        if( 0 == i)
81            printf("write result 0x%x\n", request.result);
82        if( kIOReturnSuccess != request.result)
83            return;
84
85        request.sendTransactionType     = kIOI2CNoTransactionType;
86        request.sendBytes               = 0;
87
88        request.replyAddress            = 0x95;
89        request.replySubAddress         = 0x70;
90        request.replyTransactionType    = kIOI2CCombinedTransactionType;
91        request.replyBuffer             = (vm_address_t) &inData[0];
92        request.replyBytes              = 2;
93        bzero( &inData[0], request.replyBytes );
94
95        kr = IOI2CSendRequest( connect, kNilOptions, &request );
96        assert( kIOReturnSuccess == kr );
97        if( 0 == i)
98            printf("read result 0x%x, 0x%lx bytes\n", request.result, request.replyBytes);
99        if( kIOReturnSuccess != request.result)
100            return;
101
102//        printf("%02x %02x\n", inData[0], inData[1]);
103
104        if( (inData[0] != outData[0]) || (inData[1] != outData[1])) {
105            printf("mismatch\n");
106            break;
107        }
108    }
109    printf("compares OK\n");
110}
111/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
112
113int main( int argc, char * argv[] )
114{
115    kern_return_t kr;
116    io_service_t  framebuffer, interface;
117    IOOptionBits  bus;
118    IOItemCount   busCount;
119
120    framebuffer = CGDisplayIOServicePort(CGMainDisplayID());
121
122    {
123        io_string_t path;
124        kr = IORegistryEntryGetPath(framebuffer, kIOServicePlane, path);
125        assert( KERN_SUCCESS == kr );
126        printf("\nUsing device: %s\n", path);
127
128        kr = IOFBGetI2CInterfaceCount( framebuffer, &busCount );
129        assert( kIOReturnSuccess == kr );
130
131        for( bus = 0; bus < busCount; bus++ )
132        {
133            IOI2CConnectRef  connect;
134
135            kr = IOFBCopyI2CInterfaceForBus(framebuffer, bus, &interface);
136            if( kIOReturnSuccess != kr)
137                continue;
138
139            kr = IOI2CInterfaceOpen( interface, kNilOptions, &connect );
140
141            IOObjectRelease(interface);
142            assert( kIOReturnSuccess == kr );
143            if( kIOReturnSuccess != kr)
144                continue;
145
146            printf("\nEDID using bus %ld:\n", bus);
147            EDIDTest( connect );
148
149            printf("\niTV using bus %ld:\n", bus);
150            iTVTest( connect );
151
152            IOI2CInterfaceClose( connect, kNilOptions );
153        }
154    }
155
156    exit(0);
157    return(0);
158}
159