From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Xing Zheng <zhengxing@rock-chips.com>
Date: Sun, 11 Mar 2018 11:37:28 +0800
Subject: ASoC: codecs: Add RK3308 internal codec driver

This adds support for the RK3308 audio codec.

Change-Id: Ieccdebaa27f4a46f6de9406046a6e02e20398013
Signed-off-by: Xing Zheng <zhengxing@rock-chips.com>
---
 sound/soc/codecs/Kconfig        |    5 +
 sound/soc/codecs/Makefile       |    2 +
 sound/soc/codecs/rk3308_codec.c | 1604 ++++++++++
 sound/soc/codecs/rk3308_codec.h |  960 ++++++
 4 files changed, 2571 insertions(+)

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index f1e1dbc509f6..8ce353dad530 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -177,6 +177,7 @@ config SND_SOC_ALL_CODECS
 	imply SND_SOC_PCM512x_I2C
 	imply SND_SOC_PCM512x_SPI
 	imply SND_SOC_PEB2466
+	imply SND_SOC_RK3308
 	imply SND_SOC_RK3328
 	imply SND_SOC_RK817
 	imply SND_SOC_RT274
@@ -1370,6 +1371,10 @@ config SND_SOC_PEB2466
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-soc-peb2466.
 
+config SND_SOC_RK3308
+	select REGMAP_MMIO
+	tristate "Rockchip RK3308 CODEC"
+
 config SND_SOC_RK3328
 	tristate "Rockchip RK3328 audio CODEC"
 	select REGMAP_MMIO
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index a87e56938ce5..8f539b13864d 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -199,6 +199,7 @@ snd-soc-pcm512x-objs := pcm512x.o
 snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
 snd-soc-pcm512x-spi-objs := pcm512x-spi.o
 snd-soc-peb2466-objs := peb2466.o
+snd-soc-rk3308-objs := rk3308_codec.o
 snd-soc-rk3328-objs := rk3328_codec.o
 snd-soc-rk817-objs := rk817_codec.o
 snd-soc-rl6231-objs := rl6231.o
@@ -580,6 +581,7 @@ obj-$(CONFIG_SND_SOC_PCM512x)	+= snd-soc-pcm512x.o
 obj-$(CONFIG_SND_SOC_PCM512x_I2C)	+= snd-soc-pcm512x-i2c.o
 obj-$(CONFIG_SND_SOC_PCM512x_SPI)	+= snd-soc-pcm512x-spi.o
 obj-$(CONFIG_SND_SOC_PEB2466)	+= snd-soc-peb2466.o
+obj-$(CONFIG_SND_SOC_RK3308)	+= snd-soc-rk3308.o
 obj-$(CONFIG_SND_SOC_RK3328)	+= snd-soc-rk3328.o
 obj-$(CONFIG_SND_SOC_RK817)	+= snd-soc-rk817.o
 obj-$(CONFIG_SND_SOC_RL6231)	+= snd-soc-rl6231.o
