diff options
author | Burt P <pburt0@gmail.com> | 2019-08-24 16:45:18 -0500 |
---|---|---|
committer | Leandro A. F. Pereira <leandro@hardinfo.org> | 2019-08-28 13:15:48 +0200 |
commit | 517f726a4a61e7b18e1d290d28bcbd43a072af58 (patch) | |
tree | 0686e17efd61548e3af7c3cb6772be1404a4d67f | |
parent | 691620e2d0855ab8ea5ddedc91c65a9df6ba0cfa (diff) |
monitors: fixes for vendor oui
Signed-off-by: Burt P <pburt0@gmail.com>
-rw-r--r-- | deps/sysobj_early/include/util_edid.h | 26 | ||||
-rw-r--r-- | deps/sysobj_early/src/util_edid.c | 48 | ||||
-rw-r--r-- | modules/devices/monitors.c | 6 |
3 files changed, 53 insertions, 27 deletions
diff --git a/deps/sysobj_early/include/util_edid.h b/deps/sysobj_early/include/util_edid.h index d2fe947b..5bb4b932 100644 --- a/deps/sysobj_early/include/util_edid.h +++ b/deps/sysobj_early/include/util_edid.h @@ -32,6 +32,19 @@ typedef struct { uint32_t offset; } edid_addy; +/* OUI is stored in EDID as 24-bit little-endian, + * but lookup file from IEEE expects big-endian. + * .oui_str is .oui rendered into big-endian for + * easy lookup. */ +typedef struct { + union { + char pnp[7]; /* only needs 3+null */ + char oui_str[7]; /* needs 6+null */ + }; + uint32_t oui; + uint8_t type; /* enum VEN_TYPE_* */ +} edid_ven; + typedef struct { char *str; uint16_t len; @@ -57,6 +70,9 @@ typedef struct { uint8_t revision; uint8_t len; uint8_t bounds_ok; + + /* for vendor specific block */ + edid_ven ven; } DisplayIDBlock; typedef struct { @@ -125,6 +141,9 @@ struct edid_cea_block { edid_addy addy; int type, len; uint8_t bounds_ok; + + /* for vendor specific block */ + edid_ven ven; }; struct edid_descriptor { @@ -146,13 +165,6 @@ enum { VEN_TYPE_OUI, }; -typedef struct { - //TODO: union? - char pnp[4]; - uint32_t oui; - uint8_t type; /* enum VEN_TYPE_* */ -} edid_ven; - enum { STD_EDID = 0, STD_EEDID = 1, diff --git a/deps/sysobj_early/src/util_edid.c b/deps/sysobj_early/src/util_edid.c index 38ad6823..224c1eb8 100644 --- a/deps/sysobj_early/src/util_edid.c +++ b/deps/sysobj_early/src/util_edid.c @@ -162,7 +162,11 @@ int rpnpcpy(edid_ven *dest, edid *e, uint32_t offset) { static inline int rouicpy(edid_ven *dest, edid *e, uint32_t offset) { edid_ven ret = {.type = VEN_TYPE_OUI}; - ret.oui = r24be(e, offset, NOMASK); + ret.oui = r24le(e, offset, NOMASK); + sprintf(ret.oui_str, "%02x%02x%02x", + (ret.oui >> 16) & 0xff, + (ret.oui >> 8) & 0xff, + ret.oui & 0xff ); if (ret.oui) { *dest = ret; return 1; @@ -254,11 +258,13 @@ static void cea_block_decode(struct edid_cea_block *blk) { if (!blk->bounds_ok) return; edid *e = blk->addy.e; + static uint32_t h = 1; /* header size */ + uint32_t a = blk->addy.offset; /* start of block, includes header */ uint8_t *ptr = DPTR(blk->addy); int i; switch(blk->type) { case 0x1: /* SADS */ - for(i = 1; i <= blk->len; i+=3) { + for(i = h; i <= blk->len; i+=3) { struct edid_sad *sad = &e->sads[e->sad_count]; sad->v[0] = ptr[i]; sad->v[1] = ptr[i+1]; @@ -276,14 +282,16 @@ static void cea_block_decode(struct edid_cea_block *blk) { } break; case 0x4: /* Speaker allocation */ - e->speaker_alloc_bits = ptr[1]; + e->speaker_alloc_bits = ptr[h]; break; case 0x2: /* SVDs */ - for(i = 1; i <= blk->len; i++) + for(i = h; i <= blk->len; i++) e->svds[e->svd_count++].v = ptr[i]; break; case 0x3: /* Vendor-specific */ + rouicpy(&blk->ven, e, a+h); // TODO: + break; default: break; } @@ -300,17 +308,17 @@ static void did_block_decode(DisplayIDBlock *blk) { if (!blk->bounds_ok) return; edid *e = blk->addy.e; - uint32_t a = blk->addy.offset + 3; - + static uint32_t h = 3; /* header size */ + uint32_t a = blk->addy.offset; /* start of block, includes header */ uint8_t *u8 = DPTR(blk->addy); - int b = 3; + int b = h; edid_ven ven = {}; edid_output out = {}; if (blk) { switch(blk->type) { case 0: /* Product ID (1.x) */ /* UNTESTED */ - if (rpnpcpy(&ven, e, a) ) + if (rpnpcpy(&ven, e, a+h) ) e->ven = ven; if (u8[12] || u8[13]) { e->dom.week = u8[12]; @@ -320,13 +328,13 @@ static void did_block_decode(DisplayIDBlock *blk) { } e->did_strings[e->did_string_count].is_product_name = 1; e->did_strings[e->did_string_count].len = blk->len; - e->did_strings[e->did_string_count].str = rstr_strip(e, a+12, u8[b+11]); + e->did_strings[e->did_string_count].str = rstr_strip(e, a+h+12, u8[b+11]); e->name = e->did_strings[e->did_string_count].str; e->did_string_count++; break; case 0x20: /* Product ID */ /* UNTESTED */ - if (rouicpy(&ven, e, a) ) + if (rouicpy(&ven, e, a+h) ) e->ven = ven; if (u8[12] || u8[13]) { e->dom.week = u8[12]; @@ -336,24 +344,24 @@ static void did_block_decode(DisplayIDBlock *blk) { } e->did_strings[e->did_string_count].is_product_name = 1; e->did_strings[e->did_string_count].len = blk->len; - e->did_strings[e->did_string_count].str = rstr_strip(e, a+12, u8[b+11]); + e->did_strings[e->did_string_count].str = rstr_strip(e, a+h+12, u8[b+11]); e->name = e->did_strings[e->did_string_count].str; e->did_string_count++; break; case 0x0a: /* Serial Number (ASCII String) */ e->did_strings[e->did_string_count].is_serial = 1; e->did_strings[e->did_string_count].len = blk->len; - e->did_strings[e->did_string_count].str = rstr_strip(e, a, blk->len); + e->did_strings[e->did_string_count].str = rstr_strip(e, a+h, blk->len); e->serial = e->did_strings[e->did_string_count].str; e->did_string_count++; break; case 0x0b: /* General Purpose ASCII String */ e->did_strings[e->did_string_count].len = blk->len; - e->did_strings[e->did_string_count].str = rstr(e, a, blk->len); + e->did_strings[e->did_string_count].str = rstr(e, a+h, blk->len); e->did_string_count++; break; case 0x03: /* Type I Detailed timings */ - out.pixel_clock_khz = 10 * r24le(e, a, NOMASK); + out.pixel_clock_khz = 10 * r24le(e, a+h, NOMASK); out.horiz_pixels = 1 + (u8[b+5] << 8) + u8[b+4]; out.horiz_blanking = (u8[b+7] << 8) + u8[b+6]; out.vert_lines = 1 + (u8[b+13] << 8) + u8[b+12]; @@ -395,6 +403,11 @@ static void did_block_decode(DisplayIDBlock *blk) { edid_output_fill(&out); e->didts[e->didt_count++] = out; break; + case 0x7e: /* vendor specific data */ + case 0x7f: /* vendor specific data */ + rouicpy(&blk->ven, e, a+h); + // TODO: + break; case 0x81: /* CTA DisplayID, ... Embedded CEA Blocks */ while(b < blk->len) { int db_type = (u8[b] & 0xe0) >> 5; @@ -1197,7 +1210,12 @@ char *edid_cea_block_describe(struct edid_cea_block *blk) { blk->type, _(edid_cea_block_type(blk->type)), blk->len); break; - case 0x3: //TODO + case 0x3: /* vendor specific */ + ret = g_strdup_printf("([%x] %s) len:%d (OUI:%s) -- %s", + blk->type, _(edid_cea_block_type(blk->type)), + blk->len, blk->ven.oui_str, + hb); + break; default: ret = g_strdup_printf("([%x] %s) len:%d -- %s", blk->type, _(edid_cea_block_type(blk->type)), diff --git a/modules/devices/monitors.c b/modules/devices/monitors.c index 7fd60bf5..0dfea7d3 100644 --- a/modules/devices/monitors.c +++ b/modules/devices/monitors.c @@ -117,11 +117,7 @@ gchar *monitor_vendor_str(monitor *m, gboolean include_value, gboolean link_name strcpy(v, ven.pnp); strcpy(t, "PNP"); } else if (ven.type == VEN_TYPE_OUI) { - sprintf(v, "%02x%02x%02x", - /* file lists as big endian */ - (ven.oui >> 16) & 0xff, - (ven.oui >> 8) & 0xff, - ven.oui & 0xff ); + strcpy(v, ven.oui_str); strcpy(t, "OUI"); } |