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