From 01573e231f18eb2d99162747186f59511f56b64d Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 08 Dec 2023 10:40:48 +0000
Subject: [PATCH] 移去rt

---
 kernel/sound/soc/codecs/rk3308_codec.c |  731 ++++++++++++++++----------------------------------------
 1 files changed, 211 insertions(+), 520 deletions(-)

diff --git a/kernel/sound/soc/codecs/rk3308_codec.c b/kernel/sound/soc/codecs/rk3308_codec.c
index a6ce7f0..c78752d 100644
--- a/kernel/sound/soc/codecs/rk3308_codec.c
+++ b/kernel/sound/soc/codecs/rk3308_codec.c
@@ -44,7 +44,6 @@
 #include <sound/tlv.h>
 
 #include "rk3308_codec.h"
-#include "rk3308_codec_provider.h"
 
 #if defined(CONFIG_DEBUG_FS)
 #include <linux/fs.h>
@@ -96,6 +95,7 @@
 
 #define ACODEC_VERSION_A			0xa
 #define ACODEC_VERSION_B			0xb
+#define ACODEC_VERSION_C			0xc
 
 enum {
 	ACODEC_TO_I2S2_8CH = 0,
@@ -194,14 +194,6 @@
 	int ext_micbias;
 	int pm_state;
 
-	/* AGC L/R Off/on */
-	unsigned int agc_l[ADC_LR_GROUP_MAX];
-	unsigned int agc_r[ADC_LR_GROUP_MAX];
-
-	/* AGC L/R Approximate Sample Rate */
-	unsigned int agc_asr_l[ADC_LR_GROUP_MAX];
-	unsigned int agc_asr_r[ADC_LR_GROUP_MAX];
-
 	/* ADC MIC Mute/Work */
 	unsigned int mic_mute_l[ADC_LR_GROUP_MAX];
 	unsigned int mic_mute_r[ADC_LR_GROUP_MAX];
@@ -232,12 +224,6 @@
 #endif
 };
 
-static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_grp_gain_tlv,
-				  -1800, 150, 2850);
-static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_grp_max_gain_tlv,
-				  -1350, 600, 2850);
-static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_grp_min_gain_tlv,
-				  -1800, 600, 2400);
 static const DECLARE_TLV_DB_SCALE(rk3308_codec_adc_alc_gain_tlv,
 				  -1800, 150, 2850);
 static const DECLARE_TLV_DB_SCALE(rk3308_codec_dac_lineout_gain_tlv,
@@ -263,6 +249,8 @@
 
 static int check_micbias(int micbias);
 
+static void rk3308_codec_dac_mclk_enable(struct rk3308_codec_priv *rk3308);
+
 static int rk3308_codec_micbias_enable(struct rk3308_codec_priv *rk3308,
 				       int micbias);
 static int rk3308_codec_micbias_disable(struct rk3308_codec_priv *rk3308);
@@ -279,14 +267,6 @@
 				struct snd_ctl_elem_value *ucontrol);
 static int rk3308_codec_hpf_put(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol);
-static int rk3308_codec_agc_get(struct snd_kcontrol *kcontrol,
-				struct snd_ctl_elem_value *ucontrol);
-static int rk3308_codec_agc_put(struct snd_kcontrol *kcontrol,
-				struct snd_ctl_elem_value *ucontrol);
-static int rk3308_codec_agc_asr_get(struct snd_kcontrol *kcontrol,
-				    struct snd_ctl_elem_value *ucontrol);
-static int rk3308_codec_agc_asr_put(struct snd_kcontrol *kcontrol,
-				    struct snd_ctl_elem_value *ucontrol);
 static int rk3308_codec_mic_mute_get(struct snd_kcontrol *kcontrol,
 				     struct snd_ctl_elem_value *ucontrol);
 static int rk3308_codec_mic_mute_put(struct snd_kcontrol *kcontrol,
@@ -353,18 +333,6 @@
 	SOC_ENUM_SINGLE(3, 0, ARRAY_SIZE(offon_text), offon_text),
 };
 
-/* ALC AGC Switch */
-static const struct soc_enum rk3308_agc_enum_array[] = {
-	SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(offon_text), offon_text),
-	SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(offon_text), offon_text),
-	SOC_ENUM_SINGLE(1, 0, ARRAY_SIZE(offon_text), offon_text),
-	SOC_ENUM_SINGLE(1, 1, ARRAY_SIZE(offon_text), offon_text),
-	SOC_ENUM_SINGLE(2, 0, ARRAY_SIZE(offon_text), offon_text),
-	SOC_ENUM_SINGLE(2, 1, ARRAY_SIZE(offon_text), offon_text),
-	SOC_ENUM_SINGLE(3, 0, ARRAY_SIZE(offon_text), offon_text),
-	SOC_ENUM_SINGLE(3, 1, ARRAY_SIZE(offon_text), offon_text),
-};
-
 /* ADC MIC Mute/Work Switch */
 static const struct soc_enum rk3308_mic_mute_enum_array[] = {
 	SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(mute_text), mute_text),
@@ -375,40 +343,6 @@
 	SOC_ENUM_SINGLE(2, 1, ARRAY_SIZE(mute_text), mute_text),
 	SOC_ENUM_SINGLE(3, 0, ARRAY_SIZE(mute_text), mute_text),
 	SOC_ENUM_SINGLE(3, 1, ARRAY_SIZE(mute_text), mute_text),
