124 lines · c
1// SPDX-License-Identifier: GPL-2.02//3// mt6797-afe-clk.c -- Mediatek 6797 afe clock ctrl4//5// Copyright (c) 2018 MediaTek Inc.6// Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>7 8#include <linux/clk.h>9 10#include "mt6797-afe-common.h"11#include "mt6797-afe-clk.h"12 13enum {14 CLK_INFRA_SYS_AUD,15 CLK_INFRA_SYS_AUD_26M,16 CLK_TOP_MUX_AUD,17 CLK_TOP_MUX_AUD_BUS,18 CLK_TOP_SYSPLL3_D4,19 CLK_TOP_SYSPLL1_D4,20 CLK_CLK26M,21 CLK_NUM22};23 24static const char *aud_clks[CLK_NUM] = {25 [CLK_INFRA_SYS_AUD] = "infra_sys_audio_clk",26 [CLK_INFRA_SYS_AUD_26M] = "infra_sys_audio_26m",27 [CLK_TOP_MUX_AUD] = "top_mux_audio",28 [CLK_TOP_MUX_AUD_BUS] = "top_mux_aud_intbus",29 [CLK_TOP_SYSPLL3_D4] = "top_sys_pll3_d4",30 [CLK_TOP_SYSPLL1_D4] = "top_sys_pll1_d4",31 [CLK_CLK26M] = "top_clk26m_clk",32};33 34int mt6797_init_clock(struct mtk_base_afe *afe)35{36 struct mt6797_afe_private *afe_priv = afe->platform_priv;37 int i;38 39 afe_priv->clk = devm_kcalloc(afe->dev, CLK_NUM, sizeof(*afe_priv->clk),40 GFP_KERNEL);41 if (!afe_priv->clk)42 return -ENOMEM;43 44 for (i = 0; i < CLK_NUM; i++) {45 afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]);46 if (IS_ERR(afe_priv->clk[i])) {47 dev_err(afe->dev, "%s(), devm_clk_get %s fail, ret %ld\n",48 __func__, aud_clks[i],49 PTR_ERR(afe_priv->clk[i]));50 return PTR_ERR(afe_priv->clk[i]);51 }52 }53 54 return 0;55}56 57int mt6797_afe_enable_clock(struct mtk_base_afe *afe)58{59 struct mt6797_afe_private *afe_priv = afe->platform_priv;60 int ret;61 62 ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_SYS_AUD]);63 if (ret) {64 dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",65 __func__, aud_clks[CLK_INFRA_SYS_AUD], ret);66 goto CLK_INFRA_SYS_AUDIO_ERR;67 }68 69 ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_SYS_AUD_26M]);70 if (ret) {71 dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",72 __func__, aud_clks[CLK_INFRA_SYS_AUD_26M], ret);73 goto CLK_INFRA_SYS_AUD_26M_ERR;74 }75 76 ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD]);77 if (ret) {78 dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",79 __func__, aud_clks[CLK_TOP_MUX_AUD], ret);80 goto CLK_MUX_AUDIO_ERR;81 }82 83 ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD],84 afe_priv->clk[CLK_CLK26M]);85 if (ret) {86 dev_err(afe->dev, "%s(), clk_set_parent %s-%s fail %d\n",87 __func__, aud_clks[CLK_TOP_MUX_AUD],88 aud_clks[CLK_CLK26M], ret);89 goto CLK_MUX_AUDIO_ERR;90 }91 92 ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_BUS]);93 if (ret) {94 dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",95 __func__, aud_clks[CLK_TOP_MUX_AUD_BUS], ret);96 goto CLK_MUX_AUDIO_INTBUS_ERR;97 }98 99 return ret;100 101CLK_MUX_AUDIO_INTBUS_ERR:102 clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_BUS]);103CLK_MUX_AUDIO_ERR:104 clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD]);105CLK_INFRA_SYS_AUD_26M_ERR:106 clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD_26M]);107CLK_INFRA_SYS_AUDIO_ERR:108 clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD]);109 110 return 0;111}112 113int mt6797_afe_disable_clock(struct mtk_base_afe *afe)114{115 struct mt6797_afe_private *afe_priv = afe->platform_priv;116 117 clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_BUS]);118 clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD]);119 clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD_26M]);120 clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUD]);121 122 return 0;123}124