linux/sound/soc/mediatek/mt6797/mt6797-afe-clk.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// mt6797-afe-clk.c  --  Mediatek 6797 afe clock ctrl
   4//
   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_NUM
  22};
  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