[alsa-devel] Multiple codecs on one sound card for multi-channel sound card

Caleb Crome caleb at crome.org
Thu Sep 17 15:38:23 CEST 2015


On Thu, Sep 17, 2015 at 1:51 AM, arnaud.mouiche at invoxia.com
<arnaud.mouiche at invoxia.com> wrote:
> Hello Caleb,
>
> freescale SSI is fine with more than 2 channels.
> I have planed to publish a set of patch in this direction but we still have
> some corner cases to fix first (rare issues with channels alignment)
>

I'd love to see anything you're willing to show :-)

> Yet, this following is far enough to have it working.
> And since the max/min rate is at the end the intersection of what the SSI,
> the codec and the card are declaring, it will not change anything until you
> connect the SSI to a codec with more than 2 channels, or a multi-codec
> solution.

What if I change channels_max to 16 for capture and playback?  Last
time I tried, it would not keep the channels synchronized on the TDM
bus.  I tried playing with the FIFO settings, which helped, but it
still would not start each channel in the right slot reliably.
Perhaps I was using an older kernel.

I'll give it a try again.  Like I said, we'd love to get our
16-channel board up and running on the MX6, so I'm definitely
motivated to put some work in to get it reliable.

Thanks,
 -Caleb


>
> Arnaud
>
> diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
> index c25a1e8..26e980b 100644
> --- a/sound/soc/fsl/fsl_ssi.c
> +++ b/sound/soc/fsl/fsl_ssi.c
> @@ -1082,14 +1082,14 @@ static struct snd_soc_dai_driver
> fsl_ssi_dai_template = {
>         .playback = {
>                 .stream_name = "CPU-Playback",
>                 .channels_min = 1,
> -               .channels_max = 2,
> +               .channels_max = 4,
>                 .rates = FSLSSI_I2S_RATES,
>                 .formats = FSLSSI_I2S_FORMATS,
>         },
>         .capture = {
>                 .stream_name = "CPU-Capture",
>                 .channels_min = 1,
> -               .channels_max = 2,
> +               .channels_max = 4,
>                 .rates = FSLSSI_I2S_RATES,
>                 .formats = FSLSSI_I2S_FORMATS,
>         },
>
>
>
> Le 17/09/2015 00:07, Caleb Crome a écrit :
>>
>> Ah Ha!  thank you Arnaud!  I'll understand this stuff eventually.
>> I'll implement as you've shown and see how it goes.
>>
>> I see that you have 'fsl,imx-audio-foo', using an SSI.  from what I
>> can see the SSIs only support channels_max=2.  How do you get
>> multi-channel TDM to work with the freescale SSI port?  I need to get
>> this TDM working on both TI & Freescale, and the freescale has been
>> quite problematic because the multi-channel doesn't seem to be
>> supported in the driver.
>>
>> I have just checked out and verified that
>>
>> http://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git/
>>
>> sound/soc/fsl/*ssi*
>>
>> all have channels_max = 2
>>
>> We're very motivated to get this working on the freescale MX6, and
>> getting it to work sure does not seem as simple as changing 2 to a
>> bigger number :-)
>>
>>
>> Thanks,
>>    -Caleb
>>
>>
>> On Wed, Sep 16, 2015 at 2:57 AM, arnaud.mouiche at invoxia.com
>> <arnaud.mouiche at invoxia.com> wrote:
>>>
>>> Hello Caleb,
>>>
>>> Multi-codec support is now working fine the current linux releases.
>>> for previous releases, check if commit
>>>      [PATCH] ASoC: dapm: Don't add prefix to widget stream name
>>> is included. I remember this is the last required patch.
>>>
>>> After that, I don't know if the "simple-card" can be configured for multi
>>> codec support as you wish.
>>>
>>> On my side, I cooked a particular sound card for the purpose.
>>> here is some tips:
>>>
>>>
>>>      struct snd_soc_dai_link_component codecs[2];
>>>      struct snd_soc_codec_conf codecs_conf[2];
>>> [...]
>>>      for (num_codecs=0; num_codecs<2; num_codecs++) {
>>>          struct device_node *of_node;
>>>          of_node = of_parse_phandle(pdev->dev.of_node, "audio-codec",
>>> num_codecs);
>>>          if (!of_node) break;
>>>          data->codecs[num_codecs].of_node = of_node;
>>>          data->codecs[num_codecs].dai_name = "tlv320aic3x-foo";
>>>
>>>          /* add a "C2" name prefix for every control of the 2nd codec */
>>>          data->codecs_conf[num_codecs].of_node = of_node;
>>>          if (num_codecs == 1) {
>>>              data->codecs_conf[num_codecs].name_prefix = "C2";
>>>          }
>>>      }
>>> [...]
>>>      data->dai.codecs = data->codecs;
>>>      data->dai.num_codecs = num_codecs;
>>>      data->card.dai_link = &data->dai;
>>>      data->card.codec_conf = data->codecs_conf;
>>>      data->card.num_configs = num_codecs;
>>> [...]
>>>
>>>
>>> On DTS side, I have something like
>>>
>>>      sound at 0 {
>>>          compatible = "fsl,imx-audio-foo";
>>>          model = "foo-audio";
>>>          ssi-controller = <&ssi1>;
>>>
>>>          /*
>>>           * list phandles for the 2 codecs used in the same TDM network
>>>           */
>>>          audio-codec = <&codec1>, <&codec2>;
>>>
>>>          [...]
>>>
>>>      };
>>>
>>>
>>> You also need to have a particular hw_params() method to dispatch the TDM
>>> and sysclk configuration to your codecs, making the difference between
>>> your
>>> first codec (your bus master) and the others.
>>>
>>>
>>> Arnaud
>>>
>>>
>>> Le 15/09/2015 03:07, Caleb Crome a écrit :
>>>>
>>>> (re-sending hope it's not a duplicate -- I think I must have had HTML
>>>> in my previous email and it was ignored)
>>>>
>>>>    Hi all,
>>>>       What are the current best practices to specify multiple codecs on
>>>> one sound card, with all codecs sharing a single TDM bus?
>>>>
>>>>    I have a card with up to 32 TLV320AIC33 codecs on it.  For the
>>>> moment, we can limit the discussion to only 16 codecs, so we don't
>>>> have to get extra serializers involved...
>>>>
>>>>    I currently have something like this in my am335x-boneblack.dts file:
>>>>
>>>>    (i.e. attempting to set tdm slot width and num in the i2c codec)
>>>>
>>>>    but it doesn't seem to be picking up the fact that I want all the
>>>> codecs linked together as one.
>>>>
>>>>    (FYI, the first codec, i.e. tlv32aic3x_a should be the master, and
>>>> all others including the CPU will be slaves).
>>>>
>>>>    Thanks for any help!
>>>>
>>>>    BTW, I'm happy to use whatever kernel will support me with the
>>>> minimal amount of effort, currently using 4.1
>>>>
>>>>
>>>>
>>>> Thank you!
>>>>      -Caleb
>>>>
>>>> &i2c1 {
>>>>    ...
>>>> tlv320aic3x_a: tlv320aic3x at 18 {
>>>> #sound-dai-cells = <1>;
>>>> compatible = "ti,tlv320aic3x";
>>>> reg = <0x18>;
>>>> tdm-offset = <0>;
>>>> status = "okay";
>>>> };
>>>> tlv320aic3x_b: tlv320aic3x at 19 {
>>>> #sound-dai-cells = <1>;
>>>> compatible = "ti,tlv320aic3x";
>>>> reg = <0x19>;
>>>> tdm-offset = <32>;
>>>> status = "okay";
>>>> };
>>>> tlv320aic3x_c: tlv320aic3x at 1a {
>>>> #sound-dai-cells = <1>;
>>>> compatible = "ti,tlv320aic3x";
>>>> reg = <0x1a>;
>>>> tdm-offset = <64>;
>>>> status = "okay";
>>>> };
>>>> tlv320aic3x_d: tlv320aic3x at 1b {
>>>> #sound-dai-cells = <1>;
>>>> compatible = "ti,tlv320aic3x";
>>>> reg = <0x1b>;
>>>> tdm-offset = <96>;
>>>> status = "okay";
>>>> };
>>>> };
>>>>
>>>> &mcasp0 {
>>>> #sound-dai-cells = <0>;
>>>> pinctrl-names = "default";
>>>> pinctrl-0 = <&mcasp_0_pins_default>;
>>>> status = "okay";
>>>>
>>>> op-mode = <0>;          /* MCASP_IIS_MODE */
>>>> tdm-slots = <16>;
>>>> num-serializer = <16>;
>>>> serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
>>>> 0 0 1 2
>>>> 0 0 0 0
>>>> 0 0 0 0
>>>> 0 0 0 0
>>>>>
>>>>> ;
>>>>
>>>> tx-num-evt = <1>;
>>>> rx-num-evt = <1>;
>>>> };
>>>>
>>>> / {
>>>> sound {
>>>> compatible = "simple-audio-card";
>>>> simple-audio-card,name = "puppy-audio";
>>>> simple-audio-card,mclk-fs = <256>;
>>>> system-clock-frequency = <12288000>;
>>>> status = "okay";
>>>> simple-audio-card,bitclock-master = <&tlv320aic3x_a>;
>>>>         simple-audio-card,frame-master    = <&tlv320aic3x_a>;
>>>> simple-audio-card,widgets =
>>>> "Line", "Line Out",
>>>> "Line", "Line In";
>>>> simple-audio-card,routing =
>>>> "Line Out",       "HPLOUT",
>>>> "Line Out",       "HPROUT",
>>>> "Line In",        "LINE1L",
>>>> "Line In",        "LINE1R";
>>>>
>>>> simple-audio-card,dai-link at 0 {
>>>> format = "left_j";
>>>> cpu {
>>>> sound-dai = <&mcasp0>;
>>>> };
>>>> codec {
>>>> sound-dai = <&tlv320aic3x_a 0>;
>>>> dai-tdm-slot-num = <0>;
>>>> dai-tdm-slot-width = <16>;
>>>> };
>>>> };
>>>> /**** The stuff below doesn't work -- I can't figure out how to get
>>>> the name_prefixes set
>>>>    on each codec... .How do I set up so that each codec gets its own
>>>> name
>>>> prfix
>>>> and so that the soc core thinks all codecs are on the same DAI?
>>>> **** */
>>>>
>>>> // simple-audio-card,dai-link at 1 {
>>>> // format = "left_j";
>>>> // cpu {
>>>> // sound-dai = <&mcasp0>;
>>>> // };
>>>> // codec {
>>>> // sound-dai = <&tlv320aic3x_b 0>;
>>>> // dai-tdm-slot-num = <2>;
>>>> // dai-tdm-slot-width = <16>;
>>>> // };
>>>> // };
>>>> // simple-audio-card,dai-link at 2 {
>>>> // format = "left_j";
>>>> // cpu {
>>>> // sound-dai = <&mcasp0>;
>>>> // };
>>>> // codec {
>>>> // sound-dai = <&tlv320aic3x_c>;
>>>> // dai-tdm-slot-num = <4>;
>>>> // dai-tdm-slot-width = <16>;
>>>> // };
>>>> // };
>>>> // simple-audio-card,dai-link at 3 {
>>>> // format = "left_j";
>>>> // cpu {
>>>> // sound-dai = <&mcasp0>;
>>>> // };
>>>> // codec {
>>>> // sound-dai = <&tlv320aic3x_d>;
>>>> // dai-tdm-slot-num = <6>;
>>>> // dai-tdm-slot-width = <16>;
>>>> // };
>>>> // };
>>>> };
>>>> };
>>>> _______________________________________________
>>>> Alsa-devel mailing list
>>>> Alsa-devel at alsa-project.org
>>>> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>>>
>>>
>>> _______________________________________________
>>> Alsa-devel mailing list
>>> Alsa-devel at alsa-project.org
>>> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>
>


More information about the Alsa-devel mailing list