ASoC: rt5663: Change the dev getting function in rt5663_irq
[sfrench/cifs-2.6.git] / sound / soc / codecs / rt5663.c
index fa550e3c1332bdc7071b77b712eb47dc388ee00e..e45b895d8279e42ea8bbac880f5be31a669f0206 100644 (file)
@@ -40,6 +40,7 @@ enum {
 
 struct rt5663_priv {
        struct snd_soc_codec *codec;
+       struct rt5663_platform_data pdata;
        struct regmap *regmap;
        struct delayed_work jack_detect_work;
        struct snd_soc_jack *hs_jack;
@@ -57,6 +58,11 @@ struct rt5663_priv {
        int jack_type;
 };
 
+static const struct reg_sequence rt5663_patch_list[] = {
+       { 0x002a, 0x8020 },
+       { 0x0086, 0x0028 },
+};
+
 static const struct reg_default rt5663_v2_reg[] = {
        { 0x0000, 0x0000 },
        { 0x0001, 0xc8c8 },
@@ -476,7 +482,7 @@ static const struct reg_default rt5663_reg[] = {
        { 0x0023, 0x0039 },
        { 0x0026, 0xc0c0 },
        { 0x0029, 0x8080 },
-       { 0x002a, 0xa0a0 },
+       { 0x002a, 0x8020 },
        { 0x002c, 0x000c },
        { 0x002d, 0x0000 },
        { 0x0040, 0x0808 },
@@ -504,7 +510,7 @@ static const struct reg_default rt5663_reg[] = {
        { 0x0082, 0x0000 },
        { 0x0083, 0x0000 },
        { 0x0084, 0x0000 },
-       { 0x0086, 0x0008 },
+       { 0x0086, 0x0028 },
        { 0x0087, 0x0000 },
        { 0x008a, 0x0000 },
        { 0x008b, 0x0000 },
@@ -1508,7 +1514,7 @@ static int rt5663_v2_jack_detect(struct snd_soc_codec *codec, int jack_insert)
 static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert)
 {
        struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
-       int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30};
+       int val, i = 0;
 
        dev_dbg(codec->dev, "%s jack_insert:%d\n", __func__, jack_insert);
 
@@ -1543,25 +1549,68 @@ static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert)
                        RT5663_IRQ_POW_SAV_MASK, RT5663_IRQ_POW_SAV_EN);
                snd_soc_update_bits(codec, RT5663_IRQ_1,
                        RT5663_EN_IRQ_JD1_MASK, RT5663_EN_IRQ_JD1_EN);
-               while (i < 5) {
-                       msleep(sleep_time[i]);
-                       val = snd_soc_read(codec, RT5663_EM_JACK_TYPE_2) &
-                               0x0003;
-                       dev_dbg(codec->dev, "%s: MX-00e7 val=%x sleep %d\n",
-                               __func__, val, sleep_time[i]);
-                       i++;
-                       if (val == 0x1 || val == 0x2 || val == 0x3)
+
+               while (true) {
+                       regmap_read(rt5663->regmap, RT5663_INT_ST_2, &val);
+                       if (!(val & 0x80))
+                               usleep_range(10000, 10005);
+                       else
                                break;
+
+                       if (i > 200)
+                               break;
+                       i++;
                }
+
+               val = snd_soc_read(codec, RT5663_EM_JACK_TYPE_2) & 0x0003;
                dev_dbg(codec->dev, "%s val = %d\n", __func__, val);
+
+               snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
+                       RT5663_OSW_HP_L_MASK | RT5663_OSW_HP_R_MASK,
+                       RT5663_OSW_HP_L_EN | RT5663_OSW_HP_R_EN);
+
                switch (val) {
                case 1:
                case 2:
                        rt5663->jack_type = SND_JACK_HEADSET;
                        rt5663_enable_push_button_irq(codec, true);
+
+                       if (rt5663->pdata.dc_offset_l_manual_mic) {
+                               regmap_write(rt5663->regmap, RT5663_MIC_DECRO_2,
+                                       rt5663->pdata.dc_offset_l_manual_mic >>
+                                       16);
+                               regmap_write(rt5663->regmap, RT5663_MIC_DECRO_3,
+                                       rt5663->pdata.dc_offset_l_manual_mic &
+                                       0xffff);
+                       }
+
+                       if (rt5663->pdata.dc_offset_r_manual_mic) {
+                               regmap_write(rt5663->regmap, RT5663_MIC_DECRO_5,
+                                       rt5663->pdata.dc_offset_r_manual_mic >>
+                                       16);
+                               regmap_write(rt5663->regmap, RT5663_MIC_DECRO_6,
+                                       rt5663->pdata.dc_offset_r_manual_mic &
+                                       0xffff);
+                       }
                        break;
                default:
                        rt5663->jack_type = SND_JACK_HEADPHONE;
+
+                       if (rt5663->pdata.dc_offset_l_manual) {
+                               regmap_write(rt5663->regmap, RT5663_MIC_DECRO_2,
+                                       rt5663->pdata.dc_offset_l_manual >> 16);
+                               regmap_write(rt5663->regmap, RT5663_MIC_DECRO_3,
+                                       rt5663->pdata.dc_offset_l_manual &
+                                       0xffff);
+                       }
+
+                       if (rt5663->pdata.dc_offset_r_manual) {
+                               regmap_write(rt5663->regmap, RT5663_MIC_DECRO_5,
+                                       rt5663->pdata.dc_offset_r_manual >> 16);
+                               regmap_write(rt5663->regmap, RT5663_MIC_DECRO_6,
+                                       rt5663->pdata.dc_offset_r_manual &
+                                       0xffff);
+                       }
                        break;
                }
        } else {
@@ -1590,7 +1639,8 @@ static irqreturn_t rt5663_irq(int irq, void *data)
 {
        struct rt5663_priv *rt5663 = data;
 
-       dev_dbg(rt5663->codec->dev, "%s IRQ queue work\n", __func__);
+       dev_dbg(regmap_get_device(rt5663->regmap), "%s IRQ queue work\n",
+               __func__);
 
        queue_delayed_work(system_wq, &rt5663->jack_detect_work,
                msecs_to_jiffies(250));
@@ -1656,6 +1706,9 @@ static void rt5663_jack_detect_work(struct work_struct *work)
                        default:
                                dev_err(codec->dev, "Unknown CODEC Version\n");
                        }
+
+                       /* Delay the jack insert report to avoid pop noise */
+                       msleep(30);
                } else {
                        /* jack is already in, report button event */
                        report = SND_JACK_HEADSET;
@@ -1953,13 +2006,9 @@ static const struct snd_kcontrol_new rt5663_adda_r_mix[] = {
 static const struct snd_kcontrol_new rt5663_sto1_dac_l_mix[] = {
        SOC_DAPM_SINGLE("DAC L Switch", RT5663_STO_DAC_MIXER,
                        RT5663_M_DAC_L1_STO_L_SHIFT, 1, 1),
-       SOC_DAPM_SINGLE("DAC R Switch", RT5663_STO_DAC_MIXER,
-                       RT5663_M_DAC_R1_STO_L_SHIFT, 1, 1),
 };
 
 static const struct snd_kcontrol_new rt5663_sto1_dac_r_mix[] = {
-       SOC_DAPM_SINGLE("DAC L Switch", RT5663_STO_DAC_MIXER,
-                       RT5663_M_DAC_L1_STO_R_SHIFT, 1, 1),
        SOC_DAPM_SINGLE("DAC R Switch", RT5663_STO_DAC_MIXER,
                        RT5663_M_DAC_R1_STO_R_SHIFT, 1, 1),
 };
@@ -2024,10 +2073,6 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w,
                                RT5663_HP_SIG_SRC1_SILENCE);
                } else {
                        snd_soc_write(codec, RT5663_DEPOP_2, 0x3003);
-                       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x000b,
-                               0x000b);
-                       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030,
-                               0x0030);
                        snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
                                RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_DIS);
                        snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_2, 0x1371);
