From b1d7e4b41fd0f72ea8149056778db5d737739305 Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Tue, 14 Feb 2012 11:45:36 +0800 Subject: [PATCH] drm/i915: add a "force-dvi" HDMI audio mode When HDMI-DVI converter is used, it's not only necessary to turn off audio, but also to disable HDMI_MODE_SELECT and video infoframe. Since the DVI mode is mainly tied to audio functionality from end user POV, add a new "force-dvi" audio mode: xrandr --output HDMI1 --set audio force-dvi Note that most users won't need to set this and happily rely on the EDID based DVI auto detection. Reported-by: Andrea Arcangeli Signed-off-by: Wu Fengguang Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 7 +++++++ drivers/gpu/drm/i915/intel_hdmi.c | 21 ++++++++++++--------- drivers/gpu/drm/i915/intel_modes.c | 4 +++- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 563d24e7b725..caec1fdb7dda 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -762,6 +762,13 @@ typedef struct drm_i915_private { struct drm_property *force_audio_property; } drm_i915_private_t; +enum hdmi_force_audio { + HDMI_AUDIO_OFF_DVI = -2, /* no aux data for HDMI-DVI converter */ + HDMI_AUDIO_OFF, /* force turn off HDMI audio */ + HDMI_AUDIO_AUTO, /* trust EDID */ + HDMI_AUDIO_ON, /* force turn on HDMI audio */ +}; + enum i915_cache_level { I915_CACHE_NONE, I915_CACHE_LLC, diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 086288e85fad..cae3e5f17a49 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -44,7 +44,7 @@ struct intel_hdmi { uint32_t color_range; bool has_hdmi_sink; bool has_audio; - int force_audio; + enum hdmi_force_audio force_audio; void (*write_infoframe)(struct drm_encoder *encoder, struct dip_infoframe *frame); }; @@ -339,7 +339,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) if (edid) { if (edid->input & DRM_EDID_INPUT_DIGITAL) { status = connector_status_connected; - intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid); + if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI) + intel_hdmi->has_hdmi_sink = + drm_detect_hdmi_monitor(edid); intel_hdmi->has_audio = drm_detect_monitor_audio(edid); } connector->display_info.raw_edid = NULL; @@ -347,8 +349,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) } if (status == connector_status_connected) { - if (intel_hdmi->force_audio) - intel_hdmi->has_audio = intel_hdmi->force_audio > 0; + if (intel_hdmi->force_audio != HDMI_AUDIO_AUTO) + intel_hdmi->has_audio = + (intel_hdmi->force_audio == HDMI_AUDIO_ON); } return status; @@ -402,7 +405,7 @@ intel_hdmi_set_property(struct drm_connector *connector, return ret; if (property == dev_priv->force_audio_property) { - int i = val; + enum hdmi_force_audio i = val; bool has_audio; if (i == intel_hdmi->force_audio) @@ -410,13 +413,13 @@ intel_hdmi_set_property(struct drm_connector *connector, intel_hdmi->force_audio = i; - if (i == 0) + if (i == HDMI_AUDIO_AUTO) has_audio = intel_hdmi_detect_audio(connector); else - has_audio = i > 0; + has_audio = (i == HDMI_AUDIO_ON); - if (has_audio == intel_hdmi->has_audio) - return 0; + if (i == HDMI_AUDIO_OFF_DVI) + intel_hdmi->has_hdmi_sink = 0; intel_hdmi->has_audio = has_audio; goto done; diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index be2c6fe07d12..7be46163f421 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c @@ -84,6 +84,7 @@ int intel_ddc_get_modes(struct drm_connector *connector, } static const char *force_audio_names[] = { + "force-dvi", "off", "auto", "on", @@ -106,7 +107,8 @@ intel_attach_force_audio_property(struct drm_connector *connector) return; for (i = 0; i < ARRAY_SIZE(force_audio_names); i++) - drm_property_add_enum(prop, i, i-1, force_audio_names[i]); + drm_property_add_enum(prop, i, i-2, + force_audio_names[i]); dev_priv->force_audio_property = prop; }