[PATCH 1/4] ASoC: soc-pcm: dpcm: fix playback/capture checks

Pierre-Louis Bossart pierre-louis.bossart at linux.intel.com
Wed Jun 17 16:33:40 CEST 2020



On 6/17/20 4:01 AM, Stephan Gerhold wrote:
> On Tue, Jun 16, 2020 at 12:05:49PM -0500, Pierre-Louis Bossart wrote:
>>
>>
>>
>>>>> simple-card.c and audio-graph-card do hard-code but that's done
>>>>> with C in
>>>>> the driver:
>>>>>
>>>>>      ret = asoc_simple_parse_daifmt(dev, cpu_ep, codec_ep,
>>>>>                         NULL, &dai_link->dai_fmt);
>>>>>      if (ret < 0)
>>>>>          goto out_put_node;
>>>>>
>>>>>      dai_link->dpcm_playback        = 1;
>>>>>      dai_link->dpcm_capture        = 1;
>>>>>
>>>>>
>>>>> that that should be fixed based on the DAI format used in that
>>>>> dai_link - in
>>>>> other words we can make sure the capabilities of the dailink are aligned
>>>>> with the dais while parsing the DT blobs.
>>>>
>>>> But how do you know which capabilities to set? The device tree doesn't
>>>> tells us that. We could add some code to look up the snd_soc_dai_driver
>>>> early, based on the references in the device tree (basically something
>>>> like snd_soc_of_get_dai_name(), see
>>>>      https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/sound/soc/soc-core.c#n2988)
>>>>
>>>>
>>>> At least to me that function doesn't exactly look trivial though,
>>>> and that's just to properly fill in the dpcm_playback/capture
>>>> parameters. Essentially those parameters only complicate the current
>>>> device tree use case,  where you want the DAI link to be for both
>>>> playback/capture, but restricted to the capabilities of the DAI.
>>>>
>>>> Just wondering if setting up dpcm_playback/capture properly is worth it
>>>> at all in this case. This isn't necessary for the non-DPCM case either,
>>>> there we automatically set it based on the DAI capabilities.
>>>
>>> We can add a simple loop for each direction that relies on
>>> snd_soc_dai_stream_valid() to identify if each DAI is capable of doing
>>> playback/capture.
>>
>> see below completely untested diff to show what I had in mind: we already
>> make use of snd_soc_dai_stream_valid() in other parts of the core so we
>> should be able to determine dpcm_playback/capture based on the same
>> information already used.
>>
>> diff --git a/sound/soc/generic/audio-graph-card.c
>> b/sound/soc/generic/audio-graph-card.c
>> index 9ad35d9940fe..4c67f1f65eb4 100644
>> --- a/sound/soc/generic/audio-graph-card.c
>> +++ b/sound/soc/generic/audio-graph-card.c
>> @@ -215,7 +215,9 @@ static int graph_dai_link_of_dpcm(struct
>> asoc_simple_priv *priv,
>>          struct asoc_simple_dai *dai;
>>          struct snd_soc_dai_link_component *cpus = dai_link->cpus;
>>          struct snd_soc_dai_link_component *codecs = dai_link->codecs;
>> +       int stream;
>>          int ret;
>> +       int i;
>>
>>          /* Do it all CPU endpoint, and 1st Codec endpoint */
>>          if (!li->cpu && dup_codec)
>> @@ -317,8 +319,34 @@ static int graph_dai_link_of_dpcm(struct
>> asoc_simple_priv *priv,
>>          if (ret < 0)
>>                  goto out_put_node;
>>
>> -       dai_link->dpcm_playback         = 1;
>> -       dai_link->dpcm_capture          = 1;
>> +       for_each_pcm_streams(stream) {
>> +               struct snd_soc_dai_link_component *cpu;
>> +               struct snd_soc_dai_link_component *codec;
>> +               struct snd_soc_dai *d;
>> +               bool dpcm_direction = true;
>> +
>> +               for_each_link_cpus(dai_link, i, cpu) {
>> +                       d = snd_soc_find_dai(cpu);
>> +                       if (!d || !snd_soc_dai_stream_valid(d, stream)) {
>> +                               dpcm_direction = false;
>> +                               break;
>> +                       }
>> +               }
>> +               for_each_link_codecs(dai_link, i, codec) {
>> +                       d = snd_soc_find_dai(codec);
>> +                       if (!d || !snd_soc_dai_stream_valid(d, stream)) {
>> +                               dpcm_direction = false;
>> +                               break;
>> +                       }
>> +               }
>> +               if (dpcm_direction) {
>> +                       if (stream == SNDRV_PCM_STREAM_PLAYBACK)
>> +                               dai_link->dpcm_playback = 1;
>> +                       if (stream == SNDRV_PCM_STREAM_CAPTURE)
>> +                               dai_link->dpcm_capture = 1;
>> +               }
>> +       }
>> +
>>          dai_link->ops                   = &graph_ops;
>>          dai_link->init                  = asoc_simple_dai_init;
>>
> 
> Thanks for the diff! I tested it for my case and it seems to work fine
> so far. I'm fine with this solution given that it fixes the problem
> I mentioned. We would need to patch it into at least
> simple-audio-card.c, audio-graph-card.c and soc/qcom/common.c
> (probably best to create a shared function in soc-core.c then).

Yes, I worked on a helper in soc-dai.c and have a tentative proposal in 
https://github.com/thesofproject/linux/pull/2203

> However, personally I still think that dpcm_playback/capture essentially
> just duplicate the capabilities that are already exposed as part of the
> DAI drivers. We don't need that duplication in the non-DPCM case,
> so I wonder if we really need it for DPCM.

Fully agree, but removing 
dpcm_playback/capture/playback_only/capture_only should be done in a 
follow-up patchset. It's just too complicated to both fix the current 
DPCM configurations and clean-up at the same time, it'd prefer to do 
this cleanup in two steps.

> With your diff we go over all the DAIs to set dpcm_playback/capture
> correctly so that soc_new_pcm() can then verify that they were set
> correctly. IMO it would be much simpler to restore the previous behavior
> and just make soc_new_pcm() rely on the DAI capabilities to decide
> if playback/capture is supported, without producing the error.

I don't understand what previous behavior you are referring to (it's not 
something I personally changed), and these flags are also hard-coded in 
static dailink descriptors for machine drivers.



More information about the Alsa-devel mailing list