summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorXing Zheng <zhengxing@rock-chips.com>2018-03-11 11:37:28 +0800
committerXing Zheng <zhengxing@rock-chips.com>2018-03-21 09:27:44 +0800
commitb9d097610177b7117a09ea74ed00476a2105f169 (patch)
tree0111cdf7693f2ff08f651b0104e45a1e8ea43d63 /sound
parent61c942ad002930dcd278c6738ffb7f9c1ca6bbfc (diff)
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>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/Kconfig5
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/rk3308_codec.c1604
-rw-r--r--sound/soc/codecs/rk3308_codec.h960
4 files changed, 2571 insertions, 0 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 30313b9f9087..b6ae5a8016c8 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -95,6 +95,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_PCM512x_SPI if SPI_MASTER
select SND_SOC_RK1000 if I2C
select SND_SOC_RK3228
+ select SND_SOC_RK3308
select SND_SOC_RK3328
select SND_SOC_RK817 if I2C
select SND_SOC_RT286 if I2C
@@ -585,6 +586,10 @@ config SND_SOC_RK3228
select REGMAP_MMIO
tristate "Rockchip RK3228 CODEC"
+config SND_SOC_RK3308
+ select REGMAP_MMIO
+ tristate "Rockchip RK3308 CODEC"
+
config SND_SOC_RK3328
select REGMAP_MMIO
tristate "Rockchip RK3328 CODEC"
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 042a9705da12..666ff31de4ff 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -93,6 +93,7 @@ snd-soc-pcm512x-spi-objs := pcm512x-spi.o
snd-soc-rk1000-objs := rk1000_codec.o
snd-soc-rk312x-objs := rk312x_codec.o
snd-soc-rk3228-objs := rk3228_codec.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
@@ -304,6 +305,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o
obj-$(CONFIG_SND_SOC_RK1000) += snd-soc-rk1000.o
obj-$(CONFIG_SND_SOC_RK312X) += snd-soc-rk312x.o
obj-$(CONFIG_SND_SOC_RK3228) += snd-soc-rk3228.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__ */