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