Commit f5ce4057 authored by Russell King's avatar Russell King
Browse files

drm: bridge/dw_hdmi-ahb-audio: parse ELD from HDMI driver



Parse the ELD (EDID like data) stored from the HDMI driver to restrict
the sample rates and channels which are available to ALSA.  This causes
the ALSA device to reflect the capabilities of the overall audio path,
not just what is supported at the HDMI source interface level.

Tested-by: default avatarFabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 7ed6c665
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ config DRM_DW_HDMI_AHB_AUDIO
	tristate "Synopsis Designware AHB Audio interface"
	depends on DRM_DW_HDMI && SND
	select SND_PCM
	select SND_PCM_ELD
	select SND_PCM_IEC958
	help
	  Support the AHB Audio interface which is part of the Synopsis
+6 −0
Original line number Diff line number Diff line
@@ -12,11 +12,13 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <drm/bridge/dw_hdmi.h>
#include <drm/drm_edid.h>

#include <sound/asoundef.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/pcm.h>
#include <sound/pcm_drm_eld.h>
#include <sound/pcm_iec958.h>

#include "dw_hdmi-audio.h"
@@ -286,6 +288,10 @@ static int dw_hdmi_open(struct snd_pcm_substream *substream)

	runtime->hw = dw_hdmi_hw;

	ret = snd_pcm_hw_constraint_eld(runtime, dw->data.eld);
	if (ret < 0)
		return ret;

	ret = snd_pcm_limit_hw_rates(runtime);
	if (ret < 0)
		return ret;
+1 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ struct dw_hdmi_audio_data {
	void __iomem *base;
	int irq;
	struct dw_hdmi *hdmi;
	u8 *eld;
};

#endif
+3 −0
Original line number Diff line number Diff line
@@ -1533,6 +1533,8 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
		drm_mode_connector_update_edid_property(connector, edid);
		ret = drm_add_edid_modes(connector, edid);
		/* Store the ELD */
		drm_edid_to_eld(connector, edid);
		kfree(edid);
	} else {
		dev_dbg(hdmi->dev, "failed to get edid\n");
@@ -1873,6 +1875,7 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
		audio.base = hdmi->regs;
		audio.irq = irq;
		audio.hdmi = hdmi;
		audio.eld = hdmi->connector.eld;

		pdevinfo.name = "dw-hdmi-ahb-audio";
		pdevinfo.data = &audio;