From 64f67d3916ce3a51bd75a5a7c29444af0324a318 Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Tue, 30 Jun 2020 14:32:02 +0900 Subject: [PATCH] drm/vc4: add extcon hdmi connection uevent 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. Change-Id: I962f7a39b7a3344f9793e436ef28c36b123571a8 Signed-off-by: Seung-Woo Kim Signed-off-by: Hoegeun Kwon Conflicts: drivers/gpu/drm/vc4/vc4_hdmi.h Signed-off-by: Hoegeun Kwon --- drivers/gpu/drm/vc4/vc4_hdmi.c | 35 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/vc4/vc4_hdmi.h | 9 +++++++++ 2 files changed, 44 insertions(+) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index f1e0e00..54b588f 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -242,6 +243,7 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force) struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); enum drm_connector_status ret = connector_status_disconnected; bool connected = false; + enum drm_connector_status status; mutex_lock(&vc4_hdmi->mutex); @@ -283,6 +285,15 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force) out: pm_runtime_put(&vc4_hdmi->pdev->dev); mutex_unlock(&vc4_hdmi->mutex); + +#ifdef CONFIG_EXTCON + if (ret != vc4_hdmi->status) { + extcon_set_state_sync(vc4_hdmi->edev, EXTCON_DISP_HDMI, + (status == connector_status_connected ? + true : false)); + vc4_hdmi->status = ret; + } +#endif return ret; } @@ -3042,6 +3053,13 @@ static int vc4_hdmi_runtime_resume(struct device *dev) } #endif +#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); @@ -3097,6 +3115,23 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) return -EPROBE_DEFER; } +#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. */ diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h index fa57d85..2492353 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.h +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h @@ -24,6 +24,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, @@ -262,6 +266,11 @@ struct vc4_hdmi { * for use outside of KMS hooks. Protected by @mutex. */ int broadcast_rgb; + +#ifdef CONFIG_EXTCON + enum drm_connector_status status; + struct extcon_dev *edev; +#endif }; static inline struct vc4_hdmi * -- 2.7.4