diff options
author | Ryder Lee <ryder.lee@mediatek.com> | 2018-01-02 12:47:19 +0100 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2018-01-03 16:15:24 +0100 |
commit | d8d99d8ed658a705909b07ba21b643c53851d70c (patch) | |
tree | a7feedb9d1793914fd3f98fe129a1a2a9402b04a /sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c | |
parent | ASoC: mediatek: fix error handling in mt2701_afe_pcm_dev_probe() (diff) | |
download | linux-d8d99d8ed658a705909b07ba21b643c53851d70c.tar.xz linux-d8d99d8ed658a705909b07ba21b643c53851d70c.zip |
ASoC: mediatek: rework clock functions for MT2701
Reworks clock part to make it more reasonable. The current changes are:
- Replace regmap operations by CCF APIs. Doing so, we just need to handle
the element clocks and can also get accurate information via CCF.
- Rename clocks to make them more generic so that the future revisions
of the IP can adapt gracefully.
- Regroup 'aud_clks[]' by usage - the basic needs and I2S parts:
The new code just keep the common clocks in array and let SoC self decide
I2S numbers - If future chips have different sets of channels we will
add a little more abstract here.
Moreover, this patch moves I2S clocks to the struct mt2701_i2s_data
so that we can easily manage them when calls .prepare() and .shutdown().
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
Tested-by: Garlic Tseng <garlic.tseng@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c')
-rw-r--r-- | sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c | 518 |
1 files changed, 166 insertions, 352 deletions
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c index affa7fb25dd9..75ccdca5811d 100644 --- a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c +++ b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c @@ -21,442 +21,256 @@ #include "mt2701-afe-common.h" #include "mt2701-afe-clock-ctrl.h" -static const char *aud_clks[MT2701_CLOCK_NUM] = { - [MT2701_AUD_INFRA_SYS_AUDIO] = "infra_sys_audio_clk", - [MT2701_AUD_AUD_MUX1_SEL] = "top_audio_mux1_sel", - [MT2701_AUD_AUD_MUX2_SEL] = "top_audio_mux2_sel", - [MT2701_AUD_AUD_MUX1_DIV] = "top_audio_mux1_div", - [MT2701_AUD_AUD_MUX2_DIV] = "top_audio_mux2_div", - [MT2701_AUD_AUD_48K_TIMING] = "top_audio_48k_timing", - [MT2701_AUD_AUD_44K_TIMING] = "top_audio_44k_timing", - [MT2701_AUD_AUDPLL_MUX_SEL] = "top_audpll_mux_sel", - [MT2701_AUD_APLL_SEL] = "top_apll_sel", - [MT2701_AUD_AUD1PLL_98M] = "top_aud1_pll_98M", - [MT2701_AUD_AUD2PLL_90M] = "top_aud2_pll_90M", - [MT2701_AUD_HADDS2PLL_98M] = "top_hadds2_pll_98M", - [MT2701_AUD_HADDS2PLL_294M] = "top_hadds2_pll_294M", - [MT2701_AUD_AUDPLL] = "top_audpll", - [MT2701_AUD_AUDPLL_D4] = "top_audpll_d4", - [MT2701_AUD_AUDPLL_D8] = "top_audpll_d8", - [MT2701_AUD_AUDPLL_D16] = "top_audpll_d16", - [MT2701_AUD_AUDPLL_D24] = "top_audpll_d24", - [MT2701_AUD_AUDINTBUS] = "top_audintbus_sel", - [MT2701_AUD_CLK_26M] = "clk_26m", - [MT2701_AUD_SYSPLL1_D4] = "top_syspll1_d4", - [MT2701_AUD_AUD_K1_SRC_SEL] = "top_aud_k1_src_sel", - [MT2701_AUD_AUD_K2_SRC_SEL] = "top_aud_k2_src_sel", - [MT2701_AUD_AUD_K3_SRC_SEL] = "top_aud_k3_src_sel", - [MT2701_AUD_AUD_K4_SRC_SEL] = "top_aud_k4_src_sel", - [MT2701_AUD_AUD_K5_SRC_SEL] = "top_aud_k5_src_sel", - [MT2701_AUD_AUD_K6_SRC_SEL] = "top_aud_k6_src_sel", - [MT2701_AUD_AUD_K1_SRC_DIV] = "top_aud_k1_src_div", - [MT2701_AUD_AUD_K2_SRC_DIV] = "top_aud_k2_src_div", - [MT2701_AUD_AUD_K3_SRC_DIV] = "top_aud_k3_src_div", - [MT2701_AUD_AUD_K4_SRC_DIV] = "top_aud_k4_src_div", - [MT2701_AUD_AUD_K5_SRC_DIV] = "top_aud_k5_src_div", - [MT2701_AUD_AUD_K6_SRC_DIV] = "top_aud_k6_src_div", - [MT2701_AUD_AUD_I2S1_MCLK] = "top_aud_i2s1_mclk", - [MT2701_AUD_AUD_I2S2_MCLK] = "top_aud_i2s2_mclk", - [MT2701_AUD_AUD_I2S3_MCLK] = "top_aud_i2s3_mclk", - [MT2701_AUD_AUD_I2S4_MCLK] = "top_aud_i2s4_mclk", - [MT2701_AUD_AUD_I2S5_MCLK] = "top_aud_i2s5_mclk", - [MT2701_AUD_AUD_I2S6_MCLK] = "top_aud_i2s6_mclk", - [MT2701_AUD_ASM_M_SEL] = "top_asm_m_sel", - [MT2701_AUD_ASM_H_SEL] = "top_asm_h_sel", - [MT2701_AUD_UNIVPLL2_D4] = "top_univpll2_d4", - [MT2701_AUD_UNIVPLL2_D2] = "top_univpll2_d2", - [MT2701_AUD_SYSPLL_D5] = "top_syspll_d5", +static const char *const base_clks[] = { + [MT2701_TOP_AUD_MCLK_SRC0] = "top_audio_mux1_sel", + [MT2701_TOP_AUD_MCLK_SRC1] = "top_audio_mux2_sel", + [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 = 0; - - for (i = 0; i < MT2701_CLOCK_NUM; i++) { - afe_priv->clocks[i] = devm_clk_get(afe->dev, aud_clks[i]); - if (IS_ERR(afe_priv->clocks[i])) { - dev_warn(afe->dev, "%s devm_clk_get %s fail\n", - __func__, aud_clks[i]); - return PTR_ERR(aud_clks[i]); + 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]); } } - return 0; -} + /* 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]; -int mt2701_afe_enable_clock(struct mtk_base_afe *afe) -{ - int ret = 0; + 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); + } - ret = mt2701_turn_on_a1sys_clock(afe); - if (ret) { - dev_err(afe->dev, "%s turn_on_a1sys_clock fail %d\n", - __func__, ret); - return ret; - } + 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); + } - ret = mt2701_turn_on_a2sys_clock(afe); - if (ret) { - dev_err(afe->dev, "%s turn_on_a2sys_clock fail %d\n", - __func__, ret); - mt2701_turn_off_a1sys_clock(afe); - return ret; - } + 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); + } - ret = mt2701_turn_on_afe_clock(afe); - if (ret) { - dev_err(afe->dev, "%s turn_on_afe_clock fail %d\n", - __func__, ret); - mt2701_turn_off_a1sys_clock(afe); - mt2701_turn_off_a2sys_clock(afe); - return ret; + 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); + } } - regmap_update_bits(afe->regmap, ASYS_TOP_CON, - AUDIO_TOP_CON0_A1SYS_A2SYS_ON, - AUDIO_TOP_CON0_A1SYS_A2SYS_ON); - regmap_update_bits(afe->regmap, AFE_DAC_CON0, - AFE_DAC_CON0_AFE_ON, - AFE_DAC_CON0_AFE_ON); - regmap_write(afe->regmap, PWR2_TOP_CON, - PWR2_TOP_CON_INIT_VAL); - regmap_write(afe->regmap, PWR1_ASM_CON1, - PWR1_ASM_CON1_INIT_VAL); - regmap_write(afe->regmap, PWR2_ASM_CON1, - PWR2_ASM_CON1_INIT_VAL); + /* 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; - return 0; -} + afe_priv->mrgif_ck = NULL; + } -void mt2701_afe_disable_clock(struct mtk_base_afe *afe) -{ - mt2701_turn_off_afe_clock(afe); - mt2701_turn_off_a1sys_clock(afe); - mt2701_turn_off_a2sys_clock(afe); - regmap_update_bits(afe->regmap, ASYS_TOP_CON, - AUDIO_TOP_CON0_A1SYS_A2SYS_ON, 0); - regmap_update_bits(afe->regmap, AFE_DAC_CON0, - AFE_DAC_CON0_AFE_ON, 0); + return 0; } -int mt2701_turn_on_a1sys_clock(struct mtk_base_afe *afe) +int mt2701_afe_enable_i2s(struct mtk_base_afe *afe, int id, int dir) { struct mt2701_afe_private *afe_priv = afe->platform_priv; - int ret = 0; + struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id]; + int ret; - /* Set Mux */ - ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]); + ret = clk_prepare_enable(i2s_path->asrco_ck); if (ret) { - dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", - __func__, aud_clks[MT2701_AUD_AUD_MUX1_SEL], ret); - goto A1SYS_CLK_AUD_MUX1_SEL_ERR; + dev_err(afe->dev, "failed to enable ASRC clock %d\n", ret); + return ret; } - ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL], - afe_priv->clocks[MT2701_AUD_AUD1PLL_98M]); + ret = clk_prepare_enable(i2s_path->hop_ck[dir]); if (ret) { - dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__, - aud_clks[MT2701_AUD_AUD_MUX1_SEL], - aud_clks[MT2701_AUD_AUD1PLL_98M], ret); - goto A1SYS_CLK_AUD_MUX1_SEL_ERR; + dev_err(afe->dev, "failed to enable I2S clock %d\n", ret); + goto err_hop_ck; } - /* Set Divider */ - ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV]); - if (ret) { - dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", - __func__, - aud_clks[MT2701_AUD_AUD_MUX1_DIV], - ret); - goto A1SYS_CLK_AUD_MUX1_DIV_ERR; - } + return 0; - ret = clk_set_rate(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV], - MT2701_AUD_AUD_MUX1_DIV_RATE); - if (ret) { - dev_err(afe->dev, "%s clk_set_parent %s-%d fail %d\n", __func__, - aud_clks[MT2701_AUD_AUD_MUX1_DIV], - MT2701_AUD_AUD_MUX1_DIV_RATE, ret); - goto A1SYS_CLK_AUD_MUX1_DIV_ERR; - } +err_hop_ck: + clk_disable_unprepare(i2s_path->asrco_ck); - /* Enable clock gate */ - ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_48K_TIMING]); - if (ret) { - dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", - __func__, aud_clks[MT2701_AUD_AUD_48K_TIMING], ret); - goto A1SYS_CLK_AUD_48K_ERR; - } + return ret; +} - /* Enable infra audio */ - ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); - if (ret) { - dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", - __func__, aud_clks[MT2701_AUD_INFRA_SYS_AUDIO], ret); - goto A1SYS_CLK_INFRA_ERR; - } +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]; - return 0; + clk_disable_unprepare(i2s_path->hop_ck[dir]); + clk_disable_unprepare(i2s_path->asrco_ck); +} -A1SYS_CLK_INFRA_ERR: - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); -A1SYS_CLK_AUD_48K_ERR: - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_48K_TIMING]); -A1SYS_CLK_AUD_MUX1_DIV_ERR: - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV]); -A1SYS_CLK_AUD_MUX1_SEL_ERR: - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]); +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 ret; + return clk_prepare_enable(i2s_path->mclk_ck); } -void mt2701_turn_off_a1sys_clock(struct mtk_base_afe *afe) +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(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_48K_TIMING]); - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV]); - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]); + clk_disable_unprepare(i2s_path->mclk_ck); } -int mt2701_turn_on_a2sys_clock(struct mtk_base_afe *afe) +int mt2701_enable_btmrg_clk(struct mtk_base_afe *afe) { struct mt2701_afe_private *afe_priv = afe->platform_priv; - int ret = 0; - /* Set Mux */ - ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]); - if (ret) { - dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", - __func__, aud_clks[MT2701_AUD_AUD_MUX2_SEL], ret); - goto A2SYS_CLK_AUD_MUX2_SEL_ERR; - } + return clk_prepare_enable(afe_priv->mrgif_ck); +} - ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL], - afe_priv->clocks[MT2701_AUD_AUD2PLL_90M]); - if (ret) { - dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__, - aud_clks[MT2701_AUD_AUD_MUX2_SEL], - aud_clks[MT2701_AUD_AUD2PLL_90M], ret); - goto A2SYS_CLK_AUD_MUX2_SEL_ERR; - } +void mt2701_disable_btmrg_clk(struct mtk_base_afe *afe) +{ + struct mt2701_afe_private *afe_priv = afe->platform_priv; - /* Set Divider */ - ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV]); - if (ret) { - dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", - __func__, aud_clks[MT2701_AUD_AUD_MUX2_DIV], ret); - goto A2SYS_CLK_AUD_MUX2_DIV_ERR; - } + clk_disable_unprepare(afe_priv->mrgif_ck); +} - ret = clk_set_rate(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV], - MT2701_AUD_AUD_MUX2_DIV_RATE); - if (ret) { - dev_err(afe->dev, "%s clk_set_parent %s-%d fail %d\n", __func__, - aud_clks[MT2701_AUD_AUD_MUX2_DIV], - MT2701_AUD_AUD_MUX2_DIV_RATE, ret); - goto A2SYS_CLK_AUD_MUX2_DIV_ERR; - } +static int mt2701_afe_enable_audsys(struct mtk_base_afe *afe) +{ + struct mt2701_afe_private *afe_priv = afe->platform_priv; + int ret; - /* Enable clock gate */ - ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_44K_TIMING]); - if (ret) { - dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", - __func__, aud_clks[MT2701_AUD_AUD_44K_TIMING], ret); - goto A2SYS_CLK_AUD_44K_ERR; - } + ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE]); + if (ret) + return ret; - /* Enable infra audio */ - ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); - if (ret) { - dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", - __func__, aud_clks[MT2701_AUD_INFRA_SYS_AUDIO], ret); - goto A2SYS_CLK_INFRA_ERR; - } + 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; -A2SYS_CLK_INFRA_ERR: - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); -A2SYS_CLK_AUD_44K_ERR: - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_44K_TIMING]); -A2SYS_CLK_AUD_MUX2_DIV_ERR: - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV]); -A2SYS_CLK_AUD_MUX2_SEL_ERR: - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]); +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]); return ret; } -void mt2701_turn_off_a2sys_clock(struct mtk_base_afe *afe) +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->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_44K_TIMING]); - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV]); - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]); + 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]); } -int mt2701_turn_on_afe_clock(struct mtk_base_afe *afe) +int mt2701_afe_enable_clock(struct mtk_base_afe *afe) { - struct mt2701_afe_private *afe_priv = afe->platform_priv; int ret; - /* enable INFRA_SYS */ - ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); - if (ret) { - dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", - __func__, aud_clks[MT2701_AUD_INFRA_SYS_AUDIO], ret); - goto AFE_AUD_INFRA_ERR; - } - - /* Set MT2701_AUD_AUDINTBUS to MT2701_AUD_SYSPLL1_D4 */ - ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUDINTBUS]); - if (ret) { - dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", - __func__, aud_clks[MT2701_AUD_AUDINTBUS], ret); - goto AFE_AUD_AUDINTBUS_ERR; - } - - ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_AUDINTBUS], - afe_priv->clocks[MT2701_AUD_SYSPLL1_D4]); - if (ret) { - dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__, - aud_clks[MT2701_AUD_AUDINTBUS], - aud_clks[MT2701_AUD_SYSPLL1_D4], ret); - goto AFE_AUD_AUDINTBUS_ERR; - } - - /* Set MT2701_AUD_ASM_H_SEL to MT2701_AUD_UNIVPLL2_D2 */ - ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_ASM_H_SEL]); - if (ret) { - dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", - __func__, aud_clks[MT2701_AUD_ASM_H_SEL], ret); - goto AFE_AUD_ASM_H_ERR; - } - - ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_ASM_H_SEL], - afe_priv->clocks[MT2701_AUD_UNIVPLL2_D2]); - if (ret) { - dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__, - aud_clks[MT2701_AUD_ASM_H_SEL], - aud_clks[MT2701_AUD_UNIVPLL2_D2], ret); - goto AFE_AUD_ASM_H_ERR; - } - - /* Set MT2701_AUD_ASM_M_SEL to MT2701_AUD_UNIVPLL2_D4 */ - ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_ASM_M_SEL]); + /* Enable audio system */ + ret = mt2701_afe_enable_audsys(afe); if (ret) { - dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", - __func__, aud_clks[MT2701_AUD_ASM_M_SEL], ret); - goto AFE_AUD_ASM_M_ERR; + dev_err(afe->dev, "failed to enable audio system %d\n", ret); + return ret; } - ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_ASM_M_SEL], - afe_priv->clocks[MT2701_AUD_UNIVPLL2_D4]); - if (ret) { - dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__, - aud_clks[MT2701_AUD_ASM_M_SEL], - aud_clks[MT2701_AUD_UNIVPLL2_D4], ret); - goto AFE_AUD_ASM_M_ERR; - } + regmap_update_bits(afe->regmap, ASYS_TOP_CON, + AUDIO_TOP_CON0_A1SYS_A2SYS_ON, + AUDIO_TOP_CON0_A1SYS_A2SYS_ON); + regmap_update_bits(afe->regmap, AFE_DAC_CON0, + AFE_DAC_CON0_AFE_ON, + AFE_DAC_CON0_AFE_ON); - regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, - AUDIO_TOP_CON0_PDN_AFE, 0); - regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, - AUDIO_TOP_CON0_PDN_APLL_CK, 0); - regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, - AUDIO_TOP_CON4_PDN_A1SYS, 0); - regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, - AUDIO_TOP_CON4_PDN_A2SYS, 0); - regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, - AUDIO_TOP_CON4_PDN_AFE_CONN, 0); + /* 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; - -AFE_AUD_ASM_M_ERR: - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_M_SEL]); -AFE_AUD_ASM_H_ERR: - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_H_SEL]); -AFE_AUD_AUDINTBUS_ERR: - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUDINTBUS]); -AFE_AUD_INFRA_ERR: - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); - - return ret; } -void mt2701_turn_off_afe_clock(struct mtk_base_afe *afe) +int mt2701_afe_disable_clock(struct mtk_base_afe *afe) { - struct mt2701_afe_private *afe_priv = afe->platform_priv; + regmap_update_bits(afe->regmap, ASYS_TOP_CON, + AUDIO_TOP_CON0_A1SYS_A2SYS_ON, 0); + regmap_update_bits(afe->regmap, AFE_DAC_CON0, + AFE_DAC_CON0_AFE_ON, 0); - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); - - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUDINTBUS]); - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_H_SEL]); - clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_M_SEL]); - - regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, - AUDIO_TOP_CON0_PDN_AFE, AUDIO_TOP_CON0_PDN_AFE); - regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, - AUDIO_TOP_CON0_PDN_APLL_CK, - AUDIO_TOP_CON0_PDN_APLL_CK); - regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, - AUDIO_TOP_CON4_PDN_A1SYS, - AUDIO_TOP_CON4_PDN_A1SYS); - regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, - AUDIO_TOP_CON4_PDN_A2SYS, - AUDIO_TOP_CON4_PDN_A2SYS); - regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, - AUDIO_TOP_CON4_PDN_AFE_CONN, - AUDIO_TOP_CON4_PDN_AFE_CONN); + mt2701_afe_disable_audsys(afe); + + return 0; } void mt2701_mclk_configuration(struct mtk_base_afe *afe, int id, int domain, int mclk) { - struct mt2701_afe_private *afe_priv = afe->platform_priv; + struct mt2701_afe_private *priv = afe->platform_priv; + struct mt2701_i2s_path *i2s_path = &priv->i2s_path[id]; int ret; - int aud_src_div_id = MT2701_AUD_AUD_K1_SRC_DIV + id; - int aud_src_clk_id = MT2701_AUD_AUD_K1_SRC_SEL + id; - /* Set MCLK Kx_SRC_SEL(domain) */ - ret = clk_prepare_enable(afe_priv->clocks[aud_src_clk_id]); - if (ret) - dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", - __func__, aud_clks[aud_src_clk_id], ret); - - if (domain == 0) { - ret = clk_set_parent(afe_priv->clocks[aud_src_clk_id], - afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]); - if (ret) - dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", - __func__, aud_clks[aud_src_clk_id], - aud_clks[MT2701_AUD_AUD_MUX1_SEL], ret); - } else { - ret = clk_set_parent(afe_priv->clocks[aud_src_clk_id], - afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]); - if (ret) - dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", - __func__, aud_clks[aud_src_clk_id], - aud_clks[MT2701_AUD_AUD_MUX2_SEL], ret); - } - clk_disable_unprepare(afe_priv->clocks[aud_src_clk_id]); + /* 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]); - /* Set MCLK Kx_SRC_DIV(divider) */ - ret = clk_prepare_enable(afe_priv->clocks[aud_src_div_id]); if (ret) - dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", - __func__, aud_clks[aud_src_div_id], ret); + dev_err(afe->dev, "failed to set domain%d mclk source %d\n", + domain, ret); - ret = clk_set_rate(afe_priv->clocks[aud_src_div_id], mclk); + /* Set mclk divider */ + ret = clk_set_rate(i2s_path->div_ck, mclk); if (ret) - dev_err(afe->dev, "%s clk_set_rate %s-%d fail %d\n", __func__, - aud_clks[aud_src_div_id], mclk, ret); - clk_disable_unprepare(afe_priv->clocks[aud_src_div_id]); + dev_err(afe->dev, "failed to set mclk divider %d\n", ret); } MODULE_DESCRIPTION("MT2701 afe clock control"); |