@@ -2036,6 +2081,8 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w,
                        snd_soc_write(codec, RT5663_ANA_BIAS_CUR_1, 0x7766);
                        snd_soc_write(codec, RT5663_HP_BIAS, 0xafaa);
                        snd_soc_write(codec, RT5663_CHARGE_PUMP_2, 0x7777);
+                       snd_soc_update_bits(codec, RT5663_STO_DRE_1, 0x8000,
+                               0x8000);
                        snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000,
                                0x3000);
                }
@@ -2050,9 +2097,36 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w,
                        snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0x0);
                        snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1,
                                RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_EN);
-                       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0x0);
-                       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x000b,
-                               0x000b);
+               }
+               break;
+
+       default:
+               return 0;
+       }
+
+       return 0;
+}
+
+static int rt5663_charge_pump_event(struct snd_soc_dapm_widget *w,
+       struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec);
+
+       switch (event) {
+       case SND_SOC_DAPM_PRE_PMU:
+               if (rt5663->codec_ver == CODEC_VER_0) {
+                       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030,
+                               0x0030);
+                       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003,
+                               0x0003);
+               }
+               break;
+
+       case SND_SOC_DAPM_POST_PMD:
+               if (rt5663->codec_ver == CODEC_VER_0) {
+                       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003, 0);
+                       snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0);
                }
                break;
 
