mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-21 22:47:56 +00:00
8c405cdccc
The patches were generated from the RPi repo with the following command: git format-patch v6.6.34..rpi-6.1.y Some patches needed rebasing and, as usual, the applied and reverted, wireless drivers, Github workflows, READMEs and defconfigs patches were removed. Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
188 lines
5.5 KiB
Diff
188 lines
5.5 KiB
Diff
From 051392bfdc6dc54563ed9909cc1164e8d734af43 Mon Sep 17 00:00:00 2001
|
|
From: David Turner <david.turner@raspberrypi.com>
|
|
Date: Wed, 28 Feb 2024 10:55:39 +0000
|
|
Subject: [PATCH 0930/1085] vc4: Add jack detection to HDMI audio driver
|
|
|
|
Add ALSA jack detection to the vc4-hdmi audio driver so userspace knows
|
|
when to add/remove HDMI audio devices.
|
|
|
|
Signed-off-by: David Turner <david.turner@raspberrypi.com>
|
|
---
|
|
drivers/gpu/drm/vc4/vc4_hdmi.c | 61 ++++++++++++++++++++++++++++++++--
|
|
drivers/gpu/drm/vc4/vc4_hdmi.h | 27 +++++++++++++++
|
|
2 files changed, 86 insertions(+), 2 deletions(-)
|
|
|
|
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
|
|
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
|
|
@@ -50,6 +50,7 @@
|
|
#include <linux/reset.h>
|
|
#include <sound/dmaengine_pcm.h>
|
|
#include <sound/hdmi-codec.h>
|
|
+#include <sound/jack.h>
|
|
#include <sound/pcm_drm_eld.h>
|
|
#include <sound/pcm_params.h>
|
|
#include <sound/soc.h>
|
|
@@ -421,7 +422,7 @@ static void vc4_hdmi_handle_hotplug(stru
|
|
enum drm_connector_status status)
|
|
{
|
|
struct drm_connector *connector = &vc4_hdmi->connector;
|
|
- struct edid *edid;
|
|
+ struct edid *edid = NULL;
|
|
int ret;
|
|
|
|
/*
|
|
@@ -439,12 +440,25 @@ static void vc4_hdmi_handle_hotplug(stru
|
|
* the lock for now.
|
|
*/
|
|
|
|
+ if (status != connector_status_disconnected)
|
|
+ edid = drm_get_edid(connector, vc4_hdmi->ddc);
|
|
+
|
|
+ /*
|
|
+ * Report plugged/unplugged events to ALSA jack detection. Do this
|
|
+ * *after* EDID probing, otherwise userspace might try to bring up
|
|
+ * audio before it's ready.
|
|
+ */
|
|
+ mutex_lock(&vc4_hdmi->update_plugged_status_lock);
|
|
+ if (vc4_hdmi->plugged_cb && vc4_hdmi->codec_dev)
|
|
+ vc4_hdmi->plugged_cb(vc4_hdmi->codec_dev,
|
|
+ status != connector_status_disconnected);
|
|
+ mutex_unlock(&vc4_hdmi->update_plugged_status_lock);
|
|
+
|
|
if (status == connector_status_disconnected) {
|
|
cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
|
|
return;
|
|
}
|
|
|
|
- edid = drm_get_edid(connector, vc4_hdmi->ddc);
|
|
if (!edid)
|
|
return;
|
|
|
|
@@ -2691,8 +2705,23 @@ static int vc4_hdmi_audio_get_eld(struct
|
|
return 0;
|
|
}
|
|
|
|
+static int vc4_hdmi_audio_hook_plugged_cb(struct device *dev, void *data,
|
|
+ hdmi_codec_plugged_cb fn,
|
|
+ struct device *codec_dev)
|
|
+{
|
|
+ struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
|
|
+
|
|
+ mutex_lock(&vc4_hdmi->update_plugged_status_lock);
|
|
+ vc4_hdmi->plugged_cb = fn;
|
|
+ vc4_hdmi->codec_dev = codec_dev;
|
|
+ mutex_unlock(&vc4_hdmi->update_plugged_status_lock);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static const struct hdmi_codec_ops vc4_hdmi_codec_ops = {
|
|
.get_eld = vc4_hdmi_audio_get_eld,
|
|
+ .hook_plugged_cb = vc4_hdmi_audio_hook_plugged_cb,
|
|
.prepare = vc4_hdmi_audio_prepare,
|
|
.audio_shutdown = vc4_hdmi_audio_shutdown,
|
|
.audio_startup = vc4_hdmi_audio_startup,
|
|
@@ -2712,6 +2741,22 @@ static void vc4_hdmi_audio_codec_release
|
|
vc4_hdmi->audio.codec_pdev = NULL;
|
|
}
|
|
|
|
+static int vc4_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd)
|
|
+{
|
|
+ struct vc4_hdmi *vc4_hdmi = snd_soc_card_get_drvdata(rtd->card);
|
|
+ struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
|
|
+ int ret;
|
|
+
|
|
+ ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
|
|
+ &vc4_hdmi->hdmi_jack);
|
|
+ if (ret) {
|
|
+ dev_err(rtd->dev, "HDMI Jack creation failed: %d\n", ret);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ return snd_soc_component_set_jack(component, &vc4_hdmi->hdmi_jack, NULL);
|
|
+}
|
|
+
|
|
static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
|
|
{
|
|
const struct vc4_hdmi_register *mai_data =
|
|
@@ -2841,6 +2886,8 @@ static int vc4_hdmi_audio_init(struct vc
|
|
dai_link->codecs->name = dev_name(&codec_pdev->dev);
|
|
dai_link->platforms->name = dev_name(dev);
|
|
|
|
+ dai_link->init = vc4_hdmi_codec_init;
|
|
+
|
|
card->dai_link = dai_link;
|
|
card->num_links = 1;
|
|
card->name = vc4_hdmi->variant->card_name;
|
|
@@ -3701,6 +3748,8 @@ static int vc4_hdmi_bind(struct device *
|
|
if (ret)
|
|
return ret;
|
|
|
|
+ mutex_init(&vc4_hdmi->update_plugged_status_lock);
|
|
+
|
|
spin_lock_init(&vc4_hdmi->hw_lock);
|
|
INIT_DELAYED_WORK(&vc4_hdmi->scrambling_work, vc4_hdmi_scrambling_wq);
|
|
|
|
@@ -3813,8 +3862,16 @@ err_put_runtime_pm:
|
|
return ret;
|
|
}
|
|
|
|
+static void vc4_hdmi_unbind(struct device *dev, struct device *master, void *data)
|
|
+{
|
|
+ struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
|
|
+
|
|
+ mutex_destroy(&vc4_hdmi->update_plugged_status_lock);
|
|
+}
|
|
+
|
|
static const struct component_ops vc4_hdmi_ops = {
|
|
.bind = vc4_hdmi_bind,
|
|
+ .unbind = vc4_hdmi_unbind,
|
|
};
|
|
|
|
static int vc4_hdmi_dev_probe(struct platform_device *pdev)
|
|
--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
|
|
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
|
|
@@ -2,8 +2,10 @@
|
|
#define _VC4_HDMI_H_
|
|
|
|
#include <drm/drm_connector.h>
|
|
+#include <linux/mutex.h>
|
|
#include <media/cec.h>
|
|
#include <sound/dmaengine_pcm.h>
|
|
+#include <sound/hdmi-codec.h>
|
|
#include <sound/soc.h>
|
|
|
|
#include "vc4_drv.h"
|
|
@@ -228,6 +230,31 @@ struct vc4_hdmi {
|
|
* for use outside of KMS hooks. Protected by @mutex.
|
|
*/
|
|
enum vc4_hdmi_output_format output_format;
|
|
+
|
|
+ /**
|
|
+ * @plugged_cb: Callback provided by hdmi-codec to indicate that an
|
|
+ * HDMI hotplug occurred and jack state should be updated. Protected by
|
|
+ * @update_plugged_status_lock.
|
|
+ */
|
|
+ hdmi_codec_plugged_cb plugged_cb;
|
|
+
|
|
+ /**
|
|
+ * @plugged_cb: Context for plugged_cb. Protected by
|
|
+ * @update_plugged_status_lock.
|
|
+ */
|
|
+ struct device *codec_dev;
|
|
+
|
|
+ /**
|
|
+ * @update_plugged_status_lock: Prevents a race condition where an HDMI
|
|
+ * hotplug might occur between @plugged_cb and @codec_dev being set.
|
|
+ */
|
|
+ struct mutex update_plugged_status_lock;
|
|
+
|
|
+ /**
|
|
+ * @hdmi_jack: Represents the connection state of the HDMI plug, for
|
|
+ * ALSA jack detection.
|
|
+ */
|
|
+ struct snd_soc_jack hdmi_jack;
|
|
};
|
|
|
|
#define connector_to_vc4_hdmi(_connector) \
|