ASoc: soc_core.c stream direction from snd_soc_dai

Shengjiu Wang shengjiu.wang at gmail.com
Sat Feb 20 10:29:03 CET 2021


On Fri, Mar 13, 2020 at 6:01 PM Lars-Peter Clausen <lars at metafoo.de> wrote:
>
> On 3/13/20 4:56 AM, Matt Flax wrote:
> >
> > On 13/3/20 10:19 am, Matt Flax wrote:
> >>
> >> On 13/3/20 9:55 am, Pierre-Louis Bossart wrote:
> >>>
> >>>
> >>> On 3/11/20 5:54 PM, Matt Flax wrote:
> >>>> Hi there,
> >>>>
> >>>> A large number of audio codecs allow different formats for playback
> >>>> and capture. This becomes very useful when there are different
> >>>> latencies between playback and capture hardware data lines. For
> >>>> example digital isolation chips typically have a 1 bit delay in
> >>>> propagation as the bit clock rate gets faster for higher sample
> >>>> rates. By setting the capture and playback formats to differ by one
> >>>> or two bit clock cycles, the delay problem is solved.
> >>>>
> >>>> There doesn't seem to be a simple way to detect stream direction in
> >>>> the codec driver's set_fmt function.
> >>>>
> >>>> The snd_soc_runtime_set_dai_fmt function :
> >>>>
> >>>> https://github.com/torvalds/linux/blob/master/sound/soc/soc-core.c#L1480
> >>>>
> >>>>
> >>>> calls the snd_soc_dai_set_fmt function :
> >>>>
> >>>> https://github.com/torvalds/linux/blob/master/sound/soc/soc-dai.c#L101
> >>>>
> >>>> which calls the set_fmt function :
> >>>>
> >>>> https://github.com/torvalds/linux/blob/master/include/sound/soc-dai.h#L189
> >>>>
> >>>>
> >>>>
> >>>> The snd_soc_dai_ops set_fmt function is defined as :
> >>>>
> >>>>      int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt);
> >>>>
> >>>>
> >>>> Is there a simple way to find the stream direction from a
> >>>> snd_soc_dai ?
> >>>>
> >>>> If the stream direction can be detected then the playback and
> >>>> capture formats can be set independently for the codec.
> >>>>
> >>>> It there a different way to set the playback and capture formats
> >>>> for the codec independently at runtime, depending on the sample rate ?
> >>>
> >>> FWIW I remember a discussion in the past on how to deal with
> >>> interfaces that may have different clocks sources for capture and
> >>> playback (typically with the 6-pin version of I2S/TDM), and the
> >>> answer was: use two dais, with one dealing with capture and the
> >>> other with playback.
> >>>
> >>> I would bet this applies for the format as well. If you use a DAI
> >>> that can do both directions, then indeed there's no obvious way to
> >>> specify that formats or clock ownership could be different between
> >>> the two directions.
> >>>
> >>> It would probably make sense anyway to have a representation with
> >>> two dais, e.g. the codec capture dai receives data from somewhere
> >>> and the codec playback dai forwards it to another destination.
> >>>
> >> I think I get it ...
> >>
> >> This approach would keep extra stream selective functionality out of
> >> soc-dai.c. That is probably a good thing for the simplicity of the core.
> >>
> >> A machine driver could then call snd_soc_dai_set_fmt passing in the
> >> correct codec_dai from the codec_dais array for the stream they want
> >> to operate on.
> >>
> > In an example case, cs4271 ... how do we enforce symmetric rates ?
>
> You'd have to do this manually in your driver. The core itself does not
> support synchronizing streams on different DAIs.
>
> You can do this by saving the rate when it is set on the first stream
> and then apply a constraint to the second stream using
> snd_pcm_hw_constraint_single() it the driver's startup() callback.
>
> Have a look at the uda134x.c or twl4030.c driver as an example.
>
> But I think Pierre was mainly talking about the case where there are
> separate clocks for each direction and the rates don't have to be the
> same. I believe long term it might make sense to extend the core to
> allow different formats for input and output direction on the same DAI.
>

Sorry for resuming this old thread. I have the same requirement for
supporting different formats for input and output on the same DAI.

One of the suggestions is to use two DAIs.  but sometimes the
CPU/CODEC may have the same format for playback and capture,
then one DAI is enough.  it means that we need to define 3 DAIs
for the CPU/CODEC,  one supports playback and capture, another
two support capture and playback separately, is it some kind of
duplicate?

So I'd like to extend the set_fmt() interface, but this impacts all
the drivers.

Best regards
Wang shengjiu


More information about the Alsa-devel mailing list