diff --git a/packages/linux/patches/default/linux-020-ALSA-pcm-fix-ELD-constraints-for-E-AC3-DTS-HD-and-ML.patch b/packages/linux/patches/default/linux-020-ALSA-pcm-fix-ELD-constraints-for-E-AC3-DTS-HD-and-ML.patch new file mode 100644 index 0000000000..3478eb7e09 --- /dev/null +++ b/packages/linux/patches/default/linux-020-ALSA-pcm-fix-ELD-constraints-for-E-AC3-DTS-HD-and-ML.patch @@ -0,0 +1,138 @@ +From 94d0a9815c99385e57a17fb20448e47a1f229bcf Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sat, 3 Jun 2023 12:00:28 +0200 +Subject: [PATCH 1/2] ALSA: pcm: fix ELD constraints for (E)AC3, DTS(-HD) and + MLP formats + +The SADs of compressed formats contain the channel and sample rate +info of the audio data inside the compressed stream, but when +building constraints we must use the rates and channels used to +transport the compressed streams. + +eg 48kHz 6ch EAC3 needs to be transmitted as a 2ch 192kHz stream. + +This patch fixes the constraints for the common AC3 and DTS formats, +the constraints for the less common MPEG, DSD etc formats are copied +directly from the info in the SADs as before as I don't have the specs +and equipment to test those. + +Signed-off-by: Matthias Reichl +--- + sound/core/pcm_drm_eld.c | 73 ++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 70 insertions(+), 3 deletions(-) + +diff --git a/sound/core/pcm_drm_eld.c b/sound/core/pcm_drm_eld.c +index 4b5faae5d16e5..07075071972dd 100644 +--- a/sound/core/pcm_drm_eld.c ++++ b/sound/core/pcm_drm_eld.c +@@ -2,11 +2,25 @@ + /* + * PCM DRM helpers + */ ++#include + #include ++#include + #include + #include + #include + ++#define SAD0_CHANNELS_MASK GENMASK(2, 0) /* max number of channels - 1 */ ++#define SAD0_FORMAT_MASK GENMASK(6, 3) /* audio format */ ++ ++#define SAD1_RATE_MASK GENMASK(6, 0) /* bitfield of supported rates */ ++#define SAD1_RATE_32000_MASK BIT(0) ++#define SAD1_RATE_44100_MASK BIT(1) ++#define SAD1_RATE_48000_MASK BIT(2) ++#define SAD1_RATE_88200_MASK BIT(3) ++#define SAD1_RATE_96000_MASK BIT(4) ++#define SAD1_RATE_176400_MASK BIT(5) ++#define SAD1_RATE_192000_MASK BIT(6) ++ + static const unsigned int eld_rates[] = { + 32000, + 44100, +@@ -17,9 +31,62 @@ static const unsigned int eld_rates[] = { + 192000, + }; + ++static unsigned int map_rate_families(const u8 *sad, ++ unsigned int mask_32000, ++ unsigned int mask_44100, ++ unsigned int mask_48000) ++{ ++ unsigned int rate_mask = 0; ++ ++ if (sad[1] & SAD1_RATE_32000_MASK) ++ rate_mask |= mask_32000; ++ if (sad[1] & (SAD1_RATE_44100_MASK | SAD1_RATE_88200_MASK | SAD1_RATE_176400_MASK)) ++ rate_mask |= mask_44100; ++ if (sad[1] & (SAD1_RATE_48000_MASK | SAD1_RATE_96000_MASK | SAD1_RATE_192000_MASK)) ++ rate_mask |= mask_48000; ++ return rate_mask; ++} ++ ++static unsigned int sad_rate_mask(const u8 *sad) ++{ ++ switch (FIELD_GET(SAD0_FORMAT_MASK, sad[0])) { ++ case HDMI_AUDIO_CODING_TYPE_PCM: ++ return sad[1] & SAD1_RATE_MASK; ++ case HDMI_AUDIO_CODING_TYPE_AC3: ++ case HDMI_AUDIO_CODING_TYPE_DTS: ++ return map_rate_families(sad, ++ SAD1_RATE_32000_MASK, ++ SAD1_RATE_44100_MASK, ++ SAD1_RATE_48000_MASK); ++ case HDMI_AUDIO_CODING_TYPE_EAC3: ++ case HDMI_AUDIO_CODING_TYPE_DTS_HD: ++ case HDMI_AUDIO_CODING_TYPE_MLP: ++ return map_rate_families(sad, ++ 0, ++ SAD1_RATE_176400_MASK, ++ SAD1_RATE_192000_MASK); ++ default: ++ /* TODO adjust for other compressed formats as well */ ++ return sad[1] & SAD1_RATE_MASK; ++ } ++} ++ + static unsigned int sad_max_channels(const u8 *sad) + { +- return 1 + (sad[0] & 7); ++ switch (FIELD_GET(SAD0_FORMAT_MASK, sad[0])) { ++ case HDMI_AUDIO_CODING_TYPE_PCM: ++ return 1 + FIELD_GET(SAD0_CHANNELS_MASK, sad[0]); ++ case HDMI_AUDIO_CODING_TYPE_AC3: ++ case HDMI_AUDIO_CODING_TYPE_DTS: ++ case HDMI_AUDIO_CODING_TYPE_EAC3: ++ return 2; ++ case HDMI_AUDIO_CODING_TYPE_DTS_HD: ++ case HDMI_AUDIO_CODING_TYPE_MLP: ++ return 8; ++ default: ++ /* TODO adjust for other compressed formats as well */ ++ return 1 + FIELD_GET(SAD0_CHANNELS_MASK, sad[0]); ++ } + } + + static int eld_limit_rates(struct snd_pcm_hw_params *params, +@@ -42,7 +109,7 @@ static int eld_limit_rates(struct snd_pcm_hw_params *params, + * requested number of channels. + */ + if (c->min <= max_channels) +- rate_mask |= sad[1]; ++ rate_mask |= sad_rate_mask(sad); + } + } + +@@ -70,7 +137,7 @@ static int eld_limit_channels(struct snd_pcm_hw_params *params, + rate_mask |= BIT(i); + + for (i = drm_eld_sad_count(eld); i > 0; i--, sad += 3) +- if (rate_mask & sad[1]) ++ if (rate_mask & sad_rate_mask(sad)) + t.max = max(t.max, sad_max_channels(sad)); + } + +-- +2.39.2 + diff --git a/packages/linux/patches/default/linux-020-eld-constraints-for-compressed-formats.patch b/packages/linux/patches/default/linux-020-eld-constraints-for-compressed-formats.patch deleted file mode 100644 index bb74ff7bd7..0000000000 --- a/packages/linux/patches/default/linux-020-eld-constraints-for-compressed-formats.patch +++ /dev/null @@ -1,91 +0,0 @@ -From a2769637a9b98c6809d4d25a3a20447a3ff7b23a Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Fri, 19 Mar 2021 12:14:17 +0100 -Subject: [PATCH] ALSA: pcm: fix ELD constraints for some compressed audio - formats - -The SADs of compressed formats like AC3 and DTS contain the channel -and sample rate info of the audio data inside the compressed stream, -but when building constraints we must use the rates and formats used -to pass through the stream. eg 2ch 48kHz for AC3. - -Signed-off-by: Matthias Reichl ---- - sound/core/pcm_drm_eld.c | 38 +++++++++++++++++++++++++++++++++++--- - 1 file changed, 35 insertions(+), 3 deletions(-) - -diff --git a/sound/core/pcm_drm_eld.c b/sound/core/pcm_drm_eld.c -index 4b5faae5d16e5..e7ec7a8b9d420 100644 ---- a/sound/core/pcm_drm_eld.c -+++ b/sound/core/pcm_drm_eld.c -@@ -6,6 +6,7 @@ - #include - #include - #include -+#include - - static const unsigned int eld_rates[] = { - 32000, -@@ -17,9 +18,40 @@ static const unsigned int eld_rates[] = { - 192000, - }; - -+static unsigned int sad_format(const u8 *sad) -+{ -+ return (sad[0] & 0x78) >> 3; -+} -+ - static unsigned int sad_max_channels(const u8 *sad) - { -- return 1 + (sad[0] & 7); -+ switch (sad_format(sad)) { -+ case HDMI_AUDIO_CODING_TYPE_AC3: -+ case HDMI_AUDIO_CODING_TYPE_DTS: -+ case HDMI_AUDIO_CODING_TYPE_EAC3: -+ return 2; -+ case HDMI_AUDIO_CODING_TYPE_DTS_HD: -+ case HDMI_AUDIO_CODING_TYPE_MLP: -+ return 8; -+ default: -+ return 1 + (sad[0] & 7); -+ } -+} -+ -+static unsigned int sad_rate_mask(const u8 *sad) -+{ -+ switch (sad_format(sad)) { -+ case HDMI_AUDIO_CODING_TYPE_AC3: -+ case HDMI_AUDIO_CODING_TYPE_DTS: -+ return 0x07; // 32-48kHz -+ case HDMI_AUDIO_CODING_TYPE_EAC3: -+ return 0x7f; // 32-192kHz -+ case HDMI_AUDIO_CODING_TYPE_DTS_HD: -+ case HDMI_AUDIO_CODING_TYPE_MLP: -+ return 0x60; // 176.4, 192kHz -+ default: -+ return sad[1] & 0x7f; -+ } - } - - static int eld_limit_rates(struct snd_pcm_hw_params *params, -@@ -42,7 +74,7 @@ static int eld_limit_rates(struct snd_pcm_hw_params *params, - * requested number of channels. - */ - if (c->min <= max_channels) -- rate_mask |= sad[1]; -+ rate_mask |= sad_rate_mask(sad); - } - } - -@@ -70,7 +102,7 @@ static int eld_limit_channels(struct snd_pcm_hw_params *params, - rate_mask |= BIT(i); - - for (i = drm_eld_sad_count(eld); i > 0; i--, sad += 3) -- if (rate_mask & sad[1]) -+ if (rate_mask & sad_rate_mask(sad)) - t.max = max(t.max, sad_max_channels(sad)); - } - --- -2.20.1 - diff --git a/packages/linux/patches/default/linux-021-ASoC-hdmi-codec-don-t-set-channel-and-speaker-info-f.patch b/packages/linux/patches/default/linux-021-ASoC-hdmi-codec-don-t-set-channel-and-speaker-info-f.patch new file mode 100644 index 0000000000..d63c347e5a --- /dev/null +++ b/packages/linux/patches/default/linux-021-ASoC-hdmi-codec-don-t-set-channel-and-speaker-info-f.patch @@ -0,0 +1,89 @@ +From 99586e3f502fcc4fdd21b621f3c87ae7a8f7c170 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sat, 3 Jun 2023 12:12:28 +0200 +Subject: [PATCH 2/2] ASoC: hdmi-codec: don't set channel and speaker info for + compressed formats + +CTA 861 only mandates that the speaker allocation in the audio info frame +is set for multichannel PCM formats. Likewise the number of channels in the +audio infoframe is only relevant for PCM. + +Some TVs won't decode compressed formats if the number of channels isn't +set to 0 (refer to stream header) and the speaker allocation is set to the +default 0 (FL and FR). + +So fill in this info only for PCM audio and set it to 0 for compressed +audio formats. + +This also prevents hdmi_codec_prepare failing with an error when trying to +play back DTS-HD or MLP (which is passed through as 8ch) if the sink only +supports 2ch PCM and announces only FL/FR speaker support in the EDID. + +Signed-off-by: Matthias Reichl +--- + sound/soc/codecs/hdmi-codec.c | 36 +++++++++++++++++++++++------------ + 1 file changed, 24 insertions(+), 12 deletions(-) + +diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c +index 0b1cdb2d60498..a192d985c5f18 100644 +--- a/sound/soc/codecs/hdmi-codec.c ++++ b/sound/soc/codecs/hdmi-codec.c +@@ -484,31 +484,43 @@ static int hdmi_codec_fill_codec_params(struct snd_soc_dai *dai, + 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; ++ int idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; ++ u8 ca_id = 0; ++ bool pcm_audio = !(hcp->iec_status[0] & IEC958_AES0_NONAUDIO); ++ ++ if (pcm_audio) { ++ /* 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; ++ } ++ ++ ca_id = hdmi_codec_channel_alloc[idx].ca_id; + } + + memset(hp, 0, sizeof(*hp)); + + hdmi_audio_infoframe_init(&hp->cea); +- hp->cea.channels = channels; ++ ++ if (pcm_audio) ++ hp->cea.channels = channels; ++ else ++ hp->cea.channels = 0; ++ + 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->cea.channel_allocation = 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; ++ hcp->chmap_idx = idx; + + return 0; + } +-- +2.39.2 + diff --git a/packages/linux/patches/raspberrypi/linux-020-ALSA-pcm-fix-ELD-constraints-for-E-AC3-DTS-HD-and-ML.patch b/packages/linux/patches/raspberrypi/linux-020-ALSA-pcm-fix-ELD-constraints-for-E-AC3-DTS-HD-and-ML.patch new file mode 100644 index 0000000000..3478eb7e09 --- /dev/null +++ b/packages/linux/patches/raspberrypi/linux-020-ALSA-pcm-fix-ELD-constraints-for-E-AC3-DTS-HD-and-ML.patch @@ -0,0 +1,138 @@ +From 94d0a9815c99385e57a17fb20448e47a1f229bcf Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sat, 3 Jun 2023 12:00:28 +0200 +Subject: [PATCH 1/2] ALSA: pcm: fix ELD constraints for (E)AC3, DTS(-HD) and + MLP formats + +The SADs of compressed formats contain the channel and sample rate +info of the audio data inside the compressed stream, but when +building constraints we must use the rates and channels used to +transport the compressed streams. + +eg 48kHz 6ch EAC3 needs to be transmitted as a 2ch 192kHz stream. + +This patch fixes the constraints for the common AC3 and DTS formats, +the constraints for the less common MPEG, DSD etc formats are copied +directly from the info in the SADs as before as I don't have the specs +and equipment to test those. + +Signed-off-by: Matthias Reichl +--- + sound/core/pcm_drm_eld.c | 73 ++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 70 insertions(+), 3 deletions(-) + +diff --git a/sound/core/pcm_drm_eld.c b/sound/core/pcm_drm_eld.c +index 4b5faae5d16e5..07075071972dd 100644 +--- a/sound/core/pcm_drm_eld.c ++++ b/sound/core/pcm_drm_eld.c +@@ -2,11 +2,25 @@ + /* + * PCM DRM helpers + */ ++#include + #include ++#include + #include + #include + #include + ++#define SAD0_CHANNELS_MASK GENMASK(2, 0) /* max number of channels - 1 */ ++#define SAD0_FORMAT_MASK GENMASK(6, 3) /* audio format */ ++ ++#define SAD1_RATE_MASK GENMASK(6, 0) /* bitfield of supported rates */ ++#define SAD1_RATE_32000_MASK BIT(0) ++#define SAD1_RATE_44100_MASK BIT(1) ++#define SAD1_RATE_48000_MASK BIT(2) ++#define SAD1_RATE_88200_MASK BIT(3) ++#define SAD1_RATE_96000_MASK BIT(4) ++#define SAD1_RATE_176400_MASK BIT(5) ++#define SAD1_RATE_192000_MASK BIT(6) ++ + static const unsigned int eld_rates[] = { + 32000, + 44100, +@@ -17,9 +31,62 @@ static const unsigned int eld_rates[] = { + 192000, + }; + ++static unsigned int map_rate_families(const u8 *sad, ++ unsigned int mask_32000, ++ unsigned int mask_44100, ++ unsigned int mask_48000) ++{ ++ unsigned int rate_mask = 0; ++ ++ if (sad[1] & SAD1_RATE_32000_MASK) ++ rate_mask |= mask_32000; ++ if (sad[1] & (SAD1_RATE_44100_MASK | SAD1_RATE_88200_MASK | SAD1_RATE_176400_MASK)) ++ rate_mask |= mask_44100; ++ if (sad[1] & (SAD1_RATE_48000_MASK | SAD1_RATE_96000_MASK | SAD1_RATE_192000_MASK)) ++ rate_mask |= mask_48000; ++ return rate_mask; ++} ++ ++static unsigned int sad_rate_mask(const u8 *sad) ++{ ++ switch (FIELD_GET(SAD0_FORMAT_MASK, sad[0])) { ++ case HDMI_AUDIO_CODING_TYPE_PCM: ++ return sad[1] & SAD1_RATE_MASK; ++ case HDMI_AUDIO_CODING_TYPE_AC3: ++ case HDMI_AUDIO_CODING_TYPE_DTS: ++ return map_rate_families(sad, ++ SAD1_RATE_32000_MASK, ++ SAD1_RATE_44100_MASK, ++ SAD1_RATE_48000_MASK); ++ case HDMI_AUDIO_CODING_TYPE_EAC3: ++ case HDMI_AUDIO_CODING_TYPE_DTS_HD: ++ case HDMI_AUDIO_CODING_TYPE_MLP: ++ return map_rate_families(sad, ++ 0, ++ SAD1_RATE_176400_MASK, ++ SAD1_RATE_192000_MASK); ++ default: ++ /* TODO adjust for other compressed formats as well */ ++ return sad[1] & SAD1_RATE_MASK; ++ } ++} ++ + static unsigned int sad_max_channels(const u8 *sad) + { +- return 1 + (sad[0] & 7); ++ switch (FIELD_GET(SAD0_FORMAT_MASK, sad[0])) { ++ case HDMI_AUDIO_CODING_TYPE_PCM: ++ return 1 + FIELD_GET(SAD0_CHANNELS_MASK, sad[0]); ++ case HDMI_AUDIO_CODING_TYPE_AC3: ++ case HDMI_AUDIO_CODING_TYPE_DTS: ++ case HDMI_AUDIO_CODING_TYPE_EAC3: ++ return 2; ++ case HDMI_AUDIO_CODING_TYPE_DTS_HD: ++ case HDMI_AUDIO_CODING_TYPE_MLP: ++ return 8; ++ default: ++ /* TODO adjust for other compressed formats as well */ ++ return 1 + FIELD_GET(SAD0_CHANNELS_MASK, sad[0]); ++ } + } + + static int eld_limit_rates(struct snd_pcm_hw_params *params, +@@ -42,7 +109,7 @@ static int eld_limit_rates(struct snd_pcm_hw_params *params, + * requested number of channels. + */ + if (c->min <= max_channels) +- rate_mask |= sad[1]; ++ rate_mask |= sad_rate_mask(sad); + } + } + +@@ -70,7 +137,7 @@ static int eld_limit_channels(struct snd_pcm_hw_params *params, + rate_mask |= BIT(i); + + for (i = drm_eld_sad_count(eld); i > 0; i--, sad += 3) +- if (rate_mask & sad[1]) ++ if (rate_mask & sad_rate_mask(sad)) + t.max = max(t.max, sad_max_channels(sad)); + } + +-- +2.39.2 + diff --git a/packages/linux/patches/raspberrypi/linux-020-eld-constraints-for-compressed-formats.patch b/packages/linux/patches/raspberrypi/linux-020-eld-constraints-for-compressed-formats.patch deleted file mode 100644 index bb74ff7bd7..0000000000 --- a/packages/linux/patches/raspberrypi/linux-020-eld-constraints-for-compressed-formats.patch +++ /dev/null @@ -1,91 +0,0 @@ -From a2769637a9b98c6809d4d25a3a20447a3ff7b23a Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Fri, 19 Mar 2021 12:14:17 +0100 -Subject: [PATCH] ALSA: pcm: fix ELD constraints for some compressed audio - formats - -The SADs of compressed formats like AC3 and DTS contain the channel -and sample rate info of the audio data inside the compressed stream, -but when building constraints we must use the rates and formats used -to pass through the stream. eg 2ch 48kHz for AC3. - -Signed-off-by: Matthias Reichl ---- - sound/core/pcm_drm_eld.c | 38 +++++++++++++++++++++++++++++++++++--- - 1 file changed, 35 insertions(+), 3 deletions(-) - -diff --git a/sound/core/pcm_drm_eld.c b/sound/core/pcm_drm_eld.c -index 4b5faae5d16e5..e7ec7a8b9d420 100644 ---- a/sound/core/pcm_drm_eld.c -+++ b/sound/core/pcm_drm_eld.c -@@ -6,6 +6,7 @@ - #include - #include - #include -+#include - - static const unsigned int eld_rates[] = { - 32000, -@@ -17,9 +18,40 @@ static const unsigned int eld_rates[] = { - 192000, - }; - -+static unsigned int sad_format(const u8 *sad) -+{ -+ return (sad[0] & 0x78) >> 3; -+} -+ - static unsigned int sad_max_channels(const u8 *sad) - { -- return 1 + (sad[0] & 7); -+ switch (sad_format(sad)) { -+ case HDMI_AUDIO_CODING_TYPE_AC3: -+ case HDMI_AUDIO_CODING_TYPE_DTS: -+ case HDMI_AUDIO_CODING_TYPE_EAC3: -+ return 2; -+ case HDMI_AUDIO_CODING_TYPE_DTS_HD: -+ case HDMI_AUDIO_CODING_TYPE_MLP: -+ return 8; -+ default: -+ return 1 + (sad[0] & 7); -+ } -+} -+ -+static unsigned int sad_rate_mask(const u8 *sad) -+{ -+ switch (sad_format(sad)) { -+ case HDMI_AUDIO_CODING_TYPE_AC3: -+ case HDMI_AUDIO_CODING_TYPE_DTS: -+ return 0x07; // 32-48kHz -+ case HDMI_AUDIO_CODING_TYPE_EAC3: -+ return 0x7f; // 32-192kHz -+ case HDMI_AUDIO_CODING_TYPE_DTS_HD: -+ case HDMI_AUDIO_CODING_TYPE_MLP: -+ return 0x60; // 176.4, 192kHz -+ default: -+ return sad[1] & 0x7f; -+ } - } - - static int eld_limit_rates(struct snd_pcm_hw_params *params, -@@ -42,7 +74,7 @@ static int eld_limit_rates(struct snd_pcm_hw_params *params, - * requested number of channels. - */ - if (c->min <= max_channels) -- rate_mask |= sad[1]; -+ rate_mask |= sad_rate_mask(sad); - } - } - -@@ -70,7 +102,7 @@ static int eld_limit_channels(struct snd_pcm_hw_params *params, - rate_mask |= BIT(i); - - for (i = drm_eld_sad_count(eld); i > 0; i--, sad += 3) -- if (rate_mask & sad[1]) -+ if (rate_mask & sad_rate_mask(sad)) - t.max = max(t.max, sad_max_channels(sad)); - } - --- -2.20.1 - diff --git a/packages/linux/patches/raspberrypi/linux-021-ASoC-hdmi-codec-don-t-set-channel-and-speaker-info-f.patch b/packages/linux/patches/raspberrypi/linux-021-ASoC-hdmi-codec-don-t-set-channel-and-speaker-info-f.patch new file mode 100644 index 0000000000..d63c347e5a --- /dev/null +++ b/packages/linux/patches/raspberrypi/linux-021-ASoC-hdmi-codec-don-t-set-channel-and-speaker-info-f.patch @@ -0,0 +1,89 @@ +From 99586e3f502fcc4fdd21b621f3c87ae7a8f7c170 Mon Sep 17 00:00:00 2001 +From: Matthias Reichl +Date: Sat, 3 Jun 2023 12:12:28 +0200 +Subject: [PATCH 2/2] ASoC: hdmi-codec: don't set channel and speaker info for + compressed formats + +CTA 861 only mandates that the speaker allocation in the audio info frame +is set for multichannel PCM formats. Likewise the number of channels in the +audio infoframe is only relevant for PCM. + +Some TVs won't decode compressed formats if the number of channels isn't +set to 0 (refer to stream header) and the speaker allocation is set to the +default 0 (FL and FR). + +So fill in this info only for PCM audio and set it to 0 for compressed +audio formats. + +This also prevents hdmi_codec_prepare failing with an error when trying to +play back DTS-HD or MLP (which is passed through as 8ch) if the sink only +supports 2ch PCM and announces only FL/FR speaker support in the EDID. + +Signed-off-by: Matthias Reichl +--- + sound/soc/codecs/hdmi-codec.c | 36 +++++++++++++++++++++++------------ + 1 file changed, 24 insertions(+), 12 deletions(-) + +diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c +index 0b1cdb2d60498..a192d985c5f18 100644 +--- a/sound/soc/codecs/hdmi-codec.c ++++ b/sound/soc/codecs/hdmi-codec.c +@@ -484,31 +484,43 @@ static int hdmi_codec_fill_codec_params(struct snd_soc_dai *dai, + 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; ++ int idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; ++ u8 ca_id = 0; ++ bool pcm_audio = !(hcp->iec_status[0] & IEC958_AES0_NONAUDIO); ++ ++ if (pcm_audio) { ++ /* 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; ++ } ++ ++ ca_id = hdmi_codec_channel_alloc[idx].ca_id; + } + + memset(hp, 0, sizeof(*hp)); + + hdmi_audio_infoframe_init(&hp->cea); +- hp->cea.channels = channels; ++ ++ if (pcm_audio) ++ hp->cea.channels = channels; ++ else ++ hp->cea.channels = 0; ++ + 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->cea.channel_allocation = 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; ++ hcp->chmap_idx = idx; + + return 0; + } +-- +2.39.2 +