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