Beruflich Dokumente
Kultur Dokumente
Even though exact replacement screen for Lenovo laptops can be bought through for example Ebay,
these will not be recognized due to Lenovo’s EDID white-listing, presumably in the BIOS. Screens that
are not recognized will have their brightness control to be stuck at maximum under Windows (Linux
and MacOS ignore this white-listing)
A solution to this problem is to change the EDID of the replacement screen to match an officially
recognized, white-listed EDID.
The EDID is stored in an EEPROM on the LCD panel, which is read out by the graphics driver through
I2C. In almost all cases the chip is write protected to prevent tampering. Most often this write
protection is implemented through hardware: when one of the pins of the EEPROM is pulled high, it
cannot be written to.
Unless you are a lucky one who has a non-write protected screen, you have to break-out the chip.
The easiest is to connect an Arduino to the EEPROM chip directly and by-pass the write protect.
Note: To find out what is ground on a PCB, go around with your multimeter connectivity check.
Ground is usually one big connected plane on the PCB, and many capacitors (the big square grey
blocks) are connected to it (usually to regulate voltage ripples). The I2C pins, SCL and SDA, are
(almost) always connected through ‘pull-up’ resistors to Vcc. Often these are 4.7kOhm resistors. Look
for those to find out what is Vcc, using your resistance measurement function on the multimeter.
Pin 7 is the Write Protect pin. Having the screen disconnected from the laptop, with a multimeter I
verified the pin out. The SCL and SDA pins, used for the I2C connection, were connected to Vcc
through two 4.7kOhm pull-up resistors. The WP was connected to Vcc through 2.7kOhm, therefore
enabling the write-protect. Vss was connected to ground, as well as A0 and A1. A2 was connected
also connected to Vss, meaning that according to the datasheet the I2C address should be 0x54.
Connecting Arduino to screen
I was very happy to find break-out pins for the EEPROM on the other side of the PCB. With a
multimeter I verified that all were directly connected to the chip, except for the Vcc, which showed
some weird resistance to ground, so I ignored it, instead soldering a wire to a big capacitor which was
connected directly to the Vcc on the chip.
Below you can see the break-out pins on the other side of the screen PCB. At first I tried to just short
the write-protect pin (left) to ground, and try to program the chip directly from linux, but this didn’t
work. I suspect there is a chip in between that regulates communication to the EEPROM, as Linux
listed the screen on a different I2C address (0x50). Note that I didn’t use such clips when connecting
to the Arduino. They are way too big and came loose easily. I had some smaller hook-clips lying
around, but you might have to solder to the pads to ensure a good and secure connection.
A note on voltages & arduino!
With the screen connected I read out from the Vcc that the EEPROM chip operates on 2.5V.
Furthermore, I found some 3.3V on some other locations. Arduinos typically operate at 5V, so you
should not connect an Arduino directly to the LCD screen.
However, the EEPROM chips themselves are usually 5V tolerant (see the datasheet). So what I did was
power the chip with an external power source at 2.5V, but I connected the I2C pins from the Arduino
directly (= 5V). I didn’t notice anything weird, and everything was fine afterwards, so I guess it was
fine.You can add a current limiting resistor in series on the I2C line to have a little bit more safety, but
I do recommend a level shifter (make 5V -> 3.3V or 2.5V and vice versa) to be on the safe side.
In summary:
- Connect Vcc to a 2.5V power supply (if you don’t have that, you can try the 3.3V out of the
Arduino at your own risk)
- Connect all the grounds (power supply, EEPROM and Arduino) to one another. This is
important to make sure they are all referencing voltages to the same ground, and nothing is
‘floating’.
- Connect SDA to the SDA pin of your Arduino through a level shifter, or directly if you dare.
- Connect SCL to the SCL pin of your Arduino through a level shifter, or directly if you dare.
- Connect the WP (write-protect) pin to any other digital pin on the Arduino.
To find out what are the I2C pins of your arduino, see https://www.arduino.cc/en/Reference/Wire
http://playground.arduino.cc/Main/I2cScanner
Upload that to the Arduino, run it, and see what pops up. In my case I saw only one device on port
0x54, which was as expected.
If you find multiple devices, you can query each of them in the next step.
http://www.hobbytronics.co.uk/arduino-external-eeprom
I changed it a bit to suit my needs. The following code checks the first 256 bytes of the EEPROM.
Make sure the address (here named disk1) and where you connected the Write Protect to, is correct.
(Note I haven’t actually tested this code! It is only slightly modified and it should be correct, but I
just typed it up. Anyway, not much can go wrong with reading if the code turns out to be incorrect,
so trying it is quite safe).
The result should look like 128 hexdecimals representing the EDID, and then 128 times 0xFF or 0x00.
You should copy the result in some text document to have a backup in case you need to put it back.
#include <Wire.h>
void setup(void)
{
digitalWrite(WP_PIN, HIGH); //enable write protect to be safe
Serial.begin(9600);
Wire.begin();
for (unsigned int address = 0; address < 256; address++) //first 256
bytes
{
Serial.print(readEEPROM(disk1, address), HEX);
Serial.print(' '); //a space to separate the numbers
if (address % 16 == 0) Serial.println(); //new line every 16 numbers
for readability
}
}
void loop(){}
delay(5);
}
Wire.beginTransmission(deviceaddress);
Wire.write(eeaddress);
Wire.endTransmission();
Wire.requestFrom(deviceaddress,1);
return rdata;
}
Change the hexadecimals in the array in the code below to the EDID you want to flash. Again, this
code is NOT tested, so use at your own risk.
#include <Wire.h>
char lenovo_EDID[128] =
{0x83,0x84,0xdc,0x85,0x27,0x1f,0x38,0x11,0x61,0x02,0xa9,0x4f,0x31,0x95,0x0d
,0x8e,0x7b,0xbd,0x10,0xd1,0x8e,0xfb,0xdc,0xe3,0x5a,0x16,0x38,0x3a,0xa3,0x20
,0xbe,0x5d,0x08,0x68,0xa5,0x0c,0xf2,0xfb,0xa3,0x92,0xc9,0x75,0x5b,0x4b,0x85
,0x67,0x5a,0xb0,0x32,0x5e,0x5e,0x59,0x55,0x43,0x10,0xd4,0x96,0x83,0x5b,0x23
,0x75,0xbf,0x28,0xc6,0xb9,0xd9,0x07,0xcc,0x89,0x4b,0x09,0xd7,0xab,0xcc,0x96
,0xcb,0xda,0x99,0x27,0x2d,0x7e,0x13,0x0a,0xd4,0xd5,0x98,0xbd,0xe7,0x26,0xc1
,0xb5,0x62,0x77,0x56,0x64,0x67,0x41,0xec,0x45,0xa3,0x50,0xc5,0x94,0x45,0x94
,0xfb,0xb6,0x4b,0xbb,0x3e,0x9c,0x95,0xcb,0xa1,0xa4,0x28,0xe4,0x52,0xa0,0xcf
,0x29,0x5e,0x7b,0xa9,0xfc,0xea,0x27,0xee};
void setup(void)
{
digitalWrite(WP_PIN, LOW); //disable write protect to be safe
Serial.begin(9600);
Wire.begin();
}
}
void loop(){}
delay(5);
}
Wire.beginTransmission(deviceaddress);
Wire.write(eeaddress);
Wire.endTransmission();
Wire.requestFrom(deviceaddress,1);
return rdata;
}
Voilá! You should now have flashed the new Lenovo EDID. Change the code back to reading, and
verify if indeed the right EDID is now on the EEPROM. Install your screen back into your laptop, and
see if the brightness control now works!