diff options
Diffstat (limited to 'target/linux/bcm27xx/patches-5.10/950-0635-ASoC-hdmi-codec-Add-a-prepare-hook.patch')
-rw-r--r-- | target/linux/bcm27xx/patches-5.10/950-0635-ASoC-hdmi-codec-Add-a-prepare-hook.patch | 202 |
1 files changed, 0 insertions, 202 deletions
diff --git a/target/linux/bcm27xx/patches-5.10/950-0635-ASoC-hdmi-codec-Add-a-prepare-hook.patch b/target/linux/bcm27xx/patches-5.10/950-0635-ASoC-hdmi-codec-Add-a-prepare-hook.patch deleted file mode 100644 index 1f71d06eb9..0000000000 --- a/target/linux/bcm27xx/patches-5.10/950-0635-ASoC-hdmi-codec-Add-a-prepare-hook.patch +++ /dev/null @@ -1,202 +0,0 @@ -From 067cda9dd7d018b033877df4996383b3529fdbad Mon Sep 17 00:00:00 2001 -From: Maxime Ripard <maxime@cerno.tech> -Date: Fri, 30 Apr 2021 14:22:06 +0200 -Subject: [PATCH] ASoC: hdmi-codec: Add a prepare hook - -The IEC958 status bit is usually set by the userspace after hw_params -has been called, so in order to use whatever is set by the userspace, we -need to implement the prepare hook. Let's add it to the hdmi_codec_ops, -and mandate that either prepare or hw_params is implemented. - -Signed-off-by: Maxime Ripard <maxime@cerno.tech> ---- - include/sound/hdmi-codec.h | 12 +++- - sound/soc/codecs/hdmi-codec.c | 112 ++++++++++++++++++++++++++-------- - 2 files changed, 99 insertions(+), 25 deletions(-) - ---- a/include/sound/hdmi-codec.h -+++ b/include/sound/hdmi-codec.h -@@ -65,13 +65,23 @@ struct hdmi_codec_ops { - - /* - * Configures HDMI-encoder for audio stream. -- * Mandatory -+ * Having either prepare or hw_params is mandatory. - */ - int (*hw_params)(struct device *dev, void *data, - struct hdmi_codec_daifmt *fmt, - struct hdmi_codec_params *hparms); - - /* -+ * Configures HDMI-encoder for audio stream. Can be called -+ * multiple times for each setup. -+ * -+ * Having either prepare or hw_params is mandatory. -+ */ -+ int (*prepare)(struct device *dev, void *data, -+ struct hdmi_codec_daifmt *fmt, -+ struct hdmi_codec_params *hparms); -+ -+ /* - * Shuts down the audio stream. - * Mandatory - */ ---- a/sound/soc/codecs/hdmi-codec.c -+++ b/sound/soc/codecs/hdmi-codec.c -@@ -480,6 +480,42 @@ static void hdmi_codec_shutdown(struct s - mutex_unlock(&hcp->lock); - } - -+static int hdmi_codec_fill_codec_params(struct snd_soc_dai *dai, -+ unsigned int sample_width, -+ unsigned int sample_rate, -+ unsigned int channels, -+ struct hdmi_codec_params *hp) -+{ -+ struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); -+ int idx; -+ -+ /* Select a channel allocation that matches with ELD and pcm channels */ -+ idx = hdmi_codec_get_ch_alloc_table_idx(hcp, channels); -+ if (idx < 0) { -+ dev_err(dai->dev, "Not able to map channels to speakers (%d)\n", -+ idx); -+ hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; -+ return idx; -+ } -+ -+ memset(hp, 0, sizeof(*hp)); -+ -+ hdmi_audio_infoframe_init(&hp->cea); -+ hp->cea.channels = channels; -+ hp->cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM; -+ hp->cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; -+ hp->cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; -+ hp->cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id; -+ -+ hp->sample_width = sample_width; -+ hp->sample_rate = sample_rate; -+ hp->channels = channels; -+ -+ hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id; -+ -+ return 0; -+} -+ - static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -@@ -494,13 +530,24 @@ static int hdmi_codec_hw_params(struct s - .dig_subframe = { 0 }, - } - }; -- int ret, idx; -+ int ret; -+ -+ if (!hcp->hcd.ops->hw_params) -+ return 0; - - dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__, - params_width(params), params_rate(params), - params_channels(params)); - -- memcpy(hp.iec.status, hcp->iec_status, sizeof(hp->iec_status)); -+ ret = hdmi_codec_fill_codec_params(dai, -+ params_width(params), -+ params_rate(params), -+ params_channels(params), -+ &hp); -+ if (ret < 0) -+ return ret; -+ -+ memcpy(hp.iec.status, hcp->iec_status, sizeof(hp.iec.status)); - ret = snd_pcm_fill_iec958_consumer_hw_params(params, hp.iec.status, - sizeof(hp.iec.status)); - if (ret < 0) { -@@ -509,32 +556,47 @@ static int hdmi_codec_hw_params(struct s - return ret; - } - -- hdmi_audio_infoframe_init(&hp.cea); -- hp.cea.channels = params_channels(params); -- hp.cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM; -- hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; -- hp.cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; -- -- /* Select a channel allocation that matches with ELD and pcm channels */ -- idx = hdmi_codec_get_ch_alloc_table_idx(hcp, hp.cea.channels); -- if (idx < 0) { -- dev_err(dai->dev, "Not able to map channels to speakers (%d)\n", -- idx); -- hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; -- return idx; -- } -- hp.cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id; -- hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id; -- -- hp.sample_width = params_width(params); -- hp.sample_rate = params_rate(params); -- hp.channels = params_channels(params); -- - cf->bit_fmt = params_format(params); - return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data, - cf, &hp); - } - -+static int hdmi_codec_prepare(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+ struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); -+ struct hdmi_codec_daifmt *cf = dai->playback_dma_data; -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ unsigned int channels = runtime->channels; -+ unsigned int width = snd_pcm_format_width(runtime->format); -+ unsigned int rate = runtime->rate; -+ struct hdmi_codec_params hp; -+ int ret; -+ -+ if (!hcp->hcd.ops->prepare) -+ return 0; -+ -+ dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__, -+ width, rate, channels); -+ -+ ret = hdmi_codec_fill_codec_params(dai, width, rate, channels, &hp); -+ if (ret < 0) -+ return ret; -+ -+ memcpy(hp.iec.status, hcp->iec_status, sizeof(hp.iec.status)); -+ ret = snd_pcm_fill_iec958_consumer(runtime, hp.iec.status, -+ sizeof(hp.iec.status)); -+ if (ret < 0) { -+ dev_err(dai->dev, "Creating IEC958 channel status failed %d\n", -+ ret); -+ return ret; -+ } -+ -+ cf->bit_fmt = runtime->format; -+ return hcp->hcd.ops->prepare(dai->dev->parent, hcp->hcd.data, -+ cf, &hp); -+} -+ - static int hdmi_codec_i2s_set_fmt(struct snd_soc_dai *dai, - unsigned int fmt) - { -@@ -626,6 +688,7 @@ static const struct snd_soc_dai_ops hdmi - .startup = hdmi_codec_startup, - .shutdown = hdmi_codec_shutdown, - .hw_params = hdmi_codec_hw_params, -+ .prepare = hdmi_codec_prepare, - .set_fmt = hdmi_codec_i2s_set_fmt, - .mute_stream = hdmi_codec_mute, - }; -@@ -889,7 +952,8 @@ static int hdmi_codec_probe(struct platf - } - - dai_count = hcd->i2s + hcd->spdif; -- if (dai_count < 1 || !hcd->ops || !hcd->ops->hw_params || -+ if (dai_count < 1 || !hcd->ops || -+ (!hcd->ops->hw_params && !hcd->ops->prepare) || - !hcd->ops->audio_shutdown) { - dev_err(dev, "%s: Invalid parameters\n", __func__); - return -EINVAL; |