* [PATCH 0/2] drm/bridge: lontium-lt9611uxc: switch to DRM_BRIDGE_OP_HDMI_AUDIO
@ 2025-07-18 15:21 Dmitry Baryshkov
2025-07-18 15:21 ` [PATCH 1/2] drm/bridge: add connector argument to .hpd_notify callback Dmitry Baryshkov
2025-07-18 15:21 ` [PATCH 2/2] drm/bridge: lontium-lt9611uxc: switch to HDMI audio helpers Dmitry Baryshkov
0 siblings, 2 replies; 3+ messages in thread
From: Dmitry Baryshkov @ 2025-07-18 15:21 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Kevin Hilman,
Jerome Brunet, Martin Blumenstingl, Rob Clark, Dmitry Baryshkov,
Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
Tomi Valkeinen
Cc: dri-devel, linux-kernel, linux-amlogic, linux-arm-kernel,
linux-arm-msm, freedreno
Use DRM HDMI audio helpers in order to implement HDMI audio support for
Lontium LT9611UXC bridge.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
Dmitry Baryshkov (2):
drm/bridge: add connector argument to .hpd_notify callback
drm/bridge: lontium-lt9611uxc: switch to HDMI audio helpers
drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 125 ++++++++++---------------
drivers/gpu/drm/display/drm_bridge_connector.c | 2 +-
drivers/gpu/drm/meson/meson_encoder_hdmi.c | 1 +
drivers/gpu/drm/msm/dp/dp_display.c | 3 +-
drivers/gpu/drm/msm/dp/dp_drm.h | 3 +-
drivers/gpu/drm/omapdrm/dss/hdmi4.c | 1 +
include/drm/drm_bridge.h | 1 +
7 files changed, 57 insertions(+), 79 deletions(-)
---
base-commit: 024e09e444bd2b06aee9d1f3fe7b313c7a2df1bb
change-id: 20250718-lt9611uxc-hdmi-3dd96306cdff
Best regards,
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/2] drm/bridge: add connector argument to .hpd_notify callback
2025-07-18 15:21 [PATCH 0/2] drm/bridge: lontium-lt9611uxc: switch to DRM_BRIDGE_OP_HDMI_AUDIO Dmitry Baryshkov
@ 2025-07-18 15:21 ` Dmitry Baryshkov
2025-07-18 15:21 ` [PATCH 2/2] drm/bridge: lontium-lt9611uxc: switch to HDMI audio helpers Dmitry Baryshkov
1 sibling, 0 replies; 3+ messages in thread
From: Dmitry Baryshkov @ 2025-07-18 15:21 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Kevin Hilman,
Jerome Brunet, Martin Blumenstingl, Rob Clark, Dmitry Baryshkov,
Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
Tomi Valkeinen
Cc: dri-devel, linux-kernel, linux-amlogic, linux-arm-kernel,
linux-arm-msm, freedreno
Drivers might need to update DRM connector in the
drm_bridge_funcs.hpd_notify callback (e.g. it might be necessary to
update EDID before setting ELD). Add corresponding argument to the
callback.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/display/drm_bridge_connector.c | 2 +-
drivers/gpu/drm/meson/meson_encoder_hdmi.c | 1 +
drivers/gpu/drm/msm/dp/dp_display.c | 3 ++-
drivers/gpu/drm/msm/dp/dp_drm.h | 3 ++-
drivers/gpu/drm/omapdrm/dss/hdmi4.c | 1 +
include/drm/drm_bridge.h | 1 +
6 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c
index 5eb7e9bfe36116c9618cd3773f1c01e7ebb573be..f2fd277d694b8c959f913517ff5861b777d8a9dd 100644
--- a/drivers/gpu/drm/display/drm_bridge_connector.c
+++ b/drivers/gpu/drm/display/drm_bridge_connector.c
@@ -141,7 +141,7 @@ static void drm_bridge_connector_hpd_notify(struct drm_connector *connector,
/* Notify all bridges in the pipeline of hotplug events. */
drm_for_each_bridge_in_chain(bridge_connector->encoder, bridge) {
if (bridge->funcs->hpd_notify)
- bridge->funcs->hpd_notify(bridge, status);
+ bridge->funcs->hpd_notify(bridge, connector, status);
}
}
diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
index 8205ee56a691ee7d166b16cfce6932d0308fe6c4..a665c9036878c1e879b7bd88df1d523658fe8849 100644
--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
@@ -323,6 +323,7 @@ static int meson_encoder_hdmi_atomic_check(struct drm_bridge *bridge,
}
static void meson_encoder_hdmi_hpd_notify(struct drm_bridge *bridge,
+ struct drm_connector *connector,
enum drm_connector_status status)
{
struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge);
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index d87d47cc7ec3eb757ac192c411000bc50b824c59..0676b3423abcb31ac3ea6e6269473764786133ed 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1774,7 +1774,8 @@ void msm_dp_bridge_hpd_disable(struct drm_bridge *bridge)
}
void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,
- enum drm_connector_status status)
+ struct drm_connector *connector,
+ enum drm_connector_status status)
{
struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(bridge);
struct msm_dp *msm_dp_display = msm_dp_bridge->msm_dp_display;
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h b/drivers/gpu/drm/msm/dp/dp_drm.h
index d8c9b905f8bfb5abe47c1cb26d17bc605e3e1ba6..9eb3431dd93adf096f45b6d981967734bc8a2b0c 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.h
+++ b/drivers/gpu/drm/msm/dp/dp_drm.h
@@ -40,6 +40,7 @@ void msm_dp_bridge_mode_set(struct drm_bridge *drm_bridge,
void msm_dp_bridge_hpd_enable(struct drm_bridge *bridge);
void msm_dp_bridge_hpd_disable(struct drm_bridge *bridge);
void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,
- enum drm_connector_status status);
+ struct drm_connector *connector,
+ enum drm_connector_status status);
#endif /* _DP_DRM_H_ */
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index 3cd612af24498b057c33eaecb3d43c8df76cd23e..29b2dfb90b5fa3b137d05725d65a1cccb9cd1345 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -428,6 +428,7 @@ static void hdmi4_bridge_disable(struct drm_bridge *bridge,
}
static void hdmi4_bridge_hpd_notify(struct drm_bridge *bridge,
+ struct drm_connector *connector,
enum drm_connector_status status)
{
struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 8ed80cad77ec4b40d0aa6159e802a2839d5b8792..1e73d72c55426ec21905070a13b44aa36b02e023 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -730,6 +730,7 @@ struct drm_bridge_funcs {
* controllers for HDMI bridges.
*/
void (*hpd_notify)(struct drm_bridge *bridge,
+ struct drm_connector *connector,
enum drm_connector_status status);
/**
--
2.39.5
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/2] drm/bridge: lontium-lt9611uxc: switch to HDMI audio helpers
2025-07-18 15:21 [PATCH 0/2] drm/bridge: lontium-lt9611uxc: switch to DRM_BRIDGE_OP_HDMI_AUDIO Dmitry Baryshkov
2025-07-18 15:21 ` [PATCH 1/2] drm/bridge: add connector argument to .hpd_notify callback Dmitry Baryshkov
@ 2025-07-18 15:21 ` Dmitry Baryshkov
1 sibling, 0 replies; 3+ messages in thread
From: Dmitry Baryshkov @ 2025-07-18 15:21 UTC (permalink / raw)
To: Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Kevin Hilman,
Jerome Brunet, Martin Blumenstingl, Rob Clark, Dmitry Baryshkov,
Abhinav Kumar, Jessica Zhang, Sean Paul, Marijn Suijten,
Tomi Valkeinen
Cc: dri-devel, linux-kernel, linux-amlogic, linux-arm-kernel,
linux-arm-msm, freedreno
While LT9611UXC is a DSI-to-HDMI bridge, it implements all HDMI-related
functions internally, in the firmware, thus it doesn't make sense to
implement DRM_BRIDGE_OP_HDMI. However it is possible to implement
DRM_BRIDGE_OP_HDMI_AUDIO, streamlining HDMI audio plumbing (which
includes plugged notifications and ELD handling).
Implement corresponding callbacks and trigger EDID read /
drm_connector_hdmi_audio_plugged_notify() from the hpd_notify callback.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 125 +++++++++++------------------
1 file changed, 49 insertions(+), 76 deletions(-)
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
index 38fb8776c0f441ae433c60a7680aaa6501a8956e..11aab07d88df646a54fea287030a183eb823b26d 100644
--- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
@@ -17,8 +17,6 @@
#include <linux/wait.h>
#include <linux/workqueue.h>
-#include <sound/hdmi-codec.h>
-
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_edid.h>
@@ -27,6 +25,8 @@
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
+#include <drm/display/drm_hdmi_audio_helper.h>
+
#define EDID_BLOCK_SIZE 128
#define EDID_NUM_BLOCKS 2
@@ -48,7 +48,6 @@ struct lt9611uxc {
struct device_node *dsi1_node;
struct mipi_dsi_device *dsi0;
struct mipi_dsi_device *dsi1;
- struct platform_device *audio_pdev;
struct gpio_desc *reset_gpio;
struct gpio_desc *enable_gpio;
@@ -429,12 +428,52 @@ static const struct drm_edid *lt9611uxc_bridge_edid_read(struct drm_bridge *brid
return drm_edid_read_custom(connector, lt9611uxc_get_edid_block, lt9611uxc);
}
+static void lt9611uxc_bridge_hpd_notify(struct drm_bridge *bridge,
+ struct drm_connector *connector,
+ enum drm_connector_status status)
+{
+ const struct drm_edid *drm_edid;
+
+ if (status == connector_status_disconnected) {
+ drm_connector_hdmi_audio_plugged_notify(connector, false);
+ drm_edid_connector_update(connector, NULL);
+ return;
+ }
+
+ drm_edid = lt9611uxc_bridge_edid_read(bridge, connector);
+ drm_edid_connector_update(connector, drm_edid);
+ drm_edid_free(drm_edid);
+
+ if (status == connector_status_connected)
+ drm_connector_hdmi_audio_plugged_notify(connector, true);
+}
+
+static int lt9611uxc_hdmi_audio_prepare(struct drm_bridge *bridge,
+ struct drm_connector *connector,
+ struct hdmi_codec_daifmt *fmt,
+ struct hdmi_codec_params *hparms)
+{
+ /*
+ * LT9611UXC will automatically detect rate and sample size, so no need
+ * to setup anything here.
+ */
+ return 0;
+}
+
+static void lt9611uxc_hdmi_audio_shutdown(struct drm_bridge *bridge,
+ struct drm_connector *connector)
+{
+}
+
static const struct drm_bridge_funcs lt9611uxc_bridge_funcs = {
.attach = lt9611uxc_bridge_attach,
.mode_valid = lt9611uxc_bridge_mode_valid,
.mode_set = lt9611uxc_bridge_mode_set,
.detect = lt9611uxc_bridge_detect,
.edid_read = lt9611uxc_bridge_edid_read,
+ .hpd_notify = lt9611uxc_bridge_hpd_notify,
+ .hdmi_audio_prepare = lt9611uxc_hdmi_audio_prepare,
+ .hdmi_audio_shutdown = lt9611uxc_hdmi_audio_shutdown,
};
static int lt9611uxc_parse_dt(struct device *dev,
@@ -508,73 +547,6 @@ static int lt9611uxc_read_version(struct lt9611uxc *lt9611uxc)
return ret < 0 ? ret : rev;
}
-static int lt9611uxc_hdmi_hw_params(struct device *dev, void *data,
- struct hdmi_codec_daifmt *fmt,
- struct hdmi_codec_params *hparms)
-{
- /*
- * LT9611UXC will automatically detect rate and sample size, so no need
- * to setup anything here.
- */
- return 0;
-}
-
-static void lt9611uxc_audio_shutdown(struct device *dev, void *data)
-{
-}
-
-static int lt9611uxc_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
- struct device_node *endpoint,
- void *data)
-{
- struct of_endpoint of_ep;
- int ret;
-
- ret = of_graph_parse_endpoint(endpoint, &of_ep);
- if (ret < 0)
- return ret;
-
- /*
- * HDMI sound should be located as reg = <2>
- * Then, it is sound port 0
- */
- if (of_ep.port == 2)
- return 0;
-
- return -EINVAL;
-}
-
-static const struct hdmi_codec_ops lt9611uxc_codec_ops = {
- .hw_params = lt9611uxc_hdmi_hw_params,
- .audio_shutdown = lt9611uxc_audio_shutdown,
- .get_dai_id = lt9611uxc_hdmi_i2s_get_dai_id,
-};
-
-static int lt9611uxc_audio_init(struct device *dev, struct lt9611uxc *lt9611uxc)
-{
- struct hdmi_codec_pdata codec_data = {
- .ops = <9611uxc_codec_ops,
- .max_i2s_channels = 2,
- .i2s = 1,
- .data = lt9611uxc,
- };
-
- lt9611uxc->audio_pdev =
- platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
- PLATFORM_DEVID_AUTO,
- &codec_data, sizeof(codec_data));
-
- return PTR_ERR_OR_ZERO(lt9611uxc->audio_pdev);
-}
-
-static void lt9611uxc_audio_exit(struct lt9611uxc *lt9611uxc)
-{
- if (lt9611uxc->audio_pdev) {
- platform_device_unregister(lt9611uxc->audio_pdev);
- lt9611uxc->audio_pdev = NULL;
- }
-}
-
#define LT9611UXC_FW_PAGE_SIZE 32
static void lt9611uxc_firmware_write_page(struct lt9611uxc *lt9611uxc, u16 addr, const u8 *buf)
{
@@ -858,11 +830,17 @@ static int lt9611uxc_probe(struct i2c_client *client)
i2c_set_clientdata(client, lt9611uxc);
lt9611uxc->bridge.of_node = client->dev.of_node;
- lt9611uxc->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID;
+ lt9611uxc->bridge.ops = DRM_BRIDGE_OP_DETECT |
+ DRM_BRIDGE_OP_EDID |
+ DRM_BRIDGE_OP_HDMI_AUDIO;
if (lt9611uxc->hpd_supported)
lt9611uxc->bridge.ops |= DRM_BRIDGE_OP_HPD;
lt9611uxc->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
+ lt9611uxc->bridge.hdmi_audio_dev = dev;
+ lt9611uxc->bridge.hdmi_audio_max_i2s_playback_channels = 2;
+ lt9611uxc->bridge.hdmi_audio_dai_port = 2;
+
drm_bridge_add(<9611uxc->bridge);
/* Attach primary DSI */
@@ -881,10 +859,6 @@ static int lt9611uxc_probe(struct i2c_client *client)
}
}
- ret = lt9611uxc_audio_init(dev, lt9611uxc);
- if (ret)
- goto err_remove_bridge;
-
return 0;
err_remove_bridge:
@@ -908,7 +882,6 @@ static void lt9611uxc_remove(struct i2c_client *client)
free_irq(client->irq, lt9611uxc);
cancel_work_sync(<9611uxc->work);
- lt9611uxc_audio_exit(lt9611uxc);
drm_bridge_remove(<9611uxc->bridge);
mutex_destroy(<9611uxc->ocm_lock);
--
2.39.5
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-07-18 15:21 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-18 15:21 [PATCH 0/2] drm/bridge: lontium-lt9611uxc: switch to DRM_BRIDGE_OP_HDMI_AUDIO Dmitry Baryshkov
2025-07-18 15:21 ` [PATCH 1/2] drm/bridge: add connector argument to .hpd_notify callback Dmitry Baryshkov
2025-07-18 15:21 ` [PATCH 2/2] drm/bridge: lontium-lt9611uxc: switch to HDMI audio helpers Dmitry Baryshkov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).