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