2009-03-03 17:55:20 +03:00
/*
* stv0900_sw . c
*
* Driver for ST STV0900 satellite demodulator IC .
*
* Copyright ( C ) ST Microelectronics .
* Copyright ( C ) 2009 NetUP Inc .
* Copyright ( C ) 2009 Igor M . Liplianin < liplianin @ netup . ru >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
*
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "stv0900.h"
# include "stv0900_reg.h"
# include "stv0900_priv.h"
2009-11-07 05:46:32 +03:00
s32 shiftx ( s32 x , int demod , s32 shift )
{
if ( demod = = 1 )
return x - shift ;
return x ;
}
int stv0900_check_signal_presence ( struct stv0900_internal * intp ,
2009-03-03 17:55:20 +03:00
enum fe_stv0900_demod_num demod )
{
2009-11-07 05:46:32 +03:00
s32 carr_offset ,
agc2_integr ,
max_carrier ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
int no_signal = FALSE ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
carr_offset = ( stv0900_read_reg ( intp , CFR2 ) < < 8 )
| stv0900_read_reg ( intp , CFR1 ) ;
carr_offset = ge2comp ( carr_offset , 16 ) ;
agc2_integr = ( stv0900_read_reg ( intp , AGC2I1 ) < < 8 )
| stv0900_read_reg ( intp , AGC2I0 ) ;
max_carrier = intp - > srch_range [ demod ] / 1000 ;
2009-03-03 17:55:20 +03:00
max_carrier + = ( max_carrier / 10 ) ;
max_carrier = 65536 * ( max_carrier / 2 ) ;
2009-11-07 05:46:32 +03:00
max_carrier / = intp - > mclk / 1000 ;
2009-03-03 17:55:20 +03:00
if ( max_carrier > 0x4000 )
max_carrier = 0x4000 ;
if ( ( agc2_integr > 0x2000 )
2009-11-07 05:46:32 +03:00
| | ( carr_offset > ( 2 * max_carrier ) )
| | ( carr_offset < ( - 2 * max_carrier ) ) )
2009-03-03 17:55:20 +03:00
no_signal = TRUE ;
return no_signal ;
}
2009-11-07 05:46:32 +03:00
static void stv0900_get_sw_loop_params ( struct stv0900_internal * intp ,
2009-03-03 17:55:20 +03:00
s32 * frequency_inc , s32 * sw_timeout ,
s32 * steps ,
enum fe_stv0900_demod_num demod )
{
s32 timeout , freq_inc , max_steps , srate , max_carrier ;
enum fe_stv0900_search_standard standard ;
2009-11-07 05:46:32 +03:00
srate = intp - > symbol_rate [ demod ] ;
max_carrier = intp - > srch_range [ demod ] / 1000 ;
max_carrier + = max_carrier / 10 ;
standard = intp - > srch_standard [ demod ] ;
2009-03-03 17:55:20 +03:00
max_carrier = 65536 * ( max_carrier / 2 ) ;
2009-11-07 05:46:32 +03:00
max_carrier / = intp - > mclk / 1000 ;
2009-03-03 17:55:20 +03:00
if ( max_carrier > 0x4000 )
max_carrier = 0x4000 ;
freq_inc = srate ;
2009-11-07 05:46:32 +03:00
freq_inc / = intp - > mclk > > 10 ;
2009-03-03 17:55:20 +03:00
freq_inc = freq_inc < < 6 ;
switch ( standard ) {
case STV0900_SEARCH_DVBS1 :
case STV0900_SEARCH_DSS :
freq_inc * = 3 ;
timeout = 20 ;
break ;
case STV0900_SEARCH_DVBS2 :
freq_inc * = 4 ;
timeout = 25 ;
break ;
case STV0900_AUTO_SEARCH :
default :
freq_inc * = 3 ;
timeout = 25 ;
break ;
}
freq_inc / = 100 ;
if ( ( freq_inc > max_carrier ) | | ( freq_inc < 0 ) )
freq_inc = max_carrier / 2 ;
timeout * = 27500 ;
if ( srate > 0 )
timeout / = srate / 1000 ;
if ( ( timeout > 100 ) | | ( timeout < 0 ) )
timeout = 100 ;
max_steps = ( max_carrier / freq_inc ) + 1 ;
if ( ( max_steps > 100 ) | | ( max_steps < 0 ) ) {
max_steps = 100 ;
freq_inc = max_carrier / max_steps ;
}
* frequency_inc = freq_inc ;
* sw_timeout = timeout ;
* steps = max_steps ;
}
2009-11-07 05:46:32 +03:00
static int stv0900_search_carr_sw_loop ( struct stv0900_internal * intp ,
2009-03-03 17:55:20 +03:00
s32 FreqIncr , s32 Timeout , int zigzag ,
s32 MaxStep , enum fe_stv0900_demod_num demod )
{
int no_signal ,
lock = FALSE ;
s32 stepCpt ,
freqOffset ,
max_carrier ;
2009-11-07 05:46:32 +03:00
max_carrier = intp - > srch_range [ demod ] / 1000 ;
max_carrier + = ( max_carrier / 10 ) ;
2009-03-03 17:55:20 +03:00
max_carrier = 65536 * ( max_carrier / 2 ) ;
2009-11-07 05:46:32 +03:00
max_carrier / = intp - > mclk / 1000 ;
2009-03-03 17:55:20 +03:00
if ( max_carrier > 0x4000 )
max_carrier = 0x4000 ;
if ( zigzag = = TRUE )
freqOffset = 0 ;
else
freqOffset = - max_carrier + FreqIncr ;
stepCpt = 0 ;
do {
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , DMDISTATE , 0x1c ) ;
stv0900_write_reg ( intp , CFRINIT1 , ( freqOffset / 256 ) & 0xff ) ;
stv0900_write_reg ( intp , CFRINIT0 , freqOffset & 0xff ) ;
stv0900_write_reg ( intp , DMDISTATE , 0x18 ) ;
stv0900_write_bits ( intp , ALGOSWRST , 1 ) ;
if ( intp - > chip_id = = 0x12 ) {
stv0900_write_bits ( intp , RST_HWARE , 1 ) ;
stv0900_write_bits ( intp , RST_HWARE , 0 ) ;
2009-03-03 17:55:20 +03:00
}
if ( zigzag = = TRUE ) {
if ( freqOffset > = 0 )
freqOffset = - freqOffset - 2 * FreqIncr ;
else
freqOffset = - freqOffset ;
} else
freqOffset + = + 2 * FreqIncr ;
stepCpt + + ;
2009-11-07 05:46:32 +03:00
lock = stv0900_get_demod_lock ( intp , demod , Timeout ) ;
no_signal = stv0900_check_signal_presence ( intp , demod ) ;
2009-03-03 17:55:20 +03:00
} while ( ( lock = = FALSE )
& & ( no_signal = = FALSE )
& & ( ( freqOffset - FreqIncr ) < max_carrier )
& & ( ( freqOffset + FreqIncr ) > - max_carrier )
& & ( stepCpt < MaxStep ) ) ;
2009-11-07 05:46:32 +03:00
stv0900_write_bits ( intp , ALGOSWRST , 0 ) ;
2009-03-03 17:55:20 +03:00
return lock ;
}
2010-01-16 19:35:36 +03:00
static int stv0900_sw_algo ( struct stv0900_internal * intp ,
2009-03-03 17:55:20 +03:00
enum fe_stv0900_demod_num demod )
{
2009-11-07 05:46:32 +03:00
int lock = FALSE ,
no_signal ,
zigzag ;
s32 s2fw ,
fqc_inc ,
sft_stp_tout ,
trial_cntr ,
max_steps ;
stv0900_get_sw_loop_params ( intp , & fqc_inc , & sft_stp_tout ,
2009-03-03 17:55:20 +03:00
& max_steps , demod ) ;
2009-11-07 05:46:32 +03:00
switch ( intp - > srch_standard [ demod ] ) {
case STV0900_SEARCH_DVBS1 :
case STV0900_SEARCH_DSS :
if ( intp - > chip_id > = 0x20 )
stv0900_write_reg ( intp , CARFREQ , 0x3b ) ;
else
stv0900_write_reg ( intp , CARFREQ , 0xef ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , DMDCFGMD , 0x49 ) ;
zigzag = FALSE ;
break ;
case STV0900_SEARCH_DVBS2 :
if ( intp - > chip_id > = 0x20 )
stv0900_write_reg ( intp , CORRELABS , 0x79 ) ;
else
stv0900_write_reg ( intp , CORRELABS , 0x68 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , DMDCFGMD , 0x89 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
zigzag = TRUE ;
break ;
case STV0900_AUTO_SEARCH :
default :
if ( intp - > chip_id > = 0x20 ) {
stv0900_write_reg ( intp , CARFREQ , 0x3b ) ;
stv0900_write_reg ( intp , CORRELABS , 0x79 ) ;
} else {
stv0900_write_reg ( intp , CARFREQ , 0xef ) ;
stv0900_write_reg ( intp , CORRELABS , 0x68 ) ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , DMDCFGMD , 0xc9 ) ;
zigzag = FALSE ;
2009-03-03 17:55:20 +03:00
break ;
2009-11-07 05:46:32 +03:00
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
trial_cntr = 0 ;
do {
lock = stv0900_search_carr_sw_loop ( intp ,
fqc_inc ,
sft_stp_tout ,
zigzag ,
max_steps ,
demod ) ;
no_signal = stv0900_check_signal_presence ( intp , demod ) ;
trial_cntr + + ;
if ( ( lock = = TRUE )
| | ( no_signal = = TRUE )
| | ( trial_cntr = = 2 ) ) {
if ( intp - > chip_id > = 0x20 ) {
stv0900_write_reg ( intp , CARFREQ , 0x49 ) ;
stv0900_write_reg ( intp , CORRELABS , 0x9e ) ;
2009-03-03 17:55:20 +03:00
} else {
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , CARFREQ , 0xed ) ;
stv0900_write_reg ( intp , CORRELABS , 0x88 ) ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
if ( ( stv0900_get_bits ( intp , HEADER_MODE ) = =
STV0900_DVBS2_FOUND ) & &
( lock = = TRUE ) ) {
msleep ( sft_stp_tout ) ;
s2fw = stv0900_get_bits ( intp , FLYWHEEL_CPT ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( s2fw < 0xd ) {
msleep ( sft_stp_tout ) ;
s2fw = stv0900_get_bits ( intp ,
FLYWHEEL_CPT ) ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
if ( s2fw < 0xd ) {
lock = FALSE ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( trial_cntr < 2 ) {
if ( intp - > chip_id > = 0x20 )
stv0900_write_reg ( intp ,
CORRELABS ,
0x79 ) ;
else
stv0900_write_reg ( intp ,
CORRELABS ,
0x68 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp ,
DMDCFGMD ,
0x89 ) ;
2009-03-03 17:55:20 +03:00
}
}
}
2009-11-07 05:46:32 +03:00
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
} while ( ( lock = = FALSE )
& & ( trial_cntr < 2 )
& & ( no_signal = = FALSE ) ) ;
2009-03-03 17:55:20 +03:00
return lock ;
}
2009-11-07 05:46:32 +03:00
static u32 stv0900_get_symbol_rate ( struct stv0900_internal * intp ,
2009-03-03 17:55:20 +03:00
u32 mclk ,
enum fe_stv0900_demod_num demod )
{
2009-11-07 05:46:32 +03:00
s32 rem1 , rem2 , intval1 , intval2 , srate ;
srate = ( stv0900_get_bits ( intp , SYMB_FREQ3 ) < < 24 ) +
( stv0900_get_bits ( intp , SYMB_FREQ2 ) < < 16 ) +
( stv0900_get_bits ( intp , SYMB_FREQ1 ) < < 8 ) +
( stv0900_get_bits ( intp , SYMB_FREQ0 ) ) ;
2009-03-03 17:55:20 +03:00
dprintk ( " lock: srate=%d r0=0x%x r1=0x%x r2=0x%x r3=0x%x \n " ,
2009-11-07 05:46:32 +03:00
srate , stv0900_get_bits ( intp , SYMB_FREQ0 ) ,
stv0900_get_bits ( intp , SYMB_FREQ1 ) ,
stv0900_get_bits ( intp , SYMB_FREQ2 ) ,
stv0900_get_bits ( intp , SYMB_FREQ3 ) ) ;
2009-03-03 17:55:20 +03:00
intval1 = ( mclk ) > > 16 ;
intval2 = ( srate ) > > 16 ;
rem1 = ( mclk ) % 0x10000 ;
rem2 = ( srate ) % 0x10000 ;
srate = ( intval1 * intval2 ) +
( ( intval1 * rem2 ) > > 16 ) +
( ( intval2 * rem1 ) > > 16 ) ;
return srate ;
}
2009-11-07 05:46:32 +03:00
static void stv0900_set_symbol_rate ( struct stv0900_internal * intp ,
2009-03-03 17:55:20 +03:00
u32 mclk , u32 srate ,
enum fe_stv0900_demod_num demod )
{
u32 symb ;
2009-09-19 15:37:40 +04:00
dprintk ( " %s: Mclk %d, SR %d, Dmd %d \n " , __func__ , mclk ,
2009-03-03 17:55:20 +03:00
srate , demod ) ;
if ( srate > 60000000 ) {
symb = srate < < 4 ;
symb / = ( mclk > > 12 ) ;
} else if ( srate > 6000000 ) {
symb = srate < < 6 ;
symb / = ( mclk > > 10 ) ;
} else {
symb = srate < < 9 ;
symb / = ( mclk > > 7 ) ;
}
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , SFRINIT1 , ( symb > > 8 ) & 0x7f ) ;
stv0900_write_reg ( intp , SFRINIT1 + 1 , ( symb & 0xff ) ) ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
static void stv0900_set_max_symbol_rate ( struct stv0900_internal * intp ,
2009-03-03 17:55:20 +03:00
u32 mclk , u32 srate ,
enum fe_stv0900_demod_num demod )
{
u32 symb ;
srate = 105 * ( srate / 100 ) ;
if ( srate > 60000000 ) {
symb = srate < < 4 ;
symb / = ( mclk > > 12 ) ;
} else if ( srate > 6000000 ) {
symb = srate < < 6 ;
symb / = ( mclk > > 10 ) ;
} else {
symb = srate < < 9 ;
symb / = ( mclk > > 7 ) ;
}
if ( symb < 0x7fff ) {
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , SFRUP1 , ( symb > > 8 ) & 0x7f ) ;
stv0900_write_reg ( intp , SFRUP1 + 1 , ( symb & 0xff ) ) ;
2009-03-03 17:55:20 +03:00
} else {
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , SFRUP1 , 0x7f ) ;
stv0900_write_reg ( intp , SFRUP1 + 1 , 0xff ) ;
2009-03-03 17:55:20 +03:00
}
}
2009-11-07 05:46:32 +03:00
static void stv0900_set_min_symbol_rate ( struct stv0900_internal * intp ,
2009-03-03 17:55:20 +03:00
u32 mclk , u32 srate ,
enum fe_stv0900_demod_num demod )
{
u32 symb ;
srate = 95 * ( srate / 100 ) ;
if ( srate > 60000000 ) {
symb = srate < < 4 ;
symb / = ( mclk > > 12 ) ;
} else if ( srate > 6000000 ) {
symb = srate < < 6 ;
symb / = ( mclk > > 10 ) ;
} else {
symb = srate < < 9 ;
symb / = ( mclk > > 7 ) ;
}
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , SFRLOW1 , ( symb > > 8 ) & 0xff ) ;
stv0900_write_reg ( intp , SFRLOW1 + 1 , ( symb & 0xff ) ) ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
static s32 stv0900_get_timing_offst ( struct stv0900_internal * intp ,
2009-03-03 17:55:20 +03:00
u32 srate ,
enum fe_stv0900_demod_num demod )
{
2009-11-07 05:46:32 +03:00
s32 timingoffset ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
timingoffset = ( stv0900_read_reg ( intp , TMGREG2 ) < < 16 ) +
( stv0900_read_reg ( intp , TMGREG2 + 1 ) < < 8 ) +
( stv0900_read_reg ( intp , TMGREG2 + 2 ) ) ;
2009-03-03 17:55:20 +03:00
timingoffset = ge2comp ( timingoffset , 24 ) ;
if ( timingoffset = = 0 )
timingoffset = 1 ;
timingoffset = ( ( s32 ) srate * 10 ) / ( ( s32 ) 0x1000000 / timingoffset ) ;
timingoffset / = 320 ;
return timingoffset ;
}
2009-11-07 05:46:32 +03:00
static void stv0900_set_dvbs2_rolloff ( struct stv0900_internal * intp ,
2009-03-03 17:55:20 +03:00
enum fe_stv0900_demod_num demod )
{
2009-11-07 05:46:32 +03:00
s32 rolloff ;
if ( intp - > chip_id = = 0x10 ) {
stv0900_write_bits ( intp , MANUALSX_ROLLOFF , 1 ) ;
rolloff = stv0900_read_reg ( intp , MATSTR1 ) & 0x03 ;
stv0900_write_bits ( intp , ROLLOFF_CONTROL , rolloff ) ;
} else if ( intp - > chip_id < = 0x20 )
stv0900_write_bits ( intp , MANUALSX_ROLLOFF , 0 ) ;
else /* cut 3.0 */
stv0900_write_bits ( intp , MANUALS2_ROLLOFF , 0 ) ;
2009-03-03 17:55:20 +03:00
}
static u32 stv0900_carrier_width ( u32 srate , enum fe_stv0900_rolloff ro )
{
u32 rolloff ;
switch ( ro ) {
case STV0900_20 :
rolloff = 20 ;
break ;
case STV0900_25 :
rolloff = 25 ;
break ;
case STV0900_35 :
default :
rolloff = 35 ;
break ;
}
return srate + ( srate * rolloff ) / 100 ;
}
2009-11-07 05:46:32 +03:00
static int stv0900_check_timing_lock ( struct stv0900_internal * intp ,
2009-03-03 17:55:20 +03:00
enum fe_stv0900_demod_num demod )
{
int timingLock = FALSE ;
2009-11-07 05:46:32 +03:00
s32 i ,
timingcpt = 0 ;
u8 car_freq ,
tmg_th_high ,
tmg_th_low ;
car_freq = stv0900_read_reg ( intp , CARFREQ ) ;
tmg_th_high = stv0900_read_reg ( intp , TMGTHRISE ) ;
tmg_th_low = stv0900_read_reg ( intp , TMGTHFALL ) ;
stv0900_write_reg ( intp , TMGTHRISE , 0x20 ) ;
stv0900_write_reg ( intp , TMGTHFALL , 0x0 ) ;
stv0900_write_bits ( intp , CFR_AUTOSCAN , 0 ) ;
stv0900_write_reg ( intp , RTC , 0x80 ) ;
stv0900_write_reg ( intp , RTCS2 , 0x40 ) ;
stv0900_write_reg ( intp , CARFREQ , 0x0 ) ;
stv0900_write_reg ( intp , CFRINIT1 , 0x0 ) ;
stv0900_write_reg ( intp , CFRINIT0 , 0x0 ) ;
stv0900_write_reg ( intp , AGC2REF , 0x65 ) ;
stv0900_write_reg ( intp , DMDISTATE , 0x18 ) ;
msleep ( 7 ) ;
for ( i = 0 ; i < 10 ; i + + ) {
if ( stv0900_get_bits ( intp , TMGLOCK_QUALITY ) > = 2 )
timingcpt + + ;
msleep ( 1 ) ;
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( timingcpt > = 3 )
timingLock = TRUE ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , AGC2REF , 0x38 ) ;
stv0900_write_reg ( intp , RTC , 0x88 ) ;
stv0900_write_reg ( intp , RTCS2 , 0x68 ) ;
stv0900_write_reg ( intp , CARFREQ , car_freq ) ;
stv0900_write_reg ( intp , TMGTHRISE , tmg_th_high ) ;
stv0900_write_reg ( intp , TMGTHFALL , tmg_th_low ) ;
2009-03-03 17:55:20 +03:00
return timingLock ;
}
static int stv0900_get_demod_cold_lock ( struct dvb_frontend * fe ,
s32 demod_timeout )
{
struct stv0900_state * state = fe - > demodulator_priv ;
2009-11-07 05:46:32 +03:00
struct stv0900_internal * intp = state - > internal ;
2009-03-03 17:55:20 +03:00
enum fe_stv0900_demod_num demod = state - > demod ;
2009-11-07 05:46:32 +03:00
int lock = FALSE ,
d = demod ;
s32 srate ,
search_range ,
locktimeout ,
currier_step ,
nb_steps ,
current_step ,
direction ,
tuner_freq ,
timeout ,
freq ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
srate = intp - > symbol_rate [ d ] ;
search_range = intp - > srch_range [ d ] ;
2009-03-03 17:55:20 +03:00
if ( srate > = 10000000 )
locktimeout = demod_timeout / 3 ;
else
locktimeout = demod_timeout / 2 ;
2009-11-07 05:46:32 +03:00
lock = stv0900_get_demod_lock ( intp , d , locktimeout ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( lock ! = FALSE )
return lock ;
if ( srate > = 10000000 ) {
if ( stv0900_check_timing_lock ( intp , d ) = = TRUE ) {
stv0900_write_reg ( intp , DMDISTATE , 0x1f ) ;
stv0900_write_reg ( intp , DMDISTATE , 0x15 ) ;
lock = stv0900_get_demod_lock ( intp , d , demod_timeout ) ;
} else
lock = FALSE ;
return lock ;
}
if ( intp - > chip_id < = 0x20 ) {
if ( srate < = 1000000 )
currier_step = 500 ;
else if ( srate < = 4000000 )
currier_step = 1000 ;
else if ( srate < = 7000000 )
currier_step = 2000 ;
else if ( srate < = 10000000 )
currier_step = 3000 ;
else
currier_step = 5000 ;
if ( srate > = 2000000 ) {
2009-03-03 17:55:20 +03:00
timeout = ( demod_timeout / 3 ) ;
if ( timeout > 1000 )
timeout = 1000 ;
2009-11-07 05:46:32 +03:00
} else
timeout = ( demod_timeout / 2 ) ;
} else {
/*cut 3.0 */
currier_step = srate / 4000 ;
timeout = ( demod_timeout * 3 ) / 4 ;
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
nb_steps = ( ( search_range / 1000 ) / currier_step ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( ( nb_steps % 2 ) ! = 0 )
nb_steps + = 1 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( nb_steps < = 0 )
nb_steps = 2 ;
else if ( nb_steps > 12 )
nb_steps = 12 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
current_step = 1 ;
direction = 1 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > chip_id < = 0x20 ) {
tuner_freq = intp - > freq [ d ] ;
intp - > bw [ d ] = stv0900_carrier_width ( intp - > symbol_rate [ d ] ,
intp - > rolloff ) + intp - > symbol_rate [ d ] ;
} else
tuner_freq = 0 ;
while ( ( current_step < = nb_steps ) & & ( lock = = FALSE ) ) {
if ( direction > 0 )
tuner_freq + = ( current_step * currier_step ) ;
else
tuner_freq - = ( current_step * currier_step ) ;
if ( intp - > chip_id < = 0x20 ) {
2009-12-15 02:24:56 +03:00
if ( intp - > tuner_type [ d ] = = 3 )
stv0900_set_tuner_auto ( intp , tuner_freq ,
intp - > bw [ d ] , demod ) ;
else
stv0900_set_tuner ( fe , tuner_freq , intp - > bw [ d ] ) ;
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , DMDISTATE , 0x1c ) ;
stv0900_write_reg ( intp , CFRINIT1 , 0 ) ;
stv0900_write_reg ( intp , CFRINIT0 , 0 ) ;
stv0900_write_reg ( intp , DMDISTATE , 0x1f ) ;
stv0900_write_reg ( intp , DMDISTATE , 0x15 ) ;
} else {
stv0900_write_reg ( intp , DMDISTATE , 0x1c ) ;
freq = ( tuner_freq * 65536 ) / ( intp - > mclk / 1000 ) ;
stv0900_write_bits ( intp , CFR_INIT1 , MSB ( freq ) ) ;
stv0900_write_bits ( intp , CFR_INIT0 , LSB ( freq ) ) ;
stv0900_write_reg ( intp , DMDISTATE , 0x1f ) ;
stv0900_write_reg ( intp , DMDISTATE , 0x05 ) ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
lock = stv0900_get_demod_lock ( intp , d , timeout ) ;
direction * = - 1 ;
current_step + + ;
2009-03-03 17:55:20 +03:00
}
return lock ;
}
static void stv0900_get_lock_timeout ( s32 * demod_timeout , s32 * fec_timeout ,
s32 srate ,
enum fe_stv0900_search_algo algo )
{
switch ( algo ) {
case STV0900_BLIND_SEARCH :
if ( srate < = 1500000 ) {
( * demod_timeout ) = 1500 ;
( * fec_timeout ) = 400 ;
} else if ( srate < = 5000000 ) {
( * demod_timeout ) = 1000 ;
( * fec_timeout ) = 300 ;
} else {
( * demod_timeout ) = 700 ;
( * fec_timeout ) = 100 ;
}
break ;
case STV0900_COLD_START :
case STV0900_WARM_START :
default :
if ( srate < = 1000000 ) {
( * demod_timeout ) = 3000 ;
( * fec_timeout ) = 1700 ;
} else if ( srate < = 2000000 ) {
( * demod_timeout ) = 2500 ;
( * fec_timeout ) = 1100 ;
} else if ( srate < = 5000000 ) {
( * demod_timeout ) = 1000 ;
( * fec_timeout ) = 550 ;
} else if ( srate < = 10000000 ) {
( * demod_timeout ) = 700 ;
( * fec_timeout ) = 250 ;
} else if ( srate < = 20000000 ) {
( * demod_timeout ) = 400 ;
( * fec_timeout ) = 130 ;
2009-11-07 05:46:32 +03:00
} else {
2009-03-03 17:55:20 +03:00
( * demod_timeout ) = 300 ;
( * fec_timeout ) = 100 ;
}
break ;
}
if ( algo = = STV0900_WARM_START )
( * demod_timeout ) / = 2 ;
}
2009-11-07 05:46:32 +03:00
static void stv0900_set_viterbi_tracq ( struct stv0900_internal * intp ,
2009-03-03 17:55:20 +03:00
enum fe_stv0900_demod_num demod )
{
2009-11-07 05:46:32 +03:00
s32 vth_reg = VTH12 ;
2009-03-03 17:55:20 +03:00
2009-09-19 15:37:40 +04:00
dprintk ( " %s \n " , __func__ ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , vth_reg + + , 0xd0 ) ;
stv0900_write_reg ( intp , vth_reg + + , 0x7d ) ;
stv0900_write_reg ( intp , vth_reg + + , 0x53 ) ;
stv0900_write_reg ( intp , vth_reg + + , 0x2f ) ;
stv0900_write_reg ( intp , vth_reg + + , 0x24 ) ;
stv0900_write_reg ( intp , vth_reg + + , 0x1f ) ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
static void stv0900_set_viterbi_standard ( struct stv0900_internal * intp ,
enum fe_stv0900_search_standard standard ,
enum fe_stv0900_fec fec ,
2009-03-03 17:55:20 +03:00
enum fe_stv0900_demod_num demod )
{
2009-09-19 15:37:40 +04:00
dprintk ( " %s: ViterbiStandard = " , __func__ ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
switch ( standard ) {
2009-03-03 17:55:20 +03:00
case STV0900_AUTO_SEARCH :
dprintk ( " Auto \n " ) ;
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , FECM , 0x10 ) ;
stv0900_write_reg ( intp , PRVIT , 0x3f ) ;
2009-03-03 17:55:20 +03:00
break ;
case STV0900_SEARCH_DVBS1 :
dprintk ( " DVBS1 \n " ) ;
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , FECM , 0x00 ) ;
switch ( fec ) {
2009-03-03 17:55:20 +03:00
case STV0900_FEC_UNKNOWN :
default :
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , PRVIT , 0x2f ) ;
2009-03-03 17:55:20 +03:00
break ;
case STV0900_FEC_1_2 :
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , PRVIT , 0x01 ) ;
2009-03-03 17:55:20 +03:00
break ;
case STV0900_FEC_2_3 :
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , PRVIT , 0x02 ) ;
2009-03-03 17:55:20 +03:00
break ;
case STV0900_FEC_3_4 :
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , PRVIT , 0x04 ) ;
2009-03-03 17:55:20 +03:00
break ;
case STV0900_FEC_5_6 :
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , PRVIT , 0x08 ) ;
2009-03-03 17:55:20 +03:00
break ;
case STV0900_FEC_7_8 :
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , PRVIT , 0x20 ) ;
2009-03-03 17:55:20 +03:00
break ;
}
break ;
case STV0900_SEARCH_DSS :
dprintk ( " DSS \n " ) ;
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , FECM , 0x80 ) ;
switch ( fec ) {
2009-03-03 17:55:20 +03:00
case STV0900_FEC_UNKNOWN :
default :
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , PRVIT , 0x13 ) ;
2009-03-03 17:55:20 +03:00
break ;
case STV0900_FEC_1_2 :
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , PRVIT , 0x01 ) ;
2009-03-03 17:55:20 +03:00
break ;
case STV0900_FEC_2_3 :
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , PRVIT , 0x02 ) ;
2009-03-03 17:55:20 +03:00
break ;
case STV0900_FEC_6_7 :
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , PRVIT , 0x10 ) ;
2009-03-03 17:55:20 +03:00
break ;
}
break ;
default :
break ;
}
}
2009-11-07 05:46:32 +03:00
static enum fe_stv0900_fec stv0900_get_vit_fec ( struct stv0900_internal * intp ,
enum fe_stv0900_demod_num demod )
{
enum fe_stv0900_fec prate ;
s32 rate_fld = stv0900_get_bits ( intp , VIT_CURPUN ) ;
switch ( rate_fld ) {
case 13 :
prate = STV0900_FEC_1_2 ;
break ;
case 18 :
prate = STV0900_FEC_2_3 ;
break ;
case 21 :
prate = STV0900_FEC_3_4 ;
break ;
case 24 :
prate = STV0900_FEC_5_6 ;
break ;
case 25 :
prate = STV0900_FEC_6_7 ;
break ;
case 26 :
prate = STV0900_FEC_7_8 ;
break ;
default :
prate = STV0900_FEC_UNKNOWN ;
break ;
}
return prate ;
}
2010-01-16 19:35:36 +03:00
static void stv0900_set_dvbs1_track_car_loop ( struct stv0900_internal * intp ,
2009-11-07 05:46:32 +03:00
enum fe_stv0900_demod_num demod ,
u32 srate )
{
if ( intp - > chip_id > = 0x30 ) {
if ( srate > = 15000000 ) {
stv0900_write_reg ( intp , ACLC , 0x2b ) ;
stv0900_write_reg ( intp , BCLC , 0x1a ) ;
} else if ( ( srate > = 7000000 ) & & ( 15000000 > srate ) ) {
stv0900_write_reg ( intp , ACLC , 0x0c ) ;
stv0900_write_reg ( intp , BCLC , 0x1b ) ;
} else if ( srate < 7000000 ) {
stv0900_write_reg ( intp , ACLC , 0x2c ) ;
stv0900_write_reg ( intp , BCLC , 0x1c ) ;
}
} else { /*cut 2.0 and 1.x*/
stv0900_write_reg ( intp , ACLC , 0x1a ) ;
stv0900_write_reg ( intp , BCLC , 0x09 ) ;
}
}
2009-03-03 17:55:20 +03:00
static void stv0900_track_optimization ( struct dvb_frontend * fe )
{
struct stv0900_state * state = fe - > demodulator_priv ;
2009-11-07 05:46:32 +03:00
struct stv0900_internal * intp = state - > internal ;
2009-03-03 17:55:20 +03:00
enum fe_stv0900_demod_num demod = state - > demod ;
2009-11-07 05:46:32 +03:00
s32 srate ,
pilots ,
aclc ,
freq1 ,
freq0 ,
i = 0 ,
timed ,
timef ,
blind_tun_sw = 0 ,
modulation ;
2009-03-03 17:55:20 +03:00
enum fe_stv0900_modcode foundModcod ;
2009-09-19 15:37:40 +04:00
dprintk ( " %s \n " , __func__ ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
srate = stv0900_get_symbol_rate ( intp , intp - > mclk , demod ) ;
srate + = stv0900_get_timing_offst ( intp , srate , demod ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
switch ( intp - > result [ demod ] . standard ) {
case STV0900_DVBS1_STANDARD :
case STV0900_DSS_STANDARD :
dprintk ( " %s: found DVB-S or DSS \n " , __func__ ) ;
if ( intp - > srch_standard [ demod ] = = STV0900_AUTO_SEARCH ) {
stv0900_write_bits ( intp , DVBS1_ENABLE , 1 ) ;
stv0900_write_bits ( intp , DVBS2_ENABLE , 0 ) ;
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_write_bits ( intp , ROLLOFF_CONTROL , intp - > rolloff ) ;
stv0900_write_bits ( intp , MANUALSX_ROLLOFF , 1 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > chip_id < 0x30 ) {
stv0900_write_reg ( intp , ERRCTRL1 , 0x75 ) ;
2009-03-03 17:55:20 +03:00
break ;
2009-11-07 05:46:32 +03:00
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( stv0900_get_vit_fec ( intp , demod ) = = STV0900_FEC_1_2 ) {
stv0900_write_reg ( intp , GAUSSR0 , 0x98 ) ;
stv0900_write_reg ( intp , CCIR0 , 0x18 ) ;
} else {
stv0900_write_reg ( intp , GAUSSR0 , 0x18 ) ;
stv0900_write_reg ( intp , CCIR0 , 0x18 ) ;
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , ERRCTRL1 , 0x75 ) ;
break ;
case STV0900_DVBS2_STANDARD :
dprintk ( " %s: found DVB-S2 \n " , __func__ ) ;
stv0900_write_bits ( intp , DVBS1_ENABLE , 0 ) ;
stv0900_write_bits ( intp , DVBS2_ENABLE , 1 ) ;
stv0900_write_reg ( intp , ACLC , 0 ) ;
stv0900_write_reg ( intp , BCLC , 0 ) ;
if ( intp - > result [ demod ] . frame_len = = STV0900_LONG_FRAME ) {
foundModcod = stv0900_get_bits ( intp , DEMOD_MODCOD ) ;
pilots = stv0900_get_bits ( intp , DEMOD_TYPE ) & 0x01 ;
aclc = stv0900_get_optim_carr_loop ( srate ,
foundModcod ,
pilots ,
intp - > chip_id ) ;
if ( foundModcod < = STV0900_QPSK_910 )
stv0900_write_reg ( intp , ACLC2S2Q , aclc ) ;
else if ( foundModcod < = STV0900_8PSK_910 ) {
stv0900_write_reg ( intp , ACLC2S2Q , 0x2a ) ;
stv0900_write_reg ( intp , ACLC2S28 , aclc ) ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
if ( ( intp - > demod_mode = = STV0900_SINGLE ) & &
( foundModcod > STV0900_8PSK_910 ) ) {
if ( foundModcod < = STV0900_16APSK_910 ) {
stv0900_write_reg ( intp , ACLC2S2Q , 0x2a ) ;
stv0900_write_reg ( intp , ACLC2S216A ,
aclc ) ;
} else if ( foundModcod < = STV0900_32APSK_910 ) {
stv0900_write_reg ( intp , ACLC2S2Q , 0x2a ) ;
stv0900_write_reg ( intp , ACLC2S232A ,
aclc ) ;
}
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
} else {
modulation = intp - > result [ demod ] . modulation ;
aclc = stv0900_get_optim_short_carr_loop ( srate ,
modulation , intp - > chip_id ) ;
if ( modulation = = STV0900_QPSK )
stv0900_write_reg ( intp , ACLC2S2Q , aclc ) ;
else if ( modulation = = STV0900_8PSK ) {
stv0900_write_reg ( intp , ACLC2S2Q , 0x2a ) ;
stv0900_write_reg ( intp , ACLC2S28 , aclc ) ;
} else if ( modulation = = STV0900_16APSK ) {
stv0900_write_reg ( intp , ACLC2S2Q , 0x2a ) ;
stv0900_write_reg ( intp , ACLC2S216A , aclc ) ;
} else if ( modulation = = STV0900_32APSK ) {
stv0900_write_reg ( intp , ACLC2S2Q , 0x2a ) ;
stv0900_write_reg ( intp , ACLC2S232A , aclc ) ;
2009-03-03 17:55:20 +03:00
}
}
2009-11-07 05:46:32 +03:00
if ( intp - > chip_id < = 0x11 ) {
if ( intp - > demod_mode ! = STV0900_SINGLE )
stv0900_activate_s2_modcod ( intp , demod ) ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , ERRCTRL1 , 0x67 ) ;
break ;
case STV0900_UNKNOWN_STANDARD :
default :
dprintk ( " %s: found unknown standard \n " , __func__ ) ;
stv0900_write_bits ( intp , DVBS1_ENABLE , 1 ) ;
stv0900_write_bits ( intp , DVBS2_ENABLE , 1 ) ;
break ;
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
freq1 = stv0900_read_reg ( intp , CFR2 ) ;
freq0 = stv0900_read_reg ( intp , CFR1 ) ;
if ( intp - > srch_algo [ demod ] = = STV0900_BLIND_SEARCH ) {
stv0900_write_reg ( intp , SFRSTEP , 0x00 ) ;
stv0900_write_bits ( intp , SCAN_ENABLE , 0 ) ;
stv0900_write_bits ( intp , CFR_AUTOSCAN , 0 ) ;
stv0900_write_reg ( intp , TMGCFG2 , 0xc1 ) ;
stv0900_set_symbol_rate ( intp , intp - > mclk , srate , demod ) ;
blind_tun_sw = 1 ;
if ( intp - > result [ demod ] . standard ! = STV0900_DVBS2_STANDARD )
stv0900_set_dvbs1_track_car_loop ( intp , demod , srate ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > chip_id > = 0x20 ) {
if ( ( intp - > srch_standard [ demod ] = = STV0900_SEARCH_DVBS1 ) | |
( intp - > srch_standard [ demod ] = =
STV0900_SEARCH_DSS ) | |
( intp - > srch_standard [ demod ] = =
STV0900_AUTO_SEARCH ) ) {
stv0900_write_reg ( intp , VAVSRVIT , 0x0a ) ;
stv0900_write_reg ( intp , VITSCALE , 0x0 ) ;
}
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > chip_id < 0x20 )
stv0900_write_reg ( intp , CARHDR , 0x08 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > chip_id = = 0x10 )
stv0900_write_reg ( intp , CORRELEXP , 0x0a ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , AGC2REF , 0x38 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( ( intp - > chip_id > = 0x20 ) | |
( blind_tun_sw = = 1 ) | |
( intp - > symbol_rate [ demod ] < 10000000 ) ) {
stv0900_write_reg ( intp , CFRINIT1 , freq1 ) ;
stv0900_write_reg ( intp , CFRINIT0 , freq0 ) ;
intp - > bw [ demod ] = stv0900_carrier_width ( srate ,
intp - > rolloff ) + 10000000 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( ( intp - > chip_id > = 0x20 ) | | ( blind_tun_sw = = 1 ) ) {
2009-12-15 02:24:56 +03:00
if ( intp - > srch_algo [ demod ] ! = STV0900_WARM_START ) {
if ( intp - > tuner_type [ demod ] = = 3 )
stv0900_set_tuner_auto ( intp ,
intp - > freq [ demod ] ,
intp - > bw [ demod ] ,
demod ) ;
else
stv0900_set_bandwidth ( fe ,
intp - > bw [ demod ] ) ;
}
2009-11-07 05:46:32 +03:00
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( ( intp - > srch_algo [ demod ] = = STV0900_BLIND_SEARCH ) | |
( intp - > symbol_rate [ demod ] < 10000000 ) )
msleep ( 50 ) ;
else
msleep ( 5 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_get_lock_timeout ( & timed , & timef , srate ,
STV0900_WARM_START ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( stv0900_get_demod_lock ( intp , demod , timed / 2 ) = = FALSE ) {
stv0900_write_reg ( intp , DMDISTATE , 0x1f ) ;
stv0900_write_reg ( intp , CFRINIT1 , freq1 ) ;
stv0900_write_reg ( intp , CFRINIT0 , freq0 ) ;
stv0900_write_reg ( intp , DMDISTATE , 0x18 ) ;
i = 0 ;
while ( ( stv0900_get_demod_lock ( intp ,
demod ,
timed / 2 ) = = FALSE ) & &
( i < = 2 ) ) {
stv0900_write_reg ( intp , DMDISTATE , 0x1f ) ;
stv0900_write_reg ( intp , CFRINIT1 , freq1 ) ;
stv0900_write_reg ( intp , CFRINIT0 , freq0 ) ;
stv0900_write_reg ( intp , DMDISTATE , 0x18 ) ;
i + + ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > chip_id > = 0x20 )
stv0900_write_reg ( intp , CARFREQ , 0x49 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( ( intp - > result [ demod ] . standard = = STV0900_DVBS1_STANDARD ) | |
( intp - > result [ demod ] . standard = = STV0900_DSS_STANDARD ) )
stv0900_set_viterbi_tracq ( intp , demod ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
static int stv0900_get_fec_lock ( struct stv0900_internal * intp ,
enum fe_stv0900_demod_num demod , s32 time_out )
{
s32 timer = 0 , lock = 0 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
enum fe_stv0900_search_state dmd_state ;
2009-03-03 17:55:20 +03:00
2009-09-19 15:37:40 +04:00
dprintk ( " %s \n " , __func__ ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
dmd_state = stv0900_get_bits ( intp , HEADER_MODE ) ;
2009-03-03 17:55:20 +03:00
while ( ( timer < time_out ) & & ( lock = = 0 ) ) {
switch ( dmd_state ) {
case STV0900_SEARCH :
case STV0900_PLH_DETECTED :
default :
lock = 0 ;
break ;
case STV0900_DVBS2_FOUND :
2009-11-07 05:46:32 +03:00
lock = stv0900_get_bits ( intp , PKTDELIN_LOCK ) ;
2009-03-03 17:55:20 +03:00
break ;
case STV0900_DVBS_FOUND :
2009-11-07 05:46:32 +03:00
lock = stv0900_get_bits ( intp , LOCKEDVIT ) ;
2009-03-03 17:55:20 +03:00
break ;
}
if ( lock = = 0 ) {
msleep ( 10 ) ;
timer + = 10 ;
}
}
if ( lock )
2009-11-07 05:46:32 +03:00
dprintk ( " %s: DEMOD FEC LOCK OK \n " , __func__ ) ;
2009-03-03 17:55:20 +03:00
else
2009-11-07 05:46:32 +03:00
dprintk ( " %s: DEMOD FEC LOCK FAIL \n " , __func__ ) ;
2009-03-03 17:55:20 +03:00
return lock ;
}
2009-11-07 05:46:32 +03:00
static int stv0900_wait_for_lock ( struct stv0900_internal * intp ,
2009-03-03 17:55:20 +03:00
enum fe_stv0900_demod_num demod ,
s32 dmd_timeout , s32 fec_timeout )
{
2009-11-07 05:46:32 +03:00
s32 timer = 0 , lock = 0 ;
2009-03-03 17:55:20 +03:00
2009-09-19 15:37:40 +04:00
dprintk ( " %s \n " , __func__ ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
lock = stv0900_get_demod_lock ( intp , demod , dmd_timeout ) ;
2009-03-03 17:55:20 +03:00
if ( lock )
2014-02-26 06:26:41 +04:00
lock = stv0900_get_fec_lock ( intp , demod , fec_timeout ) ;
2009-03-03 17:55:20 +03:00
if ( lock ) {
lock = 0 ;
2009-11-07 05:46:32 +03:00
dprintk ( " %s: Timer = %d, time_out = %d \n " ,
__func__ , timer , fec_timeout ) ;
2009-03-03 17:55:20 +03:00
while ( ( timer < fec_timeout ) & & ( lock = = 0 ) ) {
2009-11-07 05:46:32 +03:00
lock = stv0900_get_bits ( intp , TSFIFO_LINEOK ) ;
2009-03-03 17:55:20 +03:00
msleep ( 1 ) ;
timer + + ;
}
}
if ( lock )
2009-09-19 15:37:40 +04:00
dprintk ( " %s: DEMOD LOCK OK \n " , __func__ ) ;
2009-03-03 17:55:20 +03:00
else
2009-09-19 15:37:40 +04:00
dprintk ( " %s: DEMOD LOCK FAIL \n " , __func__ ) ;
2009-03-03 17:55:20 +03:00
if ( lock )
return TRUE ;
else
return FALSE ;
}
enum fe_stv0900_tracking_standard stv0900_get_standard ( struct dvb_frontend * fe ,
enum fe_stv0900_demod_num demod )
{
struct stv0900_state * state = fe - > demodulator_priv ;
2009-11-07 05:46:32 +03:00
struct stv0900_internal * intp = state - > internal ;
2009-03-03 17:55:20 +03:00
enum fe_stv0900_tracking_standard fnd_standard ;
2009-11-07 05:46:32 +03:00
int hdr_mode = stv0900_get_bits ( intp , HEADER_MODE ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
switch ( hdr_mode ) {
case 2 :
2009-03-03 17:55:20 +03:00
fnd_standard = STV0900_DVBS2_STANDARD ;
2009-11-07 05:46:32 +03:00
break ;
case 3 :
if ( stv0900_get_bits ( intp , DSS_DVB ) = = 1 )
2009-03-03 17:55:20 +03:00
fnd_standard = STV0900_DSS_STANDARD ;
else
fnd_standard = STV0900_DVBS1_STANDARD ;
2009-11-07 05:46:32 +03:00
break ;
default :
2009-03-03 17:55:20 +03:00
fnd_standard = STV0900_UNKNOWN_STANDARD ;
2009-11-07 05:46:32 +03:00
}
dprintk ( " %s: standard %d \n " , __func__ , fnd_standard ) ;
2009-03-03 17:55:20 +03:00
return fnd_standard ;
}
2009-11-07 05:46:32 +03:00
static s32 stv0900_get_carr_freq ( struct stv0900_internal * intp , u32 mclk ,
2009-03-03 17:55:20 +03:00
enum fe_stv0900_demod_num demod )
{
2009-11-07 05:46:32 +03:00
s32 derot ,
rem1 ,
rem2 ,
intval1 ,
intval2 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
derot = ( stv0900_get_bits ( intp , CAR_FREQ2 ) < < 16 ) +
( stv0900_get_bits ( intp , CAR_FREQ1 ) < < 8 ) +
( stv0900_get_bits ( intp , CAR_FREQ0 ) ) ;
2009-03-03 17:55:20 +03:00
derot = ge2comp ( derot , 24 ) ;
intval1 = mclk > > 12 ;
intval2 = derot > > 12 ;
rem1 = mclk % 0x1000 ;
rem2 = derot % 0x1000 ;
derot = ( intval1 * intval2 ) +
( ( intval1 * rem2 ) > > 12 ) +
( ( intval2 * rem1 ) > > 12 ) ;
return derot ;
}
static u32 stv0900_get_tuner_freq ( struct dvb_frontend * fe )
{
struct dvb_frontend_ops * frontend_ops = NULL ;
struct dvb_tuner_ops * tuner_ops = NULL ;
2009-11-07 05:46:32 +03:00
u32 freq = 0 ;
2009-03-03 17:55:20 +03:00
2013-02-04 05:34:48 +04:00
frontend_ops = & fe - > ops ;
tuner_ops = & frontend_ops - > tuner_ops ;
2009-03-03 17:55:20 +03:00
if ( tuner_ops - > get_frequency ) {
2009-11-07 05:46:32 +03:00
if ( ( tuner_ops - > get_frequency ( fe , & freq ) ) < 0 )
2009-03-03 17:55:20 +03:00
dprintk ( " %s: Invalid parameter \n " , __func__ ) ;
else
2009-11-07 05:46:32 +03:00
dprintk ( " %s: Frequency=%d \n " , __func__ , freq ) ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
return freq ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
static enum
fe_stv0900_signal_type stv0900_get_signal_params ( struct dvb_frontend * fe )
2009-03-03 17:55:20 +03:00
{
struct stv0900_state * state = fe - > demodulator_priv ;
2009-11-07 05:46:32 +03:00
struct stv0900_internal * intp = state - > internal ;
2009-03-03 17:55:20 +03:00
enum fe_stv0900_demod_num demod = state - > demod ;
enum fe_stv0900_signal_type range = STV0900_OUTOFRANGE ;
2009-11-07 05:46:32 +03:00
struct stv0900_signal_info * result = & intp - > result [ demod ] ;
s32 offsetFreq ,
srate_offset ;
int i = 0 ,
d = demod ;
2009-03-03 17:55:20 +03:00
u8 timing ;
msleep ( 5 ) ;
2009-11-07 05:46:32 +03:00
if ( intp - > srch_algo [ d ] = = STV0900_BLIND_SEARCH ) {
timing = stv0900_read_reg ( intp , TMGREG2 ) ;
i = 0 ;
stv0900_write_reg ( intp , SFRSTEP , 0x5c ) ;
while ( ( i < = 50 ) & & ( timing ! = 0 ) & & ( timing ! = 0xff ) ) {
timing = stv0900_read_reg ( intp , TMGREG2 ) ;
msleep ( 5 ) ;
i + = 5 ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
result - > standard = stv0900_get_standard ( fe , d ) ;
2009-12-15 02:24:56 +03:00
if ( intp - > tuner_type [ demod ] = = 3 )
result - > frequency = stv0900_get_freq_auto ( intp , d ) ;
else
result - > frequency = stv0900_get_tuner_freq ( fe ) ;
2009-11-07 05:46:32 +03:00
offsetFreq = stv0900_get_carr_freq ( intp , intp - > mclk , d ) / 1000 ;
result - > frequency + = offsetFreq ;
result - > symbol_rate = stv0900_get_symbol_rate ( intp , intp - > mclk , d ) ;
srate_offset = stv0900_get_timing_offst ( intp , result - > symbol_rate , d ) ;
result - > symbol_rate + = srate_offset ;
result - > fec = stv0900_get_vit_fec ( intp , d ) ;
result - > modcode = stv0900_get_bits ( intp , DEMOD_MODCOD ) ;
result - > pilot = stv0900_get_bits ( intp , DEMOD_TYPE ) & 0x01 ;
result - > frame_len = ( ( u32 ) stv0900_get_bits ( intp , DEMOD_TYPE ) ) > > 1 ;
result - > rolloff = stv0900_get_bits ( intp , ROLLOFF_STATUS ) ;
2010-02-06 11:55:47 +03:00
dprintk ( " %s: modcode=0x%x \n " , __func__ , result - > modcode ) ;
2009-11-07 05:46:32 +03:00
switch ( result - > standard ) {
case STV0900_DVBS2_STANDARD :
result - > spectrum = stv0900_get_bits ( intp , SPECINV_DEMOD ) ;
if ( result - > modcode < = STV0900_QPSK_910 )
result - > modulation = STV0900_QPSK ;
else if ( result - > modcode < = STV0900_8PSK_910 )
result - > modulation = STV0900_8PSK ;
else if ( result - > modcode < = STV0900_16APSK_910 )
result - > modulation = STV0900_16APSK ;
else if ( result - > modcode < = STV0900_32APSK_910 )
result - > modulation = STV0900_32APSK ;
else
result - > modulation = STV0900_UNKNOWN ;
2009-03-03 17:55:20 +03:00
break ;
2009-11-07 05:46:32 +03:00
case STV0900_DVBS1_STANDARD :
case STV0900_DSS_STANDARD :
result - > spectrum = stv0900_get_bits ( intp , IQINV ) ;
result - > modulation = STV0900_QPSK ;
break ;
default :
break ;
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( ( intp - > srch_algo [ d ] = = STV0900_BLIND_SEARCH ) | |
( intp - > symbol_rate [ d ] < 10000000 ) ) {
offsetFreq = result - > frequency - intp - > freq [ d ] ;
2009-12-15 02:24:56 +03:00
if ( intp - > tuner_type [ demod ] = = 3 )
intp - > freq [ d ] = stv0900_get_freq_auto ( intp , d ) ;
else
intp - > freq [ d ] = stv0900_get_tuner_freq ( fe ) ;
2009-11-07 05:46:32 +03:00
if ( ABS ( offsetFreq ) < = ( ( intp - > srch_range [ d ] / 2000 ) + 500 ) )
range = STV0900_RANGEOK ;
else if ( ABS ( offsetFreq ) < =
( stv0900_carrier_width ( result - > symbol_rate ,
result - > rolloff ) / 2000 ) )
range = STV0900_RANGEOK ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
} else if ( ABS ( offsetFreq ) < = ( ( intp - > srch_range [ d ] / 2000 ) + 500 ) )
range = STV0900_RANGEOK ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
dprintk ( " %s: range %d \n " , __func__ , range ) ;
2009-03-03 17:55:20 +03:00
return range ;
}
2009-11-07 05:46:32 +03:00
static enum
fe_stv0900_signal_type stv0900_dvbs1_acq_workaround ( struct dvb_frontend * fe )
2009-03-03 17:55:20 +03:00
{
struct stv0900_state * state = fe - > demodulator_priv ;
2009-11-07 05:46:32 +03:00
struct stv0900_internal * intp = state - > internal ;
2009-03-03 17:55:20 +03:00
enum fe_stv0900_demod_num demod = state - > demod ;
2009-07-02 22:57:09 +04:00
enum fe_stv0900_signal_type signal_type = STV0900_NODATA ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
s32 srate ,
demod_timeout ,
fec_timeout ,
freq1 ,
freq0 ;
intp - > result [ demod ] . locked = FALSE ;
if ( stv0900_get_bits ( intp , HEADER_MODE ) = = STV0900_DVBS_FOUND ) {
srate = stv0900_get_symbol_rate ( intp , intp - > mclk , demod ) ;
srate + = stv0900_get_timing_offst ( intp , srate , demod ) ;
if ( intp - > srch_algo [ demod ] = = STV0900_BLIND_SEARCH )
stv0900_set_symbol_rate ( intp , intp - > mclk , srate , demod ) ;
stv0900_get_lock_timeout ( & demod_timeout , & fec_timeout ,
srate , STV0900_WARM_START ) ;
freq1 = stv0900_read_reg ( intp , CFR2 ) ;
freq0 = stv0900_read_reg ( intp , CFR1 ) ;
stv0900_write_bits ( intp , CFR_AUTOSCAN , 0 ) ;
stv0900_write_bits ( intp , SPECINV_CONTROL ,
STV0900_IQ_FORCE_SWAPPED ) ;
stv0900_write_reg ( intp , DMDISTATE , 0x1c ) ;
stv0900_write_reg ( intp , CFRINIT1 , freq1 ) ;
stv0900_write_reg ( intp , CFRINIT0 , freq0 ) ;
stv0900_write_reg ( intp , DMDISTATE , 0x18 ) ;
if ( stv0900_wait_for_lock ( intp , demod ,
demod_timeout , fec_timeout ) = = TRUE ) {
intp - > result [ demod ] . locked = TRUE ;
signal_type = stv0900_get_signal_params ( fe ) ;
stv0900_track_optimization ( fe ) ;
} else {
stv0900_write_bits ( intp , SPECINV_CONTROL ,
STV0900_IQ_FORCE_NORMAL ) ;
stv0900_write_reg ( intp , DMDISTATE , 0x1c ) ;
stv0900_write_reg ( intp , CFRINIT1 , freq1 ) ;
stv0900_write_reg ( intp , CFRINIT0 , freq0 ) ;
stv0900_write_reg ( intp , DMDISTATE , 0x18 ) ;
if ( stv0900_wait_for_lock ( intp , demod ,
demod_timeout , fec_timeout ) = = TRUE ) {
intp - > result [ demod ] . locked = TRUE ;
2009-03-03 17:55:20 +03:00
signal_type = stv0900_get_signal_params ( fe ) ;
stv0900_track_optimization ( fe ) ;
}
2009-11-07 05:46:32 +03:00
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
} else
intp - > result [ demod ] . locked = FALSE ;
2009-03-03 17:55:20 +03:00
return signal_type ;
}
2009-11-07 05:46:32 +03:00
static u16 stv0900_blind_check_agc2_min_level ( struct stv0900_internal * intp ,
2009-03-03 17:55:20 +03:00
enum fe_stv0900_demod_num demod )
{
u32 minagc2level = 0xffff ,
agc2level ,
init_freq , freq_step ;
s32 i , j , nb_steps , direction ;
2009-09-19 15:37:40 +04:00
dprintk ( " %s \n " , __func__ ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , AGC2REF , 0x38 ) ;
stv0900_write_bits ( intp , SCAN_ENABLE , 0 ) ;
stv0900_write_bits ( intp , CFR_AUTOSCAN , 0 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_write_bits ( intp , AUTO_GUP , 1 ) ;
stv0900_write_bits ( intp , AUTO_GLOW , 1 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , DMDT0M , 0x0 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_set_symbol_rate ( intp , intp - > mclk , 1000000 , demod ) ;
nb_steps = - 1 + ( intp - > srch_range [ demod ] / 1000000 ) ;
nb_steps / = 2 ;
nb_steps = ( 2 * nb_steps ) + 1 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( nb_steps < 0 )
nb_steps = 1 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
direction = 1 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
freq_step = ( 1000000 < < 8 ) / ( intp - > mclk > > 8 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
init_freq = 0 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
for ( i = 0 ; i < nb_steps ; i + + ) {
if ( direction > 0 )
init_freq = init_freq + ( freq_step * i ) ;
else
init_freq = init_freq - ( freq_step * i ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
direction * = - 1 ;
stv0900_write_reg ( intp , DMDISTATE , 0x5C ) ;
stv0900_write_reg ( intp , CFRINIT1 , ( init_freq > > 8 ) & 0xff ) ;
stv0900_write_reg ( intp , CFRINIT0 , init_freq & 0xff ) ;
stv0900_write_reg ( intp , DMDISTATE , 0x58 ) ;
msleep ( 10 ) ;
agc2level = 0 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
for ( j = 0 ; j < 10 ; j + + )
agc2level + = ( stv0900_read_reg ( intp , AGC2I1 ) < < 8 )
| stv0900_read_reg ( intp , AGC2I0 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
agc2level / = 10 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( agc2level < minagc2level )
minagc2level = agc2level ;
2009-03-03 17:55:20 +03:00
}
return ( u16 ) minagc2level ;
}
static u32 stv0900_search_srate_coarse ( struct dvb_frontend * fe )
{
struct stv0900_state * state = fe - > demodulator_priv ;
2009-11-07 05:46:32 +03:00
struct stv0900_internal * intp = state - > internal ;
2009-03-03 17:55:20 +03:00
enum fe_stv0900_demod_num demod = state - > demod ;
2009-11-07 05:46:32 +03:00
int timing_lck = FALSE ;
2009-03-03 17:55:20 +03:00
s32 i , timingcpt = 0 ,
direction = 1 ,
nb_steps ,
current_step = 0 ,
tuner_freq ;
2009-11-07 05:46:32 +03:00
u32 agc2_th ,
coarse_srate = 0 ,
agc2_integr = 0 ,
currier_step = 1200 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > chip_id > = 0x30 )
agc2_th = 0x2e00 ;
else
agc2_th = 0x1f00 ;
stv0900_write_bits ( intp , DEMOD_MODE , 0x1f ) ;
stv0900_write_reg ( intp , TMGCFG , 0x12 ) ;
stv0900_write_reg ( intp , TMGTHRISE , 0xf0 ) ;
stv0900_write_reg ( intp , TMGTHFALL , 0xe0 ) ;
stv0900_write_bits ( intp , SCAN_ENABLE , 1 ) ;
stv0900_write_bits ( intp , CFR_AUTOSCAN , 1 ) ;
stv0900_write_reg ( intp , SFRUP1 , 0x83 ) ;
stv0900_write_reg ( intp , SFRUP0 , 0xc0 ) ;
stv0900_write_reg ( intp , SFRLOW1 , 0x82 ) ;
stv0900_write_reg ( intp , SFRLOW0 , 0xa0 ) ;
stv0900_write_reg ( intp , DMDT0M , 0x0 ) ;
stv0900_write_reg ( intp , AGC2REF , 0x50 ) ;
if ( intp - > chip_id > = 0x30 ) {
stv0900_write_reg ( intp , CARFREQ , 0x99 ) ;
stv0900_write_reg ( intp , SFRSTEP , 0x98 ) ;
} else if ( intp - > chip_id > = 0x20 ) {
stv0900_write_reg ( intp , CARFREQ , 0x6a ) ;
stv0900_write_reg ( intp , SFRSTEP , 0x95 ) ;
} else {
stv0900_write_reg ( intp , CARFREQ , 0xed ) ;
stv0900_write_reg ( intp , SFRSTEP , 0x73 ) ;
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > symbol_rate [ demod ] < = 2000000 )
currier_step = 1000 ;
else if ( intp - > symbol_rate [ demod ] < = 5000000 )
currier_step = 2000 ;
else if ( intp - > symbol_rate [ demod ] < = 12000000 )
currier_step = 3000 ;
else
2009-03-03 17:55:20 +03:00
currier_step = 5000 ;
2009-11-07 05:46:32 +03:00
nb_steps = - 1 + ( ( intp - > srch_range [ demod ] / 1000 ) / currier_step ) ;
nb_steps / = 2 ;
nb_steps = ( 2 * nb_steps ) + 1 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( nb_steps < 0 )
nb_steps = 1 ;
else if ( nb_steps > 10 ) {
nb_steps = 11 ;
currier_step = ( intp - > srch_range [ demod ] / 1000 ) / 10 ;
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
current_step = 0 ;
direction = 1 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
tuner_freq = intp - > freq [ demod ] ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
while ( ( timing_lck = = FALSE ) & & ( current_step < nb_steps ) ) {
stv0900_write_reg ( intp , DMDISTATE , 0x5f ) ;
stv0900_write_bits ( intp , DEMOD_MODE , 0 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
msleep ( 50 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
for ( i = 0 ; i < 10 ; i + + ) {
if ( stv0900_get_bits ( intp , TMGLOCK_QUALITY ) > = 2 )
timingcpt + + ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
agc2_integr + = ( stv0900_read_reg ( intp , AGC2I1 ) < < 8 ) |
stv0900_read_reg ( intp , AGC2I0 ) ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
agc2_integr / = 10 ;
coarse_srate = stv0900_get_symbol_rate ( intp , intp - > mclk , demod ) ;
current_step + + ;
direction * = - 1 ;
dprintk ( " lock: I2C_DEMOD_MODE_FIELD =0. Search started. "
" tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d \n " ,
tuner_freq , agc2_integr , coarse_srate , timingcpt ) ;
if ( ( timingcpt > = 5 ) & &
( agc2_integr < agc2_th ) & &
( coarse_srate < 55000000 ) & &
( coarse_srate > 850000 ) )
timing_lck = TRUE ;
else if ( current_step < nb_steps ) {
if ( direction > 0 )
tuner_freq + = ( current_step * currier_step ) ;
else
tuner_freq - = ( current_step * currier_step ) ;
2009-03-03 17:55:20 +03:00
2009-12-15 02:24:56 +03:00
if ( intp - > tuner_type [ demod ] = = 3 )
stv0900_set_tuner_auto ( intp , tuner_freq ,
intp - > bw [ demod ] , demod ) ;
else
stv0900_set_tuner ( fe , tuner_freq ,
intp - > bw [ demod ] ) ;
2009-03-03 17:55:20 +03:00
}
}
2009-11-07 05:46:32 +03:00
if ( timing_lck = = FALSE )
coarse_srate = 0 ;
else
coarse_srate = stv0900_get_symbol_rate ( intp , intp - > mclk , demod ) ;
2009-03-03 17:55:20 +03:00
return coarse_srate ;
}
static u32 stv0900_search_srate_fine ( struct dvb_frontend * fe )
{
struct stv0900_state * state = fe - > demodulator_priv ;
2009-11-07 05:46:32 +03:00
struct stv0900_internal * intp = state - > internal ;
2009-03-03 17:55:20 +03:00
enum fe_stv0900_demod_num demod = state - > demod ;
2009-11-07 05:46:32 +03:00
u32 coarse_srate ,
coarse_freq ,
symb ,
symbmax ,
symbmin ,
symbcomp ;
coarse_srate = stv0900_get_symbol_rate ( intp , intp - > mclk , demod ) ;
if ( coarse_srate > 3000000 ) {
symbmax = 13 * ( coarse_srate / 10 ) ;
symbmax = ( symbmax / 1000 ) * 65536 ;
symbmax / = ( intp - > mclk / 1000 ) ;
symbmin = 10 * ( coarse_srate / 13 ) ;
symbmin = ( symbmin / 1000 ) * 65536 ;
symbmin / = ( intp - > mclk / 1000 ) ;
symb = ( coarse_srate / 1000 ) * 65536 ;
symb / = ( intp - > mclk / 1000 ) ;
} else {
symbmax = 13 * ( coarse_srate / 10 ) ;
symbmax = ( symbmax / 100 ) * 65536 ;
symbmax / = ( intp - > mclk / 100 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
symbmin = 10 * ( coarse_srate / 14 ) ;
symbmin = ( symbmin / 100 ) * 65536 ;
symbmin / = ( intp - > mclk / 100 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
symb = ( coarse_srate / 100 ) * 65536 ;
symb / = ( intp - > mclk / 100 ) ;
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
symbcomp = 13 * ( coarse_srate / 10 ) ;
coarse_freq = ( stv0900_read_reg ( intp , CFR2 ) < < 8 )
| stv0900_read_reg ( intp , CFR1 ) ;
if ( symbcomp < intp - > symbol_rate [ demod ] )
coarse_srate = 0 ;
else {
stv0900_write_reg ( intp , DMDISTATE , 0x1f ) ;
stv0900_write_reg ( intp , TMGCFG2 , 0xc1 ) ;
stv0900_write_reg ( intp , TMGTHRISE , 0x20 ) ;
stv0900_write_reg ( intp , TMGTHFALL , 0x00 ) ;
stv0900_write_reg ( intp , TMGCFG , 0xd2 ) ;
stv0900_write_bits ( intp , CFR_AUTOSCAN , 0 ) ;
stv0900_write_reg ( intp , AGC2REF , 0x38 ) ;
if ( intp - > chip_id > = 0x30 )
stv0900_write_reg ( intp , CARFREQ , 0x79 ) ;
else if ( intp - > chip_id > = 0x20 )
stv0900_write_reg ( intp , CARFREQ , 0x49 ) ;
else
stv0900_write_reg ( intp , CARFREQ , 0xed ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , SFRUP1 , ( symbmax > > 8 ) & 0x7f ) ;
stv0900_write_reg ( intp , SFRUP0 , ( symbmax & 0xff ) ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , SFRLOW1 , ( symbmin > > 8 ) & 0x7f ) ;
stv0900_write_reg ( intp , SFRLOW0 , ( symbmin & 0xff ) ) ;
stv0900_write_reg ( intp , SFRINIT1 , ( symb > > 8 ) & 0xff ) ;
stv0900_write_reg ( intp , SFRINIT0 , ( symb & 0xff ) ) ;
stv0900_write_reg ( intp , DMDT0M , 0x20 ) ;
stv0900_write_reg ( intp , CFRINIT1 , ( coarse_freq > > 8 ) & 0xff ) ;
stv0900_write_reg ( intp , CFRINIT0 , coarse_freq & 0xff ) ;
stv0900_write_reg ( intp , DMDISTATE , 0x15 ) ;
2009-03-03 17:55:20 +03:00
}
return coarse_srate ;
}
static int stv0900_blind_search_algo ( struct dvb_frontend * fe )
{
struct stv0900_state * state = fe - > demodulator_priv ;
2009-11-07 05:46:32 +03:00
struct stv0900_internal * intp = state - > internal ;
2009-03-03 17:55:20 +03:00
enum fe_stv0900_demod_num demod = state - > demod ;
2009-11-07 05:46:32 +03:00
u8 k_ref_tmg ,
k_ref_tmg_max ,
k_ref_tmg_min ;
u32 coarse_srate ,
agc2_th ;
int lock = FALSE ,
coarse_fail = FALSE ;
s32 demod_timeout = 500 ,
fec_timeout = 50 ,
fail_cpt ,
i ,
agc2_overflow ;
u16 agc2_int ;
u8 dstatus2 ;
2009-03-03 17:55:20 +03:00
2009-09-19 15:37:40 +04:00
dprintk ( " %s \n " , __func__ ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > chip_id < 0x20 ) {
2009-03-03 17:55:20 +03:00
k_ref_tmg_max = 233 ;
k_ref_tmg_min = 143 ;
} else {
2009-11-07 05:46:32 +03:00
k_ref_tmg_max = 110 ;
k_ref_tmg_min = 10 ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
if ( intp - > chip_id < = 0x20 )
agc2_th = STV0900_BLIND_SEARCH_AGC2_TH ;
else
agc2_th = STV0900_BLIND_SEARCH_AGC2_TH_CUT30 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
agc2_int = stv0900_blind_check_agc2_min_level ( intp , demod ) ;
2009-03-03 17:55:20 +03:00
2010-02-06 11:55:47 +03:00
dprintk ( " %s agc2_int=%d agc2_th=%d \n " , __func__ , agc2_int , agc2_th ) ;
if ( agc2_int > agc2_th )
2009-11-07 05:46:32 +03:00
return FALSE ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > chip_id = = 0x10 )
stv0900_write_reg ( intp , CORRELEXP , 0xaa ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > chip_id < 0x20 )
stv0900_write_reg ( intp , CARHDR , 0x55 ) ;
else
stv0900_write_reg ( intp , CARHDR , 0x20 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > chip_id < = 0x20 )
stv0900_write_reg ( intp , CARCFG , 0xc4 ) ;
else
stv0900_write_reg ( intp , CARCFG , 0x6 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , RTCS2 , 0x44 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > chip_id > = 0x20 ) {
stv0900_write_reg ( intp , EQUALCFG , 0x41 ) ;
stv0900_write_reg ( intp , FFECFG , 0x41 ) ;
stv0900_write_reg ( intp , VITSCALE , 0x82 ) ;
stv0900_write_reg ( intp , VAVSRVIT , 0x0 ) ;
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
k_ref_tmg = k_ref_tmg_max ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
do {
stv0900_write_reg ( intp , KREFTMG , k_ref_tmg ) ;
if ( stv0900_search_srate_coarse ( fe ) ! = 0 ) {
coarse_srate = stv0900_search_srate_fine ( fe ) ;
if ( coarse_srate ! = 0 ) {
stv0900_get_lock_timeout ( & demod_timeout ,
& fec_timeout ,
coarse_srate ,
STV0900_BLIND_SEARCH ) ;
lock = stv0900_get_demod_lock ( intp ,
demod ,
demod_timeout ) ;
} else
lock = FALSE ;
} else {
fail_cpt = 0 ;
agc2_overflow = 0 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
for ( i = 0 ; i < 10 ; i + + ) {
agc2_int = ( stv0900_read_reg ( intp , AGC2I1 ) < < 8 )
| stv0900_read_reg ( intp , AGC2I0 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( agc2_int > = 0xff00 )
agc2_overflow + + ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
dstatus2 = stv0900_read_reg ( intp , DSTATUS2 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( ( ( dstatus2 & 0x1 ) = = 0x1 ) & &
( ( dstatus2 > > 7 ) = = 1 ) )
fail_cpt + + ;
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( ( fail_cpt > 7 ) | | ( agc2_overflow > 7 ) )
coarse_fail = TRUE ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
lock = FALSE ;
}
k_ref_tmg - = 30 ;
} while ( ( k_ref_tmg > = k_ref_tmg_min ) & &
( lock = = FALSE ) & &
( coarse_fail = = FALSE ) ) ;
2009-03-03 17:55:20 +03:00
return lock ;
}
2009-11-07 05:46:32 +03:00
static void stv0900_set_viterbi_acq ( struct stv0900_internal * intp ,
2009-03-03 17:55:20 +03:00
enum fe_stv0900_demod_num demod )
{
2009-11-07 05:46:32 +03:00
s32 vth_reg = VTH12 ;
2009-03-03 17:55:20 +03:00
2009-09-19 15:37:40 +04:00
dprintk ( " %s \n " , __func__ ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , vth_reg + + , 0x96 ) ;
stv0900_write_reg ( intp , vth_reg + + , 0x64 ) ;
stv0900_write_reg ( intp , vth_reg + + , 0x36 ) ;
stv0900_write_reg ( intp , vth_reg + + , 0x23 ) ;
stv0900_write_reg ( intp , vth_reg + + , 0x1e ) ;
stv0900_write_reg ( intp , vth_reg + + , 0x19 ) ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
static void stv0900_set_search_standard ( struct stv0900_internal * intp ,
2009-03-03 17:55:20 +03:00
enum fe_stv0900_demod_num demod )
{
2009-09-19 15:37:40 +04:00
dprintk ( " %s \n " , __func__ ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
switch ( intp - > srch_standard [ demod ] ) {
2009-03-03 17:55:20 +03:00
case STV0900_SEARCH_DVBS1 :
dprintk ( " Search Standard = DVBS1 \n " ) ;
break ;
case STV0900_SEARCH_DSS :
dprintk ( " Search Standard = DSS \n " ) ;
break ;
2014-08-05 00:04:52 +04:00
case STV0900_SEARCH_DVBS2 :
2009-03-03 17:55:20 +03:00
dprintk ( " Search Standard = DVBS2 \n " ) ;
2014-08-05 00:04:52 +04:00
break ;
2009-03-03 17:55:20 +03:00
case STV0900_AUTO_SEARCH :
default :
dprintk ( " Search Standard = AUTO \n " ) ;
break ;
}
2009-11-07 05:46:32 +03:00
switch ( intp - > srch_standard [ demod ] ) {
case STV0900_SEARCH_DVBS1 :
case STV0900_SEARCH_DSS :
stv0900_write_bits ( intp , DVBS1_ENABLE , 1 ) ;
stv0900_write_bits ( intp , DVBS2_ENABLE , 0 ) ;
stv0900_write_bits ( intp , STOP_CLKVIT , 0 ) ;
stv0900_set_dvbs1_track_car_loop ( intp ,
demod ,
intp - > symbol_rate [ demod ] ) ;
stv0900_write_reg ( intp , CAR2CFG , 0x22 ) ;
stv0900_set_viterbi_acq ( intp , demod ) ;
stv0900_set_viterbi_standard ( intp ,
intp - > srch_standard [ demod ] ,
intp - > fec [ demod ] , demod ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
break ;
case STV0900_SEARCH_DVBS2 :
stv0900_write_bits ( intp , DVBS1_ENABLE , 0 ) ;
stv0900_write_bits ( intp , DVBS2_ENABLE , 1 ) ;
stv0900_write_bits ( intp , STOP_CLKVIT , 1 ) ;
stv0900_write_reg ( intp , ACLC , 0x1a ) ;
stv0900_write_reg ( intp , BCLC , 0x09 ) ;
if ( intp - > chip_id < = 0x20 ) /*cut 1.x and 2.0*/
stv0900_write_reg ( intp , CAR2CFG , 0x26 ) ;
else
stv0900_write_reg ( intp , CAR2CFG , 0x66 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > demod_mode ! = STV0900_SINGLE ) {
if ( intp - > chip_id < = 0x11 )
stv0900_stop_all_s2_modcod ( intp , demod ) ;
2009-03-03 17:55:20 +03:00
else
2009-11-07 05:46:32 +03:00
stv0900_activate_s2_modcod ( intp , demod ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
} else
stv0900_activate_s2_modcod_single ( intp , demod ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_set_viterbi_tracq ( intp , demod ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
break ;
case STV0900_AUTO_SEARCH :
default :
stv0900_write_bits ( intp , DVBS1_ENABLE , 1 ) ;
stv0900_write_bits ( intp , DVBS2_ENABLE , 1 ) ;
stv0900_write_bits ( intp , STOP_CLKVIT , 0 ) ;
stv0900_write_reg ( intp , ACLC , 0x1a ) ;
stv0900_write_reg ( intp , BCLC , 0x09 ) ;
stv0900_set_dvbs1_track_car_loop ( intp ,
demod ,
intp - > symbol_rate [ demod ] ) ;
if ( intp - > chip_id < = 0x20 ) /*cut 1.x and 2.0*/
stv0900_write_reg ( intp , CAR2CFG , 0x26 ) ;
else
stv0900_write_reg ( intp , CAR2CFG , 0x66 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > demod_mode ! = STV0900_SINGLE ) {
if ( intp - > chip_id < = 0x11 )
stv0900_stop_all_s2_modcod ( intp , demod ) ;
2009-03-03 17:55:20 +03:00
else
2009-11-07 05:46:32 +03:00
stv0900_activate_s2_modcod ( intp , demod ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
} else
stv0900_activate_s2_modcod_single ( intp , demod ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_set_viterbi_tracq ( intp , demod ) ;
stv0900_set_viterbi_standard ( intp ,
intp - > srch_standard [ demod ] ,
intp - > fec [ demod ] , demod ) ;
2009-03-03 17:55:20 +03:00
break ;
}
}
enum fe_stv0900_signal_type stv0900_algo ( struct dvb_frontend * fe )
{
struct stv0900_state * state = fe - > demodulator_priv ;
2009-11-07 05:46:32 +03:00
struct stv0900_internal * intp = state - > internal ;
2009-03-03 17:55:20 +03:00
enum fe_stv0900_demod_num demod = state - > demod ;
2009-11-07 05:46:32 +03:00
s32 demod_timeout = 500 , fec_timeout = 50 ;
s32 aq_power , agc1_power , i ;
2009-03-03 17:55:20 +03:00
int lock = FALSE , low_sr = FALSE ;
enum fe_stv0900_signal_type signal_type = STV0900_NOCARRIER ;
enum fe_stv0900_search_algo algo ;
int no_signal = FALSE ;
2009-09-19 15:37:40 +04:00
dprintk ( " %s \n " , __func__ ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
algo = intp - > srch_algo [ demod ] ;
stv0900_write_bits ( intp , RST_HWARE , 1 ) ;
stv0900_write_reg ( intp , DMDISTATE , 0x5c ) ;
if ( intp - > chip_id > = 0x20 ) {
if ( intp - > symbol_rate [ demod ] > 5000000 )
stv0900_write_reg ( intp , CORRELABS , 0x9e ) ;
2009-03-03 17:55:20 +03:00
else
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , CORRELABS , 0x82 ) ;
} else
stv0900_write_reg ( intp , CORRELABS , 0x88 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_get_lock_timeout ( & demod_timeout , & fec_timeout ,
intp - > symbol_rate [ demod ] ,
intp - > srch_algo [ demod ] ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > srch_algo [ demod ] = = STV0900_BLIND_SEARCH ) {
intp - > bw [ demod ] = 2 * 36000000 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , TMGCFG2 , 0xc0 ) ;
stv0900_write_reg ( intp , CORRELMANT , 0x70 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_set_symbol_rate ( intp , intp - > mclk , 1000000 , demod ) ;
} else {
stv0900_write_reg ( intp , DMDT0M , 0x20 ) ;
stv0900_write_reg ( intp , TMGCFG , 0xd2 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > symbol_rate [ demod ] < 2000000 )
stv0900_write_reg ( intp , CORRELMANT , 0x63 ) ;
2009-03-03 17:55:20 +03:00
else
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , CORRELMANT , 0x70 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , AGC2REF , 0x38 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
intp - > bw [ demod ] =
stv0900_carrier_width ( intp - > symbol_rate [ demod ] ,
intp - > rolloff ) ;
if ( intp - > chip_id > = 0x20 ) {
stv0900_write_reg ( intp , KREFTMG , 0x5a ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > srch_algo [ demod ] = = STV0900_COLD_START ) {
intp - > bw [ demod ] + = 10000000 ;
intp - > bw [ demod ] * = 15 ;
intp - > bw [ demod ] / = 10 ;
} else if ( intp - > srch_algo [ demod ] = = STV0900_WARM_START )
intp - > bw [ demod ] + = 10000000 ;
2009-03-03 17:55:20 +03:00
} else {
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , KREFTMG , 0xc1 ) ;
intp - > bw [ demod ] + = 10000000 ;
intp - > bw [ demod ] * = 15 ;
intp - > bw [ demod ] / = 10 ;
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , TMGCFG2 , 0xc1 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_set_symbol_rate ( intp , intp - > mclk ,
intp - > symbol_rate [ demod ] , demod ) ;
stv0900_set_max_symbol_rate ( intp , intp - > mclk ,
intp - > symbol_rate [ demod ] , demod ) ;
stv0900_set_min_symbol_rate ( intp , intp - > mclk ,
intp - > symbol_rate [ demod ] , demod ) ;
if ( intp - > symbol_rate [ demod ] > = 10000000 )
low_sr = FALSE ;
else
low_sr = TRUE ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
}
2009-03-03 17:55:20 +03:00
2009-12-15 02:24:56 +03:00
if ( intp - > tuner_type [ demod ] = = 3 )
stv0900_set_tuner_auto ( intp , intp - > freq [ demod ] ,
intp - > bw [ demod ] , demod ) ;
else
stv0900_set_tuner ( fe , intp - > freq [ demod ] , intp - > bw [ demod ] ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
agc1_power = MAKEWORD ( stv0900_get_bits ( intp , AGCIQ_VALUE1 ) ,
stv0900_get_bits ( intp , AGCIQ_VALUE0 ) ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
aq_power = 0 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( agc1_power = = 0 ) {
for ( i = 0 ; i < 5 ; i + + )
aq_power + = ( stv0900_get_bits ( intp , POWER_I ) +
stv0900_get_bits ( intp , POWER_Q ) ) / 2 ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
aq_power / = 5 ;
}
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( ( agc1_power = = 0 ) & & ( aq_power < IQPOWER_THRESHOLD ) ) {
intp - > result [ demod ] . locked = FALSE ;
signal_type = STV0900_NOAGC1 ;
dprintk ( " %s: NO AGC1, POWERI, POWERQ \n " , __func__ ) ;
} else {
stv0900_write_bits ( intp , SPECINV_CONTROL ,
intp - > srch_iq_inv [ demod ] ) ;
if ( intp - > chip_id < = 0x20 ) /*cut 2.0*/
stv0900_write_bits ( intp , MANUALSX_ROLLOFF , 1 ) ;
else /*cut 3.0*/
stv0900_write_bits ( intp , MANUALS2_ROLLOFF , 1 ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
stv0900_set_search_standard ( intp , demod ) ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > srch_algo [ demod ] ! = STV0900_BLIND_SEARCH )
stv0900_start_search ( intp , demod ) ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
if ( signal_type = = STV0900_NOAGC1 )
return signal_type ;
if ( intp - > chip_id = = 0x12 ) {
stv0900_write_bits ( intp , RST_HWARE , 0 ) ;
2009-03-03 17:55:20 +03:00
msleep ( 3 ) ;
2009-11-07 05:46:32 +03:00
stv0900_write_bits ( intp , RST_HWARE , 1 ) ;
stv0900_write_bits ( intp , RST_HWARE , 0 ) ;
2009-03-03 17:55:20 +03:00
}
if ( algo = = STV0900_BLIND_SEARCH )
lock = stv0900_blind_search_algo ( fe ) ;
else if ( algo = = STV0900_COLD_START )
lock = stv0900_get_demod_cold_lock ( fe , demod_timeout ) ;
else if ( algo = = STV0900_WARM_START )
2009-11-07 05:46:32 +03:00
lock = stv0900_get_demod_lock ( intp , demod , demod_timeout ) ;
2009-03-03 17:55:20 +03:00
if ( ( lock = = FALSE ) & & ( algo = = STV0900_COLD_START ) ) {
if ( low_sr = = FALSE ) {
2009-11-07 05:46:32 +03:00
if ( stv0900_check_timing_lock ( intp , demod ) = = TRUE )
lock = stv0900_sw_algo ( intp , demod ) ;
2009-03-03 17:55:20 +03:00
}
}
if ( lock = = TRUE )
signal_type = stv0900_get_signal_params ( fe ) ;
if ( ( lock = = TRUE ) & & ( signal_type = = STV0900_RANGEOK ) ) {
stv0900_track_optimization ( fe ) ;
2009-11-07 05:46:32 +03:00
if ( intp - > chip_id < = 0x11 ) {
if ( ( stv0900_get_standard ( fe , 0 ) = =
STV0900_DVBS1_STANDARD ) & &
( stv0900_get_standard ( fe , 1 ) = =
STV0900_DVBS1_STANDARD ) ) {
2009-03-03 17:55:20 +03:00
msleep ( 20 ) ;
2009-11-07 05:46:32 +03:00
stv0900_write_bits ( intp , RST_HWARE , 0 ) ;
2009-03-03 17:55:20 +03:00
} else {
2009-11-07 05:46:32 +03:00
stv0900_write_bits ( intp , RST_HWARE , 0 ) ;
2009-03-03 17:55:20 +03:00
msleep ( 3 ) ;
2009-11-07 05:46:32 +03:00
stv0900_write_bits ( intp , RST_HWARE , 1 ) ;
stv0900_write_bits ( intp , RST_HWARE , 0 ) ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
} else if ( intp - > chip_id > = 0x20 ) {
stv0900_write_bits ( intp , RST_HWARE , 0 ) ;
2009-03-03 17:55:20 +03:00
msleep ( 3 ) ;
2009-11-07 05:46:32 +03:00
stv0900_write_bits ( intp , RST_HWARE , 1 ) ;
stv0900_write_bits ( intp , RST_HWARE , 0 ) ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
if ( stv0900_wait_for_lock ( intp , demod ,
fec_timeout , fec_timeout ) = = TRUE ) {
2009-03-03 17:55:20 +03:00
lock = TRUE ;
2009-11-07 05:46:32 +03:00
intp - > result [ demod ] . locked = TRUE ;
if ( intp - > result [ demod ] . standard = =
STV0900_DVBS2_STANDARD ) {
stv0900_set_dvbs2_rolloff ( intp , demod ) ;
stv0900_write_bits ( intp , RESET_UPKO_COUNT , 1 ) ;
stv0900_write_bits ( intp , RESET_UPKO_COUNT , 0 ) ;
stv0900_write_reg ( intp , ERRCTRL1 , 0x67 ) ;
} else {
stv0900_write_reg ( intp , ERRCTRL1 , 0x75 ) ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
stv0900_write_reg ( intp , FBERCPT4 , 0 ) ;
stv0900_write_reg ( intp , ERRCTRL2 , 0xc1 ) ;
2009-03-03 17:55:20 +03:00
} else {
lock = FALSE ;
signal_type = STV0900_NODATA ;
2009-11-07 05:46:32 +03:00
no_signal = stv0900_check_signal_presence ( intp , demod ) ;
intp - > result [ demod ] . locked = FALSE ;
2009-03-03 17:55:20 +03:00
}
}
2009-11-07 05:46:32 +03:00
if ( ( signal_type ! = STV0900_NODATA ) | | ( no_signal ! = FALSE ) )
return signal_type ;
2009-03-03 17:55:20 +03:00
2009-11-07 05:46:32 +03:00
if ( intp - > chip_id > 0x11 ) {
intp - > result [ demod ] . locked = FALSE ;
return signal_type ;
2009-03-03 17:55:20 +03:00
}
2009-11-07 05:46:32 +03:00
if ( ( stv0900_get_bits ( intp , HEADER_MODE ) = = STV0900_DVBS_FOUND ) & &
( intp - > srch_iq_inv [ demod ] < = STV0900_IQ_AUTO_NORMAL_FIRST ) )
signal_type = stv0900_dvbs1_acq_workaround ( fe ) ;
2009-03-03 17:55:20 +03:00
return signal_type ;
}