Markus Frahm wrote:
> Hello,
> I get 64qam as well as qam256 channels from my provider (willy-tel,Hamburg
> Germany). The qam 256 channels work well under windows with the same cable,
> so I think it should be a driver problem, pehaps in stv0297.c?The quality of
> video and sound with 256qam is very poor. If it wouldn't work with windows I
> would suppose that it was a cable/signal problem, but I have excellent
> quality under windows.
Hi,
I've snooped on the i2c-registers from saa7146 on the windows driver.
If the windows driver didn't get a lock, it does sweep some values. I've
tried to implement this behavior into the linux driver. I didn't see an
improvement on my card, so I didn't publish the patch.
- Hartmut
diff -r 5e9d301ef13b linux/drivers/media/dvb/frontends/stv0297.c
--- a/linux/drivers/media/dvb/frontends/stv0297.c Thu Oct 26 10:10:56 2006 -0300
+++ b/linux/drivers/media/dvb/frontends/stv0297.c Fri Oct 27 00:44:57 2006 +0200
@@ -36,6 +36,9 @@ struct stv0297_state {
struct dvb_frontend frontend;
unsigned long base_freq;
+ unsigned long inv_off_count;
+ unsigned long inv_on_count;
+ unsigned long current_freq;
};
#if 1 /* keep */
@@ -158,6 +161,9 @@ static void stv0297_set_symbolrate(struc
stv0297_writereg(state, 0x56, (unsigned char) (tmp >> 8));
stv0297_writereg(state, 0x57, (unsigned char) (tmp >> 16));
stv0297_writereg(state, 0x58, (unsigned char) (tmp >> 24));
+
+ dprintk("set_symbolrate: %d (%02x %02x %02x %02x)\n",
+ srate, (u8)tmp, (u8)(tmp >> 8), (u8)(tmp >> 16), (u8)(tmp >> 24));
}
static void stv0297_set_sweeprate(struct stv0297_state *state, short fshift, long symrate)
@@ -178,6 +184,9 @@ static void stv0297_set_sweeprate(struct
stv0297_writereg(state, 0x60, tmp & 0xFF);
stv0297_writereg_mask(state, 0x69, 0xF0, (tmp >> 4) & 0xf0);
+
+ dprintk("set_sweeprate: %d (%02x %01x?)\n",
+ fshift, (u8)tmp, (u8)((tmp >> 8) & 0x0f));
}
static void stv0297_set_carrieroffset(struct stv0297_state *state, long offset)
@@ -194,6 +203,9 @@ static void stv0297_set_carrieroffset(st
stv0297_writereg(state, 0x67, (unsigned char) (tmp >> 8));
stv0297_writereg(state, 0x68, (unsigned char) (tmp >> 16));
stv0297_writereg_mask(state, 0x69, 0x0F, (tmp >> 24) & 0x0f);
+
+ dprintk("set_carrieroffset: %ld (%02x %02x %02x ?%01x)\n",
+ offset, (u8)tmp, (u8)(tmp >> 8), (u8)(tmp >> 16), (u8)((tmp >> 24) & 0x0f));
}
/*
@@ -230,6 +242,9 @@ static void stv0297_set_initialdemodfreq
stv0297_writereg_mask(state, 0x25, 0x80, 0x80);
stv0297_writereg(state, 0x21, tmp >> 8);
stv0297_writereg(state, 0x20, tmp);
+
+ dprintk("set_initialdemodfreq: %ld (%02x %02x)\n",
+ freq, (u8)tmp, (u8)(tmp >> 8));
}
static int stv0297_set_qam(struct stv0297_state *state, fe_modulation_t modulation)
@@ -308,7 +323,7 @@ static int stv0297_init(struct dvb_front
/* load init table */
for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2)
stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]);
- msleep(200);
+ msleep(20);
return 0;
}
@@ -394,6 +409,11 @@ static int stv0297_set_frontend(struct d
unsigned long starttime;
unsigned long timeout;
fe_spectral_inversion_t inversion;
+
+ if (state->current_freq != p->frequency) {
+ state->inv_off_count = 1;
+ state->inv_on_count = 1;
+ }
switch (p->u.qam.modulation) {
case QAM_16:
@@ -420,11 +440,20 @@ static int stv0297_set_frontend(struct d
carrieroffset = -330;
switch (inversion) {
case INVERSION_OFF:
+ carrieroffset *= state->inv_off_count;
+ if (state->inv_off_count < 4)
+ state->inv_off_count++;
+ else
+ state->inv_off_count = 1;
break;
case INVERSION_ON:
sweeprate = -sweeprate;
- carrieroffset = -carrieroffset;
+ carrieroffset = -carrieroffset * state->inv_on_count;
+ if (state->inv_on_count < 4)
+ state->inv_on_count++;
+ else
+ state->inv_on_count = 1;
break;
default:
@@ -435,13 +464,21 @@ static int stv0297_set_frontend(struct d
if (fe->ops.tuner_ops.set_params) {
fe->ops.tuner_ops.set_params(fe, p);
if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
- }
-
+ state->current_freq = p->frequency;
+ }
+
/* clear software interrupts */
- stv0297_writereg(state, 0x82, 0x0);
+ stv0297_writereg_mask(state, 0x82, 0x04, 0x04);
/* set initial demodulation frequency */
stv0297_set_initialdemodfreq(state, 7250);
+
+ stv0297_writereg_mask(state, 0x43, 0x10, 0x00);
+ stv0297_readreg(state, 0x30);
+ stv0297_readreg(state, 0x31);
+ stv0297_readreg(state, 0x32);
+ stv0297_readreg(state, 0x33);
+ stv0297_readreg(state, 0x35);
/* setup AGC */
stv0297_writereg_mask(state, 0x43, 0x10, 0x00);
@@ -504,12 +541,8 @@ static int stv0297_set_frontend(struct d
stv0297_set_inversion(state, inversion);
/* kick off lock */
- /* Disable corner detection for higher QAMs */
- if (p->u.qam.modulation == QAM_128 ||
- p->u.qam.modulation == QAM_256)
- stv0297_writereg_mask(state, 0x88, 0x08, 0x00);
- else
- stv0297_writereg_mask(state, 0x88, 0x08, 0x08);
+ /* Enable corner detection */
+ stv0297_writereg_mask(state, 0x88, 0x08, 0x08);
stv0297_writereg_mask(state, 0x5a, 0x20, 0x00);
stv0297_writereg_mask(state, 0x6a, 0x01, 0x01);
@@ -649,6 +682,9 @@ struct dvb_frontend *stv0297_attach(cons
state->config = config;
state->i2c = i2c;
state->base_freq = 0;
+ state->current_freq = 0;
+ state->inv_off_count = 1;
+ state->inv_on_count = 1;
/* check if the demod is there */
if ((stv0297_readreg(state, 0x80) & 0x70) != 0x20)
_______________________________________________
linux-dvb mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb