[media] dib8000: In auto-search, try first with partial reception enabled
[deliverable/linux.git] / drivers / media / dvb-frontends / dib8000.c
CommitLineData
77e2c0f5
PB
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>
5a0e3ad6 11#include <linux/slab.h>
77e2c0f5 12#include <linux/i2c.h>
79fcce32 13#include <linux/mutex.h>
b4600d70 14#include <asm/div64.h>
79fcce32 15
77e2c0f5
PB
16#include "dvb_math.h"
17
18#include "dvb_frontend.h"
19
20#include "dib8000.h"
21
22#define LAYER_ALL -1
23#define LAYER_A 1
24#define LAYER_B 2
25#define LAYER_C 3
26
4c70e074 27#define MAX_NUMBER_OF_FRONTENDS 6
173a64cb 28/* #define DIB8000_AGC_FREEZE */
77e2c0f5 29
78f3bc63 30static int debug;
77e2c0f5
PB
31module_param(debug, int, 0644);
32MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
33
34#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
35
77e2c0f5
PB
36struct i2c_device {
37 struct i2c_adapter *adap;
38 u8 addr;
5a0deeed
OG
39 u8 *i2c_write_buffer;
40 u8 *i2c_read_buffer;
79fcce32 41 struct mutex *i2c_buffer_lock;
77e2c0f5
PB
42};
43
173a64cb
PB
44enum param_loop_step {
45 LOOP_TUNE_1,
46 LOOP_TUNE_2
47};
48
49enum dib8000_autosearch_step {
50 AS_START = 0,
51 AS_SEARCHING_FFT,
52 AS_SEARCHING_GUARD,
53 AS_DONE = 100,
54};
55
56enum timeout_mode {
57 SYMBOL_DEPENDENT_OFF = 0,
58 SYMBOL_DEPENDENT_ON,
59};
60
77e2c0f5 61struct dib8000_state {
77e2c0f5
PB
62 struct dib8000_config cfg;
63
64 struct i2c_device i2c;
65
66 struct dibx000_i2c_master i2c_master;
67
68 u16 wbd_ref;
69
70 u8 current_band;
71 u32 current_bandwidth;
72 struct dibx000_agc_config *current_agc;
73 u32 timf;
74 u32 timf_default;
75
76 u8 div_force_off:1;
77 u8 div_state:1;
78 u16 div_sync_wait;
79
80 u8 agc_state;
81 u8 differential_constellation;
82 u8 diversity_onoff;
83
84 s16 ber_monitored_layer;
85 u16 gpio_dir;
86 u16 gpio_val;
87
88 u16 revision;
89 u8 isdbt_cfg_loaded;
90 enum frontend_tune_state tune_state;
173a64cb 91 s32 status;
4c70e074
OG
92
93 struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
5a0deeed
OG
94
95 /* for the I2C transfer */
96 struct i2c_msg msg[2];
97 u8 i2c_write_buffer[4];
98 u8 i2c_read_buffer[2];
79fcce32 99 struct mutex i2c_buffer_lock;
0c32dbd7
OG
100 u8 input_mode_mpeg;
101
102 u16 tuner_enable;
103 struct i2c_adapter dib8096p_tuner_adap;
173a64cb
PB
104 u16 current_demod_bw;
105
106 u16 seg_mask;
107 u16 seg_diff_mask;
108 u16 mode;
109 u8 layer_b_nb_seg;
110 u8 layer_c_nb_seg;
111
112 u8 channel_parameters_set;
113 u16 autosearch_state;
114 u16 found_nfft;
115 u16 found_guard;
116 u8 subchannel;
117 u8 symbol_duration;
118 u32 timeout;
119 u8 longest_intlv_layer;
120 u16 output_mode;
121
704f01bb 122 /* for DVBv5 stats */
7a9d85d5 123 s64 init_ucb;
0400c535
MCC
124 unsigned long per_jiffies_stats;
125 unsigned long ber_jiffies_stats;
126 unsigned long ber_jiffies_stats_layer[3];
704f01bb 127
173a64cb
PB
128#ifdef DIB8000_AGC_FREEZE
129 u16 agc1_max;
130 u16 agc1_min;
131 u16 agc2_max;
132 u16 agc2_min;
133#endif
77e2c0f5
PB
134};
135
136enum dib8000_power_mode {
0c32dbd7
OG
137 DIB8000_POWER_ALL = 0,
138 DIB8000_POWER_INTERFACE_ONLY,
77e2c0f5
PB
139};
140
141static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
142{
79fcce32 143 u16 ret;
77e2c0f5 144 struct i2c_msg msg[2] = {
79fcce32
PB
145 {.addr = i2c->addr >> 1, .flags = 0, .len = 2},
146 {.addr = i2c->addr >> 1, .flags = I2C_M_RD, .len = 2},
77e2c0f5
PB
147 };
148
79fcce32
PB
149 if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
150 dprintk("could not acquire lock");
151 return 0;
152 }
153
154 msg[0].buf = i2c->i2c_write_buffer;
5a0deeed
OG
155 msg[0].buf[0] = reg >> 8;
156 msg[0].buf[1] = reg & 0xff;
79fcce32 157 msg[1].buf = i2c->i2c_read_buffer;
5a0deeed 158
77e2c0f5
PB
159 if (i2c_transfer(i2c->adap, msg, 2) != 2)
160 dprintk("i2c read error on %d", reg);
161
79fcce32
PB
162 ret = (msg[1].buf[0] << 8) | msg[1].buf[1];
163 mutex_unlock(i2c->i2c_buffer_lock);
164 return ret;
77e2c0f5
PB
165}
166
5ac64ba1 167static u16 __dib8000_read_word(struct dib8000_state *state, u16 reg)
77e2c0f5 168{
79fcce32
PB
169 u16 ret;
170
5a0deeed
OG
171 state->i2c_write_buffer[0] = reg >> 8;
172 state->i2c_write_buffer[1] = reg & 0xff;
173
174 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
175 state->msg[0].addr = state->i2c.addr >> 1;
176 state->msg[0].flags = 0;
177 state->msg[0].buf = state->i2c_write_buffer;
178 state->msg[0].len = 2;
179 state->msg[1].addr = state->i2c.addr >> 1;
180 state->msg[1].flags = I2C_M_RD;
181 state->msg[1].buf = state->i2c_read_buffer;
182 state->msg[1].len = 2;
183
184 if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2)
185 dprintk("i2c read error on %d", reg);
186
79fcce32 187 ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
5ac64ba1
MCC
188
189 return ret;
190}
191
192static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
193{
194 u16 ret;
195
196 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
197 dprintk("could not acquire lock");
198 return 0;
199 }
200
201 ret = __dib8000_read_word(state, reg);
202
79fcce32
PB
203 mutex_unlock(&state->i2c_buffer_lock);
204
205 return ret;
77e2c0f5
PB
206}
207
208static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
209{
210 u16 rw[2];
211
5ac64ba1
MCC
212 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
213 dprintk("could not acquire lock");
214 return 0;
215 }
216
217 rw[0] = __dib8000_read_word(state, reg + 0);
218 rw[1] = __dib8000_read_word(state, reg + 1);
219
220 mutex_unlock(&state->i2c_buffer_lock);
77e2c0f5
PB
221
222 return ((rw[0] << 16) | (rw[1]));
223}
224
225static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
226{
79fcce32 227 struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0, .len = 4};
5a0deeed
OG
228 int ret = 0;
229
79fcce32
PB
230 if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
231 dprintk("could not acquire lock");
232 return -EINVAL;
233 }
234
235 msg.buf = i2c->i2c_write_buffer;
5a0deeed
OG
236 msg.buf[0] = (reg >> 8) & 0xff;
237 msg.buf[1] = reg & 0xff;
238 msg.buf[2] = (val >> 8) & 0xff;
239 msg.buf[3] = val & 0xff;
240
241 ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
79fcce32 242 mutex_unlock(i2c->i2c_buffer_lock);
5a0deeed
OG
243
244 return ret;
77e2c0f5
PB
245}
246
247static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
248{
79fcce32
PB
249 int ret;
250
251 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
252 dprintk("could not acquire lock");
253 return -EINVAL;
254 }
255
5a0deeed
OG
256 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
257 state->i2c_write_buffer[1] = reg & 0xff;
258 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
259 state->i2c_write_buffer[3] = val & 0xff;
260
261 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
262 state->msg[0].addr = state->i2c.addr >> 1;
263 state->msg[0].flags = 0;
264 state->msg[0].buf = state->i2c_write_buffer;
265 state->msg[0].len = 4;
266
79fcce32
PB
267 ret = (i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ?
268 -EREMOTEIO : 0);
269 mutex_unlock(&state->i2c_buffer_lock);
270
271 return ret;
77e2c0f5
PB
272}
273
4c70e074 274static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
77e2c0f5 275 (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
4c70e074 276 (920 << 5) | 0x09
77e2c0f5
PB
277};
278
4c70e074 279static const s16 coeff_2k_sb_1seg[8] = {
77e2c0f5
PB
280 (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
281};
282
4c70e074 283static const s16 coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
77e2c0f5 284 (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
4c70e074 285 (-931 << 5) | 0x0f
77e2c0f5
PB
286};
287
4c70e074 288static const s16 coeff_2k_sb_3seg_0dqpsk[8] = {
77e2c0f5 289 (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
4c70e074 290 (982 << 5) | 0x0c
77e2c0f5
PB
291};
292
4c70e074 293static const s16 coeff_2k_sb_3seg_1dqpsk[8] = {
77e2c0f5 294 (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
4c70e074 295 (-720 << 5) | 0x0d
77e2c0f5
PB
296};
297
4c70e074 298static const s16 coeff_2k_sb_3seg[8] = {
77e2c0f5 299 (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
4c70e074 300 (-610 << 5) | 0x0a
77e2c0f5
PB
301};
302
4c70e074 303static const s16 coeff_4k_sb_1seg_dqpsk[8] = {
77e2c0f5 304 (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
4c70e074 305 (-922 << 5) | 0x0d
77e2c0f5
PB
306};
307
4c70e074 308static const s16 coeff_4k_sb_1seg[8] = {
77e2c0f5 309 (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
4c70e074 310 (-655 << 5) | 0x0a
77e2c0f5
PB
311};
312
4c70e074 313static const s16 coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
77e2c0f5 314 (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
4c70e074 315 (-958 << 5) | 0x13
77e2c0f5
PB
316};
317
4c70e074 318static const s16 coeff_4k_sb_3seg_0dqpsk[8] = {
77e2c0f5 319 (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
4c70e074 320 (-568 << 5) | 0x0f
77e2c0f5
PB
321};
322
4c70e074 323static const s16 coeff_4k_sb_3seg_1dqpsk[8] = {
77e2c0f5 324 (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
4c70e074 325 (-848 << 5) | 0x13
77e2c0f5
PB
326};
327
4c70e074 328static const s16 coeff_4k_sb_3seg[8] = {
77e2c0f5 329 (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
4c70e074 330 (-869 << 5) | 0x13
77e2c0f5
PB
331};
332
4c70e074 333static const s16 coeff_8k_sb_1seg_dqpsk[8] = {
77e2c0f5 334 (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
4c70e074 335 (-598 << 5) | 0x10
77e2c0f5
PB
336};
337
4c70e074 338static const s16 coeff_8k_sb_1seg[8] = {
77e2c0f5 339 (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
4c70e074 340 (585 << 5) | 0x0f
77e2c0f5
PB
341};
342
4c70e074 343static const s16 coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
77e2c0f5 344 (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
4c70e074 345 (0 << 5) | 0x14
77e2c0f5
PB
346};
347
4c70e074 348static const s16 coeff_8k_sb_3seg_0dqpsk[8] = {
77e2c0f5 349 (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
4c70e074 350 (-877 << 5) | 0x15
77e2c0f5
PB
351};
352
4c70e074 353static const s16 coeff_8k_sb_3seg_1dqpsk[8] = {
77e2c0f5 354 (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
4c70e074 355 (-921 << 5) | 0x14
77e2c0f5
PB
356};
357
4c70e074 358static const s16 coeff_8k_sb_3seg[8] = {
77e2c0f5 359 (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
4c70e074 360 (690 << 5) | 0x14
77e2c0f5
PB
361};
362
4c70e074 363static const s16 ana_fe_coeff_3seg[24] = {
77e2c0f5
PB
364 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
365};
366
4c70e074 367static const s16 ana_fe_coeff_1seg[24] = {
77e2c0f5
PB
368 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
369};
370
4c70e074 371static const s16 ana_fe_coeff_13seg[24] = {
77e2c0f5
PB
372 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
373};
374
375static u16 fft_to_mode(struct dib8000_state *state)
376{
377 u16 mode;
4c70e074 378 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
77e2c0f5
PB
379 case TRANSMISSION_MODE_2K:
380 mode = 1;
381 break;
382 case TRANSMISSION_MODE_4K:
383 mode = 2;
384 break;
385 default:
386 case TRANSMISSION_MODE_AUTO:
387 case TRANSMISSION_MODE_8K:
388 mode = 3;
389 break;
390 }
391 return mode;
392}
393
394static void dib8000_set_acquisition_mode(struct dib8000_state *state)
395{
396 u16 nud = dib8000_read_word(state, 298);
397 nud |= (1 << 3) | (1 << 0);
398 dprintk("acquisition mode activated");
399 dib8000_write_word(state, 298, nud);
400}
4c70e074 401static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode)
77e2c0f5 402{
4c70e074 403 struct dib8000_state *state = fe->demodulator_priv;
77e2c0f5
PB
404 u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */
405
173a64cb 406 state->output_mode = mode;
77e2c0f5
PB
407 outreg = 0;
408 fifo_threshold = 1792;
409 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
410
b4d6046e
OG
411 dprintk("-I- Setting output mode for demod %p to %d",
412 &state->fe[0], mode);
77e2c0f5
PB
413
414 switch (mode) {
415 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
416 outreg = (1 << 10); /* 0x0400 */
417 break;
418 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
419 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
420 break;
421 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
422 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
423 break;
424 case OUTMODE_DIVERSITY:
425 if (state->cfg.hostbus_diversity) {
426 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
427 sram &= 0xfdff;
428 } else
429 sram |= 0x0c00;
430 break;
431 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
432 smo_mode |= (3 << 1);
433 fifo_threshold = 512;
434 outreg = (1 << 10) | (5 << 6);
435 break;
436 case OUTMODE_HIGH_Z: // disable
437 outreg = 0;
438 break;
439
440 case OUTMODE_ANALOG_ADC:
441 outreg = (1 << 10) | (3 << 6);
442 dib8000_set_acquisition_mode(state);
443 break;
444
445 default:
b4d6046e
OG
446 dprintk("Unhandled output_mode passed to be set for demod %p",
447 &state->fe[0]);
77e2c0f5
PB
448 return -EINVAL;
449 }
450
451 if (state->cfg.output_mpeg2_in_188_bytes)
452 smo_mode |= (1 << 5);
453
454 dib8000_write_word(state, 299, smo_mode);
455 dib8000_write_word(state, 300, fifo_threshold); /* synchronous fread */
456 dib8000_write_word(state, 1286, outreg);
457 dib8000_write_word(state, 1291, sram);
458
459 return 0;
460}
461
462static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
463{
464 struct dib8000_state *state = fe->demodulator_priv;
173a64cb 465 u16 tmp, sync_wait = dib8000_read_word(state, 273) & 0xfff0;
77e2c0f5 466
173a64cb 467 dprintk("set diversity input to %i", onoff);
77e2c0f5
PB
468 if (!state->differential_constellation) {
469 dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1
470 dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2); // sync_enable = 1; comb_mode = 2
471 } else {
472 dib8000_write_word(state, 272, 0); //dvsy_off_lmod4 = 0
473 dib8000_write_word(state, 273, sync_wait); // sync_enable = 0; comb_mode = 0
474 }
475 state->diversity_onoff = onoff;
476
477 switch (onoff) {
478 case 0: /* only use the internal way - not the diversity input */
479 dib8000_write_word(state, 270, 1);
480 dib8000_write_word(state, 271, 0);
481 break;
482 case 1: /* both ways */
483 dib8000_write_word(state, 270, 6);
484 dib8000_write_word(state, 271, 6);
485 break;
486 case 2: /* only the diversity input */
487 dib8000_write_word(state, 270, 0);
488 dib8000_write_word(state, 271, 1);
489 break;
490 }
173a64cb
PB
491
492 if (state->revision == 0x8002) {
493 tmp = dib8000_read_word(state, 903);
494 dib8000_write_word(state, 903, tmp & ~(1 << 3));
495 msleep(30);
496 dib8000_write_word(state, 903, tmp | (1 << 3));
497 }
77e2c0f5
PB
498 return 0;
499}
500
501static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
502{
503 /* by default everything is going to be powered off */
504 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
b4d6046e 505 reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3,
0c32dbd7
OG
506 reg_1280;
507
508 if (state->revision != 0x8090)
b4d6046e 509 reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
0c32dbd7
OG
510 else
511 reg_1280 = (dib8000_read_word(state, 1280) & 0x707f) | 0x8f80;
77e2c0f5
PB
512
513 /* now, depending on the requested mode, we power on */
514 switch (mode) {
515 /* power up everything in the demod */
0c32dbd7 516 case DIB8000_POWER_ALL:
77e2c0f5
PB
517 reg_774 = 0x0000;
518 reg_775 = 0x0000;
519 reg_776 = 0x0000;
520 reg_900 &= 0xfffc;
0c32dbd7
OG
521 if (state->revision != 0x8090)
522 reg_1280 &= 0x00ff;
523 else
524 reg_1280 &= 0x707f;
77e2c0f5 525 break;
0c32dbd7
OG
526 case DIB8000_POWER_INTERFACE_ONLY:
527 if (state->revision != 0x8090)
528 reg_1280 &= 0x00ff;
529 else
530 reg_1280 &= 0xfa7b;
77e2c0f5
PB
531 break;
532 }
533
534 dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
535 dib8000_write_word(state, 774, reg_774);
536 dib8000_write_word(state, 775, reg_775);
537 dib8000_write_word(state, 776, reg_776);
538 dib8000_write_word(state, 900, reg_900);
539 dib8000_write_word(state, 1280, reg_1280);
540}
541
542static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
543{
544 int ret = 0;
0c32dbd7
OG
545 u16 reg, reg_907 = dib8000_read_word(state, 907);
546 u16 reg_908 = dib8000_read_word(state, 908);
77e2c0f5
PB
547
548 switch (no) {
549 case DIBX000_SLOW_ADC_ON:
0c32dbd7
OG
550 if (state->revision != 0x8090) {
551 reg_908 |= (1 << 1) | (1 << 0);
552 ret |= dib8000_write_word(state, 908, reg_908);
553 reg_908 &= ~(1 << 1);
554 } else {
555 reg = dib8000_read_word(state, 1925);
556 /* en_slowAdc = 1 & reset_sladc = 1 */
557 dib8000_write_word(state, 1925, reg |
558 (1<<4) | (1<<2));
559
560 /* read acces to make it works... strange ... */
561 reg = dib8000_read_word(state, 1925);
562 msleep(20);
563 /* en_slowAdc = 1 & reset_sladc = 0 */
564 dib8000_write_word(state, 1925, reg & ~(1<<4));
565
566 reg = dib8000_read_word(state, 921) & ~((0x3 << 14)
567 | (0x3 << 12));
568 /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ;
569 (Vin2 = Vcm) */
570 dib8000_write_word(state, 921, reg | (1 << 14)
571 | (3 << 12));
572 }
77e2c0f5
PB
573 break;
574
575 case DIBX000_SLOW_ADC_OFF:
0c32dbd7
OG
576 if (state->revision == 0x8090) {
577 reg = dib8000_read_word(state, 1925);
578 /* reset_sladc = 1 en_slowAdc = 0 */
579 dib8000_write_word(state, 1925,
580 (reg & ~(1<<2)) | (1<<4));
581 }
77e2c0f5
PB
582 reg_908 |= (1 << 1) | (1 << 0);
583 break;
584
585 case DIBX000_ADC_ON:
586 reg_907 &= 0x0fff;
587 reg_908 &= 0x0003;
588 break;
589
590 case DIBX000_ADC_OFF: // leave the VBG voltage on
c063c7c6
MCC
591 reg_907 = (1 << 13) | (1 << 12);
592 reg_908 = (1 << 6) | (1 << 5) | (1 << 4) | (1 << 3) | (1 << 1);
77e2c0f5
PB
593 break;
594
595 case DIBX000_VBG_ENABLE:
596 reg_907 &= ~(1 << 15);
597 break;
598
599 case DIBX000_VBG_DISABLE:
600 reg_907 |= (1 << 15);
601 break;
602
603 default:
604 break;
605 }
606
607 ret |= dib8000_write_word(state, 907, reg_907);
608 ret |= dib8000_write_word(state, 908, reg_908);
609
610 return ret;
611}
612
4c70e074 613static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw)
77e2c0f5 614{
4c70e074 615 struct dib8000_state *state = fe->demodulator_priv;
77e2c0f5
PB
616 u32 timf;
617
618 if (bw == 0)
619 bw = 6000;
620
621 if (state->timf == 0) {
622 dprintk("using default timf");
623 timf = state->timf_default;
624 } else {
625 dprintk("using updated timf");
626 timf = state->timf;
627 }
628
629 dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
630 dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
631
632 return 0;
633}
634
635static int dib8000_sad_calib(struct dib8000_state *state)
636{
173a64cb
PB
637 u8 sad_sel = 3;
638
0c32dbd7 639 if (state->revision == 0x8090) {
173a64cb
PB
640 dib8000_write_word(state, 922, (sad_sel << 2));
641 dib8000_write_word(state, 923, 2048);
642
643 dib8000_write_word(state, 922, (sad_sel << 2) | 0x1);
644 dib8000_write_word(state, 922, (sad_sel << 2));
645 } else {
646 /* internal */
647 dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
648 dib8000_write_word(state, 924, 776);
77e2c0f5 649
173a64cb
PB
650 /* do the calibration */
651 dib8000_write_word(state, 923, (1 << 0));
652 dib8000_write_word(state, 923, (0 << 0));
653 }
77e2c0f5
PB
654
655 msleep(1);
656 return 0;
657}
658
d44913c1 659static int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
77e2c0f5
PB
660{
661 struct dib8000_state *state = fe->demodulator_priv;
662 if (value > 4095)
663 value = 4095;
664 state->wbd_ref = value;
665 return dib8000_write_word(state, 106, value);
666}
173a64cb 667
77e2c0f5
PB
668static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
669{
670 dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
0c32dbd7
OG
671 if (state->revision != 0x8090) {
672 dib8000_write_word(state, 23,
673 (u16) (((bw->internal * 1000) >> 16) & 0xffff));
674 dib8000_write_word(state, 24,
675 (u16) ((bw->internal * 1000) & 0xffff));
676 } else {
677 dib8000_write_word(state, 23, (u16) (((bw->internal / 2 * 1000) >> 16) & 0xffff));
678 dib8000_write_word(state, 24,
679 (u16) ((bw->internal / 2 * 1000) & 0xffff));
680 }
77e2c0f5
PB
681 dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
682 dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
683 dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
684
0c32dbd7
OG
685 if (state->revision != 0x8090)
686 dib8000_write_word(state, 922, bw->sad_cfg);
77e2c0f5
PB
687}
688
689static void dib8000_reset_pll(struct dib8000_state *state)
690{
691 const struct dibx000_bandwidth_config *pll = state->cfg.pll;
0c32dbd7
OG
692 u16 clk_cfg1, reg;
693
694 if (state->revision != 0x8090) {
695 dib8000_write_word(state, 901,
696 (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
697
698 clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
699 (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) |
700 (1 << 3) | (pll->pll_range << 1) |
701 (pll->pll_reset << 0);
702
703 dib8000_write_word(state, 902, clk_cfg1);
704 clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
705 dib8000_write_word(state, 902, clk_cfg1);
706
707 dprintk("clk_cfg1: 0x%04x", clk_cfg1);
708
709 /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
710 if (state->cfg.pll->ADClkSrc == 0)
711 dib8000_write_word(state, 904,
712 (0 << 15) | (0 << 12) | (0 << 10) |
713 (pll->modulo << 8) |
714 (pll->ADClkSrc << 7) | (0 << 1));
715 else if (state->cfg.refclksel != 0)
716 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
717 ((state->cfg.refclksel & 0x3) << 10) |
718 (pll->modulo << 8) |
719 (pll->ADClkSrc << 7) | (0 << 1));
720 else
721 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
722 (3 << 10) | (pll->modulo << 8) |
723 (pll->ADClkSrc << 7) | (0 << 1));
724 } else {
725 dib8000_write_word(state, 1856, (!pll->pll_reset<<13) |
726 (pll->pll_range<<12) | (pll->pll_ratio<<6) |
727 (pll->pll_prediv));
728
729 reg = dib8000_read_word(state, 1857);
730 dib8000_write_word(state, 1857, reg|(!pll->pll_bypass<<15));
731
732 reg = dib8000_read_word(state, 1858); /* Force clk out pll /2 */
733 dib8000_write_word(state, 1858, reg | 1);
734
735 dib8000_write_word(state, 904, (pll->modulo << 8));
736 }
77e2c0f5
PB
737
738 dib8000_reset_pll_common(state, pll);
739}
740
d44913c1 741static int dib8000_update_pll(struct dvb_frontend *fe,
173a64cb 742 struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio)
0c32dbd7
OG
743{
744 struct dib8000_state *state = fe->demodulator_priv;
745 u16 reg_1857, reg_1856 = dib8000_read_word(state, 1856);
173a64cb 746 u8 loopdiv, prediv, oldprediv = state->cfg.pll->pll_prediv ;
0c32dbd7
OG
747 u32 internal, xtal;
748
749 /* get back old values */
750 prediv = reg_1856 & 0x3f;
751 loopdiv = (reg_1856 >> 6) & 0x3f;
752
173a64cb
PB
753 if ((pll == NULL) || (pll->pll_prediv == prediv &&
754 pll->pll_ratio == loopdiv))
755 return -EINVAL;
756
757 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, pll->pll_prediv, loopdiv, pll->pll_ratio);
758 if (state->revision == 0x8090) {
0c32dbd7
OG
759 reg_1856 &= 0xf000;
760 reg_1857 = dib8000_read_word(state, 1857);
761 /* disable PLL */
762 dib8000_write_word(state, 1857, reg_1857 & ~(1 << 15));
763
764 dib8000_write_word(state, 1856, reg_1856 |
765 ((pll->pll_ratio & 0x3f) << 6) |
766 (pll->pll_prediv & 0x3f));
767
768 /* write new system clk into P_sec_len */
769 internal = dib8000_read32(state, 23) / 1000;
770 dprintk("Old Internal = %d", internal);
771 xtal = 2 * (internal / loopdiv) * prediv;
772 internal = 1000 * (xtal/pll->pll_prediv) * pll->pll_ratio;
773 dprintk("Xtal = %d , New Fmem = %d New Fdemod = %d, New Fsampling = %d", xtal, internal/1000, internal/2000, internal/8000);
774 dprintk("New Internal = %d", internal);
775
776 dib8000_write_word(state, 23,
777 (u16) (((internal / 2) >> 16) & 0xffff));
778 dib8000_write_word(state, 24, (u16) ((internal / 2) & 0xffff));
779 /* enable PLL */
780 dib8000_write_word(state, 1857, reg_1857 | (1 << 15));
781
782 while (((dib8000_read_word(state, 1856)>>15)&0x1) != 1)
783 dprintk("Waiting for PLL to lock");
784
785 /* verify */
786 reg_1856 = dib8000_read_word(state, 1856);
787 dprintk("PLL Updated with prediv = %d and loopdiv = %d",
788 reg_1856&0x3f, (reg_1856>>6)&0x3f);
173a64cb
PB
789 } else {
790 if (bw != state->current_demod_bw) {
791 /** Bandwidth change => force PLL update **/
792 dprintk("PLL: Bandwidth Change %d MHz -> %d MHz (prediv: %d->%d)", state->current_demod_bw / 1000, bw / 1000, oldprediv, state->cfg.pll->pll_prediv);
793
794 if (state->cfg.pll->pll_prediv != oldprediv) {
795 /** Full PLL change only if prediv is changed **/
796
797 /** full update => bypass and reconfigure **/
798 dprintk("PLL: New Setting for %d MHz Bandwidth (prediv: %d, ratio: %d)", bw/1000, state->cfg.pll->pll_prediv, state->cfg.pll->pll_ratio);
799 dib8000_write_word(state, 902, dib8000_read_word(state, 902) | (1<<3)); /* bypass PLL */
800 dib8000_reset_pll(state);
801 dib8000_write_word(state, 898, 0x0004); /* sad */
802 } else
803 ratio = state->cfg.pll->pll_ratio;
0c32dbd7 804
173a64cb
PB
805 state->current_demod_bw = bw;
806 }
807
808 if (ratio != 0) {
809 /** ratio update => only change ratio **/
810 dprintk("PLL: Update ratio (prediv: %d, ratio: %d)", state->cfg.pll->pll_prediv, ratio);
811 dib8000_write_word(state, 901, (state->cfg.pll->pll_prediv << 8) | (ratio << 0)); /* only the PLL ratio is updated. */
812 }
6ef06e78 813 }
173a64cb
PB
814
815 return 0;
0c32dbd7 816}
0c32dbd7 817
77e2c0f5
PB
818static int dib8000_reset_gpio(struct dib8000_state *st)
819{
820 /* reset the GPIOs */
821 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
822 dib8000_write_word(st, 1030, st->cfg.gpio_val);
823
824 /* TODO 782 is P_gpio_od */
825
826 dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
827
828 dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
829 return 0;
830}
831
832static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
833{
834 st->cfg.gpio_dir = dib8000_read_word(st, 1029);
835 st->cfg.gpio_dir &= ~(1 << num); /* reset the direction bit */
836 st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */
837 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
838
839 st->cfg.gpio_val = dib8000_read_word(st, 1030);
840 st->cfg.gpio_val &= ~(1 << num); /* reset the direction bit */
841 st->cfg.gpio_val |= (val & 0x01) << num; /* set the new value */
842 dib8000_write_word(st, 1030, st->cfg.gpio_val);
843
844 dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
845
846 return 0;
847}
848
d44913c1 849static int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
77e2c0f5
PB
850{
851 struct dib8000_state *state = fe->demodulator_priv;
852 return dib8000_cfg_gpio(state, num, dir, val);
853}
854
77e2c0f5
PB
855static const u16 dib8000_defaults[] = {
856 /* auto search configuration - lock0 by default waiting
857 * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
858 3, 7,
859 0x0004,
860 0x0400,
861 0x0814,
862
863 12, 11,
864 0x001b,
865 0x7740,
866 0x005b,
867 0x8d80,
868 0x01c9,
869 0xc380,
870 0x0000,
871 0x0080,
872 0x0000,
873 0x0090,
874 0x0001,
875 0xd4c0,
876
877 /*1, 32,
4c70e074 878 0x6680 // P_corm_thres Lock algorithms configuration */
77e2c0f5
PB
879
880 11, 80, /* set ADC level to -16 */
881 (1 << 13) - 825 - 117,
882 (1 << 13) - 837 - 117,
883 (1 << 13) - 811 - 117,
884 (1 << 13) - 766 - 117,
885 (1 << 13) - 737 - 117,
886 (1 << 13) - 693 - 117,
887 (1 << 13) - 648 - 117,
888 (1 << 13) - 619 - 117,
889 (1 << 13) - 575 - 117,
890 (1 << 13) - 531 - 117,
891 (1 << 13) - 501 - 117,
892
893 4, 108,
894 0,
895 0,
896 0,
897 0,
898
899 1, 175,
900 0x0410,
901 1, 179,
902 8192, // P_fft_nb_to_cut
903
904 6, 181,
905 0x2800, // P_coff_corthres_ ( 2k 4k 8k ) 0x2800
906 0x2800,
907 0x2800,
908 0x2800, // P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
909 0x2800,
910 0x2800,
911
912 2, 193,
913 0x0666, // P_pha3_thres
914 0x0000, // P_cti_use_cpe, P_cti_use_prog
915
916 2, 205,
917 0x200f, // P_cspu_regul, P_cspu_win_cut
918 0x000f, // P_des_shift_work
919
920 5, 215,
921 0x023d, // P_adp_regul_cnt
922 0x00a4, // P_adp_noise_cnt
923 0x00a4, // P_adp_regul_ext
924 0x7ff0, // P_adp_noise_ext
925 0x3ccc, // P_adp_fil
926
927 1, 230,
928 0x0000, // P_2d_byp_ti_num
929
930 1, 263,
931 0x800, //P_equal_thres_wgn
932
933 1, 268,
934 (2 << 9) | 39, // P_equal_ctrl_synchro, P_equal_speedmode
935
936 1, 270,
937 0x0001, // P_div_lock0_wait
938 1, 285,
939 0x0020, //p_fec_
940 1, 299,
b4d6046e 941 0x0062, /* P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard */
77e2c0f5
PB
942
943 1, 338,
944 (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1
b4d6046e
OG
945 (1 << 10) |
946 (0 << 9) | /* P_ctrl_pre_freq_inh=0 */
947 (3 << 5) | /* P_ctrl_pre_freq_step=3 */
948 (1 << 0), /* P_pre_freq_win_len=1 */
77e2c0f5 949
77e2c0f5
PB
950 0,
951};
952
953static u16 dib8000_identify(struct i2c_device *client)
954{
955 u16 value;
956
957 //because of glitches sometimes
958 value = dib8000_i2c_read16(client, 896);
959
960 if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
961 dprintk("wrong Vendor ID (read=0x%x)", value);
962 return 0;
963 }
964
965 value = dib8000_i2c_read16(client, 897);
0c32dbd7
OG
966 if (value != 0x8000 && value != 0x8001 &&
967 value != 0x8002 && value != 0x8090) {
77e2c0f5
PB
968 dprintk("wrong Device ID (%x)", value);
969 return 0;
970 }
971
972 switch (value) {
973 case 0x8000:
974 dprintk("found DiB8000A");
975 break;
976 case 0x8001:
977 dprintk("found DiB8000B");
978 break;
979 case 0x8002:
980 dprintk("found DiB8000C");
981 break;
0c32dbd7
OG
982 case 0x8090:
983 dprintk("found DiB8096P");
984 break;
77e2c0f5
PB
985 }
986 return value;
987}
988
7a9d85d5
MCC
989static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 *unc);
990
6ef06e78
MCC
991static void dib8000_reset_stats(struct dvb_frontend *fe)
992{
993 struct dib8000_state *state = fe->demodulator_priv;
994 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
7a9d85d5 995 u32 ucb;
6ef06e78
MCC
996
997 memset(&c->strength, 0, sizeof(c->strength));
998 memset(&c->cnr, 0, sizeof(c->cnr));
999 memset(&c->post_bit_error, 0, sizeof(c->post_bit_error));
1000 memset(&c->post_bit_count, 0, sizeof(c->post_bit_count));
1001 memset(&c->block_error, 0, sizeof(c->block_error));
1002
1003 c->strength.len = 1;
1004 c->cnr.len = 1;
1005 c->block_error.len = 1;
0400c535 1006 c->block_count.len = 1;
6ef06e78
MCC
1007 c->post_bit_error.len = 1;
1008 c->post_bit_count.len = 1;
1009
b4600d70 1010 c->strength.stat[0].scale = FE_SCALE_DECIBEL;
6ef06e78
MCC
1011 c->strength.stat[0].uvalue = 0;
1012
1013 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1014 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0400c535 1015 c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6ef06e78
MCC
1016 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1017 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
7a9d85d5
MCC
1018
1019 dib8000_read_unc_blocks(fe, &ucb);
704f01bb 1020
7a9d85d5 1021 state->init_ucb = -ucb;
0400c535
MCC
1022 state->ber_jiffies_stats = 0;
1023 state->per_jiffies_stats = 0;
1024 memset(&state->ber_jiffies_stats_layer, 0,
1025 sizeof(state->ber_jiffies_stats_layer));
6ef06e78
MCC
1026}
1027
77e2c0f5
PB
1028static int dib8000_reset(struct dvb_frontend *fe)
1029{
1030 struct dib8000_state *state = fe->demodulator_priv;
1031
77e2c0f5
PB
1032 if ((state->revision = dib8000_identify(&state->i2c)) == 0)
1033 return -EINVAL;
1034
0c32dbd7
OG
1035 /* sram lead in, rdy */
1036 if (state->revision != 0x8090)
1037 dib8000_write_word(state, 1287, 0x0003);
1038
77e2c0f5
PB
1039 if (state->revision == 0x8000)
1040 dprintk("error : dib8000 MA not supported");
1041
1042 dibx000_reset_i2c_master(&state->i2c_master);
1043
0c32dbd7 1044 dib8000_set_power_mode(state, DIB8000_POWER_ALL);
77e2c0f5
PB
1045
1046 /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
173a64cb 1047 dib8000_set_adc_state(state, DIBX000_ADC_OFF);
77e2c0f5
PB
1048
1049 /* restart all parts */
1050 dib8000_write_word(state, 770, 0xffff);
1051 dib8000_write_word(state, 771, 0xffff);
1052 dib8000_write_word(state, 772, 0xfffc);
0c32dbd7
OG
1053 if (state->revision == 0x8090)
1054 dib8000_write_word(state, 1280, 0x0045);
1055 else
1056 dib8000_write_word(state, 1280, 0x004d);
77e2c0f5
PB
1057 dib8000_write_word(state, 1281, 0x000c);
1058
1059 dib8000_write_word(state, 770, 0x0000);
1060 dib8000_write_word(state, 771, 0x0000);
1061 dib8000_write_word(state, 772, 0x0000);
1062 dib8000_write_word(state, 898, 0x0004); // sad
1063 dib8000_write_word(state, 1280, 0x0000);
1064 dib8000_write_word(state, 1281, 0x0000);
1065
1066 /* drives */
0c32dbd7
OG
1067 if (state->revision != 0x8090) {
1068 if (state->cfg.drives)
1069 dib8000_write_word(state, 906, state->cfg.drives);
1070 else {
1071 dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
1072 /* min drive SDRAM - not optimal - adjust */
1073 dib8000_write_word(state, 906, 0x2d98);
1074 }
77e2c0f5
PB
1075 }
1076
1077 dib8000_reset_pll(state);
0c32dbd7
OG
1078 if (state->revision != 0x8090)
1079 dib8000_write_word(state, 898, 0x0004);
77e2c0f5
PB
1080
1081 if (dib8000_reset_gpio(state) != 0)
1082 dprintk("GPIO reset was not successful.");
1083
0c32dbd7
OG
1084 if ((state->revision != 0x8090) &&
1085 (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0))
77e2c0f5
PB
1086 dprintk("OUTPUT_MODE could not be resetted.");
1087
1088 state->current_agc = NULL;
1089
1090 // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
1091 /* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
1092 if (state->cfg.pll->ifreq == 0)
1093 dib8000_write_word(state, 40, 0x0755); /* P_iqc_corr_inh = 0 enable IQcorr block */
1094 else
1095 dib8000_write_word(state, 40, 0x1f55); /* P_iqc_corr_inh = 1 disable IQcorr block */
1096
1097 {
1098 u16 l = 0, r;
1099 const u16 *n;
1100 n = dib8000_defaults;
1101 l = *n++;
1102 while (l) {
1103 r = *n++;
1104 do {
1105 dib8000_write_word(state, r, *n++);
1106 r++;
1107 } while (--l);
1108 l = *n++;
1109 }
1110 }
173a64cb 1111
77e2c0f5
PB
1112 state->isdbt_cfg_loaded = 0;
1113
1114 //div_cfg override for special configs
173a64cb 1115 if ((state->revision != 8090) && (state->cfg.div_cfg != 0))
77e2c0f5
PB
1116 dib8000_write_word(state, 903, state->cfg.div_cfg);
1117
1118 /* unforce divstr regardless whether i2c enumeration was done or not */
1119 dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
1120
4c70e074 1121 dib8000_set_bandwidth(fe, 6000);
77e2c0f5
PB
1122
1123 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
173a64cb
PB
1124 dib8000_sad_calib(state);
1125 if (state->revision != 0x8090)
0c32dbd7 1126 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
173a64cb
PB
1127
1128 /* ber_rs_len = 3 */
1129 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5));
77e2c0f5 1130
0c32dbd7 1131 dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
77e2c0f5 1132
6ef06e78
MCC
1133 dib8000_reset_stats(fe);
1134
77e2c0f5
PB
1135 return 0;
1136}
1137
1138static void dib8000_restart_agc(struct dib8000_state *state)
1139{
1140 // P_restart_iqc & P_restart_agc
1141 dib8000_write_word(state, 770, 0x0a00);
1142 dib8000_write_word(state, 770, 0x0000);
1143}
1144
1145static int dib8000_update_lna(struct dib8000_state *state)
1146{
1147 u16 dyn_gain;
1148
1149 if (state->cfg.update_lna) {
1150 // read dyn_gain here (because it is demod-dependent and not tuner)
1151 dyn_gain = dib8000_read_word(state, 390);
1152
b4d6046e 1153 if (state->cfg.update_lna(state->fe[0], dyn_gain)) {
77e2c0f5
PB
1154 dib8000_restart_agc(state);
1155 return 1;
1156 }
1157 }
1158 return 0;
1159}
1160
1161static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
1162{
1163 struct dibx000_agc_config *agc = NULL;
1164 int i;
0c32dbd7
OG
1165 u16 reg;
1166
77e2c0f5
PB
1167 if (state->current_band == band && state->current_agc != NULL)
1168 return 0;
1169 state->current_band = band;
1170
1171 for (i = 0; i < state->cfg.agc_config_count; i++)
1172 if (state->cfg.agc[i].band_caps & band) {
1173 agc = &state->cfg.agc[i];
1174 break;
1175 }
1176
1177 if (agc == NULL) {
1178 dprintk("no valid AGC configuration found for band 0x%02x", band);
1179 return -EINVAL;
1180 }
1181
1182 state->current_agc = agc;
1183
1184 /* AGC */
1185 dib8000_write_word(state, 76, agc->setup);
1186 dib8000_write_word(state, 77, agc->inv_gain);
1187 dib8000_write_word(state, 78, agc->time_stabiliz);
1188 dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
1189
1190 // Demod AGC loop configuration
1191 dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
1192 dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
1193
1194 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
1195 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
1196
1197 /* AGC continued */
1198 if (state->wbd_ref != 0)
1199 dib8000_write_word(state, 106, state->wbd_ref);
1200 else // use default
1201 dib8000_write_word(state, 106, agc->wbd_ref);
0c32dbd7
OG
1202
1203 if (state->revision == 0x8090) {
1204 reg = dib8000_read_word(state, 922) & (0x3 << 2);
1205 dib8000_write_word(state, 922, reg | (agc->wbd_sel << 2));
1206 }
1207
77e2c0f5
PB
1208 dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
1209 dib8000_write_word(state, 108, agc->agc1_max);
1210 dib8000_write_word(state, 109, agc->agc1_min);
1211 dib8000_write_word(state, 110, agc->agc2_max);
1212 dib8000_write_word(state, 111, agc->agc2_min);
1213 dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
1214 dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
1215 dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
1216 dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
1217
1218 dib8000_write_word(state, 75, agc->agc1_pt3);
0c32dbd7
OG
1219 if (state->revision != 0x8090)
1220 dib8000_write_word(state, 923,
1221 (dib8000_read_word(state, 923) & 0xffe3) |
1222 (agc->wbd_inv << 4) | (agc->wbd_sel << 2));
77e2c0f5
PB
1223
1224 return 0;
1225}
1226
d44913c1 1227static void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
03245a5e
OG
1228{
1229 struct dib8000_state *state = fe->demodulator_priv;
1230 dib8000_set_adc_state(state, DIBX000_ADC_ON);
1231 dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000)));
1232}
03245a5e 1233
77e2c0f5
PB
1234static int dib8000_agc_soft_split(struct dib8000_state *state)
1235{
1236 u16 agc, split_offset;
1237
1238 if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
1239 return FE_CALLBACK_TIME_NEVER;
1240
1241 // n_agc_global
1242 agc = dib8000_read_word(state, 390);
1243
1244 if (agc > state->current_agc->split.min_thres)
1245 split_offset = state->current_agc->split.min;
1246 else if (agc < state->current_agc->split.max_thres)
1247 split_offset = state->current_agc->split.max;
1248 else
1249 split_offset = state->current_agc->split.max *
b4d6046e
OG
1250 (agc - state->current_agc->split.min_thres) /
1251 (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
77e2c0f5
PB
1252
1253 dprintk("AGC split_offset: %d", split_offset);
1254
1255 // P_agc_force_split and P_agc_split_offset
1256 dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
1257 return 5000;
1258}
1259
1260static int dib8000_agc_startup(struct dvb_frontend *fe)
1261{
1262 struct dib8000_state *state = fe->demodulator_priv;
1263 enum frontend_tune_state *tune_state = &state->tune_state;
77e2c0f5 1264 int ret = 0;
0c32dbd7 1265 u16 reg, upd_demod_gain_period = 0x8000;
77e2c0f5
PB
1266
1267 switch (*tune_state) {
1268 case CT_AGC_START:
1269 // set power-up level: interf+analog+AGC
1270
0c32dbd7
OG
1271 if (state->revision != 0x8090)
1272 dib8000_set_adc_state(state, DIBX000_ADC_ON);
1273 else {
1274 dib8000_set_power_mode(state, DIB8000_POWER_ALL);
1275
1276 reg = dib8000_read_word(state, 1947)&0xff00;
1277 dib8000_write_word(state, 1946,
1278 upd_demod_gain_period & 0xFFFF);
1279 /* bit 14 = enDemodGain */
1280 dib8000_write_word(state, 1947, reg | (1<<14) |
1281 ((upd_demod_gain_period >> 16) & 0xFF));
1282
1283 /* enable adc i & q */
1284 reg = dib8000_read_word(state, 1920);
1285 dib8000_write_word(state, 1920, (reg | 0x3) &
1286 (~(1 << 7)));
1287 }
77e2c0f5
PB
1288
1289 if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
1290 *tune_state = CT_AGC_STOP;
1291 state->status = FE_STATUS_TUNE_FAILED;
1292 break;
1293 }
1294
1295 ret = 70;
1296 *tune_state = CT_AGC_STEP_0;
1297 break;
1298
1299 case CT_AGC_STEP_0:
1300 //AGC initialization
1301 if (state->cfg.agc_control)
4c70e074 1302 state->cfg.agc_control(fe, 1);
77e2c0f5
PB
1303
1304 dib8000_restart_agc(state);
1305
1306 // wait AGC rough lock time
1307 ret = 50;
1308 *tune_state = CT_AGC_STEP_1;
1309 break;
1310
1311 case CT_AGC_STEP_1:
1312 // wait AGC accurate lock time
1313 ret = 70;
1314
1315 if (dib8000_update_lna(state))
1316 // wait only AGC rough lock time
1317 ret = 50;
1318 else
1319 *tune_state = CT_AGC_STEP_2;
1320 break;
1321
1322 case CT_AGC_STEP_2:
1323 dib8000_agc_soft_split(state);
1324
1325 if (state->cfg.agc_control)
4c70e074 1326 state->cfg.agc_control(fe, 0);
77e2c0f5
PB
1327
1328 *tune_state = CT_AGC_STOP;
1329 break;
1330 default:
1331 ret = dib8000_agc_soft_split(state);
1332 break;
1333 }
1334 return ret;
1335
1336}
1337
0c32dbd7
OG
1338static void dib8096p_host_bus_drive(struct dib8000_state *state, u8 drive)
1339{
1340 u16 reg;
1341
1342 drive &= 0x7;
1343
1344 /* drive host bus 2, 3, 4 */
1345 reg = dib8000_read_word(state, 1798) &
1346 ~(0x7 | (0x7 << 6) | (0x7 << 12));
1347 reg |= (drive<<12) | (drive<<6) | drive;
1348 dib8000_write_word(state, 1798, reg);
1349
1350 /* drive host bus 5,6 */
1351 reg = dib8000_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
1352 reg |= (drive<<8) | (drive<<2);
1353 dib8000_write_word(state, 1799, reg);
1354
1355 /* drive host bus 7, 8, 9 */
1356 reg = dib8000_read_word(state, 1800) &
1357 ~(0x7 | (0x7 << 6) | (0x7 << 12));
1358 reg |= (drive<<12) | (drive<<6) | drive;
1359 dib8000_write_word(state, 1800, reg);
1360
1361 /* drive host bus 10, 11 */
1362 reg = dib8000_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
1363 reg |= (drive<<8) | (drive<<2);
1364 dib8000_write_word(state, 1801, reg);
1365
1366 /* drive host bus 12, 13, 14 */
1367 reg = dib8000_read_word(state, 1802) &
1368 ~(0x7 | (0x7 << 6) | (0x7 << 12));
1369 reg |= (drive<<12) | (drive<<6) | drive;
1370 dib8000_write_word(state, 1802, reg);
1371}
1372
1373static u32 dib8096p_calcSyncFreq(u32 P_Kin, u32 P_Kout,
1374 u32 insertExtSynchro, u32 syncSize)
1375{
1376 u32 quantif = 3;
1377 u32 nom = (insertExtSynchro * P_Kin+syncSize);
1378 u32 denom = P_Kout;
1379 u32 syncFreq = ((nom << quantif) / denom);
1380
1381 if ((syncFreq & ((1 << quantif) - 1)) != 0)
1382 syncFreq = (syncFreq >> quantif) + 1;
1383 else
1384 syncFreq = (syncFreq >> quantif);
1385
1386 if (syncFreq != 0)
1387 syncFreq = syncFreq - 1;
1388
1389 return syncFreq;
1390}
1391
1392static void dib8096p_cfg_DibTx(struct dib8000_state *state, u32 P_Kin,
1393 u32 P_Kout, u32 insertExtSynchro, u32 synchroMode,
1394 u32 syncWord, u32 syncSize)
1395{
1396 dprintk("Configure DibStream Tx");
1397
1398 dib8000_write_word(state, 1615, 1);
1399 dib8000_write_word(state, 1603, P_Kin);
1400 dib8000_write_word(state, 1605, P_Kout);
1401 dib8000_write_word(state, 1606, insertExtSynchro);
1402 dib8000_write_word(state, 1608, synchroMode);
1403 dib8000_write_word(state, 1609, (syncWord >> 16) & 0xffff);
1404 dib8000_write_word(state, 1610, syncWord & 0xffff);
1405 dib8000_write_word(state, 1612, syncSize);
1406 dib8000_write_word(state, 1615, 0);
1407}
1408
1409static void dib8096p_cfg_DibRx(struct dib8000_state *state, u32 P_Kin,
1410 u32 P_Kout, u32 synchroMode, u32 insertExtSynchro,
1411 u32 syncWord, u32 syncSize, u32 dataOutRate)
1412{
1413 u32 syncFreq;
1414
1415 dprintk("Configure DibStream Rx synchroMode = %d", synchroMode);
1416
1417 if ((P_Kin != 0) && (P_Kout != 0)) {
1418 syncFreq = dib8096p_calcSyncFreq(P_Kin, P_Kout,
1419 insertExtSynchro, syncSize);
1420 dib8000_write_word(state, 1542, syncFreq);
1421 }
1422
1423 dib8000_write_word(state, 1554, 1);
1424 dib8000_write_word(state, 1536, P_Kin);
1425 dib8000_write_word(state, 1537, P_Kout);
1426 dib8000_write_word(state, 1539, synchroMode);
1427 dib8000_write_word(state, 1540, (syncWord >> 16) & 0xffff);
1428 dib8000_write_word(state, 1541, syncWord & 0xffff);
1429 dib8000_write_word(state, 1543, syncSize);
1430 dib8000_write_word(state, 1544, dataOutRate);
1431 dib8000_write_word(state, 1554, 0);
1432}
1433
1434static void dib8096p_enMpegMux(struct dib8000_state *state, int onoff)
1435{
1436 u16 reg_1287;
1437
1438 reg_1287 = dib8000_read_word(state, 1287);
1439
1440 switch (onoff) {
1441 case 1:
1442 reg_1287 &= ~(1 << 8);
1443 break;
1444 case 0:
1445 reg_1287 |= (1 << 8);
1446 break;
1447 }
1448
1449 dib8000_write_word(state, 1287, reg_1287);
1450}
1451
1452static void dib8096p_configMpegMux(struct dib8000_state *state,
1453 u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
1454{
1455 u16 reg_1287;
1456
1457 dprintk("Enable Mpeg mux");
1458
1459 dib8096p_enMpegMux(state, 0);
1460
1461 /* If the input mode is MPEG do not divide the serial clock */
1462 if ((enSerialMode == 1) && (state->input_mode_mpeg == 1))
1463 enSerialClkDiv2 = 0;
1464
1465 reg_1287 = ((pulseWidth & 0x1f) << 3) |
1466 ((enSerialMode & 0x1) << 2) | (enSerialClkDiv2 & 0x1);
1467 dib8000_write_word(state, 1287, reg_1287);
1468
1469 dib8096p_enMpegMux(state, 1);
1470}
1471
1472static void dib8096p_setDibTxMux(struct dib8000_state *state, int mode)
1473{
1474 u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 7);
1475
1476 switch (mode) {
1477 case MPEG_ON_DIBTX:
1478 dprintk("SET MPEG ON DIBSTREAM TX");
1479 dib8096p_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
1480 reg_1288 |= (1 << 9); break;
1481 case DIV_ON_DIBTX:
1482 dprintk("SET DIV_OUT ON DIBSTREAM TX");
1483 dib8096p_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
1484 reg_1288 |= (1 << 8); break;
1485 case ADC_ON_DIBTX:
1486 dprintk("SET ADC_OUT ON DIBSTREAM TX");
1487 dib8096p_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
1488 reg_1288 |= (1 << 7); break;
1489 default:
1490 break;
1491 }
1492 dib8000_write_word(state, 1288, reg_1288);
1493}
1494
1495static void dib8096p_setHostBusMux(struct dib8000_state *state, int mode)
1496{
1497 u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 4);
1498
1499 switch (mode) {
1500 case DEMOUT_ON_HOSTBUS:
1501 dprintk("SET DEM OUT OLD INTERF ON HOST BUS");
1502 dib8096p_enMpegMux(state, 0);
1503 reg_1288 |= (1 << 6);
1504 break;
1505 case DIBTX_ON_HOSTBUS:
1506 dprintk("SET DIBSTREAM TX ON HOST BUS");
1507 dib8096p_enMpegMux(state, 0);
1508 reg_1288 |= (1 << 5);
1509 break;
1510 case MPEG_ON_HOSTBUS:
1511 dprintk("SET MPEG MUX ON HOST BUS");
1512 reg_1288 |= (1 << 4);
1513 break;
1514 default:
1515 break;
1516 }
1517 dib8000_write_word(state, 1288, reg_1288);
1518}
1519
1520static int dib8096p_set_diversity_in(struct dvb_frontend *fe, int onoff)
1521{
1522 struct dib8000_state *state = fe->demodulator_priv;
1523 u16 reg_1287;
1524
1525 switch (onoff) {
1526 case 0: /* only use the internal way - not the diversity input */
1527 dprintk("%s mode OFF : by default Enable Mpeg INPUT",
1528 __func__);
1529 /* outputRate = 8 */
1530 dib8096p_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0);
1531
1532 /* Do not divide the serial clock of MPEG MUX in
1533 SERIAL MODE in case input mode MPEG is used */
1534 reg_1287 = dib8000_read_word(state, 1287);
1535 /* enSerialClkDiv2 == 1 ? */
1536 if ((reg_1287 & 0x1) == 1) {
1537 /* force enSerialClkDiv2 = 0 */
1538 reg_1287 &= ~0x1;
1539 dib8000_write_word(state, 1287, reg_1287);
1540 }
1541 state->input_mode_mpeg = 1;
1542 break;
1543 case 1: /* both ways */
1544 case 2: /* only the diversity input */
1545 dprintk("%s ON : Enable diversity INPUT", __func__);
1546 dib8096p_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
1547 state->input_mode_mpeg = 0;
1548 break;
1549 }
1550
1551 dib8000_set_diversity_in(state->fe[0], onoff);
1552 return 0;
1553}
1554
1555static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode)
1556{
1557 struct dib8000_state *state = fe->demodulator_priv;
1558 u16 outreg, smo_mode, fifo_threshold;
1559 u8 prefer_mpeg_mux_use = 1;
1560 int ret = 0;
1561
173a64cb 1562 state->output_mode = mode;
0c32dbd7
OG
1563 dib8096p_host_bus_drive(state, 1);
1564
1565 fifo_threshold = 1792;
1566 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
1567 outreg = dib8000_read_word(state, 1286) &
1568 ~((1 << 10) | (0x7 << 6) | (1 << 1));
1569
1570 switch (mode) {
1571 case OUTMODE_HIGH_Z:
1572 outreg = 0;
1573 break;
1574
1575 case OUTMODE_MPEG2_SERIAL:
1576 if (prefer_mpeg_mux_use) {
1577 dprintk("dib8096P setting output mode TS_SERIAL using Mpeg Mux");
1578 dib8096p_configMpegMux(state, 3, 1, 1);
1579 dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS);
1580 } else {/* Use Smooth block */
1581 dprintk("dib8096P setting output mode TS_SERIAL using Smooth bloc");
1582 dib8096p_setHostBusMux(state,
1583 DEMOUT_ON_HOSTBUS);
1584 outreg |= (2 << 6) | (0 << 1);
1585 }
1586 break;
1587
1588 case OUTMODE_MPEG2_PAR_GATED_CLK:
1589 if (prefer_mpeg_mux_use) {
1590 dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
1591 dib8096p_configMpegMux(state, 2, 0, 0);
1592 dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS);
1593 } else { /* Use Smooth block */
1594 dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Smooth block");
1595 dib8096p_setHostBusMux(state,
1596 DEMOUT_ON_HOSTBUS);
1597 outreg |= (0 << 6);
1598 }
1599 break;
1600
1601 case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */
1602 dprintk("dib8096P setting output mode TS_PARALLEL_CONT using Smooth block");
1603 dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
1604 outreg |= (1 << 6);
1605 break;
1606
1607 case OUTMODE_MPEG2_FIFO:
1608 /* Using Smooth block because not supported
1609 by new Mpeg Mux bloc */
1610 dprintk("dib8096P setting output mode TS_FIFO using Smooth block");
1611 dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
1612 outreg |= (5 << 6);
1613 smo_mode |= (3 << 1);
1614 fifo_threshold = 512;
1615 break;
1616
1617 case OUTMODE_DIVERSITY:
1618 dprintk("dib8096P setting output mode MODE_DIVERSITY");
1619 dib8096p_setDibTxMux(state, DIV_ON_DIBTX);
1620 dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
1621 break;
1622
1623 case OUTMODE_ANALOG_ADC:
1624 dprintk("dib8096P setting output mode MODE_ANALOG_ADC");
1625 dib8096p_setDibTxMux(state, ADC_ON_DIBTX);
1626 dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
1627 break;
1628 }
1629
1630 if (mode != OUTMODE_HIGH_Z)
1631 outreg |= (1<<10);
1632
1633 dprintk("output_mpeg2_in_188_bytes = %d",
1634 state->cfg.output_mpeg2_in_188_bytes);
1635 if (state->cfg.output_mpeg2_in_188_bytes)
1636 smo_mode |= (1 << 5);
1637
1638 ret |= dib8000_write_word(state, 299, smo_mode);
1639 /* synchronous fread */
1640 ret |= dib8000_write_word(state, 299 + 1, fifo_threshold);
1641 ret |= dib8000_write_word(state, 1286, outreg);
1642
1643 return ret;
1644}
1645
1646static int map_addr_to_serpar_number(struct i2c_msg *msg)
1647{
1648 if (msg->buf[0] <= 15)
1649 msg->buf[0] -= 1;
1650 else if (msg->buf[0] == 17)
1651 msg->buf[0] = 15;
1652 else if (msg->buf[0] == 16)
1653 msg->buf[0] = 17;
1654 else if (msg->buf[0] == 19)
1655 msg->buf[0] = 16;
1656 else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
1657 msg->buf[0] -= 3;
1658 else if (msg->buf[0] == 28)
1659 msg->buf[0] = 23;
1660 else if (msg->buf[0] == 99)
1661 msg->buf[0] = 99;
1662 else
1663 return -EINVAL;
1664 return 0;
1665}
1666
1667static int dib8096p_tuner_write_serpar(struct i2c_adapter *i2c_adap,
1668 struct i2c_msg msg[], int num)
1669{
1670 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1671 u8 n_overflow = 1;
1672 u16 i = 1000;
1673 u16 serpar_num = msg[0].buf[0];
1674
1675 while (n_overflow == 1 && i) {
1676 n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1;
1677 i--;
1678 if (i == 0)
1679 dprintk("Tuner ITF: write busy (overflow)");
1680 }
1681 dib8000_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
1682 dib8000_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
1683
1684 return num;
1685}
1686
1687static int dib8096p_tuner_read_serpar(struct i2c_adapter *i2c_adap,
1688 struct i2c_msg msg[], int num)
1689{
1690 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1691 u8 n_overflow = 1, n_empty = 1;
1692 u16 i = 1000;
1693 u16 serpar_num = msg[0].buf[0];
1694 u16 read_word;
1695
1696 while (n_overflow == 1 && i) {
1697 n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1;
1698 i--;
1699 if (i == 0)
1700 dprintk("TunerITF: read busy (overflow)");
1701 }
1702 dib8000_write_word(state, 1985, (0<<6) | (serpar_num&0x3f));
1703
1704 i = 1000;
1705 while (n_empty == 1 && i) {
1706 n_empty = dib8000_read_word(state, 1984)&0x1;
1707 i--;
1708 if (i == 0)
1709 dprintk("TunerITF: read busy (empty)");
1710 }
1711
1712 read_word = dib8000_read_word(state, 1987);
1713 msg[1].buf[0] = (read_word >> 8) & 0xff;
1714 msg[1].buf[1] = (read_word) & 0xff;
1715
1716 return num;
1717}
1718
1719static int dib8096p_tuner_rw_serpar(struct i2c_adapter *i2c_adap,
1720 struct i2c_msg msg[], int num)
1721{
1722 if (map_addr_to_serpar_number(&msg[0]) == 0) {
1723 if (num == 1) /* write */
1724 return dib8096p_tuner_write_serpar(i2c_adap, msg, 1);
1725 else /* read */
1726 return dib8096p_tuner_read_serpar(i2c_adap, msg, 2);
1727 }
1728 return num;
1729}
1730
1731static int dib8096p_rw_on_apb(struct i2c_adapter *i2c_adap,
1732 struct i2c_msg msg[], int num, u16 apb_address)
1733{
1734 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1735 u16 word;
1736
1737 if (num == 1) { /* write */
1738 dib8000_write_word(state, apb_address,
1739 ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
1740 } else {
1741 word = dib8000_read_word(state, apb_address);
1742 msg[1].buf[0] = (word >> 8) & 0xff;
1743 msg[1].buf[1] = (word) & 0xff;
1744 }
1745 return num;
1746}
1747
1748static int dib8096p_tuner_xfer(struct i2c_adapter *i2c_adap,
1749 struct i2c_msg msg[], int num)
1750{
1751 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1752 u16 apb_address = 0, word;
1753 int i = 0;
1754
1755 switch (msg[0].buf[0]) {
1756 case 0x12:
1757 apb_address = 1920;
1758 break;
1759 case 0x14:
1760 apb_address = 1921;
1761 break;
1762 case 0x24:
1763 apb_address = 1922;
1764 break;
1765 case 0x1a:
1766 apb_address = 1923;
1767 break;
1768 case 0x22:
1769 apb_address = 1924;
1770 break;
1771 case 0x33:
1772 apb_address = 1926;
1773 break;
1774 case 0x34:
1775 apb_address = 1927;
1776 break;
1777 case 0x35:
1778 apb_address = 1928;
1779 break;
1780 case 0x36:
1781 apb_address = 1929;
1782 break;
1783 case 0x37:
1784 apb_address = 1930;
1785 break;
1786 case 0x38:
1787 apb_address = 1931;
1788 break;
1789 case 0x39:
1790 apb_address = 1932;
1791 break;
1792 case 0x2a:
1793 apb_address = 1935;
1794 break;
1795 case 0x2b:
1796 apb_address = 1936;
1797 break;
1798 case 0x2c:
1799 apb_address = 1937;
1800 break;
1801 case 0x2d:
1802 apb_address = 1938;
1803 break;
1804 case 0x2e:
1805 apb_address = 1939;
1806 break;
1807 case 0x2f:
1808 apb_address = 1940;
1809 break;
1810 case 0x30:
1811 apb_address = 1941;
1812 break;
1813 case 0x31:
1814 apb_address = 1942;
1815 break;
1816 case 0x32:
1817 apb_address = 1943;
1818 break;
1819 case 0x3e:
1820 apb_address = 1944;
1821 break;
1822 case 0x3f:
1823 apb_address = 1945;
1824 break;
1825 case 0x40:
1826 apb_address = 1948;
1827 break;
1828 case 0x25:
1829 apb_address = 936;
1830 break;
1831 case 0x26:
1832 apb_address = 937;
1833 break;
1834 case 0x27:
1835 apb_address = 938;
1836 break;
1837 case 0x28:
1838 apb_address = 939;
1839 break;
1840 case 0x1d:
1841 /* get sad sel request */
1842 i = ((dib8000_read_word(state, 921) >> 12)&0x3);
1843 word = dib8000_read_word(state, 924+i);
1844 msg[1].buf[0] = (word >> 8) & 0xff;
1845 msg[1].buf[1] = (word) & 0xff;
1846 return num;
1847 case 0x1f:
1848 if (num == 1) { /* write */
1849 word = (u16) ((msg[0].buf[1] << 8) |
1850 msg[0].buf[2]);
1851 /* in the VGAMODE Sel are located on bit 0/1 */
1852 word &= 0x3;
1853 word = (dib8000_read_word(state, 921) &
1854 ~(3<<12)) | (word<<12);
1855 /* Set the proper input */
1856 dib8000_write_word(state, 921, word);
1857 return num;
1858 }
1859 }
1860
1861 if (apb_address != 0) /* R/W acces via APB */
1862 return dib8096p_rw_on_apb(i2c_adap, msg, num, apb_address);
1863 else /* R/W access via SERPAR */
1864 return dib8096p_tuner_rw_serpar(i2c_adap, msg, num);
1865
1866 return 0;
1867}
1868
1869static u32 dib8096p_i2c_func(struct i2c_adapter *adapter)
1870{
1871 return I2C_FUNC_I2C;
1872}
1873
1874static struct i2c_algorithm dib8096p_tuner_xfer_algo = {
1875 .master_xfer = dib8096p_tuner_xfer,
1876 .functionality = dib8096p_i2c_func,
1877};
1878
d44913c1 1879static struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe)
0c32dbd7
OG
1880{
1881 struct dib8000_state *st = fe->demodulator_priv;
1882 return &st->dib8096p_tuner_adap;
1883}
0c32dbd7 1884
d44913c1 1885static int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff)
0c32dbd7
OG
1886{
1887 struct dib8000_state *state = fe->demodulator_priv;
1888 u16 en_cur_state;
1889
1890 dprintk("sleep dib8096p: %d", onoff);
1891
1892 en_cur_state = dib8000_read_word(state, 1922);
1893
1894 /* LNAs and MIX are ON and therefore it is a valid configuration */
1895 if (en_cur_state > 0xff)
1896 state->tuner_enable = en_cur_state ;
1897
1898 if (onoff)
1899 en_cur_state &= 0x00ff;
1900 else {
1901 if (state->tuner_enable != 0)
1902 en_cur_state = state->tuner_enable;
1903 }
1904
1905 dib8000_write_word(state, 1922, en_cur_state);
1906
1907 return 0;
1908}
0c32dbd7 1909
4c70e074 1910static const s32 lut_1000ln_mant[] =
03245a5e 1911{
9c783036 1912 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
03245a5e
OG
1913};
1914
d44913c1 1915static s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
03245a5e 1916{
4c70e074
OG
1917 struct dib8000_state *state = fe->demodulator_priv;
1918 u32 ix = 0, tmp_val = 0, exp = 0, mant = 0;
1919 s32 val;
1920
1921 val = dib8000_read32(state, 384);
4c70e074
OG
1922 if (mode) {
1923 tmp_val = val;
1924 while (tmp_val >>= 1)
1925 exp++;
1926 mant = (val * 1000 / (1<<exp));
1927 ix = (u8)((mant-1000)/100); /* index of the LUT */
b4d6046e 1928 val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908);
4c70e074
OG
1929 val = (val*256)/1000;
1930 }
1931 return val;
03245a5e 1932}
03245a5e 1933
d44913c1 1934static int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ)
0c32dbd7
OG
1935{
1936 struct dib8000_state *state = fe->demodulator_priv;
1937 int val = 0;
1938
1939 switch (IQ) {
1940 case 1:
1941 val = dib8000_read_word(state, 403);
1942 break;
1943 case 0:
1944 val = dib8000_read_word(state, 404);
1945 break;
1946 }
1947 if (val & 0x200)
1948 val -= 1024;
1949
1950 return val;
1951}
0c32dbd7 1952
77e2c0f5
PB
1953static void dib8000_update_timf(struct dib8000_state *state)
1954{
1955 u32 timf = state->timf = dib8000_read32(state, 435);
1956
1957 dib8000_write_word(state, 29, (u16) (timf >> 16));
1958 dib8000_write_word(state, 30, (u16) (timf & 0xffff));
1959 dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
1960}
1961
d44913c1 1962static u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf)
0c32dbd7
OG
1963{
1964 struct dib8000_state *state = fe->demodulator_priv;
1965
1966 switch (op) {
1967 case DEMOD_TIMF_SET:
1968 state->timf = timf;
1969 break;
1970 case DEMOD_TIMF_UPDATE:
1971 dib8000_update_timf(state);
1972 break;
1973 case DEMOD_TIMF_GET:
1974 break;
1975 }
1976 dib8000_set_bandwidth(state->fe[0], 6000);
1977
1978 return state->timf;
1979}
0c32dbd7 1980
5a0deeed
OG
1981static const u16 adc_target_16dB[11] = {
1982 (1 << 13) - 825 - 117,
1983 (1 << 13) - 837 - 117,
1984 (1 << 13) - 811 - 117,
1985 (1 << 13) - 766 - 117,
1986 (1 << 13) - 737 - 117,
1987 (1 << 13) - 693 - 117,
1988 (1 << 13) - 648 - 117,
1989 (1 << 13) - 619 - 117,
1990 (1 << 13) - 575 - 117,
1991 (1 << 13) - 531 - 117,
1992 (1 << 13) - 501 - 117
1993};
1994static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
1995
173a64cb 1996static u16 dib8000_set_layer(struct dib8000_state *state, u8 layer_index, u16 max_constellation)
77e2c0f5 1997{
173a64cb 1998 u8 cr, constellation, time_intlv;
c82056d0 1999 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
77e2c0f5 2000
c82056d0 2001 switch (c->layer[layer_index].modulation) {
173a64cb 2002 case DQPSK:
77e2c0f5
PB
2003 constellation = 0;
2004 break;
173a64cb 2005 case QPSK:
77e2c0f5
PB
2006 constellation = 1;
2007 break;
173a64cb 2008 case QAM_16:
77e2c0f5
PB
2009 constellation = 2;
2010 break;
173a64cb
PB
2011 case QAM_64:
2012 default:
77e2c0f5
PB
2013 constellation = 3;
2014 break;
173a64cb 2015 }
77e2c0f5 2016
c82056d0 2017 switch (c->layer[layer_index].fec) {
173a64cb
PB
2018 case FEC_1_2:
2019 cr = 1;
77e2c0f5 2020 break;
173a64cb
PB
2021 case FEC_2_3:
2022 cr = 2;
77e2c0f5 2023 break;
173a64cb
PB
2024 case FEC_3_4:
2025 cr = 3;
77e2c0f5 2026 break;
173a64cb
PB
2027 case FEC_5_6:
2028 cr = 5;
77e2c0f5 2029 break;
173a64cb
PB
2030 case FEC_7_8:
2031 default:
2032 cr = 7;
77e2c0f5 2033 break;
173a64cb 2034 }
77e2c0f5 2035
34ba2e65
MCC
2036 time_intlv = fls(c->layer[layer_index].interleaving);
2037 if (time_intlv > 3 && !(time_intlv == 4 && c->isdbt_sb_mode == 1))
173a64cb
PB
2038 time_intlv = 0;
2039
c82056d0
MCC
2040 dib8000_write_word(state, 2 + layer_index, (constellation << 10) | ((c->layer[layer_index].segment_count & 0xf) << 6) | (cr << 3) | time_intlv);
2041 if (c->layer[layer_index].segment_count > 0) {
173a64cb
PB
2042 switch (max_constellation) {
2043 case DQPSK:
2044 case QPSK:
c82056d0
MCC
2045 if (c->layer[layer_index].modulation == QAM_16 || c->layer[layer_index].modulation == QAM_64)
2046 max_constellation = c->layer[layer_index].modulation;
77e2c0f5 2047 break;
173a64cb 2048 case QAM_16:
c82056d0
MCC
2049 if (c->layer[layer_index].modulation == QAM_64)
2050 max_constellation = c->layer[layer_index].modulation;
77e2c0f5 2051 break;
77e2c0f5
PB
2052 }
2053 }
2054
173a64cb
PB
2055 return max_constellation;
2056}
2057
2058static const u16 adp_Q64[4] = {0x0148, 0xfff0, 0x00a4, 0xfff8}; /* P_adp_regul_cnt 0.04, P_adp_noise_cnt -0.002, P_adp_regul_ext 0.02, P_adp_noise_ext -0.001 */
2059static const u16 adp_Q16[4] = {0x023d, 0xffdf, 0x00a4, 0xfff0}; /* P_adp_regul_cnt 0.07, P_adp_noise_cnt -0.004, P_adp_regul_ext 0.02, P_adp_noise_ext -0.002 */
2060static const u16 adp_Qdefault[4] = {0x099a, 0xffae, 0x0333, 0xfff8}; /* P_adp_regul_cnt 0.3, P_adp_noise_cnt -0.01, P_adp_regul_ext 0.1, P_adp_noise_ext -0.002 */
2061static u16 dib8000_adp_fine_tune(struct dib8000_state *state, u16 max_constellation)
2062{
2063 u16 i, ana_gain = 0;
2064 const u16 *adp;
2065
2066 /* channel estimation fine configuration */
2067 switch (max_constellation) {
2068 case QAM_64:
2069 ana_gain = 0x7;
2070 adp = &adp_Q64[0];
2071 break;
2072 case QAM_16:
2073 ana_gain = 0x7;
2074 adp = &adp_Q16[0];
2075 break;
2076 default:
2077 ana_gain = 0;
2078 adp = &adp_Qdefault[0];
2079 break;
2080 }
2081
2082 for (i = 0; i < 4; i++)
2083 dib8000_write_word(state, 215 + i, adp[i]);
77e2c0f5 2084
173a64cb
PB
2085 return ana_gain;
2086}
77e2c0f5 2087
173a64cb
PB
2088static void dib8000_update_ana_gain(struct dib8000_state *state, u16 ana_gain)
2089{
2090 u16 i;
77e2c0f5 2091
173a64cb 2092 dib8000_write_word(state, 116, ana_gain);
77e2c0f5 2093
173a64cb
PB
2094 /* update ADC target depending on ana_gain */
2095 if (ana_gain) { /* set -16dB ADC target for ana_gain=-1 */
2096 for (i = 0; i < 10; i++)
2097 dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
2098 } else { /* set -22dB ADC target for ana_gain=0 */
2099 for (i = 0; i < 10; i++)
2100 dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
2101 }
2102}
77e2c0f5 2103
173a64cb
PB
2104static void dib8000_load_ana_fe_coefs(struct dib8000_state *state, const s16 *ana_fe)
2105{
2106 u16 mode = 0;
2107
2108 if (state->isdbt_cfg_loaded == 0)
2109 for (mode = 0; mode < 24; mode++)
2110 dib8000_write_word(state, 117 + mode, ana_fe[mode]);
2111}
2112
2113static const u16 lut_prbs_2k[14] = {
2114 0, 0x423, 0x009, 0x5C7, 0x7A6, 0x3D8, 0x527, 0x7FF, 0x79B, 0x3D6, 0x3A2, 0x53B, 0x2F4, 0x213
2115};
2116static const u16 lut_prbs_4k[14] = {
2117 0, 0x208, 0x0C3, 0x7B9, 0x423, 0x5C7, 0x3D8, 0x7FF, 0x3D6, 0x53B, 0x213, 0x029, 0x0D0, 0x48E
2118};
2119static const u16 lut_prbs_8k[14] = {
2120 0, 0x740, 0x069, 0x7DD, 0x208, 0x7B9, 0x5C7, 0x7FF, 0x53B, 0x029, 0x48E, 0x4C4, 0x367, 0x684
2121};
2122
2123static u16 dib8000_get_init_prbs(struct dib8000_state *state, u16 subchannel)
2124{
2125 int sub_channel_prbs_group = 0;
2126
2127 sub_channel_prbs_group = (subchannel / 3) + 1;
2128 dprintk("sub_channel_prbs_group = %d , subchannel =%d prbs = 0x%04x", sub_channel_prbs_group, subchannel, lut_prbs_8k[sub_channel_prbs_group]);
2129
2130 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
2131 case TRANSMISSION_MODE_2K:
2132 return lut_prbs_2k[sub_channel_prbs_group];
2133 case TRANSMISSION_MODE_4K:
2134 return lut_prbs_4k[sub_channel_prbs_group];
2135 default:
2136 case TRANSMISSION_MODE_8K:
2137 return lut_prbs_8k[sub_channel_prbs_group];
77e2c0f5 2138 }
173a64cb 2139}
77e2c0f5 2140
173a64cb
PB
2141static void dib8000_set_13seg_channel(struct dib8000_state *state)
2142{
2143 u16 i;
2144 u16 coff_pow = 0x2800;
2145
2146 state->seg_mask = 0x1fff; /* All 13 segments enabled */
77e2c0f5 2147
173a64cb
PB
2148 /* ---- COFF ---- Carloff, the most robust --- */
2149 if (state->isdbt_cfg_loaded == 0) { /* if not Sound Broadcasting mode : put default values for 13 segments */
2150 dib8000_write_word(state, 180, (16 << 6) | 9);
2151 dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
2152 coff_pow = 0x2800;
2153 for (i = 0; i < 6; i++)
2154 dib8000_write_word(state, 181+i, coff_pow);
77e2c0f5 2155
173a64cb
PB
2156 /* P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1 */
2157 /* 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 */
2158 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
77e2c0f5 2159
173a64cb
PB
2160 /* P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6 */
2161 dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
2162 /* P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1 */
2163 dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
2164
2165 dib8000_write_word(state, 228, 0); /* default value */
2166 dib8000_write_word(state, 265, 31); /* default value */
2167 dib8000_write_word(state, 205, 0x200f); /* init value */
2168 }
2169
2170 /*
2171 * make the cpil_coff_lock more robust but slower p_coff_winlen
2172 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
2173 */
2174
2175 if (state->cfg.pll->ifreq == 0)
2176 dib8000_write_word(state, 266, ~state->seg_mask | state->seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
77e2c0f5 2177
173a64cb
PB
2178 dib8000_load_ana_fe_coefs(state, ana_fe_coeff_13seg);
2179}
2180
2181static void dib8000_set_subchannel_prbs(struct dib8000_state *state, u16 init_prbs)
2182{
2183 u16 reg_1;
2184
2185 reg_1 = dib8000_read_word(state, 1);
2186 dib8000_write_word(state, 1, (init_prbs << 2) | (reg_1 & 0x3)); /* ADDR 1 */
2187}
2188
2189static void dib8000_small_fine_tune(struct dib8000_state *state)
2190{
2191 u16 i;
2192 const s16 *ncoeff;
c82056d0 2193 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
77e2c0f5 2194
173a64cb
PB
2195 dib8000_write_word(state, 352, state->seg_diff_mask);
2196 dib8000_write_word(state, 353, state->seg_mask);
77e2c0f5 2197
173a64cb 2198 /* P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5 */
c82056d0 2199 dib8000_write_word(state, 351, (c->isdbt_sb_mode << 9) | (c->isdbt_sb_mode << 8) | (13 << 4) | 5);
77e2c0f5 2200
c82056d0 2201 if (c->isdbt_sb_mode) {
173a64cb 2202 /* ---- SMALL ---- */
c82056d0 2203 switch (c->transmission_mode) {
77e2c0f5 2204 case TRANSMISSION_MODE_2K:
c82056d0
MCC
2205 if (c->isdbt_partial_reception == 0) { /* 1-seg */
2206 if (c->layer[0].modulation == DQPSK) /* DQPSK */
173a64cb
PB
2207 ncoeff = coeff_2k_sb_1seg_dqpsk;
2208 else /* QPSK or QAM */
2209 ncoeff = coeff_2k_sb_1seg;
2210 } else { /* 3-segments */
c82056d0
MCC
2211 if (c->layer[0].modulation == DQPSK) { /* DQPSK on central segment */
2212 if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
173a64cb
PB
2213 ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
2214 else /* QPSK or QAM on external segments */
2215 ncoeff = coeff_2k_sb_3seg_0dqpsk;
2216 } else { /* QPSK or QAM on central segment */
c82056d0 2217 if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
173a64cb
PB
2218 ncoeff = coeff_2k_sb_3seg_1dqpsk;
2219 else /* QPSK or QAM on external segments */
2220 ncoeff = coeff_2k_sb_3seg;
2221 }
77e2c0f5 2222 }
173a64cb 2223 break;
77e2c0f5 2224 case TRANSMISSION_MODE_4K:
c82056d0
MCC
2225 if (c->isdbt_partial_reception == 0) { /* 1-seg */
2226 if (c->layer[0].modulation == DQPSK) /* DQPSK */
173a64cb
PB
2227 ncoeff = coeff_4k_sb_1seg_dqpsk;
2228 else /* QPSK or QAM */
2229 ncoeff = coeff_4k_sb_1seg;
2230 } else { /* 3-segments */
c82056d0
MCC
2231 if (c->layer[0].modulation == DQPSK) { /* DQPSK on central segment */
2232 if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
173a64cb
PB
2233 ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
2234 else /* QPSK or QAM on external segments */
2235 ncoeff = coeff_4k_sb_3seg_0dqpsk;
2236 } else { /* QPSK or QAM on central segment */
c82056d0 2237 if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
173a64cb
PB
2238 ncoeff = coeff_4k_sb_3seg_1dqpsk;
2239 else /* QPSK or QAM on external segments */
2240 ncoeff = coeff_4k_sb_3seg;
77e2c0f5 2241 }
77e2c0f5 2242 }
173a64cb 2243 break;
77e2c0f5
PB
2244 case TRANSMISSION_MODE_AUTO:
2245 case TRANSMISSION_MODE_8K:
2246 default:
c82056d0
MCC
2247 if (c->isdbt_partial_reception == 0) { /* 1-seg */
2248 if (c->layer[0].modulation == DQPSK) /* DQPSK */
173a64cb
PB
2249 ncoeff = coeff_8k_sb_1seg_dqpsk;
2250 else /* QPSK or QAM */
2251 ncoeff = coeff_8k_sb_1seg;
2252 } else { /* 3-segments */
c82056d0
MCC
2253 if (c->layer[0].modulation == DQPSK) { /* DQPSK on central segment */
2254 if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
173a64cb
PB
2255 ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
2256 else /* QPSK or QAM on external segments */
2257 ncoeff = coeff_8k_sb_3seg_0dqpsk;
2258 } else { /* QPSK or QAM on central segment */
c82056d0 2259 if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
173a64cb
PB
2260 ncoeff = coeff_8k_sb_3seg_1dqpsk;
2261 else /* QPSK or QAM on external segments */
2262 ncoeff = coeff_8k_sb_3seg;
77e2c0f5 2263 }
77e2c0f5 2264 }
173a64cb 2265 break;
77e2c0f5 2266 }
173a64cb 2267
77e2c0f5
PB
2268 for (i = 0; i < 8; i++)
2269 dib8000_write_word(state, 343 + i, ncoeff[i]);
6e8fdbd0 2270 }
173a64cb 2271}
77e2c0f5 2272
173a64cb
PB
2273static const u16 coff_thres_1seg[3] = {300, 150, 80};
2274static const u16 coff_thres_3seg[3] = {350, 300, 250};
2275static void dib8000_set_sb_channel(struct dib8000_state *state)
2276{
c82056d0 2277 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
173a64cb
PB
2278 const u16 *coff;
2279 u16 i;
77e2c0f5 2280
c82056d0 2281 if (c->transmission_mode == TRANSMISSION_MODE_2K || c->transmission_mode == TRANSMISSION_MODE_4K) {
173a64cb
PB
2282 dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); /* adp_pass =1 */
2283 dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); /* pha3_force_pha_shift = 1 */
2284 } else {
2285 dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); /* adp_pass =0 */
2286 dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); /* pha3_force_pha_shift = 0 */
2287 }
77e2c0f5 2288
c82056d0 2289 if (c->isdbt_partial_reception == 1) /* 3-segments */
173a64cb
PB
2290 state->seg_mask = 0x00E0;
2291 else /* 1-segment */
2292 state->seg_mask = 0x0040;
77e2c0f5 2293
173a64cb 2294 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
77e2c0f5 2295
173a64cb
PB
2296 /* ---- COFF ---- Carloff, the most robust --- */
2297 /* P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64, 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 */
c82056d0 2298 dib8000_write_word(state, 187, (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~c->isdbt_partial_reception & 1) << 2) | 0x3);
77e2c0f5 2299
173a64cb
PB
2300 dib8000_write_word(state, 340, (16 << 6) | (8 << 0)); /* P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8 */
2301 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));/* P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1 */
77e2c0f5 2302
173a64cb 2303 /* Sound Broadcasting mode 1 seg */
c82056d0 2304 if (c->isdbt_partial_reception == 0) {
173a64cb
PB
2305 /* 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) */
2306 if (state->mode == 3)
2307 dib8000_write_word(state, 180, 0x1fcf | ((state->mode - 1) << 14));
2308 else
2309 dib8000_write_word(state, 180, 0x0fcf | ((state->mode - 1) << 14));
77e2c0f5 2310
173a64cb
PB
2311 /* P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4 */
2312 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
2313 coff = &coff_thres_1seg[0];
2314 } else { /* Sound Broadcasting mode 3 seg */
2315 dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
2316 /* P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4 */
2317 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
2318 coff = &coff_thres_3seg[0];
2319 }
77e2c0f5 2320
173a64cb
PB
2321 dib8000_write_word(state, 228, 1); /* P_2d_mode_byp=1 */
2322 dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); /* P_cspu_win_cut = 0 */
2323
c82056d0 2324 if (c->isdbt_partial_reception == 0 && c->transmission_mode == TRANSMISSION_MODE_2K)
173a64cb
PB
2325 dib8000_write_word(state, 265, 15); /* P_equal_noise_sel = 15 */
2326
2327 /* Write COFF thres */
2328 for (i = 0 ; i < 3; i++) {
2329 dib8000_write_word(state, 181+i, coff[i]);
2330 dib8000_write_word(state, 184+i, coff[i]);
77e2c0f5 2331 }
77e2c0f5 2332
173a64cb
PB
2333 /*
2334 * make the cpil_coff_lock more robust but slower p_coff_winlen
77e2c0f5
PB
2335 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
2336 */
77e2c0f5 2337
173a64cb
PB
2338 dib8000_write_word(state, 266, ~state->seg_mask | state->seg_diff_mask); /* P_equal_noise_seg_inh */
2339
c82056d0 2340 if (c->isdbt_partial_reception == 0)
173a64cb 2341 dib8000_write_word(state, 178, 64); /* P_fft_powrange = 64 */
77e2c0f5 2342 else
173a64cb
PB
2343 dib8000_write_word(state, 178, 32); /* P_fft_powrange = 32 */
2344}
77e2c0f5 2345
173a64cb
PB
2346static void dib8000_set_isdbt_common_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
2347{
2348 u16 p_cfr_left_edge = 0, p_cfr_right_edge = 0;
2349 u16 tmcc_pow = 0, ana_gain = 0, tmp = 0, i = 0, nbseg_diff = 0 ;
2350 u16 max_constellation = DQPSK;
2351 int init_prbs;
c82056d0 2352 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
77e2c0f5 2353
dde8e115
MCC
2354 if (autosearching)
2355 c->isdbt_partial_reception = 1;
2356
173a64cb
PB
2357 /* P_mode */
2358 dib8000_write_word(state, 10, (seq << 4));
2359
2360 /* init mode */
2361 state->mode = fft_to_mode(state);
2362
2363 /* set guard */
2364 tmp = dib8000_read_word(state, 1);
c82056d0 2365 dib8000_write_word(state, 1, (tmp&0xfffc) | (c->guard_interval & 0x3));
173a64cb 2366
c82056d0 2367 dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) | ((c->isdbt_partial_reception & 1) << 5) | ((c->isdbt_sb_mode & 1) << 4));
173a64cb
PB
2368
2369 /* signal optimization parameter */
c82056d0
MCC
2370 if (c->isdbt_partial_reception) {
2371 state->seg_diff_mask = (c->layer[0].modulation == DQPSK) << permu_seg[0];
173a64cb 2372 for (i = 1; i < 3; i++)
c82056d0 2373 nbseg_diff += (c->layer[i].modulation == DQPSK) * c->layer[i].segment_count;
173a64cb
PB
2374 for (i = 0; i < nbseg_diff; i++)
2375 state->seg_diff_mask |= 1 << permu_seg[i+1];
2376 } else {
2377 for (i = 0; i < 3; i++)
c82056d0 2378 nbseg_diff += (c->layer[i].modulation == DQPSK) * c->layer[i].segment_count;
173a64cb
PB
2379 for (i = 0; i < nbseg_diff; i++)
2380 state->seg_diff_mask |= 1 << permu_seg[i];
2381 }
2382
2383 if (state->seg_diff_mask)
2384 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
2385 else
2386 dib8000_write_word(state, 268, (2 << 9) | 39); /*init value */
2387
2388 for (i = 0; i < 3; i++)
2389 max_constellation = dib8000_set_layer(state, i, max_constellation);
2390 if (autosearching == 0) {
c82056d0
MCC
2391 state->layer_b_nb_seg = c->layer[1].segment_count;
2392 state->layer_c_nb_seg = c->layer[2].segment_count;
77e2c0f5
PB
2393 }
2394
173a64cb
PB
2395 /* WRITE: Mode & Diff mask */
2396 dib8000_write_word(state, 0, (state->mode << 13) | state->seg_diff_mask);
2397
2398 state->differential_constellation = (state->seg_diff_mask != 0);
2399
2400 /* channel estimation fine configuration */
2401 ana_gain = dib8000_adp_fine_tune(state, max_constellation);
2402
2403 /* update ana_gain depending on max constellation */
2404 dib8000_update_ana_gain(state, ana_gain);
2405
2406 /* ---- ANA_FE ---- */
c82056d0 2407 if (c->isdbt_partial_reception) /* 3-segments */
173a64cb
PB
2408 dib8000_load_ana_fe_coefs(state, ana_fe_coeff_3seg);
2409 else
2410 dib8000_load_ana_fe_coefs(state, ana_fe_coeff_1seg); /* 1-segment */
2411
2412 /* TSB or ISDBT ? apply it now */
c82056d0 2413 if (c->isdbt_sb_mode) {
173a64cb 2414 dib8000_set_sb_channel(state);
746f7ae0 2415 if (c->isdbt_sb_subchannel < 14)
c82056d0 2416 init_prbs = dib8000_get_init_prbs(state, c->isdbt_sb_subchannel);
173a64cb
PB
2417 else
2418 init_prbs = 0;
2419 } else {
2420 dib8000_set_13seg_channel(state);
2421 init_prbs = 0xfff;
2422 }
2423
2424 /* SMALL */
2425 dib8000_small_fine_tune(state);
2426
2427 dib8000_set_subchannel_prbs(state, init_prbs);
77e2c0f5 2428
173a64cb 2429 /* ---- CHAN_BLK ---- */
77e2c0f5 2430 for (i = 0; i < 13; i++) {
173a64cb
PB
2431 if ((((~state->seg_diff_mask) >> i) & 1) == 1) {
2432 p_cfr_left_edge += (1 << i) * ((i == 0) || ((((state->seg_mask & (~state->seg_diff_mask)) >> (i - 1)) & 1) == 0));
2433 p_cfr_right_edge += (1 << i) * ((i == 12) || ((((state->seg_mask & (~state->seg_diff_mask)) >> (i + 1)) & 1) == 0));
77e2c0f5
PB
2434 }
2435 }
173a64cb
PB
2436 dib8000_write_word(state, 222, p_cfr_left_edge); /* p_cfr_left_edge */
2437 dib8000_write_word(state, 223, p_cfr_right_edge); /* p_cfr_right_edge */
2438 /* "P_cspu_left_edge" & "P_cspu_right_edge" not used => do not care */
2439
2440 dib8000_write_word(state, 189, ~state->seg_mask | state->seg_diff_mask); /* P_lmod4_seg_inh */
2441 dib8000_write_word(state, 192, ~state->seg_mask | state->seg_diff_mask); /* P_pha3_seg_inh */
2442 dib8000_write_word(state, 225, ~state->seg_mask | state->seg_diff_mask); /* P_tac_seg_inh */
2443
2444 if (!autosearching)
2445 dib8000_write_word(state, 288, (~state->seg_mask | state->seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
2446 else
2447 dib8000_write_word(state, 288, 0x1fff); /*disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels. */
2448
2449 dib8000_write_word(state, 211, state->seg_mask & (~state->seg_diff_mask)); /* P_des_seg_enabled */
2450 dib8000_write_word(state, 287, ~state->seg_mask | 0x1000); /* P_tmcc_seg_inh */
2451
2452 dib8000_write_word(state, 178, 32); /* P_fft_powrange = 32 */
2453
2454 /* ---- TMCC ---- */
77e2c0f5 2455 for (i = 0; i < 3; i++)
c82056d0 2456 tmcc_pow += (((c->layer[i].modulation == DQPSK) * 4 + 1) * c->layer[i].segment_count) ;
173a64cb
PB
2457
2458 /* Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9); */
2459 /* Threshold is set at 1/4 of max power. */
2460 tmcc_pow *= (1 << (9-2));
2461 dib8000_write_word(state, 290, tmcc_pow); /* P_tmcc_dec_thres_2k */
2462 dib8000_write_word(state, 291, tmcc_pow); /* P_tmcc_dec_thres_4k */
2463 dib8000_write_word(state, 292, tmcc_pow); /* P_tmcc_dec_thres_8k */
2464 /*dib8000_write_word(state, 287, (1 << 13) | 0x1000 ); */
77e2c0f5 2465
173a64cb 2466 /* ---- PHA3 ---- */
77e2c0f5 2467 if (state->isdbt_cfg_loaded == 0)
173a64cb 2468 dib8000_write_word(state, 250, 3285); /* p_2d_hspeed_thr0 */
77e2c0f5 2469
173a64cb
PB
2470 state->isdbt_cfg_loaded = 0;
2471}
2472
6f7ee06f
MCC
2473static u32 dib8000_wait_lock(struct dib8000_state *state, u32 internal,
2474 u32 wait0_ms, u32 wait1_ms, u32 wait2_ms)
173a64cb 2475{
13122f98
MCC
2476 u32 value = 0; /* P_search_end0 wait time */
2477 u16 reg = 11; /* P_search_end0 start addr */
77e2c0f5 2478
173a64cb
PB
2479 for (reg = 11; reg < 16; reg += 2) {
2480 if (reg == 11) {
2481 if (state->revision == 0x8090)
13122f98 2482 value = internal * wait1_ms;
173a64cb 2483 else
13122f98 2484 value = internal * wait0_ms;
173a64cb 2485 } else if (reg == 13)
13122f98 2486 value = internal * wait1_ms;
173a64cb 2487 else if (reg == 15)
13122f98 2488 value = internal * wait2_ms;
173a64cb
PB
2489 dib8000_write_word(state, reg, (u16)((value >> 16) & 0xffff));
2490 dib8000_write_word(state, (reg + 1), (u16)(value & 0xffff));
2491 }
2492 return value;
77e2c0f5
PB
2493}
2494
2495static int dib8000_autosearch_start(struct dvb_frontend *fe)
2496{
77e2c0f5 2497 struct dib8000_state *state = fe->demodulator_priv;
c82056d0 2498 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
173a64cb
PB
2499 u8 slist = 0;
2500 u32 value, internal = state->cfg.pll->internal;
77e2c0f5 2501
173a64cb
PB
2502 if (state->revision == 0x8090)
2503 internal = dib8000_read32(state, 23) / 1000;
77e2c0f5 2504
d67350f8
OG
2505 if ((state->revision >= 0x8002) &&
2506 (state->autosearch_state == AS_SEARCHING_FFT)) {
173a64cb
PB
2507 dib8000_write_word(state, 37, 0x0065); /* P_ctrl_pha_off_max default values */
2508 dib8000_write_word(state, 116, 0x0000); /* P_ana_gain to 0 */
77e2c0f5 2509
173a64cb
PB
2510 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x1fff) | (0 << 13) | (1 << 15)); /* P_mode = 0, P_restart_search=1 */
2511 dib8000_write_word(state, 1, (dib8000_read_word(state, 1) & 0xfffc) | 0); /* P_guard = 0 */
2512 dib8000_write_word(state, 6, 0); /* P_lock0_mask = 0 */
2513 dib8000_write_word(state, 7, 0); /* P_lock1_mask = 0 */
2514 dib8000_write_word(state, 8, 0); /* P_lock2_mask = 0 */
2515 dib8000_write_word(state, 10, (dib8000_read_word(state, 10) & 0x200) | (16 << 4) | (0 << 0)); /* P_search_list=16, P_search_maxtrial=0 */
2516
2517 if (state->revision == 0x8090)
2518 value = dib8000_wait_lock(state, internal, 10, 10, 10); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2519 else
2520 value = dib8000_wait_lock(state, internal, 20, 20, 20); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2521
2522 dib8000_write_word(state, 17, 0);
2523 dib8000_write_word(state, 18, 200); /* P_search_rstst = 200 */
2524 dib8000_write_word(state, 19, 0);
2525 dib8000_write_word(state, 20, 400); /* P_search_rstend = 400 */
2526 dib8000_write_word(state, 21, (value >> 16) & 0xffff); /* P_search_checkst */
2527 dib8000_write_word(state, 22, value & 0xffff);
2528
2529 if (state->revision == 0x8090)
2530 dib8000_write_word(state, 32, (dib8000_read_word(state, 32) & 0xf0ff) | (0 << 8)); /* P_corm_alpha = 0 */
2531 else
2532 dib8000_write_word(state, 32, (dib8000_read_word(state, 32) & 0xf0ff) | (9 << 8)); /* P_corm_alpha = 3 */
2533 dib8000_write_word(state, 355, 2); /* P_search_param_max = 2 */
2534
2535 /* P_search_param_select = (1 | 1<<4 | 1 << 8) */
2536 dib8000_write_word(state, 356, 0);
2537 dib8000_write_word(state, 357, 0x111);
2538
2539 dib8000_write_word(state, 770, (dib8000_read_word(state, 770) & 0xdfff) | (1 << 13)); /* P_restart_ccg = 1 */
2540 dib8000_write_word(state, 770, (dib8000_read_word(state, 770) & 0xdfff) | (0 << 13)); /* P_restart_ccg = 0 */
2541 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x7ff) | (0 << 15) | (1 << 13)); /* P_restart_search = 0; */
d67350f8
OG
2542 } else if ((state->revision >= 0x8002) &&
2543 (state->autosearch_state == AS_SEARCHING_GUARD)) {
c82056d0
MCC
2544 c->transmission_mode = TRANSMISSION_MODE_8K;
2545 c->guard_interval = GUARD_INTERVAL_1_8;
2546 c->inversion = 0;
2547 c->layer[0].modulation = QAM_64;
2548 c->layer[0].fec = FEC_2_3;
2549 c->layer[0].interleaving = 0;
2550 c->layer[0].segment_count = 13;
173a64cb
PB
2551
2552 slist = 16;
c82056d0 2553 c->transmission_mode = state->found_nfft;
173a64cb
PB
2554
2555 dib8000_set_isdbt_common_channel(state, slist, 1);
2556
2557 /* set lock_mask values */
2558 dib8000_write_word(state, 6, 0x4);
2559 if (state->revision == 0x8090)
2560 dib8000_write_word(state, 7, ((1 << 12) | (1 << 11) | (1 << 10)));/* tmcc_dec_lock, tmcc_sync_lock, tmcc_data_lock, tmcc_bch_uncor */
2561 else
2562 dib8000_write_word(state, 7, 0x8);
2563 dib8000_write_word(state, 8, 0x1000);
2564
2565 /* set lock_mask wait time values */
2566 if (state->revision == 0x8090)
2567 dib8000_wait_lock(state, internal, 50, 100, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2568 else
2569 dib8000_wait_lock(state, internal, 50, 200, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2570
2571 dib8000_write_word(state, 355, 3); /* P_search_param_max = 3 */
2572
2573 /* P_search_param_select = 0xf; look for the 4 different guard intervals */
2574 dib8000_write_word(state, 356, 0);
2575 dib8000_write_word(state, 357, 0xf);
2576
2577 value = dib8000_read_word(state, 0);
2578 dib8000_write_word(state, 0, (u16)((1 << 15) | value));
2579 dib8000_read_word(state, 1284); /* reset the INT. n_irq_pending */
2580 dib8000_write_word(state, 0, (u16)value);
77e2c0f5 2581 } else {
c82056d0
MCC
2582 c->inversion = 0;
2583 c->layer[0].modulation = QAM_64;
2584 c->layer[0].fec = FEC_2_3;
2585 c->layer[0].interleaving = 0;
2586 c->layer[0].segment_count = 13;
2587 if (!c->isdbt_sb_mode)
2588 c->layer[0].segment_count = 13;
173a64cb
PB
2589
2590 /* choose the right list, in sb, always do everything */
c82056d0 2591 if (c->isdbt_sb_mode) {
173a64cb
PB
2592 slist = 7;
2593 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
77e2c0f5 2594 } else {
c82056d0
MCC
2595 if (c->guard_interval == GUARD_INTERVAL_AUTO) {
2596 if (c->transmission_mode == TRANSMISSION_MODE_AUTO) {
2597 c->transmission_mode = TRANSMISSION_MODE_8K;
2598 c->guard_interval = GUARD_INTERVAL_1_8;
173a64cb
PB
2599 slist = 7;
2600 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); /* P_mode = 1 to have autosearch start ok with mode2 */
2601 } else {
c82056d0 2602 c->guard_interval = GUARD_INTERVAL_1_8;
173a64cb
PB
2603 slist = 3;
2604 }
2605 } else {
c82056d0
MCC
2606 if (c->transmission_mode == TRANSMISSION_MODE_AUTO) {
2607 c->transmission_mode = TRANSMISSION_MODE_8K;
173a64cb
PB
2608 slist = 2;
2609 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); /* P_mode = 1 */
2610 } else
2611 slist = 0;
2612 }
77e2c0f5 2613 }
173a64cb 2614 dprintk("Using list for autosearch : %d", slist);
77e2c0f5 2615
173a64cb 2616 dib8000_set_isdbt_common_channel(state, slist, 1);
77e2c0f5 2617
173a64cb 2618 /* set lock_mask values */
77e2c0f5 2619 dib8000_write_word(state, 6, 0x4);
173a64cb
PB
2620 if (state->revision == 0x8090)
2621 dib8000_write_word(state, 7, (1 << 12) | (1 << 11) | (1 << 10));
2622 else
2623 dib8000_write_word(state, 7, 0x8);
77e2c0f5
PB
2624 dib8000_write_word(state, 8, 0x1000);
2625
173a64cb
PB
2626 /* set lock_mask wait time values */
2627 if (state->revision == 0x8090)
2628 dib8000_wait_lock(state, internal, 50, 200, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2629 else
2630 dib8000_wait_lock(state, internal, 50, 100, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
77e2c0f5
PB
2631
2632 value = dib8000_read_word(state, 0);
173a64cb
PB
2633 dib8000_write_word(state, 0, (u16)((1 << 15) | value));
2634 dib8000_read_word(state, 1284); /* reset the INT. n_irq_pending */
2635 dib8000_write_word(state, 0, (u16)value);
77e2c0f5 2636 }
77e2c0f5
PB
2637 return 0;
2638}
2639
2640static int dib8000_autosearch_irq(struct dvb_frontend *fe)
2641{
2642 struct dib8000_state *state = fe->demodulator_priv;
2643 u16 irq_pending = dib8000_read_word(state, 1284);
2644
d67350f8
OG
2645 if ((state->revision >= 0x8002) &&
2646 (state->autosearch_state == AS_SEARCHING_FFT)) {
173a64cb
PB
2647 if (irq_pending & 0x1) {
2648 dprintk("dib8000_autosearch_irq: max correlation result available");
2649 return 3;
2650 }
2651 } else {
2652 if (irq_pending & 0x1) { /* failed */
2653 dprintk("dib8000_autosearch_irq failed");
2654 return 1;
2655 }
77e2c0f5 2656
173a64cb
PB
2657 if (irq_pending & 0x2) { /* succeeded */
2658 dprintk("dib8000_autosearch_irq succeeded");
2659 return 2;
2660 }
77e2c0f5
PB
2661 }
2662
2663 return 0; // still pending
2664}
2665
173a64cb 2666static void dib8000_viterbi_state(struct dib8000_state *state, u8 onoff)
77e2c0f5 2667{
173a64cb 2668 u16 tmp;
77e2c0f5 2669
173a64cb
PB
2670 tmp = dib8000_read_word(state, 771);
2671 if (onoff) /* start P_restart_chd : channel_decoder */
2672 dib8000_write_word(state, 771, tmp & 0xfffd);
2673 else /* stop P_restart_chd : channel_decoder */
2674 dib8000_write_word(state, 771, tmp | (1<<1));
2675}
77e2c0f5 2676
173a64cb
PB
2677static void dib8000_set_dds(struct dib8000_state *state, s32 offset_khz)
2678{
2679 s16 unit_khz_dds_val;
2680 u32 abs_offset_khz = ABS(offset_khz);
2681 u32 dds = state->cfg.pll->ifreq & 0x1ffffff;
2682 u8 invert = !!(state->cfg.pll->ifreq & (1 << 25));
2683 u8 ratio;
e04f4b2d 2684
173a64cb
PB
2685 if (state->revision == 0x8090) {
2686 ratio = 4;
2687 unit_khz_dds_val = (1<<26) / (dib8000_read32(state, 23) / 1000);
2688 if (offset_khz < 0)
2689 dds = (1 << 26) - (abs_offset_khz * unit_khz_dds_val);
2690 else
2691 dds = (abs_offset_khz * unit_khz_dds_val);
77e2c0f5 2692
173a64cb
PB
2693 if (invert)
2694 dds = (1<<26) - dds;
2695 } else {
2696 ratio = 2;
2697 unit_khz_dds_val = (u16) (67108864 / state->cfg.pll->internal);
77e2c0f5 2698
173a64cb
PB
2699 if (offset_khz < 0)
2700 unit_khz_dds_val *= -1;
77e2c0f5 2701
173a64cb
PB
2702 /* IF tuner */
2703 if (invert)
2704 dds -= abs_offset_khz * unit_khz_dds_val;
2705 else
2706 dds += abs_offset_khz * unit_khz_dds_val;
77e2c0f5 2707 }
77e2c0f5 2708
173a64cb 2709 dprintk("setting a DDS frequency offset of %c%dkHz", invert ? '-' : ' ', dds / unit_khz_dds_val);
77e2c0f5 2710
173a64cb
PB
2711 if (abs_offset_khz <= (state->cfg.pll->internal / ratio)) {
2712 /* Max dds offset is the half of the demod freq */
2713 dib8000_write_word(state, 26, invert);
2714 dib8000_write_word(state, 27, (u16)(dds >> 16) & 0x1ff);
2715 dib8000_write_word(state, 28, (u16)(dds & 0xffff));
2716 }
2717}
77e2c0f5 2718
173a64cb
PB
2719static void dib8000_set_frequency_offset(struct dib8000_state *state)
2720{
c82056d0 2721 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
173a64cb
PB
2722 int i;
2723 u32 current_rf;
2724 int total_dds_offset_khz;
2725
2726 if (state->fe[0]->ops.tuner_ops.get_frequency)
2727 state->fe[0]->ops.tuner_ops.get_frequency(state->fe[0], &current_rf);
2728 else
c82056d0 2729 current_rf = c->frequency;
173a64cb 2730 current_rf /= 1000;
c82056d0 2731 total_dds_offset_khz = (int)current_rf - (int)c->frequency / 1000;
173a64cb 2732
c82056d0
MCC
2733 if (c->isdbt_sb_mode) {
2734 state->subchannel = c->isdbt_sb_subchannel;
77e2c0f5 2735
173a64cb 2736 i = dib8000_read_word(state, 26) & 1; /* P_dds_invspec */
c82056d0 2737 dib8000_write_word(state, 26, c->inversion ^ i);
77e2c0f5 2738
173a64cb 2739 if (state->cfg.pll->ifreq == 0) { /* low if tuner */
c82056d0 2740 if ((c->inversion ^ i) == 0)
173a64cb
PB
2741 dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
2742 } else {
c82056d0 2743 if ((c->inversion ^ i) == 0)
173a64cb 2744 total_dds_offset_khz *= -1;
77e2c0f5 2745 }
173a64cb
PB
2746 }
2747
c82056d0 2748 dprintk("%dkhz tuner offset (frequency = %dHz & current_rf = %dHz) total_dds_offset_hz = %d", c->frequency - current_rf, c->frequency, current_rf, total_dds_offset_khz);
173a64cb
PB
2749
2750 /* apply dds offset now */
2751 dib8000_set_dds(state, total_dds_offset_khz);
2752}
2753
2754static u16 LUT_isdbt_symbol_duration[4] = { 26, 101, 63 };
6f7ee06f
MCC
2755
2756static u32 dib8000_get_symbol_duration(struct dib8000_state *state)
173a64cb 2757{
c82056d0 2758 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
173a64cb
PB
2759 u16 i;
2760
c82056d0 2761 switch (c->transmission_mode) {
173a64cb
PB
2762 case TRANSMISSION_MODE_2K:
2763 i = 0;
2764 break;
2765 case TRANSMISSION_MODE_4K:
2766 i = 2;
2767 break;
2768 default:
2769 case TRANSMISSION_MODE_AUTO:
2770 case TRANSMISSION_MODE_8K:
2771 i = 1;
2772 break;
2773 }
77e2c0f5 2774
c82056d0 2775 return (LUT_isdbt_symbol_duration[i] / (c->bandwidth_hz / 1000)) + 1;
173a64cb 2776}
77e2c0f5 2777
173a64cb
PB
2778static void dib8000_set_isdbt_loop_params(struct dib8000_state *state, enum param_loop_step loop_step)
2779{
c82056d0 2780 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
173a64cb 2781 u16 reg_32 = 0, reg_37 = 0;
77e2c0f5 2782
173a64cb
PB
2783 switch (loop_step) {
2784 case LOOP_TUNE_1:
c82056d0
MCC
2785 if (c->isdbt_sb_mode) {
2786 if (c->isdbt_partial_reception == 0) {
173a64cb
PB
2787 reg_32 = ((11 - state->mode) << 12) | (6 << 8) | 0x40; /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x40 */
2788 reg_37 = (3 << 5) | (0 << 4) | (10 - state->mode); /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (10-P_mode) */
2789 } else { /* Sound Broadcasting mode 3 seg */
2790 reg_32 = ((10 - state->mode) << 12) | (6 << 8) | 0x60; /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x60 */
2791 reg_37 = (3 << 5) | (0 << 4) | (9 - state->mode); /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (9-P_mode) */
2792 }
2793 } else { /* 13-seg start conf offset loop parameters */
2794 reg_32 = ((9 - state->mode) << 12) | (6 << 8) | 0x80; /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
2795 reg_37 = (3 << 5) | (0 << 4) | (8 - state->mode); /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = 9 */
2796 }
2797 break;
2798 case LOOP_TUNE_2:
c82056d0
MCC
2799 if (c->isdbt_sb_mode) {
2800 if (c->isdbt_partial_reception == 0) { /* Sound Broadcasting mode 1 seg */
173a64cb
PB
2801 reg_32 = ((13-state->mode) << 12) | (6 << 8) | 0x40; /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40*/
2802 reg_37 = (12-state->mode) | ((5 + state->mode) << 5);
2803 } else { /* Sound Broadcasting mode 3 seg */
2804 reg_32 = ((12-state->mode) << 12) | (6 << 8) | 0x60; /* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60 */
2805 reg_37 = (11-state->mode) | ((5 + state->mode) << 5);
2806 }
2807 } else { /* 13 seg */
2808 reg_32 = ((11-state->mode) << 12) | (6 << 8) | 0x80; /* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80 */
2809 reg_37 = ((5+state->mode) << 5) | (10 - state->mode);
2810 }
2811 break;
77e2c0f5 2812 }
173a64cb
PB
2813 dib8000_write_word(state, 32, reg_32);
2814 dib8000_write_word(state, 37, reg_37);
2815}
77e2c0f5 2816
173a64cb
PB
2817static void dib8000_demod_restart(struct dib8000_state *state)
2818{
2819 dib8000_write_word(state, 770, 0x4000);
2820 dib8000_write_word(state, 770, 0x0000);
2821 return;
2822}
2823
2824static void dib8000_set_sync_wait(struct dib8000_state *state)
2825{
c82056d0 2826 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
173a64cb
PB
2827 u16 sync_wait = 64;
2828
2829 /* P_dvsy_sync_wait - reuse mode */
c82056d0 2830 switch (c->transmission_mode) {
173a64cb
PB
2831 case TRANSMISSION_MODE_8K:
2832 sync_wait = 256;
2833 break;
2834 case TRANSMISSION_MODE_4K:
2835 sync_wait = 128;
2836 break;
2837 default:
2838 case TRANSMISSION_MODE_2K:
2839 sync_wait = 64;
2840 break;
2841 }
2842
2843 if (state->cfg.diversity_delay == 0)
c82056d0 2844 sync_wait = (sync_wait * (1 << (c->guard_interval)) * 3) / 2 + 48; /* add 50% SFN margin + compensate for one DVSY-fifo */
173a64cb 2845 else
c82056d0 2846 sync_wait = (sync_wait * (1 << (c->guard_interval)) * 3) / 2 + state->cfg.diversity_delay; /* add 50% SFN margin + compensate for DVSY-fifo */
173a64cb
PB
2847
2848 dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | (sync_wait << 4));
2849}
2850
2851static u32 dib8000_get_timeout(struct dib8000_state *state, u32 delay, enum timeout_mode mode)
2852{
2853 if (mode == SYMBOL_DEPENDENT_ON)
2854 return systime() + (delay * state->symbol_duration);
0c32dbd7 2855 else
173a64cb
PB
2856 return systime() + delay;
2857}
77e2c0f5 2858
173a64cb
PB
2859static s32 dib8000_get_status(struct dvb_frontend *fe)
2860{
2861 struct dib8000_state *state = fe->demodulator_priv;
2862 return state->status;
2863}
77e2c0f5 2864
d44913c1 2865static enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
173a64cb
PB
2866{
2867 struct dib8000_state *state = fe->demodulator_priv;
2868 return state->tune_state;
2869}
173a64cb 2870
d44913c1 2871static int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
173a64cb
PB
2872{
2873 struct dib8000_state *state = fe->demodulator_priv;
2874
2875 state->tune_state = tune_state;
2876 return 0;
2877}
173a64cb
PB
2878
2879static int dib8000_tune_restart_from_demod(struct dvb_frontend *fe)
2880{
2881 struct dib8000_state *state = fe->demodulator_priv;
2882
2883 state->status = FE_STATUS_TUNE_PENDING;
2884 state->tune_state = CT_DEMOD_START;
2885 return 0;
2886}
2887
2888static u16 dib8000_read_lock(struct dvb_frontend *fe)
2889{
2890 struct dib8000_state *state = fe->demodulator_priv;
2891
2892 if (state->revision == 0x8090)
2893 return dib8000_read_word(state, 570);
2894 return dib8000_read_word(state, 568);
2895}
2896
2897static int dib8090p_init_sdram(struct dib8000_state *state)
2898{
2899 u16 reg = 0;
2900 dprintk("init sdram");
2901
2902 reg = dib8000_read_word(state, 274) & 0xfff0;
2903 dib8000_write_word(state, 274, reg | 0x7); /* P_dintlv_delay_ram = 7 because of MobileSdram */
2904
2905 dib8000_write_word(state, 1803, (7 << 2));
2906
2907 reg = dib8000_read_word(state, 1280);
2908 dib8000_write_word(state, 1280, reg | (1 << 2)); /* force restart P_restart_sdram */
2909 dib8000_write_word(state, 1280, reg); /* release restart P_restart_sdram */
2910
2911 return 0;
2912}
2913
ad976187
MCC
2914/**
2915 * is_manual_mode - Check if TMCC should be used for parameters settings
2916 * @c: struct dvb_frontend_properties
2917 *
2918 * By default, TMCC table should be used for parameter settings on most
2919 * usercases. However, sometimes it is desirable to lock the demod to
2920 * use the manual parameters.
2921 *
2922 * On manual mode, the current dib8000_tune state machine is very restrict:
2923 * It requires that both per-layer and per-transponder parameters to be
2924 * properly specified, otherwise the device won't lock.
2925 *
2926 * Check if all those conditions are properly satisfied before allowing
2927 * the device to use the manual frequency lock mode.
2928 */
2929static int is_manual_mode(struct dtv_frontend_properties *c)
2930{
2931 int i, n_segs = 0;
2932
2933 /* Use auto mode on DVB-T compat mode */
2934 if (c->delivery_system != SYS_ISDBT)
2935 return 0;
2936
2937 /*
2938 * Transmission mode is only detected on auto mode, currently
2939 */
2940 if (c->transmission_mode == TRANSMISSION_MODE_AUTO) {
2941 dprintk("transmission mode auto");
2942 return 0;
2943 }
2944
2945 /*
2946 * Guard interval is only detected on auto mode, currently
2947 */
2948 if (c->guard_interval == GUARD_INTERVAL_AUTO) {
2949 dprintk("guard interval auto");
2950 return 0;
2951 }
2952
2953 /*
2954 * If no layer is enabled, assume auto mode, as at least one
2955 * layer should be enabled
2956 */
2957 if (!c->isdbt_layer_enabled) {
2958 dprintk("no layer modulation specified");
2959 return 0;
2960 }
2961
2962 /*
2963 * Check if the per-layer parameters aren't auto and
2964 * disable a layer if segment count is 0 or invalid.
2965 */
2966 for (i = 0; i < 3; i++) {
2967 if (!(c->isdbt_layer_enabled & 1 << i))
2968 continue;
2969
2970 if ((c->layer[i].segment_count > 13) ||
2971 (c->layer[i].segment_count == 0)) {
2972 c->isdbt_layer_enabled &= ~(1 << i);
2973 continue;
2974 }
2975
2976 n_segs += c->layer[i].segment_count;
2977
2978 if ((c->layer[i].modulation == QAM_AUTO) ||
2979 (c->layer[i].fec == FEC_AUTO)) {
2980 dprintk("layer %c has either modulation or FEC auto",
2981 'A' + i);
2982 return 0;
2983 }
2984 }
2985
2986 /*
2987 * Userspace specified a wrong number of segments.
2988 * fallback to auto mode.
2989 */
2990 if (n_segs == 0 || n_segs > 13) {
2991 dprintk("number of segments is invalid");
2992 return 0;
2993 }
2994
2995 /* Everything looks ok for manual mode */
2996 return 1;
2997}
2998
173a64cb
PB
2999static int dib8000_tune(struct dvb_frontend *fe)
3000{
3001 struct dib8000_state *state = fe->demodulator_priv;
c82056d0 3002 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
173a64cb
PB
3003 enum frontend_tune_state *tune_state = &state->tune_state;
3004
3005 u16 locks, deeper_interleaver = 0, i;
3006 int ret = 1; /* 1 symbol duration (in 100us unit) delay most of the time */
3007
3008 u32 *timeout = &state->timeout;
3009 u32 now = systime();
3010#ifdef DIB8000_AGC_FREEZE
3011 u16 agc1, agc2;
3012#endif
3013
3014 u32 corm[4] = {0, 0, 0, 0};
3015 u8 find_index, max_value;
3016
3017#if 0
3018 if (*tune_state < CT_DEMOD_STOP)
3019 dprintk("IN: context status = %d, TUNE_STATE %d autosearch step = %u systime = %u", state->channel_parameters_set, *tune_state, state->autosearch_state, now);
3020#endif
3021
3022 switch (*tune_state) {
3023 case CT_DEMOD_START: /* 30 */
7fa676c6 3024 dib8000_reset_stats(fe);
6ef06e78 3025
7fa676c6
MCC
3026 if (state->revision == 0x8090)
3027 dib8090p_init_sdram(state);
3028 state->status = FE_STATUS_TUNE_PENDING;
3029 state->channel_parameters_set = is_manual_mode(c);
ad976187 3030
7fa676c6
MCC
3031 dprintk("Tuning channel on %s search mode",
3032 state->channel_parameters_set ? "manual" : "auto");
173a64cb 3033
7fa676c6 3034 dib8000_viterbi_state(state, 0); /* force chan dec in restart */
173a64cb 3035
7fa676c6
MCC
3036 /* Layer monitor */
3037 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
173a64cb 3038
7fa676c6
MCC
3039 dib8000_set_frequency_offset(state);
3040 dib8000_set_bandwidth(fe, c->bandwidth_hz / 1000);
173a64cb 3041
7fa676c6 3042 if (state->channel_parameters_set == 0) { /* The channel struct is unknown, search it ! */
173a64cb 3043#ifdef DIB8000_AGC_FREEZE
7fa676c6
MCC
3044 if (state->revision != 0x8090) {
3045 state->agc1_max = dib8000_read_word(state, 108);
3046 state->agc1_min = dib8000_read_word(state, 109);
3047 state->agc2_max = dib8000_read_word(state, 110);
3048 state->agc2_min = dib8000_read_word(state, 111);
3049 agc1 = dib8000_read_word(state, 388);
3050 agc2 = dib8000_read_word(state, 389);
3051 dib8000_write_word(state, 108, agc1);
3052 dib8000_write_word(state, 109, agc1);
3053 dib8000_write_word(state, 110, agc2);
3054 dib8000_write_word(state, 111, agc2);
173a64cb 3055 }
7fa676c6
MCC
3056#endif
3057 state->autosearch_state = AS_SEARCHING_FFT;
3058 state->found_nfft = TRANSMISSION_MODE_AUTO;
3059 state->found_guard = GUARD_INTERVAL_AUTO;
3060 *tune_state = CT_DEMOD_SEARCH_NEXT;
3061 } else { /* we already know the channel struct so TUNE only ! */
3062 state->autosearch_state = AS_DONE;
3063 *tune_state = CT_DEMOD_STEP_3;
3064 }
3065 state->symbol_duration = dib8000_get_symbol_duration(state);
3066 break;
173a64cb
PB
3067
3068 case CT_DEMOD_SEARCH_NEXT: /* 51 */
7fa676c6
MCC
3069 dib8000_autosearch_start(fe);
3070 if (state->revision == 0x8090)
3071 ret = 50;
3072 else
3073 ret = 15;
3074 *tune_state = CT_DEMOD_STEP_1;
3075 break;
173a64cb
PB
3076
3077 case CT_DEMOD_STEP_1: /* 31 */
7fa676c6
MCC
3078 switch (dib8000_autosearch_irq(fe)) {
3079 case 1: /* fail */
3080 state->status = FE_STATUS_TUNE_FAILED;
3081 state->autosearch_state = AS_DONE;
3082 *tune_state = CT_DEMOD_STOP; /* else we are done here */
3083 break;
3084 case 2: /* Succes */
3085 state->status = FE_STATUS_FFT_SUCCESS; /* signal to the upper layer, that there was a channel found and the parameters can be read */
3086 *tune_state = CT_DEMOD_STEP_3;
3087 if (state->autosearch_state == AS_SEARCHING_GUARD)
3088 *tune_state = CT_DEMOD_STEP_2;
3089 else
3090 state->autosearch_state = AS_DONE;
173a64cb 3091 break;
7fa676c6
MCC
3092 case 3: /* Autosearch FFT max correlation endded */
3093 *tune_state = CT_DEMOD_STEP_2;
3094 break;
3095 }
3096 break;
173a64cb
PB
3097
3098 case CT_DEMOD_STEP_2:
7fa676c6
MCC
3099 switch (state->autosearch_state) {
3100 case AS_SEARCHING_FFT:
3101 /* searching for the correct FFT */
3102 if (state->revision == 0x8090) {
3103 corm[2] = (dib8000_read_word(state, 596) << 16) | (dib8000_read_word(state, 597));
3104 corm[1] = (dib8000_read_word(state, 598) << 16) | (dib8000_read_word(state, 599));
3105 corm[0] = (dib8000_read_word(state, 600) << 16) | (dib8000_read_word(state, 601));
3106 } else {
3107 corm[2] = (dib8000_read_word(state, 594) << 16) | (dib8000_read_word(state, 595));
3108 corm[1] = (dib8000_read_word(state, 596) << 16) | (dib8000_read_word(state, 597));
3109 corm[0] = (dib8000_read_word(state, 598) << 16) | (dib8000_read_word(state, 599));
3110 }
3111 /* dprintk("corm fft: %u %u %u", corm[0], corm[1], corm[2]); */
173a64cb 3112
7fa676c6
MCC
3113 max_value = 0;
3114 for (find_index = 1 ; find_index < 3 ; find_index++) {
3115 if (corm[max_value] < corm[find_index])
3116 max_value = find_index ;
3117 }
173a64cb 3118
7fa676c6
MCC
3119 switch (max_value) {
3120 case 0:
3121 state->found_nfft = TRANSMISSION_MODE_2K;
3122 break;
3123 case 1:
3124 state->found_nfft = TRANSMISSION_MODE_4K;
3125 break;
3126 case 2:
173a64cb 3127 default:
7fa676c6
MCC
3128 state->found_nfft = TRANSMISSION_MODE_8K;
3129 break;
173a64cb 3130 }
7fa676c6
MCC
3131 /* dprintk("Autosearch FFT has found Mode %d", max_value + 1); */
3132
3133 *tune_state = CT_DEMOD_SEARCH_NEXT;
3134 state->autosearch_state = AS_SEARCHING_GUARD;
3135 if (state->revision == 0x8090)
3136 ret = 50;
3137 else
3138 ret = 10;
173a64cb 3139 break;
7fa676c6
MCC
3140 case AS_SEARCHING_GUARD:
3141 /* searching for the correct guard interval */
3142 if (state->revision == 0x8090)
3143 state->found_guard = dib8000_read_word(state, 572) & 0x3;
3144 else
3145 state->found_guard = dib8000_read_word(state, 570) & 0x3;
3146 /* dprintk("guard interval found=%i", state->found_guard); */
173a64cb 3147
7fa676c6 3148 *tune_state = CT_DEMOD_STEP_3;
173a64cb 3149 break;
7fa676c6
MCC
3150 default:
3151 /* the demod should never be in this state */
3152 state->status = FE_STATUS_TUNE_FAILED;
3153 state->autosearch_state = AS_DONE;
3154 *tune_state = CT_DEMOD_STOP; /* else we are done here */
3155 break;
3156 }
3157 break;
3158
3159 case CT_DEMOD_STEP_3: /* 33 */
7fa676c6
MCC
3160 dib8000_set_isdbt_loop_params(state, LOOP_TUNE_1);
3161 dib8000_set_isdbt_common_channel(state, 0, 0);/* setting the known channel parameters here */
3162 *tune_state = CT_DEMOD_STEP_4;
3163 break;
173a64cb
PB
3164
3165 case CT_DEMOD_STEP_4: /* (34) */
7fa676c6 3166 dib8000_demod_restart(state);
173a64cb 3167
7fa676c6
MCC
3168 dib8000_set_sync_wait(state);
3169 dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
173a64cb 3170
7fa676c6
MCC
3171 locks = (dib8000_read_word(state, 180) >> 6) & 0x3f; /* P_coff_winlen ? */
3172 /* coff should lock over P_coff_winlen ofdm symbols : give 3 times this length to lock */
3173 *timeout = dib8000_get_timeout(state, 2 * locks, SYMBOL_DEPENDENT_ON);
3174 *tune_state = CT_DEMOD_STEP_5;
3175 break;
173a64cb
PB
3176
3177 case CT_DEMOD_STEP_5: /* (35) */
7fa676c6
MCC
3178 locks = dib8000_read_lock(fe);
3179 if (locks & (0x3 << 11)) { /* coff-lock and off_cpil_lock achieved */
3180 dib8000_update_timf(state); /* we achieved a coff_cpil_lock - it's time to update the timf */
3181 if (!state->differential_constellation) {
3182 /* 2 times lmod4_win_len + 10 symbols (pipe delay after coff + nb to compute a 1st correlation) */
3183 *timeout = dib8000_get_timeout(state, (20 * ((dib8000_read_word(state, 188)>>5)&0x1f)), SYMBOL_DEPENDENT_ON);
3184 *tune_state = CT_DEMOD_STEP_7;
3185 } else {
3186 *tune_state = CT_DEMOD_STEP_8;
173a64cb 3187 }
7fa676c6
MCC
3188 } else if (now > *timeout) {
3189 *tune_state = CT_DEMOD_STEP_6; /* goto check for diversity input connection */
3190 }
3191 break;
173a64cb
PB
3192
3193 case CT_DEMOD_STEP_6: /* (36) if there is an input (diversity) */
7fa676c6
MCC
3194 if ((state->fe[1] != NULL) && (state->output_mode != OUTMODE_DIVERSITY)) {
3195 /* if there is a diversity fe in input and this fe is has not already failled : wait here until this this fe has succedeed or failled */
3196 if (dib8000_get_status(state->fe[1]) <= FE_STATUS_STD_SUCCESS) /* Something is locked on the input fe */
3197 *tune_state = CT_DEMOD_STEP_8; /* go for mpeg */
3198 else if (dib8000_get_status(state->fe[1]) >= FE_STATUS_TUNE_TIME_TOO_SHORT) { /* fe in input failled also, break the current one */
3199 *tune_state = CT_DEMOD_STOP; /* else we are done here ; step 8 will close the loops and exit */
173a64cb
PB
3200 dib8000_viterbi_state(state, 1); /* start viterbi chandec */
3201 dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
173a64cb
PB
3202 state->status = FE_STATUS_TUNE_FAILED;
3203 }
7fa676c6
MCC
3204 } else {
3205 dib8000_viterbi_state(state, 1); /* start viterbi chandec */
3206 dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
3207 *tune_state = CT_DEMOD_STOP; /* else we are done here ; step 8 will close the loops and exit */
3208 state->status = FE_STATUS_TUNE_FAILED;
3209 }
3210 break;
173a64cb
PB
3211
3212 case CT_DEMOD_STEP_7: /* 37 */
7fa676c6
MCC
3213 locks = dib8000_read_lock(fe);
3214 if (locks & (1<<10)) { /* lmod4_lock */
3215 ret = 14; /* wait for 14 symbols */
3216 *tune_state = CT_DEMOD_STEP_8;
3217 } else if (now > *timeout)
3218 *tune_state = CT_DEMOD_STEP_6; /* goto check for diversity input connection */
3219 break;
173a64cb
PB
3220
3221 case CT_DEMOD_STEP_8: /* 38 */
7fa676c6
MCC
3222 dib8000_viterbi_state(state, 1); /* start viterbi chandec */
3223 dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
3224
3225 /* mpeg will never lock on this condition because init_prbs is not set : search for it !*/
3226 if (c->isdbt_sb_mode
3227 && c->isdbt_sb_subchannel < 14
3228 && !state->differential_constellation) {
3229 state->subchannel = 0;
3230 *tune_state = CT_DEMOD_STEP_11;
3231 } else {
3232 *tune_state = CT_DEMOD_STEP_9;
3233 state->status = FE_STATUS_LOCKED;
3234 }
3235 break;
173a64cb
PB
3236
3237 case CT_DEMOD_STEP_9: /* 39 */
7fa676c6
MCC
3238 if ((state->revision == 0x8090) || ((dib8000_read_word(state, 1291) >> 9) & 0x1)) { /* fe capable of deinterleaving : esram */
3239 /* defines timeout for mpeg lock depending on interleaver length of longest layer */
3240 for (i = 0; i < 3; i++) {
3241 if (c->layer[i].interleaving >= deeper_interleaver) {
3242 dprintk("layer%i: time interleaver = %d ", i, c->layer[i].interleaving);
3243 if (c->layer[i].segment_count > 0) { /* valid layer */
3244 deeper_interleaver = c->layer[0].interleaving;
3245 state->longest_intlv_layer = i;
173a64cb
PB
3246 }
3247 }
7fa676c6 3248 }
173a64cb 3249
7fa676c6
MCC
3250 if (deeper_interleaver == 0)
3251 locks = 2; /* locks is the tmp local variable name */
3252 else if (deeper_interleaver == 3)
3253 locks = 8;
3254 else
3255 locks = 2 * deeper_interleaver;
173a64cb 3256
7fa676c6
MCC
3257 if (state->diversity_onoff != 0) /* because of diversity sync */
3258 locks *= 2;
173a64cb 3259
7fa676c6
MCC
3260 *timeout = now + (2000 * locks); /* give the mpeg lock 800ms if sram is present */
3261 dprintk("Deeper interleaver mode = %d on layer %d : timeout mult factor = %d => will use timeout = %d", deeper_interleaver, state->longest_intlv_layer, locks, *timeout);
173a64cb 3262
7fa676c6
MCC
3263 *tune_state = CT_DEMOD_STEP_10;
3264 } else
3265 *tune_state = CT_DEMOD_STOP;
3266 break;
173a64cb
PB
3267
3268 case CT_DEMOD_STEP_10: /* 40 */
7fa676c6
MCC
3269 locks = dib8000_read_lock(fe);
3270 if (locks&(1<<(7-state->longest_intlv_layer))) { /* mpeg lock : check the longest one */
3271 dprintk("Mpeg locks [ L0 : %d | L1 : %d | L2 : %d ]", (locks>>7)&0x1, (locks>>6)&0x1, (locks>>5)&0x1);
3272 if (c->isdbt_sb_mode
3273 && c->isdbt_sb_subchannel < 14
3274 && !state->differential_constellation)
3275 /* signal to the upper layer, that there was a channel found and the parameters can be read */
3276 state->status = FE_STATUS_DEMOD_SUCCESS;
3277 else
3278 state->status = FE_STATUS_DATA_LOCKED;
3279 *tune_state = CT_DEMOD_STOP;
3280 } else if (now > *timeout) {
3281 if (c->isdbt_sb_mode
3282 && c->isdbt_sb_subchannel < 14
3283 && !state->differential_constellation) { /* continue to try init prbs autosearch */
3284 state->subchannel += 3;
3285 *tune_state = CT_DEMOD_STEP_11;
3286 } else { /* we are done mpeg of the longest interleaver xas not locking but let's try if an other layer has locked in the same time */
3287 if (locks & (0x7<<5)) {
3288 dprintk("Mpeg locks [ L0 : %d | L1 : %d | L2 : %d ]", (locks>>7)&0x1, (locks>>6)&0x1, (locks>>5)&0x1);
173a64cb 3289 state->status = FE_STATUS_DATA_LOCKED;
7fa676c6
MCC
3290 } else
3291 state->status = FE_STATUS_TUNE_FAILED;
173a64cb 3292 *tune_state = CT_DEMOD_STOP;
173a64cb 3293 }
7fa676c6
MCC
3294 }
3295 break;
173a64cb
PB
3296
3297 case CT_DEMOD_STEP_11: /* 41 : init prbs autosearch */
7fa676c6
MCC
3298 if (state->subchannel <= 41) {
3299 dib8000_set_subchannel_prbs(state, dib8000_get_init_prbs(state, state->subchannel));
3300 *tune_state = CT_DEMOD_STEP_9;
3301 } else {
3302 *tune_state = CT_DEMOD_STOP;
3303 state->status = FE_STATUS_TUNE_FAILED;
3304 }
3305 break;
173a64cb
PB
3306
3307 default:
7fa676c6 3308 break;
173a64cb
PB
3309 }
3310
3311 /* tuning is finished - cleanup the demod */
3312 switch (*tune_state) {
3313 case CT_DEMOD_STOP: /* (42) */
3314#ifdef DIB8000_AGC_FREEZE
7fa676c6
MCC
3315 if ((state->revision != 0x8090) && (state->agc1_max != 0)) {
3316 dib8000_write_word(state, 108, state->agc1_max);
3317 dib8000_write_word(state, 109, state->agc1_min);
3318 dib8000_write_word(state, 110, state->agc2_max);
3319 dib8000_write_word(state, 111, state->agc2_min);
3320 state->agc1_max = 0;
3321 state->agc1_min = 0;
3322 state->agc2_max = 0;
3323 state->agc2_min = 0;
3324 }
173a64cb 3325#endif
7fa676c6
MCC
3326 ret = FE_CALLBACK_TIME_NEVER;
3327 break;
173a64cb 3328 default:
7fa676c6 3329 break;
77e2c0f5
PB
3330 }
3331
173a64cb
PB
3332 if ((ret > 0) && (*tune_state > CT_DEMOD_STEP_3))
3333 return ret * state->symbol_duration;
3334 if ((ret > 0) && (ret < state->symbol_duration))
3335 return state->symbol_duration; /* at least one symbol */
77e2c0f5
PB
3336 return ret;
3337}
3338
3339static int dib8000_wakeup(struct dvb_frontend *fe)
3340{
3341 struct dib8000_state *state = fe->demodulator_priv;
4c70e074
OG
3342 u8 index_frontend;
3343 int ret;
77e2c0f5 3344
0c32dbd7 3345 dib8000_set_power_mode(state, DIB8000_POWER_ALL);
77e2c0f5
PB
3346 dib8000_set_adc_state(state, DIBX000_ADC_ON);
3347 if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
3348 dprintk("could not start Slow ADC");
3349
173a64cb 3350 if (state->revision == 0x8090)
0c32dbd7
OG
3351 dib8000_sad_calib(state);
3352
b4d6046e 3353 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
4c70e074 3354 ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]);
b4d6046e 3355 if (ret < 0)
4c70e074
OG
3356 return ret;
3357 }
3358
77e2c0f5
PB
3359 return 0;
3360}
3361
3362static int dib8000_sleep(struct dvb_frontend *fe)
3363{
4c70e074
OG
3364 struct dib8000_state *state = fe->demodulator_priv;
3365 u8 index_frontend;
3366 int ret;
77e2c0f5 3367
b4d6046e 3368 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
4c70e074
OG
3369 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
3370 if (ret < 0)
3371 return ret;
77e2c0f5 3372 }
4c70e074 3373
0c32dbd7
OG
3374 if (state->revision != 0x8090)
3375 dib8000_set_output_mode(fe, OUTMODE_HIGH_Z);
3376 dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
4c70e074 3377 return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF);
77e2c0f5
PB
3378}
3379
70315b3e
MCC
3380static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat);
3381
7c61d80a 3382static int dib8000_get_frontend(struct dvb_frontend *fe)
77e2c0f5
PB
3383{
3384 struct dib8000_state *state = fe->demodulator_priv;
3385 u16 i, val = 0;
70315b3e 3386 fe_status_t stat = 0;
4c70e074 3387 u8 index_frontend, sub_index_frontend;
77e2c0f5
PB
3388
3389 fe->dtv_property_cache.bandwidth_hz = 6000000;
3390
70315b3e
MCC
3391 /*
3392 * If called to early, get_frontend makes dib8000_tune to either
3393 * not lock or not sync. This causes dvbv5-scan/dvbv5-zap to fail.
3394 * So, let's just return if frontend 0 has not locked.
3395 */
3396 dib8000_read_status(fe, &stat);
3397 if (!(stat & FE_HAS_SYNC))
3398 return 0;
3399
3400 dprintk("TMCC lock");
b4d6046e 3401 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
4c70e074
OG
3402 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
3403 if (stat&FE_HAS_SYNC) {
3404 dprintk("TMCC lock on the slave%i", index_frontend);
3405 /* synchronize the cache with the other frontends */
7c61d80a 3406 state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend]);
b4d6046e 3407 for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) {
4c70e074
OG
3408 if (sub_index_frontend != index_frontend) {
3409 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
3410 state->fe[sub_index_frontend]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion;
3411 state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode;
3412 state->fe[sub_index_frontend]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval;
3413 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception;
3414 for (i = 0; i < 3; i++) {
3415 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count;
3416 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving;
3417 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec;
3418 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation;
3419 }
3420 }
3421 }
3422 return 0;
3423 }
3424 }
3425
77e2c0f5
PB
3426 fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
3427
0c32dbd7
OG
3428 if (state->revision == 0x8090)
3429 val = dib8000_read_word(state, 572);
3430 else
3431 val = dib8000_read_word(state, 570);
77e2c0f5
PB
3432 fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
3433 switch ((val & 0x30) >> 4) {
3434 case 1:
3435 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
3436 break;
7fec1c80
MCC
3437 case 2:
3438 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_4K;
3439 break;
77e2c0f5
PB
3440 case 3:
3441 default:
3442 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
3443 break;
3444 }
3445
3446 switch (val & 0x3) {
3447 case 0:
3448 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
3449 dprintk("dib8000_get_frontend GI = 1/32 ");
3450 break;
3451 case 1:
3452 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
3453 dprintk("dib8000_get_frontend GI = 1/16 ");
3454 break;
3455 case 2:
3456 dprintk("dib8000_get_frontend GI = 1/8 ");
3457 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
3458 break;
3459 case 3:
3460 dprintk("dib8000_get_frontend GI = 1/4 ");
3461 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
3462 break;
3463 }
3464
3465 val = dib8000_read_word(state, 505);
3466 fe->dtv_property_cache.isdbt_partial_reception = val & 1;
3467 dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
3468
3469 for (i = 0; i < 3; i++) {
3470 val = dib8000_read_word(state, 493 + i);
3471 fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
3472 dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
3473
51fea113
MCC
3474 val = dib8000_read_word(state, 499 + i) & 0x3;
3475 /* Interleaving can be 0, 1, 2 or 4 */
3476 if (val == 3)
3477 val = 4;
3478 fe->dtv_property_cache.layer[i].interleaving = val;
3479 dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ",
3480 i, fe->dtv_property_cache.layer[i].interleaving);
77e2c0f5
PB
3481
3482 val = dib8000_read_word(state, 481 + i);
3483 switch (val & 0x7) {
3484 case 1:
3485 fe->dtv_property_cache.layer[i].fec = FEC_1_2;
3486 dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
3487 break;
3488 case 2:
3489 fe->dtv_property_cache.layer[i].fec = FEC_2_3;
3490 dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
3491 break;
3492 case 3:
3493 fe->dtv_property_cache.layer[i].fec = FEC_3_4;
3494 dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
3495 break;
3496 case 5:
3497 fe->dtv_property_cache.layer[i].fec = FEC_5_6;
3498 dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
3499 break;
3500 default:
3501 fe->dtv_property_cache.layer[i].fec = FEC_7_8;
3502 dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
3503 break;
3504 }
3505
3506 val = dib8000_read_word(state, 487 + i);
3507 switch (val & 0x3) {
3508 case 0:
3509 dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
3510 fe->dtv_property_cache.layer[i].modulation = DQPSK;
3511 break;
3512 case 1:
3513 fe->dtv_property_cache.layer[i].modulation = QPSK;
3514 dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
3515 break;
3516 case 2:
3517 fe->dtv_property_cache.layer[i].modulation = QAM_16;
3518 dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
3519 break;
3520 case 3:
3521 default:
3522 dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
3523 fe->dtv_property_cache.layer[i].modulation = QAM_64;
3524 break;
3525 }
3526 }
4c70e074
OG
3527
3528 /* synchronize the cache with the other frontends */
b4d6046e 3529 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
4c70e074
OG
3530 state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode = fe->dtv_property_cache.isdbt_sb_mode;
3531 state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion;
3532 state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode;
3533 state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval;
3534 state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception = fe->dtv_property_cache.isdbt_partial_reception;
3535 for (i = 0; i < 3; i++) {
3536 state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count = fe->dtv_property_cache.layer[i].segment_count;
3537 state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving = fe->dtv_property_cache.layer[i].interleaving;
3538 state->fe[index_frontend]->dtv_property_cache.layer[i].fec = fe->dtv_property_cache.layer[i].fec;
3539 state->fe[index_frontend]->dtv_property_cache.layer[i].modulation = fe->dtv_property_cache.layer[i].modulation;
3540 }
3541 }
77e2c0f5
PB
3542 return 0;
3543}
3544
490ecd63 3545static int dib8000_set_frontend(struct dvb_frontend *fe)
77e2c0f5
PB
3546{
3547 struct dib8000_state *state = fe->demodulator_priv;
c82056d0 3548 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
4d8d5d92 3549 int l, i, active, time, time_slave = FE_CALLBACK_TIME_NEVER;
173a64cb
PB
3550 u8 exit_condition, index_frontend;
3551 u32 delay, callback_time;
4c70e074 3552
c82056d0 3553 if (c->frequency == 0) {
4c70e074
OG
3554 dprintk("dib8000: must at least specify frequency ");
3555 return 0;
3556 }
3557
c82056d0 3558 if (c->bandwidth_hz == 0) {
4c70e074 3559 dprintk("dib8000: no bandwidth specified, set to default ");
c82056d0 3560 c->bandwidth_hz = 6000000;
4c70e074 3561 }
77e2c0f5 3562
b4d6046e 3563 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
4c70e074
OG
3564 /* synchronization of the cache */
3565 state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT;
3566 memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
910ef763 3567
173a64cb
PB
3568 /* set output mode and diversity input */
3569 if (state->revision != 0x8090) {
3570 dib8000_set_diversity_in(state->fe[index_frontend], 1);
3571 if (index_frontend != 0)
3572 dib8000_set_output_mode(state->fe[index_frontend],
3573 OUTMODE_DIVERSITY);
3574 else
3575 dib8000_set_output_mode(state->fe[0], OUTMODE_HIGH_Z);
3576 } else {
3577 dib8096p_set_diversity_in(state->fe[index_frontend], 1);
3578 if (index_frontend != 0)
3579 dib8096p_set_output_mode(state->fe[index_frontend],
3580 OUTMODE_DIVERSITY);
3581 else
3582 dib8096p_set_output_mode(state->fe[0], OUTMODE_HIGH_Z);
3583 }
3584
3585 /* tune the tuner */
4c70e074 3586 if (state->fe[index_frontend]->ops.tuner_ops.set_params)
14d24d14 3587 state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend]);
77e2c0f5 3588
4c70e074
OG
3589 dib8000_set_tune_state(state->fe[index_frontend], CT_AGC_START);
3590 }
77e2c0f5 3591
173a64cb
PB
3592 /* turn off the diversity of the last chip */
3593 if (state->revision != 0x8090)
3594 dib8000_set_diversity_in(state->fe[index_frontend - 1], 0);
3595 else
3596 dib8096p_set_diversity_in(state->fe[index_frontend - 1], 0);
3597
77e2c0f5 3598 /* start up the AGC */
77e2c0f5 3599 do {
4c70e074 3600 time = dib8000_agc_startup(state->fe[0]);
b4d6046e 3601 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
4c70e074
OG
3602 time_slave = dib8000_agc_startup(state->fe[index_frontend]);
3603 if (time == FE_CALLBACK_TIME_NEVER)
3604 time = time_slave;
3605 else if ((time_slave != FE_CALLBACK_TIME_NEVER) && (time_slave > time))
3606 time = time_slave;
3607 }
77e2c0f5
PB
3608 if (time != FE_CALLBACK_TIME_NEVER)
3609 msleep(time / 10);
3610 else
3611 break;
4c70e074 3612 exit_condition = 1;
b4d6046e 3613 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
4c70e074
OG
3614 if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_AGC_STOP) {
3615 exit_condition = 0;
3616 break;
3617 }
3618 }
3619 } while (exit_condition == 0);
3620
b4d6046e 3621 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
4c70e074
OG
3622 dib8000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
3623
173a64cb
PB
3624 active = 1;
3625 do {
3626 callback_time = FE_CALLBACK_TIME_NEVER;
2c2c441b 3627 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
173a64cb
PB
3628 delay = dib8000_tune(state->fe[index_frontend]);
3629 if (delay != FE_CALLBACK_TIME_NEVER)
3630 delay += systime();
3631
3632 /* we are in autosearch */
3633 if (state->channel_parameters_set == 0) { /* searching */
3634 if ((dib8000_get_status(state->fe[index_frontend]) == FE_STATUS_DEMOD_SUCCESS) || (dib8000_get_status(state->fe[index_frontend]) == FE_STATUS_FFT_SUCCESS)) {
3635 dprintk("autosearch succeeded on fe%i", index_frontend);
3636 dib8000_get_frontend(state->fe[index_frontend]); /* we read the channel parameters from the frontend which was successful */
3637 state->channel_parameters_set = 1;
3638
3639 for (l = 0; (l < MAX_NUMBER_OF_FRONTENDS) && (state->fe[l] != NULL); l++) {
3640 if (l != index_frontend) { /* and for all frontend except the successful one */
3641 dib8000_tune_restart_from_demod(state->fe[l]);
3642
3643 state->fe[l]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
3644 state->fe[l]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion;
3645 state->fe[l]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode;
3646 state->fe[l]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval;
3647 state->fe[l]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception;
3648 for (i = 0; i < 3; i++) {
3649 state->fe[l]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count;
3650 state->fe[l]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving;
3651 state->fe[l]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec;
3652 state->fe[l]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation;
3653 }
3654
3655 }
2c2c441b
MCC
3656 }
3657 }
3658 }
173a64cb
PB
3659 if (delay < callback_time)
3660 callback_time = delay;
3661 }
3662 /* tuning is done when the master frontend is done (failed or success) */
3663 if (dib8000_get_status(state->fe[0]) == FE_STATUS_TUNE_FAILED ||
3664 dib8000_get_status(state->fe[0]) == FE_STATUS_LOCKED ||
3665 dib8000_get_status(state->fe[0]) == FE_STATUS_DATA_LOCKED) {
3666 active = 0;
3667 /* we need to wait for all frontends to be finished */
3668 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3669 if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_DEMOD_STOP)
3670 active = 1;
3671 }
3672 if (active == 0)
3673 dprintk("tuning done with status %d", dib8000_get_status(state->fe[0]));
2c2c441b
MCC
3674 }
3675
173a64cb
PB
3676 if ((active == 1) && (callback_time == FE_CALLBACK_TIME_NEVER)) {
3677 dprintk("strange callback time something went wrong");
3678 active = 0;
3679 }
4c70e074 3680
173a64cb
PB
3681 while ((active == 1) && (systime() < callback_time))
3682 msleep(100);
3683 } while (active);
77e2c0f5 3684
173a64cb
PB
3685 /* set output mode */
3686 if (state->revision != 0x8090)
0c32dbd7 3687 dib8000_set_output_mode(state->fe[0], state->cfg.output_mode);
173a64cb 3688 else {
0c32dbd7
OG
3689 dib8096p_set_output_mode(state->fe[0], state->cfg.output_mode);
3690 if (state->cfg.enMpegOutput == 0) {
3691 dib8096p_setDibTxMux(state, MPEG_ON_DIBTX);
3692 dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
3693 }
0c32dbd7 3694 }
77e2c0f5 3695
4d8d5d92 3696 return 0;
4c70e074 3697}
77e2c0f5 3698
6ef06e78
MCC
3699static int dib8000_get_stats(struct dvb_frontend *fe, fe_status_t stat);
3700
77e2c0f5
PB
3701static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
3702{
3703 struct dib8000_state *state = fe->demodulator_priv;
0c32dbd7 3704 u16 lock_slave = 0, lock;
4c70e074
OG
3705 u8 index_frontend;
3706
173a64cb 3707 lock = dib8000_read_lock(fe);
b4d6046e 3708 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
4c70e074 3709 lock_slave |= dib8000_read_lock(state->fe[index_frontend]);
77e2c0f5
PB
3710
3711 *stat = 0;
3712
4c70e074 3713 if (((lock >> 13) & 1) || ((lock_slave >> 13) & 1))
77e2c0f5
PB
3714 *stat |= FE_HAS_SIGNAL;
3715
4c70e074 3716 if (((lock >> 8) & 1) || ((lock_slave >> 8) & 1)) /* Equal */
77e2c0f5
PB
3717 *stat |= FE_HAS_CARRIER;
3718
4c70e074 3719 if ((((lock >> 1) & 0xf) == 0xf) || (((lock_slave >> 1) & 0xf) == 0xf)) /* TMCC_SYNC */
77e2c0f5
PB
3720 *stat |= FE_HAS_SYNC;
3721
4c70e074 3722 if ((((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) && ((lock >> 5) & 7)) /* FEC MPEG */
77e2c0f5
PB
3723 *stat |= FE_HAS_LOCK;
3724
4c70e074 3725 if (((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) {
89dfc557
OG
3726 lock = dib8000_read_word(state, 554); /* Viterbi Layer A */
3727 if (lock & 0x01)
3728 *stat |= FE_HAS_VITERBI;
77e2c0f5 3729
89dfc557
OG
3730 lock = dib8000_read_word(state, 555); /* Viterbi Layer B */
3731 if (lock & 0x01)
3732 *stat |= FE_HAS_VITERBI;
77e2c0f5 3733
89dfc557
OG
3734 lock = dib8000_read_word(state, 556); /* Viterbi Layer C */
3735 if (lock & 0x01)
3736 *stat |= FE_HAS_VITERBI;
3737 }
6ef06e78 3738 dib8000_get_stats(fe, *stat);
77e2c0f5
PB
3739
3740 return 0;
3741}
3742
3743static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
3744{
3745 struct dib8000_state *state = fe->demodulator_priv;
0c32dbd7
OG
3746
3747 /* 13 segments */
3748 if (state->revision == 0x8090)
3749 *ber = (dib8000_read_word(state, 562) << 16) |
3750 dib8000_read_word(state, 563);
3751 else
3752 *ber = (dib8000_read_word(state, 560) << 16) |
3753 dib8000_read_word(state, 561);
77e2c0f5
PB
3754 return 0;
3755}
3756
3757static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
3758{
3759 struct dib8000_state *state = fe->demodulator_priv;
0c32dbd7
OG
3760
3761 /* packet error on 13 seg */
3762 if (state->revision == 0x8090)
3763 *unc = dib8000_read_word(state, 567);
3764 else
3765 *unc = dib8000_read_word(state, 565);
77e2c0f5
PB
3766 return 0;
3767}
3768
3769static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
3770{
3771 struct dib8000_state *state = fe->demodulator_priv;
4c70e074
OG
3772 u8 index_frontend;
3773 u16 val;
3774
3775 *strength = 0;
b4d6046e 3776 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
4c70e074
OG
3777 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
3778 if (val > 65535 - *strength)
3779 *strength = 65535;
3780 else
3781 *strength += val;
3782 }
3783
3784 val = 65535 - dib8000_read_word(state, 390);
3785 if (val > 65535 - *strength)
3786 *strength = 65535;
3787 else
3788 *strength += val;
77e2c0f5
PB
3789 return 0;
3790}
3791
4c70e074 3792static u32 dib8000_get_snr(struct dvb_frontend *fe)
77e2c0f5
PB
3793{
3794 struct dib8000_state *state = fe->demodulator_priv;
4c70e074 3795 u32 n, s, exp;
77e2c0f5 3796 u16 val;
77e2c0f5 3797
0c32dbd7
OG
3798 if (state->revision != 0x8090)
3799 val = dib8000_read_word(state, 542);
3800 else
3801 val = dib8000_read_word(state, 544);
4c70e074
OG
3802 n = (val >> 6) & 0xff;
3803 exp = (val & 0x3f);
3804 if ((exp & 0x20) != 0)
3805 exp -= 0x40;
3806 n <<= exp+16;
77e2c0f5 3807
0c32dbd7
OG
3808 if (state->revision != 0x8090)
3809 val = dib8000_read_word(state, 543);
3810 else
3811 val = dib8000_read_word(state, 545);
4c70e074
OG
3812 s = (val >> 6) & 0xff;
3813 exp = (val & 0x3f);
3814 if ((exp & 0x20) != 0)
3815 exp -= 0x40;
3816 s <<= exp+16;
3817
3818 if (n > 0) {
3819 u32 t = (s/n) << 16;
3820 return t + ((s << 16) - n*t) / n;
3821 }
3822 return 0xffffffff;
3823}
3824
3825static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
3826{
3827 struct dib8000_state *state = fe->demodulator_priv;
3828 u8 index_frontend;
3829 u32 snr_master;
77e2c0f5 3830
4c70e074 3831 snr_master = dib8000_get_snr(fe);
b4d6046e 3832 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
4c70e074 3833 snr_master += dib8000_get_snr(state->fe[index_frontend]);
77e2c0f5 3834
1f6bfcc7 3835 if ((snr_master >> 16) != 0) {
4c70e074
OG
3836 snr_master = 10*intlog10(snr_master>>16);
3837 *snr = snr_master / ((1 << 24) / 10);
3838 }
77e2c0f5 3839 else
4c70e074 3840 *snr = 0;
77e2c0f5 3841
77e2c0f5 3842 return 0;
6ef06e78
MCC
3843}
3844
3845struct per_layer_regs {
3846 u16 lock, ber, per;
3847};
3848
3849static const struct per_layer_regs per_layer_regs[] = {
3850 { 554, 560, 562 },
3851 { 555, 576, 578 },
3852 { 556, 581, 583 },
3853};
3854
42ff76bd
MCC
3855struct linear_segments {
3856 unsigned x;
3857 signed y;
3858};
3859
3860/*
3861 * Table to estimate signal strength in dBm.
3862 * This table was empirically determinated by measuring the signal
3863 * strength generated by a DTA-2111 RF generator directly connected into
3864 * a dib8076 device (a PixelView PV-D231U stick), using a good quality
3865 * 3 meters RC6 cable and good RC6 connectors.
3866 * The real value can actually be different on other devices, depending
3867 * on several factors, like if LNA is enabled or not, if diversity is
3868 * enabled, type of connectors, etc.
3869 * Yet, it is better to use this measure in dB than a random non-linear
3870 * percentage value, especially for antenna adjustments.
3871 * On my tests, the precision of the measure using this table is about
3872 * 0.5 dB, with sounds reasonable enough.
3873 */
3874static struct linear_segments strength_to_db_table[] = {
3875 { 55953, 108500 }, /* -22.5 dBm */
3876 { 55394, 108000 },
3877 { 53834, 107000 },
3878 { 52863, 106000 },
3879 { 52239, 105000 },
3880 { 52012, 104000 },
3881 { 51803, 103000 },
3882 { 51566, 102000 },
3883 { 51356, 101000 },
3884 { 51112, 100000 },
3885 { 50869, 99000 },
3886 { 50600, 98000 },
3887 { 50363, 97000 },
3888 { 50117, 96000 }, /* -35 dBm */
3889 { 49889, 95000 },
3890 { 49680, 94000 },
3891 { 49493, 93000 },
3892 { 49302, 92000 },
3893 { 48929, 91000 },
3894 { 48416, 90000 },
3895 { 48035, 89000 },
3896 { 47593, 88000 },
3897 { 47282, 87000 },
3898 { 46953, 86000 },
3899 { 46698, 85000 },
3900 { 45617, 84000 },
3901 { 44773, 83000 },
3902 { 43845, 82000 },
3903 { 43020, 81000 },
3904 { 42010, 80000 }, /* -51 dBm */
3905 { 0, 0 },
3906};
3907
3908static u32 interpolate_value(u32 value, struct linear_segments *segments,
3909 unsigned len)
3910{
3911 u64 tmp64;
3912 u32 dx;
3913 s32 dy;
3914 int i, ret;
3915
3916 if (value >= segments[0].x)
3917 return segments[0].y;
3918 if (value < segments[len-1].x)
3919 return segments[len-1].y;
3920
3921 for (i = 1; i < len - 1; i++) {
3922 /* If value is identical, no need to interpolate */
3923 if (value == segments[i].x)
3924 return segments[i].y;
3925 if (value > segments[i].x)
3926 break;
3927 }
3928
3929 /* Linear interpolation between the two (x,y) points */
3930 dy = segments[i - 1].y - segments[i].y;
3931 dx = segments[i - 1].x - segments[i].x;
3932
3933 tmp64 = value - segments[i].x;
3934 tmp64 *= dy;
3935 do_div(tmp64, dx);
3936 ret = segments[i].y + tmp64;
3937
3938 return ret;
3939}
3940
704f01bb
MCC
3941static u32 dib8000_get_time_us(struct dvb_frontend *fe, int layer)
3942{
3943 struct dib8000_state *state = fe->demodulator_priv;
3944 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
3945 int ini_layer, end_layer, i;
4bf48150 3946 u64 time_us, tmp64;
704f01bb 3947 u32 tmp, denom;
e4a3bc1c
MCC
3948 int guard, rate_num, rate_denum = 1, bits_per_symbol, nsegs;
3949 int interleaving = 0, fft_div;
704f01bb
MCC
3950
3951 if (layer >= 0) {
3952 ini_layer = layer;
3953 end_layer = layer + 1;
3954 } else {
3955 ini_layer = 0;
3956 end_layer = 3;
3957 }
3958
3959 switch (c->guard_interval) {
3960 case GUARD_INTERVAL_1_4:
3961 guard = 4;
3962 break;
3963 case GUARD_INTERVAL_1_8:
3964 guard = 8;
3965 break;
3966 case GUARD_INTERVAL_1_16:
3967 guard = 16;
3968 break;
3969 default:
3970 case GUARD_INTERVAL_1_32:
3971 guard = 32;
3972 break;
3973 }
3974
3975 switch (c->transmission_mode) {
3976 case TRANSMISSION_MODE_2K:
3977 fft_div = 4;
3978 break;
3979 case TRANSMISSION_MODE_4K:
3980 fft_div = 2;
3981 break;
3982 default:
3983 case TRANSMISSION_MODE_8K:
3984 fft_div = 1;
3985 break;
3986 }
3987
3988 denom = 0;
3989 for (i = ini_layer; i < end_layer; i++) {
3990 nsegs = c->layer[i].segment_count;
3991 if (nsegs == 0 || nsegs > 13)
3992 continue;
3993
3994 switch (c->layer[i].modulation) {
3995 case DQPSK:
3996 case QPSK:
3997 bits_per_symbol = 2;
3998 break;
3999 case QAM_16:
4000 bits_per_symbol = 4;
4001 break;
4002 default:
4003 case QAM_64:
4004 bits_per_symbol = 6;
4005 break;
4006 }
4007
4008 switch (c->layer[i].fec) {
4009 case FEC_1_2:
4010 rate_num = 1;
4011 rate_denum = 2;
4012 break;
4013 case FEC_2_3:
4014 rate_num = 2;
4015 rate_denum = 3;
4016 break;
4017 case FEC_3_4:
4018 rate_num = 3;
4019 rate_denum = 4;
4020 break;
4021 case FEC_5_6:
4022 rate_num = 5;
4023 rate_denum = 6;
4024 break;
4025 default:
4026 case FEC_7_8:
4027 rate_num = 7;
4028 rate_denum = 8;
4029 break;
4030 }
4031
4032 interleaving = c->layer[i].interleaving;
4033
4034 denom += bits_per_symbol * rate_num * fft_div * nsegs * 384;
4035 }
4036
4037 /* If all goes wrong, wait for 1s for the next stats */
4038 if (!denom)
4039 return 0;
4040
4041 /* Estimate the period for the total bit rate */
4042 time_us = rate_denum * (1008 * 1562500L);
4bf48150
MCC
4043 tmp64 = time_us;
4044 do_div(tmp64, guard);
4045 time_us = time_us + tmp64;
704f01bb
MCC
4046 time_us += denom / 2;
4047 do_div(time_us, denom);
4048
4049 tmp = 1008 * 96 * interleaving;
4050 time_us += tmp + tmp / guard;
4051
4052 return time_us;
4053}
4054
6ef06e78
MCC
4055static int dib8000_get_stats(struct dvb_frontend *fe, fe_status_t stat)
4056{
4057 struct dib8000_state *state = fe->demodulator_priv;
4058 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
704f01bb 4059 int i;
0400c535
MCC
4060 int show_per_stats = 0;
4061 u32 time_us = 0, snr, val;
4062 u64 blocks;
42ff76bd 4063 s32 db;
6ef06e78
MCC
4064 u16 strength;
4065
4066 /* Get Signal strength */
4067 dib8000_read_signal_strength(fe, &strength);
42ff76bd
MCC
4068 val = strength;
4069 db = interpolate_value(val,
4070 strength_to_db_table,
4071 ARRAY_SIZE(strength_to_db_table)) - 131000;
4072 c->strength.stat[0].svalue = db;
6ef06e78 4073
704f01bb 4074 /* UCB/BER/CNR measures require lock */
6ef06e78 4075 if (!(stat & FE_HAS_LOCK)) {
704f01bb 4076 c->cnr.len = 1;
0400c535 4077 c->block_count.len = 1;
6ef06e78
MCC
4078 c->block_error.len = 1;
4079 c->post_bit_error.len = 1;
4080 c->post_bit_count.len = 1;
704f01bb 4081 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6ef06e78
MCC
4082 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
4083 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
4084 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0400c535 4085 c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
6ef06e78
MCC
4086 return 0;
4087 }
4088
704f01bb 4089 /* Check if time for stats was elapsed */
0400c535
MCC
4090 if (time_after(jiffies, state->per_jiffies_stats)) {
4091 state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000);
704f01bb
MCC
4092
4093 /* Get SNR */
4094 snr = dib8000_get_snr(fe);
4095 for (i = 1; i < MAX_NUMBER_OF_FRONTENDS; i++) {
4096 if (state->fe[i])
4097 snr += dib8000_get_snr(state->fe[i]);
4098 }
4099 snr = snr >> 16;
6ef06e78 4100
704f01bb
MCC
4101 if (snr) {
4102 snr = 10 * intlog10(snr);
4103 snr = (1000L * snr) >> 24;
4104 } else {
4105 snr = 0;
4106 }
4107 c->cnr.stat[0].svalue = snr;
4108 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
6ef06e78 4109
0400c535
MCC
4110 /* Get UCB measures */
4111 dib8000_read_unc_blocks(fe, &val);
4112 if (val < state->init_ucb)
5dc8526b 4113 state->init_ucb += 0x100000000LL;
0400c535
MCC
4114
4115 c->block_error.stat[0].scale = FE_SCALE_COUNTER;
4116 c->block_error.stat[0].uvalue = val + state->init_ucb;
4117
4118 /* Estimate the number of packets based on bitrate */
4119 if (!time_us)
4120 time_us = dib8000_get_time_us(fe, -1);
4121
4122 if (time_us) {
5dc8526b 4123 blocks = 1250000ULL * 1000000ULL;
0400c535
MCC
4124 do_div(blocks, time_us * 8 * 204);
4125 c->block_count.stat[0].scale = FE_SCALE_COUNTER;
4126 c->block_count.stat[0].uvalue += blocks;
4127 }
4128
4129 show_per_stats = 1;
4130 }
4131
4132 /* Get post-BER measures */
4133 if (time_after(jiffies, state->ber_jiffies_stats)) {
4134 time_us = dib8000_get_time_us(fe, -1);
4135 state->ber_jiffies_stats = jiffies + msecs_to_jiffies((time_us + 500) / 1000);
4136
4137 dprintk("Next all layers stats available in %u us.", time_us);
6ef06e78 4138
704f01bb
MCC
4139 dib8000_read_ber(fe, &val);
4140 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
4141 c->post_bit_error.stat[0].uvalue += val;
6ef06e78 4142
704f01bb
MCC
4143 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
4144 c->post_bit_count.stat[0].uvalue += 100000000;
704f01bb 4145 }
6ef06e78
MCC
4146
4147 if (state->revision < 0x8002)
4148 return 0;
4149
4150 c->block_error.len = 4;
4151 c->post_bit_error.len = 4;
4152 c->post_bit_count.len = 4;
4153
4154 for (i = 0; i < 3; i++) {
0400c535
MCC
4155 unsigned nsegs = c->layer[i].segment_count;
4156
4157 if (nsegs == 0 || nsegs > 13)
704f01bb
MCC
4158 continue;
4159
0400c535
MCC
4160 time_us = 0;
4161
4162 if (time_after(jiffies, state->ber_jiffies_stats_layer[i])) {
4163 time_us = dib8000_get_time_us(fe, i);
4164
4165 state->ber_jiffies_stats_layer[i] = jiffies + msecs_to_jiffies((time_us + 500) / 1000);
4166 dprintk("Next layer %c stats will be available in %u us\n",
4167 'A' + i, time_us);
704f01bb 4168
0400c535
MCC
4169 val = dib8000_read_word(state, per_layer_regs[i].ber);
4170 c->post_bit_error.stat[1 + i].scale = FE_SCALE_COUNTER;
4171 c->post_bit_error.stat[1 + i].uvalue += val;
704f01bb 4172
0400c535
MCC
4173 c->post_bit_count.stat[1 + i].scale = FE_SCALE_COUNTER;
4174 c->post_bit_count.stat[1 + i].uvalue += 100000000;
4175 }
4176
4177 if (show_per_stats) {
4178 val = dib8000_read_word(state, per_layer_regs[i].per);
704f01bb 4179
0400c535
MCC
4180 c->block_error.stat[1 + i].scale = FE_SCALE_COUNTER;
4181 c->block_error.stat[1 + i].uvalue += val;
704f01bb 4182
0400c535
MCC
4183 if (!time_us)
4184 time_us = dib8000_get_time_us(fe, i);
4185 if (time_us) {
5dc8526b 4186 blocks = 1250000ULL * 1000000ULL;
0400c535
MCC
4187 do_div(blocks, time_us * 8 * 204);
4188 c->block_count.stat[0].scale = FE_SCALE_COUNTER;
4189 c->block_count.stat[0].uvalue += blocks;
4190 }
4191 }
6ef06e78
MCC
4192 }
4193 return 0;
77e2c0f5
PB
4194}
4195
d44913c1 4196static int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
4c70e074
OG
4197{
4198 struct dib8000_state *state = fe->demodulator_priv;
4199 u8 index_frontend = 1;
4200
4201 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
4202 index_frontend++;
4203 if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
4204 dprintk("set slave fe %p to index %i", fe_slave, index_frontend);
4205 state->fe[index_frontend] = fe_slave;
4206 return 0;
4207 }
4208
4209 dprintk("too many slave frontend");
4210 return -ENOMEM;
4211}
4c70e074 4212
d44913c1 4213static int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
4c70e074
OG
4214{
4215 struct dib8000_state *state = fe->demodulator_priv;
4216 u8 index_frontend = 1;
4217
4218 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
4219 index_frontend++;
4220 if (index_frontend != 1) {
4221 dprintk("remove slave fe %p (index %i)", state->fe[index_frontend-1], index_frontend-1);
4222 state->fe[index_frontend] = NULL;
4223 return 0;
4224 }
4225
4226 dprintk("no frontend to be removed");
4227 return -ENODEV;
4228}
4c70e074 4229
d44913c1 4230static struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
4c70e074
OG
4231{
4232 struct dib8000_state *state = fe->demodulator_priv;
4233
4234 if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
4235 return NULL;
4236 return state->fe[slave_index];
4237}
4c70e074 4238
d44913c1 4239static int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods,
0c32dbd7 4240 u8 default_addr, u8 first_addr, u8 is_dib8096p)
77e2c0f5 4241{
5a0deeed 4242 int k = 0, ret = 0;
77e2c0f5
PB
4243 u8 new_addr = 0;
4244 struct i2c_device client = {.adap = host };
4245
5a0deeed
OG
4246 client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
4247 if (!client.i2c_write_buffer) {
4248 dprintk("%s: not enough memory", __func__);
4249 return -ENOMEM;
4250 }
4251 client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
4252 if (!client.i2c_read_buffer) {
4253 dprintk("%s: not enough memory", __func__);
4254 ret = -ENOMEM;
79fcce32
PB
4255 goto error_memory_read;
4256 }
4257 client.i2c_buffer_lock = kzalloc(sizeof(struct mutex), GFP_KERNEL);
4258 if (!client.i2c_buffer_lock) {
4259 dprintk("%s: not enough memory", __func__);
4260 ret = -ENOMEM;
4261 goto error_memory_lock;
5a0deeed 4262 }
79fcce32 4263 mutex_init(client.i2c_buffer_lock);
5a0deeed 4264
77e2c0f5
PB
4265 for (k = no_of_demods - 1; k >= 0; k--) {
4266 /* designated i2c address */
4267 new_addr = first_addr + (k << 1);
4268
4269 client.addr = new_addr;
0c32dbd7 4270 if (!is_dib8096p)
77e2c0f5 4271 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
0c32dbd7
OG
4272 if (dib8000_identify(&client) == 0) {
4273 /* sram lead in, rdy */
4274 if (!is_dib8096p)
4275 dib8000_i2c_write16(&client, 1287, 0x0003);
77e2c0f5
PB
4276 client.addr = default_addr;
4277 if (dib8000_identify(&client) == 0) {
4278 dprintk("#%d: not identified", k);
5a0deeed
OG
4279 ret = -EINVAL;
4280 goto error;
77e2c0f5
PB
4281 }
4282 }
4283
4284 /* start diversity to pull_down div_str - just for i2c-enumeration */
4285 dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
4286
4287 /* set new i2c address and force divstart */
4288 dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
4289 client.addr = new_addr;
4290 dib8000_identify(&client);
4291
4292 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
4293 }
4294
4295 for (k = 0; k < no_of_demods; k++) {
4296 new_addr = first_addr | (k << 1);
4297 client.addr = new_addr;
4298
4299 // unforce divstr
4300 dib8000_i2c_write16(&client, 1285, new_addr << 2);
4301
4302 /* deactivate div - it was just for i2c-enumeration */
4303 dib8000_i2c_write16(&client, 1286, 0);
4304 }
4305
5a0deeed 4306error:
79fcce32
PB
4307 kfree(client.i2c_buffer_lock);
4308error_memory_lock:
5a0deeed 4309 kfree(client.i2c_read_buffer);
79fcce32 4310error_memory_read:
5a0deeed
OG
4311 kfree(client.i2c_write_buffer);
4312
4313 return ret;
77e2c0f5
PB
4314}
4315
77e2c0f5
PB
4316static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
4317{
4318 tune->min_delay_ms = 1000;
4319 tune->step_size = 0;
4320 tune->max_drift = 0;
4321 return 0;
4322}
4323
4324static void dib8000_release(struct dvb_frontend *fe)
4325{
4326 struct dib8000_state *st = fe->demodulator_priv;
4c70e074
OG
4327 u8 index_frontend;
4328
b4d6046e 4329 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
4c70e074
OG
4330 dvb_frontend_detach(st->fe[index_frontend]);
4331
77e2c0f5 4332 dibx000_exit_i2c_master(&st->i2c_master);
0c32dbd7 4333 i2c_del_adapter(&st->dib8096p_tuner_adap);
4c70e074 4334 kfree(st->fe[0]);
77e2c0f5
PB
4335 kfree(st);
4336}
4337
d44913c1 4338static struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
77e2c0f5
PB
4339{
4340 struct dib8000_state *st = fe->demodulator_priv;
4341 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
4342}
4343
d44913c1 4344static int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
f8731f4d
OG
4345{
4346 struct dib8000_state *st = fe->demodulator_priv;
4c70e074
OG
4347 u16 val = dib8000_read_word(st, 299) & 0xffef;
4348 val |= (onoff & 0x1) << 4;
f8731f4d 4349
4c70e074
OG
4350 dprintk("pid filter enabled %d", onoff);
4351 return dib8000_write_word(st, 299, val);
f8731f4d 4352}
f8731f4d 4353
d44913c1 4354static int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
f8731f4d
OG
4355{
4356 struct dib8000_state *st = fe->demodulator_priv;
4c70e074
OG
4357 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
4358 return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
f8731f4d 4359}
f8731f4d 4360
77e2c0f5 4361static const struct dvb_frontend_ops dib8000_ops = {
490ecd63 4362 .delsys = { SYS_ISDBT },
77e2c0f5
PB
4363 .info = {
4364 .name = "DiBcom 8000 ISDB-T",
77e2c0f5
PB
4365 .frequency_min = 44250000,
4366 .frequency_max = 867250000,
4367 .frequency_stepsize = 62500,
4368 .caps = FE_CAN_INVERSION_AUTO |
4369 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
4370 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
4371 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
4372 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
4373 },
4374
4375 .release = dib8000_release,
4376
4377 .init = dib8000_wakeup,
4378 .sleep = dib8000_sleep,
4379
490ecd63 4380 .set_frontend = dib8000_set_frontend,
77e2c0f5 4381 .get_tune_settings = dib8000_fe_get_tune_settings,
490ecd63 4382 .get_frontend = dib8000_get_frontend,
77e2c0f5
PB
4383
4384 .read_status = dib8000_read_status,
4385 .read_ber = dib8000_read_ber,
4386 .read_signal_strength = dib8000_read_signal_strength,
4387 .read_snr = dib8000_read_snr,
4388 .read_ucblocks = dib8000_read_unc_blocks,
4389};
4390
d44913c1 4391static struct dvb_frontend *dib8000_init(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
77e2c0f5
PB
4392{
4393 struct dvb_frontend *fe;
4394 struct dib8000_state *state;
4395
b9bc7d59 4396 dprintk("dib8000_init");
77e2c0f5
PB
4397
4398 state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
4399 if (state == NULL)
4400 return NULL;
4c70e074
OG
4401 fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
4402 if (fe == NULL)
ed54c0e3 4403 goto error;
77e2c0f5
PB
4404
4405 memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
4406 state->i2c.adap = i2c_adap;
4407 state->i2c.addr = i2c_addr;
5a0deeed
OG
4408 state->i2c.i2c_write_buffer = state->i2c_write_buffer;
4409 state->i2c.i2c_read_buffer = state->i2c_read_buffer;
79fcce32
PB
4410 mutex_init(&state->i2c_buffer_lock);
4411 state->i2c.i2c_buffer_lock = &state->i2c_buffer_lock;
77e2c0f5
PB
4412 state->gpio_val = cfg->gpio_val;
4413 state->gpio_dir = cfg->gpio_dir;
4414
4415 /* Ensure the output mode remains at the previous default if it's
4416 * not specifically set by the caller.
4417 */
4418 if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
4419 state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
4420
4c70e074 4421 state->fe[0] = fe;
77e2c0f5 4422 fe->demodulator_priv = state;
4c70e074 4423 memcpy(&state->fe[0]->ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
77e2c0f5
PB
4424
4425 state->timf_default = cfg->pll->timf;
4426
4427 if (dib8000_identify(&state->i2c) == 0)
4428 goto error;
4429
4430 dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
4431
0c32dbd7
OG
4432 /* init 8096p tuner adapter */
4433 strncpy(state->dib8096p_tuner_adap.name, "DiB8096P tuner interface",
4434 sizeof(state->dib8096p_tuner_adap.name));
4435 state->dib8096p_tuner_adap.algo = &dib8096p_tuner_xfer_algo;
4436 state->dib8096p_tuner_adap.algo_data = NULL;
4437 state->dib8096p_tuner_adap.dev.parent = state->i2c.adap->dev.parent;
4438 i2c_set_adapdata(&state->dib8096p_tuner_adap, state);
4439 i2c_add_adapter(&state->dib8096p_tuner_adap);
4440
77e2c0f5
PB
4441 dib8000_reset(fe);
4442
4443 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */
173a64cb 4444 state->current_demod_bw = 6000;
77e2c0f5
PB
4445
4446 return fe;
4447
173a64cb 4448error:
77e2c0f5
PB
4449 kfree(state);
4450 return NULL;
4451}
4452
d44913c1
MCC
4453void *dib8000_attach(struct dib8000_ops *ops)
4454{
4455 if (!ops)
4456 return NULL;
4457
4458 ops->pwm_agc_reset = dib8000_pwm_agc_reset;
4459 ops->get_dc_power = dib8090p_get_dc_power;
4460 ops->set_gpio = dib8000_set_gpio;
4461 ops->get_slave_frontend = dib8000_get_slave_frontend;
4462 ops->set_tune_state = dib8000_set_tune_state;
4463 ops->pid_filter_ctrl = dib8000_pid_filter_ctrl;
4464 ops->remove_slave_frontend = dib8000_remove_slave_frontend;
4465 ops->get_adc_power = dib8000_get_adc_power;
4466 ops->update_pll = dib8000_update_pll;
4467 ops->tuner_sleep = dib8096p_tuner_sleep;
4468 ops->get_tune_state = dib8000_get_tune_state;
4469 ops->get_i2c_tuner = dib8096p_get_i2c_tuner;
4470 ops->set_slave_frontend = dib8000_set_slave_frontend;
4471 ops->pid_filter = dib8000_pid_filter;
4472 ops->ctrl_timf = dib8000_ctrl_timf;
4473 ops->init = dib8000_init;
4474 ops->get_i2c_master = dib8000_get_i2c_master;
4475 ops->i2c_enumeration = dib8000_i2c_enumeration;
4476 ops->set_wbd_ref = dib8000_set_wbd_ref;
4477
4478 return ops;
4479}
4480EXPORT_SYMBOL(dib8000_attach);
77e2c0f5
PB
4481
4482MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
4483MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
4484MODULE_LICENSE("GPL");
This page took 0.655282 seconds and 5 git commands to generate.