diff --git a/sound/soc/codecs/rk3308_codec.c b/sound/soc/codecs/rk3308_codec.c
new file mode 100644
index 000000000000..106f09738dd0
--- /dev/null
+++ b/sound/soc/codecs/rk3308_codec.c
@@ -0,0 +1,1604 @@
+/*
+ * rk3308_codec.c -- RK3308 ALSA Soc Audio Driver
+ *
+ * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/rockchip/grf.h>
+#include <linux/version.h>
+#include <sound/core.h>
+#include <sound/dmaengine_pcm.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+
+#include "rk3308_codec.h"
+
+struct rk3308_codec_priv {
+	const struct device *plat_dev;
+	struct device dev;
+	struct reset_control *reset;
+	struct regmap *regmap;
+	struct clk *pclk;
+	struct gpio_desc *spk_ctl_gpio;
+	int adc_ch;			/* To select ADCs for channel */
+	int adc_ch0_using_linein;
+};
+
+static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_ch_gain_tlv,
+				  -1800, 150, 2850);
+static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_ch_max_gain_tlv,
+				  -1350, 600, 2850);
+static const DECLARE_TLV_DB_SCALE(rk3308_codec_alc_agc_ch_min_gain_tlv,
+				  -1800, 600, 2400);
+static const DECLARE_TLV_DB_SCALE(rk3308_codec_adc_mic_gain_tlv,
+				  0, 600, 3000);
+static const DECLARE_TLV_DB_SCALE(rk3308_codec_adc_alc_gain_tlv,
+				  -1800, 150, 2850);
+static const DECLARE_TLV_DB_SCALE(rk3308_codec_dac_gain_tlv,
+				  0, 150, 600);
+static const DECLARE_TLV_DB_SCALE(rk3308_codec_dac_hpout_gain_tlv,
+				  -3900, 150, 600);
+static const DECLARE_TLV_DB_SCALE(rk3308_codec_dac_hpmix_gain_tlv,
+				  -600, 600, 0);
+
+static const struct snd_kcontrol_new rk3308_codec_dapm_controls[] = {
+	/* ALC AGC Channel*/
+	SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 0 Volume",
+			     RK3308_ALC_L_DIG_CON03(0),
+			     RK3308_ALC_R_DIG_CON03(0),
+			     RK3308_AGC_PGA_GAIN_SFT,
+			     RK3308_AGC_PGA_GAIN_NDB_18,
+			     RK3308_AGC_PGA_GAIN_PDB_28_5,
+			     0, rk3308_codec_alc_agc_ch_gain_tlv),
+	SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 1 Volume",
+			     RK3308_ALC_L_DIG_CON03(1),
+			     RK3308_ALC_R_DIG_CON03(1),
+			     RK3308_AGC_PGA_GAIN_SFT,
+			     RK3308_AGC_PGA_GAIN_NDB_18,
+			     RK3308_AGC_PGA_GAIN_PDB_28_5,
+			     0, rk3308_codec_alc_agc_ch_gain_tlv),
+	SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 2 Volume",
+			     RK3308_ALC_L_DIG_CON03(2),
+			     RK3308_ALC_R_DIG_CON03(2),
+			     RK3308_AGC_PGA_GAIN_SFT,
+			     RK3308_AGC_PGA_GAIN_NDB_18,
+			     RK3308_AGC_PGA_GAIN_PDB_28_5,
+			     0, rk3308_codec_alc_agc_ch_gain_tlv),
+	SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 3 Volume",
+			     RK3308_ALC_L_DIG_CON03(3),
+			     RK3308_ALC_R_DIG_CON03(3),
+			     RK3308_AGC_PGA_GAIN_SFT,
+			     RK3308_AGC_PGA_GAIN_NDB_18,
+			     RK3308_AGC_PGA_GAIN_PDB_28_5,
+			     0, rk3308_codec_alc_agc_ch_gain_tlv),
+
+	/* ALC AGC MAX */
+	SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 0 Max Volume",
+			     RK3308_ALC_L_DIG_CON09(0),
+			     RK3308_ALC_R_DIG_CON09(0),
+			     RK3308_AGC_MAX_GAIN_PGA_SFT,
+			     RK3308_AGC_MAX_GAIN_PGA_NDB_13_5,
+			     RK3308_AGC_MAX_GAIN_PGA_PDB_28_5,
+			     0, rk3308_codec_alc_agc_ch_max_gain_tlv),
+	SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 1 Max Volume",
+			     RK3308_ALC_L_DIG_CON09(1),
+			     RK3308_ALC_R_DIG_CON09(1),
+			     RK3308_AGC_MAX_GAIN_PGA_SFT,
+			     RK3308_AGC_MAX_GAIN_PGA_NDB_13_5,
+			     RK3308_AGC_MAX_GAIN_PGA_PDB_28_5,
+			     0, rk3308_codec_alc_agc_ch_max_gain_tlv),
+	SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 2 Max Volume",
+			     RK3308_ALC_L_DIG_CON09(2),
+			     RK3308_ALC_R_DIG_CON09(2),
+			     RK3308_AGC_MAX_GAIN_PGA_SFT,
+			     RK3308_AGC_MAX_GAIN_PGA_NDB_13_5,
+			     RK3308_AGC_MAX_GAIN_PGA_PDB_28_5,
+			     0, rk3308_codec_alc_agc_ch_max_gain_tlv),
+	SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 3 Max Volume",
+			     RK3308_ALC_L_DIG_CON09(3),
+			     RK3308_ALC_R_DIG_CON09(3),
+			     RK3308_AGC_MAX_GAIN_PGA_SFT,
+			     RK3308_AGC_MAX_GAIN_PGA_NDB_13_5,
+			     RK3308_AGC_MAX_GAIN_PGA_PDB_28_5,
+			     0, rk3308_codec_alc_agc_ch_max_gain_tlv),
+
+	/* ALC AGC MIN */
+	SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 0 Min Volume",
+			     RK3308_ALC_L_DIG_CON09(0),
+			     RK3308_ALC_R_DIG_CON09(0),
+			     RK3308_AGC_MIN_GAIN_PGA_SFT,
+			     RK3308_AGC_MIN_GAIN_PGA_NDB_18,
+			     RK3308_AGC_MIN_GAIN_PGA_PDB_24,
+			     0, rk3308_codec_alc_agc_ch_min_gain_tlv),
+	SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 1 Min Volume",
+			     RK3308_ALC_L_DIG_CON09(1),
+			     RK3308_ALC_R_DIG_CON09(1),
+			     RK3308_AGC_MIN_GAIN_PGA_SFT,
+			     RK3308_AGC_MIN_GAIN_PGA_NDB_18,
+			     RK3308_AGC_MIN_GAIN_PGA_PDB_24,
+			     0, rk3308_codec_alc_agc_ch_min_gain_tlv),
+	SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 2 Min Volume",
+			     RK3308_ALC_L_DIG_CON09(2),
+			     RK3308_ALC_R_DIG_CON09(2),
+			     RK3308_AGC_MIN_GAIN_PGA_SFT,
+			     RK3308_AGC_MIN_GAIN_PGA_NDB_18,
+			     RK3308_AGC_MIN_GAIN_PGA_PDB_24,
+			     0, rk3308_codec_alc_agc_ch_min_gain_tlv),
+	SOC_DOUBLE_R_RANGE_TLV("ALC AGC Channel 3 Min Volume",
+			     RK3308_ALC_L_DIG_CON09(3),
+			     RK3308_ALC_R_DIG_CON09(3),
+			     RK3308_AGC_MIN_GAIN_PGA_SFT,
+			     RK3308_AGC_MIN_GAIN_PGA_NDB_18,
+			     RK3308_AGC_MIN_GAIN_PGA_PDB_24,
+			     0, rk3308_codec_alc_agc_ch_min_gain_tlv),
+
+	/* ADC MIC */
+	SOC_SINGLE_RANGE_TLV("ADC MIC Channel 0 Left Volume",
+			     RK3308_ADC_ANA_CON01(0),
+			     RK3308_ADC_CH1_MIC_GAIN_SFT,
+			     RK3308_ADC_CH1_MIC_GAIN_0DB,
+			     RK3308_ADC_CH1_MIC_GAIN_30DB,
+			     0, rk3308_codec_adc_mic_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("ADC MIC Channel 0 Right Volume",
+			     RK3308_ADC_ANA_CON01(0),
+			     RK3308_ADC_CH2_MIC_GAIN_SFT,
+			     RK3308_ADC_CH2_MIC_GAIN_0DB,
+			     RK3308_ADC_CH2_MIC_GAIN_30DB,
+			     0, rk3308_codec_adc_mic_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("ADC MIC Channel 1 Left Volume",
+			     RK3308_ADC_ANA_CON01(1),
+			     RK3308_ADC_CH1_MIC_GAIN_SFT,
+			     RK3308_ADC_CH1_MIC_GAIN_0DB,
+			     RK3308_ADC_CH1_MIC_GAIN_30DB,
+			     0, rk3308_codec_adc_mic_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("ADC MIC Channel 1 Right Volume",
+			     RK3308_ADC_ANA_CON01(1),
+			     RK3308_ADC_CH2_MIC_GAIN_SFT,
+			     RK3308_ADC_CH2_MIC_GAIN_0DB,
+			     RK3308_ADC_CH2_MIC_GAIN_30DB,
+			     0, rk3308_codec_adc_mic_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("ADC MIC Channel 2 Left Volume",
+			     RK3308_ADC_ANA_CON01(2),
+			     RK3308_ADC_CH1_MIC_GAIN_SFT,
+			     RK3308_ADC_CH1_MIC_GAIN_0DB,
+			     RK3308_ADC_CH1_MIC_GAIN_30DB,
+			     0, rk3308_codec_adc_mic_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("ADC MIC Channel 2 Right Volume",
+			     RK3308_ADC_ANA_CON01(2),
+			     RK3308_ADC_CH2_MIC_GAIN_SFT,
+			     RK3308_ADC_CH2_MIC_GAIN_0DB,
+			     RK3308_ADC_CH2_MIC_GAIN_30DB,
+			     0, rk3308_codec_adc_mic_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("ADC MIC Channel 3 Left Volume",
+			     RK3308_ADC_ANA_CON01(3),
+			     RK3308_ADC_CH1_MIC_GAIN_SFT,
+			     RK3308_ADC_CH1_MIC_GAIN_0DB,
+			     RK3308_ADC_CH1_MIC_GAIN_30DB,
+			     0, rk3308_codec_adc_mic_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("ADC MIC Channel 3 Right Volume",
+			     RK3308_ADC_ANA_CON01(3),
+			     RK3308_ADC_CH2_MIC_GAIN_SFT,
+			     RK3308_ADC_CH2_MIC_GAIN_0DB,
+			     RK3308_ADC_CH2_MIC_GAIN_30DB,
+			     0, rk3308_codec_adc_mic_gain_tlv),
+
+	/* ADC ALC */
+	SOC_SINGLE_RANGE_TLV("ADC ALC Channel 0 Left Volume",
+			     RK3308_ADC_ANA_CON03(0),
+			     RK3308_ADC_CH1_ALC_GAIN_SFT,
+			     RK3308_ADC_CH1_ALC_GAIN_NDB_18,
+			     RK3308_ADC_CH1_ALC_GAIN_PDB_28_5,
+			     0, rk3308_codec_adc_alc_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("ADC ALC Channel 0 Right Volume",
+			     RK3308_ADC_ANA_CON04(0),
+			     RK3308_ADC_CH2_ALC_GAIN_SFT,
+			     RK3308_ADC_CH2_ALC_GAIN_NDB_18,
+			     RK3308_ADC_CH2_ALC_GAIN_PDB_28_5,
+			     0, rk3308_codec_adc_alc_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("ADC ALC Channel 1 Left Volume",
+			     RK3308_ADC_ANA_CON03(1),
+			     RK3308_ADC_CH1_ALC_GAIN_SFT,
+			     RK3308_ADC_CH1_ALC_GAIN_NDB_18,
+			     RK3308_ADC_CH1_ALC_GAIN_PDB_28_5,
+			     0, rk3308_codec_adc_alc_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("ADC ALC Channel 1 Right Volume",
+			     RK3308_ADC_ANA_CON04(1),
+			     RK3308_ADC_CH2_ALC_GAIN_SFT,
+			     RK3308_ADC_CH2_ALC_GAIN_NDB_18,
+			     RK3308_ADC_CH2_ALC_GAIN_PDB_28_5,
+			     0, rk3308_codec_adc_alc_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("ADC ALC Channel 2 Left Volume",
+			     RK3308_ADC_ANA_CON03(2),
+			     RK3308_ADC_CH1_ALC_GAIN_SFT,
+			     RK3308_ADC_CH1_ALC_GAIN_NDB_18,
+			     RK3308_ADC_CH1_ALC_GAIN_PDB_28_5,
+			     0, rk3308_codec_adc_alc_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("ADC ALC Channel 2 Right Volume",
+			     RK3308_ADC_ANA_CON04(2),
+			     RK3308_ADC_CH2_ALC_GAIN_SFT,
+			     RK3308_ADC_CH2_ALC_GAIN_NDB_18,
+			     RK3308_ADC_CH2_ALC_GAIN_PDB_28_5,
+			     0, rk3308_codec_adc_alc_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("ADC ALC Channel 3 Left Volume",
+			     RK3308_ADC_ANA_CON03(3),
+			     RK3308_ADC_CH1_ALC_GAIN_SFT,
+			     RK3308_ADC_CH1_ALC_GAIN_NDB_18,
+			     RK3308_ADC_CH1_ALC_GAIN_PDB_28_5,
+			     0, rk3308_codec_adc_alc_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("ADC ALC Channel 3 Right Volume",
+			     RK3308_ADC_ANA_CON04(3),
+			     RK3308_ADC_CH2_ALC_GAIN_SFT,
+			     RK3308_ADC_CH2_ALC_GAIN_NDB_18,
+			     RK3308_ADC_CH2_ALC_GAIN_PDB_28_5,
+			     0, rk3308_codec_adc_alc_gain_tlv),
+
+	/* DAC */
+	SOC_SINGLE_RANGE_TLV("DAC Left Volume",
+			     RK3308_DAC_ANA_CON04,
+			     RK3308_DAC_L_GAIN_SFT,
+			     RK3308_DAC_L_GAIN_0DB,
+			     RK3308_DAC_L_GAIN_PDB_6,
+			     0, rk3308_codec_dac_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("DAC Right Volume",
+			     RK3308_DAC_ANA_CON04,
+			     RK3308_DAC_R_GAIN_SFT,
+			     RK3308_DAC_R_GAIN_0DB,
+			     RK3308_DAC_R_GAIN_PDB_6,
+			     0, rk3308_codec_dac_gain_tlv),
+
+	/* DAC HPOUT */
+	SOC_SINGLE_RANGE_TLV("DAC HPOUT Left Volume",
+			     RK3308_DAC_ANA_CON05,
+			     RK3308_DAC_L_HPOUT_GAIN_SFT,
+			     RK3308_DAC_L_HPOUT_GAIN_NDB_39,
+			     RK3308_DAC_L_HPOUT_GAIN_PDB_6,
+			     0, rk3308_codec_dac_hpout_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("DAC HPOUT Right Volume",
+			     RK3308_DAC_ANA_CON06,
+			     RK3308_DAC_R_HPOUT_GAIN_SFT,
+			     RK3308_DAC_R_HPOUT_GAIN_NDB_39,
+			     RK3308_DAC_R_HPOUT_GAIN_PDB_6,
+			     0, rk3308_codec_dac_hpout_gain_tlv),
+
+	/* DAC HPMIX */
+	SOC_SINGLE_RANGE_TLV("DAC HPMIX Left Volume",
+			     RK3308_DAC_ANA_CON05,
+			     RK3308_DAC_L_HPMIX_GAIN_SFT,
+			     RK3308_DAC_L_HPMIX_GAIN_NDB_6,
+			     RK3308_DAC_L_HPMIX_GAIN_0DB,
+			     0, rk3308_codec_dac_hpmix_gain_tlv),
+	SOC_SINGLE_RANGE_TLV("DAC HPMIX Right Volume",
+			     RK3308_DAC_ANA_CON05,
+			     RK3308_DAC_R_HPMIX_GAIN_SFT,
+			     RK3308_DAC_R_HPMIX_GAIN_NDB_6,
+			     RK3308_DAC_R_HPMIX_GAIN_0DB,
+			     0, rk3308_codec_dac_hpmix_gain_tlv),
+};
+
+static void rk3308_speaker_ctl(struct rk3308_codec_priv *rk3308, int on)
+{
+	gpiod_direction_output(rk3308->spk_ctl_gpio, on);
+}
+
+static int rk3308_codec_reset(struct snd_soc_codec *codec)
+{
+	struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
+
+	reset_control_assert(rk3308->reset);
+	usleep_range(200, 300);		/* estimated value */
+	reset_control_deassert(rk3308->reset);
+
+	regmap_write(rk3308->regmap, RK3308_GLB_CON, 0x00);
+	usleep_range(200, 300);		/* estimated value */
+	regmap_write(rk3308->regmap, RK3308_GLB_CON,
+		     RK3308_SYS_WORK |
+		     RK3308_DAC_DIG_WORK |
+		     RK3308_ADC_DIG_WORK);
+
+	return 0;
+}
+
+static int rk3308_set_bias_level(struct snd_soc_codec *codec,
+				 enum snd_soc_bias_level level)
+{
+	switch (level) {
+	case SND_SOC_BIAS_ON:
+		break;
+
+	case SND_SOC_BIAS_PREPARE:
+		break;
+
+	case SND_SOC_BIAS_STANDBY:
+	case SND_SOC_BIAS_OFF:
+		break;
+	}
+
+	snd_soc_codec_force_bias_level(codec, level);
+
+	return 0;
+}
+
+static int rk3308_set_dai_fmt(struct snd_soc_dai *codec_dai,
+			      unsigned int fmt)
+{
+	struct snd_soc_codec *codec = codec_dai->codec;
+	struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
+	unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0;
+	int ch = rk3308->adc_ch;
+
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	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;
+		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;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_DSP_A:
+		adc_aif1 |= RK3308_ADC_I2S_MODE_PCM;
+		dac_aif1 |= RK3308_DAC_I2S_MODE_PCM;
+		break;
+	case SND_SOC_DAIFMT_I2S:
+		adc_aif1 |= RK3308_ADC_I2S_MODE_I2S;
+		dac_aif1 |= RK3308_DAC_I2S_MODE_I2S;
+		break;
+	case SND_SOC_DAIFMT_RIGHT_J:
+		adc_aif1 |= RK3308_ADC_I2S_MODE_RJ;
+		dac_aif1 |= RK3308_DAC_I2S_MODE_RJ;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		adc_aif1 |= RK3308_ADC_I2S_MODE_RJ;
+		dac_aif1 |= RK3308_DAC_I2S_MODE_LJ;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+		adc_aif1 |= RK3308_ADC_I2S_LRC_POL_NORMAL;
+		adc_aif2 |= RK3308_ADC_I2S_BIT_CLK_POL_NORMAL;
+		dac_aif1 |= RK3308_DAC_I2S_LRC_POL_NORMAL;
+		dac_aif2 |= RK3308_DAC_I2S_BIT_CLK_POL_NORMAL;
+		break;
+	case SND_SOC_DAIFMT_IB_IF:
+		adc_aif1 |= RK3308_ADC_I2S_LRC_POL_REVERSAL;
+		adc_aif2 |= RK3308_ADC_I2S_BIT_CLK_POL_REVERSAL;
+		dac_aif1 |= RK3308_DAC_I2S_LRC_POL_REVERSAL;
+		dac_aif2 |= RK3308_DAC_I2S_BIT_CLK_POL_REVERSAL;
+		break;
+	case SND_SOC_DAIFMT_IB_NF:
+		adc_aif1 |= RK3308_ADC_I2S_LRC_POL_NORMAL;
+		adc_aif2 |= RK3308_ADC_I2S_BIT_CLK_POL_REVERSAL;
+		dac_aif1 |= RK3308_DAC_I2S_LRC_POL_NORMAL;
+		dac_aif2 |= RK3308_DAC_I2S_BIT_CLK_POL_REVERSAL;
+		break;
+	case SND_SOC_DAIFMT_NB_IF:
+		adc_aif1 |= RK3308_ADC_I2S_LRC_POL_REVERSAL;
+		adc_aif2 |= RK3308_ADC_I2S_BIT_CLK_POL_NORMAL;
+		dac_aif1 |= RK3308_DAC_I2S_LRC_POL_REVERSAL;
+		dac_aif2 |= RK3308_DAC_I2S_BIT_CLK_POL_NORMAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON01(ch),
+			   RK3308_ADC_I2S_LRC_POL_MSK |
+			   RK3308_ADC_I2S_MODE_MSK,
+			   adc_aif1);
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON02(ch),
+			   RK3308_ADC_IO_MODE_MSK |
+			   RK3308_ADC_MODE_MSK |
+			   RK3308_ADC_I2S_BIT_CLK_POL_MSK,
+			   adc_aif2);
+
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON01,
+			   RK3308_DAC_I2S_LRC_POL_MSK |
+			   RK3308_DAC_I2S_MODE_MSK,
+			   dac_aif1);
+	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;
+}
+
+static int rk3308_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params,
+			    struct snd_soc_dai *dai)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
+	unsigned int adc_aif1 = 0, adc_aif2  = 0, dac_aif1 = 0, dac_aif2  = 0;
+	int ch = rk3308->adc_ch;
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_16BITS;
+		dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_16BITS;
+		break;
+	case SNDRV_PCM_FORMAT_S20_3LE:
+		adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_20BITS;
+		dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_20BITS;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_24BITS;
+		dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_24BITS;
+		break;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_32BITS;
+		dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_32BITS;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (params_channels(params)) {
+	case 1:
+		adc_aif1 |= RK3308_ADC_I2S_MONO;
+		break;
+	case 2:
+		adc_aif1 |= RK3308_ADC_I2S_STEREO;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	adc_aif1 |= RK3308_ADC_I2S_LR_NORMAL;
+	adc_aif2 |= RK3308_ADC_I2S_WORK;
+	dac_aif1 |= RK3308_DAC_I2S_LR_NORMAL;
+	dac_aif2 |= RK3308_DAC_I2S_WORK;
+
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON01(ch),
+			   RK3308_ADC_I2S_VALID_LEN_MSK |
+			   RK3308_ADC_I2S_LR_MSK |
+			   RK3308_ADC_I2S_TYPE_MSK,
+			   adc_aif1);
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON02(ch),
+			   RK3308_ADC_I2S_MSK,
+			   adc_aif2);
+
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON01,
+			   RK3308_DAC_I2S_VALID_LEN_MSK |
+			   RK3308_DAC_I2S_LR_MSK,
+			   dac_aif1);
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02,
+			   RK3308_DAC_I2S_MSK,
+			   dac_aif2);
+
+	return 0;
+}
+
+static int rk3308_digital_mute(struct snd_soc_dai *dai, int mute)
+{
+	return 0;
+}
+
+static int rk3308_codec_dac_enable(struct rk3308_codec_priv *rk3308)
+{
+	/* Step 01 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON00,
+			   RK3308_DAC_CURRENT_MSK,
+			   RK3308_DAC_CURRENT_EN);
+
+	/* Step 02 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01,
+			   RK3308_DAC_BUF_REF_L_MSK |
+			   RK3308_DAC_BUF_REF_R_MSK,
+			   RK3308_DAC_BUF_REF_L_EN |
+			   RK3308_DAC_BUF_REF_R_EN);
+
+	/* Step 03 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01,
+			   RK3308_DAC_POP_SOUND_L_MSK |
+			   RK3308_DAC_POP_SOUND_R_MSK,
+			   RK3308_DAC_POP_SOUND_L_WORK |
+			   RK3308_DAC_POP_SOUND_R_WORK);
+
+	/* Step 04 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13,
+			   RK3308_DAC_L_HPMIX_EN | RK3308_DAC_R_HPMIX_EN,
+			   RK3308_DAC_L_HPMIX_EN | RK3308_DAC_R_HPMIX_EN);
+
+	/* Step 05 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13,
+			   RK3308_DAC_L_HPMIX_WORK | RK3308_DAC_R_HPMIX_WORK,
+			   RK3308_DAC_L_HPMIX_WORK | RK3308_DAC_R_HPMIX_WORK);
+
+	/* Step 06 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04,
+			   RK3308_DAC_L_LINEOUT_EN | RK3308_DAC_R_LINEOUT_EN,
+			   RK3308_DAC_L_LINEOUT_EN | RK3308_DAC_R_LINEOUT_EN);
+
+	/* Step 07 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03,
+			   RK3308_DAC_L_HPOUT_EN | RK3308_DAC_R_HPOUT_EN,
+			   RK3308_DAC_L_HPOUT_EN | RK3308_DAC_R_HPOUT_EN);
+
+	/* Step 08 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03,
+			   RK3308_DAC_L_HPOUT_WORK | RK3308_DAC_R_HPOUT_WORK,
+			   RK3308_DAC_L_HPOUT_WORK | RK3308_DAC_R_HPOUT_WORK);
+
+	/* Step 09 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02,
+			   RK3308_DAC_L_REF_EN | RK3308_DAC_R_REF_EN,
+			   RK3308_DAC_L_REF_EN | RK3308_DAC_R_REF_EN);
+
+	/* Step 10 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02,
+			   RK3308_DAC_L_CLK_EN | RK3308_DAC_R_CLK_EN,
+			   RK3308_DAC_L_CLK_EN | RK3308_DAC_R_CLK_EN);
+
+	/* Step 11 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02,
+			   RK3308_DAC_L_DAC_EN | RK3308_DAC_R_DAC_EN,
+			   RK3308_DAC_L_DAC_EN | RK3308_DAC_R_DAC_EN);
+
+	/* Step 12 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02,
+			   RK3308_DAC_L_DAC_WORK | RK3308_DAC_R_DAC_WORK,
+			   RK3308_DAC_L_DAC_WORK | RK3308_DAC_R_DAC_WORK);
+
+	/* Step 13 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON12,
+			   RK3308_DAC_L_HPMIX_SEL_MSK |
+			   RK3308_DAC_R_HPMIX_SEL_MSK,
+			   RK3308_DAC_L_HPMIX_I2S |
+			   RK3308_DAC_R_HPMIX_I2S);
+
+	/* Step 14 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13,
+			   RK3308_DAC_L_HPMIX_UNMUTE |
+			   RK3308_DAC_R_HPMIX_UNMUTE,
+			   RK3308_DAC_L_HPMIX_UNMUTE |
+			   RK3308_DAC_R_HPMIX_UNMUTE);
+
+	/* Step 15 */
+	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_0DB |
+			   RK3308_DAC_R_HPMIX_GAIN_0DB);
+
+	/* Step 16 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03,
+			   RK3308_DAC_L_HPOUT_UNMUTE |
+			   RK3308_DAC_R_HPOUT_UNMUTE,
+			   RK3308_DAC_L_HPOUT_UNMUTE |
+			   RK3308_DAC_R_HPOUT_UNMUTE);
+
+	/* Step 17 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04,
+			   RK3308_DAC_L_LINEOUT_UNMUTE |
+			   RK3308_DAC_R_LINEOUT_UNMUTE,
+			   RK3308_DAC_L_LINEOUT_UNMUTE |
+			   RK3308_DAC_R_LINEOUT_UNMUTE);
+
+	/* Step 18 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON05,
+			   RK3308_DAC_L_HPOUT_GAIN_MSK,
+			   RK3308_DAC_L_HPOUT_GAIN_0DB);
+
+	/* Step 18 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON06,
+			   RK3308_DAC_R_HPOUT_GAIN_MSK,
+			   RK3308_DAC_R_HPOUT_GAIN_0DB);
+
+	/* Step 19 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04,
+			   RK3308_DAC_L_GAIN_MSK | RK3308_DAC_R_GAIN_MSK,
+			   RK3308_DAC_L_GAIN_0DB | RK3308_DAC_R_GAIN_0DB);
+
+	return 0;
+}
+
+static int rk3308_codec_dac_disable(struct rk3308_codec_priv *rk3308)
+{
+	/* Step 01 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04,
+			   RK3308_DAC_L_GAIN_MSK | RK3308_DAC_R_GAIN_MSK,
+			   RK3308_DAC_L_GAIN_0DB | RK3308_DAC_R_GAIN_0DB);
+
+	/*
+	 * Step 02
+	 *
+	 * Note1. In the step2, adjusting the register step by step to the
+	 * appropriate value and taking 20ms as time step
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON05,
+			   RK3308_DAC_L_HPOUT_GAIN_MSK,
+			   RK3308_DAC_L_HPOUT_GAIN_NDB_39);
+
+	/* Step 02 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON06,
+			   RK3308_DAC_R_HPOUT_GAIN_MSK,
+			   RK3308_DAC_R_HPOUT_GAIN_NDB_39);
+
+	/* Step 03 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13,
+			   RK3308_DAC_L_HPMIX_UNMUTE |
+			   RK3308_DAC_R_HPMIX_UNMUTE,
+			   RK3308_DAC_L_HPMIX_MUTE |
+			   RK3308_DAC_R_HPMIX_MUTE);
+
+	/* Step 04 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON12,
+			   RK3308_DAC_L_HPMIX_SEL_MSK |
+			   RK3308_DAC_R_HPMIX_SEL_MSK,
+			   RK3308_DAC_L_HPMIX_NONE |
+			   RK3308_DAC_R_HPMIX_NONE);
+
+	/* Step 05 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03,
+			   RK3308_DAC_L_HPOUT_UNMUTE |
+			   RK3308_DAC_R_HPOUT_UNMUTE,
+			   RK3308_DAC_L_HPOUT_MUTE |
+			   RK3308_DAC_R_HPOUT_MUTE);
+
+	/* Step 06 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02,
+			   RK3308_DAC_L_DAC_WORK | RK3308_DAC_R_DAC_WORK,
+			   RK3308_DAC_L_DAC_INIT | RK3308_DAC_R_DAC_INIT);
+
+	/* Step 07 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03,
+			   RK3308_DAC_L_HPOUT_EN | RK3308_DAC_R_HPOUT_EN,
+			   RK3308_DAC_L_HPOUT_DIS | RK3308_DAC_R_HPOUT_DIS);
+
+	/* Step 08 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04,
+			   RK3308_DAC_L_LINEOUT_UNMUTE |
+			   RK3308_DAC_R_LINEOUT_UNMUTE,
+			   RK3308_DAC_L_LINEOUT_MUTE |
+			   RK3308_DAC_R_LINEOUT_MUTE);
+
+	/* Step 09 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON04,
+			   RK3308_DAC_L_LINEOUT_EN | RK3308_DAC_R_LINEOUT_EN,
+			   RK3308_DAC_L_LINEOUT_DIS | RK3308_DAC_R_LINEOUT_DIS);
+
+	/* Step 10 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13,
+			   RK3308_DAC_L_HPMIX_EN | RK3308_DAC_R_HPMIX_EN,
+			   RK3308_DAC_L_HPMIX_DIS | RK3308_DAC_R_HPMIX_DIS);
+
+	/* Step 11 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02,
+			   RK3308_DAC_L_DAC_EN | RK3308_DAC_R_DAC_EN,
+			   RK3308_DAC_L_DAC_DIS | RK3308_DAC_R_DAC_DIS);
+
+	/* Step 12 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02,
+			   RK3308_DAC_L_CLK_EN | RK3308_DAC_R_CLK_EN,
+			   RK3308_DAC_L_CLK_DIS | RK3308_DAC_R_CLK_DIS);
+
+	/* Step 13 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON02,
+			   RK3308_DAC_L_REF_EN | RK3308_DAC_R_REF_EN,
+			   RK3308_DAC_L_REF_DIS | RK3308_DAC_R_REF_DIS);
+
+	/* Step 14 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01,
+			   RK3308_DAC_POP_SOUND_L_MSK |
+			   RK3308_DAC_POP_SOUND_R_MSK,
+			   RK3308_DAC_POP_SOUND_L_INIT |
+			   RK3308_DAC_POP_SOUND_R_INIT);
+
+	/* Step 15 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01,
+			   RK3308_DAC_BUF_REF_L_EN | RK3308_DAC_BUF_REF_R_EN,
+			   RK3308_DAC_BUF_REF_L_DIS | RK3308_DAC_BUF_REF_R_DIS);
+
+	/* Step 16 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON00,
+			   RK3308_DAC_CURRENT_EN,
+			   RK3308_DAC_CURRENT_DIS);
+
+	/* Step 17 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON03,
+			   RK3308_DAC_L_HPOUT_WORK | RK3308_DAC_R_HPOUT_WORK,
+			   RK3308_DAC_L_HPOUT_INIT | RK3308_DAC_R_HPOUT_INIT);
+
+	/* Step 18 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON13,
+			   RK3308_DAC_L_HPMIX_WORK | RK3308_DAC_R_HPMIX_WORK,
+			   RK3308_DAC_L_HPMIX_INIT | RK3308_DAC_R_HPMIX_INIT);
+
+	/* Step 19 */
+	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);
+
+	/*
+	 * Note2. If the ACODEC_DAC_ANA_CON12[7] or ACODEC_DAC_ANA_CON12[3]
+	 * is set to 0x1, add the steps from the section Disable DAC
+	 * Configuration Standard Usage Flow after complete the step 19
+	 */
+
+	return 0;
+}
+
+static int rk3308_codec_power_on(struct snd_soc_codec *codec)
+{
+	struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
+
+	/* 1. Supply the power of digital part and reset the Audio Codec */
+	/* Do nothing */
+
+	/*
+	 * 2. Configure ACODEC_DAC_ANA_CON1[1:0] and ACODEC_DAC_ANA_CON1[5:4]
+	 *    to 0x1, to setup dc voltage of the DAC channel output
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01,
+			   RK3308_DAC_POP_SOUND_L_MSK, RK3308_DAC_POP_SOUND_L_INIT);
+	regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01,
+			   RK3308_DAC_POP_SOUND_R_MSK, RK3308_DAC_POP_SOUND_R_INIT);
+
+	/*
+	 * 3. Configure the register ACODEC_ADC_ANA_CON10[6:0] to 0x1
+	 *
+	 * Note: Only the reg (ADC_ANA_CON10+0x0)[6:0] represent the control
+	 * signal to select current to pre-charge/dis_charge
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0),
+			   RK3308_ADC_CURRENT_CHARGE_MSK, RK3308_ADC_SEL_I_64(1));
+
+	/* 4. Supply the power of the analog part(AVDD,AVDDRV) */
+
+	/*
+	 * 5. Configure the register ACODEC_ADC_ANA_CON10[7] to 0x1 to setup
+	 *    reference voltage
+	 *
+	 * Note: Only the reg (ADC_ANA_CON10+0x0)[7] represent the enable
+	 * signal of reference voltage module
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0),
+			   RK3308_ADC_REF_EN, RK3308_ADC_REF_EN);
+
+	/*
+	 * 6. Change the register ACODEC_ADC_ANA_CON10[6:0] from the 0x1 to
+	 *    0x7f step by step or configure the ACODEC_ADC_ANA_CON10[6:0] to
+	 *    0x7f directly. The suggestion slot time of the step is 20ms.
+	 */
+	mdelay(20);
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0),
+			   RK3308_ADC_CURRENT_CHARGE_MSK,
+			   RK3308_ADC_DONT_SEL_ALL);
+
+	/* 7. Wait until the voltage of VCM keeps stable at the AVDD/2 */
+	usleep_range(200, 300);	/* estimated value */
+
+	/*
+	 * 8. Configure the register ACODEC_ADC_ANA_CON10[6:0] to the
+	 *    appropriate value(expect 0x0) for reducing power.
+	 */
+
+	 /* TODO: choose an appropriate charge value */
+
+	return 0;
+}
+
+static int rk3308_codec_power_off(struct snd_soc_codec *codec)
+{
+	struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
+
+	/*
+	 * 1. Keep the power on and disable the DAC and ADC path according to
+	 *    the section power on configuration standard usage flow.
+	 */
+
+	/* 2. Configure the register ACODEC_ADC_ANA_CON10[6:0] to 0x1 */
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0),
+			   RK3308_ADC_CURRENT_CHARGE_MSK, RK3308_ADC_SEL_I_64(1));
+
+	/* 3. Configure the register ACODEC_ADC_ANA_CON10[7] to 0x0 */
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0),
+			   RK3308_ADC_REF_EN, RK3308_ADC_REF_DIS);
+
+	/*
+	 * 4.Change the register ACODEC_ADC_ANA_CON10[6:0] from the 0x1 to 0x7f
+	 *   step by step or configure the ACODEC_ADC_ANA_CON10[6:0] to 0x7f
+	 *   directly. The suggestion slot time of the step is 20ms
+	 */
+	mdelay(20);
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0),
+			   RK3308_ADC_CURRENT_CHARGE_MSK,
+			   RK3308_ADC_DONT_SEL_ALL);
+
+	/* 5. Wait until the voltage of VCM keeps stable at the AGND */
+	usleep_range(200, 300);	/* estimated value */
+
+	/* 6. Power off the analog power supply */
+	/* 7. Power off the digital power supply */
+
+	/* Do something via hardware */
+
+	return 0;
+}
+
+static int check_micbias(int micbias)
+{
+	switch (micbias) {
+	case RK3308_ADC_MICBIAS_VOLT_0_85:
+	case RK3308_ADC_MICBIAS_VOLT_0_8:
+	case RK3308_ADC_MICBIAS_VOLT_0_75:
+	case RK3308_ADC_MICBIAS_VOLT_0_7:
+	case RK3308_ADC_MICBIAS_VOLT_0_65:
+	case RK3308_ADC_MICBIAS_VOLT_0_6:
+	case RK3308_ADC_MICBIAS_VOLT_0_55:
+	case RK3308_ADC_MICBIAS_VOLT_0_5:
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int rk3308_codec_micbias_enable(struct rk3308_codec_priv *rk3308,
+				       int micbias)
+{
+	int ch = rk3308->adc_ch;
+	int ret;
+
+	if (ch != 1 && ch != 2) {
+		dev_err(rk3308->plat_dev,
+			 "%s: currnet ch: %d, only ch1/2 control MICBIAS1/2\n",
+			 __func__, ch);
+		return -EINVAL;
+	}
+
+	/* 1. Power up the ACODEC and keep the AVDDH stable */
+
+	/* 2. Configure ACODEC_ADC_ANA_CON7[2:0] to the certain value */
+	ret = check_micbias(micbias);
+	if (ret < 0) {
+		dev_err(rk3308->plat_dev, "This is an invalid micbias: %d\n",
+			micbias);
+		return ret;
+	}
+
+	/*
+	 * Note: Only the reg (ADC_ANA_CON7+0x0)[2:0] represent the level range
+	 * control signal of MICBIAS voltage
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(0),
+			   RK3308_ADC_LEVEL_RANGE_MICBIAS_MSK,
+			   micbias);
+
+	/* 3. Wait until the VCMH keep stable */
+	usleep_range(200, 300);	/* estimated value */
+
+	/* 4. Configure ACODEC_ADC_ANA_CON8[4] to 0x1 */
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON08(ch),
+			   RK3308_ADC_MICBIAS_CURRENT_MSK,
+			   RK3308_ADC_MICBIAS_CURRENT_EN);
+
+	/*
+	 * 5. Configure the (ADC_ANA_CON7+0x40)[3] or (ADC_ANA_CON7+0x80)[3]
+	 * to 0x1.
+	 * (ADC_ANA_CON7+0x40)[3] used to control the MICBIAS1, and
+	 * (ADC_ANA_CON7+0x80)[3] used to control the MICBIAS2
+	 */
+
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(ch),
+			   RK3308_ADC_MIC_BIAS_BUF_EN,
+			   RK3308_ADC_MIC_BIAS_BUF_EN);
+
+	return 0;
+}
+
+static int rk3308_codec_micbias_disable(struct rk3308_codec_priv *rk3308)
+{
+	int ch = rk3308->adc_ch;
+
+	if (ch != 1 && ch != 2) {
+		dev_err(rk3308->plat_dev,
+			 "%s: currnet ch: %d, only ch1/2 control MICBIAS1/2\n",
+			 __func__, ch);
+		return -EINVAL;
+	}
+
+	/* 1. Enable the MICBIAS and keep the Audio Codec stable */
+	/* Do nothing */
+
+	/*
+	 * 2. Configure the (ADC_ANA_CON7+0x40)[3] or
+	 * (ADC_ANA_CON7+0x80)[3] to 0x0
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(ch),
+			   RK3308_ADC_MIC_BIAS_BUF_EN,
+			   RK3308_ADC_MIC_BIAS_BUF_DIS);
+
+	/* 3. Configure ACODEC_ADC_ANA_CON8[4] to 0x0 */
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON08(ch),
+			   RK3308_ADC_MICBIAS_CURRENT_MSK,
+			   RK3308_ADC_MICBIAS_CURRENT_DIS);
+
+	return 0;
+}
+
+static int rk3308_codec_alc_enable(struct rk3308_codec_priv *rk3308)
+{
+	int ch = rk3308->adc_ch;
+
+	/*
+	 * 1. Set he max level and min level of the ALC need to control.
+	 *
+	 * These values are estimated
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON05(ch),
+			   RK3308_AGC_LO_8BITS_AGC_MIN_MSK,
+			   0x16);
+	regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON05(ch),
+			   RK3308_AGC_HI_8BITS_AGC_MIN_MSK,
+			   0x40);
+
+	regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON05(ch),
+			   RK3308_AGC_LO_8BITS_AGC_MAX_MSK,
+			   0x26);
+	regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON05(ch),
+			   RK3308_AGC_HI_8BITS_AGC_MAX_MSK,
+			   0x40);
+
+	/*
+	 * 2. Set ACODEC_ALC_DIG_CON4[2:0] according to the sample rate
+	 *
+	 * By default is 44.1KHz for sample.
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON04(ch),
+			   RK3308_AGC_APPROX_RATE_MSK,
+			   RK3308_AGC_APPROX_RATE_44_1K);
+	regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON04(ch),
+			   RK3308_AGC_APPROX_RATE_MSK,
+			   RK3308_AGC_APPROX_RATE_44_1K);
+
+	/* 3. Set ACODEC_ALC_DIG_CON9[6] to 0x1, to enable the ALC module */
+	regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON09(ch),
+			   RK3308_AGC_FUNC_SEL_MSK,
+			   RK3308_AGC_FUNC_SEL_EN);
+	regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON09(ch),
+			   RK3308_AGC_FUNC_SEL_MSK,
+			   RK3308_AGC_FUNC_SEL_EN);
+
+	/*
+	 * 4. Set ACODEC_ADC_ANA_CON11[1:0], (ACODEC_ADC_ANA_CON11+0x40)[1:0],
+	 * (ACODEC_ADC_ANA_CON11+0x80)[1:0] and (ACODEC_ADC_ANA_CON11+0xc0)[1:0]
+	 * to 0x3, to enable the ALC module to control the gain of PGA.
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(ch),
+			   RK3308_ADC_ALCL_CON_GAIN_PGAL_MSK |
+			   RK3308_ADC_ALCR_CON_GAIN_PGAR_MSK,
+			   RK3308_ADC_ALCL_CON_GAIN_PGAL_EN |
+			   RK3308_ADC_ALCR_CON_GAIN_PGAR_EN);
+
+	/*
+	 * 5.Observe the current ALC output gain by reading
+	 * ACODEC_ALC_DIG_CON12[4:0]
+	 *
+	 * The default GAIN is 0x0c
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON12(ch),
+			   RK3308_AGC_GAIN_MSK,
+			   0x0c);
+	regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON12(ch),
+			   RK3308_AGC_GAIN_MSK,
+			   0x0c);
+
+	return 0;
+}
+
+static int rk3308_codec_alc_disable(struct rk3308_codec_priv *rk3308)
+{
+	int ch = rk3308->adc_ch;
+
+	/*
+	 * 1. Set ACODEC_ALC_DIG_CON9[6] to 0x0, to disable the ALC module,
+	 * then the ALC output gain will keep to the last value
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_ALC_L_DIG_CON09(ch),
+			   RK3308_AGC_FUNC_SEL_MSK,
+			   RK3308_AGC_FUNC_SEL_DIS);
+	regmap_update_bits(rk3308->regmap, RK3308_ALC_R_DIG_CON09(ch),
+			   RK3308_AGC_FUNC_SEL_MSK,
+			   RK3308_AGC_FUNC_SEL_DIS);
+
+	/*
+	 * 2. Set ACODEC_ADC_ANA_CON11[1:0], (ACODEC_ADC_ANA_CON11+0x40)[1:0],
+	 * (ACODEC_ADC_ANA_CON11+0x80)[1:0] and (ACODEC_ADC_ANA_CON11+0xc0)[1:0]
+	 * to 0x0, to disable the ALC module to control the gain of PGA.
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON11(ch),
+			   RK3308_ADC_ALCL_CON_GAIN_PGAL_MSK |
+			   RK3308_ADC_ALCR_CON_GAIN_PGAR_MSK,
+			   RK3308_ADC_ALCL_CON_GAIN_PGAL_DIS |
+			   RK3308_ADC_ALCR_CON_GAIN_PGAR_DIS);
+
+	return 0;
+}
+
+static int rk3308_codec_adc_ana_enable(struct rk3308_codec_priv *rk3308)
+{
+	unsigned int adc_aif1 = 0, adc_aif2 = 0;
+	unsigned int agc_func_en;
+	int ch = rk3308->adc_ch;
+
+	/*
+	 * 1. Set the ACODEC_ADC_ANA_CON7[7:6] and ACODEC_ADC_ANA_CON7[5:4],
+	 * to select the line-in or microphone as input of ADC
+	 *
+	 * Note1. Please ignore the step1 for enabling ADC3, ADC4, ADC5,
+	 * ADC6, ADC7, and ADC8
+	 */
+	if (ch == 0) {
+		if (rk3308->adc_ch0_using_linein) {
+			regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(ch),
+				   RK3308_ADC_CH1_IN_SEL_MSK,
+				   RK3308_ADC_CH1_IN_LINEIN);
+			regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(ch),
+				   RK3308_ADC_CH2_IN_SEL_MSK,
+				   RK3308_ADC_CH2_IN_LINEIN);
+		} else {
+			regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(ch),
+				   RK3308_ADC_CH1_IN_SEL_MSK,
+				   RK3308_ADC_CH1_IN_MIC);
+			regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(ch),
+				   RK3308_ADC_CH2_IN_SEL_MSK,
+				   RK3308_ADC_CH2_IN_MIC);
+		}
+	}
+
+	/*
+	 * 2. Set ACODEC_ADC_ANA_CON0[7:0] to 0xff, to end the mute station
+	 * of ADC, to enable the MIC module, to enable the reference voltage
+	 * buffer, and to end the initialization of MIC
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON00(ch),
+				   RK3308_ADC_CH1_CH2_MIC_ALL_MSK,
+				   RK3308_ADC_CH1_CH2_MIC_ALL);
+
+	/*
+	 * 3. Set ACODEC_ADC_ANA_CON6[0] to 0x1, to enable the current source
+	 * of audio
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON06(ch),
+				   RK3308_ADC_CURRENT_MSK,
+				   RK3308_ADC_CURRENT_EN);
+
+	/*
+	 * 4. Set ACODEC_ADC_ANA_CON2[7:0] to 0x77, to enable the ALC module,
+	 * to enable the zero-crossing detection function, and to end the
+	 * initialization of ALC
+	 *
+	 * Note2. Please set ACODEC_ADC_ANA_CON2[7:0] to 0x33 in step4
+	 * if the AGC function is closed
+	 */
+
+	adc_aif1 = RK3308_ADC_CH1_ALC_EN | RK3308_ADC_CH1_ALC_WORK;
+	regmap_read(rk3308->regmap, RK3308_ALC_L_DIG_CON09(ch), &agc_func_en);
+	if (agc_func_en & RK3308_AGC_FUNC_SEL_EN)
+		adc_aif1 |= RK3308_ADC_CH1_ZEROCROSS_DET_EN;
+
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(ch),
+				   RK3308_ADC_CH1_ALC_ZC_MSK,
+				   adc_aif1);
+
+	adc_aif2 = RK3308_ADC_CH2_ALC_EN | RK3308_ADC_CH2_ALC_WORK;
+	regmap_read(rk3308->regmap, RK3308_ALC_L_DIG_CON09(ch), &agc_func_en);
+	if (agc_func_en & RK3308_AGC_FUNC_SEL_EN)
+		adc_aif2 |= RK3308_ADC_CH2_ZEROCROSS_DET_EN;
+
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(ch),
+				   RK3308_ADC_CH2_ALC_ZC_MSK,
+				   adc_aif2);
+
+	/*
+	 * 5. Set ACODEC_ADC_ANA_CON5[7:0] to 0x77, to enable the clock and
+	 * ADC module, and to end the initialization of ADC
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(ch),
+				   RK3308_ADC_CH1_ADC_CLK_MSK,
+				   RK3308_ADC_CH1_CLK_EN |
+				   RK3308_ADC_CH1_ADC_EN |
+				   RK3308_ADC_CH1_ADC_WORK);
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(ch),
+				   RK3308_ADC_CH2_ADC_CLK_MSK,
+				   RK3308_ADC_CH2_CLK_EN |
+				   RK3308_ADC_CH2_ADC_EN |
+				   RK3308_ADC_CH2_ADC_WORK);
+
+	/*
+	 * 6. Set ACODEC_ADC_ANA_CON1[5:4] and ACODEC_ADC_ANA_CON1[1:0],
+	 * to select the gain of the MIC
+	 *
+	 * By default is 0db.
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(ch),
+				   RK3308_ADC_CH1_MIC_GAIN_MSK,
+				   RK3308_ADC_CH1_MIC_GAIN_0DB);
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(ch),
+				   RK3308_ADC_CH2_MIC_GAIN_MSK,
+				   RK3308_ADC_CH2_MIC_GAIN_0DB);
+
+	/*
+	 * 7.Set ACODEC_ADC_ANA_CON3[4:0] and ACODEC_ADC_ANA_CON4[3:0] to
+	 * select the gain of ALC
+	 *
+	 * By default is 0db.
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON03(ch),
+				   RK3308_ADC_CH1_ALC_GAIN_MSK,
+				   RK3308_ADC_CH1_ALC_GAIN_0DB);
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON04(ch),
+				   RK3308_ADC_CH2_ALC_GAIN_MSK,
+				   RK3308_ADC_CH2_ALC_GAIN_0DB);
+
+	/* 8.Begin recording */
+
+	return 0;
+}
+
+static int rk3308_codec_adc_ana_disable(struct rk3308_codec_priv *rk3308)
+{
+	int ch = rk3308->adc_ch;
+
+	/*
+	 * 1. Set ACODEC_ADC_ANA_CON2[7:0] to 0x0, to disable the ALC module,
+	 * to disable the zero-crossing detection function, and to begin the
+	 * initialization of ALC
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(ch),
+				   RK3308_ADC_CH1_ALC_ZC_MSK,
+				   0);
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(ch),
+				   RK3308_ADC_CH2_ALC_ZC_MSK,
+				   0);
+
+	/*
+	 * 2. Set ACODEC_ADC_ANA_CON5[7:0] to 0x0, to disable the clock and
+	 * ADC module, and to begin the initialization of ADC
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(ch),
+				   RK3308_ADC_CH1_ADC_CLK_MSK,
+				   0);
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON05(ch),
+				   RK3308_ADC_CH2_ADC_CLK_MSK,
+				   0);
+
+	/*
+	 * 3. Set ACODEC_ADC_ANA_CON0[7:0] to 0x88, to disable the MIC module,
+	 * to disable the reference voltage buffer, and to begin the
+	 * initialization of MIC
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON00(ch),
+				   RK3308_ADC_CH1_CH2_MIC_ALL_MSK,
+				   RK3308_ADC_CH1_MIC_UNMUTE |
+				   RK3308_ADC_CH2_MIC_UNMUTE);
+
+	/*
+	 * 4. Set ACODEC_ADC_ANA_CON6[0] to 0x0, to disable the current
+	 * source of audio
+	 */
+	regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON06(ch),
+				   RK3308_ADC_CURRENT_MSK,
+				   RK3308_ADC_CURRENT_DIS);
+
+	return 0;
+}
+
+static int rk3308_codec_open_capture(struct snd_soc_codec *codec)
+{
+	struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
+
+	rk3308_codec_alc_enable(rk3308);
+	rk3308_codec_adc_ana_enable(rk3308);
+
+	return 0;
+}
+
+static int rk3308_codec_close_capture(struct snd_soc_codec *codec)
+{
+	struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
+
+	rk3308_codec_alc_disable(rk3308);
+	rk3308_codec_adc_ana_disable(rk3308);
+
+	return 0;
+}
+
+static int rk3308_codec_open_playback(struct snd_soc_codec *codec)
+{
+	struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
+
+	rk3308_codec_dac_enable(rk3308);
+	rk3308_speaker_ctl(rk3308, 1);
+
+	return 0;
+}
+
+static int rk3308_codec_close_playback(struct snd_soc_codec *codec)
+{
+	struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
+
+	rk3308_speaker_ctl(rk3308, 0);
+	rk3308_codec_dac_disable(rk3308);
+
+	return 0;
+}
+
+static int rk3308_pcm_startup(struct snd_pcm_substream *substream,
+			      struct snd_soc_dai *dai)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	int ret = 0;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		ret = rk3308_codec_open_playback(codec);
+	else
+		ret = rk3308_codec_open_capture(codec);
+
+	return ret;
+}
+
+static void rk3308_pcm_shutdown(struct snd_pcm_substream *substream,
+				struct snd_soc_dai *dai)
+{
+	struct snd_soc_codec *codec = dai->codec;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		rk3308_codec_close_playback(codec);
+	else
+		rk3308_codec_close_capture(codec);
+}
+
+static struct snd_soc_dai_ops rk3308_dai_ops = {
+	.hw_params = rk3308_hw_params,
+	.set_fmt = rk3308_set_dai_fmt,
+	.digital_mute = rk3308_digital_mute,
+	.startup = rk3308_pcm_startup,
+	.shutdown = rk3308_pcm_shutdown,
+};
+
+static struct snd_soc_dai_driver rk3308_dai[] = {
+	{
+		.name = "rk3308-hifi",
+		.id = RK3308_HIFI,
+		.playback = {
+			.stream_name = "HiFi Playback",
+			.channels_min = 2,
+			.channels_max = 2,
+			.rates = SNDRV_PCM_RATE_8000_96000,
+			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
+				    SNDRV_PCM_FMTBIT_S20_3LE |
+				    SNDRV_PCM_FMTBIT_S24_LE |
+				    SNDRV_PCM_FMTBIT_S32_LE),
+		},
+		.capture = {
+			.stream_name = "HiFi Capture",
+			.channels_min = 1,
+			.channels_max = 8,
+			.rates = SNDRV_PCM_RATE_8000_96000,
+			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
+				    SNDRV_PCM_FMTBIT_S20_3LE |
+				    SNDRV_PCM_FMTBIT_S24_LE |
+				    SNDRV_PCM_FMTBIT_S32_LE),
+		},
+		.ops = &rk3308_dai_ops,
+	},
+};
+
+static int rk3308_suspend(struct snd_soc_codec *codec)
+{
+	rk3308_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+	return 0;
+}
+
+static int rk3308_resume(struct snd_soc_codec *codec)
+{
+	rk3308_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+	return 0;
+}
+
+static int rk3308_probe(struct snd_soc_codec *codec)
+{
+	struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
+
+	rk3308_codec_reset(codec);
+	rk3308_codec_power_on(codec);
+
+	rk3308_codec_micbias_enable(rk3308, RK3308_ADC_MICBIAS_VOLT_0_7);
+
+	return 0;
+}
+
+static int rk3308_remove(struct snd_soc_codec *codec)
+{
+	struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
+
+	rk3308_speaker_ctl(rk3308, 0);
+	rk3308_codec_micbias_disable(rk3308);
+	rk3308_codec_power_off(codec);
+
+	return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_rk3308 = {
+	.probe = rk3308_probe,
+	.remove = rk3308_remove,
+	.suspend = rk3308_suspend,
+	.resume = rk3308_resume,
+	.set_bias_level = rk3308_set_bias_level,
+	.controls = rk3308_codec_dapm_controls,
+	.num_controls = ARRAY_SIZE(rk3308_codec_dapm_controls),
+};
+
+static const struct reg_default rk3308_codec_reg_defaults[] = {
+	{ RK3308_GLB_CON, 0x07 },
+};
+
+static bool rk3308_codec_write_read_reg(struct device *dev, unsigned int reg)
+{
+	/* All registers can be read / write */
+	return true;
+}
+
+static bool rk3308_codec_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case RK3308_GLB_CON:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static const struct regmap_config rk3308_codec_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = RK3308_DAC_ANA_CON13,
+	.writeable_reg = rk3308_codec_write_read_reg,
+	.readable_reg = rk3308_codec_write_read_reg,
+	.volatile_reg = rk3308_codec_volatile_reg,
+	.reg_defaults = rk3308_codec_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(rk3308_codec_reg_defaults),
+	.cache_type = REGCACHE_FLAT,
+};
+
+static ssize_t adc_ch_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct rk3308_codec_priv *rk3308 =
+		container_of(dev, struct rk3308_codec_priv, dev);
+
+	return sprintf(buf, "adc_ch: %d\n", rk3308->adc_ch);
+}
+
+static ssize_t adc_ch_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
+{
+	struct rk3308_codec_priv *rk3308 =
+		container_of(dev, struct rk3308_codec_priv, dev);
+	unsigned long ch;
+	int ret = kstrtoul(buf, 10, &ch);
+
+	if (ret < 0 || ch > 4) {
+		dev_err(dev, "Invalid ch: %ld, ret: %d\n", ch, ret);
+		return -EINVAL;
+	}
+
+	rk3308->adc_ch = ch;
+
+	dev_info(dev, "Store ch: %d\n", rk3308->adc_ch);
+
+	return count;
+}
+
+static const struct device_attribute adc_ch_attrs[] = {
+	__ATTR(adc_ch, 0644, adc_ch_show, adc_ch_store),
+};
+
+static void rk3308_codec_device_release(struct device *dev)
+{
+	/* Do nothing */
+}
+
+static int rk3308_codec_sysfs_init(struct platform_device *pdev,
+				   struct rk3308_codec_priv *rk3308)
+{
+	struct device *dev = &rk3308->dev;
+	int i;
+
+	dev->release = rk3308_codec_device_release;
+	dev->parent = &pdev->dev;
+	set_dev_node(dev, dev_to_node(&pdev->dev));
+	dev_set_name(dev, "rk3308-acodec-dev");
+
+	if (device_register(dev)) {
+		dev_err(&pdev->dev,
+			"Register 'rk3308-acodec-dev' failed\n");
+		dev->parent = NULL;
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(adc_ch_attrs); i++) {
+		if (device_create_file(dev, &adc_ch_attrs[i])) {
+			dev_err(&pdev->dev,
+				"Create 'rk3308-acodec-dev' attr failed\n");
+			device_unregister(dev);
+			return -ENOMEM;
+		}
+	}
+
+	return 0;
+}
+
+static int rk3308_platform_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct rk3308_codec_priv *rk3308;
+	struct resource *res;
+	void __iomem *base;
+	int ret = 0;
+	struct regmap *grf;
+
+	grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+	if (IS_ERR(grf)) {
+		dev_err(&pdev->dev,
+			"Missing 'rockchip,grf' property\n");
+		return PTR_ERR(grf);
+	}
+
+	rk3308 = devm_kzalloc(&pdev->dev, sizeof(*rk3308), GFP_KERNEL);
+	if (!rk3308)
+		return -ENOMEM;
+
+	ret = rk3308_codec_sysfs_init(pdev, rk3308);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Sysfs init failed\n");
+		return ret;
+	}
+
+	rk3308->plat_dev = &pdev->dev;
+
+	rk3308->reset = devm_reset_control_get(&pdev->dev, "acodec-reset");
+	if (IS_ERR(rk3308->reset)) {
+		ret = PTR_ERR(rk3308->reset);
+		if (ret != -ENOENT)
+			return ret;
+
+		dev_dbg(&pdev->dev, "No reset control found\n");
+		rk3308->reset = NULL;
+	}
+
+	/* GPIO0_A5 control speaker on RK3308 EVB */
+	rk3308->spk_ctl_gpio = devm_gpiod_get_optional(&pdev->dev, "spk_ctl",
+						       GPIOD_OUT_HIGH);
+	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;
+	}
+
+	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 = clk_prepare_enable(rk3308->pclk);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to enable acodec pclk: %d\n", ret);
+		return ret;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base)) {
+		ret = PTR_ERR(base);
+		dev_err(&pdev->dev, "Failed to ioremap resource\n");
+		goto failed;
+	}
+
+	rk3308->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+					       &rk3308_codec_regmap_config);
+	if (IS_ERR(rk3308->regmap)) {
+		ret = PTR_ERR(rk3308->regmap);
+		dev_err(&pdev->dev, "Failed to regmap mmio\n");
+		goto failed;
+	}
+
+	platform_set_drvdata(pdev, rk3308);
+
+	ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_rk3308,
+				      rk3308_dai, ARRAY_SIZE(rk3308_dai));
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
+		goto failed;
+	}
+
+	return ret;
+
+failed:
+	clk_disable_unprepare(rk3308->pclk);
+
+	return ret;
+}
+
+static int rk3308_platform_remove(struct platform_device *pdev)
+{
+	struct rk3308_codec_priv *rk3308 =
+		(struct rk3308_codec_priv *)platform_get_drvdata(pdev);
+
+	clk_disable_unprepare(rk3308->pclk);
+	snd_soc_unregister_codec(&pdev->dev);
+
+	return 0;
+}
+
+static const struct of_device_id rk3308codec_of_match[] = {
+	{ .compatible = "rockchip,rk3308-codec", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, rk3308codec_of_match);
+
+static struct platform_driver rk3308_codec_driver = {
+	.driver = {
+		   .name = "rk3308-acodec",
+		   .of_match_table = of_match_ptr(rk3308codec_of_match),
+	},
+	.probe = rk3308_platform_probe,
+	.remove = rk3308_platform_remove,
+};
+module_platform_driver(rk3308_codec_driver);
+
+MODULE_AUTHOR("Xing Zheng <zhengxing@rock-chips.com>");
+MODULE_DESCRIPTION("ASoC RK3308 Codec Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/rk3308_codec.h b/sound/soc/codecs/rk3308_codec.h
new file mode 100644
index 000000000000..6cfa69157785
--- /dev/null
+++ b/sound/soc/codecs/rk3308_codec.h
@@ -0,0 +1,960 @@
+/*
+ * rk3308_codec.h -- RK3308 ALSA Soc Audio Driver
+ *
+ * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __RK3308_CODEC_H__
+#define __RK3308_CODEC_H__
+
+#define ACODEC_RESET_CTL			0x00 /* REG 0x00 */
+
+/* ADC DIGITAL REGISTERS */
+#define ACODEC_ADC_I2S_CTL0			0x04 /* REG 0x01 */
+#define ACODEC_ADC_I2S_CTL1			0x08 /* REG 0x02 */
+#define ACODEC_ADC_BIST_MODE_SEL		0x0c /* REG 0x03 */
+/* Resevred REG 0x04 ~ 0x06 */
+#define ACODEC_ADC_DATA_PATH			0x1c /* REG 0x07 */
+/* Resevred REG 0x08 ~ 0x0f */
+
+/* REG 0x10 ~ 0x1c are used to configure AGC of Left channel (ALC1) */
+#define ACODEC_ADC_PGA_AGC_L_CTL0		0x40 /* REG 0x10 */
+#define ACODEC_ADC_PGA_AGC_L_CTL1		0x44 /* REG 0x11 */
+#define ACODEC_ADC_PGA_AGC_L_CTL2		0x48 /* REG 0x12 */
+#define ACODEC_ADC_PGA_AGC_L_CTL3		0x4c /* REG 0x13 */
+#define ACODEC_ADC_PGA_AGC_L_CTL4		0x50 /* REG 0x14 */
+#define ACODEC_ADC_PGA_AGC_L_LO_MAX		0x54 /* REG 0x15 */
+#define ACODEC_ADC_PGA_AGC_L_HI_MAX		0x58 /* REG 0x16 */
+#define ACODEC_ADC_PGA_AGC_L_LO_MIN		0x5c /* REG 0x17 */
+#define ACODEC_ADC_PGA_AGC_L_HI_MIN		0x60 /* REG 0x18 */
+#define ACODEC_ADC_PGA_AGC_L_CTL5		0x64 /* REG 0x19 */
+/* Resevred REG 0x1a ~ 0x1b */
+#define ACODEC_ADC_AGC_L_RO_GAIN		0x70 /* REG 0x1c */
+
+/* REG 0x20 ~ 0x2c are used to configure AGC of Right channel (ALC2) */
+#define ACODEC_ADC_PGA_AGC_R_CTL0		0x80 /* REG 0x20 */
+#define ACODEC_ADC_PGA_AGC_R_CTL1		0x84 /* REG 0x21 */
+#define ACODEC_ADC_PGA_AGC_R_CTL2		0x88 /* REG 0x22 */
+#define ACODEC_ADC_PGA_AGC_R_CTL3		0x8c /* REG 0x23 */
+#define ACODEC_ADC_PGA_AGC_R_CTL4		0x90 /* REG 0x24 */
+#define ACODEC_ADC_PGA_AGC_R_LO_MAX		0x94 /* REG 0x25 */
+#define ACODEC_ADC_PGA_AGC_R_HI_MAX		0x98 /* REG 0x26 */
+#define ACODEC_ADC_PGA_AGC_R_LO_MIN		0x9c /* REG 0x27 */
+#define ACODEC_ADC_PGA_AGC_R_HI_MIN		0xa0 /* REG 0x28 */
+#define ACODEC_ADC_PGA_AGC_R_CTL5		0xa4 /* REG 0x29 */
+/* Resevred REG 0x2a ~ 0x2b */
+#define ACODEC_ADC_AGC_R_RO_GAIN		0xb0 /* REG 0x2c */
+
+/* DAC DIGITAL REGISTERS */
+#define ACODEC_DAC_I2S_CTL0			0x04 /* REG 0x01 */
+#define ACODEC_DAC_I2S_CTL1			0x08 /* REG 0x02 */
+#define ACODEC_DAC_BIST_MODE_SEL		0x0c /* REG 0x03 */
+/* Resevred REG 0x04 */
+#define ACODEC_DAC_DATA_SEL			0x14 /* REG 0x05 */
+/* Resevred REG 0x06 ~ 0x09 */
+#define ACODEC_DAC_DATA_HI			0x28 /* REG 0x0a */
+#define ACODEC_DAC_DATA_LO			0x2c /* REG 0x0b */
+/* Resevred REG 0x0c ~ 0x0f */
+
+/* ADC ANALOG REGISTERS */
+#define ACODEC_ADC_ANA_MIC_CTL			0x00 /* REG 0x00 */
+#define ACODEC_ADC_ANA_MIC_GAIN			0x04 /* REG 0x01 */
+#define ACODEC_ADC_ANA_ALC_CTL			0x08 /* REG 0x02 */
+#define ACODEC_ADC_ANA_ALC_GAIN1		0x0c /* REG 0x03 */
+#define ACODEC_ADC_ANA_ALC_GAIN2		0x10 /* REG 0x04 */
+#define ACODEC_ADC_ANA_CTL0			0x14 /* REG 0x05 */
+#define ACODEC_ADC_ANA_CTL1			0x18 /* REG 0x06 */
+#define ACODEC_ADC_ANA_CTL2			0x1c /* REG 0x07 */
+#define ACODEC_ADC_ANA_CTL3			0x20 /* REG 0x08 */
+/* Resevred REG 0x09 */
+#define ACODEC_ADC_ANA_CTL4			0x28 /* REG 0x0a */
+#define ACODEC_ADC_ANA_ALC_PGA			0x2c /* REG 0x0b */
+/* Resevred REG 0x0c ~ 0x0f */
+
+/* DAC ANALOG REGISTERS */
+#define ACODEC_DAC_ANA_CTL0			0x00 /* REG 0x00 */
+#define ACODEC_DAC_ANA_POP_VOLT			0x04 /* REG 0x01 */
+#define ACODEC_DAC_ANA_CTL1			0x08 /* REG 0x02 */
+#define ACODEC_DAC_ANA_HPOUT			0x0c /* REG 0x03 */
+#define ACODEC_DAC_ANA_LINEOUT			0x10 /* REG 0x04 */
+#define ACODEC_DAC_ANA_L_HPOUT_GAIN		0x14 /* REG 0x05 */
+#define ACODEC_DAC_ANA_R_HPOUT_GAIN		0x18 /* REG 0x06 */
+/* Resevred REG 0x07 ~ 0x0b */
+#define ACODEC_DAC_ANA_HPMIX_CTL0		0x30 /* REG 0x0c */
+#define ACODEC_DAC_ANA_HPMIX_CTL1		0x34 /* REG 0x0d */
+/* Resevred REG 0x0e ~ 0x0f */
+
+/*
+ * These registers are referenced by codec driver
+ */
+
+#define RK3308_GLB_CON				ACODEC_RESET_CTL
+
+/* ADC DIGITAL REGISTERS */
+
+/*
+ * The ADC chanel are 0 ~ 3, that control:
+ *
+ * CH0: left_0(ADC1) and right_0(ADC2)
+ * CH1: left_1(ADC3) and right_1(ADC4)
+ * CH2: left_2(ADC5) and right_2(ADC6)
+ * CH3: left_3(ADC7) and right_3(ADC8)
+ */
+#define RK3308_ADC_DIG_OFFSET(ch)		((ch & 0x3) * 0xc0 + 0x0)
+
+#define RK3308_ADC_DIG_CON01(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_I2S_CTL0)
+#define RK3308_ADC_DIG_CON02(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_I2S_CTL1)
+#define RK3308_ADC_DIG_CON03(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_BIST_MODE_SEL)
+#define RK3308_ADC_DIG_CON07(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_DATA_PATH)
+
+#define RK3308_ALC_L_DIG_CON00(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_CTL0)
+#define RK3308_ALC_L_DIG_CON01(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_CTL1)
+#define RK3308_ALC_L_DIG_CON02(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_CTL2)
+#define RK3308_ALC_L_DIG_CON03(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_CTL3)
+#define RK3308_ALC_L_DIG_CON04(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_CTL4)
+#define RK3308_ALC_L_DIG_CON05(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_LO_MAX)
+#define RK3308_ALC_L_DIG_CON06(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_HI_MAX)
+#define RK3308_ALC_L_DIG_CON07(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_LO_MIN)
+#define RK3308_ALC_L_DIG_CON08(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_HI_MIN)
+#define RK3308_ALC_L_DIG_CON09(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_L_CTL5)
+#define RK3308_ALC_L_DIG_CON12(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_AGC_L_RO_GAIN)
+
+#define RK3308_ALC_R_DIG_CON00(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_CTL0)
+#define RK3308_ALC_R_DIG_CON01(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_CTL1)
+#define RK3308_ALC_R_DIG_CON02(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_CTL2)
+#define RK3308_ALC_R_DIG_CON03(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_CTL3)
+#define RK3308_ALC_R_DIG_CON04(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_CTL4)
+#define RK3308_ALC_R_DIG_CON05(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_LO_MAX)
+#define RK3308_ALC_R_DIG_CON06(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_HI_MAX)
+#define RK3308_ALC_R_DIG_CON07(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_LO_MIN)
+#define RK3308_ALC_R_DIG_CON08(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_HI_MIN)
+#define RK3308_ALC_R_DIG_CON09(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_PGA_AGC_R_CTL5)
+#define RK3308_ALC_R_DIG_CON12(ch)		(RK3308_ADC_DIG_OFFSET(ch) + ACODEC_ADC_AGC_R_RO_GAIN)
+
+/* DAC DIGITAL REGISTERS */
+#define RK3308_DAC_DIG_OFFSET			0x300
+
+#define RK3308_DAC_DIG_CON01			(RK3308_DAC_DIG_OFFSET + ACODEC_DAC_I2S_CTL0)
+#define RK3308_DAC_DIG_CON02			(RK3308_DAC_DIG_OFFSET + ACODEC_DAC_I2S_CTL1)
+#define RK3308_DAC_DIG_CON03			(RK3308_DAC_DIG_OFFSET + ACODEC_DAC_BIST_MODE_SEL)
+#define RK3308_DAC_DIG_CON05			(RK3308_DAC_DIG_OFFSET + ACODEC_DAC_DATA_SEL)
+#define RK3308_DAC_DIG_CON10			(RK3308_DAC_DIG_OFFSET + ACODEC_DAC_DATA_HI)
+#define RK3308_DAC_DIG_CON11			(RK3308_DAC_DIG_OFFSET + ACODEC_DAC_DATA_LO)
+
+/* ADC ANALOG REGISTERS */
+/*
+ * The ADC chanel are 0 ~ 3, that control:
+ *
+ * CH0: left_0(ADC1) and right_0(ADC2)
+ * CH1: left_1(ADC3) and right_1(ADC4)
+ * CH2: left_2(ADC5) and right_2(ADC6)
+ * CH3: left_3(ADC7) and right_3(ADC8)
+ */
+#define RK3308_ADC_ANA_OFFSET(ch)		((ch & 0x3) * 0x40 + 0x340)
+
+#define RK3308_ADC_ANA_CON00(ch)		(RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_MIC_CTL)
+#define RK3308_ADC_ANA_CON01(ch)		(RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_MIC_GAIN)
+#define RK3308_ADC_ANA_CON02(ch)		(RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_ALC_CTL)
+#define RK3308_ADC_ANA_CON03(ch)		(RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_ALC_GAIN1)
+#define RK3308_ADC_ANA_CON04(ch)		(RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_ALC_GAIN2)
+#define RK3308_ADC_ANA_CON05(ch)		(RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_CTL0)
+#define RK3308_ADC_ANA_CON06(ch)		(RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_CTL1)
+#define RK3308_ADC_ANA_CON07(ch)		(RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_CTL2)
+#define RK3308_ADC_ANA_CON08(ch)		(RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_CTL3)
+#define RK3308_ADC_ANA_CON10(ch)		(RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_CTL4)
+#define RK3308_ADC_ANA_CON11(ch)		(RK3308_ADC_ANA_OFFSET(ch) + ACODEC_ADC_ANA_ALC_PGA)
+
+/* DAC ANALOG REGISTERS */
+#define RK3308_DAC_ANA_OFFSET			0x440
+
+#define RK3308_DAC_ANA_CON00			(RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_CTL0)
+#define RK3308_DAC_ANA_CON01			(RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_POP_VOLT)
+#define RK3308_DAC_ANA_CON02			(RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_CTL1)
+#define RK3308_DAC_ANA_CON03			(RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_HPOUT)
+#define RK3308_DAC_ANA_CON04			(RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_LINEOUT)
+#define RK3308_DAC_ANA_CON05			(RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_L_HPOUT_GAIN)
+#define RK3308_DAC_ANA_CON06			(RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_R_HPOUT_GAIN)
+#define RK3308_DAC_ANA_CON12			(RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_HPMIX_CTL0)
+#define RK3308_DAC_ANA_CON13			(RK3308_DAC_ANA_OFFSET + ACODEC_DAC_ANA_HPMIX_CTL1)
+
+/*
+ * These are the bits for registers
+ */
+
+/* RK3308_GLB_CON - REG: 0x0000 */
+#define RK3308_ADC_BIST_WORK			(1 << 7)
+#define RK3308_ADC_BIST_RESET			(0 << 7)
+#define RK3308_DAC_BIST_WORK			(1 << 6)
+#define RK3308_DAC_BIST_RESET			(0 << 6)
+#define RK3308_CODEC_RST_MSK			(0x7 << 0)
+#define RK3308_ADC_DIG_WORK			(1 << 2)
+#define RK3308_ADC_DIG_RESET			(0 << 2)
+#define RK3308_DAC_DIG_WORK			(1 << 1)
+#define RK3308_DAC_DIG_RESET			(0 << 1)
+#define RK3308_SYS_WORK				(1 << 0)
+#define RK3308_SYS_RESET			(0 << 0)
+
+/* RK3308_ADC_DIG_CON01 - REG: 0x0004 */
+#define RK3308_ADC_I2S_LRC_POL_MSK		(1 << 0)
+#define RK3308_ADC_I2S_LRC_POL_REVERSAL		(1 << 0)
+#define RK3308_ADC_I2S_LRC_POL_NORMAL		(0 << 0)
+#define RK3308_ADC_I2S_VALID_LEN_SFT		5
+#define RK3308_ADC_I2S_VALID_LEN_MSK		(0x3 << RK3308_ADC_I2S_VALID_LEN_SFT)
+#define RK3308_ADC_I2S_VALID_LEN_32BITS		(0x3 << RK3308_ADC_I2S_VALID_LEN_SFT)
+#define RK3308_ADC_I2S_VALID_LEN_24BITS		(0x2 << RK3308_ADC_I2S_VALID_LEN_SFT)
+#define RK3308_ADC_I2S_VALID_LEN_20BITS		(0x1 << RK3308_ADC_I2S_VALID_LEN_SFT)
+#define RK3308_ADC_I2S_VALID_LEN_16BITS		(0x0 << RK3308_ADC_I2S_VALID_LEN_SFT)
+#define RK3308_ADC_I2S_MODE_SFT			3
+#define RK3308_ADC_I2S_MODE_MSK			(0x3 << RK3308_ADC_I2S_MODE_SFT)
+#define RK3308_ADC_I2S_MODE_PCM			(0x3 << RK3308_ADC_I2S_MODE_SFT)
+#define RK3308_ADC_I2S_MODE_I2S			(0x2 << RK3308_ADC_I2S_MODE_SFT)
+#define RK3308_ADC_I2S_MODE_LJ			(0x1 << RK3308_ADC_I2S_MODE_SFT)
+#define RK3308_ADC_I2S_MODE_RJ			(0x0 << RK3308_ADC_I2S_MODE_SFT)
+#define RK3308_ADC_I2S_LR_MSK			(1 << 1)
+#define RK3308_ADC_I2S_LR_SWAP			(1 << 1)
+#define RK3308_ADC_I2S_LR_NORMAL		(0 << 1)
+#define RK3308_ADC_I2S_TYPE_MSK			(1 << 0)
+#define RK3308_ADC_I2S_MONO			(1 << 0)
+#define RK3308_ADC_I2S_STEREO			(0 << 0)
+
+/* RK3308_ADC_DIG_CON02 - REG: 0x0008 */
+#define RK3308_ADC_IO_MODE_MSK			(1 << 5)
+#define RK3308_ADC_IO_MODE_MASTER		(1 << 5)
+#define RK3308_ADC_IO_MODE_SLAVE		(0 << 5)
+#define RK3308_ADC_MODE_MSK			(1 << 4)
+#define RK3308_ADC_MODE_MASTER			(1 << 4)
+#define RK3308_ADC_MODE_SLAVE			(0 << 4)
+#define RK3308_ADC_I2S_FRAME_LEN_SFT		2
+#define RK3308_ADC_I2S_FRAME_LEN_MSK		(0x3 << RK3308_ADC_I2S_FRAME_LEN_SFT)
+#define RK3308_ADC_I2S_FRAME_32BITS		(0x3 << RK3308_ADC_I2S_FRAME_LEN_SFT)
+#define RK3308_ADC_I2S_FRAME_24BITS		(0x2 << RK3308_ADC_I2S_FRAME_LEN_SFT)
+#define RK3308_ADC_I2S_FRAME_20BITS		(0x1 << RK3308_ADC_I2S_FRAME_LEN_SFT)
+#define RK3308_ADC_I2S_FRAME_16BITS		(0x0 << RK3308_ADC_I2S_FRAME_LEN_SFT)
+#define RK3308_ADC_I2S_MSK			(0x1 << 1)
+#define RK3308_ADC_I2S_WORK			(0x1 << 1)
+#define RK3308_ADC_I2S_RESET			(0x0 << 1)
+#define RK3308_ADC_I2S_BIT_CLK_POL_MSK		(0x1 << 0)
+#define RK3308_ADC_I2S_BIT_CLK_POL_REVERSAL	(0x1 << 0)
+#define RK3308_ADC_I2S_BIT_CLK_POL_NORMAL	(0x0 << 0)
+
+/* RK3308_ADC_DIG_CON03 - REG: 0x000c */
+#define RK3308_ADC_L_CH_BIST_SFT		2
+#define RK3308_ADC_L_CH_BIST_MSK		(0x3 << RK3308_ADC_L_CH_BIST_SFT)
+#define RK3308_ADC_L_CH_BIST_LEFT		(0x3 << RK3308_ADC_L_CH_BIST_SFT) /* normal mode */
+#define RK3308_ADC_L_CH_BIST_SINE		(0x2 << RK3308_ADC_L_CH_BIST_SFT)
+#define RK3308_ADC_L_CH_BIST_CUBE		(0x1 << RK3308_ADC_L_CH_BIST_SFT)
+#define RK3308_ADC_L_CH_BIST_RIGHT		(0x0 << RK3308_ADC_L_CH_BIST_SFT) /* normal mode */
+#define RK3308_ADC_R_CH_BIST_SFT		0
+#define RK3308_ADC_R_CH_BIST_MSK		(0x3 << RK3308_ADC_R_CH_BIST_SFT)
+#define RK3308_ADC_R_CH_BIST_LEFT		(0x3 << RK3308_ADC_R_CH_BIST_SFT) /* normal mode */
+#define RK3308_ADC_R_CH_BIST_SINE		(0x2 << RK3308_ADC_R_CH_BIST_SFT)
+#define RK3308_ADC_R_CH_BIST_CUBE		(0x1 << RK3308_ADC_R_CH_BIST_SFT)
+#define RK3308_ADC_R_CH_BIST_RIGHT		(0x0 << RK3308_ADC_R_CH_BIST_SFT) /* normal mode */
+
+/* RK3308_ADC_DIG_CON07 - REG: 0x001c */
+#define RK3308_ADCL_DATA_SFT			4
+#define RK3308_ADCL_DATA(x)			(x << RK3308_ADCL_DATA_SFT)
+#define RK3308_ADCR_DATA_SFT			2
+#define RK3308_ADCR_DATA(x)			(x << RK3308_ADCR_DATA_SFT)
+#define RK3308_ADCL_DATA_SEL_ADCL		(0x1 << 1)
+#define RK3308_ADCL_DATA_SEL_NORMAL		(0x0 << 1)
+#define RK3308_ADCR_DATA_SEL_ADCR		(0x1 << 0)
+#define RK3308_ADCR_DATA_SEL_NORMAL		(0x0 << 0)
+
+/*
+ * RK3308_ALC_L_DIG_CON00 - REG: 0x0040 + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON00 - REG: 0x0080 + ch * 0xc0
+ */
+#define RK3308_GAIN_ATTACK_JACK			(0x1 << 6)
+#define RK3308_GAIN_ATTACK_NORMAL		(0x0 << 6)
+#define RK3308_CTRL_GEN_SFT			4
+#define RK3308_CTRL_GEN_MSK			(0x3 << RK3308_ALC_CTRL_GEN_SFT)
+#define RK3308_CTRL_GEN_JACK3			(0x3 << RK3308_ALC_CTRL_GEN_SFT)
+#define RK3308_CTRL_GEN_JACK2			(0x2 << RK3308_ALC_CTRL_GEN_SFT)
+#define RK3308_CTRL_GEN_JACK1			(0x1 << RK3308_ALC_CTRL_GEN_SFT)
+#define RK3308_CTRL_GEN_NORMAL			(0x0 << RK3308_ALC_CTRL_GEN_SFT)
+#define RK3308_AGC_HOLD_TIME_SFT		0
+#define RK3308_AGC_HOLD_TIME_MSK		(0xf << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_1S			(0xa << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_512MS		(0x9 << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_256MS		(0x8 << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_128MS		(0x7 << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_64MS		(0x6 << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_32MS		(0x5 << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_16MS		(0x4 << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_8MS		(0x3 << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_4MS		(0x2 << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_2MS		(0x1 << RK3308_AGC_HOLD_TIME_SFT)
+#define RK3308_AGC_HOLD_TIME_0MS		(0x0 << RK3308_AGC_HOLD_TIME_SFT)
+
+/*
+ * RK3308_ALC_L_DIG_CON01 - REG: 0x0044 + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON01 - REG: 0x0084 + ch * 0xc0
+ */
+#define RK3308_AGC_DECAY_TIME_SFT		4
+/* Normal mode (reg_agc_mode = 0) */
+#define RK3308_AGC_DECAY_NORMAL_MSK		(0xf << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_NORMAL_512MS		(0xa << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_NORMAL_256MS		(0x9 << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_NORMAL_128MS		(0x8 << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_NORMAL_64MS		(0x7 << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_NORMAL_32MS		(0x6 << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_NORMAL_16MS		(0x5 << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_NORMAL_8MS		(0x4 << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_NORMAL_4MS		(0x3 << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_NORMAL_2MS		(0x2 << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_NORMAL_1MS		(0x1 << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_NORMAL_0MS		(0x0 << RK3308_AGC_DECAY_TIME_SFT)
+/* Limiter mode (reg_agc_mode = 1) */
+#define RK3308_AGC_DECAY_LIMITER_MSK		(0xf << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_LIMITER_128MS		(0xa << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_LIMITER_64MS		(0x9 << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_LIMITER_32MS		(0x8 << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_LIMITER_16MS		(0x7 << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_LIMITER_8MS		(0x6 << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_LIMITER_4MS		(0x5 << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_LIMITER_2MS		(0x4 << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_LIMITER_1MS		(0x3 << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_LIMITER_500US		(0x2 << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_LIMITER_250US		(0x1 << RK3308_AGC_DECAY_TIME_SFT)
+#define RK3308_AGC_DECAY_LIMITER_125US		(0x0 << RK3308_AGC_DECAY_TIME_SFT)
+
+#define RK3308_AGC_ATTACK_TIME_SFT		0
+/* Normal mode (reg_agc_mode = 0) */
+#define RK3308_AGC_ATTACK_NORMAL_MSK		(0xf << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_NORMAL_128MS		(0xa << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_NORMAL_64MS		(0x9 << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_NORMAL_32MS		(0x8 << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_NORMAL_16MS		(0x7 << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_NORMAL_8MS		(0x6 << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_NORMAL_4MS		(0x5 << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_NORMAL_2MS		(0x4 << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_NORMAL_1MS		(0x3 << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_NORMAL_500US		(0x2 << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_NORMAL_250US		(0x1 << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_NORMAL_125US		(0x0 << RK3308_AGC_ATTACK_TIME_SFT)
+/* Limiter mode (reg_agc_mode = 1) */
+#define RK3308_AGC_ATTACK_LIMITER_MSK		(0xf << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_LIMITER_32MS		(0xa << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_LIMITER_16MS		(0x9 << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_LIMITER_8MS		(0x8 << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_LIMITER_4MS		(0x7 << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_LIMITER_2MS		(0x6 << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_LIMITER_1MS		(0x5 << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_LIMITER_500US		(0x4 << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_LIMITER_250US		(0x3 << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_LIMITER_125US		(0x2 << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_LIMITER_64US		(0x1 << RK3308_AGC_ATTACK_TIME_SFT)
+#define RK3308_AGC_ATTACK_LIMITER_32US		(0x0 << RK3308_AGC_ATTACK_TIME_SFT)
+
+/*
+ * RK3308_ALC_L_DIG_CON02 - REG: 0x0048 + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON02 - REG: 0x0088 + ch * 0xc0
+ */
+#define RK3308_AGC_MODE_LIMITER			(0x1 << 7)
+#define RK3308_AGC_MODE_NORMAL			(0x0 << 7)
+#define RK3308_AGC_ZERO_CRO_EN			(0x1 << 6)
+#define RK3308_AGC_ZERO_CRO_DIS			(0x0 << 6)
+#define RK3308_AGC_AMP_RECOVER_GAIN		(0x1 << 5)
+#define RK3308_AGC_AMP_RECOVER_LVOL		(0x0 << 5)
+#define RK3308_AGC_FAST_DEC_EN			(0x1 << 4)
+#define RK3308_AGC_FAST_DEC_DIS			(0x0 << 4)
+#define RK3308_AGC_NOISE_GATE_EN		(0x1 << 3)
+#define RK3308_AGC_NOISE_GATE_DIS		(0x0 << 3)
+#define RK3308_AGC_NOISE_GATE_THRESH_SFT	0
+#define RK3308_AGC_NOISE_GATE_THRESH_MSK	(0x7 << RK3308_AGC_NOISE_GATE_THRESH_SFT)
+#define RK3308_AGC_NOISE_GATE_THRESH_N81DB	(0x7 << RK3308_AGC_NOISE_GATE_THRESH_SFT)
+#define RK3308_AGC_NOISE_GATE_THRESH_N75DB	(0x6 << RK3308_AGC_NOISE_GATE_THRESH_SFT)
+#define RK3308_AGC_NOISE_GATE_THRESH_N69DB	(0x5 << RK3308_AGC_NOISE_GATE_THRESH_SFT)
+#define RK3308_AGC_NOISE_GATE_THRESH_N63DB	(0x4 << RK3308_AGC_NOISE_GATE_THRESH_SFT)
+#define RK3308_AGC_NOISE_GATE_THRESH_N57DB	(0x3 << RK3308_AGC_NOISE_GATE_THRESH_SFT)
+#define RK3308_AGC_NOISE_GATE_THRESH_N51DB	(0x2 << RK3308_AGC_NOISE_GATE_THRESH_SFT)
+#define RK3308_AGC_NOISE_GATE_THRESH_N45DB	(0x1 << RK3308_AGC_NOISE_GATE_THRESH_SFT)
+#define RK3308_AGC_NOISE_GATE_THRESH_N39DB	(0x0 << RK3308_AGC_NOISE_GATE_THRESH_SFT)
+
+/*
+ * RK3308_ALC_L_DIG_CON03 - REG: 0x004c + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON03 - REG: 0x008c + ch * 0xc0
+ */
+#define RK3308_AGC_PGA_ZERO_CRO_EN		(0x1 << 5)
+#define RK3308_AGC_PGA_ZERO_CRO_DIS		(0x0 << 5)
+#define RK3308_AGC_PGA_GAIN_SFT			0
+#define RK3308_AGC_PGA_GAIN_MSK			(0x1f << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_PDB_28_5		(0x1f << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_PDB_27		(0x1e << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_PDB_25_5		(0x1d << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_PDB_24		(0x1c << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_PDB_22_5		(0x1b << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_PDB_21		(0x1a << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_PDB_19_5		(0x19 << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_PDB_18		(0x18 << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_PDB_16_5		(0x17 << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_PDB_15		(0x16 << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_PDB_13_5		(0x15 << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_PDB_12		(0x14 << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_PDB_10_5		(0x13 << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_PDB_9		(0x12 << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_PDB_7_5		(0x11 << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_PDB_6		(0x10 << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_PDB_4_5		(0x0f << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_PDB_3		(0x0e << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_PDB_1_5		(0x0d << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_0DB			(0x0c << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_NDB_1_5		(0x0b << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_NDB_3		(0x0a << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_NDB_4_5		(0x09 << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_NDB_6		(0x08 << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_NDB_7_5		(0x07 << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_NDB_9		(0x06 << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_NDB_10_5		(0x05 << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_NDB_12		(0x04 << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_NDB_13_5		(0x03 << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_NDB_15		(0x02 << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_NDB_16_5		(0x01 << RK3308_AGC_PGA_GAIN_SFT)
+#define RK3308_AGC_PGA_GAIN_NDB_18		(0x00 << RK3308_AGC_PGA_GAIN_SFT)
+
+/*
+ * RK3308_ALC_L_DIG_CON04 - REG: 0x0050 + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON04 - REG: 0x0090 + ch * 0xc0
+ */
+#define RK3308_AGC_SLOW_CLK_EN			(0x1 << 3)
+#define RK3308_AGC_SLOW_CLK_DIS			(0x0 << 3)
+#define RK3308_AGC_APPROX_RATE_SFT		0
+#define RK3308_AGC_APPROX_RATE_MSK		(0x7 << RK3308_AGC_APPROX_RATE_SFT)
+#define RK3308_AGC_APPROX_RATE_8K		(0x7 << RK3308_AGC_APPROX_RATE_SFT)
+#define RK3308_AGC_APPROX_RATE_12K		(0x6 << RK3308_AGC_APPROX_RATE_SFT)
+#define RK3308_AGC_APPROX_RATE_16K		(0x5 << RK3308_AGC_APPROX_RATE_SFT)
+#define RK3308_AGC_APPROX_RATE_24K		(0x4 << RK3308_AGC_APPROX_RATE_SFT)
+#define RK3308_AGC_APPROX_RATE_32K		(0x3 << RK3308_AGC_APPROX_RATE_SFT)
+#define RK3308_AGC_APPROX_RATE_44_1K		(0x2 << RK3308_AGC_APPROX_RATE_SFT)
+#define RK3308_AGC_APPROX_RATE_48K		(0x1 << RK3308_AGC_APPROX_RATE_SFT)
+#define RK3308_AGC_APPROX_RATE_96K		(0x0 << RK3308_AGC_APPROX_RATE_SFT)
+
+/*
+ * RK3308_ALC_L_DIG_CON05 - REG: 0x0054 + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON05 - REG: 0x0094 + ch * 0xc0
+ */
+#define RK3308_AGC_LO_8BITS_AGC_MAX_MSK		0xff
+
+/*
+ * RK3308_ALC_L_DIG_CON06 - REG: 0x0058 + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON06 - REG: 0x0098 + ch * 0xc0
+ */
+#define RK3308_AGC_HI_8BITS_AGC_MAX_MSK		0xff
+
+/*
+ * RK3308_ALC_L_DIG_CON07 - REG: 0x005c + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON07 - REG: 0x009c + ch * 0xc0
+ */
+#define RK3308_AGC_LO_8BITS_AGC_MIN_MSK		0xff
+
+/*
+ * RK3308_ALC_L_DIG_CON08 - REG: 0x0060 + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON08 - REG: 0x00a0 + ch * 0xc0
+ */
+#define RK3308_AGC_HI_8BITS_AGC_MIN_MSK		0xff
+
+/*
+ * RK3308_ALC_L_DIG_CON09 - REG: 0x0064 + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON09 - REG: 0x00a4 + ch * 0xc0
+ */
+#define RK3308_AGC_FUNC_SEL_MSK			(0x1 << 6)
+#define RK3308_AGC_FUNC_SEL_EN			(0x1 << 6)
+#define RK3308_AGC_FUNC_SEL_DIS			(0x0 << 6)
+#define RK3308_AGC_MAX_GAIN_PGA_SFT		3
+#define RK3308_AGC_MAX_GAIN_PGA_MSK		(0x7 << RK3308_AGC_MAX_GAIN_PGA_SFT)
+#define RK3308_AGC_MAX_GAIN_PGA_PDB_28_5	(0x7 << RK3308_AGC_MAX_GAIN_PGA_SFT)
+#define RK3308_AGC_MAX_GAIN_PGA_PDB_22_5	(0x6 << RK3308_AGC_MAX_GAIN_PGA_SFT)
+#define RK3308_AGC_MAX_GAIN_PGA_PDB_16_5	(0x5 << RK3308_AGC_MAX_GAIN_PGA_SFT)
+#define RK3308_AGC_MAX_GAIN_PGA_PDB_10_5	(0x4 << RK3308_AGC_MAX_GAIN_PGA_SFT)
+#define RK3308_AGC_MAX_GAIN_PGA_PDB_4_5		(0x3 << RK3308_AGC_MAX_GAIN_PGA_SFT)
+#define RK3308_AGC_MAX_GAIN_PGA_NDB_1_5		(0x2 << RK3308_AGC_MAX_GAIN_PGA_SFT)
+#define RK3308_AGC_MAX_GAIN_PGA_NDB_7_5		(0x1 << RK3308_AGC_MAX_GAIN_PGA_SFT)
+#define RK3308_AGC_MAX_GAIN_PGA_NDB_13_5	(0x0 << RK3308_AGC_MAX_GAIN_PGA_SFT)
+#define RK3308_AGC_MIN_GAIN_PGA_SFT		0
+#define RK3308_AGC_MIN_GAIN_PGA_MSK		(0x7 << RK3308_AGC_MIN_GAIN_PGA_SFT)
+#define RK3308_AGC_MIN_GAIN_PGA_PDB_24		(0x7 << RK3308_AGC_MIN_GAIN_PGA_SFT)
+#define RK3308_AGC_MIN_GAIN_PGA_PDB_18		(0x6 << RK3308_AGC_MIN_GAIN_PGA_SFT)
+#define RK3308_AGC_MIN_GAIN_PGA_PDB_12		(0x5 << RK3308_AGC_MIN_GAIN_PGA_SFT)
+#define RK3308_AGC_MIN_GAIN_PGA_PDB_6		(0x4 << RK3308_AGC_MIN_GAIN_PGA_SFT)
+#define RK3308_AGC_MIN_GAIN_PGA_0DB		(0x3 << RK3308_AGC_MIN_GAIN_PGA_SFT)
+#define RK3308_AGC_MIN_GAIN_PGA_NDB_6		(0x2 << RK3308_AGC_MIN_GAIN_PGA_SFT)
+#define RK3308_AGC_MIN_GAIN_PGA_NDB_12		(0x1 << RK3308_AGC_MIN_GAIN_PGA_SFT)
+#define RK3308_AGC_MIN_GAIN_PGA_NDB_18		(0x0 << RK3308_AGC_MIN_GAIN_PGA_SFT)
+
+/*
+ * RK3308_ALC_L_DIG_CON12 - REG: 0x0068 + ch * 0xc0
+ * RK3308_ALC_R_DIG_CON12 - REG: 0x00a8 + ch * 0xc0
+ */
+#define RK3308_AGC_GAIN_MSK			0x1f
+
+/* RK3308_DAC_DIG_CON01 - REG: 0x0304 */
+#define RK3308_DAC_I2S_LRC_POL_MSK		(0x1 << 7)
+#define RK3308_DAC_I2S_LRC_POL_REVERSAL		(0x1 << 7)
+#define RK3308_DAC_I2S_LRC_POL_NORMAL		(0x0 << 7)
+#define RK3308_DAC_I2S_VALID_LEN_SFT		5
+#define RK3308_DAC_I2S_VALID_LEN_MSK		(0x3 << RK3308_DAC_I2S_VALID_LEN_SFT)
+#define RK3308_DAC_I2S_VALID_LEN_32BITS		(0x3 << RK3308_DAC_I2S_VALID_LEN_SFT)
+#define RK3308_DAC_I2S_VALID_LEN_24BITS		(0x2 << RK3308_DAC_I2S_VALID_LEN_SFT)
+#define RK3308_DAC_I2S_VALID_LEN_20BITS		(0x1 << RK3308_DAC_I2S_VALID_LEN_SFT)
+#define RK3308_DAC_I2S_VALID_LEN_16BITS		(0x0 << RK3308_DAC_I2S_VALID_LEN_SFT)
+#define RK3308_DAC_I2S_MODE_SFT			3
+#define RK3308_DAC_I2S_MODE_MSK			(0x3 << RK3308_DAC_I2S_MODE_SFT)
+#define RK3308_DAC_I2S_MODE_PCM			(0x3 << RK3308_DAC_I2S_MODE_SFT)
+#define RK3308_DAC_I2S_MODE_I2S			(0x2 << RK3308_DAC_I2S_MODE_SFT)
+#define RK3308_DAC_I2S_MODE_LJ			(0x1 << RK3308_DAC_I2S_MODE_SFT)
+#define RK3308_DAC_I2S_MODE_RJ			(0x0 << RK3308_DAC_I2S_MODE_SFT)
+#define RK3308_DAC_I2S_LR_MSK			(0x1 << 2)
+#define RK3308_DAC_I2S_LR_SWAP			(0x1 << 2)
+#define RK3308_DAC_I2S_LR_NORMAL		(0x0 << 2)
+
+/* RK3308_DAC_DIG_CON02 - REG: 0x0308 */
+#define RK3308_DAC_IO_MODE_MSK			(0x1 << 5)
+#define RK3308_DAC_IO_MODE_MASTER		(0x1 << 5)
+#define RK3308_DAC_IO_MODE_SLAVE		(0x0 << 5)
+#define RK3308_DAC_MODE_MSK			(0x1 << 4)
+#define RK3308_DAC_MODE_MASTER			(0x1 << 4)
+#define RK3308_DAC_MODE_SLAVE			(0x0 << 4)
+#define RK3308_DAC_I2S_FRAME_LEN_SFT		2
+#define RK3308_DAC_I2S_FRAME_LEN_MSK		(0x3 << RK3308_DAC_I2S_FRAME_LEN_SFT)
+#define RK3308_DAC_I2S_FRAME_32BITS		(0x3 << RK3308_DAC_I2S_FRAME_LEN_SFT)
+#define RK3308_DAC_I2S_FRAME_24BITS		(0x2 << RK3308_DAC_I2S_FRAME_LEN_SFT)
+#define RK3308_DAC_I2S_FRAME_20BITS		(0x1 << RK3308_DAC_I2S_FRAME_LEN_SFT)
+#define RK3308_DAC_I2S_FRAME_16BITS		(0x0 << RK3308_DAC_I2S_FRAME_LEN_SFT)
+#define RK3308_DAC_I2S_MSK			(0x1 << 1)
+#define RK3308_DAC_I2S_WORK			(0x1 << 1)
+#define RK3308_DAC_I2S_RESET			(0x0 << 1)
+#define RK3308_DAC_I2S_BIT_CLK_POL_MSK		(0x1 << 0)
+#define RK3308_DAC_I2S_BIT_CLK_POL_REVERSAL	(0x1 << 0)
+#define RK3308_DAC_I2S_BIT_CLK_POL_NORMAL	(0x0 << 0)
+
+/* RK3308_DAC_DIG_CON03 - REG: 0x030C */
+#define RK3308_DAC_L_CH_BIST_SFT		2
+#define RK3308_DAC_L_CH_BIST_MSK		(0x3 << RK3308_DAC_L_CH_BIST_SFT)
+#define RK3308_DAC_L_CH_BIST_LEFT		(0x3 << RK3308_DAC_L_CH_BIST_SFT) /* normal mode */
+#define RK3308_DAC_L_CH_BIST_CUBE		(0x2 << RK3308_DAC_L_CH_BIST_SFT)
+#define RK3308_DAC_L_CH_BIST_SINE		(0x1 << RK3308_DAC_L_CH_BIST_SFT)
+#define RK3308_DAC_L_CH_BIST_RIGHT		(0x0 << RK3308_DAC_L_CH_BIST_SFT) /* normal mode */
+#define RK3308_DAC_R_CH_BIST_SFT		0
+#define RK3308_DAC_R_CH_BIST_MSK		(0x3 << RK3308_DAC_R_CH_BIST_SFT)
+#define RK3308_DAC_R_CH_BIST_LEFT		(0x3 << RK3308_DAC_R_CH_BIST_SFT) /* normal mode */
+#define RK3308_DAC_R_CH_BIST_CUBE		(0x2 << RK3308_DAC_R_CH_BIST_SFT)
+#define RK3308_DAC_R_CH_BIST_SINE		(0x1 << RK3308_DAC_R_CH_BIST_SFT)
+#define RK3308_DAC_R_CH_BIST_RIGHT		(0x0 << RK3308_DAC_R_CH_BIST_SFT) /* normal mode */
+
+/* RK3308_DAC_DIG_CON05 - REG: 0x0314 */
+#define RK3308_DAC_L_REG_CTL_INDATA		(0x1 << 2)
+#define RK3308_DAC_L_NORMAL_DATA		(0x0 << 2)
+#define RK3308_DAC_R_REG_CTL_INDATA		(0x1 << 1)
+#define RK3308_DAC_R_NORMAL_DATA		(0x0 << 1)
+
+/* RK3308_DAC_DIG_CON10 - REG: 0x0328 */
+#define RK3308_DAC_DATA_HI4(x)			(x & 0xf) /* Need to RK3308_DAC_x_REG_CTL_INDATA */
+
+/* RK3308_DAC_DIG_CON11 - REG: 0x032c */
+#define RK3308_DAC_DATA_LO8(x)			(x & 0xff) /* Need to RK3308_DAC_x_REG_CTL_INDATA */
+
+/* RK3308_ADC_ANA_CON00 - REG: 0x0340 */
+#define RK3308_ADC_CH1_CH2_MIC_ALL_MSK		(0xff << 0)
+#define RK3308_ADC_CH1_CH2_MIC_ALL		0xff
+#define RK3308_ADC_CH2_MIC_UNMUTE		(0x1 << 7)
+#define RK3308_ADC_CH2_MIC_MUTE			(0x0 << 7)
+#define RK3308_ADC_CH2_MIC_WORK			(0x1 << 6)
+#define RK3308_ADC_CH2_MIC_INIT			(0x0 << 6)
+#define RK3308_ADC_CH2_MIC_EN			(0x1 << 5)
+#define RK3308_ADC_CH2_MIC_DIS			(0x0 << 5)
+#define RK3308_ADC_CH2_BUF_REF_EN		(0x1 << 4)
+#define RK3308_ADC_CH2_BUF_REF_DIS		(0x0 << 4)
+#define RK3308_ADC_CH1_MIC_UNMUTE		(0x1 << 3)
+#define RK3308_ADC_CH1_MIC_MUTE			(0x0 << 3)
+#define RK3308_ADC_CH1_MIC_WORK			(0x1 << 2)
+#define RK3308_ADC_CH1_MIC_INIT			(0x0 << 2)
+#define RK3308_ADC_CH1_MIC_EN			(0x1 << 1)
+#define RK3308_ADC_CH1_MIC_DIS			(0x0 << 1)
+#define RK3308_ADC_CH1_BUF_REF_EN		(0x1 << 0)
+#define RK3308_ADC_CH1_BUF_REF_DIS		(0x0 << 0)
+
+/* RK3308_ADC_ANA_CON01 - REG: 0x0344 */
+#define RK3308_ADC_CH2_MIC_GAIN_SFT		4
+#define RK3308_ADC_CH2_MIC_GAIN_MSK		(0x3 << RK3308_ADC_CH2_MIC_GAIN_SFT)
+#define RK3308_ADC_CH2_MIC_GAIN_30DB		(0x3 << RK3308_ADC_CH2_MIC_GAIN_SFT)
+#define RK3308_ADC_CH2_MIC_GAIN_20DB		(0x2 << RK3308_ADC_CH2_MIC_GAIN_SFT)
+#define RK3308_ADC_CH2_MIC_GAIN_6DB		(0x1 << RK3308_ADC_CH2_MIC_GAIN_SFT)
+#define RK3308_ADC_CH2_MIC_GAIN_0DB		(0x0 << RK3308_ADC_CH2_MIC_GAIN_SFT)
+#define RK3308_ADC_CH1_MIC_GAIN_SFT		0
+#define RK3308_ADC_CH1_MIC_GAIN_MSK		(0x3 << RK3308_ADC_CH1_MIC_GAIN_SFT)
+#define RK3308_ADC_CH1_MIC_GAIN_30DB		(0x3 << RK3308_ADC_CH1_MIC_GAIN_SFT)
+#define RK3308_ADC_CH1_MIC_GAIN_20DB		(0x2 << RK3308_ADC_CH1_MIC_GAIN_SFT)
+#define RK3308_ADC_CH1_MIC_GAIN_6DB		(0x1 << RK3308_ADC_CH1_MIC_GAIN_SFT)
+#define RK3308_ADC_CH1_MIC_GAIN_0DB		(0x0 << RK3308_ADC_CH1_MIC_GAIN_SFT)
+
+/* RK3308_ADC_ANA_CON02 - REG: 0x0348 */
+#define RK3308_ADC_CH2_ALC_ZC_MSK		(0x7 << 4)
+#define RK3308_ADC_CH2_ZEROCROSS_DET_EN		(0x1 << 6)
+#define RK3308_ADC_CH2_ZEROCROSS_DET_DIS	(0x0 << 6)
+#define RK3308_ADC_CH2_ALC_WORK			(0x1 << 5)
+#define RK3308_ADC_CH2_ALC_INIT			(0x0 << 5)
+#define RK3308_ADC_CH2_ALC_EN			(0x1 << 4)
+#define RK3308_ADC_CH2_ALC_DIS			(0x0 << 4)
+
+#define RK3308_ADC_CH1_ALC_ZC_MSK		(0x7 << 0)
+#define RK3308_ADC_CH1_ZEROCROSS_DET_EN		(0x1 << 2)
+#define RK3308_ADC_CH1_ZEROCROSS_DET_DIS	(0x0 << 2)
+#define RK3308_ADC_CH1_ALC_WORK			(0x1 << 1)
+#define RK3308_ADC_CH1_ALC_INIT			(0x0 << 1)
+#define RK3308_ADC_CH1_ALC_EN			(0x1 << 0)
+#define RK3308_ADC_CH1_ALC_DIS			(0x0 << 0)
+
+/* RK3308_ADC_ANA_CON03 - REG: 0x034c */
+#define RK3308_ADC_CH1_ALC_GAIN_SFT		0
+#define RK3308_ADC_CH1_ALC_GAIN_MSK		(0x1f << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_PDB_28_5	(0x1f << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_PDB_27		(0x1e << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_PDB_25_5	(0x1d << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_PDB_24		(0x1c << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_PDB_22_5	(0x1b << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_PDB_21		(0x1a << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_PDB_19_5	(0x19 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_PDB_18		(0x18 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_PDB_16_5	(0x17 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_PDB_15		(0x16 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_PDB_13_5	(0x15 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_PDB_12		(0x14 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_PDB_10_5	(0x13 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_PDB_9		(0x12 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_PDB_7_5		(0x11 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_PDB_6		(0x10 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_PDB_4_5		(0x0f << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_PDB_3		(0x0e << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_PDB_1_5		(0x0d << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_0DB		(0x0c << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_NDB_1_5		(0x0b << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_NDB_3		(0x0a << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_NDB_4_5		(0x09 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_NDB_6		(0x08 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_NDB_7_5		(0x07 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_NDB_9		(0x06 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_NDB_10_5	(0x05 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_NDB_12		(0x04 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_NDB_13_5	(0x03 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_NDB_15		(0x02 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_NDB_16_5	(0x01 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+#define RK3308_ADC_CH1_ALC_GAIN_NDB_18		(0x00 << RK3308_ADC_CH1_ALC_GAIN_SFT)
+
+/* RK3308_ADC_ANA_CON04 - REG: 0x0350 */
+#define RK3308_ADC_CH2_ALC_GAIN_SFT		0
+#define RK3308_ADC_CH2_ALC_GAIN_MSK		(0x1f << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_PDB_28_5	(0x1f << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_PDB_27		(0x1e << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_PDB_25_5	(0x1d << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_PDB_24		(0x1c << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_PDB_22_5	(0x1b << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_PDB_21		(0x1a << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_PDB_19_5	(0x19 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_PDB_18		(0x18 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_PDB_16_5	(0x17 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_PDB_15		(0x16 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_PDB_13_5	(0x15 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_PDB_12		(0x14 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_PDB_10_5	(0x13 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_PDB_9		(0x12 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_PDB_7_5		(0x11 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_PDB_6		(0x10 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_PDB_4_5		(0x0f << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_PDB_3		(0x0e << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_PDB_1_5		(0x0d << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_0DB		(0x0c << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_NDB_1_5		(0x0b << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_NDB_3		(0x0a << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_NDB_4_5		(0x09 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_NDB_6		(0x08 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_NDB_7_5		(0x07 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_NDB_9		(0x06 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_NDB_10_5	(0x05 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_NDB_12		(0x04 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_NDB_13_5	(0x03 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_NDB_15		(0x02 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_NDB_16_5	(0x01 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+#define RK3308_ADC_CH2_ALC_GAIN_NDB_18		(0x00 << RK3308_ADC_CH2_ALC_GAIN_SFT)
+
+/* RK3308_ADC_ANA_CON05 - REG: 0x0354 */
+#define RK3308_ADC_CH2_ADC_CLK_MSK		(0x7 << 4)
+#define RK3308_ADC_CH2_ADC_WORK			(0x1 << 6)
+#define RK3308_ADC_CH2_ADC_INIT			(0x0 << 6)
+#define RK3308_ADC_CH2_ADC_EN			(0x1 << 5)
+#define RK3308_ADC_CH2_ADC_DIS			(0x0 << 5)
+#define RK3308_ADC_CH2_CLK_EN			(0x1 << 4)
+#define RK3308_ADC_CH2_CLK_DIS			(0x0 << 4)
+
+#define RK3308_ADC_CH1_ADC_CLK_MSK		(0x7 << 0)
+#define RK3308_ADC_CH1_ADC_WORK			(0x1 << 2)
+#define RK3308_ADC_CH1_ADC_INIT			(0x0 << 2)
+#define RK3308_ADC_CH1_ADC_EN			(0x1 << 1)
+#define RK3308_ADC_CH1_ADC_DIS			(0x0 << 1)
+#define RK3308_ADC_CH1_CLK_EN			(0x1 << 0)
+#define RK3308_ADC_CH1_CLK_DIS			(0x0 << 0)
+
+/* RK3308_ADC_ANA_CON06 - REG: 0x0358 */
+#define RK3308_ADC_CURRENT_MSK			(0x1 << 0)
+#define RK3308_ADC_CURRENT_EN			(0x1 << 0)
+#define RK3308_ADC_CURRENT_DIS			(0x0 << 0)
+
+/* RK3308_ADC_ANA_CON07 - REG: 0x035c */
+/* Note: The register configuration is only valid for ADC2 */
+#define RK3308_ADC_CH2_IN_SEL_SFT		6
+#define RK3308_ADC_CH2_IN_SEL_MSK		(0x3 << RK3308_ADC_CH2_IN_SEL_SFT)
+#define RK3308_ADC_CH2_IN_LINEIN_MIC		(0x3 << RK3308_ADC_CH2_IN_SEL_SFT)
+#define RK3308_ADC_CH2_IN_LINEIN		(0x2 << RK3308_ADC_CH2_IN_SEL_SFT)
+#define RK3308_ADC_CH2_IN_MIC			(0x1 << RK3308_ADC_CH2_IN_SEL_SFT)
+#define RK3308_ADC_CH2_IN_NONE			(0x0 << RK3308_ADC_CH2_IN_SEL_SFT)
+/* Note: The register configuration is only valid for ADC1 */
+#define RK3308_ADC_CH1_IN_SEL_SFT		4
+#define RK3308_ADC_CH1_IN_SEL_MSK		(0x3 << RK3308_ADC_CH1_IN_SEL_SFT)
+#define RK3308_ADC_CH1_IN_LINEIN_MIC		(0x3 << RK3308_ADC_CH1_IN_SEL_SFT)
+#define RK3308_ADC_CH1_IN_LINEIN		(0x2 << RK3308_ADC_CH1_IN_SEL_SFT)
+#define RK3308_ADC_CH1_IN_MIC			(0x1 << RK3308_ADC_CH1_IN_SEL_SFT)
+#define RK3308_ADC_CH1_IN_NONE			(0x0 << RK3308_ADC_CH1_IN_SEL_SFT)
+
+#define RK3308_ADC_MIC_BIAS_BUF_EN		(0x1 << 3)
+#define RK3308_ADC_MIC_BIAS_BUF_DIS		(0x0 << 3)
+#define RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT	0
+#define RK3308_ADC_LEVEL_RANGE_MICBIAS_MSK	(0x7 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT)
+#define RK3308_ADC_MICBIAS_VOLT_0_85		(0x7 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT)
+#define RK3308_ADC_MICBIAS_VOLT_0_8		(0x6 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT)
+#define RK3308_ADC_MICBIAS_VOLT_0_75		(0x5 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT)
+#define RK3308_ADC_MICBIAS_VOLT_0_7		(0x4 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT)
+#define RK3308_ADC_MICBIAS_VOLT_0_65		(0x3 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT)
+#define RK3308_ADC_MICBIAS_VOLT_0_6		(0x2 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT)
+#define RK3308_ADC_MICBIAS_VOLT_0_55		(0x1 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT)
+#define RK3308_ADC_MICBIAS_VOLT_0_5		(0x0 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT)
+
+/* RK3308_ADC_ANA_CON08 - REG: 0x0360 */
+#define RK3308_ADC_MICBIAS_CURRENT_MSK		(0x1 << 4)
+#define RK3308_ADC_MICBIAS_CURRENT_EN		(0x1 << 4)
+#define RK3308_ADC_MICBIAS_CURRENT_DIS		(0x0 << 4)
+
+/* RK3308_ADC_ANA_CON10 - REG: 0x0368 */
+#define RK3308_ADC_REF_EN			(0x1 << 7)
+#define RK3308_ADC_REF_DIS			(0x0 << 7)
+#define RK3308_ADC_CURRENT_CHARGE_SFT		0
+#define RK3308_ADC_CURRENT_CHARGE_MSK		(0x7f << RK3308_ADC_CURRENT_CHARGE_SFT)
+#define RK3308_ADC_DONT_SEL_ALL			(0x7f << RK3308_ADC_CURRENT_CHARGE_SFT)
+/*
+ * 0: Choose the current I
+ * 1: Don't choose the current I
+ */
+#define RK3308_ADC_SEL_I_1(x)			((x & 0x1) << 6)
+#define RK3308_ADC_SEL_I_2(x)			((x & 0x1) << 5)
+#define RK3308_ADC_SEL_I_4(x)			((x & 0x1) << 4)
+#define RK3308_ADC_SEL_I_8(x)			((x & 0x1) << 3)
+#define RK3308_ADC_SEL_I_16(x)			((x & 0x1) << 2)
+#define RK3308_ADC_SEL_I_32(x)			((x & 0x1) << 1)
+#define RK3308_ADC_SEL_I_64(x)			((x & 0x1) << 0)
+
+/* RK3308_ADC_ANA_CON11 - REG: 0x036c */
+#define RK3308_ADC_ALCR_CON_GAIN_PGAR_MSK	(0x1 << 1)
+#define RK3308_ADC_ALCR_CON_GAIN_PGAR_EN	(0x1 << 1)
+#define RK3308_ADC_ALCR_CON_GAIN_PGAR_DIS	(0x0 << 1)
+#define RK3308_ADC_ALCL_CON_GAIN_PGAL_MSK	(0x1 << 0)
+#define RK3308_ADC_ALCL_CON_GAIN_PGAL_EN	(0x1 << 0)
+#define RK3308_ADC_ALCL_CON_GAIN_PGAL_DIS	(0x0 << 0)
+
+/* RK3308_DAC_ANA_CON00 - REG: 0x0440 */
+#define RK3308_DAC_HEADPHONE_DET_EN		(0x1 << 1)
+#define RK3308_DAC_HEADPHONE_DET_DIS		(0x0 << 1)
+#define RK3308_DAC_CURRENT_MSK			(0x1 << 0)
+#define RK3308_DAC_CURRENT_EN			(0x1 << 0)
+#define RK3308_DAC_CURRENT_DIS			(0x0 << 0)
+
+/* RK3308_DAC_ANA_CON01 - REG: 0x0444 */
+#define RK3308_DAC_BUF_REF_R_MSK		(0x1 << 6)
+#define RK3308_DAC_BUF_REF_R_EN			(0x1 << 6)
+#define RK3308_DAC_BUF_REF_R_DIS		(0x0 << 6)
+#define RK3308_DAC_POP_SOUND_R_SFT		4
+#define RK3308_DAC_POP_SOUND_R_MSK		(0x3 << RK3308_DAC_POP_SOUND_R_SFT)
+#define RK3308_DAC_POP_SOUND_R_WORK		(0x2 << RK3308_DAC_POP_SOUND_R_SFT)
+#define RK3308_DAC_POP_SOUND_R_INIT		(0x1 << RK3308_DAC_POP_SOUND_R_SFT)
+#define RK3308_DAC_BUF_REF_L_MSK		(0x1 << 2)
+#define RK3308_DAC_BUF_REF_L_EN			(0x1 << 2)
+#define RK3308_DAC_BUF_REF_L_DIS		(0x0 << 2)
+#define RK3308_DAC_POP_SOUND_L_SFT		0
+#define RK3308_DAC_POP_SOUND_L_MSK		(0x3 << RK3308_DAC_POP_SOUND_L_SFT)
+#define RK3308_DAC_POP_SOUND_L_WORK		(0x2 << RK3308_DAC_POP_SOUND_L_SFT)
+#define RK3308_DAC_POP_SOUND_L_INIT		(0x1 << RK3308_DAC_POP_SOUND_L_SFT)
+
+/* RK3308_DAC_ANA_CON02 - REG: 0x0448 */
+#define RK3308_DAC_R_DAC_WORK			(0x1 << 7)
+#define RK3308_DAC_R_DAC_INIT			(0x0 << 7)
+#define RK3308_DAC_R_DAC_EN			(0x1 << 6)
+#define RK3308_DAC_R_DAC_DIS			(0x0 << 6)
+#define RK3308_DAC_R_CLK_EN			(0x1 << 5)
+#define RK3308_DAC_R_CLK_DIS			(0x0 << 5)
+#define RK3308_DAC_R_REF_EN			(0x1 << 4)
+#define RK3308_DAC_R_REF_DIS			(0x0 << 4)
+#define RK3308_DAC_L_DAC_WORK			(0x1 << 3)
+#define RK3308_DAC_L_DAC_INIT			(0x0 << 3)
+#define RK3308_DAC_L_DAC_EN			(0x1 << 2)
+#define RK3308_DAC_L_DAC_DIS			(0x0 << 2)
+#define RK3308_DAC_L_CLK_EN			(0x1 << 1)
+#define RK3308_DAC_L_CLK_DIS			(0x0 << 1)
+#define RK3308_DAC_L_REF_EN			(0x1 << 0)
+#define RK3308_DAC_L_REF_DIS			(0x0 << 0)
+
+/* RK3308_DAC_ANA_CON03 - REG: 0x044c */
+#define RK3308_DAC_R_HPOUT_WORK			(0x1 << 6)
+#define RK3308_DAC_R_HPOUT_INIT			(0x0 << 6)
+#define RK3308_DAC_R_HPOUT_EN			(0x1 << 5)
+#define RK3308_DAC_R_HPOUT_DIS			(0x0 << 5)
+#define RK3308_DAC_R_HPOUT_UNMUTE		(0x1 << 4)
+#define RK3308_DAC_R_HPOUT_MUTE			(0x0 << 4)
+#define RK3308_DAC_L_HPOUT_WORK			(0x1 << 2)
+#define RK3308_DAC_L_HPOUT_INIT			(0x0 << 2)
+#define RK3308_DAC_L_HPOUT_EN			(0x1 << 1)
+#define RK3308_DAC_L_HPOUT_DIS			(0x0 << 1)
+#define RK3308_DAC_L_HPOUT_UNMUTE		(0x1 << 0)
+#define RK3308_DAC_L_HPOUT_MUTE			(0x0 << 0)
+
+/* RK3308_DAC_ANA_CON04 - REG: 0x0450 */
+#define RK3308_DAC_R_GAIN_SFT			6
+#define RK3308_DAC_R_GAIN_MSK			(0x3 << RK3308_DAC_R_GAIN_SFT)
+#define RK3308_DAC_R_GAIN_0DB			(0x3 << RK3308_DAC_R_GAIN_SFT)
+#define RK3308_DAC_R_GAIN_PDB_1_5		(0x2 << RK3308_DAC_R_GAIN_SFT)
+#define RK3308_DAC_R_GAIN_PDB_3			(0x1 << RK3308_DAC_R_GAIN_SFT)
+#define RK3308_DAC_R_GAIN_PDB_6			(0x0 << RK3308_DAC_R_GAIN_SFT)
+#define RK3308_DAC_R_LINEOUT_UNMUTE		(0x1 << 5)
+#define RK3308_DAC_R_LINEOUT_MUTE		(0x0 << 5)
+#define RK3308_DAC_R_LINEOUT_EN			(0x1 << 4)
+#define RK3308_DAC_R_LINEOUT_DIS		(0x0 << 4)
+#define RK3308_DAC_L_GAIN_SFT			2
+#define RK3308_DAC_L_GAIN_MSK			(0x3 << RK3308_DAC_L_GAIN_SFT)
+#define RK3308_DAC_L_GAIN_0DB			(0x3 << RK3308_DAC_L_GAIN_SFT)
+#define RK3308_DAC_L_GAIN_PDB_1_5		(0x2 << RK3308_DAC_L_GAIN_SFT)
+#define RK3308_DAC_L_GAIN_PDB_3			(0x1 << RK3308_DAC_L_GAIN_SFT)
+#define RK3308_DAC_L_GAIN_PDB_6			(0x0 << RK3308_DAC_L_GAIN_SFT)
+#define RK3308_DAC_L_LINEOUT_UNMUTE		(0x1 << 1)
+#define RK3308_DAC_L_LINEOUT_MUTE		(0x0 << 1)
+#define RK3308_DAC_L_LINEOUT_EN			(0x1 << 0)
+#define RK3308_DAC_L_LINEOUT_DIS		(0x0 << 0)
+
+/* RK3308_DAC_ANA_CON05 - REG: 0x0454, step is 1.5db */
+#define RK3308_DAC_L_HPOUT_GAIN_SFT		0
+#define RK3308_DAC_L_HPOUT_GAIN_MSK		(0x1f << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_PDB_6		(0x1e << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_PDB_4_5		(0x1d << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_PDB_3		(0x1c << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_PDB_1_5		(0x1b << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_0DB		(0x1a << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_1_5		(0x19 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_3		(0x18 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_4_5		(0x17 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_6		(0x16 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_7_5		(0x15 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_9		(0x14 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_10_5	(0x13 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_12		(0x12 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_13_5	(0x11 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_15		(0x10 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_16_5	(0x0f << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_18		(0x0e << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_19_5	(0x0d << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_21		(0x0c << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_22_5	(0x0b << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_24		(0x0a << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_25_5	(0x09 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_27		(0x08 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_28_5	(0x07 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_30		(0x06 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_31_5	(0x05 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_33		(0x04 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_34_5	(0x03 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_36		(0x02 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_37_5	(0x01 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+#define RK3308_DAC_L_HPOUT_GAIN_NDB_39		(0x00 << RK3308_DAC_L_HPOUT_GAIN_SFT)
+
+/* RK3308_DAC_ANA_CON06 - REG: 0x0458, step is 1.5db */
+#define RK3308_DAC_R_HPOUT_GAIN_SFT		0
+#define RK3308_DAC_R_HPOUT_GAIN_MSK		(0x1f << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_PDB_6		(0x1e << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_PDB_4_5		(0x1d << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_PDB_3		(0x1c << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_PDB_1_5		(0x1b << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_0DB		(0x1a << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_1_5		(0x19 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_3		(0x18 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_4_5		(0x17 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_6		(0x16 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_7_5		(0x15 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_9		(0x14 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_10_5	(0x13 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_12		(0x12 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_13_5	(0x11 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_15		(0x10 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_16_5	(0x0f << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_18		(0x0e << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_19_5	(0x0d << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_21		(0x0c << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_22_5	(0x0b << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_24		(0x0a << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_25_5	(0x09 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_27		(0x08 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_28_5	(0x07 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_30		(0x06 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_31_5	(0x05 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_33		(0x04 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_34_5	(0x03 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_36		(0x02 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_37_5	(0x01 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+#define RK3308_DAC_R_HPOUT_GAIN_NDB_39		(0x00 << RK3308_DAC_R_HPOUT_GAIN_SFT)
+
+/* RK3308_DAC_ANA_CON12 - REG: 0x0470 */
+#define RK3308_DAC_R_HPMIX_SEL_SFT		6
+#define RK3308_DAC_R_HPMIX_SEL_MSK		(0x3 << RK3308_DAC_R_HPMIX_SEL_SFT)
+#define RK3308_DAC_R_HPMIX_LINEIN_I2S		(0x3 << RK3308_DAC_R_HPMIX_SEL_SFT)
+#define RK3308_DAC_R_HPMIX_LINEIN		(0x2 << RK3308_DAC_R_HPMIX_SEL_SFT)
+#define RK3308_DAC_R_HPMIX_I2S			(0x1 << RK3308_DAC_R_HPMIX_SEL_SFT)
+#define RK3308_DAC_R_HPMIX_NONE			(0x0 << RK3308_DAC_R_HPMIX_SEL_SFT)
+#define RK3308_DAC_R_HPMIX_GAIN_SFT		4
+#define RK3308_DAC_R_HPMIX_GAIN_MSK		(0x3 << RK3308_DAC_R_HPMIX_GAIN_SFT)
+#define RK3308_DAC_R_HPMIX_GAIN_0DB		(0x2 << RK3308_DAC_R_HPMIX_GAIN_SFT)
+#define RK3308_DAC_R_HPMIX_GAIN_NDB_6		(0x1 << RK3308_DAC_R_HPMIX_GAIN_SFT)
+#define RK3308_DAC_L_HPMIX_SEL_SFT		2
+#define RK3308_DAC_L_HPMIX_SEL_MSK		(0x3 << RK3308_DAC_L_HPMIX_SEL_SFT)
+#define RK3308_DAC_L_HPMIX_LINEIN_I2S		(0x3 << RK3308_DAC_L_HPMIX_SEL_SFT)
+#define RK3308_DAC_L_HPMIX_LINEIN		(0x2 << RK3308_DAC_L_HPMIX_SEL_SFT)
+#define RK3308_DAC_L_HPMIX_I2S			(0x1 << RK3308_DAC_L_HPMIX_SEL_SFT)
+#define RK3308_DAC_L_HPMIX_NONE			(0x0 << RK3308_DAC_L_HPMIX_SEL_SFT)
+#define RK3308_DAC_L_HPMIX_GAIN_SFT		0
+#define RK3308_DAC_L_HPMIX_GAIN_MSK		(0x3 << RK3308_DAC_L_HPMIX_GAIN_SFT)
+#define RK3308_DAC_L_HPMIX_GAIN_0DB		(0x2 << RK3308_DAC_L_HPMIX_GAIN_SFT)
+#define RK3308_DAC_L_HPMIX_GAIN_NDB_6		(0x1 << RK3308_DAC_L_HPMIX_GAIN_SFT)
+
+/* RK3308_DAC_ANA_CON13 - REG: 0x0474 */
+#define RK3308_DAC_R_HPMIX_UNMUTE		(0x1 << 6)
+#define RK3308_DAC_R_HPMIX_MUTE			(0x0 << 6)
+#define RK3308_DAC_R_HPMIX_WORK			(0x1 << 5)
+#define RK3308_DAC_R_HPMIX_INIT			(0x0 << 5)
+#define RK3308_DAC_R_HPMIX_EN			(0x1 << 4)
+#define RK3308_DAC_R_HPMIX_DIS			(0x0 << 4)
+#define RK3308_DAC_L_HPMIX_UNMUTE		(0x1 << 2)
+#define RK3308_DAC_L_HPMIX_MUTE			(0x0 << 2)
+#define RK3308_DAC_L_HPMIX_WORK			(0x1 << 1)
+#define RK3308_DAC_L_HPMIX_INIT			(0x0 << 1)
+#define RK3308_DAC_L_HPMIX_EN			(0x1 << 0)
+#define RK3308_DAC_L_HPMIX_DIS			(0x0 << 0)
+
+#define RK3308_HIFI				0x0
+
+#endif /* __RK3308_CODEC_H__ */
-- 
Armbian

