wm8994: Add inverter to adapt
author邱建斌 <qjb@rock-chips.com>
Fri, 13 Jan 2012 08:19:34 +0000 (16:19 +0800)
committer邱建斌 <qjb@rock-chips.com>
Fri, 13 Jan 2012 08:19:34 +0000 (16:19 +0800)
drivers/mfd/wm8994-core.c
sound/soc/codecs/wm8994.c
sound/soc/rk29/rk29_wm8994.c

index d64fd1ab14ace089ab05c98432b6c808f9153c43..1005847fbb14e9dd6eeae8ea8c42872fdfd9cae5 100755 (executable)
@@ -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;
index 20ffa09743d8ad278ecd032964432d7c48715797..40a084b4e782f1a0a0ac4464c189b6e078511705 100755 (executable)
@@ -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,
index c5ededa5aa7e49e07468a65d2647d418e242b8ba..e58dcff315ef57793dc68c0f647a3dfbe7c00feb 100755 (executable)
@@ -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__);