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
;
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
];
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
)
99 afe_priv
->mrgif_ck
= NULL
;
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
];
111 ret
= clk_prepare_enable(i2s_path
->asrco_ck
);
113 dev_err(afe
->dev
, "failed to enable ASRC clock %d\n", ret
);
117 ret
= clk_prepare_enable(i2s_path
->hop_ck
[dir
]);
119 dev_err(afe
->dev
, "failed to enable I2S clock %d\n", ret
);
126 clk_disable_unprepare(i2s_path
->asrco_ck
);
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
;
175 /* Enable infra clock gate */
176 ret
= clk_prepare_enable(afe_priv
->base_ck
[MT2701_INFRA_SYS_AUDIO
]);
180 /* Enable top a1sys clock gate */
181 ret
= clk_prepare_enable(afe_priv
->base_ck
[MT2701_TOP_AUD_A1SYS
]);
185 /* Enable top a2sys clock gate */
186 ret
= clk_prepare_enable(afe_priv
->base_ck
[MT2701_TOP_AUD_A2SYS
]);
190 /* Internal clock gates */
191 ret
= clk_prepare_enable(afe_priv
->base_ck
[MT2701_AUDSYS_AFE
]);
195 ret
= clk_prepare_enable(afe_priv
->base_ck
[MT2701_AUDSYS_A1SYS
]);
197 goto err_audio_a1sys
;
199 ret
= clk_prepare_enable(afe_priv
->base_ck
[MT2701_AUDSYS_A2SYS
]);
201 goto err_audio_a2sys
;
203 ret
= clk_prepare_enable(afe_priv
->base_ck
[MT2701_AUDSYS_AFE_CONN
]);
210 clk_disable_unprepare(afe_priv
->base_ck
[MT2701_AUDSYS_A2SYS
]);
212 clk_disable_unprepare(afe_priv
->base_ck
[MT2701_AUDSYS_A1SYS
]);
214 clk_disable_unprepare(afe_priv
->base_ck
[MT2701_AUDSYS_AFE
]);
216 clk_disable_unprepare(afe_priv
->base_ck
[MT2701_TOP_AUD_A2SYS
]);
218 clk_disable_unprepare(afe_priv
->base_ck
[MT2701_TOP_AUD_A1SYS
]);
220 clk_disable_unprepare(afe_priv
->base_ck
[MT2701_INFRA_SYS_AUDIO
]);
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
)
242 /* Enable audio system */
243 ret
= mt2701_afe_enable_audsys(afe
);
245 dev_err(afe
->dev
, "failed to enable audio system %d\n", 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
,
254 AFE_DAC_CON0_AFE_ON
);
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
);
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
);
275 void mt2701_mclk_configuration(struct mtk_base_afe
*afe
, int id
, int domain
,
278 struct mt2701_afe_private
*priv
= afe
->platform_priv
;
279 struct mt2701_i2s_path
*i2s_path
= &priv
->i2s_path
[id
];
282 /* Set mclk source */
284 ret
= clk_set_parent(i2s_path
->sel_ck
,
285 priv
->base_ck
[MT2701_TOP_AUD_MCLK_SRC0
]);
287 ret
= clk_set_parent(i2s_path
->sel_ck
,
288 priv
->base_ck
[MT2701_TOP_AUD_MCLK_SRC1
]);
291 dev_err(afe
->dev
, "failed to set domain%d mclk source %d\n",
294 /* Set mclk divider */
295 ret
= clk_set_rate(i2s_path
->div_ck
, mclk
);
297 dev_err(afe
->dev
, "failed to set mclk divider %d\n", ret
);