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