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