mediatek: rework audio subsystem driver
Subsystems (6)
cover mediatek: rework audio subsystem driver
Hi all,
This patch series mainly adds a common driver [5][6] for the top block of the MediaTek audio subsystem, which includes clock part and audio components. This is a minimal driver that manages shared resources like shared registers, and expose a regmap to its sub-nodes. It was tested on the bananapi-r2 and the MT2701 EVB.
Also, this driver can be reused by other subsystems (e.g. MMSYS, ETHSYS) in future patch.
Patch[1]-[4]: rework for audio enable/disable sequences and update some part of
code to make them more generic.
Patch[7]~[12]: modify both drivers, audio and clock to adapt the new subsystem.
Ryder Lee (12):
ASoC: mediatek: fix error handling in mt2701_afe_pcm_dev_probe()
ASoC: mediatek: rework clock functions for MT2701
ASoC: mediatek: cleanup audio driver for MT2701
ASoC: mediatek: update clock related properties of MT2701 AFE
mfd: mtk-audsys: add MediaTek audio subsystem driver
mfd: add DT bindings for MedaiTek audio subsystem
ASoC: mediatek: modify MT2701 AFE driver to adapt subsystem wrapper
ASoC: mediatek: modify documentation to adapt subsystem wrapper
clk: mediatek: move part of mtk_clk_register_gates() to the new
function
clk: mediatek: switch to use dev_get_regmap() for MT7622 audsys
clk: mediatek: add audsys support for MT2701
dt-bindings: clock: mediatek: update audsys bindings to adapt the
wrapper
.../bindings/arm/mediatek/mediatek,audsys.txt | 19 +- .../devicetree/bindings/mfd/mtk-audsys.txt | 109 +++++ .../devicetree/bindings/sound/mt2701-afe-pcm.txt | 257 +++++----- drivers/clk/mediatek/Kconfig | 6 + drivers/clk/mediatek/Makefile | 1 + drivers/clk/mediatek/clk-mt2701-aud.c | 180 +++++++ drivers/clk/mediatek/clk-mt7622-aud.c | 11 +- drivers/clk/mediatek/clk-mtk.c | 26 +- drivers/clk/mediatek/clk-mtk.h | 4 + drivers/mfd/Kconfig | 9 + drivers/mfd/Makefile | 2 + drivers/mfd/mtk-audsys.c | 138 ++++++ include/dt-bindings/clock/mt7622-clk.h | 3 +- sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c | 526 +++++++-------------- sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h | 15 +- sound/soc/mediatek/mt2701/mt2701-afe-common.h | 84 +--- sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 212 +++------ sound/soc/mediatek/mt2701/mt2701-reg.h | 42 +- 18 files changed, 860 insertions(+), 784 deletions(-) create mode 100644 Documentation/devicetree/bindings/mfd/mtk-audsys.txt create mode 100644 drivers/clk/mediatek/clk-mt2701-aud.c create mode 100644 drivers/mfd/mtk-audsys.c
Signature · 6 lines
1.9.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 1/12 ASoC: mediatek: fix error handling in mt2701_afe_pcm_dev_probe()
Fix unbalanced error handling path which will get incorrect counts if probe failed. The .remove() should be adjusted accordingly.
--- sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 31 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 17 deletions(-)
sound/soc/mediatek/mt2701/mt2701-afe-pcm.c +14 -17
@@ -1590,12 +1590,16 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) }platform_set_drvdata (pdev, afe); -pm_runtime_enable (&pdev->dev); -if (!pm_runtime_enabled (&pdev->dev)) - goto err_pm_disable; -pm_runtime_get_sync (&pdev->dev); - ret =snd_soc_register_platform (&pdev->dev, &mtk_afe_pcm_platform); +pm_runtime_enable (dev); +if (!pm_runtime_enabled (dev)) { + ret =mt2701_afe_runtime_resume (dev); +if (ret) + goto err_pm_disable; + } +pm_runtime_get_sync (dev); + + ret =snd_soc_register_platform (dev, &mtk_afe_pcm_platform);if (ret) {dev_warn (dev,"err_platform\n" ); goto err_platform;
@@ -1610,35 +1614,28 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) goto err_dai_component; } -mt2701_afe_runtime_resume (&pdev->dev); -return 0 ; err_dai_component: -snd_soc_unregister_component (&pdev->dev); - +snd_soc_unregister_platform (dev); err_platform: -snd_soc_unregister_platform (&pdev->dev); - +pm_runtime_put_sync (dev); err_pm_disable: -pm_runtime_disable (&pdev->dev); +pm_runtime_disable (dev);return ret; }static int mt2701_afe_pcm_dev_remove (struct platform_device *pdev) { -struct mtk_base_afe *afe =platform_get_drvdata (pdev); - +pm_runtime_put_sync (&pdev->dev);pm_runtime_disable (&pdev->dev);if (!pm_runtime_status_suspended (&pdev->dev))mt2701_afe_runtime_suspend (&pdev->dev); -pm_runtime_put_sync (&pdev->dev);snd_soc_unregister_component (&pdev->dev);snd_soc_unregister_platform (&pdev->dev); -/* disable afe clock */ -mt2701_afe_disable_clock (afe); +return 0 ; }
Signature · 6 lines
1.9.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Mark Brown
maintainerApplied "ASoC: mediatek: fix error handling in mt2701_afe_pcm_dev_probe()" to the asoc tree
The patch
ASoC: mediatek: fix error handling in mt2701_afe_pcm_dev_probe()
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks,
Mark
Quoted 1 line
From
dd6bb9b16f23f9b95b77713c45bd6182336c5b2eMon Sep 17 00:00:00 2001
From: Ryder Lee <[email protected]>
Date: Tue, 2 Jan 2018 19:47:18 +0800
Subject: [PATCH] ASoC: mediatek: fix error handling in
mt2701_afe_pcm_dev_probe()
Fix unbalanced error handling path which will get incorrect counts if probe failed. The .remove() should be adjusted accordingly.
--- sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 31 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 17 deletions(-)
sound/soc/mediatek/mt2701/mt2701-afe-pcm.c +14 -17
@@ -1590,12 +1590,16 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) }platform_set_drvdata (pdev, afe); -pm_runtime_enable (&pdev->dev); -if (!pm_runtime_enabled (&pdev->dev)) - goto err_pm_disable; -pm_runtime_get_sync (&pdev->dev); - ret =snd_soc_register_platform (&pdev->dev, &mtk_afe_pcm_platform); +pm_runtime_enable (dev); +if (!pm_runtime_enabled (dev)) { + ret =mt2701_afe_runtime_resume (dev); +if (ret) + goto err_pm_disable; + } +pm_runtime_get_sync (dev); + + ret =snd_soc_register_platform (dev, &mtk_afe_pcm_platform);if (ret) {dev_warn (dev,"err_platform\n" ); goto err_platform;
@@ -1610,35 +1614,28 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) goto err_dai_component; } -mt2701_afe_runtime_resume (&pdev->dev); -return 0 ; err_dai_component: -snd_soc_unregister_component (&pdev->dev); - +snd_soc_unregister_platform (dev); err_platform: -snd_soc_unregister_platform (&pdev->dev); - +pm_runtime_put_sync (dev); err_pm_disable: -pm_runtime_disable (&pdev->dev); +pm_runtime_disable (dev);return ret; }static int mt2701_afe_pcm_dev_remove (struct platform_device *pdev) { -struct mtk_base_afe *afe =platform_get_drvdata (pdev); - +pm_runtime_put_sync (&pdev->dev);pm_runtime_disable (&pdev->dev);if (!pm_runtime_status_suspended (&pdev->dev))mt2701_afe_runtime_suspend (&pdev->dev); -pm_runtime_put_sync (&pdev->dev);snd_soc_unregister_component (&pdev->dev);snd_soc_unregister_platform (&pdev->dev); -/* disable afe clock */ -mt2701_afe_disable_clock (afe); +return 0 ; }
Signature · 1 line
2.15.1
PATCH 2/12 ASoC: mediatek: rework clock functions for MT2701
In reply to Ryder LeeReworks 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().
--- sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c | 518 +++++++--------------- sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h | 15 +- sound/soc/mediatek/mt2701/mt2701-afe-common.h | 64 +-- sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 45 +- 4 files changed, 200 insertions(+), 442 deletions(-)
sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c +166 -352
@@ -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" );
sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h +7 -8
@@ -21,16 +21,15 @@int mt2701_init_clock (struct mtk_base_afe *afe);int mt2701_afe_enable_clock (struct mtk_base_afe *afe); -void mt2701_afe_disable_clock (struct mtk_base_afe *afe); +int mt2701_afe_disable_clock (struct mtk_base_afe *afe); -int mt2701_turn_on_a1sys_clock (struct mtk_base_afe *afe); -void mt2701_turn_off_a1sys_clock (struct mtk_base_afe *afe); +int mt2701_afe_enable_i2s (struct mtk_base_afe *afe,int id,int dir); +void mt2701_afe_disable_i2s (struct mtk_base_afe *afe,int id,int dir); +int mt2701_afe_enable_mclk (struct mtk_base_afe *afe,int id); +void mt2701_afe_disable_mclk (struct mtk_base_afe *afe,int id); -int mt2701_turn_on_a2sys_clock (struct mtk_base_afe *afe); -void mt2701_turn_off_a2sys_clock (struct mtk_base_afe *afe); - -int mt2701_turn_on_afe_clock (struct mtk_base_afe *afe); -void mt2701_turn_off_afe_clock (struct mtk_base_afe *afe); +int mt2701_enable_btmrg_clk (struct mtk_base_afe *afe); +void mt2701_disable_btmrg_clk (struct mtk_base_afe *afe);void mt2701_mclk_configuration (struct mtk_base_afe *afe,int id,int domain,int mclk);
sound/soc/mediatek/mt2701/mt2701-afe-common.h +15 -49
86 lines not on this page · raw message
sound/soc/mediatek/mt2701/mt2701-afe-pcm.c +12 -33
147 lines not on this page · raw message
Signature · 1 line
1.9.1
Mark Brown
maintainerApplied "ASoC: mediatek: rework clock functions for MT2701" to the asoc tree
The patch
ASoC: mediatek: rework clock functions for MT2701
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks,
Mark
Quoted 1 line
From
d8d99d8ed658a705909b07ba21b643c53851d70cMon Sep 17 00:00:00 2001
From: Ryder Lee <[email protected]>
Date: Tue, 2 Jan 2018 19:47:19 +0800
Subject: [PATCH] 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().
--- sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c | 518 +++++++--------------- sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h | 15 +- sound/soc/mediatek/mt2701/mt2701-afe-common.h | 64 +-- sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 45 +- 4 files changed, 200 insertions(+), 442 deletions(-)
sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c +166 -352
@@ -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" );
sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h +7 -8
@@ -21,16 +21,15 @@ struct mtk_base_afe;int mt2701_init_clock (struct mtk_base_afe *afe);int mt2701_afe_enable_clock (struct mtk_base_afe *afe); -void mt2701_afe_disable_clock (struct mtk_base_afe *afe); +int mt2701_afe_disable_clock (struct mtk_base_afe *afe); -int mt2701_turn_on_a1sys_clock (struct mtk_base_afe *afe); -void mt2701_turn_off_a1sys_clock (struct mtk_base_afe *afe); +int mt2701_afe_enable_i2s (struct mtk_base_afe *afe,int id,int dir); +void mt2701_afe_disable_i2s (struct mtk_base_afe *afe,int id,int dir); +int mt2701_afe_enable_mclk (struct mtk_base_afe *afe,int id); +void mt2701_afe_disable_mclk (struct mtk_base_afe *afe,int id); -int mt2701_turn_on_a2sys_clock (struct mtk_base_afe *afe); -void mt2701_turn_off_a2sys_clock (struct mtk_base_afe *afe); - -int mt2701_turn_on_afe_clock (struct mtk_base_afe *afe); -void mt2701_turn_off_afe_clock (struct mtk_base_afe *afe); +int mt2701_enable_btmrg_clk (struct mtk_base_afe *afe); +void mt2701_disable_btmrg_clk (struct mtk_base_afe *afe);void mt2701_mclk_configuration (struct mtk_base_afe *afe,int id,int domain,int mclk);
sound/soc/mediatek/mt2701/mt2701-afe-common.h +15 -49
86 lines not on this page · raw message
sound/soc/mediatek/mt2701/mt2701-afe-pcm.c +12 -33
147 lines not on this page · raw message
Signature · 1 line
2.15.1
PATCH 3/12 ASoC: mediatek: cleanup audio driver for MT2701
In reply to Ryder LeeCleanup unused code such as 'i2s_num' guard, headers, indentation and some defines.
--- sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c | 14 +--- sound/soc/mediatek/mt2701/mt2701-afe-common.h | 20 +---- sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 94 ++++------------------- sound/soc/mediatek/mt2701/mt2701-reg.h | 41 +--------- 4 files changed, 24 insertions(+), 145 deletions(-)
sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c +3 -11
@@ -14,10 +14,6 @@* GNU General Public License for more details. */ -#include <sound/soc.h> -#include <linux/regmap.h> -#include <linux/pm_runtime.h> -#include "mt2701-afe-common.h" #include "mt2701-afe-clock-ctrl.h"
@@ -223,8 +219,8 @@ int mt2701_afe_enable_clock(struct mtk_base_afe *afe) }regmap_update_bits (afe->regmap,ASYS_TOP_CON , -AUDIO_TOP_CON0_A1SYS_A2SYS_ON , -AUDIO_TOP_CON0_A1SYS_A2SYS_ON ); +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 );
@@ -239,7 +235,7 @@ int mt2701_afe_enable_clock(struct mtk_base_afe *afe)int mt2701_afe_disable_clock (struct mtk_base_afe *afe) {regmap_update_bits (afe->regmap,ASYS_TOP_CON , -AUDIO_TOP_CON0_A1SYS_A2SYS_ON ,0 ); +ASYS_TOP_CON_ASYS_TIMING_ON ,0 );regmap_update_bits (afe->regmap,AFE_DAC_CON0 ,AFE_DAC_CON0_AFE_ON ,0 );
@@ -272,7 +268,3 @@ void mt2701_mclk_configuration(struct mtk_base_afe *afe, int id, int domain,if (ret)dev_err (afe->dev,"failed to set mclk divider %d\n" , ret); } - -MODULE_DESCRIPTION ("MT2701 afe clock control" ); -MODULE_AUTHOR ("Garlic Tseng <[email protected]>" ); -MODULE_LICENSE ("GPL v2" );
sound/soc/mediatek/mt2701/mt2701-afe-common.h +4 -16
@@ -16,6 +16,7 @@#ifndef _MT_2701_AFE_COMMON_H_#define _MT_2701_AFE_COMMON_H_ +#include <sound/soc.h> #include <linux/clk.h> #include <linux/regmap.h>
@@ -25,16 +26,7 @@#define MT2701_STREAM_DIR_NUM (SNDRV_PCM_STREAM_LAST + 1)#define MT2701_PLL_DOMAIN_0_RATE 98304000#define MT2701_PLL_DOMAIN_1_RATE 90316800 -#define MT2701_AUD_AUD_MUX1_DIV_RATE (MT2701_PLL_DOMAIN_0_RATE / 2) -#define MT2701_AUD_AUD_MUX2_DIV_RATE (MT2701_PLL_DOMAIN_1_RATE / 2) - -enum { -MT2701_I2S_1 , -MT2701_I2S_2 , -MT2701_I2S_3 , -MT2701_I2S_4 , -MT2701_I2S_NUM , -}; +#define MT2701_I2S_NUM 4enum {MT2701_MEMIF_DL1 ,
@@ -62,8 +54,7 @@ enum { };enum { -MT2701_IRQ_ASYS_START , -MT2701_IRQ_ASYS_IRQ1 =MT2701_IRQ_ASYS_START , +MT2701_IRQ_ASYS_IRQ1 ,MT2701_IRQ_ASYS_IRQ2 ,MT2701_IRQ_ASYS_IRQ3 ,MT2701_IRQ_ASYS_END ,
@@ -100,9 +91,6 @@ enum audio_base_clock { AFE_MEMIF_PBUF_SIZE, }; -struct snd_pcm_substream ; -struct mtk_base_irq_data ; -struct mt2701_i2s_data {int i2s_ctrl_reg;int i2s_asrc_fs_shift;
@@ -120,7 +108,7 @@ struct mt2701_i2s_path {int mclk_rate;int on[I2S_DIR_NUM ];int occupied[I2S_DIR_NUM ]; -const struct mt2701_i2s_data *i2s_data[2 ]; +const struct mt2701_i2s_data *i2s_data[I2S_DIR_NUM ];struct clk *hop_ck[I2S_DIR_NUM ];struct clk *sel_ck;struct clk *div_ck;
sound/soc/mediatek/mt2701/mt2701-afe-pcm.c +15 -79
230 lines not on this page · raw message
sound/soc/mediatek/mt2701/mt2701-reg.h +2 -39
59 lines not on this page · raw message
Signature · 1 line
1.9.1
Mark Brown
maintainerApplied "ASoC: mediatek: cleanup audio driver for MT2701" to the asoc tree
The patch
ASoC: mediatek: cleanup audio driver for MT2701
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks,
Mark
Quoted 1 line
From
600b2fd4f0f7ae5ebcb604c39c9a97e573f9d23eMon Sep 17 00:00:00 2001
From: Ryder Lee <ryder.lee-NuS5LvNUpcJWk0Htik3J/[email protected]>
Date: Tue, 2 Jan 2018 19:47:20 +0800
Subject: [PATCH] ASoC: mediatek: cleanup audio driver for MT2701
Cleanup unused code such as 'i2s_num' guard, headers, indentation and some defines.
--- sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c | 14 +--- sound/soc/mediatek/mt2701/mt2701-afe-common.h | 20 +---- sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 94 ++++------------------- sound/soc/mediatek/mt2701/mt2701-reg.h | 41 +--------- 4 files changed, 24 insertions(+), 145 deletions(-)
sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c +3 -11
@@ -14,10 +14,6 @@* GNU General Public License for more details. */ -#include <sound/soc.h> -#include <linux/regmap.h> -#include <linux/pm_runtime.h> -#include "mt2701-afe-common.h" #include "mt2701-afe-clock-ctrl.h"
@@ -223,8 +219,8 @@ int mt2701_afe_enable_clock(struct mtk_base_afe *afe) }regmap_update_bits (afe->regmap,ASYS_TOP_CON , -AUDIO_TOP_CON0_A1SYS_A2SYS_ON , -AUDIO_TOP_CON0_A1SYS_A2SYS_ON ); +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 );
@@ -239,7 +235,7 @@ int mt2701_afe_enable_clock(struct mtk_base_afe *afe)int mt2701_afe_disable_clock (struct mtk_base_afe *afe) {regmap_update_bits (afe->regmap,ASYS_TOP_CON , -AUDIO_TOP_CON0_A1SYS_A2SYS_ON ,0 ); +ASYS_TOP_CON_ASYS_TIMING_ON ,0 );regmap_update_bits (afe->regmap,AFE_DAC_CON0 ,AFE_DAC_CON0_AFE_ON ,0 );
@@ -272,7 +268,3 @@ void mt2701_mclk_configuration(struct mtk_base_afe *afe, int id, int domain,if (ret)dev_err (afe->dev,"failed to set mclk divider %d\n" , ret); } - -MODULE_DESCRIPTION ("MT2701 afe clock control" ); -MODULE_AUTHOR ("Garlic Tseng <garlic.tseng-NuS5LvNUpcJWk0Htik3J/[email protected]>" ); -MODULE_LICENSE ("GPL v2" );
sound/soc/mediatek/mt2701/mt2701-afe-common.h +4 -16
@@ -16,6 +16,7 @@#ifndef _MT_2701_AFE_COMMON_H_#define _MT_2701_AFE_COMMON_H_ +#include <sound/soc.h> #include <linux/clk.h> #include <linux/regmap.h>
@@ -25,16 +26,7 @@#define MT2701_STREAM_DIR_NUM (SNDRV_PCM_STREAM_LAST + 1)#define MT2701_PLL_DOMAIN_0_RATE 98304000#define MT2701_PLL_DOMAIN_1_RATE 90316800 -#define MT2701_AUD_AUD_MUX1_DIV_RATE (MT2701_PLL_DOMAIN_0_RATE / 2) -#define MT2701_AUD_AUD_MUX2_DIV_RATE (MT2701_PLL_DOMAIN_1_RATE / 2) - -enum { -MT2701_I2S_1 , -MT2701_I2S_2 , -MT2701_I2S_3 , -MT2701_I2S_4 , -MT2701_I2S_NUM , -}; +#define MT2701_I2S_NUM 4enum {MT2701_MEMIF_DL1 ,
@@ -62,8 +54,7 @@ enum { };enum { -MT2701_IRQ_ASYS_START , -MT2701_IRQ_ASYS_IRQ1 =MT2701_IRQ_ASYS_START , +MT2701_IRQ_ASYS_IRQ1 ,MT2701_IRQ_ASYS_IRQ2 ,MT2701_IRQ_ASYS_IRQ3 ,MT2701_IRQ_ASYS_END ,
@@ -100,9 +91,6 @@ static const unsigned int mt2701_afe_backup_list[] = { AFE_MEMIF_PBUF_SIZE, }; -struct snd_pcm_substream ; -struct mtk_base_irq_data ; -struct mt2701_i2s_data {int i2s_ctrl_reg;int i2s_asrc_fs_shift;
@@ -120,7 +108,7 @@ struct mt2701_i2s_path {int mclk_rate;int on[I2S_DIR_NUM ];int occupied[I2S_DIR_NUM ]; -const struct mt2701_i2s_data *i2s_data[2 ]; +const struct mt2701_i2s_data *i2s_data[I2S_DIR_NUM ];struct clk *hop_ck[I2S_DIR_NUM ];struct clk *sel_ck;struct clk *div_ck;
sound/soc/mediatek/mt2701/mt2701-afe-pcm.c +15 -79
230 lines not on this page · raw message
sound/soc/mediatek/mt2701/mt2701-reg.h +2 -39
59 lines not on this page · raw message
Signature · 6 lines
2.15.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 4/12 ASoC: mediatek: update clock related properties of MT2701 AFE
In reply to Ryder LeeAdd 'assigned-clocks*' properties which are used to initialize default domain sources of audio system. we could configure different sets of input clocks through DTS now. Hence driver no longer cares about that.
Also we change some 'clock-names' to make them more generic so that other chips can reuse gracefully.
--- .../devicetree/bindings/sound/mt2701-afe-pcm.txt | 207 +++++++++------------ 1 file changed, 91 insertions(+), 116 deletions(-)
Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt +91 -116
@@ -6,51 +6,44 @@ Required properties: - interrupts: should contain AFE and ASYS interrupts - interrupt-names: should be "afe" and "asys" - power-domains: should define the power domain +- clocks: Must contain an entry for each entry in clock-names + See ../clocks/clock-bindings.txt for details - clock-names: should have these clock names: - "infra_sys_audio_clk", "top_audio_mux1_sel", "top_audio_mux2_sel", - "top_audio_mux1_div", - "top_audio_mux2_div", - "top_audio_48k_timing", - "top_audio_44k_timing", - "top_audpll_mux_sel", - "top_apll_sel", - "top_aud1_pll_98M", - "top_aud2_pll_90M", - "top_hadds2_pll_98M", - "top_hadds2_pll_294M", - "top_audpll", - "top_audpll_d4", - "top_audpll_d8", - "top_audpll_d16", - "top_audpll_d24", - "top_audintbus_sel", - "clk_26m", - "top_syspll1_d4", - "top_aud_k1_src_sel", - "top_aud_k2_src_sel", - "top_aud_k3_src_sel", - "top_aud_k4_src_sel", - "top_aud_k5_src_sel", - "top_aud_k6_src_sel", - "top_aud_k1_src_div", - "top_aud_k2_src_div", - "top_aud_k3_src_div", - "top_aud_k4_src_div", - "top_aud_k5_src_div", - "top_aud_k6_src_div", - "top_aud_i2s1_mclk", - "top_aud_i2s2_mclk", - "top_aud_i2s3_mclk", - "top_aud_i2s4_mclk", - "top_aud_i2s5_mclk", - "top_aud_i2s6_mclk", - "top_asm_m_sel", - "top_asm_h_sel", - "top_univpll2_d4", - "top_univpll2_d2", - "top_syspll_d5"; + "i2s0_src_sel", + "i2s1_src_sel", + "i2s2_src_sel", + "i2s3_src_sel", + "i2s0_src_div", + "i2s1_src_div", + "i2s2_src_div", + "i2s3_src_div", + "i2s0_mclk_en", + "i2s1_mclk_en", + "i2s2_mclk_en", + "i2s3_mclk_en", + "i2so0_hop_ck", + "i2so1_hop_ck", + "i2so2_hop_ck", + "i2so3_hop_ck", + "i2si0_hop_ck", + "i2si1_hop_ck", + "i2si2_hop_ck", + "i2si3_hop_ck", + "asrc0_out_ck", + "asrc1_out_ck", + "asrc2_out_ck", + "asrc3_out_ck", + "audio_afe_pd", + "audio_afe_conn_pd", + "audio_a1sys_pd", + "audio_a2sys_pd", + "audio_mrgif_pd"; +- assigned-clocks: list of input clocks and dividers for the audio system. + See ../clocks/clock-bindings.txt for details. +- assigned-clocks-parents: parent of input clocks of assigned clocks. +- assigned-clock-rates: list of clock frequencies of assigned clocks. Example:
@@ -62,93 +55,75 @@ Example: <GIC_SPI 132 IRQ_TYPE_LEVEL_LOW>; interrupt-names = "afe", "asys"; power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; - clocks = <&infracfg CLK_INFRA_AUDIO>, - <&topckgen CLK_TOP_AUD_MUX1_SEL>, + clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>, <&topckgen CLK_TOP_AUD_MUX2_SEL>, - <&topckgen CLK_TOP_AUD_MUX1_DIV>, - <&topckgen CLK_TOP_AUD_MUX2_DIV>, - <&topckgen CLK_TOP_AUD_48K_TIMING>, - <&topckgen CLK_TOP_AUD_44K_TIMING>, - <&topckgen CLK_TOP_AUDPLL_MUX_SEL>, - <&topckgen CLK_TOP_APLL_SEL>, - <&topckgen CLK_TOP_AUD1PLL_98M>, - <&topckgen CLK_TOP_AUD2PLL_90M>, - <&topckgen CLK_TOP_HADDS2PLL_98M>, - <&topckgen CLK_TOP_HADDS2PLL_294M>, - <&topckgen CLK_TOP_AUDPLL>, - <&topckgen CLK_TOP_AUDPLL_D4>, - <&topckgen CLK_TOP_AUDPLL_D8>, - <&topckgen CLK_TOP_AUDPLL_D16>, - <&topckgen CLK_TOP_AUDPLL_D24>, - <&topckgen CLK_TOP_AUDINTBUS_SEL>, - <&clk26m>, - <&topckgen CLK_TOP_SYSPLL1_D4>, <&topckgen CLK_TOP_AUD_K1_SRC_SEL>, <&topckgen CLK_TOP_AUD_K2_SRC_SEL>, <&topckgen CLK_TOP_AUD_K3_SRC_SEL>, <&topckgen CLK_TOP_AUD_K4_SRC_SEL>, - <&topckgen CLK_TOP_AUD_K5_SRC_SEL>, - <&topckgen CLK_TOP_AUD_K6_SRC_SEL>, <&topckgen CLK_TOP_AUD_K1_SRC_DIV>, <&topckgen CLK_TOP_AUD_K2_SRC_DIV>, <&topckgen CLK_TOP_AUD_K3_SRC_DIV>, <&topckgen CLK_TOP_AUD_K4_SRC_DIV>, - <&topckgen CLK_TOP_AUD_K5_SRC_DIV>, - <&topckgen CLK_TOP_AUD_K6_SRC_DIV>, <&topckgen CLK_TOP_AUD_I2S1_MCLK>, <&topckgen CLK_TOP_AUD_I2S2_MCLK>, <&topckgen CLK_TOP_AUD_I2S3_MCLK>, <&topckgen CLK_TOP_AUD_I2S4_MCLK>, - <&topckgen CLK_TOP_AUD_I2S5_MCLK>, - <&topckgen CLK_TOP_AUD_I2S6_MCLK>, - <&topckgen CLK_TOP_ASM_M_SEL>, - <&topckgen CLK_TOP_ASM_H_SEL>, - <&topckgen CLK_TOP_UNIVPLL2_D4>, - <&topckgen CLK_TOP_UNIVPLL2_D2>, - <&topckgen CLK_TOP_SYSPLL_D5>; + <&audiosys CLK_AUD_I2SO1>, + <&audiosys CLK_AUD_I2SO2>, + <&audiosys CLK_AUD_I2SO3>, + <&audiosys CLK_AUD_I2SO4>, + <&audiosys CLK_AUD_I2SIN1>, + <&audiosys CLK_AUD_I2SIN2>, + <&audiosys CLK_AUD_I2SIN3>, + <&audiosys CLK_AUD_I2SIN4>, + <&audiosys CLK_AUD_ASRCO1>, + <&audiosys CLK_AUD_ASRCO2>, + <&audiosys CLK_AUD_ASRCO3>, + <&audiosys CLK_AUD_ASRCO4>, + <&audiosys CLK_AUD_AFE>, + <&audiosys CLK_AUD_AFE_CONN>, + <&audiosys CLK_AUD_A1SYS>, + <&audiosys CLK_AUD_A2SYS>, + <&audiosys CLK_AUD_AFE_MRGIF>; - clock-names = "infra_sys_audio_clk", - "top_audio_mux1_sel", + clock-names = "top_audio_mux1_sel", "top_audio_mux2_sel", - "top_audio_mux1_div", - "top_audio_mux2_div", - "top_audio_48k_timing", - "top_audio_44k_timing", - "top_audpll_mux_sel", - "top_apll_sel", - "top_aud1_pll_98M", - "top_aud2_pll_90M", - "top_hadds2_pll_98M", - "top_hadds2_pll_294M", - "top_audpll", - "top_audpll_d4", - "top_audpll_d8", - "top_audpll_d16", - "top_audpll_d24", - "top_audintbus_sel", - "clk_26m", - "top_syspll1_d4", - "top_aud_k1_src_sel", - "top_aud_k2_src_sel", - "top_aud_k3_src_sel", - "top_aud_k4_src_sel", - "top_aud_k5_src_sel", - "top_aud_k6_src_sel", - "top_aud_k1_src_div", - "top_aud_k2_src_div", - "top_aud_k3_src_div", - "top_aud_k4_src_div", - "top_aud_k5_src_div", - "top_aud_k6_src_div", - "top_aud_i2s1_mclk", - "top_aud_i2s2_mclk", - "top_aud_i2s3_mclk", - "top_aud_i2s4_mclk", - "top_aud_i2s5_mclk", - "top_aud_i2s6_mclk", - "top_asm_m_sel", - "top_asm_h_sel", - "top_univpll2_d4", - "top_univpll2_d2", - "top_syspll_d5"; + "i2s0_src_sel", + "i2s1_src_sel", + "i2s2_src_sel", + "i2s3_src_sel", + "i2s0_src_div", + "i2s1_src_div", + "i2s2_src_div", + "i2s3_src_div", + "i2s0_mclk_en", + "i2s1_mclk_en", + "i2s2_mclk_en", + "i2s3_mclk_en", + "i2so0_hop_ck", + "i2so1_hop_ck", + "i2so2_hop_ck", + "i2so3_hop_ck", + "i2si0_hop_ck", + "i2si1_hop_ck", + "i2si2_hop_ck", + "i2si3_hop_ck", + "asrc0_out_ck", + "asrc1_out_ck", + "asrc2_out_ck", + "asrc3_out_ck", + "audio_afe_pd", + "audio_afe_conn_pd", + "audio_a1sys_pd", + "audio_a2sys_pd", + "audio_mrgif_pd"; + + assigned-clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>, + <&topckgen CLK_TOP_AUD_MUX2_SEL>, + <&topckgen CLK_TOP_AUD_MUX1_DIV>, + <&topckgen CLK_TOP_AUD_MUX2_DIV>; + assigned-clock-parents = <&topckgen CLK_TOP_AUD1PLL_98M>, + <&topckgen CLK_TOP_AUD2PLL_90M>; + assigned-clock-rates = <0>, <0>, <49152000>, <45158400>; };
Signature · 1 line
1.9.1
Mark Brown
maintainerApplied "ASoC: mediatek: update clock related properties of MT2701 AFE" to the asoc tree
The patch
ASoC: mediatek: update clock related properties of MT2701 AFE
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks,
Mark
Quoted 1 line
From
0739fdfc0617a86781799d033e8fe758e8e48554Mon Sep 17 00:00:00 2001
From: Ryder Lee <[email protected]>
Date: Tue, 2 Jan 2018 19:47:21 +0800
Subject: [PATCH] ASoC: mediatek: update clock related properties of MT2701 AFE
Add 'assigned-clocks*' properties which are used to initialize default domain sources of audio system. we could configure different sets of input clocks through DTS now. Hence driver no longer cares about that.
Also we change some 'clock-names' to make them more generic so that other chips can reuse gracefully.
--- .../devicetree/bindings/sound/mt2701-afe-pcm.txt | 207 +++++++++------------ 1 file changed, 91 insertions(+), 116 deletions(-)
Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt +91 -116
@@ -6,51 +6,44 @@ Required properties: - interrupts: should contain AFE and ASYS interrupts - interrupt-names: should be "afe" and "asys" - power-domains: should define the power domain +- clocks: Must contain an entry for each entry in clock-names + See ../clocks/clock-bindings.txt for details - clock-names: should have these clock names: - "infra_sys_audio_clk", "top_audio_mux1_sel", "top_audio_mux2_sel", - "top_audio_mux1_div", - "top_audio_mux2_div", - "top_audio_48k_timing", - "top_audio_44k_timing", - "top_audpll_mux_sel", - "top_apll_sel", - "top_aud1_pll_98M", - "top_aud2_pll_90M", - "top_hadds2_pll_98M", - "top_hadds2_pll_294M", - "top_audpll", - "top_audpll_d4", - "top_audpll_d8", - "top_audpll_d16", - "top_audpll_d24", - "top_audintbus_sel", - "clk_26m", - "top_syspll1_d4", - "top_aud_k1_src_sel", - "top_aud_k2_src_sel", - "top_aud_k3_src_sel", - "top_aud_k4_src_sel", - "top_aud_k5_src_sel", - "top_aud_k6_src_sel", - "top_aud_k1_src_div", - "top_aud_k2_src_div", - "top_aud_k3_src_div", - "top_aud_k4_src_div", - "top_aud_k5_src_div", - "top_aud_k6_src_div", - "top_aud_i2s1_mclk", - "top_aud_i2s2_mclk", - "top_aud_i2s3_mclk", - "top_aud_i2s4_mclk", - "top_aud_i2s5_mclk", - "top_aud_i2s6_mclk", - "top_asm_m_sel", - "top_asm_h_sel", - "top_univpll2_d4", - "top_univpll2_d2", - "top_syspll_d5"; + "i2s0_src_sel", + "i2s1_src_sel", + "i2s2_src_sel", + "i2s3_src_sel", + "i2s0_src_div", + "i2s1_src_div", + "i2s2_src_div", + "i2s3_src_div", + "i2s0_mclk_en", + "i2s1_mclk_en", + "i2s2_mclk_en", + "i2s3_mclk_en", + "i2so0_hop_ck", + "i2so1_hop_ck", + "i2so2_hop_ck", + "i2so3_hop_ck", + "i2si0_hop_ck", + "i2si1_hop_ck", + "i2si2_hop_ck", + "i2si3_hop_ck", + "asrc0_out_ck", + "asrc1_out_ck", + "asrc2_out_ck", + "asrc3_out_ck", + "audio_afe_pd", + "audio_afe_conn_pd", + "audio_a1sys_pd", + "audio_a2sys_pd", + "audio_mrgif_pd"; +- assigned-clocks: list of input clocks and dividers for the audio system. + See ../clocks/clock-bindings.txt for details. +- assigned-clocks-parents: parent of input clocks of assigned clocks. +- assigned-clock-rates: list of clock frequencies of assigned clocks. Example:
@@ -62,93 +55,75 @@ Example: <GIC_SPI 132 IRQ_TYPE_LEVEL_LOW>; interrupt-names = "afe", "asys"; power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; - clocks = <&infracfg CLK_INFRA_AUDIO>, - <&topckgen CLK_TOP_AUD_MUX1_SEL>, + clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>, <&topckgen CLK_TOP_AUD_MUX2_SEL>, - <&topckgen CLK_TOP_AUD_MUX1_DIV>, - <&topckgen CLK_TOP_AUD_MUX2_DIV>, - <&topckgen CLK_TOP_AUD_48K_TIMING>, - <&topckgen CLK_TOP_AUD_44K_TIMING>, - <&topckgen CLK_TOP_AUDPLL_MUX_SEL>, - <&topckgen CLK_TOP_APLL_SEL>, - <&topckgen CLK_TOP_AUD1PLL_98M>, - <&topckgen CLK_TOP_AUD2PLL_90M>, - <&topckgen CLK_TOP_HADDS2PLL_98M>, - <&topckgen CLK_TOP_HADDS2PLL_294M>, - <&topckgen CLK_TOP_AUDPLL>, - <&topckgen CLK_TOP_AUDPLL_D4>, - <&topckgen CLK_TOP_AUDPLL_D8>, - <&topckgen CLK_TOP_AUDPLL_D16>, - <&topckgen CLK_TOP_AUDPLL_D24>, - <&topckgen CLK_TOP_AUDINTBUS_SEL>, - <&clk26m>, - <&topckgen CLK_TOP_SYSPLL1_D4>, <&topckgen CLK_TOP_AUD_K1_SRC_SEL>, <&topckgen CLK_TOP_AUD_K2_SRC_SEL>, <&topckgen CLK_TOP_AUD_K3_SRC_SEL>, <&topckgen CLK_TOP_AUD_K4_SRC_SEL>, - <&topckgen CLK_TOP_AUD_K5_SRC_SEL>, - <&topckgen CLK_TOP_AUD_K6_SRC_SEL>, <&topckgen CLK_TOP_AUD_K1_SRC_DIV>, <&topckgen CLK_TOP_AUD_K2_SRC_DIV>, <&topckgen CLK_TOP_AUD_K3_SRC_DIV>, <&topckgen CLK_TOP_AUD_K4_SRC_DIV>, - <&topckgen CLK_TOP_AUD_K5_SRC_DIV>, - <&topckgen CLK_TOP_AUD_K6_SRC_DIV>, <&topckgen CLK_TOP_AUD_I2S1_MCLK>, <&topckgen CLK_TOP_AUD_I2S2_MCLK>, <&topckgen CLK_TOP_AUD_I2S3_MCLK>, <&topckgen CLK_TOP_AUD_I2S4_MCLK>, - <&topckgen CLK_TOP_AUD_I2S5_MCLK>, - <&topckgen CLK_TOP_AUD_I2S6_MCLK>, - <&topckgen CLK_TOP_ASM_M_SEL>, - <&topckgen CLK_TOP_ASM_H_SEL>, - <&topckgen CLK_TOP_UNIVPLL2_D4>, - <&topckgen CLK_TOP_UNIVPLL2_D2>, - <&topckgen CLK_TOP_SYSPLL_D5>; + <&audiosys CLK_AUD_I2SO1>, + <&audiosys CLK_AUD_I2SO2>, + <&audiosys CLK_AUD_I2SO3>, + <&audiosys CLK_AUD_I2SO4>, + <&audiosys CLK_AUD_I2SIN1>, + <&audiosys CLK_AUD_I2SIN2>, + <&audiosys CLK_AUD_I2SIN3>, + <&audiosys CLK_AUD_I2SIN4>, + <&audiosys CLK_AUD_ASRCO1>, + <&audiosys CLK_AUD_ASRCO2>, + <&audiosys CLK_AUD_ASRCO3>, + <&audiosys CLK_AUD_ASRCO4>, + <&audiosys CLK_AUD_AFE>, + <&audiosys CLK_AUD_AFE_CONN>, + <&audiosys CLK_AUD_A1SYS>, + <&audiosys CLK_AUD_A2SYS>, + <&audiosys CLK_AUD_AFE_MRGIF>; - clock-names = "infra_sys_audio_clk", - "top_audio_mux1_sel", + clock-names = "top_audio_mux1_sel", "top_audio_mux2_sel", - "top_audio_mux1_div", - "top_audio_mux2_div", - "top_audio_48k_timing", - "top_audio_44k_timing", - "top_audpll_mux_sel", - "top_apll_sel", - "top_aud1_pll_98M", - "top_aud2_pll_90M", - "top_hadds2_pll_98M", - "top_hadds2_pll_294M", - "top_audpll", - "top_audpll_d4", - "top_audpll_d8", - "top_audpll_d16", - "top_audpll_d24", - "top_audintbus_sel", - "clk_26m", - "top_syspll1_d4", - "top_aud_k1_src_sel", - "top_aud_k2_src_sel", - "top_aud_k3_src_sel", - "top_aud_k4_src_sel", - "top_aud_k5_src_sel", - "top_aud_k6_src_sel", - "top_aud_k1_src_div", - "top_aud_k2_src_div", - "top_aud_k3_src_div", - "top_aud_k4_src_div", - "top_aud_k5_src_div", - "top_aud_k6_src_div", - "top_aud_i2s1_mclk", - "top_aud_i2s2_mclk", - "top_aud_i2s3_mclk", - "top_aud_i2s4_mclk", - "top_aud_i2s5_mclk", - "top_aud_i2s6_mclk", - "top_asm_m_sel", - "top_asm_h_sel", - "top_univpll2_d4", - "top_univpll2_d2", - "top_syspll_d5"; + "i2s0_src_sel", + "i2s1_src_sel", + "i2s2_src_sel", + "i2s3_src_sel", + "i2s0_src_div", + "i2s1_src_div", + "i2s2_src_div", + "i2s3_src_div", + "i2s0_mclk_en", + "i2s1_mclk_en", + "i2s2_mclk_en", + "i2s3_mclk_en", + "i2so0_hop_ck", + "i2so1_hop_ck", + "i2so2_hop_ck", + "i2so3_hop_ck", + "i2si0_hop_ck", + "i2si1_hop_ck", + "i2si2_hop_ck", + "i2si3_hop_ck", + "asrc0_out_ck", + "asrc1_out_ck", + "asrc2_out_ck", + "asrc3_out_ck", + "audio_afe_pd", + "audio_afe_conn_pd", + "audio_a1sys_pd", + "audio_a2sys_pd", + "audio_mrgif_pd"; + + assigned-clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>, + <&topckgen CLK_TOP_AUD_MUX2_SEL>, + <&topckgen CLK_TOP_AUD_MUX1_DIV>, + <&topckgen CLK_TOP_AUD_MUX2_DIV>; + assigned-clock-parents = <&topckgen CLK_TOP_AUD1PLL_98M>, + <&topckgen CLK_TOP_AUD2PLL_90M>; + assigned-clock-rates = <0>, <0>, <49152000>, <45158400>; };
Signature · 1 line
2.15.1
PATCH 5/12 mfd: mtk-audsys: add MediaTek audio subsystem driver
In reply to Ryder LeeAdd a common driver for the top block of the MediaTek audio subsystem. This is a wrapper which manages resources for audio components.
--- drivers/mfd/Kconfig | 9 ++++ drivers/mfd/Makefile | 2 + drivers/mfd/mtk-audsys.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 drivers/mfd/mtk-audsys.c
drivers/mfd/Kconfig +9 -0
@@ -368,6 +368,15 @@ config MFD_MC13XXX_I2C help Select this if your MC13xxx is connected via an I2C bus. +config MFD_MEDIATEK_AUDSYS + tristate "MediaTek audio subsystem interface" + select MDF_CORE + select REGMAP_MMIO + help + Select this if you have a audio subsystem in MediaTek SoC. + The audio subsystem has at least a clock driver part and some + audio components. + config MFD_MXS_LRADC tristate "Freescale i.MX23/i.MX28 LRADC" depends on ARCH_MXS || COMPILE_TEST
drivers/mfd/Makefile +2 -0
@@ -101,6 +101,8 @@ obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o obj-$(CONFIG_MFD_MC13XXX_SPI) += mc13xxx-spi.o obj-$(CONFIG_MFD_MC13XXX_I2C) += mc13xxx-i2c.o +obj-$(CONFIG_MFD_MEDIATEK_AUDSYS) += mtk-audsys.o + obj-$(CONFIG_MFD_CORE) += mfd-core.o obj-$(CONFIG_EZX_PCAP) += ezx-pcap.o
drivers/mfd/mtk-audsys.c new file +138 -0
138 lines not on this page · raw message
Signature · 1 line
1.9.1
Re: [PATCH 05/12] mfd: mtk-audsys: add MediaTek audio subsystem driver
Quoted 50 lines · Ryder Lee
Add a common driver for the top block of the MediaTek audio subsystem. This is a wrapper which manages resources for audio components.
Signed-off-by Ryder Lee <[email protected]>--- drivers/mfd/Kconfig | 9 ++++ drivers/mfd/Makefile | 2 + drivers/mfd/mtk-audsys.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 drivers/mfd/mtk-audsys.cdrivers/mfd/Kconfig +9
-0@@ -368,6 +368,15 @@ config MFD_MC13XXX_I2C help Select this if your MC13xxx is connected via an I2C bus. +config MFD_MEDIATEK_AUDSYS + tristate "MediaTek audio subsystem interface" + select MDF_CORE + select REGMAP_MMIO + help + Select this if you have a audio subsystem in MediaTek SoC. + The audio subsystem has at least a clock driver part and some + audio components. + config MFD_MXS_LRADC tristate "Freescale i.MX23/i.MX28 LRADC" depends on ARCH_MXS || COMPILE_TESTdrivers/mfd/Makefile +2
-0@@ -101,6 +101,8 @@ obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o obj-$(CONFIG_MFD_MC13XXX_SPI) += mc13xxx-spi.o obj-$(CONFIG_MFD_MC13XXX_I2C) += mc13xxx-i2c.o +obj-$(CONFIG_MFD_MEDIATEK_AUDSYS) += mtk-audsys.o + obj-$(CONFIG_MFD_CORE) += mfd-core.o obj-$(CONFIG_EZX_PCAP) += ezx-pcap.odrivers/mfd/mtk-audsys.c new file +0
-0
drivers/mfd/mtk-audsys.c line 8
Quoted 8 lines
drivers/mfd/mtk-audsys.c new file +8
-0@@ -0,0 +1,138 @@ +/* +* Mediatek audio subsystem core driver +* +* Copyright (c) 2017 MediaTek Inc. +* +* Author: Ryder Lee <[email protected]> +* +* For licencing details see kernel-base/COPYING
You can't do that.
Grep for SPDX to see what is expected.
drivers/mfd/mtk-audsys.c line 18
Quoted 10 lines
drivers/mfd/mtk-audsys.c new file +10
-0+* +*/ + +#include <linux/clk.h> +#include <linux/module.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#define AUDSYS_MAX_CLK_NUM 3
When is this not 3?
Quoted 8 lines
drivers/mfd/mtk-audsys.c new file +8
-0+struct sys_dev { +struct device *dev; +struct regmap *regmap; +int clk_num; +struct clk *clks[]; +}; + +static const struct regmap_config aud_regmap_config = {
drivers/mfd/mtk-audsys.c line 37
Quoted 10 lines
drivers/mfd/mtk-audsys.c new file +10
-0+ .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x15e0, + .cache_type = REGCACHE_NONE, +}; + +static int mtk_subsys_enable (struct sys_dev *sys) +{ +struct device *dev = sys->dev;
I would remove dev and regmap from the sys_dev struct and pass in pdev directly into this function. Then use platform_get_drvdata() as you did in .remove().
Quoted 4 lines
drivers/mfd/mtk-audsys.c new file +4
-0+struct clk *clk; +int i, ret; + +for (i =0 ; i < sys->clk_num; i++) {
drivers/mfd/mtk-audsys.c line 51
Quoted 10 lines
drivers/mfd/mtk-audsys.c new file +10
-0+ clk =of_clk_get (dev->of_node, i); +if (IS_ERR (clk)) { +if (PTR_ERR (clk) == -EPROBE_DEFER ) +return -EPROBE_DEFER ; +break ; + } + sys->clks[i] = clk; + } + +for (i =0 ; i < sys->clk_num && sys->clks[i]; i++) {
Why do you need a separate loop for this?
Just prepare and enable valid clocks in the for() loop above.
Quoted 14 lines
drivers/mfd/mtk-audsys.c new file +14
-0+ ret =clk_prepare_enable (sys->clks[i]); +if (ret) + goto err_enable_clks; + } + +return 0 ; + +err_enable_clks: +while (--i >=0 ) +clk_disable_unprepare (sys->clks[i]); + +return ret; +} +
drivers/mfd/mtk-audsys.c line 75
Quoted 10 lines
drivers/mfd/mtk-audsys.c new file +10
-0+static int mtk_subsys_probe (struct platform_device *pdev) +{ +struct sys_dev *sys; +struct resource *res; +void __iomem *mmio; +int num, ret; + + num = (int )of_device_get_match_data (&pdev->dev); +if (!num) +return -EINVAL ;
This is a very rigid method of achieving your aim. Please find a way to make this more dynamic. You're probably better off counting the elements within the property, checking to ensure there aren't more than the maximum pre-allocated/allowed clocks, then using the number gleaned directly from the Device Tree.
drivers/mfd/mtk-audsys.c line 78
Quoted 2 lines
drivers/mfd/mtk-audsys.c new file +2
-0+ sys =devm_kzalloc (&pdev->dev,sizeof (*sys) + +sizeof (struct clk *) * num,GFP_KERNEL );
You need to add bracketing here for clarity.
drivers/mfd/mtk-audsys.c line 83
Quoted 5 lines
drivers/mfd/mtk-audsys.c new file +5
-0+if (!sys) +return -ENOMEM ; + + sys->clk_num = num; + sys->dev = &pdev->dev;
Why are you saving the device pointer?
drivers/mfd/mtk-audsys.c line 91
Quoted 7 lines
drivers/mfd/mtk-audsys.c new file +7
-0+ res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); + mmio =devm_ioremap_resource (sys->dev, res); +if (IS_ERR (mmio)) +return PTR_ERR (mmio); + + sys->regmap =devm_regmap_init_mmio (sys->dev, mmio, + &aud_regmap_config);
Why are you saving a devm'ed regmap pointer?
drivers/mfd/mtk-audsys.c line 98
Quoted 7 lines
drivers/mfd/mtk-audsys.c new file +7
-0+if (IS_ERR (sys->regmap)) +return PTR_ERR (sys->regmap); + +platform_set_drvdata (pdev, sys); + +/* Enable top level clocks */ + ret =mtk_subsys_enable (sys);
mtk_subsys_enable_clks()
drivers/mfd/mtk-audsys.c line 111
Quoted 13 lines
drivers/mfd/mtk-audsys.c new file +13
-0+if (ret) +return ret; + +return devm_of_platform_populate (sys->dev); +}; + +static int mtk_subsys_remove (struct platform_device *pdev) +{ +struct sys_dev *sys =platform_get_drvdata (pdev); +int i; + +for (i = sys->clk_num -1 ; i >=0 ; i--) +if (sys->clks[i])
This check is superfluous as the clk subsystem does this for you.
drivers/mfd/mtk-audsys.c line 120
Quoted 9 lines
drivers/mfd/mtk-audsys.c new file +9
-0+clk_disable_unprepare (sys->clks[i]); + +return 0 ; +} + +static const struct of_device_id of_match_audsys[] = { + { + .compatible ="mediatek,mt2701-audsys-core" , + .data = (void *)AUDSYS_MAX_CLK_NUM ,
You can remove this line.
Quoted 9 lines
drivers/mfd/mtk-audsys.c new file +9
-0+ }, + {}, +}; +MODULE_DEVICE_TABLE (platform, of_match_audsys); + +static struct platform_driver audsys_drv = { + .probe = mtk_subsys_probe, + .remove = mtk_subsys_remove, + .driver = {
drivers/mfd/mtk-audsys.c line 138
Quoted 10 lines
drivers/mfd/mtk-audsys.c new file +9
-0+ .name = "mediatek-audsys-core", + .of_match_table = of_match_ptr(of_match_audsys), + }, +}; + +builtin_platform_driver (audsys_drv); + +MODULE_DESCRIPTION ("Mediatek audio subsystem core driver" ); +MODULE_LICENSE ("GPL" );
<just_checking>
Are you sure this is what you want?
</just_checking>
Signature · 4 lines
Lee Jones Linaro Services Technical Lead Linaro.org ? Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog
Re: [PATCH 05/12] mfd: mtk-audsys: add MediaTek audio subsystem driver
Quoted 24 lines · Lee Jones
Quoted 11 lines · Ryder Lee
Add a common driver for the top block of the MediaTek audio subsystem. This is a wrapper which manages resources for audio components.
drivers/mfd/mtk-audsys.c new file +0
-0drivers/mfd/mtk-audsys.c line 8
Quoted 8 lines
drivers/mfd/mtk-audsys.c new file +8
-0@@ -0,0 +1,138 @@ +/* +* Mediatek audio subsystem core driver +* +* Copyright (c) 2017 MediaTek Inc. +* +* Author: Ryder Lee <ryder.lee-NuS5LvNUpcJWk0Htik3J/[email protected]> +* +* For licencing details see kernel-base/COPYING You can't do that.
Quoted 1 line
Grep for SPDX to see what is expected.
Okay.
Quoted 4 lines
Quoted 4 lines
drivers/mfd/mtk-audsys.c new file +4
-0+* +*/ + +#include <linux/clk.h>
Quoted 8 lines
drivers/mfd/mtk-audsys.c line 18
Quoted 6 lines
drivers/mfd/mtk-audsys.c new file +6
-0+#include <linux/module.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#define AUDSYS_MAX_CLK_NUM 3When is this not 3?
If other subsystems have different clocks numbers.
Quoted 40 lines
Quoted 8 lines
drivers/mfd/mtk-audsys.c new file +8
-0+struct sys_dev { +struct device *dev; +struct regmap *regmap; +int clk_num; +struct clk *clks[]; +}; + +static const struct regmap_config aud_regmap_config = {drivers/mfd/mtk-audsys.c line 37
Quoted 10 lines
drivers/mfd/mtk-audsys.c new file +10
-0+ .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x15e0, + .cache_type = REGCACHE_NONE, +}; + +static int mtk_subsys_enable (struct sys_dev *sys) +{ +struct device *dev = sys->dev;I would remove dev and regmap from the
sys_devstruct and pass in pdev directly into this function. Then useplatform_get_drvdata()as you did in .remove().Quoted 4 lines
drivers/mfd/mtk-audsys.c new file +4
-0+struct clk *clk; +int i, ret; + +for (i =0 ; i < sys->clk_num; i++) {drivers/mfd/mtk-audsys.c line 51
Quoted 10 lines
drivers/mfd/mtk-audsys.c new file +10
-0+ clk =of_clk_get (dev->of_node, i); +if (IS_ERR (clk)) { +if (PTR_ERR (clk) == -EPROBE_DEFER ) +return -EPROBE_DEFER ; +break ; + } + sys->clks[i] = clk; + } + +for (i =0 ; i < sys->clk_num && sys->clks[i]; i++) {Why do you need a separate loop for this?
Quoted 1 line
Just prepare and enable valid clocks in the
for()loop above.
Ohh, it's a mistake. Thanks for reminding me.
Quoted 22 lines
Quoted 22 lines
drivers/mfd/mtk-audsys.c new file +22
-0+ ret =clk_prepare_enable (sys->clks[i]); +if (ret) + goto err_enable_clks; + } + +return 0 ; + +err_enable_clks: +while (--i >=0 ) +clk_disable_unprepare (sys->clks[i]); + +return ret; +} + +static int mtk_subsys_probe (struct platform_device *pdev) +{ +struct sys_dev *sys; +struct resource *res; +void __iomem *mmio; +int num, ret; + + num = (int )of_device_get_match_data (&pdev->dev);
Quoted 8 lines
drivers/mfd/mtk-audsys.c line 75
Quoted 2 lines
drivers/mfd/mtk-audsys.c new file +2
-0+if (!num) +return -EINVAL ;This is a very rigid method of achieving your aim. Please find a way to make this more dynamic. You're probably better off counting the elements within the property, checking to ensure there aren't more than the maximum pre-allocated/allowed clocks, then using the number gleaned directly from the Device Tree.
Just in case other MTK subsystems can reuse this driver and set their own clock numbers in SoC data table, but yes, it's too rigid.
Quoted 4 lines
drivers/mfd/mtk-audsys.c line 78
Quoted 2 lines
drivers/mfd/mtk-audsys.c new file +2
-0+ sys =devm_kzalloc (&pdev->dev,sizeof (*sys) + +sizeof (struct clk *) * num,GFP_KERNEL );You need to add bracketing here for clarity.
Okay.
Quoted 7 lines
drivers/mfd/mtk-audsys.c line 83
Quoted 5 lines
drivers/mfd/mtk-audsys.c new file +5
-0+if (!sys) +return -ENOMEM ; + + sys->clk_num = num; + sys->dev = &pdev->dev;Why are you saving the device pointer?
will remove it.
Quoted 9 lines
drivers/mfd/mtk-audsys.c line 91
Quoted 7 lines
drivers/mfd/mtk-audsys.c new file +7
-0+ res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); + mmio =devm_ioremap_resource (sys->dev, res); +if (IS_ERR (mmio)) +return PTR_ERR (mmio); + + sys->regmap =devm_regmap_init_mmio (sys->dev, mmio, + &aud_regmap_config);Why are you saving a devm'ed regmap pointer?
We don't really need this 'sys->regmap" in driver, but need to initialize mmio so that its subnodes can obtain regmap through dev_get_regmap().
Quoted 9 lines
drivers/mfd/mtk-audsys.c line 98
Quoted 7 lines
drivers/mfd/mtk-audsys.c new file +7
-0+if (IS_ERR (sys->regmap)) +return PTR_ERR (sys->regmap); + +platform_set_drvdata (pdev, sys); + +/* Enable top level clocks */ + ret =mtk_subsys_enable (sys);
mtk_subsys_enable_clks()
Okay.
Quoted 16 lines
drivers/mfd/mtk-audsys.c line 111
Quoted 13 lines
drivers/mfd/mtk-audsys.c new file +13
-0+if (ret) +return ret; + +return devm_of_platform_populate (sys->dev); +}; + +static int mtk_subsys_remove (struct platform_device *pdev) +{ +struct sys_dev *sys =platform_get_drvdata (pdev); +int i; + +for (i = sys->clk_num -1 ; i >=0 ; i--) +if (sys->clks[i])This check is superfluous as the clk subsystem does this for you.
Quoted 11 lines
drivers/mfd/mtk-audsys.c line 120
Quoted 9 lines
drivers/mfd/mtk-audsys.c new file +9
-0+clk_disable_unprepare (sys->clks[i]); + +return 0 ; +} + +static const struct of_device_id of_match_audsys[] = { + { + .compatible ="mediatek,mt2701-audsys-core" , + .data = (void *)AUDSYS_MAX_CLK_NUM ,You can remove this line.
Okay
Quoted 18 lines
Quoted 17 lines
drivers/mfd/mtk-audsys.c new file +17
-0+ }, + {}, +}; +MODULE_DEVICE_TABLE (platform, of_match_audsys); + +static struct platform_driver audsys_drv = { + .probe = mtk_subsys_probe, + .remove = mtk_subsys_remove, + .driver = { + .name ="mediatek-audsys-core" , + .of_match_table =of_match_ptr (of_match_audsys), + }, +}; + +builtin_platform_driver (audsys_drv); + +MODULE_DESCRIPTION ("Mediatek audio subsystem core driver" );
Quoted 6 lines
drivers/mfd/mtk-audsys.c line 138
Quoted 1 line
drivers/mfd/mtk-audsys.c new file +1
-0+MODULE_LICENSE ("GPL" );<
just_checking>
Are you sure this is what you want?
</just_checking>
The reason to add this driver is some MTK subsystem blocks expose more than a single functionality but register those in different kernel subsystems (e.g., AUDSYS includes audio components and clock part).
But I think I should just add a property "simple-mfd" in DTS instead of adding this driver.
Thanks.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 6/12 mfd: add DT bindings for MedaiTek audio subsystem
In reply to Ryder LeeThis patch adds documentation of the DT bindings for the MediaTek audio subsystem wrapper.
--- .../devicetree/bindings/mfd/mtk-audsys.txt | 109 +++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/mtk-audsys.txt
Documentation/devicetree/bindings/mfd/mtk-audsys.txt new file +109 -0
@@ -0,0 +1,109 @@ +MediaTek Audio Subsystem Wrapper + +Required properties: +- compatible: Should be "mediatek,mt2701-audsys-core". +- reg: Should contain the device's region location and size. +- clocks: Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. +- clock-names: Should contain "infra_aud", "top_a1sys", "top_a2sys". + +Required subnodes are described in: +- ../sound/mt2701-afe-pcm.txt. +- ../arm/mediatek/mediatek,audsys.txt. + +Example: + + audio-subsystm@11220000 { + compatible = "mediatek,mt2701-audsys-core"; + reg = <0 0x11220000 0 0x2000>, + <0 0x112a0000 0 0x20000>; + clocks = <&infracfg CLK_INFRA_AUDIO>, + <&topckgen CLK_TOP_AUD_48K_TIMING>, + <&topckgen CLK_TOP_AUD_44K_TIMING>; + clock-names = "infra_aud", "top_a1sys", "top_a2sys"; + + audsys: clock { + compatible = "mediatek,mt2701-audsys"; + #clock-cells = <1>; + }; + + afe: audio { + compatible = "mediatek,mt2701-audio"; + interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 132 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "afe", "asys"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; + + clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>, + <&topckgen CLK_TOP_AUD_MUX2_SEL>, + <&topckgen CLK_TOP_AUD_K1_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K2_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K3_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K4_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K1_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K2_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K3_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K4_SRC_DIV>, + <&topckgen CLK_TOP_AUD_I2S1_MCLK>, + <&topckgen CLK_TOP_AUD_I2S2_MCLK>, + <&topckgen CLK_TOP_AUD_I2S3_MCLK>, + <&topckgen CLK_TOP_AUD_I2S4_MCLK>, + <&audsys CLK_AUD_I2SO1>, + <&audsys CLK_AUD_I2SO2>, + <&audsys CLK_AUD_I2SO3>, + <&audsys CLK_AUD_I2SO4>, + <&audsys CLK_AUD_I2SIN1>, + <&audsys CLK_AUD_I2SIN2>, + <&audsys CLK_AUD_I2SIN3>, + <&audsys CLK_AUD_I2SIN4>, + <&audsys CLK_AUD_ASRCO1>, + <&audsys CLK_AUD_ASRCO2>, + <&audsys CLK_AUD_ASRCO3>, + <&audsys CLK_AUD_ASRCO4>, + <&audsys CLK_AUD_AFE>, + <&audsys CLK_AUD_AFE_CONN>, + <&audsys CLK_AUD_A1SYS>, + <&audsys CLK_AUD_A2SYS>, + <&audsys CLK_AUD_AFE_MRGIF>; + + clock-names = "top_audio_mux1_sel", + "top_audio_mux2_sel", + "i2s0_src_sel", + "i2s1_src_sel", + "i2s2_src_sel", + "i2s3_src_sel", + "i2s0_src_div", + "i2s1_src_div", + "i2s2_src_div", + "i2s3_src_div", + "i2s0_mclk_en", + "i2s1_mclk_en", + "i2s2_mclk_en", + "i2s3_mclk_en", + "i2so0_hop_ck", + "i2so1_hop_ck", + "i2so2_hop_ck", + "i2so3_hop_ck", + "i2si0_hop_ck", + "i2si1_hop_ck", + "i2si2_hop_ck", + "i2si3_hop_ck", + "asrc0_out_ck", + "asrc1_out_ck", + "asrc2_out_ck", + "asrc3_out_ck", + "audio_afe_pd", + "audio_afe_conn_pd", + "audio_a1sys_pd", + "audio_a2sys_pd", + "audio_mrgif_pd"; + + assigned-clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>, + <&topckgen CLK_TOP_AUD_MUX2_SEL>, + <&topckgen CLK_TOP_AUD_MUX1_DIV>, + <&topckgen CLK_TOP_AUD_MUX2_DIV>; + assigned-clock-parents = <&topckgen CLK_TOP_AUD1PLL_98M>, + <&topckgen CLK_TOP_AUD2PLL_90M>; + assigned-clock-rates = <0>, <0>, <49152000>, <45158400>; + }; + };
Signature · 1 line
1.9.1
Rob Herring
maintainerRe: [PATCH 06/12] mfd: add DT bindings for MedaiTek audio subsystem
Quoted 15 lines · Ryder Lee
This patch adds documentation of the DT bindings for the MediaTek audio subsystem wrapper.
--- .../devicetree/bindings/mfd/mtk-audsys.txt | 109 +++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/mtk-audsys.txtDocumentation/devicetree/bindings/mfd/mtk-audsys.txt new file +0
-0
Documentation/devicetree/bindings/mfd/mtk-audsys.txt line 5
Quoted 5 lines
Documentation/devicetree/bindings/mfd/mtk-audsys.txt new file +5
-0@@ -0,0 +1,109 @@ +MediaTek Audio Subsystem Wrapper + +Required properties: +- compatible: Should be "mediatek,mt2701-audsys-core". +- reg: Should contain the device's region location and size.
The example shows 2 regions. What are they?
Quoted 12 lines
Documentation/devicetree/bindings/mfd/mtk-audsys.txt new file +12
-0+- clocks: Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. +- clock-names: Should contain "infra_aud", "top_a1sys", "top_a2sys". + +Required subnodes are described in: +- ../sound/mt2701-afe-pcm.txt. +- ../arm/mediatek/mediatek,audsys.txt. + +Example: + + audio-subsystm@11220000 { + compatible = "mediatek,mt2701-audsys-core";
Documentation/devicetree/bindings/mfd/mtk-audsys.txt line 27
Quoted 10 lines
Documentation/devicetree/bindings/mfd/mtk-audsys.txt new file +10
-0+ reg = <0 0x11220000 0 0x2000>, + <0 0x112a0000 0 0x20000>; + clocks = <&infracfg CLK_INFRA_AUDIO>, + <&topckgen CLK_TOP_AUD_48K_TIMING>, + <&topckgen CLK_TOP_AUD_44K_TIMING>; + clock-names = "infra_aud", "top_a1sys", "top_a2sys"; + + audsys: clock { + compatible = "mediatek,mt2701-audsys"; + #clock-cells = <1>;
There's no need for a node here. Just put #clock-cells in the parent.
Documentation/devicetree/bindings/mfd/mtk-audsys.txt line 31
Quoted 4 lines
Documentation/devicetree/bindings/mfd/mtk-audsys.txt new file +4
-0+ }; + + afe: audio { + compatible = "mediatek,mt2701-audio";
No registers associated with this?
Looks to me like you are creating nodes just to instantiate drivers. Describe h/w blocks. DT is not the only way to instantiate drivers.
Quoted 85 lines
Documentation/devicetree/bindings/mfd/mtk-audsys.txt new file +78
-0+ interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 132 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "afe", "asys"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; + + clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>, + <&topckgen CLK_TOP_AUD_MUX2_SEL>, + <&topckgen CLK_TOP_AUD_K1_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K2_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K3_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K4_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K1_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K2_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K3_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K4_SRC_DIV>, + <&topckgen CLK_TOP_AUD_I2S1_MCLK>, + <&topckgen CLK_TOP_AUD_I2S2_MCLK>, + <&topckgen CLK_TOP_AUD_I2S3_MCLK>, + <&topckgen CLK_TOP_AUD_I2S4_MCLK>, + <&audsys CLK_AUD_I2SO1>, + <&audsys CLK_AUD_I2SO2>, + <&audsys CLK_AUD_I2SO3>, + <&audsys CLK_AUD_I2SO4>, + <&audsys CLK_AUD_I2SIN1>, + <&audsys CLK_AUD_I2SIN2>, + <&audsys CLK_AUD_I2SIN3>, + <&audsys CLK_AUD_I2SIN4>, + <&audsys CLK_AUD_ASRCO1>, + <&audsys CLK_AUD_ASRCO2>, + <&audsys CLK_AUD_ASRCO3>, + <&audsys CLK_AUD_ASRCO4>, + <&audsys CLK_AUD_AFE>, + <&audsys CLK_AUD_AFE_CONN>, + <&audsys CLK_AUD_A1SYS>, + <&audsys CLK_AUD_A2SYS>, + <&audsys CLK_AUD_AFE_MRGIF>; + + clock-names = "top_audio_mux1_sel", + "top_audio_mux2_sel", + "i2s0_src_sel", + "i2s1_src_sel", + "i2s2_src_sel", + "i2s3_src_sel", + "i2s0_src_div", + "i2s1_src_div", + "i2s2_src_div", + "i2s3_src_div", + "i2s0_mclk_en", + "i2s1_mclk_en", + "i2s2_mclk_en", + "i2s3_mclk_en", + "i2so0_hop_ck", + "i2so1_hop_ck", + "i2so2_hop_ck", + "i2so3_hop_ck", + "i2si0_hop_ck", + "i2si1_hop_ck", + "i2si2_hop_ck", + "i2si3_hop_ck", + "asrc0_out_ck", + "asrc1_out_ck", + "asrc2_out_ck", + "asrc3_out_ck", + "audio_afe_pd", + "audio_afe_conn_pd", + "audio_a1sys_pd", + "audio_a2sys_pd", + "audio_mrgif_pd"; + + assigned-clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>, + <&topckgen CLK_TOP_AUD_MUX2_SEL>, + <&topckgen CLK_TOP_AUD_MUX1_DIV>, + <&topckgen CLK_TOP_AUD_MUX2_DIV>; + assigned-clock-parents = <&topckgen CLK_TOP_AUD1PLL_98M>, + <&topckgen CLK_TOP_AUD2PLL_90M>; + assigned-clock-rates = <0>, <0>, <49152000>, <45158400>; + }; + };Signature · 6 lines
1.9.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 7/12 ASoC: mediatek: modify MT2701 AFE driver to adapt subsystem wrapper
In reply to Ryder LeeAs the new audio subsystem wrapper is in place, modify MT2701 AFE driver to adapt it.
--- sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 42 ++++++++++++------------------ sound/soc/mediatek/mt2701/mt2701-reg.h | 1 - 2 files changed, 17 insertions(+), 26 deletions(-)
sound/soc/mediatek/mt2701/mt2701-afe-pcm.c +17 -25
@@ -1368,14 +1368,6 @@ static int mt2701_irq_fs(struct snd_pcm_substream *substream, unsigned int rate) }, }; -static const struct regmap_config mt2701_afe_regmap_config = { - .reg_bits =32 , - .reg_stride =4 , - .val_bits =32 , - .max_register =AFE_END_ADDR , - .cache_type =REGCACHE_NONE , -}; -static irqreturn_t mt2701_asys_isr (int irq_id,void *dev) {int id;
@@ -1414,9 +1406,9 @@ static int mt2701_afe_runtime_resume(struct device *dev)static int mt2701_afe_pcm_dev_probe (struct platform_device *pdev) { +struct snd_soc_component *component;struct mtk_base_afe *afe;struct mt2701_afe_private *afe_priv; -struct resource *res;struct device *dev;int i, irq_id, ret;
@@ -1446,17 +1438,9 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)return ret; } - res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); - - afe->base_addr =devm_ioremap_resource (&pdev->dev, res); - -if (IS_ERR (afe->base_addr)) -return PTR_ERR (afe->base_addr); - - afe->regmap =devm_regmap_init_mmio (&pdev->dev, afe->base_addr, - &mt2701_afe_regmap_config); -if (IS_ERR (afe->regmap)) -return PTR_ERR (afe->regmap); + afe->regmap =dev_get_regmap (dev->parent,NULL ); +if (!afe->regmap) +return -ENODEV ;mutex_init (&afe->irq_alloc_lock);
@@ -1490,6 +1474,12 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) = &mt2701_i2s_data[i][I2S_IN]; } + component =kzalloc (sizeof (*component),GFP_KERNEL ); +if (!component) +return -ENOMEM ; + + component->regmap = afe->regmap; + afe->mtk_afe_hardware = &mt2701_afe_hardware; afe->memif_fs = mt2701_memif_fs; afe->irq_fs = mt2701_irq_fs;
@@ -1502,7 +1492,7 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) ret =mt2701_init_clock (afe);if (ret) {dev_err (dev,"init clock error\n" ); -return ret; + goto err_init_clock; }platform_set_drvdata (pdev, afe);
@@ -1521,10 +1511,10 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) goto err_platform; } - ret =snd_soc_register_component (&pdev->dev, - &mt2701_afe_pcm_dai_component, - mt2701_afe_pcm_dais, -ARRAY_SIZE (mt2701_afe_pcm_dais)); + ret =snd_soc_add_component (dev, component, + &mt2701_afe_pcm_dai_component, + mt2701_afe_pcm_dais, +ARRAY_SIZE (mt2701_afe_pcm_dais));if (ret) {dev_warn (dev,"err_dai_component\n" ); goto err_dai_component;
@@ -1538,6 +1528,8 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)pm_runtime_put_sync (dev); err_pm_disable:pm_runtime_disable (dev); +err_init_clock: +kfree (component);return ret; }
sound/soc/mediatek/mt2701/mt2701-reg.h +0 -1
@@ -145,5 +145,4 @@#define ASYS_I2S_CON_WIDE_MODE_SET (x) ((x) << 1)#define ASYS_I2S_IN_PHASE_FIX (0x1 << 31) -#define AFE_END_ADDR 0x15e0#endif
Signature · 6 lines
1.9.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 8/12 ASoC: mediatek: modify documentation to adapt subsystem wrapper
In reply to Ryder LeeAs the new audio subsystem wrapper is in place, modify documentation to adapt it.
--- .../devicetree/bindings/sound/mt2701-afe-pcm.txt | 160 +++++++++++---------- 1 file changed, 82 insertions(+), 78 deletions(-)
Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt +82 -78
@@ -2,7 +2,6 @@ Mediatek AFE PCM controller for mt2701 Required properties: - compatible = "mediatek,mt2701-audio"; -- reg: register location and size - interrupts: should contain AFE and ASYS interrupts - interrupt-names: should be "afe" and "asys" - power-domains: should define the power domain
@@ -45,85 +44,90 @@ Required properties: - assigned-clocks-parents: parent of input clocks of assigned clocks. - assigned-clock-rates: list of clock frequencies of assigned clocks. +Must be a subnode of MediaTek Audio Subsystem device tree node. +See ../mfd/mtk-audsys.txt for details about the parent node. + Example: - afe: mt2701-afe-pcm@11220000 { - compatible = "mediatek,mt2701-audio"; - reg = <0 0x11220000 0 0x2000>, - <0 0x112A0000 0 0x20000>; - interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_LOW>, - <GIC_SPI 132 IRQ_TYPE_LEVEL_LOW>; - interrupt-names = "afe", "asys"; - power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; - clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>, - <&topckgen CLK_TOP_AUD_MUX2_SEL>, - <&topckgen CLK_TOP_AUD_K1_SRC_SEL>, - <&topckgen CLK_TOP_AUD_K2_SRC_SEL>, - <&topckgen CLK_TOP_AUD_K3_SRC_SEL>, - <&topckgen CLK_TOP_AUD_K4_SRC_SEL>, - <&topckgen CLK_TOP_AUD_K1_SRC_DIV>, - <&topckgen CLK_TOP_AUD_K2_SRC_DIV>, - <&topckgen CLK_TOP_AUD_K3_SRC_DIV>, - <&topckgen CLK_TOP_AUD_K4_SRC_DIV>, - <&topckgen CLK_TOP_AUD_I2S1_MCLK>, - <&topckgen CLK_TOP_AUD_I2S2_MCLK>, - <&topckgen CLK_TOP_AUD_I2S3_MCLK>, - <&topckgen CLK_TOP_AUD_I2S4_MCLK>, - <&audiosys CLK_AUD_I2SO1>, - <&audiosys CLK_AUD_I2SO2>, - <&audiosys CLK_AUD_I2SO3>, - <&audiosys CLK_AUD_I2SO4>, - <&audiosys CLK_AUD_I2SIN1>, - <&audiosys CLK_AUD_I2SIN2>, - <&audiosys CLK_AUD_I2SIN3>, - <&audiosys CLK_AUD_I2SIN4>, - <&audiosys CLK_AUD_ASRCO1>, - <&audiosys CLK_AUD_ASRCO2>, - <&audiosys CLK_AUD_ASRCO3>, - <&audiosys CLK_AUD_ASRCO4>, - <&audiosys CLK_AUD_AFE>, - <&audiosys CLK_AUD_AFE_CONN>, - <&audiosys CLK_AUD_A1SYS>, - <&audiosys CLK_AUD_A2SYS>, - <&audiosys CLK_AUD_AFE_MRGIF>; + audio-subsystm@11220000 { + compatible = "mediatek,mt2701-audsys-core"; + ... + afe: audio { + compatible = "mediatek,mt2701-audio"; + interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 132 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "afe", "asys"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; + clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>, + <&topckgen CLK_TOP_AUD_MUX2_SEL>, + <&topckgen CLK_TOP_AUD_K1_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K2_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K3_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K4_SRC_SEL>, + <&topckgen CLK_TOP_AUD_K1_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K2_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K3_SRC_DIV>, + <&topckgen CLK_TOP_AUD_K4_SRC_DIV>, + <&topckgen CLK_TOP_AUD_I2S1_MCLK>, + <&topckgen CLK_TOP_AUD_I2S2_MCLK>, + <&topckgen CLK_TOP_AUD_I2S3_MCLK>, + <&topckgen CLK_TOP_AUD_I2S4_MCLK>, + <&audiosys CLK_AUD_I2SO1>, + <&audiosys CLK_AUD_I2SO2>, + <&audiosys CLK_AUD_I2SO3>, + <&audiosys CLK_AUD_I2SO4>, + <&audiosys CLK_AUD_I2SIN1>, + <&audiosys CLK_AUD_I2SIN2>, + <&audiosys CLK_AUD_I2SIN3>, + <&audiosys CLK_AUD_I2SIN4>, + <&audiosys CLK_AUD_ASRCO1>, + <&audiosys CLK_AUD_ASRCO2>, + <&audiosys CLK_AUD_ASRCO3>, + <&audiosys CLK_AUD_ASRCO4>, + <&audiosys CLK_AUD_AFE>, + <&audiosys CLK_AUD_AFE_CONN>, + <&audiosys CLK_AUD_A1SYS>, + <&audiosys CLK_AUD_A2SYS>, + <&audiosys CLK_AUD_AFE_MRGIF>; - clock-names = "top_audio_mux1_sel", - "top_audio_mux2_sel", - "i2s0_src_sel", - "i2s1_src_sel", - "i2s2_src_sel", - "i2s3_src_sel", - "i2s0_src_div", - "i2s1_src_div", - "i2s2_src_div", - "i2s3_src_div", - "i2s0_mclk_en", - "i2s1_mclk_en", - "i2s2_mclk_en", - "i2s3_mclk_en", - "i2so0_hop_ck", - "i2so1_hop_ck", - "i2so2_hop_ck", - "i2so3_hop_ck", - "i2si0_hop_ck", - "i2si1_hop_ck", - "i2si2_hop_ck", - "i2si3_hop_ck", - "asrc0_out_ck", - "asrc1_out_ck", - "asrc2_out_ck", - "asrc3_out_ck", - "audio_afe_pd", - "audio_afe_conn_pd", - "audio_a1sys_pd", - "audio_a2sys_pd", - "audio_mrgif_pd"; + clock-names = "top_audio_mux1_sel", + "top_audio_mux2_sel", + "i2s0_src_sel", + "i2s1_src_sel", + "i2s2_src_sel", + "i2s3_src_sel", + "i2s0_src_div", + "i2s1_src_div", + "i2s2_src_div", + "i2s3_src_div", + "i2s0_mclk_en", + "i2s1_mclk_en", + "i2s2_mclk_en", + "i2s3_mclk_en", + "i2so0_hop_ck", + "i2so1_hop_ck", + "i2so2_hop_ck", + "i2so3_hop_ck", + "i2si0_hop_ck", + "i2si1_hop_ck", + "i2si2_hop_ck", + "i2si3_hop_ck", + "asrc0_out_ck", + "asrc1_out_ck", + "asrc2_out_ck", + "asrc3_out_ck", + "audio_afe_pd", + "audio_afe_conn_pd", + "audio_a1sys_pd", + "audio_a2sys_pd", + "audio_mrgif_pd"; - assigned-clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>, - <&topckgen CLK_TOP_AUD_MUX2_SEL>, - <&topckgen CLK_TOP_AUD_MUX1_DIV>, - <&topckgen CLK_TOP_AUD_MUX2_DIV>; - assigned-clock-parents = <&topckgen CLK_TOP_AUD1PLL_98M>, - <&topckgen CLK_TOP_AUD2PLL_90M>; - assigned-clock-rates = <0>, <0>, <49152000>, <45158400>; + assigned-clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>, + <&topckgen CLK_TOP_AUD_MUX2_SEL>, + <&topckgen CLK_TOP_AUD_MUX1_DIV>, + <&topckgen CLK_TOP_AUD_MUX2_DIV>; + assigned-clock-parents = <&topckgen CLK_TOP_AUD1PLL_98M>, + <&topckgen CLK_TOP_AUD2PLL_90M>; + assigned-clock-rates = <0>, <0>, <49152000>, <45158400>; + }; };
Signature · 1 line
1.9.1
PATCH 9/12 clk: mediatek: move part of mtk_clk_register_gates() to the new function
In reply to Ryder LeeIn some subsystems, the regmap has already been initialized from its parent, so there is no need to map it again. To keep flexible, we move some parts to the new function - mtk_clk_register_num_gates(), and then use it for those subsystems.
--- drivers/clk/mediatek/clk-mtk.c | 26 +++++++++++++++++--------- drivers/clk/mediatek/clk-mtk.h | 4 ++++ 2 files changed, 21 insertions(+), 9 deletions(-)
drivers/clk/mediatek/clk-mtk.c +17 -9
@@ -101,24 +101,16 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, } } -int mtk_clk_register_gates (struct device_node *node, +int mtk_clk_register_num_gates (struct regmap *regmap,const struct mtk_gate *clks,int num,struct clk_onecell_data *clk_data) {int i;struct clk *clk; -struct regmap *regmap;if (!clk_data)return -ENOMEM ; - regmap =syscon_node_to_regmap (node); -if (IS_ERR (regmap)) { -pr_err ("Cannot find regmap for %pOF: %ld\n" , node, -PTR_ERR (regmap)); -return PTR_ERR (regmap); - } -for (i =0 ; i < num; i++) {const struct mtk_gate *gate = &clks[i];
@@ -144,6 +136,22 @@ int mtk_clk_register_gates(struct device_node *node,return 0 ; } +int mtk_clk_register_gates (struct device_node *node, +const struct mtk_gate *clks, +int num,struct clk_onecell_data *clk_data) +{ +struct regmap *regmap; + + regmap =syscon_node_to_regmap (node); +if (IS_ERR (regmap)) { +pr_err ("Cannot find regmap for %pOF: %ld\n" , node, +PTR_ERR (regmap)); +return PTR_ERR (regmap); + } + +return mtk_clk_register_num_gates (regmap, clks, num, clk_data); +} +struct clk *mtk_clk_register_composite (const struct mtk_composite *mc,void __iomem *base,spinlock_t *lock) {
drivers/clk/mediatek/clk-mtk.h +4 -0
@@ -159,6 +159,10 @@ struct mtk_gate {const struct clk_ops *ops; }; +int mtk_clk_register_num_gates (struct regmap *regmap, +const struct mtk_gate *clks,int num, +struct clk_onecell_data *clk_data); +int mtk_clk_register_gates (struct device_node *node,const struct mtk_gate *clks,int num,struct clk_onecell_data *clk_data);
Signature · 1 line
1.9.1
PATCH 10/12 clk: mediatek: switch to use dev_get_regmap() for MT7622 audsys
In reply to Ryder LeeAs the new audsys wrapper driver is in place, switch to use dev_get_regmap() to obtain the regmap from its parent.
This patch also add missing clock data 'CLK_AUDIO_AFE_CONN'.
--- drivers/clk/mediatek/clk-mt7622-aud.c | 11 +++++++++-- include/dt-bindings/clock/mt7622-clk.h | 3 ++- 2 files changed, 11 insertions(+), 3 deletions(-)
drivers/clk/mediatek/clk-mt7622-aud.c +9 -2
@@ -106,6 +106,7 @@GATE_AUDIO1 (CLK_AUDIO_INTDIR ,"audio_intdir" ,"intdir_sel" ,20 ),GATE_AUDIO1 (CLK_AUDIO_A1SYS ,"audio_a1sys" ,"a1sys_hp_sel" ,21 ),GATE_AUDIO1 (CLK_AUDIO_A2SYS ,"audio_a2sys" ,"a2sys_hp_sel" ,22 ), +GATE_AUDIO1 (CLK_AUDIO_AFE_CONN ,"audio_afe_conn" ,"a1sys_hp_sel" ,23 ),/* AUDIO2 */ GATE_AUDIO2 (CLK_AUDIO_UL1 ,"audio_ul1" ,"a1sys_hp_sel" ,0 ), GATE_AUDIO2(CLK_AUDIO_UL2, "audio_ul2", "a1sys_hp_sel", 1),
@@ -141,12 +142,18 @@ static int clk_mt7622_audiosys_init(struct platform_device *pdev) {struct clk_onecell_data *clk_data;struct device_node *node = pdev->dev.of_node; +struct regmap *regmap;int r; clk_data =mtk_alloc_clk_data (CLK_AUDIO_NR_CLK ); -mtk_clk_register_gates (node, audio_clks,ARRAY_SIZE (audio_clks), - clk_data); +/* Obtain the regmap from parent - audsys wrapper */ + regmap =dev_get_regmap (pdev->dev.parent,NULL ); +if (!regmap) +return -ENODEV ; + +mtk_clk_register_num_gates (regmap, audio_clks,ARRAY_SIZE (audio_clks), + clk_data); r =of_clk_add_provider (node, of_clk_src_onecell_get, clk_data);if (r)
include/dt-bindings/clock/mt7622-clk.h +2 -1
@@ -235,7 +235,8 @@#define CLK_AUDIO_MEM_ASRC3 43#define CLK_AUDIO_MEM_ASRC4 44#define CLK_AUDIO_MEM_ASRC5 45 -#define CLK_AUDIO_NR_CLK 46 +#define CLK_AUDIO_AFE_CONN 46 +#define CLK_AUDIO_NR_CLK 47/* SSUSBSYS */
Signature · 1 line
1.9.1
Rob Herring
maintainerRe: [PATCH 10/12] clk: mediatek: switch to use dev_get_regmap() for MT7622 audsys
Quoted 4 lines · Ryder Lee
As the new audsys wrapper driver is in place, switch to use
dev_get_regmap()to obtain the regmap from its parent.This patch also add missing clock data '
CLK_AUDIO_AFE_CONN'.
"also" is a keyword for this belonging in a separate patch.
Quoted 6 lines
Signed-off-by Ryder Lee <[email protected]>--- drivers/clk/mediatek/clk-mt7622-aud.c | 11 +++++++++-- include/dt-bindings/clock/mt7622-clk.h | 3 ++- 2 files changed, 11 insertions(+), 3 deletions(-)
PATCH 11/12 clk: mediatek: add audsys support for MT2701
In reply to Ryder LeeAdd clock driver support for MT2701 audio subsystem.
--- drivers/clk/mediatek/Kconfig | 6 ++ drivers/clk/mediatek/Makefile | 1 + drivers/clk/mediatek/clk-mt2701-aud.c | 180 ++++++++++++++++++++++++++++++++++ 3 files changed, 187 insertions(+) create mode 100644 drivers/clk/mediatek/clk-mt2701-aud.c
drivers/clk/mediatek/Kconfig +6 -0
@@ -50,6 +50,12 @@ config COMMON_CLK_MT2701_BDPSYS ---help--- This driver supports Mediatek MT2701 bdpsys clocks. +config COMMON_CLK_MT2701_AUDSYS + bool "Clock driver for Mediatek MT2701 audsys" + depends on COMMON_CLK_MT2701 + ---help--- + This driver supports Mediatek MT2701 audsys clocks. + config COMMON_CLK_MT2712 bool "Clock driver for Mediatek MT2712" depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
drivers/clk/mediatek/Makefile +1 -0
@@ -7,6 +7,7 @@ obj-$(CONFIG_COMMON_CLK_MT6797_MMSYS) += clk-mt6797-mm.o obj-$(CONFIG_COMMON_CLK_MT6797_VDECSYS) += clk-mt6797-vdec.o obj-$(CONFIG_COMMON_CLK_MT6797_VENCSYS) += clk-mt6797-venc.o obj-$(CONFIG_COMMON_CLK_MT2701) += clk-mt2701.o +obj-$(CONFIG_COMMON_CLK_MT2701_AUDSYS) += clk-mt2701-aud.o obj-$(CONFIG_COMMON_CLK_MT2701_BDPSYS) += clk-mt2701-bdp.o obj-$(CONFIG_COMMON_CLK_MT2701_ETHSYS) += clk-mt2701-eth.o obj-$(CONFIG_COMMON_CLK_MT2701_HIFSYS) += clk-mt2701-hif.o
drivers/clk/mediatek/clk-mt2701-aud.c new file +180 -0
180 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH 12/12 dt-bindings: clock: mediatek: update audsys bindings to adapt the wrapper
In reply to Ryder LeeUpdate the DT binding to adapt the new audio subsystem wrapper. Also add a compatible string for MT2701.
--- .../bindings/arm/mediatek/mediatek,audsys.txt | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt +13 -6
@@ -6,17 +6,24 @@ The MediaTek AUDSYS controller provides various clocks to the system. Required Properties: - compatible: Should be one of: - - "mediatek,mt7622-audsys", "syscon" + - "mediatek,mt2701-audsys", + - "mediatek,mt7622-audsys", - #clock-cells: Must be 1 The AUDSYS controller uses the common clk binding from Documentation/devicetree/bindings/clock/clock-bindings.txt The available clocks are defined in dt-bindings/clock/mt*-clk.h. +Must be a subnode of MediaTek audio subsystem device tree node. +See ../mfd/mtk-audsys.txt for details about the parent node. + Example: -audsys: audsys at 11220000 { - compatible = "mediatek,mt7622-audsys", "syscon"; - reg = <0 0x11220000 0 0x1000>; - #clock-cells = <1>; -}; + audio-subsystm at 11220000 { + compatible = "mediatek,mt2701-audsys-core"; + ... + audsys: clock { + compatible = "mediatek,mt2701-audsys"; + #clock-cells = <1>; + }; + };
Signature · 1 line
1.9.1