From: 邱建斌 <qjb@rock-chips.com>
Date: Mon, 9 Jan 2012 10:41:33 +0000 (+0800)
Subject: wm8994: fix bt_incall config
X-Git-Tag: firefly_0821_release~9682
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=997c99f6f18847dff06b923aed51cba964702923;p=firefly-linux-kernel-4.4.55.git

wm8994: fix bt_incall config
---

diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 662b01364d36..778f98a103f2 100755
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -54,6 +54,19 @@ char debug_write_read = 0;
 #define DBG(x...) do { } while (0)
 #endif
 
+#if 0
+#define DBG_CLK(x...) printk(KERN_INFO x)
+#else
+#define DBG_CLK(x...) do { } while (0)
+#endif
+
+#if 0
+#define DBG_INFO(x...) dev_info(x)
+#else
+#define DBG_INFO(x...) do { } while (0)
+#endif
+
+
 #define WM8994_NUM_DRC 3
 #define WM8994_NUM_EQ  3
 
@@ -135,6 +148,8 @@ static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
 	unsigned int value)
 {
 	int ret;
+	if(reg == 0x3 || reg == 0x208)
+		debug_write_read = 1;
 
 	BUG_ON(reg > WM8994_MAX_REGISTER);
 #ifdef WM8994_PROC		
@@ -152,6 +167,8 @@ static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
 			DBG("snd_soc_cache_write:0x%04x = 0x%04x\n",reg,value);
 #endif	
 	}
+	if(reg == 0x3 || reg == 0x208)
+		debug_write_read = 0;
 
 	return wm8994_reg_write(codec->control_data, reg, value);
 }
@@ -227,13 +244,13 @@ static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
 		rate /= 2;
 		reg1 |= WM8994_AIF1CLK_DIV;
 
-		dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n",
+		DBG_INFO(codec->dev, "Dividing AIF%d clock to %dHz\n",
 			aif + 1, rate);
 	}
 
 	if (rate && rate < 3000000)
-		dev_warn(codec->dev, "AIF%dCLK is %dHz, should be >=3MHz for optimal performance\n",
-			 aif + 1, rate);
+		DBG_INFO(codec->dev, "AIF%dCLK is %dHz, should be >=3MHz for optimal performance\n",
+			 aif + 1, rate);//dev_warn
 
 	wm8994->aifclk[aif] = rate;
 
@@ -267,7 +284,7 @@ static int configure_clock(struct snd_soc_codec *codec)
 		new = WM8994_SYSCLK_SRC;
 	else
 		new = 0;
-
+	
 	old = snd_soc_read(codec, WM8994_CLOCKING_1) & WM8994_SYSCLK_SRC;
 
 	/* If there's no change then we're done. */
@@ -708,7 +725,8 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
 			 struct snd_kcontrol *kcontrol, int event)
 {
 	struct snd_soc_codec *codec = w->codec;
-
+//	DBG("%s::%d\n",__FUNCTION__,__LINE__);
+	
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		return configure_clock(codec);
@@ -789,6 +807,7 @@ static int late_enable_ev(struct snd_soc_dapm_widget *w,
 {
 	struct snd_soc_codec *codec = w->codec;
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+//	DBG("%s::%d\n",__FUNCTION__,__LINE__);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
@@ -803,6 +822,13 @@ static int late_enable_ev(struct snd_soc_dapm_widget *w,
 					    WM8994_AIF2CLK_ENA_MASK,
 					    WM8994_AIF2CLK_ENA);
 			wm8994->aif2clk_enable = 0;
+			//add
+			snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3,
+				0x30a0,
+				0x30a0);
+			snd_soc_update_bits(codec, WM8994_CLOCKING_1,
+					    WM8994_SYSCLK_SRC,
+					    WM8994_SYSCLK_SRC);			
 		}
 		break;
 	}
