[alsa-devel] [Q] ASoC: What's the real meaning of SND_SOC_DAIFMT_NB_NF?
Hi, I am trying to configure a DAI interface between a i.MX27 SSI and a wm8974 codec.
The definition of SND_SOC_DAIFMT_NB_NF specifies 'normal' bit clock and frame for the specified format. http://lxr.linux.no/#linux+v3.2.7/include/sound/soc-dai.h#L48
As I wasn't sure about the meaning of 'normal' I've dug into the code of some platforms to see what they do. What I've found, however, is that it doesn't seem to be an agreement about it.
Let me expose some examples:
1. Frame clock is active High:
i.MX: http://lxr.linux.no/#linux+v3.2.7/sound/soc/imx/imx-ssi.c#L131 + MCIMX27RM.pdf (p 1606) (default) PXA: http://lxr.linux.no/#linux+v3.2.7/sound/soc/pxa/pxa-ssp.c#L498 pxa-ssp.c + PXA3xx_DM_Vol_IV.pdf (p 332) (not default)
2. Frame clock is active Low:
OMAP: http://lxr.linux.no/#linux+v3.2.7/sound/soc/omap/omap-mcbsp.c#L478 + sprugn4h.pdf (p 3165) (not default)
Some chips like s6000 seem to provide a more original use for this flag:
http://lxr.linux.no/#linux+v3.2.7/sound/soc/s6000/s6000-i2s.c#L255
Similar behavior has been found for bit clock.
ALso, it seems that there is no possibility to specify different configurations for RX and TX parts.
On Thu, Feb 23, 2012 at 01:40:40PM +0100, javier Martin wrote:
As I wasn't sure about the meaning of 'normal' I've dug into the code of some platforms to see what they do. What I've found, however, is that it doesn't seem to be an agreement about it.
It's whatever is standard for the given format - the Wolfson datasheets are a pretty good reference, they have clear diagrams.
ALso, it seems that there is no possibility to specify different configurations for RX and TX parts.
This is correct, if the configurations are different you're really looking at separate audio interfaces so should have multiple DAIs.
On 23 February 2012 16:19, Mark Brown broonie@opensource.wolfsonmicro.com wrote:
On Thu, Feb 23, 2012 at 01:40:40PM +0100, javier Martin wrote:
As I wasn't sure about the meaning of 'normal' I've dug into the code of some platforms to see what they do. What I've found, however, is that it doesn't seem to be an agreement about it.
It's whatever is standard for the given format - the Wolfson datasheets are a pretty good reference, they have clear diagrams.
So, let's see if I understood properly. If I want to configure the i.MX SSI into standard, I2S format I should do:
dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF; snd_soc_dai_set_fmt(cpu_dai, dai_format);
However, this doesn't work with the imx-ssi driver which does the following: http://lxr.linux.no/#linux+v3.2.7/sound/soc/imx/imx-ssi.c#L83
case SND_SOC_DAIFMT_I2S: /* data on rising edge of bclk, frame low 1clk before data */ strcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0; scr |= SSI_SCR_NET; if (ssi->flags & IMX_SSI_USE_I2S_SLAVE) { scr &= ~SSI_I2S_MODE_MASK; scr |= SSI_SCR_I2S_MODE_SLAVE; } break; [...] case SND_SOC_DAIFMT_NB_NF: strcr &= ~SSI_STCR_TFSI; strcr |= SSI_STCR_TSCKP; break;
While initially TFSI bit is set because of I2S flag, it is then cleared because of the NB_NF.
Does this mean this is a bug then? If it is, I would gladly fix it but there is at least one platform relying on this misleading behavior that I can't test: http://lxr.linux.no/#linux+v3.2.7/sound/soc/imx/wm1133-ev1.c#L81
On Thu, Feb 23, 2012 at 04:58:09PM +0100, javier Martin wrote:
So, let's see if I understood properly. If I want to configure the i.MX SSI into standard, I2S format I should do:
dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF; snd_soc_dai_set_fmt(cpu_dai, dai_format);
Yes.
While initially TFSI bit is set because of I2S flag, it is then cleared because of the NB_NF.
Does this mean this is a bug then? If it is, I would gladly fix it but
I've no idea what any of the register settings mean here...
there is at least one platform relying on this misleading behavior that I can't test: http://lxr.linux.no/#linux+v3.2.7/sound/soc/imx/wm1133-ev1.c#L81
That was correct at the time it was written, though the code has changed since then and I don't know when it was last retested. Of course depending on the signal it may interoperate well even if the setup isn't actually correct. I'd just fix the driver and if it works for yours it's probably OK for that board too.
On 23 February 2012 17:14, Mark Brown broonie@opensource.wolfsonmicro.com wrote:
On Thu, Feb 23, 2012 at 04:58:09PM +0100, javier Martin wrote:
So, let's see if I understood properly. If I want to configure the i.MX SSI into standard, I2S format I should do:
dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF; snd_soc_dai_set_fmt(cpu_dai, dai_format);
Yes.
While initially TFSI bit is set because of I2S flag, it is then cleared because of the NB_NF.
Does this mean this is a bug then? If it is, I would gladly fix it but
I've no idea what any of the register settings mean here...
If TFSI bit is 1, frame clock is active high. If TFSI bit is 0, frame clock is active low.
In the piece of code I've shown to you, when someone configures (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF) he's really selecting an active high frame clock when the standard says just the opposite (wm8974 datasheet p50).
there is at least one platform relying on this misleading behavior that I can't test: http://lxr.linux.no/#linux+v3.2.7/sound/soc/imx/wm1133-ev1.c#L81
That was correct at the time it was written, though the code has changed since then and I don't know when it was last retested. Of course depending on the signal it may interoperate well even if the setup isn't actually correct. I'd just fix the driver and if it works for yours it's probably OK for that board too.
It is not one but two boards that are affected: http://lxr.linux.no/#linux+v3.2.7/sound/soc/imx/wm1133-ev1.c#L81 http://lxr.linux.no/#linux+v3.2.7/sound/soc/imx/eukrea-tlv320.c#L32
If I fixed the bug in the SSI I would break both of them, since I would be changing frame clock polarity.
Regards.
On 02/24/2012 09:53 AM, javier Martin wrote:
If TFSI bit is 1, frame clock is active high. If TFSI bit is 0, frame clock is active low.
In the piece of code I've shown to you, when someone configures (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF) he's really selecting an active high frame clock when the standard says just the opposite (wm8974 datasheet p50).
We had similar issues on OMAP McBSP in the past. If you take a look at the omap-mcbsp.c: omap_mcbsp_dai_set_dai_fmt() function we have inv_fs variable to handle such a case. We do the FS/BCLK configuration only in DAIFMT_INV config phase. The FS active level is different in these formats. We invert the FS based on the used format (LEFT/RIGHT just, DSP). The DAIFMT_INV switch configures according to I2S, but we invert the FS if we are in DSP, Justified modes afterwards.
there is at least one platform relying on this misleading behavior that I can't test: http://lxr.linux.no/#linux+v3.2.7/sound/soc/imx/wm1133-ev1.c#L81
That was correct at the time it was written, though the code has changed since then and I don't know when it was last retested. Of course depending on the signal it may interoperate well even if the setup isn't actually correct. I'd just fix the driver and if it works for yours it's probably OK for that board too.
It is not one but two boards that are affected: http://lxr.linux.no/#linux+v3.2.7/sound/soc/imx/wm1133-ev1.c#L81 http://lxr.linux.no/#linux+v3.2.7/sound/soc/imx/eukrea-tlv320.c#L32
If I fixed the bug in the SSI I would break both of them, since I would be changing frame clock polarity.
I don't think it is going to break. I would guess that the channels are swapped on these machines at the moment. If you correct the CPU dai driver the only thing that will happen is that the channels will jump in their correct place.
On 24 February 2012 09:34, Peter Ujfalusi peter.ujfalusi@ti.com wrote:
On 02/24/2012 09:53 AM, javier Martin wrote:
If TFSI bit is 1, frame clock is active high. If TFSI bit is 0, frame clock is active low.
In the piece of code I've shown to you, when someone configures (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF) he's really selecting an active high frame clock when the standard says just the opposite (wm8974 datasheet p50).
We had similar issues on OMAP McBSP in the past. If you take a look at the omap-mcbsp.c: omap_mcbsp_dai_set_dai_fmt() function we have inv_fs variable to handle such a case. We do the FS/BCLK configuration only in DAIFMT_INV config phase. The FS active level is different in these formats. We invert the FS based on the used format (LEFT/RIGHT just, DSP). The DAIFMT_INV switch configures according to I2S, but we invert the FS if we are in DSP, Justified modes afterwards.
I intend to do something similar for imx-ssi. What keeps me awake is that there are some other platforms as well that don't respect the convention.
there is at least one platform relying on this misleading behavior that I can't test: http://lxr.linux.no/#linux+v3.2.7/sound/soc/imx/wm1133-ev1.c#L81
That was correct at the time it was written, though the code has changed since then and I don't know when it was last retested. Of course depending on the signal it may interoperate well even if the setup isn't actually correct. I'd just fix the driver and if it works for yours it's probably OK for that board too.
It is not one but two boards that are affected: http://lxr.linux.no/#linux+v3.2.7/sound/soc/imx/wm1133-ev1.c#L81 http://lxr.linux.no/#linux+v3.2.7/sound/soc/imx/eukrea-tlv320.c#L32
If I fixed the bug in the SSI I would break both of them, since I would be changing frame clock polarity.
I don't think it is going to break. I would guess that the channels are swapped on these machines at the moment. If you correct the CPU dai driver the only thing that will happen is that the channels will jump in their correct place.
That would be true for stereo. However, mono should not be working right now.
On Fri, Feb 24, 2012 at 12:05:09PM +0100, javier Martin wrote:
On 24 February 2012 09:34, Peter Ujfalusi peter.ujfalusi@ti.com wrote:
I don't think it is going to break. I would guess that the channels are swapped on these machines at the moment. If you correct the CPU dai driver the only thing that will happen is that the channels will jump in their correct place.
That would be true for stereo. However, mono should not be working right now.
Mono isn't particularly defined for I2S at the best of times; the clocking is inherently stereo. You may just pick out the left channel or you may duplicate things on left and right channels (at which point a polarity change won't be noticed). I wouldn't worry too much about it, it's better to have things the right way round and fix up configuration for machines that need it.
On 02/24/2012 01:05 PM, javier Martin wrote:
I don't think it is going to break. I would guess that the channels are swapped on these machines at the moment. If you correct the CPU dai driver the only thing that will happen is that the channels will jump in their correct place.
That would be true for stereo. However, mono should not be working right now.
The notion of mono in I2S, Left/Right Justified formats is not really valid. They are stereo protocols by design. DSP_A/B is used with mono audio (which often referred as PCM). It is the responsibility of the codec/cpu drivers to interpret the standards correctly, and configure themselves accordingly. Take a look at the Wolfson codec documentation they are really good in this matter (what I2S, DSP/PCM, and other coding means in real life). You can look at the omap-mcbsp driver for an example, but configuring the FS/BC polarity in the format selection (without taking a look at the INV mask) does not seam to be correct.
On Fri, Feb 24, 2012 at 08:53:11AM +0100, javier Martin wrote:
In the piece of code I've shown to you, when someone configures (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF) he's really selecting an active high frame clock when the standard says just the opposite (wm8974 datasheet p50).
If I fixed the bug in the SSI I would break both of them, since I would be changing frame clock polarity.
No, with I2S the main effect of inverting the frame clock is to cause a left/right swap which is a relatively subtle issue, it's not obvious on an immediate listening test. It's not really active high or active low but rather indicating which channel the sample is.
participants (3)
-
javier Martin
-
Mark Brown
-
Peter Ujfalusi