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