From 37092df65a4e853d24a6b916b46c6f2ef27fa2e6 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 drivers/gpu/drm/vc4/vc4_hdmi.c 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 65868eb..8c0c0b5 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -412,6 +413,7 @@ static void vc4_hdmi_handle_hotplug(struct vc4_hdmi *vc4_hdmi, { struct drm_connector *connector = &vc4_hdmi->connector; struct edid *edid; + int ret; /* * NOTE: This function should really be called with @@ -445,6 +447,15 @@ static void vc4_hdmi_handle_hotplug(struct vc4_hdmi *vc4_hdmi, kfree(edid); vc4_hdmi_reset_link(connector, ctx); + +#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 } static int vc4_hdmi_connector_detect_ctx(struct drm_connector *connector, @@ -3642,6 +3653,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); @@ -3704,6 +3722,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. */ diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h index 724b145..2c599db 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.h +++ b/drivers/gpu/drm/vc4/vc4_hdmi.h @@ -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, @@ -235,6 +239,11 @@ struct vc4_hdmi { struct debugfs_regset32 phy_regset; struct debugfs_regset32 ram_regset; struct debugfs_regset32 rm_regset; + +#ifdef CONFIG_EXTCON + enum drm_connector_status status; + struct extcon_dev *edev; +#endif }; static inline struct vc4_hdmi * -- 2.7.4