File Index
Files and directories
Sign in
FILE

dib7000p.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/dvb-frontends/dib7000p.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Linux-DVB Driver for DiBcom's second generation DiB7000P (PC).
   4 *
   5 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
   6 */
   7
   8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   9
  10#include <linux/kernel.h>
  11#include <linux/slab.h>
  12#include <linux/i2c.h>
  13#include <linux/mutex.h>
  14#include <asm/div64.h>
  15
  16#include <linux/int_log.h>
  17#include <media/dvb_frontend.h>
  18
  19#include "dib7000p.h"
  20
  21static int debug;
  22module_param(debug, int, 0644);
  23MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
  24
  25static int buggy_sfn_workaround;
  26module_param(buggy_sfn_workaround, int, 0644);
  27MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
  28
  29#define dprintk(fmt, arg...) do {					\
  30	if (debug)							\
  31		printk(KERN_DEBUG pr_fmt("%s: " fmt),			\
  32		       __func__, ##arg);				\
  33} while (0)
  34
  35struct dib7000p_state {
  36	struct dvb_frontend demod;
  37	struct dib7000p_config cfg;
  38
  39	u8 i2c_addr;
  40	struct i2c_adapter *i2c_adap;
  41
  42	struct dibx000_i2c_master i2c_master;
  43
  44	u16 wbd_ref;
  45
  46	u8 current_band;
  47	u32 current_bandwidth;
  48	struct dibx000_agc_config *current_agc;
  49	u32 timf;
  50
  51	u8 div_force_off:1;
  52	u8 div_state:1;
  53	u16 div_sync_wait;
  54
  55	u8 agc_state;
  56
  57	u16 gpio_dir;
  58	u16 gpio_val;
  59
  60	u8 sfn_workaround_active:1;
  61
  62#define SOC7090 0x7090
  63	u16 version;
  64
  65	u16 tuner_enable;
  66	struct i2c_adapter dib7090_tuner_adap;
  67
  68	/* for the I2C transfer */
  69	struct i2c_msg msg[2];
  70	u8 i2c_write_buffer[4];
  71	u8 i2c_read_buffer[2];
  72	struct mutex i2c_buffer_lock;
  73
  74	u8 input_mode_mpeg;
  75
  76	/* for DVBv5 stats */
  77	s64 old_ucb;
  78	unsigned long per_jiffies_stats;
  79	unsigned long ber_jiffies_stats;
  80	unsigned long get_stats_time;
  81};
  82
  83enum dib7000p_power_mode {
  84	DIB7000P_POWER_ALL = 0,
  85	DIB7000P_POWER_ANALOG_ADC,
  86	DIB7000P_POWER_INTERFACE_ONLY,
  87};
  88
  89/* dib7090 specific functions */
  90static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode);
  91static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
  92static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode);
  93static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode);
  94
  95static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
  96{
  97	u16 ret;
  98
  99	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
 100		dprintk("could not acquire lock\n");
 101		return 0;
 102	}
 103
 104	state->i2c_write_buffer[0] = reg >> 8;
 105	state->i2c_write_buffer[1] = reg & 0xff;
 106
 107	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
 108	state->msg[0].addr = state->i2c_addr >> 1;
 109	state->msg[0].flags = 0;
 110	state->msg[0].buf = state->i2c_write_buffer;
 111	state->msg[0].len = 2;
 112	state->msg[1].addr = state->i2c_addr >> 1;
 113	state->msg[1].flags = I2C_M_RD;
 114	state->msg[1].buf = state->i2c_read_buffer;
 115	state->msg[1].len = 2;
 116
 117	if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
 118		dprintk("i2c read error on %d\n", reg);
 119
 120	ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
 121	mutex_unlock(&state->i2c_buffer_lock);
 122	return ret;
 123}
 124
 125static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
 126{
 127	int ret;
 128
 129	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
 130		dprintk("could not acquire lock\n");
 131		return -EINVAL;
 132	}
 133
 134	state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
 135	state->i2c_write_buffer[1] = reg & 0xff;
 136	state->i2c_write_buffer[2] = (val >> 8) & 0xff;
 137	state->i2c_write_buffer[3] = val & 0xff;
 138
 139	memset(&state->msg[0], 0, sizeof(struct i2c_msg));
 140	state->msg[0].addr = state->i2c_addr >> 1;
 141	state->msg[0].flags = 0;
 142	state->msg[0].buf = state->i2c_write_buffer;
 143	state->msg[0].len = 4;
 144
 145	ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ?
 146			-EREMOTEIO : 0);
 147	mutex_unlock(&state->i2c_buffer_lock);
 148	return ret;
 149}
 150
 151static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
 152{
 153	u16 l = 0, r, *n;
 154	n = buf;
 155	l = *n++;
 156	while (l) {
 157		r = *n++;
 158
 159		do {
 160			dib7000p_write_word(state, r, *n++);
 161			r++;
 162		} while (--l);
 163		l = *n++;
 164	}
 165}
 166
 167static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
 168{
 169	int ret = 0;
 170	u16 outreg, fifo_threshold, smo_mode;
 171
 172	outreg = 0;
 173	fifo_threshold = 1792;
 174	smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
 175
 176	dprintk("setting output mode for demod %p to %d\n", &state->demod, mode);
 177
 178	switch (mode) {
 179	case OUTMODE_MPEG2_PAR_GATED_CLK:
 180		outreg = (1 << 10);	/* 0x0400 */
 181		break;
 182	case OUTMODE_MPEG2_PAR_CONT_CLK:
 183		outreg = (1 << 10) | (1 << 6);	/* 0x0440 */
 184		break;
 185	case OUTMODE_MPEG2_SERIAL:
 186		outreg = (1 << 10) | (2 << 6) | (0 << 1);	/* 0x0480 */
 187		break;
 188	case OUTMODE_DIVERSITY:
 189		if (state->cfg.hostbus_diversity)
 190			outreg = (1 << 10) | (4 << 6);	/* 0x0500 */
 191		else
 192			outreg = (1 << 11);
 193		break;
 194	case OUTMODE_MPEG2_FIFO:
 195		smo_mode |= (3 << 1);
 196		fifo_threshold = 512;
 197		outreg = (1 << 10) | (5 << 6);
 198		break;
 199	case OUTMODE_ANALOG_ADC:
 200		outreg = (1 << 10) | (3 << 6);
 201		break;
 202	case OUTMODE_HIGH_Z:
 203		outreg = 0;
 204		break;
 205	default:
 206		dprintk("Unhandled output_mode passed to be set for demod %p\n", &state->demod);
 207		break;
 208	}
 209
 210	if (state->cfg.output_mpeg2_in_188_bytes)
 211		smo_mode |= (1 << 5);
 212
 213	ret |= dib7000p_write_word(state, 235, smo_mode);
 214	ret |= dib7000p_write_word(state, 236, fifo_threshold);	/* synchronous fread */
 215	if (state->version != SOC7090)
 216		ret |= dib7000p_write_word(state, 1286, outreg);	/* P_Div_active */
 217
 218	return ret;
 219}
 220
 221static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
 222{
 223	struct dib7000p_state *state = demod->demodulator_priv;
 224
 225	if (state->div_force_off) {
 226		dprintk("diversity combination deactivated - forced by COFDM parameters\n");
 227		onoff = 0;
 228		dib7000p_write_word(state, 207, 0);
 229	} else
 230		dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
 231
 232	state->div_state = (u8) onoff;
 233
 234	if (onoff) {
 235		dib7000p_write_word(state, 204, 6);
 236		dib7000p_write_word(state, 205, 16);
 237		/* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
 238	} else {
 239		dib7000p_write_word(state, 204, 1);
 240		dib7000p_write_word(state, 205, 0);
 241	}
 242
 243	return 0;
 244}
 245
 246static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
 247{
 248	/* by default everything is powered off */
 249	u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
 250
 251	/* now, depending on the requested mode, we power on */
 252	switch (mode) {
 253		/* power up everything in the demod */
 254	case DIB7000P_POWER_ALL:
 255		reg_774 = 0x0000;
 256		reg_775 = 0x0000;
 257		reg_776 = 0x0;
 258		reg_899 = 0x0;
 259		if (state->version == SOC7090)
 260			reg_1280 &= 0x001f;
 261		else
 262			reg_1280 &= 0x01ff;
 263		break;
 264
 265	case DIB7000P_POWER_ANALOG_ADC:
 266		/* dem, cfg, iqc, sad, agc */
 267		reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
 268		/* nud */
 269		reg_776 &= ~((1 << 0));
 270		/* Dout */
 271		if (state->version != SOC7090)
 272			reg_1280 &= ~((1 << 11));
 273		reg_1280 &= ~(1 << 6);
 274		fallthrough;
 275	case DIB7000P_POWER_INTERFACE_ONLY:
 276		/* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
 277		/* TODO power up either SDIO or I2C */
 278		if (state->version == SOC7090)
 279			reg_1280 &= ~((1 << 7) | (1 << 5));
 280		else
 281			reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
 282		break;
 283
 284/* TODO following stuff is just converted from the dib7000-driver - check when is used what */
 285	}
 286
 287	dib7000p_write_word(state, 774, reg_774);
 288	dib7000p_write_word(state, 775, reg_775);
 289	dib7000p_write_word(state, 776, reg_776);
 290	dib7000p_write_word(state, 1280, reg_1280);
 291	if (state->version != SOC7090)
 292		dib7000p_write_word(state, 899, reg_899);
 293
 294	return 0;
 295}
 296
 297static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no)
 298{
 299	u16 reg_908 = 0, reg_909 = 0;
 300	u16 reg;
 301
 302	if (state->version != SOC7090) {
 303		reg_908 = dib7000p_read_word(state, 908);
 304		reg_909 = dib7000p_read_word(state, 909);
 305	}
 306
 307	switch (no) {
 308	case DIBX000_SLOW_ADC_ON:
 309		if (state->version == SOC7090) {
 310			reg = dib7000p_read_word(state, 1925);
 311
 312			dib7000p_write_word(state, 1925, reg | (1 << 4) | (1 << 2));	/* en_slowAdc = 1 & reset_sladc = 1 */
 313
 314			reg = dib7000p_read_word(state, 1925);	/* read access to make it works... strange ... */
 315			msleep(200);
 316			dib7000p_write_word(state, 1925, reg & ~(1 << 4));	/* en_slowAdc = 1 & reset_sladc = 0 */
 317
 318			reg = dib7000p_read_word(state, 72) & ~((0x3 << 14) | (0x3 << 12));
 319			dib7000p_write_word(state, 72, reg | (1 << 14) | (3 << 12) | 524);	/* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; (Vin2 = Vcm) */
 320		} else {
 321			reg_909 |= (1 << 1) | (1 << 0);
 322			dib7000p_write_word(state, 909, reg_909);
 323			reg_909 &= ~(1 << 1);
 324		}
 325		break;
 326
 327	case DIBX000_SLOW_ADC_OFF:
 328		if (state->version == SOC7090) {
 329			reg = dib7000p_read_word(state, 1925);
 330			dib7000p_write_word(state, 1925, (reg & ~(1 << 2)) | (1 << 4));	/* reset_sladc = 1 en_slowAdc = 0 */
 331		} else
 332			reg_909 |= (1 << 1) | (1 << 0);
 333		break;
 334
 335	case DIBX000_ADC_ON:
 336		reg_908 &= 0x0fff;
 337		reg_909 &= 0x0003;
 338		break;
 339
 340	case DIBX000_ADC_OFF:
 341		reg_908 |= (1 << 14) | (1 << 13) | (1 << 12);
 342		reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
 343		break;
 344
 345	case DIBX000_VBG_ENABLE:
 346		reg_908 &= ~(1 << 15);
 347		break;
 348
 349	case DIBX000_VBG_DISABLE:
 350		reg_908 |= (1 << 15);
 351		break;
 352
 353	default:
 354		break;
 355	}
 356
 357//	dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
 358
 359	reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4;
 360	reg_908 |= (state->cfg.enable_current_mirror & 1) << 7;
 361
 362	if (state->version != SOC7090) {
 363		dib7000p_write_word(state, 908, reg_908);
 364		dib7000p_write_word(state, 909, reg_909);
 365	}
 366}
 367
 368static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
 369{
 370	u32 timf;
 371
 372	// store the current bandwidth for later use
 373	state->current_bandwidth = bw;
 374
 375	if (state->timf == 0) {
 376		dprintk("using default timf\n");
 377		timf = state->cfg.bw->timf;
 378	} else {
 379		dprintk("using updated timf\n");
 380		timf = state->timf;
 381	}
 382
 383	timf = timf * (bw / 50) / 160;
 384
 385	dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
 386	dib7000p_write_word(state, 24, (u16) ((timf) & 0xffff));
 387
 388	return 0;
 389}
 390
 391static int dib7000p_sad_calib(struct dib7000p_state *state)
 392{
 393/* internal */
 394	dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
 395
 396	if (state->version == SOC7090)
 397		dib7000p_write_word(state, 74, 2048);
 398	else
 399		dib7000p_write_word(state, 74, 776);
 400
 401	/* do the calibration */
 402	dib7000p_write_word(state, 73, (1 << 0));
 403	dib7000p_write_word(state, 73, (0 << 0));
 404
 405	msleep(1);
 406
 407	return 0;
 408}
 409
 410static int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
 411{
 412	struct dib7000p_state *state = demod->demodulator_priv;
 413	if (value > 4095)
 414		value = 4095;
 415	state->wbd_ref = value;
 416	return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
 417}
 418
 419static int dib7000p_get_agc_values(struct dvb_frontend *fe,
 420		u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd)
 421{
 422	struct dib7000p_state *state = fe->demodulator_priv;
 423
 424	if (agc_global != NULL)
 425		*agc_global = dib7000p_read_word(state, 394);
 426	if (agc1 != NULL)
 427		*agc1 = dib7000p_read_word(state, 392);
 428	if (agc2 != NULL)
 429		*agc2 = dib7000p_read_word(state, 393);
 430	if (wbd != NULL)
 431		*wbd = dib7000p_read_word(state, 397);
 432
 433	return 0;
 434}
 435
 436static int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v)
 437{
 438	struct dib7000p_state *state = fe->demodulator_priv;
 439	return dib7000p_write_word(state, 108,  v);
 440}
 441
 442static void dib7000p_reset_pll(struct dib7000p_state *state)
 443{
 444	struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
 445	u16 clk_cfg0;
 446
 447	if (state->version == SOC7090) {
 448		dib7000p_write_word(state, 1856, (!bw->pll_reset << 13) | (bw->pll_range << 12) | (bw->pll_ratio << 6) | (bw->pll_prediv));
 449
 450		while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
 451			;
 452
 453		dib7000p_write_word(state, 1857, dib7000p_read_word(state, 1857) | (!bw->pll_bypass << 15));
 454	} else {
 455		/* force PLL bypass */
 456		clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
 457			(bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
 458
 459		dib7000p_write_word(state, 900, clk_cfg0);
 460
 461		/* P_pll_cfg */
 462		dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
 463		clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
 464		dib7000p_write_word(state, 900, clk_cfg0);
 465	}
 466
 467	dib7000p_write_word(state, 18, (u16) (((bw->internal * 1000) >> 16) & 0xffff));
 468	dib7000p_write_word(state, 19, (u16) ((bw->internal * 1000) & 0xffff));
 469	dib7000p_write_word(state, 21, (u16) ((bw->ifreq >> 16) & 0xffff));
 470	dib7000p_write_word(state, 22, (u16) ((bw->ifreq) & 0xffff));
 471
 472	dib7000p_write_word(state, 72, bw->sad_cfg);
 473}
 474
 475static u32 dib7000p_get_internal_freq(struct dib7000p_state *state)
 476{
 477	u32 internal = (u32) dib7000p_read_word(state, 18) << 16;
 478	internal |= (u32) dib7000p_read_word(state, 19);
 479	internal /= 1000;
 480
 481	return internal;
 482}
 483
 484static int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
 485{
 486	struct dib7000p_state *state = fe->demodulator_priv;
 487	u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856);
 488	u8 loopdiv, prediv;
 489	u32 internal, xtal;
 490
 491	/* get back old values */
 492	prediv = reg_1856 & 0x3f;
 493	loopdiv = (reg_1856 >> 6) & 0x3f;
 494
 495	if (loopdiv && bw && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) {
 496		dprintk("Updating pll (prediv: old =  %d new = %d ; loopdiv : old = %d new = %d)\n", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio);
 497		reg_1856 &= 0xf000;
 498		reg_1857 = dib7000p_read_word(state, 1857);
 499		dib7000p_write_word(state, 1857, reg_1857 & ~(1 << 15));
 500
 501		dib7000p_write_word(state, 1856, reg_1856 | ((bw->pll_ratio & 0x3f) << 6) | (bw->pll_prediv & 0x3f));
 502
 503		/* write new system clk into P_sec_len */
 504		internal = dib7000p_get_internal_freq(state);
 505		xtal = (internal / loopdiv) * prediv;
 506		internal = 1000 * (xtal / bw->pll_prediv) * bw->pll_ratio;	/* new internal */
 507		dib7000p_write_word(state, 18, (u16) ((internal >> 16) & 0xffff));
 508		dib7000p_write_word(state, 19, (u16) (internal & 0xffff));
 509
 510		dib7000p_write_word(state, 1857, reg_1857 | (1 << 15));
 511
 512		while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
 513			dprintk("Waiting for PLL to lock\n");
 514
 515		return 0;
 516	}
 517	return -EIO;
 518}
 519
 520static int dib7000p_reset_gpio(struct dib7000p_state *st)
 521{
 522	/* reset the GPIOs */
 523	dprintk("gpio dir: %x: val: %x, pwm_pos: %x\n", st->gpio_dir, st->gpio_val, st->cfg.gpio_pwm_pos);
 524
 525	dib7000p_write_word(st, 1029, st->gpio_dir);
 526	dib7000p_write_word(st, 1030, st->gpio_val);
 527
 528	/* TODO 1031 is P_gpio_od */
 529
 530	dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos);
 531
 532	dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div);
 533	return 0;
 534}
 535
 536static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
 537{
 538	st->gpio_dir = dib7000p_read_word(st, 1029);
 539	st->gpio_dir &= ~(1 << num);	/* reset the direction bit */
 540	st->gpio_dir |= (dir & 0x1) << num;	/* set the new direction */
 541	dib7000p_write_word(st, 1029, st->gpio_dir);
 542
 543	st->gpio_val = dib7000p_read_word(st, 1030);
 544	st->gpio_val &= ~(1 << num);	/* reset the direction bit */
 545	st->gpio_val |= (val & 0x01) << num;	/* set the new value */
 546	dib7000p_write_word(st, 1030, st->gpio_val);
 547
 548	return 0;
 549}
 550
 551static int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
 552{
 553	struct dib7000p_state *state = demod->demodulator_priv;
 554	return dib7000p_cfg_gpio(state, num, dir, val);
 555}
 556
 557static u16 dib7000p_defaults[] = {
 558	// auto search configuration
 559	3, 2,
 560	0x0004,
 561	(1<<3)|(1<<11)|(1<<12)|(1<<13),
 562	0x0814,			/* Equal Lock */
 563
 564	12, 6,
 565	0x001b,
 566	0x7740,
 567	0x005b,
 568	0x8d80,
 569	0x01c9,
 570	0xc380,
 571	0x0000,
 572	0x0080,
 573	0x0000,
 574	0x0090,
 575	0x0001,
 576	0xd4c0,
 577
 578	1, 26,
 579	0x6680,
 580
 581	/* set ADC level to -16 */
 582	11, 79,
 583	(1 << 13) - 825 - 117,
 584	(1 << 13) - 837 - 117,
 585	(1 << 13) - 811 - 117,
 586	(1 << 13) - 766 - 117,
 587	(1 << 13) - 737 - 117,
 588	(1 << 13) - 693 - 117,
 589	(1 << 13) - 648 - 117,
 590	(1 << 13) - 619 - 117,
 591	(1 << 13) - 575 - 117,
 592	(1 << 13) - 531 - 117,
 593	(1 << 13) - 501 - 117,
 594
 595	1, 142,
 596	0x0410,
 597
 598	/* disable power smoothing */
 599	8, 145,
 600	0,
 601	0,
 602	0,
 603	0,
 604	0,
 605	0,
 606	0,
 607	0,
 608
 609	1, 154,
 610	1 << 13,
 611
 612	1, 168,
 613	0x0ccd,
 614
 615	1, 183,
 616	0x200f,
 617
 618	1, 212,
 619		0x169,
 620
 621	5, 187,
 622	0x023d,
 623	0x00a4,
 624	0x00a4,
 625	0x7ff0,
 626	0x3ccc,
 627
 628	1, 198,
 629	0x800,
 630
 631	1, 222,
 632	0x0010,
 633
 634	1, 235,
 635	0x0062,
 636
 637	0,
 638};
 639
 640static void dib7000p_reset_stats(struct dvb_frontend *fe);
 641
 642static int dib7000p_demod_reset(struct dib7000p_state *state)
 643{
 644	dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
 645
 646	if (state->version == SOC7090)
 647		dibx000_reset_i2c_master(&state->i2c_master);
 648
 649	dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE);
 650
 651	/* restart all parts */
 652	dib7000p_write_word(state, 770, 0xffff);
 653	dib7000p_write_word(state, 771, 0xffff);
 654	dib7000p_write_word(state, 772, 0x001f);
 655	dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3)));
 656
 657	dib7000p_write_word(state, 770, 0);
 658	dib7000p_write_word(state, 771, 0);
 659	dib7000p_write_word(state, 772, 0);
 660	dib7000p_write_word(state, 1280, 0);
 661
 662	if (state->version != SOC7090) {
 663		dib7000p_write_word(state,  898, 0x0003);
 664		dib7000p_write_word(state,  898, 0);
 665	}
 666
 667	/* default */
 668	dib7000p_reset_pll(state);
 669
 670	if (dib7000p_reset_gpio(state) != 0)
 671		dprintk("GPIO reset was not successful.\n");
 672
 673	if (state->version == SOC7090) {
 674		dib7000p_write_word(state, 899, 0);
 675
 676		/* impulse noise */
 677		dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */
 678		dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */
 679		dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */
 680		dib7000p_write_word(state, 273, (0<<6) | 30);
 681	}
 682	if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
 683		dprintk("OUTPUT_MODE could not be reset.\n");
 684
 685	dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
 686	dib7000p_sad_calib(state);
 687	dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
 688
 689	/* unforce divstr regardless whether i2c enumeration was done or not */
 690	dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1));
 691
 692	dib7000p_set_bandwidth(state, 8000);
 693
 694	if (state->version == SOC7090) {
 695		dib7000p_write_word(state, 36, 0x0755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
 696	} else {
 697		if (state->cfg.tuner_is_baseband)
 698			dib7000p_write_word(state, 36, 0x0755);
 699		else
 700			dib7000p_write_word(state, 36, 0x1f55);
 701	}
 702
 703	dib7000p_write_tab(state, dib7000p_defaults);
 704	if (state->version != SOC7090) {
 705		dib7000p_write_word(state, 901, 0x0006);
 706		dib7000p_write_word(state, 902, (3 << 10) | (1 << 6));
 707		dib7000p_write_word(state, 905, 0x2c8e);
 708	}
 709
 710	dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
 711
 712	return 0;
 713}
 714
 715static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
 716{
 717	u16 tmp = 0;
 718	tmp = dib7000p_read_word(state, 903);
 719	dib7000p_write_word(state, 903, (tmp | 0x1));
 720	tmp = dib7000p_read_word(state, 900);
 721	dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6));
 722}
 723
 724static void dib7000p_restart_agc(struct dib7000p_state *state)
 725{
 726	// P_restart_iqc & P_restart_agc
 727	dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));
 728	dib7000p_write_word(state, 770, 0x0000);
 729}
 730
 731static int dib7000p_update_lna(struct dib7000p_state *state)
 732{
 733	u16 dyn_gain;
 734
 735	if (state->cfg.update_lna) {
 736		dyn_gain = dib7000p_read_word(state, 394);
 737		if (state->cfg.update_lna(&state->demod, dyn_gain)) {
 738			dib7000p_restart_agc(state);
 739			return 1;
 740		}
 741	}
 742
 743	return 0;
 744}
 745
 746static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
 747{
 748	struct dibx000_agc_config *agc = NULL;
 749	int i;
 750	if (state->current_band == band && state->current_agc != NULL)
 751		return 0;
 752	state->current_band = band;
 753
 754	for (i = 0; i < state->cfg.agc_config_count; i++)
 755		if (state->cfg.agc[i].band_caps & band) {
 756			agc = &state->cfg.agc[i];
 757			break;
 758		}
 759
 760	if (agc == NULL) {
 761		dprintk("no valid AGC configuration found for band 0x%02x\n", band);
 762		return -EINVAL;
 763	}
 764
 765	state->current_agc = agc;
 766
 767	/* AGC */
 768	dib7000p_write_word(state, 75, agc->setup);
 769	dib7000p_write_word(state, 76, agc->inv_gain);
 770	dib7000p_write_word(state, 77, agc->time_stabiliz);
 771	dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
 772
 773	// Demod AGC loop configuration
 774	dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
 775	dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
 776
 777	/* AGC continued */
 778	dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d\n",
 779		state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
 780
 781	if (state->wbd_ref != 0)
 782		dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
 783	else
 784		dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
 785
 786	dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
 787
 788	dib7000p_write_word(state, 107, agc->agc1_max);
 789	dib7000p_write_word(state, 108, agc->agc1_min);
 790	dib7000p_write_word(state, 109, agc->agc2_max);
 791	dib7000p_write_word(state, 110, agc->agc2_min);
 792	dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
 793	dib7000p_write_word(state, 112, agc->agc1_pt3);
 794	dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
 795	dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
 796	dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
 797	return 0;
 798}
 799
 800static int dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz)
 801{
 802	u32 internal = dib7000p_get_internal_freq(state);
 803	s32 unit_khz_dds_val;
 804	u32 abs_offset_khz = abs(offset_khz);
 805	u32 dds = state->cfg.bw->ifreq & 0x1ffffff;
 806	u8 invert = !!(state->cfg.bw->ifreq & (1 << 25));
 807	if (internal == 0) {
 808		pr_warn("DIB7000P: dib7000p_get_internal_freq returned 0\n");
 809		return -1;
 810	}
 811	/* 2**26 / Fsampling is the unit 1KHz offset */
 812	unit_khz_dds_val = 67108864 / (internal);
 813
 814	dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d\n", offset_khz, internal, invert);
 815
 816	if (offset_khz < 0)
 817		unit_khz_dds_val *= -1;
 818
 819	/* IF tuner */
 820	if (invert)
 821		dds -= (abs_offset_khz * unit_khz_dds_val);	/* /100 because of /100 on the unit_khz_dds_val line calc for better accuracy */
 822	else
 823		dds += (abs_offset_khz * unit_khz_dds_val);
 824
 825	if (abs_offset_khz <= (internal / 2)) {	/* Max dds offset is the half of the demod freq */
 826		dib7000p_write_word(state, 21, (u16) (((dds >> 16) & 0x1ff) | (0 << 10) | (invert << 9)));
 827		dib7000p_write_word(state, 22, (u16) (dds & 0xffff));
 828	}
 829	return 0;
 830}
 831
 832static int dib7000p_agc_startup(struct dvb_frontend *demod)
 833{
 834	struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
 835	struct dib7000p_state *state = demod->demodulator_priv;
 836	int ret = -1;
 837	u8 *agc_state = &state->agc_state;
 838	u8 agc_split;
 839	u16 reg;
 840	u32 upd_demod_gain_period = 0x1000;
 841	s32 frequency_offset = 0;
 842
 843	switch (state->agc_state) {
 844	case 0:
 845		dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
 846		if (state->version == SOC7090) {
 847			reg = dib7000p_read_word(state, 0x79b) & 0xff00;
 848			dib7000p_write_word(state, 0x79a, upd_demod_gain_period & 0xFFFF);	/* lsb */
 849			dib7000p_write_word(state, 0x79b, reg | (1 << 14) | ((upd_demod_gain_period >> 16) & 0xFF));
 850
 851			/* enable adc i & q */
 852			reg = dib7000p_read_word(state, 0x780);
 853			dib7000p_write_word(state, 0x780, (reg | (0x3)) & (~(1 << 7)));
 854		} else {
 855			dib7000p_set_adc_state(state, DIBX000_ADC_ON);
 856			dib7000p_pll_clk_cfg(state);
 857		}
 858
 859		if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency / 1000)) != 0)
 860			return -1;
 861
 862		if (demod->ops.tuner_ops.get_frequency) {
 863			u32 frequency_tuner;
 864
 865			demod->ops.tuner_ops.get_frequency(demod, &frequency_tuner);
 866			frequency_offset = (s32)frequency_tuner / 1000 - ch->frequency / 1000;
 867		}
 868
 869		if (dib7000p_set_dds(state, frequency_offset) < 0)
 870			return -1;
 871
 872		ret = 7;
 873		(*agc_state)++;
 874		break;
 875
 876	case 1:
 877		if (state->cfg.agc_control)
 878			state->cfg.agc_control(&state->demod, 1);
 879
 880		dib7000p_write_word(state, 78, 32768);
 881		if (!state->current_agc->perform_agc_softsplit) {
 882			/* we are using the wbd - so slow AGC startup */
 883			/* force 0 split on WBD and restart AGC */
 884			dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
 885			(*agc_state)++;
 886			ret = 5;
 887		} else {
 888			/* default AGC startup */
 889			(*agc_state) = 4;
 890			/* wait AGC rough lock time */
 891			ret = 7;
 892		}
 893
 894		dib7000p_restart_agc(state);
 895		break;
 896
 897	case 2:		/* fast split search path after 5sec */
 898		dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4));	/* freeze AGC loop */
 899		dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8));	/* fast split search 0.25kHz */
 900		(*agc_state)++;
 901		ret = 14;
 902		break;
 903
 904	case 3:		/* split search ended */
 905		agc_split = (u8) dib7000p_read_word(state, 396);	/* store the split value for the next time */
 906		dib7000p_write_word(state, 78, dib7000p_read_word(state, 394));	/* set AGC gain start value */
 907
 908		dib7000p_write_word(state, 75, state->current_agc->setup);	/* std AGC loop */
 909		dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split);	/* standard split search */
 910
 911		dib7000p_restart_agc(state);
 912
 913		dprintk("SPLIT %p: %u\n", demod, agc_split);
 914
 915		(*agc_state)++;
 916		ret = 5;
 917		break;
 918
 919	case 4:		/* LNA startup */
 920		ret = 7;
 921
 922		if (dib7000p_update_lna(state))
 923			ret = 5;
 924		else
 925			(*agc_state)++;
 926		break;
 927
 928	case 5:
 929		if (state->cfg.agc_control)
 930			state->cfg.agc_control(&state->demod, 0);
 931		(*agc_state)++;
 932		break;
 933	default:
 934		break;
 935	}
 936	return ret;
 937}
 938
 939static void dib7000p_update_timf(struct dib7000p_state *state)
 940{
 941	u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428);
 942	state->timf = timf * 160 / (state->current_bandwidth / 50);
 943	dib7000p_write_word(state, 23, (u16) (timf >> 16));
 944	dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
 945	dprintk("updated timf_frequency: %d (default: %d)\n", state->timf, state->cfg.bw->timf);
 946
 947}
 948
 949static u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
 950{
 951	struct dib7000p_state *state = fe->demodulator_priv;
 952	switch (op) {
 953	case DEMOD_TIMF_SET:
 954		state->timf = timf;
 955		break;
 956	case DEMOD_TIMF_UPDATE:
 957		dib7000p_update_timf(state);
 958		break;
 959	case DEMOD_TIMF_GET:
 960		break;
 961	}
 962	dib7000p_set_bandwidth(state, state->current_bandwidth);
 963	return state->timf;
 964}
 965
 966static void dib7000p_set_channel(struct dib7000p_state *state,
 967				 struct dtv_frontend_properties *ch, u8 seq)
 968{
 969	u16 value, est[4];
 970
 971	dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
 972
 973	/* nfft, guard, qam, alpha */
 974	value = 0;
 975	switch (ch->transmission_mode) {
 976	case TRANSMISSION_MODE_2K:
 977		value |= (0 << 7);
 978		break;
 979	case TRANSMISSION_MODE_4K:
 980		value |= (2 << 7);
 981		break;
 982	default:
 983	case TRANSMISSION_MODE_8K:
 984		value |= (1 << 7);
 985		break;
 986	}
 987	switch (ch->guard_interval) {
 988	case GUARD_INTERVAL_1_32:
 989		value |= (0 << 5);
 990		break;
 991	case GUARD_INTERVAL_1_16:
 992		value |= (1 << 5);
 993		break;
 994	case GUARD_INTERVAL_1_4:
 995		value |= (3 << 5);
 996		break;
 997	default:
 998	case GUARD_INTERVAL_1_8:
 999		value |= (2 << 5);
1000		break;
1001	}
1002	switch (ch->modulation) {
1003	case QPSK:
1004		value |= (0 << 3);
1005		break;
1006	case QAM_16:
1007		value |= (1 << 3);
1008		break;
1009	default:
1010	case QAM_64:
1011		value |= (2 << 3);
1012		break;
1013	}
1014	switch (HIERARCHY_1) {
1015	case HIERARCHY_2:
1016		value |= 2;
1017		break;
1018	case HIERARCHY_4:
1019		value |= 4;
1020		break;
1021	default:
1022	case HIERARCHY_1:
1023		value |= 1;
1024		break;
1025	}
1026	dib7000p_write_word(state, 0, value);
1027	dib7000p_write_word(state, 5, (seq << 4) | 1);	/* do not force tps, search list 0 */
1028
1029	/* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
1030	value = 0;
1031	if (1 != 0)
1032		value |= (1 << 6);
1033	if (ch->hierarchy == 1)
1034		value |= (1 << 4);
1035	if (1 == 1)
1036		value |= 1;
1037	switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) {
1038	case FEC_2_3:
1039		value |= (2 << 1);
1040		break;
1041	case FEC_3_4:
1042		value |= (3 << 1);
1043		break;
1044	case FEC_5_6:
1045		value |= (5 << 1);
1046		break;
1047	case FEC_7_8:
1048		value |= (7 << 1);
1049		break;
1050	default:
1051	case FEC_1_2:
1052		value |= (1 << 1);
1053		break;
1054	}
1055	dib7000p_write_word(state, 208, value);
1056
1057	/* offset loop parameters */
1058	dib7000p_write_word(state, 26, 0x6680);
1059	dib7000p_write_word(state, 32, 0x0003);
1060	dib7000p_write_word(state, 29, 0x1273);
1061	dib7000p_write_word(state, 33, 0x0005);
1062
1063	/* P_dvsy_sync_wait */
1064	switch (ch->transmission_mode) {
1065	case TRANSMISSION_MODE_8K:
1066		value = 256;
1067		break;
1068	case TRANSMISSION_MODE_4K:
1069		value = 128;
1070		break;
1071	case TRANSMISSION_MODE_2K:
1072	default:
1073		value = 64;
1074		break;
1075	}
1076	switch (ch->guard_interval) {
1077	case GUARD_INTERVAL_1_16:
1078		value *= 2;
1079		break;
1080	case GUARD_INTERVAL_1_8:
1081		value *= 4;
1082		break;
1083	case GUARD_INTERVAL_1_4:
1084		value *= 8;
1085		break;
1086	default:
1087	case GUARD_INTERVAL_1_32:
1088		value *= 1;
1089		break;
1090	}
1091	if (state->cfg.diversity_delay == 0)
1092		state->div_sync_wait = (value * 3) / 2 + 48;
1093	else
1094		state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay;
1095
1096	/* deactivate the possibility of diversity reception if extended interleaver */
1097	state->div_force_off = !1 && ch->transmission_mode != TRANSMISSION_MODE_8K;
1098	dib7000p_set_diversity_in(&state->demod, state->div_state);
1099
1100	/* channel estimation fine configuration */
1101	switch (ch->modulation) {
1102	case QAM_64:
1103		est[0] = 0x0148;	/* P_adp_regul_cnt 0.04 */
1104		est[1] = 0xfff0;	/* P_adp_noise_cnt -0.002 */
1105		est[2] = 0x00a4;	/* P_adp_regul_ext 0.02 */
1106		est[3] = 0xfff8;	/* P_adp_noise_ext -0.001 */
1107		break;
1108	case QAM_16:
1109		est[0] = 0x023d;	/* P_adp_regul_cnt 0.07 */
1110		est[1] = 0xffdf;	/* P_adp_noise_cnt -0.004 */
1111		est[2] = 0x00a4;	/* P_adp_regul_ext 0.02 */
1112		est[3] = 0xfff0;	/* P_adp_noise_ext -0.002 */
1113		break;
1114	default:
1115		est[0] = 0x099a;	/* P_adp_regul_cnt 0.3 */
1116		est[1] = 0xffae;	/* P_adp_noise_cnt -0.01 */
1117		est[2] = 0x0333;	/* P_adp_regul_ext 0.1 */
1118		est[3] = 0xfff8;	/* P_adp_noise_ext -0.002 */
1119		break;
1120	}
1121	for (value = 0; value < 4; value++)
1122		dib7000p_write_word(state, 187 + value, est[value]);
1123}
1124
1125static int dib7000p_autosearch_start(struct dvb_frontend *demod)
1126{
1127	struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
1128	struct dib7000p_state *state = demod->demodulator_priv;
1129	struct dtv_frontend_properties schan;
1130	u32 value, factor;
1131	u32 internal = dib7000p_get_internal_freq(state);
1132
1133	schan = *ch;
1134	schan.modulation = QAM_64;
1135	schan.guard_interval = GUARD_INTERVAL_1_32;
1136	schan.transmission_mode = TRANSMISSION_MODE_8K;
1137	schan.code_rate_HP = FEC_2_3;
1138	schan.code_rate_LP = FEC_3_4;
1139	schan.hierarchy = 0;
1140
1141	dib7000p_set_channel(state, &schan, 7);
1142
1143	factor = BANDWIDTH_TO_KHZ(ch->bandwidth_hz);
1144	if (factor >= 5000) {
1145		if (state->version == SOC7090)
1146			factor = 2;
1147		else
1148			factor = 1;
1149	} else
1150		factor = 6;
1151
1152	value = 30 * internal * factor;
1153	dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff));
1154	dib7000p_write_word(state, 7, (u16) (value & 0xffff));
1155	value = 100 * internal * factor;
1156	dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff));
1157	dib7000p_write_word(state, 9, (u16) (value & 0xffff));
1158	value = 500 * internal * factor;
1159	dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff));
1160	dib7000p_write_word(state, 11, (u16) (value & 0xffff));
1161
1162	value = dib7000p_read_word(state, 0);
1163	dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
1164	dib7000p_read_word(state, 1284);
1165	dib7000p_write_word(state, 0, (u16) value);
1166
1167	return 0;
1168}
1169
1170static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
1171{
1172	struct dib7000p_state *state = demod->demodulator_priv;
1173	u16 irq_pending = dib7000p_read_word(state, 1284);
1174
1175	if (irq_pending & 0x1)
1176		return 1;
1177
1178	if (irq_pending & 0x2)
1179		return 2;
1180
1181	return 0;
1182}
1183
1184static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
1185{
1186	static const s16 notch[] = { 16143, 14402, 12238, 9713, 6902, 3888, 759, -2392 };
1187	static const u8 sine[] = { 0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
1188		24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
1189		53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
1190		82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
1191		107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
1192		128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
1193		147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
1194		166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
1195		183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
1196		199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
1197		213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
1198		225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
1199		235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
1200		244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
1201		250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
1202		254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1203		255, 255, 255, 255, 255, 255
1204	};
1205
1206	u32 xtal = state->cfg.bw->xtal_hz / 1000;
1207	int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz;
1208	int k;
1209	int coef_re[8], coef_im[8];
1210	int bw_khz = bw;
1211	u32 pha;
1212
1213	dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)\n", f_rel, rf_khz, xtal);
1214
1215	if (f_rel < -bw_khz / 2 || f_rel > bw_khz / 2)
1216		return;
1217
1218	bw_khz /= 100;
1219
1220	dib7000p_write_word(state, 142, 0x0610);
1221
1222	for (k = 0; k < 8; k++) {
1223		pha = ((f_rel * (k + 1) * 112 * 80 / bw_khz) / 1000) & 0x3ff;
1224
1225		if (pha == 0) {
1226			coef_re[k] = 256;
1227			coef_im[k] = 0;
1228		} else if (pha < 256) {
1229			coef_re[k] = sine[256 - (pha & 0xff)];
1230			coef_im[k] = sine[pha & 0xff];
1231		} else if (pha == 256) {
1232			coef_re[k] = 0;
1233			coef_im[k] = 256;
1234		} else if (pha < 512) {
1235			coef_re[k] = -sine[pha & 0xff];
1236			coef_im[k] = sine[256 - (pha & 0xff)];
1237		} else if (pha == 512) {
1238			coef_re[k] = -256;
1239			coef_im[k] = 0;
1240		} else if (pha < 768) {
1241			coef_re[k] = -sine[256 - (pha & 0xff)];
1242			coef_im[k] = -sine[pha & 0xff];
1243		} else if (pha == 768) {
1244			coef_re[k] = 0;
1245			coef_im[k] = -256;
1246		} else {
1247			coef_re[k] = sine[pha & 0xff];
1248			coef_im[k] = -sine[256 - (pha & 0xff)];
1249		}
1250
1251		coef_re[k] *= notch[k];
1252		coef_re[k] += (1 << 14);
1253		if (coef_re[k] >= (1 << 24))
1254			coef_re[k] = (1 << 24) - 1;
1255		coef_re[k] /= (1 << 15);
1256
1257		coef_im[k] *= notch[k];
1258		coef_im[k] += (1 << 14);
1259		if (coef_im[k] >= (1 << 24))
1260			coef_im[k] = (1 << 24) - 1;
1261		coef_im[k] /= (1 << 15);
1262
1263		dprintk("PALF COEF: %d re: %d im: %d\n", k, coef_re[k], coef_im[k]);
1264
1265		dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1266		dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
1267		dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1268	}
1269	dib7000p_write_word(state, 143, 0);
1270}
1271
1272static int dib7000p_tune(struct dvb_frontend *demod)
1273{
1274	struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
1275	struct dib7000p_state *state = demod->demodulator_priv;
1276	u16 tmp = 0;
1277
1278	if (ch != NULL)
1279		dib7000p_set_channel(state, ch, 0);
1280	else
1281		return -EINVAL;
1282
1283	// restart demod
1284	dib7000p_write_word(state, 770, 0x4000);
1285	dib7000p_write_word(state, 770, 0x0000);
1286	msleep(45);
1287
1288	/* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
1289	tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
1290	if (state->sfn_workaround_active) {
1291		dprintk("SFN workaround is active\n");
1292		tmp |= (1 << 9);
1293		dib7000p_write_word(state, 166, 0x4000);
1294	} else {
1295		dib7000p_write_word(state, 166, 0x0000);
1296	}
1297	dib7000p_write_word(state, 29, tmp);
1298
1299	// never achieved a lock with that bandwidth so far - wait for osc-freq to update
1300	if (state->timf == 0)
1301		msleep(200);
1302
1303	/* offset loop parameters */
1304
1305	/* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1306	tmp = (6 << 8) | 0x80;
1307	switch (ch->transmission_mode) {
1308	case TRANSMISSION_MODE_2K:
1309		tmp |= (2 << 12);
1310		break;
1311	case TRANSMISSION_MODE_4K:
1312		tmp |= (3 << 12);
1313		break;
1314	default:
1315	case TRANSMISSION_MODE_8K:
1316		tmp |= (4 << 12);
1317		break;
1318	}
1319	dib7000p_write_word(state, 26, tmp);	/* timf_a(6xxx) */
1320
1321	/* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1322	tmp = (0 << 4);
1323	switch (ch->transmission_mode) {
1324	case TRANSMISSION_MODE_2K:
1325		tmp |= 0x6;
1326		break;
1327	case TRANSMISSION_MODE_4K:
1328		tmp |= 0x7;
1329		break;
1330	default:
1331	case TRANSMISSION_MODE_8K:
1332		tmp |= 0x8;
1333		break;
1334	}
1335	dib7000p_write_word(state, 32, tmp);
1336
1337	/* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1338	tmp = (0 << 4);
1339	switch (ch->transmission_mode) {
1340	case TRANSMISSION_MODE_2K:
1341		tmp |= 0x6;
1342		break;
1343	case TRANSMISSION_MODE_4K:
1344		tmp |= 0x7;
1345		break;
1346	default:
1347	case TRANSMISSION_MODE_8K:
1348		tmp |= 0x8;
1349		break;
1350	}
1351	dib7000p_write_word(state, 33, tmp);
1352
1353	tmp = dib7000p_read_word(state, 509);
1354	if (!((tmp >> 6) & 0x1)) {
1355		/* restart the fec */
1356		tmp = dib7000p_read_word(state, 771);
1357		dib7000p_write_word(state, 771, tmp | (1 << 1));
1358		dib7000p_write_word(state, 771, tmp);
1359		msleep(40);
1360		tmp = dib7000p_read_word(state, 509);
1361	}
1362	// we achieved a lock - it's time to update the osc freq
1363	if ((tmp >> 6) & 0x1) {
1364		dib7000p_update_timf(state);
1365		/* P_timf_alpha += 2 */
1366		tmp = dib7000p_read_word(state, 26);
1367		dib7000p_write_word(state, 26, (tmp & ~(0xf << 12)) | ((((tmp >> 12) & 0xf) + 5) << 12));
1368	}
1369
1370	if (state->cfg.spur_protect)
1371		dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
1372
1373	dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
1374
1375	dib7000p_reset_stats(demod);
1376
1377	return 0;
1378}
1379
1380static int dib7000p_wakeup(struct dvb_frontend *demod)
1381{
1382	struct dib7000p_state *state = demod->demodulator_priv;
1383	dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
1384	dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1385	if (state->version == SOC7090)
1386		dib7000p_sad_calib(state);
1387	return 0;
1388}
1389
1390static int dib7000p_sleep(struct dvb_frontend *demod)
1391{
1392	struct dib7000p_state *state = demod->demodulator_priv;
1393	if (state->version == SOC7090)
1394		return dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1395	return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1396}
1397
1398static int dib7000p_identify(struct dib7000p_state *st)
1399{
1400	u16 value;
1401	dprintk("checking demod on I2C address: %d (%x)\n", st->i2c_addr, st->i2c_addr);
1402
1403	if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
1404		dprintk("wrong Vendor ID (read=0x%x)\n", value);
1405		return -EREMOTEIO;
1406	}
1407
1408	if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
1409		dprintk("wrong Device ID (%x)\n", value);
1410		return -EREMOTEIO;
1411	}
1412
1413	return 0;
1414}
1415
1416static int dib7000p_get_frontend(struct dvb_frontend *fe,
1417				 struct dtv_frontend_properties *fep)
1418{
1419	struct dib7000p_state *state = fe->demodulator_priv;
1420	u16 tps = dib7000p_read_word(state, 463);
1421
1422	fep->inversion = INVERSION_AUTO;
1423
1424	fep->bandwidth_hz = BANDWIDTH_TO_HZ(state->current_bandwidth);
1425
1426	switch ((tps >> 8) & 0x3) {
1427	case 0:
1428		fep->transmission_mode = TRANSMISSION_MODE_2K;
1429		break;
1430	case 1:
1431		fep->transmission_mode = TRANSMISSION_MODE_8K;
1432		break;
1433	/* case 2: fep->transmission_mode = TRANSMISSION_MODE_4K; break; */
1434	}
1435
1436	switch (tps & 0x3) {
1437	case 0:
1438		fep->guard_interval = GUARD_INTERVAL_1_32;
1439		break;
1440	case 1:
1441		fep->guard_interval = GUARD_INTERVAL_1_16;
1442		break;
1443	case 2:
1444		fep->guard_interval = GUARD_INTERVAL_1_8;
1445		break;
1446	case 3:
1447		fep->guard_interval = GUARD_INTERVAL_1_4;
1448		break;
1449	}
1450
1451	switch ((tps >> 14) & 0x3) {
1452	case 0:
1453		fep->modulation = QPSK;
1454		break;
1455	case 1:
1456		fep->modulation = QAM_16;
1457		break;
1458	case 2:
1459	default:
1460		fep->modulation = QAM_64;
1461		break;
1462	}
1463
1464	/* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1465	/* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1466
1467	fep->hierarchy = HIERARCHY_NONE;
1468	switch ((tps >> 5) & 0x7) {
1469	case 1:
1470		fep->code_rate_HP = FEC_1_2;
1471		break;
1472	case 2:
1473		fep->code_rate_HP = FEC_2_3;
1474		break;
1475	case 3:
1476		fep->code_rate_HP = FEC_3_4;
1477		break;
1478	case 5:
1479		fep->code_rate_HP = FEC_5_6;
1480		break;
1481	case 7:
1482	default:
1483		fep->code_rate_HP = FEC_7_8;
1484		break;
1485
1486	}
1487
1488	switch ((tps >> 2) & 0x7) {
1489	case 1:
1490		fep->code_rate_LP = FEC_1_2;
1491		break;
1492	case 2:
1493		fep->code_rate_LP = FEC_2_3;
1494		break;
1495	case 3:
1496		fep->code_rate_LP = FEC_3_4;
1497		break;
1498	case 5:
1499		fep->code_rate_LP = FEC_5_6;
1500		break;
1501	case 7:
1502	default:
1503		fep->code_rate_LP = FEC_7_8;
1504		break;
1505	}
1506
1507	/* native interleaver: (dib7000p_read_word(state, 464) >>  5) & 0x1 */
1508
1509	return 0;
1510}
1511
1512static int dib7000p_set_frontend(struct dvb_frontend *fe)
1513{
1514	struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
1515	struct dib7000p_state *state = fe->demodulator_priv;
1516	int time, ret;
1517
1518	if (state->version == SOC7090)
1519		dib7090_set_diversity_in(fe, 0);
1520	else
1521		dib7000p_set_output_mode(state, OUTMODE_HIGH_Z);
1522
1523	/* maybe the parameter has been changed */
1524	state->sfn_workaround_active = buggy_sfn_workaround;
1525
1526	if (fe->ops.tuner_ops.set_params)
1527		fe->ops.tuner_ops.set_params(fe);
1528
1529	/* start up the AGC */
1530	state->agc_state = 0;
1531	do {
1532		time = dib7000p_agc_startup(fe);
1533		if (time != -1)
1534			msleep(time);
1535	} while (time != -1);
1536
1537	if (fep->transmission_mode == TRANSMISSION_MODE_AUTO ||
1538		fep->guard_interval == GUARD_INTERVAL_AUTO || fep->modulation == QAM_AUTO || fep->code_rate_HP == FEC_AUTO) {
1539		int i = 800, found;
1540
1541		dib7000p_autosearch_start(fe);
1542		do {
1543			msleep(1);
1544			found = dib7000p_autosearch_is_irq(fe);
1545		} while (found == 0 && i--);
1546
1547		dprintk("autosearch returns: %d\n", found);
1548		if (found == 0 || found == 1)
1549			return 0;
1550
1551		dib7000p_get_frontend(fe, fep);
1552	}
1553
1554	ret = dib7000p_tune(fe);
1555
1556	/* make this a config parameter */
1557	if (state->version == SOC7090) {
1558		dib7090_set_output_mode(fe, state->cfg.output_mode);
1559		if (state->cfg.enMpegOutput == 0) {
1560			dib7090_setDibTxMux(state, MPEG_ON_DIBTX);
1561			dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
1562		}
1563	} else
1564		dib7000p_set_output_mode(state, state->cfg.output_mode);
1565
1566	return ret;
1567}
1568
1569static int dib7000p_get_stats(struct dvb_frontend *fe, enum fe_status stat);
1570
1571static int dib7000p_read_status(struct dvb_frontend *fe, enum fe_status *stat)
1572{
1573	struct dib7000p_state *state = fe->demodulator_priv;
1574	u16 lock = dib7000p_read_word(state, 509);
1575
1576	*stat = 0;
1577
1578	if (lock & 0x8000)
1579		*stat |= FE_HAS_SIGNAL;
1580	if (lock & 0x3000)
1581		*stat |= FE_HAS_CARRIER;
1582	if (lock & 0x0100)
1583		*stat |= FE_HAS_VITERBI;
1584	if (lock & 0x0010)
1585		*stat |= FE_HAS_SYNC;
1586	if ((lock & 0x0038) == 0x38)
1587		*stat |= FE_HAS_LOCK;
1588
1589	dib7000p_get_stats(fe, *stat);
1590
1591	return 0;
1592}
1593
1594static int dib7000p_read_ber(struct dvb_frontend *fe, u32 * ber)
1595{
1596	struct dib7000p_state *state = fe->demodulator_priv;
1597	*ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501);
1598	return 0;
1599}
1600
1601static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
1602{
1603	struct dib7000p_state *state = fe->demodulator_priv;
1604	*unc = dib7000p_read_word(state, 506);
1605	return 0;
1606}
1607
1608static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
1609{
1610	struct dib7000p_state *state = fe->demodulator_priv;
1611	u16 val = dib7000p_read_word(state, 394);
1612	*strength = 65535 - val;
1613	return 0;
1614}
1615
1616static u32 dib7000p_get_snr(struct dvb_frontend *fe)
1617{
1618	struct dib7000p_state *state = fe->demodulator_priv;
1619	u16 val;
1620	s32 signal_mant, signal_exp, noise_mant, noise_exp;
1621	u32 result = 0;
1622
1623	val = dib7000p_read_word(state, 479);
1624	noise_mant = (val >> 4) & 0xff;
1625	noise_exp = ((val & 0xf) << 2);
1626	val = dib7000p_read_word(state, 480);
1627	noise_exp += ((val >> 14) & 0x3);
1628	if ((noise_exp & 0x20) != 0)
1629		noise_exp -= 0x40;
1630
1631	signal_mant = (val >> 6) & 0xFF;
1632	signal_exp = (val & 0x3F);
1633	if ((signal_exp & 0x20) != 0)
1634		signal_exp -= 0x40;
1635
1636	if (signal_mant != 0)
1637		result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
1638	else
1639		result = intlog10(2) * 10 * signal_exp - 100;
1640
1641	if (noise_mant != 0)
1642		result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
1643	else
1644		result -= intlog10(2) * 10 * noise_exp - 100;
1645
1646	return result;
1647}
1648
1649static int dib7000p_read_snr(struct dvb_frontend *fe, u16 *snr)
1650{
1651	u32 result;
1652
1653	result = dib7000p_get_snr(fe);
1654
1655	*snr = result / ((1 << 24) / 10);
1656	return 0;
1657}
1658
1659static void dib7000p_reset_stats(struct dvb_frontend *demod)
1660{
1661	struct dib7000p_state *state = demod->demodulator_priv;
1662	struct dtv_frontend_properties *c = &demod->dtv_property_cache;
1663	u32 ucb;
1664
1665	memset(&c->strength, 0, sizeof(c->strength));
1666	memset(&c->cnr, 0, sizeof(c->cnr));
1667	memset(&c->post_bit_error, 0, sizeof(c->post_bit_error));
1668	memset(&c->post_bit_count, 0, sizeof(c->post_bit_count));
1669	memset(&c->block_error, 0, sizeof(c->block_error));
1670
1671	c->strength.len = 1;
1672	c->cnr.len = 1;
1673	c->block_error.len = 1;
1674	c->block_count.len = 1;
1675	c->post_bit_error.len = 1;
1676	c->post_bit_count.len = 1;
1677
1678	c->strength.stat[0].scale = FE_SCALE_DECIBEL;
1679	c->strength.stat[0].uvalue = 0;
1680
1681	c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1682	c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1683	c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1684	c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1685	c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1686
1687	dib7000p_read_unc_blocks(demod, &ucb);
1688
1689	state->old_ucb = ucb;
1690	state->ber_jiffies_stats = 0;
1691	state->per_jiffies_stats = 0;
1692}
1693
1694struct linear_segments {
1695	unsigned x;
1696	signed y;
1697};
1698
1699/*
1700 * Table to estimate signal strength in dBm.
1701 * This table should be empirically determinated by measuring the signal
1702 * strength generated by a RF generator directly connected into
1703 * a device.
1704 * This table was determinated by measuring the signal strength generated
1705 * by a DTA-2111 RF generator directly connected into a dib7000p device
1706 * (a Hauppauge Nova-TD stick), using a good quality 3 meters length
1707 * RC6 cable and good RC6 connectors, connected directly to antenna 1.
1708 * As the minimum output power of DTA-2111 is -31dBm, a 16 dBm attenuator
1709 * were used, for the lower power values.
1710 * The real value can actually be on other devices, or even at the
1711 * second antena input, depending on several factors, like if LNA
1712 * is enabled or not, if diversity is enabled, type of connectors, etc.
1713 * Yet, it is better to use this measure in dB than a random non-linear
1714 * percentage value, especially for antenna adjustments.
1715 * On my tests, the precision of the measure using this table is about
1716 * 0.5 dB, with sounds reasonable enough to adjust antennas.
1717 */
1718#define DB_OFFSET 131000
1719
1720static struct linear_segments strength_to_db_table[] = {
1721	{ 63630, DB_OFFSET - 20500},
1722	{ 62273, DB_OFFSET - 21000},
1723	{ 60162, DB_OFFSET - 22000},
1724	{ 58730, DB_OFFSET - 23000},
1725	{ 58294, DB_OFFSET - 24000},
1726	{ 57778, DB_OFFSET - 25000},
1727	{ 57320, DB_OFFSET - 26000},
1728	{ 56779, DB_OFFSET - 27000},
1729	{ 56293, DB_OFFSET - 28000},
1730	{ 55724, DB_OFFSET - 29000},
1731	{ 55145, DB_OFFSET - 30000},
1732	{ 54680, DB_OFFSET - 31000},
1733	{ 54293, DB_OFFSET - 32000},
1734	{ 53813, DB_OFFSET - 33000},
1735	{ 53427, DB_OFFSET - 34000},
1736	{ 52981, DB_OFFSET - 35000},
1737
1738	{ 52636, DB_OFFSET - 36000},
1739	{ 52014, DB_OFFSET - 37000},
1740	{ 51674, DB_OFFSET - 38000},
1741	{ 50692, DB_OFFSET - 39000},
1742	{ 49824, DB_OFFSET - 40000},
1743	{ 49052, DB_OFFSET - 41000},
1744	{ 48436, DB_OFFSET - 42000},
1745	{ 47836, DB_OFFSET - 43000},
1746	{ 47368, DB_OFFSET - 44000},
1747	{ 46468, DB_OFFSET - 45000},
1748	{ 45597, DB_OFFSET - 46000},
1749	{ 44586, DB_OFFSET - 47000},
1750	{ 43667, DB_OFFSET - 48000},
1751	{ 42673, DB_OFFSET - 49000},
1752	{ 41816, DB_OFFSET - 50000},
1753	{ 40876, DB_OFFSET - 51000},
1754	{     0,      0},
1755};
1756
1757static u32 interpolate_value(u32 value, struct linear_segments *segments,
1758			     unsigned len)
1759{
1760	u64 tmp64;
1761	u32 dx;
1762	s32 dy;
1763	int i, ret;
1764
1765	if (value >= segments[0].x)
1766		return segments[0].y;
1767	if (value < segments[len-1].x)
1768		return segments[len-1].y;
1769
1770	for (i = 1; i < len - 1; i++) {
1771		/* If value is identical, no need to interpolate */
1772		if (value == segments[i].x)
1773			return segments[i].y;
1774		if (value > segments[i].x)
1775			break;
1776	}
1777
1778	/* Linear interpolation between the two (x,y) points */
1779	dy = segments[i - 1].y - segments[i].y;
1780	dx = segments[i - 1].x - segments[i].x;
1781
1782	tmp64 = value - segments[i].x;
1783	tmp64 *= dy;
1784	do_div(tmp64, dx);
1785	ret = segments[i].y + tmp64;
1786
1787	return ret;
1788}
1789
1790/* FIXME: may require changes - this one was borrowed from dib8000 */
1791static u32 dib7000p_get_time_us(struct dvb_frontend *demod)
1792{
1793	struct dtv_frontend_properties *c = &demod->dtv_property_cache;
1794	u64 time_us, tmp64;
1795	u32 tmp, denom;
1796	int guard, rate_num, rate_denum = 1, bits_per_symbol;
1797	int interleaving = 0, fft_div;
1798
1799	switch (c->guard_interval) {
1800	case GUARD_INTERVAL_1_4:
1801		guard = 4;
1802		break;
1803	case GUARD_INTERVAL_1_8:
1804		guard = 8;
1805		break;
1806	case GUARD_INTERVAL_1_16:
1807		guard = 16;
1808		break;
1809	default:
1810	case GUARD_INTERVAL_1_32:
1811		guard = 32;
1812		break;
1813	}
1814
1815	switch (c->transmission_mode) {
1816	case TRANSMISSION_MODE_2K:
1817		fft_div = 4;
1818		break;
1819	case TRANSMISSION_MODE_4K:
1820		fft_div = 2;
1821		break;
1822	default:
1823	case TRANSMISSION_MODE_8K:
1824		fft_div = 1;
1825		break;
1826	}
1827
1828	switch (c->modulation) {
1829	case DQPSK:
1830	case QPSK:
1831		bits_per_symbol = 2;
1832		break;
1833	case QAM_16:
1834		bits_per_symbol = 4;
1835		break;
1836	default:
1837	case QAM_64:
1838		bits_per_symbol = 6;
1839		break;
1840	}
1841
1842	switch ((c->hierarchy == 0 || 1 == 1) ? c->code_rate_HP : c->code_rate_LP) {
1843	case FEC_1_2:
1844		rate_num = 1;
1845		rate_denum = 2;
1846		break;
1847	case FEC_2_3:
1848		rate_num = 2;
1849		rate_denum = 3;
1850		break;
1851	case FEC_3_4:
1852		rate_num = 3;
1853		rate_denum = 4;
1854		break;
1855	case FEC_5_6:
1856		rate_num = 5;
1857		rate_denum = 6;
1858		break;
1859	default:
1860	case FEC_7_8:
1861		rate_num = 7;
1862		rate_denum = 8;
1863		break;
1864	}
1865
1866	denom = bits_per_symbol * rate_num * fft_div * 384;
1867
1868	/*
1869	 * FIXME: check if the math makes sense. If so, fill the
1870	 * interleaving var.
1871	 */
1872
1873	/* If calculus gets wrong, wait for 1s for the next stats */
1874	if (!denom)
1875		return 0;
1876
1877	/* Estimate the period for the total bit rate */
1878	time_us = rate_denum * (1008 * 1562500L);
1879	tmp64 = time_us;
1880	do_div(tmp64, guard);
1881	time_us = time_us + tmp64;
1882	time_us += denom / 2;
1883	do_div(time_us, denom);
1884
1885	tmp = 1008 * 96 * interleaving;
1886	time_us += tmp + tmp / guard;
1887
1888	return time_us;
1889}
1890
1891static int dib7000p_get_stats(struct dvb_frontend *demod, enum fe_status stat)
1892{
1893	struct dib7000p_state *state = demod->demodulator_priv;
1894	struct dtv_frontend_properties *c = &demod->dtv_property_cache;
1895	int show_per_stats = 0;
1896	u32 time_us = 0, val, snr;
1897	u64 blocks, ucb;
1898	s32 db;
1899	u16 strength;
1900
1901	/* Get Signal strength */
1902	dib7000p_read_signal_strength(demod, &strength);
1903	val = strength;
1904	db = interpolate_value(val,
1905			       strength_to_db_table,
1906			       ARRAY_SIZE(strength_to_db_table)) - DB_OFFSET;
1907	c->strength.stat[0].svalue = db;
1908
1909	/* UCB/BER/CNR measures require lock */
1910	if (!(stat & FE_HAS_LOCK)) {
1911		c->cnr.len = 1;
1912		c->block_count.len = 1;
1913		c->block_error.len = 1;
1914		c->post_bit_error.len = 1;
1915		c->post_bit_count.len = 1;
1916		c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1917		c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1918		c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1919		c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1920		c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1921		return 0;
1922	}
1923
1924	/* Check if time for stats was elapsed */
1925	if (time_after(jiffies, state->per_jiffies_stats)) {
1926		state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000);
1927
1928		/* Get SNR */
1929		snr = dib7000p_get_snr(demod);
1930		if (snr)
1931			snr = (1000L * snr) >> 24;
1932		else
1933			snr = 0;
1934		c->cnr.stat[0].svalue = snr;
1935		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
1936
1937		/* Get UCB measures */
1938		dib7000p_read_unc_blocks(demod, &val);
1939		ucb = val - state->old_ucb;
1940		if (val < state->old_ucb)
1941			ucb += 0x100000000LL;
1942
1943		c->block_error.stat[0].scale = FE_SCALE_COUNTER;
1944		c->block_error.stat[0].uvalue = ucb;
1945
1946		/* Estimate the number of packets based on bitrate */
1947		if (!time_us)
1948			time_us = dib7000p_get_time_us(demod);
1949
1950		if (time_us) {
1951			blocks = 1250000ULL * 1000000ULL;
1952			do_div(blocks, time_us * 8 * 204);
1953			c->block_count.stat[0].scale = FE_SCALE_COUNTER;
1954			c->block_count.stat[0].uvalue += blocks;
1955		}
1956
1957		show_per_stats = 1;
1958	}
1959
1960	/* Get post-BER measures */
1961	if (time_after(jiffies, state->ber_jiffies_stats)) {
1962		time_us = dib7000p_get_time_us(demod);
1963		state->ber_jiffies_stats = jiffies + msecs_to_jiffies((time_us + 500) / 1000);
1964
1965		dprintk("Next all layers stats available in %u us.\n", time_us);
1966
1967		dib7000p_read_ber(demod, &val);
1968		c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
1969		c->post_bit_error.stat[0].uvalue += val;
1970
1971		c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
1972		c->post_bit_count.stat[0].uvalue += 100000000;
1973	}
1974
1975	/* Get PER measures */
1976	if (show_per_stats) {
1977		dib7000p_read_unc_blocks(demod, &val);
1978
1979		c->block_error.stat[0].scale = FE_SCALE_COUNTER;
1980		c->block_error.stat[0].uvalue += val;
1981
1982		time_us = dib7000p_get_time_us(demod);
1983		if (time_us) {
1984			blocks = 1250000ULL * 1000000ULL;
1985			do_div(blocks, time_us * 8 * 204);
1986			c->block_count.stat[0].scale = FE_SCALE_COUNTER;
1987			c->block_count.stat[0].uvalue += blocks;
1988		}
1989	}
1990	return 0;
1991}
1992
1993static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
1994{
1995	tune->min_delay_ms = 1000;
1996	return 0;
1997}
1998
1999static void dib7000p_release(struct dvb_frontend *demod)
2000{
2001	struct dib7000p_state *st = demod->demodulator_priv;
2002	dibx000_exit_i2c_master(&st->i2c_master);
2003	i2c_del_adapter(&st->dib7090_tuner_adap);
2004	kfree(st);
2005}
2006
2007static int dib7000pc_detection(struct i2c_adapter *i2c_adap)
2008{
2009	u8 *tx, *rx;
2010	struct i2c_msg msg[2] = {
2011		{.addr = 18 >> 1, .flags = 0, .len = 2},
2012		{.addr = 18 >> 1, .flags = I2C_M_RD, .len = 2},
2013	};
2014	int ret = 0;
2015
2016	tx = kzalloc(2, GFP_KERNEL);
2017	if (!tx)
2018		return -ENOMEM;
2019	rx = kzalloc(2, GFP_KERNEL);
2020	if (!rx) {
2021		ret = -ENOMEM;
2022		goto rx_memory_error;
2023	}
2024
2025	msg[0].buf = tx;
2026	msg[1].buf = rx;
2027
2028	tx[0] = 0x03;
2029	tx[1] = 0x00;
2030
2031	if (i2c_transfer(i2c_adap, msg, 2) == 2)
2032		if (rx[0] == 0x01 && rx[1] == 0xb3) {
2033			dprintk("-D-  DiB7000PC detected\n");
2034			ret = 1;
2035			goto out;
2036		}
2037
2038	msg[0].addr = msg[1].addr = 0x40;
2039
2040	if (i2c_transfer(i2c_adap, msg, 2) == 2)
2041		if (rx[0] == 0x01 && rx[1] == 0xb3) {
2042			dprintk("-D-  DiB7000PC detected\n");
2043			ret = 1;
2044			goto out;
2045		}
2046
2047	dprintk("-D-  DiB7000PC not detected\n");
2048
2049out:
2050	kfree(rx);
2051rx_memory_error:
2052	kfree(tx);
2053	return ret;
2054}
2055
2056static struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
2057{
2058	struct dib7000p_state *st = demod->demodulator_priv;
2059	return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
2060}
2061
2062static int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
2063{
2064	struct dib7000p_state *state = fe->demodulator_priv;
2065	u16 val = dib7000p_read_word(state, 235) & 0xffef;
2066	val |= (onoff & 0x1) << 4;
2067	dprintk("PID filter enabled %d\n", onoff);
2068	return dib7000p_write_word(state, 235, val);
2069}
2070
2071static int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
2072{
2073	struct dib7000p_state *state = fe->demodulator_priv;
2074	dprintk("PID filter: index %x, PID %d, OnOff %d\n", id, pid, onoff);
2075	return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
2076}
2077
2078static int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
2079{
2080	struct dib7000p_state *dpst;
2081	int k = 0;
2082	u8 new_addr = 0;
2083
2084	dpst = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
2085	if (!dpst)
2086		return -ENOMEM;
2087
2088	dpst->i2c_adap = i2c;
2089	mutex_init(&dpst->i2c_buffer_lock);
2090
2091	for (k = no_of_demods - 1; k >= 0; k--) {
2092		dpst->cfg = cfg[k];
2093
2094		/* designated i2c address */
2095		if (cfg[k].default_i2c_addr != 0)
2096			new_addr = cfg[k].default_i2c_addr + (k << 1);
2097		else
2098			new_addr = (0x40 + k) << 1;
2099		dpst->i2c_addr = new_addr;
2100		dib7000p_write_word(dpst, 1287, 0x0003);	/* sram lead in, rdy */
2101		if (dib7000p_identify(dpst) != 0) {
2102			dpst->i2c_addr = default_addr;
2103			dib7000p_write_word(dpst, 1287, 0x0003);	/* sram lead in, rdy */
2104			if (dib7000p_identify(dpst) != 0) {
2105				dprintk("DiB7000P #%d: not identified\n", k);
2106				kfree(dpst);
2107				return -EIO;
2108			}
2109		}
2110
2111		/* start diversity to pull_down div_str - just for i2c-enumeration */
2112		dib7000p_set_output_mode(dpst, OUTMODE_DIVERSITY);
2113
2114		/* set new i2c address and force divstart */
2115		dib7000p_write_word(dpst, 1285, (new_addr << 2) | 0x2);
2116
2117		dprintk("IC %d initialized (to i2c_address 0x%x)\n", k, new_addr);
2118	}
2119
2120	for (k = 0; k < no_of_demods; k++) {
2121		dpst->cfg = cfg[k];
2122		if (cfg[k].default_i2c_addr != 0)
2123			dpst->i2c_addr = (cfg[k].default_i2c_addr + k) << 1;
2124		else
2125			dpst->i2c_addr = (0x40 + k) << 1;
2126
2127		// unforce divstr
2128		dib7000p_write_word(dpst, 1285, dpst->i2c_addr << 2);
2129
2130		/* deactivate div - it was just for i2c-enumeration */
2131		dib7000p_set_output_mode(dpst, OUTMODE_HIGH_Z);
2132	}
2133
2134	kfree(dpst);
2135	return 0;
2136}
2137
2138static const s32 lut_1000ln_mant[] = {
2139	6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
2140};
2141
2142static s32 dib7000p_get_adc_power(struct dvb_frontend *fe)
2143{
2144	struct dib7000p_state *state = fe->demodulator_priv;
2145	u32 tmp_val = 0, exp = 0, mant = 0;
2146	s32 pow_i;
2147	u16 buf[2];
2148	u8 ix = 0;
2149
2150	buf[0] = dib7000p_read_word(state, 0x184);
2151	buf[1] = dib7000p_read_word(state, 0x185);
2152	pow_i = (buf[0] << 16) | buf[1];
2153	dprintk("raw pow_i = %d\n", pow_i);
2154
2155	tmp_val = pow_i;
2156	while (tmp_val >>= 1)
2157		exp++;
2158
2159	mant = (pow_i * 1000 / (1 << exp));
2160	dprintk(" mant = %d exp = %d\n", mant / 1000, exp);
2161
2162	ix = (u8) ((mant - 1000) / 100);	/* index of the LUT */
2163	dprintk(" ix = %d\n", ix);
2164
2165	pow_i = (lut_1000ln_mant[ix] + 693 * (exp - 20) - 6908);
2166	pow_i = (pow_i << 8) / 1000;
2167	dprintk(" pow_i = %d\n", pow_i);
2168
2169	return pow_i;
2170}
2171
2172static int map_addr_to_serpar_number(struct i2c_msg *msg)
2173{
2174	if ((msg->buf[0] <= 15))
2175		msg->buf[0] -= 1;
2176	else if (msg->buf[0] == 17)
2177		msg->buf[0] = 15;
2178	else if (msg->buf[0] == 16)
2179		msg->buf[0] = 17;
2180	else if (msg->buf[0] == 19)
2181		msg->buf[0] = 16;
2182	else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
2183		msg->buf[0] -= 3;
2184	else if (msg->buf[0] == 28)
2185		msg->buf[0] = 23;
2186	else
2187		return -EINVAL;
2188	return 0;
2189}
2190
2191static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
2192{
2193	struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
2194	u8 n_overflow = 1;
2195	u16 i = 1000;
2196	if (msg[0].len < 3)
2197		return -EOPNOTSUPP;
2198	u16 serpar_num = msg[0].buf[0];
2199
2200	while (n_overflow == 1 && i) {
2201		n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
2202		i--;
2203		if (i == 0)
2204			dprintk("Tuner ITF: write busy (overflow)\n");
2205	}
2206	dib7000p_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
2207	dib7000p_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
2208
2209	return num;
2210}
2211
2212static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
2213{
2214	struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
2215	u8 n_overflow = 1, n_empty = 1;
2216	u16 i = 1000;
2217	if (msg[0].len < 1 || msg[1].len < 2)
2218		return -EOPNOTSUPP;
2219	u16 serpar_num = msg[0].buf[0];
2220	u16 read_word;
2221
2222	while (n_overflow == 1 && i) {
2223		n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
2224		i--;
2225		if (i == 0)
2226			dprintk("TunerITF: read busy (overflow)\n");
2227	}
2228	dib7000p_write_word(state, 1985, (0 << 6) | (serpar_num & 0x3f));
2229
2230	i = 1000;
2231	while (n_empty == 1 && i) {
2232		n_empty = dib7000p_read_word(state, 1984) & 0x1;
2233		i--;
2234		if (i == 0)
2235			dprintk("TunerITF: read busy (empty)\n");
2236	}
2237	read_word = dib7000p_read_word(state, 1987);
2238	msg[1].buf[0] = (read_word >> 8) & 0xff;
2239	msg[1].buf[1] = (read_word) & 0xff;
2240
2241	return num;
2242}
2243
2244static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
2245{
2246	if (map_addr_to_serpar_number(&msg[0]) == 0) {	/* else = Tuner regs to ignore : DIG_CFG, CTRL_RF_LT, PLL_CFG, PWM1_REG, ADCCLK, DIG_CFG_3; SLEEP_EN... */
2247		if (num == 1) {	/* write */
2248			return w7090p_tuner_write_serpar(i2c_adap, msg, 1);
2249		} else {	/* read */
2250			return w7090p_tuner_read_serpar(i2c_adap, msg, 2);
2251		}
2252	}
2253	return num;
2254}
2255
2256static int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap,
2257		struct i2c_msg msg[], int num, u16 apb_address)
2258{
2259	struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
2260	u16 word;
2261
2262	if (num == 1) {		/* write */
2263		if (msg[0].len < 3)
2264			return -EOPNOTSUPP;
2265		dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
2266	} else {
2267		if (msg[1].len < 2)
2268			return -EOPNOTSUPP;
2269		word = dib7000p_read_word(state, apb_address);
2270		msg[1].buf[0] = (word >> 8) & 0xff;
2271		msg[1].buf[1] = (word) & 0xff;
2272	}
2273
2274	return num;
2275}
2276
2277static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
2278{
2279	struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
2280
2281	u16 apb_address = 0, word;
2282	int i = 0;
2283	switch (msg[0].buf[0]) {
2284	case 0x12:
2285		apb_address = 1920;
2286		break;
2287	case 0x14:
2288		apb_address = 1921;
2289		break;
2290	case 0x24:
2291		apb_address = 1922;
2292		break;
2293	case 0x1a:
2294		apb_address = 1923;
2295		break;
2296	case 0x22:
2297		apb_address = 1924;
2298		break;
2299	case 0x33:
2300		apb_address = 1926;
2301		break;
2302	case 0x34:
2303		apb_address = 1927;
2304		break;
2305	case 0x35:
2306		apb_address = 1928;
2307		break;
2308	case 0x36:
2309		apb_address = 1929;
2310		break;
2311	case 0x37:
2312		apb_address = 1930;
2313		break;
2314	case 0x38:
2315		apb_address = 1931;
2316		break;
2317	case 0x39:
2318		apb_address = 1932;
2319		break;
2320	case 0x2a:
2321		apb_address = 1935;
2322		break;
2323	case 0x2b:
2324		apb_address = 1936;
2325		break;
2326	case 0x2c:
2327		apb_address = 1937;
2328		break;
2329	case 0x2d:
2330		apb_address = 1938;
2331		break;
2332	case 0x2e:
2333		apb_address = 1939;
2334		break;
2335	case 0x2f:
2336		apb_address = 1940;
2337		break;
2338	case 0x30:
2339		apb_address = 1941;
2340		break;
2341	case 0x31:
2342		apb_address = 1942;
2343		break;
2344	case 0x32:
2345		apb_address = 1943;
2346		break;
2347	case 0x3e:
2348		apb_address = 1944;
2349		break;
2350	case 0x3f:
2351		apb_address = 1945;
2352		break;
2353	case 0x40:
2354		apb_address = 1948;
2355		break;
2356	case 0x25:
2357		apb_address = 914;
2358		break;
2359	case 0x26:
2360		apb_address = 915;
2361		break;
2362	case 0x27:
2363		apb_address = 917;
2364		break;
2365	case 0x28:
2366		apb_address = 916;
2367		break;
2368	case 0x1d:
2369		i = ((dib7000p_read_word(state, 72) >> 12) & 0x3);
2370		word = dib7000p_read_word(state, 384 + i);
2371		msg[1].buf[0] = (word >> 8) & 0xff;
2372		msg[1].buf[1] = (word) & 0xff;
2373		return num;
2374	case 0x1f:
2375		if (num == 1) {	/* write */
2376			word = (u16) ((msg[0].buf[1] << 8) | msg[0].buf[2]);
2377			word &= 0x3;
2378			word = (dib7000p_read_word(state, 72) & ~(3 << 12)) | (word << 12);
2379			dib7000p_write_word(state, 72, word);	/* Set the proper input */
2380			return num;
2381		}
2382	}
2383
2384	if (apb_address != 0)	/* R/W access via APB */
2385		return dib7090p_rw_on_apb(i2c_adap, msg, num, apb_address);
2386	else			/* R/W access via SERPAR  */
2387		return w7090p_tuner_rw_serpar(i2c_adap, msg, num);
2388
2389	return 0;
2390}
2391
2392static u32 dib7000p_i2c_func(struct i2c_adapter *adapter)
2393{
2394	return I2C_FUNC_I2C;
2395}
2396
2397static const struct i2c_algorithm dib7090_tuner_xfer_algo = {
2398	.master_xfer = dib7090_tuner_xfer,
2399	.functionality = dib7000p_i2c_func,
2400};
2401
2402static struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
2403{
2404	struct dib7000p_state *st = fe->demodulator_priv;
2405	return &st->dib7090_tuner_adap;
2406}
2407
2408static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive)
2409{
2410	u16 reg;
2411
2412	/* drive host bus 2, 3, 4 */
2413	reg = dib7000p_read_word(state, 1798) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2414	reg |= (drive << 12) | (drive << 6) | drive;
2415	dib7000p_write_word(state, 1798, reg);
2416
2417	/* drive host bus 5,6 */
2418	reg = dib7000p_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
2419	reg |= (drive << 8) | (drive << 2);
2420	dib7000p_write_word(state, 1799, reg);
2421
2422	/* drive host bus 7, 8, 9 */
2423	reg = dib7000p_read_word(state, 1800) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2424	reg |= (drive << 12) | (drive << 6) | drive;
2425	dib7000p_write_word(state, 1800, reg);
2426
2427	/* drive host bus 10, 11 */
2428	reg = dib7000p_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
2429	reg |= (drive << 8) | (drive << 2);
2430	dib7000p_write_word(state, 1801, reg);
2431
2432	/* drive host bus 12, 13, 14 */
2433	reg = dib7000p_read_word(state, 1802) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2434	reg |= (drive << 12) | (drive << 6) | drive;
2435	dib7000p_write_word(state, 1802, reg);
2436
2437	return 0;
2438}
2439
2440static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 syncSize)
2441{
2442	u32 quantif = 3;
2443	u32 nom = (insertExtSynchro * P_Kin + syncSize);
2444	u32 denom = P_Kout;
2445	u32 syncFreq = ((nom << quantif) / denom);
2446
2447	if ((syncFreq & ((1 << quantif) - 1)) != 0)
2448		syncFreq = (syncFreq >> quantif) + 1;
2449	else
2450		syncFreq = (syncFreq >> quantif);
2451
2452	if (syncFreq != 0)
2453		syncFreq = syncFreq - 1;
2454
2455	return syncFreq;
2456}
2457
2458static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize)
2459{
2460	dprintk("Configure DibStream Tx\n");
2461
2462	dib7000p_write_word(state, 1615, 1);
2463	dib7000p_write_word(state, 1603, P_Kin);
2464	dib7000p_write_word(state, 1605, P_Kout);
2465	dib7000p_write_word(state, 1606, insertExtSynchro);
2466	dib7000p_write_word(state, 1608, synchroMode);
2467	dib7000p_write_word(state, 1609, (syncWord >> 16) & 0xffff);
2468	dib7000p_write_word(state, 1610, syncWord & 0xffff);
2469	dib7000p_write_word(state, 1612, syncSize);
2470	dib7000p_write_word(state, 1615, 0);
2471
2472	return 0;
2473}
2474
2475static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, u32 syncWord, u32 syncSize,
2476		u32 dataOutRate)
2477{
2478	u32 syncFreq;
2479
2480	dprintk("Configure DibStream Rx\n");
2481	if ((P_Kin != 0) && (P_Kout != 0)) {
2482		syncFreq = dib7090_calcSyncFreq(P_Kin, P_Kout, insertExtSynchro, syncSize);
2483		dib7000p_write_word(state, 1542, syncFreq);
2484	}
2485	dib7000p_write_word(state, 1554, 1);
2486	dib7000p_write_word(state, 1536, P_Kin);
2487	dib7000p_write_word(state, 1537, P_Kout);
2488	dib7000p_write_word(state, 1539, synchroMode);
2489	dib7000p_write_word(state, 1540, (syncWord >> 16) & 0xffff);
2490	dib7000p_write_word(state, 1541, syncWord & 0xffff);
2491	dib7000p_write_word(state, 1543, syncSize);
2492	dib7000p_write_word(state, 1544, dataOutRate);
2493	dib7000p_write_word(state, 1554, 0);
2494
2495	return 0;
2496}
2497
2498static void dib7090_enMpegMux(struct dib7000p_state *state, int onoff)
2499{
2500	u16 reg_1287 = dib7000p_read_word(state, 1287);
2501
2502	switch (onoff) {
2503	case 1:
2504			reg_1287 &= ~(1<<7);
2505			break;
2506	case 0:
2507			reg_1287 |= (1<<7);
2508			break;
2509	}
2510
2511	dib7000p_write_word(state, 1287, reg_1287);
2512}
2513
2514static void dib7090_configMpegMux(struct dib7000p_state *state,
2515		u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
2516{
2517	dprintk("Enable Mpeg mux\n");
2518
2519	dib7090_enMpegMux(state, 0);
2520
2521	/* If the input mode is MPEG do not divide the serial clock */
2522	if ((enSerialMode == 1) && (state->input_mode_mpeg == 1))
2523		enSerialClkDiv2 = 0;
2524
2525	dib7000p_write_word(state, 1287, ((pulseWidth & 0x1f) << 2)
2526			| ((enSerialMode & 0x1) << 1)
2527			| (enSerialClkDiv2 & 0x1));
2528
2529	dib7090_enMpegMux(state, 1);
2530}
2531
2532static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode)
2533{
2534	u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 7);
2535
2536	switch (mode) {
2537	case MPEG_ON_DIBTX:
2538			dprintk("SET MPEG ON DIBSTREAM TX\n");
2539			dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
2540			reg_1288 |= (1<<9);
2541			break;
2542	case DIV_ON_DIBTX:
2543			dprintk("SET DIV_OUT ON DIBSTREAM TX\n");
2544			dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
2545			reg_1288 |= (1<<8);
2546			break;
2547	case ADC_ON_DIBTX:
2548			dprintk("SET ADC_OUT ON DIBSTREAM TX\n");
2549			dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
2550			reg_1288 |= (1<<7);
2551			break;
2552	default:
2553			break;
2554	}
2555	dib7000p_write_word(state, 1288, reg_1288);
2556}
2557
2558static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode)
2559{
2560	u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 4);
2561
2562	switch (mode) {
2563	case DEMOUT_ON_HOSTBUS:
2564			dprintk("SET DEM OUT OLD INTERF ON HOST BUS\n");
2565			dib7090_enMpegMux(state, 0);
2566			reg_1288 |= (1<<6);
2567			break;
2568	case DIBTX_ON_HOSTBUS:
2569			dprintk("SET DIBSTREAM TX ON HOST BUS\n");
2570			dib7090_enMpegMux(state, 0);
2571			reg_1288 |= (1<<5);
2572			break;
2573	case MPEG_ON_HOSTBUS:
2574			dprintk("SET MPEG MUX ON HOST BUS\n");
2575			reg_1288 |= (1<<4);
2576			break;
2577	default:
2578			break;
2579	}
2580	dib7000p_write_word(state, 1288, reg_1288);
2581}
2582
2583static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
2584{
2585	struct dib7000p_state *state = fe->demodulator_priv;
2586	u16 reg_1287;
2587
2588	switch (onoff) {
2589	case 0: /* only use the internal way - not the diversity input */
2590			dprintk("%s mode OFF : by default Enable Mpeg INPUT\n", __func__);
2591			dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0);
2592
2593			/* Do not divide the serial clock of MPEG MUX */
2594			/* in SERIAL MODE in case input mode MPEG is used */
2595			reg_1287 = dib7000p_read_word(state, 1287);
2596			/* enSerialClkDiv2 == 1 ? */
2597			if ((reg_1287 & 0x1) == 1) {
2598				/* force enSerialClkDiv2 = 0 */
2599				reg_1287 &= ~0x1;
2600				dib7000p_write_word(state, 1287, reg_1287);
2601			}
2602			state->input_mode_mpeg = 1;
2603			break;
2604	case 1: /* both ways */
2605	case 2: /* only the diversity input */
2606			dprintk("%s ON : Enable diversity INPUT\n", __func__);
2607			dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
2608			state->input_mode_mpeg = 0;
2609			break;
2610	}
2611
2612	dib7000p_set_diversity_in(&state->demod, onoff);
2613	return 0;
2614}
2615
2616static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
2617{
2618	struct dib7000p_state *state = fe->demodulator_priv;
2619
2620	u16 outreg, smo_mode, fifo_threshold;
2621	u8 prefer_mpeg_mux_use = 1;
2622	int ret = 0;
2623
2624	dib7090_host_bus_drive(state, 1);
2625
2626	fifo_threshold = 1792;
2627	smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
2628	outreg = dib7000p_read_word(state, 1286) & ~((1 << 10) | (0x7 << 6) | (1 << 1));
2629
2630	switch (mode) {
2631	case OUTMODE_HIGH_Z:
2632		outreg = 0;
2633		break;
2634
2635	case OUTMODE_MPEG2_SERIAL:
2636		if (prefer_mpeg_mux_use) {
2637			dprintk("setting output mode TS_SERIAL using Mpeg Mux\n");
2638			dib7090_configMpegMux(state, 3, 1, 1);
2639			dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS);
2640		} else {/* Use Smooth block */
2641			dprintk("setting output mode TS_SERIAL using Smooth block\n");
2642			dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
2643			outreg |= (2<<6) | (0 << 1);
2644		}
2645		break;
2646
2647	case OUTMODE_MPEG2_PAR_GATED_CLK:
2648		if (prefer_mpeg_mux_use) {
2649			dprintk("setting output mode TS_PARALLEL_GATED using Mpeg Mux\n");
2650			dib7090_configMpegMux(state, 2, 0, 0);
2651			dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS);
2652		} else { /* Use Smooth block */
2653			dprintk("setting output mode TS_PARALLEL_GATED using Smooth block\n");
2654			dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
2655			outreg |= (0<<6);
2656		}
2657		break;
2658
2659	case OUTMODE_MPEG2_PAR_CONT_CLK:	/* Using Smooth block only */
2660		dprintk("setting output mode TS_PARALLEL_CONT using Smooth block\n");
2661		dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
2662		outreg |= (1<<6);
2663		break;
2664
2665	case OUTMODE_MPEG2_FIFO:	/* Using Smooth block because not supported by new Mpeg Mux block */
2666		dprintk("setting output mode TS_FIFO using Smooth block\n");
2667		dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
2668		outreg |= (5<<6);
2669		smo_mode |= (3 << 1);
2670		fifo_threshold = 512;
2671		break;
2672
2673	case OUTMODE_DIVERSITY:
2674		dprintk("setting output mode MODE_DIVERSITY\n");
2675		dib7090_setDibTxMux(state, DIV_ON_DIBTX);
2676		dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
2677		break;
2678
2679	case OUTMODE_ANALOG_ADC:
2680		dprintk("setting output mode MODE_ANALOG_ADC\n");
2681		dib7090_setDibTxMux(state, ADC_ON_DIBTX);
2682		dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
2683		break;
2684	}
2685	if (mode != OUTMODE_HIGH_Z)
2686		outreg |= (1 << 10);
2687
2688	if (state->cfg.output_mpeg2_in_188_bytes)
2689		smo_mode |= (1 << 5);
2690
2691	ret |= dib7000p_write_word(state, 235, smo_mode);
2692	ret |= dib7000p_write_word(state, 236, fifo_threshold);	/* synchronous fread */
2693	ret |= dib7000p_write_word(state, 1286, outreg);
2694
2695	return ret;
2696}
2697
2698static int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
2699{
2700	struct dib7000p_state *state = fe->demodulator_priv;
2701	u16 en_cur_state;
2702
2703	dprintk("sleep dib7090: %d\n", onoff);
2704
2705	en_cur_state = dib7000p_read_word(state, 1922);
2706
2707	if (en_cur_state > 0xff)
2708		state->tuner_enable = en_cur_state;
2709
2710	if (onoff)
2711		en_cur_state &= 0x00ff;
2712	else {
2713		if (state->tuner_enable != 0)
2714			en_cur_state = state->tuner_enable;
2715	}
2716
2717	dib7000p_write_word(state, 1922, en_cur_state);
2718
2719	return 0;
2720}
2721
2722static int dib7090_get_adc_power(struct dvb_frontend *fe)
2723{
2724	return dib7000p_get_adc_power(fe);
2725}
2726
2727static int dib7090_slave_reset(struct dvb_frontend *fe)
2728{
2729	struct dib7000p_state *state = fe->demodulator_priv;
2730	u16 reg;
2731
2732	reg = dib7000p_read_word(state, 1794);
2733	dib7000p_write_word(state, 1794, reg | (4 << 12));
2734
2735	dib7000p_write_word(state, 1032, 0xffff);
2736	return 0;
2737}
2738
2739static const struct dvb_frontend_ops dib7000p_ops;
2740static struct dvb_frontend *dib7000p_init(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
2741{
2742	struct dvb_frontend *demod;
2743	struct dib7000p_state *st;
2744	st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
2745	if (st == NULL)
2746		return NULL;
2747
2748	memcpy(&st->cfg, cfg, sizeof(struct dib7000p_config));
2749	st->i2c_adap = i2c_adap;
2750	st->i2c_addr = i2c_addr;
2751	st->gpio_val = cfg->gpio_val;
2752	st->gpio_dir = cfg->gpio_dir;
2753
2754	/* Ensure the output mode remains at the previous default if it's
2755	 * not specifically set by the caller.
2756	 */
2757	if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2758		st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2759
2760	demod = &st->demod;
2761	demod->demodulator_priv = st;
2762	memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
2763	mutex_init(&st->i2c_buffer_lock);
2764
2765	dib7000p_write_word(st, 1287, 0x0003);	/* sram lead in, rdy */
2766
2767	if (dib7000p_identify(st) != 0)
2768		goto error;
2769
2770	st->version = dib7000p_read_word(st, 897);
2771
2772	/* FIXME: make sure the dev.parent field is initialized, or else
2773	   request_firmware() will hit an OOPS (this should be moved somewhere
2774	   more common) */
2775	st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
2776
2777	dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
2778
2779	/* init 7090 tuner adapter */
2780	strscpy(st->dib7090_tuner_adap.name, "DiB7090 tuner interface",
2781		sizeof(st->dib7090_tuner_adap.name));
2782	st->dib7090_tuner_adap.algo = &dib7090_tuner_xfer_algo;
2783	st->dib7090_tuner_adap.algo_data = NULL;
2784	st->dib7090_tuner_adap.dev.parent = st->i2c_adap->dev.parent;
2785	i2c_set_adapdata(&st->dib7090_tuner_adap, st);
2786	i2c_add_adapter(&st->dib7090_tuner_adap);
2787
2788	dib7000p_demod_reset(st);
2789
2790	dib7000p_reset_stats(demod);
2791
2792	if (st->version == SOC7090) {
2793		dib7090_set_output_mode(demod, st->cfg.output_mode);
2794		dib7090_set_diversity_in(demod, 0);
2795	}
2796
2797	return demod;
2798
2799error:
2800	kfree(st);
2801	return NULL;
2802}
2803
2804void *dib7000p_attach(struct dib7000p_ops *ops)
2805{
2806	if (!ops)
2807		return NULL;
2808
2809	ops->slave_reset = dib7090_slave_reset;
2810	ops->get_adc_power = dib7090_get_adc_power;
2811	ops->dib7000pc_detection = dib7000pc_detection;
2812	ops->get_i2c_tuner = dib7090_get_i2c_tuner;
2813	ops->tuner_sleep = dib7090_tuner_sleep;
2814	ops->init = dib7000p_init;
2815	ops->set_agc1_min = dib7000p_set_agc1_min;
2816	ops->set_gpio = dib7000p_set_gpio;
2817	ops->i2c_enumeration = dib7000p_i2c_enumeration;
2818	ops->pid_filter = dib7000p_pid_filter;
2819	ops->pid_filter_ctrl = dib7000p_pid_filter_ctrl;
2820	ops->get_i2c_master = dib7000p_get_i2c_master;
2821	ops->update_pll = dib7000p_update_pll;
2822	ops->ctrl_timf = dib7000p_ctrl_timf;
2823	ops->get_agc_values = dib7000p_get_agc_values;
2824	ops->set_wbd_ref = dib7000p_set_wbd_ref;
2825
2826	return ops;
2827}
2828EXPORT_SYMBOL_GPL(dib7000p_attach);
2829
2830static const struct dvb_frontend_ops dib7000p_ops = {
2831	.delsys = { SYS_DVBT },
2832	.info = {
2833		 .name = "DiBcom 7000PC",
2834		 .frequency_min_hz =  44250 * kHz,
2835		 .frequency_max_hz = 867250 * kHz,
2836		 .frequency_stepsize_hz = 62500,
2837		 .caps = FE_CAN_INVERSION_AUTO |
2838		 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2839		 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2840		 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2841		 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2842		 },
2843
2844	.release = dib7000p_release,
2845
2846	.init = dib7000p_wakeup,
2847	.sleep = dib7000p_sleep,
2848
2849	.set_frontend = dib7000p_set_frontend,
2850	.get_tune_settings = dib7000p_fe_get_tune_settings,
2851	.get_frontend = dib7000p_get_frontend,
2852
2853	.read_status = dib7000p_read_status,
2854	.read_ber = dib7000p_read_ber,
2855	.read_signal_strength = dib7000p_read_signal_strength,
2856	.read_snr = dib7000p_read_snr,
2857	.read_ucblocks = dib7000p_read_unc_blocks,
2858};
2859
2860MODULE_AUTHOR("Olivier Grenie <olivie.grenie@parrot.com>");
2861MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
2862MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
2863MODULE_LICENSE("GPL");
~/ Read-only file preview.