aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb-frontends
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2013-03-04 06:15:49 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-03-04 14:37:07 -0500
commit0e4bbedd638d6d13b0cfe2c95c75fc3736daec94 (patch)
treebdc113859e2503e298a1d066d6cc0c329507e8a5 /drivers/media/dvb-frontends
parent04fa725e7b1c22c583dd71a8cd85b8d997edfce3 (diff)
[media] mb86a20s: Don't assume a 32.57142MHz clock
Now that some devices initialize register 0x2a with different values, add the calculus formula, instead of hardcoding it. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb-frontends')
-rw-r--r--drivers/media/dvb-frontends/mb86a20s.c26
-rw-r--r--drivers/media/dvb-frontends/mb86a20s.h8
2 files changed, 30 insertions, 4 deletions
diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c
index 1859e9ddba6e..d04b52e3f4cc 100644
--- a/drivers/media/dvb-frontends/mb86a20s.c
+++ b/drivers/media/dvb-frontends/mb86a20s.c
@@ -70,7 +70,6 @@ static struct regdata mb86a20s_init1[] = {
70 { 0x70, 0xff }, 70 { 0x70, 0xff },
71 { 0x08, 0x01 }, 71 { 0x08, 0x01 },
72 { 0x50, 0xd1 }, { 0x51, 0x20 }, 72 { 0x50, 0xd1 }, { 0x51, 0x20 },
73 { 0x28, 0x2a }, { 0x29, 0x00 }, { 0x2a, 0xff }, { 0x2b, 0x80 },
74}; 73};
75 74
76static struct regdata mb86a20s_init2[] = { 75static struct regdata mb86a20s_init2[] = {
@@ -1776,6 +1775,7 @@ static int mb86a20s_initfe(struct dvb_frontend *fe)
1776{ 1775{
1777 struct mb86a20s_state *state = fe->demodulator_priv; 1776 struct mb86a20s_state *state = fe->demodulator_priv;
1778 u64 pll; 1777 u64 pll;
1778 u32 fclk;
1779 int rc; 1779 int rc;
1780 u8 regD5 = 1, reg71, reg09 = 0x3a; 1780 u8 regD5 = 1, reg71, reg09 = 0x3a;
1781 1781
@@ -1810,6 +1810,10 @@ static int mb86a20s_initfe(struct dvb_frontend *fe)
1810 goto err; 1810 goto err;
1811 } 1811 }
1812 1812
1813 fclk = state->config->fclk;
1814 if (!fclk)
1815 fclk = 32571428;
1816
1813 /* Adjust IF frequency to match tuner */ 1817 /* Adjust IF frequency to match tuner */
1814 if (fe->ops.tuner_ops.get_if_frequency) 1818 if (fe->ops.tuner_ops.get_if_frequency)
1815 fe->ops.tuner_ops.get_if_frequency(fe, &state->if_freq); 1819 fe->ops.tuner_ops.get_if_frequency(fe, &state->if_freq);
@@ -1817,6 +1821,24 @@ static int mb86a20s_initfe(struct dvb_frontend *fe)
1817 if (!state->if_freq) 1821 if (!state->if_freq)
1818 state->if_freq = 3300000; 1822 state->if_freq = 3300000;
1819 1823
1824 pll = (((u64)1) << 34) * state->if_freq;
1825 do_div(pll, 63 * fclk);
1826 pll = (1 << 25) - pll;
1827 rc = mb86a20s_writereg(state, 0x28, 0x2a);
1828 if (rc < 0)
1829 goto err;
1830 rc = mb86a20s_writereg(state, 0x29, (pll >> 16) & 0xff);
1831 if (rc < 0)
1832 goto err;
1833 rc = mb86a20s_writereg(state, 0x2a, (pll >> 8) & 0xff);
1834 if (rc < 0)
1835 goto err;
1836 rc = mb86a20s_writereg(state, 0x2b, pll & 0xff);
1837 if (rc < 0)
1838 goto err;
1839 dev_dbg(&state->i2c->dev, "%s: fclk=%d, IF=%d, clock reg=0x%06llx\n",
1840 __func__, fclk, state->if_freq, (long long)pll);
1841
1820 /* pll = freq[Hz] * 2^24/10^6 / 16.285714286 */ 1842 /* pll = freq[Hz] * 2^24/10^6 / 16.285714286 */
1821 pll = state->if_freq * 1677721600L; 1843 pll = state->if_freq * 1677721600L;
1822 do_div(pll, 1628571429L); 1844 do_div(pll, 1628571429L);
@@ -1832,7 +1854,7 @@ static int mb86a20s_initfe(struct dvb_frontend *fe)
1832 rc = mb86a20s_writereg(state, 0x2b, pll & 0xff); 1854 rc = mb86a20s_writereg(state, 0x2b, pll & 0xff);
1833 if (rc < 0) 1855 if (rc < 0)
1834 goto err; 1856 goto err;
1835 dev_dbg(&state->i2c->dev, "%s: IF=%d, PLL=0x%06llx\n", 1857 dev_dbg(&state->i2c->dev, "%s: IF=%d, IF reg=0x%06llx\n",
1836 __func__, state->if_freq, (long long)pll); 1858 __func__, state->if_freq, (long long)pll);
1837 1859
1838 if (!state->config->is_serial) { 1860 if (!state->config->is_serial) {
diff --git a/drivers/media/dvb-frontends/mb86a20s.h b/drivers/media/dvb-frontends/mb86a20s.h
index bf22e77888b9..1a7dea2b237a 100644
--- a/drivers/media/dvb-frontends/mb86a20s.h
+++ b/drivers/media/dvb-frontends/mb86a20s.h
@@ -21,12 +21,16 @@
21/** 21/**
22 * struct mb86a20s_config - Define the per-device attributes of the frontend 22 * struct mb86a20s_config - Define the per-device attributes of the frontend
23 * 23 *
24 * @fclk: Clock frequency. If zero, assumes the default
25 * (32.57142 Mhz)
24 * @demod_address: the demodulator's i2c address 26 * @demod_address: the demodulator's i2c address
27 * @is_serial: if true, TS is serial. Otherwise, TS is parallel
25 */ 28 */
26 29
27struct mb86a20s_config { 30struct mb86a20s_config {
28 u8 demod_address; 31 u32 fclk;
29 bool is_serial; 32 u8 demod_address;
33 bool is_serial;
30}; 34};
31 35
32#if defined(CONFIG_DVB_MB86A20S) || (defined(CONFIG_DVB_MB86A20S_MODULE) \ 36#if defined(CONFIG_DVB_MB86A20S) || (defined(CONFIG_DVB_MB86A20S_MODULE) \