| /* |
| * 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" |
| |
| s32 shiftx(s32 x, int demod, s32 shift) |
| { |
| if (demod == 1) |
| return x - shift; |
| |
| return x; |
| } |
| |
| int stv0900_check_signal_presence(struct stv0900_internal *intp, |
| enum fe_stv0900_demod_num demod) |
| { |
| s32 carr_offset, |
| agc2_integr, |
| max_carrier; |
| |
| int no_signal = FALSE; |
| |
| carr_offset = (stv0900_read_reg(intp, CFR2) << 8) |
| | stv0900_read_reg(intp, CFR1); |
| carr_offset = ge2comp(carr_offset, 16); |
| agc2_integr = (stv0900_read_reg(intp, AGC2I1) << 8) |
| | stv0900_read_reg(intp, AGC2I0); |
| max_carrier = intp->srch_range[demod] / 1000; |
| |
| max_carrier += (max_carrier / 10); |
| max_carrier = 65536 * (max_carrier / 2); |
| max_carrier /= intp->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; |
| |
| return no_signal; |
| } |
| |
| static void stv0900_get_sw_loop_params(struct stv0900_internal *intp, |
| 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; |
| |
| srate = intp->symbol_rate[demod]; |
| max_carrier = intp->srch_range[demod] / 1000; |
| max_carrier += max_carrier / 10; |
| standard = intp->srch_standard[demod]; |
| |
| max_carrier = 65536 * (max_carrier / 2); |
| max_carrier /= intp->mclk / 1000; |
| |
| if (max_carrier > 0x4000) |
| max_carrier = 0x4000; |
| |
| freq_inc = srate; |
| freq_inc /= intp->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 *intp, |
| s32 FreqIncr, s32 Timeout, int zigzag, |
| s32 MaxStep, enum fe_stv0900_demod_num demod) |
| { |
| int no_signal, |
| lock = FALSE; |
| s32 stepCpt, |
| freqOffset, |
| max_carrier; |
| |
| max_carrier = intp->srch_range[demod] / 1000; |
| max_carrier += (max_carrier / 10); |
| |
| max_carrier = 65536 * (max_carrier / 2); |
| max_carrier /= intp->mclk / 1000; |
| |
| if (max_carrier > 0x4000) |
| max_carrier = 0x4000; |
| |
| if (zigzag == TRUE) |
| freqOffset = 0; |
| else |
| freqOffset = -max_carrier + FreqIncr; |
| |
| stepCpt = 0; |
| |
| do { |
| stv0900_write_reg(intp, DMDISTATE, 0x1c); |
| stv0900_write_reg(intp, CFRINIT1, (freqOffset / 256) & 0xff); |
| stv0900_write_reg(intp, CFRINIT0, freqOffset & 0xff); |
| stv0900_write_reg(intp, DMDISTATE, 0x18); |
| stv0900_write_bits(intp, ALGOSWRST, 1); |
| |
| if (intp->chip_id == 0x12) { |
| stv0900_write_bits(intp, RST_HWARE, 1); |
| stv0900_write_bits(intp, RST_HWARE, 0); |
| } |
| |
| if (zigzag == TRUE) { |
| if (freqOffset >= 0) |
| freqOffset = -freqOffset - 2 * FreqIncr; |
| else |
| freqOffset = -freqOffset; |
| } else |
| freqOffset += + 2 * FreqIncr; |
| |
| stepCpt++; |
| lock = stv0900_get_demod_lock(intp, demod, Timeout); |
| no_signal = stv0900_check_signal_presence(intp, demod); |
| |
| } while ((lock == FALSE) |
| && (no_signal == FALSE) |
| && ((freqOffset - FreqIncr) < max_carrier) |
| && ((freqOffset + FreqIncr) > -max_carrier) |
| && (stepCpt < MaxStep)); |
| |
| stv0900_write_bits(intp, ALGOSWRST, 0); |
| |
| return lock; |
| } |
| |
| static int stv0900_sw_algo(struct stv0900_internal *intp, |
| enum fe_stv0900_demod_num demod) |
| { |
| int lock = FALSE, |
| no_signal, |
| zigzag; |
| s32 s2fw, |
| fqc_inc, |
| sft_stp_tout, |
| trial_cntr, |
| max_steps; |
| |
| stv0900_get_sw_loop_params(intp, &fqc_inc, &sft_stp_tout, |
| &max_steps, demod); |
| switch (intp->srch_standard[demod]) { |
| case STV0900_SEARCH_DVBS1: |
| case STV0900_SEARCH_DSS: |
| if (intp->chip_id >= 0x20) |
| stv0900_write_reg(intp, CARFREQ, 0x3b); |
| else |
| stv0900_write_reg(intp, CARFREQ, 0xef); |
| |
| stv0900_write_reg(intp, DMDCFGMD, 0x49); |
| zigzag = FALSE; |
| break; |
| case STV0900_SEARCH_DVBS2: |
| if (intp->chip_id >= 0x20) |
| stv0900_write_reg(intp, CORRELABS, 0x79); |
| else |
| stv0900_write_reg(intp, CORRELABS, 0x68); |
| |
| stv0900_write_reg(intp, DMDCFGMD, 0x89); |
| |
| zigzag = TRUE; |
| break; |
| case STV0900_AUTO_SEARCH: |
| default: |
| if (intp->chip_id >= 0x20) { |
| stv0900_write_reg(intp, CARFREQ, 0x3b); |
| stv0900_write_reg(intp, CORRELABS, 0x79); |
| } else { |
| stv0900_write_reg(intp, CARFREQ, 0xef); |
| stv0900_write_reg(intp, CORRELABS, 0x68); |
| } |
| |
| stv0900_write_reg(intp, DMDCFGMD, 0xc9); |
| zigzag = FALSE; |
| break; |
| } |
| |
| trial_cntr = 0; |
| do { |
| lock = stv0900_search_carr_sw_loop(intp, |
| fqc_inc, |
| sft_stp_tout, |
| zigzag, |
| max_steps, |
| demod); |
| no_signal = stv0900_check_signal_presence(intp, demod); |
| trial_cntr++; |
| if ((lock == TRUE) |
| || (no_signal == TRUE) |
| || (trial_cntr == 2)) { |
| |
| if (intp->chip_id >= 0x20) { |
| stv0900_write_reg(intp, CARFREQ, 0x49); |
| stv0900_write_reg(intp, CORRELABS, 0x9e); |
| } else { |
| stv0900_write_reg(intp, CARFREQ, 0xed); |
| stv0900_write_reg(intp, CORRELABS, 0x88); |
| } |
| |
| if ((stv0900_get_bits(intp, HEADER_MODE) == |
| STV0900_DVBS2_FOUND) && |
| (lock == TRUE)) { |
| msleep(sft_stp_tout); |
| s2fw = stv0900_get_bits(intp, FLYWHEEL_CPT); |
| |
| if (s2fw < 0xd) { |
| msleep(sft_stp_tout); |
| s2fw = stv0900_get_bits(intp, |
| FLYWHEEL_CPT); |
| } |
| |
| if (s2fw < 0xd) { |
| lock = FALSE; |
| |
| if (trial_cntr < 2) { |
| if (intp->chip_id >= 0x20) |
| stv0900_write_reg(intp, |
| CORRELABS, |
| 0x79); |
| else |
| stv0900_write_reg(intp, |
| CORRELABS, |
| 0x68); |
| |
| stv0900_write_reg(intp, |
| DMDCFGMD, |
| 0x89); |
| } |
| } |
| } |
| } |
| |
| } while ((lock == FALSE) |
| && (trial_cntr < 2) |
| && (no_signal == FALSE)); |
| |
| return lock; |
| } |
| |
| static u32 stv0900_get_symbol_rate(struct stv0900_internal *intp, |
| u32 mclk, |
| enum fe_stv0900_demod_num demod) |
| { |
| s32 rem1, rem2, intval1, intval2, srate; |
| |
| srate = (stv0900_get_bits(intp, SYMB_FREQ3) << 24) + |
| (stv0900_get_bits(intp, SYMB_FREQ2) << 16) + |
| (stv0900_get_bits(intp, SYMB_FREQ1) << 8) + |
| (stv0900_get_bits(intp, SYMB_FREQ0)); |
| dprintk("lock: srate=%d r0=0x%x r1=0x%x r2=0x%x r3=0x%x \n", |
| srate, stv0900_get_bits(intp, SYMB_FREQ0), |
| stv0900_get_bits(intp, SYMB_FREQ1), |
| stv0900_get_bits(intp, SYMB_FREQ2), |
| stv0900_get_bits(intp, SYMB_FREQ3)); |
| |
| 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 *intp, |
| u32 mclk, u32 srate, |
| enum fe_stv0900_demod_num demod) |
| { |
| u32 symb; |
| |
| dprintk("%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk, |
| srate, demod); |
| |
| if (srate > 60000000) { |
| symb = srate << 4; |
| symb /= (mclk >> 12); |
| } else if (srate > 6000000) { |
| symb = srate << 6; |
| symb /= (mclk >> 10); |
| } else { |
| symb = srate << 9; |
| symb /= (mclk >> 7); |
| } |
| |
| stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0x7f); |
| stv0900_write_reg(intp, SFRINIT1 + 1, (symb & 0xff)); |
| } |
| |
| static void stv0900_set_max_symbol_rate(struct stv0900_internal *intp, |
| u32 mclk, u32 srate, |
| enum fe_stv0900_demod_num demod) |
| { |
| u32 symb; |
| |
| srate = 105 * (srate / 100); |
| |
| if (srate > 60000000) { |
| symb = srate << 4; |
| symb /= (mclk >> 12); |
| } else if (srate > 6000000) { |
| symb = srate << 6; |
| symb /= (mclk >> 10); |
| } else { |
| symb = srate << 9; |
| symb /= (mclk >> 7); |
| } |
| |
| if (symb < 0x7fff) { |
| stv0900_write_reg(intp, SFRUP1, (symb >> 8) & 0x7f); |
| stv0900_write_reg(intp, SFRUP1 + 1, (symb & 0xff)); |
| } else { |
| stv0900_write_reg(intp, SFRUP1, 0x7f); |
| stv0900_write_reg(intp, SFRUP1 + 1, 0xff); |
| } |
| } |
| |
| static void stv0900_set_min_symbol_rate(struct stv0900_internal *intp, |
| u32 mclk, u32 srate, |
| enum fe_stv0900_demod_num demod) |
| { |
| u32 symb; |
| |
| srate = 95 * (srate / 100); |
| if (srate > 60000000) { |
| symb = srate << 4; |
| symb /= (mclk >> 12); |
| |
| } else if (srate > 6000000) { |
| symb = srate << 6; |
| symb /= (mclk >> 10); |
| |
| } else { |
| symb = srate << 9; |
| symb /= (mclk >> 7); |
| } |
| |
| stv0900_write_reg(intp, SFRLOW1, (symb >> 8) & 0xff); |
| stv0900_write_reg(intp, SFRLOW1 + 1, (symb & 0xff)); |
| } |
| |
| static s32 stv0900_get_timing_offst(struct stv0900_internal *intp, |
| u32 srate, |
| enum fe_stv0900_demod_num demod) |
| { |
| s32 timingoffset; |
| |
| |
| timingoffset = (stv0900_read_reg(intp, TMGREG2) << 16) + |
| (stv0900_read_reg(intp, TMGREG2 + 1) << 8) + |
| (stv0900_read_reg(intp, TMGREG2 + 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 *intp, |
| enum fe_stv0900_demod_num demod) |
| { |
| s32 rolloff; |
| |
| if (intp->chip_id == 0x10) { |
| stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1); |
| rolloff = stv0900_read_reg(intp, MATSTR1) & 0x03; |
| stv0900_write_bits(intp, ROLLOFF_CONTROL, rolloff); |
| } else if (intp->chip_id <= 0x20) |
| stv0900_write_bits(intp, MANUALSX_ROLLOFF, 0); |
| else /* cut 3.0 */ |
| stv0900_write_bits(intp, MANUALS2_ROLLOFF, 0); |
| } |
| |
| 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 *intp, |
| enum fe_stv0900_demod_num demod) |
| { |
| int timingLock = FALSE; |
| s32 i, |
| timingcpt = 0; |
| u8 car_freq, |
| tmg_th_high, |
| tmg_th_low; |
| |
| car_freq = stv0900_read_reg(intp, CARFREQ); |
| tmg_th_high = stv0900_read_reg(intp, TMGTHRISE); |
| tmg_th_low = stv0900_read_reg(intp, TMGTHFALL); |
| stv0900_write_reg(intp, TMGTHRISE, 0x20); |
| stv0900_write_reg(intp, TMGTHFALL, 0x0); |
| stv0900_write_bits(intp, CFR_AUTOSCAN, 0); |
| stv0900_write_reg(intp, RTC, 0x80); |
| stv0900_write_reg(intp, RTCS2, 0x40); |
| stv0900_write_reg(intp, CARFREQ, 0x0); |
| stv0900_write_reg(intp, CFRINIT1, 0x0); |
| stv0900_write_reg(intp, CFRINIT0, 0x0); |
| stv0900_write_reg(intp, AGC2REF, 0x65); |
| stv0900_write_reg(intp, DMDISTATE, 0x18); |
| msleep(7); |
| |
| for (i = 0; i < 10; i++) { |
| if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2) |
| timingcpt++; |
| |
| msleep(1); |
| } |
| |
| if (timingcpt >= 3) |
| timingLock = TRUE; |
| |
| stv0900_write_reg(intp, AGC2REF, 0x38); |
| stv0900_write_reg(intp, RTC, 0x88); |
| stv0900_write_reg(intp, RTCS2, 0x68); |
| stv0900_write_reg(intp, CARFREQ, car_freq); |
| stv0900_write_reg(intp, TMGTHRISE, tmg_th_high); |
| stv0900_write_reg(intp, TMGTHFALL, tmg_th_low); |
| |
| 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 *intp = state->internal; |
| enum fe_stv0900_demod_num demod = state->demod; |
| int lock = FALSE, |
| d = demod; |
| s32 srate, |
| search_range, |
| locktimeout, |
| currier_step, |
| nb_steps, |
| current_step, |
| direction, |
| tuner_freq, |
| timeout, |
| freq; |
| |
| srate = intp->symbol_rate[d]; |
| search_range = intp->srch_range[d]; |
| |
| if (srate >= 10000000) |
| locktimeout = demod_timeout / 3; |
| else |
| locktimeout = demod_timeout / 2; |
| |
| lock = stv0900_get_demod_lock(intp, d, locktimeout); |
| |
| if (lock != FALSE) |
| return lock; |
| |
| if (srate >= 10000000) { |
| if (stv0900_check_timing_lock(intp, d) == TRUE) { |
| stv0900_write_reg(intp, DMDISTATE, 0x1f); |
| stv0900_write_reg(intp, DMDISTATE, 0x15); |
| lock = stv0900_get_demod_lock(intp, d, demod_timeout); |
| } else |
| lock = FALSE; |
| |
| return lock; |
| } |
| |
| if (intp->chip_id <= 0x20) { |
| if (srate <= 1000000) |
| currier_step = 500; |
| else if (srate <= 4000000) |
| currier_step = 1000; |
| else if (srate <= 7000000) |
| currier_step = 2000; |
| else if (srate <= 10000000) |
| currier_step = 3000; |
| else |
| currier_step = 5000; |
| |
| if (srate >= 2000000) { |
| timeout = (demod_timeout / 3); |
| if (timeout > 1000) |
| timeout = 1000; |
| } else |
| timeout = (demod_timeout / 2); |
| } else { |
| /*cut 3.0 */ |
| currier_step = srate / 4000; |
| timeout = (demod_timeout * 3) / 4; |
| } |
| |
| nb_steps = ((search_range / 1000) / currier_step); |
| |
| if ((nb_steps % 2) != 0) |
| nb_steps += 1; |
| |
| if (nb_steps <= 0) |
| nb_steps = 2; |
| else if (nb_steps > 12) |
| nb_steps = 12; |
| |
| current_step = 1; |
| direction = 1; |
| |
| if (intp->chip_id <= 0x20) { |
| tuner_freq = intp->freq[d]; |
| intp->bw[d] = stv0900_carrier_width(intp->symbol_rate[d], |
| intp->rolloff) + intp->symbol_rate[d]; |
| } else |
| tuner_freq = 0; |
| |
| while ((current_step <= nb_steps) && (lock == FALSE)) { |
| if (direction > 0) |
| tuner_freq += (current_step * currier_step); |
| else |
| tuner_freq -= (current_step * currier_step); |
| |
| if (intp->chip_id <= 0x20) { |
| if (intp->tuner_type[d] == 3) |
| stv0900_set_tuner_auto(intp, tuner_freq, |
| intp->bw[d], demod); |
| else |
| stv0900_set_tuner(fe, tuner_freq, intp->bw[d]); |
| |
| stv0900_write_reg(intp, DMDISTATE, 0x1c); |
| stv0900_write_reg(intp, CFRINIT1, 0); |
| stv0900_write_reg(intp, CFRINIT0, 0); |
| stv0900_write_reg(intp, DMDISTATE, 0x1f); |
| stv0900_write_reg(intp, DMDISTATE, 0x15); |
| } else { |
| stv0900_write_reg(intp, DMDISTATE, 0x1c); |
| freq = (tuner_freq * 65536) / (intp->mclk / 1000); |
| stv0900_write_bits(intp, CFR_INIT1, MSB(freq)); |
| stv0900_write_bits(intp, CFR_INIT0, LSB(freq)); |
| stv0900_write_reg(intp, DMDISTATE, 0x1f); |
| stv0900_write_reg(intp, DMDISTATE, 0x05); |
| } |
| |
| lock = stv0900_get_demod_lock(intp, d, timeout); |
| direction *= -1; |
| current_step++; |
| } |
| |
| 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 *intp, |
| enum fe_stv0900_demod_num demod) |
| { |
| |
| s32 vth_reg = VTH12; |
| |
| dprintk("%s\n", __func__); |
| |
| stv0900_write_reg(intp, vth_reg++, 0xd0); |
| stv0900_write_reg(intp, vth_reg++, 0x7d); |
| stv0900_write_reg(intp, vth_reg++, 0x53); |
| stv0900_write_reg(intp, vth_reg++, 0x2f); |
| stv0900_write_reg(intp, vth_reg++, 0x24); |
| stv0900_write_reg(intp, vth_reg++, 0x1f); |
| } |
| |
| static void stv0900_set_viterbi_standard(struct stv0900_internal *intp, |
| enum fe_stv0900_search_standard standard, |
| enum fe_stv0900_fec fec, |
| enum fe_stv0900_demod_num demod) |
| { |
| dprintk("%s: ViterbiStandard = ", __func__); |
| |
| switch (standard) { |
| case STV0900_AUTO_SEARCH: |
| dprintk("Auto\n"); |
| stv0900_write_reg(intp, FECM, 0x10); |
| stv0900_write_reg(intp, PRVIT, 0x3f); |
| break; |
| case STV0900_SEARCH_DVBS1: |
| dprintk("DVBS1\n"); |
| stv0900_write_reg(intp, FECM, 0x00); |
| switch (fec) { |
| case STV0900_FEC_UNKNOWN: |
| default: |
| stv0900_write_reg(intp, PRVIT, 0x2f); |
| break; |
| case STV0900_FEC_1_2: |
| stv0900_write_reg(intp, PRVIT, 0x01); |
| break; |
| case STV0900_FEC_2_3: |
| stv0900_write_reg(intp, PRVIT, 0x02); |
| break; |
| case STV0900_FEC_3_4: |
| stv0900_write_reg(intp, PRVIT, 0x04); |
| break; |
| case STV0900_FEC_5_6: |
| stv0900_write_reg(intp, PRVIT, 0x08); |
| break; |
| case STV0900_FEC_7_8: |
| stv0900_write_reg(intp, PRVIT, 0x20); |
| break; |
| } |
| |
| break; |
| case STV0900_SEARCH_DSS: |
| dprintk("DSS\n"); |
| stv0900_write_reg(intp, FECM, 0x80); |
| switch (fec) { |
| case STV0900_FEC_UNKNOWN: |
| default: |
| stv0900_write_reg(intp, PRVIT, 0x13); |
| break; |
| case STV0900_FEC_1_2: |
| stv0900_write_reg(intp, PRVIT, 0x01); |
| break; |
| case STV0900_FEC_2_3: |
| stv0900_write_reg(intp, PRVIT, 0x02); |
| break; |
| case STV0900_FEC_6_7: |
| stv0900_write_reg(intp, PRVIT, 0x10); |
| break; |
| } |
| break; |
| default: |
| break; |
| } |
| } |
| |
| static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *intp, |
| enum fe_stv0900_demod_num demod) |
| { |
| enum fe_stv0900_fec prate; |
| s32 rate_fld = stv0900_get_bits(intp, VIT_CURPUN); |
| |
| switch (rate_fld) { |
| case 13: |
| prate = STV0900_FEC_1_2; |
| break; |
| case 18: |
| prate = STV0900_FEC_2_3; |
| break; |
| case 21: |
| prate = STV0900_FEC_3_4; |
| break; |
| case 24: |
| prate = STV0900_FEC_5_6; |
| break; |
| case 25: |
| prate = STV0900_FEC_6_7; |
| break; |
| case 26: |
| prate = STV0900_FEC_7_8; |
| break; |
| default: |
| prate = STV0900_FEC_UNKNOWN; |
| break; |
| } |
| |
| return prate; |
| } |
| |
| static void stv0900_set_dvbs1_track_car_loop(struct stv0900_internal *intp, |
| enum fe_stv0900_demod_num demod, |
| u32 srate) |
| { |
| if (intp->chip_id >= 0x30) { |
| if (srate >= 15000000) { |
| stv0900_write_reg(intp, ACLC, 0x2b); |
| stv0900_write_reg(intp, BCLC, 0x1a); |
| } else if ((srate >= 7000000) && (15000000 > srate)) { |
| stv0900_write_reg(intp, ACLC, 0x0c); |
| stv0900_write_reg(intp, BCLC, 0x1b); |
| } else if (srate < 7000000) { |
| stv0900_write_reg(intp, ACLC, 0x2c); |
| stv0900_write_reg(intp, BCLC, 0x1c); |
| } |
| |
| } else { /*cut 2.0 and 1.x*/ |
| stv0900_write_reg(intp, ACLC, 0x1a); |
| stv0900_write_reg(intp, BCLC, 0x09); |
| } |
| |
| } |
| |
| static void stv0900_track_optimization(struct dvb_frontend *fe) |
| { |
| struct stv0900_state *state = fe->demodulator_priv; |
| struct stv0900_internal *intp = state->internal; |
| enum fe_stv0900_demod_num demod = state->demod; |
| |
| s32 srate, |
| pilots, |
| aclc, |
| freq1, |
| freq0, |
| i = 0, |
| timed, |
| timef, |
| blind_tun_sw = 0, |
| modulation; |
| |
| enum fe_stv0900_modcode foundModcod; |
| |
| dprintk("%s\n", __func__); |
| |
| srate = stv0900_get_symbol_rate(intp, intp->mclk, demod); |
| srate += stv0900_get_timing_offst(intp, srate, demod); |
| |
| switch (intp->result[demod].standard) { |
| case STV0900_DVBS1_STANDARD: |
| case STV0900_DSS_STANDARD: |
| dprintk("%s: found DVB-S or DSS\n", __func__); |
| if (intp->srch_standard[demod] == STV0900_AUTO_SEARCH) { |
| stv0900_write_bits(intp, DVBS1_ENABLE, 1); |
| stv0900_write_bits(intp, DVBS2_ENABLE, 0); |
| } |
| |
| stv0900_write_bits(intp, ROLLOFF_CONTROL, intp->rolloff); |
| stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1); |
| |
| if (intp->chip_id < 0x30) { |
| stv0900_write_reg(intp, ERRCTRL1, 0x75); |
| break; |
| } |
| |
| if (stv0900_get_vit_fec(intp, demod) == STV0900_FEC_1_2) { |
| stv0900_write_reg(intp, GAUSSR0, 0x98); |
| stv0900_write_reg(intp, CCIR0, 0x18); |
| } else { |
| stv0900_write_reg(intp, GAUSSR0, 0x18); |
| stv0900_write_reg(intp, CCIR0, 0x18); |
| } |
| |
| stv0900_write_reg(intp, ERRCTRL1, 0x75); |
| break; |
| case STV0900_DVBS2_STANDARD: |
| dprintk("%s: found DVB-S2\n", __func__); |
| stv0900_write_bits(intp, DVBS1_ENABLE, 0); |
| stv0900_write_bits(intp, DVBS2_ENABLE, 1); |
| stv0900_write_reg(intp, ACLC, 0); |
| stv0900_write_reg(intp, BCLC, 0); |
| if (intp->result[demod].frame_len == STV0900_LONG_FRAME) { |
| foundModcod = stv0900_get_bits(intp, DEMOD_MODCOD); |
| pilots = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01; |
| aclc = stv0900_get_optim_carr_loop(srate, |
| foundModcod, |
| pilots, |
| intp->chip_id); |
| if (foundModcod <= STV0900_QPSK_910) |
| stv0900_write_reg(intp, ACLC2S2Q, aclc); |
| else if (foundModcod <= STV0900_8PSK_910) { |
| stv0900_write_reg(intp, ACLC2S2Q, 0x2a); |
| stv0900_write_reg(intp, ACLC2S28, aclc); |
| } |
| |
| if ((intp->demod_mode == STV0900_SINGLE) && |
| (foundModcod > STV0900_8PSK_910)) { |
| if (foundModcod <= STV0900_16APSK_910) { |
| stv0900_write_reg(intp, ACLC2S2Q, 0x2a); |
| stv0900_write_reg(intp, ACLC2S216A, |
| aclc); |
| } else if (foundModcod <= STV0900_32APSK_910) { |
| stv0900_write_reg(intp, ACLC2S2Q, 0x2a); |
| stv0900_write_reg(intp, ACLC2S232A, |
| aclc); |
| } |
| } |
| |
| } else { |
| modulation = intp->result[demod].modulation; |
| aclc = stv0900_get_optim_short_carr_loop(srate, |
| modulation, intp->chip_id); |
| if (modulation == STV0900_QPSK) |
| stv0900_write_reg(intp, ACLC2S2Q, aclc); |
| else if (modulation == STV0900_8PSK) { |
| stv0900_write_reg(intp, ACLC2S2Q, 0x2a); |
| stv0900_write_reg(intp, ACLC2S28, aclc); |
| } else if (modulation == STV0900_16APSK) { |
| stv0900_write_reg(intp, ACLC2S2Q, 0x2a); |
| stv0900_write_reg(intp, ACLC2S216A, aclc); |
| } else if (modulation == STV0900_32APSK) { |
| stv0900_write_reg(intp, ACLC2S2Q, 0x2a); |
| stv0900_write_reg(intp, ACLC2S232A, aclc); |
| } |
| |
| } |
| |
| if (intp->chip_id <= 0x11) { |
| if (intp->demod_mode != STV0900_SINGLE) |
| stv0900_activate_s2_modcod(intp, demod); |
| |
| } |
| |
| stv0900_write_reg(intp, ERRCTRL1, 0x67); |
| break; |
| case STV0900_UNKNOWN_STANDARD: |
| default: |
| dprintk("%s: found unknown standard\n", __func__); |
| stv0900_write_bits(intp, DVBS1_ENABLE, 1); |
| stv0900_write_bits(intp, DVBS2_ENABLE, 1); |
| break; |
| } |
| |
| freq1 = stv0900_read_reg(intp, CFR2); |
| freq0 = stv0900_read_reg(intp, CFR1); |
| if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) { |
| stv0900_write_reg(intp, SFRSTEP, 0x00); |
| stv0900_write_bits(intp, SCAN_ENABLE, 0); |
| stv0900_write_bits(intp, CFR_AUTOSCAN, 0); |
| stv0900_write_reg(intp, TMGCFG2, 0xc1); |
| stv0900_set_symbol_rate(intp, intp->mclk, srate, demod); |
| blind_tun_sw = 1; |
| if (intp->result[demod].standard != STV0900_DVBS2_STANDARD) |
| stv0900_set_dvbs1_track_car_loop(intp, demod, srate); |
| |
| } |
| |
| if (intp->chip_id >= 0x20) { |
| if ((intp->srch_standard[demod] == STV0900_SEARCH_DVBS1) || |
| (intp->srch_standard[demod] == |
| STV0900_SEARCH_DSS) || |
| (intp->srch_standard[demod] == |
| STV0900_AUTO_SEARCH)) { |
| stv0900_write_reg(intp, VAVSRVIT, 0x0a); |
| stv0900_write_reg(intp, VITSCALE, 0x0); |
| } |
| } |
| |
| if (intp->chip_id < 0x20) |
| stv0900_write_reg(intp, CARHDR, 0x08); |
| |
| if (intp->chip_id == 0x10) |
| stv0900_write_reg(intp, CORRELEXP, 0x0a); |
| |
| stv0900_write_reg(intp, AGC2REF, 0x38); |
| |
| if ((intp->chip_id >= 0x20) || |
| (blind_tun_sw == 1) || |
| (intp->symbol_rate[demod] < 10000000)) { |
| stv0900_write_reg(intp, CFRINIT1, freq1); |
| stv0900_write_reg(intp, CFRINIT0, freq0); |
| intp->bw[demod] = stv0900_carrier_width(srate, |
| intp->rolloff) + 10000000; |
| |
| if ((intp->chip_id >= 0x20) || (blind_tun_sw == 1)) { |
| if (intp->srch_algo[demod] != STV0900_WARM_START) { |
| if (intp->tuner_type[demod] == 3) |
| stv0900_set_tuner_auto(intp, |
| intp->freq[demod], |
| intp->bw[demod], |
| demod); |
| else |
| stv0900_set_bandwidth(fe, |
| intp->bw[demod]); |
| } |
| } |
| |
| if ((intp->srch_algo[demod] == STV0900_BLIND_SEARCH) || |
| (intp->symbol_rate[demod] < 10000000)) |
| msleep(50); |
| else |
| msleep(5); |
| |
| stv0900_get_lock_timeout(&timed, &timef, srate, |
| STV0900_WARM_START); |
| |
| if (stv0900_get_demod_lock(intp, demod, timed / 2) == FALSE) { |
| stv0900_write_reg(intp, DMDISTATE, 0x1f); |
| stv0900_write_reg(intp, CFRINIT1, freq1); |
| stv0900_write_reg(intp, CFRINIT0, freq0); |
| stv0900_write_reg(intp, DMDISTATE, 0x18); |
| i = 0; |
| while ((stv0900_get_demod_lock(intp, |
| demod, |
| timed / 2) == FALSE) && |
| (i <= 2)) { |
| stv0900_write_reg(intp, DMDISTATE, 0x1f); |
| stv0900_write_reg(intp, CFRINIT1, freq1); |
| stv0900_write_reg(intp, CFRINIT0, freq0); |
| stv0900_write_reg(intp, DMDISTATE, 0x18); |
| i++; |
| } |
| } |
| |
| } |
| |
| if (intp->chip_id >= 0x20) |
| stv0900_write_reg(intp, CARFREQ, 0x49); |
| |
| if ((intp->result[demod].standard == STV0900_DVBS1_STANDARD) || |
| (intp->result[demod].standard == STV0900_DSS_STANDARD)) |
| stv0900_set_viterbi_tracq(intp, demod); |
| |
| } |
| |
| static int stv0900_get_fec_lock(struct stv0900_internal *intp, |
| enum fe_stv0900_demod_num demod, s32 time_out) |
| { |
| s32 timer = 0, lock = 0; |
| |
| enum fe_stv0900_search_state dmd_state; |
| |
| dprintk("%s\n", __func__); |
| |
| dmd_state = stv0900_get_bits(intp, HEADER_MODE); |
| |
| 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(intp, PKTDELIN_LOCK); |
| break; |
| case STV0900_DVBS_FOUND: |
| lock = stv0900_get_bits(intp, LOCKEDVIT); |
| break; |
| } |
| |
| if (lock == 0) { |
| msleep(10); |
| timer += 10; |
| } |
| } |
| |
| if (lock) |
| dprintk("%s: DEMOD FEC LOCK OK\n", __func__); |
| else |
| dprintk("%s: DEMOD FEC LOCK FAIL\n", __func__); |
| |
| return lock; |
| } |
| |
| static int stv0900_wait_for_lock(struct stv0900_internal *intp, |
| enum fe_stv0900_demod_num demod, |
| s32 dmd_timeout, s32 fec_timeout) |
| { |
| |
| s32 timer = 0, lock = 0; |
| |
| dprintk("%s\n", __func__); |
| |
| lock = stv0900_get_demod_lock(intp, demod, dmd_timeout); |
| |
| if (lock) |
| lock = stv0900_get_fec_lock(intp, demod, fec_timeout); |
| |
| if (lock) { |
| lock = 0; |
| |
| dprintk("%s: Timer = %d, time_out = %d\n", |
| __func__, timer, fec_timeout); |
| |
| while ((timer < fec_timeout) && (lock == 0)) { |
| lock = stv0900_get_bits(intp, TSFIFO_LINEOK); |
| msleep(1); |
| timer++; |
| } |
| } |
| |
| if (lock) |
| dprintk("%s: DEMOD LOCK OK\n", __func__); |
| else |
| dprintk("%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 *intp = state->internal; |
| enum fe_stv0900_tracking_standard fnd_standard; |
| |
| int hdr_mode = stv0900_get_bits(intp, HEADER_MODE); |
| |
| switch (hdr_mode) { |
| case 2: |
| fnd_standard = STV0900_DVBS2_STANDARD; |
| break; |
| case 3: |
| if (stv0900_get_bits(intp, DSS_DVB) == 1) |
| fnd_standard = STV0900_DSS_STANDARD; |
| else |
| fnd_standard = STV0900_DVBS1_STANDARD; |
| |
| break; |
| default: |
| fnd_standard = STV0900_UNKNOWN_STANDARD; |
| } |
| |
| dprintk("%s: standard %d\n", __func__, fnd_standard); |
| |
| return fnd_standard; |
| } |
| |
| static s32 stv0900_get_carr_freq(struct stv0900_internal *intp, u32 mclk, |
| enum fe_stv0900_demod_num demod) |
| { |
| s32 derot, |
| rem1, |
| rem2, |
| intval1, |
| intval2; |
| |
| derot = (stv0900_get_bits(intp, CAR_FREQ2) << 16) + |
| (stv0900_get_bits(intp, CAR_FREQ1) << 8) + |
| (stv0900_get_bits(intp, CAR_FREQ0)); |
| |
| 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 freq = 0; |
| |
| frontend_ops = &fe->ops; |
| tuner_ops = &frontend_ops->tuner_ops; |
| |
| if (tuner_ops->get_frequency) { |
| if ((tuner_ops->get_frequency(fe, &freq)) < 0) |
| dprintk("%s: Invalid parameter\n", __func__); |
| else |
| dprintk("%s: Frequency=%d\n", __func__, freq); |
| |
| } |
| |
| return freq; |
| } |
| |
| static enum |
| fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe) |
| { |
| struct stv0900_state *state = fe->demodulator_priv; |
| struct stv0900_internal *intp = state->internal; |
| enum fe_stv0900_demod_num demod = state->demod; |
| enum fe_stv0900_signal_type range = STV0900_OUTOFRANGE; |
| struct stv0900_signal_info *result = &intp->result[demod]; |
| s32 offsetFreq, |
| srate_offset; |
| int i = 0, |
| d = demod; |
| |
| u8 timing; |
| |
| msleep(5); |
| if (intp->srch_algo[d] == STV0900_BLIND_SEARCH) { |
| timing = stv0900_read_reg(intp, TMGREG2); |
| i = 0; |
| stv0900_write_reg(intp, SFRSTEP, 0x5c); |
| |
| while ((i <= 50) && (timing != 0) && (timing != 0xff)) { |
| timing = stv0900_read_reg(intp, TMGREG2); |
| msleep(5); |
| i += 5; |
| } |
| } |
| |
| result->standard = stv0900_get_standard(fe, d); |
| if (intp->tuner_type[demod] == 3) |
| result->frequency = stv0900_get_freq_auto(intp, d); |
| else |
| result->frequency = stv0900_get_tuner_freq(fe); |
| |
| offsetFreq = stv0900_get_carr_freq(intp, intp->mclk, d) / 1000; |
| result->frequency += offsetFreq; |
| result->symbol_rate = stv0900_get_symbol_rate(intp, intp->mclk, d); |
| srate_offset = stv0900_get_timing_offst(intp, result->symbol_rate, d); |
| result->symbol_rate += srate_offset; |
| result->fec = stv0900_get_vit_fec(intp, d); |
| result->modcode = stv0900_get_bits(intp, DEMOD_MODCOD); |
| result->pilot = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01; |
| result->frame_len = ((u32)stv0900_get_bits(intp, DEMOD_TYPE)) >> 1; |
| result->rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS); |
| |
| dprintk("%s: modcode=0x%x \n", __func__, result->modcode); |
| |
| switch (result->standard) { |
| case STV0900_DVBS2_STANDARD: |
| result->spectrum = stv0900_get_bits(intp, SPECINV_DEMOD); |
| if (result->modcode <= STV0900_QPSK_910) |
| result->modulation = STV0900_QPSK; |
| else if (result->modcode <= STV0900_8PSK_910) |
| result->modulation = STV0900_8PSK; |
| else if (result->modcode <= STV0900_16APSK_910) |
| result->modulation = STV0900_16APSK; |
| else if (result->modcode <= STV0900_32APSK_910) |
| result->modulation = STV0900_32APSK; |
| else |
| result->modulation = STV0900_UNKNOWN; |
| break; |
| case STV0900_DVBS1_STANDARD: |
| case STV0900_DSS_STANDARD: |
| result->spectrum = stv0900_get_bits(intp, IQINV); |
| result->modulation = STV0900_QPSK; |
| break; |
| default: |
| break; |
| } |
| |
| if ((intp->srch_algo[d] == STV0900_BLIND_SEARCH) || |
| (intp->symbol_rate[d] < 10000000)) { |
| offsetFreq = result->frequency - intp->freq[d]; |
| if (intp->tuner_type[demod] == 3) |
| intp->freq[d] = stv0900_get_freq_auto(intp, d); |
| else |
| intp->freq[d] = stv0900_get_tuner_freq(fe); |
| |
| if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500)) |
| range = STV0900_RANGEOK; |
| else if (ABS(offsetFreq) <= |
| (stv0900_carrier_width(result->symbol_rate, |
| result->rolloff) / 2000)) |
| range = STV0900_RANGEOK; |
| |
| } else if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500)) |
| range = STV0900_RANGEOK; |
| |
| dprintk("%s: range %d\n", __func__, range); |
| |
| 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 *intp = state->internal; |
| enum fe_stv0900_demod_num demod = state->demod; |
| enum fe_stv0900_signal_type signal_type = STV0900_NODATA; |
| |
| s32 srate, |
| demod_timeout, |
| fec_timeout, |
| freq1, |
| freq0; |
| |
| intp->result[demod].locked = FALSE; |
| |
| if (stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) { |
| srate = stv0900_get_symbol_rate(intp, intp->mclk, demod); |
| srate += stv0900_get_timing_offst(intp, srate, demod); |
| if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) |
| stv0900_set_symbol_rate(intp, intp->mclk, srate, demod); |
| |
| stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, |
| srate, STV0900_WARM_START); |
| freq1 = stv0900_read_reg(intp, CFR2); |
| freq0 = stv0900_read_reg(intp, CFR1); |
| stv0900_write_bits(intp, CFR_AUTOSCAN, 0); |
| stv0900_write_bits(intp, SPECINV_CONTROL, |
| STV0900_IQ_FORCE_SWAPPED); |
| stv0900_write_reg(intp, DMDISTATE, 0x1c); |
| stv0900_write_reg(intp, CFRINIT1, freq1); |
| stv0900_write_reg(intp, CFRINIT0, freq0); |
| stv0900_write_reg(intp, DMDISTATE, 0x18); |
| if (stv0900_wait_for_lock(intp, demod, |
| demod_timeout, fec_timeout) == TRUE) { |
| intp->result[demod].locked = TRUE; |
| signal_type = stv0900_get_signal_params(fe); |
| stv0900_track_optimization(fe); |
| } else { |
| stv0900_write_bits(intp, SPECINV_CONTROL, |
| STV0900_IQ_FORCE_NORMAL); |
| stv0900_write_reg(intp, DMDISTATE, 0x1c); |
| stv0900_write_reg(intp, CFRINIT1, freq1); |
| stv0900_write_reg(intp, CFRINIT0, freq0); |
| stv0900_write_reg(intp, DMDISTATE, 0x18); |
| if (stv0900_wait_for_lock(intp, demod, |
| demod_timeout, fec_timeout) == TRUE) { |
| intp->result[demod].locked = TRUE; |
| signal_type = stv0900_get_signal_params(fe); |
| stv0900_track_optimization(fe); |
| } |
| |
| } |
| |
| } else |
| intp->result[demod].locked = FALSE; |
| |
| return signal_type; |
| } |
| |
| static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *intp, |
| enum fe_stv0900_demod_num demod) |
| { |
| u32 minagc2level = 0xffff, |
| agc2level, |
| init_freq, freq_step; |
| |
| s32 i, j, nb_steps, direction; |
| |
| dprintk("%s\n", __func__); |
| |
| stv0900_write_reg(intp, AGC2REF, 0x38); |
| stv0900_write_bits(intp, SCAN_ENABLE, 0); |
| stv0900_write_bits(intp, CFR_AUTOSCAN, 0); |
| |
| stv0900_write_bits(intp, AUTO_GUP, 1); |
| stv0900_write_bits(intp, AUTO_GLOW, 1); |
| |
| stv0900_write_reg(intp, DMDT0M, 0x0); |
| |
| stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod); |
| nb_steps = -1 + (intp->srch_range[demod] / 1000000); |
| nb_steps /= 2; |
| nb_steps = (2 * nb_steps) + 1; |
| |
| if (nb_steps < 0) |
| nb_steps = 1; |
| |
| direction = 1; |
| |
| freq_step = (1000000 << 8) / (intp->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(intp, DMDISTATE, 0x5C); |
| stv0900_write_reg(intp, CFRINIT1, (init_freq >> 8) & 0xff); |
| stv0900_write_reg(intp, CFRINIT0, init_freq & 0xff); |
| stv0900_write_reg(intp, DMDISTATE, 0x58); |
| msleep(10); |
| agc2level = 0; |
| |
| for (j = 0; j < 10; j++) |
| agc2level += (stv0900_read_reg(intp, AGC2I1) << 8) |
| | stv0900_read_reg(intp, AGC2I0); |
| |
| agc2level /= 10; |
| |
| if (agc2level < minagc2level) |
| minagc2level = agc2level; |
| |
| } |
| |
| return (u16)minagc2level; |
| } |
| |
| static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe) |
| { |
| struct stv0900_state *state = fe->demodulator_priv; |
| struct stv0900_internal *intp = state->internal; |
| enum fe_stv0900_demod_num demod = state->demod; |
| int timing_lck = FALSE; |
| s32 i, timingcpt = 0, |
| direction = 1, |
| nb_steps, |
| current_step = 0, |
| tuner_freq; |
| u32 agc2_th, |
| coarse_srate = 0, |
| agc2_integr = 0, |
| currier_step = 1200; |
| |
| if (intp->chip_id >= 0x30) |
| agc2_th = 0x2e00; |
| else |
| agc2_th = 0x1f00; |
| |
| stv0900_write_bits(intp, DEMOD_MODE, 0x1f); |
| stv0900_write_reg(intp, TMGCFG, 0x12); |
| stv0900_write_reg(intp, TMGTHRISE, 0xf0); |
| stv0900_write_reg(intp, TMGTHFALL, 0xe0); |
| stv0900_write_bits(intp, SCAN_ENABLE, 1); |
| stv0900_write_bits(intp, CFR_AUTOSCAN, 1); |
| stv0900_write_reg(intp, SFRUP1, 0x83); |
| stv0900_write_reg(intp, SFRUP0, 0xc0); |
| stv0900_write_reg(intp, SFRLOW1, 0x82); |
| stv0900_write_reg(intp, SFRLOW0, 0xa0); |
| stv0900_write_reg(intp, DMDT0M, 0x0); |
| stv0900_write_reg(intp, AGC2REF, 0x50); |
| |
| if (intp->chip_id >= 0x30) { |
| stv0900_write_reg(intp, CARFREQ, 0x99); |
| stv0900_write_reg(intp, SFRSTEP, 0x98); |
| } else if (intp->chip_id >= 0x20) { |
| stv0900_write_reg(intp, CARFREQ, 0x6a); |
| stv0900_write_reg(intp, SFRSTEP, 0x95); |
| } else { |
| stv0900_write_reg(intp, CARFREQ, 0xed); |
| stv0900_write_reg(intp, SFRSTEP, 0x73); |
| } |
| |
| if (intp->symbol_rate[demod] <= 2000000) |
| currier_step = 1000; |
| else if (intp->symbol_rate[demod] <= 5000000) |
| currier_step = 2000; |
| else if (intp->symbol_rate[demod] <= 12000000) |
| currier_step = 3000; |
| else |
| currier_step = 5000; |
| |
| nb_steps = -1 + ((intp->srch_range[demod] / 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 = (intp->srch_range[demod] / 1000) / 10; |
| } |
| |
| current_step = 0; |
| direction = 1; |
| |
| tuner_freq = intp->freq[demod]; |
| |
| while ((timing_lck == FALSE) && (current_step < nb_steps)) { |
| stv0900_write_reg(intp, DMDISTATE, 0x5f); |
| stv0900_write_bits(intp, DEMOD_MODE, 0); |
| |
| msleep(50); |
| |
| for (i = 0; i < 10; i++) { |
| if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2) |
| timingcpt++; |
| |
| agc2_integr += (stv0900_read_reg(intp, AGC2I1) << 8) | |
| stv0900_read_reg(intp, AGC2I0); |
| } |
| |
| agc2_integr /= 10; |
| coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod); |
| current_step++; |
| direction *= -1; |
| |
| dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started." |
| " tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n", |
| tuner_freq, agc2_integr, coarse_srate, timingcpt); |
| |
| if ((timingcpt >= 5) && |
| (agc2_integr < agc2_th) && |
| (coarse_srate < 55000000) && |
| (coarse_srate > 850000)) |
| timing_lck = TRUE; |
| else if (current_step < nb_steps) { |
| if (direction > 0) |
| tuner_freq += (current_step * currier_step); |
| else |
| tuner_freq -= (current_step * currier_step); |
| |
| if (intp->tuner_type[demod] == 3) |
| stv0900_set_tuner_auto(intp, tuner_freq, |
| intp->bw[demod], demod); |
| else |
| stv0900_set_tuner(fe, tuner_freq, |
| intp->bw[demod]); |
| } |
| } |
| |
| if (timing_lck == FALSE) |
| coarse_srate = 0; |
| else |
| coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod); |
| |
| return coarse_srate; |
| } |
| |
| static u32 stv0900_search_srate_fine(struct dvb_frontend *fe) |
| { |
| struct stv0900_state *state = fe->demodulator_priv; |
| struct stv0900_internal *intp = state->internal; |
| enum fe_stv0900_demod_num demod = state->demod; |
| u32 coarse_srate, |
| coarse_freq, |
| symb, |
| symbmax, |
| symbmin, |
| symbcomp; |
| |
| coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod); |
| |
| if (coarse_srate > 3000000) { |
| symbmax = 13 * (coarse_srate / 10); |
| symbmax = (symbmax / 1000) * 65536; |
| symbmax /= (intp->mclk / 1000); |
| |
| symbmin = 10 * (coarse_srate / 13); |
| symbmin = (symbmin / 1000)*65536; |
| symbmin /= (intp->mclk / 1000); |
| |
| symb = (coarse_srate / 1000) * 65536; |
| symb /= (intp->mclk / 1000); |
| } else { |
| symbmax = 13 * (coarse_srate / 10); |
| symbmax = (symbmax / 100) * 65536; |
| symbmax /= (intp->mclk / 100); |
| |
| symbmin = 10 * (coarse_srate / 14); |
| symbmin = (symbmin / 100) * 65536; |
| symbmin /= (intp->mclk / 100); |
| |
| symb = (coarse_srate / 100) * 65536; |
| symb /= (intp->mclk / 100); |
| } |
| |
| symbcomp = 13 * (coarse_srate / 10); |
| coarse_freq = (stv0900_read_reg(intp, CFR2) << 8) |
| | stv0900_read_reg(intp, CFR1); |
| |
| if (symbcomp < intp->symbol_rate[demod]) |
| coarse_srate = 0; |
| else { |
| stv0900_write_reg(intp, DMDISTATE, 0x1f); |
| stv0900_write_reg(intp, TMGCFG2, 0xc1); |
| stv0900_write_reg(intp, TMGTHRISE, 0x20); |
| stv0900_write_reg(intp, TMGTHFALL, 0x00); |
| stv0900_write_reg(intp, TMGCFG, 0xd2); |
| stv0900_write_bits(intp, CFR_AUTOSCAN, 0); |
| stv0900_write_reg(intp, AGC2REF, 0x38); |
| |
| if (intp->chip_id >= 0x30) |
| stv0900_write_reg(intp, CARFREQ, 0x79); |
| else if (intp->chip_id >= 0x20) |
| stv0900_write_reg(intp, CARFREQ, 0x49); |
| else |
| stv0900_write_reg(intp, CARFREQ, 0xed); |
| |
| stv0900_write_reg(intp, SFRUP1, (symbmax >> 8) & 0x7f); |
| stv0900_write_reg(intp, SFRUP0, (symbmax & 0xff)); |
| |
| stv0900_write_reg(intp, SFRLOW1, (symbmin >> 8) & 0x7f); |
| stv0900_write_reg(intp, SFRLOW0, (symbmin & 0xff)); |
| |
| stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0xff); |
| stv0900_write_reg(intp, SFRINIT0, (symb & 0xff)); |
| |
| stv0900_write_reg(intp, DMDT0M, 0x20); |
| stv0900_write_reg(intp, CFRINIT1, (coarse_freq >> 8) & 0xff); |
| stv0900_write_reg(intp, CFRINIT0, coarse_freq & 0xff); |
| stv0900_write_reg(intp, DMDISTATE, 0x15); |
| } |
| |
| return coarse_srate; |
| } |
| |
| static int stv0900_blind_search_algo(struct dvb_frontend *fe) |
| { |
| struct stv0900_state *state = fe->demodulator_priv; |
| struct stv0900_internal *intp = 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, |
| agc2_th; |
| int lock = FALSE, |
| coarse_fail = FALSE; |
| s32 demod_timeout = 500, |
| fec_timeout = 50, |
| fail_cpt, |
| i, |
| agc2_overflow; |
| u16 agc2_int; |
| u8 dstatus2; |
| |
| dprintk("%s\n", __func__); |
| |
| if (intp->chip_id < 0x20) { |
| k_ref_tmg_max = 233; |
| k_ref_tmg_min = 143; |
| } else { |
| k_ref_tmg_max = 110; |
| k_ref_tmg_min = 10; |
| } |
| |
| if (intp->chip_id <= 0x20) |
| agc2_th = STV0900_BLIND_SEARCH_AGC2_TH; |
| else |
| agc2_th = STV0900_BLIND_SEARCH_AGC2_TH_CUT30; |
| |
| agc2_int = stv0900_blind_check_agc2_min_level(intp, demod); |
| |
| dprintk("%s agc2_int=%d agc2_th=%d \n", __func__, agc2_int, agc2_th); |
| if (agc2_int > agc2_th) |
| return FALSE; |
| |
| if (intp->chip_id == 0x10) |
| stv0900_write_reg(intp, CORRELEXP, 0xaa); |
| |
| if (intp->chip_id < 0x20) |
| stv0900_write_reg(intp, CARHDR, 0x55); |
| else |
| stv0900_write_reg(intp, CARHDR, 0x20); |
| |
| if (intp->chip_id <= 0x20) |
| stv0900_write_reg(intp, CARCFG, 0xc4); |
| else |
| stv0900_write_reg(intp, CARCFG, 0x6); |
| |
| stv0900_write_reg(intp, RTCS2, 0x44); |
| |
| if (intp->chip_id >= 0x20) { |
| stv0900_write_reg(intp, EQUALCFG, 0x41); |
| stv0900_write_reg(intp, FFECFG, 0x41); |
| stv0900_write_reg(intp, VITSCALE, 0x82); |
| stv0900_write_reg(intp, VAVSRVIT, 0x0); |
| } |
| |
| k_ref_tmg = k_ref_tmg_max; |
| |
| do { |
| stv0900_write_reg(intp, KREFTMG, k_ref_tmg); |
| if (stv0900_search_srate_coarse(fe) != 0) { |
| coarse_srate = stv0900_search_srate_fine(fe); |
| |
| if (coarse_srate != 0) { |
| stv0900_get_lock_timeout(&demod_timeout, |
| &fec_timeout, |
| coarse_srate, |
| STV0900_BLIND_SEARCH); |
| lock = stv0900_get_demod_lock(intp, |
| demod, |
| demod_timeout); |
| } else |
| lock = FALSE; |
| } else { |
| fail_cpt = 0; |
| agc2_overflow = 0; |
| |
| for (i = 0; i < 10; i++) { |
| agc2_int = (stv0900_read_reg(intp, AGC2I1) << 8) |
| | stv0900_read_reg(intp, AGC2I0); |
| |
| if (agc2_int >= 0xff00) |
| agc2_overflow++; |
| |
| dstatus2 = stv0900_read_reg(intp, DSTATUS2); |
| |
| if (((dstatus2 & 0x1) == 0x1) && |
| ((dstatus2 >> 7) == 1)) |
| fail_cpt++; |
| } |
| |
| 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 *intp, |
| enum fe_stv0900_demod_num demod) |
| { |
| s32 vth_reg = VTH12; |
| |
| dprintk("%s\n", __func__); |
| |
| stv0900_write_reg(intp, vth_reg++, 0x96); |
| stv0900_write_reg(intp, vth_reg++, 0x64); |
| stv0900_write_reg(intp, vth_reg++, 0x36); |
| stv0900_write_reg(intp, vth_reg++, 0x23); |
| stv0900_write_reg(intp, vth_reg++, 0x1e); |
| stv0900_write_reg(intp, vth_reg++, 0x19); |
| } |
| |
| static void stv0900_set_search_standard(struct stv0900_internal *intp, |
| enum fe_stv0900_demod_num demod) |
| { |
| |
| dprintk("%s\n", __func__); |
| |
| switch (intp->srch_standard[demod]) { |
| case STV0900_SEARCH_DVBS1: |
| dprintk("Search Standard = DVBS1\n"); |
| break; |
| case STV0900_SEARCH_DSS: |
| dprintk("Search Standard = DSS\n"); |
| break; |
| case STV0900_SEARCH_DVBS2: |
| dprintk("Search Standard = DVBS2\n"); |
| break; |
| case STV0900_AUTO_SEARCH: |
| default: |
| dprintk("Search Standard = AUTO\n"); |
| break; |
| } |
| |
| switch (intp->srch_standard[demod]) { |
| case STV0900_SEARCH_DVBS1: |
| case STV0900_SEARCH_DSS: |
| stv0900_write_bits(intp, DVBS1_ENABLE, 1); |
| stv0900_write_bits(intp, DVBS2_ENABLE, 0); |
| stv0900_write_bits(intp, STOP_CLKVIT, 0); |
| stv0900_set_dvbs1_track_car_loop(intp, |
| demod, |
| intp->symbol_rate[demod]); |
| stv0900_write_reg(intp, CAR2CFG, 0x22); |
| |
| stv0900_set_viterbi_acq(intp, demod); |
| stv0900_set_viterbi_standard(intp, |
| intp->srch_standard[demod], |
| intp->fec[demod], demod); |
| |
| break; |
| case STV0900_SEARCH_DVBS2: |
| stv0900_write_bits(intp, DVBS1_ENABLE, 0); |
| stv0900_write_bits(intp, DVBS2_ENABLE, 1); |
| stv0900_write_bits(intp, STOP_CLKVIT, 1); |
| stv0900_write_reg(intp, ACLC, 0x1a); |
| stv0900_write_reg(intp, BCLC, 0x09); |
| if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/ |
| stv0900_write_reg(intp, CAR2CFG, 0x26); |
| else |
| stv0900_write_reg(intp, CAR2CFG, 0x66); |
| |
| if (intp->demod_mode != STV0900_SINGLE) { |
| if (intp->chip_id <= 0x11) |
| stv0900_stop_all_s2_modcod(intp, demod); |
| else |
| stv0900_activate_s2_modcod(intp, demod); |
| |
| } else |
| stv0900_activate_s2_modcod_single(intp, demod); |
| |
| stv0900_set_viterbi_tracq(intp, demod); |
| |
| break; |
| case STV0900_AUTO_SEARCH: |
| default: |
| stv0900_write_bits(intp, DVBS1_ENABLE, 1); |
| stv0900_write_bits(intp, DVBS2_ENABLE, 1); |
| stv0900_write_bits(intp, STOP_CLKVIT, 0); |
| stv0900_write_reg(intp, ACLC, 0x1a); |
| stv0900_write_reg(intp, BCLC, 0x09); |
| stv0900_set_dvbs1_track_car_loop(intp, |
| demod, |
| intp->symbol_rate[demod]); |
| if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/ |
| stv0900_write_reg(intp, CAR2CFG, 0x26); |
| else |
| stv0900_write_reg(intp, CAR2CFG, 0x66); |
| |
| if (intp->demod_mode != STV0900_SINGLE) { |
| if (intp->chip_id <= 0x11) |
| stv0900_stop_all_s2_modcod(intp, demod); |
| else |
| stv0900_activate_s2_modcod(intp, demod); |
| |
| } else |
| stv0900_activate_s2_modcod_single(intp, demod); |
| |
| stv0900_set_viterbi_tracq(intp, demod); |
| stv0900_set_viterbi_standard(intp, |
| intp->srch_standard[demod], |
| intp->fec[demod], demod); |
| |
| break; |
| } |
| } |
| |
| enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe) |
| { |
| struct stv0900_state *state = fe->demodulator_priv; |
| struct stv0900_internal *intp = state->internal; |
| enum fe_stv0900_demod_num demod = state->demod; |
| |
| s32 demod_timeout = 500, fec_timeout = 50; |
| s32 aq_power, agc1_power, i; |
| |
| 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("%s\n", __func__); |
| |
| algo = intp->srch_algo[demod]; |
| stv0900_write_bits(intp, RST_HWARE, 1); |
| stv0900_write_reg(intp, DMDISTATE, 0x5c); |
| if (intp->chip_id >= 0x20) { |
| if (intp->symbol_rate[demod] > 5000000) |
| stv0900_write_reg(intp, CORRELABS, 0x9e); |
| else |
| stv0900_write_reg(intp, CORRELABS, 0x82); |
| } else |
| stv0900_write_reg(intp, CORRELABS, 0x88); |
| |
| stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, |
| intp->symbol_rate[demod], |
| intp->srch_algo[demod]); |
| |
| if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) { |
| intp->bw[demod] = 2 * 36000000; |
| |
| stv0900_write_reg(intp, TMGCFG2, 0xc0); |
| stv0900_write_reg(intp, CORRELMANT, 0x70); |
| |
| stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod); |
| } else { |
| stv0900_write_reg(intp, DMDT0M, 0x20); |
| stv0900_write_reg(intp, TMGCFG, 0xd2); |
| |
| if (intp->symbol_rate[demod] < 2000000) |
| stv0900_write_reg(intp, CORRELMANT, 0x63); |
| else |
| stv0900_write_reg(intp, CORRELMANT, 0x70); |
| |
| stv0900_write_reg(intp, AGC2REF, 0x38); |
| |
| intp->bw[demod] = |
| stv0900_carrier_width(intp->symbol_rate[demod], |
| intp->rolloff); |
| if (intp->chip_id >= 0x20) { |
| stv0900_write_reg(intp, KREFTMG, 0x5a); |
| |
| if (intp->srch_algo[demod] == STV0900_COLD_START) { |
| intp->bw[demod] += 10000000; |
| intp->bw[demod] *= 15; |
| intp->bw[demod] /= 10; |
| } else if (intp->srch_algo[demod] == STV0900_WARM_START) |
| intp->bw[demod] += 10000000; |
| |
| } else { |
| stv0900_write_reg(intp, KREFTMG, 0xc1); |
| intp->bw[demod] += 10000000; |
| intp->bw[demod] *= 15; |
| intp->bw[demod] /= 10; |
| } |
| |
| stv0900_write_reg(intp, TMGCFG2, 0xc1); |
| |
| stv0900_set_symbol_rate(intp, intp->mclk, |
| intp->symbol_rate[demod], demod); |
| stv0900_set_max_symbol_rate(intp, intp->mclk, |
| intp->symbol_rate[demod], demod); |
| stv0900_set_min_symbol_rate(intp, intp->mclk, |
| intp->symbol_rate[demod], demod); |
| if (intp->symbol_rate[demod] >= 10000000) |
| low_sr = FALSE; |
| else |
| low_sr = TRUE; |
| |
| } |
| |
| if (intp->tuner_type[demod] == 3) |
| stv0900_set_tuner_auto(intp, intp->freq[demod], |
| intp->bw[demod], demod); |
| else |
| stv0900_set_tuner(fe, intp->freq[demod], intp->bw[demod]); |
| |
| agc1_power = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1), |
| stv0900_get_bits(intp, AGCIQ_VALUE0)); |
| |
| aq_power = 0; |
| |
| if (agc1_power == 0) { |
| for (i = 0; i < 5; i++) |
| aq_power += (stv0900_get_bits(intp, POWER_I) + |
| stv0900_get_bits(intp, POWER_Q)) / 2; |
| |
| aq_power /= 5; |
| } |
| |
| if ((agc1_power == 0) && (aq_power < IQPOWER_THRESHOLD)) { |
| intp->result[demod].locked = FALSE; |
| signal_type = STV0900_NOAGC1; |
| dprintk("%s: NO AGC1, POWERI, POWERQ\n", __func__); |
| } else { |
| stv0900_write_bits(intp, SPECINV_CONTROL, |
| intp->srch_iq_inv[demod]); |
| if (intp->chip_id <= 0x20) /*cut 2.0*/ |
| stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1); |
| else /*cut 3.0*/ |
| stv0900_write_bits(intp, MANUALS2_ROLLOFF, 1); |
| |
| stv0900_set_search_standard(intp, demod); |
| |
| if (intp->srch_algo[demod] != STV0900_BLIND_SEARCH) |
| stv0900_start_search(intp, demod); |
| } |
| |
| if (signal_type == STV0900_NOAGC1) |
| return signal_type; |
| |
| if (intp->chip_id == 0x12) { |
| stv0900_write_bits(intp, RST_HWARE, 0); |
| msleep(3); |
| stv0900_write_bits(intp, RST_HWARE, 1); |
| stv0900_write_bits(intp, RST_HWARE, 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(intp, demod, demod_timeout); |
| |
| if ((lock == FALSE) && (algo == STV0900_COLD_START)) { |
| if (low_sr == FALSE) { |
| if (stv0900_check_timing_lock(intp, demod) == TRUE) |
| lock = stv0900_sw_algo(intp, demod); |
| } |
| } |
| |
| if (lock == TRUE) |
| signal_type = stv0900_get_signal_params(fe); |
| |
| if ((lock == TRUE) && (signal_type == STV0900_RANGEOK)) { |
| stv0900_track_optimization(fe); |
| if (intp->chip_id <= 0x11) { |
| if ((stv0900_get_standard(fe, 0) == |
| STV0900_DVBS1_STANDARD) && |
| (stv0900_get_standard(fe, 1) == |
| STV0900_DVBS1_STANDARD)) { |
| msleep(20); |
| stv0900_write_bits(intp, RST_HWARE, 0); |
| } else { |
| stv0900_write_bits(intp, RST_HWARE, 0); |
| msleep(3); |
| stv0900_write_bits(intp, RST_HWARE, 1); |
| stv0900_write_bits(intp, RST_HWARE, 0); |
| } |
| |
| } else if (intp->chip_id >= 0x20) { |
| stv0900_write_bits(intp, RST_HWARE, 0); |
| msleep(3); |
| stv0900_write_bits(intp, RST_HWARE, 1); |
| stv0900_write_bits(intp, RST_HWARE, 0); |
| } |
| |
| if (stv0900_wait_for_lock(intp, demod, |
| fec_timeout, fec_timeout) == TRUE) { |
| lock = TRUE; |
| intp->result[demod].locked = TRUE; |
| if (intp->result[demod].standard == |
| STV0900_DVBS2_STANDARD) { |
| stv0900_set_dvbs2_rolloff(intp, demod); |
| stv0900_write_bits(intp, RESET_UPKO_COUNT, 1); |
| stv0900_write_bits(intp, RESET_UPKO_COUNT, 0); |
| stv0900_write_reg(intp, ERRCTRL1, 0x67); |
| } else { |
| stv0900_write_reg(intp, ERRCTRL1, 0x75); |
| } |
| |
| stv0900_write_reg(intp, FBERCPT4, 0); |
| stv0900_write_reg(intp, ERRCTRL2, 0xc1); |
| } else { |
| lock = FALSE; |
| signal_type = STV0900_NODATA; |
| no_signal = stv0900_check_signal_presence(intp, demod); |
| |
| intp->result[demod].locked = FALSE; |
| } |
| } |
| |
| if ((signal_type != STV0900_NODATA) || (no_signal != FALSE)) |
| return signal_type; |
| |
| if (intp->chip_id > 0x11) { |
| intp->result[demod].locked = FALSE; |
| return signal_type; |
| } |
| |
| if ((stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) && |
| (intp->srch_iq_inv[demod] <= STV0900_IQ_AUTO_NORMAL_FIRST)) |
| signal_type = stv0900_dvbs1_acq_workaround(fe); |
| |
| return signal_type; |
| } |
| |