summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-09-19 12:29:33 +0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-10-19 12:18:12 +0400
commit7f36e7edd6c1851ea1f061ddbefb6f820a0575a2 (patch)
treee4c721a0694270b79db70fad857ea5fb1e0c3162 /drivers/gpu
parentf684960ed5b902994ba6540138d910f5caf7ea2a (diff)
downloadlinux-7f36e7edd6c1851ea1f061ddbefb6f820a0575a2.tar.xz
drm/i915/sdvo: Add 'force_audio' property
Allow the user to override the detection of the sink's audio capabilities from EDID. Not all sinks support the required EDID level to specify whether they handle audio over the display connection, so allow the user to enable it manually. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c48
1 files changed, 46 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index a84224f37605..c245383cf7ed 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -107,6 +107,7 @@ struct intel_sdvo {
* This is set if we treat the device as HDMI, instead of DVI.
*/
bool is_hdmi;
+ bool has_audio;
/**
* This is set if we detect output of sdvo device as LVDS and
@@ -138,11 +139,15 @@ struct intel_sdvo_connector {
/* Mark the type of connector */
uint16_t output_flag;
+ int force_audio;
+
/* This contains all current supported TV format */
u8 tv_format_supported[TV_FORMAT_NUM];
int format_supported_num;
struct drm_property *tv_format;
+ struct drm_property *force_audio_property;
+
/* add the property for the SDVO-TV */
struct drm_property *left;
struct drm_property *right;
@@ -1150,7 +1155,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
}
if (intel_crtc->pipe == 1)
sdvox |= SDVO_PIPE_B_SELECT;
- if (intel_sdvo->is_hdmi)
+ if (intel_sdvo->has_audio)
sdvox |= SDVO_AUDIO_ENABLE;
if (INTEL_INFO(dev)->gen >= 4) {
@@ -1476,11 +1481,18 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
if (edid->input & DRM_EDID_INPUT_DIGITAL) {
status = connector_status_connected;
intel_sdvo->is_hdmi = drm_detect_hdmi_monitor(edid);
+ intel_sdvo->has_audio = drm_detect_monitor_audio(edid);
}
connector->display_info.raw_edid = NULL;
kfree(edid);
}
-
+
+ if (status == connector_status_connected) {
+ struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
+ if (intel_sdvo_connector->force_audio)
+ intel_sdvo->has_audio = intel_sdvo_connector->force_audio > 0;
+ }
+
return status;
}
@@ -1787,6 +1799,21 @@ intel_sdvo_set_property(struct drm_connector *connector,
if (ret)
return ret;
+ if (property == intel_sdvo_connector->force_audio_property) {
+ if (val == intel_sdvo_connector->force_audio)
+ return 0;
+
+ intel_sdvo_connector->force_audio = val;
+
+ if (val > 0 && intel_sdvo->has_audio)
+ return 0;
+ if (val < 0 && !intel_sdvo->has_audio)
+ return 0;
+
+ intel_sdvo->has_audio = val > 0;
+ goto done;
+ }
+
#define CHECK_PROPERTY(name, NAME) \
if (intel_sdvo_connector->name == property) { \
if (intel_sdvo_connector->cur_##name == temp_value) return 0; \
@@ -2078,6 +2105,21 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector,
drm_sysfs_connector_add(&connector->base.base);
}
+static void
+intel_sdvo_add_hdmi_properties(struct intel_sdvo_connector *connector)
+{
+ struct drm_device *dev = connector->base.base.dev;
+
+ connector->force_audio_property =
+ drm_property_create(dev, DRM_MODE_PROP_RANGE, "force_audio", 2);
+ if (connector->force_audio_property) {
+ connector->force_audio_property->values[0] = -1;
+ connector->force_audio_property->values[1] = 1;
+ drm_connector_attach_property(&connector->base.base,
+ connector->force_audio_property, 0);
+ }
+}
+
static bool
intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
{
@@ -2118,6 +2160,8 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
+ intel_sdvo_add_hdmi_properties(intel_sdvo_connector);
+
return true;
}