DEBUGFS_CREATE_NODE(audio_nicam_delay, 0640, dentry, u32)\
DEBUGFS_CREATE_NODE(audio_a2_auto, 0640, dentry, u32)\
DEBUGFS_CREATE_NODE(audio_a2_power_threshold, 0640, dentry, u32)\
+ DEBUGFS_CREATE_NODE(audio_a2_carrier_report, 0640, dentry, u32)\
DEBUGFS_CREATE_NODE(audio_gain_shift, 0640, dentry, u32)\
DEBUGFS_CREATE_NODE(audio_gain_lpr, 0640, dentry, u32)\
DEBUGFS_CREATE_NODE(audio_atv_ov, 0640, dentry, u32)\
#include "atvauddemod_func.h"
-#define AMLATVDEMOD_VER "V2.05"
+#define AMLATVDEMOD_VER "V2.06"
struct aml_atvdemod_device *amlatvdemod_devp;
(p->tuner_id == AM_TUNER_SI2151) ||
(p->tuner_id == AM_TUNER_SI2159) ||
(p->tuner_id == AM_TUNER_MXL661))
- reconfig = true;
+ reconfig = false;
/* In general, demod does not need to be reconfigured
* if parameters such as STD remain unchanged,
amlatvdemod_devp->tuner_id = p->tuner_id;
atv_dmd_set_std();
-
+ atvdemod_init(!priv->scanning);
} else
atv_dmd_soft_reset();
static void atvdemod_fe_try_analog_format(struct v4l2_frontend *v4l2_fe,
int auto_search_std, v4l2_std_id *video_fmt,
- unsigned int *audio_fmt)
+ unsigned int *audio_fmt, unsigned int *soundsys)
{
struct dvb_frontend *fe = &v4l2_fe->fe;
struct v4l2_analog_parameters *p = &v4l2_fe->params;
#endif
}
- pr_info("autodet audio mode %d, [%s][0x%x]\n",
- broad_std, v4l2_std_to_str(audio), audio);
-
*audio_fmt = audio;
+
+ /* for audio standard detection */
+ if (is_meson_txlx_cpu() || is_meson_txhd_cpu() || is_meson_tl1_cpu()) {
+ *soundsys = amlfmt_aud_standard(broad_std);
+ *soundsys = (*soundsys << 16) | 0x00FFFF;
+ } else
+ *soundsys = 0xFFFFFF;
+
+ pr_info("autodet audio broad_std %d, [%s][0x%x] soundsys[0x%x]\n",
+ broad_std, v4l2_std_to_str(audio), audio, *soundsys);
}
static int atvdemod_fe_afc_closer(struct v4l2_frontend *v4l2_fe, int minafcfreq,
static int atvdemod_fe_set_property(struct v4l2_frontend *v4l2_fe,
struct v4l2_property *tvp)
{
- struct dvb_frontend *fe = &amlatvdemod_devp->v4l2_fe.fe;
+ struct dvb_frontend *fe = &v4l2_fe->fe;
struct atv_demod_priv *priv = fe->analog_demod_priv;
+ struct v4l2_analog_parameters *params = &v4l2_fe->params;
pr_dbg("%s: cmd = 0x%x.\n", __func__, tvp->cmd);
case V4L2_SOUND_SYS:
/* aud_mode = tvp->data & 0xFF; */
amlatvdemod_devp->soundsys = tvp->data & 0xFF;
- if (amlatvdemod_devp->soundsys != 0xFF)
+ if (amlatvdemod_devp->soundsys != 0xFF) {
aud_mode = amlatvdemod_devp->soundsys;
+ params->soundsys = aud_mode;
+ }
priv->sound_sys.output_mode = tvp->data & 0xFF;
break;
int tuner_status_cnt_local = tuner_status_cnt;
v4l2_std_id std_bk = 0;
unsigned int audio = 0;
+ unsigned int soundsys = 0;
int double_check_cnt = 1;
int auto_search_std = 0;
int search_count = 0;
*/
if (p->std == 0) {
p->std = V4L2_COLOR_STD_NTSC | V4L2_STD_NTSC_M;
+ /* p->std = V4L2_COLOR_STD_PAL | V4L2_STD_DK; */
auto_search_std = 0x01;
pr_dbg("[%s] user std is 0, so set it to NTSC | M.\n",
__func__);
pr_dbg("[%s] freq: [%d] pll lock success\n",
__func__, p->frequency);
-#if 0 /* In get_pll_status has line_lock check.*/
- if (fee->tuner->drv->id == AM_TUNER_MXL661) {
- fe->ops.analog_ops.get_atv_status(fe,
- &atv_status);
- if (atv_status.atv_lock)
- usleep_range(30 * 1000,
- 30 * 1000 + 100);
- }
-#endif
+
ret = atvdemod_fe_afc_closer(v4l2_fe, minafcfreq,
maxafcfreq + ATV_AFC_500KHZ, 1);
if (ret == 0) {
atvdemod_fe_try_analog_format(v4l2_fe,
auto_search_std,
- &std_bk, &audio);
+ &std_bk, &audio, &soundsys);
pr_dbg("[%s] freq:%d, std_bk:0x%x, audmode:0x%x, search OK.\n",
__func__, p->frequency,
p->std = std_bk;
/*avoid std unenable */
p->frequency -= 1;
+ p->soundsys = soundsys;
std_bk = 0;
audio = 0;
}
poll_wait(filp, &fepriv->events.wait_queue, pts);
if (fepriv->events.eventw != fepriv->events.eventr) {
- pr_dbg("%s: POLLIN | POLLRDNORM | POLLPRI.\n", __func__);
+ pr_dbg("%s: POLLIN | POLLRDNORM | POLLPRI.\n", __func__);
return (POLLIN | POLLRDNORM | POLLPRI);
}
struct v4l2_property *tvp, struct file *file)
{
int r = 0;
+ struct v4l2_analog_parameters *params = &v4l2_fe->params;
v4l2_property_dump(v4l2_fe, true, tvp);
switch (tvp->cmd) {
case V4L2_TUNE:
+ v4l2_set_frontend(v4l2_fe, params);
break;
case V4L2_SOUND_SYS:
case V4L2_SLOW_SEARCH_MODE:
return r;
}
break;
+ case V4L2_FREQUENCY:
+ params->frequency = tvp->data;
+ break;
+ case V4L2_STD:
+ /* std & 0xFF000000: color std */
+ /* std & 0x00FFFFFF: audio std */
+ if (tvp->data & 0xFF000000)
+ params->std = (tvp->data & 0xFF000000);
+ if (tvp->data & 0x00FFFFFF) {
+ params->audmode = params->std & 0xFFFFFF;
+ params->std = (tvp->data & 0xFF000000)
+ | (params->audmode);
+ }
+ break;
default:
return -EINVAL;
}
struct v4l2_property *tvp, struct file *file)
{
int r = 0;
+ struct v4l2_analog_parameters *params = &v4l2_fe->params;
switch (tvp->cmd) {
case V4L2_SOUND_SYS:
return r;
}
break;
-
+ case V4L2_FREQUENCY:
+ tvp->data = params->frequency;
+ break;
+ case V4L2_STD:
+ /* std & 0xFF000000: color std */
+ /* std & 0x00FFFFFF: audio std */
+ tvp->data = params->std;
+ break;
default:
pr_dbg("%s: V4L2 property %d doesn't exist\n",
__func__, tvp->cmd);
#define V4L2_TUNE 1
#define V4L2_SOUND_SYS 2
#define V4L2_SLOW_SEARCH_MODE 3
-
+#define V4L2_FREQUENCY 4
+#define V4L2_STD 5
struct v4l2_frontend;
unsigned int audio_a2_auto = 1;
unsigned int audio_a2_power_threshold = 0x1800;
+unsigned int audio_a2_carrier_report = 0x600;
static int last_nicam_lock = -1;
static int last_nicam_mono_flag = -1;
aa = (int)((FCLK-5.85e6)/FCLK*1024.0*1024.0*16.0);
adec_wr_reg(0x110, aa);
}
+
+void set_mono_m(void)
+{
+ int aa;
+
+ adec_wr_reg(ADDR_ADEC_CTRL, 0x2);
+
+ set_filter(filter_50k, ADDR_DDC_FIR0_COEF, 65);
+ set_filter(filter_50k, ADDR_DDC_FIR1_COEF, 65);
+
+ aa = (int)(4.5e6/FCLK*1024.0*1024.0*8.0);
+ adec_wr_reg(ADDR_DDC_FREQ0, aa);
+
+ set_lpf15k();
+ set_deem(0);
+
+ adec_wr_reg(ADDR_DEMOD_GAIN, 0x12);
+
+ adec_wr_reg(ADDR_LPR_GAIN_ADJ, 0x200);
+
+ adec_wr_reg((ADDR_SEL_CTRL), 0x1000);
+
+ set_lpf15k();
+ set_deem(0);
+}
+
+void set_mono_dk(void)
+{
+ int aa;
+
+ adec_wr_reg(ADDR_ADEC_CTRL, 0xa);
+
+ set_filter(filter_100k, ADDR_DDC_FIR0_COEF, 65);
+ set_filter(filter_100k, ADDR_DDC_FIR1_COEF, 65);
+
+ aa = (int)(6.5e6/FCLK*1024.0*1024.0*8.0);
+ adec_wr_reg(ADDR_DDC_FREQ0, aa);
+
+ adec_wr_reg(ADDR_LPR_GAIN_ADJ, 0x200);
+
+ set_deem(1);
+ set_lpf15k();
+}
+
+void set_mono_i(void)
+{
+ int aa;
+
+ adec_wr_reg(ADDR_ADEC_CTRL, 0x7);
+
+ set_filter(filter_100k, ADDR_DDC_FIR0_COEF, 65);
+ set_filter(filter_100k, ADDR_DDC_FIR1_COEF, 65);
+
+ aa = (int)(6.0e6/FCLK*1024.0*1024.0*8.0);
+ adec_wr_reg(ADDR_DDC_FREQ0, aa);
+ adec_wr_reg(ADDR_LPR_GAIN_ADJ, 0x200);
+
+ set_deem(1);
+ set_lpf15k();
+}
+
+void set_mono_bg(void)
+{
+ int aa;
+
+ adec_wr_reg(ADDR_ADEC_CTRL, 0x8);
+
+ set_filter(filter_100k, ADDR_DDC_FIR0_COEF, 65);
+ set_filter(filter_100k, ADDR_DDC_FIR1_COEF, 65);
+
+ aa = (int)(5.5e6/FCLK*1024.0*1024.0*8.0);
+ adec_wr_reg(ADDR_DDC_FREQ0, aa);
+ adec_wr_reg(ADDR_LPR_GAIN_ADJ, 0x200);
+
+ set_deem(1);
+ set_lpf15k();
+}
+
+void set_mono_l(void)
+{
+ int aa;
+
+ adec_wr_reg(ADDR_ADEC_CTRL, 0x9);
+
+ set_filter(filter_100k, ADDR_DDC_FIR0_COEF, 65);
+ set_filter(filter_100k, ADDR_DDC_FIR1_COEF, 65);
+
+ aa = (int)(6.5e6/FCLK*1024.0*1024.0*8.0);
+ adec_wr_reg(ADDR_DDC_FREQ0, aa);
+ adec_wr_reg(ADDR_LPR_GAIN_ADJ, 0x200);
+
+ set_deem(1);
+ set_lpf15k();
+}
+
static void set_standard(uint32_t standard)
{
pr_info("\n<<<<<<<<<<<<<<< start configure register\n");
pr_info("<<<<<<<<<<<<<<< Set NICAM L and Test\n");
set_nicam_l();
break;
+ case AUDIO_STANDARD_MONO_M:
+ pr_info("<<<<<<<<<<<<<<< Set mono M and Test\n");
+ set_mono_m();
+ break;
+ case AUDIO_STANDARD_MONO_DK:
+ pr_info("<<<<<<<<<<<<<<< Set mono DK and Test\n");
+ set_mono_dk();
+ break;
+ case AUDIO_STANDARD_MONO_I:
+ pr_info("<<<<<<<<<<<<<<< Set mono I and Test\n");
+ set_mono_i();
+ break;
+ case AUDIO_STANDARD_MONO_BG:
+ pr_info("<<<<<<<<<<<<<<< Set mono BG and Test\n");
+ set_mono_bg();
+ break;
+ case AUDIO_STANDARD_MONO_L:
+ pr_info("<<<<<<<<<<<<<<< Set mono L and Test\n");
+ set_mono_l();
+ break;
}
pr_info("\n<<<<<<<<<<<<<<< configure register finished\n");
if (auto_en) {
reg_value = adec_rd_reg(CARRIER_MAG_REPORT);
- if (((reg_value >> 16) & 0xffff) < 0x400) {
+ if (((reg_value >> 16) & 0xffff) < audio_a2_carrier_report) {
*stereo_flag = 0;
*dual_flag = 0;
} else {
unsigned int aud_mode = AUDIO_OUTMODE_STEREO;
bool aud_auto = true;
bool aud_reinit;
+bool aud_mono_only;
unsigned long over_threshold = 0xffff;
unsigned long input_amplitude = 0xffff;
atv_dmd_wr_byte(APB_BLOCK_ADDR_SYSTEM_MGT, 0x0, 0x0);
atv_dmd_wr_byte(APB_BLOCK_ADDR_SYSTEM_MGT, 0x0, 0x1);
atv_dmd_wr_long(0x1d, 0x0, 0x1037);/* enable dac */
+
+ /* for +-0.5M scanning lose */
+ atv_dmd_wr_long(APB_BLOCK_ADDR_CARR_RCVY, 0x24, 0xc010301);
}
void atv_dmd_input_clk_32m(void)
switch (broad_std) {
case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M:
case AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC:
+ if (aud_mono_only) {
+ std = AUDIO_STANDARD_MONO_M;
+ aud_mode = AUDIO_OUTMODE_MONO;
+ configure_adec(std);
+ adec_soft_reset();
+ break;
+ }
+
std = AUDIO_STANDARD_A2_K;
configure_adec(std);
adec_soft_reset();
/* maybe need wait */
reg_value = adec_rd_reg(CARRIER_MAG_REPORT);
- pr_info("\n%s 0x%x\n", __func__, (reg_value>>16)&0xffff);
+ pr_info("\n%s CARRIER_MAG_REPORT: 0x%x\n",
+ __func__, (reg_value >> 16) & 0xffff);
if (((reg_value>>16)&0xffff) > audio_a2_threshold) {
std = AUDIO_STANDARD_A2_K;
if (amlatvdemod_devp->soundsys == 0xFF)
}
break;
case AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_J:
+ if (aud_mono_only) {
+ std = AUDIO_STANDARD_MONO_M;
+ aud_mode = AUDIO_OUTMODE_MONO;
+ configure_adec(std);
+ adec_soft_reset();
+ break;
+ }
+
std = AUDIO_STANDARD_EIAJ;
configure_adec(std);
adec_soft_reset();
break;
case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG:
+ if (aud_mono_only) {
+ std = AUDIO_STANDARD_MONO_BG;
+ aud_mode = AUDIO_OUTMODE_MONO;
+ configure_adec(std);
+ adec_soft_reset();
+ break;
+ }
+
std = AUDIO_STANDARD_NICAM_BG;
configure_adec(std);
adec_soft_reset();
retrieve_vpll_carrier_line_lock(&line_lock);
reg_value = adec_rd_reg(NICAM_LEVEL_REPORT);
- nicam_lock = (reg_value>>28)&1;
- pr_info("\n%s 0x%x\n", __func__, reg_value);
+ nicam_lock = (reg_value >> 28) & 1;
+ pr_info("\n%s NICAM_LEVEL_REPORT: 0x%x\n",
+ __func__, reg_value);
if (nicam_lock) {
std = AUDIO_STANDARD_NICAM_BG;
if (amlatvdemod_devp->soundsys == 0xFF)
}
break;
case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK:
+ if (aud_mono_only) {
+ std = AUDIO_STANDARD_MONO_DK;
+ aud_mode = AUDIO_OUTMODE_MONO;
+ configure_adec(std);
+ adec_soft_reset();
+ break;
+ }
+
std = AUDIO_STANDARD_NICAM_DK;
configure_adec(std);
adec_soft_reset();
retrieve_vpll_carrier_line_lock(&line_lock);
reg_value = adec_rd_reg(NICAM_LEVEL_REPORT);
- nicam_lock = (reg_value>>28)&1;
- pr_info("\n%s 0x%x\n", __func__, reg_value);
+ nicam_lock = (reg_value >> 28) & 1;
+ pr_info("\n%s NICAM_LEVEL_REPORT: 0x%x\n",
+ __func__, reg_value);
if (nicam_lock) {
std = AUDIO_STANDARD_NICAM_DK;
if (amlatvdemod_devp->soundsys == 0xFF)
}
break;
case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_I:
+ if (aud_mono_only) {
+ std = AUDIO_STANDARD_MONO_I;
+ aud_mode = AUDIO_OUTMODE_MONO;
+ configure_adec(std);
+ adec_soft_reset();
+ break;
+ }
+
std = AUDIO_STANDARD_NICAM_I;
configure_adec(std);
adec_soft_reset();
+ msleep(audio_nicam_delay);
+ /* need wait */
+
+ retrieve_vpll_carrier_lock(&vpll_lock);
+ retrieve_vpll_carrier_line_lock(&line_lock);
+
+ reg_value = adec_rd_reg(NICAM_LEVEL_REPORT);
+ nicam_lock = (reg_value >> 28) & 1;
+ pr_info("\n%s NICAM_LEVEL_REPORT: 0x%x\n",
+ __func__, reg_value);
+ if (nicam_lock) {
+ std = AUDIO_STANDARD_NICAM_I;
+ if (amlatvdemod_devp->soundsys == 0xFF)
+ aud_mode = AUDIO_OUTMODE_NICAM_STEREO;
+ else
+ aud_mode = amlatvdemod_devp->soundsys;
+ } else {
+ std = AUDIO_STANDARD_MONO_I;
+ aud_mode = AUDIO_OUTMODE_MONO;
+ configure_adec(std);
+ adec_soft_reset();
+ }
break;
case AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_L:
+ if (aud_mono_only) {
+ std = AUDIO_STANDARD_MONO_L;
+ aud_mode = AUDIO_OUTMODE_MONO;
+ configure_adec(std);
+ adec_soft_reset();
+ break;
+ }
+
std = AUDIO_STANDARD_NICAM_L;
configure_adec(std);
adec_soft_reset();
+ msleep(audio_nicam_delay);
+ /* need wait */
+
+ retrieve_vpll_carrier_lock(&vpll_lock);
+ retrieve_vpll_carrier_line_lock(&line_lock);
+
+ reg_value = adec_rd_reg(NICAM_LEVEL_REPORT);
+ nicam_lock = (reg_value >> 28) & 1;
+ pr_info("\n%s NICAM_LEVEL_REPORT: 0x%x\n",
+ __func__, reg_value);
+ if (nicam_lock) {
+ std = AUDIO_STANDARD_NICAM_L;
+ if (amlatvdemod_devp->soundsys == 0xFF)
+ aud_mode = AUDIO_OUTMODE_NICAM_STEREO;
+ else
+ aud_mode = amlatvdemod_devp->soundsys;
+ } else {
+ std = AUDIO_STANDARD_MONO_L;
+ aud_mode = AUDIO_OUTMODE_MONO;
+ configure_adec(std);
+ adec_soft_reset();
+ }
break;
}
}
}
-int atvdemod_init(void)
+int atvdemod_init(bool on)
{
/* 1.set system clock when atv enter*/
pr_dbg("%s do atv_dmd_misc ...\n", __func__);
atv_dmd_misc();
- if (broad_std == AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_M ||
- broad_std == AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC)
+ if (on && (broad_std == AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_M ||
+ broad_std == AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC))
atv_dmd_ring_filter(true);
else
atv_dmd_ring_filter(false);
pr_dbg("[%s] set if_freq %d, if_inv %d.\n",
__func__, amlatvdemod_devp->if_freq,
amlatvdemod_devp->if_inv);
-
- if (atvdemod_init())
- pr_info("[%s]: atv restart error.\n", __func__);
}
int aml_audiomode_autodet(struct v4l2_frontend *v4l2_fe)
bool ntsc_signal = false;
bool pal_signal = false;
bool has_audio = false;
-#if 0
- temp_data = atv_dmd_rd_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02);
- temp_data = temp_data | 0x80;/* 0x40 */
- atv_dmd_wr_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02, temp_data);
-#endif
switch (broad_std) {
case AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK:
ntsc_signal = true;
broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M;
break;
-#if 0 /* ntsc will try other audio */
- broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_M;
- atvdemod_init();
- temp_data = atv_dmd_rd_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02);
- temp_data = temp_data & (~0x80); /* 0xbf; */
- atv_dmd_wr_reg(APB_BLOCK_ADDR_SIF_STG_2, 0x02, temp_data);
- /* pr_err("%s, SECAM ,audio set SECAM_L\n", __func__); */
- return broad_std;
-#endif
case AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_L:
case AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_DK2:
case AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_DK3:
broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M;
} else {
broad_std = AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_L;
- atvdemod_init();
+ atvdemod_init(false);
temp_data = atv_dmd_rd_reg(APB_BLOCK_ADDR_SIF_STG_2,
0x02);
int Tuner_Input_IF_inverted, int GDE_Curve,
int sound_format);
extern int atvdemod_clk_init(void);
-extern int atvdemod_init(void);
+extern int atvdemod_init(bool on);
extern void atvdemod_uninit(void);
extern void atv_dmd_set_std(void);
extern void retrieve_adc_power(int *adc_level);
extern void retrieve_field_lock(int *lock);
extern void set_atvdemod_scan_mode(int val);
extern int atvauddemod_init(void);
+extern int amlfmt_aud_standard(int broad_std);
extern void atvauddemod_set_outputmode(void);
/*from amldemod/amlfrontend.c*/
#define AUDIO_STANDARD_INDIAN 0x0F
#define AUDIO_STANDARD_BTSC_SA 0x10
#define AUDIO_STANDARD_MONO_ONLY 0x11
+#define AUDIO_STANDARD_MONO_BG 0x12
+#define AUDIO_STANDARD_MONO_DK 0x13
+#define AUDIO_STANDARD_MONO_I 0x14
+#define AUDIO_STANDARD_MONO_M 0x15
+#define AUDIO_STANDARD_MONO_L 0x16
#define AUDIO_OUTMODE_MONO 0
#define AUDIO_OUTMODE_STEREO 1