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 		/* fall through */
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=%hd,Offset=%hd,Value Set=%hd\n", state->dc->addr, state->adc_diff, state->step);
1752 
1753 			state->dc++;
1754 			if (state->dc->addr == 0)	/* done */
1755 				*tune_state = CT_TUNER_STEP_6;
1756 			else
1757 				*tune_state = CT_TUNER_STEP_0;
1758 
1759 		}
1760 		break;
1761 
1762 	case CT_TUNER_STEP_6:
1763 		dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008);
1764 		dib0090_write_reg(state, 0x1f, 0x7);
1765 		*tune_state = CT_TUNER_START;	/* reset done -> real tuning can now begin */
1766 		state->calibrate &= ~DC_CAL;
1767 	default:
1768 		break;
1769 	}
1770 	return ret;
1771 }
1772 
1773 static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1774 {
1775 	u8 wbd_gain;
1776 	const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1777 
1778 	switch (*tune_state) {
1779 	case CT_TUNER_START:
1780 		while (state->current_rf / 1000 > wbd->max_freq)
1781 			wbd++;
1782 		if (wbd->wbd_gain != 0)
1783 			wbd_gain = wbd->wbd_gain;
1784 		else {
1785 			wbd_gain = 4;
1786 #if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND)
1787 			if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND))
1788 				wbd_gain = 2;
1789 #endif
1790 		}
1791 
1792 		if (wbd_gain == state->wbd_calibration_gain) {	/* the WBD calibration has already been done */
1793 			*tune_state = CT_TUNER_START;
1794 			state->calibrate &= ~WBD_CAL;
1795 			return 0;
1796 		}
1797 
1798 		dib0090_write_reg(state, 0x10, 0x1b81 | (1 << 10) | (wbd_gain << 13) | (1 << 3));
1799 
1800 		dib0090_write_reg(state, 0x24, ((EN_UHF & 0x0fff) | (1 << 1)));
1801 		*tune_state = CT_TUNER_STEP_0;
1802 		state->wbd_calibration_gain = wbd_gain;
1803 		return 90;	/* wait for the WBDMUX to switch and for the ADC to sample */
1804 
1805 	case CT_TUNER_STEP_0:
1806 		state->wbd_offset = dib0090_get_slow_adc_val(state);
1807 		dprintk("WBD calibration offset = %d\n", state->wbd_offset);
1808 		*tune_state = CT_TUNER_START;	/* reset done -> real tuning can now begin */
1809 		state->calibrate &= ~WBD_CAL;
1810 		break;
1811 
1812 	default:
1813 		break;
1814 	}
1815 	return 0;
1816 }
1817 
1818 static void dib0090_set_bandwidth(struct dib0090_state *state)
1819 {
1820 	u16 tmp;
1821 
1822 	if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000)
1823 		tmp = (3 << 14);
1824 	else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000)
1825 		tmp = (2 << 14);
1826 	else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000)
1827 		tmp = (1 << 14);
1828 	else
1829 		tmp = (0 << 14);
1830 
1831 	state->bb_1_def &= 0x3fff;
1832 	state->bb_1_def |= tmp;
1833 
1834 	dib0090_write_reg(state, 0x01, state->bb_1_def);	/* be sure that we have the right bb-filter */
1835 
1836 	dib0090_write_reg(state, 0x03, 0x6008);	/* = 0x6008 : vcm3_trim = 1 ; filter2_gm1_trim = 8 ; filter2_cutoff_freq = 0 */
1837 	dib0090_write_reg(state, 0x04, 0x1);	/* 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast */
1838 	if (state->identity.in_soc) {
1839 		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 */
1840 	} else {
1841 		dib0090_write_reg(state, 0x02, (5 << 11) | (8 << 6) | (22 & 0x3f));	/* 22 = cap_value */
1842 		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 */
1843 	}
1844 }
1845 
1846 static const struct dib0090_pll dib0090_pll_table[] = {
1847 #ifdef CONFIG_BAND_CBAND
1848 	{56000, 0, 9, 48, 6},
1849 	{70000, 1, 9, 48, 6},
1850 	{87000, 0, 8, 32, 4},
1851 	{105000, 1, 8, 32, 4},
1852 	{115000, 0, 7, 24, 6},
1853 	{140000, 1, 7, 24, 6},
1854 	{170000, 0, 6, 16, 4},
1855 #endif
1856 #ifdef CONFIG_BAND_VHF
1857 	{200000, 1, 6, 16, 4},
1858 	{230000, 0, 5, 12, 6},
1859 	{280000, 1, 5, 12, 6},
1860 	{340000, 0, 4, 8, 4},
1861 	{380000, 1, 4, 8, 4},
1862 	{450000, 0, 3, 6, 6},
1863 #endif
1864 #ifdef CONFIG_BAND_UHF
1865 	{580000, 1, 3, 6, 6},
1866 	{700000, 0, 2, 4, 4},
1867 	{860000, 1, 2, 4, 4},
1868 #endif
1869 #ifdef CONFIG_BAND_LBAND
1870 	{1800000, 1, 0, 2, 4},
1871 #endif
1872 #ifdef CONFIG_BAND_SBAND
1873 	{2900000, 0, 14, 1, 4},
1874 #endif
1875 };
1876 
1877 static const struct dib0090_tuning dib0090_tuning_table_fm_vhf_on_cband[] = {
1878 
1879 #ifdef CONFIG_BAND_CBAND
1880 	{184000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1881 	{227000, 4, 3, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1882 	{380000, 4, 7, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1883 #endif
1884 #ifdef CONFIG_BAND_UHF
1885 	{520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1886 	{550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1887 	{650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1888 	{750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1889 	{850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1890 	{900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1891 #endif
1892 #ifdef CONFIG_BAND_LBAND
1893 	{1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1894 	{1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1895 	{1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1896 #endif
1897 #ifdef CONFIG_BAND_SBAND
1898 	{2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1899 	{2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1900 #endif
1901 };
1902 
1903 static const struct dib0090_tuning dib0090_tuning_table[] = {
1904 
1905 #ifdef CONFIG_BAND_CBAND
1906 	{170000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1907 #endif
1908 #ifdef CONFIG_BAND_VHF
1909 	{184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1910 	{227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1911 	{380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1912 #endif
1913 #ifdef CONFIG_BAND_UHF
1914 	{520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1915 	{550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1916 	{650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1917 	{750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1918 	{850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1919 	{900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1920 #endif
1921 #ifdef CONFIG_BAND_LBAND
1922 	{1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1923 	{1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1924 	{1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1925 #endif
1926 #ifdef CONFIG_BAND_SBAND
1927 	{2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1928 	{2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1929 #endif
1930 };
1931 
1932 static const struct dib0090_tuning dib0090_p1g_tuning_table[] = {
1933 #ifdef CONFIG_BAND_CBAND
1934 	{170000, 4, 1, 0x820f, 0x300, 0x2d22, 0x82cb, EN_CAB},
1935 #endif
1936 #ifdef CONFIG_BAND_VHF
1937 	{184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1938 	{227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1939 	{380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1940 #endif
1941 #ifdef CONFIG_BAND_UHF
1942 	{510000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1943 	{540000, 2, 1, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1944 	{600000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1945 	{630000, 2, 4, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1946 	{680000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1947 	{720000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1948 	{900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1949 #endif
1950 #ifdef CONFIG_BAND_LBAND
1951 	{1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1952 	{1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1953 	{1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1954 #endif
1955 #ifdef CONFIG_BAND_SBAND
1956 	{2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1957 	{2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1958 #endif
1959 };
1960 
1961 static const struct dib0090_pll dib0090_p1g_pll_table[] = {
1962 #ifdef CONFIG_BAND_CBAND
1963 	{57000, 0, 11, 48, 6},
1964 	{70000, 1, 11, 48, 6},
1965 	{86000, 0, 10, 32, 4},
1966 	{105000, 1, 10, 32, 4},
1967 	{115000, 0, 9, 24, 6},
1968 	{140000, 1, 9, 24, 6},
1969 	{170000, 0, 8, 16, 4},
1970 #endif
1971 #ifdef CONFIG_BAND_VHF
1972 	{200000, 1, 8, 16, 4},
1973 	{230000, 0, 7, 12, 6},
1974 	{280000, 1, 7, 12, 6},
1975 	{340000, 0, 6, 8, 4},
1976 	{380000, 1, 6, 8, 4},
1977 	{455000, 0, 5, 6, 6},
1978 #endif
1979 #ifdef CONFIG_BAND_UHF
1980 	{580000, 1, 5, 6, 6},
1981 	{680000, 0, 4, 4, 4},
1982 	{860000, 1, 4, 4, 4},
1983 #endif
1984 #ifdef CONFIG_BAND_LBAND
1985 	{1800000, 1, 2, 2, 4},
1986 #endif
1987 #ifdef CONFIG_BAND_SBAND
1988 	{2900000, 0, 1, 1, 6},
1989 #endif
1990 };
1991 
1992 static const struct dib0090_tuning dib0090_p1g_tuning_table_fm_vhf_on_cband[] = {
1993 #ifdef CONFIG_BAND_CBAND
1994 	{184000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
1995 	{227000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
1996 	{380000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
1997 #endif
1998 #ifdef CONFIG_BAND_UHF
1999 	{520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2000 	{550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2001 	{650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2002 	{750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2003 	{850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2004 	{900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2005 #endif
2006 #ifdef CONFIG_BAND_LBAND
2007 	{1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2008 	{1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2009 	{1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2010 #endif
2011 #ifdef CONFIG_BAND_SBAND
2012 	{2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
2013 	{2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
2014 #endif
2015 };
2016 
2017 static const struct dib0090_tuning dib0090_tuning_table_cband_7090[] = {
2018 #ifdef CONFIG_BAND_CBAND
2019 	{300000, 4, 3, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2020 	{380000, 4, 10, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2021 	{570000, 4, 10, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2022 	{858000, 4, 5, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2023 #endif
2024 };
2025 
2026 static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_sensitivity[] = {
2027 #ifdef CONFIG_BAND_CBAND
2028 	{ 300000,  0 ,  3,  0x8105, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2029 	{ 380000,  0 ,  10, 0x810F, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2030 	{ 600000,  0 ,  10, 0x815E, 0x280, 0x2d12, 0xb84e, EN_CAB },
2031 	{ 660000,  0 ,  5,  0x85E3, 0x280, 0x2d12, 0xb84e, EN_CAB },
2032 	{ 720000,  0 ,  5,  0x852E, 0x280, 0x2d12, 0xb84e, EN_CAB },
2033 	{ 860000,  0 ,  4,  0x85E5, 0x280, 0x2d12, 0xb84e, EN_CAB },
2034 #endif
2035 };
2036 
2037 int dib0090_update_tuning_table_7090(struct dvb_frontend *fe,
2038 		u8 cfg_sensitivity)
2039 {
2040 	struct dib0090_state *state = fe->tuner_priv;
2041 	const struct dib0090_tuning *tune =
2042 		dib0090_tuning_table_cband_7090e_sensitivity;
2043 	static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_aci[] = {
2044 		{ 300000,  0 ,  3,  0x8165, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2045 		{ 650000,  0 ,  4,  0x815B, 0x280, 0x2d12, 0xb84e, EN_CAB },
2046 		{ 860000,  0 ,  5,  0x84EF, 0x280, 0x2d12, 0xb84e, EN_CAB },
2047 	};
2048 
2049 	if ((!state->identity.p1g) || (!state->identity.in_soc)
2050 			|| ((state->identity.version != SOC_7090_P1G_21R1)
2051 				&& (state->identity.version != SOC_7090_P1G_11R1))) {
2052 		dprintk("%s() function can only be used for dib7090\n", __func__);
2053 		return -ENODEV;
2054 	}
2055 
2056 	if (cfg_sensitivity)
2057 		tune = dib0090_tuning_table_cband_7090e_sensitivity;
2058 	else
2059 		tune = dib0090_tuning_table_cband_7090e_aci;
2060 
2061 	while (state->rf_request > tune->max_freq)
2062 		tune++;
2063 
2064 	dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x8000)
2065 			| (tune->lna_bias & 0x7fff));
2066 	dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xf83f)
2067 			| ((tune->lna_tune << 6) & 0x07c0));
2068 	return 0;
2069 }
2070 EXPORT_SYMBOL(dib0090_update_tuning_table_7090);
2071 
2072 static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state)
2073 {
2074 	int ret = 0;
2075 	u16 lo4 = 0xe900;
2076 
2077 	s16 adc_target;
2078 	u16 adc;
2079 	s8 step_sign;
2080 	u8 force_soft_search = 0;
2081 
2082 	if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
2083 		force_soft_search = 1;
2084 
2085 	if (*tune_state == CT_TUNER_START) {
2086 		dprintk("Start Captrim search : %s\n",
2087 			(force_soft_search == 1) ? "FORCE SOFT SEARCH" : "AUTO");
2088 		dib0090_write_reg(state, 0x10, 0x2B1);
2089 		dib0090_write_reg(state, 0x1e, 0x0032);
2090 
2091 		if (!state->tuner_is_tuned) {
2092 			/* prepare a complete captrim */
2093 			if (!state->identity.p1g || force_soft_search)
2094 				state->step = state->captrim = state->fcaptrim = 64;
2095 
2096 			state->current_rf = state->rf_request;
2097 		} else {	/* we are already tuned to this frequency - the configuration is correct  */
2098 			if (!state->identity.p1g || force_soft_search) {
2099 				/* do a minimal captrim even if the frequency has not changed */
2100 				state->step = 4;
2101 				state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f;
2102 			}
2103 		}
2104 		state->adc_diff = 3000;
2105 		*tune_state = CT_TUNER_STEP_0;
2106 
2107 	} else if (*tune_state == CT_TUNER_STEP_0) {
2108 		if (state->identity.p1g && !force_soft_search) {
2109 			u8 ratio = 31;
2110 
2111 			dib0090_write_reg(state, 0x40, (3 << 7) | (ratio << 2) | (1 << 1) | 1);
2112 			dib0090_read_reg(state, 0x40);
2113 			ret = 50;
2114 		} else {
2115 			state->step /= 2;
2116 			dib0090_write_reg(state, 0x18, lo4 | state->captrim);
2117 
2118 			if (state->identity.in_soc)
2119 				ret = 25;
2120 		}
2121 		*tune_state = CT_TUNER_STEP_1;
2122 
2123 	} else if (*tune_state == CT_TUNER_STEP_1) {
2124 		if (state->identity.p1g && !force_soft_search) {
2125 			dib0090_write_reg(state, 0x40, 0x18c | (0 << 1) | 0);
2126 			dib0090_read_reg(state, 0x40);
2127 
2128 			state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7F;
2129 			dprintk("***Final Captrim= 0x%x\n", state->fcaptrim);
2130 			*tune_state = CT_TUNER_STEP_3;
2131 
2132 		} else {
2133 			/* MERGE for all krosus before P1G */
2134 			adc = dib0090_get_slow_adc_val(state);
2135 			dprintk("CAPTRIM=%d; ADC = %d (ADC) & %dmV\n", (u32) state->captrim, (u32) adc, (u32) (adc) * (u32) 1800 / (u32) 1024);
2136 
2137 			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 !!! */
2138 				adc_target = 200;
2139 			} else
2140 				adc_target = 400;
2141 
2142 			if (adc >= adc_target) {
2143 				adc -= adc_target;
2144 				step_sign = -1;
2145 			} else {
2146 				adc = adc_target - adc;
2147 				step_sign = 1;
2148 			}
2149 
2150 			if (adc < state->adc_diff) {
2151 				dprintk("CAPTRIM=%d is closer to target (%d/%d)\n", (u32) state->captrim, (u32) adc, (u32) state->adc_diff);
2152 				state->adc_diff = adc;
2153 				state->fcaptrim = state->captrim;
2154 			}
2155 
2156 			state->captrim += step_sign * state->step;
2157 			if (state->step >= 1)
2158 				*tune_state = CT_TUNER_STEP_0;
2159 			else
2160 				*tune_state = CT_TUNER_STEP_2;
2161 
2162 			ret = 25;
2163 		}
2164 	} else if (*tune_state == CT_TUNER_STEP_2) {	/* this step is only used by krosus < P1G */
2165 		/*write the final cptrim config */
2166 		dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim);
2167 
2168 		*tune_state = CT_TUNER_STEP_3;
2169 
2170 	} else if (*tune_state == CT_TUNER_STEP_3) {
2171 		state->calibrate &= ~CAPTRIM_CAL;
2172 		*tune_state = CT_TUNER_STEP_0;
2173 	}
2174 
2175 	return ret;
2176 }
2177 
2178 static int dib0090_get_temperature(struct dib0090_state *state, enum frontend_tune_state *tune_state)
2179 {
2180 	int ret = 15;
2181 	s16 val;
2182 
2183 	switch (*tune_state) {
2184 	case CT_TUNER_START:
2185 		state->wbdmux = dib0090_read_reg(state, 0x10);
2186 		dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x8 << 3));
2187 
2188 		state->bias = dib0090_read_reg(state, 0x13);
2189 		dib0090_write_reg(state, 0x13, state->bias | (0x3 << 8));
2190 
2191 		*tune_state = CT_TUNER_STEP_0;
2192 		/* wait for the WBDMUX to switch and for the ADC to sample */
2193 		break;
2194 
2195 	case CT_TUNER_STEP_0:
2196 		state->adc_diff = dib0090_get_slow_adc_val(state);
2197 		dib0090_write_reg(state, 0x13, (state->bias & ~(0x3 << 8)) | (0x2 << 8));
2198 		*tune_state = CT_TUNER_STEP_1;
2199 		break;
2200 
2201 	case CT_TUNER_STEP_1:
2202 		val = dib0090_get_slow_adc_val(state);
2203 		state->temperature = ((s16) ((val - state->adc_diff) * 180) >> 8) + 55;
2204 
2205 		dprintk("temperature: %d C\n", state->temperature - 30);
2206 
2207 		*tune_state = CT_TUNER_STEP_2;
2208 		break;
2209 
2210 	case CT_TUNER_STEP_2:
2211 		dib0090_write_reg(state, 0x13, state->bias);
2212 		dib0090_write_reg(state, 0x10, state->wbdmux);	/* write back original WBDMUX */
2213 
2214 		*tune_state = CT_TUNER_START;
2215 		state->calibrate &= ~TEMP_CAL;
2216 		if (state->config->analog_output == 0)
2217 			dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2218 
2219 		break;
2220 
2221 	default:
2222 		ret = 0;
2223 		break;
2224 	}
2225 	return ret;
2226 }
2227 
2228 #define WBD     0x781		/* 1 1 1 1 0000 0 0 1 */
2229 static int dib0090_tune(struct dvb_frontend *fe)
2230 {
2231 	struct dib0090_state *state = fe->tuner_priv;
2232 	const struct dib0090_tuning *tune = state->current_tune_table_index;
2233 	const struct dib0090_pll *pll = state->current_pll_table_index;
2234 	enum frontend_tune_state *tune_state = &state->tune_state;
2235 
2236 	u16 lo5, lo6, Den, tmp;
2237 	u32 FBDiv, Rest, FREF, VCOF_kHz = 0;
2238 	int ret = 10;		/* 1ms is the default delay most of the time */
2239 	u8 c, i;
2240 
2241 	/************************* VCO ***************************/
2242 	/* Default values for FG                                 */
2243 	/* from these are needed :                               */
2244 	/* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv             */
2245 
2246 	/* in any case we first need to do a calibration if needed */
2247 	if (*tune_state == CT_TUNER_START) {
2248 		/* deactivate DataTX before some calibrations */
2249 		if (state->calibrate & (DC_CAL | TEMP_CAL | WBD_CAL))
2250 			dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
2251 		else
2252 			/* Activate DataTX in case a calibration has been done before */
2253 			if (state->config->analog_output == 0)
2254 				dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2255 	}
2256 
2257 	if (state->calibrate & DC_CAL)
2258 		return dib0090_dc_offset_calibration(state, tune_state);
2259 	else if (state->calibrate & WBD_CAL) {
2260 		if (state->current_rf == 0)
2261 			state->current_rf = state->fe->dtv_property_cache.frequency / 1000;
2262 		return dib0090_wbd_calibration(state, tune_state);
2263 	} else if (state->calibrate & TEMP_CAL)
2264 		return dib0090_get_temperature(state, tune_state);
2265 	else if (state->calibrate & CAPTRIM_CAL)
2266 		return dib0090_captrim_search(state, tune_state);
2267 
2268 	if (*tune_state == CT_TUNER_START) {
2269 		/* 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 */
2270 		if (state->config->use_pwm_agc && state->identity.in_soc) {
2271 			tmp = dib0090_read_reg(state, 0x39);
2272 			if ((tmp >> 10) & 0x1)
2273 				dib0090_write_reg(state, 0x39, tmp & ~(1 << 10));
2274 		}
2275 
2276 		state->current_band = (u8) BAND_OF_FREQUENCY(state->fe->dtv_property_cache.frequency / 1000);
2277 		state->rf_request =
2278 			state->fe->dtv_property_cache.frequency / 1000 + (state->current_band ==
2279 					BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->
2280 					freq_offset_khz_vhf);
2281 
2282 		/* in ISDB-T 1seg we shift tuning frequency */
2283 		if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1
2284 					&& state->fe->dtv_property_cache.isdbt_partial_reception == 0)) {
2285 			const struct dib0090_low_if_offset_table *LUT_offset = state->config->low_if;
2286 			u8 found_offset = 0;
2287 			u32 margin_khz = 100;
2288 
2289 			if (LUT_offset != NULL) {
2290 				while (LUT_offset->RF_freq != 0xffff) {
2291 					if (((state->rf_request > (LUT_offset->RF_freq - margin_khz))
2292 								&& (state->rf_request < (LUT_offset->RF_freq + margin_khz)))
2293 							&& LUT_offset->std == state->fe->dtv_property_cache.delivery_system) {
2294 						state->rf_request += LUT_offset->offset_khz;
2295 						found_offset = 1;
2296 						break;
2297 					}
2298 					LUT_offset++;
2299 				}
2300 			}
2301 
2302 			if (found_offset == 0)
2303 				state->rf_request += 400;
2304 		}
2305 		if (state->current_rf != state->rf_request || (state->current_standard != state->fe->dtv_property_cache.delivery_system)) {
2306 			state->tuner_is_tuned = 0;
2307 			state->current_rf = 0;
2308 			state->current_standard = 0;
2309 
2310 			tune = dib0090_tuning_table;
2311 			if (state->identity.p1g)
2312 				tune = dib0090_p1g_tuning_table;
2313 
2314 			tmp = (state->identity.version >> 5) & 0x7;
2315 
2316 			if (state->identity.in_soc) {
2317 				if (state->config->force_cband_input) {	/* Use the CBAND input for all band */
2318 					if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF
2319 							|| state->current_band & BAND_UHF) {
2320 						state->current_band = BAND_CBAND;
2321 						if (state->config->is_dib7090e)
2322 							tune = dib0090_tuning_table_cband_7090e_sensitivity;
2323 						else
2324 							tune = dib0090_tuning_table_cband_7090;
2325 					}
2326 				} else {	/* Use the CBAND input for all band under UHF */
2327 					if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) {
2328 						state->current_band = BAND_CBAND;
2329 						if (state->config->is_dib7090e)
2330 							tune = dib0090_tuning_table_cband_7090e_sensitivity;
2331 						else
2332 							tune = dib0090_tuning_table_cband_7090;
2333 					}
2334 				}
2335 			} else
2336 			 if (tmp == 0x4 || tmp == 0x7) {
2337 				/* CBAND tuner version for VHF */
2338 				if (state->current_band == BAND_FM || state->current_band == BAND_CBAND || state->current_band == BAND_VHF) {
2339 					state->current_band = BAND_CBAND;	/* Force CBAND */
2340 
2341 					tune = dib0090_tuning_table_fm_vhf_on_cband;
2342 					if (state->identity.p1g)
2343 						tune = dib0090_p1g_tuning_table_fm_vhf_on_cband;
2344 				}
2345 			}
2346 
2347 			pll = dib0090_pll_table;
2348 			if (state->identity.p1g)
2349 				pll = dib0090_p1g_pll_table;
2350 
2351 			/* Look for the interval */
2352 			while (state->rf_request > tune->max_freq)
2353 				tune++;
2354 			while (state->rf_request > pll->max_freq)
2355 				pll++;
2356 
2357 			state->current_tune_table_index = tune;
2358 			state->current_pll_table_index = pll;
2359 
2360 			dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim));
2361 
2362 			VCOF_kHz = (pll->hfdiv * state->rf_request) * 2;
2363 
2364 			FREF = state->config->io.clock_khz;
2365 			if (state->config->fref_clock_ratio != 0)
2366 				FREF /= state->config->fref_clock_ratio;
2367 
2368 			FBDiv = (VCOF_kHz / pll->topresc / FREF);
2369 			Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF;
2370 
2371 			if (Rest < LPF)
2372 				Rest = 0;
2373 			else if (Rest < 2 * LPF)
2374 				Rest = 2 * LPF;
2375 			else if (Rest > (FREF - LPF)) {
2376 				Rest = 0;
2377 				FBDiv += 1;
2378 			} else if (Rest > (FREF - 2 * LPF))
2379 				Rest = FREF - 2 * LPF;
2380 			Rest = (Rest * 6528) / (FREF / 10);
2381 			state->rest = Rest;
2382 
2383 			/* external loop filter, otherwise:
2384 			 * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4;
2385 			 * lo6 = 0x0e34 */
2386 
2387 			if (Rest == 0) {
2388 				if (pll->vco_band)
2389 					lo5 = 0x049f;
2390 				else
2391 					lo5 = 0x041f;
2392 			} else {
2393 				if (pll->vco_band)
2394 					lo5 = 0x049e;
2395 				else if (state->config->analog_output)
2396 					lo5 = 0x041d;
2397 				else
2398 					lo5 = 0x041c;
2399 			}
2400 
2401 			if (state->identity.p1g) {	/* Bias is done automatically in P1G */
2402 				if (state->identity.in_soc) {
2403 					if (state->identity.version == SOC_8090_P1G_11R1)
2404 						lo5 = 0x46f;
2405 					else
2406 						lo5 = 0x42f;
2407 				} else
2408 					lo5 = 0x42c;
2409 			}
2410 
2411 			lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7);	/* bit 15 is the split to the slave, we do not do it here */
2412 
2413 			if (!state->config->io.pll_int_loop_filt) {
2414 				if (state->identity.in_soc)
2415 					lo6 = 0xff98;
2416 				else if (state->identity.p1g || (Rest == 0))
2417 					lo6 = 0xfff8;
2418 				else
2419 					lo6 = 0xff28;
2420 			} else
2421 				lo6 = (state->config->io.pll_int_loop_filt << 3);
2422 
2423 			Den = 1;
2424 
2425 			if (Rest > 0) {
2426 				lo6 |= (1 << 2) | 2;
2427 				Den = 255;
2428 			}
2429 			dib0090_write_reg(state, 0x15, (u16) FBDiv);
2430 			if (state->config->fref_clock_ratio != 0)
2431 				dib0090_write_reg(state, 0x16, (Den << 8) | state->config->fref_clock_ratio);
2432 			else
2433 				dib0090_write_reg(state, 0x16, (Den << 8) | 1);
2434 			dib0090_write_reg(state, 0x17, (u16) Rest);
2435 			dib0090_write_reg(state, 0x19, lo5);
2436 			dib0090_write_reg(state, 0x1c, lo6);
2437 
2438 			lo6 = tune->tuner_enable;
2439 			if (state->config->analog_output)
2440 				lo6 = (lo6 & 0xff9f) | 0x2;
2441 
2442 			dib0090_write_reg(state, 0x24, lo6 | EN_LO | state->config->use_pwm_agc * EN_CRYSTAL);
2443 
2444 		}
2445 
2446 		state->current_rf = state->rf_request;
2447 		state->current_standard = state->fe->dtv_property_cache.delivery_system;
2448 
2449 		ret = 20;
2450 		state->calibrate = CAPTRIM_CAL;	/* captrim search now */
2451 	}
2452 
2453 	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 */
2454 		const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
2455 
2456 		while (state->current_rf / 1000 > wbd->max_freq)
2457 			wbd++;
2458 
2459 		dib0090_write_reg(state, 0x1e, 0x07ff);
2460 		dprintk("Final Captrim: %d\n", (u32) state->fcaptrim);
2461 		dprintk("HFDIV code: %d\n", (u32) pll->hfdiv_code);
2462 		dprintk("VCO = %d\n", (u32) pll->vco_band);
2463 		dprintk("VCOF in kHz: %d ((%d*%d) << 1))\n", (u32) ((pll->hfdiv * state->rf_request) * 2), (u32) pll->hfdiv, (u32) state->rf_request);
2464 		dprintk("REFDIV: %d, FREF: %d\n", (u32) 1, (u32) state->config->io.clock_khz);
2465 		dprintk("FBDIV: %d, Rest: %d\n", (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17));
2466 		dprintk("Num: %d, Den: %d, SD: %d\n", (u32) dib0090_read_reg(state, 0x17), (u32) (dib0090_read_reg(state, 0x16) >> 8),
2467 			(u32) dib0090_read_reg(state, 0x1c) & 0x3);
2468 
2469 #define WBD     0x781		/* 1 1 1 1 0000 0 0 1 */
2470 		c = 4;
2471 		i = 3;
2472 
2473 		if (wbd->wbd_gain != 0)
2474 			c = wbd->wbd_gain;
2475 
2476 		state->wbdmux = (c << 13) | (i << 11) | (WBD | (state->config->use_pwm_agc << 1));
2477 		dib0090_write_reg(state, 0x10, state->wbdmux);
2478 
2479 		if ((tune->tuner_enable == EN_CAB) && state->identity.p1g) {
2480 			dprintk("P1G : The cable band is selected and lna_tune = %d\n", tune->lna_tune);
2481 			dib0090_write_reg(state, 0x09, tune->lna_bias);
2482 			dib0090_write_reg(state, 0x0b, 0xb800 | (tune->lna_tune << 6) | (tune->switch_trim));
2483 		} else
2484 			dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | tune->lna_bias);
2485 
2486 		dib0090_write_reg(state, 0x0c, tune->v2i);
2487 		dib0090_write_reg(state, 0x0d, tune->mix);
2488 		dib0090_write_reg(state, 0x0e, tune->load);
2489 		*tune_state = CT_TUNER_STEP_1;
2490 
2491 	} else if (*tune_state == CT_TUNER_STEP_1) {
2492 		/* initialize the lt gain register */
2493 		state->rf_lt_def = 0x7c00;
2494 
2495 		dib0090_set_bandwidth(state);
2496 		state->tuner_is_tuned = 1;
2497 
2498 		state->calibrate |= WBD_CAL;
2499 		state->calibrate |= TEMP_CAL;
2500 		*tune_state = CT_TUNER_STOP;
2501 	} else
2502 		ret = FE_CALLBACK_TIME_NEVER;
2503 	return ret;
2504 }
2505 
2506 static void dib0090_release(struct dvb_frontend *fe)
2507 {
2508 	kfree(fe->tuner_priv);
2509 	fe->tuner_priv = NULL;
2510 }
2511 
2512 enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
2513 {
2514 	struct dib0090_state *state = fe->tuner_priv;
2515 
2516 	return state->tune_state;
2517 }
2518 
2519 EXPORT_SYMBOL(dib0090_get_tune_state);
2520 
2521 int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
2522 {
2523 	struct dib0090_state *state = fe->tuner_priv;
2524 
2525 	state->tune_state = tune_state;
2526 	return 0;
2527 }
2528 
2529 EXPORT_SYMBOL(dib0090_set_tune_state);
2530 
2531 static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency)
2532 {
2533 	struct dib0090_state *state = fe->tuner_priv;
2534 
2535 	*frequency = 1000 * state->current_rf;
2536 	return 0;
2537 }
2538 
2539 static int dib0090_set_params(struct dvb_frontend *fe)
2540 {
2541 	struct dib0090_state *state = fe->tuner_priv;
2542 	u32 ret;
2543 
2544 	state->tune_state = CT_TUNER_START;
2545 
2546 	do {
2547 		ret = dib0090_tune(fe);
2548 		if (ret == FE_CALLBACK_TIME_NEVER)
2549 			break;
2550 
2551 		/*
2552 		 * Despite dib0090_tune returns time at a 0.1 ms range,
2553 		 * the actual sleep time depends on CONFIG_HZ. The worse case
2554 		 * is when CONFIG_HZ=100. In such case, the minimum granularity
2555 		 * is 10ms. On some real field tests, the tuner sometimes don't
2556 		 * lock when this timer is lower than 10ms. So, enforce a 10ms
2557 		 * granularity and use usleep_range() instead of msleep().
2558 		 */
2559 		ret = 10 * (ret + 99)/100;
2560 		usleep_range(ret * 1000, (ret + 1) * 1000);
2561 	} while (state->tune_state != CT_TUNER_STOP);
2562 
2563 	return 0;
2564 }
2565 
2566 static const struct dvb_tuner_ops dib0090_ops = {
2567 	.info = {
2568 		 .name = "DiBcom DiB0090",
2569 		 .frequency_min_hz  =  45 * MHz,
2570 		 .frequency_max_hz  = 860 * MHz,
2571 		 .frequency_step_hz =   1 * kHz,
2572 		 },
2573 	.release = dib0090_release,
2574 
2575 	.init = dib0090_wakeup,
2576 	.sleep = dib0090_sleep,
2577 	.set_params = dib0090_set_params,
2578 	.get_frequency = dib0090_get_frequency,
2579 };
2580 
2581 static const struct dvb_tuner_ops dib0090_fw_ops = {
2582 	.info = {
2583 		 .name = "DiBcom DiB0090",
2584 		 .frequency_min_hz  =  45 * MHz,
2585 		 .frequency_max_hz  = 860 * MHz,
2586 		 .frequency_step_hz =   1 * kHz,
2587 		 },
2588 	.release = dib0090_release,
2589 
2590 	.init = NULL,
2591 	.sleep = NULL,
2592 	.set_params = NULL,
2593 	.get_frequency = NULL,
2594 };
2595 
2596 static const struct dib0090_wbd_slope dib0090_wbd_table_default[] = {
2597 	{470, 0, 250, 0, 100, 4},
2598 	{860, 51, 866, 21, 375, 4},
2599 	{1700, 0, 800, 0, 850, 4},
2600 	{2900, 0, 250, 0, 100, 6},
2601 	{0xFFFF, 0, 0, 0, 0, 0},
2602 };
2603 
2604 struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
2605 {
2606 	struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL);
2607 	if (st == NULL)
2608 		return NULL;
2609 
2610 	st->config = config;
2611 	st->i2c = i2c;
2612 	st->fe = fe;
2613 	mutex_init(&st->i2c_buffer_lock);
2614 	fe->tuner_priv = st;
2615 
2616 	if (config->wbd == NULL)
2617 		st->current_wbd_table = dib0090_wbd_table_default;
2618 	else
2619 		st->current_wbd_table = config->wbd;
2620 
2621 	if (dib0090_reset(fe) != 0)
2622 		goto free_mem;
2623 
2624 	pr_info("DiB0090: successfully identified\n");
2625 	memcpy(&fe->ops.tuner_ops, &dib0090_ops, sizeof(struct dvb_tuner_ops));
2626 
2627 	return fe;
2628  free_mem:
2629 	kfree(st);
2630 	fe->tuner_priv = NULL;
2631 	return NULL;
2632 }
2633 
2634 EXPORT_SYMBOL(dib0090_register);
2635 
2636 struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
2637 {
2638 	struct dib0090_fw_state *st = kzalloc(sizeof(struct dib0090_fw_state), GFP_KERNEL);
2639 	if (st == NULL)
2640 		return NULL;
2641 
2642 	st->config = config;
2643 	st->i2c = i2c;
2644 	st->fe = fe;
2645 	mutex_init(&st->i2c_buffer_lock);
2646 	fe->tuner_priv = st;
2647 
2648 	if (dib0090_fw_reset_digital(fe, st->config) != 0)
2649 		goto free_mem;
2650 
2651 	dprintk("DiB0090 FW: successfully identified\n");
2652 	memcpy(&fe->ops.tuner_ops, &dib0090_fw_ops, sizeof(struct dvb_tuner_ops));
2653 
2654 	return fe;
2655 free_mem:
2656 	kfree(st);
2657 	fe->tuner_priv = NULL;
2658 	return NULL;
2659 }
2660 EXPORT_SYMBOL(dib0090_fw_register);
2661 
2662 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
2663 MODULE_AUTHOR("Olivier Grenie <olivier.grenie@parrot.com>");
2664 MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner");
2665 MODULE_LICENSE("GPL");
2666