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