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