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); struct intel_digital_port *intel_dig_port = hdmi_to_dig_port(intel_hdmi); struct drm_i915_private *dev_priv = connector->dev->dev_private; int ret; ret = drm_object_property_set_value(&connector->base, property, val); if (ret) return ret; if (property == dev_priv->force_audio_property) { enum hdmi_force_audio i = val; bool has_audio; if (i == intel_hdmi->force_audio) return 0; intel_hdmi->force_audio = i; if (i == HDMI_AUDIO_AUTO) has_audio = intel_hdmi_detect_audio(connector); else has_audio = (i == HDMI_AUDIO_ON); if (i == HDMI_AUDIO_OFF_DVI) intel_hdmi->has_hdmi_sink = 0; intel_hdmi->has_audio = has_audio; goto done; } if (property == dev_priv->broadcast_rgb_property) { if (val == !!intel_hdmi->color_range) return 0; intel_hdmi->color_range = val ? SDVO_COLOR_RANGE_16_235 : 0; goto done; } return -EINVAL; done: if (intel_dig_port->base.base.crtc) { struct drm_crtc *crtc = intel_dig_port->base.base.crtc; intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->fb); } return 0; }
static enum drm_connector_status intel_hdmi_detect(struct drm_connector *connector, bool force) { struct drm_device *dev = connector->dev; struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); struct intel_digital_port *intel_dig_port = hdmi_to_dig_port(intel_hdmi); struct intel_encoder *intel_encoder = &intel_dig_port->base; struct drm_i915_private *dev_priv = dev->dev_private; struct edid *edid; enum drm_connector_status status = connector_status_disconnected; DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, drm_get_connector_name(connector)); intel_hdmi->has_hdmi_sink = false; intel_hdmi->has_audio = false; intel_hdmi->rgb_quant_range_selectable = false; edid = drm_get_edid(connector, intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus)); if (edid) { if (edid->input & DRM_EDID_INPUT_DIGITAL) { status = connector_status_connected; if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI) intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid); intel_hdmi->has_audio = drm_detect_monitor_audio(edid); intel_hdmi->rgb_quant_range_selectable = drm_rgb_quant_range_selectable(edid); } kfree(edid); } if (status == connector_status_connected) { if (intel_hdmi->force_audio != HDMI_AUDIO_AUTO) intel_hdmi->has_audio = (intel_hdmi->force_audio == HDMI_AUDIO_ON); intel_encoder->type = INTEL_OUTPUT_HDMI; } return status; }
static enum drm_connector_status intel_hdmi_detect(struct drm_connector *connector, bool force) { struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); struct intel_digital_port *intel_dig_port = hdmi_to_dig_port(intel_hdmi); struct intel_encoder *intel_encoder = &intel_dig_port->base; struct drm_i915_private *dev_priv = connector->dev->dev_private; struct edid *edid; enum drm_connector_status status = connector_status_disconnected; if (IS_G4X(connector->dev) && !g4x_hdmi_connected(intel_hdmi)) return status; intel_hdmi->has_hdmi_sink = false; intel_hdmi->has_audio = false; edid = drm_get_edid(connector, intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus)); if (edid) { if (edid->input & DRM_EDID_INPUT_DIGITAL) { status = connector_status_connected; if (intel_hdmi->force_audio != HDMI_AUDIO_OFF_DVI) intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid); intel_hdmi->has_audio = drm_detect_monitor_audio(edid); } free(edid, DRM_MEM_KMS); } if (status == connector_status_connected) { if (intel_hdmi->force_audio != HDMI_AUDIO_AUTO) intel_hdmi->has_audio = (intel_hdmi->force_audio == HDMI_AUDIO_ON); intel_encoder->type = INTEL_OUTPUT_HDMI; } return status; }
static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi) { return hdmi_to_dig_port(intel_hdmi)->base.base.dev; }
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); struct intel_digital_port *intel_dig_port = hdmi_to_dig_port(intel_hdmi); struct drm_i915_private *dev_priv = connector->dev->dev_private; int ret; ret = drm_object_property_set_value(&connector->base, property, val); if (ret) return ret; if (property == dev_priv->force_audio_property) { enum hdmi_force_audio i = val; bool has_audio; if (i == intel_hdmi->force_audio) return 0; intel_hdmi->force_audio = i; if (i == HDMI_AUDIO_AUTO) has_audio = intel_hdmi_detect_audio(connector); else has_audio = (i == HDMI_AUDIO_ON); if (i == HDMI_AUDIO_OFF_DVI) intel_hdmi->has_hdmi_sink = 0; intel_hdmi->has_audio = has_audio; goto done; } if (property == dev_priv->broadcast_rgb_property) { bool old_auto = intel_hdmi->color_range_auto; uint32_t old_range = intel_hdmi->color_range; switch (val) { case INTEL_BROADCAST_RGB_AUTO: intel_hdmi->color_range_auto = true; break; case INTEL_BROADCAST_RGB_FULL: intel_hdmi->color_range_auto = false; intel_hdmi->color_range = 0; break; case INTEL_BROADCAST_RGB_LIMITED: intel_hdmi->color_range_auto = false; intel_hdmi->color_range = HDMI_COLOR_RANGE_16_235; break; default: return -EINVAL; } if (old_auto == intel_hdmi->color_range_auto && old_range == intel_hdmi->color_range) return 0; goto done; } return -EINVAL; done: if (intel_dig_port->base.base.crtc) intel_crtc_restore_mode(intel_dig_port->base.base.crtc); return 0; }