Linux 4.16.11
[linux/fpc-iii.git] / sound / soc / mediatek / mt2701 / mt2701-afe-clock-ctrl.c
blob949fc3a1d02578d4e718cb80c87af4263de72d9f
1 /*
2 * mt2701-afe-clock-ctrl.c -- Mediatek 2701 afe clock ctrl
4 * Copyright (c) 2016 MediaTek Inc.
5 * Author: Garlic Tseng <garlic.tseng@mediatek.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 and
9 * only version 2 as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 #include "mt2701-afe-common.h"
18 #include "mt2701-afe-clock-ctrl.h"
20 static const char *const base_clks[] = {
21 [MT2701_INFRA_SYS_AUDIO] = "infra_sys_audio_clk",
22 [MT2701_TOP_AUD_MCLK_SRC0] = "top_audio_mux1_sel",
23 [MT2701_TOP_AUD_MCLK_SRC1] = "top_audio_mux2_sel",
24 [MT2701_TOP_AUD_A1SYS] = "top_audio_a1sys_hp",
25 [MT2701_TOP_AUD_A2SYS] = "top_audio_a2sys_hp",
26 [MT2701_AUDSYS_AFE] = "audio_afe_pd",
27 [MT2701_AUDSYS_AFE_CONN] = "audio_afe_conn_pd",
28 [MT2701_AUDSYS_A1SYS] = "audio_a1sys_pd",
29 [MT2701_AUDSYS_A2SYS] = "audio_a2sys_pd",
32 int mt2701_init_clock(struct mtk_base_afe *afe)
34 struct mt2701_afe_private *afe_priv = afe->platform_priv;
35 int i;
37 for (i = 0; i < MT2701_BASE_CLK_NUM; i++) {
38 afe_priv->base_ck[i] = devm_clk_get(afe->dev, base_clks[i]);
39 if (IS_ERR(afe_priv->base_ck[i])) {
40 dev_err(afe->dev, "failed to get %s\n", base_clks[i]);
41 return PTR_ERR(afe_priv->base_ck[i]);
45 /* Get I2S related clocks */
46 for (i = 0; i < MT2701_I2S_NUM; i++) {
47 struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i];
48 char name[13];
50 snprintf(name, sizeof(name), "i2s%d_src_sel", i);
51 i2s_path->sel_ck = devm_clk_get(afe->dev, name);
52 if (IS_ERR(i2s_path->sel_ck)) {
53 dev_err(afe->dev, "failed to get %s\n", name);
54 return PTR_ERR(i2s_path->sel_ck);
57 snprintf(name, sizeof(name), "i2s%d_src_div", i);
58 i2s_path->div_ck = devm_clk_get(afe->dev, name);
59 if (IS_ERR(i2s_path->div_ck)) {
60 dev_err(afe->dev, "failed to get %s\n", name);
61 return PTR_ERR(i2s_path->div_ck);
64 snprintf(name, sizeof(name), "i2s%d_mclk_en", i);
65 i2s_path->mclk_ck = devm_clk_get(afe->dev, name);
66 if (IS_ERR(i2s_path->mclk_ck)) {
67 dev_err(afe->dev, "failed to get %s\n", name);
68 return PTR_ERR(i2s_path->mclk_ck);
71 snprintf(name, sizeof(name), "i2so%d_hop_ck", i);
72 i2s_path->hop_ck[I2S_OUT] = devm_clk_get(afe->dev, name);
73 if (IS_ERR(i2s_path->hop_ck[I2S_OUT])) {
74 dev_err(afe->dev, "failed to get %s\n", name);
75 return PTR_ERR(i2s_path->hop_ck[I2S_OUT]);
78 snprintf(name, sizeof(name), "i2si%d_hop_ck", i);
79 i2s_path->hop_ck[I2S_IN] = devm_clk_get(afe->dev, name);
80 if (IS_ERR(i2s_path->hop_ck[I2S_IN])) {
81 dev_err(afe->dev, "failed to get %s\n", name);
82 return PTR_ERR(i2s_path->hop_ck[I2S_IN]);
85 snprintf(name, sizeof(name), "asrc%d_out_ck", i);
86 i2s_path->asrco_ck = devm_clk_get(afe->dev, name);
87 if (IS_ERR(i2s_path->asrco_ck)) {
88 dev_err(afe->dev, "failed to get %s\n", name);
89 return PTR_ERR(i2s_path->asrco_ck);
93 /* Some platforms may support BT path */
94 afe_priv->mrgif_ck = devm_clk_get(afe->dev, "audio_mrgif_pd");
95 if (IS_ERR(afe_priv->mrgif_ck)) {
96 if (PTR_ERR(afe_priv->mrgif_ck) == -EPROBE_DEFER)
97 return -EPROBE_DEFER;
99 afe_priv->mrgif_ck = NULL;
102 return 0;
105 int mt2701_afe_enable_i2s(struct mtk_base_afe *afe, int id, int dir)
107 struct mt2701_afe_private *afe_priv = afe->platform_priv;
108 struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
109 int ret;
111 ret = clk_prepare_enable(i2s_path->asrco_ck);
112 if (ret) {
113 dev_err(afe->dev, "failed to enable ASRC clock %d\n", ret);
114 return ret;
117 ret = clk_prepare_enable(i2s_path->hop_ck[dir]);
118 if (ret) {
119 dev_err(afe->dev, "failed to enable I2S clock %d\n", ret);
120 goto err_hop_ck;
123 return 0;
125 err_hop_ck:
126 clk_disable_unprepare(i2s_path->asrco_ck);
128 return ret;
131 void mt2701_afe_disable_i2s(struct mtk_base_afe *afe, int id, int dir)
133 struct mt2701_afe_private *afe_priv = afe->platform_priv;
134 struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
136 clk_disable_unprepare(i2s_path->hop_ck[dir]);
137 clk_disable_unprepare(i2s_path->asrco_ck);
140 int mt2701_afe_enable_mclk(struct mtk_base_afe *afe, int id)
142 struct mt2701_afe_private *afe_priv = afe->platform_priv;
143 struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
145 return clk_prepare_enable(i2s_path->mclk_ck);
148 void mt2701_afe_disable_mclk(struct mtk_base_afe *afe, int id)
150 struct mt2701_afe_private *afe_priv = afe->platform_priv;
151 struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
153 clk_disable_unprepare(i2s_path->mclk_ck);
156 int mt2701_enable_btmrg_clk(struct mtk_base_afe *afe)
158 struct mt2701_afe_private *afe_priv = afe->platform_priv;
160 return clk_prepare_enable(afe_priv->mrgif_ck);
163 void mt2701_disable_btmrg_clk(struct mtk_base_afe *afe)
165 struct mt2701_afe_private *afe_priv = afe->platform_priv;
167 clk_disable_unprepare(afe_priv->mrgif_ck);
170 static int mt2701_afe_enable_audsys(struct mtk_base_afe *afe)
172 struct mt2701_afe_private *afe_priv = afe->platform_priv;
173 int ret;
175 /* Enable infra clock gate */
176 ret = clk_prepare_enable(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
177 if (ret)
178 return ret;
180 /* Enable top a1sys clock gate */
181 ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
182 if (ret)
183 goto err_a1sys;
185 /* Enable top a2sys clock gate */
186 ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
187 if (ret)
188 goto err_a2sys;
190 /* Internal clock gates */
191 ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
192 if (ret)
193 goto err_afe;
195 ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
196 if (ret)
197 goto err_audio_a1sys;
199 ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
200 if (ret)
201 goto err_audio_a2sys;
203 ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]);
204 if (ret)
205 goto err_afe_conn;
207 return 0;
209 err_afe_conn:
210 clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
211 err_audio_a2sys:
212 clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
213 err_audio_a1sys:
214 clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
215 err_afe:
216 clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
217 err_a2sys:
218 clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
219 err_a1sys:
220 clk_disable_unprepare(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
222 return ret;
225 static void mt2701_afe_disable_audsys(struct mtk_base_afe *afe)
227 struct mt2701_afe_private *afe_priv = afe->platform_priv;
229 clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]);
230 clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
231 clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
232 clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
233 clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
234 clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
235 clk_disable_unprepare(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
238 int mt2701_afe_enable_clock(struct mtk_base_afe *afe)
240 int ret;
242 /* Enable audio system */
243 ret = mt2701_afe_enable_audsys(afe);
244 if (ret) {
245 dev_err(afe->dev, "failed to enable audio system %d\n", ret);
246 return ret;
249 regmap_update_bits(afe->regmap, ASYS_TOP_CON,
250 ASYS_TOP_CON_ASYS_TIMING_ON,
251 ASYS_TOP_CON_ASYS_TIMING_ON);
252 regmap_update_bits(afe->regmap, AFE_DAC_CON0,
253 AFE_DAC_CON0_AFE_ON,
254 AFE_DAC_CON0_AFE_ON);
256 /* Configure ASRC */
257 regmap_write(afe->regmap, PWR1_ASM_CON1, PWR1_ASM_CON1_INIT_VAL);
258 regmap_write(afe->regmap, PWR2_ASM_CON1, PWR2_ASM_CON1_INIT_VAL);
260 return 0;
263 int mt2701_afe_disable_clock(struct mtk_base_afe *afe)
265 regmap_update_bits(afe->regmap, ASYS_TOP_CON,
266 ASYS_TOP_CON_ASYS_TIMING_ON, 0);
267 regmap_update_bits(afe->regmap, AFE_DAC_CON0,
268 AFE_DAC_CON0_AFE_ON, 0);
270 mt2701_afe_disable_audsys(afe);
272 return 0;
275 void mt2701_mclk_configuration(struct mtk_base_afe *afe, int id, int domain,
276 int mclk)
278 struct mt2701_afe_private *priv = afe->platform_priv;
279 struct mt2701_i2s_path *i2s_path = &priv->i2s_path[id];
280 int ret;
282 /* Set mclk source */
283 if (domain == 0)
284 ret = clk_set_parent(i2s_path->sel_ck,
285 priv->base_ck[MT2701_TOP_AUD_MCLK_SRC0]);
286 else
287 ret = clk_set_parent(i2s_path->sel_ck,
288 priv->base_ck[MT2701_TOP_AUD_MCLK_SRC1]);
290 if (ret)
291 dev_err(afe->dev, "failed to set domain%d mclk source %d\n",
292 domain, ret);
294 /* Set mclk divider */
295 ret = clk_set_rate(i2s_path->div_ck, mclk);
296 if (ret)
297 dev_err(afe->dev, "failed to set mclk divider %d\n", ret);