162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci//
362306a36Sopenharmony_ci// mt6797-afe-clk.c  --  Mediatek 6797 afe clock ctrl
462306a36Sopenharmony_ci//
562306a36Sopenharmony_ci// Copyright (c) 2018 MediaTek Inc.
662306a36Sopenharmony_ci// Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/clk.h>
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include "mt6797-afe-common.h"
1162306a36Sopenharmony_ci#include "mt6797-afe-clk.h"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_cienum {
1462306a36Sopenharmony_ci	CLK_INFRA_SYS_AUD,
1562306a36Sopenharmony_ci	CLK_INFRA_SYS_AUD_26M,
1662306a36Sopenharmony_ci	CLK_TOP_MUX_AUD,
1762306a36Sopenharmony_ci	CLK_TOP_MUX_AUD_BUS,
1862306a36Sopenharmony_ci	CLK_TOP_SYSPLL3_D4,
1962306a36Sopenharmony_ci	CLK_TOP_SYSPLL1_D4,
2062306a36Sopenharmony_ci	CLK_CLK26M,
2162306a36Sopenharmony_ci	CLK_NUM
2262306a36Sopenharmony_ci};
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistatic const char *aud_clks[CLK_NUM] = {
2562306a36Sopenharmony_ci	[CLK_INFRA_SYS_AUD] = "infra_sys_audio_clk",
2662306a36Sopenharmony_ci	[CLK_INFRA_SYS_AUD_26M] = "infra_sys_audio_26m",
2762306a36Sopenharmony_ci	[CLK_TOP_MUX_AUD] = "top_mux_audio",
2862306a36Sopenharmony_ci	[CLK_TOP_MUX_AUD_BUS] = "top_mux_aud_intbus",
2962306a36Sopenharmony_ci	[CLK_TOP_SYSPLL3_D4] = "top_sys_pll3_d4",
3062306a36Sopenharmony_ci	[CLK_TOP_SYSPLL1_D4] = "top_sys_pll1_d4",
3162306a36Sopenharmony_ci	[CLK_CLK26M] = "top_clk26m_clk",
3262306a36Sopenharmony_ci};
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ciint mt6797_init_clock(struct mtk_base_afe *afe)
3562306a36Sopenharmony_ci{
3662306a36Sopenharmony_ci	struct mt6797_afe_private *afe_priv = afe->platform_priv;
3762306a36Sopenharmony_ci	int i;
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	afe_priv->clk = devm_kcalloc(afe->dev, CLK_NUM, sizeof(*afe_priv->clk),
4062306a36Sopenharmony_ci				     GFP_KERNEL);
4162306a36Sopenharmony_ci	if (!afe_priv->clk)
4262306a36Sopenharmony_ci		return -ENOMEM;
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	for (i = 0; i < CLK_NUM; i++) {
4562306a36Sopenharmony_ci		afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]);
4662306a36Sopenharmony_ci		if (IS_ERR(afe_priv->clk[i])) {
4762306a36Sopenharmony_ci			dev_err(afe->dev, "%s(), devm_clk_get %s fail, ret %ld\n",
4862306a36Sopenharmony_ci				__func__, aud_clks[i],
4962306a36Sopenharmony_ci				PTR_ERR(afe_priv->clk[i]));
5062306a36Sopenharmony_ci			return PTR_ERR(afe_priv->clk[i]);
5162306a36Sopenharmony_ci		}
5262306a36Sopenharmony_ci	}
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	return 0;
5562306a36Sopenharmony_ci}
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ciint mt6797_afe_enable_clock(struct mtk_base_afe *afe)
5862306a36Sopenharmony_ci{
5962306a36Sopenharmony_ci	struct mt6797_afe_private *afe_priv = afe->platform_priv;
6062306a36Sopenharmony_ci	int ret;
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_SYS_AUD]);
6362306a36Sopenharmony_ci	if (ret) {
6462306a36Sopenharmony_ci		dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
6562306a36Sopenharmony_ci			__func__, aud_clks[CLK_INFRA_SYS_AUD], ret);
6662306a36Sopenharmony_ci		goto CLK_INFRA_SYS_AUDIO_ERR;
6762306a36Sopenharmony_ci	}
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_SYS_AUD_26M]);
7062306a36Sopenharmony_ci	if (ret) {
7162306a36Sopenharmony_ci		dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
7262306a36Sopenharmony_ci			__func__, aud_clks[CLK_INFRA_SYS_AUD_26M], ret);
7362306a36Sopenharmony_ci		goto CLK_INFRA_SYS_AUD_26M_ERR;
7462306a36Sopenharmony_ci	}
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci	ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD]);
7762306a36Sopenharmony_ci	if (ret) {
7862306a36Sopenharmony_ci		dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
7962306a36Sopenharmony_ci			__func__, aud_clks[CLK_TOP_MUX_AUD], ret);
8062306a36Sopenharmony_ci		goto CLK_MUX_AUDIO_ERR;
8162306a36Sopenharmony_ci	}
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci	ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD],
8462306a36Sopenharmony_ci			     afe_priv->clk[CLK_CLK26M]);
8562306a36Sopenharmony_ci	if (ret) {
8662306a36Sopenharmony_ci		dev_err(afe->dev, "%s(), clk_set_parent %s-%s fail %d\n",
8762306a36Sopenharmony_ci			__func__, aud_clks[CLK_TOP_MUX_AUD],
8862306a36Sopenharmony_ci			aud_clks[CLK_CLK26M], ret);
8962306a36Sopenharmony_ci		goto CLK_MUX_AUDIO_ERR;
9062306a36Sopenharmony_ci	}
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci	ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_BUS]);
9362306a36Sopenharmony_ci	if (ret) {
9462306a36Sopenharmony_ci		dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
9562306a36Sopenharmony_ci			__func__, aud_clks[CLK_TOP_MUX_AUD_BUS], ret);
9662306a36Sopenharmony_ci		goto CLK_MUX_AUDIO_INTBUS_ERR;
9762306a36Sopenharmony_ci	}
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	return ret;
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ciCLK_MUX_AUDIO_INTBUS_ERR:
10262306a36Sopenharmony_ci	clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_BUS]);
10362306a36Sopenharmony_ciCLK_MUX_AUDIO_ERR:
10462306a36Sopenharmony_ci	clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD]);
10562306a36Sopenharmony_ciCLK_INFRA_SYS_AUD_26M_ERR:
10662306a36Sopenharmony_ci	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD_26M]);
10762306a36Sopenharmony_ciCLK_INFRA_SYS_AUDIO_ERR:
10862306a36Sopenharmony_ci	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD]);
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci	return 0;
11162306a36Sopenharmony_ci}
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ciint mt6797_afe_disable_clock(struct mtk_base_afe *afe)
11462306a36Sopenharmony_ci{
11562306a36Sopenharmony_ci	struct mt6797_afe_private *afe_priv = afe->platform_priv;
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_BUS]);
11862306a36Sopenharmony_ci	clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD]);
11962306a36Sopenharmony_ci	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD_26M]);
12062306a36Sopenharmony_ci	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD]);
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	return 0;
12362306a36Sopenharmony_ci}
124