Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d75d5388 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

[media] r820t: proper initialize the PLL register



The rtl-sdr library, from where this driver was initially
based, doesn't use half PLL clock, but this is used on
the Realtek Kernel driver. So, also do the same here.

Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
Tested-by: default avatarAntti Palosaari <crope@iki.fi>
parent 9cc2570a
Loading
Loading
Loading
Loading
+28 −15
Original line number Original line Diff line number Diff line
@@ -522,10 +522,12 @@ static int r820t_set_mux(struct r820t_priv *priv, u32 freq)
	return rc;
	return rc;
}
}


static int r820t_set_pll(struct r820t_priv *priv, u32 freq)
static int r820t_set_pll(struct r820t_priv *priv, enum v4l2_tuner_type type,
			 u32 freq)
{
{
	u64 tmp64, vco_freq;
	u64 tmp64, vco_freq;
	int rc, i;
	int rc, i;
	unsigned sleep_time = 10000;
	u32 vco_fra;		/* VCO contribution by SDM (kHz) */
	u32 vco_fra;		/* VCO contribution by SDM (kHz) */
	u32 vco_min  = 1770000;
	u32 vco_min  = 1770000;
	u32 vco_max  = vco_min * 2;
	u32 vco_max  = vco_min * 2;
@@ -535,17 +537,34 @@ static int r820t_set_pll(struct r820t_priv *priv, u32 freq)
	u8 mix_div = 2;
	u8 mix_div = 2;
	u8 div_buf = 0;
	u8 div_buf = 0;
	u8 div_num = 0;
	u8 div_num = 0;
	u8 refdiv2 = 0;
	u8 ni, si, nint, vco_fine_tune, val;
	u8 ni, si, nint, vco_fine_tune, val;
	u8 data[5];
	u8 data[5];


	freq = freq / 1000;	/* Frequency in kHz */
	/* Frequency in kHz */

	freq = freq / 1000;
	pll_ref = priv->cfg->xtal / 1000;
	pll_ref = priv->cfg->xtal / 1000;


	tuner_dbg("set r820t pll for frequency %d kHz = %d\n", freq, pll_ref);
	if ((priv->cfg->rafael_chip == CHIP_R620D) ||
	   (priv->cfg->rafael_chip == CHIP_R828D) ||
	   (priv->cfg->rafael_chip == CHIP_R828)) {
		/* ref set refdiv2, reffreq = Xtal/2 on ATV application */
		if (type != V4L2_TUNER_DIGITAL_TV) {
			pll_ref /= 2;
			refdiv2 = 0x10;
			sleep_time = 20000;
		}
	} else {
		if (priv->cfg->xtal > 24000000) {
			pll_ref /= 2;
			refdiv2 = 0x10;
		}
	}


	/* FIXME: this seems to be a hack - probably it can be removed */
	tuner_dbg("set r820t pll for frequency %d kHz = %d%s\n",
	rc = r820t_write_reg_mask(priv, 0x10, 0x00, 0x00);
		  freq, pll_ref, refdiv2 ? " / 2" : "");

	rc = r820t_write_reg_mask(priv, 0x10, refdiv2, 0x10);
	if (rc < 0)
	if (rc < 0)
		return rc;
		return rc;


@@ -598,8 +617,6 @@ static int r820t_set_pll(struct r820t_priv *priv, u32 freq)
	do_div(tmp64, 1000);
	do_div(tmp64, 1000);
	vco_fra  = (u16)(tmp64);
	vco_fra  = (u16)(tmp64);


	pll_ref /= 1000;

	/* boundary spur prevention */
	/* boundary spur prevention */
	if (vco_fra < pll_ref / 64) {
	if (vco_fra < pll_ref / 64) {
		vco_fra = 0;
		vco_fra = 0;
@@ -653,11 +670,7 @@ static int r820t_set_pll(struct r820t_priv *priv, u32 freq)
		return rc;
		return rc;


	for (i = 0; i < 2; i++) {
	for (i = 0; i < 2; i++) {
		/*
		usleep_range(sleep_time, sleep_time + 1000);
		 * FIXME: Rafael chips R620D, R828D and R828 seems to
		 * need 20 ms for analog TV
		 */
		usleep_range(10000, 11000);


		/* Check if PLL has locked */
		/* Check if PLL has locked */
		rc = r820t_read(priv, 0x00, data, 3);
		rc = r820t_read(priv, 0x00, data, 3);
@@ -1040,7 +1053,7 @@ static int r820t_set_tv_standard(struct r820t_priv *priv,
			if (rc < 0)
			if (rc < 0)
				return rc;
				return rc;


			rc = r820t_set_pll(priv, filt_cal_lo);
			rc = r820t_set_pll(priv, type, filt_cal_lo);
			if (rc < 0 || !priv->has_lock)
			if (rc < 0 || !priv->has_lock)
				return rc;
				return rc;


@@ -1244,7 +1257,7 @@ static int generic_set_freq(struct dvb_frontend *fe,
	if (rc < 0)
	if (rc < 0)
		goto err;
		goto err;


	rc = r820t_set_pll(priv, lo_freq);
	rc = r820t_set_pll(priv, type, lo_freq);
	if (rc < 0 || !priv->has_lock)
	if (rc < 0 || !priv->has_lock)
		goto err;
		goto err;


+3 −0
Original line number Original line Diff line number Diff line
@@ -26,6 +26,9 @@


enum r820t_chip {
enum r820t_chip {
	CHIP_R820T,
	CHIP_R820T,
	CHIP_R620D,
	CHIP_R828D,
	CHIP_R828,
	CHIP_R828S,
	CHIP_R828S,
	CHIP_R820C,
	CHIP_R820C,
};
};