@@ -2182,6 +2256,9 @@ static const struct snd_soc_dapm_widget rt5663_dapm_widgets[] = {
        SND_SOC_DAPM_DAC("DAC R", NULL, SND_SOC_NOPM, 0, 0),
 
        /* Headphone*/
+       SND_SOC_DAPM_SUPPLY("HP Charge Pump", SND_SOC_NOPM, 0, 0,
+               rt5663_charge_pump_event, SND_SOC_DAPM_PRE_PMU |
+               SND_SOC_DAPM_POST_PMD),
        SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5663_hp_event,
                SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
 
@@ -2330,14 +2407,13 @@ static const struct snd_soc_dapm_route rt5663_dapm_routes[] = {
        { "DAC R1", NULL, "ADDA MIXR" },
 
        { "STO1 DAC MIXL", "DAC L Switch", "DAC L1" },
-       { "STO1 DAC MIXL", "DAC R Switch", "DAC R1" },
        { "STO1 DAC MIXL", NULL, "STO1 DAC L Power" },
        { "STO1 DAC MIXL", NULL, "STO1 DAC Filter" },
        { "STO1 DAC MIXR", "DAC R Switch", "DAC R1" },
-       { "STO1 DAC MIXR", "DAC L Switch", "DAC L1" },
        { "STO1 DAC MIXR", NULL, "STO1 DAC R Power" },
        { "STO1 DAC MIXR", NULL, "STO1 DAC Filter" },
 
+       { "HP Amp", NULL, "HP Charge Pump" },
        { "HP Amp", NULL, "DAC L" },
        { "HP Amp", NULL, "DAC R" },
 };
@@ -2860,7 +2936,7 @@ static int rt5663_resume(struct snd_soc_codec *codec)
 #define RT5663_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
                        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
 
-static struct snd_soc_dai_ops rt5663_aif_dai_ops = {
+static const struct snd_soc_dai_ops rt5663_aif_dai_ops = {
        .hw_params = rt5663_hw_params,
        .set_fmt = rt5663_set_dai_fmt,
        .set_sysclk = rt5663_set_dai_sysclk,
@@ -2891,7 +2967,7 @@ static struct snd_soc_dai_driver rt5663_dai[] = {
        },
 };
 
-static struct snd_soc_codec_driver soc_codec_dev_rt5663 = {
+static const struct snd_soc_codec_driver soc_codec_dev_rt5663 = {
        .probe = rt5663_probe,
        .remove = rt5663_remove,
        .suspend = rt5663_suspend,
@@ -2956,7 +3032,7 @@ MODULE_DEVICE_TABLE(of, rt5663_of_match);
 #endif
 
 #ifdef CONFIG_ACPI
-static struct acpi_device_id rt5663_acpi_match[] = {
+static const struct acpi_device_id rt5663_acpi_match[] = {
        { "10EC5663", 0},
        {},
 };
@@ -2986,47 +3062,93 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663)
 {
        int value, count;
 
-       regmap_write(rt5663->regmap, RT5663_RC_CLK, 0x0280);
+       regmap_write(rt5663->regmap, RT5663_RESET, 0x0000);
+       msleep(20);
+       regmap_write(rt5663->regmap, RT5663_ANA_BIAS_CUR_4, 0x00a1);
+       regmap_write(rt5663->regmap, RT5663_RC_CLK, 0x0380);
        regmap_write(rt5663->regmap, RT5663_GLB_CLK, 0x8000);
-       regmap_write(rt5663->regmap, RT5663_DIG_MISC, 0x8001);
+       regmap_write(rt5663->regmap, RT5663_ADDA_CLK_1, 0x1000);
        regmap_write(rt5663->regmap, RT5663_VREF_RECMIX, 0x0032);
-       regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xa2be);
-       msleep(20);
-       regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xf2be);
-       regmap_write(rt5663->regmap, RT5663_PWR_DIG_2, 0x8400);
-       regmap_write(rt5663->regmap, RT5663_CHOP_ADC, 0x3000);
-       regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x003b);
-       regmap_write(rt5663->regmap, RT5663_PWR_DIG_1, 0x8df8);
-       regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x0003);
-       regmap_write(rt5663->regmap, RT5663_PWR_ANLG_3, 0x018c);
-       regmap_write(rt5663->regmap, RT5663_ADDA_CLK_1, 0x1111);
+       regmap_write(rt5663->regmap, RT5663_HP_IMP_SEN_19, 0x000c);
+       regmap_write(rt5663->regmap, RT5663_DUMMY_1, 0x0324);
+       regmap_write(rt5663->regmap, RT5663_DIG_MISC, 0x8001);
+       regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xa23b);
+       msleep(30);
+       regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xf23b);
+       regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x8000);
+       regmap_write(rt5663->regmap, RT5663_PWR_ANLG_3, 0x0008);
        regmap_write(rt5663->regmap, RT5663_PRE_DIV_GATING_1, 0xffff);
        regmap_write(rt5663->regmap, RT5663_PRE_DIV_GATING_2, 0xffff);
