From 6dfe8782528f0dc7c1e7832e39cb0e48620c7cff Mon Sep 17 00:00:00 2001 From: Xiaoming Sui Date: Mon, 15 Apr 2019 20:38:47 +0800 Subject: [PATCH] avsync: spdif: fix the avsync for ms12 [1/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: I199383aa1c0de1b4f0ec646d9d066910b3bb2b42 Signed-off-by: Xiaoming Sui 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 --- drivers/amlogic/media/frame_sync/timestamp.c | 13 +++++++++++++ drivers/amlogic/media/frame_sync/tsync.c | 20 ++++++++++++++++++++ include/linux/amlogic/media/frame_sync/tsync.h | 3 +++ sound/soc/amlogic/auge/spdif.c | 26 +++++++++++++++++++++----- 4 files changed, 57 insertions(+), 5 deletions(-) diff --git a/drivers/amlogic/media/frame_sync/timestamp.c b/drivers/amlogic/media/frame_sync/timestamp.c index a6076d5..03e3fe9 100644 --- a/drivers/amlogic/media/frame_sync/timestamp.c +++ b/drivers/amlogic/media/frame_sync/timestamp.c @@ -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) diff --git a/drivers/amlogic/media/frame_sync/tsync.c b/drivers/amlogic/media/frame_sync/tsync.c index 98192bfb..c6a9b41 100644 --- a/drivers/amlogic/media/frame_sync/tsync.c +++ b/drivers/amlogic/media/frame_sync/tsync.c @@ -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 }; diff --git a/include/linux/amlogic/media/frame_sync/tsync.h b/include/linux/amlogic/media/frame_sync/tsync.h index 2194d6a..edf83a7 100644 --- a/include/linux/amlogic/media/frame_sync/tsync.h +++ b/include/linux/amlogic/media/frame_sync/tsync.h @@ -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(); diff --git a/sound/soc/amlogic/auge/spdif.c b/sound/soc/amlogic/auge/spdif.c index 11066d7..54d4b3e 100644 --- a/sound/soc/amlogic/auge/spdif.c +++ b/sound/soc/amlogic/auge/spdif.c @@ -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; } -- 2.7.4