[media] ds3000: clean up in tune procedure

Variable 'retune' does not make sense.
Loop is not needed for only one try.
Remove unnecessary dprintk's.
Remove a lot of debug messages and delays.

Signed-off-by: Igor M. Liplianin <liplianin@me.by>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Igor M. Liplianin 2011-02-25 18:41:23 -03:00 committed by Mauro Carvalho Chehab
parent 2f30fb49c3
commit 18a73f36a2
1 changed files with 201 additions and 247 deletions

View File

@ -536,25 +536,6 @@ static int ds3000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
return 0;
}
static void ds3000_dump_registers(struct dvb_frontend *fe)
{
struct ds3000_state *state = fe->demodulator_priv;
int x, y, reg = 0, val;
for (y = 0; y < 16; y++) {
dprintk("%s: %02x: ", __func__, y);
for (x = 0; x < 16; x++) {
reg = (y << 4) + x;
val = ds3000_readreg(state, reg);
if (x != 15)
dprintk("%02x ", val);
else
dprintk("%02x\n", val);
}
}
dprintk("%s: -- DS3000 DUMP DONE --\n", __func__);
}
static int ds3000_read_status(struct dvb_frontend *fe, fe_status_t* status)
{
struct ds3000_state *state = fe->demodulator_priv;
@ -589,16 +570,6 @@ static int ds3000_read_status(struct dvb_frontend *fe, fe_status_t* status)
return 0;
}
#define FE_IS_TUNED (FE_HAS_SIGNAL + FE_HAS_LOCK)
static int ds3000_is_tuned(struct dvb_frontend *fe)
{
fe_status_t tunerstat;
ds3000_read_status(fe, &tunerstat);
return ((tunerstat & FE_IS_TUNED) == FE_IS_TUNED);
}
/* read DS3000 BER value */
static int ds3000_read_ber(struct dvb_frontend *fe, u32* ber)
{
@ -1049,7 +1020,7 @@ static int ds3000_tune(struct dvb_frontend *fe,
struct ds3000_state *state = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int ret = 0, retune, i;
int i;
u8 status, mlpf, mlpf_new, mlpf_max, mlpf_min, nlpf;
u16 value, ndiv;
u32 f3db;
@ -1072,252 +1043,235 @@ static int ds3000_tune(struct dvb_frontend *fe,
/* discard the 'current' tuning parameters and prepare to tune */
ds3000_clone_params(fe);
retune = 1; /* try 1 times */
dprintk("%s: retune = %d\n", __func__, retune);
dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency);
dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate);
dprintk("%s: FEC = %d \n", __func__,
state->dcur.fec);
dprintk("%s: Inversion = %d\n", __func__, state->dcur.inversion);
/* Reset status register */
status = 0;
/* Tune */
/* unknown */
ds3000_tuner_writereg(state, 0x07, 0x02);
ds3000_tuner_writereg(state, 0x10, 0x00);
ds3000_tuner_writereg(state, 0x60, 0x79);
ds3000_tuner_writereg(state, 0x08, 0x01);
ds3000_tuner_writereg(state, 0x00, 0x01);
/* calculate and set freq divider */
if (state->dcur.frequency < 1146000) {
ds3000_tuner_writereg(state, 0x10, 0x11);
ndiv = ((state->dcur.frequency * (6 + 8) * 4) +
(DS3000_XTAL_FREQ / 2)) /
DS3000_XTAL_FREQ - 1024;
} else {
ds3000_tuner_writereg(state, 0x10, 0x01);
ndiv = ((state->dcur.frequency * (6 + 8) * 2) +
(DS3000_XTAL_FREQ / 2)) /
DS3000_XTAL_FREQ - 1024;
}
do {
/* Reset status register */
status = 0;
/* Tune */
/* unknown */
ds3000_tuner_writereg(state, 0x07, 0x02);
ds3000_tuner_writereg(state, 0x10, 0x00);
ds3000_tuner_writereg(state, 0x60, 0x79);
ds3000_tuner_writereg(state, 0x08, 0x01);
ds3000_tuner_writereg(state, 0x00, 0x01);
/* calculate and set freq divider */
if (state->dcur.frequency < 1146000) {
ds3000_tuner_writereg(state, 0x10, 0x11);
ndiv = ((state->dcur.frequency * (6 + 8) * 4) +
(DS3000_XTAL_FREQ / 2)) /
DS3000_XTAL_FREQ - 1024;
} else {
ds3000_tuner_writereg(state, 0x10, 0x01);
ndiv = ((state->dcur.frequency * (6 + 8) * 2) +
(DS3000_XTAL_FREQ / 2)) /
DS3000_XTAL_FREQ - 1024;
}
ds3000_tuner_writereg(state, 0x01, (ndiv & 0x0f00) >> 8);
ds3000_tuner_writereg(state, 0x02, ndiv & 0x00ff);
ds3000_tuner_writereg(state, 0x01, (ndiv & 0x0f00) >> 8);
ds3000_tuner_writereg(state, 0x02, ndiv & 0x00ff);
/* set pll */
ds3000_tuner_writereg(state, 0x03, 0x06);
ds3000_tuner_writereg(state, 0x51, 0x0f);
ds3000_tuner_writereg(state, 0x51, 0x1f);
ds3000_tuner_writereg(state, 0x50, 0x10);
ds3000_tuner_writereg(state, 0x50, 0x00);
msleep(5);
/* set pll */
ds3000_tuner_writereg(state, 0x03, 0x06);
ds3000_tuner_writereg(state, 0x51, 0x0f);
ds3000_tuner_writereg(state, 0x51, 0x1f);
ds3000_tuner_writereg(state, 0x50, 0x10);
ds3000_tuner_writereg(state, 0x50, 0x00);
msleep(5);
/* unknown */
ds3000_tuner_writereg(state, 0x51, 0x17);
ds3000_tuner_writereg(state, 0x51, 0x1f);
ds3000_tuner_writereg(state, 0x50, 0x08);
ds3000_tuner_writereg(state, 0x50, 0x00);
msleep(5);
/* unknown */
ds3000_tuner_writereg(state, 0x51, 0x17);
ds3000_tuner_writereg(state, 0x51, 0x1f);
ds3000_tuner_writereg(state, 0x50, 0x08);
ds3000_tuner_writereg(state, 0x50, 0x00);
msleep(5);
value = ds3000_tuner_readreg(state, 0x3d);
value &= 0x0f;
if ((value > 4) && (value < 15)) {
value -= 3;
if (value < 4)
value = 4;
value = ((value << 3) | 0x01) & 0x79;
}
value = ds3000_tuner_readreg(state, 0x3d);
value &= 0x0f;
if ((value > 4) && (value < 15)) {
value -= 3;
if (value < 4)
value = 4;
value = ((value << 3) | 0x01) & 0x79;
}
ds3000_tuner_writereg(state, 0x60, value);
ds3000_tuner_writereg(state, 0x51, 0x17);
ds3000_tuner_writereg(state, 0x51, 0x1f);
ds3000_tuner_writereg(state, 0x50, 0x08);
ds3000_tuner_writereg(state, 0x50, 0x00);
ds3000_tuner_writereg(state, 0x60, value);
ds3000_tuner_writereg(state, 0x51, 0x17);
ds3000_tuner_writereg(state, 0x51, 0x1f);
ds3000_tuner_writereg(state, 0x50, 0x08);
ds3000_tuner_writereg(state, 0x50, 0x00);
/* set low-pass filter period */
ds3000_tuner_writereg(state, 0x04, 0x2e);
ds3000_tuner_writereg(state, 0x51, 0x1b);
ds3000_tuner_writereg(state, 0x51, 0x1f);
ds3000_tuner_writereg(state, 0x50, 0x04);
ds3000_tuner_writereg(state, 0x50, 0x00);
msleep(5);
/* set low-pass filter period */
ds3000_tuner_writereg(state, 0x04, 0x2e);
ds3000_tuner_writereg(state, 0x51, 0x1b);
ds3000_tuner_writereg(state, 0x51, 0x1f);
ds3000_tuner_writereg(state, 0x50, 0x04);
ds3000_tuner_writereg(state, 0x50, 0x00);
msleep(5);
f3db = ((state->dcur.symbol_rate / 1000) << 2) / 5 + 2000;
if ((state->dcur.symbol_rate / 1000) < 5000)
f3db += 3000;
if (f3db < 7000)
f3db = 7000;
if (f3db > 40000)
f3db = 40000;
f3db = ((state->dcur.symbol_rate / 1000) << 2) / 5 + 2000;
if ((state->dcur.symbol_rate / 1000) < 5000)
f3db += 3000;
if (f3db < 7000)
f3db = 7000;
if (f3db > 40000)
f3db = 40000;
/* set low-pass filter baseband */
value = ds3000_tuner_readreg(state, 0x26);
mlpf = 0x2e * 207 / ((value << 1) + 151);
mlpf_max = mlpf * 135 / 100;
mlpf_min = mlpf * 78 / 100;
if (mlpf_max > 63)
mlpf_max = 63;
/* set low-pass filter baseband */
value = ds3000_tuner_readreg(state, 0x26);
mlpf = 0x2e * 207 / ((value << 1) + 151);
mlpf_max = mlpf * 135 / 100;
mlpf_min = mlpf * 78 / 100;
if (mlpf_max > 63)
mlpf_max = 63;
/* rounded to the closest integer */
nlpf = ((mlpf * f3db * 1000) + (2766 * DS3000_XTAL_FREQ / 2))
/ (2766 * DS3000_XTAL_FREQ);
if (nlpf > 23)
nlpf = 23;
if (nlpf < 1)
nlpf = 1;
/* rounded to the closest integer */
nlpf = ((mlpf * f3db * 1000) + (2766 * DS3000_XTAL_FREQ / 2))
/ (2766 * DS3000_XTAL_FREQ);
if (nlpf > 23)
nlpf = 23;
if (nlpf < 1)
nlpf = 1;
/* rounded to the closest integer */
mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
(1000 * f3db / 2)) / (1000 * f3db);
/* rounded to the closest integer */
if (mlpf_new < mlpf_min) {
nlpf++;
mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
(1000 * f3db / 2)) / (1000 * f3db);
}
if (mlpf_new < mlpf_min) {
nlpf++;
mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
(1000 * f3db / 2)) / (1000 * f3db);
}
if (mlpf_new > mlpf_max)
mlpf_new = mlpf_max;
if (mlpf_new > mlpf_max)
mlpf_new = mlpf_max;
ds3000_tuner_writereg(state, 0x04, mlpf_new);
ds3000_tuner_writereg(state, 0x06, nlpf);
ds3000_tuner_writereg(state, 0x51, 0x1b);
ds3000_tuner_writereg(state, 0x51, 0x1f);
ds3000_tuner_writereg(state, 0x50, 0x04);
ds3000_tuner_writereg(state, 0x50, 0x00);
msleep(5);
ds3000_tuner_writereg(state, 0x04, mlpf_new);
ds3000_tuner_writereg(state, 0x06, nlpf);
ds3000_tuner_writereg(state, 0x51, 0x1b);
ds3000_tuner_writereg(state, 0x51, 0x1f);
ds3000_tuner_writereg(state, 0x50, 0x04);
ds3000_tuner_writereg(state, 0x50, 0x00);
msleep(5);
/* unknown */
ds3000_tuner_writereg(state, 0x51, 0x1e);
ds3000_tuner_writereg(state, 0x51, 0x1f);
ds3000_tuner_writereg(state, 0x50, 0x01);
ds3000_tuner_writereg(state, 0x50, 0x00);
msleep(60);
/* unknown */
ds3000_tuner_writereg(state, 0x51, 0x1e);
ds3000_tuner_writereg(state, 0x51, 0x1f);
ds3000_tuner_writereg(state, 0x50, 0x01);
ds3000_tuner_writereg(state, 0x50, 0x00);
msleep(60);
/* ds3000 global reset */
ds3000_writereg(state, 0x07, 0x80);
ds3000_writereg(state, 0x07, 0x00);
/* ds3000 build-in uC reset */
ds3000_writereg(state, 0xb2, 0x01);
/* ds3000 software reset */
ds3000_writereg(state, 0x00, 0x01);
/* ds3000 global reset */
ds3000_writereg(state, 0x07, 0x80);
ds3000_writereg(state, 0x07, 0x00);
/* ds3000 build-in uC reset */
ds3000_writereg(state, 0xb2, 0x01);
/* ds3000 software reset */
ds3000_writereg(state, 0x00, 0x01);
switch (c->delivery_system) {
case SYS_DVBS:
/* initialise the demod in DVB-S mode */
for (i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2)
ds3000_writereg(state,
ds3000_dvbs_init_tab[i],
ds3000_dvbs_init_tab[i + 1]);
value = ds3000_readreg(state, 0xfe);
value &= 0xc0;
value |= 0x1b;
ds3000_writereg(state, 0xfe, value);
break;
case SYS_DVBS2:
/* initialise the demod in DVB-S2 mode */
for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2)
ds3000_writereg(state,
ds3000_dvbs2_init_tab[i],
ds3000_dvbs2_init_tab[i + 1]);
ds3000_writereg(state, 0xfe, 0x98);
break;
default:
return 1;
}
/* enable 27MHz clock output */
ds3000_writereg(state, 0x29, 0x80);
/* enable ac coupling */
ds3000_writereg(state, 0x25, 0x8a);
/* enhance symbol rate performance */
if ((state->dcur.symbol_rate / 1000) <= 5000) {
value = 29777 / (state->dcur.symbol_rate / 1000) + 1;
if (value % 2 != 0)
value++;
ds3000_writereg(state, 0xc3, 0x0d);
ds3000_writereg(state, 0xc8, value);
ds3000_writereg(state, 0xc4, 0x10);
ds3000_writereg(state, 0xc7, 0x0e);
} else if ((state->dcur.symbol_rate / 1000) <= 10000) {
value = 92166 / (state->dcur.symbol_rate / 1000) + 1;
if (value % 2 != 0)
value++;
ds3000_writereg(state, 0xc3, 0x07);
ds3000_writereg(state, 0xc8, value);
ds3000_writereg(state, 0xc4, 0x09);
ds3000_writereg(state, 0xc7, 0x12);
} else if ((state->dcur.symbol_rate / 1000) <= 20000) {
value = 64516 / (state->dcur.symbol_rate / 1000) + 1;
ds3000_writereg(state, 0xc3, value);
ds3000_writereg(state, 0xc8, 0x0e);
ds3000_writereg(state, 0xc4, 0x07);
ds3000_writereg(state, 0xc7, 0x18);
} else {
value = 129032 / (state->dcur.symbol_rate / 1000) + 1;
ds3000_writereg(state, 0xc3, value);
ds3000_writereg(state, 0xc8, 0x0a);
ds3000_writereg(state, 0xc4, 0x05);
ds3000_writereg(state, 0xc7, 0x24);
}
/* normalized symbol rate rounded to the closest integer */
value = (((state->dcur.symbol_rate / 1000) << 16) +
(DS3000_SAMPLE_RATE / 2)) / DS3000_SAMPLE_RATE;
ds3000_writereg(state, 0x61, value & 0x00ff);
ds3000_writereg(state, 0x62, (value & 0xff00) >> 8);
/* co-channel interference cancellation disabled */
ds3000_writereg(state, 0x56, 0x00);
/* equalizer disabled */
ds3000_writereg(state, 0x76, 0x00);
/*ds3000_writereg(state, 0x08, 0x03);
ds3000_writereg(state, 0xfd, 0x22);
ds3000_writereg(state, 0x08, 0x07);
ds3000_writereg(state, 0xfd, 0x42);
ds3000_writereg(state, 0x08, 0x07);*/
if (state->config->ci_mode) {
switch (c->delivery_system) {
case SYS_DVBS:
/* initialise the demod in DVB-S mode */
for (i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2)
ds3000_writereg(state,
ds3000_dvbs_init_tab[i],
ds3000_dvbs_init_tab[i + 1]);
value = ds3000_readreg(state, 0xfe);
value &= 0xc0;
value |= 0x1b;
ds3000_writereg(state, 0xfe, value);
break;
case SYS_DVBS2:
/* initialise the demod in DVB-S2 mode */
for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2)
ds3000_writereg(state,
ds3000_dvbs2_init_tab[i],
ds3000_dvbs2_init_tab[i + 1]);
ds3000_writereg(state, 0xfe, 0x98);
break;
default:
return 1;
}
/* enable 27MHz clock output */
ds3000_writereg(state, 0x29, 0x80);
/* enable ac coupling */
ds3000_writereg(state, 0x25, 0x8a);
/* enhance symbol rate performance */
if ((state->dcur.symbol_rate / 1000) <= 5000) {
value = 29777 / (state->dcur.symbol_rate / 1000) + 1;
if (value % 2 != 0)
value++;
ds3000_writereg(state, 0xc3, 0x0d);
ds3000_writereg(state, 0xc8, value);
ds3000_writereg(state, 0xc4, 0x10);
ds3000_writereg(state, 0xc7, 0x0e);
} else if ((state->dcur.symbol_rate / 1000) <= 10000) {
value = 92166 / (state->dcur.symbol_rate / 1000) + 1;
if (value % 2 != 0)
value++;
ds3000_writereg(state, 0xc3, 0x07);
ds3000_writereg(state, 0xc8, value);
ds3000_writereg(state, 0xc4, 0x09);
ds3000_writereg(state, 0xc7, 0x12);
} else if ((state->dcur.symbol_rate / 1000) <= 20000) {
value = 64516 / (state->dcur.symbol_rate / 1000) + 1;
ds3000_writereg(state, 0xc3, value);
ds3000_writereg(state, 0xc8, 0x0e);
ds3000_writereg(state, 0xc4, 0x07);
ds3000_writereg(state, 0xc7, 0x18);
} else {
value = 129032 / (state->dcur.symbol_rate / 1000) + 1;
ds3000_writereg(state, 0xc3, value);
ds3000_writereg(state, 0xc8, 0x0a);
ds3000_writereg(state, 0xc4, 0x05);
ds3000_writereg(state, 0xc7, 0x24);
}
/* normalized symbol rate rounded to the closest integer */
value = (((state->dcur.symbol_rate / 1000) << 16) +
(DS3000_SAMPLE_RATE / 2)) / DS3000_SAMPLE_RATE;
ds3000_writereg(state, 0x61, value & 0x00ff);
ds3000_writereg(state, 0x62, (value & 0xff00) >> 8);
/* co-channel interference cancellation disabled */
ds3000_writereg(state, 0x56, 0x00);
/* equalizer disabled */
ds3000_writereg(state, 0x76, 0x00);
/*ds3000_writereg(state, 0x08, 0x03);
ds3000_writereg(state, 0xfd, 0x22);
ds3000_writereg(state, 0x08, 0x07);
ds3000_writereg(state, 0xfd, 0x42);
ds3000_writereg(state, 0x08, 0x07);*/
if (state->config->ci_mode) {
switch (c->delivery_system) {
case SYS_DVBS:
default:
ds3000_writereg(state, 0xfd, 0x80);
ds3000_writereg(state, 0xfd, 0x80);
break;
case SYS_DVBS2:
ds3000_writereg(state, 0xfd, 0x01);
break;
case SYS_DVBS2:
ds3000_writereg(state, 0xfd, 0x01);
break;
}
}
}
/* ds3000 out of software reset */
ds3000_writereg(state, 0x00, 0x00);
/* start ds3000 build-in uC */
ds3000_writereg(state, 0xb2, 0x00);
/* ds3000 out of software reset */
ds3000_writereg(state, 0x00, 0x00);
/* start ds3000 build-in uC */
ds3000_writereg(state, 0xb2, 0x00);
/* TODO: calculate and set carrier offset */
/* TODO: calculate and set carrier offset */
/* wait before retrying */
for (i = 0; i < 30 ; i++) {
if (ds3000_is_tuned(fe)) {
dprintk("%s: Tuned\n", __func__);
ds3000_dump_registers(fe);
goto tuned;
}
msleep(1);
}
for (i = 0; i < 30 ; i++) {
ds3000_read_status(fe, &status);
if (status && FE_HAS_LOCK)
break;
dprintk("%s: Not tuned\n", __func__);
ds3000_dump_registers(fe);
msleep(10);
}
} while (--retune);
tuned:
return ret;
return 0;
}
static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe)