On 10/23/23 00:35, Kuninori Morimoto wrote: > Current ASoC CPU:Codec = N:M connection is using connection mapping idea, > but it is used for N < M case only. We want to use it for any case. > > By this patch, not only N:M connection, but all existing connection > (1:1, 1:N, N:N) will use same connection mapping. Then, because it will > use default mapping, no conversion patch is needed to exising drivers. > > More over, CPU:Codec = N:M (N > M) also supported in the same time. > > ch_maps array will has CPU/Codec index by this patch. > > Image > CPU0 <---> Codec0 > CPU1 <-+-> Codec1 > CPU2 <-/ > > ch_map > ch_map[0].cpu = 0 ch_map[0].codec = 0 > ch_map[1].cpu = 1 ch_map[1].codec = 1 > ch_map[2].cpu = 2 ch_map[2].codec = 1 > > Link: https://lore.kernel.org/r/87fs6wuszr.wl-kuninori.morimoto.gx@xxxxxxxxxxx > Link: https://lore.kernel.org/r/878r7yqeo4.wl-kuninori.morimoto.gx@xxxxxxxxxxx > Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@xxxxxxxxxxx> The Intel CI did not detect any issues with this patch, see https://github.com/thesofproject/linux/pull/4632, so Tested-by: Pierre-Louis Bossart <pierre-louis.bossart@xxxxxxxxxxxxxxx> Note however the -W1 error below > +static int snd_soc_compensate_channel_connection_map(struct snd_soc_card *card, > + struct snd_soc_dai_link *dai_link) > +{ > + struct snd_soc_dai_link_ch_map *ch_maps; > + int i, max; sound/soc/soc-core.c: In function ‘snd_soc_compensate_channel_connection_map’: sound/soc/soc-core.c:1050:16: error: variable ‘max’ set but not used [-Werror=unused-but-set-variable] 1050 | int i, max; | ^~~ > + /* > + * dai_link->ch_maps indicates how CPU/Codec are connected. > + * It will be a map seen from a larger number of DAI. > + * see > + * soc.h :: [dai_link->ch_maps Image sample] > + */ > + > + /* it should have ch_maps if connection was N:M */ > + if (dai_link->num_cpus > 1 && dai_link->num_codecs > 1 && > + dai_link->num_cpus != dai_link->num_codecs && !dai_link->ch_maps) { > + dev_err(card->dev, "need to have ch_maps when N:M connction (%s)", > + dai_link->name); > + return -EINVAL; > + } > + > + /* do nothing if it has own maps */ > + if (dai_link->ch_maps) > + goto sanity_check; > + > + /* check default map size */ > + if (dai_link->num_cpus > MAX_DEFAULT_CH_MAP_SIZE || > + dai_link->num_codecs > MAX_DEFAULT_CH_MAP_SIZE) { > + dev_err(card->dev, "soc-core.c needs update default_connection_maps"); > + return -EINVAL; > + } > + > + /* Compensate missing map for ... */ > + if (dai_link->num_cpus == dai_link->num_codecs) > + dai_link->ch_maps = default_ch_map_sync; /* for 1:1 or N:N */ > + else if (dai_link->num_cpus < dai_link->num_codecs) > + dai_link->ch_maps = default_ch_map_1cpu; /* for 1:N */ > + else > + dai_link->ch_maps = default_ch_map_1codec; /* for N:1 */ > + > +sanity_check: > + max = min(dai_link->num_cpus, dai_link->num_codecs); sound/soc/soc-core.c: In function ‘snd_soc_compensate_channel_connection_map’: sound/soc/soc-core.c:1050:16: error: variable ‘max’ set but not used [-Werror=unused-but-set-variable] 1050 | int i, max; | ^~~ > + > + dev_dbg(card->dev, "dai_link %s\n", dai_link->stream_name); > + for_each_link_ch_maps(dai_link, i, ch_maps) { > + if ((ch_maps->cpu >= dai_link->num_cpus) || > + (ch_maps->codec >= dai_link->num_codecs)) { > + dev_err(card->dev, > + "unexpected dai_link->ch_maps[%d] index (cpu(%d/%d) codec(%d/%d))", > + i, > + ch_maps->cpu, dai_link->num_cpus, > + ch_maps->codec, dai_link->num_codecs); > + return -EINVAL; > + } > + > + dev_dbg(card->dev, " [%d] cpu%d <-> codec%d\n", > + i, ch_maps->cpu, ch_maps->codec); > + } > + > + return 0; > +}