From e3e12f52b214121840b44c91de5b3e5af5d3eb84 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 06 Nov 2023 03:04:41 +0000 Subject: [PATCH] rk3568 rt init --- kernel/sound/soc/codecs/hdmi-codec.c | 67 +++++++++++++++++++++++++++++++-- 1 files changed, 62 insertions(+), 5 deletions(-) diff --git a/kernel/sound/soc/codecs/hdmi-codec.c b/kernel/sound/soc/codecs/hdmi-codec.c index 0cb4976..93fa207 100644 --- a/kernel/sound/soc/codecs/hdmi-codec.c +++ b/kernel/sound/soc/codecs/hdmi-codec.c @@ -14,6 +14,7 @@ */ #include <linux/module.h> #include <linux/string.h> +#include <linux/extcon-provider.h> #include <sound/core.h> #include <sound/jack.h> #include <sound/pcm.h> @@ -277,6 +278,11 @@ .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC }, }; +static const unsigned int hdmi_extcon_cable[] = { + EXTCON_DISP_HDMI_AUDIO, + EXTCON_NONE, +}; + struct hdmi_codec_priv { struct hdmi_codec_pdata hcd; struct snd_soc_dai_driver *daidrv; @@ -288,6 +294,7 @@ unsigned int chmap_idx; unsigned int mode; struct snd_soc_jack *jack; + struct extcon_dev *edev; unsigned int jack_status; }; @@ -498,7 +505,8 @@ WARN_ON(hcp->current_stream != substream); hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; - hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data); + if (hcp->hcd.ops->audio_shutdown) + hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data); mutex_lock(&hcp->current_stream_lock); hcp->current_stream = NULL; @@ -774,10 +782,48 @@ { struct hdmi_codec_priv *hcp = dev_get_drvdata(dev); - if (plugged) + if (plugged) { hdmi_codec_jack_report(hcp, SND_JACK_LINEOUT); - else + extcon_set_state_sync(hcp->edev, + EXTCON_DISP_HDMI_AUDIO, true); + } else { hdmi_codec_jack_report(hcp, 0); + extcon_set_state_sync(hcp->edev, + EXTCON_DISP_HDMI_AUDIO, false); + } + + mutex_lock(&hcp->current_stream_lock); + if (hcp->current_stream) { + /* + * Workaround for HDMIIN and HDMIOUT plug-{in,out} when streaming. + * + * Actually, we should do stop stream both for HDMI_{OUT,IN} on + * plug-{out,in} event. but for better experience and depop stream, + * we optimize as follows: + * + * a) Do stop stream for HDMIIN on plug-out when streaming. + * because HDMIIN work as SLAVE mode, CLK lost after HDMI cable + * plugged out which will make stream stuck until ALSA timeout(10s). + * so, for better experience, we should stop stream at the moment. + * + * b) Do stop stream for HDMIOUT on plug-in when streaming. + * because HDMIOUT work as MASTER mode, there is no clk-issue like + * HDMIIN, but, on HDR situation, HDMI will be reconfigured which + * make HDMI audio configure lost, especially for NLPCM/HBR bitstream + * which require IEC937 packet alignment, so, for this situation, + * we stop stream to notify user to re-open and configure sound card + * and then go on streaming. + */ + int stream = hcp->current_stream->stream; + + if (stream == SNDRV_PCM_STREAM_PLAYBACK && plugged) + snd_pcm_stop(hcp->current_stream, SNDRV_PCM_STATE_SETUP); + else if (stream == SNDRV_PCM_STREAM_CAPTURE && !plugged) + snd_pcm_stop(hcp->current_stream, SNDRV_PCM_STATE_DISCONNECTED); + + dev_dbg(dev, "stream[%d]: %s\n", stream, plugged ? "plug in" : "plug out"); + } + mutex_unlock(&hcp->current_stream_lock); } static int hdmi_codec_set_jack(struct snd_soc_component *component, @@ -884,8 +930,7 @@ } dai_count = hcd->i2s + hcd->spdif; - if (dai_count < 1 || !hcd->ops || !hcd->ops->hw_params || - !hcd->ops->audio_shutdown) { + if (dai_count < 1 || !hcd->ops || !hcd->ops->hw_params) { dev_err(dev, "%s: Invalid parameters\n", __func__); return -EINVAL; } @@ -916,6 +961,18 @@ dev_set_drvdata(dev, hcp); + hcp->edev = devm_extcon_dev_allocate(&pdev->dev, hdmi_extcon_cable); + if (IS_ERR(hcp->edev)) { + dev_err(&pdev->dev, "Failed to allocate extcon device\n"); + return -ENOMEM; + } + + ret = devm_extcon_dev_register(&pdev->dev, hcp->edev); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to register extcon device\n"); + return ret; + } + ret = devm_snd_soc_register_component(dev, &hdmi_driver, hcp->daidrv, dai_count); if (ret) { -- Gitblit v1.6.2