ASoC: rt3261: initial micbais.
[firefly-linux-kernel-4.4.55.git] / sound / soc / codecs / rt3261.c
old mode 100644 (file)
new mode 100755 (executable)
index 393cf39..1541f31
@@ -17,6 +17,8 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
+#include <linux/of_gpio.h>
+#include <linux/clk.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc-dapm.h>
 #include <sound/initval.h>
 #include <sound/tlv.h>
-#include <mach/board.h>
-#include <linux/clk.h>
-#include <mach/iomux.h>
-
-#define RT3261_PROC
-#ifdef RT3261_PROC
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/vmalloc.h>
-#endif
 
 //#define USE_INT_CLK
+#define DIFFERENTIAL 1
+#define SINGLE_END 0
+#define TWO_SPK 2
+#define ONE_SPK 1
+
+enum {
+       SPK_AMPLIFY_ZERO_POINT_FIVE_WATT=1,
+       SPK_AMPLIFY_ZERO_POINT_SIX_WATT,
+       SPK_AMPLIFY_ZERO_POINT_EIGHT_WATT,
+       SPK_AMPLIFY_ONE_WATT,
+};
+
+enum {
+       LR_NORMAL,
+       LR_SWAP,
+       LEFT_COPY_TO_RIGHT,
+       RIGHT_COPY_LEFT,
+};
 
 static struct snd_soc_codec *rt3261_codec;
 
 #if 0
-#define DBG(x...)      printk(KERN_INFO x)
+#define DBG(x...)      printk(KERN_DEBUG x)
 #else
 #define DBG(x...)
 #endif
 
-//#define RTK_IOCTL
+#define RTK_IOCTL
 #ifdef RTK_IOCTL
 #if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE)
 #include "rt_codec_ioctl.h"
@@ -61,7 +71,7 @@ static struct snd_soc_codec *rt3261_codec;
 #define RT3261_REG_RW 1 /* for debug */
 #define RT3261_DET_EXT_MIC 0
 
-#define VERSION "RT3261_V1.2.0"
+#define VERSION "RT3261_V1.3.0"
 
 #if defined (CONFIG_SND_SOC_RT5623)
 extern void rt5623_on(void);
@@ -74,7 +84,7 @@ struct rt3261_init_reg {
 };
 
 static struct rt3261_init_reg init_list[] = {
-       {RT3261_GEN_CTRL1       , 0x3f01},//fa[12:13] = 1'b; fa[8~10]=1; fa[0]=1
+       {RT3261_GEN_CTRL1       , 0x3701},//fa[12:13] = 1'b; fa[8~10]=1; fa[0]=1
        {RT3261_ADDA_CLK1       , 0x1114},//73[2] = 1'b
        {RT3261_MICBIAS         , 0x3030},//93[5:4] = 11'b
        {RT3261_CLS_D_OUT       , 0xa000},//8d[11] = 0'b
@@ -96,6 +106,50 @@ static struct rt3261_init_reg init_list[] = {
        {RT3261_OUTPUT          , 0x8888},//unmute OUTVOLL/R
        {RT3261_SPO_CLSD_RATIO  , 0x0001},
        {RT3261_I2S1_SDP        , 0xd000},
+       {RT3261_GLB_CLK         , 0x4000},//0424
+       //{0x90         , 0x636},//0424
+       {RT3261_CHARGE_PUMP     , 0xe00},//0424
+       {RT3261_DEPOP_M3        , 0x636},//0424
+       {RT3261_DEPOP_M1        , 0x84},//0424
+       {RT3261_PWR_DIG1        , 0x8000},//0424
+       {RT3261_PWR_ANLG2       , 0x0800},
+       // huangcun 20130816 s
+#if 0
+       /*speaker*/
+       {RT3261_DSP_PATH2       , 0x0000},
+       {RT3261_PRIV_INDEX      , 0x003f},//PR3d[14] = 0'b; 
+       {RT3261_PRIV_DATA       , 0x0000},
+       {RT3261_DAC2_CTRL       , 0x0000},
+       {RT3261_MONO_DAC_MIXER, 0x4444},
+       {RT3261_SPK_L_MIXER,  0x003a},
+       {RT3261_SPK_R_MIXER,  0x003a},
+       {RT3261_SPO_L_MIXER,  0xc800},
+       /*headphone*/
+       {RT3261_OUT_L3_MIXER, 0x01fd},
+       {RT3261_OUT_R3_MIXER, 0x01fd},
+       {RT3261_HPO_MIXER,        0xc000},
+#endif
+#if 0
+       /*capture*/
+       {RT3261_IN1_IN2,          0x2080},//boost1 = 24db
+       {RT3261_REC_R2_MIXER, 0x007d},
+       {RT3261_MONO_ADC_MIXER,0x7030},
+       //{RT3261_GEN_CTRL1 , 0x2701},//regfa[13]=0
+       {RT3261_DSP_PATH2       , 0x0400},
+       {RT3261_DIG_INF_DATA, 0x0300},//right copy to left
+#endif
+#if 0
+       /*lin out*/
+       {RT3261_DSP_PATH2       , 0x0000},
+       {RT3261_PRIV_INDEX      , 0x003f},//PR3d[14] = 0'b; 
+       {RT3261_PRIV_DATA       , 0x0000},
+       {RT3261_DAC2_CTRL       , 0x0000},
+       {RT3261_MONO_DAC_MIXER, 0x4444},
+       {RT3261_OUT_L3_MIXER, 0x01fd},
+       {RT3261_OUT_R3_MIXER, 0x01fd},
+       {RT3261_LOUT_MIXER,   0xc000},
+#endif
+       // huangcun 20130816 e
 };
 #define RT3261_INIT_REG_LEN ARRAY_SIZE(init_list)
 
@@ -109,6 +163,40 @@ static int rt3261_reg_init(struct snd_soc_codec *codec)
        return 0;
 }
 
+static int rt3261_customer_redefine(struct snd_soc_codec *codec, struct rt3261_priv *rt3261)
+{
+       if(rt3261->spk_num==TWO_SPK)
+       {
+               snd_soc_update_bits(codec, RT3261_SPO_L_MIXER,
+                       RT3261_M_SV_R_SPM_L | RT3261_M_SV_L_SPM_L,
+                       1 << RT3261_M_SV_R_SPM_L_SFT | 0 << RT3261_M_SV_L_SPM_L_SFT);
+               snd_soc_update_bits(codec, RT3261_SPO_R_MIXER,
+                       RT3261_M_SV_R_SPM_R, 0 << RT3261_M_SV_R_SPM_R_SFT);
+       }
+       else
+       {
+               snd_soc_update_bits(codec, RT3261_SPO_L_MIXER,
+                       RT3261_M_SV_R_SPM_L | RT3261_M_SV_L_SPM_L,
+                       0 << RT3261_M_SV_R_SPM_L_SFT | 0 << RT3261_M_SV_L_SPM_L_SFT);
+               snd_soc_update_bits(codec, RT3261_SPO_R_MIXER,
+                       RT3261_M_SV_R_SPM_R, 1 << RT3261_M_SV_R_SPM_R_SFT);
+       }
+
+       
+       snd_soc_update_bits(codec, RT3261_IN3_IN4,
+               RT3261_IN_DF2, rt3261->modem_input_mode << RT3261_IN_SFT2);
+       snd_soc_update_bits(codec, RT3261_GEN_CTRL1,
+               RT3261_LOUT_DF_MASK, rt3261->lout_to_modem_mode << RT3261_LOUT_DF);
+       snd_soc_update_bits(codec, RT3261_SPO_CLSD_RATIO,
+               RT3261_SPO_CLSD_RATIO_MASK, rt3261->spk_amplify);
+       snd_soc_update_bits(codec, RT3261_DIG_INF_DATA,
+               RT3261_IF1_DAC_SEL_MASK | RT3261_IF2_DAC_SEL_MASK, 
+               (rt3261->playback_if1_data_control<<RT3261_IF1_DAC_SEL_SFT) | (rt3261->playback_if2_data_control<<RT3261_IF2_DAC_SEL_SFT));
+
+       return 0;
+}
+
+
 static int rt3261_index_sync(struct snd_soc_codec *codec)
 {
        int i;
@@ -190,7 +278,7 @@ static int rt3261_reset(struct snd_soc_codec *codec)
 {
        return snd_soc_write(codec, RT3261_RESET, 0);
 }
-
+#if 0
 static unsigned int rt3261_read(struct snd_soc_codec *codec,
                unsigned int reg)
 {
@@ -199,10 +287,11 @@ static unsigned int rt3261_read(struct snd_soc_codec *codec,
        val = codec->hw_read(codec, reg);
        return val;
 }
-
+#endif
 static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg,
                unsigned int value, const void *data, int len)
 {
+       struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec);
        int ret;
 
        if (!snd_soc_codec_volatile_register(codec, reg) &&
@@ -218,11 +307,8 @@ static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg,
                return 0;
        }
 
-       ret = i2c_master_normal_send(codec->control_data, data, len,400*1000);
-       if (ret == len)
+       if (i2c_master_send(rt3261->i2c, data, len) == len)
                return 0;
-       if (ret < 0)
-               return ret;
        else
                return -EIO;
 }
@@ -237,6 +323,7 @@ static int rt3261_write(struct snd_soc_codec *codec, unsigned int reg,
        data[2] = value & 0xff;
 
        DBG("rt3261_write 0x%x = 0x%x\n",reg,value);
+
        return do_hw_write(codec, reg, value, data, 3);
 }
 
@@ -486,29 +573,6 @@ static int rt3261_readable_register(
        }
 }
 
-void codec_set_spk(bool on)
-{
-
-       struct snd_soc_codec *codec = rt3261_codec;
-       DBG("%s: %d\n", __func__, on);
-
-       if(!codec)
-               return;
-
-       if(on){
-               DBG("snd_soc_dapm_enable_pin\n");
-               snd_soc_dapm_enable_pin(&codec->dapm, "Headphone Jack");
-               snd_soc_dapm_enable_pin(&codec->dapm, "Ext Spk");
-       }else{
-               DBG("snd_soc_dapm_disable_pin\n");
-               snd_soc_dapm_disable_pin(&codec->dapm, "Headphone Jack");
-               snd_soc_dapm_disable_pin(&codec->dapm, "Ext Spk");
-       }
-       snd_soc_dapm_sync(&codec->dapm);
-}
-
-
-
 /**
  * rt3261_headset_mic_detect - Detect headset.
  * @codec: SoC audio codec device.
@@ -525,6 +589,10 @@ int rt3261_headset_mic_detect(int jack_insert)
        int sclk_src;
 #endif
 
+       if(rt3261_codec == NULL){
+               return -1;
+       }
+
        if(jack_insert) {
                if (SND_SOC_BIAS_OFF == rt3261_codec->dapm.bias_level) {
                        snd_soc_write(rt3261_codec, RT3261_PWR_ANLG1, 0x2004);
@@ -541,7 +609,7 @@ int rt3261_headset_mic_detect(int jack_insert)
                        RT3261_PWR_LDO2, RT3261_PWR_LDO2);
                snd_soc_update_bits(rt3261_codec, RT3261_PWR_ANLG2,
                        RT3261_PWR_MB1, RT3261_PWR_MB1);
-               mdelay(400);
+               msleep(400);
                snd_soc_update_bits(rt3261_codec, RT3261_MICBIAS,
                        RT3261_MIC1_OVCD_MASK | RT3261_MIC1_OVTH_MASK |
                        RT3261_PWR_CLK25M_MASK | RT3261_PWR_MB_MASK,
@@ -666,8 +734,66 @@ static int rt3261_dmic_put(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
+static int rt3261_asrc_get(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec);
+
+       DBG("%s\n", __FUNCTION__);
+       ucontrol->value.integer.value[0] = rt3261->asrc_en;
+
+       return 0;
+}
+
+static int rt3261_asrc_put(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec);
+
+       DBG("%s\n", __FUNCTION__);
+       if (rt3261->asrc_en == ucontrol->value.integer.value[0])
+               return 0;
+
+       rt3261->asrc_en = ucontrol->value.integer.value[0];
+       switch (rt3261->asrc_en) {
+       case RT3261_ASRC_DIS://disable ASRC
+               DBG("%s disable\n", __FUNCTION__);
+               snd_soc_write(codec, RT3261_ASRC_1, 0x0);                       
+               snd_soc_write(codec, RT3261_ASRC_2, 0x0);
+               snd_soc_update_bits(codec, RT3261_GEN_CTRL1, 0x70, 0x0); //bard 8-29
+               mutex_lock(&codec->mutex);
+               snd_soc_dapm_disable_pin(&codec->dapm, "DAC L2 Power"); //bard 9-4
+               snd_soc_dapm_disable_pin(&codec->dapm, "stereo filter"); //bard 9-4
+               snd_soc_dapm_sync(&codec->dapm); //bard 9-4
+               mutex_unlock(&codec->mutex);
+               break;
+
+       case RT3261_ASRC_EN://enable ASRC
+               DBG("%s enable\n", __FUNCTION__);
+               snd_soc_write(codec, RT3261_ASRC_1, 0x9800);                    
+               snd_soc_write(codec, RT3261_ASRC_2, 0xF800);
+               snd_soc_update_bits(codec, RT3261_GEN_CTRL1, 0x70, 0x70); //bard 8-29
+               snd_soc_write(codec, RT3261_JD_CTRL, 0x03); //bard 8-29
+               //snd_soc_update_bits(codec, RT3261_PWR_DIG1, 0x0080, 0x0080);
+               //snd_soc_update_bits(codec, RT3261_PWR_DIG2, 0x8000, 0x8000);
+               mutex_lock(&codec->mutex);
+               snd_soc_dapm_force_enable_pin(&codec->dapm, "DAC L2 Power"); //bard 9-4
+               snd_soc_dapm_force_enable_pin(&codec->dapm, "stereo filter"); //bard 9-4
+               snd_soc_dapm_sync(&codec->dapm); //bard 9-4
+               mutex_unlock(&codec->mutex);
+               snd_soc_write(codec, RT3261_ADDA_CLK1, 0x1114);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 //bard 8-9 s
-#if 0
 static int rt3261_mic1_get(struct snd_kcontrol *kcontrol,
                struct snd_ctl_elem_value *ucontrol)
 {
@@ -684,7 +810,7 @@ static int rt3261_mic1_put(struct snd_kcontrol *kcontrol,
 {
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 
-       if(ucontrol->value.integer.value[0]) {
+       if(ucontrol->value.integer.value[0]==0) {
                snd_soc_update_bits(codec, RT3261_REC_L2_MIXER,
                        RT3261_M_BST1_RM_L, 0);
                snd_soc_update_bits(codec, RT3261_REC_R2_MIXER,
@@ -715,7 +841,7 @@ static int rt3261_mic2_put(struct snd_kcontrol *kcontrol,
 {
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 
-       if(ucontrol->value.integer.value[0]) {
+       if(ucontrol->value.integer.value[0]==0) {
                snd_soc_update_bits(codec, RT3261_REC_L2_MIXER,
                        RT3261_M_BST4_RM_L, 0);
                snd_soc_update_bits(codec, RT3261_REC_R2_MIXER,
@@ -729,24 +855,29 @@ static int rt3261_mic2_put(struct snd_kcontrol *kcontrol,
 
        return 0;
 }
-#endif
 //bard 8-9 e
 
-void hp_amp_power(struct snd_soc_codec *codec, int on)
+void rt3261_hp_amp_power(struct snd_soc_codec *codec, int on)
 {
        static int hp_amp_power_count;
-       printk("hp_amp_power on=%d hp_amp_power_count=%d\n",on,hp_amp_power_count);
+       DBG("rt3261_hp_amp_power on=%d hp_amp_power_count=%d\n",on,hp_amp_power_count);
 //     dump_reg(codec);
        if(on) {
                if(hp_amp_power_count <= 0) {
                        snd_soc_update_bits(codec, RT3261_PWR_DIG1,
                                RT3261_PWR_I2S1, RT3261_PWR_I2S1);
                        /* depop parameters */
