[alsa-devel] [PATCH v5 1/3] ASoC: Add initial support for multiple CPU DAIs
Pierre-Louis Bossart
pierre-louis.bossart at linux.intel.com
Thu May 24 22:45:40 CEST 2018
On 05/24/2018 12:34 AM, Shreyas NC wrote:
>>> @@ -1120,6 +1123,9 @@ struct snd_soc_pcm_runtime {
>>> struct snd_soc_dai **codec_dais;
>>> unsigned int num_codecs;
>>> + struct snd_soc_dai **cpu_dais;
>>> + unsigned int num_cpu_dai;
>>> +
>> This structure is becoming difficult to interpret:
>>
>> struct snd_soc_dai *codec_dai;
>> struct snd_soc_dai *cpu_dai;
>>
>> struct snd_soc_dai **codec_dais;
>> unsigned int num_codecs;
>>
>> struct snd_soc_dai **cpu_dais;
>> unsigned int num_cpu_dai;
>>
>> What is the intended usage of codec_dai vs. codec_dais and cpu_dai vs.
>> cpu_dais?
> rtd->cpu_dai is used in many drivers to get cpu_dai from soc_pcm_runtime.
> Similarly cpu_dais is addded to get multiple cpu_dais from runtime.
>
> TBH, I have shadowed the codec_dais implementation for sake of
> convenience and being conformal :)
>
>> If this is only to handle the single codec_dai/single cpu_dai as an
>> exception, should we port the code to support multiple cpu_dais/multiple
>> codec_dais?
>>
> As mentioned in [1] (in cover letter), there are discussions to unify cpu and
> codec dais and this is the first step towards that. So, yes, eventually we
> should port the code as you have suggested :)
ok, maybe add a comment in the commit message then?
>
>>> /* close any waiting streams */
>>> @@ -552,16 +565,21 @@ int snd_soc_suspend(struct device *dev)
>>> }
>>> list_for_each_entry(rtd, &card->rtd_list, list) {
>>> - struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
>>> + struct snd_soc_dai *cpu_dai;
>>> - if (rtd->dai_link->ignore_suspend)
>>> - continue;
>>> + for (i = 0; i < rtd->num_cpu_dai; i++) {
>>> + cpu_dai = rtd->cpu_dais[i];
>>> +
>>> + if (rtd->dai_link->ignore_suspend)
>>> + continue;
>> this test needs to be outside of the for loop? the 'continue' should result
>> in moving to the next element of the list, not to the next cpu_dai.
>> see below, this statement is indeed outside for the resume part.
> Yes, will fix this. Thanks :)
ok
>
> - /*
> - * At least one of CPU DAI name or CPU device name/node must be
> - * specified
> - */
> - if (!link->cpu_dai_name &&
> - !(link->cpu_name || link->cpu_of_node)) {
> - dev_err(card->dev,
> - "ASoC: Neither cpu_dai_name nor cpu_name/of_node are set for %s\n",
> - link->name);
> - return -EINVAL;
> - }
> + for (i = 0; i < link->num_cpu_dai; i++) {
> + if (link->cpu_dai[i].name &&
> + link->cpu_dai[i].of_node) {
> + dev_err(card->dev,
> + "ASoC: Neither/both cpu name/of_node are set for %s\n",
> + link->cpu_dai[i].name);
> + return -EINVAL;
> + }
> +
> + /*
> + * At least one of CPU DAI name or CPU device name/node must be
> + * specified
> + */
> + if (!link->cpu_dai[i].dai_name &&
> + !(link->cpu_dai[i].name || link->cpu_dai[i].of_node)) {
>> This doesn't seem to be the logical translation of the initial condition
>> based on link->cpu_name and link->cpu_of_node?
>>
> pasting the code added from the function above to show the mapping b/w name,
> of_node and dai_name:
>
> dai_link->cpu_dai[0].name = dai_link->cpu_name;
> dai_link->cpu_dai[0].of_node = dai_link->cpu_of_node;
> dai_link->cpu_dai[0].dai_name = dai_link->cpu_dai_name;
>
> and the original condition was:
> if (!link->cpu_dai_name &&
> !(link->cpu_name || link->cpu_of_node)) {
>
> So, it does look correct to me, unless I am missing something obvious :(
The original code I was referring to is this:
/*
* CPU device may be specified by either name or OF node, but
* can be left unspecified, and will be matched based on DAI
* name alone..
*/
if (link->cpu_name && link->cpu_of_node) {
dev_err(card->dev,
"ASoC: Neither/both cpu name/of_node are set for %s\n",
link->name);
return -EINVAL;
}
/*
* At least one of CPU DAI name or CPU device name/node must be
* specified
*/
if (!link->cpu_dai_name &&
!(link->cpu_name || link->cpu_of_node)) {
dev_err(card->dev,
"ASoC: Neither cpu_dai_name nor cpu_name/of_node are set
for %s\n",
link->name);
return -EINVAL;
}
return 0;
The new code is this:
for (i = 0; i < link->num_cpu_dai; i++) {
if (link->cpu_dai[i].name &&
link->cpu_dai[i].of_node) {
dev_err(card->dev,
"ASoC: Neither/both cpu name/of_node are set for %s\n",
link->cpu_dai[i].name);
return -EINVAL;
}
/*
* At least one of CPU DAI name or CPU device name/node must be
* specified
*/
if (!link->cpu_dai[i].dai_name &&
!(link->cpu_dai[i].name || link->cpu_dai[i].of_node)) {
dev_err(card->dev,
"ASoC: Neither cpu_dai_name nor cpu_name/of_node are
set for %s\n",
link->name);
return -EINVAL;
}
}
Yes, it's equivalent for i==0, but it's not clear to me for non-zero
indices. I don't get how/where
link->cpu_dai[i].name and link->cpu_dai[i].of_node are initialized for i>0.
>>> - if (cpu_dai->driver->compress_new) {
>>> + if (rtd->cpu_dais[0]->driver->compress_new) {
>>> + if (rtd->num_cpu_dai > 1)
>>> + dev_warn(card->dev,
>>> + "ASoC: multi-cpu compress dais not supported");
>> Not sure this is right, you could have a case where the compress dai is not
>> on the cpu_dai[0]?
> I am not able to comprehend that we can have multi CPU DAIS in a DAI Link
> with one of the DAI being compress and the other being a PCM DAI.
>
> Any such systems that you can think of ?
Yes I agree, my point was that you test only for the first cpu_dai
(index 0), but if rtd->cpu_dais[1]->drivers->compress_new is non NULL
then it's also wrong. You should test for all cpu_dais to make sure they
are all PCM.
More information about the Alsa-devel
mailing list