+       regmap_write(rt5663->regmap, RT5663_CBJ_1, 0x8c10);
+       regmap_write(rt5663->regmap, RT5663_IL_CMD_2, 0x00c1);
+       regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_1, 0xb880);
+       regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_2, 0x4110);
+       regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_2, 0x4118);
+
+       count = 0;
+       while (true) {
+               regmap_read(rt5663->regmap, RT5663_INT_ST_2, &value);
+               if (!(value & 0x80))
+                       usleep_range(10000, 10005);
+               else
+                       break;
+
+               if (++count > 200)
+                       break;
+       }
+
+       regmap_write(rt5663->regmap, RT5663_HP_IMP_SEN_19, 0x0000);
        regmap_write(rt5663->regmap, RT5663_DEPOP_2, 0x3003);
+       regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x0038);
        regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x003b);
+       regmap_write(rt5663->regmap, RT5663_PWR_DIG_2, 0x8400);
+       regmap_write(rt5663->regmap, RT5663_PWR_DIG_1, 0x8df8);
+       regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x8003);
+       regmap_write(rt5663->regmap, RT5663_PWR_ANLG_3, 0x018c);
        regmap_write(rt5663->regmap, RT5663_HP_CHARGE_PUMP_1, 0x1e32);
-       regmap_write(rt5663->regmap, RT5663_HP_CHARGE_PUMP_2, 0x1371);
        regmap_write(rt5663->regmap, RT5663_DACREF_LDO, 0x3b0b);
-       regmap_write(rt5663->regmap, RT5663_STO_DAC_MIXER, 0x2080);
+       msleep(40);
+       regmap_write(rt5663->regmap, RT5663_STO_DAC_MIXER, 0x0000);
        regmap_write(rt5663->regmap, RT5663_BYPASS_STO_DAC, 0x000c);
-       regmap_write(rt5663->regmap, RT5663_HP_BIAS, 0xabba);
+       regmap_write(rt5663->regmap, RT5663_HP_BIAS, 0xafaa);
        regmap_write(rt5663->regmap, RT5663_CHARGE_PUMP_1, 0x2224);
        regmap_write(rt5663->regmap, RT5663_HP_OUT_EN, 0x8088);
        regmap_write(rt5663->regmap, RT5663_STO_DRE_9, 0x0017);
        regmap_write(rt5663->regmap, RT5663_STO_DRE_10, 0x0017);
        regmap_write(rt5663->regmap, RT5663_STO1_ADC_MIXER, 0x4040);
+       regmap_write(rt5663->regmap, RT5663_CHOP_ADC, 0x3000);
        regmap_write(rt5663->regmap, RT5663_RECMIX, 0x0005);
        regmap_write(rt5663->regmap, RT5663_ADDA_RST, 0xc000);
        regmap_write(rt5663->regmap, RT5663_STO1_HPF_ADJ1, 0x3320);
        regmap_write(rt5663->regmap, RT5663_HP_CALIB_2, 0x00c9);
        regmap_write(rt5663->regmap, RT5663_DUMMY_1, 0x004c);
-       regmap_write(rt5663->regmap, RT5663_ANA_BIAS_CUR_1, 0x7766);
-       regmap_write(rt5663->regmap, RT5663_BIAS_CUR_8, 0x4702);
-       msleep(200);
+       regmap_write(rt5663->regmap, RT5663_ANA_BIAS_CUR_1, 0x1111);
+       regmap_write(rt5663->regmap, RT5663_BIAS_CUR_8, 0x4402);
+       regmap_write(rt5663->regmap, RT5663_CHARGE_PUMP_2, 0x3311);
        regmap_write(rt5663->regmap, RT5663_HP_CALIB_1, 0x0069);