-};
-
-/* ALC AGC Approximate Sample Rate */
-#define AGC_ASR_NUM				8
-
-#define AGC_ASR_96KHZ				0
-#define AGC_ASR_48KHZ				1
-#define AGC_ASR_44_1KHZ				2
-#define AGC_ASR_32KHZ				3
-#define AGC_ASR_24KHZ				4
-#define AGC_ASR_16KHZ				5
-#define AGC_ASR_12KHZ				6
-#define AGC_ASR_8KHZ				7
-
-static const char *agc_asr_text[AGC_ASR_NUM] = {
-	[AGC_ASR_96KHZ] = "96KHz",
-	[AGC_ASR_48KHZ] = "48KHz",
-	[AGC_ASR_44_1KHZ] = "44.1KHz",
-	[AGC_ASR_32KHZ] = "32KHz",
-	[AGC_ASR_24KHZ] = "24KHz",
-	[AGC_ASR_16KHZ] = "16KHz",
-	[AGC_ASR_12KHZ] = "12KHz",
-	[AGC_ASR_8KHZ] = "8KHz",
-};
-
-static const struct soc_enum rk3308_agc_asr_enum_array[] = {
-	SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(agc_asr_text), agc_asr_text),
-	SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(agc_asr_text), agc_asr_text),
-	SOC_ENUM_SINGLE(1, 0, ARRAY_SIZE(agc_asr_text), agc_asr_text),
-	SOC_ENUM_SINGLE(1, 1, ARRAY_SIZE(agc_asr_text), agc_asr_text),
-	SOC_ENUM_SINGLE(2, 0, ARRAY_SIZE(agc_asr_text), agc_asr_text),
-	SOC_ENUM_SINGLE(2, 1, ARRAY_SIZE(agc_asr_text), agc_asr_text),
-	SOC_ENUM_SINGLE(3, 0, ARRAY_SIZE(agc_asr_text), agc_asr_text),
-	SOC_ENUM_SINGLE(3, 1, ARRAY_SIZE(agc_asr_text), agc_asr_text),
 };
 
 static const struct snd_kcontrol_new mic_gains_a[] = {
@@ -548,201 +482,6 @@
 };
 
 static const struct snd_kcontrol_new rk3308_codec_dapm_controls[] = {
-	/* ALC AGC Group */
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Left Volume",
-			     RK3308_ALC_L_DIG_CON03(0),
-			     RK3308_AGC_PGA_GAIN_SFT,
-			     RK3308_AGC_PGA_GAIN_MIN,
-			     RK3308_AGC_PGA_GAIN_MAX,
-			     0, rk3308_codec_alc_agc_grp_gain_tlv),
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Right Volume",
-			     RK3308_ALC_R_DIG_CON03(0),
-			     RK3308_AGC_PGA_GAIN_SFT,
-			     RK3308_AGC_PGA_GAIN_MIN,
-			     RK3308_AGC_PGA_GAIN_MAX,
-			     0, rk3308_codec_alc_agc_grp_gain_tlv),
-
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Left Volume",
-			     RK3308_ALC_L_DIG_CON03(1),
-			     RK3308_AGC_PGA_GAIN_SFT,
-			     RK3308_AGC_PGA_GAIN_MIN,
-			     RK3308_AGC_PGA_GAIN_MAX,
-			     0, rk3308_codec_alc_agc_grp_gain_tlv),
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Right Volume",
-			     RK3308_ALC_R_DIG_CON03(1),
-			     RK3308_AGC_PGA_GAIN_SFT,
-			     RK3308_AGC_PGA_GAIN_MIN,
-			     RK3308_AGC_PGA_GAIN_MAX,
-			     0, rk3308_codec_alc_agc_grp_gain_tlv),
-
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Left Volume",
-			     RK3308_ALC_L_DIG_CON03(2),
-			     RK3308_AGC_PGA_GAIN_SFT,
-			     RK3308_AGC_PGA_GAIN_MIN,
-			     RK3308_AGC_PGA_GAIN_MAX,
-			     0, rk3308_codec_alc_agc_grp_gain_tlv),
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Right Volume",
-			     RK3308_ALC_R_DIG_CON03(2),
-			     RK3308_AGC_PGA_GAIN_SFT,
-			     RK3308_AGC_PGA_GAIN_MIN,
-			     RK3308_AGC_PGA_GAIN_MAX,
-			     0, rk3308_codec_alc_agc_grp_gain_tlv),
-
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Left Volume",
-			     RK3308_ALC_L_DIG_CON03(3),
-			     RK3308_AGC_PGA_GAIN_SFT,
-			     RK3308_AGC_PGA_GAIN_MIN,
-			     RK3308_AGC_PGA_GAIN_MAX,
-			     0, rk3308_codec_alc_agc_grp_gain_tlv),
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Right Volume",
-			     RK3308_ALC_R_DIG_CON03(3),
-			     RK3308_AGC_PGA_GAIN_SFT,
-			     RK3308_AGC_PGA_GAIN_MIN,
-			     RK3308_AGC_PGA_GAIN_MAX,
-			     0, rk3308_codec_alc_agc_grp_gain_tlv),
-
-	/* ALC AGC MAX */
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Left Max Volume",
-			     RK3308_ALC_L_DIG_CON09(0),
-			     RK3308_AGC_MAX_GAIN_PGA_SFT,
-			     RK3308_AGC_MAX_GAIN_PGA_MIN,
-			     RK3308_AGC_MAX_GAIN_PGA_MAX,
-			     0, rk3308_codec_alc_agc_grp_max_gain_tlv),
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Right Max Volume",
-			     RK3308_ALC_R_DIG_CON09(0),
-			     RK3308_AGC_MAX_GAIN_PGA_SFT,
-			     RK3308_AGC_MAX_GAIN_PGA_MIN,
-			     RK3308_AGC_MAX_GAIN_PGA_MAX,
-			     0, rk3308_codec_alc_agc_grp_max_gain_tlv),
-
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Left Max Volume",
-			     RK3308_ALC_L_DIG_CON09(1),
-			     RK3308_AGC_MAX_GAIN_PGA_SFT,
-			     RK3308_AGC_MAX_GAIN_PGA_MIN,
-			     RK3308_AGC_MAX_GAIN_PGA_MAX,
-			     0, rk3308_codec_alc_agc_grp_max_gain_tlv),
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Right Max Volume",
-			     RK3308_ALC_R_DIG_CON09(1),
-			     RK3308_AGC_MAX_GAIN_PGA_SFT,
-			     RK3308_AGC_MAX_GAIN_PGA_MIN,
-			     RK3308_AGC_MAX_GAIN_PGA_MAX,
-			     0, rk3308_codec_alc_agc_grp_max_gain_tlv),
-
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Left Max Volume",
-			     RK3308_ALC_L_DIG_CON09(2),
-			     RK3308_AGC_MAX_GAIN_PGA_SFT,
-			     RK3308_AGC_MAX_GAIN_PGA_MIN,
-			     RK3308_AGC_MAX_GAIN_PGA_MAX,
-			     0, rk3308_codec_alc_agc_grp_max_gain_tlv),
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Right Max Volume",
-			     RK3308_ALC_R_DIG_CON09(2),
-			     RK3308_AGC_MAX_GAIN_PGA_SFT,
-			     RK3308_AGC_MAX_GAIN_PGA_MIN,
-			     RK3308_AGC_MAX_GAIN_PGA_MAX,
-			     0, rk3308_codec_alc_agc_grp_max_gain_tlv),
-
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Left Max Volume",
-			     RK3308_ALC_L_DIG_CON09(3),
-			     RK3308_AGC_MAX_GAIN_PGA_SFT,
-			     RK3308_AGC_MAX_GAIN_PGA_MIN,
-			     RK3308_AGC_MAX_GAIN_PGA_MAX,
-			     0, rk3308_codec_alc_agc_grp_max_gain_tlv),
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Right Max Volume",
-			     RK3308_ALC_R_DIG_CON09(3),
-			     RK3308_AGC_MAX_GAIN_PGA_SFT,
-			     RK3308_AGC_MAX_GAIN_PGA_MIN,
-			     RK3308_AGC_MAX_GAIN_PGA_MAX,
-			     0, rk3308_codec_alc_agc_grp_max_gain_tlv),
-
-	/* ALC AGC MIN */
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Left Min Volume",
-			     RK3308_ALC_L_DIG_CON09(0),
-			     RK3308_AGC_MIN_GAIN_PGA_SFT,
-			     RK3308_AGC_MIN_GAIN_PGA_MIN,
-			     RK3308_AGC_MIN_GAIN_PGA_MAX,
-			     0, rk3308_codec_alc_agc_grp_min_gain_tlv),
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 0 Right Min Volume",
-			     RK3308_ALC_R_DIG_CON09(0),
-			     RK3308_AGC_MIN_GAIN_PGA_SFT,
-			     RK3308_AGC_MIN_GAIN_PGA_MIN,
-			     RK3308_AGC_MIN_GAIN_PGA_MAX,
-			     0, rk3308_codec_alc_agc_grp_min_gain_tlv),
-
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Left Min Volume",
-			     RK3308_ALC_L_DIG_CON09(1),
-			     RK3308_AGC_MIN_GAIN_PGA_SFT,
-			     RK3308_AGC_MIN_GAIN_PGA_MIN,
-			     RK3308_AGC_MIN_GAIN_PGA_MAX,
-			     0, rk3308_codec_alc_agc_grp_min_gain_tlv),
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 1 Right Min Volume",
-			     RK3308_ALC_R_DIG_CON09(1),
-			     RK3308_AGC_MIN_GAIN_PGA_SFT,
-			     RK3308_AGC_MIN_GAIN_PGA_MIN,
-			     RK3308_AGC_MIN_GAIN_PGA_MAX,
-			     0, rk3308_codec_alc_agc_grp_min_gain_tlv),
-
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Left Min Volume",
-			     RK3308_ALC_L_DIG_CON09(2),
-			     RK3308_AGC_MIN_GAIN_PGA_SFT,
-			     RK3308_AGC_MIN_GAIN_PGA_MIN,
-			     RK3308_AGC_MIN_GAIN_PGA_MAX,
-			     0, rk3308_codec_alc_agc_grp_min_gain_tlv),
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 2 Right Min Volume",
-			     RK3308_ALC_R_DIG_CON09(2),
-			     RK3308_AGC_MIN_GAIN_PGA_SFT,
-			     RK3308_AGC_MIN_GAIN_PGA_MIN,
-			     RK3308_AGC_MIN_GAIN_PGA_MAX,
-			     0, rk3308_codec_alc_agc_grp_min_gain_tlv),
-
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Left Min Volume",
-			     RK3308_ALC_L_DIG_CON09(3),
-			     RK3308_AGC_MIN_GAIN_PGA_SFT,
-			     RK3308_AGC_MIN_GAIN_PGA_MIN,
-			     RK3308_AGC_MIN_GAIN_PGA_MAX,
-			     0, rk3308_codec_alc_agc_grp_min_gain_tlv),
-	SOC_SINGLE_RANGE_TLV("ALC AGC Group 3 Right Min Volume",
-			     RK3308_ALC_R_DIG_CON09(3),
-			     RK3308_AGC_MIN_GAIN_PGA_SFT,
-			     RK3308_AGC_MIN_GAIN_PGA_MIN,
-			     RK3308_AGC_MIN_GAIN_PGA_MAX,
-			     0, rk3308_codec_alc_agc_grp_min_gain_tlv),
-
-	/* ALC AGC Switch */
-	SOC_ENUM_EXT("ALC AGC Group 0 Left Switch", rk3308_agc_enum_array[0],
-		     rk3308_codec_agc_get, rk3308_codec_agc_put),
-	SOC_ENUM_EXT("ALC AGC Group 0 Right Switch", rk3308_agc_enum_array[1],
-		     rk3308_codec_agc_get, rk3308_codec_agc_put),
-	SOC_ENUM_EXT("ALC AGC Group 1 Left Switch", rk3308_agc_enum_array[2],
-		     rk3308_codec_agc_get, rk3308_codec_agc_put),
-	SOC_ENUM_EXT("ALC AGC Group 1 Right Switch", rk3308_agc_enum_array[3],
-		     rk3308_codec_agc_get, rk3308_codec_agc_put),
-	SOC_ENUM_EXT("ALC AGC Group 2 Left Switch", rk3308_agc_enum_array[4],
-		     rk3308_codec_agc_get, rk3308_codec_agc_put),
-	SOC_ENUM_EXT("ALC AGC Group 2 Right Switch", rk3308_agc_enum_array[5],
-		     rk3308_codec_agc_get, rk3308_codec_agc_put),
-	SOC_ENUM_EXT("ALC AGC Group 3 Left Switch", rk3308_agc_enum_array[6],
-		     rk3308_codec_agc_get, rk3308_codec_agc_put),
-	SOC_ENUM_EXT("ALC AGC Group 3 Right Switch", rk3308_agc_enum_array[7],
-		     rk3308_codec_agc_get, rk3308_codec_agc_put),
-
-	/* ALC AGC Approximate Sample Rate */
-	SOC_ENUM_EXT("AGC Group 0 Left Approximate Sample Rate", rk3308_agc_asr_enum_array[0],
-		     rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put),
-	SOC_ENUM_EXT("AGC Group 0 Right Approximate Sample Rate", rk3308_agc_asr_enum_array[1],
-		     rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put),
-	SOC_ENUM_EXT("AGC Group 1 Left Approximate Sample Rate", rk3308_agc_asr_enum_array[2],
-		     rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put),
-	SOC_ENUM_EXT("AGC Group 1 Right Approximate Sample Rate", rk3308_agc_asr_enum_array[3],
-		     rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put),
-	SOC_ENUM_EXT("AGC Group 2 Left Approximate Sample Rate", rk3308_agc_asr_enum_array[4],
-		     rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put),
-	SOC_ENUM_EXT("AGC Group 2 Right Approximate Sample Rate", rk3308_agc_asr_enum_array[5],
-		     rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put),
-	SOC_ENUM_EXT("AGC Group 3 Left Approximate Sample Rate", rk3308_agc_asr_enum_array[6],
-		     rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put),
-	SOC_ENUM_EXT("AGC Group 3 Right Approximate Sample Rate", rk3308_agc_asr_enum_array[7],
-		     rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put),
-
 	/* ADC MICBIAS Voltage */
 	SOC_ENUM_EXT("ADC MICBIAS Voltage", rk3308_micbias_volts_enum_array[0],
 		     rk3308_codec_micbias_volts_get, rk3308_codec_micbias_volts_put),
