aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb-frontends/mb86a20s.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2013-02-28 14:45:39 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-03-04 14:32:33 -0500
commit768e6dadd748ecceee852def1f7f71aac4cd35a1 (patch)
tree31950f5638a41a5a9e8af06c7ae13b5f17c6476e /drivers/media/dvb-frontends/mb86a20s.c
parentd56e326f7b7f409f0390517b0a29d65b4d60c14c (diff)
[media] mb86a20s: adjust IF based on what's set on the tuner
Instead of hardcoding a fixed IF frequency of 3.3 MHz, use the IF frequency provided by the tuner driver. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb-frontends/mb86a20s.c')
-rw-r--r--drivers/media/dvb-frontends/mb86a20s.c57
1 files changed, 53 insertions, 4 deletions
diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c
index 44bfb884ba11..daeee814e491 100644
--- a/drivers/media/dvb-frontends/mb86a20s.c
+++ b/drivers/media/dvb-frontends/mb86a20s.c
@@ -31,6 +31,8 @@ struct mb86a20s_state {
31 31
32 struct dvb_frontend frontend; 32 struct dvb_frontend frontend;
33 33
34 u32 if_freq;
35
34 u32 estimated_rate[3]; 36 u32 estimated_rate[3];
35 37
36 bool need_init; 38 bool need_init;
@@ -47,7 +49,7 @@ struct regdata {
47 * Initialization sequence: Use whatevere default values that PV SBTVD 49 * Initialization sequence: Use whatevere default values that PV SBTVD
48 * does on its initialisation, obtained via USB snoop 50 * does on its initialisation, obtained via USB snoop
49 */ 51 */
50static struct regdata mb86a20s_init[] = { 52static struct regdata mb86a20s_init1[] = {
51 { 0x70, 0x0f }, 53 { 0x70, 0x0f },
52 { 0x70, 0xff }, 54 { 0x70, 0xff },
53 { 0x08, 0x01 }, 55 { 0x08, 0x01 },
@@ -56,7 +58,9 @@ static struct regdata mb86a20s_init[] = {
56 { 0x39, 0x01 }, 58 { 0x39, 0x01 },
57 { 0x71, 0x00 }, 59 { 0x71, 0x00 },
58 { 0x28, 0x2a }, { 0x29, 0x00 }, { 0x2a, 0xff }, { 0x2b, 0x80 }, 60 { 0x28, 0x2a }, { 0x29, 0x00 }, { 0x2a, 0xff }, { 0x2b, 0x80 },
59 { 0x28, 0x20 }, { 0x29, 0x33 }, { 0x2a, 0xdf }, { 0x2b, 0xa9 }, 61};
62
63static struct regdata mb86a20s_init2[] = {
60 { 0x28, 0x22 }, { 0x29, 0x00 }, { 0x2a, 0x1f }, { 0x2b, 0xf0 }, 64 { 0x28, 0x22 }, { 0x29, 0x00 }, { 0x2a, 0x1f }, { 0x2b, 0xf0 },
61 { 0x3b, 0x21 }, 65 { 0x3b, 0x21 },
62 { 0x3c, 0x3a }, 66 { 0x3c, 0x3a },
@@ -1737,6 +1741,7 @@ static int mb86a20s_get_stats(struct dvb_frontend *fe)
1737static int mb86a20s_initfe(struct dvb_frontend *fe) 1741static int mb86a20s_initfe(struct dvb_frontend *fe)
1738{ 1742{
1739 struct mb86a20s_state *state = fe->demodulator_priv; 1743 struct mb86a20s_state *state = fe->demodulator_priv;
1744 u64 pll;
1740 int rc; 1745 int rc;
1741 u8 regD5 = 1; 1746 u8 regD5 = 1;
1742 1747
@@ -1746,10 +1751,35 @@ static int mb86a20s_initfe(struct dvb_frontend *fe)
1746 fe->ops.i2c_gate_ctrl(fe, 0); 1751 fe->ops.i2c_gate_ctrl(fe, 0);
1747 1752
1748 /* Initialize the frontend */ 1753 /* Initialize the frontend */
1749 rc = mb86a20s_writeregdata(state, mb86a20s_init); 1754 rc = mb86a20s_writeregdata(state, mb86a20s_init1);
1750 if (rc < 0) 1755 if (rc < 0)
1751 goto err; 1756 goto err;
1752 1757
1758 /* Adjust IF frequency to match tuner */
1759 if (fe->ops.tuner_ops.get_if_frequency)
1760 fe->ops.tuner_ops.get_if_frequency(fe, &state->if_freq);
1761
1762 if (!state->if_freq)
1763 state->if_freq = 3300000;
1764
1765 /* pll = freq[Hz] * 2^24/10^6 / 16.285714286 */
1766 pll = state->if_freq * 1677721600L;
1767 do_div(pll, 1628571429L);
1768 rc = mb86a20s_writereg(state, 0x28, 0x20);
1769 if (rc < 0)
1770 goto err;
1771 rc = mb86a20s_writereg(state, 0x29, (pll >> 16) & 0xff);
1772 if (rc < 0)
1773 goto err;
1774 rc = mb86a20s_writereg(state, 0x2a, (pll >> 8) & 0xff);
1775 if (rc < 0)
1776 goto err;
1777 rc = mb86a20s_writereg(state, 0x2b, pll & 0xff);
1778 if (rc < 0)
1779 goto err;
1780 dev_dbg(&state->i2c->dev, "%s: IF=%d, PLL=0x%06llx\n",
1781 __func__, state->if_freq, (long long)pll);
1782
1753 if (!state->config->is_serial) { 1783 if (!state->config->is_serial) {
1754 regD5 &= ~1; 1784 regD5 &= ~1;
1755 1785
@@ -1761,6 +1791,11 @@ static int mb86a20s_initfe(struct dvb_frontend *fe)
1761 goto err; 1791 goto err;
1762 } 1792 }
1763 1793
1794 rc = mb86a20s_writeregdata(state, mb86a20s_init2);
1795 if (rc < 0)
1796 goto err;
1797
1798
1764err: 1799err:
1765 if (fe->ops.i2c_gate_ctrl) 1800 if (fe->ops.i2c_gate_ctrl)
1766 fe->ops.i2c_gate_ctrl(fe, 1); 1801 fe->ops.i2c_gate_ctrl(fe, 1);
@@ -1779,7 +1814,7 @@ err:
1779static int mb86a20s_set_frontend(struct dvb_frontend *fe) 1814static int mb86a20s_set_frontend(struct dvb_frontend *fe)
1780{ 1815{
1781 struct mb86a20s_state *state = fe->demodulator_priv; 1816 struct mb86a20s_state *state = fe->demodulator_priv;
1782 int rc; 1817 int rc, if_freq;
1783#if 0 1818#if 0
1784 /* 1819 /*
1785 * FIXME: Properly implement the set frontend properties 1820 * FIXME: Properly implement the set frontend properties
@@ -1796,6 +1831,18 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe)
1796 fe->ops.i2c_gate_ctrl(fe, 1); 1831 fe->ops.i2c_gate_ctrl(fe, 1);
1797 fe->ops.tuner_ops.set_params(fe); 1832 fe->ops.tuner_ops.set_params(fe);
1798 1833
1834 if (fe->ops.tuner_ops.get_if_frequency) {
1835 fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
1836
1837 /*
1838 * If the IF frequency changed, re-initialize the
1839 * frontend. This is needed by some drivers like tda18271,
1840 * that only sets the IF after receiving a set_params() call
1841 */
1842 if (if_freq != state->if_freq)
1843 state->need_init = true;
1844 }
1845
1799 /* 1846 /*
1800 * Make it more reliable: if, for some reason, the initial 1847 * Make it more reliable: if, for some reason, the initial
1801 * device initialization doesn't happen, initialize it when 1848 * device initialization doesn't happen, initialize it when
@@ -1805,6 +1852,8 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe)
1805 * the agc callback logic is not called during DVB attach time, 1852 * the agc callback logic is not called during DVB attach time,
1806 * causing mb86a20s to not be initialized with Kworld SBTVD. 1853 * causing mb86a20s to not be initialized with Kworld SBTVD.
1807 * So, this hack is needed, in order to make Kworld SBTVD to work. 1854 * So, this hack is needed, in order to make Kworld SBTVD to work.
1855 *
1856 * It is also needed to change the IF after the initial init.
1808 */ 1857 */
1809 if (state->need_init) 1858 if (state->need_init)
1810 mb86a20s_initfe(fe); 1859 mb86a20s_initfe(fe);