From 2e16669748ebc43e2b09416ea6d619f25c98c7fc Mon Sep 17 00:00:00 2001 From: Jian Xu Date: Wed, 29 May 2019 20:06:35 +0800 Subject: [PATCH] audio: auge: fix the samesource spdif clock recovery issue [1/1] PD#SWPL-3667 Problem: after playback none-48K raw audio, the spdif clock is not recoved to 48K when tdm/spdif same source Solution: use the same clock source as tdm if samesource and config that when tdm hardware prepare. Verify: AC213 Change-Id: I0d5dc5f51b5de14d155902e0fe72c293071c93ec Signed-off-by: Jian Xu --- MAINTAINERS | 1 + sound/soc/amlogic/auge/spdif.c | 35 ++++++++++++++++++++++++++++++++-- sound/soc/amlogic/auge/spdif.h | 7 ++++--- sound/soc/amlogic/auge/tdm.c | 10 ++++++++++ 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 5f9b7fae53f4..6afb67d53bde 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13810,6 +13810,7 @@ ANLOGIC AUDIO M: Xing Wang M: Zhe Wang M: Shuai Li +M: Jian Xu F: arch/arm64/boot/dts/amlogic/* F: arch/arm/boot/dts/amlogic/* F: arch/arm64/configs/meson64_defconfig diff --git a/sound/soc/amlogic/auge/spdif.c b/sound/soc/amlogic/auge/spdif.c index f328c17d30d2..99f48f1cc456 100644 --- a/sound/soc/amlogic/auge/spdif.c +++ b/sound/soc/amlogic/auge/spdif.c @@ -38,6 +38,7 @@ #include "spdif_match_table.c" #include "resample.h" #include "resample_hw.h" +#include "spdif.h" #define DRV_NAME "snd_spdif" @@ -48,6 +49,7 @@ /*#define __SPDIFIN_INSERT_CHNUM__*/ /*#define __SPDIFIN_AUDIO_TYPE_HW__*/ +struct aml_spdif *spdif_priv[2]; static int aml_dai_set_spdif_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir); @@ -114,6 +116,8 @@ struct aml_spdif { /* mixer control vals */ bool mute; enum SPDIF_SRC spdifin_src; + int clk_tuning_enable; + bool on; }; static const struct snd_pcm_hardware aml_spdif_hardware = { @@ -377,6 +381,27 @@ int spdifin_source_set_enum( return 0; } + +int spdif_set_audio_clk(int id, + struct clk *clk_src, int rate, int same) +{ + int ret = 0; + + if (spdif_priv[id]->on && same) { + pr_debug("spdif priority"); + return 0; + } + + clk_set_parent(spdif_priv[id]->clk_spdifout, clk_src); + clk_set_rate(spdif_priv[id]->clk_spdifout, rate); + ret = clk_prepare_enable(spdif_priv[id]->clk_spdifout); + if (ret) { + pr_err("%s Can't enable clk_spdifout clock,ret %d\n", + __func__, ret); + } + return 0; +} + static int spdif_clk_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -803,6 +828,7 @@ static int aml_spdif_open(struct snd_pcm_substream *substream) snd_soc_set_runtime_hwparams(substream, &aml_spdif_hardware); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + p_spdif->on = true; p_spdif->fddr = aml_audio_register_frddr(dev, p_spdif->actrl, aml_spdif_ddr_isr, substream, false); @@ -847,6 +873,7 @@ static int aml_spdif_close(struct snd_pcm_substream *substream) pr_info("%s\n", __func__); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + p_spdif->on = false; aml_audio_unregister_frddr(p_spdif->dev, substream); } else { aml_audio_unregister_toddr(p_spdif->dev, substream); @@ -1384,8 +1411,13 @@ static void aml_set_spdifclk(struct aml_spdif *p_spdif) mpll_freq = p_spdif->sysclk_freq * 58 / 2; /* 96k */ #endif clk_set_rate(p_spdif->sysclk, mpll_freq); + /* clk_set_rate(p_spdif->clk_spdifout, p_spdif->sysclk_freq); + */ + spdif_set_audio_clk(p_spdif->id, + p_spdif->sysclk, + p_spdif->sysclk_freq, 0); ret = clk_prepare_enable(p_spdif->sysclk); if (ret) { @@ -1630,7 +1662,6 @@ static int aml_spdif_platform_probe(struct platform_device *pdev) ret = aml_spdif_parse_of(pdev); if (ret) return -EINVAL; - if (aml_spdif->clk_cont) spdifout_play_with_zerodata(aml_spdif->id, spdif_reenable); @@ -1640,7 +1671,7 @@ static int aml_spdif_platform_probe(struct platform_device *pdev) dev_err(dev, "devm_snd_soc_register_component failed\n"); return ret; } - + spdif_priv[aml_spdif->id] = aml_spdif; pr_info("%s, register soc platform\n", __func__); return devm_snd_soc_register_platform(dev, &aml_spdif_platform); diff --git a/sound/soc/amlogic/auge/spdif.h b/sound/soc/amlogic/auge/spdif.h index d6e6ba0f8af4..66e36d86e43a 100644 --- a/sound/soc/amlogic/auge/spdif.h +++ b/sound/soc/amlogic/auge/spdif.h @@ -18,14 +18,15 @@ #ifndef __AML_SPDIF_H__ #define __AML_SPDIF_H__ #include - +#if 0 enum SPDIF_ID { SPDIF_A, SPDIF_B, SPDIF_ID_CNT }; +#endif -int spdif_set_audio_clk(enum SPDIF_ID id, - struct clk *clk_src, int rate, bool same); +extern int spdif_set_audio_clk(int id, + struct clk *clk_src, int rate, int same); #endif diff --git a/sound/soc/amlogic/auge/tdm.c b/sound/soc/amlogic/auge/tdm.c index 67fc1211b1e1..6bb974c0c6cb 100644 --- a/sound/soc/amlogic/auge/tdm.c +++ b/sound/soc/amlogic/auge/tdm.c @@ -43,6 +43,8 @@ #include "spdif_hw.h" #include "tdm_match_table.c" #include "effects_v2.h" +#include "spdif.h" + /*#define __PTM_TDM_CLK__*/ @@ -112,6 +114,9 @@ struct aml_tdm { /* tdmin_lb src sel */ int tdmin_lb_src; + int start_clk_enable; + int clk_tuning_enable; + int last_rate; }; static const struct snd_pcm_hardware aml_tdm_hardware = { @@ -491,6 +496,9 @@ static int aml_dai_tdm_prepare(struct snd_pcm_substream *substream, fr, p_tdm->samesource_sel, p_tdm->lane_ss, p_tdm->chipinfo->reset_reg_offset); + /* sharebuffer default uses spdif_a */ + spdif_set_audio_clk(p_tdm->samesource_sel - 3, + p_tdm->clk, runtime->rate*128, 1); } /* i2s source to hdmix */ @@ -963,6 +971,7 @@ static int aml_dai_tdm_hw_params(struct snd_pcm_substream *substream, && (aml_check_sharebuffer_valid(p_tdm->fddr, p_tdm->samesource_sel)) && p_tdm->en_share) { +#if 0 int mux = 0, ratio = 0; sharebuffer_get_mclk_fs_ratio(p_tdm->samesource_sel, @@ -978,6 +987,7 @@ static int aml_dai_tdm_hw_params(struct snd_pcm_substream *substream, rate * ratio); clk_prepare_enable(p_tdm->samesrc_clk); } +#endif } if (!p_tdm->contns_clk && !IS_ERR(p_tdm->mclk)) {