@@ -879,156 +618,6 @@
 			     RK3308_DAC_R_HPMIX_GAIN_MAX,
 			     0, rk3308_codec_dac_hpmix_gain_tlv),
 };
-
-static int rk3308_codec_agc_get(struct snd_kcontrol *kcontrol,
-				struct snd_ctl_elem_value *ucontrol)
-{
-	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
-	struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
-	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
-
-	if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) {
-		dev_err(rk3308->plat_dev,
-			"%s: Invalid ADC grp: %d\n", __func__, e->reg);
-		return -EINVAL;
-	}
-
-	if (e->shift_l)
-		ucontrol->value.integer.value[0] = rk3308->agc_r[e->reg];
-	else
-		ucontrol->value.integer.value[0] = rk3308->agc_l[e->reg];
-
-	return 0;
-}
-
-static int rk3308_codec_agc_put(struct snd_kcontrol *kcontrol,
-				struct snd_ctl_elem_value *ucontrol)
-{
-	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
-	struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
-
-	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
-	unsigned int value = ucontrol->value.integer.value[0];
-	int grp = e->reg;
-
-	if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) {
-		dev_err(rk3308->plat_dev,
-			"%s: Invalid ADC grp: %d\n", __func__, e->reg);
-		return -EINVAL;
-	}
-
-	if (value) {
-		/* ALC AGC On */
-		if (e->shift_l) {
-			/* ALC AGC Right On */
-			regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON09(grp),
-					   RK3308_AGC_FUNC_SEL_MSK,
-					   RK3308_AGC_FUNC_SEL_EN);
-			regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(grp),
-					   RK3308_ADC_ALCR_CON_GAIN_PGAR_MSK,
-					   RK3308_ADC_ALCR_CON_GAIN_PGAR_EN);
-
-			rk3308->agc_r[e->reg] = 1;
-		} else {
-			/* ALC AGC Left On */
-			regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON09(grp),
-					   RK3308_AGC_FUNC_SEL_MSK,
-					   RK3308_AGC_FUNC_SEL_EN);
-			regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(grp),
-					   RK3308_ADC_ALCL_CON_GAIN_PGAL_MSK,
-					   RK3308_ADC_ALCL_CON_GAIN_PGAL_EN);
-
-			rk3308->agc_l[e->reg] = 1;
-		}
-	} else {
-		/* ALC AGC Off */
-		if (e->shift_l) {
-			/* ALC AGC Right Off */
-			regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON09(grp),
-					   RK3308_AGC_FUNC_SEL_MSK,
-					   RK3308_AGC_FUNC_SEL_DIS);
-			regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(grp),
-					   RK3308_ADC_ALCR_CON_GAIN_PGAR_MSK,
-					   RK3308_ADC_ALCR_CON_GAIN_PGAR_DIS);
-
-			rk3308->agc_r[e->reg] = 0;
-		} else {
-			/* ALC AGC Left Off */
-			regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON09(grp),
-					   RK3308_AGC_FUNC_SEL_MSK,
-					   RK3308_AGC_FUNC_SEL_DIS);
-			regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(grp),
-					   RK3308_ADC_ALCL_CON_GAIN_PGAL_MSK,
-					   RK3308_ADC_ALCL_CON_GAIN_PGAL_DIS);
-
-			rk3308->agc_l[e->reg] = 0;
-		}
-	}
-
-	return 0;
-}
-
-static int rk3308_codec_agc_asr_get(struct snd_kcontrol *kcontrol,
-				    struct snd_ctl_elem_value *ucontrol)
-{
-	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
-	struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
-	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
-	unsigned int value;
-	int grp = e->reg;
-
-	if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) {
-		dev_err(rk3308->plat_dev,
-			"%s: Invalid ADC grp: %d\n", __func__, e->reg);
-		return -EINVAL;
-	}
-
-	if (e->shift_l) {
-		regmap_read(rk3308->regmap, RK3308_ALC_R_DIG_CON04(grp), &value);
-		rk3308->agc_asr_r[e->reg] = value >> RK3308_AGC_APPROX_RATE_SFT;
-		ucontrol->value.integer.value[0] = rk3308->agc_asr_r[e->reg];
-	} else {
-		regmap_read(rk3308->regmap, RK3308_ALC_L_DIG_CON04(grp), &value);
-		rk3308->agc_asr_l[e->reg] = value >> RK3308_AGC_APPROX_RATE_SFT;
-		ucontrol->value.integer.value[0] = rk3308->agc_asr_l[e->reg];
-	}
-
-	return 0;
-}
-
-static int rk3308_codec_agc_asr_put(struct snd_kcontrol *kcontrol,
-				    struct snd_ctl_elem_value *ucontrol)
-{
-	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
-	struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
-	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
-	unsigned int value;
-	int grp = e->reg;
-
-	if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) {
-		dev_err(rk3308->plat_dev,
-			"%s: Invalid ADC grp: %d\n", __func__, e->reg);
-		return -EINVAL;
-	}
-
-	value = ucontrol->value.integer.value[0] << RK3308_AGC_APPROX_RATE_SFT;
-
-	if (e->shift_l) {
-		/* ALC AGC Right Approximate Sample Rate */
-		regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON04(grp),
-				   RK3308_AGC_APPROX_RATE_MSK,
-				   value);
-		rk3308->agc_asr_r[e->reg] = ucontrol->value.integer.value[0];
-	} else {
-		/* ALC AGC Left Approximate Sample Rate */
-		regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON04(grp),
-				   RK3308_AGC_APPROX_RATE_MSK,
-				   value);
-		rk3308->agc_asr_l[e->reg] = ucontrol->value.integer.value[0];
-	}
-
-	return 0;
-}
 
 static int rk3308_codec_mic_mute_get(struct snd_kcontrol *kcontrol,
 				     struct snd_ctl_elem_value *ucontrol)
