UPSTREAM: ASoC: da7219: Use logical instead of bitwise OR for boolean expression
[firefly-linux-kernel-4.4.55.git] / sound / soc / codecs / rk1000_codec.c
index d6b796a9acaffa483b158c500ad562da1050ad8d..8237ec0b86305837313fe32298435601831aa902 100755 (executable)
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#include <linux/vmalloc.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/regulator/consumer.h>
-#include <linux/slab.h>
 #include <sound/core.h>
-#include <sound/jack.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
+#include <sound/soc-dapm.h>
 #include <sound/initval.h>
-#include <sound/tlv.h>
-#include <trace/events/asoc.h>
-#include <mach/gpio.h>
-#include <mach/iomux.h>
-
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 #include "rk1000_codec.h"
-#define RK1000_CODEC_PROC
-#ifdef RK1000_CODEC_PROC
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/vmalloc.h>
-char debug_write_read = 0;
-#endif
+
+
 /*
  * Debug
  */
-#if 1
-#define        DBG(x...)       printk(KERN_INFO x)
+#define RK1000_CODEC_DBG 0
+#if RK1000_CODEC_DBG
+#define        DBG(x...)       pr_info(x)
 #else
 #define        DBG(x...)
 #endif
 
-#define err(format, arg...) \
-       printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg)
-#define info(format, arg...) \
-       printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
-       
-#define OUT_CAPLESS  (0)   //ÊÇ·ñΪÎÞµçÈÝÊä³ö£¬1:ÎÞµçÈÝÊä³ö£¬0:ÓеçÈÝÊä³ö      
+/*rk1000 codec proc debug*/
+#define RK1000_CODEC_PROC 1
 
-static struct snd_soc_codec *rk1000_codec_codec;
+#define HP_OUT 0
+#define HP_IN  1
+#define USE_MIC_IN
+#define USE_LPF
+
+#define FREQ441KHZ    (0x11 << 1)
+/* rk1000 output volume,DAC Digital Gain */
+/* 0x0000 ~ 0xF42 */
+#define VOLUME_OUTPUT 0xF42
+/* 0x0 ~ 0x3f(bit0-bit5)        max=0x0(+6DB) min=0x3f(-60DB)   Analog Gain */
+#define VOLUME_CODEC_PA 0x0
+
+/* rk1000 input volume,rk610 can not adjust the recording volume */
+#define VOLUME_INPUT 0x07
+
+#define OUT_CAPLESS  (1)
 
-//static u32 gVolReg = 0x0f;  ///0x0f; //ÓÃÓڼǼÒôÁ¿¼Ä´æÆ÷
-//static u32 gCodecVol = 0x0f;
-static u8 gR0AReg = 0;  //ÓÃÓڼǼR0A¼Ä´æÆ÷µÄÖµ£¬ÓÃÓڸıä²ÉÑùÂÊǰͨ¹ýR0AÍ£Ö¹clk
-static u8 gR0BReg = 0;  //ÓÃÓڼǼR0B¼Ä´æÆ÷µÄÖµ£¬ÓÃÓڸıä²ÉÑùÂÊǰͨ¹ýR0BÍ£Ö¹interplateºÍdecimation
-static u8 gR1314Reg = 0;  //ÓÃÓڼǼR13,R14¼Ä´æÆ÷µÄÖµ£¬ÓÃÓÚFMÒôÁ¿Îª0ʱ
+/* 1:set pll from rk1000 */
+#define RK1000_CTL_PLL 0
+
+static u8 g_r0_a_reg;
+static u8 g_r0_b_reg;
 
 /*
  * rk1000 register cache
@@ -80,48 +82,86 @@ static const u16 rk1000_codec_reg[] = {
        0x0000, 0x00ff, 0x00ff, 0x00ff,  /* 0x1a */
 };
 
+static struct snd_soc_codec *rk1000_codec_codec;
 /* codec private data */
 struct rk1000_codec_priv {
        enum snd_soc_control_type control_type;
-       void *control_data;
-       
        unsigned int sysclk;
        struct snd_soc_codec codec;
        struct snd_pcm_hw_constraint_list *sysclk_constraints;
        u16 reg_cache[RK1000_CODEC_NUM_REG];
+
+       struct delayed_work rk1000_delayed_work;
+       unsigned int spk_ctrl_io;
+       enum of_gpio_flags flags;
+       /*
+               Some amplifiers enable a longer time.
+               config after pa_enable_io delay pa_enable_time(ms)
+               so value range is 0 - 8000.
+       */
+       unsigned int pa_enable_time;
+       /* if found boot pop,set boot_depop 1 test */
+       int boot_depop;
+       int call_enable;
+       int headset_status;
 };
 
+
+static void spk_ctrl_fun(int status)
+{
+       struct rk1000_codec_priv *rk1000_codec;
+
+       if (rk1000_codec_codec == NULL)
+               return;
+       rk1000_codec = snd_soc_codec_get_drvdata(rk1000_codec_codec);
+       if (rk1000_codec == NULL)
+               return;
+       if (!rk1000_codec->spk_ctrl_io)
+               return;
+       DBG("%s:: spk status = %d\n", __func__, status);
+       if (status)
+               gpio_set_value(rk1000_codec->spk_ctrl_io,
+                              rk1000_codec->flags);
+       else
+               gpio_set_value(rk1000_codec->spk_ctrl_io,
+                              !rk1000_codec->flags);
+}
+
+
 /*
  * read rk1000 register cache
  */
-static inline unsigned int rk1000_codec_read_reg_cache(struct snd_soc_codec *codec,
-       unsigned int reg)
+static unsigned int rk1000_codec_read_reg_cache(struct snd_soc_codec *codec,
+                                               unsigned int reg)
 {
        u16 *cache = codec->reg_cache;
+
        if (reg > RK1000_CACHE_REGNUM)
                return -1;
        return cache[reg];
 }
 
-static unsigned int rk1000_codec_read(struct snd_soc_codec *codec, unsigned int r)
-{      
+static unsigned int rk1000_codec_read(struct snd_soc_codec *codec,
+                                     unsigned int r)
+{
        struct i2c_msg xfer[1];
-       u8 reg = r;
+       int reg;
        int ret;
-       struct i2c_client *client = codec->control_data;
+       struct i2c_client *i2c;
 
+       reg = r;
+       i2c = to_i2c_client(codec->dev);
        /* Read register */
-       xfer[0].addr = (client->addr& 0x60)|(reg);
+       xfer[0].addr = (i2c->addr & 0x60) | (reg);
        xfer[0].flags = I2C_M_RD;
        xfer[0].len = 1;
-       xfer[0].buf = &reg;
-       xfer[0].scl_rate = 100*1000;
-       ret = i2c_transfer(client->adapter, xfer, 1);
+       xfer[0].buf = (unsigned char *)&reg;
+       xfer[0].scl_rate = 100000;
+       ret = i2c_transfer(i2c->adapter, xfer, 1);
        if (ret != 1) {
-               dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
+               dev_err(&i2c->dev, "i2c_transfer() returned %d\n", ret);
                return 0;
        }
-
        return reg;
 }
 
@@ -129,143 +169,109 @@ static unsigned int rk1000_codec_read(struct snd_soc_codec *codec, unsigned int
  * write rk1000 register cache
  */
 static inline void rk1000_codec_write_reg_cache(struct snd_soc_codec *codec,
-       unsigned int reg, unsigned int value)
+                                               unsigned int reg,
+                                               unsigned int value)
 {
-       u16 *cache = codec->reg_cache;
+       u16 *cache;
+
+       cache = codec->reg_cache;
        if (reg > RK1000_CACHE_REGNUM)
                return;
        cache[reg] = value;
 }
 
 static int rk1000_codec_write(struct snd_soc_codec *codec, unsigned int reg,
-       unsigned int value)
+                             unsigned int value)
 {
+#ifdef CONFIG_MODEM_SOUND
+       struct rk1000_codec_priv *rk1000_codec;
+#endif
        u8 data[2];
        struct i2c_client *i2c;
-       DBG("Enter-%s::reg=0x%02X, value=0x%02X\n",__FUNCTION__, reg, value);
+
+       i2c = to_i2c_client(codec->dev);
+#ifdef CONFIG_MODEM_SOUND
+       rk1000_codec = snd_soc_codec_get_drvdata(rk1000_codec_codec);
+       if (rk1000_codec->call_enable)
+               return 0;
+#endif
+       DBG("Enter::%s, %d, reg=0x%02X, value=0x%02X\n", __func__,
+           __LINE__, reg, value);
        data[0] = value & 0x00ff;
-       rk1000_codec_write_reg_cache (codec, reg, value);
-       i2c = (struct i2c_client *)codec->control_data;
        i2c->addr = (i2c->addr & 0x60)|reg;
-       if (codec->hw_write(codec->control_data, data, 1) == 1){
-//                DBG("================%s Run OK====%d============\n",__FUNCTION__,__LINE__);
+       if (codec->hw_write(i2c, data, 1) == 1) {
+               DBG("====%s %d Run OK=======\n", __func__, __LINE__);
+               rk1000_codec_write_reg_cache(codec, reg, value);
                return 0;
-       }else{
-               DBG("================%s Run EIO=======%d=========\n",__FUNCTION__,__LINE__);
+       } else {
+               DBG("====%s %d Run EIO=====\n", __func__, __LINE__);
                return -EIO;
-        }
+       }
 }
 
