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