]>
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 | ||
936c05e7 | 180 | static void extract_mask_pos(u32 label, u8 *mask, u8 *pos) |
99277b38 IL |
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 | ||
936c05e7 | 221 | static 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 | ||
936c05e7 | 285 | static 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 | ||
936c05e7 | 299 | static enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 mclk) |
99277b38 | 300 | { |
99277b38 IL |
301 | u32 m_div, clk_sel; |
302 | ||
1e0c397d IL |
303 | if (intp == NULL) |
304 | return STV0900_INVALID_HANDLE; | |
99277b38 | 305 | |
1e0c397d IL |
306 | if (intp->errs) |
307 | return STV0900_I2C_ERROR; | |
308 | ||
b0f9bf36 WY |
309 | dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk, |
310 | intp->quartz); | |
311 | ||
1e0c397d IL |
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 | ||
936c05e7 | 337 | static 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 | ||
4880f564 CD |
527 | frontend_ops = &fe->ops; |
528 | tuner_ops = &frontend_ops->tuner_ops; | |
99277b38 IL |
529 | |
530 | if (tuner_ops->set_frequency) { | |
531 | if ((tuner_ops->set_frequency(fe, frequency)) < 0) | |
532 | dprintk("%s: Invalid parameter\n", __func__); | |
533 | else | |
534 | dprintk("%s: Frequency=%d\n", __func__, frequency); | |
535 | ||
536 | } | |
537 | ||
538 | if (tuner_ops->set_bandwidth) { | |
539 | if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0) | |
540 | dprintk("%s: Invalid parameter\n", __func__); | |
541 | else | |
542 | dprintk("%s: Bandwidth=%d\n", __func__, bandwidth); | |
543 | ||
544 | } | |
545 | } | |
546 | ||
547 | void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) | |
548 | { | |
549 | struct dvb_frontend_ops *frontend_ops = NULL; | |
550 | struct dvb_tuner_ops *tuner_ops = NULL; | |
551 | ||
4880f564 CD |
552 | frontend_ops = &fe->ops; |
553 | tuner_ops = &frontend_ops->tuner_ops; | |
99277b38 IL |
554 | |
555 | if (tuner_ops->set_bandwidth) { | |
556 | if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0) | |
557 | dprintk("%s: Invalid parameter\n", __func__); | |
558 | else | |
559 | dprintk("%s: Bandwidth=%d\n", __func__, bandwidth); | |
560 | ||
561 | } | |
562 | } | |
563 | ||
cd79d33e IL |
564 | u32 stv0900_get_freq_auto(struct stv0900_internal *intp, int demod) |
565 | { | |
566 | u32 freq, round; | |
567 | /* Formulat : | |
568 | Tuner_Frequency(MHz) = Regs / 64 | |
569 | Tuner_granularity(MHz) = Regs / 2048 | |
570 | real_Tuner_Frequency = Tuner_Frequency(MHz) - Tuner_granularity(MHz) | |
571 | */ | |
572 | freq = (stv0900_get_bits(intp, TUN_RFFREQ2) << 10) + | |
573 | (stv0900_get_bits(intp, TUN_RFFREQ1) << 2) + | |
574 | stv0900_get_bits(intp, TUN_RFFREQ0); | |
575 | ||
576 | freq = (freq * 1000) / 64; | |
577 | ||
578 | round = (stv0900_get_bits(intp, TUN_RFRESTE1) >> 2) + | |
579 | stv0900_get_bits(intp, TUN_RFRESTE0); | |
580 | ||
581 | round = (round * 1000) / 2048; | |
582 | ||
583 | return freq + round; | |
584 | } | |
585 | ||
586 | void stv0900_set_tuner_auto(struct stv0900_internal *intp, u32 Frequency, | |
587 | u32 Bandwidth, int demod) | |
588 | { | |
589 | u32 tunerFrequency; | |
590 | /* Formulat: | |
591 | Tuner_frequency_reg= Frequency(MHz)*64 | |
592 | */ | |
593 | tunerFrequency = (Frequency * 64) / 1000; | |
594 | ||
595 | stv0900_write_bits(intp, TUN_RFFREQ2, (tunerFrequency >> 10)); | |
596 | stv0900_write_bits(intp, TUN_RFFREQ1, (tunerFrequency >> 2) & 0xff); | |
597 | stv0900_write_bits(intp, TUN_RFFREQ0, (tunerFrequency & 0x03)); | |
598 | /* Low Pass Filter = BW /2 (MHz)*/ | |
599 | stv0900_write_bits(intp, TUN_BW, Bandwidth / 2000000); | |
600 | /* Tuner Write trig */ | |
601 | stv0900_write_reg(intp, TNRLD, 1); | |
602 | } | |
603 | ||
1e0c397d | 604 | static s32 stv0900_get_rf_level(struct stv0900_internal *intp, |
99277b38 IL |
605 | const struct stv0900_table *lookup, |
606 | enum fe_stv0900_demod_num demod) | |
607 | { | |
608 | s32 agc_gain = 0, | |
609 | imin, | |
610 | imax, | |
611 | i, | |
612 | rf_lvl = 0; | |
613 | ||
8171c205 | 614 | dprintk("%s\n", __func__); |
99277b38 | 615 | |
1e0c397d IL |
616 | if ((lookup == NULL) || (lookup->size <= 0)) |
617 | return 0; | |
502cd96d | 618 | |
1e0c397d IL |
619 | agc_gain = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1), |
620 | stv0900_get_bits(intp, AGCIQ_VALUE0)); | |
99277b38 | 621 | |
1e0c397d IL |
622 | imin = 0; |
623 | imax = lookup->size - 1; | |
624 | if (INRANGE(lookup->table[imin].regval, agc_gain, | |
625 | lookup->table[imax].regval)) { | |
626 | while ((imax - imin) > 1) { | |
627 | i = (imax + imin) >> 1; | |
99277b38 | 628 | |
1e0c397d IL |
629 | if (INRANGE(lookup->table[imin].regval, |
630 | agc_gain, | |
631 | lookup->table[i].regval)) | |
632 | imax = i; | |
633 | else | |
634 | imin = i; | |
635 | } | |
99277b38 | 636 | |
1e0c397d IL |
637 | rf_lvl = (s32)agc_gain - lookup->table[imin].regval; |
638 | rf_lvl *= (lookup->table[imax].realval - | |
639 | lookup->table[imin].realval); | |
640 | rf_lvl /= (lookup->table[imax].regval - | |
641 | lookup->table[imin].regval); | |
642 | rf_lvl += lookup->table[imin].realval; | |
643 | } else if (agc_gain > lookup->table[0].regval) | |
644 | rf_lvl = 5; | |
645 | else if (agc_gain < lookup->table[lookup->size-1].regval) | |
646 | rf_lvl = -100; | |
99277b38 | 647 | |
8171c205 | 648 | dprintk("%s: RFLevel = %d\n", __func__, rf_lvl); |
99277b38 IL |
649 | |
650 | return rf_lvl; | |
651 | } | |
652 | ||
653 | static int stv0900_read_signal_strength(struct dvb_frontend *fe, u16 *strength) | |
654 | { | |
655 | struct stv0900_state *state = fe->demodulator_priv; | |
656 | struct stv0900_internal *internal = state->internal; | |
657 | s32 rflevel = stv0900_get_rf_level(internal, &stv0900_rf, | |
658 | state->demod); | |
659 | ||
502cd96d IL |
660 | rflevel = (rflevel + 100) * (65535 / 70); |
661 | if (rflevel < 0) | |
662 | rflevel = 0; | |
663 | ||
664 | if (rflevel > 65535) | |
665 | rflevel = 65535; | |
666 | ||
667 | *strength = rflevel; | |
99277b38 IL |
668 | |
669 | return 0; | |
670 | } | |
671 | ||
99277b38 IL |
672 | static s32 stv0900_carr_get_quality(struct dvb_frontend *fe, |
673 | const struct stv0900_table *lookup) | |
674 | { | |
675 | struct stv0900_state *state = fe->demodulator_priv; | |
1e0c397d | 676 | struct stv0900_internal *intp = state->internal; |
99277b38 IL |
677 | enum fe_stv0900_demod_num demod = state->demod; |
678 | ||
1e0c397d IL |
679 | s32 c_n = -100, |
680 | regval, | |
681 | imin, | |
682 | imax, | |
99277b38 | 683 | i, |
99277b38 IL |
684 | noise_field1, |
685 | noise_field0; | |
686 | ||
8171c205 | 687 | dprintk("%s\n", __func__); |
99277b38 | 688 | |
99277b38 | 689 | if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) { |
1e0c397d IL |
690 | noise_field1 = NOSPLHT_NORMED1; |
691 | noise_field0 = NOSPLHT_NORMED0; | |
99277b38 | 692 | } else { |
1e0c397d IL |
693 | noise_field1 = NOSDATAT_NORMED1; |
694 | noise_field0 = NOSDATAT_NORMED0; | |
99277b38 IL |
695 | } |
696 | ||
1e0c397d | 697 | if (stv0900_get_bits(intp, LOCK_DEFINITIF)) { |
99277b38 IL |
698 | if ((lookup != NULL) && lookup->size) { |
699 | regval = 0; | |
700 | msleep(5); | |
701 | for (i = 0; i < 16; i++) { | |
1e0c397d | 702 | regval += MAKEWORD(stv0900_get_bits(intp, |
11a84143 | 703 | noise_field1), |
1e0c397d | 704 | stv0900_get_bits(intp, |
11a84143 | 705 | noise_field0)); |
99277b38 IL |
706 | msleep(1); |
707 | } | |
708 | ||
709 | regval /= 16; | |
710 | imin = 0; | |
711 | imax = lookup->size - 1; | |
11a84143 IL |
712 | if (INRANGE(lookup->table[imin].regval, |
713 | regval, | |
714 | lookup->table[imax].regval)) { | |
99277b38 IL |
715 | while ((imax - imin) > 1) { |
716 | i = (imax + imin) >> 1; | |
11a84143 IL |
717 | if (INRANGE(lookup->table[imin].regval, |
718 | regval, | |
719 | lookup->table[i].regval)) | |
99277b38 IL |
720 | imax = i; |
721 | else | |
722 | imin = i; | |
723 | } | |
724 | ||
725 | c_n = ((regval - lookup->table[imin].regval) | |
11a84143 IL |
726 | * (lookup->table[imax].realval |
727 | - lookup->table[imin].realval) | |
728 | / (lookup->table[imax].regval | |
729 | - lookup->table[imin].regval)) | |
99277b38 IL |
730 | + lookup->table[imin].realval; |
731 | } else if (regval < lookup->table[imin].regval) | |
732 | c_n = 1000; | |
733 | } | |
734 | } | |
735 | ||
736 | return c_n; | |
737 | } | |
738 | ||
ee1ebcfe AO |
739 | static int stv0900_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks) |
740 | { | |
741 | struct stv0900_state *state = fe->demodulator_priv; | |
1e0c397d | 742 | struct stv0900_internal *intp = state->internal; |
ee1ebcfe AO |
743 | enum fe_stv0900_demod_num demod = state->demod; |
744 | u8 err_val1, err_val0; | |
ee1ebcfe AO |
745 | u32 header_err_val = 0; |
746 | ||
747 | *ucblocks = 0x0; | |
748 | if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) { | |
749 | /* DVB-S2 delineator errors count */ | |
750 | ||
751 | /* retreiving number for errnous headers */ | |
1e0c397d IL |
752 | err_val1 = stv0900_read_reg(intp, BBFCRCKO1); |
753 | err_val0 = stv0900_read_reg(intp, BBFCRCKO0); | |
754 | header_err_val = (err_val1 << 8) | err_val0; | |
ee1ebcfe AO |
755 | |
756 | /* retreiving number for errnous packets */ | |
1e0c397d IL |
757 | err_val1 = stv0900_read_reg(intp, UPCRCKO1); |
758 | err_val0 = stv0900_read_reg(intp, UPCRCKO0); | |
759 | *ucblocks = (err_val1 << 8) | err_val0; | |
ee1ebcfe AO |
760 | *ucblocks += header_err_val; |
761 | } | |
762 | ||
763 | return 0; | |
764 | } | |
765 | ||
99277b38 IL |
766 | static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr) |
767 | { | |
502cd96d | 768 | s32 snrlcl = stv0900_carr_get_quality(fe, |
11a84143 | 769 | (const struct stv0900_table *)&stv0900_s2_cn); |
502cd96d IL |
770 | snrlcl = (snrlcl + 30) * 384; |
771 | if (snrlcl < 0) | |
772 | snrlcl = 0; | |
773 | ||
774 | if (snrlcl > 65535) | |
775 | snrlcl = 65535; | |
776 | ||
777 | *snr = snrlcl; | |
99277b38 IL |
778 | |
779 | return 0; | |
780 | } | |
781 | ||
1e0c397d | 782 | static u32 stv0900_get_ber(struct stv0900_internal *intp, |
99277b38 IL |
783 | enum fe_stv0900_demod_num demod) |
784 | { | |
785 | u32 ber = 10000000, i; | |
99277b38 | 786 | s32 demod_state; |
99277b38 | 787 | |
1e0c397d | 788 | demod_state = stv0900_get_bits(intp, HEADER_MODE); |
99277b38 IL |
789 | |
790 | switch (demod_state) { | |
791 | case STV0900_SEARCH: | |
792 | case STV0900_PLH_DETECTED: | |
793 | default: | |
794 | ber = 10000000; | |
795 | break; | |
796 | case STV0900_DVBS_FOUND: | |
797 | ber = 0; | |
798 | for (i = 0; i < 5; i++) { | |
799 | msleep(5); | |
1e0c397d | 800 | ber += stv0900_get_err_count(intp, 0, demod); |
99277b38 IL |
801 | } |
802 | ||
803 | ber /= 5; | |
1e0c397d | 804 | if (stv0900_get_bits(intp, PRFVIT)) { |
99277b38 IL |
805 | ber *= 9766; |
806 | ber = ber >> 13; | |
807 | } | |
808 | ||
809 | break; | |
810 | case STV0900_DVBS2_FOUND: | |
811 | ber = 0; | |
812 | for (i = 0; i < 5; i++) { | |
813 | msleep(5); | |
1e0c397d | 814 | ber += stv0900_get_err_count(intp, 0, demod); |
99277b38 IL |
815 | } |
816 | ||
817 | ber /= 5; | |
1e0c397d | 818 | if (stv0900_get_bits(intp, PKTDELIN_LOCK)) { |
99277b38 IL |
819 | ber *= 9766; |
820 | ber = ber >> 13; | |
821 | } | |
822 | ||
823 | break; | |
824 | } | |
825 | ||
826 | return ber; | |
827 | } | |
828 | ||
829 | static int stv0900_read_ber(struct dvb_frontend *fe, u32 *ber) | |
830 | { | |
831 | struct stv0900_state *state = fe->demodulator_priv; | |
832 | struct stv0900_internal *internal = state->internal; | |
833 | ||
834 | *ber = stv0900_get_ber(internal, state->demod); | |
835 | ||
836 | return 0; | |
837 | } | |
838 | ||
1e0c397d | 839 | int stv0900_get_demod_lock(struct stv0900_internal *intp, |
99277b38 IL |
840 | enum fe_stv0900_demod_num demod, s32 time_out) |
841 | { | |
842 | s32 timer = 0, | |
1e0c397d | 843 | lock = 0; |
99277b38 IL |
844 | |
845 | enum fe_stv0900_search_state dmd_state; | |
846 | ||
99277b38 | 847 | while ((timer < time_out) && (lock == 0)) { |
1e0c397d | 848 | dmd_state = stv0900_get_bits(intp, HEADER_MODE); |
99277b38 IL |
849 | dprintk("Demod State = %d\n", dmd_state); |
850 | switch (dmd_state) { | |
851 | case STV0900_SEARCH: | |
852 | case STV0900_PLH_DETECTED: | |
853 | default: | |
854 | lock = 0; | |
855 | break; | |
856 | case STV0900_DVBS2_FOUND: | |
857 | case STV0900_DVBS_FOUND: | |
1e0c397d | 858 | lock = stv0900_get_bits(intp, LOCK_DEFINITIF); |
99277b38 IL |
859 | break; |
860 | } | |
861 | ||
862 | if (lock == 0) | |
863 | msleep(10); | |
864 | ||
865 | timer += 10; | |
866 | } | |
867 | ||
868 | if (lock) | |
869 | dprintk("DEMOD LOCK OK\n"); | |
870 | else | |
871 | dprintk("DEMOD LOCK FAIL\n"); | |
872 | ||
873 | return lock; | |
874 | } | |
875 | ||
1e0c397d | 876 | void stv0900_stop_all_s2_modcod(struct stv0900_internal *intp, |
99277b38 IL |
877 | enum fe_stv0900_demod_num demod) |
878 | { | |
879 | s32 regflist, | |
880 | i; | |
881 | ||
8171c205 | 882 | dprintk("%s\n", __func__); |
99277b38 | 883 | |
1e0c397d | 884 | regflist = MODCODLST0; |
99277b38 IL |
885 | |
886 | for (i = 0; i < 16; i++) | |
1e0c397d | 887 | stv0900_write_reg(intp, regflist + i, 0xff); |
99277b38 IL |
888 | } |
889 | ||
1e0c397d | 890 | void stv0900_activate_s2_modcod(struct stv0900_internal *intp, |
99277b38 IL |
891 | enum fe_stv0900_demod_num demod) |
892 | { | |
893 | u32 matype, | |
1e0c397d IL |
894 | mod_code, |
895 | fmod, | |
896 | reg_index, | |
897 | field_index; | |
99277b38 | 898 | |
8171c205 | 899 | dprintk("%s\n", __func__); |
99277b38 | 900 | |
1e0c397d | 901 | if (intp->chip_id <= 0x11) { |
99277b38 IL |
902 | msleep(5); |
903 | ||
1e0c397d IL |
904 | mod_code = stv0900_read_reg(intp, PLHMODCOD); |
905 | matype = mod_code & 0x3; | |
906 | mod_code = (mod_code & 0x7f) >> 2; | |
99277b38 | 907 | |
1e0c397d IL |
908 | reg_index = MODCODLSTF - mod_code / 2; |
909 | field_index = mod_code % 2; | |
99277b38 IL |
910 | |
911 | switch (matype) { | |
912 | case 0: | |
913 | default: | |
914 | fmod = 14; | |
915 | break; | |
916 | case 1: | |
917 | fmod = 13; | |
918 | break; | |
919 | case 2: | |
920 | fmod = 11; | |
921 | break; | |
922 | case 3: | |
923 | fmod = 7; | |
924 | break; | |
925 | } | |
926 | ||
927 | if ((INRANGE(STV0900_QPSK_12, mod_code, STV0900_8PSK_910)) | |
1e0c397d | 928 | && (matype <= 1)) { |
99277b38 | 929 | if (field_index == 0) |
1e0c397d | 930 | stv0900_write_reg(intp, reg_index, |
99277b38 IL |
931 | 0xf0 | fmod); |
932 | else | |
1e0c397d | 933 | stv0900_write_reg(intp, reg_index, |
99277b38 IL |
934 | (fmod << 4) | 0xf); |
935 | } | |
99277b38 | 936 | |
1e0c397d IL |
937 | } else if (intp->chip_id >= 0x12) { |
938 | for (reg_index = 0; reg_index < 7; reg_index++) | |
939 | stv0900_write_reg(intp, MODCODLST0 + reg_index, 0xff); | |
99277b38 | 940 | |
1e0c397d IL |
941 | stv0900_write_reg(intp, MODCODLSTE, 0xff); |
942 | stv0900_write_reg(intp, MODCODLSTF, 0xcf); | |
943 | for (reg_index = 0; reg_index < 8; reg_index++) | |
944 | stv0900_write_reg(intp, MODCODLST7 + reg_index, 0xcc); | |
99277b38 | 945 | |
99277b38 IL |
946 | |
947 | } | |
948 | } | |
949 | ||
1e0c397d | 950 | void stv0900_activate_s2_modcod_single(struct stv0900_internal *intp, |
99277b38 IL |
951 | enum fe_stv0900_demod_num demod) |
952 | { | |
953 | u32 reg_index; | |
954 | ||
8171c205 | 955 | dprintk("%s\n", __func__); |
99277b38 | 956 | |
1e0c397d IL |
957 | stv0900_write_reg(intp, MODCODLST0, 0xff); |
958 | stv0900_write_reg(intp, MODCODLST1, 0xf0); | |
959 | stv0900_write_reg(intp, MODCODLSTF, 0x0f); | |
960 | for (reg_index = 0; reg_index < 13; reg_index++) | |
961 | stv0900_write_reg(intp, MODCODLST2 + reg_index, 0); | |
99277b38 | 962 | |
99277b38 IL |
963 | } |
964 | ||
965 | static enum dvbfe_algo stv0900_frontend_algo(struct dvb_frontend *fe) | |
966 | { | |
967 | return DVBFE_ALGO_CUSTOM; | |
968 | } | |
969 | ||
1e0c397d | 970 | void stv0900_start_search(struct stv0900_internal *intp, |
99277b38 IL |
971 | enum fe_stv0900_demod_num demod) |
972 | { | |
1e0c397d IL |
973 | u32 freq; |
974 | s16 freq_s16 ; | |
975 | ||
976 | stv0900_write_bits(intp, DEMOD_MODE, 0x1f); | |
977 | if (intp->chip_id == 0x10) | |
978 | stv0900_write_reg(intp, CORRELEXP, 0xaa); | |
979 | ||
980 | if (intp->chip_id < 0x20) | |
981 | stv0900_write_reg(intp, CARHDR, 0x55); | |
982 | ||
983 | if (intp->chip_id <= 0x20) { | |
984 | if (intp->symbol_rate[0] <= 5000000) { | |
985 | stv0900_write_reg(intp, CARCFG, 0x44); | |
986 | stv0900_write_reg(intp, CFRUP1, 0x0f); | |
987 | stv0900_write_reg(intp, CFRUP0, 0xff); | |
988 | stv0900_write_reg(intp, CFRLOW1, 0xf0); | |
989 | stv0900_write_reg(intp, CFRLOW0, 0x00); | |
990 | stv0900_write_reg(intp, RTCS2, 0x68); | |
99277b38 | 991 | } else { |
1e0c397d IL |
992 | stv0900_write_reg(intp, CARCFG, 0xc4); |
993 | stv0900_write_reg(intp, RTCS2, 0x44); | |
99277b38 IL |
994 | } |
995 | ||
1e0c397d IL |
996 | } else { /*cut 3.0 above*/ |
997 | if (intp->symbol_rate[demod] <= 5000000) | |
998 | stv0900_write_reg(intp, RTCS2, 0x68); | |
999 | else | |
1000 | stv0900_write_reg(intp, RTCS2, 0x44); | |
99277b38 | 1001 | |
1e0c397d IL |
1002 | stv0900_write_reg(intp, CARCFG, 0x46); |
1003 | if (intp->srch_algo[demod] == STV0900_WARM_START) { | |
1004 | freq = 1000 << 16; | |
1005 | freq /= (intp->mclk / 1000); | |
1006 | freq_s16 = (s16)freq; | |
99277b38 | 1007 | } else { |
1e0c397d IL |
1008 | freq = (intp->srch_range[demod] / 2000); |
1009 | if (intp->symbol_rate[demod] <= 5000000) | |
1010 | freq += 80; | |
99277b38 | 1011 | else |
1e0c397d | 1012 | freq += 600; |
99277b38 | 1013 | |
1e0c397d IL |
1014 | freq = freq << 16; |
1015 | freq /= (intp->mclk / 1000); | |
1016 | freq_s16 = (s16)freq; | |
99277b38 IL |
1017 | } |
1018 | ||
1e0c397d IL |
1019 | stv0900_write_bits(intp, CFR_UP1, MSB(freq_s16)); |
1020 | stv0900_write_bits(intp, CFR_UP0, LSB(freq_s16)); | |
1021 | freq_s16 *= (-1); | |
1022 | stv0900_write_bits(intp, CFR_LOW1, MSB(freq_s16)); | |
1023 | stv0900_write_bits(intp, CFR_LOW0, LSB(freq_s16)); | |
1024 | } | |
99277b38 | 1025 | |
1e0c397d IL |
1026 | stv0900_write_reg(intp, CFRINIT1, 0); |
1027 | stv0900_write_reg(intp, CFRINIT0, 0); | |
99277b38 | 1028 | |
1e0c397d IL |
1029 | if (intp->chip_id >= 0x20) { |
1030 | stv0900_write_reg(intp, EQUALCFG, 0x41); | |
1031 | stv0900_write_reg(intp, FFECFG, 0x41); | |
99277b38 | 1032 | |
1e0c397d IL |
1033 | if ((intp->srch_standard[demod] == STV0900_SEARCH_DVBS1) || |
1034 | (intp->srch_standard[demod] == STV0900_SEARCH_DSS) || | |
1035 | (intp->srch_standard[demod] == STV0900_AUTO_SEARCH)) { | |
1036 | stv0900_write_reg(intp, VITSCALE, | |
1037 | 0x82); | |
1038 | stv0900_write_reg(intp, VAVSRVIT, 0x0); | |
1039 | } | |
1040 | } | |
99277b38 | 1041 | |
1e0c397d IL |
1042 | stv0900_write_reg(intp, SFRSTEP, 0x00); |
1043 | stv0900_write_reg(intp, TMGTHRISE, 0xe0); | |
1044 | stv0900_write_reg(intp, TMGTHFALL, 0xc0); | |
1045 | stv0900_write_bits(intp, SCAN_ENABLE, 0); | |
1046 | stv0900_write_bits(intp, CFR_AUTOSCAN, 0); | |
1047 | stv0900_write_bits(intp, S1S2_SEQUENTIAL, 0); | |
1048 | stv0900_write_reg(intp, RTC, 0x88); | |
1049 | if (intp->chip_id >= 0x20) { | |
1050 | if (intp->symbol_rate[demod] < 2000000) { | |
1051 | if (intp->chip_id <= 0x20) | |
1052 | stv0900_write_reg(intp, CARFREQ, 0x39); | |
1053 | else /*cut 3.0*/ | |
1054 | stv0900_write_reg(intp, CARFREQ, 0x89); | |
1055 | ||
1056 | stv0900_write_reg(intp, CARHDR, 0x40); | |
1057 | } else if (intp->symbol_rate[demod] < 10000000) { | |
1058 | stv0900_write_reg(intp, CARFREQ, 0x4c); | |
1059 | stv0900_write_reg(intp, CARHDR, 0x20); | |
99277b38 | 1060 | } else { |
1e0c397d IL |
1061 | stv0900_write_reg(intp, CARFREQ, 0x4b); |
1062 | stv0900_write_reg(intp, CARHDR, 0x20); | |
99277b38 IL |
1063 | } |
1064 | ||
1e0c397d IL |
1065 | } else { |
1066 | if (intp->symbol_rate[demod] < 10000000) | |
1067 | stv0900_write_reg(intp, CARFREQ, 0xef); | |
1068 | else | |
1069 | stv0900_write_reg(intp, CARFREQ, 0xed); | |
1070 | } | |
99277b38 | 1071 | |
1e0c397d IL |
1072 | switch (intp->srch_algo[demod]) { |
1073 | case STV0900_WARM_START: | |
1074 | stv0900_write_reg(intp, DMDISTATE, 0x1f); | |
1075 | stv0900_write_reg(intp, DMDISTATE, 0x18); | |
1076 | break; | |
1077 | case STV0900_COLD_START: | |
1078 | stv0900_write_reg(intp, DMDISTATE, 0x1f); | |
1079 | stv0900_write_reg(intp, DMDISTATE, 0x15); | |
1080 | break; | |
1081 | default: | |
99277b38 IL |
1082 | break; |
1083 | } | |
1084 | } | |
1085 | ||
1086 | u8 stv0900_get_optim_carr_loop(s32 srate, enum fe_stv0900_modcode modcode, | |
1087 | s32 pilot, u8 chip_id) | |
1088 | { | |
1089 | u8 aclc_value = 0x29; | |
1e0c397d IL |
1090 | s32 i; |
1091 | const struct stv0900_car_loop_optim *cls2, *cllqs2, *cllas2; | |
99277b38 | 1092 | |
8171c205 | 1093 | dprintk("%s\n", __func__); |
99277b38 | 1094 | |
1e0c397d IL |
1095 | if (chip_id <= 0x12) { |
1096 | cls2 = FE_STV0900_S2CarLoop; | |
1097 | cllqs2 = FE_STV0900_S2LowQPCarLoopCut30; | |
1098 | cllas2 = FE_STV0900_S2APSKCarLoopCut30; | |
1099 | } else if (chip_id == 0x20) { | |
1100 | cls2 = FE_STV0900_S2CarLoopCut20; | |
1101 | cllqs2 = FE_STV0900_S2LowQPCarLoopCut20; | |
1102 | cllas2 = FE_STV0900_S2APSKCarLoopCut20; | |
1103 | } else { | |
1104 | cls2 = FE_STV0900_S2CarLoopCut30; | |
1105 | cllqs2 = FE_STV0900_S2LowQPCarLoopCut30; | |
1106 | cllas2 = FE_STV0900_S2APSKCarLoopCut30; | |
1107 | } | |
99277b38 IL |
1108 | |
1109 | if (modcode < STV0900_QPSK_12) { | |
1110 | i = 0; | |
1e0c397d | 1111 | while ((i < 3) && (modcode != cllqs2[i].modcode)) |
99277b38 IL |
1112 | i++; |
1113 | ||
1114 | if (i >= 3) | |
1115 | i = 2; | |
1116 | } else { | |
1117 | i = 0; | |
1e0c397d | 1118 | while ((i < 14) && (modcode != cls2[i].modcode)) |
99277b38 IL |
1119 | i++; |
1120 | ||
1121 | if (i >= 14) { | |
1122 | i = 0; | |
1e0c397d | 1123 | while ((i < 11) && (modcode != cllas2[i].modcode)) |
99277b38 IL |
1124 | i++; |
1125 | ||
1126 | if (i >= 11) | |
1127 | i = 10; | |
1128 | } | |
1129 | } | |
1130 | ||
1131 | if (modcode <= STV0900_QPSK_25) { | |
1132 | if (pilot) { | |
1133 | if (srate <= 3000000) | |
1e0c397d | 1134 | aclc_value = cllqs2[i].car_loop_pilots_on_2; |
99277b38 | 1135 | else if (srate <= 7000000) |
1e0c397d | 1136 | aclc_value = cllqs2[i].car_loop_pilots_on_5; |
99277b38 | 1137 | else if (srate <= 15000000) |
1e0c397d | 1138 | aclc_value = cllqs2[i].car_loop_pilots_on_10; |
99277b38 | 1139 | else if (srate <= 25000000) |
1e0c397d | 1140 | aclc_value = cllqs2[i].car_loop_pilots_on_20; |
99277b38 | 1141 | else |
1e0c397d | 1142 | aclc_value = cllqs2[i].car_loop_pilots_on_30; |
99277b38 IL |
1143 | } else { |
1144 | if (srate <= 3000000) | |
1e0c397d | 1145 | aclc_value = cllqs2[i].car_loop_pilots_off_2; |
99277b38 | 1146 | else if (srate <= 7000000) |
1e0c397d | 1147 | aclc_value = cllqs2[i].car_loop_pilots_off_5; |
99277b38 | 1148 | else if (srate <= 15000000) |
1e0c397d | 1149 | aclc_value = cllqs2[i].car_loop_pilots_off_10; |
99277b38 | 1150 | else if (srate <= 25000000) |
1e0c397d | 1151 | aclc_value = cllqs2[i].car_loop_pilots_off_20; |
99277b38 | 1152 | else |
1e0c397d | 1153 | aclc_value = cllqs2[i].car_loop_pilots_off_30; |
99277b38 IL |
1154 | } |
1155 | ||
1156 | } else if (modcode <= STV0900_8PSK_910) { | |
1157 | if (pilot) { | |
1158 | if (srate <= 3000000) | |
1e0c397d | 1159 | aclc_value = cls2[i].car_loop_pilots_on_2; |
99277b38 | 1160 | else if (srate <= 7000000) |
1e0c397d | 1161 | aclc_value = cls2[i].car_loop_pilots_on_5; |
99277b38 | 1162 | else if (srate <= 15000000) |
1e0c397d | 1163 | aclc_value = cls2[i].car_loop_pilots_on_10; |
99277b38 | 1164 | else if (srate <= 25000000) |
1e0c397d | 1165 | aclc_value = cls2[i].car_loop_pilots_on_20; |
99277b38 | 1166 | else |
1e0c397d | 1167 | aclc_value = cls2[i].car_loop_pilots_on_30; |
99277b38 IL |
1168 | } else { |
1169 | if (srate <= 3000000) | |
1e0c397d | 1170 | aclc_value = cls2[i].car_loop_pilots_off_2; |
99277b38 | 1171 | else if (srate <= 7000000) |
1e0c397d | 1172 | aclc_value = cls2[i].car_loop_pilots_off_5; |
99277b38 | 1173 | else if (srate <= 15000000) |
1e0c397d | 1174 | aclc_value = cls2[i].car_loop_pilots_off_10; |
99277b38 | 1175 | else if (srate <= 25000000) |
1e0c397d | 1176 | aclc_value = cls2[i].car_loop_pilots_off_20; |
99277b38 | 1177 | else |
1e0c397d | 1178 | aclc_value = cls2[i].car_loop_pilots_off_30; |
99277b38 IL |
1179 | } |
1180 | ||
1181 | } else { | |
1182 | if (srate <= 3000000) | |
1e0c397d | 1183 | aclc_value = cllas2[i].car_loop_pilots_on_2; |
99277b38 | 1184 | else if (srate <= 7000000) |
1e0c397d | 1185 | aclc_value = cllas2[i].car_loop_pilots_on_5; |
99277b38 | 1186 | else if (srate <= 15000000) |
1e0c397d | 1187 | aclc_value = cllas2[i].car_loop_pilots_on_10; |
99277b38 | 1188 | else if (srate <= 25000000) |
1e0c397d | 1189 | aclc_value = cllas2[i].car_loop_pilots_on_20; |
99277b38 | 1190 | else |
1e0c397d | 1191 | aclc_value = cllas2[i].car_loop_pilots_on_30; |
99277b38 IL |
1192 | } |
1193 | ||
1194 | return aclc_value; | |
1195 | } | |
1196 | ||
1e0c397d IL |
1197 | u8 stv0900_get_optim_short_carr_loop(s32 srate, |
1198 | enum fe_stv0900_modulation modulation, | |
1199 | u8 chip_id) | |
99277b38 | 1200 | { |
1e0c397d IL |
1201 | const struct stv0900_short_frames_car_loop_optim *s2scl; |
1202 | const struct stv0900_short_frames_car_loop_optim_vs_mod *s2sclc30; | |
99277b38 | 1203 | s32 mod_index = 0; |
99277b38 IL |
1204 | u8 aclc_value = 0x0b; |
1205 | ||
8171c205 | 1206 | dprintk("%s\n", __func__); |
99277b38 | 1207 | |
1e0c397d IL |
1208 | s2scl = FE_STV0900_S2ShortCarLoop; |
1209 | s2sclc30 = FE_STV0900_S2ShortCarLoopCut30; | |
1210 | ||
99277b38 IL |
1211 | switch (modulation) { |
1212 | case STV0900_QPSK: | |
1213 | default: | |
1214 | mod_index = 0; | |
1215 | break; | |
1216 | case STV0900_8PSK: | |
1217 | mod_index = 1; | |
1218 | break; | |
1219 | case STV0900_16APSK: | |
1220 | mod_index = 2; | |
1221 | break; | |
1222 | case STV0900_32APSK: | |
1223 | mod_index = 3; | |
1224 | break; | |
1225 | } | |
1226 | ||
1e0c397d | 1227 | if (chip_id >= 0x30) { |
99277b38 | 1228 | if (srate <= 3000000) |
1e0c397d | 1229 | aclc_value = s2sclc30[mod_index].car_loop_2; |
99277b38 | 1230 | else if (srate <= 7000000) |
1e0c397d | 1231 | aclc_value = s2sclc30[mod_index].car_loop_5; |
99277b38 | 1232 | else if (srate <= 15000000) |
1e0c397d | 1233 | aclc_value = s2sclc30[mod_index].car_loop_10; |
99277b38 | 1234 | else if (srate <= 25000000) |
1e0c397d | 1235 | aclc_value = s2sclc30[mod_index].car_loop_20; |
99277b38 | 1236 | else |
1e0c397d | 1237 | aclc_value = s2sclc30[mod_index].car_loop_30; |
99277b38 | 1238 | |
1e0c397d | 1239 | } else if (chip_id >= 0x20) { |
99277b38 | 1240 | if (srate <= 3000000) |
1e0c397d | 1241 | aclc_value = s2scl[mod_index].car_loop_cut20_2; |
99277b38 | 1242 | else if (srate <= 7000000) |
1e0c397d | 1243 | aclc_value = s2scl[mod_index].car_loop_cut20_5; |
99277b38 | 1244 | else if (srate <= 15000000) |
1e0c397d | 1245 | aclc_value = s2scl[mod_index].car_loop_cut20_10; |
99277b38 | 1246 | else if (srate <= 25000000) |
1e0c397d | 1247 | aclc_value = s2scl[mod_index].car_loop_cut20_20; |
99277b38 | 1248 | else |
1e0c397d IL |
1249 | aclc_value = s2scl[mod_index].car_loop_cut20_30; |
1250 | ||
1251 | } else { | |
1252 | if (srate <= 3000000) | |
1253 | aclc_value = s2scl[mod_index].car_loop_cut12_2; | |
1254 | else if (srate <= 7000000) | |
1255 | aclc_value = s2scl[mod_index].car_loop_cut12_5; | |
1256 | else if (srate <= 15000000) | |
1257 | aclc_value = s2scl[mod_index].car_loop_cut12_10; | |
1258 | else if (srate <= 25000000) | |
1259 | aclc_value = s2scl[mod_index].car_loop_cut12_20; | |
1260 | else | |
1261 | aclc_value = s2scl[mod_index].car_loop_cut12_30; | |
99277b38 | 1262 | |
99277b38 IL |
1263 | } |
1264 | ||
1265 | return aclc_value; | |
1266 | } | |
1267 | ||
1e0c397d IL |
1268 | static |
1269 | enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *intp, | |
99277b38 IL |
1270 | enum fe_stv0900_demod_mode LDPC_Mode, |
1271 | enum fe_stv0900_demod_num demod) | |
1272 | { | |
1273 | enum fe_stv0900_error error = STV0900_NO_ERROR; | |
1e0c397d | 1274 | s32 reg_ind; |
99277b38 | 1275 | |
8171c205 | 1276 | dprintk("%s\n", __func__); |
99277b38 IL |
1277 | |
1278 | switch (LDPC_Mode) { | |
1279 | case STV0900_DUAL: | |
1280 | default: | |
1e0c397d IL |
1281 | if ((intp->demod_mode != STV0900_DUAL) |
1282 | || (stv0900_get_bits(intp, F0900_DDEMOD) != 1)) { | |
1283 | stv0900_write_reg(intp, R0900_GENCFG, 0x1d); | |
1284 | ||
1285 | intp->demod_mode = STV0900_DUAL; | |
1286 | ||
1287 | stv0900_write_bits(intp, F0900_FRESFEC, 1); | |
1288 | stv0900_write_bits(intp, F0900_FRESFEC, 0); | |
1289 | ||
1290 | for (reg_ind = 0; reg_ind < 7; reg_ind++) | |
1291 | stv0900_write_reg(intp, | |
1292 | R0900_P1_MODCODLST0 + reg_ind, | |
1293 | 0xff); | |
1294 | for (reg_ind = 0; reg_ind < 8; reg_ind++) | |
1295 | stv0900_write_reg(intp, | |
1296 | R0900_P1_MODCODLST7 + reg_ind, | |
1297 | 0xcc); | |
1298 | ||
1299 | stv0900_write_reg(intp, R0900_P1_MODCODLSTE, 0xff); | |
1300 | stv0900_write_reg(intp, R0900_P1_MODCODLSTF, 0xcf); | |
1301 | ||
1302 | for (reg_ind = 0; reg_ind < 7; reg_ind++) | |
1303 | stv0900_write_reg(intp, | |
1304 | R0900_P2_MODCODLST0 + reg_ind, | |
1305 | 0xff); | |
1306 | for (reg_ind = 0; reg_ind < 8; reg_ind++) | |
1307 | stv0900_write_reg(intp, | |
1308 | R0900_P2_MODCODLST7 + reg_ind, | |
1309 | 0xcc); | |
1310 | ||
1311 | stv0900_write_reg(intp, R0900_P2_MODCODLSTE, 0xff); | |
1312 | stv0900_write_reg(intp, R0900_P2_MODCODLSTF, 0xcf); | |
99277b38 IL |
1313 | } |
1314 | ||
1315 | break; | |
1316 | case STV0900_SINGLE: | |
1e0c397d IL |
1317 | if (demod == STV0900_DEMOD_2) { |
1318 | stv0900_stop_all_s2_modcod(intp, STV0900_DEMOD_1); | |
1319 | stv0900_activate_s2_modcod_single(intp, | |
1320 | STV0900_DEMOD_2); | |
1321 | stv0900_write_reg(intp, R0900_GENCFG, 0x06); | |
1322 | } else { | |
1323 | stv0900_stop_all_s2_modcod(intp, STV0900_DEMOD_2); | |
1324 | stv0900_activate_s2_modcod_single(intp, | |
1325 | STV0900_DEMOD_1); | |
1326 | stv0900_write_reg(intp, R0900_GENCFG, 0x04); | |
1327 | } | |
99277b38 | 1328 | |
1e0c397d | 1329 | intp->demod_mode = STV0900_SINGLE; |
99277b38 | 1330 | |
1e0c397d IL |
1331 | stv0900_write_bits(intp, F0900_FRESFEC, 1); |
1332 | stv0900_write_bits(intp, F0900_FRESFEC, 0); | |
1333 | stv0900_write_bits(intp, F0900_P1_ALGOSWRST, 1); | |
1334 | stv0900_write_bits(intp, F0900_P1_ALGOSWRST, 0); | |
1335 | stv0900_write_bits(intp, F0900_P2_ALGOSWRST, 1); | |
1336 | stv0900_write_bits(intp, F0900_P2_ALGOSWRST, 0); | |
99277b38 IL |
1337 | break; |
1338 | } | |
1339 | ||
1340 | return error; | |
1341 | } | |
1342 | ||
1343 | static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe, | |
1344 | struct stv0900_init_params *p_init) | |
1345 | { | |
1346 | struct stv0900_state *state = fe->demodulator_priv; | |
1347 | enum fe_stv0900_error error = STV0900_NO_ERROR; | |
1348 | enum fe_stv0900_error demodError = STV0900_NO_ERROR; | |
1e0c397d | 1349 | struct stv0900_internal *intp = NULL; |
f867c3f4 | 1350 | int selosci, i; |
99277b38 IL |
1351 | |
1352 | struct stv0900_inode *temp_int = find_inode(state->i2c_adap, | |
1353 | state->config->demod_address); | |
1354 | ||
8171c205 | 1355 | dprintk("%s\n", __func__); |
99277b38 | 1356 | |
29372a8d | 1357 | if ((temp_int != NULL) && (p_init->demod_mode == STV0900_DUAL)) { |
99277b38 IL |
1358 | state->internal = temp_int->internal; |
1359 | (state->internal->dmds_used)++; | |
8171c205 | 1360 | dprintk("%s: Find Internal Structure!\n", __func__); |
99277b38 IL |
1361 | return STV0900_NO_ERROR; |
1362 | } else { | |
1e0c397d IL |
1363 | state->internal = kmalloc(sizeof(struct stv0900_internal), |
1364 | GFP_KERNEL); | |
fb3ab105 RK |
1365 | if (state->internal == NULL) |
1366 | return STV0900_INVALID_HANDLE; | |
99277b38 | 1367 | temp_int = append_internal(state->internal); |
fb3ab105 RK |
1368 | if (temp_int == NULL) { |
1369 | kfree(state->internal); | |
1370 | state->internal = NULL; | |
1371 | return STV0900_INVALID_HANDLE; | |
1372 | } | |
99277b38 IL |
1373 | state->internal->dmds_used = 1; |
1374 | state->internal->i2c_adap = state->i2c_adap; | |
1375 | state->internal->i2c_addr = state->config->demod_address; | |
1376 | state->internal->clkmode = state->config->clkmode; | |
1377 | state->internal->errs = STV0900_NO_ERROR; | |
8171c205 | 1378 | dprintk("%s: Create New Internal Structure!\n", __func__); |
99277b38 IL |
1379 | } |
1380 | ||
1e0c397d IL |
1381 | if (state->internal == NULL) { |
1382 | error = STV0900_INVALID_HANDLE; | |
1383 | return error; | |
1384 | } | |
99277b38 | 1385 | |
1e0c397d IL |
1386 | demodError = stv0900_initialize(state->internal); |
1387 | if (demodError == STV0900_NO_ERROR) { | |
1388 | error = STV0900_NO_ERROR; | |
1389 | } else { | |
1390 | if (demodError == STV0900_INVALID_HANDLE) | |
1391 | error = STV0900_INVALID_HANDLE; | |
1392 | else | |
1393 | error = STV0900_I2C_ERROR; | |
f867c3f4 | 1394 | |
1e0c397d IL |
1395 | return error; |
1396 | } | |
99277b38 | 1397 | |
1e0c397d | 1398 | intp = state->internal; |
99277b38 | 1399 | |
1e0c397d IL |
1400 | intp->demod_mode = p_init->demod_mode; |
1401 | stv0900_st_dvbs2_single(intp, intp->demod_mode, STV0900_DEMOD_1); | |
1402 | intp->chip_id = stv0900_read_reg(intp, R0900_MID); | |
1403 | intp->rolloff = p_init->rolloff; | |
1404 | intp->quartz = p_init->dmd_ref_clk; | |
1405 | ||
1406 | stv0900_write_bits(intp, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff); | |
1407 | stv0900_write_bits(intp, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff); | |
1408 | ||
1409 | intp->ts_config = p_init->ts_config; | |
1410 | if (intp->ts_config == NULL) | |
1411 | stv0900_set_ts_parallel_serial(intp, | |
1412 | p_init->path1_ts_clock, | |
1413 | p_init->path2_ts_clock); | |
1414 | else { | |
1415 | for (i = 0; intp->ts_config[i].addr != 0xffff; i++) | |
1416 | stv0900_write_reg(intp, | |
1417 | intp->ts_config[i].addr, | |
1418 | intp->ts_config[i].val); | |
1419 | ||
1420 | stv0900_write_bits(intp, F0900_P2_RST_HWARE, 1); | |
1421 | stv0900_write_bits(intp, F0900_P2_RST_HWARE, 0); | |
1422 | stv0900_write_bits(intp, F0900_P1_RST_HWARE, 1); | |
1423 | stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0); | |
1424 | } | |
1425 | ||
cd79d33e IL |
1426 | intp->tuner_type[0] = p_init->tuner1_type; |
1427 | intp->tuner_type[1] = p_init->tuner2_type; | |
1428 | /* tuner init */ | |
1429 | switch (p_init->tuner1_type) { | |
1430 | case 3: /*FE_AUTO_STB6100:*/ | |
1431 | stv0900_write_reg(intp, R0900_P1_TNRCFG, 0x3c); | |
1432 | stv0900_write_reg(intp, R0900_P1_TNRCFG2, 0x86); | |
1433 | stv0900_write_reg(intp, R0900_P1_TNRCFG3, 0x18); | |
1434 | stv0900_write_reg(intp, R0900_P1_TNRXTAL, 27); /* 27MHz */ | |
1435 | stv0900_write_reg(intp, R0900_P1_TNRSTEPS, 0x05); | |
1436 | stv0900_write_reg(intp, R0900_P1_TNRGAIN, 0x17); | |
1437 | stv0900_write_reg(intp, R0900_P1_TNRADJ, 0x1f); | |
1438 | stv0900_write_reg(intp, R0900_P1_TNRCTL2, 0x0); | |
1439 | stv0900_write_bits(intp, F0900_P1_TUN_TYPE, 3); | |
1440 | break; | |
1441 | /* case FE_SW_TUNER: */ | |
1442 | default: | |
1443 | stv0900_write_bits(intp, F0900_P1_TUN_TYPE, 6); | |
1444 | break; | |
1445 | } | |
1446 | ||
1e0c397d IL |
1447 | stv0900_write_bits(intp, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress); |
1448 | switch (p_init->tuner1_adc) { | |
1449 | case 1: | |
1450 | stv0900_write_reg(intp, R0900_TSTTNR1, 0x26); | |
1451 | break; | |
1452 | default: | |
1453 | break; | |
1454 | } | |
1455 | ||
cd79d33e IL |
1456 | stv0900_write_reg(intp, R0900_P1_TNRLD, 1); /* hw tuner */ |
1457 | ||
1458 | /* tuner init */ | |
1459 | switch (p_init->tuner2_type) { | |
1460 | case 3: /*FE_AUTO_STB6100:*/ | |
1461 | stv0900_write_reg(intp, R0900_P2_TNRCFG, 0x3c); | |
1462 | stv0900_write_reg(intp, R0900_P2_TNRCFG2, 0x86); | |
1463 | stv0900_write_reg(intp, R0900_P2_TNRCFG3, 0x18); | |
1464 | stv0900_write_reg(intp, R0900_P2_TNRXTAL, 27); /* 27MHz */ | |
1465 | stv0900_write_reg(intp, R0900_P2_TNRSTEPS, 0x05); | |
1466 | stv0900_write_reg(intp, R0900_P2_TNRGAIN, 0x17); | |
1467 | stv0900_write_reg(intp, R0900_P2_TNRADJ, 0x1f); | |
1468 | stv0900_write_reg(intp, R0900_P2_TNRCTL2, 0x0); | |
1469 | stv0900_write_bits(intp, F0900_P2_TUN_TYPE, 3); | |
1470 | break; | |
1471 | /* case FE_SW_TUNER: */ | |
1472 | default: | |
1473 | stv0900_write_bits(intp, F0900_P2_TUN_TYPE, 6); | |
1474 | break; | |
1475 | } | |
1476 | ||
1e0c397d IL |
1477 | stv0900_write_bits(intp, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress); |
1478 | switch (p_init->tuner2_adc) { | |
1479 | case 1: | |
1480 | stv0900_write_reg(intp, R0900_TSTTNR3, 0x26); | |
1481 | break; | |
1482 | default: | |
1483 | break; | |
99277b38 IL |
1484 | } |
1485 | ||
cd79d33e IL |
1486 | stv0900_write_reg(intp, R0900_P2_TNRLD, 1); /* hw tuner */ |
1487 | ||
1e0c397d IL |
1488 | stv0900_write_bits(intp, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inv); |
1489 | stv0900_write_bits(intp, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inv); | |
1490 | stv0900_set_mclk(intp, 135000000); | |
1491 | msleep(3); | |
1492 | ||
1493 | switch (intp->clkmode) { | |
1494 | case 0: | |
1495 | case 2: | |
1496 | stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | intp->clkmode); | |
1497 | break; | |
1498 | default: | |
1499 | selosci = 0x02 & stv0900_read_reg(intp, R0900_SYNTCTRL); | |
1500 | stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | selosci); | |
1501 | break; | |
1502 | } | |
1503 | msleep(3); | |
1504 | ||
1505 | intp->mclk = stv0900_get_mclk_freq(intp, intp->quartz); | |
1506 | if (intp->errs) | |
1507 | error = STV0900_I2C_ERROR; | |
1508 | ||
99277b38 IL |
1509 | return error; |
1510 | } | |
1511 | ||
1e0c397d | 1512 | static int stv0900_status(struct stv0900_internal *intp, |
99277b38 IL |
1513 | enum fe_stv0900_demod_num demod) |
1514 | { | |
1515 | enum fe_stv0900_search_state demod_state; | |
99277b38 | 1516 | int locked = FALSE; |
247cb142 AO |
1517 | u8 tsbitrate0_val, tsbitrate1_val; |
1518 | s32 bitrate; | |
99277b38 | 1519 | |
1e0c397d | 1520 | demod_state = stv0900_get_bits(intp, HEADER_MODE); |
99277b38 IL |
1521 | switch (demod_state) { |
1522 | case STV0900_SEARCH: | |
1523 | case STV0900_PLH_DETECTED: | |
1524 | default: | |
1525 | locked = FALSE; | |
1526 | break; | |
1527 | case STV0900_DVBS2_FOUND: | |
1e0c397d IL |
1528 | locked = stv0900_get_bits(intp, LOCK_DEFINITIF) && |
1529 | stv0900_get_bits(intp, PKTDELIN_LOCK) && | |
1530 | stv0900_get_bits(intp, TSFIFO_LINEOK); | |
99277b38 IL |
1531 | break; |
1532 | case STV0900_DVBS_FOUND: | |
1e0c397d IL |
1533 | locked = stv0900_get_bits(intp, LOCK_DEFINITIF) && |
1534 | stv0900_get_bits(intp, LOCKEDVIT) && | |
1535 | stv0900_get_bits(intp, TSFIFO_LINEOK); | |
99277b38 IL |
1536 | break; |
1537 | } | |
1538 | ||
1e0c397d IL |
1539 | dprintk("%s: locked = %d\n", __func__, locked); |
1540 | ||
247cb142 AO |
1541 | if (stvdebug) { |
1542 | /* Print TS bitrate */ | |
1543 | tsbitrate0_val = stv0900_read_reg(intp, TSBITRATE0); | |
1544 | tsbitrate1_val = stv0900_read_reg(intp, TSBITRATE1); | |
1545 | /* Formula Bit rate = Mclk * px_tsfifo_bitrate / 16384 */ | |
1546 | bitrate = (stv0900_get_mclk_freq(intp, intp->quartz)/1000000) | |
1547 | * (tsbitrate1_val << 8 | tsbitrate0_val); | |
1548 | bitrate /= 16384; | |
c2c1b415 PST |
1549 | dprintk("TS bitrate = %d Mbit/sec\n", bitrate); |
1550 | } | |
247cb142 | 1551 | |
99277b38 IL |
1552 | return locked; |
1553 | } | |
1554 | ||
73ec66c0 EP |
1555 | static int stv0900_set_mis(struct stv0900_internal *intp, |
1556 | enum fe_stv0900_demod_num demod, int mis) | |
1557 | { | |
1558 | enum fe_stv0900_error error = STV0900_NO_ERROR; | |
1559 | ||
1560 | dprintk("%s\n", __func__); | |
1561 | ||
1562 | if (mis < 0 || mis > 255) { | |
1563 | dprintk("Disable MIS filtering\n"); | |
1564 | stv0900_write_bits(intp, FILTER_EN, 0); | |
1565 | } else { | |
1566 | dprintk("Enable MIS filtering - %d\n", mis); | |
1567 | stv0900_write_bits(intp, FILTER_EN, 1); | |
1568 | stv0900_write_reg(intp, ISIENTRY, mis); | |
1569 | stv0900_write_reg(intp, ISIBITENA, 0xff); | |
1570 | } | |
1571 | ||
1572 | return error; | |
1573 | } | |
1574 | ||
1575 | ||
41da5320 | 1576 | static enum dvbfe_search stv0900_search(struct dvb_frontend *fe) |
99277b38 IL |
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; | |
403c34f6 | 1584 | struct stv0900_signal_info p_result = intp->result[demod]; |
99277b38 IL |
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 | ||
73ec66c0 EP |
1596 | stv0900_set_mis(intp, demod, c->stream_id); |
1597 | ||
99277b38 | 1598 | p_result.locked = FALSE; |
1e0c397d | 1599 | p_search.path = demod; |
99277b38 IL |
1600 | p_search.frequency = c->frequency; |
1601 | p_search.symbol_rate = c->symbol_rate; | |
1602 | p_search.search_range = 10000000; | |
1603 | p_search.fec = STV0900_FEC_UNKNOWN; | |
1604 | p_search.standard = STV0900_AUTO_SEARCH; | |
1605 | p_search.iq_inversion = STV0900_IQ_AUTO; | |
1606 | p_search.search_algo = STV0900_BLIND_SEARCH; | |
38cdbce7 IL |
1607 | /* Speeds up DVB-S searching */ |
1608 | if (c->delivery_system == SYS_DVBS) | |
1609 | p_search.standard = STV0900_SEARCH_DVBS1; | |
99277b38 | 1610 | |
1e0c397d IL |
1611 | intp->srch_standard[demod] = p_search.standard; |
1612 | intp->symbol_rate[demod] = p_search.symbol_rate; | |
1613 | intp->srch_range[demod] = p_search.search_range; | |
1614 | intp->freq[demod] = p_search.frequency; | |
1615 | intp->srch_algo[demod] = p_search.search_algo; | |
1616 | intp->srch_iq_inv[demod] = p_search.iq_inversion; | |
1617 | intp->fec[demod] = p_search.fec; | |
1618 | if ((stv0900_algo(fe) == STV0900_RANGEOK) && | |
1619 | (intp->errs == STV0900_NO_ERROR)) { | |
1620 | p_result.locked = intp->result[demod].locked; | |
1621 | p_result.standard = intp->result[demod].standard; | |
1622 | p_result.frequency = intp->result[demod].frequency; | |
1623 | p_result.symbol_rate = intp->result[demod].symbol_rate; | |
1624 | p_result.fec = intp->result[demod].fec; | |
1625 | p_result.modcode = intp->result[demod].modcode; | |
1626 | p_result.pilot = intp->result[demod].pilot; | |
1627 | p_result.frame_len = intp->result[demod].frame_len; | |
1628 | p_result.spectrum = intp->result[demod].spectrum; | |
1629 | p_result.rolloff = intp->result[demod].rolloff; | |
1630 | p_result.modulation = intp->result[demod].modulation; | |
1631 | } else { | |
1632 | p_result.locked = FALSE; | |
1633 | switch (intp->err[demod]) { | |
1634 | case STV0900_I2C_ERROR: | |
1635 | error = STV0900_I2C_ERROR; | |
99277b38 | 1636 | break; |
1e0c397d IL |
1637 | case STV0900_NO_ERROR: |
1638 | default: | |
1639 | error = STV0900_SEARCH_FAILED; | |
99277b38 IL |
1640 | break; |
1641 | } | |
1e0c397d | 1642 | } |
99277b38 IL |
1643 | |
1644 | if ((p_result.locked == TRUE) && (error == STV0900_NO_ERROR)) { | |
8171c205 | 1645 | dprintk("Search Success\n"); |
99277b38 IL |
1646 | return DVBFE_ALGO_SEARCH_SUCCESS; |
1647 | } else { | |
8171c205 | 1648 | dprintk("Search Fail\n"); |
99277b38 IL |
1649 | return DVBFE_ALGO_SEARCH_FAILED; |
1650 | } | |
1651 | ||
99277b38 IL |
1652 | } |
1653 | ||
1654 | static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status) | |
1655 | { | |
1656 | struct stv0900_state *state = fe->demodulator_priv; | |
1657 | ||
78175bf2 | 1658 | dprintk("%s: ", __func__); |
99277b38 IL |
1659 | |
1660 | if ((stv0900_status(state->internal, state->demod)) == TRUE) { | |
1661 | dprintk("DEMOD LOCK OK\n"); | |
1662 | *status = FE_HAS_CARRIER | |
1663 | | FE_HAS_VITERBI | |
1664 | | FE_HAS_SYNC | |
1665 | | FE_HAS_LOCK; | |
fa8bae10 IL |
1666 | if (state->config->set_lock_led) |
1667 | state->config->set_lock_led(fe, 1); | |
1668 | } else { | |
3b30e0a8 | 1669 | *status = 0; |
fa8bae10 IL |
1670 | if (state->config->set_lock_led) |
1671 | state->config->set_lock_led(fe, 0); | |
99277b38 | 1672 | dprintk("DEMOD LOCK FAIL\n"); |
fa8bae10 | 1673 | } |
99277b38 IL |
1674 | |
1675 | return 0; | |
1676 | } | |
1677 | ||
99277b38 IL |
1678 | static int stv0900_stop_ts(struct dvb_frontend *fe, int stop_ts) |
1679 | { | |
1680 | ||
1681 | struct stv0900_state *state = fe->demodulator_priv; | |
1e0c397d | 1682 | struct stv0900_internal *intp = state->internal; |
99277b38 | 1683 | enum fe_stv0900_demod_num demod = state->demod; |
99277b38 IL |
1684 | |
1685 | if (stop_ts == TRUE) | |
1e0c397d | 1686 | stv0900_write_bits(intp, RST_HWARE, 1); |
99277b38 | 1687 | else |
1e0c397d | 1688 | stv0900_write_bits(intp, RST_HWARE, 0); |
99277b38 IL |
1689 | |
1690 | return 0; | |
1691 | } | |
1692 | ||
1693 | static int stv0900_diseqc_init(struct dvb_frontend *fe) | |
1694 | { | |
1695 | struct stv0900_state *state = fe->demodulator_priv; | |
1e0c397d | 1696 | struct stv0900_internal *intp = state->internal; |
99277b38 | 1697 | enum fe_stv0900_demod_num demod = state->demod; |
99277b38 | 1698 | |
1e0c397d IL |
1699 | stv0900_write_bits(intp, DISTX_MODE, state->config->diseqc_mode); |
1700 | stv0900_write_bits(intp, DISEQC_RESET, 1); | |
1701 | stv0900_write_bits(intp, DISEQC_RESET, 0); | |
99277b38 IL |
1702 | |
1703 | return 0; | |
1704 | } | |
1705 | ||
1706 | static int stv0900_init(struct dvb_frontend *fe) | |
1707 | { | |
8171c205 | 1708 | dprintk("%s\n", __func__); |
99277b38 IL |
1709 | |
1710 | stv0900_stop_ts(fe, 1); | |
1711 | stv0900_diseqc_init(fe); | |
1712 | ||
1713 | return 0; | |
1714 | } | |
1715 | ||
1e0c397d | 1716 | static int stv0900_diseqc_send(struct stv0900_internal *intp , u8 *data, |
99277b38 IL |
1717 | u32 NbData, enum fe_stv0900_demod_num demod) |
1718 | { | |
1719 | s32 i = 0; | |
1720 | ||
1e0c397d IL |
1721 | stv0900_write_bits(intp, DIS_PRECHARGE, 1); |
1722 | while (i < NbData) { | |
1723 | while (stv0900_get_bits(intp, FIFO_FULL)) | |
1724 | ;/* checkpatch complains */ | |
1725 | stv0900_write_reg(intp, DISTXDATA, data[i]); | |
1726 | i++; | |
1727 | } | |
99277b38 | 1728 | |
1e0c397d IL |
1729 | stv0900_write_bits(intp, DIS_PRECHARGE, 0); |
1730 | i = 0; | |
1731 | while ((stv0900_get_bits(intp, TX_IDLE) != 1) && (i < 10)) { | |
1732 | msleep(10); | |
1733 | i++; | |
99277b38 IL |
1734 | } |
1735 | ||
1736 | return 0; | |
1737 | } | |
1738 | ||
1739 | static int stv0900_send_master_cmd(struct dvb_frontend *fe, | |
1740 | struct dvb_diseqc_master_cmd *cmd) | |
1741 | { | |
1742 | struct stv0900_state *state = fe->demodulator_priv; | |
1743 | ||
1744 | return stv0900_diseqc_send(state->internal, | |
1745 | cmd->msg, | |
1746 | cmd->msg_len, | |
1747 | state->demod); | |
1748 | } | |
1749 | ||
1750 | static int stv0900_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) | |
1751 | { | |
1752 | struct stv0900_state *state = fe->demodulator_priv; | |
1e0c397d | 1753 | struct stv0900_internal *intp = state->internal; |
99277b38 | 1754 | enum fe_stv0900_demod_num demod = state->demod; |
9329fb5b | 1755 | u8 data; |
99277b38 | 1756 | |
99277b38 IL |
1757 | |
1758 | switch (burst) { | |
1759 | case SEC_MINI_A: | |
1e0c397d | 1760 | stv0900_write_bits(intp, DISTX_MODE, 3);/* Unmodulated */ |
9329fb5b | 1761 | data = 0x00; |
1e0c397d | 1762 | stv0900_diseqc_send(intp, &data, 1, state->demod); |
99277b38 IL |
1763 | break; |
1764 | case SEC_MINI_B: | |
1e0c397d | 1765 | stv0900_write_bits(intp, DISTX_MODE, 2);/* Modulated */ |
9329fb5b | 1766 | data = 0xff; |
1e0c397d | 1767 | stv0900_diseqc_send(intp, &data, 1, state->demod); |
99277b38 IL |
1768 | break; |
1769 | } | |
1770 | ||
1771 | return 0; | |
1772 | } | |
1773 | ||
1774 | static int stv0900_recv_slave_reply(struct dvb_frontend *fe, | |
1775 | struct dvb_diseqc_slave_reply *reply) | |
1776 | { | |
1777 | struct stv0900_state *state = fe->demodulator_priv; | |
1e0c397d IL |
1778 | struct stv0900_internal *intp = state->internal; |
1779 | enum fe_stv0900_demod_num demod = state->demod; | |
99277b38 IL |
1780 | s32 i = 0; |
1781 | ||
1e0c397d | 1782 | reply->msg_len = 0; |
99277b38 | 1783 | |
1e0c397d IL |
1784 | while ((stv0900_get_bits(intp, RX_END) != 1) && (i < 10)) { |
1785 | msleep(10); | |
1786 | i++; | |
1787 | } | |
99277b38 | 1788 | |
1e0c397d IL |
1789 | if (stv0900_get_bits(intp, RX_END)) { |
1790 | reply->msg_len = stv0900_get_bits(intp, FIFO_BYTENBR); | |
99277b38 | 1791 | |
1e0c397d IL |
1792 | for (i = 0; i < reply->msg_len; i++) |
1793 | reply->msg[i] = stv0900_read_reg(intp, DISRXDATA); | |
99277b38 IL |
1794 | } |
1795 | ||
1796 | return 0; | |
1797 | } | |
1798 | ||
9329fb5b | 1799 | static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t toneoff) |
99277b38 IL |
1800 | { |
1801 | struct stv0900_state *state = fe->demodulator_priv; | |
1e0c397d | 1802 | struct stv0900_internal *intp = state->internal; |
99277b38 | 1803 | enum fe_stv0900_demod_num demod = state->demod; |
99277b38 | 1804 | |
9329fb5b | 1805 | dprintk("%s: %s\n", __func__, ((toneoff == 0) ? "On" : "Off")); |
99277b38 | 1806 | |
9329fb5b AO |
1807 | switch (toneoff) { |
1808 | case SEC_TONE_ON: | |
1809 | /*Set the DiseqC mode to 22Khz _continues_ tone*/ | |
1e0c397d IL |
1810 | stv0900_write_bits(intp, DISTX_MODE, 0); |
1811 | stv0900_write_bits(intp, DISEQC_RESET, 1); | |
99277b38 | 1812 | /*release DiseqC reset to enable the 22KHz tone*/ |
1e0c397d | 1813 | stv0900_write_bits(intp, DISEQC_RESET, 0); |
9329fb5b AO |
1814 | break; |
1815 | case SEC_TONE_OFF: | |
1816 | /*return diseqc mode to config->diseqc_mode. | |
1817 | Usually it's without _continues_ tone */ | |
1e0c397d | 1818 | stv0900_write_bits(intp, DISTX_MODE, |
9329fb5b | 1819 | state->config->diseqc_mode); |
99277b38 | 1820 | /*maintain the DiseqC reset to disable the 22KHz tone*/ |
1e0c397d IL |
1821 | stv0900_write_bits(intp, DISEQC_RESET, 1); |
1822 | stv0900_write_bits(intp, DISEQC_RESET, 0); | |
9329fb5b AO |
1823 | break; |
1824 | default: | |
1825 | return -EINVAL; | |
99277b38 IL |
1826 | } |
1827 | ||
1828 | return 0; | |
1829 | } | |
1830 | ||
1831 | static void stv0900_release(struct dvb_frontend *fe) | |
1832 | { | |
1833 | struct stv0900_state *state = fe->demodulator_priv; | |
1834 | ||
8171c205 | 1835 | dprintk("%s\n", __func__); |
99277b38 | 1836 | |
fa8bae10 IL |
1837 | if (state->config->set_lock_led) |
1838 | state->config->set_lock_led(fe, 0); | |
1839 | ||
99277b38 IL |
1840 | if ((--(state->internal->dmds_used)) <= 0) { |
1841 | ||
8171c205 | 1842 | dprintk("%s: Actually removing\n", __func__); |
99277b38 IL |
1843 | |
1844 | remove_inode(state->internal); | |
1845 | kfree(state->internal); | |
1846 | } | |
1847 | ||
1848 | kfree(state); | |
1849 | } | |
1850 | ||
fa8bae10 IL |
1851 | static int stv0900_sleep(struct dvb_frontend *fe) |
1852 | { | |
1853 | struct stv0900_state *state = fe->demodulator_priv; | |
1854 | ||
1855 | dprintk("%s\n", __func__); | |
1856 | ||
1857 | if (state->config->set_lock_led) | |
1858 | state->config->set_lock_led(fe, 0); | |
1859 | ||
1860 | return 0; | |
1861 | } | |
1862 | ||
7c61d80a | 1863 | static int stv0900_get_frontend(struct dvb_frontend *fe) |
403c34f6 | 1864 | { |
7c61d80a | 1865 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; |
403c34f6 AO |
1866 | struct stv0900_state *state = fe->demodulator_priv; |
1867 | struct stv0900_internal *intp = state->internal; | |
1868 | enum fe_stv0900_demod_num demod = state->demod; | |
1869 | struct stv0900_signal_info p_result = intp->result[demod]; | |
1870 | ||
1871 | p->frequency = p_result.locked ? p_result.frequency : 0; | |
38d945e0 | 1872 | p->symbol_rate = p_result.locked ? p_result.symbol_rate : 0; |
403c34f6 AO |
1873 | return 0; |
1874 | } | |
1875 | ||
99277b38 | 1876 | static struct dvb_frontend_ops stv0900_ops = { |
38d945e0 | 1877 | .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, |
99277b38 IL |
1878 | .info = { |
1879 | .name = "STV0900 frontend", | |
99277b38 IL |
1880 | .frequency_min = 950000, |
1881 | .frequency_max = 2150000, | |
1882 | .frequency_stepsize = 125, | |
1883 | .frequency_tolerance = 0, | |
1884 | .symbol_rate_min = 1000000, | |
1885 | .symbol_rate_max = 45000000, | |
1886 | .symbol_rate_tolerance = 500, | |
1887 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | | |
1888 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | | |
1889 | FE_CAN_FEC_7_8 | FE_CAN_QPSK | | |
1890 | FE_CAN_2G_MODULATION | | |
1891 | FE_CAN_FEC_AUTO | |
1892 | }, | |
1893 | .release = stv0900_release, | |
1894 | .init = stv0900_init, | |
38d945e0 | 1895 | .get_frontend = stv0900_get_frontend, |
fa8bae10 | 1896 | .sleep = stv0900_sleep, |
99277b38 IL |
1897 | .get_frontend_algo = stv0900_frontend_algo, |
1898 | .i2c_gate_ctrl = stv0900_i2c_gate_ctrl, | |
1899 | .diseqc_send_master_cmd = stv0900_send_master_cmd, | |
1900 | .diseqc_send_burst = stv0900_send_burst, | |
1901 | .diseqc_recv_slave_reply = stv0900_recv_slave_reply, | |
1902 | .set_tone = stv0900_set_tone, | |
99277b38 | 1903 | .search = stv0900_search, |
99277b38 IL |
1904 | .read_status = stv0900_read_status, |
1905 | .read_ber = stv0900_read_ber, | |
1906 | .read_signal_strength = stv0900_read_signal_strength, | |
1907 | .read_snr = stv0900_read_snr, | |
ee1ebcfe | 1908 | .read_ucblocks = stv0900_read_ucblocks, |
99277b38 IL |
1909 | }; |
1910 | ||
1911 | struct dvb_frontend *stv0900_attach(const struct stv0900_config *config, | |
1912 | struct i2c_adapter *i2c, | |
1913 | int demod) | |
1914 | { | |
1915 | struct stv0900_state *state = NULL; | |
1916 | struct stv0900_init_params init_params; | |
1917 | enum fe_stv0900_error err_stv0900; | |
1918 | ||
1919 | state = kzalloc(sizeof(struct stv0900_state), GFP_KERNEL); | |
1920 | if (state == NULL) | |
1921 | goto error; | |
1922 | ||
1923 | state->demod = demod; | |
1924 | state->config = config; | |
1925 | state->i2c_adap = i2c; | |
1926 | ||
1927 | memcpy(&state->frontend.ops, &stv0900_ops, | |
1928 | sizeof(struct dvb_frontend_ops)); | |
1929 | state->frontend.demodulator_priv = state; | |
1930 | ||
1931 | switch (demod) { | |
1932 | case 0: | |
1933 | case 1: | |
1934 | init_params.dmd_ref_clk = config->xtal; | |
29372a8d | 1935 | init_params.demod_mode = config->demod_mode; |
99277b38 IL |
1936 | init_params.rolloff = STV0900_35; |
1937 | init_params.path1_ts_clock = config->path1_mode; | |
1938 | init_params.tun1_maddress = config->tun1_maddress; | |
1e0c397d | 1939 | init_params.tun1_iq_inv = STV0900_IQ_NORMAL; |
99277b38 | 1940 | init_params.tuner1_adc = config->tun1_adc; |
cd79d33e | 1941 | init_params.tuner1_type = config->tun1_type; |
99277b38 | 1942 | init_params.path2_ts_clock = config->path2_mode; |
f867c3f4 | 1943 | init_params.ts_config = config->ts_config_regs; |
99277b38 IL |
1944 | init_params.tun2_maddress = config->tun2_maddress; |
1945 | init_params.tuner2_adc = config->tun2_adc; | |
cd79d33e | 1946 | init_params.tuner2_type = config->tun2_type; |
1e0c397d | 1947 | init_params.tun2_iq_inv = STV0900_IQ_SWAPPED; |
99277b38 IL |
1948 | |
1949 | err_stv0900 = stv0900_init_internal(&state->frontend, | |
1950 | &init_params); | |
1951 | ||
1952 | if (err_stv0900) | |
1953 | goto error; | |
1954 | ||
73ec66c0 EP |
1955 | if (state->internal->chip_id >= 0x30) |
1956 | state->frontend.ops.info.caps |= FE_CAN_MULTISTREAM; | |
1957 | ||
99277b38 IL |
1958 | break; |
1959 | default: | |
1960 | goto error; | |
1961 | break; | |
1962 | } | |
1963 | ||
1964 | dprintk("%s: Attaching STV0900 demodulator(%d) \n", __func__, demod); | |
1965 | return &state->frontend; | |
1966 | ||
1967 | error: | |
1968 | dprintk("%s: Failed to attach STV0900 demodulator(%d) \n", | |
1969 | __func__, demod); | |
1970 | kfree(state); | |
1971 | return NULL; | |
1972 | } | |
1973 | EXPORT_SYMBOL(stv0900_attach); | |
1974 | ||
1975 | MODULE_PARM_DESC(debug, "Set debug"); | |
1976 | ||
1977 | MODULE_AUTHOR("Igor M. Liplianin"); | |
1978 | MODULE_DESCRIPTION("ST STV0900 frontend"); | |
1979 | MODULE_LICENSE("GPL"); |