avsync: spdif: fix the avsync for ms12 [1/4]
authorXiaoming Sui <xiaoming.sui@amlogic.com>
Mon, 15 Apr 2019 12:38:47 +0000 (20:38 +0800)
committerNick Xie <nick@khadas.com>
Mon, 5 Aug 2019 06:18:10 +0000 (14:18 +0800)
PD#SWPL-5837

Problem:
dtv is out of avsync when dolby ms12 certificate

Solution:
when the audio is played, recalculate the apts to sync
pcrsrc when pcrmaster.

Verify:
X301

Change-Id: I199383aa1c0de1b4f0ec646d9d066910b3bb2b42
Signed-off-by: Xiaoming Sui <xiaoming.sui@amlogic.com>
avsync: tsync: fix the avsync for ms12 [3/4]

PD#SWPL-5837

Problem:
dtv is out of avsync when dolby ms12 certificate

Solution:
when the audio is played, recalculate the apts to sync
pcrsrc when pcrmaster.

Verify:
X301

Change-Id: Ia121e57ad69c5b0d211e14bf3a61f165457e54c7
Signed-off-by: Xiaoming Sui <xiaoming.sui@amlogic.com>
drivers/amlogic/media/frame_sync/timestamp.c
drivers/amlogic/media/frame_sync/tsync.c
include/linux/amlogic/media/frame_sync/tsync.h
sound/soc/amlogic/auge/spdif.c

index a6076d5..03e3fe9 100644 (file)
@@ -136,6 +136,19 @@ u32 timestamp_pcrscr_get(void)
 }
 EXPORT_SYMBOL(timestamp_pcrscr_get);
 
+void timestamp_set_pcrlatency(u32 latency)
+{
+       if (latency < 500 * 90)
+               pcrscr_lantcy = latency;
+}
+EXPORT_SYMBOL(timestamp_set_pcrlatency);
+
+u32 timestamp_get_pcrlatency(void)
+{
+       return pcrscr_lantcy;
+}
+EXPORT_SYMBOL(timestamp_get_pcrlatency);
+
 u32 timestamp_tsdemux_pcr_get(void)
 {
        if (tsdemux_pcrscr_get_cb)
index 98192bf..c6a9b41 100644 (file)
@@ -1999,6 +1999,25 @@ static ssize_t show_startsync_mode(struct class *class,
        return sprintf(buf, "0x%x\n", tsync_get_startsync_mode());
 }
 
+static ssize_t show_latency(struct class *class,
+               struct class_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%u\n", timestamp_get_pcrlatency());
+}
+
+static ssize_t store_latency(struct class *class,
+       struct class_attribute *attr,
+       const char *buf, size_t size)
+{
+       unsigned int latency = 0;
+       ssize_t r;
+
+       r = kstrtoint(buf, 0, &latency);
+       if (r != 0)
+               return -EINVAL;
+       timestamp_set_pcrlatency(latency);
+       return size;
+}
 
 static ssize_t show_apts_lookup(struct class *class,
        struct class_attribute *attrr, char *buf)
@@ -2088,6 +2107,7 @@ static struct class_attribute tsync_class_attrs[] = {
        NULL),
        __ATTR(checkin_firstapts, 0644, show_checkin_firstapts,
        NULL),
+       __ATTR(pts_latency, 0664, show_latency, store_latency),
        __ATTR_NULL
 };
 
index 2194d6a..edf83a7 100644 (file)
@@ -157,6 +157,9 @@ extern int tsync_set_av_threshold_max(int max);
 
 extern void set_pts_realign(void);
 
+extern void timestamp_set_pcrlatency(u32 latency);
+extern u32 timestamp_get_pcrlatency(void);
+
 static inline u32 tsync_vpts_discontinuity_margin(void)
 {
        return tsync_get_av_threshold_min();
index 11066d7..54d4b3e 100644 (file)
@@ -338,19 +338,35 @@ static int spdif_clk_set(struct snd_kcontrol *kcontrol,
 {
        struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
        struct aml_spdif *p_spdif = snd_soc_dai_get_drvdata(cpu_dai);
+       unsigned int mpll_freq = 0;
+       int ret;
 
        int sysclk = p_spdif->sysclk_freq;
        int value = ucontrol->value.enumerated.item[0];
-
        if (value > 2000000 || value < 0) {
                pr_err("Fine spdif sysclk setting range(0~2000000), %d\n",
                                value);
                return 0;
        }
-       sysclk += (value - 1000000);
-
-       aml_dai_set_spdif_sysclk(cpu_dai, 0, sysclk, 0);
-
+       value = value - 1000000;
+       sysclk += value;
+       /* pr_info("spdif_set %d to %d,diff %d\n",
+        * p_spdif->sysclk_freq,sysclk,value);
+        */
+       mpll_freq = sysclk * 4;
+       p_spdif->sysclk_freq = sysclk;
+       clk_set_rate(p_spdif->sysclk, mpll_freq);
+       clk_set_rate(p_spdif->clk_spdifout, p_spdif->sysclk_freq);
+       ret = clk_prepare_enable(p_spdif->sysclk);
+       if (ret) {
+               pr_err("Can't enable pcm sysclk clock: %d\n", ret);
+               return 0;
+       }
+       ret = clk_prepare_enable(p_spdif->clk_spdifout);
+       if (ret) {
+               pr_err("Can't enable clk_spdifout clock: %d\n", ret);
+               return 0;
+       }
        return 0;
 }