audio: auge: fix the samesource spdif clock recovery issue [1/1]
authorJian Xu <jian.xu@amlogic.com>
Sun, 26 May 2019 07:05:05 +0000 (15:05 +0800)
committerNick Xie <nick@khadas.com>
Mon, 5 Aug 2019 06:34:44 +0000 (14:34 +0800)
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 <jian.xu@amlogic.com>
MAINTAINERS
sound/soc/amlogic/auge/spdif.c
sound/soc/amlogic/auge/spdif.h [new file with mode: 0644]
sound/soc/amlogic/auge/tdm.c

index 924b9f6..5dce353 100644 (file)
@@ -13802,6 +13802,7 @@ ANLOGIC AUDIO
 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>
 F: arch/arm64/boot/dts/amlogic/*
 F: arch/arm/boot/dts/amlogic/*
 F: arch/arm64/configs/meson64_defconfig
index 852c3f2..27ede5e 100644 (file)
@@ -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)
 {
@@ -749,6 +766,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);
@@ -793,6 +811,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);
@@ -1327,8 +1346,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) {
@@ -1598,7 +1622,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 (file)
index 0000000..66e36d8
--- /dev/null
@@ -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
index e4af0e5..a37ad3d 100644 (file)
@@ -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)) {