1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * stv0900_sw.c
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Driver for ST STV0900 satellite demodulator IC.
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Copyright (C) ST Microelectronics.
8*4882a593Smuzhiyun * Copyright (C) 2009 NetUP Inc.
9*4882a593Smuzhiyun * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
10*4882a593Smuzhiyun */
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include "stv0900.h"
13*4882a593Smuzhiyun #include "stv0900_reg.h"
14*4882a593Smuzhiyun #include "stv0900_priv.h"
15*4882a593Smuzhiyun
shiftx(s32 x,int demod,s32 shift)16*4882a593Smuzhiyun s32 shiftx(s32 x, int demod, s32 shift)
17*4882a593Smuzhiyun {
18*4882a593Smuzhiyun if (demod == 1)
19*4882a593Smuzhiyun return x - shift;
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun return x;
22*4882a593Smuzhiyun }
23*4882a593Smuzhiyun
stv0900_check_signal_presence(struct stv0900_internal * intp,enum fe_stv0900_demod_num demod)24*4882a593Smuzhiyun int stv0900_check_signal_presence(struct stv0900_internal *intp,
25*4882a593Smuzhiyun enum fe_stv0900_demod_num demod)
26*4882a593Smuzhiyun {
27*4882a593Smuzhiyun s32 carr_offset,
28*4882a593Smuzhiyun agc2_integr,
29*4882a593Smuzhiyun max_carrier;
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun int no_signal = FALSE;
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun carr_offset = (stv0900_read_reg(intp, CFR2) << 8)
34*4882a593Smuzhiyun | stv0900_read_reg(intp, CFR1);
35*4882a593Smuzhiyun carr_offset = ge2comp(carr_offset, 16);
36*4882a593Smuzhiyun agc2_integr = (stv0900_read_reg(intp, AGC2I1) << 8)
37*4882a593Smuzhiyun | stv0900_read_reg(intp, AGC2I0);
38*4882a593Smuzhiyun max_carrier = intp->srch_range[demod] / 1000;
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun max_carrier += (max_carrier / 10);
41*4882a593Smuzhiyun max_carrier = 65536 * (max_carrier / 2);
42*4882a593Smuzhiyun max_carrier /= intp->mclk / 1000;
43*4882a593Smuzhiyun if (max_carrier > 0x4000)
44*4882a593Smuzhiyun max_carrier = 0x4000;
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun if ((agc2_integr > 0x2000)
47*4882a593Smuzhiyun || (carr_offset > (2 * max_carrier))
48*4882a593Smuzhiyun || (carr_offset < (-2 * max_carrier)))
49*4882a593Smuzhiyun no_signal = TRUE;
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun return no_signal;
52*4882a593Smuzhiyun }
53*4882a593Smuzhiyun
stv0900_get_sw_loop_params(struct stv0900_internal * intp,s32 * frequency_inc,s32 * sw_timeout,s32 * steps,enum fe_stv0900_demod_num demod)54*4882a593Smuzhiyun static void stv0900_get_sw_loop_params(struct stv0900_internal *intp,
55*4882a593Smuzhiyun s32 *frequency_inc, s32 *sw_timeout,
56*4882a593Smuzhiyun s32 *steps,
57*4882a593Smuzhiyun enum fe_stv0900_demod_num demod)
58*4882a593Smuzhiyun {
59*4882a593Smuzhiyun s32 timeout, freq_inc, max_steps, srate, max_carrier;
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun enum fe_stv0900_search_standard standard;
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun srate = intp->symbol_rate[demod];
64*4882a593Smuzhiyun max_carrier = intp->srch_range[demod] / 1000;
65*4882a593Smuzhiyun max_carrier += max_carrier / 10;
66*4882a593Smuzhiyun standard = intp->srch_standard[demod];
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun max_carrier = 65536 * (max_carrier / 2);
69*4882a593Smuzhiyun max_carrier /= intp->mclk / 1000;
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun if (max_carrier > 0x4000)
72*4882a593Smuzhiyun max_carrier = 0x4000;
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun freq_inc = srate;
75*4882a593Smuzhiyun freq_inc /= intp->mclk >> 10;
76*4882a593Smuzhiyun freq_inc = freq_inc << 6;
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun switch (standard) {
79*4882a593Smuzhiyun case STV0900_SEARCH_DVBS1:
80*4882a593Smuzhiyun case STV0900_SEARCH_DSS:
81*4882a593Smuzhiyun freq_inc *= 3;
82*4882a593Smuzhiyun timeout = 20;
83*4882a593Smuzhiyun break;
84*4882a593Smuzhiyun case STV0900_SEARCH_DVBS2:
85*4882a593Smuzhiyun freq_inc *= 4;
86*4882a593Smuzhiyun timeout = 25;
87*4882a593Smuzhiyun break;
88*4882a593Smuzhiyun case STV0900_AUTO_SEARCH:
89*4882a593Smuzhiyun default:
90*4882a593Smuzhiyun freq_inc *= 3;
91*4882a593Smuzhiyun timeout = 25;
92*4882a593Smuzhiyun break;
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun freq_inc /= 100;
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun if ((freq_inc > max_carrier) || (freq_inc < 0))
98*4882a593Smuzhiyun freq_inc = max_carrier / 2;
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun timeout *= 27500;
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun if (srate > 0)
103*4882a593Smuzhiyun timeout /= srate / 1000;
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun if ((timeout > 100) || (timeout < 0))
106*4882a593Smuzhiyun timeout = 100;
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun max_steps = (max_carrier / freq_inc) + 1;
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun if ((max_steps > 100) || (max_steps < 0)) {
111*4882a593Smuzhiyun max_steps = 100;
112*4882a593Smuzhiyun freq_inc = max_carrier / max_steps;
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun *frequency_inc = freq_inc;
116*4882a593Smuzhiyun *sw_timeout = timeout;
117*4882a593Smuzhiyun *steps = max_steps;
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun
stv0900_search_carr_sw_loop(struct stv0900_internal * intp,s32 FreqIncr,s32 Timeout,int zigzag,s32 MaxStep,enum fe_stv0900_demod_num demod)121*4882a593Smuzhiyun static int stv0900_search_carr_sw_loop(struct stv0900_internal *intp,
122*4882a593Smuzhiyun s32 FreqIncr, s32 Timeout, int zigzag,
123*4882a593Smuzhiyun s32 MaxStep, enum fe_stv0900_demod_num demod)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun int no_signal,
126*4882a593Smuzhiyun lock = FALSE;
127*4882a593Smuzhiyun s32 stepCpt,
128*4882a593Smuzhiyun freqOffset,
129*4882a593Smuzhiyun max_carrier;
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun max_carrier = intp->srch_range[demod] / 1000;
132*4882a593Smuzhiyun max_carrier += (max_carrier / 10);
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun max_carrier = 65536 * (max_carrier / 2);
135*4882a593Smuzhiyun max_carrier /= intp->mclk / 1000;
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun if (max_carrier > 0x4000)
138*4882a593Smuzhiyun max_carrier = 0x4000;
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun if (zigzag == TRUE)
141*4882a593Smuzhiyun freqOffset = 0;
142*4882a593Smuzhiyun else
143*4882a593Smuzhiyun freqOffset = -max_carrier + FreqIncr;
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun stepCpt = 0;
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun do {
148*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x1c);
149*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT1, (freqOffset / 256) & 0xff);
150*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT0, freqOffset & 0xff);
151*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x18);
152*4882a593Smuzhiyun stv0900_write_bits(intp, ALGOSWRST, 1);
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun if (intp->chip_id == 0x12) {
155*4882a593Smuzhiyun stv0900_write_bits(intp, RST_HWARE, 1);
156*4882a593Smuzhiyun stv0900_write_bits(intp, RST_HWARE, 0);
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun if (zigzag == TRUE) {
160*4882a593Smuzhiyun if (freqOffset >= 0)
161*4882a593Smuzhiyun freqOffset = -freqOffset - 2 * FreqIncr;
162*4882a593Smuzhiyun else
163*4882a593Smuzhiyun freqOffset = -freqOffset;
164*4882a593Smuzhiyun } else
165*4882a593Smuzhiyun freqOffset += + 2 * FreqIncr;
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun stepCpt++;
168*4882a593Smuzhiyun lock = stv0900_get_demod_lock(intp, demod, Timeout);
169*4882a593Smuzhiyun no_signal = stv0900_check_signal_presence(intp, demod);
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun } while ((lock == FALSE)
172*4882a593Smuzhiyun && (no_signal == FALSE)
173*4882a593Smuzhiyun && ((freqOffset - FreqIncr) < max_carrier)
174*4882a593Smuzhiyun && ((freqOffset + FreqIncr) > -max_carrier)
175*4882a593Smuzhiyun && (stepCpt < MaxStep));
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun stv0900_write_bits(intp, ALGOSWRST, 0);
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun return lock;
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun
stv0900_sw_algo(struct stv0900_internal * intp,enum fe_stv0900_demod_num demod)182*4882a593Smuzhiyun static int stv0900_sw_algo(struct stv0900_internal *intp,
183*4882a593Smuzhiyun enum fe_stv0900_demod_num demod)
184*4882a593Smuzhiyun {
185*4882a593Smuzhiyun int lock = FALSE,
186*4882a593Smuzhiyun no_signal,
187*4882a593Smuzhiyun zigzag;
188*4882a593Smuzhiyun s32 s2fw,
189*4882a593Smuzhiyun fqc_inc,
190*4882a593Smuzhiyun sft_stp_tout,
191*4882a593Smuzhiyun trial_cntr,
192*4882a593Smuzhiyun max_steps;
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun stv0900_get_sw_loop_params(intp, &fqc_inc, &sft_stp_tout,
195*4882a593Smuzhiyun &max_steps, demod);
196*4882a593Smuzhiyun switch (intp->srch_standard[demod]) {
197*4882a593Smuzhiyun case STV0900_SEARCH_DVBS1:
198*4882a593Smuzhiyun case STV0900_SEARCH_DSS:
199*4882a593Smuzhiyun if (intp->chip_id >= 0x20)
200*4882a593Smuzhiyun stv0900_write_reg(intp, CARFREQ, 0x3b);
201*4882a593Smuzhiyun else
202*4882a593Smuzhiyun stv0900_write_reg(intp, CARFREQ, 0xef);
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun stv0900_write_reg(intp, DMDCFGMD, 0x49);
205*4882a593Smuzhiyun zigzag = FALSE;
206*4882a593Smuzhiyun break;
207*4882a593Smuzhiyun case STV0900_SEARCH_DVBS2:
208*4882a593Smuzhiyun if (intp->chip_id >= 0x20)
209*4882a593Smuzhiyun stv0900_write_reg(intp, CORRELABS, 0x79);
210*4882a593Smuzhiyun else
211*4882a593Smuzhiyun stv0900_write_reg(intp, CORRELABS, 0x68);
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun stv0900_write_reg(intp, DMDCFGMD, 0x89);
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun zigzag = TRUE;
216*4882a593Smuzhiyun break;
217*4882a593Smuzhiyun case STV0900_AUTO_SEARCH:
218*4882a593Smuzhiyun default:
219*4882a593Smuzhiyun if (intp->chip_id >= 0x20) {
220*4882a593Smuzhiyun stv0900_write_reg(intp, CARFREQ, 0x3b);
221*4882a593Smuzhiyun stv0900_write_reg(intp, CORRELABS, 0x79);
222*4882a593Smuzhiyun } else {
223*4882a593Smuzhiyun stv0900_write_reg(intp, CARFREQ, 0xef);
224*4882a593Smuzhiyun stv0900_write_reg(intp, CORRELABS, 0x68);
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun stv0900_write_reg(intp, DMDCFGMD, 0xc9);
228*4882a593Smuzhiyun zigzag = FALSE;
229*4882a593Smuzhiyun break;
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun trial_cntr = 0;
233*4882a593Smuzhiyun do {
234*4882a593Smuzhiyun lock = stv0900_search_carr_sw_loop(intp,
235*4882a593Smuzhiyun fqc_inc,
236*4882a593Smuzhiyun sft_stp_tout,
237*4882a593Smuzhiyun zigzag,
238*4882a593Smuzhiyun max_steps,
239*4882a593Smuzhiyun demod);
240*4882a593Smuzhiyun no_signal = stv0900_check_signal_presence(intp, demod);
241*4882a593Smuzhiyun trial_cntr++;
242*4882a593Smuzhiyun if ((lock == TRUE)
243*4882a593Smuzhiyun || (no_signal == TRUE)
244*4882a593Smuzhiyun || (trial_cntr == 2)) {
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun if (intp->chip_id >= 0x20) {
247*4882a593Smuzhiyun stv0900_write_reg(intp, CARFREQ, 0x49);
248*4882a593Smuzhiyun stv0900_write_reg(intp, CORRELABS, 0x9e);
249*4882a593Smuzhiyun } else {
250*4882a593Smuzhiyun stv0900_write_reg(intp, CARFREQ, 0xed);
251*4882a593Smuzhiyun stv0900_write_reg(intp, CORRELABS, 0x88);
252*4882a593Smuzhiyun }
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun if ((stv0900_get_bits(intp, HEADER_MODE) ==
255*4882a593Smuzhiyun STV0900_DVBS2_FOUND) &&
256*4882a593Smuzhiyun (lock == TRUE)) {
257*4882a593Smuzhiyun msleep(sft_stp_tout);
258*4882a593Smuzhiyun s2fw = stv0900_get_bits(intp, FLYWHEEL_CPT);
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun if (s2fw < 0xd) {
261*4882a593Smuzhiyun msleep(sft_stp_tout);
262*4882a593Smuzhiyun s2fw = stv0900_get_bits(intp,
263*4882a593Smuzhiyun FLYWHEEL_CPT);
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun if (s2fw < 0xd) {
267*4882a593Smuzhiyun lock = FALSE;
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun if (trial_cntr < 2) {
270*4882a593Smuzhiyun if (intp->chip_id >= 0x20)
271*4882a593Smuzhiyun stv0900_write_reg(intp,
272*4882a593Smuzhiyun CORRELABS,
273*4882a593Smuzhiyun 0x79);
274*4882a593Smuzhiyun else
275*4882a593Smuzhiyun stv0900_write_reg(intp,
276*4882a593Smuzhiyun CORRELABS,
277*4882a593Smuzhiyun 0x68);
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun stv0900_write_reg(intp,
280*4882a593Smuzhiyun DMDCFGMD,
281*4882a593Smuzhiyun 0x89);
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun }
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun } while ((lock == FALSE)
288*4882a593Smuzhiyun && (trial_cntr < 2)
289*4882a593Smuzhiyun && (no_signal == FALSE));
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun return lock;
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun
stv0900_get_symbol_rate(struct stv0900_internal * intp,u32 mclk,enum fe_stv0900_demod_num demod)294*4882a593Smuzhiyun static u32 stv0900_get_symbol_rate(struct stv0900_internal *intp,
295*4882a593Smuzhiyun u32 mclk,
296*4882a593Smuzhiyun enum fe_stv0900_demod_num demod)
297*4882a593Smuzhiyun {
298*4882a593Smuzhiyun s32 rem1, rem2, intval1, intval2, srate;
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun srate = (stv0900_get_bits(intp, SYMB_FREQ3) << 24) +
301*4882a593Smuzhiyun (stv0900_get_bits(intp, SYMB_FREQ2) << 16) +
302*4882a593Smuzhiyun (stv0900_get_bits(intp, SYMB_FREQ1) << 8) +
303*4882a593Smuzhiyun (stv0900_get_bits(intp, SYMB_FREQ0));
304*4882a593Smuzhiyun dprintk("lock: srate=%d r0=0x%x r1=0x%x r2=0x%x r3=0x%x \n",
305*4882a593Smuzhiyun srate, stv0900_get_bits(intp, SYMB_FREQ0),
306*4882a593Smuzhiyun stv0900_get_bits(intp, SYMB_FREQ1),
307*4882a593Smuzhiyun stv0900_get_bits(intp, SYMB_FREQ2),
308*4882a593Smuzhiyun stv0900_get_bits(intp, SYMB_FREQ3));
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun intval1 = (mclk) >> 16;
311*4882a593Smuzhiyun intval2 = (srate) >> 16;
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun rem1 = (mclk) % 0x10000;
314*4882a593Smuzhiyun rem2 = (srate) % 0x10000;
315*4882a593Smuzhiyun srate = (intval1 * intval2) +
316*4882a593Smuzhiyun ((intval1 * rem2) >> 16) +
317*4882a593Smuzhiyun ((intval2 * rem1) >> 16);
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun return srate;
320*4882a593Smuzhiyun }
321*4882a593Smuzhiyun
stv0900_set_symbol_rate(struct stv0900_internal * intp,u32 mclk,u32 srate,enum fe_stv0900_demod_num demod)322*4882a593Smuzhiyun static void stv0900_set_symbol_rate(struct stv0900_internal *intp,
323*4882a593Smuzhiyun u32 mclk, u32 srate,
324*4882a593Smuzhiyun enum fe_stv0900_demod_num demod)
325*4882a593Smuzhiyun {
326*4882a593Smuzhiyun u32 symb;
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun dprintk("%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk,
329*4882a593Smuzhiyun srate, demod);
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun if (srate > 60000000) {
332*4882a593Smuzhiyun symb = srate << 4;
333*4882a593Smuzhiyun symb /= (mclk >> 12);
334*4882a593Smuzhiyun } else if (srate > 6000000) {
335*4882a593Smuzhiyun symb = srate << 6;
336*4882a593Smuzhiyun symb /= (mclk >> 10);
337*4882a593Smuzhiyun } else {
338*4882a593Smuzhiyun symb = srate << 9;
339*4882a593Smuzhiyun symb /= (mclk >> 7);
340*4882a593Smuzhiyun }
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0x7f);
343*4882a593Smuzhiyun stv0900_write_reg(intp, SFRINIT1 + 1, (symb & 0xff));
344*4882a593Smuzhiyun }
345*4882a593Smuzhiyun
stv0900_set_max_symbol_rate(struct stv0900_internal * intp,u32 mclk,u32 srate,enum fe_stv0900_demod_num demod)346*4882a593Smuzhiyun static void stv0900_set_max_symbol_rate(struct stv0900_internal *intp,
347*4882a593Smuzhiyun u32 mclk, u32 srate,
348*4882a593Smuzhiyun enum fe_stv0900_demod_num demod)
349*4882a593Smuzhiyun {
350*4882a593Smuzhiyun u32 symb;
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun srate = 105 * (srate / 100);
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun if (srate > 60000000) {
355*4882a593Smuzhiyun symb = srate << 4;
356*4882a593Smuzhiyun symb /= (mclk >> 12);
357*4882a593Smuzhiyun } else if (srate > 6000000) {
358*4882a593Smuzhiyun symb = srate << 6;
359*4882a593Smuzhiyun symb /= (mclk >> 10);
360*4882a593Smuzhiyun } else {
361*4882a593Smuzhiyun symb = srate << 9;
362*4882a593Smuzhiyun symb /= (mclk >> 7);
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun if (symb < 0x7fff) {
366*4882a593Smuzhiyun stv0900_write_reg(intp, SFRUP1, (symb >> 8) & 0x7f);
367*4882a593Smuzhiyun stv0900_write_reg(intp, SFRUP1 + 1, (symb & 0xff));
368*4882a593Smuzhiyun } else {
369*4882a593Smuzhiyun stv0900_write_reg(intp, SFRUP1, 0x7f);
370*4882a593Smuzhiyun stv0900_write_reg(intp, SFRUP1 + 1, 0xff);
371*4882a593Smuzhiyun }
372*4882a593Smuzhiyun }
373*4882a593Smuzhiyun
stv0900_set_min_symbol_rate(struct stv0900_internal * intp,u32 mclk,u32 srate,enum fe_stv0900_demod_num demod)374*4882a593Smuzhiyun static void stv0900_set_min_symbol_rate(struct stv0900_internal *intp,
375*4882a593Smuzhiyun u32 mclk, u32 srate,
376*4882a593Smuzhiyun enum fe_stv0900_demod_num demod)
377*4882a593Smuzhiyun {
378*4882a593Smuzhiyun u32 symb;
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun srate = 95 * (srate / 100);
381*4882a593Smuzhiyun if (srate > 60000000) {
382*4882a593Smuzhiyun symb = srate << 4;
383*4882a593Smuzhiyun symb /= (mclk >> 12);
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun } else if (srate > 6000000) {
386*4882a593Smuzhiyun symb = srate << 6;
387*4882a593Smuzhiyun symb /= (mclk >> 10);
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun } else {
390*4882a593Smuzhiyun symb = srate << 9;
391*4882a593Smuzhiyun symb /= (mclk >> 7);
392*4882a593Smuzhiyun }
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun stv0900_write_reg(intp, SFRLOW1, (symb >> 8) & 0xff);
395*4882a593Smuzhiyun stv0900_write_reg(intp, SFRLOW1 + 1, (symb & 0xff));
396*4882a593Smuzhiyun }
397*4882a593Smuzhiyun
stv0900_get_timing_offst(struct stv0900_internal * intp,u32 srate,enum fe_stv0900_demod_num demod)398*4882a593Smuzhiyun static s32 stv0900_get_timing_offst(struct stv0900_internal *intp,
399*4882a593Smuzhiyun u32 srate,
400*4882a593Smuzhiyun enum fe_stv0900_demod_num demod)
401*4882a593Smuzhiyun {
402*4882a593Smuzhiyun s32 timingoffset;
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun timingoffset = (stv0900_read_reg(intp, TMGREG2) << 16) +
406*4882a593Smuzhiyun (stv0900_read_reg(intp, TMGREG2 + 1) << 8) +
407*4882a593Smuzhiyun (stv0900_read_reg(intp, TMGREG2 + 2));
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun timingoffset = ge2comp(timingoffset, 24);
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun
412*4882a593Smuzhiyun if (timingoffset == 0)
413*4882a593Smuzhiyun timingoffset = 1;
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun timingoffset = ((s32)srate * 10) / ((s32)0x1000000 / timingoffset);
416*4882a593Smuzhiyun timingoffset /= 320;
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun return timingoffset;
419*4882a593Smuzhiyun }
420*4882a593Smuzhiyun
stv0900_set_dvbs2_rolloff(struct stv0900_internal * intp,enum fe_stv0900_demod_num demod)421*4882a593Smuzhiyun static void stv0900_set_dvbs2_rolloff(struct stv0900_internal *intp,
422*4882a593Smuzhiyun enum fe_stv0900_demod_num demod)
423*4882a593Smuzhiyun {
424*4882a593Smuzhiyun s32 rolloff;
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun if (intp->chip_id == 0x10) {
427*4882a593Smuzhiyun stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
428*4882a593Smuzhiyun rolloff = stv0900_read_reg(intp, MATSTR1) & 0x03;
429*4882a593Smuzhiyun stv0900_write_bits(intp, ROLLOFF_CONTROL, rolloff);
430*4882a593Smuzhiyun } else if (intp->chip_id <= 0x20)
431*4882a593Smuzhiyun stv0900_write_bits(intp, MANUALSX_ROLLOFF, 0);
432*4882a593Smuzhiyun else /* cut 3.0 */
433*4882a593Smuzhiyun stv0900_write_bits(intp, MANUALS2_ROLLOFF, 0);
434*4882a593Smuzhiyun }
435*4882a593Smuzhiyun
stv0900_carrier_width(u32 srate,enum fe_stv0900_rolloff ro)436*4882a593Smuzhiyun static u32 stv0900_carrier_width(u32 srate, enum fe_stv0900_rolloff ro)
437*4882a593Smuzhiyun {
438*4882a593Smuzhiyun u32 rolloff;
439*4882a593Smuzhiyun
440*4882a593Smuzhiyun switch (ro) {
441*4882a593Smuzhiyun case STV0900_20:
442*4882a593Smuzhiyun rolloff = 20;
443*4882a593Smuzhiyun break;
444*4882a593Smuzhiyun case STV0900_25:
445*4882a593Smuzhiyun rolloff = 25;
446*4882a593Smuzhiyun break;
447*4882a593Smuzhiyun case STV0900_35:
448*4882a593Smuzhiyun default:
449*4882a593Smuzhiyun rolloff = 35;
450*4882a593Smuzhiyun break;
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun
453*4882a593Smuzhiyun return srate + (srate * rolloff) / 100;
454*4882a593Smuzhiyun }
455*4882a593Smuzhiyun
stv0900_check_timing_lock(struct stv0900_internal * intp,enum fe_stv0900_demod_num demod)456*4882a593Smuzhiyun static int stv0900_check_timing_lock(struct stv0900_internal *intp,
457*4882a593Smuzhiyun enum fe_stv0900_demod_num demod)
458*4882a593Smuzhiyun {
459*4882a593Smuzhiyun int timingLock = FALSE;
460*4882a593Smuzhiyun s32 i,
461*4882a593Smuzhiyun timingcpt = 0;
462*4882a593Smuzhiyun u8 car_freq,
463*4882a593Smuzhiyun tmg_th_high,
464*4882a593Smuzhiyun tmg_th_low;
465*4882a593Smuzhiyun
466*4882a593Smuzhiyun car_freq = stv0900_read_reg(intp, CARFREQ);
467*4882a593Smuzhiyun tmg_th_high = stv0900_read_reg(intp, TMGTHRISE);
468*4882a593Smuzhiyun tmg_th_low = stv0900_read_reg(intp, TMGTHFALL);
469*4882a593Smuzhiyun stv0900_write_reg(intp, TMGTHRISE, 0x20);
470*4882a593Smuzhiyun stv0900_write_reg(intp, TMGTHFALL, 0x0);
471*4882a593Smuzhiyun stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
472*4882a593Smuzhiyun stv0900_write_reg(intp, RTC, 0x80);
473*4882a593Smuzhiyun stv0900_write_reg(intp, RTCS2, 0x40);
474*4882a593Smuzhiyun stv0900_write_reg(intp, CARFREQ, 0x0);
475*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT1, 0x0);
476*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT0, 0x0);
477*4882a593Smuzhiyun stv0900_write_reg(intp, AGC2REF, 0x65);
478*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x18);
479*4882a593Smuzhiyun msleep(7);
480*4882a593Smuzhiyun
481*4882a593Smuzhiyun for (i = 0; i < 10; i++) {
482*4882a593Smuzhiyun if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2)
483*4882a593Smuzhiyun timingcpt++;
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun msleep(1);
486*4882a593Smuzhiyun }
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun if (timingcpt >= 3)
489*4882a593Smuzhiyun timingLock = TRUE;
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun stv0900_write_reg(intp, AGC2REF, 0x38);
492*4882a593Smuzhiyun stv0900_write_reg(intp, RTC, 0x88);
493*4882a593Smuzhiyun stv0900_write_reg(intp, RTCS2, 0x68);
494*4882a593Smuzhiyun stv0900_write_reg(intp, CARFREQ, car_freq);
495*4882a593Smuzhiyun stv0900_write_reg(intp, TMGTHRISE, tmg_th_high);
496*4882a593Smuzhiyun stv0900_write_reg(intp, TMGTHFALL, tmg_th_low);
497*4882a593Smuzhiyun
498*4882a593Smuzhiyun return timingLock;
499*4882a593Smuzhiyun }
500*4882a593Smuzhiyun
stv0900_get_demod_cold_lock(struct dvb_frontend * fe,s32 demod_timeout)501*4882a593Smuzhiyun static int stv0900_get_demod_cold_lock(struct dvb_frontend *fe,
502*4882a593Smuzhiyun s32 demod_timeout)
503*4882a593Smuzhiyun {
504*4882a593Smuzhiyun struct stv0900_state *state = fe->demodulator_priv;
505*4882a593Smuzhiyun struct stv0900_internal *intp = state->internal;
506*4882a593Smuzhiyun enum fe_stv0900_demod_num demod = state->demod;
507*4882a593Smuzhiyun int lock = FALSE,
508*4882a593Smuzhiyun d = demod;
509*4882a593Smuzhiyun s32 srate,
510*4882a593Smuzhiyun search_range,
511*4882a593Smuzhiyun locktimeout,
512*4882a593Smuzhiyun currier_step,
513*4882a593Smuzhiyun nb_steps,
514*4882a593Smuzhiyun current_step,
515*4882a593Smuzhiyun direction,
516*4882a593Smuzhiyun tuner_freq,
517*4882a593Smuzhiyun timeout,
518*4882a593Smuzhiyun freq;
519*4882a593Smuzhiyun
520*4882a593Smuzhiyun srate = intp->symbol_rate[d];
521*4882a593Smuzhiyun search_range = intp->srch_range[d];
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun if (srate >= 10000000)
524*4882a593Smuzhiyun locktimeout = demod_timeout / 3;
525*4882a593Smuzhiyun else
526*4882a593Smuzhiyun locktimeout = demod_timeout / 2;
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun lock = stv0900_get_demod_lock(intp, d, locktimeout);
529*4882a593Smuzhiyun
530*4882a593Smuzhiyun if (lock != FALSE)
531*4882a593Smuzhiyun return lock;
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun if (srate >= 10000000) {
534*4882a593Smuzhiyun if (stv0900_check_timing_lock(intp, d) == TRUE) {
535*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x1f);
536*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x15);
537*4882a593Smuzhiyun lock = stv0900_get_demod_lock(intp, d, demod_timeout);
538*4882a593Smuzhiyun } else
539*4882a593Smuzhiyun lock = FALSE;
540*4882a593Smuzhiyun
541*4882a593Smuzhiyun return lock;
542*4882a593Smuzhiyun }
543*4882a593Smuzhiyun
544*4882a593Smuzhiyun if (intp->chip_id <= 0x20) {
545*4882a593Smuzhiyun if (srate <= 1000000)
546*4882a593Smuzhiyun currier_step = 500;
547*4882a593Smuzhiyun else if (srate <= 4000000)
548*4882a593Smuzhiyun currier_step = 1000;
549*4882a593Smuzhiyun else if (srate <= 7000000)
550*4882a593Smuzhiyun currier_step = 2000;
551*4882a593Smuzhiyun else if (srate <= 10000000)
552*4882a593Smuzhiyun currier_step = 3000;
553*4882a593Smuzhiyun else
554*4882a593Smuzhiyun currier_step = 5000;
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun if (srate >= 2000000) {
557*4882a593Smuzhiyun timeout = (demod_timeout / 3);
558*4882a593Smuzhiyun if (timeout > 1000)
559*4882a593Smuzhiyun timeout = 1000;
560*4882a593Smuzhiyun } else
561*4882a593Smuzhiyun timeout = (demod_timeout / 2);
562*4882a593Smuzhiyun } else {
563*4882a593Smuzhiyun /*cut 3.0 */
564*4882a593Smuzhiyun currier_step = srate / 4000;
565*4882a593Smuzhiyun timeout = (demod_timeout * 3) / 4;
566*4882a593Smuzhiyun }
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun nb_steps = ((search_range / 1000) / currier_step);
569*4882a593Smuzhiyun
570*4882a593Smuzhiyun if ((nb_steps % 2) != 0)
571*4882a593Smuzhiyun nb_steps += 1;
572*4882a593Smuzhiyun
573*4882a593Smuzhiyun if (nb_steps <= 0)
574*4882a593Smuzhiyun nb_steps = 2;
575*4882a593Smuzhiyun else if (nb_steps > 12)
576*4882a593Smuzhiyun nb_steps = 12;
577*4882a593Smuzhiyun
578*4882a593Smuzhiyun current_step = 1;
579*4882a593Smuzhiyun direction = 1;
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun if (intp->chip_id <= 0x20) {
582*4882a593Smuzhiyun tuner_freq = intp->freq[d];
583*4882a593Smuzhiyun intp->bw[d] = stv0900_carrier_width(intp->symbol_rate[d],
584*4882a593Smuzhiyun intp->rolloff) + intp->symbol_rate[d];
585*4882a593Smuzhiyun } else
586*4882a593Smuzhiyun tuner_freq = 0;
587*4882a593Smuzhiyun
588*4882a593Smuzhiyun while ((current_step <= nb_steps) && (lock == FALSE)) {
589*4882a593Smuzhiyun if (direction > 0)
590*4882a593Smuzhiyun tuner_freq += (current_step * currier_step);
591*4882a593Smuzhiyun else
592*4882a593Smuzhiyun tuner_freq -= (current_step * currier_step);
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun if (intp->chip_id <= 0x20) {
595*4882a593Smuzhiyun if (intp->tuner_type[d] == 3)
596*4882a593Smuzhiyun stv0900_set_tuner_auto(intp, tuner_freq,
597*4882a593Smuzhiyun intp->bw[d], demod);
598*4882a593Smuzhiyun else
599*4882a593Smuzhiyun stv0900_set_tuner(fe, tuner_freq, intp->bw[d]);
600*4882a593Smuzhiyun
601*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x1c);
602*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT1, 0);
603*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT0, 0);
604*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x1f);
605*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x15);
606*4882a593Smuzhiyun } else {
607*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x1c);
608*4882a593Smuzhiyun freq = (tuner_freq * 65536) / (intp->mclk / 1000);
609*4882a593Smuzhiyun stv0900_write_bits(intp, CFR_INIT1, MSB(freq));
610*4882a593Smuzhiyun stv0900_write_bits(intp, CFR_INIT0, LSB(freq));
611*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x1f);
612*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x05);
613*4882a593Smuzhiyun }
614*4882a593Smuzhiyun
615*4882a593Smuzhiyun lock = stv0900_get_demod_lock(intp, d, timeout);
616*4882a593Smuzhiyun direction *= -1;
617*4882a593Smuzhiyun current_step++;
618*4882a593Smuzhiyun }
619*4882a593Smuzhiyun
620*4882a593Smuzhiyun return lock;
621*4882a593Smuzhiyun }
622*4882a593Smuzhiyun
stv0900_get_lock_timeout(s32 * demod_timeout,s32 * fec_timeout,s32 srate,enum fe_stv0900_search_algo algo)623*4882a593Smuzhiyun static void stv0900_get_lock_timeout(s32 *demod_timeout, s32 *fec_timeout,
624*4882a593Smuzhiyun s32 srate,
625*4882a593Smuzhiyun enum fe_stv0900_search_algo algo)
626*4882a593Smuzhiyun {
627*4882a593Smuzhiyun switch (algo) {
628*4882a593Smuzhiyun case STV0900_BLIND_SEARCH:
629*4882a593Smuzhiyun if (srate <= 1500000) {
630*4882a593Smuzhiyun (*demod_timeout) = 1500;
631*4882a593Smuzhiyun (*fec_timeout) = 400;
632*4882a593Smuzhiyun } else if (srate <= 5000000) {
633*4882a593Smuzhiyun (*demod_timeout) = 1000;
634*4882a593Smuzhiyun (*fec_timeout) = 300;
635*4882a593Smuzhiyun } else {
636*4882a593Smuzhiyun (*demod_timeout) = 700;
637*4882a593Smuzhiyun (*fec_timeout) = 100;
638*4882a593Smuzhiyun }
639*4882a593Smuzhiyun
640*4882a593Smuzhiyun break;
641*4882a593Smuzhiyun case STV0900_COLD_START:
642*4882a593Smuzhiyun case STV0900_WARM_START:
643*4882a593Smuzhiyun default:
644*4882a593Smuzhiyun if (srate <= 1000000) {
645*4882a593Smuzhiyun (*demod_timeout) = 3000;
646*4882a593Smuzhiyun (*fec_timeout) = 1700;
647*4882a593Smuzhiyun } else if (srate <= 2000000) {
648*4882a593Smuzhiyun (*demod_timeout) = 2500;
649*4882a593Smuzhiyun (*fec_timeout) = 1100;
650*4882a593Smuzhiyun } else if (srate <= 5000000) {
651*4882a593Smuzhiyun (*demod_timeout) = 1000;
652*4882a593Smuzhiyun (*fec_timeout) = 550;
653*4882a593Smuzhiyun } else if (srate <= 10000000) {
654*4882a593Smuzhiyun (*demod_timeout) = 700;
655*4882a593Smuzhiyun (*fec_timeout) = 250;
656*4882a593Smuzhiyun } else if (srate <= 20000000) {
657*4882a593Smuzhiyun (*demod_timeout) = 400;
658*4882a593Smuzhiyun (*fec_timeout) = 130;
659*4882a593Smuzhiyun } else {
660*4882a593Smuzhiyun (*demod_timeout) = 300;
661*4882a593Smuzhiyun (*fec_timeout) = 100;
662*4882a593Smuzhiyun }
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun break;
665*4882a593Smuzhiyun
666*4882a593Smuzhiyun }
667*4882a593Smuzhiyun
668*4882a593Smuzhiyun if (algo == STV0900_WARM_START)
669*4882a593Smuzhiyun (*demod_timeout) /= 2;
670*4882a593Smuzhiyun }
671*4882a593Smuzhiyun
stv0900_set_viterbi_tracq(struct stv0900_internal * intp,enum fe_stv0900_demod_num demod)672*4882a593Smuzhiyun static void stv0900_set_viterbi_tracq(struct stv0900_internal *intp,
673*4882a593Smuzhiyun enum fe_stv0900_demod_num demod)
674*4882a593Smuzhiyun {
675*4882a593Smuzhiyun
676*4882a593Smuzhiyun s32 vth_reg = VTH12;
677*4882a593Smuzhiyun
678*4882a593Smuzhiyun dprintk("%s\n", __func__);
679*4882a593Smuzhiyun
680*4882a593Smuzhiyun stv0900_write_reg(intp, vth_reg++, 0xd0);
681*4882a593Smuzhiyun stv0900_write_reg(intp, vth_reg++, 0x7d);
682*4882a593Smuzhiyun stv0900_write_reg(intp, vth_reg++, 0x53);
683*4882a593Smuzhiyun stv0900_write_reg(intp, vth_reg++, 0x2f);
684*4882a593Smuzhiyun stv0900_write_reg(intp, vth_reg++, 0x24);
685*4882a593Smuzhiyun stv0900_write_reg(intp, vth_reg++, 0x1f);
686*4882a593Smuzhiyun }
687*4882a593Smuzhiyun
stv0900_set_viterbi_standard(struct stv0900_internal * intp,enum fe_stv0900_search_standard standard,enum fe_stv0900_fec fec,enum fe_stv0900_demod_num demod)688*4882a593Smuzhiyun static void stv0900_set_viterbi_standard(struct stv0900_internal *intp,
689*4882a593Smuzhiyun enum fe_stv0900_search_standard standard,
690*4882a593Smuzhiyun enum fe_stv0900_fec fec,
691*4882a593Smuzhiyun enum fe_stv0900_demod_num demod)
692*4882a593Smuzhiyun {
693*4882a593Smuzhiyun dprintk("%s: ViterbiStandard = ", __func__);
694*4882a593Smuzhiyun
695*4882a593Smuzhiyun switch (standard) {
696*4882a593Smuzhiyun case STV0900_AUTO_SEARCH:
697*4882a593Smuzhiyun dprintk("Auto\n");
698*4882a593Smuzhiyun stv0900_write_reg(intp, FECM, 0x10);
699*4882a593Smuzhiyun stv0900_write_reg(intp, PRVIT, 0x3f);
700*4882a593Smuzhiyun break;
701*4882a593Smuzhiyun case STV0900_SEARCH_DVBS1:
702*4882a593Smuzhiyun dprintk("DVBS1\n");
703*4882a593Smuzhiyun stv0900_write_reg(intp, FECM, 0x00);
704*4882a593Smuzhiyun switch (fec) {
705*4882a593Smuzhiyun case STV0900_FEC_UNKNOWN:
706*4882a593Smuzhiyun default:
707*4882a593Smuzhiyun stv0900_write_reg(intp, PRVIT, 0x2f);
708*4882a593Smuzhiyun break;
709*4882a593Smuzhiyun case STV0900_FEC_1_2:
710*4882a593Smuzhiyun stv0900_write_reg(intp, PRVIT, 0x01);
711*4882a593Smuzhiyun break;
712*4882a593Smuzhiyun case STV0900_FEC_2_3:
713*4882a593Smuzhiyun stv0900_write_reg(intp, PRVIT, 0x02);
714*4882a593Smuzhiyun break;
715*4882a593Smuzhiyun case STV0900_FEC_3_4:
716*4882a593Smuzhiyun stv0900_write_reg(intp, PRVIT, 0x04);
717*4882a593Smuzhiyun break;
718*4882a593Smuzhiyun case STV0900_FEC_5_6:
719*4882a593Smuzhiyun stv0900_write_reg(intp, PRVIT, 0x08);
720*4882a593Smuzhiyun break;
721*4882a593Smuzhiyun case STV0900_FEC_7_8:
722*4882a593Smuzhiyun stv0900_write_reg(intp, PRVIT, 0x20);
723*4882a593Smuzhiyun break;
724*4882a593Smuzhiyun }
725*4882a593Smuzhiyun
726*4882a593Smuzhiyun break;
727*4882a593Smuzhiyun case STV0900_SEARCH_DSS:
728*4882a593Smuzhiyun dprintk("DSS\n");
729*4882a593Smuzhiyun stv0900_write_reg(intp, FECM, 0x80);
730*4882a593Smuzhiyun switch (fec) {
731*4882a593Smuzhiyun case STV0900_FEC_UNKNOWN:
732*4882a593Smuzhiyun default:
733*4882a593Smuzhiyun stv0900_write_reg(intp, PRVIT, 0x13);
734*4882a593Smuzhiyun break;
735*4882a593Smuzhiyun case STV0900_FEC_1_2:
736*4882a593Smuzhiyun stv0900_write_reg(intp, PRVIT, 0x01);
737*4882a593Smuzhiyun break;
738*4882a593Smuzhiyun case STV0900_FEC_2_3:
739*4882a593Smuzhiyun stv0900_write_reg(intp, PRVIT, 0x02);
740*4882a593Smuzhiyun break;
741*4882a593Smuzhiyun case STV0900_FEC_6_7:
742*4882a593Smuzhiyun stv0900_write_reg(intp, PRVIT, 0x10);
743*4882a593Smuzhiyun break;
744*4882a593Smuzhiyun }
745*4882a593Smuzhiyun break;
746*4882a593Smuzhiyun default:
747*4882a593Smuzhiyun break;
748*4882a593Smuzhiyun }
749*4882a593Smuzhiyun }
750*4882a593Smuzhiyun
stv0900_get_vit_fec(struct stv0900_internal * intp,enum fe_stv0900_demod_num demod)751*4882a593Smuzhiyun static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *intp,
752*4882a593Smuzhiyun enum fe_stv0900_demod_num demod)
753*4882a593Smuzhiyun {
754*4882a593Smuzhiyun enum fe_stv0900_fec prate;
755*4882a593Smuzhiyun s32 rate_fld = stv0900_get_bits(intp, VIT_CURPUN);
756*4882a593Smuzhiyun
757*4882a593Smuzhiyun switch (rate_fld) {
758*4882a593Smuzhiyun case 13:
759*4882a593Smuzhiyun prate = STV0900_FEC_1_2;
760*4882a593Smuzhiyun break;
761*4882a593Smuzhiyun case 18:
762*4882a593Smuzhiyun prate = STV0900_FEC_2_3;
763*4882a593Smuzhiyun break;
764*4882a593Smuzhiyun case 21:
765*4882a593Smuzhiyun prate = STV0900_FEC_3_4;
766*4882a593Smuzhiyun break;
767*4882a593Smuzhiyun case 24:
768*4882a593Smuzhiyun prate = STV0900_FEC_5_6;
769*4882a593Smuzhiyun break;
770*4882a593Smuzhiyun case 25:
771*4882a593Smuzhiyun prate = STV0900_FEC_6_7;
772*4882a593Smuzhiyun break;
773*4882a593Smuzhiyun case 26:
774*4882a593Smuzhiyun prate = STV0900_FEC_7_8;
775*4882a593Smuzhiyun break;
776*4882a593Smuzhiyun default:
777*4882a593Smuzhiyun prate = STV0900_FEC_UNKNOWN;
778*4882a593Smuzhiyun break;
779*4882a593Smuzhiyun }
780*4882a593Smuzhiyun
781*4882a593Smuzhiyun return prate;
782*4882a593Smuzhiyun }
783*4882a593Smuzhiyun
stv0900_set_dvbs1_track_car_loop(struct stv0900_internal * intp,enum fe_stv0900_demod_num demod,u32 srate)784*4882a593Smuzhiyun static void stv0900_set_dvbs1_track_car_loop(struct stv0900_internal *intp,
785*4882a593Smuzhiyun enum fe_stv0900_demod_num demod,
786*4882a593Smuzhiyun u32 srate)
787*4882a593Smuzhiyun {
788*4882a593Smuzhiyun if (intp->chip_id >= 0x30) {
789*4882a593Smuzhiyun if (srate >= 15000000) {
790*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC, 0x2b);
791*4882a593Smuzhiyun stv0900_write_reg(intp, BCLC, 0x1a);
792*4882a593Smuzhiyun } else if ((srate >= 7000000) && (15000000 > srate)) {
793*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC, 0x0c);
794*4882a593Smuzhiyun stv0900_write_reg(intp, BCLC, 0x1b);
795*4882a593Smuzhiyun } else if (srate < 7000000) {
796*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC, 0x2c);
797*4882a593Smuzhiyun stv0900_write_reg(intp, BCLC, 0x1c);
798*4882a593Smuzhiyun }
799*4882a593Smuzhiyun
800*4882a593Smuzhiyun } else { /*cut 2.0 and 1.x*/
801*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC, 0x1a);
802*4882a593Smuzhiyun stv0900_write_reg(intp, BCLC, 0x09);
803*4882a593Smuzhiyun }
804*4882a593Smuzhiyun
805*4882a593Smuzhiyun }
806*4882a593Smuzhiyun
stv0900_track_optimization(struct dvb_frontend * fe)807*4882a593Smuzhiyun static void stv0900_track_optimization(struct dvb_frontend *fe)
808*4882a593Smuzhiyun {
809*4882a593Smuzhiyun struct stv0900_state *state = fe->demodulator_priv;
810*4882a593Smuzhiyun struct stv0900_internal *intp = state->internal;
811*4882a593Smuzhiyun enum fe_stv0900_demod_num demod = state->demod;
812*4882a593Smuzhiyun
813*4882a593Smuzhiyun s32 srate,
814*4882a593Smuzhiyun pilots,
815*4882a593Smuzhiyun aclc,
816*4882a593Smuzhiyun freq1,
817*4882a593Smuzhiyun freq0,
818*4882a593Smuzhiyun i = 0,
819*4882a593Smuzhiyun timed,
820*4882a593Smuzhiyun timef,
821*4882a593Smuzhiyun blind_tun_sw = 0,
822*4882a593Smuzhiyun modulation;
823*4882a593Smuzhiyun
824*4882a593Smuzhiyun enum fe_stv0900_modcode foundModcod;
825*4882a593Smuzhiyun
826*4882a593Smuzhiyun dprintk("%s\n", __func__);
827*4882a593Smuzhiyun
828*4882a593Smuzhiyun srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
829*4882a593Smuzhiyun srate += stv0900_get_timing_offst(intp, srate, demod);
830*4882a593Smuzhiyun
831*4882a593Smuzhiyun switch (intp->result[demod].standard) {
832*4882a593Smuzhiyun case STV0900_DVBS1_STANDARD:
833*4882a593Smuzhiyun case STV0900_DSS_STANDARD:
834*4882a593Smuzhiyun dprintk("%s: found DVB-S or DSS\n", __func__);
835*4882a593Smuzhiyun if (intp->srch_standard[demod] == STV0900_AUTO_SEARCH) {
836*4882a593Smuzhiyun stv0900_write_bits(intp, DVBS1_ENABLE, 1);
837*4882a593Smuzhiyun stv0900_write_bits(intp, DVBS2_ENABLE, 0);
838*4882a593Smuzhiyun }
839*4882a593Smuzhiyun
840*4882a593Smuzhiyun stv0900_write_bits(intp, ROLLOFF_CONTROL, intp->rolloff);
841*4882a593Smuzhiyun stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
842*4882a593Smuzhiyun
843*4882a593Smuzhiyun if (intp->chip_id < 0x30) {
844*4882a593Smuzhiyun stv0900_write_reg(intp, ERRCTRL1, 0x75);
845*4882a593Smuzhiyun break;
846*4882a593Smuzhiyun }
847*4882a593Smuzhiyun
848*4882a593Smuzhiyun if (stv0900_get_vit_fec(intp, demod) == STV0900_FEC_1_2) {
849*4882a593Smuzhiyun stv0900_write_reg(intp, GAUSSR0, 0x98);
850*4882a593Smuzhiyun stv0900_write_reg(intp, CCIR0, 0x18);
851*4882a593Smuzhiyun } else {
852*4882a593Smuzhiyun stv0900_write_reg(intp, GAUSSR0, 0x18);
853*4882a593Smuzhiyun stv0900_write_reg(intp, CCIR0, 0x18);
854*4882a593Smuzhiyun }
855*4882a593Smuzhiyun
856*4882a593Smuzhiyun stv0900_write_reg(intp, ERRCTRL1, 0x75);
857*4882a593Smuzhiyun break;
858*4882a593Smuzhiyun case STV0900_DVBS2_STANDARD:
859*4882a593Smuzhiyun dprintk("%s: found DVB-S2\n", __func__);
860*4882a593Smuzhiyun stv0900_write_bits(intp, DVBS1_ENABLE, 0);
861*4882a593Smuzhiyun stv0900_write_bits(intp, DVBS2_ENABLE, 1);
862*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC, 0);
863*4882a593Smuzhiyun stv0900_write_reg(intp, BCLC, 0);
864*4882a593Smuzhiyun if (intp->result[demod].frame_len == STV0900_LONG_FRAME) {
865*4882a593Smuzhiyun foundModcod = stv0900_get_bits(intp, DEMOD_MODCOD);
866*4882a593Smuzhiyun pilots = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01;
867*4882a593Smuzhiyun aclc = stv0900_get_optim_carr_loop(srate,
868*4882a593Smuzhiyun foundModcod,
869*4882a593Smuzhiyun pilots,
870*4882a593Smuzhiyun intp->chip_id);
871*4882a593Smuzhiyun if (foundModcod <= STV0900_QPSK_910)
872*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC2S2Q, aclc);
873*4882a593Smuzhiyun else if (foundModcod <= STV0900_8PSK_910) {
874*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
875*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC2S28, aclc);
876*4882a593Smuzhiyun }
877*4882a593Smuzhiyun
878*4882a593Smuzhiyun if ((intp->demod_mode == STV0900_SINGLE) &&
879*4882a593Smuzhiyun (foundModcod > STV0900_8PSK_910)) {
880*4882a593Smuzhiyun if (foundModcod <= STV0900_16APSK_910) {
881*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
882*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC2S216A,
883*4882a593Smuzhiyun aclc);
884*4882a593Smuzhiyun } else if (foundModcod <= STV0900_32APSK_910) {
885*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
886*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC2S232A,
887*4882a593Smuzhiyun aclc);
888*4882a593Smuzhiyun }
889*4882a593Smuzhiyun }
890*4882a593Smuzhiyun
891*4882a593Smuzhiyun } else {
892*4882a593Smuzhiyun modulation = intp->result[demod].modulation;
893*4882a593Smuzhiyun aclc = stv0900_get_optim_short_carr_loop(srate,
894*4882a593Smuzhiyun modulation, intp->chip_id);
895*4882a593Smuzhiyun if (modulation == STV0900_QPSK)
896*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC2S2Q, aclc);
897*4882a593Smuzhiyun else if (modulation == STV0900_8PSK) {
898*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
899*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC2S28, aclc);
900*4882a593Smuzhiyun } else if (modulation == STV0900_16APSK) {
901*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
902*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC2S216A, aclc);
903*4882a593Smuzhiyun } else if (modulation == STV0900_32APSK) {
904*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
905*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC2S232A, aclc);
906*4882a593Smuzhiyun }
907*4882a593Smuzhiyun
908*4882a593Smuzhiyun }
909*4882a593Smuzhiyun
910*4882a593Smuzhiyun if (intp->chip_id <= 0x11) {
911*4882a593Smuzhiyun if (intp->demod_mode != STV0900_SINGLE)
912*4882a593Smuzhiyun stv0900_activate_s2_modcod(intp, demod);
913*4882a593Smuzhiyun
914*4882a593Smuzhiyun }
915*4882a593Smuzhiyun
916*4882a593Smuzhiyun stv0900_write_reg(intp, ERRCTRL1, 0x67);
917*4882a593Smuzhiyun break;
918*4882a593Smuzhiyun case STV0900_UNKNOWN_STANDARD:
919*4882a593Smuzhiyun default:
920*4882a593Smuzhiyun dprintk("%s: found unknown standard\n", __func__);
921*4882a593Smuzhiyun stv0900_write_bits(intp, DVBS1_ENABLE, 1);
922*4882a593Smuzhiyun stv0900_write_bits(intp, DVBS2_ENABLE, 1);
923*4882a593Smuzhiyun break;
924*4882a593Smuzhiyun }
925*4882a593Smuzhiyun
926*4882a593Smuzhiyun freq1 = stv0900_read_reg(intp, CFR2);
927*4882a593Smuzhiyun freq0 = stv0900_read_reg(intp, CFR1);
928*4882a593Smuzhiyun if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) {
929*4882a593Smuzhiyun stv0900_write_reg(intp, SFRSTEP, 0x00);
930*4882a593Smuzhiyun stv0900_write_bits(intp, SCAN_ENABLE, 0);
931*4882a593Smuzhiyun stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
932*4882a593Smuzhiyun stv0900_write_reg(intp, TMGCFG2, 0xc1);
933*4882a593Smuzhiyun stv0900_set_symbol_rate(intp, intp->mclk, srate, demod);
934*4882a593Smuzhiyun blind_tun_sw = 1;
935*4882a593Smuzhiyun if (intp->result[demod].standard != STV0900_DVBS2_STANDARD)
936*4882a593Smuzhiyun stv0900_set_dvbs1_track_car_loop(intp, demod, srate);
937*4882a593Smuzhiyun
938*4882a593Smuzhiyun }
939*4882a593Smuzhiyun
940*4882a593Smuzhiyun if (intp->chip_id >= 0x20) {
941*4882a593Smuzhiyun if ((intp->srch_standard[demod] == STV0900_SEARCH_DVBS1) ||
942*4882a593Smuzhiyun (intp->srch_standard[demod] ==
943*4882a593Smuzhiyun STV0900_SEARCH_DSS) ||
944*4882a593Smuzhiyun (intp->srch_standard[demod] ==
945*4882a593Smuzhiyun STV0900_AUTO_SEARCH)) {
946*4882a593Smuzhiyun stv0900_write_reg(intp, VAVSRVIT, 0x0a);
947*4882a593Smuzhiyun stv0900_write_reg(intp, VITSCALE, 0x0);
948*4882a593Smuzhiyun }
949*4882a593Smuzhiyun }
950*4882a593Smuzhiyun
951*4882a593Smuzhiyun if (intp->chip_id < 0x20)
952*4882a593Smuzhiyun stv0900_write_reg(intp, CARHDR, 0x08);
953*4882a593Smuzhiyun
954*4882a593Smuzhiyun if (intp->chip_id == 0x10)
955*4882a593Smuzhiyun stv0900_write_reg(intp, CORRELEXP, 0x0a);
956*4882a593Smuzhiyun
957*4882a593Smuzhiyun stv0900_write_reg(intp, AGC2REF, 0x38);
958*4882a593Smuzhiyun
959*4882a593Smuzhiyun if ((intp->chip_id >= 0x20) ||
960*4882a593Smuzhiyun (blind_tun_sw == 1) ||
961*4882a593Smuzhiyun (intp->symbol_rate[demod] < 10000000)) {
962*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT1, freq1);
963*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT0, freq0);
964*4882a593Smuzhiyun intp->bw[demod] = stv0900_carrier_width(srate,
965*4882a593Smuzhiyun intp->rolloff) + 10000000;
966*4882a593Smuzhiyun
967*4882a593Smuzhiyun if ((intp->chip_id >= 0x20) || (blind_tun_sw == 1)) {
968*4882a593Smuzhiyun if (intp->srch_algo[demod] != STV0900_WARM_START) {
969*4882a593Smuzhiyun if (intp->tuner_type[demod] == 3)
970*4882a593Smuzhiyun stv0900_set_tuner_auto(intp,
971*4882a593Smuzhiyun intp->freq[demod],
972*4882a593Smuzhiyun intp->bw[demod],
973*4882a593Smuzhiyun demod);
974*4882a593Smuzhiyun else
975*4882a593Smuzhiyun stv0900_set_bandwidth(fe,
976*4882a593Smuzhiyun intp->bw[demod]);
977*4882a593Smuzhiyun }
978*4882a593Smuzhiyun }
979*4882a593Smuzhiyun
980*4882a593Smuzhiyun if ((intp->srch_algo[demod] == STV0900_BLIND_SEARCH) ||
981*4882a593Smuzhiyun (intp->symbol_rate[demod] < 10000000))
982*4882a593Smuzhiyun msleep(50);
983*4882a593Smuzhiyun else
984*4882a593Smuzhiyun msleep(5);
985*4882a593Smuzhiyun
986*4882a593Smuzhiyun stv0900_get_lock_timeout(&timed, &timef, srate,
987*4882a593Smuzhiyun STV0900_WARM_START);
988*4882a593Smuzhiyun
989*4882a593Smuzhiyun if (stv0900_get_demod_lock(intp, demod, timed / 2) == FALSE) {
990*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x1f);
991*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT1, freq1);
992*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT0, freq0);
993*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x18);
994*4882a593Smuzhiyun i = 0;
995*4882a593Smuzhiyun while ((stv0900_get_demod_lock(intp,
996*4882a593Smuzhiyun demod,
997*4882a593Smuzhiyun timed / 2) == FALSE) &&
998*4882a593Smuzhiyun (i <= 2)) {
999*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x1f);
1000*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT1, freq1);
1001*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT0, freq0);
1002*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x18);
1003*4882a593Smuzhiyun i++;
1004*4882a593Smuzhiyun }
1005*4882a593Smuzhiyun }
1006*4882a593Smuzhiyun
1007*4882a593Smuzhiyun }
1008*4882a593Smuzhiyun
1009*4882a593Smuzhiyun if (intp->chip_id >= 0x20)
1010*4882a593Smuzhiyun stv0900_write_reg(intp, CARFREQ, 0x49);
1011*4882a593Smuzhiyun
1012*4882a593Smuzhiyun if ((intp->result[demod].standard == STV0900_DVBS1_STANDARD) ||
1013*4882a593Smuzhiyun (intp->result[demod].standard == STV0900_DSS_STANDARD))
1014*4882a593Smuzhiyun stv0900_set_viterbi_tracq(intp, demod);
1015*4882a593Smuzhiyun
1016*4882a593Smuzhiyun }
1017*4882a593Smuzhiyun
stv0900_get_fec_lock(struct stv0900_internal * intp,enum fe_stv0900_demod_num demod,s32 time_out)1018*4882a593Smuzhiyun static int stv0900_get_fec_lock(struct stv0900_internal *intp,
1019*4882a593Smuzhiyun enum fe_stv0900_demod_num demod, s32 time_out)
1020*4882a593Smuzhiyun {
1021*4882a593Smuzhiyun s32 timer = 0, lock = 0;
1022*4882a593Smuzhiyun
1023*4882a593Smuzhiyun enum fe_stv0900_search_state dmd_state;
1024*4882a593Smuzhiyun
1025*4882a593Smuzhiyun dprintk("%s\n", __func__);
1026*4882a593Smuzhiyun
1027*4882a593Smuzhiyun dmd_state = stv0900_get_bits(intp, HEADER_MODE);
1028*4882a593Smuzhiyun
1029*4882a593Smuzhiyun while ((timer < time_out) && (lock == 0)) {
1030*4882a593Smuzhiyun switch (dmd_state) {
1031*4882a593Smuzhiyun case STV0900_SEARCH:
1032*4882a593Smuzhiyun case STV0900_PLH_DETECTED:
1033*4882a593Smuzhiyun default:
1034*4882a593Smuzhiyun lock = 0;
1035*4882a593Smuzhiyun break;
1036*4882a593Smuzhiyun case STV0900_DVBS2_FOUND:
1037*4882a593Smuzhiyun lock = stv0900_get_bits(intp, PKTDELIN_LOCK);
1038*4882a593Smuzhiyun break;
1039*4882a593Smuzhiyun case STV0900_DVBS_FOUND:
1040*4882a593Smuzhiyun lock = stv0900_get_bits(intp, LOCKEDVIT);
1041*4882a593Smuzhiyun break;
1042*4882a593Smuzhiyun }
1043*4882a593Smuzhiyun
1044*4882a593Smuzhiyun if (lock == 0) {
1045*4882a593Smuzhiyun msleep(10);
1046*4882a593Smuzhiyun timer += 10;
1047*4882a593Smuzhiyun }
1048*4882a593Smuzhiyun }
1049*4882a593Smuzhiyun
1050*4882a593Smuzhiyun if (lock)
1051*4882a593Smuzhiyun dprintk("%s: DEMOD FEC LOCK OK\n", __func__);
1052*4882a593Smuzhiyun else
1053*4882a593Smuzhiyun dprintk("%s: DEMOD FEC LOCK FAIL\n", __func__);
1054*4882a593Smuzhiyun
1055*4882a593Smuzhiyun return lock;
1056*4882a593Smuzhiyun }
1057*4882a593Smuzhiyun
stv0900_wait_for_lock(struct stv0900_internal * intp,enum fe_stv0900_demod_num demod,s32 dmd_timeout,s32 fec_timeout)1058*4882a593Smuzhiyun static int stv0900_wait_for_lock(struct stv0900_internal *intp,
1059*4882a593Smuzhiyun enum fe_stv0900_demod_num demod,
1060*4882a593Smuzhiyun s32 dmd_timeout, s32 fec_timeout)
1061*4882a593Smuzhiyun {
1062*4882a593Smuzhiyun
1063*4882a593Smuzhiyun s32 timer = 0, lock = 0;
1064*4882a593Smuzhiyun
1065*4882a593Smuzhiyun dprintk("%s\n", __func__);
1066*4882a593Smuzhiyun
1067*4882a593Smuzhiyun lock = stv0900_get_demod_lock(intp, demod, dmd_timeout);
1068*4882a593Smuzhiyun
1069*4882a593Smuzhiyun if (lock)
1070*4882a593Smuzhiyun lock = stv0900_get_fec_lock(intp, demod, fec_timeout);
1071*4882a593Smuzhiyun
1072*4882a593Smuzhiyun if (lock) {
1073*4882a593Smuzhiyun lock = 0;
1074*4882a593Smuzhiyun
1075*4882a593Smuzhiyun dprintk("%s: Timer = %d, time_out = %d\n",
1076*4882a593Smuzhiyun __func__, timer, fec_timeout);
1077*4882a593Smuzhiyun
1078*4882a593Smuzhiyun while ((timer < fec_timeout) && (lock == 0)) {
1079*4882a593Smuzhiyun lock = stv0900_get_bits(intp, TSFIFO_LINEOK);
1080*4882a593Smuzhiyun msleep(1);
1081*4882a593Smuzhiyun timer++;
1082*4882a593Smuzhiyun }
1083*4882a593Smuzhiyun }
1084*4882a593Smuzhiyun
1085*4882a593Smuzhiyun if (lock)
1086*4882a593Smuzhiyun dprintk("%s: DEMOD LOCK OK\n", __func__);
1087*4882a593Smuzhiyun else
1088*4882a593Smuzhiyun dprintk("%s: DEMOD LOCK FAIL\n", __func__);
1089*4882a593Smuzhiyun
1090*4882a593Smuzhiyun if (lock)
1091*4882a593Smuzhiyun return TRUE;
1092*4882a593Smuzhiyun else
1093*4882a593Smuzhiyun return FALSE;
1094*4882a593Smuzhiyun }
1095*4882a593Smuzhiyun
stv0900_get_standard(struct dvb_frontend * fe,enum fe_stv0900_demod_num demod)1096*4882a593Smuzhiyun enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
1097*4882a593Smuzhiyun enum fe_stv0900_demod_num demod)
1098*4882a593Smuzhiyun {
1099*4882a593Smuzhiyun struct stv0900_state *state = fe->demodulator_priv;
1100*4882a593Smuzhiyun struct stv0900_internal *intp = state->internal;
1101*4882a593Smuzhiyun enum fe_stv0900_tracking_standard fnd_standard;
1102*4882a593Smuzhiyun
1103*4882a593Smuzhiyun int hdr_mode = stv0900_get_bits(intp, HEADER_MODE);
1104*4882a593Smuzhiyun
1105*4882a593Smuzhiyun switch (hdr_mode) {
1106*4882a593Smuzhiyun case 2:
1107*4882a593Smuzhiyun fnd_standard = STV0900_DVBS2_STANDARD;
1108*4882a593Smuzhiyun break;
1109*4882a593Smuzhiyun case 3:
1110*4882a593Smuzhiyun if (stv0900_get_bits(intp, DSS_DVB) == 1)
1111*4882a593Smuzhiyun fnd_standard = STV0900_DSS_STANDARD;
1112*4882a593Smuzhiyun else
1113*4882a593Smuzhiyun fnd_standard = STV0900_DVBS1_STANDARD;
1114*4882a593Smuzhiyun
1115*4882a593Smuzhiyun break;
1116*4882a593Smuzhiyun default:
1117*4882a593Smuzhiyun fnd_standard = STV0900_UNKNOWN_STANDARD;
1118*4882a593Smuzhiyun }
1119*4882a593Smuzhiyun
1120*4882a593Smuzhiyun dprintk("%s: standard %d\n", __func__, fnd_standard);
1121*4882a593Smuzhiyun
1122*4882a593Smuzhiyun return fnd_standard;
1123*4882a593Smuzhiyun }
1124*4882a593Smuzhiyun
stv0900_get_carr_freq(struct stv0900_internal * intp,u32 mclk,enum fe_stv0900_demod_num demod)1125*4882a593Smuzhiyun static s32 stv0900_get_carr_freq(struct stv0900_internal *intp, u32 mclk,
1126*4882a593Smuzhiyun enum fe_stv0900_demod_num demod)
1127*4882a593Smuzhiyun {
1128*4882a593Smuzhiyun s32 derot,
1129*4882a593Smuzhiyun rem1,
1130*4882a593Smuzhiyun rem2,
1131*4882a593Smuzhiyun intval1,
1132*4882a593Smuzhiyun intval2;
1133*4882a593Smuzhiyun
1134*4882a593Smuzhiyun derot = (stv0900_get_bits(intp, CAR_FREQ2) << 16) +
1135*4882a593Smuzhiyun (stv0900_get_bits(intp, CAR_FREQ1) << 8) +
1136*4882a593Smuzhiyun (stv0900_get_bits(intp, CAR_FREQ0));
1137*4882a593Smuzhiyun
1138*4882a593Smuzhiyun derot = ge2comp(derot, 24);
1139*4882a593Smuzhiyun intval1 = mclk >> 12;
1140*4882a593Smuzhiyun intval2 = derot >> 12;
1141*4882a593Smuzhiyun rem1 = mclk % 0x1000;
1142*4882a593Smuzhiyun rem2 = derot % 0x1000;
1143*4882a593Smuzhiyun derot = (intval1 * intval2) +
1144*4882a593Smuzhiyun ((intval1 * rem2) >> 12) +
1145*4882a593Smuzhiyun ((intval2 * rem1) >> 12);
1146*4882a593Smuzhiyun
1147*4882a593Smuzhiyun return derot;
1148*4882a593Smuzhiyun }
1149*4882a593Smuzhiyun
stv0900_get_tuner_freq(struct dvb_frontend * fe)1150*4882a593Smuzhiyun static u32 stv0900_get_tuner_freq(struct dvb_frontend *fe)
1151*4882a593Smuzhiyun {
1152*4882a593Smuzhiyun struct dvb_frontend_ops *frontend_ops = NULL;
1153*4882a593Smuzhiyun struct dvb_tuner_ops *tuner_ops = NULL;
1154*4882a593Smuzhiyun u32 freq = 0;
1155*4882a593Smuzhiyun
1156*4882a593Smuzhiyun frontend_ops = &fe->ops;
1157*4882a593Smuzhiyun tuner_ops = &frontend_ops->tuner_ops;
1158*4882a593Smuzhiyun
1159*4882a593Smuzhiyun if (tuner_ops->get_frequency) {
1160*4882a593Smuzhiyun if ((tuner_ops->get_frequency(fe, &freq)) < 0)
1161*4882a593Smuzhiyun dprintk("%s: Invalid parameter\n", __func__);
1162*4882a593Smuzhiyun else
1163*4882a593Smuzhiyun dprintk("%s: Frequency=%d\n", __func__, freq);
1164*4882a593Smuzhiyun
1165*4882a593Smuzhiyun }
1166*4882a593Smuzhiyun
1167*4882a593Smuzhiyun return freq;
1168*4882a593Smuzhiyun }
1169*4882a593Smuzhiyun
1170*4882a593Smuzhiyun static enum
stv0900_get_signal_params(struct dvb_frontend * fe)1171*4882a593Smuzhiyun fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe)
1172*4882a593Smuzhiyun {
1173*4882a593Smuzhiyun struct stv0900_state *state = fe->demodulator_priv;
1174*4882a593Smuzhiyun struct stv0900_internal *intp = state->internal;
1175*4882a593Smuzhiyun enum fe_stv0900_demod_num demod = state->demod;
1176*4882a593Smuzhiyun enum fe_stv0900_signal_type range = STV0900_OUTOFRANGE;
1177*4882a593Smuzhiyun struct stv0900_signal_info *result = &intp->result[demod];
1178*4882a593Smuzhiyun s32 offsetFreq,
1179*4882a593Smuzhiyun srate_offset;
1180*4882a593Smuzhiyun int i = 0,
1181*4882a593Smuzhiyun d = demod;
1182*4882a593Smuzhiyun
1183*4882a593Smuzhiyun u8 timing;
1184*4882a593Smuzhiyun
1185*4882a593Smuzhiyun msleep(5);
1186*4882a593Smuzhiyun if (intp->srch_algo[d] == STV0900_BLIND_SEARCH) {
1187*4882a593Smuzhiyun timing = stv0900_read_reg(intp, TMGREG2);
1188*4882a593Smuzhiyun i = 0;
1189*4882a593Smuzhiyun stv0900_write_reg(intp, SFRSTEP, 0x5c);
1190*4882a593Smuzhiyun
1191*4882a593Smuzhiyun while ((i <= 50) && (timing != 0) && (timing != 0xff)) {
1192*4882a593Smuzhiyun timing = stv0900_read_reg(intp, TMGREG2);
1193*4882a593Smuzhiyun msleep(5);
1194*4882a593Smuzhiyun i += 5;
1195*4882a593Smuzhiyun }
1196*4882a593Smuzhiyun }
1197*4882a593Smuzhiyun
1198*4882a593Smuzhiyun result->standard = stv0900_get_standard(fe, d);
1199*4882a593Smuzhiyun if (intp->tuner_type[demod] == 3)
1200*4882a593Smuzhiyun result->frequency = stv0900_get_freq_auto(intp, d);
1201*4882a593Smuzhiyun else
1202*4882a593Smuzhiyun result->frequency = stv0900_get_tuner_freq(fe);
1203*4882a593Smuzhiyun
1204*4882a593Smuzhiyun offsetFreq = stv0900_get_carr_freq(intp, intp->mclk, d) / 1000;
1205*4882a593Smuzhiyun result->frequency += offsetFreq;
1206*4882a593Smuzhiyun result->symbol_rate = stv0900_get_symbol_rate(intp, intp->mclk, d);
1207*4882a593Smuzhiyun srate_offset = stv0900_get_timing_offst(intp, result->symbol_rate, d);
1208*4882a593Smuzhiyun result->symbol_rate += srate_offset;
1209*4882a593Smuzhiyun result->fec = stv0900_get_vit_fec(intp, d);
1210*4882a593Smuzhiyun result->modcode = stv0900_get_bits(intp, DEMOD_MODCOD);
1211*4882a593Smuzhiyun result->pilot = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01;
1212*4882a593Smuzhiyun result->frame_len = ((u32)stv0900_get_bits(intp, DEMOD_TYPE)) >> 1;
1213*4882a593Smuzhiyun result->rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS);
1214*4882a593Smuzhiyun
1215*4882a593Smuzhiyun dprintk("%s: modcode=0x%x \n", __func__, result->modcode);
1216*4882a593Smuzhiyun
1217*4882a593Smuzhiyun switch (result->standard) {
1218*4882a593Smuzhiyun case STV0900_DVBS2_STANDARD:
1219*4882a593Smuzhiyun result->spectrum = stv0900_get_bits(intp, SPECINV_DEMOD);
1220*4882a593Smuzhiyun if (result->modcode <= STV0900_QPSK_910)
1221*4882a593Smuzhiyun result->modulation = STV0900_QPSK;
1222*4882a593Smuzhiyun else if (result->modcode <= STV0900_8PSK_910)
1223*4882a593Smuzhiyun result->modulation = STV0900_8PSK;
1224*4882a593Smuzhiyun else if (result->modcode <= STV0900_16APSK_910)
1225*4882a593Smuzhiyun result->modulation = STV0900_16APSK;
1226*4882a593Smuzhiyun else if (result->modcode <= STV0900_32APSK_910)
1227*4882a593Smuzhiyun result->modulation = STV0900_32APSK;
1228*4882a593Smuzhiyun else
1229*4882a593Smuzhiyun result->modulation = STV0900_UNKNOWN;
1230*4882a593Smuzhiyun break;
1231*4882a593Smuzhiyun case STV0900_DVBS1_STANDARD:
1232*4882a593Smuzhiyun case STV0900_DSS_STANDARD:
1233*4882a593Smuzhiyun result->spectrum = stv0900_get_bits(intp, IQINV);
1234*4882a593Smuzhiyun result->modulation = STV0900_QPSK;
1235*4882a593Smuzhiyun break;
1236*4882a593Smuzhiyun default:
1237*4882a593Smuzhiyun break;
1238*4882a593Smuzhiyun }
1239*4882a593Smuzhiyun
1240*4882a593Smuzhiyun if ((intp->srch_algo[d] == STV0900_BLIND_SEARCH) ||
1241*4882a593Smuzhiyun (intp->symbol_rate[d] < 10000000)) {
1242*4882a593Smuzhiyun offsetFreq = result->frequency - intp->freq[d];
1243*4882a593Smuzhiyun if (intp->tuner_type[demod] == 3)
1244*4882a593Smuzhiyun intp->freq[d] = stv0900_get_freq_auto(intp, d);
1245*4882a593Smuzhiyun else
1246*4882a593Smuzhiyun intp->freq[d] = stv0900_get_tuner_freq(fe);
1247*4882a593Smuzhiyun
1248*4882a593Smuzhiyun if (abs(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500))
1249*4882a593Smuzhiyun range = STV0900_RANGEOK;
1250*4882a593Smuzhiyun else if (abs(offsetFreq) <=
1251*4882a593Smuzhiyun (stv0900_carrier_width(result->symbol_rate,
1252*4882a593Smuzhiyun result->rolloff) / 2000))
1253*4882a593Smuzhiyun range = STV0900_RANGEOK;
1254*4882a593Smuzhiyun
1255*4882a593Smuzhiyun } else if (abs(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500))
1256*4882a593Smuzhiyun range = STV0900_RANGEOK;
1257*4882a593Smuzhiyun
1258*4882a593Smuzhiyun dprintk("%s: range %d\n", __func__, range);
1259*4882a593Smuzhiyun
1260*4882a593Smuzhiyun return range;
1261*4882a593Smuzhiyun }
1262*4882a593Smuzhiyun
1263*4882a593Smuzhiyun static enum
stv0900_dvbs1_acq_workaround(struct dvb_frontend * fe)1264*4882a593Smuzhiyun fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_frontend *fe)
1265*4882a593Smuzhiyun {
1266*4882a593Smuzhiyun struct stv0900_state *state = fe->demodulator_priv;
1267*4882a593Smuzhiyun struct stv0900_internal *intp = state->internal;
1268*4882a593Smuzhiyun enum fe_stv0900_demod_num demod = state->demod;
1269*4882a593Smuzhiyun enum fe_stv0900_signal_type signal_type = STV0900_NODATA;
1270*4882a593Smuzhiyun
1271*4882a593Smuzhiyun s32 srate,
1272*4882a593Smuzhiyun demod_timeout,
1273*4882a593Smuzhiyun fec_timeout,
1274*4882a593Smuzhiyun freq1,
1275*4882a593Smuzhiyun freq0;
1276*4882a593Smuzhiyun
1277*4882a593Smuzhiyun intp->result[demod].locked = FALSE;
1278*4882a593Smuzhiyun
1279*4882a593Smuzhiyun if (stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) {
1280*4882a593Smuzhiyun srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
1281*4882a593Smuzhiyun srate += stv0900_get_timing_offst(intp, srate, demod);
1282*4882a593Smuzhiyun if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH)
1283*4882a593Smuzhiyun stv0900_set_symbol_rate(intp, intp->mclk, srate, demod);
1284*4882a593Smuzhiyun
1285*4882a593Smuzhiyun stv0900_get_lock_timeout(&demod_timeout, &fec_timeout,
1286*4882a593Smuzhiyun srate, STV0900_WARM_START);
1287*4882a593Smuzhiyun freq1 = stv0900_read_reg(intp, CFR2);
1288*4882a593Smuzhiyun freq0 = stv0900_read_reg(intp, CFR1);
1289*4882a593Smuzhiyun stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
1290*4882a593Smuzhiyun stv0900_write_bits(intp, SPECINV_CONTROL,
1291*4882a593Smuzhiyun STV0900_IQ_FORCE_SWAPPED);
1292*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x1c);
1293*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT1, freq1);
1294*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT0, freq0);
1295*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x18);
1296*4882a593Smuzhiyun if (stv0900_wait_for_lock(intp, demod,
1297*4882a593Smuzhiyun demod_timeout, fec_timeout) == TRUE) {
1298*4882a593Smuzhiyun intp->result[demod].locked = TRUE;
1299*4882a593Smuzhiyun signal_type = stv0900_get_signal_params(fe);
1300*4882a593Smuzhiyun stv0900_track_optimization(fe);
1301*4882a593Smuzhiyun } else {
1302*4882a593Smuzhiyun stv0900_write_bits(intp, SPECINV_CONTROL,
1303*4882a593Smuzhiyun STV0900_IQ_FORCE_NORMAL);
1304*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x1c);
1305*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT1, freq1);
1306*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT0, freq0);
1307*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x18);
1308*4882a593Smuzhiyun if (stv0900_wait_for_lock(intp, demod,
1309*4882a593Smuzhiyun demod_timeout, fec_timeout) == TRUE) {
1310*4882a593Smuzhiyun intp->result[demod].locked = TRUE;
1311*4882a593Smuzhiyun signal_type = stv0900_get_signal_params(fe);
1312*4882a593Smuzhiyun stv0900_track_optimization(fe);
1313*4882a593Smuzhiyun }
1314*4882a593Smuzhiyun
1315*4882a593Smuzhiyun }
1316*4882a593Smuzhiyun
1317*4882a593Smuzhiyun } else
1318*4882a593Smuzhiyun intp->result[demod].locked = FALSE;
1319*4882a593Smuzhiyun
1320*4882a593Smuzhiyun return signal_type;
1321*4882a593Smuzhiyun }
1322*4882a593Smuzhiyun
stv0900_blind_check_agc2_min_level(struct stv0900_internal * intp,enum fe_stv0900_demod_num demod)1323*4882a593Smuzhiyun static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *intp,
1324*4882a593Smuzhiyun enum fe_stv0900_demod_num demod)
1325*4882a593Smuzhiyun {
1326*4882a593Smuzhiyun u32 minagc2level = 0xffff,
1327*4882a593Smuzhiyun agc2level,
1328*4882a593Smuzhiyun init_freq, freq_step;
1329*4882a593Smuzhiyun
1330*4882a593Smuzhiyun s32 i, j, nb_steps, direction;
1331*4882a593Smuzhiyun
1332*4882a593Smuzhiyun dprintk("%s\n", __func__);
1333*4882a593Smuzhiyun
1334*4882a593Smuzhiyun stv0900_write_reg(intp, AGC2REF, 0x38);
1335*4882a593Smuzhiyun stv0900_write_bits(intp, SCAN_ENABLE, 0);
1336*4882a593Smuzhiyun stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
1337*4882a593Smuzhiyun
1338*4882a593Smuzhiyun stv0900_write_bits(intp, AUTO_GUP, 1);
1339*4882a593Smuzhiyun stv0900_write_bits(intp, AUTO_GLOW, 1);
1340*4882a593Smuzhiyun
1341*4882a593Smuzhiyun stv0900_write_reg(intp, DMDT0M, 0x0);
1342*4882a593Smuzhiyun
1343*4882a593Smuzhiyun stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod);
1344*4882a593Smuzhiyun nb_steps = -1 + (intp->srch_range[demod] / 1000000);
1345*4882a593Smuzhiyun nb_steps /= 2;
1346*4882a593Smuzhiyun nb_steps = (2 * nb_steps) + 1;
1347*4882a593Smuzhiyun
1348*4882a593Smuzhiyun if (nb_steps < 0)
1349*4882a593Smuzhiyun nb_steps = 1;
1350*4882a593Smuzhiyun
1351*4882a593Smuzhiyun direction = 1;
1352*4882a593Smuzhiyun
1353*4882a593Smuzhiyun freq_step = (1000000 << 8) / (intp->mclk >> 8);
1354*4882a593Smuzhiyun
1355*4882a593Smuzhiyun init_freq = 0;
1356*4882a593Smuzhiyun
1357*4882a593Smuzhiyun for (i = 0; i < nb_steps; i++) {
1358*4882a593Smuzhiyun if (direction > 0)
1359*4882a593Smuzhiyun init_freq = init_freq + (freq_step * i);
1360*4882a593Smuzhiyun else
1361*4882a593Smuzhiyun init_freq = init_freq - (freq_step * i);
1362*4882a593Smuzhiyun
1363*4882a593Smuzhiyun direction *= -1;
1364*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x5C);
1365*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT1, (init_freq >> 8) & 0xff);
1366*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT0, init_freq & 0xff);
1367*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x58);
1368*4882a593Smuzhiyun msleep(10);
1369*4882a593Smuzhiyun agc2level = 0;
1370*4882a593Smuzhiyun
1371*4882a593Smuzhiyun for (j = 0; j < 10; j++)
1372*4882a593Smuzhiyun agc2level += (stv0900_read_reg(intp, AGC2I1) << 8)
1373*4882a593Smuzhiyun | stv0900_read_reg(intp, AGC2I0);
1374*4882a593Smuzhiyun
1375*4882a593Smuzhiyun agc2level /= 10;
1376*4882a593Smuzhiyun
1377*4882a593Smuzhiyun if (agc2level < minagc2level)
1378*4882a593Smuzhiyun minagc2level = agc2level;
1379*4882a593Smuzhiyun
1380*4882a593Smuzhiyun }
1381*4882a593Smuzhiyun
1382*4882a593Smuzhiyun return (u16)minagc2level;
1383*4882a593Smuzhiyun }
1384*4882a593Smuzhiyun
stv0900_search_srate_coarse(struct dvb_frontend * fe)1385*4882a593Smuzhiyun static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe)
1386*4882a593Smuzhiyun {
1387*4882a593Smuzhiyun struct stv0900_state *state = fe->demodulator_priv;
1388*4882a593Smuzhiyun struct stv0900_internal *intp = state->internal;
1389*4882a593Smuzhiyun enum fe_stv0900_demod_num demod = state->demod;
1390*4882a593Smuzhiyun int timing_lck = FALSE;
1391*4882a593Smuzhiyun s32 i, timingcpt = 0,
1392*4882a593Smuzhiyun direction = 1,
1393*4882a593Smuzhiyun nb_steps,
1394*4882a593Smuzhiyun current_step = 0,
1395*4882a593Smuzhiyun tuner_freq;
1396*4882a593Smuzhiyun u32 agc2_th,
1397*4882a593Smuzhiyun coarse_srate = 0,
1398*4882a593Smuzhiyun agc2_integr = 0,
1399*4882a593Smuzhiyun currier_step = 1200;
1400*4882a593Smuzhiyun
1401*4882a593Smuzhiyun if (intp->chip_id >= 0x30)
1402*4882a593Smuzhiyun agc2_th = 0x2e00;
1403*4882a593Smuzhiyun else
1404*4882a593Smuzhiyun agc2_th = 0x1f00;
1405*4882a593Smuzhiyun
1406*4882a593Smuzhiyun stv0900_write_bits(intp, DEMOD_MODE, 0x1f);
1407*4882a593Smuzhiyun stv0900_write_reg(intp, TMGCFG, 0x12);
1408*4882a593Smuzhiyun stv0900_write_reg(intp, TMGTHRISE, 0xf0);
1409*4882a593Smuzhiyun stv0900_write_reg(intp, TMGTHFALL, 0xe0);
1410*4882a593Smuzhiyun stv0900_write_bits(intp, SCAN_ENABLE, 1);
1411*4882a593Smuzhiyun stv0900_write_bits(intp, CFR_AUTOSCAN, 1);
1412*4882a593Smuzhiyun stv0900_write_reg(intp, SFRUP1, 0x83);
1413*4882a593Smuzhiyun stv0900_write_reg(intp, SFRUP0, 0xc0);
1414*4882a593Smuzhiyun stv0900_write_reg(intp, SFRLOW1, 0x82);
1415*4882a593Smuzhiyun stv0900_write_reg(intp, SFRLOW0, 0xa0);
1416*4882a593Smuzhiyun stv0900_write_reg(intp, DMDT0M, 0x0);
1417*4882a593Smuzhiyun stv0900_write_reg(intp, AGC2REF, 0x50);
1418*4882a593Smuzhiyun
1419*4882a593Smuzhiyun if (intp->chip_id >= 0x30) {
1420*4882a593Smuzhiyun stv0900_write_reg(intp, CARFREQ, 0x99);
1421*4882a593Smuzhiyun stv0900_write_reg(intp, SFRSTEP, 0x98);
1422*4882a593Smuzhiyun } else if (intp->chip_id >= 0x20) {
1423*4882a593Smuzhiyun stv0900_write_reg(intp, CARFREQ, 0x6a);
1424*4882a593Smuzhiyun stv0900_write_reg(intp, SFRSTEP, 0x95);
1425*4882a593Smuzhiyun } else {
1426*4882a593Smuzhiyun stv0900_write_reg(intp, CARFREQ, 0xed);
1427*4882a593Smuzhiyun stv0900_write_reg(intp, SFRSTEP, 0x73);
1428*4882a593Smuzhiyun }
1429*4882a593Smuzhiyun
1430*4882a593Smuzhiyun if (intp->symbol_rate[demod] <= 2000000)
1431*4882a593Smuzhiyun currier_step = 1000;
1432*4882a593Smuzhiyun else if (intp->symbol_rate[demod] <= 5000000)
1433*4882a593Smuzhiyun currier_step = 2000;
1434*4882a593Smuzhiyun else if (intp->symbol_rate[demod] <= 12000000)
1435*4882a593Smuzhiyun currier_step = 3000;
1436*4882a593Smuzhiyun else
1437*4882a593Smuzhiyun currier_step = 5000;
1438*4882a593Smuzhiyun
1439*4882a593Smuzhiyun nb_steps = -1 + ((intp->srch_range[demod] / 1000) / currier_step);
1440*4882a593Smuzhiyun nb_steps /= 2;
1441*4882a593Smuzhiyun nb_steps = (2 * nb_steps) + 1;
1442*4882a593Smuzhiyun
1443*4882a593Smuzhiyun if (nb_steps < 0)
1444*4882a593Smuzhiyun nb_steps = 1;
1445*4882a593Smuzhiyun else if (nb_steps > 10) {
1446*4882a593Smuzhiyun nb_steps = 11;
1447*4882a593Smuzhiyun currier_step = (intp->srch_range[demod] / 1000) / 10;
1448*4882a593Smuzhiyun }
1449*4882a593Smuzhiyun
1450*4882a593Smuzhiyun current_step = 0;
1451*4882a593Smuzhiyun direction = 1;
1452*4882a593Smuzhiyun
1453*4882a593Smuzhiyun tuner_freq = intp->freq[demod];
1454*4882a593Smuzhiyun
1455*4882a593Smuzhiyun while ((timing_lck == FALSE) && (current_step < nb_steps)) {
1456*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x5f);
1457*4882a593Smuzhiyun stv0900_write_bits(intp, DEMOD_MODE, 0);
1458*4882a593Smuzhiyun
1459*4882a593Smuzhiyun msleep(50);
1460*4882a593Smuzhiyun
1461*4882a593Smuzhiyun for (i = 0; i < 10; i++) {
1462*4882a593Smuzhiyun if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2)
1463*4882a593Smuzhiyun timingcpt++;
1464*4882a593Smuzhiyun
1465*4882a593Smuzhiyun agc2_integr += (stv0900_read_reg(intp, AGC2I1) << 8) |
1466*4882a593Smuzhiyun stv0900_read_reg(intp, AGC2I0);
1467*4882a593Smuzhiyun }
1468*4882a593Smuzhiyun
1469*4882a593Smuzhiyun agc2_integr /= 10;
1470*4882a593Smuzhiyun coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
1471*4882a593Smuzhiyun current_step++;
1472*4882a593Smuzhiyun direction *= -1;
1473*4882a593Smuzhiyun
1474*4882a593Smuzhiyun dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started. tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n",
1475*4882a593Smuzhiyun tuner_freq, agc2_integr, coarse_srate, timingcpt);
1476*4882a593Smuzhiyun
1477*4882a593Smuzhiyun if ((timingcpt >= 5) &&
1478*4882a593Smuzhiyun (agc2_integr < agc2_th) &&
1479*4882a593Smuzhiyun (coarse_srate < 55000000) &&
1480*4882a593Smuzhiyun (coarse_srate > 850000))
1481*4882a593Smuzhiyun timing_lck = TRUE;
1482*4882a593Smuzhiyun else if (current_step < nb_steps) {
1483*4882a593Smuzhiyun if (direction > 0)
1484*4882a593Smuzhiyun tuner_freq += (current_step * currier_step);
1485*4882a593Smuzhiyun else
1486*4882a593Smuzhiyun tuner_freq -= (current_step * currier_step);
1487*4882a593Smuzhiyun
1488*4882a593Smuzhiyun if (intp->tuner_type[demod] == 3)
1489*4882a593Smuzhiyun stv0900_set_tuner_auto(intp, tuner_freq,
1490*4882a593Smuzhiyun intp->bw[demod], demod);
1491*4882a593Smuzhiyun else
1492*4882a593Smuzhiyun stv0900_set_tuner(fe, tuner_freq,
1493*4882a593Smuzhiyun intp->bw[demod]);
1494*4882a593Smuzhiyun }
1495*4882a593Smuzhiyun }
1496*4882a593Smuzhiyun
1497*4882a593Smuzhiyun if (timing_lck == FALSE)
1498*4882a593Smuzhiyun coarse_srate = 0;
1499*4882a593Smuzhiyun else
1500*4882a593Smuzhiyun coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
1501*4882a593Smuzhiyun
1502*4882a593Smuzhiyun return coarse_srate;
1503*4882a593Smuzhiyun }
1504*4882a593Smuzhiyun
stv0900_search_srate_fine(struct dvb_frontend * fe)1505*4882a593Smuzhiyun static u32 stv0900_search_srate_fine(struct dvb_frontend *fe)
1506*4882a593Smuzhiyun {
1507*4882a593Smuzhiyun struct stv0900_state *state = fe->demodulator_priv;
1508*4882a593Smuzhiyun struct stv0900_internal *intp = state->internal;
1509*4882a593Smuzhiyun enum fe_stv0900_demod_num demod = state->demod;
1510*4882a593Smuzhiyun u32 coarse_srate,
1511*4882a593Smuzhiyun coarse_freq,
1512*4882a593Smuzhiyun symb,
1513*4882a593Smuzhiyun symbmax,
1514*4882a593Smuzhiyun symbmin,
1515*4882a593Smuzhiyun symbcomp;
1516*4882a593Smuzhiyun
1517*4882a593Smuzhiyun coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
1518*4882a593Smuzhiyun
1519*4882a593Smuzhiyun if (coarse_srate > 3000000) {
1520*4882a593Smuzhiyun symbmax = 13 * (coarse_srate / 10);
1521*4882a593Smuzhiyun symbmax = (symbmax / 1000) * 65536;
1522*4882a593Smuzhiyun symbmax /= (intp->mclk / 1000);
1523*4882a593Smuzhiyun
1524*4882a593Smuzhiyun symbmin = 10 * (coarse_srate / 13);
1525*4882a593Smuzhiyun symbmin = (symbmin / 1000)*65536;
1526*4882a593Smuzhiyun symbmin /= (intp->mclk / 1000);
1527*4882a593Smuzhiyun
1528*4882a593Smuzhiyun symb = (coarse_srate / 1000) * 65536;
1529*4882a593Smuzhiyun symb /= (intp->mclk / 1000);
1530*4882a593Smuzhiyun } else {
1531*4882a593Smuzhiyun symbmax = 13 * (coarse_srate / 10);
1532*4882a593Smuzhiyun symbmax = (symbmax / 100) * 65536;
1533*4882a593Smuzhiyun symbmax /= (intp->mclk / 100);
1534*4882a593Smuzhiyun
1535*4882a593Smuzhiyun symbmin = 10 * (coarse_srate / 14);
1536*4882a593Smuzhiyun symbmin = (symbmin / 100) * 65536;
1537*4882a593Smuzhiyun symbmin /= (intp->mclk / 100);
1538*4882a593Smuzhiyun
1539*4882a593Smuzhiyun symb = (coarse_srate / 100) * 65536;
1540*4882a593Smuzhiyun symb /= (intp->mclk / 100);
1541*4882a593Smuzhiyun }
1542*4882a593Smuzhiyun
1543*4882a593Smuzhiyun symbcomp = 13 * (coarse_srate / 10);
1544*4882a593Smuzhiyun coarse_freq = (stv0900_read_reg(intp, CFR2) << 8)
1545*4882a593Smuzhiyun | stv0900_read_reg(intp, CFR1);
1546*4882a593Smuzhiyun
1547*4882a593Smuzhiyun if (symbcomp < intp->symbol_rate[demod])
1548*4882a593Smuzhiyun coarse_srate = 0;
1549*4882a593Smuzhiyun else {
1550*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x1f);
1551*4882a593Smuzhiyun stv0900_write_reg(intp, TMGCFG2, 0xc1);
1552*4882a593Smuzhiyun stv0900_write_reg(intp, TMGTHRISE, 0x20);
1553*4882a593Smuzhiyun stv0900_write_reg(intp, TMGTHFALL, 0x00);
1554*4882a593Smuzhiyun stv0900_write_reg(intp, TMGCFG, 0xd2);
1555*4882a593Smuzhiyun stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
1556*4882a593Smuzhiyun stv0900_write_reg(intp, AGC2REF, 0x38);
1557*4882a593Smuzhiyun
1558*4882a593Smuzhiyun if (intp->chip_id >= 0x30)
1559*4882a593Smuzhiyun stv0900_write_reg(intp, CARFREQ, 0x79);
1560*4882a593Smuzhiyun else if (intp->chip_id >= 0x20)
1561*4882a593Smuzhiyun stv0900_write_reg(intp, CARFREQ, 0x49);
1562*4882a593Smuzhiyun else
1563*4882a593Smuzhiyun stv0900_write_reg(intp, CARFREQ, 0xed);
1564*4882a593Smuzhiyun
1565*4882a593Smuzhiyun stv0900_write_reg(intp, SFRUP1, (symbmax >> 8) & 0x7f);
1566*4882a593Smuzhiyun stv0900_write_reg(intp, SFRUP0, (symbmax & 0xff));
1567*4882a593Smuzhiyun
1568*4882a593Smuzhiyun stv0900_write_reg(intp, SFRLOW1, (symbmin >> 8) & 0x7f);
1569*4882a593Smuzhiyun stv0900_write_reg(intp, SFRLOW0, (symbmin & 0xff));
1570*4882a593Smuzhiyun
1571*4882a593Smuzhiyun stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0xff);
1572*4882a593Smuzhiyun stv0900_write_reg(intp, SFRINIT0, (symb & 0xff));
1573*4882a593Smuzhiyun
1574*4882a593Smuzhiyun stv0900_write_reg(intp, DMDT0M, 0x20);
1575*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT1, (coarse_freq >> 8) & 0xff);
1576*4882a593Smuzhiyun stv0900_write_reg(intp, CFRINIT0, coarse_freq & 0xff);
1577*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x15);
1578*4882a593Smuzhiyun }
1579*4882a593Smuzhiyun
1580*4882a593Smuzhiyun return coarse_srate;
1581*4882a593Smuzhiyun }
1582*4882a593Smuzhiyun
stv0900_blind_search_algo(struct dvb_frontend * fe)1583*4882a593Smuzhiyun static int stv0900_blind_search_algo(struct dvb_frontend *fe)
1584*4882a593Smuzhiyun {
1585*4882a593Smuzhiyun struct stv0900_state *state = fe->demodulator_priv;
1586*4882a593Smuzhiyun struct stv0900_internal *intp = state->internal;
1587*4882a593Smuzhiyun enum fe_stv0900_demod_num demod = state->demod;
1588*4882a593Smuzhiyun u8 k_ref_tmg,
1589*4882a593Smuzhiyun k_ref_tmg_max,
1590*4882a593Smuzhiyun k_ref_tmg_min;
1591*4882a593Smuzhiyun u32 coarse_srate,
1592*4882a593Smuzhiyun agc2_th;
1593*4882a593Smuzhiyun int lock = FALSE,
1594*4882a593Smuzhiyun coarse_fail = FALSE;
1595*4882a593Smuzhiyun s32 demod_timeout = 500,
1596*4882a593Smuzhiyun fec_timeout = 50,
1597*4882a593Smuzhiyun fail_cpt,
1598*4882a593Smuzhiyun i,
1599*4882a593Smuzhiyun agc2_overflow;
1600*4882a593Smuzhiyun u16 agc2_int;
1601*4882a593Smuzhiyun u8 dstatus2;
1602*4882a593Smuzhiyun
1603*4882a593Smuzhiyun dprintk("%s\n", __func__);
1604*4882a593Smuzhiyun
1605*4882a593Smuzhiyun if (intp->chip_id < 0x20) {
1606*4882a593Smuzhiyun k_ref_tmg_max = 233;
1607*4882a593Smuzhiyun k_ref_tmg_min = 143;
1608*4882a593Smuzhiyun } else {
1609*4882a593Smuzhiyun k_ref_tmg_max = 110;
1610*4882a593Smuzhiyun k_ref_tmg_min = 10;
1611*4882a593Smuzhiyun }
1612*4882a593Smuzhiyun
1613*4882a593Smuzhiyun if (intp->chip_id <= 0x20)
1614*4882a593Smuzhiyun agc2_th = STV0900_BLIND_SEARCH_AGC2_TH;
1615*4882a593Smuzhiyun else
1616*4882a593Smuzhiyun agc2_th = STV0900_BLIND_SEARCH_AGC2_TH_CUT30;
1617*4882a593Smuzhiyun
1618*4882a593Smuzhiyun agc2_int = stv0900_blind_check_agc2_min_level(intp, demod);
1619*4882a593Smuzhiyun
1620*4882a593Smuzhiyun dprintk("%s agc2_int=%d agc2_th=%d \n", __func__, agc2_int, agc2_th);
1621*4882a593Smuzhiyun if (agc2_int > agc2_th)
1622*4882a593Smuzhiyun return FALSE;
1623*4882a593Smuzhiyun
1624*4882a593Smuzhiyun if (intp->chip_id == 0x10)
1625*4882a593Smuzhiyun stv0900_write_reg(intp, CORRELEXP, 0xaa);
1626*4882a593Smuzhiyun
1627*4882a593Smuzhiyun if (intp->chip_id < 0x20)
1628*4882a593Smuzhiyun stv0900_write_reg(intp, CARHDR, 0x55);
1629*4882a593Smuzhiyun else
1630*4882a593Smuzhiyun stv0900_write_reg(intp, CARHDR, 0x20);
1631*4882a593Smuzhiyun
1632*4882a593Smuzhiyun if (intp->chip_id <= 0x20)
1633*4882a593Smuzhiyun stv0900_write_reg(intp, CARCFG, 0xc4);
1634*4882a593Smuzhiyun else
1635*4882a593Smuzhiyun stv0900_write_reg(intp, CARCFG, 0x6);
1636*4882a593Smuzhiyun
1637*4882a593Smuzhiyun stv0900_write_reg(intp, RTCS2, 0x44);
1638*4882a593Smuzhiyun
1639*4882a593Smuzhiyun if (intp->chip_id >= 0x20) {
1640*4882a593Smuzhiyun stv0900_write_reg(intp, EQUALCFG, 0x41);
1641*4882a593Smuzhiyun stv0900_write_reg(intp, FFECFG, 0x41);
1642*4882a593Smuzhiyun stv0900_write_reg(intp, VITSCALE, 0x82);
1643*4882a593Smuzhiyun stv0900_write_reg(intp, VAVSRVIT, 0x0);
1644*4882a593Smuzhiyun }
1645*4882a593Smuzhiyun
1646*4882a593Smuzhiyun k_ref_tmg = k_ref_tmg_max;
1647*4882a593Smuzhiyun
1648*4882a593Smuzhiyun do {
1649*4882a593Smuzhiyun stv0900_write_reg(intp, KREFTMG, k_ref_tmg);
1650*4882a593Smuzhiyun if (stv0900_search_srate_coarse(fe) != 0) {
1651*4882a593Smuzhiyun coarse_srate = stv0900_search_srate_fine(fe);
1652*4882a593Smuzhiyun
1653*4882a593Smuzhiyun if (coarse_srate != 0) {
1654*4882a593Smuzhiyun stv0900_get_lock_timeout(&demod_timeout,
1655*4882a593Smuzhiyun &fec_timeout,
1656*4882a593Smuzhiyun coarse_srate,
1657*4882a593Smuzhiyun STV0900_BLIND_SEARCH);
1658*4882a593Smuzhiyun lock = stv0900_get_demod_lock(intp,
1659*4882a593Smuzhiyun demod,
1660*4882a593Smuzhiyun demod_timeout);
1661*4882a593Smuzhiyun } else
1662*4882a593Smuzhiyun lock = FALSE;
1663*4882a593Smuzhiyun } else {
1664*4882a593Smuzhiyun fail_cpt = 0;
1665*4882a593Smuzhiyun agc2_overflow = 0;
1666*4882a593Smuzhiyun
1667*4882a593Smuzhiyun for (i = 0; i < 10; i++) {
1668*4882a593Smuzhiyun agc2_int = (stv0900_read_reg(intp, AGC2I1) << 8)
1669*4882a593Smuzhiyun | stv0900_read_reg(intp, AGC2I0);
1670*4882a593Smuzhiyun
1671*4882a593Smuzhiyun if (agc2_int >= 0xff00)
1672*4882a593Smuzhiyun agc2_overflow++;
1673*4882a593Smuzhiyun
1674*4882a593Smuzhiyun dstatus2 = stv0900_read_reg(intp, DSTATUS2);
1675*4882a593Smuzhiyun
1676*4882a593Smuzhiyun if (((dstatus2 & 0x1) == 0x1) &&
1677*4882a593Smuzhiyun ((dstatus2 >> 7) == 1))
1678*4882a593Smuzhiyun fail_cpt++;
1679*4882a593Smuzhiyun }
1680*4882a593Smuzhiyun
1681*4882a593Smuzhiyun if ((fail_cpt > 7) || (agc2_overflow > 7))
1682*4882a593Smuzhiyun coarse_fail = TRUE;
1683*4882a593Smuzhiyun
1684*4882a593Smuzhiyun lock = FALSE;
1685*4882a593Smuzhiyun }
1686*4882a593Smuzhiyun k_ref_tmg -= 30;
1687*4882a593Smuzhiyun } while ((k_ref_tmg >= k_ref_tmg_min) &&
1688*4882a593Smuzhiyun (lock == FALSE) &&
1689*4882a593Smuzhiyun (coarse_fail == FALSE));
1690*4882a593Smuzhiyun
1691*4882a593Smuzhiyun return lock;
1692*4882a593Smuzhiyun }
1693*4882a593Smuzhiyun
stv0900_set_viterbi_acq(struct stv0900_internal * intp,enum fe_stv0900_demod_num demod)1694*4882a593Smuzhiyun static void stv0900_set_viterbi_acq(struct stv0900_internal *intp,
1695*4882a593Smuzhiyun enum fe_stv0900_demod_num demod)
1696*4882a593Smuzhiyun {
1697*4882a593Smuzhiyun s32 vth_reg = VTH12;
1698*4882a593Smuzhiyun
1699*4882a593Smuzhiyun dprintk("%s\n", __func__);
1700*4882a593Smuzhiyun
1701*4882a593Smuzhiyun stv0900_write_reg(intp, vth_reg++, 0x96);
1702*4882a593Smuzhiyun stv0900_write_reg(intp, vth_reg++, 0x64);
1703*4882a593Smuzhiyun stv0900_write_reg(intp, vth_reg++, 0x36);
1704*4882a593Smuzhiyun stv0900_write_reg(intp, vth_reg++, 0x23);
1705*4882a593Smuzhiyun stv0900_write_reg(intp, vth_reg++, 0x1e);
1706*4882a593Smuzhiyun stv0900_write_reg(intp, vth_reg++, 0x19);
1707*4882a593Smuzhiyun }
1708*4882a593Smuzhiyun
stv0900_set_search_standard(struct stv0900_internal * intp,enum fe_stv0900_demod_num demod)1709*4882a593Smuzhiyun static void stv0900_set_search_standard(struct stv0900_internal *intp,
1710*4882a593Smuzhiyun enum fe_stv0900_demod_num demod)
1711*4882a593Smuzhiyun {
1712*4882a593Smuzhiyun
1713*4882a593Smuzhiyun dprintk("%s\n", __func__);
1714*4882a593Smuzhiyun
1715*4882a593Smuzhiyun switch (intp->srch_standard[demod]) {
1716*4882a593Smuzhiyun case STV0900_SEARCH_DVBS1:
1717*4882a593Smuzhiyun dprintk("Search Standard = DVBS1\n");
1718*4882a593Smuzhiyun break;
1719*4882a593Smuzhiyun case STV0900_SEARCH_DSS:
1720*4882a593Smuzhiyun dprintk("Search Standard = DSS\n");
1721*4882a593Smuzhiyun break;
1722*4882a593Smuzhiyun case STV0900_SEARCH_DVBS2:
1723*4882a593Smuzhiyun dprintk("Search Standard = DVBS2\n");
1724*4882a593Smuzhiyun break;
1725*4882a593Smuzhiyun case STV0900_AUTO_SEARCH:
1726*4882a593Smuzhiyun default:
1727*4882a593Smuzhiyun dprintk("Search Standard = AUTO\n");
1728*4882a593Smuzhiyun break;
1729*4882a593Smuzhiyun }
1730*4882a593Smuzhiyun
1731*4882a593Smuzhiyun switch (intp->srch_standard[demod]) {
1732*4882a593Smuzhiyun case STV0900_SEARCH_DVBS1:
1733*4882a593Smuzhiyun case STV0900_SEARCH_DSS:
1734*4882a593Smuzhiyun stv0900_write_bits(intp, DVBS1_ENABLE, 1);
1735*4882a593Smuzhiyun stv0900_write_bits(intp, DVBS2_ENABLE, 0);
1736*4882a593Smuzhiyun stv0900_write_bits(intp, STOP_CLKVIT, 0);
1737*4882a593Smuzhiyun stv0900_set_dvbs1_track_car_loop(intp,
1738*4882a593Smuzhiyun demod,
1739*4882a593Smuzhiyun intp->symbol_rate[demod]);
1740*4882a593Smuzhiyun stv0900_write_reg(intp, CAR2CFG, 0x22);
1741*4882a593Smuzhiyun
1742*4882a593Smuzhiyun stv0900_set_viterbi_acq(intp, demod);
1743*4882a593Smuzhiyun stv0900_set_viterbi_standard(intp,
1744*4882a593Smuzhiyun intp->srch_standard[demod],
1745*4882a593Smuzhiyun intp->fec[demod], demod);
1746*4882a593Smuzhiyun
1747*4882a593Smuzhiyun break;
1748*4882a593Smuzhiyun case STV0900_SEARCH_DVBS2:
1749*4882a593Smuzhiyun stv0900_write_bits(intp, DVBS1_ENABLE, 0);
1750*4882a593Smuzhiyun stv0900_write_bits(intp, DVBS2_ENABLE, 1);
1751*4882a593Smuzhiyun stv0900_write_bits(intp, STOP_CLKVIT, 1);
1752*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC, 0x1a);
1753*4882a593Smuzhiyun stv0900_write_reg(intp, BCLC, 0x09);
1754*4882a593Smuzhiyun if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/
1755*4882a593Smuzhiyun stv0900_write_reg(intp, CAR2CFG, 0x26);
1756*4882a593Smuzhiyun else
1757*4882a593Smuzhiyun stv0900_write_reg(intp, CAR2CFG, 0x66);
1758*4882a593Smuzhiyun
1759*4882a593Smuzhiyun if (intp->demod_mode != STV0900_SINGLE) {
1760*4882a593Smuzhiyun if (intp->chip_id <= 0x11)
1761*4882a593Smuzhiyun stv0900_stop_all_s2_modcod(intp, demod);
1762*4882a593Smuzhiyun else
1763*4882a593Smuzhiyun stv0900_activate_s2_modcod(intp, demod);
1764*4882a593Smuzhiyun
1765*4882a593Smuzhiyun } else
1766*4882a593Smuzhiyun stv0900_activate_s2_modcod_single(intp, demod);
1767*4882a593Smuzhiyun
1768*4882a593Smuzhiyun stv0900_set_viterbi_tracq(intp, demod);
1769*4882a593Smuzhiyun
1770*4882a593Smuzhiyun break;
1771*4882a593Smuzhiyun case STV0900_AUTO_SEARCH:
1772*4882a593Smuzhiyun default:
1773*4882a593Smuzhiyun stv0900_write_bits(intp, DVBS1_ENABLE, 1);
1774*4882a593Smuzhiyun stv0900_write_bits(intp, DVBS2_ENABLE, 1);
1775*4882a593Smuzhiyun stv0900_write_bits(intp, STOP_CLKVIT, 0);
1776*4882a593Smuzhiyun stv0900_write_reg(intp, ACLC, 0x1a);
1777*4882a593Smuzhiyun stv0900_write_reg(intp, BCLC, 0x09);
1778*4882a593Smuzhiyun stv0900_set_dvbs1_track_car_loop(intp,
1779*4882a593Smuzhiyun demod,
1780*4882a593Smuzhiyun intp->symbol_rate[demod]);
1781*4882a593Smuzhiyun if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/
1782*4882a593Smuzhiyun stv0900_write_reg(intp, CAR2CFG, 0x26);
1783*4882a593Smuzhiyun else
1784*4882a593Smuzhiyun stv0900_write_reg(intp, CAR2CFG, 0x66);
1785*4882a593Smuzhiyun
1786*4882a593Smuzhiyun if (intp->demod_mode != STV0900_SINGLE) {
1787*4882a593Smuzhiyun if (intp->chip_id <= 0x11)
1788*4882a593Smuzhiyun stv0900_stop_all_s2_modcod(intp, demod);
1789*4882a593Smuzhiyun else
1790*4882a593Smuzhiyun stv0900_activate_s2_modcod(intp, demod);
1791*4882a593Smuzhiyun
1792*4882a593Smuzhiyun } else
1793*4882a593Smuzhiyun stv0900_activate_s2_modcod_single(intp, demod);
1794*4882a593Smuzhiyun
1795*4882a593Smuzhiyun stv0900_set_viterbi_tracq(intp, demod);
1796*4882a593Smuzhiyun stv0900_set_viterbi_standard(intp,
1797*4882a593Smuzhiyun intp->srch_standard[demod],
1798*4882a593Smuzhiyun intp->fec[demod], demod);
1799*4882a593Smuzhiyun
1800*4882a593Smuzhiyun break;
1801*4882a593Smuzhiyun }
1802*4882a593Smuzhiyun }
1803*4882a593Smuzhiyun
stv0900_algo(struct dvb_frontend * fe)1804*4882a593Smuzhiyun enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe)
1805*4882a593Smuzhiyun {
1806*4882a593Smuzhiyun struct stv0900_state *state = fe->demodulator_priv;
1807*4882a593Smuzhiyun struct stv0900_internal *intp = state->internal;
1808*4882a593Smuzhiyun enum fe_stv0900_demod_num demod = state->demod;
1809*4882a593Smuzhiyun
1810*4882a593Smuzhiyun s32 demod_timeout = 500, fec_timeout = 50;
1811*4882a593Smuzhiyun s32 aq_power, agc1_power, i;
1812*4882a593Smuzhiyun
1813*4882a593Smuzhiyun int lock = FALSE, low_sr = FALSE;
1814*4882a593Smuzhiyun
1815*4882a593Smuzhiyun enum fe_stv0900_signal_type signal_type = STV0900_NOCARRIER;
1816*4882a593Smuzhiyun enum fe_stv0900_search_algo algo;
1817*4882a593Smuzhiyun int no_signal = FALSE;
1818*4882a593Smuzhiyun
1819*4882a593Smuzhiyun dprintk("%s\n", __func__);
1820*4882a593Smuzhiyun
1821*4882a593Smuzhiyun algo = intp->srch_algo[demod];
1822*4882a593Smuzhiyun stv0900_write_bits(intp, RST_HWARE, 1);
1823*4882a593Smuzhiyun stv0900_write_reg(intp, DMDISTATE, 0x5c);
1824*4882a593Smuzhiyun if (intp->chip_id >= 0x20) {
1825*4882a593Smuzhiyun if (intp->symbol_rate[demod] > 5000000)
1826*4882a593Smuzhiyun stv0900_write_reg(intp, CORRELABS, 0x9e);
1827*4882a593Smuzhiyun else
1828*4882a593Smuzhiyun stv0900_write_reg(intp, CORRELABS, 0x82);
1829*4882a593Smuzhiyun } else
1830*4882a593Smuzhiyun stv0900_write_reg(intp, CORRELABS, 0x88);
1831*4882a593Smuzhiyun
1832*4882a593Smuzhiyun stv0900_get_lock_timeout(&demod_timeout, &fec_timeout,
1833*4882a593Smuzhiyun intp->symbol_rate[demod],
1834*4882a593Smuzhiyun intp->srch_algo[demod]);
1835*4882a593Smuzhiyun
1836*4882a593Smuzhiyun if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) {
1837*4882a593Smuzhiyun intp->bw[demod] = 2 * 36000000;
1838*4882a593Smuzhiyun
1839*4882a593Smuzhiyun stv0900_write_reg(intp, TMGCFG2, 0xc0);
1840*4882a593Smuzhiyun stv0900_write_reg(intp, CORRELMANT, 0x70);
1841*4882a593Smuzhiyun
1842*4882a593Smuzhiyun stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod);
1843*4882a593Smuzhiyun } else {
1844*4882a593Smuzhiyun stv0900_write_reg(intp, DMDT0M, 0x20);
1845*4882a593Smuzhiyun stv0900_write_reg(intp, TMGCFG, 0xd2);
1846*4882a593Smuzhiyun
1847*4882a593Smuzhiyun if (intp->symbol_rate[demod] < 2000000)
1848*4882a593Smuzhiyun stv0900_write_reg(intp, CORRELMANT, 0x63);
1849*4882a593Smuzhiyun else
1850*4882a593Smuzhiyun stv0900_write_reg(intp, CORRELMANT, 0x70);
1851*4882a593Smuzhiyun
1852*4882a593Smuzhiyun stv0900_write_reg(intp, AGC2REF, 0x38);
1853*4882a593Smuzhiyun
1854*4882a593Smuzhiyun intp->bw[demod] =
1855*4882a593Smuzhiyun stv0900_carrier_width(intp->symbol_rate[demod],
1856*4882a593Smuzhiyun intp->rolloff);
1857*4882a593Smuzhiyun if (intp->chip_id >= 0x20) {
1858*4882a593Smuzhiyun stv0900_write_reg(intp, KREFTMG, 0x5a);
1859*4882a593Smuzhiyun
1860*4882a593Smuzhiyun if (intp->srch_algo[demod] == STV0900_COLD_START) {
1861*4882a593Smuzhiyun intp->bw[demod] += 10000000;
1862*4882a593Smuzhiyun intp->bw[demod] *= 15;
1863*4882a593Smuzhiyun intp->bw[demod] /= 10;
1864*4882a593Smuzhiyun } else if (intp->srch_algo[demod] == STV0900_WARM_START)
1865*4882a593Smuzhiyun intp->bw[demod] += 10000000;
1866*4882a593Smuzhiyun
1867*4882a593Smuzhiyun } else {
1868*4882a593Smuzhiyun stv0900_write_reg(intp, KREFTMG, 0xc1);
1869*4882a593Smuzhiyun intp->bw[demod] += 10000000;
1870*4882a593Smuzhiyun intp->bw[demod] *= 15;
1871*4882a593Smuzhiyun intp->bw[demod] /= 10;
1872*4882a593Smuzhiyun }
1873*4882a593Smuzhiyun
1874*4882a593Smuzhiyun stv0900_write_reg(intp, TMGCFG2, 0xc1);
1875*4882a593Smuzhiyun
1876*4882a593Smuzhiyun stv0900_set_symbol_rate(intp, intp->mclk,
1877*4882a593Smuzhiyun intp->symbol_rate[demod], demod);
1878*4882a593Smuzhiyun stv0900_set_max_symbol_rate(intp, intp->mclk,
1879*4882a593Smuzhiyun intp->symbol_rate[demod], demod);
1880*4882a593Smuzhiyun stv0900_set_min_symbol_rate(intp, intp->mclk,
1881*4882a593Smuzhiyun intp->symbol_rate[demod], demod);
1882*4882a593Smuzhiyun if (intp->symbol_rate[demod] >= 10000000)
1883*4882a593Smuzhiyun low_sr = FALSE;
1884*4882a593Smuzhiyun else
1885*4882a593Smuzhiyun low_sr = TRUE;
1886*4882a593Smuzhiyun
1887*4882a593Smuzhiyun }
1888*4882a593Smuzhiyun
1889*4882a593Smuzhiyun if (intp->tuner_type[demod] == 3)
1890*4882a593Smuzhiyun stv0900_set_tuner_auto(intp, intp->freq[demod],
1891*4882a593Smuzhiyun intp->bw[demod], demod);
1892*4882a593Smuzhiyun else
1893*4882a593Smuzhiyun stv0900_set_tuner(fe, intp->freq[demod], intp->bw[demod]);
1894*4882a593Smuzhiyun
1895*4882a593Smuzhiyun agc1_power = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1),
1896*4882a593Smuzhiyun stv0900_get_bits(intp, AGCIQ_VALUE0));
1897*4882a593Smuzhiyun
1898*4882a593Smuzhiyun aq_power = 0;
1899*4882a593Smuzhiyun
1900*4882a593Smuzhiyun if (agc1_power == 0) {
1901*4882a593Smuzhiyun for (i = 0; i < 5; i++)
1902*4882a593Smuzhiyun aq_power += (stv0900_get_bits(intp, POWER_I) +
1903*4882a593Smuzhiyun stv0900_get_bits(intp, POWER_Q)) / 2;
1904*4882a593Smuzhiyun
1905*4882a593Smuzhiyun aq_power /= 5;
1906*4882a593Smuzhiyun }
1907*4882a593Smuzhiyun
1908*4882a593Smuzhiyun if ((agc1_power == 0) && (aq_power < IQPOWER_THRESHOLD)) {
1909*4882a593Smuzhiyun intp->result[demod].locked = FALSE;
1910*4882a593Smuzhiyun signal_type = STV0900_NOAGC1;
1911*4882a593Smuzhiyun dprintk("%s: NO AGC1, POWERI, POWERQ\n", __func__);
1912*4882a593Smuzhiyun } else {
1913*4882a593Smuzhiyun stv0900_write_bits(intp, SPECINV_CONTROL,
1914*4882a593Smuzhiyun intp->srch_iq_inv[demod]);
1915*4882a593Smuzhiyun if (intp->chip_id <= 0x20) /*cut 2.0*/
1916*4882a593Smuzhiyun stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
1917*4882a593Smuzhiyun else /*cut 3.0*/
1918*4882a593Smuzhiyun stv0900_write_bits(intp, MANUALS2_ROLLOFF, 1);
1919*4882a593Smuzhiyun
1920*4882a593Smuzhiyun stv0900_set_search_standard(intp, demod);
1921*4882a593Smuzhiyun
1922*4882a593Smuzhiyun if (intp->srch_algo[demod] != STV0900_BLIND_SEARCH)
1923*4882a593Smuzhiyun stv0900_start_search(intp, demod);
1924*4882a593Smuzhiyun }
1925*4882a593Smuzhiyun
1926*4882a593Smuzhiyun if (signal_type == STV0900_NOAGC1)
1927*4882a593Smuzhiyun return signal_type;
1928*4882a593Smuzhiyun
1929*4882a593Smuzhiyun if (intp->chip_id == 0x12) {
1930*4882a593Smuzhiyun stv0900_write_bits(intp, RST_HWARE, 0);
1931*4882a593Smuzhiyun msleep(3);
1932*4882a593Smuzhiyun stv0900_write_bits(intp, RST_HWARE, 1);
1933*4882a593Smuzhiyun stv0900_write_bits(intp, RST_HWARE, 0);
1934*4882a593Smuzhiyun }
1935*4882a593Smuzhiyun
1936*4882a593Smuzhiyun if (algo == STV0900_BLIND_SEARCH)
1937*4882a593Smuzhiyun lock = stv0900_blind_search_algo(fe);
1938*4882a593Smuzhiyun else if (algo == STV0900_COLD_START)
1939*4882a593Smuzhiyun lock = stv0900_get_demod_cold_lock(fe, demod_timeout);
1940*4882a593Smuzhiyun else if (algo == STV0900_WARM_START)
1941*4882a593Smuzhiyun lock = stv0900_get_demod_lock(intp, demod, demod_timeout);
1942*4882a593Smuzhiyun
1943*4882a593Smuzhiyun if ((lock == FALSE) && (algo == STV0900_COLD_START)) {
1944*4882a593Smuzhiyun if (low_sr == FALSE) {
1945*4882a593Smuzhiyun if (stv0900_check_timing_lock(intp, demod) == TRUE)
1946*4882a593Smuzhiyun lock = stv0900_sw_algo(intp, demod);
1947*4882a593Smuzhiyun }
1948*4882a593Smuzhiyun }
1949*4882a593Smuzhiyun
1950*4882a593Smuzhiyun if (lock == TRUE)
1951*4882a593Smuzhiyun signal_type = stv0900_get_signal_params(fe);
1952*4882a593Smuzhiyun
1953*4882a593Smuzhiyun if ((lock == TRUE) && (signal_type == STV0900_RANGEOK)) {
1954*4882a593Smuzhiyun stv0900_track_optimization(fe);
1955*4882a593Smuzhiyun if (intp->chip_id <= 0x11) {
1956*4882a593Smuzhiyun if ((stv0900_get_standard(fe, 0) ==
1957*4882a593Smuzhiyun STV0900_DVBS1_STANDARD) &&
1958*4882a593Smuzhiyun (stv0900_get_standard(fe, 1) ==
1959*4882a593Smuzhiyun STV0900_DVBS1_STANDARD)) {
1960*4882a593Smuzhiyun msleep(20);
1961*4882a593Smuzhiyun stv0900_write_bits(intp, RST_HWARE, 0);
1962*4882a593Smuzhiyun } else {
1963*4882a593Smuzhiyun stv0900_write_bits(intp, RST_HWARE, 0);
1964*4882a593Smuzhiyun msleep(3);
1965*4882a593Smuzhiyun stv0900_write_bits(intp, RST_HWARE, 1);
1966*4882a593Smuzhiyun stv0900_write_bits(intp, RST_HWARE, 0);
1967*4882a593Smuzhiyun }
1968*4882a593Smuzhiyun
1969*4882a593Smuzhiyun } else if (intp->chip_id >= 0x20) {
1970*4882a593Smuzhiyun stv0900_write_bits(intp, RST_HWARE, 0);
1971*4882a593Smuzhiyun msleep(3);
1972*4882a593Smuzhiyun stv0900_write_bits(intp, RST_HWARE, 1);
1973*4882a593Smuzhiyun stv0900_write_bits(intp, RST_HWARE, 0);
1974*4882a593Smuzhiyun }
1975*4882a593Smuzhiyun
1976*4882a593Smuzhiyun if (stv0900_wait_for_lock(intp, demod,
1977*4882a593Smuzhiyun fec_timeout, fec_timeout) == TRUE) {
1978*4882a593Smuzhiyun lock = TRUE;
1979*4882a593Smuzhiyun intp->result[demod].locked = TRUE;
1980*4882a593Smuzhiyun if (intp->result[demod].standard ==
1981*4882a593Smuzhiyun STV0900_DVBS2_STANDARD) {
1982*4882a593Smuzhiyun stv0900_set_dvbs2_rolloff(intp, demod);
1983*4882a593Smuzhiyun stv0900_write_bits(intp, RESET_UPKO_COUNT, 1);
1984*4882a593Smuzhiyun stv0900_write_bits(intp, RESET_UPKO_COUNT, 0);
1985*4882a593Smuzhiyun stv0900_write_reg(intp, ERRCTRL1, 0x67);
1986*4882a593Smuzhiyun } else {
1987*4882a593Smuzhiyun stv0900_write_reg(intp, ERRCTRL1, 0x75);
1988*4882a593Smuzhiyun }
1989*4882a593Smuzhiyun
1990*4882a593Smuzhiyun stv0900_write_reg(intp, FBERCPT4, 0);
1991*4882a593Smuzhiyun stv0900_write_reg(intp, ERRCTRL2, 0xc1);
1992*4882a593Smuzhiyun } else {
1993*4882a593Smuzhiyun lock = FALSE;
1994*4882a593Smuzhiyun signal_type = STV0900_NODATA;
1995*4882a593Smuzhiyun no_signal = stv0900_check_signal_presence(intp, demod);
1996*4882a593Smuzhiyun
1997*4882a593Smuzhiyun intp->result[demod].locked = FALSE;
1998*4882a593Smuzhiyun }
1999*4882a593Smuzhiyun }
2000*4882a593Smuzhiyun
2001*4882a593Smuzhiyun if ((signal_type != STV0900_NODATA) || (no_signal != FALSE))
2002*4882a593Smuzhiyun return signal_type;
2003*4882a593Smuzhiyun
2004*4882a593Smuzhiyun if (intp->chip_id > 0x11) {
2005*4882a593Smuzhiyun intp->result[demod].locked = FALSE;
2006*4882a593Smuzhiyun return signal_type;
2007*4882a593Smuzhiyun }
2008*4882a593Smuzhiyun
2009*4882a593Smuzhiyun if ((stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) &&
2010*4882a593Smuzhiyun (intp->srch_iq_inv[demod] <= STV0900_IQ_AUTO_NORMAL_FIRST))
2011*4882a593Smuzhiyun signal_type = stv0900_dvbs1_acq_workaround(fe);
2012*4882a593Smuzhiyun
2013*4882a593Smuzhiyun return signal_type;
2014*4882a593Smuzhiyun }
2015*4882a593Smuzhiyun
2016