Dear all,
I'm trying to connect a codec ( wm8740) through ssi1 and audmux4.
I succeed to connect and play a media with sample rate of 44100 by changing the ssi1_clk to 11289600 but i guess it is not the solution.
My configuration is
unsigned int ptcr, pdcr; | ||
slave = slave - 1; | ||
master = master - 1; | ||
ptcr = MXC_AUDMUX_V2_PTCR_SYN | | ||
MXC_AUDMUX_V2_PTCR_TFSDIR | | ||
MXC_AUDMUX_V2_PTCR_TFSEL(slave) | | ||
MXC_AUDMUX_V2_PTCR_RCLKDIR | | ||
MXC_AUDMUX_V2_PTCR_RCSEL(slave | 0x8) | | ||
MXC_AUDMUX_V2_PTCR_TCLKDIR | | ||
MXC_AUDMUX_V2_PTCR_TCSEL(slave); | ||
pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(slave); | ||
mxc_audmux_v2_configure_port(master, ptcr, pdcr); | ||
ptcr = ptcr & ~MXC_AUDMUX_V2_PTCR_SYN; | ||
mxc_audmux_v2_configure_port(master, ptcr, pdcr); |
ptcr = MXC_AUDMUX_V2_PTCR_SYN | | ||
MXC_AUDMUX_V2_PTCR_RCLKDIR | | ||
MXC_AUDMUX_V2_PTCR_RCSEL(master | 0x8) | | ||
MXC_AUDMUX_V2_PTCR_TCLKDIR | | ||
MXC_AUDMUX_V2_PTCR_TCSEL(master); | ||
pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(master); | ||
mxc_audmux_v2_configure_port(slave, ptcr, pdcr); | ||
ptcr = ptcr & ~MXC_AUDMUX_V2_PTCR_SYN; | ||
mxc_audmux_v2_configure_port(slave, ptcr, pdcr); |
In this case i have a MCLK coming which is SRCK (network_clock) then STCK which is the bitclock and the frame clock.
How could i change the MCLK without changing the ssi_clk ? Is there a way to put some divider on this clock ?
Any advise ?
Or how can I change the ssi sys clock in imx_ssi.c or anywhere else? It seems that according to the reference manual(page 5126) we can change ssi sys clk to 12,288 by example.
What is the best way to change it ?
Hello,Cerveau,
MCLK is a clock for audio codec working. It can be changed to system clock of audio codec by PLL in codec, or use it directly. For most of audio codecs, it system clock(bit clock) supports : sysclk = 512*FS or 384*FS or 256*FS, Here FS is sample rate. For example 44.1K, 48K ect.
if you set ssi output clk(bitclk)=11.2896M, FS=44.1K, It means WM8740 supports 256*FS . you can check WM8740 datasheet and confirm this point.
--------------------
In addition, User doesn't need to change bitclk manually, when playing a audio file(such as .wav), sound card driver should get parameters including sample rate from audio file, then set sysclk and sample rate(FS) to Master Side(CPU ssi or audio codec). It is done automatically by drivers !
Regards,
Weidong
Here is my solution to set the SRCK to different value.
static struct {
u32 sample_rate;
u32 rate_pll_clk;
u32 rate_ssi_clk;
u32 div_pm;
} lrclk_ratios[] = {
{ 32000, 688128000, 12288000, 2 },
{ 44100, 632217600, 11289600, 1 },
{ 48000, 688128000, 12288000, 1 },
{ 96000, 688128000, 12288000, 0 },
{ 192000, 24576000, 24576000, 3 },
};
In imx_wm8740_params:
switch(sample_rate) { | |
---|---|
case 32000: | |
i = 0; | |
break; | |
case 44100: | |
i = 1; | |
break; | |
case 48000: | |
i = 2; | |
break; | |
case 96000: | |
i = 3; | |
break; | |
case 19200: | |
i= 4; | |
break; | |
default: | |
pr_err("sample rate %d not supported\n",sample_rate); | |
return -EINVAL; | |
} | |
if(!card_priv.ssi_clk) | |
{ | |
card_priv.ssi_clk = clk_get(cpu_dai->dev,"NULL"); | |
if (IS_ERR(card_priv.ssi_clk)) { | |
pr_err("can't get ssi1_clk clock.\n"); | |
return -EINVAL; | |
} | |
clk_set_parent(card_priv.ssi_clk, card_priv.ssi_parent_clk); | |
} | |
/* change pll4 value */ | |
rate = clk_round_rate(card_priv.ssi_parent_clk, lrclk_ratios[i].rate_pll_clk); | |
clk_set_rate(card_priv.ssi_parent_clk, rate); | |
/* change ssi clk based on pll4 */ | |
rate = clk_round_rate(card_priv.ssi_clk, lrclk_ratios[i].rate_ssi_clk); | |
clk_set_rate(card_priv.ssi_clk, rate); |
/* Activate the MCLK from SRCK */ | |
snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0, SND_SOC_CLOCK_OUT); |
Hope it can help someone.
Best regards.
Stéphane