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