-static const struct snd_kcontrol_new rk1000_codec_snd_controls[] = {
-
-SOC_DOUBLE_R("Capture Volume", ACCELCODEC_R0C, ACCELCODEC_R0D, 0, 15, 0),
-SOC_DOUBLE_R("Capture Switch", ACCELCODEC_R0C, ACCELCODEC_R0D, 7, 1, 1),
-
-SOC_DOUBLE_R("PCM Volume", ACCELCODEC_R0D, ACCELCODEC_R0E, 0, 7, 0),
-
-//SOC_SINGLE("Left ADC Capture Volume", ACCELCODEC_R17, 0, 63, 0),
-//SOC_SINGLE("Right ADC Capture Volume", ACCELCODEC_R18, 0, 63, 0),
-
-
-};
-
-
-/* Left Mixer */
-static const struct snd_kcontrol_new rk1000_codec_left_mixer_controls[] = {
-SOC_DAPM_SINGLE("Playback Switch", ACCELCODEC_R15, 6, 1, 0),
-SOC_DAPM_SINGLE("Left Bypass Switch", ACCELCODEC_R15, 2, 1, 0),
+#ifdef CONFIG_MODEM_SOUND
+static int rk1000_codec_write_incall(struct snd_soc_codec *codec,
+                                    unsigned int reg, unsigned int value)
+{
+       u8 data[2];
+       struct i2c_client *i2c;
 
-};
+       DBG("Enter::%s, %d, reg=0x%02X, value=0x%02X\n",
+           __func__, __LINE__, reg, value);
+       i2c = to_i2c_client(codec->dev);
+       data[0] = value & 0x00ff;
+       rk1000_codec_write_reg_cache(codec, reg, value);
+       i2c = (struct i2c_client *)codec->control_data;
+       i2c->addr = (i2c->addr & 0x60) | reg;
+       if (codec->hw_write(i2c, data, 1) == 1)
+               return 0;
+       else
+               return -EIO;
+}
 
-/* Right Mixer */
-static const struct snd_kcontrol_new rk1000_codec_right_mixer_controls[] = {
-SOC_DAPM_SINGLE("Playback Switch", ACCELCODEC_R15, 7, 1, 0),
-SOC_DAPM_SINGLE("Left Bypass Switch", ACCELCODEC_R15, 3, 1, 0),
+void call_set_spk(int on)
+{
+       struct rk1000_codec_priv *rk1000_codec;
 
-};
+       if (!rk1000_codec_codec)
+               return;
+       rk1000_codec = snd_soc_codec_get_drvdata(rk1000codec_codec);
+       if (!rk1000_codec)
+               return;
 
+       switch (on) {
+       case 0:
+               /* modem exit call,codec disable loopback */
+               DBG("%s modem exit call\n", __func__);
+               rk1000_codec_write_incall(rk1000_codec_codec,
+                                         ACCELCODEC_R0E, 0x80);
+               rk1000_codec->call_enable = 0;
+               break;
+       case 1:
+               /* modem calling,codec enable loopback,
+               * spk hp different volume */
+               DBG("%s spk incalling\n", __func__);
+               rk1000_codec->call_enable = 1;
+               rk1000_codec_write_incall(rk1000_codec_codec,
+                                         ACCELCODEC_R0E, 0x00);
+               return;
+       case 2:
+               DBG("%s hp incalling\n", __func__);
+               rk1000_codec->call_enable = 1;
+               rk1000_codec_write_incall(rk1000_codec_codec,
+                                         ACCELCODEC_R0E, 0x00);
+               break;
+       case 3:
+               DBG("%s bt incalling\n", __func__);
+               rk1000_codec->call_enable = 1;
+               rk1000_codec_write_incall(rk1000_codec_codec,
+                                         ACCELCODEC_R0E, 0x00);
+               break;
+       }
+}
+#endif
 
-static const struct snd_soc_dapm_widget rk1000_codec_dapm_widgets[] = {
-       SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
-               &rk1000_codec_left_mixer_controls[0],
-               ARRAY_SIZE(rk1000_codec_left_mixer_controls)),
-       SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
-               &rk1000_codec_right_mixer_controls[0],
-               ARRAY_SIZE(rk1000_codec_right_mixer_controls)),
-    
-       //SND_SOC_DAPM_PGA("Right Out 1", ACCELCODEC_R1E, 0, 0, NULL, 0),
-       //SND_SOC_DAPM_PGA("Left Out 1", ACCELCODEC_R1E, 1, 0, NULL, 0),
-       //SND_SOC_DAPM_DAC("Right DAC", "Right Playback", ACCELCODEC_R1F, 1, 0),
-       //SND_SOC_DAPM_DAC("Left DAC", "Left Playback", ACCELCODEC_R1F, 2, 0),
-    
-       SND_SOC_DAPM_ADC("ADC", "Capture", ACCELCODEC_R1D, 6, 1),
-       SND_SOC_DAPM_ADC("ADC BUFF", "Capture BUFF", ACCELCODEC_R1D, 2, 0),
-    
-     
-       SND_SOC_DAPM_OUTPUT("LOUT1"),
-       SND_SOC_DAPM_OUTPUT("ROUT1"),
-    
-       SND_SOC_DAPM_INPUT("LINPUT1"),
-       SND_SOC_DAPM_INPUT("RINPUT1"),
-};
 