+                       rt3261_index_update_bits(codec, RT3261_CHPUMP_INT_REG1,0x0700, 0x0200); //bard 12-6
+                       snd_soc_write(codec, RT3261_DEPOP_M2, 0x3100);  //bard 4-22
+                       snd_soc_write(codec, RT3261_DEPOP_M1, 0x0009);  //bard 4-22
+                       msleep(50);
+/*
                        snd_soc_update_bits(codec, RT3261_DEPOP_M2,
                                RT3261_DEPOP_MASK, RT3261_DEPOP_MAN);
                        snd_soc_update_bits(codec, RT3261_DEPOP_M1,
                                RT3261_HP_CP_MASK | RT3261_HP_SG_MASK | RT3261_HP_CB_MASK,
                                RT3261_HP_CP_PU | RT3261_HP_SG_DIS | RT3261_HP_CB_PU);
+*/
                        rt3261_index_write(codec, RT3261_HP_DCC_INT1, 0x9f00);
                        /* headphone amp power on */
                        snd_soc_update_bits(codec, RT3261_PWR_ANLG1,
@@ -757,7 +888,7 @@ void hp_amp_power(struct snd_soc_codec *codec, int on)
                        snd_soc_update_bits(codec, RT3261_PWR_ANLG1,
                                RT3261_PWR_HP_L | RT3261_PWR_HP_R | RT3261_PWR_HA , //bard 10-18
                                RT3261_PWR_HP_L | RT3261_PWR_HP_R | RT3261_PWR_HA); //bard 10-18
-                       msleep(50);
+                       msleep(30);  //bard 4-22
                        snd_soc_update_bits(codec, RT3261_PWR_ANLG1,
                                RT3261_PWR_FV1 | RT3261_PWR_FV2,
                                RT3261_PWR_FV1 | RT3261_PWR_FV2);
@@ -768,6 +899,7 @@ void hp_amp_power(struct snd_soc_codec *codec, int on)
                        snd_soc_update_bits(codec, RT3261_DEPOP_M1,
                                RT3261_HP_CO_MASK | RT3261_HP_SG_MASK,
                                RT3261_HP_CO_EN | RT3261_HP_SG_EN);
+                       rt3261_index_update_bits(codec, RT3261_CHPUMP_INT_REG1,0x0700, 0x0400); //bard 12-6
                }
                hp_amp_power_count++;
        } else {
@@ -811,6 +943,7 @@ static int rt3261_hp_mute_put(struct snd_kcontrol *kcontrol,
 
        if(ucontrol->value.integer.value[0]) {
                /* headphone unmute sequence */
+
                snd_soc_update_bits(codec, RT3261_DEPOP_M3,
                        RT3261_CP_FQ1_MASK | RT3261_CP_FQ2_MASK | RT3261_CP_FQ3_MASK,
                        (RT3261_CP_FQ_192_KHZ << RT3261_CP_FQ1_SFT) |
@@ -824,9 +957,9 @@ static int rt3261_hp_mute_put(struct snd_kcontrol *kcontrol,
                snd_soc_update_bits(codec, RT3261_DEPOP_M1,
                        RT3261_RSTN_MASK | RT3261_HP_L_SMT_MASK | RT3261_HP_R_SMT_MASK,
                        RT3261_RSTN_DIS | RT3261_HP_L_SMT_EN | RT3261_HP_R_SMT_EN);
-               snd_soc_update_bits(codec, RT3261_HP_VOL,
-                       RT3261_L_MUTE | RT3261_R_MUTE, 0);
-               msleep(100);
+               //snd_soc_update_bits(codec, RT3261_HP_VOL,
+               //      RT3261_L_MUTE | RT3261_R_MUTE, RT3261_L_MUTE | RT3261_R_MUTE);
+               msleep(60);  //bard 4-22
                snd_soc_update_bits(codec, RT3261_DEPOP_M1,
                        RT3261_HP_SG_MASK | RT3261_HP_L_SMT_MASK |
                        RT3261_HP_R_SMT_MASK, RT3261_HP_SG_DIS |
@@ -859,10 +992,12 @@ static int rt3261_hp_mute_put(struct snd_kcontrol *kcontrol,
                */
                snd_soc_update_bits(codec, RT3261_HP_VOL,
                        RT3261_L_MUTE | RT3261_R_MUTE, RT3261_L_MUTE | RT3261_R_MUTE);
-               msleep(30);
+               msleep(60);
+/*
                snd_soc_update_bits(codec, RT3261_DEPOP_M1,
                        RT3261_HP_R_SMT_MASK | RT3261_HP_L_SMT_MASK,
                        RT3261_HP_L_SMT_DIS | RT3261_HP_R_SMT_DIS);
+*/
                } 
        return 0;
 }
@@ -894,6 +1029,18 @@ static int rt3261_modem_input_switch_put(struct snd_kcontrol *kcontrol,
 
        return 0;
 }
+#else
+static int rt3261_modem_input_switch_get(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_value *ucontrol)
+{
+       return 0;
+}
+
+static int rt3261_modem_input_switch_put(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_value *ucontrol)
+{
+       return 0;
+}
 #endif
 
 static int rt3261_dacr_sel_get(struct snd_kcontrol *kcontrol,
@@ -1027,6 +1174,10 @@ static const SOC_ENUM_SINGLE_DECL(
 static const char *rt3261_dmic_mode[] = {"Disable", "DMIC1", "DMIC2"};
 
 static const SOC_ENUM_SINGLE_DECL(rt3261_dmic_enum, 0, 0, rt3261_dmic_mode);
+/* ASRC */
+static const char *rt3261_asrc_mode[] = {"Disable", "Enable"};
+
+static const SOC_ENUM_SINGLE_DECL(rt3261_asrc_enum, 0, 0, rt3261_asrc_mode);
 
 /* PR-3F */
 static const char *rt3261_dacr_sel_mode[] = {"IF2_DAC", "IF2_ADC"};
@@ -1043,22 +1194,17 @@ static const SOC_ENUM_SINGLE_DECL(rt3261_rxdp1_sel_enum, 0, 0, rt3261_rxdp1_sel_
 
 
 //bard 8-9 s
-#if 0
 static const char *rt3261_mic_mode[] = {"off", "on",};
-
 static const SOC_ENUM_SINGLE_DECL(rt3261_mic_enum, 0, 0, rt3261_mic_mode);
-#endif
 //bard 8-9 e
 
 static const char *rt3261_hp_mute_mode[] = {"off", "on",};
 
 static const SOC_ENUM_SINGLE_DECL(rt3261_hp_mute_enum, 0, 0, rt3261_hp_mute_mode);
 
-#if defined (CONFIG_SND_SOC_RT5623)
 static const char *rt3261_modem_input_switch_mode[] = {"off", "on",};
 
 static const SOC_ENUM_SINGLE_DECL(rt3261_modem_input_switch_enum, 0, 0, rt3261_modem_input_switch_mode);
-#endif
 
 #ifdef RT3261_REG_RW
 #define REGVAL_MAX 0xffff
@@ -1136,10 +1282,12 @@ static const struct snd_kcontrol_new rt3261_snd_controls[] = {
                RT3261_L_VOL_SFT, RT3261_R_VOL_SFT, RT3261_VOL_RSCL_RANGE, 0,
                rt3261_vol_rescale_get, rt3261_vol_rescale_put, out_vol_tlv),
        /* Headphone Output Volume */
+/*
        SOC_DOUBLE("HP Playback Switch", RT3261_HP_VOL,
                RT3261_L_MUTE_SFT, RT3261_R_MUTE_SFT, 1, 1),
+*/
        SOC_DOUBLE_EXT_TLV("Headphone Playback Volume", RT3261_HP_VOL,
-               RT3261_L_VOL_SFT, RT3261_R_VOL_SFT, RT3261_HP_VOL_RSCL_RANGE, 0,
+               RT3261_L_VOL_SFT, RT3261_R_VOL_SFT, RT3261_VOL_RSCL_RANGE, 0,
                rt3261_vol_rescale_get, rt3261_vol_rescale_put, out_vol_tlv),
        /* OUTPUT Control */
        SOC_DOUBLE("OUT Playback Switch", RT3261_OUTPUT,
@@ -1194,7 +1342,9 @@ static const struct snd_kcontrol_new rt3261_snd_controls[] = {
        /* DMIC */
        SOC_ENUM_EXT("DMIC Switch", rt3261_dmic_enum,
                rt3261_dmic_get, rt3261_dmic_put),
-
+       /* ASRC */
+       SOC_ENUM_EXT("ASRC Switch", rt3261_asrc_enum,
+               rt3261_asrc_get, rt3261_asrc_put),
        /* PR-3F */
        SOC_ENUM_EXT("DACR Select", rt3261_dacr_sel_enum,
                rt3261_dacr_sel_get, rt3261_dacr_sel_put),
@@ -1212,7 +1362,6 @@ static const struct snd_kcontrol_new rt3261_snd_controls[] = {
        },
 #endif
 //bard 8-9 s
-#if 0
        SOC_SINGLE_TLV("Main Mic Capture Volume", RT3261_IN1_IN2,
                RT3261_BST_SFT1,  8, 0, bst_tlv), 
        SOC_SINGLE_TLV("Headset Mic Capture Volume", RT3261_IN3_IN4,
@@ -1221,16 +1370,13 @@ static const struct snd_kcontrol_new rt3261_snd_controls[] = {
                rt3261_mic1_get, rt3261_mic1_put),
        SOC_ENUM_EXT("Headset Mic Capture Switch", rt3261_mic_enum,
                rt3261_mic2_get, rt3261_mic2_put),
-#endif
 //bard 8-9 e
 
        SOC_ENUM_EXT("HP mute Switch", rt3261_hp_mute_enum,
                rt3261_hp_mute_get, rt3261_hp_mute_put),
 
-       #if defined (CONFIG_SND_SOC_RT5623)
        SOC_ENUM_EXT("Modem Input Switch", rt3261_modem_input_switch_enum,
                rt3261_modem_input_switch_get, rt3261_modem_input_switch_put),
-       #endif
 
        SOC_ENUM("ADC IF1 Data Switch", rt3261_if1_adc_enum), 
        SOC_ENUM("DAC IF1 Data Switch", rt3261_if1_dac_enum), 
@@ -1690,25 +1836,29 @@ static const struct snd_kcontrol_new rt3261_sdi_mux =
 static int rt3261_adc_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
-       struct snd_soc_codec *codec = w->codec;
-       unsigned int val, mask;
+       //struct snd_soc_codec *codec = w->codec;
+       //unsigned int val, mask;
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                //rt3261_index_update_bits(codec,
                //      RT3261_CHOP_DAC_ADC, 0x1000, 0x1000);
+               /*bard 3-26 r
                val = snd_soc_read(codec, RT3261_MONO_ADC_MIXER);
                mask = RT3261_M_MONO_ADC_L1 | RT3261_M_MONO_ADC_L2 |
                        RT3261_M_MONO_ADC_R1 | RT3261_M_MONO_ADC_R2;
                if ((val & mask) ^ mask)
                        snd_soc_update_bits(codec, RT3261_GEN_CTRL1,
                                RT3261_M_MAMIX_L | RT3261_M_MAMIX_R, 0);
+               */
                break;
 
        case SND_SOC_DAPM_POST_PMD:
+               /*bard 3-26 r
                snd_soc_update_bits(codec, RT3261_GEN_CTRL1,
                        RT3261_M_MAMIX_L | RT3261_M_MAMIX_R,
                        RT3261_M_MAMIX_L | RT3261_M_MAMIX_R);
+               */
                //rt3261_index_update_bits(codec,
                //      RT3261_CHOP_DAC_ADC, 0x1000, 0x0000);
                break;
@@ -1720,6 +1870,55 @@ static int rt3261_adc_event(struct snd_soc_dapm_widget *w,
        return 0;
 }
 
+//bard 3-26 s
+static int rt3261_mono_adcl_event(struct snd_soc_dapm_widget *w,
+       struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+       //unsigned int val, mask;
+
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMU:
+               snd_soc_update_bits(codec, RT3261_GEN_CTRL1,
+                       RT3261_M_MAMIX_L, 0);
+               break;
+       case SND_SOC_DAPM_PRE_PMD:
+               snd_soc_update_bits(codec, RT3261_GEN_CTRL1,
+                       RT3261_M_MAMIX_L,
+                       RT3261_M_MAMIX_L);
+               break;
+
+       default:
+               return 0;
+       }
+
+       return 0;
+}
+
+static int rt3261_mono_adcr_event(struct snd_soc_dapm_widget *w,
+       struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+       //unsigned int val, mask;
+
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMU:
+               snd_soc_update_bits(codec, RT3261_GEN_CTRL1,
+                       RT3261_M_MAMIX_R, 0);
+               break;
+       case SND_SOC_DAPM_PRE_PMD:
+               snd_soc_update_bits(codec, RT3261_GEN_CTRL1,
+                       RT3261_M_MAMIX_R,
+                       RT3261_M_MAMIX_R);
+               break;
+
+       default:
+               return 0;
+       }
+
+       return 0;
+}
+//bard 3-26 e
 static int rt3261_spk_event(struct snd_soc_dapm_widget *w,
                struct snd_kcontrol *kcontrol, int event)
 {
@@ -1766,6 +1965,7 @@ static void rt3261_pmu_depop(struct snd_soc_codec *codec)
 {
 #if 0
        /* depop parameters */
+       rt3261_index_update_bits(codec, RT3261_CHPUMP_INT_REG1,0x0700, 0x0200); //bard 12-6
        snd_soc_update_bits(codec, RT3261_DEPOP_M2,
                RT3261_DEPOP_MASK, RT3261_DEPOP_MAN);
        snd_soc_update_bits(codec, RT3261_DEPOP_M1,
@@ -1793,8 +1993,9 @@ static void rt3261_pmu_depop(struct snd_soc_codec *codec)
        snd_soc_update_bits(codec, RT3261_DEPOP_M1,
                RT3261_HP_CO_MASK | RT3261_HP_SG_MASK,
                RT3261_HP_CO_EN | RT3261_HP_SG_EN);
+       rt3261_index_update_bits(codec, RT3261_CHPUMP_INT_REG1,0x0700, 0x0400); //bard 12-6
 #else
-       hp_amp_power(codec, 1);
+       rt3261_hp_amp_power(codec, 1);
 #endif
        /* headphone unmute sequence */
        snd_soc_update_bits(codec, RT3261_DEPOP_M3,
@@ -1810,9 +2011,10 @@ static void rt3261_pmu_depop(struct snd_soc_codec *codec)
        snd_soc_update_bits(codec, RT3261_DEPOP_M1,
                RT3261_RSTN_MASK | RT3261_HP_L_SMT_MASK | RT3261_HP_R_SMT_MASK,
                RT3261_RSTN_DIS | RT3261_HP_L_SMT_EN | RT3261_HP_R_SMT_EN);
+       //msleep(30); 
        snd_soc_update_bits(codec, RT3261_HP_VOL,
                RT3261_L_MUTE | RT3261_R_MUTE, 0);
-       msleep(100);
+       msleep(30);  //bard 4-22
        snd_soc_update_bits(codec, RT3261_DEPOP_M1,
                RT3261_HP_SG_MASK | RT3261_HP_L_SMT_MASK |
                RT3261_HP_R_SMT_MASK, RT3261_HP_SG_DIS |
@@ -1843,9 +2045,8 @@ static void rt3261_pmd_depop(struct snd_soc_codec *codec)
                RT3261_HP_L_SMT_EN | RT3261_HP_R_SMT_EN);
        /*bard 10-18 r
        snd_soc_update_bits(codec, RT3261_HP_CALIB_AMP_DET,
-               RT3261_HPD_PS_MASK, RT3261_HPD_PS_DIS);
-       msleep(90);
-       */
+               RT3261_HPD_PS_MASK, RT3261_HPD_PS_DIS);*/
+       //msleep(90);
        snd_soc_update_bits(codec, RT3261_HP_VOL,
                RT3261_L_MUTE | RT3261_R_MUTE, RT3261_L_MUTE | RT3261_R_MUTE);
        msleep(30);
@@ -1867,13 +2068,14 @@ static void rt3261_pmd_depop(struct snd_soc_codec *codec)
                RT3261_PWR_HP_L | RT3261_PWR_HP_R | RT3261_PWR_HA,
                0);
 #else
-       hp_amp_power(codec, 0);
+       rt3261_hp_amp_power(codec, 0);
 #endif
 }
 #else //one bit
 static void rt3261_pmu_depop(struct snd_soc_codec *codec)
 {
        /* depop parameters */
+       rt3261_index_update_bits(codec, RT3261_CHPUMP_INT_REG1,0x0700, 0x0200); //bard 12-6
        snd_soc_update_bits(codec, RT3261_DEPOP_M2,
                RT3261_DEPOP_MASK, RT3261_DEPOP_MAN);
        snd_soc_update_bits(codec, RT3261_DEPOP_M1,
@@ -1908,6 +2110,7 @@ static void rt3261_pmu_depop(struct snd_soc_codec *codec)
        snd_soc_update_bits(codec, RT3261_DEPOP_M1,
                RT3261_HP_CP_MASK | RT3261_HP_SG_MASK,
                RT3261_HP_CP_PD | RT3261_HP_SG_EN);
+       rt3261_index_update_bits(codec, RT3261_CHPUMP_INT_REG1,0x0700, 0x0400); //bard 12-6
        msleep(10);
        snd_soc_update_bits(codec, RT3261_HP_VOL,
                RT3261_L_MUTE | RT3261_R_MUTE, 0);
@@ -1927,10 +2130,8 @@ static void rt3261_pmd_depop(struct snd_soc_codec *codec)
        snd_soc_update_bits(codec, RT3261_HP_VOL,
                RT3261_L_MUTE | RT3261_R_MUTE,
                RT3261_L_MUTE | RT3261_R_MUTE);
-       msleep(90);
        snd_soc_update_bits(codec, RT3261_DEPOP_M1,
                RT3261_HP_CB_MASK, RT3261_HP_CB_PD);
-       msleep(30);
        //rt3261_index_update_bits(codec, RT3261_CHOP_DAC_ADC, 0x0200, 0x0);
        snd_soc_update_bits(codec, RT3261_PWR_ANLG1,
                RT3261_PWR_HP_L | RT3261_PWR_HP_R | RT3261_PWR_HA,
@@ -1942,7 +2143,6 @@ static int rt3261_hp_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol, int event)
 {
        struct snd_soc_codec *codec = w->codec;
-
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                rt3261_pmu_depop(codec);
@@ -1989,7 +2189,7 @@ static int rt3261_lout_event(struct snd_soc_dapm_widget *w,
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
-               hp_amp_power(codec,1);
+               rt3261_hp_amp_power(codec,1);
                snd_soc_update_bits(codec, RT3261_PWR_ANLG1,
                        RT3261_PWR_LM, RT3261_PWR_LM); //bard 10-18
                snd_soc_update_bits(codec, RT3261_OUTPUT,
@@ -2002,7 +2202,7 @@ static int rt3261_lout_event(struct snd_soc_dapm_widget *w,
                        RT3261_L_MUTE | RT3261_R_MUTE);
                snd_soc_update_bits(codec, RT3261_PWR_ANLG1,
                        RT3261_PWR_LM, 0); //bard 10-18
-               hp_amp_power(codec,0);
+               rt3261_hp_amp_power(codec,0);
                break;
 
        default:
@@ -2011,7 +2211,30 @@ static int rt3261_lout_event(struct snd_soc_dapm_widget *w,
 
        return 0;
 }
+//bard 8-29 s
+static int rt3261_dac_event(struct snd_soc_dapm_widget *w, 
+       struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+       struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec);
+
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMU:
+               if( rt3261->asrc_en == RT3261_ASRC_EN)
+                       rt3261_update_eqmode(codec, 2);//BT_VOIP
+               break;
 
+       case SND_SOC_DAPM_PRE_PMD:
+               rt3261_update_eqmode(codec, 0);//NORMAL
+               break;
+
+       default:
+               return 0;
+       }
+
+       return 0;
+}
+//bard 8-29 e
 static const struct snd_soc_dapm_widget rt3261_dapm_widgets[] = {
        SND_SOC_DAPM_SUPPLY("PLL1", RT3261_PWR_ANLG2,
                        RT3261_PWR_PLL_BIT, 0, NULL, 0),
@@ -2060,8 +2283,10 @@ static const struct snd_soc_dapm_widget rt3261_dapm_widgets[] = {
        SND_SOC_DAPM_PGA("INR VOL", RT3261_PWR_VOL,
                RT3261_PWR_IN_R_BIT, 0, NULL, 0),
        /* IN Mux */
+/*
        SND_SOC_DAPM_MUX("INL Mux", SND_SOC_NOPM, 0, 0, &rt3261_inl_mux),
        SND_SOC_DAPM_MUX("INR Mux", SND_SOC_NOPM, 0, 0, &rt3261_inr_mux),
+*/
        /* REC Mixer */
        SND_SOC_DAPM_MIXER("RECMIXL", RT3261_PWR_MIXER, RT3261_PWR_RM_L_BIT, 0,
                        rt3261_rec_l_mix, ARRAY_SIZE(rt3261_rec_l_mix)),
@@ -2104,12 +2329,14 @@ static const struct snd_soc_dapm_widget rt3261_dapm_widgets[] = {
                rt3261_sto_adc_r_mix, ARRAY_SIZE(rt3261_sto_adc_r_mix)),
        SND_SOC_DAPM_SUPPLY("mono left filter", RT3261_PWR_DIG2,
                RT3261_PWR_ADC_MF_L_BIT, 0, NULL, 0),
-       SND_SOC_DAPM_MIXER("Mono ADC MIXL", SND_SOC_NOPM, 0, 0,
-               rt3261_mono_adc_l_mix, ARRAY_SIZE(rt3261_mono_adc_l_mix)),
+       SND_SOC_DAPM_MIXER_E("Mono ADC MIXL", SND_SOC_NOPM, 0, 0,
+               rt3261_mono_adc_l_mix, ARRAY_SIZE(rt3261_mono_adc_l_mix),
+               rt3261_mono_adcl_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), //bard 3-26
        SND_SOC_DAPM_SUPPLY("mono right filter", RT3261_PWR_DIG2,
                RT3261_PWR_ADC_MF_R_BIT, 0, NULL, 0),
-       SND_SOC_DAPM_MIXER("Mono ADC MIXR", SND_SOC_NOPM, 0, 0,
-               rt3261_mono_adc_r_mix, ARRAY_SIZE(rt3261_mono_adc_r_mix)),
+       SND_SOC_DAPM_MIXER_E("Mono ADC MIXR", SND_SOC_NOPM, 0, 0,
+               rt3261_mono_adc_r_mix, ARRAY_SIZE(rt3261_mono_adc_r_mix),
+               rt3261_mono_adcr_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), //bard 3-26
 
        /* IF2 Mux */
        SND_SOC_DAPM_MUX("IF2 ADC L Mux", SND_SOC_NOPM, 0, 0,
@@ -2118,8 +2345,8 @@ static const struct snd_soc_dapm_widget rt3261_dapm_widgets[] = {
                                &rt3261_if2_adc_r_mux),
 
        /* Digital Interface */
-       SND_SOC_DAPM_SUPPLY("I2S1", RT3261_PWR_DIG1,
-               RT3261_PWR_I2S1_BIT, 0, NULL, 0),
+       SND_SOC_DAPM_SUPPLY("I2S1", SND_SOC_NOPM,
+               0, 0, NULL, 0),
        SND_SOC_DAPM_PGA("IF1 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
        SND_SOC_DAPM_PGA("IF1 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0),
        SND_SOC_DAPM_PGA("IF1 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -2175,10 +2402,19 @@ static const struct snd_soc_dapm_widget rt3261_dapm_widgets[] = {
 
        /* Output Side */
        /* DAC mixer before sound effect  */
+#if 0 //org
        SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0,
                rt3261_dac_l_mix, ARRAY_SIZE(rt3261_dac_l_mix)),
        SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0,
                rt3261_dac_r_mix, ARRAY_SIZE(rt3261_dac_r_mix)),
+#else //bard 8-29
+       SND_SOC_DAPM_MIXER_E("DAC MIXL", SND_SOC_NOPM, 0, 0,
+               rt3261_dac_l_mix, ARRAY_SIZE(rt3261_dac_l_mix),
+               rt3261_dac_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+       SND_SOC_DAPM_MIXER_E("DAC MIXR", SND_SOC_NOPM, 0, 0,
+               rt3261_dac_r_mix, ARRAY_SIZE(rt3261_dac_r_mix),
+               rt3261_dac_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+#endif
 
        /* DAC2 channel Mux */
        SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0,
@@ -2684,10 +2920,15 @@ static int get_sdp_info(struct snd_soc_codec *codec, int dai_id)
 static int get_clk_info(int sclk, int rate)
 {
        int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
+       struct snd_soc_codec *codec = rt3261_codec;
+       struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec);
 
        if (sclk <= 0 || rate <= 0)
                return -EINVAL;
-
+//bard 8-29 s
+       if (rt3261->asrc_en)
+               return 1;
+//bard 8-29 e
        rate = rate << 8;
        for (i = 0; i < ARRAY_SIZE(pd); i++)
                if (sclk == rate * pd[i])
@@ -2754,16 +2995,20 @@ static int rt3261_hw_params(struct snd_pcm_substream *substream,
                        pre_div << RT3261_I2S_PD1_SFT;
                snd_soc_update_bits(codec, RT3261_I2S1_SDP,
                        RT3261_I2S_DL_MASK, val_len);
-               snd_soc_update_bits(codec, RT3261_ADDA_CLK1, mask_clk, val_clk);
+               //snd_soc_update_bits(codec, RT3261_ADDA_CLK1, mask_clk, val_clk);
        }
        if (dai_sel & RT3261_U_IF2) {
-               mask_clk = RT3261_I2S_BCLK_MS2_MASK | RT3261_I2S_PD2_MASK;
-               val_clk = bclk_ms << RT3261_I2S_BCLK_MS2_SFT |
+               mask_clk |= RT3261_I2S_BCLK_MS2_MASK | RT3261_I2S_PD2_MASK;
+               val_clk |= bclk_ms << RT3261_I2S_BCLK_MS2_SFT |
                        pre_div << RT3261_I2S_PD2_SFT;
                snd_soc_update_bits(codec, RT3261_I2S2_SDP,
                        RT3261_I2S_DL_MASK, val_len);
-               snd_soc_update_bits(codec, RT3261_ADDA_CLK1, mask_clk, val_clk);
+               //snd_soc_update_bits(codec, RT3261_ADDA_CLK1, mask_clk, val_clk);
        }
+       if (rt3261->asrc_en)
+               snd_soc_write(codec, RT3261_ADDA_CLK1, 0x1114);
+       else 
+               snd_soc_update_bits(codec, RT3261_ADDA_CLK1, mask_clk, val_clk);
 
        return 0;
 }
@@ -2851,6 +3096,7 @@ static int rt3261_set_dai_sysclk(struct snd_soc_dai *dai,
 
        if (freq == rt3261->sysclk && clk_id == rt3261->sysclk_src)
                return 0;
+ snd_soc_update_bits(codec, RT3261_PWR_ANLG2, RT3261_PWR_PLL, RT3261_PWR_PLL);
 
        switch (clk_id) {
        case RT3261_SCLK_S_MCLK:
@@ -3049,27 +3295,8 @@ static int rt3261_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_PREPARE:
-               /* headphone mute sequence */
-               snd_soc_update_bits(codec, RT3261_DEPOP_M3,
-                       RT3261_CP_FQ1_MASK | RT3261_CP_FQ2_MASK | RT3261_CP_FQ3_MASK,
-                       (RT3261_CP_FQ_96_KHZ << RT3261_CP_FQ1_SFT) |
-                       (RT3261_CP_FQ_12_KHZ << RT3261_CP_FQ2_SFT) |
-                       (RT3261_CP_FQ_96_KHZ << RT3261_CP_FQ3_SFT));
-               rt3261_index_write(codec, RT3261_MAMP_INT_REG2, 0xfc00);
-               snd_soc_update_bits(codec, RT3261_DEPOP_M1,
-                       RT3261_HP_SG_MASK, RT3261_HP_SG_EN);
-               snd_soc_update_bits(codec, RT3261_DEPOP_M1,
-                       RT3261_RSTP_MASK, RT3261_RSTP_EN);
-               snd_soc_update_bits(codec, RT3261_DEPOP_M1,
-                       RT3261_RSTP_MASK | RT3261_HP_L_SMT_MASK |
-                       RT3261_HP_R_SMT_MASK, RT3261_RSTP_DIS |
-                       RT3261_HP_L_SMT_EN | RT3261_HP_R_SMT_EN);
-
-               snd_soc_update_bits(codec, RT3261_HP_VOL,
-                       RT3261_L_MUTE | RT3261_R_MUTE, RT3261_L_MUTE | RT3261_R_MUTE);
-               msleep(30);
-               snd_soc_write(codec, RT3261_DEPOP_M1, 0x0004);
-
+               //snd_soc_update_bits(codec, RT3261_HP_VOL,
+               //      RT3261_L_MUTE | RT3261_R_MUTE, RT3261_L_MUTE | RT3261_R_MUTE); //bard 12-7
                snd_soc_update_bits(codec, RT3261_SPK_VOL,
                        RT3261_L_MUTE | RT3261_R_MUTE,
                        RT3261_L_MUTE | RT3261_R_MUTE);
@@ -3090,6 +3317,9 @@ static int rt3261_set_bias_level(struct snd_soc_codec *codec,
                                RT3261_PWR_FV1 | RT3261_PWR_FV2,
                                RT3261_PWR_FV1 | RT3261_PWR_FV2);
                        snd_soc_write(codec, RT3261_GEN_CTRL1, 0x3701);
+                       snd_soc_update_bits(codec, RT3261_PWR_ANLG2,
+                               RT3261_PWR_MB1 | RT3261_PWR_MB2,
+                               RT3261_PWR_MB1 | RT3261_PWR_MB2);
                        codec->cache_only = false;
                        codec->cache_sync = 1;
                        snd_soc_cache_sync(codec);
@@ -3098,8 +3328,8 @@ static int rt3261_set_bias_level(struct snd_soc_codec *codec,
                break;
 
        case SND_SOC_BIAS_OFF:
-               snd_soc_write(codec, RT3261_DEPOP_M1, 0x0004);
-               snd_soc_write(codec, RT3261_DEPOP_M2, 0x1100);
+               //snd_soc_write(codec, RT3261_DEPOP_M1, 0x0004);//bard 4-22 r
+               //snd_soc_write(codec, RT3261_DEPOP_M2, 0x1100);//bard 4-22 r
                snd_soc_write(codec, RT3261_GEN_CTRL1, 0x3700);
                snd_soc_write(codec, RT3261_PWR_DIG1, 0x0000);
                snd_soc_write(codec, RT3261_PWR_DIG2, 0x0000);
@@ -3116,16 +3346,16 @@ static int rt3261_set_bias_level(struct snd_soc_codec *codec,
 
        return 0;
 }
-       
-static int rt3261_proc_init(void);
-
 
 static int rt3261_probe(struct snd_soc_codec *codec)
 {
        struct rt3261_priv *rt3261 = snd_soc_codec_get_drvdata(codec);
        int ret;
-       struct clk *iis_clk;
-
+#ifdef RTK_IOCTL
+#if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE)
+       struct rt_codec_ops *ioctl_ops = rt_codec_get_ioctl_ops();
+#endif
+#endif
        #if defined (CONFIG_SND_SOC_RT3224)
        pr_info("Codec driver version %s, in fact you choose rt3224, no dsp!\n", VERSION);
        #else
@@ -3138,19 +3368,16 @@ static int rt3261_probe(struct snd_soc_codec *codec)
                return ret;
        }
        codec->write = rt3261_write;
-       
-       #ifdef RT3261_PROC      
-       rt3261_proc_init();
-       #endif
 
-       #if defined (CONFIG_SND_SOC_RT5623)
+       #if 0//defined (CONFIG_SND_SOC_RT5623)
+       struct clk *iis_clk;
        //for rt5623 MCLK use
-       iis_clk = clk_get_sys("rk29_i2s.2", "i2s");
+       iis_clk = clk_get_sys("rk_i2s.2", "i2s");
        if (IS_ERR(iis_clk)) {
-               printk("failed to get i2s clk\n");
+               DBG("failed to get i2s clk\n");
                ret = PTR_ERR(iis_clk);
        }else{
-               printk("I2S2 got i2s clk ok!\n");
+               DBG("I2S2 got i2s clk ok!\n");
                clk_enable(iis_clk);
                clk_set_rate(iis_clk, 11289600);
                rk30_mux_api_set(GPIO0D0_I2S22CHCLK_SMCCSN0_NAME, GPIO0D_I2S2_2CH_CLK);
@@ -3158,7 +3385,11 @@ static int rt3261_probe(struct snd_soc_codec *codec)
        }
        #endif
        
-       rt3261_reset(codec);
+       ret=rt3261_reset(codec);
+       if (ret < 0)
+       {
+               return -ENODEV;
+       }
        snd_soc_update_bits(codec, RT3261_PWR_ANLG1,
                RT3261_PWR_VREF1 | RT3261_PWR_MB |
                RT3261_PWR_BG | RT3261_PWR_VREF2,
@@ -3198,11 +3429,12 @@ static int rt3261_probe(struct snd_soc_codec *codec)
                        RT3261_PWR_HP_L | RT3261_PWR_HP_R,
                        0<<7 | 0<<6 );
        rt3261_reg_init(codec);
+       rt3261_customer_redefine(codec, rt3261);
 
        codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
        rt3261->codec = codec;
 
-       snd_soc_add_controls(codec, rt3261_snd_controls,
+       snd_soc_add_codec_controls(codec, rt3261_snd_controls,
                        ARRAY_SIZE(rt3261_snd_controls));
        snd_soc_dapm_new_controls(&codec->dapm, rt3261_dapm_widgets,
                        ARRAY_SIZE(rt3261_dapm_widgets));
@@ -3217,7 +3449,6 @@ static int rt3261_probe(struct snd_soc_codec *codec)
 
 #ifdef RTK_IOCTL
 #if defined(CONFIG_SND_HWDEP) || defined(CONFIG_SND_HWDEP_MODULE)
-       struct rt_codec_ops *ioctl_ops = rt_codec_get_ioctl_ops();
        ioctl_ops->index_write = rt3261_index_write;
        ioctl_ops->index_read = rt3261_index_read;
        ioctl_ops->index_update_bits = rt3261_index_update_bits;
@@ -3234,6 +3465,7 @@ static int rt3261_probe(struct snd_soc_codec *codec)
                return ret;
        }
        rt3261_codec = codec;
+
        return 0;
 }
 
@@ -3244,7 +3476,7 @@ static int rt3261_remove(struct snd_soc_codec *codec)
 }
 
 #ifdef CONFIG_PM
-static int rt3261_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int rt3261_suspend(struct snd_soc_codec *codec)
 {
 #if defined (CONFIG_SND_SOC_RT3261)
        /* After opening LDO of DSP, then close LDO of codec.
@@ -3253,7 +3485,7 @@ static int rt3261_suspend(struct snd_soc_codec *codec, pm_message_t state)
         * (3) DSP IIS interface power off
         * (4) Toggle pin of codec LDO1 to power off
         */
-       rt3261_dsp_suspend(codec, state);
+       rt3261_dsp_suspend(codec);
 #endif
        rt3261_set_bias_level(codec, SND_SOC_BIAS_OFF);
        return 0;
@@ -3347,22 +3579,119 @@ static const struct i2c_device_id rt3261_i2c_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, rt3261_i2c_id);
 
-static int __devinit rt3261_i2c_probe(struct i2c_client *i2c,
+#ifdef CONFIG_OF
+/*
+dts:
+       rt3261: rt3261@1c {
+               compatible = "rt3261";
+               reg = <0x1c>;
+               codec-en-gpio = <&gpio3 GPIO_D7 GPIO_ACTIVE_HIGH>;
+               spk-num= <2>;
+               modem-input-mode = <1>;
+               lout-to-modem_mode = <1>;
+               spk-amplify = <2>;
+               playback-if1-data_control = <0>;
+               playback-if2-data_control = <0>;
+       };
+*/
+
+static int rt3261_parse_dt_property(struct device *dev,
+                                 struct rt3261_priv *rt3261)
+{
+       struct device_node *node = dev->of_node;
+       int ret;
+       enum of_gpio_flags flags;
+
+       DBG("%s()\n", __FUNCTION__);
+
+       if (!node)
+               return -ENODEV;
+
+       rt3261->codec_en_gpio = of_get_named_gpio_flags(node, "codec-en-gpio", 0, &flags);
+       if (rt3261->codec_en_gpio <= 0) {
+               DBG("%s() Can not read property codec-en-gpio\n", __FUNCTION__);
+       } else {
+               ret = devm_gpio_request(dev, rt3261->codec_en_gpio, "codec_en_gpio");
+               if(ret){
+                       printk("%s() codec_en_gpio request ERROR", __FUNCTION__);
+                       return ret;
+               }
+               ret = gpio_direction_output(rt3261->codec_en_gpio , !flags);
+               if(ret){
+                       printk("%s() codec_en_gpio set ERROR", __FUNCTION__);
+                       return ret;
+               }
+       }
+
+       ret = of_property_read_u32(node, "spk-num", &rt3261->spk_num);
+       if (ret < 0) {
+               DBG("%s() Can not read property spk-num\n", __FUNCTION__);
+               rt3261->spk_num = TWO_SPK;
+       }
+
+       ret = of_property_read_u32(node, "modem-input-mode", &rt3261->modem_input_mode);
+       if (ret < 0) {
+               DBG("%s() Can not read property modem-input-mode\n", __FUNCTION__);
+               rt3261->modem_input_mode = DIFFERENTIAL;
+       }
+
+       ret = of_property_read_u32(node, "lout-to-modem-mode", &rt3261->lout_to_modem_mode);
+       if (ret < 0) {
+               DBG("%s() Can not read property lout-to-modem-mode\n", __FUNCTION__);
+               rt3261->lout_to_modem_mode = DIFFERENTIAL;
+       }
+
+       ret = of_property_read_u32(node, "spk-amplify", &rt3261->spk_amplify);
+       if (ret < 0) {
+               DBG("%s() Can not read property spk-amplify\n", __FUNCTION__);
+               rt3261->spk_amplify = SPK_AMPLIFY_ZERO_POINT_SIX_WATT;
+       }
+
+       ret = of_property_read_u32(node, "playback-if1-data-control", &rt3261->playback_if1_data_control);
+       if (ret < 0) {
+               DBG("%s() Can not read property playback-if1-data-control\n", __FUNCTION__);
+               rt3261->playback_if1_data_control = LR_NORMAL;
+       }
+
+       ret = of_property_read_u32(node, "playback-if2-data-control", &rt3261->playback_if2_data_control);
+       if (ret < 0) {
+               DBG("%s() Can not read property playback-if2-data-control\n", __FUNCTION__);
+               rt3261->playback_if1_data_control = LR_NORMAL;
+       }
+       return 0;
+}
+#else
+static int rt3261_parse_dt_property(struct device *dev,
+                                 struct rt3261_priv *rt3261)
+{
+       return -ENOSYS;
+}
+#endif //#ifdef CONFIG_OF
+
+static int rt3261_i2c_probe(struct i2c_client *i2c,
                    const struct i2c_device_id *id)
 {
        struct rt3261_priv *rt3261;
        int ret;
-       struct rt3261_platform_data *pdata = pdata = i2c->dev.platform_data;
+       char reg;
 
-       rt3261 = kzalloc(sizeof(struct rt3261_priv), GFP_KERNEL);
+       reg = RT3261_VENDOR_ID;
+       ret = i2c_master_recv(i2c, &reg, 1);
+       if (ret < 0){
+               printk("rt3261 && rt3224 probe error\n");
+               return ret;
+       }
+
+       rt3261 = devm_kzalloc(&i2c->dev,sizeof(struct rt3261_priv), GFP_KERNEL);
        if (NULL == rt3261)
                return -ENOMEM;
+       rt3261->i2c = i2c;
 
-       rt3261->codec_en_gpio = pdata->codec_en_gpio;
-       rt3261->io_init = pdata->io_init;
-
-       if(rt3261->io_init)
-               rt3261->io_init(pdata->codec_en_gpio, pdata->codec_en_gpio_info.iomux_name, pdata->codec_en_gpio_info.iomux_mode);
+       ret = rt3261_parse_dt_property(&i2c->dev, rt3261);
+       if (ret < 0) {
+               printk("%s() parse device tree property error %d\n", __FUNCTION__, ret);
+               return ret;
+       }
 
        #if defined (CONFIG_SND_SOC_RT5623)
        rt3261->modem_is_open = 0;
@@ -3372,13 +3701,11 @@ static int __devinit rt3261_i2c_probe(struct i2c_client *i2c,
        DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
        ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt3261,
                        rt3261_dai, ARRAY_SIZE(rt3261_dai));
-       if (ret < 0)
-               kfree(rt3261);
 
        return ret;
 }
 
-static int __devexit rt3261_i2c_remove(struct i2c_client *i2c)
+static int rt3261_i2c_remove(struct i2c_client *i2c)
 {
        snd_soc_unregister_codec(&i2c->dev);
        kfree(i2c_get_clientdata(i2c));
@@ -3400,7 +3727,7 @@ struct i2c_driver rt3261_i2c_driver = {
                .owner = THIS_MODULE,
        },
        .probe = rt3261_i2c_probe,
-       .remove   = __devexit_p(rt3261_i2c_remove),
+       .remove   = rt3261_i2c_remove,
        .shutdown = rt3261_i2c_shutdown,
        .id_table = rt3261_i2c_id,
 };
@@ -3420,148 +3747,3 @@ module_exit(rt3261_modexit);
 MODULE_DESCRIPTION("ASoC RT3261 driver");
 MODULE_AUTHOR("Johnny Hsu <johnnyhsu@realtek.com>");
 MODULE_LICENSE("GPL");
-
-
-#ifdef RT3261_PROC
-
-static ssize_t rt3261_proc_write(struct file *file, const char __user *buffer,
-               unsigned long len, void *data)
-{
-       char *cookie_pot; 
-       char *p;
-       int reg;
-       int i;
-       int value;
-       #if defined (CONFIG_SND_SOC_RT3261)
-       struct rt3261_dsp_param param;
-       #endif
-
-       cookie_pot = (char *)vmalloc( len );
-       if (!cookie_pot) 
-       {
-               return -ENOMEM;
-       } 
-       else 
-       {
-               if (copy_from_user( cookie_pot, buffer, len )) 
-                       return -EFAULT;
-       }
-
-       switch(cookie_pot[0])
-       {
-               case 'r':
-               case 'R':
-                       printk("Read reg debug\n");             
-                       if(cookie_pot[1] ==':')
-                       {
-                               strsep(&cookie_pot,":");
-                               while((p=strsep(&cookie_pot,",")))
-                               {
-                                       reg = simple_strtol(p,NULL,16);
-                                       value = rt3261_read(rt3261_codec,reg);
-                                       printk("rt3261_read:0x%04x = 0x%04x\n",reg,value);
-                               }
-                               printk("\n");
-                       }
-                       else
-                       {
-                               printk("Error Read reg debug.\n");
-                               printk("For example: echo r:22,23,24,25>rt3261_ts\n");
-                       }
-                       break;
-               case 'w':
-               case 'W':
-                       printk("Write reg debug\n");            
-                       if(cookie_pot[1] ==':')
-                       {
-                               strsep(&cookie_pot,":");
-                               while((p=strsep(&cookie_pot,"=")))
-                               {
-                                       reg = simple_strtol(p,NULL,16);
-                                       p=strsep(&cookie_pot,",");
-                                       value = simple_strtol(p,NULL,16);
-                                       rt3261_write(rt3261_codec,reg,value);
-                                       printk("rt3261_write:0x%04x = 0x%04x\n",reg,value);
-                               }
-                               printk("\n");
-                       }
-                       else
-                       {
-                               printk("Error Write reg debug.\n");
-                               printk("For example: w:22=0,23=0,24=0,25=0>rt3261_ts\n");
-                       }
-                       break;
-               case 'a':
-                       printk("Dump rt3261 index reg \n");             
-
-                       for (i = 0; i < 0xb4; i++) 
-                       {
-                               value = rt3261_index_read(rt3261_codec, i);
-                               printk("rt3261_index_read:0x%04x = 0x%04x\n",i,value);
-                       }
-                       break;  
-               #if defined (CONFIG_SND_SOC_RT3261)
-               case 'b':
-                       param.cmd_fmt =  0x00e0;
-                       param.cmd = RT3261_DSP_CMD_MW;
-                       printk("Write dsp reg debug\n");                
-                       if(cookie_pot[1] ==':')
-                       {
-                               strsep(&cookie_pot,":");
-                               while((p=strsep(&cookie_pot,"=")))
-                               {
-                                       param.addr = simple_strtol(p,NULL,16);
-                                       p=strsep(&cookie_pot,",");
-                                       param.data = simple_strtol(p,NULL,16);
-                                       rt3261_dsp_write(rt3261_codec,&param);
-                                       printk("rt3261_dsp_write:0x%04x = 0x%04x\n",param.addr,param.data);
-                               }
-                               printk("\n");
-                       }
-                       break;
-               case 'c':
-                       printk("Read dsp reg debug\n");         
-                       if(cookie_pot[1] ==':')
-                       {
-                               strsep(&cookie_pot,":");
-                               while((p=strsep(&cookie_pot,",")))
-                               {
-                                       reg = simple_strtol(p,NULL,16);
-                                       value = rt3261_dsp_read(rt3261_codec,reg);
-                                       printk("rt3261_dsp_read:0x%04x = 0x%04x\n",reg,value);
-                               }
-                               printk("\n");
-                       }
-                       break;
-               #endif
-               default:
-                       printk("Help for rt3261_ts .\n-->The Cmd list: \n");
-                       printk("-->'d&&D' Open or Off the debug\n");
-                       printk("-->'r&&R' Read reg debug,Example: echo 'r:22,23,24,25'>rt3261_ts\n");
-                       printk("-->'w&&W' Write reg debug,Example: echo 'w:22=0,23=0,24=0,25=0'>rt3261_ts\n");
-                       break;
-       }
-
-       return len;
-}
-
-static const struct file_operations rt3261_proc_fops = {
-       .owner          = THIS_MODULE,
-};
-
-static int rt3261_proc_init(void)
-{
-       struct proc_dir_entry *rt3261_proc_entry;
-       rt3261_proc_entry = create_proc_entry("driver/rt3261_ts", 0777, NULL);
-       if(rt3261_proc_entry != NULL)
-       {
-               rt3261_proc_entry->write_proc = rt3261_proc_write;
-               return 0;
-       }
-       else
-       {
-               printk("create proc error !\n");
-               return -1;
-       }
-}
-#endif