From: Martin Mares Date: Sat, 7 Nov 2015 19:00:48 +0000 (+0100) Subject: edid: Moved to a separate repository X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=23578f82f8ad51c14dc23467d41a9f80a7ff49aa;p=misc.git edid: Moved to a separate repository --- diff --git a/edid-drm b/edid-drm deleted file mode 100755 index dde382d..0000000 --- a/edid-drm +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -set -e -for a in /sys/class/drm/card*-* ; do - if [ -f $a/edid -a "$(cat 2>/dev/null $a/enabled)" = enabled ] ; then - echo "### $(basename $a) ###" - echo - ./edid <$a/edid - echo - fi -done diff --git a/edid.c b/edid.c deleted file mode 100644 index d6972d1..0000000 --- a/edid.c +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Parse VESA Extended Display Identification Data - * - * (c) 2011 Martin Mares - * - * This program can be distributed and used under the terms - * of the GNU General Public License version 2 or later. - */ - -#include -#include -#include -#include -#include - -typedef unsigned int uns; -typedef unsigned char byte; - -static byte edid[128]; -static int version; - -static void -#ifdef __GNUC__ - __attribute__((format(printf,1,2))) - __attribute__((noreturn)) -#endif -die(char *msg, ...) -{ - va_list args; - va_start(args, msg); - fprintf(stderr, "edid: "); - vfprintf(stderr, msg, args); - fputc('\n', stderr); - va_end(args); - exit(1); -} - -static uns -u16_le(byte *p) -{ - return p[0] | (p[1] << 8); -} - -static uns -u32_le(byte *p) -{ - return u16_le(p) | (u16_le(p+2) << 16); -} - -static uns -B(uns x) -{ - return x ? '+' : '-'; -} - -static void -show_model(byte *p) -{ - printf("Model: %c%c%c %04x #%u\n", - ('A' - 1 + ((p[0] >> 2) & 0x1f)), - ('A' - 1 + ((p[0] & 3) << 3) | ((p[1] & 0xe0) >> 5)), - ('A' - 1 + (p[1] & 0x1f)), - u16_le(p+2), - u32_le(p+4)); - printf("Manufactured: %d week %d\n", p[9] + 1990, p[8]); -} - -static void -show_basic(byte *p) -{ - uns input = p[0]; - if (input & 0x80) - printf("Input: Digital DFP%c\n", B(input & 1)); - else - printf("Input: Analog SigLev=%d Setup%c SepSync%c CompSync%c GreenSync%c SerrSync%c\n", - ((input >> 5) & 3), - B(input & 0x10), - B(input & 0x08), - B(input & 0x04), - B(input & 0x02), - B(input & 0x01)); - - printf("Image size: %dx%dcm\n", p[1], p[2]); - if (p[3] == 0xff) - printf("Gamma: not given\n"); - else - printf("Gamma: %d.%02d\n", (p[3] / 100) + 1, p[3] % 100); - - uns flags = p[4]; - static const char * const types[4] = { "Mono/Gray", "RGB", "NonRGB", "Unknown" }; - printf("Flags: Suspend%c Standby%c ActiveOff%c Colors=%s HasSRGB%c PrefTiming%c GTF%c\n", - B(flags & 0x80), - B(flags & 0x40), - B(flags & 0x20), - types[(flags >> 3) & 3], - B(flags & 0x04), - B(flags & 0x02), - B(flags & 0x01)); -} - -static void -show_color(byte *p) -{ - uns rx = 4*p[2] | ((p[0] >> 6) & 3); - uns ry = 4*p[3] | ((p[0] >> 4) & 3); - uns gx = 4*p[4] | ((p[0] >> 2) & 3); - uns gy = 4*p[5] | ((p[0] ) & 3); - uns bx = 4*p[5] | ((p[1] >> 6) & 3); - uns by = 4*p[7] | ((p[1] >> 4) & 3); - uns wx = 4*p[8] | ((p[1] >> 2) & 3); - uns wy = 4*p[9] | ((p[1] ) & 3); -#define C(c) ((double)c / 1024) - printf("Chromaticity: R=(%.3f,%.3f) G=(%.3f,%.3f) B=(%.3f,%.3f) W=(%.3f,%.3f)\n", - C(rx), C(ry), C(gx), C(gy), C(bx), C(by), C(wx), C(wy)); -#undef C -} - -static void -show_timings(byte *p) -{ - static const char * const estab_timings[24] = { - "720x400@70", - "720x400@88", - "640x480@60", - "640x480@67", - "640x480@72", - "640x480@75", - "800x600@56", - "800x600@60", - "800x600@72", - "800x600@75", - "832x624@75", - "1024x768@87i", - "1024x768@60", - "1024x768@70", - "1024x768@75", - "1280x1024@75", - "MFG7", - "MFG6", - "MFG5", - "MFG4", - "MFG3", - "MFG2", - "MFG1", - "MFG0", - }; - printf("Basic timings:"); - for (int i=0; i<24; i++) - if (p[i/8] & (0x80 >> (i%8))) - printf(" %s", estab_timings[i]); - printf("\n"); - - printf("Extended timings:"); - for (int i=0; i<8; i++) - { - byte *q = p + 3 + 2*i; - if (q[0] == 1 && q[1] == 1) - continue; - uns h = (31 + q[0]) * 8; - uns v; - switch (q[1] >> 6) - { - case 0: - if (version < 0x0103) - v = h; - else - v = 10*h/16; - break; - case 1: - v = 3*h/4; - break; - case 2: - v = 4*h/5; - break; - default: - v = 9*h/16; - break; - } - printf(" %dx%d@%d", h, v, 60 + (q[1] & 0x3f)); - } - printf("\n"); -} - -static void -show_detailed_timing(byte *p) -{ - uns hactive = p[2] | ((p[4] << 4) & 0xf00); - uns hblank = p[3] | ((p[4] << 8) & 0xf00); - uns vactive = p[5] | ((p[7] << 4) & 0xf00); - uns vblank = p[6] | ((p[7] << 8) & 0xf00); - uns hs_offset = p[8] | ((p[11] << 2) & 0x300); - uns hs_width = p[9] | ((p[11] << 4) & 0x300); - uns vs_offset = (p[10] >> 4) | ((p[11] << 2) & 0x30); - uns vs_width = (p[10] & 0xf) | ((p[11] << 4) & 0x30); - uns hsize = p[12] | ((p[14] << 4) & 0xf00); - uns vsize = p[13] | ((p[14] << 8) & 0xf00); - uns hborder = p[15]; - uns vborder = p[16]; - - printf("Detailed timing: %dx%d (%.1f Hz)\n", - hactive, vactive, - u16_le(p) * 10000. / (hactive+hblank) / (vactive+vblank)); - printf("\tPixClk: %.2fMHz\n", u16_le(p) / 100.); - printf("\tH: Active=%d Blank=%d SyncOffset=%d SyncWidth=%d Border=%d\n", - hactive, hblank, hs_offset, hs_width, hborder); - printf("\tV: Active=%d Blank=%d SyncOffset=%d SyncWidth=%d Border=%d\n", - vactive, vblank, vs_offset, vs_width, vborder); - printf("\tSize: %dx%dmm\n", hsize, vsize); - - uns flags = p[17]; - uns stereo = ((flags >> 4) & 6) | (flags & 1); - uns input = (flags >> 3) & 3; - if (stereo >= 2) - printf("\tStereo mode: #%d\n", stereo); - - static const char * const input_types[4] = { "AnalogComposite", "BipolarAnalogComposite", "DigitalComposite", "DigitalSeparate" }; - printf("\tInput: %s", input_types[input]); - if (input < 3) - printf(" Serrate%c", B(flags & 4)); - else - printf(" VPolarity%c", B(flags & 4)); - if (input < 2) - printf(" OnRGB%c", B(flags & 2)); - else if (input == 2) - printf(" CompPolarity%c", B(flags & 2)); - else - printf(" HPolarity%c", B(flags & 2)); - printf("\n"); - - if (hsize && vsize) - printf("\tCalculated DPI: %dx%d\n", - (int)(hactive / (hsize / 25.4)), - (int)(vactive / (vsize / 25.4))); -} - -static void -show_ascii(char *field, byte *p, uns len) -{ - printf("%s: ", field); - while (len--) - { - if (*p == '\n') - break; - else if (*p >= 0x20 && *p <= 0x7e) - putchar(*p); - else - printf("<%02x>", *p); - p++; - } - putchar('\n'); -} - -static void -show_descriptor(byte *p) -{ - switch (p[3]) - { - case 0xff: // Serial number - show_ascii("Serial", p+5, 13); - break; - case 0xfe: // ASCII data - show_ascii("Comment", p+5, 13); - break; - case 0xfd: // Range limits - printf("Limits: Vert=%d-%dHz Horiz=%d-%dkHz PixClk=%dMHz\n", - p[5], p[6], p[7], p[8], p[9]*10); - switch (p[10]) - { - case 0: // No secondary timing formula - break; - case 2: // Secondary GTF - printf("Secondary GTF parameters: fStart=%dkHz C=%.1f M=%d K=%d J=%.1f\n", - p[12]*2, p[13]/2., u16_le(p+14), p[16], p[17]/2.); - break; - default: - printf("Unidentified secondary timing formula #%02x\n", p[10]); - } - break; - case 0xfc: // Monitor name - show_ascii("Monitor name", p+5, 13); - break; - case 0xfb: // Color point - printf("Color point: [...]\n"); - break; - case 0xfa: // More standard timings - printf("More standard timings: [...]\n"); - break; - case 0x10: // Dummy descriptor -- entry unused - return; - default: - printf("Unknown descriptor type %02x\n", p[3]); - } -} - -static void -show_edid(void) -{ - if (memcmp(edid, "\000\377\377\377\377\377\377\000", 8)) - die("Invalid EDID signature, giving up"); - int ver = edid[0x12]; - int rev = edid[0x13]; - printf("EDID %d.%d\n", ver, rev); - version = (ver << 8) | rev; - - byte sum = 0; - for (int i=0; i<128; i++) - sum += edid[i]; - if (sum) - printf("Invalid checksum: off by %02x\n", sum); - - show_model(edid + 8); - show_basic(edid + 0x14); - show_color(edid + 0x19); - show_timings(edid + 0x23); - for (int i=0; i<4; i++) - { - byte *p = edid + 0x36 + 18*i; - if (p[0] || p[1]) - show_detailed_timing(p); - else - show_descriptor(p); - } - - if (edid[0x7e]) - printf("### %d extension blocks follow, but they are not supported yet ###\n", edid[0x7e]); -} - -static void read_binary(void) -{ - int c = read(0, edid, 128); - if (c < 0) - die("Read error: %m"); - else if (c < 128) - die("Read only %d bytes, need 128", c); -} - -static void -read_xorg_log(void) -{ - char line[1024]; - int mode = 0; - int cnt = 0; - - while (fgets(line, sizeof(line), stdin)) - { - if (!mode) - { - if (strstr(line, "EDID (in hex):")) - mode = 1; - } - else - { - char *c = strchr(line, '\n'); - if (!c) - goto parseerr; - cnt += 16; - for (int i=0; i<32; i++) - { - if (c == line) - goto parseerr; - int x = *--c; - if (x >= '0' && x <= '9') - x -= '0'; - else if (x >= 'A' && x <= 'F') - x -= 'A' - 10; - else if (x >= 'a' && x <= 'f') - x -= 'a' - 10; - else - goto parseerr; - if (!(i % 2)) - edid[cnt-1-i/2] = x; - else - edid[cnt-1-i/2] |= x << 4; - } - if (c > line && c[-1] != ' ' && c[-1] != '\t') - goto parseerr; - if (cnt == 128) - return; - } - } - if (!cnt) - die("No EDID log found"); - else - die("EDID log found, but it is too short (only %d bytes)", cnt); - -parseerr: - die("EDID log parse error at: %s", line); -} - -static void -show_hex(void) -{ - printf("\n"); - for (int i=0; i<128; i+=16) - { - printf("@%02x:", i); - for (int j=0; j<16; j++) - printf(" %02x", edid[i+j]); - printf("\n"); - } -} - -static void -usage(void) -{ - fprintf(stderr, "Usage: edid \n\n\ -Options:\n\ --l\t\tParse input as Xorg log file and try to find EDID dump there\n\ --x\t\tShow hexdump of the whole EDID block\n\ -"); - exit(1); -} - -int main(int argc, char **argv) -{ - int opt; - int hex_mode = 0; - int log_mode = 0; - - while ((opt = getopt(argc, argv, "xl")) >= 0) - switch (opt) - { - case 'l': - log_mode = 1; - break; - case 'x': - hex_mode = 1; - break; - default: - usage(); - } - if (optind < argc) - usage(); - - if (log_mode) - read_xorg_log(); - else - read_binary(); - - show_edid(); - - if (hex_mode) - show_hex(); - return 0; -}