atv_demod: Fix ATV audio output noise when switching channels to play [1/1]
authornengwen.chen <nengwen.chen@amlogic.com>
Mon, 11 Mar 2019 06:00:31 +0000 (14:00 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Thu, 14 Mar 2019 11:26:49 +0000 (03:26 -0800)
PD#SWPL-2297, PD#SWPL-5450, PD#TV-2311

Problem:
Fix ATV audio output noise when switching channels to play.

Solution:
1.Add the judgment of SNR to prevent the weak signal
  from entering the OV mode.
2.Wait for the signal to be completely stable before OV detection.
3.OV detection is turned off by default,
  and will be turned on again when non-standard signals are encountered.
4.The OV detection moves from afc timer to monitor.
5.Optimize detection of A2/FM.
6.atv demod ver: V2.08.

Verify:
verified by x301

Change-Id: I3064230472ce51e1192a2d08ef6cc6f4ba10abaa
Signed-off-by: nengwen.chen <nengwen.chen@amlogic.com>
drivers/amlogic/atv_demod/atv_demod_afc.c
drivers/amlogic/atv_demod/atv_demod_debug.c
drivers/amlogic/atv_demod/atv_demod_driver.c
drivers/amlogic/atv_demod/atv_demod_monitor.c
drivers/amlogic/atv_demod/atv_demod_monitor.h
drivers/amlogic/atv_demod/atvauddemod_func.c
drivers/amlogic/atv_demod/atvdemod_func.c

index b2ffce0..3cf5d95 100644 (file)
@@ -107,7 +107,6 @@ void atv_demod_afc_do_work(struct work_struct *work)
        int freq_offset = 100;
        int tmp = 0;
        int field_lock = 0;
-       static int audio_overmodul;
 
        if (afc->state == false)
                return;
@@ -125,13 +124,6 @@ void atv_demod_afc_do_work(struct work_struct *work)
 
        afc->pre_step = 0;
 
-       if (afc->lock) {
-               if (0 == ((audio_overmodul++) % 10)) {
-                       aml_audio_overmodulation(1);
-                       audio_overmodul = 0;
-               }
-       }
-
        retrieve_frequency_offset(&freq_offset);
 
        if (++(afc->wave_cnt) <= afc_wave_cnt) {/*40ms*/
index 6535e09..284eeb8 100644 (file)
@@ -87,6 +87,7 @@
        DEBUGFS_CREATE_NODE(atvdemod_timer_delay2, 0640, dentry, u32)\
        DEBUGFS_CREATE_NODE(atvdemod_mixer_tune_en, 0640, dentry, bool)\
        DEBUGFS_CREATE_NODE(atvdemod_overmodulated_en, 0640, dentry, bool)\
+       DEBUGFS_CREATE_NODE(atv_audio_overmodulated_en, 0640, dentry, bool)\
        DEBUGFS_CREATE_NODE(audio_thd_en, 0640, dentry, bool)\
        DEBUGFS_CREATE_NODE(pwm_kp, 0640, dentry, u32)\
        DEBUGFS_CREATE_NODE(audio_gain_val, 0640, dentry, u32)\
        DEBUGFS_CREATE_FILE(sum2_thd_h, 0640, dentry, fops, int)\
        DEBUGFS_CREATE_FILE(sum2_thd_l, 0640, dentry, fops, int)\
        DEBUGFS_CREATE_FILE(afc_default, 0640, dentry, fops, int)\
+       DEBUGFS_CREATE_FILE(snr_threshold, 0640, dentry, fops, int)\
 }
 
 
@@ -131,6 +133,7 @@ DEBUGFS_DENTRY_DEFINE(sum1_thd_l);
 DEBUGFS_DENTRY_DEFINE(sum2_thd_h);
 DEBUGFS_DENTRY_DEFINE(sum2_thd_l);
 DEBUGFS_DENTRY_DEFINE(afc_default);
+DEBUGFS_DENTRY_DEFINE(snr_threshold);
 
 struct dentry_value *debugfs_dentry[] = {
        DEBUGFS_DENTRY_VALUE(non_std_thld_4c_h),
@@ -142,6 +145,7 @@ struct dentry_value *debugfs_dentry[] = {
        DEBUGFS_DENTRY_VALUE(sum2_thd_h),
        DEBUGFS_DENTRY_VALUE(sum2_thd_l),
        DEBUGFS_DENTRY_VALUE(afc_default),
+       DEBUGFS_DENTRY_VALUE(snr_threshold),
 };
 
 static int debugfs_open(struct inode *node, struct file *file)
index 8ef1a93..c9da1c2 100644 (file)
@@ -45,7 +45,7 @@
 #include "atvauddemod_func.h"
 
 
-#define AMLATVDEMOD_VER "V2.07"
+#define AMLATVDEMOD_VER "V2.08"
 
 struct aml_atvdemod_device *amlatvdemod_devp;
 
index 0ebc929..070a667 100644 (file)
@@ -29,6 +29,7 @@ static DEFINE_MUTEX(monitor_mutex);
 
 bool atvdemod_mixer_tune_en;
 bool atvdemod_overmodulated_en;
+bool atv_audio_overmodulated_en;
 bool audio_det_en;
 bool atvdemod_det_snr_en = true;
 bool audio_thd_en = true;
@@ -53,8 +54,12 @@ static void atv_demod_monitor_do_work(struct work_struct *work)
 
        retrieve_vpll_carrier_lock(&vpll_lock);
        retrieve_vpll_carrier_line_lock(&line_lock);
-       if ((vpll_lock != 0) || (line_lock != 0))
+       if ((vpll_lock != 0) || (line_lock != 0)) {
+               monitor->lock_cnt = 0;
                return;
+       }
+
+       monitor->lock_cnt++;
 
        if (atvdemod_mixer_tune_en)
                atvdemod_mixer_tune();
@@ -62,6 +67,11 @@ static void atv_demod_monitor_do_work(struct work_struct *work)
        if (atvdemod_overmodulated_en)
                atvdemod_video_overmodulated();
 
+       if (atv_audio_overmodulated_en) {
+               if (monitor->lock_cnt % 10 == 0)
+                       aml_audio_overmodulation(1);
+       }
+
        if (atvdemod_det_snr_en)
                atvdemod_det_snr_serice();
 
@@ -112,6 +122,7 @@ static void atv_demod_monitor_enable(struct atv_demod_monitor *monitor)
                                ATVDEMOD_INTERVAL * atvdemod_timer_delay;
                add_timer(&monitor->timer);
                monitor->state = true;
+               monitor->lock_cnt = 0;
        }
 
        mutex_unlock(&monitor->mtx);
@@ -143,6 +154,7 @@ void atv_demod_monitor_init(struct atv_demod_monitor *monitor)
 
        monitor->state = false;
        monitor->lock = false;
+       monitor->lock_cnt = 0;
        monitor->disable = atv_demod_monitor_disable;
        monitor->enable = atv_demod_monitor_enable;
 
index b9c1e6a..95c5a2b 100644 (file)
@@ -34,6 +34,8 @@ struct atv_demod_monitor {
        bool state;
        bool lock;
 
+       unsigned int lock_cnt;
+
        void (*disable)(struct atv_demod_monitor *monitor);
        void (*enable)(struct atv_demod_monitor *monitor);
 };
index 8c16833..4331447 100644 (file)
@@ -48,7 +48,7 @@ unsigned int audio_thd_threshold2 = 0xf00;
 
 unsigned int audio_a2_auto = 1;
 unsigned int audio_a2_power_threshold = 0x1800;
-unsigned int audio_a2_carrier_report = 0x600;
+unsigned int audio_a2_carrier_report = 0xc00;
 
 static int last_nicam_lock = -1;
 static int last_nicam_mono_flag = -1;
@@ -392,7 +392,9 @@ void set_a2k(void)
        adec_wr_reg(ADDR_LPR_GAIN_ADJ, 0x3e0);
 
        adec_wr_reg(ADDR_LPR_COMP_CTRL, 0x010);
-       adec_wr_reg(ADDR_IIR_SPEED_CTRL, 0xd65d7f7f);
+       adec_wr_reg(ADDR_IIR_SPEED_CTRL, 0xff5d7f7f/*0xd65d7f7f*/);
+       adec_wr_reg(STEREO_DET_THD, 0x4000);
+       adec_wr_reg(DUAL_DET_THD, 0x4000);
 
        adec_wr_reg((ADDR_SEL_CTRL), 0x1000);
 }