-static const struct snd_soc_dapm_route audio_map[] = {
-       /* left mixer */
-       {"Left Mixer", "Playback Switch", "Left DAC"},
-       {"Left Mixer", "Left Bypass Switch", "Left Line Mux"},
-       {"Right Mixer", "Playback Switch", "Right DAC"},
-       {"Right Mixer", "Right Bypass Switch", "Right Line Mux"},
-    
-       /* left out 1 */
-       {"Left Out 1", NULL, "Left Mixer"},
-       {"LOUT1", NULL, "Left Out 1"},
-    
-    
-       /* right out 1 */
-       {"Right Out 1", NULL, "Right Mixer"},
-       {"ROUT1", NULL, "Right Out 1"},
-    
-       /* Left Line Mux */
-       {"Left Line Mux", "Line 1", "LINPUT1"},
-       {"Left Line Mux", "PGA", "Left PGA Mux"},
-       {"Left Line Mux", "Differential", "Differential Mux"},
-    
-       /* Right Line Mux */
-       {"Right Line Mux", "Line 1", "RINPUT1"},
-       {"Right Line Mux", "PGA", "Right PGA Mux"},
-       {"Right Line Mux", "Differential", "Differential Mux"},
-    
-       /* Left PGA Mux */
-       {"Left PGA Mux", "Line 1", "LINPUT1"},
-       {"Left PGA Mux", "Line 2", "LINPUT2"},
-       {"Left PGA Mux", "Line 3", "LINPUT3"},
-       {"Left PGA Mux", "Differential", "Differential Mux"},
-    
-       /* Right PGA Mux */
-       {"Right PGA Mux", "Line 1", "RINPUT1"},
-       {"Right PGA Mux", "Differential", "Differential Mux"},
-    
-       /* Differential Mux */
-       {"Differential Mux", "Line 1", "LINPUT1"},
-       {"Differential Mux", "Line 1", "RINPUT1"},
-    
-       /* Left ADC Mux */
-       {"Left ADC Mux", "Stereo", "Left PGA Mux"},
-       {"Left ADC Mux", "Mono (Left)", "Left PGA Mux"},
-       {"Left ADC Mux", "Digital Mono", "Left PGA Mux"},
-    
-       /* Right ADC Mux */
-       {"Right ADC Mux", "Stereo", "Right PGA Mux"},
-       {"Right ADC Mux", "Mono (Right)", "Right PGA Mux"},
-       {"Right ADC Mux", "Digital Mono", "Right PGA Mux"},
-    
-       /* ADC */
-       {"Left ADC", NULL, "Left ADC Mux"},
-       {"Right ADC", NULL, "Right ADC Mux"},
-    
-       /* terminator */
-       {NULL, NULL, NULL},
-};
 
 struct _coeff_div {
        u32 mclk;
@@ -279,62 +285,52 @@ struct _coeff_div {
 /* codec hifi mclk clock divider coefficients */
 static const struct _coeff_div coeff_div[] = {
        /* 8k */
-       {12288000, 8000, 1536, 0x6, 0x0,ASC_BCLKDIV_16},
-       {11289600, 8000, 1408, 0x16, 0x0,ASC_BCLKDIV_16},
-       {18432000, 8000, 2304, 0x7, 0x0,ASC_BCLKDIV_16},
-       {16934400, 8000, 2112, 0x17, 0x0,ASC_BCLKDIV_16},
-       {8192000, 8000, 1024, 0x0, 0x0,ASC_BCLKDIV_16},
-       {12000000, 8000, 1500, 0x6, 0x1,ASC_BCLKDIV_16},
-    
+       {12288000, 8000, 1536, 0x6, 0x0, ASC_BCLKDIV_16},
+       {11289600, 8000, 1408, 0x16, 0x0, ASC_BCLKDIV_16},
+       {18432000, 8000, 2304, 0x7, 0x0, ASC_BCLKDIV_16},
+       {16934400, 8000, 2112, 0x17, 0x0, ASC_BCLKDIV_16},
+       {8192000, 8000, 1024, 0x0, 0x0, ASC_BCLKDIV_16},
+       {12000000, 8000, 1500, 0x6, 0x1, ASC_BCLKDIV_16},
        /* 11.025k */
-       {11289600, 11025, 1024, 0x18, 0x0,ASC_BCLKDIV_16},
-       {16934400, 11025, 1536, 0x19, 0x0,ASC_BCLKDIV_16},
-       {12000000, 11025, 1088, 0x19, 0x1,ASC_BCLKDIV_16},
-    
-    /* 12k */
-       {12288000, 12000, 1024, 0x8, 0x0,ASC_BCLKDIV_16},
-       {18432000, 12000, 1536, 0x9, 0x0,ASC_BCLKDIV_16},
-       {12000000, 12000, 1000, 0x8, 0x1,ASC_BCLKDIV_16},
-    
+       {11289600, 11025, 1024, 0x18, 0x0, ASC_BCLKDIV_16},
+       {16934400, 11025, 1536, 0x19, 0x0, ASC_BCLKDIV_16},
+       {12000000, 11025, 1088, 0x19, 0x1, ASC_BCLKDIV_16},
+       /* 12k */
+       {12288000, 12000, 1024, 0x8, 0x0, ASC_BCLKDIV_16},
+       {18432000, 12000, 1536, 0x9, 0x0, ASC_BCLKDIV_16},
+       {12000000, 12000, 1000, 0x8, 0x1, ASC_BCLKDIV_16},
        /* 16k */
-       {12288000, 16000, 768, 0xa, 0x0,ASC_BCLKDIV_8},
-       {18432000, 16000, 1152, 0xb, 0x0,ASC_BCLKDIV_8},
-       {12000000, 16000, 750, 0xa, 0x1,ASC_BCLKDIV_8},
-    
+       {12288000, 16000, 768, 0xa, 0x0, ASC_BCLKDIV_8},
+       {18432000, 16000, 1152, 0xb, 0x0, ASC_BCLKDIV_8},
+       {12000000, 16000, 750, 0xa, 0x1, ASC_BCLKDIV_8},
        /* 22.05k */
-       {11289600, 22050, 512, 0x1a, 0x0,ASC_BCLKDIV_8},
-       {16934400, 22050, 768, 0x1b, 0x0,ASC_BCLKDIV_8},
-       {12000000, 22050, 544, 0x1b, 0x1,ASC_BCLKDIV_8},
-    
-    /* 24k */
-       {12288000, 24000, 512, 0x1c, 0x0,ASC_BCLKDIV_8},
-       {18432000, 24000, 768, 0x1d, 0x0,ASC_BCLKDIV_8},
-       {12000000, 24000, 500, 0x1c, 0x1,ASC_BCLKDIV_8},
-       
+       {11289600, 22050, 512, 0x1a, 0x0, ASC_BCLKDIV_8},
+       {16934400, 22050, 768, 0x1b, 0x0, ASC_BCLKDIV_8},
+       {12000000, 22050, 544, 0x1b, 0x1, ASC_BCLKDIV_8},
+       /* 24k */
+       {12288000, 24000, 512, 0x1c, 0x0, ASC_BCLKDIV_8},
+       {18432000, 24000, 768, 0x1d, 0x0, ASC_BCLKDIV_8},
+       {12000000, 24000, 500, 0x1c, 0x1, ASC_BCLKDIV_8},
        /* 32k */
-       {12288000, 32000, 384, 0xc, 0x0,ASC_BCLKDIV_8},
-       {18432000, 32000, 576, 0xd, 0x0,ASC_BCLKDIV_8},
-       {12000000, 32000, 375, 0xa, 0x1,ASC_BCLKDIV_8},
-    
+       {12288000, 32000, 384, 0xc, 0x0, ASC_BCLKDIV_8},
+       {18432000, 32000, 576, 0xd, 0x0, ASC_BCLKDIV_8},
+       {12000000, 32000, 375, 0xa, 0x1, ASC_BCLKDIV_8},
        /* 44.1k */
-       {11289600, 44100, 256, 0x10, 0x0,ASC_BCLKDIV_8},
-       {16934400, 44100, 384, 0x11, 0x0,ASC_BCLKDIV_8},
-       {12000000, 44100, 272, 0x11, 0x1,ASC_BCLKDIV_8},
-    
+       {11289600, 44100, 256, 0x10, 0x0, ASC_BCLKDIV_4},
+       {16934400, 44100, 384, 0x11, 0x0, ASC_BCLKDIV_8},
+       {12000000, 44100, 272, 0x11, 0x1, ASC_BCLKDIV_8},
        /* 48k */
-       {12288000, 48000, 256, 0x0, 0x0,ASC_BCLKDIV_4},
-       {18432000, 48000, 384, 0x1, 0x0,ASC_BCLKDIV_4},
-       {12000000, 48000, 250, 0x0, 0x1,ASC_BCLKDIV_4},
-    
+       {12288000, 48000, 256, 0x0, 0x0, ASC_BCLKDIV_4},
+       {18432000, 48000, 384, 0x1, 0x0, ASC_BCLKDIV_4},
+       {12000000, 48000, 250, 0x0, 0x1, ASC_BCLKDIV_4},
        /* 88.2k */
-       {11289600, 88200, 128, 0x1e, 0x0,ASC_BCLKDIV_4},
-       {16934400, 88200, 192, 0x1f, 0x0,ASC_BCLKDIV_4},
-       {12000000, 88200, 136, 0x1f, 0x1,ASC_BCLKDIV_4},
-    
+       {11289600, 88200, 128, 0x1e, 0x0, ASC_BCLKDIV_4},
+       {16934400, 88200, 192, 0x1f, 0x0, ASC_BCLKDIV_4},
+       {12000000, 88200, 136, 0x1f, 0x1, ASC_BCLKDIV_4},
        /* 96k */
-       {12288000, 96000, 128, 0xe, 0x0,ASC_BCLKDIV_4},
-       {18432000, 96000, 192, 0xf, 0x0,ASC_BCLKDIV_4},
-       {12000000, 96000, 125, 0xe, 0x1,ASC_BCLKDIV_4},
+       {12288000, 96000, 128, 0xe, 0x0, ASC_BCLKDIV_4},
+       {18432000, 96000, 192, 0xf, 0x0, ASC_BCLKDIV_4},
+       {12000000, 96000, 125, 0xe, 0x1, ASC_BCLKDIV_4},
 };
 
 static inline int get_coeff(int mclk, int rate)
@@ -345,7 +341,6 @@ static inline int get_coeff(int mclk, int rate)
                if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
                        return i;
        }
-
        return -EINVAL;
 }
 
@@ -379,17 +374,50 @@ static struct snd_pcm_hw_constraint_list constraints_12 = {
        .list   = rates_12,
 };
 
+static int rk1000_codec_set_bias_level(struct snd_soc_codec *codec,
+                                      enum snd_soc_bias_level level)
+{
+       DBG("Enter::%s----%d now_level =%d  old_level = %d\n",
+           __func__, __LINE__, level, codec->dapm.bias_level);
+       switch (level) {
+       case SND_SOC_BIAS_ON:
+               break;
+       case SND_SOC_BIAS_PREPARE:
+               rk1000_codec_write(codec, ACCELCODEC_R1D, 0x2a);
+               rk1000_codec_write(codec, ACCELCODEC_R1E, 0x40);
+               rk1000_codec_write(codec, ACCELCODEC_R1F, 0x49);
+               /*VREF, VMID=2x50k, digital enabled */
+               break;
+
+       case SND_SOC_BIAS_STANDBY:
+               DBG("rk1000 standby\n");
+               rk1000_codec_write(codec, ACCELCODEC_R1D, 0x2a);
+               rk1000_codec_write(codec, ACCELCODEC_R1E, 0x40);
+               rk1000_codec_write(codec, ACCELCODEC_R1F, 0x49);
+               break;
+
+       case SND_SOC_BIAS_OFF:
+               DBG("rk1000 power off\n");
+               spk_ctrl_fun(GPIO_LOW);
+               rk1000_codec_write(codec, ACCELCODEC_R1D, 0xFF);
+               rk1000_codec_write(codec, ACCELCODEC_R1E, 0xFF);
+               rk1000_codec_write(codec, ACCELCODEC_R1F, 0xFF);
+               break;
+       }
+       codec->dapm.bias_level = level;
+       return 0;
+}
 /*
  * Note that this should be called from init rather than from hw_params.
  */
 static int rk1000_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai,
-               int clk_id, unsigned int freq, int dir)
+                                      int clk_id, unsigned int freq, int dir)
 {
        struct snd_soc_codec *codec = codec_dai->codec;
-       struct rk1000_codec_priv *rk1000_codec = snd_soc_codec_get_drvdata(codec);
-       
-       DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
-       freq = 12000000;        
+       struct rk1000_codec_priv *rk1000_codec;
+
+       DBG("Enter::%s----%d\n", __func__, __LINE__);
+       rk1000_codec = snd_soc_codec_get_drvdata(codec);
        switch (freq) {
        case 11289600:
        case 18432000:
@@ -417,23 +445,27 @@ static int rk1000_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 }
 
 static int rk1000_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
-               unsigned int fmt)
+                                   unsigned int fmt)
 {
        struct snd_soc_codec *codec = codec_dai->codec;
+       struct rk1000_codec_priv *rk1000_codec;
        u16 iface = 0;
 
+       rk1000_codec = snd_soc_codec_get_drvdata(codec);
+       /* setup Vmid and Vref, other module power down */
+       rk1000_codec_write(codec, ACCELCODEC_R1D, 0x2a);
+       rk1000_codec_write(codec, ACCELCODEC_R1E, 0x40);
        /* set master/slave audio interface */
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBM_CFM:
                iface = 0x0040;
                break;
        case SND_SOC_DAIFMT_CBS_CFS:
-               iface = 0x0020;
+               iface = 0x0000;
                break;
        default:
                return -EINVAL;
        }
-
        /* interface format */
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
@@ -453,7 +485,6 @@ static int rk1000_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
        default:
                return -EINVAL;
        }
-
        /* clock inversion */
        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
        case SND_SOC_DAIFMT_NB_NF:
@@ -470,223 +501,129 @@ static int rk1000_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
        default:
                return -EINVAL;
        }
-
-       DBG("Enter::%s----%d  iface=%x\n",__FUNCTION__,__LINE__,iface);
+       DBG("Enter::%s----%d  iface=%x\n", __func__, __LINE__, iface);
        rk1000_codec_write(codec, ACCELCODEC_R09, iface);
        return 0;
 }
 
