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