brintos

brintos / linux-shallow public Read only

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