In order to simplify the driver even further and to remove the
boilerplate code, rewrite the audio interface to use the DRM HDMI Audio
framework.

Signed-off-by: Dmitry Baryshkov <dmitry.barysh...@linaro.org>
---
 drivers/gpu/drm/msm/hdmi/hdmi.c        | 91 ----------------------------------
 drivers/gpu/drm/msm/hdmi/hdmi.h        | 20 ++++----
 drivers/gpu/drm/msm/hdmi/hdmi_audio.c  | 75 +++++++++++++++++++++++-----
 drivers/gpu/drm/msm/hdmi/hdmi_bridge.c |  5 ++
 4 files changed, 76 insertions(+), 115 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index 
6b77e0fb8d5ec218dfbf58215e2e12ad1dfb1b85..248541ff449204c72cd444458dadb9ae4a0a53d1
 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -14,7 +14,6 @@
 #include <drm/drm_of.h>
 #include <drm/display/drm_hdmi_state_helper.h>
 
-#include <sound/hdmi-codec.h>
 #include "hdmi.h"
 
 void msm_hdmi_set_mode(struct hdmi *hdmi, bool power_on)
@@ -245,87 +244,6 @@ static const struct hdmi_platform_config 
hdmi_tx_8974_config = {
                .hpd_freq      = hpd_clk_freq_8x74,
 };
 
-/*
- * HDMI audio codec callbacks
- */
-static int msm_hdmi_audio_hw_params(struct device *dev, void *data,
-                                   struct hdmi_codec_daifmt *daifmt,
-                                   struct hdmi_codec_params *params)
-{
-       struct hdmi *hdmi = dev_get_drvdata(dev);
-       unsigned int rate;
-       int ret;
-
-       DRM_DEV_DEBUG(dev, "%u Hz, %d bit, %d channels\n", params->sample_rate,
-                params->sample_width, params->cea.channels);
-
-       switch (params->sample_rate) {
-       case 32000:
-               rate = HDMI_SAMPLE_RATE_32KHZ;
-               break;
-       case 44100:
-               rate = HDMI_SAMPLE_RATE_44_1KHZ;
-               break;
-       case 48000:
-               rate = HDMI_SAMPLE_RATE_48KHZ;
-               break;
-       case 88200:
-               rate = HDMI_SAMPLE_RATE_88_2KHZ;
-               break;
-       case 96000:
-               rate = HDMI_SAMPLE_RATE_96KHZ;
-               break;
-       case 176400:
-               rate = HDMI_SAMPLE_RATE_176_4KHZ;
-               break;
-       case 192000:
-               rate = HDMI_SAMPLE_RATE_192KHZ;
-               break;
-       default:
-               DRM_DEV_ERROR(dev, "rate[%d] not supported!\n",
-                       params->sample_rate);
-               return -EINVAL;
-       }
-
-       ret = 
drm_atomic_helper_connector_hdmi_update_audio_infoframe(hdmi->connector,
-                                                                     
&params->cea);
-       if (ret)
-               return ret;
-
-       msm_hdmi_audio_info_setup(hdmi, rate, params->cea.channels);
-
-       return 0;
-}
-
-static void msm_hdmi_audio_shutdown(struct device *dev, void *data)
-{
-       struct hdmi *hdmi = dev_get_drvdata(dev);
-
-       drm_atomic_helper_connector_hdmi_clear_audio_infoframe(hdmi->connector);
-       msm_hdmi_audio_disable(hdmi);
-}
-
-static const struct hdmi_codec_ops msm_hdmi_audio_codec_ops = {
-       .hw_params = msm_hdmi_audio_hw_params,
-       .audio_shutdown = msm_hdmi_audio_shutdown,
-};
-
-static struct hdmi_codec_pdata codec_data = {
-       .ops = &msm_hdmi_audio_codec_ops,
-       .max_i2s_channels = 8,
-       .i2s = 1,
-};
-
-static int msm_hdmi_register_audio_driver(struct hdmi *hdmi, struct device 
*dev)
-{
-       hdmi->audio_pdev = platform_device_register_data(dev,
-                                                        HDMI_CODEC_DRV_NAME,
-                                                        PLATFORM_DEVID_AUTO,
-                                                        &codec_data,
-                                                        sizeof(codec_data));
-       return PTR_ERR_OR_ZERO(hdmi->audio_pdev);
-}
-
 static int msm_hdmi_bind(struct device *dev, struct device *master, void *data)
 {
        struct msm_drm_private *priv = dev_get_drvdata(master);
@@ -337,12 +255,6 @@ static int msm_hdmi_bind(struct device *dev, struct device 
*master, void *data)
                return err;
        priv->hdmi = hdmi;
 
-       err = msm_hdmi_register_audio_driver(hdmi, dev);
-       if (err) {
-               DRM_ERROR("Failed to attach an audio codec %d\n", err);
-               hdmi->audio_pdev = NULL;
-       }
-
        return 0;
 }
 