@@ -1487,15 +1076,25 @@
 	case SND_SOC_DAIFMT_CBS_CFS:
 		adc_aif2 |= RK3308_ADC_IO_MODE_SLAVE;
 		adc_aif2 |= RK3308_ADC_MODE_SLAVE;
-		dac_aif2 |= RK3308_DAC_IO_MODE_SLAVE;
-		dac_aif2 |= RK3308_DAC_MODE_SLAVE;
+		if (rk3308->codec_ver == ACODEC_VERSION_C) {
+			dac_aif2 |= RK3308BS_DAC_IO_MODE_SLAVE;
+			dac_aif2 |= RK3308BS_DAC_MODE_SLAVE;
+		} else {
+			dac_aif2 |= RK3308_DAC_IO_MODE_SLAVE;
+			dac_aif2 |= RK3308_DAC_MODE_SLAVE;
+		}
 		is_master = 0;
 		break;
 	case SND_SOC_DAIFMT_CBM_CFM:
 		adc_aif2 |= RK3308_ADC_IO_MODE_MASTER;
 		adc_aif2 |= RK3308_ADC_MODE_MASTER;
-		dac_aif2 |= RK3308_DAC_IO_MODE_MASTER;
-		dac_aif2 |= RK3308_DAC_MODE_MASTER;
+		if (rk3308->codec_ver == ACODEC_VERSION_C) {
+			dac_aif2 |= RK3308BS_DAC_IO_MODE_MASTER;
+			dac_aif2 |= RK3308BS_DAC_MODE_MASTER;
+		} else {
+			dac_aif2 |= RK3308_DAC_IO_MODE_MASTER;
+			dac_aif2 |= RK3308_DAC_MODE_MASTER;
+		}
 		is_master = 1;
 		break;
 	default:
@@ -1589,11 +1188,19 @@
 			   RK3308_DAC_I2S_LRC_POL_MSK |
 			   RK3308_DAC_I2S_MODE_MSK,
 			   dac_aif1);
-	regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02,
+	if (rk3308->codec_ver == ACODEC_VERSION_C) {
+		regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02,
+			   RK3308BS_DAC_IO_MODE_MSK |
+			   RK3308BS_DAC_MODE_MSK |
+			   RK3308_DAC_I2S_BIT_CLK_POL_MSK,
+			   dac_aif2);
+	} else {
+		regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02,
 			   RK3308_DAC_IO_MODE_MSK |
 			   RK3308_DAC_MODE_MSK |
 			   RK3308_DAC_I2S_BIT_CLK_POL_MSK,
 			   dac_aif2);