@@ -428,7 +430,9 @@ void set_a2g(void)
        adec_wr_reg(ADDR_LPR_GAIN_ADJ, 0x3e0);
 
        adec_wr_reg(ADDR_LPR_COMP_CTRL, 0x010);
-       adec_wr_reg(ADDR_IIR_SPEED_CTRL, 0xd65d7f7f);
+       adec_wr_reg(ADDR_IIR_SPEED_CTRL, 0xff5d7f7f/*0xd65d7f7f*/);
+       adec_wr_reg(STEREO_DET_THD, 0x4000);
+       adec_wr_reg(DUAL_DET_THD, 0x4000);
 }
 
 void set_a2bg(void)
@@ -462,7 +466,9 @@ void set_a2bg(void)
        adec_wr_reg(ADDR_LPR_GAIN_ADJ, 0x3e0);
 
        adec_wr_reg(ADDR_LPR_COMP_CTRL, 0x010);
-       adec_wr_reg(ADDR_IIR_SPEED_CTRL, 0xd65d7f7f);
+       adec_wr_reg(ADDR_IIR_SPEED_CTRL, 0xff5d7f7f/*0xd65d7f7f*/);
+       adec_wr_reg(STEREO_DET_THD, 0x4000);
+       adec_wr_reg(DUAL_DET_THD, 0x4000);
 }
 
 void set_a2dk1(void)
