Re: [PATCH 1/2] ASoC: add N cpus to M codecs dai link support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Bard

> Currently, ASoC supports dailinks with the following mappings:
> 1 cpu DAI to N codec DAIs
> N cpu DAIs to N codec DAIs
> But the mapping between N cpu DAIs and M codec DAIs is not supported.
> The reason is that we didn't have a mechanism to map cpu and codec DAIs
> 
> This patch suggests a new snd_soc_dai_link_codec_ch_map struct in
> struct snd_soc_dai_link{} which provides codec DAI to cpu DAI mapping
> information used to implement N cpu DAIs to M codec DAIs
> support.
> 
> When a dailink contains two or more cpu DAIs, we should set channel
> number of cpus based on its channel mask. The new struct also provides
> channel mask information for each codec and we can construct the cpu
> channel mask by combining all codec channel masks which map to the cpu.
> 
> The N:M mapping is however restricted to the N <= M case due to physical
> restrictions on a time-multiplexed bus such as I2S/TDM, AC97, SoundWire
> and HDaudio.

I like CPU:Codec = N:M support !
OTOH, I have interesting to ASoC code cleanup too.
So this is meddlesome from me.

> +struct snd_soc_dai_link_codec_ch_map {
> +	unsigned int connected_cpu_id;
> +	unsigned int ch_mask;
> +};

If my understanding was correct, this map is used only for N:M mapping,
but we want to use it for all cases.
In such case, the code can be more flexible and more clean.
see below.

> @@ -1041,13 +1045,32 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd,
>  		if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream))
>  			continue;
>  
> -		ret = snd_soc_dai_hw_params(cpu_dai, substream, params);
> +		/* copy params for each cpu */
> +		cpu_params = *params;
> +
> +		if (!rtd->dai_link->codec_ch_maps)
> +			goto hw_params;
> +		/*
> +		 * construct cpu channel mask by combining ch_mask of each
> +		 * codec which maps to the cpu.
> +		 */
> +		for_each_rtd_codec_dais(rtd, j, codec_dai) {
> +			if (rtd->dai_link->codec_ch_maps[j].connected_cpu_id == i)
> +				ch_mask |= rtd->dai_link->codec_ch_maps[j].ch_mask;
> +		}

Can we re-use snd_soc_dai_tdm_mask_get() for this purpose instead of .ch_mask ?
May be we want to rename it and/or want to have new xxx_mask on dai->stream[].
I'm asking because it is natural to reuse existing data and/or have variable on
similar place instead of on new structure.


Maybe I'm not 100% well understanding about CPU:Codec = N:M connection,
but if we can assume like below, we can use it on all cases not only for N:M case.

We can have connection map on dai_link which is for from M side (here N <= M).
The image is like this.

	CPU0 <---> Codec2
	CPU1 <-+-> Codec0
	       \-> Codec1

	.num_cpus   = 2;
	.num_codecs = 3;
	.map = [1, 1, 0]; // From Codec point of view.
	                  // sizeof(map) = num_codecs, because 3 > 2;

In this rule, we can also handle CPU > Codec case, too.

	CPU0 <---> Codec1
	CPU1 <-+-> Codec0
	CPU2 <-/

	.num_cpus   = 3;
	.num_codecs = 2;
	.map = [1, 0, 0]; // From CPU point of view.

We can use this idea for existing connection, too.

	1:1 case
	CPU0 <-> Codec0

	N:N case
	CPU0 <---> Codec0
	CPU1 <---> Codec1

	1:N case
	CPU0 <-+-> Codec0
	       \-> Codec1

	default_map1 = [0, 1, 2, 3,...];
	default_map2 = [0, 0, 0, 0,...];

	if (!dai_link->map) {
		if (dai_link->num_cpus == dai_link->num_codecs)
			dai_link->map = default_map1; /* for 1:1, N:N */
		else
			dai_link->map = default_map2; /* for 1:N */
	}

We can handle more flexible N:N connection as Richard said

	fixup N:N case
	CPU0 <---> Codec2
	CPU1 <---> Codec1
	CPU2 <---> Codec0

	.num_cpus   = 3;
	.num_codecs = 3;
	.map = [2, 1, 0]; // From CPU point of view.

with is new .map, we can handle existing 1:1, N:N, 1:N, and new N:M (and M:N)
connection with same code.
This is just meddlesome from me, but I hope you can think about this.


Thank you for your help !!

Best regards
---
Kuninori Morimoto



[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Pulse Audio]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux