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