-static int rk1000_codec_pcm_startup(struct snd_pcm_substream *substream,
-                             struct snd_soc_dai *dai)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_codec *codec = rtd->codec;
-       struct rk1000_codec_priv *rk1000_codec = snd_soc_codec_get_drvdata(codec);
-       
-       /* The set of sample rates that can be supported depends on the
-        * MCLK supplied to the CODEC - enforce this.
-        */
-       DBG("Enter::%s----%d  rk1000_codec->sysclk=%d\n",__FUNCTION__,__LINE__,rk1000_codec->sysclk); 
-//     if (!rk1000_codec->sysclk) {
-//             dev_err(codec->dev,
-//                     "No MCLK configured, call set_sysclk() on init\n");
-//             return -EINVAL;
-//     }
-
-#if 0
-    snd_pcm_hw_constraint_list(substream->runtime, 0,
-                                  SNDRV_PCM_HW_PARAM_RATE,
-                                  rk1000_codec->sysclk_constraints);
-#endif
-       return 0;
-}
+
 
 static int rk1000_codec_pcm_hw_params(struct snd_pcm_substream *substream,
-                               struct snd_pcm_hw_params *params,
-                               struct snd_soc_dai *dai)
+                                     struct snd_pcm_hw_params *params,
+                                     struct snd_soc_dai *dai)
 {
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_codec *codec = rtd->codec;
-       struct rk1000_codec_priv *rk1000_codec = snd_soc_codec_get_drvdata(codec);
-       
-       u16 iface = rk1000_codec_read_reg_cache(codec, ACCELCODEC_R09) & 0x1f3;
-       u16 srate = rk1000_codec_read_reg_cache(codec, ACCELCODEC_R00) & 0x180;
+       u16 iface;
        int coeff;
-
-       rk1000_codec->sysclk = 12000000;
-       /*by Vincent Hsiung for EQ Vol Change*/
-       #define HW_PARAMS_FLAG_EQVOL_ON 0x21
-       #define HW_PARAMS_FLAG_EQVOL_OFF 0x22
-       if (params->flags == HW_PARAMS_FLAG_EQVOL_ON)
-       {
-               u16 r17 = rk1000_codec_read_reg_cache(codec, ACCELCODEC_R17);
-               u16 r18 = rk1000_codec_read_reg_cache(codec, ACCELCODEC_R18);
-               
-               r17 &= (~0x3f); //6db
-               r18 &= (~0x3f); //6db
-               
-               rk1000_codec_write(codec, ACCELCODEC_R17, r17);
-               rk1000_codec_write(codec, ACCELCODEC_R18, r18);
-               
-               return 0;
-       }
-       else if (params->flags == HW_PARAMS_FLAG_EQVOL_OFF)
-       {
-               u16 r17 = rk1000_codec_read_reg_cache(codec, ACCELCODEC_R17);
-               u16 r18 = rk1000_codec_read_reg_cache(codec, ACCELCODEC_R18);
-               
-               r17 &= (~0x3f); 
-               r17 |= 0x0f; //0db
-               
-               r18 &= (~0x3f); 
-               r18 |= 0x0f; //0db
-               
-               rk1000_codec_write(codec, ACCELCODEC_R17, r17);
-               rk1000_codec_write(codec, ACCELCODEC_R18, r18);
-               return 0;
-       } 
-       
-       coeff = get_coeff(rk1000_codec->sysclk, params_rate(params));
-
-       /* bit size */
-       switch (params_format(params)) {
-       case SNDRV_PCM_FORMAT_S16_LE:
-               break;
-       case SNDRV_PCM_FORMAT_S20_3LE:
-               iface |= 0x0004;
-               break;
-       case SNDRV_PCM_FORMAT_S24_LE:
-               iface |= 0x0008;
-               break;
-       case SNDRV_PCM_FORMAT_S32_LE:
-               iface |= 0x000c;
-               break;
-       }
-       DBG("Enter::%s----%d  iface=%x srate =%x rate=%d\n",__FUNCTION__,__LINE__,iface,srate,params_rate(params));
-       
-       rk1000_codec_write(codec,ACCELCODEC_R0C, 0x17);  
-       rk1000_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF);   //soft mute
-       //±ØÐëÏȽ«clkºÍEN_INT¶¼disableµô£¬·ñÔòÇл»bclk·ÖƵֵ¿ÉÄܵ¼ÖÂcodecÄÚ²¿Ê±Ðò»ìÂÒµô£¬
-       //±íÏÖ³öÀ´µÄÏÖÏóÊÇ£¬ÒÔºóµÄÒôÀÖ¶¼±ä³ÉÁËÔëÒô£¬¶øÇÒ¾ÍËã°ÑÊäÈëcodecµÄI2S_DATAOUT¶Ï¿ªÒ²Ò»Ñù³öÔëÒô
-       rk1000_codec_write(codec,ACCELCODEC_R0B, ASC_DEC_DISABLE|ASC_INT_DISABLE);  //0x00
-       
+       struct snd_soc_pcm_runtime *rtd;
+       struct snd_soc_codec *codec;
+       unsigned int dai_fmt;
+
+       rtd = substream->private_data;
+       codec = rtd->codec;
+       dai_fmt = rtd->card->dai_link[0].dai_fmt;
+       iface = rk1000_codec_read_reg_cache(codec, ACCELCODEC_R09) & 0x1f3;
+       coeff = 0;
+       rk1000_codec_write(codec, ACCELCODEC_R0C, 0x17);
+       rk1000_codec_write(codec, ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|
+                          ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF);
+       rk1000_codec_write(codec, ACCELCODEC_R0B,
+                          ASC_DEC_DISABLE|ASC_INT_DISABLE);
        /* set iface & srate */
+       if ((dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
+               iface |= ASC_INVERT_BCLK;
        rk1000_codec_write(codec, ACCELCODEC_R09, iface);
        if (coeff >= 0)
-       {
-       //      rk1000_codec_write(codec, ACCELCODEC_R0A, (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb|ASC_CLKNODIV|ASC_CLK_ENABLE);
                rk1000_codec_write(codec, ACCELCODEC_R0A, 0xa0);
-       //      rk1000_codec_write(codec, ACCELCODEC_R00, srate|coeff_div[coeff].bclk);
-       }               
-       rk1000_codec_write(codec,ACCELCODEC_R0B, gR0BReg);
-       
+       rk1000_codec_write(codec, ACCELCODEC_R0B, g_r0_b_reg);
        return 0;
 }
 
-void PhaseOut(struct snd_soc_codec *codec,u32 nStep, u32 us)
-{
-        DBG("%s[%d]\n",__FUNCTION__,__LINE__); 
-        rk1000_codec_write(codec,ACCELCODEC_R17, 0x00|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN);  //AOL
-        rk1000_codec_write(codec,ACCELCODEC_R18, 0x00|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN);  //AOR
-        udelay(us);
-}
 
-void PhaseIn(struct snd_soc_codec *codec,u32 nStep, u32 us)
-{
-        DBG("%s[%d]\n",__FUNCTION__,__LINE__); 
-        rk1000_codec_write(codec,ACCELCODEC_R17, 0x00|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN);  //AOL gVolReg|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN);  //AOL
-        rk1000_codec_write(codec,ACCELCODEC_R18, 0x00|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN); //gVolReg|ASC_OUTPUT_ACTIVE|ASC_CROSSZERO_EN);  //AOR
-        udelay(us);
-}
 
 static int rk1000_codec_mute(struct snd_soc_dai *dai, int mute)
 {
        struct snd_soc_codec *codec = dai->codec;
+       struct rk1000_codec_priv *rk1000_codec;
 
-       DBG("Enter::%s----%d--mute=%d\n",__FUNCTION__,__LINE__,mute);
-    
-       if (mute)
-       {
-               PhaseOut(codec,1, 5000);
-               rk1000_codec_write(codec,ACCELCODEC_R19, 0xFF);  //AOM
-               rk1000_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF);  //soft mute   
-       }
-       else
-       {               
-               rk1000_codec_write(codec,ACCELCODEC_R1D, 0x2a);  //setup Vmid and Vref, other module power down
-               rk1000_codec_write(codec,ACCELCODEC_R1E, 0x40);  ///|ASC_PDASDML_ENABLE);
-               rk1000_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE);  ///|ASC_PDMICB_ENABLE|ASC_PDMIXM_ENABLE);
-               PhaseIn(codec,1, 5000);
-       //      if(gCodecVol != 0)
-               {
-                       rk1000_codec_write(codec,ACCELCODEC_R04, ASC_INT_ACTIVE_L|ASC_INT_ACTIVE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF);
-        }
-               rk1000_codec_write(codec,ACCELCODEC_R19, 0x7F);  //AOM
-               #if 0
-               /*disable speaker */
-               rockchip_mux_api_set(SPK_IOMUX_PIN_NAME, SPK_IOMUX_PIN_DIR);
-               GPIOSetPinDirection(SPK_CTRL_PIN,GPIO_OUT);
-               GPIOSetPinLevel(SPK_CTRL_PIN,GPIO_HIGH);
+       DBG("Enter::%s----%d--mute=%d\n", __func__, __LINE__, mute);
+       rk1000_codec = snd_soc_codec_get_drvdata(codec);
+       if (mute) {
+               /* AOL */
+               rk1000_codec_write(codec, ACCELCODEC_R17, 0xFF);
+               /* AOR */
+               rk1000_codec_write(codec, ACCELCODEC_R18, 0xFF);
+               /* AOM */
+               rk1000_codec_write(codec, ACCELCODEC_R19, 0xFF);
+               /* soft mute */
+               rk1000_codec_write(codec, ACCELCODEC_R04, ASC_INT_MUTE_L|
+                                  ASC_INT_MUTE_R | ASC_SIDETONE_L_OFF |
+                                  ASC_SIDETONE_R_OFF);
+       } else {
+               /* setup Vmid and Vref, other module power down */
+               rk1000_codec_write(codec, ACCELCODEC_R1D, 0x2a);
+               rk1000_codec_write(codec, ACCELCODEC_R1E, 0x40);
+               /* AOL */
+               rk1000_codec_write(codec, ACCELCODEC_R17, VOLUME_CODEC_PA |
+                                  ASC_OUTPUT_ACTIVE | ASC_CROSSZERO_EN);
+               /* AOR */
+               rk1000_codec_write(codec, ACCELCODEC_R18, VOLUME_CODEC_PA |
+                                  ASC_OUTPUT_ACTIVE | ASC_CROSSZERO_EN);
+               rk1000_codec_write(codec, ACCELCODEC_R04, ASC_INT_ACTIVE_L|
+                                  ASC_INT_ACTIVE_R | ASC_SIDETONE_L_OFF|
+                                  ASC_SIDETONE_R_OFF);
+               /* AOM */
+               rk1000_codec_write(codec, ACCELCODEC_R19, 0x7F);
+               #if OUT_CAPLESS
+               rk1000_codec_write(codec, ACCELCODEC_R1F, 0x09|
+                                  ASC_PDMIXM_ENABLE);
+               #else
+               rk1000_codec_write(codec, ACCELCODEC_R1F, 0x09|
+                                  ASC_PDMIXM_ENABLE | ASC_PDPAM_ENABLE);
                #endif
        }
        return 0;
 }
 
