| /* |
| * 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 02139, USA. |
| */ |
| |
| #include "stv0900.h" |
| #include "stv0900_reg.h" |
| #include "stv0900_priv.h" |
| |
| int stv0900_check_signal_presence(struct stv0900_internal *i_params, |
| enum fe_stv0900_demod_num demod) |
| { |
| s32 carr_offset, |
| agc2_integr, |
| max_carrier; |
| |
| int no_signal; |
| |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| carr_offset = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8) |
| | stv0900_read_reg(i_params, |
| R0900_P1_CFR1); |
| carr_offset = ge2comp(carr_offset, 16); |
| agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) |
| | stv0900_read_reg(i_params, |
| R0900_P1_AGC2I0); |
| max_carrier = i_params->dmd1_srch_range / 1000; |
| break; |
| case STV0900_DEMOD_2: |
| carr_offset = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8) |
| | stv0900_read_reg(i_params, |
| R0900_P2_CFR1); |
| carr_offset = ge2comp(carr_offset, 16); |
| agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8) |
| | stv0900_read_reg(i_params, |
| R0900_P2_AGC2I0); |
| max_carrier = i_params->dmd2_srch_range / 1000; |
| break; |
| } |
| |
| max_carrier += (max_carrier / 10); |
| max_carrier = 65536 * (max_carrier / 2); |
| max_carrier /= i_params->mclk / 1000; |
| if (max_carrier > 0x4000) |
| max_carrier = 0x4000; |
| |
| if ((agc2_integr > 0x2000) |
| || (carr_offset > + 2*max_carrier) |
| || (carr_offset < -2*max_carrier)) |
| no_signal = TRUE; |
| else |
| no_signal = FALSE; |
| |
| return no_signal; |
| } |
| |
| static void stv0900_get_sw_loop_params(struct stv0900_internal *i_params, |
| 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; |
| |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| srate = i_params->dmd1_symbol_rate; |
| max_carrier = i_params->dmd1_srch_range / 1000; |
| max_carrier += max_carrier / 10; |
| standard = i_params->dmd1_srch_standard; |
| break; |
| case STV0900_DEMOD_2: |
| srate = i_params->dmd2_symbol_rate; |
| max_carrier = i_params->dmd2_srch_range / 1000; |
| max_carrier += max_carrier / 10; |
| standard = i_params->dmd2_srch_stndrd; |
| break; |
| } |
| |
| max_carrier = 65536 * (max_carrier / 2); |
| max_carrier /= i_params->mclk / 1000; |
| |
| if (max_carrier > 0x4000) |
| max_carrier = 0x4000; |
| |
| freq_inc = srate; |
| freq_inc /= i_params->mclk >> 10; |
| 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; |
| |
| } |
| |
| static int stv0900_search_carr_sw_loop(struct stv0900_internal *i_params, |
| s32 FreqIncr, s32 Timeout, int zigzag, |
| s32 MaxStep, enum fe_stv0900_demod_num demod) |
| { |
| int no_signal, |
| lock = FALSE; |
| s32 stepCpt, |
| freqOffset, |
| max_carrier; |
| |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| max_carrier = i_params->dmd1_srch_range / 1000; |
| max_carrier += (max_carrier / 10); |
| break; |
| case STV0900_DEMOD_2: |
| max_carrier = i_params->dmd2_srch_range / 1000; |
| max_carrier += (max_carrier / 10); |
| break; |
| } |
| |
| max_carrier = 65536 * (max_carrier / 2); |
| max_carrier /= i_params->mclk / 1000; |
| |
| if (max_carrier > 0x4000) |
| max_carrier = 0x4000; |
| |
| if (zigzag == TRUE) |
| freqOffset = 0; |
| else |
| freqOffset = -max_carrier + FreqIncr; |
| |
| stepCpt = 0; |
| |
| do { |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C); |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT1, |
| (freqOffset / 256) & 0xFF); |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT0, |
| freqOffset & 0xFF); |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); |
| stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 1); |
| |
| if (i_params->chip_id == 0x12) { |
| stv0900_write_bits(i_params, |
| F0900_P1_RST_HWARE, 1); |
| stv0900_write_bits(i_params, |
| F0900_P1_RST_HWARE, 0); |
| } |
| break; |
| case STV0900_DEMOD_2: |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C); |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT1, |
| (freqOffset / 256) & 0xFF); |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT0, |
| freqOffset & 0xFF); |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); |
| stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 1); |
| |
| if (i_params->chip_id == 0x12) { |
| stv0900_write_bits(i_params, |
| F0900_P2_RST_HWARE, 1); |
| stv0900_write_bits(i_params, |
| F0900_P2_RST_HWARE, 0); |
| } |
| break; |
| } |
| |
| if (zigzag == TRUE) { |
| if (freqOffset >= 0) |
| freqOffset = -freqOffset - 2 * FreqIncr; |
| else |
| freqOffset = -freqOffset; |
| } else |
| freqOffset += + 2 * FreqIncr; |
| |
| stepCpt++; |
| lock = stv0900_get_demod_lock(i_params, demod, Timeout); |
| no_signal = stv0900_check_signal_presence(i_params, demod); |
| |
| } while ((lock == FALSE) |
| && (no_signal == FALSE) |
| && ((freqOffset - FreqIncr) < max_carrier) |
| && ((freqOffset + FreqIncr) > -max_carrier) |
| && (stepCpt < MaxStep)); |
| |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 0); |
| break; |
| case STV0900_DEMOD_2: |
| stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 0); |
| break; |
| } |
| |
| return lock; |
| } |
| |
| int stv0900_sw_algo(struct stv0900_internal *i_params, |
| enum fe_stv0900_demod_num demod) |
| { |
| int lock = FALSE; |
| |
| int no_signal, |
| zigzag; |
| s32 dvbs2_fly_wheel; |
| |
| s32 freqIncrement, softStepTimeout, trialCounter, max_steps; |
| |
| stv0900_get_sw_loop_params(i_params, &freqIncrement, &softStepTimeout, |
| &max_steps, demod); |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| switch (i_params->dmd1_srch_standard) { |
| case STV0900_SEARCH_DVBS1: |
| case STV0900_SEARCH_DSS: |
| if (i_params->chip_id >= 0x20) |
| stv0900_write_reg(i_params, R0900_P1_CARFREQ, |
| 0x3B); |
| else |
| stv0900_write_reg(i_params, R0900_P1_CARFREQ, |
| 0xef); |
| |
| stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x49); |
| zigzag = FALSE; |
| break; |
| case STV0900_SEARCH_DVBS2: |
| if (i_params->chip_id >= 0x20) |
| stv0900_write_reg(i_params, R0900_P1_CORRELABS, |
| 0x79); |
| else |
| stv0900_write_reg(i_params, R0900_P1_CORRELABS, |
| 0x68); |
| |
| stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, |
| 0x89); |
| |
| zigzag = TRUE; |
| break; |
| case STV0900_AUTO_SEARCH: |
| default: |
| if (i_params->chip_id >= 0x20) { |
| stv0900_write_reg(i_params, R0900_P1_CARFREQ, |
| 0x3B); |
| stv0900_write_reg(i_params, R0900_P1_CORRELABS, |
| 0x79); |
| } else { |
| stv0900_write_reg(i_params, R0900_P1_CARFREQ, |
| 0xef); |
| stv0900_write_reg(i_params, R0900_P1_CORRELABS, |
| 0x68); |
| } |
| |
| stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, |
| 0xc9); |
| zigzag = FALSE; |
| break; |
| } |
| |
| trialCounter = 0; |
| do { |
| lock = stv0900_search_carr_sw_loop(i_params, |
| freqIncrement, |
| softStepTimeout, |
| zigzag, |
| max_steps, |
| demod); |
| no_signal = stv0900_check_signal_presence(i_params, |
| demod); |
| trialCounter++; |
| if ((lock == TRUE) |
| || (no_signal == TRUE) |
| || (trialCounter == 2)) { |
| |
| if (i_params->chip_id >= 0x20) { |
| stv0900_write_reg(i_params, |
| R0900_P1_CARFREQ, |
| 0x49); |
| stv0900_write_reg(i_params, |
| R0900_P1_CORRELABS, |
| 0x9e); |
| } else { |
| stv0900_write_reg(i_params, |
| R0900_P1_CARFREQ, |
| 0xed); |
| stv0900_write_reg(i_params, |
| R0900_P1_CORRELABS, |
| 0x88); |
| } |
| |
| if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS2_FOUND)) { |
| msleep(softStepTimeout); |
| dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT); |
| |
| if (dvbs2_fly_wheel < 0xd) { |
| msleep(softStepTimeout); |
| dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT); |
| } |
| |
| if (dvbs2_fly_wheel < 0xd) { |
| lock = FALSE; |
| |
| if (trialCounter < 2) { |
| if (i_params->chip_id >= 0x20) |
| stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x79); |
| else |
| stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x68); |
| |
| stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x89); |
| } |
| } |
| } |
| } |
| |
| } while ((lock == FALSE) |
| && (trialCounter < 2) |
| && (no_signal == FALSE)); |
| |
| break; |
| case STV0900_DEMOD_2: |
| switch (i_params->dmd2_srch_stndrd) { |
| case STV0900_SEARCH_DVBS1: |
| case STV0900_SEARCH_DSS: |
| if (i_params->chip_id >= 0x20) |
| stv0900_write_reg(i_params, R0900_P2_CARFREQ, |
| 0x3b); |
| else |
| stv0900_write_reg(i_params, R0900_P2_CARFREQ, |
| 0xef); |
| |
| stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, |
| 0x49); |
| zigzag = FALSE; |
| break; |
| case STV0900_SEARCH_DVBS2: |
| if (i_params->chip_id >= 0x20) |
| stv0900_write_reg(i_params, R0900_P2_CORRELABS, |
| 0x79); |
| else |
| stv0900_write_reg(i_params, R0900_P2_CORRELABS, |
| 0x68); |
| |
| stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89); |
| zigzag = TRUE; |
| break; |
| case STV0900_AUTO_SEARCH: |
| default: |
| if (i_params->chip_id >= 0x20) { |
| stv0900_write_reg(i_params, R0900_P2_CARFREQ, |
| 0x3b); |
| stv0900_write_reg(i_params, R0900_P2_CORRELABS, |
| 0x79); |
| } else { |
| stv0900_write_reg(i_params, R0900_P2_CARFREQ, |
| 0xef); |
| stv0900_write_reg(i_params, R0900_P2_CORRELABS, |
| 0x68); |
| } |
| |
| stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0xc9); |
| |
| zigzag = FALSE; |
| break; |
| } |
| |
| trialCounter = 0; |
| |
| do { |
| lock = stv0900_search_carr_sw_loop(i_params, |
| freqIncrement, |
| softStepTimeout, |
| zigzag, |
| max_steps, |
| demod); |
| no_signal = stv0900_check_signal_presence(i_params, |
| demod); |
| trialCounter++; |
| if ((lock == TRUE) |
| || (no_signal == TRUE) |
| || (trialCounter == 2)) { |
| if (i_params->chip_id >= 0x20) { |
| stv0900_write_reg(i_params, |
| R0900_P2_CARFREQ, |
| 0x49); |
| stv0900_write_reg(i_params, |
| R0900_P2_CORRELABS, |
| 0x9e); |
| } else { |
| stv0900_write_reg(i_params, |
| R0900_P2_CARFREQ, |
| 0xed); |
| stv0900_write_reg(i_params, |
| R0900_P2_CORRELABS, |
| 0x88); |
| } |
| |
| if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS2_FOUND)) { |
| msleep(softStepTimeout); |
| dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT); |
| if (dvbs2_fly_wheel < 0xd) { |
| msleep(softStepTimeout); |
| dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT); |
| } |
| |
| if (dvbs2_fly_wheel < 0xd) { |
| lock = FALSE; |
| if (trialCounter < 2) { |
| if (i_params->chip_id >= 0x20) |
| stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x79); |
| else |
| stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x68); |
| |
| stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89); |
| } |
| } |
| } |
| } |
| |
| } while ((lock == FALSE) && (trialCounter < 2) && (no_signal == FALSE)); |
| |
| break; |
| } |
| |
| return lock; |
| } |
| |
| static u32 stv0900_get_symbol_rate(struct stv0900_internal *i_params, |
| u32 mclk, |
| enum fe_stv0900_demod_num demod) |
| { |
| s32 sfr_field3, sfr_field2, sfr_field1, sfr_field0, |
| rem1, rem2, intval1, intval2, srate; |
| |
| dmd_reg(sfr_field3, F0900_P1_SYMB_FREQ3, F0900_P2_SYMB_FREQ3); |
| dmd_reg(sfr_field2, F0900_P1_SYMB_FREQ2, F0900_P2_SYMB_FREQ2); |
| dmd_reg(sfr_field1, F0900_P1_SYMB_FREQ1, F0900_P2_SYMB_FREQ1); |
| dmd_reg(sfr_field0, F0900_P1_SYMB_FREQ0, F0900_P2_SYMB_FREQ0); |
| |
| srate = (stv0900_get_bits(i_params, sfr_field3) << 24) + |
| (stv0900_get_bits(i_params, sfr_field2) << 16) + |
| (stv0900_get_bits(i_params, sfr_field1) << 8) + |
| (stv0900_get_bits(i_params, sfr_field0)); |
| dprintk("lock: srate=%d r0=0x%x r1=0x%x r2=0x%x r3=0x%x \n", |
| srate, stv0900_get_bits(i_params, sfr_field0), |
| stv0900_get_bits(i_params, sfr_field1), |
| stv0900_get_bits(i_params, sfr_field2), |
| stv0900_get_bits(i_params, sfr_field3)); |
| |
| intval1 = (mclk) >> 16; |
| intval2 = (srate) >> 16; |
| |
| rem1 = (mclk) % 0x10000; |
| rem2 = (srate) % 0x10000; |
| srate = (intval1 * intval2) + |
| ((intval1 * rem2) >> 16) + |
| ((intval2 * rem1) >> 16); |
| |
| return srate; |
| } |
| |
| static void stv0900_set_symbol_rate(struct stv0900_internal *i_params, |
| u32 mclk, u32 srate, |
| enum fe_stv0900_demod_num demod) |
| { |
| s32 sfr_init_reg; |
| u32 symb; |
| |
| dprintk(KERN_INFO "%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk, |
| srate, demod); |
| |
| dmd_reg(sfr_init_reg, R0900_P1_SFRINIT1, R0900_P2_SFRINIT1); |
| |
| 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); |
| } |
| |
| stv0900_write_reg(i_params, sfr_init_reg, (symb >> 8) & 0x7F); |
| stv0900_write_reg(i_params, sfr_init_reg + 1, (symb & 0xFF)); |
| } |
| |
| static void stv0900_set_max_symbol_rate(struct stv0900_internal *i_params, |
| u32 mclk, u32 srate, |
| enum fe_stv0900_demod_num demod) |
| { |
| s32 sfr_max_reg; |
| u32 symb; |
| |
| dmd_reg(sfr_max_reg, R0900_P1_SFRUP1, R0900_P2_SFRUP1); |
| |
| 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) { |
| stv0900_write_reg(i_params, sfr_max_reg, (symb >> 8) & 0x7F); |
| stv0900_write_reg(i_params, sfr_max_reg + 1, (symb & 0xFF)); |
| } else { |
| stv0900_write_reg(i_params, sfr_max_reg, 0x7F); |
| stv0900_write_reg(i_params, sfr_max_reg + 1, 0xFF); |
| } |
| } |
| |
| static void stv0900_set_min_symbol_rate(struct stv0900_internal *i_params, |
| u32 mclk, u32 srate, |
| enum fe_stv0900_demod_num demod) |
| { |
| s32 sfr_min_reg; |
| u32 symb; |
| |
| dmd_reg(sfr_min_reg, R0900_P1_SFRLOW1, R0900_P2_SFRLOW1); |
| |
| 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); |
| } |
| |
| stv0900_write_reg(i_params, sfr_min_reg, (symb >> 8) & 0xFF); |
| stv0900_write_reg(i_params, sfr_min_reg + 1, (symb & 0xFF)); |
| } |
| |
| static s32 stv0900_get_timing_offst(struct stv0900_internal *i_params, |
| u32 srate, |
| enum fe_stv0900_demod_num demod) |
| { |
| s32 tmgreg, |
| timingoffset; |
| |
| dmd_reg(tmgreg, R0900_P1_TMGREG2, R0900_P2_TMGREG2); |
| |
| timingoffset = (stv0900_read_reg(i_params, tmgreg) << 16) + |
| (stv0900_read_reg(i_params, tmgreg + 1) << 8) + |
| (stv0900_read_reg(i_params, tmgreg + 2)); |
| |
| timingoffset = ge2comp(timingoffset, 24); |
| |
| |
| if (timingoffset == 0) |
| timingoffset = 1; |
| |
| timingoffset = ((s32)srate * 10) / ((s32)0x1000000 / timingoffset); |
| timingoffset /= 320; |
| |
| return timingoffset; |
| } |
| |
| static void stv0900_set_dvbs2_rolloff(struct stv0900_internal *i_params, |
| enum fe_stv0900_demod_num demod) |
| { |
| s32 rolloff, man_fld, matstr_reg, rolloff_ctl_fld; |
| |
| dmd_reg(man_fld, F0900_P1_MANUAL_ROLLOFF, F0900_P2_MANUAL_ROLLOFF); |
| dmd_reg(matstr_reg, R0900_P1_MATSTR1, R0900_P2_MATSTR1); |
| dmd_reg(rolloff_ctl_fld, F0900_P1_ROLLOFF_CONTROL, |
| F0900_P2_ROLLOFF_CONTROL); |
| |
| if (i_params->chip_id == 0x10) { |
| stv0900_write_bits(i_params, man_fld, 1); |
| rolloff = stv0900_read_reg(i_params, matstr_reg) & 0x03; |
| stv0900_write_bits(i_params, rolloff_ctl_fld, rolloff); |
| } else |
| stv0900_write_bits(i_params, man_fld, 0); |
| } |
| |
| 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; |
| } |
| |
| static int stv0900_check_timing_lock(struct stv0900_internal *i_params, |
| enum fe_stv0900_demod_num demod) |
| { |
| int timingLock = FALSE; |
| s32 i, |
| timingcpt = 0; |
| u8 carFreq, |
| tmgTHhigh, |
| tmgTHLow; |
| |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| carFreq = stv0900_read_reg(i_params, R0900_P1_CARFREQ); |
| tmgTHhigh = stv0900_read_reg(i_params, R0900_P1_TMGTHRISE); |
| tmgTHLow = stv0900_read_reg(i_params, R0900_P1_TMGTHFALL); |
| stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20); |
| stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x0); |
| stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); |
| stv0900_write_reg(i_params, R0900_P1_RTC, 0x80); |
| stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x40); |
| stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x0); |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0x0); |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0x0); |
| stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x65); |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); |
| msleep(7); |
| |
| for (i = 0; i < 10; i++) { |
| if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2) |
| timingcpt++; |
| |
| msleep(1); |
| } |
| |
| if (timingcpt >= 3) |
| timingLock = TRUE; |
| |
| stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38); |
| stv0900_write_reg(i_params, R0900_P1_RTC, 0x88); |
| stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x68); |
| stv0900_write_reg(i_params, R0900_P1_CARFREQ, carFreq); |
| stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, tmgTHhigh); |
| stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, tmgTHLow); |
| break; |
| case STV0900_DEMOD_2: |
| carFreq = stv0900_read_reg(i_params, R0900_P2_CARFREQ); |
| tmgTHhigh = stv0900_read_reg(i_params, R0900_P2_TMGTHRISE); |
| tmgTHLow = stv0900_read_reg(i_params, R0900_P2_TMGTHFALL); |
| stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20); |
| stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0); |
| stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); |
| stv0900_write_reg(i_params, R0900_P2_RTC, 0x80); |
| stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x40); |
| stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x0); |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0x0); |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0x0); |
| stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x65); |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); |
| msleep(5); |
| for (i = 0; i < 10; i++) { |
| if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2) |
| timingcpt++; |
| |
| msleep(1); |
| } |
| |
| if (timingcpt >= 3) |
| timingLock = TRUE; |
| |
| stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38); |
| stv0900_write_reg(i_params, R0900_P2_RTC, 0x88); |
| stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x68); |
| stv0900_write_reg(i_params, R0900_P2_CARFREQ, carFreq); |
| stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, tmgTHhigh); |
| stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, tmgTHLow); |
| break; |
| } |
| |
| return timingLock; |
| } |
| |
| static int stv0900_get_demod_cold_lock(struct dvb_frontend *fe, |
| s32 demod_timeout) |
| { |
| struct stv0900_state *state = fe->demodulator_priv; |
| struct stv0900_internal *i_params = state->internal; |
| enum fe_stv0900_demod_num demod = state->demod; |
| |
| int lock = FALSE; |
| s32 srate, search_range, locktimeout, |
| currier_step, nb_steps, current_step, |
| direction, tuner_freq, timeout; |
| |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| srate = i_params->dmd1_symbol_rate; |
| search_range = i_params->dmd1_srch_range; |
| break; |
| |
| case STV0900_DEMOD_2: |
| srate = i_params->dmd2_symbol_rate; |
| search_range = i_params->dmd2_srch_range; |
| break; |
| } |
| |
| if (srate >= 10000000) |
| locktimeout = demod_timeout / 3; |
| else |
| locktimeout = demod_timeout / 2; |
| |
| lock = stv0900_get_demod_lock(i_params, demod, locktimeout); |
| |
| if (lock == FALSE) { |
| if (srate >= 10000000) { |
| if (stv0900_check_timing_lock(i_params, demod) == TRUE) { |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f); |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15); |
| break; |
| case STV0900_DEMOD_2: |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f); |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15); |
| break; |
| } |
| |
| lock = stv0900_get_demod_lock(i_params, demod, demod_timeout); |
| } else |
| lock = FALSE; |
| } 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; |
| |
| nb_steps = ((search_range / 1000) / currier_step); |
| nb_steps /= 2; |
| nb_steps = (2 * (nb_steps + 1)); |
| if (nb_steps < 0) |
| nb_steps = 2; |
| else if (nb_steps > 12) |
| nb_steps = 12; |
| |
| current_step = 1; |
| direction = 1; |
| timeout = (demod_timeout / 3); |
| if (timeout > 1000) |
| timeout = 1000; |
| |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| if (lock == FALSE) { |
| tuner_freq = i_params->tuner1_freq; |
| i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + i_params->dmd1_symbol_rate; |
| |
| while ((current_step <= nb_steps) && (lock == FALSE)) { |
| |
| if (direction > 0) |
| tuner_freq += (current_step * currier_step); |
| else |
| tuner_freq -= (current_step * currier_step); |
| |
| stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw); |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C); |
| if (i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS2) { |
| stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0); |
| stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); |
| stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); |
| } |
| |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0); |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0); |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F); |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15); |
| lock = stv0900_get_demod_lock(i_params, demod, timeout); |
| direction *= -1; |
| current_step++; |
| } |
| } |
| break; |
| case STV0900_DEMOD_2: |
| if (lock == FALSE) { |
| tuner_freq = i_params->tuner2_freq; |
| i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + srate; |
| |
| while ((current_step <= nb_steps) && (lock == FALSE)) { |
| |
| if (direction > 0) |
| tuner_freq += (current_step * currier_step); |
| else |
| tuner_freq -= (current_step * currier_step); |
| |
| stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw); |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C); |
| if (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS2) { |
| stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0); |
| stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); |
| stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); |
| } |
| |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0); |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0); |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15); |
| lock = stv0900_get_demod_lock(i_params, demod, timeout); |
| direction *= -1; |
| current_step++; |
| } |
| } |
| break; |
| } |
| } |
| } |
| |
| 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; |
| } |
| |
| else { |
| (*demod_timeout) = 300; |
| (*fec_timeout) = 100; |
| } |
| |
| break; |
| |
| } |
| |
| if (algo == STV0900_WARM_START) |
| (*demod_timeout) /= 2; |
| } |
| |
| static void stv0900_set_viterbi_tracq(struct stv0900_internal *i_params, |
| enum fe_stv0900_demod_num demod) |
| { |
| |
| s32 vth_reg; |
| |
| dprintk(KERN_INFO "%s\n", __func__); |
| |
| dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12); |
| |
| stv0900_write_reg(i_params, vth_reg++, 0xd0); |
| stv0900_write_reg(i_params, vth_reg++, 0x7d); |
| stv0900_write_reg(i_params, vth_reg++, 0x53); |
| stv0900_write_reg(i_params, vth_reg++, 0x2F); |
| stv0900_write_reg(i_params, vth_reg++, 0x24); |
| stv0900_write_reg(i_params, vth_reg++, 0x1F); |
| } |
| |
| static void stv0900_set_viterbi_standard(struct stv0900_internal *i_params, |
| enum fe_stv0900_search_standard Standard, |
| enum fe_stv0900_fec PunctureRate, |
| enum fe_stv0900_demod_num demod) |
| { |
| |
| s32 fecmReg, |
| prvitReg; |
| |
| dprintk(KERN_INFO "%s: ViterbiStandard = ", __func__); |
| |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| fecmReg = R0900_P1_FECM; |
| prvitReg = R0900_P1_PRVIT; |
| break; |
| case STV0900_DEMOD_2: |
| fecmReg = R0900_P2_FECM; |
| prvitReg = R0900_P2_PRVIT; |
| break; |
| } |
| |
| switch (Standard) { |
| case STV0900_AUTO_SEARCH: |
| dprintk("Auto\n"); |
| stv0900_write_reg(i_params, fecmReg, 0x10); |
| stv0900_write_reg(i_params, prvitReg, 0x3F); |
| break; |
| case STV0900_SEARCH_DVBS1: |
| dprintk("DVBS1\n"); |
| stv0900_write_reg(i_params, fecmReg, 0x00); |
| switch (PunctureRate) { |
| case STV0900_FEC_UNKNOWN: |
| default: |
| stv0900_write_reg(i_params, prvitReg, 0x2F); |
| break; |
| case STV0900_FEC_1_2: |
| stv0900_write_reg(i_params, prvitReg, 0x01); |
| break; |
| case STV0900_FEC_2_3: |
| stv0900_write_reg(i_params, prvitReg, 0x02); |
| break; |
| case STV0900_FEC_3_4: |
| stv0900_write_reg(i_params, prvitReg, 0x04); |
| break; |
| case STV0900_FEC_5_6: |
| stv0900_write_reg(i_params, prvitReg, 0x08); |
| break; |
| case STV0900_FEC_7_8: |
| stv0900_write_reg(i_params, prvitReg, 0x20); |
| break; |
| } |
| |
| break; |
| case STV0900_SEARCH_DSS: |
| dprintk("DSS\n"); |
| stv0900_write_reg(i_params, fecmReg, 0x80); |
| switch (PunctureRate) { |
| case STV0900_FEC_UNKNOWN: |
| default: |
| stv0900_write_reg(i_params, prvitReg, 0x13); |
| break; |
| case STV0900_FEC_1_2: |
| stv0900_write_reg(i_params, prvitReg, 0x01); |
| break; |
| case STV0900_FEC_2_3: |
| stv0900_write_reg(i_params, prvitReg, 0x02); |
| break; |
| case STV0900_FEC_6_7: |
| stv0900_write_reg(i_params, prvitReg, 0x10); |
| break; |
| } |
| break; |
| default: |
| break; |
| } |
| } |
| |
| static void stv0900_track_optimization(struct dvb_frontend *fe) |
| { |
| struct stv0900_state *state = fe->demodulator_priv; |
| struct stv0900_internal *i_params = state->internal; |
| enum fe_stv0900_demod_num demod = state->demod; |
| |
| s32 srate, pilots, aclc, freq1, freq0, |
| i = 0, timed, timef, blindTunSw = 0; |
| |
| enum fe_stv0900_rolloff rolloff; |
| enum fe_stv0900_modcode foundModcod; |
| |
| dprintk(KERN_INFO "%s\n", __func__); |
| |
| srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); |
| srate += stv0900_get_timing_offst(i_params, srate, demod); |
| |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| switch (i_params->dmd1_rslts.standard) { |
| case STV0900_DVBS1_STANDARD: |
| if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) { |
| stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); |
| } |
| |
| stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff); |
| stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1); |
| stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75); |
| break; |
| case STV0900_DSS_STANDARD: |
| if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) { |
| stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); |
| } |
| |
| stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff); |
| stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1); |
| stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75); |
| break; |
| case STV0900_DVBS2_STANDARD: |
| stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0); |
| stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); |
| stv0900_write_reg(i_params, R0900_P1_ACLC, 0); |
| stv0900_write_reg(i_params, R0900_P1_BCLC, 0); |
| if (i_params->dmd1_rslts.frame_length == STV0900_LONG_FRAME) { |
| foundModcod = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD); |
| pilots = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01; |
| aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id); |
| if (foundModcod <= STV0900_QPSK_910) |
| stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc); |
| else if (foundModcod <= STV0900_8PSK_910) { |
| stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); |
| stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc); |
| } |
| |
| if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) { |
| if (foundModcod <= STV0900_16APSK_910) { |
| stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); |
| stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc); |
| } else if (foundModcod <= STV0900_32APSK_910) { |
| stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); |
| stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc); |
| } |
| } |
| |
| } else { |
| aclc = stv0900_get_optim_short_carr_loop(srate, i_params->dmd1_rslts.modulation, i_params->chip_id); |
| if (i_params->dmd1_rslts.modulation == STV0900_QPSK) |
| stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc); |
| |
| else if (i_params->dmd1_rslts.modulation == STV0900_8PSK) { |
| stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); |
| stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc); |
| } else if (i_params->dmd1_rslts.modulation == STV0900_16APSK) { |
| stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); |
| stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc); |
| } else if (i_params->dmd1_rslts.modulation == STV0900_32APSK) { |
| stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a); |
| stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc); |
| } |
| |
| } |
| |
| if (i_params->chip_id <= 0x11) { |
| if (i_params->demod_mode != STV0900_SINGLE) |
| stv0900_activate_s2_modcode(i_params, demod); |
| |
| } |
| |
| stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67); |
| break; |
| case STV0900_UNKNOWN_STANDARD: |
| default: |
| stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); |
| break; |
| } |
| |
| freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2); |
| freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1); |
| rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS); |
| if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) { |
| stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x00); |
| stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 0); |
| stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); |
| stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01); |
| stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod); |
| stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod); |
| stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod); |
| blindTunSw = 1; |
| } |
| |
| if (i_params->chip_id >= 0x20) { |
| if ((i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS1) || (i_params->dmd1_srch_standard == STV0900_SEARCH_DSS) || (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH)) { |
| stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0a); |
| stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x0); |
| } |
| } |
| |
| if (i_params->chip_id < 0x20) |
| stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x08); |
| |
| if (i_params->chip_id == 0x10) |
| stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0x0A); |
| |
| stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38); |
| |
| if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd1_symbol_rate < 10000000)) { |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); |
| i_params->tuner1_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000; |
| |
| if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) { |
| if (i_params->dmd1_srch_algo != STV0900_WARM_START) |
| stv0900_set_bandwidth(fe, i_params->tuner1_bw); |
| } |
| |
| if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000)) |
| msleep(50); |
| else |
| msleep(5); |
| |
| stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START); |
| |
| if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) { |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F); |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); |
| i = 0; |
| while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) { |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F); |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); |
| i++; |
| } |
| } |
| |
| } |
| |
| if (i_params->chip_id >= 0x20) |
| stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49); |
| |
| if ((i_params->dmd1_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd1_rslts.standard == STV0900_DSS_STANDARD)) |
| stv0900_set_viterbi_tracq(i_params, demod); |
| |
| break; |
| |
| case STV0900_DEMOD_2: |
| switch (i_params->dmd2_rslts.standard) { |
| case STV0900_DVBS1_STANDARD: |
| |
| if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) { |
| stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); |
| } |
| |
| stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff); |
| stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1); |
| stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75); |
| break; |
| case STV0900_DSS_STANDARD: |
| if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) { |
| stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); |
| } |
| |
| stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff); |
| stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1); |
| stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75); |
| break; |
| case STV0900_DVBS2_STANDARD: |
| stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0); |
| stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); |
| stv0900_write_reg(i_params, R0900_P2_ACLC, 0); |
| stv0900_write_reg(i_params, R0900_P2_BCLC, 0); |
| if (i_params->dmd2_rslts.frame_length == STV0900_LONG_FRAME) { |
| foundModcod = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD); |
| pilots = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01; |
| aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id); |
| if (foundModcod <= STV0900_QPSK_910) |
| stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc); |
| else if (foundModcod <= STV0900_8PSK_910) { |
| stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); |
| stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc); |
| } |
| |
| if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) { |
| if (foundModcod <= STV0900_16APSK_910) { |
| stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); |
| stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc); |
| } else if (foundModcod <= STV0900_32APSK_910) { |
| stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); |
| stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc); |
| } |
| |
| } |
| |
| } else { |
| aclc = stv0900_get_optim_short_carr_loop(srate, |
| i_params->dmd2_rslts.modulation, |
| i_params->chip_id); |
| |
| if (i_params->dmd2_rslts.modulation == STV0900_QPSK) |
| stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc); |
| |
| else if (i_params->dmd2_rslts.modulation == STV0900_8PSK) { |
| stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); |
| stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc); |
| } else if (i_params->dmd2_rslts.modulation == STV0900_16APSK) { |
| stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); |
| stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc); |
| } else if (i_params->dmd2_rslts.modulation == STV0900_32APSK) { |
| stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a); |
| stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc); |
| } |
| } |
| |
| stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67); |
| |
| break; |
| case STV0900_UNKNOWN_STANDARD: |
| default: |
| stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); |
| break; |
| } |
| |
| freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2); |
| freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1); |
| rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS); |
| if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) { |
| stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x00); |
| stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 0); |
| stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); |
| stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01); |
| stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod); |
| stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod); |
| stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod); |
| blindTunSw = 1; |
| } |
| |
| if (i_params->chip_id >= 0x20) { |
| if ((i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS1) || (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DSS) || (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH)) { |
| stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0a); |
| stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x0); |
| } |
| } |
| |
| if (i_params->chip_id < 0x20) |
| stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x08); |
| |
| if (i_params->chip_id == 0x10) |
| stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0x0a); |
| |
| stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38); |
| if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd2_symbol_rate < 10000000)) { |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); |
| i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000; |
| |
| if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) { |
| if (i_params->dmd2_srch_algo != STV0900_WARM_START) |
| stv0900_set_bandwidth(fe, i_params->tuner2_bw); |
| } |
| |
| if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000)) |
| msleep(50); |
| else |
| msleep(5); |
| |
| stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START); |
| if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) { |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); |
| i = 0; |
| while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) { |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); |
| i++; |
| } |
| } |
| } |
| |
| if (i_params->chip_id >= 0x20) |
| stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49); |
| |
| if ((i_params->dmd2_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd2_rslts.standard == STV0900_DSS_STANDARD)) |
| stv0900_set_viterbi_tracq(i_params, demod); |
| |
| break; |
| } |
| } |
| |
| static int stv0900_get_fec_lock(struct stv0900_internal *i_params, enum fe_stv0900_demod_num demod, s32 time_out) |
| { |
| s32 timer = 0, lock = 0, header_field, pktdelin_field, lock_vit_field; |
| |
| enum fe_stv0900_search_state dmd_state; |
| |
| dprintk(KERN_INFO "%s\n", __func__); |
| |
| dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); |
| dmd_reg(pktdelin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK); |
| dmd_reg(lock_vit_field, F0900_P1_LOCKEDVIT, F0900_P2_LOCKEDVIT); |
| |
| dmd_state = stv0900_get_bits(i_params, header_field); |
| |
| while ((timer < time_out) && (lock == 0)) { |
| switch (dmd_state) { |
| case STV0900_SEARCH: |
| case STV0900_PLH_DETECTED: |
| default: |
| lock = 0; |
| break; |
| case STV0900_DVBS2_FOUND: |
| lock = stv0900_get_bits(i_params, pktdelin_field); |
| break; |
| case STV0900_DVBS_FOUND: |
| lock = stv0900_get_bits(i_params, lock_vit_field); |
| break; |
| } |
| |
| if (lock == 0) { |
| msleep(10); |
| timer += 10; |
| } |
| } |
| |
| if (lock) |
| dprintk("DEMOD FEC LOCK OK\n"); |
| else |
| dprintk("DEMOD FEC LOCK FAIL\n"); |
| |
| return lock; |
| } |
| |
| static int stv0900_wait_for_lock(struct stv0900_internal *i_params, |
| enum fe_stv0900_demod_num demod, |
| s32 dmd_timeout, s32 fec_timeout) |
| { |
| |
| s32 timer = 0, lock = 0, str_merg_rst_fld, str_merg_lock_fld; |
| |
| dprintk(KERN_INFO "%s\n", __func__); |
| |
| dmd_reg(str_merg_rst_fld, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE); |
| dmd_reg(str_merg_lock_fld, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK); |
| |
| lock = stv0900_get_demod_lock(i_params, demod, dmd_timeout); |
| |
| if (lock) |
| lock = lock && stv0900_get_fec_lock(i_params, demod, fec_timeout); |
| |
| if (lock) { |
| lock = 0; |
| |
| dprintk(KERN_INFO "%s: Timer = %d, time_out = %d\n", __func__, timer, fec_timeout); |
| |
| while ((timer < fec_timeout) && (lock == 0)) { |
| lock = stv0900_get_bits(i_params, str_merg_lock_fld); |
| msleep(1); |
| timer++; |
| } |
| } |
| |
| if (lock) |
| dprintk(KERN_INFO "%s: DEMOD LOCK OK\n", __func__); |
| else |
| dprintk(KERN_INFO "%s: DEMOD LOCK FAIL\n", __func__); |
| |
| 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; |
| struct stv0900_internal *i_params = state->internal; |
| enum fe_stv0900_tracking_standard fnd_standard; |
| s32 state_field, |
| dss_dvb_field; |
| |
| dprintk(KERN_INFO "%s\n", __func__); |
| |
| dmd_reg(state_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE); |
| dmd_reg(dss_dvb_field, F0900_P1_DSS_DVB, F0900_P2_DSS_DVB); |
| |
| if (stv0900_get_bits(i_params, state_field) == 2) |
| fnd_standard = STV0900_DVBS2_STANDARD; |
| |
| else if (stv0900_get_bits(i_params, state_field) == 3) { |
| if (stv0900_get_bits(i_params, dss_dvb_field) == 1) |
| fnd_standard = STV0900_DSS_STANDARD; |
| else |
| fnd_standard = STV0900_DVBS1_STANDARD; |
| } else |
| fnd_standard = STV0900_UNKNOWN_STANDARD; |
| |
| return fnd_standard; |
| } |
| |
| static s32 stv0900_get_carr_freq(struct stv0900_internal *i_params, u32 mclk, |
| enum fe_stv0900_demod_num demod) |
| { |
| s32 cfr_field2, cfr_field1, cfr_field0, |
| derot, rem1, rem2, intval1, intval2; |
| |
| dmd_reg(cfr_field2, F0900_P1_CAR_FREQ2, F0900_P2_CAR_FREQ2); |
| dmd_reg(cfr_field1, F0900_P1_CAR_FREQ1, F0900_P2_CAR_FREQ1); |
| dmd_reg(cfr_field0, F0900_P1_CAR_FREQ0, F0900_P2_CAR_FREQ0); |
| |
| derot = (stv0900_get_bits(i_params, cfr_field2) << 16) + |
| (stv0900_get_bits(i_params, cfr_field1) << 8) + |
| (stv0900_get_bits(i_params, cfr_field0)); |
| |
| 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; |
| u32 frequency = 0; |
| |
| if (&fe->ops) |
| frontend_ops = &fe->ops; |
| |
| if (&frontend_ops->tuner_ops) |
| tuner_ops = &frontend_ops->tuner_ops; |
| |
| if (tuner_ops->get_frequency) { |
| if ((tuner_ops->get_frequency(fe, &frequency)) < 0) |
| dprintk("%s: Invalid parameter\n", __func__); |
| else |
| dprintk("%s: Frequency=%d\n", __func__, frequency); |
| |
| } |
| |
| return frequency; |
| } |
| |
| static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *i_params, |
| enum fe_stv0900_demod_num demod) |
| { |
| s32 rate_fld, vit_curpun_fld; |
| enum fe_stv0900_fec prate; |
| |
| dmd_reg(vit_curpun_fld, F0900_P1_VIT_CURPUN, F0900_P2_VIT_CURPUN); |
| rate_fld = stv0900_get_bits(i_params, vit_curpun_fld); |
| |
| 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; |
| } |
| |
| static enum fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe) |
| { |
| struct stv0900_state *state = fe->demodulator_priv; |
| struct stv0900_internal *i_params = state->internal; |
| enum fe_stv0900_demod_num demod = state->demod; |
| enum fe_stv0900_signal_type range = STV0900_OUTOFRANGE; |
| s32 offsetFreq, |
| srate_offset, |
| i = 0; |
| |
| u8 timing; |
| |
| msleep(5); |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) { |
| timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2); |
| i = 0; |
| stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x5c); |
| |
| while ((i <= 50) && (timing != 0) && (timing != 0xFF)) { |
| timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2); |
| msleep(5); |
| i += 5; |
| } |
| } |
| |
| i_params->dmd1_rslts.standard = stv0900_get_standard(fe, demod); |
| i_params->dmd1_rslts.frequency = stv0900_get_tuner_freq(fe); |
| offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000; |
| i_params->dmd1_rslts.frequency += offsetFreq; |
| i_params->dmd1_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); |
| srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd1_rslts.symbol_rate, demod); |
| i_params->dmd1_rslts.symbol_rate += srate_offset; |
| i_params->dmd1_rslts.fec = stv0900_get_vit_fec(i_params, demod); |
| i_params->dmd1_rslts.modcode = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD); |
| i_params->dmd1_rslts.pilot = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01; |
| i_params->dmd1_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE)) >> 1; |
| i_params->dmd1_rslts.rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS); |
| switch (i_params->dmd1_rslts.standard) { |
| case STV0900_DVBS2_STANDARD: |
| i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_SPECINV_DEMOD); |
| if (i_params->dmd1_rslts.modcode <= STV0900_QPSK_910) |
| i_params->dmd1_rslts.modulation = STV0900_QPSK; |
| else if (i_params->dmd1_rslts.modcode <= STV0900_8PSK_910) |
| i_params->dmd1_rslts.modulation = STV0900_8PSK; |
| else if (i_params->dmd1_rslts.modcode <= STV0900_16APSK_910) |
| i_params->dmd1_rslts.modulation = STV0900_16APSK; |
| else if (i_params->dmd1_rslts.modcode <= STV0900_32APSK_910) |
| i_params->dmd1_rslts.modulation = STV0900_32APSK; |
| else |
| i_params->dmd1_rslts.modulation = STV0900_UNKNOWN; |
| break; |
| case STV0900_DVBS1_STANDARD: |
| case STV0900_DSS_STANDARD: |
| i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_IQINV); |
| i_params->dmd1_rslts.modulation = STV0900_QPSK; |
| break; |
| default: |
| break; |
| } |
| |
| if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000)) { |
| offsetFreq = i_params->dmd1_rslts.frequency - i_params->tuner1_freq; |
| i_params->tuner1_freq = stv0900_get_tuner_freq(fe); |
| if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500)) |
| range = STV0900_RANGEOK; |
| else |
| if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd1_rslts.symbol_rate, i_params->dmd1_rslts.rolloff) / 2000)) |
| range = STV0900_RANGEOK; |
| else |
| range = STV0900_OUTOFRANGE; |
| |
| } else { |
| if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500)) |
| range = STV0900_RANGEOK; |
| else |
| range = STV0900_OUTOFRANGE; |
| } |
| break; |
| case STV0900_DEMOD_2: |
| if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) { |
| timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2); |
| i = 0; |
| stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x5c); |
| |
| while ((i <= 50) && (timing != 0) && (timing != 0xff)) { |
| timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2); |
| msleep(5); |
| i += 5; |
| } |
| } |
| |
| i_params->dmd2_rslts.standard = stv0900_get_standard(fe, demod); |
| i_params->dmd2_rslts.frequency = stv0900_get_tuner_freq(fe); |
| offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000; |
| i_params->dmd2_rslts.frequency += offsetFreq; |
| i_params->dmd2_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); |
| srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd2_rslts.symbol_rate, demod); |
| i_params->dmd2_rslts.symbol_rate += srate_offset; |
| i_params->dmd2_rslts.fec = stv0900_get_vit_fec(i_params, demod); |
| i_params->dmd2_rslts.modcode = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD); |
| i_params->dmd2_rslts.pilot = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01; |
| i_params->dmd2_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE)) >> 1; |
| i_params->dmd2_rslts.rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS); |
| switch (i_params->dmd2_rslts.standard) { |
| case STV0900_DVBS2_STANDARD: |
| i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_SPECINV_DEMOD); |
| if (i_params->dmd2_rslts.modcode <= STV0900_QPSK_910) |
| i_params->dmd2_rslts.modulation = STV0900_QPSK; |
| else if (i_params->dmd2_rslts.modcode <= STV0900_8PSK_910) |
| i_params->dmd2_rslts.modulation = STV0900_8PSK; |
| else if (i_params->dmd2_rslts.modcode <= STV0900_16APSK_910) |
| i_params->dmd2_rslts.modulation = STV0900_16APSK; |
| else if (i_params->dmd2_rslts.modcode <= STV0900_32APSK_910) |
| i_params->dmd2_rslts.modulation = STV0900_32APSK; |
| else |
| i_params->dmd2_rslts.modulation = STV0900_UNKNOWN; |
| break; |
| case STV0900_DVBS1_STANDARD: |
| case STV0900_DSS_STANDARD: |
| i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_IQINV); |
| i_params->dmd2_rslts.modulation = STV0900_QPSK; |
| break; |
| default: |
| break; |
| } |
| |
| if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000)) { |
| offsetFreq = i_params->dmd2_rslts.frequency - i_params->tuner2_freq; |
| i_params->tuner2_freq = stv0900_get_tuner_freq(fe); |
| |
| if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500)) |
| range = STV0900_RANGEOK; |
| else |
| if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd2_rslts.symbol_rate, i_params->dmd2_rslts.rolloff) / 2000)) |
| range = STV0900_RANGEOK; |
| else |
| range = STV0900_OUTOFRANGE; |
| } else { |
| if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500)) |
| range = STV0900_RANGEOK; |
| else |
| range = STV0900_OUTOFRANGE; |
| } |
| |
| break; |
| } |
| |
| return range; |
| } |
| |
| static enum fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_frontend *fe) |
| { |
| struct stv0900_state *state = fe->demodulator_priv; |
| struct stv0900_internal *i_params = state->internal; |
| enum fe_stv0900_demod_num demod = state->demod; |
| |
| s32 srate, demod_timeout, |
| fec_timeout, freq1, freq0; |
| enum fe_stv0900_signal_type signal_type = STV0900_NODATA;; |
| |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| i_params->dmd1_rslts.locked = FALSE; |
| if (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) { |
| srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); |
| srate += stv0900_get_timing_offst(i_params, srate, demod); |
| if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) |
| stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod); |
| |
| stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START); |
| freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2); |
| freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1); |
| stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); |
| stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED); |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C); |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); |
| if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) { |
| i_params->dmd1_rslts.locked = TRUE; |
| signal_type = stv0900_get_signal_params(fe); |
| stv0900_track_optimization(fe); |
| } else { |
| stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL); |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1c); |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1); |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0); |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18); |
| if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) { |
| i_params->dmd1_rslts.locked = TRUE; |
| signal_type = stv0900_get_signal_params(fe); |
| stv0900_track_optimization(fe); |
| } |
| |
| } |
| |
| } else |
| i_params->dmd1_rslts.locked = FALSE; |
| |
| break; |
| case STV0900_DEMOD_2: |
| i_params->dmd2_rslts.locked = FALSE; |
| if (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) { |
| srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); |
| srate += stv0900_get_timing_offst(i_params, srate, demod); |
| |
| if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) |
| stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod); |
| |
| stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START); |
| freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2); |
| freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1); |
| stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); |
| stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED); |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C); |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); |
| |
| if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) { |
| i_params->dmd2_rslts.locked = TRUE; |
| signal_type = stv0900_get_signal_params(fe); |
| stv0900_track_optimization(fe); |
| } else { |
| stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL); |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1c); |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1); |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0); |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18); |
| |
| if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) { |
| i_params->dmd2_rslts.locked = TRUE; |
| signal_type = stv0900_get_signal_params(fe); |
| stv0900_track_optimization(fe); |
| } |
| |
| } |
| |
| } else |
| i_params->dmd1_rslts.locked = FALSE; |
| |
| break; |
| } |
| |
| return signal_type; |
| } |
| |
| static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *i_params, |
| enum fe_stv0900_demod_num demod) |
| { |
| u32 minagc2level = 0xffff, |
| agc2level, |
| init_freq, freq_step; |
| |
| s32 i, j, nb_steps, direction; |
| |
| dprintk(KERN_INFO "%s\n", __func__); |
| |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38); |
| stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1); |
| |
| stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83); |
| stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0); |
| |
| stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82); |
| stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0); |
| stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0); |
| |
| stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod); |
| nb_steps = -1 + (i_params->dmd1_srch_range / 1000000); |
| nb_steps /= 2; |
| nb_steps = (2 * nb_steps) + 1; |
| |
| if (nb_steps < 0) |
| nb_steps = 1; |
| |
| direction = 1; |
| |
| freq_step = (1000000 << 8) / (i_params->mclk >> 8); |
| |
| init_freq = 0; |
| |
| 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); |
| |
| direction *= -1; |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C); |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (init_freq >> 8) & 0xff); |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT0, init_freq & 0xff); |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x58); |
| msleep(10); |
| agc2level = 0; |
| |
| for (j = 0; j < 10; j++) |
| agc2level += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) |
| | stv0900_read_reg(i_params, R0900_P1_AGC2I0); |
| |
| agc2level /= 10; |
| |
| if (agc2level < minagc2level) |
| minagc2level = agc2level; |
| } |
| break; |
| case STV0900_DEMOD_2: |
| stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38); |
| stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1); |
| stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83); |
| stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0); |
| stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82); |
| stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0); |
| stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0); |
| stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod); |
| nb_steps = -1 + (i_params->dmd2_srch_range / 1000000); |
| nb_steps /= 2; |
| nb_steps = (2 * nb_steps) + 1; |
| |
| if (nb_steps < 0) |
| nb_steps = 1; |
| |
| direction = 1; |
| freq_step = (1000000 << 8) / (i_params->mclk >> 8); |
| init_freq = 0; |
| 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); |
| |
| direction *= -1; |
| |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C); |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (init_freq >> 8) & 0xff); |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT0, init_freq & 0xff); |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x58); |
| |
| msleep(10); |
| agc2level = 0; |
| for (j = 0; j < 10; j++) |
| agc2level += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8) |
| | stv0900_read_reg(i_params, R0900_P2_AGC2I0); |
| |
| agc2level /= 10; |
| |
| if (agc2level < minagc2level) |
| minagc2level = agc2level; |
| } |
| break; |
| } |
| |
| return (u16)minagc2level; |
| } |
| |
| static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe) |
| { |
| struct stv0900_state *state = fe->demodulator_priv; |
| struct stv0900_internal *i_params = state->internal; |
| enum fe_stv0900_demod_num demod = state->demod; |
| int timingLock = FALSE; |
| s32 i, timingcpt = 0, |
| direction = 1, |
| nb_steps, |
| current_step = 0, |
| tuner_freq; |
| |
| u32 coarse_srate = 0, agc2_integr = 0, currier_step = 1200; |
| |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x1F); |
| stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0x12); |
| stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0xf0); |
| stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0xe0); |
| stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1); |
| stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83); |
| stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0); |
| stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82); |
| stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0); |
| stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0); |
| stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x50); |
| |
| if (i_params->chip_id >= 0x20) { |
| stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x6a); |
| stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x95); |
| } else { |
| stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed); |
| stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x73); |
| } |
| |
| if (i_params->dmd1_symbol_rate <= 2000000) |
| currier_step = 1000; |
| else if (i_params->dmd1_symbol_rate <= 5000000) |
| currier_step = 2000; |
| else if (i_params->dmd1_symbol_rate <= 12000000) |
| currier_step = 3000; |
| else |
| currier_step = 5000; |
| |
| nb_steps = -1 + ((i_params->dmd1_srch_range / 1000) / currier_step); |
| nb_steps /= 2; |
| nb_steps = (2 * nb_steps) + 1; |
| |
| if (nb_steps < 0) |
| nb_steps = 1; |
| |
| else if (nb_steps > 10) { |
| nb_steps = 11; |
| currier_step = (i_params->dmd1_srch_range / 1000) / 10; |
| } |
| |
| current_step = 0; |
| |
| direction = 1; |
| tuner_freq = i_params->tuner1_freq; |
| |
| while ((timingLock == FALSE) && (current_step < nb_steps)) { |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5F); |
| stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x0); |
| |
| msleep(50); |
| |
| for (i = 0; i < 10; i++) { |
| if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2) |
| timingcpt++; |
| |
| agc2_integr += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) | stv0900_read_reg(i_params, R0900_P1_AGC2I0); |
| |
| } |
| |
| agc2_integr /= 10; |
| coarse_srate = stv0900_get_symbol_rate(i_params, i_params->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 < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000)) { |
| timingLock = TRUE; |
| } |
| |
| else if (current_step < nb_steps) { |
| if (direction > 0) |
| tuner_freq += (current_step * currier_step); |
| else |
| tuner_freq -= (current_step * currier_step); |
| |
| stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw); |
| } |
| } |
| |
| if (timingLock == FALSE) |
| coarse_srate = 0; |
| else |
| coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); |
| break; |
| case STV0900_DEMOD_2: |
| stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x1F); |
| stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0x12); |
| stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0xf0); |
| stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0xe0); |
| stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1); |
| stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83); |
| stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0); |
| stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82); |
| stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0); |
| stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0); |
| stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x50); |
| |
| if (i_params->chip_id >= 0x20) { |
| stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x6a); |
| stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x95); |
| } else { |
| stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed); |
| stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x73); |
| } |
| |
| if (i_params->dmd2_symbol_rate <= 2000000) |
| currier_step = 1000; |
| else if (i_params->dmd2_symbol_rate <= 5000000) |
| currier_step = 2000; |
| else if (i_params->dmd2_symbol_rate <= 12000000) |
| currier_step = 3000; |
| else |
| currier_step = 5000; |
| |
| |
| nb_steps = -1 + ((i_params->dmd2_srch_range / 1000) / currier_step); |
| nb_steps /= 2; |
| nb_steps = (2 * nb_steps) + 1; |
| |
| if (nb_steps < 0) |
| nb_steps = 1; |
| else if (nb_steps > 10) { |
| nb_steps = 11; |
| currier_step = (i_params->dmd2_srch_range / 1000) / 10; |
| } |
| |
| current_step = 0; |
| direction = 1; |
| tuner_freq = i_params->tuner2_freq; |
| |
| while ((timingLock == FALSE) && (current_step < nb_steps)) { |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5F); |
| stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x0); |
| |
| msleep(50); |
| timingcpt = 0; |
| |
| for (i = 0; i < 20; i++) { |
| if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2) |
| timingcpt++; |
| agc2_integr += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8) |
| | stv0900_read_reg(i_params, R0900_P2_AGC2I0); |
| } |
| |
| agc2_integr /= 20; |
| coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); |
| if ((timingcpt >= 10) && (agc2_integr < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000)) |
| timingLock = TRUE; |
| else { |
| current_step++; |
| direction *= -1; |
| |
| if (direction > 0) |
| tuner_freq += (current_step * currier_step); |
| else |
| tuner_freq -= (current_step * currier_step); |
| |
| stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw); |
| } |
| } |
| |
| if (timingLock == FALSE) |
| coarse_srate = 0; |
| else |
| coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); |
| break; |
| } |
| |
| return coarse_srate; |
| } |
| |
| static u32 stv0900_search_srate_fine(struct dvb_frontend *fe) |
| { |
| struct stv0900_state *state = fe->demodulator_priv; |
| struct stv0900_internal *i_params = state->internal; |
| enum fe_stv0900_demod_num demod = state->demod; |
| u32 coarse_srate, |
| coarse_freq, |
| symb; |
| |
| coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod); |
| |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| coarse_freq = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8) |
| | stv0900_read_reg(i_params, R0900_P1_CFR1); |
| symb = 13 * (coarse_srate / 10); |
| |
| if (symb < i_params->dmd1_symbol_rate) |
| coarse_srate = 0; |
| else { |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F); |
| stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01); |
| stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20); |
| stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x00); |
| stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2); |
| stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0); |
| |
| if (i_params->chip_id >= 0x20) |
| stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49); |
| else |
| stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed); |
| |
| if (coarse_srate > 3000000) { |
| symb = 13 * (coarse_srate / 10); |
| symb = (symb / 1000) * 65536; |
| symb /= (i_params->mclk / 1000); |
| stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F); |
| stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF)); |
| |
| symb = 10 * (coarse_srate / 13); |
| symb = (symb / 1000) * 65536; |
| symb /= (i_params->mclk / 1000); |
| |
| stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F); |
| stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF)); |
| |
| symb = (coarse_srate / 1000) * 65536; |
| symb /= (i_params->mclk / 1000); |
| stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF); |
| stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF)); |
| } else { |
| symb = 13 * (coarse_srate / 10); |
| symb = (symb / 100) * 65536; |
| symb /= (i_params->mclk / 100); |
| stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F); |
| stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF)); |
| |
| symb = 10 * (coarse_srate / 14); |
| symb = (symb / 100) * 65536; |
| symb /= (i_params->mclk / 100); |
| stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F); |
| stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF)); |
| |
| symb = (coarse_srate / 100) * 65536; |
| symb /= (i_params->mclk / 100); |
| stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF); |
| stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF)); |
| } |
| |
| stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20); |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (coarse_freq >> 8) & 0xff); |
| stv0900_write_reg(i_params, R0900_P1_CFRINIT0, coarse_freq & 0xff); |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15); |
| } |
| break; |
| case STV0900_DEMOD_2: |
| coarse_freq = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8) |
| | stv0900_read_reg(i_params, R0900_P2_CFR1); |
| |
| symb = 13 * (coarse_srate / 10); |
| |
| if (symb < i_params->dmd2_symbol_rate) |
| coarse_srate = 0; |
| else { |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F); |
| stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01); |
| stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20); |
| stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0x00); |
| stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2); |
| stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0); |
| |
| if (i_params->chip_id >= 0x20) |
| stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49); |
| else |
| stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed); |
| |
| if (coarse_srate > 3000000) { |
| symb = 13 * (coarse_srate / 10); |
| symb = (symb / 1000) * 65536; |
| symb /= (i_params->mclk / 1000); |
| stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F); |
| stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF)); |
| |
| symb = 10 * (coarse_srate / 13); |
| symb = (symb / 1000) * 65536; |
| symb /= (i_params->mclk / 1000); |
| |
| stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F); |
| stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF)); |
| |
| symb = (coarse_srate / 1000) * 65536; |
| symb /= (i_params->mclk / 1000); |
| stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF); |
| stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF)); |
| } else { |
| symb = 13 * (coarse_srate / 10); |
| symb = (symb / 100) * 65536; |
| symb /= (i_params->mclk / 100); |
| stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F); |
| stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF)); |
| |
| symb = 10 * (coarse_srate / 14); |
| symb = (symb / 100) * 65536; |
| symb /= (i_params->mclk / 100); |
| stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F); |
| stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF)); |
| |
| symb = (coarse_srate / 100) * 65536; |
| symb /= (i_params->mclk / 100); |
| stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF); |
| stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF)); |
| } |
| |
| stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20); |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (coarse_freq >> 8) & 0xff); |
| stv0900_write_reg(i_params, R0900_P2_CFRINIT0, coarse_freq & 0xff); |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15); |
| } |
| |
| break; |
| } |
| |
| return coarse_srate; |
| } |
| |
| static int stv0900_blind_search_algo(struct dvb_frontend *fe) |
| { |
| struct stv0900_state *state = fe->demodulator_priv; |
| struct stv0900_internal *i_params = state->internal; |
| enum fe_stv0900_demod_num demod = state->demod; |
| u8 k_ref_tmg, k_ref_tmg_max, k_ref_tmg_min; |
| u32 coarse_srate; |
| int lock = FALSE, coarse_fail = FALSE; |
| s32 demod_timeout = 500, fec_timeout = 50, kref_tmg_reg, fail_cpt, i, agc2_overflow; |
| u16 agc2_integr; |
| u8 dstatus2; |
| |
| dprintk(KERN_INFO "%s\n", __func__); |
| |
| if (i_params->chip_id < 0x20) { |
| k_ref_tmg_max = 233; |
| k_ref_tmg_min = 143; |
| } else { |
| k_ref_tmg_max = 120; |
| k_ref_tmg_min = 30; |
| } |
| |
| agc2_integr = stv0900_blind_check_agc2_min_level(i_params, demod); |
| |
| if (agc2_integr > STV0900_BLIND_SEARCH_AGC2_TH) { |
| lock = FALSE; |
| |
| } else { |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| if (i_params->chip_id == 0x10) |
| stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0xAA); |
| |
| if (i_params->chip_id < 0x20) |
| stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x55); |
| |
| stv0900_write_reg(i_params, R0900_P1_CARCFG, 0xC4); |
| stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x44); |
| |
| if (i_params->chip_id >= 0x20) { |
| stv0900_write_reg(i_params, R0900_P1_EQUALCFG, 0x41); |
| stv0900_write_reg(i_params, R0900_P1_FFECFG, 0x41); |
| stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x82); |
| stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0); |
| } |
| |
| kref_tmg_reg = R0900_P1_KREFTMG; |
| break; |
| case STV0900_DEMOD_2: |
| if (i_params->chip_id == 0x10) |
| stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0xAA); |
| |
| if (i_params->chip_id < 0x20) |
| stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55); |
| |
| stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xC4); |
| stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44); |
| |
| if (i_params->chip_id >= 0x20) { |
| stv0900_write_reg(i_params, R0900_P2_EQUALCFG, 0x41); |
| stv0900_write_reg(i_params, R0900_P2_FFECFG, 0x41); |
| stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x82); |
| stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0); |
| } |
| |
| kref_tmg_reg = R0900_P2_KREFTMG; |
| break; |
| } |
| |
| k_ref_tmg = k_ref_tmg_max; |
| |
| do { |
| stv0900_write_reg(i_params, kref_tmg_reg, 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(i_params, demod, demod_timeout); |
| } else |
| lock = FALSE; |
| } else { |
| fail_cpt = 0; |
| agc2_overflow = 0; |
| |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| for (i = 0; i < 10; i++) { |
| agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) |
| | stv0900_read_reg(i_params, R0900_P1_AGC2I0); |
| |
| if (agc2_integr >= 0xff00) |
| agc2_overflow++; |
| |
| dstatus2 = stv0900_read_reg(i_params, R0900_P1_DSTATUS2); |
| |
| if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1)) |
| fail_cpt++; |
| } |
| break; |
| case STV0900_DEMOD_2: |
| for (i = 0; i < 10; i++) { |
| agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8) |
| | stv0900_read_reg(i_params, R0900_P2_AGC2I0); |
| |
| if (agc2_integr >= 0xff00) |
| agc2_overflow++; |
| |
| dstatus2 = stv0900_read_reg(i_params, R0900_P2_DSTATUS2); |
| |
| if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1)) |
| fail_cpt++; |
| } |
| break; |
| } |
| |
| if ((fail_cpt > 7) || (agc2_overflow > 7)) |
| coarse_fail = TRUE; |
| |
| lock = FALSE; |
| } |
| k_ref_tmg -= 30; |
| } while ((k_ref_tmg >= k_ref_tmg_min) && (lock == FALSE) && (coarse_fail == FALSE)); |
| } |
| |
| return lock; |
| } |
| |
| static void stv0900_set_viterbi_acq(struct stv0900_internal *i_params, |
| enum fe_stv0900_demod_num demod) |
| { |
| s32 vth_reg; |
| |
| dprintk(KERN_INFO "%s\n", __func__); |
| |
| dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12); |
| |
| stv0900_write_reg(i_params, vth_reg++, 0x96); |
| stv0900_write_reg(i_params, vth_reg++, 0x64); |
| stv0900_write_reg(i_params, vth_reg++, 0x36); |
| stv0900_write_reg(i_params, vth_reg++, 0x23); |
| stv0900_write_reg(i_params, vth_reg++, 0x1E); |
| stv0900_write_reg(i_params, vth_reg++, 0x19); |
| } |
| |
| static void stv0900_set_search_standard(struct stv0900_internal *i_params, |
| enum fe_stv0900_demod_num demod) |
| { |
| |
| int sstndrd; |
| |
| dprintk(KERN_INFO "%s\n", __func__); |
| |
| sstndrd = i_params->dmd1_srch_standard; |
| if (demod == 1) |
| sstndrd = i_params->dmd2_srch_stndrd; |
| |
| switch (sstndrd) { |
| case STV0900_SEARCH_DVBS1: |
| dprintk("Search Standard = DVBS1\n"); |
| break; |
| case STV0900_SEARCH_DSS: |
| dprintk("Search Standard = DSS\n"); |
| case STV0900_SEARCH_DVBS2: |
| break; |
| dprintk("Search Standard = DVBS2\n"); |
| case STV0900_AUTO_SEARCH: |
| default: |
| dprintk("Search Standard = AUTO\n"); |
| break; |
| } |
| |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| switch (i_params->dmd1_srch_standard) { |
| case STV0900_SEARCH_DVBS1: |
| case STV0900_SEARCH_DSS: |
| stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); |
| |
| stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0); |
| stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a); |
| stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09); |
| stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x22); |
| |
| stv0900_set_viterbi_acq(i_params, demod); |
| stv0900_set_viterbi_standard(i_params, |
| i_params->dmd1_srch_standard, |
| i_params->dmd1_fec, demod); |
| |
| break; |
| case STV0900_SEARCH_DVBS2: |
| stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0); |
| stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); |
| stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 1); |
| stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a); |
| stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09); |
| stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26); |
| if (i_params->demod_mode != STV0900_SINGLE) { |
| if (i_params->chip_id <= 0x11) |
| stv0900_stop_all_s2_modcod(i_params, demod); |
| else |
| stv0900_activate_s2_modcode(i_params, demod); |
| |
| } else |
| stv0900_activate_s2_modcode_single(i_params, demod); |
| |
| stv0900_set_viterbi_tracq(i_params, demod); |
| |
| break; |
| case STV0900_AUTO_SEARCH: |
| default: |
| stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0); |
| stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0); |
| stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0); |
| stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a); |
| stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09); |
| stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26); |
| if (i_params->demod_mode != STV0900_SINGLE) { |
| if (i_params->chip_id <= 0x11) |
| stv0900_stop_all_s2_modcod(i_params, demod); |
| else |
| stv0900_activate_s2_modcode(i_params, demod); |
| |
| } else |
| stv0900_activate_s2_modcode_single(i_params, demod); |
| |
| if (i_params->dmd1_symbol_rate >= 2000000) |
| stv0900_set_viterbi_acq(i_params, demod); |
| else |
| stv0900_set_viterbi_tracq(i_params, demod); |
| |
| stv0900_set_viterbi_standard(i_params, i_params->dmd1_srch_standard, i_params->dmd1_fec, demod); |
| |
| break; |
| } |
| break; |
| case STV0900_DEMOD_2: |
| switch (i_params->dmd2_srch_stndrd) { |
| case STV0900_SEARCH_DVBS1: |
| case STV0900_SEARCH_DSS: |
| stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); |
| stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0); |
| stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a); |
| stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09); |
| stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x22); |
| stv0900_set_viterbi_acq(i_params, demod); |
| stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod); |
| break; |
| case STV0900_SEARCH_DVBS2: |
| stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0); |
| stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); |
| stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 1); |
| stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a); |
| stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09); |
| stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26); |
| if (i_params->demod_mode != STV0900_SINGLE) |
| stv0900_activate_s2_modcode(i_params, demod); |
| else |
| stv0900_activate_s2_modcode_single(i_params, demod); |
| |
| stv0900_set_viterbi_tracq(i_params, demod); |
| break; |
| case STV0900_AUTO_SEARCH: |
| default: |
| stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0); |
| stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0); |
| stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1); |
| stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0); |
| stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a); |
| stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09); |
| stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26); |
| if (i_params->demod_mode != STV0900_SINGLE) |
| stv0900_activate_s2_modcode(i_params, demod); |
| else |
| stv0900_activate_s2_modcode_single(i_params, demod); |
| |
| if (i_params->dmd2_symbol_rate >= 2000000) |
| stv0900_set_viterbi_acq(i_params, demod); |
| else |
| stv0900_set_viterbi_tracq(i_params, demod); |
| |
| stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod); |
| |
| break; |
| } |
| |
| break; |
| } |
| } |
| |
| enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe) |
| { |
| struct stv0900_state *state = fe->demodulator_priv; |
| struct stv0900_internal *i_params = state->internal; |
| enum fe_stv0900_demod_num demod = state->demod; |
| |
| s32 demod_timeout = 500, fec_timeout = 50, stream_merger_field; |
| |
| 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; |
| |
| dprintk(KERN_INFO "%s\n", __func__); |
| |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| algo = i_params->dmd1_srch_algo; |
| |
| stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 1); |
| stream_merger_field = F0900_P1_RST_HWARE; |
| |
| stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C); |
| |
| if (i_params->chip_id >= 0x20) |
| stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x9e); |
| else |
| stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x88); |
| |
| stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd1_symbol_rate, i_params->dmd1_srch_algo); |
| |
| if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) { |
| i_params->tuner1_bw = 2 * 36000000; |
| |
| stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x00); |
| stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70); |
| |
| stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod); |
| } else { |
| stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20); |
| stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2); |
| |
| if (i_params->dmd1_symbol_rate < 2000000) |
| stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x63); |
| else |
| stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70); |
| |
| stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38); |
| if (i_params->chip_id >= 0x20) { |
| stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0x5a); |
| |
| if (i_params->dmd1_srch_algo == STV0900_COLD_START) |
| i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10; |
| else if (i_params->dmd1_srch_algo == STV0900_WARM_START) |
| i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000; |
| } else { |
| stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0xc1); |
| i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10; |
| } |
| |
| stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01); |
| |
| stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod); |
| stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod); |
| stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod); |
| if (i_params->dmd1_symbol_rate >= 10000000) |
| low_sr = FALSE; |
| else |
| low_sr = TRUE; |
| |
| } |
| |
| stv0900_set_tuner(fe, i_params->tuner1_freq, i_params->tuner1_bw); |
| |
| stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, i_params->dmd1_srch_iq_inv); |
| stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1); |
| |
| stv0900_set_search_standard(i_params, demod); |
| |
| if (i_params->dmd1_srch_algo != STV0900_BLIND_SEARCH) |
| stv0900_start_search(i_params, demod); |
| break; |
| case STV0900_DEMOD_2: |
| algo = i_params->dmd2_srch_algo; |
| |
| stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 1); |
| |
| stream_merger_field = F0900_P2_RST_HWARE; |
| |
| stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C); |
| |
| if (i_params->chip_id >= 0x20) |
| stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x9e); |
| else |
| stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x88); |
| |
| stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd2_symbol_rate, i_params->dmd2_srch_algo); |
| |
| if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) { |
| i_params->tuner2_bw = 2 * 36000000; |
| |
| stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x00); |
| stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70); |
| |
| stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod); |
| } else { |
| stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20); |
| stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2); |
| |
| if (i_params->dmd2_symbol_rate < 2000000) |
| stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x63); |
| else |
| stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70); |
| |
| if (i_params->dmd2_symbol_rate >= 10000000) |
| stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38); |
| else |
| stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x60); |
| |
| if (i_params->chip_id >= 0x20) { |
| stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0x5a); |
| |
| if (i_params->dmd2_srch_algo == STV0900_COLD_START) |
| i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate, |
| i_params->rolloff) + 10000000)) / 10; |
| else if (i_params->dmd2_srch_algo == STV0900_WARM_START) |
| i_params->tuner2_bw = stv0900_carrier_width(i_params->dmd2_symbol_rate, |
| i_params->rolloff) + 10000000; |
| } else { |
| stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0xc1); |
| i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate, |
| i_params->rolloff) + 10000000)) / 10; |
| } |
| |
| stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01); |
| |
| stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod); |
| stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod); |
| stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod); |
| if (i_params->dmd2_symbol_rate >= 10000000) |
| low_sr = FALSE; |
| else |
| low_sr = TRUE; |
| |
| } |
| |
| stv0900_set_tuner(fe, i_params->tuner2_freq, i_params->tuner2_bw); |
| |
| stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, i_params->dmd2_srch_iq_inv); |
| stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1); |
| |
| stv0900_set_search_standard(i_params, demod); |
| |
| if (i_params->dmd2_srch_algo != STV0900_BLIND_SEARCH) |
| stv0900_start_search(i_params, demod); |
| break; |
| } |
| |
| if (i_params->chip_id == 0x12) { |
| stv0900_write_bits(i_params, stream_merger_field, 0); |
| msleep(3); |
| stv0900_write_bits(i_params, stream_merger_field, 1); |
| stv0900_write_bits(i_params, stream_merger_field, 0); |
| } |
| |
| 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) |
| lock = stv0900_get_demod_lock(i_params, demod, demod_timeout); |
| |
| if ((lock == FALSE) && (algo == STV0900_COLD_START)) { |
| if (low_sr == FALSE) { |
| if (stv0900_check_timing_lock(i_params, demod) == TRUE) |
| lock = stv0900_sw_algo(i_params, demod); |
| } |
| } |
| |
| if (lock == TRUE) |
| signal_type = stv0900_get_signal_params(fe); |
| |
| if ((lock == TRUE) && (signal_type == STV0900_RANGEOK)) { |
| stv0900_track_optimization(fe); |
| if (i_params->chip_id <= 0x11) { |
| if ((stv0900_get_standard(fe, STV0900_DEMOD_1) == STV0900_DVBS1_STANDARD) && (stv0900_get_standard(fe, STV0900_DEMOD_2) == STV0900_DVBS1_STANDARD)) { |
| msleep(20); |
| stv0900_write_bits(i_params, stream_merger_field, 0); |
| } else { |
| stv0900_write_bits(i_params, stream_merger_field, 0); |
| msleep(3); |
| stv0900_write_bits(i_params, stream_merger_field, 1); |
| stv0900_write_bits(i_params, stream_merger_field, 0); |
| } |
| } else if (i_params->chip_id == 0x20) { |
| stv0900_write_bits(i_params, stream_merger_field, 0); |
| msleep(3); |
| stv0900_write_bits(i_params, stream_merger_field, 1); |
| stv0900_write_bits(i_params, stream_merger_field, 0); |
| } |
| |
| if (stv0900_wait_for_lock(i_params, demod, fec_timeout, fec_timeout) == TRUE) { |
| lock = TRUE; |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| i_params->dmd1_rslts.locked = TRUE; |
| if (i_params->dmd1_rslts.standard == STV0900_DVBS2_STANDARD) { |
| stv0900_set_dvbs2_rolloff(i_params, demod); |
| stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0x40); |
| stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0); |
| stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67); |
| } else { |
| stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75); |
| } |
| |
| stv0900_write_reg(i_params, R0900_P1_FBERCPT4, 0); |
| stv0900_write_reg(i_params, R0900_P1_ERRCTRL2, 0xc1); |
| break; |
| case STV0900_DEMOD_2: |
| i_params->dmd2_rslts.locked = TRUE; |
| |
| if (i_params->dmd2_rslts.standard == STV0900_DVBS2_STANDARD) { |
| stv0900_set_dvbs2_rolloff(i_params, demod); |
| stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x60); |
| stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x20); |
| stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67); |
| } else { |
| stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75); |
| } |
| |
| stv0900_write_reg(i_params, R0900_P2_FBERCPT4, 0); |
| |
| stv0900_write_reg(i_params, R0900_P2_ERRCTRL2, 0xc1); |
| break; |
| } |
| } else { |
| lock = FALSE; |
| signal_type = STV0900_NODATA; |
| no_signal = stv0900_check_signal_presence(i_params, demod); |
| |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| i_params->dmd1_rslts.locked = FALSE; |
| break; |
| case STV0900_DEMOD_2: |
| i_params->dmd2_rslts.locked = FALSE; |
| break; |
| } |
| } |
| } |
| |
| if ((signal_type == STV0900_NODATA) && (no_signal == FALSE)) { |
| switch (demod) { |
| case STV0900_DEMOD_1: |
| default: |
| if (i_params->chip_id <= 0x11) { |
| if ((stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) && |
| (i_params->dmd1_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST)) |
| signal_type = stv0900_dvbs1_acq_workaround(fe); |
| } else |
| i_params->dmd1_rslts.locked = FALSE; |
| |
| break; |
| case STV0900_DEMOD_2: |
| if (i_params->chip_id <= 0x11) { |
| if ((stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) && |
| (i_params->dmd2_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST)) |
| signal_type = stv0900_dvbs1_acq_workaround(fe); |
| } else |
| i_params->dmd2_rslts.locked = FALSE; |
| break; |
| } |
| } |
| |
| return signal_type; |
| } |
| |