18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * stv0900_sw.c
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Driver for ST STV0900 satellite demodulator IC.
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Copyright (C) ST Microelectronics.
88c2ecf20Sopenharmony_ci * Copyright (C) 2009 NetUP Inc.
98c2ecf20Sopenharmony_ci * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include "stv0900.h"
138c2ecf20Sopenharmony_ci#include "stv0900_reg.h"
148c2ecf20Sopenharmony_ci#include "stv0900_priv.h"
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_cis32 shiftx(s32 x, int demod, s32 shift)
178c2ecf20Sopenharmony_ci{
188c2ecf20Sopenharmony_ci	if (demod == 1)
198c2ecf20Sopenharmony_ci		return x - shift;
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci	return x;
228c2ecf20Sopenharmony_ci}
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ciint stv0900_check_signal_presence(struct stv0900_internal *intp,
258c2ecf20Sopenharmony_ci					enum fe_stv0900_demod_num demod)
268c2ecf20Sopenharmony_ci{
278c2ecf20Sopenharmony_ci	s32	carr_offset,
288c2ecf20Sopenharmony_ci		agc2_integr,
298c2ecf20Sopenharmony_ci		max_carrier;
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci	int no_signal = FALSE;
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci	carr_offset = (stv0900_read_reg(intp, CFR2) << 8)
348c2ecf20Sopenharmony_ci					| stv0900_read_reg(intp, CFR1);
358c2ecf20Sopenharmony_ci	carr_offset = ge2comp(carr_offset, 16);
368c2ecf20Sopenharmony_ci	agc2_integr = (stv0900_read_reg(intp, AGC2I1) << 8)
378c2ecf20Sopenharmony_ci					| stv0900_read_reg(intp, AGC2I0);
388c2ecf20Sopenharmony_ci	max_carrier = intp->srch_range[demod] / 1000;
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci	max_carrier += (max_carrier / 10);
418c2ecf20Sopenharmony_ci	max_carrier = 65536 * (max_carrier / 2);
428c2ecf20Sopenharmony_ci	max_carrier /= intp->mclk / 1000;
438c2ecf20Sopenharmony_ci	if (max_carrier > 0x4000)
448c2ecf20Sopenharmony_ci		max_carrier = 0x4000;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	if ((agc2_integr > 0x2000)
478c2ecf20Sopenharmony_ci			|| (carr_offset > (2 * max_carrier))
488c2ecf20Sopenharmony_ci			|| (carr_offset < (-2 * max_carrier)))
498c2ecf20Sopenharmony_ci		no_signal = TRUE;
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	return no_signal;
528c2ecf20Sopenharmony_ci}
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_cistatic void stv0900_get_sw_loop_params(struct stv0900_internal *intp,
558c2ecf20Sopenharmony_ci				s32 *frequency_inc, s32 *sw_timeout,
568c2ecf20Sopenharmony_ci				s32 *steps,
578c2ecf20Sopenharmony_ci				enum fe_stv0900_demod_num demod)
588c2ecf20Sopenharmony_ci{
598c2ecf20Sopenharmony_ci	s32 timeout, freq_inc, max_steps, srate, max_carrier;
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	enum fe_stv0900_search_standard	standard;
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci	srate = intp->symbol_rate[demod];
648c2ecf20Sopenharmony_ci	max_carrier = intp->srch_range[demod] / 1000;
658c2ecf20Sopenharmony_ci	max_carrier += max_carrier / 10;
668c2ecf20Sopenharmony_ci	standard = intp->srch_standard[demod];
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	max_carrier = 65536 * (max_carrier / 2);
698c2ecf20Sopenharmony_ci	max_carrier /= intp->mclk / 1000;
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	if (max_carrier > 0x4000)
728c2ecf20Sopenharmony_ci		max_carrier = 0x4000;
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci	freq_inc = srate;
758c2ecf20Sopenharmony_ci	freq_inc /= intp->mclk >> 10;
768c2ecf20Sopenharmony_ci	freq_inc = freq_inc << 6;
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	switch (standard) {
798c2ecf20Sopenharmony_ci	case STV0900_SEARCH_DVBS1:
808c2ecf20Sopenharmony_ci	case STV0900_SEARCH_DSS:
818c2ecf20Sopenharmony_ci		freq_inc *= 3;
828c2ecf20Sopenharmony_ci		timeout = 20;
838c2ecf20Sopenharmony_ci		break;
848c2ecf20Sopenharmony_ci	case STV0900_SEARCH_DVBS2:
858c2ecf20Sopenharmony_ci		freq_inc *= 4;
868c2ecf20Sopenharmony_ci		timeout = 25;
878c2ecf20Sopenharmony_ci		break;
888c2ecf20Sopenharmony_ci	case STV0900_AUTO_SEARCH:
898c2ecf20Sopenharmony_ci	default:
908c2ecf20Sopenharmony_ci		freq_inc *= 3;
918c2ecf20Sopenharmony_ci		timeout = 25;
928c2ecf20Sopenharmony_ci		break;
938c2ecf20Sopenharmony_ci	}
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci	freq_inc /= 100;
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci	if ((freq_inc > max_carrier) || (freq_inc < 0))
988c2ecf20Sopenharmony_ci		freq_inc = max_carrier / 2;
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci	timeout *= 27500;
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci	if (srate > 0)
1038c2ecf20Sopenharmony_ci		timeout /= srate / 1000;
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	if ((timeout > 100) || (timeout < 0))
1068c2ecf20Sopenharmony_ci		timeout = 100;
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci	max_steps = (max_carrier / freq_inc) + 1;
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci	if ((max_steps > 100) || (max_steps < 0)) {
1118c2ecf20Sopenharmony_ci		max_steps =  100;
1128c2ecf20Sopenharmony_ci		freq_inc = max_carrier / max_steps;
1138c2ecf20Sopenharmony_ci	}
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	*frequency_inc = freq_inc;
1168c2ecf20Sopenharmony_ci	*sw_timeout = timeout;
1178c2ecf20Sopenharmony_ci	*steps = max_steps;
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci}
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_cistatic int stv0900_search_carr_sw_loop(struct stv0900_internal *intp,
1228c2ecf20Sopenharmony_ci				s32 FreqIncr, s32 Timeout, int zigzag,
1238c2ecf20Sopenharmony_ci				s32 MaxStep, enum fe_stv0900_demod_num demod)
1248c2ecf20Sopenharmony_ci{
1258c2ecf20Sopenharmony_ci	int	no_signal,
1268c2ecf20Sopenharmony_ci		lock = FALSE;
1278c2ecf20Sopenharmony_ci	s32	stepCpt,
1288c2ecf20Sopenharmony_ci		freqOffset,
1298c2ecf20Sopenharmony_ci		max_carrier;
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci	max_carrier = intp->srch_range[demod] / 1000;
1328c2ecf20Sopenharmony_ci	max_carrier += (max_carrier / 10);
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci	max_carrier = 65536 * (max_carrier / 2);
1358c2ecf20Sopenharmony_ci	max_carrier /= intp->mclk / 1000;
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci	if (max_carrier > 0x4000)
1388c2ecf20Sopenharmony_ci		max_carrier = 0x4000;
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	if (zigzag == TRUE)
1418c2ecf20Sopenharmony_ci		freqOffset = 0;
1428c2ecf20Sopenharmony_ci	else
1438c2ecf20Sopenharmony_ci		freqOffset = -max_carrier + FreqIncr;
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci	stepCpt = 0;
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci	do {
1488c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, DMDISTATE, 0x1c);
1498c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CFRINIT1, (freqOffset / 256) & 0xff);
1508c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CFRINIT0, freqOffset & 0xff);
1518c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, DMDISTATE, 0x18);
1528c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, ALGOSWRST, 1);
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci		if (intp->chip_id == 0x12) {
1558c2ecf20Sopenharmony_ci			stv0900_write_bits(intp, RST_HWARE, 1);
1568c2ecf20Sopenharmony_ci			stv0900_write_bits(intp, RST_HWARE, 0);
1578c2ecf20Sopenharmony_ci		}
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci		if (zigzag == TRUE) {
1608c2ecf20Sopenharmony_ci			if (freqOffset >= 0)
1618c2ecf20Sopenharmony_ci				freqOffset = -freqOffset - 2 * FreqIncr;
1628c2ecf20Sopenharmony_ci			else
1638c2ecf20Sopenharmony_ci				freqOffset = -freqOffset;
1648c2ecf20Sopenharmony_ci		} else
1658c2ecf20Sopenharmony_ci			freqOffset += + 2 * FreqIncr;
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci		stepCpt++;
1688c2ecf20Sopenharmony_ci		lock = stv0900_get_demod_lock(intp, demod, Timeout);
1698c2ecf20Sopenharmony_ci		no_signal = stv0900_check_signal_presence(intp, demod);
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ci	} while ((lock == FALSE)
1728c2ecf20Sopenharmony_ci			&& (no_signal == FALSE)
1738c2ecf20Sopenharmony_ci			&& ((freqOffset - FreqIncr) <  max_carrier)
1748c2ecf20Sopenharmony_ci			&& ((freqOffset + FreqIncr) > -max_carrier)
1758c2ecf20Sopenharmony_ci			&& (stepCpt < MaxStep));
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ci	stv0900_write_bits(intp, ALGOSWRST, 0);
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci	return lock;
1808c2ecf20Sopenharmony_ci}
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_cistatic int stv0900_sw_algo(struct stv0900_internal *intp,
1838c2ecf20Sopenharmony_ci				enum fe_stv0900_demod_num demod)
1848c2ecf20Sopenharmony_ci{
1858c2ecf20Sopenharmony_ci	int	lock = FALSE,
1868c2ecf20Sopenharmony_ci		no_signal,
1878c2ecf20Sopenharmony_ci		zigzag;
1888c2ecf20Sopenharmony_ci	s32	s2fw,
1898c2ecf20Sopenharmony_ci		fqc_inc,
1908c2ecf20Sopenharmony_ci		sft_stp_tout,
1918c2ecf20Sopenharmony_ci		trial_cntr,
1928c2ecf20Sopenharmony_ci		max_steps;
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ci	stv0900_get_sw_loop_params(intp, &fqc_inc, &sft_stp_tout,
1958c2ecf20Sopenharmony_ci					&max_steps, demod);
1968c2ecf20Sopenharmony_ci	switch (intp->srch_standard[demod]) {
1978c2ecf20Sopenharmony_ci	case STV0900_SEARCH_DVBS1:
1988c2ecf20Sopenharmony_ci	case STV0900_SEARCH_DSS:
1998c2ecf20Sopenharmony_ci		if (intp->chip_id >= 0x20)
2008c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CARFREQ, 0x3b);
2018c2ecf20Sopenharmony_ci		else
2028c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CARFREQ, 0xef);
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, DMDCFGMD, 0x49);
2058c2ecf20Sopenharmony_ci		zigzag = FALSE;
2068c2ecf20Sopenharmony_ci		break;
2078c2ecf20Sopenharmony_ci	case STV0900_SEARCH_DVBS2:
2088c2ecf20Sopenharmony_ci		if (intp->chip_id >= 0x20)
2098c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CORRELABS, 0x79);
2108c2ecf20Sopenharmony_ci		else
2118c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CORRELABS, 0x68);
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, DMDCFGMD, 0x89);
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci		zigzag = TRUE;
2168c2ecf20Sopenharmony_ci		break;
2178c2ecf20Sopenharmony_ci	case STV0900_AUTO_SEARCH:
2188c2ecf20Sopenharmony_ci	default:
2198c2ecf20Sopenharmony_ci		if (intp->chip_id >= 0x20) {
2208c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CARFREQ, 0x3b);
2218c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CORRELABS, 0x79);
2228c2ecf20Sopenharmony_ci		} else {
2238c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CARFREQ, 0xef);
2248c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CORRELABS, 0x68);
2258c2ecf20Sopenharmony_ci		}
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, DMDCFGMD, 0xc9);
2288c2ecf20Sopenharmony_ci		zigzag = FALSE;
2298c2ecf20Sopenharmony_ci		break;
2308c2ecf20Sopenharmony_ci	}
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ci	trial_cntr = 0;
2338c2ecf20Sopenharmony_ci	do {
2348c2ecf20Sopenharmony_ci		lock = stv0900_search_carr_sw_loop(intp,
2358c2ecf20Sopenharmony_ci						fqc_inc,
2368c2ecf20Sopenharmony_ci						sft_stp_tout,
2378c2ecf20Sopenharmony_ci						zigzag,
2388c2ecf20Sopenharmony_ci						max_steps,
2398c2ecf20Sopenharmony_ci						demod);
2408c2ecf20Sopenharmony_ci		no_signal = stv0900_check_signal_presence(intp, demod);
2418c2ecf20Sopenharmony_ci		trial_cntr++;
2428c2ecf20Sopenharmony_ci		if ((lock == TRUE)
2438c2ecf20Sopenharmony_ci				|| (no_signal == TRUE)
2448c2ecf20Sopenharmony_ci				|| (trial_cntr == 2)) {
2458c2ecf20Sopenharmony_ci
2468c2ecf20Sopenharmony_ci			if (intp->chip_id >= 0x20) {
2478c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, CARFREQ, 0x49);
2488c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, CORRELABS, 0x9e);
2498c2ecf20Sopenharmony_ci			} else {
2508c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, CARFREQ, 0xed);
2518c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, CORRELABS, 0x88);
2528c2ecf20Sopenharmony_ci			}
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_ci			if ((stv0900_get_bits(intp, HEADER_MODE) ==
2558c2ecf20Sopenharmony_ci						STV0900_DVBS2_FOUND) &&
2568c2ecf20Sopenharmony_ci							(lock == TRUE)) {
2578c2ecf20Sopenharmony_ci				msleep(sft_stp_tout);
2588c2ecf20Sopenharmony_ci				s2fw = stv0900_get_bits(intp, FLYWHEEL_CPT);
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci				if (s2fw < 0xd) {
2618c2ecf20Sopenharmony_ci					msleep(sft_stp_tout);
2628c2ecf20Sopenharmony_ci					s2fw = stv0900_get_bits(intp,
2638c2ecf20Sopenharmony_ci								FLYWHEEL_CPT);
2648c2ecf20Sopenharmony_ci				}
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_ci				if (s2fw < 0xd) {
2678c2ecf20Sopenharmony_ci					lock = FALSE;
2688c2ecf20Sopenharmony_ci
2698c2ecf20Sopenharmony_ci					if (trial_cntr < 2) {
2708c2ecf20Sopenharmony_ci						if (intp->chip_id >= 0x20)
2718c2ecf20Sopenharmony_ci							stv0900_write_reg(intp,
2728c2ecf20Sopenharmony_ci								CORRELABS,
2738c2ecf20Sopenharmony_ci								0x79);
2748c2ecf20Sopenharmony_ci						else
2758c2ecf20Sopenharmony_ci							stv0900_write_reg(intp,
2768c2ecf20Sopenharmony_ci								CORRELABS,
2778c2ecf20Sopenharmony_ci								0x68);
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci						stv0900_write_reg(intp,
2808c2ecf20Sopenharmony_ci								DMDCFGMD,
2818c2ecf20Sopenharmony_ci								0x89);
2828c2ecf20Sopenharmony_ci					}
2838c2ecf20Sopenharmony_ci				}
2848c2ecf20Sopenharmony_ci			}
2858c2ecf20Sopenharmony_ci		}
2868c2ecf20Sopenharmony_ci
2878c2ecf20Sopenharmony_ci	} while ((lock == FALSE)
2888c2ecf20Sopenharmony_ci		&& (trial_cntr < 2)
2898c2ecf20Sopenharmony_ci		&& (no_signal == FALSE));
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_ci	return lock;
2928c2ecf20Sopenharmony_ci}
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_cistatic u32 stv0900_get_symbol_rate(struct stv0900_internal *intp,
2958c2ecf20Sopenharmony_ci					u32 mclk,
2968c2ecf20Sopenharmony_ci					enum fe_stv0900_demod_num demod)
2978c2ecf20Sopenharmony_ci{
2988c2ecf20Sopenharmony_ci	s32	rem1, rem2, intval1, intval2, srate;
2998c2ecf20Sopenharmony_ci
3008c2ecf20Sopenharmony_ci	srate = (stv0900_get_bits(intp, SYMB_FREQ3) << 24) +
3018c2ecf20Sopenharmony_ci		(stv0900_get_bits(intp, SYMB_FREQ2) << 16) +
3028c2ecf20Sopenharmony_ci		(stv0900_get_bits(intp, SYMB_FREQ1) << 8) +
3038c2ecf20Sopenharmony_ci		(stv0900_get_bits(intp, SYMB_FREQ0));
3048c2ecf20Sopenharmony_ci	dprintk("lock: srate=%d r0=0x%x r1=0x%x r2=0x%x r3=0x%x \n",
3058c2ecf20Sopenharmony_ci		srate, stv0900_get_bits(intp, SYMB_FREQ0),
3068c2ecf20Sopenharmony_ci		stv0900_get_bits(intp, SYMB_FREQ1),
3078c2ecf20Sopenharmony_ci		stv0900_get_bits(intp, SYMB_FREQ2),
3088c2ecf20Sopenharmony_ci		stv0900_get_bits(intp, SYMB_FREQ3));
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_ci	intval1 = (mclk) >> 16;
3118c2ecf20Sopenharmony_ci	intval2 = (srate) >> 16;
3128c2ecf20Sopenharmony_ci
3138c2ecf20Sopenharmony_ci	rem1 = (mclk) % 0x10000;
3148c2ecf20Sopenharmony_ci	rem2 = (srate) % 0x10000;
3158c2ecf20Sopenharmony_ci	srate =	(intval1 * intval2) +
3168c2ecf20Sopenharmony_ci		((intval1 * rem2) >> 16) +
3178c2ecf20Sopenharmony_ci		((intval2 * rem1) >> 16);
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_ci	return srate;
3208c2ecf20Sopenharmony_ci}
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_cistatic void stv0900_set_symbol_rate(struct stv0900_internal *intp,
3238c2ecf20Sopenharmony_ci					u32 mclk, u32 srate,
3248c2ecf20Sopenharmony_ci					enum fe_stv0900_demod_num demod)
3258c2ecf20Sopenharmony_ci{
3268c2ecf20Sopenharmony_ci	u32 symb;
3278c2ecf20Sopenharmony_ci
3288c2ecf20Sopenharmony_ci	dprintk("%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk,
3298c2ecf20Sopenharmony_ci							srate, demod);
3308c2ecf20Sopenharmony_ci
3318c2ecf20Sopenharmony_ci	if (srate > 60000000) {
3328c2ecf20Sopenharmony_ci		symb = srate << 4;
3338c2ecf20Sopenharmony_ci		symb /= (mclk >> 12);
3348c2ecf20Sopenharmony_ci	} else if (srate > 6000000) {
3358c2ecf20Sopenharmony_ci		symb = srate << 6;
3368c2ecf20Sopenharmony_ci		symb /= (mclk >> 10);
3378c2ecf20Sopenharmony_ci	} else {
3388c2ecf20Sopenharmony_ci		symb = srate << 9;
3398c2ecf20Sopenharmony_ci		symb /= (mclk >> 7);
3408c2ecf20Sopenharmony_ci	}
3418c2ecf20Sopenharmony_ci
3428c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0x7f);
3438c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, SFRINIT1 + 1, (symb & 0xff));
3448c2ecf20Sopenharmony_ci}
3458c2ecf20Sopenharmony_ci
3468c2ecf20Sopenharmony_cistatic void stv0900_set_max_symbol_rate(struct stv0900_internal *intp,
3478c2ecf20Sopenharmony_ci					u32 mclk, u32 srate,
3488c2ecf20Sopenharmony_ci					enum fe_stv0900_demod_num demod)
3498c2ecf20Sopenharmony_ci{
3508c2ecf20Sopenharmony_ci	u32 symb;
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_ci	srate = 105 * (srate / 100);
3538c2ecf20Sopenharmony_ci
3548c2ecf20Sopenharmony_ci	if (srate > 60000000) {
3558c2ecf20Sopenharmony_ci		symb = srate << 4;
3568c2ecf20Sopenharmony_ci		symb /= (mclk >> 12);
3578c2ecf20Sopenharmony_ci	} else if (srate > 6000000) {
3588c2ecf20Sopenharmony_ci		symb = srate << 6;
3598c2ecf20Sopenharmony_ci		symb /= (mclk >> 10);
3608c2ecf20Sopenharmony_ci	} else {
3618c2ecf20Sopenharmony_ci		symb = srate << 9;
3628c2ecf20Sopenharmony_ci		symb /= (mclk >> 7);
3638c2ecf20Sopenharmony_ci	}
3648c2ecf20Sopenharmony_ci
3658c2ecf20Sopenharmony_ci	if (symb < 0x7fff) {
3668c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, SFRUP1, (symb >> 8) & 0x7f);
3678c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, SFRUP1 + 1, (symb & 0xff));
3688c2ecf20Sopenharmony_ci	} else {
3698c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, SFRUP1, 0x7f);
3708c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, SFRUP1 + 1, 0xff);
3718c2ecf20Sopenharmony_ci	}
3728c2ecf20Sopenharmony_ci}
3738c2ecf20Sopenharmony_ci
3748c2ecf20Sopenharmony_cistatic void stv0900_set_min_symbol_rate(struct stv0900_internal *intp,
3758c2ecf20Sopenharmony_ci					u32 mclk, u32 srate,
3768c2ecf20Sopenharmony_ci					enum fe_stv0900_demod_num demod)
3778c2ecf20Sopenharmony_ci{
3788c2ecf20Sopenharmony_ci	u32	symb;
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci	srate = 95 * (srate / 100);
3818c2ecf20Sopenharmony_ci	if (srate > 60000000) {
3828c2ecf20Sopenharmony_ci		symb = srate << 4;
3838c2ecf20Sopenharmony_ci		symb /= (mclk >> 12);
3848c2ecf20Sopenharmony_ci
3858c2ecf20Sopenharmony_ci	} else if (srate > 6000000) {
3868c2ecf20Sopenharmony_ci		symb = srate << 6;
3878c2ecf20Sopenharmony_ci		symb /= (mclk >> 10);
3888c2ecf20Sopenharmony_ci
3898c2ecf20Sopenharmony_ci	} else {
3908c2ecf20Sopenharmony_ci		symb = srate << 9;
3918c2ecf20Sopenharmony_ci		symb /= (mclk >> 7);
3928c2ecf20Sopenharmony_ci	}
3938c2ecf20Sopenharmony_ci
3948c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, SFRLOW1, (symb >> 8) & 0xff);
3958c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, SFRLOW1 + 1, (symb & 0xff));
3968c2ecf20Sopenharmony_ci}
3978c2ecf20Sopenharmony_ci
3988c2ecf20Sopenharmony_cistatic s32 stv0900_get_timing_offst(struct stv0900_internal *intp,
3998c2ecf20Sopenharmony_ci					u32 srate,
4008c2ecf20Sopenharmony_ci					enum fe_stv0900_demod_num demod)
4018c2ecf20Sopenharmony_ci{
4028c2ecf20Sopenharmony_ci	s32 timingoffset;
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_ci
4058c2ecf20Sopenharmony_ci	timingoffset = (stv0900_read_reg(intp, TMGREG2) << 16) +
4068c2ecf20Sopenharmony_ci		       (stv0900_read_reg(intp, TMGREG2 + 1) << 8) +
4078c2ecf20Sopenharmony_ci		       (stv0900_read_reg(intp, TMGREG2 + 2));
4088c2ecf20Sopenharmony_ci
4098c2ecf20Sopenharmony_ci	timingoffset = ge2comp(timingoffset, 24);
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci
4128c2ecf20Sopenharmony_ci	if (timingoffset == 0)
4138c2ecf20Sopenharmony_ci		timingoffset = 1;
4148c2ecf20Sopenharmony_ci
4158c2ecf20Sopenharmony_ci	timingoffset = ((s32)srate * 10) / ((s32)0x1000000 / timingoffset);
4168c2ecf20Sopenharmony_ci	timingoffset /= 320;
4178c2ecf20Sopenharmony_ci
4188c2ecf20Sopenharmony_ci	return timingoffset;
4198c2ecf20Sopenharmony_ci}
4208c2ecf20Sopenharmony_ci
4218c2ecf20Sopenharmony_cistatic void stv0900_set_dvbs2_rolloff(struct stv0900_internal *intp,
4228c2ecf20Sopenharmony_ci					enum fe_stv0900_demod_num demod)
4238c2ecf20Sopenharmony_ci{
4248c2ecf20Sopenharmony_ci	s32 rolloff;
4258c2ecf20Sopenharmony_ci
4268c2ecf20Sopenharmony_ci	if (intp->chip_id == 0x10) {
4278c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
4288c2ecf20Sopenharmony_ci		rolloff = stv0900_read_reg(intp, MATSTR1) & 0x03;
4298c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, ROLLOFF_CONTROL, rolloff);
4308c2ecf20Sopenharmony_ci	} else if (intp->chip_id <= 0x20)
4318c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, MANUALSX_ROLLOFF, 0);
4328c2ecf20Sopenharmony_ci	else /* cut 3.0 */
4338c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, MANUALS2_ROLLOFF, 0);
4348c2ecf20Sopenharmony_ci}
4358c2ecf20Sopenharmony_ci
4368c2ecf20Sopenharmony_cistatic u32 stv0900_carrier_width(u32 srate, enum fe_stv0900_rolloff ro)
4378c2ecf20Sopenharmony_ci{
4388c2ecf20Sopenharmony_ci	u32 rolloff;
4398c2ecf20Sopenharmony_ci
4408c2ecf20Sopenharmony_ci	switch (ro) {
4418c2ecf20Sopenharmony_ci	case STV0900_20:
4428c2ecf20Sopenharmony_ci		rolloff = 20;
4438c2ecf20Sopenharmony_ci		break;
4448c2ecf20Sopenharmony_ci	case STV0900_25:
4458c2ecf20Sopenharmony_ci		rolloff = 25;
4468c2ecf20Sopenharmony_ci		break;
4478c2ecf20Sopenharmony_ci	case STV0900_35:
4488c2ecf20Sopenharmony_ci	default:
4498c2ecf20Sopenharmony_ci		rolloff = 35;
4508c2ecf20Sopenharmony_ci		break;
4518c2ecf20Sopenharmony_ci	}
4528c2ecf20Sopenharmony_ci
4538c2ecf20Sopenharmony_ci	return srate  + (srate * rolloff) / 100;
4548c2ecf20Sopenharmony_ci}
4558c2ecf20Sopenharmony_ci
4568c2ecf20Sopenharmony_cistatic int stv0900_check_timing_lock(struct stv0900_internal *intp,
4578c2ecf20Sopenharmony_ci				enum fe_stv0900_demod_num demod)
4588c2ecf20Sopenharmony_ci{
4598c2ecf20Sopenharmony_ci	int timingLock = FALSE;
4608c2ecf20Sopenharmony_ci	s32	i,
4618c2ecf20Sopenharmony_ci		timingcpt = 0;
4628c2ecf20Sopenharmony_ci	u8	car_freq,
4638c2ecf20Sopenharmony_ci		tmg_th_high,
4648c2ecf20Sopenharmony_ci		tmg_th_low;
4658c2ecf20Sopenharmony_ci
4668c2ecf20Sopenharmony_ci	car_freq = stv0900_read_reg(intp, CARFREQ);
4678c2ecf20Sopenharmony_ci	tmg_th_high = stv0900_read_reg(intp, TMGTHRISE);
4688c2ecf20Sopenharmony_ci	tmg_th_low = stv0900_read_reg(intp, TMGTHFALL);
4698c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, TMGTHRISE, 0x20);
4708c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, TMGTHFALL, 0x0);
4718c2ecf20Sopenharmony_ci	stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
4728c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, RTC, 0x80);
4738c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, RTCS2, 0x40);
4748c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, CARFREQ, 0x0);
4758c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, CFRINIT1, 0x0);
4768c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, CFRINIT0, 0x0);
4778c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, AGC2REF, 0x65);
4788c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, DMDISTATE, 0x18);
4798c2ecf20Sopenharmony_ci	msleep(7);
4808c2ecf20Sopenharmony_ci
4818c2ecf20Sopenharmony_ci	for (i = 0; i < 10; i++) {
4828c2ecf20Sopenharmony_ci		if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2)
4838c2ecf20Sopenharmony_ci			timingcpt++;
4848c2ecf20Sopenharmony_ci
4858c2ecf20Sopenharmony_ci		msleep(1);
4868c2ecf20Sopenharmony_ci	}
4878c2ecf20Sopenharmony_ci
4888c2ecf20Sopenharmony_ci	if (timingcpt >= 3)
4898c2ecf20Sopenharmony_ci		timingLock = TRUE;
4908c2ecf20Sopenharmony_ci
4918c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, AGC2REF, 0x38);
4928c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, RTC, 0x88);
4938c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, RTCS2, 0x68);
4948c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, CARFREQ, car_freq);
4958c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, TMGTHRISE, tmg_th_high);
4968c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, TMGTHFALL, tmg_th_low);
4978c2ecf20Sopenharmony_ci
4988c2ecf20Sopenharmony_ci	return	timingLock;
4998c2ecf20Sopenharmony_ci}
5008c2ecf20Sopenharmony_ci
5018c2ecf20Sopenharmony_cistatic int stv0900_get_demod_cold_lock(struct dvb_frontend *fe,
5028c2ecf20Sopenharmony_ci					s32 demod_timeout)
5038c2ecf20Sopenharmony_ci{
5048c2ecf20Sopenharmony_ci	struct stv0900_state *state = fe->demodulator_priv;
5058c2ecf20Sopenharmony_ci	struct stv0900_internal *intp = state->internal;
5068c2ecf20Sopenharmony_ci	enum fe_stv0900_demod_num demod = state->demod;
5078c2ecf20Sopenharmony_ci	int	lock = FALSE,
5088c2ecf20Sopenharmony_ci		d = demod;
5098c2ecf20Sopenharmony_ci	s32	srate,
5108c2ecf20Sopenharmony_ci		search_range,
5118c2ecf20Sopenharmony_ci		locktimeout,
5128c2ecf20Sopenharmony_ci		currier_step,
5138c2ecf20Sopenharmony_ci		nb_steps,
5148c2ecf20Sopenharmony_ci		current_step,
5158c2ecf20Sopenharmony_ci		direction,
5168c2ecf20Sopenharmony_ci		tuner_freq,
5178c2ecf20Sopenharmony_ci		timeout,
5188c2ecf20Sopenharmony_ci		freq;
5198c2ecf20Sopenharmony_ci
5208c2ecf20Sopenharmony_ci	srate = intp->symbol_rate[d];
5218c2ecf20Sopenharmony_ci	search_range = intp->srch_range[d];
5228c2ecf20Sopenharmony_ci
5238c2ecf20Sopenharmony_ci	if (srate >= 10000000)
5248c2ecf20Sopenharmony_ci		locktimeout = demod_timeout / 3;
5258c2ecf20Sopenharmony_ci	else
5268c2ecf20Sopenharmony_ci		locktimeout = demod_timeout / 2;
5278c2ecf20Sopenharmony_ci
5288c2ecf20Sopenharmony_ci	lock = stv0900_get_demod_lock(intp, d, locktimeout);
5298c2ecf20Sopenharmony_ci
5308c2ecf20Sopenharmony_ci	if (lock != FALSE)
5318c2ecf20Sopenharmony_ci		return lock;
5328c2ecf20Sopenharmony_ci
5338c2ecf20Sopenharmony_ci	if (srate >= 10000000) {
5348c2ecf20Sopenharmony_ci		if (stv0900_check_timing_lock(intp, d) == TRUE) {
5358c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, DMDISTATE, 0x1f);
5368c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, DMDISTATE, 0x15);
5378c2ecf20Sopenharmony_ci			lock = stv0900_get_demod_lock(intp, d, demod_timeout);
5388c2ecf20Sopenharmony_ci		} else
5398c2ecf20Sopenharmony_ci			lock = FALSE;
5408c2ecf20Sopenharmony_ci
5418c2ecf20Sopenharmony_ci		return lock;
5428c2ecf20Sopenharmony_ci	}
5438c2ecf20Sopenharmony_ci
5448c2ecf20Sopenharmony_ci	if (intp->chip_id <= 0x20) {
5458c2ecf20Sopenharmony_ci		if (srate <= 1000000)
5468c2ecf20Sopenharmony_ci			currier_step = 500;
5478c2ecf20Sopenharmony_ci		else if (srate <= 4000000)
5488c2ecf20Sopenharmony_ci			currier_step = 1000;
5498c2ecf20Sopenharmony_ci		else if (srate <= 7000000)
5508c2ecf20Sopenharmony_ci			currier_step = 2000;
5518c2ecf20Sopenharmony_ci		else if (srate <= 10000000)
5528c2ecf20Sopenharmony_ci			currier_step = 3000;
5538c2ecf20Sopenharmony_ci		else
5548c2ecf20Sopenharmony_ci			currier_step = 5000;
5558c2ecf20Sopenharmony_ci
5568c2ecf20Sopenharmony_ci		if (srate >= 2000000) {
5578c2ecf20Sopenharmony_ci			timeout = (demod_timeout / 3);
5588c2ecf20Sopenharmony_ci			if (timeout > 1000)
5598c2ecf20Sopenharmony_ci				timeout = 1000;
5608c2ecf20Sopenharmony_ci		} else
5618c2ecf20Sopenharmony_ci			timeout = (demod_timeout / 2);
5628c2ecf20Sopenharmony_ci	} else {
5638c2ecf20Sopenharmony_ci		/*cut 3.0 */
5648c2ecf20Sopenharmony_ci		currier_step = srate / 4000;
5658c2ecf20Sopenharmony_ci		timeout = (demod_timeout * 3) / 4;
5668c2ecf20Sopenharmony_ci	}
5678c2ecf20Sopenharmony_ci
5688c2ecf20Sopenharmony_ci	nb_steps = ((search_range / 1000) / currier_step);
5698c2ecf20Sopenharmony_ci
5708c2ecf20Sopenharmony_ci	if ((nb_steps % 2) != 0)
5718c2ecf20Sopenharmony_ci		nb_steps += 1;
5728c2ecf20Sopenharmony_ci
5738c2ecf20Sopenharmony_ci	if (nb_steps <= 0)
5748c2ecf20Sopenharmony_ci		nb_steps = 2;
5758c2ecf20Sopenharmony_ci	else if (nb_steps > 12)
5768c2ecf20Sopenharmony_ci		nb_steps = 12;
5778c2ecf20Sopenharmony_ci
5788c2ecf20Sopenharmony_ci	current_step = 1;
5798c2ecf20Sopenharmony_ci	direction = 1;
5808c2ecf20Sopenharmony_ci
5818c2ecf20Sopenharmony_ci	if (intp->chip_id <= 0x20) {
5828c2ecf20Sopenharmony_ci		tuner_freq = intp->freq[d];
5838c2ecf20Sopenharmony_ci		intp->bw[d] = stv0900_carrier_width(intp->symbol_rate[d],
5848c2ecf20Sopenharmony_ci				intp->rolloff) + intp->symbol_rate[d];
5858c2ecf20Sopenharmony_ci	} else
5868c2ecf20Sopenharmony_ci		tuner_freq = 0;
5878c2ecf20Sopenharmony_ci
5888c2ecf20Sopenharmony_ci	while ((current_step <= nb_steps) && (lock == FALSE)) {
5898c2ecf20Sopenharmony_ci		if (direction > 0)
5908c2ecf20Sopenharmony_ci			tuner_freq += (current_step * currier_step);
5918c2ecf20Sopenharmony_ci		else
5928c2ecf20Sopenharmony_ci			tuner_freq -= (current_step * currier_step);
5938c2ecf20Sopenharmony_ci
5948c2ecf20Sopenharmony_ci		if (intp->chip_id <= 0x20) {
5958c2ecf20Sopenharmony_ci			if (intp->tuner_type[d] == 3)
5968c2ecf20Sopenharmony_ci				stv0900_set_tuner_auto(intp, tuner_freq,
5978c2ecf20Sopenharmony_ci						intp->bw[d], demod);
5988c2ecf20Sopenharmony_ci			else
5998c2ecf20Sopenharmony_ci				stv0900_set_tuner(fe, tuner_freq, intp->bw[d]);
6008c2ecf20Sopenharmony_ci
6018c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, DMDISTATE, 0x1c);
6028c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CFRINIT1, 0);
6038c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CFRINIT0, 0);
6048c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, DMDISTATE, 0x1f);
6058c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, DMDISTATE, 0x15);
6068c2ecf20Sopenharmony_ci		} else {
6078c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, DMDISTATE, 0x1c);
6088c2ecf20Sopenharmony_ci			freq = (tuner_freq * 65536) / (intp->mclk / 1000);
6098c2ecf20Sopenharmony_ci			stv0900_write_bits(intp, CFR_INIT1, MSB(freq));
6108c2ecf20Sopenharmony_ci			stv0900_write_bits(intp, CFR_INIT0, LSB(freq));
6118c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, DMDISTATE, 0x1f);
6128c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, DMDISTATE, 0x05);
6138c2ecf20Sopenharmony_ci		}
6148c2ecf20Sopenharmony_ci
6158c2ecf20Sopenharmony_ci		lock = stv0900_get_demod_lock(intp, d, timeout);
6168c2ecf20Sopenharmony_ci		direction *= -1;
6178c2ecf20Sopenharmony_ci		current_step++;
6188c2ecf20Sopenharmony_ci	}
6198c2ecf20Sopenharmony_ci
6208c2ecf20Sopenharmony_ci	return	lock;
6218c2ecf20Sopenharmony_ci}
6228c2ecf20Sopenharmony_ci
6238c2ecf20Sopenharmony_cistatic void stv0900_get_lock_timeout(s32 *demod_timeout, s32 *fec_timeout,
6248c2ecf20Sopenharmony_ci					s32 srate,
6258c2ecf20Sopenharmony_ci					enum fe_stv0900_search_algo algo)
6268c2ecf20Sopenharmony_ci{
6278c2ecf20Sopenharmony_ci	switch (algo) {
6288c2ecf20Sopenharmony_ci	case STV0900_BLIND_SEARCH:
6298c2ecf20Sopenharmony_ci		if (srate <= 1500000) {
6308c2ecf20Sopenharmony_ci			(*demod_timeout) = 1500;
6318c2ecf20Sopenharmony_ci			(*fec_timeout) = 400;
6328c2ecf20Sopenharmony_ci		} else if (srate <= 5000000) {
6338c2ecf20Sopenharmony_ci			(*demod_timeout) = 1000;
6348c2ecf20Sopenharmony_ci			(*fec_timeout) = 300;
6358c2ecf20Sopenharmony_ci		} else {
6368c2ecf20Sopenharmony_ci			(*demod_timeout) = 700;
6378c2ecf20Sopenharmony_ci			(*fec_timeout) = 100;
6388c2ecf20Sopenharmony_ci		}
6398c2ecf20Sopenharmony_ci
6408c2ecf20Sopenharmony_ci		break;
6418c2ecf20Sopenharmony_ci	case STV0900_COLD_START:
6428c2ecf20Sopenharmony_ci	case STV0900_WARM_START:
6438c2ecf20Sopenharmony_ci	default:
6448c2ecf20Sopenharmony_ci		if (srate <= 1000000) {
6458c2ecf20Sopenharmony_ci			(*demod_timeout) = 3000;
6468c2ecf20Sopenharmony_ci			(*fec_timeout) = 1700;
6478c2ecf20Sopenharmony_ci		} else if (srate <= 2000000) {
6488c2ecf20Sopenharmony_ci			(*demod_timeout) = 2500;
6498c2ecf20Sopenharmony_ci			(*fec_timeout) = 1100;
6508c2ecf20Sopenharmony_ci		} else if (srate <= 5000000) {
6518c2ecf20Sopenharmony_ci			(*demod_timeout) = 1000;
6528c2ecf20Sopenharmony_ci			(*fec_timeout) = 550;
6538c2ecf20Sopenharmony_ci		} else if (srate <= 10000000) {
6548c2ecf20Sopenharmony_ci			(*demod_timeout) = 700;
6558c2ecf20Sopenharmony_ci			(*fec_timeout) = 250;
6568c2ecf20Sopenharmony_ci		} else if (srate <= 20000000) {
6578c2ecf20Sopenharmony_ci			(*demod_timeout) = 400;
6588c2ecf20Sopenharmony_ci			(*fec_timeout) = 130;
6598c2ecf20Sopenharmony_ci		} else {
6608c2ecf20Sopenharmony_ci			(*demod_timeout) = 300;
6618c2ecf20Sopenharmony_ci			(*fec_timeout) = 100;
6628c2ecf20Sopenharmony_ci		}
6638c2ecf20Sopenharmony_ci
6648c2ecf20Sopenharmony_ci		break;
6658c2ecf20Sopenharmony_ci
6668c2ecf20Sopenharmony_ci	}
6678c2ecf20Sopenharmony_ci
6688c2ecf20Sopenharmony_ci	if (algo == STV0900_WARM_START)
6698c2ecf20Sopenharmony_ci		(*demod_timeout) /= 2;
6708c2ecf20Sopenharmony_ci}
6718c2ecf20Sopenharmony_ci
6728c2ecf20Sopenharmony_cistatic void stv0900_set_viterbi_tracq(struct stv0900_internal *intp,
6738c2ecf20Sopenharmony_ci					enum fe_stv0900_demod_num demod)
6748c2ecf20Sopenharmony_ci{
6758c2ecf20Sopenharmony_ci
6768c2ecf20Sopenharmony_ci	s32 vth_reg = VTH12;
6778c2ecf20Sopenharmony_ci
6788c2ecf20Sopenharmony_ci	dprintk("%s\n", __func__);
6798c2ecf20Sopenharmony_ci
6808c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, vth_reg++, 0xd0);
6818c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, vth_reg++, 0x7d);
6828c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, vth_reg++, 0x53);
6838c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, vth_reg++, 0x2f);
6848c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, vth_reg++, 0x24);
6858c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, vth_reg++, 0x1f);
6868c2ecf20Sopenharmony_ci}
6878c2ecf20Sopenharmony_ci
6888c2ecf20Sopenharmony_cistatic void stv0900_set_viterbi_standard(struct stv0900_internal *intp,
6898c2ecf20Sopenharmony_ci				   enum fe_stv0900_search_standard standard,
6908c2ecf20Sopenharmony_ci				   enum fe_stv0900_fec fec,
6918c2ecf20Sopenharmony_ci				   enum fe_stv0900_demod_num demod)
6928c2ecf20Sopenharmony_ci{
6938c2ecf20Sopenharmony_ci	dprintk("%s: ViterbiStandard = ", __func__);
6948c2ecf20Sopenharmony_ci
6958c2ecf20Sopenharmony_ci	switch (standard) {
6968c2ecf20Sopenharmony_ci	case STV0900_AUTO_SEARCH:
6978c2ecf20Sopenharmony_ci		dprintk("Auto\n");
6988c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, FECM, 0x10);
6998c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, PRVIT, 0x3f);
7008c2ecf20Sopenharmony_ci		break;
7018c2ecf20Sopenharmony_ci	case STV0900_SEARCH_DVBS1:
7028c2ecf20Sopenharmony_ci		dprintk("DVBS1\n");
7038c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, FECM, 0x00);
7048c2ecf20Sopenharmony_ci		switch (fec) {
7058c2ecf20Sopenharmony_ci		case STV0900_FEC_UNKNOWN:
7068c2ecf20Sopenharmony_ci		default:
7078c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, PRVIT, 0x2f);
7088c2ecf20Sopenharmony_ci			break;
7098c2ecf20Sopenharmony_ci		case STV0900_FEC_1_2:
7108c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, PRVIT, 0x01);
7118c2ecf20Sopenharmony_ci			break;
7128c2ecf20Sopenharmony_ci		case STV0900_FEC_2_3:
7138c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, PRVIT, 0x02);
7148c2ecf20Sopenharmony_ci			break;
7158c2ecf20Sopenharmony_ci		case STV0900_FEC_3_4:
7168c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, PRVIT, 0x04);
7178c2ecf20Sopenharmony_ci			break;
7188c2ecf20Sopenharmony_ci		case STV0900_FEC_5_6:
7198c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, PRVIT, 0x08);
7208c2ecf20Sopenharmony_ci			break;
7218c2ecf20Sopenharmony_ci		case STV0900_FEC_7_8:
7228c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, PRVIT, 0x20);
7238c2ecf20Sopenharmony_ci			break;
7248c2ecf20Sopenharmony_ci		}
7258c2ecf20Sopenharmony_ci
7268c2ecf20Sopenharmony_ci		break;
7278c2ecf20Sopenharmony_ci	case STV0900_SEARCH_DSS:
7288c2ecf20Sopenharmony_ci		dprintk("DSS\n");
7298c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, FECM, 0x80);
7308c2ecf20Sopenharmony_ci		switch (fec) {
7318c2ecf20Sopenharmony_ci		case STV0900_FEC_UNKNOWN:
7328c2ecf20Sopenharmony_ci		default:
7338c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, PRVIT, 0x13);
7348c2ecf20Sopenharmony_ci			break;
7358c2ecf20Sopenharmony_ci		case STV0900_FEC_1_2:
7368c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, PRVIT, 0x01);
7378c2ecf20Sopenharmony_ci			break;
7388c2ecf20Sopenharmony_ci		case STV0900_FEC_2_3:
7398c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, PRVIT, 0x02);
7408c2ecf20Sopenharmony_ci			break;
7418c2ecf20Sopenharmony_ci		case STV0900_FEC_6_7:
7428c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, PRVIT, 0x10);
7438c2ecf20Sopenharmony_ci			break;
7448c2ecf20Sopenharmony_ci		}
7458c2ecf20Sopenharmony_ci		break;
7468c2ecf20Sopenharmony_ci	default:
7478c2ecf20Sopenharmony_ci		break;
7488c2ecf20Sopenharmony_ci	}
7498c2ecf20Sopenharmony_ci}
7508c2ecf20Sopenharmony_ci
7518c2ecf20Sopenharmony_cistatic enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *intp,
7528c2ecf20Sopenharmony_ci						enum fe_stv0900_demod_num demod)
7538c2ecf20Sopenharmony_ci{
7548c2ecf20Sopenharmony_ci	enum fe_stv0900_fec prate;
7558c2ecf20Sopenharmony_ci	s32 rate_fld = stv0900_get_bits(intp, VIT_CURPUN);
7568c2ecf20Sopenharmony_ci
7578c2ecf20Sopenharmony_ci	switch (rate_fld) {
7588c2ecf20Sopenharmony_ci	case 13:
7598c2ecf20Sopenharmony_ci		prate = STV0900_FEC_1_2;
7608c2ecf20Sopenharmony_ci		break;
7618c2ecf20Sopenharmony_ci	case 18:
7628c2ecf20Sopenharmony_ci		prate = STV0900_FEC_2_3;
7638c2ecf20Sopenharmony_ci		break;
7648c2ecf20Sopenharmony_ci	case 21:
7658c2ecf20Sopenharmony_ci		prate = STV0900_FEC_3_4;
7668c2ecf20Sopenharmony_ci		break;
7678c2ecf20Sopenharmony_ci	case 24:
7688c2ecf20Sopenharmony_ci		prate = STV0900_FEC_5_6;
7698c2ecf20Sopenharmony_ci		break;
7708c2ecf20Sopenharmony_ci	case 25:
7718c2ecf20Sopenharmony_ci		prate = STV0900_FEC_6_7;
7728c2ecf20Sopenharmony_ci		break;
7738c2ecf20Sopenharmony_ci	case 26:
7748c2ecf20Sopenharmony_ci		prate = STV0900_FEC_7_8;
7758c2ecf20Sopenharmony_ci		break;
7768c2ecf20Sopenharmony_ci	default:
7778c2ecf20Sopenharmony_ci		prate = STV0900_FEC_UNKNOWN;
7788c2ecf20Sopenharmony_ci		break;
7798c2ecf20Sopenharmony_ci	}
7808c2ecf20Sopenharmony_ci
7818c2ecf20Sopenharmony_ci	return prate;
7828c2ecf20Sopenharmony_ci}
7838c2ecf20Sopenharmony_ci
7848c2ecf20Sopenharmony_cistatic void stv0900_set_dvbs1_track_car_loop(struct stv0900_internal *intp,
7858c2ecf20Sopenharmony_ci					enum fe_stv0900_demod_num demod,
7868c2ecf20Sopenharmony_ci					u32 srate)
7878c2ecf20Sopenharmony_ci{
7888c2ecf20Sopenharmony_ci	if (intp->chip_id >= 0x30) {
7898c2ecf20Sopenharmony_ci		if (srate >= 15000000) {
7908c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, ACLC, 0x2b);
7918c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, BCLC, 0x1a);
7928c2ecf20Sopenharmony_ci		} else if ((srate >= 7000000) && (15000000 > srate)) {
7938c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, ACLC, 0x0c);
7948c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, BCLC, 0x1b);
7958c2ecf20Sopenharmony_ci		} else if (srate < 7000000) {
7968c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, ACLC, 0x2c);
7978c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, BCLC, 0x1c);
7988c2ecf20Sopenharmony_ci		}
7998c2ecf20Sopenharmony_ci
8008c2ecf20Sopenharmony_ci	} else { /*cut 2.0 and 1.x*/
8018c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, ACLC, 0x1a);
8028c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, BCLC, 0x09);
8038c2ecf20Sopenharmony_ci	}
8048c2ecf20Sopenharmony_ci
8058c2ecf20Sopenharmony_ci}
8068c2ecf20Sopenharmony_ci
8078c2ecf20Sopenharmony_cistatic void stv0900_track_optimization(struct dvb_frontend *fe)
8088c2ecf20Sopenharmony_ci{
8098c2ecf20Sopenharmony_ci	struct stv0900_state *state = fe->demodulator_priv;
8108c2ecf20Sopenharmony_ci	struct stv0900_internal *intp = state->internal;
8118c2ecf20Sopenharmony_ci	enum fe_stv0900_demod_num demod = state->demod;
8128c2ecf20Sopenharmony_ci
8138c2ecf20Sopenharmony_ci	s32	srate,
8148c2ecf20Sopenharmony_ci		pilots,
8158c2ecf20Sopenharmony_ci		aclc,
8168c2ecf20Sopenharmony_ci		freq1,
8178c2ecf20Sopenharmony_ci		freq0,
8188c2ecf20Sopenharmony_ci		i = 0,
8198c2ecf20Sopenharmony_ci		timed,
8208c2ecf20Sopenharmony_ci		timef,
8218c2ecf20Sopenharmony_ci		blind_tun_sw = 0,
8228c2ecf20Sopenharmony_ci		modulation;
8238c2ecf20Sopenharmony_ci
8248c2ecf20Sopenharmony_ci	enum fe_stv0900_modcode foundModcod;
8258c2ecf20Sopenharmony_ci
8268c2ecf20Sopenharmony_ci	dprintk("%s\n", __func__);
8278c2ecf20Sopenharmony_ci
8288c2ecf20Sopenharmony_ci	srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
8298c2ecf20Sopenharmony_ci	srate += stv0900_get_timing_offst(intp, srate, demod);
8308c2ecf20Sopenharmony_ci
8318c2ecf20Sopenharmony_ci	switch (intp->result[demod].standard) {
8328c2ecf20Sopenharmony_ci	case STV0900_DVBS1_STANDARD:
8338c2ecf20Sopenharmony_ci	case STV0900_DSS_STANDARD:
8348c2ecf20Sopenharmony_ci		dprintk("%s: found DVB-S or DSS\n", __func__);
8358c2ecf20Sopenharmony_ci		if (intp->srch_standard[demod] == STV0900_AUTO_SEARCH) {
8368c2ecf20Sopenharmony_ci			stv0900_write_bits(intp, DVBS1_ENABLE, 1);
8378c2ecf20Sopenharmony_ci			stv0900_write_bits(intp, DVBS2_ENABLE, 0);
8388c2ecf20Sopenharmony_ci		}
8398c2ecf20Sopenharmony_ci
8408c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, ROLLOFF_CONTROL, intp->rolloff);
8418c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
8428c2ecf20Sopenharmony_ci
8438c2ecf20Sopenharmony_ci		if (intp->chip_id < 0x30) {
8448c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, ERRCTRL1, 0x75);
8458c2ecf20Sopenharmony_ci			break;
8468c2ecf20Sopenharmony_ci		}
8478c2ecf20Sopenharmony_ci
8488c2ecf20Sopenharmony_ci		if (stv0900_get_vit_fec(intp, demod) == STV0900_FEC_1_2) {
8498c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, GAUSSR0, 0x98);
8508c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CCIR0, 0x18);
8518c2ecf20Sopenharmony_ci		} else {
8528c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, GAUSSR0, 0x18);
8538c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CCIR0, 0x18);
8548c2ecf20Sopenharmony_ci		}
8558c2ecf20Sopenharmony_ci
8568c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, ERRCTRL1, 0x75);
8578c2ecf20Sopenharmony_ci		break;
8588c2ecf20Sopenharmony_ci	case STV0900_DVBS2_STANDARD:
8598c2ecf20Sopenharmony_ci		dprintk("%s: found DVB-S2\n", __func__);
8608c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, DVBS1_ENABLE, 0);
8618c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, DVBS2_ENABLE, 1);
8628c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, ACLC, 0);
8638c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, BCLC, 0);
8648c2ecf20Sopenharmony_ci		if (intp->result[demod].frame_len == STV0900_LONG_FRAME) {
8658c2ecf20Sopenharmony_ci			foundModcod = stv0900_get_bits(intp, DEMOD_MODCOD);
8668c2ecf20Sopenharmony_ci			pilots = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01;
8678c2ecf20Sopenharmony_ci			aclc = stv0900_get_optim_carr_loop(srate,
8688c2ecf20Sopenharmony_ci							foundModcod,
8698c2ecf20Sopenharmony_ci							pilots,
8708c2ecf20Sopenharmony_ci							intp->chip_id);
8718c2ecf20Sopenharmony_ci			if (foundModcod <= STV0900_QPSK_910)
8728c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, ACLC2S2Q, aclc);
8738c2ecf20Sopenharmony_ci			else if (foundModcod <= STV0900_8PSK_910) {
8748c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
8758c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, ACLC2S28, aclc);
8768c2ecf20Sopenharmony_ci			}
8778c2ecf20Sopenharmony_ci
8788c2ecf20Sopenharmony_ci			if ((intp->demod_mode == STV0900_SINGLE) &&
8798c2ecf20Sopenharmony_ci					(foundModcod > STV0900_8PSK_910)) {
8808c2ecf20Sopenharmony_ci				if (foundModcod <= STV0900_16APSK_910) {
8818c2ecf20Sopenharmony_ci					stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
8828c2ecf20Sopenharmony_ci					stv0900_write_reg(intp, ACLC2S216A,
8838c2ecf20Sopenharmony_ci									aclc);
8848c2ecf20Sopenharmony_ci				} else if (foundModcod <= STV0900_32APSK_910) {
8858c2ecf20Sopenharmony_ci					stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
8868c2ecf20Sopenharmony_ci					stv0900_write_reg(intp,	ACLC2S232A,
8878c2ecf20Sopenharmony_ci									aclc);
8888c2ecf20Sopenharmony_ci				}
8898c2ecf20Sopenharmony_ci			}
8908c2ecf20Sopenharmony_ci
8918c2ecf20Sopenharmony_ci		} else {
8928c2ecf20Sopenharmony_ci			modulation = intp->result[demod].modulation;
8938c2ecf20Sopenharmony_ci			aclc = stv0900_get_optim_short_carr_loop(srate,
8948c2ecf20Sopenharmony_ci					modulation, intp->chip_id);
8958c2ecf20Sopenharmony_ci			if (modulation == STV0900_QPSK)
8968c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, ACLC2S2Q, aclc);
8978c2ecf20Sopenharmony_ci			else if (modulation == STV0900_8PSK) {
8988c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
8998c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, ACLC2S28, aclc);
9008c2ecf20Sopenharmony_ci			} else if (modulation == STV0900_16APSK) {
9018c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
9028c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, ACLC2S216A, aclc);
9038c2ecf20Sopenharmony_ci			} else if (modulation == STV0900_32APSK) {
9048c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
9058c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, ACLC2S232A, aclc);
9068c2ecf20Sopenharmony_ci			}
9078c2ecf20Sopenharmony_ci
9088c2ecf20Sopenharmony_ci		}
9098c2ecf20Sopenharmony_ci
9108c2ecf20Sopenharmony_ci		if (intp->chip_id <= 0x11) {
9118c2ecf20Sopenharmony_ci			if (intp->demod_mode != STV0900_SINGLE)
9128c2ecf20Sopenharmony_ci				stv0900_activate_s2_modcod(intp, demod);
9138c2ecf20Sopenharmony_ci
9148c2ecf20Sopenharmony_ci		}
9158c2ecf20Sopenharmony_ci
9168c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, ERRCTRL1, 0x67);
9178c2ecf20Sopenharmony_ci		break;
9188c2ecf20Sopenharmony_ci	case STV0900_UNKNOWN_STANDARD:
9198c2ecf20Sopenharmony_ci	default:
9208c2ecf20Sopenharmony_ci		dprintk("%s: found unknown standard\n", __func__);
9218c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, DVBS1_ENABLE, 1);
9228c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, DVBS2_ENABLE, 1);
9238c2ecf20Sopenharmony_ci		break;
9248c2ecf20Sopenharmony_ci	}
9258c2ecf20Sopenharmony_ci
9268c2ecf20Sopenharmony_ci	freq1 = stv0900_read_reg(intp, CFR2);
9278c2ecf20Sopenharmony_ci	freq0 = stv0900_read_reg(intp, CFR1);
9288c2ecf20Sopenharmony_ci	if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) {
9298c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, SFRSTEP, 0x00);
9308c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, SCAN_ENABLE, 0);
9318c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
9328c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, TMGCFG2, 0xc1);
9338c2ecf20Sopenharmony_ci		stv0900_set_symbol_rate(intp, intp->mclk, srate, demod);
9348c2ecf20Sopenharmony_ci		blind_tun_sw = 1;
9358c2ecf20Sopenharmony_ci		if (intp->result[demod].standard != STV0900_DVBS2_STANDARD)
9368c2ecf20Sopenharmony_ci			stv0900_set_dvbs1_track_car_loop(intp, demod, srate);
9378c2ecf20Sopenharmony_ci
9388c2ecf20Sopenharmony_ci	}
9398c2ecf20Sopenharmony_ci
9408c2ecf20Sopenharmony_ci	if (intp->chip_id >= 0x20) {
9418c2ecf20Sopenharmony_ci		if ((intp->srch_standard[demod] == STV0900_SEARCH_DVBS1) ||
9428c2ecf20Sopenharmony_ci				(intp->srch_standard[demod] ==
9438c2ecf20Sopenharmony_ci							STV0900_SEARCH_DSS) ||
9448c2ecf20Sopenharmony_ci				(intp->srch_standard[demod] ==
9458c2ecf20Sopenharmony_ci							STV0900_AUTO_SEARCH)) {
9468c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, VAVSRVIT, 0x0a);
9478c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, VITSCALE, 0x0);
9488c2ecf20Sopenharmony_ci		}
9498c2ecf20Sopenharmony_ci	}
9508c2ecf20Sopenharmony_ci
9518c2ecf20Sopenharmony_ci	if (intp->chip_id < 0x20)
9528c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CARHDR, 0x08);
9538c2ecf20Sopenharmony_ci
9548c2ecf20Sopenharmony_ci	if (intp->chip_id == 0x10)
9558c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CORRELEXP, 0x0a);
9568c2ecf20Sopenharmony_ci
9578c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, AGC2REF, 0x38);
9588c2ecf20Sopenharmony_ci
9598c2ecf20Sopenharmony_ci	if ((intp->chip_id >= 0x20) ||
9608c2ecf20Sopenharmony_ci			(blind_tun_sw == 1) ||
9618c2ecf20Sopenharmony_ci			(intp->symbol_rate[demod] < 10000000)) {
9628c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CFRINIT1, freq1);
9638c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CFRINIT0, freq0);
9648c2ecf20Sopenharmony_ci		intp->bw[demod] = stv0900_carrier_width(srate,
9658c2ecf20Sopenharmony_ci					intp->rolloff) + 10000000;
9668c2ecf20Sopenharmony_ci
9678c2ecf20Sopenharmony_ci		if ((intp->chip_id >= 0x20) || (blind_tun_sw == 1)) {
9688c2ecf20Sopenharmony_ci			if (intp->srch_algo[demod] != STV0900_WARM_START) {
9698c2ecf20Sopenharmony_ci				if (intp->tuner_type[demod] == 3)
9708c2ecf20Sopenharmony_ci					stv0900_set_tuner_auto(intp,
9718c2ecf20Sopenharmony_ci							intp->freq[demod],
9728c2ecf20Sopenharmony_ci							intp->bw[demod],
9738c2ecf20Sopenharmony_ci							demod);
9748c2ecf20Sopenharmony_ci				else
9758c2ecf20Sopenharmony_ci					stv0900_set_bandwidth(fe,
9768c2ecf20Sopenharmony_ci							intp->bw[demod]);
9778c2ecf20Sopenharmony_ci			}
9788c2ecf20Sopenharmony_ci		}
9798c2ecf20Sopenharmony_ci
9808c2ecf20Sopenharmony_ci		if ((intp->srch_algo[demod] == STV0900_BLIND_SEARCH) ||
9818c2ecf20Sopenharmony_ci				(intp->symbol_rate[demod] < 10000000))
9828c2ecf20Sopenharmony_ci			msleep(50);
9838c2ecf20Sopenharmony_ci		else
9848c2ecf20Sopenharmony_ci			msleep(5);
9858c2ecf20Sopenharmony_ci
9868c2ecf20Sopenharmony_ci		stv0900_get_lock_timeout(&timed, &timef, srate,
9878c2ecf20Sopenharmony_ci						STV0900_WARM_START);
9888c2ecf20Sopenharmony_ci
9898c2ecf20Sopenharmony_ci		if (stv0900_get_demod_lock(intp, demod, timed / 2) == FALSE) {
9908c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, DMDISTATE, 0x1f);
9918c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CFRINIT1, freq1);
9928c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CFRINIT0, freq0);
9938c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, DMDISTATE, 0x18);
9948c2ecf20Sopenharmony_ci			i = 0;
9958c2ecf20Sopenharmony_ci			while ((stv0900_get_demod_lock(intp,
9968c2ecf20Sopenharmony_ci							demod,
9978c2ecf20Sopenharmony_ci							timed / 2) == FALSE) &&
9988c2ecf20Sopenharmony_ci						(i <= 2)) {
9998c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, DMDISTATE, 0x1f);
10008c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, CFRINIT1, freq1);
10018c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, CFRINIT0, freq0);
10028c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, DMDISTATE, 0x18);
10038c2ecf20Sopenharmony_ci				i++;
10048c2ecf20Sopenharmony_ci			}
10058c2ecf20Sopenharmony_ci		}
10068c2ecf20Sopenharmony_ci
10078c2ecf20Sopenharmony_ci	}
10088c2ecf20Sopenharmony_ci
10098c2ecf20Sopenharmony_ci	if (intp->chip_id >= 0x20)
10108c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CARFREQ, 0x49);
10118c2ecf20Sopenharmony_ci
10128c2ecf20Sopenharmony_ci	if ((intp->result[demod].standard == STV0900_DVBS1_STANDARD) ||
10138c2ecf20Sopenharmony_ci			(intp->result[demod].standard == STV0900_DSS_STANDARD))
10148c2ecf20Sopenharmony_ci		stv0900_set_viterbi_tracq(intp, demod);
10158c2ecf20Sopenharmony_ci
10168c2ecf20Sopenharmony_ci}
10178c2ecf20Sopenharmony_ci
10188c2ecf20Sopenharmony_cistatic int stv0900_get_fec_lock(struct stv0900_internal *intp,
10198c2ecf20Sopenharmony_ci				enum fe_stv0900_demod_num demod, s32 time_out)
10208c2ecf20Sopenharmony_ci{
10218c2ecf20Sopenharmony_ci	s32 timer = 0, lock = 0;
10228c2ecf20Sopenharmony_ci
10238c2ecf20Sopenharmony_ci	enum fe_stv0900_search_state dmd_state;
10248c2ecf20Sopenharmony_ci
10258c2ecf20Sopenharmony_ci	dprintk("%s\n", __func__);
10268c2ecf20Sopenharmony_ci
10278c2ecf20Sopenharmony_ci	dmd_state = stv0900_get_bits(intp, HEADER_MODE);
10288c2ecf20Sopenharmony_ci
10298c2ecf20Sopenharmony_ci	while ((timer < time_out) && (lock == 0)) {
10308c2ecf20Sopenharmony_ci		switch (dmd_state) {
10318c2ecf20Sopenharmony_ci		case STV0900_SEARCH:
10328c2ecf20Sopenharmony_ci		case STV0900_PLH_DETECTED:
10338c2ecf20Sopenharmony_ci		default:
10348c2ecf20Sopenharmony_ci			lock = 0;
10358c2ecf20Sopenharmony_ci			break;
10368c2ecf20Sopenharmony_ci		case STV0900_DVBS2_FOUND:
10378c2ecf20Sopenharmony_ci			lock = stv0900_get_bits(intp, PKTDELIN_LOCK);
10388c2ecf20Sopenharmony_ci			break;
10398c2ecf20Sopenharmony_ci		case STV0900_DVBS_FOUND:
10408c2ecf20Sopenharmony_ci			lock = stv0900_get_bits(intp, LOCKEDVIT);
10418c2ecf20Sopenharmony_ci			break;
10428c2ecf20Sopenharmony_ci		}
10438c2ecf20Sopenharmony_ci
10448c2ecf20Sopenharmony_ci		if (lock == 0) {
10458c2ecf20Sopenharmony_ci			msleep(10);
10468c2ecf20Sopenharmony_ci			timer += 10;
10478c2ecf20Sopenharmony_ci		}
10488c2ecf20Sopenharmony_ci	}
10498c2ecf20Sopenharmony_ci
10508c2ecf20Sopenharmony_ci	if (lock)
10518c2ecf20Sopenharmony_ci		dprintk("%s: DEMOD FEC LOCK OK\n", __func__);
10528c2ecf20Sopenharmony_ci	else
10538c2ecf20Sopenharmony_ci		dprintk("%s: DEMOD FEC LOCK FAIL\n", __func__);
10548c2ecf20Sopenharmony_ci
10558c2ecf20Sopenharmony_ci	return lock;
10568c2ecf20Sopenharmony_ci}
10578c2ecf20Sopenharmony_ci
10588c2ecf20Sopenharmony_cistatic int stv0900_wait_for_lock(struct stv0900_internal *intp,
10598c2ecf20Sopenharmony_ci				enum fe_stv0900_demod_num demod,
10608c2ecf20Sopenharmony_ci				s32 dmd_timeout, s32 fec_timeout)
10618c2ecf20Sopenharmony_ci{
10628c2ecf20Sopenharmony_ci
10638c2ecf20Sopenharmony_ci	s32 timer = 0, lock = 0;
10648c2ecf20Sopenharmony_ci
10658c2ecf20Sopenharmony_ci	dprintk("%s\n", __func__);
10668c2ecf20Sopenharmony_ci
10678c2ecf20Sopenharmony_ci	lock = stv0900_get_demod_lock(intp, demod, dmd_timeout);
10688c2ecf20Sopenharmony_ci
10698c2ecf20Sopenharmony_ci	if (lock)
10708c2ecf20Sopenharmony_ci		lock = stv0900_get_fec_lock(intp, demod, fec_timeout);
10718c2ecf20Sopenharmony_ci
10728c2ecf20Sopenharmony_ci	if (lock) {
10738c2ecf20Sopenharmony_ci		lock = 0;
10748c2ecf20Sopenharmony_ci
10758c2ecf20Sopenharmony_ci		dprintk("%s: Timer = %d, time_out = %d\n",
10768c2ecf20Sopenharmony_ci				__func__, timer, fec_timeout);
10778c2ecf20Sopenharmony_ci
10788c2ecf20Sopenharmony_ci		while ((timer < fec_timeout) && (lock == 0)) {
10798c2ecf20Sopenharmony_ci			lock = stv0900_get_bits(intp, TSFIFO_LINEOK);
10808c2ecf20Sopenharmony_ci			msleep(1);
10818c2ecf20Sopenharmony_ci			timer++;
10828c2ecf20Sopenharmony_ci		}
10838c2ecf20Sopenharmony_ci	}
10848c2ecf20Sopenharmony_ci
10858c2ecf20Sopenharmony_ci	if (lock)
10868c2ecf20Sopenharmony_ci		dprintk("%s: DEMOD LOCK OK\n", __func__);
10878c2ecf20Sopenharmony_ci	else
10888c2ecf20Sopenharmony_ci		dprintk("%s: DEMOD LOCK FAIL\n", __func__);
10898c2ecf20Sopenharmony_ci
10908c2ecf20Sopenharmony_ci	if (lock)
10918c2ecf20Sopenharmony_ci		return TRUE;
10928c2ecf20Sopenharmony_ci	else
10938c2ecf20Sopenharmony_ci		return FALSE;
10948c2ecf20Sopenharmony_ci}
10958c2ecf20Sopenharmony_ci
10968c2ecf20Sopenharmony_cienum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
10978c2ecf20Sopenharmony_ci						enum fe_stv0900_demod_num demod)
10988c2ecf20Sopenharmony_ci{
10998c2ecf20Sopenharmony_ci	struct stv0900_state *state = fe->demodulator_priv;
11008c2ecf20Sopenharmony_ci	struct stv0900_internal *intp = state->internal;
11018c2ecf20Sopenharmony_ci	enum fe_stv0900_tracking_standard fnd_standard;
11028c2ecf20Sopenharmony_ci
11038c2ecf20Sopenharmony_ci	int hdr_mode = stv0900_get_bits(intp, HEADER_MODE);
11048c2ecf20Sopenharmony_ci
11058c2ecf20Sopenharmony_ci	switch (hdr_mode) {
11068c2ecf20Sopenharmony_ci	case 2:
11078c2ecf20Sopenharmony_ci		fnd_standard = STV0900_DVBS2_STANDARD;
11088c2ecf20Sopenharmony_ci		break;
11098c2ecf20Sopenharmony_ci	case 3:
11108c2ecf20Sopenharmony_ci		if (stv0900_get_bits(intp, DSS_DVB) == 1)
11118c2ecf20Sopenharmony_ci			fnd_standard = STV0900_DSS_STANDARD;
11128c2ecf20Sopenharmony_ci		else
11138c2ecf20Sopenharmony_ci			fnd_standard = STV0900_DVBS1_STANDARD;
11148c2ecf20Sopenharmony_ci
11158c2ecf20Sopenharmony_ci		break;
11168c2ecf20Sopenharmony_ci	default:
11178c2ecf20Sopenharmony_ci		fnd_standard = STV0900_UNKNOWN_STANDARD;
11188c2ecf20Sopenharmony_ci	}
11198c2ecf20Sopenharmony_ci
11208c2ecf20Sopenharmony_ci	dprintk("%s: standard %d\n", __func__, fnd_standard);
11218c2ecf20Sopenharmony_ci
11228c2ecf20Sopenharmony_ci	return fnd_standard;
11238c2ecf20Sopenharmony_ci}
11248c2ecf20Sopenharmony_ci
11258c2ecf20Sopenharmony_cistatic s32 stv0900_get_carr_freq(struct stv0900_internal *intp, u32 mclk,
11268c2ecf20Sopenharmony_ci					enum fe_stv0900_demod_num demod)
11278c2ecf20Sopenharmony_ci{
11288c2ecf20Sopenharmony_ci	s32	derot,
11298c2ecf20Sopenharmony_ci		rem1,
11308c2ecf20Sopenharmony_ci		rem2,
11318c2ecf20Sopenharmony_ci		intval1,
11328c2ecf20Sopenharmony_ci		intval2;
11338c2ecf20Sopenharmony_ci
11348c2ecf20Sopenharmony_ci	derot = (stv0900_get_bits(intp, CAR_FREQ2) << 16) +
11358c2ecf20Sopenharmony_ci		(stv0900_get_bits(intp, CAR_FREQ1) << 8) +
11368c2ecf20Sopenharmony_ci		(stv0900_get_bits(intp, CAR_FREQ0));
11378c2ecf20Sopenharmony_ci
11388c2ecf20Sopenharmony_ci	derot = ge2comp(derot, 24);
11398c2ecf20Sopenharmony_ci	intval1 = mclk >> 12;
11408c2ecf20Sopenharmony_ci	intval2 = derot >> 12;
11418c2ecf20Sopenharmony_ci	rem1 = mclk % 0x1000;
11428c2ecf20Sopenharmony_ci	rem2 = derot % 0x1000;
11438c2ecf20Sopenharmony_ci	derot = (intval1 * intval2) +
11448c2ecf20Sopenharmony_ci		((intval1 * rem2) >> 12) +
11458c2ecf20Sopenharmony_ci		((intval2 * rem1) >> 12);
11468c2ecf20Sopenharmony_ci
11478c2ecf20Sopenharmony_ci	return derot;
11488c2ecf20Sopenharmony_ci}
11498c2ecf20Sopenharmony_ci
11508c2ecf20Sopenharmony_cistatic u32 stv0900_get_tuner_freq(struct dvb_frontend *fe)
11518c2ecf20Sopenharmony_ci{
11528c2ecf20Sopenharmony_ci	struct dvb_frontend_ops	*frontend_ops = NULL;
11538c2ecf20Sopenharmony_ci	struct dvb_tuner_ops *tuner_ops = NULL;
11548c2ecf20Sopenharmony_ci	u32 freq = 0;
11558c2ecf20Sopenharmony_ci
11568c2ecf20Sopenharmony_ci	frontend_ops = &fe->ops;
11578c2ecf20Sopenharmony_ci	tuner_ops = &frontend_ops->tuner_ops;
11588c2ecf20Sopenharmony_ci
11598c2ecf20Sopenharmony_ci	if (tuner_ops->get_frequency) {
11608c2ecf20Sopenharmony_ci		if ((tuner_ops->get_frequency(fe, &freq)) < 0)
11618c2ecf20Sopenharmony_ci			dprintk("%s: Invalid parameter\n", __func__);
11628c2ecf20Sopenharmony_ci		else
11638c2ecf20Sopenharmony_ci			dprintk("%s: Frequency=%d\n", __func__, freq);
11648c2ecf20Sopenharmony_ci
11658c2ecf20Sopenharmony_ci	}
11668c2ecf20Sopenharmony_ci
11678c2ecf20Sopenharmony_ci	return freq;
11688c2ecf20Sopenharmony_ci}
11698c2ecf20Sopenharmony_ci
11708c2ecf20Sopenharmony_cistatic enum
11718c2ecf20Sopenharmony_cife_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe)
11728c2ecf20Sopenharmony_ci{
11738c2ecf20Sopenharmony_ci	struct stv0900_state *state = fe->demodulator_priv;
11748c2ecf20Sopenharmony_ci	struct stv0900_internal *intp = state->internal;
11758c2ecf20Sopenharmony_ci	enum fe_stv0900_demod_num demod = state->demod;
11768c2ecf20Sopenharmony_ci	enum fe_stv0900_signal_type range = STV0900_OUTOFRANGE;
11778c2ecf20Sopenharmony_ci	struct stv0900_signal_info *result = &intp->result[demod];
11788c2ecf20Sopenharmony_ci	s32	offsetFreq,
11798c2ecf20Sopenharmony_ci		srate_offset;
11808c2ecf20Sopenharmony_ci	int	i = 0,
11818c2ecf20Sopenharmony_ci		d = demod;
11828c2ecf20Sopenharmony_ci
11838c2ecf20Sopenharmony_ci	u8 timing;
11848c2ecf20Sopenharmony_ci
11858c2ecf20Sopenharmony_ci	msleep(5);
11868c2ecf20Sopenharmony_ci	if (intp->srch_algo[d] == STV0900_BLIND_SEARCH) {
11878c2ecf20Sopenharmony_ci		timing = stv0900_read_reg(intp, TMGREG2);
11888c2ecf20Sopenharmony_ci		i = 0;
11898c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, SFRSTEP, 0x5c);
11908c2ecf20Sopenharmony_ci
11918c2ecf20Sopenharmony_ci		while ((i <= 50) && (timing != 0) && (timing != 0xff)) {
11928c2ecf20Sopenharmony_ci			timing = stv0900_read_reg(intp, TMGREG2);
11938c2ecf20Sopenharmony_ci			msleep(5);
11948c2ecf20Sopenharmony_ci			i += 5;
11958c2ecf20Sopenharmony_ci		}
11968c2ecf20Sopenharmony_ci	}
11978c2ecf20Sopenharmony_ci
11988c2ecf20Sopenharmony_ci	result->standard = stv0900_get_standard(fe, d);
11998c2ecf20Sopenharmony_ci	if (intp->tuner_type[demod] == 3)
12008c2ecf20Sopenharmony_ci		result->frequency = stv0900_get_freq_auto(intp, d);
12018c2ecf20Sopenharmony_ci	else
12028c2ecf20Sopenharmony_ci		result->frequency = stv0900_get_tuner_freq(fe);
12038c2ecf20Sopenharmony_ci
12048c2ecf20Sopenharmony_ci	offsetFreq = stv0900_get_carr_freq(intp, intp->mclk, d) / 1000;
12058c2ecf20Sopenharmony_ci	result->frequency += offsetFreq;
12068c2ecf20Sopenharmony_ci	result->symbol_rate = stv0900_get_symbol_rate(intp, intp->mclk, d);
12078c2ecf20Sopenharmony_ci	srate_offset = stv0900_get_timing_offst(intp, result->symbol_rate, d);
12088c2ecf20Sopenharmony_ci	result->symbol_rate += srate_offset;
12098c2ecf20Sopenharmony_ci	result->fec = stv0900_get_vit_fec(intp, d);
12108c2ecf20Sopenharmony_ci	result->modcode = stv0900_get_bits(intp, DEMOD_MODCOD);
12118c2ecf20Sopenharmony_ci	result->pilot = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01;
12128c2ecf20Sopenharmony_ci	result->frame_len = ((u32)stv0900_get_bits(intp, DEMOD_TYPE)) >> 1;
12138c2ecf20Sopenharmony_ci	result->rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS);
12148c2ecf20Sopenharmony_ci
12158c2ecf20Sopenharmony_ci	dprintk("%s: modcode=0x%x \n", __func__, result->modcode);
12168c2ecf20Sopenharmony_ci
12178c2ecf20Sopenharmony_ci	switch (result->standard) {
12188c2ecf20Sopenharmony_ci	case STV0900_DVBS2_STANDARD:
12198c2ecf20Sopenharmony_ci		result->spectrum = stv0900_get_bits(intp, SPECINV_DEMOD);
12208c2ecf20Sopenharmony_ci		if (result->modcode <= STV0900_QPSK_910)
12218c2ecf20Sopenharmony_ci			result->modulation = STV0900_QPSK;
12228c2ecf20Sopenharmony_ci		else if (result->modcode <= STV0900_8PSK_910)
12238c2ecf20Sopenharmony_ci			result->modulation = STV0900_8PSK;
12248c2ecf20Sopenharmony_ci		else if (result->modcode <= STV0900_16APSK_910)
12258c2ecf20Sopenharmony_ci			result->modulation = STV0900_16APSK;
12268c2ecf20Sopenharmony_ci		else if (result->modcode <= STV0900_32APSK_910)
12278c2ecf20Sopenharmony_ci			result->modulation = STV0900_32APSK;
12288c2ecf20Sopenharmony_ci		else
12298c2ecf20Sopenharmony_ci			result->modulation = STV0900_UNKNOWN;
12308c2ecf20Sopenharmony_ci		break;
12318c2ecf20Sopenharmony_ci	case STV0900_DVBS1_STANDARD:
12328c2ecf20Sopenharmony_ci	case STV0900_DSS_STANDARD:
12338c2ecf20Sopenharmony_ci		result->spectrum = stv0900_get_bits(intp, IQINV);
12348c2ecf20Sopenharmony_ci		result->modulation = STV0900_QPSK;
12358c2ecf20Sopenharmony_ci		break;
12368c2ecf20Sopenharmony_ci	default:
12378c2ecf20Sopenharmony_ci		break;
12388c2ecf20Sopenharmony_ci	}
12398c2ecf20Sopenharmony_ci
12408c2ecf20Sopenharmony_ci	if ((intp->srch_algo[d] == STV0900_BLIND_SEARCH) ||
12418c2ecf20Sopenharmony_ci				(intp->symbol_rate[d] < 10000000)) {
12428c2ecf20Sopenharmony_ci		offsetFreq = result->frequency - intp->freq[d];
12438c2ecf20Sopenharmony_ci		if (intp->tuner_type[demod] == 3)
12448c2ecf20Sopenharmony_ci			intp->freq[d] = stv0900_get_freq_auto(intp, d);
12458c2ecf20Sopenharmony_ci		else
12468c2ecf20Sopenharmony_ci			intp->freq[d] = stv0900_get_tuner_freq(fe);
12478c2ecf20Sopenharmony_ci
12488c2ecf20Sopenharmony_ci		if (abs(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500))
12498c2ecf20Sopenharmony_ci			range = STV0900_RANGEOK;
12508c2ecf20Sopenharmony_ci		else if (abs(offsetFreq) <=
12518c2ecf20Sopenharmony_ci				(stv0900_carrier_width(result->symbol_rate,
12528c2ecf20Sopenharmony_ci						result->rolloff) / 2000))
12538c2ecf20Sopenharmony_ci			range = STV0900_RANGEOK;
12548c2ecf20Sopenharmony_ci
12558c2ecf20Sopenharmony_ci	} else if (abs(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500))
12568c2ecf20Sopenharmony_ci		range = STV0900_RANGEOK;
12578c2ecf20Sopenharmony_ci
12588c2ecf20Sopenharmony_ci	dprintk("%s: range %d\n", __func__, range);
12598c2ecf20Sopenharmony_ci
12608c2ecf20Sopenharmony_ci	return range;
12618c2ecf20Sopenharmony_ci}
12628c2ecf20Sopenharmony_ci
12638c2ecf20Sopenharmony_cistatic enum
12648c2ecf20Sopenharmony_cife_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_frontend *fe)
12658c2ecf20Sopenharmony_ci{
12668c2ecf20Sopenharmony_ci	struct stv0900_state *state = fe->demodulator_priv;
12678c2ecf20Sopenharmony_ci	struct stv0900_internal *intp = state->internal;
12688c2ecf20Sopenharmony_ci	enum fe_stv0900_demod_num demod = state->demod;
12698c2ecf20Sopenharmony_ci	enum fe_stv0900_signal_type signal_type = STV0900_NODATA;
12708c2ecf20Sopenharmony_ci
12718c2ecf20Sopenharmony_ci	s32	srate,
12728c2ecf20Sopenharmony_ci		demod_timeout,
12738c2ecf20Sopenharmony_ci		fec_timeout,
12748c2ecf20Sopenharmony_ci		freq1,
12758c2ecf20Sopenharmony_ci		freq0;
12768c2ecf20Sopenharmony_ci
12778c2ecf20Sopenharmony_ci	intp->result[demod].locked = FALSE;
12788c2ecf20Sopenharmony_ci
12798c2ecf20Sopenharmony_ci	if (stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) {
12808c2ecf20Sopenharmony_ci		srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
12818c2ecf20Sopenharmony_ci		srate += stv0900_get_timing_offst(intp, srate, demod);
12828c2ecf20Sopenharmony_ci		if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH)
12838c2ecf20Sopenharmony_ci			stv0900_set_symbol_rate(intp, intp->mclk, srate, demod);
12848c2ecf20Sopenharmony_ci
12858c2ecf20Sopenharmony_ci		stv0900_get_lock_timeout(&demod_timeout, &fec_timeout,
12868c2ecf20Sopenharmony_ci					srate, STV0900_WARM_START);
12878c2ecf20Sopenharmony_ci		freq1 = stv0900_read_reg(intp, CFR2);
12888c2ecf20Sopenharmony_ci		freq0 = stv0900_read_reg(intp, CFR1);
12898c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
12908c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, SPECINV_CONTROL,
12918c2ecf20Sopenharmony_ci					STV0900_IQ_FORCE_SWAPPED);
12928c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, DMDISTATE, 0x1c);
12938c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CFRINIT1, freq1);
12948c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CFRINIT0, freq0);
12958c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, DMDISTATE, 0x18);
12968c2ecf20Sopenharmony_ci		if (stv0900_wait_for_lock(intp, demod,
12978c2ecf20Sopenharmony_ci				demod_timeout, fec_timeout) == TRUE) {
12988c2ecf20Sopenharmony_ci			intp->result[demod].locked = TRUE;
12998c2ecf20Sopenharmony_ci			signal_type = stv0900_get_signal_params(fe);
13008c2ecf20Sopenharmony_ci			stv0900_track_optimization(fe);
13018c2ecf20Sopenharmony_ci		} else {
13028c2ecf20Sopenharmony_ci			stv0900_write_bits(intp, SPECINV_CONTROL,
13038c2ecf20Sopenharmony_ci					STV0900_IQ_FORCE_NORMAL);
13048c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, DMDISTATE, 0x1c);
13058c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CFRINIT1, freq1);
13068c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CFRINIT0, freq0);
13078c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, DMDISTATE, 0x18);
13088c2ecf20Sopenharmony_ci			if (stv0900_wait_for_lock(intp, demod,
13098c2ecf20Sopenharmony_ci					demod_timeout, fec_timeout) == TRUE) {
13108c2ecf20Sopenharmony_ci				intp->result[demod].locked = TRUE;
13118c2ecf20Sopenharmony_ci				signal_type = stv0900_get_signal_params(fe);
13128c2ecf20Sopenharmony_ci				stv0900_track_optimization(fe);
13138c2ecf20Sopenharmony_ci			}
13148c2ecf20Sopenharmony_ci
13158c2ecf20Sopenharmony_ci		}
13168c2ecf20Sopenharmony_ci
13178c2ecf20Sopenharmony_ci	} else
13188c2ecf20Sopenharmony_ci		intp->result[demod].locked = FALSE;
13198c2ecf20Sopenharmony_ci
13208c2ecf20Sopenharmony_ci	return signal_type;
13218c2ecf20Sopenharmony_ci}
13228c2ecf20Sopenharmony_ci
13238c2ecf20Sopenharmony_cistatic u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *intp,
13248c2ecf20Sopenharmony_ci					enum fe_stv0900_demod_num demod)
13258c2ecf20Sopenharmony_ci{
13268c2ecf20Sopenharmony_ci	u32 minagc2level = 0xffff,
13278c2ecf20Sopenharmony_ci		agc2level,
13288c2ecf20Sopenharmony_ci		init_freq, freq_step;
13298c2ecf20Sopenharmony_ci
13308c2ecf20Sopenharmony_ci	s32 i, j, nb_steps, direction;
13318c2ecf20Sopenharmony_ci
13328c2ecf20Sopenharmony_ci	dprintk("%s\n", __func__);
13338c2ecf20Sopenharmony_ci
13348c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, AGC2REF, 0x38);
13358c2ecf20Sopenharmony_ci	stv0900_write_bits(intp, SCAN_ENABLE, 0);
13368c2ecf20Sopenharmony_ci	stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
13378c2ecf20Sopenharmony_ci
13388c2ecf20Sopenharmony_ci	stv0900_write_bits(intp, AUTO_GUP, 1);
13398c2ecf20Sopenharmony_ci	stv0900_write_bits(intp, AUTO_GLOW, 1);
13408c2ecf20Sopenharmony_ci
13418c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, DMDT0M, 0x0);
13428c2ecf20Sopenharmony_ci
13438c2ecf20Sopenharmony_ci	stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod);
13448c2ecf20Sopenharmony_ci	nb_steps = -1 + (intp->srch_range[demod] / 1000000);
13458c2ecf20Sopenharmony_ci	nb_steps /= 2;
13468c2ecf20Sopenharmony_ci	nb_steps = (2 * nb_steps) + 1;
13478c2ecf20Sopenharmony_ci
13488c2ecf20Sopenharmony_ci	if (nb_steps < 0)
13498c2ecf20Sopenharmony_ci		nb_steps = 1;
13508c2ecf20Sopenharmony_ci
13518c2ecf20Sopenharmony_ci	direction = 1;
13528c2ecf20Sopenharmony_ci
13538c2ecf20Sopenharmony_ci	freq_step = (1000000 << 8) / (intp->mclk >> 8);
13548c2ecf20Sopenharmony_ci
13558c2ecf20Sopenharmony_ci	init_freq = 0;
13568c2ecf20Sopenharmony_ci
13578c2ecf20Sopenharmony_ci	for (i = 0; i < nb_steps; i++) {
13588c2ecf20Sopenharmony_ci		if (direction > 0)
13598c2ecf20Sopenharmony_ci			init_freq = init_freq + (freq_step * i);
13608c2ecf20Sopenharmony_ci		else
13618c2ecf20Sopenharmony_ci			init_freq = init_freq - (freq_step * i);
13628c2ecf20Sopenharmony_ci
13638c2ecf20Sopenharmony_ci		direction *= -1;
13648c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, DMDISTATE, 0x5C);
13658c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CFRINIT1, (init_freq >> 8) & 0xff);
13668c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CFRINIT0, init_freq  & 0xff);
13678c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, DMDISTATE, 0x58);
13688c2ecf20Sopenharmony_ci		msleep(10);
13698c2ecf20Sopenharmony_ci		agc2level = 0;
13708c2ecf20Sopenharmony_ci
13718c2ecf20Sopenharmony_ci		for (j = 0; j < 10; j++)
13728c2ecf20Sopenharmony_ci			agc2level += (stv0900_read_reg(intp, AGC2I1) << 8)
13738c2ecf20Sopenharmony_ci					| stv0900_read_reg(intp, AGC2I0);
13748c2ecf20Sopenharmony_ci
13758c2ecf20Sopenharmony_ci		agc2level /= 10;
13768c2ecf20Sopenharmony_ci
13778c2ecf20Sopenharmony_ci		if (agc2level < minagc2level)
13788c2ecf20Sopenharmony_ci			minagc2level = agc2level;
13798c2ecf20Sopenharmony_ci
13808c2ecf20Sopenharmony_ci	}
13818c2ecf20Sopenharmony_ci
13828c2ecf20Sopenharmony_ci	return (u16)minagc2level;
13838c2ecf20Sopenharmony_ci}
13848c2ecf20Sopenharmony_ci
13858c2ecf20Sopenharmony_cistatic u32 stv0900_search_srate_coarse(struct dvb_frontend *fe)
13868c2ecf20Sopenharmony_ci{
13878c2ecf20Sopenharmony_ci	struct stv0900_state *state = fe->demodulator_priv;
13888c2ecf20Sopenharmony_ci	struct stv0900_internal *intp = state->internal;
13898c2ecf20Sopenharmony_ci	enum fe_stv0900_demod_num demod = state->demod;
13908c2ecf20Sopenharmony_ci	int timing_lck = FALSE;
13918c2ecf20Sopenharmony_ci	s32 i, timingcpt = 0,
13928c2ecf20Sopenharmony_ci		direction = 1,
13938c2ecf20Sopenharmony_ci		nb_steps,
13948c2ecf20Sopenharmony_ci		current_step = 0,
13958c2ecf20Sopenharmony_ci		tuner_freq;
13968c2ecf20Sopenharmony_ci	u32 agc2_th,
13978c2ecf20Sopenharmony_ci		coarse_srate = 0,
13988c2ecf20Sopenharmony_ci		agc2_integr = 0,
13998c2ecf20Sopenharmony_ci		currier_step = 1200;
14008c2ecf20Sopenharmony_ci
14018c2ecf20Sopenharmony_ci	if (intp->chip_id >= 0x30)
14028c2ecf20Sopenharmony_ci		agc2_th = 0x2e00;
14038c2ecf20Sopenharmony_ci	else
14048c2ecf20Sopenharmony_ci		agc2_th = 0x1f00;
14058c2ecf20Sopenharmony_ci
14068c2ecf20Sopenharmony_ci	stv0900_write_bits(intp, DEMOD_MODE, 0x1f);
14078c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, TMGCFG, 0x12);
14088c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, TMGTHRISE, 0xf0);
14098c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, TMGTHFALL, 0xe0);
14108c2ecf20Sopenharmony_ci	stv0900_write_bits(intp, SCAN_ENABLE, 1);
14118c2ecf20Sopenharmony_ci	stv0900_write_bits(intp, CFR_AUTOSCAN, 1);
14128c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, SFRUP1, 0x83);
14138c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, SFRUP0, 0xc0);
14148c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, SFRLOW1, 0x82);
14158c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, SFRLOW0, 0xa0);
14168c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, DMDT0M, 0x0);
14178c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, AGC2REF, 0x50);
14188c2ecf20Sopenharmony_ci
14198c2ecf20Sopenharmony_ci	if (intp->chip_id >= 0x30) {
14208c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CARFREQ, 0x99);
14218c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, SFRSTEP, 0x98);
14228c2ecf20Sopenharmony_ci	} else if (intp->chip_id >= 0x20) {
14238c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CARFREQ, 0x6a);
14248c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, SFRSTEP, 0x95);
14258c2ecf20Sopenharmony_ci	} else {
14268c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CARFREQ, 0xed);
14278c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, SFRSTEP, 0x73);
14288c2ecf20Sopenharmony_ci	}
14298c2ecf20Sopenharmony_ci
14308c2ecf20Sopenharmony_ci	if (intp->symbol_rate[demod] <= 2000000)
14318c2ecf20Sopenharmony_ci		currier_step = 1000;
14328c2ecf20Sopenharmony_ci	else if (intp->symbol_rate[demod] <= 5000000)
14338c2ecf20Sopenharmony_ci		currier_step = 2000;
14348c2ecf20Sopenharmony_ci	else if (intp->symbol_rate[demod] <= 12000000)
14358c2ecf20Sopenharmony_ci		currier_step = 3000;
14368c2ecf20Sopenharmony_ci	else
14378c2ecf20Sopenharmony_ci			currier_step = 5000;
14388c2ecf20Sopenharmony_ci
14398c2ecf20Sopenharmony_ci	nb_steps = -1 + ((intp->srch_range[demod] / 1000) / currier_step);
14408c2ecf20Sopenharmony_ci	nb_steps /= 2;
14418c2ecf20Sopenharmony_ci	nb_steps = (2 * nb_steps) + 1;
14428c2ecf20Sopenharmony_ci
14438c2ecf20Sopenharmony_ci	if (nb_steps < 0)
14448c2ecf20Sopenharmony_ci		nb_steps = 1;
14458c2ecf20Sopenharmony_ci	else if (nb_steps > 10) {
14468c2ecf20Sopenharmony_ci		nb_steps = 11;
14478c2ecf20Sopenharmony_ci		currier_step = (intp->srch_range[demod] / 1000) / 10;
14488c2ecf20Sopenharmony_ci	}
14498c2ecf20Sopenharmony_ci
14508c2ecf20Sopenharmony_ci	current_step = 0;
14518c2ecf20Sopenharmony_ci	direction = 1;
14528c2ecf20Sopenharmony_ci
14538c2ecf20Sopenharmony_ci	tuner_freq = intp->freq[demod];
14548c2ecf20Sopenharmony_ci
14558c2ecf20Sopenharmony_ci	while ((timing_lck == FALSE) && (current_step < nb_steps)) {
14568c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, DMDISTATE, 0x5f);
14578c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, DEMOD_MODE, 0);
14588c2ecf20Sopenharmony_ci
14598c2ecf20Sopenharmony_ci		msleep(50);
14608c2ecf20Sopenharmony_ci
14618c2ecf20Sopenharmony_ci		for (i = 0; i < 10; i++) {
14628c2ecf20Sopenharmony_ci			if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2)
14638c2ecf20Sopenharmony_ci				timingcpt++;
14648c2ecf20Sopenharmony_ci
14658c2ecf20Sopenharmony_ci			agc2_integr += (stv0900_read_reg(intp, AGC2I1) << 8) |
14668c2ecf20Sopenharmony_ci					stv0900_read_reg(intp, AGC2I0);
14678c2ecf20Sopenharmony_ci		}
14688c2ecf20Sopenharmony_ci
14698c2ecf20Sopenharmony_ci		agc2_integr /= 10;
14708c2ecf20Sopenharmony_ci		coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
14718c2ecf20Sopenharmony_ci		current_step++;
14728c2ecf20Sopenharmony_ci		direction *= -1;
14738c2ecf20Sopenharmony_ci
14748c2ecf20Sopenharmony_ci		dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started. tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n",
14758c2ecf20Sopenharmony_ci			tuner_freq, agc2_integr, coarse_srate, timingcpt);
14768c2ecf20Sopenharmony_ci
14778c2ecf20Sopenharmony_ci		if ((timingcpt >= 5) &&
14788c2ecf20Sopenharmony_ci				(agc2_integr < agc2_th) &&
14798c2ecf20Sopenharmony_ci				(coarse_srate < 55000000) &&
14808c2ecf20Sopenharmony_ci				(coarse_srate > 850000))
14818c2ecf20Sopenharmony_ci			timing_lck = TRUE;
14828c2ecf20Sopenharmony_ci		else if (current_step < nb_steps) {
14838c2ecf20Sopenharmony_ci			if (direction > 0)
14848c2ecf20Sopenharmony_ci				tuner_freq += (current_step * currier_step);
14858c2ecf20Sopenharmony_ci			else
14868c2ecf20Sopenharmony_ci				tuner_freq -= (current_step * currier_step);
14878c2ecf20Sopenharmony_ci
14888c2ecf20Sopenharmony_ci			if (intp->tuner_type[demod] == 3)
14898c2ecf20Sopenharmony_ci				stv0900_set_tuner_auto(intp, tuner_freq,
14908c2ecf20Sopenharmony_ci						intp->bw[demod], demod);
14918c2ecf20Sopenharmony_ci			else
14928c2ecf20Sopenharmony_ci				stv0900_set_tuner(fe, tuner_freq,
14938c2ecf20Sopenharmony_ci						intp->bw[demod]);
14948c2ecf20Sopenharmony_ci		}
14958c2ecf20Sopenharmony_ci	}
14968c2ecf20Sopenharmony_ci
14978c2ecf20Sopenharmony_ci	if (timing_lck == FALSE)
14988c2ecf20Sopenharmony_ci		coarse_srate = 0;
14998c2ecf20Sopenharmony_ci	else
15008c2ecf20Sopenharmony_ci		coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
15018c2ecf20Sopenharmony_ci
15028c2ecf20Sopenharmony_ci	return coarse_srate;
15038c2ecf20Sopenharmony_ci}
15048c2ecf20Sopenharmony_ci
15058c2ecf20Sopenharmony_cistatic u32 stv0900_search_srate_fine(struct dvb_frontend *fe)
15068c2ecf20Sopenharmony_ci{
15078c2ecf20Sopenharmony_ci	struct stv0900_state *state = fe->demodulator_priv;
15088c2ecf20Sopenharmony_ci	struct stv0900_internal *intp = state->internal;
15098c2ecf20Sopenharmony_ci	enum fe_stv0900_demod_num demod = state->demod;
15108c2ecf20Sopenharmony_ci	u32	coarse_srate,
15118c2ecf20Sopenharmony_ci		coarse_freq,
15128c2ecf20Sopenharmony_ci		symb,
15138c2ecf20Sopenharmony_ci		symbmax,
15148c2ecf20Sopenharmony_ci		symbmin,
15158c2ecf20Sopenharmony_ci		symbcomp;
15168c2ecf20Sopenharmony_ci
15178c2ecf20Sopenharmony_ci	coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
15188c2ecf20Sopenharmony_ci
15198c2ecf20Sopenharmony_ci	if (coarse_srate > 3000000) {
15208c2ecf20Sopenharmony_ci		symbmax = 13 * (coarse_srate / 10);
15218c2ecf20Sopenharmony_ci		symbmax = (symbmax / 1000) * 65536;
15228c2ecf20Sopenharmony_ci		symbmax /= (intp->mclk / 1000);
15238c2ecf20Sopenharmony_ci
15248c2ecf20Sopenharmony_ci		symbmin = 10 * (coarse_srate / 13);
15258c2ecf20Sopenharmony_ci		symbmin = (symbmin / 1000)*65536;
15268c2ecf20Sopenharmony_ci		symbmin /= (intp->mclk / 1000);
15278c2ecf20Sopenharmony_ci
15288c2ecf20Sopenharmony_ci		symb = (coarse_srate / 1000) * 65536;
15298c2ecf20Sopenharmony_ci		symb /= (intp->mclk / 1000);
15308c2ecf20Sopenharmony_ci	} else {
15318c2ecf20Sopenharmony_ci		symbmax = 13 * (coarse_srate / 10);
15328c2ecf20Sopenharmony_ci		symbmax = (symbmax / 100) * 65536;
15338c2ecf20Sopenharmony_ci		symbmax /= (intp->mclk / 100);
15348c2ecf20Sopenharmony_ci
15358c2ecf20Sopenharmony_ci		symbmin = 10 * (coarse_srate / 14);
15368c2ecf20Sopenharmony_ci		symbmin = (symbmin / 100) * 65536;
15378c2ecf20Sopenharmony_ci		symbmin /= (intp->mclk / 100);
15388c2ecf20Sopenharmony_ci
15398c2ecf20Sopenharmony_ci		symb = (coarse_srate / 100) * 65536;
15408c2ecf20Sopenharmony_ci		symb /= (intp->mclk / 100);
15418c2ecf20Sopenharmony_ci	}
15428c2ecf20Sopenharmony_ci
15438c2ecf20Sopenharmony_ci	symbcomp = 13 * (coarse_srate / 10);
15448c2ecf20Sopenharmony_ci	coarse_freq = (stv0900_read_reg(intp, CFR2) << 8)
15458c2ecf20Sopenharmony_ci		      | stv0900_read_reg(intp, CFR1);
15468c2ecf20Sopenharmony_ci
15478c2ecf20Sopenharmony_ci	if (symbcomp < intp->symbol_rate[demod])
15488c2ecf20Sopenharmony_ci		coarse_srate = 0;
15498c2ecf20Sopenharmony_ci	else {
15508c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, DMDISTATE, 0x1f);
15518c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, TMGCFG2, 0xc1);
15528c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, TMGTHRISE, 0x20);
15538c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, TMGTHFALL, 0x00);
15548c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, TMGCFG, 0xd2);
15558c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
15568c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, AGC2REF, 0x38);
15578c2ecf20Sopenharmony_ci
15588c2ecf20Sopenharmony_ci		if (intp->chip_id >= 0x30)
15598c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CARFREQ, 0x79);
15608c2ecf20Sopenharmony_ci		else if (intp->chip_id >= 0x20)
15618c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CARFREQ, 0x49);
15628c2ecf20Sopenharmony_ci		else
15638c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CARFREQ, 0xed);
15648c2ecf20Sopenharmony_ci
15658c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, SFRUP1, (symbmax >> 8) & 0x7f);
15668c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, SFRUP0, (symbmax & 0xff));
15678c2ecf20Sopenharmony_ci
15688c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, SFRLOW1, (symbmin >> 8) & 0x7f);
15698c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, SFRLOW0, (symbmin & 0xff));
15708c2ecf20Sopenharmony_ci
15718c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0xff);
15728c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, SFRINIT0, (symb & 0xff));
15738c2ecf20Sopenharmony_ci
15748c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, DMDT0M, 0x20);
15758c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CFRINIT1, (coarse_freq >> 8) & 0xff);
15768c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CFRINIT0, coarse_freq  & 0xff);
15778c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, DMDISTATE, 0x15);
15788c2ecf20Sopenharmony_ci	}
15798c2ecf20Sopenharmony_ci
15808c2ecf20Sopenharmony_ci	return coarse_srate;
15818c2ecf20Sopenharmony_ci}
15828c2ecf20Sopenharmony_ci
15838c2ecf20Sopenharmony_cistatic int stv0900_blind_search_algo(struct dvb_frontend *fe)
15848c2ecf20Sopenharmony_ci{
15858c2ecf20Sopenharmony_ci	struct stv0900_state *state = fe->demodulator_priv;
15868c2ecf20Sopenharmony_ci	struct stv0900_internal *intp = state->internal;
15878c2ecf20Sopenharmony_ci	enum fe_stv0900_demod_num demod = state->demod;
15888c2ecf20Sopenharmony_ci	u8	k_ref_tmg,
15898c2ecf20Sopenharmony_ci		k_ref_tmg_max,
15908c2ecf20Sopenharmony_ci		k_ref_tmg_min;
15918c2ecf20Sopenharmony_ci	u32	coarse_srate,
15928c2ecf20Sopenharmony_ci		agc2_th;
15938c2ecf20Sopenharmony_ci	int	lock = FALSE,
15948c2ecf20Sopenharmony_ci		coarse_fail = FALSE;
15958c2ecf20Sopenharmony_ci	s32	demod_timeout = 500,
15968c2ecf20Sopenharmony_ci		fec_timeout = 50,
15978c2ecf20Sopenharmony_ci		fail_cpt,
15988c2ecf20Sopenharmony_ci		i,
15998c2ecf20Sopenharmony_ci		agc2_overflow;
16008c2ecf20Sopenharmony_ci	u16	agc2_int;
16018c2ecf20Sopenharmony_ci	u8	dstatus2;
16028c2ecf20Sopenharmony_ci
16038c2ecf20Sopenharmony_ci	dprintk("%s\n", __func__);
16048c2ecf20Sopenharmony_ci
16058c2ecf20Sopenharmony_ci	if (intp->chip_id < 0x20) {
16068c2ecf20Sopenharmony_ci		k_ref_tmg_max = 233;
16078c2ecf20Sopenharmony_ci		k_ref_tmg_min = 143;
16088c2ecf20Sopenharmony_ci	} else {
16098c2ecf20Sopenharmony_ci		k_ref_tmg_max = 110;
16108c2ecf20Sopenharmony_ci		k_ref_tmg_min = 10;
16118c2ecf20Sopenharmony_ci	}
16128c2ecf20Sopenharmony_ci
16138c2ecf20Sopenharmony_ci	if (intp->chip_id <= 0x20)
16148c2ecf20Sopenharmony_ci		agc2_th = STV0900_BLIND_SEARCH_AGC2_TH;
16158c2ecf20Sopenharmony_ci	else
16168c2ecf20Sopenharmony_ci		agc2_th = STV0900_BLIND_SEARCH_AGC2_TH_CUT30;
16178c2ecf20Sopenharmony_ci
16188c2ecf20Sopenharmony_ci	agc2_int = stv0900_blind_check_agc2_min_level(intp, demod);
16198c2ecf20Sopenharmony_ci
16208c2ecf20Sopenharmony_ci	dprintk("%s agc2_int=%d agc2_th=%d \n", __func__, agc2_int, agc2_th);
16218c2ecf20Sopenharmony_ci	if (agc2_int > agc2_th)
16228c2ecf20Sopenharmony_ci		return FALSE;
16238c2ecf20Sopenharmony_ci
16248c2ecf20Sopenharmony_ci	if (intp->chip_id == 0x10)
16258c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CORRELEXP, 0xaa);
16268c2ecf20Sopenharmony_ci
16278c2ecf20Sopenharmony_ci	if (intp->chip_id < 0x20)
16288c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CARHDR, 0x55);
16298c2ecf20Sopenharmony_ci	else
16308c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CARHDR, 0x20);
16318c2ecf20Sopenharmony_ci
16328c2ecf20Sopenharmony_ci	if (intp->chip_id <= 0x20)
16338c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CARCFG, 0xc4);
16348c2ecf20Sopenharmony_ci	else
16358c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CARCFG, 0x6);
16368c2ecf20Sopenharmony_ci
16378c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, RTCS2, 0x44);
16388c2ecf20Sopenharmony_ci
16398c2ecf20Sopenharmony_ci	if (intp->chip_id >= 0x20) {
16408c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, EQUALCFG, 0x41);
16418c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, FFECFG, 0x41);
16428c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, VITSCALE, 0x82);
16438c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, VAVSRVIT, 0x0);
16448c2ecf20Sopenharmony_ci	}
16458c2ecf20Sopenharmony_ci
16468c2ecf20Sopenharmony_ci	k_ref_tmg = k_ref_tmg_max;
16478c2ecf20Sopenharmony_ci
16488c2ecf20Sopenharmony_ci	do {
16498c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, KREFTMG, k_ref_tmg);
16508c2ecf20Sopenharmony_ci		if (stv0900_search_srate_coarse(fe) != 0) {
16518c2ecf20Sopenharmony_ci			coarse_srate = stv0900_search_srate_fine(fe);
16528c2ecf20Sopenharmony_ci
16538c2ecf20Sopenharmony_ci			if (coarse_srate != 0) {
16548c2ecf20Sopenharmony_ci				stv0900_get_lock_timeout(&demod_timeout,
16558c2ecf20Sopenharmony_ci							&fec_timeout,
16568c2ecf20Sopenharmony_ci							coarse_srate,
16578c2ecf20Sopenharmony_ci							STV0900_BLIND_SEARCH);
16588c2ecf20Sopenharmony_ci				lock = stv0900_get_demod_lock(intp,
16598c2ecf20Sopenharmony_ci							demod,
16608c2ecf20Sopenharmony_ci							demod_timeout);
16618c2ecf20Sopenharmony_ci			} else
16628c2ecf20Sopenharmony_ci				lock = FALSE;
16638c2ecf20Sopenharmony_ci		} else {
16648c2ecf20Sopenharmony_ci			fail_cpt = 0;
16658c2ecf20Sopenharmony_ci			agc2_overflow = 0;
16668c2ecf20Sopenharmony_ci
16678c2ecf20Sopenharmony_ci			for (i = 0; i < 10; i++) {
16688c2ecf20Sopenharmony_ci				agc2_int = (stv0900_read_reg(intp, AGC2I1) << 8)
16698c2ecf20Sopenharmony_ci					| stv0900_read_reg(intp, AGC2I0);
16708c2ecf20Sopenharmony_ci
16718c2ecf20Sopenharmony_ci				if (agc2_int >= 0xff00)
16728c2ecf20Sopenharmony_ci					agc2_overflow++;
16738c2ecf20Sopenharmony_ci
16748c2ecf20Sopenharmony_ci				dstatus2 = stv0900_read_reg(intp, DSTATUS2);
16758c2ecf20Sopenharmony_ci
16768c2ecf20Sopenharmony_ci				if (((dstatus2 & 0x1) == 0x1) &&
16778c2ecf20Sopenharmony_ci						((dstatus2 >> 7) == 1))
16788c2ecf20Sopenharmony_ci					fail_cpt++;
16798c2ecf20Sopenharmony_ci			}
16808c2ecf20Sopenharmony_ci
16818c2ecf20Sopenharmony_ci			if ((fail_cpt > 7) || (agc2_overflow > 7))
16828c2ecf20Sopenharmony_ci				coarse_fail = TRUE;
16838c2ecf20Sopenharmony_ci
16848c2ecf20Sopenharmony_ci			lock = FALSE;
16858c2ecf20Sopenharmony_ci		}
16868c2ecf20Sopenharmony_ci		k_ref_tmg -= 30;
16878c2ecf20Sopenharmony_ci	} while ((k_ref_tmg >= k_ref_tmg_min) &&
16888c2ecf20Sopenharmony_ci				(lock == FALSE) &&
16898c2ecf20Sopenharmony_ci				(coarse_fail == FALSE));
16908c2ecf20Sopenharmony_ci
16918c2ecf20Sopenharmony_ci	return lock;
16928c2ecf20Sopenharmony_ci}
16938c2ecf20Sopenharmony_ci
16948c2ecf20Sopenharmony_cistatic void stv0900_set_viterbi_acq(struct stv0900_internal *intp,
16958c2ecf20Sopenharmony_ci					enum fe_stv0900_demod_num demod)
16968c2ecf20Sopenharmony_ci{
16978c2ecf20Sopenharmony_ci	s32 vth_reg = VTH12;
16988c2ecf20Sopenharmony_ci
16998c2ecf20Sopenharmony_ci	dprintk("%s\n", __func__);
17008c2ecf20Sopenharmony_ci
17018c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, vth_reg++, 0x96);
17028c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, vth_reg++, 0x64);
17038c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, vth_reg++, 0x36);
17048c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, vth_reg++, 0x23);
17058c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, vth_reg++, 0x1e);
17068c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, vth_reg++, 0x19);
17078c2ecf20Sopenharmony_ci}
17088c2ecf20Sopenharmony_ci
17098c2ecf20Sopenharmony_cistatic void stv0900_set_search_standard(struct stv0900_internal *intp,
17108c2ecf20Sopenharmony_ci					enum fe_stv0900_demod_num demod)
17118c2ecf20Sopenharmony_ci{
17128c2ecf20Sopenharmony_ci
17138c2ecf20Sopenharmony_ci	dprintk("%s\n", __func__);
17148c2ecf20Sopenharmony_ci
17158c2ecf20Sopenharmony_ci	switch (intp->srch_standard[demod]) {
17168c2ecf20Sopenharmony_ci	case STV0900_SEARCH_DVBS1:
17178c2ecf20Sopenharmony_ci		dprintk("Search Standard = DVBS1\n");
17188c2ecf20Sopenharmony_ci		break;
17198c2ecf20Sopenharmony_ci	case STV0900_SEARCH_DSS:
17208c2ecf20Sopenharmony_ci		dprintk("Search Standard = DSS\n");
17218c2ecf20Sopenharmony_ci		break;
17228c2ecf20Sopenharmony_ci	case STV0900_SEARCH_DVBS2:
17238c2ecf20Sopenharmony_ci		dprintk("Search Standard = DVBS2\n");
17248c2ecf20Sopenharmony_ci		break;
17258c2ecf20Sopenharmony_ci	case STV0900_AUTO_SEARCH:
17268c2ecf20Sopenharmony_ci	default:
17278c2ecf20Sopenharmony_ci		dprintk("Search Standard = AUTO\n");
17288c2ecf20Sopenharmony_ci		break;
17298c2ecf20Sopenharmony_ci	}
17308c2ecf20Sopenharmony_ci
17318c2ecf20Sopenharmony_ci	switch (intp->srch_standard[demod]) {
17328c2ecf20Sopenharmony_ci	case STV0900_SEARCH_DVBS1:
17338c2ecf20Sopenharmony_ci	case STV0900_SEARCH_DSS:
17348c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, DVBS1_ENABLE, 1);
17358c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, DVBS2_ENABLE, 0);
17368c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, STOP_CLKVIT, 0);
17378c2ecf20Sopenharmony_ci		stv0900_set_dvbs1_track_car_loop(intp,
17388c2ecf20Sopenharmony_ci						demod,
17398c2ecf20Sopenharmony_ci						intp->symbol_rate[demod]);
17408c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CAR2CFG, 0x22);
17418c2ecf20Sopenharmony_ci
17428c2ecf20Sopenharmony_ci		stv0900_set_viterbi_acq(intp, demod);
17438c2ecf20Sopenharmony_ci		stv0900_set_viterbi_standard(intp,
17448c2ecf20Sopenharmony_ci					intp->srch_standard[demod],
17458c2ecf20Sopenharmony_ci					intp->fec[demod], demod);
17468c2ecf20Sopenharmony_ci
17478c2ecf20Sopenharmony_ci		break;
17488c2ecf20Sopenharmony_ci	case STV0900_SEARCH_DVBS2:
17498c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, DVBS1_ENABLE, 0);
17508c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, DVBS2_ENABLE, 1);
17518c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, STOP_CLKVIT, 1);
17528c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, ACLC, 0x1a);
17538c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, BCLC, 0x09);
17548c2ecf20Sopenharmony_ci		if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/
17558c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CAR2CFG, 0x26);
17568c2ecf20Sopenharmony_ci		else
17578c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CAR2CFG, 0x66);
17588c2ecf20Sopenharmony_ci
17598c2ecf20Sopenharmony_ci		if (intp->demod_mode != STV0900_SINGLE) {
17608c2ecf20Sopenharmony_ci			if (intp->chip_id <= 0x11)
17618c2ecf20Sopenharmony_ci				stv0900_stop_all_s2_modcod(intp, demod);
17628c2ecf20Sopenharmony_ci			else
17638c2ecf20Sopenharmony_ci				stv0900_activate_s2_modcod(intp, demod);
17648c2ecf20Sopenharmony_ci
17658c2ecf20Sopenharmony_ci		} else
17668c2ecf20Sopenharmony_ci			stv0900_activate_s2_modcod_single(intp, demod);
17678c2ecf20Sopenharmony_ci
17688c2ecf20Sopenharmony_ci		stv0900_set_viterbi_tracq(intp, demod);
17698c2ecf20Sopenharmony_ci
17708c2ecf20Sopenharmony_ci		break;
17718c2ecf20Sopenharmony_ci	case STV0900_AUTO_SEARCH:
17728c2ecf20Sopenharmony_ci	default:
17738c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, DVBS1_ENABLE, 1);
17748c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, DVBS2_ENABLE, 1);
17758c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, STOP_CLKVIT, 0);
17768c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, ACLC, 0x1a);
17778c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, BCLC, 0x09);
17788c2ecf20Sopenharmony_ci		stv0900_set_dvbs1_track_car_loop(intp,
17798c2ecf20Sopenharmony_ci						demod,
17808c2ecf20Sopenharmony_ci						intp->symbol_rate[demod]);
17818c2ecf20Sopenharmony_ci		if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/
17828c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CAR2CFG, 0x26);
17838c2ecf20Sopenharmony_ci		else
17848c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CAR2CFG, 0x66);
17858c2ecf20Sopenharmony_ci
17868c2ecf20Sopenharmony_ci		if (intp->demod_mode != STV0900_SINGLE) {
17878c2ecf20Sopenharmony_ci			if (intp->chip_id <= 0x11)
17888c2ecf20Sopenharmony_ci				stv0900_stop_all_s2_modcod(intp, demod);
17898c2ecf20Sopenharmony_ci			else
17908c2ecf20Sopenharmony_ci				stv0900_activate_s2_modcod(intp, demod);
17918c2ecf20Sopenharmony_ci
17928c2ecf20Sopenharmony_ci		} else
17938c2ecf20Sopenharmony_ci			stv0900_activate_s2_modcod_single(intp, demod);
17948c2ecf20Sopenharmony_ci
17958c2ecf20Sopenharmony_ci		stv0900_set_viterbi_tracq(intp, demod);
17968c2ecf20Sopenharmony_ci		stv0900_set_viterbi_standard(intp,
17978c2ecf20Sopenharmony_ci						intp->srch_standard[demod],
17988c2ecf20Sopenharmony_ci						intp->fec[demod], demod);
17998c2ecf20Sopenharmony_ci
18008c2ecf20Sopenharmony_ci		break;
18018c2ecf20Sopenharmony_ci	}
18028c2ecf20Sopenharmony_ci}
18038c2ecf20Sopenharmony_ci
18048c2ecf20Sopenharmony_cienum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe)
18058c2ecf20Sopenharmony_ci{
18068c2ecf20Sopenharmony_ci	struct stv0900_state *state = fe->demodulator_priv;
18078c2ecf20Sopenharmony_ci	struct stv0900_internal *intp = state->internal;
18088c2ecf20Sopenharmony_ci	enum fe_stv0900_demod_num demod = state->demod;
18098c2ecf20Sopenharmony_ci
18108c2ecf20Sopenharmony_ci	s32 demod_timeout = 500, fec_timeout = 50;
18118c2ecf20Sopenharmony_ci	s32 aq_power, agc1_power, i;
18128c2ecf20Sopenharmony_ci
18138c2ecf20Sopenharmony_ci	int lock = FALSE, low_sr = FALSE;
18148c2ecf20Sopenharmony_ci
18158c2ecf20Sopenharmony_ci	enum fe_stv0900_signal_type signal_type = STV0900_NOCARRIER;
18168c2ecf20Sopenharmony_ci	enum fe_stv0900_search_algo algo;
18178c2ecf20Sopenharmony_ci	int no_signal = FALSE;
18188c2ecf20Sopenharmony_ci
18198c2ecf20Sopenharmony_ci	dprintk("%s\n", __func__);
18208c2ecf20Sopenharmony_ci
18218c2ecf20Sopenharmony_ci	algo = intp->srch_algo[demod];
18228c2ecf20Sopenharmony_ci	stv0900_write_bits(intp, RST_HWARE, 1);
18238c2ecf20Sopenharmony_ci	stv0900_write_reg(intp, DMDISTATE, 0x5c);
18248c2ecf20Sopenharmony_ci	if (intp->chip_id >= 0x20) {
18258c2ecf20Sopenharmony_ci		if (intp->symbol_rate[demod] > 5000000)
18268c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CORRELABS, 0x9e);
18278c2ecf20Sopenharmony_ci		else
18288c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CORRELABS, 0x82);
18298c2ecf20Sopenharmony_ci	} else
18308c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CORRELABS, 0x88);
18318c2ecf20Sopenharmony_ci
18328c2ecf20Sopenharmony_ci	stv0900_get_lock_timeout(&demod_timeout, &fec_timeout,
18338c2ecf20Sopenharmony_ci				intp->symbol_rate[demod],
18348c2ecf20Sopenharmony_ci				intp->srch_algo[demod]);
18358c2ecf20Sopenharmony_ci
18368c2ecf20Sopenharmony_ci	if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) {
18378c2ecf20Sopenharmony_ci		intp->bw[demod] = 2 * 36000000;
18388c2ecf20Sopenharmony_ci
18398c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, TMGCFG2, 0xc0);
18408c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, CORRELMANT, 0x70);
18418c2ecf20Sopenharmony_ci
18428c2ecf20Sopenharmony_ci		stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod);
18438c2ecf20Sopenharmony_ci	} else {
18448c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, DMDT0M, 0x20);
18458c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, TMGCFG, 0xd2);
18468c2ecf20Sopenharmony_ci
18478c2ecf20Sopenharmony_ci		if (intp->symbol_rate[demod] < 2000000)
18488c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CORRELMANT, 0x63);
18498c2ecf20Sopenharmony_ci		else
18508c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, CORRELMANT, 0x70);
18518c2ecf20Sopenharmony_ci
18528c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, AGC2REF, 0x38);
18538c2ecf20Sopenharmony_ci
18548c2ecf20Sopenharmony_ci		intp->bw[demod] =
18558c2ecf20Sopenharmony_ci				stv0900_carrier_width(intp->symbol_rate[demod],
18568c2ecf20Sopenharmony_ci								intp->rolloff);
18578c2ecf20Sopenharmony_ci		if (intp->chip_id >= 0x20) {
18588c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, KREFTMG, 0x5a);
18598c2ecf20Sopenharmony_ci
18608c2ecf20Sopenharmony_ci			if (intp->srch_algo[demod] == STV0900_COLD_START) {
18618c2ecf20Sopenharmony_ci				intp->bw[demod] += 10000000;
18628c2ecf20Sopenharmony_ci				intp->bw[demod] *= 15;
18638c2ecf20Sopenharmony_ci				intp->bw[demod] /= 10;
18648c2ecf20Sopenharmony_ci			} else if (intp->srch_algo[demod] == STV0900_WARM_START)
18658c2ecf20Sopenharmony_ci				intp->bw[demod] += 10000000;
18668c2ecf20Sopenharmony_ci
18678c2ecf20Sopenharmony_ci		} else {
18688c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, KREFTMG, 0xc1);
18698c2ecf20Sopenharmony_ci			intp->bw[demod] += 10000000;
18708c2ecf20Sopenharmony_ci			intp->bw[demod] *= 15;
18718c2ecf20Sopenharmony_ci			intp->bw[demod] /= 10;
18728c2ecf20Sopenharmony_ci		}
18738c2ecf20Sopenharmony_ci
18748c2ecf20Sopenharmony_ci		stv0900_write_reg(intp, TMGCFG2, 0xc1);
18758c2ecf20Sopenharmony_ci
18768c2ecf20Sopenharmony_ci		stv0900_set_symbol_rate(intp, intp->mclk,
18778c2ecf20Sopenharmony_ci					intp->symbol_rate[demod], demod);
18788c2ecf20Sopenharmony_ci		stv0900_set_max_symbol_rate(intp, intp->mclk,
18798c2ecf20Sopenharmony_ci					intp->symbol_rate[demod], demod);
18808c2ecf20Sopenharmony_ci		stv0900_set_min_symbol_rate(intp, intp->mclk,
18818c2ecf20Sopenharmony_ci					intp->symbol_rate[demod], demod);
18828c2ecf20Sopenharmony_ci		if (intp->symbol_rate[demod] >= 10000000)
18838c2ecf20Sopenharmony_ci			low_sr = FALSE;
18848c2ecf20Sopenharmony_ci		else
18858c2ecf20Sopenharmony_ci			low_sr = TRUE;
18868c2ecf20Sopenharmony_ci
18878c2ecf20Sopenharmony_ci	}
18888c2ecf20Sopenharmony_ci
18898c2ecf20Sopenharmony_ci	if (intp->tuner_type[demod] == 3)
18908c2ecf20Sopenharmony_ci		stv0900_set_tuner_auto(intp, intp->freq[demod],
18918c2ecf20Sopenharmony_ci				intp->bw[demod], demod);
18928c2ecf20Sopenharmony_ci	else
18938c2ecf20Sopenharmony_ci		stv0900_set_tuner(fe, intp->freq[demod], intp->bw[demod]);
18948c2ecf20Sopenharmony_ci
18958c2ecf20Sopenharmony_ci	agc1_power = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1),
18968c2ecf20Sopenharmony_ci				stv0900_get_bits(intp, AGCIQ_VALUE0));
18978c2ecf20Sopenharmony_ci
18988c2ecf20Sopenharmony_ci	aq_power = 0;
18998c2ecf20Sopenharmony_ci
19008c2ecf20Sopenharmony_ci	if (agc1_power == 0) {
19018c2ecf20Sopenharmony_ci		for (i = 0; i < 5; i++)
19028c2ecf20Sopenharmony_ci			aq_power += (stv0900_get_bits(intp, POWER_I) +
19038c2ecf20Sopenharmony_ci					stv0900_get_bits(intp, POWER_Q)) / 2;
19048c2ecf20Sopenharmony_ci
19058c2ecf20Sopenharmony_ci		aq_power /= 5;
19068c2ecf20Sopenharmony_ci	}
19078c2ecf20Sopenharmony_ci
19088c2ecf20Sopenharmony_ci	if ((agc1_power == 0) && (aq_power < IQPOWER_THRESHOLD)) {
19098c2ecf20Sopenharmony_ci		intp->result[demod].locked = FALSE;
19108c2ecf20Sopenharmony_ci		signal_type = STV0900_NOAGC1;
19118c2ecf20Sopenharmony_ci		dprintk("%s: NO AGC1, POWERI, POWERQ\n", __func__);
19128c2ecf20Sopenharmony_ci	} else {
19138c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, SPECINV_CONTROL,
19148c2ecf20Sopenharmony_ci					intp->srch_iq_inv[demod]);
19158c2ecf20Sopenharmony_ci		if (intp->chip_id <= 0x20) /*cut 2.0*/
19168c2ecf20Sopenharmony_ci			stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
19178c2ecf20Sopenharmony_ci		else /*cut 3.0*/
19188c2ecf20Sopenharmony_ci			stv0900_write_bits(intp, MANUALS2_ROLLOFF, 1);
19198c2ecf20Sopenharmony_ci
19208c2ecf20Sopenharmony_ci		stv0900_set_search_standard(intp, demod);
19218c2ecf20Sopenharmony_ci
19228c2ecf20Sopenharmony_ci		if (intp->srch_algo[demod] != STV0900_BLIND_SEARCH)
19238c2ecf20Sopenharmony_ci			stv0900_start_search(intp, demod);
19248c2ecf20Sopenharmony_ci	}
19258c2ecf20Sopenharmony_ci
19268c2ecf20Sopenharmony_ci	if (signal_type == STV0900_NOAGC1)
19278c2ecf20Sopenharmony_ci		return signal_type;
19288c2ecf20Sopenharmony_ci
19298c2ecf20Sopenharmony_ci	if (intp->chip_id == 0x12) {
19308c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, RST_HWARE, 0);
19318c2ecf20Sopenharmony_ci		msleep(3);
19328c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, RST_HWARE, 1);
19338c2ecf20Sopenharmony_ci		stv0900_write_bits(intp, RST_HWARE, 0);
19348c2ecf20Sopenharmony_ci	}
19358c2ecf20Sopenharmony_ci
19368c2ecf20Sopenharmony_ci	if (algo == STV0900_BLIND_SEARCH)
19378c2ecf20Sopenharmony_ci		lock = stv0900_blind_search_algo(fe);
19388c2ecf20Sopenharmony_ci	else if (algo == STV0900_COLD_START)
19398c2ecf20Sopenharmony_ci		lock = stv0900_get_demod_cold_lock(fe, demod_timeout);
19408c2ecf20Sopenharmony_ci	else if (algo == STV0900_WARM_START)
19418c2ecf20Sopenharmony_ci		lock = stv0900_get_demod_lock(intp, demod, demod_timeout);
19428c2ecf20Sopenharmony_ci
19438c2ecf20Sopenharmony_ci	if ((lock == FALSE) && (algo == STV0900_COLD_START)) {
19448c2ecf20Sopenharmony_ci		if (low_sr == FALSE) {
19458c2ecf20Sopenharmony_ci			if (stv0900_check_timing_lock(intp, demod) == TRUE)
19468c2ecf20Sopenharmony_ci				lock = stv0900_sw_algo(intp, demod);
19478c2ecf20Sopenharmony_ci		}
19488c2ecf20Sopenharmony_ci	}
19498c2ecf20Sopenharmony_ci
19508c2ecf20Sopenharmony_ci	if (lock == TRUE)
19518c2ecf20Sopenharmony_ci		signal_type = stv0900_get_signal_params(fe);
19528c2ecf20Sopenharmony_ci
19538c2ecf20Sopenharmony_ci	if ((lock == TRUE) && (signal_type == STV0900_RANGEOK)) {
19548c2ecf20Sopenharmony_ci		stv0900_track_optimization(fe);
19558c2ecf20Sopenharmony_ci		if (intp->chip_id <= 0x11) {
19568c2ecf20Sopenharmony_ci			if ((stv0900_get_standard(fe, 0) ==
19578c2ecf20Sopenharmony_ci						STV0900_DVBS1_STANDARD) &&
19588c2ecf20Sopenharmony_ci			   (stv0900_get_standard(fe, 1) ==
19598c2ecf20Sopenharmony_ci						STV0900_DVBS1_STANDARD)) {
19608c2ecf20Sopenharmony_ci				msleep(20);
19618c2ecf20Sopenharmony_ci				stv0900_write_bits(intp, RST_HWARE, 0);
19628c2ecf20Sopenharmony_ci			} else {
19638c2ecf20Sopenharmony_ci				stv0900_write_bits(intp, RST_HWARE, 0);
19648c2ecf20Sopenharmony_ci				msleep(3);
19658c2ecf20Sopenharmony_ci				stv0900_write_bits(intp, RST_HWARE, 1);
19668c2ecf20Sopenharmony_ci				stv0900_write_bits(intp, RST_HWARE, 0);
19678c2ecf20Sopenharmony_ci			}
19688c2ecf20Sopenharmony_ci
19698c2ecf20Sopenharmony_ci		} else if (intp->chip_id >= 0x20) {
19708c2ecf20Sopenharmony_ci			stv0900_write_bits(intp, RST_HWARE, 0);
19718c2ecf20Sopenharmony_ci			msleep(3);
19728c2ecf20Sopenharmony_ci			stv0900_write_bits(intp, RST_HWARE, 1);
19738c2ecf20Sopenharmony_ci			stv0900_write_bits(intp, RST_HWARE, 0);
19748c2ecf20Sopenharmony_ci		}
19758c2ecf20Sopenharmony_ci
19768c2ecf20Sopenharmony_ci		if (stv0900_wait_for_lock(intp, demod,
19778c2ecf20Sopenharmony_ci					fec_timeout, fec_timeout) == TRUE) {
19788c2ecf20Sopenharmony_ci			lock = TRUE;
19798c2ecf20Sopenharmony_ci			intp->result[demod].locked = TRUE;
19808c2ecf20Sopenharmony_ci			if (intp->result[demod].standard ==
19818c2ecf20Sopenharmony_ci						STV0900_DVBS2_STANDARD) {
19828c2ecf20Sopenharmony_ci				stv0900_set_dvbs2_rolloff(intp, demod);
19838c2ecf20Sopenharmony_ci				stv0900_write_bits(intp, RESET_UPKO_COUNT, 1);
19848c2ecf20Sopenharmony_ci				stv0900_write_bits(intp, RESET_UPKO_COUNT, 0);
19858c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, ERRCTRL1, 0x67);
19868c2ecf20Sopenharmony_ci			} else {
19878c2ecf20Sopenharmony_ci				stv0900_write_reg(intp, ERRCTRL1, 0x75);
19888c2ecf20Sopenharmony_ci			}
19898c2ecf20Sopenharmony_ci
19908c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, FBERCPT4, 0);
19918c2ecf20Sopenharmony_ci			stv0900_write_reg(intp, ERRCTRL2, 0xc1);
19928c2ecf20Sopenharmony_ci		} else {
19938c2ecf20Sopenharmony_ci			lock = FALSE;
19948c2ecf20Sopenharmony_ci			signal_type = STV0900_NODATA;
19958c2ecf20Sopenharmony_ci			no_signal = stv0900_check_signal_presence(intp, demod);
19968c2ecf20Sopenharmony_ci
19978c2ecf20Sopenharmony_ci			intp->result[demod].locked = FALSE;
19988c2ecf20Sopenharmony_ci		}
19998c2ecf20Sopenharmony_ci	}
20008c2ecf20Sopenharmony_ci
20018c2ecf20Sopenharmony_ci	if ((signal_type != STV0900_NODATA) || (no_signal != FALSE))
20028c2ecf20Sopenharmony_ci		return signal_type;
20038c2ecf20Sopenharmony_ci
20048c2ecf20Sopenharmony_ci	if (intp->chip_id > 0x11) {
20058c2ecf20Sopenharmony_ci		intp->result[demod].locked = FALSE;
20068c2ecf20Sopenharmony_ci		return signal_type;
20078c2ecf20Sopenharmony_ci	}
20088c2ecf20Sopenharmony_ci
20098c2ecf20Sopenharmony_ci	if ((stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) &&
20108c2ecf20Sopenharmony_ci	   (intp->srch_iq_inv[demod] <= STV0900_IQ_AUTO_NORMAL_FIRST))
20118c2ecf20Sopenharmony_ci		signal_type = stv0900_dvbs1_acq_workaround(fe);
20128c2ecf20Sopenharmony_ci
20138c2ecf20Sopenharmony_ci	return signal_type;
20148c2ecf20Sopenharmony_ci}
20158c2ecf20Sopenharmony_ci
2016