A few months ago the HTPC (with my Showtime installation) refused to start. Power LED were lit, but nothing else happened. After quite some troubleshooting I realised that the machine would hang if connected to my TV. The TV did not even have to be powered in order to block the system boot. My initial thought was that somehow the DDC bus had been damaged in one way or another (ESD, short circuit, some weird ground loop or whatever). Fortunately the TV has two HDMI connectors so I just switched to the other one and everything was fine and dandy. Until a few days ago…
The same problem was now exhibited on the other HDMI port. This definitely called for some deeper analysis. I didn’t want to buy a new TV just because of this. All other parts of it worked just fine.
First approach – Open the thing and do some measurements. For some reason beyond my understanding LG had been kind enough to bundle printed schematics with the TV. This picture shows one of the HDMI connectors and the I2C EEPROM holding the EDID information for it. The only thing powered by the computer are those EDID EEPROMs.

So our prime suspects where IC1201 and IC1202 (outside of the image above), but both highlighted in this photograph of the PCB:

Initially I thought that the I2C bus was somehow locked due to either SDL or SDC constantly being pulled low. I’ve prior experience with I2C bus lockups like this due to malfunctioning hardware. So I did some measurements with my multimeter. Everything seemed OK. I had also realised that if I plugged in the HDMI cable after boot the system would not hang. It just was just not able detect the monitor even though I explicitly asked it to reprobe all monitors. So next idea was to actually try to see what was going on over the I2C bus…
I decided to sacrifice an HDMI cable and build an I2C bus snooper using the parallel port. Perhaps not the most beautiful thing I’ve made, but hey, it worked just fine.

Now, things started to get interesting. I also found some snooping code on this page. Surprisingly the snooper worked at first attempt. I didn’t even care to check that I didn’t mixed up SDA and SCL. Apparently Murphy had other things to mess up that day.
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef 00: ff ff ff ff ff ff ff ff 1e 6d 6c 75 7f d1 02 00 ........?mlu???. 10: 0b 10 01 03 80 46 27 78 ea d9 b0 a3 57 49 9c 25 ?????F'x????WI?% 20: 11 49 4b a5 6e 80 31 40 01 01 01 01 45 40 01 01 ?IK?n?1@????E@?? 30: 61 40 01 01 01 01 1b 21 50 a0 51 00 1e 30 48 88 a@?????!P?Q.?0H? 40: 35 00 bc 88 21 00 00 1c 4e 1f 00 80 51 00 1e 30 5.??!..?N?.?Q.?0 50: 40 80 37 00 bc 88 21 00 00 18 00 00 00 fc 00 33 @?7.??!..?...?.3 60: 37 4c 43 32 52 2d 5a 48 0a 20 20 20 00 00 00 fd 7LC2R-ZH? ...? 70: 00 38 4b 1f 3d 09 00 0a 20 20 20 20 20 20 01 c1 .8K?=?.? ??
If you spend some time reading more about EDID, it says that byte 00–07 is Header information “00h FFh FFh FFh FFh FFh FFh 00h”. This is clearly not what’s in my EDID ROM. Also the last byte of the EDID is a checksum byte which should be written such that if you sum all 128 bytes the sum should be zero. When I summed the bytes it ended up being 0xFE. Another evidence that the first and last byte in the EDID header has been changed from 00 to FF. The obvious strategy now was to rewrite those bytes back to zero again. So I had to build a full blown I2C interface:
This is based on the Linux kernel parport interface. I loaded the i2c_parport kernel module and run the i2cdetect tool. Nothing was found.
Well, after a fixing a few incorrect solderings I finally got it running (It’s so much easier to write software than to build hardware, that’s for sure). It did detect something at address 0×50, just where the EDID EEPROM is supposed to be located. And even when clocking out the bits myself I could confirm that the two bytes in the header were corrupted.
So now, all that was left was to modify those bytes back. Or? Not really, the EEPROM is write protected (Pin 7 is pulled low, just look at the schematics) so this is not possible. But what the heck, at least I could try it.
root@htpc:~/nvidia# i2cset 3 0x50 0x00 0x00 No size specified (using byte-data access) WARNING! This program can confuse your I2C bus, cause data loss and worse! DANGEROUS! Writing to a serial EEPROM on a memory DIMM may render your memory USELESS and make your system UNBOOTABLE! I will write to device file /dev/i2c-3, chip address 0x50, data address 0x00, data 0x00, mode byte. Continue? [y/N] y Value 0x00 written, readback matched
Wait? What’s that: ”readback matched”. It actually succeeded to write the byte?!
root@htpc:~/nvidia# i2cset 3 0x50 0x07 0x00
No size specified (using byte-data access)
WARNING! This program can confuse your I2C bus, cause data loss and worse!
DANGEROUS! Writing to a serial EEPROM on a memory DIMM
may render your memory USELESS and make your system UNBOOTABLE!
I will write to device file /dev/i2c-3, chip address 0x50, data address
0x07, data 0x00, mode byte.
Continue? [y/N] y
Value 0x00 written, readback matched
root@htpc:~/nvidia# i2cdump -r 0-127 -y 3 0x50 c
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 00 ff ff ff ff ff ff 00 1e 6d 6c 75 7f d1 02 00 ........?mlu???.
10: 0b 10 01 03 80 46 27 78 ea d9 b0 a3 57 49 9c 25 ?????F'x????WI?%
20: 11 49 4b a5 6e 80 31 40 01 01 01 01 45 40 01 01 ?IK?n?1@????E@??
30: 61 40 01 01 01 01 1b 21 50 a0 51 00 1e 30 48 88 a@?????!P?Q.?0H?
40: 35 00 bc 88 21 00 00 1c 4e 1f 00 80 51 00 1e 30 5.??!..?N?.?Q.?0
50: 40 80 37 00 bc 88 21 00 00 18 00 00 00 fc 00 33 @?7.??!..?...?.3
60: 37 4c 43 32 52 2d 5a 48 0a 20 20 20 00 00 00 fd 7LC2R-ZH? ...?
70: 00 38 4b 1f 3d 09 00 0a 20 20 20 20 20 20 01 c1 .8K?=?.? ??
Yep, the other address seemed to play along nice too.
Next I Connected it all back together again as it is supposed to be and it worked again :-)
Having initially been bothered by the fact that the bytes somehow changed even though the EEPROM is write protected I now rather believe that the write protect pin is not correctly hooked up. Either it’s left floating or the “Don’t mount” optional resistor is actually mounted. But right now I don’t care to open the TV once again just to check that. Perhaps I’ll look into it if this happens again.
Comments