-static int rk1000_codec_set_bias_level(struct snd_soc_codec *codec,
-                                enum snd_soc_bias_level level)
+static void rk1000_delayedwork_fun(struct work_struct *work)
 {
-       u16 pwr_reg = rk1000_codec_read_reg_cache(codec, ACCELCODEC_R1D) & ~0x1c1;
-       DBG("Enter::%s----%d level =%d\n",__FUNCTION__,__LINE__,level);
-       switch (level) {
-       case SND_SOC_BIAS_ON:
-               break;
-
-       case SND_SOC_BIAS_PREPARE:
-               /* VREF, VMID=2x50k, digital enabled */
-               rk1000_codec_write(codec, ACCELCODEC_R1D, pwr_reg | 0x0080);
-               break;
-
-       case SND_SOC_BIAS_STANDBY:
-               if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
-                       /* VREF, VMID=2x5k */
-                       rk1000_codec_write(codec, ACCELCODEC_R1D, pwr_reg | 0x0080);
-
-                       /* Charge caps */
-                       msleep(100);
-               }
-
-               /* VREF, VMID=2*500k, digital stopped */
-               rk1000_codec_write(codec, ACCELCODEC_R1D, pwr_reg | 0x0080);
-               break;
+       struct snd_soc_codec *codec;
+       struct rk1000_codec_priv *rk1000_codec;
 
-       case SND_SOC_BIAS_OFF:
-               rk1000_codec_write(codec, ACCELCODEC_R1D, 0x0000);
-               break;
+       DBG("--------%s----------\n", __func__);
+       codec = rk1000_codec_codec;
+       rk1000_codec = snd_soc_codec_get_drvdata(codec);
+       if (!rk1000_codec->boot_depop) {
+               #if OUT_CAPLESS
+               rk1000_codec_write(codec, ACCELCODEC_R1F,
+                                  0x09 | ASC_PDMIXM_ENABLE);
+               #else
+               rk1000_codec_write(codec, ACCELCODEC_R1F,
+                                  0x09 | ASC_PDMIXM_ENABLE | ASC_PDPAM_ENABLE);
+               #endif
        }
-       codec->dapm.bias_level = level;
-       return 0;
+       spk_ctrl_fun(GPIO_HIGH);
 }
 
-#define RK1000_CODEC_RATES SNDRV_PCM_RATE_8000_96000
 
-#define RK1000_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
-       SNDRV_PCM_FMTBIT_S24_LE)
 
 static struct snd_soc_dai_ops rk1000_codec_ops = {
-       .startup = rk1000_codec_pcm_startup,
        .hw_params = rk1000_codec_pcm_hw_params,
        .set_fmt = rk1000_codec_set_dai_fmt,
        .set_sysclk = rk1000_codec_set_dai_sysclk,
        .digital_mute = rk1000_codec_mute,
 };
 
