All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/7] ASoC: mediatek: mt8188: revise AFE driver
@ 2023-04-26  5:51 ` Trevor Wu
  0 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree

The series of patches consists of three major changes.
First, remove redundant supply for ADDA DAI dirver. Second, revise ETDM
control including APLL dynamic switch via DAPM, so APLL can be enabled
when it is really required. Finally, AFE probe function is updated. Bus
protection change was dropped at the previous patch because the dependent
change was not accepted.

Changes since v2:
  - remove required properties in dt-binding file

Changes since v1:
  - replace unnecessary dev_info with dev_dbg
  - fix dt-binging ABI breaking behavior

Trevor Wu (7):
  ASoC: mediatek: mt8188: remove supply AUDIO_HIRES
  ASoC: mediatek: mt8188: complete set_tdm_slot function
  ASoC: mediatek: mt8188: revise ETDM control flow
  ASoC: mediatek: mt8188: refine APLL control
  ASoC: mediatek: mt8188: combine afe component registration
  ASoC: mediatek: mt8188: add bus protection
  ASoC: dt-bindings: mediatek,mt8188-afe: add audio properties

 .../bindings/sound/mediatek,mt8188-afe.yaml   |  12 +-
 sound/soc/mediatek/mt8188/mt8188-afe-clk.c    | 138 ++-
 sound/soc/mediatek/mt8188/mt8188-afe-clk.h    |  11 +
 sound/soc/mediatek/mt8188/mt8188-afe-pcm.c    | 113 ++-
 sound/soc/mediatek/mt8188/mt8188-dai-adda.c   |  37 -
 sound/soc/mediatek/mt8188/mt8188-dai-etdm.c   | 922 ++++++++++--------
 sound/soc/mediatek/mt8188/mt8188-reg.h        |   2 +
 7 files changed, 751 insertions(+), 484 deletions(-)

-- 
2.18.0


^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v3 0/7] ASoC: mediatek: mt8188: revise AFE driver
@ 2023-04-26  5:51 ` Trevor Wu
  0 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree

The series of patches consists of three major changes.
First, remove redundant supply for ADDA DAI dirver. Second, revise ETDM
control including APLL dynamic switch via DAPM, so APLL can be enabled
when it is really required. Finally, AFE probe function is updated. Bus
protection change was dropped at the previous patch because the dependent
change was not accepted.

Changes since v2:
  - remove required properties in dt-binding file

Changes since v1:
  - replace unnecessary dev_info with dev_dbg
  - fix dt-binging ABI breaking behavior

Trevor Wu (7):
  ASoC: mediatek: mt8188: remove supply AUDIO_HIRES
  ASoC: mediatek: mt8188: complete set_tdm_slot function
  ASoC: mediatek: mt8188: revise ETDM control flow
  ASoC: mediatek: mt8188: refine APLL control
  ASoC: mediatek: mt8188: combine afe component registration
  ASoC: mediatek: mt8188: add bus protection
  ASoC: dt-bindings: mediatek,mt8188-afe: add audio properties

 .../bindings/sound/mediatek,mt8188-afe.yaml   |  12 +-
 sound/soc/mediatek/mt8188/mt8188-afe-clk.c    | 138 ++-
 sound/soc/mediatek/mt8188/mt8188-afe-clk.h    |  11 +
 sound/soc/mediatek/mt8188/mt8188-afe-pcm.c    | 113 ++-
 sound/soc/mediatek/mt8188/mt8188-dai-adda.c   |  37 -
 sound/soc/mediatek/mt8188/mt8188-dai-etdm.c   | 922 ++++++++++--------
 sound/soc/mediatek/mt8188/mt8188-reg.h        |   2 +
 7 files changed, 751 insertions(+), 484 deletions(-)

-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v3 1/7] ASoC: mediatek: mt8188: remove supply AUDIO_HIRES
  2023-04-26  5:51 ` Trevor Wu
@ 2023-04-26  5:51   ` Trevor Wu
  -1 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree

AUDIO_HIRES is not required in MT8188. Because top_audio_h is disabled
when hires clock is not used, set_parent is a redundant operation.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 sound/soc/mediatek/mt8188/mt8188-dai-adda.c | 37 ---------------------
 1 file changed, 37 deletions(-)

diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-adda.c b/sound/soc/mediatek/mt8188/mt8188-dai-adda.c
index d71696901553..fed9f927e623 100644
--- a/sound/soc/mediatek/mt8188/mt8188-dai-adda.c
+++ b/sound/soc/mediatek/mt8188/mt8188-dai-adda.c
@@ -18,7 +18,6 @@
 #define ADDA_HIRES_THRES 48000
 
 enum {
-	SUPPLY_SEQ_CLOCK_SEL,
 	SUPPLY_SEQ_ADDA_DL_ON,
 	SUPPLY_SEQ_ADDA_MTKAIF_CFG,
 	SUPPLY_SEQ_ADDA_UL_ON,
@@ -242,34 +241,6 @@ static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
 	return 0;
 }
 
