1
0
mirror of https://github.com/libretro/Lakka-LibreELEC.git synced 2024-11-25 04:56:18 +00:00
Lakka-LibreELEC/projects/NXP/devices/iMX8/patches/linux/0014-MLK-24611-2-drm-bridge-cdns-Add-callback-function-fo.patch
2022-08-01 07:05:17 +00:00

158 lines
5.0 KiB
Diff

From 46bf1dc2ba34440e8f83b3f70e3e4d6b3f9e6183 Mon Sep 17 00:00:00 2001
From: Shengjiu Wang <shengjiu.wang@nxp.com>
Date: Mon, 31 Aug 2020 14:50:29 +0800
Subject: [PATCH 14/49] MLK-24611-2: drm: bridge: cdns: Add callback function
for plug/unplug event
cdns-hdmi-core exports a function cdns_hdmi_set_plugged_cb so
platform device can register the callback
implement hook_plugged_cb to register callback function for hdmi cable
plug/unplug event.
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Reviewed-by: Sandor Yu <Sandor.yu@nxp.com>
---
.../gpu/drm/bridge/cadence/cdns-hdmi-core.c | 41 +++++++++++++++++--
.../gpu/drm/bridge/cadence/cdns-mhdp-audio.c | 10 +++++
include/drm/bridge/cdns-mhdp.h | 6 +++
3 files changed, 54 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
index a8fa559de9e9..5890da8aa1a1 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
@@ -225,11 +225,35 @@ void cdns_hdmi_mode_set(struct cdns_mhdp_device *mhdp)
}
}
+static void handle_plugged_change(struct cdns_mhdp_device *mhdp, bool plugged)
+{
+ if (mhdp->plugged_cb && mhdp->codec_dev)
+ mhdp->plugged_cb(mhdp->codec_dev, plugged);
+}
+
+int cdns_hdmi_set_plugged_cb(struct cdns_mhdp_device *mhdp,
+ hdmi_codec_plugged_cb fn,
+ struct device *codec_dev)
+{
+ bool plugged;
+
+ mutex_lock(&mhdp->lock);
+ mhdp->plugged_cb = fn;
+ mhdp->codec_dev = codec_dev;
+ plugged = mhdp->last_connector_result == connector_status_connected;
+ handle_plugged_change(mhdp, plugged);
+ mutex_unlock(&mhdp->lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cdns_hdmi_set_plugged_cb);
+
static enum drm_connector_status
cdns_hdmi_connector_detect(struct drm_connector *connector, bool force)
{
struct cdns_mhdp_device *mhdp =
container_of(connector, struct cdns_mhdp_device, connector.base);
+ enum drm_connector_status result;
u8 hpd = 0xf;
@@ -237,15 +261,25 @@ cdns_hdmi_connector_detect(struct drm_connector *connector, bool force)
if (hpd == 1)
/* Cable Connected */
- return connector_status_connected;
+ result = connector_status_connected;
else if (hpd == 0)
/* Cable Disconnedted */
- return connector_status_disconnected;
+ result = connector_status_disconnected;
else {
/* Cable status unknown */
DRM_INFO("Unknow cable status, hdp=%u\n", hpd);
- return connector_status_unknown;
+ result = connector_status_unknown;
+ }
+
+ mutex_lock(&mhdp->lock);
+ if (result != mhdp->last_connector_result) {
+ handle_plugged_change(mhdp,
+ result == connector_status_connected);
+ mhdp->last_connector_result = result;
}
+ mutex_unlock(&mhdp->lock);
+
+ return result;
}
static int cdns_hdmi_connector_get_modes(struct drm_connector *connector)
@@ -624,6 +658,7 @@ static int __cdns_hdmi_probe(struct platform_device *pdev,
#ifdef CONFIG_OF
mhdp->bridge.base.of_node = dev->of_node;
#endif
+ mhdp->last_connector_result = connector_status_disconnected;
memset(&pdevinfo, 0, sizeof(pdevinfo));
pdevinfo.parent = dev;
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-audio.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-audio.c
index fa1dcf781539..f4f3f9ca437c 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-audio.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-audio.c
@@ -380,11 +380,21 @@ static int audio_get_eld(struct device *dev, void *data,
return 0;
}
+static int audio_hook_plugged_cb(struct device *dev, void *data,
+ hdmi_codec_plugged_cb fn,
+ struct device *codec_dev)
+{
+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev);
+
+ return cdns_hdmi_set_plugged_cb(mhdp, fn, codec_dev);
+}
+
static const struct hdmi_codec_ops audio_codec_ops = {
.hw_params = audio_hw_params,
.audio_shutdown = audio_shutdown,
.digital_mute = audio_digital_mute,
.get_eld = audio_get_eld,
+ .hook_plugged_cb = audio_hook_plugged_cb,
};
int cdns_mhdp_register_audio_driver(struct device *dev)
diff --git a/include/drm/bridge/cdns-mhdp.h b/include/drm/bridge/cdns-mhdp.h
index 1f8fd024cdfa..6bfd82a3d9a2 100644
--- a/include/drm/bridge/cdns-mhdp.h
+++ b/include/drm/bridge/cdns-mhdp.h
@@ -22,6 +22,7 @@
#include <drm/display/drm_dp_mst_helper.h>
#include <media/cec.h>
#include <linux/bitops.h>
+#include <sound/hdmi-codec.h>
#define ADDR_IMEM 0x10000
#define ADDR_DMEM 0x20000
@@ -714,6 +715,9 @@ struct cdns_mhdp_device {
};
const struct cdns_plat_data *plat_data;
+ hdmi_codec_plugged_cb plugged_cb;
+ struct device *codec_dev;
+ enum drm_connector_status last_connector_result;
};
u32 cdns_mhdp_bus_read(struct cdns_mhdp_device *mhdp, u32 offset);
@@ -796,6 +800,8 @@ void cdns_dp_remove(struct platform_device *pdev);
void cdns_dp_unbind(struct device *dev);
int cdns_dp_bind(struct platform_device *pdev,
struct drm_encoder *encoder, struct cdns_mhdp_device *mhdp);
+int cdns_hdmi_set_plugged_cb(struct cdns_mhdp_device *mhdp, hdmi_codec_plugged_cb fn,
+ struct device *codec_dev);
/* CEC */
#ifdef CONFIG_DRM_CDNS_HDMI_CEC
--
2.29.2