Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 218315
b: refs/heads/master
c: 8fe9790
h: refs/heads/master
i:
  218313: 8335f4b
  218311: 3c7bc51
v: v3
  • Loading branch information
Zhenyu Wang authored and Chris Wilson committed Oct 19, 2010
1 parent 715345b commit 5a6b958
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6d139a87b747aaebc969ac5f4eb8db766fcd9cbd
refs/heads/master: 8fe9790d1652e7c306c862ea102a5e6126b412e1
92 changes: 78 additions & 14 deletions trunk/drivers/gpu/drm/drm_edid.c
Original file line number Diff line number Diff line change
Expand Up @@ -1267,34 +1267,51 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid,
}

#define HDMI_IDENTIFIER 0x000C03
#define AUDIO_BLOCK 0x01
#define VENDOR_BLOCK 0x03
#define EDID_BASIC_AUDIO (1 << 6)

/**
* 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.
* Search EDID for CEA extension block.
*/
bool drm_detect_hdmi_monitor(struct edid *edid)
static u8 *drm_find_cea_extension(struct edid *edid)
{
char *edid_ext = NULL;
int i, hdmi_id;
int start_offset, end_offset;
bool is_hdmi = false;
u8 *edid_ext = NULL;
int i;

/* No EDID or EDID extensions */
if (edid == NULL || edid->extensions == 0)
goto end;
return NULL;

/* 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)
edid_ext = (u8 *)edid + EDID_LENGTH * (i + 1);
if (edid_ext[0] == CEA_EXT)
break;
}

if (i == edid->extensions)
return NULL;

return edid_ext;
}

/**
* 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)
{
u8 *edid_ext;
int i, hdmi_id;
int start_offset, end_offset;
bool is_hdmi = false;

edid_ext = drm_find_cea_extension(edid);
if (!edid_ext)
goto end;

/* Data block offset in CEA extension block */
Expand Down Expand Up @@ -1324,6 +1341,53 @@ bool drm_detect_hdmi_monitor(struct edid *edid)
}
EXPORT_SYMBOL(drm_detect_hdmi_monitor);

/**
* drm_detect_monitor_audio - check monitor audio capability
*
* Monitor should have CEA extension block.
* If monitor has 'basic audio', but no CEA audio blocks, it's 'basic
* audio' only. If there is any audio extension block and supported
* audio format, assume at least 'basic audio' support, even if 'basic
* audio' is not defined in EDID.
*
*/
bool drm_detect_monitor_audio(struct edid *edid)
{
u8 *edid_ext;
int i, j;
bool has_audio = false;
int start_offset, end_offset;

edid_ext = drm_find_cea_extension(edid);
if (!edid_ext)
goto end;

has_audio = ((edid_ext[3] & EDID_BASIC_AUDIO) != 0);

if (has_audio) {
DRM_DEBUG_KMS("Monitor has basic audio support\n");
goto end;
}

/* Data block offset in CEA extension block */
start_offset = 4;
end_offset = edid_ext[2];

for (i = start_offset; i < end_offset;
i += ((edid_ext[i] & 0x1f) + 1)) {
if ((edid_ext[i] >> 5) == AUDIO_BLOCK) {
has_audio = true;
for (j = 1; j < (edid_ext[i] & 0x1f); j += 3)
DRM_DEBUG_KMS("CEA audio format %d\n",
(edid_ext[i + j] >> 3) & 0xf);
goto end;
}
}
end:
return has_audio;
}
EXPORT_SYMBOL(drm_detect_monitor_audio);

/**
* drm_add_edid_modes - add modes from EDID data, if available
* @connector: connector we're probing
Expand Down
1 change: 1 addition & 0 deletions trunk/include/drm/drm_crtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,7 @@ extern int drm_mode_gamma_get_ioctl(struct drm_device *dev,
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);
extern bool drm_detect_monitor_audio(struct edid *edid);
extern int drm_mode_page_flip_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
extern struct drm_display_mode *drm_cvt_mode(struct drm_device *dev,
Expand Down

0 comments on commit 5a6b958

Please sign in to comment.