ASoC: rockchip: rk817-codec: Fix a large number of mclk counts being enabled

If it is not controlled, when the path is configured after
resume, the clock will be continuously turn on to increase
the clock count.

Therefore, we can count and control the switch of clock
separately according to the current status of playback and
capture, so as to avoid that mclk is accidentally turned off
when playback and capture exist at the same time, causing
the other stream to fail to work.

For example:
- before:
  mclk_sai0          2        2        0    11289600          0     0  50000
     mclk_sai0_out2io       1        1        0    11289600          0     0  50000
        mclk_sai0_to_io      16       16        0    11289600          0     0  50000

- after:
  mclk_sai0          2        2        0    11289600          0     0  50000
     mclk_sai0_out2io       1        1        0    11289600          0     0  50000
        mclk_sai0_to_io       2        2        0    11289600          0     0  50000

Change-Id: I78ec18c7ffc42f548e82357bcf20701aa057f15d
Signed-off-by: Xing Zheng <zhengxing@rock-chips.com>
This commit is contained in:
Xing Zheng
2023-06-13 22:35:38 +08:00
committed by Tao Huang
parent b2f8e21628
commit ed36cde37c

View File

@@ -67,7 +67,10 @@ struct rk817_codec_priv {
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;
@@ -539,10 +542,19 @@ static int rk817_playback_path_config(struct snd_soc_component *component,
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:
@@ -726,10 +738,19 @@ static int rk817_capture_path_config(struct snd_soc_component *component,
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:
@@ -1223,6 +1244,9 @@ static int rk817_probe(struct snd_soc_component *component)
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));
@@ -1243,6 +1267,7 @@ static void rk817_remove(struct snd_soc_component *component)
rk817_codec_power_down(component, RK817_CODEC_ALL);
snd_soc_component_exit_regmap(component);
mutex_destroy(&rk817->clk_lock);
mdelay(10);
}