forked from libretro/Lakka-LibreELEC
158 lines
5.0 KiB
Diff
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
|
|
|