From 23fa18eaa71266feff7ba8d83022d9e1cc83c65a Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 10 May 2024 07:42:03 +0000
Subject: [PATCH] disable pwm7
---
kernel/sound/soc/codecs/rk817_codec.c | 176 +++++++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 137 insertions(+), 39 deletions(-)
diff --git a/kernel/sound/soc/codecs/rk817_codec.c b/kernel/sound/soc/codecs/rk817_codec.c
index 6e9d024..8c767ce 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;
@@ -282,10 +286,10 @@
{RK817_CODEC_AREF_RTCFG1, 0x40},
{RK817_CODEC_DDAC_POPD_DACST, 0x02},
/* APLL */
- {RK817_CODEC_APLL_CFG0, 0x04},
+ /* {RK817_CODEC_APLL_CFG0, 0x04}, */
{RK817_CODEC_APLL_CFG1, 0x58},
{RK817_CODEC_APLL_CFG2, 0x2d},
- {RK817_CODEC_APLL_CFG4, 0xa5},
+ /* {RK817_CODEC_APLL_CFG4, 0xa5}, */
{RK817_CODEC_APLL_CFG5, 0x00},
{RK817_CODEC_DI2S_RXCMD_TSD, 0x00},
@@ -320,10 +324,10 @@
{RK817_CODEC_AREF_RTCFG1, 0x40},
{RK817_CODEC_DADC_SR_ACL0, 0x02},
/* {RK817_CODEC_DTOP_DIGEN_CLKE, 0xff}, */
- {RK817_CODEC_APLL_CFG0, 0x04},
+ /* {RK817_CODEC_APLL_CFG0, 0x04}, */
{RK817_CODEC_APLL_CFG1, 0x58},
{RK817_CODEC_APLL_CFG2, 0x2d},
- {RK817_CODEC_APLL_CFG4, 0xa5},
+ /* {RK817_CODEC_APLL_CFG4, 0xa5}, */
{RK817_CODEC_APLL_CFG5, 0x00},
/*{RK817_CODEC_DI2S_RXCMD_TSD, 0x00},*/
@@ -374,12 +378,16 @@
playback_power_up_list[i].value);
}
- /* Re-configure APLL CFG0/4 if (chip_ver <= 0x4) */
+ /* configure APLL CFG0/4 */
if (rk817->chip_ver <= 0x4) {
DBG("%s (%d): SMIC TudorAG and previous versions\n",
__func__, __LINE__);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95);
+ } else {
+ DBG("%s: SMIC TudorAG version later\n", __func__);
+ snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04);
+ snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5);
}
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
@@ -401,16 +409,20 @@
capture_power_up_list[i].value);
}
- /* Re-configure APLL CFG0/4 if (chip_ver <= 0x4) */
+ /* configure APLL CFG0/4 */
if (rk817->chip_ver <= 0x4) {
DBG("%s (%d): SMIC TudorAG and previous versions\n",
__func__, __LINE__);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c);
snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95);
+ } else {
+ DBG("%s: SMIC TudorAG version later\n", __func__);
+ snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04);
+ snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5);
}
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
- ADC_DIG_CLK_MASK, DAC_DIG_CLK_DIS);
+ ADC_DIG_CLK_MASK, ADC_DIG_CLK_DIS);
usleep_range(2000, 2500);
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
ADC_DIG_CLK_MASK, ADC_DIG_CLK_EN);
@@ -506,10 +518,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 +526,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 +539,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 +735,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 +866,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 +943,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 +996,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:
@@ -976,7 +1034,7 @@
return 0;
}
-static int rk817_digital_mute(struct snd_soc_dai *dai, int mute)
+static int rk817_digital_mute_dac(struct snd_soc_dai *dai, int mute, int stream)
{
struct snd_soc_component *component = dai->component;
struct rk817_codec_priv *rk817 = snd_soc_component_get_drvdata(component);
@@ -998,7 +1056,11 @@
DAC_DIG_CLK_EN, DAC_DIG_CLK_DIS);
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
DAC_DIG_CLK_EN, DAC_DIG_CLK_EN);
+ snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
+ I2SRX_EN_MASK, I2SRX_DIS);
} else {
+ snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
+ I2SRX_EN_MASK, I2SRX_EN);
snd_soc_component_update_bits(component,
RK817_CODEC_DDAC_MUTE_MIXCTL,
DACMT_ENABLE, DACMT_DISABLE);
@@ -1048,6 +1110,28 @@
return 0;
}
+static int rk817_digital_mute_adc(struct snd_soc_dai *dai, int mute, int stream)
+{
+ struct snd_soc_component *component = dai->component;
+
+ if (mute)
+ snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
+ I2STX_EN_MASK, I2STX_DIS);
+ else
+ snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
+ I2STX_EN_MASK, I2STX_EN);
+
+ return 0;
+}
+
+static int rk817_digital_mute(struct snd_soc_dai *dai, int mute, int stream)
+{
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+ return rk817_digital_mute_dac(dai, mute, stream);
+ else
+ return rk817_digital_mute_adc(dai, mute, stream);
+}
+
#define RK817_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\
SNDRV_PCM_RATE_16000 | \
SNDRV_PCM_RATE_32000 | \
@@ -1090,7 +1174,7 @@
.hw_params = rk817_hw_params,
.set_fmt = rk817_set_dai_fmt,
.set_sysclk = rk817_set_dai_sysclk,
- .digital_mute = rk817_digital_mute,
+ .mute_stream = rk817_digital_mute,
.shutdown = rk817_codec_shutdown,
};
@@ -1144,6 +1228,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;
}
@@ -1165,14 +1258,17 @@
rk817->playback_path = OFF;
rk817->capture_path = MIC_OFF;
- chip_name = snd_soc_component_read32(component, RK817_PMIC_CHIP_NAME);
- chip_ver = snd_soc_component_read32(component, RK817_PMIC_CHIP_VER);
+ chip_name = snd_soc_component_read(component, RK817_PMIC_CHIP_NAME);
+ chip_ver = snd_soc_component_read(component, RK817_PMIC_CHIP_VER);
rk817->chip_ver = (chip_ver & 0x0f);
dev_info(component->dev, "%s: chip_name:0x%x, chip_ver:0x%x\n", __func__, chip_name, chip_ver);
+ /* always enable mclk, and will disable mclk in rk817_remove */
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 +1289,8 @@
rk817_codec_power_down(component, RK817_CODEC_ALL);
snd_soc_component_exit_regmap(component);
+ mutex_destroy(&rk817->clk_lock);
+ clk_disable_unprepare(rk817->mclk);
mdelay(10);
}
--
Gitblit v1.6.2