+	}
 
 	return 0;
 }
@@ -1729,18 +1336,20 @@
 		int dgain;
 
 		if (mute) {
-			for (dgain = 0x2; dgain <= 0x7; dgain++) {
-				/*
-				 * Keep the max -> min digital CIC interpolation
-				 * filter gain step by step.
-				 *
-				 * loud: 0x2; whisper: 0x7
-				 */
-				regmap_update_bits(rk3308->regmap,
-						   RK3308_DAC_DIG_CON04,
-						   RK3308_DAC_CIC_IF_GAIN_MSK,
-						   dgain);
-				usleep_range(200, 300);  /* estimated value */
+			if (rk3308->codec_ver <= ACODEC_VERSION_B) {
+				for (dgain = 0x2; dgain <= 0x7; dgain++) {
+					/*
+					 * Keep the max -> min digital CIC interpolation
+					 * filter gain step by step.
+					 *
+					 * loud: 0x2; whisper: 0x7
+					 */
+					regmap_update_bits(rk3308->regmap,
+							   RK3308_DAC_DIG_CON04,
+							   RK3308_DAC_CIC_IF_GAIN_MSK,
+							   dgain);
+					usleep_range(200, 300);  /* estimated value */
+				}
 			}
 
 #if !DEBUG_POP_ALWAYS
@@ -1757,18 +1366,20 @@
 			if (rk3308->delay_start_play_ms)
 				msleep(rk3308->delay_start_play_ms);
 #endif
-			for (dgain = 0x7; dgain >= 0x2; dgain--) {
-				/*
-				 * Keep the min -> max digital CIC interpolation
-				 * filter gain step by step
-				 *
-				 * loud: 0x2; whisper: 0x7
-				 */
-				regmap_update_bits(rk3308->regmap,
-						   RK3308_DAC_DIG_CON04,
-						   RK3308_DAC_CIC_IF_GAIN_MSK,
-						   dgain);
-				usleep_range(200, 300);  /* estimated value */
+			if (rk3308->codec_ver <= ACODEC_VERSION_B) {
+				for (dgain = 0x7; dgain >= 0x2; dgain--) {
+					/*
+					 * Keep the min -> max digital CIC interpolation
+					 * filter gain step by step
+					 *
+					 * loud: 0x2; whisper: 0x7
+					 */
+					regmap_update_bits(rk3308->regmap,
+							   RK3308_DAC_DIG_CON04,
+							   RK3308_DAC_CIC_IF_GAIN_MSK,
+							   dgain);
+					usleep_range(200, 300);  /* estimated value */
+				}
 			}
 		}
 	}
@@ -1856,6 +1467,14 @@
 
 static int rk3308_codec_dac_lineout_enable(struct rk3308_codec_priv *rk3308)
 {
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15,
+			   RK3308_DAC_LINEOUT_POP_SOUND_L_MSK |
+			   RK3308_DAC_LINEOUT_POP_SOUND_R_MSK,
+			   RK3308_DAC_L_SEL_LINEOUT_FROM_INTERNAL |
+			   RK3308_DAC_R_SEL_LINEOUT_FROM_INTERNAL);
+
+	udelay(20);
+
 	/* Step 07 */
 	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04,
 			   RK3308_DAC_L_LINEOUT_EN |
@@ -1892,11 +1511,22 @@
 			   RK3308_DAC_L_LINEOUT_DIS |
 			   RK3308_DAC_R_LINEOUT_DIS);
 
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15,
+			   RK3308_DAC_LINEOUT_POP_SOUND_L_MSK |
+			   RK3308_DAC_LINEOUT_POP_SOUND_R_MSK,
+			   RK3308_DAC_L_SEL_DC_FROM_INTERNAL |
+			   RK3308_DAC_R_SEL_DC_FROM_INTERNAL);
+
 	return 0;
 }
 
 static int rk3308_codec_dac_hpout_enable(struct rk3308_codec_priv *rk3308)
 {
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01,
+			   RK3308_DAC_HPOUT_POP_SOUND_L_MSK |
+			   RK3308_DAC_HPOUT_POP_SOUND_R_MSK,
+			   RK3308_DAC_HPOUT_POP_SOUND_L_WORK |
+			   RK3308_DAC_HPOUT_POP_SOUND_R_WORK);
 	udelay(20);
 
 	/* Step 07 */
@@ -1952,6 +1582,12 @@
 			   RK3308_DAC_L_HPOUT_MUTE |
 			   RK3308_DAC_R_HPOUT_MUTE);
 
+	udelay(20);
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01,
+			   RK3308_DAC_HPOUT_POP_SOUND_L_MSK |
+			   RK3308_DAC_HPOUT_POP_SOUND_R_MSK,
+			   RK3308_DAC_HPOUT_POP_SOUND_L_DIS |
+			   RK3308_DAC_HPOUT_POP_SOUND_R_DIS);
 	return 0;
 }
 
@@ -2075,7 +1711,7 @@
 
 	udelay(20);
 
-	if (rk3308->codec_ver == ACODEC_VERSION_B &&
+	if (rk3308->codec_ver >= ACODEC_VERSION_B &&
 	    (rk3308->dac_output == DAC_LINEOUT ||
 	     rk3308->dac_output == DAC_LINEOUT_HPOUT)) {
 		/* Step 04 */
@@ -2146,13 +1782,22 @@
 		udelay(20);
 	}
 
-	if (rk3308->codec_ver == ACODEC_VERSION_B) {
+	if (rk3308->codec_ver >= ACODEC_VERSION_B) {
 		/* Step 10 */
-		regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15,
+		if (rk3308->dac_output == DAC_HPOUT) {
+			regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15,
+				   RK3308_DAC_LINEOUT_POP_SOUND_L_MSK |
+				   RK3308_DAC_LINEOUT_POP_SOUND_R_MSK,
+				   RK3308_DAC_L_SEL_DC_FROM_INTERNAL |
+				   RK3308_DAC_R_SEL_DC_FROM_INTERNAL);
+		} else {
+			/* LINEOUT and LINEOUT + HPOUT */
+			regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15,
 				   RK3308_DAC_LINEOUT_POP_SOUND_L_MSK |
 				   RK3308_DAC_LINEOUT_POP_SOUND_R_MSK,
 				   RK3308_DAC_L_SEL_LINEOUT_FROM_INTERNAL |
 				   RK3308_DAC_R_SEL_LINEOUT_FROM_INTERNAL);
+		}
 
 		udelay(20);
 	}
@@ -2352,7 +1997,7 @@
 			   RK3308_DAC_HPOUT_POP_SOUND_R_INIT);
 
 	/* Step 15 */
