[Intel-gfx] [RFC][PATCH] drm: detect hdmi monitor by hdmi identifier (v1)

Ma Ling ling.ma at intel.com
Tue Mar 24 07:29:35 CET 2009


On Sat, 2009-03-21 at 04:03 +0800, Eric Anholt wrote:
> 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 , I agree, fixed in next version.
> 
> > Thanks
> > Ma Ling
> > 
> > Signed-off-by: Ma Ling <ling.ma at 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?
fixed.
> 
> > +
> > +	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
fixed.
> 
> > +		/* 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__ */




More information about the Intel-gfx mailing list