[alsa-devel] Dynamic PCM and Tegra AHUB
Stephen Warren
swarren at wwwdotorg.org
Sat May 26 02:23:48 CEST 2012
Mark, Liam,
Tegra30's AHUB is structured as follows:
> +-------------+ +-----+ +--------------+ +-----+ +------+
> | FIFO pair 0 |<->| CIF |<->| Cross-bar |<->| CIF |<->| I2S0 |<-> External IO
> +-------------+ +-----+ | (the "AHUB") | +-----+ +------+
> . . . | | . . .
> +-------------+ +-----+ | | +-----+ +------+
> | FIFO pair 3 |<->| CIF |<->| |<->| CIF |<->| I2S4 |<-> External IO
> +-------------+ +-----+ | | +-----+ +------+
> | |
> | | +-----+ +-------+
> | |<->| CIF |<->| SPDIF |<-> External IO
> | | +-----+ +-------+
> | |
> | | +-----+ +-------+
> | |<->| CIF |<->| DAM |
> | | +-----+ +-------+
> +--------------+
Notes on the diagram:
Each FIFO above is a separate TX and RX FIFO. I merged them in the
drawing for simplicity, but they operate completely independently;
different memory packing formats, data flow rates, ...
The CIF can convert the audio format, e.g. mono<->stereo conversion and
change the # of bits in the data in pretty arbitrary combinations. This
is true for all CIFs; those that join the AHUB core to either the DMA
FIFOs or the I2S/SPDIF/DAM controllers.
The AHUB core is a complete cross-bar; each output selects 1 of the n
inputs.
The I2S and SPDIF controllers take audio from the AHUB, format it to the
appropriate protocol, and send to external IO (or the other way around).
The I2S and SPDIF modules don't perform any additional data
rate/width/channel conversion; the CIF must do whatever conversions are
needed.
The DAMs take 2 input channels from the AHUB, optionally perform some
sample rate conversion and/or bit size conversion beyond what the CIF
does, mix them together, and send them back into the AHUB cross-bar.
Questions:
It seems like the whole point of ASoC dynamic PCM is to represent the
AHUB core, and at least some of the surrounding boxes above, as an ASoC
CODEC.
Initially, I would assume the AHUB CODEC's DAIs would be the DMA FIFOs
and the I2S* controllers themselves, i.e. include everything in the
above diagram.
If I do that, then the dai_links that the ASoC machine driver registers
for I2S->WM8903 would represent a codec DAI <-> codec DAI link rather
than a regular CPU DAI <-> codec DAI link. The difference here is the
lack of symmetry in struct snd_soc_dai_link: The CPU-side of each DAI
link only has a "cpu_dai_name" to identify it, whereas the codec side
has both a codec_name (or of node) /plus/ a DAI name. This is important
at least in the context of device tree, where to avoid hard-coding
specific device names into the dai_link structure's .codec_name field in
the machine driver, an of_node is looked up at run-time instead, and
then the codec_dai_name interpreted relative to that. Without a CPU-side
separation between name/node and dai_name, that's not possible. So, I
sent a patch for that in case this is the right approach.
An alternative to expanding struct snd_soc_dai_link might be to add an
API so the machine driver could ask the AHUB driver for the
globally-unique name of each DAI it exposes, and write that into
dai_link.cpu_dai_name. But if we have that API, we could use it for the
codec-side of the link to, and just have .codec_dai_name and remove the
.codec_name and .codec_of_node fields.
Alternatively, perhaps the DMA FIFOs should be registered as CPU DAIs
completely separately from the AHUB CODEC. The AHUB CIFs would then be
the DAIs registered by the AHUB CODEC. But then, the machine driver
would need to include dai_links for all the DMA FIFO <-> CIF
connections, which would end up duplicating that list of links into all
Tegra machine drives (or perhaps sharing it in common code).
Very curious for your thoughts...
More information about the Alsa-devel
mailing list