From 997c99f6f18847dff06b923aed51cba964702923 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=82=B1=E5=BB=BA=E6=96=8C?= Date: Mon, 9 Jan 2012 18:41:33 +0800 Subject: [PATCH] wm8994: fix bt_incall config --- sound/soc/codecs/wm8994.c | 320 +++++++++++++++++++++++++++++++---- sound/soc/codecs/wm_hubs.c | 4 +- sound/soc/rk29/rk29_wm8994.c | 107 +++++++----- 3 files changed, 348 insertions(+), 83 deletions(-) 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<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) -- 2.34.1