linux/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * mt2701-afe-clock-ctrl.c  --  Mediatek 2701 afe clock ctrl
   4 *
   5 * Copyright (c) 2016 MediaTek Inc.
   6 * Author: Garlic Tseng <garlic.tseng@mediatek.com>
   7 *         Ryder Lee <ryder.lee@mediatek.com>
   8 */
   9
  10#include "mt2701-afe-common.h"
  11#include "mt2701-afe-clock-ctrl.h"
  12
  13static const char *const base_clks[] = {
  14        [MT2701_INFRA_SYS_AUDIO] = "infra_sys_audio_clk",
  15        [MT2701_TOP_AUD_MCLK_SRC0] = "top_audio_mux1_sel",
  16        [MT2701_TOP_AUD_MCLK_SRC1] = "top_audio_mux2_sel",
  17        [MT2701_TOP_AUD_A1SYS] = "top_audio_a1sys_hp",
  18        [MT2701_TOP_AUD_A2SYS] = "top_audio_a2sys_hp",
  19        [MT2701_AUDSYS_AFE] = "audio_afe_pd",
  20        [MT2701_AUDSYS_AFE_CONN] = "audio_afe_conn_pd",
  21        [MT2701_AUDSYS_A1SYS] = "audio_a1sys_pd",
  22        [MT2701_AUDSYS_A2SYS] = "audio_a2sys_pd",
  23};
  24
  25int mt2701_init_clock(struct mtk_base_afe *afe)
  26{
  27        struct mt2701_afe_private *afe_priv = afe->platform_priv;
  28        int i;
  29
  30        for (i = 0; i < MT2701_BASE_CLK_NUM; i++) {
  31                afe_priv->base_ck[i] = devm_clk_get(afe->dev, base_clks[i]);
  32                if (IS_ERR(afe_priv->base_ck[i])) {
  33                        dev_err(afe->dev, "failed to get %s\n", base_clks[i]);
  34                        return PTR_ERR(afe_priv->base_ck[i]);
  35                }
  36        }
  37
  38        /* Get I2S related clocks */
  39        for (i = 0; i < afe_priv->soc->i2s_num; i++) {
  40                struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i];
  41                struct clk *i2s_ck;
  42                char name[13];
  43
  44                snprintf(name, sizeof(name), "i2s%d_src_sel", i);
  45                i2s_path->sel_ck = devm_clk_get(afe->dev, name);
  46                if (IS_ERR(i2s_path->sel_ck)) {
  47                        dev_err(afe->dev, "failed to get %s\n", name);
  48                        return PTR_ERR(i2s_path->sel_ck);
  49                }
  50
  51                snprintf(name, sizeof(name), "i2s%d_src_div", i);
  52                i2s_path->div_ck = devm_clk_get(afe->dev, name);
  53                if (IS_ERR(i2s_path->div_ck)) {
  54                        dev_err(afe->dev, "failed to get %s\n", name);
  55                        return PTR_ERR(i2s_path->div_ck);
  56                }
  57
  58                snprintf(name, sizeof(name), "i2s%d_mclk_en", i);
  59                i2s_path->mclk_ck = devm_clk_get(afe->dev, name);
  60                if (IS_ERR(i2s_path->mclk_ck)) {
  61                        dev_err(afe->dev, "failed to get %s\n", name);
  62                        return PTR_ERR(i2s_path->mclk_ck);
  63                }
  64
  65                snprintf(name, sizeof(name), "i2so%d_hop_ck", i);
  66                i2s_ck = devm_clk_get(afe->dev, name);
  67                if (IS_ERR(i2s_ck)) {
  68                        dev_err(afe->dev, "failed to get %s\n", name);
  69                        return PTR_ERR(i2s_ck);
  70                }
  71                i2s_path->hop_ck[SNDRV_PCM_STREAM_PLAYBACK] = i2s_ck;
  72
  73                snprintf(name, sizeof(name), "i2si%d_hop_ck", i);
  74                i2s_ck = devm_clk_get(afe->dev, name);
  75                if (IS_ERR(i2s_ck)) {
  76                        dev_err(afe->dev, "failed to get %s\n", name);
  77                        return PTR_ERR(i2s_ck);
  78                }
  79                i2s_path->hop_ck[SNDRV_PCM_STREAM_CAPTURE] = i2s_ck;
  80
  81                snprintf(name, sizeof(name), "asrc%d_out_ck", i);
  82                i2s_path->asrco_ck = devm_clk_get(afe->dev, name);
  83                if (IS_ERR(i2s_path->asrco_ck)) {
  84                        dev_err(afe->dev, "failed to get %s\n", name);
  85                        return PTR_ERR(i2s_path->asrco_ck);
  86                }
  87        }
  88
  89        /* Some platforms may support BT path */
  90        afe_priv->mrgif_ck = devm_clk_get(afe->dev, "audio_mrgif_pd");
  91        if (IS_ERR(afe_priv->mrgif_ck)) {
  92                if (PTR_ERR(afe_priv->mrgif_ck) == -EPROBE_DEFER)
  93                        return -EPROBE_DEFER;
  94
  95                afe_priv->mrgif_ck = NULL;
  96        }
  97
  98        return 0;
  99}
 100
 101int mt2701_afe_enable_i2s(struct mtk_base_afe *afe,
 102                          struct mt2701_i2s_path *i2s_path,
 103                          int dir)
 104{
 105        int ret;
 106
 107        ret = clk_prepare_enable(i2s_path->asrco_ck);
 108        if (ret) {
 109                dev_err(afe->dev, "failed to enable ASRC clock %d\n", ret);
 110                return ret;
 111        }
 112
 113        ret = clk_prepare_enable(i2s_path->hop_ck[dir]);
 114        if (ret) {
 115                dev_err(afe->dev, "failed to enable I2S clock %d\n", ret);
 116                goto err_hop_ck;
 117        }
 118
 119        return 0;
 120
 121err_hop_ck:
 122        clk_disable_unprepare(i2s_path->asrco_ck);
 123
 124        return ret;
 125}
 126
 127void mt2701_afe_disable_i2s(struct mtk_base_afe *afe,
 128                            struct mt2701_i2s_path *i2s_path,
 129                            int dir)
 130{
 131        clk_disable_unprepare(i2s_path->hop_ck[dir]);
 132        clk_disable_unprepare(i2s_path->asrco_ck);
 133}
 134
 135int mt2701_afe_enable_mclk(struct mtk_base_afe *afe, int id)
 136{
 137        struct mt2701_afe_private *afe_priv = afe->platform_priv;
 138        struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
 139
 140        return clk_prepare_enable(i2s_path->mclk_ck);
 141}
 142
 143void mt2701_afe_disable_mclk(struct mtk_base_afe *afe, int id)
 144{
 145        struct mt2701_afe_private *afe_priv = afe->platform_priv;
 146        struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
 147
 148        clk_disable_unprepare(i2s_path->mclk_ck);
 149}
 150
 151int mt2701_enable_btmrg_clk(struct mtk_base_afe *afe)
 152{
 153        struct mt2701_afe_private *afe_priv = afe->platform_priv;
 154
 155        return clk_prepare_enable(afe_priv->mrgif_ck);
 156}
 157
 158void mt2701_disable_btmrg_clk(struct mtk_base_afe *afe)
 159{
 160        struct mt2701_afe_private *afe_priv = afe->platform_priv;
 161
 162        clk_disable_unprepare(afe_priv->mrgif_ck);
 163}
 164
 165static int mt2701_afe_enable_audsys(struct mtk_base_afe *afe)
 166{
 167        struct mt2701_afe_private *afe_priv = afe->platform_priv;
 168        int ret;
 169
 170        /* Enable infra clock gate */
 171        ret = clk_prepare_enable(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
 172        if (ret)
 173                return ret;
 174
 175        /* Enable top a1sys clock gate */
 176        ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
 177        if (ret)
 178                goto err_a1sys;
 179
 180        /* Enable top a2sys clock gate */
 181        ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
 182        if (ret)
 183                goto err_a2sys;
 184
 185        /* Internal clock gates */
 186        ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
 187        if (ret)
 188                goto err_afe;
 189
 190        ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
 191        if (ret)
 192                goto err_audio_a1sys;
 193
 194        ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
 195        if (ret)
 196                goto err_audio_a2sys;
 197
 198        ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]);
 199        if (ret)
 200                goto err_afe_conn;
 201
 202        return 0;
 203
 204err_afe_conn:
 205        clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
 206err_audio_a2sys:
 207        clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
 208err_audio_a1sys:
 209        clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
 210err_afe:
 211        clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
 212err_a2sys:
 213        clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
 214err_a1sys:
 215        clk_disable_unprepare(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
 216
 217        return ret;
 218}
 219
 220static void mt2701_afe_disable_audsys(struct mtk_base_afe *afe)
 221{
 222        struct mt2701_afe_private *afe_priv = afe->platform_priv;
 223
 224        clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]);
 225        clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
 226        clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
 227        clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
 228        clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
 229        clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
 230        clk_disable_unprepare(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
 231}
 232
 233int mt2701_afe_enable_clock(struct mtk_base_afe *afe)
 234{
 235        int ret;
 236
 237        /* Enable audio system */
 238        ret = mt2701_afe_enable_audsys(afe);
 239        if (ret) {
 240                dev_err(afe->dev, "failed to enable audio system %d\n", ret);
 241                return ret;
 242        }
 243
 244        regmap_update_bits(afe->regmap, ASYS_TOP_CON,
 245                           ASYS_TOP_CON_ASYS_TIMING_ON,
 246                           ASYS_TOP_CON_ASYS_TIMING_ON);
 247        regmap_update_bits(afe->regmap, AFE_DAC_CON0,
 248                           AFE_DAC_CON0_AFE_ON,
 249                           AFE_DAC_CON0_AFE_ON);
 250
 251        /* Configure ASRC */
 252        regmap_write(afe->regmap, PWR1_ASM_CON1, PWR1_ASM_CON1_INIT_VAL);
 253        regmap_write(afe->regmap, PWR2_ASM_CON1, PWR2_ASM_CON1_INIT_VAL);
 254
 255        return 0;
 256}
 257
 258int mt2701_afe_disable_clock(struct mtk_base_afe *afe)
 259{
 260        regmap_update_bits(afe->regmap, ASYS_TOP_CON,
 261                           ASYS_TOP_CON_ASYS_TIMING_ON, 0);
 262        regmap_update_bits(afe->regmap, AFE_DAC_CON0,
 263                           AFE_DAC_CON0_AFE_ON, 0);
 264
 265        mt2701_afe_disable_audsys(afe);
 266
 267        return 0;
 268}
 269
 270int mt2701_mclk_configuration(struct mtk_base_afe *afe, int id)
 271
 272{
 273        struct mt2701_afe_private *priv = afe->platform_priv;
 274        struct mt2701_i2s_path *i2s_path = &priv->i2s_path[id];
 275        int ret = -EINVAL;
 276
 277        /* Set mclk source */
 278        if (!(MT2701_PLL_DOMAIN_0_RATE % i2s_path->mclk_rate))
 279                ret = clk_set_parent(i2s_path->sel_ck,
 280                                     priv->base_ck[MT2701_TOP_AUD_MCLK_SRC0]);
 281        else if (!(MT2701_PLL_DOMAIN_1_RATE % i2s_path->mclk_rate))
 282                ret = clk_set_parent(i2s_path->sel_ck,
 283                                     priv->base_ck[MT2701_TOP_AUD_MCLK_SRC1]);
 284
 285        if (ret) {
 286                dev_err(afe->dev, "failed to set mclk source\n");
 287                return ret;
 288        }
 289
 290        /* Set mclk divider */
 291        ret = clk_set_rate(i2s_path->div_ck, i2s_path->mclk_rate);
 292        if (ret) {
 293                dev_err(afe->dev, "failed to set mclk divider %d\n", ret);
 294                return ret;
 295        }
 296
 297        return 0;
 298}
 299