1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Linux-DVB Driver for DiBcom's DiB7000M and
4 *              first generation DiB7000P-demodulator-family.
5 *
6 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
7 */
8
9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10
11#include <linux/kernel.h>
12#include <linux/slab.h>
13#include <linux/i2c.h>
14#include <linux/mutex.h>
15
16#include <media/dvb_frontend.h>
17
18#include "dib7000m.h"
19
20static int debug;
21module_param(debug, int, 0644);
22MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
23
24#define dprintk(fmt, arg...) do {					\
25	if (debug)							\
26		printk(KERN_DEBUG pr_fmt("%s: " fmt),			\
27		       __func__, ##arg);				\
28} while (0)
29
30struct dib7000m_state {
31	struct dvb_frontend demod;
32    struct dib7000m_config cfg;
33
34	u8 i2c_addr;
35	struct i2c_adapter   *i2c_adap;
36
37	struct dibx000_i2c_master i2c_master;
38
39/* offset is 1 in case of the 7000MC */
40	u8 reg_offs;
41
42	u16 wbd_ref;
43
44	u8 current_band;
45	u32 current_bandwidth;
46	struct dibx000_agc_config *current_agc;
47	u32 timf;
48	u32 timf_default;
49	u32 internal_clk;
50
51	u8 div_force_off : 1;
52	u8 div_state : 1;
53	u16 div_sync_wait;
54
55	u16 revision;
56
57	u8 agc_state;
58
59	/* for the I2C transfer */
60	struct i2c_msg msg[2];
61	u8 i2c_write_buffer[4];
62	u8 i2c_read_buffer[2];
63	struct mutex i2c_buffer_lock;
64};
65
66enum dib7000m_power_mode {
67	DIB7000M_POWER_ALL = 0,
68
69	DIB7000M_POWER_NO,
70	DIB7000M_POWER_INTERF_ANALOG_AGC,
71	DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD,
72	DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD,
73	DIB7000M_POWER_INTERFACE_ONLY,
74};
75
76static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg)
77{
78	u16 ret;
79
80	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
81		dprintk("could not acquire lock\n");
82		return 0;
83	}
84
85	state->i2c_write_buffer[0] = (reg >> 8) | 0x80;
86	state->i2c_write_buffer[1] = reg & 0xff;
87
88	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
89	state->msg[0].addr = state->i2c_addr >> 1;
90	state->msg[0].flags = 0;
91	state->msg[0].buf = state->i2c_write_buffer;
92	state->msg[0].len = 2;
93	state->msg[1].addr = state->i2c_addr >> 1;
94	state->msg[1].flags = I2C_M_RD;
95	state->msg[1].buf = state->i2c_read_buffer;
96	state->msg[1].len = 2;
97
98	if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
99		dprintk("i2c read error on %d\n", reg);
100
101	ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
102	mutex_unlock(&state->i2c_buffer_lock);
103
104	return ret;
105}
106
107static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val)
108{
109	int ret;
110
111	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
112		dprintk("could not acquire lock\n");
113		return -EINVAL;
114	}
115
116	state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
117	state->i2c_write_buffer[1] = reg & 0xff;
118	state->i2c_write_buffer[2] = (val >> 8) & 0xff;
119	state->i2c_write_buffer[3] = val & 0xff;
120
121	memset(&state->msg[0], 0, sizeof(struct i2c_msg));
122	state->msg[0].addr = state->i2c_addr >> 1;
123	state->msg[0].flags = 0;
124	state->msg[0].buf = state->i2c_write_buffer;
125	state->msg[0].len = 4;
126
127	ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ?
128			-EREMOTEIO : 0);
129	mutex_unlock(&state->i2c_buffer_lock);
130	return ret;
131}
132static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf)
133{
134	u16 l = 0, r, *n;
135	n = buf;
136	l = *n++;
137	while (l) {
138		r = *n++;
139
140		if (state->reg_offs && (r >= 112 && r <= 331)) // compensate for 7000MC
141			r++;
142
143		do {
144			dib7000m_write_word(state, r, *n++);
145			r++;
146		} while (--l);
147		l = *n++;
148	}
149}
150
151static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode)
152{
153	int    ret = 0;
154	u16 outreg, fifo_threshold, smo_mode,
155		sram = 0x0005; /* by default SRAM output is disabled */
156
157	outreg = 0;
158	fifo_threshold = 1792;
159	smo_mode = (dib7000m_read_word(state, 294 + state->reg_offs) & 0x0010) | (1 << 1);
160
161	dprintk("setting output mode for demod %p to %d\n", &state->demod, mode);
162
163	switch (mode) {
164		case OUTMODE_MPEG2_PAR_GATED_CLK:   // STBs with parallel gated clock
165			outreg = (1 << 10);  /* 0x0400 */
166			break;
167		case OUTMODE_MPEG2_PAR_CONT_CLK:    // STBs with parallel continues clock
168			outreg = (1 << 10) | (1 << 6); /* 0x0440 */
169			break;
170		case OUTMODE_MPEG2_SERIAL:          // STBs with serial input
171			outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
172			break;
173		case OUTMODE_DIVERSITY:
174			if (state->cfg.hostbus_diversity)
175				outreg = (1 << 10) | (4 << 6); /* 0x0500 */
176			else
177				sram   |= 0x0c00;
178			break;
179		case OUTMODE_MPEG2_FIFO:            // e.g. USB feeding
180			smo_mode |= (3 << 1);
181			fifo_threshold = 512;
182			outreg = (1 << 10) | (5 << 6);
183			break;
184		case OUTMODE_HIGH_Z:  // disable
185			outreg = 0;
186			break;
187		default:
188			dprintk("Unhandled output_mode passed to be set for demod %p\n", &state->demod);
189			break;
190	}
191
192	if (state->cfg.output_mpeg2_in_188_bytes)
193		smo_mode |= (1 << 5) ;
194
195	ret |= dib7000m_write_word(state,  294 + state->reg_offs, smo_mode);
196	ret |= dib7000m_write_word(state,  295 + state->reg_offs, fifo_threshold); /* synchronous fread */
197	ret |= dib7000m_write_word(state, 1795, outreg);
198	ret |= dib7000m_write_word(state, 1805, sram);
199
200	if (state->revision == 0x4003) {
201		u16 clk_cfg1 = dib7000m_read_word(state, 909) & 0xfffd;
202		if (mode == OUTMODE_DIVERSITY)
203			clk_cfg1 |= (1 << 1); // P_O_CLK_en
204		dib7000m_write_word(state, 909, clk_cfg1);
205	}
206	return ret;
207}
208
209static void dib7000m_set_power_mode(struct dib7000m_state *state, enum dib7000m_power_mode mode)
210{
211	/* by default everything is going to be powered off */
212	u16 reg_903 = 0xffff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906  = 0x3fff;
213	u8  offset = 0;
214
215	/* now, depending on the requested mode, we power on */
216	switch (mode) {
217		/* power up everything in the demod */
218		case DIB7000M_POWER_ALL:
219			reg_903 = 0x0000; reg_904 = 0x0000; reg_905 = 0x0000; reg_906 = 0x0000;
220			break;
221
222		/* just leave power on the control-interfaces: GPIO and (I2C or SDIO or SRAM) */
223		case DIB7000M_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C or SRAM */
224			reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 2));
225			break;
226
227		case DIB7000M_POWER_INTERF_ANALOG_AGC:
228			reg_903 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10));
229			reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2));
230			reg_906 &= ~((1 << 0));
231			break;
232
233		case DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD:
234			reg_903 = 0x0000; reg_904 = 0x801f; reg_905 = 0x0000; reg_906 = 0x0000;
235			break;
236
237		case DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD:
238			reg_903 = 0x0000; reg_904 = 0x8000; reg_905 = 0x010b; reg_906 = 0x0000;
239			break;
240		case DIB7000M_POWER_NO:
241			break;
242	}
243
244	/* always power down unused parts */
245	if (!state->cfg.mobile_mode)
246		reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1);
247
248	/* P_sdio_select_clk = 0 on MC and after*/
249	if (state->revision != 0x4000)
250		reg_906 <<= 1;
251
252	if (state->revision == 0x4003)
253		offset = 1;
254
255	dib7000m_write_word(state, 903 + offset, reg_903);
256	dib7000m_write_word(state, 904 + offset, reg_904);
257	dib7000m_write_word(state, 905 + offset, reg_905);
258	dib7000m_write_word(state, 906 + offset, reg_906);
259}
260
261static int dib7000m_set_adc_state(struct dib7000m_state *state, enum dibx000_adc_states no)
262{
263	int ret = 0;
264	u16 reg_913 = dib7000m_read_word(state, 913),
265	       reg_914 = dib7000m_read_word(state, 914);
266
267	switch (no) {
268		case DIBX000_SLOW_ADC_ON:
269			reg_914 |= (1 << 1) | (1 << 0);
270			ret |= dib7000m_write_word(state, 914, reg_914);
271			reg_914 &= ~(1 << 1);
272			break;
273
274		case DIBX000_SLOW_ADC_OFF:
275			reg_914 |=  (1 << 1) | (1 << 0);
276			break;
277
278		case DIBX000_ADC_ON:
279			if (state->revision == 0x4000) { // workaround for PA/MA
280				// power-up ADC
281				dib7000m_write_word(state, 913, 0);
282				dib7000m_write_word(state, 914, reg_914 & 0x3);
283				// power-down bandgag
284				dib7000m_write_word(state, 913, (1 << 15));
285				dib7000m_write_word(state, 914, reg_914 & 0x3);
286			}
287
288			reg_913 &= 0x0fff;
289			reg_914 &= 0x0003;
290			break;
291
292		case DIBX000_ADC_OFF: // leave the VBG voltage on
293			reg_913 |= (1 << 14) | (1 << 13) | (1 << 12);
294			reg_914 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
295			break;
296
297		case DIBX000_VBG_ENABLE:
298			reg_913 &= ~(1 << 15);
299			break;
300
301		case DIBX000_VBG_DISABLE:
302			reg_913 |= (1 << 15);
303			break;
304
305		default:
306			break;
307	}
308
309//	dprintk("913: %x, 914: %x\n", reg_913, reg_914);
310	ret |= dib7000m_write_word(state, 913, reg_913);
311	ret |= dib7000m_write_word(state, 914, reg_914);
312
313	return ret;
314}
315
316static int dib7000m_set_bandwidth(struct dib7000m_state *state, u32 bw)
317{
318	u32 timf;
319
320	if (!bw)
321		bw = 8000;
322
323	// store the current bandwidth for later use
324	state->current_bandwidth = bw;
325
326	if (state->timf == 0) {
327		dprintk("using default timf\n");
328		timf = state->timf_default;
329	} else {
330		dprintk("using updated timf\n");
331		timf = state->timf;
332	}
333
334	timf = timf * (bw / 50) / 160;
335
336	dib7000m_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
337	dib7000m_write_word(state, 24, (u16) ((timf      ) & 0xffff));
338
339	return 0;
340}
341
342static int dib7000m_set_diversity_in(struct dvb_frontend *demod, int onoff)
343{
344	struct dib7000m_state *state = demod->demodulator_priv;
345
346	if (state->div_force_off) {
347		dprintk("diversity combination deactivated - forced by COFDM parameters\n");
348		onoff = 0;
349	}
350	state->div_state = (u8)onoff;
351
352	if (onoff) {
353		dib7000m_write_word(state, 263 + state->reg_offs, 6);
354		dib7000m_write_word(state, 264 + state->reg_offs, 6);
355		dib7000m_write_word(state, 266 + state->reg_offs, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
356	} else {
357		dib7000m_write_word(state, 263 + state->reg_offs, 1);
358		dib7000m_write_word(state, 264 + state->reg_offs, 0);
359		dib7000m_write_word(state, 266 + state->reg_offs, 0);
360	}
361
362	return 0;
363}
364
365static int dib7000m_sad_calib(struct dib7000m_state *state)
366{
367
368/* internal */
369//	dib7000m_write_word(state, 928, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writing in set_bandwidth
370	dib7000m_write_word(state, 929, (0 << 1) | (0 << 0));
371	dib7000m_write_word(state, 930, 776); // 0.625*3.3 / 4096
372
373	/* do the calibration */
374	dib7000m_write_word(state, 929, (1 << 0));
375	dib7000m_write_word(state, 929, (0 << 0));
376
377	msleep(1);
378
379	return 0;
380}
381
382static void dib7000m_reset_pll_common(struct dib7000m_state *state, const struct dibx000_bandwidth_config *bw)
383{
384	dib7000m_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff));
385	dib7000m_write_word(state, 19, (u16) ( (bw->internal*1000)        & 0xffff));
386	dib7000m_write_word(state, 21, (u16) ( (bw->ifreq          >> 16) & 0xffff));
387	dib7000m_write_word(state, 22, (u16) (  bw->ifreq                 & 0xffff));
388
389	dib7000m_write_word(state, 928, bw->sad_cfg);
390}
391
392static void dib7000m_reset_pll(struct dib7000m_state *state)
393{
394	const struct dibx000_bandwidth_config *bw = state->cfg.bw;
395	u16 reg_907,reg_910;
396
397	/* default */
398	reg_907 = (bw->pll_bypass << 15) | (bw->modulo << 7) |
399		(bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) |
400		(bw->enable_refdiv << 1) | (0 << 0);
401	reg_910 = (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset;
402
403	// for this oscillator frequency should be 30 MHz for the Master (default values in the board_parameters give that value)
404	// this is only working only for 30 MHz crystals
405	if (!state->cfg.quartz_direct) {
406		reg_910 |= (1 << 5);  // forcing the predivider to 1
407
408		// if the previous front-end is baseband, its output frequency is 15 MHz (prev freq divided by 2)
409		if(state->cfg.input_clk_is_div_2)
410			reg_907 |= (16 << 9);
411		else // otherwise the previous front-end puts out its input (default 30MHz) - no extra division necessary
412			reg_907 |= (8 << 9);
413	} else {
414		reg_907 |= (bw->pll_ratio & 0x3f) << 9;
415		reg_910 |= (bw->pll_prediv << 5);
416	}
417
418	dib7000m_write_word(state, 910, reg_910); // pll cfg
419	dib7000m_write_word(state, 907, reg_907); // clk cfg0
420	dib7000m_write_word(state, 908, 0x0006);  // clk_cfg1
421
422	dib7000m_reset_pll_common(state, bw);
423}
424
425static void dib7000mc_reset_pll(struct dib7000m_state *state)
426{
427	const struct dibx000_bandwidth_config *bw = state->cfg.bw;
428	u16 clk_cfg1;
429
430	// clk_cfg0
431	dib7000m_write_word(state, 907, (bw->pll_prediv << 8) | (bw->pll_ratio << 0));
432
433	// clk_cfg1
434	//dib7000m_write_word(state, 908, (1 << 14) | (3 << 12) |(0 << 11) |
435	clk_cfg1 = (0 << 14) | (3 << 12) |(0 << 11) |
436			(bw->IO_CLK_en_core << 10) | (bw->bypclk_div << 5) | (bw->enable_refdiv << 4) |
437			(1 << 3) | (bw->pll_range << 1) | (bw->pll_reset << 0);
438	dib7000m_write_word(state, 908, clk_cfg1);
439	clk_cfg1 = (clk_cfg1 & 0xfff7) | (bw->pll_bypass << 3);
440	dib7000m_write_word(state, 908, clk_cfg1);
441
442	// smpl_cfg
443	dib7000m_write_word(state, 910, (1 << 12) | (2 << 10) | (bw->modulo << 8) | (bw->ADClkSrc << 7));
444
445	dib7000m_reset_pll_common(state, bw);
446}
447
448static int dib7000m_reset_gpio(struct dib7000m_state *st)
449{
450	/* reset the GPIOs */
451	dib7000m_write_word(st, 773, st->cfg.gpio_dir);
452	dib7000m_write_word(st, 774, st->cfg.gpio_val);
453
454	/* TODO 782 is P_gpio_od */
455
456	dib7000m_write_word(st, 775, st->cfg.gpio_pwm_pos);
457
458	dib7000m_write_word(st, 780, st->cfg.pwm_freq_div);
459	return 0;
460}
461
462static u16 dib7000m_defaults_common[] =
463
464{
465	// auto search configuration
466	3, 2,
467		0x0004,
468		0x1000,
469		0x0814,
470
471	12, 6,
472		0x001b,
473		0x7740,
474		0x005b,
475		0x8d80,
476		0x01c9,
477		0xc380,
478		0x0000,
479		0x0080,
480		0x0000,
481		0x0090,
482		0x0001,
483		0xd4c0,
484
485	1, 26,
486		0x6680, // P_corm_thres Lock algorithms configuration
487
488	1, 170,
489		0x0410, // P_palf_alpha_regul, P_palf_filter_freeze, P_palf_filter_on
490
491	8, 173,
492		0,
493		0,
494		0,
495		0,
496		0,
497		0,
498		0,
499		0,
500
501	1, 182,
502		8192, // P_fft_nb_to_cut
503
504	2, 195,
505		0x0ccd, // P_pha3_thres
506		0,      // P_cti_use_cpe, P_cti_use_prog
507
508	1, 205,
509		0x200f, // P_cspu_regul, P_cspu_win_cut
510
511	5, 214,
512		0x023d, // P_adp_regul_cnt
513		0x00a4, // P_adp_noise_cnt
514		0x00a4, // P_adp_regul_ext
515		0x7ff0, // P_adp_noise_ext
516		0x3ccc, // P_adp_fil
517
518	1, 226,
519		0, // P_2d_byp_ti_num
520
521	1, 255,
522		0x800, // P_equal_thres_wgn
523
524	1, 263,
525		0x0001,
526
527	1, 281,
528		0x0010, // P_fec_*
529
530	1, 294,
531		0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
532
533	0
534};
535
536static u16 dib7000m_defaults[] =
537
538{
539	/* set ADC level to -16 */
540	11, 76,
541		(1 << 13) - 825 - 117,
542		(1 << 13) - 837 - 117,
543		(1 << 13) - 811 - 117,
544		(1 << 13) - 766 - 117,
545		(1 << 13) - 737 - 117,
546		(1 << 13) - 693 - 117,
547		(1 << 13) - 648 - 117,
548		(1 << 13) - 619 - 117,
549		(1 << 13) - 575 - 117,
550		(1 << 13) - 531 - 117,
551		(1 << 13) - 501 - 117,
552
553	// Tuner IO bank: max drive (14mA)
554	1, 912,
555		0x2c8a,
556
557	1, 1817,
558		1,
559
560	0,
561};
562
563static int dib7000m_demod_reset(struct dib7000m_state *state)
564{
565	dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
566
567	/* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
568	dib7000m_set_adc_state(state, DIBX000_VBG_ENABLE);
569
570	/* restart all parts */
571	dib7000m_write_word(state,  898, 0xffff);
572	dib7000m_write_word(state,  899, 0xffff);
573	dib7000m_write_word(state,  900, 0xff0f);
574	dib7000m_write_word(state,  901, 0xfffc);
575
576	dib7000m_write_word(state,  898, 0);
577	dib7000m_write_word(state,  899, 0);
578	dib7000m_write_word(state,  900, 0);
579	dib7000m_write_word(state,  901, 0);
580
581	if (state->revision == 0x4000)
582		dib7000m_reset_pll(state);
583	else
584		dib7000mc_reset_pll(state);
585
586	if (dib7000m_reset_gpio(state) != 0)
587		dprintk("GPIO reset was not successful.\n");
588
589	if (dib7000m_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
590		dprintk("OUTPUT_MODE could not be reset.\n");
591
592	/* unforce divstr regardless whether i2c enumeration was done or not */
593	dib7000m_write_word(state, 1794, dib7000m_read_word(state, 1794) & ~(1 << 1) );
594
595	dib7000m_set_bandwidth(state, 8000);
596
597	dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON);
598	dib7000m_sad_calib(state);
599	dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
600
601	if (state->cfg.dvbt_mode)
602		dib7000m_write_word(state, 1796, 0x0); // select DVB-T output
603
604	if (state->cfg.mobile_mode)
605		dib7000m_write_word(state, 261 + state->reg_offs, 2);
606	else
607		dib7000m_write_word(state, 224 + state->reg_offs, 1);
608
609	// P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
610	if(state->cfg.tuner_is_baseband)
611		dib7000m_write_word(state, 36, 0x0755);
612	else
613		dib7000m_write_word(state, 36, 0x1f55);
614
615	// P_divclksel=3 P_divbitsel=1
616	if (state->revision == 0x4000)
617		dib7000m_write_word(state, 909, (3 << 10) | (1 << 6));
618	else
619		dib7000m_write_word(state, 909, (3 << 4) | 1);
620
621	dib7000m_write_tab(state, dib7000m_defaults_common);
622	dib7000m_write_tab(state, dib7000m_defaults);
623
624	dib7000m_set_power_mode(state, DIB7000M_POWER_INTERFACE_ONLY);
625
626	state->internal_clk = state->cfg.bw->internal;
627
628	return 0;
629}
630
631static void dib7000m_restart_agc(struct dib7000m_state *state)
632{
633	// P_restart_iqc & P_restart_agc
634	dib7000m_write_word(state, 898, 0x0c00);
635	dib7000m_write_word(state, 898, 0x0000);
636}
637
638static int dib7000m_agc_soft_split(struct dib7000m_state *state)
639{
640	u16 agc,split_offset;
641
642	if(!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
643		return 0;
644
645	// n_agc_global
646	agc = dib7000m_read_word(state, 390);
647
648	if (agc > state->current_agc->split.min_thres)
649		split_offset = state->current_agc->split.min;
650	else if (agc < state->current_agc->split.max_thres)
651		split_offset = state->current_agc->split.max;
652	else
653		split_offset = state->current_agc->split.max *
654			(agc - state->current_agc->split.min_thres) /
655			(state->current_agc->split.max_thres - state->current_agc->split.min_thres);
656
657	dprintk("AGC split_offset: %d\n", split_offset);
658
659	// P_agc_force_split and P_agc_split_offset
660	return dib7000m_write_word(state, 103, (dib7000m_read_word(state, 103) & 0xff00) | split_offset);
661}
662
663static int dib7000m_update_lna(struct dib7000m_state *state)
664{
665	u16 dyn_gain;
666
667	if (state->cfg.update_lna) {
668		// read dyn_gain here (because it is demod-dependent and not fe)
669		dyn_gain = dib7000m_read_word(state, 390);
670
671		if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed
672			dib7000m_restart_agc(state);
673			return 1;
674		}
675	}
676	return 0;
677}
678
679static int dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
680{
681	struct dibx000_agc_config *agc = NULL;
682	int i;
683	if (state->current_band == band && state->current_agc != NULL)
684		return 0;
685	state->current_band = band;
686
687	for (i = 0; i < state->cfg.agc_config_count; i++)
688		if (state->cfg.agc[i].band_caps & band) {
689			agc = &state->cfg.agc[i];
690			break;
691		}
692
693	if (agc == NULL) {
694		dprintk("no valid AGC configuration found for band 0x%02x\n", band);
695		return -EINVAL;
696	}
697
698	state->current_agc = agc;
699
700	/* AGC */
701	dib7000m_write_word(state, 72 ,  agc->setup);
702	dib7000m_write_word(state, 73 ,  agc->inv_gain);
703	dib7000m_write_word(state, 74 ,  agc->time_stabiliz);
704	dib7000m_write_word(state, 97 , (agc->alpha_level << 12) | agc->thlock);
705
706	// Demod AGC loop configuration
707	dib7000m_write_word(state, 98, (agc->alpha_mant << 5) | agc->alpha_exp);
708	dib7000m_write_word(state, 99, (agc->beta_mant  << 6) | agc->beta_exp);
709
710	dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d\n",
711		state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
712
713	/* AGC continued */
714	if (state->wbd_ref != 0)
715		dib7000m_write_word(state, 102, state->wbd_ref);
716	else // use default
717		dib7000m_write_word(state, 102, agc->wbd_ref);
718
719	dib7000m_write_word(state, 103, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8) );
720	dib7000m_write_word(state, 104,  agc->agc1_max);
721	dib7000m_write_word(state, 105,  agc->agc1_min);
722	dib7000m_write_word(state, 106,  agc->agc2_max);
723	dib7000m_write_word(state, 107,  agc->agc2_min);
724	dib7000m_write_word(state, 108, (agc->agc1_pt1 << 8) | agc->agc1_pt2 );
725	dib7000m_write_word(state, 109, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
726	dib7000m_write_word(state, 110, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
727	dib7000m_write_word(state, 111, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
728
729	if (state->revision > 0x4000) { // settings for the MC
730		dib7000m_write_word(state, 71,   agc->agc1_pt3);
731//		dprintk("929: %x %d %d\n",
732//			(dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2), agc->wbd_inv, agc->wbd_sel);
733		dib7000m_write_word(state, 929, (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2));
734	} else {
735		// wrong default values
736		u16 b[9] = { 676, 696, 717, 737, 758, 778, 799, 819, 840 };
737		for (i = 0; i < 9; i++)
738			dib7000m_write_word(state, 88 + i, b[i]);
739	}
740	return 0;
741}
742
743static void dib7000m_update_timf(struct dib7000m_state *state)
744{
745	u32 timf = (dib7000m_read_word(state, 436) << 16) | dib7000m_read_word(state, 437);
746	state->timf = timf * 160 / (state->current_bandwidth / 50);
747	dib7000m_write_word(state, 23, (u16) (timf >> 16));
748	dib7000m_write_word(state, 24, (u16) (timf & 0xffff));
749	dprintk("updated timf_frequency: %d (default: %d)\n", state->timf, state->timf_default);
750}
751
752static int dib7000m_agc_startup(struct dvb_frontend *demod)
753{
754	struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
755	struct dib7000m_state *state = demod->demodulator_priv;
756	u16 cfg_72 = dib7000m_read_word(state, 72);
757	int ret = -1;
758	u8 *agc_state = &state->agc_state;
759	u8 agc_split;
760
761	switch (state->agc_state) {
762		case 0:
763			// set power-up level: interf+analog+AGC
764			dib7000m_set_power_mode(state, DIB7000M_POWER_INTERF_ANALOG_AGC);
765			dib7000m_set_adc_state(state, DIBX000_ADC_ON);
766
767			if (dib7000m_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0)
768				return -1;
769
770			ret = 7; /* ADC power up */
771			(*agc_state)++;
772			break;
773
774		case 1:
775			/* AGC initialization */
776			if (state->cfg.agc_control)
777				state->cfg.agc_control(&state->demod, 1);
778
779			dib7000m_write_word(state, 75, 32768);
780			if (!state->current_agc->perform_agc_softsplit) {
781				/* we are using the wbd - so slow AGC startup */
782				dib7000m_write_word(state, 103, 1 << 8); /* force 0 split on WBD and restart AGC */
783				(*agc_state)++;
784				ret = 5;
785			} else {
786				/* default AGC startup */
787				(*agc_state) = 4;
788				/* wait AGC rough lock time */
789				ret = 7;
790			}
791
792			dib7000m_restart_agc(state);
793			break;
794
795		case 2: /* fast split search path after 5sec */
796			dib7000m_write_word(state,  72, cfg_72 | (1 << 4)); /* freeze AGC loop */
797			dib7000m_write_word(state, 103, 2 << 9);            /* fast split search 0.25kHz */
798			(*agc_state)++;
799			ret = 14;
800			break;
801
802	case 3: /* split search ended */
803			agc_split = (u8)dib7000m_read_word(state, 392); /* store the split value for the next time */
804			dib7000m_write_word(state, 75, dib7000m_read_word(state, 390)); /* set AGC gain start value */
805
806			dib7000m_write_word(state, 72,  cfg_72 & ~(1 << 4));   /* std AGC loop */
807			dib7000m_write_word(state, 103, (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
808
809			dib7000m_restart_agc(state);
810
811			dprintk("SPLIT %p: %u\n", demod, agc_split);
812
813			(*agc_state)++;
814			ret = 5;
815			break;
816
817		case 4: /* LNA startup */
818			/* wait AGC accurate lock time */
819			ret = 7;
820
821			if (dib7000m_update_lna(state))
822				// wait only AGC rough lock time
823				ret = 5;
824			else
825				(*agc_state)++;
826			break;
827
828		case 5:
829			dib7000m_agc_soft_split(state);
830
831			if (state->cfg.agc_control)
832				state->cfg.agc_control(&state->demod, 0);
833
834			(*agc_state)++;
835			break;
836
837		default:
838			break;
839	}
840	return ret;
841}
842
843static void dib7000m_set_channel(struct dib7000m_state *state, struct dtv_frontend_properties *ch,
844				 u8 seq)
845{
846	u16 value, est[4];
847
848	dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
849
850	/* nfft, guard, qam, alpha */
851	value = 0;
852	switch (ch->transmission_mode) {
853		case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
854		case TRANSMISSION_MODE_4K: value |= (2 << 7); break;
855		default:
856		case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
857	}
858	switch (ch->guard_interval) {
859		case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
860		case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
861		case GUARD_INTERVAL_1_4:  value |= (3 << 5); break;
862		default:
863		case GUARD_INTERVAL_1_8:  value |= (2 << 5); break;
864	}
865	switch (ch->modulation) {
866		case QPSK:  value |= (0 << 3); break;
867		case QAM_16: value |= (1 << 3); break;
868		default:
869		case QAM_64: value |= (2 << 3); break;
870	}
871	switch (HIERARCHY_1) {
872		case HIERARCHY_2: value |= 2; break;
873		case HIERARCHY_4: value |= 4; break;
874		default:
875		case HIERARCHY_1: value |= 1; break;
876	}
877	dib7000m_write_word(state, 0, value);
878	dib7000m_write_word(state, 5, (seq << 4));
879
880	/* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
881	value = 0;
882	if (1 != 0)
883		value |= (1 << 6);
884	if (ch->hierarchy == 1)
885		value |= (1 << 4);
886	if (1 == 1)
887		value |= 1;
888	switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) {
889		case FEC_2_3: value |= (2 << 1); break;
890		case FEC_3_4: value |= (3 << 1); break;
891		case FEC_5_6: value |= (5 << 1); break;
892		case FEC_7_8: value |= (7 << 1); break;
893		default:
894		case FEC_1_2: value |= (1 << 1); break;
895	}
896	dib7000m_write_word(state, 267 + state->reg_offs, value);
897
898	/* offset loop parameters */
899
900	/* P_timf_alpha = 6, P_corm_alpha=6, P_corm_thres=0x80 */
901	dib7000m_write_word(state, 26, (6 << 12) | (6 << 8) | 0x80);
902
903	/* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=1, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
904	dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (1 << 9) | (3 << 5) | (1 << 4) | (0x3));
905
906	/* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max=3 */
907	dib7000m_write_word(state, 32, (0 << 4) | 0x3);
908
909	/* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step=5 */
910	dib7000m_write_word(state, 33, (0 << 4) | 0x5);
911
912	/* P_dvsy_sync_wait */
913	switch (ch->transmission_mode) {
914		case TRANSMISSION_MODE_8K: value = 256; break;
915		case TRANSMISSION_MODE_4K: value = 128; break;
916		case TRANSMISSION_MODE_2K:
917		default: value = 64; break;
918	}
919	switch (ch->guard_interval) {
920		case GUARD_INTERVAL_1_16: value *= 2; break;
921		case GUARD_INTERVAL_1_8:  value *= 4; break;
922		case GUARD_INTERVAL_1_4:  value *= 8; break;
923		default:
924		case GUARD_INTERVAL_1_32: value *= 1; break;
925	}
926	state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
927
928	/* deactivate the possibility of diversity reception if extended interleave - not for 7000MC */
929	/* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
930	if (1 == 1 || state->revision > 0x4000)
931		state->div_force_off = 0;
932	else
933		state->div_force_off = 1;
934	dib7000m_set_diversity_in(&state->demod, state->div_state);
935
936	/* channel estimation fine configuration */
937	switch (ch->modulation) {
938		case QAM_64:
939			est[0] = 0x0148;       /* P_adp_regul_cnt 0.04 */
940			est[1] = 0xfff0;       /* P_adp_noise_cnt -0.002 */
941			est[2] = 0x00a4;       /* P_adp_regul_ext 0.02 */
942			est[3] = 0xfff8;       /* P_adp_noise_ext -0.001 */
943			break;
944		case QAM_16:
945			est[0] = 0x023d;       /* P_adp_regul_cnt 0.07 */
946			est[1] = 0xffdf;       /* P_adp_noise_cnt -0.004 */
947			est[2] = 0x00a4;       /* P_adp_regul_ext 0.02 */
948			est[3] = 0xfff0;       /* P_adp_noise_ext -0.002 */
949			break;
950		default:
951			est[0] = 0x099a;       /* P_adp_regul_cnt 0.3 */
952			est[1] = 0xffae;       /* P_adp_noise_cnt -0.01 */
953			est[2] = 0x0333;       /* P_adp_regul_ext 0.1 */
954			est[3] = 0xfff8;       /* P_adp_noise_ext -0.002 */
955			break;
956	}
957	for (value = 0; value < 4; value++)
958		dib7000m_write_word(state, 214 + value + state->reg_offs, est[value]);
959
960	// set power-up level: autosearch
961	dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD);
962}
963
964static int dib7000m_autosearch_start(struct dvb_frontend *demod)
965{
966	struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
967	struct dib7000m_state *state = demod->demodulator_priv;
968	struct dtv_frontend_properties schan;
969	int ret = 0;
970	u32 value, factor;
971
972	schan = *ch;
973
974	schan.modulation = QAM_64;
975	schan.guard_interval        = GUARD_INTERVAL_1_32;
976	schan.transmission_mode         = TRANSMISSION_MODE_8K;
977	schan.code_rate_HP = FEC_2_3;
978	schan.code_rate_LP = FEC_3_4;
979	schan.hierarchy    = 0;
980
981	dib7000m_set_channel(state, &schan, 7);
982
983	factor = BANDWIDTH_TO_KHZ(schan.bandwidth_hz);
984	if (factor >= 5000)
985		factor = 1;
986	else
987		factor = 6;
988
989	// always use the setting for 8MHz here lock_time for 7,6 MHz are longer
990	value = 30 * state->internal_clk * factor;
991	ret |= dib7000m_write_word(state, 6,  (u16) ((value >> 16) & 0xffff)); // lock0 wait time
992	ret |= dib7000m_write_word(state, 7,  (u16)  (value        & 0xffff)); // lock0 wait time
993	value = 100 * state->internal_clk * factor;
994	ret |= dib7000m_write_word(state, 8,  (u16) ((value >> 16) & 0xffff)); // lock1 wait time
995	ret |= dib7000m_write_word(state, 9,  (u16)  (value        & 0xffff)); // lock1 wait time
996	value = 500 * state->internal_clk * factor;
997	ret |= dib7000m_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
998	ret |= dib7000m_write_word(state, 11, (u16)  (value        & 0xffff)); // lock2 wait time
999
1000	// start search
1001	value = dib7000m_read_word(state, 0);
1002	ret |= dib7000m_write_word(state, 0, (u16) (value | (1 << 9)));
1003
1004	/* clear n_irq_pending */
1005	if (state->revision == 0x4000)
1006		dib7000m_write_word(state, 1793, 0);
1007	else
1008		dib7000m_read_word(state, 537);
1009
1010	ret |= dib7000m_write_word(state, 0, (u16) value);
1011
1012	return ret;
1013}
1014
1015static int dib7000m_autosearch_irq(struct dib7000m_state *state, u16 reg)
1016{
1017	u16 irq_pending = dib7000m_read_word(state, reg);
1018
1019	if (irq_pending & 0x1) { // failed
1020		dprintk("autosearch failed\n");
1021		return 1;
1022	}
1023
1024	if (irq_pending & 0x2) { // succeeded
1025		dprintk("autosearch succeeded\n");
1026		return 2;
1027	}
1028	return 0; // still pending
1029}
1030
1031static int dib7000m_autosearch_is_irq(struct dvb_frontend *demod)
1032{
1033	struct dib7000m_state *state = demod->demodulator_priv;
1034	if (state->revision == 0x4000)
1035		return dib7000m_autosearch_irq(state, 1793);
1036	else
1037		return dib7000m_autosearch_irq(state, 537);
1038}
1039
1040static int dib7000m_tune(struct dvb_frontend *demod)
1041{
1042	struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
1043	struct dib7000m_state *state = demod->demodulator_priv;
1044	int ret = 0;
1045	u16 value;
1046
1047	// we are already tuned - just resuming from suspend
1048	dib7000m_set_channel(state, ch, 0);
1049
1050	// restart demod
1051	ret |= dib7000m_write_word(state, 898, 0x4000);
1052	ret |= dib7000m_write_word(state, 898, 0x0000);
1053	msleep(45);
1054
1055	dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD);
1056	/* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
1057	ret |= dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3));
1058
1059	// never achieved a lock before - wait for timfreq to update
1060	if (state->timf == 0)
1061		msleep(200);
1062
1063	//dump_reg(state);
1064	/* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1065	value = (6 << 8) | 0x80;
1066	switch (ch->transmission_mode) {
1067		case TRANSMISSION_MODE_2K: value |= (7 << 12); break;
1068		case TRANSMISSION_MODE_4K: value |= (8 << 12); break;
1069		default:
1070		case TRANSMISSION_MODE_8K: value |= (9 << 12); break;
1071	}
1072	ret |= dib7000m_write_word(state, 26, value);
1073
1074	/* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1075	value = (0 << 4);
1076	switch (ch->transmission_mode) {
1077		case TRANSMISSION_MODE_2K: value |= 0x6; break;
1078		case TRANSMISSION_MODE_4K: value |= 0x7; break;
1079		default:
1080		case TRANSMISSION_MODE_8K: value |= 0x8; break;
1081	}
1082	ret |= dib7000m_write_word(state, 32, value);
1083
1084	/* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1085	value = (0 << 4);
1086	switch (ch->transmission_mode) {
1087		case TRANSMISSION_MODE_2K: value |= 0x6; break;
1088		case TRANSMISSION_MODE_4K: value |= 0x7; break;
1089		default:
1090		case TRANSMISSION_MODE_8K: value |= 0x8; break;
1091	}
1092	ret |= dib7000m_write_word(state, 33,  value);
1093
1094	// we achieved a lock - it's time to update the timf freq
1095	if ((dib7000m_read_word(state, 535) >> 6)  & 0x1)
1096		dib7000m_update_timf(state);
1097
1098	dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
1099	return ret;
1100}
1101
1102static int dib7000m_wakeup(struct dvb_frontend *demod)
1103{
1104	struct dib7000m_state *state = demod->demodulator_priv;
1105
1106	dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
1107
1108	if (dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1109		dprintk("could not start Slow ADC\n");
1110
1111	return 0;
1112}
1113
1114static int dib7000m_sleep(struct dvb_frontend *demod)
1115{
1116	struct dib7000m_state *st = demod->demodulator_priv;
1117	dib7000m_set_output_mode(st, OUTMODE_HIGH_Z);
1118	dib7000m_set_power_mode(st, DIB7000M_POWER_INTERFACE_ONLY);
1119	return dib7000m_set_adc_state(st, DIBX000_SLOW_ADC_OFF) |
1120		dib7000m_set_adc_state(st, DIBX000_ADC_OFF);
1121}
1122
1123static int dib7000m_identify(struct dib7000m_state *state)
1124{
1125	u16 value;
1126
1127	if ((value = dib7000m_read_word(state, 896)) != 0x01b3) {
1128		dprintk("wrong Vendor ID (0x%x)\n", value);
1129		return -EREMOTEIO;
1130	}
1131
1132	state->revision = dib7000m_read_word(state, 897);
1133	if (state->revision != 0x4000 &&
1134		state->revision != 0x4001 &&
1135		state->revision != 0x4002 &&
1136		state->revision != 0x4003) {
1137		dprintk("wrong Device ID (0x%x)\n", value);
1138		return -EREMOTEIO;
1139	}
1140
1141	/* protect this driver to be used with 7000PC */
1142	if (state->revision == 0x4000 && dib7000m_read_word(state, 769) == 0x4000) {
1143		dprintk("this driver does not work with DiB7000PC\n");
1144		return -EREMOTEIO;
1145	}
1146
1147	switch (state->revision) {
1148	case 0x4000: dprintk("found DiB7000MA/PA/MB/PB\n"); break;
1149	case 0x4001: state->reg_offs = 1; dprintk("found DiB7000HC\n"); break;
1150	case 0x4002: state->reg_offs = 1; dprintk("found DiB7000MC\n"); break;
1151	case 0x4003: state->reg_offs = 1; dprintk("found DiB9000\n"); break;
1152	}
1153
1154	return 0;
1155}
1156
1157
1158static int dib7000m_get_frontend(struct dvb_frontend* fe,
1159				 struct dtv_frontend_properties *fep)
1160{
1161	struct dib7000m_state *state = fe->demodulator_priv;
1162	u16 tps = dib7000m_read_word(state,480);
1163
1164	fep->inversion = INVERSION_AUTO;
1165
1166	fep->bandwidth_hz = BANDWIDTH_TO_HZ(state->current_bandwidth);
1167
1168	switch ((tps >> 8) & 0x3) {
1169		case 0: fep->transmission_mode = TRANSMISSION_MODE_2K; break;
1170		case 1: fep->transmission_mode = TRANSMISSION_MODE_8K; break;
1171		/* case 2: fep->transmission_mode = TRANSMISSION_MODE_4K; break; */
1172	}
1173
1174	switch (tps & 0x3) {
1175		case 0: fep->guard_interval = GUARD_INTERVAL_1_32; break;
1176		case 1: fep->guard_interval = GUARD_INTERVAL_1_16; break;
1177		case 2: fep->guard_interval = GUARD_INTERVAL_1_8; break;
1178		case 3: fep->guard_interval = GUARD_INTERVAL_1_4; break;
1179	}
1180
1181	switch ((tps >> 14) & 0x3) {
1182		case 0: fep->modulation = QPSK; break;
1183		case 1: fep->modulation = QAM_16; break;
1184		case 2:
1185		default: fep->modulation = QAM_64; break;
1186	}
1187
1188	/* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1189	/* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1190
1191	fep->hierarchy = HIERARCHY_NONE;
1192	switch ((tps >> 5) & 0x7) {
1193		case 1: fep->code_rate_HP = FEC_1_2; break;
1194		case 2: fep->code_rate_HP = FEC_2_3; break;
1195		case 3: fep->code_rate_HP = FEC_3_4; break;
1196		case 5: fep->code_rate_HP = FEC_5_6; break;
1197		case 7:
1198		default: fep->code_rate_HP = FEC_7_8; break;
1199
1200	}
1201
1202	switch ((tps >> 2) & 0x7) {
1203		case 1: fep->code_rate_LP = FEC_1_2; break;
1204		case 2: fep->code_rate_LP = FEC_2_3; break;
1205		case 3: fep->code_rate_LP = FEC_3_4; break;
1206		case 5: fep->code_rate_LP = FEC_5_6; break;
1207		case 7:
1208		default: fep->code_rate_LP = FEC_7_8; break;
1209	}
1210
1211	/* native interleaver: (dib7000m_read_word(state, 481) >>  5) & 0x1 */
1212
1213	return 0;
1214}
1215
1216static int dib7000m_set_frontend(struct dvb_frontend *fe)
1217{
1218	struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
1219	struct dib7000m_state *state = fe->demodulator_priv;
1220	int time, ret;
1221
1222	dib7000m_set_output_mode(state, OUTMODE_HIGH_Z);
1223
1224	dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->bandwidth_hz));
1225
1226	if (fe->ops.tuner_ops.set_params)
1227		fe->ops.tuner_ops.set_params(fe);
1228
1229	/* start up the AGC */
1230	state->agc_state = 0;
1231	do {
1232		time = dib7000m_agc_startup(fe);
1233		if (time != -1)
1234			msleep(time);
1235	} while (time != -1);
1236
1237	if (fep->transmission_mode == TRANSMISSION_MODE_AUTO ||
1238		fep->guard_interval    == GUARD_INTERVAL_AUTO ||
1239		fep->modulation        == QAM_AUTO ||
1240		fep->code_rate_HP      == FEC_AUTO) {
1241		int i = 800, found;
1242
1243		dib7000m_autosearch_start(fe);
1244		do {
1245			msleep(1);
1246			found = dib7000m_autosearch_is_irq(fe);
1247		} while (found == 0 && i--);
1248
1249		dprintk("autosearch returns: %d\n", found);
1250		if (found == 0 || found == 1)
1251			return 0; // no channel found
1252
1253		dib7000m_get_frontend(fe, fep);
1254	}
1255
1256	ret = dib7000m_tune(fe);
1257
1258	/* make this a config parameter */
1259	dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO);
1260	return ret;
1261}
1262
1263static int dib7000m_read_status(struct dvb_frontend *fe, enum fe_status *stat)
1264{
1265	struct dib7000m_state *state = fe->demodulator_priv;
1266	u16 lock = dib7000m_read_word(state, 535);
1267
1268	*stat = 0;
1269
1270	if (lock & 0x8000)
1271		*stat |= FE_HAS_SIGNAL;
1272	if (lock & 0x3000)
1273		*stat |= FE_HAS_CARRIER;
1274	if (lock & 0x0100)
1275		*stat |= FE_HAS_VITERBI;
1276	if (lock & 0x0010)
1277		*stat |= FE_HAS_SYNC;
1278	if (lock & 0x0008)
1279		*stat |= FE_HAS_LOCK;
1280
1281	return 0;
1282}
1283
1284static int dib7000m_read_ber(struct dvb_frontend *fe, u32 *ber)
1285{
1286	struct dib7000m_state *state = fe->demodulator_priv;
1287	*ber = (dib7000m_read_word(state, 526) << 16) | dib7000m_read_word(state, 527);
1288	return 0;
1289}
1290
1291static int dib7000m_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
1292{
1293	struct dib7000m_state *state = fe->demodulator_priv;
1294	*unc = dib7000m_read_word(state, 534);
1295	return 0;
1296}
1297
1298static int dib7000m_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1299{
1300	struct dib7000m_state *state = fe->demodulator_priv;
1301	u16 val = dib7000m_read_word(state, 390);
1302	*strength = 65535 - val;
1303	return 0;
1304}
1305
1306static int dib7000m_read_snr(struct dvb_frontend* fe, u16 *snr)
1307{
1308	*snr = 0x0000;
1309	return 0;
1310}
1311
1312static int dib7000m_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
1313{
1314	tune->min_delay_ms = 1000;
1315	return 0;
1316}
1317
1318static void dib7000m_release(struct dvb_frontend *demod)
1319{
1320	struct dib7000m_state *st = demod->demodulator_priv;
1321	dibx000_exit_i2c_master(&st->i2c_master);
1322	kfree(st);
1323}
1324
1325struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1326{
1327	struct dib7000m_state *st = demod->demodulator_priv;
1328	return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1329}
1330EXPORT_SYMBOL(dib7000m_get_i2c_master);
1331
1332int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1333{
1334	struct dib7000m_state *state = fe->demodulator_priv;
1335	u16 val = dib7000m_read_word(state, 294 + state->reg_offs) & 0xffef;
1336	val |= (onoff & 0x1) << 4;
1337	dprintk("PID filter enabled %d\n", onoff);
1338	return dib7000m_write_word(state, 294 + state->reg_offs, val);
1339}
1340EXPORT_SYMBOL(dib7000m_pid_filter_ctrl);
1341
1342int dib7000m_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1343{
1344	struct dib7000m_state *state = fe->demodulator_priv;
1345	dprintk("PID filter: index %x, PID %d, OnOff %d\n", id, pid, onoff);
1346	return dib7000m_write_word(state, 300 + state->reg_offs + id,
1347			onoff ? (1 << 13) | pid : 0);
1348}
1349EXPORT_SYMBOL(dib7000m_pid_filter);
1350
1351#if 0
1352/* used with some prototype boards */
1353int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods,
1354		u8 default_addr, struct dib7000m_config cfg[])
1355{
1356	struct dib7000m_state st = { .i2c_adap = i2c };
1357	int k = 0;
1358	u8 new_addr = 0;
1359
1360	for (k = no_of_demods-1; k >= 0; k--) {
1361		st.cfg = cfg[k];
1362
1363		/* designated i2c address */
1364		new_addr          = (0x40 + k) << 1;
1365		st.i2c_addr = new_addr;
1366		if (dib7000m_identify(&st) != 0) {
1367			st.i2c_addr = default_addr;
1368			if (dib7000m_identify(&st) != 0) {
1369				dprintk("DiB7000M #%d: not identified\n", k);
1370				return -EIO;
1371			}
1372		}
1373
1374		/* start diversity to pull_down div_str - just for i2c-enumeration */
1375		dib7000m_set_output_mode(&st, OUTMODE_DIVERSITY);
1376
1377		dib7000m_write_word(&st, 1796, 0x0); // select DVB-T output
1378
1379		/* set new i2c address and force divstart */
1380		dib7000m_write_word(&st, 1794, (new_addr << 2) | 0x2);
1381
1382		dprintk("IC %d initialized (to i2c_address 0x%x)\n", k, new_addr);
1383	}
1384
1385	for (k = 0; k < no_of_demods; k++) {
1386		st.cfg = cfg[k];
1387		st.i2c_addr = (0x40 + k) << 1;
1388
1389		// unforce divstr
1390		dib7000m_write_word(&st,1794, st.i2c_addr << 2);
1391
1392		/* deactivate div - it was just for i2c-enumeration */
1393		dib7000m_set_output_mode(&st, OUTMODE_HIGH_Z);
1394	}
1395
1396	return 0;
1397}
1398EXPORT_SYMBOL(dib7000m_i2c_enumeration);
1399#endif
1400
1401static const struct dvb_frontend_ops dib7000m_ops;
1402struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg)
1403{
1404	struct dvb_frontend *demod;
1405	struct dib7000m_state *st;
1406	st = kzalloc(sizeof(struct dib7000m_state), GFP_KERNEL);
1407	if (st == NULL)
1408		return NULL;
1409
1410	memcpy(&st->cfg, cfg, sizeof(struct dib7000m_config));
1411	st->i2c_adap = i2c_adap;
1412	st->i2c_addr = i2c_addr;
1413
1414	demod                   = &st->demod;
1415	demod->demodulator_priv = st;
1416	memcpy(&st->demod.ops, &dib7000m_ops, sizeof(struct dvb_frontend_ops));
1417	mutex_init(&st->i2c_buffer_lock);
1418
1419	st->timf_default = cfg->bw->timf;
1420
1421	if (dib7000m_identify(st) != 0)
1422		goto error;
1423
1424	if (st->revision == 0x4000)
1425		dibx000_init_i2c_master(&st->i2c_master, DIB7000, st->i2c_adap, st->i2c_addr);
1426	else
1427		dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c_adap, st->i2c_addr);
1428
1429	dib7000m_demod_reset(st);
1430
1431	return demod;
1432
1433error:
1434	kfree(st);
1435	return NULL;
1436}
1437EXPORT_SYMBOL_GPL(dib7000m_attach);
1438
1439static const struct dvb_frontend_ops dib7000m_ops = {
1440	.delsys = { SYS_DVBT },
1441	.info = {
1442		.name = "DiBcom 7000MA/MB/PA/PB/MC",
1443		.frequency_min_hz      =  44250 * kHz,
1444		.frequency_max_hz      = 867250 * kHz,
1445		.frequency_stepsize_hz = 62500,
1446		.caps = FE_CAN_INVERSION_AUTO |
1447			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1448			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1449			FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1450			FE_CAN_TRANSMISSION_MODE_AUTO |
1451			FE_CAN_GUARD_INTERVAL_AUTO |
1452			FE_CAN_RECOVER |
1453			FE_CAN_HIERARCHY_AUTO,
1454	},
1455
1456	.release              = dib7000m_release,
1457
1458	.init                 = dib7000m_wakeup,
1459	.sleep                = dib7000m_sleep,
1460
1461	.set_frontend         = dib7000m_set_frontend,
1462	.get_tune_settings    = dib7000m_fe_get_tune_settings,
1463	.get_frontend         = dib7000m_get_frontend,
1464
1465	.read_status          = dib7000m_read_status,
1466	.read_ber             = dib7000m_read_ber,
1467	.read_signal_strength = dib7000m_read_signal_strength,
1468	.read_snr             = dib7000m_read_snr,
1469	.read_ucblocks        = dib7000m_read_unc_blocks,
1470};
1471
1472MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
1473MODULE_DESCRIPTION("Driver for the DiBcom 7000MA/MB/PA/PB/MC COFDM demodulator");
1474MODULE_LICENSE("GPL");
1475