-	if (rk3308->codec_ver == ACODEC_VERSION_B &&
+	if (rk3308->codec_ver >= ACODEC_VERSION_B &&
 	    (rk3308->dac_output == DAC_LINEOUT ||
 	     rk3308->dac_output == DAC_LINEOUT_HPOUT)) {
 		regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON15,
@@ -2422,7 +2067,7 @@
 			   RK3308_DAC_HPOUT_POP_SOUND_R_MSK,
 			   RK3308_DAC_HPOUT_POP_SOUND_R_INIT);
 
-	if (rk3308->codec_ver == ACODEC_VERSION_B) {
+	if (rk3308->codec_ver >= ACODEC_VERSION_B) {
 		/*
 		 * 2. Configure ACODEC_DAC_ANA_CON15[1:0] and
 		 *    ACODEC_DAC_ANA_CON15[5:4] to 0x1, to setup dc voltage of
@@ -2443,7 +2088,7 @@
 			   RK3308_ADC_CURRENT_CHARGE_MSK,
 			   RK3308_ADC_SEL_I(0x1));
 
-	if (rk3308->codec_ver == ACODEC_VERSION_B) {
+	if (rk3308->codec_ver >= ACODEC_VERSION_B) {
 		/*
 		 * 4. Configure the register ACODEC_ADC_ANA_CON14[3:0] to
 		 *    4’b0001.
@@ -2462,7 +2107,7 @@
 	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0),
 			   RK3308_ADC_REF_EN, RK3308_ADC_REF_EN);
 
-	if (rk3308->codec_ver == ACODEC_VERSION_B) {
+	if (rk3308->codec_ver >= ACODEC_VERSION_B) {
 		/*
 		 * 7. Configure the register ACODEC_ADC_ANA_CON14[4] to 0x1 to
 		 *    setup reference voltage
@@ -2484,7 +2129,7 @@
 		udelay(200);
 	}
 
-	if (rk3308->codec_ver == ACODEC_VERSION_B) {
+	if (rk3308->codec_ver >= ACODEC_VERSION_B) {
 		/*
 		 * 9. Change the register ACODEC_ADC_ANA_CON14[3:0] from the 0x1
 		 *    to 0xf step by step or configure the
@@ -2509,13 +2154,19 @@
 	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0),
 			   RK3308_ADC_CURRENT_CHARGE_MSK, 0x7c);
 
-	if (rk3308->codec_ver == ACODEC_VERSION_B) {
+	if (rk3308->codec_ver >= ACODEC_VERSION_B) {
 		/*
 		 * 12. Configure the register ACODEC_DAC_ANA_CON14[6:0] to the
 		 *     appropriate value(expect 0x0) for reducing power.
 		 */
 		regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON14,
 				   RK3308_DAC_CURRENT_CHARGE_MSK, 0xf);
+	}
+
+	if (rk3308->codec_ver == ACODEC_VERSION_C) {
+		/* Using large driver strength for HPOUT and LINEOUT */
+		regmap_write(rk3308->regmap, RK3308_DAC_ANA_CON07, 0x11);
+		regmap_write(rk3308->regmap, RK3308_DAC_ANA_CON08, 0x11);
 	}
 
 	return 0;
@@ -2537,7 +2188,7 @@
 			   RK3308_ADC_CURRENT_CHARGE_MSK,
 			   RK3308_ADC_SEL_I(0x1));
 
-	if (rk3308->codec_ver == ACODEC_VERSION_B) {
+	if (rk3308->codec_ver >= ACODEC_VERSION_B) {
 		/*
 		 * 2. Configure the register ACODEC_DAC_ANA_CON14[3:0] to
 		 *    4’b0001.
@@ -2552,7 +2203,7 @@
 			   RK3308_ADC_REF_EN,
 			   RK3308_ADC_REF_DIS);
 
-	if (rk3308->codec_ver == ACODEC_VERSION_B) {
+	if (rk3308->codec_ver >= ACODEC_VERSION_B) {
 		/* 4. Configure the register ACODEC_DAC_ANA_CON14[7] to 0x0 */
 		regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON14,
 				   RK3308_DAC_VCM_LINEOUT_EN,
@@ -2571,7 +2222,7 @@
 		udelay(200);
 	}
 
-	if (rk3308->codec_ver == ACODEC_VERSION_B) {
+	if (rk3308->codec_ver >= ACODEC_VERSION_B) {
 		/*
 		 * 6. Change the register ACODEC_DAC_ANA_CON14[3:0] from the 0x1
 		 *    to 0xf step by step or configure the
@@ -2600,6 +2251,9 @@
 
 static int rk3308_codec_headset_detect_enable(struct rk3308_codec_priv *rk3308)
 {
+	if (rk3308->codec_ver == ACODEC_VERSION_C)
+		rk3308_codec_dac_mclk_enable(rk3308);
+
 	/*
 	 * Set ACODEC_DAC_ANA_CON0[1] to 0x1, to enable the headset insert
 	 * detection
@@ -2792,7 +2446,7 @@
 static bool handle_loopback(struct rk3308_codec_priv *rk3308)
 {
 	/* The version B doesn't need to handle loopback. */
-	if (rk3308->codec_ver == ACODEC_VERSION_B)
+	if (rk3308->codec_ver >= ACODEC_VERSION_B)
 		return false;
 
 	switch (rk3308->loopback_grp) {
@@ -3426,6 +3080,9 @@
 
 static void rk3308_codec_dac_mclk_disable(struct rk3308_codec_priv *rk3308)
 {
+	if (!rk3308->no_hp_det && rk3308->codec_ver == ACODEC_VERSION_C)
+		return;
+
 	regmap_update_bits(rk3308->regmap, RK3308_GLB_CON,
 			   RK3308_DAC_MCLK_MSK,
 			   RK3308_DAC_MCLK_DIS);
@@ -3849,31 +3506,49 @@
 				   RK3308_ADC_CH2_ALC_GAIN_0DB);
 	}
 
+	if (rk3308->codec_ver == ACODEC_VERSION_C) {
+		/* recover ADC digtial volume to 0dB */
+		for (grp = 0; grp < ADC_LR_GROUP_MAX; grp++) {
+			/* DIG_VOL: -97dB ~ +32dB  */
+			regmap_write(rk3308->regmap, RK3308BS_ADC_DIG_CON05(grp),
+					   RK3308_ADC_DIG_VOL_CON_L(RK3308_ADC_DIG_VOL_0DB));
+			regmap_write(rk3308->regmap, RK3308BS_ADC_DIG_CON06(grp),
+					   RK3308_ADC_DIG_VOL_CON_R(RK3308_ADC_DIG_VOL_0DB));
+		}
+	}
+
 	/* Prepare DAC gains */
 	/* Step 15, set HPMIX default gains */
 	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON12,
 			   RK3308_DAC_L_HPMIX_GAIN_MSK |
 			   RK3308_DAC_R_HPMIX_GAIN_MSK,
-			   RK3308_DAC_L_HPMIX_GAIN_NDB_6 |
-			   RK3308_DAC_R_HPMIX_GAIN_NDB_6);
+			   RK3308_DAC_L_HPMIX_GAIN_0DB |
+			   RK3308_DAC_R_HPMIX_GAIN_0DB);
 
 	/* Step 18, set HPOUT default gains */
 	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON05,
 			   RK3308_DAC_L_HPOUT_GAIN_MSK,
-			   RK3308_DAC_L_HPOUT_GAIN_NDB_39);
+			   RK3308_DAC_L_HPOUT_GAIN_0DB);
 	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON06,
 			   RK3308_DAC_R_HPOUT_GAIN_MSK,
