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