From e3e12f52b214121840b44c91de5b3e5af5d3eb84 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 06 Nov 2023 03:04:41 +0000 Subject: [PATCH] rk3568 rt init --- kernel/sound/soc/codecs/rk817_codec.c | 117 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 90 insertions(+), 27 deletions(-) diff --git a/kernel/sound/soc/codecs/rk817_codec.c b/kernel/sound/soc/codecs/rk817_codec.c index 6e9d024..66d1ca2 100644 --- a/kernel/sound/soc/codecs/rk817_codec.c +++ b/kernel/sound/soc/codecs/rk817_codec.c @@ -67,7 +67,10 @@ struct regmap *regmap; struct rk808 *rk817; struct clk *mclk; + struct mutex clk_lock; + unsigned int clk_capture; + unsigned int clk_playback; unsigned int stereo_sysclk; unsigned int rate; @@ -79,6 +82,7 @@ bool pdmdata_out_enable; bool use_ext_amplifier; bool adc_for_loopback; + bool resume_path; bool out_l2spk_r2hp; long int playback_path; @@ -506,10 +510,7 @@ static const char * const rk817_capture_path_mode[] = { "MIC OFF", "Main Mic", "Hands Free Mic", "BT Sco Mic"}; -static const char * const rk817_call_path_mode[] = { - "OFF", "RCV", "SPK", "HP", "HP_NO_MIC", "BT"}; /* 0-5 */ - -static const char * const rk817_modem_input_mode[] = {"OFF", "ON"}; +static const char * const rk817_binary_mode[] = {"OFF", "ON"}; static SOC_ENUM_SINGLE_DECL(rk817_playback_path_type, 0, 0, rk817_playback_path_mode); @@ -517,11 +518,8 @@ static SOC_ENUM_SINGLE_DECL(rk817_capture_path_type, 0, 0, rk817_capture_path_mode); -static SOC_ENUM_SINGLE_DECL(rk817_call_path_type, - 0, 0, rk817_call_path_mode); - -static SOC_ENUM_SINGLE_DECL(rk817_modem_input_type, - 0, 0, rk817_modem_input_mode); +static SOC_ENUM_SINGLE_DECL(rk817_resume_path_type, + 0, 0, rk817_binary_mode); static int rk817_playback_path_config(struct snd_soc_component *component, long pre_path, long target_path) @@ -533,10 +531,19 @@ DBG("%s : set playback_path %ld, pre_path %ld\n", __func__, rk817->playback_path, pre_path); - if (rk817->playback_path != OFF) - clk_prepare_enable(rk817->mclk); - else - clk_disable_unprepare(rk817->mclk); + mutex_lock(&rk817->clk_lock); + if (rk817->playback_path != OFF) { + if (rk817->clk_playback == 0) { + clk_prepare_enable(rk817->mclk); + rk817->clk_playback++; + } + } else { + if (rk817->clk_playback > 0) { + clk_disable_unprepare(rk817->mclk); + rk817->clk_playback--; + } + } + mutex_unlock(&rk817->clk_lock); switch (rk817->playback_path) { case OFF: @@ -720,10 +727,19 @@ DBG("%s : set capture_path %ld, pre_path %ld\n", __func__, rk817->capture_path, pre_path); - if (rk817->capture_path != MIC_OFF) - clk_prepare_enable(rk817->mclk); - else - clk_disable_unprepare(rk817->mclk); + mutex_lock(&rk817->clk_lock); + if (rk817->capture_path != MIC_OFF) { + if (rk817->clk_capture == 0) { + clk_prepare_enable(rk817->mclk); + rk817->clk_capture++; + } + } else { + if (rk817->clk_capture > 0) { + clk_disable_unprepare(rk817->mclk); + rk817->clk_capture--; + } + } + mutex_unlock(&rk817->clk_lock); switch (rk817->capture_path) { case MIC_OFF: @@ -842,12 +858,39 @@ ucontrol->value.integer.value[0]); } +static int rk817_resume_path_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rk817_codec_priv *rk817 = snd_soc_component_get_drvdata(component); + + DBG("%s : resume_path %ld\n", __func__, rk817->resume_path); + + ucontrol->value.integer.value[0] = rk817->resume_path; + + return 0; +} + +static int rk817_resume_path_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rk817_codec_priv *rk817 = snd_soc_component_get_drvdata(component); + + rk817->resume_path = ucontrol->value.integer.value[0]; + + return 0; +} + static struct snd_kcontrol_new rk817_snd_path_controls[] = { SOC_ENUM_EXT("Playback Path", rk817_playback_path_type, rk817_playback_path_get, rk817_playback_path_put), SOC_ENUM_EXT("Capture MIC Path", rk817_capture_path_type, rk817_capture_path_get, rk817_capture_path_put), + + SOC_ENUM_EXT("Resume Path", rk817_resume_path_type, + rk817_resume_path_get, rk817_resume_path_put), }; static int rk817_set_dai_sysclk(struct snd_soc_dai *codec_dai, @@ -892,8 +935,7 @@ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_component *component = rtd->codec_dai->component; + struct snd_soc_component *component = dai->component; struct rk817_codec_priv *rk817 = snd_soc_component_get_drvdata(component); unsigned int rate = params_rate(params); unsigned char apll_cfg3_val; @@ -946,14 +988,22 @@ * is before playback/capture_path_put, therefore, we need to configure * APLL_CFG3/DTOP_DIGEN_CLKE/DDAC_SR_LMT0 for different sample rates. */ - snd_soc_component_write(component, RK817_CODEC_APLL_CFG3, apll_cfg3_val); - /* The 0x00 contains ADC_DIG_CLK_DIS and DAC_DIG_CLK_DIS */ - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, - dtop_digen_clke, 0x00); - snd_soc_component_update_bits(component, RK817_CODEC_DDAC_SR_LMT0, - DACSRT_MASK, dtop_digen_sr_lmt0); - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, - dtop_digen_clke, dtop_digen_clke); + if (!((substream->stream == SNDRV_PCM_STREAM_CAPTURE) && rk817->pdmdata_out_enable)) { + snd_soc_component_write(component, RK817_CODEC_APLL_CFG3, apll_cfg3_val); + /* The 0x00 contains ADC_DIG_CLK_DIS and DAC_DIG_CLK_DIS */ + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, + dtop_digen_clke, 0x00); + snd_soc_component_update_bits(component, RK817_CODEC_DDAC_SR_LMT0, + DACSRT_MASK, dtop_digen_sr_lmt0); + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, + dtop_digen_clke, dtop_digen_clke); + snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5, + PLL_PW_DOWN, PLL_PW_DOWN); + usleep_range(50, 60); + snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5, + PLL_PW_DOWN, PLL_PW_UP); + usleep_range(500, 600); + } switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: @@ -1144,6 +1194,15 @@ static int rk817_resume(struct snd_soc_component *component) { + struct rk817_codec_priv *rk817 = snd_soc_component_get_drvdata(component); + + if (rk817->resume_path) { + if (rk817->capture_path != MIC_OFF) + rk817_capture_path_config(component, OFF, rk817->capture_path); + if (rk817->playback_path != OFF) + rk817_playback_path_config(component, OFF, rk817->playback_path); + } + return 0; } @@ -1173,6 +1232,9 @@ clk_prepare_enable(rk817->mclk); rk817_reset(component); clk_disable_unprepare(rk817->mclk); + mutex_init(&rk817->clk_lock); + rk817->clk_capture = 0; + rk817->clk_playback = 0; snd_soc_add_component_controls(component, rk817_snd_path_controls, ARRAY_SIZE(rk817_snd_path_controls)); @@ -1193,6 +1255,7 @@ rk817_codec_power_down(component, RK817_CODEC_ALL); snd_soc_component_exit_regmap(component); + mutex_destroy(&rk817->clk_lock); mdelay(10); } -- Gitblit v1.6.2