@@ -847,12 +873,12 @@ static int wm8994_PA_event(struct snd_soc_dapm_widget *w,
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		DBG("PA enable\n");
+		DBG("wm8994_PA_event PA enable\n");
 		gpio_set_value(pdata->PA_control_pin,GPIO_HIGH);	
 		break;
 
 	case SND_SOC_DAPM_PRE_PMD:
-		DBG("PA disable\n");
+		DBG("wm8994_PA_event PA disable\n");
 		gpio_set_value(pdata->PA_control_pin,GPIO_LOW);
 		break;
 
@@ -1318,7 +1344,7 @@ SND_SOC_DAPM_AIF_IN_E("AIF2DACL", NULL, 0,
 SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0,
 		      WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev,
 		      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
-
+     
 SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
 SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
 SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
@@ -1519,14 +1545,16 @@ static const struct snd_soc_dapm_route intercon[] = {
 	{ "AIF2ADCDAT", NULL, "AIF2ADC Mux" },
 
 	/* AIF3 output */
-	{ "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC1L" },
-	{ "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC1R" },
-	{ "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC2L" },
-	{ "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC2R" },
-	{ "AIF3ADCDAT", "AIF2ADCDAT", "AIF2ADCL" },
-	{ "AIF3ADCDAT", "AIF2ADCDAT", "AIF2ADCR" },
-	{ "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACL" },
-	{ "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACR" },
+	{ "AIF3ADC Mux", "AIF1ADCDAT", "AIF1ADC1L" },
+	{ "AIF3ADC Mux", "AIF1ADCDAT", "AIF1ADC1R" },
+	{ "AIF3ADC Mux", "AIF1ADCDAT", "AIF1ADC2L" },
+	{ "AIF3ADC Mux", "AIF1ADCDAT", "AIF1ADC2R" },
+	{ "AIF3ADC Mux", "AIF2ADCDAT", "AIF2ADCL" },
+	{ "AIF3ADC Mux", "AIF2ADCDAT", "AIF2ADCR" },
+	{ "AIF3ADC Mux", "AIF2DACDAT", "AIF2DACL" },
+	{ "AIF3ADC Mux", "AIF2DACDAT", "AIF2DACR" },
+	
+	{ "AIF3ADCDAT", NULL, "AIF3ADC Mux" },
 
 	/* Sidetone */
 	{ "Left Sidetone", "ADC/DMIC1", "ADCL Mux" },
@@ -1728,6 +1756,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
 		id = 1;
 		break;
 	default:
+		printk("%s:__ id = %d\n",__FUNCTION__,id);
 		return -EINVAL;
 	}
 
@@ -1735,7 +1764,10 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
 	case 0:
 		/* Allow no source specification when stopping */
 		if (freq_out)
+		{
+			printk("%s:__ src = %d && freq_out = %d\n",__FUNCTION__,src,freq_out);	
 			return -EINVAL;
+		}	
 		src = wm8994->fll[id].src;
 		break;
 	case WM8994_FLL_SRC_MCLK1:
@@ -1744,6 +1776,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
 	case WM8994_FLL_SRC_BCLK:
 		break;
 	default:
+		printk("%s:__ src = %d\n",__FUNCTION__,src);
 		return -EINVAL;
 	}
 
@@ -1850,7 +1883,7 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
 	case WM8994_SYSCLK_MCLK1:
 		wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK1;
 		wm8994->mclk[0] = freq;
-		dev_dbg(dai->dev, "AIF%d using MCLK1 at %uHz\n",
+		DBG_INFO(dai->dev, "AIF%d using MCLK1 at %uHz\n",
 			dai->id, freq);
 		break;
 
@@ -1858,18 +1891,18 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
 		/* TODO: Set GPIO AF */
 		wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK2;
 		wm8994->mclk[1] = freq;
-		dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n",
+		DBG_INFO(dai->dev, "AIF%d using MCLK2 at %uHz\n",
 			dai->id, freq);
 		break;
 
 	case WM8994_SYSCLK_FLL1:
 		wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL1;
-		dev_dbg(dai->dev, "AIF%d using FLL1\n", dai->id);
+		DBG_INFO(dai->dev, "AIF%d using FLL1\n", dai->id);
 		break;
 
 	case WM8994_SYSCLK_FLL2:
 		wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL2;
-		dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id);
+		DBG_INFO(dai->dev, "AIF%d using FLL2\n", dai->id);
 		break;
 
 	case WM8994_SYSCLK_OPCLK:
@@ -2161,6 +2194,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
 	struct snd_soc_codec *codec = dai->codec;
 	struct wm8994 *control = codec->control_data;
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+	int rate = params_rate(params);
 	int aif1_reg;
 	int aif2_reg;
 	int bclk_reg;
@@ -2188,6 +2222,10 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
 			lrclk_reg = WM8994_AIF1ADC_LRCLK;
 			dev_dbg(codec->dev, "AIF1 using split LRCLK\n");
 		}
+		//add		
+		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
+				WM8994_AIF2DACL_ENA_MASK | WM8994_AIF2DACR_ENA_MASK,
+				0);		
 		break;
 	case 2:
 		aif1_reg = WM8994_AIF2_CONTROL_1;
@@ -2201,6 +2239,23 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
 			lrclk_reg = WM8994_AIF2ADC_LRCLK;
 			dev_dbg(codec->dev, "AIF2 using split LRCLK\n");
 		}
