From fb3d6d24744d00eddc2ace18a851977b1b2acd9a Mon Sep 17 00:00:00 2001 From: Jian Xu Date: Sun, 26 May 2019 15:05:05 +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: u212 Change-Id: I2a847273ab0b920f6cee691ee0db006709ffde2a Signed-off-by: Jian Xu --- MAINTAINERS | 1 + sound/soc/amlogic/auge/spdif.c | 26 +++++++++++++++++++++++++- sound/soc/amlogic/auge/spdif.h | 32 ++++++++++++++++++++++++++++++++ sound/soc/amlogic/auge/tdm.c | 7 +++++++ 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 sound/soc/amlogic/auge/spdif.h diff --git a/MAINTAINERS b/MAINTAINERS index 4be3220..ea44e65 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13805,6 +13805,7 @@ ANLOGIC AUDIO DRIVER 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 acc4822..7663244b 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); @@ -115,6 +117,7 @@ struct aml_spdif { bool mute; enum SPDIF_SRC spdifin_src; int clk_tuning_enable; + bool on; }; static const struct snd_pcm_hardware aml_spdif_hardware = { @@ -322,6 +325,20 @@ int spdifin_source_set_enum( return 0; } + +int spdif_set_audio_clk(int id, + struct clk *clk_src, int rate, int same) +{ + 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); + return 0; +} + static int spdif_clk_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -750,6 +767,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); @@ -794,6 +812,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); @@ -1329,8 +1348,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) { @@ -1600,7 +1624,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 new file mode 100644 index 0000000..66e36d8 --- /dev/null +++ b/sound/soc/amlogic/auge/spdif.h @@ -0,0 +1,32 @@ +/* + * sound/soc/amlogic/auge/spdif.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef __AML_SPDIF_H__ +#define __AML_SPDIF_H__ +#include +#if 0 +enum SPDIF_ID { + SPDIF_A, + SPDIF_B, + SPDIF_ID_CNT +}; +#endif + +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 e4af0e5..a37ad3d 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__*/ @@ -489,6 +491,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 */ @@ -954,6 +959,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, @@ -969,6 +975,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)) { -- 2.7.4