On Fri, 2009-03-20 at 15:52 +0800, Ma Ling wrote:
> sometime we need to communicate with HDMI monitor by sending audio or video 
> info frame,
> so we have to know the monitor type. However if user utilize HDMI->DVI 
> adapter to connect DVI monitor,
> hardware detection will incorrectly shows the monitor is HDMI.
> HDMI spec tell us that any device containing IEEE Registration Identifier 
> will be
> treated HDMI device. The patch intends to detect HDMI monitor by this rule.   
> 
> Any comments are welcome.

Most consumers of this API will have just fetched the EDID block for
another reason, but this code would just go and fetch it again.  It
seems like this function should probably drm_edid_block_is_hdmi(struct
edid *edid).  Or is there some problem here?

> Thanks
> Ma Ling
> 
> Signed-off-by: Ma Ling <ling...@intel.com>
> ---
>  drivers/gpu/drm/drm_edid.c |   68 
> ++++++++++++++++++++++++++++++++++++++++++++
>  include/drm/drm_crtc.h     |    2 +
>  2 files changed, 70 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index a839a28..f92babe 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -677,6 +677,74 @@ struct edid *drm_get_edid(struct drm_connector 
> *connector,
>  }
>  EXPORT_SYMBOL(drm_get_edid);
>  
> +#define HDMI_IDENTIFIER 0x000C03
> +#define VENDOR_BLOCK    0x03
> +/**
> + * drm_detect_hdmi_monitor - detect whether monitor is hdmi.
> + * @connector: connector we're probing
> + * @adapter: i2c adapter to use for DDC
> + *
> + * Parse the CEA extension according to CEA-861-B.
> + * Return true if HDMI, false if not or unknown.
> + */
> +bool drm_detect_hdmi_monitor(struct drm_connector *connector,
> +                          struct i2c_adapter *adapter)
> +{
> +     struct edid *edid;
> +     char *edid_ext = NULL;
> +     int start_offset, end_offset;
> +     int i, hdmi_id;
> +     bool ret = false;

since ret isn't "0 for success, -ESOMETHING for failure", could it get
renamed to "is_hdmi" or something?

> +
> +     edid = drm_get_edid(connector, adapter);
> +
> +     /* No EDID or EDID extensions */
> +     if (edid == NULL || edid->extensions == 0)
> +             goto end;
> +
> +     /* Find CEA extension */
> +     for (i = 0; i < edid->extensions; i++) {
> +             edid_ext = (char *)edid + EDID_LENGTH * (i + 1);
> +             /* This block is CEA extension */
> +             if (edid_ext[0] == 0x02)
> +                     break;
> +     }
> +
> +     if (i == edid->extensions)
> +             goto end;
> +
> +     /* Data block offset in CEA extension block */
> +     start_offset = 4;
> +     end_offset = edid_ext[2];
> +
> +     /*
> +      * Because HDMI identifier is in Vendor Specific Block,
> +      * search it from all data blocks of CEA extension.
> +      */
> +     for (i = start_offset; i < end_offset;
> +                     /* Increased by data block len */
> +                     i += ((edid_ext[i] & 0x1f) + 1)) {

indentation alignment

> +             /* Find vendor specific block */
> +             if ((edid_ext[i] >> 5) == VENDOR_BLOCK) {
> +                     hdmi_id = edid_ext[i + 1] | (edid_ext[i + 2] << 8) |
> +                               edid_ext[i + 3] << 16;
> +                     /* Find HDMI identifier */
> +                     if (hdmi_id == HDMI_IDENTIFIER)
> +                             ret = true;
> +                     break;
> +             }
> +     }
> +
> +end:
> +     if (edid != NULL) {
> +             connector->display_info.raw_edid = NULL;
> +             kfree(edid);
> +     }
> +
> +     return ret;
> +}
> +EXPORT_SYMBOL(drm_detect_hdmi_monitor);
> +
>  /**
>   * drm_add_edid_modes - add modes from EDID data, if available
>   * @connector: connector we're probing
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 5ded1ac..e578f55 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -731,4 +731,6 @@ extern int drm_mode_gamma_get_ioctl(struct drm_device 
> *dev,
>                                   void *data, struct drm_file *file_priv);
>  extern int drm_mode_gamma_set_ioctl(struct drm_device *dev,
>                                   void *data, struct drm_file *file_priv);
> +extern bool drm_detect_hdmi_monitor(struct drm_connector *connector,
> +                                 struct i2c_adapter *adapter);
>  #endif /* __DRM_CRTC_H__ */
-- 
Eric Anholt
e...@anholt.net                         eric.anh...@intel.com


Attachment: signature.asc
Description: This is a digitally signed message part

------------------------------------------------------------------------------
Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are
powering Web 2.0 with engaging, cross-platform capabilities. Quickly and
easily build your RIAs with Flex Builder, the Eclipse(TM)based development
software that enables intelligent coding and step-through debugging.
Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to