, 2 min read
Patching Faulty EDID Information
Original post is here eklausmeier.goip.de/blog/2014/05-15-patching-faulty-edid-information.
Some computer monitors either do not provide correct EDID, or no EDID at all. An example monitor is LG E2340T. In this case you can provide a hand-crafted EDID file in xorg.conf
. For setting the correct screen resolution in the EDID file you can either use a hex-editor, or use below short C program.
The C program reads a "half-way" working EDID file and changes resolution to the required values. It does this by modifying the bytes at positions (56, 58, 59, 61) and (74, 76, 77, 79).
// This program was written by Gordian Edenhofer on 04-May-2014
// It is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
// Simple EDID Manipulation Tool
// Usage: semt [Inputfile] [X-Resolution] [Y-Resolution] [Outputfile] [Options]
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main (int argc, char *argv[]) {
int i, c, x_res, y_res, checksum = 0, debug=0;
unsigned char edid[128];
FILE *fp;
while ((c = getopt(argc,argv,"dvh")) != -1) {
// ...
}
if (argc-optind != 4) {
printf("%s: is meant to be used with the following arguments [Inputfile] [X-Resolution] [Y-Resolution] [Outputfile]\n",argv[0]);
return 1;
}
if ((fp = fopen(argv[optind],"r")) == NULL) { ... }
if (fread( edid, 1, 128, fp ) != 128) { ... }
if (fclose(fp) != 0) { ... }
x_res = atoi(argv[optind+1]);
y_res = atoi(argv[optind+2]);
// Dumping X-Resolution to EDID
edid[56] = x_res%256;
edid[58] = (x_res/256)*16;
edid[74] = x_res%256;
edid[76] = (x_res/256)*16;
// Dumping Y-Resolution to EDID
edid[59] = y_res%256;
edid[61] = (y_res/256)*16;
edid[77] = y_res%256;
edid[79] = (y_res/256)*16;
y_res = atoi(argv[optind+2]);
// Dumping X-Resolution to EDID
edid[56] = x_res%256;
edid[58] = (x_res/256)*16;
edid[74] = x_res%256;
edid[76] = (x_res/256)*16;
// Dumping Y-Resolution to EDID
edid[59] = y_res%256;
edid[61] = (y_res/256)*16;
edid[77] = y_res%256;
edid[79] = (y_res/256)*16;
// Calculating and writing the checksum
for (i=0; i<=126; ++i)
checksum += edid[i];
checksum %= 256;
edid[127] = (256-checksum)%256;
if ((fp = fopen(argv[optind+3],"w")) == NULL) { ... }
if (fwrite(edid,1,128,fp) != 128) { ... }
if (fclose(fp) != 0) { ... }
return 0;
}
The complete source code for semt.c
is in GitHub. An example EDID file is in edid.bin
.
The difficulty was to come up with the correct bytes to change. The program parse-edid
in read-edid was a very helpful guide here. parse-edid
is contained in Debian package read-edid
.
Using the modified EDID in xorg.conf
goes like this:
Section "Screen"
Identifier "Screen0"
Device "Device0"
Monitor "Monitor0"
DefaultDepth 24
Option "CustomEDID" "CRT-1:/etc/X11/LG2.bin"
# Option "UseEdid" "False"
Option "TwinView" "0"
Option "metamodes" "1920x1080 +0+0"
SubSection "Display"
Depth 24
EndSubSection
EndSection
Section "Device"
Identifier "Device0"
# Option "NoLogo" "True"
EndSection
Use either CRT-0 or CRT-1 depending on which connector of the graphic card the monitor is plugged on.
More on EDID and fixing stuff in xorg.conf: Workaround buggy HDMI audio with EDID modification. EDID standard is here: EDID standard.
Added 12-Jul-2015: There is an AUR package for semt: aur.archlinux.org/packages/semt/.