How to model 3xADAU1761 codec in TDM8 with 2xSAI in ALSA ?

Lars-Peter Clausen lars at metafoo.de
Tue Mar 10 22:02:47 CET 2020


On 3/10/20 8:21 PM, Rolf Peder Klemetsen wrote:
> Hi,
> 
> Thanks Lars.
> I finally got prefix working by adding "sound-name-prefix" to the
> adau1761 definitions under &i2c0. And as you stated the controls are
> now name "c1 LOUT", etc. So that is good!
> But I still haven't got multi-codec to work; only the first codec in
> each dailink is enumerated. The others are ignored.
> 
> To me it seems that Asoc simple card supports multi-codec. See for
> example  here:
> https://www.alsa-project.org/pipermail/alsa-devel/2018-March/133104.html
> and "Example 2 - many DAI links and multi-CODECs".
> I am unable to spot what is wrong with my dailink definition compared
> to the above example.

Hi,

I just had a quick look at the code and it seems that at the moment the 
simple-card only supports a single CODEC.

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/sound/soc/generic/simple-card-utils.c#n585

Your options are to extend it to support multiple CODECs or create a 
custom card driver that handles your case.

On a first look it seems it wouldn't be that difficult to extend it, but 
there might be some hidden pitfalls.

- Lars

> 
> 
> 
> 
> 
> 
> 
> 
> tir. 10. mar. 2020 kl. 14:28 skrev Lars-Peter Clausen <lars at metafoo.de>:
>>
>> On 3/9/20 9:33 AM, Rolf Peder Klemetsen wrote:
>>> Hello,
>>>
>>> I am working on bringup of a custom board that has three ADAU1761
>>> codecs, and a NXP LS1028A SoC. The codecs are supposed to be
>>> configured in TDM8 mode and share a common playback I2S bus connected
>>> to SAI4, and a common capture I2S bus connected to SAI3.
>>> What is the recommended way of modelling this setup in the Linux device tree ?
>>>
>>> So far I have tried the following:
>>>
>>> &i2c0 {
>>>       status = "okay";
>>>
>>>       i2c_codec1: adau1761 at 38 {
>>>           compatible = "adi,adau1761";
>>>           #sound-dai-cells=<0>;
>>>           reg = <0x38>;
>>>           tdm-offset = <0>;
>>>           clocks = <&adau1761_mclk>;
>>>           clock-names = "mclk";
>>>       };
>>>
>>>       i2c_codec2: adau1761 at 39 {
>>>           compatible = "adi,adau1761";
>>>           #sound-dai-cells=<0>;
>>>           reg = <0x39>;
>>>           tdm-offset = <16>;
>>>           clocks = <&adau1761_mclk>;
>>>           clock-names = "mclk";
>>>       };
>>>
>>>       i2c_codec3: adau1761 at 3a {
>>>           compatible = "adi,adau1761";
>>>           #sound-dai-cells=<0>;
>>>           reg = <0x3a>;
>>>           tdm-offset = <32>;
>>>           clocks = <&adau1761_mclk>;
>>>           clock-names = "mclk";
>>>       };
>>> };
>>>
>>> At first I attempted creating three simple-audio-card's. That
>>> attempted failed since sharing the same cpu (SAI3 and SAI4) failed
>>> with no ALSA device as a result.
>>>
>>> Then I attempted creating a single simple-audio-card with two
>>> dai-links (one for playback and one for capture), each containing
>>> three codec sub-nodes.
>>> That doesn't really work either. Can someone please point me in the
>>> right direction?
>>> Many of the parameters that I have put in the dts have no effect and
>>> are assumed not supported.
>>
>> Hi,
>>
>> One physical sound card is definitely the right direction. If you need
>> multiple sound cards exposed to userspace you can use the ALSA plugin
>> architecture to create multiple virtual sound cards on top of the one
>> sound card.
>>
>> Do you know why your approach with a single sound card does not work, do
>> you get any error messages? Is the sound card registered?
>>
>> The primary use case of the simple-audio-card is as the name suggests
>> simple setups and your setup is not that simple. It is possible that
>> your particular setup has never been tested with the simple-sound-card
>> and there are still some hidden bugs. It might also be the case that you
>> might have to create a custom sound card driver for your setup if you
>> can't make it work with the simple card driver.
>>
>> I believe I can see at least on issue with your DT snipped. For the
>> widgets that are registered by the CODECs the prefix will be added to
>> the name. So for example "LOUT" has to be "c1 LOUT", in addition you'll
>> have to add one route for each sound card.
>>
>> - Lars
>>
>>>
>>> Regards
>>> Rolf
>>>
>>> sound {
>>>           status = "okay";
>>>           model = "Super Sound System";
>>>           compatible = "simple-audio-card";
>>>           simple-audio-card,name = "sound";
>>>           simple-audio-card,format = "i2s";
>>>           simple-audio-card,bitclock-master = <&p_snd_codec_o1>;
>>>           simple-audio-card,frame-master = <&p_snd_codec_o1>;
>>>           simple-audio-card,widgets =
>>>               "Microphone", "Mic In",
>>>               "Headphone", "Headphone Out",
>>>               "Line", "Line In",
>>>               "Line", "Line Out";
>>>
>>>           simple-audio-card,routing =
>>>               "Line Out", "LOUT",
>>>               "Line Out", "ROUT",
>>>               "Headphone Out", "LHP",
>>>               "Headphone Out", "RHP",
>>>               "Mic In", "MICBIAS",
>>>               "LINN", "Mic In",
>>>               "RINN", "Mic In",
>>>               "LINP", "Mic In",
>>>               "RINP", "Mic In",
>>>               "LAUX", "Line In",
>>>               "RAUX", "Line In";
>>>
>>>           playback_link: simple-audio-card,dai-link at 0 {
>>>               format = "i2s";
>>>               convert-channels = <8>;
>>>               bitclock-master = <&p_snd_codec_o1>;
>>>               frame-master = <&p_snd_codec_o1>;
>>>               name-prefix = "p";
>>>
>>>               snd_dai_playback: cpu at 0 {
>>>
>>>                   cpu-dai-name = "sai4_0";
>>>                   sound-dai-name = "sai4_0";
>>>
>>>
>>>                   sound-dai = <&sai4 0>;
>>>                   dai-tdm-slot-num = <8>;
>>>                   dai-tdm-slot-width = <16>;
>>>                   dai-tdm-slot-tx-mask = <1 0 1 0 1 0 0 0>;
>>>                   dai-tdm-slot-rx-mask = <0 0 0 0 0 0 0 0>;
>>>               };
>>>
>>>               p_snd_codec_o1: codec at 0 {
>>>                   sound-dai = <&i2c_codec1>;
>>>                   frame-master;
>>>                   bitclock-master;
>>>                   clocks=<&adau1761_mclk>;
>>>                   clock-frequency = <12288000>;
>>>                   clock-names = "mclk";
>>>                   name-prefix = "c1";
>>>                   dai-tdm-slot-tx-mask = <1 0 0 0 0 0 0 0>;
>>>                   dai-tdm-slot-rx-mask = <0 0 0 0 0 0 0 0>;
>>>               };
>>>
>>>               p_snd_codec_o2: codec at 1 {
>>>                   sound-dai = <&i2c_codec2>;
>>>                   clocks=<&adau1761_mclk>;
>>>                   clock-frequency = <12288000>;
>>>                   clock-names = "mclk";
>>>                   name-prefix = "c2";
>>>                   dai-tdm-slot-tx-mask = <0 0 1 0 0 0 0 0>;
>>>                   dai-tdm-slot-rx-mask = <0 0 0 0 0 0 0 0>;
>>>               };
>>>               p_snd_codec_o3: codec at 2 {
>>>                   sound-dai = <&i2c_codec3>;
>>>                   clocks=<&adau1761_mclk>;
>>>                   clock-frequency = <12288000>;
>>>                   clock-names = "mclk";
>>>                   name-prefix = "c3";
>>>                   dai-tdm-slot-tx-mask = <0 0 0 0 1 0 0 0>;
>>>                   dai-tdm-slot-rx-mask = <0 0 0 0 0 0 0 0>;
>>>               };
>>>
>>>
>>>           };
>>>
>>>           capture_link: simple-audio-card,dai-link at 1 {
>>>               format = "i2s";
>>>               convert-channels = <8>;
>>>               bitclock-master = <&c_snd_codec_o1>;
>>>               frame-master = <&c_snd_codec_o1>;
>>>               name-prefix = "c";
>>>
>>>               snd_dai_capture: cpu at 0 {
>>>                   sound-dai = <&sai3>;
>>>                   dai-tdm-slot-num = <8>;
>>>                   dai-tdm-slot-width = <16>;
>>>                   dai-tdm-slot-tx-mask = <0 0 0 0 0 0 0 0>;
>>>                   dai-tdm-slot-rx-mask = <0 1 0 1 0 1 0 0>;
>>>               };
>>>
>>>               c_snd_codec_o1: codec at 0 {
>>>                   sound-dai = <&i2c_codec1>;
>>>                   frame-master;
>>>                   bitclock-master;
>>>                   clocks=<&adau1761_mclk>;
>>>                   clock-names = "mclk";
>>>                   clock-frequency = <12288000>;
>>>                   name-prefix = "c1";
>>>                   dai-tdm-slot-tx-mask = <0 0 0 0 0 0 0 0>;
>>>                   dai-tdm-slot-rx-mask = <0 1 0 0 0 0 0 0>;
>>>               };
>>>
>>>               c_snd_codec_o2: codec at 1 {
>>>                   sound-dai = <&i2c_codec2>;
>>>                   clocks=<&adau1761_mclk>;
>>>                   clock-names = "mclk";
>>>                   clock-frequency = <12288000>;
>>>                   name-prefix = "c2";
>>>                   dai-tdm-slot-tx-mask = <0 0 0 0 0 0 0 0>;
>>>                   dai-tdm-slot-rx-mask = <0 0 0 1 0 0 0 0>;
>>>               };
>>>               c_snd_codec_o3: codec at 2 {
>>>                   sound-dai = <&i2c_codec3>;
>>>                   clocks=<&adau1761_mclk>;
>>>                   clock-names = "mclk";
>>>                   clock-frequency = <12288000>;
>>>                   name-prefix = "c3";
>>>                   dai-tdm-slot-tx-mask = <0 0 0 0 0 0 0 0>;
>>>                   dai-tdm-slot-rx-mask = <0 0 0 0 0 1 0 0>;
>>>               };
>>>
>>>
>>>           };
>>
>>



More information about the Alsa-devel mailing list