+#define RK1000_CODEC_RATES SNDRV_PCM_RATE_8000_192000
+#define RK1000_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
+                               SNDRV_PCM_FMTBIT_S20_3LE |\
+                               SNDRV_PCM_FMTBIT_S24_LE)
 static struct snd_soc_dai_driver rk1000_codec_dai[] = {
        {
                .name = "rk1000_codec",
                .playback = {
                        .stream_name = "Playback",
                        .channels_min = 1,
-                       .channels_max = 2,
+                       .channels_max = 8,
                        .rates = RK1000_CODEC_RATES,
                        .formats = RK1000_CODEC_FORMATS,
                },
@@ -702,212 +639,224 @@ static struct snd_soc_dai_driver rk1000_codec_dai[] = {
        }
 };
 
-static int rk1000_codec_suspend(struct snd_soc_codec *codec, pm_message_t state)
-{
-       DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
-       rk1000_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
-       return 0;
-}
 
-static int rk1000_codec_resume(struct snd_soc_codec *codec)
+void rk1000_codec_reg_set(void)
 {
-       int i;
-       u8 data[2];
-       struct i2c_client *i2c;
-       u16 *cache = codec->reg_cache;
-       
-       DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
-       /* Sync reg_cache with the hardware */
-       for (i = 0; i < RK1000_CODEC_NUM_REG; i++) {
-               data[0] = cache[i] & 0x00ff;
-               i2c = (struct i2c_client *)codec->control_data;
-               i2c->addr = (i2c->addr & 0x60)|i;
-               codec->hw_write(codec->control_data, data, 1);
+       struct snd_soc_codec *codec;
+       struct rk1000_codec_priv *rk1000_codec;
+       unsigned int digital_gain;
+       unsigned int mic_vol;
+
+       mic_vol = VOLUME_INPUT;
+       codec = rk1000_codec_codec;
+       rk1000_codec = snd_soc_codec_get_drvdata(codec);
+       rk1000_codec_write(codec, ACCELCODEC_R1D, 0x30);
+       rk1000_codec_write(codec, ACCELCODEC_R1E, 0x40);
+#ifdef USE_LPF
+       /*Route R-LPF->R-Mixer, L-LPF->L-Mixer*/
+       rk1000_codec_write(codec, ACCELCODEC_R15, 0xC1);
+#else
+       /*Route RDAC->R-Mixer, LDAC->L->Mixer*/
+       rk1000_codec_write(codec, ACCELCODEC_R15, 0x0C);
+#endif
+       /*With Cap Output, VMID ramp up slow*/
+       rk1000_codec_write(codec, ACCELCODEC_R1A, 0x14);
+       mdelay(10);
+       rk1000_codec_write(codec, ACCELCODEC_R0C, 0x10 | ASC_INPUT_VOL_0DB);
+       rk1000_codec_write(codec, ACCELCODEC_R0D, 0x10 | ASC_INPUT_VOL_0DB);
+#ifdef USE_MIC_IN
+       if (mic_vol > 0x07) {
+               /*Select MIC input*/
+               rk1000_codec_write(codec, ACCELCODEC_R12,
+                                  0x4c | ASC_MIC_INPUT | ASC_MIC_BOOST_20DB);
+               mic_vol -= 0x07;
+       } else
+               /*Select MIC input*/
+               rk1000_codec_write(codec, ACCELCODEC_R12, 0x4c | ASC_MIC_INPUT);
+       /*use default value*/
+       rk1000_codec_write(codec, ACCELCODEC_R1C, ASC_DEM_ENABLE);
+#else
+       /*Select Line input*/
+       rk1000_codec_write(codec, ACCELCODEC_R12, 0x4c);
+#endif
+       rk1000_codec_write(codec, ACCELCODEC_R0E, 0x10|mic_vol);
+       /*Diable route PGA->R/L Mixer, PGA gain 0db.*/
+       rk1000_codec_write(codec, ACCELCODEC_R13, 0x05 | 0 << 3);
+       rk1000_codec_write(codec, ACCELCODEC_R14, 0x05 | 0 << 3);
+       /*2soft mute*/
+       rk1000_codec_write(codec, ACCELCODEC_R04,
+                          ASC_INT_MUTE_L | ASC_INT_MUTE_R |
+                          ASC_SIDETONE_L_OFF | ASC_SIDETONE_R_OFF);
+       /*2set default SR and clk*/
+       rk1000_codec_write(codec, ACCELCODEC_R0A, FREQ441KHZ | ASC_NORMAL_MODE |
+                          (0x10 << 1) | ASC_CLKNODIV | ASC_CLK_ENABLE);
+       g_r0_a_reg = ASC_NORMAL_MODE | (0x10 << 1) |
+                    ASC_CLKNODIV | ASC_CLK_DISABLE;
+       /*2Config audio  interface*/
+       rk1000_codec_write(codec, ACCELCODEC_R09, ASC_I2S_MODE |
+                          ASC_16BIT_MODE | ASC_NORMAL_LRCLK |
+                          ASC_LRSWAP_DISABLE | ASC_NORMAL_BCLK);
+       rk1000_codec_write(codec, ACCELCODEC_R00, ASC_HPF_ENABLE
+                          | ASC_DSM_MODE_ENABLE | ASC_SCRAMBLE_ENABLE
+                          | ASC_DITHER_ENABLE | ASC_BCLKDIV_4);
+       /*2volume,input,output*/
+       digital_gain = VOLUME_OUTPUT;
+       if (rk1000_codec_read(codec, ACCELCODEC_R05) != 0x0f) {
+               rk1000_codec_write(codec, ACCELCODEC_R05,
+                                  (digital_gain >> 8) & 0xFF);
+               rk1000_codec_write(codec, ACCELCODEC_R06, digital_gain & 0xFF);
+       }
+       if (rk1000_codec_read(codec, ACCELCODEC_R07) != 0x0f) {
+               rk1000_codec_write(codec, ACCELCODEC_R07,
+                                  (digital_gain >> 8) & 0xFF);
+               rk1000_codec_write(codec, ACCELCODEC_R08, digital_gain & 0xFF);
+       }
+       rk1000_codec_write(codec, ACCELCODEC_R0B,
+                          ASC_DEC_ENABLE | ASC_INT_ENABLE);
+       g_r0_b_reg = ASC_DEC_ENABLE | ASC_INT_ENABLE;
+       if (rk1000_codec->boot_depop) {
+               #if OUT_CAPLESS
+               rk1000_codec_write(codec, ACCELCODEC_R1F,
+                                  0x09 | ASC_PDMIXM_ENABLE);
+               #else
+               rk1000_codec_write(codec, ACCELCODEC_R1F, 0x09 |
+                                  ASC_PDMIXM_ENABLE | ASC_PDPAM_ENABLE);
+               #endif
        }
+       rk1000_codec_write(codec, ACCELCODEC_R17, VOLUME_CODEC_PA |
+                          ASC_OUTPUT_ACTIVE | ASC_CROSSZERO_EN);
+       rk1000_codec_write(codec, ACCELCODEC_R18, VOLUME_CODEC_PA |
+                          ASC_OUTPUT_ACTIVE | ASC_CROSSZERO_EN);
+       rk1000_codec_write(codec, ACCELCODEC_R04, ASC_INT_ACTIVE_L |
+                          ASC_INT_ACTIVE_R | ASC_SIDETONE_L_OFF |
+                          ASC_SIDETONE_R_OFF);
+       rk1000_codec_write(codec, ACCELCODEC_R19, 0x7F);
+}
 
-       rk1000_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
+static int rk1000_codec_suspend(struct snd_soc_codec *codec)
+{
+       DBG("Enter::%s----%d\n", __func__, __LINE__);
+       spk_ctrl_fun(GPIO_LOW);
+       rk1000_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
        return 0;
 }
 
-static void rk1000_reg_init(struct snd_soc_codec *codec)
+static int rk1000_codec_resume(struct snd_soc_codec *codec)
 {
-       rk1000_codec_write(codec,ACCELCODEC_R1D, 0x00);
-    rk1000_codec_write(codec,ACCELCODEC_R17, 0xFF);  //AOL
-    rk1000_codec_write(codec,ACCELCODEC_R18, 0xFF);  //AOR
-    rk1000_codec_write(codec,ACCELCODEC_R19, 0xFF);  //AOM
-
-    rk1000_codec_write(codec,ACCELCODEC_R1F, 0xDF);
-    mdelay(10);
-    rk1000_codec_write(codec,ACCELCODEC_R1F, 0x5F);
-    rk1000_codec_write(codec,ACCELCODEC_R19, 0x7F);  //AOM
-    rk1000_codec_write(codec,ACCELCODEC_R15, 0xC1);//rk1000_codec_write(codec,ACCELCODEC_R15, 0xCD);//by Vincent Hsiung
-    rk1000_codec_write(codec,ACCELCODEC_R1A, 0x1C);
-    mdelay(100);
-    rk1000_codec_write(codec,ACCELCODEC_R1F, 0x09);
-    rk1000_codec_write(codec,ACCELCODEC_R1E, 0x00);
-    mdelay(10);
-    rk1000_codec_write(codec,ACCELCODEC_R1A, 0x14);
-    rk1000_codec_write(codec,ACCELCODEC_R1D, 0xFE);
-    rk1000_codec_write(codec,ACCELCODEC_R17, 0xBF);  //AOL
-    rk1000_codec_write(codec,ACCELCODEC_R18, 0xBF);  //AOR
-    rk1000_codec_write(codec,ACCELCODEC_R19, 0x7F);  //AOM
-    rk1000_codec_write(codec,ACCELCODEC_R1F, 0xDF);
-
-    //2soft mute
-    rk1000_codec_write(codec,ACCELCODEC_R04, ASC_INT_MUTE_L|ASC_INT_MUTE_R|ASC_SIDETONE_L_OFF|ASC_SIDETONE_R_OFF);   //soft mute
-    
-    //2set default SR and clk
-    rk1000_codec_write(codec,ACCELCODEC_R0A, ASC_USB_MODE|FREQ48kHz|ASC_CLKNODIV|ASC_CLK_DISABLE);
-    gR0AReg = ASC_USB_MODE|FREQ48kHz|ASC_CLKNODIV|ASC_CLK_DISABLE;
-    //2Config audio  interface
-    rk1000_codec_write(codec,ACCELCODEC_R09, ASC_I2S_MODE|ASC_16BIT_MODE|ASC_NORMAL_LRCLK|ASC_LRSWAP_DISABLE|ASC_MASTER_MODE|ASC_NORMAL_BCLK);
-    rk1000_codec_write(codec,ACCELCODEC_R00, ASC_HPF_ENABLE|ASC_DSM_MODE_DISABLE|ASC_SCRAMBLE_ENABLE|ASC_DITHER_ENABLE|ASC_BCLKDIV_8);  //BCLK div 8
-    //2volume,input,outpu
-    rk1000_codec_write(codec,ACCELCODEC_R05, 0x0e);
-    rk1000_codec_write(codec,ACCELCODEC_R06, 0x42);
-    rk1000_codec_write(codec,ACCELCODEC_R07, 0x0e);
-    rk1000_codec_write(codec,ACCELCODEC_R08, 0x42);
-    
-    rk1000_codec_write(codec,ACCELCODEC_R0C, 0x10|ASC_INPUT_VOL_0DB|ASC_INPUT_MUTE);   //LIL
-    rk1000_codec_write(codec,ACCELCODEC_R0D, 0x10|ASC_INPUT_VOL_0DB);   //LIR
-    rk1000_codec_write(codec,ACCELCODEC_R0E, 0x10|ASC_INPUT_VOL_0DB);   //MIC
-    rk1000_codec_write(codec,ACCELCODEC_R12, 0x4c|ASC_MIC_INPUT|ASC_MIC_BOOST_20DB);  //mic input and boost 20dB
-    rk1000_codec_write(codec,ACCELCODEC_R13, ASC_LPGAMX_DISABLE|ASC_ALMX_DISABLE|((LINE_2_MIXER_GAIN & 0x7) << 4)|0x0);
-    rk1000_codec_write(codec,ACCELCODEC_R14, ASC_RPGAMX_DISABLE|ASC_ARMX_DISABLE|((LINE_2_MIXER_GAIN & 0x7) << 4)|0x0);
-    gR1314Reg = ASC_RPGAMX_DISABLE|ASC_ARMX_DISABLE|((LINE_2_MIXER_GAIN & 0x7) << 4)|0x0;
-
-    //2other
-    rk1000_codec_write(codec,ACCELCODEC_R0B, ASC_DEC_DISABLE|ASC_INT_DISABLE);  //0x00
-    gR0BReg = ASC_DEC_DISABLE|ASC_INT_DISABLE;
-    rk1000_codec_write(codec,ACCELCODEC_R15, \
-                    0x01|ASC_RLPFMX_DISABLE|ASC_LLPFMX_DISABLE|ASC_LDAMX_DISABLE|ASC_RDAMX_DISABLE|ASC_LSCF_ACTIVE|ASC_RSCF_ACTIVE);  //0x3c
-    rk1000_codec_write(codec,ACCELCODEC_R1B, 0x32);
-    rk1000_codec_write(codec,ACCELCODEC_R1C, ASC_DEM_ENABLE);  ///0x00);  //use default value
-    
-    //dac mode
-    rk1000_codec_write(codec,ACCELCODEC_R17, 0xBF);  //AOL  ÒôÁ¿×îµÍ
-    rk1000_codec_write(codec,ACCELCODEC_R18, 0xBF);  //AOR
-        
-    //2power down useless module
-    rk1000_codec_write(codec,ACCELCODEC_R1D, 0x2a|ASC_PDSDL_ENABLE|ASC_PDBSTL_ENABLE|ASC_PDPGAL_ENABLE);  //setup Vmid and Vref, other module power down
-    rk1000_codec_write(codec,ACCELCODEC_R1E, 0x40|ASC_PDASDML_ENABLE);
-    #if OUT_CAPLESS
-    rk1000_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMICB_ENABLE|ASC_PDMIXM_ENABLE);
-    #else
-    rk1000_codec_write(codec,ACCELCODEC_R1F, 0x09|ASC_PDMICB_ENABLE|ASC_PDMIXM_ENABLE|ASC_PDPAM_ENABLE);
-    #endif
-
-    //2other
-    rk1000_codec_write(codec,ACCELCODEC_R0B, ASC_DEC_DISABLE|ASC_INT_ENABLE);
-    gR0BReg = ASC_DEC_ENABLE|ASC_INT_ENABLE;  //ASC_DEC_DISABLE|ASC_INT_ENABLE;
-    rk1000_codec_write(codec,ACCELCODEC_R15, 0xC1);//rk1000_codec_write(codec,ACCELCODEC_R15, 0xCD);//by Vincent Hsiung
-    rk1000_codec_write(codec,ACCELCODEC_R0C, 0x10|ASC_INPUT_VOL_0DB|ASC_INPUT_MUTE);   //LIL
-    rk1000_codec_write(codec,ACCELCODEC_R0D, 0x10|ASC_INPUT_VOL_0DB);   //LIR
-    rk1000_codec_write(codec,ACCELCODEC_R0E, 0x10|ASC_INPUT_VOL_0DB);   //MIC
-    rk1000_codec_write(codec,ACCELCODEC_R12, 0x4c|ASC_MIC_INPUT|ASC_MIC_BOOST_20DB);  //mic input and boost 20dB
-    rk1000_codec_write(codec,ACCELCODEC_R13, 0x00);
-    rk1000_codec_write(codec,ACCELCODEC_R14, 0x00);
-    gR1314Reg = 0x00;
-    rk1000_codec_write(codec,ACCELCODEC_R1C, ASC_DEM_ENABLE);  //0x00);  //use default value
+       rk1000_codec_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
+       spk_ctrl_fun(GPIO_HIGH);
+       return 0;
 }
 
 static int rk1000_codec_probe(struct snd_soc_codec *codec)
 {
-       struct rk1000_codec_priv *rk1000_codec_priv = snd_soc_codec_get_drvdata(codec);
-
-       int ret = 0;
-       DBG("%s::%d\n",__FUNCTION__,__LINE__);
+       struct rk1000_codec_priv *rk1000_codec;
+       int ret;
 
        rk1000_codec_codec = codec;
-       
-       codec->control_data = rk1000_codec_priv->control_data;
-       
-       ret = snd_soc_codec_set_cache_io(codec, 8, 8, rk1000_codec_priv->control_type);
+       rk1000_codec = snd_soc_codec_get_drvdata(codec);
+       DBG("[%s] start\n", __func__);
+       ret = snd_soc_codec_set_cache_io(codec, 8, 16,
+                                        rk1000_codec->control_type);
        if (ret != 0) {
                dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
                return ret;
        }
-       
-       codec->reg_cache = kmemdup(rk1000_codec_reg, sizeof(rk1000_codec_reg), GFP_KERNEL);
-       if (codec->reg_cache == NULL)
-               return -ENOMEM;
-
-       rk1000_reg_init(codec);
-//     snd_soc_add_controls(codec, rk1000_codec_snd_controls,
-//                             ARRAY_SIZE(rk1000_codec_snd_controls));
-//     snd_soc_dapm_new_controls(codec, rk1000_codec_dapm_widgets,
-//                               ARRAY_SIZE(rk1000_codec_dapm_widgets));
-//     snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
-
-
+       /*For RK1000, i2c write&read method is special
+        *do not use system default method.*/
+       codec->write = rk1000_codec_write;
+       codec->read = rk1000_codec_read;
+       codec->hw_write = (hw_write_t)i2c_master_send;
+       if (rk1000_codec_codec == NULL) {
+               dev_err(codec->dev, "Codec device not registered\n");
+               return -ENODEV;
+       }
+       INIT_DELAYED_WORK(&rk1000_codec->rk1000_delayed_work,
+                         rk1000_delayedwork_fun);
+
+       if (rk1000_codec->spk_ctrl_io) {
+               ret = gpio_request(rk1000_codec->spk_ctrl_io,
+                                  "rk1000-spk-ctrl");
+               if (ret) {
+                       DBG("rk1000 codec request gpio fail!\n");
+                       return ret;
+               }
+               /*set hight disable codec lr output*/
+               gpio_direction_output(rk1000_codec->spk_ctrl_io,
+                                     !rk1000_codec->flags);
+               gpio_set_value(rk1000_codec->spk_ctrl_io,
+                              !rk1000_codec->flags);
+       }
+       rk1000_codec->call_enable = 0;
+       rk1000_codec->headset_status = HP_OUT;
+       rk1000_codec_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
+       schedule_delayed_work(&rk1000_codec->rk1000_delayed_work,
+                             msecs_to_jiffies(rk1000_codec->pa_enable_time));
+       rk1000_codec_reg_set();
+       DBG("rk1000_codec_probe ret=0x%x\n", ret);
        return ret;
 }
 
 static int rk1000_codec_remove(struct snd_soc_codec *codec)
 {
-       struct rk1000_codec_priv *rk1000_codec_priv = snd_soc_codec_get_drvdata(codec);
-
        rk1000_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
-       kfree(rk1000_codec_priv);
        return 0;
 }
 
 static struct snd_soc_codec_driver soc_codec_dev_rk1000_codec = {
-       .probe =        rk1000_codec_probe,
-       .remove =       rk1000_codec_remove,
-       .suspend =      rk1000_codec_suspend,
+       .probe =        rk1000_codec_probe,
+       .remove =       rk1000_codec_remove,
+       .suspend =      rk1000_codec_suspend,
        .resume =       rk1000_codec_resume,
        .set_bias_level = rk1000_codec_set_bias_level,
-       .read =         rk1000_codec_read,
-       .write =        rk1000_codec_write,
-//     .readable_register = rk1000_codec_read_reg_cache,
-//     .writable_register = rk1000_codec_write_reg_cache,
-//     .volatile_register = wm8994_volatile,   
        .reg_cache_size = ARRAY_SIZE(rk1000_codec_reg),
-       .reg_word_size = sizeof(u8),
+       .reg_word_size = sizeof(u16),
        .reg_cache_default = rk1000_codec_reg,
 };
 
-#ifdef RK1000_CODEC_PROC       
-static int rk1000_codec_proc_init(void);
-#endif
 
-static __devinit int rk1000_codec_i2c_probe(struct i2c_client *i2c,
-                           const struct i2c_device_id *id)
+static int rk1000_codec_i2c_probe(struct i2c_client *i2c,
+                                 const struct i2c_device_id *id)
 {
        struct rk1000_codec_priv *rk1000_codec;
+       struct device_node *rk1000_np = i2c->dev.of_node;
        int ret;
-       DBG("%s::%d\n",__FUNCTION__,__LINE__);
-       rk1000_codec = kzalloc(sizeof(struct rk1000_codec_priv), GFP_KERNEL);
+
+       DBG("%s::%d\n", __func__, __LINE__);
+       rk1000_codec = kmalloc(sizeof(*rk1000_codec), GFP_KERNEL);
        if (rk1000_codec == NULL)
                return -ENOMEM;
-
+       rk1000_codec->spk_ctrl_io = of_get_named_gpio_flags(rk1000_np,
+                                   "spk_ctl_io", 0, &(rk1000_codec->flags));
+       if (!gpio_is_valid(rk1000_codec->spk_ctrl_io)) {
+               DBG("invalid core_info->reset_gpio: %d\n",
+                   rk1000_codec->spk_ctrl_io);
+               return -1;
+       }
+       of_property_read_u32(rk1000_np, "pa_enable_time",
+                            &(rk1000_codec->pa_enable_time));
+       of_property_read_u32(rk1000_np, "boot_depop",
+                            &(rk1000_codec->boot_depop));
        i2c_set_clientdata(i2c, rk1000_codec);
        rk1000_codec->control_type = SND_SOC_I2C;
-       rk1000_codec->control_data = i2c;
-       
        ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rk1000_codec,
-                       rk1000_codec_dai, ARRAY_SIZE(rk1000_codec_dai));
+                                    rk1000_codec_dai,
+                                    ARRAY_SIZE(rk1000_codec_dai));
        if (ret < 0)
                kfree(rk1000_codec);
