aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-09-19 04:29:33 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-10-19 04:18:25 -0400
commit55b7d6e8c4690047ac001026cb75a47f747db816 (patch)
treeac22b2f7c44238213f7f5ced223df19cc19e28c8
parent7f36e7edd6c1851ea1f061ddbefb6f820a0575a2 (diff)
drm/i915/hdmi: 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>
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 2d918dc046ef..6c3b2ecd59d5 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -43,6 +43,8 @@ struct intel_hdmi {
43 int ddc_bus; 43 int ddc_bus;
44 bool has_hdmi_sink; 44 bool has_hdmi_sink;
45 bool has_audio; 45 bool has_audio;
46 int force_audio;
47 struct drm_property *force_audio_property;
46}; 48};
47 49
48static struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder) 50static struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder)
@@ -170,6 +172,11 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
170 kfree(edid); 172 kfree(edid);
171 } 173 }
172 174
175 if (status == connector_status_connected) {
176 if (intel_hdmi->force_audio)
177 intel_hdmi->has_audio = intel_hdmi->force_audio > 0;
178 }
179
173 return status; 180 return status;
174} 181}
175 182
@@ -186,6 +193,46 @@ static int intel_hdmi_get_modes(struct drm_connector *connector)
186 &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter); 193 &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter);
187} 194}
188 195
196static int
197intel_hdmi_set_property(struct drm_connector *connector,
198 struct drm_property *property,
199 uint64_t val)
200{
201 struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
202 int ret;
203
204 ret = drm_connector_property_set_value(connector, property, val);
205 if (ret)
206 return ret;
207
208 if (property == intel_hdmi->force_audio_property) {
209 if (val == intel_hdmi->force_audio)
210 return 0;
211
212 intel_hdmi->force_audio = val;
213
214 if (val > 0 && intel_hdmi->has_audio)
215 return 0;
216 if (val < 0 && !intel_hdmi->has_audio)
217 return 0;
218
219 intel_hdmi->has_audio = val > 0;
220 goto done;
221 }
222
223 return -EINVAL;
224
225done:
226 if (intel_hdmi->base.base.crtc) {
227 struct drm_crtc *crtc = intel_hdmi->base.base.crtc;
228 drm_crtc_helper_set_mode(crtc, &crtc->mode,
229 crtc->x, crtc->y,
230 crtc->fb);
231 }
232
233 return 0;
234}
235
189static void intel_hdmi_destroy(struct drm_connector *connector) 236static void intel_hdmi_destroy(struct drm_connector *connector)
190{ 237{
191 drm_sysfs_connector_remove(connector); 238 drm_sysfs_connector_remove(connector);
@@ -205,6 +252,7 @@ static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
205 .dpms = drm_helper_connector_dpms, 252 .dpms = drm_helper_connector_dpms,
206 .detect = intel_hdmi_detect, 253 .detect = intel_hdmi_detect,
207 .fill_modes = drm_helper_probe_single_connector_modes, 254 .fill_modes = drm_helper_probe_single_connector_modes,
255 .set_property = intel_hdmi_set_property,
208 .destroy = intel_hdmi_destroy, 256 .destroy = intel_hdmi_destroy,
209}; 257};
210 258
@@ -218,6 +266,20 @@ static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
218 .destroy = intel_encoder_destroy, 266 .destroy = intel_encoder_destroy,
219}; 267};
220 268
269static void
270intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector)
271{
272 struct drm_device *dev = connector->dev;
273
274 intel_hdmi->force_audio_property =
275 drm_property_create(dev, DRM_MODE_PROP_RANGE, "force_audio", 2);
276 if (intel_hdmi->force_audio_property) {
277 intel_hdmi->force_audio_property->values[0] = -1;
278 intel_hdmi->force_audio_property->values[1] = 1;
279 drm_connector_attach_property(connector, intel_hdmi->force_audio_property, 0);
280 }
281}
282
221void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) 283void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
222{ 284{
223 struct drm_i915_private *dev_priv = dev->dev_private; 285 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -279,6 +341,8 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
279 341
280 drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs); 342 drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs);
281 343
344 intel_hdmi_add_properties(intel_hdmi, connector);
345
282 intel_connector_attach_encoder(intel_connector, intel_encoder); 346 intel_connector_attach_encoder(intel_connector, intel_encoder);
283 drm_sysfs_connector_add(connector); 347 drm_sysfs_connector_add(connector);
284 348