cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dib7000p.c (75813B)


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