diff options
| -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");      } | 
