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