From c12f8957d441e99d3c037dfe1f36029f55421fe3 Mon Sep 17 00:00:00 2001 From: "nengwen.chen" Date: Mon, 10 Jun 2019 20:04:56 +0800 Subject: [PATCH] atv_demod: fix atv non standard signal audio handle [1/1] PD#TV-6044, PD#TV-6047 Problem: ATV sound output has noise when input non standard signal. Solution: 1.fix atv non standard signal audio handle. 2.remove atv audio source selection in audio module. 3.atv demod selects audio source according to signal. 4.atv demod version: V2.12. Verify: Verified by x301 Change-Id: Ie0fce492f1ce7f5a5866d8674c95c97ee32452c0 Signed-off-by: nengwen.chen --- drivers/amlogic/atv_demod/atv_demod_debug.c | 1 + drivers/amlogic/atv_demod/atv_demod_driver.c | 2 +- drivers/amlogic/atv_demod/atv_demod_monitor.c | 3 +- drivers/amlogic/atv_demod/atvauddemod_func.c | 37 ++- drivers/amlogic/atv_demod/atvauddemod_func.h | 13 +- drivers/amlogic/atv_demod/atvdemod_func.c | 336 ++++++++++++++------------ drivers/amlogic/atv_demod/atvdemod_func.h | 1 + 7 files changed, 226 insertions(+), 167 deletions(-) diff --git a/drivers/amlogic/atv_demod/atv_demod_debug.c b/drivers/amlogic/atv_demod/atv_demod_debug.c index 971320e..069d32d 100644 --- a/drivers/amlogic/atv_demod/atv_demod_debug.c +++ b/drivers/amlogic/atv_demod/atv_demod_debug.c @@ -102,6 +102,7 @@ DEBUGFS_CREATE_NODE(audio_atv_ov, 0640, dentry, u32)\ DEBUGFS_CREATE_NODE(audio_atv_ov_flag, 0640, dentry, u32)\ DEBUGFS_CREATE_NODE(atvdemod_isr_en, 0640, dentry, bool)\ + DEBUGFS_CREATE_NODE(atv_audio_overmodulated_cnt, 0640, dentry, u32)\ } diff --git a/drivers/amlogic/atv_demod/atv_demod_driver.c b/drivers/amlogic/atv_demod/atv_demod_driver.c index df03253..93acb74 100644 --- a/drivers/amlogic/atv_demod/atv_demod_driver.c +++ b/drivers/amlogic/atv_demod/atv_demod_driver.c @@ -45,7 +45,7 @@ #include "atvauddemod_func.h" -#define AMLATVDEMOD_VER "V2.11" +#define AMLATVDEMOD_VER "V2.12" struct aml_atvdemod_device *amlatvdemod_devp; diff --git a/drivers/amlogic/atv_demod/atv_demod_monitor.c b/drivers/amlogic/atv_demod/atv_demod_monitor.c index ae8b458..4969acb 100644 --- a/drivers/amlogic/atv_demod/atv_demod_monitor.c +++ b/drivers/amlogic/atv_demod/atv_demod_monitor.c @@ -30,6 +30,7 @@ static DEFINE_MUTEX(monitor_mutex); bool atvdemod_mixer_tune_en; bool atvdemod_overmodulated_en; bool atv_audio_overmodulated_en; +unsigned int atv_audio_overmodulated_cnt = 1; bool audio_det_en; bool atvdemod_det_snr_en = true; bool audio_thd_en; @@ -68,7 +69,7 @@ static void atv_demod_monitor_do_work(struct work_struct *work) atvdemod_video_overmodulated(); if (atv_audio_overmodulated_en) { - if (monitor->lock_cnt % 10 == 0) + if (monitor->lock_cnt > atv_audio_overmodulated_cnt) aml_audio_overmodulation(1); } diff --git a/drivers/amlogic/atv_demod/atvauddemod_func.c b/drivers/amlogic/atv_demod/atvauddemod_func.c index 86eb307..38fb8b7 100644 --- a/drivers/amlogic/atv_demod/atvauddemod_func.c +++ b/drivers/amlogic/atv_demod/atvauddemod_func.c @@ -15,9 +15,6 @@ * */ -#ifndef __ATVAUDDEMOD_FUN_H -#define __ATVAUDDEMOD_FUN_H - #include #include #include @@ -1670,6 +1667,7 @@ void set_outputmode_status_init(void) void set_output_left_right_exchange(unsigned int ch) { +#if 0 /* use audio module interface */ unsigned int read = 0; atvaudio_ctrl_read(&read); @@ -1683,6 +1681,37 @@ void set_output_left_right_exchange(unsigned int ch) atvaudio_ctrl_write((read & ~(1 << 2)) | ((ch & 0x01) << 2)); } +#else + +#endif } -#endif /* __ATVAUDDEMOD_FUN_H */ +/* atv audio source select + * 0: select from ATV; + * 1: select from ADEC; + */ +void audio_source_select(int source) +{ +#if 0 /* use audio module interface */ + unsigned int reg = 0; + + atvaudio_ctrl_read(®); + + if (source) { + if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) + atvaudio_ctrl_write(reg | 0x100000);/* bit20 */ + else + atvaudio_ctrl_write(reg | 0x3);/* bit[1-0] */ + } else { + if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) + atvaudio_ctrl_write(reg & (~0x100000));/* bit20 */ + else + atvaudio_ctrl_write(reg & (~0x3));/* bit[1-0] */ + } +#else + if (source) + fratv_src_select(1); + else + fratv_src_select(0); +#endif +} diff --git a/drivers/amlogic/atv_demod/atvauddemod_func.h b/drivers/amlogic/atv_demod/atvauddemod_func.h index c71037f..3e60518 100644 --- a/drivers/amlogic/atv_demod/atvauddemod_func.h +++ b/drivers/amlogic/atv_demod/atvauddemod_func.h @@ -15,11 +15,17 @@ * */ -#ifndef __ATVAUDDEMOD_H_ -#define __ATVAUDDEMOD_H_ +#ifndef __ATV_AUD_DEMOD_H__ +#define __ATV_AUD_DEMOD_H__ #include "aud_demod_reg.h" +#ifdef CONFIG_AMLOGIC_SND_SOC_AUGE +#include "sound/soc/amlogic/auge/audio_utils.h" +#else +#include "sound/soc/amlogic/meson/audio_utils.h" +#endif + extern unsigned int signal_audmode; extern uint32_t adec_rd_reg(uint32_t addr); @@ -43,5 +49,6 @@ void update_a2_eiaj_mode(int auto_en, int *stereo_flag, int *dual_flag); void set_outputmode_status_init(void); void set_output_left_right_exchange(unsigned int ch); +void audio_source_select(int source); -#endif /* __ATVAUDDEMOD_H_ */ +#endif /* __ATV_AUD_DEMOD_H__ */ diff --git a/drivers/amlogic/atv_demod/atvdemod_func.c b/drivers/amlogic/atv_demod/atvdemod_func.c index 0bcd4b2..5daa986 100644 --- a/drivers/amlogic/atv_demod/atvdemod_func.c +++ b/drivers/amlogic/atv_demod/atvdemod_func.c @@ -110,6 +110,10 @@ enum AUDIO_SCAN_ID { ID_MAX, }; +static char *AUDIO_NAME[] = { + "I", "M", "DK", "BG" +}; + static unsigned int mix1_freq; int snr_val; int broad_std_except_pal_m; @@ -252,7 +256,14 @@ void atv_dmd_misc(void) /*atv_dmd_wr_byte(APB_BLOCK_ADDR_DAC_UPS, 0x01, 0x28);//pwd-out gain*/ /*atv_dmd_wr_byte(APB_BLOCK_ADDR_DAC_UPS, 0x04, 0xc0);//pwd-out offset*/ - aml_audio_valume_gain_set(audio_gain_val); + /* for audio non-standard signal, first set gain 0 to mute, + * then unmute in detection. + */ + if (audio_atv_ov || atv_audio_overmodulated_en) + aml_audio_valume_gain_set(0); + else + aml_audio_valume_gain_set(audio_gain_val); + /* 20160121 fix audio demodulation over */ atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, 0x00, 0x1030501); atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, 0x04, 0x1900000); @@ -286,19 +297,23 @@ void atv_dmd_misc(void) carrier_amplif_val); } - if (audio_atv_ov) { + if (audio_atv_ov || atv_audio_overmodulated_en) { + reg = atv_dmd_rd_long(APB_BLOCK_ADDR_SIF_STG_2, 0); + reg = (reg & 0xffffff) | (1 << 24); + atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, 0, reg); atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, 0x14, 0x8000015); atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, 0x18, 0x7ffff); atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, 0x1c, 0x0f000); - atvaudio_ctrl_read(®); - if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) - atvaudio_ctrl_write(reg & (~0x100000));/* bit20 */ + + audio_source_select(0); + + if (atv_audio_overmodulated_en) + audio_atv_ov_flag = 0; else - atvaudio_ctrl_write(reg & (~0x3));/* bit[1-0] */ - audio_atv_ov_flag = 1; + audio_atv_ov_flag = 1; } else { atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, 0x14, 0xf400000); @@ -306,11 +321,9 @@ void atv_dmd_misc(void) 0x18, 0xc000); atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, 0x1c, 0x1f000); - atvaudio_ctrl_read(®); - if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) - atvaudio_ctrl_write(reg | 0x100000);/* bit20 */ - else - atvaudio_ctrl_write(reg | 0x3);/* bit[1-0] */ + + audio_source_select(1); + audio_atv_ov_flag = 0; } @@ -2120,7 +2133,7 @@ int aml_audiomode_autodet(struct v4l2_frontend *v4l2_fe) int lock = 0, line_lock = 0; int broad_std_final = 0; int num = 0, i = 0, final_id = 0; - int delay_ms = 10, delay_ms_default = 10; + int delay_ms = 20, delay_ms_default = 20; int cur_std = ID_PAL_DK; bool secam_signal = false; bool ntsc_signal = false; @@ -2174,130 +2187,11 @@ int aml_audiomode_autodet(struct v4l2_frontend *v4l2_fe) atv_dmd_wr_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02, temp_data); return broad_std; } + /* ----------------read carrier_power--------------------- */ /* SIF_STG_2[0x09],address 0x03 */ - while (1) { - if (num >= 4) { - temp_data = - atv_dmd_rd_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02); - temp_data = temp_data & (~0x80); - atv_dmd_wr_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02, - temp_data); - carrier_power_max = carrier_power_average[0]; - for (i = 0; i < ID_MAX; i++) { - if (carrier_power_max - < carrier_power_average[i]) { - carrier_power_max = - carrier_power_average[i]; - final_id = i; - } - } - - switch (final_id) { - case ID_PAL_I: - broad_std_final = - AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_I; - break; - case ID_PAL_BG: - broad_std_final = - AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG; - break; - case ID_PAL_M: - broad_std_final = - AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M; - break; - case ID_PAL_DK: - broad_std_final = - AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK; - break; - } - - carrier_power_average_max = carrier_power_max; - broad_std = broad_std_final; - pr_err("%s:broad_std:%d,carrier_power_average_max:%lu\n", - __func__, broad_std, carrier_power_average_max); - - if (carrier_power_average_max < 150) { - pr_err("%s,carrier too low error\n", __func__); - if (secam_signal) { - broad_std = - AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_L; - pr_err("%s,set broad_std to SECAM_L\n", - __func__); - } - } - - if (broad_std == AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M - && pal_signal) { - /*the max except palm*/ - carrier_power_average[final_id] = 0; - final_id = 0; - carrier_power_max = carrier_power_average[0]; - for (i = 0; i < ID_MAX; i++) { - if (carrier_power_max - < carrier_power_average[i]) { - carrier_power_max = - carrier_power_average[i]; - final_id = i; - } - } - - switch (final_id) { - case ID_PAL_I: - broad_std_except_pal_m = - AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_I; - break; - case ID_PAL_BG: - broad_std_except_pal_m = - AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG; - break; - case ID_PAL_DK: - broad_std_except_pal_m = - AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK; - break; - } - /* pal signal and pal-m power max, - * so set to second max std. - */ - broad_std = broad_std_except_pal_m; - pr_err("%s:pal signal and pal-m power max, set broad_std:%d\n", - __func__, broad_std); - } - - p->std = V4L2_COLOR_STD_PAL; - switch (broad_std) { - case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK: - p->std |= V4L2_STD_PAL_DK; - p->audmode = V4L2_STD_PAL_DK; - break; - case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_I: - p->std |= V4L2_STD_PAL_I; - p->audmode = V4L2_STD_PAL_I; - break; - case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG: - p->std |= V4L2_STD_PAL_BG; - p->audmode = V4L2_STD_PAL_BG; - break; - case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M: - p->std |= V4L2_STD_PAL_M; - p->audmode = V4L2_STD_PAL_M; - break; - default: - p->std |= V4L2_STD_PAL_DK; - p->audmode = V4L2_STD_PAL_DK; - } - - p->frequency += 1; - params.frequency = p->frequency; - params.mode = p->afc_range; - params.audmode = p->audmode; - params.std = p->std; - - fe->ops.analog_ops.set_params(fe, ¶ms); - - return broad_std; - } - + num = 0; + while (num < 4) { switch (broad_std) { case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK: broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_I; @@ -2345,7 +2239,6 @@ int aml_audiomode_autodet(struct v4l2_frontend *v4l2_fe) delay_ms = delay_ms_default; break; - default: pr_err("unsupport broadcast_standard!!!\n"); break; @@ -2355,7 +2248,8 @@ int aml_audiomode_autodet(struct v4l2_frontend *v4l2_fe) params.mode = p->afc_range; params.audmode = p->audmode; params.std = p->std; - fe->ops.analog_ops.set_params(fe, ¶ms); + if (fe->ops.analog_ops.set_params) + fe->ops.analog_ops.set_params(fe, ¶ms); /* enable audio detect function */ temp_data = atv_dmd_rd_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02); @@ -2391,12 +2285,144 @@ int aml_audiomode_autodet(struct v4l2_frontend *v4l2_fe) } carrier_power_max = 0; - pr_err("[%s] [num:%d] [broad_std:%d] audio carrier power: %lu. @@@@@@@@@@\n", - __func__, num, broad_std, carrier_power); + pr_err("[%s] [num:%d] [broad_std:%d] [%s] audio carrier power: %lu. @@@@@@@@@@\n", + __func__, num, broad_std, AUDIO_NAME[cur_std], + carrier_power); carrier_power_average[cur_std] += carrier_power; num++; } + /* disable audio detect function */ + temp_data = atv_dmd_rd_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02); + atv_dmd_wr_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02, temp_data & (~0x80)); + + carrier_power_max = carrier_power_average[0]; + for (i = 0; i < ID_MAX; i++) { + if (carrier_power_max < carrier_power_average[i]) { + carrier_power_max = carrier_power_average[i]; + final_id = i; + } + } + + switch (final_id) { + case ID_PAL_I: + broad_std_final = AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_I; + break; + case ID_PAL_BG: + broad_std_final = AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG; + break; + case ID_PAL_M: + broad_std_final = AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M; + break; + case ID_PAL_DK: + broad_std_final = AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK; + break; + } + + carrier_power_average_max = carrier_power_max; + broad_std = broad_std_final; + pr_err("%s:broad_std:%d,carrier_power_average_max:%lu\n", + __func__, broad_std, carrier_power_average_max); + + if (carrier_power_average_max < 150) { + pr_err("%s,carrier too low error\n", __func__); + if (secam_signal) { + broad_std = + AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_L; + pr_err("%s,set broad_std to SECAM_L\n", + __func__); + } + } + + if (broad_std == AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M && pal_signal) { + /*the max except palm*/ + carrier_power_average[final_id] = 0; + final_id = 0; + carrier_power_max = carrier_power_average[0]; + for (i = 0; i < ID_MAX; i++) { + if (carrier_power_max < carrier_power_average[i]) { + carrier_power_max = carrier_power_average[i]; + final_id = i; + } + } + + switch (final_id) { + case ID_PAL_I: + broad_std_except_pal_m = + AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_I; + break; + case ID_PAL_BG: + broad_std_except_pal_m = + AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG; + break; + case ID_PAL_DK: + broad_std_except_pal_m = + AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK; + break; + } + + /* for non-standard signal */ + if (broad_std_except_pal_m == + AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG && + abs(carrier_power_average[ID_PAL_DK] - + carrier_power_average[ID_PAL_BG]) < 25) + broad_std_except_pal_m = + AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK; + + /* pal signal and pal-m power max, so set to second max std. */ + broad_std = broad_std_except_pal_m; + pr_err("%s:pal signal and pal-m power max, set broad_std:%d\n", + __func__, broad_std); + } else { + /* for non-standard signal */ + if (carrier_power_average[ID_PAL_I] < 30 && + carrier_power_average[ID_PAL_M] < 30 && + carrier_power_average[ID_PAL_DK] < 30 && + carrier_power_average[ID_PAL_BG] < 30 && + pal_signal) { + broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK; + pr_err("%s:power all < 30, set broad_std: PAL_DK\n", + __func__); + } + } + + if (secam_signal) + p->std = V4L2_COLOR_STD_SECAM; + else if (ntsc_signal) + p->std = V4L2_COLOR_STD_NTSC; + else + p->std = V4L2_COLOR_STD_PAL; + + switch (broad_std) { + case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK: + p->std |= V4L2_STD_PAL_DK; + p->audmode = V4L2_STD_PAL_DK; + break; + case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_I: + p->std |= V4L2_STD_PAL_I; + p->audmode = V4L2_STD_PAL_I; + break; + case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG: + p->std |= V4L2_STD_PAL_BG; + p->audmode = V4L2_STD_PAL_BG; + break; + case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M: + p->std |= V4L2_STD_PAL_M; + p->audmode = V4L2_STD_PAL_M; + break; + default: + p->std |= V4L2_STD_PAL_DK; + p->audmode = V4L2_STD_PAL_DK; + } + + p->frequency += 1; + params.frequency = p->frequency; + params.mode = p->afc_range; + params.audmode = p->audmode; + params.std = p->std; + if (fe->ops.analog_ops.set_params) + fe->ops.analog_ops.set_params(fe, ¶ms); + return broad_std; } @@ -2449,7 +2475,6 @@ void aml_audio_overmodulation(int enable) { unsigned long tmp_v = 0; unsigned long tmp_v1 = 0; - unsigned int reg = 0; u32 Broadcast_Standard = broad_std; /* False entry on weak signal */ @@ -2471,18 +2496,17 @@ void aml_audio_overmodulation(int enable) 0x18, 0x7ffff); atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, 0x1c, 0x0f000); - atvaudio_ctrl_read(®); - if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) { - /* bit20 */ - atvaudio_ctrl_write(reg & (~0x100000)); - } else { - /* bit[1-0] */ - atvaudio_ctrl_write(reg & (~0x3)); - } - /* audio_atv_ov_flag = 1;*/ /* Enter and hold */ + + audio_source_select(0); + + aml_audio_valume_gain_set(audio_gain_val); + + audio_atv_ov_flag = 1; pr_info("tmp_v[0x%lx] > 0x10 && audio_atv_ov_flag == 0.\n", tmp_v); - } else if (tmp_v <= 0x10 && audio_atv_ov_flag == 1) { + } +#if 0 /* No need, Enter and hold */ + else if (tmp_v <= 0x10 && audio_atv_ov_flag == 1) { tmp_v1 = atv_dmd_rd_long(APB_BLOCK_ADDR_SIF_STG_2, 0); tmp_v1 = (tmp_v1&0xffffff)|(0<<24); atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, 0, tmp_v1); @@ -2492,17 +2516,13 @@ void aml_audio_overmodulation(int enable) 0x18, 0xc000); atv_dmd_wr_long(APB_BLOCK_ADDR_SIF_STG_2, 0x1c, 0x1f000); - atvaudio_ctrl_read(®); - if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) { - /* bit20 */ - atvaudio_ctrl_write(reg | 0x100000); - } else { - /* bit[1-0] */ - atvaudio_ctrl_write(reg | 0x3); - } + + audio_source_select(1); + audio_atv_ov_flag = 0; pr_info("tmp_v[0x%lx] <= 0x10 && audio_atv_ov_flag == 1.\n", tmp_v); } +#endif } } diff --git a/drivers/amlogic/atv_demod/atvdemod_func.h b/drivers/amlogic/atv_demod/atvdemod_func.h index c3771a6..b330e34 100644 --- a/drivers/amlogic/atv_demod/atvdemod_func.h +++ b/drivers/amlogic/atv_demod/atvdemod_func.h @@ -29,6 +29,7 @@ extern unsigned int aud_std; extern unsigned int aud_mode; extern bool audio_thd_en; extern bool aud_reinit; +extern bool atv_audio_overmodulated_en; enum broadcast_standard_e { ATVDEMOD_STD_NTSC = 0, -- 2.7.4