Most cards supported by patch_hdmi.c have the property of a 1:1 mapping or connection between converter widgets and pin widgets. Hence, patch_hdmi.c sets up a PCM for each converter, and occasionally performs some operations on the pin widget as required.
However, some new cards don't have this 1:1 mapping. In particular, the new GeForce GT 520 and many future NVIDIA cards, and at least the Intel Ibex Peak (in my wife's laptop), have more pin widgets than converters, and each pin widget has a mux to select which converter to take the audio from.
For pretty pictures, see the 4th (and 3rd) diagrams at:
ftp://download.nvidia.com/XFree86/gpu-hdmi-audio-document/gpu-hdmi-audio.html#_examples
I'd like to discuss how best to handle such cards.
I'd expect to see a PCM device created for each pin widget. This would create a 1:1 mapping between PCM devices and attached monitors and hence ELD data (with the possible exception of DisplayPort 1.2 daisy-chaining; I have no idea yet how that plays into this).
Does this seem like a reasonable approach to everyone?
The current situation is that we only create a PCM for each converter that is mux'd to a pin by default HW initialization. On both the GeForce 520 and Ibex Peak, this means that only 1 PCM gets created, since all pin widgets' muxes point at the first converter by default. This:
a) Doesn't allow usage of both converters at once, since there's only 1 PCM object.
b) Ends up with up to 4 (in NVIDIA's case) pin widgets (and hence ELD information) logically associated with the PCM object. Hence, it'll be confusing for application to know what features they can really use on the PCM. In fact, ALSA actually only enforces the ELD of the first pin associated with the converter, and ignores the rest.
The basic mechanics of a-PCM-per-pin would require hdmi_pcm_open to look at the list of converters, find one not in use by a stream, and then dynamically associate the converter with the stream, or fail the open if a converter was not available. We'd also need a custom close or cleanup function to "unassign" the converter from the PCM, and set hda_pcm_stream.nid to an invalid value.
That might be easiest to implement if hda_pcm_stream.nid were to refer to the pin widget rather than the converter widget. However, I notice that some core code in hda_codec.c would be confused by this, so perhaps we'd better just have have hdmi_pcm_open use some other way to determine which stream object is associated with the pin. I suppose that it'd be pretty easy to set up a mapping from hda_pcm_stream to pin nid as part of generic_hdmi_build_pcms.
As an aside, this rather reminds me of the mux'ing that goes on inside codecs controlled by ASoC, although I don't think we need to expose this muxing to user-space in the case, but instead make it automatic as I outlined above.
Thanks for any thoughts.