From 7c5535c11ff9c684b1cfaf2b3906bf3496640841 Mon Sep 17 00:00:00 2001 From: Xing Zheng Date: Mon, 21 Nov 2022 19:53:40 +0800 Subject: [PATCH] ASoC: codecs: rv1106_codec: add support properties to configure init gains Add support init gains: MIC Gain ALC Gain (0dB: 0x06) Lineout Gain (0dB: 0x1a) 0dB (0x01) min: -9.0dB (0x00) min: -39.0dB (0x00) 20dB (0x02) max: +37.5dB (0x1f) max: +6.0dB (0x1f) 12dB (0x03) step: +1.5dB step: +1.5dB Signed-off-by: Xing Zheng Change-Id: I827329e3b96c64a7a344dfc4094fea6d118503a5 --- sound/soc/codecs/rv1106_codec.c | 67 +++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/rv1106_codec.c b/sound/soc/codecs/rv1106_codec.c index a16f64b5cf43..3714bdcf0199 100644 --- a/sound/soc/codecs/rv1106_codec.c +++ b/sound/soc/codecs/rv1106_codec.c @@ -50,6 +50,8 @@ #define ADCL (1 << 0) #define ADCR (1 << 1) +#define NOT_SPECIFIED (-1) + enum soc_id_e { SOC_RV1103 = 0x1103, SOC_RV1106 = 0x1106, @@ -97,6 +99,11 @@ struct rv1106_codec_priv { /* For the high pass filter */ unsigned int hpf_cutoff; + /* Specify init gains after codec startup */ + unsigned int init_mic_gain; + unsigned int init_alc_gain; + unsigned int init_lineout_gain; + bool adc_enable; bool dac_enable; bool micbias_enable; @@ -1697,31 +1704,68 @@ out: static int rv1106_codec_default_gains(struct rv1106_codec_priv *rv1106) { + int gainl, gainr; + + /** + * MIC Gain + * 0dB (0x01) + * 20dB (0x02) + * 12dB (0x03) + */ + if (rv1106->init_mic_gain == NOT_SPECIFIED) { + gainl = ACODEC_ADC_L_MIC_GAIN_0DB; + gainr = ACODEC_ADC_R_MIC_GAIN_0DB; + } else { + gainl = ((rv1106->init_mic_gain >> 4) & 0x03) << ACODEC_ADC_L_MIC_GAIN_SFT; + gainr = ((rv1106->init_mic_gain >> 0) & 0x03) << ACODEC_ADC_R_MIC_GAIN_SFT; + } + /* Prepare ADC gains */ /* vendor step 12, set MIC PGA default gains */ regmap_update_bits(rv1106->regmap, ACODEC_ADC_ANA_CTL2, ACODEC_ADC_L_MIC_GAIN_MSK | ACODEC_ADC_R_MIC_GAIN_MSK, - ACODEC_ADC_L_MIC_GAIN_20DB | - ACODEC_ADC_R_MIC_GAIN_20DB); // TODO: using 20dB + gainl | gainr); + /** + * ALC Gain (0dB: 0x06) + * min: -9.0dB (0x00) + * max: +37.5dB (0x1f) + * step: +1.5dB + */ + if (rv1106->init_alc_gain == NOT_SPECIFIED) { + gainl = ACODEC_ADC_L_ALC_GAIN_0DB; + gainr = ACODEC_ADC_R_ALC_GAIN_0DB; + } else { + gainl = ((rv1106->init_alc_gain >> 4) & 0x1f); + gainr = ((rv1106->init_alc_gain >> 0) & 0x1f); + } /* vendor step 13, set ALC default gains */ regmap_update_bits(rv1106->regmap, ACODEC_ADC_ANA_CTL4, ACODEC_ADC_L_ALC_GAIN_MSK, - ACODEC_ADC_L_ALC_GAIN_0DB); + gainl); regmap_update_bits(rv1106->regmap, ACODEC_ADC_ANA_CTL5, ACODEC_ADC_R_ALC_GAIN_MSK, - ACODEC_ADC_R_ALC_GAIN_0DB); + gainr); /* Prepare DAC gains */ /* Step 19, set LINEOUT default gains */ regmap_update_bits(rv1106->regmap, ACODEC_DAC_GAIN_SEL, ACODEC_DAC_DIG_GAIN_MSK, - ACODEC_DAC_DIG_GAIN(ACODEC_DAC_DIG_0DB)); + ACODEC_DAC_DIG_GAIN(ACODEC_DAC_DIG_0DB)); /* The calibrated fixed gain */ + /** + * Lineout Gain (0dB: 0x1a) + * min: -39.0dB (0x00) + * max: +6.0dB (0x1f) + * step: +1.5dB + */ + if (rv1106->init_lineout_gain == NOT_SPECIFIED) + gainl = ACODEC_DAC_LINEOUT_GAIN_0DB; + else + gainl = rv1106->init_lineout_gain & 0x1f; regmap_update_bits(rv1106->regmap, ACODEC_DAC_ANA_CTL2, ACODEC_DAC_LINEOUT_GAIN_MSK, - ACODEC_DAC_LINEOUT_GAIN_0DB); - + gainl); return 0; } @@ -2065,6 +2109,15 @@ static int rv1106_platform_probe(struct platform_device *pdev) rv1106->reset = NULL; } + rv1106->init_mic_gain = NOT_SPECIFIED; + of_property_read_u32(np, "init-mic-gain", &rv1106->init_mic_gain); + + rv1106->init_alc_gain = NOT_SPECIFIED; + of_property_read_u32(np, "init-alc-gain", &rv1106->init_alc_gain); + + rv1106->init_lineout_gain = NOT_SPECIFIED; + of_property_read_u32(np, "init-lineout-gain", &rv1106->init_lineout_gain); + rv1106->pa_ctl_gpio = devm_gpiod_get_optional(&pdev->dev, "pa-ctl", GPIOD_OUT_LOW); if (IS_ERR(rv1106->pa_ctl_gpio))