xref: /linux/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c (revision d6f3710a56e10b42945ed2dbcca71d2748174299)
1*d6f3710aSGarlic Tseng /*
2*d6f3710aSGarlic Tseng  * mt2701-afe-clock-ctrl.c  --  Mediatek 2701 afe clock ctrl
3*d6f3710aSGarlic Tseng  *
4*d6f3710aSGarlic Tseng  * Copyright (c) 2016 MediaTek Inc.
5*d6f3710aSGarlic Tseng  * Author: Garlic Tseng <garlic.tseng@mediatek.com>
6*d6f3710aSGarlic Tseng  *
7*d6f3710aSGarlic Tseng  * This program is free software; you can redistribute it and/or modify
8*d6f3710aSGarlic Tseng  * it under the terms of the GNU General Public License version 2 and
9*d6f3710aSGarlic Tseng  * only version 2 as published by the Free Software Foundation.
10*d6f3710aSGarlic Tseng  *
11*d6f3710aSGarlic Tseng  * This program is distributed in the hope that it will be useful,
12*d6f3710aSGarlic Tseng  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*d6f3710aSGarlic Tseng  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*d6f3710aSGarlic Tseng  * GNU General Public License for more details.
15*d6f3710aSGarlic Tseng  */
16*d6f3710aSGarlic Tseng 
17*d6f3710aSGarlic Tseng #include <sound/soc.h>
18*d6f3710aSGarlic Tseng #include <linux/regmap.h>
19*d6f3710aSGarlic Tseng #include <linux/pm_runtime.h>
20*d6f3710aSGarlic Tseng 
21*d6f3710aSGarlic Tseng #include "mt2701-afe-common.h"
22*d6f3710aSGarlic Tseng #include "mt2701-afe-clock-ctrl.h"
23*d6f3710aSGarlic Tseng 
24*d6f3710aSGarlic Tseng static const char *aud_clks[MT2701_CLOCK_NUM] = {
25*d6f3710aSGarlic Tseng 	[MT2701_AUD_INFRA_SYS_AUDIO] = "infra_sys_audio_clk",
26*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_MUX1_SEL] = "top_audio_mux1_sel",
27*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_MUX2_SEL] = "top_audio_mux2_sel",
28*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_MUX1_DIV] = "top_audio_mux1_div",
29*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_MUX2_DIV] = "top_audio_mux2_div",
30*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_48K_TIMING] = "top_audio_48k_timing",
31*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_44K_TIMING] = "top_audio_44k_timing",
32*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUDPLL_MUX_SEL] = "top_audpll_mux_sel",
33*d6f3710aSGarlic Tseng 	[MT2701_AUD_APLL_SEL] = "top_apll_sel",
34*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD1PLL_98M] = "top_aud1_pll_98M",
35*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD2PLL_90M] = "top_aud2_pll_90M",
36*d6f3710aSGarlic Tseng 	[MT2701_AUD_HADDS2PLL_98M] = "top_hadds2_pll_98M",
37*d6f3710aSGarlic Tseng 	[MT2701_AUD_HADDS2PLL_294M] = "top_hadds2_pll_294M",
38*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUDPLL] = "top_audpll",
39*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUDPLL_D4] = "top_audpll_d4",
40*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUDPLL_D8] = "top_audpll_d8",
41*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUDPLL_D16] = "top_audpll_d16",
42*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUDPLL_D24] = "top_audpll_d24",
43*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUDINTBUS] = "top_audintbus_sel",
44*d6f3710aSGarlic Tseng 	[MT2701_AUD_CLK_26M] = "clk_26m",
45*d6f3710aSGarlic Tseng 	[MT2701_AUD_SYSPLL1_D4] = "top_syspll1_d4",
46*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_K1_SRC_SEL] = "top_aud_k1_src_sel",
47*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_K2_SRC_SEL] = "top_aud_k2_src_sel",
48*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_K3_SRC_SEL] = "top_aud_k3_src_sel",
49*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_K4_SRC_SEL] = "top_aud_k4_src_sel",
50*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_K5_SRC_SEL] = "top_aud_k5_src_sel",
51*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_K6_SRC_SEL] = "top_aud_k6_src_sel",
52*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_K1_SRC_DIV] = "top_aud_k1_src_div",
53*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_K2_SRC_DIV] = "top_aud_k2_src_div",
54*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_K3_SRC_DIV] = "top_aud_k3_src_div",
55*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_K4_SRC_DIV] = "top_aud_k4_src_div",
56*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_K5_SRC_DIV] = "top_aud_k5_src_div",
57*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_K6_SRC_DIV] = "top_aud_k6_src_div",
58*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_I2S1_MCLK] = "top_aud_i2s1_mclk",
59*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_I2S2_MCLK] = "top_aud_i2s2_mclk",
60*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_I2S3_MCLK] = "top_aud_i2s3_mclk",
61*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_I2S4_MCLK] = "top_aud_i2s4_mclk",
62*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_I2S5_MCLK] = "top_aud_i2s5_mclk",
63*d6f3710aSGarlic Tseng 	[MT2701_AUD_AUD_I2S6_MCLK] = "top_aud_i2s6_mclk",
64*d6f3710aSGarlic Tseng 	[MT2701_AUD_ASM_M_SEL] = "top_asm_m_sel",
65*d6f3710aSGarlic Tseng 	[MT2701_AUD_ASM_H_SEL] = "top_asm_h_sel",
66*d6f3710aSGarlic Tseng 	[MT2701_AUD_UNIVPLL2_D4] = "top_univpll2_d4",
67*d6f3710aSGarlic Tseng 	[MT2701_AUD_UNIVPLL2_D2] = "top_univpll2_d2",
68*d6f3710aSGarlic Tseng 	[MT2701_AUD_SYSPLL_D5] = "top_syspll_d5",
69*d6f3710aSGarlic Tseng };
70*d6f3710aSGarlic Tseng 
71*d6f3710aSGarlic Tseng int mt2701_init_clock(struct mtk_base_afe *afe)
72*d6f3710aSGarlic Tseng {
73*d6f3710aSGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
74*d6f3710aSGarlic Tseng 	int i = 0;
75*d6f3710aSGarlic Tseng 
76*d6f3710aSGarlic Tseng 	for (i = 0; i < MT2701_CLOCK_NUM; i++) {
77*d6f3710aSGarlic Tseng 		afe_priv->clocks[i] = devm_clk_get(afe->dev, aud_clks[i]);
78*d6f3710aSGarlic Tseng 		if (IS_ERR(aud_clks[i])) {
79*d6f3710aSGarlic Tseng 			dev_warn(afe->dev, "%s devm_clk_get %s fail\n",
80*d6f3710aSGarlic Tseng 				 __func__, aud_clks[i]);
81*d6f3710aSGarlic Tseng 			return PTR_ERR(aud_clks[i]);
82*d6f3710aSGarlic Tseng 		}
83*d6f3710aSGarlic Tseng 	}
84*d6f3710aSGarlic Tseng 
85*d6f3710aSGarlic Tseng 	return 0;
86*d6f3710aSGarlic Tseng }
87*d6f3710aSGarlic Tseng 
88*d6f3710aSGarlic Tseng int mt2701_afe_enable_clock(struct mtk_base_afe *afe)
89*d6f3710aSGarlic Tseng {
90*d6f3710aSGarlic Tseng 	int ret = 0;
91*d6f3710aSGarlic Tseng 
92*d6f3710aSGarlic Tseng 	ret = mt2701_turn_on_a1sys_clock(afe);
93*d6f3710aSGarlic Tseng 	if (ret) {
94*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s turn_on_a1sys_clock fail %d\n",
95*d6f3710aSGarlic Tseng 			__func__, ret);
96*d6f3710aSGarlic Tseng 		return ret;
97*d6f3710aSGarlic Tseng 	}
98*d6f3710aSGarlic Tseng 
99*d6f3710aSGarlic Tseng 	ret = mt2701_turn_on_a2sys_clock(afe);
100*d6f3710aSGarlic Tseng 	if (ret) {
101*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s turn_on_a2sys_clock fail %d\n",
102*d6f3710aSGarlic Tseng 			__func__, ret);
103*d6f3710aSGarlic Tseng 		mt2701_turn_off_a1sys_clock(afe);
104*d6f3710aSGarlic Tseng 		return ret;
105*d6f3710aSGarlic Tseng 	}
106*d6f3710aSGarlic Tseng 
107*d6f3710aSGarlic Tseng 	ret = mt2701_turn_on_afe_clock(afe);
108*d6f3710aSGarlic Tseng 	if (ret) {
109*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s turn_on_afe_clock fail %d\n",
110*d6f3710aSGarlic Tseng 			__func__, ret);
111*d6f3710aSGarlic Tseng 		mt2701_turn_off_a1sys_clock(afe);
112*d6f3710aSGarlic Tseng 		mt2701_turn_off_a2sys_clock(afe);
113*d6f3710aSGarlic Tseng 		return ret;
114*d6f3710aSGarlic Tseng 	}
115*d6f3710aSGarlic Tseng 
116*d6f3710aSGarlic Tseng 	regmap_update_bits(afe->regmap, ASYS_TOP_CON,
117*d6f3710aSGarlic Tseng 			   AUDIO_TOP_CON0_A1SYS_A2SYS_ON,
118*d6f3710aSGarlic Tseng 			   AUDIO_TOP_CON0_A1SYS_A2SYS_ON);
119*d6f3710aSGarlic Tseng 	regmap_update_bits(afe->regmap, AFE_DAC_CON0,
120*d6f3710aSGarlic Tseng 			   AFE_DAC_CON0_AFE_ON,
121*d6f3710aSGarlic Tseng 			   AFE_DAC_CON0_AFE_ON);
122*d6f3710aSGarlic Tseng 	regmap_write(afe->regmap, PWR2_TOP_CON,
123*d6f3710aSGarlic Tseng 		     PWR2_TOP_CON_INIT_VAL);
124*d6f3710aSGarlic Tseng 	regmap_write(afe->regmap, PWR1_ASM_CON1,
125*d6f3710aSGarlic Tseng 		     PWR1_ASM_CON1_INIT_VAL);
126*d6f3710aSGarlic Tseng 	regmap_write(afe->regmap, PWR2_ASM_CON1,
127*d6f3710aSGarlic Tseng 		     PWR2_ASM_CON1_INIT_VAL);
128*d6f3710aSGarlic Tseng 
129*d6f3710aSGarlic Tseng 	return 0;
130*d6f3710aSGarlic Tseng }
131*d6f3710aSGarlic Tseng 
132*d6f3710aSGarlic Tseng void mt2701_afe_disable_clock(struct mtk_base_afe *afe)
133*d6f3710aSGarlic Tseng {
134*d6f3710aSGarlic Tseng 	mt2701_turn_off_afe_clock(afe);
135*d6f3710aSGarlic Tseng 	mt2701_turn_off_a1sys_clock(afe);
136*d6f3710aSGarlic Tseng 	mt2701_turn_off_a2sys_clock(afe);
137*d6f3710aSGarlic Tseng 	regmap_update_bits(afe->regmap, ASYS_TOP_CON,
138*d6f3710aSGarlic Tseng 			   AUDIO_TOP_CON0_A1SYS_A2SYS_ON, 0);
139*d6f3710aSGarlic Tseng 	regmap_update_bits(afe->regmap, AFE_DAC_CON0,
140*d6f3710aSGarlic Tseng 			   AFE_DAC_CON0_AFE_ON, 0);
141*d6f3710aSGarlic Tseng }
142*d6f3710aSGarlic Tseng 
143*d6f3710aSGarlic Tseng int mt2701_turn_on_a1sys_clock(struct mtk_base_afe *afe)
144*d6f3710aSGarlic Tseng {
145*d6f3710aSGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
146*d6f3710aSGarlic Tseng 	int ret = 0;
147*d6f3710aSGarlic Tseng 
148*d6f3710aSGarlic Tseng 	/* Set Mux */
149*d6f3710aSGarlic Tseng 	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]);
150*d6f3710aSGarlic Tseng 	if (ret) {
151*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
152*d6f3710aSGarlic Tseng 			__func__, aud_clks[MT2701_AUD_AUD_MUX1_SEL], ret);
153*d6f3710aSGarlic Tseng 		goto A1SYS_CLK_AUD_MUX1_SEL_ERR;
154*d6f3710aSGarlic Tseng 	}
155*d6f3710aSGarlic Tseng 
156*d6f3710aSGarlic Tseng 	ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL],
157*d6f3710aSGarlic Tseng 			     afe_priv->clocks[MT2701_AUD_AUD1PLL_98M]);
158*d6f3710aSGarlic Tseng 	if (ret) {
159*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__,
160*d6f3710aSGarlic Tseng 			aud_clks[MT2701_AUD_AUD_MUX1_SEL],
161*d6f3710aSGarlic Tseng 			aud_clks[MT2701_AUD_AUD1PLL_98M], ret);
162*d6f3710aSGarlic Tseng 		goto A1SYS_CLK_AUD_MUX1_SEL_ERR;
163*d6f3710aSGarlic Tseng 	}
164*d6f3710aSGarlic Tseng 
165*d6f3710aSGarlic Tseng 	/* Set Divider */
166*d6f3710aSGarlic Tseng 	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV]);
167*d6f3710aSGarlic Tseng 	if (ret) {
168*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
169*d6f3710aSGarlic Tseng 			__func__,
170*d6f3710aSGarlic Tseng 			aud_clks[MT2701_AUD_AUD_MUX1_DIV],
171*d6f3710aSGarlic Tseng 			ret);
172*d6f3710aSGarlic Tseng 		goto A1SYS_CLK_AUD_MUX1_DIV_ERR;
173*d6f3710aSGarlic Tseng 	}
174*d6f3710aSGarlic Tseng 
175*d6f3710aSGarlic Tseng 	ret = clk_set_rate(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV],
176*d6f3710aSGarlic Tseng 			   MT2701_AUD_AUD_MUX1_DIV_RATE);
177*d6f3710aSGarlic Tseng 	if (ret) {
178*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_set_parent %s-%d fail %d\n", __func__,
179*d6f3710aSGarlic Tseng 			aud_clks[MT2701_AUD_AUD_MUX1_DIV],
180*d6f3710aSGarlic Tseng 			MT2701_AUD_AUD_MUX1_DIV_RATE, ret);
181*d6f3710aSGarlic Tseng 		goto A1SYS_CLK_AUD_MUX1_DIV_ERR;
182*d6f3710aSGarlic Tseng 	}
183*d6f3710aSGarlic Tseng 
184*d6f3710aSGarlic Tseng 	/* Enable clock gate */
185*d6f3710aSGarlic Tseng 	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_48K_TIMING]);
186*d6f3710aSGarlic Tseng 	if (ret) {
187*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
188*d6f3710aSGarlic Tseng 			__func__, aud_clks[MT2701_AUD_AUD_48K_TIMING], ret);
189*d6f3710aSGarlic Tseng 		goto A1SYS_CLK_AUD_48K_ERR;
190*d6f3710aSGarlic Tseng 	}
191*d6f3710aSGarlic Tseng 
192*d6f3710aSGarlic Tseng 	/* Enable infra audio */
193*d6f3710aSGarlic Tseng 	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
194*d6f3710aSGarlic Tseng 	if (ret) {
195*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
196*d6f3710aSGarlic Tseng 			__func__, aud_clks[MT2701_AUD_INFRA_SYS_AUDIO], ret);
197*d6f3710aSGarlic Tseng 		goto A1SYS_CLK_INFRA_ERR;
198*d6f3710aSGarlic Tseng 	}
199*d6f3710aSGarlic Tseng 
200*d6f3710aSGarlic Tseng 	return 0;
201*d6f3710aSGarlic Tseng 
202*d6f3710aSGarlic Tseng A1SYS_CLK_INFRA_ERR:
203*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
204*d6f3710aSGarlic Tseng A1SYS_CLK_AUD_48K_ERR:
205*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_48K_TIMING]);
206*d6f3710aSGarlic Tseng A1SYS_CLK_AUD_MUX1_DIV_ERR:
207*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV]);
208*d6f3710aSGarlic Tseng A1SYS_CLK_AUD_MUX1_SEL_ERR:
209*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]);
210*d6f3710aSGarlic Tseng 
211*d6f3710aSGarlic Tseng 	return ret;
212*d6f3710aSGarlic Tseng }
213*d6f3710aSGarlic Tseng 
214*d6f3710aSGarlic Tseng void mt2701_turn_off_a1sys_clock(struct mtk_base_afe *afe)
215*d6f3710aSGarlic Tseng {
216*d6f3710aSGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
217*d6f3710aSGarlic Tseng 
218*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
219*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_48K_TIMING]);
220*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV]);
221*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]);
222*d6f3710aSGarlic Tseng }
223*d6f3710aSGarlic Tseng 
224*d6f3710aSGarlic Tseng int mt2701_turn_on_a2sys_clock(struct mtk_base_afe *afe)
225*d6f3710aSGarlic Tseng {
226*d6f3710aSGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
227*d6f3710aSGarlic Tseng 	int ret = 0;
228*d6f3710aSGarlic Tseng 
229*d6f3710aSGarlic Tseng 	/* Set Mux */
230*d6f3710aSGarlic Tseng 	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]);
231*d6f3710aSGarlic Tseng 	if (ret) {
232*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
233*d6f3710aSGarlic Tseng 			__func__, aud_clks[MT2701_AUD_AUD_MUX2_SEL], ret);
234*d6f3710aSGarlic Tseng 		goto A2SYS_CLK_AUD_MUX2_SEL_ERR;
235*d6f3710aSGarlic Tseng 	}
236*d6f3710aSGarlic Tseng 
237*d6f3710aSGarlic Tseng 	ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL],
238*d6f3710aSGarlic Tseng 			     afe_priv->clocks[MT2701_AUD_AUD2PLL_90M]);
239*d6f3710aSGarlic Tseng 	if (ret) {
240*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__,
241*d6f3710aSGarlic Tseng 			aud_clks[MT2701_AUD_AUD_MUX2_SEL],
242*d6f3710aSGarlic Tseng 			aud_clks[MT2701_AUD_AUD2PLL_90M], ret);
243*d6f3710aSGarlic Tseng 		goto A2SYS_CLK_AUD_MUX2_SEL_ERR;
244*d6f3710aSGarlic Tseng 	}
245*d6f3710aSGarlic Tseng 
246*d6f3710aSGarlic Tseng 	/* Set Divider */
247*d6f3710aSGarlic Tseng 	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV]);
248*d6f3710aSGarlic Tseng 	if (ret) {
249*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
250*d6f3710aSGarlic Tseng 			__func__, aud_clks[MT2701_AUD_AUD_MUX2_DIV], ret);
251*d6f3710aSGarlic Tseng 		goto A2SYS_CLK_AUD_MUX2_DIV_ERR;
252*d6f3710aSGarlic Tseng 	}
253*d6f3710aSGarlic Tseng 
254*d6f3710aSGarlic Tseng 	ret = clk_set_rate(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV],
255*d6f3710aSGarlic Tseng 			   MT2701_AUD_AUD_MUX2_DIV_RATE);
256*d6f3710aSGarlic Tseng 	if (ret) {
257*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_set_parent %s-%d fail %d\n", __func__,
258*d6f3710aSGarlic Tseng 			aud_clks[MT2701_AUD_AUD_MUX2_DIV],
259*d6f3710aSGarlic Tseng 			MT2701_AUD_AUD_MUX2_DIV_RATE, ret);
260*d6f3710aSGarlic Tseng 		goto A2SYS_CLK_AUD_MUX2_DIV_ERR;
261*d6f3710aSGarlic Tseng 	}
262*d6f3710aSGarlic Tseng 
263*d6f3710aSGarlic Tseng 	/* Enable clock gate */
264*d6f3710aSGarlic Tseng 	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_44K_TIMING]);
265*d6f3710aSGarlic Tseng 	if (ret) {
266*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
267*d6f3710aSGarlic Tseng 			__func__, aud_clks[MT2701_AUD_AUD_44K_TIMING], ret);
268*d6f3710aSGarlic Tseng 		goto A2SYS_CLK_AUD_44K_ERR;
269*d6f3710aSGarlic Tseng 	}
270*d6f3710aSGarlic Tseng 
271*d6f3710aSGarlic Tseng 	/* Enable infra audio */
272*d6f3710aSGarlic Tseng 	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
273*d6f3710aSGarlic Tseng 	if (ret) {
274*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
275*d6f3710aSGarlic Tseng 			__func__, aud_clks[MT2701_AUD_INFRA_SYS_AUDIO], ret);
276*d6f3710aSGarlic Tseng 		goto A2SYS_CLK_INFRA_ERR;
277*d6f3710aSGarlic Tseng 	}
278*d6f3710aSGarlic Tseng 
279*d6f3710aSGarlic Tseng 	return 0;
280*d6f3710aSGarlic Tseng 
281*d6f3710aSGarlic Tseng A2SYS_CLK_INFRA_ERR:
282*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
283*d6f3710aSGarlic Tseng A2SYS_CLK_AUD_44K_ERR:
284*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_44K_TIMING]);
285*d6f3710aSGarlic Tseng A2SYS_CLK_AUD_MUX2_DIV_ERR:
286*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV]);
287*d6f3710aSGarlic Tseng A2SYS_CLK_AUD_MUX2_SEL_ERR:
288*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]);
289*d6f3710aSGarlic Tseng 
290*d6f3710aSGarlic Tseng 	return ret;
291*d6f3710aSGarlic Tseng }
292*d6f3710aSGarlic Tseng 
293*d6f3710aSGarlic Tseng void mt2701_turn_off_a2sys_clock(struct mtk_base_afe *afe)
294*d6f3710aSGarlic Tseng {
295*d6f3710aSGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
296*d6f3710aSGarlic Tseng 
297*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
298*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_44K_TIMING]);
299*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV]);
300*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]);
301*d6f3710aSGarlic Tseng }
302*d6f3710aSGarlic Tseng 
303*d6f3710aSGarlic Tseng int mt2701_turn_on_afe_clock(struct mtk_base_afe *afe)
304*d6f3710aSGarlic Tseng {
305*d6f3710aSGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
306*d6f3710aSGarlic Tseng 	int ret;
307*d6f3710aSGarlic Tseng 
308*d6f3710aSGarlic Tseng 	/* enable INFRA_SYS */
309*d6f3710aSGarlic Tseng 	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
310*d6f3710aSGarlic Tseng 	if (ret) {
311*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
312*d6f3710aSGarlic Tseng 			__func__, aud_clks[MT2701_AUD_INFRA_SYS_AUDIO], ret);
313*d6f3710aSGarlic Tseng 		goto AFE_AUD_INFRA_ERR;
314*d6f3710aSGarlic Tseng 	}
315*d6f3710aSGarlic Tseng 
316*d6f3710aSGarlic Tseng 	/* Set MT2701_AUD_AUDINTBUS to MT2701_AUD_SYSPLL1_D4 */
317*d6f3710aSGarlic Tseng 	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUDINTBUS]);
318*d6f3710aSGarlic Tseng 	if (ret) {
319*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
320*d6f3710aSGarlic Tseng 			__func__, aud_clks[MT2701_AUD_AUDINTBUS], ret);
321*d6f3710aSGarlic Tseng 		goto AFE_AUD_AUDINTBUS_ERR;
322*d6f3710aSGarlic Tseng 	}
323*d6f3710aSGarlic Tseng 
324*d6f3710aSGarlic Tseng 	ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_AUDINTBUS],
325*d6f3710aSGarlic Tseng 			     afe_priv->clocks[MT2701_AUD_SYSPLL1_D4]);
326*d6f3710aSGarlic Tseng 	if (ret) {
327*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__,
328*d6f3710aSGarlic Tseng 			aud_clks[MT2701_AUD_AUDINTBUS],
329*d6f3710aSGarlic Tseng 			aud_clks[MT2701_AUD_SYSPLL1_D4], ret);
330*d6f3710aSGarlic Tseng 		goto AFE_AUD_AUDINTBUS_ERR;
331*d6f3710aSGarlic Tseng 	}
332*d6f3710aSGarlic Tseng 
333*d6f3710aSGarlic Tseng 	/* Set MT2701_AUD_ASM_H_SEL to MT2701_AUD_UNIVPLL2_D2 */
334*d6f3710aSGarlic Tseng 	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_ASM_H_SEL]);
335*d6f3710aSGarlic Tseng 	if (ret) {
336*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
337*d6f3710aSGarlic Tseng 			__func__, aud_clks[MT2701_AUD_ASM_H_SEL], ret);
338*d6f3710aSGarlic Tseng 		goto AFE_AUD_ASM_H_ERR;
339*d6f3710aSGarlic Tseng 	}
340*d6f3710aSGarlic Tseng 
341*d6f3710aSGarlic Tseng 	ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_ASM_H_SEL],
342*d6f3710aSGarlic Tseng 			     afe_priv->clocks[MT2701_AUD_UNIVPLL2_D2]);
343*d6f3710aSGarlic Tseng 	if (ret) {
344*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__,
345*d6f3710aSGarlic Tseng 			aud_clks[MT2701_AUD_ASM_H_SEL],
346*d6f3710aSGarlic Tseng 			aud_clks[MT2701_AUD_UNIVPLL2_D2], ret);
347*d6f3710aSGarlic Tseng 		goto AFE_AUD_ASM_H_ERR;
348*d6f3710aSGarlic Tseng 	}
349*d6f3710aSGarlic Tseng 
350*d6f3710aSGarlic Tseng 	/* Set MT2701_AUD_ASM_M_SEL to MT2701_AUD_UNIVPLL2_D4 */
351*d6f3710aSGarlic Tseng 	ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_ASM_M_SEL]);
352*d6f3710aSGarlic Tseng 	if (ret) {
353*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
354*d6f3710aSGarlic Tseng 			__func__, aud_clks[MT2701_AUD_ASM_M_SEL], ret);
355*d6f3710aSGarlic Tseng 		goto AFE_AUD_ASM_M_ERR;
356*d6f3710aSGarlic Tseng 	}
357*d6f3710aSGarlic Tseng 
358*d6f3710aSGarlic Tseng 	ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_ASM_M_SEL],
359*d6f3710aSGarlic Tseng 			     afe_priv->clocks[MT2701_AUD_UNIVPLL2_D4]);
360*d6f3710aSGarlic Tseng 	if (ret) {
361*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__,
362*d6f3710aSGarlic Tseng 			aud_clks[MT2701_AUD_ASM_M_SEL],
363*d6f3710aSGarlic Tseng 			aud_clks[MT2701_AUD_UNIVPLL2_D4], ret);
364*d6f3710aSGarlic Tseng 		goto AFE_AUD_ASM_M_ERR;
365*d6f3710aSGarlic Tseng 	}
366*d6f3710aSGarlic Tseng 
367*d6f3710aSGarlic Tseng 	regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
368*d6f3710aSGarlic Tseng 			   AUDIO_TOP_CON0_PDN_AFE, 0);
369*d6f3710aSGarlic Tseng 	regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
370*d6f3710aSGarlic Tseng 			   AUDIO_TOP_CON0_PDN_APLL_CK, 0);
371*d6f3710aSGarlic Tseng 	regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
372*d6f3710aSGarlic Tseng 			   AUDIO_TOP_CON4_PDN_A1SYS, 0);
373*d6f3710aSGarlic Tseng 	regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
374*d6f3710aSGarlic Tseng 			   AUDIO_TOP_CON4_PDN_A2SYS, 0);
375*d6f3710aSGarlic Tseng 	regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
376*d6f3710aSGarlic Tseng 			   AUDIO_TOP_CON4_PDN_AFE_CONN, 0);
377*d6f3710aSGarlic Tseng 
378*d6f3710aSGarlic Tseng 	return 0;
379*d6f3710aSGarlic Tseng 
380*d6f3710aSGarlic Tseng AFE_AUD_ASM_M_ERR:
381*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_M_SEL]);
382*d6f3710aSGarlic Tseng AFE_AUD_ASM_H_ERR:
383*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_H_SEL]);
384*d6f3710aSGarlic Tseng AFE_AUD_AUDINTBUS_ERR:
385*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUDINTBUS]);
386*d6f3710aSGarlic Tseng AFE_AUD_INFRA_ERR:
387*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
388*d6f3710aSGarlic Tseng 
389*d6f3710aSGarlic Tseng 	return ret;
390*d6f3710aSGarlic Tseng }
391*d6f3710aSGarlic Tseng 
392*d6f3710aSGarlic Tseng void mt2701_turn_off_afe_clock(struct mtk_base_afe *afe)
393*d6f3710aSGarlic Tseng {
394*d6f3710aSGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
395*d6f3710aSGarlic Tseng 
396*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]);
397*d6f3710aSGarlic Tseng 
398*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUDINTBUS]);
399*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_H_SEL]);
400*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_M_SEL]);
401*d6f3710aSGarlic Tseng 
402*d6f3710aSGarlic Tseng 	regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
403*d6f3710aSGarlic Tseng 			   AUDIO_TOP_CON0_PDN_AFE, AUDIO_TOP_CON0_PDN_AFE);
404*d6f3710aSGarlic Tseng 	regmap_update_bits(afe->regmap, AUDIO_TOP_CON0,
405*d6f3710aSGarlic Tseng 			   AUDIO_TOP_CON0_PDN_APLL_CK,
406*d6f3710aSGarlic Tseng 			   AUDIO_TOP_CON0_PDN_APLL_CK);
407*d6f3710aSGarlic Tseng 	regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
408*d6f3710aSGarlic Tseng 			   AUDIO_TOP_CON4_PDN_A1SYS,
409*d6f3710aSGarlic Tseng 			   AUDIO_TOP_CON4_PDN_A1SYS);
410*d6f3710aSGarlic Tseng 	regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
411*d6f3710aSGarlic Tseng 			   AUDIO_TOP_CON4_PDN_A2SYS,
412*d6f3710aSGarlic Tseng 			   AUDIO_TOP_CON4_PDN_A2SYS);
413*d6f3710aSGarlic Tseng 	regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
414*d6f3710aSGarlic Tseng 			   AUDIO_TOP_CON4_PDN_AFE_CONN,
415*d6f3710aSGarlic Tseng 			   AUDIO_TOP_CON4_PDN_AFE_CONN);
416*d6f3710aSGarlic Tseng }
417*d6f3710aSGarlic Tseng 
418*d6f3710aSGarlic Tseng void mt2701_mclk_configuration(struct mtk_base_afe *afe, int id, int domain,
419*d6f3710aSGarlic Tseng 			       int mclk)
420*d6f3710aSGarlic Tseng {
421*d6f3710aSGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
422*d6f3710aSGarlic Tseng 	int ret;
423*d6f3710aSGarlic Tseng 	int aud_src_div_id = MT2701_AUD_AUD_K1_SRC_DIV + id;
424*d6f3710aSGarlic Tseng 	int aud_src_clk_id = MT2701_AUD_AUD_K1_SRC_SEL + id;
425*d6f3710aSGarlic Tseng 
426*d6f3710aSGarlic Tseng 	/* Set MCLK Kx_SRC_SEL(domain) */
427*d6f3710aSGarlic Tseng 	ret = clk_prepare_enable(afe_priv->clocks[aud_src_clk_id]);
428*d6f3710aSGarlic Tseng 	if (ret)
429*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
430*d6f3710aSGarlic Tseng 			__func__, aud_clks[aud_src_clk_id], ret);
431*d6f3710aSGarlic Tseng 
432*d6f3710aSGarlic Tseng 	if (domain == 0) {
433*d6f3710aSGarlic Tseng 		ret = clk_set_parent(afe_priv->clocks[aud_src_clk_id],
434*d6f3710aSGarlic Tseng 				     afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]);
435*d6f3710aSGarlic Tseng 		if (ret)
436*d6f3710aSGarlic Tseng 			dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
437*d6f3710aSGarlic Tseng 				__func__, aud_clks[aud_src_clk_id],
438*d6f3710aSGarlic Tseng 				aud_clks[MT2701_AUD_AUD_MUX1_SEL], ret);
439*d6f3710aSGarlic Tseng 	} else {
440*d6f3710aSGarlic Tseng 		ret = clk_set_parent(afe_priv->clocks[aud_src_clk_id],
441*d6f3710aSGarlic Tseng 				     afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]);
442*d6f3710aSGarlic Tseng 		if (ret)
443*d6f3710aSGarlic Tseng 			dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
444*d6f3710aSGarlic Tseng 				__func__, aud_clks[aud_src_clk_id],
445*d6f3710aSGarlic Tseng 				aud_clks[MT2701_AUD_AUD_MUX2_SEL], ret);
446*d6f3710aSGarlic Tseng 	}
447*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[aud_src_clk_id]);
448*d6f3710aSGarlic Tseng 
449*d6f3710aSGarlic Tseng 	/* Set MCLK Kx_SRC_DIV(divider) */
450*d6f3710aSGarlic Tseng 	ret = clk_prepare_enable(afe_priv->clocks[aud_src_div_id]);
451*d6f3710aSGarlic Tseng 	if (ret)
452*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
453*d6f3710aSGarlic Tseng 			__func__, aud_clks[aud_src_div_id], ret);
454*d6f3710aSGarlic Tseng 
455*d6f3710aSGarlic Tseng 	ret = clk_set_rate(afe_priv->clocks[aud_src_div_id], mclk);
456*d6f3710aSGarlic Tseng 	if (ret)
457*d6f3710aSGarlic Tseng 		dev_err(afe->dev, "%s clk_set_rate %s-%d fail %d\n", __func__,
458*d6f3710aSGarlic Tseng 			aud_clks[aud_src_div_id], mclk, ret);
459*d6f3710aSGarlic Tseng 	clk_disable_unprepare(afe_priv->clocks[aud_src_div_id]);
460*d6f3710aSGarlic Tseng }
461*d6f3710aSGarlic Tseng 
462*d6f3710aSGarlic Tseng MODULE_DESCRIPTION("MT2701 afe clock control");
463*d6f3710aSGarlic Tseng MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>");
464*d6f3710aSGarlic Tseng MODULE_LICENSE("GPL v2");
465