Skip to content

Commit c5ab93e

Browse files
wenliangwubroonie
authored andcommitted
ASoC: mediatek: mt8195: update control for RT5682 series
Playback pop is observed and the root cause is the reference clock provided by MT8195 is diabled before RT5682 finishes the control flow. To ensure the reference clock supplied to RT5682 is disabled after RT5682 finishes all register controls. We replace BCLK with MCLK for RT5682 reference clock, and makes use of set_bias_level_post to handle MCLK which guarantees MCLK is off after all RT5682 register access. Signed-off-by: Trevor Wu <[email protected]> Reviewed-by: Tzung-Bi Shih <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 3ecb467 commit c5ab93e

File tree

2 files changed

+110
-14
lines changed

2 files changed

+110
-14
lines changed

sound/soc/mediatek/mt8195/mt8195-mt6359-rt1011-rt5682.c

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "../../codecs/rt1011.h"
1919
#include "../../codecs/rt5682.h"
2020
#include "../common/mtk-afe-platform-driver.h"
21+
#include "mt8195-afe-clk.h"
2122
#include "mt8195-afe-common.h"
2223

2324
#define RT1011_CODEC_DAI "rt1011-aif"
@@ -34,6 +35,7 @@ struct mt8195_mt6359_rt1011_rt5682_priv {
3435
struct snd_soc_jack headset_jack;
3536
struct snd_soc_jack dp_jack;
3637
struct snd_soc_jack hdmi_jack;
38+
struct clk *i2so1_mclk;
3739
};
3840

3941
static const struct snd_soc_dapm_widget
@@ -84,8 +86,8 @@ static int mt8195_rt5682_etdm_hw_params(struct snd_pcm_substream *substream,
8486
return ret;
8587
}
8688

87-
ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1, RT5682_PLL1_S_BCLK1,
88-
rate * 64, rate * 512);
89+
ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1, RT5682_PLL1_S_MCLK,
90+
rate * 256, rate * 512);
8991
if (ret) {
9092
dev_err(card->dev, "failed to set pll\n");
9193
return ret;
@@ -98,7 +100,7 @@ static int mt8195_rt5682_etdm_hw_params(struct snd_pcm_substream *substream,
98100
return ret;
99101
}
100102

101-
return snd_soc_dai_set_sysclk(cpu_dai, 0, rate * 128,
103+
return snd_soc_dai_set_sysclk(cpu_dai, 0, rate * 256,
102104
SND_SOC_CLOCK_OUT);
103105
}
104106

@@ -327,8 +329,14 @@ static int mt8195_rt5682_init(struct snd_soc_pcm_runtime *rtd)
327329
struct mt8195_mt6359_rt1011_rt5682_priv *priv =
328330
snd_soc_card_get_drvdata(rtd->card);
329331
struct snd_soc_jack *jack = &priv->headset_jack;
332+
struct snd_soc_component *cmpnt_afe =
333+
snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
334+
struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
335+
struct mt8195_afe_private *afe_priv = afe->platform_priv;
330336
int ret;
331337

338+
priv->i2so1_mclk = afe_priv->clk[MT8195_CLK_TOP_APLL12_DIV2];
339+
332340
ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
333341
SND_JACK_HEADSET | SND_JACK_BTN_0 |
334342
SND_JACK_BTN_1 | SND_JACK_BTN_2 |
@@ -562,6 +570,47 @@ static const struct snd_soc_ops mt8195_capture_ops = {
562570
.startup = mt8195_capture_startup,
563571
};
564572

573+
static int mt8195_set_bias_level_post(struct snd_soc_card *card,
574+
struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
575+
{
576+
struct snd_soc_component *component = dapm->component;
577+
struct mt8195_mt6359_rt1011_rt5682_priv *priv =
578+
snd_soc_card_get_drvdata(card);
579+
int ret;
580+
581+
/*
582+
* It's required to control mclk directly in the set_bias_level_post
583+
* function for rt5682 and rt5682s codec, or the unexpected pop happens
584+
* at the end of playback.
585+
*/
586+
if (!component ||
587+
(strcmp(component->name, RT5682_DEV0_NAME) &&
588+
strcmp(component->name, RT5682S_DEV0_NAME)))
589+
return 0;
590+
591+
switch (level) {
592+
case SND_SOC_BIAS_OFF:
593+
if (!__clk_is_enabled(priv->i2so1_mclk))
594+
return 0;
595+
596+
clk_disable_unprepare(priv->i2so1_mclk);
597+
dev_dbg(card->dev, "Disable i2so1 mclk\n");
598+
break;
599+
case SND_SOC_BIAS_ON:
600+
ret = clk_prepare_enable(priv->i2so1_mclk);
601+
if (ret) {
602+
dev_err(card->dev, "Can't enable i2so1 mclk: %d\n", ret);
603+
return ret;
604+
}
605+
dev_dbg(card->dev, "Enable i2so1 mclk\n");
606+
break;
607+
default:
608+
break;
609+
}
610+
611+
return 0;
612+
}
613+
565614
enum {
566615
DAI_LINK_DL2_FE,
567616
DAI_LINK_DL3_FE,
@@ -1037,6 +1086,7 @@ static struct snd_soc_card mt8195_mt6359_rt1011_rt5682_soc_card = {
10371086
.num_dapm_routes = ARRAY_SIZE(mt8195_mt6359_rt1011_rt5682_routes),
10381087
.codec_conf = rt1011_amp_conf,
10391088
.num_configs = ARRAY_SIZE(rt1011_amp_conf),
1089+
.set_bias_level_post = mt8195_set_bias_level_post,
10401090
};
10411091

10421092
static int mt8195_mt6359_rt1011_rt5682_dev_probe(struct platform_device *pdev)

sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "../../codecs/mt6359.h"
2020
#include "../../codecs/rt5682.h"
2121
#include "../common/mtk-afe-platform-driver.h"
22+
#include "mt8195-afe-clk.h"
2223
#include "mt8195-afe-common.h"
2324

2425
#define RT1019_CODEC_DAI "HiFi"
@@ -46,6 +47,7 @@ struct mt8195_mt6359_rt1019_rt5682_priv {
4647
struct snd_soc_jack headset_jack;
4748
struct snd_soc_jack dp_jack;
4849
struct snd_soc_jack hdmi_jack;
50+
struct clk *i2so1_mclk;
4951
};
5052

5153
static const struct snd_soc_dapm_widget
@@ -92,8 +94,6 @@ static int mt8195_rt5682_etdm_hw_params(struct snd_pcm_substream *substream,
9294
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
9395
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
9496
unsigned int rate = params_rate(params);
95-
unsigned int mclk_fs_ratio = 128;
96-
unsigned int mclk_fs = rate * mclk_fs_ratio;
9797
int bitwidth;
9898
int ret;
9999

@@ -109,25 +109,22 @@ static int mt8195_rt5682_etdm_hw_params(struct snd_pcm_substream *substream,
109109
return ret;
110110
}
111111

112-
ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1,
113-
RT5682_PLL1_S_BCLK1,
114-
params_rate(params) * 64,
115-
params_rate(params) * 512);
112+
ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1, RT5682_PLL1_S_MCLK,
113+
rate * 256, rate * 512);
116114
if (ret) {
117115
dev_err(card->dev, "failed to set pll\n");
118116
return ret;
119117
}
120118

121-
ret = snd_soc_dai_set_sysclk(codec_dai,
122-
RT5682_SCLK_S_PLL1,
123-
params_rate(params) * 512,
124-
SND_SOC_CLOCK_IN);
119+
ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1,
120+
rate * 512, SND_SOC_CLOCK_IN);
125121
if (ret) {
126122
dev_err(card->dev, "failed to set sysclk\n");
127123
return ret;
128124
}
129125

130-
return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs, SND_SOC_CLOCK_OUT);
126+
return snd_soc_dai_set_sysclk(cpu_dai, 0, rate * 256,
127+
SND_SOC_CLOCK_OUT);
131128
}
132129

