Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: codecs: Add RK3308 internal audio codec driver

Add driver for the internal audio codec of the Rockchip RK3308 SoC.

Initially based on the vendor kernel driver [0], with lots of cleanups,
fixes, improvements, conversion to DAPM and removal of some features.

[0] https://github.com/rockchip-linux/kernel/blob/develop-4.19/sound/soc/codecs/rk3308_codec.c

Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Link: https://msgid.link/r/20240305-rk3308-audio-codec-v4-4-312acdbe628f@bootlin.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Luca Ceresoli and committed by
Mark Brown
4ed0915f d75a2161

+1568
+2
MAINTAINERS
··· 19050 19050 M: Luca Ceresoli <luca.ceresoli@bootlin.com> 19051 19051 S: Maintained 19052 19052 F: Documentation/devicetree/bindings/sound/rockchip,rk3308-codec.yaml 19053 + F: sound/soc/codecs/rk3308_codec.c 19054 + F: sound/soc/codecs/rk3308_codec.h 19053 19055 19054 19056 ROCKCHIP VIDEO DECODER DRIVER 19055 19057 M: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
+11
sound/soc/codecs/Kconfig
··· 180 180 imply SND_SOC_PCM512x_I2C 181 181 imply SND_SOC_PCM512x_SPI 182 182 imply SND_SOC_PEB2466 183 + imply SND_SOC_RK3308 183 184 imply SND_SOC_RK3328 184 185 imply SND_SOC_RK817 185 186 imply SND_SOC_RT274 ··· 1433 1432 1434 1433 To compile this driver as a module, choose M here: the module 1435 1434 will be called snd-soc-peb2466. 1435 + 1436 + config SND_SOC_RK3308 1437 + tristate "Rockchip RK3308 audio CODEC" 1438 + select REGMAP_MMIO 1439 + help 1440 + This is a device driver for the audio codec embedded in the 1441 + Rockchip RK3308 SoC. 1442 + 1443 + It has 8 24-bit ADCs and 2 24-bit DACs. The maximum supported 1444 + sampling rate is 192 kHz. 1436 1445 1437 1446 config SND_SOC_RK3328 1438 1447 tristate "Rockchip RK3328 audio CODEC"
+2
sound/soc/codecs/Makefile
··· 205 205 snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o 206 206 snd-soc-pcm512x-spi-objs := pcm512x-spi.o 207 207 snd-soc-peb2466-objs := peb2466.o 208 + snd-soc-rk3308-objs := rk3308_codec.o 208 209 snd-soc-rk3328-objs := rk3328_codec.o 209 210 snd-soc-rk817-objs := rk817_codec.o 210 211 snd-soc-rl6231-objs := rl6231.o ··· 596 595 obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o 597 596 obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o 598 597 obj-$(CONFIG_SND_SOC_PEB2466) += snd-soc-peb2466.o 598 + obj-$(CONFIG_SND_SOC_RK3308) += snd-soc-rk3308.o 599 599 obj-$(CONFIG_SND_SOC_RK3328) += snd-soc-rk3328.o 600 600 obj-$(CONFIG_SND_SOC_RK817) += snd-soc-rk817.o 601 601 obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o
+974
sound/soc/codecs/rk3308_codec.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Rockchip RK3308 internal audio codec driver 4 + * 5 + * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd All rights reserved. 6 + * Copyright (c) 2024, Vivax-Metrotech Ltd 7 + */ 8 + 9 + #include <linux/clk.h> 10 + #include <linux/device.h> 11 + #include <linux/delay.h> 12 + #include <linux/init.h> 13 + #include <linux/io.h> 14 + #include <linux/mfd/syscon.h> 15 + #include <linux/module.h> 16 + #include <linux/of.h> 17 + #include <linux/platform_device.h> 18 + #include <linux/regmap.h> 19 + #include <linux/reset.h> 20 + #include <linux/util_macros.h> 21 + #include <sound/core.h> 22 + #include <sound/pcm.h> 23 + #include <sound/pcm_params.h> 24 + #include <sound/soc.h> 25 + #include <sound/tlv.h> 26 + 27 + #include "rk3308_codec.h" 28 + 29 + #define ADC_LR_GROUP_MAX 4 30 + 31 + #define GRF_CHIP_ID 0x800 32 + 33 + enum { 34 + ACODEC_VERSION_A = 'A', 35 + ACODEC_VERSION_B, 36 + ACODEC_VERSION_C, 37 + }; 38 + 39 + struct rk3308_codec_priv { 40 + const struct device *dev; 41 + struct regmap *regmap; 42 + struct regmap *grf; 43 + struct reset_control *reset; 44 + struct clk *hclk; 45 + struct clk *mclk_rx; 46 + struct clk *mclk_tx; 47 + struct snd_soc_component *component; 48 + unsigned char codec_ver; 49 + }; 50 + 51 + static struct clk_bulk_data rk3308_codec_clocks[] = { 52 + { .id = "hclk" }, 53 + { .id = "mclk_rx" }, 54 + { .id = "mclk_tx" }, 55 + }; 56 + 57 + static const DECLARE_TLV_DB_SCALE(rk3308_codec_adc_alc_gain_tlv, -1800, 150, 0); 58 + static const DECLARE_TLV_DB_SCALE(rk3308_codec_dac_hpout_gain_tlv, -3900, 150, 0); 59 + static const DECLARE_TLV_DB_SCALE(rk3308_codec_dac_hpmix_gain_tlv, -600, 600, 0); 60 + 61 + static const DECLARE_TLV_DB_RANGE(rk3308_codec_dac_lineout_gain_tlv, 62 + 0, 0, TLV_DB_SCALE_ITEM(-600, 0, 0), 63 + 1, 1, TLV_DB_SCALE_ITEM(-300, 0, 0), 64 + 2, 2, TLV_DB_SCALE_ITEM(-150, 0, 0), 65 + 3, 3, TLV_DB_SCALE_ITEM(0, 0, 0), 66 + ); 67 + 68 + static const char * const rk3308_codec_hpf_cutoff_text[] = { 69 + "20 Hz", "245 Hz", "612 Hz" 70 + }; 71 + 72 + static SOC_ENUM_SINGLE_DECL(rk3308_codec_hpf_cutoff_enum12, RK3308_ADC_DIG_CON04(0), 0, 73 + rk3308_codec_hpf_cutoff_text); 74 + static SOC_ENUM_SINGLE_DECL(rk3308_codec_hpf_cutoff_enum34, RK3308_ADC_DIG_CON04(1), 0, 75 + rk3308_codec_hpf_cutoff_text); 76 + static SOC_ENUM_SINGLE_DECL(rk3308_codec_hpf_cutoff_enum56, RK3308_ADC_DIG_CON04(2), 0, 77 + rk3308_codec_hpf_cutoff_text); 78 + static SOC_ENUM_SINGLE_DECL(rk3308_codec_hpf_cutoff_enum78, RK3308_ADC_DIG_CON04(3), 0, 79 + rk3308_codec_hpf_cutoff_text); 80 + 81 + static const struct snd_kcontrol_new rk3308_codec_controls[] = { 82 + /* Despite the register names, these set the gain when AGC is OFF */ 83 + SOC_SINGLE_RANGE_TLV("MIC1 Capture Volume", 84 + RK3308_ADC_ANA_CON03(0), 85 + RK3308_ADC_CH1_ALC_GAIN_SFT, 86 + RK3308_ADC_CH1_ALC_GAIN_MIN, 87 + RK3308_ADC_CH1_ALC_GAIN_MAX, 88 + 0, rk3308_codec_adc_alc_gain_tlv), 89 + SOC_SINGLE_RANGE_TLV("MIC2 Capture Volume", 90 + RK3308_ADC_ANA_CON04(0), 91 + RK3308_ADC_CH2_ALC_GAIN_SFT, 92 + RK3308_ADC_CH2_ALC_GAIN_MIN, 93 + RK3308_ADC_CH2_ALC_GAIN_MAX, 94 + 0, rk3308_codec_adc_alc_gain_tlv), 95 + SOC_SINGLE_RANGE_TLV("MIC3 Capture Volume", 96 + RK3308_ADC_ANA_CON03(1), 97 + RK3308_ADC_CH1_ALC_GAIN_SFT, 98 + RK3308_ADC_CH1_ALC_GAIN_MIN, 99 + RK3308_ADC_CH1_ALC_GAIN_MAX, 100 + 0, rk3308_codec_adc_alc_gain_tlv), 101 + SOC_SINGLE_RANGE_TLV("MIC4 Capture Volume", 102 + RK3308_ADC_ANA_CON04(1), 103 + RK3308_ADC_CH2_ALC_GAIN_SFT, 104 + RK3308_ADC_CH2_ALC_GAIN_MIN, 105 + RK3308_ADC_CH2_ALC_GAIN_MAX, 106 + 0, rk3308_codec_adc_alc_gain_tlv), 107 + SOC_SINGLE_RANGE_TLV("MIC5 Capture Volume", 108 + RK3308_ADC_ANA_CON03(2), 109 + RK3308_ADC_CH1_ALC_GAIN_SFT, 110 + RK3308_ADC_CH1_ALC_GAIN_MIN, 111 + RK3308_ADC_CH1_ALC_GAIN_MAX, 112 + 0, rk3308_codec_adc_alc_gain_tlv), 113 + SOC_SINGLE_RANGE_TLV("MIC6 Capture Volume", 114 + RK3308_ADC_ANA_CON04(2), 115 + RK3308_ADC_CH2_ALC_GAIN_SFT, 116 + RK3308_ADC_CH2_ALC_GAIN_MIN, 117 + RK3308_ADC_CH2_ALC_GAIN_MAX, 118 + 0, rk3308_codec_adc_alc_gain_tlv), 119 + SOC_SINGLE_RANGE_TLV("MIC7 Capture Volume", 120 + RK3308_ADC_ANA_CON03(3), 121 + RK3308_ADC_CH1_ALC_GAIN_SFT, 122 + RK3308_ADC_CH1_ALC_GAIN_MIN, 123 + RK3308_ADC_CH1_ALC_GAIN_MAX, 124 + 0, rk3308_codec_adc_alc_gain_tlv), 125 + SOC_SINGLE_RANGE_TLV("MIC8 Capture Volume", 126 + RK3308_ADC_ANA_CON04(3), 127 + RK3308_ADC_CH2_ALC_GAIN_SFT, 128 + RK3308_ADC_CH2_ALC_GAIN_MIN, 129 + RK3308_ADC_CH2_ALC_GAIN_MAX, 130 + 0, rk3308_codec_adc_alc_gain_tlv), 131 + 132 + SOC_SINGLE("MIC1 Capture Switch", RK3308_ADC_ANA_CON00(0), 3, 1, 0), 133 + SOC_SINGLE("MIC2 Capture Switch", RK3308_ADC_ANA_CON00(0), 7, 1, 0), 134 + SOC_SINGLE("MIC3 Capture Switch", RK3308_ADC_ANA_CON00(1), 3, 1, 0), 135 + SOC_SINGLE("MIC4 Capture Switch", RK3308_ADC_ANA_CON00(1), 7, 1, 0), 136 + SOC_SINGLE("MIC5 Capture Switch", RK3308_ADC_ANA_CON00(2), 3, 1, 0), 137 + SOC_SINGLE("MIC6 Capture Switch", RK3308_ADC_ANA_CON00(2), 7, 1, 0), 138 + SOC_SINGLE("MIC7 Capture Switch", RK3308_ADC_ANA_CON00(3), 3, 1, 0), 139 + SOC_SINGLE("MIC8 Capture Switch", RK3308_ADC_ANA_CON00(3), 7, 1, 0), 140 + 141 + SOC_SINGLE("MIC12 HPF Capture Switch", RK3308_ADC_DIG_CON04(0), 2, 1, 1), 142 + SOC_SINGLE("MIC34 HPF Capture Switch", RK3308_ADC_DIG_CON04(1), 2, 1, 1), 143 + SOC_SINGLE("MIC56 HPF Capture Switch", RK3308_ADC_DIG_CON04(2), 2, 1, 1), 144 + SOC_SINGLE("MIC78 HPF Capture Switch", RK3308_ADC_DIG_CON04(3), 2, 1, 1), 145 + 146 + SOC_ENUM("MIC12 HPF Cutoff", rk3308_codec_hpf_cutoff_enum12), 147 + SOC_ENUM("MIC34 HPF Cutoff", rk3308_codec_hpf_cutoff_enum34), 148 + SOC_ENUM("MIC56 HPF Cutoff", rk3308_codec_hpf_cutoff_enum56), 149 + SOC_ENUM("MIC78 HPF Cutoff", rk3308_codec_hpf_cutoff_enum78), 150 + 151 + SOC_DOUBLE_TLV("Line Out Playback Volume", 152 + RK3308_DAC_ANA_CON04, 153 + RK3308_DAC_L_LINEOUT_GAIN_SFT, 154 + RK3308_DAC_R_LINEOUT_GAIN_SFT, 155 + RK3308_DAC_x_LINEOUT_GAIN_MAX, 156 + 0, rk3308_codec_dac_lineout_gain_tlv), 157 + SOC_DOUBLE("Line Out Playback Switch", 158 + RK3308_DAC_ANA_CON04, 159 + RK3308_DAC_L_LINEOUT_MUTE_SFT, 160 + RK3308_DAC_R_LINEOUT_MUTE_SFT, 1, 0), 161 + SOC_DOUBLE_R_TLV("Headphone Playback Volume", 162 + RK3308_DAC_ANA_CON05, 163 + RK3308_DAC_ANA_CON06, 164 + RK3308_DAC_x_HPOUT_GAIN_SFT, 165 + RK3308_DAC_x_HPOUT_GAIN_MAX, 166 + 0, rk3308_codec_dac_hpout_gain_tlv), 167 + SOC_DOUBLE("Headphone Playback Switch", 168 + RK3308_DAC_ANA_CON03, 169 + RK3308_DAC_L_HPOUT_MUTE_SFT, 170 + RK3308_DAC_R_HPOUT_MUTE_SFT, 1, 0), 171 + SOC_DOUBLE_RANGE_TLV("DAC HPMIX Playback Volume", 172 + RK3308_DAC_ANA_CON12, 173 + RK3308_DAC_L_HPMIX_GAIN_SFT, 174 + RK3308_DAC_R_HPMIX_GAIN_SFT, 175 + 1, 2, 0, rk3308_codec_dac_hpmix_gain_tlv), 176 + }; 177 + 178 + static int rk3308_codec_pop_sound_set(struct snd_soc_dapm_widget *w, 179 + struct snd_kcontrol *kcontrol, 180 + int event) 181 + { 182 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 183 + struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); 184 + unsigned int val = (event == SND_SOC_DAPM_POST_PMU) ? 185 + RK3308_DAC_HPOUT_POP_SOUND_x_WORK : 186 + RK3308_DAC_HPOUT_POP_SOUND_x_INIT; 187 + unsigned int mask = RK3308_DAC_HPOUT_POP_SOUND_x_MSK; 188 + 189 + regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, 190 + mask << w->shift, val << w->shift); 191 + 192 + return 0; 193 + } 194 + 195 + static const struct snd_soc_dapm_widget rk3308_codec_dapm_widgets[] = { 196 + SND_SOC_DAPM_INPUT("MIC1"), 197 + SND_SOC_DAPM_INPUT("MIC2"), 198 + SND_SOC_DAPM_INPUT("MIC3"), 199 + SND_SOC_DAPM_INPUT("MIC4"), 200 + SND_SOC_DAPM_INPUT("MIC5"), 201 + SND_SOC_DAPM_INPUT("MIC6"), 202 + SND_SOC_DAPM_INPUT("MIC7"), 203 + SND_SOC_DAPM_INPUT("MIC8"), 204 + 205 + SND_SOC_DAPM_SUPPLY("ADC_CURRENT_EN12", RK3308_ADC_ANA_CON06(0), 0, 0, NULL, 0), 206 + SND_SOC_DAPM_SUPPLY("ADC_CURRENT_EN34", RK3308_ADC_ANA_CON06(1), 0, 0, NULL, 0), 207 + SND_SOC_DAPM_SUPPLY("ADC_CURRENT_EN56", RK3308_ADC_ANA_CON06(2), 0, 0, NULL, 0), 208 + SND_SOC_DAPM_SUPPLY("ADC_CURRENT_EN78", RK3308_ADC_ANA_CON06(3), 0, 0, NULL, 0), 209 + 210 + SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC1_EN", RK3308_ADC_ANA_CON00(0), 1, 1, 1, 0), 211 + SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC2_EN", RK3308_ADC_ANA_CON00(0), 5, 1, 1, 0), 212 + SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC3_EN", RK3308_ADC_ANA_CON00(1), 1, 1, 1, 0), 213 + SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC4_EN", RK3308_ADC_ANA_CON00(1), 5, 1, 1, 0), 214 + SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC5_EN", RK3308_ADC_ANA_CON00(2), 1, 1, 1, 0), 215 + SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC6_EN", RK3308_ADC_ANA_CON00(2), 5, 1, 1, 0), 216 + SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC7_EN", RK3308_ADC_ANA_CON00(3), 1, 1, 1, 0), 217 + SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC8_EN", RK3308_ADC_ANA_CON00(3), 5, 1, 1, 0), 218 + 219 + SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC1_WORK", RK3308_ADC_ANA_CON00(0), 2, 1, 1, 0), 220 + SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC2_WORK", RK3308_ADC_ANA_CON00(0), 6, 1, 1, 0), 221 + SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC3_WORK", RK3308_ADC_ANA_CON00(1), 2, 1, 1, 0), 222 + SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC4_WORK", RK3308_ADC_ANA_CON00(1), 6, 1, 1, 0), 223 + SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC5_WORK", RK3308_ADC_ANA_CON00(2), 2, 1, 1, 0), 224 + SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC6_WORK", RK3308_ADC_ANA_CON00(2), 6, 1, 1, 0), 225 + SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC7_WORK", RK3308_ADC_ANA_CON00(3), 2, 1, 1, 0), 226 + SND_SOC_DAPM_REG(snd_soc_dapm_mic, "MIC8_WORK", RK3308_ADC_ANA_CON00(3), 6, 1, 1, 0), 227 + 228 + /* 229 + * In theory MIC1 and MIC2 can switch to LINE IN, but this is not 230 + * supported so all we can do is enabling the MIC input. 231 + */ 232 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "CH1_IN_SEL", RK3308_ADC_ANA_CON07(0), 4, 1, 1, 0), 233 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "CH2_IN_SEL", RK3308_ADC_ANA_CON07(0), 6, 1, 1, 0), 234 + 235 + SND_SOC_DAPM_SUPPLY("ADC1_BUF_REF_EN", RK3308_ADC_ANA_CON00(0), 0, 0, NULL, 0), 236 + SND_SOC_DAPM_SUPPLY("ADC2_BUF_REF_EN", RK3308_ADC_ANA_CON00(0), 4, 0, NULL, 0), 237 + SND_SOC_DAPM_SUPPLY("ADC3_BUF_REF_EN", RK3308_ADC_ANA_CON00(1), 0, 0, NULL, 0), 238 + SND_SOC_DAPM_SUPPLY("ADC4_BUF_REF_EN", RK3308_ADC_ANA_CON00(1), 4, 0, NULL, 0), 239 + SND_SOC_DAPM_SUPPLY("ADC5_BUF_REF_EN", RK3308_ADC_ANA_CON00(2), 0, 0, NULL, 0), 240 + SND_SOC_DAPM_SUPPLY("ADC6_BUF_REF_EN", RK3308_ADC_ANA_CON00(2), 4, 0, NULL, 0), 241 + SND_SOC_DAPM_SUPPLY("ADC7_BUF_REF_EN", RK3308_ADC_ANA_CON00(3), 0, 0, NULL, 0), 242 + SND_SOC_DAPM_SUPPLY("ADC8_BUF_REF_EN", RK3308_ADC_ANA_CON00(3), 4, 0, NULL, 0), 243 + 244 + SND_SOC_DAPM_SUPPLY("ADC_MCLK_GATE", RK3308_GLB_CON, 5, 1, NULL, 0), 245 + 246 + SND_SOC_DAPM_SUPPLY("ADC1_CLK_EN", RK3308_ADC_ANA_CON05(0), 0, 0, NULL, 0), 247 + SND_SOC_DAPM_SUPPLY("ADC2_CLK_EN", RK3308_ADC_ANA_CON05(0), 4, 0, NULL, 0), 248 + SND_SOC_DAPM_SUPPLY("ADC3_CLK_EN", RK3308_ADC_ANA_CON05(1), 0, 0, NULL, 0), 249 + SND_SOC_DAPM_SUPPLY("ADC4_CLK_EN", RK3308_ADC_ANA_CON05(1), 4, 0, NULL, 0), 250 + SND_SOC_DAPM_SUPPLY("ADC5_CLK_EN", RK3308_ADC_ANA_CON05(2), 0, 0, NULL, 0), 251 + SND_SOC_DAPM_SUPPLY("ADC6_CLK_EN", RK3308_ADC_ANA_CON05(2), 4, 0, NULL, 0), 252 + SND_SOC_DAPM_SUPPLY("ADC7_CLK_EN", RK3308_ADC_ANA_CON05(3), 0, 0, NULL, 0), 253 + SND_SOC_DAPM_SUPPLY("ADC8_CLK_EN", RK3308_ADC_ANA_CON05(3), 4, 0, NULL, 0), 254 + 255 + /* The "ALC" name from the TRM is misleading, these are needed even without ALC/AGC */ 256 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC1_EN", RK3308_ADC_ANA_CON02(0), 0, 1, 1, 0), 257 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC2_EN", RK3308_ADC_ANA_CON02(0), 4, 1, 1, 0), 258 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC3_EN", RK3308_ADC_ANA_CON02(1), 0, 1, 1, 0), 259 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC4_EN", RK3308_ADC_ANA_CON02(1), 4, 1, 1, 0), 260 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC5_EN", RK3308_ADC_ANA_CON02(2), 0, 1, 1, 0), 261 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC6_EN", RK3308_ADC_ANA_CON02(2), 4, 1, 1, 0), 262 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC7_EN", RK3308_ADC_ANA_CON02(3), 0, 1, 1, 0), 263 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC8_EN", RK3308_ADC_ANA_CON02(3), 4, 1, 1, 0), 264 + 265 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC1_EN", RK3308_ADC_ANA_CON05(0), 1, 1, 1, 0), 266 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC2_EN", RK3308_ADC_ANA_CON05(0), 5, 1, 1, 0), 267 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC3_EN", RK3308_ADC_ANA_CON05(1), 1, 1, 1, 0), 268 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC4_EN", RK3308_ADC_ANA_CON05(1), 5, 1, 1, 0), 269 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC5_EN", RK3308_ADC_ANA_CON05(2), 1, 1, 1, 0), 270 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC6_EN", RK3308_ADC_ANA_CON05(2), 5, 1, 1, 0), 271 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC7_EN", RK3308_ADC_ANA_CON05(3), 1, 1, 1, 0), 272 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC8_EN", RK3308_ADC_ANA_CON05(3), 5, 1, 1, 0), 273 + 274 + SND_SOC_DAPM_ADC("ADC1_WORK", "Capture", RK3308_ADC_ANA_CON05(0), 2, 0), 275 + SND_SOC_DAPM_ADC("ADC2_WORK", "Capture", RK3308_ADC_ANA_CON05(0), 6, 0), 276 + SND_SOC_DAPM_ADC("ADC3_WORK", "Capture", RK3308_ADC_ANA_CON05(1), 2, 0), 277 + SND_SOC_DAPM_ADC("ADC4_WORK", "Capture", RK3308_ADC_ANA_CON05(1), 6, 0), 278 + SND_SOC_DAPM_ADC("ADC5_WORK", "Capture", RK3308_ADC_ANA_CON05(2), 2, 0), 279 + SND_SOC_DAPM_ADC("ADC6_WORK", "Capture", RK3308_ADC_ANA_CON05(2), 6, 0), 280 + SND_SOC_DAPM_ADC("ADC7_WORK", "Capture", RK3308_ADC_ANA_CON05(3), 2, 0), 281 + SND_SOC_DAPM_ADC("ADC8_WORK", "Capture", RK3308_ADC_ANA_CON05(3), 6, 0), 282 + 283 + /* The "ALC" name from the TRM is misleading, these are needed even without ALC/AGC */ 284 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC1_WORK", RK3308_ADC_ANA_CON02(0), 1, 1, 1, 0), 285 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC2_WORK", RK3308_ADC_ANA_CON02(0), 5, 1, 1, 0), 286 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC3_WORK", RK3308_ADC_ANA_CON02(1), 1, 1, 1, 0), 287 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC4_WORK", RK3308_ADC_ANA_CON02(1), 5, 1, 1, 0), 288 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC5_WORK", RK3308_ADC_ANA_CON02(2), 1, 1, 1, 0), 289 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC6_WORK", RK3308_ADC_ANA_CON02(2), 5, 1, 1, 0), 290 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC7_WORK", RK3308_ADC_ANA_CON02(3), 1, 1, 1, 0), 291 + SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ALC8_WORK", RK3308_ADC_ANA_CON02(3), 5, 1, 1, 0), 292 + 293 + SND_SOC_DAPM_SUPPLY("MICBIAS Current", RK3308_ADC_ANA_CON08(0), 4, 0, NULL, 0), 294 + SND_SOC_DAPM_SUPPLY("MICBIAS1", RK3308_ADC_ANA_CON07(1), 3, 0, NULL, 0), 295 + SND_SOC_DAPM_SUPPLY("MICBIAS2", RK3308_ADC_ANA_CON07(2), 3, 0, NULL, 0), 296 + 297 + SND_SOC_DAPM_OUT_DRV("DAC_L_HPMIX_EN", RK3308_DAC_ANA_CON13, 0, 0, NULL, 0), 298 + SND_SOC_DAPM_OUT_DRV("DAC_R_HPMIX_EN", RK3308_DAC_ANA_CON13, 4, 0, NULL, 0), 299 + SND_SOC_DAPM_OUT_DRV("DAC_L_HPMIX_WORK", RK3308_DAC_ANA_CON13, 1, 0, NULL, 0), 300 + SND_SOC_DAPM_OUT_DRV("DAC_R_HPMIX_WORK", RK3308_DAC_ANA_CON13, 5, 0, NULL, 0), 301 + /* HPMIX is not actually acting as a mixer as the only supported input is I2S */ 302 + SND_SOC_DAPM_OUT_DRV("DAC_L_HPMIX_SEL", RK3308_DAC_ANA_CON12, 2, 0, NULL, 0), 303 + SND_SOC_DAPM_OUT_DRV("DAC_R_HPMIX_SEL", RK3308_DAC_ANA_CON12, 6, 0, NULL, 0), 304 + SND_SOC_DAPM_MIXER("DAC HPMIX Left", RK3308_DAC_ANA_CON13, 2, 0, NULL, 0), 305 + SND_SOC_DAPM_MIXER("DAC HPMIX Right", RK3308_DAC_ANA_CON13, 6, 0, NULL, 0), 306 + 307 + SND_SOC_DAPM_SUPPLY("DAC_MCLK_GATE", RK3308_GLB_CON, 4, 1, NULL, 0), 308 + 309 + SND_SOC_DAPM_SUPPLY("DAC_CURRENT_EN", RK3308_DAC_ANA_CON00, 0, 0, NULL, 0), 310 + SND_SOC_DAPM_SUPPLY("DAC_L_REF_EN", RK3308_DAC_ANA_CON02, 0, 0, NULL, 0), 311 + SND_SOC_DAPM_SUPPLY("DAC_R_REF_EN", RK3308_DAC_ANA_CON02, 4, 0, NULL, 0), 312 + SND_SOC_DAPM_SUPPLY("DAC_L_CLK_EN", RK3308_DAC_ANA_CON02, 1, 0, NULL, 0), 313 + SND_SOC_DAPM_SUPPLY("DAC_R_CLK_EN", RK3308_DAC_ANA_CON02, 5, 0, NULL, 0), 314 + SND_SOC_DAPM_DAC("DAC_L_DAC_WORK", NULL, RK3308_DAC_ANA_CON02, 3, 0), 315 + SND_SOC_DAPM_DAC("DAC_R_DAC_WORK", NULL, RK3308_DAC_ANA_CON02, 7, 0), 316 + 317 + SND_SOC_DAPM_SUPPLY("DAC_BUF_REF_L", RK3308_DAC_ANA_CON01, 2, 0, NULL, 0), 318 + SND_SOC_DAPM_SUPPLY("DAC_BUF_REF_R", RK3308_DAC_ANA_CON01, 6, 0, NULL, 0), 319 + SND_SOC_DAPM_OUT_DRV_E("HPOUT_POP_SOUND_L", SND_SOC_NOPM, 0, 0, NULL, 0, 320 + rk3308_codec_pop_sound_set, 321 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 322 + SND_SOC_DAPM_OUT_DRV_E("HPOUT_POP_SOUND_R", SND_SOC_NOPM, 4, 0, NULL, 0, 323 + rk3308_codec_pop_sound_set, 324 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 325 + SND_SOC_DAPM_OUT_DRV("L_HPOUT_EN", RK3308_DAC_ANA_CON03, 1, 0, NULL, 0), 326 + SND_SOC_DAPM_OUT_DRV("R_HPOUT_EN", RK3308_DAC_ANA_CON03, 5, 0, NULL, 0), 327 + SND_SOC_DAPM_OUT_DRV("L_HPOUT_WORK", RK3308_DAC_ANA_CON03, 2, 0, NULL, 0), 328 + SND_SOC_DAPM_OUT_DRV("R_HPOUT_WORK", RK3308_DAC_ANA_CON03, 6, 0, NULL, 0), 329 + SND_SOC_DAPM_OUTPUT("HPOUT_L"), 330 + SND_SOC_DAPM_OUTPUT("HPOUT_R"), 331 + 332 + SND_SOC_DAPM_OUT_DRV("L_LINEOUT_EN", RK3308_DAC_ANA_CON04, 0, 0, NULL, 0), 333 + SND_SOC_DAPM_OUT_DRV("R_LINEOUT_EN", RK3308_DAC_ANA_CON04, 4, 0, NULL, 0), 334 + SND_SOC_DAPM_OUTPUT("LINEOUT_L"), 335 + SND_SOC_DAPM_OUTPUT("LINEOUT_R"), 336 + }; 337 + 338 + static const struct snd_soc_dapm_route rk3308_codec_dapm_routes[] = { 339 + { "MICBIAS1", NULL, "MICBIAS Current" }, 340 + { "MICBIAS2", NULL, "MICBIAS Current" }, 341 + 342 + { "MIC1_EN", NULL, "MIC1" }, 343 + { "MIC2_EN", NULL, "MIC2" }, 344 + { "MIC3_EN", NULL, "MIC3" }, 345 + { "MIC4_EN", NULL, "MIC4" }, 346 + { "MIC5_EN", NULL, "MIC5" }, 347 + { "MIC6_EN", NULL, "MIC6" }, 348 + { "MIC7_EN", NULL, "MIC7" }, 349 + { "MIC8_EN", NULL, "MIC8" }, 350 + 351 + { "MIC1_WORK", NULL, "MIC1_EN" }, 352 + { "MIC2_WORK", NULL, "MIC2_EN" }, 353 + { "MIC3_WORK", NULL, "MIC3_EN" }, 354 + { "MIC4_WORK", NULL, "MIC4_EN" }, 355 + { "MIC5_WORK", NULL, "MIC5_EN" }, 356 + { "MIC6_WORK", NULL, "MIC6_EN" }, 357 + { "MIC7_WORK", NULL, "MIC7_EN" }, 358 + { "MIC8_WORK", NULL, "MIC8_EN" }, 359 + 360 + { "CH1_IN_SEL", NULL, "MIC1_WORK" }, 361 + { "CH2_IN_SEL", NULL, "MIC2_WORK" }, 362 + 363 + { "ALC1_EN", NULL, "CH1_IN_SEL" }, 364 + { "ALC2_EN", NULL, "CH2_IN_SEL" }, 365 + { "ALC3_EN", NULL, "MIC3_WORK" }, 366 + { "ALC4_EN", NULL, "MIC4_WORK" }, 367 + { "ALC5_EN", NULL, "MIC5_WORK" }, 368 + { "ALC6_EN", NULL, "MIC6_WORK" }, 369 + { "ALC7_EN", NULL, "MIC7_WORK" }, 370 + { "ALC8_EN", NULL, "MIC8_WORK" }, 371 + 372 + { "ADC1_EN", NULL, "ALC1_EN" }, 373 + { "ADC2_EN", NULL, "ALC2_EN" }, 374 + { "ADC3_EN", NULL, "ALC3_EN" }, 375 + { "ADC4_EN", NULL, "ALC4_EN" }, 376 + { "ADC5_EN", NULL, "ALC5_EN" }, 377 + { "ADC6_EN", NULL, "ALC6_EN" }, 378 + { "ADC7_EN", NULL, "ALC7_EN" }, 379 + { "ADC8_EN", NULL, "ALC8_EN" }, 380 + 381 + { "ADC1_WORK", NULL, "ADC1_EN" }, 382 + { "ADC2_WORK", NULL, "ADC2_EN" }, 383 + { "ADC3_WORK", NULL, "ADC3_EN" }, 384 + { "ADC4_WORK", NULL, "ADC4_EN" }, 385 + { "ADC5_WORK", NULL, "ADC5_EN" }, 386 + { "ADC6_WORK", NULL, "ADC6_EN" }, 387 + { "ADC7_WORK", NULL, "ADC7_EN" }, 388 + { "ADC8_WORK", NULL, "ADC8_EN" }, 389 + 390 + { "ADC1_BUF_REF_EN", NULL, "ADC_CURRENT_EN12" }, 391 + { "ADC2_BUF_REF_EN", NULL, "ADC_CURRENT_EN12" }, 392 + { "ADC3_BUF_REF_EN", NULL, "ADC_CURRENT_EN34" }, 393 + { "ADC4_BUF_REF_EN", NULL, "ADC_CURRENT_EN34" }, 394 + { "ADC5_BUF_REF_EN", NULL, "ADC_CURRENT_EN56" }, 395 + { "ADC6_BUF_REF_EN", NULL, "ADC_CURRENT_EN56" }, 396 + { "ADC7_BUF_REF_EN", NULL, "ADC_CURRENT_EN78" }, 397 + { "ADC8_BUF_REF_EN", NULL, "ADC_CURRENT_EN78" }, 398 + 399 + { "ADC1_WORK", NULL, "ADC1_BUF_REF_EN" }, 400 + { "ADC2_WORK", NULL, "ADC2_BUF_REF_EN" }, 401 + { "ADC3_WORK", NULL, "ADC3_BUF_REF_EN" }, 402 + { "ADC4_WORK", NULL, "ADC4_BUF_REF_EN" }, 403 + { "ADC5_WORK", NULL, "ADC5_BUF_REF_EN" }, 404 + { "ADC6_WORK", NULL, "ADC6_BUF_REF_EN" }, 405 + { "ADC7_WORK", NULL, "ADC7_BUF_REF_EN" }, 406 + { "ADC8_WORK", NULL, "ADC8_BUF_REF_EN" }, 407 + 408 + { "ADC1_CLK_EN", NULL, "ADC_MCLK_GATE" }, 409 + { "ADC2_CLK_EN", NULL, "ADC_MCLK_GATE" }, 410 + { "ADC3_CLK_EN", NULL, "ADC_MCLK_GATE" }, 411 + { "ADC4_CLK_EN", NULL, "ADC_MCLK_GATE" }, 412 + { "ADC5_CLK_EN", NULL, "ADC_MCLK_GATE" }, 413 + { "ADC6_CLK_EN", NULL, "ADC_MCLK_GATE" }, 414 + { "ADC7_CLK_EN", NULL, "ADC_MCLK_GATE" }, 415 + { "ADC8_CLK_EN", NULL, "ADC_MCLK_GATE" }, 416 + 417 + { "ADC1_WORK", NULL, "ADC1_CLK_EN" }, 418 + { "ADC2_WORK", NULL, "ADC2_CLK_EN" }, 419 + { "ADC3_WORK", NULL, "ADC3_CLK_EN" }, 420 + { "ADC4_WORK", NULL, "ADC4_CLK_EN" }, 421 + { "ADC5_WORK", NULL, "ADC5_CLK_EN" }, 422 + { "ADC6_WORK", NULL, "ADC6_CLK_EN" }, 423 + { "ADC7_WORK", NULL, "ADC7_CLK_EN" }, 424 + { "ADC8_WORK", NULL, "ADC8_CLK_EN" }, 425 + 426 + { "ALC1_WORK", NULL, "ADC1_WORK" }, 427 + { "ALC2_WORK", NULL, "ADC2_WORK" }, 428 + { "ALC3_WORK", NULL, "ADC3_WORK" }, 429 + { "ALC4_WORK", NULL, "ADC4_WORK" }, 430 + { "ALC5_WORK", NULL, "ADC5_WORK" }, 431 + { "ALC6_WORK", NULL, "ADC6_WORK" }, 432 + { "ALC7_WORK", NULL, "ADC7_WORK" }, 433 + { "ALC8_WORK", NULL, "ADC8_WORK" }, 434 + 435 + { "HiFi Capture", NULL, "ALC1_WORK" }, 436 + { "HiFi Capture", NULL, "ALC2_WORK" }, 437 + { "HiFi Capture", NULL, "ALC3_WORK" }, 438 + { "HiFi Capture", NULL, "ALC4_WORK" }, 439 + { "HiFi Capture", NULL, "ALC5_WORK" }, 440 + { "HiFi Capture", NULL, "ALC6_WORK" }, 441 + { "HiFi Capture", NULL, "ALC7_WORK" }, 442 + { "HiFi Capture", NULL, "ALC8_WORK" }, 443 + 444 + { "DAC_L_HPMIX_EN", NULL, "HiFi Playback" }, 445 + { "DAC_R_HPMIX_EN", NULL, "HiFi Playback" }, 446 + { "DAC_L_HPMIX_WORK", NULL, "DAC_L_HPMIX_EN" }, 447 + { "DAC_R_HPMIX_WORK", NULL, "DAC_R_HPMIX_EN" }, 448 + { "DAC HPMIX Left", NULL, "DAC_L_HPMIX_WORK" }, 449 + { "DAC HPMIX Right", NULL, "DAC_R_HPMIX_WORK" }, 450 + 451 + { "DAC_L_DAC_WORK", NULL, "DAC HPMIX Left" }, 452 + { "DAC_R_DAC_WORK", NULL, "DAC HPMIX Right" }, 453 + 454 + { "DAC_L_REF_EN", NULL, "DAC_CURRENT_EN" }, 455 + { "DAC_R_REF_EN", NULL, "DAC_CURRENT_EN" }, 456 + { "DAC_L_CLK_EN", NULL, "DAC_L_REF_EN" }, 457 + { "DAC_R_CLK_EN", NULL, "DAC_R_REF_EN" }, 458 + { "DAC_L_CLK_EN", NULL, "DAC_MCLK_GATE" }, 459 + { "DAC_R_CLK_EN", NULL, "DAC_MCLK_GATE" }, 460 + { "DAC_L_DAC_WORK", NULL, "DAC_L_CLK_EN" }, 461 + { "DAC_R_DAC_WORK", NULL, "DAC_R_CLK_EN" }, 462 + { "DAC_L_HPMIX_SEL", NULL, "DAC_L_DAC_WORK" }, 463 + { "DAC_R_HPMIX_SEL", NULL, "DAC_R_DAC_WORK" }, 464 + 465 + { "HPOUT_L", NULL, "DAC_BUF_REF_L" }, 466 + { "HPOUT_R", NULL, "DAC_BUF_REF_R" }, 467 + { "L_HPOUT_EN", NULL, "DAC_L_HPMIX_SEL" }, 468 + { "R_HPOUT_EN", NULL, "DAC_R_HPMIX_SEL" }, 469 + { "L_HPOUT_WORK", NULL, "L_HPOUT_EN" }, 470 + { "R_HPOUT_WORK", NULL, "R_HPOUT_EN" }, 471 + { "HPOUT_POP_SOUND_L", NULL, "L_HPOUT_WORK" }, 472 + { "HPOUT_POP_SOUND_R", NULL, "R_HPOUT_WORK" }, 473 + { "HPOUT_L", NULL, "HPOUT_POP_SOUND_L" }, 474 + { "HPOUT_R", NULL, "HPOUT_POP_SOUND_R" }, 475 + 476 + { "L_LINEOUT_EN", NULL, "DAC_L_HPMIX_SEL" }, 477 + { "R_LINEOUT_EN", NULL, "DAC_R_HPMIX_SEL" }, 478 + { "LINEOUT_L", NULL, "L_LINEOUT_EN" }, 479 + { "LINEOUT_R", NULL, "R_LINEOUT_EN" }, 480 + }; 481 + 482 + static int rk3308_codec_set_dai_fmt(struct snd_soc_dai *codec_dai, 483 + unsigned int fmt) 484 + { 485 + struct snd_soc_component *component = codec_dai->component; 486 + struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); 487 + const unsigned int inv_bits = fmt & SND_SOC_DAIFMT_INV_MASK; 488 + const bool inv_bitclk = 489 + (inv_bits & SND_SOC_DAIFMT_IB_IF) || 490 + (inv_bits & SND_SOC_DAIFMT_IB_NF); 491 + const bool inv_frmclk = 492 + (inv_bits & SND_SOC_DAIFMT_IB_IF) || 493 + (inv_bits & SND_SOC_DAIFMT_NB_IF); 494 + const unsigned int dac_master_bits = rk3308->codec_ver < ACODEC_VERSION_C ? 495 + RK3308_DAC_IO_MODE_MASTER | RK3308_DAC_MODE_MASTER : 496 + RK3308BS_DAC_IO_MODE_MASTER | RK3308BS_DAC_MODE_MASTER; 497 + unsigned int adc_aif1 = 0, adc_aif2 = 0, dac_aif1 = 0, dac_aif2 = 0; 498 + bool is_master = false; 499 + int grp; 500 + 501 + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 502 + case SND_SOC_DAIFMT_CBC_CFC: 503 + break; 504 + case SND_SOC_DAIFMT_CBP_CFP: 505 + adc_aif2 |= RK3308_ADC_IO_MODE_MASTER; 506 + adc_aif2 |= RK3308_ADC_MODE_MASTER; 507 + dac_aif2 |= dac_master_bits; 508 + is_master = true; 509 + break; 510 + default: 511 + return -EINVAL; 512 + } 513 + 514 + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 515 + case SND_SOC_DAIFMT_DSP_A: 516 + adc_aif1 |= RK3308_ADC_I2S_MODE_PCM; 517 + dac_aif1 |= RK3308_DAC_I2S_MODE_PCM; 518 + break; 519 + case SND_SOC_DAIFMT_I2S: 520 + adc_aif1 |= RK3308_ADC_I2S_MODE_I2S; 521 + dac_aif1 |= RK3308_DAC_I2S_MODE_I2S; 522 + break; 523 + case SND_SOC_DAIFMT_RIGHT_J: 524 + adc_aif1 |= RK3308_ADC_I2S_MODE_RJ; 525 + dac_aif1 |= RK3308_DAC_I2S_MODE_RJ; 526 + break; 527 + case SND_SOC_DAIFMT_LEFT_J: 528 + adc_aif1 |= RK3308_ADC_I2S_MODE_LJ; 529 + dac_aif1 |= RK3308_DAC_I2S_MODE_LJ; 530 + break; 531 + default: 532 + return -EINVAL; 533 + } 534 + 535 + if (inv_bitclk) { 536 + adc_aif2 |= RK3308_ADC_I2S_BIT_CLK_POL_REVERSAL; 537 + dac_aif2 |= RK3308_DAC_I2S_BIT_CLK_POL_REVERSAL; 538 + } 539 + 540 + if (inv_frmclk) { 541 + adc_aif1 |= RK3308_ADC_I2S_LRC_POL_REVERSAL; 542 + dac_aif1 |= RK3308_DAC_I2S_LRC_POL_REVERSAL; 543 + } 544 + 545 + /* 546 + * Hold ADC Digital registers start at master mode 547 + * 548 + * There are 8 ADCs which use the same internal SCLK and LRCK for 549 + * master mode. We need to make sure that they are in effect at the 550 + * same time, otherwise they will cause abnormal clocks. 551 + */ 552 + if (is_master) 553 + regmap_clear_bits(rk3308->regmap, RK3308_GLB_CON, RK3308_ADC_DIG_WORK); 554 + 555 + for (grp = 0; grp < ADC_LR_GROUP_MAX; grp++) { 556 + regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON01(grp), 557 + RK3308_ADC_I2S_LRC_POL_REVERSAL | 558 + RK3308_ADC_I2S_MODE_MSK, 559 + adc_aif1); 560 + regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON02(grp), 561 + RK3308_ADC_IO_MODE_MASTER | 562 + RK3308_ADC_MODE_MASTER | 563 + RK3308_ADC_I2S_BIT_CLK_POL_REVERSAL, 564 + adc_aif2); 565 + } 566 + 567 + /* Hold ADC Digital registers end at master mode */ 568 + if (is_master) 569 + regmap_set_bits(rk3308->regmap, RK3308_GLB_CON, RK3308_ADC_DIG_WORK); 570 + 571 + regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON01, 572 + RK3308_DAC_I2S_LRC_POL_REVERSAL | 573 + RK3308_DAC_I2S_MODE_MSK, 574 + dac_aif1); 575 + regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02, 576 + dac_master_bits | RK3308_DAC_I2S_BIT_CLK_POL_REVERSAL, 577 + dac_aif2); 578 + 579 + return 0; 580 + } 581 + 582 + static int rk3308_codec_dac_dig_config(struct rk3308_codec_priv *rk3308, 583 + struct snd_pcm_hw_params *params) 584 + { 585 + unsigned int dac_aif1 = 0; 586 + 587 + switch (params_format(params)) { 588 + case SNDRV_PCM_FORMAT_S16_LE: 589 + dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_16BITS; 590 + break; 591 + case SNDRV_PCM_FORMAT_S20_3LE: 592 + dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_20BITS; 593 + break; 594 + case SNDRV_PCM_FORMAT_S24_LE: 595 + dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_24BITS; 596 + break; 597 + case SNDRV_PCM_FORMAT_S32_LE: 598 + dac_aif1 |= RK3308_DAC_I2S_VALID_LEN_32BITS; 599 + break; 600 + default: 601 + return -EINVAL; 602 + } 603 + 604 + regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON01, 605 + RK3308_DAC_I2S_VALID_LEN_MSK, dac_aif1); 606 + regmap_set_bits(rk3308->regmap, RK3308_DAC_DIG_CON02, RK3308_DAC_I2S_WORK); 607 + 608 + return 0; 609 + } 610 + 611 + static int rk3308_codec_adc_dig_config(struct rk3308_codec_priv *rk3308, 612 + struct snd_pcm_hw_params *params) 613 + { 614 + unsigned int adc_aif1 = 0; 615 + /* 616 + * grp 0 = ADC1 and ADC2 617 + * grp 1 = ADC3 and ADC4 618 + * grp 2 = ADC5 and ADC6 619 + * grp 3 = ADC7 and ADC8 620 + */ 621 + u32 used_adc_grps; 622 + int grp; 623 + 624 + switch (params_channels(params)) { 625 + case 1: 626 + adc_aif1 |= RK3308_ADC_I2S_MONO; 627 + used_adc_grps = 1; 628 + break; 629 + case 2: 630 + case 4: 631 + case 6: 632 + case 8: 633 + used_adc_grps = params_channels(params) / 2; 634 + break; 635 + default: 636 + dev_err(rk3308->dev, "Invalid channel number %d\n", params_channels(params)); 637 + return -EINVAL; 638 + } 639 + 640 + switch (params_format(params)) { 641 + case SNDRV_PCM_FORMAT_S16_LE: 642 + adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_16BITS; 643 + break; 644 + case SNDRV_PCM_FORMAT_S20_3LE: 645 + adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_20BITS; 646 + break; 647 + case SNDRV_PCM_FORMAT_S24_LE: 648 + adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_24BITS; 649 + break; 650 + case SNDRV_PCM_FORMAT_S32_LE: 651 + adc_aif1 |= RK3308_ADC_I2S_VALID_LEN_32BITS; 652 + break; 653 + default: 654 + return -EINVAL; 655 + } 656 + 657 + for (grp = 0; grp < used_adc_grps; grp++) { 658 + regmap_update_bits(rk3308->regmap, 659 + RK3308_ADC_DIG_CON03(grp), 660 + RK3308_ADC_L_CH_BIST_MSK | RK3308_ADC_R_CH_BIST_MSK, 661 + RK3308_ADC_L_CH_NORMAL_LEFT | RK3308_ADC_R_CH_NORMAL_RIGHT); 662 + regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON01(grp), 663 + RK3308_ADC_I2S_VALID_LEN_MSK | RK3308_ADC_I2S_MONO, adc_aif1); 664 + regmap_set_bits(rk3308->regmap, RK3308_ADC_DIG_CON02(grp), RK3308_ADC_I2S_WORK); 665 + } 666 + 667 + return 0; 668 + } 669 + 670 + static int rk3308_codec_hw_params(struct snd_pcm_substream *substream, 671 + struct snd_pcm_hw_params *params, 672 + struct snd_soc_dai *dai) 673 + { 674 + struct snd_soc_component *component = dai->component; 675 + struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); 676 + 677 + return (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 678 + rk3308_codec_dac_dig_config(rk3308, params) : 679 + rk3308_codec_adc_dig_config(rk3308, params); 680 + } 681 + 682 + static const struct snd_soc_dai_ops rk3308_codec_dai_ops = { 683 + .hw_params = rk3308_codec_hw_params, 684 + .set_fmt = rk3308_codec_set_dai_fmt, 685 + }; 686 + 687 + static struct snd_soc_dai_driver rk3308_codec_dai_driver = { 688 + .name = "rk3308-hifi", 689 + .playback = { 690 + .stream_name = "HiFi Playback", 691 + .channels_min = 2, 692 + .channels_max = 2, 693 + .rates = SNDRV_PCM_RATE_8000_192000, 694 + .formats = (SNDRV_PCM_FMTBIT_S16_LE | 695 + SNDRV_PCM_FMTBIT_S20_3LE | 696 + SNDRV_PCM_FMTBIT_S24_LE | 697 + SNDRV_PCM_FMTBIT_S32_LE), 698 + }, 699 + .capture = { 700 + .stream_name = "HiFi Capture", 701 + .channels_min = 1, 702 + .channels_max = 8, 703 + .rates = SNDRV_PCM_RATE_8000_192000, 704 + .formats = (SNDRV_PCM_FMTBIT_S16_LE | 705 + SNDRV_PCM_FMTBIT_S20_3LE | 706 + SNDRV_PCM_FMTBIT_S24_LE | 707 + SNDRV_PCM_FMTBIT_S32_LE), 708 + }, 709 + .ops = &rk3308_codec_dai_ops, 710 + }; 711 + 712 + static void rk3308_codec_reset(struct snd_soc_component *component) 713 + { 714 + struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); 715 + 716 + reset_control_assert(rk3308->reset); 717 + usleep_range(10000, 11000); /* estimated value */ 718 + reset_control_deassert(rk3308->reset); 719 + 720 + regmap_write(rk3308->regmap, RK3308_GLB_CON, 0x00); 721 + usleep_range(10000, 11000); /* estimated value */ 722 + regmap_write(rk3308->regmap, RK3308_GLB_CON, 723 + RK3308_SYS_WORK | 724 + RK3308_DAC_DIG_WORK | 725 + RK3308_ADC_DIG_WORK); 726 + } 727 + 728 + /* 729 + * Initialize register whose default after HW reset is problematic or which 730 + * are never modified. 731 + */ 732 + static int rk3308_codec_initialize(struct rk3308_codec_priv *rk3308) 733 + { 734 + int grp; 735 + 736 + /* 737 + * Init ADC digital vol to 0 dB (reset value is 0xff, undocumented). 738 + * Range: -97dB ~ +32dB. 739 + */ 740 + if (rk3308->codec_ver == ACODEC_VERSION_C) { 741 + for (grp = 0; grp < ADC_LR_GROUP_MAX; grp++) { 742 + regmap_write(rk3308->regmap, RK3308_ADC_DIG_CON05(grp), 743 + RK3308_ADC_DIG_VOL_CON_x_0DB); 744 + regmap_write(rk3308->regmap, RK3308_ADC_DIG_CON06(grp), 745 + RK3308_ADC_DIG_VOL_CON_x_0DB); 746 + } 747 + } 748 + 749 + /* set HPMIX default gains (reset value is 0, which is illegal) */ 750 + regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON12, 751 + RK3308_DAC_L_HPMIX_GAIN_MSK | 752 + RK3308_DAC_R_HPMIX_GAIN_MSK, 753 + RK3308_DAC_L_HPMIX_GAIN_NDB_6 | 754 + RK3308_DAC_R_HPMIX_GAIN_NDB_6); 755 + 756 + /* recover DAC digital gain to 0 dB (reset value is 0xff, undocumented) */ 757 + if (rk3308->codec_ver == ACODEC_VERSION_C) 758 + regmap_write(rk3308->regmap, RK3308_DAC_DIG_CON04, 759 + RK3308BS_DAC_DIG_GAIN_0DB); 760 + 761 + /* 762 + * Unconditionally enable zero-cross detection (needed for AGC, 763 + * harmless without AGC) 764 + */ 765 + for (grp = 0; grp < ADC_LR_GROUP_MAX; grp++) 766 + regmap_set_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(grp), 767 + RK3308_ADC_CH1_ZEROCROSS_DET_EN | 768 + RK3308_ADC_CH2_ZEROCROSS_DET_EN); 769 + 770 + return 0; 771 + } 772 + 773 + static int rk3308_codec_probe(struct snd_soc_component *component) 774 + { 775 + struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); 776 + 777 + rk3308->component = component; 778 + 779 + rk3308_codec_reset(component); 780 + rk3308_codec_initialize(rk3308); 781 + 782 + return 0; 783 + } 784 + 785 + static int rk3308_codec_set_bias_level(struct snd_soc_component *component, 786 + enum snd_soc_bias_level level) 787 + { 788 + struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); 789 + 790 + switch (level) { 791 + case SND_SOC_BIAS_ON: 792 + break; 793 + case SND_SOC_BIAS_PREPARE: 794 + break; 795 + case SND_SOC_BIAS_STANDBY: 796 + if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_OFF) 797 + break; 798 + 799 + /* Sequence from TRM Section 8.6.3 "Power Up" */ 800 + regmap_set_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, 801 + RK3308_DAC_L_DAC_EN | RK3308_DAC_R_DAC_EN); 802 + regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), 803 + RK3308_ADC_CURRENT_CHARGE_MSK, 1); 804 + regmap_set_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), 805 + RK3308_ADC_REF_EN); 806 + regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), 807 + RK3308_ADC_CURRENT_CHARGE_MSK, 0x7f); 808 + msleep(20); /* estimated value */ 809 + break; 810 + case SND_SOC_BIAS_OFF: 811 + /* Sequence from TRM Section 8.6.4 "Power Down" */ 812 + regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), 813 + RK3308_ADC_CURRENT_CHARGE_MSK, 1); 814 + regmap_clear_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), 815 + RK3308_ADC_REF_EN); 816 + regmap_clear_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, 817 + RK3308_DAC_L_DAC_EN | RK3308_DAC_R_DAC_EN); 818 + msleep(20); /* estimated value */ 819 + break; 820 + } 821 + return 0; 822 + } 823 + 824 + static const struct snd_soc_component_driver rk3308_codec_component_driver = { 825 + .probe = rk3308_codec_probe, 826 + .set_bias_level = rk3308_codec_set_bias_level, 827 + .controls = rk3308_codec_controls, 828 + .num_controls = ARRAY_SIZE(rk3308_codec_controls), 829 + .dapm_widgets = rk3308_codec_dapm_widgets, 830 + .num_dapm_widgets = ARRAY_SIZE(rk3308_codec_dapm_widgets), 831 + .dapm_routes = rk3308_codec_dapm_routes, 832 + .num_dapm_routes = ARRAY_SIZE(rk3308_codec_dapm_routes), 833 + }; 834 + 835 + static const struct regmap_config rk3308_codec_regmap_config = { 836 + .reg_bits = 32, 837 + .reg_stride = 4, 838 + .val_bits = 32, 839 + .max_register = RK3308_DAC_ANA_CON15, 840 + }; 841 + 842 + static int rk3308_codec_get_version(struct rk3308_codec_priv *rk3308) 843 + { 844 + unsigned int chip_id; 845 + int err; 846 + 847 + err = regmap_read(rk3308->grf, GRF_CHIP_ID, &chip_id); 848 + if (err) 849 + return err; 850 + 851 + switch (chip_id) { 852 + case 3306: 853 + rk3308->codec_ver = ACODEC_VERSION_A; 854 + break; 855 + case 0x3308: 856 + rk3308->codec_ver = ACODEC_VERSION_B; 857 + return dev_err_probe(rk3308->dev, -EINVAL, "Chip version B not supported\n"); 858 + case 0x3308c: 859 + rk3308->codec_ver = ACODEC_VERSION_C; 860 + break; 861 + default: 862 + return dev_err_probe(rk3308->dev, -EINVAL, "Unknown chip_id: 0x%x\n", chip_id); 863 + } 864 + 865 + dev_info(rk3308->dev, "Found codec version %c\n", rk3308->codec_ver); 866 + return 0; 867 + } 868 + 869 + static int rk3308_codec_set_micbias_level(struct rk3308_codec_priv *rk3308) 870 + { 871 + struct device_node *np = rk3308->dev->of_node; 872 + u32 percent; 873 + u32 mult; 874 + int err; 875 + 876 + err = of_property_read_u32(np, "rockchip,micbias-avdd-percent", &percent); 877 + if (err == -EINVAL) 878 + return 0; 879 + if (err) 880 + return dev_err_probe(rk3308->dev, err, 881 + "Error reading 'rockchip,micbias-avdd-percent'\n"); 882 + 883 + /* Convert percent to register value, linerarly (50% -> 0, 5% step = +1) */ 884 + mult = (percent - 50) / 5; 885 + 886 + /* Check range and that the percent was an exact value allowed */ 887 + if (mult > RK3308_ADC_LEVEL_RANGE_MICBIAS_MAX || mult * 5 + 50 != percent) 888 + return dev_err_probe(rk3308->dev, -EINVAL, 889 + "Invalid value %u for 'rockchip,micbias-avdd-percent'\n", 890 + percent); 891 + 892 + regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(0), 893 + RK3308_ADC_LEVEL_RANGE_MICBIAS_MSK, 894 + mult << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT); 895 + 896 + return 0; 897 + } 898 + 899 + static int rk3308_codec_platform_probe(struct platform_device *pdev) 900 + { 901 + struct device_node *np = pdev->dev.of_node; 902 + struct device *dev = &pdev->dev; 903 + struct rk3308_codec_priv *rk3308; 904 + void __iomem *base; 905 + int err; 906 + 907 + rk3308 = devm_kzalloc(&pdev->dev, sizeof(*rk3308), GFP_KERNEL); 908 + if (!rk3308) 909 + return -ENOMEM; 910 + 911 + rk3308->dev = dev; 912 + 913 + rk3308->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); 914 + if (IS_ERR(rk3308->grf)) 915 + return dev_err_probe(dev, PTR_ERR(rk3308->grf), "Error getting GRF\n"); 916 + 917 + rk3308->reset = devm_reset_control_get_optional_exclusive(dev, "codec"); 918 + if (IS_ERR(rk3308->reset)) 919 + return dev_err_probe(dev, PTR_ERR(rk3308->reset), "Failed to get reset control\n"); 920 + 921 + err = devm_clk_bulk_get(dev, ARRAY_SIZE(rk3308_codec_clocks), rk3308_codec_clocks); 922 + if (err) 923 + return dev_err_probe(dev, err, "Failed to get clocks\n"); 924 + 925 + err = clk_bulk_prepare_enable(ARRAY_SIZE(rk3308_codec_clocks), rk3308_codec_clocks); 926 + if (err) 927 + return dev_err_probe(dev, err, "Failed to enable clocks\n"); 928 + 929 + err = rk3308_codec_get_version(rk3308); 930 + if (err) 931 + return err; 932 + 933 + base = devm_platform_ioremap_resource(pdev, 0); 934 + if (IS_ERR(base)) 935 + return PTR_ERR(base); 936 + 937 + rk3308->regmap = devm_regmap_init_mmio(dev, base, &rk3308_codec_regmap_config); 938 + if (IS_ERR(rk3308->regmap)) 939 + return dev_err_probe(dev, PTR_ERR(rk3308->regmap), 940 + "Failed to init regmap\n"); 941 + 942 + platform_set_drvdata(pdev, rk3308); 943 + 944 + err = rk3308_codec_set_micbias_level(rk3308); 945 + if (err) 946 + return err; 947 + 948 + err = devm_snd_soc_register_component(dev, &rk3308_codec_component_driver, 949 + &rk3308_codec_dai_driver, 1); 950 + if (err) 951 + return dev_err_probe(dev, err, "Failed to register codec\n"); 952 + 953 + return 0; 954 + } 955 + 956 + static const struct of_device_id rk3308_codec_of_match[] = { 957 + { .compatible = "rockchip,rk3308-codec", }, 958 + {}, 959 + }; 960 + MODULE_DEVICE_TABLE(of, rk3308_codec_of_match); 961 + 962 + static struct platform_driver rk3308_codec_driver = { 963 + .driver = { 964 + .name = "rk3308-acodec", 965 + .of_match_table = of_match_ptr(rk3308_codec_of_match), 966 + }, 967 + .probe = rk3308_codec_platform_probe, 968 + }; 969 + module_platform_driver(rk3308_codec_driver); 970 + 971 + MODULE_AUTHOR("Xing Zheng <zhengxing@rock-chips.com>"); 972 + MODULE_AUTHOR("Luca Ceresoli <luca.ceresoli@bootlin.com>"); 973 + MODULE_DESCRIPTION("ASoC RK3308 Codec Driver"); 974 + MODULE_LICENSE("GPL");
+579
sound/soc/codecs/rk3308_codec.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Rockchip RK3308 internal audio codec driver -- register definitions 4 + * 5 + * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd All rights reserved. 6 + * Copyright (c) 2022, Vivax-Metrotech Ltd 7 + */ 8 + 9 + #ifndef __RK3308_CODEC_H__ 10 + #define __RK3308_CODEC_H__ 11 + 12 + #define RK3308_GLB_CON 0x00 13 + 14 + /* ADC DIGITAL REGISTERS */ 15 + 16 + /* 17 + * The ADC group are 0 ~ 3, that control: 18 + * 19 + * CH0: left_0(ADC1) and right_0(ADC2) 20 + * CH1: left_1(ADC3) and right_1(ADC4) 21 + * CH2: left_2(ADC5) and right_2(ADC6) 22 + * CH3: left_3(ADC7) and right_3(ADC8) 23 + */ 24 + #define RK3308_ADC_DIG_OFFSET(ch) (((ch) & 0x3) * 0xc0 + 0x0) 25 + 26 + #define RK3308_ADC_DIG_CON01(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x04) 27 + #define RK3308_ADC_DIG_CON02(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x08) 28 + #define RK3308_ADC_DIG_CON03(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x0c) 29 + #define RK3308_ADC_DIG_CON04(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x10) 30 + #define RK3308_ADC_DIG_CON05(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x14) // ver.C only 31 + #define RK3308_ADC_DIG_CON06(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x18) // ver.C only 32 + #define RK3308_ADC_DIG_CON07(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x1c) 33 + 34 + #define RK3308_ALC_L_DIG_CON00(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x40) 35 + #define RK3308_ALC_L_DIG_CON01(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x44) 36 + #define RK3308_ALC_L_DIG_CON02(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x48) 37 + #define RK3308_ALC_L_DIG_CON03(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x4c) 38 + #define RK3308_ALC_L_DIG_CON04(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x50) 39 + #define RK3308_ALC_L_DIG_CON05(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x54) 40 + #define RK3308_ALC_L_DIG_CON06(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x58) 41 + #define RK3308_ALC_L_DIG_CON07(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x5c) 42 + #define RK3308_ALC_L_DIG_CON08(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x60) 43 + #define RK3308_ALC_L_DIG_CON09(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x64) 44 + #define RK3308_ALC_L_DIG_CON12(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x70) 45 + 46 + #define RK3308_ALC_R_DIG_CON00(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x80) 47 + #define RK3308_ALC_R_DIG_CON01(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x84) 48 + #define RK3308_ALC_R_DIG_CON02(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x88) 49 + #define RK3308_ALC_R_DIG_CON03(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x8c) 50 + #define RK3308_ALC_R_DIG_CON04(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x90) 51 + #define RK3308_ALC_R_DIG_CON05(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x94) 52 + #define RK3308_ALC_R_DIG_CON06(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x98) 53 + #define RK3308_ALC_R_DIG_CON07(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0x9c) 54 + #define RK3308_ALC_R_DIG_CON08(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0xa0) 55 + #define RK3308_ALC_R_DIG_CON09(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0xa4) 56 + #define RK3308_ALC_R_DIG_CON12(ch) (RK3308_ADC_DIG_OFFSET((ch)) + 0xb0) 57 + 58 + /* DAC DIGITAL REGISTERS */ 59 + #define RK3308_DAC_DIG_OFFSET 0x300 60 + #define RK3308_DAC_DIG_CON01 (RK3308_DAC_DIG_OFFSET + 0x04) 61 + #define RK3308_DAC_DIG_CON02 (RK3308_DAC_DIG_OFFSET + 0x08) 62 + #define RK3308_DAC_DIG_CON03 (RK3308_DAC_DIG_OFFSET + 0x0c) 63 + #define RK3308_DAC_DIG_CON04 (RK3308_DAC_DIG_OFFSET + 0x10) 64 + #define RK3308_DAC_DIG_CON05 (RK3308_DAC_DIG_OFFSET + 0x14) 65 + #define RK3308_DAC_DIG_CON10 (RK3308_DAC_DIG_OFFSET + 0x28) 66 + #define RK3308_DAC_DIG_CON11 (RK3308_DAC_DIG_OFFSET + 0x2c) 67 + #define RK3308_DAC_DIG_CON13 (RK3308_DAC_DIG_OFFSET + 0x34) 68 + #define RK3308_DAC_DIG_CON14 (RK3308_DAC_DIG_OFFSET + 0x38) 69 + 70 + /* ADC ANALOG REGISTERS */ 71 + /* 72 + * The ADC group are 0 ~ 3, that control: 73 + * 74 + * CH0: left_0(ADC1) and right_0(ADC2) 75 + * CH1: left_1(ADC3) and right_1(ADC4) 76 + * CH2: left_2(ADC5) and right_2(ADC6) 77 + * CH3: left_3(ADC7) and right_3(ADC8) 78 + */ 79 + #define RK3308_ADC_ANA_OFFSET(ch) (((ch) & 0x3) * 0x40 + 0x340) 80 + #define RK3308_ADC_ANA_CON00(ch) (RK3308_ADC_ANA_OFFSET((ch)) + 0x00) 81 + #define RK3308_ADC_ANA_CON01(ch) (RK3308_ADC_ANA_OFFSET((ch)) + 0x04) 82 + #define RK3308_ADC_ANA_CON02(ch) (RK3308_ADC_ANA_OFFSET((ch)) + 0x08) 83 + #define RK3308_ADC_ANA_CON03(ch) (RK3308_ADC_ANA_OFFSET((ch)) + 0x0c) 84 + #define RK3308_ADC_ANA_CON04(ch) (RK3308_ADC_ANA_OFFSET((ch)) + 0x10) 85 + #define RK3308_ADC_ANA_CON05(ch) (RK3308_ADC_ANA_OFFSET((ch)) + 0x14) 86 + #define RK3308_ADC_ANA_CON06(ch) (RK3308_ADC_ANA_OFFSET((ch)) + 0x18) 87 + #define RK3308_ADC_ANA_CON07(ch) (RK3308_ADC_ANA_OFFSET((ch)) + 0x1c) 88 + #define RK3308_ADC_ANA_CON08(ch) (RK3308_ADC_ANA_OFFSET((ch)) + 0x20) 89 + #define RK3308_ADC_ANA_CON10(ch) (RK3308_ADC_ANA_OFFSET((ch)) + 0x28) 90 + #define RK3308_ADC_ANA_CON11(ch) (RK3308_ADC_ANA_OFFSET((ch)) + 0x2c) 91 + 92 + /* DAC ANALOG REGISTERS */ 93 + #define RK3308_DAC_ANA_OFFSET 0x440 94 + #define RK3308_DAC_ANA_CON00 (RK3308_DAC_ANA_OFFSET + 0x00) 95 + #define RK3308_DAC_ANA_CON01 (RK3308_DAC_ANA_OFFSET + 0x04) 96 + #define RK3308_DAC_ANA_CON02 (RK3308_DAC_ANA_OFFSET + 0x08) 97 + #define RK3308_DAC_ANA_CON03 (RK3308_DAC_ANA_OFFSET + 0x0c) 98 + #define RK3308_DAC_ANA_CON04 (RK3308_DAC_ANA_OFFSET + 0x10) 99 + #define RK3308_DAC_ANA_CON05 (RK3308_DAC_ANA_OFFSET + 0x14) 100 + #define RK3308_DAC_ANA_CON06 (RK3308_DAC_ANA_OFFSET + 0x18) 101 + #define RK3308_DAC_ANA_CON07 (RK3308_DAC_ANA_OFFSET + 0x1c) 102 + #define RK3308_DAC_ANA_CON08 (RK3308_DAC_ANA_OFFSET + 0x20) 103 + #define RK3308_DAC_ANA_CON12 (RK3308_DAC_ANA_OFFSET + 0x30) 104 + #define RK3308_DAC_ANA_CON13 (RK3308_DAC_ANA_OFFSET + 0x34) 105 + #define RK3308_DAC_ANA_CON14 (RK3308_DAC_ANA_OFFSET + 0x38) 106 + #define RK3308_DAC_ANA_CON15 (RK3308_DAC_ANA_OFFSET + 0x3c) 107 + 108 + /* 109 + * These are the bits for registers 110 + */ 111 + 112 + /* RK3308_GLB_CON - REG: 0x0000 */ 113 + #define RK3308_ADC_BIST_WORK BIT(7) 114 + #define RK3308_DAC_BIST_WORK BIT(6) 115 + #define RK3308_ADC_MCLK_GATING BIT(5) 116 + #define RK3308_DAC_MCLK_GATING BIT(4) 117 + #define RK3308_ADC_DIG_WORK BIT(2) 118 + #define RK3308_DAC_DIG_WORK BIT(1) 119 + #define RK3308_SYS_WORK BIT(0) 120 + 121 + /* RK3308_ADC_DIG_CON01 - REG: 0x0004 */ 122 + #define RK3308_ADC_I2S_LRC_POL_REVERSAL BIT(7) 123 + #define RK3308_ADC_I2S_VALID_LEN_SFT 5 124 + #define RK3308_ADC_I2S_VALID_LEN_MSK (0x3 << RK3308_ADC_I2S_VALID_LEN_SFT) 125 + #define RK3308_ADC_I2S_VALID_LEN_32BITS (0x3 << RK3308_ADC_I2S_VALID_LEN_SFT) 126 + #define RK3308_ADC_I2S_VALID_LEN_24BITS (0x2 << RK3308_ADC_I2S_VALID_LEN_SFT) 127 + #define RK3308_ADC_I2S_VALID_LEN_20BITS (0x1 << RK3308_ADC_I2S_VALID_LEN_SFT) 128 + #define RK3308_ADC_I2S_VALID_LEN_16BITS (0x0 << RK3308_ADC_I2S_VALID_LEN_SFT) 129 + #define RK3308_ADC_I2S_MODE_SFT 3 130 + #define RK3308_ADC_I2S_MODE_MSK (0x3 << RK3308_ADC_I2S_MODE_SFT) 131 + #define RK3308_ADC_I2S_MODE_PCM (0x3 << RK3308_ADC_I2S_MODE_SFT) 132 + #define RK3308_ADC_I2S_MODE_I2S (0x2 << RK3308_ADC_I2S_MODE_SFT) 133 + #define RK3308_ADC_I2S_MODE_LJ (0x1 << RK3308_ADC_I2S_MODE_SFT) 134 + #define RK3308_ADC_I2S_MODE_RJ (0x0 << RK3308_ADC_I2S_MODE_SFT) 135 + #define RK3308_ADC_I2S_LR_SWAP BIT(1) 136 + #define RK3308_ADC_I2S_MONO BIT(0) 137 + 138 + /* RK3308_ADC_DIG_CON02 - REG: 0x0008 */ 139 + #define RK3308_ADC_IO_MODE_MASTER BIT(5) 140 + #define RK3308_ADC_MODE_MASTER BIT(4) 141 + #define RK3308_ADC_I2S_FRAME_LEN_SFT 2 142 + #define RK3308_ADC_I2S_FRAME_LEN_MSK (0x3 << RK3308_ADC_I2S_FRAME_LEN_SFT) 143 + #define RK3308_ADC_I2S_FRAME_32BITS (0x3 << RK3308_ADC_I2S_FRAME_LEN_SFT) 144 + #define RK3308_ADC_I2S_FRAME_24BITS (0x2 << RK3308_ADC_I2S_FRAME_LEN_SFT) 145 + #define RK3308_ADC_I2S_FRAME_20BITS (0x1 << RK3308_ADC_I2S_FRAME_LEN_SFT) 146 + #define RK3308_ADC_I2S_FRAME_16BITS (0x0 << RK3308_ADC_I2S_FRAME_LEN_SFT) 147 + #define RK3308_ADC_I2S_WORK BIT(1) 148 + #define RK3308_ADC_I2S_BIT_CLK_POL_REVERSAL BIT(0) 149 + 150 + /* RK3308_ADC_DIG_CON03 - REG: 0x000c */ 151 + #define RK3308_ADC_L_CH_BIST_SFT 2 152 + #define RK3308_ADC_L_CH_BIST_MSK (0x3 << RK3308_ADC_L_CH_BIST_SFT) 153 + #define RK3308_ADC_L_CH_NORMAL_RIGHT (0x3 << RK3308_ADC_L_CH_BIST_SFT) /* normal mode */ 154 + #define RK3308_ADC_L_CH_BIST_CUBE (0x2 << RK3308_ADC_L_CH_BIST_SFT) 155 + #define RK3308_ADC_L_CH_BIST_SINE (0x1 << RK3308_ADC_L_CH_BIST_SFT) 156 + #define RK3308_ADC_L_CH_NORMAL_LEFT (0x0 << RK3308_ADC_L_CH_BIST_SFT) /* normal mode */ 157 + #define RK3308_ADC_R_CH_BIST_SFT 0 158 + #define RK3308_ADC_R_CH_BIST_MSK (0x3 << RK3308_ADC_R_CH_BIST_SFT) 159 + #define RK3308_ADC_R_CH_NORMAL_LEFT (0x3 << RK3308_ADC_R_CH_BIST_SFT) /* normal mode */ 160 + #define RK3308_ADC_R_CH_BIST_CUBE (0x2 << RK3308_ADC_R_CH_BIST_SFT) 161 + #define RK3308_ADC_R_CH_BIST_SINE (0x1 << RK3308_ADC_R_CH_BIST_SFT) 162 + #define RK3308_ADC_R_CH_NORMAL_RIGHT (0x0 << RK3308_ADC_R_CH_BIST_SFT) /* normal mode */ 163 + 164 + /* RK3308_ADC_DIG_CON04 - REG: 0x0010 */ 165 + #define RK3308_ADC_HPF_PATH_DIS BIT(2) 166 + #define RK3308_ADC_HPF_CUTOFF_SFT 0 167 + #define RK3308_ADC_HPF_CUTOFF_MSK (0x3 << RK3308_ADC_HPF_CUTOFF_SFT) 168 + #define RK3308_ADC_HPF_CUTOFF_612HZ (0x2 << RK3308_ADC_HPF_CUTOFF_SFT) 169 + #define RK3308_ADC_HPF_CUTOFF_245HZ (0x1 << RK3308_ADC_HPF_CUTOFF_SFT) 170 + #define RK3308_ADC_HPF_CUTOFF_20HZ (0x0 << RK3308_ADC_HPF_CUTOFF_SFT) 171 + 172 + /* RK3308_ADC_DIG_CON07 - REG: 0x001c */ 173 + #define RK3308_ADCL_DATA_SFT 4 174 + #define RK3308_ADCR_DATA_SFT 2 175 + #define RK3308_ADCL_DATA_SEL_ADCL BIT(1) 176 + #define RK3308_ADCR_DATA_SEL_ADCR BIT(0) 177 + 178 + /* 179 + * RK3308_ALC_L_DIG_CON00 - REG: 0x0040 + ch * 0xc0 180 + * RK3308_ALC_R_DIG_CON00 - REG: 0x0080 + ch * 0xc0 181 + */ 182 + #define RK3308_GAIN_ATTACK_JACK BIT(6) 183 + #define RK3308_CTRL_GEN_SFT 4 184 + #define RK3308_CTRL_GEN_MSK (0x3 << RK3308_ALC_CTRL_GEN_SFT) 185 + #define RK3308_CTRL_GEN_JACK3 (0x3 << RK3308_ALC_CTRL_GEN_SFT) 186 + #define RK3308_CTRL_GEN_JACK2 (0x2 << RK3308_ALC_CTRL_GEN_SFT) 187 + #define RK3308_CTRL_GEN_JACK1 (0x1 << RK3308_ALC_CTRL_GEN_SFT) 188 + #define RK3308_CTRL_GEN_NORMAL (0x0 << RK3308_ALC_CTRL_GEN_SFT) 189 + #define RK3308_AGC_HOLD_TIME_SFT 0 190 + #define RK3308_AGC_HOLD_TIME_MSK (0xf << RK3308_AGC_HOLD_TIME_SFT) 191 + #define RK3308_AGC_HOLD_TIME_1S (0xa << RK3308_AGC_HOLD_TIME_SFT) 192 + #define RK3308_AGC_HOLD_TIME_512MS (0x9 << RK3308_AGC_HOLD_TIME_SFT) 193 + #define RK3308_AGC_HOLD_TIME_256MS (0x8 << RK3308_AGC_HOLD_TIME_SFT) 194 + #define RK3308_AGC_HOLD_TIME_128MS (0x7 << RK3308_AGC_HOLD_TIME_SFT) 195 + #define RK3308_AGC_HOLD_TIME_64MS (0x6 << RK3308_AGC_HOLD_TIME_SFT) 196 + #define RK3308_AGC_HOLD_TIME_32MS (0x5 << RK3308_AGC_HOLD_TIME_SFT) 197 + #define RK3308_AGC_HOLD_TIME_16MS (0x4 << RK3308_AGC_HOLD_TIME_SFT) 198 + #define RK3308_AGC_HOLD_TIME_8MS (0x3 << RK3308_AGC_HOLD_TIME_SFT) 199 + #define RK3308_AGC_HOLD_TIME_4MS (0x2 << RK3308_AGC_HOLD_TIME_SFT) 200 + #define RK3308_AGC_HOLD_TIME_2MS (0x1 << RK3308_AGC_HOLD_TIME_SFT) 201 + #define RK3308_AGC_HOLD_TIME_0MS (0x0 << RK3308_AGC_HOLD_TIME_SFT) 202 + 203 + /* 204 + * RK3308_ALC_L_DIG_CON01 - REG: 0x0044 + ch * 0xc0 205 + * RK3308_ALC_R_DIG_CON01 - REG: 0x0084 + ch * 0xc0 206 + */ 207 + #define RK3308_AGC_DECAY_TIME_SFT 4 208 + #define RK3308_AGC_ATTACK_TIME_SFT 0 209 + 210 + /* 211 + * RK3308_ALC_L_DIG_CON02 - REG: 0x0048 + ch * 0xc0 212 + * RK3308_ALC_R_DIG_CON02 - REG: 0x0088 + ch * 0xc0 213 + */ 214 + #define RK3308_AGC_MODE_LIMITER BIT(7) 215 + #define RK3308_AGC_ZERO_CRO_EN BIT(6) 216 + #define RK3308_AGC_AMP_RECOVER_GAIN BIT(5) 217 + #define RK3308_AGC_FAST_DEC_EN BIT(4) 218 + #define RK3308_AGC_NOISE_GATE_EN BIT(3) 219 + #define RK3308_AGC_NOISE_GATE_THRESH_SFT 0 220 + #define RK3308_AGC_NOISE_GATE_THRESH_MSK (0x7 << RK3308_AGC_NOISE_GATE_THRESH_SFT) 221 + 222 + /* 223 + * RK3308_ALC_L_DIG_CON03 - REG: 0x004c + ch * 0xc0 224 + * RK3308_ALC_R_DIG_CON03 - REG: 0x008c + ch * 0xc0 225 + */ 226 + #define RK3308_AGC_PGA_ZERO_CRO_EN BIT(5) 227 + #define RK3308_AGC_PGA_GAIN_MAX 0x1f 228 + #define RK3308_AGC_PGA_GAIN_MIN 0 229 + #define RK3308_AGC_PGA_GAIN_SFT 0 230 + 231 + /* 232 + * RK3308_ALC_L_DIG_CON04 - REG: 0x0050 + ch * 0xc0 233 + * RK3308_ALC_R_DIG_CON04 - REG: 0x0090 + ch * 0xc0 234 + */ 235 + #define RK3308_AGC_SLOW_CLK_EN BIT(3) 236 + #define RK3308_AGC_APPROX_RATE_SFT 0 237 + #define RK3308_AGC_APPROX_RATE_MSK (0x7 << RK3308_AGC_APPROX_RATE_SFT) 238 + 239 + /* 240 + * RK3308_ALC_L_DIG_CON05 - REG: 0x0054 + ch * 0xc0 241 + * RK3308_ALC_R_DIG_CON05 - REG: 0x0094 + ch * 0xc0 242 + */ 243 + #define RK3308_AGC_LO_8BITS_AGC_MAX_MSK 0xff 244 + 245 + /* 246 + * RK3308_ALC_L_DIG_CON06 - REG: 0x0058 + ch * 0xc0 247 + * RK3308_ALC_R_DIG_CON06 - REG: 0x0098 + ch * 0xc0 248 + */ 249 + #define RK3308_AGC_HI_8BITS_AGC_MAX_MSK 0xff 250 + 251 + /* 252 + * RK3308_ALC_L_DIG_CON07 - REG: 0x005c + ch * 0xc0 253 + * RK3308_ALC_R_DIG_CON07 - REG: 0x009c + ch * 0xc0 254 + */ 255 + #define RK3308_AGC_LO_8BITS_AGC_MIN_MSK 0xff 256 + 257 + /* 258 + * RK3308_ALC_L_DIG_CON08 - REG: 0x0060 + ch * 0xc0 259 + * RK3308_ALC_R_DIG_CON08 - REG: 0x00a0 + ch * 0xc0 260 + */ 261 + #define RK3308_AGC_HI_8BITS_AGC_MIN_MSK 0xff 262 + 263 + /* 264 + * RK3308_ALC_L_DIG_CON09 - REG: 0x0064 + ch * 0xc0 265 + * RK3308_ALC_R_DIG_CON09 - REG: 0x00a4 + ch * 0xc0 266 + */ 267 + #define RK3308_AGC_FUNC_SEL BIT(6) 268 + #define RK3308_AGC_MAX_GAIN_PGA_MAX 0x7 269 + #define RK3308_AGC_MAX_GAIN_PGA_MIN 0 270 + #define RK3308_AGC_MAX_GAIN_PGA_SFT 3 271 + #define RK3308_AGC_MAX_GAIN_PGA_MSK (0x7 << RK3308_AGC_MAX_GAIN_PGA_SFT) 272 + #define RK3308_AGC_MIN_GAIN_PGA_MAX 0x7 273 + #define RK3308_AGC_MIN_GAIN_PGA_MIN 0 274 + #define RK3308_AGC_MIN_GAIN_PGA_SFT 0 275 + #define RK3308_AGC_MIN_GAIN_PGA_MSK (0x7 << RK3308_AGC_MIN_GAIN_PGA_SFT) 276 + 277 + /* 278 + * RK3308_ALC_L_DIG_CON12 - REG: 0x0068 + ch * 0xc0 279 + * RK3308_ALC_R_DIG_CON12 - REG: 0x00a8 + ch * 0xc0 280 + */ 281 + #define RK3308_AGC_GAIN_MSK 0x1f 282 + 283 + /* RK3308_DAC_DIG_CON01 - REG: 0x0304 */ 284 + #define RK3308_DAC_I2S_LRC_POL_REVERSAL BIT(7) 285 + #define RK3308_DAC_I2S_VALID_LEN_SFT 5 286 + #define RK3308_DAC_I2S_VALID_LEN_MSK (0x3 << RK3308_DAC_I2S_VALID_LEN_SFT) 287 + #define RK3308_DAC_I2S_VALID_LEN_32BITS (0x3 << RK3308_DAC_I2S_VALID_LEN_SFT) 288 + #define RK3308_DAC_I2S_VALID_LEN_24BITS (0x2 << RK3308_DAC_I2S_VALID_LEN_SFT) 289 + #define RK3308_DAC_I2S_VALID_LEN_20BITS (0x1 << RK3308_DAC_I2S_VALID_LEN_SFT) 290 + #define RK3308_DAC_I2S_VALID_LEN_16BITS (0x0 << RK3308_DAC_I2S_VALID_LEN_SFT) 291 + #define RK3308_DAC_I2S_MODE_SFT 3 292 + #define RK3308_DAC_I2S_MODE_MSK (0x3 << RK3308_DAC_I2S_MODE_SFT) 293 + #define RK3308_DAC_I2S_MODE_PCM (0x3 << RK3308_DAC_I2S_MODE_SFT) 294 + #define RK3308_DAC_I2S_MODE_I2S (0x2 << RK3308_DAC_I2S_MODE_SFT) 295 + #define RK3308_DAC_I2S_MODE_LJ (0x1 << RK3308_DAC_I2S_MODE_SFT) 296 + #define RK3308_DAC_I2S_MODE_RJ (0x0 << RK3308_DAC_I2S_MODE_SFT) 297 + #define RK3308_DAC_I2S_LR_SWAP BIT(2) 298 + 299 + /* RK3308_DAC_DIG_CON02 - REG: 0x0308 */ 300 + #define RK3308BS_DAC_IO_MODE_MASTER BIT(7) 301 + #define RK3308BS_DAC_MODE_MASTER BIT(6) 302 + #define RK3308_DAC_IO_MODE_MASTER BIT(5) 303 + #define RK3308_DAC_MODE_MASTER BIT(4) 304 + #define RK3308_DAC_I2S_FRAME_LEN_SFT 2 305 + #define RK3308_DAC_I2S_FRAME_LEN_MSK (0x3 << RK3308_DAC_I2S_FRAME_LEN_SFT) 306 + #define RK3308_DAC_I2S_FRAME_32BITS (0x3 << RK3308_DAC_I2S_FRAME_LEN_SFT) 307 + #define RK3308_DAC_I2S_FRAME_24BITS (0x2 << RK3308_DAC_I2S_FRAME_LEN_SFT) 308 + #define RK3308_DAC_I2S_FRAME_20BITS (0x1 << RK3308_DAC_I2S_FRAME_LEN_SFT) 309 + #define RK3308_DAC_I2S_FRAME_16BITS (0x0 << RK3308_DAC_I2S_FRAME_LEN_SFT) 310 + #define RK3308_DAC_I2S_WORK BIT(1) 311 + #define RK3308_DAC_I2S_BIT_CLK_POL_REVERSAL BIT(0) 312 + 313 + /* RK3308_DAC_DIG_CON03 - REG: 0x030C */ 314 + #define RK3308_DAC_L_CH_BIST_SFT 2 315 + #define RK3308_DAC_L_CH_BIST_MSK (0x3 << RK3308_DAC_L_CH_BIST_SFT) 316 + #define RK3308_DAC_L_CH_BIST_LEFT (0x3 << RK3308_DAC_L_CH_BIST_SFT) /* normal mode */ 317 + #define RK3308_DAC_L_CH_BIST_CUBE (0x2 << RK3308_DAC_L_CH_BIST_SFT) 318 + #define RK3308_DAC_L_CH_BIST_SINE (0x1 << RK3308_DAC_L_CH_BIST_SFT) 319 + #define RK3308_DAC_L_CH_BIST_RIGHT (0x0 << RK3308_DAC_L_CH_BIST_SFT) /* normal mode */ 320 + #define RK3308_DAC_R_CH_BIST_SFT 0 321 + #define RK3308_DAC_R_CH_BIST_MSK (0x3 << RK3308_DAC_R_CH_BIST_SFT) 322 + #define RK3308_DAC_R_CH_BIST_LEFT (0x3 << RK3308_DAC_R_CH_BIST_SFT) /* normal mode */ 323 + #define RK3308_DAC_R_CH_BIST_CUBE (0x2 << RK3308_DAC_R_CH_BIST_SFT) 324 + #define RK3308_DAC_R_CH_BIST_SINE (0x1 << RK3308_DAC_R_CH_BIST_SFT) 325 + #define RK3308_DAC_R_CH_BIST_RIGHT (0x0 << RK3308_DAC_R_CH_BIST_SFT) /* normal mode */ 326 + 327 + /* RK3308_DAC_DIG_CON04 - REG: 0x0310 */ 328 + /* Versions up to B: */ 329 + #define RK3308_DAC_MODULATOR_GAIN_SFT 4 330 + #define RK3308_DAC_MODULATOR_GAIN_MSK (0x7 << RK3308_DAC_MODULATOR_GAIN_SFT) 331 + #define RK3308_DAC_CIC_IF_GAIN_SFT 0 332 + #define RK3308_DAC_CIC_IF_GAIN_MSK (0x7 << RK3308_DAC_CIC_IF_GAIN_SFT) 333 + /* Version C: */ 334 + #define RK3308BS_DAC_DIG_GAIN_SFT 0 335 + #define RK3308BS_DAC_DIG_GAIN_MSK (0xff << RK3308BS_DAC_DIG_GAIN_SFT) 336 + #define RK3308BS_DAC_DIG_GAIN_0DB (0xed << RK3308BS_DAC_DIG_GAIN_SFT) 337 + 338 + /* RK3308BS_ADC_DIG_CON05..06 (Version C only) */ 339 + #define RK3308_ADC_DIG_VOL_CON_x_SFT 0 340 + #define RK3308_ADC_DIG_VOL_CON_x_MSK (0xff << RK3308_ADC_DIG_VOL_CON_x_SFT) 341 + #define RK3308_ADC_DIG_VOL_CON_x_0DB (0xc2 << RK3308_ADC_DIG_VOL_CON_x_SFT) 342 + 343 + /* RK3308_DAC_DIG_CON05 - REG: 0x0314 */ 344 + #define RK3308_DAC_L_REG_CTL_INDATA BIT(2) 345 + #define RK3308_DAC_R_REG_CTL_INDATA BIT(1) 346 + 347 + /* RK3308_DAC_DIG_CON10 - REG: 0x0328 */ 348 + #define RK3308_DAC_DATA_HI4(x) ((x) & 0xf) 349 + 350 + /* RK3308_DAC_DIG_CON11 - REG: 0x032c */ 351 + #define RK3308_DAC_DATA_LO8(x) ((x) & 0xff) 352 + 353 + /* RK3308_ADC_ANA_CON00 - REG: 0x0340 */ 354 + #define RK3308_ADC_CH1_CH2_MIC_ALL_MSK (0xff << 0) 355 + #define RK3308_ADC_CH1_CH2_MIC_ALL 0xff 356 + #define RK3308_ADC_CH2_MIC_UNMUTE BIT(7) 357 + #define RK3308_ADC_CH2_MIC_WORK BIT(6) 358 + #define RK3308_ADC_CH2_MIC_EN BIT(5) 359 + #define RK3308_ADC_CH2_BUF_REF_EN BIT(4) 360 + #define RK3308_ADC_CH1_MIC_UNMUTE BIT(3) 361 + #define RK3308_ADC_CH1_MIC_WORK BIT(2) 362 + #define RK3308_ADC_CH1_MIC_EN BIT(1) 363 + #define RK3308_ADC_CH1_BUF_REF_EN BIT(0) 364 + 365 + /* RK3308_ADC_ANA_CON01 - REG: 0x0344 366 + * 367 + * The PGA of MIC-INs: 368 + * - HW version A: 369 + * 0x0 - MIC1~MIC8 0 dB (recommended when ADC used as loopback) 370 + * 0x3 - MIC1~MIC8 20 dB (recommended when ADC used as MIC input) 371 + * - HW version B: 372 + * 0x0 - MIC1~MIC8 0 dB 373 + * 0x1 - MIC1~MIC8 6.6 dB 374 + * 0x2 - MIC1~MIC8 13 dB 375 + * 0x3 - MIC1~MIC8 20 dB 376 + */ 377 + #define RK3308_ADC_CH2_MIC_GAIN_MAX 0x3 378 + #define RK3308_ADC_CH2_MIC_GAIN_MIN 0 379 + #define RK3308_ADC_CH2_MIC_GAIN_SFT 4 380 + #define RK3308_ADC_CH2_MIC_GAIN_MSK (0x3 << RK3308_ADC_CH2_MIC_GAIN_SFT) 381 + #define RK3308_ADC_CH2_MIC_GAIN_20DB (0x3 << RK3308_ADC_CH2_MIC_GAIN_SFT) 382 + #define RK3308_ADC_CH2_MIC_GAIN_13DB (0x2 << RK3308_ADC_CH2_MIC_GAIN_SFT) 383 + #define RK3308_ADC_CH2_MIC_GAIN_6_6DB (0x1 << RK3308_ADC_CH2_MIC_GAIN_SFT) 384 + #define RK3308_ADC_CH2_MIC_GAIN_0DB (0x0 << RK3308_ADC_CH2_MIC_GAIN_SFT) 385 + 386 + #define RK3308_ADC_CH1_MIC_GAIN_MAX 0x3 387 + #define RK3308_ADC_CH1_MIC_GAIN_MIN 0 388 + #define RK3308_ADC_CH1_MIC_GAIN_SFT 0 389 + #define RK3308_ADC_CH1_MIC_GAIN_MSK (0x3 << RK3308_ADC_CH1_MIC_GAIN_SFT) 390 + #define RK3308_ADC_CH1_MIC_GAIN_20DB (0x3 << RK3308_ADC_CH1_MIC_GAIN_SFT) 391 + #define RK3308_ADC_CH1_MIC_GAIN_13DB (0x2 << RK3308_ADC_CH1_MIC_GAIN_SFT) 392 + #define RK3308_ADC_CH1_MIC_GAIN_6_6DB (0x1 << RK3308_ADC_CH1_MIC_GAIN_SFT) 393 + #define RK3308_ADC_CH1_MIC_GAIN_0DB (0x0 << RK3308_ADC_CH1_MIC_GAIN_SFT) 394 + 395 + /* RK3308_ADC_ANA_CON02 - REG: 0x0348 */ 396 + #define RK3308_ADC_CH2_ZEROCROSS_DET_EN BIT(6) 397 + #define RK3308_ADC_CH2_ALC_WORK BIT(5) 398 + #define RK3308_ADC_CH2_ALC_EN BIT(4) 399 + #define RK3308_ADC_CH1_ZEROCROSS_DET_EN BIT(2) 400 + #define RK3308_ADC_CH1_ALC_WORK BIT(1) 401 + #define RK3308_ADC_CH1_ALC_EN BIT(0) 402 + 403 + /* RK3308_ADC_ANA_CON03 - REG: 0x034c */ 404 + #define RK3308_ADC_CH1_ALC_GAIN_MAX 0x1f 405 + #define RK3308_ADC_CH1_ALC_GAIN_MIN 0 406 + #define RK3308_ADC_CH1_ALC_GAIN_SFT 0 407 + #define RK3308_ADC_CH1_ALC_GAIN_MSK (0x1f << RK3308_ADC_CH1_ALC_GAIN_SFT) 408 + #define RK3308_ADC_CH1_ALC_GAIN_0DB (0x0c << RK3308_ADC_CH1_ALC_GAIN_SFT) 409 + 410 + /* RK3308_ADC_ANA_CON04 - REG: 0x0350 */ 411 + #define RK3308_ADC_CH2_ALC_GAIN_MAX 0x1f 412 + #define RK3308_ADC_CH2_ALC_GAIN_MIN 0 413 + #define RK3308_ADC_CH2_ALC_GAIN_SFT 0 414 + #define RK3308_ADC_CH2_ALC_GAIN_MSK (0x1f << RK3308_ADC_CH2_ALC_GAIN_SFT) 415 + #define RK3308_ADC_CH2_ALC_GAIN_0DB (0x0c << RK3308_ADC_CH2_ALC_GAIN_SFT) 416 + 417 + /* RK3308_ADC_ANA_CON05 - REG: 0x0354 */ 418 + #define RK3308_ADC_CH2_ADC_WORK BIT(6) 419 + #define RK3308_ADC_CH2_ADC_EN BIT(5) 420 + #define RK3308_ADC_CH2_CLK_EN BIT(4) 421 + #define RK3308_ADC_CH1_ADC_WORK BIT(2) 422 + #define RK3308_ADC_CH1_ADC_EN BIT(1) 423 + #define RK3308_ADC_CH1_CLK_EN BIT(0) 424 + 425 + /* RK3308_ADC_ANA_CON06 - REG: 0x0358 */ 426 + #define RK3308_ADC_CURRENT_EN BIT(0) 427 + 428 + /* RK3308_ADC_ANA_CON07 - REG: 0x035c */ 429 + /* Note: The register configuration is only valid for ADC2 */ 430 + #define RK3308_ADC_CH2_IN_SEL_SFT 6 431 + #define RK3308_ADC_CH2_IN_SEL_MSK (0x3 << RK3308_ADC_CH2_IN_SEL_SFT) 432 + #define RK3308_ADC_CH2_IN_LINEIN_MIC (0x3 << RK3308_ADC_CH2_IN_SEL_SFT) 433 + #define RK3308_ADC_CH2_IN_LINEIN (0x2 << RK3308_ADC_CH2_IN_SEL_SFT) 434 + #define RK3308_ADC_CH2_IN_MIC (0x1 << RK3308_ADC_CH2_IN_SEL_SFT) 435 + #define RK3308_ADC_CH2_IN_NONE (0x0 << RK3308_ADC_CH2_IN_SEL_SFT) 436 + /* Note: The register configuration is only valid for ADC1 */ 437 + #define RK3308_ADC_CH1_IN_SEL_SFT 4 438 + #define RK3308_ADC_CH1_IN_SEL_MSK (0x3 << RK3308_ADC_CH1_IN_SEL_SFT) 439 + #define RK3308_ADC_CH1_IN_LINEIN_MIC (0x3 << RK3308_ADC_CH1_IN_SEL_SFT) 440 + #define RK3308_ADC_CH1_IN_LINEIN (0x2 << RK3308_ADC_CH1_IN_SEL_SFT) 441 + #define RK3308_ADC_CH1_IN_MIC (0x1 << RK3308_ADC_CH1_IN_SEL_SFT) 442 + #define RK3308_ADC_CH1_IN_NONE (0x0 << RK3308_ADC_CH1_IN_SEL_SFT) 443 + #define RK3308_ADC_MIC_BIAS_BUF_EN BIT(3) 444 + #define RK3308_ADC_LEVEL_RANGE_MICBIAS_MAX 7 445 + #define RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT 0 446 + #define RK3308_ADC_LEVEL_RANGE_MICBIAS_MSK (0x7 << RK3308_ADC_LEVEL_RANGE_MICBIAS_SFT) 447 + 448 + /* RK3308_ADC_ANA_CON08 - REG: 0x0360 */ 449 + #define RK3308_ADC_MICBIAS_CURRENT_EN BIT(4) 450 + 451 + /* RK3308_ADC_ANA_CON10 - REG: 0x0368 */ 452 + #define RK3308_ADC_REF_EN BIT(7) 453 + #define RK3308_ADC_CURRENT_CHARGE_SFT 0 454 + #define RK3308_ADC_CURRENT_CHARGE_MSK (0x7f << RK3308_ADC_CURRENT_CHARGE_SFT) 455 + 456 + /* RK3308_ADC_ANA_CON11 - REG: 0x036c */ 457 + #define RK3308_ADC_ALCR_CON_GAIN_PGAR_EN BIT(1) 458 + #define RK3308_ADC_ALCL_CON_GAIN_PGAL_EN BIT(0) 459 + 460 + /* RK3308_DAC_ANA_CON00 - REG: 0x0440 */ 461 + #define RK3308_DAC_HEADPHONE_DET_EN BIT(1) 462 + #define RK3308_DAC_CURRENT_EN BIT(0) 463 + 464 + /* RK3308_DAC_ANA_CON01 - REG: 0x0444 */ 465 + #define RK3308_DAC_BUF_REF_R_EN BIT(6) 466 + #define RK3308_DAC_BUF_REF_L_EN BIT(2) 467 + #define RK3308_DAC_HPOUT_POP_SOUND_R_SFT 4 468 + #define RK3308_DAC_HPOUT_POP_SOUND_L_SFT 0 469 + // unshifted values for both L and R: 470 + #define RK3308_DAC_HPOUT_POP_SOUND_x_MSK 0x3 471 + #define RK3308_DAC_HPOUT_POP_SOUND_x_WORK 0x2 472 + #define RK3308_DAC_HPOUT_POP_SOUND_x_INIT 0x1 473 + 474 + /* RK3308_DAC_ANA_CON02 - REG: 0x0448 */ 475 + #define RK3308_DAC_R_DAC_WORK BIT(7) 476 + #define RK3308_DAC_R_DAC_EN BIT(6) 477 + #define RK3308_DAC_R_CLK_EN BIT(5) 478 + #define RK3308_DAC_R_REF_EN BIT(4) 479 + #define RK3308_DAC_L_DAC_WORK BIT(3) 480 + #define RK3308_DAC_L_DAC_EN BIT(2) 481 + #define RK3308_DAC_L_CLK_EN BIT(1) 482 + #define RK3308_DAC_L_REF_EN BIT(0) 483 + 484 + /* RK3308_DAC_ANA_CON03 - REG: 0x044c */ 485 + #define RK3308_DAC_R_HPOUT_WORK BIT(6) 486 + #define RK3308_DAC_R_HPOUT_EN BIT(5) 487 + #define RK3308_DAC_R_HPOUT_MUTE_SFT 4 488 + #define RK3308_DAC_L_HPOUT_WORK BIT(2) 489 + #define RK3308_DAC_L_HPOUT_EN BIT(1) 490 + #define RK3308_DAC_L_HPOUT_MUTE_SFT 0 491 + 492 + /* RK3308_DAC_ANA_CON04 - REG: 0x0450 */ 493 + #define RK3308_DAC_x_LINEOUT_GAIN_MAX 0x3 494 + #define RK3308_DAC_R_LINEOUT_GAIN_SFT 6 495 + #define RK3308_DAC_R_LINEOUT_GAIN_MSK (0x3 << RK3308_DAC_R_LINEOUT_GAIN_SFT) 496 + #define RK3308_DAC_R_LINEOUT_GAIN_0DB (0x3 << RK3308_DAC_R_LINEOUT_GAIN_SFT) 497 + #define RK3308_DAC_R_LINEOUT_GAIN_NDB_1_5 (0x2 << RK3308_DAC_R_LINEOUT_GAIN_SFT) 498 + #define RK3308_DAC_R_LINEOUT_GAIN_NDB_3 (0x1 << RK3308_DAC_R_LINEOUT_GAIN_SFT) 499 + #define RK3308_DAC_R_LINEOUT_GAIN_NDB_6 (0x0 << RK3308_DAC_R_LINEOUT_GAIN_SFT) 500 + #define RK3308_DAC_R_LINEOUT_MUTE_SFT 5 501 + #define RK3308_DAC_R_LINEOUT_EN BIT(4) 502 + #define RK3308_DAC_L_LINEOUT_GAIN_SFT 2 503 + #define RK3308_DAC_L_LINEOUT_GAIN_MSK (0x3 << RK3308_DAC_L_LINEOUT_GAIN_SFT) 504 + #define RK3308_DAC_L_LINEOUT_GAIN_0DB (0x3 << RK3308_DAC_L_LINEOUT_GAIN_SFT) 505 + #define RK3308_DAC_L_LINEOUT_GAIN_NDB_1_5 (0x2 << RK3308_DAC_L_LINEOUT_GAIN_SFT) 506 + #define RK3308_DAC_L_LINEOUT_GAIN_NDB_3 (0x1 << RK3308_DAC_L_LINEOUT_GAIN_SFT) 507 + #define RK3308_DAC_L_LINEOUT_GAIN_NDB_6 (0x0 << RK3308_DAC_L_LINEOUT_GAIN_SFT) 508 + #define RK3308_DAC_L_LINEOUT_MUTE_SFT 1 509 + #define RK3308_DAC_L_LINEOUT_EN BIT(0) 510 + 511 + /* RK3308_DAC_ANA_CON05 - REG: 0x0454, step is 1.5db */ 512 + /* RK3308_DAC_ANA_CON06 - REG: 0x0458, step is 1.5db */ 513 + #define RK3308_DAC_x_HPOUT_GAIN_MAX 0x1e 514 + #define RK3308_DAC_x_HPOUT_GAIN_SFT 0 515 + #define RK3308_DAC_x_HPOUT_GAIN_MSK (0x1f << RK3308_DAC_x_HPOUT_GAIN_SFT) 516 + #define RK3308_DAC_x_HPOUT_GAIN_MIN (0x00 << RK3308_DAC_x_HPOUT_GAIN_SFT) 517 + 518 + /* RK3308_DAC_ANA_CON07 - REG: 0x045c */ 519 + #define RK3308_DAC_R_HPOUT_DRV_SFT 4 520 + #define RK3308_DAC_R_HPOUT_DRV_MSK (0xf << RK3308_DAC_R_HPOUT_DRV_SFT) 521 + #define RK3308_DAC_L_HPOUT_DRV_SFT 0 522 + #define RK3308_DAC_L_HPOUT_DRV_MSK (0xf << RK3308_DAC_L_HPOUT_DRV_SFT) 523 + 524 + /* RK3308_DAC_ANA_CON08 - REG: 0x0460 */ 525 + #define RK3308_DAC_R_LINEOUT_DRV_SFT 4 526 + #define RK3308_DAC_R_LINEOUT_DRV_MSK (0xf << RK3308_DAC_R_LINEOUT_DRV_SFT) 527 + #define RK3308_DAC_L_LINEOUT_DRV_SFT 0 528 + #define RK3308_DAC_L_LINEOUT_DRV_MSK (0xf << RK3308_DAC_L_LINEOUT_DRV_SFT) 529 + 530 + /* RK3308_DAC_ANA_CON12 - REG: 0x0470 */ 531 + #define RK3308_DAC_R_HPMIX_SEL_SFT 6 532 + #define RK3308_DAC_R_HPMIX_SEL_MSK (0x3 << RK3308_DAC_R_HPMIX_SEL_SFT) 533 + #define RK3308_DAC_R_HPMIX_LINEIN_I2S (0x3 << RK3308_DAC_R_HPMIX_SEL_SFT) 534 + #define RK3308_DAC_R_HPMIX_LINEIN (0x2 << RK3308_DAC_R_HPMIX_SEL_SFT) 535 + #define RK3308_DAC_R_HPMIX_I2S (0x1 << RK3308_DAC_R_HPMIX_SEL_SFT) 536 + #define RK3308_DAC_R_HPMIX_NONE (0x0 << RK3308_DAC_R_HPMIX_SEL_SFT) 537 + #define RK3308_DAC_L_HPMIX_SEL_SFT 2 538 + #define RK3308_DAC_L_HPMIX_SEL_MSK (0x3 << RK3308_DAC_L_HPMIX_SEL_SFT) 539 + #define RK3308_DAC_L_HPMIX_LINEIN_I2S (0x3 << RK3308_DAC_L_HPMIX_SEL_SFT) 540 + #define RK3308_DAC_L_HPMIX_LINEIN (0x2 << RK3308_DAC_L_HPMIX_SEL_SFT) 541 + #define RK3308_DAC_L_HPMIX_I2S (0x1 << RK3308_DAC_L_HPMIX_SEL_SFT) 542 + #define RK3308_DAC_L_HPMIX_NONE (0x0 << RK3308_DAC_L_HPMIX_SEL_SFT) 543 + #define RK3308_DAC_x_HPMIX_GAIN_MIN 0x1 /* 0x0 and 0x3 are reserved */ 544 + #define RK3308_DAC_x_HPMIX_GAIN_MAX 0x2 545 + #define RK3308_DAC_R_HPMIX_GAIN_SFT 4 546 + #define RK3308_DAC_R_HPMIX_GAIN_MSK (0x3 << RK3308_DAC_R_HPMIX_GAIN_SFT) 547 + #define RK3308_DAC_R_HPMIX_GAIN_0DB (0x2 << RK3308_DAC_R_HPMIX_GAIN_SFT) 548 + #define RK3308_DAC_R_HPMIX_GAIN_NDB_6 (0x1 << RK3308_DAC_R_HPMIX_GAIN_SFT) 549 + #define RK3308_DAC_L_HPMIX_GAIN_SFT 0 550 + #define RK3308_DAC_L_HPMIX_GAIN_MSK (0x3 << RK3308_DAC_L_HPMIX_GAIN_SFT) 551 + #define RK3308_DAC_L_HPMIX_GAIN_0DB (0x2 << RK3308_DAC_L_HPMIX_GAIN_SFT) 552 + #define RK3308_DAC_L_HPMIX_GAIN_NDB_6 (0x1 << RK3308_DAC_L_HPMIX_GAIN_SFT) 553 + 554 + /* RK3308_DAC_ANA_CON13 - REG: 0x0474 */ 555 + #define RK3308_DAC_R_HPMIX_UNMUTE BIT(6) 556 + #define RK3308_DAC_R_HPMIX_WORK BIT(5) 557 + #define RK3308_DAC_R_HPMIX_EN BIT(4) 558 + #define RK3308_DAC_L_HPMIX_UNMUTE BIT(2) 559 + #define RK3308_DAC_L_HPMIX_WORK BIT(1) 560 + #define RK3308_DAC_L_HPMIX_EN BIT(0) 561 + 562 + /* RK3308_DAC_ANA_CON14 - REG: 0x0478 */ 563 + #define RK3308_DAC_VCM_LINEOUT_EN (0x1 << 4) 564 + #define RK3308_DAC_CURRENT_CHARGE_SFT 0 565 + #define RK3308_DAC_CURRENT_CHARGE_MSK (0xf << RK3308_DAC_CURRENT_CHARGE_SFT) 566 + 567 + /* RK3308_DAC_ANA_CON15 - REG: 0x047C */ 568 + #define RK3308_DAC_LINEOUT_POP_SOUND_R_SFT 4 569 + #define RK3308_DAC_LINEOUT_POP_SOUND_R_MSK (0x3 << RK3308_DAC_LINEOUT_POP_SOUND_R_SFT) 570 + #define RK3308_DAC_R_SEL_DC_FROM_INTERNAL (0x2 << RK3308_DAC_LINEOUT_POP_SOUND_R_SFT) 571 + #define RK3308_DAC_R_SEL_DC_FROM_VCM (0x1 << RK3308_DAC_LINEOUT_POP_SOUND_R_SFT) 572 + #define RK3308_DAC_R_SEL_LINEOUT_FROM_INTERNAL (0x0 << RK3308_DAC_LINEOUT_POP_SOUND_R_SFT) 573 + #define RK3308_DAC_LINEOUT_POP_SOUND_L_SFT 0 574 + #define RK3308_DAC_LINEOUT_POP_SOUND_L_MSK (0x3 << RK3308_DAC_LINEOUT_POP_SOUND_L_SFT) 575 + #define RK3308_DAC_L_SEL_DC_FROM_INTERNAL (0x2 << RK3308_DAC_LINEOUT_POP_SOUND_L_SFT) 576 + #define RK3308_DAC_L_SEL_DC_FROM_VCM (0x1 << RK3308_DAC_LINEOUT_POP_SOUND_L_SFT) 577 + #define RK3308_DAC_L_SEL_LINEOUT_FROM_INTERNAL (0x0 << RK3308_DAC_LINEOUT_POP_SOUND_L_SFT) 578 + 579 + #endif /* __RK3308_CODEC_H__ */