-			   RK3308_DAC_R_HPOUT_GAIN_NDB_39);
+			   RK3308_DAC_R_HPOUT_GAIN_0DB);
 
 	/* Using the same gain to HPOUT LR channels */
-	rk3308->hpout_l_dgain = RK3308_DAC_L_HPOUT_GAIN_NDB_39;
+	rk3308->hpout_l_dgain = RK3308_DAC_L_HPOUT_GAIN_0DB;
+	rk3308->hpout_r_dgain = RK3308_DAC_R_HPOUT_GAIN_0DB;
 
 	/* Step 19, set LINEOUT default gains */
 	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04,
 			   RK3308_DAC_L_LINEOUT_GAIN_MSK |
 			   RK3308_DAC_R_LINEOUT_GAIN_MSK,
-			   RK3308_DAC_L_LINEOUT_GAIN_NDB_6 |
-			   RK3308_DAC_R_LINEOUT_GAIN_NDB_6);
+			   RK3308_DAC_L_LINEOUT_GAIN_0DB |
+			   RK3308_DAC_R_LINEOUT_GAIN_0DB);
+
+	if (rk3308->codec_ver == ACODEC_VERSION_C) {
+		/* recover DAC digtial gain to 0dB */
+		regmap_write(rk3308->regmap, RK3308BS_DAC_DIG_CON04,
+			     RK3308BS_DAC_DIG_GAIN(RK3308BS_DAC_DIG_0DB));
+	}
 
 	return 0;
 }
@@ -3935,7 +3610,7 @@
 {
 	int ret;
 
-	if (rk3308->codec_ver == ACODEC_VERSION_B) {
+	if (rk3308->codec_ver >= ACODEC_VERSION_B) {
 		ret = snd_soc_add_component_controls(rk3308->component,
 						     mic_gains_b,
 						     ARRAY_SIZE(mic_gains_b));
@@ -4020,13 +3695,8 @@
 {
 	int grp;
 
-	for (grp = 0; grp < ADC_LR_GROUP_MAX; grp++) {
+	for (grp = 0; grp < ADC_LR_GROUP_MAX; grp++)
 		rk3308->hpf_cutoff[grp] = 0;
-		rk3308->agc_l[grp] = 0;
-		rk3308->agc_r[grp] = 0;
-		rk3308->agc_asr_l[grp] = AGC_ASR_96KHZ;
-		rk3308->agc_asr_r[grp] = AGC_ASR_96KHZ;
-	}
 
 	rk3308_codec_dapm_mic_gains(rk3308);
 
@@ -4089,6 +3759,28 @@
 	regcache_sync(rk3308->regmap);
 }
 
+static int rk3308_codec_set_jack(struct snd_soc_component *component,
+				 struct snd_soc_jack *jack, void *data)
+{
+	struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
+
+	/* Return directly if the DUT don't need to support headphone detection */
+	if (rk3308->no_hp_det)
+		return 0;
+
+	rk3308->hpdet_jack = jack;
+
+	/* To detect jack once during startup */
+	disable_irq_nosync(rk3308->irq);
+	queue_delayed_work(system_power_efficient_wq,
+			   &rk3308->hpdet_work, msecs_to_jiffies(10));
+
+	dev_info(rk3308->plat_dev, "%s: Request detect hp jack once\n",
+		 __func__);
+
+	return 0;
+}
+
 static const struct snd_soc_component_driver soc_codec_dev_rk3308 = {
 	.probe = rk3308_probe,
 	.remove = rk3308_remove,
@@ -4097,6 +3789,7 @@
 	.set_bias_level = rk3308_set_bias_level,
 	.controls = rk3308_codec_dapm_controls,
 	.num_controls = ARRAY_SIZE(rk3308_codec_dapm_controls),
+	.set_jack = rk3308_codec_set_jack,
 };
 
 static const struct reg_default rk3308_codec_reg_defaults[] = {
@@ -4118,12 +3811,15 @@
 {
 	struct rk3308_codec_priv *rk3308 =
 		container_of(work, struct rk3308_codec_priv, hpdet_work.work);
-	unsigned int val;
+	unsigned int val, headphone_con = RK3308_CODEC_HEADPHONE_CON;
 	int need_poll = 0, need_irq = 0;
 	int need_report = 0, report_type = 0;
 	int dac_output = DAC_LINEOUT;
 
-	if (rk3308->codec_ver == ACODEC_VERSION_B) {
+	if (rk3308->codec_ver == ACODEC_VERSION_C)
+		headphone_con = RK3308BS_CODEC_HEADPHONE_CON;
+
+	if (rk3308->codec_ver >= ACODEC_VERSION_B) {
 		/* Check headphone plugged/unplugged directly. */
 		regmap_read(rk3308->detect_grf,
 			    DETECT_GRF_ACODEC_HPDET_STATUS, &val);
@@ -4164,7 +3860,7 @@
 	}
 
 	/* Check headphone unplugged via poll. */
-	regmap_read(rk3308->regmap, RK3308_DAC_DIG_CON14, &val);
+	regmap_read(rk3308->regmap, headphone_con, &val);
 
 	if (rk3308->hp_jack_reversed) {
 		if (!val) {
@@ -4259,26 +3955,6 @@
 			   &rk3308->hpdet_work, msecs_to_jiffies(10));
 
 	return IRQ_HANDLED;
-}
-
-void (*rk3308_codec_set_jack_detect_cb)(struct snd_soc_component *component,
-					struct snd_soc_jack *hpdet_jack);
-EXPORT_SYMBOL_GPL(rk3308_codec_set_jack_detect_cb);
-
-static void rk3308_codec_set_jack_detect(struct snd_soc_component *component,
-				  struct snd_soc_jack *hpdet_jack)
-{
-	struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
-
-	rk3308->hpdet_jack = hpdet_jack;
-
-	/* To detect jack once during startup */
-	disable_irq_nosync(rk3308->irq);
-	queue_delayed_work(system_power_efficient_wq,
-			   &rk3308->hpdet_work, msecs_to_jiffies(10));
-
-	dev_info(rk3308->plat_dev, "%s: Request detect hp jack once\n",
-		 __func__);
 }
 
 static const struct regmap_config rk3308_codec_regmap_config = {
@@ -4721,6 +4397,16 @@
 	return 0;
 }
 
+static void rk3308_codec_sysfs_exit(struct rk3308_codec_priv *rk3308)
+{
+	struct device *dev = &rk3308->dev;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(acodec_attrs); i++)
+		device_remove_file(dev, &acodec_attrs[i]);
+	device_unregister(dev);
+}
+
 #if defined(CONFIG_DEBUG_FS)
 static int rk3308_codec_debugfs_reg_show(struct seq_file *s, void *v)
 {
@@ -4808,6 +4494,9 @@
 	case 0x3308:
 		rk3308->codec_ver = ACODEC_VERSION_B;
 		break;
+	case 0x3308c:
+		rk3308->codec_ver = ACODEC_VERSION_C;
+		break;
 	default:
 		pr_err("Unknown chip_id: %d / 0x%x\n", chip_id, chip_id);
 		return -EFAULT;
@@ -4836,6 +4525,10 @@
 		return PTR_ERR(rk3308->grf);
 	}
 
+	ret = rk3308_codec_get_version(rk3308);
+	if (ret < 0)
+		return dev_err_probe(&pdev->dev, ret, "Failed to get acodec version\n");
+
 	ret = rk3308_codec_sysfs_init(pdev, rk3308);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Sysfs init failed\n");
@@ -4857,7 +4550,7 @@
 	if (IS_ERR(rk3308->reset)) {
 		ret = PTR_ERR(rk3308->reset);
 		if (ret != -ENOENT)
-			return ret;
+			goto out_sysfs;
 
 		dev_dbg(&pdev->dev, "No reset control found\n");
 		rk3308->reset = NULL;
@@ -4870,7 +4563,7 @@
 	} else if (IS_ERR(rk3308->hp_ctl_gpio)) {
 		ret = PTR_ERR(rk3308->hp_ctl_gpio);
 		dev_err(&pdev->dev, "Unable to claim gpio hp-ctl\n");
-		return ret;
+		goto out_sysfs;
 	}
 
 	rk3308->spk_ctl_gpio = devm_gpiod_get_optional(&pdev->dev, "spk-ctl",
@@ -4881,7 +4574,7 @@
 	} else if (IS_ERR(rk3308->spk_ctl_gpio)) {
 		ret = PTR_ERR(rk3308->spk_ctl_gpio);
 		dev_err(&pdev->dev, "Unable to claim gpio spk-ctl\n");
-		return ret;
+		goto out_sysfs;
 	}
 
 	rk3308->pa_drv_gpio = devm_gpiod_get_optional(&pdev->dev, "pa-drv",
@@ -4892,7 +4585,7 @@
 	} else if (IS_ERR(rk3308->pa_drv_gpio)) {
 		ret = PTR_ERR(rk3308->pa_drv_gpio);
 		dev_err(&pdev->dev, "Unable to claim gpio pa-drv\n");
-		return ret;
+		goto out_sysfs;
 	}
 
 	if (rk3308->pa_drv_gpio) {
@@ -4914,37 +4607,40 @@
 	rk3308->pclk = devm_clk_get(&pdev->dev, "acodec");
 	if (IS_ERR(rk3308->pclk)) {
 		dev_err(&pdev->dev, "Can't get acodec pclk\n");
-		return PTR_ERR(rk3308->pclk);
+		ret = PTR_ERR(rk3308->pclk);
+		goto out_sysfs;
 	}
 
 	rk3308->mclk_rx = devm_clk_get(&pdev->dev, "mclk_rx");
 	if (IS_ERR(rk3308->mclk_rx)) {
 		dev_err(&pdev->dev, "Can't get acodec mclk_rx\n");
-		return PTR_ERR(rk3308->mclk_rx);
+		ret = PTR_ERR(rk3308->mclk_rx);
+		goto out_sysfs;
 	}
 
 	rk3308->mclk_tx = devm_clk_get(&pdev->dev, "mclk_tx");
 	if (IS_ERR(rk3308->mclk_tx)) {
 		dev_err(&pdev->dev, "Can't get acodec mclk_tx\n");
-		return PTR_ERR(rk3308->mclk_tx);
+		ret = PTR_ERR(rk3308->mclk_tx);
+		goto out_sysfs;
 	}
 
 	ret = clk_prepare_enable(rk3308->pclk);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Failed to enable acodec pclk: %d\n", ret);
-		return ret;
+		goto out_sysfs;
 	}
 
 	ret = clk_prepare_enable(rk3308->mclk_rx);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Failed to enable i2s mclk_rx: %d\n", ret);
-		return ret;
+		goto out_pclk;
 	}
 
 	ret = clk_prepare_enable(rk3308->mclk_tx);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Failed to enable i2s mclk_tx: %d\n", ret);
-		return ret;
+		goto out_mclk_rx;
 	}
 
 	rk3308_codec_check_micbias(rk3308, np);
@@ -4979,28 +4675,21 @@
 	if (ret < 0 && ret != -EINVAL) {
 		dev_err(&pdev->dev, "Failed to read loopback property: %d\n",
 			ret);
-		return ret;
+		goto failed;
 	}
 
 	ret = rk3308_codec_adc_grps_route(rk3308, np);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Failed to route ADC groups: %d\n",
 			ret);
-		return ret;
+		goto failed;
 	}
 
 	ret = rk3308_codec_setup_en_always_adcs(rk3308, np);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Failed to setup enabled always ADCs: %d\n",
 			ret);
