[PATCH] drm/omap: Report HDMI hotplug events to the ASoC HDMI codec
Ivaylo Dimitrov <[email protected]> Wed, 5 Aug 2026 18:20:57 +0300
| Newsgroups | gmane.linux.ports.arm.omap,gmane.comp.video.dri.devel,gmane.linux.kernel,gmane.linux.sound |
|---|---|
| Message-ID | <[email protected]> |
The OMAP HDMI audio driver currently has no way of reporting HDMI cable hotplug events to ASoC. As a result, user space cannot detect HDMI audio availability through the standard jack mechanism and audio policy managers cannot automatically route audio to or from the HDMI output. Add an optional HPD callback to `omap_hdmi_audio_pdata` and invoke it from the DRM HDMI bridge whenever the connector status changes. The HDMI audio driver registers an ASoC jack and reports `SND_JACK_AVOUT` state changes in response to these notifications. Also fix the disconnect path by taking a runtime PM reference before updating the CEC physical address. Signed-off-by: Ivaylo Dimitrov <[email protected]> --- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 12 ++++++++++- include/sound/omap-hdmi-audio.h | 1 + sound/soc/ti/omap-hdmi.c | 33 +++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index e306247ed8a0..b466bbdae5cc 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -432,9 +432,19 @@ static void hdmi4_bridge_hpd_notify(struct drm_bridge *bridge, enum drm_connector_status status) { struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge); + struct device *dev = &hdmi->audio_pdev->dev; + struct omap_hdmi_audio_pdata *ha = dev_get_platdata(dev); + + if (ha->audio_hpd) + ha->audio_hpd(dev, status == connector_status_connected); + + if (status == connector_status_disconnected) { + if (hdmi_runtime_get(hdmi)) + return; - if (status == connector_status_disconnected) hdmi4_cec_set_phys_addr(&hdmi->core, CEC_PHYS_ADDR_INVALID); + hdmi_runtime_put(hdmi); + } } static const struct drm_edid *hdmi4_bridge_edid_read(struct drm_bridge *bridge, diff --git a/include/sound/omap-hdmi-audio.h b/include/sound/omap-hdmi-audio.h index e5f82044a404..8dca92360ee0 100644 --- a/include/sound/omap-hdmi-audio.h +++ b/include/sound/omap-hdmi-audio.h @@ -34,6 +34,7 @@ struct omap_hdmi_audio_pdata { phys_addr_t audio_dma_addr; const struct omap_hdmi_audio_ops *ops; + void (*audio_hpd)(struct device *dev, bool connected); }; #endif /* __OMAP_HDMI_AUDIO_H__ */ diff --git a/sound/soc/ti/omap-hdmi.c b/sound/soc/ti/omap-hdmi.c index e60f5b483fc5..333aa308979e 100644 --- a/sound/soc/ti/omap-hdmi.c +++ b/sound/soc/ti/omap-hdmi.c @@ -17,6 +17,7 @@ #include <sound/dmaengine_pcm.h> #include <uapi/sound/asound.h> #include <sound/asoundef.h> +#include <sound/jack.h> #include <sound/omap-hdmi-audio.h> #include "sdma-pcm.h" @@ -35,6 +36,8 @@ struct hdmi_audio_data { struct mutex current_stream_lock; struct snd_pcm_substream *current_stream; + struct snd_soc_jack jack; + atomic_t jack_state; }; static @@ -262,6 +265,18 @@ static void hdmi_dai_shutdown(struct snd_pcm_substream *substream, ad->current_stream = NULL; } +static void hdmi_audio_hpd(struct device *dev, bool connected) +{ + struct hdmi_audio_data *ad = dev_get_drvdata(dev); + + if (atomic_xchg(&ad->jack_state, connected) == connected) + return; + + snd_soc_jack_report(&ad->jack, + connected ? SND_JACK_AVOUT : 0, SND_JACK_AVOUT); + dev_dbg(dev, "HDMI %s\n", connected ? "CONNECTED" : "DISCONNECTED"); +} + static const struct snd_soc_dai_ops hdmi_dai_ops = { .startup = hdmi_dai_startup, .hw_params = hdmi_dai_hw_params, @@ -380,19 +395,37 @@ static int omap_hdmi_audio_probe(struct platform_device *pdev) return ret; } + atomic_set(&ad->jack_state, -1); ad->card = card; snd_soc_card_set_drvdata(card, ad); dev_set_drvdata(dev, ad); + ret = snd_soc_card_jack_new( + card, "HDMI", SND_JACK_AVOUT, &ad->jack); + if (ret < 0) { + dev_err(dev, "Cannot create HDMI jack: %i\n", ret); + return ret; + } + + ha->audio_hpd = hdmi_audio_hpd; + return 0; } +static void omap_hdmi_audio_remove(struct platform_device *pdev) +{ + struct omap_hdmi_audio_pdata *ha = pdev->dev.platform_data; + + ha->audio_hpd = NULL; +} + static struct platform_driver hdmi_audio_driver = { .driver = { .name = DRV_NAME, }, .probe = omap_hdmi_audio_probe, + .remove = omap_hdmi_audio_remove, }; module_platform_driver(hdmi_audio_driver); -- 2.39.5