From 4f1b399e46833818a78886e4300212e4c1021b76 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=82=B1=E5=BB=BA=E6=96=8C?= Date: Fri, 13 Jan 2012 16:19:34 +0800 Subject: [PATCH] wm8994: Add inverter to adapt --- drivers/mfd/wm8994-core.c | 6 +- sound/soc/codecs/wm8994.c | 8 ++- sound/soc/rk29/rk29_wm8994.c | 107 +++++++++++++++++++++++++++++++---- 3 files changed, 105 insertions(+), 16 deletions(-) diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index d64fd1ab14ac..1005847fbb14 100755 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c @@ -277,7 +277,8 @@ static int wm8994_suspend(struct device *dev) { struct wm8994 *wm8994 = dev_get_drvdata(dev); int ret; - + +// printk("on wm8994-core.c wm8994_suspend\n"); /* Don't actually go through with the suspend if the CODEC is * still active (eg, for audio passthrough from CP. */ ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_1); @@ -324,7 +325,8 @@ static int wm8994_resume(struct device *dev) { struct wm8994 *wm8994 = dev_get_drvdata(dev); int ret; - + +// printk("on wm8994-core.c wm8994_resume\n"); /* We may have lied to the PM core about suspending */ if (!wm8994->suspended) return 0; diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 20ffa09743d8..40a084b4e782 100755 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -1957,6 +1957,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, { struct wm8994 *control = codec->control_data; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); +// DBG("Enter %s::%s---%d\n",__FILE__,__FUNCTION__,__LINE__); switch (level) { case SND_SOC_BIAS_ON: @@ -1969,6 +1970,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: + printk("standby wm8994\n"); if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { pm_runtime_get_sync(codec->dev); @@ -2588,7 +2590,8 @@ static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state) struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994 *control = codec->control_data; int i, ret; - + +// printk("on wm8994.c wm8994_suspend\n"); switch (control->type) { case WM8994: snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0); @@ -2619,7 +2622,8 @@ static int wm8994_resume(struct snd_soc_codec *codec) struct wm8994 *control = codec->control_data; int i, ret; unsigned int val, mask; - + +// printk("on wm8994.c wm8994_resume\n"); if (wm8994->revision < 4) { /* force a HW read */ val = wm8994_reg_read(codec->control_data, diff --git a/sound/soc/rk29/rk29_wm8994.c b/sound/soc/rk29/rk29_wm8994.c index c5ededa5aa7e..e58dcff315ef 100755 --- a/sound/soc/rk29/rk29_wm8994.c +++ b/sound/soc/rk29/rk29_wm8994.c @@ -39,7 +39,10 @@ static int rk29_aif1_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; unsigned int pll_out = 0; + int div_bclk,div_mclk; int ret; + struct clk *general_pll; + DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); @@ -89,18 +92,65 @@ static int rk29_aif1_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - DBG("Enter:%s, %d, rate=%d,pll_out = %d\n",__FUNCTION__,__LINE__,params_rate(params),pll_out); +// DBG("Enter:%s, %d, rate=%d,pll_out = %d\n",__FUNCTION__,__LINE__,params_rate(params),pll_out); #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) + general_pll=clk_get(NULL, "general_pll"); + if(clk_get_rate(general_pll)>260000000) + { + div_bclk=(pll_out/4)/params_rate(params)-1; + div_mclk=3; + } + else if(clk_get_rate(general_pll)>130000000) + { + div_bclk=(pll_out/2)/params_rate(params)-1; + div_mclk=1; + } + else + {//96M + pll_out=pll_out/4; + div_bclk=(pll_out)/params_rate(params)-1; + div_mclk=0; + } + + DBG("func is%s,gpll=%ld,pll_out=%d,div_mclk=%d\n", + __FUNCTION__,clk_get_rate(general_pll),pll_out,div_mclk); + ret = snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0); if(ret < 0) { DBG("rk29_hw_params_wm8994:failed to set the cpu sysclk for codec side\n"); return ret; } - ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1, pll_out, 0); - if (ret < 0) { - DBG("rk29_hw_params_wm8994:failed to set the sysclk for codec side\n"); - return ret; + snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK,div_bclk); + snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, div_mclk); + DBG("Enter:%s, %d, LRCK=%d\n",__FUNCTION__,__LINE__,(pll_out/4)/params_rate(params)); + + if(div_mclk== 3) + {//MCLK == 11289600 or 12288000 + ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1, pll_out, 0); + if (ret < 0) { + DBG("rk29_hw_params_wm8994:failed to set the sysclk for codec side\n"); + return ret; + } + } + else + { + /* set the codec FLL */ + ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1, pll_out, + params_rate(params) * 256); + if (ret < 0) + { + printk("%s: snd_soc_dai_set_pll err =%d\n",__FUNCTION__,ret); + return ret; + } + /* set the codec system clock */ + ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, + params_rate(params) * 256, SND_SOC_CLOCK_IN); + if (ret < 0) + { + printk("%s: snd_soc_dai_set_sysclk err =%d\n",__FUNCTION__,ret); + return ret; + } } #elif defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) @@ -116,7 +166,10 @@ static int rk29_aif2_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; unsigned int pll_out = 0; - int ret = 0; + int div_bclk,div_mclk; + int ret; + struct clk *general_pll; + //change to 8Khz // params->intervals[SNDRV_PCM_HW_PARAM_RATE - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL].min = 8000; @@ -135,22 +188,53 @@ static int rk29_aif2_hw_params(struct snd_pcm_substream *substream, } switch(params_rate(params)) { case 8000: - case 44100: + case 16000: + case 24000: + case 32000: + case 48000: + pll_out = 12288000; + break; + case 11025: + case 22050: + case 44100: pll_out = 11289600; break; default: DBG("Enter:%s, %d, Error rate=%d\n",__FUNCTION__,__LINE__,params_rate(params)); return -EINVAL; - break; } + general_pll=clk_get(NULL, "general_pll"); + if(clk_get_rate(general_pll)>260000000) + { + div_bclk=(pll_out/4)/params_rate(params)-1; + div_mclk=3; + } + else if(clk_get_rate(general_pll)>130000000) + { + div_bclk=(pll_out/2)/params_rate(params)-1; + div_mclk=1; + } + else + {//96M + pll_out=pll_out/4; + div_bclk=(pll_out)/params_rate(params)-1; + div_mclk=0; + } + + DBG("func is%s,gpll=%ld,pll_out=%d,div_mclk=%d\n", + __FUNCTION__,clk_get_rate(general_pll),pll_out,div_mclk); + ret = snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0); if(ret < 0) { DBG("rk29_hw_params_wm8994:failed to set the cpu sysclk for codec side\n"); return ret; } - + snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK,div_bclk); + snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, div_mclk); + DBG("Enter:%s, %d, LRCK=%d\n",__FUNCTION__,__LINE__,(pll_out/4)/params_rate(params)); + /* set the codec FLL */ ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, WM8994_FLL_SRC_MCLK1, pll_out, 8000 * 256); @@ -167,7 +251,6 @@ static int rk29_aif2_hw_params(struct snd_pcm_substream *substream, printk("%s: snd_soc_dai_set_sysclk err =%d\n",__FUNCTION__,ret); return ret; } - return ret; } @@ -179,9 +262,9 @@ static int rk29_aif3_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; unsigned int pll_out = 0; - int div_bclk,div_mclk; +// int div_bclk,div_mclk; int ret; - struct clk *general_pll; +// struct clk *general_pll; DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__); -- 2.34.1