-static int mtk_audio_hires_event(struct snd_soc_dapm_widget *w,
-				 struct snd_kcontrol *kcontrol,
-				 int event)
-{
-	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
-	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct clk *clk = afe_priv->clk[MT8188_CLK_TOP_AUDIO_H_SEL];
-	struct clk *clk_parent;
-
-	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
-		__func__, w->name, event);
-
-	switch (event) {
-	case SND_SOC_DAPM_PRE_PMU:
-		clk_parent = afe_priv->clk[MT8188_CLK_APMIXED_APLL1];
-		break;
-	case SND_SOC_DAPM_POST_PMD:
-		clk_parent = afe_priv->clk[MT8188_CLK_XTAL_26M];
-		break;
-	default:
-		return 0;
-	}
-	mt8188_afe_set_clk_parent(afe, clk, clk_parent);
-
-	return 0;
-}
-
 static int mtk_afe_adc_hires_connect(struct snd_soc_dapm_widget *source,
 				     struct snd_soc_dapm_widget *sink)
 {
@@ -364,12 +335,6 @@ static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {
 			      mtk_adda_ul_event,
 			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
-	SND_SOC_DAPM_SUPPLY_S("AUDIO_HIRES", SUPPLY_SEQ_CLOCK_SEL,
-			      SND_SOC_NOPM,
-			      0, 0,
-			      mtk_audio_hires_event,
-			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
 	SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG,
 			      SND_SOC_NOPM,
 			      0, 0,
@@ -397,7 +362,6 @@ static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
 	{"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"},
 	{"ADDA Capture", NULL, "aud_adc"},
 	{"ADDA Capture", NULL, "aud_adc_hires", mtk_afe_adc_hires_connect},
-	{"aud_adc_hires", NULL, "AUDIO_HIRES"},
 
 	{"I168", NULL, "ADDA Capture"},
 	{"I169", NULL, "ADDA Capture"},
@@ -406,7 +370,6 @@ static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
 	{"ADDA Playback", NULL, "ADDA Playback Enable"},
 	{"ADDA Playback", NULL, "aud_dac"},
 	{"ADDA Playback", NULL, "aud_dac_hires", mtk_afe_dac_hires_connect},
-	{"aud_dac_hires", NULL, "AUDIO_HIRES"},
 
 	{"DL_GAIN", NULL, "O176"},
 	{"DL_GAIN", NULL, "O177"},
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 1/7] ASoC: mediatek: mt8188: remove supply AUDIO_HIRES
  2023-04-26  5:51 ` Trevor Wu
  (?)
  (?)
@ 2023-04-26  5:51 ` Trevor Wu via Alsa-devel
  -1 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu via Alsa-devel @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree


[-- Attachment #0: Type: message/rfc822, Size: 7727 bytes --]

From: Trevor Wu <trevor.wu@mediatek.com>
To: <broonie@kernel.org>, <lgirdwood@gmail.com>, <tiwai@suse.com>, <perex@perex.cz>, <robh+dt@kernel.org>, <krzysztof.kozlowski+dt@linaro.org>, <matthias.bgg@gmail.com>, <angelogioacchino.delregno@collabora.com>
Cc: trevor.wu@mediatek.com, alsa-devel@alsa-project.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org
Subject: [PATCH v3 1/7] ASoC: mediatek: mt8188: remove supply AUDIO_HIRES
Date: Wed, 26 Apr 2023 13:51:18 +0800
Message-ID: <20230426055124.16529-2-trevor.wu@mediatek.com>

AUDIO_HIRES is not required in MT8188. Because top_audio_h is disabled
when hires clock is not used, set_parent is a redundant operation.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 sound/soc/mediatek/mt8188/mt8188-dai-adda.c | 37 ---------------------
 1 file changed, 37 deletions(-)

diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-adda.c b/sound/soc/mediatek/mt8188/mt8188-dai-adda.c
index d71696901553..fed9f927e623 100644
--- a/sound/soc/mediatek/mt8188/mt8188-dai-adda.c
+++ b/sound/soc/mediatek/mt8188/mt8188-dai-adda.c
@@ -18,7 +18,6 @@
 #define ADDA_HIRES_THRES 48000
 
 enum {
-	SUPPLY_SEQ_CLOCK_SEL,
 	SUPPLY_SEQ_ADDA_DL_ON,
 	SUPPLY_SEQ_ADDA_MTKAIF_CFG,
 	SUPPLY_SEQ_ADDA_UL_ON,
@@ -242,34 +241,6 @@ static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
 	return 0;
 }
 
-static int mtk_audio_hires_event(struct snd_soc_dapm_widget *w,
-				 struct snd_kcontrol *kcontrol,
-				 int event)
-{
-	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
-	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct clk *clk = afe_priv->clk[MT8188_CLK_TOP_AUDIO_H_SEL];
-	struct clk *clk_parent;
-
-	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
-		__func__, w->name, event);
-
-	switch (event) {
-	case SND_SOC_DAPM_PRE_PMU:
-		clk_parent = afe_priv->clk[MT8188_CLK_APMIXED_APLL1];
-		break;
-	case SND_SOC_DAPM_POST_PMD:
-		clk_parent = afe_priv->clk[MT8188_CLK_XTAL_26M];
-		break;
-	default:
-		return 0;
-	}
-	mt8188_afe_set_clk_parent(afe, clk, clk_parent);
-
-	return 0;
-}
-
 static int mtk_afe_adc_hires_connect(struct snd_soc_dapm_widget *source,
 				     struct snd_soc_dapm_widget *sink)
 {
@@ -364,12 +335,6 @@ static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {
 			      mtk_adda_ul_event,
 			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
-	SND_SOC_DAPM_SUPPLY_S("AUDIO_HIRES", SUPPLY_SEQ_CLOCK_SEL,
-			      SND_SOC_NOPM,
-			      0, 0,
-			      mtk_audio_hires_event,
-			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
 	SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG,
 			      SND_SOC_NOPM,
 			      0, 0,
@@ -397,7 +362,6 @@ static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
 	{"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"},
 	{"ADDA Capture", NULL, "aud_adc"},
 	{"ADDA Capture", NULL, "aud_adc_hires", mtk_afe_adc_hires_connect},
-	{"aud_adc_hires", NULL, "AUDIO_HIRES"},
 
 	{"I168", NULL, "ADDA Capture"},
 	{"I169", NULL, "ADDA Capture"},
@@ -406,7 +370,6 @@ static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
 	{"ADDA Playback", NULL, "ADDA Playback Enable"},
 	{"ADDA Playback", NULL, "aud_dac"},
 	{"ADDA Playback", NULL, "aud_dac_hires", mtk_afe_dac_hires_connect},
-	{"aud_dac_hires", NULL, "AUDIO_HIRES"},
 
 	{"DL_GAIN", NULL, "O176"},
 	{"DL_GAIN", NULL, "O177"},
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 1/7] ASoC: mediatek: mt8188: remove supply AUDIO_HIRES
@ 2023-04-26  5:51   ` Trevor Wu
  0 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree

AUDIO_HIRES is not required in MT8188. Because top_audio_h is disabled
when hires clock is not used, set_parent is a redundant operation.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 sound/soc/mediatek/mt8188/mt8188-dai-adda.c | 37 ---------------------
 1 file changed, 37 deletions(-)

diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-adda.c b/sound/soc/mediatek/mt8188/mt8188-dai-adda.c
index d71696901553..fed9f927e623 100644
--- a/sound/soc/mediatek/mt8188/mt8188-dai-adda.c
+++ b/sound/soc/mediatek/mt8188/mt8188-dai-adda.c
@@ -18,7 +18,6 @@
 #define ADDA_HIRES_THRES 48000
 
 enum {
-	SUPPLY_SEQ_CLOCK_SEL,
 	SUPPLY_SEQ_ADDA_DL_ON,
 	SUPPLY_SEQ_ADDA_MTKAIF_CFG,
 	SUPPLY_SEQ_ADDA_UL_ON,
@@ -242,34 +241,6 @@ static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
 	return 0;
 }
 
-static int mtk_audio_hires_event(struct snd_soc_dapm_widget *w,
-				 struct snd_kcontrol *kcontrol,
-				 int event)
-{
-	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
-	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct clk *clk = afe_priv->clk[MT8188_CLK_TOP_AUDIO_H_SEL];
-	struct clk *clk_parent;
-
-	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
-		__func__, w->name, event);
-
-	switch (event) {
-	case SND_SOC_DAPM_PRE_PMU:
-		clk_parent = afe_priv->clk[MT8188_CLK_APMIXED_APLL1];
-		break;
-	case SND_SOC_DAPM_POST_PMD:
-		clk_parent = afe_priv->clk[MT8188_CLK_XTAL_26M];
-		break;
-	default:
-		return 0;
-	}
-	mt8188_afe_set_clk_parent(afe, clk, clk_parent);
-
-	return 0;
-}
-
 static int mtk_afe_adc_hires_connect(struct snd_soc_dapm_widget *source,
 				     struct snd_soc_dapm_widget *sink)
 {
@@ -364,12 +335,6 @@ static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {
 			      mtk_adda_ul_event,
 			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
-	SND_SOC_DAPM_SUPPLY_S("AUDIO_HIRES", SUPPLY_SEQ_CLOCK_SEL,
-			      SND_SOC_NOPM,
-			      0, 0,
-			      mtk_audio_hires_event,
-			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
 	SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG,
 			      SND_SOC_NOPM,
 			      0, 0,
@@ -397,7 +362,6 @@ static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
 	{"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"},
 	{"ADDA Capture", NULL, "aud_adc"},
 	{"ADDA Capture", NULL, "aud_adc_hires", mtk_afe_adc_hires_connect},
-	{"aud_adc_hires", NULL, "AUDIO_HIRES"},
 
 	{"I168", NULL, "ADDA Capture"},
 	{"I169", NULL, "ADDA Capture"},
@@ -406,7 +370,6 @@ static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
 	{"ADDA Playback", NULL, "ADDA Playback Enable"},
 	{"ADDA Playback", NULL, "aud_dac"},
 	{"ADDA Playback", NULL, "aud_dac_hires", mtk_afe_dac_hires_connect},
-	{"aud_dac_hires", NULL, "AUDIO_HIRES"},
 
 	{"DL_GAIN", NULL, "O176"},
 	{"DL_GAIN", NULL, "O177"},
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 2/7] ASoC: mediatek: mt8188: complete set_tdm_slot function
  2023-04-26  5:51 ` Trevor Wu
@ 2023-04-26  5:51   ` Trevor Wu
  -1 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree

User can configures slot number of TDM mode via set_tdm_slot callback.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
 sound/soc/mediatek/mt8188/mt8188-dai-etdm.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
index 7a37752d4244..fddecf5bf7c6 100644
--- a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
+++ b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
@@ -1909,6 +1909,10 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
 		if (!is_valid_etdm_dai(mst_dai_id))
 			return -EINVAL;
 
+		mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
+		if (mst_etdm_data->slots)
+			channels = mst_etdm_data->slots;
+
 		ret = mtk_dai_etdm_mclk_configure(afe, mst_dai_id);
 		if (ret)
 			return ret;
@@ -1918,7 +1922,6 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
 		if (ret)
 			return ret;
 
-		mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
 		for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
 			slv_dai_id = mst_etdm_data->cowork_slv_id[i];
 			ret = mtk_dai_etdm_configure(afe, rate, channels,
@@ -1931,6 +1934,12 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
 				return ret;
 		}
 	} else {
+		if (!is_valid_etdm_dai(dai->id))
+			return -EINVAL;
+		mst_etdm_data = afe_priv->dai_priv[dai->id];
+		if (mst_etdm_data->slots)
+			channels = mst_etdm_data->slots;
+
 		ret = mtk_dai_etdm_mclk_configure(afe, dai->id);
 		if (ret)
 			return ret;
@@ -2073,10 +2082,16 @@ static int mtk_dai_etdm_set_tdm_slot(struct snd_soc_dai *dai,
 	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
 	struct mtk_dai_etdm_priv *etdm_data;
+	int dai_id;
 
-	if (!is_valid_etdm_dai(dai->id))
+	if (is_cowork_mode(dai))
+		dai_id = get_etdm_cowork_master_id(dai);
+	else
+		dai_id = dai->id;
+
+	if (!is_valid_etdm_dai(dai_id))
 		return -EINVAL;
-	etdm_data = afe_priv->dai_priv[dai->id];
+	etdm_data = afe_priv->dai_priv[dai_id];
 
 	dev_dbg(dai->dev, "%s id %d slot_width %d\n",
 		__func__, dai->id, slot_width);
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 2/7] ASoC: mediatek: mt8188: complete set_tdm_slot function
@ 2023-04-26  5:51   ` Trevor Wu
  0 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree

User can configures slot number of TDM mode via set_tdm_slot callback.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
 sound/soc/mediatek/mt8188/mt8188-dai-etdm.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
index 7a37752d4244..fddecf5bf7c6 100644
--- a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
+++ b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
@@ -1909,6 +1909,10 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
 		if (!is_valid_etdm_dai(mst_dai_id))
 			return -EINVAL;
 
+		mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
+		if (mst_etdm_data->slots)
+			channels = mst_etdm_data->slots;
+
 		ret = mtk_dai_etdm_mclk_configure(afe, mst_dai_id);
 		if (ret)
 			return ret;
@@ -1918,7 +1922,6 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
 		if (ret)
 			return ret;
 
-		mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
 		for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
 			slv_dai_id = mst_etdm_data->cowork_slv_id[i];
 			ret = mtk_dai_etdm_configure(afe, rate, channels,
@@ -1931,6 +1934,12 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
 				return ret;
 		}
 	} else {
+		if (!is_valid_etdm_dai(dai->id))
+			return -EINVAL;
+		mst_etdm_data = afe_priv->dai_priv[dai->id];
+		if (mst_etdm_data->slots)
+			channels = mst_etdm_data->slots;
+
 		ret = mtk_dai_etdm_mclk_configure(afe, dai->id);
 		if (ret)
 			return ret;
@@ -2073,10 +2082,16 @@ static int mtk_dai_etdm_set_tdm_slot(struct snd_soc_dai *dai,
 	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
 	struct mtk_dai_etdm_priv *etdm_data;
+	int dai_id;
 
-	if (!is_valid_etdm_dai(dai->id))
+	if (is_cowork_mode(dai))
+		dai_id = get_etdm_cowork_master_id(dai);
+	else
+		dai_id = dai->id;
+
+	if (!is_valid_etdm_dai(dai_id))
 		return -EINVAL;
-	etdm_data = afe_priv->dai_priv[dai->id];
+	etdm_data = afe_priv->dai_priv[dai_id];
 
 	dev_dbg(dai->dev, "%s id %d slot_width %d\n",
 		__func__, dai->id, slot_width);
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 2/7] ASoC: mediatek: mt8188: complete set_tdm_slot function
  2023-04-26  5:51 ` Trevor Wu
                   ` (3 preceding siblings ...)
  (?)
@ 2023-04-26  5:51 ` Trevor Wu via Alsa-devel
  -1 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu via Alsa-devel @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree


[-- Attachment #0: Type: message/rfc822, Size: 7148 bytes --]

From: Trevor Wu <trevor.wu@mediatek.com>
To: <broonie@kernel.org>, <lgirdwood@gmail.com>, <tiwai@suse.com>, <perex@perex.cz>, <robh+dt@kernel.org>, <krzysztof.kozlowski+dt@linaro.org>, <matthias.bgg@gmail.com>, <angelogioacchino.delregno@collabora.com>
Cc: trevor.wu@mediatek.com, alsa-devel@alsa-project.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org
Subject: [PATCH v3 2/7] ASoC: mediatek: mt8188: complete set_tdm_slot function
Date: Wed, 26 Apr 2023 13:51:19 +0800
Message-ID: <20230426055124.16529-3-trevor.wu@mediatek.com>

User can configures slot number of TDM mode via set_tdm_slot callback.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
 sound/soc/mediatek/mt8188/mt8188-dai-etdm.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
index 7a37752d4244..fddecf5bf7c6 100644
--- a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
+++ b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
@@ -1909,6 +1909,10 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
 		if (!is_valid_etdm_dai(mst_dai_id))
 			return -EINVAL;
 
+		mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
+		if (mst_etdm_data->slots)
+			channels = mst_etdm_data->slots;
+
 		ret = mtk_dai_etdm_mclk_configure(afe, mst_dai_id);
 		if (ret)
 			return ret;
@@ -1918,7 +1922,6 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
 		if (ret)
 			return ret;
 
-		mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
 		for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
 			slv_dai_id = mst_etdm_data->cowork_slv_id[i];
 			ret = mtk_dai_etdm_configure(afe, rate, channels,
@@ -1931,6 +1934,12 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
 				return ret;
 		}
 	} else {
+		if (!is_valid_etdm_dai(dai->id))
+			return -EINVAL;
+		mst_etdm_data = afe_priv->dai_priv[dai->id];
+		if (mst_etdm_data->slots)
+			channels = mst_etdm_data->slots;
+
 		ret = mtk_dai_etdm_mclk_configure(afe, dai->id);
 		if (ret)
 			return ret;
@@ -2073,10 +2082,16 @@ static int mtk_dai_etdm_set_tdm_slot(struct snd_soc_dai *dai,
 	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
 	struct mtk_dai_etdm_priv *etdm_data;
+	int dai_id;
 
-	if (!is_valid_etdm_dai(dai->id))
+	if (is_cowork_mode(dai))
+		dai_id = get_etdm_cowork_master_id(dai);
+	else
+		dai_id = dai->id;
+
+	if (!is_valid_etdm_dai(dai_id))
 		return -EINVAL;
-	etdm_data = afe_priv->dai_priv[dai->id];
+	etdm_data = afe_priv->dai_priv[dai_id];
 
 	dev_dbg(dai->dev, "%s id %d slot_width %d\n",
 		__func__, dai->id, slot_width);
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 3/7] ASoC: mediatek: mt8188: revise ETDM control flow
  2023-04-26  5:51 ` Trevor Wu
@ 2023-04-26  5:51   ` Trevor Wu
  -1 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree

Replace register controls in snd_soc_dai_ops with snd_soc_dapm_widgets.
startup, shutdown and trigger ops are removed, and create DAPM_SUPPLY
to handle mclk, clock gating and etdm enabling. Additionally, mclk setup
sequence is also updated because of new supply enabling sequence.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
 sound/soc/mediatek/mt8188/mt8188-dai-etdm.c | 790 ++++++++++----------
 sound/soc/mediatek/mt8188/mt8188-reg.h      |   2 +
 2 files changed, 406 insertions(+), 386 deletions(-)

diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
index fddecf5bf7c6..fd6e39a1e4c1 100644
--- a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
+++ b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
@@ -21,6 +21,13 @@
 #define ETDM_TO_DAI_ID(x) ((x) + MT8188_AFE_IO_ETDM_START)
 #define ENUM_TO_STR(x)	#x
 
+enum {
+	SUPPLY_SEQ_ETDM_MCLK,
+	SUPPLY_SEQ_ETDM_CG,
+	SUPPLY_SEQ_DPTX_EN,
+	SUPPLY_SEQ_ETDM_EN,
+};
+
 enum {
 	MTK_DAI_ETDM_FORMAT_I2S = 0,
 	MTK_DAI_ETDM_FORMAT_LJ,
@@ -84,7 +91,6 @@ struct mtk_dai_etdm_rate {
 };
 
 struct mtk_dai_etdm_priv {
-	unsigned int clock_mode;
 	unsigned int data_mode;
 	bool slave_mode;
 	bool lrck_inv;
@@ -100,8 +106,6 @@ struct mtk_dai_etdm_priv {
 	unsigned int cowork_slv_count;
 	int cowork_slv_id[MT8188_AFE_IO_ETDM_NUM - 1]; //dai_id
 	bool in_disable_ch[MT8188_ETDM_MAX_CHANNELS];
-	unsigned int en_ref_cnt;
-	bool is_prepared;
 };
 
 static const struct mtk_dai_etdm_rate mt8188_etdm_rates[] = {
@@ -345,14 +349,82 @@ static int mtk_dai_etdm_get_clkdiv_id_by_dai_id(int dai_id)
 	}
 }
 
+static int get_etdm_id_by_name(struct mtk_base_afe *afe,
+			       const char *name)
+{
+	if (!strncmp(name, "ETDM1_IN", strlen("ETDM1_IN")))
+		return MT8188_AFE_IO_ETDM1_IN;
+	else if (!strncmp(name, "ETDM2_IN", strlen("ETDM2_IN")))
+		return MT8188_AFE_IO_ETDM2_IN;
+	else if (!strncmp(name, "ETDM1_OUT", strlen("ETDM1_OUT")))
+		return MT8188_AFE_IO_ETDM1_OUT;
+	else if (!strncmp(name, "ETDM2_OUT", strlen("ETDM2_OUT")))
+		return MT8188_AFE_IO_ETDM2_OUT;
+	else
+		return -EINVAL;
+}
+
+static struct mtk_dai_etdm_priv *get_etdm_priv_by_name(struct mtk_base_afe *afe,
+						       const char *name)
+{
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	int dai_id = get_etdm_id_by_name(afe, name);
+
+	if (dai_id < MT8188_AFE_IO_ETDM_START ||
+	    dai_id >= MT8188_AFE_IO_ETDM_END)
+		return NULL;
+
+	return afe_priv->dai_priv[dai_id];
+}
+
 static int mtk_dai_etdm_enable_mclk(struct mtk_base_afe *afe, int dai_id)
 {
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_etdm_priv *etdm_data;
+	struct etdm_con_reg etdm_reg;
+	unsigned int val = 0;
+	unsigned int mask;
+	int clkmux_id = mtk_dai_etdm_get_clk_id_by_dai_id(dai_id);
 	int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id);
+	int apll_clk_id;
+	int apll;
+	int ret;
+
+	if (!is_valid_etdm_dai(dai_id))
+		return -EINVAL;
+	etdm_data = afe_priv->dai_priv[dai_id];
 
-	if (clkdiv_id < 0)
+	apll = etdm_data->mclk_apll;
+	apll_clk_id = mt8188_afe_get_mclk_source_clk_id(apll);
+
+	if (clkmux_id < 0 || clkdiv_id < 0)
 		return -EINVAL;
 
+	if (apll_clk_id < 0)
+		return apll_clk_id;
+
+	ret = get_etdm_reg(dai_id, &etdm_reg);
+	if (ret < 0)
+		return ret;
+
+	mask = ETDM_CON1_MCLK_OUTPUT;
+	if (etdm_data->mclk_dir == SND_SOC_CLOCK_OUT)
+		val = ETDM_CON1_MCLK_OUTPUT;
+	regmap_update_bits(afe->regmap, etdm_reg.con1, mask, val);
+
+	/* enable parent clock before select apll*/
+	mt8188_afe_enable_clk(afe, afe_priv->clk[clkmux_id]);
+
+	/* select apll */
+	ret = mt8188_afe_set_clk_parent(afe, afe_priv->clk[clkmux_id],
+					afe_priv->clk[apll_clk_id]);
+	if (ret)
+		return ret;
+
+	/* set rate */
+	ret = mt8188_afe_set_clk_rate(afe, afe_priv->clk[clkdiv_id],
+				      etdm_data->mclk_freq);
+
 	mt8188_afe_enable_clk(afe, afe_priv->clk[clkdiv_id]);
 
 	return 0;
@@ -361,12 +433,207 @@ static int mtk_dai_etdm_enable_mclk(struct mtk_base_afe *afe, int dai_id)
 static int mtk_dai_etdm_disable_mclk(struct mtk_base_afe *afe, int dai_id)
 {
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	int clkmux_id = mtk_dai_etdm_get_clk_id_by_dai_id(dai_id);
 	int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id);
 
-	if (clkdiv_id < 0)
+	if (clkmux_id < 0 || clkdiv_id < 0)
 		return -EINVAL;
 
 	mt8188_afe_disable_clk(afe, afe_priv->clk[clkdiv_id]);
+	mt8188_afe_disable_clk(afe, afe_priv->clk[clkmux_id]);
+
+	return 0;
+}
+
+static int mtk_etdm_mclk_connect(struct snd_soc_dapm_widget *source,
+				 struct snd_soc_dapm_widget *sink)
+{
+	struct snd_soc_dapm_widget *w = sink;
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_etdm_priv *etdm_priv;
+	int mclk_id;
+
+	mclk_id = get_etdm_id_by_name(afe, source->name);
+	if (mclk_id < 0) {
+		dev_dbg(afe->dev, "mclk_id < 0\n");
+		return 0;
+	}
+
+	etdm_priv = get_etdm_priv_by_name(afe, w->name);
+	if (!etdm_priv) {
+		dev_dbg(afe->dev, "etdm_priv == NULL\n");
+		return 0;
+	}
+
+	if (get_etdm_id_by_name(afe, sink->name) == mclk_id)
+		return !!(etdm_priv->mclk_freq > 0);
+
+	if (etdm_priv->cowork_source_id == mclk_id) {
+		etdm_priv = afe_priv->dai_priv[mclk_id];
+		return !!(etdm_priv->mclk_freq > 0);
+	}
+
+	return 0;
+}
+
+static int mtk_etdm_cowork_connect(struct snd_soc_dapm_widget *source,
+				   struct snd_soc_dapm_widget *sink)
+{
+	struct snd_soc_dapm_widget *w = sink;
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_etdm_priv *etdm_priv;
+	int source_id;
+	int i;
+
+	source_id = get_etdm_id_by_name(afe, source->name);
+	if (source_id < 0) {
+		dev_dbg(afe->dev, "%s() source_id < 0\n", __func__);
+		return 0;
+	}
+
+	etdm_priv = get_etdm_priv_by_name(afe, w->name);
+	if (!etdm_priv) {
+		dev_dbg(afe->dev, "%s() etdm_priv == NULL\n", __func__);
+		return 0;
+	}
+
+	if (etdm_priv->cowork_source_id != COWORK_ETDM_NONE) {
+		if (etdm_priv->cowork_source_id == source_id)
+			return 1;
+
+		etdm_priv = afe_priv->dai_priv[etdm_priv->cowork_source_id];
+		for (i = 0; i < etdm_priv->cowork_slv_count; i++) {
+			if (etdm_priv->cowork_slv_id[i] == source_id)
+				return 1;
+		}
+	} else {
+		for (i = 0; i < etdm_priv->cowork_slv_count; i++) {
+			if (etdm_priv->cowork_slv_id[i] == source_id)
+				return 1;
+		}
+	}
+
+	return 0;
+}
+
+static int mtk_etdm_mclk_event(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol,
+			       int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	int mclk_id = get_etdm_id_by_name(afe, w->name);
+
+	if (mclk_id < 0) {
+		dev_dbg(afe->dev, "%s() mclk_id < 0\n", __func__);
+		return 0;
+	}
+
+	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mtk_dai_etdm_enable_mclk(afe, mclk_id);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		mtk_dai_etdm_disable_mclk(afe, mclk_id);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mtk_dptx_mclk_event(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol,
+			       int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+
+	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mtk_dai_etdm_enable_mclk(afe, MT8188_AFE_IO_DPTX);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		mtk_dai_etdm_disable_mclk(afe, MT8188_AFE_IO_DPTX);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mtk_etdm_cg_event(struct snd_soc_dapm_widget *w,
+			     struct snd_kcontrol *kcontrol,
+			     int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	int etdm_id;
+	int cg_id;
+
+	etdm_id = get_etdm_id_by_name(afe, w->name);
+	if (etdm_id < 0) {
+		dev_dbg(afe->dev, "%s() etdm_id < 0\n", __func__);
+		return 0;
+	}
+
+	cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(etdm_id);
+	if (cg_id < 0) {
+		dev_dbg(afe->dev, "%s() cg_id < 0\n", __func__);
+		return 0;
+	}
+
+	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mtk_etdm3_cg_event(struct snd_soc_dapm_widget *w,
+			      struct snd_kcontrol *kcontrol,
+			      int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+
+	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_HDMI_OUT]);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_HDMI_OUT]);
+		break;
+	default:
+		break;
+	}
 
 	return 0;
 }
@@ -906,11 +1173,141 @@ static const struct snd_soc_dapm_widget mtk_dai_etdm_widgets[] = {
 	SND_SOC_DAPM_MUX("HDMI_CH7_MUX", SND_SOC_NOPM, 0, 0,
 			 &hdmi_ch7_mux_control),
 
+	/* mclk en */
+	SND_SOC_DAPM_SUPPLY_S("ETDM1_IN_MCLK", SUPPLY_SEQ_ETDM_MCLK,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_mclk_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM2_IN_MCLK", SUPPLY_SEQ_ETDM_MCLK,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_mclk_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM1_OUT_MCLK", SUPPLY_SEQ_ETDM_MCLK,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_mclk_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM2_OUT_MCLK", SUPPLY_SEQ_ETDM_MCLK,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_mclk_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("DPTX_MCLK", SUPPLY_SEQ_ETDM_MCLK,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_dptx_mclk_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	/* cg */
+	SND_SOC_DAPM_SUPPLY_S("ETDM1_IN_CG", SUPPLY_SEQ_ETDM_CG,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_cg_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM2_IN_CG", SUPPLY_SEQ_ETDM_CG,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_cg_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM1_OUT_CG", SUPPLY_SEQ_ETDM_CG,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_cg_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM2_OUT_CG", SUPPLY_SEQ_ETDM_CG,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_cg_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM3_OUT_CG", SUPPLY_SEQ_ETDM_CG,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm3_cg_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	/* en */
+	SND_SOC_DAPM_SUPPLY_S("ETDM1_IN_EN", SUPPLY_SEQ_ETDM_EN,
+			      ETDM_IN1_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("ETDM2_IN_EN", SUPPLY_SEQ_ETDM_EN,
+			      ETDM_IN2_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("ETDM1_OUT_EN", SUPPLY_SEQ_ETDM_EN,
+			      ETDM_OUT1_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("ETDM2_OUT_EN", SUPPLY_SEQ_ETDM_EN,
+			      ETDM_OUT2_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("ETDM3_OUT_EN", SUPPLY_SEQ_ETDM_EN,
+			      ETDM_OUT3_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("DPTX_EN", SUPPLY_SEQ_DPTX_EN,
+			      AFE_DPTX_CON, AFE_DPTX_CON_ON_SHIFT, 0, NULL, 0),
+
 	SND_SOC_DAPM_INPUT("ETDM_INPUT"),
 	SND_SOC_DAPM_OUTPUT("ETDM_OUTPUT"),
 };
 
 static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = {
+	/* mclk */
+	{"ETDM1_IN", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM1_IN", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM1_IN", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM1_IN", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect},
+
+	{"ETDM2_IN", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM2_IN", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM2_IN", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM2_IN", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect},
+
+	{"ETDM1_OUT", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM1_OUT", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM1_OUT", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM1_OUT", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect},
+
+	{"ETDM2_OUT", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM2_OUT", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM2_OUT", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM2_OUT", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect},
+
+	{"DPTX", NULL, "DPTX_MCLK"},
+
+	/* cg */
+	{"ETDM1_IN", NULL, "ETDM1_IN_CG"},
+	{"ETDM1_IN", NULL, "ETDM2_IN_CG", mtk_etdm_cowork_connect},
+	{"ETDM1_IN", NULL, "ETDM1_OUT_CG", mtk_etdm_cowork_connect},
+	{"ETDM1_IN", NULL, "ETDM2_OUT_CG", mtk_etdm_cowork_connect},
+
+	{"ETDM2_IN", NULL, "ETDM1_IN_CG", mtk_etdm_cowork_connect},
+	{"ETDM2_IN", NULL, "ETDM2_IN_CG"},
+	{"ETDM2_IN", NULL, "ETDM1_OUT_CG", mtk_etdm_cowork_connect},
+	{"ETDM2_IN", NULL, "ETDM2_OUT_CG", mtk_etdm_cowork_connect},
+
+	{"ETDM1_OUT", NULL, "ETDM1_IN_CG", mtk_etdm_cowork_connect},
+	{"ETDM1_OUT", NULL, "ETDM2_IN_CG", mtk_etdm_cowork_connect},
+	{"ETDM1_OUT", NULL, "ETDM1_OUT_CG"},
+	{"ETDM1_OUT", NULL, "ETDM2_OUT_CG", mtk_etdm_cowork_connect},
+
+	{"ETDM2_OUT", NULL, "ETDM1_IN_CG", mtk_etdm_cowork_connect},
+	{"ETDM2_OUT", NULL, "ETDM2_IN_CG", mtk_etdm_cowork_connect},
+	{"ETDM2_OUT", NULL, "ETDM1_OUT_CG", mtk_etdm_cowork_connect},
+	{"ETDM2_OUT", NULL, "ETDM2_OUT_CG"},
+
+	{"ETDM3_OUT", NULL, "ETDM3_OUT_CG"},
+	{"DPTX", NULL, "ETDM3_OUT_CG"},
+
+	/* en */
+	{"ETDM1_IN", NULL, "ETDM1_IN_EN"},
+	{"ETDM1_IN", NULL, "ETDM2_IN_EN", mtk_etdm_cowork_connect},
+	{"ETDM1_IN", NULL, "ETDM1_OUT_EN", mtk_etdm_cowork_connect},
+	{"ETDM1_IN", NULL, "ETDM2_OUT_EN", mtk_etdm_cowork_connect},
+
+	{"ETDM2_IN", NULL, "ETDM1_IN_EN", mtk_etdm_cowork_connect},
+	{"ETDM2_IN", NULL, "ETDM2_IN_EN"},
+	{"ETDM2_IN", NULL, "ETDM1_OUT_EN", mtk_etdm_cowork_connect},
+	{"ETDM2_IN", NULL, "ETDM2_OUT_EN", mtk_etdm_cowork_connect},
+
+	{"ETDM1_OUT", NULL, "ETDM1_IN_EN", mtk_etdm_cowork_connect},
+	{"ETDM1_OUT", NULL, "ETDM2_IN_EN", mtk_etdm_cowork_connect},
+	{"ETDM1_OUT", NULL, "ETDM1_OUT_EN"},
+	{"ETDM1_OUT", NULL, "ETDM2_OUT_EN", mtk_etdm_cowork_connect},
+
+	{"ETDM2_OUT", NULL, "ETDM1_IN_EN", mtk_etdm_cowork_connect},
+	{"ETDM2_OUT", NULL, "ETDM2_IN_EN", mtk_etdm_cowork_connect},
+	{"ETDM2_OUT", NULL, "ETDM1_OUT_EN", mtk_etdm_cowork_connect},
+	{"ETDM2_OUT", NULL, "ETDM2_OUT_EN"},
+
+	{"ETDM3_OUT", NULL, "ETDM3_OUT_EN"},
+	{"DPTX", NULL, "ETDM3_OUT_EN"},
+	{"DPTX", NULL, "DPTX_EN"},
+
 	{"I012", NULL, "ETDM2_IN"},
 	{"I013", NULL, "ETDM2_IN"},
 	{"I014", NULL, "ETDM2_IN"},
@@ -1163,64 +1560,6 @@ static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = {
 	{"ETDM2_IN", NULL, "ETDM_INPUT"},
 };
 
-static int mt8188_afe_enable_etdm(struct mtk_base_afe *afe, int dai_id)
-{
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *etdm_data;
-	struct etdm_con_reg etdm_reg;
-	unsigned long flags;
-	int ret = 0;
-
-	if (!is_valid_etdm_dai(dai_id))
-		return -EINVAL;
-	etdm_data = afe_priv->dai_priv[dai_id];
-
-	dev_dbg(afe->dev, "%s [%d]%d\n", __func__, dai_id, etdm_data->en_ref_cnt);
-	spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
-	etdm_data->en_ref_cnt++;
-	if (etdm_data->en_ref_cnt == 1) {
-		ret = get_etdm_reg(dai_id, &etdm_reg);
-		if (ret < 0)
-			goto out;
-
-		regmap_set_bits(afe->regmap, etdm_reg.con0, ETDM_CON0_EN);
-	}
-
-out:
-	spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
-	return ret;
-}
-
-static int mt8188_afe_disable_etdm(struct mtk_base_afe *afe, int dai_id)
-{
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *etdm_data;
-	struct etdm_con_reg etdm_reg;
-	unsigned long flags;
-	int ret = 0;
-
-	if (!is_valid_etdm_dai(dai_id))
-		return -EINVAL;
-	etdm_data = afe_priv->dai_priv[dai_id];
-
-	dev_dbg(afe->dev, "%s [%d]%d\n", __func__, dai_id, etdm_data->en_ref_cnt);
-	spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
-	if (etdm_data->en_ref_cnt > 0) {
-		etdm_data->en_ref_cnt--;
-		if (etdm_data->en_ref_cnt == 0) {
-			ret = get_etdm_reg(dai_id, &etdm_reg);
-			if (ret < 0)
-				goto out;
-			regmap_clear_bits(afe->regmap, etdm_reg.con0,
-					  ETDM_CON0_EN);
-		}
-	}
-
-out:
-	spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
-	return ret;
-}
-
 static int etdm_cowork_slv_sel(int id, int slave_mode)
 {
 	if (slave_mode) {
@@ -1408,121 +1747,6 @@ static int mt8188_etdm_sync_mode_configure(struct mtk_base_afe *afe, int dai_id)
 }
 
 /* dai ops */
-static int mtk_dai_etdm_startup(struct snd_pcm_substream *substream,
-				struct snd_soc_dai *dai)
-{
-	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *mst_etdm_data;
-	int mst_dai_id;
-	int slv_dai_id;
-	int cg_id;
-	int i;
-
-	if (is_cowork_mode(dai)) {
-		mst_dai_id = get_etdm_cowork_master_id(dai);
-		if (!is_valid_etdm_dai(mst_dai_id))
-			return -EINVAL;
-		mtk_dai_etdm_enable_mclk(afe, mst_dai_id);
-
-		cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(mst_dai_id);
-		if (cg_id >= 0)
-			mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]);
-
-		mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
-
-		for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
-			slv_dai_id = mst_etdm_data->cowork_slv_id[i];
-			cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(slv_dai_id);
-			if (cg_id >= 0)
-				mt8188_afe_enable_clk(afe,
-						      afe_priv->clk[cg_id]);
-		}
-	} else {
-		mtk_dai_etdm_enable_mclk(afe, dai->id);
-
-		cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
-		if (cg_id >= 0)
-			mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]);
-	}
-
-	return 0;
-}
-
-static void mtk_dai_etdm_shutdown(struct snd_pcm_substream *substream,
-				  struct snd_soc_dai *dai)
-{
-	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *mst_etdm_data;
-	int mst_dai_id;
-	int slv_dai_id;
-	int cg_id;
-	int ret;
-	int i;
-
-	if (!is_valid_etdm_dai(dai->id))
-		return;
-	mst_etdm_data = afe_priv->dai_priv[dai->id];
-
-	dev_dbg(afe->dev, "%s(), dai id %d, prepared %d\n", __func__, dai->id,
-		mst_etdm_data->is_prepared);
-
-	if (mst_etdm_data->is_prepared) {
-		mst_etdm_data->is_prepared = false;
-
-		if (is_cowork_mode(dai)) {
-			mst_dai_id = get_etdm_cowork_master_id(dai);
-			if (!is_valid_etdm_dai(mst_dai_id))
-				return;
-			mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
-
-			ret = mt8188_afe_disable_etdm(afe, mst_dai_id);
-			if (ret)
-				dev_dbg(afe->dev, "%s disable %d failed\n",
-					__func__, mst_dai_id);
-
-			for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
-				slv_dai_id = mst_etdm_data->cowork_slv_id[i];
-				ret = mt8188_afe_disable_etdm(afe, slv_dai_id);
-				if (ret)
-					dev_dbg(afe->dev, "%s disable %d failed\n",
-						__func__, slv_dai_id);
-			}
-		} else {
-			ret = mt8188_afe_disable_etdm(afe, dai->id);
-			if (ret)
-				dev_dbg(afe->dev, "%s disable %d failed\n",
-					__func__, dai->id);
-		}
-	}
-
-	if (is_cowork_mode(dai)) {
-		mst_dai_id = get_etdm_cowork_master_id(dai);
-		if (!is_valid_etdm_dai(mst_dai_id))
-			return;
-		cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(mst_dai_id);
-		if (cg_id >= 0)
-			mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]);
-
-		mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
-		for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
-			slv_dai_id = mst_etdm_data->cowork_slv_id[i];
-			cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(slv_dai_id);
-			if (cg_id >= 0)
-				mt8188_afe_disable_clk(afe,
-						       afe_priv->clk[cg_id]);
-		}
-		mtk_dai_etdm_disable_mclk(afe, mst_dai_id);
-	} else {
-		cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
-		if (cg_id >= 0)
-			mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]);
-
-		mtk_dai_etdm_disable_mclk(afe, dai->id);
-	}
-}
-
 static int mtk_dai_etdm_fifo_mode(struct mtk_base_afe *afe,
 				  int dai_id, unsigned int rate)
 {
@@ -1759,60 +1983,6 @@ static int mtk_dai_etdm_out_configure(struct mtk_base_afe *afe,
 	return 0;
 }
 
-static int mtk_dai_etdm_mclk_configure(struct mtk_base_afe *afe, int dai_id)
-{
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *etdm_data;
-	struct etdm_con_reg etdm_reg;
-	int clk_id = mtk_dai_etdm_get_clk_id_by_dai_id(dai_id);
-	int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id);
-	int apll_clk_id;
-	int apll;
-	int ret;
-
-	if (clk_id < 0 || clkdiv_id < 0)
-		return -EINVAL;
-
-	if (!is_valid_etdm_dai(dai_id))
-		return -EINVAL;
-	etdm_data = afe_priv->dai_priv[dai_id];
-
-	ret = get_etdm_reg(dai_id, &etdm_reg);
-	if (ret < 0)
-		return ret;
-
-	if (etdm_data->mclk_dir == SND_SOC_CLOCK_OUT)
-		regmap_set_bits(afe->regmap, etdm_reg.con1,
-				ETDM_CON1_MCLK_OUTPUT);
-	else
-		regmap_clear_bits(afe->regmap, etdm_reg.con1,
-				  ETDM_CON1_MCLK_OUTPUT);
-
-	if (etdm_data->mclk_freq) {
-		apll = etdm_data->mclk_apll;
-		apll_clk_id = mt8188_afe_get_mclk_source_clk_id(apll);
-		if (apll_clk_id < 0)
-			return apll_clk_id;
-
-		/* select apll */
-		ret = mt8188_afe_set_clk_parent(afe, afe_priv->clk[clk_id],
-						afe_priv->clk[apll_clk_id]);
-		if (ret)
-			return ret;
-
-		/* set rate */
-		ret = mt8188_afe_set_clk_rate(afe, afe_priv->clk[clkdiv_id],
-					      etdm_data->mclk_freq);
-		if (ret)
-			return ret;
-	} else {
-		if (etdm_data->mclk_dir == SND_SOC_CLOCK_OUT)
-			dev_dbg(afe->dev, "%s mclk freq = 0\n", __func__);
-	}
-
-	return 0;
-}
-
 static int mtk_dai_etdm_configure(struct mtk_base_afe *afe,
 				  unsigned int rate,
 				  unsigned int channels,
@@ -1839,10 +2009,10 @@ static int mtk_dai_etdm_configure(struct mtk_base_afe *afe,
 	if (ret < 0)
 		return ret;
 
-	dev_dbg(afe->dev, "%s fmt %u data %u lrck %d-%u bck %d, clock %u slv %u\n",
+	dev_dbg(afe->dev, "%s fmt %u data %u lrck %d-%u bck %d, slv %u\n",
 		__func__, etdm_data->format, etdm_data->data_mode,
 		etdm_data->lrck_inv, etdm_data->lrck_width, etdm_data->bck_inv,
-		etdm_data->clock_mode, etdm_data->slave_mode);
+		etdm_data->slave_mode);
 	dev_dbg(afe->dev, "%s rate %u channels %u bitwidth %u, id %d\n",
 		__func__, rate, channels, bit_width, dai_id);
 
@@ -1913,10 +2083,6 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
 		if (mst_etdm_data->slots)
 			channels = mst_etdm_data->slots;
 
-		ret = mtk_dai_etdm_mclk_configure(afe, mst_dai_id);
-		if (ret)
-			return ret;
-
 		ret = mtk_dai_etdm_configure(afe, rate, channels,
 					     bit_width, mst_dai_id);
 		if (ret)
@@ -1940,10 +2106,6 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
 		if (mst_etdm_data->slots)
 			channels = mst_etdm_data->slots;
 
-		ret = mtk_dai_etdm_mclk_configure(afe, dai->id);
-		if (ret)
-			return ret;
-
 		ret = mtk_dai_etdm_configure(afe, rate, channels,
 					     bit_width, dai->id);
 		if (ret)
@@ -1953,66 +2115,6 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
 	return 0;
 }
 
-static int mtk_dai_etdm_prepare(struct snd_pcm_substream *substream,
-				struct snd_soc_dai *dai)
-{
-	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *mst_etdm_data;
-	int mst_dai_id;
-	int slv_dai_id;
-	int ret;
-	int i;
-
-	if (!is_valid_etdm_dai(dai->id))
-		return -EINVAL;
-	mst_etdm_data = afe_priv->dai_priv[dai->id];
-
-	dev_dbg(afe->dev, "%s(), dai id %d, prepared %d\n", __func__, dai->id,
-		mst_etdm_data->is_prepared);
-
-	if (mst_etdm_data->is_prepared)
-		return 0;
-
-	mst_etdm_data->is_prepared = true;
-
-	if (is_cowork_mode(dai)) {
-		mst_dai_id = get_etdm_cowork_master_id(dai);
-		if (!is_valid_etdm_dai(mst_dai_id))
-			return -EINVAL;
-		mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
-
-		for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
-			slv_dai_id = mst_etdm_data->cowork_slv_id[i];
-			ret = mt8188_afe_enable_etdm(afe, slv_dai_id);
-			if (ret) {
-				dev_dbg(afe->dev, "%s enable %d failed\n",
-					__func__, slv_dai_id);
-
-				return ret;
-			}
-		}
-
-		ret = mt8188_afe_enable_etdm(afe, mst_dai_id);
-		if (ret) {
-			dev_dbg(afe->dev, "%s enable %d failed\n",
-				__func__, mst_dai_id);
-
-			return ret;
-		}
-	} else {
-		ret = mt8188_afe_enable_etdm(afe, dai->id);
-		if (ret) {
-			dev_dbg(afe->dev, "%s enable %d failed\n",
-				__func__, dai->id);
-
-			return ret;
-		}
-	}
-
-	return 0;
-}
-
 static int mtk_dai_etdm_cal_mclk(struct mtk_base_afe *afe, int freq, int dai_id)
 {
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
@@ -2166,53 +2268,6 @@ static int mtk_dai_etdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	return 0;
 }
 
-static int mtk_dai_hdmitx_dptx_startup(struct snd_pcm_substream *substream,
-				       struct snd_soc_dai *dai)
-{
-	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	int cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
-
-	if (cg_id >= 0)
-		mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]);
-
-	mtk_dai_etdm_enable_mclk(afe, dai->id);
-
-	return 0;
-}
-
-static void mtk_dai_hdmitx_dptx_shutdown(struct snd_pcm_substream *substream,
-					 struct snd_soc_dai *dai)
-{
-	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	int cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
-	struct mtk_dai_etdm_priv *etdm_data;
-	int ret;
-
-	if (!is_valid_etdm_dai(dai->id))
-		return;
-	etdm_data = afe_priv->dai_priv[dai->id];
-
-	if (etdm_data->is_prepared) {
-		etdm_data->is_prepared = false;
-		/* disable etdm_out3 */
-		ret = mt8188_afe_disable_etdm(afe, dai->id);
-		if (ret)
-			dev_dbg(afe->dev, "%s disable failed\n", __func__);
-
-		/* disable dptx interface */
-		if (dai->id == MT8188_AFE_IO_DPTX)
-			regmap_clear_bits(afe->regmap, AFE_DPTX_CON,
-					  AFE_DPTX_CON_ON);
-	}
-
-	mtk_dai_etdm_disable_mclk(afe, dai->id);
-
-	if (cg_id >= 0)
-		mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]);
-}
-
 static unsigned int mtk_dai_get_dptx_ch_en(unsigned int channel)
 {
 	switch (channel) {
@@ -2280,42 +2335,11 @@ static int mtk_dai_hdmitx_dptx_hw_params(struct snd_pcm_substream *substream,
 		etdm_data->data_mode = MTK_DAI_ETDM_DATA_MULTI_PIN;
 	}
 
-	ret = mtk_dai_etdm_mclk_configure(afe, dai->id);
-	if (ret)
-		return ret;
-
 	ret = mtk_dai_etdm_configure(afe, rate, channels, width, dai->id);
 
 	return ret;
 }
 
-static int mtk_dai_hdmitx_dptx_prepare(struct snd_pcm_substream *substream,
-				       struct snd_soc_dai *dai)
-{
-	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *etdm_data;
-
-	if (!is_valid_etdm_dai(dai->id))
-		return -EINVAL;
-	etdm_data = afe_priv->dai_priv[dai->id];
-
-	dev_dbg(afe->dev, "%s(), dai id %d, prepared %d\n", __func__, dai->id,
-		etdm_data->is_prepared);
-
-	if (etdm_data->is_prepared)
-		return 0;
-
-	etdm_data->is_prepared = true;
-
-	/* enable dptx interface */
-	if (dai->id == MT8188_AFE_IO_DPTX)
-		regmap_set_bits(afe->regmap, AFE_DPTX_CON, AFE_DPTX_CON_ON);
-
-	/* enable etdm_out3 */
-	return mt8188_afe_enable_etdm(afe, dai->id);
-}
-
 static int mtk_dai_hdmitx_dptx_set_sysclk(struct snd_soc_dai *dai,
 					  int clk_id,
 					  unsigned int freq,
@@ -2337,20 +2361,14 @@ static int mtk_dai_hdmitx_dptx_set_sysclk(struct snd_soc_dai *dai,
 }
 
 static const struct snd_soc_dai_ops mtk_dai_etdm_ops = {
-	.startup = mtk_dai_etdm_startup,
-	.shutdown = mtk_dai_etdm_shutdown,
 	.hw_params = mtk_dai_etdm_hw_params,
-	.prepare = mtk_dai_etdm_prepare,
 	.set_sysclk = mtk_dai_etdm_set_sysclk,
 	.set_fmt = mtk_dai_etdm_set_fmt,
 	.set_tdm_slot = mtk_dai_etdm_set_tdm_slot,
 };
 
 static const struct snd_soc_dai_ops mtk_dai_hdmitx_dptx_ops = {
-	.startup	= mtk_dai_hdmitx_dptx_startup,
-	.shutdown	= mtk_dai_hdmitx_dptx_shutdown,
 	.hw_params	= mtk_dai_hdmitx_dptx_hw_params,
-	.prepare	= mtk_dai_hdmitx_dptx_prepare,
 	.set_sysclk	= mtk_dai_hdmitx_dptx_set_sysclk,
 	.set_fmt	= mtk_dai_etdm_set_fmt,
 };
diff --git a/sound/soc/mediatek/mt8188/mt8188-reg.h b/sound/soc/mediatek/mt8188/mt8188-reg.h
index 51cd1a83dd9d..bdd885419ff3 100644
--- a/sound/soc/mediatek/mt8188/mt8188-reg.h
+++ b/sound/soc/mediatek/mt8188/mt8188-reg.h
@@ -3007,6 +3007,7 @@
 #define ETDM_CON0_SLAVE_MODE		BIT(5)
 #define ETDM_CON0_SYNC_MODE		BIT(1)
 #define ETDM_CON0_EN			BIT(0)
+#define ETDM_CON0_EN_SHIFT		0
 
 #define ETDM_OUT_CON0_RELATCH_DOMAIN_MASK	GENMASK(29, 28)
 
@@ -3108,6 +3109,7 @@
 #define AFE_DPTX_CON_CH_NUM_8CH		(0x1 << 1)
 #define AFE_DPTX_CON_CH_NUM_MASK	BIT(1)
 #define AFE_DPTX_CON_ON			BIT(0)
+#define AFE_DPTX_CON_ON_SHIFT		0
 
 /* AFE_ADDA_DL_SRC2_CON0 */
 #define DL_2_INPUT_MODE_CTL_MASK	GENMASK(31, 28)
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 3/7] ASoC: mediatek: mt8188: revise ETDM control flow
@ 2023-04-26  5:51   ` Trevor Wu
  0 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree

Replace register controls in snd_soc_dai_ops with snd_soc_dapm_widgets.
startup, shutdown and trigger ops are removed, and create DAPM_SUPPLY
to handle mclk, clock gating and etdm enabling. Additionally, mclk setup
sequence is also updated because of new supply enabling sequence.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
 sound/soc/mediatek/mt8188/mt8188-dai-etdm.c | 790 ++++++++++----------
 sound/soc/mediatek/mt8188/mt8188-reg.h      |   2 +
 2 files changed, 406 insertions(+), 386 deletions(-)

diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
index fddecf5bf7c6..fd6e39a1e4c1 100644
--- a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
+++ b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
@@ -21,6 +21,13 @@
 #define ETDM_TO_DAI_ID(x) ((x) + MT8188_AFE_IO_ETDM_START)
 #define ENUM_TO_STR(x)	#x
 
+enum {
+	SUPPLY_SEQ_ETDM_MCLK,
+	SUPPLY_SEQ_ETDM_CG,
+	SUPPLY_SEQ_DPTX_EN,
+	SUPPLY_SEQ_ETDM_EN,
+};
+
 enum {
 	MTK_DAI_ETDM_FORMAT_I2S = 0,
 	MTK_DAI_ETDM_FORMAT_LJ,
@@ -84,7 +91,6 @@ struct mtk_dai_etdm_rate {
 };
 
 struct mtk_dai_etdm_priv {
-	unsigned int clock_mode;
 	unsigned int data_mode;
 	bool slave_mode;
 	bool lrck_inv;
@@ -100,8 +106,6 @@ struct mtk_dai_etdm_priv {
 	unsigned int cowork_slv_count;
 	int cowork_slv_id[MT8188_AFE_IO_ETDM_NUM - 1]; //dai_id
 	bool in_disable_ch[MT8188_ETDM_MAX_CHANNELS];
-	unsigned int en_ref_cnt;
-	bool is_prepared;
 };
 
 static const struct mtk_dai_etdm_rate mt8188_etdm_rates[] = {
@@ -345,14 +349,82 @@ static int mtk_dai_etdm_get_clkdiv_id_by_dai_id(int dai_id)
 	}
 }
 
+static int get_etdm_id_by_name(struct mtk_base_afe *afe,
+			       const char *name)
+{
+	if (!strncmp(name, "ETDM1_IN", strlen("ETDM1_IN")))
+		return MT8188_AFE_IO_ETDM1_IN;
+	else if (!strncmp(name, "ETDM2_IN", strlen("ETDM2_IN")))
+		return MT8188_AFE_IO_ETDM2_IN;
+	else if (!strncmp(name, "ETDM1_OUT", strlen("ETDM1_OUT")))
+		return MT8188_AFE_IO_ETDM1_OUT;
+	else if (!strncmp(name, "ETDM2_OUT", strlen("ETDM2_OUT")))
+		return MT8188_AFE_IO_ETDM2_OUT;
+	else
+		return -EINVAL;
+}
+
+static struct mtk_dai_etdm_priv *get_etdm_priv_by_name(struct mtk_base_afe *afe,
+						       const char *name)
+{
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	int dai_id = get_etdm_id_by_name(afe, name);
+
+	if (dai_id < MT8188_AFE_IO_ETDM_START ||
+	    dai_id >= MT8188_AFE_IO_ETDM_END)
+		return NULL;
+
+	return afe_priv->dai_priv[dai_id];
+}
+
 static int mtk_dai_etdm_enable_mclk(struct mtk_base_afe *afe, int dai_id)
 {
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_etdm_priv *etdm_data;
+	struct etdm_con_reg etdm_reg;
+	unsigned int val = 0;
+	unsigned int mask;
+	int clkmux_id = mtk_dai_etdm_get_clk_id_by_dai_id(dai_id);
 	int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id);
+	int apll_clk_id;
+	int apll;
+	int ret;
+
+	if (!is_valid_etdm_dai(dai_id))
+		return -EINVAL;
+	etdm_data = afe_priv->dai_priv[dai_id];
 
-	if (clkdiv_id < 0)
+	apll = etdm_data->mclk_apll;
+	apll_clk_id = mt8188_afe_get_mclk_source_clk_id(apll);
+
+	if (clkmux_id < 0 || clkdiv_id < 0)
 		return -EINVAL;
 
+	if (apll_clk_id < 0)
+		return apll_clk_id;
+
+	ret = get_etdm_reg(dai_id, &etdm_reg);
+	if (ret < 0)
+		return ret;
+
+	mask = ETDM_CON1_MCLK_OUTPUT;
+	if (etdm_data->mclk_dir == SND_SOC_CLOCK_OUT)
+		val = ETDM_CON1_MCLK_OUTPUT;
+	regmap_update_bits(afe->regmap, etdm_reg.con1, mask, val);
+
+	/* enable parent clock before select apll*/
+	mt8188_afe_enable_clk(afe, afe_priv->clk[clkmux_id]);
+
+	/* select apll */
+	ret = mt8188_afe_set_clk_parent(afe, afe_priv->clk[clkmux_id],
+					afe_priv->clk[apll_clk_id]);
+	if (ret)
+		return ret;
+
+	/* set rate */
+	ret = mt8188_afe_set_clk_rate(afe, afe_priv->clk[clkdiv_id],
+				      etdm_data->mclk_freq);
+
 	mt8188_afe_enable_clk(afe, afe_priv->clk[clkdiv_id]);
 
 	return 0;
@@ -361,12 +433,207 @@ static int mtk_dai_etdm_enable_mclk(struct mtk_base_afe *afe, int dai_id)
 static int mtk_dai_etdm_disable_mclk(struct mtk_base_afe *afe, int dai_id)
 {
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	int clkmux_id = mtk_dai_etdm_get_clk_id_by_dai_id(dai_id);
 	int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id);
 
-	if (clkdiv_id < 0)
+	if (clkmux_id < 0 || clkdiv_id < 0)
 		return -EINVAL;
 
 	mt8188_afe_disable_clk(afe, afe_priv->clk[clkdiv_id]);
+	mt8188_afe_disable_clk(afe, afe_priv->clk[clkmux_id]);
+
+	return 0;
+}
+
+static int mtk_etdm_mclk_connect(struct snd_soc_dapm_widget *source,
+				 struct snd_soc_dapm_widget *sink)
+{
+	struct snd_soc_dapm_widget *w = sink;
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_etdm_priv *etdm_priv;
+	int mclk_id;
+
+	mclk_id = get_etdm_id_by_name(afe, source->name);
+	if (mclk_id < 0) {
+		dev_dbg(afe->dev, "mclk_id < 0\n");
+		return 0;
+	}
+
+	etdm_priv = get_etdm_priv_by_name(afe, w->name);
+	if (!etdm_priv) {
+		dev_dbg(afe->dev, "etdm_priv == NULL\n");
+		return 0;
+	}
+
+	if (get_etdm_id_by_name(afe, sink->name) == mclk_id)
+		return !!(etdm_priv->mclk_freq > 0);
+
+	if (etdm_priv->cowork_source_id == mclk_id) {
+		etdm_priv = afe_priv->dai_priv[mclk_id];
+		return !!(etdm_priv->mclk_freq > 0);
+	}
+
+	return 0;
+}
+
+static int mtk_etdm_cowork_connect(struct snd_soc_dapm_widget *source,
+				   struct snd_soc_dapm_widget *sink)
+{
+	struct snd_soc_dapm_widget *w = sink;
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_etdm_priv *etdm_priv;
+	int source_id;
+	int i;
+
+	source_id = get_etdm_id_by_name(afe, source->name);
+	if (source_id < 0) {
+		dev_dbg(afe->dev, "%s() source_id < 0\n", __func__);
+		return 0;
+	}
+
+	etdm_priv = get_etdm_priv_by_name(afe, w->name);
+	if (!etdm_priv) {
+		dev_dbg(afe->dev, "%s() etdm_priv == NULL\n", __func__);
+		return 0;
+	}
+
+	if (etdm_priv->cowork_source_id != COWORK_ETDM_NONE) {
+		if (etdm_priv->cowork_source_id == source_id)
+			return 1;
+
+		etdm_priv = afe_priv->dai_priv[etdm_priv->cowork_source_id];
+		for (i = 0; i < etdm_priv->cowork_slv_count; i++) {
+			if (etdm_priv->cowork_slv_id[i] == source_id)
+				return 1;
+		}
+	} else {
+		for (i = 0; i < etdm_priv->cowork_slv_count; i++) {
+			if (etdm_priv->cowork_slv_id[i] == source_id)
+				return 1;
+		}
+	}
+
+	return 0;
+}
+
+static int mtk_etdm_mclk_event(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol,
+			       int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	int mclk_id = get_etdm_id_by_name(afe, w->name);
+
+	if (mclk_id < 0) {
+		dev_dbg(afe->dev, "%s() mclk_id < 0\n", __func__);
+		return 0;
+	}
+
+	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mtk_dai_etdm_enable_mclk(afe, mclk_id);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		mtk_dai_etdm_disable_mclk(afe, mclk_id);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mtk_dptx_mclk_event(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol,
+			       int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+
+	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mtk_dai_etdm_enable_mclk(afe, MT8188_AFE_IO_DPTX);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		mtk_dai_etdm_disable_mclk(afe, MT8188_AFE_IO_DPTX);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mtk_etdm_cg_event(struct snd_soc_dapm_widget *w,
+			     struct snd_kcontrol *kcontrol,
+			     int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	int etdm_id;
+	int cg_id;
+
+	etdm_id = get_etdm_id_by_name(afe, w->name);
+	if (etdm_id < 0) {
+		dev_dbg(afe->dev, "%s() etdm_id < 0\n", __func__);
+		return 0;
+	}
+
+	cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(etdm_id);
+	if (cg_id < 0) {
+		dev_dbg(afe->dev, "%s() cg_id < 0\n", __func__);
+		return 0;
+	}
+
+	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mtk_etdm3_cg_event(struct snd_soc_dapm_widget *w,
+			      struct snd_kcontrol *kcontrol,
+			      int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+
+	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_HDMI_OUT]);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_HDMI_OUT]);
+		break;
+	default:
+		break;
+	}
 
 	return 0;
 }
@@ -906,11 +1173,141 @@ static const struct snd_soc_dapm_widget mtk_dai_etdm_widgets[] = {
 	SND_SOC_DAPM_MUX("HDMI_CH7_MUX", SND_SOC_NOPM, 0, 0,
 			 &hdmi_ch7_mux_control),
 
+	/* mclk en */
+	SND_SOC_DAPM_SUPPLY_S("ETDM1_IN_MCLK", SUPPLY_SEQ_ETDM_MCLK,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_mclk_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM2_IN_MCLK", SUPPLY_SEQ_ETDM_MCLK,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_mclk_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM1_OUT_MCLK", SUPPLY_SEQ_ETDM_MCLK,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_mclk_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM2_OUT_MCLK", SUPPLY_SEQ_ETDM_MCLK,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_mclk_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("DPTX_MCLK", SUPPLY_SEQ_ETDM_MCLK,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_dptx_mclk_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	/* cg */
+	SND_SOC_DAPM_SUPPLY_S("ETDM1_IN_CG", SUPPLY_SEQ_ETDM_CG,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_cg_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM2_IN_CG", SUPPLY_SEQ_ETDM_CG,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_cg_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM1_OUT_CG", SUPPLY_SEQ_ETDM_CG,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_cg_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM2_OUT_CG", SUPPLY_SEQ_ETDM_CG,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_cg_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM3_OUT_CG", SUPPLY_SEQ_ETDM_CG,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm3_cg_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	/* en */
+	SND_SOC_DAPM_SUPPLY_S("ETDM1_IN_EN", SUPPLY_SEQ_ETDM_EN,
+			      ETDM_IN1_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("ETDM2_IN_EN", SUPPLY_SEQ_ETDM_EN,
+			      ETDM_IN2_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("ETDM1_OUT_EN", SUPPLY_SEQ_ETDM_EN,
+			      ETDM_OUT1_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("ETDM2_OUT_EN", SUPPLY_SEQ_ETDM_EN,
+			      ETDM_OUT2_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("ETDM3_OUT_EN", SUPPLY_SEQ_ETDM_EN,
+			      ETDM_OUT3_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("DPTX_EN", SUPPLY_SEQ_DPTX_EN,
+			      AFE_DPTX_CON, AFE_DPTX_CON_ON_SHIFT, 0, NULL, 0),
+
 	SND_SOC_DAPM_INPUT("ETDM_INPUT"),
 	SND_SOC_DAPM_OUTPUT("ETDM_OUTPUT"),
 };
 
 static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = {
+	/* mclk */
+	{"ETDM1_IN", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM1_IN", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM1_IN", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM1_IN", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect},
+
+	{"ETDM2_IN", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM2_IN", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM2_IN", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM2_IN", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect},
+
+	{"ETDM1_OUT", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM1_OUT", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM1_OUT", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM1_OUT", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect},
+
+	{"ETDM2_OUT", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM2_OUT", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM2_OUT", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM2_OUT", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect},
+
+	{"DPTX", NULL, "DPTX_MCLK"},
+
+	/* cg */
+	{"ETDM1_IN", NULL, "ETDM1_IN_CG"},
+	{"ETDM1_IN", NULL, "ETDM2_IN_CG", mtk_etdm_cowork_connect},
+	{"ETDM1_IN", NULL, "ETDM1_OUT_CG", mtk_etdm_cowork_connect},
+	{"ETDM1_IN", NULL, "ETDM2_OUT_CG", mtk_etdm_cowork_connect},
+
+	{"ETDM2_IN", NULL, "ETDM1_IN_CG", mtk_etdm_cowork_connect},
+	{"ETDM2_IN", NULL, "ETDM2_IN_CG"},
+	{"ETDM2_IN", NULL, "ETDM1_OUT_CG", mtk_etdm_cowork_connect},
+	{"ETDM2_IN", NULL, "ETDM2_OUT_CG", mtk_etdm_cowork_connect},
+
+	{"ETDM1_OUT", NULL, "ETDM1_IN_CG", mtk_etdm_cowork_connect},
+	{"ETDM1_OUT", NULL, "ETDM2_IN_CG", mtk_etdm_cowork_connect},
+	{"ETDM1_OUT", NULL, "ETDM1_OUT_CG"},
+	{"ETDM1_OUT", NULL, "ETDM2_OUT_CG", mtk_etdm_cowork_connect},
+
+	{"ETDM2_OUT", NULL, "ETDM1_IN_CG", mtk_etdm_cowork_connect},
+	{"ETDM2_OUT", NULL, "ETDM2_IN_CG", mtk_etdm_cowork_connect},
+	{"ETDM2_OUT", NULL, "ETDM1_OUT_CG", mtk_etdm_cowork_connect},
+	{"ETDM2_OUT", NULL, "ETDM2_OUT_CG"},
+
+	{"ETDM3_OUT", NULL, "ETDM3_OUT_CG"},
+	{"DPTX", NULL, "ETDM3_OUT_CG"},
+
+	/* en */
+	{"ETDM1_IN", NULL, "ETDM1_IN_EN"},
+	{"ETDM1_IN", NULL, "ETDM2_IN_EN", mtk_etdm_cowork_connect},
+	{"ETDM1_IN", NULL, "ETDM1_OUT_EN", mtk_etdm_cowork_connect},
+	{"ETDM1_IN", NULL, "ETDM2_OUT_EN", mtk_etdm_cowork_connect},
+
+	{"ETDM2_IN", NULL, "ETDM1_IN_EN", mtk_etdm_cowork_connect},
+	{"ETDM2_IN", NULL, "ETDM2_IN_EN"},
+	{"ETDM2_IN", NULL, "ETDM1_OUT_EN", mtk_etdm_cowork_connect},
+	{"ETDM2_IN", NULL, "ETDM2_OUT_EN", mtk_etdm_cowork_connect},
+
+	{"ETDM1_OUT", NULL, "ETDM1_IN_EN", mtk_etdm_cowork_connect},
+	{"ETDM1_OUT", NULL, "ETDM2_IN_EN", mtk_etdm_cowork_connect},
+	{"ETDM1_OUT", NULL, "ETDM1_OUT_EN"},
+	{"ETDM1_OUT", NULL, "ETDM2_OUT_EN", mtk_etdm_cowork_connect},
+
+	{"ETDM2_OUT", NULL, "ETDM1_IN_EN", mtk_etdm_cowork_connect},
+	{"ETDM2_OUT", NULL, "ETDM2_IN_EN", mtk_etdm_cowork_connect},
+	{"ETDM2_OUT", NULL, "ETDM1_OUT_EN", mtk_etdm_cowork_connect},
+	{"ETDM2_OUT", NULL, "ETDM2_OUT_EN"},
+
+	{"ETDM3_OUT", NULL, "ETDM3_OUT_EN"},
+	{"DPTX", NULL, "ETDM3_OUT_EN"},
+	{"DPTX", NULL, "DPTX_EN"},
+
 	{"I012", NULL, "ETDM2_IN"},
 	{"I013", NULL, "ETDM2_IN"},
 	{"I014", NULL, "ETDM2_IN"},
@@ -1163,64 +1560,6 @@ static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = {
 	{"ETDM2_IN", NULL, "ETDM_INPUT"},
 };
 
-static int mt8188_afe_enable_etdm(struct mtk_base_afe *afe, int dai_id)
-{
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *etdm_data;
-	struct etdm_con_reg etdm_reg;
-	unsigned long flags;
-	int ret = 0;
-
-	if (!is_valid_etdm_dai(dai_id))
-		return -EINVAL;
-	etdm_data = afe_priv->dai_priv[dai_id];
-
-	dev_dbg(afe->dev, "%s [%d]%d\n", __func__, dai_id, etdm_data->en_ref_cnt);
-	spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
-	etdm_data->en_ref_cnt++;
-	if (etdm_data->en_ref_cnt == 1) {
-		ret = get_etdm_reg(dai_id, &etdm_reg);
-		if (ret < 0)
-			goto out;
-
-		regmap_set_bits(afe->regmap, etdm_reg.con0, ETDM_CON0_EN);
-	}
-
-out:
-	spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
-	return ret;
-}
-
-static int mt8188_afe_disable_etdm(struct mtk_base_afe *afe, int dai_id)
-{
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *etdm_data;
-	struct etdm_con_reg etdm_reg;
-	unsigned long flags;
-	int ret = 0;
-
-	if (!is_valid_etdm_dai(dai_id))
-		return -EINVAL;
-	etdm_data = afe_priv->dai_priv[dai_id];
-
-	dev_dbg(afe->dev, "%s [%d]%d\n", __func__, dai_id, etdm_data->en_ref_cnt);
-	spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
-	if (etdm_data->en_ref_cnt > 0) {
-		etdm_data->en_ref_cnt--;
-		if (etdm_data->en_ref_cnt == 0) {
-			ret = get_etdm_reg(dai_id, &etdm_reg);
-			if (ret < 0)
-				goto out;
-			regmap_clear_bits(afe->regmap, etdm_reg.con0,
-					  ETDM_CON0_EN);
-		}
-	}
-
-out:
-	spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
-	return ret;
-}
-
 static int etdm_cowork_slv_sel(int id, int slave_mode)
 {
 	if (slave_mode) {
@@ -1408,121 +1747,6 @@ static int mt8188_etdm_sync_mode_configure(struct mtk_base_afe *afe, int dai_id)
 }
 
 /* dai ops */
-static int mtk_dai_etdm_startup(struct snd_pcm_substream *substream,
-				struct snd_soc_dai *dai)
-{
-	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *mst_etdm_data;
-	int mst_dai_id;
-	int slv_dai_id;
-	int cg_id;
-	int i;
-
-	if (is_cowork_mode(dai)) {
-		mst_dai_id = get_etdm_cowork_master_id(dai);
-		if (!is_valid_etdm_dai(mst_dai_id))
-			return -EINVAL;
-		mtk_dai_etdm_enable_mclk(afe, mst_dai_id);
-
-		cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(mst_dai_id);
-		if (cg_id >= 0)
-			mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]);
-
-		mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
-
-		for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
-			slv_dai_id = mst_etdm_data->cowork_slv_id[i];
-			cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(slv_dai_id);
-			if (cg_id >= 0)
-				mt8188_afe_enable_clk(afe,
-						      afe_priv->clk[cg_id]);
-		}
-	} else {
-		mtk_dai_etdm_enable_mclk(afe, dai->id);
-
-		cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
-		if (cg_id >= 0)
-			mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]);
-	}
-
-	return 0;
-}
-
-static void mtk_dai_etdm_shutdown(struct snd_pcm_substream *substream,
-				  struct snd_soc_dai *dai)
-{
-	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *mst_etdm_data;
-	int mst_dai_id;
-	int slv_dai_id;
-	int cg_id;
-	int ret;
-	int i;
-
-	if (!is_valid_etdm_dai(dai->id))
-		return;
-	mst_etdm_data = afe_priv->dai_priv[dai->id];
-
-	dev_dbg(afe->dev, "%s(), dai id %d, prepared %d\n", __func__, dai->id,
-		mst_etdm_data->is_prepared);
-
-	if (mst_etdm_data->is_prepared) {
-		mst_etdm_data->is_prepared = false;
-
-		if (is_cowork_mode(dai)) {
-			mst_dai_id = get_etdm_cowork_master_id(dai);
-			if (!is_valid_etdm_dai(mst_dai_id))
-				return;
-			mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
-
-			ret = mt8188_afe_disable_etdm(afe, mst_dai_id);
-			if (ret)
-				dev_dbg(afe->dev, "%s disable %d failed\n",
-					__func__, mst_dai_id);
-
-			for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
-				slv_dai_id = mst_etdm_data->cowork_slv_id[i];
-				ret = mt8188_afe_disable_etdm(afe, slv_dai_id);
-				if (ret)
-					dev_dbg(afe->dev, "%s disable %d failed\n",
-						__func__, slv_dai_id);
-			}
-		} else {
-			ret = mt8188_afe_disable_etdm(afe, dai->id);
-			if (ret)
-				dev_dbg(afe->dev, "%s disable %d failed\n",
-					__func__, dai->id);
-		}
-	}
-
-	if (is_cowork_mode(dai)) {
-		mst_dai_id = get_etdm_cowork_master_id(dai);
-		if (!is_valid_etdm_dai(mst_dai_id))
-			return;
-		cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(mst_dai_id);
-		if (cg_id >= 0)
-			mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]);
-
-		mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
-		for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
-			slv_dai_id = mst_etdm_data->cowork_slv_id[i];
-			cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(slv_dai_id);
-			if (cg_id >= 0)
-				mt8188_afe_disable_clk(afe,
-						       afe_priv->clk[cg_id]);
-		}
-		mtk_dai_etdm_disable_mclk(afe, mst_dai_id);
-	} else {
-		cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
-		if (cg_id >= 0)
-			mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]);
-
-		mtk_dai_etdm_disable_mclk(afe, dai->id);
-	}
-}
-
 static int mtk_dai_etdm_fifo_mode(struct mtk_base_afe *afe,
 				  int dai_id, unsigned int rate)
 {
@@ -1759,60 +1983,6 @@ static int mtk_dai_etdm_out_configure(struct mtk_base_afe *afe,
 	return 0;
 }
 
-static int mtk_dai_etdm_mclk_configure(struct mtk_base_afe *afe, int dai_id)
-{
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *etdm_data;
-	struct etdm_con_reg etdm_reg;
-	int clk_id = mtk_dai_etdm_get_clk_id_by_dai_id(dai_id);
-	int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id);
-	int apll_clk_id;
-	int apll;
-	int ret;
-
-	if (clk_id < 0 || clkdiv_id < 0)
-		return -EINVAL;
-
-	if (!is_valid_etdm_dai(dai_id))
-		return -EINVAL;
-	etdm_data = afe_priv->dai_priv[dai_id];
-
-	ret = get_etdm_reg(dai_id, &etdm_reg);
-	if (ret < 0)
-		return ret;
-
-	if (etdm_data->mclk_dir == SND_SOC_CLOCK_OUT)
-		regmap_set_bits(afe->regmap, etdm_reg.con1,
-				ETDM_CON1_MCLK_OUTPUT);
-	else
-		regmap_clear_bits(afe->regmap, etdm_reg.con1,
-				  ETDM_CON1_MCLK_OUTPUT);
-
-	if (etdm_data->mclk_freq) {
-		apll = etdm_data->mclk_apll;
-		apll_clk_id = mt8188_afe_get_mclk_source_clk_id(apll);
-		if (apll_clk_id < 0)
-			return apll_clk_id;
-
-		/* select apll */
-		ret = mt8188_afe_set_clk_parent(afe, afe_priv->clk[clk_id],
-						afe_priv->clk[apll_clk_id]);
-		if (ret)
-			return ret;
-
-		/* set rate */
-		ret = mt8188_afe_set_clk_rate(afe, afe_priv->clk[clkdiv_id],
-					      etdm_data->mclk_freq);
-		if (ret)
-			return ret;
-	} else {
-		if (etdm_data->mclk_dir == SND_SOC_CLOCK_OUT)
-			dev_dbg(afe->dev, "%s mclk freq = 0\n", __func__);
-	}
-
-	return 0;
-}
-
 static int mtk_dai_etdm_configure(struct mtk_base_afe *afe,
 				  unsigned int rate,
 				  unsigned int channels,
@@ -1839,10 +2009,10 @@ static int mtk_dai_etdm_configure(struct mtk_base_afe *afe,
 	if (ret < 0)
 		return ret;
 
-	dev_dbg(afe->dev, "%s fmt %u data %u lrck %d-%u bck %d, clock %u slv %u\n",
+	dev_dbg(afe->dev, "%s fmt %u data %u lrck %d-%u bck %d, slv %u\n",
 		__func__, etdm_data->format, etdm_data->data_mode,
 		etdm_data->lrck_inv, etdm_data->lrck_width, etdm_data->bck_inv,
-		etdm_data->clock_mode, etdm_data->slave_mode);
+		etdm_data->slave_mode);
 	dev_dbg(afe->dev, "%s rate %u channels %u bitwidth %u, id %d\n",
 		__func__, rate, channels, bit_width, dai_id);
 
@@ -1913,10 +2083,6 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
 		if (mst_etdm_data->slots)
 			channels = mst_etdm_data->slots;
 
-		ret = mtk_dai_etdm_mclk_configure(afe, mst_dai_id);
-		if (ret)
-			return ret;
-
 		ret = mtk_dai_etdm_configure(afe, rate, channels,
 					     bit_width, mst_dai_id);
 		if (ret)
@@ -1940,10 +2106,6 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
 		if (mst_etdm_data->slots)
 			channels = mst_etdm_data->slots;
 
-		ret = mtk_dai_etdm_mclk_configure(afe, dai->id);
-		if (ret)
-			return ret;
-
 		ret = mtk_dai_etdm_configure(afe, rate, channels,
 					     bit_width, dai->id);
 		if (ret)
@@ -1953,66 +2115,6 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
 	return 0;
 }
 
-static int mtk_dai_etdm_prepare(struct snd_pcm_substream *substream,
-				struct snd_soc_dai *dai)
-{
-	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *mst_etdm_data;
-	int mst_dai_id;
-	int slv_dai_id;
-	int ret;
-	int i;
-
-	if (!is_valid_etdm_dai(dai->id))
-		return -EINVAL;
-	mst_etdm_data = afe_priv->dai_priv[dai->id];
-
-	dev_dbg(afe->dev, "%s(), dai id %d, prepared %d\n", __func__, dai->id,
-		mst_etdm_data->is_prepared);
-
-	if (mst_etdm_data->is_prepared)
-		return 0;
-
-	mst_etdm_data->is_prepared = true;
-
-	if (is_cowork_mode(dai)) {
-		mst_dai_id = get_etdm_cowork_master_id(dai);
-		if (!is_valid_etdm_dai(mst_dai_id))
-			return -EINVAL;
-		mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
-
-		for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
-			slv_dai_id = mst_etdm_data->cowork_slv_id[i];
-			ret = mt8188_afe_enable_etdm(afe, slv_dai_id);
-			if (ret) {
-				dev_dbg(afe->dev, "%s enable %d failed\n",
-					__func__, slv_dai_id);
-
-				return ret;
-			}
-		}
-
-		ret = mt8188_afe_enable_etdm(afe, mst_dai_id);
-		if (ret) {
-			dev_dbg(afe->dev, "%s enable %d failed\n",
-				__func__, mst_dai_id);
-
-			return ret;
-		}
-	} else {
-		ret = mt8188_afe_enable_etdm(afe, dai->id);
-		if (ret) {
-			dev_dbg(afe->dev, "%s enable %d failed\n",
-				__func__, dai->id);
-
-			return ret;
-		}
-	}
-
-	return 0;
-}
-
 static int mtk_dai_etdm_cal_mclk(struct mtk_base_afe *afe, int freq, int dai_id)
 {
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
@@ -2166,53 +2268,6 @@ static int mtk_dai_etdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	return 0;
 }
 
-static int mtk_dai_hdmitx_dptx_startup(struct snd_pcm_substream *substream,
-				       struct snd_soc_dai *dai)
-{
-	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	int cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
-
-	if (cg_id >= 0)
-		mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]);
-
-	mtk_dai_etdm_enable_mclk(afe, dai->id);
-
-	return 0;
-}
-
-static void mtk_dai_hdmitx_dptx_shutdown(struct snd_pcm_substream *substream,
-					 struct snd_soc_dai *dai)
-{
-	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	int cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
-	struct mtk_dai_etdm_priv *etdm_data;
-	int ret;
-
-	if (!is_valid_etdm_dai(dai->id))
-		return;
-	etdm_data = afe_priv->dai_priv[dai->id];
-
-	if (etdm_data->is_prepared) {
-		etdm_data->is_prepared = false;
-		/* disable etdm_out3 */
-		ret = mt8188_afe_disable_etdm(afe, dai->id);
-		if (ret)
-			dev_dbg(afe->dev, "%s disable failed\n", __func__);
-
-		/* disable dptx interface */
-		if (dai->id == MT8188_AFE_IO_DPTX)
-			regmap_clear_bits(afe->regmap, AFE_DPTX_CON,
-					  AFE_DPTX_CON_ON);
-	}
-
-	mtk_dai_etdm_disable_mclk(afe, dai->id);
-
-	if (cg_id >= 0)
-		mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]);
-}
-
 static unsigned int mtk_dai_get_dptx_ch_en(unsigned int channel)
 {
 	switch (channel) {
@@ -2280,42 +2335,11 @@ static int mtk_dai_hdmitx_dptx_hw_params(struct snd_pcm_substream *substream,
 		etdm_data->data_mode = MTK_DAI_ETDM_DATA_MULTI_PIN;
 	}
 
-	ret = mtk_dai_etdm_mclk_configure(afe, dai->id);
-	if (ret)
-		return ret;
-
 	ret = mtk_dai_etdm_configure(afe, rate, channels, width, dai->id);
 
 	return ret;
 }
 
-static int mtk_dai_hdmitx_dptx_prepare(struct snd_pcm_substream *substream,
-				       struct snd_soc_dai *dai)
-{
-	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *etdm_data;
-
-	if (!is_valid_etdm_dai(dai->id))
-		return -EINVAL;
-	etdm_data = afe_priv->dai_priv[dai->id];
-
-	dev_dbg(afe->dev, "%s(), dai id %d, prepared %d\n", __func__, dai->id,
-		etdm_data->is_prepared);
-
-	if (etdm_data->is_prepared)
-		return 0;
-
-	etdm_data->is_prepared = true;
-
-	/* enable dptx interface */
-	if (dai->id == MT8188_AFE_IO_DPTX)
-		regmap_set_bits(afe->regmap, AFE_DPTX_CON, AFE_DPTX_CON_ON);
-
-	/* enable etdm_out3 */
-	return mt8188_afe_enable_etdm(afe, dai->id);
-}
-
 static int mtk_dai_hdmitx_dptx_set_sysclk(struct snd_soc_dai *dai,
 					  int clk_id,
 					  unsigned int freq,
@@ -2337,20 +2361,14 @@ static int mtk_dai_hdmitx_dptx_set_sysclk(struct snd_soc_dai *dai,
 }
 
 static const struct snd_soc_dai_ops mtk_dai_etdm_ops = {
-	.startup = mtk_dai_etdm_startup,
-	.shutdown = mtk_dai_etdm_shutdown,
 	.hw_params = mtk_dai_etdm_hw_params,
-	.prepare = mtk_dai_etdm_prepare,
 	.set_sysclk = mtk_dai_etdm_set_sysclk,
 	.set_fmt = mtk_dai_etdm_set_fmt,
 	.set_tdm_slot = mtk_dai_etdm_set_tdm_slot,
 };
 
 static const struct snd_soc_dai_ops mtk_dai_hdmitx_dptx_ops = {
-	.startup	= mtk_dai_hdmitx_dptx_startup,
-	.shutdown	= mtk_dai_hdmitx_dptx_shutdown,
 	.hw_params	= mtk_dai_hdmitx_dptx_hw_params,
-	.prepare	= mtk_dai_hdmitx_dptx_prepare,
 	.set_sysclk	= mtk_dai_hdmitx_dptx_set_sysclk,
 	.set_fmt	= mtk_dai_etdm_set_fmt,
 };
diff --git a/sound/soc/mediatek/mt8188/mt8188-reg.h b/sound/soc/mediatek/mt8188/mt8188-reg.h
index 51cd1a83dd9d..bdd885419ff3 100644
--- a/sound/soc/mediatek/mt8188/mt8188-reg.h
+++ b/sound/soc/mediatek/mt8188/mt8188-reg.h
@@ -3007,6 +3007,7 @@
 #define ETDM_CON0_SLAVE_MODE		BIT(5)
 #define ETDM_CON0_SYNC_MODE		BIT(1)
 #define ETDM_CON0_EN			BIT(0)
+#define ETDM_CON0_EN_SHIFT		0
 
 #define ETDM_OUT_CON0_RELATCH_DOMAIN_MASK	GENMASK(29, 28)
 
@@ -3108,6 +3109,7 @@
 #define AFE_DPTX_CON_CH_NUM_8CH		(0x1 << 1)
 #define AFE_DPTX_CON_CH_NUM_MASK	BIT(1)
 #define AFE_DPTX_CON_ON			BIT(0)
+#define AFE_DPTX_CON_ON_SHIFT		0
 
 /* AFE_ADDA_DL_SRC2_CON0 */
 #define DL_2_INPUT_MODE_CTL_MASK	GENMASK(31, 28)
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 3/7] ASoC: mediatek: mt8188: revise ETDM control flow
  2023-04-26  5:51 ` Trevor Wu
                   ` (4 preceding siblings ...)
  (?)
@ 2023-04-26  5:51 ` Trevor Wu via Alsa-devel
  -1 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu via Alsa-devel @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree


[-- Attachment #0: Type: message/rfc822, Size: 34574 bytes --]

From: Trevor Wu <trevor.wu@mediatek.com>
To: <broonie@kernel.org>, <lgirdwood@gmail.com>, <tiwai@suse.com>, <perex@perex.cz>, <robh+dt@kernel.org>, <krzysztof.kozlowski+dt@linaro.org>, <matthias.bgg@gmail.com>, <angelogioacchino.delregno@collabora.com>
Cc: trevor.wu@mediatek.com, alsa-devel@alsa-project.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org
Subject: [PATCH v3 3/7] ASoC: mediatek: mt8188: revise ETDM control flow
Date: Wed, 26 Apr 2023 13:51:20 +0800
Message-ID: <20230426055124.16529-4-trevor.wu@mediatek.com>

Replace register controls in snd_soc_dai_ops with snd_soc_dapm_widgets.
startup, shutdown and trigger ops are removed, and create DAPM_SUPPLY
to handle mclk, clock gating and etdm enabling. Additionally, mclk setup
sequence is also updated because of new supply enabling sequence.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
 sound/soc/mediatek/mt8188/mt8188-dai-etdm.c | 790 ++++++++++----------
 sound/soc/mediatek/mt8188/mt8188-reg.h      |   2 +
 2 files changed, 406 insertions(+), 386 deletions(-)

diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
index fddecf5bf7c6..fd6e39a1e4c1 100644
--- a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
+++ b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
@@ -21,6 +21,13 @@
 #define ETDM_TO_DAI_ID(x) ((x) + MT8188_AFE_IO_ETDM_START)
 #define ENUM_TO_STR(x)	#x
 
+enum {
+	SUPPLY_SEQ_ETDM_MCLK,
+	SUPPLY_SEQ_ETDM_CG,
+	SUPPLY_SEQ_DPTX_EN,
+	SUPPLY_SEQ_ETDM_EN,
+};
+
 enum {
 	MTK_DAI_ETDM_FORMAT_I2S = 0,
 	MTK_DAI_ETDM_FORMAT_LJ,
@@ -84,7 +91,6 @@ struct mtk_dai_etdm_rate {
 };
 
 struct mtk_dai_etdm_priv {
-	unsigned int clock_mode;
 	unsigned int data_mode;
 	bool slave_mode;
 	bool lrck_inv;
@@ -100,8 +106,6 @@ struct mtk_dai_etdm_priv {
 	unsigned int cowork_slv_count;
 	int cowork_slv_id[MT8188_AFE_IO_ETDM_NUM - 1]; //dai_id
 	bool in_disable_ch[MT8188_ETDM_MAX_CHANNELS];
-	unsigned int en_ref_cnt;
-	bool is_prepared;
 };
 
 static const struct mtk_dai_etdm_rate mt8188_etdm_rates[] = {
@@ -345,14 +349,82 @@ static int mtk_dai_etdm_get_clkdiv_id_by_dai_id(int dai_id)
 	}
 }
 
+static int get_etdm_id_by_name(struct mtk_base_afe *afe,
+			       const char *name)
+{
+	if (!strncmp(name, "ETDM1_IN", strlen("ETDM1_IN")))
+		return MT8188_AFE_IO_ETDM1_IN;
+	else if (!strncmp(name, "ETDM2_IN", strlen("ETDM2_IN")))
+		return MT8188_AFE_IO_ETDM2_IN;
+	else if (!strncmp(name, "ETDM1_OUT", strlen("ETDM1_OUT")))
+		return MT8188_AFE_IO_ETDM1_OUT;
+	else if (!strncmp(name, "ETDM2_OUT", strlen("ETDM2_OUT")))
+		return MT8188_AFE_IO_ETDM2_OUT;
+	else
+		return -EINVAL;
+}
+
+static struct mtk_dai_etdm_priv *get_etdm_priv_by_name(struct mtk_base_afe *afe,
+						       const char *name)
+{
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	int dai_id = get_etdm_id_by_name(afe, name);
+
+	if (dai_id < MT8188_AFE_IO_ETDM_START ||
+	    dai_id >= MT8188_AFE_IO_ETDM_END)
+		return NULL;
+
+	return afe_priv->dai_priv[dai_id];
+}
+
 static int mtk_dai_etdm_enable_mclk(struct mtk_base_afe *afe, int dai_id)
 {
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_etdm_priv *etdm_data;
+	struct etdm_con_reg etdm_reg;
+	unsigned int val = 0;
+	unsigned int mask;
+	int clkmux_id = mtk_dai_etdm_get_clk_id_by_dai_id(dai_id);
 	int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id);
+	int apll_clk_id;
+	int apll;
+	int ret;
+
+	if (!is_valid_etdm_dai(dai_id))
+		return -EINVAL;
+	etdm_data = afe_priv->dai_priv[dai_id];
 
-	if (clkdiv_id < 0)
+	apll = etdm_data->mclk_apll;
+	apll_clk_id = mt8188_afe_get_mclk_source_clk_id(apll);
+
+	if (clkmux_id < 0 || clkdiv_id < 0)
 		return -EINVAL;
 
+	if (apll_clk_id < 0)
+		return apll_clk_id;
+
+	ret = get_etdm_reg(dai_id, &etdm_reg);
+	if (ret < 0)
+		return ret;
+
+	mask = ETDM_CON1_MCLK_OUTPUT;
+	if (etdm_data->mclk_dir == SND_SOC_CLOCK_OUT)
+		val = ETDM_CON1_MCLK_OUTPUT;
+	regmap_update_bits(afe->regmap, etdm_reg.con1, mask, val);
+
+	/* enable parent clock before select apll*/
+	mt8188_afe_enable_clk(afe, afe_priv->clk[clkmux_id]);
+
+	/* select apll */
+	ret = mt8188_afe_set_clk_parent(afe, afe_priv->clk[clkmux_id],
+					afe_priv->clk[apll_clk_id]);
+	if (ret)
+		return ret;
+
+	/* set rate */
+	ret = mt8188_afe_set_clk_rate(afe, afe_priv->clk[clkdiv_id],
+				      etdm_data->mclk_freq);
+
 	mt8188_afe_enable_clk(afe, afe_priv->clk[clkdiv_id]);
 
 	return 0;
@@ -361,12 +433,207 @@ static int mtk_dai_etdm_enable_mclk(struct mtk_base_afe *afe, int dai_id)
 static int mtk_dai_etdm_disable_mclk(struct mtk_base_afe *afe, int dai_id)
 {
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	int clkmux_id = mtk_dai_etdm_get_clk_id_by_dai_id(dai_id);
 	int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id);
 
-	if (clkdiv_id < 0)
+	if (clkmux_id < 0 || clkdiv_id < 0)
 		return -EINVAL;
 
 	mt8188_afe_disable_clk(afe, afe_priv->clk[clkdiv_id]);
+	mt8188_afe_disable_clk(afe, afe_priv->clk[clkmux_id]);
+
+	return 0;
+}
+
+static int mtk_etdm_mclk_connect(struct snd_soc_dapm_widget *source,
+				 struct snd_soc_dapm_widget *sink)
+{
+	struct snd_soc_dapm_widget *w = sink;
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_etdm_priv *etdm_priv;
+	int mclk_id;
+
+	mclk_id = get_etdm_id_by_name(afe, source->name);
+	if (mclk_id < 0) {
+		dev_dbg(afe->dev, "mclk_id < 0\n");
+		return 0;
+	}
+
+	etdm_priv = get_etdm_priv_by_name(afe, w->name);
+	if (!etdm_priv) {
+		dev_dbg(afe->dev, "etdm_priv == NULL\n");
+		return 0;
+	}
+
+	if (get_etdm_id_by_name(afe, sink->name) == mclk_id)
+		return !!(etdm_priv->mclk_freq > 0);
+
+	if (etdm_priv->cowork_source_id == mclk_id) {
+		etdm_priv = afe_priv->dai_priv[mclk_id];
+		return !!(etdm_priv->mclk_freq > 0);
+	}
+
+	return 0;
+}
+
+static int mtk_etdm_cowork_connect(struct snd_soc_dapm_widget *source,
+				   struct snd_soc_dapm_widget *sink)
+{
+	struct snd_soc_dapm_widget *w = sink;
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	struct mtk_dai_etdm_priv *etdm_priv;
+	int source_id;
+	int i;
+
+	source_id = get_etdm_id_by_name(afe, source->name);
+	if (source_id < 0) {
+		dev_dbg(afe->dev, "%s() source_id < 0\n", __func__);
+		return 0;
+	}
+
+	etdm_priv = get_etdm_priv_by_name(afe, w->name);
+	if (!etdm_priv) {
+		dev_dbg(afe->dev, "%s() etdm_priv == NULL\n", __func__);
+		return 0;
+	}
+
+	if (etdm_priv->cowork_source_id != COWORK_ETDM_NONE) {
+		if (etdm_priv->cowork_source_id == source_id)
+			return 1;
+
+		etdm_priv = afe_priv->dai_priv[etdm_priv->cowork_source_id];
+		for (i = 0; i < etdm_priv->cowork_slv_count; i++) {
+			if (etdm_priv->cowork_slv_id[i] == source_id)
+				return 1;
+		}
+	} else {
+		for (i = 0; i < etdm_priv->cowork_slv_count; i++) {
+			if (etdm_priv->cowork_slv_id[i] == source_id)
+				return 1;
+		}
+	}
+
+	return 0;
+}
+
+static int mtk_etdm_mclk_event(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol,
+			       int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	int mclk_id = get_etdm_id_by_name(afe, w->name);
+
+	if (mclk_id < 0) {
+		dev_dbg(afe->dev, "%s() mclk_id < 0\n", __func__);
+		return 0;
+	}
+
+	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mtk_dai_etdm_enable_mclk(afe, mclk_id);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		mtk_dai_etdm_disable_mclk(afe, mclk_id);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mtk_dptx_mclk_event(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol,
+			       int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+
+	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mtk_dai_etdm_enable_mclk(afe, MT8188_AFE_IO_DPTX);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		mtk_dai_etdm_disable_mclk(afe, MT8188_AFE_IO_DPTX);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mtk_etdm_cg_event(struct snd_soc_dapm_widget *w,
+			     struct snd_kcontrol *kcontrol,
+			     int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	int etdm_id;
+	int cg_id;
+
+	etdm_id = get_etdm_id_by_name(afe, w->name);
+	if (etdm_id < 0) {
+		dev_dbg(afe->dev, "%s() etdm_id < 0\n", __func__);
+		return 0;
+	}
+
+	cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(etdm_id);
+	if (cg_id < 0) {
+		dev_dbg(afe->dev, "%s() cg_id < 0\n", __func__);
+		return 0;
+	}
+
+	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int mtk_etdm3_cg_event(struct snd_soc_dapm_widget *w,
+			      struct snd_kcontrol *kcontrol,
+			      int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+
+	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_HDMI_OUT]);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_HDMI_OUT]);
+		break;
+	default:
+		break;
+	}
 
 	return 0;
 }
@@ -906,11 +1173,141 @@ static const struct snd_soc_dapm_widget mtk_dai_etdm_widgets[] = {
 	SND_SOC_DAPM_MUX("HDMI_CH7_MUX", SND_SOC_NOPM, 0, 0,
 			 &hdmi_ch7_mux_control),
 
+	/* mclk en */
+	SND_SOC_DAPM_SUPPLY_S("ETDM1_IN_MCLK", SUPPLY_SEQ_ETDM_MCLK,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_mclk_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM2_IN_MCLK", SUPPLY_SEQ_ETDM_MCLK,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_mclk_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM1_OUT_MCLK", SUPPLY_SEQ_ETDM_MCLK,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_mclk_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM2_OUT_MCLK", SUPPLY_SEQ_ETDM_MCLK,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_mclk_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("DPTX_MCLK", SUPPLY_SEQ_ETDM_MCLK,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_dptx_mclk_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	/* cg */
+	SND_SOC_DAPM_SUPPLY_S("ETDM1_IN_CG", SUPPLY_SEQ_ETDM_CG,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_cg_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM2_IN_CG", SUPPLY_SEQ_ETDM_CG,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_cg_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM1_OUT_CG", SUPPLY_SEQ_ETDM_CG,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_cg_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM2_OUT_CG", SUPPLY_SEQ_ETDM_CG,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm_cg_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S("ETDM3_OUT_CG", SUPPLY_SEQ_ETDM_CG,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_etdm3_cg_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	/* en */
+	SND_SOC_DAPM_SUPPLY_S("ETDM1_IN_EN", SUPPLY_SEQ_ETDM_EN,
+			      ETDM_IN1_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("ETDM2_IN_EN", SUPPLY_SEQ_ETDM_EN,
+			      ETDM_IN2_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("ETDM1_OUT_EN", SUPPLY_SEQ_ETDM_EN,
+			      ETDM_OUT1_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("ETDM2_OUT_EN", SUPPLY_SEQ_ETDM_EN,
+			      ETDM_OUT2_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("ETDM3_OUT_EN", SUPPLY_SEQ_ETDM_EN,
+			      ETDM_OUT3_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY_S("DPTX_EN", SUPPLY_SEQ_DPTX_EN,
+			      AFE_DPTX_CON, AFE_DPTX_CON_ON_SHIFT, 0, NULL, 0),
+
 	SND_SOC_DAPM_INPUT("ETDM_INPUT"),
 	SND_SOC_DAPM_OUTPUT("ETDM_OUTPUT"),
 };
 
 static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = {
+	/* mclk */
+	{"ETDM1_IN", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM1_IN", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM1_IN", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM1_IN", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect},
+
+	{"ETDM2_IN", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM2_IN", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM2_IN", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM2_IN", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect},
+
+	{"ETDM1_OUT", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM1_OUT", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM1_OUT", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM1_OUT", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect},
+
+	{"ETDM2_OUT", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM2_OUT", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM2_OUT", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect},
+	{"ETDM2_OUT", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect},
+
+	{"DPTX", NULL, "DPTX_MCLK"},
+
+	/* cg */
+	{"ETDM1_IN", NULL, "ETDM1_IN_CG"},
+	{"ETDM1_IN", NULL, "ETDM2_IN_CG", mtk_etdm_cowork_connect},
+	{"ETDM1_IN", NULL, "ETDM1_OUT_CG", mtk_etdm_cowork_connect},
+	{"ETDM1_IN", NULL, "ETDM2_OUT_CG", mtk_etdm_cowork_connect},
+
+	{"ETDM2_IN", NULL, "ETDM1_IN_CG", mtk_etdm_cowork_connect},
+	{"ETDM2_IN", NULL, "ETDM2_IN_CG"},
+	{"ETDM2_IN", NULL, "ETDM1_OUT_CG", mtk_etdm_cowork_connect},
+	{"ETDM2_IN", NULL, "ETDM2_OUT_CG", mtk_etdm_cowork_connect},
+
+	{"ETDM1_OUT", NULL, "ETDM1_IN_CG", mtk_etdm_cowork_connect},
+	{"ETDM1_OUT", NULL, "ETDM2_IN_CG", mtk_etdm_cowork_connect},
+	{"ETDM1_OUT", NULL, "ETDM1_OUT_CG"},
+	{"ETDM1_OUT", NULL, "ETDM2_OUT_CG", mtk_etdm_cowork_connect},
+
+	{"ETDM2_OUT", NULL, "ETDM1_IN_CG", mtk_etdm_cowork_connect},
+	{"ETDM2_OUT", NULL, "ETDM2_IN_CG", mtk_etdm_cowork_connect},
+	{"ETDM2_OUT", NULL, "ETDM1_OUT_CG", mtk_etdm_cowork_connect},
+	{"ETDM2_OUT", NULL, "ETDM2_OUT_CG"},
+
+	{"ETDM3_OUT", NULL, "ETDM3_OUT_CG"},
+	{"DPTX", NULL, "ETDM3_OUT_CG"},
+
+	/* en */
+	{"ETDM1_IN", NULL, "ETDM1_IN_EN"},
+	{"ETDM1_IN", NULL, "ETDM2_IN_EN", mtk_etdm_cowork_connect},
+	{"ETDM1_IN", NULL, "ETDM1_OUT_EN", mtk_etdm_cowork_connect},
+	{"ETDM1_IN", NULL, "ETDM2_OUT_EN", mtk_etdm_cowork_connect},
+
+	{"ETDM2_IN", NULL, "ETDM1_IN_EN", mtk_etdm_cowork_connect},
+	{"ETDM2_IN", NULL, "ETDM2_IN_EN"},
+	{"ETDM2_IN", NULL, "ETDM1_OUT_EN", mtk_etdm_cowork_connect},
+	{"ETDM2_IN", NULL, "ETDM2_OUT_EN", mtk_etdm_cowork_connect},
+
+	{"ETDM1_OUT", NULL, "ETDM1_IN_EN", mtk_etdm_cowork_connect},
+	{"ETDM1_OUT", NULL, "ETDM2_IN_EN", mtk_etdm_cowork_connect},
+	{"ETDM1_OUT", NULL, "ETDM1_OUT_EN"},
+	{"ETDM1_OUT", NULL, "ETDM2_OUT_EN", mtk_etdm_cowork_connect},
+
+	{"ETDM2_OUT", NULL, "ETDM1_IN_EN", mtk_etdm_cowork_connect},
+	{"ETDM2_OUT", NULL, "ETDM2_IN_EN", mtk_etdm_cowork_connect},
+	{"ETDM2_OUT", NULL, "ETDM1_OUT_EN", mtk_etdm_cowork_connect},
+	{"ETDM2_OUT", NULL, "ETDM2_OUT_EN"},
+
+	{"ETDM3_OUT", NULL, "ETDM3_OUT_EN"},
+	{"DPTX", NULL, "ETDM3_OUT_EN"},
+	{"DPTX", NULL, "DPTX_EN"},
+
 	{"I012", NULL, "ETDM2_IN"},
 	{"I013", NULL, "ETDM2_IN"},
 	{"I014", NULL, "ETDM2_IN"},
@@ -1163,64 +1560,6 @@ static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = {
 	{"ETDM2_IN", NULL, "ETDM_INPUT"},
 };
 
-static int mt8188_afe_enable_etdm(struct mtk_base_afe *afe, int dai_id)
-{
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *etdm_data;
-	struct etdm_con_reg etdm_reg;
-	unsigned long flags;
-	int ret = 0;
-
-	if (!is_valid_etdm_dai(dai_id))
-		return -EINVAL;
-	etdm_data = afe_priv->dai_priv[dai_id];
-
-	dev_dbg(afe->dev, "%s [%d]%d\n", __func__, dai_id, etdm_data->en_ref_cnt);
-	spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
-	etdm_data->en_ref_cnt++;
-	if (etdm_data->en_ref_cnt == 1) {
-		ret = get_etdm_reg(dai_id, &etdm_reg);
-		if (ret < 0)
-			goto out;
-
-		regmap_set_bits(afe->regmap, etdm_reg.con0, ETDM_CON0_EN);
-	}
-
-out:
-	spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
-	return ret;
-}
-
-static int mt8188_afe_disable_etdm(struct mtk_base_afe *afe, int dai_id)
-{
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *etdm_data;
-	struct etdm_con_reg etdm_reg;
-	unsigned long flags;
-	int ret = 0;
-
-	if (!is_valid_etdm_dai(dai_id))
-		return -EINVAL;
-	etdm_data = afe_priv->dai_priv[dai_id];
-
-	dev_dbg(afe->dev, "%s [%d]%d\n", __func__, dai_id, etdm_data->en_ref_cnt);
-	spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
-	if (etdm_data->en_ref_cnt > 0) {
-		etdm_data->en_ref_cnt--;
-		if (etdm_data->en_ref_cnt == 0) {
-			ret = get_etdm_reg(dai_id, &etdm_reg);
-			if (ret < 0)
-				goto out;
-			regmap_clear_bits(afe->regmap, etdm_reg.con0,
-					  ETDM_CON0_EN);
-		}
-	}
-
-out:
-	spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
-	return ret;
-}
-
 static int etdm_cowork_slv_sel(int id, int slave_mode)
 {
 	if (slave_mode) {
@@ -1408,121 +1747,6 @@ static int mt8188_etdm_sync_mode_configure(struct mtk_base_afe *afe, int dai_id)
 }
 
 /* dai ops */
-static int mtk_dai_etdm_startup(struct snd_pcm_substream *substream,
-				struct snd_soc_dai *dai)
-{
-	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *mst_etdm_data;
-	int mst_dai_id;
-	int slv_dai_id;
-	int cg_id;
-	int i;
-
-	if (is_cowork_mode(dai)) {
-		mst_dai_id = get_etdm_cowork_master_id(dai);
-		if (!is_valid_etdm_dai(mst_dai_id))
-			return -EINVAL;
-		mtk_dai_etdm_enable_mclk(afe, mst_dai_id);
-
-		cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(mst_dai_id);
-		if (cg_id >= 0)
-			mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]);
-
-		mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
-
-		for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
-			slv_dai_id = mst_etdm_data->cowork_slv_id[i];
-			cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(slv_dai_id);
-			if (cg_id >= 0)
-				mt8188_afe_enable_clk(afe,
-						      afe_priv->clk[cg_id]);
-		}
-	} else {
-		mtk_dai_etdm_enable_mclk(afe, dai->id);
-
-		cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
-		if (cg_id >= 0)
-			mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]);
-	}
-
-	return 0;
-}
-
-static void mtk_dai_etdm_shutdown(struct snd_pcm_substream *substream,
-				  struct snd_soc_dai *dai)
-{
-	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *mst_etdm_data;
-	int mst_dai_id;
-	int slv_dai_id;
-	int cg_id;
-	int ret;
-	int i;
-
-	if (!is_valid_etdm_dai(dai->id))
-		return;
-	mst_etdm_data = afe_priv->dai_priv[dai->id];
-
-	dev_dbg(afe->dev, "%s(), dai id %d, prepared %d\n", __func__, dai->id,
-		mst_etdm_data->is_prepared);
-
-	if (mst_etdm_data->is_prepared) {
-		mst_etdm_data->is_prepared = false;
-
-		if (is_cowork_mode(dai)) {
-			mst_dai_id = get_etdm_cowork_master_id(dai);
-			if (!is_valid_etdm_dai(mst_dai_id))
-				return;
-			mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
-
-			ret = mt8188_afe_disable_etdm(afe, mst_dai_id);
-			if (ret)
-				dev_dbg(afe->dev, "%s disable %d failed\n",
-					__func__, mst_dai_id);
-
-			for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
-				slv_dai_id = mst_etdm_data->cowork_slv_id[i];
-				ret = mt8188_afe_disable_etdm(afe, slv_dai_id);
-				if (ret)
-					dev_dbg(afe->dev, "%s disable %d failed\n",
-						__func__, slv_dai_id);
-			}
-		} else {
-			ret = mt8188_afe_disable_etdm(afe, dai->id);
-			if (ret)
-				dev_dbg(afe->dev, "%s disable %d failed\n",
-					__func__, dai->id);
-		}
-	}
-
-	if (is_cowork_mode(dai)) {
-		mst_dai_id = get_etdm_cowork_master_id(dai);
-		if (!is_valid_etdm_dai(mst_dai_id))
-			return;
-		cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(mst_dai_id);
-		if (cg_id >= 0)
-			mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]);
-
-		mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
-		for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
-			slv_dai_id = mst_etdm_data->cowork_slv_id[i];
-			cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(slv_dai_id);
-			if (cg_id >= 0)
-				mt8188_afe_disable_clk(afe,
-						       afe_priv->clk[cg_id]);
-		}
-		mtk_dai_etdm_disable_mclk(afe, mst_dai_id);
-	} else {
-		cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
-		if (cg_id >= 0)
-			mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]);
-
-		mtk_dai_etdm_disable_mclk(afe, dai->id);
-	}
-}
-
 static int mtk_dai_etdm_fifo_mode(struct mtk_base_afe *afe,
 				  int dai_id, unsigned int rate)
 {
@@ -1759,60 +1983,6 @@ static int mtk_dai_etdm_out_configure(struct mtk_base_afe *afe,
 	return 0;
 }
 
-static int mtk_dai_etdm_mclk_configure(struct mtk_base_afe *afe, int dai_id)
-{
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *etdm_data;
-	struct etdm_con_reg etdm_reg;
-	int clk_id = mtk_dai_etdm_get_clk_id_by_dai_id(dai_id);
-	int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id);
-	int apll_clk_id;
-	int apll;
-	int ret;
-
-	if (clk_id < 0 || clkdiv_id < 0)
-		return -EINVAL;
-
-	if (!is_valid_etdm_dai(dai_id))
-		return -EINVAL;
-	etdm_data = afe_priv->dai_priv[dai_id];
-
-	ret = get_etdm_reg(dai_id, &etdm_reg);
-	if (ret < 0)
-		return ret;
-
-	if (etdm_data->mclk_dir == SND_SOC_CLOCK_OUT)
-		regmap_set_bits(afe->regmap, etdm_reg.con1,
-				ETDM_CON1_MCLK_OUTPUT);
-	else
-		regmap_clear_bits(afe->regmap, etdm_reg.con1,
-				  ETDM_CON1_MCLK_OUTPUT);
-
-	if (etdm_data->mclk_freq) {
-		apll = etdm_data->mclk_apll;
-		apll_clk_id = mt8188_afe_get_mclk_source_clk_id(apll);
-		if (apll_clk_id < 0)
-			return apll_clk_id;
-
-		/* select apll */
-		ret = mt8188_afe_set_clk_parent(afe, afe_priv->clk[clk_id],
-						afe_priv->clk[apll_clk_id]);
-		if (ret)
-			return ret;
-
-		/* set rate */
-		ret = mt8188_afe_set_clk_rate(afe, afe_priv->clk[clkdiv_id],
-					      etdm_data->mclk_freq);
-		if (ret)
-			return ret;
-	} else {
-		if (etdm_data->mclk_dir == SND_SOC_CLOCK_OUT)
-			dev_dbg(afe->dev, "%s mclk freq = 0\n", __func__);
-	}
-
-	return 0;
-}
-
 static int mtk_dai_etdm_configure(struct mtk_base_afe *afe,
 				  unsigned int rate,
 				  unsigned int channels,
@@ -1839,10 +2009,10 @@ static int mtk_dai_etdm_configure(struct mtk_base_afe *afe,
 	if (ret < 0)
 		return ret;
 
-	dev_dbg(afe->dev, "%s fmt %u data %u lrck %d-%u bck %d, clock %u slv %u\n",
+	dev_dbg(afe->dev, "%s fmt %u data %u lrck %d-%u bck %d, slv %u\n",
 		__func__, etdm_data->format, etdm_data->data_mode,
 		etdm_data->lrck_inv, etdm_data->lrck_width, etdm_data->bck_inv,
-		etdm_data->clock_mode, etdm_data->slave_mode);
+		etdm_data->slave_mode);
 	dev_dbg(afe->dev, "%s rate %u channels %u bitwidth %u, id %d\n",
 		__func__, rate, channels, bit_width, dai_id);
 
@@ -1913,10 +2083,6 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
 		if (mst_etdm_data->slots)
 			channels = mst_etdm_data->slots;
 
-		ret = mtk_dai_etdm_mclk_configure(afe, mst_dai_id);
-		if (ret)
-			return ret;
-
 		ret = mtk_dai_etdm_configure(afe, rate, channels,
 					     bit_width, mst_dai_id);
 		if (ret)
@@ -1940,10 +2106,6 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
 		if (mst_etdm_data->slots)
 			channels = mst_etdm_data->slots;
 
-		ret = mtk_dai_etdm_mclk_configure(afe, dai->id);
-		if (ret)
-			return ret;
-
 		ret = mtk_dai_etdm_configure(afe, rate, channels,
 					     bit_width, dai->id);
 		if (ret)
@@ -1953,66 +2115,6 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
 	return 0;
 }
 
-static int mtk_dai_etdm_prepare(struct snd_pcm_substream *substream,
-				struct snd_soc_dai *dai)
-{
-	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *mst_etdm_data;
-	int mst_dai_id;
-	int slv_dai_id;
-	int ret;
-	int i;
-
-	if (!is_valid_etdm_dai(dai->id))
-		return -EINVAL;
-	mst_etdm_data = afe_priv->dai_priv[dai->id];
-
-	dev_dbg(afe->dev, "%s(), dai id %d, prepared %d\n", __func__, dai->id,
-		mst_etdm_data->is_prepared);
-
-	if (mst_etdm_data->is_prepared)
-		return 0;
-
-	mst_etdm_data->is_prepared = true;
-
-	if (is_cowork_mode(dai)) {
-		mst_dai_id = get_etdm_cowork_master_id(dai);
-		if (!is_valid_etdm_dai(mst_dai_id))
-			return -EINVAL;
-		mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
-
-		for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
-			slv_dai_id = mst_etdm_data->cowork_slv_id[i];
-			ret = mt8188_afe_enable_etdm(afe, slv_dai_id);
-			if (ret) {
-				dev_dbg(afe->dev, "%s enable %d failed\n",
-					__func__, slv_dai_id);
-
-				return ret;
-			}
-		}
-
-		ret = mt8188_afe_enable_etdm(afe, mst_dai_id);
-		if (ret) {
-			dev_dbg(afe->dev, "%s enable %d failed\n",
-				__func__, mst_dai_id);
-
-			return ret;
-		}
-	} else {
-		ret = mt8188_afe_enable_etdm(afe, dai->id);
-		if (ret) {
-			dev_dbg(afe->dev, "%s enable %d failed\n",
-				__func__, dai->id);
-
-			return ret;
-		}
-	}
-
-	return 0;
-}
-
 static int mtk_dai_etdm_cal_mclk(struct mtk_base_afe *afe, int freq, int dai_id)
 {
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
@@ -2166,53 +2268,6 @@ static int mtk_dai_etdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 	return 0;
 }
 
-static int mtk_dai_hdmitx_dptx_startup(struct snd_pcm_substream *substream,
-				       struct snd_soc_dai *dai)
-{
-	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	int cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
-
-	if (cg_id >= 0)
-		mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]);
-
-	mtk_dai_etdm_enable_mclk(afe, dai->id);
-
-	return 0;
-}
-
-static void mtk_dai_hdmitx_dptx_shutdown(struct snd_pcm_substream *substream,
-					 struct snd_soc_dai *dai)
-{
-	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	int cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
-	struct mtk_dai_etdm_priv *etdm_data;
-	int ret;
-
-	if (!is_valid_etdm_dai(dai->id))
-		return;
-	etdm_data = afe_priv->dai_priv[dai->id];
-
-	if (etdm_data->is_prepared) {
-		etdm_data->is_prepared = false;
-		/* disable etdm_out3 */
-		ret = mt8188_afe_disable_etdm(afe, dai->id);
-		if (ret)
-			dev_dbg(afe->dev, "%s disable failed\n", __func__);
-
-		/* disable dptx interface */
-		if (dai->id == MT8188_AFE_IO_DPTX)
-			regmap_clear_bits(afe->regmap, AFE_DPTX_CON,
-					  AFE_DPTX_CON_ON);
-	}
-
-	mtk_dai_etdm_disable_mclk(afe, dai->id);
-
-	if (cg_id >= 0)
-		mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]);
-}
-
 static unsigned int mtk_dai_get_dptx_ch_en(unsigned int channel)
 {
 	switch (channel) {
@@ -2280,42 +2335,11 @@ static int mtk_dai_hdmitx_dptx_hw_params(struct snd_pcm_substream *substream,
 		etdm_data->data_mode = MTK_DAI_ETDM_DATA_MULTI_PIN;
 	}
 
-	ret = mtk_dai_etdm_mclk_configure(afe, dai->id);
-	if (ret)
-		return ret;
-
 	ret = mtk_dai_etdm_configure(afe, rate, channels, width, dai->id);
 
 	return ret;
 }
 
-static int mtk_dai_hdmitx_dptx_prepare(struct snd_pcm_substream *substream,
-				       struct snd_soc_dai *dai)
-{
-	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
-	struct mt8188_afe_private *afe_priv = afe->platform_priv;
-	struct mtk_dai_etdm_priv *etdm_data;
-
-	if (!is_valid_etdm_dai(dai->id))
-		return -EINVAL;
-	etdm_data = afe_priv->dai_priv[dai->id];
-
-	dev_dbg(afe->dev, "%s(), dai id %d, prepared %d\n", __func__, dai->id,
-		etdm_data->is_prepared);
-
-	if (etdm_data->is_prepared)
-		return 0;
-
-	etdm_data->is_prepared = true;
-
-	/* enable dptx interface */
-	if (dai->id == MT8188_AFE_IO_DPTX)
-		regmap_set_bits(afe->regmap, AFE_DPTX_CON, AFE_DPTX_CON_ON);
-
-	/* enable etdm_out3 */
-	return mt8188_afe_enable_etdm(afe, dai->id);
-}
-
 static int mtk_dai_hdmitx_dptx_set_sysclk(struct snd_soc_dai *dai,
 					  int clk_id,
 					  unsigned int freq,
@@ -2337,20 +2361,14 @@ static int mtk_dai_hdmitx_dptx_set_sysclk(struct snd_soc_dai *dai,
 }
 
 static const struct snd_soc_dai_ops mtk_dai_etdm_ops = {
-	.startup = mtk_dai_etdm_startup,
-	.shutdown = mtk_dai_etdm_shutdown,
 	.hw_params = mtk_dai_etdm_hw_params,
-	.prepare = mtk_dai_etdm_prepare,
 	.set_sysclk = mtk_dai_etdm_set_sysclk,
 	.set_fmt = mtk_dai_etdm_set_fmt,
 	.set_tdm_slot = mtk_dai_etdm_set_tdm_slot,
 };
 
 static const struct snd_soc_dai_ops mtk_dai_hdmitx_dptx_ops = {
-	.startup	= mtk_dai_hdmitx_dptx_startup,
-	.shutdown	= mtk_dai_hdmitx_dptx_shutdown,
 	.hw_params	= mtk_dai_hdmitx_dptx_hw_params,
-	.prepare	= mtk_dai_hdmitx_dptx_prepare,
 	.set_sysclk	= mtk_dai_hdmitx_dptx_set_sysclk,
 	.set_fmt	= mtk_dai_etdm_set_fmt,
 };
diff --git a/sound/soc/mediatek/mt8188/mt8188-reg.h b/sound/soc/mediatek/mt8188/mt8188-reg.h
index 51cd1a83dd9d..bdd885419ff3 100644
--- a/sound/soc/mediatek/mt8188/mt8188-reg.h
+++ b/sound/soc/mediatek/mt8188/mt8188-reg.h
@@ -3007,6 +3007,7 @@
 #define ETDM_CON0_SLAVE_MODE		BIT(5)
 #define ETDM_CON0_SYNC_MODE		BIT(1)
 #define ETDM_CON0_EN			BIT(0)
+#define ETDM_CON0_EN_SHIFT		0
 
 #define ETDM_OUT_CON0_RELATCH_DOMAIN_MASK	GENMASK(29, 28)
 
@@ -3108,6 +3109,7 @@
 #define AFE_DPTX_CON_CH_NUM_8CH		(0x1 << 1)
 #define AFE_DPTX_CON_CH_NUM_MASK	BIT(1)
 #define AFE_DPTX_CON_ON			BIT(0)
+#define AFE_DPTX_CON_ON_SHIFT		0
 
 /* AFE_ADDA_DL_SRC2_CON0 */
 #define DL_2_INPUT_MODE_CTL_MASK	GENMASK(31, 28)
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 4/7] ASoC: mediatek: mt8188: refine APLL control
  2023-04-26  5:51 ` Trevor Wu
                   ` (6 preceding siblings ...)
  (?)
@ 2023-04-26  5:51 ` Trevor Wu via Alsa-devel
  -1 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu via Alsa-devel @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree


[-- Attachment #0: Type: message/rfc822, Size: 19443 bytes --]

From: Trevor Wu <trevor.wu@mediatek.com>
To: <broonie@kernel.org>, <lgirdwood@gmail.com>, <tiwai@suse.com>, <perex@perex.cz>, <robh+dt@kernel.org>, <krzysztof.kozlowski+dt@linaro.org>, <matthias.bgg@gmail.com>, <angelogioacchino.delregno@collabora.com>
Cc: trevor.wu@mediatek.com, alsa-devel@alsa-project.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org
Subject: [PATCH v3 4/7] ASoC: mediatek: mt8188: refine APLL control
Date: Wed, 26 Apr 2023 13:51:21 +0800
Message-ID: <20230426055124.16529-5-trevor.wu@mediatek.com>

Currently, APLL is only used in ETDM module, so APLL and APLL tuner
don't need to be enabled when AFE is used. Integrate APLL control into
ETDM DAPM routes, so that APLL can be enabled when it is really required.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
 sound/soc/mediatek/mt8188/mt8188-afe-clk.c  | 138 ++++++++++++++++----
 sound/soc/mediatek/mt8188/mt8188-afe-clk.h  |  11 ++
 sound/soc/mediatek/mt8188/mt8188-dai-etdm.c | 115 ++++++++++++++++
 3 files changed, 241 insertions(+), 23 deletions(-)

diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
index 743d6a162cb9..02411be93900 100644
--- a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
@@ -24,6 +24,7 @@ static const char *aud_clks[MT8188_CLK_NUM] = {
 	[MT8188_CLK_APMIXED_APLL2] = "apll2",
 
 	/* divider */
+	[MT8188_CLK_TOP_APLL1_D4] = "apll1_d4",
 	[MT8188_CLK_TOP_APLL12_DIV0] = "apll12_div0",
 	[MT8188_CLK_TOP_APLL12_DIV1] = "apll12_div1",
 	[MT8188_CLK_TOP_APLL12_DIV2] = "apll12_div2",
@@ -378,6 +379,19 @@ int mt8188_afe_get_default_mclk_source_by_rate(int rate)
 		MT8188_MCK_SEL_APLL1 : MT8188_MCK_SEL_APLL2;
 }
 
+int mt8188_get_apll_by_rate(struct mtk_base_afe *afe, int rate)
+{
+	return ((rate % 8000) == 0) ? MT8188_AUD_PLL1 : MT8188_AUD_PLL2;
+}
+
+int mt8188_get_apll_by_name(struct mtk_base_afe *afe, const char *name)
+{
+	if (strcmp(name, APLL1_W_NAME) == 0)
+		return MT8188_AUD_PLL1;
+
+	return MT8188_AUD_PLL2;
+}
+
 int mt8188_afe_init_clock(struct mtk_base_afe *afe)
 {
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
@@ -477,8 +491,8 @@ int mt8188_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk,
 	if (clk && parent) {
 		ret = clk_set_parent(clk, parent);
 		if (ret) {
-			dev_dbg(afe->dev, "%s(), failed to set clk parent\n",
-				__func__);
+			dev_dbg(afe->dev, "%s(), failed to set clk parent %d\n",
+				__func__, ret);
 			return ret;
 		}
 	}
@@ -605,54 +619,132 @@ static int mt8188_afe_disable_afe_on(struct mtk_base_afe *afe)
 	return 0;
 }
 
-static int mt8188_afe_enable_timing_sys(struct mtk_base_afe *afe)
+static int mt8188_afe_enable_a1sys(struct mtk_base_afe *afe)
 {
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	int ret;
 
-	mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
-	mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]);
+	ret = mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
+	if (ret)
+		return ret;
 
-	mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING);
-	mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING);
-	mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_26M_TIMING);
+	return mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING);
+}
+
+static int mt8188_afe_disable_a1sys(struct mtk_base_afe *afe)
+{
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
 
+	mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING);
+	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
 	return 0;
 }
 
