drm/msm/dp: add hook_plugged_cb hdmi-codec op for MSM DP driver
authorAbhinav Kumar <abhinavk@codeaurora.org>
Sat, 12 Sep 2020 20:49:30 +0000 (13:49 -0700)
committerRob Clark <robdclark@chromium.org>
Tue, 15 Sep 2020 17:54:34 +0000 (10:54 -0700)
Add the hook_plugged_cb op for the MSM DP driver to signal connect
and disconnect events to the hdmi-codec driver which in-turn shall
notify the audio subsystem to start a new or teardown an existing
session.

Changes in v2: none
Changes in v3: none
Changes in v4: rebase on top of latest patchset of dependency
Changes in v5: rebase on top of latest patchset of dependency
Changes in v6: none

Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@chromium.org>
drivers/gpu/drm/msm/dp/dp_audio.c
drivers/gpu/drm/msm/dp/dp_display.c
drivers/gpu/drm/msm/dp/dp_display.h

index 75556eea10592593b1d70da122fd0b7db9c7bf98..11fa5ad7a8016c83b0769a7c97731a55c3255727 100644 (file)
@@ -10,7 +10,6 @@
 
 #include <drm/drm_dp_helper.h>
 #include <drm/drm_edid.h>
-#include <sound/hdmi-codec.h>
 
 #include "dp_catalog.h"
 #include "dp_audio.h"
@@ -442,6 +441,29 @@ static struct dp_audio_private *dp_audio_get_data(struct platform_device *pdev)
        return container_of(dp_audio, struct dp_audio_private, dp_audio);
 }
 
+static int dp_audio_hook_plugged_cb(struct device *dev, void *data,
+               hdmi_codec_plugged_cb fn,
+               struct device *codec_dev)
+{
+
+       struct platform_device *pdev;
+       struct msm_dp *dp_display;
+
+       pdev = to_platform_device(dev);
+       if (!pdev) {
+               pr_err("invalid input\n");
+               return -ENODEV;
+       }
+
+       dp_display = platform_get_drvdata(pdev);
+       if (!dp_display) {
+               pr_err("invalid input\n");
+               return -ENODEV;
+       }
+
+       return dp_display_set_plugged_cb(dp_display, fn, codec_dev);
+}
+
 static int dp_audio_get_eld(struct device *dev,
        void *data, uint8_t *buf, size_t len)
 {
@@ -513,6 +535,7 @@ static const struct hdmi_codec_ops dp_audio_codec_ops = {
        .hw_params = dp_audio_hw_params,
        .audio_shutdown = dp_audio_shutdown,
        .get_eld = dp_audio_get_eld,
+       .hook_plugged_cb = dp_audio_hook_plugged_cb,
 };
 
 static struct hdmi_codec_pdata codec_data = {
index dd2d9433f4d75f450f432e97a0e3ca47c2f1e43b..c30ffe778ffeae3e0ab85ab04e46efb4879704b9 100644 (file)
@@ -780,6 +780,13 @@ static int dp_display_prepare(struct msm_dp *dp)
        return 0;
 }
 
+static void dp_display_handle_plugged_change(struct msm_dp *dp_display,
+               bool plugged)
+{
+       if (dp_display->plugged_cb && dp_display->codec_dev)
+               dp_display->plugged_cb(dp_display->codec_dev, plugged);
+}
+
 static int dp_display_enable(struct dp_display_private *dp, u32 data)
 {
        int rc = 0;
@@ -812,6 +819,8 @@ static int dp_display_post_enable(struct msm_dp *dp_display)
                dp->audio->lane_count = dp->link->link_params.num_lanes;
        }
 
+       /* signal the connect event late to synchronize video and display */
+       dp_display_handle_plugged_change(dp_display, true);
        return 0;
 }
 
@@ -834,6 +843,19 @@ static int dp_display_unprepare(struct msm_dp *dp)
        return 0;
 }
 
+int dp_display_set_plugged_cb(struct msm_dp *dp_display,
+               hdmi_codec_plugged_cb fn, struct device *codec_dev)
+{
+       bool plugged;
+
+       dp_display->plugged_cb = fn;
+       dp_display->codec_dev = codec_dev;
+       plugged = dp_display->is_connected;
+       dp_display_handle_plugged_change(dp_display, plugged);
+
+       return 0;
+}
+
 int dp_display_validate_mode(struct msm_dp *dp, u32 mode_pclk_khz)
 {
        const u32 num_components = 3, default_bpp = 24;
@@ -1349,6 +1371,8 @@ int msm_dp_display_pre_disable(struct msm_dp *dp, struct drm_encoder *encoder)
 
        dp_ctrl_push_idle(dp_display->ctrl);
 
+       dp_display_handle_plugged_change(dp, false);
+
        return 0;
 }
 
index 1e0d2b9d9a2aee2855109e94c78ff71541a4dc38..5020faf360db78001472fc842fd48d6ae8dc8ca2 100644 (file)
@@ -7,18 +7,25 @@
 #define _DP_DISPLAY_H_
 
 #include "dp_panel.h"
+#include <sound/hdmi-codec.h>
 
 struct msm_dp {
        struct drm_device *drm_dev;
+       struct device *codec_dev;
        struct drm_connector *connector;
        struct drm_encoder *encoder;
        bool is_connected;
+
+       hdmi_codec_plugged_cb plugged_cb;
+
        u32 max_pclk_khz;
 
        u32 max_dp_lanes;
        struct dp_audio *dp_audio;
 };
 
+int dp_display_set_plugged_cb(struct msm_dp *dp_display,
+               hdmi_codec_plugged_cb fn, struct device *codec_dev);
 int dp_display_validate_mode(struct msm_dp *dp_display, u32 mode_pclk_khz);
 int dp_display_get_modes(struct msm_dp *dp_display,
                struct dp_display_mode *dp_mode);