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