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 linux-dvb@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb