xref: /linux/drivers/media/dvb-frontends/dib0090.c (revision 8c57a5e7b2820f349c95b8c8393fec1e0f4070d2)
1 /*
2  * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner.
3  *
4  * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  *
22  * This code is more or less generated from another driver, please
23  * excuse some codingstyle oddities.
24  *
25  */
26 
27 #include <linux/kernel.h>
28 #include <linux/slab.h>
29 #include <linux/i2c.h>
30 #include <linux/mutex.h>
31 
32 #include "dvb_frontend.h"
33 
34 #include "dib0090.h"
35 #include "dibx000_common.h"
36 
37 static int debug;
38 module_param(debug, int, 0644);
39 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
40 
41 #define dprintk(args...) do { \
42 	if (debug) { \
43 		printk(KERN_DEBUG "DiB0090: "); \
44 		printk(args); \
45 		printk("\n"); \
46 	} \
47 } while (0)
48 
49 #define CONFIG_SYS_DVBT
50 #define CONFIG_SYS_ISDBT
51 #define CONFIG_BAND_CBAND
52 #define CONFIG_BAND_VHF
53 #define CONFIG_BAND_UHF
54 #define CONFIG_DIB0090_USE_PWM_AGC
55 
56 #define EN_LNA0      0x8000
57 #define EN_LNA1      0x4000
58 #define EN_LNA2      0x2000
59 #define EN_LNA3      0x1000
60 #define EN_MIX0      0x0800
61 #define EN_MIX1      0x0400
62 #define EN_MIX2      0x0200
63 #define EN_MIX3      0x0100
64 #define EN_IQADC     0x0040
65 #define EN_PLL       0x0020
66 #define EN_TX        0x0010
67 #define EN_BB        0x0008
68 #define EN_LO        0x0004
69 #define EN_BIAS      0x0001
70 
71 #define EN_IQANA     0x0002
72 #define EN_DIGCLK    0x0080	/* not in the 0x24 reg, only in 0x1b */
73 #define EN_CRYSTAL   0x0002
74 
75 #define EN_UHF		 0x22E9
76 #define EN_VHF		 0x44E9
77 #define EN_LBD		 0x11E9
78 #define EN_SBD		 0x44E9
79 #define EN_CAB		 0x88E9
80 
81 /* Calibration defines */
82 #define      DC_CAL 0x1
83 #define     WBD_CAL 0x2
84 #define    TEMP_CAL 0x4
85 #define CAPTRIM_CAL 0x8
86 
87 #define KROSUS_PLL_LOCKED   0x800
88 #define KROSUS              0x2
89 
90 /* Use those defines to identify SOC version */
91 #define SOC               0x02
92 #define SOC_7090_P1G_11R1 0x82
93 #define SOC_7090_P1G_21R1 0x8a
94 #define SOC_8090_P1G_11R1 0x86
95 #define SOC_8090_P1G_21R1 0x8e
96 
97 /* else use thos ones to check */
98 #define P1A_B      0x0
99 #define P1C	   0x1
100 #define P1D_E_F    0x3
101 #define P1G	   0x7
102 #define P1G_21R2   0xf
103 
104 #define MP001 0x1		/* Single 9090/8096 */
105 #define MP005 0x4		/* Single Sband */
106 #define MP008 0x6		/* Dual diversity VHF-UHF-LBAND */
107 #define MP009 0x7		/* Dual diversity 29098 CBAND-UHF-LBAND-SBAND */
108 
109 #define pgm_read_word(w) (*w)
110 
111 struct dc_calibration;
112 
113 struct dib0090_tuning {
114 	u32 max_freq;		/* for every frequency less than or equal to that field: this information is correct */
115 	u8 switch_trim;
116 	u8 lna_tune;
117 	u16 lna_bias;
118 	u16 v2i;
119 	u16 mix;
120 	u16 load;
121 	u16 tuner_enable;
122 };
123 
124 struct dib0090_pll {
125 	u32 max_freq;		/* for every frequency less than or equal to that field: this information is correct */
126 	u8 vco_band;
127 	u8 hfdiv_code;
128 	u8 hfdiv;
129 	u8 topresc;
130 };
131 
132 struct dib0090_identity {
133 	u8 version;
134 	u8 product;
135 	u8 p1g;
136 	u8 in_soc;
137 };
138 
139 struct dib0090_state {
140 	struct i2c_adapter *i2c;
141 	struct dvb_frontend *fe;
142 	const struct dib0090_config *config;
143 
144 	u8 current_band;
145 	enum frontend_tune_state tune_state;
146 	u32 current_rf;
147 
148 	u16 wbd_offset;
149 	s16 wbd_target;		/* in dB */
150 
151 	s16 rf_gain_limit;	/* take-over-point: where to split between bb and rf gain */
152 	s16 current_gain;	/* keeps the currently programmed gain */
153 	u8 agc_step;		/* new binary search */
154 
155 	u16 gain[2];		/* for channel monitoring */
156 
157 	const u16 *rf_ramp;
158 	const u16 *bb_ramp;
159 
160 	/* for the software AGC ramps */
161 	u16 bb_1_def;
162 	u16 rf_lt_def;
163 	u16 gain_reg[4];
164 
165 	/* for the captrim/dc-offset search */
166 	s8 step;
167 	s16 adc_diff;
168 	s16 min_adc_diff;
169 
170 	s8 captrim;
171 	s8 fcaptrim;
172 
173 	const struct dc_calibration *dc;
174 	u16 bb6, bb7;
175 
176 	const struct dib0090_tuning *current_tune_table_index;
177 	const struct dib0090_pll *current_pll_table_index;
178 
179 	u8 tuner_is_tuned;
180 	u8 agc_freeze;
181 
182 	struct dib0090_identity identity;
183 
184 	u32 rf_request;
185 	u8 current_standard;
186 
187 	u8 calibrate;
188 	u32 rest;
189 	u16 bias;
190 	s16 temperature;
191 
192 	u8 wbd_calibration_gain;
193 	const struct dib0090_wbd_slope *current_wbd_table;
194 	u16 wbdmux;
195 
196 	/* for the I2C transfer */
197 	struct i2c_msg msg[2];
198 	u8 i2c_write_buffer[3];
199 	u8 i2c_read_buffer[2];
200 	struct mutex i2c_buffer_lock;
201 };
202 
203 struct dib0090_fw_state {
204 	struct i2c_adapter *i2c;
205 	struct dvb_frontend *fe;
206 	struct dib0090_identity identity;
207 	const struct dib0090_config *config;
208 
209 	/* for the I2C transfer */
210 	struct i2c_msg msg;
211 	u8 i2c_write_buffer[2];
212 	u8 i2c_read_buffer[2];
213 	struct mutex i2c_buffer_lock;
214 };
215 
216 static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
217 {
218 	u16 ret;
219 
220 	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
221 		dprintk("could not acquire lock");
222 		return 0;
223 	}
224 
225 	state->i2c_write_buffer[0] = reg;
226 
227 	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
228 	state->msg[0].addr = state->config->i2c_address;
229 	state->msg[0].flags = 0;
230 	state->msg[0].buf = state->i2c_write_buffer;
231 	state->msg[0].len = 1;
232 	state->msg[1].addr = state->config->i2c_address;
233 	state->msg[1].flags = I2C_M_RD;
234 	state->msg[1].buf = state->i2c_read_buffer;
235 	state->msg[1].len = 2;
236 
237 	if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
238 		printk(KERN_WARNING "DiB0090 I2C read failed\n");
239 		ret = 0;
240 	} else
241 		ret = (state->i2c_read_buffer[0] << 8)
242 			| state->i2c_read_buffer[1];
243 
244 	mutex_unlock(&state->i2c_buffer_lock);
245 	return ret;
246 }
247 
248 static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
249 {
250 	int ret;
251 
252 	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
253 		dprintk("could not acquire lock");
254 		return -EINVAL;
255 	}
256 
257 	state->i2c_write_buffer[0] = reg & 0xff;
258 	state->i2c_write_buffer[1] = val >> 8;
259 	state->i2c_write_buffer[2] = val & 0xff;
260 
261 	memset(state->msg, 0, sizeof(struct i2c_msg));
262 	state->msg[0].addr = state->config->i2c_address;
263 	state->msg[0].flags = 0;
264 	state->msg[0].buf = state->i2c_write_buffer;
265 	state->msg[0].len = 3;
266 
267 	if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
268 		printk(KERN_WARNING "DiB0090 I2C write failed\n");
269 		ret = -EREMOTEIO;
270 	} else
271 		ret = 0;
272 
273 	mutex_unlock(&state->i2c_buffer_lock);
274 	return ret;
275 }
276 
277 static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg)
278 {
279 	u16 ret;
280 
281 	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
282 		dprintk("could not acquire lock");
283 		return 0;
284 	}
285 
286 	state->i2c_write_buffer[0] = reg;
287 
288 	memset(&state->msg, 0, sizeof(struct i2c_msg));
289 	state->msg.addr = reg;
290 	state->msg.flags = I2C_M_RD;
291 	state->msg.buf = state->i2c_read_buffer;
292 	state->msg.len = 2;
293 	if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
294 		printk(KERN_WARNING "DiB0090 I2C read failed\n");
295 		ret = 0;
296 	} else
297 		ret = (state->i2c_read_buffer[0] << 8)
298 			| state->i2c_read_buffer[1];
299 
300 	mutex_unlock(&state->i2c_buffer_lock);
301 	return ret;
302 }
303 
304 static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val)
305 {
306 	int ret;
307 
308 	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
309 		dprintk("could not acquire lock");
310 		return -EINVAL;
311 	}
312 
313 	state->i2c_write_buffer[0] = val >> 8;
314 	state->i2c_write_buffer[1] = val & 0xff;
315 
316 	memset(&state->msg, 0, sizeof(struct i2c_msg));
317 	state->msg.addr = reg;
318 	state->msg.flags = 0;
319 	state->msg.buf = state->i2c_write_buffer;
320 	state->msg.len = 2;
321 	if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
322 		printk(KERN_WARNING "DiB0090 I2C write failed\n");
323 		ret = -EREMOTEIO;
324 	} else
325 		ret = 0;
326 
327 	mutex_unlock(&state->i2c_buffer_lock);
328 	return ret;
329 }
330 
331 #define HARD_RESET(state) do {  if (cfg->reset) {  if (cfg->sleep) cfg->sleep(fe, 0); msleep(10);  cfg->reset(fe, 1); msleep(10);  cfg->reset(fe, 0); msleep(10);  }  } while (0)
332 #define ADC_TARGET -220
333 #define GAIN_ALPHA 5
334 #define WBD_ALPHA 6
335 #define LPF	100
336 static void dib0090_write_regs(struct dib0090_state *state, u8 r, const u16 * b, u8 c)
337 {
338 	do {
339 		dib0090_write_reg(state, r++, *b++);
340 	} while (--c);
341 }
342 
343 static int dib0090_identify(struct dvb_frontend *fe)
344 {
345 	struct dib0090_state *state = fe->tuner_priv;
346 	u16 v;
347 	struct dib0090_identity *identity = &state->identity;
348 
349 	v = dib0090_read_reg(state, 0x1a);
350 
351 	identity->p1g = 0;
352 	identity->in_soc = 0;
353 
354 	dprintk("Tuner identification (Version = 0x%04x)", v);
355 
356 	/* without PLL lock info */
357 	v &= ~KROSUS_PLL_LOCKED;
358 
359 	identity->version = v & 0xff;
360 	identity->product = (v >> 8) & 0xf;
361 
362 	if (identity->product != KROSUS)
363 		goto identification_error;
364 
365 	if ((identity->version & 0x3) == SOC) {
366 		identity->in_soc = 1;
367 		switch (identity->version) {
368 		case SOC_8090_P1G_11R1:
369 			dprintk("SOC 8090 P1-G11R1 Has been detected");
370 			identity->p1g = 1;
371 			break;
372 		case SOC_8090_P1G_21R1:
373 			dprintk("SOC 8090 P1-G21R1 Has been detected");
374 			identity->p1g = 1;
375 			break;
376 		case SOC_7090_P1G_11R1:
377 			dprintk("SOC 7090 P1-G11R1 Has been detected");
378 			identity->p1g = 1;
379 			break;
380 		case SOC_7090_P1G_21R1:
381 			dprintk("SOC 7090 P1-G21R1 Has been detected");
382 			identity->p1g = 1;
383 			break;
384 		default:
385 			goto identification_error;
386 		}
387 	} else {
388 		switch ((identity->version >> 5) & 0x7) {
389 		case MP001:
390 			dprintk("MP001 : 9090/8096");
391 			break;
392 		case MP005:
393 			dprintk("MP005 : Single Sband");
394 			break;
395 		case MP008:
396 			dprintk("MP008 : diversity VHF-UHF-LBAND");
397 			break;
398 		case MP009:
399 			dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND");
400 			break;
401 		default:
402 			goto identification_error;
403 		}
404 
405 		switch (identity->version & 0x1f) {
406 		case P1G_21R2:
407 			dprintk("P1G_21R2 detected");
408 			identity->p1g = 1;
409 			break;
410 		case P1G:
411 			dprintk("P1G detected");
412 			identity->p1g = 1;
413 			break;
414 		case P1D_E_F:
415 			dprintk("P1D/E/F detected");
416 			break;
417 		case P1C:
418 			dprintk("P1C detected");
419 			break;
420 		case P1A_B:
421 			dprintk("P1-A/B detected: driver is deactivated - not available");
422 			goto identification_error;
423 			break;
424 		default:
425 			goto identification_error;
426 		}
427 	}
428 
429 	return 0;
430 
431 identification_error:
432 	return -EIO;
433 }
434 
435 static int dib0090_fw_identify(struct dvb_frontend *fe)
436 {
437 	struct dib0090_fw_state *state = fe->tuner_priv;
438 	struct dib0090_identity *identity = &state->identity;
439 
440 	u16 v = dib0090_fw_read_reg(state, 0x1a);
441 	identity->p1g = 0;
442 	identity->in_soc = 0;
443 
444 	dprintk("FE: Tuner identification (Version = 0x%04x)", v);
445 
446 	/* without PLL lock info */
447 	v &= ~KROSUS_PLL_LOCKED;
448 
449 	identity->version = v & 0xff;
450 	identity->product = (v >> 8) & 0xf;
451 
452 	if (identity->product != KROSUS)
453 		goto identification_error;
454 
455 	if ((identity->version & 0x3) == SOC) {
456 		identity->in_soc = 1;
457 		switch (identity->version) {
458 		case SOC_8090_P1G_11R1:
459 			dprintk("SOC 8090 P1-G11R1 Has been detected");
460 			identity->p1g = 1;
461 			break;
462 		case SOC_8090_P1G_21R1:
463 			dprintk("SOC 8090 P1-G21R1 Has been detected");
464 			identity->p1g = 1;
465 			break;
466 		case SOC_7090_P1G_11R1:
467 			dprintk("SOC 7090 P1-G11R1 Has been detected");
468 			identity->p1g = 1;
469 			break;
470 		case SOC_7090_P1G_21R1:
471 			dprintk("SOC 7090 P1-G21R1 Has been detected");
472 			identity->p1g = 1;
473 			break;
474 		default:
475 			goto identification_error;
476 		}
477 	} else {
478 		switch ((identity->version >> 5) & 0x7) {
479 		case MP001:
480 			dprintk("MP001 : 9090/8096");
481 			break;
482 		case MP005:
483 			dprintk("MP005 : Single Sband");
484 			break;
485 		case MP008:
486 			dprintk("MP008 : diversity VHF-UHF-LBAND");
487 			break;
488 		case MP009:
489 			dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND");
490 			break;
491 		default:
492 			goto identification_error;
493 		}
494 
495 		switch (identity->version & 0x1f) {
496 		case P1G_21R2:
497 			dprintk("P1G_21R2 detected");
498 			identity->p1g = 1;
499 			break;
500 		case P1G:
501 			dprintk("P1G detected");
502 			identity->p1g = 1;
503 			break;
504 		case P1D_E_F:
505 			dprintk("P1D/E/F detected");
506 			break;
507 		case P1C:
508 			dprintk("P1C detected");
509 			break;
510 		case P1A_B:
511 			dprintk("P1-A/B detected: driver is deactivated - not available");
512 			goto identification_error;
513 			break;
514 		default:
515 			goto identification_error;
516 		}
517 	}
518 
519 	return 0;
520 
521 identification_error:
522 	return -EIO;
523 }
524 
525 static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
526 {
527 	struct dib0090_state *state = fe->tuner_priv;
528 	u16 PllCfg, i, v;
529 
530 	HARD_RESET(state);
531 	dib0090_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
532 	if (cfg->in_soc)
533 		return;
534 
535 	dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL);	/* PLL, DIG_CLK and CRYSTAL remain */
536 	/* adcClkOutRatio=8->7, release reset */
537 	dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0);
538 	if (cfg->clkoutdrive != 0)
539 		dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
540 				| (cfg->clkoutdrive << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
541 	else
542 		dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
543 				| (7 << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
544 
545 	/* Read Pll current config * */
546 	PllCfg = dib0090_read_reg(state, 0x21);
547 
548 	/** Reconfigure PLL if current setting is different from default setting **/
549 	if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && (!cfg->in_soc)
550 			&& !cfg->io.pll_bypass) {
551 
552 		/* Set Bypass mode */
553 		PllCfg |= (1 << 15);
554 		dib0090_write_reg(state, 0x21, PllCfg);
555 
556 		/* Set Reset Pll */
557 		PllCfg &= ~(1 << 13);
558 		dib0090_write_reg(state, 0x21, PllCfg);
559 
560 	/*** Set new Pll configuration in bypass and reset state ***/
561 		PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
562 		dib0090_write_reg(state, 0x21, PllCfg);
563 
564 		/* Remove Reset Pll */
565 		PllCfg |= (1 << 13);
566 		dib0090_write_reg(state, 0x21, PllCfg);
567 
568 	/*** Wait for PLL lock ***/
569 		i = 100;
570 		do {
571 			v = !!(dib0090_read_reg(state, 0x1a) & 0x800);
572 			if (v)
573 				break;
574 		} while (--i);
575 
576 		if (i == 0) {
577 			dprintk("Pll: Unable to lock Pll");
578 			return;
579 		}
580 
581 		/* Finally Remove Bypass mode */
582 		PllCfg &= ~(1 << 15);
583 		dib0090_write_reg(state, 0x21, PllCfg);
584 	}
585 
586 	if (cfg->io.pll_bypass) {
587 		PllCfg |= (cfg->io.pll_bypass << 15);
588 		dib0090_write_reg(state, 0x21, PllCfg);
589 	}
590 }
591 
592 static int dib0090_fw_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
593 {
594 	struct dib0090_fw_state *state = fe->tuner_priv;
595 	u16 PllCfg;
596 	u16 v;
597 	int i;
598 
599 	dprintk("fw reset digital");
600 	HARD_RESET(state);
601 
602 	dib0090_fw_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
603 	dib0090_fw_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL);	/* PLL, DIG_CLK and CRYSTAL remain */
604 
605 	dib0090_fw_write_reg(state, 0x20,
606 			((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (cfg->data_tx_drv << 4) | cfg->ls_cfg_pad_drv);
607 
608 	v = (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 9) | (0 << 8) | (cfg->clkouttobamse << 4) | (0 << 2) | (0);
609 	if (cfg->clkoutdrive != 0)
610 		v |= cfg->clkoutdrive << 5;
611 	else
612 		v |= 7 << 5;
613 
614 	v |= 2 << 10;
615 	dib0090_fw_write_reg(state, 0x23, v);
616 
617 	/* Read Pll current config * */
618 	PllCfg = dib0090_fw_read_reg(state, 0x21);
619 
620 	/** Reconfigure PLL if current setting is different from default setting **/
621 	if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && !cfg->io.pll_bypass) {
622 
623 		/* Set Bypass mode */
624 		PllCfg |= (1 << 15);
625 		dib0090_fw_write_reg(state, 0x21, PllCfg);
626 
627 		/* Set Reset Pll */
628 		PllCfg &= ~(1 << 13);
629 		dib0090_fw_write_reg(state, 0x21, PllCfg);
630 
631 	/*** Set new Pll configuration in bypass and reset state ***/
632 		PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
633 		dib0090_fw_write_reg(state, 0x21, PllCfg);
634 
635 		/* Remove Reset Pll */
636 		PllCfg |= (1 << 13);
637 		dib0090_fw_write_reg(state, 0x21, PllCfg);
638 
639 	/*** Wait for PLL lock ***/
640 		i = 100;
641 		do {
642 			v = !!(dib0090_fw_read_reg(state, 0x1a) & 0x800);
643 			if (v)
644 				break;
645 		} while (--i);
646 
647 		if (i == 0) {
648 			dprintk("Pll: Unable to lock Pll");
649 			return -EIO;
650 		}
651 
652 		/* Finally Remove Bypass mode */
653 		PllCfg &= ~(1 << 15);
654 		dib0090_fw_write_reg(state, 0x21, PllCfg);
655 	}
656 
657 	if (cfg->io.pll_bypass) {
658 		PllCfg |= (cfg->io.pll_bypass << 15);
659 		dib0090_fw_write_reg(state, 0x21, PllCfg);
660 	}
661 
662 	return dib0090_fw_identify(fe);
663 }
664 
665 static int dib0090_wakeup(struct dvb_frontend *fe)
666 {
667 	struct dib0090_state *state = fe->tuner_priv;
668 	if (state->config->sleep)
669 		state->config->sleep(fe, 0);
670 
671 	/* enable dataTX in case we have been restarted in the wrong moment */
672 	dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
673 	return 0;
674 }
675 
676 static int dib0090_sleep(struct dvb_frontend *fe)
677 {
678 	struct dib0090_state *state = fe->tuner_priv;
679 	if (state->config->sleep)
680 		state->config->sleep(fe, 1);
681 	return 0;
682 }
683 
684 void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
685 {
686 	struct dib0090_state *state = fe->tuner_priv;
687 	if (fast)
688 		dib0090_write_reg(state, 0x04, 0);
689 	else
690 		dib0090_write_reg(state, 0x04, 1);
691 }
692 
693 EXPORT_SYMBOL(dib0090_dcc_freq);
694 
695 static const u16 bb_ramp_pwm_normal_socs[] = {
696 	550, /* max BB gain in 10th of dB */
697 	(1<<9) | 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
698 	440,
699 	(4  << 9) | 0, /* BB_RAMP3 = 26dB */
700 	(0  << 9) | 208, /* BB_RAMP4 */
701 	(4  << 9) | 208, /* BB_RAMP5 = 29dB */
702 	(0  << 9) | 440, /* BB_RAMP6 */
703 };
704 
705 static const u16 rf_ramp_pwm_cband_7090p[] = {
706 	280, /* max RF gain in 10th of dB */
707 	18, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
708 	504, /* ramp_max = maximum X used on the ramp */
709 	(29 << 10) | 364, /* RF_RAMP5, LNA 1 = 8dB */
710 	(0  << 10) | 504, /* RF_RAMP6, LNA 1 */
711 	(60 << 10) | 228, /* RF_RAMP7, LNA 2 = 7.7dB */
712 	(0  << 10) | 364, /* RF_RAMP8, LNA 2 */
713 	(34 << 10) | 109, /* GAIN_4_1, LNA 3 = 6.8dB */
714 	(0  << 10) | 228, /* GAIN_4_2, LNA 3 */
715 	(37 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */
716 	(0  << 10) | 109, /* RF_RAMP4, LNA 4 */
717 };
718 
719 static const u16 rf_ramp_pwm_cband_7090e_sensitivity[] = {
720 	186, /* max RF gain in 10th of dB */
721 	40, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
722 	746, /* ramp_max = maximum X used on the ramp */
723 	(10 << 10) | 345, /* RF_RAMP5, LNA 1 = 10dB */
724 	(0  << 10) | 746, /* RF_RAMP6, LNA 1 */
725 	(0 << 10) | 0, /* RF_RAMP7, LNA 2 = 0 dB */
726 	(0  << 10) | 0, /* RF_RAMP8, LNA 2 */
727 	(28 << 10) | 200, /* GAIN_4_1, LNA 3 = 6.8dB */ /* 3.61 dB */
728 	(0  << 10) | 345, /* GAIN_4_2, LNA 3 */
729 	(20 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */ /* 4.96 dB */
730 	(0  << 10) | 200, /* RF_RAMP4, LNA 4 */
731 };
732 
733 static const u16 rf_ramp_pwm_cband_7090e_aci[] = {
734 	86, /* max RF gain in 10th of dB */
735 	40, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
736 	345, /* ramp_max = maximum X used on the ramp */
737 	(0 << 10) | 0, /* RF_RAMP5, LNA 1 = 8dB */ /* 7.47 dB */
738 	(0 << 10) | 0, /* RF_RAMP6, LNA 1 */
739 	(0 << 10) | 0, /* RF_RAMP7, LNA 2 = 0 dB */
740 	(0 << 10) | 0, /* RF_RAMP8, LNA 2 */
741 	(28 << 10) | 200, /* GAIN_4_1, LNA 3 = 6.8dB */ /* 3.61 dB */
742 	(0  << 10) | 345, /* GAIN_4_2, LNA 3 */
743 	(20 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */ /* 4.96 dB */
744 	(0  << 10) | 200, /* RF_RAMP4, LNA 4 */
745 };
746 
747 static const u16 rf_ramp_pwm_cband_8090[] = {
748 	345, /* max RF gain in 10th of dB */
749 	29, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
750 	1000, /* ramp_max = maximum X used on the ramp */
751 	(35 << 10) | 772, /* RF_RAMP3, LNA 1 = 8dB */
752 	(0  << 10) | 1000, /* RF_RAMP4, LNA 1 */
753 	(58 << 10) | 496, /* RF_RAMP5, LNA 2 = 9.5dB */
754 	(0  << 10) | 772, /* RF_RAMP6, LNA 2 */
755 	(27 << 10) | 200, /* RF_RAMP7, LNA 3 = 10.5dB */
756 	(0  << 10) | 496, /* RF_RAMP8, LNA 3 */
757 	(40 << 10) | 0, /* GAIN_4_1, LNA 4 = 7dB */
758 	(0  << 10) | 200, /* GAIN_4_2, LNA 4 */
759 };
760 
761 static const u16 rf_ramp_pwm_uhf_7090[] = {
762 	407, /* max RF gain in 10th of dB */
763 	13, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
764 	529, /* ramp_max = maximum X used on the ramp */
765 	(23 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
766 	(0  << 10) | 176, /* RF_RAMP4, LNA 1 */
767 	(63 << 10) | 400, /* RF_RAMP5, LNA 2 = 8dB */
768 	(0  << 10) | 529, /* RF_RAMP6, LNA 2 */
769 	(48 << 10) | 316, /* RF_RAMP7, LNA 3 = 6.8dB */
770 	(0  << 10) | 400, /* RF_RAMP8, LNA 3 */
771 	(29 << 10) | 176, /* GAIN_4_1, LNA 4 = 11.5dB */
772 	(0  << 10) | 316, /* GAIN_4_2, LNA 4 */
773 };
774 
775 static const u16 rf_ramp_pwm_uhf_8090[] = {
776 	388, /* max RF gain in 10th of dB */
777 	26, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
778 	1008, /* ramp_max = maximum X used on the ramp */
779 	(11 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
780 	(0  << 10) | 369, /* RF_RAMP4, LNA 1 */
781 	(41 << 10) | 809, /* RF_RAMP5, LNA 2 = 8dB */
782 	(0  << 10) | 1008, /* RF_RAMP6, LNA 2 */
783 	(27 << 10) | 659, /* RF_RAMP7, LNA 3 = 6dB */
784 	(0  << 10) | 809, /* RF_RAMP8, LNA 3 */
785 	(14 << 10) | 369, /* GAIN_4_1, LNA 4 = 11.5dB */
786 	(0  << 10) | 659, /* GAIN_4_2, LNA 4 */
787 };
788 
789 /* GENERAL PWM ramp definition for all other Krosus */
790 static const u16 bb_ramp_pwm_normal[] = {
791 	500, /* max BB gain in 10th of dB */
792 	8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
793 	400,
794 	(2  << 9) | 0, /* BB_RAMP3 = 21dB */
795 	(0  << 9) | 168, /* BB_RAMP4 */
796 	(2  << 9) | 168, /* BB_RAMP5 = 29dB */
797 	(0  << 9) | 400, /* BB_RAMP6 */
798 };
799 
800 static const u16 bb_ramp_pwm_boost[] = {
801 	550, /* max BB gain in 10th of dB */
802 	8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
803 	440,
804 	(2  << 9) | 0, /* BB_RAMP3 = 26dB */
805 	(0  << 9) | 208, /* BB_RAMP4 */
806 	(2  << 9) | 208, /* BB_RAMP5 = 29dB */
807 	(0  << 9) | 440, /* BB_RAMP6 */
808 };
809 
810 static const u16 rf_ramp_pwm_cband[] = {
811 	314, /* max RF gain in 10th of dB */
812 	33, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
813 	1023, /* ramp_max = maximum X used on the ramp */
814 	(8  << 10) | 743, /* RF_RAMP3, LNA 1 = 0dB */
815 	(0  << 10) | 1023, /* RF_RAMP4, LNA 1 */
816 	(15 << 10) | 469, /* RF_RAMP5, LNA 2 = 0dB */
817 	(0  << 10) | 742, /* RF_RAMP6, LNA 2 */
818 	(9  << 10) | 234, /* RF_RAMP7, LNA 3 = 0dB */
819 	(0  << 10) | 468, /* RF_RAMP8, LNA 3 */
820 	(9  << 10) | 0, /* GAIN_4_1, LNA 4 = 0dB */
821 	(0  << 10) | 233, /* GAIN_4_2, LNA 4 */
822 };
823 
824 static const u16 rf_ramp_pwm_vhf[] = {
825 	398, /* max RF gain in 10th of dB */
826 	24, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
827 	954, /* ramp_max = maximum X used on the ramp */
828 	(7  << 10) | 0, /* RF_RAMP3, LNA 1 = 13.2dB */
829 	(0  << 10) | 290, /* RF_RAMP4, LNA 1 */
830 	(16 << 10) | 699, /* RF_RAMP5, LNA 2 = 10.5dB */
831 	(0  << 10) | 954, /* RF_RAMP6, LNA 2 */
832 	(17 << 10) | 580, /* RF_RAMP7, LNA 3 = 5dB */
833 	(0  << 10) | 699, /* RF_RAMP8, LNA 3 */
834 	(7  << 10) | 290, /* GAIN_4_1, LNA 4 = 12.5dB */
835 	(0  << 10) | 580, /* GAIN_4_2, LNA 4 */
836 };
837 
838 static const u16 rf_ramp_pwm_uhf[] = {
839 	398, /* max RF gain in 10th of dB */
840 	24, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
841 	954, /* ramp_max = maximum X used on the ramp */
842 	(7  << 10) | 0, /* RF_RAMP3, LNA 1 = 13.2dB */
843 	(0  << 10) | 290, /* RF_RAMP4, LNA 1 */
844 	(16 << 10) | 699, /* RF_RAMP5, LNA 2 = 10.5dB */
845 	(0  << 10) | 954, /* RF_RAMP6, LNA 2 */
846 	(17 << 10) | 580, /* RF_RAMP7, LNA 3 = 5dB */
847 	(0  << 10) | 699, /* RF_RAMP8, LNA 3 */
848 	(7  << 10) | 290, /* GAIN_4_1, LNA 4 = 12.5dB */
849 	(0  << 10) | 580, /* GAIN_4_2, LNA 4 */
850 };
851 
852 static const u16 rf_ramp_pwm_sband[] = {
853 	253, /* max RF gain in 10th of dB */
854 	38, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
855 	961,
856 	(4  << 10) | 0, /* RF_RAMP3, LNA 1 = 14.1dB */
857 	(0  << 10) | 508, /* RF_RAMP4, LNA 1 */
858 	(9  << 10) | 508, /* RF_RAMP5, LNA 2 = 11.2dB */
859 	(0  << 10) | 961, /* RF_RAMP6, LNA 2 */
860 	(0  << 10) | 0, /* RF_RAMP7, LNA 3 = 0dB */
861 	(0  << 10) | 0, /* RF_RAMP8, LNA 3 */
862 	(0  << 10) | 0, /* GAIN_4_1, LNA 4 = 0dB */
863 	(0  << 10) | 0, /* GAIN_4_2, LNA 4 */
864 };
865 
866 struct slope {
867 	s16 range;
868 	s16 slope;
869 };
870 static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val)
871 {
872 	u8 i;
873 	u16 rest;
874 	u16 ret = 0;
875 	for (i = 0; i < num; i++) {
876 		if (val > slopes[i].range)
877 			rest = slopes[i].range;
878 		else
879 			rest = val;
880 		ret += (rest * slopes[i].slope) / slopes[i].range;
881 		val -= rest;
882 	}
883 	return ret;
884 }
885 
886 static const struct slope dib0090_wbd_slopes[3] = {
887 	{66, 120},		/* -64,-52: offset -   65 */
888 	{600, 170},		/* -52,-35: 65     -  665 */
889 	{170, 250},		/* -45,-10: 665    - 835 */
890 };
891 
892 static s16 dib0090_wbd_to_db(struct dib0090_state *state, u16 wbd)
893 {
894 	wbd &= 0x3ff;
895 	if (wbd < state->wbd_offset)
896 		wbd = 0;
897 	else
898 		wbd -= state->wbd_offset;
899 	/* -64dB is the floor */
900 	return -640 + (s16) slopes_to_scale(dib0090_wbd_slopes, ARRAY_SIZE(dib0090_wbd_slopes), wbd);
901 }
902 
903 static void dib0090_wbd_target(struct dib0090_state *state, u32 rf)
904 {
905 	u16 offset = 250;
906 
907 	/* TODO : DAB digital N+/-1 interferer perfs : offset = 10 */
908 
909 	if (state->current_band == BAND_VHF)
910 		offset = 650;
911 #ifndef FIRMWARE_FIREFLY
912 	if (state->current_band == BAND_VHF)
913 		offset = state->config->wbd_vhf_offset;
914 	if (state->current_band == BAND_CBAND)
915 		offset = state->config->wbd_cband_offset;
916 #endif
917 
918 	state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + offset);
919 	dprintk("wbd-target: %d dB", (u32) state->wbd_target);
920 }
921 
922 static const int gain_reg_addr[4] = {
923 	0x08, 0x0a, 0x0f, 0x01
924 };
925 
926 static void dib0090_gain_apply(struct dib0090_state *state, s16 gain_delta, s16 top_delta, u8 force)
927 {
928 	u16 rf, bb, ref;
929 	u16 i, v, gain_reg[4] = { 0 }, gain;
930 	const u16 *g;
931 
932 	if (top_delta < -511)
933 		top_delta = -511;
934 	if (top_delta > 511)
935 		top_delta = 511;
936 
937 	if (force) {
938 		top_delta *= (1 << WBD_ALPHA);
939 		gain_delta *= (1 << GAIN_ALPHA);
940 	}
941 
942 	if (top_delta >= ((s16) (state->rf_ramp[0] << WBD_ALPHA) - state->rf_gain_limit))	/* overflow */
943 		state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
944 	else
945 		state->rf_gain_limit += top_delta;
946 
947 	if (state->rf_gain_limit < 0)	/*underflow */
948 		state->rf_gain_limit = 0;
949 
950 	/* use gain as a temporary variable and correct current_gain */
951 	gain = ((state->rf_gain_limit >> WBD_ALPHA) + state->bb_ramp[0]) << GAIN_ALPHA;
952 	if (gain_delta >= ((s16) gain - state->current_gain))	/* overflow */
953 		state->current_gain = gain;
954 	else
955 		state->current_gain += gain_delta;
956 	/* cannot be less than 0 (only if gain_delta is less than 0 we can have current_gain < 0) */
957 	if (state->current_gain < 0)
958 		state->current_gain = 0;
959 
960 	/* now split total gain to rf and bb gain */
961 	gain = state->current_gain >> GAIN_ALPHA;
962 
963 	/* requested gain is bigger than rf gain limit - ACI/WBD adjustment */
964 	if (gain > (state->rf_gain_limit >> WBD_ALPHA)) {
965 		rf = state->rf_gain_limit >> WBD_ALPHA;
966 		bb = gain - rf;
967 		if (bb > state->bb_ramp[0])
968 			bb = state->bb_ramp[0];
969 	} else {		/* high signal level -> all gains put on RF */
970 		rf = gain;
971 		bb = 0;
972 	}
973 
974 	state->gain[0] = rf;
975 	state->gain[1] = bb;
976 
977 	/* software ramp */
978 	/* Start with RF gains */
979 	g = state->rf_ramp + 1;	/* point on RF LNA1 max gain */
980 	ref = rf;
981 	for (i = 0; i < 7; i++) {	/* Go over all amplifiers => 5RF amps + 2 BB amps = 7 amps */
982 		if (g[0] == 0 || ref < (g[1] - g[0]))	/* if total gain of the current amp is null or this amp is not concerned because it starts to work from an higher gain value */
983 			v = 0;	/* force the gain to write for the current amp to be null */
984 		else if (ref >= g[1])	/* Gain to set is higher than the high working point of this amp */
985 			v = g[2];	/* force this amp to be full gain */
986 		else		/* compute the value to set to this amp because we are somewhere in his range */
987 			v = ((ref - (g[1] - g[0])) * g[2]) / g[0];
988 
989 		if (i == 0)	/* LNA 1 reg mapping */
990 			gain_reg[0] = v;
991 		else if (i == 1)	/* LNA 2 reg mapping */
992 			gain_reg[0] |= v << 7;
993 		else if (i == 2)	/* LNA 3 reg mapping */
994 			gain_reg[1] = v;
995 		else if (i == 3)	/* LNA 4 reg mapping */
996 			gain_reg[1] |= v << 7;
997 		else if (i == 4)	/* CBAND LNA reg mapping */
998 			gain_reg[2] = v | state->rf_lt_def;
999 		else if (i == 5)	/* BB gain 1 reg mapping */
1000 			gain_reg[3] = v << 3;
1001 		else if (i == 6)	/* BB gain 2 reg mapping */
1002 			gain_reg[3] |= v << 8;
1003 
1004 		g += 3;		/* go to next gain bloc */
1005 
1006 		/* When RF is finished, start with BB */
1007 		if (i == 4) {
1008 			g = state->bb_ramp + 1;	/* point on BB gain 1 max gain */
1009 			ref = bb;
1010 		}
1011 	}
1012 	gain_reg[3] |= state->bb_1_def;
1013 	gain_reg[3] |= ((bb % 10) * 100) / 125;
1014 
1015 #ifdef DEBUG_AGC
1016 	dprintk("GA CALC: DB: %3d(rf) + %3d(bb) = %3d gain_reg[0]=%04x gain_reg[1]=%04x gain_reg[2]=%04x gain_reg[0]=%04x", rf, bb, rf + bb,
1017 		gain_reg[0], gain_reg[1], gain_reg[2], gain_reg[3]);
1018 #endif
1019 
1020 	/* Write the amplifier regs */
1021 	for (i = 0; i < 4; i++) {
1022 		v = gain_reg[i];
1023 		if (force || state->gain_reg[i] != v) {
1024 			state->gain_reg[i] = v;
1025 			dib0090_write_reg(state, gain_reg_addr[i], v);
1026 		}
1027 	}
1028 }
1029 
1030 static void dib0090_set_boost(struct dib0090_state *state, int onoff)
1031 {
1032 	state->bb_1_def &= 0xdfff;
1033 	state->bb_1_def |= onoff << 13;
1034 }
1035 
1036 static void dib0090_set_rframp(struct dib0090_state *state, const u16 * cfg)
1037 {
1038 	state->rf_ramp = cfg;
1039 }
1040 
1041 static void dib0090_set_rframp_pwm(struct dib0090_state *state, const u16 * cfg)
1042 {
1043 	state->rf_ramp = cfg;
1044 
1045 	dib0090_write_reg(state, 0x2a, 0xffff);
1046 
1047 	dprintk("total RF gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x2a));
1048 
1049 	dib0090_write_regs(state, 0x2c, cfg + 3, 6);
1050 	dib0090_write_regs(state, 0x3e, cfg + 9, 2);
1051 }
1052 
1053 static void dib0090_set_bbramp(struct dib0090_state *state, const u16 * cfg)
1054 {
1055 	state->bb_ramp = cfg;
1056 	dib0090_set_boost(state, cfg[0] > 500);	/* we want the boost if the gain is higher that 50dB */
1057 }
1058 
1059 static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg)
1060 {
1061 	state->bb_ramp = cfg;
1062 
1063 	dib0090_set_boost(state, cfg[0] > 500);	/* we want the boost if the gain is higher that 50dB */
1064 
1065 	dib0090_write_reg(state, 0x33, 0xffff);
1066 	dprintk("total BB gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x33));
1067 	dib0090_write_regs(state, 0x35, cfg + 3, 4);
1068 }
1069 
1070 void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
1071 {
1072 	struct dib0090_state *state = fe->tuner_priv;
1073 	u16 *bb_ramp = (u16 *)&bb_ramp_pwm_normal; /* default baseband config */
1074 	u16 *rf_ramp = NULL;
1075 	u8 en_pwm_rf_mux = 1;
1076 
1077 	/* reset the AGC */
1078 	if (state->config->use_pwm_agc) {
1079 		if (state->current_band == BAND_CBAND) {
1080 			if (state->identity.in_soc) {
1081 				bb_ramp = (u16 *)&bb_ramp_pwm_normal_socs;
1082 				if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1083 					rf_ramp = (u16 *)&rf_ramp_pwm_cband_8090;
1084 				else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1) {
1085 					if (state->config->is_dib7090e) {
1086 						if (state->rf_ramp == NULL)
1087 							rf_ramp = (u16 *)&rf_ramp_pwm_cband_7090e_sensitivity;
1088 						else
1089 							rf_ramp = (u16 *)state->rf_ramp;
1090 					} else
1091 						rf_ramp = (u16 *)&rf_ramp_pwm_cband_7090p;
1092 				}
1093 			} else
1094 				rf_ramp = (u16 *)&rf_ramp_pwm_cband;
1095 		} else
1096 
1097 			if (state->current_band == BAND_VHF) {
1098 				if (state->identity.in_soc) {
1099 					bb_ramp = (u16 *)&bb_ramp_pwm_normal_socs;
1100 					/* rf_ramp = &rf_ramp_pwm_vhf_socs; */ /* TODO */
1101 				} else
1102 					rf_ramp = (u16 *)&rf_ramp_pwm_vhf;
1103 			} else if (state->current_band == BAND_UHF) {
1104 				if (state->identity.in_soc) {
1105 					bb_ramp = (u16 *)&bb_ramp_pwm_normal_socs;
1106 					if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1107 						rf_ramp = (u16 *)&rf_ramp_pwm_uhf_8090;
1108 					else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
1109 						rf_ramp = (u16 *)&rf_ramp_pwm_uhf_7090;
1110 				} else
1111 					rf_ramp = (u16 *)&rf_ramp_pwm_uhf;
1112 			}
1113 		if (rf_ramp)
1114 			dib0090_set_rframp_pwm(state, rf_ramp);
1115 		dib0090_set_bbramp_pwm(state, bb_ramp);
1116 
1117 		/* activate the ramp generator using PWM control */
1118 		if (state->rf_ramp)
1119 			dprintk("ramp RF gain = %d BAND = %s version = %d",
1120 				state->rf_ramp[0],
1121 				(state->current_band == BAND_CBAND) ? "CBAND" : "NOT CBAND",
1122 				state->identity.version & 0x1f);
1123 
1124 		if (rf_ramp && ((state->rf_ramp[0] == 0) ||
1125 		    (state->current_band == BAND_CBAND &&
1126 		    (state->identity.version & 0x1f) <= P1D_E_F))) {
1127 			dprintk("DE-Engage mux for direct gain reg control");
1128 			en_pwm_rf_mux = 0;
1129 		} else
1130 			dprintk("Engage mux for PWM control");
1131 
1132 		dib0090_write_reg(state, 0x32, (en_pwm_rf_mux << 12) | (en_pwm_rf_mux << 11));
1133 
1134 		/* Set fast servo cutoff to start AGC; 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast*/
1135 		if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
1136 			dib0090_write_reg(state, 0x04, 3);
1137 		else
1138 			dib0090_write_reg(state, 0x04, 1);
1139 		dib0090_write_reg(state, 0x39, (1 << 10)); /* 0 gain by default */
1140 	}
1141 }
1142 EXPORT_SYMBOL(dib0090_pwm_gain_reset);
1143 
1144 void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff)
1145 {
1146 	struct dib0090_state *state = fe->tuner_priv;
1147 	if (DC_servo_cutoff < 4)
1148 		dib0090_write_reg(state, 0x04, DC_servo_cutoff);
1149 }
1150 EXPORT_SYMBOL(dib0090_set_dc_servo);
1151 
1152 static u32 dib0090_get_slow_adc_val(struct dib0090_state *state)
1153 {
1154 	u16 adc_val = dib0090_read_reg(state, 0x1d);
1155 	if (state->identity.in_soc)
1156 		adc_val >>= 2;
1157 	return adc_val;
1158 }
1159 
1160 int dib0090_gain_control(struct dvb_frontend *fe)
1161 {
1162 	struct dib0090_state *state = fe->tuner_priv;
1163 	enum frontend_tune_state *tune_state = &state->tune_state;
1164 	int ret = 10;
1165 
1166 	u16 wbd_val = 0;
1167 	u8 apply_gain_immediatly = 1;
1168 	s16 wbd_error = 0, adc_error = 0;
1169 
1170 	if (*tune_state == CT_AGC_START) {
1171 		state->agc_freeze = 0;
1172 		dib0090_write_reg(state, 0x04, 0x0);
1173 
1174 #ifdef CONFIG_BAND_SBAND
1175 		if (state->current_band == BAND_SBAND) {
1176 			dib0090_set_rframp(state, rf_ramp_sband);
1177 			dib0090_set_bbramp(state, bb_ramp_boost);
1178 		} else
1179 #endif
1180 #ifdef CONFIG_BAND_VHF
1181 		if (state->current_band == BAND_VHF && !state->identity.p1g) {
1182 			dib0090_set_rframp(state, rf_ramp_pwm_vhf);
1183 			dib0090_set_bbramp(state, bb_ramp_pwm_normal);
1184 		} else
1185 #endif
1186 #ifdef CONFIG_BAND_CBAND
1187 		if (state->current_band == BAND_CBAND && !state->identity.p1g) {
1188 			dib0090_set_rframp(state, rf_ramp_pwm_cband);
1189 			dib0090_set_bbramp(state, bb_ramp_pwm_normal);
1190 		} else
1191 #endif
1192 		if ((state->current_band == BAND_CBAND || state->current_band == BAND_VHF) && state->identity.p1g) {
1193 			dib0090_set_rframp(state, rf_ramp_pwm_cband_7090p);
1194 			dib0090_set_bbramp(state, bb_ramp_pwm_normal_socs);
1195 		} else {
1196 			dib0090_set_rframp(state, rf_ramp_pwm_uhf);
1197 			dib0090_set_bbramp(state, bb_ramp_pwm_normal);
1198 		}
1199 
1200 		dib0090_write_reg(state, 0x32, 0);
1201 		dib0090_write_reg(state, 0x39, 0);
1202 
1203 		dib0090_wbd_target(state, state->current_rf);
1204 
1205 		state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
1206 		state->current_gain = ((state->rf_ramp[0] + state->bb_ramp[0]) / 2) << GAIN_ALPHA;
1207 
1208 		*tune_state = CT_AGC_STEP_0;
1209 	} else if (!state->agc_freeze) {
1210 		s16 wbd = 0, i, cnt;
1211 
1212 		int adc;
1213 		wbd_val = dib0090_get_slow_adc_val(state);
1214 
1215 		if (*tune_state == CT_AGC_STEP_0)
1216 			cnt = 5;
1217 		else
1218 			cnt = 1;
1219 
1220 		for (i = 0; i < cnt; i++) {
1221 			wbd_val = dib0090_get_slow_adc_val(state);
1222 			wbd += dib0090_wbd_to_db(state, wbd_val);
1223 		}
1224 		wbd /= cnt;
1225 		wbd_error = state->wbd_target - wbd;
1226 
1227 		if (*tune_state == CT_AGC_STEP_0) {
1228 			if (wbd_error < 0 && state->rf_gain_limit > 0 && !state->identity.p1g) {
1229 #ifdef CONFIG_BAND_CBAND
1230 				/* in case of CBAND tune reduce first the lt_gain2 before adjusting the RF gain */
1231 				u8 ltg2 = (state->rf_lt_def >> 10) & 0x7;
1232 				if (state->current_band == BAND_CBAND && ltg2) {
1233 					ltg2 >>= 1;
1234 					state->rf_lt_def &= ltg2 << 10;	/* reduce in 3 steps from 7 to 0 */
1235 				}
1236 #endif
1237 			} else {
1238 				state->agc_step = 0;
1239 				*tune_state = CT_AGC_STEP_1;
1240 			}
1241 		} else {
1242 			/* calc the adc power */
1243 			adc = state->config->get_adc_power(fe);
1244 			adc = (adc * ((s32) 355774) + (((s32) 1) << 20)) >> 21;	/* included in [0:-700] */
1245 
1246 			adc_error = (s16) (((s32) ADC_TARGET) - adc);
1247 #ifdef CONFIG_STANDARD_DAB
1248 			if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB)
1249 				adc_error -= 10;
1250 #endif
1251 #ifdef CONFIG_STANDARD_DVBT
1252 			if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT &&
1253 					(state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16))
1254 				adc_error += 60;
1255 #endif
1256 #ifdef CONFIG_SYS_ISDBT
1257 			if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count >
1258 								0)
1259 							&&
1260 							((state->fe->dtv_property_cache.layer[0].modulation ==
1261 							  QAM_64)
1262 							 || (state->fe->dtv_property_cache.
1263 								 layer[0].modulation == QAM_16)))
1264 						||
1265 						((state->fe->dtv_property_cache.layer[1].segment_count >
1266 						  0)
1267 						 &&
1268 						 ((state->fe->dtv_property_cache.layer[1].modulation ==
1269 						   QAM_64)
1270 						  || (state->fe->dtv_property_cache.
1271 							  layer[1].modulation == QAM_16)))
1272 						||
1273 						((state->fe->dtv_property_cache.layer[2].segment_count >
1274 						  0)
1275 						 &&
1276 						 ((state->fe->dtv_property_cache.layer[2].modulation ==
1277 						   QAM_64)
1278 						  || (state->fe->dtv_property_cache.
1279 							  layer[2].modulation == QAM_16)))
1280 						)
1281 				)
1282 				adc_error += 60;
1283 #endif
1284 
1285 			if (*tune_state == CT_AGC_STEP_1) {	/* quickly go to the correct range of the ADC power */
1286 				if (ABS(adc_error) < 50 || state->agc_step++ > 5) {
1287 
1288 #ifdef CONFIG_STANDARD_DAB
1289 					if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) {
1290 						dib0090_write_reg(state, 0x02, (1 << 15) | (15 << 11) | (31 << 6) | (63));	/* cap value = 63 : narrow BB filter : Fc = 1.8MHz */
1291 						dib0090_write_reg(state, 0x04, 0x0);
1292 					} else
1293 #endif
1294 					{
1295 						dib0090_write_reg(state, 0x02, (1 << 15) | (3 << 11) | (6 << 6) | (32));
1296 						dib0090_write_reg(state, 0x04, 0x01);	/*0 = 1KHz ; 1 = 150Hz ; 2 = 50Hz ; 3 = 50KHz ; 4 = servo fast */
1297 					}
1298 
1299 					*tune_state = CT_AGC_STOP;
1300 				}
1301 			} else {
1302 				/* everything higher than or equal to CT_AGC_STOP means tracking */
1303 				ret = 100;	/* 10ms interval */
1304 				apply_gain_immediatly = 0;
1305 			}
1306 		}
1307 #ifdef DEBUG_AGC
1308 		dprintk
1309 			("tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm",
1310 			 (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val,
1311 			 (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA));
1312 #endif
1313 	}
1314 
1315 	/* apply gain */
1316 	if (!state->agc_freeze)
1317 		dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly);
1318 	return ret;
1319 }
1320 
1321 EXPORT_SYMBOL(dib0090_gain_control);
1322 
1323 void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
1324 {
1325 	struct dib0090_state *state = fe->tuner_priv;
1326 	if (rf)
1327 		*rf = state->gain[0];
1328 	if (bb)
1329 		*bb = state->gain[1];
1330 	if (rf_gain_limit)
1331 		*rf_gain_limit = state->rf_gain_limit;
1332 	if (rflt)
1333 		*rflt = (state->rf_lt_def >> 10) & 0x7;
1334 }
1335 
1336 EXPORT_SYMBOL(dib0090_get_current_gain);
1337 
1338 u16 dib0090_get_wbd_target(struct dvb_frontend *fe)
1339 {
1340 	struct dib0090_state *state = fe->tuner_priv;
1341 	u32 f_MHz = state->fe->dtv_property_cache.frequency / 1000000;
1342 	s32 current_temp = state->temperature;
1343 	s32 wbd_thot, wbd_tcold;
1344 	const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1345 
1346 	while (f_MHz > wbd->max_freq)
1347 		wbd++;
1348 
1349 	dprintk("using wbd-table-entry with max freq %d", wbd->max_freq);
1350 
1351 	if (current_temp < 0)
1352 		current_temp = 0;
1353 	if (current_temp > 128)
1354 		current_temp = 128;
1355 
1356 	state->wbdmux &= ~(7 << 13);
1357 	if (wbd->wbd_gain != 0)
1358 		state->wbdmux |= (wbd->wbd_gain << 13);
1359 	else
1360 		state->wbdmux |= (4 << 13);
1361 
1362 	dib0090_write_reg(state, 0x10, state->wbdmux);
1363 
1364 	wbd_thot = wbd->offset_hot - (((u32) wbd->slope_hot * f_MHz) >> 6);
1365 	wbd_tcold = wbd->offset_cold - (((u32) wbd->slope_cold * f_MHz) >> 6);
1366 
1367 	wbd_tcold += ((wbd_thot - wbd_tcold) * current_temp) >> 7;
1368 
1369 	state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + wbd_tcold);
1370 	dprintk("wbd-target: %d dB", (u32) state->wbd_target);
1371 	dprintk("wbd offset applied is %d", wbd_tcold);
1372 
1373 	return state->wbd_offset + wbd_tcold;
1374 }
1375 EXPORT_SYMBOL(dib0090_get_wbd_target);
1376 
1377 u16 dib0090_get_wbd_offset(struct dvb_frontend *fe)
1378 {
1379 	struct dib0090_state *state = fe->tuner_priv;
1380 	return state->wbd_offset;
1381 }
1382 EXPORT_SYMBOL(dib0090_get_wbd_offset);
1383 
1384 int dib0090_set_switch(struct dvb_frontend *fe, u8 sw1, u8 sw2, u8 sw3)
1385 {
1386 	struct dib0090_state *state = fe->tuner_priv;
1387 
1388 	dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xfff8)
1389 			| ((sw3 & 1) << 2) | ((sw2 & 1) << 1) | (sw1 & 1));
1390 
1391 	return 0;
1392 }
1393 EXPORT_SYMBOL(dib0090_set_switch);
1394 
1395 int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff)
1396 {
1397 	struct dib0090_state *state = fe->tuner_priv;
1398 
1399 	dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x7fff)
1400 			| ((onoff & 1) << 15));
1401 	return 0;
1402 }
1403 EXPORT_SYMBOL(dib0090_set_vga);
1404 
1405 int dib0090_update_rframp_7090(struct dvb_frontend *fe, u8 cfg_sensitivity)
1406 {
1407 	struct dib0090_state *state = fe->tuner_priv;
1408 
1409 	if ((!state->identity.p1g) || (!state->identity.in_soc)
1410 			|| ((state->identity.version != SOC_7090_P1G_21R1)
1411 				&& (state->identity.version != SOC_7090_P1G_11R1))) {
1412 		dprintk("%s() function can only be used for dib7090P", __func__);
1413 		return -ENODEV;
1414 	}
1415 
1416 	if (cfg_sensitivity)
1417 		state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_sensitivity;
1418 	else
1419 		state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_aci;
1420 	dib0090_pwm_gain_reset(fe);
1421 
1422 	return 0;
1423 }
1424 EXPORT_SYMBOL(dib0090_update_rframp_7090);
1425 
1426 static const u16 dib0090_defaults[] = {
1427 
1428 	25, 0x01,
1429 	0x0000,
1430 	0x99a0,
1431 	0x6008,
1432 	0x0000,
1433 	0x8bcb,
1434 	0x0000,
1435 	0x0405,
1436 	0x0000,
1437 	0x0000,
1438 	0x0000,
1439 	0xb802,
1440 	0x0300,
1441 	0x2d12,
1442 	0xbac0,
1443 	0x7c00,
1444 	0xdbb9,
1445 	0x0954,
1446 	0x0743,
1447 	0x8000,
1448 	0x0001,
1449 	0x0040,
1450 	0x0100,
1451 	0x0000,
1452 	0xe910,
1453 	0x149e,
1454 
1455 	1, 0x1c,
1456 	0xff2d,
1457 
1458 	1, 0x39,
1459 	0x0000,
1460 
1461 	2, 0x1e,
1462 	0x07FF,
1463 	0x0007,
1464 
1465 	1, 0x24,
1466 	EN_UHF | EN_CRYSTAL,
1467 
1468 	2, 0x3c,
1469 	0x3ff,
1470 	0x111,
1471 	0
1472 };
1473 
1474 static const u16 dib0090_p1g_additionnal_defaults[] = {
1475 	1, 0x05,
1476 	0xabcd,
1477 
1478 	1, 0x11,
1479 	0x00b4,
1480 
1481 	1, 0x1c,
1482 	0xfffd,
1483 
1484 	1, 0x40,
1485 	0x108,
1486 	0
1487 };
1488 
1489 static void dib0090_set_default_config(struct dib0090_state *state, const u16 * n)
1490 {
1491 	u16 l, r;
1492 
1493 	l = pgm_read_word(n++);
1494 	while (l) {
1495 		r = pgm_read_word(n++);
1496 		do {
1497 			dib0090_write_reg(state, r, pgm_read_word(n++));
1498 			r++;
1499 		} while (--l);
1500 		l = pgm_read_word(n++);
1501 	}
1502 }
1503 
1504 #define CAP_VALUE_MIN (u8)  9
1505 #define CAP_VALUE_MAX (u8) 40
1506 #define HR_MIN	      (u8) 25
1507 #define HR_MAX	      (u8) 40
1508 #define POLY_MIN      (u8)  0
1509 #define POLY_MAX      (u8)  8
1510 
1511 static void dib0090_set_EFUSE(struct dib0090_state *state)
1512 {
1513 	u8 c, h, n;
1514 	u16 e2, e4;
1515 	u16 cal;
1516 
1517 	e2 = dib0090_read_reg(state, 0x26);
1518 	e4 = dib0090_read_reg(state, 0x28);
1519 
1520 	if ((state->identity.version == P1D_E_F) ||
1521 			(state->identity.version == P1G) || (e2 == 0xffff)) {
1522 
1523 		dib0090_write_reg(state, 0x22, 0x10);
1524 		cal = (dib0090_read_reg(state, 0x22) >> 6) & 0x3ff;
1525 
1526 		if ((cal < 670) || (cal == 1023))
1527 			cal = 850;
1528 		n = 165 - ((cal * 10)>>6) ;
1529 		e2 = e4 = (3<<12) | (34<<6) | (n);
1530 	}
1531 
1532 	if (e2 != e4)
1533 		e2 &= e4; /* Remove the redundancy  */
1534 
1535 	if (e2 != 0xffff) {
1536 		c = e2 & 0x3f;
1537 		n = (e2 >> 12) & 0xf;
1538 		h = (e2 >> 6) & 0x3f;
1539 
1540 		if ((c >= CAP_VALUE_MAX) || (c <= CAP_VALUE_MIN))
1541 			c = 32;
1542 		else
1543 			c += 14;
1544 		if ((h >= HR_MAX) || (h <= HR_MIN))
1545 			h = 34;
1546 		if ((n >= POLY_MAX) || (n <= POLY_MIN))
1547 			n = 3;
1548 
1549 		dib0090_write_reg(state, 0x13, (h << 10));
1550 		e2 = (n << 11) | ((h >> 2)<<6) | c;
1551 		dib0090_write_reg(state, 0x2, e2); /* Load the BB_2 */
1552 	}
1553 }
1554 
1555 static int dib0090_reset(struct dvb_frontend *fe)
1556 {
1557 	struct dib0090_state *state = fe->tuner_priv;
1558 
1559 	dib0090_reset_digital(fe, state->config);
1560 	if (dib0090_identify(fe) < 0)
1561 		return -EIO;
1562 
1563 #ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT
1564 	if (!(state->identity.version & 0x1))	/* it is P1B - reset is already done */
1565 		return 0;
1566 #endif
1567 
1568 	if (!state->identity.in_soc) {
1569 		if ((dib0090_read_reg(state, 0x1a) >> 5) & 0x2)
1570 			dib0090_write_reg(state, 0x1b, (EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1571 		else
1572 			dib0090_write_reg(state, 0x1b, (EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1573 	}
1574 
1575 	dib0090_set_default_config(state, dib0090_defaults);
1576 
1577 	if (state->identity.in_soc)
1578 		dib0090_write_reg(state, 0x18, 0x2910);  /* charge pump current = 0 */
1579 
1580 	if (state->identity.p1g)
1581 		dib0090_set_default_config(state, dib0090_p1g_additionnal_defaults);
1582 
1583 	/* Update the efuse : Only available for KROSUS > P1C  and SOC as well*/
1584 	if (((state->identity.version & 0x1f) >= P1D_E_F) || (state->identity.in_soc))
1585 		dib0090_set_EFUSE(state);
1586 
1587 	/* Congigure in function of the crystal */
1588 	if (state->config->force_crystal_mode != 0)
1589 		dib0090_write_reg(state, 0x14,
1590 				state->config->force_crystal_mode & 3);
1591 	else if (state->config->io.clock_khz >= 24000)
1592 		dib0090_write_reg(state, 0x14, 1);
1593 	else
1594 		dib0090_write_reg(state, 0x14, 2);
1595 	dprintk("Pll lock : %d", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1);
1596 
1597 	state->calibrate = DC_CAL | WBD_CAL | TEMP_CAL;	/* enable iq-offset-calibration and wbd-calibration when tuning next time */
1598 
1599 	return 0;
1600 }
1601 
1602 #define steps(u) (((u) > 15) ? ((u)-16) : (u))
1603 #define INTERN_WAIT 10
1604 static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1605 {
1606 	int ret = INTERN_WAIT * 10;
1607 
1608 	switch (*tune_state) {
1609 	case CT_TUNER_STEP_2:
1610 		/* Turns to positive */
1611 		dib0090_write_reg(state, 0x1f, 0x7);
1612 		*tune_state = CT_TUNER_STEP_3;
1613 		break;
1614 
1615 	case CT_TUNER_STEP_3:
1616 		state->adc_diff = dib0090_read_reg(state, 0x1d);
1617 
1618 		/* Turns to negative */
1619 		dib0090_write_reg(state, 0x1f, 0x4);
1620 		*tune_state = CT_TUNER_STEP_4;
1621 		break;
1622 
1623 	case CT_TUNER_STEP_4:
1624 		state->adc_diff -= dib0090_read_reg(state, 0x1d);
1625 		*tune_state = CT_TUNER_STEP_5;
1626 		ret = 0;
1627 		break;
1628 
1629 	default:
1630 		break;
1631 	}
1632 
1633 	return ret;
1634 }
1635 
1636 struct dc_calibration {
1637 	u8 addr;
1638 	u8 offset;
1639 	u8 pga:1;
1640 	u16 bb1;
1641 	u8 i:1;
1642 };
1643 
1644 static const struct dc_calibration dc_table[] = {
1645 	/* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
1646 	{0x06, 5, 1, (1 << 13) | (0 << 8) | (26 << 3), 1},
1647 	{0x07, 11, 1, (1 << 13) | (0 << 8) | (26 << 3), 0},
1648 	/* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
1649 	{0x06, 0, 0, (1 << 13) | (29 << 8) | (26 << 3), 1},
1650 	{0x06, 10, 0, (1 << 13) | (29 << 8) | (26 << 3), 0},
1651 	{0},
1652 };
1653 
1654 static const struct dc_calibration dc_p1g_table[] = {
1655 	/* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
1656 	/* addr ; trim reg offset ; pga ; CTRL_BB1 value ; i or q */
1657 	{0x06, 5, 1, (1 << 13) | (0 << 8) | (15 << 3), 1},
1658 	{0x07, 11, 1, (1 << 13) | (0 << 8) | (15 << 3), 0},
1659 	/* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
1660 	{0x06, 0, 0, (1 << 13) | (29 << 8) | (15 << 3), 1},
1661 	{0x06, 10, 0, (1 << 13) | (29 << 8) | (15 << 3), 0},
1662 	{0},
1663 };
1664 
1665 static void dib0090_set_trim(struct dib0090_state *state)
1666 {
1667 	u16 *val;
1668 
1669 	if (state->dc->addr == 0x07)
1670 		val = &state->bb7;
1671 	else
1672 		val = &state->bb6;
1673 
1674 	*val &= ~(0x1f << state->dc->offset);
1675 	*val |= state->step << state->dc->offset;
1676 
1677 	dib0090_write_reg(state, state->dc->addr, *val);
1678 }
1679 
1680 static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1681 {
1682 	int ret = 0;
1683 	u16 reg;
1684 
1685 	switch (*tune_state) {
1686 	case CT_TUNER_START:
1687 		dprintk("Start DC offset calibration");
1688 
1689 		/* force vcm2 = 0.8V */
1690 		state->bb6 = 0;
1691 		state->bb7 = 0x040d;
1692 
1693 		/* the LNA AND LO are off */
1694 		reg = dib0090_read_reg(state, 0x24) & 0x0ffb;	/* shutdown lna and lo */
1695 		dib0090_write_reg(state, 0x24, reg);
1696 
1697 		state->wbdmux = dib0090_read_reg(state, 0x10);
1698 		dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x7 << 3) | 0x3);
1699 		dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
1700 
1701 		state->dc = dc_table;
1702 
1703 		if (state->identity.p1g)
1704 			state->dc = dc_p1g_table;
1705 
1706 		/* fall through */
1707 	case CT_TUNER_STEP_0:
1708 		dprintk("Start/continue DC calibration for %s path", (state->dc->i == 1) ? "I" : "Q");
1709 		dib0090_write_reg(state, 0x01, state->dc->bb1);
1710 		dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7));
1711 
1712 		state->step = 0;
1713 		state->min_adc_diff = 1023;
1714 		*tune_state = CT_TUNER_STEP_1;
1715 		ret = 50;
1716 		break;
1717 
1718 	case CT_TUNER_STEP_1:
1719 		dib0090_set_trim(state);
1720 		*tune_state = CT_TUNER_STEP_2;
1721 		break;
1722 
1723 	case CT_TUNER_STEP_2:
1724 	case CT_TUNER_STEP_3:
1725 	case CT_TUNER_STEP_4:
1726 		ret = dib0090_get_offset(state, tune_state);
1727 		break;
1728 
1729 	case CT_TUNER_STEP_5:	/* found an offset */
1730 		dprintk("adc_diff = %d, current step= %d", (u32) state->adc_diff, state->step);
1731 		if (state->step == 0 && state->adc_diff < 0) {
1732 			state->min_adc_diff = -1023;
1733 			dprintk("Change of sign of the minimum adc diff");
1734 		}
1735 
1736 		dprintk("adc_diff = %d, min_adc_diff = %d current_step = %d", state->adc_diff, state->min_adc_diff, state->step);
1737 
1738 		/* first turn for this frequency */
1739 		if (state->step == 0) {
1740 			if (state->dc->pga && state->adc_diff < 0)
1741 				state->step = 0x10;
1742 			if (state->dc->pga == 0 && state->adc_diff > 0)
1743 				state->step = 0x10;
1744 		}
1745 
1746 		/* Look for a change of Sign in the Adc_diff.min_adc_diff is used to STORE the setp N-1 */
1747 		if ((state->adc_diff & 0x8000) == (state->min_adc_diff & 0x8000) && steps(state->step) < 15) {
1748 			/* stop search when the delta the sign is changing and Steps =15 and Step=0 is force for continuance */
1749 			state->step++;
1750 			state->min_adc_diff = state->adc_diff;
1751 			*tune_state = CT_TUNER_STEP_1;
1752 		} else {
1753 			/* the minimum was what we have seen in the step before */
1754 			if (ABS(state->adc_diff) > ABS(state->min_adc_diff)) {
1755 				dprintk("Since adc_diff N = %d  > adc_diff step N-1 = %d, Come back one step", state->adc_diff, state->min_adc_diff);
1756 				state->step--;
1757 			}
1758 
1759 			dib0090_set_trim(state);
1760 			dprintk("BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd", state->dc->addr, state->adc_diff, state->step);
1761 
1762 			state->dc++;
1763 			if (state->dc->addr == 0)	/* done */
1764 				*tune_state = CT_TUNER_STEP_6;
1765 			else
1766 				*tune_state = CT_TUNER_STEP_0;
1767 
1768 		}
1769 		break;
1770 
1771 	case CT_TUNER_STEP_6:
1772 		dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008);
1773 		dib0090_write_reg(state, 0x1f, 0x7);
1774 		*tune_state = CT_TUNER_START;	/* reset done -> real tuning can now begin */
1775 		state->calibrate &= ~DC_CAL;
1776 	default:
1777 		break;
1778 	}
1779 	return ret;
1780 }
1781 
1782 static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1783 {
1784 	u8 wbd_gain;
1785 	const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1786 
1787 	switch (*tune_state) {
1788 	case CT_TUNER_START:
1789 		while (state->current_rf / 1000 > wbd->max_freq)
1790 			wbd++;
1791 		if (wbd->wbd_gain != 0)
1792 			wbd_gain = wbd->wbd_gain;
1793 		else {
1794 			wbd_gain = 4;
1795 #if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND)
1796 			if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND))
1797 				wbd_gain = 2;
1798 #endif
1799 		}
1800 
1801 		if (wbd_gain == state->wbd_calibration_gain) {	/* the WBD calibration has already been done */
1802 			*tune_state = CT_TUNER_START;
1803 			state->calibrate &= ~WBD_CAL;
1804 			return 0;
1805 		}
1806 
1807 		dib0090_write_reg(state, 0x10, 0x1b81 | (1 << 10) | (wbd_gain << 13) | (1 << 3));
1808 
1809 		dib0090_write_reg(state, 0x24, ((EN_UHF & 0x0fff) | (1 << 1)));
1810 		*tune_state = CT_TUNER_STEP_0;
1811 		state->wbd_calibration_gain = wbd_gain;
1812 		return 90;	/* wait for the WBDMUX to switch and for the ADC to sample */
1813 
1814 	case CT_TUNER_STEP_0:
1815 		state->wbd_offset = dib0090_get_slow_adc_val(state);
1816 		dprintk("WBD calibration offset = %d", state->wbd_offset);
1817 		*tune_state = CT_TUNER_START;	/* reset done -> real tuning can now begin */
1818 		state->calibrate &= ~WBD_CAL;
1819 		break;
1820 
1821 	default:
1822 		break;
1823 	}
1824 	return 0;
1825 }
1826 
1827 static void dib0090_set_bandwidth(struct dib0090_state *state)
1828 {
1829 	u16 tmp;
1830 
1831 	if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000)
1832 		tmp = (3 << 14);
1833 	else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000)
1834 		tmp = (2 << 14);
1835 	else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000)
1836 		tmp = (1 << 14);
1837 	else
1838 		tmp = (0 << 14);
1839 
1840 	state->bb_1_def &= 0x3fff;
1841 	state->bb_1_def |= tmp;
1842 
1843 	dib0090_write_reg(state, 0x01, state->bb_1_def);	/* be sure that we have the right bb-filter */
1844 
1845 	dib0090_write_reg(state, 0x03, 0x6008);	/* = 0x6008 : vcm3_trim = 1 ; filter2_gm1_trim = 8 ; filter2_cutoff_freq = 0 */
1846 	dib0090_write_reg(state, 0x04, 0x1);	/* 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast */
1847 	if (state->identity.in_soc) {
1848 		dib0090_write_reg(state, 0x05, 0x9bcf); /* attenuator_ibias_tri = 2 ; input_stage_ibias_tr = 1 ; nc = 11 ; ext_gm_trim = 1 ; obuf_ibias_trim = 4 ; filter13_gm2_ibias_t = 15 */
1849 	} else {
1850 		dib0090_write_reg(state, 0x02, (5 << 11) | (8 << 6) | (22 & 0x3f));	/* 22 = cap_value */
1851 		dib0090_write_reg(state, 0x05, 0xabcd);	/* = 0xabcd : attenuator_ibias_tri = 2 ; input_stage_ibias_tr = 2 ; nc = 11 ; ext_gm_trim = 1 ; obuf_ibias_trim = 4 ; filter13_gm2_ibias_t = 13 */
1852 	}
1853 }
1854 
1855 static const struct dib0090_pll dib0090_pll_table[] = {
1856 #ifdef CONFIG_BAND_CBAND
1857 	{56000, 0, 9, 48, 6},
1858 	{70000, 1, 9, 48, 6},
1859 	{87000, 0, 8, 32, 4},
1860 	{105000, 1, 8, 32, 4},
1861 	{115000, 0, 7, 24, 6},
1862 	{140000, 1, 7, 24, 6},
1863 	{170000, 0, 6, 16, 4},
1864 #endif
1865 #ifdef CONFIG_BAND_VHF
1866 	{200000, 1, 6, 16, 4},
1867 	{230000, 0, 5, 12, 6},
1868 	{280000, 1, 5, 12, 6},
1869 	{340000, 0, 4, 8, 4},
1870 	{380000, 1, 4, 8, 4},
1871 	{450000, 0, 3, 6, 6},
1872 #endif
1873 #ifdef CONFIG_BAND_UHF
1874 	{580000, 1, 3, 6, 6},
1875 	{700000, 0, 2, 4, 4},
1876 	{860000, 1, 2, 4, 4},
1877 #endif
1878 #ifdef CONFIG_BAND_LBAND
1879 	{1800000, 1, 0, 2, 4},
1880 #endif
1881 #ifdef CONFIG_BAND_SBAND
1882 	{2900000, 0, 14, 1, 4},
1883 #endif
1884 };
1885 
1886 static const struct dib0090_tuning dib0090_tuning_table_fm_vhf_on_cband[] = {
1887 
1888 #ifdef CONFIG_BAND_CBAND
1889 	{184000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1890 	{227000, 4, 3, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1891 	{380000, 4, 7, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1892 #endif
1893 #ifdef CONFIG_BAND_UHF
1894 	{520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1895 	{550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1896 	{650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1897 	{750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1898 	{850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1899 	{900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1900 #endif
1901 #ifdef CONFIG_BAND_LBAND
1902 	{1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1903 	{1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1904 	{1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1905 #endif
1906 #ifdef CONFIG_BAND_SBAND
1907 	{2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1908 	{2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1909 #endif
1910 };
1911 
1912 static const struct dib0090_tuning dib0090_tuning_table[] = {
1913 
1914 #ifdef CONFIG_BAND_CBAND
1915 	{170000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1916 #endif
1917 #ifdef CONFIG_BAND_VHF
1918 	{184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1919 	{227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1920 	{380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1921 #endif
1922 #ifdef CONFIG_BAND_UHF
1923 	{520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1924 	{550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1925 	{650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1926 	{750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1927 	{850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1928 	{900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1929 #endif
1930 #ifdef CONFIG_BAND_LBAND
1931 	{1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1932 	{1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1933 	{1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1934 #endif
1935 #ifdef CONFIG_BAND_SBAND
1936 	{2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1937 	{2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1938 #endif
1939 };
1940 
1941 static const struct dib0090_tuning dib0090_p1g_tuning_table[] = {
1942 #ifdef CONFIG_BAND_CBAND
1943 	{170000, 4, 1, 0x820f, 0x300, 0x2d22, 0x82cb, EN_CAB},
1944 #endif
1945 #ifdef CONFIG_BAND_VHF
1946 	{184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1947 	{227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1948 	{380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1949 #endif
1950 #ifdef CONFIG_BAND_UHF
1951 	{510000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1952 	{540000, 2, 1, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1953 	{600000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1954 	{630000, 2, 4, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1955 	{680000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1956 	{720000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1957 	{900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1958 #endif
1959 #ifdef CONFIG_BAND_LBAND
1960 	{1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1961 	{1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1962 	{1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1963 #endif
1964 #ifdef CONFIG_BAND_SBAND
1965 	{2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1966 	{2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1967 #endif
1968 };
1969 
1970 static const struct dib0090_pll dib0090_p1g_pll_table[] = {
1971 #ifdef CONFIG_BAND_CBAND
1972 	{57000, 0, 11, 48, 6},
1973 	{70000, 1, 11, 48, 6},
1974 	{86000, 0, 10, 32, 4},
1975 	{105000, 1, 10, 32, 4},
1976 	{115000, 0, 9, 24, 6},
1977 	{140000, 1, 9, 24, 6},
1978 	{170000, 0, 8, 16, 4},
1979 #endif
1980 #ifdef CONFIG_BAND_VHF
1981 	{200000, 1, 8, 16, 4},
1982 	{230000, 0, 7, 12, 6},
1983 	{280000, 1, 7, 12, 6},
1984 	{340000, 0, 6, 8, 4},
1985 	{380000, 1, 6, 8, 4},
1986 	{455000, 0, 5, 6, 6},
1987 #endif
1988 #ifdef CONFIG_BAND_UHF
1989 	{580000, 1, 5, 6, 6},
1990 	{680000, 0, 4, 4, 4},
1991 	{860000, 1, 4, 4, 4},
1992 #endif
1993 #ifdef CONFIG_BAND_LBAND
1994 	{1800000, 1, 2, 2, 4},
1995 #endif
1996 #ifdef CONFIG_BAND_SBAND
1997 	{2900000, 0, 1, 1, 6},
1998 #endif
1999 };
2000 
2001 static const struct dib0090_tuning dib0090_p1g_tuning_table_fm_vhf_on_cband[] = {
2002 #ifdef CONFIG_BAND_CBAND
2003 	{184000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
2004 	{227000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
2005 	{380000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
2006 #endif
2007 #ifdef CONFIG_BAND_UHF
2008 	{520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2009 	{550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2010 	{650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2011 	{750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2012 	{850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2013 	{900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2014 #endif
2015 #ifdef CONFIG_BAND_LBAND
2016 	{1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2017 	{1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2018 	{1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2019 #endif
2020 #ifdef CONFIG_BAND_SBAND
2021 	{2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
2022 	{2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
2023 #endif
2024 };
2025 
2026 static const struct dib0090_tuning dib0090_tuning_table_cband_7090[] = {
2027 #ifdef CONFIG_BAND_CBAND
2028 	{300000, 4, 3, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2029 	{380000, 4, 10, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2030 	{570000, 4, 10, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2031 	{858000, 4, 5, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2032 #endif
2033 };
2034 
2035 static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_sensitivity[] = {
2036 #ifdef CONFIG_BAND_CBAND
2037 	{ 300000,  0 ,  3,  0x8105, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2038 	{ 380000,  0 ,  10, 0x810F, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2039 	{ 600000,  0 ,  10, 0x815E, 0x280, 0x2d12, 0xb84e, EN_CAB },
2040 	{ 660000,  0 ,  5,  0x85E3, 0x280, 0x2d12, 0xb84e, EN_CAB },
2041 	{ 720000,  0 ,  5,  0x852E, 0x280, 0x2d12, 0xb84e, EN_CAB },
2042 	{ 860000,  0 ,  4,  0x85E5, 0x280, 0x2d12, 0xb84e, EN_CAB },
2043 #endif
2044 };
2045 
2046 int dib0090_update_tuning_table_7090(struct dvb_frontend *fe,
2047 		u8 cfg_sensitivity)
2048 {
2049 	struct dib0090_state *state = fe->tuner_priv;
2050 	const struct dib0090_tuning *tune =
2051 		dib0090_tuning_table_cband_7090e_sensitivity;
2052 	const struct dib0090_tuning dib0090_tuning_table_cband_7090e_aci[] = {
2053 		{ 300000,  0 ,  3,  0x8165, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2054 		{ 650000,  0 ,  4,  0x815B, 0x280, 0x2d12, 0xb84e, EN_CAB },
2055 		{ 860000,  0 ,  5,  0x84EF, 0x280, 0x2d12, 0xb84e, EN_CAB },
2056 	};
2057 
2058 	if ((!state->identity.p1g) || (!state->identity.in_soc)
2059 			|| ((state->identity.version != SOC_7090_P1G_21R1)
2060 				&& (state->identity.version != SOC_7090_P1G_11R1))) {
2061 		dprintk("%s() function can only be used for dib7090", __func__);
2062 		return -ENODEV;
2063 	}
2064 
2065 	if (cfg_sensitivity)
2066 		tune = dib0090_tuning_table_cband_7090e_sensitivity;
2067 	else
2068 		tune = dib0090_tuning_table_cband_7090e_aci;
2069 
2070 	while (state->rf_request > tune->max_freq)
2071 		tune++;
2072 
2073 	dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x8000)
2074 			| (tune->lna_bias & 0x7fff));
2075 	dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xf83f)
2076 			| ((tune->lna_tune << 6) & 0x07c0));
2077 	return 0;
2078 }
2079 EXPORT_SYMBOL(dib0090_update_tuning_table_7090);
2080 
2081 static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state)
2082 {
2083 	int ret = 0;
2084 	u16 lo4 = 0xe900;
2085 
2086 	s16 adc_target;
2087 	u16 adc;
2088 	s8 step_sign;
2089 	u8 force_soft_search = 0;
2090 
2091 	if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
2092 		force_soft_search = 1;
2093 
2094 	if (*tune_state == CT_TUNER_START) {
2095 		dprintk("Start Captrim search : %s", (force_soft_search == 1) ? "FORCE SOFT SEARCH" : "AUTO");
2096 		dib0090_write_reg(state, 0x10, 0x2B1);
2097 		dib0090_write_reg(state, 0x1e, 0x0032);
2098 
2099 		if (!state->tuner_is_tuned) {
2100 			/* prepare a complete captrim */
2101 			if (!state->identity.p1g || force_soft_search)
2102 				state->step = state->captrim = state->fcaptrim = 64;
2103 
2104 			state->current_rf = state->rf_request;
2105 		} else {	/* we are already tuned to this frequency - the configuration is correct  */
2106 			if (!state->identity.p1g || force_soft_search) {
2107 				/* do a minimal captrim even if the frequency has not changed */
2108 				state->step = 4;
2109 				state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f;
2110 			}
2111 		}
2112 		state->adc_diff = 3000;
2113 		*tune_state = CT_TUNER_STEP_0;
2114 
2115 	} else if (*tune_state == CT_TUNER_STEP_0) {
2116 		if (state->identity.p1g && !force_soft_search) {
2117 			u8 ratio = 31;
2118 
2119 			dib0090_write_reg(state, 0x40, (3 << 7) | (ratio << 2) | (1 << 1) | 1);
2120 			dib0090_read_reg(state, 0x40);
2121 			ret = 50;
2122 		} else {
2123 			state->step /= 2;
2124 			dib0090_write_reg(state, 0x18, lo4 | state->captrim);
2125 
2126 			if (state->identity.in_soc)
2127 				ret = 25;
2128 		}
2129 		*tune_state = CT_TUNER_STEP_1;
2130 
2131 	} else if (*tune_state == CT_TUNER_STEP_1) {
2132 		if (state->identity.p1g && !force_soft_search) {
2133 			dib0090_write_reg(state, 0x40, 0x18c | (0 << 1) | 0);
2134 			dib0090_read_reg(state, 0x40);
2135 
2136 			state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7F;
2137 			dprintk("***Final Captrim= 0x%x", state->fcaptrim);
2138 			*tune_state = CT_TUNER_STEP_3;
2139 
2140 		} else {
2141 			/* MERGE for all krosus before P1G */
2142 			adc = dib0090_get_slow_adc_val(state);
2143 			dprintk("CAPTRIM=%d; ADC = %d (ADC) & %dmV", (u32) state->captrim, (u32) adc, (u32) (adc) * (u32) 1800 / (u32) 1024);
2144 
2145 			if (state->rest == 0 || state->identity.in_soc) {	/* Just for 8090P SOCS where auto captrim HW bug : TO CHECK IN ACI for SOCS !!! if 400 for 8090p SOC => tune issue !!! */
2146 				adc_target = 200;
2147 			} else
2148 				adc_target = 400;
2149 
2150 			if (adc >= adc_target) {
2151 				adc -= adc_target;
2152 				step_sign = -1;
2153 			} else {
2154 				adc = adc_target - adc;
2155 				step_sign = 1;
2156 			}
2157 
2158 			if (adc < state->adc_diff) {
2159 				dprintk("CAPTRIM=%d is closer to target (%d/%d)", (u32) state->captrim, (u32) adc, (u32) state->adc_diff);
2160 				state->adc_diff = adc;
2161 				state->fcaptrim = state->captrim;
2162 			}
2163 
2164 			state->captrim += step_sign * state->step;
2165 			if (state->step >= 1)
2166 				*tune_state = CT_TUNER_STEP_0;
2167 			else
2168 				*tune_state = CT_TUNER_STEP_2;
2169 
2170 			ret = 25;
2171 		}
2172 	} else if (*tune_state == CT_TUNER_STEP_2) {	/* this step is only used by krosus < P1G */
2173 		/*write the final cptrim config */
2174 		dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim);
2175 
2176 		*tune_state = CT_TUNER_STEP_3;
2177 
2178 	} else if (*tune_state == CT_TUNER_STEP_3) {
2179 		state->calibrate &= ~CAPTRIM_CAL;
2180 		*tune_state = CT_TUNER_STEP_0;
2181 	}
2182 
2183 	return ret;
2184 }
2185 
2186 static int dib0090_get_temperature(struct dib0090_state *state, enum frontend_tune_state *tune_state)
2187 {
2188 	int ret = 15;
2189 	s16 val;
2190 
2191 	switch (*tune_state) {
2192 	case CT_TUNER_START:
2193 		state->wbdmux = dib0090_read_reg(state, 0x10);
2194 		dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x8 << 3));
2195 
2196 		state->bias = dib0090_read_reg(state, 0x13);
2197 		dib0090_write_reg(state, 0x13, state->bias | (0x3 << 8));
2198 
2199 		*tune_state = CT_TUNER_STEP_0;
2200 		/* wait for the WBDMUX to switch and for the ADC to sample */
2201 		break;
2202 
2203 	case CT_TUNER_STEP_0:
2204 		state->adc_diff = dib0090_get_slow_adc_val(state);
2205 		dib0090_write_reg(state, 0x13, (state->bias & ~(0x3 << 8)) | (0x2 << 8));
2206 		*tune_state = CT_TUNER_STEP_1;
2207 		break;
2208 
2209 	case CT_TUNER_STEP_1:
2210 		val = dib0090_get_slow_adc_val(state);
2211 		state->temperature = ((s16) ((val - state->adc_diff) * 180) >> 8) + 55;
2212 
2213 		dprintk("temperature: %d C", state->temperature - 30);
2214 
2215 		*tune_state = CT_TUNER_STEP_2;
2216 		break;
2217 
2218 	case CT_TUNER_STEP_2:
2219 		dib0090_write_reg(state, 0x13, state->bias);
2220 		dib0090_write_reg(state, 0x10, state->wbdmux);	/* write back original WBDMUX */
2221 
2222 		*tune_state = CT_TUNER_START;
2223 		state->calibrate &= ~TEMP_CAL;
2224 		if (state->config->analog_output == 0)
2225 			dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2226 
2227 		break;
2228 
2229 	default:
2230 		ret = 0;
2231 		break;
2232 	}
2233 	return ret;
2234 }
2235 
2236 #define WBD     0x781		/* 1 1 1 1 0000 0 0 1 */
2237 static int dib0090_tune(struct dvb_frontend *fe)
2238 {
2239 	struct dib0090_state *state = fe->tuner_priv;
2240 	const struct dib0090_tuning *tune = state->current_tune_table_index;
2241 	const struct dib0090_pll *pll = state->current_pll_table_index;
2242 	enum frontend_tune_state *tune_state = &state->tune_state;
2243 
2244 	u16 lo5, lo6, Den, tmp;
2245 	u32 FBDiv, Rest, FREF, VCOF_kHz = 0;
2246 	int ret = 10;		/* 1ms is the default delay most of the time */
2247 	u8 c, i;
2248 
2249 	/************************* VCO ***************************/
2250 	/* Default values for FG                                 */
2251 	/* from these are needed :                               */
2252 	/* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv             */
2253 
2254 	/* in any case we first need to do a calibration if needed */
2255 	if (*tune_state == CT_TUNER_START) {
2256 		/* deactivate DataTX before some calibrations */
2257 		if (state->calibrate & (DC_CAL | TEMP_CAL | WBD_CAL))
2258 			dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
2259 		else
2260 			/* Activate DataTX in case a calibration has been done before */
2261 			if (state->config->analog_output == 0)
2262 				dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2263 	}
2264 
2265 	if (state->calibrate & DC_CAL)
2266 		return dib0090_dc_offset_calibration(state, tune_state);
2267 	else if (state->calibrate & WBD_CAL) {
2268 		if (state->current_rf == 0)
2269 			state->current_rf = state->fe->dtv_property_cache.frequency / 1000;
2270 		return dib0090_wbd_calibration(state, tune_state);
2271 	} else if (state->calibrate & TEMP_CAL)
2272 		return dib0090_get_temperature(state, tune_state);
2273 	else if (state->calibrate & CAPTRIM_CAL)
2274 		return dib0090_captrim_search(state, tune_state);
2275 
2276 	if (*tune_state == CT_TUNER_START) {
2277 		/* if soc and AGC pwm control, disengage mux to be able to R/W access to 0x01 register to set the right filter (cutoff_freq_select) during the tune sequence, otherwise, SOC SERPAR error when accessing to 0x01 */
2278 		if (state->config->use_pwm_agc && state->identity.in_soc) {
2279 			tmp = dib0090_read_reg(state, 0x39);
2280 			if ((tmp >> 10) & 0x1)
2281 				dib0090_write_reg(state, 0x39, tmp & ~(1 << 10));
2282 		}
2283 
2284 		state->current_band = (u8) BAND_OF_FREQUENCY(state->fe->dtv_property_cache.frequency / 1000);
2285 		state->rf_request =
2286 			state->fe->dtv_property_cache.frequency / 1000 + (state->current_band ==
2287 					BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->
2288 					freq_offset_khz_vhf);
2289 
2290 		/* in ISDB-T 1seg we shift tuning frequency */
2291 		if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1
2292 					&& state->fe->dtv_property_cache.isdbt_partial_reception == 0)) {
2293 			const struct dib0090_low_if_offset_table *LUT_offset = state->config->low_if;
2294 			u8 found_offset = 0;
2295 			u32 margin_khz = 100;
2296 
2297 			if (LUT_offset != NULL) {
2298 				while (LUT_offset->RF_freq != 0xffff) {
2299 					if (((state->rf_request > (LUT_offset->RF_freq - margin_khz))
2300 								&& (state->rf_request < (LUT_offset->RF_freq + margin_khz)))
2301 							&& LUT_offset->std == state->fe->dtv_property_cache.delivery_system) {
2302 						state->rf_request += LUT_offset->offset_khz;
2303 						found_offset = 1;
2304 						break;
2305 					}
2306 					LUT_offset++;
2307 				}
2308 			}
2309 
2310 			if (found_offset == 0)
2311 				state->rf_request += 400;
2312 		}
2313 		if (state->current_rf != state->rf_request || (state->current_standard != state->fe->dtv_property_cache.delivery_system)) {
2314 			state->tuner_is_tuned = 0;
2315 			state->current_rf = 0;
2316 			state->current_standard = 0;
2317 
2318 			tune = dib0090_tuning_table;
2319 			if (state->identity.p1g)
2320 				tune = dib0090_p1g_tuning_table;
2321 
2322 			tmp = (state->identity.version >> 5) & 0x7;
2323 
2324 			if (state->identity.in_soc) {
2325 				if (state->config->force_cband_input) {	/* Use the CBAND input for all band */
2326 					if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF
2327 							|| state->current_band & BAND_UHF) {
2328 						state->current_band = BAND_CBAND;
2329 						if (state->config->is_dib7090e)
2330 							tune = dib0090_tuning_table_cband_7090e_sensitivity;
2331 						else
2332 							tune = dib0090_tuning_table_cband_7090;
2333 					}
2334 				} else {	/* Use the CBAND input for all band under UHF */
2335 					if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) {
2336 						state->current_band = BAND_CBAND;
2337 						if (state->config->is_dib7090e)
2338 							tune = dib0090_tuning_table_cband_7090e_sensitivity;
2339 						else
2340 							tune = dib0090_tuning_table_cband_7090;
2341 					}
2342 				}
2343 			} else
2344 			 if (tmp == 0x4 || tmp == 0x7) {
2345 				/* CBAND tuner version for VHF */
2346 				if (state->current_band == BAND_FM || state->current_band == BAND_CBAND || state->current_band == BAND_VHF) {
2347 					state->current_band = BAND_CBAND;	/* Force CBAND */
2348 
2349 					tune = dib0090_tuning_table_fm_vhf_on_cband;
2350 					if (state->identity.p1g)
2351 						tune = dib0090_p1g_tuning_table_fm_vhf_on_cband;
2352 				}
2353 			}
2354 
2355 			pll = dib0090_pll_table;
2356 			if (state->identity.p1g)
2357 				pll = dib0090_p1g_pll_table;
2358 
2359 			/* Look for the interval */
2360 			while (state->rf_request > tune->max_freq)
2361 				tune++;
2362 			while (state->rf_request > pll->max_freq)
2363 				pll++;
2364 
2365 			state->current_tune_table_index = tune;
2366 			state->current_pll_table_index = pll;
2367 
2368 			dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim));
2369 
2370 			VCOF_kHz = (pll->hfdiv * state->rf_request) * 2;
2371 
2372 			FREF = state->config->io.clock_khz;
2373 			if (state->config->fref_clock_ratio != 0)
2374 				FREF /= state->config->fref_clock_ratio;
2375 
2376 			FBDiv = (VCOF_kHz / pll->topresc / FREF);
2377 			Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF;
2378 
2379 			if (Rest < LPF)
2380 				Rest = 0;
2381 			else if (Rest < 2 * LPF)
2382 				Rest = 2 * LPF;
2383 			else if (Rest > (FREF - LPF)) {
2384 				Rest = 0;
2385 				FBDiv += 1;
2386 			} else if (Rest > (FREF - 2 * LPF))
2387 				Rest = FREF - 2 * LPF;
2388 			Rest = (Rest * 6528) / (FREF / 10);
2389 			state->rest = Rest;
2390 
2391 			/* external loop filter, otherwise:
2392 			 * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4;
2393 			 * lo6 = 0x0e34 */
2394 
2395 			if (Rest == 0) {
2396 				if (pll->vco_band)
2397 					lo5 = 0x049f;
2398 				else
2399 					lo5 = 0x041f;
2400 			} else {
2401 				if (pll->vco_band)
2402 					lo5 = 0x049e;
2403 				else if (state->config->analog_output)
2404 					lo5 = 0x041d;
2405 				else
2406 					lo5 = 0x041c;
2407 			}
2408 
2409 			if (state->identity.p1g) {	/* Bias is done automatically in P1G */
2410 				if (state->identity.in_soc) {
2411 					if (state->identity.version == SOC_8090_P1G_11R1)
2412 						lo5 = 0x46f;
2413 					else
2414 						lo5 = 0x42f;
2415 				} else
2416 					lo5 = 0x42c;
2417 			}
2418 
2419 			lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7);	/* bit 15 is the split to the slave, we do not do it here */
2420 
2421 			if (!state->config->io.pll_int_loop_filt) {
2422 				if (state->identity.in_soc)
2423 					lo6 = 0xff98;
2424 				else if (state->identity.p1g || (Rest == 0))
2425 					lo6 = 0xfff8;
2426 				else
2427 					lo6 = 0xff28;
2428 			} else
2429 				lo6 = (state->config->io.pll_int_loop_filt << 3);
2430 
2431 			Den = 1;
2432 
2433 			if (Rest > 0) {
2434 				if (state->config->analog_output)
2435 					lo6 |= (1 << 2) | 2;
2436 				else {
2437 					if (state->identity.in_soc)
2438 						lo6 |= (1 << 2) | 2;
2439 					else
2440 						lo6 |= (1 << 2) | 2;
2441 				}
2442 				Den = 255;
2443 			}
2444 			dib0090_write_reg(state, 0x15, (u16) FBDiv);
2445 			if (state->config->fref_clock_ratio != 0)
2446 				dib0090_write_reg(state, 0x16, (Den << 8) | state->config->fref_clock_ratio);
2447 			else
2448 				dib0090_write_reg(state, 0x16, (Den << 8) | 1);
2449 			dib0090_write_reg(state, 0x17, (u16) Rest);
2450 			dib0090_write_reg(state, 0x19, lo5);
2451 			dib0090_write_reg(state, 0x1c, lo6);
2452 
2453 			lo6 = tune->tuner_enable;
2454 			if (state->config->analog_output)
2455 				lo6 = (lo6 & 0xff9f) | 0x2;
2456 
2457 			dib0090_write_reg(state, 0x24, lo6 | EN_LO | state->config->use_pwm_agc * EN_CRYSTAL);
2458 
2459 		}
2460 
2461 		state->current_rf = state->rf_request;
2462 		state->current_standard = state->fe->dtv_property_cache.delivery_system;
2463 
2464 		ret = 20;
2465 		state->calibrate = CAPTRIM_CAL;	/* captrim serach now */
2466 	}
2467 
2468 	else if (*tune_state == CT_TUNER_STEP_0) {	/* Warning : because of captrim cal, if you change this step, change it also in _cal.c file because it is the step following captrim cal state machine */
2469 		const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
2470 
2471 		while (state->current_rf / 1000 > wbd->max_freq)
2472 			wbd++;
2473 
2474 		dib0090_write_reg(state, 0x1e, 0x07ff);
2475 		dprintk("Final Captrim: %d", (u32) state->fcaptrim);
2476 		dprintk("HFDIV code: %d", (u32) pll->hfdiv_code);
2477 		dprintk("VCO = %d", (u32) pll->vco_band);
2478 		dprintk("VCOF in kHz: %d ((%d*%d) << 1))", (u32) ((pll->hfdiv * state->rf_request) * 2), (u32) pll->hfdiv, (u32) state->rf_request);
2479 		dprintk("REFDIV: %d, FREF: %d", (u32) 1, (u32) state->config->io.clock_khz);
2480 		dprintk("FBDIV: %d, Rest: %d", (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17));
2481 		dprintk("Num: %d, Den: %d, SD: %d", (u32) dib0090_read_reg(state, 0x17), (u32) (dib0090_read_reg(state, 0x16) >> 8),
2482 			(u32) dib0090_read_reg(state, 0x1c) & 0x3);
2483 
2484 #define WBD     0x781		/* 1 1 1 1 0000 0 0 1 */
2485 		c = 4;
2486 		i = 3;
2487 
2488 		if (wbd->wbd_gain != 0)
2489 			c = wbd->wbd_gain;
2490 
2491 		state->wbdmux = (c << 13) | (i << 11) | (WBD | (state->config->use_pwm_agc << 1));
2492 		dib0090_write_reg(state, 0x10, state->wbdmux);
2493 
2494 		if ((tune->tuner_enable == EN_CAB) && state->identity.p1g) {
2495 			dprintk("P1G : The cable band is selected and lna_tune = %d", tune->lna_tune);
2496 			dib0090_write_reg(state, 0x09, tune->lna_bias);
2497 			dib0090_write_reg(state, 0x0b, 0xb800 | (tune->lna_tune << 6) | (tune->switch_trim));
2498 		} else
2499 			dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | tune->lna_bias);
2500 
2501 		dib0090_write_reg(state, 0x0c, tune->v2i);
2502 		dib0090_write_reg(state, 0x0d, tune->mix);
2503 		dib0090_write_reg(state, 0x0e, tune->load);
2504 		*tune_state = CT_TUNER_STEP_1;
2505 
2506 	} else if (*tune_state == CT_TUNER_STEP_1) {
2507 		/* initialize the lt gain register */
2508 		state->rf_lt_def = 0x7c00;
2509 
2510 		dib0090_set_bandwidth(state);
2511 		state->tuner_is_tuned = 1;
2512 
2513 		state->calibrate |= WBD_CAL;
2514 		state->calibrate |= TEMP_CAL;
2515 		*tune_state = CT_TUNER_STOP;
2516 	} else
2517 		ret = FE_CALLBACK_TIME_NEVER;
2518 	return ret;
2519 }
2520 
2521 static int dib0090_release(struct dvb_frontend *fe)
2522 {
2523 	kfree(fe->tuner_priv);
2524 	fe->tuner_priv = NULL;
2525 	return 0;
2526 }
2527 
2528 enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
2529 {
2530 	struct dib0090_state *state = fe->tuner_priv;
2531 
2532 	return state->tune_state;
2533 }
2534 
2535 EXPORT_SYMBOL(dib0090_get_tune_state);
2536 
2537 int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
2538 {
2539 	struct dib0090_state *state = fe->tuner_priv;
2540 
2541 	state->tune_state = tune_state;
2542 	return 0;
2543 }
2544 
2545 EXPORT_SYMBOL(dib0090_set_tune_state);
2546 
2547 static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency)
2548 {
2549 	struct dib0090_state *state = fe->tuner_priv;
2550 
2551 	*frequency = 1000 * state->current_rf;
2552 	return 0;
2553 }
2554 
2555 static int dib0090_set_params(struct dvb_frontend *fe)
2556 {
2557 	struct dib0090_state *state = fe->tuner_priv;
2558 	u32 ret;
2559 
2560 	state->tune_state = CT_TUNER_START;
2561 
2562 	do {
2563 		ret = dib0090_tune(fe);
2564 		if (ret == FE_CALLBACK_TIME_NEVER)
2565 			break;
2566 
2567 		/*
2568 		 * Despite dib0090_tune returns time at a 0.1 ms range,
2569 		 * the actual sleep time depends on CONFIG_HZ. The worse case
2570 		 * is when CONFIG_HZ=100. In such case, the minimum granularity
2571 		 * is 10ms. On some real field tests, the tuner sometimes don't
2572 		 * lock when this timer is lower than 10ms. So, enforce a 10ms
2573 		 * granularity and use usleep_range() instead of msleep().
2574 		 */
2575 		ret = 10 * (ret + 99)/100;
2576 		usleep_range(ret * 1000, (ret + 1) * 1000);
2577 	} while (state->tune_state != CT_TUNER_STOP);
2578 
2579 	return 0;
2580 }
2581 
2582 static const struct dvb_tuner_ops dib0090_ops = {
2583 	.info = {
2584 		 .name = "DiBcom DiB0090",
2585 		 .frequency_min = 45000000,
2586 		 .frequency_max = 860000000,
2587 		 .frequency_step = 1000,
2588 		 },
2589 	.release = dib0090_release,
2590 
2591 	.init = dib0090_wakeup,
2592 	.sleep = dib0090_sleep,
2593 	.set_params = dib0090_set_params,
2594 	.get_frequency = dib0090_get_frequency,
2595 };
2596 
2597 static const struct dvb_tuner_ops dib0090_fw_ops = {
2598 	.info = {
2599 		 .name = "DiBcom DiB0090",
2600 		 .frequency_min = 45000000,
2601 		 .frequency_max = 860000000,
2602 		 .frequency_step = 1000,
2603 		 },
2604 	.release = dib0090_release,
2605 
2606 	.init = NULL,
2607 	.sleep = NULL,
2608 	.set_params = NULL,
2609 	.get_frequency = NULL,
2610 };
2611 
2612 static const struct dib0090_wbd_slope dib0090_wbd_table_default[] = {
2613 	{470, 0, 250, 0, 100, 4},
2614 	{860, 51, 866, 21, 375, 4},
2615 	{1700, 0, 800, 0, 850, 4},
2616 	{2900, 0, 250, 0, 100, 6},
2617 	{0xFFFF, 0, 0, 0, 0, 0},
2618 };
2619 
2620 struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
2621 {
2622 	struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL);
2623 	if (st == NULL)
2624 		return NULL;
2625 
2626 	st->config = config;
2627 	st->i2c = i2c;
2628 	st->fe = fe;
2629 	mutex_init(&st->i2c_buffer_lock);
2630 	fe->tuner_priv = st;
2631 
2632 	if (config->wbd == NULL)
2633 		st->current_wbd_table = dib0090_wbd_table_default;
2634 	else
2635 		st->current_wbd_table = config->wbd;
2636 
2637 	if (dib0090_reset(fe) != 0)
2638 		goto free_mem;
2639 
2640 	printk(KERN_INFO "DiB0090: successfully identified\n");
2641 	memcpy(&fe->ops.tuner_ops, &dib0090_ops, sizeof(struct dvb_tuner_ops));
2642 
2643 	return fe;
2644  free_mem:
2645 	kfree(st);
2646 	fe->tuner_priv = NULL;
2647 	return NULL;
2648 }
2649 
2650 EXPORT_SYMBOL(dib0090_register);
2651 
2652 struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
2653 {
2654 	struct dib0090_fw_state *st = kzalloc(sizeof(struct dib0090_fw_state), GFP_KERNEL);
2655 	if (st == NULL)
2656 		return NULL;
2657 
2658 	st->config = config;
2659 	st->i2c = i2c;
2660 	st->fe = fe;
2661 	mutex_init(&st->i2c_buffer_lock);
2662 	fe->tuner_priv = st;
2663 
2664 	if (dib0090_fw_reset_digital(fe, st->config) != 0)
2665 		goto free_mem;
2666 
2667 	dprintk("DiB0090 FW: successfully identified");
2668 	memcpy(&fe->ops.tuner_ops, &dib0090_fw_ops, sizeof(struct dvb_tuner_ops));
2669 
2670 	return fe;
2671 free_mem:
2672 	kfree(st);
2673 	fe->tuner_priv = NULL;
2674 	return NULL;
2675 }
2676 EXPORT_SYMBOL(dib0090_fw_register);
2677 
2678 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
2679 MODULE_AUTHOR("Olivier Grenie <olivier.grenie@parrot.com>");
2680 MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner");
2681 MODULE_LICENSE("GPL");
2682