-static int mt8188_afe_disable_timing_sys(struct mtk_base_afe *afe)
+static int mt8188_afe_enable_a2sys(struct mtk_base_afe *afe)
 {
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	int ret;
 
-	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
-	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]);
+	ret = mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]);
+	if (ret)
+		return ret;
 
-	mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_26M_TIMING);
-	mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING);
-	mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING);
+	return mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING);
+}
+
+static int mt8188_afe_disable_a2sys(struct mtk_base_afe *afe)
+{
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
 
+	mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING);
+	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]);
 	return 0;
 }
 
-int mt8188_afe_enable_main_clock(struct mtk_base_afe *afe)
+int mt8188_apll1_enable(struct mtk_base_afe *afe)
 {
-	mt8188_afe_enable_timing_sys(afe);
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	int ret;
 
-	mt8188_afe_enable_afe_on(afe);
+	ret = mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]);
+	if (ret)
+		return ret;
+
+	ret = mt8188_afe_set_clk_parent(afe, afe_priv->clk[MT8188_CLK_TOP_A1SYS_HP_SEL],
+					afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]);
+	if (ret)
+		goto err_clk_parent;
 
-	mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL1);
-	mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL2);
+	ret = mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL1);
+	if (ret)
+		goto err_apll_tuner;
+
+	ret = mt8188_afe_enable_a1sys(afe);
+	if (ret)
+		goto err_a1sys;
 
 	return 0;
