author | Jian Xu <jian.xu@amlogic.com> | 2019-05-29 12:06:35 (GMT) |
---|---|---|
committer | Jianxin Pan <jianxin.pan@amlogic.com> | 2019-05-31 04:57:56 (GMT) |
commit | 8302596dc383643f5ad18b718f7ae1a46f8e344c (patch) | |
tree | 92061922bb5ef68b4add6eeafe02595b9a2a6195 | |
parent | 42644bc4ab6114a817530af39366a0a7e7fa72d6 (diff) | |
download | common-8302596dc383643f5ad18b718f7ae1a46f8e344c.zip common-8302596dc383643f5ad18b718f7ae1a46f8e344c.tar.gz common-8302596dc383643f5ad18b718f7ae1a46f8e344c.tar.bz2 |
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 <jian.xu@amlogic.com>
-rw-r--r-- | MAINTAINERS | 1 | ||||
-rw-r--r-- | sound/soc/amlogic/auge/spdif.c | 34 | ||||
-rw-r--r-- | sound/soc/amlogic/auge/spdif.h | 32 | ||||
-rw-r--r-- | sound/soc/amlogic/auge/tdm.c | 8 |
4 files changed, 72 insertions, 3 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 48f467e..ea44e65 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13806,7 +13806,6 @@ M: Xing Wang <xing.wang@amlogic.com> M: Zhe Wang <Zhe.Wang@amlogic.com> M: Shuai Li <shuai.li@amlogic.com> M: Jian Xu <jian.xu@amlogic.com> -M: Jian Xu <jian.xu@amlogic.com> 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..fa3709b 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,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) { @@ -750,6 +774,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 +819,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 +1355,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) { @@ -1590,7 +1621,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); @@ -1600,7 +1630,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 --- a/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 <linux/clk.h> +#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..09fa586 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,7 @@ struct aml_tdm { int tdmin_lb_src; int start_clk_enable; int clk_tuning_enable; + int last_rate; }; static const struct snd_pcm_hardware aml_tdm_hardware = { @@ -489,6 +492,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 +960,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 +976,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)) { |