drm: bridge/dw_hdmi-ahb-audio: parse ELD from HDMI driver
authorRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 7 Nov 2013 16:06:01 +0000 (16:06 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Fri, 9 Oct 2015 16:17:24 +0000 (17:17 +0100)
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: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
drivers/gpu/drm/bridge/Kconfig
drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
drivers/gpu/drm/bridge/dw_hdmi-audio.h
drivers/gpu/drm/bridge/dw_hdmi.c

index 0d0a4f7f4f5ced24d51eac8205b58cfd06859914..6dddd392aa42f119ff572993ac887eb3a3a277b6 100644 (file)
@@ -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
index bf379310008adebd704b5a1ca0671c382f7ad071..fbcef2695c93e004594a543c24b3527913b1ef62 100644 (file)
 #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;
index 1e840118d90ae8bc761c2f6d541b10e7258130d3..91f631beecc7cd83199dc0787db7228ccb98c5bf 100644 (file)
@@ -8,6 +8,7 @@ struct dw_hdmi_audio_data {
        void __iomem *base;
        int irq;
        struct dw_hdmi *hdmi;
+       u8 *eld;
 };
 
 #endif
index d61a9fb46c6dfe025e03b892b7f8203d1898bd62..70e7a938a37b7388a92a6bc51f79576371952a68 100644 (file)
@@ -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;