]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/display: bridge-connector: hook in CEC notifier support
authorDmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Sat, 17 May 2025 01:59:44 +0000 (04:59 +0300)
committerDmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Tue, 20 May 2025 22:35:16 +0000 (01:35 +0300)
Allow HDMI DRM bridges to create CEC notifier. Physical address is
handled automatically by drm_atomic_helper_connector_hdmi_hotplug()
being called from .detect() path.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Link: https://lore.kernel.org/r/20250517-drm-hdmi-connector-cec-v6-8-35651db6f19b@oss.qualcomm.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
drivers/gpu/drm/display/drm_bridge_connector.c
include/drm/drm_bridge.h

index 381a0f9d4259bf9f72d3a292b7dcc82e45c61bae..0377dcd691a871643710d667248b05f8eb9e84d6 100644 (file)
@@ -20,6 +20,7 @@
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/display/drm_hdmi_audio_helper.h>
+#include <drm/display/drm_hdmi_cec_helper.h>
 #include <drm/display/drm_hdmi_helper.h>
 #include <drm/display/drm_hdmi_state_helper.h>
 
@@ -113,6 +114,13 @@ struct drm_bridge_connector {
         * &DRM_BRIDGE_OP_DP_AUDIO).
         */
        struct drm_bridge *bridge_dp_audio;
+       /**
+        * @bridge_hdmi_cec:
+        *
+        * The bridge in the chain that implements CEC support, if any (see
+        * DRM_BRIDGE_OP_HDMI_CEC_NOTIFIER).
+        */
+       struct drm_bridge *bridge_hdmi_cec;
 };
 
 #define to_drm_bridge_connector(x) \
@@ -662,6 +670,13 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
                        bridge_connector->bridge_dp_audio = bridge;
                }
 
+               if (bridge->ops & DRM_BRIDGE_OP_HDMI_CEC_NOTIFIER) {
+                       if (bridge_connector->bridge_hdmi_cec)
+                               return ERR_PTR(-EBUSY);
+
+                       bridge_connector->bridge_hdmi_cec = bridge;
+               }
+
                if (!drm_bridge_get_next_bridge(bridge))
                        connector_type = bridge->type;
 
@@ -724,6 +739,15 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
                        return ERR_PTR(ret);
        }
 
+       if (bridge_connector->bridge_hdmi_cec &&
+           bridge_connector->bridge_hdmi_cec->ops & DRM_BRIDGE_OP_HDMI_CEC_NOTIFIER) {
+               ret = drmm_connector_hdmi_cec_notifier_register(connector,
+                                                               NULL,
+                                                               bridge->hdmi_cec_dev);
+               if (ret)
+                       return ERR_PTR(ret);
+       }
+
        drm_connector_helper_add(connector, &drm_bridge_connector_helper_funcs);
 
        if (bridge_connector->bridge_hpd)
index db0d374d863b0b1f774d395743f1e29bb84e8937..0e5f6a007d536215bd50e11846433290c2060b9c 100644 (file)
@@ -907,6 +907,11 @@ enum drm_bridge_ops {
         * flag.
         */
        DRM_BRIDGE_OP_DP_AUDIO = BIT(6),
+       /**
+        * @DRM_BRIDGE_OP_HDMI_CEC_NOTIFIER: The bridge requires CEC notifier
+        * to be present.
+        */
+       DRM_BRIDGE_OP_HDMI_CEC_NOTIFIER = BIT(7),
 };
 
 /**
@@ -1003,6 +1008,12 @@ struct drm_bridge {
         */
        unsigned int max_bpc;
 
+       /**
+        * @hdmi_cec_dev: device to be used as a containing device for CEC
+        * functions.
+        */
+       struct device *hdmi_cec_dev;
+
        /**
         * @hdmi_audio_dev: device to be used as a parent for the HDMI Codec if
         * either of @DRM_BRIDGE_OP_HDMI_AUDIO or @DRM_BRIDGE_OP_DP_AUDIO is set.