• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/media/dvb/frontends/
1/*
2 * Linux-DVB Driver for DiBcom's DiB8000 chip (ISDB-T).
3 *
4 * Copyright (C) 2009 DiBcom (http://www.dibcom.fr/)
5 *
6 * This program is free software; you can redistribute it and/or
7 *  modify it under the terms of the GNU General Public License as
8 *  published by the Free Software Foundation, version 2.
9 */
10#include <linux/kernel.h>
11#include <linux/slab.h>
12#include <linux/i2c.h>
13#include "dvb_math.h"
14
15#include "dvb_frontend.h"
16
17#include "dib8000.h"
18
19#define LAYER_ALL -1
20#define LAYER_A   1
21#define LAYER_B   2
22#define LAYER_C   3
23
24#define FE_CALLBACK_TIME_NEVER 0xffffffff
25
26static int debug;
27module_param(debug, int, 0644);
28MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
29
30#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
31
32#define FE_STATUS_TUNE_FAILED 0
33
34struct i2c_device {
35	struct i2c_adapter *adap;
36	u8 addr;
37};
38
39struct dib8000_state {
40	struct dvb_frontend fe;
41	struct dib8000_config cfg;
42
43	struct i2c_device i2c;
44
45	struct dibx000_i2c_master i2c_master;
46
47	u16 wbd_ref;
48
49	u8 current_band;
50	u32 current_bandwidth;
51	struct dibx000_agc_config *current_agc;
52	u32 timf;
53	u32 timf_default;
54
55	u8 div_force_off:1;
56	u8 div_state:1;
57	u16 div_sync_wait;
58
59	u8 agc_state;
60	u8 differential_constellation;
61	u8 diversity_onoff;
62
63	s16 ber_monitored_layer;
64	u16 gpio_dir;
65	u16 gpio_val;
66
67	u16 revision;
68	u8 isdbt_cfg_loaded;
69	enum frontend_tune_state tune_state;
70	u32 status;
71};
72
73enum dib8000_power_mode {
74	DIB8000M_POWER_ALL = 0,
75	DIB8000M_POWER_INTERFACE_ONLY,
76};
77
78static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
79{
80	u8 wb[2] = { reg >> 8, reg & 0xff };
81	u8 rb[2];
82	struct i2c_msg msg[2] = {
83		{.addr = i2c->addr >> 1,.flags = 0,.buf = wb,.len = 2},
84		{.addr = i2c->addr >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2},
85	};
86
87	if (i2c_transfer(i2c->adap, msg, 2) != 2)
88		dprintk("i2c read error on %d", reg);
89
90	return (rb[0] << 8) | rb[1];
91}
92
93static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
94{
95	return dib8000_i2c_read16(&state->i2c, reg);
96}
97
98static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
99{
100	u16 rw[2];
101
102	rw[0] = dib8000_read_word(state, reg + 0);
103	rw[1] = dib8000_read_word(state, reg + 1);
104
105	return ((rw[0] << 16) | (rw[1]));
106}
107
108static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
109{
110	u8 b[4] = {
111		(reg >> 8) & 0xff, reg & 0xff,
112		(val >> 8) & 0xff, val & 0xff,
113	};
114	struct i2c_msg msg = {
115		.addr = i2c->addr >> 1,.flags = 0,.buf = b,.len = 4
116	};
117	return i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
118}
119
120static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
121{
122	return dib8000_i2c_write16(&state->i2c, reg, val);
123}
124
125static const int16_t coeff_2k_sb_1seg_dqpsk[8] = {
126	(769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
127	    (920 << 5) | 0x09
128};
129
130static const int16_t coeff_2k_sb_1seg[8] = {
131	(692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
132};
133
134static const int16_t coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
135	(832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
136	    (-931 << 5) | 0x0f
137};
138
139static const int16_t coeff_2k_sb_3seg_0dqpsk[8] = {
140	(622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
141	    (982 << 5) | 0x0c
142};
143
144static const int16_t coeff_2k_sb_3seg_1dqpsk[8] = {
145	(699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
146	    (-720 << 5) | 0x0d
147};
148
149static const int16_t coeff_2k_sb_3seg[8] = {
150	(664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
151	    (-610 << 5) | 0x0a
152};
153
154static const int16_t coeff_4k_sb_1seg_dqpsk[8] = {
155	(-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
156	    (-922 << 5) | 0x0d
157};
158
159static const int16_t coeff_4k_sb_1seg[8] = {
160	(638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
161	    (-655 << 5) | 0x0a
162};
163
164static const int16_t coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
165	(-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
166	    (-958 << 5) | 0x13
167};
168
169static const int16_t coeff_4k_sb_3seg_0dqpsk[8] = {
170	(-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
171	    (-568 << 5) | 0x0f
172};
173
174static const int16_t coeff_4k_sb_3seg_1dqpsk[8] = {
175	(-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
176	    (-848 << 5) | 0x13
177};
178
179static const int16_t coeff_4k_sb_3seg[8] = {
180	(612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
181	    (-869 << 5) | 0x13
182};
183
184static const int16_t coeff_8k_sb_1seg_dqpsk[8] = {
185	(-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
186	    (-598 << 5) | 0x10
187};
188
189static const int16_t coeff_8k_sb_1seg[8] = {
190	(673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
191	    (585 << 5) | 0x0f
192};
193
194static const int16_t coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
195	(863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
196	    (0 << 5) | 0x14
197};
198
199static const int16_t coeff_8k_sb_3seg_0dqpsk[8] = {
200	(-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
201	    (-877 << 5) | 0x15
202};
203
204static const int16_t coeff_8k_sb_3seg_1dqpsk[8] = {
205	(-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
206	    (-921 << 5) | 0x14
207};
208
209static const int16_t coeff_8k_sb_3seg[8] = {
210	(514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
211	    (690 << 5) | 0x14
212};
213
214static const int16_t ana_fe_coeff_3seg[24] = {
215	81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
216};
217
218static const int16_t ana_fe_coeff_1seg[24] = {
219	249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
220};
221
222static const int16_t ana_fe_coeff_13seg[24] = {
223	396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
224};
225
226static u16 fft_to_mode(struct dib8000_state *state)
227{
228	u16 mode;
229	switch (state->fe.dtv_property_cache.transmission_mode) {
230	case TRANSMISSION_MODE_2K:
231		mode = 1;
232		break;
233	case TRANSMISSION_MODE_4K:
234		mode = 2;
235		break;
236	default:
237	case TRANSMISSION_MODE_AUTO:
238	case TRANSMISSION_MODE_8K:
239		mode = 3;
240		break;
241	}
242	return mode;
243}
244
245static void dib8000_set_acquisition_mode(struct dib8000_state *state)
246{
247	u16 nud = dib8000_read_word(state, 298);
248	nud |= (1 << 3) | (1 << 0);
249	dprintk("acquisition mode activated");
250	dib8000_write_word(state, 298, nud);
251}
252
253static int dib8000_set_output_mode(struct dib8000_state *state, int mode)
254{
255	u16 outreg, fifo_threshold, smo_mode, sram = 0x0205;	/* by default SDRAM deintlv is enabled */
256
257	outreg = 0;
258	fifo_threshold = 1792;
259	smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
260
261	dprintk("-I-  Setting output mode for demod %p to %d", &state->fe, mode);
262
263	switch (mode) {
264	case OUTMODE_MPEG2_PAR_GATED_CLK:	// STBs with parallel gated clock
265		outreg = (1 << 10);	/* 0x0400 */
266		break;
267	case OUTMODE_MPEG2_PAR_CONT_CLK:	// STBs with parallel continues clock
268		outreg = (1 << 10) | (1 << 6);	/* 0x0440 */
269		break;
270	case OUTMODE_MPEG2_SERIAL:	// STBs with serial input
271		outreg = (1 << 10) | (2 << 6) | (0 << 1);	/* 0x0482 */
272		break;
273	case OUTMODE_DIVERSITY:
274		if (state->cfg.hostbus_diversity) {
275			outreg = (1 << 10) | (4 << 6);	/* 0x0500 */
276			sram &= 0xfdff;
277		} else
278			sram |= 0x0c00;
279		break;
280	case OUTMODE_MPEG2_FIFO:	// e.g. USB feeding
281		smo_mode |= (3 << 1);
282		fifo_threshold = 512;
283		outreg = (1 << 10) | (5 << 6);
284		break;
285	case OUTMODE_HIGH_Z:	// disable
286		outreg = 0;
287		break;
288
289	case OUTMODE_ANALOG_ADC:
290		outreg = (1 << 10) | (3 << 6);
291		dib8000_set_acquisition_mode(state);
292		break;
293
294	default:
295		dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe);
296		return -EINVAL;
297	}
298
299	if (state->cfg.output_mpeg2_in_188_bytes)
300		smo_mode |= (1 << 5);
301
302	dib8000_write_word(state, 299, smo_mode);
303	dib8000_write_word(state, 300, fifo_threshold);	/* synchronous fread */
304	dib8000_write_word(state, 1286, outreg);
305	dib8000_write_word(state, 1291, sram);
306
307	return 0;
308}
309
310static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
311{
312	struct dib8000_state *state = fe->demodulator_priv;
313	u16 sync_wait = dib8000_read_word(state, 273) & 0xfff0;
314
315	if (!state->differential_constellation) {
316		dib8000_write_word(state, 272, 1 << 9);	//dvsy_off_lmod4 = 1
317		dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2);	// sync_enable = 1; comb_mode = 2
318	} else {
319		dib8000_write_word(state, 272, 0);	//dvsy_off_lmod4 = 0
320		dib8000_write_word(state, 273, sync_wait);	// sync_enable = 0; comb_mode = 0
321	}
322	state->diversity_onoff = onoff;
323
324	switch (onoff) {
325	case 0:		/* only use the internal way - not the diversity input */
326		dib8000_write_word(state, 270, 1);
327		dib8000_write_word(state, 271, 0);
328		break;
329	case 1:		/* both ways */
330		dib8000_write_word(state, 270, 6);
331		dib8000_write_word(state, 271, 6);
332		break;
333	case 2:		/* only the diversity input */
334		dib8000_write_word(state, 270, 0);
335		dib8000_write_word(state, 271, 1);
336		break;
337	}
338	return 0;
339}
340
341static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
342{
343	/* by default everything is going to be powered off */
344	u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
345	    reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
346
347	/* now, depending on the requested mode, we power on */
348	switch (mode) {
349		/* power up everything in the demod */
350	case DIB8000M_POWER_ALL:
351		reg_774 = 0x0000;
352		reg_775 = 0x0000;
353		reg_776 = 0x0000;
354		reg_900 &= 0xfffc;
355		reg_1280 &= 0x00ff;
356		break;
357	case DIB8000M_POWER_INTERFACE_ONLY:
358		reg_1280 &= 0x00ff;
359		break;
360	}
361
362	dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
363	dib8000_write_word(state, 774, reg_774);
364	dib8000_write_word(state, 775, reg_775);
365	dib8000_write_word(state, 776, reg_776);
366	dib8000_write_word(state, 900, reg_900);
367	dib8000_write_word(state, 1280, reg_1280);
368}
369
370static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
371{
372	int ret = 0;
373	u16 reg_907 = dib8000_read_word(state, 907), reg_908 = dib8000_read_word(state, 908);
374
375	switch (no) {
376	case DIBX000_SLOW_ADC_ON:
377		reg_908 |= (1 << 1) | (1 << 0);
378		ret |= dib8000_write_word(state, 908, reg_908);
379		reg_908 &= ~(1 << 1);
380		break;
381
382	case DIBX000_SLOW_ADC_OFF:
383		reg_908 |= (1 << 1) | (1 << 0);
384		break;
385
386	case DIBX000_ADC_ON:
387		reg_907 &= 0x0fff;
388		reg_908 &= 0x0003;
389		break;
390
391	case DIBX000_ADC_OFF:	// leave the VBG voltage on
392		reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
393		reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
394		break;
395
396	case DIBX000_VBG_ENABLE:
397		reg_907 &= ~(1 << 15);
398		break;
399
400	case DIBX000_VBG_DISABLE:
401		reg_907 |= (1 << 15);
402		break;
403
404	default:
405		break;
406	}
407
408	ret |= dib8000_write_word(state, 907, reg_907);
409	ret |= dib8000_write_word(state, 908, reg_908);
410
411	return ret;
412}
413
414static int dib8000_set_bandwidth(struct dib8000_state *state, u32 bw)
415{
416	u32 timf;
417
418	if (bw == 0)
419		bw = 6000;
420
421	if (state->timf == 0) {
422		dprintk("using default timf");
423		timf = state->timf_default;
424	} else {
425		dprintk("using updated timf");
426		timf = state->timf;
427	}
428
429	dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
430	dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
431
432	return 0;
433}
434
435static int dib8000_sad_calib(struct dib8000_state *state)
436{
437/* internal */
438	dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
439	dib8000_write_word(state, 924, 776);	// 0.625*3.3 / 4096
440
441	/* do the calibration */
442	dib8000_write_word(state, 923, (1 << 0));
443	dib8000_write_word(state, 923, (0 << 0));
444
445	msleep(1);
446	return 0;
447}
448
449int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
450{
451	struct dib8000_state *state = fe->demodulator_priv;
452	if (value > 4095)
453		value = 4095;
454	state->wbd_ref = value;
455	return dib8000_write_word(state, 106, value);
456}
457
458EXPORT_SYMBOL(dib8000_set_wbd_ref);
459static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
460{
461	dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
462	dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff));	/* P_sec_len */
463	dib8000_write_word(state, 24, (u16) ((bw->internal * 1000) & 0xffff));
464	dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
465	dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
466	dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
467
468	dib8000_write_word(state, 922, bw->sad_cfg);
469}
470
471static void dib8000_reset_pll(struct dib8000_state *state)
472{
473	const struct dibx000_bandwidth_config *pll = state->cfg.pll;
474	u16 clk_cfg1;
475
476	// clk_cfg0
477	dib8000_write_word(state, 901, (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
478
479	// clk_cfg1
480	clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
481	    (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | (pll->pll_range << 1) | (pll->pll_reset << 0);
482
483	dib8000_write_word(state, 902, clk_cfg1);
484	clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
485	dib8000_write_word(state, 902, clk_cfg1);
486
487	dprintk("clk_cfg1: 0x%04x", clk_cfg1);	/* 0x507 1 0 1 000 0 0 11 1 */
488
489	/* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
490	if (state->cfg.pll->ADClkSrc == 0)
491		dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
492	else if (state->cfg.refclksel != 0)
493		dib8000_write_word(state, 904,
494				   (0 << 15) | (1 << 12) | ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | (pll->
495															ADClkSrc << 7) | (0 << 1));
496	else
497		dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
498
499	dib8000_reset_pll_common(state, pll);
500}
501
502static int dib8000_reset_gpio(struct dib8000_state *st)
503{
504	/* reset the GPIOs */
505	dib8000_write_word(st, 1029, st->cfg.gpio_dir);
506	dib8000_write_word(st, 1030, st->cfg.gpio_val);
507
508	/* TODO 782 is P_gpio_od */
509
510	dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
511
512	dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
513	return 0;
514}
515
516static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
517{
518	st->cfg.gpio_dir = dib8000_read_word(st, 1029);
519	st->cfg.gpio_dir &= ~(1 << num);	/* reset the direction bit */
520	st->cfg.gpio_dir |= (dir & 0x1) << num;	/* set the new direction */
521	dib8000_write_word(st, 1029, st->cfg.gpio_dir);
522
523	st->cfg.gpio_val = dib8000_read_word(st, 1030);
524	st->cfg.gpio_val &= ~(1 << num);	/* reset the direction bit */
525	st->cfg.gpio_val |= (val & 0x01) << num;	/* set the new value */
526	dib8000_write_word(st, 1030, st->cfg.gpio_val);
527
528	dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
529
530	return 0;
531}
532
533int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
534{
535	struct dib8000_state *state = fe->demodulator_priv;
536	return dib8000_cfg_gpio(state, num, dir, val);
537}
538
539EXPORT_SYMBOL(dib8000_set_gpio);
540static const u16 dib8000_defaults[] = {
541	/* auto search configuration - lock0 by default waiting
542	 * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
543	3, 7,
544	0x0004,
545	0x0400,
546	0x0814,
547
548	12, 11,
549	0x001b,
550	0x7740,
551	0x005b,
552	0x8d80,
553	0x01c9,
554	0xc380,
555	0x0000,
556	0x0080,
557	0x0000,
558	0x0090,
559	0x0001,
560	0xd4c0,
561
562	/*1, 32,
563	   0x6680 // P_corm_thres Lock algorithms configuration */
564
565	11, 80,			/* set ADC level to -16 */
566	(1 << 13) - 825 - 117,
567	(1 << 13) - 837 - 117,
568	(1 << 13) - 811 - 117,
569	(1 << 13) - 766 - 117,
570	(1 << 13) - 737 - 117,
571	(1 << 13) - 693 - 117,
572	(1 << 13) - 648 - 117,
573	(1 << 13) - 619 - 117,
574	(1 << 13) - 575 - 117,
575	(1 << 13) - 531 - 117,
576	(1 << 13) - 501 - 117,
577
578	4, 108,
579	0,
580	0,
581	0,
582	0,
583
584	1, 175,
585	0x0410,
586	1, 179,
587	8192,			// P_fft_nb_to_cut
588
589	6, 181,
590	0x2800,			// P_coff_corthres_ ( 2k 4k 8k ) 0x2800
591	0x2800,
592	0x2800,
593	0x2800,			// P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
594	0x2800,
595	0x2800,
596
597	2, 193,
598	0x0666,			// P_pha3_thres
599	0x0000,			// P_cti_use_cpe, P_cti_use_prog
600
601	2, 205,
602	0x200f,			// P_cspu_regul, P_cspu_win_cut
603	0x000f,			// P_des_shift_work
604
605	5, 215,
606	0x023d,			// P_adp_regul_cnt
607	0x00a4,			// P_adp_noise_cnt
608	0x00a4,			// P_adp_regul_ext
609	0x7ff0,			// P_adp_noise_ext
610	0x3ccc,			// P_adp_fil
611
612	1, 230,
613	0x0000,			// P_2d_byp_ti_num
614
615	1, 263,
616	0x800,			//P_equal_thres_wgn
617
618	1, 268,
619	(2 << 9) | 39,		// P_equal_ctrl_synchro, P_equal_speedmode
620
621	1, 270,
622	0x0001,			// P_div_lock0_wait
623	1, 285,
624	0x0020,			//p_fec_
625	1, 299,
626	0x0062,			// P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
627
628	1, 338,
629	(1 << 12) |		// P_ctrl_corm_thres4pre_freq_inh=1
630	    (1 << 10) |		// P_ctrl_pre_freq_mode_sat=1
631	    (0 << 9) |		// P_ctrl_pre_freq_inh=0
632	    (3 << 5) |		// P_ctrl_pre_freq_step=3
633	    (1 << 0),		// P_pre_freq_win_len=1
634
635	1, 903,
636	(0 << 4) | 2,		// P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW)
637
638	0,
639};
640
641static u16 dib8000_identify(struct i2c_device *client)
642{
643	u16 value;
644
645	//because of glitches sometimes
646	value = dib8000_i2c_read16(client, 896);
647
648	if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
649		dprintk("wrong Vendor ID (read=0x%x)", value);
650		return 0;
651	}
652
653	value = dib8000_i2c_read16(client, 897);
654	if (value != 0x8000 && value != 0x8001 && value != 0x8002) {
655		dprintk("wrong Device ID (%x)", value);
656		return 0;
657	}
658
659	switch (value) {
660	case 0x8000:
661		dprintk("found DiB8000A");
662		break;
663	case 0x8001:
664		dprintk("found DiB8000B");
665		break;
666	case 0x8002:
667		dprintk("found DiB8000C");
668		break;
669	}
670	return value;
671}
672
673static int dib8000_reset(struct dvb_frontend *fe)
674{
675	struct dib8000_state *state = fe->demodulator_priv;
676
677	dib8000_write_word(state, 1287, 0x0003);	/* sram lead in, rdy */
678
679	if ((state->revision = dib8000_identify(&state->i2c)) == 0)
680		return -EINVAL;
681
682	if (state->revision == 0x8000)
683		dprintk("error : dib8000 MA not supported");
684
685	dibx000_reset_i2c_master(&state->i2c_master);
686
687	dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
688
689	/* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
690	dib8000_set_adc_state(state, DIBX000_VBG_ENABLE);
691
692	/* restart all parts */
693	dib8000_write_word(state, 770, 0xffff);
694	dib8000_write_word(state, 771, 0xffff);
695	dib8000_write_word(state, 772, 0xfffc);
696	dib8000_write_word(state, 898, 0x000c);	// sad
697	dib8000_write_word(state, 1280, 0x004d);
698	dib8000_write_word(state, 1281, 0x000c);
699
700	dib8000_write_word(state, 770, 0x0000);
701	dib8000_write_word(state, 771, 0x0000);
702	dib8000_write_word(state, 772, 0x0000);
703	dib8000_write_word(state, 898, 0x0004);	// sad
704	dib8000_write_word(state, 1280, 0x0000);
705	dib8000_write_word(state, 1281, 0x0000);
706
707	/* drives */
708	if (state->cfg.drives)
709		dib8000_write_word(state, 906, state->cfg.drives);
710	else {
711		dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
712		dib8000_write_word(state, 906, 0x2d98);	// min drive SDRAM - not optimal - adjust
713	}
714
715	dib8000_reset_pll(state);
716
717	if (dib8000_reset_gpio(state) != 0)
718		dprintk("GPIO reset was not successful.");
719
720	if (dib8000_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
721		dprintk("OUTPUT_MODE could not be resetted.");
722
723	state->current_agc = NULL;
724
725	// P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
726	/* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
727	if (state->cfg.pll->ifreq == 0)
728		dib8000_write_word(state, 40, 0x0755);	/* P_iqc_corr_inh = 0 enable IQcorr block */
729	else
730		dib8000_write_word(state, 40, 0x1f55);	/* P_iqc_corr_inh = 1 disable IQcorr block */
731
732	{
733		u16 l = 0, r;
734		const u16 *n;
735		n = dib8000_defaults;
736		l = *n++;
737		while (l) {
738			r = *n++;
739			do {
740				dib8000_write_word(state, r, *n++);
741				r++;
742			} while (--l);
743			l = *n++;
744		}
745	}
746	state->isdbt_cfg_loaded = 0;
747
748	//div_cfg override for special configs
749	if (state->cfg.div_cfg != 0)
750		dib8000_write_word(state, 903, state->cfg.div_cfg);
751
752	/* unforce divstr regardless whether i2c enumeration was done or not */
753	dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
754
755	dib8000_set_bandwidth(state, 6000);
756
757	dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
758	dib8000_sad_calib(state);
759	dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
760
761	dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
762
763	return 0;
764}
765
766static void dib8000_restart_agc(struct dib8000_state *state)
767{
768	// P_restart_iqc & P_restart_agc
769	dib8000_write_word(state, 770, 0x0a00);
770	dib8000_write_word(state, 770, 0x0000);
771}
772
773static int dib8000_update_lna(struct dib8000_state *state)
774{
775	u16 dyn_gain;
776
777	if (state->cfg.update_lna) {
778		// read dyn_gain here (because it is demod-dependent and not tuner)
779		dyn_gain = dib8000_read_word(state, 390);
780
781		if (state->cfg.update_lna(&state->fe, dyn_gain)) {	// LNA has changed
782			dib8000_restart_agc(state);
783			return 1;
784		}
785	}
786	return 0;
787}
788
789static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
790{
791	struct dibx000_agc_config *agc = NULL;
792	int i;
793	if (state->current_band == band && state->current_agc != NULL)
794		return 0;
795	state->current_band = band;
796
797	for (i = 0; i < state->cfg.agc_config_count; i++)
798		if (state->cfg.agc[i].band_caps & band) {
799			agc = &state->cfg.agc[i];
800			break;
801		}
802
803	if (agc == NULL) {
804		dprintk("no valid AGC configuration found for band 0x%02x", band);
805		return -EINVAL;
806	}
807
808	state->current_agc = agc;
809
810	/* AGC */
811	dib8000_write_word(state, 76, agc->setup);
812	dib8000_write_word(state, 77, agc->inv_gain);
813	dib8000_write_word(state, 78, agc->time_stabiliz);
814	dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
815
816	// Demod AGC loop configuration
817	dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
818	dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
819
820	dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
821		state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
822
823	/* AGC continued */
824	if (state->wbd_ref != 0)
825		dib8000_write_word(state, 106, state->wbd_ref);
826	else			// use default
827		dib8000_write_word(state, 106, agc->wbd_ref);
828	dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
829	dib8000_write_word(state, 108, agc->agc1_max);
830	dib8000_write_word(state, 109, agc->agc1_min);
831	dib8000_write_word(state, 110, agc->agc2_max);
832	dib8000_write_word(state, 111, agc->agc2_min);
833	dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
834	dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
835	dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
836	dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
837
838	dib8000_write_word(state, 75, agc->agc1_pt3);
839	dib8000_write_word(state, 923, (dib8000_read_word(state, 923) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2));	/*LB : 929 -> 923 */
840
841	return 0;
842}
843
844void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
845{
846	struct dib8000_state *state = fe->demodulator_priv;
847	dib8000_set_adc_state(state, DIBX000_ADC_ON);
848	dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000)));
849}
850EXPORT_SYMBOL(dib8000_pwm_agc_reset);
851
852static int dib8000_agc_soft_split(struct dib8000_state *state)
853{
854	u16 agc, split_offset;
855
856	if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
857		return FE_CALLBACK_TIME_NEVER;
858
859	// n_agc_global
860	agc = dib8000_read_word(state, 390);
861
862	if (agc > state->current_agc->split.min_thres)
863		split_offset = state->current_agc->split.min;
864	else if (agc < state->current_agc->split.max_thres)
865		split_offset = state->current_agc->split.max;
866	else
867		split_offset = state->current_agc->split.max *
868		    (agc - state->current_agc->split.min_thres) / (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
869
870	dprintk("AGC split_offset: %d", split_offset);
871
872	// P_agc_force_split and P_agc_split_offset
873	dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
874	return 5000;
875}
876
877static int dib8000_agc_startup(struct dvb_frontend *fe)
878{
879	struct dib8000_state *state = fe->demodulator_priv;
880	enum frontend_tune_state *tune_state = &state->tune_state;
881
882	int ret = 0;
883
884	switch (*tune_state) {
885	case CT_AGC_START:
886		// set power-up level: interf+analog+AGC
887
888		dib8000_set_adc_state(state, DIBX000_ADC_ON);
889
890		if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
891			*tune_state = CT_AGC_STOP;
892			state->status = FE_STATUS_TUNE_FAILED;
893			break;
894		}
895
896		ret = 70;
897		*tune_state = CT_AGC_STEP_0;
898		break;
899
900	case CT_AGC_STEP_0:
901		//AGC initialization
902		if (state->cfg.agc_control)
903			state->cfg.agc_control(&state->fe, 1);
904
905		dib8000_restart_agc(state);
906
907		// wait AGC rough lock time
908		ret = 50;
909		*tune_state = CT_AGC_STEP_1;
910		break;
911
912	case CT_AGC_STEP_1:
913		// wait AGC accurate lock time
914		ret = 70;
915
916		if (dib8000_update_lna(state))
917			// wait only AGC rough lock time
918			ret = 50;
919		else
920			*tune_state = CT_AGC_STEP_2;
921		break;
922
923	case CT_AGC_STEP_2:
924		dib8000_agc_soft_split(state);
925
926		if (state->cfg.agc_control)
927			state->cfg.agc_control(&state->fe, 0);
928
929		*tune_state = CT_AGC_STOP;
930		break;
931	default:
932		ret = dib8000_agc_soft_split(state);
933		break;
934	}
935	return ret;
936
937}
938
939static const int32_t lut_1000ln_mant[] =
940{
941	908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
942};
943
944int32_t dib8000_get_adc_power(struct dvb_frontend *fe, uint8_t mode)
945{
946    struct dib8000_state *state = fe->demodulator_priv;
947    uint32_t ix = 0, tmp_val = 0, exp = 0, mant = 0;
948    int32_t val;
949
950    val = dib8000_read32(state, 384);
951    /* mode = 1 : ln_agcpower calc using mant-exp conversion and mantis look up table */
952    if (mode) {
953	tmp_val = val;
954	while (tmp_val >>= 1)
955		exp++;
956	mant = (val * 1000 / (1<<exp));
957	ix = (uint8_t)((mant-1000)/100); /* index of the LUT */
958	val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908); /* 1000 * ln(adcpower_real) ; 693 = 1000ln(2) ; 6908 = 1000*ln(1000) ; 20 comes from adc_real = adc_pow_int / 2**20 */
959	val = (val*256)/1000;
960    }
961    return val;
962}
963EXPORT_SYMBOL(dib8000_get_adc_power);
964
965static void dib8000_update_timf(struct dib8000_state *state)
966{
967	u32 timf = state->timf = dib8000_read32(state, 435);
968
969	dib8000_write_word(state, 29, (u16) (timf >> 16));
970	dib8000_write_word(state, 30, (u16) (timf & 0xffff));
971	dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
972}
973
974static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
975{
976	u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
977	u8 guard, crate, constellation, timeI;
978	u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
979	u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff;	// All 13 segments enabled
980	const s16 *ncoeff = NULL, *ana_fe;
981	u16 tmcc_pow = 0;
982	u16 coff_pow = 0x2800;
983	u16 init_prbs = 0xfff;
984	u16 ana_gain = 0;
985	u16 adc_target_16dB[11] = {
986		(1 << 13) - 825 - 117,
987		(1 << 13) - 837 - 117,
988		(1 << 13) - 811 - 117,
989		(1 << 13) - 766 - 117,
990		(1 << 13) - 737 - 117,
991		(1 << 13) - 693 - 117,
992		(1 << 13) - 648 - 117,
993		(1 << 13) - 619 - 117,
994		(1 << 13) - 575 - 117,
995		(1 << 13) - 531 - 117,
996		(1 << 13) - 501 - 117
997	};
998
999	if (state->ber_monitored_layer != LAYER_ALL)
1000		dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
1001	else
1002		dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
1003
1004	i = dib8000_read_word(state, 26) & 1;	// P_dds_invspec
1005	dib8000_write_word(state, 26, state->fe.dtv_property_cache.inversion ^ i);
1006
1007	if (state->fe.dtv_property_cache.isdbt_sb_mode) {
1008		//compute new dds_freq for the seg and adjust prbs
1009		int seg_offset =
1010		    state->fe.dtv_property_cache.isdbt_sb_segment_idx - (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) -
1011		    (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2);
1012		int clk = state->cfg.pll->internal;
1013		u32 segtodds = ((u32) (430 << 23) / clk) << 3;	// segtodds = SegBW / Fclk * pow(2,26)
1014		int dds_offset = seg_offset * segtodds;
1015		int new_dds, sub_channel;
1016		if ((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)	// if even
1017			dds_offset -= (int)(segtodds / 2);
1018
1019		if (state->cfg.pll->ifreq == 0) {
1020			if ((state->fe.dtv_property_cache.inversion ^ i) == 0) {
1021				dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
1022				new_dds = dds_offset;
1023			} else
1024				new_dds = dds_offset;
1025
1026			// We shift tuning frequency if the wanted segment is :
1027			//  - the segment of center frequency with an odd total number of segments
1028			//  - the segment to the left of center frequency with an even total number of segments
1029			//  - the segment to the right of center frequency with an even total number of segments
1030			if ((state->fe.dtv_property_cache.delivery_system == SYS_ISDBT) && (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
1031			    &&
1032			    (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2)
1033			      && (state->fe.dtv_property_cache.isdbt_sb_segment_idx ==
1034				  ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1035			     || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1036				 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2)))
1037			     || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1038				 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx ==
1039				     ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1040			    )) {
1041				new_dds -= ((u32) (850 << 22) / clk) << 4;	// new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
1042			}
1043		} else {
1044			if ((state->fe.dtv_property_cache.inversion ^ i) == 0)
1045				new_dds = state->cfg.pll->ifreq - dds_offset;
1046			else
1047				new_dds = state->cfg.pll->ifreq + dds_offset;
1048		}
1049		dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
1050		dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
1051		if (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2)	// if odd
1052			sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
1053		else		// if even
1054			sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
1055		sub_channel -= 6;
1056
1057		if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
1058		    || state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
1059			dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1);	//adp_pass =1
1060			dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14));	//pha3_force_pha_shift = 1
1061		} else {
1062			dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe);	//adp_pass =0
1063			dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff);	//pha3_force_pha_shift = 0
1064		}
1065
1066		switch (state->fe.dtv_property_cache.transmission_mode) {
1067		case TRANSMISSION_MODE_2K:
1068			switch (sub_channel) {
1069			case -6:
1070				init_prbs = 0x0;
1071				break;	// 41, 0, 1
1072			case -5:
1073				init_prbs = 0x423;
1074				break;	// 02~04
1075			case -4:
1076				init_prbs = 0x9;
1077				break;	// 05~07
1078			case -3:
1079				init_prbs = 0x5C7;
1080				break;	// 08~10
1081			case -2:
1082				init_prbs = 0x7A6;
1083				break;	// 11~13
1084			case -1:
1085				init_prbs = 0x3D8;
1086				break;	// 14~16
1087			case 0:
1088				init_prbs = 0x527;
1089				break;	// 17~19
1090			case 1:
1091				init_prbs = 0x7FF;
1092				break;	// 20~22
1093			case 2:
1094				init_prbs = 0x79B;
1095				break;	// 23~25
1096			case 3:
1097				init_prbs = 0x3D6;
1098				break;	// 26~28
1099			case 4:
1100				init_prbs = 0x3A2;
1101				break;	// 29~31
1102			case 5:
1103				init_prbs = 0x53B;
1104				break;	// 32~34
1105			case 6:
1106				init_prbs = 0x2F4;
1107				break;	// 35~37
1108			default:
1109			case 7:
1110				init_prbs = 0x213;
1111				break;	// 38~40
1112			}
1113			break;
1114
1115		case TRANSMISSION_MODE_4K:
1116			switch (sub_channel) {
1117			case -6:
1118				init_prbs = 0x0;
1119				break;	// 41, 0, 1
1120			case -5:
1121				init_prbs = 0x208;
1122				break;	// 02~04
1123			case -4:
1124				init_prbs = 0xC3;
1125				break;	// 05~07
1126			case -3:
1127				init_prbs = 0x7B9;
1128				break;	// 08~10
1129			case -2:
1130				init_prbs = 0x423;
1131				break;	// 11~13
1132			case -1:
1133				init_prbs = 0x5C7;
1134				break;	// 14~16
1135			case 0:
1136				init_prbs = 0x3D8;
1137				break;	// 17~19
1138			case 1:
1139				init_prbs = 0x7FF;
1140				break;	// 20~22
1141			case 2:
1142				init_prbs = 0x3D6;
1143				break;	// 23~25
1144			case 3:
1145				init_prbs = 0x53B;
1146				break;	// 26~28
1147			case 4:
1148				init_prbs = 0x213;
1149				break;	// 29~31
1150			case 5:
1151				init_prbs = 0x29;
1152				break;	// 32~34
1153			case 6:
1154				init_prbs = 0xD0;
1155				break;	// 35~37
1156			default:
1157			case 7:
1158				init_prbs = 0x48E;
1159				break;	// 38~40
1160			}
1161			break;
1162
1163		default:
1164		case TRANSMISSION_MODE_8K:
1165			switch (sub_channel) {
1166			case -6:
1167				init_prbs = 0x0;
1168				break;	// 41, 0, 1
1169			case -5:
1170				init_prbs = 0x740;
1171				break;	// 02~04
1172			case -4:
1173				init_prbs = 0x069;
1174				break;	// 05~07
1175			case -3:
1176				init_prbs = 0x7DD;
1177				break;	// 08~10
1178			case -2:
1179				init_prbs = 0x208;
1180				break;	// 11~13
1181			case -1:
1182				init_prbs = 0x7B9;
1183				break;	// 14~16
1184			case 0:
1185				init_prbs = 0x5C7;
1186				break;	// 17~19
1187			case 1:
1188				init_prbs = 0x7FF;
1189				break;	// 20~22
1190			case 2:
1191				init_prbs = 0x53B;
1192				break;	// 23~25
1193			case 3:
1194				init_prbs = 0x29;
1195				break;	// 26~28
1196			case 4:
1197				init_prbs = 0x48E;
1198				break;	// 29~31
1199			case 5:
1200				init_prbs = 0x4C4;
1201				break;	// 32~34
1202			case 6:
1203				init_prbs = 0x367;
1204				break;	// 33~37
1205			default:
1206			case 7:
1207				init_prbs = 0x684;
1208				break;	// 38~40
1209			}
1210			break;
1211		}
1212	} else {		// if not state->fe.dtv_property_cache.isdbt_sb_mode
1213		dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
1214		dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
1215		dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
1216	}
1217	/*P_mode == ?? */
1218	dib8000_write_word(state, 10, (seq << 4));
1219	//  dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
1220
1221	switch (state->fe.dtv_property_cache.guard_interval) {
1222	case GUARD_INTERVAL_1_32:
1223		guard = 0;
1224		break;
1225	case GUARD_INTERVAL_1_16:
1226		guard = 1;
1227		break;
1228	case GUARD_INTERVAL_1_8:
1229		guard = 2;
1230		break;
1231	case GUARD_INTERVAL_1_4:
1232	default:
1233		guard = 3;
1234		break;
1235	}
1236
1237	dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3));	// ADDR 1
1238
1239	max_constellation = DQPSK;
1240	for (i = 0; i < 3; i++) {
1241		switch (state->fe.dtv_property_cache.layer[i].modulation) {
1242		case DQPSK:
1243			constellation = 0;
1244			break;
1245		case QPSK:
1246			constellation = 1;
1247			break;
1248		case QAM_16:
1249			constellation = 2;
1250			break;
1251		case QAM_64:
1252		default:
1253			constellation = 3;
1254			break;
1255		}
1256
1257		switch (state->fe.dtv_property_cache.layer[i].fec) {
1258		case FEC_1_2:
1259			crate = 1;
1260			break;
1261		case FEC_2_3:
1262			crate = 2;
1263			break;
1264		case FEC_3_4:
1265			crate = 3;
1266			break;
1267		case FEC_5_6:
1268			crate = 5;
1269			break;
1270		case FEC_7_8:
1271		default:
1272			crate = 7;
1273			break;
1274		}
1275
1276		if ((state->fe.dtv_property_cache.layer[i].interleaving > 0) &&
1277		    ((state->fe.dtv_property_cache.layer[i].interleaving <= 3) ||
1278		     (state->fe.dtv_property_cache.layer[i].interleaving == 4 && state->fe.dtv_property_cache.isdbt_sb_mode == 1))
1279		    )
1280			timeI = state->fe.dtv_property_cache.layer[i].interleaving;
1281		else
1282			timeI = 0;
1283		dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe.dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
1284				   (crate << 3) | timeI);
1285		if (state->fe.dtv_property_cache.layer[i].segment_count > 0) {
1286			switch (max_constellation) {
1287			case DQPSK:
1288			case QPSK:
1289				if (state->fe.dtv_property_cache.layer[i].modulation == QAM_16 ||
1290				    state->fe.dtv_property_cache.layer[i].modulation == QAM_64)
1291					max_constellation = state->fe.dtv_property_cache.layer[i].modulation;
1292				break;
1293			case QAM_16:
1294				if (state->fe.dtv_property_cache.layer[i].modulation == QAM_64)
1295					max_constellation = state->fe.dtv_property_cache.layer[i].modulation;
1296				break;
1297			}
1298		}
1299	}
1300
1301	mode = fft_to_mode(state);
1302
1303	//dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
1304
1305	dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
1306			   ((state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe.dtv_property_cache.
1307												 isdbt_sb_mode & 1) << 4));
1308
1309	dprintk("mode = %d ; guard = %d", mode, state->fe.dtv_property_cache.guard_interval);
1310
1311	/* signal optimization parameter */
1312
1313	if (state->fe.dtv_property_cache.isdbt_partial_reception) {
1314		seg_diff_mask = (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
1315		for (i = 1; i < 3; i++)
1316			nbseg_diff +=
1317			    (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count;
1318		for (i = 0; i < nbseg_diff; i++)
1319			seg_diff_mask |= 1 << permu_seg[i + 1];
1320	} else {
1321		for (i = 0; i < 3; i++)
1322			nbseg_diff +=
1323			    (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count;
1324		for (i = 0; i < nbseg_diff; i++)
1325			seg_diff_mask |= 1 << permu_seg[i];
1326	}
1327	dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
1328
1329	state->differential_constellation = (seg_diff_mask != 0);
1330	dib8000_set_diversity_in(&state->fe, state->diversity_onoff);
1331
1332	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {	// ISDB-Tsb
1333		if (state->fe.dtv_property_cache.isdbt_partial_reception == 1)	// 3-segments
1334			seg_mask13 = 0x00E0;
1335		else		// 1-segment
1336			seg_mask13 = 0x0040;
1337	} else
1338		seg_mask13 = 0x1fff;
1339
1340	// WRITE: Mode & Diff mask
1341	dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
1342
1343	if ((seg_diff_mask) || (state->fe.dtv_property_cache.isdbt_sb_mode))
1344		dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
1345	else
1346		dib8000_write_word(state, 268, (2 << 9) | 39);	//init value
1347
1348	// ---- SMALL ----
1349	// P_small_seg_diff
1350	dib8000_write_word(state, 352, seg_diff_mask);	// ADDR 352
1351
1352	dib8000_write_word(state, 353, seg_mask13);	// ADDR 353
1353
1354/*     // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
1355	// dib8000_write_word(state, 351, (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5 );
1356
1357	// ---- SMALL ----
1358	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1359		switch (state->fe.dtv_property_cache.transmission_mode) {
1360		case TRANSMISSION_MODE_2K:
1361			if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) {	// 1-seg
1362				if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK)	// DQPSK
1363					ncoeff = coeff_2k_sb_1seg_dqpsk;
1364				else	// QPSK or QAM
1365					ncoeff = coeff_2k_sb_1seg;
1366			} else {	// 3-segments
1367				if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) {	// DQPSK on central segment
1368					if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK)	// DQPSK on external segments
1369						ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
1370					else	// QPSK or QAM on external segments
1371						ncoeff = coeff_2k_sb_3seg_0dqpsk;
1372				} else {	// QPSK or QAM on central segment
1373					if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK)	// DQPSK on external segments
1374						ncoeff = coeff_2k_sb_3seg_1dqpsk;
1375					else	// QPSK or QAM on external segments
1376						ncoeff = coeff_2k_sb_3seg;
1377				}
1378			}
1379			break;
1380
1381		case TRANSMISSION_MODE_4K:
1382			if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) {	// 1-seg
1383				if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK)	// DQPSK
1384					ncoeff = coeff_4k_sb_1seg_dqpsk;
1385				else	// QPSK or QAM
1386					ncoeff = coeff_4k_sb_1seg;
1387			} else {	// 3-segments
1388				if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) {	// DQPSK on central segment
1389					if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) {	// DQPSK on external segments
1390						ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
1391					} else {	// QPSK or QAM on external segments
1392						ncoeff = coeff_4k_sb_3seg_0dqpsk;
1393					}
1394				} else {	// QPSK or QAM on central segment
1395					if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) {	// DQPSK on external segments
1396						ncoeff = coeff_4k_sb_3seg_1dqpsk;
1397					} else	// QPSK or QAM on external segments
1398						ncoeff = coeff_4k_sb_3seg;
1399				}
1400			}
1401			break;
1402
1403		case TRANSMISSION_MODE_AUTO:
1404		case TRANSMISSION_MODE_8K:
1405		default:
1406			if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) {	// 1-seg
1407				if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK)	// DQPSK
1408					ncoeff = coeff_8k_sb_1seg_dqpsk;
1409				else	// QPSK or QAM
1410					ncoeff = coeff_8k_sb_1seg;
1411			} else {	// 3-segments
1412				if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) {	// DQPSK on central segment
1413					if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) {	// DQPSK on external segments
1414						ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
1415					} else {	// QPSK or QAM on external segments
1416						ncoeff = coeff_8k_sb_3seg_0dqpsk;
1417					}
1418				} else {	// QPSK or QAM on central segment
1419					if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) {	// DQPSK on external segments
1420						ncoeff = coeff_8k_sb_3seg_1dqpsk;
1421					} else	// QPSK or QAM on external segments
1422						ncoeff = coeff_8k_sb_3seg;
1423				}
1424			}
1425			break;
1426		}
1427		for (i = 0; i < 8; i++)
1428			dib8000_write_word(state, 343 + i, ncoeff[i]);
1429	}
1430
1431	// P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
1432	dib8000_write_word(state, 351,
1433			   (state->fe.dtv_property_cache.isdbt_sb_mode << 9) | (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
1434
1435	// ---- COFF ----
1436	// Carloff, the most robust
1437	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {	// Sound Broadcasting mode - use both TMCC and AC pilots
1438
1439		// P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
1440		// 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
1441		dib8000_write_word(state, 187,
1442				   (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 2)
1443				   | 0x3);
1444
1445/*             // P_small_coef_ext_enable = 1 */
1446/*             dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
1447
1448		if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) {	// Sound Broadcasting mode 1 seg
1449
1450			// 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)
1451			if (mode == 3)
1452				dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14));
1453			else
1454				dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14));
1455			// P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1,
1456			// P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4
1457			dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
1458			// P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1459			dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1460			// P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1461			dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1462
1463			// P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1464			dib8000_write_word(state, 181, 300);
1465			dib8000_write_word(state, 182, 150);
1466			dib8000_write_word(state, 183, 80);
1467			dib8000_write_word(state, 184, 300);
1468			dib8000_write_word(state, 185, 150);
1469			dib8000_write_word(state, 186, 80);
1470		} else {	// Sound Broadcasting mode 3 seg
1471			// P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
1472			/*                 if (mode == 3) */
1473			/*                     dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
1474			/*                 else */
1475			/*                     dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
1476			dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
1477
1478			// P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
1479			// P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4
1480			dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
1481			// P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1482			dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1483			//P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1484			dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1485
1486			// P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1487			dib8000_write_word(state, 181, 350);
1488			dib8000_write_word(state, 182, 300);
1489			dib8000_write_word(state, 183, 250);
1490			dib8000_write_word(state, 184, 350);
1491			dib8000_write_word(state, 185, 300);
1492			dib8000_write_word(state, 186, 250);
1493		}
1494
1495	} else if (state->isdbt_cfg_loaded == 0) {	// if not Sound Broadcasting mode : put default values for 13 segments
1496		dib8000_write_word(state, 180, (16 << 6) | 9);
1497		dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
1498		coff_pow = 0x2800;
1499		for (i = 0; i < 6; i++)
1500			dib8000_write_word(state, 181 + i, coff_pow);
1501
1502		// P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1,
1503		// 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
1504		dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
1505
1506		// P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6
1507		dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
1508		// P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1
1509		dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1510	}
1511	// ---- FFT ----
1512	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 && state->fe.dtv_property_cache.isdbt_partial_reception == 0)	// 1-seg
1513		dib8000_write_word(state, 178, 64);	// P_fft_powrange=64
1514	else
1515		dib8000_write_word(state, 178, 32);	// P_fft_powrange=32
1516
1517	/* make the cpil_coff_lock more robust but slower p_coff_winlen
1518	 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
1519	 */
1520	/* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
1521	   dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
1522
1523	dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask);	/* P_lmod4_seg_inh       */
1524	dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask);	/* P_pha3_seg_inh        */
1525	dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask);	/* P_tac_seg_inh         */
1526	if ((!state->fe.dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
1527		dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40);	/* P_equal_noise_seg_inh */
1528	else
1529		dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask);	/* P_equal_noise_seg_inh */
1530	dib8000_write_word(state, 287, ~seg_mask13 | 0x1000);	/* P_tmcc_seg_inh        */
1531	//dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */
1532	if (!autosearching)
1533		dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff);	/* P_tmcc_seg_eq_inh */
1534	else
1535		dib8000_write_word(state, 288, 0x1fff);	//disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels.
1536	dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000);
1537
1538	dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask));	/* P_des_seg_enabled     */
1539
1540	/* offset loop parameters */
1541	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1542		if (state->fe.dtv_property_cache.isdbt_partial_reception == 0)	// Sound Broadcasting mode 1 seg
1543			/* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1544			dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
1545
1546		else		// Sound Broadcasting mode 3 seg
1547			/* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1548			dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60);
1549	} else
1550		// TODO in 13 seg, timf_alpha can always be the same or not ?
1551		/* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
1552		dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
1553
1554	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1555		if (state->fe.dtv_property_cache.isdbt_partial_reception == 0)	// Sound Broadcasting mode 1 seg
1556			/* P_ctrl_pha_off_max=3   P_ctrl_sfreq_inh =0  P_ctrl_sfreq_step = (11-P_mode)  */
1557			dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
1558
1559		else		// Sound Broadcasting mode 3 seg
1560			/* P_ctrl_pha_off_max=3   P_ctrl_sfreq_inh =0  P_ctrl_sfreq_step = (10-P_mode)  */
1561			dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (9 - mode));
1562	} else
1563		/* P_ctrl_pha_off_max=3   P_ctrl_sfreq_inh =0  P_ctrl_sfreq_step = 9  */
1564		dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
1565
1566	/* P_dvsy_sync_wait - reuse mode */
1567	switch (state->fe.dtv_property_cache.transmission_mode) {
1568	case TRANSMISSION_MODE_8K:
1569		mode = 256;
1570		break;
1571	case TRANSMISSION_MODE_4K:
1572		mode = 128;
1573		break;
1574	default:
1575	case TRANSMISSION_MODE_2K:
1576		mode = 64;
1577		break;
1578	}
1579	if (state->cfg.diversity_delay == 0)
1580		mode = (mode * (1 << (guard)) * 3) / 2 + 48;	// add 50% SFN margin + compensate for one DVSY-fifo
1581	else
1582		mode = (mode * (1 << (guard)) * 3) / 2 + state->cfg.diversity_delay;	// add 50% SFN margin + compensate for DVSY-fifo
1583	mode <<= 4;
1584	dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | mode);
1585
1586	/* channel estimation fine configuration */
1587	switch (max_constellation) {
1588	case QAM_64:
1589		ana_gain = 0x7;	// -1 : avoid def_est saturation when ADC target is -16dB
1590		coeff[0] = 0x0148;	/* P_adp_regul_cnt 0.04 */
1591		coeff[1] = 0xfff0;	/* P_adp_noise_cnt -0.002 */
1592		coeff[2] = 0x00a4;	/* P_adp_regul_ext 0.02 */
1593		coeff[3] = 0xfff8;	/* P_adp_noise_ext -0.001 */
1594		//if (!state->cfg.hostbus_diversity) //if diversity, we should prehaps use the configuration of the max_constallation -1
1595		break;
1596	case QAM_16:
1597		ana_gain = 0x7;	// -1 : avoid def_est saturation when ADC target is -16dB
1598		coeff[0] = 0x023d;	/* P_adp_regul_cnt 0.07 */
1599		coeff[1] = 0xffdf;	/* P_adp_noise_cnt -0.004 */
1600		coeff[2] = 0x00a4;	/* P_adp_regul_ext 0.02 */
1601		coeff[3] = 0xfff0;	/* P_adp_noise_ext -0.002 */
1602		//if (!((state->cfg.hostbus_diversity) && (max_constellation == QAM_16)))
1603		break;
1604	default:
1605		ana_gain = 0;	// 0 : goes along with ADC target at -22dB to keep good mobile performance and lock at sensitivity level
1606		coeff[0] = 0x099a;	/* P_adp_regul_cnt 0.3 */
1607		coeff[1] = 0xffae;	/* P_adp_noise_cnt -0.01 */
1608		coeff[2] = 0x0333;	/* P_adp_regul_ext 0.1 */
1609		coeff[3] = 0xfff8;	/* P_adp_noise_ext -0.002 */
1610		break;
1611	}
1612	for (mode = 0; mode < 4; mode++)
1613		dib8000_write_word(state, 215 + mode, coeff[mode]);
1614
1615	// update ana_gain depending on max constellation
1616	dib8000_write_word(state, 116, ana_gain);
1617	// update ADC target depending on ana_gain
1618	if (ana_gain) {		// set -16dB ADC target for ana_gain=-1
1619		for (i = 0; i < 10; i++)
1620			dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
1621	} else {		// set -22dB ADC target for ana_gain=0
1622		for (i = 0; i < 10; i++)
1623			dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
1624	}
1625
1626	// ---- ANA_FE ----
1627	if (state->fe.dtv_property_cache.isdbt_sb_mode) {
1628		if (state->fe.dtv_property_cache.isdbt_partial_reception == 1)	// 3-segments
1629			ana_fe = ana_fe_coeff_3seg;
1630		else		// 1-segment
1631			ana_fe = ana_fe_coeff_1seg;
1632	} else
1633		ana_fe = ana_fe_coeff_13seg;
1634
1635	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0)
1636		for (mode = 0; mode < 24; mode++)
1637			dib8000_write_word(state, 117 + mode, ana_fe[mode]);
1638
1639	// ---- CHAN_BLK ----
1640	for (i = 0; i < 13; i++) {
1641		if ((((~seg_diff_mask) >> i) & 1) == 1) {
1642			P_cfr_left_edge += (1 << i) * ((i == 0) || ((((seg_mask13 & (~seg_diff_mask)) >> (i - 1)) & 1) == 0));
1643			P_cfr_right_edge += (1 << i) * ((i == 12) || ((((seg_mask13 & (~seg_diff_mask)) >> (i + 1)) & 1) == 0));
1644		}
1645	}
1646	dib8000_write_word(state, 222, P_cfr_left_edge);	// P_cfr_left_edge
1647	dib8000_write_word(state, 223, P_cfr_right_edge);	// P_cfr_right_edge
1648	// "P_cspu_left_edge"  not used => do not care
1649	// "P_cspu_right_edge" not used => do not care
1650
1651	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {	// ISDB-Tsb
1652		dib8000_write_word(state, 228, 1);	// P_2d_mode_byp=1
1653		dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0);	// P_cspu_win_cut = 0
1654		if (state->fe.dtv_property_cache.isdbt_partial_reception == 0	// 1-segment
1655		    && state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) {
1656			//dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0
1657			dib8000_write_word(state, 265, 15);	// P_equal_noise_sel = 15
1658		}
1659	} else if (state->isdbt_cfg_loaded == 0) {
1660		dib8000_write_word(state, 228, 0);	// default value
1661		dib8000_write_word(state, 265, 31);	// default value
1662		dib8000_write_word(state, 205, 0x200f);	// init value
1663	}
1664	// ---- TMCC ----
1665	for (i = 0; i < 3; i++)
1666		tmcc_pow +=
1667		    (((state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe.dtv_property_cache.layer[i].segment_count);
1668	// Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9);
1669	// Threshold is set at 1/4 of max power.
1670	tmcc_pow *= (1 << (9 - 2));
1671
1672	dib8000_write_word(state, 290, tmcc_pow);	// P_tmcc_dec_thres_2k
1673	dib8000_write_word(state, 291, tmcc_pow);	// P_tmcc_dec_thres_4k
1674	dib8000_write_word(state, 292, tmcc_pow);	// P_tmcc_dec_thres_8k
1675	//dib8000_write_word(state, 287, (1 << 13) | 0x1000 );
1676	// ---- PHA3 ----
1677
1678	if (state->isdbt_cfg_loaded == 0)
1679		dib8000_write_word(state, 250, 3285);	/*p_2d_hspeed_thr0 */
1680
1681	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
1682		state->isdbt_cfg_loaded = 0;
1683	else
1684		state->isdbt_cfg_loaded = 1;
1685
1686}
1687
1688static int dib8000_autosearch_start(struct dvb_frontend *fe)
1689{
1690	u8 factor;
1691	u32 value;
1692	struct dib8000_state *state = fe->demodulator_priv;
1693
1694	int slist = 0;
1695
1696	state->fe.dtv_property_cache.inversion = 0;
1697	if (!state->fe.dtv_property_cache.isdbt_sb_mode)
1698		state->fe.dtv_property_cache.layer[0].segment_count = 13;
1699	state->fe.dtv_property_cache.layer[0].modulation = QAM_64;
1700	state->fe.dtv_property_cache.layer[0].fec = FEC_2_3;
1701	state->fe.dtv_property_cache.layer[0].interleaving = 0;
1702
1703	//choose the right list, in sb, always do everything
1704	if (state->fe.dtv_property_cache.isdbt_sb_mode) {
1705		state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1706		state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1707		slist = 7;
1708		dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
1709	} else {
1710		if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) {
1711			if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1712				slist = 7;
1713				dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));	// P_mode = 1 to have autosearch start ok with mode2
1714			} else
1715				slist = 3;
1716		} else {
1717			if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1718				slist = 2;
1719				dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));	// P_mode = 1
1720			} else
1721				slist = 0;
1722		}
1723
1724		if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO)
1725			state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1726		if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO)
1727			state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1728
1729		dprintk("using list for autosearch : %d", slist);
1730		dib8000_set_channel(state, (unsigned char)slist, 1);
1731		//dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));  // P_mode = 1
1732
1733		factor = 1;
1734
1735		//set lock_mask values
1736		dib8000_write_word(state, 6, 0x4);
1737		dib8000_write_word(state, 7, 0x8);
1738		dib8000_write_word(state, 8, 0x1000);
1739
1740		//set lock_mask wait time values
1741		value = 50 * state->cfg.pll->internal * factor;
1742		dib8000_write_word(state, 11, (u16) ((value >> 16) & 0xffff));	// lock0 wait time
1743		dib8000_write_word(state, 12, (u16) (value & 0xffff));	// lock0 wait time
1744		value = 100 * state->cfg.pll->internal * factor;
1745		dib8000_write_word(state, 13, (u16) ((value >> 16) & 0xffff));	// lock1 wait time
1746		dib8000_write_word(state, 14, (u16) (value & 0xffff));	// lock1 wait time
1747		value = 1000 * state->cfg.pll->internal * factor;
1748		dib8000_write_word(state, 15, (u16) ((value >> 16) & 0xffff));	// lock2 wait time
1749		dib8000_write_word(state, 16, (u16) (value & 0xffff));	// lock2 wait time
1750
1751		value = dib8000_read_word(state, 0);
1752		dib8000_write_word(state, 0, (u16) ((1 << 15) | value));
1753		dib8000_read_word(state, 1284);	// reset the INT. n_irq_pending
1754		dib8000_write_word(state, 0, (u16) value);
1755
1756	}
1757
1758	return 0;
1759}
1760
1761static int dib8000_autosearch_irq(struct dvb_frontend *fe)
1762{
1763	struct dib8000_state *state = fe->demodulator_priv;
1764	u16 irq_pending = dib8000_read_word(state, 1284);
1765
1766	if (irq_pending & 0x1) {	// failed
1767		dprintk("dib8000_autosearch_irq failed");
1768		return 1;
1769	}
1770
1771	if (irq_pending & 0x2) {	// succeeded
1772		dprintk("dib8000_autosearch_irq succeeded");
1773		return 2;
1774	}
1775
1776	return 0;		// still pending
1777}
1778
1779static int dib8000_tune(struct dvb_frontend *fe)
1780{
1781	struct dib8000_state *state = fe->demodulator_priv;
1782	int ret = 0;
1783	u16 value, mode = fft_to_mode(state);
1784
1785	// we are already tuned - just resuming from suspend
1786	if (state == NULL)
1787		return -EINVAL;
1788
1789	dib8000_set_bandwidth(state, state->fe.dtv_property_cache.bandwidth_hz / 1000);
1790	dib8000_set_channel(state, 0, 0);
1791
1792	// restart demod
1793	ret |= dib8000_write_word(state, 770, 0x4000);
1794	ret |= dib8000_write_word(state, 770, 0x0000);
1795	msleep(45);
1796
1797	/* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3 */
1798
1799	// never achieved a lock before - wait for timfreq to update
1800	if (state->timf == 0) {
1801		if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1802			if (state->fe.dtv_property_cache.isdbt_partial_reception == 0)	// Sound Broadcasting mode 1 seg
1803				msleep(300);
1804			else	// Sound Broadcasting mode 3 seg
1805				msleep(500);
1806		} else		// 13 seg
1807			msleep(200);
1808	}
1809	//dump_reg(state);
1810	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1811		if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) {	// Sound Broadcasting mode 1 seg
1812
1813			/* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40  alpha to check on board */
1814			dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40);
1815			//dib8000_write_word(state, 32, (8 << 12) | (6 << 8) | 0x80);
1816
1817			/*  P_ctrl_sfreq_step= (12-P_mode)   P_ctrl_sfreq_inh =0     P_ctrl_pha_off_max  */
1818			ret |= dib8000_write_word(state, 37, (12 - mode) | ((5 + mode) << 5));
1819
1820		} else {	// Sound Broadcasting mode 3 seg
1821
1822			/* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60  alpha to check on board */
1823			dib8000_write_word(state, 32, ((12 - mode) << 12) | (6 << 8) | 0x60);
1824
1825			ret |= dib8000_write_word(state, 37, (11 - mode) | ((5 + mode) << 5));
1826		}
1827
1828	} else {		// 13 seg
1829		/* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80  alpha to check on board */
1830		dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x80);
1831
1832		ret |= dib8000_write_word(state, 37, (10 - mode) | ((5 + mode) << 5));
1833
1834	}
1835
1836	// we achieved a coff_cpil_lock - it's time to update the timf
1837	if ((dib8000_read_word(state, 568) >> 11) & 0x1)
1838		dib8000_update_timf(state);
1839
1840	//now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start
1841	dib8000_write_word(state, 6, 0x200);
1842
1843	if (state->revision == 0x8002) {
1844		value = dib8000_read_word(state, 903);
1845		dib8000_write_word(state, 903, value & ~(1 << 3));
1846		msleep(1);
1847		dib8000_write_word(state, 903, value | (1 << 3));
1848	}
1849
1850	return ret;
1851}
1852
1853static int dib8000_wakeup(struct dvb_frontend *fe)
1854{
1855	struct dib8000_state *state = fe->demodulator_priv;
1856
1857	dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
1858	dib8000_set_adc_state(state, DIBX000_ADC_ON);
1859	if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1860		dprintk("could not start Slow ADC");
1861
1862	return 0;
1863}
1864
1865static int dib8000_sleep(struct dvb_frontend *fe)
1866{
1867	struct dib8000_state *st = fe->demodulator_priv;
1868	if (1) {
1869		dib8000_set_output_mode(st, OUTMODE_HIGH_Z);
1870		dib8000_set_power_mode(st, DIB8000M_POWER_INTERFACE_ONLY);
1871		return dib8000_set_adc_state(st, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(st, DIBX000_ADC_OFF);
1872	} else {
1873
1874		return 0;
1875	}
1876}
1877
1878enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
1879{
1880	struct dib8000_state *state = fe->demodulator_priv;
1881	return state->tune_state;
1882}
1883EXPORT_SYMBOL(dib8000_get_tune_state);
1884
1885int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
1886{
1887	struct dib8000_state *state = fe->demodulator_priv;
1888	state->tune_state = tune_state;
1889	return 0;
1890}
1891EXPORT_SYMBOL(dib8000_set_tune_state);
1892
1893
1894
1895
1896static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1897{
1898	struct dib8000_state *state = fe->demodulator_priv;
1899	u16 i, val = 0;
1900
1901	fe->dtv_property_cache.bandwidth_hz = 6000000;
1902
1903	fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
1904
1905	val = dib8000_read_word(state, 570);
1906	fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
1907	switch ((val & 0x30) >> 4) {
1908	case 1:
1909		fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
1910		break;
1911	case 3:
1912	default:
1913		fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1914		break;
1915	}
1916
1917	switch (val & 0x3) {
1918	case 0:
1919		fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
1920		dprintk("dib8000_get_frontend GI = 1/32 ");
1921		break;
1922	case 1:
1923		fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
1924		dprintk("dib8000_get_frontend GI = 1/16 ");
1925		break;
1926	case 2:
1927		dprintk("dib8000_get_frontend GI = 1/8 ");
1928		fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1929		break;
1930	case 3:
1931		dprintk("dib8000_get_frontend GI = 1/4 ");
1932		fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
1933		break;
1934	}
1935
1936	val = dib8000_read_word(state, 505);
1937	fe->dtv_property_cache.isdbt_partial_reception = val & 1;
1938	dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
1939
1940	for (i = 0; i < 3; i++) {
1941		val = dib8000_read_word(state, 493 + i);
1942		fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
1943		dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
1944
1945		val = dib8000_read_word(state, 499 + i);
1946		fe->dtv_property_cache.layer[i].interleaving = val & 0x3;
1947		dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving);
1948
1949		val = dib8000_read_word(state, 481 + i);
1950		switch (val & 0x7) {
1951		case 1:
1952			fe->dtv_property_cache.layer[i].fec = FEC_1_2;
1953			dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
1954			break;
1955		case 2:
1956			fe->dtv_property_cache.layer[i].fec = FEC_2_3;
1957			dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
1958			break;
1959		case 3:
1960			fe->dtv_property_cache.layer[i].fec = FEC_3_4;
1961			dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
1962			break;
1963		case 5:
1964			fe->dtv_property_cache.layer[i].fec = FEC_5_6;
1965			dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
1966			break;
1967		default:
1968			fe->dtv_property_cache.layer[i].fec = FEC_7_8;
1969			dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
1970			break;
1971		}
1972
1973		val = dib8000_read_word(state, 487 + i);
1974		switch (val & 0x3) {
1975		case 0:
1976			dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
1977			fe->dtv_property_cache.layer[i].modulation = DQPSK;
1978			break;
1979		case 1:
1980			fe->dtv_property_cache.layer[i].modulation = QPSK;
1981			dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
1982			break;
1983		case 2:
1984			fe->dtv_property_cache.layer[i].modulation = QAM_16;
1985			dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
1986			break;
1987		case 3:
1988		default:
1989			dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
1990			fe->dtv_property_cache.layer[i].modulation = QAM_64;
1991			break;
1992		}
1993	}
1994	return 0;
1995}
1996
1997static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1998{
1999	struct dib8000_state *state = fe->demodulator_priv;
2000	int time, ret;
2001
2002	fe->dtv_property_cache.delivery_system = SYS_ISDBT;
2003
2004	dib8000_set_output_mode(state, OUTMODE_HIGH_Z);
2005
2006	if (fe->ops.tuner_ops.set_params)
2007		fe->ops.tuner_ops.set_params(fe, fep);
2008
2009	/* start up the AGC */
2010	state->tune_state = CT_AGC_START;
2011	do {
2012		time = dib8000_agc_startup(fe);
2013		if (time != FE_CALLBACK_TIME_NEVER)
2014			msleep(time / 10);
2015		else
2016			break;
2017	} while (state->tune_state != CT_AGC_STOP);
2018
2019	if (state->fe.dtv_property_cache.frequency == 0) {
2020		dprintk("dib8000: must at least specify frequency ");
2021		return 0;
2022	}
2023
2024	if (state->fe.dtv_property_cache.bandwidth_hz == 0) {
2025		dprintk("dib8000: no bandwidth specified, set to default ");
2026		state->fe.dtv_property_cache.bandwidth_hz = 6000000;
2027	}
2028
2029	state->tune_state = CT_DEMOD_START;
2030
2031	if ((state->fe.dtv_property_cache.delivery_system != SYS_ISDBT) ||
2032	    (state->fe.dtv_property_cache.inversion == INVERSION_AUTO) ||
2033	    (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
2034	    (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
2035	    (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
2036	     (state->fe.dtv_property_cache.layer[0].segment_count != 0xff) &&
2037	     (state->fe.dtv_property_cache.layer[0].segment_count != 0) &&
2038	     ((state->fe.dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
2039	      (state->fe.dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
2040	    (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
2041	     (state->fe.dtv_property_cache.layer[1].segment_count != 0xff) &&
2042	     (state->fe.dtv_property_cache.layer[1].segment_count != 0) &&
2043	     ((state->fe.dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
2044	      (state->fe.dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
2045	    (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
2046	     (state->fe.dtv_property_cache.layer[2].segment_count != 0xff) &&
2047	     (state->fe.dtv_property_cache.layer[2].segment_count != 0) &&
2048	     ((state->fe.dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
2049	      (state->fe.dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
2050	    (((state->fe.dtv_property_cache.layer[0].segment_count == 0) ||
2051	      ((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
2052	     ((state->fe.dtv_property_cache.layer[1].segment_count == 0) ||
2053	      ((state->fe.dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
2054	     ((state->fe.dtv_property_cache.layer[2].segment_count == 0) || ((state->fe.dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
2055		int i = 800, found;
2056
2057		dib8000_set_bandwidth(state, fe->dtv_property_cache.bandwidth_hz / 1000);
2058		dib8000_autosearch_start(fe);
2059		do {
2060			msleep(10);
2061			found = dib8000_autosearch_irq(fe);
2062		} while (found == 0 && i--);
2063
2064		dprintk("Frequency %d Hz, autosearch returns: %d", fep->frequency, found);
2065
2066		if (found == 0 || found == 1)
2067			return 0;	// no channel found
2068
2069		dib8000_get_frontend(fe, fep);
2070	}
2071
2072	ret = dib8000_tune(fe);
2073
2074	/* make this a config parameter */
2075	dib8000_set_output_mode(state, state->cfg.output_mode);
2076
2077	return ret;
2078}
2079
2080static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2081{
2082	struct dib8000_state *state = fe->demodulator_priv;
2083	u16 lock = dib8000_read_word(state, 568);
2084
2085	*stat = 0;
2086
2087	if ((lock >> 13) & 1)
2088		*stat |= FE_HAS_SIGNAL;
2089
2090	if ((lock >> 8) & 1) /* Equal */
2091		*stat |= FE_HAS_CARRIER;
2092
2093	if (((lock >> 1) & 0xf) == 0xf) /* TMCC_SYNC */
2094		*stat |= FE_HAS_SYNC;
2095
2096	if (((lock >> 12) & 1) && ((lock >> 5) & 7)) /* FEC MPEG */
2097		*stat |= FE_HAS_LOCK;
2098
2099	if ((lock >> 12) & 1) {
2100		lock = dib8000_read_word(state, 554); /* Viterbi Layer A */
2101		if (lock & 0x01)
2102			*stat |= FE_HAS_VITERBI;
2103
2104		lock = dib8000_read_word(state, 555); /* Viterbi Layer B */
2105		if (lock & 0x01)
2106			*stat |= FE_HAS_VITERBI;
2107
2108		lock = dib8000_read_word(state, 556); /* Viterbi Layer C */
2109		if (lock & 0x01)
2110			*stat |= FE_HAS_VITERBI;
2111	}
2112
2113	return 0;
2114}
2115
2116static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
2117{
2118	struct dib8000_state *state = fe->demodulator_priv;
2119	*ber = (dib8000_read_word(state, 560) << 16) | dib8000_read_word(state, 561);	// 13 segments
2120	return 0;
2121}
2122
2123static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2124{
2125	struct dib8000_state *state = fe->demodulator_priv;
2126	*unc = dib8000_read_word(state, 565);	// packet error on 13 seg
2127	return 0;
2128}
2129
2130static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2131{
2132	struct dib8000_state *state = fe->demodulator_priv;
2133	u16 val = dib8000_read_word(state, 390);
2134	*strength = 65535 - val;
2135	return 0;
2136}
2137
2138static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
2139{
2140	struct dib8000_state *state = fe->demodulator_priv;
2141	u16 val;
2142	s32 signal_mant, signal_exp, noise_mant, noise_exp;
2143	u32 result = 0;
2144
2145	val = dib8000_read_word(state, 542);
2146	noise_mant = (val >> 6) & 0xff;
2147	noise_exp = (val & 0x3f);
2148
2149	val = dib8000_read_word(state, 543);
2150	signal_mant = (val >> 6) & 0xff;
2151	signal_exp = (val & 0x3f);
2152
2153	if ((noise_exp & 0x20) != 0)
2154		noise_exp -= 0x40;
2155	if ((signal_exp & 0x20) != 0)
2156		signal_exp -= 0x40;
2157
2158	if (signal_mant != 0)
2159		result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
2160	else
2161		result = intlog10(2) * 10 * signal_exp - 100;
2162	if (noise_mant != 0)
2163		result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
2164	else
2165		result -= intlog10(2) * 10 * noise_exp - 100;
2166
2167	*snr = result / ((1 << 24) / 10);
2168	return 0;
2169}
2170
2171int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
2172{
2173	int k = 0;
2174	u8 new_addr = 0;
2175	struct i2c_device client = {.adap = host };
2176
2177	for (k = no_of_demods - 1; k >= 0; k--) {
2178		/* designated i2c address */
2179		new_addr = first_addr + (k << 1);
2180
2181		client.addr = new_addr;
2182		dib8000_i2c_write16(&client, 1287, 0x0003);	/* sram lead in, rdy */
2183		if (dib8000_identify(&client) == 0) {
2184			dib8000_i2c_write16(&client, 1287, 0x0003);	/* sram lead in, rdy */
2185			client.addr = default_addr;
2186			if (dib8000_identify(&client) == 0) {
2187				dprintk("#%d: not identified", k);
2188				return -EINVAL;
2189			}
2190		}
2191
2192		/* start diversity to pull_down div_str - just for i2c-enumeration */
2193		dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
2194
2195		/* set new i2c address and force divstart */
2196		dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
2197		client.addr = new_addr;
2198		dib8000_identify(&client);
2199
2200		dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
2201	}
2202
2203	for (k = 0; k < no_of_demods; k++) {
2204		new_addr = first_addr | (k << 1);
2205		client.addr = new_addr;
2206
2207		// unforce divstr
2208		dib8000_i2c_write16(&client, 1285, new_addr << 2);
2209
2210		/* deactivate div - it was just for i2c-enumeration */
2211		dib8000_i2c_write16(&client, 1286, 0);
2212	}
2213
2214	return 0;
2215}
2216
2217EXPORT_SYMBOL(dib8000_i2c_enumeration);
2218static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
2219{
2220	tune->min_delay_ms = 1000;
2221	tune->step_size = 0;
2222	tune->max_drift = 0;
2223	return 0;
2224}
2225
2226static void dib8000_release(struct dvb_frontend *fe)
2227{
2228	struct dib8000_state *st = fe->demodulator_priv;
2229	dibx000_exit_i2c_master(&st->i2c_master);
2230	kfree(st);
2231}
2232
2233struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
2234{
2235	struct dib8000_state *st = fe->demodulator_priv;
2236	return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
2237}
2238
2239EXPORT_SYMBOL(dib8000_get_i2c_master);
2240
2241int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
2242{
2243	struct dib8000_state *st = fe->demodulator_priv;
2244    u16 val = dib8000_read_word(st, 299) & 0xffef;
2245    val |= (onoff & 0x1) << 4;
2246
2247    dprintk("pid filter enabled %d", onoff);
2248    return dib8000_write_word(st, 299, val);
2249}
2250EXPORT_SYMBOL(dib8000_pid_filter_ctrl);
2251
2252int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
2253{
2254	struct dib8000_state *st = fe->demodulator_priv;
2255    dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
2256    return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
2257}
2258EXPORT_SYMBOL(dib8000_pid_filter);
2259
2260static const struct dvb_frontend_ops dib8000_ops = {
2261	.info = {
2262		 .name = "DiBcom 8000 ISDB-T",
2263		 .type = FE_OFDM,
2264		 .frequency_min = 44250000,
2265		 .frequency_max = 867250000,
2266		 .frequency_stepsize = 62500,
2267		 .caps = FE_CAN_INVERSION_AUTO |
2268		 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2269		 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2270		 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2271		 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2272		 },
2273
2274	.release = dib8000_release,
2275
2276	.init = dib8000_wakeup,
2277	.sleep = dib8000_sleep,
2278
2279	.set_frontend = dib8000_set_frontend,
2280	.get_tune_settings = dib8000_fe_get_tune_settings,
2281	.get_frontend = dib8000_get_frontend,
2282
2283	.read_status = dib8000_read_status,
2284	.read_ber = dib8000_read_ber,
2285	.read_signal_strength = dib8000_read_signal_strength,
2286	.read_snr = dib8000_read_snr,
2287	.read_ucblocks = dib8000_read_unc_blocks,
2288};
2289
2290struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
2291{
2292	struct dvb_frontend *fe;
2293	struct dib8000_state *state;
2294
2295	dprintk("dib8000_attach");
2296
2297	state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
2298	if (state == NULL)
2299		return NULL;
2300
2301	memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
2302	state->i2c.adap = i2c_adap;
2303	state->i2c.addr = i2c_addr;
2304	state->gpio_val = cfg->gpio_val;
2305	state->gpio_dir = cfg->gpio_dir;
2306
2307	/* Ensure the output mode remains at the previous default if it's
2308	 * not specifically set by the caller.
2309	 */
2310	if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2311		state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2312
2313	fe = &state->fe;
2314	fe->demodulator_priv = state;
2315	memcpy(&state->fe.ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
2316
2317	state->timf_default = cfg->pll->timf;
2318
2319	if (dib8000_identify(&state->i2c) == 0)
2320		goto error;
2321
2322	dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
2323
2324	dib8000_reset(fe);
2325
2326	dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5));	/* ber_rs_len = 3 */
2327
2328	return fe;
2329
2330 error:
2331	kfree(state);
2332	return NULL;
2333}
2334
2335EXPORT_SYMBOL(dib8000_attach);
2336
2337MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
2338MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
2339MODULE_LICENSE("GPL");
2340