-       regmap_write(rt5663->regmap, RT5663_HP_CALIB_3, 0x06c2);
-       regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0x7b00);
-       regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0xfb00);
+       regmap_write(rt5663->regmap, RT5663_HP_CALIB_3, 0x06ce);
+       regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0x6800);
+       regmap_write(rt5663->regmap, RT5663_CHARGE_PUMP_2, 0x1100);
+       regmap_write(rt5663->regmap, RT5663_HP_CALIB_7, 0x0057);
+       regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0xe800);
+
+       count = 0;
+       while (true) {
+               regmap_read(rt5663->regmap, RT5663_HP_CALIB_1_1, &value);
+               if (value & 0x8000)
+                       usleep_range(10000, 10005);
+               else
+                       break;
+
+               if (count > 200)
+                       return;
+               count++;
+       }
+
+       regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0x6200);
+       regmap_write(rt5663->regmap, RT5663_HP_CALIB_7, 0x0059);
+       regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0xe200);
+
        count = 0;
        while (true) {
                regmap_read(rt5663->regmap, RT5663_HP_CALIB_1_1, &value);
@@ -3039,11 +3161,39 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663)
                        return;
                count++;
        }
+
+       regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_1, 0xb8e0);
+       usleep_range(10000, 10005);
+       regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0x003b);
+       usleep_range(10000, 10005);
+       regmap_write(rt5663->regmap, RT5663_PWR_DIG_1, 0x0000);
+       usleep_range(10000, 10005);
+       regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x000b);
+       usleep_range(10000, 10005);
+       regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x0008);
+       usleep_range(10000, 10005);
+       regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x0000);
+       usleep_range(10000, 10005);
+}
+
+static int rt5663_parse_dp(struct rt5663_priv *rt5663, struct device *dev)
+{
+       device_property_read_u32(dev, "realtek,dc_offset_l_manual",
+               &rt5663->pdata.dc_offset_l_manual);
+       device_property_read_u32(dev, "realtek,dc_offset_r_manual",
+               &rt5663->pdata.dc_offset_r_manual);
+       device_property_read_u32(dev, "realtek,dc_offset_l_manual_mic",
+               &rt5663->pdata.dc_offset_l_manual_mic);
+       device_property_read_u32(dev, "realtek,dc_offset_r_manual_mic",
+               &rt5663->pdata.dc_offset_r_manual_mic);
+
+       return 0;
 }
 
 static int rt5663_i2c_probe(struct i2c_client *i2c,
                    const struct i2c_device_id *id)
 {
+       struct rt5663_platform_data *pdata = dev_get_platdata(&i2c->dev);
        struct rt5663_priv *rt5663;
        int ret;
        unsigned int val;
@@ -3057,6 +3207,11 @@ static int rt5663_i2c_probe(struct i2c_client *i2c,
 
        i2c_set_clientdata(i2c, rt5663);
 
+       if (pdata)
+               rt5663->pdata = *pdata;
+       else
+               rt5663_parse_dp(rt5663, &i2c->dev);
+
        regmap = devm_regmap_init_i2c(i2c, &temp_regmap);
        if (IS_ERR(regmap)) {
                ret = PTR_ERR(regmap);
@@ -3105,6 +3260,20 @@ static int rt5663_i2c_probe(struct i2c_client *i2c,
        regmap_write(rt5663->regmap, RT5663_RESET, 0);
        dev_dbg(&i2c->dev, "calibrate done\n");
 
+       switch (rt5663->codec_ver) {
+       case CODEC_VER_1:
+               break;
+       case CODEC_VER_0:
+               ret = regmap_register_patch(rt5663->regmap, rt5663_patch_list,
+                                           ARRAY_SIZE(rt5663_patch_list));
+               if (ret != 0)
+                       dev_warn(&i2c->dev,
+                               "Failed to apply regmap patch: %d\n", ret);
+               break;
+       default:
+               dev_err(&i2c->dev, "%s:Unknown codec type\n", __func__);
+       }
+
        /* GPIO1 as IRQ */
        regmap_update_bits(rt5663->regmap, RT5663_GPIO_1, RT5663_GP1_PIN_MASK,
                RT5663_GP1_PIN_IRQ);