+
+err_a1sys:
+	mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL1);
+err_apll_tuner:
+	mt8188_afe_set_clk_parent(afe, afe_priv->clk[MT8188_CLK_TOP_A1SYS_HP_SEL],
+				  afe_priv->clk[MT8188_CLK_XTAL_26M]);
+err_clk_parent:
+	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]);
+
+	return ret;
 }
 
-int mt8188_afe_disable_main_clock(struct mtk_base_afe *afe)
+int mt8188_apll1_disable(struct mtk_base_afe *afe)
 {
-	mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL2);
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+
+	mt8188_afe_disable_a1sys(afe);
 	mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL1);
+	mt8188_afe_set_clk_parent(afe, afe_priv->clk[MT8188_CLK_TOP_A1SYS_HP_SEL],
+				  afe_priv->clk[MT8188_CLK_XTAL_26M]);
+	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]);
 
-	mt8188_afe_disable_afe_on(afe);
+	return 0;
+}
+
+int mt8188_apll2_enable(struct mtk_base_afe *afe)
+{
+	int ret;
 
-	mt8188_afe_disable_timing_sys(afe);
+	ret = mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL2);
+	if (ret)
+		return ret;
 
+	ret =  mt8188_afe_enable_a2sys(afe);
+	if (ret)
+		goto err_a2sys;
+
+	return 0;
+err_a2sys:
+	mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL2);
+
+	return ret;
+}
+
+int mt8188_apll2_disable(struct mtk_base_afe *afe)
+{
+	mt8188_afe_disable_a2sys(afe);
+	mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL2);
+	return 0;
+}
+
+int mt8188_afe_enable_main_clock(struct mtk_base_afe *afe)
+{
+	mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_26M_TIMING);
+	mt8188_afe_enable_afe_on(afe);
+	return 0;
+}
+
+int mt8188_afe_disable_main_clock(struct mtk_base_afe *afe)
+{
+	mt8188_afe_disable_afe_on(afe);
+	mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_26M_TIMING);
 	return 0;
 }
diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.h b/sound/soc/mediatek/mt8188/mt8188-afe-clk.h
index 084fdfb1d877..04cb476f0bcb 100644
--- a/sound/soc/mediatek/mt8188/mt8188-afe-clk.h
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.h
@@ -11,6 +11,10 @@
 #ifndef _MT8188_AFE_CLK_H_
 #define _MT8188_AFE_CLK_H_
 
+/* APLL */
+#define APLL1_W_NAME "APLL1"
+#define APLL2_W_NAME "APLL2"
+
 enum {
 	/* xtal */
 	MT8188_CLK_XTAL_26M,
@@ -18,6 +22,7 @@ enum {
 	MT8188_CLK_APMIXED_APLL1,
 	MT8188_CLK_APMIXED_APLL2,
 	/* divider */
+	MT8188_CLK_TOP_APLL1_D4,
 	MT8188_CLK_TOP_APLL12_DIV0,
 	MT8188_CLK_TOP_APLL12_DIV1,
 	MT8188_CLK_TOP_APLL12_DIV2,
@@ -99,6 +104,8 @@ struct mtk_base_afe;
 int mt8188_afe_get_mclk_source_clk_id(int sel);
 int mt8188_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll);
 int mt8188_afe_get_default_mclk_source_by_rate(int rate);
+int mt8188_get_apll_by_rate(struct mtk_base_afe *afe, int rate);
+int mt8188_get_apll_by_name(struct mtk_base_afe *afe, const char *name);
 int mt8188_afe_init_clock(struct mtk_base_afe *afe);
 void mt8188_afe_deinit_clock(void *priv);
 int mt8188_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk);
@@ -107,6 +114,10 @@ int mt8188_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk,
 			    unsigned int rate);
 int mt8188_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk,
 			      struct clk *parent);
+int mt8188_apll1_enable(struct mtk_base_afe *afe);
+int mt8188_apll1_disable(struct mtk_base_afe *afe);
+int mt8188_apll2_enable(struct mtk_base_afe *afe);
+int mt8188_apll2_disable(struct mtk_base_afe *afe);
 int mt8188_afe_enable_main_clock(struct mtk_base_afe *afe);
 int mt8188_afe_disable_main_clock(struct mtk_base_afe *afe);
 int mt8188_afe_enable_reg_rw_clk(struct mtk_base_afe *afe);
diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
index fd6e39a1e4c1..16440dd0a89c 100644
--- a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
+++ b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
@@ -22,6 +22,7 @@
 #define ENUM_TO_STR(x)	#x
 
 enum {
+	SUPPLY_SEQ_APLL,
 	SUPPLY_SEQ_ETDM_MCLK,
 	SUPPLY_SEQ_ETDM_CG,
 	SUPPLY_SEQ_DPTX_EN,
@@ -95,6 +96,7 @@ struct mtk_dai_etdm_priv {
 	bool slave_mode;
 	bool lrck_inv;
 	bool bck_inv;
+	unsigned int rate;
 	unsigned int format;
 	unsigned int slots;
 	unsigned int lrck_width;
@@ -360,6 +362,10 @@ static int get_etdm_id_by_name(struct mtk_base_afe *afe,
 		return MT8188_AFE_IO_ETDM1_OUT;
 	else if (!strncmp(name, "ETDM2_OUT", strlen("ETDM2_OUT")))
 		return MT8188_AFE_IO_ETDM2_OUT;
+	else if (!strncmp(name, "ETDM3_OUT", strlen("ETDM3_OUT")))
+		return MT8188_AFE_IO_ETDM3_OUT;
+	else if (!strncmp(name, "DPTX", strlen("DPTX")))
+		return MT8188_AFE_IO_ETDM3_OUT;
 	else
 		return -EINVAL;
 }
@@ -445,6 +451,44 @@ static int mtk_dai_etdm_disable_mclk(struct mtk_base_afe *afe, int dai_id)
 	return 0;
 }
 
+static int mtk_afe_etdm_apll_connect(struct snd_soc_dapm_widget *source,
+				     struct snd_soc_dapm_widget *sink)
+{
+	struct snd_soc_dapm_widget *w = sink;
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mtk_dai_etdm_priv *etdm_priv;
+	int cur_apll;
+	int need_apll;
+
+	etdm_priv = get_etdm_priv_by_name(afe, w->name);
+	if (!etdm_priv) {
+		dev_dbg(afe->dev, "etdm_priv == NULL\n");
+		return 0;
+	}
+
+	cur_apll = mt8188_get_apll_by_name(afe, source->name);
+	need_apll = mt8188_get_apll_by_rate(afe, etdm_priv->rate);
+
+	return (need_apll == cur_apll) ? 1 : 0;
+}
+
+static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source,
+				     struct snd_soc_dapm_widget *sink)
+{
+	struct snd_soc_dapm_widget *w = sink;
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mtk_dai_etdm_priv *etdm_priv;
+	int cur_apll;
+
+	etdm_priv = get_etdm_priv_by_name(afe, w->name);
+
+	cur_apll = mt8188_get_apll_by_name(afe, source->name);
+
+	return (etdm_priv->mclk_apll == cur_apll) ? 1 : 0;
+}
+
 static int mtk_etdm_mclk_connect(struct snd_soc_dapm_widget *source,
 				 struct snd_soc_dapm_widget *sink)
 {
@@ -520,6 +564,36 @@ static int mtk_etdm_cowork_connect(struct snd_soc_dapm_widget *source,
 	return 0;
 }
 
+static int mtk_apll_event(struct snd_soc_dapm_widget *w,
+			  struct snd_kcontrol *kcontrol,
+			  int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+
+	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		if (strcmp(w->name, APLL1_W_NAME) == 0)
+			mt8188_apll1_enable(afe);
+		else
+			mt8188_apll2_enable(afe);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		if (strcmp(w->name, APLL1_W_NAME) == 0)
+			mt8188_apll1_disable(afe);
+		else
+			mt8188_apll2_disable(afe);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
 static int mtk_etdm_mclk_event(struct snd_soc_dapm_widget *w,
 			       struct snd_kcontrol *kcontrol,
 			       int event)
@@ -1231,6 +1305,16 @@ static const struct snd_soc_dapm_widget mtk_dai_etdm_widgets[] = {
 	SND_SOC_DAPM_SUPPLY_S("DPTX_EN", SUPPLY_SEQ_DPTX_EN,
 			      AFE_DPTX_CON, AFE_DPTX_CON_ON_SHIFT, 0, NULL, 0),
 
+	/* apll */
+	SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_apll_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_apll_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
 	SND_SOC_DAPM_INPUT("ETDM_INPUT"),
 	SND_SOC_DAPM_OUTPUT("ETDM_OUTPUT"),
 };
@@ -1259,6 +1343,21 @@ static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = {
 
 	{"DPTX", NULL, "DPTX_MCLK"},
 
+	{"ETDM1_IN_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
+	{"ETDM1_IN_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
+
+	{"ETDM2_IN_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
+	{"ETDM2_IN_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
+
+	{"ETDM1_OUT_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
+	{"ETDM1_OUT_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
+
+	{"ETDM2_OUT_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
+	{"ETDM2_OUT_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
+
+	{"DPTX_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
+	{"DPTX_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
+
 	/* cg */
 	{"ETDM1_IN", NULL, "ETDM1_IN_CG"},
 	{"ETDM1_IN", NULL, "ETDM2_IN_CG", mtk_etdm_cowork_connect},
@@ -1308,6 +1407,21 @@ static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = {
 	{"DPTX", NULL, "ETDM3_OUT_EN"},
 	{"DPTX", NULL, "DPTX_EN"},
 
+	{"ETDM1_IN_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},
+	{"ETDM1_IN_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},
+
+	{"ETDM2_IN_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},
+	{"ETDM2_IN_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},
+
+	{"ETDM1_OUT_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},
+	{"ETDM1_OUT_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},
+
+	{"ETDM2_OUT_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},
+	{"ETDM2_OUT_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},
+
+	{"ETDM3_OUT_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},
+	{"ETDM3_OUT_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},
+
 	{"I012", NULL, "ETDM2_IN"},
 	{"I013", NULL, "ETDM2_IN"},
 	{"I014", NULL, "ETDM2_IN"},
@@ -2004,6 +2118,7 @@ static int mtk_dai_etdm_configure(struct mtk_base_afe *afe,
 		return -EINVAL;
 	etdm_data = afe_priv->dai_priv[dai_id];
 	slave_mode = etdm_data->slave_mode;
+	etdm_data->rate = rate;
 
 	ret = get_etdm_reg(dai_id, &etdm_reg);
 	if (ret < 0)
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 4/7] ASoC: mediatek: mt8188: refine APLL control
  2023-04-26  5:51 ` Trevor Wu
@ 2023-04-26  5:51   ` Trevor Wu
  -1 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree

Currently, APLL is only used in ETDM module, so APLL and APLL tuner
don't need to be enabled when AFE is used. Integrate APLL control into
ETDM DAPM routes, so that APLL can be enabled when it is really required.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
 sound/soc/mediatek/mt8188/mt8188-afe-clk.c  | 138 ++++++++++++++++----
 sound/soc/mediatek/mt8188/mt8188-afe-clk.h  |  11 ++
 sound/soc/mediatek/mt8188/mt8188-dai-etdm.c | 115 ++++++++++++++++
 3 files changed, 241 insertions(+), 23 deletions(-)

diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
index 743d6a162cb9..02411be93900 100644
--- a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
@@ -24,6 +24,7 @@ static const char *aud_clks[MT8188_CLK_NUM] = {
 	[MT8188_CLK_APMIXED_APLL2] = "apll2",
 
 	/* divider */
+	[MT8188_CLK_TOP_APLL1_D4] = "apll1_d4",
 	[MT8188_CLK_TOP_APLL12_DIV0] = "apll12_div0",
 	[MT8188_CLK_TOP_APLL12_DIV1] = "apll12_div1",
 	[MT8188_CLK_TOP_APLL12_DIV2] = "apll12_div2",
@@ -378,6 +379,19 @@ int mt8188_afe_get_default_mclk_source_by_rate(int rate)
 		MT8188_MCK_SEL_APLL1 : MT8188_MCK_SEL_APLL2;
 }
 
+int mt8188_get_apll_by_rate(struct mtk_base_afe *afe, int rate)
+{
+	return ((rate % 8000) == 0) ? MT8188_AUD_PLL1 : MT8188_AUD_PLL2;
+}
+
+int mt8188_get_apll_by_name(struct mtk_base_afe *afe, const char *name)
+{
+	if (strcmp(name, APLL1_W_NAME) == 0)
+		return MT8188_AUD_PLL1;
+
+	return MT8188_AUD_PLL2;
+}
+
 int mt8188_afe_init_clock(struct mtk_base_afe *afe)
 {
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
@@ -477,8 +491,8 @@ int mt8188_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk,
 	if (clk && parent) {
 		ret = clk_set_parent(clk, parent);
 		if (ret) {
-			dev_dbg(afe->dev, "%s(), failed to set clk parent\n",
-				__func__);
+			dev_dbg(afe->dev, "%s(), failed to set clk parent %d\n",
+				__func__, ret);
 			return ret;
 		}
 	}
@@ -605,54 +619,132 @@ static int mt8188_afe_disable_afe_on(struct mtk_base_afe *afe)
 	return 0;
 }
 
-static int mt8188_afe_enable_timing_sys(struct mtk_base_afe *afe)
+static int mt8188_afe_enable_a1sys(struct mtk_base_afe *afe)
 {
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	int ret;
 
-	mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
-	mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]);
+	ret = mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
+	if (ret)
+		return ret;
 
-	mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING);
-	mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING);
-	mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_26M_TIMING);
+	return mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING);
+}
+
+static int mt8188_afe_disable_a1sys(struct mtk_base_afe *afe)
+{
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
 
+	mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING);
+	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
 	return 0;
 }
 
-static int mt8188_afe_disable_timing_sys(struct mtk_base_afe *afe)
+static int mt8188_afe_enable_a2sys(struct mtk_base_afe *afe)
 {
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	int ret;
 
-	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
-	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]);
+	ret = mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]);
+	if (ret)
+		return ret;
 
-	mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_26M_TIMING);
-	mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING);
-	mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING);
+	return mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING);
+}
+
+static int mt8188_afe_disable_a2sys(struct mtk_base_afe *afe)
+{
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
 
+	mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING);
+	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]);
 	return 0;
 }
 
-int mt8188_afe_enable_main_clock(struct mtk_base_afe *afe)
+int mt8188_apll1_enable(struct mtk_base_afe *afe)
 {
-	mt8188_afe_enable_timing_sys(afe);
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	int ret;
 
-	mt8188_afe_enable_afe_on(afe);
+	ret = mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]);
+	if (ret)
+		return ret;
+
+	ret = mt8188_afe_set_clk_parent(afe, afe_priv->clk[MT8188_CLK_TOP_A1SYS_HP_SEL],
+					afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]);
+	if (ret)
+		goto err_clk_parent;
 
-	mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL1);
-	mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL2);
+	ret = mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL1);
+	if (ret)
+		goto err_apll_tuner;
+
+	ret = mt8188_afe_enable_a1sys(afe);
+	if (ret)
+		goto err_a1sys;
 
 	return 0;
+
+err_a1sys:
+	mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL1);
+err_apll_tuner:
+	mt8188_afe_set_clk_parent(afe, afe_priv->clk[MT8188_CLK_TOP_A1SYS_HP_SEL],
+				  afe_priv->clk[MT8188_CLK_XTAL_26M]);
+err_clk_parent:
+	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]);
+
+	return ret;
 }
 
-int mt8188_afe_disable_main_clock(struct mtk_base_afe *afe)
+int mt8188_apll1_disable(struct mtk_base_afe *afe)
 {
-	mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL2);
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+
+	mt8188_afe_disable_a1sys(afe);
 	mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL1);
+	mt8188_afe_set_clk_parent(afe, afe_priv->clk[MT8188_CLK_TOP_A1SYS_HP_SEL],
+				  afe_priv->clk[MT8188_CLK_XTAL_26M]);
+	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]);
 
-	mt8188_afe_disable_afe_on(afe);
+	return 0;
+}
+
+int mt8188_apll2_enable(struct mtk_base_afe *afe)
+{
+	int ret;
 
-	mt8188_afe_disable_timing_sys(afe);
+	ret = mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL2);
+	if (ret)
+		return ret;
 
+	ret =  mt8188_afe_enable_a2sys(afe);
+	if (ret)
+		goto err_a2sys;
+
+	return 0;
+err_a2sys:
+	mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL2);
+
+	return ret;
+}
+
+int mt8188_apll2_disable(struct mtk_base_afe *afe)
+{
+	mt8188_afe_disable_a2sys(afe);
+	mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL2);
+	return 0;
+}
+
+int mt8188_afe_enable_main_clock(struct mtk_base_afe *afe)
+{
+	mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_26M_TIMING);
+	mt8188_afe_enable_afe_on(afe);
+	return 0;
+}
+
+int mt8188_afe_disable_main_clock(struct mtk_base_afe *afe)
+{
+	mt8188_afe_disable_afe_on(afe);
+	mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_26M_TIMING);
 	return 0;
 }
diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.h b/sound/soc/mediatek/mt8188/mt8188-afe-clk.h
index 084fdfb1d877..04cb476f0bcb 100644
--- a/sound/soc/mediatek/mt8188/mt8188-afe-clk.h
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.h
@@ -11,6 +11,10 @@
 #ifndef _MT8188_AFE_CLK_H_
 #define _MT8188_AFE_CLK_H_
 
+/* APLL */
+#define APLL1_W_NAME "APLL1"
+#define APLL2_W_NAME "APLL2"
+
 enum {
 	/* xtal */
 	MT8188_CLK_XTAL_26M,
@@ -18,6 +22,7 @@ enum {
 	MT8188_CLK_APMIXED_APLL1,
 	MT8188_CLK_APMIXED_APLL2,
 	/* divider */
+	MT8188_CLK_TOP_APLL1_D4,
 	MT8188_CLK_TOP_APLL12_DIV0,
 	MT8188_CLK_TOP_APLL12_DIV1,
 	MT8188_CLK_TOP_APLL12_DIV2,
@@ -99,6 +104,8 @@ struct mtk_base_afe;
 int mt8188_afe_get_mclk_source_clk_id(int sel);
 int mt8188_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll);
 int mt8188_afe_get_default_mclk_source_by_rate(int rate);
+int mt8188_get_apll_by_rate(struct mtk_base_afe *afe, int rate);
+int mt8188_get_apll_by_name(struct mtk_base_afe *afe, const char *name);
 int mt8188_afe_init_clock(struct mtk_base_afe *afe);
 void mt8188_afe_deinit_clock(void *priv);
 int mt8188_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk);
@@ -107,6 +114,10 @@ int mt8188_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk,
 			    unsigned int rate);
 int mt8188_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk,
 			      struct clk *parent);
+int mt8188_apll1_enable(struct mtk_base_afe *afe);
+int mt8188_apll1_disable(struct mtk_base_afe *afe);
+int mt8188_apll2_enable(struct mtk_base_afe *afe);
+int mt8188_apll2_disable(struct mtk_base_afe *afe);
 int mt8188_afe_enable_main_clock(struct mtk_base_afe *afe);
 int mt8188_afe_disable_main_clock(struct mtk_base_afe *afe);
 int mt8188_afe_enable_reg_rw_clk(struct mtk_base_afe *afe);
diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
index fd6e39a1e4c1..16440dd0a89c 100644
--- a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
+++ b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
@@ -22,6 +22,7 @@
 #define ENUM_TO_STR(x)	#x
 
 enum {
+	SUPPLY_SEQ_APLL,
 	SUPPLY_SEQ_ETDM_MCLK,
 	SUPPLY_SEQ_ETDM_CG,
 	SUPPLY_SEQ_DPTX_EN,
@@ -95,6 +96,7 @@ struct mtk_dai_etdm_priv {
 	bool slave_mode;
 	bool lrck_inv;
 	bool bck_inv;
+	unsigned int rate;
 	unsigned int format;
 	unsigned int slots;
 	unsigned int lrck_width;
@@ -360,6 +362,10 @@ static int get_etdm_id_by_name(struct mtk_base_afe *afe,
 		return MT8188_AFE_IO_ETDM1_OUT;
 	else if (!strncmp(name, "ETDM2_OUT", strlen("ETDM2_OUT")))
 		return MT8188_AFE_IO_ETDM2_OUT;
+	else if (!strncmp(name, "ETDM3_OUT", strlen("ETDM3_OUT")))
+		return MT8188_AFE_IO_ETDM3_OUT;
+	else if (!strncmp(name, "DPTX", strlen("DPTX")))
+		return MT8188_AFE_IO_ETDM3_OUT;
 	else
 		return -EINVAL;
 }
@@ -445,6 +451,44 @@ static int mtk_dai_etdm_disable_mclk(struct mtk_base_afe *afe, int dai_id)
 	return 0;
 }
 
+static int mtk_afe_etdm_apll_connect(struct snd_soc_dapm_widget *source,
+				     struct snd_soc_dapm_widget *sink)
+{
+	struct snd_soc_dapm_widget *w = sink;
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mtk_dai_etdm_priv *etdm_priv;
+	int cur_apll;
+	int need_apll;
+
+	etdm_priv = get_etdm_priv_by_name(afe, w->name);
+	if (!etdm_priv) {
+		dev_dbg(afe->dev, "etdm_priv == NULL\n");
+		return 0;
+	}
+
+	cur_apll = mt8188_get_apll_by_name(afe, source->name);
+	need_apll = mt8188_get_apll_by_rate(afe, etdm_priv->rate);
+
+	return (need_apll == cur_apll) ? 1 : 0;
+}
+
+static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source,
+				     struct snd_soc_dapm_widget *sink)
+{
+	struct snd_soc_dapm_widget *w = sink;
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mtk_dai_etdm_priv *etdm_priv;
+	int cur_apll;
+
+	etdm_priv = get_etdm_priv_by_name(afe, w->name);
+
+	cur_apll = mt8188_get_apll_by_name(afe, source->name);
+
+	return (etdm_priv->mclk_apll == cur_apll) ? 1 : 0;
+}
+
 static int mtk_etdm_mclk_connect(struct snd_soc_dapm_widget *source,
 				 struct snd_soc_dapm_widget *sink)
 {
@@ -520,6 +564,36 @@ static int mtk_etdm_cowork_connect(struct snd_soc_dapm_widget *source,
 	return 0;
 }
 
+static int mtk_apll_event(struct snd_soc_dapm_widget *w,
+			  struct snd_kcontrol *kcontrol,
+			  int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+
+	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		if (strcmp(w->name, APLL1_W_NAME) == 0)
+			mt8188_apll1_enable(afe);
+		else
+			mt8188_apll2_enable(afe);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		if (strcmp(w->name, APLL1_W_NAME) == 0)
+			mt8188_apll1_disable(afe);
+		else
+			mt8188_apll2_disable(afe);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
 static int mtk_etdm_mclk_event(struct snd_soc_dapm_widget *w,
 			       struct snd_kcontrol *kcontrol,
 			       int event)
@@ -1231,6 +1305,16 @@ static const struct snd_soc_dapm_widget mtk_dai_etdm_widgets[] = {
 	SND_SOC_DAPM_SUPPLY_S("DPTX_EN", SUPPLY_SEQ_DPTX_EN,
 			      AFE_DPTX_CON, AFE_DPTX_CON_ON_SHIFT, 0, NULL, 0),
 
+	/* apll */
+	SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_apll_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_apll_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
 	SND_SOC_DAPM_INPUT("ETDM_INPUT"),
 	SND_SOC_DAPM_OUTPUT("ETDM_OUTPUT"),
 };
@@ -1259,6 +1343,21 @@ static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = {
 
 	{"DPTX", NULL, "DPTX_MCLK"},
 
+	{"ETDM1_IN_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
+	{"ETDM1_IN_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
+
+	{"ETDM2_IN_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
+	{"ETDM2_IN_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
+
+	{"ETDM1_OUT_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
+	{"ETDM1_OUT_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
+
+	{"ETDM2_OUT_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
+	{"ETDM2_OUT_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
+
+	{"DPTX_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
+	{"DPTX_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
+
 	/* cg */
 	{"ETDM1_IN", NULL, "ETDM1_IN_CG"},
 	{"ETDM1_IN", NULL, "ETDM2_IN_CG", mtk_etdm_cowork_connect},
@@ -1308,6 +1407,21 @@ static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = {
 	{"DPTX", NULL, "ETDM3_OUT_EN"},
 	{"DPTX", NULL, "DPTX_EN"},
 
+	{"ETDM1_IN_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},
+	{"ETDM1_IN_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},
+
+	{"ETDM2_IN_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},
+	{"ETDM2_IN_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},
+
+	{"ETDM1_OUT_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},
+	{"ETDM1_OUT_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},
+
+	{"ETDM2_OUT_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},
+	{"ETDM2_OUT_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},
+
+	{"ETDM3_OUT_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},
+	{"ETDM3_OUT_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},
+
 	{"I012", NULL, "ETDM2_IN"},
 	{"I013", NULL, "ETDM2_IN"},
 	{"I014", NULL, "ETDM2_IN"},
@@ -2004,6 +2118,7 @@ static int mtk_dai_etdm_configure(struct mtk_base_afe *afe,
 		return -EINVAL;
 	etdm_data = afe_priv->dai_priv[dai_id];
 	slave_mode = etdm_data->slave_mode;
+	etdm_data->rate = rate;
 
 	ret = get_etdm_reg(dai_id, &etdm_reg);
 	if (ret < 0)
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 4/7] ASoC: mediatek: mt8188: refine APLL control
@ 2023-04-26  5:51   ` Trevor Wu
  0 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree

Currently, APLL is only used in ETDM module, so APLL and APLL tuner
don't need to be enabled when AFE is used. Integrate APLL control into
ETDM DAPM routes, so that APLL can be enabled when it is really required.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
 sound/soc/mediatek/mt8188/mt8188-afe-clk.c  | 138 ++++++++++++++++----
 sound/soc/mediatek/mt8188/mt8188-afe-clk.h  |  11 ++
 sound/soc/mediatek/mt8188/mt8188-dai-etdm.c | 115 ++++++++++++++++
 3 files changed, 241 insertions(+), 23 deletions(-)

diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
index 743d6a162cb9..02411be93900 100644
--- a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
@@ -24,6 +24,7 @@ static const char *aud_clks[MT8188_CLK_NUM] = {
 	[MT8188_CLK_APMIXED_APLL2] = "apll2",
 
 	/* divider */
+	[MT8188_CLK_TOP_APLL1_D4] = "apll1_d4",
 	[MT8188_CLK_TOP_APLL12_DIV0] = "apll12_div0",
 	[MT8188_CLK_TOP_APLL12_DIV1] = "apll12_div1",
 	[MT8188_CLK_TOP_APLL12_DIV2] = "apll12_div2",
@@ -378,6 +379,19 @@ int mt8188_afe_get_default_mclk_source_by_rate(int rate)
 		MT8188_MCK_SEL_APLL1 : MT8188_MCK_SEL_APLL2;
 }
 
+int mt8188_get_apll_by_rate(struct mtk_base_afe *afe, int rate)
+{
+	return ((rate % 8000) == 0) ? MT8188_AUD_PLL1 : MT8188_AUD_PLL2;
+}
+
+int mt8188_get_apll_by_name(struct mtk_base_afe *afe, const char *name)
+{
+	if (strcmp(name, APLL1_W_NAME) == 0)
+		return MT8188_AUD_PLL1;
+
+	return MT8188_AUD_PLL2;
+}
+
 int mt8188_afe_init_clock(struct mtk_base_afe *afe)
 {
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
@@ -477,8 +491,8 @@ int mt8188_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk,
 	if (clk && parent) {
 		ret = clk_set_parent(clk, parent);
 		if (ret) {
-			dev_dbg(afe->dev, "%s(), failed to set clk parent\n",
-				__func__);
+			dev_dbg(afe->dev, "%s(), failed to set clk parent %d\n",
+				__func__, ret);
 			return ret;
 		}
 	}
@@ -605,54 +619,132 @@ static int mt8188_afe_disable_afe_on(struct mtk_base_afe *afe)
 	return 0;
 }
 
-static int mt8188_afe_enable_timing_sys(struct mtk_base_afe *afe)
+static int mt8188_afe_enable_a1sys(struct mtk_base_afe *afe)
 {
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	int ret;
 
-	mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
-	mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]);
+	ret = mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
+	if (ret)
+		return ret;
 
-	mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING);
-	mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING);
-	mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_26M_TIMING);
+	return mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING);
+}
+
+static int mt8188_afe_disable_a1sys(struct mtk_base_afe *afe)
+{
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
 
+	mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING);
+	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
 	return 0;
 }
 
-static int mt8188_afe_disable_timing_sys(struct mtk_base_afe *afe)
+static int mt8188_afe_enable_a2sys(struct mtk_base_afe *afe)
 {
 	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	int ret;
 
-	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
-	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]);
+	ret = mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]);
+	if (ret)
+		return ret;
 
-	mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_26M_TIMING);
-	mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING);
-	mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING);
+	return mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING);
+}
+
+static int mt8188_afe_disable_a2sys(struct mtk_base_afe *afe)
+{
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
 
+	mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING);
+	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]);
 	return 0;
 }
 
-int mt8188_afe_enable_main_clock(struct mtk_base_afe *afe)
+int mt8188_apll1_enable(struct mtk_base_afe *afe)
 {
-	mt8188_afe_enable_timing_sys(afe);
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+	int ret;
 
-	mt8188_afe_enable_afe_on(afe);
+	ret = mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]);
+	if (ret)
+		return ret;
+
+	ret = mt8188_afe_set_clk_parent(afe, afe_priv->clk[MT8188_CLK_TOP_A1SYS_HP_SEL],
+					afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]);
+	if (ret)
+		goto err_clk_parent;
 
-	mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL1);
-	mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL2);
+	ret = mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL1);
+	if (ret)
+		goto err_apll_tuner;
+
+	ret = mt8188_afe_enable_a1sys(afe);
+	if (ret)
+		goto err_a1sys;
 
 	return 0;
+
+err_a1sys:
+	mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL1);
+err_apll_tuner:
+	mt8188_afe_set_clk_parent(afe, afe_priv->clk[MT8188_CLK_TOP_A1SYS_HP_SEL],
+				  afe_priv->clk[MT8188_CLK_XTAL_26M]);
+err_clk_parent:
+	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]);
+
+	return ret;
 }
 
-int mt8188_afe_disable_main_clock(struct mtk_base_afe *afe)
+int mt8188_apll1_disable(struct mtk_base_afe *afe)
 {
-	mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL2);
+	struct mt8188_afe_private *afe_priv = afe->platform_priv;
+
+	mt8188_afe_disable_a1sys(afe);
 	mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL1);
+	mt8188_afe_set_clk_parent(afe, afe_priv->clk[MT8188_CLK_TOP_A1SYS_HP_SEL],
+				  afe_priv->clk[MT8188_CLK_XTAL_26M]);
+	mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]);
 
-	mt8188_afe_disable_afe_on(afe);
+	return 0;
+}
+
+int mt8188_apll2_enable(struct mtk_base_afe *afe)
+{
+	int ret;
 
-	mt8188_afe_disable_timing_sys(afe);
+	ret = mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL2);
+	if (ret)
+		return ret;
 
+	ret =  mt8188_afe_enable_a2sys(afe);
+	if (ret)
+		goto err_a2sys;
+
+	return 0;
+err_a2sys:
+	mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL2);
+
+	return ret;
+}
+
+int mt8188_apll2_disable(struct mtk_base_afe *afe)
+{
+	mt8188_afe_disable_a2sys(afe);
+	mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL2);
+	return 0;
+}
+
+int mt8188_afe_enable_main_clock(struct mtk_base_afe *afe)
+{
+	mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_26M_TIMING);
+	mt8188_afe_enable_afe_on(afe);
+	return 0;
+}
+
+int mt8188_afe_disable_main_clock(struct mtk_base_afe *afe)
+{
+	mt8188_afe_disable_afe_on(afe);
+	mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_26M_TIMING);
 	return 0;
 }
diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.h b/sound/soc/mediatek/mt8188/mt8188-afe-clk.h
index 084fdfb1d877..04cb476f0bcb 100644
--- a/sound/soc/mediatek/mt8188/mt8188-afe-clk.h
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.h
@@ -11,6 +11,10 @@
 #ifndef _MT8188_AFE_CLK_H_
 #define _MT8188_AFE_CLK_H_
 
+/* APLL */
+#define APLL1_W_NAME "APLL1"
+#define APLL2_W_NAME "APLL2"
+
 enum {
 	/* xtal */
 	MT8188_CLK_XTAL_26M,
@@ -18,6 +22,7 @@ enum {
 	MT8188_CLK_APMIXED_APLL1,
 	MT8188_CLK_APMIXED_APLL2,
 	/* divider */
+	MT8188_CLK_TOP_APLL1_D4,
 	MT8188_CLK_TOP_APLL12_DIV0,
 	MT8188_CLK_TOP_APLL12_DIV1,
 	MT8188_CLK_TOP_APLL12_DIV2,
@@ -99,6 +104,8 @@ struct mtk_base_afe;
 int mt8188_afe_get_mclk_source_clk_id(int sel);
 int mt8188_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll);
 int mt8188_afe_get_default_mclk_source_by_rate(int rate);
+int mt8188_get_apll_by_rate(struct mtk_base_afe *afe, int rate);
+int mt8188_get_apll_by_name(struct mtk_base_afe *afe, const char *name);
 int mt8188_afe_init_clock(struct mtk_base_afe *afe);
 void mt8188_afe_deinit_clock(void *priv);
 int mt8188_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk);
@@ -107,6 +114,10 @@ int mt8188_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk,
 			    unsigned int rate);
 int mt8188_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk,
 			      struct clk *parent);
+int mt8188_apll1_enable(struct mtk_base_afe *afe);
+int mt8188_apll1_disable(struct mtk_base_afe *afe);
+int mt8188_apll2_enable(struct mtk_base_afe *afe);
+int mt8188_apll2_disable(struct mtk_base_afe *afe);
 int mt8188_afe_enable_main_clock(struct mtk_base_afe *afe);
 int mt8188_afe_disable_main_clock(struct mtk_base_afe *afe);
 int mt8188_afe_enable_reg_rw_clk(struct mtk_base_afe *afe);
diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
index fd6e39a1e4c1..16440dd0a89c 100644
--- a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
+++ b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
@@ -22,6 +22,7 @@
 #define ENUM_TO_STR(x)	#x
 
 enum {
+	SUPPLY_SEQ_APLL,
 	SUPPLY_SEQ_ETDM_MCLK,
 	SUPPLY_SEQ_ETDM_CG,
 	SUPPLY_SEQ_DPTX_EN,
@@ -95,6 +96,7 @@ struct mtk_dai_etdm_priv {
 	bool slave_mode;
 	bool lrck_inv;
 	bool bck_inv;
+	unsigned int rate;
 	unsigned int format;
 	unsigned int slots;
 	unsigned int lrck_width;
@@ -360,6 +362,10 @@ static int get_etdm_id_by_name(struct mtk_base_afe *afe,
 		return MT8188_AFE_IO_ETDM1_OUT;
 	else if (!strncmp(name, "ETDM2_OUT", strlen("ETDM2_OUT")))
 		return MT8188_AFE_IO_ETDM2_OUT;
+	else if (!strncmp(name, "ETDM3_OUT", strlen("ETDM3_OUT")))
+		return MT8188_AFE_IO_ETDM3_OUT;
+	else if (!strncmp(name, "DPTX", strlen("DPTX")))
+		return MT8188_AFE_IO_ETDM3_OUT;
 	else
 		return -EINVAL;
 }
@@ -445,6 +451,44 @@ static int mtk_dai_etdm_disable_mclk(struct mtk_base_afe *afe, int dai_id)
 	return 0;
 }
 
+static int mtk_afe_etdm_apll_connect(struct snd_soc_dapm_widget *source,
+				     struct snd_soc_dapm_widget *sink)
+{
+	struct snd_soc_dapm_widget *w = sink;
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mtk_dai_etdm_priv *etdm_priv;
+	int cur_apll;
+	int need_apll;
+
+	etdm_priv = get_etdm_priv_by_name(afe, w->name);
+	if (!etdm_priv) {
+		dev_dbg(afe->dev, "etdm_priv == NULL\n");
+		return 0;
+	}
+
+	cur_apll = mt8188_get_apll_by_name(afe, source->name);
+	need_apll = mt8188_get_apll_by_rate(afe, etdm_priv->rate);
+
+	return (need_apll == cur_apll) ? 1 : 0;
+}
+
+static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source,
+				     struct snd_soc_dapm_widget *sink)
+{
+	struct snd_soc_dapm_widget *w = sink;
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+	struct mtk_dai_etdm_priv *etdm_priv;
+	int cur_apll;
+
+	etdm_priv = get_etdm_priv_by_name(afe, w->name);
+
+	cur_apll = mt8188_get_apll_by_name(afe, source->name);
+
+	return (etdm_priv->mclk_apll == cur_apll) ? 1 : 0;
+}
+
 static int mtk_etdm_mclk_connect(struct snd_soc_dapm_widget *source,
 				 struct snd_soc_dapm_widget *sink)
 {
@@ -520,6 +564,36 @@ static int mtk_etdm_cowork_connect(struct snd_soc_dapm_widget *source,
 	return 0;
 }
 
+static int mtk_apll_event(struct snd_soc_dapm_widget *w,
+			  struct snd_kcontrol *kcontrol,
+			  int event)
+{
+	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+
+	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
+		__func__, w->name, event);
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		if (strcmp(w->name, APLL1_W_NAME) == 0)
+			mt8188_apll1_enable(afe);
+		else
+			mt8188_apll2_enable(afe);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		if (strcmp(w->name, APLL1_W_NAME) == 0)
+			mt8188_apll1_disable(afe);
+		else
+			mt8188_apll2_disable(afe);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
 static int mtk_etdm_mclk_event(struct snd_soc_dapm_widget *w,
 			       struct snd_kcontrol *kcontrol,
 			       int event)
@@ -1231,6 +1305,16 @@ static const struct snd_soc_dapm_widget mtk_dai_etdm_widgets[] = {
 	SND_SOC_DAPM_SUPPLY_S("DPTX_EN", SUPPLY_SEQ_DPTX_EN,
 			      AFE_DPTX_CON, AFE_DPTX_CON_ON_SHIFT, 0, NULL, 0),
 
+	/* apll */
+	SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_apll_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL,
+			      SND_SOC_NOPM, 0, 0,
+			      mtk_apll_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
 	SND_SOC_DAPM_INPUT("ETDM_INPUT"),
 	SND_SOC_DAPM_OUTPUT("ETDM_OUTPUT"),
 };
@@ -1259,6 +1343,21 @@ static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = {
 
 	{"DPTX", NULL, "DPTX_MCLK"},
 
+	{"ETDM1_IN_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
+	{"ETDM1_IN_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
+
+	{"ETDM2_IN_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
+	{"ETDM2_IN_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
+
+	{"ETDM1_OUT_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
+	{"ETDM1_OUT_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
+
+	{"ETDM2_OUT_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
+	{"ETDM2_OUT_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
+
+	{"DPTX_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
+	{"DPTX_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
+
 	/* cg */
 	{"ETDM1_IN", NULL, "ETDM1_IN_CG"},
 	{"ETDM1_IN", NULL, "ETDM2_IN_CG", mtk_etdm_cowork_connect},
@@ -1308,6 +1407,21 @@ static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = {
 	{"DPTX", NULL, "ETDM3_OUT_EN"},
 	{"DPTX", NULL, "DPTX_EN"},
 
+	{"ETDM1_IN_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},
+	{"ETDM1_IN_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},
+
+	{"ETDM2_IN_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},
+	{"ETDM2_IN_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},
+
+	{"ETDM1_OUT_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},
+	{"ETDM1_OUT_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},
+
+	{"ETDM2_OUT_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},
+	{"ETDM2_OUT_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},
+
+	{"ETDM3_OUT_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},
+	{"ETDM3_OUT_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},
+
 	{"I012", NULL, "ETDM2_IN"},
 	{"I013", NULL, "ETDM2_IN"},
 	{"I014", NULL, "ETDM2_IN"},
@@ -2004,6 +2118,7 @@ static int mtk_dai_etdm_configure(struct mtk_base_afe *afe,
 		return -EINVAL;
 	etdm_data = afe_priv->dai_priv[dai_id];
 	slave_mode = etdm_data->slave_mode;
+	etdm_data->rate = rate;
 
 	ret = get_etdm_reg(dai_id, &etdm_reg);
 	if (ret < 0)
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 5/7] ASoC: mediatek: mt8188: combine afe component registration
  2023-04-26  5:51 ` Trevor Wu
@ 2023-04-26  5:51   ` Trevor Wu
  -1 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree

There is no benefit to separate two components for AFE, so DAI driver
registration is moved to dev_snd_soc_register_component to merge these
two components.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
 sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 37 ++--------------------
 1 file changed, 2 insertions(+), 35 deletions(-)

diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
index e5f9373bed56..fecc891f892d 100644
--- a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
@@ -1898,10 +1898,6 @@ static const struct snd_kcontrol_new mt8188_memif_controls[] = {
 			    MT8188_AFE_MEMIF_UL10),
 };
 
-static const struct snd_soc_component_driver mt8188_afe_pcm_dai_component = {
-	.name = "mt8188-afe-pcm-dai",
-};
-
 static const struct mtk_base_memif_data memif_data[MT8188_AFE_MEMIF_NUM] = {
 	[MT8188_AFE_MEMIF_DL2] = {
 		.name = "DL2",
@@ -3142,9 +3138,8 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
 	struct mtk_base_afe *afe;
 	struct mt8188_afe_private *afe_priv;
 	struct device *dev;
-	int i, irq_id, ret;
-	struct snd_soc_component *component;
 	struct reset_control *rstc;
+	int i, irq_id, ret;
 
 	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33));
 	if (ret)
@@ -3280,34 +3275,12 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
 
 	/* register component */
 	ret = devm_snd_soc_register_component(dev, &mt8188_afe_component,
-					      NULL, 0);
+					      afe->dai_drivers, afe->num_dai_drivers);
 	if (ret) {
 		dev_warn(dev, "err_platform\n");
 		goto err_pm_put;
 	}
 
-	component = devm_kzalloc(&pdev->dev, sizeof(*component), GFP_KERNEL);
-	if (!component) {
-		ret = -ENOMEM;
-		goto err_pm_put;
-	}
-
-	ret = snd_soc_component_initialize(component,
-					   &mt8188_afe_pcm_dai_component,
-					   &pdev->dev);
-	if (ret)
-		goto err_pm_put;
-#ifdef CONFIG_DEBUG_FS
-	component->debugfs_prefix = "pcm";
-#endif
-	ret = snd_soc_add_component(component,
-				    afe->dai_drivers,
-				    afe->num_dai_drivers);
-	if (ret) {
-		dev_warn(dev, "err_add_component\n");
-		goto err_pm_put;
-	}
-
 	mt8188_afe_init_registers(afe);
 
 	pm_runtime_put_sync(&pdev->dev);
@@ -3323,11 +3296,6 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
 	return ret;
 }
 
-static void mt8188_afe_pcm_dev_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_component(&pdev->dev);
-}
-
 static const struct of_device_id mt8188_afe_pcm_dt_match[] = {
 	{ .compatible = "mediatek,mt8188-afe", },
 	{},
@@ -3346,7 +3314,6 @@ static struct platform_driver mt8188_afe_pcm_driver = {
 		   .pm = &mt8188_afe_pm_ops,
 	},
 	.probe = mt8188_afe_pcm_dev_probe,
-	.remove_new = mt8188_afe_pcm_dev_remove,
 };
 
 module_platform_driver(mt8188_afe_pcm_driver);
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 5/7] ASoC: mediatek: mt8188: combine afe component registration
@ 2023-04-26  5:51   ` Trevor Wu
  0 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree

There is no benefit to separate two components for AFE, so DAI driver
registration is moved to dev_snd_soc_register_component to merge these
two components.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
 sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 37 ++--------------------
 1 file changed, 2 insertions(+), 35 deletions(-)

diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
index e5f9373bed56..fecc891f892d 100644
--- a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
@@ -1898,10 +1898,6 @@ static const struct snd_kcontrol_new mt8188_memif_controls[] = {
 			    MT8188_AFE_MEMIF_UL10),
 };
 
-static const struct snd_soc_component_driver mt8188_afe_pcm_dai_component = {
-	.name = "mt8188-afe-pcm-dai",
-};
-
 static const struct mtk_base_memif_data memif_data[MT8188_AFE_MEMIF_NUM] = {
 	[MT8188_AFE_MEMIF_DL2] = {
 		.name = "DL2",
@@ -3142,9 +3138,8 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
 	struct mtk_base_afe *afe;
 	struct mt8188_afe_private *afe_priv;
 	struct device *dev;
-	int i, irq_id, ret;
-	struct snd_soc_component *component;
 	struct reset_control *rstc;
+	int i, irq_id, ret;
 
 	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33));
 	if (ret)
@@ -3280,34 +3275,12 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
 
 	/* register component */
 	ret = devm_snd_soc_register_component(dev, &mt8188_afe_component,
-					      NULL, 0);
+					      afe->dai_drivers, afe->num_dai_drivers);
 	if (ret) {
 		dev_warn(dev, "err_platform\n");
 		goto err_pm_put;
 	}
 
-	component = devm_kzalloc(&pdev->dev, sizeof(*component), GFP_KERNEL);
-	if (!component) {
-		ret = -ENOMEM;
-		goto err_pm_put;
-	}
-
-	ret = snd_soc_component_initialize(component,
-					   &mt8188_afe_pcm_dai_component,
-					   &pdev->dev);
-	if (ret)
-		goto err_pm_put;
-#ifdef CONFIG_DEBUG_FS
-	component->debugfs_prefix = "pcm";
-#endif
-	ret = snd_soc_add_component(component,
-				    afe->dai_drivers,
-				    afe->num_dai_drivers);
-	if (ret) {
-		dev_warn(dev, "err_add_component\n");
-		goto err_pm_put;
-	}
-
 	mt8188_afe_init_registers(afe);
 
 	pm_runtime_put_sync(&pdev->dev);
@@ -3323,11 +3296,6 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
 	return ret;
 }
 
-static void mt8188_afe_pcm_dev_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_component(&pdev->dev);
-}
-
 static const struct of_device_id mt8188_afe_pcm_dt_match[] = {
 	{ .compatible = "mediatek,mt8188-afe", },
 	{},
@@ -3346,7 +3314,6 @@ static struct platform_driver mt8188_afe_pcm_driver = {
 		   .pm = &mt8188_afe_pm_ops,
 	},
 	.probe = mt8188_afe_pcm_dev_probe,
-	.remove_new = mt8188_afe_pcm_dev_remove,
 };
 
 module_platform_driver(mt8188_afe_pcm_driver);
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 5/7] ASoC: mediatek: mt8188: combine afe component registration
  2023-04-26  5:51 ` Trevor Wu
                   ` (9 preceding siblings ...)
  (?)
@ 2023-04-26  5:51 ` Trevor Wu via Alsa-devel
  -1 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu via Alsa-devel @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree


[-- Attachment #0: Type: message/rfc822, Size: 7804 bytes --]

From: Trevor Wu <trevor.wu@mediatek.com>
To: <broonie@kernel.org>, <lgirdwood@gmail.com>, <tiwai@suse.com>, <perex@perex.cz>, <robh+dt@kernel.org>, <krzysztof.kozlowski+dt@linaro.org>, <matthias.bgg@gmail.com>, <angelogioacchino.delregno@collabora.com>
Cc: trevor.wu@mediatek.com, alsa-devel@alsa-project.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org
Subject: [PATCH v3 5/7] ASoC: mediatek: mt8188: combine afe component registration
Date: Wed, 26 Apr 2023 13:51:22 +0800
Message-ID: <20230426055124.16529-6-trevor.wu@mediatek.com>

There is no benefit to separate two components for AFE, so DAI driver
registration is moved to dev_snd_soc_register_component to merge these
two components.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
 sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 37 ++--------------------
 1 file changed, 2 insertions(+), 35 deletions(-)

diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
index e5f9373bed56..fecc891f892d 100644
--- a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
@@ -1898,10 +1898,6 @@ static const struct snd_kcontrol_new mt8188_memif_controls[] = {
 			    MT8188_AFE_MEMIF_UL10),
 };
 
-static const struct snd_soc_component_driver mt8188_afe_pcm_dai_component = {
-	.name = "mt8188-afe-pcm-dai",
-};
-
 static const struct mtk_base_memif_data memif_data[MT8188_AFE_MEMIF_NUM] = {
 	[MT8188_AFE_MEMIF_DL2] = {
 		.name = "DL2",
@@ -3142,9 +3138,8 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
 	struct mtk_base_afe *afe;
 	struct mt8188_afe_private *afe_priv;
 	struct device *dev;
-	int i, irq_id, ret;
-	struct snd_soc_component *component;
 	struct reset_control *rstc;
+	int i, irq_id, ret;
 
 	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33));
 	if (ret)
@@ -3280,34 +3275,12 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
 
 	/* register component */
 	ret = devm_snd_soc_register_component(dev, &mt8188_afe_component,
-					      NULL, 0);
+					      afe->dai_drivers, afe->num_dai_drivers);
 	if (ret) {
 		dev_warn(dev, "err_platform\n");
 		goto err_pm_put;
 	}
 
-	component = devm_kzalloc(&pdev->dev, sizeof(*component), GFP_KERNEL);
-	if (!component) {
-		ret = -ENOMEM;
-		goto err_pm_put;
-	}
-
-	ret = snd_soc_component_initialize(component,
-					   &mt8188_afe_pcm_dai_component,
-					   &pdev->dev);
-	if (ret)
-		goto err_pm_put;
-#ifdef CONFIG_DEBUG_FS
-	component->debugfs_prefix = "pcm";
-#endif
-	ret = snd_soc_add_component(component,
-				    afe->dai_drivers,
-				    afe->num_dai_drivers);
-	if (ret) {
-		dev_warn(dev, "err_add_component\n");
-		goto err_pm_put;
-	}
-
 	mt8188_afe_init_registers(afe);
 
 	pm_runtime_put_sync(&pdev->dev);
@@ -3323,11 +3296,6 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
 	return ret;
 }
 
-static void mt8188_afe_pcm_dev_remove(struct platform_device *pdev)
-{
-	snd_soc_unregister_component(&pdev->dev);
-}
-
 static const struct of_device_id mt8188_afe_pcm_dt_match[] = {
 	{ .compatible = "mediatek,mt8188-afe", },
 	{},
@@ -3346,7 +3314,6 @@ static struct platform_driver mt8188_afe_pcm_driver = {
 		   .pm = &mt8188_afe_pm_ops,
 	},
 	.probe = mt8188_afe_pcm_dev_probe,
-	.remove_new = mt8188_afe_pcm_dev_remove,
 };
 
 module_platform_driver(mt8188_afe_pcm_driver);
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 6/7] ASoC: mediatek: mt8188: add bus protection
  2023-04-26  5:51 ` Trevor Wu
@ 2023-04-26  5:51   ` Trevor Wu
  -1 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree

Add bus protection for reset controller.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
 sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 76 ++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
index fecc891f892d..c3fd32764da0 100644
--- a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
@@ -17,6 +17,7 @@
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/pm_runtime.h>
+#include <linux/soc/mediatek/infracfg.h>
 #include <linux/reset.h>
 #include <sound/pcm_params.h>
 #include "mt8188-afe-common.h"
@@ -3133,12 +3134,68 @@ static int mt8188_afe_parse_of(struct mtk_base_afe *afe,
 	return 0;
 }
 
+#define MT8188_DELAY_US 10
+#define MT8188_TIMEOUT_US USEC_PER_SEC
+
+static int bus_protect_enable(struct regmap *regmap)
+{
+	int ret;
+	u32 val;
+	u32 mask;
+
+	val = 0;
+	mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1;
+	regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_SET, mask);
+
+	ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+				       val, (val & mask) == mask,
+				       MT8188_DELAY_US, MT8188_TIMEOUT_US);
+	if (ret)
+		return ret;
+
+	val = 0;
+	mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2;
+	regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_SET, mask);
+
+	ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+				       val, (val & mask) == mask,
+				       MT8188_DELAY_US, MT8188_TIMEOUT_US);
+	return ret;
+}
+
+static int bus_protect_disable(struct regmap *regmap)
+{
+	int ret;
+	u32 val;
+	u32 mask;
+
+	val = 0;
+	mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2;
+	regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_CLR, mask);
+
+	ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+				       val, !(val & mask),
+				       MT8188_DELAY_US, MT8188_TIMEOUT_US);
+	if (ret)
+		return ret;
+
+	val = 0;
+	mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1;
+	regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_CLR, mask);
+
+	ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+				       val, !(val & mask),
+				       MT8188_DELAY_US, MT8188_TIMEOUT_US);
+	return ret;
+}
+
 static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
 {
 	struct mtk_base_afe *afe;
 	struct mt8188_afe_private *afe_priv;
 	struct device *dev;
 	struct reset_control *rstc;
+	struct regmap *infra_ao;
 	int i, irq_id, ret;
 
 	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33));
@@ -3163,18 +3220,37 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(afe->base_addr),
 				     "AFE base_addr not found\n");
 
+	infra_ao = syscon_regmap_lookup_by_phandle(dev->of_node,
+						   "mediatek,infracfg");
+	if (IS_ERR(infra_ao))
+		return dev_err_probe(dev, PTR_ERR(infra_ao),
+				     "%s() Cannot find infra_ao controller\n",
+				     __func__);
+
 	/* reset controller to reset audio regs before regmap cache */
 	rstc = devm_reset_control_get_exclusive(dev, "audiosys");
 	if (IS_ERR(rstc))
 		return dev_err_probe(dev, PTR_ERR(rstc),
 				     "could not get audiosys reset\n");
 
+	ret = bus_protect_enable(infra_ao);
+	if (ret) {
+		dev_err(dev, "bus_protect_enable failed\n");
+		return ret;
+	}
+
 	ret = reset_control_reset(rstc);
 	if (ret) {
 		dev_err(dev, "failed to trigger audio reset:%d\n", ret);
 		return ret;
 	}
 
+	ret = bus_protect_disable(infra_ao);
+	if (ret) {
+		dev_err(dev, "bus_protect_disable failed\n");
+		return ret;
+	}
+
 	/* initial audio related clock */
 	ret = mt8188_afe_init_clock(afe);
 	if (ret)
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 6/7] ASoC: mediatek: mt8188: add bus protection
@ 2023-04-26  5:51   ` Trevor Wu
  0 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree

Add bus protection for reset controller.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
 sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 76 ++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
index fecc891f892d..c3fd32764da0 100644
--- a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
@@ -17,6 +17,7 @@
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/pm_runtime.h>
+#include <linux/soc/mediatek/infracfg.h>
 #include <linux/reset.h>
 #include <sound/pcm_params.h>
 #include "mt8188-afe-common.h"
@@ -3133,12 +3134,68 @@ static int mt8188_afe_parse_of(struct mtk_base_afe *afe,
 	return 0;
 }
 
+#define MT8188_DELAY_US 10
+#define MT8188_TIMEOUT_US USEC_PER_SEC
+
+static int bus_protect_enable(struct regmap *regmap)
+{
+	int ret;
+	u32 val;
+	u32 mask;
+
+	val = 0;
+	mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1;
+	regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_SET, mask);
+
+	ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+				       val, (val & mask) == mask,
+				       MT8188_DELAY_US, MT8188_TIMEOUT_US);
+	if (ret)
+		return ret;
+
+	val = 0;
+	mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2;
+	regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_SET, mask);
+
+	ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+				       val, (val & mask) == mask,
+				       MT8188_DELAY_US, MT8188_TIMEOUT_US);
+	return ret;
+}
+
+static int bus_protect_disable(struct regmap *regmap)
+{
+	int ret;
+	u32 val;
+	u32 mask;
+
+	val = 0;
+	mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2;
+	regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_CLR, mask);
+
+	ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+				       val, !(val & mask),
+				       MT8188_DELAY_US, MT8188_TIMEOUT_US);
+	if (ret)
+		return ret;
+
+	val = 0;
+	mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1;
+	regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_CLR, mask);
+
+	ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+				       val, !(val & mask),
+				       MT8188_DELAY_US, MT8188_TIMEOUT_US);
+	return ret;
+}
+
 static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
 {
 	struct mtk_base_afe *afe;
 	struct mt8188_afe_private *afe_priv;
 	struct device *dev;
 	struct reset_control *rstc;
+	struct regmap *infra_ao;
 	int i, irq_id, ret;
 
 	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33));
@@ -3163,18 +3220,37 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(afe->base_addr),
 				     "AFE base_addr not found\n");
 
+	infra_ao = syscon_regmap_lookup_by_phandle(dev->of_node,
+						   "mediatek,infracfg");
+	if (IS_ERR(infra_ao))
+		return dev_err_probe(dev, PTR_ERR(infra_ao),
+				     "%s() Cannot find infra_ao controller\n",
+				     __func__);
+
 	/* reset controller to reset audio regs before regmap cache */
 	rstc = devm_reset_control_get_exclusive(dev, "audiosys");
 	if (IS_ERR(rstc))
 		return dev_err_probe(dev, PTR_ERR(rstc),
 				     "could not get audiosys reset\n");
 
+	ret = bus_protect_enable(infra_ao);
+	if (ret) {
+		dev_err(dev, "bus_protect_enable failed\n");
+		return ret;
+	}
+
 	ret = reset_control_reset(rstc);
 	if (ret) {
 		dev_err(dev, "failed to trigger audio reset:%d\n", ret);
 		return ret;
 	}
 
+	ret = bus_protect_disable(infra_ao);
+	if (ret) {
+		dev_err(dev, "bus_protect_disable failed\n");
+		return ret;
+	}
+
 	/* initial audio related clock */
 	ret = mt8188_afe_init_clock(afe);
 	if (ret)
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 6/7] ASoC: mediatek: mt8188: add bus protection
  2023-04-26  5:51 ` Trevor Wu
                   ` (10 preceding siblings ...)
  (?)
@ 2023-04-26  5:51 ` Trevor Wu via Alsa-devel
  -1 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu via Alsa-devel @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree


[-- Attachment #0: Type: message/rfc822, Size: 8585 bytes --]

From: Trevor Wu <trevor.wu@mediatek.com>
To: <broonie@kernel.org>, <lgirdwood@gmail.com>, <tiwai@suse.com>, <perex@perex.cz>, <robh+dt@kernel.org>, <krzysztof.kozlowski+dt@linaro.org>, <matthias.bgg@gmail.com>, <angelogioacchino.delregno@collabora.com>
Cc: trevor.wu@mediatek.com, alsa-devel@alsa-project.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org
Subject: [PATCH v3 6/7] ASoC: mediatek: mt8188: add bus protection
Date: Wed, 26 Apr 2023 13:51:23 +0800
Message-ID: <20230426055124.16529-7-trevor.wu@mediatek.com>

Add bus protection for reset controller.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
 sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 76 ++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
index fecc891f892d..c3fd32764da0 100644
--- a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
@@ -17,6 +17,7 @@
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/pm_runtime.h>
+#include <linux/soc/mediatek/infracfg.h>
 #include <linux/reset.h>
 #include <sound/pcm_params.h>
 #include "mt8188-afe-common.h"
@@ -3133,12 +3134,68 @@ static int mt8188_afe_parse_of(struct mtk_base_afe *afe,
 	return 0;
 }
 
+#define MT8188_DELAY_US 10
+#define MT8188_TIMEOUT_US USEC_PER_SEC
+
+static int bus_protect_enable(struct regmap *regmap)
+{
+	int ret;
+	u32 val;
+	u32 mask;
+
+	val = 0;
+	mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1;
+	regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_SET, mask);
+
+	ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+				       val, (val & mask) == mask,
+				       MT8188_DELAY_US, MT8188_TIMEOUT_US);
+	if (ret)
+		return ret;
+
+	val = 0;
+	mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2;
+	regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_SET, mask);
+
+	ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+				       val, (val & mask) == mask,
+				       MT8188_DELAY_US, MT8188_TIMEOUT_US);
+	return ret;
+}
+
+static int bus_protect_disable(struct regmap *regmap)
+{
+	int ret;
+	u32 val;
+	u32 mask;
+
+	val = 0;
+	mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2;
+	regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_CLR, mask);
+
+	ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+				       val, !(val & mask),
+				       MT8188_DELAY_US, MT8188_TIMEOUT_US);
+	if (ret)
+		return ret;
+
+	val = 0;
+	mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1;
+	regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_CLR, mask);
+
+	ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+				       val, !(val & mask),
+				       MT8188_DELAY_US, MT8188_TIMEOUT_US);
+	return ret;
+}
+
 static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
 {
 	struct mtk_base_afe *afe;
 	struct mt8188_afe_private *afe_priv;
 	struct device *dev;
 	struct reset_control *rstc;
+	struct regmap *infra_ao;
 	int i, irq_id, ret;
 
 	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33));
@@ -3163,18 +3220,37 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(afe->base_addr),
 				     "AFE base_addr not found\n");
 
+	infra_ao = syscon_regmap_lookup_by_phandle(dev->of_node,
+						   "mediatek,infracfg");
+	if (IS_ERR(infra_ao))
+		return dev_err_probe(dev, PTR_ERR(infra_ao),
+				     "%s() Cannot find infra_ao controller\n",
+				     __func__);
+
 	/* reset controller to reset audio regs before regmap cache */
 	rstc = devm_reset_control_get_exclusive(dev, "audiosys");
 	if (IS_ERR(rstc))
 		return dev_err_probe(dev, PTR_ERR(rstc),
 				     "could not get audiosys reset\n");
 
+	ret = bus_protect_enable(infra_ao);
+	if (ret) {
+		dev_err(dev, "bus_protect_enable failed\n");
+		return ret;
+	}
+
 	ret = reset_control_reset(rstc);
 	if (ret) {
 		dev_err(dev, "failed to trigger audio reset:%d\n", ret);
 		return ret;
 	}
 
+	ret = bus_protect_disable(infra_ao);
+	if (ret) {
+		dev_err(dev, "bus_protect_disable failed\n");
+		return ret;
+	}
+
 	/* initial audio related clock */
 	ret = mt8188_afe_init_clock(afe);
 	if (ret)
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 7/7] ASoC: dt-bindings: mediatek,mt8188-afe: add audio properties
  2023-04-26  5:51 ` Trevor Wu
@ 2023-04-26  5:51   ` Trevor Wu
  -1 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree

Add apll1_d4 to clocks for switching the parent of top_a1sys_hp
dynamically. On the other hand, "mediatek,infracfg" is included for bus
protection.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
 .../bindings/sound/mediatek,mt8188-afe.yaml          | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
index 82ccb32f08f2..eb58de8c0e68 100644
--- a/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
+++ b/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
@@ -29,6 +29,10 @@ properties:
     $ref: /schemas/types.yaml#/definitions/phandle
     description: The phandle of the mediatek topckgen controller
 
+  mediatek,infracfg:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: The phandle of the mediatek infracfg controller
+
   power-domains:
     maxItems: 1
 
@@ -52,6 +56,7 @@ properties:
       - description: mux for i2si1_mck
       - description: mux for i2si2_mck
       - description: audio 26m clock
+      - description: audio pll1 divide 4
 
   clock-names:
     items:
@@ -73,6 +78,7 @@ properties:
       - const: i2si1_m_sel
       - const: i2si2_m_sel
       - const: adsp_audio_26m
+      - const: apll1_d4
 
   mediatek,etdm-in1-cowork-source:
     $ref: /schemas/types.yaml#/definitions/uint32
@@ -184,7 +190,8 @@ examples:
                  <&topckgen 78>, //CLK_TOP_I2SO2
                  <&topckgen 79>, //CLK_TOP_I2SI1
                  <&topckgen 80>, //CLK_TOP_I2SI2
-                 <&adsp_audio26m 0>; //CLK_AUDIODSP_AUDIO26M
+                 <&adsp_audio26m 0>, //CLK_AUDIODSP_AUDIO26M
+                 <&topckgen 136>; //CLK_TOP_APLL1_D4
         clock-names = "clk26m",
                       "apll1",
                       "apll2",
@@ -202,7 +209,8 @@ examples:
                       "i2so2_m_sel",
                       "i2si1_m_sel",
                       "i2si2_m_sel",
-                      "adsp_audio_26m";
+                      "adsp_audio_26m",
+                      "apll1_d4";
     };
 
 ...
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 7/7] ASoC: dt-bindings: mediatek,mt8188-afe: add audio properties
@ 2023-04-26  5:51   ` Trevor Wu
  0 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree

Add apll1_d4 to clocks for switching the parent of top_a1sys_hp
dynamically. On the other hand, "mediatek,infracfg" is included for bus
protection.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
 .../bindings/sound/mediatek,mt8188-afe.yaml          | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
index 82ccb32f08f2..eb58de8c0e68 100644
--- a/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
+++ b/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
@@ -29,6 +29,10 @@ properties:
     $ref: /schemas/types.yaml#/definitions/phandle
     description: The phandle of the mediatek topckgen controller
 
+  mediatek,infracfg:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: The phandle of the mediatek infracfg controller
+
   power-domains:
     maxItems: 1
 
@@ -52,6 +56,7 @@ properties:
       - description: mux for i2si1_mck
       - description: mux for i2si2_mck
       - description: audio 26m clock
+      - description: audio pll1 divide 4
 
   clock-names:
     items:
@@ -73,6 +78,7 @@ properties:
       - const: i2si1_m_sel
       - const: i2si2_m_sel
       - const: adsp_audio_26m
+      - const: apll1_d4
 
   mediatek,etdm-in1-cowork-source:
     $ref: /schemas/types.yaml#/definitions/uint32
@@ -184,7 +190,8 @@ examples:
                  <&topckgen 78>, //CLK_TOP_I2SO2
                  <&topckgen 79>, //CLK_TOP_I2SI1
                  <&topckgen 80>, //CLK_TOP_I2SI2
-                 <&adsp_audio26m 0>; //CLK_AUDIODSP_AUDIO26M
+                 <&adsp_audio26m 0>, //CLK_AUDIODSP_AUDIO26M
+                 <&topckgen 136>; //CLK_TOP_APLL1_D4
         clock-names = "clk26m",
                       "apll1",
                       "apll2",
@@ -202,7 +209,8 @@ examples:
                       "i2so2_m_sel",
                       "i2si1_m_sel",
                       "i2si2_m_sel",
-                      "adsp_audio_26m";
+                      "adsp_audio_26m",
+                      "apll1_d4";
     };
 
 ...
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH v3 7/7] ASoC: dt-bindings: mediatek,mt8188-afe: add audio properties
  2023-04-26  5:51 ` Trevor Wu
                   ` (12 preceding siblings ...)
  (?)
@ 2023-04-26  5:51 ` Trevor Wu via Alsa-devel
  -1 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu via Alsa-devel @ 2023-04-26  5:51 UTC (permalink / raw)
  To: broonie, lgirdwood, tiwai, perex, robh+dt,
	krzysztof.kozlowski+dt, matthias.bgg, angelogioacchino.delregno
  Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
	linux-kernel, devicetree


[-- Attachment #0: Type: message/rfc822, Size: 6923 bytes --]

From: Trevor Wu <trevor.wu@mediatek.com>
To: <broonie@kernel.org>, <lgirdwood@gmail.com>, <tiwai@suse.com>, <perex@perex.cz>, <robh+dt@kernel.org>, <krzysztof.kozlowski+dt@linaro.org>, <matthias.bgg@gmail.com>, <angelogioacchino.delregno@collabora.com>
Cc: trevor.wu@mediatek.com, alsa-devel@alsa-project.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org
Subject: [PATCH v3 7/7] ASoC: dt-bindings: mediatek,mt8188-afe: add audio properties
Date: Wed, 26 Apr 2023 13:51:24 +0800
Message-ID: <20230426055124.16529-8-trevor.wu@mediatek.com>

Add apll1_d4 to clocks for switching the parent of top_a1sys_hp
dynamically. On the other hand, "mediatek,infracfg" is included for bus
protection.

Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
 .../bindings/sound/mediatek,mt8188-afe.yaml          | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
index 82ccb32f08f2..eb58de8c0e68 100644
--- a/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
+++ b/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
@@ -29,6 +29,10 @@ properties:
     $ref: /schemas/types.yaml#/definitions/phandle
     description: The phandle of the mediatek topckgen controller
 
+  mediatek,infracfg:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: The phandle of the mediatek infracfg controller
+
   power-domains:
     maxItems: 1
 
@@ -52,6 +56,7 @@ properties:
       - description: mux for i2si1_mck
       - description: mux for i2si2_mck
       - description: audio 26m clock
+      - description: audio pll1 divide 4
 
   clock-names:
     items:
@@ -73,6 +78,7 @@ properties:
       - const: i2si1_m_sel
       - const: i2si2_m_sel
       - const: adsp_audio_26m
+      - const: apll1_d4
 
   mediatek,etdm-in1-cowork-source:
     $ref: /schemas/types.yaml#/definitions/uint32
@@ -184,7 +190,8 @@ examples:
                  <&topckgen 78>, //CLK_TOP_I2SO2
                  <&topckgen 79>, //CLK_TOP_I2SI1
                  <&topckgen 80>, //CLK_TOP_I2SI2
-                 <&adsp_audio26m 0>; //CLK_AUDIODSP_AUDIO26M
+                 <&adsp_audio26m 0>, //CLK_AUDIODSP_AUDIO26M
+                 <&topckgen 136>; //CLK_TOP_APLL1_D4
         clock-names = "clk26m",
                       "apll1",
                       "apll2",
@@ -202,7 +209,8 @@ examples:
                       "i2so2_m_sel",
                       "i2si1_m_sel",
                       "i2si2_m_sel",
-                      "adsp_audio_26m";
+                      "adsp_audio_26m",
+                      "apll1_d4";
     };
 
 ...
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH v3 7/7] ASoC: dt-bindings: mediatek,mt8188-afe: add audio properties
  2023-04-26  5:51   ` Trevor Wu
  (?)
@ 2023-04-27 14:48     ` Rob Herring
  -1 siblings, 0 replies; 29+ messages in thread
From: Rob Herring @ 2023-04-27 14:48 UTC (permalink / raw)
  To: Trevor Wu
  Cc: broonie, lgirdwood, tiwai, perex, krzysztof.kozlowski+dt,
	matthias.bgg, angelogioacchino.delregno, alsa-devel,
	linux-mediatek, linux-arm-kernel, linux-kernel, devicetree

On Wed, Apr 26, 2023 at 01:51:24PM +0800, Trevor Wu wrote:
> Add apll1_d4 to clocks for switching the parent of top_a1sys_hp
> dynamically. On the other hand, "mediatek,infracfg" is included for bus
> protection.

Bus protection? Meaning access controls for the device? If so, there's a 
proposed binding[1] for just that. If that's something Mediatek needs 
too, please participate in that discussion. It's easier to define new 
common bindings if there is more than one user.

> 
> Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
> ---
>  .../bindings/sound/mediatek,mt8188-afe.yaml          | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
> index 82ccb32f08f2..eb58de8c0e68 100644
> --- a/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
> +++ b/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
> @@ -29,6 +29,10 @@ properties:
>      $ref: /schemas/types.yaml#/definitions/phandle
>      description: The phandle of the mediatek topckgen controller
>  
> +  mediatek,infracfg:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: The phandle of the mediatek infracfg controller
> +
>    power-domains:
>      maxItems: 1
>  
> @@ -52,6 +56,7 @@ properties:
>        - description: mux for i2si1_mck
>        - description: mux for i2si2_mck
>        - description: audio 26m clock
> +      - description: audio pll1 divide 4
>  
>    clock-names:
>      items:
> @@ -73,6 +78,7 @@ properties:
>        - const: i2si1_m_sel
>        - const: i2si2_m_sel
>        - const: adsp_audio_26m
> +      - const: apll1_d4

A new required entry may break the ABI. If that's okay, it needs to be 
explained in the commit msg.

Rob

[1] https://lore.kernel.org/lkml/cover.1668070216.git.oleksii_moisieiev@epam.com/

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v3 7/7] ASoC: dt-bindings: mediatek,mt8188-afe: add audio properties
@ 2023-04-27 14:48     ` Rob Herring
  0 siblings, 0 replies; 29+ messages in thread
From: Rob Herring @ 2023-04-27 14:48 UTC (permalink / raw)
  To: Trevor Wu
  Cc: broonie, lgirdwood, tiwai, perex, krzysztof.kozlowski+dt,
	matthias.bgg, angelogioacchino.delregno, alsa-devel,
	linux-mediatek, linux-arm-kernel, linux-kernel, devicetree

On Wed, Apr 26, 2023 at 01:51:24PM +0800, Trevor Wu wrote:
> Add apll1_d4 to clocks for switching the parent of top_a1sys_hp
> dynamically. On the other hand, "mediatek,infracfg" is included for bus
> protection.

Bus protection? Meaning access controls for the device? If so, there's a 
proposed binding[1] for just that. If that's something Mediatek needs 
too, please participate in that discussion. It's easier to define new 
common bindings if there is more than one user.

> 
> Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
> ---
>  .../bindings/sound/mediatek,mt8188-afe.yaml          | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
> index 82ccb32f08f2..eb58de8c0e68 100644
> --- a/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
> +++ b/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
> @@ -29,6 +29,10 @@ properties:
>      $ref: /schemas/types.yaml#/definitions/phandle
>      description: The phandle of the mediatek topckgen controller
>  
> +  mediatek,infracfg:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: The phandle of the mediatek infracfg controller
> +
>    power-domains:
>      maxItems: 1
>  
> @@ -52,6 +56,7 @@ properties:
>        - description: mux for i2si1_mck
>        - description: mux for i2si2_mck
>        - description: audio 26m clock
> +      - description: audio pll1 divide 4
>  
>    clock-names:
>      items:
> @@ -73,6 +78,7 @@ properties:
>        - const: i2si1_m_sel
>        - const: i2si2_m_sel
>        - const: adsp_audio_26m
> +      - const: apll1_d4

A new required entry may break the ABI. If that's okay, it needs to be 
explained in the commit msg.

Rob

[1] https://lore.kernel.org/lkml/cover.1668070216.git.oleksii_moisieiev@epam.com/

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v3 7/7] ASoC: dt-bindings: mediatek,mt8188-afe: add audio properties
@ 2023-04-27 14:48     ` Rob Herring
  0 siblings, 0 replies; 29+ messages in thread
From: Rob Herring @ 2023-04-27 14:48 UTC (permalink / raw)
  To: Trevor Wu
  Cc: broonie, lgirdwood, tiwai, krzysztof.kozlowski+dt, matthias.bgg,
	angelogioacchino.delregno, alsa-devel, linux-mediatek,
	linux-arm-kernel, linux-kernel, devicetree

On Wed, Apr 26, 2023 at 01:51:24PM +0800, Trevor Wu wrote:
> Add apll1_d4 to clocks for switching the parent of top_a1sys_hp
> dynamically. On the other hand, "mediatek,infracfg" is included for bus
> protection.

Bus protection? Meaning access controls for the device? If so, there's a 
proposed binding[1] for just that. If that's something Mediatek needs 
too, please participate in that discussion. It's easier to define new 
common bindings if there is more than one user.

> 
> Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
> ---
>  .../bindings/sound/mediatek,mt8188-afe.yaml          | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
> index 82ccb32f08f2..eb58de8c0e68 100644
> --- a/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
> +++ b/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
> @@ -29,6 +29,10 @@ properties:
>      $ref: /schemas/types.yaml#/definitions/phandle
>      description: The phandle of the mediatek topckgen controller
>  
> +  mediatek,infracfg:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: The phandle of the mediatek infracfg controller
> +
>    power-domains:
>      maxItems: 1
>  
> @@ -52,6 +56,7 @@ properties:
>        - description: mux for i2si1_mck
>        - description: mux for i2si2_mck
>        - description: audio 26m clock
> +      - description: audio pll1 divide 4
>  
>    clock-names:
>      items:
> @@ -73,6 +78,7 @@ properties:
>        - const: i2si1_m_sel
>        - const: i2si2_m_sel
>        - const: adsp_audio_26m
> +      - const: apll1_d4

A new required entry may break the ABI. If that's okay, it needs to be 
explained in the commit msg.

Rob

[1] https://lore.kernel.org/lkml/cover.1668070216.git.oleksii_moisieiev@epam.com/

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v3 7/7] ASoC: dt-bindings: mediatek,mt8188-afe: add audio properties
  2023-04-27 14:48     ` Rob Herring
@ 2023-05-05  7:31       ` Trevor Wu (吳文良)
  -1 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu (吳文良) @ 2023-05-05  7:31 UTC (permalink / raw)
  To: robh
  Cc: linux-mediatek, linux-kernel, devicetree, broonie, tiwai,
	lgirdwood, linux-arm-kernel, krzysztof.kozlowski+dt,
	matthias.bgg, perex, alsa-devel, angelogioacchino.delregno

On Thu, 2023-04-27 at 09:48 -0500, Rob Herring wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> 
> 
> On Wed, Apr 26, 2023 at 01:51:24PM +0800, Trevor Wu wrote:
> > Add apll1_d4 to clocks for switching the parent of top_a1sys_hp
> > dynamically. On the other hand, "mediatek,infracfg" is included for
> > bus
> > protection.
> 
> Bus protection? Meaning access controls for the device? If so,
> there's a
> proposed binding[1] for just that. If that's something Mediatek needs
> too, please participate in that discussion. It's easier to define new
> common bindings if there is more than one user.
> 

Hi Rob,

Bus protection is a function used to prevent from the unexpected glitch
during the reset. The suggested reset control flow is listed as below.

bus protection on
module reset
bus protection off

I think it is not the same as access control of the device. In
addition, no framework or controller was implemented for MTK bus
protection. Here, I just make use of the property to get the phandle of
infracfg to access the register for bus protection.

> > 
> > Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
> > ---
> >  .../bindings/sound/mediatek,mt8188-afe.yaml          | 12
> > ++++++++++--
> >  1 file changed, 10 insertions(+), 2 deletions(-)
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
> > b/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
> > index 82ccb32f08f2..eb58de8c0e68 100644
> > --- a/Documentation/devicetree/bindings/sound/mediatek,mt8188-
> > afe.yaml
> > +++ b/Documentation/devicetree/bindings/sound/mediatek,mt8188-
> > afe.yaml
> > @@ -29,6 +29,10 @@ properties:
> >      $ref: /schemas/types.yaml#/definitions/phandle
> >      description: The phandle of the mediatek topckgen controller
> > 
> > +  mediatek,infracfg:
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> > +    description: The phandle of the mediatek infracfg controller
> > +
> >    power-domains:
> >      maxItems: 1
> > 
> > @@ -52,6 +56,7 @@ properties:
> >        - description: mux for i2si1_mck
> >        - description: mux for i2si2_mck
> >        - description: audio 26m clock
> > +      - description: audio pll1 divide 4
> > 
> >    clock-names:
> >      items:
> > @@ -73,6 +78,7 @@ properties:
> >        - const: i2si1_m_sel
> >        - const: i2si2_m_sel
> >        - const: adsp_audio_26m
> > +      - const: apll1_d4
> 
> A new required entry may break the ABI. If that's okay, it needs to
> be
> explained in the commit msg.
> 

It should be OK, because the project is still developing and there is
no device tree file for mt8188 upstream. I will add the reason to the
message in v4.

Sorry, I didn't notice that before. I will review my future work and
check if any required property or item should be included to the
binding before mt8188 audio device tree upstream.

Thanks,
Trevor

> Rob
> 
> [1] 
> https://lore.kernel.org/lkml/cover.1668070216.git.oleksii_moisieiev@epam.com/

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v3 7/7] ASoC: dt-bindings: mediatek,mt8188-afe: add audio properties
  2023-04-27 14:48     ` Rob Herring
                       ` (2 preceding siblings ...)
  (?)
@ 2023-05-05  7:31     ` Trevor Wu (吳文良) via Alsa-devel
  -1 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu (吳文良) via Alsa-devel @ 2023-05-05  7:31 UTC (permalink / raw)
  To: robh
  Cc: linux-mediatek, linux-kernel, devicetree, broonie, tiwai,
	lgirdwood, linux-arm-kernel, krzysztof.kozlowski+dt,
	matthias.bgg, alsa-devel, angelogioacchino.delregno


[-- Attachment #0: Type: message/rfc822, Size: 17607 bytes --]

From: "Trevor Wu (吳文良)" <Trevor.Wu@mediatek.com>
To: "robh@kernel.org" <robh@kernel.org>
Cc: "linux-mediatek@lists.infradead.org" <linux-mediatek@lists.infradead.org>, "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>, "devicetree@vger.kernel.org" <devicetree@vger.kernel.org>, "broonie@kernel.org" <broonie@kernel.org>, "tiwai@suse.com" <tiwai@suse.com>, "lgirdwood@gmail.com" <lgirdwood@gmail.com>, "linux-arm-kernel@lists.infradead.org" <linux-arm-kernel@lists.infradead.org>, "krzysztof.kozlowski+dt@linaro.org" <krzysztof.kozlowski+dt@linaro.org>, "matthias.bgg@gmail.com" <matthias.bgg@gmail.com>, "alsa-devel@alsa-project.org" <alsa-devel@alsa-project.org>, "angelogioacchino.delregno@collabora.com" <angelogioacchino.delregno@collabora.com>
Subject: Re: [PATCH v3 7/7] ASoC: dt-bindings: mediatek,mt8188-afe: add audio properties
Date: Fri, 5 May 2023 07:31:44 +0000
Message-ID: <5433e5c1e046c756bd7e423edfad57813e8fdfb9.camel@mediatek.com>

On Thu, 2023-04-27 at 09:48 -0500, Rob Herring wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> 
> 
> On Wed, Apr 26, 2023 at 01:51:24PM +0800, Trevor Wu wrote:
> > Add apll1_d4 to clocks for switching the parent of top_a1sys_hp
> > dynamically. On the other hand, "mediatek,infracfg" is included for
> > bus
> > protection.
> 
> Bus protection? Meaning access controls for the device? If so,
> there's a
> proposed binding[1] for just that. If that's something Mediatek needs
> too, please participate in that discussion. It's easier to define new
> common bindings if there is more than one user.
> 

Hi Rob,

Bus protection is a function used to prevent from the unexpected glitch
during the reset. The suggested reset control flow is listed as below.

bus protection on
module reset
bus protection off

I think it is not the same as access control of the device. In
addition, no framework or controller was implemented for MTK bus
protection. Here, I just make use of the property to get the phandle of
infracfg to access the register for bus protection.

> > 
> > Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
> > ---
> >  .../bindings/sound/mediatek,mt8188-afe.yaml          | 12
> > ++++++++++--
> >  1 file changed, 10 insertions(+), 2 deletions(-)
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
> > b/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
> > index 82ccb32f08f2..eb58de8c0e68 100644
> > --- a/Documentation/devicetree/bindings/sound/mediatek,mt8188-
> > afe.yaml
> > +++ b/Documentation/devicetree/bindings/sound/mediatek,mt8188-
> > afe.yaml
> > @@ -29,6 +29,10 @@ properties:
> >      $ref: /schemas/types.yaml#/definitions/phandle
> >      description: The phandle of the mediatek topckgen controller
> > 
> > +  mediatek,infracfg:
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> > +    description: The phandle of the mediatek infracfg controller
> > +
> >    power-domains:
> >      maxItems: 1
> > 
> > @@ -52,6 +56,7 @@ properties:
> >        - description: mux for i2si1_mck
> >        - description: mux for i2si2_mck
> >        - description: audio 26m clock
> > +      - description: audio pll1 divide 4
> > 
> >    clock-names:
> >      items:
> > @@ -73,6 +78,7 @@ properties:
> >        - const: i2si1_m_sel
> >        - const: i2si2_m_sel
> >        - const: adsp_audio_26m
> > +      - const: apll1_d4
> 
> A new required entry may break the ABI. If that's okay, it needs to
> be
> explained in the commit msg.
> 

It should be OK, because the project is still developing and there is
no device tree file for mt8188 upstream. I will add the reason to the
message in v4.

Sorry, I didn't notice that before. I will review my future work and
check if any required property or item should be included to the
binding before mt8188 audio device tree upstream.

Thanks,
Trevor

> Rob
> 
> [1] 
> https://lore.kernel.org/lkml/cover.1668070216.git.oleksii_moisieiev@epam.com/

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v3 7/7] ASoC: dt-bindings: mediatek,mt8188-afe: add audio properties
@ 2023-05-05  7:31       ` Trevor Wu (吳文良)
  0 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu (吳文良) @ 2023-05-05  7:31 UTC (permalink / raw)
  To: robh
  Cc: linux-mediatek, linux-kernel, devicetree, broonie, tiwai,
	lgirdwood, linux-arm-kernel, krzysztof.kozlowski+dt,
	matthias.bgg, perex, alsa-devel, angelogioacchino.delregno

On Thu, 2023-04-27 at 09:48 -0500, Rob Herring wrote:
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> 
> 
> On Wed, Apr 26, 2023 at 01:51:24PM +0800, Trevor Wu wrote:
> > Add apll1_d4 to clocks for switching the parent of top_a1sys_hp
> > dynamically. On the other hand, "mediatek,infracfg" is included for
> > bus
> > protection.
> 
> Bus protection? Meaning access controls for the device? If so,
> there's a
> proposed binding[1] for just that. If that's something Mediatek needs
> too, please participate in that discussion. It's easier to define new
> common bindings if there is more than one user.
> 

Hi Rob,

Bus protection is a function used to prevent from the unexpected glitch
during the reset. The suggested reset control flow is listed as below.

bus protection on
module reset
bus protection off

I think it is not the same as access control of the device. In
addition, no framework or controller was implemented for MTK bus
protection. Here, I just make use of the property to get the phandle of
infracfg to access the register for bus protection.

> > 
> > Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
> > ---
> >  .../bindings/sound/mediatek,mt8188-afe.yaml          | 12
> > ++++++++++--
> >  1 file changed, 10 insertions(+), 2 deletions(-)
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
> > b/Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
> > index 82ccb32f08f2..eb58de8c0e68 100644
> > --- a/Documentation/devicetree/bindings/sound/mediatek,mt8188-
> > afe.yaml
> > +++ b/Documentation/devicetree/bindings/sound/mediatek,mt8188-
> > afe.yaml
> > @@ -29,6 +29,10 @@ properties:
> >      $ref: /schemas/types.yaml#/definitions/phandle
> >      description: The phandle of the mediatek topckgen controller
> > 
> > +  mediatek,infracfg:
> > +    $ref: /schemas/types.yaml#/definitions/phandle
> > +    description: The phandle of the mediatek infracfg controller
> > +
> >    power-domains:
> >      maxItems: 1
> > 
> > @@ -52,6 +56,7 @@ properties:
> >        - description: mux for i2si1_mck
> >        - description: mux for i2si2_mck
> >        - description: audio 26m clock
> > +      - description: audio pll1 divide 4
> > 
> >    clock-names:
> >      items:
> > @@ -73,6 +78,7 @@ properties:
> >        - const: i2si1_m_sel
> >        - const: i2si2_m_sel
> >        - const: adsp_audio_26m
> > +      - const: apll1_d4
> 
> A new required entry may break the ABI. If that's okay, it needs to
> be
> explained in the commit msg.
> 

It should be OK, because the project is still developing and there is
no device tree file for mt8188 upstream. I will add the reason to the
message in v4.

Sorry, I didn't notice that before. I will review my future work and
check if any required property or item should be included to the
binding before mt8188 audio device tree upstream.

Thanks,
Trevor

> Rob
> 
> [1] 
> https://lore.kernel.org/lkml/cover.1668070216.git.oleksii_moisieiev@epam.com/
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2023-05-05  7:33 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-26  5:51 [PATCH v3 0/7] ASoC: mediatek: mt8188: revise AFE driver Trevor Wu
2023-04-26  5:51 ` Trevor Wu
2023-04-26  5:51 ` [PATCH v3 1/7] ASoC: mediatek: mt8188: remove supply AUDIO_HIRES Trevor Wu
2023-04-26  5:51   ` Trevor Wu
2023-04-26  5:51 ` Trevor Wu via Alsa-devel
2023-04-26  5:51 ` [PATCH v3 2/7] ASoC: mediatek: mt8188: complete set_tdm_slot function Trevor Wu
2023-04-26  5:51   ` Trevor Wu
2023-04-26  5:51 ` Trevor Wu via Alsa-devel
2023-04-26  5:51 ` [PATCH v3 3/7] ASoC: mediatek: mt8188: revise ETDM control flow Trevor Wu via Alsa-devel
2023-04-26  5:51 ` Trevor Wu
2023-04-26  5:51   ` Trevor Wu
2023-04-26  5:51 ` [PATCH v3 4/7] ASoC: mediatek: mt8188: refine APLL control Trevor Wu via Alsa-devel
2023-04-26  5:51 ` Trevor Wu
2023-04-26  5:51   ` Trevor Wu
2023-04-26  5:51 ` [PATCH v3 5/7] ASoC: mediatek: mt8188: combine afe component registration Trevor Wu
2023-04-26  5:51   ` Trevor Wu
2023-04-26  5:51 ` Trevor Wu via Alsa-devel
2023-04-26  5:51 ` [PATCH v3 6/7] ASoC: mediatek: mt8188: add bus protection Trevor Wu via Alsa-devel
2023-04-26  5:51 ` Trevor Wu
2023-04-26  5:51   ` Trevor Wu
2023-04-26  5:51 ` [PATCH v3 7/7] ASoC: dt-bindings: mediatek,mt8188-afe: add audio properties Trevor Wu via Alsa-devel
2023-04-26  5:51 ` Trevor Wu
2023-04-26  5:51   ` Trevor Wu
2023-04-27 14:48   ` Rob Herring
2023-04-27 14:48     ` Rob Herring
2023-04-27 14:48     ` Rob Herring
2023-05-05  7:31     ` Trevor Wu (吳文良)
2023-05-05  7:31       ` Trevor Wu (吳文良)
2023-05-05  7:31     ` Trevor Wu (吳文良) via Alsa-devel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.