[PATCH v1 2/6] ASoC: codecs: rk3308: expose per-channel microphone boost

Xing Zheng zhengxing at rock-chips.com
Sat Oct 31 21:01:21 PDT 2026


The existing MIC Capture Volume controls adjust the ALC gain stage,
leaving the preceding microphone boost stage inaccessible. Add
independent boost controls for all eight inputs without changing the
existing controls or reset gains.

Use the revision-specific dB scales. Revision A permits only the 0 dB
and 20 dB encodings; reject its reserved intermediate settings while
allowing all four settings on revisions B and C.

Signed-off-by: Xing Zheng <zhengxing at rock-chips.com>
---
 sound/soc/codecs/rk3308_codec.c | 80 ++++++++++++++++++++++++++++++++-
 1 file changed, 79 insertions(+), 1 deletion(-)

diff --git a/sound/soc/codecs/rk3308_codec.c b/sound/soc/codecs/rk3308_codec.c
index 7a18ff45e391..fc7e20e82700 100644
--- a/sound/soc/codecs/rk3308_codec.c
+++ b/sound/soc/codecs/rk3308_codec.c
@@ -66,6 +66,84 @@ static const DECLARE_TLV_DB_RANGE(rk3308_codec_dac_lineout_gain_tlv,
 	3, 3, TLV_DB_SCALE_ITEM(0,    0, 0),
 );
 
+static const DECLARE_TLV_DB_RANGE(rk3308_codec_adc_mic_gain_tlv_a,
+	0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
+	3, 3, TLV_DB_SCALE_ITEM(2000, 0, 0),
+);
+
+static const DECLARE_TLV_DB_RANGE(rk3308_codec_adc_mic_gain_tlv_b,
+	0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
+	1, 1, TLV_DB_SCALE_ITEM(660, 0, 0),
+	2, 2, TLV_DB_SCALE_ITEM(1300, 0, 0),
+	3, 3, TLV_DB_SCALE_ITEM(2000, 0, 0),
+);
+
+static int rk3308_codec_mic_boost_put(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+	struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
+	long gain = ucontrol->value.integer.value[0];
+
+	if (rk3308->codec_ver == ACODEC_VERSION_A && gain != 0 && gain != 3)
+		return -EINVAL;
+
+	return snd_soc_put_volsw(kcontrol, ucontrol);
+}
+
+static const struct snd_kcontrol_new rk3308_codec_mic_boost_controls[] = {
+	SOC_SINGLE_EXT_TLV("MIC1 Boost Volume", RK3308_ADC_ANA_CON01(0),
+			   RK3308_ADC_CH1_MIC_GAIN_SFT, RK3308_ADC_CH1_MIC_GAIN_MAX, 0,
+			   snd_soc_get_volsw, rk3308_codec_mic_boost_put,
+			   rk3308_codec_adc_mic_gain_tlv_b),
+	SOC_SINGLE_EXT_TLV("MIC2 Boost Volume", RK3308_ADC_ANA_CON01(0),
+			   RK3308_ADC_CH2_MIC_GAIN_SFT, RK3308_ADC_CH2_MIC_GAIN_MAX, 0,
+			   snd_soc_get_volsw, rk3308_codec_mic_boost_put,
+			   rk3308_codec_adc_mic_gain_tlv_b),
+	SOC_SINGLE_EXT_TLV("MIC3 Boost Volume", RK3308_ADC_ANA_CON01(1),
+			   RK3308_ADC_CH1_MIC_GAIN_SFT, RK3308_ADC_CH1_MIC_GAIN_MAX, 0,
+			   snd_soc_get_volsw, rk3308_codec_mic_boost_put,
+			   rk3308_codec_adc_mic_gain_tlv_b),
+	SOC_SINGLE_EXT_TLV("MIC4 Boost Volume", RK3308_ADC_ANA_CON01(1),
+			   RK3308_ADC_CH2_MIC_GAIN_SFT, RK3308_ADC_CH2_MIC_GAIN_MAX, 0,
+			   snd_soc_get_volsw, rk3308_codec_mic_boost_put,
+			   rk3308_codec_adc_mic_gain_tlv_b),
+	SOC_SINGLE_EXT_TLV("MIC5 Boost Volume", RK3308_ADC_ANA_CON01(2),
+			   RK3308_ADC_CH1_MIC_GAIN_SFT, RK3308_ADC_CH1_MIC_GAIN_MAX, 0,
+			   snd_soc_get_volsw, rk3308_codec_mic_boost_put,
+			   rk3308_codec_adc_mic_gain_tlv_b),
+	SOC_SINGLE_EXT_TLV("MIC6 Boost Volume", RK3308_ADC_ANA_CON01(2),
+			   RK3308_ADC_CH2_MIC_GAIN_SFT, RK3308_ADC_CH2_MIC_GAIN_MAX, 0,
+			   snd_soc_get_volsw, rk3308_codec_mic_boost_put,
+			   rk3308_codec_adc_mic_gain_tlv_b),
+	SOC_SINGLE_EXT_TLV("MIC7 Boost Volume", RK3308_ADC_ANA_CON01(3),
+			   RK3308_ADC_CH1_MIC_GAIN_SFT, RK3308_ADC_CH1_MIC_GAIN_MAX, 0,
+			   snd_soc_get_volsw, rk3308_codec_mic_boost_put,
+			   rk3308_codec_adc_mic_gain_tlv_b),
+	SOC_SINGLE_EXT_TLV("MIC8 Boost Volume", RK3308_ADC_ANA_CON01(3),
+			   RK3308_ADC_CH2_MIC_GAIN_SFT, RK3308_ADC_CH2_MIC_GAIN_MAX, 0,
+			   snd_soc_get_volsw, rk3308_codec_mic_boost_put,
+			   rk3308_codec_adc_mic_gain_tlv_b),
+};
+
+static int rk3308_codec_add_mic_boost_controls(struct snd_soc_component *component)
+{
+	struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component);
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(rk3308_codec_mic_boost_controls); i++) {
+		struct snd_kcontrol_new control = rk3308_codec_mic_boost_controls[i];
+
+		if (rk3308->codec_ver == ACODEC_VERSION_A)
+			control.tlv.p = rk3308_codec_adc_mic_gain_tlv_a;
+		ret = snd_soc_add_component_controls(component, &control, 1);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 static const char * const rk3308_codec_hpf_cutoff_text[] = {
 	"20 Hz", "245 Hz", "612 Hz"
 };
@@ -891,7 +969,7 @@ static int rk3308_codec_probe(struct snd_soc_component *component)
 	rk3308_codec_reset(component);
 	rk3308_codec_initialize(rk3308);
 
-	return 0;
+	return rk3308_codec_add_mic_boost_controls(component);
 }
 
 static int rk3308_codec_set_bias_level(struct snd_soc_component *component,



More information about the linux-arm-kernel mailing list