aboutsummaryrefslogtreecommitdiff
path: root/deps
diff options
context:
space:
mode:
authorBurt P <pburt0@gmail.com>2019-08-24 16:45:18 -0500
committerLeandro A. F. Pereira <leandro@hardinfo.org>2019-08-28 13:15:48 +0200
commit517f726a4a61e7b18e1d290d28bcbd43a072af58 (patch)
tree0686e17efd61548e3af7c3cb6772be1404a4d67f /deps
parent691620e2d0855ab8ea5ddedc91c65a9df6ba0cfa (diff)
monitors: fixes for vendor oui
Signed-off-by: Burt P <pburt0@gmail.com>
Diffstat (limited to 'deps')
-rw-r--r--deps/sysobj_early/include/util_edid.h26
-rw-r--r--deps/sysobj_early/src/util_edid.c48
2 files changed, 52 insertions, 22 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)),