1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * stv0900_core.c |
4 | * |
5 | * Driver for ST STV0900 satellite demodulator IC. |
6 | * |
7 | * Copyright (C) ST Microelectronics. |
8 | * Copyright (C) 2009 NetUP Inc. |
9 | * Copyright (C) 2009 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 "stv0900.h" |
19 | #include "stv0900_reg.h" |
20 | #include "stv0900_priv.h" |
21 | #include "stv0900_init.h" |
22 | |
23 | int stvdebug = 1; |
24 | module_param_named(debug, stvdebug, int, 0644); |
25 | |
26 | /* internal params node */ |
27 | struct stv0900_inode { |
28 | /* pointer for internal params, one for each pair of demods */ |
29 | struct stv0900_internal *internal; |
30 | struct stv0900_inode *next_inode; |
31 | }; |
32 | |
33 | /* first internal params */ |
34 | static struct stv0900_inode *stv0900_first_inode; |
35 | |
36 | /* find chip by i2c adapter and i2c address */ |
37 | static struct stv0900_inode *find_inode(struct i2c_adapter *i2c_adap, |
38 | u8 i2c_addr) |
39 | { |
40 | struct stv0900_inode *temp_chip = stv0900_first_inode; |
41 | |
42 | if (temp_chip != NULL) { |
43 | /* |
44 | Search of the last stv0900 chip or |
45 | find it by i2c adapter and i2c address */ |
46 | while ((temp_chip != NULL) && |
47 | ((temp_chip->internal->i2c_adap != i2c_adap) || |
48 | (temp_chip->internal->i2c_addr != i2c_addr))) |
49 | |
50 | temp_chip = temp_chip->next_inode; |
51 | |
52 | } |
53 | |
54 | return temp_chip; |
55 | } |
56 | |
57 | /* deallocating chip */ |
58 | static void remove_inode(struct stv0900_internal *internal) |
59 | { |
60 | struct stv0900_inode *prev_node = stv0900_first_inode; |
61 | struct stv0900_inode *del_node = find_inode(i2c_adap: internal->i2c_adap, |
62 | i2c_addr: internal->i2c_addr); |
63 | |
64 | if (del_node != NULL) { |
65 | if (del_node == stv0900_first_inode) { |
66 | stv0900_first_inode = del_node->next_inode; |
67 | } else { |
68 | while (prev_node->next_inode != del_node) |
69 | prev_node = prev_node->next_inode; |
70 | |
71 | if (del_node->next_inode == NULL) |
72 | prev_node->next_inode = NULL; |
73 | else |
74 | prev_node->next_inode = |
75 | prev_node->next_inode->next_inode; |
76 | } |
77 | |
78 | kfree(objp: del_node); |
79 | } |
80 | } |
81 | |
82 | /* allocating new chip */ |
83 | static struct stv0900_inode *append_internal(struct stv0900_internal *internal) |
84 | { |
85 | struct stv0900_inode *new_node = stv0900_first_inode; |
86 | |
87 | if (new_node == NULL) { |
88 | new_node = kmalloc(size: sizeof(struct stv0900_inode), GFP_KERNEL); |
89 | stv0900_first_inode = new_node; |
90 | } else { |
91 | while (new_node->next_inode != NULL) |
92 | new_node = new_node->next_inode; |
93 | |
94 | new_node->next_inode = kmalloc(size: sizeof(struct stv0900_inode), |
95 | GFP_KERNEL); |
96 | if (new_node->next_inode != NULL) |
97 | new_node = new_node->next_inode; |
98 | else |
99 | new_node = NULL; |
100 | } |
101 | |
102 | if (new_node != NULL) { |
103 | new_node->internal = internal; |
104 | new_node->next_inode = NULL; |
105 | } |
106 | |
107 | return new_node; |
108 | } |
109 | |
110 | s32 ge2comp(s32 a, s32 width) |
111 | { |
112 | if (width == 32) |
113 | return a; |
114 | else |
115 | return (a >= (1 << (width - 1))) ? (a - (1 << width)) : a; |
116 | } |
117 | |
118 | void stv0900_write_reg(struct stv0900_internal *intp, u16 reg_addr, |
119 | u8 reg_data) |
120 | { |
121 | u8 data[3]; |
122 | int ret; |
123 | struct i2c_msg i2cmsg = { |
124 | .addr = intp->i2c_addr, |
125 | .flags = 0, |
126 | .len = 3, |
127 | .buf = data, |
128 | }; |
129 | |
130 | data[0] = MSB(reg_addr); |
131 | data[1] = LSB(reg_addr); |
132 | data[2] = reg_data; |
133 | |
134 | ret = i2c_transfer(adap: intp->i2c_adap, msgs: &i2cmsg, num: 1); |
135 | if (ret != 1) |
136 | dprintk("%s: i2c error %d\n" , __func__, ret); |
137 | } |
138 | |
139 | u8 stv0900_read_reg(struct stv0900_internal *intp, u16 reg) |
140 | { |
141 | int ret; |
142 | u8 b0[] = { MSB(reg), LSB(reg) }; |
143 | u8 buf = 0; |
144 | struct i2c_msg msg[] = { |
145 | { |
146 | .addr = intp->i2c_addr, |
147 | .flags = 0, |
148 | .buf = b0, |
149 | .len = 2, |
150 | }, { |
151 | .addr = intp->i2c_addr, |
152 | .flags = I2C_M_RD, |
153 | .buf = &buf, |
154 | .len = 1, |
155 | }, |
156 | }; |
157 | |
158 | ret = i2c_transfer(adap: intp->i2c_adap, msgs: msg, num: 2); |
159 | if (ret != 2) |
160 | dprintk("%s: i2c error %d, reg[0x%02x]\n" , |
161 | __func__, ret, reg); |
162 | |
163 | return buf; |
164 | } |
165 | |
166 | static void (u32 label, u8 *mask, u8 *pos) |
167 | { |
168 | u8 position = 0, i = 0; |
169 | |
170 | (*mask) = label & 0xff; |
171 | |
172 | while ((position == 0) && (i < 8)) { |
173 | position = ((*mask) >> i) & 0x01; |
174 | i++; |
175 | } |
176 | |
177 | (*pos) = (i - 1); |
178 | } |
179 | |
180 | void stv0900_write_bits(struct stv0900_internal *intp, u32 label, u8 val) |
181 | { |
182 | u8 reg, mask, pos; |
183 | |
184 | reg = stv0900_read_reg(intp, reg: (label >> 16) & 0xffff); |
185 | extract_mask_pos(label, mask: &mask, pos: &pos); |
186 | |
187 | val = mask & (val << pos); |
188 | |
189 | reg = (reg & (~mask)) | val; |
190 | stv0900_write_reg(intp, reg_addr: (label >> 16) & 0xffff, reg_data: reg); |
191 | |
192 | } |
193 | |
194 | u8 stv0900_get_bits(struct stv0900_internal *intp, u32 label) |
195 | { |
196 | u8 val; |
197 | u8 mask, pos; |
198 | |
199 | extract_mask_pos(label, mask: &mask, pos: &pos); |
200 | |
201 | val = stv0900_read_reg(intp, reg: label >> 16); |
202 | val = (val & mask) >> pos; |
203 | |
204 | return val; |
205 | } |
206 | |
207 | static enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *intp) |
208 | { |
209 | s32 i; |
210 | |
211 | if (intp == NULL) |
212 | return STV0900_INVALID_HANDLE; |
213 | |
214 | intp->chip_id = stv0900_read_reg(intp, R0900_MID); |
215 | |
216 | if (intp->errs != STV0900_NO_ERROR) |
217 | return intp->errs; |
218 | |
219 | /*Startup sequence*/ |
220 | stv0900_write_reg(intp, R0900_P1_DMDISTATE, reg_data: 0x5c); |
221 | stv0900_write_reg(intp, R0900_P2_DMDISTATE, reg_data: 0x5c); |
222 | msleep(msecs: 3); |
223 | stv0900_write_reg(intp, R0900_P1_TNRCFG, reg_data: 0x6c); |
224 | stv0900_write_reg(intp, R0900_P2_TNRCFG, reg_data: 0x6f); |
225 | stv0900_write_reg(intp, R0900_P1_I2CRPT, reg_data: 0x20); |
226 | stv0900_write_reg(intp, R0900_P2_I2CRPT, reg_data: 0x20); |
227 | stv0900_write_reg(intp, R0900_NCOARSE, reg_data: 0x13); |
228 | msleep(msecs: 3); |
229 | stv0900_write_reg(intp, R0900_I2CCFG, reg_data: 0x08); |
230 | |
231 | switch (intp->clkmode) { |
232 | case 0: |
233 | case 2: |
234 | stv0900_write_reg(intp, R0900_SYNTCTRL, reg_data: 0x20 |
235 | | intp->clkmode); |
236 | break; |
237 | default: |
238 | /* preserve SELOSCI bit */ |
239 | i = 0x02 & stv0900_read_reg(intp, R0900_SYNTCTRL); |
240 | stv0900_write_reg(intp, R0900_SYNTCTRL, reg_data: 0x20 | i); |
241 | break; |
242 | } |
243 | |
244 | msleep(msecs: 3); |
245 | for (i = 0; i < 181; i++) |
246 | stv0900_write_reg(intp, reg_addr: STV0900_InitVal[i][0], |
247 | reg_data: STV0900_InitVal[i][1]); |
248 | |
249 | if (stv0900_read_reg(intp, R0900_MID) >= 0x20) { |
250 | stv0900_write_reg(intp, R0900_TSGENERAL, reg_data: 0x0c); |
251 | for (i = 0; i < 32; i++) |
252 | stv0900_write_reg(intp, reg_addr: STV0900_Cut20_AddOnVal[i][0], |
253 | reg_data: STV0900_Cut20_AddOnVal[i][1]); |
254 | } |
255 | |
256 | stv0900_write_reg(intp, R0900_P1_FSPYCFG, reg_data: 0x6c); |
257 | stv0900_write_reg(intp, R0900_P2_FSPYCFG, reg_data: 0x6c); |
258 | |
259 | stv0900_write_reg(intp, R0900_P1_PDELCTRL2, reg_data: 0x01); |
260 | stv0900_write_reg(intp, R0900_P2_PDELCTRL2, reg_data: 0x21); |
261 | |
262 | stv0900_write_reg(intp, R0900_P1_PDELCTRL3, reg_data: 0x20); |
263 | stv0900_write_reg(intp, R0900_P2_PDELCTRL3, reg_data: 0x20); |
264 | |
265 | stv0900_write_reg(intp, R0900_TSTRES0, reg_data: 0x80); |
266 | stv0900_write_reg(intp, R0900_TSTRES0, reg_data: 0x00); |
267 | |
268 | return STV0900_NO_ERROR; |
269 | } |
270 | |
271 | static u32 stv0900_get_mclk_freq(struct stv0900_internal *intp, u32 ext_clk) |
272 | { |
273 | u32 mclk, div, ad_div; |
274 | |
275 | div = stv0900_get_bits(intp, F0900_M_DIV); |
276 | ad_div = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6); |
277 | |
278 | mclk = (div + 1) * ext_clk / ad_div; |
279 | |
280 | dprintk("%s: Calculated Mclk = %d\n" , __func__, mclk); |
281 | |
282 | return mclk; |
283 | } |
284 | |
285 | static enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 mclk) |
286 | { |
287 | u32 m_div, clk_sel; |
288 | |
289 | if (intp == NULL) |
290 | return STV0900_INVALID_HANDLE; |
291 | |
292 | if (intp->errs) |
293 | return STV0900_I2C_ERROR; |
294 | |
295 | dprintk("%s: Mclk set to %d, Quartz = %d\n" , __func__, mclk, |
296 | intp->quartz); |
297 | |
298 | clk_sel = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6); |
299 | m_div = ((clk_sel * mclk) / intp->quartz) - 1; |
300 | stv0900_write_bits(intp, F0900_M_DIV, val: m_div); |
301 | intp->mclk = stv0900_get_mclk_freq(intp, |
302 | ext_clk: intp->quartz); |
303 | |
304 | /*Set the DiseqC frequency to 22KHz */ |
305 | /* |
306 | Formula: |
307 | DiseqC_TX_Freq= MasterClock/(32*F22TX_Reg) |
308 | DiseqC_RX_Freq= MasterClock/(32*F22RX_Reg) |
309 | */ |
310 | m_div = intp->mclk / 704000; |
311 | stv0900_write_reg(intp, R0900_P1_F22TX, reg_data: m_div); |
312 | stv0900_write_reg(intp, R0900_P1_F22RX, reg_data: m_div); |
313 | |
314 | stv0900_write_reg(intp, R0900_P2_F22TX, reg_data: m_div); |
315 | stv0900_write_reg(intp, R0900_P2_F22RX, reg_data: m_div); |
316 | |
317 | if ((intp->errs)) |
318 | return STV0900_I2C_ERROR; |
319 | |
320 | return STV0900_NO_ERROR; |
321 | } |
322 | |
323 | static u32 stv0900_get_err_count(struct stv0900_internal *intp, int cntr, |
324 | enum fe_stv0900_demod_num demod) |
325 | { |
326 | u32 lsb, msb, hsb, err_val; |
327 | |
328 | switch (cntr) { |
329 | case 0: |
330 | default: |
331 | hsb = stv0900_get_bits(intp, ERR_CNT12); |
332 | msb = stv0900_get_bits(intp, ERR_CNT11); |
333 | lsb = stv0900_get_bits(intp, ERR_CNT10); |
334 | break; |
335 | case 1: |
336 | hsb = stv0900_get_bits(intp, ERR_CNT22); |
337 | msb = stv0900_get_bits(intp, ERR_CNT21); |
338 | lsb = stv0900_get_bits(intp, ERR_CNT20); |
339 | break; |
340 | } |
341 | |
342 | err_val = (hsb << 16) + (msb << 8) + (lsb); |
343 | |
344 | return err_val; |
345 | } |
346 | |
347 | static int stv0900_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) |
348 | { |
349 | struct stv0900_state *state = fe->demodulator_priv; |
350 | struct stv0900_internal *intp = state->internal; |
351 | enum fe_stv0900_demod_num demod = state->demod; |
352 | |
353 | stv0900_write_bits(intp, I2CT_ON, val: enable); |
354 | |
355 | return 0; |
356 | } |
357 | |
358 | static void stv0900_set_ts_parallel_serial(struct stv0900_internal *intp, |
359 | enum fe_stv0900_clock_type path1_ts, |
360 | enum fe_stv0900_clock_type path2_ts) |
361 | { |
362 | |
363 | dprintk("%s\n" , __func__); |
364 | |
365 | if (intp->chip_id >= 0x20) { |
366 | switch (path1_ts) { |
367 | case STV0900_PARALLEL_PUNCT_CLOCK: |
368 | case STV0900_DVBCI_CLOCK: |
369 | switch (path2_ts) { |
370 | case STV0900_SERIAL_PUNCT_CLOCK: |
371 | case STV0900_SERIAL_CONT_CLOCK: |
372 | default: |
373 | stv0900_write_reg(intp, R0900_TSGENERAL, |
374 | reg_data: 0x00); |
375 | break; |
376 | case STV0900_PARALLEL_PUNCT_CLOCK: |
377 | case STV0900_DVBCI_CLOCK: |
378 | stv0900_write_reg(intp, R0900_TSGENERAL, |
379 | reg_data: 0x06); |
380 | stv0900_write_bits(intp, |
381 | F0900_P1_TSFIFO_MANSPEED, val: 3); |
382 | stv0900_write_bits(intp, |
383 | F0900_P2_TSFIFO_MANSPEED, val: 0); |
384 | stv0900_write_reg(intp, |
385 | R0900_P1_TSSPEED, reg_data: 0x14); |
386 | stv0900_write_reg(intp, |
387 | R0900_P2_TSSPEED, reg_data: 0x28); |
388 | break; |
389 | } |
390 | break; |
391 | case STV0900_SERIAL_PUNCT_CLOCK: |
392 | case STV0900_SERIAL_CONT_CLOCK: |
393 | default: |
394 | switch (path2_ts) { |
395 | case STV0900_SERIAL_PUNCT_CLOCK: |
396 | case STV0900_SERIAL_CONT_CLOCK: |
397 | default: |
398 | stv0900_write_reg(intp, |
399 | R0900_TSGENERAL, reg_data: 0x0C); |
400 | break; |
401 | case STV0900_PARALLEL_PUNCT_CLOCK: |
402 | case STV0900_DVBCI_CLOCK: |
403 | stv0900_write_reg(intp, |
404 | R0900_TSGENERAL, reg_data: 0x0A); |
405 | dprintk("%s: 0x0a\n" , __func__); |
406 | break; |
407 | } |
408 | break; |
409 | } |
410 | } else { |
411 | switch (path1_ts) { |
412 | case STV0900_PARALLEL_PUNCT_CLOCK: |
413 | case STV0900_DVBCI_CLOCK: |
414 | switch (path2_ts) { |
415 | case STV0900_SERIAL_PUNCT_CLOCK: |
416 | case STV0900_SERIAL_CONT_CLOCK: |
417 | default: |
418 | stv0900_write_reg(intp, R0900_TSGENERAL1X, |
419 | reg_data: 0x10); |
420 | break; |
421 | case STV0900_PARALLEL_PUNCT_CLOCK: |
422 | case STV0900_DVBCI_CLOCK: |
423 | stv0900_write_reg(intp, R0900_TSGENERAL1X, |
424 | reg_data: 0x16); |
425 | stv0900_write_bits(intp, |
426 | F0900_P1_TSFIFO_MANSPEED, val: 3); |
427 | stv0900_write_bits(intp, |
428 | F0900_P2_TSFIFO_MANSPEED, val: 0); |
429 | stv0900_write_reg(intp, R0900_P1_TSSPEED, |
430 | reg_data: 0x14); |
431 | stv0900_write_reg(intp, R0900_P2_TSSPEED, |
432 | reg_data: 0x28); |
433 | break; |
434 | } |
435 | |
436 | break; |
437 | case STV0900_SERIAL_PUNCT_CLOCK: |
438 | case STV0900_SERIAL_CONT_CLOCK: |
439 | default: |
440 | switch (path2_ts) { |
441 | case STV0900_SERIAL_PUNCT_CLOCK: |
442 | case STV0900_SERIAL_CONT_CLOCK: |
443 | default: |
444 | stv0900_write_reg(intp, R0900_TSGENERAL1X, |
445 | reg_data: 0x14); |
446 | break; |
447 | case STV0900_PARALLEL_PUNCT_CLOCK: |
448 | case STV0900_DVBCI_CLOCK: |
449 | stv0900_write_reg(intp, R0900_TSGENERAL1X, |
450 | reg_data: 0x12); |
451 | dprintk("%s: 0x12\n" , __func__); |
452 | break; |
453 | } |
454 | |
455 | break; |
456 | } |
457 | } |
458 | |
459 | switch (path1_ts) { |
460 | case STV0900_PARALLEL_PUNCT_CLOCK: |
461 | stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, val: 0x00); |
462 | stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, val: 0x00); |
463 | break; |
464 | case STV0900_DVBCI_CLOCK: |
465 | stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, val: 0x00); |
466 | stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, val: 0x01); |
467 | break; |
468 | case STV0900_SERIAL_PUNCT_CLOCK: |
469 | stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, val: 0x01); |
470 | stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, val: 0x00); |
471 | break; |
472 | case STV0900_SERIAL_CONT_CLOCK: |
473 | stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, val: 0x01); |
474 | stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, val: 0x01); |
475 | break; |
476 | default: |
477 | break; |
478 | } |
479 | |
480 | switch (path2_ts) { |
481 | case STV0900_PARALLEL_PUNCT_CLOCK: |
482 | stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, val: 0x00); |
483 | stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, val: 0x00); |
484 | break; |
485 | case STV0900_DVBCI_CLOCK: |
486 | stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, val: 0x00); |
487 | stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, val: 0x01); |
488 | break; |
489 | case STV0900_SERIAL_PUNCT_CLOCK: |
490 | stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, val: 0x01); |
491 | stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, val: 0x00); |
492 | break; |
493 | case STV0900_SERIAL_CONT_CLOCK: |
494 | stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, val: 0x01); |
495 | stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, val: 0x01); |
496 | break; |
497 | default: |
498 | break; |
499 | } |
500 | |
501 | stv0900_write_bits(intp, F0900_P2_RST_HWARE, val: 1); |
502 | stv0900_write_bits(intp, F0900_P2_RST_HWARE, val: 0); |
503 | stv0900_write_bits(intp, F0900_P1_RST_HWARE, val: 1); |
504 | stv0900_write_bits(intp, F0900_P1_RST_HWARE, val: 0); |
505 | } |
506 | |
507 | void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency, |
508 | u32 bandwidth) |
509 | { |
510 | struct dvb_frontend_ops *frontend_ops = NULL; |
511 | struct dvb_tuner_ops *tuner_ops = NULL; |
512 | |
513 | frontend_ops = &fe->ops; |
514 | tuner_ops = &frontend_ops->tuner_ops; |
515 | |
516 | if (tuner_ops->set_frequency) { |
517 | if ((tuner_ops->set_frequency(fe, frequency)) < 0) |
518 | dprintk("%s: Invalid parameter\n" , __func__); |
519 | else |
520 | dprintk("%s: Frequency=%d\n" , __func__, frequency); |
521 | |
522 | } |
523 | |
524 | if (tuner_ops->set_bandwidth) { |
525 | if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0) |
526 | dprintk("%s: Invalid parameter\n" , __func__); |
527 | else |
528 | dprintk("%s: Bandwidth=%d\n" , __func__, bandwidth); |
529 | |
530 | } |
531 | } |
532 | |
533 | void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) |
534 | { |
535 | struct dvb_frontend_ops *frontend_ops = NULL; |
536 | struct dvb_tuner_ops *tuner_ops = NULL; |
537 | |
538 | frontend_ops = &fe->ops; |
539 | tuner_ops = &frontend_ops->tuner_ops; |
540 | |
541 | if (tuner_ops->set_bandwidth) { |
542 | if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0) |
543 | dprintk("%s: Invalid parameter\n" , __func__); |
544 | else |
545 | dprintk("%s: Bandwidth=%d\n" , __func__, bandwidth); |
546 | |
547 | } |
548 | } |
549 | |
550 | u32 stv0900_get_freq_auto(struct stv0900_internal *intp, int demod) |
551 | { |
552 | u32 freq, round; |
553 | /* Formulat : |
554 | Tuner_Frequency(MHz) = Regs / 64 |
555 | Tuner_granularity(MHz) = Regs / 2048 |
556 | real_Tuner_Frequency = Tuner_Frequency(MHz) - Tuner_granularity(MHz) |
557 | */ |
558 | freq = (stv0900_get_bits(intp, TUN_RFFREQ2) << 10) + |
559 | (stv0900_get_bits(intp, TUN_RFFREQ1) << 2) + |
560 | stv0900_get_bits(intp, TUN_RFFREQ0); |
561 | |
562 | freq = (freq * 1000) / 64; |
563 | |
564 | round = (stv0900_get_bits(intp, TUN_RFRESTE1) >> 2) + |
565 | stv0900_get_bits(intp, TUN_RFRESTE0); |
566 | |
567 | round = (round * 1000) / 2048; |
568 | |
569 | return freq + round; |
570 | } |
571 | |
572 | void stv0900_set_tuner_auto(struct stv0900_internal *intp, u32 Frequency, |
573 | u32 Bandwidth, int demod) |
574 | { |
575 | u32 tunerFrequency; |
576 | /* Formulat: |
577 | Tuner_frequency_reg= Frequency(MHz)*64 |
578 | */ |
579 | tunerFrequency = (Frequency * 64) / 1000; |
580 | |
581 | stv0900_write_bits(intp, TUN_RFFREQ2, val: (tunerFrequency >> 10)); |
582 | stv0900_write_bits(intp, TUN_RFFREQ1, val: (tunerFrequency >> 2) & 0xff); |
583 | stv0900_write_bits(intp, TUN_RFFREQ0, val: (tunerFrequency & 0x03)); |
584 | /* Low Pass Filter = BW /2 (MHz)*/ |
585 | stv0900_write_bits(intp, TUN_BW, val: Bandwidth / 2000000); |
586 | /* Tuner Write trig */ |
587 | stv0900_write_reg(intp, TNRLD, reg_data: 1); |
588 | } |
589 | |
590 | static s32 stv0900_get_rf_level(struct stv0900_internal *intp, |
591 | const struct stv0900_table *lookup, |
592 | enum fe_stv0900_demod_num demod) |
593 | { |
594 | s32 agc_gain = 0, |
595 | imin, |
596 | imax, |
597 | i, |
598 | rf_lvl = 0; |
599 | |
600 | dprintk("%s\n" , __func__); |
601 | |
602 | if ((lookup == NULL) || (lookup->size <= 0)) |
603 | return 0; |
604 | |
605 | agc_gain = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1), |
606 | stv0900_get_bits(intp, AGCIQ_VALUE0)); |
607 | |
608 | imin = 0; |
609 | imax = lookup->size - 1; |
610 | if (INRANGE(lookup->table[imin].regval, agc_gain, |
611 | lookup->table[imax].regval)) { |
612 | while ((imax - imin) > 1) { |
613 | i = (imax + imin) >> 1; |
614 | |
615 | if (INRANGE(lookup->table[imin].regval, |
616 | agc_gain, |
617 | lookup->table[i].regval)) |
618 | imax = i; |
619 | else |
620 | imin = i; |
621 | } |
622 | |
623 | rf_lvl = (s32)agc_gain - lookup->table[imin].regval; |
624 | rf_lvl *= (lookup->table[imax].realval - |
625 | lookup->table[imin].realval); |
626 | rf_lvl /= (lookup->table[imax].regval - |
627 | lookup->table[imin].regval); |
628 | rf_lvl += lookup->table[imin].realval; |
629 | } else if (agc_gain > lookup->table[0].regval) |
630 | rf_lvl = 5; |
631 | else if (agc_gain < lookup->table[lookup->size-1].regval) |
632 | rf_lvl = -100; |
633 | |
634 | dprintk("%s: RFLevel = %d\n" , __func__, rf_lvl); |
635 | |
636 | return rf_lvl; |
637 | } |
638 | |
639 | static int stv0900_read_signal_strength(struct dvb_frontend *fe, u16 *strength) |
640 | { |
641 | struct stv0900_state *state = fe->demodulator_priv; |
642 | struct stv0900_internal *internal = state->internal; |
643 | s32 rflevel = stv0900_get_rf_level(intp: internal, lookup: &stv0900_rf, |
644 | demod: state->demod); |
645 | |
646 | rflevel = (rflevel + 100) * (65535 / 70); |
647 | if (rflevel < 0) |
648 | rflevel = 0; |
649 | |
650 | if (rflevel > 65535) |
651 | rflevel = 65535; |
652 | |
653 | *strength = rflevel; |
654 | |
655 | return 0; |
656 | } |
657 | |
658 | static s32 stv0900_carr_get_quality(struct dvb_frontend *fe, |
659 | const struct stv0900_table *lookup) |
660 | { |
661 | struct stv0900_state *state = fe->demodulator_priv; |
662 | struct stv0900_internal *intp = state->internal; |
663 | enum fe_stv0900_demod_num demod = state->demod; |
664 | |
665 | s32 c_n = -100, |
666 | regval, |
667 | imin, |
668 | imax, |
669 | i, |
670 | noise_field1, |
671 | noise_field0; |
672 | |
673 | dprintk("%s\n" , __func__); |
674 | |
675 | if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) { |
676 | noise_field1 = NOSPLHT_NORMED1; |
677 | noise_field0 = NOSPLHT_NORMED0; |
678 | } else { |
679 | noise_field1 = NOSDATAT_NORMED1; |
680 | noise_field0 = NOSDATAT_NORMED0; |
681 | } |
682 | |
683 | if (stv0900_get_bits(intp, LOCK_DEFINITIF)) { |
684 | if ((lookup != NULL) && lookup->size) { |
685 | regval = 0; |
686 | msleep(msecs: 5); |
687 | for (i = 0; i < 16; i++) { |
688 | regval += MAKEWORD(stv0900_get_bits(intp, |
689 | noise_field1), |
690 | stv0900_get_bits(intp, |
691 | noise_field0)); |
692 | msleep(msecs: 1); |
693 | } |
694 | |
695 | regval /= 16; |
696 | imin = 0; |
697 | imax = lookup->size - 1; |
698 | if (INRANGE(lookup->table[imin].regval, |
699 | regval, |
700 | lookup->table[imax].regval)) { |
701 | while ((imax - imin) > 1) { |
702 | i = (imax + imin) >> 1; |
703 | if (INRANGE(lookup->table[imin].regval, |
704 | regval, |
705 | lookup->table[i].regval)) |
706 | imax = i; |
707 | else |
708 | imin = i; |
709 | } |
710 | |
711 | c_n = ((regval - lookup->table[imin].regval) |
712 | * (lookup->table[imax].realval |
713 | - lookup->table[imin].realval) |
714 | / (lookup->table[imax].regval |
715 | - lookup->table[imin].regval)) |
716 | + lookup->table[imin].realval; |
717 | } else if (regval < lookup->table[imin].regval) |
718 | c_n = 1000; |
719 | } |
720 | } |
721 | |
722 | return c_n; |
723 | } |
724 | |
725 | static int stv0900_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks) |
726 | { |
727 | struct stv0900_state *state = fe->demodulator_priv; |
728 | struct stv0900_internal *intp = state->internal; |
729 | enum fe_stv0900_demod_num demod = state->demod; |
730 | u8 err_val1, err_val0; |
731 | u32 = 0; |
732 | |
733 | *ucblocks = 0x0; |
734 | if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) { |
735 | /* DVB-S2 delineator errors count */ |
736 | |
737 | /* retrieving number for errnous headers */ |
738 | err_val1 = stv0900_read_reg(intp, BBFCRCKO1); |
739 | err_val0 = stv0900_read_reg(intp, BBFCRCKO0); |
740 | header_err_val = (err_val1 << 8) | err_val0; |
741 | |
742 | /* retrieving number for errnous packets */ |
743 | err_val1 = stv0900_read_reg(intp, UPCRCKO1); |
744 | err_val0 = stv0900_read_reg(intp, UPCRCKO0); |
745 | *ucblocks = (err_val1 << 8) | err_val0; |
746 | *ucblocks += header_err_val; |
747 | } |
748 | |
749 | return 0; |
750 | } |
751 | |
752 | static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr) |
753 | { |
754 | s32 snrlcl = stv0900_carr_get_quality(fe, |
755 | lookup: (const struct stv0900_table *)&stv0900_s2_cn); |
756 | snrlcl = (snrlcl + 30) * 384; |
757 | if (snrlcl < 0) |
758 | snrlcl = 0; |
759 | |
760 | if (snrlcl > 65535) |
761 | snrlcl = 65535; |
762 | |
763 | *snr = snrlcl; |
764 | |
765 | return 0; |
766 | } |
767 | |
768 | static u32 stv0900_get_ber(struct stv0900_internal *intp, |
769 | enum fe_stv0900_demod_num demod) |
770 | { |
771 | u32 ber = 10000000, i; |
772 | s32 demod_state; |
773 | |
774 | demod_state = stv0900_get_bits(intp, HEADER_MODE); |
775 | |
776 | switch (demod_state) { |
777 | case STV0900_SEARCH: |
778 | case STV0900_PLH_DETECTED: |
779 | default: |
780 | ber = 10000000; |
781 | break; |
782 | case STV0900_DVBS_FOUND: |
783 | ber = 0; |
784 | for (i = 0; i < 5; i++) { |
785 | msleep(msecs: 5); |
786 | ber += stv0900_get_err_count(intp, cntr: 0, demod); |
787 | } |
788 | |
789 | ber /= 5; |
790 | if (stv0900_get_bits(intp, PRFVIT)) { |
791 | ber *= 9766; |
792 | ber = ber >> 13; |
793 | } |
794 | |
795 | break; |
796 | case STV0900_DVBS2_FOUND: |
797 | ber = 0; |
798 | for (i = 0; i < 5; i++) { |
799 | msleep(msecs: 5); |
800 | ber += stv0900_get_err_count(intp, cntr: 0, demod); |
801 | } |
802 | |
803 | ber /= 5; |
804 | if (stv0900_get_bits(intp, PKTDELIN_LOCK)) { |
805 | ber *= 9766; |
806 | ber = ber >> 13; |
807 | } |
808 | |
809 | break; |
810 | } |
811 | |
812 | return ber; |
813 | } |
814 | |
815 | static int stv0900_read_ber(struct dvb_frontend *fe, u32 *ber) |
816 | { |
817 | struct stv0900_state *state = fe->demodulator_priv; |
818 | struct stv0900_internal *internal = state->internal; |
819 | |
820 | *ber = stv0900_get_ber(intp: internal, demod: state->demod); |
821 | |
822 | return 0; |
823 | } |
824 | |
825 | int stv0900_get_demod_lock(struct stv0900_internal *intp, |
826 | enum fe_stv0900_demod_num demod, s32 time_out) |
827 | { |
828 | s32 timer = 0, |
829 | lock = 0; |
830 | |
831 | enum fe_stv0900_search_state dmd_state; |
832 | |
833 | while ((timer < time_out) && (lock == 0)) { |
834 | dmd_state = stv0900_get_bits(intp, HEADER_MODE); |
835 | dprintk("Demod State = %d\n" , dmd_state); |
836 | switch (dmd_state) { |
837 | case STV0900_SEARCH: |
838 | case STV0900_PLH_DETECTED: |
839 | default: |
840 | lock = 0; |
841 | break; |
842 | case STV0900_DVBS2_FOUND: |
843 | case STV0900_DVBS_FOUND: |
844 | lock = stv0900_get_bits(intp, LOCK_DEFINITIF); |
845 | break; |
846 | } |
847 | |
848 | if (lock == 0) |
849 | msleep(msecs: 10); |
850 | |
851 | timer += 10; |
852 | } |
853 | |
854 | if (lock) |
855 | dprintk("DEMOD LOCK OK\n" ); |
856 | else |
857 | dprintk("DEMOD LOCK FAIL\n" ); |
858 | |
859 | return lock; |
860 | } |
861 | |
862 | void stv0900_stop_all_s2_modcod(struct stv0900_internal *intp, |
863 | enum fe_stv0900_demod_num demod) |
864 | { |
865 | s32 regflist, |
866 | i; |
867 | |
868 | dprintk("%s\n" , __func__); |
869 | |
870 | regflist = MODCODLST0; |
871 | |
872 | for (i = 0; i < 16; i++) |
873 | stv0900_write_reg(intp, reg_addr: regflist + i, reg_data: 0xff); |
874 | } |
875 | |
876 | void stv0900_activate_s2_modcod(struct stv0900_internal *intp, |
877 | enum fe_stv0900_demod_num demod) |
878 | { |
879 | u32 matype, |
880 | mod_code, |
881 | fmod, |
882 | reg_index, |
883 | field_index; |
884 | |
885 | dprintk("%s\n" , __func__); |
886 | |
887 | if (intp->chip_id <= 0x11) { |
888 | msleep(msecs: 5); |
889 | |
890 | mod_code = stv0900_read_reg(intp, PLHMODCOD); |
891 | matype = mod_code & 0x3; |
892 | mod_code = (mod_code & 0x7f) >> 2; |
893 | |
894 | reg_index = MODCODLSTF - mod_code / 2; |
895 | field_index = mod_code % 2; |
896 | |
897 | switch (matype) { |
898 | case 0: |
899 | default: |
900 | fmod = 14; |
901 | break; |
902 | case 1: |
903 | fmod = 13; |
904 | break; |
905 | case 2: |
906 | fmod = 11; |
907 | break; |
908 | case 3: |
909 | fmod = 7; |
910 | break; |
911 | } |
912 | |
913 | if ((INRANGE(STV0900_QPSK_12, mod_code, STV0900_8PSK_910)) |
914 | && (matype <= 1)) { |
915 | if (field_index == 0) |
916 | stv0900_write_reg(intp, reg_addr: reg_index, |
917 | reg_data: 0xf0 | fmod); |
918 | else |
919 | stv0900_write_reg(intp, reg_addr: reg_index, |
920 | reg_data: (fmod << 4) | 0xf); |
921 | } |
922 | |
923 | } else if (intp->chip_id >= 0x12) { |
924 | for (reg_index = 0; reg_index < 7; reg_index++) |
925 | stv0900_write_reg(intp, MODCODLST0 + reg_index, reg_data: 0xff); |
926 | |
927 | stv0900_write_reg(intp, MODCODLSTE, reg_data: 0xff); |
928 | stv0900_write_reg(intp, MODCODLSTF, reg_data: 0xcf); |
929 | for (reg_index = 0; reg_index < 8; reg_index++) |
930 | stv0900_write_reg(intp, MODCODLST7 + reg_index, reg_data: 0xcc); |
931 | |
932 | |
933 | } |
934 | } |
935 | |
936 | void stv0900_activate_s2_modcod_single(struct stv0900_internal *intp, |
937 | enum fe_stv0900_demod_num demod) |
938 | { |
939 | u32 reg_index; |
940 | |
941 | dprintk("%s\n" , __func__); |
942 | |
943 | stv0900_write_reg(intp, MODCODLST0, reg_data: 0xff); |
944 | stv0900_write_reg(intp, MODCODLST1, reg_data: 0xf0); |
945 | stv0900_write_reg(intp, MODCODLSTF, reg_data: 0x0f); |
946 | for (reg_index = 0; reg_index < 13; reg_index++) |
947 | stv0900_write_reg(intp, MODCODLST2 + reg_index, reg_data: 0); |
948 | |
949 | } |
950 | |
951 | static enum dvbfe_algo stv0900_frontend_algo(struct dvb_frontend *fe) |
952 | { |
953 | return DVBFE_ALGO_CUSTOM; |
954 | } |
955 | |
956 | void stv0900_start_search(struct stv0900_internal *intp, |
957 | enum fe_stv0900_demod_num demod) |
958 | { |
959 | u32 freq; |
960 | s16 freq_s16 ; |
961 | |
962 | stv0900_write_bits(intp, DEMOD_MODE, val: 0x1f); |
963 | if (intp->chip_id == 0x10) |
964 | stv0900_write_reg(intp, CORRELEXP, reg_data: 0xaa); |
965 | |
966 | if (intp->chip_id < 0x20) |
967 | stv0900_write_reg(intp, CARHDR, reg_data: 0x55); |
968 | |
969 | if (intp->chip_id <= 0x20) { |
970 | if (intp->symbol_rate[0] <= 5000000) { |
971 | stv0900_write_reg(intp, CARCFG, reg_data: 0x44); |
972 | stv0900_write_reg(intp, CFRUP1, reg_data: 0x0f); |
973 | stv0900_write_reg(intp, CFRUP0, reg_data: 0xff); |
974 | stv0900_write_reg(intp, CFRLOW1, reg_data: 0xf0); |
975 | stv0900_write_reg(intp, CFRLOW0, reg_data: 0x00); |
976 | stv0900_write_reg(intp, RTCS2, reg_data: 0x68); |
977 | } else { |
978 | stv0900_write_reg(intp, CARCFG, reg_data: 0xc4); |
979 | stv0900_write_reg(intp, RTCS2, reg_data: 0x44); |
980 | } |
981 | |
982 | } else { /*cut 3.0 above*/ |
983 | if (intp->symbol_rate[demod] <= 5000000) |
984 | stv0900_write_reg(intp, RTCS2, reg_data: 0x68); |
985 | else |
986 | stv0900_write_reg(intp, RTCS2, reg_data: 0x44); |
987 | |
988 | stv0900_write_reg(intp, CARCFG, reg_data: 0x46); |
989 | if (intp->srch_algo[demod] == STV0900_WARM_START) { |
990 | freq = 1000 << 16; |
991 | freq /= (intp->mclk / 1000); |
992 | freq_s16 = (s16)freq; |
993 | } else { |
994 | freq = (intp->srch_range[demod] / 2000); |
995 | if (intp->symbol_rate[demod] <= 5000000) |
996 | freq += 80; |
997 | else |
998 | freq += 600; |
999 | |
1000 | freq = freq << 16; |
1001 | freq /= (intp->mclk / 1000); |
1002 | freq_s16 = (s16)freq; |
1003 | } |
1004 | |
1005 | stv0900_write_bits(intp, CFR_UP1, MSB(freq_s16)); |
1006 | stv0900_write_bits(intp, CFR_UP0, LSB(freq_s16)); |
1007 | freq_s16 *= (-1); |
1008 | stv0900_write_bits(intp, CFR_LOW1, MSB(freq_s16)); |
1009 | stv0900_write_bits(intp, CFR_LOW0, LSB(freq_s16)); |
1010 | } |
1011 | |
1012 | stv0900_write_reg(intp, CFRINIT1, reg_data: 0); |
1013 | stv0900_write_reg(intp, CFRINIT0, reg_data: 0); |
1014 | |
1015 | if (intp->chip_id >= 0x20) { |
1016 | stv0900_write_reg(intp, EQUALCFG, reg_data: 0x41); |
1017 | stv0900_write_reg(intp, FFECFG, reg_data: 0x41); |
1018 | |
1019 | if ((intp->srch_standard[demod] == STV0900_SEARCH_DVBS1) || |
1020 | (intp->srch_standard[demod] == STV0900_SEARCH_DSS) || |
1021 | (intp->srch_standard[demod] == STV0900_AUTO_SEARCH)) { |
1022 | stv0900_write_reg(intp, VITSCALE, |
1023 | reg_data: 0x82); |
1024 | stv0900_write_reg(intp, VAVSRVIT, reg_data: 0x0); |
1025 | } |
1026 | } |
1027 | |
1028 | stv0900_write_reg(intp, SFRSTEP, reg_data: 0x00); |
1029 | stv0900_write_reg(intp, TMGTHRISE, reg_data: 0xe0); |
1030 | stv0900_write_reg(intp, TMGTHFALL, reg_data: 0xc0); |
1031 | stv0900_write_bits(intp, SCAN_ENABLE, val: 0); |
1032 | stv0900_write_bits(intp, CFR_AUTOSCAN, val: 0); |
1033 | stv0900_write_bits(intp, S1S2_SEQUENTIAL, val: 0); |
1034 | stv0900_write_reg(intp, RTC, reg_data: 0x88); |
1035 | if (intp->chip_id >= 0x20) { |
1036 | if (intp->symbol_rate[demod] < 2000000) { |
1037 | if (intp->chip_id <= 0x20) |
1038 | stv0900_write_reg(intp, CARFREQ, reg_data: 0x39); |
1039 | else /*cut 3.0*/ |
1040 | stv0900_write_reg(intp, CARFREQ, reg_data: 0x89); |
1041 | |
1042 | stv0900_write_reg(intp, CARHDR, reg_data: 0x40); |
1043 | } else if (intp->symbol_rate[demod] < 10000000) { |
1044 | stv0900_write_reg(intp, CARFREQ, reg_data: 0x4c); |
1045 | stv0900_write_reg(intp, CARHDR, reg_data: 0x20); |
1046 | } else { |
1047 | stv0900_write_reg(intp, CARFREQ, reg_data: 0x4b); |
1048 | stv0900_write_reg(intp, CARHDR, reg_data: 0x20); |
1049 | } |
1050 | |
1051 | } else { |
1052 | if (intp->symbol_rate[demod] < 10000000) |
1053 | stv0900_write_reg(intp, CARFREQ, reg_data: 0xef); |
1054 | else |
1055 | stv0900_write_reg(intp, CARFREQ, reg_data: 0xed); |
1056 | } |
1057 | |
1058 | switch (intp->srch_algo[demod]) { |
1059 | case STV0900_WARM_START: |
1060 | stv0900_write_reg(intp, DMDISTATE, reg_data: 0x1f); |
1061 | stv0900_write_reg(intp, DMDISTATE, reg_data: 0x18); |
1062 | break; |
1063 | case STV0900_COLD_START: |
1064 | stv0900_write_reg(intp, DMDISTATE, reg_data: 0x1f); |
1065 | stv0900_write_reg(intp, DMDISTATE, reg_data: 0x15); |
1066 | break; |
1067 | default: |
1068 | break; |
1069 | } |
1070 | } |
1071 | |
1072 | u8 stv0900_get_optim_carr_loop(s32 srate, enum fe_stv0900_modcode modcode, |
1073 | s32 pilot, u8 chip_id) |
1074 | { |
1075 | u8 aclc_value = 0x29; |
1076 | s32 i, cllas2_size; |
1077 | const struct stv0900_car_loop_optim *cls2, *cllqs2, *cllas2; |
1078 | |
1079 | dprintk("%s\n" , __func__); |
1080 | |
1081 | if (chip_id <= 0x12) { |
1082 | cls2 = FE_STV0900_S2CarLoop; |
1083 | cllqs2 = FE_STV0900_S2LowQPCarLoopCut30; |
1084 | cllas2 = FE_STV0900_S2APSKCarLoopCut30; |
1085 | cllas2_size = ARRAY_SIZE(FE_STV0900_S2APSKCarLoopCut30); |
1086 | } else if (chip_id == 0x20) { |
1087 | cls2 = FE_STV0900_S2CarLoopCut20; |
1088 | cllqs2 = FE_STV0900_S2LowQPCarLoopCut20; |
1089 | cllas2 = FE_STV0900_S2APSKCarLoopCut20; |
1090 | cllas2_size = ARRAY_SIZE(FE_STV0900_S2APSKCarLoopCut20); |
1091 | } else { |
1092 | cls2 = FE_STV0900_S2CarLoopCut30; |
1093 | cllqs2 = FE_STV0900_S2LowQPCarLoopCut30; |
1094 | cllas2 = FE_STV0900_S2APSKCarLoopCut30; |
1095 | cllas2_size = ARRAY_SIZE(FE_STV0900_S2APSKCarLoopCut30); |
1096 | } |
1097 | |
1098 | if (modcode < STV0900_QPSK_12) { |
1099 | i = 0; |
1100 | while ((i < 3) && (modcode != cllqs2[i].modcode)) |
1101 | i++; |
1102 | |
1103 | if (i >= 3) |
1104 | i = 2; |
1105 | } else { |
1106 | i = 0; |
1107 | while ((i < 14) && (modcode != cls2[i].modcode)) |
1108 | i++; |
1109 | |
1110 | if (i >= 14) { |
1111 | i = 0; |
1112 | while ((i < 11) && (modcode != cllas2[i].modcode)) |
1113 | i++; |
1114 | |
1115 | if (i >= 11) |
1116 | i = 10; |
1117 | } |
1118 | } |
1119 | |
1120 | if (modcode <= STV0900_QPSK_25) { |
1121 | if (pilot) { |
1122 | if (srate <= 3000000) |
1123 | aclc_value = cllqs2[i].car_loop_pilots_on_2; |
1124 | else if (srate <= 7000000) |
1125 | aclc_value = cllqs2[i].car_loop_pilots_on_5; |
1126 | else if (srate <= 15000000) |
1127 | aclc_value = cllqs2[i].car_loop_pilots_on_10; |
1128 | else if (srate <= 25000000) |
1129 | aclc_value = cllqs2[i].car_loop_pilots_on_20; |
1130 | else |
1131 | aclc_value = cllqs2[i].car_loop_pilots_on_30; |
1132 | } else { |
1133 | if (srate <= 3000000) |
1134 | aclc_value = cllqs2[i].car_loop_pilots_off_2; |
1135 | else if (srate <= 7000000) |
1136 | aclc_value = cllqs2[i].car_loop_pilots_off_5; |
1137 | else if (srate <= 15000000) |
1138 | aclc_value = cllqs2[i].car_loop_pilots_off_10; |
1139 | else if (srate <= 25000000) |
1140 | aclc_value = cllqs2[i].car_loop_pilots_off_20; |
1141 | else |
1142 | aclc_value = cllqs2[i].car_loop_pilots_off_30; |
1143 | } |
1144 | |
1145 | } else if (modcode <= STV0900_8PSK_910) { |
1146 | if (pilot) { |
1147 | if (srate <= 3000000) |
1148 | aclc_value = cls2[i].car_loop_pilots_on_2; |
1149 | else if (srate <= 7000000) |
1150 | aclc_value = cls2[i].car_loop_pilots_on_5; |
1151 | else if (srate <= 15000000) |
1152 | aclc_value = cls2[i].car_loop_pilots_on_10; |
1153 | else if (srate <= 25000000) |
1154 | aclc_value = cls2[i].car_loop_pilots_on_20; |
1155 | else |
1156 | aclc_value = cls2[i].car_loop_pilots_on_30; |
1157 | } else { |
1158 | if (srate <= 3000000) |
1159 | aclc_value = cls2[i].car_loop_pilots_off_2; |
1160 | else if (srate <= 7000000) |
1161 | aclc_value = cls2[i].car_loop_pilots_off_5; |
1162 | else if (srate <= 15000000) |
1163 | aclc_value = cls2[i].car_loop_pilots_off_10; |
1164 | else if (srate <= 25000000) |
1165 | aclc_value = cls2[i].car_loop_pilots_off_20; |
1166 | else |
1167 | aclc_value = cls2[i].car_loop_pilots_off_30; |
1168 | } |
1169 | |
1170 | } else if (i < cllas2_size) { |
1171 | if (srate <= 3000000) |
1172 | aclc_value = cllas2[i].car_loop_pilots_on_2; |
1173 | else if (srate <= 7000000) |
1174 | aclc_value = cllas2[i].car_loop_pilots_on_5; |
1175 | else if (srate <= 15000000) |
1176 | aclc_value = cllas2[i].car_loop_pilots_on_10; |
1177 | else if (srate <= 25000000) |
1178 | aclc_value = cllas2[i].car_loop_pilots_on_20; |
1179 | else |
1180 | aclc_value = cllas2[i].car_loop_pilots_on_30; |
1181 | } |
1182 | |
1183 | return aclc_value; |
1184 | } |
1185 | |
1186 | u8 stv0900_get_optim_short_carr_loop(s32 srate, |
1187 | enum fe_stv0900_modulation modulation, |
1188 | u8 chip_id) |
1189 | { |
1190 | const struct stv0900_short_frames_car_loop_optim *s2scl; |
1191 | const struct stv0900_short_frames_car_loop_optim_vs_mod *s2sclc30; |
1192 | s32 mod_index = 0; |
1193 | u8 aclc_value = 0x0b; |
1194 | |
1195 | dprintk("%s\n" , __func__); |
1196 | |
1197 | s2scl = FE_STV0900_S2ShortCarLoop; |
1198 | s2sclc30 = FE_STV0900_S2ShortCarLoopCut30; |
1199 | |
1200 | switch (modulation) { |
1201 | case STV0900_QPSK: |
1202 | default: |
1203 | mod_index = 0; |
1204 | break; |
1205 | case STV0900_8PSK: |
1206 | mod_index = 1; |
1207 | break; |
1208 | case STV0900_16APSK: |
1209 | mod_index = 2; |
1210 | break; |
1211 | case STV0900_32APSK: |
1212 | mod_index = 3; |
1213 | break; |
1214 | } |
1215 | |
1216 | if (chip_id >= 0x30) { |
1217 | if (srate <= 3000000) |
1218 | aclc_value = s2sclc30[mod_index].car_loop_2; |
1219 | else if (srate <= 7000000) |
1220 | aclc_value = s2sclc30[mod_index].car_loop_5; |
1221 | else if (srate <= 15000000) |
1222 | aclc_value = s2sclc30[mod_index].car_loop_10; |
1223 | else if (srate <= 25000000) |
1224 | aclc_value = s2sclc30[mod_index].car_loop_20; |
1225 | else |
1226 | aclc_value = s2sclc30[mod_index].car_loop_30; |
1227 | |
1228 | } else if (chip_id >= 0x20) { |
1229 | if (srate <= 3000000) |
1230 | aclc_value = s2scl[mod_index].car_loop_cut20_2; |
1231 | else if (srate <= 7000000) |
1232 | aclc_value = s2scl[mod_index].car_loop_cut20_5; |
1233 | else if (srate <= 15000000) |
1234 | aclc_value = s2scl[mod_index].car_loop_cut20_10; |
1235 | else if (srate <= 25000000) |
1236 | aclc_value = s2scl[mod_index].car_loop_cut20_20; |
1237 | else |
1238 | aclc_value = s2scl[mod_index].car_loop_cut20_30; |
1239 | |
1240 | } else { |
1241 | if (srate <= 3000000) |
1242 | aclc_value = s2scl[mod_index].car_loop_cut12_2; |
1243 | else if (srate <= 7000000) |
1244 | aclc_value = s2scl[mod_index].car_loop_cut12_5; |
1245 | else if (srate <= 15000000) |
1246 | aclc_value = s2scl[mod_index].car_loop_cut12_10; |
1247 | else if (srate <= 25000000) |
1248 | aclc_value = s2scl[mod_index].car_loop_cut12_20; |
1249 | else |
1250 | aclc_value = s2scl[mod_index].car_loop_cut12_30; |
1251 | |
1252 | } |
1253 | |
1254 | return aclc_value; |
1255 | } |
1256 | |
1257 | static |
1258 | enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *intp, |
1259 | enum fe_stv0900_demod_mode LDPC_Mode, |
1260 | enum fe_stv0900_demod_num demod) |
1261 | { |
1262 | s32 reg_ind; |
1263 | |
1264 | dprintk("%s\n" , __func__); |
1265 | |
1266 | switch (LDPC_Mode) { |
1267 | case STV0900_DUAL: |
1268 | default: |
1269 | if ((intp->demod_mode != STV0900_DUAL) |
1270 | || (stv0900_get_bits(intp, F0900_DDEMOD) != 1)) { |
1271 | stv0900_write_reg(intp, R0900_GENCFG, reg_data: 0x1d); |
1272 | |
1273 | intp->demod_mode = STV0900_DUAL; |
1274 | |
1275 | stv0900_write_bits(intp, F0900_FRESFEC, val: 1); |
1276 | stv0900_write_bits(intp, F0900_FRESFEC, val: 0); |
1277 | |
1278 | for (reg_ind = 0; reg_ind < 7; reg_ind++) |
1279 | stv0900_write_reg(intp, |
1280 | R0900_P1_MODCODLST0 + reg_ind, |
1281 | reg_data: 0xff); |
1282 | for (reg_ind = 0; reg_ind < 8; reg_ind++) |
1283 | stv0900_write_reg(intp, |
1284 | R0900_P1_MODCODLST7 + reg_ind, |
1285 | reg_data: 0xcc); |
1286 | |
1287 | stv0900_write_reg(intp, R0900_P1_MODCODLSTE, reg_data: 0xff); |
1288 | stv0900_write_reg(intp, R0900_P1_MODCODLSTF, reg_data: 0xcf); |
1289 | |
1290 | for (reg_ind = 0; reg_ind < 7; reg_ind++) |
1291 | stv0900_write_reg(intp, |
1292 | R0900_P2_MODCODLST0 + reg_ind, |
1293 | reg_data: 0xff); |
1294 | for (reg_ind = 0; reg_ind < 8; reg_ind++) |
1295 | stv0900_write_reg(intp, |
1296 | R0900_P2_MODCODLST7 + reg_ind, |
1297 | reg_data: 0xcc); |
1298 | |
1299 | stv0900_write_reg(intp, R0900_P2_MODCODLSTE, reg_data: 0xff); |
1300 | stv0900_write_reg(intp, R0900_P2_MODCODLSTF, reg_data: 0xcf); |
1301 | } |
1302 | |
1303 | break; |
1304 | case STV0900_SINGLE: |
1305 | if (demod == STV0900_DEMOD_2) { |
1306 | stv0900_stop_all_s2_modcod(intp, demod: STV0900_DEMOD_1); |
1307 | stv0900_activate_s2_modcod_single(intp, |
1308 | demod: STV0900_DEMOD_2); |
1309 | stv0900_write_reg(intp, R0900_GENCFG, reg_data: 0x06); |
1310 | } else { |
1311 | stv0900_stop_all_s2_modcod(intp, demod: STV0900_DEMOD_2); |
1312 | stv0900_activate_s2_modcod_single(intp, |
1313 | demod: STV0900_DEMOD_1); |
1314 | stv0900_write_reg(intp, R0900_GENCFG, reg_data: 0x04); |
1315 | } |
1316 | |
1317 | intp->demod_mode = STV0900_SINGLE; |
1318 | |
1319 | stv0900_write_bits(intp, F0900_FRESFEC, val: 1); |
1320 | stv0900_write_bits(intp, F0900_FRESFEC, val: 0); |
1321 | stv0900_write_bits(intp, F0900_P1_ALGOSWRST, val: 1); |
1322 | stv0900_write_bits(intp, F0900_P1_ALGOSWRST, val: 0); |
1323 | stv0900_write_bits(intp, F0900_P2_ALGOSWRST, val: 1); |
1324 | stv0900_write_bits(intp, F0900_P2_ALGOSWRST, val: 0); |
1325 | break; |
1326 | } |
1327 | |
1328 | return STV0900_NO_ERROR; |
1329 | } |
1330 | |
1331 | static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe, |
1332 | struct stv0900_init_params *p_init) |
1333 | { |
1334 | struct stv0900_state *state = fe->demodulator_priv; |
1335 | enum fe_stv0900_error error = STV0900_NO_ERROR; |
1336 | enum fe_stv0900_error demodError = STV0900_NO_ERROR; |
1337 | struct stv0900_internal *intp = NULL; |
1338 | int selosci, i; |
1339 | |
1340 | struct stv0900_inode *temp_int = find_inode(i2c_adap: state->i2c_adap, |
1341 | i2c_addr: state->config->demod_address); |
1342 | |
1343 | dprintk("%s\n" , __func__); |
1344 | |
1345 | if ((temp_int != NULL) && (p_init->demod_mode == STV0900_DUAL)) { |
1346 | state->internal = temp_int->internal; |
1347 | (state->internal->dmds_used)++; |
1348 | dprintk("%s: Find Internal Structure!\n" , __func__); |
1349 | return STV0900_NO_ERROR; |
1350 | } else { |
1351 | state->internal = kmalloc(size: sizeof(struct stv0900_internal), |
1352 | GFP_KERNEL); |
1353 | if (state->internal == NULL) |
1354 | return STV0900_INVALID_HANDLE; |
1355 | temp_int = append_internal(internal: state->internal); |
1356 | if (temp_int == NULL) { |
1357 | kfree(objp: state->internal); |
1358 | state->internal = NULL; |
1359 | return STV0900_INVALID_HANDLE; |
1360 | } |
1361 | state->internal->dmds_used = 1; |
1362 | state->internal->i2c_adap = state->i2c_adap; |
1363 | state->internal->i2c_addr = state->config->demod_address; |
1364 | state->internal->clkmode = state->config->clkmode; |
1365 | state->internal->errs = STV0900_NO_ERROR; |
1366 | dprintk("%s: Create New Internal Structure!\n" , __func__); |
1367 | } |
1368 | |
1369 | if (state->internal == NULL) { |
1370 | error = STV0900_INVALID_HANDLE; |
1371 | return error; |
1372 | } |
1373 | |
1374 | demodError = stv0900_initialize(intp: state->internal); |
1375 | if (demodError == STV0900_NO_ERROR) { |
1376 | error = STV0900_NO_ERROR; |
1377 | } else { |
1378 | if (demodError == STV0900_INVALID_HANDLE) |
1379 | error = STV0900_INVALID_HANDLE; |
1380 | else |
1381 | error = STV0900_I2C_ERROR; |
1382 | |
1383 | return error; |
1384 | } |
1385 | |
1386 | intp = state->internal; |
1387 | |
1388 | intp->demod_mode = p_init->demod_mode; |
1389 | stv0900_st_dvbs2_single(intp, LDPC_Mode: intp->demod_mode, demod: STV0900_DEMOD_1); |
1390 | intp->chip_id = stv0900_read_reg(intp, R0900_MID); |
1391 | intp->rolloff = p_init->rolloff; |
1392 | intp->quartz = p_init->dmd_ref_clk; |
1393 | |
1394 | stv0900_write_bits(intp, F0900_P1_ROLLOFF_CONTROL, val: p_init->rolloff); |
1395 | stv0900_write_bits(intp, F0900_P2_ROLLOFF_CONTROL, val: p_init->rolloff); |
1396 | |
1397 | intp->ts_config = p_init->ts_config; |
1398 | if (intp->ts_config == NULL) |
1399 | stv0900_set_ts_parallel_serial(intp, |
1400 | path1_ts: p_init->path1_ts_clock, |
1401 | path2_ts: p_init->path2_ts_clock); |
1402 | else { |
1403 | for (i = 0; intp->ts_config[i].addr != 0xffff; i++) |
1404 | stv0900_write_reg(intp, |
1405 | reg_addr: intp->ts_config[i].addr, |
1406 | reg_data: intp->ts_config[i].val); |
1407 | |
1408 | stv0900_write_bits(intp, F0900_P2_RST_HWARE, val: 1); |
1409 | stv0900_write_bits(intp, F0900_P2_RST_HWARE, val: 0); |
1410 | stv0900_write_bits(intp, F0900_P1_RST_HWARE, val: 1); |
1411 | stv0900_write_bits(intp, F0900_P1_RST_HWARE, val: 0); |
1412 | } |
1413 | |
1414 | intp->tuner_type[0] = p_init->tuner1_type; |
1415 | intp->tuner_type[1] = p_init->tuner2_type; |
1416 | /* tuner init */ |
1417 | switch (p_init->tuner1_type) { |
1418 | case 3: /*FE_AUTO_STB6100:*/ |
1419 | stv0900_write_reg(intp, R0900_P1_TNRCFG, reg_data: 0x3c); |
1420 | stv0900_write_reg(intp, R0900_P1_TNRCFG2, reg_data: 0x86); |
1421 | stv0900_write_reg(intp, R0900_P1_TNRCFG3, reg_data: 0x18); |
1422 | stv0900_write_reg(intp, R0900_P1_TNRXTAL, reg_data: 27); /* 27MHz */ |
1423 | stv0900_write_reg(intp, R0900_P1_TNRSTEPS, reg_data: 0x05); |
1424 | stv0900_write_reg(intp, R0900_P1_TNRGAIN, reg_data: 0x17); |
1425 | stv0900_write_reg(intp, R0900_P1_TNRADJ, reg_data: 0x1f); |
1426 | stv0900_write_reg(intp, R0900_P1_TNRCTL2, reg_data: 0x0); |
1427 | stv0900_write_bits(intp, F0900_P1_TUN_TYPE, val: 3); |
1428 | break; |
1429 | /* case FE_SW_TUNER: */ |
1430 | default: |
1431 | stv0900_write_bits(intp, F0900_P1_TUN_TYPE, val: 6); |
1432 | break; |
1433 | } |
1434 | |
1435 | stv0900_write_bits(intp, F0900_P1_TUN_MADDRESS, val: p_init->tun1_maddress); |
1436 | switch (p_init->tuner1_adc) { |
1437 | case 1: |
1438 | stv0900_write_reg(intp, R0900_TSTTNR1, reg_data: 0x26); |
1439 | break; |
1440 | default: |
1441 | break; |
1442 | } |
1443 | |
1444 | stv0900_write_reg(intp, R0900_P1_TNRLD, reg_data: 1); /* hw tuner */ |
1445 | |
1446 | /* tuner init */ |
1447 | switch (p_init->tuner2_type) { |
1448 | case 3: /*FE_AUTO_STB6100:*/ |
1449 | stv0900_write_reg(intp, R0900_P2_TNRCFG, reg_data: 0x3c); |
1450 | stv0900_write_reg(intp, R0900_P2_TNRCFG2, reg_data: 0x86); |
1451 | stv0900_write_reg(intp, R0900_P2_TNRCFG3, reg_data: 0x18); |
1452 | stv0900_write_reg(intp, R0900_P2_TNRXTAL, reg_data: 27); /* 27MHz */ |
1453 | stv0900_write_reg(intp, R0900_P2_TNRSTEPS, reg_data: 0x05); |
1454 | stv0900_write_reg(intp, R0900_P2_TNRGAIN, reg_data: 0x17); |
1455 | stv0900_write_reg(intp, R0900_P2_TNRADJ, reg_data: 0x1f); |
1456 | stv0900_write_reg(intp, R0900_P2_TNRCTL2, reg_data: 0x0); |
1457 | stv0900_write_bits(intp, F0900_P2_TUN_TYPE, val: 3); |
1458 | break; |
1459 | /* case FE_SW_TUNER: */ |
1460 | default: |
1461 | stv0900_write_bits(intp, F0900_P2_TUN_TYPE, val: 6); |
1462 | break; |
1463 | } |
1464 | |
1465 | stv0900_write_bits(intp, F0900_P2_TUN_MADDRESS, val: p_init->tun2_maddress); |
1466 | switch (p_init->tuner2_adc) { |
1467 | case 1: |
1468 | stv0900_write_reg(intp, R0900_TSTTNR3, reg_data: 0x26); |
1469 | break; |
1470 | default: |
1471 | break; |
1472 | } |
1473 | |
1474 | stv0900_write_reg(intp, R0900_P2_TNRLD, reg_data: 1); /* hw tuner */ |
1475 | |
1476 | stv0900_write_bits(intp, F0900_P1_TUN_IQSWAP, val: p_init->tun1_iq_inv); |
1477 | stv0900_write_bits(intp, F0900_P2_TUN_IQSWAP, val: p_init->tun2_iq_inv); |
1478 | stv0900_set_mclk(intp, mclk: 135000000); |
1479 | msleep(msecs: 3); |
1480 | |
1481 | switch (intp->clkmode) { |
1482 | case 0: |
1483 | case 2: |
1484 | stv0900_write_reg(intp, R0900_SYNTCTRL, reg_data: 0x20 | intp->clkmode); |
1485 | break; |
1486 | default: |
1487 | selosci = 0x02 & stv0900_read_reg(intp, R0900_SYNTCTRL); |
1488 | stv0900_write_reg(intp, R0900_SYNTCTRL, reg_data: 0x20 | selosci); |
1489 | break; |
1490 | } |
1491 | msleep(msecs: 3); |
1492 | |
1493 | intp->mclk = stv0900_get_mclk_freq(intp, ext_clk: intp->quartz); |
1494 | if (intp->errs) |
1495 | error = STV0900_I2C_ERROR; |
1496 | |
1497 | return error; |
1498 | } |
1499 | |
1500 | static int stv0900_status(struct stv0900_internal *intp, |
1501 | enum fe_stv0900_demod_num demod) |
1502 | { |
1503 | enum fe_stv0900_search_state demod_state; |
1504 | int locked = FALSE; |
1505 | u8 tsbitrate0_val, tsbitrate1_val; |
1506 | s32 bitrate; |
1507 | |
1508 | demod_state = stv0900_get_bits(intp, HEADER_MODE); |
1509 | switch (demod_state) { |
1510 | case STV0900_SEARCH: |
1511 | case STV0900_PLH_DETECTED: |
1512 | default: |
1513 | locked = FALSE; |
1514 | break; |
1515 | case STV0900_DVBS2_FOUND: |
1516 | locked = stv0900_get_bits(intp, LOCK_DEFINITIF) && |
1517 | stv0900_get_bits(intp, PKTDELIN_LOCK) && |
1518 | stv0900_get_bits(intp, TSFIFO_LINEOK); |
1519 | break; |
1520 | case STV0900_DVBS_FOUND: |
1521 | locked = stv0900_get_bits(intp, LOCK_DEFINITIF) && |
1522 | stv0900_get_bits(intp, LOCKEDVIT) && |
1523 | stv0900_get_bits(intp, TSFIFO_LINEOK); |
1524 | break; |
1525 | } |
1526 | |
1527 | dprintk("%s: locked = %d\n" , __func__, locked); |
1528 | |
1529 | if (stvdebug) { |
1530 | /* Print TS bitrate */ |
1531 | tsbitrate0_val = stv0900_read_reg(intp, TSBITRATE0); |
1532 | tsbitrate1_val = stv0900_read_reg(intp, TSBITRATE1); |
1533 | /* Formula Bit rate = Mclk * px_tsfifo_bitrate / 16384 */ |
1534 | bitrate = (stv0900_get_mclk_freq(intp, ext_clk: intp->quartz)/1000000) |
1535 | * (tsbitrate1_val << 8 | tsbitrate0_val); |
1536 | bitrate /= 16384; |
1537 | dprintk("TS bitrate = %d Mbit/sec\n" , bitrate); |
1538 | } |
1539 | |
1540 | return locked; |
1541 | } |
1542 | |
1543 | static int stv0900_set_mis(struct stv0900_internal *intp, |
1544 | enum fe_stv0900_demod_num demod, int mis) |
1545 | { |
1546 | dprintk("%s\n" , __func__); |
1547 | |
1548 | if (mis < 0 || mis > 255) { |
1549 | dprintk("Disable MIS filtering\n" ); |
1550 | stv0900_write_bits(intp, FILTER_EN, val: 0); |
1551 | } else { |
1552 | dprintk("Enable MIS filtering - %d\n" , mis); |
1553 | stv0900_write_bits(intp, FILTER_EN, val: 1); |
1554 | stv0900_write_reg(intp, ISIENTRY, reg_data: mis); |
1555 | stv0900_write_reg(intp, ISIBITENA, reg_data: 0xff); |
1556 | } |
1557 | |
1558 | return STV0900_NO_ERROR; |
1559 | } |
1560 | |
1561 | |
1562 | static enum dvbfe_search stv0900_search(struct dvb_frontend *fe) |
1563 | { |
1564 | struct stv0900_state *state = fe->demodulator_priv; |
1565 | struct stv0900_internal *intp = state->internal; |
1566 | enum fe_stv0900_demod_num demod = state->demod; |
1567 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
1568 | |
1569 | struct stv0900_search_params p_search; |
1570 | struct stv0900_signal_info p_result = intp->result[demod]; |
1571 | |
1572 | enum fe_stv0900_error error = STV0900_NO_ERROR; |
1573 | |
1574 | dprintk("%s: " , __func__); |
1575 | |
1576 | if (!(INRANGE(100000, c->symbol_rate, 70000000))) |
1577 | return DVBFE_ALGO_SEARCH_FAILED; |
1578 | |
1579 | if (state->config->set_ts_params) |
1580 | state->config->set_ts_params(fe, 0); |
1581 | |
1582 | stv0900_set_mis(intp, demod, mis: c->stream_id); |
1583 | |
1584 | p_result.locked = FALSE; |
1585 | p_search.path = demod; |
1586 | p_search.frequency = c->frequency; |
1587 | p_search.symbol_rate = c->symbol_rate; |
1588 | p_search.search_range = 10000000; |
1589 | p_search.fec = STV0900_FEC_UNKNOWN; |
1590 | p_search.standard = STV0900_AUTO_SEARCH; |
1591 | p_search.iq_inversion = STV0900_IQ_AUTO; |
1592 | p_search.search_algo = STV0900_BLIND_SEARCH; |
1593 | /* Speeds up DVB-S searching */ |
1594 | if (c->delivery_system == SYS_DVBS) |
1595 | p_search.standard = STV0900_SEARCH_DVBS1; |
1596 | |
1597 | intp->srch_standard[demod] = p_search.standard; |
1598 | intp->symbol_rate[demod] = p_search.symbol_rate; |
1599 | intp->srch_range[demod] = p_search.search_range; |
1600 | intp->freq[demod] = p_search.frequency; |
1601 | intp->srch_algo[demod] = p_search.search_algo; |
1602 | intp->srch_iq_inv[demod] = p_search.iq_inversion; |
1603 | intp->fec[demod] = p_search.fec; |
1604 | if ((stv0900_algo(fe) == STV0900_RANGEOK) && |
1605 | (intp->errs == STV0900_NO_ERROR)) { |
1606 | p_result.locked = intp->result[demod].locked; |
1607 | p_result.standard = intp->result[demod].standard; |
1608 | p_result.frequency = intp->result[demod].frequency; |
1609 | p_result.symbol_rate = intp->result[demod].symbol_rate; |
1610 | p_result.fec = intp->result[demod].fec; |
1611 | p_result.modcode = intp->result[demod].modcode; |
1612 | p_result.pilot = intp->result[demod].pilot; |
1613 | p_result.frame_len = intp->result[demod].frame_len; |
1614 | p_result.spectrum = intp->result[demod].spectrum; |
1615 | p_result.rolloff = intp->result[demod].rolloff; |
1616 | p_result.modulation = intp->result[demod].modulation; |
1617 | } else { |
1618 | p_result.locked = FALSE; |
1619 | switch (intp->err[demod]) { |
1620 | case STV0900_I2C_ERROR: |
1621 | error = STV0900_I2C_ERROR; |
1622 | break; |
1623 | case STV0900_NO_ERROR: |
1624 | default: |
1625 | error = STV0900_SEARCH_FAILED; |
1626 | break; |
1627 | } |
1628 | } |
1629 | |
1630 | if ((p_result.locked == TRUE) && (error == STV0900_NO_ERROR)) { |
1631 | dprintk("Search Success\n" ); |
1632 | return DVBFE_ALGO_SEARCH_SUCCESS; |
1633 | } else { |
1634 | dprintk("Search Fail\n" ); |
1635 | return DVBFE_ALGO_SEARCH_FAILED; |
1636 | } |
1637 | |
1638 | } |
1639 | |
1640 | static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status) |
1641 | { |
1642 | struct stv0900_state *state = fe->demodulator_priv; |
1643 | |
1644 | dprintk("%s: " , __func__); |
1645 | |
1646 | if ((stv0900_status(intp: state->internal, demod: state->demod)) == TRUE) { |
1647 | dprintk("DEMOD LOCK OK\n" ); |
1648 | *status = FE_HAS_CARRIER |
1649 | | FE_HAS_VITERBI |
1650 | | FE_HAS_SYNC |
1651 | | FE_HAS_LOCK; |
1652 | if (state->config->set_lock_led) |
1653 | state->config->set_lock_led(fe, 1); |
1654 | } else { |
1655 | *status = 0; |
1656 | if (state->config->set_lock_led) |
1657 | state->config->set_lock_led(fe, 0); |
1658 | dprintk("DEMOD LOCK FAIL\n" ); |
1659 | } |
1660 | |
1661 | return 0; |
1662 | } |
1663 | |
1664 | static int stv0900_stop_ts(struct dvb_frontend *fe, int stop_ts) |
1665 | { |
1666 | |
1667 | struct stv0900_state *state = fe->demodulator_priv; |
1668 | struct stv0900_internal *intp = state->internal; |
1669 | enum fe_stv0900_demod_num demod = state->demod; |
1670 | |
1671 | if (stop_ts == TRUE) |
1672 | stv0900_write_bits(intp, RST_HWARE, val: 1); |
1673 | else |
1674 | stv0900_write_bits(intp, RST_HWARE, val: 0); |
1675 | |
1676 | return 0; |
1677 | } |
1678 | |
1679 | static int stv0900_diseqc_init(struct dvb_frontend *fe) |
1680 | { |
1681 | struct stv0900_state *state = fe->demodulator_priv; |
1682 | struct stv0900_internal *intp = state->internal; |
1683 | enum fe_stv0900_demod_num demod = state->demod; |
1684 | |
1685 | stv0900_write_bits(intp, DISTX_MODE, val: state->config->diseqc_mode); |
1686 | stv0900_write_bits(intp, DISEQC_RESET, val: 1); |
1687 | stv0900_write_bits(intp, DISEQC_RESET, val: 0); |
1688 | |
1689 | return 0; |
1690 | } |
1691 | |
1692 | static int stv0900_init(struct dvb_frontend *fe) |
1693 | { |
1694 | dprintk("%s\n" , __func__); |
1695 | |
1696 | stv0900_stop_ts(fe, stop_ts: 1); |
1697 | stv0900_diseqc_init(fe); |
1698 | |
1699 | return 0; |
1700 | } |
1701 | |
1702 | static int stv0900_diseqc_send(struct stv0900_internal *intp , u8 *data, |
1703 | u32 NbData, enum fe_stv0900_demod_num demod) |
1704 | { |
1705 | s32 i = 0; |
1706 | |
1707 | stv0900_write_bits(intp, DIS_PRECHARGE, val: 1); |
1708 | while (i < NbData) { |
1709 | while (stv0900_get_bits(intp, FIFO_FULL)) |
1710 | ;/* checkpatch complains */ |
1711 | stv0900_write_reg(intp, DISTXDATA, reg_data: data[i]); |
1712 | i++; |
1713 | } |
1714 | |
1715 | stv0900_write_bits(intp, DIS_PRECHARGE, val: 0); |
1716 | i = 0; |
1717 | while ((stv0900_get_bits(intp, TX_IDLE) != 1) && (i < 10)) { |
1718 | msleep(msecs: 10); |
1719 | i++; |
1720 | } |
1721 | |
1722 | return 0; |
1723 | } |
1724 | |
1725 | static int stv0900_send_master_cmd(struct dvb_frontend *fe, |
1726 | struct dvb_diseqc_master_cmd *cmd) |
1727 | { |
1728 | struct stv0900_state *state = fe->demodulator_priv; |
1729 | |
1730 | return stv0900_diseqc_send(intp: state->internal, |
1731 | data: cmd->msg, |
1732 | NbData: cmd->msg_len, |
1733 | demod: state->demod); |
1734 | } |
1735 | |
1736 | static int stv0900_send_burst(struct dvb_frontend *fe, |
1737 | enum fe_sec_mini_cmd burst) |
1738 | { |
1739 | struct stv0900_state *state = fe->demodulator_priv; |
1740 | struct stv0900_internal *intp = state->internal; |
1741 | enum fe_stv0900_demod_num demod = state->demod; |
1742 | u8 data; |
1743 | |
1744 | |
1745 | switch (burst) { |
1746 | case SEC_MINI_A: |
1747 | stv0900_write_bits(intp, DISTX_MODE, val: 3);/* Unmodulated */ |
1748 | data = 0x00; |
1749 | stv0900_diseqc_send(intp, data: &data, NbData: 1, demod: state->demod); |
1750 | break; |
1751 | case SEC_MINI_B: |
1752 | stv0900_write_bits(intp, DISTX_MODE, val: 2);/* Modulated */ |
1753 | data = 0xff; |
1754 | stv0900_diseqc_send(intp, data: &data, NbData: 1, demod: state->demod); |
1755 | break; |
1756 | } |
1757 | |
1758 | return 0; |
1759 | } |
1760 | |
1761 | static int stv0900_recv_slave_reply(struct dvb_frontend *fe, |
1762 | struct dvb_diseqc_slave_reply *reply) |
1763 | { |
1764 | struct stv0900_state *state = fe->demodulator_priv; |
1765 | struct stv0900_internal *intp = state->internal; |
1766 | enum fe_stv0900_demod_num demod = state->demod; |
1767 | s32 i = 0; |
1768 | |
1769 | reply->msg_len = 0; |
1770 | |
1771 | while ((stv0900_get_bits(intp, RX_END) != 1) && (i < 10)) { |
1772 | msleep(msecs: 10); |
1773 | i++; |
1774 | } |
1775 | |
1776 | if (stv0900_get_bits(intp, RX_END)) { |
1777 | reply->msg_len = stv0900_get_bits(intp, FIFO_BYTENBR); |
1778 | |
1779 | for (i = 0; i < reply->msg_len; i++) |
1780 | reply->msg[i] = stv0900_read_reg(intp, DISRXDATA); |
1781 | } |
1782 | |
1783 | return 0; |
1784 | } |
1785 | |
1786 | static int stv0900_set_tone(struct dvb_frontend *fe, |
1787 | enum fe_sec_tone_mode toneoff) |
1788 | { |
1789 | struct stv0900_state *state = fe->demodulator_priv; |
1790 | struct stv0900_internal *intp = state->internal; |
1791 | enum fe_stv0900_demod_num demod = state->demod; |
1792 | |
1793 | dprintk("%s: %s\n" , __func__, ((toneoff == 0) ? "On" : "Off" )); |
1794 | |
1795 | switch (toneoff) { |
1796 | case SEC_TONE_ON: |
1797 | /*Set the DiseqC mode to 22Khz _continues_ tone*/ |
1798 | stv0900_write_bits(intp, DISTX_MODE, val: 0); |
1799 | stv0900_write_bits(intp, DISEQC_RESET, val: 1); |
1800 | /*release DiseqC reset to enable the 22KHz tone*/ |
1801 | stv0900_write_bits(intp, DISEQC_RESET, val: 0); |
1802 | break; |
1803 | case SEC_TONE_OFF: |
1804 | /*return diseqc mode to config->diseqc_mode. |
1805 | Usually it's without _continues_ tone */ |
1806 | stv0900_write_bits(intp, DISTX_MODE, |
1807 | val: state->config->diseqc_mode); |
1808 | /*maintain the DiseqC reset to disable the 22KHz tone*/ |
1809 | stv0900_write_bits(intp, DISEQC_RESET, val: 1); |
1810 | stv0900_write_bits(intp, DISEQC_RESET, val: 0); |
1811 | break; |
1812 | default: |
1813 | return -EINVAL; |
1814 | } |
1815 | |
1816 | return 0; |
1817 | } |
1818 | |
1819 | static void stv0900_release(struct dvb_frontend *fe) |
1820 | { |
1821 | struct stv0900_state *state = fe->demodulator_priv; |
1822 | |
1823 | dprintk("%s\n" , __func__); |
1824 | |
1825 | if (state->config->set_lock_led) |
1826 | state->config->set_lock_led(fe, 0); |
1827 | |
1828 | if ((--(state->internal->dmds_used)) <= 0) { |
1829 | |
1830 | dprintk("%s: Actually removing\n" , __func__); |
1831 | |
1832 | remove_inode(internal: state->internal); |
1833 | kfree(objp: state->internal); |
1834 | } |
1835 | |
1836 | kfree(objp: state); |
1837 | } |
1838 | |
1839 | static int stv0900_sleep(struct dvb_frontend *fe) |
1840 | { |
1841 | struct stv0900_state *state = fe->demodulator_priv; |
1842 | |
1843 | dprintk("%s\n" , __func__); |
1844 | |
1845 | if (state->config->set_lock_led) |
1846 | state->config->set_lock_led(fe, 0); |
1847 | |
1848 | return 0; |
1849 | } |
1850 | |
1851 | static int stv0900_get_frontend(struct dvb_frontend *fe, |
1852 | struct dtv_frontend_properties *p) |
1853 | { |
1854 | struct stv0900_state *state = fe->demodulator_priv; |
1855 | struct stv0900_internal *intp = state->internal; |
1856 | enum fe_stv0900_demod_num demod = state->demod; |
1857 | struct stv0900_signal_info p_result = intp->result[demod]; |
1858 | |
1859 | p->frequency = p_result.locked ? p_result.frequency : 0; |
1860 | p->symbol_rate = p_result.locked ? p_result.symbol_rate : 0; |
1861 | return 0; |
1862 | } |
1863 | |
1864 | static const struct dvb_frontend_ops stv0900_ops = { |
1865 | .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, |
1866 | .info = { |
1867 | .name = "STV0900 frontend" , |
1868 | .frequency_min_hz = 950 * MHz, |
1869 | .frequency_max_hz = 2150 * MHz, |
1870 | .frequency_stepsize_hz = 125 * kHz, |
1871 | .symbol_rate_min = 1000000, |
1872 | .symbol_rate_max = 45000000, |
1873 | .symbol_rate_tolerance = 500, |
1874 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | |
1875 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | |
1876 | FE_CAN_FEC_7_8 | FE_CAN_QPSK | |
1877 | FE_CAN_2G_MODULATION | |
1878 | FE_CAN_FEC_AUTO |
1879 | }, |
1880 | .release = stv0900_release, |
1881 | .init = stv0900_init, |
1882 | .get_frontend = stv0900_get_frontend, |
1883 | .sleep = stv0900_sleep, |
1884 | .get_frontend_algo = stv0900_frontend_algo, |
1885 | .i2c_gate_ctrl = stv0900_i2c_gate_ctrl, |
1886 | .diseqc_send_master_cmd = stv0900_send_master_cmd, |
1887 | .diseqc_send_burst = stv0900_send_burst, |
1888 | .diseqc_recv_slave_reply = stv0900_recv_slave_reply, |
1889 | .set_tone = stv0900_set_tone, |
1890 | .search = stv0900_search, |
1891 | .read_status = stv0900_read_status, |
1892 | .read_ber = stv0900_read_ber, |
1893 | .read_signal_strength = stv0900_read_signal_strength, |
1894 | .read_snr = stv0900_read_snr, |
1895 | .read_ucblocks = stv0900_read_ucblocks, |
1896 | }; |
1897 | |
1898 | struct dvb_frontend *stv0900_attach(const struct stv0900_config *config, |
1899 | struct i2c_adapter *i2c, |
1900 | int demod) |
1901 | { |
1902 | struct stv0900_state *state = NULL; |
1903 | struct stv0900_init_params init_params; |
1904 | enum fe_stv0900_error err_stv0900; |
1905 | |
1906 | state = kzalloc(size: sizeof(struct stv0900_state), GFP_KERNEL); |
1907 | if (state == NULL) |
1908 | goto error; |
1909 | |
1910 | state->demod = demod; |
1911 | state->config = config; |
1912 | state->i2c_adap = i2c; |
1913 | |
1914 | memcpy(&state->frontend.ops, &stv0900_ops, |
1915 | sizeof(struct dvb_frontend_ops)); |
1916 | state->frontend.demodulator_priv = state; |
1917 | |
1918 | switch (demod) { |
1919 | case 0: |
1920 | case 1: |
1921 | init_params.dmd_ref_clk = config->xtal; |
1922 | init_params.demod_mode = config->demod_mode; |
1923 | init_params.rolloff = STV0900_35; |
1924 | init_params.path1_ts_clock = config->path1_mode; |
1925 | init_params.tun1_maddress = config->tun1_maddress; |
1926 | init_params.tun1_iq_inv = STV0900_IQ_NORMAL; |
1927 | init_params.tuner1_adc = config->tun1_adc; |
1928 | init_params.tuner1_type = config->tun1_type; |
1929 | init_params.path2_ts_clock = config->path2_mode; |
1930 | init_params.ts_config = config->ts_config_regs; |
1931 | init_params.tun2_maddress = config->tun2_maddress; |
1932 | init_params.tuner2_adc = config->tun2_adc; |
1933 | init_params.tuner2_type = config->tun2_type; |
1934 | init_params.tun2_iq_inv = STV0900_IQ_SWAPPED; |
1935 | |
1936 | err_stv0900 = stv0900_init_internal(fe: &state->frontend, |
1937 | p_init: &init_params); |
1938 | |
1939 | if (err_stv0900) |
1940 | goto error; |
1941 | |
1942 | if (state->internal->chip_id >= 0x30) |
1943 | state->frontend.ops.info.caps |= FE_CAN_MULTISTREAM; |
1944 | |
1945 | break; |
1946 | default: |
1947 | goto error; |
1948 | break; |
1949 | } |
1950 | |
1951 | dprintk("%s: Attaching STV0900 demodulator(%d) \n" , __func__, demod); |
1952 | return &state->frontend; |
1953 | |
1954 | error: |
1955 | dprintk("%s: Failed to attach STV0900 demodulator(%d) \n" , |
1956 | __func__, demod); |
1957 | kfree(objp: state); |
1958 | return NULL; |
1959 | } |
1960 | EXPORT_SYMBOL_GPL(stv0900_attach); |
1961 | |
1962 | MODULE_PARM_DESC(debug, "Set debug" ); |
1963 | |
1964 | MODULE_AUTHOR("Igor M. Liplianin" ); |
1965 | MODULE_DESCRIPTION("ST STV0900 frontend" ); |
1966 | MODULE_LICENSE("GPL" ); |
1967 | |