PageRenderTime 72ms CodeModel.GetById 5ms app.highlight 50ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/media/dvb/frontends/dib0090.c

https://bitbucket.org/wisechild/galaxy-nexus
C | 2539 lines | 2037 code | 399 blank | 103 comment | 444 complexity | 173aea7f46a970b97863768ab1ba62ea MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0

Large files files are truncated, but you can click here to view the full file

   1/*
   2 * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner.
   3 *
   4 * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/)
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License as
   8 * published by the Free Software Foundation; either version 2 of the
   9 * License, or (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful, but
  12 * WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 *
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20 *
  21 *
  22 * This code is more or less generated from another driver, please
  23 * excuse some codingstyle oddities.
  24 *
  25 */
  26
  27#include <linux/kernel.h>
  28#include <linux/slab.h>
  29#include <linux/i2c.h>
  30#include <linux/mutex.h>
  31
  32#include "dvb_frontend.h"
  33
  34#include "dib0090.h"
  35#include "dibx000_common.h"
  36
  37static int debug;
  38module_param(debug, int, 0644);
  39MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
  40
  41#define dprintk(args...) do { \
  42	if (debug) { \
  43		printk(KERN_DEBUG "DiB0090: "); \
  44		printk(args); \
  45		printk("\n"); \
  46	} \
  47} while (0)
  48
  49#define CONFIG_SYS_DVBT
  50#define CONFIG_SYS_ISDBT
  51#define CONFIG_BAND_CBAND
  52#define CONFIG_BAND_VHF
  53#define CONFIG_BAND_UHF
  54#define CONFIG_DIB0090_USE_PWM_AGC
  55
  56#define EN_LNA0      0x8000
  57#define EN_LNA1      0x4000
  58#define EN_LNA2      0x2000
  59#define EN_LNA3      0x1000
  60#define EN_MIX0      0x0800
  61#define EN_MIX1      0x0400
  62#define EN_MIX2      0x0200
  63#define EN_MIX3      0x0100
  64#define EN_IQADC     0x0040
  65#define EN_PLL       0x0020
  66#define EN_TX        0x0010
  67#define EN_BB        0x0008
  68#define EN_LO        0x0004
  69#define EN_BIAS      0x0001
  70
  71#define EN_IQANA     0x0002
  72#define EN_DIGCLK    0x0080	/* not in the 0x24 reg, only in 0x1b */
  73#define EN_CRYSTAL   0x0002
  74
  75#define EN_UHF		 0x22E9
  76#define EN_VHF		 0x44E9
  77#define EN_LBD		 0x11E9
  78#define EN_SBD		 0x44E9
  79#define EN_CAB		 0x88E9
  80
  81/* Calibration defines */
  82#define      DC_CAL 0x1
  83#define     WBD_CAL 0x2
  84#define    TEMP_CAL 0x4
  85#define CAPTRIM_CAL 0x8
  86
  87#define KROSUS_PLL_LOCKED   0x800
  88#define KROSUS              0x2
  89
  90/* Use those defines to identify SOC version */
  91#define SOC               0x02
  92#define SOC_7090_P1G_11R1 0x82
  93#define SOC_7090_P1G_21R1 0x8a
  94#define SOC_8090_P1G_11R1 0x86
  95#define SOC_8090_P1G_21R1 0x8e
  96
  97/* else use thos ones to check */
  98#define P1A_B      0x0
  99#define P1C	   0x1
 100#define P1D_E_F    0x3
 101#define P1G	   0x7
 102#define P1G_21R2   0xf
 103
 104#define MP001 0x1		/* Single 9090/8096 */
 105#define MP005 0x4		/* Single Sband */
 106#define MP008 0x6		/* Dual diversity VHF-UHF-LBAND */
 107#define MP009 0x7		/* Dual diversity 29098 CBAND-UHF-LBAND-SBAND */
 108
 109#define pgm_read_word(w) (*w)
 110
 111struct dc_calibration;
 112
 113struct 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
 124struct 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
 132struct dib0090_identity {
 133	u8 version;
 134	u8 product;
 135	u8 p1g;
 136	u8 in_soc;
 137};
 138
 139struct 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
 203struct 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
 216static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
 217{
 218	u16 ret;
 219
 220	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
 221		dprintk("could not acquire lock");
 222		return 0;
 223	}
 224
 225	state->i2c_write_buffer[0] = reg;
 226
 227	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
 228	state->msg[0].addr = state->config->i2c_address;
 229	state->msg[0].flags = 0;
 230	state->msg[0].buf = state->i2c_write_buffer;
 231	state->msg[0].len = 1;
 232	state->msg[1].addr = state->config->i2c_address;
 233	state->msg[1].flags = I2C_M_RD;
 234	state->msg[1].buf = state->i2c_read_buffer;
 235	state->msg[1].len = 2;
 236
 237	if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
 238		printk(KERN_WARNING "DiB0090 I2C read failed\n");
 239		ret = 0;
 240	} else
 241		ret = (state->i2c_read_buffer[0] << 8)
 242			| state->i2c_read_buffer[1];
 243
 244	mutex_unlock(&state->i2c_buffer_lock);
 245	return ret;
 246}
 247
 248static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
 249{
 250	int ret;
 251
 252	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
 253		dprintk("could not acquire lock");
 254		return -EINVAL;
 255	}
 256
 257	state->i2c_write_buffer[0] = reg & 0xff;
 258	state->i2c_write_buffer[1] = val >> 8;
 259	state->i2c_write_buffer[2] = val & 0xff;
 260
 261	memset(state->msg, 0, sizeof(struct i2c_msg));
 262	state->msg[0].addr = state->config->i2c_address;
 263	state->msg[0].flags = 0;
 264	state->msg[0].buf = state->i2c_write_buffer;
 265	state->msg[0].len = 3;
 266
 267	if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
 268		printk(KERN_WARNING "DiB0090 I2C write failed\n");
 269		ret = -EREMOTEIO;
 270	} else
 271		ret = 0;
 272
 273	mutex_unlock(&state->i2c_buffer_lock);
 274	return ret;
 275}
 276
 277static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg)
 278{
 279	u16 ret;
 280
 281	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
 282		dprintk("could not acquire lock");
 283		return 0;
 284	}
 285
 286	state->i2c_write_buffer[0] = reg;
 287
 288	memset(&state->msg, 0, sizeof(struct i2c_msg));
 289	state->msg.addr = reg;
 290	state->msg.flags = I2C_M_RD;
 291	state->msg.buf = state->i2c_read_buffer;
 292	state->msg.len = 2;
 293	if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
 294		printk(KERN_WARNING "DiB0090 I2C read failed\n");
 295		ret = 0;
 296	} else
 297		ret = (state->i2c_read_buffer[0] << 8)
 298			| state->i2c_read_buffer[1];
 299
 300	mutex_unlock(&state->i2c_buffer_lock);
 301	return ret;
 302}
 303
 304static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val)
 305{
 306	int ret;
 307
 308	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
 309		dprintk("could not acquire lock");
 310		return -EINVAL;
 311	}
 312
 313	state->i2c_write_buffer[0] = val >> 8;
 314	state->i2c_write_buffer[1] = val & 0xff;
 315
 316	memset(&state->msg, 0, sizeof(struct i2c_msg));
 317	state->msg.addr = reg;
 318	state->msg.flags = 0;
 319	state->msg.buf = state->i2c_write_buffer;
 320	state->msg.len = 2;
 321	if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
 322		printk(KERN_WARNING "DiB0090 I2C write failed\n");
 323		ret = -EREMOTEIO;
 324	} else
 325		ret = 0;
 326
 327	mutex_unlock(&state->i2c_buffer_lock);
 328	return ret;
 329}
 330
 331#define HARD_RESET(state) do {  if (cfg->reset) {  if (cfg->sleep) cfg->sleep(fe, 0); msleep(10);  cfg->reset(fe, 1); msleep(10);  cfg->reset(fe, 0); msleep(10);  }  } while (0)
 332#define ADC_TARGET -220
 333#define GAIN_ALPHA 5
 334#define WBD_ALPHA 6
 335#define LPF	100
 336static 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
 343static int dib0090_identify(struct dvb_frontend *fe)
 344{
 345	struct dib0090_state *state = fe->tuner_priv;
 346	u16 v;
 347	struct dib0090_identity *identity = &state->identity;
 348
 349	v = dib0090_read_reg(state, 0x1a);
 350
 351	identity->p1g = 0;
 352	identity->in_soc = 0;
 353
 354	dprintk("Tuner identification (Version = 0x%04x)", v);
 355
 356	/* without PLL lock info */
 357	v &= ~KROSUS_PLL_LOCKED;
 358
 359	identity->version = v & 0xff;
 360	identity->product = (v >> 8) & 0xf;
 361
 362	if (identity->product != KROSUS)
 363		goto identification_error;
 364
 365	if ((identity->version & 0x3) == SOC) {
 366		identity->in_soc = 1;
 367		switch (identity->version) {
 368		case SOC_8090_P1G_11R1:
 369			dprintk("SOC 8090 P1-G11R1 Has been detected");
 370			identity->p1g = 1;
 371			break;
 372		case SOC_8090_P1G_21R1:
 373			dprintk("SOC 8090 P1-G21R1 Has been detected");
 374			identity->p1g = 1;
 375			break;
 376		case SOC_7090_P1G_11R1:
 377			dprintk("SOC 7090 P1-G11R1 Has been detected");
 378			identity->p1g = 1;
 379			break;
 380		case SOC_7090_P1G_21R1:
 381			dprintk("SOC 7090 P1-G21R1 Has been detected");
 382			identity->p1g = 1;
 383			break;
 384		default:
 385			goto identification_error;
 386		}
 387	} else {
 388		switch ((identity->version >> 5) & 0x7) {
 389		case MP001:
 390			dprintk("MP001 : 9090/8096");
 391			break;
 392		case MP005:
 393			dprintk("MP005 : Single Sband");
 394			break;
 395		case MP008:
 396			dprintk("MP008 : diversity VHF-UHF-LBAND");
 397			break;
 398		case MP009:
 399			dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND");
 400			break;
 401		default:
 402			goto identification_error;
 403		}
 404
 405		switch (identity->version & 0x1f) {
 406		case P1G_21R2:
 407			dprintk("P1G_21R2 detected");
 408			identity->p1g = 1;
 409			break;
 410		case P1G:
 411			dprintk("P1G detected");
 412			identity->p1g = 1;
 413			break;
 414		case P1D_E_F:
 415			dprintk("P1D/E/F detected");
 416			break;
 417		case P1C:
 418			dprintk("P1C detected");
 419			break;
 420		case P1A_B:
 421			dprintk("P1-A/B detected: driver is deactivated - not available");
 422			goto identification_error;
 423			break;
 424		default:
 425			goto identification_error;
 426		}
 427	}
 428
 429	return 0;
 430
 431identification_error:
 432	return -EIO;
 433}
 434
 435static int dib0090_fw_identify(struct dvb_frontend *fe)
 436{
 437	struct dib0090_fw_state *state = fe->tuner_priv;
 438	struct dib0090_identity *identity = &state->identity;
 439
 440	u16 v = dib0090_fw_read_reg(state, 0x1a);
 441	identity->p1g = 0;
 442	identity->in_soc = 0;
 443
 444	dprintk("FE: Tuner identification (Version = 0x%04x)", v);
 445
 446	/* without PLL lock info */
 447	v &= ~KROSUS_PLL_LOCKED;
 448
 449	identity->version = v & 0xff;
 450	identity->product = (v >> 8) & 0xf;
 451
 452	if (identity->product != KROSUS)
 453		goto identification_error;
 454
 455	if ((identity->version & 0x3) == SOC) {
 456		identity->in_soc = 1;
 457		switch (identity->version) {
 458		case SOC_8090_P1G_11R1:
 459			dprintk("SOC 8090 P1-G11R1 Has been detected");
 460			identity->p1g = 1;
 461			break;
 462		case SOC_8090_P1G_21R1:
 463			dprintk("SOC 8090 P1-G21R1 Has been detected");
 464			identity->p1g = 1;
 465			break;
 466		case SOC_7090_P1G_11R1:
 467			dprintk("SOC 7090 P1-G11R1 Has been detected");
 468			identity->p1g = 1;
 469			break;
 470		case SOC_7090_P1G_21R1:
 471			dprintk("SOC 7090 P1-G21R1 Has been detected");
 472			identity->p1g = 1;
 473			break;
 474		default:
 475			goto identification_error;
 476		}
 477	} else {
 478		switch ((identity->version >> 5) & 0x7) {
 479		case MP001:
 480			dprintk("MP001 : 9090/8096");
 481			break;
 482		case MP005:
 483			dprintk("MP005 : Single Sband");
 484			break;
 485		case MP008:
 486			dprintk("MP008 : diversity VHF-UHF-LBAND");
 487			break;
 488		case MP009:
 489			dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND");
 490			break;
 491		default:
 492			goto identification_error;
 493		}
 494
 495		switch (identity->version & 0x1f) {
 496		case P1G_21R2:
 497			dprintk("P1G_21R2 detected");
 498			identity->p1g = 1;
 499			break;
 500		case P1G:
 501			dprintk("P1G detected");
 502			identity->p1g = 1;
 503			break;
 504		case P1D_E_F:
 505			dprintk("P1D/E/F detected");
 506			break;
 507		case P1C:
 508			dprintk("P1C detected");
 509			break;
 510		case P1A_B:
 511			dprintk("P1-A/B detected: driver is deactivated - not available");
 512			goto identification_error;
 513			break;
 514		default:
 515			goto identification_error;
 516		}
 517	}
 518
 519	return 0;
 520
 521identification_error:
 522	return -EIO;;
 523}
 524
 525static 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
 532	dib0090_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
 533	dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL);	/* PLL, DIG_CLK and CRYSTAL remain */
 534
 535	if (!cfg->in_soc) {
 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
 546	/* Read Pll current config * */
 547	PllCfg = dib0090_read_reg(state, 0x21);
 548
 549	/** Reconfigure PLL if current setting is different from default setting **/
 550	if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && (!cfg->in_soc)
 551			&& !cfg->io.pll_bypass) {
 552
 553		/* Set Bypass mode */
 554		PllCfg |= (1 << 15);
 555		dib0090_write_reg(state, 0x21, PllCfg);
 556
 557		/* Set Reset Pll */
 558		PllCfg &= ~(1 << 13);
 559		dib0090_write_reg(state, 0x21, PllCfg);
 560
 561	/*** Set new Pll configuration in bypass and reset state ***/
 562		PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
 563		dib0090_write_reg(state, 0x21, PllCfg);
 564
 565		/* Remove Reset Pll */
 566		PllCfg |= (1 << 13);
 567		dib0090_write_reg(state, 0x21, PllCfg);
 568
 569	/*** Wait for PLL lock ***/
 570		i = 100;
 571		do {
 572			v = !!(dib0090_read_reg(state, 0x1a) & 0x800);
 573			if (v)
 574				break;
 575		} while (--i);
 576
 577		if (i == 0) {
 578			dprintk("Pll: Unable to lock Pll");
 579			return;
 580		}
 581
 582		/* Finally Remove Bypass mode */
 583		PllCfg &= ~(1 << 15);
 584		dib0090_write_reg(state, 0x21, PllCfg);
 585	}
 586
 587	if (cfg->io.pll_bypass) {
 588		PllCfg |= (cfg->io.pll_bypass << 15);
 589		dib0090_write_reg(state, 0x21, PllCfg);
 590	}
 591}
 592
 593static int dib0090_fw_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
 594{
 595	struct dib0090_fw_state *state = fe->tuner_priv;
 596	u16 PllCfg;
 597	u16 v;
 598	int i;
 599
 600	dprintk("fw reset digital");
 601	HARD_RESET(state);
 602
 603	dib0090_fw_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
 604	dib0090_fw_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL);	/* PLL, DIG_CLK and CRYSTAL remain */
 605
 606	dib0090_fw_write_reg(state, 0x20,
 607			((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (cfg->data_tx_drv << 4) | cfg->ls_cfg_pad_drv);
 608
 609	v = (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 9) | (0 << 8) | (cfg->clkouttobamse << 4) | (0 << 2) | (0);
 610	if (cfg->clkoutdrive != 0)
 611		v |= cfg->clkoutdrive << 5;
 612	else
 613		v |= 7 << 5;
 614
 615	v |= 2 << 10;
 616	dib0090_fw_write_reg(state, 0x23, v);
 617
 618	/* Read Pll current config * */
 619	PllCfg = dib0090_fw_read_reg(state, 0x21);
 620
 621	/** Reconfigure PLL if current setting is different from default setting **/
 622	if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && !cfg->io.pll_bypass) {
 623
 624		/* Set Bypass mode */
 625		PllCfg |= (1 << 15);
 626		dib0090_fw_write_reg(state, 0x21, PllCfg);
 627
 628		/* Set Reset Pll */
 629		PllCfg &= ~(1 << 13);
 630		dib0090_fw_write_reg(state, 0x21, PllCfg);
 631
 632	/*** Set new Pll configuration in bypass and reset state ***/
 633		PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
 634		dib0090_fw_write_reg(state, 0x21, PllCfg);
 635
 636		/* Remove Reset Pll */
 637		PllCfg |= (1 << 13);
 638		dib0090_fw_write_reg(state, 0x21, PllCfg);
 639
 640	/*** Wait for PLL lock ***/
 641		i = 100;
 642		do {
 643			v = !!(dib0090_fw_read_reg(state, 0x1a) & 0x800);
 644			if (v)
 645				break;
 646		} while (--i);
 647
 648		if (i == 0) {
 649			dprintk("Pll: Unable to lock Pll");
 650			return -EIO;
 651		}
 652
 653		/* Finally Remove Bypass mode */
 654		PllCfg &= ~(1 << 15);
 655		dib0090_fw_write_reg(state, 0x21, PllCfg);
 656	}
 657
 658	if (cfg->io.pll_bypass) {
 659		PllCfg |= (cfg->io.pll_bypass << 15);
 660		dib0090_fw_write_reg(state, 0x21, PllCfg);
 661	}
 662
 663	return dib0090_fw_identify(fe);
 664}
 665
 666static int dib0090_wakeup(struct dvb_frontend *fe)
 667{
 668	struct dib0090_state *state = fe->tuner_priv;
 669	if (state->config->sleep)
 670		state->config->sleep(fe, 0);
 671
 672	/* enable dataTX in case we have been restarted in the wrong moment */
 673	dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
 674	return 0;
 675}
 676
 677static int dib0090_sleep(struct dvb_frontend *fe)
 678{
 679	struct dib0090_state *state = fe->tuner_priv;
 680	if (state->config->sleep)
 681		state->config->sleep(fe, 1);
 682	return 0;
 683}
 684
 685void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
 686{
 687	struct dib0090_state *state = fe->tuner_priv;
 688	if (fast)
 689		dib0090_write_reg(state, 0x04, 0);
 690	else
 691		dib0090_write_reg(state, 0x04, 1);
 692}
 693
 694EXPORT_SYMBOL(dib0090_dcc_freq);
 695
 696static const u16 bb_ramp_pwm_normal_socs[] = {
 697	550,			/* max BB gain in 10th of dB */
 698	(1 << 9) | 8,		/* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
 699	440,
 700	(4 << 9) | 0,		/* BB_RAMP3 = 26dB */
 701	(0 << 9) | 208,		/* BB_RAMP4 */
 702	(4 << 9) | 208,		/* BB_RAMP5 = 29dB */
 703	(0 << 9) | 440,		/* BB_RAMP6 */
 704};
 705
 706static const u16 rf_ramp_pwm_cband_7090[] = {
 707	280,			/* max RF gain in 10th of dB */
 708	18,			/* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
 709	504,			/* ramp_max = maximum X used on the ramp */
 710	(29 << 10) | 364,	/* RF_RAMP5, LNA 1 = 8dB */
 711	(0 << 10) | 504,	/* RF_RAMP6, LNA 1 */
 712	(60 << 10) | 228,	/* RF_RAMP7, LNA 2 = 7.7dB */
 713	(0 << 10) | 364,	/* RF_RAMP8, LNA 2 */
 714	(34 << 10) | 109,	/* GAIN_4_1, LNA 3 = 6.8dB */
 715	(0 << 10) | 228,	/* GAIN_4_2, LNA 3 */
 716	(37 << 10) | 0,		/* RF_RAMP3, LNA 4 = 6.2dB */
 717	(0 << 10) | 109,	/* RF_RAMP4, LNA 4 */
 718};
 719
 720static const u16 rf_ramp_pwm_cband_8090[] = {
 721	345,			/* max RF gain in 10th of dB */
 722	29,			/* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
 723	1000,			/* ramp_max = maximum X used on the ramp */
 724	(35 << 10) | 772,	/* RF_RAMP3, LNA 1 = 8dB */
 725	(0 << 10) | 1000,	/* RF_RAMP4, LNA 1 */
 726	(58 << 10) | 496,	/* RF_RAMP5, LNA 2 = 9.5dB */
 727	(0 << 10) | 772,	/* RF_RAMP6, LNA 2 */
 728	(27 << 10) | 200,	/* RF_RAMP7, LNA 3 = 10.5dB */
 729	(0 << 10) | 496,	/* RF_RAMP8, LNA 3 */
 730	(40 << 10) | 0,		/* GAIN_4_1, LNA 4 = 7dB */
 731	(0 << 10) | 200,	/* GAIN_4_2, LNA 4 */
 732};
 733
 734static const u16 rf_ramp_pwm_uhf_7090[] = {
 735	407,			/* max RF gain in 10th of dB */
 736	13,			/* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
 737	529,			/* ramp_max = maximum X used on the ramp */
 738	(23 << 10) | 0,		/* RF_RAMP3, LNA 1 = 14.7dB */
 739	(0 << 10) | 176,	/* RF_RAMP4, LNA 1 */
 740	(63 << 10) | 400,	/* RF_RAMP5, LNA 2 = 8dB */
 741	(0 << 10) | 529,	/* RF_RAMP6, LNA 2 */
 742	(48 << 10) | 316,	/* RF_RAMP7, LNA 3 = 6.8dB */
 743	(0 << 10) | 400,	/* RF_RAMP8, LNA 3 */
 744	(29 << 10) | 176,	/* GAIN_4_1, LNA 4 = 11.5dB */
 745	(0 << 10) | 316,	/* GAIN_4_2, LNA 4 */
 746};
 747
 748static const u16 rf_ramp_pwm_uhf_8090[] = {
 749	388,			/* max RF gain in 10th of dB */
 750	26,			/* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
 751	1008,			/* ramp_max = maximum X used on the ramp */
 752	(11 << 10) | 0,		/* RF_RAMP3, LNA 1 = 14.7dB */
 753	(0 << 10) | 369,	/* RF_RAMP4, LNA 1 */
 754	(41 << 10) | 809,	/* RF_RAMP5, LNA 2 = 8dB */
 755	(0 << 10) | 1008,	/* RF_RAMP6, LNA 2 */
 756	(27 << 10) | 659,	/* RF_RAMP7, LNA 3 = 6dB */
 757	(0 << 10) | 809,	/* RF_RAMP8, LNA 3 */
 758	(14 << 10) | 369,	/* GAIN_4_1, LNA 4 = 11.5dB */
 759	(0 << 10) | 659,	/* GAIN_4_2, LNA 4 */
 760};
 761
 762static const u16 rf_ramp_pwm_cband[] = {
 763	0,			/* max RF gain in 10th of dB */
 764	0,			/* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
 765	0,			/* ramp_max = maximum X used on the ramp */
 766	(0 << 10) | 0,		/* 0x2c, LNA 1 = 0dB */
 767	(0 << 10) | 0,		/* 0x2d, LNA 1 */
 768	(0 << 10) | 0,		/* 0x2e, LNA 2 = 0dB */
 769	(0 << 10) | 0,		/* 0x2f, LNA 2 */
 770	(0 << 10) | 0,		/* 0x30, LNA 3 = 0dB */
 771	(0 << 10) | 0,		/* 0x31, LNA 3 */
 772	(0 << 10) | 0,		/* GAIN_4_1, LNA 4 = 0dB */
 773	(0 << 10) | 0,		/* GAIN_4_2, LNA 4 */
 774};
 775
 776static const u16 rf_ramp_vhf[] = {
 777	412,			/* max RF gain in 10th of dB */
 778	132, 307, 127,		/* LNA1,  13.2dB */
 779	105, 412, 255,		/* LNA2,  10.5dB */
 780	50, 50, 127,		/* LNA3,  5dB */
 781	125, 175, 127,		/* LNA4,  12.5dB */
 782	0, 0, 127,		/* CBAND, 0dB */
 783};
 784
 785static const u16 rf_ramp_uhf[] = {
 786	412,			/* max RF gain in 10th of dB */
 787	132, 307, 127,		/* LNA1  : total gain = 13.2dB, point on the ramp where this amp is full gain, value to write to get full gain */
 788	105, 412, 255,		/* LNA2  : 10.5 dB */
 789	50, 50, 127,		/* LNA3  :  5.0 dB */
 790	125, 175, 127,		/* LNA4  : 12.5 dB */
 791	0, 0, 127,		/* CBAND :  0.0 dB */
 792};
 793
 794static const u16 rf_ramp_cband_broadmatching[] =	/* for p1G only */
 795{
 796	314,			/* Calibrated at 200MHz order has been changed g4-g3-g2-g1 */
 797	84, 314, 127,		/* LNA1 */
 798	80, 230, 255,		/* LNA2 */
 799	80, 150, 127,		/* LNA3  It was measured 12dB, do not lock if 120 */
 800	70, 70, 127,		/* LNA4 */
 801	0, 0, 127,		/* CBAND */
 802};
 803
 804static const u16 rf_ramp_cband[] = {
 805	332,			/* max RF gain in 10th of dB */
 806	132, 252, 127,		/* LNA1,  dB */
 807	80, 332, 255,		/* LNA2,  dB */
 808	0, 0, 127,		/* LNA3,  dB */
 809	0, 0, 127,		/* LNA4,  dB */
 810	120, 120, 127,		/* LT1 CBAND */
 811};
 812
 813static const u16 rf_ramp_pwm_vhf[] = {
 814	404,			/* max RF gain in 10th of dB */
 815	25,			/* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
 816	1011,			/* ramp_max = maximum X used on the ramp */
 817	(6 << 10) | 417,	/* 0x2c, LNA 1 = 13.2dB */
 818	(0 << 10) | 756,	/* 0x2d, LNA 1 */
 819	(16 << 10) | 756,	/* 0x2e, LNA 2 = 10.5dB */
 820	(0 << 10) | 1011,	/* 0x2f, LNA 2 */
 821	(16 << 10) | 290,	/* 0x30, LNA 3 = 5dB */
 822	(0 << 10) | 417,	/* 0x31, LNA 3 */
 823	(7 << 10) | 0,		/* GAIN_4_1, LNA 4 = 12.5dB */
 824	(0 << 10) | 290,	/* GAIN_4_2, LNA 4 */
 825};
 826
 827static const u16 rf_ramp_pwm_uhf[] = {
 828	404,			/* max RF gain in 10th of dB */
 829	25,			/* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
 830	1011,			/* ramp_max = maximum X used on the ramp */
 831	(6 << 10) | 417,	/* 0x2c, LNA 1 = 13.2dB */
 832	(0 << 10) | 756,	/* 0x2d, LNA 1 */
 833	(16 << 10) | 756,	/* 0x2e, LNA 2 = 10.5dB */
 834	(0 << 10) | 1011,	/* 0x2f, LNA 2 */
 835	(16 << 10) | 0,		/* 0x30, LNA 3 = 5dB */
 836	(0 << 10) | 127,	/* 0x31, LNA 3 */
 837	(7 << 10) | 127,	/* GAIN_4_1, LNA 4 = 12.5dB */
 838	(0 << 10) | 417,	/* GAIN_4_2, LNA 4 */
 839};
 840
 841static const u16 bb_ramp_boost[] = {
 842	550,			/* max BB gain in 10th of dB */
 843	260, 260, 26,		/* BB1, 26dB */
 844	290, 550, 29,		/* BB2, 29dB */
 845};
 846
 847static const u16 bb_ramp_pwm_normal[] = {
 848	500,			/* max RF gain in 10th of dB */
 849	8,			/* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x34 */
 850	400,
 851	(2 << 9) | 0,		/* 0x35 = 21dB */
 852	(0 << 9) | 168,		/* 0x36 */
 853	(2 << 9) | 168,		/* 0x37 = 29dB */
 854	(0 << 9) | 400,		/* 0x38 */
 855};
 856
 857struct slope {
 858	s16 range;
 859	s16 slope;
 860};
 861static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val)
 862{
 863	u8 i;
 864	u16 rest;
 865	u16 ret = 0;
 866	for (i = 0; i < num; i++) {
 867		if (val > slopes[i].range)
 868			rest = slopes[i].range;
 869		else
 870			rest = val;
 871		ret += (rest * slopes[i].slope) / slopes[i].range;
 872		val -= rest;
 873	}
 874	return ret;
 875}
 876
 877static const struct slope dib0090_wbd_slopes[3] = {
 878	{66, 120},		/* -64,-52: offset -   65 */
 879	{600, 170},		/* -52,-35: 65     -  665 */
 880	{170, 250},		/* -45,-10: 665    - 835 */
 881};
 882
 883static s16 dib0090_wbd_to_db(struct dib0090_state *state, u16 wbd)
 884{
 885	wbd &= 0x3ff;
 886	if (wbd < state->wbd_offset)
 887		wbd = 0;
 888	else
 889		wbd -= state->wbd_offset;
 890	/* -64dB is the floor */
 891	return -640 + (s16) slopes_to_scale(dib0090_wbd_slopes, ARRAY_SIZE(dib0090_wbd_slopes), wbd);
 892}
 893
 894static void dib0090_wbd_target(struct dib0090_state *state, u32 rf)
 895{
 896	u16 offset = 250;
 897
 898	/* TODO : DAB digital N+/-1 interferer perfs : offset = 10 */
 899
 900	if (state->current_band == BAND_VHF)
 901		offset = 650;
 902#ifndef FIRMWARE_FIREFLY
 903	if (state->current_band == BAND_VHF)
 904		offset = state->config->wbd_vhf_offset;
 905	if (state->current_band == BAND_CBAND)
 906		offset = state->config->wbd_cband_offset;
 907#endif
 908
 909	state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + offset);
 910	dprintk("wbd-target: %d dB", (u32) state->wbd_target);
 911}
 912
 913static const int gain_reg_addr[4] = {
 914	0x08, 0x0a, 0x0f, 0x01
 915};
 916
 917static void dib0090_gain_apply(struct dib0090_state *state, s16 gain_delta, s16 top_delta, u8 force)
 918{
 919	u16 rf, bb, ref;
 920	u16 i, v, gain_reg[4] = { 0 }, gain;
 921	const u16 *g;
 922
 923	if (top_delta < -511)
 924		top_delta = -511;
 925	if (top_delta > 511)
 926		top_delta = 511;
 927
 928	if (force) {
 929		top_delta *= (1 << WBD_ALPHA);
 930		gain_delta *= (1 << GAIN_ALPHA);
 931	}
 932
 933	if (top_delta >= ((s16) (state->rf_ramp[0] << WBD_ALPHA) - state->rf_gain_limit))	/* overflow */
 934		state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
 935	else
 936		state->rf_gain_limit += top_delta;
 937
 938	if (state->rf_gain_limit < 0)	/*underflow */
 939		state->rf_gain_limit = 0;
 940
 941	/* use gain as a temporary variable and correct current_gain */
 942	gain = ((state->rf_gain_limit >> WBD_ALPHA) + state->bb_ramp[0]) << GAIN_ALPHA;
 943	if (gain_delta >= ((s16) gain - state->current_gain))	/* overflow */
 944		state->current_gain = gain;
 945	else
 946		state->current_gain += gain_delta;
 947	/* cannot be less than 0 (only if gain_delta is less than 0 we can have current_gain < 0) */
 948	if (state->current_gain < 0)
 949		state->current_gain = 0;
 950
 951	/* now split total gain to rf and bb gain */
 952	gain = state->current_gain >> GAIN_ALPHA;
 953
 954	/* requested gain is bigger than rf gain limit - ACI/WBD adjustment */
 955	if (gain > (state->rf_gain_limit >> WBD_ALPHA)) {
 956		rf = state->rf_gain_limit >> WBD_ALPHA;
 957		bb = gain - rf;
 958		if (bb > state->bb_ramp[0])
 959			bb = state->bb_ramp[0];
 960	} else {		/* high signal level -> all gains put on RF */
 961		rf = gain;
 962		bb = 0;
 963	}
 964
 965	state->gain[0] = rf;
 966	state->gain[1] = bb;
 967
 968	/* software ramp */
 969	/* Start with RF gains */
 970	g = state->rf_ramp + 1;	/* point on RF LNA1 max gain */
 971	ref = rf;
 972	for (i = 0; i < 7; i++) {	/* Go over all amplifiers => 5RF amps + 2 BB amps = 7 amps */
 973		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 */
 974			v = 0;	/* force the gain to write for the current amp to be null */
 975		else if (ref >= g[1])	/* Gain to set is higher than the high working point of this amp */
 976			v = g[2];	/* force this amp to be full gain */
 977		else		/* compute the value to set to this amp because we are somewhere in his range */
 978			v = ((ref - (g[1] - g[0])) * g[2]) / g[0];
 979
 980		if (i == 0)	/* LNA 1 reg mapping */
 981			gain_reg[0] = v;
 982		else if (i == 1)	/* LNA 2 reg mapping */
 983			gain_reg[0] |= v << 7;
 984		else if (i == 2)	/* LNA 3 reg mapping */
 985			gain_reg[1] = v;
 986		else if (i == 3)	/* LNA 4 reg mapping */
 987			gain_reg[1] |= v << 7;
 988		else if (i == 4)	/* CBAND LNA reg mapping */
 989			gain_reg[2] = v | state->rf_lt_def;
 990		else if (i == 5)	/* BB gain 1 reg mapping */
 991			gain_reg[3] = v << 3;
 992		else if (i == 6)	/* BB gain 2 reg mapping */
 993			gain_reg[3] |= v << 8;
 994
 995		g += 3;		/* go to next gain bloc */
 996
 997		/* When RF is finished, start with BB */
 998		if (i == 4) {
 999			g = state->bb_ramp + 1;	/* point on BB gain 1 max gain */
1000			ref = bb;
1001		}
1002	}
1003	gain_reg[3] |= state->bb_1_def;
1004	gain_reg[3] |= ((bb % 10) * 100) / 125;
1005
1006#ifdef DEBUG_AGC
1007	dprintk("GA CALC: DB: %3d(rf) + %3d(bb) = %3d gain_reg[0]=%04x gain_reg[1]=%04x gain_reg[2]=%04x gain_reg[0]=%04x", rf, bb, rf + bb,
1008		gain_reg[0], gain_reg[1], gain_reg[2], gain_reg[3]);
1009#endif
1010
1011	/* Write the amplifier regs */
1012	for (i = 0; i < 4; i++) {
1013		v = gain_reg[i];
1014		if (force || state->gain_reg[i] != v) {
1015			state->gain_reg[i] = v;
1016			dib0090_write_reg(state, gain_reg_addr[i], v);
1017		}
1018	}
1019}
1020
1021static void dib0090_set_boost(struct dib0090_state *state, int onoff)
1022{
1023	state->bb_1_def &= 0xdfff;
1024	state->bb_1_def |= onoff << 13;
1025}
1026
1027static void dib0090_set_rframp(struct dib0090_state *state, const u16 * cfg)
1028{
1029	state->rf_ramp = cfg;
1030}
1031
1032static void dib0090_set_rframp_pwm(struct dib0090_state *state, const u16 * cfg)
1033{
1034	state->rf_ramp = cfg;
1035
1036	dib0090_write_reg(state, 0x2a, 0xffff);
1037
1038	dprintk("total RF gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x2a));
1039
1040	dib0090_write_regs(state, 0x2c, cfg + 3, 6);
1041	dib0090_write_regs(state, 0x3e, cfg + 9, 2);
1042}
1043
1044static void dib0090_set_bbramp(struct dib0090_state *state, const u16 * cfg)
1045{
1046	state->bb_ramp = cfg;
1047	dib0090_set_boost(state, cfg[0] > 500);	/* we want the boost if the gain is higher that 50dB */
1048}
1049
1050static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg)
1051{
1052	state->bb_ramp = cfg;
1053
1054	dib0090_set_boost(state, cfg[0] > 500);	/* we want the boost if the gain is higher that 50dB */
1055
1056	dib0090_write_reg(state, 0x33, 0xffff);
1057	dprintk("total BB gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x33));
1058	dib0090_write_regs(state, 0x35, cfg + 3, 4);
1059}
1060
1061void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
1062{
1063	struct dib0090_state *state = fe->tuner_priv;
1064	/* reset the AGC */
1065
1066	if (state->config->use_pwm_agc) {
1067#ifdef CONFIG_BAND_SBAND
1068		if (state->current_band == BAND_SBAND) {
1069			dib0090_set_rframp_pwm(state, rf_ramp_pwm_sband);
1070			dib0090_set_bbramp_pwm(state, bb_ramp_pwm_boost);
1071		} else
1072#endif
1073#ifdef CONFIG_BAND_CBAND
1074		if (state->current_band == BAND_CBAND) {
1075			if (state->identity.in_soc) {
1076				dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
1077				if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1078					dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_8090);
1079				else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
1080					dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090);
1081			} else {
1082				dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband);
1083				dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
1084			}
1085		} else
1086#endif
1087#ifdef CONFIG_BAND_VHF
1088		if (state->current_band == BAND_VHF) {
1089			if (state->identity.in_soc) {
1090				dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
1091			} else {
1092				dib0090_set_rframp_pwm(state, rf_ramp_pwm_vhf);
1093				dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
1094			}
1095		} else
1096#endif
1097		{
1098			if (state->identity.in_soc) {
1099				if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1100					dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf_8090);
1101				else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
1102					dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf_7090);
1103				dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
1104			} else {
1105				dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf);
1106				dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
1107			}
1108		}
1109
1110		if (state->rf_ramp[0] != 0)
1111			dib0090_write_reg(state, 0x32, (3 << 11));
1112		else
1113			dib0090_write_reg(state, 0x32, (0 << 11));
1114
1115		dib0090_write_reg(state, 0x04, 0x01);
1116		dib0090_write_reg(state, 0x39, (1 << 10));
1117	}
1118}
1119
1120EXPORT_SYMBOL(dib0090_pwm_gain_reset);
1121
1122static u32 dib0090_get_slow_adc_val(struct dib0090_state *state)
1123{
1124	u16 adc_val = dib0090_read_reg(state, 0x1d);
1125	if (state->identity.in_soc)
1126		adc_val >>= 2;
1127	return adc_val;
1128}
1129
1130int dib0090_gain_control(struct dvb_frontend *fe)
1131{
1132	struct dib0090_state *state = fe->tuner_priv;
1133	enum frontend_tune_state *tune_state = &state->tune_state;
1134	int ret = 10;
1135
1136	u16 wbd_val = 0;
1137	u8 apply_gain_immediatly = 1;
1138	s16 wbd_error = 0, adc_error = 0;
1139
1140	if (*tune_state == CT_AGC_START) {
1141		state->agc_freeze = 0;
1142		dib0090_write_reg(state, 0x04, 0x0);
1143
1144#ifdef CONFIG_BAND_SBAND
1145		if (state->current_band == BAND_SBAND) {
1146			dib0090_set_rframp(state, rf_ramp_sband);
1147			dib0090_set_bbramp(state, bb_ramp_boost);
1148		} else
1149#endif
1150#ifdef CONFIG_BAND_VHF
1151		if (state->current_band == BAND_VHF && !state->identity.p1g) {
1152			dib0090_set_rframp(state, rf_ramp_vhf);
1153			dib0090_set_bbramp(state, bb_ramp_boost);
1154		} else
1155#endif
1156#ifdef CONFIG_BAND_CBAND
1157		if (state->current_band == BAND_CBAND && !state->identity.p1g) {
1158			dib0090_set_rframp(state, rf_ramp_cband);
1159			dib0090_set_bbramp(state, bb_ramp_boost);
1160		} else
1161#endif
1162		if ((state->current_band == BAND_CBAND || state->current_band == BAND_VHF) && state->identity.p1g) {
1163			dib0090_set_rframp(state, rf_ramp_cband_broadmatching);
1164			dib0090_set_bbramp(state, bb_ramp_boost);
1165		} else {
1166			dib0090_set_rframp(state, rf_ramp_uhf);
1167			dib0090_set_bbramp(state, bb_ramp_boost);
1168		}
1169
1170		dib0090_write_reg(state, 0x32, 0);
1171		dib0090_write_reg(state, 0x39, 0);
1172
1173		dib0090_wbd_target(state, state->current_rf);
1174
1175		state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
1176		state->current_gain = ((state->rf_ramp[0] + state->bb_ramp[0]) / 2) << GAIN_ALPHA;
1177
1178		*tune_state = CT_AGC_STEP_0;
1179	} else if (!state->agc_freeze) {
1180		s16 wbd = 0, i, cnt;
1181
1182		int adc;
1183		wbd_val = dib0090_get_slow_adc_val(state);
1184
1185		if (*tune_state == CT_AGC_STEP_0)
1186			cnt = 5;
1187		else
1188			cnt = 1;
1189
1190		for (i = 0; i < cnt; i++) {
1191			wbd_val = dib0090_get_slow_adc_val(state);
1192			wbd += dib0090_wbd_to_db(state, wbd_val);
1193		}
1194		wbd /= cnt;
1195		wbd_error = state->wbd_target - wbd;
1196
1197		if (*tune_state == CT_AGC_STEP_0) {
1198			if (wbd_error < 0 && state->rf_gain_limit > 0 && !state->identity.p1g) {
1199#ifdef CONFIG_BAND_CBAND
1200				/* in case of CBAND tune reduce first the lt_gain2 before adjusting the RF gain */
1201				u8 ltg2 = (state->rf_lt_def >> 10) & 0x7;
1202				if (state->current_band == BAND_CBAND && ltg2) {
1203					ltg2 >>= 1;
1204					state->rf_lt_def &= ltg2 << 10;	/* reduce in 3 steps from 7 to 0 */
1205				}
1206#endif
1207			} else {
1208				state->agc_step = 0;
1209				*tune_state = CT_AGC_STEP_1;
1210			}
1211		} else {
1212			/* calc the adc power */
1213			adc = state->config->get_adc_power(fe);
1214			adc = (adc * ((s32) 355774) + (((s32) 1) << 20)) >> 21;	/* included in [0:-700] */
1215
1216			adc_error = (s16) (((s32) ADC_TARGET) - adc);
1217#ifdef CONFIG_STANDARD_DAB
1218			if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB)
1219				adc_error -= 10;
1220#endif
1221#ifdef CONFIG_STANDARD_DVBT
1222			if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT &&
1223					(state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16))
1224				adc_error += 60;
1225#endif
1226#ifdef CONFIG_SYS_ISDBT
1227			if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count >
1228								0)
1229							&&
1230							((state->fe->dtv_property_cache.layer[0].modulation ==
1231							  QAM_64)
1232							 || (state->fe->dtv_property_cache.
1233								 layer[0].modulation == QAM_16)))
1234						||
1235						((state->fe->dtv_property_cache.layer[1].segment_count >
1236						  0)
1237						 &&
1238						 ((state->fe->dtv_property_cache.layer[1].modulation ==
1239						   QAM_64)
1240						  || (state->fe->dtv_property_cache.
1241							  layer[1].modulation == QAM_16)))
1242						||
1243						((state->fe->dtv_property_cache.layer[2].segment_count >
1244						  0)
1245						 &&
1246						 ((state->fe->dtv_property_cache.layer[2].modulation ==
1247						   QAM_64)
1248						  || (state->fe->dtv_property_cache.
1249							  layer[2].modulation == QAM_16)))
1250						)
1251				)
1252				adc_error += 60;
1253#endif
1254
1255			if (*tune_state == CT_AGC_STEP_1) {	/* quickly go to the correct range of the ADC power */
1256				if (ABS(adc_error) < 50 || state->agc_step++ > 5) {
1257
1258#ifdef CONFIG_STANDARD_DAB
1259					if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) {
1260						dib0090_write_reg(state, 0x02, (1 << 15) | (15 << 11) | (31 << 6) | (63));	/* cap value = 63 : narrow BB filter : Fc = 1.8MHz */
1261						dib0090_write_reg(state, 0x04, 0x0);
1262					} else
1263#endif
1264					{
1265						dib0090_write_reg(state, 0x02, (1 << 15) | (3 << 11) | (6 << 6) | (32));
1266						dib0090_write_reg(state, 0x04, 0x01);	/*0 = 1KHz ; 1 = 150Hz ; 2 = 50Hz ; 3 = 50KHz ; 4 = servo fast */
1267					}
1268
1269					*tune_state = CT_AGC_STOP;
1270				}
1271			} else {
1272				/* everything higher than or equal to CT_AGC_STOP means tracking */
1273				ret = 100;	/* 10ms interval */
1274				apply_gain_immediatly = 0;
1275			}
1276		}
1277#ifdef DEBUG_AGC
1278		dprintk
1279			("tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm",
1280			 (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val,
1281			 (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA));
1282#endif
1283	}
1284
1285	/* apply gain */
1286	if (!state->agc_freeze)
1287		dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly);
1288	return ret;
1289}
1290
1291EXPORT_SYMBOL(dib0090_gain_control);
1292
1293void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
1294{
1295	struct dib0090_state *state = fe->tuner_priv;
1296	if (rf)
1297		*rf = state->gain[0];
1298	if (bb)
1299		*bb = state->gain[1];
1300	if (rf_gain_limit)
1301		*rf_gain_limit = state->rf_gain_limit;
1302	if (rflt)
1303		*rflt = (state->rf_lt_def >> 10) & 0x7;
1304}
1305
1306EXPORT_SYMBOL(dib0090_get_current_gain);
1307
1308u16 dib0090_get_wbd_offset(struct dvb_frontend *fe)
1309{
1310	struct dib0090_state *state = fe->tuner_priv;
1311	u32 f_MHz = state->fe->dtv_property_cache.frequency / 1000000;
1312	s32 current_temp = state->temperature;
1313	s32 wbd_thot, wbd_tcold;
1314	const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1315
1316	while (f_MHz > wbd->max_freq)
1317		wbd++;
1318
1319	dprintk("using wbd-table-entry with max freq %d", wbd->max_freq);
1320
1321	if (current_temp < 0)
1322		current_temp = 0;
1323	if (current_temp > 128)
1324		current_temp = 128;
1325
1326	state->wbdmux &= ~(7 << 13);
1327	if (wbd->wbd_gain != 0)
1328		state->wbdmux |= (wbd->wbd_gain << 13);
1329	else
1330		state->wbdmux |= (4 << 13);
1331
1332	dib0090_write_reg(state, 0x10, state->wbdmux);
1333
1334	wbd_thot = wbd->offset_hot - (((u32) wbd->slope_hot * f_MHz) >> 6);
1335	wbd_tcold = wbd->offset_cold - (((u32) wbd->slope_cold * f_MHz) >> 6);
1336
1337	wbd_tcold += ((wbd_thot - wbd_tcold) * current_temp) >> 7;
1338
1339	state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + wbd_tcold);
1340	dprintk("wbd-target: %d dB", (u32) state->wbd_target);
1341	dprintk("wbd offset applied is %d", wbd_tcold);
1342
1343	return state->wbd_offset + wbd_tcold;
1344}
1345
1346EXPORT_SYMBOL(dib0090_get_wbd_offset);
1347
1348static const u16 dib0090_defaults[] = {
1349
1350	25, 0x01,
1351	0x0000,
1352	0x99a0,
1353	0x6008,
1354	0x0000,
1355	0x8bcb,
1356	0x0000,
1357	0x0405,
1358	0x0000,
1359	0x0000,
1360	0x0000,
1361	0xb802,
1362	0x0300,
1363	0x2d12,
1364	0xbac0,
1365	0x7c00,
1366	0xdbb9,
1367	0x0954,
1368	0x0743,
1369	0x8000,
1370	0x0001,
1371	0x0040,
1372	0x0100,
1373	0x0000,
1374	0xe910,
1375	0x149e,
1376
1377	1, 0x1c,
1378	0xff2d,
1379
1380	1, 0x39,
1381	0x0000,
1382
1383	2, 0x1e,
1384	0x07FF,
1385	0x0007,
1386
1387	1, 0x24,
1388	EN_UHF | EN_CRYSTAL,
1389
1390	2, 0x3c,
1391	0x3ff,
1392	0x111,
1393	0
1394};
1395
1396static const u16 dib0090_p1g_additionnal_defaults[] = {
1397	1, 0x05,
1398	0xabcd,
1399
1400	1, 0x11,
1401	0x00b4,
1402
1403	1, 0x1c,
1404	0xfffd,
1405
1406	1, 0x40,
1407	0x108,
1408	0
1409};
1410
1411static void dib0090_set_default_config(struct dib0090_state *state, const u16 * n)
1412{
1413	u16 l, r;
1414
1415	l = pgm_read_word(n++);
1416	while (l) {
1417		r = pgm_read_word(n++);
1418		do {
1419			dib0090_write_reg(state, r, pgm_read_word(n++));
1420			r++;
1421		} while (--l);
1422		l = pgm_read_word(n++);
1423	}
1424}
1425
1426#define CAP_VALUE_MIN (u8)  9
1427#define CAP_VALUE_MAX (u8) 40
1428#define HR_MIN	      (u8) 25
1429#define HR_MAX	      (u8) 40
1430#define POLY_MIN      (u8)  0
1431#define POLY_MAX      (u8)  8
1432
1433void dib0090_set_EFUSE(struct dib0090_state *state)
1434{
1435	u8 c, h, n;
1436	u16 e2, e4;
1437	u16 cal;
1438
1439	e2 = dib0090_read_reg(state, 0x26);
1440	e4 = dib0090_read_reg(state, 0x28);
1441
1442	if ((state->identity.version == P1D_E_F) ||
1443			(state->identity.version == P1G) || (e2 == 0xffff)) {
1444
1445		dib0090_write_reg(state, 0x22, 0x10);
1446		cal = (dib0090_read_reg(state, 0x22) >> 6) & 0x3ff;
1447
1448		if ((cal < 670) || (cal == 1023))
1449			cal = 850;
1450		n = 165 - ((cal * 10)>>6) ;
1451		e2 = e4 = (3<<12) | (34<<6) | (n);
1452	}
1453
1454	if (e2 != e4)
1455		e2 &= e4; /* Remove the redundancy  */
1456
1457	if (e2 != 0xffff) {
1458		c = e2 & 0x3f;
1459		n = (e2 >> 12) & 0xf;
1460		h = (e2 >> 6) & 0x3f;
1461
1462		if ((c >= CAP_VALUE_MAX) || (c <= CAP_VALUE_MIN))
1463			c = 32;
1464		if ((h >= HR_MAX) || (h <= HR_MIN))
1465			h = 34;
1466		if ((n >= POLY_MAX) || (n <= POLY_MIN))
1467			n = 3;
1468
1469		dib0090_write_reg(state, 0x13, (h << 10)) ;
1470		e2 = (n<<11) | ((h>>2)<<6) | (c);
1471		dib0090_write_reg(state, 0x2, e2) ; /* Load the BB_2 */
1472	}
1473}
1474
1475static int dib0090_reset(struct dvb_frontend *fe)
1476{
1477	struct dib0090_state *state = fe->tuner_priv;
1478
1479	dib0090_reset_digital(fe, state->config);
1480	if (dib0090_identify(fe) < 0)
1481		return -EIO;
1482
1483#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT
1484	if (!(state->identity.version & 0x1))	/* it is P1B - reset is already done */
1485		return 0;
1486#endif
1487
1488	if (!state->identity.in_soc) {
1489		if ((dib0090_read_reg(state, 0x1a) >> 5) & 0x2)
1490			dib0090_write_reg(state, 0x1b, (EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1491		else
1492			dib0090_write_reg(state, 0x1b, (EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1493	}
1494
1495	dib0090_set_default_config(state, dib0090_defaults);
1496
1497	if (state->identity.in_soc)
1498		dib0090_write_reg(state, 0x18, 0x2910);  /* charge pump current = 0 */
1499
1500	if (state->identity.p1g)
1501		dib0090_set_default_config(state, dib0090_p1g_additionnal_defaults);
1502
1503	/* Update the efuse : Only available for KROSUS > P1C  and SOC as well*/
1504	if (((state->identity.version & 0x1f) >= P1D_E_F) || (state->identity.in_soc))
1505		dib0090_set_EFUSE(state);
1506
1507	/* Congigure in function of the crystal */
1508	if (state->config->io.clock_khz >= 24000)
1509		dib0090_write_reg(state, 0x14, 1);
1510	else
1511		dib0090_write_reg(state, 0x14, 2);
1512	dprintk("Pll lock : %d", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1);
1513
1514	state->calibrate = DC_CAL | WBD_CAL | TEMP_CAL;	/* enable iq-offset-calibration and wbd-calibration when tuning next time */
1515
1516	return 0;
1517}
1518
1519#define steps(u) (((u) > 15) ? ((u)-16) : (u))
1520#define INTERN_WAIT 10
1521static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1522{
1523	int ret = INTERN_WAIT * 10;
1524
1525	switch (*tune_state) {
1526	case CT_TUNER_STEP_2:
1527		/* Turns to positive */
1528		dib0090_write_reg(state, 0x1f, 0x7);
1529		*tune_state = CT_TUNER_STEP_3;
1530		break;
1531
1532	case CT_TUNER_STEP_3:
1533		state->adc_diff = dib0090_read_reg(state, 0x1d);
1534
1535		/* Turns to negative */
1536		dib0090_write_reg(state, 0x1f, 0x4);
1537		*tune_state = CT_TUNER_STEP_4;
1538		break;
1539
1540	case CT_TUNER_STEP_4:
1541		state->adc_diff -= dib0090_read_reg(state, 0x1d);
1542		*tune_state = CT_TUNER_STEP_5;
1543		ret = 0;
1544		break;
1545
1546	default:
1547		break;
1548	}
1549
1550	return ret;
1551}
1552
1553struct dc_calibration {
1554	u8 addr;
1555	u8 offset;
1556	u8 pga:1;
1557	u16 bb1;
1558	u8 i:1;
1559};
1560
1561static const struct dc_calibration dc_table[] = {
1562	/* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
1563	{0x06, 5, 1, (1 << 13) | (0 << 8) | (26 << 3), 1},
1564	{0x07, 11, 1, (1 << 13) | (0 << 8) | (26 << 3), 0},
1565	/* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
1566	{0x06, 0, 0, (1 << 13) | (29 << 8) | (26 << 3), 1},
1567	{0x06, 10, 0, (1 << 13) | (29 << 8) | (26 << 3), 0},
1568	{0},
1569};
1570
1571static const struct dc_calibration dc_p1g_table[] = {
1572	/* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
1573	/* addr ; trim reg offset ; pga ; CTRL_BB1 value ; i or q */
1574	{0x06, 5, 1, (1 << 13) | (0 << 8) | (15 << 3), 1},
1575	{0x07, 11, 1, (1 << 13) | (0 << 8) | (15 << 3), 0},
1576	/* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
1577	{0x06, 0, 0, (1 << 13) | (29 << 8) | (15 << 3), 1},
1578	{0x06, 10, 0, (1 << 13) | (29 << 8) | (15 << 3), 0},
1579	{0},
1580};
1581
1582static void dib0090_set_trim(struct dib0090_state *state)
1583{
1584	u16 *val;
1585
1586	if (state->dc->addr == 0x07)
1587		val = &state->bb7;
1588	else
1589		val = &state->bb6;
1590
1591	*val &= ~(0x1f << state->dc->offset);
1592	*val |= state->step << state->dc->offset;
1593
1594	dib0090_write_reg(state, state->dc->addr, *val);
1595}
1596
1597static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1598{
1599	int ret = 0;
1600	u16 reg;
1601
1602	switch (*tune_state) {
1603	case CT_TUNER_START:
1604		dprintk("Start DC offset calibration");
1605
1606		/* force vcm2 = 0.8V */
1607		state->bb6 = 0;
1608		state->bb7 = 0x040d;
1609
1610		/* the LNA AND LO are off */
1611		reg = dib0090_read_reg(state, 0x24) & 0x0ffb;	/* shutdown lna and lo */
1612		dib0090_write_reg(state, 0x24, reg);
1613
1614		state->wbdmux = dib0090_read_reg(state, 0x10);
1615		dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x7 << 3) | 0x3);
1616		dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
1617
1618		state->dc = dc_table;
1619
1620		if (state->identity.p1g)
1621			state->dc = dc_p1g_table;
1622		*tune_state = CT_TUNER_STEP_0;
1623
1624		/* fall through */
1625
1626	case CT_TUNER_STEP_0:
1627		dprintk("Sart/continue DC calibration for %s path", (state->dc->i == 1) ? "I" : "Q");
1628		dib0090_write_reg(state, 0x01, state->dc->bb1);
1629		dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7));
1630
1631		state->step = 0;
1632		state->min_adc_diff = 1023;
1633		*tune_state = CT_TUNER_STEP_1;
1634		ret = 50;
1635		break;
1636
1637	case CT_TUNER_STEP_1:
1638		dib0090_set_trim(state);
1639		*tune_state = CT_TUNER_STEP_2;
1640		break;
1641
1642	case CT_TUNER_STEP_2:
1643	case CT_TUNER_STEP_3:
1644	case CT_TUNER_STEP_4:
1645		ret = dib0090_get_offset(state, tune_state);
1646		break;
1647
1648	case CT_TUNER_STEP_5:	/* found an offset */
1649		dprintk("adc_diff = %d, current step= %d", (u32) state->adc_diff, state->step);
1650		if (state->step == 0 && state->adc_diff < 0) {
1651			state->min_adc_diff = -1023;
1652			dprintk("Change of sign of the minimum adc diff");
1653		}
1654
1655		dprintk("adc_diff = %d, min_adc_diff = %d current_step = %d", state->adc_diff, state->min_adc_diff, state->step);
1656
1657		/* first turn for this frequency */
1658		if (state->step == 0) {
1659			if (state->dc->pga && state->adc_diff < 0)
1660				state->step = 0x10;
1661			if (state->dc->pga == 0 && state->adc_diff > 0)
1662				state->step = 0x10;
1663		}
1664
1665		/* Look for a change of Sign in the Adc_diff.min_adc_diff is used to STORE the setp N-1 */
1666		if ((state->adc_diff & 0x8000) == (state->min_adc_diff & 0x8000) && steps(state->step) < 15) {
1667			/* stop search when the delta the sign is changing and Steps =15 and Step=0 is force for continuance */
1668			state->step++;
1669			state->min_adc_diff = state->adc_diff;
1670			*tune_state = CT_TUNER_STEP_1;
1671		} else {
1672			/* the minimum was what we have seen in the step before */
1673			if (ABS(state->adc_diff) > ABS(state->min_adc_diff)) {
1674				dprintk("Since adc_diff N = %d  > adc_diff step N-1 = %d, Come back one step", state->adc_diff, state->min_adc_diff);
1675				state->step--;
1676			}
1677
1678			dib0090_set_trim(state);
1679			dprintk("BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd", state->dc->addr, state->adc_diff, state->step);
1680
1681			state->dc++;
1682			if (state->dc->addr == 0)	/* done */
1683				*tune_state = CT_TUNER_STEP_6;
1684			else
1685				*tune_state = CT_TUNER_STEP_0;
1686
1687		}
1688		break;
1689
1690	case CT_TUNER_STEP_6:
1691		dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008);
1692		dib0090_write_reg(state, 0x1f, 0x7);
1693		*tune_state = CT_TUNER_START;	/* reset done -> real tuning can now begin */
1694		state->calibrate &= ~DC_CAL;
1695	default:
1696		break;
1697	}
1698	return ret;
1699}
1700
1701static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1702{
1703	u8 wbd_gain;
1704	const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1705
1706	switch (*tune_state) {
1707	case CT_TUNER_START:
1708		while (state->current_rf / 1000 > wbd->max_freq)
1709			wbd++;
1710		if (wbd->wbd_gain != 0)
1711			wbd_gain = wbd->wbd_gain;
1712		else {
1713			wbd_gain = 4;
1714#if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND)
1715			if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND))
1716				wbd_gain = 2;
1717#endif
1718		}
1719
1720		if (wbd_gain == state->wbd_calibration_gain) {	/* the WBD calibration has already been done */
1721			*tune_state = CT_TUNER_START;
1722			state->calibrate &= ~WBD_CAL;
1723			return 0;
1724		}
1725
1726		dib0090_write_reg(state, 0x10, 0x1b81 | (1 << 10) | (wbd_gain << 13) | (1 << 3));
1727
1728		dib0090_write_reg(state, 0x24, ((EN_UHF & 0x0fff) | (1 << 1)));
1729		*tune_state = CT_TUNER_STEP_0;
1730		state->wbd_calibration_gain = wbd_gain;
1731		return 90;	/* wait for the WBDMUX to switch and for the ADC to sample */
1732
1733	case CT_TUNER_STEP_0:
1734		state->wbd_offset = dib0090_get_slow_adc_val(state);
1735		dprintk("WBD calibration offset = %d", state->wbd_offset);
1736		*tune_state = CT_TUNER_START;	/* reset done -> real tuning can now begin */
1737		state->calibrate &= ~WBD_CAL;
1738		break;
1739
1740	default:
1741		break;
1742	}
1743	return 0;
1744}
1745
1746static void dib0090_set_bandwidth(struct dib0090_state *state)
1747{
1748	u16 tmp;
1749
1750	if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000)
1751		tmp = (3 << 14);
1752	else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000)
1753		tmp = (2 << 14);
1754	else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000)
1755		tmp = (1 << 14);
1756	else
1757		tmp = (0 << 14);
1758
1759	state->bb_1_def &= 0x3fff;
1760	state->bb_1_def |= tmp;
1761
1762	dib0090_write_reg(state, 0x01, state->bb_1_def);	/* be sure that we have the right bb-filter */
1763
1764	dib0090_write_reg(state, 0x03, 0x6008);	/* = 0x6008 : vcm3_trim = 1 ; filter2_gm1_trim = 8 ; filter2_cutoff_freq = 0 */
1765	dib0090_write_reg(state, 0x04, 0x1);	/* 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast */
1766	if (state->identity.in_soc) {
1767		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 */
1768	} else {
1769		dib0090_write_reg(state, 0x02, (5 << 11) | (8 << 6) | (22 & 0x3f));	/* 22 = cap_value */
1770		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 */
1771	}
1772}
1773
1774static const struct dib0090_pll dib0090_pll_table[] = {
1775#ifdef CONFIG_BAND_CBAND
1776	{56000, 0, 9, 48, 6},
1777	{70000, 1, 9, 48, 6},
1778	{87000, 0, 8, 32, 4},
1779	{105000, 1, 8, 32, 4},
1780	{115000, 0, 7, 24, 6},
1781	{140000, 1, 7, 24, 6},
1782	{170000, 0, 6, 16, 4},
1783#endif
1784#ifdef CONFIG_BAND_VHF
1785	{200000, 1, 6, 16, 4},
1786	{230000, 0, 5, 12, 6},
1787	{280000, 1, 5, 12, 6},
1788	{340000, 0, 4, 8, 4},
1789	{380000, 1, 4, 8, 4},
1790	{450000, 0, 3, 6, 6},
1791#endif
1792#ifdef CONFIG_BAND_UHF
1793	{580000, 1, 3, 6, 6},
1794	{700000, 0, 2, 4, 4},
1795	{860000, 1, 2, 4, 4},
1796#endif
1797#ifdef CONFIG_BAND_LBAND
1798	{1800000, 1, 0, 2, 4},
1799#endif
1800#ifdef CONFIG_BAND_SBAND
1801	{2900000, 0, 14, 1, 4},
1802#endif
1803};
1804
1805static const struct dib0090_tuning dib0090_tuning_table_fm_vhf_on_cband[] = {
1806
1807#ifdef CONFIG_BAND_CBAND
1808	{184000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1809	{227000

Large files files are truncated, but you can click here to view the full file