-		return ret;
-	}
-
-	ret = rk3308_codec_get_version(rk3308);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to get acodec version: %d\n",
-			ret);
-		return ret;
+		goto failed;
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -5022,7 +4711,7 @@
 	if (!rk3308->no_hp_det) {
 		int index = 0;
 
-		if (rk3308->codec_ver == ACODEC_VERSION_B)
+		if (rk3308->codec_ver >= ACODEC_VERSION_B)
 			index = 1;
 
 		rk3308->irq = platform_get_irq(pdev, index);
@@ -5043,13 +4732,14 @@
 			goto failed;
 		}
 
-		if (rk3308->codec_ver == ACODEC_VERSION_B) {
+		if (rk3308->codec_ver >= ACODEC_VERSION_B) {
 			rk3308->detect_grf =
 				syscon_regmap_lookup_by_phandle(np, "rockchip,detect-grf");
 			if (IS_ERR(rk3308->detect_grf)) {
 				dev_err(&pdev->dev,
 					"Missing 'rockchip,detect-grf' property\n");
-				return PTR_ERR(rk3308->detect_grf);
+				ret = PTR_ERR(rk3308->detect_grf);
+				goto failed;
 			}
 
 			/* Configure filter count and enable hpdet irq. */
@@ -5061,8 +4751,6 @@
 				     (HPDET_BOTH_NEG_POS << 16) |
 				      HPDET_BOTH_NEG_POS);
 		}
-
-		rk3308_codec_set_jack_detect_cb = rk3308_codec_set_jack_detect;
 	}
 
 	if (rk3308->codec_ver == ACODEC_VERSION_A)
@@ -5086,10 +4774,13 @@
 	return ret;
 
 failed:
-	clk_disable_unprepare(rk3308->mclk_rx);
 	clk_disable_unprepare(rk3308->mclk_tx);
+out_mclk_rx:
+	clk_disable_unprepare(rk3308->mclk_rx);
+out_pclk:
 	clk_disable_unprepare(rk3308->pclk);
-	device_unregister(&rk3308->dev);
+out_sysfs:
+	rk3308_codec_sysfs_exit(rk3308);
 
 	return ret;
 }

--
Gitblit v1.6.2