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	dib7000m_set_channel(state, ch, 0);
1045
1046	// restart demod
1047	ret |= dib7000m_write_word(state, 898, 0x4000);
1048	ret |= dib7000m_write_word(state, 898, 0x0000);
1049	msleep(45);
1050
1051	dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD);
1052	/* 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 */
1053	ret |= dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3));
1054
1055	// never achieved a lock before - wait for timfreq to update
1056	if (state->timf == 0)
1057		msleep(200);
1058
1059	//dump_reg(state);
1060	/* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1061	value = (6 << 8) | 0x80;
1062	switch (ch->transmission_mode) {
1063		case TRANSMISSION_MODE_2K: value |= (7 << 12); break;
1064		case TRANSMISSION_MODE_4K: value |= (8 << 12); break;
1065		default:
1066		case TRANSMISSION_MODE_8K: value |= (9 << 12); break;
1067	}
1068	ret |= dib7000m_write_word(state, 26, value);
1069
1070	/* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1071	value = (0 << 4);
1072	switch (ch->transmission_mode) {
1073		case TRANSMISSION_MODE_2K: value |= 0x6; break;
1074		case TRANSMISSION_MODE_4K: value |= 0x7; break;
1075		default:
1076		case TRANSMISSION_MODE_8K: value |= 0x8; break;
1077	}
1078	ret |= dib7000m_write_word(state, 32, value);
1079
1080	/* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1081	value = (0 << 4);
1082	switch (ch->transmission_mode) {
1083		case TRANSMISSION_MODE_2K: value |= 0x6; break;
1084		case TRANSMISSION_MODE_4K: value |= 0x7; break;
1085		default:
1086		case TRANSMISSION_MODE_8K: value |= 0x8; break;
1087	}
1088	ret |= dib7000m_write_word(state, 33,  value);
1089
1090	// we achieved a lock - it's time to update the timf freq
1091	if ((dib7000m_read_word(state, 535) >> 6)  & 0x1)
1092		dib7000m_update_timf(state);
1093
1094	dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
1095	return ret;
1096}
1097
1098static int dib7000m_wakeup(struct dvb_frontend *demod)
1099{
1100	struct dib7000m_state *state = demod->demodulator_priv;
1101
1102	dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
1103
1104	if (dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1105		dprintk( "could not start Slow ADC");
1106
1107	return 0;
1108}
1109
1110static int dib7000m_sleep(struct dvb_frontend *demod)
1111{
1112	struct dib7000m_state *st = demod->demodulator_priv;
1113	dib7000m_set_output_mode(st, OUTMODE_HIGH_Z);
1114	dib7000m_set_power_mode(st, DIB7000M_POWER_INTERFACE_ONLY);
1115	return dib7000m_set_adc_state(st, DIBX000_SLOW_ADC_OFF) |
1116		dib7000m_set_adc_state(st, DIBX000_ADC_OFF);
1117}
1118
1119static int dib7000m_identify(struct dib7000m_state *state)
1120{
1121	u16 value;
1122
1123	if ((value = dib7000m_read_word(state, 896)) != 0x01b3) {
1124		dprintk( "wrong Vendor ID (0x%x)",value);
1125		return -EREMOTEIO;
1126	}
1127
1128	state->revision = dib7000m_read_word(state, 897);
1129	if (state->revision != 0x4000 &&
1130		state->revision != 0x4001 &&
1131		state->revision != 0x4002 &&
1132		state->revision != 0x4003) {
1133		dprintk( "wrong Device ID (0x%x)",value);
1134		return -EREMOTEIO;
1135	}
1136
1137	/* protect this driver to be used with 7000PC */
1138	if (state->revision == 0x4000 && dib7000m_read_word(state, 769) == 0x4000) {
1139		dprintk( "this driver does not work with DiB7000PC");
1140		return -EREMOTEIO;
1141	}
1142
1143	switch (state->revision) {
1144		case 0x4000: dprintk( "found DiB7000MA/PA/MB/PB"); break;
1145		case 0x4001: state->reg_offs = 1; dprintk( "found DiB7000HC"); break;
1146		case 0x4002: state->reg_offs = 1; dprintk( "found DiB7000MC"); break;
1147		case 0x4003: state->reg_offs = 1; dprintk( "found DiB9000"); break;
1148	}
1149
1150	return 0;
1151}
1152
1153
1154static int dib7000m_get_frontend(struct dvb_frontend* fe)
1155{
1156	struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
1157	struct dib7000m_state *state = fe->demodulator_priv;
1158	u16 tps = dib7000m_read_word(state,480);
1159
1160	fep->inversion = INVERSION_AUTO;
1161
1162	fep->bandwidth_hz = BANDWIDTH_TO_HZ(state->current_bandwidth);
1163
1164	switch ((tps >> 8) & 0x3) {
1165		case 0: fep->transmission_mode = TRANSMISSION_MODE_2K; break;
1166		case 1: fep->transmission_mode = TRANSMISSION_MODE_8K; break;
1167		/* case 2: fep->transmission_mode = TRANSMISSION_MODE_4K; break; */
1168	}
1169
1170	switch (tps & 0x3) {
1171		case 0: fep->guard_interval = GUARD_INTERVAL_1_32; break;
1172		case 1: fep->guard_interval = GUARD_INTERVAL_1_16; break;
1173		case 2: fep->guard_interval = GUARD_INTERVAL_1_8; break;
1174		case 3: fep->guard_interval = GUARD_INTERVAL_1_4; break;
1175	}
1176
1177	switch ((tps >> 14) & 0x3) {
1178		case 0: fep->modulation = QPSK; break;
1179		case 1: fep->modulation = QAM_16; break;
1180		case 2:
1181		default: fep->modulation = QAM_64; break;
1182	}
1183
1184	/* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1185	/* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1186
1187	fep->hierarchy = HIERARCHY_NONE;
1188	switch ((tps >> 5) & 0x7) {
1189		case 1: fep->code_rate_HP = FEC_1_2; break;
1190		case 2: fep->code_rate_HP = FEC_2_3; break;
1191		case 3: fep->code_rate_HP = FEC_3_4; break;
1192		case 5: fep->code_rate_HP = FEC_5_6; break;
1193		case 7:
1194		default: fep->code_rate_HP = FEC_7_8; break;
1195
1196	}
1197
1198	switch ((tps >> 2) & 0x7) {
1199		case 1: fep->code_rate_LP = FEC_1_2; break;
1200		case 2: fep->code_rate_LP = FEC_2_3; break;
1201		case 3: fep->code_rate_LP = FEC_3_4; break;
1202		case 5: fep->code_rate_LP = FEC_5_6; break;
1203		case 7:
1204		default: fep->code_rate_LP = FEC_7_8; break;
1205	}
1206
1207	/* native interleaver: (dib7000m_read_word(state, 481) >>  5) & 0x1 */
1208
1209	return 0;
1210}
1211
1212static int dib7000m_set_frontend(struct dvb_frontend *fe)
1213{
1214	struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
1215	struct dib7000m_state *state = fe->demodulator_priv;
1216	int time, ret;
1217
1218	dib7000m_set_output_mode(state, OUTMODE_HIGH_Z);
1219
1220	dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->bandwidth_hz));
1221
1222	if (fe->ops.tuner_ops.set_params)
1223		fe->ops.tuner_ops.set_params(fe);
1224
1225	/* start up the AGC */
1226	state->agc_state = 0;
1227	do {
1228		time = dib7000m_agc_startup(fe);
1229		if (time != -1)
1230			msleep(time);
1231	} while (time != -1);
1232
1233	if (fep->transmission_mode == TRANSMISSION_MODE_AUTO ||
1234		fep->guard_interval    == GUARD_INTERVAL_AUTO ||
1235		fep->modulation        == QAM_AUTO ||
1236		fep->code_rate_HP      == FEC_AUTO) {
1237		int i = 800, found;
1238
1239		dib7000m_autosearch_start(fe);
1240		do {
1241			msleep(1);
1242			found = dib7000m_autosearch_is_irq(fe);
1243		} while (found == 0 && i--);
1244
1245		dprintk("autosearch returns: %d",found);
1246		if (found == 0 || found == 1)
1247			return 0; // no channel found
1248
1249		dib7000m_get_frontend(fe);
1250	}
1251
1252	ret = dib7000m_tune(fe);
1253
1254	/* make this a config parameter */
1255	dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO);
1256	return ret;
1257}
1258
1259static int dib7000m_read_status(struct dvb_frontend *fe, enum fe_status *stat)
1260{
1261	struct dib7000m_state *state = fe->demodulator_priv;
1262	u16 lock = dib7000m_read_word(state, 535);
1263
1264	*stat = 0;
1265
1266	if (lock & 0x8000)
1267		*stat |= FE_HAS_SIGNAL;
1268	if (lock & 0x3000)
1269		*stat |= FE_HAS_CARRIER;
1270	if (lock & 0x0100)
1271		*stat |= FE_HAS_VITERBI;
1272	if (lock & 0x0010)
1273		*stat |= FE_HAS_SYNC;
1274	if (lock & 0x0008)
1275		*stat |= FE_HAS_LOCK;
1276
1277	return 0;
1278}
1279
1280static int dib7000m_read_ber(struct dvb_frontend *fe, u32 *ber)
1281{
1282	struct dib7000m_state *state = fe->demodulator_priv;
1283	*ber = (dib7000m_read_word(state, 526) << 16) | dib7000m_read_word(state, 527);
1284	return 0;
1285}
1286
1287static int dib7000m_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
1288{
1289	struct dib7000m_state *state = fe->demodulator_priv;
1290	*unc = dib7000m_read_word(state, 534);
1291	return 0;
1292}
1293
1294static int dib7000m_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1295{
1296	struct dib7000m_state *state = fe->demodulator_priv;
1297	u16 val = dib7000m_read_word(state, 390);
1298	*strength = 65535 - val;
1299	return 0;
1300}
1301
1302static int dib7000m_read_snr(struct dvb_frontend* fe, u16 *snr)
1303{
1304	*snr = 0x0000;
1305	return 0;
1306}
1307
1308static int dib7000m_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
1309{
1310	tune->min_delay_ms = 1000;
1311	return 0;
1312}
1313
1314static void dib7000m_release(struct dvb_frontend *demod)
1315{
1316	struct dib7000m_state *st = demod->demodulator_priv;
1317	dibx000_exit_i2c_master(&st->i2c_master);
1318	kfree(st);
1319}
1320
1321struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1322{
1323	struct dib7000m_state *st = demod->demodulator_priv;
1324	return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1325}
1326EXPORT_SYMBOL(dib7000m_get_i2c_master);
1327
1328int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1329{
1330	struct dib7000m_state *state = fe->demodulator_priv;
1331	u16 val = dib7000m_read_word(state, 294 + state->reg_offs) & 0xffef;
1332	val |= (onoff & 0x1) << 4;
1333	dprintk("PID filter enabled %d", onoff);
1334	return dib7000m_write_word(state, 294 + state->reg_offs, val);
1335}
1336EXPORT_SYMBOL(dib7000m_pid_filter_ctrl);
1337
1338int dib7000m_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1339{
1340	struct dib7000m_state *state = fe->demodulator_priv;
1341	dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
1342	return dib7000m_write_word(state, 300 + state->reg_offs + id,
1343			onoff ? (1 << 13) | pid : 0);
1344}
1345EXPORT_SYMBOL(dib7000m_pid_filter);
1346
1347#if 0
1348/* used with some prototype boards */
1349int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods,
1350		u8 default_addr, struct dib7000m_config cfg[])
1351{
1352	struct dib7000m_state st = { .i2c_adap = i2c };
1353	int k = 0;
1354	u8 new_addr = 0;
1355
1356	for (k = no_of_demods-1; k >= 0; k--) {
1357		st.cfg = cfg[k];
1358
1359		/* designated i2c address */
1360		new_addr          = (0x40 + k) << 1;
1361		st.i2c_addr = new_addr;
1362		if (dib7000m_identify(&st) != 0) {
1363			st.i2c_addr = default_addr;
1364			if (dib7000m_identify(&st) != 0) {
1365				dprintk("DiB7000M #%d: not identified", k);
1366				return -EIO;
1367			}
1368		}
1369
1370		/* start diversity to pull_down div_str - just for i2c-enumeration */
1371		dib7000m_set_output_mode(&st, OUTMODE_DIVERSITY);
1372
1373		dib7000m_write_word(&st, 1796, 0x0); // select DVB-T output
1374
1375		/* set new i2c address and force divstart */
1376		dib7000m_write_word(&st, 1794, (new_addr << 2) | 0x2);
1377
1378		dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
1379	}
1380
1381	for (k = 0; k < no_of_demods; k++) {
1382		st.cfg = cfg[k];
1383		st.i2c_addr = (0x40 + k) << 1;
1384
1385		// unforce divstr
1386		dib7000m_write_word(&st,1794, st.i2c_addr << 2);
1387
1388		/* deactivate div - it was just for i2c-enumeration */
1389		dib7000m_set_output_mode(&st, OUTMODE_HIGH_Z);
1390	}
1391
1392	return 0;
1393}
1394EXPORT_SYMBOL(dib7000m_i2c_enumeration);
1395#endif
1396
1397static struct dvb_frontend_ops dib7000m_ops;
1398struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg)
1399{
1400	struct dvb_frontend *demod;
1401	struct dib7000m_state *st;
1402	st = kzalloc(sizeof(struct dib7000m_state), GFP_KERNEL);
1403	if (st == NULL)
1404		return NULL;
1405
1406	memcpy(&st->cfg, cfg, sizeof(struct dib7000m_config));
1407	st->i2c_adap = i2c_adap;
1408	st->i2c_addr = i2c_addr;
1409
1410	demod                   = &st->demod;
1411	demod->demodulator_priv = st;
1412	memcpy(&st->demod.ops, &dib7000m_ops, sizeof(struct dvb_frontend_ops));
1413	mutex_init(&st->i2c_buffer_lock);
1414
1415	st->timf_default = cfg->bw->timf;
1416
1417	if (dib7000m_identify(st) != 0)
1418		goto error;
1419
1420	if (st->revision == 0x4000)
1421		dibx000_init_i2c_master(&st->i2c_master, DIB7000, st->i2c_adap, st->i2c_addr);
1422	else
1423		dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c_adap, st->i2c_addr);
1424
1425	dib7000m_demod_reset(st);
1426
1427	return demod;
1428
1429error:
1430	kfree(st);
1431	return NULL;
1432}
1433EXPORT_SYMBOL(dib7000m_attach);
1434
1435static struct dvb_frontend_ops dib7000m_ops = {
1436	.delsys = { SYS_DVBT },
1437	.info = {
1438		.name = "DiBcom 7000MA/MB/PA/PB/MC",
1439		.frequency_min      = 44250000,
1440		.frequency_max      = 867250000,
1441		.frequency_stepsize = 62500,
1442		.caps = FE_CAN_INVERSION_AUTO |
1443			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1444			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1445			FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1446			FE_CAN_TRANSMISSION_MODE_AUTO |
1447			FE_CAN_GUARD_INTERVAL_AUTO |
1448			FE_CAN_RECOVER |
1449			FE_CAN_HIERARCHY_AUTO,
1450	},
1451
1452	.release              = dib7000m_release,
1453
1454	.init                 = dib7000m_wakeup,
1455	.sleep                = dib7000m_sleep,
1456
1457	.set_frontend         = dib7000m_set_frontend,
1458	.get_tune_settings    = dib7000m_fe_get_tune_settings,
1459	.get_frontend         = dib7000m_get_frontend,
1460
1461	.read_status          = dib7000m_read_status,
1462	.read_ber             = dib7000m_read_ber,
1463	.read_signal_strength = dib7000m_read_signal_strength,
1464	.read_snr             = dib7000m_read_snr,
1465	.read_ucblocks        = dib7000m_read_unc_blocks,
1466};
1467
1468MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
1469MODULE_DESCRIPTION("Driver for the DiBcom 7000MA/MB/PA/PB/MC COFDM demodulator");
1470MODULE_LICENSE("GPL");
1471