Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b1d7e4b4 authored by Wu Fengguang's avatar Wu Fengguang Committed by Daniel Vetter
Browse files

drm/i915: add a "force-dvi" HDMI audio mode



When HDMI-DVI converter is used, it's not only necessary to turn off
audio, but also to disable HDMI_MODE_SELECT and video infoframe. Since
the DVI mode is mainly tied to audio functionality from end user POV,
add a new "force-dvi" audio mode:

	xrandr --output HDMI1 --set audio force-dvi

Note that most users won't need to set this and happily rely on the EDID
based DVI auto detection.

Reported-by: default avatarAndrea Arcangeli <aarcange@redhat.com>
Signed-off-by: default avatarWu Fengguang <fengguang.wu@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 8ac5a6d5
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -762,6 +762,13 @@ typedef struct drm_i915_private {
	struct drm_property *force_audio_property;
} drm_i915_private_t;

enum hdmi_force_audio {
	HDMI_AUDIO_OFF_DVI = -2,	/* no aux data for HDMI-DVI converter */
	HDMI_AUDIO_OFF,			/* force turn off HDMI audio */
	HDMI_AUDIO_AUTO,		/* trust EDID */
	HDMI_AUDIO_ON,			/* force turn on HDMI audio */
};

enum i915_cache_level {
	I915_CACHE_NONE,
	I915_CACHE_LLC,
+12 −9
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ struct intel_hdmi {
	uint32_t color_range;
	bool has_hdmi_sink;
	bool has_audio;
	int force_audio;
	enum hdmi_force_audio force_audio;
	void (*write_infoframe)(struct drm_encoder *encoder,
				struct dip_infoframe *frame);
};
@@ -339,7 +339,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
	if (edid) {
		if (edid->input & DRM_EDID_INPUT_DIGITAL) {
			status = connector_status_connected;
			intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
			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);
		}
		connector->display_info.raw_edid = NULL;
@@ -347,8 +349,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
	}

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

	return status;
@@ -402,7 +405,7 @@ intel_hdmi_set_property(struct drm_connector *connector,
		return ret;

	if (property == dev_priv->force_audio_property) {
		int i = val;
		enum hdmi_force_audio i = val;
		bool has_audio;

		if (i == intel_hdmi->force_audio)
@@ -410,13 +413,13 @@ intel_hdmi_set_property(struct drm_connector *connector,

		intel_hdmi->force_audio = i;

		if (i == 0)
		if (i == HDMI_AUDIO_AUTO)
			has_audio = intel_hdmi_detect_audio(connector);
		else
			has_audio = i > 0;
			has_audio = (i == HDMI_AUDIO_ON);

		if (has_audio == intel_hdmi->has_audio)
			return 0;
		if (i == HDMI_AUDIO_OFF_DVI)
			intel_hdmi->has_hdmi_sink = 0;

		intel_hdmi->has_audio = has_audio;
		goto done;
+3 −1
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ int intel_ddc_get_modes(struct drm_connector *connector,
}

static const char *force_audio_names[] = {
	"force-dvi",
	"off",
	"auto",
	"on",
@@ -106,7 +107,8 @@ intel_attach_force_audio_property(struct drm_connector *connector)
			return;

		for (i = 0; i < ARRAY_SIZE(force_audio_names); i++)
			drm_property_add_enum(prop, i, i-1, force_audio_names[i]);
			drm_property_add_enum(prop, i, i-2,
					      force_audio_names[i]);

		dev_priv->force_audio_property = prop;
	}