@@ -352,9 +264,6 @@ static void msm_hdmi_unbind(struct device *dev, struct 
device *master,
        struct msm_drm_private *priv = dev_get_drvdata(master);
 
        if (priv->hdmi) {
-               if (priv->hdmi->audio_pdev)
-                       platform_device_unregister(priv->hdmi->audio_pdev);
-
                if (priv->hdmi->bridge)
                        msm_hdmi_hpd_disable(priv->hdmi);
 
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
index 
ab169b77377097dc22c0c718f65024cb8ad1d317..88a41be7c6fc2f878a1c372a0c75b3277f24f893
 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -33,7 +33,6 @@ struct hdmi_hdcp_ctrl;
 struct hdmi {
        struct drm_device *dev;
        struct platform_device *pdev;
-       struct platform_device *audio_pdev;
 
        const struct hdmi_platform_config *config;
 
@@ -205,16 +204,15 @@ static inline int msm_hdmi_pll_8998_init(struct 
platform_device *pdev)
 /*
  * audio:
  */
-#define        HDMI_SAMPLE_RATE_32KHZ          0
-#define        HDMI_SAMPLE_RATE_44_1KHZ        1
-#define        HDMI_SAMPLE_RATE_48KHZ          2
-#define        HDMI_SAMPLE_RATE_88_2KHZ        3
-#define        HDMI_SAMPLE_RATE_96KHZ          4
-#define        HDMI_SAMPLE_RATE_176_4KHZ       5
-#define        HDMI_SAMPLE_RATE_192KHZ         6
-
-int msm_hdmi_audio_info_setup(struct hdmi *hdmi, int rate, int channels);
-int msm_hdmi_audio_disable(struct hdmi *hdmi);
+struct hdmi_codec_daifmt;
+struct hdmi_codec_params;
+
+int msm_hdmi_bridge_audio_prepare(struct drm_connector *connector,
+                                 struct drm_bridge *bridge,
+                                 struct hdmi_codec_daifmt *daifmt,
+                                 struct hdmi_codec_params *params);
+void msm_hdmi_bridge_audio_shutdown(struct drm_connector *connector,
+                                   struct drm_bridge *bridge);
 
 /*
  * hdmi bridge:
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_audio.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_audio.c
index 
924654bfb48cf17feadea1c0661ee6ee4e1b4589..9c5b5310bfeb54902d7d0687909afc79e320f560
 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_audio.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_audio.c
@@ -4,7 +4,12 @@
  * Author: Rob Clark <robdcl...@gmail.com>
  */
 
+#include <drm/display/drm_hdmi_state_helper.h>
+
 #include <linux/hdmi.h>
+
+#include <sound/hdmi-codec.h>
+
 #include "hdmi.h"
 
 /* Supported HDMI Audio sample rates */
@@ -68,7 +73,8 @@ static const struct hdmi_msm_audio_arcs *get_arcs(unsigned 
long int pixclock)
        return NULL;
 }
 
-static int msm_hdmi_audio_update(struct hdmi *hdmi)
+static int msm_hdmi_audio_update(struct hdmi *hdmi,
+                                struct drm_connector *connector)
 {
        struct hdmi_audio *audio = &hdmi->audio;
        const struct hdmi_msm_audio_arcs *arcs = NULL;
@@ -76,7 +82,7 @@ static int msm_hdmi_audio_update(struct hdmi *hdmi)
        uint32_t acr_pkt_ctrl, vbi_pkt_ctrl, aud_pkt_ctrl;
        uint32_t audio_config;
 
-       if (!hdmi->connector->display_info.is_hdmi)
+       if (!connector->display_info.is_hdmi)
                return -EINVAL;
 
        DBG("audio: enabled=%d, channels=%d, rate=%d",
@@ -192,29 +198,72 @@ static int msm_hdmi_audio_update(struct hdmi *hdmi)
        return 0;
 }
 
-int msm_hdmi_audio_info_setup(struct hdmi *hdmi, int rate, int channels)
+int msm_hdmi_bridge_audio_prepare(struct drm_connector *connector,
+                                 struct drm_bridge *bridge,
+                                 struct hdmi_codec_daifmt *daifmt,
+                                 struct hdmi_codec_params *params)
 {
-       if (!hdmi)
-               return -ENXIO;
-
-       if ((rate < 0) || (rate >= MSM_HDMI_SAMPLE_RATE_MAX))
+       struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
+       struct hdmi *hdmi = hdmi_bridge->hdmi;
+       unsigned int rate;
+       int ret;
+
+       drm_dbg_driver(bridge->dev, "%u Hz, %d bit, %d channels\n",
+                      params->sample_rate,
+                      params->sample_width,
+                      params->cea.channels);
+
+       switch (params->sample_rate) {
+       case 32000:
+               rate = MSM_HDMI_SAMPLE_RATE_32KHZ;
+               break;
+       case 44100:
+               rate = MSM_HDMI_SAMPLE_RATE_44_1KHZ;
+               break;
+       case 48000:
+               rate = MSM_HDMI_SAMPLE_RATE_48KHZ;
+               break;
+       case 88200:
+               rate = MSM_HDMI_SAMPLE_RATE_88_2KHZ;
+               break;
+       case 96000:
+               rate = MSM_HDMI_SAMPLE_RATE_96KHZ;
+               break;
+       case 176400:
+               rate = MSM_HDMI_SAMPLE_RATE_176_4KHZ;
+               break;
+       case 192000:
+               rate = MSM_HDMI_SAMPLE_RATE_192KHZ;
+               break;
+       default:
+               drm_err(bridge->dev, "rate[%d] not supported!\n",
+                       params->sample_rate);
                return -EINVAL;
+       }
+
+       ret = drm_atomic_helper_connector_hdmi_update_audio_infoframe(connector,
+                                                                     
&params->cea);
+       if (ret)
+               return ret;
 
        hdmi->audio.rate = rate;
-       hdmi->audio.channels = channels;
+       hdmi->audio.channels = params->cea.channels;
        hdmi->audio.enabled = true;
 
-       return msm_hdmi_audio_update(hdmi);
+       return msm_hdmi_audio_update(hdmi, connector);
 }
 
-int msm_hdmi_audio_disable(struct hdmi *hdmi)
+void msm_hdmi_bridge_audio_shutdown(struct drm_connector *connector,
+                                   struct drm_bridge *bridge)
 {
-       if (!hdmi)
-               return -ENXIO;
+       struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
+       struct hdmi *hdmi = hdmi_bridge->hdmi;
+
+       drm_atomic_helper_connector_hdmi_clear_audio_infoframe(connector);
 
        hdmi->audio.rate = 0;
        hdmi->audio.channels = 2;
        hdmi->audio.enabled = false;
 
-       return msm_hdmi_audio_update(hdmi);
+       msm_hdmi_audio_update(hdmi, connector);
 }
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index 
c31e1d33593de6480c0c2b7cb322a85e645ff332..8a1bbcf578b0749480799d9e5b2baf3778322edc
 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -470,6 +470,8 @@ static const struct drm_bridge_funcs msm_hdmi_bridge_funcs 
= {
        .hdmi_tmds_char_rate_valid = msm_hdmi_bridge_tmds_char_rate_valid,
        .hdmi_clear_infoframe = msm_hdmi_bridge_clear_infoframe,
        .hdmi_write_infoframe = msm_hdmi_bridge_write_infoframe,
+       .hdmi_audio_prepare = msm_hdmi_bridge_audio_prepare,
+       .hdmi_audio_shutdown = msm_hdmi_bridge_audio_shutdown,
 };
 
 static void
@@ -507,6 +509,9 @@ int msm_hdmi_bridge_init(struct hdmi *hdmi)
                DRM_BRIDGE_OP_DETECT |
                DRM_BRIDGE_OP_HDMI |
                DRM_BRIDGE_OP_EDID;
+       bridge->hdmi_audio_max_i2s_playback_channels = 8;
+       bridge->hdmi_audio_dev = &hdmi->pdev->dev;
+       bridge->hdmi_audio_dai_port = -1;
 
        ret = devm_drm_bridge_add(hdmi->dev->dev, bridge);
        if (ret)

-- 
2.39.5

Reply via email to