-               
-#ifdef RK1000_CODEC_PROC       
-  rk1000_codec_proc_init();
-#endif
-
        return ret;
 }
 
-static __devexit int rk1000_codec_i2c_remove(struct i2c_client *client)
+static int rk1000_codec_i2c_remove(struct i2c_client *client)
 {
        snd_soc_unregister_codec(&client->dev);
-       kfree(i2c_get_clientdata(client));      
+       kfree(i2c_get_clientdata(client));
        return 0;
 }
 
 static const struct i2c_device_id rk1000_codec_i2c_id[] = {
-       { "rk1000_i2c_codec", 0 },
+       { "rk1000_codec", 0 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, rk1000_codec_i2c_id);
@@ -915,20 +864,26 @@ MODULE_DEVICE_TABLE(i2c, rk1000_codec_i2c_id);
 /* corgi i2c codec control layer */
 static struct i2c_driver rk1000_codec_i2c_driver = {
        .driver = {
-               .name = "RK1000_CODEC",
+               .name = "rk1000_codec",
                .owner = THIS_MODULE,
        },
        .probe = rk1000_codec_i2c_probe,
-       .remove = __devexit_p(rk1000_codec_i2c_remove),
+       .remove = rk1000_codec_i2c_remove,
        .id_table = rk1000_codec_i2c_id,
 };
 
 
 static int __init rk1000_codec_modinit(void)
 {
-       DBG("%s::%d\n",__FUNCTION__,__LINE__);
-       return i2c_add_driver(&rk1000_codec_i2c_driver);
+       int ret;
+
+       DBG("[%s] start\n", __func__);
+       ret = i2c_add_driver(&rk1000_codec_i2c_driver);
+       if (ret != 0)
+               pr_err("rk1000 codec: register I2C driver err=: %d\n", ret);
+       return ret;
 }
+/* late_initcall(rk1000_codec_modinit); */
 module_init(rk1000_codec_modinit);
 
 static void __exit rk1000_codec_exit(void)
@@ -937,229 +892,136 @@ static void __exit rk1000_codec_exit(void)
 }
 module_exit(rk1000_codec_exit);
 
+
+
 #ifdef RK1000_CODEC_PROC
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+static int debug_write_read;
+
 void rk1000_codec_reg_read(void)
 {
-    struct snd_soc_codec *codec = rk1000_codec_codec;
-    int i;
-    unsigned int data;
-
-    for (i=0; i<=0x1f; i++){
-        data = rk1000_codec_read(codec, i);
-        printk("reg[0x%x]=0x%x\n",i,data);
-    }
+       struct snd_soc_codec *codec;
+       int i;
+       unsigned int data;
+
+       codec = rk1000_codec_codec;
+       for (i = 0; i <= 0x1f; i++) {
+               data = rk1000_codec_read(codec, i);
+               pr_info("reg[0x%x]=0x%x\n", i, data);
+       }
 }
 
