drm/vc4: add extcon hdmi connection uevent 33/306633/1
authorSeung-Woo Kim <sw0312.kim@samsung.com>
Tue, 30 Jun 2020 05:32:02 +0000 (14:32 +0900)
committerMarek Szyprowski <m.szyprowski@samsung.com>
Fri, 23 Feb 2024 11:30:21 +0000 (12:30 +0100)
Add extcon hdmi connection and disconnection uevent when extcon
module is enabled.

The vc4_hdmi detection is done by polling way, so extcon uevent
for connection is a bit slow after changing real hdmi cable state.

Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Signed-off-by: Hoegeun Kwon <hoegeun.kwon@samsung.com>
[mszyprow: this is a squashed set of the following patches
 from platform/kernel/linux-rpi 'tizen' (c4f85fdcd893) branch:
 drm/vc4: add extcon hdmi connection uevent
 drm/vc4: hdmi: Fix hotplug extcon uevent to works
 ported and adapted to Linux v6.6 kernel base]

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Change-Id: I2a825241cd72befd1f75bd094405f719d4b20638

drivers/gpu/drm/vc4/vc4_hdmi.c
drivers/gpu/drm/vc4/vc4_hdmi.h

index b56d736..0722636 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/clk.h>
 #include <linux/component.h>
 #include <linux/gpio/consumer.h>
+#include <linux/extcon-provider.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -496,6 +497,15 @@ static int vc4_hdmi_connector_detect_ctx(struct drm_connector *connector,
        vc4_hdmi_handle_hotplug(vc4_hdmi, ctx, status);
        pm_runtime_put(&vc4_hdmi->pdev->dev);
 
+#ifdef CONFIG_EXTCON
+       if (status != vc4_hdmi->status) {
+               extcon_set_state_sync(vc4_hdmi->edev, EXTCON_DISP_HDMI,
+                                     (status == connector_status_connected ?
+                                     true : false));
+               vc4_hdmi->status = status;
+       }
+#endif
+
        return status;
 }
 
@@ -3676,6 +3686,13 @@ static void vc4_hdmi_put_ddc_device(void *ptr)
        put_device(&vc4_hdmi->ddc->dev);
 }
 
+#ifdef CONFIG_EXTCON
+static const unsigned int vc4_hdmi_extcon_cable[] = {
+       EXTCON_DISP_HDMI,
+       EXTCON_NONE,
+};
+#endif
+
 static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
 {
        const struct vc4_hdmi_variant *variant = of_device_get_match_data(dev);
@@ -3738,6 +3755,23 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
        if (ret)
                return ret;
 
+#ifdef CONFIG_EXTCON
+       vc4_hdmi->status = connector_status_disconnected;
+
+       /* Initialize extcon device */
+       vc4_hdmi->edev = devm_extcon_dev_allocate(dev, vc4_hdmi_extcon_cable);
+       if (IS_ERR(vc4_hdmi->edev)) {
+               dev_err(dev, "failed to allocate memory for extcon\n");
+               return PTR_ERR(vc4_hdmi->edev);
+       }
+
+       ret = devm_extcon_dev_register(dev, vc4_hdmi->edev);
+       if (ret) {
+               dev_err(dev, "failed to register extcon device\n");
+               return ret;
+       }
+#endif
+
        /* Only use the GPIO HPD pin if present in the DT, otherwise
         * we'll use the HDMI core's register.
         */
index 79811fb..4a96d2f 100644 (file)
@@ -12,6 +12,10 @@ struct vc4_hdmi;
 struct vc4_hdmi_register;
 struct vc4_hdmi_connector_state;
 
+#ifdef CONFIG_EXTCON
+struct extcon_dev;
+#endif
+
 enum vc4_hdmi_phy_channel {
        PHY_LANE_0 = 0,
        PHY_LANE_1,
@@ -228,6 +232,11 @@ struct vc4_hdmi {
         * for use outside of KMS hooks. Protected by @mutex.
         */
        enum vc4_hdmi_output_format output_format;
+
+#ifdef CONFIG_EXTCON
+       enum drm_connector_status status;
+       struct extcon_dev *edev;
+#endif
 };
 
 #define connector_to_vc4_hdmi(_connector)                              \