ASoC: hdmi-codec: Fall back to a valid channel allocation - #7604
ASoC: hdmi-codec: Fall back to a valid channel allocation#7604popcornmix wants to merge 2 commits into
Conversation
|
Tested successfully in #7603 |
|
@6by9 ? Note this follows the logic in hda driver. |
|
I'd had a quick look at the HDA driver and could see the It looks like you're just setting up If returning
(The |
af03e50 to
b3bcac7
Compare
|
|
||
| /* hdmi_codec_eld_chmap() leaves only CA 0x00 indexable for these */ | ||
| if (!(spk_mask & ~(FL | FR))) | ||
| return 0; |
There was a problem hiding this comment.
Don't we end up returning 0 as the default value for fallback if we go through the loop when spk_mask doesn't include FL or FR?
|
Updated to match the shape I think you wanted, but I don't believe there is any change in behaviour. I also believe we are functionally equivalent to HDA driver. |
hdmi_codec_get_ch_alloc_table_idx() searches for a CEA channel allocation whose speaker mask is a subset of the one advertised in the sink's ELD. Every allocation in the table contains the front pair, and the only escape hatch requires the ELD speaker allocation byte to be entirely zero (the unplugged case), so a sink that advertises speakers without setting bit 0 (FL/FR) matches nothing and the function returns -EINVAL. A Philips 77OLED809 does exactly that. Its Speaker Allocation Data Block is 0x7e, declaring LFE1, FC, BL/BR, BC, FLc/FRc and RLC/RRC but no front pair. CTA-861 defines bit 0 as FL/FR and attaches no further requirement to it, so edid-decode -c passes this EDID, but with the bit clear there is no allocation left to select. The set's only LPCM format is 2 channel, so every playback attempt fails: hdmi-audio-codec hdmi-audio-codec.1.auto: Not able to map channels to speakers (-22) hdmi-audio-codec hdmi-audio-codec.1.auto: ASoC: error at snd_soc_pcm_dai_prepare on i2s-hifi: -22 This repeats for as long as userspace retries the open, and leaves no usable HDMI audio output. CA 0x00 describes plain stereo and is valid whatever the sink advertises, so return it for two channels or fewer without consulting the ELD. Compressed formats are unaffected, as they do not reach this function. See: raspberrypi#7603 Signed-off-by: Dom Cobley <popcornmix@gmail.com>
b3bcac7 to
390564d
Compare
|
Latest version just keeps the "accept 2 channels" part of patch, which is what resolved #7603 and is directly comparable with HDA. Let's go with that for now. We can reconsider the other part of patch when find a user with an edid that works with HDA and not with us. As an aside, vc4 declares HDA also can't do odd numbered counts due to speaker allocation, but at least declares that up front. I believe odd channel counts should be usable (FL/FR/C or FL/FR/LFE seem like reasonable sound bar configs) - and I'm pretty sure I had that working with the firmware side driver. |
6by9
left a comment
There was a problem hiding this comment.
I was happy with the fallback, but just saw optimisations.
No quibble at all with this though - 2 channels is going to be CA 0x00.
I haven't looked in detail at the HDMI specs, but as the audio data gets IEC60958 encapsulated and that is inherently carrying a multiple of 2 channels, I suspect that is why they have rounded the channel count up to an even value. This may be more applicable on vc4 as we're relying on ALSA to do the IEC60958 encapsulation, so that bit of parsing may not be in the most obvious location. I have no issues with adding a |
|
The two subframes per frame just means the channels are packed like: so, there is no padding needed for odd numbers of channels. |
The CPU DAI advertises 1 to 8 channels and nothing narrows that further, so userspace can open a 3, 5 or 7 channel stream and have hw_params succeed. hdmi_codec_channel_alloc[] only holds allocations for 2, 4, 6 and 8 channels, so hdmi_codec_get_ch_alloc_table_idx() then fails the stream at prepare: hdmi-audio-codec hdmi-audio-codec.1.auto: Not able to map channels to speakers (-22) Constrain the channel count to a multiple of two at startup so the odd counts are never offered, rather than being accepted and rejected later. This matches the HDA HDMI codec, which applies the same constraint. Signed-off-by: Dom Cobley <popcornmix@gmail.com>
|
Added commit to set Before: speaker-test thinks 3 channels is supported, but fails in set hw params. After the commit: (analyser shows 4 channels, with one silent). |
hdmi_codec_get_ch_alloc_table_idx() only succeeds when it finds a CEA channel allocation whose speaker mask is a subset of the one advertised in the sink's ELD. Every allocation in the table contains the front pair, and the only escape hatch requires the ELD speaker allocation byte to be entirely zero (the unplugged case), so a sink that advertises speakers without setting bit 0 (FL/FR) matches nothing at all and the function returns -EINVAL.
A Philips 77OLED809 does exactly that. Its Speaker Allocation Data Block is 0x7e, declaring LFE1, FC, BL/BR, BC, FLc/FRc and RLC/RRC but no front pair. CTA-861 defines bit 0 as FL/FR and attaches no further requirement to it, so edid-decode -c passes this EDID, but with the bit clear there is no allocation left to select. Playback then fails for every channel count, including the 2 channel LPCM that is the only uncompressed format the set accepts:
hdmi-audio-codec hdmi-audio-codec.1.auto: Not able to map channels to speakers (-22)
hdmi-audio-codec hdmi-audio-codec.1.auto: ASoC: error at snd_soc_pcm_dai_prepare on i2s-hifi: -22
This repeats for as long as userspace retries the open, and leaves no usable HDMI audio output.
Handle it the way hdmi_channel_allocation_spk_alloc_blk() in the HDA driver always has: return CA 0x00 for two channels or fewer without consulting the ELD at all, and where the speaker mask matches nothing, substitute the first allocation with the requested channel count rather than failing.
The fallback is restricted to sinks advertising more than the front pair. hdmi_codec_chmap_ctl_get() indexes the installed channel map array by ca_id, and hdmi_codec_eld_chmap() only installs the ca_id-indexed 8 channel maps under that same condition. hdmi_codec_stereo_chmaps has no entry beyond CA 0x00, so returning a higher ca_id with that array installed would read out of bounds.
Well-formed ELDs are unaffected: every speaker allocation that previously selected an allocation still selects the same one.
See: #7603