[PATCH 1/3] xfree86: Add a xf86MonitorFindHDMIBlock()

walter harms wharms at bfs.de
Thu Aug 22 00:11:47 PDT 2013



Am 21.08.2013 19:25, schrieb Damien Lespiau:
> The HDMI CEA vendor specific block has some interesting information,
> such as the maximum TMDS dot clock.
> 
> v2: Don't parse CEA blocks with invalid offsets, remove spurious
>     brackets (Chris Wilson)
> 
> Signed-off-by: Damien Lespiau <damien.lespiau at intel.com>
> ---
>  hw/xfree86/ddc/interpret_edid.c | 91 +++++++++++++++++++++++++++++++++++++++++
>  hw/xfree86/ddc/xf86DDC.h        |  2 +
>  2 files changed, 93 insertions(+)
> 
> diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c
> index e6b4d5b..eff928e 100644
> --- a/hw/xfree86/ddc/interpret_edid.c
> +++ b/hw/xfree86/ddc/interpret_edid.c
> @@ -332,6 +332,97 @@ xf86ForEachVideoBlock(xf86MonPtr mon, handle_video_fn fn, void *data)
>      }
>  }
>  
> +static Bool
> +cea_db_offsets(Uchar *cea, int *start, int *end)
> +{
> +    /* Data block offset in CEA extension block */
> +    *start = CEA_EXT_MIN_DATA_OFFSET;
> +    *end = cea[2];
> +    if (*end == 0);
> +        *end = CEA_EXT_MAX_DATA_OFFSET;
> +    if (*end < CEA_EXT_MIN_DATA_OFFSET || *end > CEA_EXT_MAX_DATA_OFFSET)
> +        return FALSE;
> +    return TRUE;
> +}
> +
> +static int
> +cea_db_len(Uchar *db)
> +{
> +    return db[0] & 0x1f;
> +}
> +
> +static int
> +cea_db_tag(Uchar *db)
> +{
> +    return db[0] >> 5;
> +}
> +
> +typedef void (*handle_cea_db_fn) (Uchar *, void *);
> +
> +static void
> +cea_for_each_db(xf86MonPtr mon, handle_cea_db_fn fn, void *data)
> +{
> +    int i;
> +
> +    if (!mon)
> +        return;
> +
> +    if (!(mon->flags & EDID_COMPLETE_RAWDATA))
> +        return;
> +
> +    if (!mon->no_sections)
> +        return;
> +
> +    if (!mon->rawData)
> +        return;
> +
> +    for (i = 0; i < mon->no_sections; i++) {
> +        int start, end, offset;
> +        Uchar *ext;
> +
> +        ext = mon->rawData + EDID1_LEN * (i + 1);
> +        if (ext[EXT_TAG] != CEA_EXT)
> +            continue;
> +
> +        if (!cea_db_offsets(ext, &start, &end))
> +            continue;
> +
> +        for (offset = start;
> +             offset < end && offset + cea_db_len(&ext[i]) < end;
> +             offset += cea_db_len(&ext[offset]) + 1)
> +                fn(&ext[offset], data);
> +    }
> +}
> +
> +struct find_hdmi_block_data {
> +    struct cea_data_block *hdmi;
> +};
> +
> +static void find_hdmi_block(Uchar *db, void *data)
> +{
> +    struct find_hdmi_block_data *result = data;
> +    int oui;
> +
> +    if (cea_db_tag(db) != CEA_VENDOR_BLK)
> +        return;
> +
> +    if (cea_db_len(db) < 5)
> +        return;
> +
> +    oui = (db[3] << 16) + (db[2] << 8) + db[1];
> +    if (oui == IEEE_ID_HDMI)
> +        result->hdmi = (struct cea_data_block *)db;
> +}

result->hdmi could be undefined, is that intentional ?


re,
 wh

> +
> +struct cea_data_block *xf86MonitorFindHDMIBlock(xf86MonPtr mon)
> +{
> +    struct find_hdmi_block_data result = { NULL };
> +
> +    cea_for_each_db(mon, find_hdmi_block, &result);
> +
> +    return result.hdmi;
> +}
> +
>  xf86MonPtr
>  xf86InterpretEEDID(int scrnIndex, Uchar * block)
>  {
> diff --git a/hw/xfree86/ddc/xf86DDC.h b/hw/xfree86/ddc/xf86DDC.h
> index bdc7648..de8e718 100644
> --- a/hw/xfree86/ddc/xf86DDC.h
> +++ b/hw/xfree86/ddc/xf86DDC.h
> @@ -98,4 +98,6 @@ typedef void (*handle_video_fn) (struct cea_video_block *, void *);
>  
>  void xf86ForEachVideoBlock(xf86MonPtr, handle_video_fn, void *);
>  
> +struct cea_data_block *xf86MonitorFindHDMIBlock(xf86MonPtr mon);
> +
>  #endif


More information about the xorg-devel mailing list