On Fri, Mar 13, 2020 at 6:01 PM Lars-Peter Clausen <lars@xxxxxxxxxx> 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