[alsa-devel] Question about struct snd_soc_dai() :: cpu_dai->codec

Kuninori Morimoto kuninori.morimoto.gx at renesas.com
Fri Aug 5 09:29:58 CEST 2016


Hi Lars

Thank you for your idea

> To be honest I'd also get rid of DAIs has a top level concept. This image
> (http://metafoo.de/the_new_asoc.svg) is something I've put together awhile
> ago how I think we should lay things out if we do a major refactoring of the
> ASoC core.

I think most important ideas on this image is ALSA SoC new style has
 - "component" can have many "domain"
 - "domain" can connect to other "domain" by using "bridge"
 - "bridge" can connect to many "domain"s
 - "domain" has certain properties, and "bridge" translate it to other "domain"

Here, my opinions are...
 - Actually, I want to have more and more simple style.
   If "domain" can have its format / frequency etc, "domain" list/array
   without "bridge" is very enough ?
   or no distinction in "domain" and "bridge" ?
   because we can have many "domain" on new style ?
   something like
	struct snd_soc_node;
	struct snd_soc_domain {
		struct snd_soc_node;
	};
	struct snd_soc_bridge {
		struct snd_soc_node;
	};
   This case ALSA SoC cares snd_soc_node only;
 - If we have "bridge", I think "component property" can be
   "component needs to setup connected bridge's parameter in init time", and
   "component should follow bridge's parameter when playback time" is nicer ?
   It is easy to care about "crossbar" case ?

On your image,
DMA / Audio controller / CODEC are component inheritance struct,
Playback / Capture / Digital / Link / Analog are domain inheritance struct,
PCM / DAI / DAC / ADC / crossbar are bridge inheritance struct.
ALSA SoC framework cares "component", "domain", "bridge" only.
Each driver can create original structure if it was based on
"component" or "domain" or "bridge", or it can use soc-core's
basic helper (= CPU / Codec / Plaform etc).
Then, it is easy to add new device / connection in the future ?
And it is easy to use OF graph style on DT ?

struct snd_soc_component {

       /* we want to have rtd list here for hotplug purpose ? */

	struct list_head component_domain_head; 
};

struct snd_soc_domain {

	struct snd_soc_component *component; /* parent */

	struct list_head component_domain;
};

struct snd_soc_bridge {

	/* connected domain will sets available parameter */
	unsigned int fmt, ...;

	struct list_head runtime_bridge;
	struct snd_soc_domain *domains[0] /* domain array */
};

struct snd_soc_pcm_runtime {

	struct list_head runtime_bridge_head;
};

static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_bridge *bridge;
	struct snd_soc_domain *domain;

	for_each_bridge(bridge, rtd) {
		for_each_domain(domain, bridge) {
			domain->trigger(domain, bridge, rtd);
		}
	}
	...
}

> The dark grey boxes are bridges between domains and they translate
> properties from one domain to another. This can either be straight forward
> propagation like a PCM device where the samplerate in the source and target
> domain are the same, or it can modify the properties, e.g. a samplerate
> converter between two digital domains will change the samplerate according
> to the interpolation/decimation factor of the SRC.
> 
> In addition to just translating the properties a bridge can also translate
> the constraints on properties from one domain to another or even add its own
> constraints. E.g. if a CODEC has a constraint that it can run either with
> 48kHz or 96kHz this constraint is propagated through the bridges to the PCM
> devices so that the userspace application using the PCM is aware of this.
> Bridges can also add their own constraints e.g. a SRC might have multiple
> interpolation/decimation rates available, so it might say the samplerate in
> the target domain must be 1x or 2x that of the source domain. Going back to
> the example that means for a CODEC that supports either 48kHz or 96kHz and
> there is a SRC with interpolation factors of 1 or 2 then the PCM device will
> present the list of either 24kHz, 48kHz or 96kHz to the userspace application.

I think this is current DPCM's dai_link->be_hw_params_fixup portion ?
I think "bridge" can/should handle it ?


> A bridge is also not limited to one source and one sink. It can have
> multiple sources and multiple sinks e.g. for a crossbar with a complex
> routing matrix.

Do you mean runtime-path-change by this "crossbar" ?

--A1-+-B1--
     |
--A2-+-B2--

For example, like this ??

	> amixer set "A1-B1" ... // connect
	> aplay xxx
	> amixer set "A1 B1" ... // disconnect
	> amixer set "A1-B2" ... // connect
	> aplay xxx

Or having fixed path card ?

	> aplay -D plughw:0,0 xxx  // A1-B1 path
	> aplay -D plughw:0,1 xxx  // A1-B2 path
	> aplay -D plughw:0,2 xxx  // B1-A1 path
	> aplay -D plughw:0,3 xxx  // B1-B2 path
	...

> Obviously we can't convert everything at the same time and it will take a
> lot of time and effort to update all drivers to this new model. This is
> where the legacy bridge kicks in which still keeps the concept of 1 CPU, 1
> CODEC, 1 platform. If you want to use the advanced features of the new
> framework you have to update your driver, if you are OK with the current set
> of features just keep the drivers the way they are and use the legacy bridge
> that is automatically managed by the ASoC core.

I think it will be super x 10 long term project
Because of it, we need to consider about
 - "Big picture" and "details" of final style
 - consider how to goto there from current style

Best regards
---
Kuninori Morimoto


More information about the Alsa-devel mailing list