Release 4.17 sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
/*
* mt2701-afe-clock-ctrl.c -- Mediatek 2701 afe clock ctrl
*
* Copyright (c) 2016 MediaTek Inc.
* Author: Garlic Tseng <garlic.tseng@mediatek.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "mt2701-afe-common.h"
#include "mt2701-afe-clock-ctrl.h"
static const char *const base_clks[] = {
[MT2701_INFRA_SYS_AUDIO] = "infra_sys_audio_clk",
[MT2701_TOP_AUD_MCLK_SRC0] = "top_audio_mux1_sel",
[MT2701_TOP_AUD_MCLK_SRC1] = "top_audio_mux2_sel",
[MT2701_TOP_AUD_A1SYS] = "top_audio_a1sys_hp",
[MT2701_TOP_AUD_A2SYS] = "top_audio_a2sys_hp",
[MT2701_AUDSYS_AFE] = "audio_afe_pd",
[MT2701_AUDSYS_AFE_CONN] = "audio_afe_conn_pd",
[MT2701_AUDSYS_A1SYS] = "audio_a1sys_pd",
[MT2701_AUDSYS_A2SYS] = "audio_a2sys_pd",
};
int mt2701_init_clock(struct mtk_base_afe *afe)
{
struct mt2701_afe_private *afe_priv = afe->platform_priv;
int i;
for (i = 0; i < MT2701_BASE_CLK_NUM; i++) {
afe_priv->base_ck[i] = devm_clk_get(afe->dev, base_clks[i]);
if (IS_ERR(afe_priv->base_ck[i])) {
dev_err(afe->dev, "failed to get %s\n", base_clks[i]);
return PTR_ERR(afe_priv->base_ck[i]);
}
}
/* Get I2S related clocks */
for (i = 0; i < MT2701_I2S_NUM; i++) {
struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i];
char name[13];
snprintf(name, sizeof(name), "i2s%d_src_sel", i);
i2s_path->sel_ck = devm_clk_get(afe->dev, name);
if (IS_ERR(i2s_path->sel_ck)) {
dev_err(afe->dev, "failed to get %s\n", name);
return PTR_ERR(i2s_path->sel_ck);
}
snprintf(name, sizeof(name), "i2s%d_src_div", i);
i2s_path->div_ck = devm_clk_get(afe->dev, name);
if (IS_ERR(i2s_path->div_ck)) {
dev_err(afe->dev, "failed to get %s\n", name);
return PTR_ERR(i2s_path->div_ck);
}
snprintf(name, sizeof(name), "i2s%d_mclk_en", i);
i2s_path->mclk_ck = devm_clk_get(afe->dev, name);
if (IS_ERR(i2s_path->mclk_ck)) {
dev_err(afe->dev, "failed to get %s\n", name);
return PTR_ERR(i2s_path->mclk_ck);
}
snprintf(name, sizeof(name), "i2so%d_hop_ck", i);
i2s_path->hop_ck[I2S_OUT] = devm_clk_get(afe->dev, name);
if (IS_ERR(i2s_path->hop_ck[I2S_OUT])) {
dev_err(afe->dev, "failed to get %s\n", name);
return PTR_ERR(i2s_path->hop_ck[I2S_OUT]);
}
snprintf(name, sizeof(name), "i2si%d_hop_ck", i);
i2s_path->hop_ck[I2S_IN] = devm_clk_get(afe->dev, name);
if (IS_ERR(i2s_path->hop_ck[I2S_IN])) {
dev_err(afe->dev, "failed to get %s\n", name);
return PTR_ERR(i2s_path->hop_ck[I2S_IN]);
}
snprintf(name, sizeof(name), "asrc%d_out_ck", i);
i2s_path->asrco_ck = devm_clk_get(afe->dev, name);
if (IS_ERR(i2s_path->asrco_ck)) {
dev_err(afe->dev, "failed to get %s\n", name);
return PTR_ERR(i2s_path->asrco_ck);
}
}
/* Some platforms may support BT path */
afe_priv->mrgif_ck = devm_clk_get(afe->dev, "audio_mrgif_pd");
if (IS_ERR(afe_priv->mrgif_ck)) {
if (PTR_ERR(afe_priv->mrgif_ck) == -EPROBE_DEFER)
return -EPROBE_DEFER;
afe_priv->mrgif_ck = NULL;
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Ryder Lee | 327 | 60.56% | 1 | 33.33% |
Garlic Tseng | 211 | 39.07% | 1 | 33.33% |
Christophe Jaillet | 2 | 0.37% | 1 | 33.33% |
Total | 540 | 100.00% | 3 | 100.00% |
int mt2701_afe_enable_i2s(struct mtk_base_afe *afe, int id, int dir)
{
struct mt2701_afe_private *afe_priv = afe->platform_priv;
struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
int ret;
ret = clk_prepare_enable(i2s_path->asrco_ck);
if (ret) {
dev_err(afe->dev, "failed to enable ASRC clock %d\n", ret);
return ret;
}
ret = clk_prepare_enable(i2s_path->hop_ck[dir]);
if (ret) {
dev_err(afe->dev, "failed to enable I2S clock %d\n", ret);
goto err_hop_ck;
}
return 0;
err_hop_ck:
clk_disable_unprepare(i2s_path->asrco_ck);
return ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Garlic Tseng | 75 | 64.10% | 1 | 50.00% |
Ryder Lee | 42 | 35.90% | 1 | 50.00% |
Total | 117 | 100.00% | 2 | 100.00% |
void mt2701_afe_disable_i2s(struct mtk_base_afe *afe, int id, int dir)
{
struct mt2701_afe_private *afe_priv = afe->platform_priv;
struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
clk_disable_unprepare(i2s_path->hop_ck[dir]);
clk_disable_unprepare(i2s_path->asrco_ck);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Ryder Lee | 37 | 67.27% | 1 | 50.00% |
Garlic Tseng | 18 | 32.73% | 1 | 50.00% |
Total | 55 | 100.00% | 2 | 100.00% |
int mt2701_afe_enable_mclk(struct mtk_base_afe *afe, int id)
{
struct mt2701_afe_private *afe_priv = afe->platform_priv;
struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
return clk_prepare_enable(i2s_path->mclk_ck);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Ryder Lee | 32 | 74.42% | 1 | 50.00% |
Garlic Tseng | 11 | 25.58% | 1 | 50.00% |
Total | 43 | 100.00% | 2 | 100.00% |
void mt2701_afe_disable_mclk(struct mtk_base_afe *afe, int id)
{
struct mt2701_afe_private *afe_priv = afe->platform_priv;
struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id];
clk_disable_unprepare(i2s_path->mclk_ck);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Garlic Tseng | 26 | 61.90% | 1 | 50.00% |
Ryder Lee | 16 | 38.10% | 1 | 50.00% |
Total | 42 | 100.00% | 2 | 100.00% |
int mt2701_enable_btmrg_clk(struct mtk_base_afe *afe)
{
struct mt2701_afe_private *afe_priv = afe->platform_priv;
return clk_prepare_enable(afe_priv->mrgif_ck);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Ryder Lee | 20 | 74.07% | 1 | 50.00% |
Garlic Tseng | 7 | 25.93% | 1 | 50.00% |
Total | 27 | 100.00% | 2 | 100.00% |
void mt2701_disable_btmrg_clk(struct mtk_base_afe *afe)
{
struct mt2701_afe_private *afe_priv = afe->platform_priv;
clk_disable_unprepare(afe_priv->mrgif_ck);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Garlic Tseng | 22 | 84.62% | 1 | 50.00% |
Ryder Lee | 4 | 15.38% | 1 | 50.00% |
Total | 26 | 100.00% | 2 | 100.00% |
static int mt2701_afe_enable_audsys(struct mtk_base_afe *afe)
{
struct mt2701_afe_private *afe_priv = afe->platform_priv;
int ret;
/* Enable infra clock gate */
ret = clk_prepare_enable(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
if (ret)
return ret;
/* Enable top a1sys clock gate */
ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
if (ret)
goto err_a1sys;
/* Enable top a2sys clock gate */
ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
if (ret)
goto err_a2sys;
/* Internal clock gates */
ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
if (ret)
goto err_afe;
ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
if (ret)
goto err_audio_a1sys;
ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
if (ret)
goto err_audio_a2sys;
ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]);
if (ret)
goto err_afe_conn;
return 0;
err_afe_conn:
clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
err_audio_a2sys:
clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
err_audio_a1sys:
clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
err_afe:
clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
err_a2sys:
clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
err_a1sys:
clk_disable_unprepare(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
return ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Ryder Lee | 160 | 67.23% | 2 | 66.67% |
Garlic Tseng | 78 | 32.77% | 1 | 33.33% |
Total | 238 | 100.00% | 3 | 100.00% |
static void mt2701_afe_disable_audsys(struct mtk_base_afe *afe)
{
struct mt2701_afe_private *afe_priv = afe->platform_priv;
clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]);
clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]);
clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]);
clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]);
clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]);
clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]);
clk_disable_unprepare(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Garlic Tseng | 49 | 54.44% | 1 | 33.33% |
Ryder Lee | 41 | 45.56% | 2 | 66.67% |
Total | 90 | 100.00% | 3 | 100.00% |
int mt2701_afe_enable_clock(struct mtk_base_afe *afe)
{
int ret;
/* Enable audio system */
ret = mt2701_afe_enable_audsys(afe);
if (ret) {
dev_err(afe->dev, "failed to enable audio system %d\n", ret);
return ret;
}
regmap_update_bits(afe->regmap, ASYS_TOP_CON,
ASYS_TOP_CON_ASYS_TIMING_ON,
ASYS_TOP_CON_ASYS_TIMING_ON);
regmap_update_bits(afe->regmap, AFE_DAC_CON0,
AFE_DAC_CON0_AFE_ON,
AFE_DAC_CON0_AFE_ON);
/* Configure ASRC */
regmap_write(afe->regmap, PWR1_ASM_CON1, PWR1_ASM_CON1_INIT_VAL);
regmap_write(afe->regmap, PWR2_ASM_CON1, PWR2_ASM_CON1_INIT_VAL);
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Ryder Lee | 64 | 68.82% | 2 | 66.67% |
Garlic Tseng | 29 | 31.18% | 1 | 33.33% |
Total | 93 | 100.00% | 3 | 100.00% |
int mt2701_afe_disable_clock(struct mtk_base_afe *afe)
{
regmap_update_bits(afe->regmap, ASYS_TOP_CON,
ASYS_TOP_CON_ASYS_TIMING_ON, 0);
regmap_update_bits(afe->regmap, AFE_DAC_CON0,
AFE_DAC_CON0_AFE_ON, 0);
mt2701_afe_disable_audsys(afe);
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Ryder Lee | 23 | 52.27% | 2 | 66.67% |
Garlic Tseng | 21 | 47.73% | 1 | 33.33% |
Total | 44 | 100.00% | 3 | 100.00% |
void mt2701_mclk_configuration(struct mtk_base_afe *afe, int id, int domain,
int mclk)
{
struct mt2701_afe_private *priv = afe->platform_priv;
struct mt2701_i2s_path *i2s_path = &priv->i2s_path[id];
int ret;
/* Set mclk source */
if (domain == 0)
ret = clk_set_parent(i2s_path->sel_ck,
priv->base_ck[MT2701_TOP_AUD_MCLK_SRC0]);
else
ret = clk_set_parent(i2s_path->sel_ck,
priv->base_ck[MT2701_TOP_AUD_MCLK_SRC1]);
if (ret)
dev_err(afe->dev, "failed to set domain%d mclk source %d\n",
domain, ret);
/* Set mclk divider */
ret = clk_set_rate(i2s_path->div_ck, mclk);
if (ret)
dev_err(afe->dev, "failed to set mclk divider %d\n", ret);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Garlic Tseng | 99 | 77.34% | 1 | 50.00% |
Ryder Lee | 29 | 22.66% | 1 | 50.00% |
Total | 128 | 100.00% | 2 | 100.00% |
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Ryder Lee | 826 | 54.56% | 3 | 60.00% |
Garlic Tseng | 686 | 45.31% | 1 | 20.00% |
Christophe Jaillet | 2 | 0.13% | 1 | 20.00% |
Total | 1514 | 100.00% | 5 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.