[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>
This commit is contained in:
Mauro Carvalho Chehab 2013-03-04 08:15:49 -03:00
parent 04fa725e7b
commit 0e4bbedd63
2 changed files with 30 additions and 4 deletions

View File

@ -70,7 +70,6 @@ static struct regdata mb86a20s_init1[] = {
{ 0x70, 0xff }, { 0x70, 0xff },
{ 0x08, 0x01 }, { 0x08, 0x01 },
{ 0x50, 0xd1 }, { 0x51, 0x20 }, { 0x50, 0xd1 }, { 0x51, 0x20 },
{ 0x28, 0x2a }, { 0x29, 0x00 }, { 0x2a, 0xff }, { 0x2b, 0x80 },
}; };
static struct regdata mb86a20s_init2[] = { static struct regdata mb86a20s_init2[] = {
@ -1776,6 +1775,7 @@ static int mb86a20s_initfe(struct dvb_frontend *fe)
{ {
struct mb86a20s_state *state = fe->demodulator_priv; struct mb86a20s_state *state = fe->demodulator_priv;
u64 pll; u64 pll;
u32 fclk;
int rc; int rc;
u8 regD5 = 1, reg71, reg09 = 0x3a; u8 regD5 = 1, reg71, reg09 = 0x3a;
@ -1810,6 +1810,10 @@ static int mb86a20s_initfe(struct dvb_frontend *fe)
goto err; goto err;
} }
fclk = state->config->fclk;
if (!fclk)
fclk = 32571428;
/* Adjust IF frequency to match tuner */ /* Adjust IF frequency to match tuner */
if (fe->ops.tuner_ops.get_if_frequency) if (fe->ops.tuner_ops.get_if_frequency)
fe->ops.tuner_ops.get_if_frequency(fe, &state->if_freq); fe->ops.tuner_ops.get_if_frequency(fe, &state->if_freq);
@ -1817,6 +1821,24 @@ static int mb86a20s_initfe(struct dvb_frontend *fe)
if (!state->if_freq) if (!state->if_freq)
state->if_freq = 3300000; state->if_freq = 3300000;
pll = (((u64)1) << 34) * state->if_freq;
do_div(pll, 63 * fclk);
pll = (1 << 25) - pll;
rc = mb86a20s_writereg(state, 0x28, 0x2a);
if (rc < 0)
goto err;
rc = mb86a20s_writereg(state, 0x29, (pll >> 16) & 0xff);
if (rc < 0)
goto err;
rc = mb86a20s_writereg(state, 0x2a, (pll >> 8) & 0xff);
if (rc < 0)
goto err;
rc = mb86a20s_writereg(state, 0x2b, pll & 0xff);
if (rc < 0)
goto err;
dev_dbg(&state->i2c->dev, "%s: fclk=%d, IF=%d, clock reg=0x%06llx\n",
__func__, fclk, state->if_freq, (long long)pll);
/* pll = freq[Hz] * 2^24/10^6 / 16.285714286 */ /* pll = freq[Hz] * 2^24/10^6 / 16.285714286 */
pll = state->if_freq * 1677721600L; pll = state->if_freq * 1677721600L;
do_div(pll, 1628571429L); do_div(pll, 1628571429L);
@ -1832,7 +1854,7 @@ static int mb86a20s_initfe(struct dvb_frontend *fe)
rc = mb86a20s_writereg(state, 0x2b, pll & 0xff); rc = mb86a20s_writereg(state, 0x2b, pll & 0xff);
if (rc < 0) if (rc < 0)
goto err; goto err;
dev_dbg(&state->i2c->dev, "%s: IF=%d, PLL=0x%06llx\n", dev_dbg(&state->i2c->dev, "%s: IF=%d, IF reg=0x%06llx\n",
__func__, state->if_freq, (long long)pll); __func__, state->if_freq, (long long)pll);
if (!state->config->is_serial) { if (!state->config->is_serial) {

View File

@ -21,12 +21,16 @@
/** /**
* struct mb86a20s_config - Define the per-device attributes of the frontend * struct mb86a20s_config - Define the per-device attributes of the frontend
* *
* @fclk: Clock frequency. If zero, assumes the default
* (32.57142 Mhz)
* @demod_address: the demodulator's i2c address * @demod_address: the demodulator's i2c address
* @is_serial: if true, TS is serial. Otherwise, TS is parallel
*/ */
struct mb86a20s_config { struct mb86a20s_config {
u8 demod_address; u32 fclk;
bool is_serial; u8 demod_address;
bool is_serial;
}; };
#if defined(CONFIG_DVB_MB86A20S) || (defined(CONFIG_DVB_MB86A20S_MODULE) \ #if defined(CONFIG_DVB_MB86A20S) || (defined(CONFIG_DVB_MB86A20S_MODULE) \