aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2013-04-11 14:04:54 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-04-16 20:37:17 -0400
commitc0c6ed8d0479d47949e2345510b8fc8af41f7ed2 (patch)
tree60783566d681992402c4011c58cd4dc2c8abaafb
parent064fd169c508ce20e35babdd82946dab7219ccc5 (diff)
[media] r820t: fix PLL calculus
There are a few errors at the PLL calculus, causing the device to use wrong values. While here, change the calculus to use 32 bits, as there's no need for 64 bits there. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com> Tested-by: Antti Palosaari <crope@iki.fi>
-rw-r--r--drivers/media/tuners/r820t.c27
1 files changed, 10 insertions, 17 deletions
diff --git a/drivers/media/tuners/r820t.c b/drivers/media/tuners/r820t.c
index b679a3f1fb7a..f5a5fb03dfd5 100644
--- a/drivers/media/tuners/r820t.c
+++ b/drivers/media/tuners/r820t.c
@@ -36,7 +36,6 @@
36#include <linux/mutex.h> 36#include <linux/mutex.h>
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/bitrev.h> 38#include <linux/bitrev.h>
39#include <asm/div64.h>
40 39
41#include "tuner-i2c.h" 40#include "tuner-i2c.h"
42#include "r820t.h" 41#include "r820t.h"
@@ -540,7 +539,7 @@ static int r820t_set_mux(struct r820t_priv *priv, u32 freq)
540static int r820t_set_pll(struct r820t_priv *priv, enum v4l2_tuner_type type, 539static int r820t_set_pll(struct r820t_priv *priv, enum v4l2_tuner_type type,
541 u32 freq) 540 u32 freq)
542{ 541{
543 u64 tmp64, vco_freq; 542 u32 vco_freq;
544 int rc, i; 543 int rc, i;
545 unsigned sleep_time = 10000; 544 unsigned sleep_time = 10000;
546 u32 vco_fra; /* VCO contribution by SDM (kHz) */ 545 u32 vco_fra; /* VCO contribution by SDM (kHz) */
@@ -576,9 +575,6 @@ static int r820t_set_pll(struct r820t_priv *priv, enum v4l2_tuner_type type,
576 } 575 }
577 } 576 }
578 577
579 tuner_dbg("set r820t pll for frequency %d kHz = %d%s\n",
580 freq, pll_ref, refdiv2 ? " / 2" : "");
581
582 rc = r820t_write_reg_mask(priv, 0x10, refdiv2, 0x10); 578 rc = r820t_write_reg_mask(priv, 0x10, refdiv2, 0x10);
583 if (rc < 0) 579 if (rc < 0)
584 return rc; 580 return rc;
@@ -622,15 +618,9 @@ static int r820t_set_pll(struct r820t_priv *priv, enum v4l2_tuner_type type,
622 if (rc < 0) 618 if (rc < 0)
623 return rc; 619 return rc;
624 620
625 vco_freq = (u64)(freq * (u64)mix_div); 621 vco_freq = freq * mix_div;
626 622 nint = vco_freq / (2 * pll_ref);
627 tmp64 = vco_freq; 623 vco_fra = vco_freq - 2 * pll_ref * nint;
628 do_div(tmp64, 2 * pll_ref);
629 nint = (u8)tmp64;
630
631 tmp64 = vco_freq - ((u64)2) * pll_ref * nint;
632 do_div(tmp64, 1000);
633 vco_fra = (u16)(tmp64);
634 624
635 /* boundary spur prevention */ 625 /* boundary spur prevention */
636 if (vco_fra < pll_ref / 64) { 626 if (vco_fra < pll_ref / 64) {
@@ -677,10 +667,13 @@ static int r820t_set_pll(struct r820t_priv *priv, enum v4l2_tuner_type type,
677 n_sdm = n_sdm << 1; 667 n_sdm = n_sdm << 1;
678 } 668 }
679 669
680 rc = r820t_write_reg_mask(priv, 0x16, sdm >> 8, 0x08); 670 tuner_dbg("freq %d kHz, pll ref %d%s, sdm=0x%04x\n",
671 freq, pll_ref, refdiv2 ? " / 2" : "", sdm);
672
673 rc = r820t_write_reg(priv, 0x16, sdm >> 8);
681 if (rc < 0) 674 if (rc < 0)
682 return rc; 675 return rc;
683 rc = r820t_write_reg_mask(priv, 0x15, sdm & 0xff, 0x08); 676 rc = r820t_write_reg(priv, 0x15, sdm & 0xff);
684 if (rc < 0) 677 if (rc < 0)
685 return rc; 678 return rc;
686 679
@@ -1068,7 +1061,7 @@ static int r820t_set_tv_standard(struct r820t_priv *priv,
1068 if (rc < 0) 1061 if (rc < 0)
1069 return rc; 1062 return rc;
1070 1063
1071 rc = r820t_set_pll(priv, type, filt_cal_lo); 1064 rc = r820t_set_pll(priv, type, filt_cal_lo * 1000);
1072 if (rc < 0 || !priv->has_lock) 1065 if (rc < 0 || !priv->has_lock)
1073 return rc; 1066 return rc;
1074 1067