[alsa-devel] Bug? Sound support for at91sam9x5-wm8731 based boards
Richard Genoud
richard.genoud at gmail.com
Thu Nov 21 04:51:05 EST 2013
2013/11/20 Zhong Li <zql at glomationinc.com>:
>>
>> After reading the sources (mainly sound/soc/atmel/atmel_ssc_dai.c), I
>> don't understand how the right and left channel are synchronized.
>> (which one will be on TF rising edge, and which one on TF falling edge
>> ?)
>> In the SSC_TCMR register, the start event is TF_FALLING when there only
>> one channel (i.e. mono source always on left channel) With a stereo
>> source, it's TF_EDGE (Detection of any edge on TF
>> signal) ; so the samples are transferred on rising and falling edge.
>> I didn't see anything in the SSC what could synchronize the first
>> sample with a TF falling edge.
>> Or I missed something ?
>>
>
>
> The codec seems to be set to I2S mode based on the parameter name. And the FSOS field in the TFMR is set to be negative pulse. So it matches the I2S mode diagram (Figure 27 of WM8731 datasheet). The high to low on DACLRC (TF line aka PA25 pin) indicate start of the left channel data. Looks like the TF signal is automatically generated by the SSC controller according to the TFMR settings.
Yes, we use the I2S mode as in wm8731-figure27.
But the WM8731 is in master mode (wm8731-figure3). So it provides BCLK
(TK) and frame clock (DACLRC (TF)).
That's set in sam9x5_wm8731.c :
dai->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM;
DAIFMT_I2S : I2S mode obviously (wm8731 reg 7 bit 0:1 = 2)
DAIFMT_NB_NF : clock frames phasing (wm8731 reg7 bit4=0, bit7=0 : Left
channel when DAC is low and BCKL not inverted)
DAIFMT_CBM_CFM : master mode (wm8731 reg7 bit6=1 )
And I think you read the wrong value for the FSOS field of TFMR
register : in the I2S + CBM_CFM case, it's set to 0 because TF pin is
an input for the SSC.
So yes, the wm8731 generates the TK and TF signals and the SSC is
configured to send 16bits data on every TF edge (SSC_START_EDGE_RF).
The SSC_FSEDGE_POSITIVE flag will trigger the TXSYN interrupt on a TF
positive edge.
That's a way to get the sync between right/left channel I think :
If we set SSC_FSEDGE_POSITIVE, and enable the TXSYN interrupt, at the
first interrupt received we could start the DMA transfer (and disable
the interrupt).
The SSC will then send the 1st data (left data) on the next TF edge
which will be a negative edge (left channel).
Richard
More information about the linux-arm-kernel
mailing list