diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 48 |
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 { | |||
107 | * This is set if we treat the device as HDMI, instead of DVI. | 107 | * This is set if we treat the device as HDMI, instead of DVI. |
108 | */ | 108 | */ |
109 | bool is_hdmi; | 109 | bool is_hdmi; |
110 | bool has_audio; | ||
110 | 111 | ||
111 | /** | 112 | /** |
112 | * This is set if we detect output of sdvo device as LVDS and | 113 | * This is set if we detect output of sdvo device as LVDS and |
@@ -138,11 +139,15 @@ struct intel_sdvo_connector { | |||
138 | /* Mark the type of connector */ | 139 | /* Mark the type of connector */ |
139 | uint16_t output_flag; | 140 | uint16_t output_flag; |
140 | 141 | ||
142 | int force_audio; | ||
143 | |||
141 | /* This contains all current supported TV format */ | 144 | /* This contains all current supported TV format */ |
142 | u8 tv_format_supported[TV_FORMAT_NUM]; | 145 | u8 tv_format_supported[TV_FORMAT_NUM]; |
143 | int format_supported_num; | 146 | int format_supported_num; |
144 | struct drm_property *tv_format; | 147 | struct drm_property *tv_format; |
145 | 148 | ||
149 | struct drm_property *force_audio_property; | ||
150 | |||
146 | /* add the property for the SDVO-TV */ | 151 | /* add the property for the SDVO-TV */ |
147 | struct drm_property *left; | 152 | struct drm_property *left; |
148 | struct drm_property *right; | 153 | struct drm_property *right; |
@@ -1150,7 +1155,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1150 | } | 1155 | } |
1151 | if (intel_crtc->pipe == 1) | 1156 | if (intel_crtc->pipe == 1) |
1152 | sdvox |= SDVO_PIPE_B_SELECT; | 1157 | sdvox |= SDVO_PIPE_B_SELECT; |
1153 | if (intel_sdvo->is_hdmi) | 1158 | if (intel_sdvo->has_audio) |
1154 | sdvox |= SDVO_AUDIO_ENABLE; | 1159 | sdvox |= SDVO_AUDIO_ENABLE; |
1155 | 1160 | ||
1156 | if (INTEL_INFO(dev)->gen >= 4) { | 1161 | if (INTEL_INFO(dev)->gen >= 4) { |
@@ -1476,11 +1481,18 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | |||
1476 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { | 1481 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { |
1477 | status = connector_status_connected; | 1482 | status = connector_status_connected; |
1478 | intel_sdvo->is_hdmi = drm_detect_hdmi_monitor(edid); | 1483 | intel_sdvo->is_hdmi = drm_detect_hdmi_monitor(edid); |
1484 | intel_sdvo->has_audio = drm_detect_monitor_audio(edid); | ||
1479 | } | 1485 | } |
1480 | connector->display_info.raw_edid = NULL; | 1486 | connector->display_info.raw_edid = NULL; |
1481 | kfree(edid); | 1487 | kfree(edid); |
1482 | } | 1488 | } |
1483 | 1489 | ||
1490 | if (status == connector_status_connected) { | ||
1491 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); | ||
1492 | if (intel_sdvo_connector->force_audio) | ||
1493 | intel_sdvo->has_audio = intel_sdvo_connector->force_audio > 0; | ||
1494 | } | ||
1495 | |||
1484 | return status; | 1496 | return status; |
1485 | } | 1497 | } |
1486 | 1498 | ||
@@ -1787,6 +1799,21 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
1787 | if (ret) | 1799 | if (ret) |
1788 | return ret; | 1800 | return ret; |
1789 | 1801 | ||
1802 | if (property == intel_sdvo_connector->force_audio_property) { | ||
1803 | if (val == intel_sdvo_connector->force_audio) | ||
1804 | return 0; | ||
1805 | |||
1806 | intel_sdvo_connector->force_audio = val; | ||
1807 | |||
1808 | if (val > 0 && intel_sdvo->has_audio) | ||
1809 | return 0; | ||
1810 | if (val < 0 && !intel_sdvo->has_audio) | ||
1811 | return 0; | ||
1812 | |||
1813 | intel_sdvo->has_audio = val > 0; | ||
1814 | goto done; | ||
1815 | } | ||
1816 | |||
1790 | #define CHECK_PROPERTY(name, NAME) \ | 1817 | #define CHECK_PROPERTY(name, NAME) \ |
1791 | if (intel_sdvo_connector->name == property) { \ | 1818 | if (intel_sdvo_connector->name == property) { \ |
1792 | if (intel_sdvo_connector->cur_##name == temp_value) return 0; \ | 1819 | if (intel_sdvo_connector->cur_##name == temp_value) return 0; \ |
@@ -2078,6 +2105,21 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector, | |||
2078 | drm_sysfs_connector_add(&connector->base.base); | 2105 | drm_sysfs_connector_add(&connector->base.base); |
2079 | } | 2106 | } |
2080 | 2107 | ||
2108 | static void | ||
2109 | intel_sdvo_add_hdmi_properties(struct intel_sdvo_connector *connector) | ||
2110 | { | ||
2111 | struct drm_device *dev = connector->base.base.dev; | ||
2112 | |||
2113 | connector->force_audio_property = | ||
2114 | drm_property_create(dev, DRM_MODE_PROP_RANGE, "force_audio", 2); | ||
2115 | if (connector->force_audio_property) { | ||
2116 | connector->force_audio_property->values[0] = -1; | ||
2117 | connector->force_audio_property->values[1] = 1; | ||
2118 | drm_connector_attach_property(&connector->base.base, | ||
2119 | connector->force_audio_property, 0); | ||
2120 | } | ||
2121 | } | ||
2122 | |||
2081 | static bool | 2123 | static bool |
2082 | intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) | 2124 | intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) |
2083 | { | 2125 | { |
@@ -2118,6 +2160,8 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) | |||
2118 | 2160 | ||
2119 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); | 2161 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
2120 | 2162 | ||
2163 | intel_sdvo_add_hdmi_properties(intel_sdvo_connector); | ||
2164 | |||
2121 | return true; | 2165 | return true; |
2122 | } | 2166 | } |
2123 | 2167 | ||