@@ -496,7 +502,9 @@ void set_a2dk1(void)
        adec_wr_reg(ADDR_LPR_GAIN_ADJ, 0x3e0);
 
        adec_wr_reg(ADDR_LPR_COMP_CTRL, 0x010);
-       adec_wr_reg(ADDR_IIR_SPEED_CTRL, 0xd65d7f7f);
+       adec_wr_reg(ADDR_IIR_SPEED_CTRL, 0xff5d7f7f/*0xd65d7f7f*/);
+       adec_wr_reg(STEREO_DET_THD, 0x4000);
+       adec_wr_reg(DUAL_DET_THD, 0x4000);
 }
 
 void set_a2dk2(void)
@@ -530,7 +538,9 @@ void set_a2dk2(void)
        adec_wr_reg(ADDR_LPR_GAIN_ADJ, 0x3e0);
 
        adec_wr_reg(ADDR_LPR_COMP_CTRL, 0x010);
-       adec_wr_reg(ADDR_IIR_SPEED_CTRL, 0xd65d7f7f);
+       adec_wr_reg(ADDR_IIR_SPEED_CTRL, 0xff5d7f7f/*0xd65d7f7f*/);
+       adec_wr_reg(STEREO_DET_THD, 0x4000);
+       adec_wr_reg(DUAL_DET_THD, 0x4000);
 }
 
 void set_a2dk3(void)
@@ -564,7 +574,9 @@ void set_a2dk3(void)
        adec_wr_reg(ADDR_LPR_GAIN_ADJ, 0x3e0);
 
        adec_wr_reg(ADDR_LPR_COMP_CTRL, 0x010);
-       adec_wr_reg(ADDR_IIR_SPEED_CTRL, 0xd65d7f7f);
+       adec_wr_reg(ADDR_IIR_SPEED_CTRL, 0xff5d7f7f/*0xd65d7f7f*/);
+       adec_wr_reg(STEREO_DET_THD, 0x4000);
+       adec_wr_reg(DUAL_DET_THD, 0x4000);
 }
 
 void set_eiaj(void)
@@ -903,13 +915,15 @@ void update_car_power_measure(int *sc1_power, int *sc2_power)
 
 void update_a2_eiaj_mode(int auto_en, int *stereo_flag, int *dual_flag)
 {
-       uint32_t reg_value;
-       uint32_t stereo_power, dual_power;
+       uint32_t reg_value = 0;
+       uint32_t stereo_power = 0, dual_power = 0;
 
        msleep(a2_detect_delay);
 
        if (auto_en) {
                reg_value = adec_rd_reg(CARRIER_MAG_REPORT);
+               pr_info("%s CARRIER_MAG_REPORT: 0x%x [threshold: 0x%x].\n",
+                               __func__, reg_value, audio_a2_carrier_report);
                if (((reg_value >> 16) & 0xffff) < audio_a2_carrier_report) {
                        *stereo_flag = 0;
                        *dual_flag = 0;
@@ -920,6 +934,8 @@ void update_a2_eiaj_mode(int auto_en, int *stereo_flag, int *dual_flag)
                }
        } else {
                reg_value = adec_rd_reg(POWER_REPORT);
+               pr_info("%s POWER_REPORT: 0x%x [threshold: 0x%x].\n",
+                               __func__, reg_value, audio_a2_power_threshold);
                stereo_power = reg_value & 0xffff;
                dual_power = (reg_value >> 16) & 0xffff;
 
index e667f2a..efb7378 100644 (file)
@@ -66,6 +66,7 @@ unsigned int if_freq = 4250000;       /*PAL-DK:3250000;NTSC-M:4250000*/
 unsigned int if_inv;
 
 int afc_default = CARR_AFC_DEFAULT_VAL;
+int snr_threshold = 30;
 
 
 /*
@@ -2434,6 +2435,10 @@ void aml_audio_overmodulation(int enable)
        unsigned int reg = 0;
        u32 Broadcast_Standard = broad_std;
 
+       /* False entry on weak signal */
+       if (atvdemod_get_snr() < snr_threshold)
+               return;
+
        if (enable && Broadcast_Standard ==
                AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK) {
                tmp_v = atv_dmd_rd_long(APB_BLOCK_ADDR_SIF_STG_2, 0x28);