From aadf8893c854a318288f2164a972673bd49ed76b Mon Sep 17 00:00:00 2001 From: "nengwen.chen" Date: Wed, 18 Jul 2018 11:23:51 +0800 Subject: [PATCH] atv_demod: improve atv demod timer handler [1/1] PD#169330: improve atv demod timer handler 1.Add work queue to do the time consuming operations. 2.Optimize code. 3.V2.02 Change-Id: I809179ab84fc236cc4dba234e21448d6528f9c5e Signed-off-by: nengwen.chen --- drivers/amlogic/atv_demod/atv_demod_debug.c | 12 +- drivers/amlogic/atv_demod/atv_demod_driver.c | 6 +- drivers/amlogic/atv_demod/atv_demod_ops.c | 317 ++++++++++--------- drivers/amlogic/atv_demod/atv_demod_ops.h | 20 +- drivers/amlogic/atv_demod/atvdemod_func.c | 143 ++++----- drivers/amlogic/atv_demod/atvdemod_func.h | 7 +- 6 files changed, 258 insertions(+), 247 deletions(-) diff --git a/drivers/amlogic/atv_demod/atv_demod_debug.c b/drivers/amlogic/atv_demod/atv_demod_debug.c index 1eb4b80ec3f3..567385e312c4 100644 --- a/drivers/amlogic/atv_demod/atv_demod_debug.c +++ b/drivers/amlogic/atv_demod/atv_demod_debug.c @@ -41,7 +41,7 @@ DEBUGFS_CREATE_NODE(reg_23cf, 0640, dentry, u32)\ DEBUGFS_CREATE_NODE(btsc_sap_mode, 0640, dentry, u32)\ DEBUGFS_CREATE_NODE(afc_limit, 0640, dentry, u32)\ - DEBUGFS_CREATE_NODE(aml_timer_en, 0640, dentry, bool)\ + DEBUGFS_CREATE_NODE(afc_timer_en, 0640, dentry, bool)\ DEBUGFS_CREATE_NODE(timer_delay, 0640, dentry, u32)\ DEBUGFS_CREATE_NODE(timer_delay2, 0640, dentry, u32)\ DEBUGFS_CREATE_NODE(timer_delay3, 0640, dentry, u32)\ @@ -57,7 +57,7 @@ DEBUGFS_CREATE_NODE(input_amplitude, 0640, dentry, u64)\ DEBUGFS_CREATE_NODE(audio_det_en, 0640, dentry, bool)\ DEBUGFS_CREATE_NODE(non_std_en, 0640, dentry, u32)\ - DEBUGFS_CREATE_NODE(non_std_onoff, 0640, dentry, bool)\ + DEBUGFS_CREATE_NODE(atvdemod_non_std_en, 0640, dentry, bool)\ DEBUGFS_CREATE_NODE(non_std_times, 0640, dentry, u32)\ DEBUGFS_CREATE_NODE(atv_video_gain, 0640, dentry, u32)\ DEBUGFS_CREATE_NODE(carrier_amplif_val, 0640, dentry, u32)\ @@ -79,10 +79,10 @@ DEBUGFS_CREATE_NODE(atvdemod_agc_pinmux, 0640, dentry, u32)\ DEBUGFS_CREATE_NODE(atvdemod_afc_range, 0640, dentry, u32)\ DEBUGFS_CREATE_NODE(atvdemod_afc_offset, 0640, dentry, u32)\ - DEBUGFS_CREATE_NODE(atvdemod_timer_en, 0640, dentry, u32)\ - DEBUGFS_CREATE_NODE(atvdemod_afc_en, 0640, dentry, u32)\ - DEBUGFS_CREATE_NODE(atvdemod_monitor_en, 0640, dentry, u32)\ - DEBUGFS_CREATE_NODE(audio_thd_en, 0640, dentry, u32)\ + DEBUGFS_CREATE_NODE(atvdemod_timer_en, 0640, dentry, bool)\ + DEBUGFS_CREATE_NODE(atvdemod_tune_en, 0640, dentry, bool)\ + DEBUGFS_CREATE_NODE(atvdemod_monitor_en, 0640, dentry, bool)\ + DEBUGFS_CREATE_NODE(audio_thd_en, 0640, dentry, bool)\ DEBUGFS_CREATE_NODE(pwm_kp, 0640, dentry, u32)\ DEBUGFS_CREATE_NODE(reg_dbg_en, 0640, dentry, u32)\ DEBUGFS_CREATE_NODE(audio_gain_val, 0640, dentry, u32)\ diff --git a/drivers/amlogic/atv_demod/atv_demod_driver.c b/drivers/amlogic/atv_demod/atv_demod_driver.c index a5a5a1a4f7dc..55d42a944905 100644 --- a/drivers/amlogic/atv_demod/atv_demod_driver.c +++ b/drivers/amlogic/atv_demod/atv_demod_driver.c @@ -39,7 +39,7 @@ #include "atvauddemod_func.h" -#define AMLATVDEMOD_VER "V2.01" +#define AMLATVDEMOD_VER "V2.02" struct aml_atvdemod_device *amlatvdemod_devp; @@ -76,7 +76,7 @@ static ssize_t aml_atvdemod_store(struct class *class, goto EXIT; if (!strncmp(parm[0], "init", 4)) { - ret = atv_demod_enter_mode(); + ret = atv_demod_enter_mode(&amlatvdemod_devp->v4l2_fe.fe); if (ret) pr_info("atv init error.\n"); } else if (!strncmp(parm[0], "audout_mode", 11)) { @@ -162,7 +162,7 @@ static ssize_t aml_atvdemod_store(struct class *class, pr_dbg("aml_atvdemod_ver %s.\n", AMLATVDEMOD_VER); } else if (!strncmp(parm[0], "audio_autodet", 13)) { - aml_audiomode_autodet(NULL); + aml_audiomode_autodet(&amlatvdemod_devp->v4l2_fe.fe); } else if (!strncmp(parm[0], "overmodule_det", 14)) { /* unsigned long over_threshold, */ /* int det_mode = auto_det_mode; */ diff --git a/drivers/amlogic/atv_demod/atv_demod_ops.c b/drivers/amlogic/atv_demod/atv_demod_ops.c index 12d58c851c66..1a2fed72a036 100644 --- a/drivers/amlogic/atv_demod/atv_demod_ops.c +++ b/drivers/amlogic/atv_demod/atv_demod_ops.c @@ -41,23 +41,28 @@ static LIST_HEAD(hybrid_tuner_instance_list); unsigned int reg_23cf = 0x88188832; /*IIR filter*/ unsigned int btsc_sap_mode = 1; /*0: off 1:monitor 2:auto */ +unsigned int atvdemod_scan_mode; + +bool atvdemod_tune_en; +bool atvdemod_monitor_en; +bool audio_det_en; +bool atvdemod_det_snr_en = true; +bool audio_thd_en = true; +bool atvdemod_non_std_en; + int afc_offset; unsigned int afc_limit = 2100;/*+-2.1Mhz*/ - static int no_sig_cnt; -struct timer_list aml_timer; -#define AML_INTERVAL (HZ/100) /* 10ms, #define HZ 100 */ -static unsigned int timer_init_state; -static unsigned int aft_thread_enable; +static unsigned int afc_timer_init_state; static unsigned int aft_thread_delaycnt; - - -bool aml_timer_en = true; +bool afc_timer_en = true; unsigned int timer_delay = 1; unsigned int timer_delay2 = 10; unsigned int timer_delay3 = 10;/*100ms*/ unsigned int afc_wave_cnt = 4; +static unsigned int demod_timer_init_state; +bool atvdemod_timer_en = true; #define AFC_LOCK_STATUS_NULL 0 #define AFC_LOCK_STATUS_PRE_UNLOCK 1 @@ -77,7 +82,7 @@ static unsigned int afc_pre_lock_cnt; static unsigned int afc_pre_unlock_cnt; static unsigned int afc_lock_status = AFC_LOCK_STATUS_NULL; -static void aml_fe_do_work_pre(int lock) +static void aml_afc_do_work_pre(int lock) { struct dvb_frontend *fe = &amlatvdemod_devp->v4l2_fe.fe; struct atv_demod_priv *priv = fe->analog_demod_priv; @@ -134,7 +139,7 @@ static void aml_fe_do_work_pre(int lock) } } -static void aml_fe_do_work(struct work_struct *work) +static void aml_afc_do_work(struct work_struct *work) { struct dvb_frontend *fe = &amlatvdemod_devp->v4l2_fe.fe; struct atv_demod_priv *priv = fe->analog_demod_priv; @@ -146,7 +151,7 @@ static void aml_fe_do_work(struct work_struct *work) static int audio_overmodul; static int wave_cnt; - if (timer_init_state == 0) + if (afc_timer_init_state == 0) return; retrieve_vpll_carrier_lock(&tmp);/* 0 means lock, 1 means unlock */ @@ -156,7 +161,7 @@ static void aml_fe_do_work(struct work_struct *work) if ((afc_lock_status != AFC_LOCK_STATUS_POST_PROCESS) && (afc_lock_status != AFC_LOCK_STATUS_POST_LOCK) && (afc_lock_status != AFC_LOCK_STATUS_PRE_LOCK)) { - aml_fe_do_work_pre(lock); + aml_afc_do_work_pre(lock); return; } @@ -235,13 +240,13 @@ static void aml_fe_do_work(struct work_struct *work) afc_lock_status = AFC_LOCK_STATUS_POST_PROCESS; } -void aml_timer_handler(unsigned long arg) +void aml_afc_timer_handler(unsigned long arg) { struct dvb_frontend *fe = (struct dvb_frontend *)arg; struct atv_demod_priv *priv = fe->analog_demod_priv; unsigned int delay_ms = 0; - if ((fe == NULL) || (priv == NULL) || (timer_init_state == 0)) + if (afc_timer_init_state == 0) return; if (afc_lock_status == AFC_LOCK_STATUS_POST_OVER_RANGE || @@ -251,69 +256,132 @@ void aml_timer_handler(unsigned long arg) else delay_ms = timer_delay;/*10ms*/ - aml_timer.function = aml_timer_handler; - aml_timer.data = arg; - aml_timer.expires = jiffies + AML_INTERVAL * delay_ms; - add_timer(&aml_timer); - - if (!aft_thread_enable) { - /*pr_info("%s, stop aft thread\n", __func__);*/ - return; - } + priv->afc_timer.function = aml_afc_timer_handler; + priv->afc_timer.data = arg; + priv->afc_timer.expires = jiffies + ATVDEMOD_INTERVAL * delay_ms; + add_timer(&priv->afc_timer); if (aft_thread_delaycnt > 0) { aft_thread_delaycnt--; return; } - if ((aml_timer_en == false) || (fe->ops.info.type != FE_ANALOG)) + if ((afc_timer_en == false) || (fe->ops.info.type != FE_ANALOG)) return; - schedule_work(&priv->demod_wq); + schedule_work(&priv->afc_wq); } -static void afc_timer_disable(struct dvb_frontend *fe) +static void aml_afc_timer_disable(struct dvb_frontend *fe) { struct atv_demod_priv *priv = fe->analog_demod_priv; - if (aml_timer_en && (timer_init_state == 1)) { - del_timer_sync(&aml_timer); + if (afc_timer_en && (afc_timer_init_state == 1)) { + del_timer_sync(&priv->afc_timer); cancel_work_sync(&priv->demod_wq); - timer_init_state = 0; + afc_timer_init_state = 0; } } -static void afc_timer_enable(struct dvb_frontend *fe) +static void aml_afc_timer_enable(struct dvb_frontend *fe) { - if (fe && aml_timer_en && (timer_init_state == 0)) { - init_timer(&aml_timer); - aml_timer.function = aml_timer_handler; - aml_timer.data = (ulong) fe; + struct atv_demod_priv *priv = fe->analog_demod_priv; + + if (afc_timer_en && (afc_timer_init_state == 0)) { + init_timer(&priv->afc_timer); + priv->afc_timer.function = aml_afc_timer_handler; + priv->afc_timer.data = (ulong) fe; /* after 5s enable demod auto detect */ - aml_timer.expires = jiffies + AML_INTERVAL * timer_delay3; + priv->afc_timer.expires = jiffies + + ATVDEMOD_INTERVAL * timer_delay3; afc_offset = 0; no_sig_cnt = 0; afc_pre_step = 0; afc_lock_status = AFC_LOCK_STATUS_NULL; - add_timer(&aml_timer); - timer_init_state = 1; + add_timer(&priv->afc_timer); + afc_timer_init_state = 1; } } -static void set_aft_thread_enable(int enable, unsigned int delay) +static void aml_atvdemod_do_work(struct work_struct *work) { - if (enable == aft_thread_enable) + if (demod_timer_init_state == 0) return; - aft_thread_enable = enable; - aft_thread_delaycnt = delay; + if (atvdemod_tune_en) + atvdemod_afc_tune(); - if (aft_thread_enable) - afc_timer_enable(&amlatvdemod_devp->v4l2_fe.fe); - else - afc_timer_disable(&amlatvdemod_devp->v4l2_fe.fe); + if (atvdemod_monitor_en) + atvdemod_monitor_serice(); + + if (audio_det_en) + aml_atvdemod_overmodule_det(); + + if (atvdemod_det_snr_en) + atvdemod_det_snr_serice(); + + if (audio_thd_en) + audio_thd_det(); + +#if 0 + if (aml_atvdemod_get_btsc_sap_mode() == 1 && + aud_std == AUDIO_STANDARD_BTSC) + audio_mode_det(aud_mode); +#endif + + if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) + set_outputmode(aud_std, aud_mode); + + if (atvdemod_non_std_en) + atv_dmd_non_std_set(true); +} + +static void aml_atvdemod_timer_handler(unsigned long arg) +{ + struct dvb_frontend *fe = (struct dvb_frontend *)arg; + struct atv_demod_priv *priv = fe->analog_demod_priv; + + /* 100ms timer */ + priv->demod_timer.data = arg; + priv->demod_timer.expires = jiffies + ATVDEMOD_INTERVAL * 10; + add_timer(&priv->demod_timer); + + if (atvdemod_timer_en == 0) + return; + + if (vdac_enable_check_dtv()) + return; + + schedule_work(&priv->demod_wq); +} + +static void aml_demod_timer_enable(struct dvb_frontend *fe) +{ + struct atv_demod_priv *priv = fe->analog_demod_priv; + + if (atvdemod_timer_en && (demod_timer_init_state == 0)) { + init_timer(&priv->demod_timer); + priv->demod_timer.data = (ulong) fe; + priv->demod_timer.function = aml_atvdemod_timer_handler; + /* after 1s enable demod auto detect */ + priv->demod_timer.expires = jiffies + ATVDEMOD_INTERVAL * 100; + add_timer(&priv->demod_timer); + demod_timer_init_state = 1; + } +} + +static void aml_demod_timer_disable(struct dvb_frontend *fe) +{ + struct atv_demod_priv *priv = fe->analog_demod_priv; + + if (atvdemod_timer_en && (demod_timer_init_state == 1)) { + del_timer_sync(&priv->demod_timer); + cancel_work_sync(&priv->demod_wq); + demod_timer_init_state = 0; + } } + /* * add interface for audio driver to get atv audio state. * state: @@ -362,65 +430,6 @@ int aml_atvdemod_get_btsc_sap_mode(void) return btsc_sap_mode; } -unsigned int atvdemod_scan_mode; /*IIR filter*/ - -/* ret:5~100;the val is bigger,the signal is better */ -int aml_atvdemod_get_snr(struct dvb_frontend *fe) -{ -#if 1 - return get_atvdemod_snr_val(); -#else - unsigned int snr_val; - int ret; - - snr_val = atv_dmd_rd_long(APB_BLOCK_ADDR_VDAGC, 0x50) >> 8; - /* snr_val:900000~0xffffff,ret:5~15 */ - if (snr_val > 900000) - ret = 15 - (snr_val - 900000)*10/(0xffffff - 900000); - /* snr_val:158000~900000,ret:15~30 */ - else if (snr_val > 158000) - ret = 30 - (snr_val - 158000)*15/(900000 - 158000); - /* snr_val:31600~158000,ret:30~50 */ - else if (snr_val > 31600) - ret = 50 - (snr_val - 31600)*20/(158000 - 31600); - /* snr_val:316~31600,ret:50~80 */ - else if (snr_val > 316) - ret = 80 - (snr_val - 316)*30/(31600 - 316); - /* snr_val:0~316,ret:80~100 */ - else - ret = 100 - (316 - snr_val)*20/316; - return ret; -#endif -} - -int aml_atvdemod_get_snr_ex(void) -{ -#if 1 - return get_atvdemod_snr_val(); -#else - unsigned int snr_val; - int ret; - - snr_val = atv_dmd_rd_long(APB_BLOCK_ADDR_VDAGC, 0x50) >> 8; - /* snr_val:900000~0xffffff,ret:5~15 */ - if (snr_val > 900000) - ret = 15 - (snr_val - 900000)*10/(0xffffff - 900000); - /* snr_val:158000~900000,ret:15~30 */ - else if (snr_val > 158000) - ret = 30 - (snr_val - 158000)*15/(900000 - 158000); - /* snr_val:31600~158000,ret:30~50 */ - else if (snr_val > 31600) - ret = 50 - (snr_val - 31600)*20/(158000 - 31600); - /* snr_val:316~31600,ret:50~80 */ - else if (snr_val > 316) - ret = 80 - (snr_val - 316)*30/(31600 - 316); - /* snr_val:0~316,ret:80~100 */ - else - ret = 100 - (316 - snr_val)*20/316; - return ret; -#endif -} - int is_atvdemod_work(void) { int ret = 0; @@ -431,12 +440,12 @@ int is_atvdemod_work(void) return ret; } -int atv_demod_get_scan_mode(void) +static int atv_demod_get_scan_mode(void) { return atvdemod_scan_mode; } -void atv_demod_set_scan_mode(int val) +static void atv_demod_set_scan_mode(int val) { atvdemod_scan_mode = val; } @@ -451,7 +460,7 @@ static void atv_demod_set_state(int state) atvdemod_state = state; } -int atv_demod_enter_mode(void) +int atv_demod_enter_mode(struct dvb_frontend *fe) { int err_code = 0; @@ -479,11 +488,9 @@ int atv_demod_enter_mode(void) return err_code; } - set_aft_thread_enable(1, 0); - /* - * memset(&(amlatvdemod_devp->parm), 0, - * sizeof(amlatvdemod_devp->parm)); - */ + aml_afc_timer_enable(fe); + aml_demod_timer_enable(fe); + amlatvdemod_devp->std = 0; amlatvdemod_devp->audmode = 0; @@ -494,12 +501,14 @@ int atv_demod_enter_mode(void) return 0; } -int atv_demod_leave_mode(void) +int atv_demod_leave_mode(struct dvb_frontend *fe) { if (atv_demod_get_state() == ATVDEMOD_STATE_IDEL) return 0; - set_aft_thread_enable(0, 0); + aml_demod_timer_disable(fe); + aml_afc_timer_disable(fe); + atvdemod_uninit(); if (amlatvdemod_devp->agc_pin != NULL) { devm_pinctrl_put(amlatvdemod_devp->agc_pin); @@ -511,10 +520,6 @@ int atv_demod_leave_mode(void) if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) aud_demod_clk_gate(0); - /* - * memset(&(amlatvdemod_devp->parm), 0, - * sizeof(amlatvdemod_devp->parm)); - */ amlatvdemod_devp->std = 0; amlatvdemod_devp->audmode = 0; atv_demod_set_state(ATVDEMOD_STATE_IDEL); @@ -540,7 +545,8 @@ static void atv_demod_set_params(struct dvb_frontend *fe, p->param.std = params->std; /* afc tune disable,must cancel wq before set tuner freq*/ - afc_timer_disable(fe); + aml_afc_timer_disable(fe); + aml_demod_timer_disable(fe); if (fe->ops.tuner_ops.set_analog_params) ret = fe->ops.tuner_ops.set_analog_params(fe, params); @@ -551,43 +557,37 @@ static void atv_demod_set_params(struct dvb_frontend *fe, p->if_inv = if_info[0]; p->if_freq = if_info[1]; - if ((p->param.std != amlatvdemod_devp->std) || - (p->tuner_id == AM_TUNER_R840) || - (p->tuner_id == AM_TUNER_R842) || - (p->tuner_id == AM_TUNER_SI2151) || - (p->tuner_id == AM_TUNER_MXL661) || - (p->tuner_id == AM_TUNER_SI2159)) { - #if 0 /* unused */ - last_frq = p->param.frequency; - last_std = p->param.std; + last_frq = p->param.frequency; + last_std = p->param.std; #endif - if (amlatvdemod_devp->std != p->param.std || - amlatvdemod_devp->audmode != p->param.audmode || - amlatvdemod_devp->if_freq != p->if_freq || - amlatvdemod_devp->if_inv != p->if_inv || - amlatvdemod_devp->tuner_id != p->tuner_id) { - amlatvdemod_devp->std = p->param.std; - amlatvdemod_devp->audmode = p->param.audmode; - amlatvdemod_devp->if_freq = p->if_freq; - amlatvdemod_devp->if_inv = p->if_inv; - amlatvdemod_devp->tuner_id = p->tuner_id; - - atv_dmd_set_std(); - - } else - atv_dmd_soft_reset(); - - if (!atv_demod_get_scan_mode()) - atvauddemod_init(); - } + if (amlatvdemod_devp->std != p->param.std || + amlatvdemod_devp->audmode != p->param.audmode || + amlatvdemod_devp->if_freq != p->if_freq || + amlatvdemod_devp->if_inv != p->if_inv || + amlatvdemod_devp->tuner_id != p->tuner_id) { + amlatvdemod_devp->std = p->param.std; + amlatvdemod_devp->audmode = p->param.audmode; + amlatvdemod_devp->if_freq = p->if_freq; + amlatvdemod_devp->if_inv = p->if_inv; + amlatvdemod_devp->tuner_id = p->tuner_id; + + atv_dmd_set_std(); + + } else + atv_dmd_soft_reset(); + + if (!atv_demod_get_scan_mode()) + atvauddemod_init(); /* afc tune enable */ /* analog_search_flag == 0 or afc_range != 0 means searching */ if ((fe->ops.info.type == FE_ANALOG) && (atv_demod_get_scan_mode() == 0) - && (p->param.mode == 0)) - afc_timer_enable(fe); + && (p->param.mode == 0)) { + aml_afc_timer_enable(fe); + aml_demod_timer_enable(fe); + } } static int atv_demod_has_signal(struct dvb_frontend *fe, u16 *signal) @@ -616,7 +616,7 @@ static int atv_demod_has_signal(struct dvb_frontend *fe, u16 *signal) static void atv_demod_standby(struct dvb_frontend *fe) { if (atv_demod_get_state() != ATVDEMOD_STATE_IDEL) { - atv_demod_leave_mode(); + atv_demod_leave_mode(fe); atv_demod_set_state(ATVDEMOD_STATE_SLEEP); } @@ -640,7 +640,7 @@ static void atv_demod_release(struct dvb_frontend *fe) int instance = 0; struct atv_demod_priv *priv = fe->analog_demod_priv; - atv_demod_leave_mode(); + atv_demod_leave_mode(fe); mutex_lock(&atv_demod_list_mutex); @@ -671,13 +671,13 @@ static int atv_demod_set_config(struct dvb_frontend *fe, void *priv_cfg) if (atv_demod_get_state() != ATVDEMOD_STATE_WORK) { if (fe->ops.tuner_ops.set_config) fe->ops.tuner_ops.set_config(fe, NULL); - atv_demod_enter_mode(); + atv_demod_enter_mode(fe); } break; case AML_ATVDEMOD_UNINIT: if (atv_demod_get_state() != ATVDEMOD_STATE_IDEL) { - atv_demod_leave_mode(); + atv_demod_leave_mode(fe); if (fe->ops.tuner_ops.release) fe->ops.tuner_ops.release(fe); } @@ -685,7 +685,7 @@ static int atv_demod_set_config(struct dvb_frontend *fe, void *priv_cfg) case AML_ATVDEMOD_RESUME: if (atv_demod_get_state() == ATVDEMOD_STATE_SLEEP) { - atv_demod_enter_mode(); + atv_demod_enter_mode(fe); if (fe->ops.tuner_ops.resume) fe->ops.tuner_ops.resume(fe); } @@ -693,12 +693,14 @@ static int atv_demod_set_config(struct dvb_frontend *fe, void *priv_cfg) case AML_ATVDEMOD_SCAN_MODE: atv_demod_set_scan_mode(1); - afc_timer_disable(fe); + aml_afc_timer_disable(fe); + aml_demod_timer_disable(fe); break; case AML_ATVDEMOD_UNSCAN_MODE: atv_demod_set_scan_mode(0); - afc_timer_enable(fe); + aml_afc_timer_enable(fe); + aml_demod_timer_enable(fe); break; } @@ -1448,7 +1450,8 @@ struct dvb_frontend *aml_atvdemod_attach(struct dvb_frontend *fe, mutex_unlock(&atv_demod_list_mutex); return NULL; case 1: - INIT_WORK(&priv->demod_wq, aml_fe_do_work); + INIT_WORK(&priv->afc_wq, aml_afc_do_work); + INIT_WORK(&priv->demod_wq, aml_atvdemod_do_work); fe->analog_demod_priv = priv; priv->standby = true; pr_info("aml_atvdemod found\n"); diff --git a/drivers/amlogic/atv_demod/atv_demod_ops.h b/drivers/amlogic/atv_demod/atv_demod_ops.h index dbffc1c9df77..45a98977001a 100644 --- a/drivers/amlogic/atv_demod/atv_demod_ops.h +++ b/drivers/amlogic/atv_demod/atv_demod_ops.h @@ -14,6 +14,12 @@ #ifndef __ATV_DEMOD_OPS_H__ #define __ATV_DEMOD_OPS_H__ +#include "drivers/media/dvb-core/dvb_frontend.h" +#include "drivers/media/tuners/tuner-i2c.h" + +#include "atv_demod_driver.h" + + #define AML_ATVDEMOD_UNINIT 0x0 #define AML_ATVDEMOD_INIT 0x1 #define AML_ATVDEMOD_RESUME 0x2 @@ -25,10 +31,8 @@ #define ATV_AFC_1_0MHZ 1000000 #define ATV_AFC_2_0MHZ 2000000 -#include "drivers/media/dvb-core/dvb_frontend.h" -#include "drivers/media/tuners/tuner-i2c.h" +#define ATVDEMOD_INTERVAL (HZ / 100) /* 10ms, #define HZ 100 */ -#include "atv_demod_driver.h" struct atv_demod_sound_system { unsigned int broadcast_std; @@ -45,12 +49,16 @@ struct atv_demod_priv { struct aml_atvdemod_parameters atvdemod_param; struct atv_demod_sound_system sound_sys; + + struct work_struct afc_wq; + struct timer_list afc_timer; + struct work_struct demod_wq; + struct timer_list demod_timer; }; -extern int atv_demod_get_scan_mode(void); -extern void atv_demod_set_scan_mode(int val); -extern int atv_demod_enter_mode(void); + +extern int atv_demod_enter_mode(struct dvb_frontend *fe); struct dvb_frontend *aml_atvdemod_attach(struct dvb_frontend *fe, struct v4l2_frontend *v4l2_fe, diff --git a/drivers/amlogic/atv_demod/atvdemod_func.c b/drivers/amlogic/atv_demod/atvdemod_func.c index ec2d6196c392..941417bf3cbb 100644 --- a/drivers/amlogic/atv_demod/atvdemod_func.c +++ b/drivers/amlogic/atv_demod/atvdemod_func.c @@ -37,10 +37,9 @@ unsigned int aud_mode = AUDIO_OUTMODE_STEREO; bool aud_auto = true; unsigned long over_threshold = 0xffff; unsigned long input_amplitude = 0xffff; -bool audio_det_en; unsigned int non_std_en; -bool non_std_onoff; + unsigned int non_std_times = 50; int non_std_thld_4c_h = 100; int non_std_thld_4c_l = 30; @@ -85,11 +84,7 @@ unsigned int atvdemod_debug_en; unsigned int atvdemod_agc_pinmux = 2; unsigned int atvdemod_afc_range = 5; unsigned int atvdemod_afc_offset = 500; -unsigned int atvdemod_timer_en = 1; -unsigned int atvdemod_afc_en; -unsigned int atvdemod_monitor_en; -unsigned int atvdemod_det_snr_en = 1; -unsigned int audio_thd_en = 1; + unsigned int pwm_kp = 0x19; unsigned int reg_dbg_en; unsigned int audio_gain_val = 512; @@ -106,11 +101,10 @@ enum AUDIO_SCAN_ID { }; static unsigned int mix1_freq; -static unsigned int timer_init_flag; -struct timer_list atvdemod_timer; static int snr_val; int broad_std_except_pal_m; + int get_atvdemod_snr_val(void) { return snr_val; @@ -1523,6 +1517,63 @@ void atvdemod_afc_tune(void) /* pr_info("horizontal frequency:%d Hz\n",fh*190735/100000); */ } +/* ret:5~100;the val is bigger,the signal is better */ +int aml_atvdemod_get_snr(struct dvb_frontend *fe) +{ +#if 1 + return get_atvdemod_snr_val(); +#else + unsigned int snr_val; + int ret; + + snr_val = atv_dmd_rd_long(APB_BLOCK_ADDR_VDAGC, 0x50) >> 8; + /* snr_val:900000~0xffffff,ret:5~15 */ + if (snr_val > 900000) + ret = 15 - (snr_val - 900000)*10/(0xffffff - 900000); + /* snr_val:158000~900000,ret:15~30 */ + else if (snr_val > 158000) + ret = 30 - (snr_val - 158000)*15/(900000 - 158000); + /* snr_val:31600~158000,ret:30~50 */ + else if (snr_val > 31600) + ret = 50 - (snr_val - 31600)*20/(158000 - 31600); + /* snr_val:316~31600,ret:50~80 */ + else if (snr_val > 316) + ret = 80 - (snr_val - 316)*30/(31600 - 316); + /* snr_val:0~316,ret:80~100 */ + else + ret = 100 - (316 - snr_val)*20/316; + return ret; +#endif +} + +int aml_atvdemod_get_snr_ex(void) +{ +#if 1 + return get_atvdemod_snr_val(); +#else + unsigned int snr_val; + int ret; + + snr_val = atv_dmd_rd_long(APB_BLOCK_ADDR_VDAGC, 0x50) >> 8; + /* snr_val:900000~0xffffff,ret:5~15 */ + if (snr_val > 900000) + ret = 15 - (snr_val - 900000)*10/(0xffffff - 900000); + /* snr_val:158000~900000,ret:15~30 */ + else if (snr_val > 158000) + ret = 30 - (snr_val - 158000)*15/(900000 - 158000); + /* snr_val:31600~158000,ret:30~50 */ + else if (snr_val > 31600) + ret = 50 - (snr_val - 31600)*20/(158000 - 31600); + /* snr_val:316~31600,ret:50~80 */ + else if (snr_val > 316) + ret = 80 - (snr_val - 316)*30/(31600 - 316); + /* snr_val:0~316,ret:80~100 */ + else + ret = 100 - (316 - snr_val)*20/316; + return ret; +#endif +} + static enum amlatvdemod_snr_level_e aml_atvdemod_get_snr_level(void) { unsigned int snr_val, i, snr_d[8]; @@ -1653,38 +1704,6 @@ void atvdemod_det_snr_serice(void) snr_val = atvdemod_get_snr(NULL); } -void atvdemod_timer_handler(unsigned long arg) -{ - if (atvdemod_timer_en == 0) - return; - - if (vdac_enable_check_dtv()) - return; - - atvdemod_timer.expires = jiffies + ATVDEMOD_INTERVAL*10;/*100ms timer*/ - add_timer(&atvdemod_timer); - if (atvdemod_afc_en) - atvdemod_afc_tune(); - if (atvdemod_monitor_en) - atvdemod_monitor_serice(); - if (audio_det_en) - aml_atvdemod_overmodule_det(); - if (atvdemod_det_snr_en) - atvdemod_det_snr_serice(); - if (audio_thd_en) - audio_thd_det(); -/* - if (aml_atvdemod_get_btsc_sap_mode() == 1 && - aud_std == AUDIO_STANDARD_BTSC) - audio_mode_det(aud_mode); -*/ - if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) - set_outputmode(aud_std, aud_mode); - - if (non_std_onoff) - atv_dmd_non_std_set(true); -} - int atvdemod_clk_init(void) { /* clocks_set_hdtv (); */ @@ -1847,12 +1866,16 @@ int amlfmt_aud_standard(int broad_std) int atvauddemod_init(void) { if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) { + if (audio_thd_en) + audio_thd_init(); + if (aud_auto) aud_std = amlfmt_aud_standard(broad_std); /* configure_adec(aud_std); */ /* adec_soft_reset(); */ set_outputmode(aud_std, aud_mode); } + return 0; } @@ -1863,15 +1886,6 @@ void atvauddemod_set_outputmode(void) int atvdemod_init(void) { - /* unsigned long data32; */ - if (atvdemod_timer_en == 1 && !atv_demod_get_scan_mode()) { - if (timer_init_flag == 1) { - del_timer_sync(&atvdemod_timer); - timer_init_flag = 0; - atv_dmd_non_std_set(false); - } - } - /* 1.set system clock when atv enter*/ pr_err("%s do configure_receiver ...\n", __func__); @@ -1897,34 +1911,17 @@ int atvdemod_init(void) * delay_us(400); * } */ - #if 1/* temp mark */ - if (atvdemod_timer_en == 1 && !atv_demod_get_scan_mode()) { - if (audio_thd_en) - audio_thd_init(); - /*atvdemod timer handler*/ - init_timer(&atvdemod_timer); - /* atvdemod_timer.data = (ulong) devp; */ - atvdemod_timer.function = atvdemod_timer_handler; - /* after 1s enable demod auto detect */ - atvdemod_timer.expires = jiffies + ATVDEMOD_INTERVAL*100; - add_timer(&atvdemod_timer); - mix1_freq = atv_dmd_rd_byte(APB_BLOCK_ADDR_MIXER_1, 0x0); - timer_init_flag = 1; - } - #endif + + mix1_freq = atv_dmd_rd_byte(APB_BLOCK_ADDR_MIXER_1, 0x0); + pr_err("%s done\n", __func__); + return 0; } + void atvdemod_uninit(void) { - /* del the timer */ - if (atvdemod_timer_en == 1) { - if (timer_init_flag == 1) { - del_timer_sync(&atvdemod_timer); - timer_init_flag = 0; - atv_dmd_non_std_set(false); - } - } + atv_dmd_non_std_set(false); } void atv_dmd_set_std(void) diff --git a/drivers/amlogic/atv_demod/atvdemod_func.h b/drivers/amlogic/atv_demod/atvdemod_func.h index b7659069e92d..de5cde44d1b4 100644 --- a/drivers/amlogic/atv_demod/atvdemod_func.h +++ b/drivers/amlogic/atv_demod/atvdemod_func.h @@ -31,8 +31,7 @@ extern unsigned int reg_23cf; /* IIR filter */ extern int broad_std_except_pal_m; extern unsigned int aud_std; extern unsigned int aud_mode; - -#define ATVDEMOD_INTERVAL (HZ/100) /*10ms, #define HZ 100*/ +extern bool audio_thd_en; extern int amlatvdemod_reg_read(unsigned int reg, unsigned int *val); extern int amlatvdemod_reg_write(unsigned int reg, unsigned int val); @@ -177,8 +176,12 @@ extern void retrieve_vpll_carrier_audio_power(int *power); extern void retrieve_video_lock(int *lock); extern int retrieve_vpll_carrier_afc(void); +extern void atv_dmd_non_std_set(bool enable); +extern void atvdemod_monitor_serice(void); +extern void atvdemod_det_snr_serice(void); extern int get_atvdemod_snr_val(void); extern int aml_atvdemod_get_snr(struct dvb_frontend *fe); +extern void atvdemod_afc_tune(void); /*atv demod block address*/ /*address interval is 4, because it's 32bit interface,*/ -- 2.20.1