133130
static const struct snd_soc_ops mt8195_rt5682_etdm_ops = {
@@ -322,8 +319,14 @@ static int mt8195_rt5682_init(struct snd_soc_pcm_runtime *rtd)
322319
struct mt8195_mt6359_rt1019_rt5682_priv *priv =
323320
snd_soc_card_get_drvdata(rtd->card);
324321
struct snd_soc_jack *jack = &priv->headset_jack;
322+
struct snd_soc_component *cmpnt_afe =
323+
snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
324+
struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
325+
struct mt8195_afe_private *afe_priv = afe->platform_priv;
325326
int ret;
326327

328+
priv->i2so1_mclk = afe_priv->clk[MT8195_CLK_TOP_APLL12_DIV2];
329+
327330
ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
328331
SND_JACK_HEADSET | SND_JACK_BTN_0 |
329332
SND_JACK_BTN_1 | SND_JACK_BTN_2 |
@@ -560,6 +563,48 @@ static const struct snd_soc_ops mt8195_capture_ops = {
560563
.startup = mt8195_capture_startup,
561564
};
562565

566+
static int mt8195_set_bias_level_post(struct snd_soc_card *card,
567+
struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
568+
{
569+
struct snd_soc_component *component = dapm->component;
570+
struct mt8195_mt6359_rt1019_rt5682_priv *priv =
571+
snd_soc_card_get_drvdata(card);
572+
int ret;
573+
574+
/*
575+
* It's required to control mclk directly in the set_bias_level_post
576+
* function for rt5682 and rt5682s codec, or the unexpected pop happens
577+
* at the end of playback.
578+
*/
579+
if (!component ||
580+
(strcmp(component->name, RT5682_DEV0_NAME) &&
581+
strcmp(component->name, RT5682S_DEV0_NAME)))
582+
return 0;
583+
584+
585+
switch (level) {
586+
case SND_SOC_BIAS_OFF:
587+
if (!__clk_is_enabled(priv->i2so1_mclk))
588+
return 0;
589+
590+
clk_disable_unprepare(priv->i2so1_mclk);
591+
dev_dbg(card->dev, "Disable i2so1 mclk\n");
592+
break;
593+
case SND_SOC_BIAS_ON:
594+
ret = clk_prepare_enable(priv->i2so1_mclk);
595+
if (ret) {
596+
dev_err(card->dev, "Can't enable i2so1 mclk: %d\n", ret);
597+
return ret;
598+
}
599+
dev_dbg(card->dev, "Enable i2so1 mclk\n");
600+
break;
601+
default:
602+
break;
603+
}
604+
605+
return 0;
606+
}
607+
563608
enum {
564609
DAI_LINK_DL2_FE,
565610
DAI_LINK_DL3_FE,
@@ -1199,6 +1244,7 @@ static struct snd_soc_card mt8195_mt6359_rt1019_rt5682_soc_card = {
11991244
.num_dapm_widgets = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_widgets),
12001245
.dapm_routes = mt8195_mt6359_rt1019_rt5682_routes,
12011246
.num_dapm_routes = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_routes),
1247+
.set_bias_level_post = mt8195_set_bias_level_post,
12021248
};
12031249

12041250
static int mt8195_dailink_parse_of(struct snd_soc_card *card, struct device_node *np,

0 commit comments

Comments
 (0)