Xiubo,
I did a mistake in the v1 of my 'ASoC: simple-card: simplify code': I
did not initialize the pointer to the asoc_simple_card_dai_init()
function when DT. Then, I fixed that, and the simple card does not work
for me.
First, without any 'format' in the DT, I get a fmt for each CPU / CODEC
DAI: SND_SOC_DAIFMT_CBS_CFS is always set. Well, some code is executed
for nothing, but this is not critical.
The main problem is about sysclk: when there is no clock in the DT,
you get the clock of the CPU or CODEC DAI. In my system, two clocks
are declared in the controller CPU DAI, but there is no .set_sysclk
pointer. So, snd_soc_dai_set_sysclk() returns -EINVAL and the card is
not created.
As I don't know why you need these fmt and sysclk, may you have a
look at these problems?
--
Ken ar c'hentañ | ** Breizh ha Linux atav! **
Jef | http://moinejf.free.fr/
On Wed, Jan 15, 2014 at 07:18:31PM +0100, Jean-Francois Moine wrote:
> Xiubo,
Adding Morimoto-san.
> I did a mistake in the v1 of my 'ASoC: simple-card: simplify code': I
> did not initialize the pointer to the asoc_simple_card_dai_init()
> function when DT. Then, I fixed that, and the simple card does not work
> for me.
>
> First, without any 'format' in the DT, I get a fmt for each CPU / CODEC
> DAI: SND_SOC_DAIFMT_CBS_CFS is always set. Well, some code is executed
> for nothing, but this is not critical.
>
> The main problem is about sysclk: when there is no clock in the DT,
> you get the clock of the CPU or CODEC DAI. In my system, two clocks
> are declared in the controller CPU DAI, but there is no .set_sysclk
> pointer. So, snd_soc_dai_set_sysclk() returns -EINVAL and the card is
> not created.
>
> As I don't know why you need these fmt and sysclk, may you have a
> look at these problems?
>
> --
> Ken ar c'henta? | ** Breizh ha Linux atav! **
> Jef | http://moinejf.free.fr/
>
On Wed, Jan 15, 2014 at 07:18:31PM +0100, Jean-Francois Moine wrote:
> The main problem is about sysclk: when there is no clock in the DT,
> you get the clock of the CPU or CODEC DAI. In my system, two clocks
> are declared in the controller CPU DAI, but there is no .set_sysclk
> pointer. So, snd_soc_dai_set_sysclk() returns -EINVAL and the card is
> not created.
set_sysclk() should be returning -ENOTSUPP in this case as with
set_fmt() and the generic code then ignoring that error.
> As I don't know why you need these fmt and sysclk, may you have a
> look at these problems?
The overwhelming majority of combinations of devices need a format
specifying (usually one will be imposed by the system design even if
both devices could be master).
Hi
> > The main problem is about sysclk: when there is no clock in the DT,
> > you get the clock of the CPU or CODEC DAI. In my system, two clocks
> > are declared in the controller CPU DAI, but there is no .set_sysclk
> > pointer. So, snd_soc_dai_set_sysclk() returns -EINVAL and the card is
> > not created.
>
> set_sysclk() should be returning -ENOTSUPP in this case as with
> set_fmt() and the generic code then ignoring that error.
>
> > As I don't know why you need these fmt and sysclk, may you have a
> > look at these problems?
>
> The overwhelming majority of combinations of devices need a format
> specifying (usually one will be imposed by the system design even if
> both devices could be master).
If my understanding is correct, this patch is the reason ?
71467e46414d3bab220de77d3d085be0c0aa03e1
(ASoC: simple-card: Add device's module clock selection)
It seems break non .set_sysclk drivers.
Hi,
> I did a mistake in the v1 of my 'ASoC: simple-card: simplify code': I
> did not initialize the pointer to the asoc_simple_card_dai_init()
> function when DT. Then, I fixed that, and the simple card does not work
> for me.
>
> First, without any 'format' in the DT, I get a fmt for each CPU / CODEC
> DAI: SND_SOC_DAIFMT_CBS_CFS is always set. Well, some code is executed
> for nothing, but this is not critical.
>
This is the old issue that I have raised before, which is one limitation
of snd_soc_of_parse_daifmt(). As descript above, if without any fmt in the
DT node, and just using snd_soc_of_parse_daifmt() for each CPU/CODEC DAI fmt
the SND_SOC_DAIFMT_CBS_CFS (none zero) is always set.
@Mark and Morimoto-san, there has two ways to deal with this in my mind:
Fist, in the snd_soc_of_parse_daifmt(), modifying the
boolen : "[prefix]bitclock-master"
boolen : "[prefix]frame-master"
==>
[prefix]master = "XXX" and "XXX" is :
"cbm-cfm" --> SND_SOC_DAIFMT_CBM_CFM
"cbs-cfm" --> SND_SOC_DAIFMT_CBS_CFM
"cbm-cfs" --> SND_SOC_DAIFMT_CBM_CFS
"cbs-cfs" --> SND_SOC_DAIFMT_CBS_CFS
And the default value will be zero...
If this method is applied, and there is no need any masks for
snd_soc_of_parse_daifmt(), like in simple card driver:
/* get CPU/CODEC common format via simple-audio-card,format */
info->daifmt = snd_soc_of_parse_daifmt(node, "simple-audio-card,") &
(SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK);
Second, if there hasn't any DAI fmts in DT node and at the same time the CPU
and CODEC DAI devices don't need to care about of them, and set_dai() pointer
could be set to be NULL, and then snd_soc_dai_set_fmt() just returned -ENOTSUPP.
Thanks,
????{.n?+???????+%?????ݶ??w??{.n?+????{??G?????{ay?ʇڙ?,j??f???h?????????z_??(?階?ݢj"???m??????G????????????&???~???iO???z??v?^?m????????????I?