aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb-frontends/dib8000.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb-frontends/dib8000.c')
-rw-r--r--drivers/media/dvb-frontends/dib8000.c3560
1 files changed, 3560 insertions, 0 deletions
diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
new file mode 100644
index 000000000000..1f3bcb5a1de8
--- /dev/null
+++ b/drivers/media/dvb-frontends/dib8000.c
@@ -0,0 +1,3560 @@
1/*
2 * Linux-DVB Driver for DiBcom's DiB8000 chip (ISDB-T).
3 *
4 * Copyright (C) 2009 DiBcom (http://www.dibcom.fr/)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 */
10#include <linux/kernel.h>
11#include <linux/slab.h>
12#include <linux/i2c.h>
13#include <linux/mutex.h>
14
15#include "dvb_math.h"
16
17#include "dvb_frontend.h"
18
19#include "dib8000.h"
20
21#define LAYER_ALL -1
22#define LAYER_A 1
23#define LAYER_B 2
24#define LAYER_C 3
25
26#define FE_CALLBACK_TIME_NEVER 0xffffffff
27#define MAX_NUMBER_OF_FRONTENDS 6
28
29static int debug;
30module_param(debug, int, 0644);
31MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
32
33#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
34
35#define FE_STATUS_TUNE_FAILED 0
36
37struct i2c_device {
38 struct i2c_adapter *adap;
39 u8 addr;
40 u8 *i2c_write_buffer;
41 u8 *i2c_read_buffer;
42 struct mutex *i2c_buffer_lock;
43};
44
45struct dib8000_state {
46 struct dib8000_config cfg;
47
48 struct i2c_device i2c;
49
50 struct dibx000_i2c_master i2c_master;
51
52 u16 wbd_ref;
53
54 u8 current_band;
55 u32 current_bandwidth;
56 struct dibx000_agc_config *current_agc;
57 u32 timf;
58 u32 timf_default;
59
60 u8 div_force_off:1;
61 u8 div_state:1;
62 u16 div_sync_wait;
63
64 u8 agc_state;
65 u8 differential_constellation;
66 u8 diversity_onoff;
67
68 s16 ber_monitored_layer;
69 u16 gpio_dir;
70 u16 gpio_val;
71
72 u16 revision;
73 u8 isdbt_cfg_loaded;
74 enum frontend_tune_state tune_state;
75 u32 status;
76
77 struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
78
79 /* for the I2C transfer */
80 struct i2c_msg msg[2];
81 u8 i2c_write_buffer[4];
82 u8 i2c_read_buffer[2];
83 struct mutex i2c_buffer_lock;
84 u8 input_mode_mpeg;
85
86 u16 tuner_enable;
87 struct i2c_adapter dib8096p_tuner_adap;
88};
89
90enum dib8000_power_mode {
91 DIB8000_POWER_ALL = 0,
92 DIB8000_POWER_INTERFACE_ONLY,
93};
94
95static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
96{
97 u16 ret;
98 struct i2c_msg msg[2] = {
99 {.addr = i2c->addr >> 1, .flags = 0, .len = 2},
100 {.addr = i2c->addr >> 1, .flags = I2C_M_RD, .len = 2},
101 };
102
103 if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
104 dprintk("could not acquire lock");
105 return 0;
106 }
107
108 msg[0].buf = i2c->i2c_write_buffer;
109 msg[0].buf[0] = reg >> 8;
110 msg[0].buf[1] = reg & 0xff;
111 msg[1].buf = i2c->i2c_read_buffer;
112
113 if (i2c_transfer(i2c->adap, msg, 2) != 2)
114 dprintk("i2c read error on %d", reg);
115
116 ret = (msg[1].buf[0] << 8) | msg[1].buf[1];
117 mutex_unlock(i2c->i2c_buffer_lock);
118 return ret;
119}
120
121static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
122{
123 u16 ret;
124
125 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
126 dprintk("could not acquire lock");
127 return 0;
128 }
129
130 state->i2c_write_buffer[0] = reg >> 8;
131 state->i2c_write_buffer[1] = reg & 0xff;
132
133 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
134 state->msg[0].addr = state->i2c.addr >> 1;
135 state->msg[0].flags = 0;
136 state->msg[0].buf = state->i2c_write_buffer;
137 state->msg[0].len = 2;
138 state->msg[1].addr = state->i2c.addr >> 1;
139 state->msg[1].flags = I2C_M_RD;
140 state->msg[1].buf = state->i2c_read_buffer;
141 state->msg[1].len = 2;
142
143 if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2)
144 dprintk("i2c read error on %d", reg);
145
146 ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
147 mutex_unlock(&state->i2c_buffer_lock);
148
149 return ret;
150}
151
152static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
153{
154 u16 rw[2];
155
156 rw[0] = dib8000_read_word(state, reg + 0);
157 rw[1] = dib8000_read_word(state, reg + 1);
158
159 return ((rw[0] << 16) | (rw[1]));
160}
161
162static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
163{
164 struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0, .len = 4};
165 int ret = 0;
166
167 if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
168 dprintk("could not acquire lock");
169 return -EINVAL;
170 }
171
172 msg.buf = i2c->i2c_write_buffer;
173 msg.buf[0] = (reg >> 8) & 0xff;
174 msg.buf[1] = reg & 0xff;
175 msg.buf[2] = (val >> 8) & 0xff;
176 msg.buf[3] = val & 0xff;
177
178 ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
179 mutex_unlock(i2c->i2c_buffer_lock);
180
181 return ret;
182}
183
184static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
185{
186 int ret;
187
188 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
189 dprintk("could not acquire lock");
190 return -EINVAL;
191 }
192
193 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
194 state->i2c_write_buffer[1] = reg & 0xff;
195 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
196 state->i2c_write_buffer[3] = val & 0xff;
197
198 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
199 state->msg[0].addr = state->i2c.addr >> 1;
200 state->msg[0].flags = 0;
201 state->msg[0].buf = state->i2c_write_buffer;
202 state->msg[0].len = 4;
203
204 ret = (i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ?
205 -EREMOTEIO : 0);
206 mutex_unlock(&state->i2c_buffer_lock);
207
208 return ret;
209}
210
211static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
212 (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
213 (920 << 5) | 0x09
214};
215
216static const s16 coeff_2k_sb_1seg[8] = {
217 (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
218};
219
220static const s16 coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
221 (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
222 (-931 << 5) | 0x0f
223};
224
225static const s16 coeff_2k_sb_3seg_0dqpsk[8] = {
226 (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
227 (982 << 5) | 0x0c
228};
229
230static const s16 coeff_2k_sb_3seg_1dqpsk[8] = {
231 (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
232 (-720 << 5) | 0x0d
233};
234
235static const s16 coeff_2k_sb_3seg[8] = {
236 (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
237 (-610 << 5) | 0x0a
238};
239
240static const s16 coeff_4k_sb_1seg_dqpsk[8] = {
241 (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
242 (-922 << 5) | 0x0d
243};
244
245static const s16 coeff_4k_sb_1seg[8] = {
246 (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
247 (-655 << 5) | 0x0a
248};
249
250static const s16 coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
251 (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
252 (-958 << 5) | 0x13
253};
254
255static const s16 coeff_4k_sb_3seg_0dqpsk[8] = {
256 (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
257 (-568 << 5) | 0x0f
258};
259
260static const s16 coeff_4k_sb_3seg_1dqpsk[8] = {
261 (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
262 (-848 << 5) | 0x13
263};
264
265static const s16 coeff_4k_sb_3seg[8] = {
266 (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
267 (-869 << 5) | 0x13
268};
269
270static const s16 coeff_8k_sb_1seg_dqpsk[8] = {
271 (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
272 (-598 << 5) | 0x10
273};
274
275static const s16 coeff_8k_sb_1seg[8] = {
276 (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
277 (585 << 5) | 0x0f
278};
279
280static const s16 coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
281 (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
282 (0 << 5) | 0x14
283};
284
285static const s16 coeff_8k_sb_3seg_0dqpsk[8] = {
286 (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
287 (-877 << 5) | 0x15
288};
289
290static const s16 coeff_8k_sb_3seg_1dqpsk[8] = {
291 (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
292 (-921 << 5) | 0x14
293};
294
295static const s16 coeff_8k_sb_3seg[8] = {
296 (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
297 (690 << 5) | 0x14
298};
299
300static const s16 ana_fe_coeff_3seg[24] = {
301 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
302};
303
304static const s16 ana_fe_coeff_1seg[24] = {
305 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
306};
307
308static const s16 ana_fe_coeff_13seg[24] = {
309 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
310};
311
312static u16 fft_to_mode(struct dib8000_state *state)
313{
314 u16 mode;
315 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
316 case TRANSMISSION_MODE_2K:
317 mode = 1;
318 break;
319 case TRANSMISSION_MODE_4K:
320 mode = 2;
321 break;
322 default:
323 case TRANSMISSION_MODE_AUTO:
324 case TRANSMISSION_MODE_8K:
325 mode = 3;
326 break;
327 }
328 return mode;
329}
330
331static void dib8000_set_acquisition_mode(struct dib8000_state *state)
332{
333 u16 nud = dib8000_read_word(state, 298);
334 nud |= (1 << 3) | (1 << 0);
335 dprintk("acquisition mode activated");
336 dib8000_write_word(state, 298, nud);
337}
338static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode)
339{
340 struct dib8000_state *state = fe->demodulator_priv;
341
342 u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */
343
344 outreg = 0;
345 fifo_threshold = 1792;
346 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
347
348 dprintk("-I- Setting output mode for demod %p to %d",
349 &state->fe[0], mode);
350
351 switch (mode) {
352 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
353 outreg = (1 << 10); /* 0x0400 */
354 break;
355 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
356 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
357 break;
358 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
359 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
360 break;
361 case OUTMODE_DIVERSITY:
362 if (state->cfg.hostbus_diversity) {
363 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
364 sram &= 0xfdff;
365 } else
366 sram |= 0x0c00;
367 break;
368 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
369 smo_mode |= (3 << 1);
370 fifo_threshold = 512;
371 outreg = (1 << 10) | (5 << 6);
372 break;
373 case OUTMODE_HIGH_Z: // disable
374 outreg = 0;
375 break;
376
377 case OUTMODE_ANALOG_ADC:
378 outreg = (1 << 10) | (3 << 6);
379 dib8000_set_acquisition_mode(state);
380 break;
381
382 default:
383 dprintk("Unhandled output_mode passed to be set for demod %p",
384 &state->fe[0]);
385 return -EINVAL;
386 }
387
388 if (state->cfg.output_mpeg2_in_188_bytes)
389 smo_mode |= (1 << 5);
390
391 dib8000_write_word(state, 299, smo_mode);
392 dib8000_write_word(state, 300, fifo_threshold); /* synchronous fread */
393 dib8000_write_word(state, 1286, outreg);
394 dib8000_write_word(state, 1291, sram);
395
396 return 0;
397}
398
399static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
400{
401 struct dib8000_state *state = fe->demodulator_priv;
402 u16 sync_wait = dib8000_read_word(state, 273) & 0xfff0;
403
404 if (!state->differential_constellation) {
405 dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1
406 dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2); // sync_enable = 1; comb_mode = 2
407 } else {
408 dib8000_write_word(state, 272, 0); //dvsy_off_lmod4 = 0
409 dib8000_write_word(state, 273, sync_wait); // sync_enable = 0; comb_mode = 0
410 }
411 state->diversity_onoff = onoff;
412
413 switch (onoff) {
414 case 0: /* only use the internal way - not the diversity input */
415 dib8000_write_word(state, 270, 1);
416 dib8000_write_word(state, 271, 0);
417 break;
418 case 1: /* both ways */
419 dib8000_write_word(state, 270, 6);
420 dib8000_write_word(state, 271, 6);
421 break;
422 case 2: /* only the diversity input */
423 dib8000_write_word(state, 270, 0);
424 dib8000_write_word(state, 271, 1);
425 break;
426 }
427 return 0;
428}
429
430static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
431{
432 /* by default everything is going to be powered off */
433 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
434 reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3,
435 reg_1280;
436
437 if (state->revision != 0x8090)
438 reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
439 else
440 reg_1280 = (dib8000_read_word(state, 1280) & 0x707f) | 0x8f80;
441
442 /* now, depending on the requested mode, we power on */
443 switch (mode) {
444 /* power up everything in the demod */
445 case DIB8000_POWER_ALL:
446 reg_774 = 0x0000;
447 reg_775 = 0x0000;
448 reg_776 = 0x0000;
449 reg_900 &= 0xfffc;
450 if (state->revision != 0x8090)
451 reg_1280 &= 0x00ff;
452 else
453 reg_1280 &= 0x707f;
454 break;
455 case DIB8000_POWER_INTERFACE_ONLY:
456 if (state->revision != 0x8090)
457 reg_1280 &= 0x00ff;
458 else
459 reg_1280 &= 0xfa7b;
460 break;
461 }
462
463 dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
464 dib8000_write_word(state, 774, reg_774);
465 dib8000_write_word(state, 775, reg_775);
466 dib8000_write_word(state, 776, reg_776);
467 dib8000_write_word(state, 900, reg_900);
468 dib8000_write_word(state, 1280, reg_1280);
469}
470
471static int dib8000_init_sdram(struct dib8000_state *state)
472{
473 u16 reg = 0;
474 dprintk("Init sdram");
475
476 reg = dib8000_read_word(state, 274)&0xfff0;
477 /* P_dintlv_delay_ram = 7 because of MobileSdram */
478 dib8000_write_word(state, 274, reg | 0x7);
479
480 dib8000_write_word(state, 1803, (7<<2));
481
482 reg = dib8000_read_word(state, 1280);
483 /* force restart P_restart_sdram */
484 dib8000_write_word(state, 1280, reg | (1<<2));
485
486 /* release restart P_restart_sdram */
487 dib8000_write_word(state, 1280, reg);
488
489 return 0;
490}
491
492static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
493{
494 int ret = 0;
495 u16 reg, reg_907 = dib8000_read_word(state, 907);
496 u16 reg_908 = dib8000_read_word(state, 908);
497
498 switch (no) {
499 case DIBX000_SLOW_ADC_ON:
500 if (state->revision != 0x8090) {
501 reg_908 |= (1 << 1) | (1 << 0);
502 ret |= dib8000_write_word(state, 908, reg_908);
503 reg_908 &= ~(1 << 1);
504 } else {
505 reg = dib8000_read_word(state, 1925);
506 /* en_slowAdc = 1 & reset_sladc = 1 */
507 dib8000_write_word(state, 1925, reg |
508 (1<<4) | (1<<2));
509
510 /* read acces to make it works... strange ... */
511 reg = dib8000_read_word(state, 1925);
512 msleep(20);
513 /* en_slowAdc = 1 & reset_sladc = 0 */
514 dib8000_write_word(state, 1925, reg & ~(1<<4));
515
516 reg = dib8000_read_word(state, 921) & ~((0x3 << 14)
517 | (0x3 << 12));
518 /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ;
519 (Vin2 = Vcm) */
520 dib8000_write_word(state, 921, reg | (1 << 14)
521 | (3 << 12));
522 }
523 break;
524
525 case DIBX000_SLOW_ADC_OFF:
526 if (state->revision == 0x8090) {
527 reg = dib8000_read_word(state, 1925);
528 /* reset_sladc = 1 en_slowAdc = 0 */
529 dib8000_write_word(state, 1925,
530 (reg & ~(1<<2)) | (1<<4));
531 }
532 reg_908 |= (1 << 1) | (1 << 0);
533 break;
534
535 case DIBX000_ADC_ON:
536 reg_907 &= 0x0fff;
537 reg_908 &= 0x0003;
538 break;
539
540 case DIBX000_ADC_OFF: // leave the VBG voltage on
541 reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
542 reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
543 break;
544
545 case DIBX000_VBG_ENABLE:
546 reg_907 &= ~(1 << 15);
547 break;
548
549 case DIBX000_VBG_DISABLE:
550 reg_907 |= (1 << 15);
551 break;
552
553 default:
554 break;
555 }
556
557 ret |= dib8000_write_word(state, 907, reg_907);
558 ret |= dib8000_write_word(state, 908, reg_908);
559
560 return ret;
561}
562
563static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw)
564{
565 struct dib8000_state *state = fe->demodulator_priv;
566 u32 timf;
567
568 if (bw == 0)
569 bw = 6000;
570
571 if (state->timf == 0) {
572 dprintk("using default timf");
573 timf = state->timf_default;
574 } else {
575 dprintk("using updated timf");
576 timf = state->timf;
577 }
578
579 dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
580 dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
581
582 return 0;
583}
584
585static int dib8000_sad_calib(struct dib8000_state *state)
586{
587 if (state->revision == 0x8090) {
588 dprintk("%s: the sad calibration is not needed for the dib8096P",
589 __func__);
590 return 0;
591 }
592 /* internal */
593 dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
594 dib8000_write_word(state, 924, 776); // 0.625*3.3 / 4096
595
596 /* do the calibration */
597 dib8000_write_word(state, 923, (1 << 0));
598 dib8000_write_word(state, 923, (0 << 0));
599
600 msleep(1);
601 return 0;
602}
603
604int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
605{
606 struct dib8000_state *state = fe->demodulator_priv;
607 if (value > 4095)
608 value = 4095;
609 state->wbd_ref = value;
610 return dib8000_write_word(state, 106, value);
611}
612
613EXPORT_SYMBOL(dib8000_set_wbd_ref);
614static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
615{
616 dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
617 if (state->revision != 0x8090) {
618 dib8000_write_word(state, 23,
619 (u16) (((bw->internal * 1000) >> 16) & 0xffff));
620 dib8000_write_word(state, 24,
621 (u16) ((bw->internal * 1000) & 0xffff));
622 } else {
623 dib8000_write_word(state, 23, (u16) (((bw->internal / 2 * 1000) >> 16) & 0xffff));
624 dib8000_write_word(state, 24,
625 (u16) ((bw->internal / 2 * 1000) & 0xffff));
626 }
627 dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
628 dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
629 dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
630
631 if (state->revision != 0x8090)
632 dib8000_write_word(state, 922, bw->sad_cfg);
633}
634
635static void dib8000_reset_pll(struct dib8000_state *state)
636{
637 const struct dibx000_bandwidth_config *pll = state->cfg.pll;
638 u16 clk_cfg1, reg;
639
640 if (state->revision != 0x8090) {
641 dib8000_write_word(state, 901,
642 (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
643
644 clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
645 (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) |
646 (1 << 3) | (pll->pll_range << 1) |
647 (pll->pll_reset << 0);
648
649 dib8000_write_word(state, 902, clk_cfg1);
650 clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
651 dib8000_write_word(state, 902, clk_cfg1);
652
653 dprintk("clk_cfg1: 0x%04x", clk_cfg1);
654
655 /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
656 if (state->cfg.pll->ADClkSrc == 0)
657 dib8000_write_word(state, 904,
658 (0 << 15) | (0 << 12) | (0 << 10) |
659 (pll->modulo << 8) |
660 (pll->ADClkSrc << 7) | (0 << 1));
661 else if (state->cfg.refclksel != 0)
662 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
663 ((state->cfg.refclksel & 0x3) << 10) |
664 (pll->modulo << 8) |
665 (pll->ADClkSrc << 7) | (0 << 1));
666 else
667 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
668 (3 << 10) | (pll->modulo << 8) |
669 (pll->ADClkSrc << 7) | (0 << 1));
670 } else {
671 dib8000_write_word(state, 1856, (!pll->pll_reset<<13) |
672 (pll->pll_range<<12) | (pll->pll_ratio<<6) |
673 (pll->pll_prediv));
674
675 reg = dib8000_read_word(state, 1857);
676 dib8000_write_word(state, 1857, reg|(!pll->pll_bypass<<15));
677
678 reg = dib8000_read_word(state, 1858); /* Force clk out pll /2 */
679 dib8000_write_word(state, 1858, reg | 1);
680
681 dib8000_write_word(state, 904, (pll->modulo << 8));
682 }
683
684 dib8000_reset_pll_common(state, pll);
685}
686
687int dib8000_update_pll(struct dvb_frontend *fe,
688 struct dibx000_bandwidth_config *pll)
689{
690 struct dib8000_state *state = fe->demodulator_priv;
691 u16 reg_1857, reg_1856 = dib8000_read_word(state, 1856);
692 u8 loopdiv, prediv;
693 u32 internal, xtal;
694
695 /* get back old values */
696 prediv = reg_1856 & 0x3f;
697 loopdiv = (reg_1856 >> 6) & 0x3f;
698
699 if ((pll != NULL) && (pll->pll_prediv != prediv ||
700 pll->pll_ratio != loopdiv)) {
701 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, pll->pll_prediv, loopdiv, pll->pll_ratio);
702 reg_1856 &= 0xf000;
703 reg_1857 = dib8000_read_word(state, 1857);
704 /* disable PLL */
705 dib8000_write_word(state, 1857, reg_1857 & ~(1 << 15));
706
707 dib8000_write_word(state, 1856, reg_1856 |
708 ((pll->pll_ratio & 0x3f) << 6) |
709 (pll->pll_prediv & 0x3f));
710
711 /* write new system clk into P_sec_len */
712 internal = dib8000_read32(state, 23) / 1000;
713 dprintk("Old Internal = %d", internal);
714 xtal = 2 * (internal / loopdiv) * prediv;
715 internal = 1000 * (xtal/pll->pll_prediv) * pll->pll_ratio;
716 dprintk("Xtal = %d , New Fmem = %d New Fdemod = %d, New Fsampling = %d", xtal, internal/1000, internal/2000, internal/8000);
717 dprintk("New Internal = %d", internal);
718
719 dib8000_write_word(state, 23,
720 (u16) (((internal / 2) >> 16) & 0xffff));
721 dib8000_write_word(state, 24, (u16) ((internal / 2) & 0xffff));
722 /* enable PLL */
723 dib8000_write_word(state, 1857, reg_1857 | (1 << 15));
724
725 while (((dib8000_read_word(state, 1856)>>15)&0x1) != 1)
726 dprintk("Waiting for PLL to lock");
727
728 /* verify */
729 reg_1856 = dib8000_read_word(state, 1856);
730 dprintk("PLL Updated with prediv = %d and loopdiv = %d",
731 reg_1856&0x3f, (reg_1856>>6)&0x3f);
732
733 return 0;
734 }
735 return -EINVAL;
736}
737EXPORT_SYMBOL(dib8000_update_pll);
738
739
740static int dib8000_reset_gpio(struct dib8000_state *st)
741{
742 /* reset the GPIOs */
743 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
744 dib8000_write_word(st, 1030, st->cfg.gpio_val);
745
746 /* TODO 782 is P_gpio_od */
747
748 dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
749
750 dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
751 return 0;
752}
753
754static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
755{
756 st->cfg.gpio_dir = dib8000_read_word(st, 1029);
757 st->cfg.gpio_dir &= ~(1 << num); /* reset the direction bit */
758 st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */
759 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
760
761 st->cfg.gpio_val = dib8000_read_word(st, 1030);
762 st->cfg.gpio_val &= ~(1 << num); /* reset the direction bit */
763 st->cfg.gpio_val |= (val & 0x01) << num; /* set the new value */
764 dib8000_write_word(st, 1030, st->cfg.gpio_val);
765
766 dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
767
768 return 0;
769}
770
771int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
772{
773 struct dib8000_state *state = fe->demodulator_priv;
774 return dib8000_cfg_gpio(state, num, dir, val);
775}
776
777EXPORT_SYMBOL(dib8000_set_gpio);
778static const u16 dib8000_defaults[] = {
779 /* auto search configuration - lock0 by default waiting
780 * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
781 3, 7,
782 0x0004,
783 0x0400,
784 0x0814,
785
786 12, 11,
787 0x001b,
788 0x7740,
789 0x005b,
790 0x8d80,
791 0x01c9,
792 0xc380,
793 0x0000,
794 0x0080,
795 0x0000,
796 0x0090,
797 0x0001,
798 0xd4c0,
799
800 /*1, 32,
801 0x6680 // P_corm_thres Lock algorithms configuration */
802
803 11, 80, /* set ADC level to -16 */
804 (1 << 13) - 825 - 117,
805 (1 << 13) - 837 - 117,
806 (1 << 13) - 811 - 117,
807 (1 << 13) - 766 - 117,
808 (1 << 13) - 737 - 117,
809 (1 << 13) - 693 - 117,
810 (1 << 13) - 648 - 117,
811 (1 << 13) - 619 - 117,
812 (1 << 13) - 575 - 117,
813 (1 << 13) - 531 - 117,
814 (1 << 13) - 501 - 117,
815
816 4, 108,
817 0,
818 0,
819 0,
820 0,
821
822 1, 175,
823 0x0410,
824 1, 179,
825 8192, // P_fft_nb_to_cut
826
827 6, 181,
828 0x2800, // P_coff_corthres_ ( 2k 4k 8k ) 0x2800
829 0x2800,
830 0x2800,
831 0x2800, // P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
832 0x2800,
833 0x2800,
834
835 2, 193,
836 0x0666, // P_pha3_thres
837 0x0000, // P_cti_use_cpe, P_cti_use_prog
838
839 2, 205,
840 0x200f, // P_cspu_regul, P_cspu_win_cut
841 0x000f, // P_des_shift_work
842
843 5, 215,
844 0x023d, // P_adp_regul_cnt
845 0x00a4, // P_adp_noise_cnt
846 0x00a4, // P_adp_regul_ext
847 0x7ff0, // P_adp_noise_ext
848 0x3ccc, // P_adp_fil
849
850 1, 230,
851 0x0000, // P_2d_byp_ti_num
852
853 1, 263,
854 0x800, //P_equal_thres_wgn
855
856 1, 268,
857 (2 << 9) | 39, // P_equal_ctrl_synchro, P_equal_speedmode
858
859 1, 270,
860 0x0001, // P_div_lock0_wait
861 1, 285,
862 0x0020, //p_fec_
863 1, 299,
864 0x0062, /* P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard */
865
866 1, 338,
867 (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1
868 (1 << 10) |
869 (0 << 9) | /* P_ctrl_pre_freq_inh=0 */
870 (3 << 5) | /* P_ctrl_pre_freq_step=3 */
871 (1 << 0), /* P_pre_freq_win_len=1 */
872
873 0,
874};
875
876static u16 dib8000_identify(struct i2c_device *client)
877{
878 u16 value;
879
880 //because of glitches sometimes
881 value = dib8000_i2c_read16(client, 896);
882
883 if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
884 dprintk("wrong Vendor ID (read=0x%x)", value);
885 return 0;
886 }
887
888 value = dib8000_i2c_read16(client, 897);
889 if (value != 0x8000 && value != 0x8001 &&
890 value != 0x8002 && value != 0x8090) {
891 dprintk("wrong Device ID (%x)", value);
892 return 0;
893 }
894
895 switch (value) {
896 case 0x8000:
897 dprintk("found DiB8000A");
898 break;
899 case 0x8001:
900 dprintk("found DiB8000B");
901 break;
902 case 0x8002:
903 dprintk("found DiB8000C");
904 break;
905 case 0x8090:
906 dprintk("found DiB8096P");
907 break;
908 }
909 return value;
910}
911
912static int dib8000_reset(struct dvb_frontend *fe)
913{
914 struct dib8000_state *state = fe->demodulator_priv;
915
916 if ((state->revision = dib8000_identify(&state->i2c)) == 0)
917 return -EINVAL;
918
919 /* sram lead in, rdy */
920 if (state->revision != 0x8090)
921 dib8000_write_word(state, 1287, 0x0003);
922
923 if (state->revision == 0x8000)
924 dprintk("error : dib8000 MA not supported");
925
926 dibx000_reset_i2c_master(&state->i2c_master);
927
928 dib8000_set_power_mode(state, DIB8000_POWER_ALL);
929
930 /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
931 dib8000_set_adc_state(state, DIBX000_VBG_ENABLE);
932
933 /* restart all parts */
934 dib8000_write_word(state, 770, 0xffff);
935 dib8000_write_word(state, 771, 0xffff);
936 dib8000_write_word(state, 772, 0xfffc);
937 if (state->revision == 0x8090)
938 dib8000_write_word(state, 1280, 0x0045);
939 else
940 dib8000_write_word(state, 1280, 0x004d);
941 dib8000_write_word(state, 1281, 0x000c);
942
943 dib8000_write_word(state, 770, 0x0000);
944 dib8000_write_word(state, 771, 0x0000);
945 dib8000_write_word(state, 772, 0x0000);
946 dib8000_write_word(state, 898, 0x0004); // sad
947 dib8000_write_word(state, 1280, 0x0000);
948 dib8000_write_word(state, 1281, 0x0000);
949
950 /* drives */
951 if (state->revision != 0x8090) {
952 if (state->cfg.drives)
953 dib8000_write_word(state, 906, state->cfg.drives);
954 else {
955 dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
956 /* min drive SDRAM - not optimal - adjust */
957 dib8000_write_word(state, 906, 0x2d98);
958 }
959 }
960
961 dib8000_reset_pll(state);
962 if (state->revision != 0x8090)
963 dib8000_write_word(state, 898, 0x0004);
964
965 if (dib8000_reset_gpio(state) != 0)
966 dprintk("GPIO reset was not successful.");
967
968 if ((state->revision != 0x8090) &&
969 (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0))
970 dprintk("OUTPUT_MODE could not be resetted.");
971
972 state->current_agc = NULL;
973
974 // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
975 /* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
976 if (state->cfg.pll->ifreq == 0)
977 dib8000_write_word(state, 40, 0x0755); /* P_iqc_corr_inh = 0 enable IQcorr block */
978 else
979 dib8000_write_word(state, 40, 0x1f55); /* P_iqc_corr_inh = 1 disable IQcorr block */
980
981 {
982 u16 l = 0, r;
983 const u16 *n;
984 n = dib8000_defaults;
985 l = *n++;
986 while (l) {
987 r = *n++;
988 do {
989 dib8000_write_word(state, r, *n++);
990 r++;
991 } while (--l);
992 l = *n++;
993 }
994 }
995 if (state->revision != 0x8090)
996 dib8000_write_word(state, 903, (0 << 4) | 2);
997 state->isdbt_cfg_loaded = 0;
998
999 //div_cfg override for special configs
1000 if (state->cfg.div_cfg != 0)
1001 dib8000_write_word(state, 903, state->cfg.div_cfg);
1002
1003 /* unforce divstr regardless whether i2c enumeration was done or not */
1004 dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
1005
1006 dib8000_set_bandwidth(fe, 6000);
1007
1008 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1009 if (state->revision != 0x8090) {
1010 dib8000_sad_calib(state);
1011 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
1012 }
1013
1014 dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
1015
1016 return 0;
1017}
1018
1019static void dib8000_restart_agc(struct dib8000_state *state)
1020{
1021 // P_restart_iqc & P_restart_agc
1022 dib8000_write_word(state, 770, 0x0a00);
1023 dib8000_write_word(state, 770, 0x0000);
1024}
1025
1026static int dib8000_update_lna(struct dib8000_state *state)
1027{
1028 u16 dyn_gain;
1029
1030 if (state->cfg.update_lna) {
1031 // read dyn_gain here (because it is demod-dependent and not tuner)
1032 dyn_gain = dib8000_read_word(state, 390);
1033
1034 if (state->cfg.update_lna(state->fe[0], dyn_gain)) {
1035 dib8000_restart_agc(state);
1036 return 1;
1037 }
1038 }
1039 return 0;
1040}
1041
1042static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
1043{
1044 struct dibx000_agc_config *agc = NULL;
1045 int i;
1046 u16 reg;
1047
1048 if (state->current_band == band && state->current_agc != NULL)
1049 return 0;
1050 state->current_band = band;
1051
1052 for (i = 0; i < state->cfg.agc_config_count; i++)
1053 if (state->cfg.agc[i].band_caps & band) {
1054 agc = &state->cfg.agc[i];
1055 break;
1056 }
1057
1058 if (agc == NULL) {
1059 dprintk("no valid AGC configuration found for band 0x%02x", band);
1060 return -EINVAL;
1061 }
1062
1063 state->current_agc = agc;
1064
1065 /* AGC */
1066 dib8000_write_word(state, 76, agc->setup);
1067 dib8000_write_word(state, 77, agc->inv_gain);
1068 dib8000_write_word(state, 78, agc->time_stabiliz);
1069 dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
1070
1071 // Demod AGC loop configuration
1072 dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
1073 dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
1074
1075 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
1076 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
1077
1078 /* AGC continued */
1079 if (state->wbd_ref != 0)
1080 dib8000_write_word(state, 106, state->wbd_ref);
1081 else // use default
1082 dib8000_write_word(state, 106, agc->wbd_ref);
1083
1084 if (state->revision == 0x8090) {
1085 reg = dib8000_read_word(state, 922) & (0x3 << 2);
1086 dib8000_write_word(state, 922, reg | (agc->wbd_sel << 2));
1087 }
1088
1089 dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
1090 dib8000_write_word(state, 108, agc->agc1_max);
1091 dib8000_write_word(state, 109, agc->agc1_min);
1092 dib8000_write_word(state, 110, agc->agc2_max);
1093 dib8000_write_word(state, 111, agc->agc2_min);
1094 dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
1095 dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
1096 dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
1097 dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
1098
1099 dib8000_write_word(state, 75, agc->agc1_pt3);
1100 if (state->revision != 0x8090)
1101 dib8000_write_word(state, 923,
1102 (dib8000_read_word(state, 923) & 0xffe3) |
1103 (agc->wbd_inv << 4) | (agc->wbd_sel << 2));
1104
1105 return 0;
1106}
1107
1108void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
1109{
1110 struct dib8000_state *state = fe->demodulator_priv;
1111 dib8000_set_adc_state(state, DIBX000_ADC_ON);
1112 dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000)));
1113}
1114EXPORT_SYMBOL(dib8000_pwm_agc_reset);
1115
1116static int dib8000_agc_soft_split(struct dib8000_state *state)
1117{
1118 u16 agc, split_offset;
1119
1120 if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
1121 return FE_CALLBACK_TIME_NEVER;
1122
1123 // n_agc_global
1124 agc = dib8000_read_word(state, 390);
1125
1126 if (agc > state->current_agc->split.min_thres)
1127 split_offset = state->current_agc->split.min;
1128 else if (agc < state->current_agc->split.max_thres)
1129 split_offset = state->current_agc->split.max;
1130 else
1131 split_offset = state->current_agc->split.max *
1132 (agc - state->current_agc->split.min_thres) /
1133 (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
1134
1135 dprintk("AGC split_offset: %d", split_offset);
1136
1137 // P_agc_force_split and P_agc_split_offset
1138 dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
1139 return 5000;
1140}
1141
1142static int dib8000_agc_startup(struct dvb_frontend *fe)
1143{
1144 struct dib8000_state *state = fe->demodulator_priv;
1145 enum frontend_tune_state *tune_state = &state->tune_state;
1146 int ret = 0;
1147 u16 reg, upd_demod_gain_period = 0x8000;
1148
1149 switch (*tune_state) {
1150 case CT_AGC_START:
1151 // set power-up level: interf+analog+AGC
1152
1153 if (state->revision != 0x8090)
1154 dib8000_set_adc_state(state, DIBX000_ADC_ON);
1155 else {
1156 dib8000_set_power_mode(state, DIB8000_POWER_ALL);
1157
1158 reg = dib8000_read_word(state, 1947)&0xff00;
1159 dib8000_write_word(state, 1946,
1160 upd_demod_gain_period & 0xFFFF);
1161 /* bit 14 = enDemodGain */
1162 dib8000_write_word(state, 1947, reg | (1<<14) |
1163 ((upd_demod_gain_period >> 16) & 0xFF));
1164
1165 /* enable adc i & q */
1166 reg = dib8000_read_word(state, 1920);
1167 dib8000_write_word(state, 1920, (reg | 0x3) &
1168 (~(1 << 7)));
1169 }
1170
1171 if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
1172 *tune_state = CT_AGC_STOP;
1173 state->status = FE_STATUS_TUNE_FAILED;
1174 break;
1175 }
1176
1177 ret = 70;
1178 *tune_state = CT_AGC_STEP_0;
1179 break;
1180
1181 case CT_AGC_STEP_0:
1182 //AGC initialization
1183 if (state->cfg.agc_control)
1184 state->cfg.agc_control(fe, 1);
1185
1186 dib8000_restart_agc(state);
1187
1188 // wait AGC rough lock time
1189 ret = 50;
1190 *tune_state = CT_AGC_STEP_1;
1191 break;
1192
1193 case CT_AGC_STEP_1:
1194 // wait AGC accurate lock time
1195 ret = 70;
1196
1197 if (dib8000_update_lna(state))
1198 // wait only AGC rough lock time
1199 ret = 50;
1200 else
1201 *tune_state = CT_AGC_STEP_2;
1202 break;
1203
1204 case CT_AGC_STEP_2:
1205 dib8000_agc_soft_split(state);
1206
1207 if (state->cfg.agc_control)
1208 state->cfg.agc_control(fe, 0);
1209
1210 *tune_state = CT_AGC_STOP;
1211 break;
1212 default:
1213 ret = dib8000_agc_soft_split(state);
1214 break;
1215 }
1216 return ret;
1217
1218}
1219
1220static void dib8096p_host_bus_drive(struct dib8000_state *state, u8 drive)
1221{
1222 u16 reg;
1223
1224 drive &= 0x7;
1225
1226 /* drive host bus 2, 3, 4 */
1227 reg = dib8000_read_word(state, 1798) &
1228 ~(0x7 | (0x7 << 6) | (0x7 << 12));
1229 reg |= (drive<<12) | (drive<<6) | drive;
1230 dib8000_write_word(state, 1798, reg);
1231
1232 /* drive host bus 5,6 */
1233 reg = dib8000_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
1234 reg |= (drive<<8) | (drive<<2);
1235 dib8000_write_word(state, 1799, reg);
1236
1237 /* drive host bus 7, 8, 9 */
1238 reg = dib8000_read_word(state, 1800) &
1239 ~(0x7 | (0x7 << 6) | (0x7 << 12));
1240 reg |= (drive<<12) | (drive<<6) | drive;
1241 dib8000_write_word(state, 1800, reg);
1242
1243 /* drive host bus 10, 11 */
1244 reg = dib8000_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
1245 reg |= (drive<<8) | (drive<<2);
1246 dib8000_write_word(state, 1801, reg);
1247
1248 /* drive host bus 12, 13, 14 */
1249 reg = dib8000_read_word(state, 1802) &
1250 ~(0x7 | (0x7 << 6) | (0x7 << 12));
1251 reg |= (drive<<12) | (drive<<6) | drive;
1252 dib8000_write_word(state, 1802, reg);
1253}
1254
1255static u32 dib8096p_calcSyncFreq(u32 P_Kin, u32 P_Kout,
1256 u32 insertExtSynchro, u32 syncSize)
1257{
1258 u32 quantif = 3;
1259 u32 nom = (insertExtSynchro * P_Kin+syncSize);
1260 u32 denom = P_Kout;
1261 u32 syncFreq = ((nom << quantif) / denom);
1262
1263 if ((syncFreq & ((1 << quantif) - 1)) != 0)
1264 syncFreq = (syncFreq >> quantif) + 1;
1265 else
1266 syncFreq = (syncFreq >> quantif);
1267
1268 if (syncFreq != 0)
1269 syncFreq = syncFreq - 1;
1270
1271 return syncFreq;
1272}
1273
1274static void dib8096p_cfg_DibTx(struct dib8000_state *state, u32 P_Kin,
1275 u32 P_Kout, u32 insertExtSynchro, u32 synchroMode,
1276 u32 syncWord, u32 syncSize)
1277{
1278 dprintk("Configure DibStream Tx");
1279
1280 dib8000_write_word(state, 1615, 1);
1281 dib8000_write_word(state, 1603, P_Kin);
1282 dib8000_write_word(state, 1605, P_Kout);
1283 dib8000_write_word(state, 1606, insertExtSynchro);
1284 dib8000_write_word(state, 1608, synchroMode);
1285 dib8000_write_word(state, 1609, (syncWord >> 16) & 0xffff);
1286 dib8000_write_word(state, 1610, syncWord & 0xffff);
1287 dib8000_write_word(state, 1612, syncSize);
1288 dib8000_write_word(state, 1615, 0);
1289}
1290
1291static void dib8096p_cfg_DibRx(struct dib8000_state *state, u32 P_Kin,
1292 u32 P_Kout, u32 synchroMode, u32 insertExtSynchro,
1293 u32 syncWord, u32 syncSize, u32 dataOutRate)
1294{
1295 u32 syncFreq;
1296
1297 dprintk("Configure DibStream Rx synchroMode = %d", synchroMode);
1298
1299 if ((P_Kin != 0) && (P_Kout != 0)) {
1300 syncFreq = dib8096p_calcSyncFreq(P_Kin, P_Kout,
1301 insertExtSynchro, syncSize);
1302 dib8000_write_word(state, 1542, syncFreq);
1303 }
1304
1305 dib8000_write_word(state, 1554, 1);
1306 dib8000_write_word(state, 1536, P_Kin);
1307 dib8000_write_word(state, 1537, P_Kout);
1308 dib8000_write_word(state, 1539, synchroMode);
1309 dib8000_write_word(state, 1540, (syncWord >> 16) & 0xffff);
1310 dib8000_write_word(state, 1541, syncWord & 0xffff);
1311 dib8000_write_word(state, 1543, syncSize);
1312 dib8000_write_word(state, 1544, dataOutRate);
1313 dib8000_write_word(state, 1554, 0);
1314}
1315
1316static void dib8096p_enMpegMux(struct dib8000_state *state, int onoff)
1317{
1318 u16 reg_1287;
1319
1320 reg_1287 = dib8000_read_word(state, 1287);
1321
1322 switch (onoff) {
1323 case 1:
1324 reg_1287 &= ~(1 << 8);
1325 break;
1326 case 0:
1327 reg_1287 |= (1 << 8);
1328 break;
1329 }
1330
1331 dib8000_write_word(state, 1287, reg_1287);
1332}
1333
1334static void dib8096p_configMpegMux(struct dib8000_state *state,
1335 u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
1336{
1337 u16 reg_1287;
1338
1339 dprintk("Enable Mpeg mux");
1340
1341 dib8096p_enMpegMux(state, 0);
1342
1343 /* If the input mode is MPEG do not divide the serial clock */
1344 if ((enSerialMode == 1) && (state->input_mode_mpeg == 1))
1345 enSerialClkDiv2 = 0;
1346
1347 reg_1287 = ((pulseWidth & 0x1f) << 3) |
1348 ((enSerialMode & 0x1) << 2) | (enSerialClkDiv2 & 0x1);
1349 dib8000_write_word(state, 1287, reg_1287);
1350
1351 dib8096p_enMpegMux(state, 1);
1352}
1353
1354static void dib8096p_setDibTxMux(struct dib8000_state *state, int mode)
1355{
1356 u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 7);
1357
1358 switch (mode) {
1359 case MPEG_ON_DIBTX:
1360 dprintk("SET MPEG ON DIBSTREAM TX");
1361 dib8096p_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
1362 reg_1288 |= (1 << 9); break;
1363 case DIV_ON_DIBTX:
1364 dprintk("SET DIV_OUT ON DIBSTREAM TX");
1365 dib8096p_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
1366 reg_1288 |= (1 << 8); break;
1367 case ADC_ON_DIBTX:
1368 dprintk("SET ADC_OUT ON DIBSTREAM TX");
1369 dib8096p_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
1370 reg_1288 |= (1 << 7); break;
1371 default:
1372 break;
1373 }
1374 dib8000_write_word(state, 1288, reg_1288);
1375}
1376
1377static void dib8096p_setHostBusMux(struct dib8000_state *state, int mode)
1378{
1379 u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 4);
1380
1381 switch (mode) {
1382 case DEMOUT_ON_HOSTBUS:
1383 dprintk("SET DEM OUT OLD INTERF ON HOST BUS");
1384 dib8096p_enMpegMux(state, 0);
1385 reg_1288 |= (1 << 6);
1386 break;
1387 case DIBTX_ON_HOSTBUS:
1388 dprintk("SET DIBSTREAM TX ON HOST BUS");
1389 dib8096p_enMpegMux(state, 0);
1390 reg_1288 |= (1 << 5);
1391 break;
1392 case MPEG_ON_HOSTBUS:
1393 dprintk("SET MPEG MUX ON HOST BUS");
1394 reg_1288 |= (1 << 4);
1395 break;
1396 default:
1397 break;
1398 }
1399 dib8000_write_word(state, 1288, reg_1288);
1400}
1401
1402static int dib8096p_set_diversity_in(struct dvb_frontend *fe, int onoff)
1403{
1404 struct dib8000_state *state = fe->demodulator_priv;
1405 u16 reg_1287;
1406
1407 switch (onoff) {
1408 case 0: /* only use the internal way - not the diversity input */
1409 dprintk("%s mode OFF : by default Enable Mpeg INPUT",
1410 __func__);
1411 /* outputRate = 8 */
1412 dib8096p_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0);
1413
1414 /* Do not divide the serial clock of MPEG MUX in
1415 SERIAL MODE in case input mode MPEG is used */
1416 reg_1287 = dib8000_read_word(state, 1287);
1417 /* enSerialClkDiv2 == 1 ? */
1418 if ((reg_1287 & 0x1) == 1) {
1419 /* force enSerialClkDiv2 = 0 */
1420 reg_1287 &= ~0x1;
1421 dib8000_write_word(state, 1287, reg_1287);
1422 }
1423 state->input_mode_mpeg = 1;
1424 break;
1425 case 1: /* both ways */
1426 case 2: /* only the diversity input */
1427 dprintk("%s ON : Enable diversity INPUT", __func__);
1428 dib8096p_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
1429 state->input_mode_mpeg = 0;
1430 break;
1431 }
1432
1433 dib8000_set_diversity_in(state->fe[0], onoff);
1434 return 0;
1435}
1436
1437static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode)
1438{
1439 struct dib8000_state *state = fe->demodulator_priv;
1440 u16 outreg, smo_mode, fifo_threshold;
1441 u8 prefer_mpeg_mux_use = 1;
1442 int ret = 0;
1443
1444 dib8096p_host_bus_drive(state, 1);
1445
1446 fifo_threshold = 1792;
1447 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
1448 outreg = dib8000_read_word(state, 1286) &
1449 ~((1 << 10) | (0x7 << 6) | (1 << 1));
1450
1451 switch (mode) {
1452 case OUTMODE_HIGH_Z:
1453 outreg = 0;
1454 break;
1455
1456 case OUTMODE_MPEG2_SERIAL:
1457 if (prefer_mpeg_mux_use) {
1458 dprintk("dib8096P setting output mode TS_SERIAL using Mpeg Mux");
1459 dib8096p_configMpegMux(state, 3, 1, 1);
1460 dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS);
1461 } else {/* Use Smooth block */
1462 dprintk("dib8096P setting output mode TS_SERIAL using Smooth bloc");
1463 dib8096p_setHostBusMux(state,
1464 DEMOUT_ON_HOSTBUS);
1465 outreg |= (2 << 6) | (0 << 1);
1466 }
1467 break;
1468
1469 case OUTMODE_MPEG2_PAR_GATED_CLK:
1470 if (prefer_mpeg_mux_use) {
1471 dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
1472 dib8096p_configMpegMux(state, 2, 0, 0);
1473 dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS);
1474 } else { /* Use Smooth block */
1475 dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Smooth block");
1476 dib8096p_setHostBusMux(state,
1477 DEMOUT_ON_HOSTBUS);
1478 outreg |= (0 << 6);
1479 }
1480 break;
1481
1482 case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */
1483 dprintk("dib8096P setting output mode TS_PARALLEL_CONT using Smooth block");
1484 dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
1485 outreg |= (1 << 6);
1486 break;
1487
1488 case OUTMODE_MPEG2_FIFO:
1489 /* Using Smooth block because not supported
1490 by new Mpeg Mux bloc */
1491 dprintk("dib8096P setting output mode TS_FIFO using Smooth block");
1492 dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
1493 outreg |= (5 << 6);
1494 smo_mode |= (3 << 1);
1495 fifo_threshold = 512;
1496 break;
1497
1498 case OUTMODE_DIVERSITY:
1499 dprintk("dib8096P setting output mode MODE_DIVERSITY");
1500 dib8096p_setDibTxMux(state, DIV_ON_DIBTX);
1501 dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
1502 break;
1503
1504 case OUTMODE_ANALOG_ADC:
1505 dprintk("dib8096P setting output mode MODE_ANALOG_ADC");
1506 dib8096p_setDibTxMux(state, ADC_ON_DIBTX);
1507 dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
1508 break;
1509 }
1510
1511 if (mode != OUTMODE_HIGH_Z)
1512 outreg |= (1<<10);
1513
1514 dprintk("output_mpeg2_in_188_bytes = %d",
1515 state->cfg.output_mpeg2_in_188_bytes);
1516 if (state->cfg.output_mpeg2_in_188_bytes)
1517 smo_mode |= (1 << 5);
1518
1519 ret |= dib8000_write_word(state, 299, smo_mode);
1520 /* synchronous fread */
1521 ret |= dib8000_write_word(state, 299 + 1, fifo_threshold);
1522 ret |= dib8000_write_word(state, 1286, outreg);
1523
1524 return ret;
1525}
1526
1527static int map_addr_to_serpar_number(struct i2c_msg *msg)
1528{
1529 if (msg->buf[0] <= 15)
1530 msg->buf[0] -= 1;
1531 else if (msg->buf[0] == 17)
1532 msg->buf[0] = 15;
1533 else if (msg->buf[0] == 16)
1534 msg->buf[0] = 17;
1535 else if (msg->buf[0] == 19)
1536 msg->buf[0] = 16;
1537 else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
1538 msg->buf[0] -= 3;
1539 else if (msg->buf[0] == 28)
1540 msg->buf[0] = 23;
1541 else if (msg->buf[0] == 99)
1542 msg->buf[0] = 99;
1543 else
1544 return -EINVAL;
1545 return 0;
1546}
1547
1548static int dib8096p_tuner_write_serpar(struct i2c_adapter *i2c_adap,
1549 struct i2c_msg msg[], int num)
1550{
1551 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1552 u8 n_overflow = 1;
1553 u16 i = 1000;
1554 u16 serpar_num = msg[0].buf[0];
1555
1556 while (n_overflow == 1 && i) {
1557 n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1;
1558 i--;
1559 if (i == 0)
1560 dprintk("Tuner ITF: write busy (overflow)");
1561 }
1562 dib8000_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
1563 dib8000_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
1564
1565 return num;
1566}
1567
1568static int dib8096p_tuner_read_serpar(struct i2c_adapter *i2c_adap,
1569 struct i2c_msg msg[], int num)
1570{
1571 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1572 u8 n_overflow = 1, n_empty = 1;
1573 u16 i = 1000;
1574 u16 serpar_num = msg[0].buf[0];
1575 u16 read_word;
1576
1577 while (n_overflow == 1 && i) {
1578 n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1;
1579 i--;
1580 if (i == 0)
1581 dprintk("TunerITF: read busy (overflow)");
1582 }
1583 dib8000_write_word(state, 1985, (0<<6) | (serpar_num&0x3f));
1584
1585 i = 1000;
1586 while (n_empty == 1 && i) {
1587 n_empty = dib8000_read_word(state, 1984)&0x1;
1588 i--;
1589 if (i == 0)
1590 dprintk("TunerITF: read busy (empty)");
1591 }
1592
1593 read_word = dib8000_read_word(state, 1987);
1594 msg[1].buf[0] = (read_word >> 8) & 0xff;
1595 msg[1].buf[1] = (read_word) & 0xff;
1596
1597 return num;
1598}
1599
1600static int dib8096p_tuner_rw_serpar(struct i2c_adapter *i2c_adap,
1601 struct i2c_msg msg[], int num)
1602{
1603 if (map_addr_to_serpar_number(&msg[0]) == 0) {
1604 if (num == 1) /* write */
1605 return dib8096p_tuner_write_serpar(i2c_adap, msg, 1);
1606 else /* read */
1607 return dib8096p_tuner_read_serpar(i2c_adap, msg, 2);
1608 }
1609 return num;
1610}
1611
1612static int dib8096p_rw_on_apb(struct i2c_adapter *i2c_adap,
1613 struct i2c_msg msg[], int num, u16 apb_address)
1614{
1615 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1616 u16 word;
1617
1618 if (num == 1) { /* write */
1619 dib8000_write_word(state, apb_address,
1620 ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
1621 } else {
1622 word = dib8000_read_word(state, apb_address);
1623 msg[1].buf[0] = (word >> 8) & 0xff;
1624 msg[1].buf[1] = (word) & 0xff;
1625 }
1626 return num;
1627}
1628
1629static int dib8096p_tuner_xfer(struct i2c_adapter *i2c_adap,
1630 struct i2c_msg msg[], int num)
1631{
1632 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1633 u16 apb_address = 0, word;
1634 int i = 0;
1635
1636 switch (msg[0].buf[0]) {
1637 case 0x12:
1638 apb_address = 1920;
1639 break;
1640 case 0x14:
1641 apb_address = 1921;
1642 break;
1643 case 0x24:
1644 apb_address = 1922;
1645 break;
1646 case 0x1a:
1647 apb_address = 1923;
1648 break;
1649 case 0x22:
1650 apb_address = 1924;
1651 break;
1652 case 0x33:
1653 apb_address = 1926;
1654 break;
1655 case 0x34:
1656 apb_address = 1927;
1657 break;
1658 case 0x35:
1659 apb_address = 1928;
1660 break;
1661 case 0x36:
1662 apb_address = 1929;
1663 break;
1664 case 0x37:
1665 apb_address = 1930;
1666 break;
1667 case 0x38:
1668 apb_address = 1931;
1669 break;
1670 case 0x39:
1671 apb_address = 1932;
1672 break;
1673 case 0x2a:
1674 apb_address = 1935;
1675 break;
1676 case 0x2b:
1677 apb_address = 1936;
1678 break;
1679 case 0x2c:
1680 apb_address = 1937;
1681 break;
1682 case 0x2d:
1683 apb_address = 1938;
1684 break;
1685 case 0x2e:
1686 apb_address = 1939;
1687 break;
1688 case 0x2f:
1689 apb_address = 1940;
1690 break;
1691 case 0x30:
1692 apb_address = 1941;
1693 break;
1694 case 0x31:
1695 apb_address = 1942;
1696 break;
1697 case 0x32:
1698 apb_address = 1943;
1699 break;
1700 case 0x3e:
1701 apb_address = 1944;
1702 break;
1703 case 0x3f:
1704 apb_address = 1945;
1705 break;
1706 case 0x40:
1707 apb_address = 1948;
1708 break;
1709 case 0x25:
1710 apb_address = 936;
1711 break;
1712 case 0x26:
1713 apb_address = 937;
1714 break;
1715 case 0x27:
1716 apb_address = 938;
1717 break;
1718 case 0x28:
1719 apb_address = 939;
1720 break;
1721 case 0x1d:
1722 /* get sad sel request */
1723 i = ((dib8000_read_word(state, 921) >> 12)&0x3);
1724 word = dib8000_read_word(state, 924+i);
1725 msg[1].buf[0] = (word >> 8) & 0xff;
1726 msg[1].buf[1] = (word) & 0xff;
1727 return num;
1728 case 0x1f:
1729 if (num == 1) { /* write */
1730 word = (u16) ((msg[0].buf[1] << 8) |
1731 msg[0].buf[2]);
1732 /* in the VGAMODE Sel are located on bit 0/1 */
1733 word &= 0x3;
1734 word = (dib8000_read_word(state, 921) &
1735 ~(3<<12)) | (word<<12);
1736 /* Set the proper input */
1737 dib8000_write_word(state, 921, word);
1738 return num;
1739 }
1740 }
1741
1742 if (apb_address != 0) /* R/W acces via APB */
1743 return dib8096p_rw_on_apb(i2c_adap, msg, num, apb_address);
1744 else /* R/W access via SERPAR */
1745 return dib8096p_tuner_rw_serpar(i2c_adap, msg, num);
1746
1747 return 0;
1748}
1749
1750static u32 dib8096p_i2c_func(struct i2c_adapter *adapter)
1751{
1752 return I2C_FUNC_I2C;
1753}
1754
1755static struct i2c_algorithm dib8096p_tuner_xfer_algo = {
1756 .master_xfer = dib8096p_tuner_xfer,
1757 .functionality = dib8096p_i2c_func,
1758};
1759
1760struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe)
1761{
1762 struct dib8000_state *st = fe->demodulator_priv;
1763 return &st->dib8096p_tuner_adap;
1764}
1765EXPORT_SYMBOL(dib8096p_get_i2c_tuner);
1766
1767int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff)
1768{
1769 struct dib8000_state *state = fe->demodulator_priv;
1770 u16 en_cur_state;
1771
1772 dprintk("sleep dib8096p: %d", onoff);
1773
1774 en_cur_state = dib8000_read_word(state, 1922);
1775
1776 /* LNAs and MIX are ON and therefore it is a valid configuration */
1777 if (en_cur_state > 0xff)
1778 state->tuner_enable = en_cur_state ;
1779
1780 if (onoff)
1781 en_cur_state &= 0x00ff;
1782 else {
1783 if (state->tuner_enable != 0)
1784 en_cur_state = state->tuner_enable;
1785 }
1786
1787 dib8000_write_word(state, 1922, en_cur_state);
1788
1789 return 0;
1790}
1791EXPORT_SYMBOL(dib8096p_tuner_sleep);
1792
1793static const s32 lut_1000ln_mant[] =
1794{
1795 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
1796};
1797
1798s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
1799{
1800 struct dib8000_state *state = fe->demodulator_priv;
1801 u32 ix = 0, tmp_val = 0, exp = 0, mant = 0;
1802 s32 val;
1803
1804 val = dib8000_read32(state, 384);
1805 if (mode) {
1806 tmp_val = val;
1807 while (tmp_val >>= 1)
1808 exp++;
1809 mant = (val * 1000 / (1<<exp));
1810 ix = (u8)((mant-1000)/100); /* index of the LUT */
1811 val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908);
1812 val = (val*256)/1000;
1813 }
1814 return val;
1815}
1816EXPORT_SYMBOL(dib8000_get_adc_power);
1817
1818int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ)
1819{
1820 struct dib8000_state *state = fe->demodulator_priv;
1821 int val = 0;
1822
1823 switch (IQ) {
1824 case 1:
1825 val = dib8000_read_word(state, 403);
1826 break;
1827 case 0:
1828 val = dib8000_read_word(state, 404);
1829 break;
1830 }
1831 if (val & 0x200)
1832 val -= 1024;
1833
1834 return val;
1835}
1836EXPORT_SYMBOL(dib8090p_get_dc_power);
1837
1838static void dib8000_update_timf(struct dib8000_state *state)
1839{
1840 u32 timf = state->timf = dib8000_read32(state, 435);
1841
1842 dib8000_write_word(state, 29, (u16) (timf >> 16));
1843 dib8000_write_word(state, 30, (u16) (timf & 0xffff));
1844 dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
1845}
1846
1847u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf)
1848{
1849 struct dib8000_state *state = fe->demodulator_priv;
1850
1851 switch (op) {
1852 case DEMOD_TIMF_SET:
1853 state->timf = timf;
1854 break;
1855 case DEMOD_TIMF_UPDATE:
1856 dib8000_update_timf(state);
1857 break;
1858 case DEMOD_TIMF_GET:
1859 break;
1860 }
1861 dib8000_set_bandwidth(state->fe[0], 6000);
1862
1863 return state->timf;
1864}
1865EXPORT_SYMBOL(dib8000_ctrl_timf);
1866
1867static const u16 adc_target_16dB[11] = {
1868 (1 << 13) - 825 - 117,
1869 (1 << 13) - 837 - 117,
1870 (1 << 13) - 811 - 117,
1871 (1 << 13) - 766 - 117,
1872 (1 << 13) - 737 - 117,
1873 (1 << 13) - 693 - 117,
1874 (1 << 13) - 648 - 117,
1875 (1 << 13) - 619 - 117,
1876 (1 << 13) - 575 - 117,
1877 (1 << 13) - 531 - 117,
1878 (1 << 13) - 501 - 117
1879};
1880static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
1881
1882static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
1883{
1884 u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
1885 u8 guard, crate, constellation, timeI;
1886 u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled
1887 const s16 *ncoeff = NULL, *ana_fe;
1888 u16 tmcc_pow = 0;
1889 u16 coff_pow = 0x2800;
1890 u16 init_prbs = 0xfff;
1891 u16 ana_gain = 0;
1892
1893 if (state->revision == 0x8090)
1894 dib8000_init_sdram(state);
1895
1896 if (state->ber_monitored_layer != LAYER_ALL)
1897 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
1898 else
1899 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
1900
1901 i = dib8000_read_word(state, 26) & 1; // P_dds_invspec
1902 dib8000_write_word(state, 26, state->fe[0]->dtv_property_cache.inversion^i);
1903
1904 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1905 //compute new dds_freq for the seg and adjust prbs
1906 int seg_offset =
1907 state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx -
1908 (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) -
1909 (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2);
1910 int clk = state->cfg.pll->internal;
1911 u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26)
1912 int dds_offset = seg_offset * segtodds;
1913 int new_dds, sub_channel;
1914 if ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1915 dds_offset -= (int)(segtodds / 2);
1916
1917 if (state->cfg.pll->ifreq == 0) {
1918 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0) {
1919 dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
1920 new_dds = dds_offset;
1921 } else
1922 new_dds = dds_offset;
1923
1924 // We shift tuning frequency if the wanted segment is :
1925 // - the segment of center frequency with an odd total number of segments
1926 // - the segment to the left of center frequency with an even total number of segments
1927 // - the segment to the right of center frequency with an even total number of segments
1928 if ((state->fe[0]->dtv_property_cache.delivery_system == SYS_ISDBT)
1929 && (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
1930 && (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1931 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1932 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1933 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1934 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2)))
1935 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1936 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1937 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1938 )) {
1939 new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
1940 }
1941 } else {
1942 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0)
1943 new_dds = state->cfg.pll->ifreq - dds_offset;
1944 else
1945 new_dds = state->cfg.pll->ifreq + dds_offset;
1946 }
1947 dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
1948 dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
1949 if (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1950 sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
1951 else
1952 sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
1953 sub_channel -= 6;
1954
1955 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
1956 || state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
1957 dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1
1958 dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1
1959 } else {
1960 dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); //adp_pass =0
1961 dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0
1962 }
1963
1964 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1965 case TRANSMISSION_MODE_2K:
1966 switch (sub_channel) {
1967 case -6:
1968 init_prbs = 0x0;
1969 break; // 41, 0, 1
1970 case -5:
1971 init_prbs = 0x423;
1972 break; // 02~04
1973 case -4:
1974 init_prbs = 0x9;
1975 break; // 05~07
1976 case -3:
1977 init_prbs = 0x5C7;
1978 break; // 08~10
1979 case -2:
1980 init_prbs = 0x7A6;
1981 break; // 11~13
1982 case -1:
1983 init_prbs = 0x3D8;
1984 break; // 14~16
1985 case 0:
1986 init_prbs = 0x527;
1987 break; // 17~19
1988 case 1:
1989 init_prbs = 0x7FF;
1990 break; // 20~22
1991 case 2:
1992 init_prbs = 0x79B;
1993 break; // 23~25
1994 case 3:
1995 init_prbs = 0x3D6;
1996 break; // 26~28
1997 case 4:
1998 init_prbs = 0x3A2;
1999 break; // 29~31
2000 case 5:
2001 init_prbs = 0x53B;
2002 break; // 32~34
2003 case 6:
2004 init_prbs = 0x2F4;
2005 break; // 35~37
2006 default:
2007 case 7:
2008 init_prbs = 0x213;
2009 break; // 38~40
2010 }
2011 break;
2012
2013 case TRANSMISSION_MODE_4K:
2014 switch (sub_channel) {
2015 case -6:
2016 init_prbs = 0x0;
2017 break; // 41, 0, 1
2018 case -5:
2019 init_prbs = 0x208;
2020 break; // 02~04
2021 case -4:
2022 init_prbs = 0xC3;
2023 break; // 05~07
2024 case -3:
2025 init_prbs = 0x7B9;
2026 break; // 08~10
2027 case -2:
2028 init_prbs = 0x423;
2029 break; // 11~13
2030 case -1:
2031 init_prbs = 0x5C7;
2032 break; // 14~16
2033 case 0:
2034 init_prbs = 0x3D8;
2035 break; // 17~19
2036 case 1:
2037 init_prbs = 0x7FF;
2038 break; // 20~22
2039 case 2:
2040 init_prbs = 0x3D6;
2041 break; // 23~25
2042 case 3:
2043 init_prbs = 0x53B;
2044 break; // 26~28
2045 case 4:
2046 init_prbs = 0x213;
2047 break; // 29~31
2048 case 5:
2049 init_prbs = 0x29;
2050 break; // 32~34
2051 case 6:
2052 init_prbs = 0xD0;
2053 break; // 35~37
2054 default:
2055 case 7:
2056 init_prbs = 0x48E;
2057 break; // 38~40
2058 }
2059 break;
2060
2061 default:
2062 case TRANSMISSION_MODE_8K:
2063 switch (sub_channel) {
2064 case -6:
2065 init_prbs = 0x0;
2066 break; // 41, 0, 1
2067 case -5:
2068 init_prbs = 0x740;
2069 break; // 02~04
2070 case -4:
2071 init_prbs = 0x069;
2072 break; // 05~07
2073 case -3:
2074 init_prbs = 0x7DD;
2075 break; // 08~10
2076 case -2:
2077 init_prbs = 0x208;
2078 break; // 11~13
2079 case -1:
2080 init_prbs = 0x7B9;
2081 break; // 14~16
2082 case 0:
2083 init_prbs = 0x5C7;
2084 break; // 17~19
2085 case 1:
2086 init_prbs = 0x7FF;
2087 break; // 20~22
2088 case 2:
2089 init_prbs = 0x53B;
2090 break; // 23~25
2091 case 3:
2092 init_prbs = 0x29;
2093 break; // 26~28
2094 case 4:
2095 init_prbs = 0x48E;
2096 break; // 29~31
2097 case 5:
2098 init_prbs = 0x4C4;
2099 break; // 32~34
2100 case 6:
2101 init_prbs = 0x367;
2102 break; // 33~37
2103 default:
2104 case 7:
2105 init_prbs = 0x684;
2106 break; // 38~40
2107 }
2108 break;
2109 }
2110 } else {
2111 dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
2112 dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
2113 dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
2114 }
2115 /*P_mode == ?? */
2116 dib8000_write_word(state, 10, (seq << 4));
2117 // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
2118
2119 switch (state->fe[0]->dtv_property_cache.guard_interval) {
2120 case GUARD_INTERVAL_1_32:
2121 guard = 0;
2122 break;
2123 case GUARD_INTERVAL_1_16:
2124 guard = 1;
2125 break;
2126 case GUARD_INTERVAL_1_8:
2127 guard = 2;
2128 break;
2129 case GUARD_INTERVAL_1_4:
2130 default:
2131 guard = 3;
2132 break;
2133 }
2134
2135 dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3)); // ADDR 1
2136
2137 max_constellation = DQPSK;
2138 for (i = 0; i < 3; i++) {
2139 switch (state->fe[0]->dtv_property_cache.layer[i].modulation) {
2140 case DQPSK:
2141 constellation = 0;
2142 break;
2143 case QPSK:
2144 constellation = 1;
2145 break;
2146 case QAM_16:
2147 constellation = 2;
2148 break;
2149 case QAM_64:
2150 default:
2151 constellation = 3;
2152 break;
2153 }
2154
2155 switch (state->fe[0]->dtv_property_cache.layer[i].fec) {
2156 case FEC_1_2:
2157 crate = 1;
2158 break;
2159 case FEC_2_3:
2160 crate = 2;
2161 break;
2162 case FEC_3_4:
2163 crate = 3;
2164 break;
2165 case FEC_5_6:
2166 crate = 5;
2167 break;
2168 case FEC_7_8:
2169 default:
2170 crate = 7;
2171 break;
2172 }
2173
2174 if ((state->fe[0]->dtv_property_cache.layer[i].interleaving > 0) &&
2175 ((state->fe[0]->dtv_property_cache.layer[i].interleaving <= 3) ||
2176 (state->fe[0]->dtv_property_cache.layer[i].interleaving == 4 && state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1))
2177 )
2178 timeI = state->fe[0]->dtv_property_cache.layer[i].interleaving;
2179 else
2180 timeI = 0;
2181 dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe[0]->dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
2182 (crate << 3) | timeI);
2183 if (state->fe[0]->dtv_property_cache.layer[i].segment_count > 0) {
2184 switch (max_constellation) {
2185 case DQPSK:
2186 case QPSK:
2187 if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_16 ||
2188 state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
2189 max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
2190 break;
2191 case QAM_16:
2192 if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
2193 max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
2194 break;
2195 }
2196 }
2197 }
2198
2199 mode = fft_to_mode(state);
2200
2201 //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
2202
2203 dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
2204 ((state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe[0]->dtv_property_cache.
2205 isdbt_sb_mode & 1) << 4));
2206
2207 dprintk("mode = %d ; guard = %d", mode, state->fe[0]->dtv_property_cache.guard_interval);
2208
2209 /* signal optimization parameter */
2210
2211 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception) {
2212 seg_diff_mask = (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
2213 for (i = 1; i < 3; i++)
2214 nbseg_diff +=
2215 (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
2216 for (i = 0; i < nbseg_diff; i++)
2217 seg_diff_mask |= 1 << permu_seg[i + 1];
2218 } else {
2219 for (i = 0; i < 3; i++)
2220 nbseg_diff +=
2221 (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
2222 for (i = 0; i < nbseg_diff; i++)
2223 seg_diff_mask |= 1 << permu_seg[i];
2224 }
2225 dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
2226
2227 state->differential_constellation = (seg_diff_mask != 0);
2228 if (state->revision != 0x8090)
2229 dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
2230 else
2231 dib8096p_set_diversity_in(state->fe[0], state->diversity_onoff);
2232
2233 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
2234 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
2235 seg_mask13 = 0x00E0;
2236 else // 1-segment
2237 seg_mask13 = 0x0040;
2238 } else
2239 seg_mask13 = 0x1fff;
2240
2241 // WRITE: Mode & Diff mask
2242 dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
2243
2244 if ((seg_diff_mask) || (state->fe[0]->dtv_property_cache.isdbt_sb_mode))
2245 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
2246 else
2247 dib8000_write_word(state, 268, (2 << 9) | 39); //init value
2248
2249 // ---- SMALL ----
2250 // P_small_seg_diff
2251 dib8000_write_word(state, 352, seg_diff_mask); // ADDR 352
2252
2253 dib8000_write_word(state, 353, seg_mask13); // ADDR 353
2254
2255/* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
2256
2257 // ---- SMALL ----
2258 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
2259 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
2260 case TRANSMISSION_MODE_2K:
2261 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
2262 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
2263 ncoeff = coeff_2k_sb_1seg_dqpsk;
2264 else // QPSK or QAM
2265 ncoeff = coeff_2k_sb_1seg;
2266 } else { // 3-segments
2267 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
2268 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
2269 ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
2270 else // QPSK or QAM on external segments
2271 ncoeff = coeff_2k_sb_3seg_0dqpsk;
2272 } else { // QPSK or QAM on central segment
2273 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
2274 ncoeff = coeff_2k_sb_3seg_1dqpsk;
2275 else // QPSK or QAM on external segments
2276 ncoeff = coeff_2k_sb_3seg;
2277 }
2278 }
2279 break;
2280
2281 case TRANSMISSION_MODE_4K:
2282 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
2283 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
2284 ncoeff = coeff_4k_sb_1seg_dqpsk;
2285 else // QPSK or QAM
2286 ncoeff = coeff_4k_sb_1seg;
2287 } else { // 3-segments
2288 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
2289 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
2290 ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
2291 } else { // QPSK or QAM on external segments
2292 ncoeff = coeff_4k_sb_3seg_0dqpsk;
2293 }
2294 } else { // QPSK or QAM on central segment
2295 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
2296 ncoeff = coeff_4k_sb_3seg_1dqpsk;
2297 } else // QPSK or QAM on external segments
2298 ncoeff = coeff_4k_sb_3seg;
2299 }
2300 }
2301 break;
2302
2303 case TRANSMISSION_MODE_AUTO:
2304 case TRANSMISSION_MODE_8K:
2305 default:
2306 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
2307 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
2308 ncoeff = coeff_8k_sb_1seg_dqpsk;
2309 else // QPSK or QAM
2310 ncoeff = coeff_8k_sb_1seg;
2311 } else { // 3-segments
2312 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
2313 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
2314 ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
2315 } else { // QPSK or QAM on external segments
2316 ncoeff = coeff_8k_sb_3seg_0dqpsk;
2317 }
2318 } else { // QPSK or QAM on central segment
2319 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
2320 ncoeff = coeff_8k_sb_3seg_1dqpsk;
2321 } else // QPSK or QAM on external segments
2322 ncoeff = coeff_8k_sb_3seg;
2323 }
2324 }
2325 break;
2326 }
2327 for (i = 0; i < 8; i++)
2328 dib8000_write_word(state, 343 + i, ncoeff[i]);
2329 }
2330
2331 // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
2332 dib8000_write_word(state, 351,
2333 (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 9) | (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
2334
2335 // ---- COFF ----
2336 // Carloff, the most robust
2337 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
2338
2339 // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
2340 // P_coff_narrow_band=1, P_coff_square_val=1, P_coff_one_seg=~partial_rcpt, P_coff_use_tmcc=1, P_coff_use_ac=1
2341 dib8000_write_word(state, 187,
2342 (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 2)
2343 | 0x3);
2344
2345/* // P_small_coef_ext_enable = 1 */
2346/* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
2347
2348 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
2349
2350 // P_coff_winlen=63, P_coff_thres_lock=15, P_coff_one_seg_width= (P_mode == 3) , P_coff_one_seg_sym= (P_mode-1)
2351 if (mode == 3)
2352 dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14));
2353 else
2354 dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14));
2355 // P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1,
2356 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4
2357 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
2358 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
2359 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
2360 // P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
2361 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
2362
2363 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
2364 dib8000_write_word(state, 181, 300);
2365 dib8000_write_word(state, 182, 150);
2366 dib8000_write_word(state, 183, 80);
2367 dib8000_write_word(state, 184, 300);
2368 dib8000_write_word(state, 185, 150);
2369 dib8000_write_word(state, 186, 80);
2370 } else { // Sound Broadcasting mode 3 seg
2371 // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
2372 /* if (mode == 3) */
2373 /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
2374 /* else */
2375 /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
2376 dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
2377
2378 // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
2379 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4
2380 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
2381 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
2382 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
2383 //P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
2384 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
2385
2386 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
2387 dib8000_write_word(state, 181, 350);
2388 dib8000_write_word(state, 182, 300);
2389 dib8000_write_word(state, 183, 250);
2390 dib8000_write_word(state, 184, 350);
2391 dib8000_write_word(state, 185, 300);
2392 dib8000_write_word(state, 186, 250);
2393 }
2394
2395 } else if (state->isdbt_cfg_loaded == 0) { // if not Sound Broadcasting mode : put default values for 13 segments
2396 dib8000_write_word(state, 180, (16 << 6) | 9);
2397 dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
2398 coff_pow = 0x2800;
2399 for (i = 0; i < 6; i++)
2400 dib8000_write_word(state, 181 + i, coff_pow);
2401
2402 // P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1,
2403 // P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 3, P_pre_freq_win_len=1
2404 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
2405
2406 // P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6
2407 dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
2408 // P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1
2409 dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
2410 }
2411 // ---- FFT ----
2412 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 && state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
2413 dib8000_write_word(state, 178, 64); // P_fft_powrange=64
2414 else
2415 dib8000_write_word(state, 178, 32); // P_fft_powrange=32
2416
2417 /* make the cpil_coff_lock more robust but slower p_coff_winlen
2418 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
2419 */
2420 /* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
2421 dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
2422
2423 dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */
2424 dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */
2425 dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */
2426 if ((!state->fe[0]->dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
2427 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
2428 else
2429 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */
2430 dib8000_write_word(state, 287, ~seg_mask13 | 0x1000); /* P_tmcc_seg_inh */
2431 //dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */
2432 if (!autosearching)
2433 dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
2434 else
2435 dib8000_write_word(state, 288, 0x1fff); //disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels.
2436 dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000);
2437
2438 dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */
2439
2440 /* offset loop parameters */
2441 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
2442 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
2443 /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
2444 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
2445
2446 else // Sound Broadcasting mode 3 seg
2447 /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
2448 dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60);
2449 } else
2450 // TODO in 13 seg, timf_alpha can always be the same or not ?
2451 /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
2452 dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
2453
2454 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
2455 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
2456 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */
2457 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
2458
2459 else // Sound Broadcasting mode 3 seg
2460 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (10-P_mode) */
2461 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (9 - mode));
2462 } else
2463 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = 9 */
2464 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
2465
2466 /* P_dvsy_sync_wait - reuse mode */
2467 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
2468 case TRANSMISSION_MODE_8K:
2469 mode = 256;
2470 break;
2471 case TRANSMISSION_MODE_4K:
2472 mode = 128;
2473 break;
2474 default:
2475 case TRANSMISSION_MODE_2K:
2476 mode = 64;
2477 break;
2478 }
2479 if (state->cfg.diversity_delay == 0)
2480 mode = (mode * (1 << (guard)) * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo
2481 else
2482 mode = (mode * (1 << (guard)) * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for DVSY-fifo
2483 mode <<= 4;
2484 dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | mode);
2485
2486 /* channel estimation fine configuration */
2487 switch (max_constellation) {
2488 case QAM_64:
2489 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
2490 coeff[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
2491 coeff[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
2492 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
2493 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
2494 //if (!state->cfg.hostbus_diversity) //if diversity, we should prehaps use the configuration of the max_constallation -1
2495 break;
2496 case QAM_16:
2497 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
2498 coeff[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
2499 coeff[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
2500 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
2501 coeff[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
2502 //if (!((state->cfg.hostbus_diversity) && (max_constellation == QAM_16)))
2503 break;
2504 default:
2505 ana_gain = 0; // 0 : goes along with ADC target at -22dB to keep good mobile performance and lock at sensitivity level
2506 coeff[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
2507 coeff[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
2508 coeff[2] = 0x0333; /* P_adp_regul_ext 0.1 */
2509 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
2510 break;
2511 }
2512 for (mode = 0; mode < 4; mode++)
2513 dib8000_write_word(state, 215 + mode, coeff[mode]);
2514
2515 // update ana_gain depending on max constellation
2516 dib8000_write_word(state, 116, ana_gain);
2517 // update ADC target depending on ana_gain
2518 if (ana_gain) { // set -16dB ADC target for ana_gain=-1
2519 for (i = 0; i < 10; i++)
2520 dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
2521 } else { // set -22dB ADC target for ana_gain=0
2522 for (i = 0; i < 10; i++)
2523 dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
2524 }
2525
2526 // ---- ANA_FE ----
2527 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
2528 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
2529 ana_fe = ana_fe_coeff_3seg;
2530 else // 1-segment
2531 ana_fe = ana_fe_coeff_1seg;
2532 } else
2533 ana_fe = ana_fe_coeff_13seg;
2534
2535 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0)
2536 for (mode = 0; mode < 24; mode++)
2537 dib8000_write_word(state, 117 + mode, ana_fe[mode]);
2538
2539 // ---- CHAN_BLK ----
2540 for (i = 0; i < 13; i++) {
2541 if ((((~seg_diff_mask) >> i) & 1) == 1) {
2542 P_cfr_left_edge += (1 << i) * ((i == 0) || ((((seg_mask13 & (~seg_diff_mask)) >> (i - 1)) & 1) == 0));
2543 P_cfr_right_edge += (1 << i) * ((i == 12) || ((((seg_mask13 & (~seg_diff_mask)) >> (i + 1)) & 1) == 0));
2544 }
2545 }
2546 dib8000_write_word(state, 222, P_cfr_left_edge); // P_cfr_left_edge
2547 dib8000_write_word(state, 223, P_cfr_right_edge); // P_cfr_right_edge
2548 // "P_cspu_left_edge" not used => do not care
2549 // "P_cspu_right_edge" not used => do not care
2550
2551 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
2552 dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1
2553 dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0
2554 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0
2555 && state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) {
2556 //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0
2557 dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15
2558 }
2559 } else if (state->isdbt_cfg_loaded == 0) {
2560 dib8000_write_word(state, 228, 0); // default value
2561 dib8000_write_word(state, 265, 31); // default value
2562 dib8000_write_word(state, 205, 0x200f); // init value
2563 }
2564 // ---- TMCC ----
2565 for (i = 0; i < 3; i++)
2566 tmcc_pow +=
2567 (((state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe[0]->dtv_property_cache.layer[i].segment_count);
2568 // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9);
2569 // Threshold is set at 1/4 of max power.
2570 tmcc_pow *= (1 << (9 - 2));
2571
2572 dib8000_write_word(state, 290, tmcc_pow); // P_tmcc_dec_thres_2k
2573 dib8000_write_word(state, 291, tmcc_pow); // P_tmcc_dec_thres_4k
2574 dib8000_write_word(state, 292, tmcc_pow); // P_tmcc_dec_thres_8k
2575 //dib8000_write_word(state, 287, (1 << 13) | 0x1000 );
2576 // ---- PHA3 ----
2577
2578 if (state->isdbt_cfg_loaded == 0)
2579 dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */
2580
2581 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
2582 state->isdbt_cfg_loaded = 0;
2583 else
2584 state->isdbt_cfg_loaded = 1;
2585
2586}
2587
2588static int dib8000_autosearch_start(struct dvb_frontend *fe)
2589{
2590 u8 factor;
2591 u32 value;
2592 struct dib8000_state *state = fe->demodulator_priv;
2593
2594 int slist = 0;
2595
2596 state->fe[0]->dtv_property_cache.inversion = 0;
2597 if (!state->fe[0]->dtv_property_cache.isdbt_sb_mode)
2598 state->fe[0]->dtv_property_cache.layer[0].segment_count = 13;
2599 state->fe[0]->dtv_property_cache.layer[0].modulation = QAM_64;
2600 state->fe[0]->dtv_property_cache.layer[0].fec = FEC_2_3;
2601 state->fe[0]->dtv_property_cache.layer[0].interleaving = 0;
2602
2603 //choose the right list, in sb, always do everything
2604 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
2605 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
2606 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
2607 slist = 7;
2608 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
2609 } else {
2610 if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) {
2611 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
2612 slist = 7;
2613 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 to have autosearch start ok with mode2
2614 } else
2615 slist = 3;
2616 } else {
2617 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
2618 slist = 2;
2619 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
2620 } else
2621 slist = 0;
2622 }
2623
2624 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO)
2625 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
2626 if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO)
2627 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
2628
2629 dprintk("using list for autosearch : %d", slist);
2630 dib8000_set_channel(state, (unsigned char)slist, 1);
2631 //dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
2632
2633 factor = 1;
2634
2635 //set lock_mask values
2636 dib8000_write_word(state, 6, 0x4);
2637 dib8000_write_word(state, 7, 0x8);
2638 dib8000_write_word(state, 8, 0x1000);
2639
2640 //set lock_mask wait time values
2641 value = 50 * state->cfg.pll->internal * factor;
2642 dib8000_write_word(state, 11, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
2643 dib8000_write_word(state, 12, (u16) (value & 0xffff)); // lock0 wait time
2644 value = 100 * state->cfg.pll->internal * factor;
2645 dib8000_write_word(state, 13, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
2646 dib8000_write_word(state, 14, (u16) (value & 0xffff)); // lock1 wait time
2647 value = 1000 * state->cfg.pll->internal * factor;
2648 dib8000_write_word(state, 15, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
2649 dib8000_write_word(state, 16, (u16) (value & 0xffff)); // lock2 wait time
2650
2651 value = dib8000_read_word(state, 0);
2652 dib8000_write_word(state, 0, (u16) ((1 << 15) | value));
2653 dib8000_read_word(state, 1284); // reset the INT. n_irq_pending
2654 dib8000_write_word(state, 0, (u16) value);
2655
2656 }
2657
2658 return 0;
2659}
2660
2661static int dib8000_autosearch_irq(struct dvb_frontend *fe)
2662{
2663 struct dib8000_state *state = fe->demodulator_priv;
2664 u16 irq_pending = dib8000_read_word(state, 1284);
2665
2666 if (irq_pending & 0x1) { // failed
2667 dprintk("dib8000_autosearch_irq failed");
2668 return 1;
2669 }
2670
2671 if (irq_pending & 0x2) { // succeeded
2672 dprintk("dib8000_autosearch_irq succeeded");
2673 return 2;
2674 }
2675
2676 return 0; // still pending
2677}
2678
2679static int dib8000_tune(struct dvb_frontend *fe)
2680{
2681 struct dib8000_state *state = fe->demodulator_priv;
2682 int ret = 0;
2683 u16 lock, value, mode;
2684
2685 // we are already tuned - just resuming from suspend
2686 if (state == NULL)
2687 return -EINVAL;
2688
2689 mode = fft_to_mode(state);
2690
2691 dib8000_set_bandwidth(fe, state->fe[0]->dtv_property_cache.bandwidth_hz / 1000);
2692 dib8000_set_channel(state, 0, 0);
2693
2694 // restart demod
2695 ret |= dib8000_write_word(state, 770, 0x4000);
2696 ret |= dib8000_write_word(state, 770, 0x0000);
2697 msleep(45);
2698
2699 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3 */
2700 /* ret |= dib8000_write_word(state, 29, (0 << 9) | (4 << 5) | (0 << 4) | (3 << 0) ); workaround inh_isi stays at 1 */
2701
2702 // never achieved a lock before - wait for timfreq to update
2703 if (state->timf == 0) {
2704 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
2705 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
2706 msleep(300);
2707 else // Sound Broadcasting mode 3 seg
2708 msleep(500);
2709 } else // 13 seg
2710 msleep(200);
2711 }
2712 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
2713 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
2714
2715 /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */
2716 dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40);
2717 //dib8000_write_word(state, 32, (8 << 12) | (6 << 8) | 0x80);
2718
2719 /* P_ctrl_sfreq_step= (12-P_mode) P_ctrl_sfreq_inh =0 P_ctrl_pha_off_max */
2720 ret |= dib8000_write_word(state, 37, (12 - mode) | ((5 + mode) << 5));
2721
2722 } else { // Sound Broadcasting mode 3 seg
2723
2724 /* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60 alpha to check on board */
2725 dib8000_write_word(state, 32, ((12 - mode) << 12) | (6 << 8) | 0x60);
2726
2727 ret |= dib8000_write_word(state, 37, (11 - mode) | ((5 + mode) << 5));
2728 }
2729
2730 } else { // 13 seg
2731 /* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80 alpha to check on board */
2732 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x80);
2733
2734 ret |= dib8000_write_word(state, 37, (10 - mode) | ((5 + mode) << 5));
2735
2736 }
2737
2738 // we achieved a coff_cpil_lock - it's time to update the timf
2739 if (state->revision != 0x8090)
2740 lock = dib8000_read_word(state, 568);
2741 else
2742 lock = dib8000_read_word(state, 570);
2743 if ((lock >> 11) & 0x1)
2744 dib8000_update_timf(state);
2745
2746 //now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start
2747 dib8000_write_word(state, 6, 0x200);
2748
2749 if (state->revision == 0x8002) {
2750 value = dib8000_read_word(state, 903);
2751 dib8000_write_word(state, 903, value & ~(1 << 3));
2752 msleep(1);
2753 dib8000_write_word(state, 903, value | (1 << 3));
2754 }
2755
2756 return ret;
2757}
2758
2759static int dib8000_wakeup(struct dvb_frontend *fe)
2760{
2761 struct dib8000_state *state = fe->demodulator_priv;
2762 u8 index_frontend;
2763 int ret;
2764
2765 dib8000_set_power_mode(state, DIB8000_POWER_ALL);
2766 dib8000_set_adc_state(state, DIBX000_ADC_ON);
2767 if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
2768 dprintk("could not start Slow ADC");
2769
2770 if (state->revision != 0x8090)
2771 dib8000_sad_calib(state);
2772
2773 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2774 ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]);
2775 if (ret < 0)
2776 return ret;
2777 }
2778
2779 return 0;
2780}
2781
2782static int dib8000_sleep(struct dvb_frontend *fe)
2783{
2784 struct dib8000_state *state = fe->demodulator_priv;
2785 u8 index_frontend;
2786 int ret;
2787
2788 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2789 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
2790 if (ret < 0)
2791 return ret;
2792 }
2793
2794 if (state->revision != 0x8090)
2795 dib8000_set_output_mode(fe, OUTMODE_HIGH_Z);
2796 dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
2797 return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF);
2798}
2799
2800enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
2801{
2802 struct dib8000_state *state = fe->demodulator_priv;
2803 return state->tune_state;
2804}
2805EXPORT_SYMBOL(dib8000_get_tune_state);
2806
2807int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
2808{
2809 struct dib8000_state *state = fe->demodulator_priv;
2810 state->tune_state = tune_state;
2811 return 0;
2812}
2813EXPORT_SYMBOL(dib8000_set_tune_state);
2814
2815static int dib8000_get_frontend(struct dvb_frontend *fe)
2816{
2817 struct dib8000_state *state = fe->demodulator_priv;
2818 u16 i, val = 0;
2819 fe_status_t stat;
2820 u8 index_frontend, sub_index_frontend;
2821
2822 fe->dtv_property_cache.bandwidth_hz = 6000000;
2823
2824 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2825 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
2826 if (stat&FE_HAS_SYNC) {
2827 dprintk("TMCC lock on the slave%i", index_frontend);
2828 /* synchronize the cache with the other frontends */
2829 state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend]);
2830 for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) {
2831 if (sub_index_frontend != index_frontend) {
2832 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
2833 state->fe[sub_index_frontend]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion;
2834 state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode;
2835 state->fe[sub_index_frontend]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval;
2836 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception;
2837 for (i = 0; i < 3; i++) {
2838 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count;
2839 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving;
2840 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec;
2841 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation;
2842 }
2843 }
2844 }
2845 return 0;
2846 }
2847 }
2848
2849 fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
2850
2851 if (state->revision == 0x8090)
2852 val = dib8000_read_word(state, 572);
2853 else
2854 val = dib8000_read_word(state, 570);
2855 fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
2856 switch ((val & 0x30) >> 4) {
2857 case 1:
2858 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
2859 break;
2860 case 3:
2861 default:
2862 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
2863 break;
2864 }
2865
2866 switch (val & 0x3) {
2867 case 0:
2868 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
2869 dprintk("dib8000_get_frontend GI = 1/32 ");
2870 break;
2871 case 1:
2872 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
2873 dprintk("dib8000_get_frontend GI = 1/16 ");
2874 break;
2875 case 2:
2876 dprintk("dib8000_get_frontend GI = 1/8 ");
2877 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
2878 break;
2879 case 3:
2880 dprintk("dib8000_get_frontend GI = 1/4 ");
2881 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
2882 break;
2883 }
2884
2885 val = dib8000_read_word(state, 505);
2886 fe->dtv_property_cache.isdbt_partial_reception = val & 1;
2887 dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
2888
2889 for (i = 0; i < 3; i++) {
2890 val = dib8000_read_word(state, 493 + i);
2891 fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
2892 dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
2893
2894 val = dib8000_read_word(state, 499 + i);
2895 fe->dtv_property_cache.layer[i].interleaving = val & 0x3;
2896 dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving);
2897
2898 val = dib8000_read_word(state, 481 + i);
2899 switch (val & 0x7) {
2900 case 1:
2901 fe->dtv_property_cache.layer[i].fec = FEC_1_2;
2902 dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
2903 break;
2904 case 2:
2905 fe->dtv_property_cache.layer[i].fec = FEC_2_3;
2906 dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
2907 break;
2908 case 3:
2909 fe->dtv_property_cache.layer[i].fec = FEC_3_4;
2910 dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
2911 break;
2912 case 5:
2913 fe->dtv_property_cache.layer[i].fec = FEC_5_6;
2914 dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
2915 break;
2916 default:
2917 fe->dtv_property_cache.layer[i].fec = FEC_7_8;
2918 dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
2919 break;
2920 }
2921
2922 val = dib8000_read_word(state, 487 + i);
2923 switch (val & 0x3) {
2924 case 0:
2925 dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
2926 fe->dtv_property_cache.layer[i].modulation = DQPSK;
2927 break;
2928 case 1:
2929 fe->dtv_property_cache.layer[i].modulation = QPSK;
2930 dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
2931 break;
2932 case 2:
2933 fe->dtv_property_cache.layer[i].modulation = QAM_16;
2934 dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
2935 break;
2936 case 3:
2937 default:
2938 dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
2939 fe->dtv_property_cache.layer[i].modulation = QAM_64;
2940 break;
2941 }
2942 }
2943
2944 /* synchronize the cache with the other frontends */
2945 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2946 state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode = fe->dtv_property_cache.isdbt_sb_mode;
2947 state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion;
2948 state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode;
2949 state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval;
2950 state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception = fe->dtv_property_cache.isdbt_partial_reception;
2951 for (i = 0; i < 3; i++) {
2952 state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count = fe->dtv_property_cache.layer[i].segment_count;
2953 state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving = fe->dtv_property_cache.layer[i].interleaving;
2954 state->fe[index_frontend]->dtv_property_cache.layer[i].fec = fe->dtv_property_cache.layer[i].fec;
2955 state->fe[index_frontend]->dtv_property_cache.layer[i].modulation = fe->dtv_property_cache.layer[i].modulation;
2956 }
2957 }
2958 return 0;
2959}
2960
2961static int dib8000_set_frontend(struct dvb_frontend *fe)
2962{
2963 struct dib8000_state *state = fe->demodulator_priv;
2964 u8 nbr_pending, exit_condition, index_frontend;
2965 s8 index_frontend_success = -1;
2966 int time, ret;
2967 int time_slave = FE_CALLBACK_TIME_NEVER;
2968
2969 if (state->fe[0]->dtv_property_cache.frequency == 0) {
2970 dprintk("dib8000: must at least specify frequency ");
2971 return 0;
2972 }
2973
2974 if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) {
2975 dprintk("dib8000: no bandwidth specified, set to default ");
2976 state->fe[0]->dtv_property_cache.bandwidth_hz = 6000000;
2977 }
2978
2979 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2980 /* synchronization of the cache */
2981 state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT;
2982 memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
2983
2984 if (state->revision != 0x8090)
2985 dib8000_set_output_mode(state->fe[index_frontend],
2986 OUTMODE_HIGH_Z);
2987 else
2988 dib8096p_set_output_mode(state->fe[index_frontend],
2989 OUTMODE_HIGH_Z);
2990 if (state->fe[index_frontend]->ops.tuner_ops.set_params)
2991 state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend]);
2992
2993 dib8000_set_tune_state(state->fe[index_frontend], CT_AGC_START);
2994 }
2995
2996 /* start up the AGC */
2997 do {
2998 time = dib8000_agc_startup(state->fe[0]);
2999 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3000 time_slave = dib8000_agc_startup(state->fe[index_frontend]);
3001 if (time == FE_CALLBACK_TIME_NEVER)
3002 time = time_slave;
3003 else if ((time_slave != FE_CALLBACK_TIME_NEVER) && (time_slave > time))
3004 time = time_slave;
3005 }
3006 if (time != FE_CALLBACK_TIME_NEVER)
3007 msleep(time / 10);
3008 else
3009 break;
3010 exit_condition = 1;
3011 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3012 if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_AGC_STOP) {
3013 exit_condition = 0;
3014 break;
3015 }
3016 }
3017 } while (exit_condition == 0);
3018
3019 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
3020 dib8000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
3021
3022 if ((state->fe[0]->dtv_property_cache.delivery_system != SYS_ISDBT) ||
3023 (state->fe[0]->dtv_property_cache.inversion == INVERSION_AUTO) ||
3024 (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
3025 (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
3026 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
3027 (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0xff) &&
3028 (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0) &&
3029 ((state->fe[0]->dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
3030 (state->fe[0]->dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
3031 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
3032 (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0xff) &&
3033 (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0) &&
3034 ((state->fe[0]->dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
3035 (state->fe[0]->dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
3036 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
3037 (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0xff) &&
3038 (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0) &&
3039 ((state->fe[0]->dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
3040 (state->fe[0]->dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
3041 (((state->fe[0]->dtv_property_cache.layer[0].segment_count == 0) ||
3042 ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
3043 ((state->fe[0]->dtv_property_cache.layer[1].segment_count == 0) ||
3044 ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
3045 ((state->fe[0]->dtv_property_cache.layer[2].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
3046 int i = 100;
3047 u8 found = 0;
3048 u8 tune_failed = 0;
3049
3050 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3051 dib8000_set_bandwidth(state->fe[index_frontend], fe->dtv_property_cache.bandwidth_hz / 1000);
3052 dib8000_autosearch_start(state->fe[index_frontend]);
3053 }
3054
3055 do {
3056 msleep(20);
3057 nbr_pending = 0;
3058 exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */
3059 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3060 if (((tune_failed >> index_frontend) & 0x1) == 0) {
3061 found = dib8000_autosearch_irq(state->fe[index_frontend]);
3062 switch (found) {
3063 case 0: /* tune pending */
3064 nbr_pending++;
3065 break;
3066 case 2:
3067 dprintk("autosearch succeed on the frontend%i", index_frontend);
3068 exit_condition = 2;
3069 index_frontend_success = index_frontend;
3070 break;
3071 default:
3072 dprintk("unhandled autosearch result");
3073 case 1:
3074 tune_failed |= (1 << index_frontend);
3075 dprintk("autosearch failed for the frontend%i", index_frontend);
3076 break;
3077 }
3078 }
3079 }
3080
3081 /* if all tune are done and no success, exit: tune failed */
3082 if ((nbr_pending == 0) && (exit_condition == 0))
3083 exit_condition = 1;
3084 } while ((exit_condition == 0) && i--);
3085
3086 if (exit_condition == 1) { /* tune failed */
3087 dprintk("tune failed");
3088 return 0;
3089 }
3090
3091 dprintk("tune success on frontend%i", index_frontend_success);
3092
3093 dib8000_get_frontend(fe);
3094 }
3095
3096 for (index_frontend = 0, ret = 0; (ret >= 0) && (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
3097 ret = dib8000_tune(state->fe[index_frontend]);
3098
3099 /* set output mode and diversity input */
3100 if (state->revision != 0x8090) {
3101 dib8000_set_output_mode(state->fe[0], state->cfg.output_mode);
3102 for (index_frontend = 1;
3103 (index_frontend < MAX_NUMBER_OF_FRONTENDS) &&
3104 (state->fe[index_frontend] != NULL);
3105 index_frontend++) {
3106 dib8000_set_output_mode(state->fe[index_frontend],
3107 OUTMODE_DIVERSITY);
3108 dib8000_set_diversity_in(state->fe[index_frontend-1], 1);
3109 }
3110
3111 /* turn off the diversity of the last chip */
3112 dib8000_set_diversity_in(state->fe[index_frontend-1], 0);
3113 } else {
3114 dib8096p_set_output_mode(state->fe[0], state->cfg.output_mode);
3115 if (state->cfg.enMpegOutput == 0) {
3116 dib8096p_setDibTxMux(state, MPEG_ON_DIBTX);
3117 dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
3118 }
3119 for (index_frontend = 1;
3120 (index_frontend < MAX_NUMBER_OF_FRONTENDS) &&
3121 (state->fe[index_frontend] != NULL);
3122 index_frontend++) {
3123 dib8096p_set_output_mode(state->fe[index_frontend],
3124 OUTMODE_DIVERSITY);
3125 dib8096p_set_diversity_in(state->fe[index_frontend-1], 1);
3126 }
3127
3128 /* turn off the diversity of the last chip */
3129 dib8096p_set_diversity_in(state->fe[index_frontend-1], 0);
3130 }
3131
3132 return ret;
3133}
3134
3135static u16 dib8000_read_lock(struct dvb_frontend *fe)
3136{
3137 struct dib8000_state *state = fe->demodulator_priv;
3138
3139 if (state->revision == 0x8090)
3140 return dib8000_read_word(state, 570);
3141 return dib8000_read_word(state, 568);
3142}
3143
3144static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
3145{
3146 struct dib8000_state *state = fe->demodulator_priv;
3147 u16 lock_slave = 0, lock;
3148 u8 index_frontend;
3149
3150 if (state->revision == 0x8090)
3151 lock = dib8000_read_word(state, 570);
3152 else
3153 lock = dib8000_read_word(state, 568);
3154
3155 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
3156 lock_slave |= dib8000_read_lock(state->fe[index_frontend]);
3157
3158 *stat = 0;
3159
3160 if (((lock >> 13) & 1) || ((lock_slave >> 13) & 1))
3161 *stat |= FE_HAS_SIGNAL;
3162
3163 if (((lock >> 8) & 1) || ((lock_slave >> 8) & 1)) /* Equal */
3164 *stat |= FE_HAS_CARRIER;
3165
3166 if ((((lock >> 1) & 0xf) == 0xf) || (((lock_slave >> 1) & 0xf) == 0xf)) /* TMCC_SYNC */
3167 *stat |= FE_HAS_SYNC;
3168
3169 if ((((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) && ((lock >> 5) & 7)) /* FEC MPEG */
3170 *stat |= FE_HAS_LOCK;
3171
3172 if (((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) {
3173 lock = dib8000_read_word(state, 554); /* Viterbi Layer A */
3174 if (lock & 0x01)
3175 *stat |= FE_HAS_VITERBI;
3176
3177 lock = dib8000_read_word(state, 555); /* Viterbi Layer B */
3178 if (lock & 0x01)
3179 *stat |= FE_HAS_VITERBI;
3180
3181 lock = dib8000_read_word(state, 556); /* Viterbi Layer C */
3182 if (lock & 0x01)
3183 *stat |= FE_HAS_VITERBI;
3184 }
3185
3186 return 0;
3187}
3188
3189static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
3190{
3191 struct dib8000_state *state = fe->demodulator_priv;
3192
3193 /* 13 segments */
3194 if (state->revision == 0x8090)
3195 *ber = (dib8000_read_word(state, 562) << 16) |
3196 dib8000_read_word(state, 563);
3197 else
3198 *ber = (dib8000_read_word(state, 560) << 16) |
3199 dib8000_read_word(state, 561);
3200 return 0;
3201}
3202
3203static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
3204{
3205 struct dib8000_state *state = fe->demodulator_priv;
3206
3207 /* packet error on 13 seg */
3208 if (state->revision == 0x8090)
3209 *unc = dib8000_read_word(state, 567);
3210 else
3211 *unc = dib8000_read_word(state, 565);
3212 return 0;
3213}
3214
3215static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
3216{
3217 struct dib8000_state *state = fe->demodulator_priv;
3218 u8 index_frontend;
3219 u16 val;
3220
3221 *strength = 0;
3222 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3223 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
3224 if (val > 65535 - *strength)
3225 *strength = 65535;
3226 else
3227 *strength += val;
3228 }
3229
3230 val = 65535 - dib8000_read_word(state, 390);
3231 if (val > 65535 - *strength)
3232 *strength = 65535;
3233 else
3234 *strength += val;
3235 return 0;
3236}
3237
3238static u32 dib8000_get_snr(struct dvb_frontend *fe)
3239{
3240 struct dib8000_state *state = fe->demodulator_priv;
3241 u32 n, s, exp;
3242 u16 val;
3243
3244 if (state->revision != 0x8090)
3245 val = dib8000_read_word(state, 542);
3246 else
3247 val = dib8000_read_word(state, 544);
3248 n = (val >> 6) & 0xff;
3249 exp = (val & 0x3f);
3250 if ((exp & 0x20) != 0)
3251 exp -= 0x40;
3252 n <<= exp+16;
3253
3254 if (state->revision != 0x8090)
3255 val = dib8000_read_word(state, 543);
3256 else
3257 val = dib8000_read_word(state, 545);
3258 s = (val >> 6) & 0xff;
3259 exp = (val & 0x3f);
3260 if ((exp & 0x20) != 0)
3261 exp -= 0x40;
3262 s <<= exp+16;
3263
3264 if (n > 0) {
3265 u32 t = (s/n) << 16;
3266 return t + ((s << 16) - n*t) / n;
3267 }
3268 return 0xffffffff;
3269}
3270
3271static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
3272{
3273 struct dib8000_state *state = fe->demodulator_priv;
3274 u8 index_frontend;
3275 u32 snr_master;
3276
3277 snr_master = dib8000_get_snr(fe);
3278 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
3279 snr_master += dib8000_get_snr(state->fe[index_frontend]);
3280
3281 if ((snr_master >> 16) != 0) {
3282 snr_master = 10*intlog10(snr_master>>16);
3283 *snr = snr_master / ((1 << 24) / 10);
3284 }
3285 else
3286 *snr = 0;
3287
3288 return 0;
3289}
3290
3291int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
3292{
3293 struct dib8000_state *state = fe->demodulator_priv;
3294 u8 index_frontend = 1;
3295
3296 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
3297 index_frontend++;
3298 if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
3299 dprintk("set slave fe %p to index %i", fe_slave, index_frontend);
3300 state->fe[index_frontend] = fe_slave;
3301 return 0;
3302 }
3303
3304 dprintk("too many slave frontend");
3305 return -ENOMEM;
3306}
3307EXPORT_SYMBOL(dib8000_set_slave_frontend);
3308
3309int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
3310{
3311 struct dib8000_state *state = fe->demodulator_priv;
3312 u8 index_frontend = 1;
3313
3314 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
3315 index_frontend++;
3316 if (index_frontend != 1) {
3317 dprintk("remove slave fe %p (index %i)", state->fe[index_frontend-1], index_frontend-1);
3318 state->fe[index_frontend] = NULL;
3319 return 0;
3320 }
3321
3322 dprintk("no frontend to be removed");
3323 return -ENODEV;
3324}
3325EXPORT_SYMBOL(dib8000_remove_slave_frontend);
3326
3327struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
3328{
3329 struct dib8000_state *state = fe->demodulator_priv;
3330
3331 if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
3332 return NULL;
3333 return state->fe[slave_index];
3334}
3335EXPORT_SYMBOL(dib8000_get_slave_frontend);
3336
3337
3338int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods,
3339 u8 default_addr, u8 first_addr, u8 is_dib8096p)
3340{
3341 int k = 0, ret = 0;
3342 u8 new_addr = 0;
3343 struct i2c_device client = {.adap = host };
3344
3345 client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
3346 if (!client.i2c_write_buffer) {
3347 dprintk("%s: not enough memory", __func__);
3348 return -ENOMEM;
3349 }
3350 client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
3351 if (!client.i2c_read_buffer) {
3352 dprintk("%s: not enough memory", __func__);
3353 ret = -ENOMEM;
3354 goto error_memory_read;
3355 }
3356 client.i2c_buffer_lock = kzalloc(sizeof(struct mutex), GFP_KERNEL);
3357 if (!client.i2c_buffer_lock) {
3358 dprintk("%s: not enough memory", __func__);
3359 ret = -ENOMEM;
3360 goto error_memory_lock;
3361 }
3362 mutex_init(client.i2c_buffer_lock);
3363
3364 for (k = no_of_demods - 1; k >= 0; k--) {
3365 /* designated i2c address */
3366 new_addr = first_addr + (k << 1);
3367
3368 client.addr = new_addr;
3369 if (!is_dib8096p)
3370 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
3371 if (dib8000_identify(&client) == 0) {
3372 /* sram lead in, rdy */
3373 if (!is_dib8096p)
3374 dib8000_i2c_write16(&client, 1287, 0x0003);
3375 client.addr = default_addr;
3376 if (dib8000_identify(&client) == 0) {
3377 dprintk("#%d: not identified", k);
3378 ret = -EINVAL;
3379 goto error;
3380 }
3381 }
3382
3383 /* start diversity to pull_down div_str - just for i2c-enumeration */
3384 dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
3385
3386 /* set new i2c address and force divstart */
3387 dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
3388 client.addr = new_addr;
3389 dib8000_identify(&client);
3390
3391 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
3392 }
3393
3394 for (k = 0; k < no_of_demods; k++) {
3395 new_addr = first_addr | (k << 1);
3396 client.addr = new_addr;
3397
3398 // unforce divstr
3399 dib8000_i2c_write16(&client, 1285, new_addr << 2);
3400
3401 /* deactivate div - it was just for i2c-enumeration */
3402 dib8000_i2c_write16(&client, 1286, 0);
3403 }
3404
3405error:
3406 kfree(client.i2c_buffer_lock);
3407error_memory_lock:
3408 kfree(client.i2c_read_buffer);
3409error_memory_read:
3410 kfree(client.i2c_write_buffer);
3411
3412 return ret;
3413}
3414
3415EXPORT_SYMBOL(dib8000_i2c_enumeration);
3416static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
3417{
3418 tune->min_delay_ms = 1000;
3419 tune->step_size = 0;
3420 tune->max_drift = 0;
3421 return 0;
3422}
3423
3424static void dib8000_release(struct dvb_frontend *fe)
3425{
3426 struct dib8000_state *st = fe->demodulator_priv;
3427 u8 index_frontend;
3428
3429 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
3430 dvb_frontend_detach(st->fe[index_frontend]);
3431
3432 dibx000_exit_i2c_master(&st->i2c_master);
3433 i2c_del_adapter(&st->dib8096p_tuner_adap);
3434 kfree(st->fe[0]);
3435 kfree(st);
3436}
3437
3438struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
3439{
3440 struct dib8000_state *st = fe->demodulator_priv;
3441 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
3442}
3443
3444EXPORT_SYMBOL(dib8000_get_i2c_master);
3445
3446int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
3447{
3448 struct dib8000_state *st = fe->demodulator_priv;
3449 u16 val = dib8000_read_word(st, 299) & 0xffef;
3450 val |= (onoff & 0x1) << 4;
3451
3452 dprintk("pid filter enabled %d", onoff);
3453 return dib8000_write_word(st, 299, val);
3454}
3455EXPORT_SYMBOL(dib8000_pid_filter_ctrl);
3456
3457int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
3458{
3459 struct dib8000_state *st = fe->demodulator_priv;
3460 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
3461 return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
3462}
3463EXPORT_SYMBOL(dib8000_pid_filter);
3464
3465static const struct dvb_frontend_ops dib8000_ops = {
3466 .delsys = { SYS_ISDBT },
3467 .info = {
3468 .name = "DiBcom 8000 ISDB-T",
3469 .frequency_min = 44250000,
3470 .frequency_max = 867250000,
3471 .frequency_stepsize = 62500,
3472 .caps = FE_CAN_INVERSION_AUTO |
3473 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
3474 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
3475 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
3476 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
3477 },
3478
3479 .release = dib8000_release,
3480
3481 .init = dib8000_wakeup,
3482 .sleep = dib8000_sleep,
3483
3484 .set_frontend = dib8000_set_frontend,
3485 .get_tune_settings = dib8000_fe_get_tune_settings,
3486 .get_frontend = dib8000_get_frontend,
3487
3488 .read_status = dib8000_read_status,
3489 .read_ber = dib8000_read_ber,
3490 .read_signal_strength = dib8000_read_signal_strength,
3491 .read_snr = dib8000_read_snr,
3492 .read_ucblocks = dib8000_read_unc_blocks,
3493};
3494
3495struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
3496{
3497 struct dvb_frontend *fe;
3498 struct dib8000_state *state;
3499
3500 dprintk("dib8000_attach");
3501
3502 state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
3503 if (state == NULL)
3504 return NULL;
3505 fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
3506 if (fe == NULL)
3507 goto error;
3508
3509 memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
3510 state->i2c.adap = i2c_adap;
3511 state->i2c.addr = i2c_addr;
3512 state->i2c.i2c_write_buffer = state->i2c_write_buffer;
3513 state->i2c.i2c_read_buffer = state->i2c_read_buffer;
3514 mutex_init(&state->i2c_buffer_lock);
3515 state->i2c.i2c_buffer_lock = &state->i2c_buffer_lock;
3516 state->gpio_val = cfg->gpio_val;
3517 state->gpio_dir = cfg->gpio_dir;
3518
3519 /* Ensure the output mode remains at the previous default if it's
3520 * not specifically set by the caller.
3521 */
3522 if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
3523 state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
3524
3525 state->fe[0] = fe;
3526 fe->demodulator_priv = state;
3527 memcpy(&state->fe[0]->ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
3528
3529 state->timf_default = cfg->pll->timf;
3530
3531 if (dib8000_identify(&state->i2c) == 0)
3532 goto error;
3533
3534 dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
3535
3536 /* init 8096p tuner adapter */
3537 strncpy(state->dib8096p_tuner_adap.name, "DiB8096P tuner interface",
3538 sizeof(state->dib8096p_tuner_adap.name));
3539 state->dib8096p_tuner_adap.algo = &dib8096p_tuner_xfer_algo;
3540 state->dib8096p_tuner_adap.algo_data = NULL;
3541 state->dib8096p_tuner_adap.dev.parent = state->i2c.adap->dev.parent;
3542 i2c_set_adapdata(&state->dib8096p_tuner_adap, state);
3543 i2c_add_adapter(&state->dib8096p_tuner_adap);
3544
3545 dib8000_reset(fe);
3546
3547 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */
3548
3549 return fe;
3550
3551 error:
3552 kfree(state);
3553 return NULL;
3554}
3555
3556EXPORT_SYMBOL(dib8000_attach);
3557
3558MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
3559MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
3560MODULE_LICENSE("GPL");