[alsa-devel] Choosing the sysclk in simple-card looks broken to me.
jonsmirl at gmail.com
jonsmirl at gmail.com
Sun Aug 10 14:34:20 CEST 2014
On Sun, Aug 10, 2014 at 6:54 AM, Mark Brown <broonie at kernel.org> wrote:
> On Sat, Aug 09, 2014 at 08:08:45PM -0400, jonsmirl at gmail.com wrote:
>
>> The problem is in asoc_simple_card_sub_parse_of()
>> in the else case..
>
>> } else {
>> clk = of_clk_get(node, 0);
>> if (!IS_ERR(clk))
>> dai->sysclk = clk_get_rate(clk);
>> }
>
>> This is picking up the input clocks to the devices. On the cpu-dai
>> you want to pick up the ouput mclk (my first input clock is an 80Mhz
>> bus clock). My IIS output clock is: clock-output-names = "mclk0";
>
>> Setting clocks="" doesn't work either, it also picks up the input clock.
>
> I'm sorry but I'm having an awfully hard time working out what you are
> trying to say in this mail. When you say things like "you want to pick
> up the ouput mclk" it's really not clear what any of that means - why do
> you want to pick it and what is it being picked for?
Inside simple audio card, __asoc_simple_card_dai_init() calls
snd_soc_dai_set_sysclk(). So where is it getting the clock values used
in __asoc_simple_card_dai_init()?
Here is my DTS for my cpu-dai...
iis0: iis at 01c22400 {
#clock-cells = <0>;
#sound-dai-cells = <0>;
compatible = "allwinner,sun7i-a20-iis";
reg = <0x01C22400 0x40>;
interrupts = <0 16 4>;
clocks = <&apb0_gates 3>, <&i2s0_clk>;
clock-names = "apb", "iis";
clock-output-names = "mclk0";
dmas = <&dma 0 3>, <&dma 0 3>;
dma-names = "rx", "tx";
status = "disabled";
};
This unit has three clocks.
apb - bus input 80Mhz to run the unit
iis - a programable input from a system PLL
mclk0 - a clock that is output to the MCLK pin
This is my codec
sgtl5000: sgtl5000 at a {
compatible = "fsl,sgtl5000";
reg = <0x0a>;
clocks = <&iis0>;
#sound-dai-cells = <0>;
VDDA-supply = <®_vcc3v3>;
VDDIO-supply = <®_vcc3v3>;
};
It has single input clock
clocks (unnamed) - it is wired to the MCLK pin
My simple audio card section...
sound {
compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = <&iis0>;
};
simple-audio-card,codec {
sound-dai = <&sgtl5000>;
};
};
Now look at what simple_card_dai_link_of() does. It parse this section
and then calls asoc_simple_card_sub_parse_of() for each of the two
DAI's.
Now look look at what asoc_simple_card_sub_parse_of() does when it
parses each of those subnodes. It looks up the first input clock off
from both of those nodes and saves it as dai->sysclk. Then in
__asoc_simple_card_dai_init() it pokes those values back into my
driver via snd_soc_dai_set_sysclk().
So on the first node.
simple-audio-card,cpu {
sound-dai = <&iis0>;
};
It goes over to the iis driver and gets rate from the first input
clock for iis0 - apb (80Mhz) and sets this back into my driver via
snd_soc_dai_set_sysclk().
On the second node
simple-audio-card,codec {
sound-dai = <&sgtl5000>;
};
Then it does a getrate() on the first input clock for sgtl5000. But
that clock has not been initialized yet. And then it sets the value
back in via snd_soc_dai_set_sysclk().
------
The problem is that asoc_simple_card_sub_parse_of() is doing getrate()
on input clocks when it should be doing it on output clocks.
So in my case, iis has a single output clock 'mclk0'. simple can
getrate() on it and then set the rate back in via
snd_soc_dai_set_sysclk(). Codec has no output clocks so it does
nothing with sysclk.
>
>> But then simple goes and tries to set both system clocks - my 80Mhz
>> bus clock and the 22.5 true sysclk. And my cpu-dai barfs when it is
>> passed a 80Mhz sysclk.
>
> Naturally... this does suggest you're doing something wrong but like I
> say I really don't understand what's going on. What does your system
> look like, what are you trying to get it to do and how are you going
> about that?
--
Jon Smirl
jonsmirl at gmail.com
More information about the Alsa-devel
mailing list