+		//add
+		rate = 8000;
+	//	wm8994_set_bias_level(codec,SND_SOC_BIAS_PREPARE);
+	//	snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_2,
+	//			WM8994_IN2R_ENA | WM8994_IN2L_ENA | WM8994_MIXINR_ENA | WM8994_MIXINL_ENA,
+	//			WM8994_IN2R_ENA| WM8994_IN2L_ENA| WM8994_MIXINR_ENA | WM8994_MIXINL_ENA);	
+	//	snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3,
+	//			0x30a0,
+	//			0x30a0);
+	//	snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
+	//			0x3303,
+	//			0x3303);
+		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
+				WM8994_AIF2DACL_ENA_MASK | WM8994_AIF2DACR_ENA_MASK,
+				1 << WM8994_AIF2DACL_ENA_SHIFT| 1<<WM8994_AIF2DACR_ENA_SHIFT);
+		
+
 		break;
 	case 3:
 		switch (control->type) {
@@ -2214,7 +2269,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	bclk_rate = params_rate(params) * 2;
+	bclk_rate = rate * 4;
 	switch (params_format(params)) {
 	case SNDRV_PCM_FORMAT_S16_LE:
 		bclk_rate *= 16;
@@ -2237,14 +2292,14 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
 
 	/* Try to find an appropriate sample rate; look for an exact match. */
 	for (i = 0; i < ARRAY_SIZE(srs); i++)
-		if (srs[i].rate == params_rate(params))
+		if (srs[i].rate == rate)
 			break;
 	if (i == ARRAY_SIZE(srs))
 		return -EINVAL;
 	rate_val |= srs[i].val << WM8994_AIF1_SR_SHIFT;
 
-	dev_dbg(dai->dev, "Sample rate is %dHz\n", srs[i].rate);
-	dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n",
+	DBG_INFO(dai->dev, "Sample rate is %dHz\n", srs[i].rate);
+	DBG_INFO(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n",
 		dai->id, wm8994->aifclk[id], bclk_rate);
 
 	if (params_channels(params) == 1 &&
@@ -2258,17 +2313,17 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
 
 	/* AIFCLK/fs ratio; look for a close match in either direction */
 	best = 0;
-	best_val = abs((fs_ratios[0] * params_rate(params))
+	best_val = abs((fs_ratios[0] * rate)
 		       - wm8994->aifclk[id]);
 	for (i = 1; i < ARRAY_SIZE(fs_ratios); i++) {
-		cur_val = abs((fs_ratios[i] * params_rate(params))
+		cur_val = abs((fs_ratios[i] * rate)
 			      - wm8994->aifclk[id]);
 		if (cur_val >= best_val)
 			continue;
 		best = i;
 		best_val = cur_val;
 	}
-	dev_dbg(dai->dev, "Selected AIF%dCLK/fs = %d\n",
+	DBG_INFO(dai->dev, "Selected AIF%dCLK/fs = %d\n",
 		dai->id, fs_ratios[best]);
 	rate_val |= best;
 
@@ -2285,12 +2340,12 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
 		best = i;
 	}
 	bclk_rate = wm8994->aifclk[id] * 10 / bclk_divs[best];
-	dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
+	DBG_INFO(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
 		bclk_divs[best], bclk_rate);
 	bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT;
 
-	lrclk = bclk_rate / params_rate(params);
-	dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
+	lrclk = bclk_rate / rate;
+	DBG_INFO(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
 		lrclk, bclk_rate / lrclk);
 
 	snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
@@ -2304,12 +2359,12 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		switch (dai->id) {
 		case 1:
-			wm8994->dac_rates[0] = params_rate(params);
+			wm8994->dac_rates[0] = rate;
 			wm8994_set_retune_mobile(codec, 0);
 			wm8994_set_retune_mobile(codec, 1);
 			break;
 		case 2:
-			wm8994->dac_rates[1] = params_rate(params);
+			wm8994->dac_rates[1] = rate;
 			wm8994_set_retune_mobile(codec, 2);
 			break;
 		}
@@ -3217,6 +3272,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 					ARRAY_SIZE(wm8994_intercon));
 
 		if (wm8994->revision < 4) {
+			printk("wm8994->revision = %d\n",wm8994->revision);
 			snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon,
 						ARRAY_SIZE(wm8994_revd_intercon));
 			snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon,
@@ -3245,7 +3301,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 	
 	if(pdata ->PA_control_pin)
 	{
-		dev_info(codec->dev,"Add the PA control route\n");
+		DBG_INFO(codec->dev,"Add the PA control route\n");
 		snd_soc_dapm_new_controls(dapm, wm8994_PA_dapm_widgets,
 				  ARRAY_SIZE(wm8994_PA_dapm_widgets));	
 		snd_soc_dapm_add_routes(dapm, wm8994_PA_intercon, 
@@ -3256,7 +3312,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 		gpio_direction_output(pdata->PA_control_pin,GPIO_LOW);
 	}
 	else
-		dev_warn(codec->dev, "have not pa control\n");
+		dev_info(codec->dev, "have not pa control\n");	
 	
 	return 0;
 
@@ -3372,6 +3428,188 @@ MODULE_ALIAS("platform:wm8994-codec");
 //=====================================================================
 //Proc
 #ifdef WM8994_PROC
+void BT_BB(void)
+{//
+	DBG("%s::%d\n",__FUNCTION__,__LINE__);
+#if 0
+//	wm8994_reg_write(wm8994_codec->control_data,0x0,  0x0);
+	msleep(50);
+
+	wm8994_reg_write(wm8994_codec->control_data,0x01,  0x0023);
+	wm8994_reg_write(wm8994_codec->control_data,0x200, 0x0000);
+	msleep(50);
+//CLK
+	//AIF2CLK use FLL2
+    //BT CLK = 8000
+    //8KHz, BCLK=8KHz*64=512KHz, Fout=2.048MHz
+    
+	wm8994_reg_write(wm8994_codec->control_data,0x241, 0x2b00);
+	wm8994_reg_write(wm8994_codec->control_data,0x242, 0xfb5b);
+	wm8994_reg_write(wm8994_codec->control_data,0x243, 0x00e0);
+	wm8994_reg_write(wm8994_codec->control_data,0x240, 0x0005);    //FLL2_ENA = 1  \u8fd9\u8fb9\u5f97\u5230\u7684FLL CLK\u5e94\u8be5=2.048M
+
+	wm8994_reg_write(wm8994_codec->control_data,0x204, 0x0018);    // AIF2CLK_SRC=10 use FLL2 AIF2CLK_ENA=0
+	wm8994_reg_write(wm8994_codec->control_data,0x208, 0x000F);    // DSP_FS1CLK_ENA = 1 DSP_FS2CLK_ENA = 1 DSP_FSINTCLK_ENA =1 SYSCLK_SRC=AIF1CLK
+	wm8994_reg_write(wm8994_codec->control_data,0x211, 0x0003);    // AIF2_SR[3:0]=0 8k   AIF2CLK_RATE [3:0]=3 256\u5206\u9891    Fout = 8000 * 256 = 2.048MHz
+
+	wm8994_reg_write(wm8994_codec->control_data,0x312, 0x3000);    // AIF2 Master/Slave(312H): 7000  AIF2_TRI=0, AIF2_MSTR=1, AIF2_CLK_FRC=0, AIF2_LRCLK_FRC=0
+	msleep(30);
+	wm8994_reg_write(wm8994_codec->control_data,0x312, 0x7000);
+	wm8994_reg_write(wm8994_codec->control_data,0x313, 0x0020);    // AIF2 BCLK DIV--------AIF1CLK/2
+	wm8994_reg_write(wm8994_codec->control_data,0x314, 0x0080);    // AIF2 ADCLRCK DIV-----BCLK/128
+	wm8994_reg_write(wm8994_codec->control_data,0x315, 0x0080);
+	wm8994_reg_write(wm8994_codec->control_data,0x310, 0x0118);    // DSP/PCM; 16bits; ADC L channel = R channel;MODE A
+
+	wm8994_reg_write(wm8994_codec->control_data,0x204, 0x0019);    // AIF2CLK_SRC=10 use FLL2 AIF2CLK_ENA=1
+	
+//GPIO
+	wm8994_reg_write(wm8994_codec->control_data,0x702, 0x2100);//BCLK2
+	wm8994_reg_write(wm8994_codec->control_data,0x703, 0x2100);//DACLRCLK2
+	wm8994_reg_write(wm8994_codec->control_data,0x704, 0xA100);//DACDAT2
+	wm8994_reg_write(wm8994_codec->control_data,0x707, 0xA100);//DACDAT3
+	wm8994_reg_write(wm8994_codec->control_data,0x708, 0x2100);//ADCDAT3
+	wm8994_reg_write(wm8994_codec->control_data,0x709, 0x2100);//LRCLK3
+	wm8994_reg_write(wm8994_codec->control_data,0x70A, 0x2100);//BCLK3
+	wm8994_reg_write(wm8994_codec->control_data,0x06,  0x000A);
+//1010  bit_0 AIF1DACDAT=DACDAT1 bit_1 AIF2DACDAT=GPIO8/DACDAT3 bit_2 GPIO7/ADCDAT2=AIF2ADCDAT2 bit_3 GPIO9/ADCDAT3=AIF2ADCDAT2
+//path
+	
+    //listen   IN2RP/IN2LP to MIXIN to ADC to DAC2 to AIF2
+	wm8994_reg_write(wm8994_codec->control_data,0x28,   0x00C0);   //IN2LP_TO_IN2L IN2LN_TO_IN2L
+	wm8994_reg_write(wm8994_codec->control_data,0x29,   0x0100);   //IN2L_TO_MIXINL   BB
+	wm8994_reg_write(wm8994_codec->control_data,0x2A,   0x0100);   //IN2R_TO_MIXINR
+	wm8994_reg_write(wm8994_codec->control_data,0x604,  0x0010);   //ADC1_TO_DAC2L
+	wm8994_reg_write(wm8994_codec->control_data,0x605,  0x0010);   //ADC1_TO_DAC2R
+//	wm8994_reg_write(wm8994_codec->control_data,0x29,   0x0130);//IN1L_TO_MIXINL   MIC
+//	wm8994_reg_write(wm8994_codec->control_data,0x2A,   0x0130);//IN1R_TO_MIXINR
+    //say   AIF2DACL to DACL to MIXOUTL to LINEOUT
+    //\u6309\u952e\u97f3 AIF1ADCR to DACR to MIXOUTR to SPKMIXR
+	wm8994_reg_write(wm8994_codec->control_data,0x601,  0x0004);   //AIF2DACL_TO_DAC1L
+	wm8994_reg_write(wm8994_codec->control_data,0x602,  0x0001);   //AIF1DAC1R_TO_DAC1R
+	wm8994_reg_write(wm8994_codec->control_data,0x2D,   0x0001);   //DAC1L_TO_MIXOUTL
+	wm8994_reg_write(wm8994_codec->control_data,0x2E,   0x0001);   //DAC1R_TO_MIXOUTR
+	wm8994_reg_write(wm8994_codec->control_data,0x34,   0x0001);   //MIXOUTL_TO_LINEOUT1P
+	wm8994_reg_write(wm8994_codec->control_data,0x36,   0x0004);   //MIXOUTR_TO_SPKMIXR
+	wm8994_reg_write(wm8994_codec->control_data,0x24,   0x0009);   //SPKMIXR_TO_SPKOUTL   SPKMIXR_TO_SPKOUTR
+	
+//volume
+	wm8994_reg_write(wm8994_codec->control_data,0x19,   0x011F);   // IN2L volume
+	wm8994_reg_write(wm8994_codec->control_data,0x20,   0x017F);   // MIXOUTL volume
+	wm8994_reg_write(wm8994_codec->control_data,0x0500, 0x017F);   // AIF2 ADC Left Volume
+	wm8994_reg_write(wm8994_codec->control_data,0x0501, 0x0100);   // AIF2 ADC Right Volume mute
+	wm8994_reg_write(wm8994_codec->control_data,0x1E,   0x0006);   //LINEOUT2N_MUTE=UN-MUTE  LINEOUT2P_MUTE=UN-MUTE
+
+	wm8994_reg_write(wm8994_codec->control_data,0x22,   0x0000);
+	wm8994_reg_write(wm8994_codec->control_data,0x23,   0x0100);
+	wm8994_reg_write(wm8994_codec->control_data,0x610, 0x01C0);//DAC1L
+	wm8994_reg_write(wm8994_codec->control_data,0x611, 0x01C0);//DAC1R
+	wm8994_reg_write(wm8994_codec->control_data,0x612, 0x01C0);//DAC2L
+	wm8994_reg_write(wm8994_codec->control_data,0x613, 0x01C0);//DAC2R
+
+	wm8994_reg_write(wm8994_codec->control_data,0x603, 0x000C);//ADC1_DAC2_VOL[3:0] 1100 0DB
+	wm8994_reg_write(wm8994_codec->control_data,0x620, 0x0000);
+	wm8994_reg_write(wm8994_codec->control_data,0x420, 0x0000);
+//other
+	wm8994_reg_write(wm8994_codec->control_data,0x4C,   0x9F25);
+	wm8994_reg_write(wm8994_codec->control_data,0x60,   0x00EE);
+	msleep(5);
+//power
+	wm8994_reg_write(wm8994_codec->control_data,0x01,   0x3033);
+	wm8994_reg_write(wm8994_codec->control_data,0x02,   0x63A0);
+	wm8994_reg_write(wm8994_codec->control_data,0x03,   0x33F0);
+	wm8994_reg_write(wm8994_codec->control_data,0x04,   0x3303);
+	wm8994_reg_write(wm8994_codec->control_data,0x05,   0x3303);
+#endif	
+//	wm8994_write(wm8994_codec,0x0,  0x0);
+//	msleep(50);
+
+//	wm8994_write(wm8994_codec,0x01,  0x0023);
+//	wm8994_write(wm8994_codec,0x200, 0x0000);
+//	msleep(50);
+//CLK
+	//AIF2CLK use FLL2
+    //BT CLK = 8000
+    //8KHz, BCLK=8KHz*64=512KHz, Fout=2.048MHz
+    
+//	wm8994_write(wm8994_codec,0x241, 0x2b00);
+//	wm8994_write(wm8994_codec,0x242, 0xfb5b);
+//	wm8994_write(wm8994_codec,0x243, 0x00e0);
+//	wm8994_write(wm8994_codec,0x240, 0x0005);    //FLL2_ENA = 1  \u8fd9\u8fb9\u5f97\u5230\u7684FLL CLK\u5e94\u8be5=2.048M
+
+//	wm8994_write(wm8994_codec,0x204, 0x0018);    // AIF2CLK_SRC=10 use FLL2 AIF2CLK_ENA=0
+//	wm8994_write(wm8994_codec,0x208, 0x000F);    // DSP_FS1CLK_ENA = 1 DSP_FS2CLK_ENA = 1 DSP_FSINTCLK_ENA =1 SYSCLK_SRC=AIF1CLK
+//	wm8994_write(wm8994_codec,0x211, 0x0003);    // AIF2_SR[3:0]=0 8k   AIF2CLK_RATE [3:0]=3 256\u5206\u9891    Fout = 8000 * 256 = 2.048MHz
+
+//	wm8994_write(wm8994_codec,0x312, 0x3000);    // AIF2 Master/Slave(312H): 7000  AIF2_TRI=0, AIF2_MSTR=1, AIF2_CLK_FRC=0, AIF2_LRCLK_FRC=0
+//	msleep(30);
+//	wm8994_write(wm8994_codec,0x312, 0x7000);
+//	wm8994_write(wm8994_codec,0x313, 0x0020);    // AIF2 BCLK DIV--------AIF1CLK/2
+//	wm8994_write(wm8994_codec,0x314, 0x0080);    // AIF2 ADCLRCK DIV-----BCLK/128
+//	wm8994_write(wm8994_codec,0x315, 0x0080);
+//	wm8994_write(wm8994_codec,0x310, 0x0118);    // DSP/PCM; 16bits; ADC L channel = R channel;MODE A
+
+//	wm8994_write(wm8994_codec,0x204, 0x0019);    // AIF2CLK_SRC=10 use FLL2 AIF2CLK_ENA=1
+	
+//GPIO
+//	wm8994_write(wm8994_codec,0x702, 0x2100);//BCLK2
+//	wm8994_write(wm8994_codec,0x703, 0x2100);//DACLRCLK2
+//	wm8994_write(wm8994_codec,0x704, 0xA100);//DACDAT2
+//	wm8994_write(wm8994_codec,0x707, 0xA100);//DACDAT3
+//	wm8994_write(wm8994_codec,0x708, 0x2100);//ADCDAT3
+//	wm8994_write(wm8994_codec,0x709, 0x2100);//LRCLK3
+//	wm8994_write(wm8994_codec,0x70A, 0x2100);//BCLK3
+//	wm8994_write(wm8994_codec,0x06,  0x000A);
+//1010  bit_0 AIF1DACDAT=DACDAT1 bit_1 AIF2DACDAT=GPIO8/DACDAT3 bit_2 GPIO7/ADCDAT2=AIF2ADCDAT2 bit_3 GPIO9/ADCDAT3=AIF2ADCDAT2
+//path
+	
+    //listen   IN2RP/IN2LP to MIXIN to ADC to DAC2 to AIF2
+	wm8994_write(wm8994_codec,0x28,   0x00C0);   //IN2LP_TO_IN2L IN2LN_TO_IN2L
+	wm8994_write(wm8994_codec,0x29,   0x0100);   //IN2L_TO_MIXINL   BB
+	wm8994_write(wm8994_codec,0x2A,   0x0100);   //IN2R_TO_MIXINR
+	wm8994_write(wm8994_codec,0x604,  0x0010);   //ADC1_TO_DAC2L
+	wm8994_write(wm8994_codec,0x605,  0x0010);   //ADC1_TO_DAC2R
+//	wm8994_reg_write(wm8994_codec->control_data,0x29,   0x0130);//IN1L_TO_MIXINL   MIC
+//	wm8994_reg_write(wm8994_codec->control_data,0x2A,   0x0130);//IN1R_TO_MIXINR
+    //say   AIF2DACL to DACL to MIXOUTL to LINEOUT
+    //\u6309\u952e\u97f3 AIF1ADCR to DACR to MIXOUTR to SPKMIXR
+	wm8994_write(wm8994_codec,0x601,  0x0004);   //AIF2DACL_TO_DAC1L
+//	wm8994_write(wm8994_codec,0x602,  0x0001);   //AIF1DAC1R_TO_DAC1R
+	wm8994_write(wm8994_codec,0x2D,   0x0001);   //DAC1L_TO_MIXOUTL
+//	wm8994_write(wm8994_codec,0x2E,   0x0001);   //DAC1R_TO_MIXOUTR
+	wm8994_write(wm8994_codec,0x34,   0x0001);   //MIXOUTL_TO_LINEOUT1P
+//	wm8994_write(wm8994_codec,0x36,   0x0004);   //MIXOUTR_TO_SPKMIXR
+	wm8994_write(wm8994_codec,0x24,   0x0009);   //SPKMIXR_TO_SPKOUTL   SPKMIXR_TO_SPKOUTR
+	/*
+//volume
+	wm8994_write(wm8994_codec,0x19,   0x011F);   // IN2L volume
+	wm8994_write(wm8994_codec,0x20,   0x017F);   // MIXOUTL volume
+	wm8994_write(wm8994_codec,0x0500, 0x017F);   // AIF2 ADC Left Volume
+	wm8994_write(wm8994_codec,0x0501, 0x0100);   // AIF2 ADC Right Volume mute
+	wm8994_write(wm8994_codec,0x1E,   0x0006);   //LINEOUT2N_MUTE=UN-MUTE  LINEOUT2P_MUTE=UN-MUTE
+
+	wm8994_write(wm8994_codec,0x22,   0x0000);
+	wm8994_write(wm8994_codec,0x23,   0x0100);
+	wm8994_write(wm8994_codec,0x610, 0x01C0);//DAC1L
+	wm8994_write(wm8994_codec,0x611, 0x01C0);//DAC1R
+	wm8994_write(wm8994_codec,0x612, 0x01C0);//DAC2L
+	wm8994_write(wm8994_codec,0x613, 0x01C0);//DAC2R
+
+	wm8994_write(wm8994_codec,0x603, 0x000C);//ADC1_DAC2_VOL[3:0] 1100 0DB
+	wm8994_write(wm8994_codec,0x620, 0x0000);
+	wm8994_write(wm8994_codec,0x420, 0x0000);*/
+//other
+//	wm8994_write(wm8994_codec,0x4C,   0x9F25);
+//	wm8994_write(wm8994_codec,0x60,   0x00EE);
+//	msleep(5);
+//power
+//	wm8994_write(wm8994_codec,0x01,   0x0003);
+//	wm8994_write(wm8994_codec,0x02,   0x63A0);
+//	wm8994_write(wm8994_codec,0x03,   0x30a0);
+//	wm8994_write(wm8994_codec,0x04,   0x3303);
+//	wm8994_write(wm8994_codec,0x05,   0x3003);
+
+}
+
 static ssize_t wm8994_proc_write(struct file *file, const char __user *buffer,
 			   unsigned long len, void *data)
 {
@@ -3453,6 +3691,20 @@ static ssize_t wm8994_proc_write(struct file *file, const char __user *buffer,
 		gpio_direction_output(RK29_PIN6_PD3,GPIO_HIGH); 			
 		gpio_free(RK29_PIN6_PD3);
 		break;
+
+	case 'a':
+		printk("Dump reg \n");		
+
+		for(reg = 0; reg < 0x621; reg++)
+		{
+			value = wm8994_reg_read(wm8994_codec->control_data,reg);
+			printk("wm8994_read:0x%04x = 0x%04x\n",reg,value);
+		}
+
+		break;		
+	case 'b':
+		BT_BB();
+		break;
 	default:
 		printk("Help for wm8994_ts .\n-->The Cmd list: \n");
 		printk("-->'d&&D' Open or Off the debug\n");
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 06c72f8fc7d8..aef36262cf44 100755
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -76,10 +76,10 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
 
 	do {
 		count++;
-		msleep(1);
+		msleep(100);
 		reg = snd_soc_read(codec, WM8993_DC_SERVO_0);
 		dev_dbg(codec->dev, "DC servo: %x\n", reg);
-	} while (reg & op && count < 400);
+	} while (reg & op && count < 4);
 
 	if (reg & op)
 		dev_err(codec->dev, "Timed out waiting for DC Servo %x\n",
diff --git a/sound/soc/rk29/rk29_wm8994.c b/sound/soc/rk29/rk29_wm8994.c
index f5da0f052302..c5ededa5aa7e 100755
--- a/sound/soc/rk29/rk29_wm8994.c
+++ b/sound/soc/rk29/rk29_wm8994.c
@@ -32,9 +32,6 @@
 #define	DBG(x...)
 #endif
 
-#define HW_PARAMS_FLAG_EQVOL_ON 0x21
-#define HW_PARAMS_FLAG_EQVOL_OFF 0x22
-
 static int rk29_aif1_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params)
 {
@@ -119,37 +116,26 @@ 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 div_bclk,div_mclk;
-	int ret;
-	struct clk	*general_pll;
+	int ret = 0;
+	//change to 8Khz
+//	params->intervals[SNDRV_PCM_HW_PARAM_RATE - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL].min = 8000;	
 
-	DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
+	DBG("Enter:%s, %d, rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
+	
+//	if (params_rate(params) != 8000)
+//		return -EINVAL;
 
 	/* set codec DAI configuration */
-#if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) 
-	DBG("Set codec_dai slave\n");
-	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
-	 	SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
-#endif	
-#if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) 			   
-	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
-		SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
-	DBG("Set codec_dai master\n");
-#endif
+	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A |
+			SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBM_CFM);
 	if (ret < 0)
-		return ret; 
-
+	{
+		printk("%s: snd_soc_dai_set_fmt err =%d\n",__FUNCTION__,ret);
+		return ret;
+	}
 	switch(params_rate(params)) {
 		case 8000:
-		case 16000:
-		case 24000:
-		case 32000:
-		case 48000:
-			pll_out = 12288000;
-			break;
-		case 11025:
-		case 22050:
-		case 44100:
+		case 44100:		
 			pll_out = 11289600;
 			break;
 		default:
@@ -157,23 +143,33 @@ static int rk29_aif2_hw_params(struct snd_pcm_substream *substream,
 			return -EINVAL;
 			break;
 	}
-
-	DBG("Enter:%s, %d, rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
-
-	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"); 
+	
+	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;
 	}
+	
+	/* set the codec FLL */
+	ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, WM8994_FLL_SRC_MCLK1, pll_out,
+			8000 * 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_FLL2,
+			8000 * 256, SND_SOC_CLOCK_IN);
+	if (ret < 0)
+	{
+		printk("%s: snd_soc_dai_set_sysclk err =%d\n",__FUNCTION__,ret);
+		return ret;
+	}
+	
 
-	snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
-
-#if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE)
-	snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK, (pll_out/4)/params_rate(params)-1);
-	snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, 3);
-#endif
-
-	return 0;
+	return ret;
 }
 
 static int rk29_aif3_hw_params(struct snd_pcm_substream *substream,
@@ -265,6 +261,21 @@ static struct snd_soc_ops rk29_aif3_ops = {
 	  .hw_params = rk29_aif3_hw_params,
 };
 
+static struct snd_soc_dai_driver voice_dai = {
+	.name = "rk29-voice-dai",
+	.id = 0,
+	.playback = {
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
+	.capture = {
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
+};
+
 static struct snd_soc_dai_link rk29_dai[] = {
 	{
 		.name = "WM8994 I2S1",
@@ -285,13 +296,14 @@ static struct snd_soc_dai_link rk29_dai[] = {
 		.codec_name = "wm8994-codec",
 		.platform_name = "rockchip-audio",
 #if defined(CONFIG_SND_RK29_SOC_I2S_8CH)	
-        	.cpu_dai_name = "rk29_i2s.0",
+        .cpu_dai_name = "rk29_i2s.0",
 #elif defined(CONFIG_SND_RK29_SOC_I2S_2CH)
 		.cpu_dai_name = "rk29_i2s.1",
 #endif
 		.codec_dai_name = "wm8994-aif2",
 		.ops = &rk29_aif2_ops,
 	},
+	
 	{
 		.name = "WM8994 I2S3",
 		.stream_name = "WM8994 PCM",
@@ -305,6 +317,7 @@ static struct snd_soc_dai_link rk29_dai[] = {
 		.codec_dai_name = "wm8994-aif3",
 		.ops = &rk29_aif3_ops,
 	},
+
 };
 
 static struct snd_soc_card snd_soc_card_rk29 = {
@@ -326,17 +339,17 @@ static int __init audio_card_init(void)
 		  printk("platform device allocation failed\n");
 		  return -ENOMEM;
 	}
-
+	
 	platform_set_drvdata(rk29_snd_device, &snd_soc_card_rk29);
 	ret = platform_device_add(rk29_snd_device);
 	if (ret) {
 		printk("platform device add failed\n");
-
+	//	snd_soc_unregister_dai(&rk29_snd_device->dev);
 		platform_device_put(rk29_snd_device);
 		return ret;
 	}
-		
-        return ret;
+	
+	return ret;		
 }
 
 static void __exit audio_card_exit(void)