[linux-dvb] FIX: No recovery after lost lock

Oliver Endriss o.endriss at gmx.de
Wed Sep 21 19:38:14 CEST 2005


Marian Durkovic wrote:
> On Mon, Sep 19, 2005 at 12:33:35PM +0200, Johannes Stezenbach wrote:
> > On Wed, Sep 07, 2005 Oliver Endriss wrote:
> > > Marian Durkovic wrote:
> > > > I have no idea why the transition from 1 to 0 helps, maybe changing of
> > > > inversion resets some other internal parameters of STV 299B and the problem
> > > > is in fact somewhere else (bad initialization settings or so). 
> > > 
> > > Ok, please test the attached patch.
> > > It adds a transition of the inversion bit to the frontend driver.
> > 
> > Did you test if this patch fixes the problem for you?
>
>   as I've written in my previous mail, the reason for this problem is the
> fine-tuning code in stv0299.c, which plays with derotator registers. If
> I comment out this code, it's not needed to flip inversion anymore, since
> the frontend does not hang at all.

Sorry, I must have missed your message.

Imho the 'enhanced' code looks broken:

       if (state->config->enhanced_tuning) {
                /* check if we should do a finetune */
                int frequency_delta = p->frequency - state->tuner_frequency;
                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                ...
                if ((frequency_delta > -minmax) && (frequency_delta < minmax) && (frequency_delta != 0) &&
                    (state->fec_inner == p->u.qpsk.fec_inner) &&
                    (state->symbol_rate == p->u.qpsk.symbol_rate) {
                        /* fine-tuning */
                        int Drot_freq = (frequency_delta << 16) / (state->config->mclk / 1000);

                        // zap the derotator registers first
                        stv0299_writeregI(state, 0x22, 0x00);
                        stv0299_writeregI(state, 0x23, 0x00);

                        // now set them as we want
                        stv0299_writeregI(state, 0x22, Drot_freq >> 8);
                        stv0299_writeregI(state, 0x23, Drot_freq);
                } else {
                        ...
                        state->config->pll_set(fe, state->i2c, p);
                        ...
                }
        } else {
                ...
                state->config->pll_set(fe, state->i2c, p);
                ...
        }

        state->tuner_frequency = p->frequency;
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        ...

        
For fine-tuning, this code finally sets state->tuner_frequency, too.

The derotator can be used if (and only if)
  pll_frequency - delta < p->frequency < pll_frequency + delta
AFAICS the real *pll* frequency is never checked. :-(

If frequency_delta is small enough for subsequent calls, the pll will
not be set, the derotator registers will be set incorrectly, and tuning
will fail. Is this optimization really useful?

Furthermore, there are two slightly different tuning sections:
- 'enhanced':
                        stv0299_writeregI(state, 0x05, 0xb5);   /*  enable i2c repeater on stv0299  */
                        state->config->pll_set(fe, state->i2c, p);
                        stv0299_writeregI(state, 0x05, 0x35);   /*  disable i2c repeater on stv0299  */

                        stv0299_writeregI(state, 0x32, 0x80);   <-- ???
                        stv0299_writeregI(state, 0x22, 0x00);
                        stv0299_writeregI(state, 0x23, 0x00);
                        stv0299_writeregI(state, 0x32, 0x19);   <-- ???
                        stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
                        stv0299_set_FEC (state, p->u.qpsk.fec_inner);

- 'standard':
                stv0299_writeregI(state, 0x05, 0xb5);   /*  enable i2c repeater on stv0299  */
                state->config->pll_set(fe, state->i2c, p);
                stv0299_writeregI(state, 0x05, 0x35);   /*  disable i2c repeater on stv0299  */

                stv0299_set_FEC (state, p->u.qpsk.fec_inner);
                stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
                stv0299_writeregI(state, 0x22, 0x00);
                stv0299_writeregI(state, 0x23, 0x00);
                stv0299_readreg (state, 0x23);             <-- why?
                stv0299_writeregI(state, 0x12, 0xb9);      <-- should be set by xxx_inittab!

The 'enhanced' version is used by the budget-ci driver for sub-system
13c2:100f. All other cards and drivers use the standard variant...
Is there a good reason for the enhanced tuning code?

Above I marked all lines which look strange to me. Maybe a stv0299
expert could comment on this. Imho the standard code looks better.

Btw. what is 'skip_reinit' in struct stv0299_config good for?
It is not used anywhere...

Oliver

-- 
--------------------------------------------------------
VDR Remote Plugin available at
http://www.escape-edv.de/endriss/vdr/
--------------------------------------------------------



More information about the linux-dvb mailing list