-static ssize_t rk1000_codec_proc_write(struct file *file, const char __user *buffer,
-                          unsigned long len, void *data)
+
+static ssize_t rk1000_codec_proc_write(struct file *file,
+                                      const char __user *buffer,
+                                      size_t len, loff_t *data)
 {
-       char *cookie_pot; 
+       char *cookie_pot;
        char *p;
-       int reg;
-       int value;
-       
-       cookie_pot = (char *)vmalloc( len );
-       if (!cookie_pot) 
-       {
+       long reg;
+       long value;
+       int ret;
+
+       cookie_pot = vmalloc(len);
+       if (!cookie_pot) {
+               pr_err("malloc cookie error for rk1000 codec proc debug\n");
                return -ENOMEM;
-       } 
-       else 
-       {
-               if (copy_from_user( cookie_pot, buffer, len )) 
+       } else {
+               if (copy_from_user(cookie_pot, buffer, len))
                        return -EFAULT;
        }
-
-       switch(cookie_pot[0])
-       {
+       switch (cookie_pot[0]) {
        case 'd':
        case 'D':
-               debug_write_read ++;
+               debug_write_read++;
                debug_write_read %= 2;
-               if(debug_write_read != 0)
-                       printk("Debug read and write reg on\n");
-               else    
-                       printk("Debug read and write reg off\n");       
-               break;  
+               if (debug_write_read != 0)
+                       pr_info("Debug read and write reg on\n");
+               else
+                       pr_info("Debug read and write reg off\n");
+               break;
        case 'r':
        case 'R':
-               printk("Read reg debug\n");             
-               if(cookie_pot[1] ==':')
-               {
+               pr_info("Read reg debug\n");
+               if (cookie_pot[1] == ':') {
                        debug_write_read = 1;
-                       strsep(&cookie_pot,":");
-                       while((p=strsep(&cookie_pot,",")))
-                       {
-                               reg = simple_strtol(p,NULL,16);
-                               value = rk1000_codec_read(rk1000_codec_codec,reg);
-                               printk("rk1000_codec_read:0x%04x = 0x%04x",reg,value);
+                       strsep(&cookie_pot, ":");
+                       while ((p = strsep(&cookie_pot, ","))) {
+                               ret = kstrtol((const char *)p, 0, &reg);
+                               if (ret < 0) {
+                                       pr_err("string to long error\n");
+                                       return ret;
+                               }
+                               value = rk1000_codec_read(rk1000_codec_codec,
+                                                         reg);
+                               pr_info("rk1000_codec_read:0x%04lx = 0x%04lx",
+                                       reg, value);
                        }
                        debug_write_read = 0;
-                       printk("\n");
-               }
-               else
-               {
-                       printk("Error Read reg debug.\n");
-                       printk("For example: echo 'r:22,23,24,25'>wm8994_ts\n");
+                       pr_info("\n");
+               } else {
+                       pr_info("Error Read reg debug.\n");
                }
                break;
        case 'w':
        case 'W':
-               printk("Write reg debug\n");            
-               if(cookie_pot[1] ==':')
-               {
+               pr_info("Write reg debug\n");
+               if (cookie_pot[1] == ':') {
                        debug_write_read = 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);
-                               rk1000_codec_write(rk1000_codec_codec,reg,value);
-                               printk("rk1000_codec_write:0x%04x = 0x%04x\n",reg,value);
+                       strsep(&cookie_pot, ":");
+                       while ((p = strsep(&cookie_pot, "="))) {
+                               ret = kstrtol(p, 0, &reg);
+                               if (ret < 0) {
+                                       pr_err("string to long error\n");
+                                       return ret;
+                               }
+                               p = strsep(&cookie_pot, ",");
+                               ret = kstrtol(p, 0, &value);
+                               if (ret < 0) {
+                                       pr_err("string to long error\n");
+                                       return ret;
+                               }
+                               rk1000_codec_write(rk1000_codec_codec, reg,
+                                                  value);
+                               pr_info("rk1000_codec_write:0x%04lx = 0x%04lx\n",
+                                       reg, value);
                        }
                        debug_write_read = 0;
-                       printk("\n");
-               }
-               else
-               {
-                       printk("Error Write reg debug.\n");
-                       printk("For example: w:22=0,23=0,24=0,25=0\n");
+                       pr_info("\n");
+               } else {
+                       pr_info("Error Write reg debug.\n");
+                       pr_info("For example: w:22=0,23=0,24=0,25=0\n");
                }
                break;
-       case 'p'://enable pa
+       case 'p':
                rk1000_codec_reg_read();
                break;
        default:
-               printk("Help for rk1000_codec_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'>rk1000_codec_ts\n");
-               printk("-->'w&&W' Write reg debug,Example: echo 'w:22=0,23=0,24=0,25=0'>rk1000_codec_ts\n");
+               pr_info("Help for rk1000_codec_ts .\n-->The Cmd list:\n");
+               pr_info("-->'d&&D' Open or Off the debug\n");
+               pr_info("-->'r&&R' Read reg debug,Example:");
+               pr_info("echo 'r:22,23,24,25'>rk1000_codec_ts\n");
+               pr_info("-->'w&&W' Write reg debug,Example:");
+               pr_info("echo 'w:22=0,23=0,24=0,25=0'>rk1000_codec_ts\n");
                break;
        }
-
+       vfree(cookie_pot);
        return len;
 }
+
+
 static const struct file_operations rk1000_codec_proc_fops = {
-       .owner          = THIS_MODULE,
-       //.open         = snd_mem_proc_open,
-       //.read         = seq_read,
-//#ifdef CONFIG_PCI
-//     .write          = rk1000_codec_proc_write,
-//#endif
-       //.llseek       = seq_lseek,
-       //.release      = single_release,
+       .owner = THIS_MODULE,
+       .write = rk1000_codec_proc_write,
 };
 
 static int rk1000_codec_proc_init(void)
 {
-       struct proc_dir_entry *rk1000_codec_proc_entry;
-       rk1000_codec_proc_entry = create_proc_entry("driver/rk1000_codec", 0777, NULL);
-       if(rk1000_codec_proc_entry != NULL)
-       {
-               rk1000_codec_proc_entry->write_proc = rk1000_codec_proc_write;
-               return -1;
-       }
-       else
-       {
-               printk("create rk1000_codec proc error !\n");
-       }
+       proc_create("rk1000_codec_reg", 0,
+                   NULL, &rk1000_codec_proc_fops);
        return 0;
 }
-
-#endif
-
-#if 1
-int reg_send_data(struct i2c_client *client, const char start_reg,
-                               const char *buf, int count, unsigned int scl_rate)
-{
-       int ret;
-       struct i2c_adapter *adap = client->adapter;
-       struct i2c_msg msg;
-       char tx_buf[count + 1];
-                                           
-       tx_buf[0] = start_reg;
-       memcpy(tx_buf+1, buf, count); 
-  
-       msg.addr = client->addr;
-       msg.buf = tx_buf;
-       msg.len = count +1;
-       msg.flags = client->flags;   
-       msg.scl_rate = scl_rate;
-                                                                                                   
-       ret = i2c_transfer(adap, &msg, 1);
-
-       return ret;    
-}
-
-static int rk1000_control_probe(struct i2c_client *client,
-                       const struct i2c_device_id *id)
-{
-       int ret;
-       char data[4] = {0x88, 0x0d, 0x22, 0x00};
-//     reg[0x00] = 0x88, --> ADC_CON
-//     reg[0x01] = 0x0d, --> CODEC_CON
-//     reg[0x02] = 0x22, --> I2C_CON
-//     reg[0x03] = 0x00, --> TVE_CON
-       #ifdef CONFIG_SND_SOC_RK1000
-    data[1] = 0x00;
-    #endif
-       
-       DBG("%s::%d\n",__FUNCTION__,__LINE__);
-       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 
-       {
-               dev_err(&client->dev, "i2c bus does not support the rk1000_control\n");
-               return -EIO;
-       }
-       
-       msleep(50);
-       ret = reg_send_data(client, 0x00, data, 4, 100 * 1000);
-#if 1
-    printk("i2c write ret = 0x%x\n",ret);
-       memset(data,0,sizeof(data));
-    ret = i2c_master_reg8_recv(client, 0, data, (int)4, 20*1000);
-    printk("i2c read reg    %x,   %x,   %x,  %x   ret=x%x\n",data[0],data[1],data[2],data[3],ret);
+late_initcall(rk1000_codec_proc_init);
 #endif
-       
-       if (ret > 0)
-               ret = 0;
-
-       return ret;     
-}
-
-static int rk1000_control_remove(struct i2c_client *client)
-{
-       return 0;
-}
-
-static const struct i2c_device_id rk1000_control_id[] = {
-       { "rk1000_control", 0 },
-       { }
-};
-MODULE_DEVICE_TABLE(i2c, rk1000_control_id);
-
-static struct i2c_driver rk1000_control_driver = {
-       .driver = {
-               .name = "rk1000_control",
-       },
-       .probe = rk1000_control_probe,
-       .remove = rk1000_control_remove,
-       .id_table = rk1000_control_id,
-};
-
-static int __init rk1000_control_init(void)
-{
-       return i2c_add_driver(&rk1000_control_driver);
-}
-
-static void __exit rk1000_control_exit(void)
-{
-       i2c_del_driver(&rk1000_control_driver);
-}
-
-module_init(rk1000_control_init);
-module_exit(rk1000_control_exit);
-
-MODULE_DESCRIPTION("ASoC RK1000 CODEC driver");
-MODULE_AUTHOR("lhh lhh@rock-chips.com");
-MODULE_LICENSE("GPL");
-#endif 
\ No newline at end of file