Any comments ? Thanks Ma Ling
On Tue, 2009-03-24 at 14:31 +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 > adaptor 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 as HDMI device. > The patch intends to detect HDMI monitor by this rule. > > Signed-off-by: Ma Ling <[email protected]> > --- > In this version the function will use edid info directly, instead of fetching > it again, > at same time I did some clean-up,the patch need to re-base on [PATCH] drm: > read EDID extensions from monitor(v2). > > drivers/gpu/drm/drm_edid.c | 62 > ++++++++++++++++++++++++++++++++++++++++++++ > include/drm/drm_crtc.h | 1 + > 2 files changed, 63 insertions(+), 0 deletions(-) > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > index a839a28..9b72fda 100644 > --- a/drivers/gpu/drm/drm_edid.c > +++ b/drivers/gpu/drm/drm_edid.c > @@ -677,6 +677,68 @@ 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. > + * @edid: monitor EDID information > + * > + * Parse the CEA extension according to CEA-861-B. > + * Return true if HDMI, false if not or unknown. > + */ > +bool drm_detect_hdmi_monitor(struct edid *edid) > +{ > + char *edid_ext = NULL; > + int i, hdmi_id, edid_ext_num; > + int start_offset, end_offset; > + bool is_hdmi = false; > + > + /* No EDID or EDID extensions */ > + if (edid == NULL || edid->extensions == 0) > + goto end; > + > + /* Chose real EDID extension number */ > + edid_ext_num = edid->extensions > MAX_EDID_EXT_NUM ? > + MAX_EDID_EXT_NUM : edid->extensions; > + > + /* Find CEA extension */ > + for (i = 0; i < edid_ext_num; i++) { > + edid_ext = (char *)edid + EDID_LENGTH * (i + 1); > + /* This block is CEA extension */ > + if (edid_ext[0] == 0x02) > + break; > + } > + > + if (i == edid_ext_num) > + 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)) { > + /* 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) > + is_hdmi = true; > + break; > + } > + } > + > +end: > + return is_hdmi; > +} > +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..2d81578 100644 > --- a/include/drm/drm_crtc.h > +++ b/include/drm/drm_crtc.h > @@ -731,4 +731,5 @@ 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 edid *edid); > #endif /* __DRM_CRTC_H__ */ ------------------------------------------------------------------------------ -- _______________________________________________ Dri-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/dri-devel
