|
@@ -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)
|
|
@@ -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;
|
|
|
}
|
|
|
|
|
@@ -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);
|
|
@@ -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,
|
|
|
};
|
|
|
|
|
@@ -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;
|
|
@@ -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);
|
|
|
|