Skip to content

Commit

Permalink
drm/i915/hdmi: Add 'force_audio' property
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Chris Wilson committed Oct 19, 2010
1 parent 7f36e7e commit 55b7d6e
Showing 1 changed file with 64 additions and 0 deletions.
64 changes: 64 additions & 0 deletions drivers/gpu/drm/i915/intel_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ struct intel_hdmi {
int ddc_bus;
bool has_hdmi_sink;
bool has_audio;
int force_audio;
struct drm_property *force_audio_property;
};

static struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder)
Expand Down Expand Up @@ -170,6 +172,11 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
kfree(edid);
}

if (status == connector_status_connected) {
if (intel_hdmi->force_audio)
intel_hdmi->has_audio = intel_hdmi->force_audio > 0;
}

return status;
}

Expand All @@ -186,6 +193,46 @@ static int intel_hdmi_get_modes(struct drm_connector *connector)
&dev_priv->gmbus[intel_hdmi->ddc_bus].adapter);
}

static int
intel_hdmi_set_property(struct drm_connector *connector,
struct drm_property *property,
uint64_t val)
{
struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
int ret;

ret = drm_connector_property_set_value(connector, property, val);
if (ret)
return ret;

if (property == intel_hdmi->force_audio_property) {
if (val == intel_hdmi->force_audio)
return 0;

intel_hdmi->force_audio = val;

if (val > 0 && intel_hdmi->has_audio)
return 0;
if (val < 0 && !intel_hdmi->has_audio)
return 0;

intel_hdmi->has_audio = val > 0;
goto done;
}

return -EINVAL;

done:
if (intel_hdmi->base.base.crtc) {
struct drm_crtc *crtc = intel_hdmi->base.base.crtc;
drm_crtc_helper_set_mode(crtc, &crtc->mode,
crtc->x, crtc->y,
crtc->fb);
}

return 0;
}

static void intel_hdmi_destroy(struct drm_connector *connector)
{
drm_sysfs_connector_remove(connector);
Expand All @@ -205,6 +252,7 @@ static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.detect = intel_hdmi_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = intel_hdmi_set_property,
.destroy = intel_hdmi_destroy,
};

Expand All @@ -218,6 +266,20 @@ static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
.destroy = intel_encoder_destroy,
};

static void
intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;

intel_hdmi->force_audio_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE, "force_audio", 2);
if (intel_hdmi->force_audio_property) {
intel_hdmi->force_audio_property->values[0] = -1;
intel_hdmi->force_audio_property->values[1] = 1;
drm_connector_attach_property(connector, intel_hdmi->force_audio_property, 0);
}
}

void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
{
struct drm_i915_private *dev_priv = dev->dev_private;
Expand Down Expand Up @@ -279,6 +341,8 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)

drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs);

intel_hdmi_add_properties(intel_hdmi, connector);

intel_connector_attach_encoder(intel_connector, intel_encoder);
drm_sysfs_connector_add(connector);

Expand Down

0 comments on commit 55b7d6e

Please sign in to comment.