1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * stv0367.c |
4 | * |
5 | * Driver for ST STV0367 DVB-T & DVB-C demodulator IC. |
6 | * |
7 | * Copyright (C) ST Microelectronics. |
8 | * Copyright (C) 2010,2011 NetUP Inc. |
9 | * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru> |
10 | */ |
11 | |
12 | #include <linux/kernel.h> |
13 | #include <linux/module.h> |
14 | #include <linux/string.h> |
15 | #include <linux/slab.h> |
16 | #include <linux/i2c.h> |
17 | |
18 | #include <linux/int_log.h> |
19 | |
20 | #include "stv0367.h" |
21 | #include "stv0367_defs.h" |
22 | #include "stv0367_regs.h" |
23 | #include "stv0367_priv.h" |
24 | |
25 | /* Max transfer size done by I2C transfer functions */ |
26 | #define MAX_XFER_SIZE 64 |
27 | |
28 | static int stvdebug; |
29 | module_param_named(debug, stvdebug, int, 0644); |
30 | |
31 | static int i2cdebug; |
32 | module_param_named(i2c_debug, i2cdebug, int, 0644); |
33 | |
34 | #define dprintk(args...) \ |
35 | do { \ |
36 | if (stvdebug) \ |
37 | printk(KERN_DEBUG args); \ |
38 | } while (0) |
39 | /* DVB-C */ |
40 | |
41 | enum active_demod_state { demod_none, demod_ter, demod_cab }; |
42 | |
43 | struct stv0367cab_state { |
44 | enum stv0367_cab_signal_type state; |
45 | u32 mclk; |
46 | u32 adc_clk; |
47 | s32 search_range; |
48 | s32 derot_offset; |
49 | /* results */ |
50 | int locked; /* channel found */ |
51 | u32 freq_khz; /* found frequency (in kHz) */ |
52 | u32 symbol_rate; /* found symbol rate (in Bds) */ |
53 | enum fe_spectral_inversion spect_inv; /* Spectrum Inversion */ |
54 | u32 qamfec_status_reg; /* status reg to poll for FEC Lock */ |
55 | }; |
56 | |
57 | struct stv0367ter_state { |
58 | /* DVB-T */ |
59 | enum stv0367_ter_signal_type state; |
60 | enum stv0367_ter_if_iq_mode if_iq_mode; |
61 | enum stv0367_ter_mode mode;/* mode 2K or 8K */ |
62 | enum fe_guard_interval guard; |
63 | enum stv0367_ter_hierarchy hierarchy; |
64 | u32 frequency; |
65 | enum fe_spectral_inversion sense; /* current search spectrum */ |
66 | u8 force; /* force mode/guard */ |
67 | u8 bw; /* channel width 6, 7 or 8 in MHz */ |
68 | u8 pBW; /* channel width used during previous lock */ |
69 | u32 pBER; |
70 | u32 pPER; |
71 | u32 ucblocks; |
72 | s8 echo_pos; /* echo position */ |
73 | u8 first_lock; |
74 | u8 unlock_counter; |
75 | u32 agc_val; |
76 | }; |
77 | |
78 | struct stv0367_state { |
79 | struct dvb_frontend fe; |
80 | struct i2c_adapter *i2c; |
81 | /* config settings */ |
82 | const struct stv0367_config *config; |
83 | u8 chip_id; |
84 | /* DVB-C */ |
85 | struct stv0367cab_state *cab_state; |
86 | /* DVB-T */ |
87 | struct stv0367ter_state *ter_state; |
88 | /* flags for operation control */ |
89 | u8 use_i2c_gatectrl; |
90 | u8 deftabs; |
91 | u8 reinit_on_setfrontend; |
92 | u8 auto_if_khz; |
93 | enum active_demod_state activedemod; |
94 | }; |
95 | |
96 | #define RF_LOOKUP_TABLE_SIZE 31 |
97 | #define RF_LOOKUP_TABLE2_SIZE 16 |
98 | /* RF Level (for RF AGC->AGC1) Lookup Table, depends on the board and tuner.*/ |
99 | static const s32 stv0367cab_RF_LookUp1[RF_LOOKUP_TABLE_SIZE][RF_LOOKUP_TABLE_SIZE] = { |
100 | {/*AGC1*/ |
101 | 48, 50, 51, 53, 54, 56, 57, 58, 60, 61, 62, 63, |
102 | 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, |
103 | 76, 77, 78, 80, 83, 85, 88, |
104 | }, {/*RF(dbm)*/ |
105 | 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, |
106 | 34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 46, 47, |
107 | 49, 50, 52, 53, 54, 55, 56, |
108 | } |
109 | }; |
110 | /* RF Level (for IF AGC->AGC2) Lookup Table, depends on the board and tuner.*/ |
111 | static const s32 stv0367cab_RF_LookUp2[RF_LOOKUP_TABLE2_SIZE][RF_LOOKUP_TABLE2_SIZE] = { |
112 | {/*AGC2*/ |
113 | 28, 29, 31, 32, 34, 35, 36, 37, |
114 | 38, 39, 40, 41, 42, 43, 44, 45, |
115 | }, {/*RF(dbm)*/ |
116 | 57, 58, 59, 60, 61, 62, 63, 64, |
117 | 65, 66, 67, 68, 69, 70, 71, 72, |
118 | } |
119 | }; |
120 | |
121 | static noinline_for_stack |
122 | int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data) |
123 | { |
124 | u8 buf[3] = { MSB(reg), LSB(reg), data }; |
125 | struct i2c_msg msg = { |
126 | .addr = state->config->demod_address, |
127 | .flags = 0, |
128 | .buf = buf, |
129 | .len = 3, |
130 | }; |
131 | int ret; |
132 | |
133 | if (i2cdebug) |
134 | printk(KERN_DEBUG "%s: [%02x] %02x: %02x\n" , __func__, |
135 | state->config->demod_address, reg, data); |
136 | |
137 | ret = i2c_transfer(adap: state->i2c, msgs: &msg, num: 1); |
138 | if (ret != 1) |
139 | printk(KERN_ERR "%s: i2c write error! ([%02x] %02x: %02x)\n" , |
140 | __func__, state->config->demod_address, reg, data); |
141 | |
142 | return (ret != 1) ? -EREMOTEIO : 0; |
143 | } |
144 | |
145 | static noinline_for_stack |
146 | u8 stv0367_readreg(struct stv0367_state *state, u16 reg) |
147 | { |
148 | u8 b0[] = { 0, 0 }; |
149 | u8 b1[] = { 0 }; |
150 | struct i2c_msg msg[] = { |
151 | { |
152 | .addr = state->config->demod_address, |
153 | .flags = 0, |
154 | .buf = b0, |
155 | .len = 2 |
156 | }, { |
157 | .addr = state->config->demod_address, |
158 | .flags = I2C_M_RD, |
159 | .buf = b1, |
160 | .len = 1 |
161 | } |
162 | }; |
163 | int ret; |
164 | |
165 | b0[0] = MSB(reg); |
166 | b0[1] = LSB(reg); |
167 | |
168 | ret = i2c_transfer(adap: state->i2c, msgs: msg, num: 2); |
169 | if (ret != 2) |
170 | printk(KERN_ERR "%s: i2c read error ([%02x] %02x: %02x)\n" , |
171 | __func__, state->config->demod_address, reg, b1[0]); |
172 | |
173 | if (i2cdebug) |
174 | printk(KERN_DEBUG "%s: [%02x] %02x: %02x\n" , __func__, |
175 | state->config->demod_address, reg, b1[0]); |
176 | |
177 | return b1[0]; |
178 | } |
179 | |
180 | static void (u32 label, u8 *mask, u8 *pos) |
181 | { |
182 | u8 position = 0, i = 0; |
183 | |
184 | (*mask) = label & 0xff; |
185 | |
186 | while ((position == 0) && (i < 8)) { |
187 | position = ((*mask) >> i) & 0x01; |
188 | i++; |
189 | } |
190 | |
191 | (*pos) = (i - 1); |
192 | } |
193 | |
194 | static void stv0367_writebits(struct stv0367_state *state, u32 label, u8 val) |
195 | { |
196 | u8 reg, mask, pos; |
197 | |
198 | reg = stv0367_readreg(state, reg: (label >> 16) & 0xffff); |
199 | extract_mask_pos(label, mask: &mask, pos: &pos); |
200 | |
201 | val = mask & (val << pos); |
202 | |
203 | reg = (reg & (~mask)) | val; |
204 | stv0367_writereg(state, reg: (label >> 16) & 0xffff, data: reg); |
205 | |
206 | } |
207 | |
208 | static void stv0367_setbits(u8 *reg, u32 label, u8 val) |
209 | { |
210 | u8 mask, pos; |
211 | |
212 | extract_mask_pos(label, mask: &mask, pos: &pos); |
213 | |
214 | val = mask & (val << pos); |
215 | |
216 | (*reg) = ((*reg) & (~mask)) | val; |
217 | } |
218 | |
219 | static u8 stv0367_readbits(struct stv0367_state *state, u32 label) |
220 | { |
221 | u8 val = 0xff; |
222 | u8 mask, pos; |
223 | |
224 | extract_mask_pos(label, mask: &mask, pos: &pos); |
225 | |
226 | val = stv0367_readreg(state, reg: label >> 16); |
227 | val = (val & mask) >> pos; |
228 | |
229 | return val; |
230 | } |
231 | |
232 | #if 0 /* Currently, unused */ |
233 | static u8 stv0367_getbits(u8 reg, u32 label) |
234 | { |
235 | u8 mask, pos; |
236 | |
237 | extract_mask_pos(label, &mask, &pos); |
238 | |
239 | return (reg & mask) >> pos; |
240 | } |
241 | #endif |
242 | |
243 | static void stv0367_write_table(struct stv0367_state *state, |
244 | const struct st_register *deftab) |
245 | { |
246 | int i = 0; |
247 | |
248 | while (1) { |
249 | if (!deftab[i].addr) |
250 | break; |
251 | stv0367_writereg(state, reg: deftab[i].addr, data: deftab[i].value); |
252 | i++; |
253 | } |
254 | } |
255 | |
256 | static void stv0367_pll_setup(struct stv0367_state *state, |
257 | u32 icspeed, u32 xtal) |
258 | { |
259 | /* note on regs: R367TER_* and R367CAB_* defines each point to |
260 | * 0xf0d8, so just use R367TER_ for both cases |
261 | */ |
262 | |
263 | switch (icspeed) { |
264 | case STV0367_ICSPEED_58000: |
265 | switch (xtal) { |
266 | default: |
267 | case 27000000: |
268 | dprintk("STV0367 SetCLKgen for 58MHz IC and 27Mhz crystal\n" ); |
269 | /* PLLMDIV: 27, PLLNDIV: 232 */ |
270 | stv0367_writereg(state, R367TER_PLLMDIV, data: 0x1b); |
271 | stv0367_writereg(state, R367TER_PLLNDIV, data: 0xe8); |
272 | break; |
273 | } |
274 | break; |
275 | default: |
276 | case STV0367_ICSPEED_53125: |
277 | switch (xtal) { |
278 | /* set internal freq to 53.125MHz */ |
279 | case 16000000: |
280 | stv0367_writereg(state, R367TER_PLLMDIV, data: 0x2); |
281 | stv0367_writereg(state, R367TER_PLLNDIV, data: 0x1b); |
282 | break; |
283 | case 25000000: |
284 | stv0367_writereg(state, R367TER_PLLMDIV, data: 0xa); |
285 | stv0367_writereg(state, R367TER_PLLNDIV, data: 0x55); |
286 | break; |
287 | default: |
288 | case 27000000: |
289 | dprintk("FE_STV0367TER_SetCLKgen for 27Mhz\n" ); |
290 | stv0367_writereg(state, R367TER_PLLMDIV, data: 0x1); |
291 | stv0367_writereg(state, R367TER_PLLNDIV, data: 0x8); |
292 | break; |
293 | case 30000000: |
294 | stv0367_writereg(state, R367TER_PLLMDIV, data: 0xc); |
295 | stv0367_writereg(state, R367TER_PLLNDIV, data: 0x55); |
296 | break; |
297 | } |
298 | } |
299 | |
300 | stv0367_writereg(state, R367TER_PLLSETUP, data: 0x18); |
301 | } |
302 | |
303 | static int stv0367_get_if_khz(struct stv0367_state *state, u32 *ifkhz) |
304 | { |
305 | if (state->auto_if_khz && state->fe.ops.tuner_ops.get_if_frequency) { |
306 | state->fe.ops.tuner_ops.get_if_frequency(&state->fe, ifkhz); |
307 | *ifkhz = *ifkhz / 1000; /* hz -> khz */ |
308 | } else |
309 | *ifkhz = state->config->if_khz; |
310 | |
311 | return 0; |
312 | } |
313 | |
314 | static int stv0367ter_gate_ctrl(struct dvb_frontend *fe, int enable) |
315 | { |
316 | struct stv0367_state *state = fe->demodulator_priv; |
317 | u8 tmp = stv0367_readreg(state, R367TER_I2CRPT); |
318 | |
319 | dprintk("%s:\n" , __func__); |
320 | |
321 | if (enable) { |
322 | stv0367_setbits(reg: &tmp, F367TER_STOP_ENABLE, val: 0); |
323 | stv0367_setbits(reg: &tmp, F367TER_I2CT_ON, val: 1); |
324 | } else { |
325 | stv0367_setbits(reg: &tmp, F367TER_STOP_ENABLE, val: 1); |
326 | stv0367_setbits(reg: &tmp, F367TER_I2CT_ON, val: 0); |
327 | } |
328 | |
329 | stv0367_writereg(state, R367TER_I2CRPT, data: tmp); |
330 | |
331 | return 0; |
332 | } |
333 | |
334 | static u32 stv0367_get_tuner_freq(struct dvb_frontend *fe) |
335 | { |
336 | struct dvb_frontend_ops *frontend_ops = &fe->ops; |
337 | struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; |
338 | u32 freq = 0; |
339 | int err = 0; |
340 | |
341 | dprintk("%s:\n" , __func__); |
342 | |
343 | if (tuner_ops->get_frequency) { |
344 | err = tuner_ops->get_frequency(fe, &freq); |
345 | if (err < 0) { |
346 | printk(KERN_ERR "%s: Invalid parameter\n" , __func__); |
347 | return err; |
348 | } |
349 | |
350 | dprintk("%s: frequency=%d\n" , __func__, freq); |
351 | |
352 | } else |
353 | return -1; |
354 | |
355 | return freq; |
356 | } |
357 | |
358 | static u16 CellsCoeffs_8MHz_367cofdm[3][6][5] = { |
359 | { |
360 | {0x10EF, 0xE205, 0x10EF, 0xCE49, 0x6DA7}, /* CELL 1 COEFFS 27M*/ |
361 | {0x2151, 0xc557, 0x2151, 0xc705, 0x6f93}, /* CELL 2 COEFFS */ |
362 | {0x2503, 0xc000, 0x2503, 0xc375, 0x7194}, /* CELL 3 COEFFS */ |
363 | {0x20E9, 0xca94, 0x20e9, 0xc153, 0x7194}, /* CELL 4 COEFFS */ |
364 | {0x06EF, 0xF852, 0x06EF, 0xC057, 0x7207}, /* CELL 5 COEFFS */ |
365 | {0x0000, 0x0ECC, 0x0ECC, 0x0000, 0x3647} /* CELL 6 COEFFS */ |
366 | }, { |
367 | {0x10A0, 0xE2AF, 0x10A1, 0xCE76, 0x6D6D}, /* CELL 1 COEFFS 25M*/ |
368 | {0x20DC, 0xC676, 0x20D9, 0xC80A, 0x6F29}, |
369 | {0x2532, 0xC000, 0x251D, 0xC391, 0x706F}, |
370 | {0x1F7A, 0xCD2B, 0x2032, 0xC15E, 0x711F}, |
371 | {0x0698, 0xFA5E, 0x0568, 0xC059, 0x7193}, |
372 | {0x0000, 0x0918, 0x149C, 0x0000, 0x3642} /* CELL 6 COEFFS */ |
373 | }, { |
374 | {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */ |
375 | {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, |
376 | {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, |
377 | {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, |
378 | {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, |
379 | {0x0000, 0x0000, 0x0000, 0x0000, 0x0000} |
380 | } |
381 | }; |
382 | |
383 | static u16 CellsCoeffs_7MHz_367cofdm[3][6][5] = { |
384 | { |
385 | {0x12CA, 0xDDAF, 0x12CA, 0xCCEB, 0x6FB1}, /* CELL 1 COEFFS 27M*/ |
386 | {0x2329, 0xC000, 0x2329, 0xC6B0, 0x725F}, /* CELL 2 COEFFS */ |
387 | {0x2394, 0xC000, 0x2394, 0xC2C7, 0x7410}, /* CELL 3 COEFFS */ |
388 | {0x251C, 0xC000, 0x251C, 0xC103, 0x74D9}, /* CELL 4 COEFFS */ |
389 | {0x0804, 0xF546, 0x0804, 0xC040, 0x7544}, /* CELL 5 COEFFS */ |
390 | {0x0000, 0x0CD9, 0x0CD9, 0x0000, 0x370A} /* CELL 6 COEFFS */ |
391 | }, { |
392 | {0x1285, 0xDE47, 0x1285, 0xCD17, 0x6F76}, /*25M*/ |
393 | {0x234C, 0xC000, 0x2348, 0xC6DA, 0x7206}, |
394 | {0x23B4, 0xC000, 0x23AC, 0xC2DB, 0x73B3}, |
395 | {0x253D, 0xC000, 0x25B6, 0xC10B, 0x747F}, |
396 | {0x0721, 0xF79C, 0x065F, 0xC041, 0x74EB}, |
397 | {0x0000, 0x08FA, 0x1162, 0x0000, 0x36FF} |
398 | }, { |
399 | {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */ |
400 | {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, |
401 | {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, |
402 | {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, |
403 | {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, |
404 | {0x0000, 0x0000, 0x0000, 0x0000, 0x0000} |
405 | } |
406 | }; |
407 | |
408 | static u16 CellsCoeffs_6MHz_367cofdm[3][6][5] = { |
409 | { |
410 | {0x1699, 0xD5B8, 0x1699, 0xCBC3, 0x713B}, /* CELL 1 COEFFS 27M*/ |
411 | {0x2245, 0xC000, 0x2245, 0xC568, 0x74D5}, /* CELL 2 COEFFS */ |
412 | {0x227F, 0xC000, 0x227F, 0xC1FC, 0x76C6}, /* CELL 3 COEFFS */ |
413 | {0x235E, 0xC000, 0x235E, 0xC0A7, 0x778A}, /* CELL 4 COEFFS */ |
414 | {0x0ECB, 0xEA0B, 0x0ECB, 0xC027, 0x77DD}, /* CELL 5 COEFFS */ |
415 | {0x0000, 0x0B68, 0x0B68, 0x0000, 0xC89A}, /* CELL 6 COEFFS */ |
416 | }, { |
417 | {0x1655, 0xD64E, 0x1658, 0xCBEF, 0x70FE}, /*25M*/ |
418 | {0x225E, 0xC000, 0x2256, 0xC589, 0x7489}, |
419 | {0x2293, 0xC000, 0x2295, 0xC209, 0x767E}, |
420 | {0x2377, 0xC000, 0x23AA, 0xC0AB, 0x7746}, |
421 | {0x0DC7, 0xEBC8, 0x0D07, 0xC027, 0x7799}, |
422 | {0x0000, 0x0888, 0x0E9C, 0x0000, 0x3757} |
423 | |
424 | }, { |
425 | {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */ |
426 | {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, |
427 | {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, |
428 | {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, |
429 | {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, |
430 | {0x0000, 0x0000, 0x0000, 0x0000, 0x0000} |
431 | } |
432 | }; |
433 | |
434 | static u32 stv0367ter_get_mclk(struct stv0367_state *state, u32 ExtClk_Hz) |
435 | { |
436 | u32 mclk_Hz = 0; /* master clock frequency (Hz) */ |
437 | u32 m, n, p; |
438 | |
439 | dprintk("%s:\n" , __func__); |
440 | |
441 | if (stv0367_readbits(state, F367TER_BYPASS_PLLXN) == 0) { |
442 | n = (u32)stv0367_readbits(state, F367TER_PLL_NDIV); |
443 | if (n == 0) |
444 | n = n + 1; |
445 | |
446 | m = (u32)stv0367_readbits(state, F367TER_PLL_MDIV); |
447 | if (m == 0) |
448 | m = m + 1; |
449 | |
450 | p = (u32)stv0367_readbits(state, F367TER_PLL_PDIV); |
451 | if (p > 5) |
452 | p = 5; |
453 | |
454 | mclk_Hz = ((ExtClk_Hz / 2) * n) / (m * (1 << p)); |
455 | |
456 | dprintk("N=%d M=%d P=%d mclk_Hz=%d ExtClk_Hz=%d\n" , |
457 | n, m, p, mclk_Hz, ExtClk_Hz); |
458 | } else |
459 | mclk_Hz = ExtClk_Hz; |
460 | |
461 | dprintk("%s: mclk_Hz=%d\n" , __func__, mclk_Hz); |
462 | |
463 | return mclk_Hz; |
464 | } |
465 | |
466 | static int stv0367ter_filt_coeff_init(struct stv0367_state *state, |
467 | u16 CellsCoeffs[3][6][5], u32 DemodXtal) |
468 | { |
469 | int i, j, k, freq; |
470 | |
471 | dprintk("%s:\n" , __func__); |
472 | |
473 | freq = stv0367ter_get_mclk(state, ExtClk_Hz: DemodXtal); |
474 | |
475 | if (freq == 53125000) |
476 | k = 1; /* equivalent to Xtal 25M on 362*/ |
477 | else if (freq == 54000000) |
478 | k = 0; /* equivalent to Xtal 27M on 362*/ |
479 | else if (freq == 52500000) |
480 | k = 2; /* equivalent to Xtal 30M on 362*/ |
481 | else |
482 | return 0; |
483 | |
484 | for (i = 1; i <= 6; i++) { |
485 | stv0367_writebits(state, F367TER_IIR_CELL_NB, val: i - 1); |
486 | |
487 | for (j = 1; j <= 5; j++) { |
488 | stv0367_writereg(state, |
489 | reg: (R367TER_IIRCX_COEFF1_MSB + 2 * (j - 1)), |
490 | MSB(CellsCoeffs[k][i-1][j-1])); |
491 | stv0367_writereg(state, |
492 | reg: (R367TER_IIRCX_COEFF1_LSB + 2 * (j - 1)), |
493 | LSB(CellsCoeffs[k][i-1][j-1])); |
494 | } |
495 | } |
496 | |
497 | return 1; |
498 | |
499 | } |
500 | |
501 | static void stv0367ter_agc_iir_lock_detect_set(struct stv0367_state *state) |
502 | { |
503 | dprintk("%s:\n" , __func__); |
504 | |
505 | stv0367_writebits(state, F367TER_LOCK_DETECT_LSB, val: 0x00); |
506 | |
507 | /* Lock detect 1 */ |
508 | stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, val: 0x00); |
509 | stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, val: 0x06); |
510 | stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, val: 0x04); |
511 | |
512 | /* Lock detect 2 */ |
513 | stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, val: 0x01); |
514 | stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, val: 0x06); |
515 | stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, val: 0x04); |
516 | |
517 | /* Lock detect 3 */ |
518 | stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, val: 0x02); |
519 | stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, val: 0x01); |
520 | stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, val: 0x00); |
521 | |
522 | /* Lock detect 4 */ |
523 | stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, val: 0x03); |
524 | stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, val: 0x01); |
525 | stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, val: 0x00); |
526 | |
527 | } |
528 | |
529 | static int stv0367_iir_filt_init(struct stv0367_state *state, u8 Bandwidth, |
530 | u32 DemodXtalValue) |
531 | { |
532 | dprintk("%s:\n" , __func__); |
533 | |
534 | stv0367_writebits(state, F367TER_NRST_IIR, val: 0); |
535 | |
536 | switch (Bandwidth) { |
537 | case 6: |
538 | if (!stv0367ter_filt_coeff_init(state, |
539 | CellsCoeffs: CellsCoeffs_6MHz_367cofdm, |
540 | DemodXtal: DemodXtalValue)) |
541 | return 0; |
542 | break; |
543 | case 7: |
544 | if (!stv0367ter_filt_coeff_init(state, |
545 | CellsCoeffs: CellsCoeffs_7MHz_367cofdm, |
546 | DemodXtal: DemodXtalValue)) |
547 | return 0; |
548 | break; |
549 | case 8: |
550 | if (!stv0367ter_filt_coeff_init(state, |
551 | CellsCoeffs: CellsCoeffs_8MHz_367cofdm, |
552 | DemodXtal: DemodXtalValue)) |
553 | return 0; |
554 | break; |
555 | default: |
556 | return 0; |
557 | } |
558 | |
559 | stv0367_writebits(state, F367TER_NRST_IIR, val: 1); |
560 | |
561 | return 1; |
562 | } |
563 | |
564 | static void stv0367ter_agc_iir_rst(struct stv0367_state *state) |
565 | { |
566 | |
567 | u8 com_n; |
568 | |
569 | dprintk("%s:\n" , __func__); |
570 | |
571 | com_n = stv0367_readbits(state, F367TER_COM_N); |
572 | |
573 | stv0367_writebits(state, F367TER_COM_N, val: 0x07); |
574 | |
575 | stv0367_writebits(state, F367TER_COM_SOFT_RSTN, val: 0x00); |
576 | stv0367_writebits(state, F367TER_COM_AGC_ON, val: 0x00); |
577 | |
578 | stv0367_writebits(state, F367TER_COM_SOFT_RSTN, val: 0x01); |
579 | stv0367_writebits(state, F367TER_COM_AGC_ON, val: 0x01); |
580 | |
581 | stv0367_writebits(state, F367TER_COM_N, val: com_n); |
582 | |
583 | } |
584 | |
585 | static int stv0367ter_duration(s32 mode, int tempo1, int tempo2, int tempo3) |
586 | { |
587 | int local_tempo = 0; |
588 | switch (mode) { |
589 | case 0: |
590 | local_tempo = tempo1; |
591 | break; |
592 | case 1: |
593 | local_tempo = tempo2; |
594 | break ; |
595 | |
596 | case 2: |
597 | local_tempo = tempo3; |
598 | break; |
599 | |
600 | default: |
601 | break; |
602 | } |
603 | /* msleep(local_tempo); */ |
604 | return local_tempo; |
605 | } |
606 | |
607 | static enum |
608 | stv0367_ter_signal_type stv0367ter_check_syr(struct stv0367_state *state) |
609 | { |
610 | int wd = 100; |
611 | unsigned short int SYR_var; |
612 | s32 SYRStatus; |
613 | |
614 | dprintk("%s:\n" , __func__); |
615 | |
616 | SYR_var = stv0367_readbits(state, F367TER_SYR_LOCK); |
617 | |
618 | while ((!SYR_var) && (wd > 0)) { |
619 | usleep_range(min: 2000, max: 3000); |
620 | wd -= 2; |
621 | SYR_var = stv0367_readbits(state, F367TER_SYR_LOCK); |
622 | } |
623 | |
624 | if (!SYR_var) |
625 | SYRStatus = FE_TER_NOSYMBOL; |
626 | else |
627 | SYRStatus = FE_TER_SYMBOLOK; |
628 | |
629 | dprintk("stv0367ter_check_syr SYRStatus %s\n" , |
630 | SYR_var == 0 ? "No Symbol" : "OK" ); |
631 | |
632 | return SYRStatus; |
633 | } |
634 | |
635 | static enum |
636 | stv0367_ter_signal_type stv0367ter_check_cpamp(struct stv0367_state *state, |
637 | s32 FFTmode) |
638 | { |
639 | |
640 | s32 CPAMPvalue = 0, CPAMPStatus, CPAMPMin; |
641 | int wd = 0; |
642 | |
643 | dprintk("%s:\n" , __func__); |
644 | |
645 | switch (FFTmode) { |
646 | case 0: /*2k mode*/ |
647 | CPAMPMin = 20; |
648 | wd = 10; |
649 | break; |
650 | case 1: /*8k mode*/ |
651 | CPAMPMin = 80; |
652 | wd = 55; |
653 | break; |
654 | case 2: /*4k mode*/ |
655 | CPAMPMin = 40; |
656 | wd = 30; |
657 | break; |
658 | default: |
659 | CPAMPMin = 0xffff; /*drives to NOCPAMP */ |
660 | break; |
661 | } |
662 | |
663 | dprintk("%s: CPAMPMin=%d wd=%d\n" , __func__, CPAMPMin, wd); |
664 | |
665 | CPAMPvalue = stv0367_readbits(state, F367TER_PPM_CPAMP_DIRECT); |
666 | while ((CPAMPvalue < CPAMPMin) && (wd > 0)) { |
667 | usleep_range(min: 1000, max: 2000); |
668 | wd -= 1; |
669 | CPAMPvalue = stv0367_readbits(state, F367TER_PPM_CPAMP_DIRECT); |
670 | /*dprintk("CPAMPvalue= %d at wd=%d\n",CPAMPvalue,wd); */ |
671 | } |
672 | dprintk("******last CPAMPvalue= %d at wd=%d\n" , CPAMPvalue, wd); |
673 | if (CPAMPvalue < CPAMPMin) { |
674 | CPAMPStatus = FE_TER_NOCPAMP; |
675 | dprintk("%s: CPAMP failed\n" , __func__); |
676 | } else { |
677 | dprintk("%s: CPAMP OK !\n" , __func__); |
678 | CPAMPStatus = FE_TER_CPAMPOK; |
679 | } |
680 | |
681 | return CPAMPStatus; |
682 | } |
683 | |
684 | static enum stv0367_ter_signal_type |
685 | stv0367ter_lock_algo(struct stv0367_state *state) |
686 | { |
687 | enum stv0367_ter_signal_type ret_flag; |
688 | short int wd, tempo; |
689 | u8 try, u_var1 = 0, u_var2 = 0, u_var3 = 0, u_var4 = 0, mode, guard; |
690 | u8 tmp, tmp2; |
691 | |
692 | dprintk("%s:\n" , __func__); |
693 | |
694 | if (state == NULL) |
695 | return FE_TER_SWNOK; |
696 | |
697 | try = 0; |
698 | do { |
699 | ret_flag = FE_TER_LOCKOK; |
700 | |
701 | stv0367_writebits(state, F367TER_CORE_ACTIVE, val: 0); |
702 | |
703 | if (state->config->if_iq_mode != 0) |
704 | stv0367_writebits(state, F367TER_COM_N, val: 0x07); |
705 | |
706 | stv0367_writebits(state, F367TER_GUARD, val: 3);/* suggest 2k 1/4 */ |
707 | stv0367_writebits(state, F367TER_MODE, val: 0); |
708 | stv0367_writebits(state, F367TER_SYR_TR_DIS, val: 0); |
709 | usleep_range(min: 5000, max: 10000); |
710 | |
711 | stv0367_writebits(state, F367TER_CORE_ACTIVE, val: 1); |
712 | |
713 | |
714 | if (stv0367ter_check_syr(state) == FE_TER_NOSYMBOL) |
715 | return FE_TER_NOSYMBOL; |
716 | else { /* |
717 | if chip locked on wrong mode first try, |
718 | it must lock correctly second try */ |
719 | mode = stv0367_readbits(state, F367TER_SYR_MODE); |
720 | if (stv0367ter_check_cpamp(state, FFTmode: mode) == |
721 | FE_TER_NOCPAMP) { |
722 | if (try == 0) |
723 | ret_flag = FE_TER_NOCPAMP; |
724 | |
725 | } |
726 | } |
727 | |
728 | try++; |
729 | } while ((try < 10) && (ret_flag != FE_TER_LOCKOK)); |
730 | |
731 | tmp = stv0367_readreg(state, R367TER_SYR_STAT); |
732 | tmp2 = stv0367_readreg(state, R367TER_STATUS); |
733 | dprintk("state=%p\n" , state); |
734 | dprintk("LOCK OK! mode=%d SYR_STAT=0x%x R367TER_STATUS=0x%x\n" , |
735 | mode, tmp, tmp2); |
736 | |
737 | tmp = stv0367_readreg(state, R367TER_PRVIT); |
738 | tmp2 = stv0367_readreg(state, R367TER_I2CRPT); |
739 | dprintk("PRVIT=0x%x I2CRPT=0x%x\n" , tmp, tmp2); |
740 | |
741 | tmp = stv0367_readreg(state, R367TER_GAIN_SRC1); |
742 | dprintk("GAIN_SRC1=0x%x\n" , tmp); |
743 | |
744 | if ((mode != 0) && (mode != 1) && (mode != 2)) |
745 | return FE_TER_SWNOK; |
746 | |
747 | /*guard=stv0367_readbits(state,F367TER_SYR_GUARD); */ |
748 | |
749 | /*suppress EPQ auto for SYR_GARD 1/16 or 1/32 |
750 | and set channel predictor in automatic */ |
751 | #if 0 |
752 | switch (guard) { |
753 | |
754 | case 0: |
755 | case 1: |
756 | stv0367_writebits(state, F367TER_AUTO_LE_EN, 0); |
757 | stv0367_writereg(state, R367TER_CHC_CTL, 0x01); |
758 | break; |
759 | case 2: |
760 | case 3: |
761 | stv0367_writebits(state, F367TER_AUTO_LE_EN, 1); |
762 | stv0367_writereg(state, R367TER_CHC_CTL, 0x11); |
763 | break; |
764 | |
765 | default: |
766 | return FE_TER_SWNOK; |
767 | } |
768 | #endif |
769 | |
770 | /*reset fec an reedsolo FOR 367 only*/ |
771 | stv0367_writebits(state, F367TER_RST_SFEC, val: 1); |
772 | stv0367_writebits(state, F367TER_RST_REEDSOLO, val: 1); |
773 | usleep_range(min: 1000, max: 2000); |
774 | stv0367_writebits(state, F367TER_RST_SFEC, val: 0); |
775 | stv0367_writebits(state, F367TER_RST_REEDSOLO, val: 0); |
776 | |
777 | u_var1 = stv0367_readbits(state, F367TER_LK); |
778 | u_var2 = stv0367_readbits(state, F367TER_PRF); |
779 | u_var3 = stv0367_readbits(state, F367TER_TPS_LOCK); |
780 | /* u_var4=stv0367_readbits(state,F367TER_TSFIFO_LINEOK); */ |
781 | |
782 | wd = stv0367ter_duration(mode, tempo1: 125, tempo2: 500, tempo3: 250); |
783 | tempo = stv0367ter_duration(mode, tempo1: 4, tempo2: 16, tempo3: 8); |
784 | |
785 | /*while ( ((!u_var1)||(!u_var2)||(!u_var3)||(!u_var4)) && (wd>=0)) */ |
786 | while (((!u_var1) || (!u_var2) || (!u_var3)) && (wd >= 0)) { |
787 | usleep_range(min: 1000 * tempo, max: 1000 * (tempo + 1)); |
788 | wd -= tempo; |
789 | u_var1 = stv0367_readbits(state, F367TER_LK); |
790 | u_var2 = stv0367_readbits(state, F367TER_PRF); |
791 | u_var3 = stv0367_readbits(state, F367TER_TPS_LOCK); |
792 | /*u_var4=stv0367_readbits(state, F367TER_TSFIFO_LINEOK); */ |
793 | } |
794 | |
795 | if (!u_var1) |
796 | return FE_TER_NOLOCK; |
797 | |
798 | |
799 | if (!u_var2) |
800 | return FE_TER_NOPRFOUND; |
801 | |
802 | if (!u_var3) |
803 | return FE_TER_NOTPS; |
804 | |
805 | guard = stv0367_readbits(state, F367TER_SYR_GUARD); |
806 | stv0367_writereg(state, R367TER_CHC_CTL, data: 0x11); |
807 | switch (guard) { |
808 | case 0: |
809 | case 1: |
810 | stv0367_writebits(state, F367TER_AUTO_LE_EN, val: 0); |
811 | /*stv0367_writereg(state,R367TER_CHC_CTL, 0x1);*/ |
812 | stv0367_writebits(state, F367TER_SYR_FILTER, val: 0); |
813 | break; |
814 | case 2: |
815 | case 3: |
816 | stv0367_writebits(state, F367TER_AUTO_LE_EN, val: 1); |
817 | /*stv0367_writereg(state,R367TER_CHC_CTL, 0x11);*/ |
818 | stv0367_writebits(state, F367TER_SYR_FILTER, val: 1); |
819 | break; |
820 | |
821 | default: |
822 | return FE_TER_SWNOK; |
823 | } |
824 | |
825 | /* apply Sfec workaround if 8K 64QAM CR!=1/2*/ |
826 | if ((stv0367_readbits(state, F367TER_TPS_CONST) == 2) && |
827 | (mode == 1) && |
828 | (stv0367_readbits(state, F367TER_TPS_HPCODE) != 0)) { |
829 | stv0367_writereg(state, R367TER_SFDLYSETH, data: 0xc0); |
830 | stv0367_writereg(state, R367TER_SFDLYSETM, data: 0x60); |
831 | stv0367_writereg(state, R367TER_SFDLYSETL, data: 0x0); |
832 | } else |
833 | stv0367_writereg(state, R367TER_SFDLYSETH, data: 0x0); |
834 | |
835 | wd = stv0367ter_duration(mode, tempo1: 125, tempo2: 500, tempo3: 250); |
836 | u_var4 = stv0367_readbits(state, F367TER_TSFIFO_LINEOK); |
837 | |
838 | while ((!u_var4) && (wd >= 0)) { |
839 | usleep_range(min: 1000 * tempo, max: 1000 * (tempo + 1)); |
840 | wd -= tempo; |
841 | u_var4 = stv0367_readbits(state, F367TER_TSFIFO_LINEOK); |
842 | } |
843 | |
844 | if (!u_var4) |
845 | return FE_TER_NOLOCK; |
846 | |
847 | /* for 367 leave COM_N at 0x7 for IQ_mode*/ |
848 | /*if(ter_state->if_iq_mode!=FE_TER_NORMAL_IF_TUNER) { |
849 | tempo=0; |
850 | while ((stv0367_readbits(state,F367TER_COM_USEGAINTRK)!=1) && |
851 | (stv0367_readbits(state,F367TER_COM_AGCLOCK)!=1)&&(tempo<100)) { |
852 | ChipWaitOrAbort(state,1); |
853 | tempo+=1; |
854 | } |
855 | |
856 | stv0367_writebits(state,F367TER_COM_N,0x17); |
857 | } */ |
858 | |
859 | stv0367_writebits(state, F367TER_SYR_TR_DIS, val: 1); |
860 | |
861 | dprintk("FE_TER_LOCKOK !!!\n" ); |
862 | |
863 | return FE_TER_LOCKOK; |
864 | |
865 | } |
866 | |
867 | static void stv0367ter_set_ts_mode(struct stv0367_state *state, |
868 | enum stv0367_ts_mode PathTS) |
869 | { |
870 | |
871 | dprintk("%s:\n" , __func__); |
872 | |
873 | if (state == NULL) |
874 | return; |
875 | |
876 | stv0367_writebits(state, F367TER_TS_DIS, val: 0); |
877 | switch (PathTS) { |
878 | default: |
879 | /*for removing warning :default we can assume in parallel mode*/ |
880 | case STV0367_PARALLEL_PUNCT_CLOCK: |
881 | stv0367_writebits(state, F367TER_TSFIFO_SERIAL, val: 0); |
882 | stv0367_writebits(state, F367TER_TSFIFO_DVBCI, val: 0); |
883 | break; |
884 | case STV0367_SERIAL_PUNCT_CLOCK: |
885 | stv0367_writebits(state, F367TER_TSFIFO_SERIAL, val: 1); |
886 | stv0367_writebits(state, F367TER_TSFIFO_DVBCI, val: 1); |
887 | break; |
888 | } |
889 | } |
890 | |
891 | static void stv0367ter_set_clk_pol(struct stv0367_state *state, |
892 | enum stv0367_clk_pol clock) |
893 | { |
894 | |
895 | dprintk("%s:\n" , __func__); |
896 | |
897 | if (state == NULL) |
898 | return; |
899 | |
900 | switch (clock) { |
901 | case STV0367_RISINGEDGE_CLOCK: |
902 | stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, val: 1); |
903 | break; |
904 | case STV0367_FALLINGEDGE_CLOCK: |
905 | stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, val: 0); |
906 | break; |
907 | /*case FE_TER_CLOCK_POLARITY_DEFAULT:*/ |
908 | default: |
909 | stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, val: 0); |
910 | break; |
911 | } |
912 | } |
913 | |
914 | #if 0 |
915 | static void stv0367ter_core_sw(struct stv0367_state *state) |
916 | { |
917 | |
918 | dprintk("%s:\n" , __func__); |
919 | |
920 | stv0367_writebits(state, F367TER_CORE_ACTIVE, 0); |
921 | stv0367_writebits(state, F367TER_CORE_ACTIVE, 1); |
922 | msleep(350); |
923 | } |
924 | #endif |
925 | static int stv0367ter_standby(struct dvb_frontend *fe, u8 standby_on) |
926 | { |
927 | struct stv0367_state *state = fe->demodulator_priv; |
928 | |
929 | dprintk("%s:\n" , __func__); |
930 | |
931 | if (standby_on) { |
932 | stv0367_writebits(state, F367TER_STDBY, val: 1); |
933 | stv0367_writebits(state, F367TER_STDBY_FEC, val: 1); |
934 | stv0367_writebits(state, F367TER_STDBY_CORE, val: 1); |
935 | } else { |
936 | stv0367_writebits(state, F367TER_STDBY, val: 0); |
937 | stv0367_writebits(state, F367TER_STDBY_FEC, val: 0); |
938 | stv0367_writebits(state, F367TER_STDBY_CORE, val: 0); |
939 | } |
940 | |
941 | return 0; |
942 | } |
943 | |
944 | static int stv0367ter_sleep(struct dvb_frontend *fe) |
945 | { |
946 | return stv0367ter_standby(fe, standby_on: 1); |
947 | } |
948 | |
949 | static int stv0367ter_init(struct dvb_frontend *fe) |
950 | { |
951 | struct stv0367_state *state = fe->demodulator_priv; |
952 | struct stv0367ter_state *ter_state = state->ter_state; |
953 | |
954 | dprintk("%s:\n" , __func__); |
955 | |
956 | ter_state->pBER = 0; |
957 | |
958 | stv0367_write_table(state, |
959 | deftab: stv0367_deftabs[state->deftabs][STV0367_TAB_TER]); |
960 | |
961 | stv0367_pll_setup(state, STV0367_ICSPEED_53125, xtal: state->config->xtal); |
962 | |
963 | stv0367_writereg(state, R367TER_I2CRPT, data: 0xa0); |
964 | stv0367_writereg(state, R367TER_ANACTRL, data: 0x00); |
965 | |
966 | /*Set TS1 and TS2 to serial or parallel mode */ |
967 | stv0367ter_set_ts_mode(state, PathTS: state->config->ts_mode); |
968 | stv0367ter_set_clk_pol(state, clock: state->config->clk_pol); |
969 | |
970 | state->chip_id = stv0367_readreg(state, R367TER_ID); |
971 | ter_state->first_lock = 0; |
972 | ter_state->unlock_counter = 2; |
973 | |
974 | return 0; |
975 | } |
976 | |
977 | static int stv0367ter_algo(struct dvb_frontend *fe) |
978 | { |
979 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; |
980 | struct stv0367_state *state = fe->demodulator_priv; |
981 | struct stv0367ter_state *ter_state = state->ter_state; |
982 | int offset = 0, tempo = 0; |
983 | u8 u_var; |
984 | u8 /*constell,*/ counter; |
985 | s8 step; |
986 | s32 timing_offset = 0; |
987 | u32 trl_nomrate = 0, InternalFreq = 0, temp = 0, ifkhz = 0; |
988 | |
989 | dprintk("%s:\n" , __func__); |
990 | |
991 | stv0367_get_if_khz(state, ifkhz: &ifkhz); |
992 | |
993 | ter_state->frequency = p->frequency; |
994 | ter_state->force = FE_TER_FORCENONE |
995 | + stv0367_readbits(state, F367TER_FORCE) * 2; |
996 | ter_state->if_iq_mode = state->config->if_iq_mode; |
997 | switch (state->config->if_iq_mode) { |
998 | case FE_TER_NORMAL_IF_TUNER: /* Normal IF mode */ |
999 | dprintk("ALGO: FE_TER_NORMAL_IF_TUNER selected\n" ); |
1000 | stv0367_writebits(state, F367TER_TUNER_BB, val: 0); |
1001 | stv0367_writebits(state, F367TER_LONGPATH_IF, val: 0); |
1002 | stv0367_writebits(state, F367TER_DEMUX_SWAP, val: 0); |
1003 | break; |
1004 | case FE_TER_LONGPATH_IF_TUNER: /* Long IF mode */ |
1005 | dprintk("ALGO: FE_TER_LONGPATH_IF_TUNER selected\n" ); |
1006 | stv0367_writebits(state, F367TER_TUNER_BB, val: 0); |
1007 | stv0367_writebits(state, F367TER_LONGPATH_IF, val: 1); |
1008 | stv0367_writebits(state, F367TER_DEMUX_SWAP, val: 1); |
1009 | break; |
1010 | case FE_TER_IQ_TUNER: /* IQ mode */ |
1011 | dprintk("ALGO: FE_TER_IQ_TUNER selected\n" ); |
1012 | stv0367_writebits(state, F367TER_TUNER_BB, val: 1); |
1013 | stv0367_writebits(state, F367TER_PPM_INVSEL, val: 0); |
1014 | break; |
1015 | default: |
1016 | printk(KERN_ERR "ALGO: wrong TUNER type selected\n" ); |
1017 | return -EINVAL; |
1018 | } |
1019 | |
1020 | usleep_range(min: 5000, max: 7000); |
1021 | |
1022 | switch (p->inversion) { |
1023 | case INVERSION_AUTO: |
1024 | default: |
1025 | dprintk("%s: inversion AUTO\n" , __func__); |
1026 | if (ter_state->if_iq_mode == FE_TER_IQ_TUNER) |
1027 | stv0367_writebits(state, F367TER_IQ_INVERT, |
1028 | val: ter_state->sense); |
1029 | else |
1030 | stv0367_writebits(state, F367TER_INV_SPECTR, |
1031 | val: ter_state->sense); |
1032 | |
1033 | break; |
1034 | case INVERSION_ON: |
1035 | case INVERSION_OFF: |
1036 | if (ter_state->if_iq_mode == FE_TER_IQ_TUNER) |
1037 | stv0367_writebits(state, F367TER_IQ_INVERT, |
1038 | val: p->inversion); |
1039 | else |
1040 | stv0367_writebits(state, F367TER_INV_SPECTR, |
1041 | val: p->inversion); |
1042 | |
1043 | break; |
1044 | } |
1045 | |
1046 | if ((ter_state->if_iq_mode != FE_TER_NORMAL_IF_TUNER) && |
1047 | (ter_state->pBW != ter_state->bw)) { |
1048 | stv0367ter_agc_iir_lock_detect_set(state); |
1049 | |
1050 | /*set fine agc target to 180 for LPIF or IQ mode*/ |
1051 | /* set Q_AGCTarget */ |
1052 | stv0367_writebits(state, F367TER_SEL_IQNTAR, val: 1); |
1053 | stv0367_writebits(state, F367TER_AUT_AGC_TARGET_MSB, val: 0xB); |
1054 | /*stv0367_writebits(state,AUT_AGC_TARGET_LSB,0x04); */ |
1055 | |
1056 | /* set Q_AGCTarget */ |
1057 | stv0367_writebits(state, F367TER_SEL_IQNTAR, val: 0); |
1058 | stv0367_writebits(state, F367TER_AUT_AGC_TARGET_MSB, val: 0xB); |
1059 | /*stv0367_writebits(state,AUT_AGC_TARGET_LSB,0x04); */ |
1060 | |
1061 | if (!stv0367_iir_filt_init(state, Bandwidth: ter_state->bw, |
1062 | DemodXtalValue: state->config->xtal)) |
1063 | return -EINVAL; |
1064 | /*set IIR filter once for 6,7 or 8MHz BW*/ |
1065 | ter_state->pBW = ter_state->bw; |
1066 | |
1067 | stv0367ter_agc_iir_rst(state); |
1068 | } |
1069 | |
1070 | if (ter_state->hierarchy == FE_TER_HIER_LOW_PRIO) |
1071 | stv0367_writebits(state, F367TER_BDI_LPSEL, val: 0x01); |
1072 | else |
1073 | stv0367_writebits(state, F367TER_BDI_LPSEL, val: 0x00); |
1074 | |
1075 | InternalFreq = stv0367ter_get_mclk(state, ExtClk_Hz: state->config->xtal) / 1000; |
1076 | temp = (int) |
1077 | ((((ter_state->bw * 64 * (1 << 15) * 100) |
1078 | / (InternalFreq)) * 10) / 7); |
1079 | |
1080 | stv0367_writebits(state, F367TER_TRL_NOMRATE_LSB, val: temp % 2); |
1081 | temp = temp / 2; |
1082 | stv0367_writebits(state, F367TER_TRL_NOMRATE_HI, val: temp / 256); |
1083 | stv0367_writebits(state, F367TER_TRL_NOMRATE_LO, val: temp % 256); |
1084 | |
1085 | temp = stv0367_readbits(state, F367TER_TRL_NOMRATE_HI) * 512 + |
1086 | stv0367_readbits(state, F367TER_TRL_NOMRATE_LO) * 2 + |
1087 | stv0367_readbits(state, F367TER_TRL_NOMRATE_LSB); |
1088 | temp = (int)(((1 << 17) * ter_state->bw * 1000) / (7 * (InternalFreq))); |
1089 | stv0367_writebits(state, F367TER_GAIN_SRC_HI, val: temp / 256); |
1090 | stv0367_writebits(state, F367TER_GAIN_SRC_LO, val: temp % 256); |
1091 | temp = stv0367_readbits(state, F367TER_GAIN_SRC_HI) * 256 + |
1092 | stv0367_readbits(state, F367TER_GAIN_SRC_LO); |
1093 | |
1094 | temp = (int) |
1095 | ((InternalFreq - ifkhz) * (1 << 16) / (InternalFreq)); |
1096 | |
1097 | dprintk("DEROT temp=0x%x\n" , temp); |
1098 | stv0367_writebits(state, F367TER_INC_DEROT_HI, val: temp / 256); |
1099 | stv0367_writebits(state, F367TER_INC_DEROT_LO, val: temp % 256); |
1100 | |
1101 | ter_state->echo_pos = 0; |
1102 | ter_state->ucblocks = 0; /* liplianin */ |
1103 | ter_state->pBER = 0; /* liplianin */ |
1104 | stv0367_writebits(state, F367TER_LONG_ECHO, val: ter_state->echo_pos); |
1105 | |
1106 | if (stv0367ter_lock_algo(state) != FE_TER_LOCKOK) |
1107 | return 0; |
1108 | |
1109 | ter_state->state = FE_TER_LOCKOK; |
1110 | |
1111 | ter_state->mode = stv0367_readbits(state, F367TER_SYR_MODE); |
1112 | ter_state->guard = stv0367_readbits(state, F367TER_SYR_GUARD); |
1113 | |
1114 | ter_state->first_lock = 1; /* we know sense now :) */ |
1115 | |
1116 | ter_state->agc_val = |
1117 | (stv0367_readbits(state, F367TER_AGC1_VAL_LO) << 16) + |
1118 | (stv0367_readbits(state, F367TER_AGC1_VAL_HI) << 24) + |
1119 | stv0367_readbits(state, F367TER_AGC2_VAL_LO) + |
1120 | (stv0367_readbits(state, F367TER_AGC2_VAL_HI) << 8); |
1121 | |
1122 | /* Carrier offset calculation */ |
1123 | stv0367_writebits(state, F367TER_FREEZE, val: 1); |
1124 | offset = (stv0367_readbits(state, F367TER_CRL_FOFFSET_VHI) << 16) ; |
1125 | offset += (stv0367_readbits(state, F367TER_CRL_FOFFSET_HI) << 8); |
1126 | offset += (stv0367_readbits(state, F367TER_CRL_FOFFSET_LO)); |
1127 | stv0367_writebits(state, F367TER_FREEZE, val: 0); |
1128 | if (offset > 8388607) |
1129 | offset -= 16777216; |
1130 | |
1131 | offset = offset * 2 / 16384; |
1132 | |
1133 | if (ter_state->mode == FE_TER_MODE_2K) |
1134 | offset = (offset * 4464) / 1000;/*** 1 FFT BIN=4.464khz***/ |
1135 | else if (ter_state->mode == FE_TER_MODE_4K) |
1136 | offset = (offset * 223) / 100;/*** 1 FFT BIN=2.23khz***/ |
1137 | else if (ter_state->mode == FE_TER_MODE_8K) |
1138 | offset = (offset * 111) / 100;/*** 1 FFT BIN=1.1khz***/ |
1139 | |
1140 | if (stv0367_readbits(state, F367TER_PPM_INVSEL) == 1) { |
1141 | if ((stv0367_readbits(state, F367TER_INV_SPECTR) == |
1142 | (stv0367_readbits(state, |
1143 | F367TER_STATUS_INV_SPECRUM) == 1))) |
1144 | offset = offset * -1; |
1145 | } |
1146 | |
1147 | if (ter_state->bw == 6) |
1148 | offset = (offset * 6) / 8; |
1149 | else if (ter_state->bw == 7) |
1150 | offset = (offset * 7) / 8; |
1151 | |
1152 | ter_state->frequency += offset; |
1153 | |
1154 | tempo = 10; /* exit even if timing_offset stays null */ |
1155 | while ((timing_offset == 0) && (tempo > 0)) { |
1156 | usleep_range(min: 10000, max: 20000); /*was 20ms */ |
1157 | /* fine tuning of timing offset if required */ |
1158 | timing_offset = stv0367_readbits(state, F367TER_TRL_TOFFSET_LO) |
1159 | + 256 * stv0367_readbits(state, |
1160 | F367TER_TRL_TOFFSET_HI); |
1161 | if (timing_offset >= 32768) |
1162 | timing_offset -= 65536; |
1163 | trl_nomrate = (512 * stv0367_readbits(state, |
1164 | F367TER_TRL_NOMRATE_HI) |
1165 | + stv0367_readbits(state, F367TER_TRL_NOMRATE_LO) * 2 |
1166 | + stv0367_readbits(state, F367TER_TRL_NOMRATE_LSB)); |
1167 | |
1168 | timing_offset = ((signed)(1000000 / trl_nomrate) * |
1169 | timing_offset) / 2048; |
1170 | tempo--; |
1171 | } |
1172 | |
1173 | if (timing_offset <= 0) { |
1174 | timing_offset = (timing_offset - 11) / 22; |
1175 | step = -1; |
1176 | } else { |
1177 | timing_offset = (timing_offset + 11) / 22; |
1178 | step = 1; |
1179 | } |
1180 | |
1181 | for (counter = 0; counter < abs(timing_offset); counter++) { |
1182 | trl_nomrate += step; |
1183 | stv0367_writebits(state, F367TER_TRL_NOMRATE_LSB, |
1184 | val: trl_nomrate % 2); |
1185 | stv0367_writebits(state, F367TER_TRL_NOMRATE_LO, |
1186 | val: trl_nomrate / 2); |
1187 | usleep_range(min: 1000, max: 2000); |
1188 | } |
1189 | |
1190 | usleep_range(min: 5000, max: 6000); |
1191 | /* unlocks could happen in case of trl centring big step, |
1192 | then a core off/on restarts demod */ |
1193 | u_var = stv0367_readbits(state, F367TER_LK); |
1194 | |
1195 | if (!u_var) { |
1196 | stv0367_writebits(state, F367TER_CORE_ACTIVE, val: 0); |
1197 | msleep(msecs: 20); |
1198 | stv0367_writebits(state, F367TER_CORE_ACTIVE, val: 1); |
1199 | } |
1200 | |
1201 | return 0; |
1202 | } |
1203 | |
1204 | static int stv0367ter_set_frontend(struct dvb_frontend *fe) |
1205 | { |
1206 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; |
1207 | struct stv0367_state *state = fe->demodulator_priv; |
1208 | struct stv0367ter_state *ter_state = state->ter_state; |
1209 | |
1210 | /*u8 trials[2]; */ |
1211 | s8 num_trials, index; |
1212 | u8 SenseTrials[] = { INVERSION_ON, INVERSION_OFF }; |
1213 | |
1214 | if (state->reinit_on_setfrontend) |
1215 | stv0367ter_init(fe); |
1216 | |
1217 | if (fe->ops.tuner_ops.set_params) { |
1218 | if (state->use_i2c_gatectrl && fe->ops.i2c_gate_ctrl) |
1219 | fe->ops.i2c_gate_ctrl(fe, 1); |
1220 | fe->ops.tuner_ops.set_params(fe); |
1221 | if (state->use_i2c_gatectrl && fe->ops.i2c_gate_ctrl) |
1222 | fe->ops.i2c_gate_ctrl(fe, 0); |
1223 | } |
1224 | |
1225 | switch (p->transmission_mode) { |
1226 | default: |
1227 | case TRANSMISSION_MODE_AUTO: |
1228 | case TRANSMISSION_MODE_2K: |
1229 | ter_state->mode = FE_TER_MODE_2K; |
1230 | break; |
1231 | /* case TRANSMISSION_MODE_4K: |
1232 | pLook.mode = FE_TER_MODE_4K; |
1233 | break;*/ |
1234 | case TRANSMISSION_MODE_8K: |
1235 | ter_state->mode = FE_TER_MODE_8K; |
1236 | break; |
1237 | } |
1238 | |
1239 | switch (p->guard_interval) { |
1240 | default: |
1241 | case GUARD_INTERVAL_1_32: |
1242 | case GUARD_INTERVAL_1_16: |
1243 | case GUARD_INTERVAL_1_8: |
1244 | case GUARD_INTERVAL_1_4: |
1245 | ter_state->guard = p->guard_interval; |
1246 | break; |
1247 | case GUARD_INTERVAL_AUTO: |
1248 | ter_state->guard = GUARD_INTERVAL_1_32; |
1249 | break; |
1250 | } |
1251 | |
1252 | switch (p->bandwidth_hz) { |
1253 | case 6000000: |
1254 | ter_state->bw = FE_TER_CHAN_BW_6M; |
1255 | break; |
1256 | case 7000000: |
1257 | ter_state->bw = FE_TER_CHAN_BW_7M; |
1258 | break; |
1259 | case 8000000: |
1260 | default: |
1261 | ter_state->bw = FE_TER_CHAN_BW_8M; |
1262 | } |
1263 | |
1264 | ter_state->hierarchy = FE_TER_HIER_NONE; |
1265 | |
1266 | switch (p->inversion) { |
1267 | case INVERSION_OFF: |
1268 | case INVERSION_ON: |
1269 | num_trials = 1; |
1270 | break; |
1271 | default: |
1272 | num_trials = 2; |
1273 | if (ter_state->first_lock) |
1274 | num_trials = 1; |
1275 | break; |
1276 | } |
1277 | |
1278 | ter_state->state = FE_TER_NOLOCK; |
1279 | index = 0; |
1280 | |
1281 | while (((index) < num_trials) && (ter_state->state != FE_TER_LOCKOK)) { |
1282 | if (!ter_state->first_lock) { |
1283 | if (p->inversion == INVERSION_AUTO) |
1284 | ter_state->sense = SenseTrials[index]; |
1285 | |
1286 | } |
1287 | stv0367ter_algo(fe); |
1288 | |
1289 | if ((ter_state->state == FE_TER_LOCKOK) && |
1290 | (p->inversion == INVERSION_AUTO) && |
1291 | (index == 1)) { |
1292 | /* invert spectrum sense */ |
1293 | SenseTrials[index] = SenseTrials[0]; |
1294 | SenseTrials[(index + 1) % 2] = (SenseTrials[1] + 1) % 2; |
1295 | } |
1296 | |
1297 | index++; |
1298 | } |
1299 | |
1300 | return 0; |
1301 | } |
1302 | |
1303 | static int stv0367ter_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) |
1304 | { |
1305 | struct stv0367_state *state = fe->demodulator_priv; |
1306 | struct stv0367ter_state *ter_state = state->ter_state; |
1307 | u32 errs = 0; |
1308 | |
1309 | /*wait for counting completion*/ |
1310 | if (stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 0) { |
1311 | errs = |
1312 | ((u32)stv0367_readbits(state, F367TER_ERR_CNT1) |
1313 | * (1 << 16)) |
1314 | + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_HI) |
1315 | * (1 << 8)) |
1316 | + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_LO)); |
1317 | ter_state->ucblocks = errs; |
1318 | } |
1319 | |
1320 | (*ucblocks) = ter_state->ucblocks; |
1321 | |
1322 | return 0; |
1323 | } |
1324 | |
1325 | static int stv0367ter_get_frontend(struct dvb_frontend *fe, |
1326 | struct dtv_frontend_properties *p) |
1327 | { |
1328 | struct stv0367_state *state = fe->demodulator_priv; |
1329 | struct stv0367ter_state *ter_state = state->ter_state; |
1330 | enum stv0367_ter_mode mode; |
1331 | int constell = 0,/* snr = 0,*/ Data = 0; |
1332 | |
1333 | p->frequency = stv0367_get_tuner_freq(fe); |
1334 | if ((int)p->frequency < 0) |
1335 | p->frequency = -p->frequency; |
1336 | |
1337 | constell = stv0367_readbits(state, F367TER_TPS_CONST); |
1338 | if (constell == 0) |
1339 | p->modulation = QPSK; |
1340 | else if (constell == 1) |
1341 | p->modulation = QAM_16; |
1342 | else |
1343 | p->modulation = QAM_64; |
1344 | |
1345 | p->inversion = stv0367_readbits(state, F367TER_INV_SPECTR); |
1346 | |
1347 | /* Get the Hierarchical mode */ |
1348 | Data = stv0367_readbits(state, F367TER_TPS_HIERMODE); |
1349 | |
1350 | switch (Data) { |
1351 | case 0: |
1352 | p->hierarchy = HIERARCHY_NONE; |
1353 | break; |
1354 | case 1: |
1355 | p->hierarchy = HIERARCHY_1; |
1356 | break; |
1357 | case 2: |
1358 | p->hierarchy = HIERARCHY_2; |
1359 | break; |
1360 | case 3: |
1361 | p->hierarchy = HIERARCHY_4; |
1362 | break; |
1363 | default: |
1364 | p->hierarchy = HIERARCHY_AUTO; |
1365 | break; /* error */ |
1366 | } |
1367 | |
1368 | /* Get the FEC Rate */ |
1369 | if (ter_state->hierarchy == FE_TER_HIER_LOW_PRIO) |
1370 | Data = stv0367_readbits(state, F367TER_TPS_LPCODE); |
1371 | else |
1372 | Data = stv0367_readbits(state, F367TER_TPS_HPCODE); |
1373 | |
1374 | switch (Data) { |
1375 | case 0: |
1376 | p->code_rate_HP = FEC_1_2; |
1377 | break; |
1378 | case 1: |
1379 | p->code_rate_HP = FEC_2_3; |
1380 | break; |
1381 | case 2: |
1382 | p->code_rate_HP = FEC_3_4; |
1383 | break; |
1384 | case 3: |
1385 | p->code_rate_HP = FEC_5_6; |
1386 | break; |
1387 | case 4: |
1388 | p->code_rate_HP = FEC_7_8; |
1389 | break; |
1390 | default: |
1391 | p->code_rate_HP = FEC_AUTO; |
1392 | break; /* error */ |
1393 | } |
1394 | |
1395 | mode = stv0367_readbits(state, F367TER_SYR_MODE); |
1396 | |
1397 | switch (mode) { |
1398 | case FE_TER_MODE_2K: |
1399 | p->transmission_mode = TRANSMISSION_MODE_2K; |
1400 | break; |
1401 | /* case FE_TER_MODE_4K: |
1402 | p->transmission_mode = TRANSMISSION_MODE_4K; |
1403 | break;*/ |
1404 | case FE_TER_MODE_8K: |
1405 | p->transmission_mode = TRANSMISSION_MODE_8K; |
1406 | break; |
1407 | default: |
1408 | p->transmission_mode = TRANSMISSION_MODE_AUTO; |
1409 | } |
1410 | |
1411 | p->guard_interval = stv0367_readbits(state, F367TER_SYR_GUARD); |
1412 | |
1413 | return 0; |
1414 | } |
1415 | |
1416 | static u32 stv0367ter_snr_readreg(struct dvb_frontend *fe) |
1417 | { |
1418 | struct stv0367_state *state = fe->demodulator_priv; |
1419 | u32 snru32 = 0; |
1420 | int cpt = 0; |
1421 | u8 cut = stv0367_readbits(state, F367TER_IDENTIFICATIONREG); |
1422 | |
1423 | while (cpt < 10) { |
1424 | usleep_range(min: 2000, max: 3000); |
1425 | if (cut == 0x50) /*cut 1.0 cut 1.1*/ |
1426 | snru32 += stv0367_readbits(state, F367TER_CHCSNR) / 4; |
1427 | else /*cu2.0*/ |
1428 | snru32 += 125 * stv0367_readbits(state, F367TER_CHCSNR); |
1429 | |
1430 | cpt++; |
1431 | } |
1432 | snru32 /= 10;/*average on 10 values*/ |
1433 | |
1434 | return snru32; |
1435 | } |
1436 | |
1437 | static int stv0367ter_read_snr(struct dvb_frontend *fe, u16 *snr) |
1438 | { |
1439 | u32 snrval = stv0367ter_snr_readreg(fe); |
1440 | |
1441 | *snr = snrval / 1000; |
1442 | |
1443 | return 0; |
1444 | } |
1445 | |
1446 | #if 0 |
1447 | static int stv0367ter_status(struct dvb_frontend *fe) |
1448 | { |
1449 | |
1450 | struct stv0367_state *state = fe->demodulator_priv; |
1451 | struct stv0367ter_state *ter_state = state->ter_state; |
1452 | int locked = FALSE; |
1453 | |
1454 | locked = (stv0367_readbits(state, F367TER_LK)); |
1455 | if (!locked) |
1456 | ter_state->unlock_counter += 1; |
1457 | else |
1458 | ter_state->unlock_counter = 0; |
1459 | |
1460 | if (ter_state->unlock_counter > 2) { |
1461 | if (!stv0367_readbits(state, F367TER_TPS_LOCK) || |
1462 | (!stv0367_readbits(state, F367TER_LK))) { |
1463 | stv0367_writebits(state, F367TER_CORE_ACTIVE, 0); |
1464 | usleep_range(2000, 3000); |
1465 | stv0367_writebits(state, F367TER_CORE_ACTIVE, 1); |
1466 | msleep(350); |
1467 | locked = (stv0367_readbits(state, F367TER_TPS_LOCK)) && |
1468 | (stv0367_readbits(state, F367TER_LK)); |
1469 | } |
1470 | |
1471 | } |
1472 | |
1473 | return locked; |
1474 | } |
1475 | #endif |
1476 | static int stv0367ter_read_status(struct dvb_frontend *fe, |
1477 | enum fe_status *status) |
1478 | { |
1479 | struct stv0367_state *state = fe->demodulator_priv; |
1480 | |
1481 | dprintk("%s:\n" , __func__); |
1482 | |
1483 | *status = 0; |
1484 | |
1485 | if (stv0367_readbits(state, F367TER_LK)) { |
1486 | *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
1487 | | FE_HAS_SYNC | FE_HAS_LOCK; |
1488 | dprintk("%s: stv0367 has locked\n" , __func__); |
1489 | } |
1490 | |
1491 | return 0; |
1492 | } |
1493 | |
1494 | static int stv0367ter_read_ber(struct dvb_frontend *fe, u32 *ber) |
1495 | { |
1496 | struct stv0367_state *state = fe->demodulator_priv; |
1497 | struct stv0367ter_state *ter_state = state->ter_state; |
1498 | u32 Errors = 0, tber = 0, temporary = 0; |
1499 | int abc = 0, def = 0; |
1500 | |
1501 | |
1502 | /*wait for counting completion*/ |
1503 | if (stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 0) |
1504 | Errors = ((u32)stv0367_readbits(state, F367TER_SFEC_ERR_CNT) |
1505 | * (1 << 16)) |
1506 | + ((u32)stv0367_readbits(state, F367TER_SFEC_ERR_CNT_HI) |
1507 | * (1 << 8)) |
1508 | + ((u32)stv0367_readbits(state, |
1509 | F367TER_SFEC_ERR_CNT_LO)); |
1510 | /*measurement not completed, load previous value*/ |
1511 | else { |
1512 | tber = ter_state->pBER; |
1513 | return 0; |
1514 | } |
1515 | |
1516 | abc = stv0367_readbits(state, F367TER_SFEC_ERR_SOURCE); |
1517 | def = stv0367_readbits(state, F367TER_SFEC_NUM_EVENT); |
1518 | |
1519 | if (Errors == 0) { |
1520 | tber = 0; |
1521 | } else if (abc == 0x7) { |
1522 | if (Errors <= 4) { |
1523 | temporary = (Errors * 1000000000) / (8 * (1 << 14)); |
1524 | } else if (Errors <= 42) { |
1525 | temporary = (Errors * 100000000) / (8 * (1 << 14)); |
1526 | temporary = temporary * 10; |
1527 | } else if (Errors <= 429) { |
1528 | temporary = (Errors * 10000000) / (8 * (1 << 14)); |
1529 | temporary = temporary * 100; |
1530 | } else if (Errors <= 4294) { |
1531 | temporary = (Errors * 1000000) / (8 * (1 << 14)); |
1532 | temporary = temporary * 1000; |
1533 | } else if (Errors <= 42949) { |
1534 | temporary = (Errors * 100000) / (8 * (1 << 14)); |
1535 | temporary = temporary * 10000; |
1536 | } else if (Errors <= 429496) { |
1537 | temporary = (Errors * 10000) / (8 * (1 << 14)); |
1538 | temporary = temporary * 100000; |
1539 | } else { /*if (Errors<4294967) 2^22 max error*/ |
1540 | temporary = (Errors * 1000) / (8 * (1 << 14)); |
1541 | temporary = temporary * 100000; /* still to *10 */ |
1542 | } |
1543 | |
1544 | /* Byte error*/ |
1545 | if (def == 2) |
1546 | /*tber=Errors/(8*(1 <<14));*/ |
1547 | tber = temporary; |
1548 | else if (def == 3) |
1549 | /*tber=Errors/(8*(1 <<16));*/ |
1550 | tber = temporary / 4; |
1551 | else if (def == 4) |
1552 | /*tber=Errors/(8*(1 <<18));*/ |
1553 | tber = temporary / 16; |
1554 | else if (def == 5) |
1555 | /*tber=Errors/(8*(1 <<20));*/ |
1556 | tber = temporary / 64; |
1557 | else if (def == 6) |
1558 | /*tber=Errors/(8*(1 <<22));*/ |
1559 | tber = temporary / 256; |
1560 | else |
1561 | /* should not pass here*/ |
1562 | tber = 0; |
1563 | |
1564 | if ((Errors < 4294967) && (Errors > 429496)) |
1565 | tber *= 10; |
1566 | |
1567 | } |
1568 | |
1569 | /* save actual value */ |
1570 | ter_state->pBER = tber; |
1571 | |
1572 | (*ber) = tber; |
1573 | |
1574 | return 0; |
1575 | } |
1576 | #if 0 |
1577 | static u32 stv0367ter_get_per(struct stv0367_state *state) |
1578 | { |
1579 | struct stv0367ter_state *ter_state = state->ter_state; |
1580 | u32 Errors = 0, Per = 0, temporary = 0; |
1581 | int abc = 0, def = 0, cpt = 0; |
1582 | |
1583 | while (((stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 1) && |
1584 | (cpt < 400)) || ((Errors == 0) && (cpt < 400))) { |
1585 | usleep_range(1000, 2000); |
1586 | Errors = ((u32)stv0367_readbits(state, F367TER_ERR_CNT1) |
1587 | * (1 << 16)) |
1588 | + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_HI) |
1589 | * (1 << 8)) |
1590 | + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_LO)); |
1591 | cpt++; |
1592 | } |
1593 | abc = stv0367_readbits(state, F367TER_ERR_SRC1); |
1594 | def = stv0367_readbits(state, F367TER_NUM_EVT1); |
1595 | |
1596 | if (Errors == 0) |
1597 | Per = 0; |
1598 | else if (abc == 0x9) { |
1599 | if (Errors <= 4) { |
1600 | temporary = (Errors * 1000000000) / (8 * (1 << 8)); |
1601 | } else if (Errors <= 42) { |
1602 | temporary = (Errors * 100000000) / (8 * (1 << 8)); |
1603 | temporary = temporary * 10; |
1604 | } else if (Errors <= 429) { |
1605 | temporary = (Errors * 10000000) / (8 * (1 << 8)); |
1606 | temporary = temporary * 100; |
1607 | } else if (Errors <= 4294) { |
1608 | temporary = (Errors * 1000000) / (8 * (1 << 8)); |
1609 | temporary = temporary * 1000; |
1610 | } else if (Errors <= 42949) { |
1611 | temporary = (Errors * 100000) / (8 * (1 << 8)); |
1612 | temporary = temporary * 10000; |
1613 | } else { /*if(Errors<=429496) 2^16 errors max*/ |
1614 | temporary = (Errors * 10000) / (8 * (1 << 8)); |
1615 | temporary = temporary * 100000; |
1616 | } |
1617 | |
1618 | /* pkt error*/ |
1619 | if (def == 2) |
1620 | /*Per=Errors/(1 << 8);*/ |
1621 | Per = temporary; |
1622 | else if (def == 3) |
1623 | /*Per=Errors/(1 << 10);*/ |
1624 | Per = temporary / 4; |
1625 | else if (def == 4) |
1626 | /*Per=Errors/(1 << 12);*/ |
1627 | Per = temporary / 16; |
1628 | else if (def == 5) |
1629 | /*Per=Errors/(1 << 14);*/ |
1630 | Per = temporary / 64; |
1631 | else if (def == 6) |
1632 | /*Per=Errors/(1 << 16);*/ |
1633 | Per = temporary / 256; |
1634 | else |
1635 | Per = 0; |
1636 | |
1637 | } |
1638 | /* save actual value */ |
1639 | ter_state->pPER = Per; |
1640 | |
1641 | return Per; |
1642 | } |
1643 | #endif |
1644 | static int stv0367_get_tune_settings(struct dvb_frontend *fe, |
1645 | struct dvb_frontend_tune_settings |
1646 | *fe_tune_settings) |
1647 | { |
1648 | fe_tune_settings->min_delay_ms = 1000; |
1649 | fe_tune_settings->step_size = 0; |
1650 | fe_tune_settings->max_drift = 0; |
1651 | |
1652 | return 0; |
1653 | } |
1654 | |
1655 | static void stv0367_release(struct dvb_frontend *fe) |
1656 | { |
1657 | struct stv0367_state *state = fe->demodulator_priv; |
1658 | |
1659 | kfree(objp: state->ter_state); |
1660 | kfree(objp: state->cab_state); |
1661 | kfree(objp: state); |
1662 | } |
1663 | |
1664 | static const struct dvb_frontend_ops stv0367ter_ops = { |
1665 | .delsys = { SYS_DVBT }, |
1666 | .info = { |
1667 | .name = "ST STV0367 DVB-T" , |
1668 | .frequency_min_hz = 47 * MHz, |
1669 | .frequency_max_hz = 862 * MHz, |
1670 | .frequency_stepsize_hz = 15625, |
1671 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | |
1672 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | |
1673 | FE_CAN_FEC_AUTO | |
1674 | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | |
1675 | FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO | |
1676 | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER | |
1677 | FE_CAN_INVERSION_AUTO | |
1678 | FE_CAN_MUTE_TS |
1679 | }, |
1680 | .release = stv0367_release, |
1681 | .init = stv0367ter_init, |
1682 | .sleep = stv0367ter_sleep, |
1683 | .i2c_gate_ctrl = stv0367ter_gate_ctrl, |
1684 | .set_frontend = stv0367ter_set_frontend, |
1685 | .get_frontend = stv0367ter_get_frontend, |
1686 | .get_tune_settings = stv0367_get_tune_settings, |
1687 | .read_status = stv0367ter_read_status, |
1688 | .read_ber = stv0367ter_read_ber,/* too slow */ |
1689 | /* .read_signal_strength = stv0367_read_signal_strength,*/ |
1690 | .read_snr = stv0367ter_read_snr, |
1691 | .read_ucblocks = stv0367ter_read_ucblocks, |
1692 | }; |
1693 | |
1694 | struct dvb_frontend *stv0367ter_attach(const struct stv0367_config *config, |
1695 | struct i2c_adapter *i2c) |
1696 | { |
1697 | struct stv0367_state *state = NULL; |
1698 | struct stv0367ter_state *ter_state = NULL; |
1699 | |
1700 | /* allocate memory for the internal state */ |
1701 | state = kzalloc(size: sizeof(struct stv0367_state), GFP_KERNEL); |
1702 | if (state == NULL) |
1703 | goto error; |
1704 | ter_state = kzalloc(size: sizeof(struct stv0367ter_state), GFP_KERNEL); |
1705 | if (ter_state == NULL) |
1706 | goto error; |
1707 | |
1708 | /* setup the state */ |
1709 | state->i2c = i2c; |
1710 | state->config = config; |
1711 | state->ter_state = ter_state; |
1712 | state->fe.ops = stv0367ter_ops; |
1713 | state->fe.demodulator_priv = state; |
1714 | state->chip_id = stv0367_readreg(state, reg: 0xf000); |
1715 | |
1716 | /* demod operation options */ |
1717 | state->use_i2c_gatectrl = 1; |
1718 | state->deftabs = STV0367_DEFTAB_GENERIC; |
1719 | state->reinit_on_setfrontend = 1; |
1720 | state->auto_if_khz = 0; |
1721 | |
1722 | dprintk("%s: chip_id = 0x%x\n" , __func__, state->chip_id); |
1723 | |
1724 | /* check if the demod is there */ |
1725 | if ((state->chip_id != 0x50) && (state->chip_id != 0x60)) |
1726 | goto error; |
1727 | |
1728 | return &state->fe; |
1729 | |
1730 | error: |
1731 | kfree(objp: ter_state); |
1732 | kfree(objp: state); |
1733 | return NULL; |
1734 | } |
1735 | EXPORT_SYMBOL_GPL(stv0367ter_attach); |
1736 | |
1737 | static int stv0367cab_gate_ctrl(struct dvb_frontend *fe, int enable) |
1738 | { |
1739 | struct stv0367_state *state = fe->demodulator_priv; |
1740 | |
1741 | dprintk("%s:\n" , __func__); |
1742 | |
1743 | stv0367_writebits(state, F367CAB_I2CT_ON, val: (enable > 0) ? 1 : 0); |
1744 | |
1745 | return 0; |
1746 | } |
1747 | |
1748 | static u32 stv0367cab_get_mclk(struct dvb_frontend *fe, u32 ExtClk_Hz) |
1749 | { |
1750 | struct stv0367_state *state = fe->demodulator_priv; |
1751 | u32 mclk_Hz = 0;/* master clock frequency (Hz) */ |
1752 | u32 M, N, P; |
1753 | |
1754 | |
1755 | if (stv0367_readbits(state, F367CAB_BYPASS_PLLXN) == 0) { |
1756 | N = (u32)stv0367_readbits(state, F367CAB_PLL_NDIV); |
1757 | if (N == 0) |
1758 | N = N + 1; |
1759 | |
1760 | M = (u32)stv0367_readbits(state, F367CAB_PLL_MDIV); |
1761 | if (M == 0) |
1762 | M = M + 1; |
1763 | |
1764 | P = (u32)stv0367_readbits(state, F367CAB_PLL_PDIV); |
1765 | |
1766 | if (P > 5) |
1767 | P = 5; |
1768 | |
1769 | mclk_Hz = ((ExtClk_Hz / 2) * N) / (M * (1 << P)); |
1770 | dprintk("stv0367cab_get_mclk BYPASS_PLLXN mclk_Hz=%d\n" , |
1771 | mclk_Hz); |
1772 | } else |
1773 | mclk_Hz = ExtClk_Hz; |
1774 | |
1775 | dprintk("stv0367cab_get_mclk final mclk_Hz=%d\n" , mclk_Hz); |
1776 | |
1777 | return mclk_Hz; |
1778 | } |
1779 | |
1780 | static u32 stv0367cab_get_adc_freq(struct dvb_frontend *fe, u32 ExtClk_Hz) |
1781 | { |
1782 | return stv0367cab_get_mclk(fe, ExtClk_Hz); |
1783 | } |
1784 | |
1785 | static enum stv0367cab_mod stv0367cab_SetQamSize(struct stv0367_state *state, |
1786 | u32 SymbolRate, |
1787 | enum stv0367cab_mod QAMSize) |
1788 | { |
1789 | /* Set QAM size */ |
1790 | stv0367_writebits(state, F367CAB_QAM_MODE, val: QAMSize); |
1791 | |
1792 | /* Set Registers settings specific to the QAM size */ |
1793 | switch (QAMSize) { |
1794 | case FE_CAB_MOD_QAM4: |
1795 | stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, data: 0x00); |
1796 | break; |
1797 | case FE_CAB_MOD_QAM16: |
1798 | stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, data: 0x64); |
1799 | stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, data: 0x00); |
1800 | stv0367_writereg(state, R367CAB_FSM_STATE, data: 0x90); |
1801 | stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, data: 0xc1); |
1802 | stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, data: 0xa7); |
1803 | stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, data: 0x95); |
1804 | stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, data: 0x40); |
1805 | stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, data: 0x8a); |
1806 | break; |
1807 | case FE_CAB_MOD_QAM32: |
1808 | stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, data: 0x00); |
1809 | stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, data: 0x6e); |
1810 | stv0367_writereg(state, R367CAB_FSM_STATE, data: 0xb0); |
1811 | stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, data: 0xc1); |
1812 | stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, data: 0xb7); |
1813 | stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, data: 0x9d); |
1814 | stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, data: 0x7f); |
1815 | stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, data: 0xa7); |
1816 | break; |
1817 | case FE_CAB_MOD_QAM64: |
1818 | stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, data: 0x82); |
1819 | stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, data: 0x5a); |
1820 | if (SymbolRate > 4500000) { |
1821 | stv0367_writereg(state, R367CAB_FSM_STATE, data: 0xb0); |
1822 | stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, data: 0xc1); |
1823 | stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, data: 0xa5); |
1824 | } else if (SymbolRate > 2500000) { |
1825 | stv0367_writereg(state, R367CAB_FSM_STATE, data: 0xa0); |
1826 | stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, data: 0xc1); |
1827 | stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, data: 0xa6); |
1828 | } else { |
1829 | stv0367_writereg(state, R367CAB_FSM_STATE, data: 0xa0); |
1830 | stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, data: 0xd1); |
1831 | stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, data: 0xa7); |
1832 | } |
1833 | stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, data: 0x95); |
1834 | stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, data: 0x40); |
1835 | stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, data: 0x99); |
1836 | break; |
1837 | case FE_CAB_MOD_QAM128: |
1838 | stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, data: 0x00); |
1839 | stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, data: 0x76); |
1840 | stv0367_writereg(state, R367CAB_FSM_STATE, data: 0x90); |
1841 | stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, data: 0xb1); |
1842 | if (SymbolRate > 4500000) |
1843 | stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, data: 0xa7); |
1844 | else if (SymbolRate > 2500000) |
1845 | stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, data: 0xa6); |
1846 | else |
1847 | stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, data: 0x97); |
1848 | |
1849 | stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, data: 0x8e); |
1850 | stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, data: 0x7f); |
1851 | stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, data: 0xa7); |
1852 | break; |
1853 | case FE_CAB_MOD_QAM256: |
1854 | stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, data: 0x94); |
1855 | stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, data: 0x5a); |
1856 | stv0367_writereg(state, R367CAB_FSM_STATE, data: 0xa0); |
1857 | if (SymbolRate > 4500000) |
1858 | stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, data: 0xc1); |
1859 | else if (SymbolRate > 2500000) |
1860 | stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, data: 0xc1); |
1861 | else |
1862 | stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, data: 0xd1); |
1863 | |
1864 | stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, data: 0xa7); |
1865 | stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, data: 0x85); |
1866 | stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, data: 0x40); |
1867 | stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, data: 0xa7); |
1868 | break; |
1869 | case FE_CAB_MOD_QAM512: |
1870 | stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, data: 0x00); |
1871 | break; |
1872 | case FE_CAB_MOD_QAM1024: |
1873 | stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, data: 0x00); |
1874 | break; |
1875 | default: |
1876 | break; |
1877 | } |
1878 | |
1879 | return QAMSize; |
1880 | } |
1881 | |
1882 | static u32 stv0367cab_set_derot_freq(struct stv0367_state *state, |
1883 | u32 adc_hz, s32 derot_hz) |
1884 | { |
1885 | u32 sampled_if = 0; |
1886 | u32 adc_khz; |
1887 | |
1888 | adc_khz = adc_hz / 1000; |
1889 | |
1890 | dprintk("%s: adc_hz=%d derot_hz=%d\n" , __func__, adc_hz, derot_hz); |
1891 | |
1892 | if (adc_khz != 0) { |
1893 | if (derot_hz < 1000000) |
1894 | derot_hz = adc_hz / 4; /* ZIF operation */ |
1895 | if (derot_hz > adc_hz) |
1896 | derot_hz = derot_hz - adc_hz; |
1897 | sampled_if = (u32)derot_hz / 1000; |
1898 | sampled_if *= 32768; |
1899 | sampled_if /= adc_khz; |
1900 | sampled_if *= 256; |
1901 | } |
1902 | |
1903 | if (sampled_if > 8388607) |
1904 | sampled_if = 8388607; |
1905 | |
1906 | dprintk("%s: sampled_if=0x%x\n" , __func__, sampled_if); |
1907 | |
1908 | stv0367_writereg(state, R367CAB_MIX_NCO_LL, data: sampled_if); |
1909 | stv0367_writereg(state, R367CAB_MIX_NCO_HL, data: (sampled_if >> 8)); |
1910 | stv0367_writebits(state, F367CAB_MIX_NCO_INC_HH, val: (sampled_if >> 16)); |
1911 | |
1912 | return derot_hz; |
1913 | } |
1914 | |
1915 | static u32 stv0367cab_get_derot_freq(struct stv0367_state *state, u32 adc_hz) |
1916 | { |
1917 | u32 sampled_if; |
1918 | |
1919 | sampled_if = stv0367_readbits(state, F367CAB_MIX_NCO_INC_LL) + |
1920 | (stv0367_readbits(state, F367CAB_MIX_NCO_INC_HL) << 8) + |
1921 | (stv0367_readbits(state, F367CAB_MIX_NCO_INC_HH) << 16); |
1922 | |
1923 | sampled_if /= 256; |
1924 | sampled_if *= (adc_hz / 1000); |
1925 | sampled_if += 1; |
1926 | sampled_if /= 32768; |
1927 | |
1928 | return sampled_if; |
1929 | } |
1930 | |
1931 | static u32 stv0367cab_set_srate(struct stv0367_state *state, u32 adc_hz, |
1932 | u32 mclk_hz, u32 SymbolRate, |
1933 | enum stv0367cab_mod QAMSize) |
1934 | { |
1935 | u32 QamSizeCorr = 0; |
1936 | u32 u32_tmp = 0, u32_tmp1 = 0; |
1937 | u32 adp_khz; |
1938 | |
1939 | dprintk("%s:\n" , __func__); |
1940 | |
1941 | /* Set Correction factor of SRC gain */ |
1942 | switch (QAMSize) { |
1943 | case FE_CAB_MOD_QAM4: |
1944 | QamSizeCorr = 1110; |
1945 | break; |
1946 | case FE_CAB_MOD_QAM16: |
1947 | QamSizeCorr = 1032; |
1948 | break; |
1949 | case FE_CAB_MOD_QAM32: |
1950 | QamSizeCorr = 954; |
1951 | break; |
1952 | case FE_CAB_MOD_QAM64: |
1953 | QamSizeCorr = 983; |
1954 | break; |
1955 | case FE_CAB_MOD_QAM128: |
1956 | QamSizeCorr = 957; |
1957 | break; |
1958 | case FE_CAB_MOD_QAM256: |
1959 | QamSizeCorr = 948; |
1960 | break; |
1961 | case FE_CAB_MOD_QAM512: |
1962 | QamSizeCorr = 0; |
1963 | break; |
1964 | case FE_CAB_MOD_QAM1024: |
1965 | QamSizeCorr = 944; |
1966 | break; |
1967 | default: |
1968 | break; |
1969 | } |
1970 | |
1971 | /* Transfer ratio calculation */ |
1972 | if (adc_hz != 0) { |
1973 | u32_tmp = 256 * SymbolRate; |
1974 | u32_tmp = u32_tmp / adc_hz; |
1975 | } |
1976 | stv0367_writereg(state, R367CAB_EQU_CRL_TFR, data: (u8)u32_tmp); |
1977 | |
1978 | /* Symbol rate and SRC gain calculation */ |
1979 | adp_khz = (mclk_hz >> 1) / 1000;/* TRL works at half the system clock */ |
1980 | if (adp_khz != 0) { |
1981 | u32_tmp = SymbolRate; |
1982 | u32_tmp1 = SymbolRate; |
1983 | |
1984 | if (u32_tmp < 2097152) { /* 2097152 = 2^21 */ |
1985 | /* Symbol rate calculation */ |
1986 | u32_tmp *= 2048; /* 2048 = 2^11 */ |
1987 | u32_tmp = u32_tmp / adp_khz; |
1988 | u32_tmp = u32_tmp * 16384; /* 16384 = 2^14 */ |
1989 | u32_tmp /= 125 ; /* 125 = 1000/2^3 */ |
1990 | u32_tmp = u32_tmp * 8; /* 8 = 2^3 */ |
1991 | |
1992 | /* SRC Gain Calculation */ |
1993 | u32_tmp1 *= 2048; /* *2*2^10 */ |
1994 | u32_tmp1 /= 439; /* *2/878 */ |
1995 | u32_tmp1 *= 256; /* *2^8 */ |
1996 | u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */ |
1997 | u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */ |
1998 | u32_tmp1 = u32_tmp1 / 10000000; |
1999 | |
2000 | } else if (u32_tmp < 4194304) { /* 4194304 = 2**22 */ |
2001 | /* Symbol rate calculation */ |
2002 | u32_tmp *= 1024 ; /* 1024 = 2**10 */ |
2003 | u32_tmp = u32_tmp / adp_khz; |
2004 | u32_tmp = u32_tmp * 16384; /* 16384 = 2**14 */ |
2005 | u32_tmp /= 125 ; /* 125 = 1000/2**3 */ |
2006 | u32_tmp = u32_tmp * 16; /* 16 = 2**4 */ |
2007 | |
2008 | /* SRC Gain Calculation */ |
2009 | u32_tmp1 *= 1024; /* *2*2^9 */ |
2010 | u32_tmp1 /= 439; /* *2/878 */ |
2011 | u32_tmp1 *= 256; /* *2^8 */ |
2012 | u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz)*/ |
2013 | u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */ |
2014 | u32_tmp1 = u32_tmp1 / 5000000; |
2015 | } else if (u32_tmp < 8388607) { /* 8388607 = 2**23 */ |
2016 | /* Symbol rate calculation */ |
2017 | u32_tmp *= 512 ; /* 512 = 2**9 */ |
2018 | u32_tmp = u32_tmp / adp_khz; |
2019 | u32_tmp = u32_tmp * 16384; /* 16384 = 2**14 */ |
2020 | u32_tmp /= 125 ; /* 125 = 1000/2**3 */ |
2021 | u32_tmp = u32_tmp * 32; /* 32 = 2**5 */ |
2022 | |
2023 | /* SRC Gain Calculation */ |
2024 | u32_tmp1 *= 512; /* *2*2^8 */ |
2025 | u32_tmp1 /= 439; /* *2/878 */ |
2026 | u32_tmp1 *= 256; /* *2^8 */ |
2027 | u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */ |
2028 | u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */ |
2029 | u32_tmp1 = u32_tmp1 / 2500000; |
2030 | } else { |
2031 | /* Symbol rate calculation */ |
2032 | u32_tmp *= 256 ; /* 256 = 2**8 */ |
2033 | u32_tmp = u32_tmp / adp_khz; |
2034 | u32_tmp = u32_tmp * 16384; /* 16384 = 2**13 */ |
2035 | u32_tmp /= 125 ; /* 125 = 1000/2**3 */ |
2036 | u32_tmp = u32_tmp * 64; /* 64 = 2**6 */ |
2037 | |
2038 | /* SRC Gain Calculation */ |
2039 | u32_tmp1 *= 256; /* 2*2^7 */ |
2040 | u32_tmp1 /= 439; /* *2/878 */ |
2041 | u32_tmp1 *= 256; /* *2^8 */ |
2042 | u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */ |
2043 | u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */ |
2044 | u32_tmp1 = u32_tmp1 / 1250000; |
2045 | } |
2046 | } |
2047 | #if 0 |
2048 | /* Filters' coefficients are calculated and written |
2049 | into registers only if the filters are enabled */ |
2050 | if (stv0367_readbits(state, F367CAB_ADJ_EN)) { |
2051 | stv0367cab_SetIirAdjacentcoefficient(state, mclk_hz, |
2052 | SymbolRate); |
2053 | /* AllPass filter must be enabled |
2054 | when the adjacents filter is used */ |
2055 | stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 1); |
2056 | stv0367cab_SetAllPasscoefficient(state, mclk_hz, SymbolRate); |
2057 | } else |
2058 | /* AllPass filter must be disabled |
2059 | when the adjacents filter is not used */ |
2060 | #endif |
2061 | stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, val: 0); |
2062 | |
2063 | stv0367_writereg(state, R367CAB_SRC_NCO_LL, data: u32_tmp); |
2064 | stv0367_writereg(state, R367CAB_SRC_NCO_LH, data: (u32_tmp >> 8)); |
2065 | stv0367_writereg(state, R367CAB_SRC_NCO_HL, data: (u32_tmp >> 16)); |
2066 | stv0367_writereg(state, R367CAB_SRC_NCO_HH, data: (u32_tmp >> 24)); |
2067 | |
2068 | stv0367_writereg(state, R367CAB_IQDEM_GAIN_SRC_L, data: u32_tmp1 & 0x00ff); |
2069 | stv0367_writebits(state, F367CAB_GAIN_SRC_HI, val: (u32_tmp1 >> 8) & 0x00ff); |
2070 | |
2071 | return SymbolRate ; |
2072 | } |
2073 | |
2074 | static u32 stv0367cab_GetSymbolRate(struct stv0367_state *state, u32 mclk_hz) |
2075 | { |
2076 | u32 regsym; |
2077 | u32 adp_khz; |
2078 | |
2079 | regsym = stv0367_readreg(state, R367CAB_SRC_NCO_LL) + |
2080 | (stv0367_readreg(state, R367CAB_SRC_NCO_LH) << 8) + |
2081 | (stv0367_readreg(state, R367CAB_SRC_NCO_HL) << 16) + |
2082 | (stv0367_readreg(state, R367CAB_SRC_NCO_HH) << 24); |
2083 | |
2084 | adp_khz = (mclk_hz >> 1) / 1000;/* TRL works at half the system clock */ |
2085 | |
2086 | if (regsym < 134217728) { /* 134217728L = 2**27*/ |
2087 | regsym = regsym * 32; /* 32 = 2**5 */ |
2088 | regsym = regsym / 32768; /* 32768L = 2**15 */ |
2089 | regsym = adp_khz * regsym; /* AdpClk in kHz */ |
2090 | regsym = regsym / 128; /* 128 = 2**7 */ |
2091 | regsym *= 125 ; /* 125 = 1000/2**3 */ |
2092 | regsym /= 2048 ; /* 2048 = 2**11 */ |
2093 | } else if (regsym < 268435456) { /* 268435456L = 2**28 */ |
2094 | regsym = regsym * 16; /* 16 = 2**4 */ |
2095 | regsym = regsym / 32768; /* 32768L = 2**15 */ |
2096 | regsym = adp_khz * regsym; /* AdpClk in kHz */ |
2097 | regsym = regsym / 128; /* 128 = 2**7 */ |
2098 | regsym *= 125 ; /* 125 = 1000/2**3*/ |
2099 | regsym /= 1024 ; /* 256 = 2**10*/ |
2100 | } else if (regsym < 536870912) { /* 536870912L = 2**29*/ |
2101 | regsym = regsym * 8; /* 8 = 2**3 */ |
2102 | regsym = regsym / 32768; /* 32768L = 2**15 */ |
2103 | regsym = adp_khz * regsym; /* AdpClk in kHz */ |
2104 | regsym = regsym / 128; /* 128 = 2**7 */ |
2105 | regsym *= 125 ; /* 125 = 1000/2**3 */ |
2106 | regsym /= 512 ; /* 128 = 2**9 */ |
2107 | } else { |
2108 | regsym = regsym * 4; /* 4 = 2**2 */ |
2109 | regsym = regsym / 32768; /* 32768L = 2**15 */ |
2110 | regsym = adp_khz * regsym; /* AdpClk in kHz */ |
2111 | regsym = regsym / 128; /* 128 = 2**7 */ |
2112 | regsym *= 125 ; /* 125 = 1000/2**3 */ |
2113 | regsym /= 256 ; /* 64 = 2**8 */ |
2114 | } |
2115 | |
2116 | return regsym; |
2117 | } |
2118 | |
2119 | static u32 stv0367cab_fsm_status(struct stv0367_state *state) |
2120 | { |
2121 | return stv0367_readbits(state, F367CAB_FSM_STATUS); |
2122 | } |
2123 | |
2124 | static u32 stv0367cab_qamfec_lock(struct stv0367_state *state) |
2125 | { |
2126 | return stv0367_readbits(state, |
2127 | label: (state->cab_state->qamfec_status_reg ? |
2128 | state->cab_state->qamfec_status_reg : |
2129 | F367CAB_QAMFEC_LOCK)); |
2130 | } |
2131 | |
2132 | static |
2133 | enum stv0367_cab_signal_type stv0367cab_fsm_signaltype(u32 qam_fsm_status) |
2134 | { |
2135 | enum stv0367_cab_signal_type signaltype = FE_CAB_NOAGC; |
2136 | |
2137 | switch (qam_fsm_status) { |
2138 | case 1: |
2139 | signaltype = FE_CAB_NOAGC; |
2140 | break; |
2141 | case 2: |
2142 | signaltype = FE_CAB_NOTIMING; |
2143 | break; |
2144 | case 3: |
2145 | signaltype = FE_CAB_TIMINGOK; |
2146 | break; |
2147 | case 4: |
2148 | signaltype = FE_CAB_NOCARRIER; |
2149 | break; |
2150 | case 5: |
2151 | signaltype = FE_CAB_CARRIEROK; |
2152 | break; |
2153 | case 7: |
2154 | signaltype = FE_CAB_NOBLIND; |
2155 | break; |
2156 | case 8: |
2157 | signaltype = FE_CAB_BLINDOK; |
2158 | break; |
2159 | case 10: |
2160 | signaltype = FE_CAB_NODEMOD; |
2161 | break; |
2162 | case 11: |
2163 | signaltype = FE_CAB_DEMODOK; |
2164 | break; |
2165 | case 12: |
2166 | signaltype = FE_CAB_DEMODOK; |
2167 | break; |
2168 | case 13: |
2169 | signaltype = FE_CAB_NODEMOD; |
2170 | break; |
2171 | case 14: |
2172 | signaltype = FE_CAB_NOBLIND; |
2173 | break; |
2174 | case 15: |
2175 | signaltype = FE_CAB_NOSIGNAL; |
2176 | break; |
2177 | default: |
2178 | break; |
2179 | } |
2180 | |
2181 | return signaltype; |
2182 | } |
2183 | |
2184 | static int stv0367cab_read_status(struct dvb_frontend *fe, |
2185 | enum fe_status *status) |
2186 | { |
2187 | struct stv0367_state *state = fe->demodulator_priv; |
2188 | |
2189 | dprintk("%s:\n" , __func__); |
2190 | |
2191 | *status = 0; |
2192 | |
2193 | /* update cab_state->state from QAM_FSM_STATUS */ |
2194 | state->cab_state->state = stv0367cab_fsm_signaltype( |
2195 | qam_fsm_status: stv0367cab_fsm_status(state)); |
2196 | |
2197 | if (stv0367cab_qamfec_lock(state)) { |
2198 | *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
2199 | | FE_HAS_SYNC | FE_HAS_LOCK; |
2200 | dprintk("%s: stv0367 has locked\n" , __func__); |
2201 | } else { |
2202 | if (state->cab_state->state > FE_CAB_NOSIGNAL) |
2203 | *status |= FE_HAS_SIGNAL; |
2204 | |
2205 | if (state->cab_state->state > FE_CAB_NOCARRIER) |
2206 | *status |= FE_HAS_CARRIER; |
2207 | |
2208 | if (state->cab_state->state >= FE_CAB_DEMODOK) |
2209 | *status |= FE_HAS_VITERBI; |
2210 | |
2211 | if (state->cab_state->state >= FE_CAB_DATAOK) |
2212 | *status |= FE_HAS_SYNC; |
2213 | } |
2214 | |
2215 | return 0; |
2216 | } |
2217 | |
2218 | static int stv0367cab_standby(struct dvb_frontend *fe, u8 standby_on) |
2219 | { |
2220 | struct stv0367_state *state = fe->demodulator_priv; |
2221 | |
2222 | dprintk("%s:\n" , __func__); |
2223 | |
2224 | if (standby_on) { |
2225 | stv0367_writebits(state, F367CAB_BYPASS_PLLXN, val: 0x03); |
2226 | stv0367_writebits(state, F367CAB_STDBY_PLLXN, val: 0x01); |
2227 | stv0367_writebits(state, F367CAB_STDBY, val: 1); |
2228 | stv0367_writebits(state, F367CAB_STDBY_CORE, val: 1); |
2229 | stv0367_writebits(state, F367CAB_EN_BUFFER_I, val: 0); |
2230 | stv0367_writebits(state, F367CAB_EN_BUFFER_Q, val: 0); |
2231 | stv0367_writebits(state, F367CAB_POFFQ, val: 1); |
2232 | stv0367_writebits(state, F367CAB_POFFI, val: 1); |
2233 | } else { |
2234 | stv0367_writebits(state, F367CAB_STDBY_PLLXN, val: 0x00); |
2235 | stv0367_writebits(state, F367CAB_BYPASS_PLLXN, val: 0x00); |
2236 | stv0367_writebits(state, F367CAB_STDBY, val: 0); |
2237 | stv0367_writebits(state, F367CAB_STDBY_CORE, val: 0); |
2238 | stv0367_writebits(state, F367CAB_EN_BUFFER_I, val: 1); |
2239 | stv0367_writebits(state, F367CAB_EN_BUFFER_Q, val: 1); |
2240 | stv0367_writebits(state, F367CAB_POFFQ, val: 0); |
2241 | stv0367_writebits(state, F367CAB_POFFI, val: 0); |
2242 | } |
2243 | |
2244 | return 0; |
2245 | } |
2246 | |
2247 | static int stv0367cab_sleep(struct dvb_frontend *fe) |
2248 | { |
2249 | return stv0367cab_standby(fe, standby_on: 1); |
2250 | } |
2251 | |
2252 | static int stv0367cab_init(struct dvb_frontend *fe) |
2253 | { |
2254 | struct stv0367_state *state = fe->demodulator_priv; |
2255 | struct stv0367cab_state *cab_state = state->cab_state; |
2256 | |
2257 | dprintk("%s:\n" , __func__); |
2258 | |
2259 | stv0367_write_table(state, |
2260 | deftab: stv0367_deftabs[state->deftabs][STV0367_TAB_CAB]); |
2261 | |
2262 | switch (state->config->ts_mode) { |
2263 | case STV0367_DVBCI_CLOCK: |
2264 | dprintk("Setting TSMode = STV0367_DVBCI_CLOCK\n" ); |
2265 | stv0367_writebits(state, F367CAB_OUTFORMAT, val: 0x03); |
2266 | break; |
2267 | case STV0367_SERIAL_PUNCT_CLOCK: |
2268 | case STV0367_SERIAL_CONT_CLOCK: |
2269 | stv0367_writebits(state, F367CAB_OUTFORMAT, val: 0x01); |
2270 | break; |
2271 | case STV0367_PARALLEL_PUNCT_CLOCK: |
2272 | case STV0367_OUTPUTMODE_DEFAULT: |
2273 | stv0367_writebits(state, F367CAB_OUTFORMAT, val: 0x00); |
2274 | break; |
2275 | } |
2276 | |
2277 | switch (state->config->clk_pol) { |
2278 | case STV0367_RISINGEDGE_CLOCK: |
2279 | stv0367_writebits(state, F367CAB_CLK_POLARITY, val: 0x00); |
2280 | break; |
2281 | case STV0367_FALLINGEDGE_CLOCK: |
2282 | case STV0367_CLOCKPOLARITY_DEFAULT: |
2283 | stv0367_writebits(state, F367CAB_CLK_POLARITY, val: 0x01); |
2284 | break; |
2285 | } |
2286 | |
2287 | stv0367_writebits(state, F367CAB_SYNC_STRIP, val: 0x00); |
2288 | |
2289 | stv0367_writebits(state, F367CAB_CT_NBST, val: 0x01); |
2290 | |
2291 | stv0367_writebits(state, F367CAB_TS_SWAP, val: 0x01); |
2292 | |
2293 | stv0367_writebits(state, F367CAB_FIFO_BYPASS, val: 0x00); |
2294 | |
2295 | stv0367_writereg(state, R367CAB_ANACTRL, data: 0x00);/*PLL enabled and used */ |
2296 | |
2297 | cab_state->mclk = stv0367cab_get_mclk(fe, ExtClk_Hz: state->config->xtal); |
2298 | cab_state->adc_clk = stv0367cab_get_adc_freq(fe, ExtClk_Hz: state->config->xtal); |
2299 | |
2300 | return 0; |
2301 | } |
2302 | static |
2303 | enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state, |
2304 | struct dtv_frontend_properties *p) |
2305 | { |
2306 | struct stv0367cab_state *cab_state = state->cab_state; |
2307 | enum stv0367_cab_signal_type signalType = FE_CAB_NOAGC; |
2308 | u32 QAMFEC_Lock, QAM_Lock, u32_tmp, ifkhz, |
2309 | LockTime, TRLTimeOut, AGCTimeOut, CRLSymbols, |
2310 | CRLTimeOut, EQLTimeOut, DemodTimeOut, FECTimeOut; |
2311 | u8 TrackAGCAccum; |
2312 | s32 tmp; |
2313 | |
2314 | dprintk("%s:\n" , __func__); |
2315 | |
2316 | stv0367_get_if_khz(state, ifkhz: &ifkhz); |
2317 | |
2318 | /* Timeouts calculation */ |
2319 | /* A max lock time of 25 ms is allowed for delayed AGC */ |
2320 | AGCTimeOut = 25; |
2321 | /* 100000 symbols needed by the TRL as a maximum value */ |
2322 | TRLTimeOut = 100000000 / p->symbol_rate; |
2323 | /* CRLSymbols is the needed number of symbols to achieve a lock |
2324 | within [-4%, +4%] of the symbol rate. |
2325 | CRL timeout is calculated |
2326 | for a lock within [-search_range, +search_range]. |
2327 | EQL timeout can be changed depending on |
2328 | the micro-reflections we want to handle. |
2329 | A characterization must be performed |
2330 | with these echoes to get new timeout values. |
2331 | */ |
2332 | switch (p->modulation) { |
2333 | case QAM_16: |
2334 | CRLSymbols = 150000; |
2335 | EQLTimeOut = 100; |
2336 | break; |
2337 | case QAM_32: |
2338 | CRLSymbols = 250000; |
2339 | EQLTimeOut = 100; |
2340 | break; |
2341 | case QAM_64: |
2342 | CRLSymbols = 200000; |
2343 | EQLTimeOut = 100; |
2344 | break; |
2345 | case QAM_128: |
2346 | CRLSymbols = 250000; |
2347 | EQLTimeOut = 100; |
2348 | break; |
2349 | case QAM_256: |
2350 | CRLSymbols = 250000; |
2351 | EQLTimeOut = 100; |
2352 | break; |
2353 | default: |
2354 | CRLSymbols = 200000; |
2355 | EQLTimeOut = 100; |
2356 | break; |
2357 | } |
2358 | #if 0 |
2359 | if (pIntParams->search_range < 0) { |
2360 | CRLTimeOut = (25 * CRLSymbols * |
2361 | (-pIntParams->search_range / 1000)) / |
2362 | (pIntParams->symbol_rate / 1000); |
2363 | } else |
2364 | #endif |
2365 | CRLTimeOut = (25 * CRLSymbols * (cab_state->search_range / 1000)) / |
2366 | (p->symbol_rate / 1000); |
2367 | |
2368 | CRLTimeOut = (1000 * CRLTimeOut) / p->symbol_rate; |
2369 | /* Timeouts below 50ms are coerced */ |
2370 | if (CRLTimeOut < 50) |
2371 | CRLTimeOut = 50; |
2372 | /* A maximum of 100 TS packets is needed to get FEC lock even in case |
2373 | the spectrum inversion needs to be changed. |
2374 | This is equal to 20 ms in case of the lowest symbol rate of 0.87Msps |
2375 | */ |
2376 | FECTimeOut = 20; |
2377 | DemodTimeOut = AGCTimeOut + TRLTimeOut + CRLTimeOut + EQLTimeOut; |
2378 | |
2379 | dprintk("%s: DemodTimeOut=%d\n" , __func__, DemodTimeOut); |
2380 | |
2381 | /* Reset the TRL to ensure nothing starts until the |
2382 | AGC is stable which ensures a better lock time |
2383 | */ |
2384 | stv0367_writereg(state, R367CAB_CTRL_1, data: 0x04); |
2385 | /* Set AGC accumulation time to minimum and lock threshold to maximum |
2386 | in order to speed up the AGC lock */ |
2387 | TrackAGCAccum = stv0367_readbits(state, F367CAB_AGC_ACCUMRSTSEL); |
2388 | stv0367_writebits(state, F367CAB_AGC_ACCUMRSTSEL, val: 0x0); |
2389 | /* Modulus Mapper is disabled */ |
2390 | stv0367_writebits(state, F367CAB_MODULUSMAP_EN, val: 0); |
2391 | /* Disable the sweep function */ |
2392 | stv0367_writebits(state, F367CAB_SWEEP_EN, val: 0); |
2393 | /* The sweep function is never used, Sweep rate must be set to 0 */ |
2394 | /* Set the derotator frequency in Hz */ |
2395 | stv0367cab_set_derot_freq(state, adc_hz: cab_state->adc_clk, |
2396 | derot_hz: (1000 * (s32)ifkhz + cab_state->derot_offset)); |
2397 | /* Disable the Allpass Filter when the symbol rate is out of range */ |
2398 | if ((p->symbol_rate > 10800000) | (p->symbol_rate < 1800000)) { |
2399 | stv0367_writebits(state, F367CAB_ADJ_EN, val: 0); |
2400 | stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, val: 0); |
2401 | } |
2402 | #if 0 |
2403 | /* Check if the tuner is locked */ |
2404 | tuner_lock = stv0367cab_tuner_get_status(fe); |
2405 | if (tuner_lock == 0) |
2406 | return FE_367CAB_NOTUNER; |
2407 | #endif |
2408 | /* Release the TRL to start demodulator acquisition */ |
2409 | /* Wait for QAM lock */ |
2410 | LockTime = 0; |
2411 | stv0367_writereg(state, R367CAB_CTRL_1, data: 0x00); |
2412 | do { |
2413 | QAM_Lock = stv0367cab_fsm_status(state); |
2414 | if ((LockTime >= (DemodTimeOut - EQLTimeOut)) && |
2415 | (QAM_Lock == 0x04)) |
2416 | /* |
2417 | * We don't wait longer, the frequency/phase offset |
2418 | * must be too big |
2419 | */ |
2420 | LockTime = DemodTimeOut; |
2421 | else if ((LockTime >= (AGCTimeOut + TRLTimeOut)) && |
2422 | (QAM_Lock == 0x02)) |
2423 | /* |
2424 | * We don't wait longer, either there is no signal or |
2425 | * it is not the right symbol rate or it is an analog |
2426 | * carrier |
2427 | */ |
2428 | { |
2429 | LockTime = DemodTimeOut; |
2430 | u32_tmp = stv0367_readbits(state, |
2431 | F367CAB_AGC_PWR_WORD_LO) + |
2432 | (stv0367_readbits(state, |
2433 | F367CAB_AGC_PWR_WORD_ME) << 8) + |
2434 | (stv0367_readbits(state, |
2435 | F367CAB_AGC_PWR_WORD_HI) << 16); |
2436 | if (u32_tmp >= 131072) |
2437 | u32_tmp = 262144 - u32_tmp; |
2438 | u32_tmp = u32_tmp / (1 << (11 - stv0367_readbits(state, |
2439 | F367CAB_AGC_IF_BWSEL))); |
2440 | |
2441 | if (u32_tmp < stv0367_readbits(state, |
2442 | F367CAB_AGC_PWRREF_LO) + |
2443 | 256 * stv0367_readbits(state, |
2444 | F367CAB_AGC_PWRREF_HI) - 10) |
2445 | QAM_Lock = 0x0f; |
2446 | } else { |
2447 | usleep_range(min: 10000, max: 20000); |
2448 | LockTime += 10; |
2449 | } |
2450 | dprintk("QAM_Lock=0x%x LockTime=%d\n" , QAM_Lock, LockTime); |
2451 | tmp = stv0367_readreg(state, R367CAB_IT_STATUS1); |
2452 | |
2453 | dprintk("R367CAB_IT_STATUS1=0x%x\n" , tmp); |
2454 | |
2455 | } while (((QAM_Lock != 0x0c) && (QAM_Lock != 0x0b)) && |
2456 | (LockTime < DemodTimeOut)); |
2457 | |
2458 | dprintk("QAM_Lock=0x%x\n" , QAM_Lock); |
2459 | |
2460 | tmp = stv0367_readreg(state, R367CAB_IT_STATUS1); |
2461 | dprintk("R367CAB_IT_STATUS1=0x%x\n" , tmp); |
2462 | tmp = stv0367_readreg(state, R367CAB_IT_STATUS2); |
2463 | dprintk("R367CAB_IT_STATUS2=0x%x\n" , tmp); |
2464 | |
2465 | tmp = stv0367cab_get_derot_freq(state, adc_hz: cab_state->adc_clk); |
2466 | dprintk("stv0367cab_get_derot_freq=0x%x\n" , tmp); |
2467 | |
2468 | if ((QAM_Lock == 0x0c) || (QAM_Lock == 0x0b)) { |
2469 | /* Wait for FEC lock */ |
2470 | LockTime = 0; |
2471 | do { |
2472 | usleep_range(min: 5000, max: 7000); |
2473 | LockTime += 5; |
2474 | QAMFEC_Lock = stv0367cab_qamfec_lock(state); |
2475 | } while (!QAMFEC_Lock && (LockTime < FECTimeOut)); |
2476 | } else |
2477 | QAMFEC_Lock = 0; |
2478 | |
2479 | if (QAMFEC_Lock) { |
2480 | signalType = FE_CAB_DATAOK; |
2481 | cab_state->spect_inv = stv0367_readbits(state, |
2482 | F367CAB_QUAD_INV); |
2483 | #if 0 |
2484 | /* not clear for me */ |
2485 | if (ifkhz != 0) { |
2486 | if (ifkhz > cab_state->adc_clk / 1000) { |
2487 | cab_state->freq_khz = |
2488 | FE_Cab_TunerGetFrequency(pIntParams->hTuner) |
2489 | - stv0367cab_get_derot_freq(state, cab_state->adc_clk) |
2490 | - cab_state->adc_clk / 1000 + ifkhz; |
2491 | } else { |
2492 | cab_state->freq_khz = |
2493 | FE_Cab_TunerGetFrequency(pIntParams->hTuner) |
2494 | - stv0367cab_get_derot_freq(state, cab_state->adc_clk) |
2495 | + ifkhz; |
2496 | } |
2497 | } else { |
2498 | cab_state->freq_khz = |
2499 | FE_Cab_TunerGetFrequency(pIntParams->hTuner) + |
2500 | stv0367cab_get_derot_freq(state, |
2501 | cab_state->adc_clk) - |
2502 | cab_state->adc_clk / 4000; |
2503 | } |
2504 | #endif |
2505 | cab_state->symbol_rate = stv0367cab_GetSymbolRate(state, |
2506 | mclk_hz: cab_state->mclk); |
2507 | cab_state->locked = 1; |
2508 | |
2509 | /* stv0367_setbits(state, F367CAB_AGC_ACCUMRSTSEL,7);*/ |
2510 | } else |
2511 | signalType = stv0367cab_fsm_signaltype(qam_fsm_status: QAM_Lock); |
2512 | |
2513 | /* Set the AGC control values to tracking values */ |
2514 | stv0367_writebits(state, F367CAB_AGC_ACCUMRSTSEL, val: TrackAGCAccum); |
2515 | return signalType; |
2516 | } |
2517 | |
2518 | static int stv0367cab_set_frontend(struct dvb_frontend *fe) |
2519 | { |
2520 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; |
2521 | struct stv0367_state *state = fe->demodulator_priv; |
2522 | struct stv0367cab_state *cab_state = state->cab_state; |
2523 | enum stv0367cab_mod QAMSize = 0; |
2524 | |
2525 | dprintk("%s: freq = %d, srate = %d\n" , __func__, |
2526 | p->frequency, p->symbol_rate); |
2527 | |
2528 | cab_state->derot_offset = 0; |
2529 | |
2530 | switch (p->modulation) { |
2531 | case QAM_16: |
2532 | QAMSize = FE_CAB_MOD_QAM16; |
2533 | break; |
2534 | case QAM_32: |
2535 | QAMSize = FE_CAB_MOD_QAM32; |
2536 | break; |
2537 | case QAM_64: |
2538 | QAMSize = FE_CAB_MOD_QAM64; |
2539 | break; |
2540 | case QAM_128: |
2541 | QAMSize = FE_CAB_MOD_QAM128; |
2542 | break; |
2543 | case QAM_256: |
2544 | QAMSize = FE_CAB_MOD_QAM256; |
2545 | break; |
2546 | default: |
2547 | break; |
2548 | } |
2549 | |
2550 | if (state->reinit_on_setfrontend) |
2551 | stv0367cab_init(fe); |
2552 | |
2553 | /* Tuner Frequency Setting */ |
2554 | if (fe->ops.tuner_ops.set_params) { |
2555 | if (state->use_i2c_gatectrl && fe->ops.i2c_gate_ctrl) |
2556 | fe->ops.i2c_gate_ctrl(fe, 1); |
2557 | fe->ops.tuner_ops.set_params(fe); |
2558 | if (state->use_i2c_gatectrl && fe->ops.i2c_gate_ctrl) |
2559 | fe->ops.i2c_gate_ctrl(fe, 0); |
2560 | } |
2561 | |
2562 | stv0367cab_SetQamSize( |
2563 | state, |
2564 | SymbolRate: p->symbol_rate, |
2565 | QAMSize); |
2566 | |
2567 | stv0367cab_set_srate(state, |
2568 | adc_hz: cab_state->adc_clk, |
2569 | mclk_hz: cab_state->mclk, |
2570 | SymbolRate: p->symbol_rate, |
2571 | QAMSize); |
2572 | /* Search algorithm launch, [-1.1*RangeOffset, +1.1*RangeOffset] scan */ |
2573 | cab_state->state = stv0367cab_algo(state, p); |
2574 | return 0; |
2575 | } |
2576 | |
2577 | static int stv0367cab_get_frontend(struct dvb_frontend *fe, |
2578 | struct dtv_frontend_properties *p) |
2579 | { |
2580 | struct stv0367_state *state = fe->demodulator_priv; |
2581 | struct stv0367cab_state *cab_state = state->cab_state; |
2582 | u32 ifkhz = 0; |
2583 | |
2584 | enum stv0367cab_mod QAMSize; |
2585 | |
2586 | dprintk("%s:\n" , __func__); |
2587 | |
2588 | stv0367_get_if_khz(state, ifkhz: &ifkhz); |
2589 | p->symbol_rate = stv0367cab_GetSymbolRate(state, mclk_hz: cab_state->mclk); |
2590 | |
2591 | QAMSize = stv0367_readbits(state, F367CAB_QAM_MODE); |
2592 | switch (QAMSize) { |
2593 | case FE_CAB_MOD_QAM16: |
2594 | p->modulation = QAM_16; |
2595 | break; |
2596 | case FE_CAB_MOD_QAM32: |
2597 | p->modulation = QAM_32; |
2598 | break; |
2599 | case FE_CAB_MOD_QAM64: |
2600 | p->modulation = QAM_64; |
2601 | break; |
2602 | case FE_CAB_MOD_QAM128: |
2603 | p->modulation = QAM_128; |
2604 | break; |
2605 | case FE_CAB_MOD_QAM256: |
2606 | p->modulation = QAM_256; |
2607 | break; |
2608 | default: |
2609 | break; |
2610 | } |
2611 | |
2612 | p->frequency = stv0367_get_tuner_freq(fe); |
2613 | |
2614 | dprintk("%s: tuner frequency = %d\n" , __func__, p->frequency); |
2615 | |
2616 | if (ifkhz == 0) { |
2617 | p->frequency += |
2618 | (stv0367cab_get_derot_freq(state, adc_hz: cab_state->adc_clk) - |
2619 | cab_state->adc_clk / 4000); |
2620 | return 0; |
2621 | } |
2622 | |
2623 | if (ifkhz > cab_state->adc_clk / 1000) |
2624 | p->frequency += (ifkhz |
2625 | - stv0367cab_get_derot_freq(state, adc_hz: cab_state->adc_clk) |
2626 | - cab_state->adc_clk / 1000); |
2627 | else |
2628 | p->frequency += (ifkhz |
2629 | - stv0367cab_get_derot_freq(state, adc_hz: cab_state->adc_clk)); |
2630 | |
2631 | return 0; |
2632 | } |
2633 | |
2634 | #if 0 |
2635 | void stv0367cab_GetErrorCount(state, enum stv0367cab_mod QAMSize, |
2636 | u32 symbol_rate, FE_367qam_Monitor *Monitor_results) |
2637 | { |
2638 | stv0367cab_OptimiseNByteAndGetBER(state, QAMSize, symbol_rate, Monitor_results); |
2639 | stv0367cab_GetPacketsCount(state, Monitor_results); |
2640 | |
2641 | return; |
2642 | } |
2643 | |
2644 | static int stv0367cab_read_ber(struct dvb_frontend *fe, u32 *ber) |
2645 | { |
2646 | struct stv0367_state *state = fe->demodulator_priv; |
2647 | |
2648 | return 0; |
2649 | } |
2650 | #endif |
2651 | static s32 stv0367cab_get_rf_lvl(struct stv0367_state *state) |
2652 | { |
2653 | s32 rfLevel = 0; |
2654 | s32 RfAgcPwm = 0, IfAgcPwm = 0; |
2655 | u8 i; |
2656 | |
2657 | stv0367_writebits(state, F367CAB_STDBY_ADCGP, val: 0x0); |
2658 | |
2659 | RfAgcPwm = |
2660 | (stv0367_readbits(state, F367CAB_RF_AGC1_LEVEL_LO) & 0x03) + |
2661 | (stv0367_readbits(state, F367CAB_RF_AGC1_LEVEL_HI) << 2); |
2662 | RfAgcPwm = 100 * RfAgcPwm / 1023; |
2663 | |
2664 | IfAgcPwm = |
2665 | stv0367_readbits(state, F367CAB_AGC_IF_PWMCMD_LO) + |
2666 | (stv0367_readbits(state, F367CAB_AGC_IF_PWMCMD_HI) << 8); |
2667 | if (IfAgcPwm >= 2048) |
2668 | IfAgcPwm -= 2048; |
2669 | else |
2670 | IfAgcPwm += 2048; |
2671 | |
2672 | IfAgcPwm = 100 * IfAgcPwm / 4095; |
2673 | |
2674 | /* For DTT75467 on NIM */ |
2675 | if (RfAgcPwm < 90 && IfAgcPwm < 28) { |
2676 | for (i = 0; i < RF_LOOKUP_TABLE_SIZE; i++) { |
2677 | if (RfAgcPwm <= stv0367cab_RF_LookUp1[0][i]) { |
2678 | rfLevel = (-1) * stv0367cab_RF_LookUp1[1][i]; |
2679 | break; |
2680 | } |
2681 | } |
2682 | if (i == RF_LOOKUP_TABLE_SIZE) |
2683 | rfLevel = -56; |
2684 | } else { /*if IF AGC>10*/ |
2685 | for (i = 0; i < RF_LOOKUP_TABLE2_SIZE; i++) { |
2686 | if (IfAgcPwm <= stv0367cab_RF_LookUp2[0][i]) { |
2687 | rfLevel = (-1) * stv0367cab_RF_LookUp2[1][i]; |
2688 | break; |
2689 | } |
2690 | } |
2691 | if (i == RF_LOOKUP_TABLE2_SIZE) |
2692 | rfLevel = -72; |
2693 | } |
2694 | return rfLevel; |
2695 | } |
2696 | |
2697 | static int stv0367cab_read_strength(struct dvb_frontend *fe, u16 *strength) |
2698 | { |
2699 | struct stv0367_state *state = fe->demodulator_priv; |
2700 | |
2701 | s32 signal = stv0367cab_get_rf_lvl(state); |
2702 | |
2703 | dprintk("%s: signal=%d dBm\n" , __func__, signal); |
2704 | |
2705 | if (signal <= -72) |
2706 | *strength = 65535; |
2707 | else |
2708 | *strength = (22 + signal) * (-1311); |
2709 | |
2710 | dprintk("%s: strength=%d\n" , __func__, (*strength)); |
2711 | |
2712 | return 0; |
2713 | } |
2714 | |
2715 | static int stv0367cab_snr_power(struct dvb_frontend *fe) |
2716 | { |
2717 | struct stv0367_state *state = fe->demodulator_priv; |
2718 | enum stv0367cab_mod QAMSize; |
2719 | |
2720 | QAMSize = stv0367_readbits(state, F367CAB_QAM_MODE); |
2721 | switch (QAMSize) { |
2722 | case FE_CAB_MOD_QAM4: |
2723 | return 21904; |
2724 | case FE_CAB_MOD_QAM16: |
2725 | return 20480; |
2726 | case FE_CAB_MOD_QAM32: |
2727 | return 23040; |
2728 | case FE_CAB_MOD_QAM64: |
2729 | return 21504; |
2730 | case FE_CAB_MOD_QAM128: |
2731 | return 23616; |
2732 | case FE_CAB_MOD_QAM256: |
2733 | return 21760; |
2734 | case FE_CAB_MOD_QAM1024: |
2735 | return 21280; |
2736 | default: |
2737 | break; |
2738 | } |
2739 | |
2740 | return 1; |
2741 | } |
2742 | |
2743 | static int stv0367cab_snr_readreg(struct dvb_frontend *fe, int avgdiv) |
2744 | { |
2745 | struct stv0367_state *state = fe->demodulator_priv; |
2746 | u32 regval = 0; |
2747 | int i; |
2748 | |
2749 | for (i = 0; i < 10; i++) { |
2750 | regval += (stv0367_readbits(state, F367CAB_SNR_LO) |
2751 | + 256 * stv0367_readbits(state, F367CAB_SNR_HI)); |
2752 | } |
2753 | |
2754 | if (avgdiv) |
2755 | regval /= 10; |
2756 | |
2757 | return regval; |
2758 | } |
2759 | |
2760 | static int stv0367cab_read_snr(struct dvb_frontend *fe, u16 *snr) |
2761 | { |
2762 | struct stv0367_state *state = fe->demodulator_priv; |
2763 | u32 noisepercentage; |
2764 | u32 regval = 0, temp = 0; |
2765 | int power; |
2766 | |
2767 | power = stv0367cab_snr_power(fe); |
2768 | regval = stv0367cab_snr_readreg(fe, avgdiv: 1); |
2769 | |
2770 | if (regval != 0) { |
2771 | temp = power |
2772 | * (1 << (3 + stv0367_readbits(state, F367CAB_SNR_PER))); |
2773 | temp /= regval; |
2774 | } |
2775 | |
2776 | /* table values, not needed to calculate logarithms */ |
2777 | if (temp >= 5012) |
2778 | noisepercentage = 100; |
2779 | else if (temp >= 3981) |
2780 | noisepercentage = 93; |
2781 | else if (temp >= 3162) |
2782 | noisepercentage = 86; |
2783 | else if (temp >= 2512) |
2784 | noisepercentage = 79; |
2785 | else if (temp >= 1995) |
2786 | noisepercentage = 72; |
2787 | else if (temp >= 1585) |
2788 | noisepercentage = 65; |
2789 | else if (temp >= 1259) |
2790 | noisepercentage = 58; |
2791 | else if (temp >= 1000) |
2792 | noisepercentage = 50; |
2793 | else if (temp >= 794) |
2794 | noisepercentage = 43; |
2795 | else if (temp >= 501) |
2796 | noisepercentage = 36; |
2797 | else if (temp >= 316) |
2798 | noisepercentage = 29; |
2799 | else if (temp >= 200) |
2800 | noisepercentage = 22; |
2801 | else if (temp >= 158) |
2802 | noisepercentage = 14; |
2803 | else if (temp >= 126) |
2804 | noisepercentage = 7; |
2805 | else |
2806 | noisepercentage = 0; |
2807 | |
2808 | dprintk("%s: noisepercentage=%d\n" , __func__, noisepercentage); |
2809 | |
2810 | *snr = (noisepercentage * 65535) / 100; |
2811 | |
2812 | return 0; |
2813 | } |
2814 | |
2815 | static int stv0367cab_read_ucblcks(struct dvb_frontend *fe, u32 *ucblocks) |
2816 | { |
2817 | struct stv0367_state *state = fe->demodulator_priv; |
2818 | int corrected, tscount; |
2819 | |
2820 | *ucblocks = (stv0367_readreg(state, R367CAB_RS_COUNTER_5) << 8) |
2821 | | stv0367_readreg(state, R367CAB_RS_COUNTER_4); |
2822 | corrected = (stv0367_readreg(state, R367CAB_RS_COUNTER_3) << 8) |
2823 | | stv0367_readreg(state, R367CAB_RS_COUNTER_2); |
2824 | tscount = (stv0367_readreg(state, R367CAB_RS_COUNTER_2) << 8) |
2825 | | stv0367_readreg(state, R367CAB_RS_COUNTER_1); |
2826 | |
2827 | dprintk("%s: uncorrected blocks=%d corrected blocks=%d tscount=%d\n" , |
2828 | __func__, *ucblocks, corrected, tscount); |
2829 | |
2830 | return 0; |
2831 | }; |
2832 | |
2833 | static const struct dvb_frontend_ops stv0367cab_ops = { |
2834 | .delsys = { SYS_DVBC_ANNEX_A }, |
2835 | .info = { |
2836 | .name = "ST STV0367 DVB-C" , |
2837 | .frequency_min_hz = 47 * MHz, |
2838 | .frequency_max_hz = 862 * MHz, |
2839 | .frequency_stepsize_hz = 62500, |
2840 | .symbol_rate_min = 870000, |
2841 | .symbol_rate_max = 11700000, |
2842 | .caps = 0x400 |/* FE_CAN_QAM_4 */ |
2843 | FE_CAN_QAM_16 | FE_CAN_QAM_32 | |
2844 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | |
2845 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO |
2846 | }, |
2847 | .release = stv0367_release, |
2848 | .init = stv0367cab_init, |
2849 | .sleep = stv0367cab_sleep, |
2850 | .i2c_gate_ctrl = stv0367cab_gate_ctrl, |
2851 | .set_frontend = stv0367cab_set_frontend, |
2852 | .get_frontend = stv0367cab_get_frontend, |
2853 | .read_status = stv0367cab_read_status, |
2854 | /* .read_ber = stv0367cab_read_ber, */ |
2855 | .read_signal_strength = stv0367cab_read_strength, |
2856 | .read_snr = stv0367cab_read_snr, |
2857 | .read_ucblocks = stv0367cab_read_ucblcks, |
2858 | .get_tune_settings = stv0367_get_tune_settings, |
2859 | }; |
2860 | |
2861 | struct dvb_frontend *stv0367cab_attach(const struct stv0367_config *config, |
2862 | struct i2c_adapter *i2c) |
2863 | { |
2864 | struct stv0367_state *state = NULL; |
2865 | struct stv0367cab_state *cab_state = NULL; |
2866 | |
2867 | /* allocate memory for the internal state */ |
2868 | state = kzalloc(size: sizeof(struct stv0367_state), GFP_KERNEL); |
2869 | if (state == NULL) |
2870 | goto error; |
2871 | cab_state = kzalloc(size: sizeof(struct stv0367cab_state), GFP_KERNEL); |
2872 | if (cab_state == NULL) |
2873 | goto error; |
2874 | |
2875 | /* setup the state */ |
2876 | state->i2c = i2c; |
2877 | state->config = config; |
2878 | cab_state->search_range = 280000; |
2879 | cab_state->qamfec_status_reg = F367CAB_QAMFEC_LOCK; |
2880 | state->cab_state = cab_state; |
2881 | state->fe.ops = stv0367cab_ops; |
2882 | state->fe.demodulator_priv = state; |
2883 | state->chip_id = stv0367_readreg(state, reg: 0xf000); |
2884 | |
2885 | /* demod operation options */ |
2886 | state->use_i2c_gatectrl = 1; |
2887 | state->deftabs = STV0367_DEFTAB_GENERIC; |
2888 | state->reinit_on_setfrontend = 1; |
2889 | state->auto_if_khz = 0; |
2890 | |
2891 | dprintk("%s: chip_id = 0x%x\n" , __func__, state->chip_id); |
2892 | |
2893 | /* check if the demod is there */ |
2894 | if ((state->chip_id != 0x50) && (state->chip_id != 0x60)) |
2895 | goto error; |
2896 | |
2897 | return &state->fe; |
2898 | |
2899 | error: |
2900 | kfree(objp: cab_state); |
2901 | kfree(objp: state); |
2902 | return NULL; |
2903 | } |
2904 | EXPORT_SYMBOL_GPL(stv0367cab_attach); |
2905 | |
2906 | /* |
2907 | * Functions for operation on Digital Devices hardware |
2908 | */ |
2909 | |
2910 | static void stv0367ddb_setup_ter(struct stv0367_state *state) |
2911 | { |
2912 | stv0367_writereg(state, R367TER_DEBUG_LT4, data: 0x00); |
2913 | stv0367_writereg(state, R367TER_DEBUG_LT5, data: 0x00); |
2914 | stv0367_writereg(state, R367TER_DEBUG_LT6, data: 0x00); /* R367CAB_CTRL_1 */ |
2915 | stv0367_writereg(state, R367TER_DEBUG_LT7, data: 0x00); /* R367CAB_CTRL_2 */ |
2916 | stv0367_writereg(state, R367TER_DEBUG_LT8, data: 0x00); |
2917 | stv0367_writereg(state, R367TER_DEBUG_LT9, data: 0x00); |
2918 | |
2919 | /* Tuner Setup */ |
2920 | /* Buffer Q disabled, I Enabled, unsigned ADC */ |
2921 | stv0367_writereg(state, R367TER_ANADIGCTRL, data: 0x89); |
2922 | stv0367_writereg(state, R367TER_DUAL_AD12, data: 0x04); /* ADCQ disabled */ |
2923 | |
2924 | /* Clock setup */ |
2925 | /* PLL bypassed and disabled */ |
2926 | stv0367_writereg(state, R367TER_ANACTRL, data: 0x0D); |
2927 | stv0367_writereg(state, R367TER_TOPCTRL, data: 0x00); /* Set OFDM */ |
2928 | |
2929 | /* IC runs at 54 MHz with a 27 MHz crystal */ |
2930 | stv0367_pll_setup(state, STV0367_ICSPEED_53125, xtal: state->config->xtal); |
2931 | |
2932 | msleep(msecs: 50); |
2933 | /* PLL enabled and used */ |
2934 | stv0367_writereg(state, R367TER_ANACTRL, data: 0x00); |
2935 | |
2936 | state->activedemod = demod_ter; |
2937 | } |
2938 | |
2939 | static void stv0367ddb_setup_cab(struct stv0367_state *state) |
2940 | { |
2941 | stv0367_writereg(state, R367TER_DEBUG_LT4, data: 0x00); |
2942 | stv0367_writereg(state, R367TER_DEBUG_LT5, data: 0x01); |
2943 | stv0367_writereg(state, R367TER_DEBUG_LT6, data: 0x06); /* R367CAB_CTRL_1 */ |
2944 | stv0367_writereg(state, R367TER_DEBUG_LT7, data: 0x03); /* R367CAB_CTRL_2 */ |
2945 | stv0367_writereg(state, R367TER_DEBUG_LT8, data: 0x00); |
2946 | stv0367_writereg(state, R367TER_DEBUG_LT9, data: 0x00); |
2947 | |
2948 | /* Tuner Setup */ |
2949 | /* Buffer Q disabled, I Enabled, signed ADC */ |
2950 | stv0367_writereg(state, R367TER_ANADIGCTRL, data: 0x8B); |
2951 | /* ADCQ disabled */ |
2952 | stv0367_writereg(state, R367TER_DUAL_AD12, data: 0x04); |
2953 | |
2954 | /* Clock setup */ |
2955 | /* PLL bypassed and disabled */ |
2956 | stv0367_writereg(state, R367TER_ANACTRL, data: 0x0D); |
2957 | /* Set QAM */ |
2958 | stv0367_writereg(state, R367TER_TOPCTRL, data: 0x10); |
2959 | |
2960 | /* IC runs at 58 MHz with a 27 MHz crystal */ |
2961 | stv0367_pll_setup(state, STV0367_ICSPEED_58000, xtal: state->config->xtal); |
2962 | |
2963 | msleep(msecs: 50); |
2964 | /* PLL enabled and used */ |
2965 | stv0367_writereg(state, R367TER_ANACTRL, data: 0x00); |
2966 | |
2967 | state->cab_state->mclk = stv0367cab_get_mclk(fe: &state->fe, |
2968 | ExtClk_Hz: state->config->xtal); |
2969 | state->cab_state->adc_clk = stv0367cab_get_adc_freq(fe: &state->fe, |
2970 | ExtClk_Hz: state->config->xtal); |
2971 | |
2972 | state->activedemod = demod_cab; |
2973 | } |
2974 | |
2975 | static int stv0367ddb_set_frontend(struct dvb_frontend *fe) |
2976 | { |
2977 | struct stv0367_state *state = fe->demodulator_priv; |
2978 | |
2979 | switch (fe->dtv_property_cache.delivery_system) { |
2980 | case SYS_DVBT: |
2981 | if (state->activedemod != demod_ter) |
2982 | stv0367ddb_setup_ter(state); |
2983 | |
2984 | return stv0367ter_set_frontend(fe); |
2985 | case SYS_DVBC_ANNEX_A: |
2986 | if (state->activedemod != demod_cab) |
2987 | stv0367ddb_setup_cab(state); |
2988 | |
2989 | /* protect against division error oopses */ |
2990 | if (fe->dtv_property_cache.symbol_rate == 0) { |
2991 | printk(KERN_ERR "Invalid symbol rate\n" ); |
2992 | return -EINVAL; |
2993 | } |
2994 | |
2995 | return stv0367cab_set_frontend(fe); |
2996 | default: |
2997 | break; |
2998 | } |
2999 | |
3000 | return -EINVAL; |
3001 | } |
3002 | |
3003 | static void stv0367ddb_read_signal_strength(struct dvb_frontend *fe) |
3004 | { |
3005 | struct stv0367_state *state = fe->demodulator_priv; |
3006 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; |
3007 | s32 signalstrength; |
3008 | |
3009 | switch (state->activedemod) { |
3010 | case demod_cab: |
3011 | signalstrength = stv0367cab_get_rf_lvl(state) * 1000; |
3012 | break; |
3013 | default: |
3014 | p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; |
3015 | return; |
3016 | } |
3017 | |
3018 | p->strength.stat[0].scale = FE_SCALE_DECIBEL; |
3019 | p->strength.stat[0].uvalue = signalstrength; |
3020 | } |
3021 | |
3022 | static void stv0367ddb_read_snr(struct dvb_frontend *fe) |
3023 | { |
3024 | struct stv0367_state *state = fe->demodulator_priv; |
3025 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; |
3026 | int cab_pwr; |
3027 | u32 regval, tmpval, snrval = 0; |
3028 | |
3029 | switch (state->activedemod) { |
3030 | case demod_ter: |
3031 | snrval = stv0367ter_snr_readreg(fe); |
3032 | break; |
3033 | case demod_cab: |
3034 | cab_pwr = stv0367cab_snr_power(fe); |
3035 | regval = stv0367cab_snr_readreg(fe, avgdiv: 0); |
3036 | |
3037 | /* prevent division by zero */ |
3038 | if (!regval) { |
3039 | snrval = 0; |
3040 | break; |
3041 | } |
3042 | |
3043 | tmpval = (cab_pwr * 320) / regval; |
3044 | snrval = ((tmpval != 0) ? (intlog2(value: tmpval) / 5581) : 0); |
3045 | break; |
3046 | default: |
3047 | p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; |
3048 | return; |
3049 | } |
3050 | |
3051 | p->cnr.stat[0].scale = FE_SCALE_DECIBEL; |
3052 | p->cnr.stat[0].uvalue = snrval; |
3053 | } |
3054 | |
3055 | static void stv0367ddb_read_ucblocks(struct dvb_frontend *fe) |
3056 | { |
3057 | struct stv0367_state *state = fe->demodulator_priv; |
3058 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; |
3059 | u32 ucblocks = 0; |
3060 | |
3061 | switch (state->activedemod) { |
3062 | case demod_ter: |
3063 | stv0367ter_read_ucblocks(fe, ucblocks: &ucblocks); |
3064 | break; |
3065 | case demod_cab: |
3066 | stv0367cab_read_ucblcks(fe, ucblocks: &ucblocks); |
3067 | break; |
3068 | default: |
3069 | p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; |
3070 | return; |
3071 | } |
3072 | |
3073 | p->block_error.stat[0].scale = FE_SCALE_COUNTER; |
3074 | p->block_error.stat[0].uvalue = ucblocks; |
3075 | } |
3076 | |
3077 | static int stv0367ddb_read_status(struct dvb_frontend *fe, |
3078 | enum fe_status *status) |
3079 | { |
3080 | struct stv0367_state *state = fe->demodulator_priv; |
3081 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; |
3082 | int ret = 0; |
3083 | |
3084 | switch (state->activedemod) { |
3085 | case demod_ter: |
3086 | ret = stv0367ter_read_status(fe, status); |
3087 | break; |
3088 | case demod_cab: |
3089 | ret = stv0367cab_read_status(fe, status); |
3090 | break; |
3091 | default: |
3092 | break; |
3093 | } |
3094 | |
3095 | /* stop and report on *_read_status failure */ |
3096 | if (ret) |
3097 | return ret; |
3098 | |
3099 | stv0367ddb_read_signal_strength(fe); |
3100 | |
3101 | /* read carrier/noise when a carrier is detected */ |
3102 | if (*status & FE_HAS_CARRIER) |
3103 | stv0367ddb_read_snr(fe); |
3104 | else |
3105 | p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; |
3106 | |
3107 | /* read uncorrected blocks on FE_HAS_LOCK */ |
3108 | if (*status & FE_HAS_LOCK) |
3109 | stv0367ddb_read_ucblocks(fe); |
3110 | else |
3111 | p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; |
3112 | |
3113 | return 0; |
3114 | } |
3115 | |
3116 | static int stv0367ddb_get_frontend(struct dvb_frontend *fe, |
3117 | struct dtv_frontend_properties *p) |
3118 | { |
3119 | struct stv0367_state *state = fe->demodulator_priv; |
3120 | |
3121 | switch (state->activedemod) { |
3122 | case demod_ter: |
3123 | return stv0367ter_get_frontend(fe, p); |
3124 | case demod_cab: |
3125 | return stv0367cab_get_frontend(fe, p); |
3126 | default: |
3127 | break; |
3128 | } |
3129 | |
3130 | return 0; |
3131 | } |
3132 | |
3133 | static int stv0367ddb_sleep(struct dvb_frontend *fe) |
3134 | { |
3135 | struct stv0367_state *state = fe->demodulator_priv; |
3136 | |
3137 | switch (state->activedemod) { |
3138 | case demod_ter: |
3139 | state->activedemod = demod_none; |
3140 | return stv0367ter_sleep(fe); |
3141 | case demod_cab: |
3142 | state->activedemod = demod_none; |
3143 | return stv0367cab_sleep(fe); |
3144 | default: |
3145 | break; |
3146 | } |
3147 | |
3148 | return -EINVAL; |
3149 | } |
3150 | |
3151 | static int stv0367ddb_init(struct stv0367_state *state) |
3152 | { |
3153 | struct stv0367ter_state *ter_state = state->ter_state; |
3154 | struct dtv_frontend_properties *p = &state->fe.dtv_property_cache; |
3155 | |
3156 | stv0367_writereg(state, R367TER_TOPCTRL, data: 0x10); |
3157 | |
3158 | if (stv0367_deftabs[state->deftabs][STV0367_TAB_BASE]) |
3159 | stv0367_write_table(state, |
3160 | deftab: stv0367_deftabs[state->deftabs][STV0367_TAB_BASE]); |
3161 | |
3162 | stv0367_write_table(state, |
3163 | deftab: stv0367_deftabs[state->deftabs][STV0367_TAB_CAB]); |
3164 | |
3165 | stv0367_writereg(state, R367TER_TOPCTRL, data: 0x00); |
3166 | stv0367_write_table(state, |
3167 | deftab: stv0367_deftabs[state->deftabs][STV0367_TAB_TER]); |
3168 | |
3169 | stv0367_writereg(state, R367TER_GAIN_SRC1, data: 0x2A); |
3170 | stv0367_writereg(state, R367TER_GAIN_SRC2, data: 0xD6); |
3171 | stv0367_writereg(state, R367TER_INC_DEROT1, data: 0x55); |
3172 | stv0367_writereg(state, R367TER_INC_DEROT2, data: 0x55); |
3173 | stv0367_writereg(state, R367TER_TRL_CTL, data: 0x14); |
3174 | stv0367_writereg(state, R367TER_TRL_NOMRATE1, data: 0xAE); |
3175 | stv0367_writereg(state, R367TER_TRL_NOMRATE2, data: 0x56); |
3176 | stv0367_writereg(state, R367TER_FEPATH_CFG, data: 0x0); |
3177 | |
3178 | /* OFDM TS Setup */ |
3179 | |
3180 | stv0367_writereg(state, R367TER_TSCFGH, data: 0x70); |
3181 | stv0367_writereg(state, R367TER_TSCFGM, data: 0xC0); |
3182 | stv0367_writereg(state, R367TER_TSCFGL, data: 0x20); |
3183 | stv0367_writereg(state, R367TER_TSSPEED, data: 0x40); /* Fixed at 54 MHz */ |
3184 | |
3185 | stv0367_writereg(state, R367TER_TSCFGH, data: 0x71); |
3186 | stv0367_writereg(state, R367TER_TSCFGH, data: 0x70); |
3187 | |
3188 | stv0367_writereg(state, R367TER_TOPCTRL, data: 0x10); |
3189 | |
3190 | /* Also needed for QAM */ |
3191 | stv0367_writereg(state, R367TER_AGC12C, data: 0x01); /* AGC Pin setup */ |
3192 | |
3193 | stv0367_writereg(state, R367TER_AGCCTRL1, data: 0x8A); |
3194 | |
3195 | /* QAM TS setup, note exact format also depends on descrambler */ |
3196 | /* settings */ |
3197 | /* Inverted Clock, Swap, serial */ |
3198 | stv0367_writereg(state, R367CAB_OUTFORMAT_0, data: 0x85); |
3199 | |
3200 | /* Clock setup (PLL bypassed and disabled) */ |
3201 | stv0367_writereg(state, R367TER_ANACTRL, data: 0x0D); |
3202 | |
3203 | /* IC runs at 58 MHz with a 27 MHz crystal */ |
3204 | stv0367_pll_setup(state, STV0367_ICSPEED_58000, xtal: state->config->xtal); |
3205 | |
3206 | /* Tuner setup */ |
3207 | /* Buffer Q disabled, I Enabled, signed ADC */ |
3208 | stv0367_writereg(state, R367TER_ANADIGCTRL, data: 0x8b); |
3209 | stv0367_writereg(state, R367TER_DUAL_AD12, data: 0x04); /* ADCQ disabled */ |
3210 | |
3211 | /* Improves the C/N lock limit */ |
3212 | stv0367_writereg(state, R367CAB_FSM_SNR2_HTH, data: 0x23); |
3213 | /* ZIF/IF Automatic mode */ |
3214 | stv0367_writereg(state, R367CAB_IQ_QAM, data: 0x01); |
3215 | /* Improving burst noise performances */ |
3216 | stv0367_writereg(state, R367CAB_EQU_FFE_LEAKAGE, data: 0x83); |
3217 | /* Improving ACI performances */ |
3218 | stv0367_writereg(state, R367CAB_IQDEM_ADJ_EN, data: 0x05); |
3219 | |
3220 | /* PLL enabled and used */ |
3221 | stv0367_writereg(state, R367TER_ANACTRL, data: 0x00); |
3222 | |
3223 | stv0367_writereg(state, R367TER_I2CRPT, data: (0x08 | ((5 & 0x07) << 4))); |
3224 | |
3225 | ter_state->pBER = 0; |
3226 | ter_state->first_lock = 0; |
3227 | ter_state->unlock_counter = 2; |
3228 | |
3229 | p->strength.len = 1; |
3230 | p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; |
3231 | p->cnr.len = 1; |
3232 | p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; |
3233 | p->block_error.len = 1; |
3234 | p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; |
3235 | |
3236 | return 0; |
3237 | } |
3238 | |
3239 | static const struct dvb_frontend_ops stv0367ddb_ops = { |
3240 | .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBT }, |
3241 | .info = { |
3242 | .name = "ST STV0367 DDB DVB-C/T" , |
3243 | .frequency_min_hz = 47 * MHz, |
3244 | .frequency_max_hz = 865 * MHz, |
3245 | .frequency_stepsize_hz = 166667, |
3246 | .symbol_rate_min = 870000, |
3247 | .symbol_rate_max = 11700000, |
3248 | .caps = /* DVB-C */ |
3249 | 0x400 |/* FE_CAN_QAM_4 */ |
3250 | FE_CAN_QAM_16 | FE_CAN_QAM_32 | |
3251 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | |
3252 | FE_CAN_QAM_256 | |
3253 | /* DVB-T */ |
3254 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | |
3255 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | |
3256 | FE_CAN_QPSK | FE_CAN_TRANSMISSION_MODE_AUTO | |
3257 | FE_CAN_RECOVER | FE_CAN_INVERSION_AUTO | |
3258 | FE_CAN_MUTE_TS |
3259 | }, |
3260 | .release = stv0367_release, |
3261 | .sleep = stv0367ddb_sleep, |
3262 | .i2c_gate_ctrl = stv0367cab_gate_ctrl, /* valid for TER and CAB */ |
3263 | .set_frontend = stv0367ddb_set_frontend, |
3264 | .get_frontend = stv0367ddb_get_frontend, |
3265 | .get_tune_settings = stv0367_get_tune_settings, |
3266 | .read_status = stv0367ddb_read_status, |
3267 | }; |
3268 | |
3269 | struct dvb_frontend *stv0367ddb_attach(const struct stv0367_config *config, |
3270 | struct i2c_adapter *i2c) |
3271 | { |
3272 | struct stv0367_state *state = NULL; |
3273 | struct stv0367ter_state *ter_state = NULL; |
3274 | struct stv0367cab_state *cab_state = NULL; |
3275 | |
3276 | /* allocate memory for the internal state */ |
3277 | state = kzalloc(size: sizeof(struct stv0367_state), GFP_KERNEL); |
3278 | if (state == NULL) |
3279 | goto error; |
3280 | ter_state = kzalloc(size: sizeof(struct stv0367ter_state), GFP_KERNEL); |
3281 | if (ter_state == NULL) |
3282 | goto error; |
3283 | cab_state = kzalloc(size: sizeof(struct stv0367cab_state), GFP_KERNEL); |
3284 | if (cab_state == NULL) |
3285 | goto error; |
3286 | |
3287 | /* setup the state */ |
3288 | state->i2c = i2c; |
3289 | state->config = config; |
3290 | state->ter_state = ter_state; |
3291 | cab_state->search_range = 280000; |
3292 | cab_state->qamfec_status_reg = F367CAB_DESCR_SYNCSTATE; |
3293 | state->cab_state = cab_state; |
3294 | state->fe.ops = stv0367ddb_ops; |
3295 | state->fe.demodulator_priv = state; |
3296 | state->chip_id = stv0367_readreg(state, R367TER_ID); |
3297 | |
3298 | /* demod operation options */ |
3299 | state->use_i2c_gatectrl = 0; |
3300 | state->deftabs = STV0367_DEFTAB_DDB; |
3301 | state->reinit_on_setfrontend = 0; |
3302 | state->auto_if_khz = 1; |
3303 | state->activedemod = demod_none; |
3304 | |
3305 | dprintk("%s: chip_id = 0x%x\n" , __func__, state->chip_id); |
3306 | |
3307 | /* check if the demod is there */ |
3308 | if ((state->chip_id != 0x50) && (state->chip_id != 0x60)) |
3309 | goto error; |
3310 | |
3311 | dev_info(&i2c->dev, "Found %s with ChipID %02X at adr %02X\n" , |
3312 | state->fe.ops.info.name, state->chip_id, |
3313 | config->demod_address); |
3314 | |
3315 | stv0367ddb_init(state); |
3316 | |
3317 | return &state->fe; |
3318 | |
3319 | error: |
3320 | kfree(objp: cab_state); |
3321 | kfree(objp: ter_state); |
3322 | kfree(objp: state); |
3323 | return NULL; |
3324 | } |
3325 | EXPORT_SYMBOL_GPL(stv0367ddb_attach); |
3326 | |
3327 | MODULE_PARM_DESC(debug, "Set debug" ); |
3328 | MODULE_PARM_DESC(i2c_debug, "Set i2c debug" ); |
3329 | |
3330 | MODULE_AUTHOR("Igor M. Liplianin" ); |
3331 | MODULE_DESCRIPTION("ST STV0367 DVB-C/T demodulator driver" ); |
3332 | MODULE_LICENSE("GPL" ); |
3333 | |