Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Linux-DVB Driver for DiBcom's DiB7000M and
   4 *              first generation DiB7000P-demodulator-family.
   5 *
   6 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
   7 */
   8
   9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  10
  11#include <linux/kernel.h>
  12#include <linux/slab.h>
  13#include <linux/i2c.h>
  14#include <linux/mutex.h>
  15
  16#include <media/dvb_frontend.h>
  17
  18#include "dib7000m.h"
  19
  20static int debug;
  21module_param(debug, int, 0644);
  22MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
  23
  24#define dprintk(fmt, arg...) do {					\
  25	if (debug)							\
  26		printk(KERN_DEBUG pr_fmt("%s: " fmt),			\
  27		       __func__, ##arg);				\
  28} while (0)
  29
  30struct dib7000m_state {
  31	struct dvb_frontend demod;
  32    struct dib7000m_config cfg;
  33
  34	u8 i2c_addr;
  35	struct i2c_adapter   *i2c_adap;
  36
  37	struct dibx000_i2c_master i2c_master;
  38
  39/* offset is 1 in case of the 7000MC */
  40	u8 reg_offs;
  41
  42	u16 wbd_ref;
  43
  44	u8 current_band;
  45	u32 current_bandwidth;
  46	struct dibx000_agc_config *current_agc;
  47	u32 timf;
  48	u32 timf_default;
  49	u32 internal_clk;
  50
  51	u8 div_force_off : 1;
  52	u8 div_state : 1;
  53	u16 div_sync_wait;
  54
  55	u16 revision;
  56
  57	u8 agc_state;
  58
  59	/* for the I2C transfer */
  60	struct i2c_msg msg[2];
  61	u8 i2c_write_buffer[4];
  62	u8 i2c_read_buffer[2];
  63	struct mutex i2c_buffer_lock;
  64};
  65
  66enum dib7000m_power_mode {
  67	DIB7000M_POWER_ALL = 0,
  68
  69	DIB7000M_POWER_NO,
  70	DIB7000M_POWER_INTERF_ANALOG_AGC,
  71	DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD,
  72	DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD,
  73	DIB7000M_POWER_INTERFACE_ONLY,
  74};
  75
  76static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg)
  77{
  78	u16 ret;
  79
  80	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
  81		dprintk("could not acquire lock\n");
  82		return 0;
  83	}
  84
  85	state->i2c_write_buffer[0] = (reg >> 8) | 0x80;
  86	state->i2c_write_buffer[1] = reg & 0xff;
  87
  88	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
  89	state->msg[0].addr = state->i2c_addr >> 1;
  90	state->msg[0].flags = 0;
  91	state->msg[0].buf = state->i2c_write_buffer;
  92	state->msg[0].len = 2;
  93	state->msg[1].addr = state->i2c_addr >> 1;
  94	state->msg[1].flags = I2C_M_RD;
  95	state->msg[1].buf = state->i2c_read_buffer;
  96	state->msg[1].len = 2;
  97
  98	if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
  99		dprintk("i2c read error on %d\n", reg);
 100
 101	ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
 102	mutex_unlock(&state->i2c_buffer_lock);
 103
 104	return ret;
 105}
 106
 107static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val)
 108{
 109	int ret;
 110
 111	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
 112		dprintk("could not acquire lock\n");
 113		return -EINVAL;
 114	}
 115
 116	state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
 117	state->i2c_write_buffer[1] = reg & 0xff;
 118	state->i2c_write_buffer[2] = (val >> 8) & 0xff;
 119	state->i2c_write_buffer[3] = val & 0xff;
 120
 121	memset(&state->msg[0], 0, sizeof(struct i2c_msg));
 122	state->msg[0].addr = state->i2c_addr >> 1;
 123	state->msg[0].flags = 0;
 124	state->msg[0].buf = state->i2c_write_buffer;
 125	state->msg[0].len = 4;
 126
 127	ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ?
 128			-EREMOTEIO : 0);
 129	mutex_unlock(&state->i2c_buffer_lock);
 130	return ret;
 131}
 132static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf)
 133{
 134	u16 l = 0, r, *n;
 135	n = buf;
 136	l = *n++;
 137	while (l) {
 138		r = *n++;
 139
 140		if (state->reg_offs && (r >= 112 && r <= 331)) // compensate for 7000MC
 141			r++;
 142
 143		do {
 144			dib7000m_write_word(state, r, *n++);
 145			r++;
 146		} while (--l);
 147		l = *n++;
 148	}
 149}
 150
 151static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode)
 152{
 153	int    ret = 0;
 154	u16 outreg, fifo_threshold, smo_mode,
 155		sram = 0x0005; /* by default SRAM output is disabled */
 156
 157	outreg = 0;
 158	fifo_threshold = 1792;
 159	smo_mode = (dib7000m_read_word(state, 294 + state->reg_offs) & 0x0010) | (1 << 1);
 160
 161	dprintk("setting output mode for demod %p to %d\n", &state->demod, mode);
 162
 163	switch (mode) {
 164		case OUTMODE_MPEG2_PAR_GATED_CLK:   // STBs with parallel gated clock
 165			outreg = (1 << 10);  /* 0x0400 */
 166			break;
 167		case OUTMODE_MPEG2_PAR_CONT_CLK:    // STBs with parallel continues clock
 168			outreg = (1 << 10) | (1 << 6); /* 0x0440 */
 169			break;
 170		case OUTMODE_MPEG2_SERIAL:          // STBs with serial input
 171			outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
 172			break;
 173		case OUTMODE_DIVERSITY:
 174			if (state->cfg.hostbus_diversity)
 175				outreg = (1 << 10) | (4 << 6); /* 0x0500 */
 176			else
 177				sram   |= 0x0c00;
 178			break;
 179		case OUTMODE_MPEG2_FIFO:            // e.g. USB feeding
 180			smo_mode |= (3 << 1);
 181			fifo_threshold = 512;
 182			outreg = (1 << 10) | (5 << 6);
 183			break;
 184		case OUTMODE_HIGH_Z:  // disable
 185			outreg = 0;
 186			break;
 187		default:
 188			dprintk("Unhandled output_mode passed to be set for demod %p\n", &state->demod);
 189			break;
 190	}
 191
 192	if (state->cfg.output_mpeg2_in_188_bytes)
 193		smo_mode |= (1 << 5) ;
 194
 195	ret |= dib7000m_write_word(state,  294 + state->reg_offs, smo_mode);
 196	ret |= dib7000m_write_word(state,  295 + state->reg_offs, fifo_threshold); /* synchronous fread */
 197	ret |= dib7000m_write_word(state, 1795, outreg);
 198	ret |= dib7000m_write_word(state, 1805, sram);
 199
 200	if (state->revision == 0x4003) {
 201		u16 clk_cfg1 = dib7000m_read_word(state, 909) & 0xfffd;
 202		if (mode == OUTMODE_DIVERSITY)
 203			clk_cfg1 |= (1 << 1); // P_O_CLK_en
 204		dib7000m_write_word(state, 909, clk_cfg1);
 205	}
 206	return ret;
 207}
 208
 209static void dib7000m_set_power_mode(struct dib7000m_state *state, enum dib7000m_power_mode mode)
 210{
 211	/* by default everything is going to be powered off */
 212	u16 reg_903 = 0xffff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906  = 0x3fff;
 213	u8  offset = 0;
 214
 215	/* now, depending on the requested mode, we power on */
 216	switch (mode) {
 217		/* power up everything in the demod */
 218		case DIB7000M_POWER_ALL:
 219			reg_903 = 0x0000; reg_904 = 0x0000; reg_905 = 0x0000; reg_906 = 0x0000;
 220			break;
 221
 222		/* just leave power on the control-interfaces: GPIO and (I2C or SDIO or SRAM) */
 223		case DIB7000M_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C or SRAM */
 224			reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 2));
 225			break;
 226
 227		case DIB7000M_POWER_INTERF_ANALOG_AGC:
 228			reg_903 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10));
 229			reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2));
 230			reg_906 &= ~((1 << 0));
 231			break;
 232
 233		case DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD:
 234			reg_903 = 0x0000; reg_904 = 0x801f; reg_905 = 0x0000; reg_906 = 0x0000;
 235			break;
 236
 237		case DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD:
 238			reg_903 = 0x0000; reg_904 = 0x8000; reg_905 = 0x010b; reg_906 = 0x0000;
 239			break;
 240		case DIB7000M_POWER_NO:
 241			break;
 242	}
 243
 244	/* always power down unused parts */
 245	if (!state->cfg.mobile_mode)
 246		reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1);
 247
 248	/* P_sdio_select_clk = 0 on MC and after*/
 249	if (state->revision != 0x4000)
 250		reg_906 <<= 1;
 251
 252	if (state->revision == 0x4003)
 253		offset = 1;
 254
 255	dib7000m_write_word(state, 903 + offset, reg_903);
 256	dib7000m_write_word(state, 904 + offset, reg_904);
 257	dib7000m_write_word(state, 905 + offset, reg_905);
 258	dib7000m_write_word(state, 906 + offset, reg_906);
 259}
 260
 261static int dib7000m_set_adc_state(struct dib7000m_state *state, enum dibx000_adc_states no)
 262{
 263	int ret = 0;
 264	u16 reg_913 = dib7000m_read_word(state, 913),
 265	       reg_914 = dib7000m_read_word(state, 914);
 266
 267	switch (no) {
 268		case DIBX000_SLOW_ADC_ON:
 269			reg_914 |= (1 << 1) | (1 << 0);
 270			ret |= dib7000m_write_word(state, 914, reg_914);
 271			reg_914 &= ~(1 << 1);
 272			break;
 273
 274		case DIBX000_SLOW_ADC_OFF:
 275			reg_914 |=  (1 << 1) | (1 << 0);
 276			break;
 277
 278		case DIBX000_ADC_ON:
 279			if (state->revision == 0x4000) { // workaround for PA/MA
 280				// power-up ADC
 281				dib7000m_write_word(state, 913, 0);
 282				dib7000m_write_word(state, 914, reg_914 & 0x3);
 283				// power-down bandgag
 284				dib7000m_write_word(state, 913, (1 << 15));
 285				dib7000m_write_word(state, 914, reg_914 & 0x3);
 286			}
 287
 288			reg_913 &= 0x0fff;
 289			reg_914 &= 0x0003;
 290			break;
 291
 292		case DIBX000_ADC_OFF: // leave the VBG voltage on
 293			reg_913 |= (1 << 14) | (1 << 13) | (1 << 12);
 294			reg_914 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
 295			break;
 296
 297		case DIBX000_VBG_ENABLE:
 298			reg_913 &= ~(1 << 15);
 299			break;
 300
 301		case DIBX000_VBG_DISABLE:
 302			reg_913 |= (1 << 15);
 303			break;
 304
 305		default:
 306			break;
 307	}
 308
 309//	dprintk("913: %x, 914: %x\n", reg_913, reg_914);
 310	ret |= dib7000m_write_word(state, 913, reg_913);
 311	ret |= dib7000m_write_word(state, 914, reg_914);
 312
 313	return ret;
 314}
 315
 316static int dib7000m_set_bandwidth(struct dib7000m_state *state, u32 bw)
 317{
 318	u32 timf;
 319
 320	if (!bw)
 321		bw = 8000;
 322
 323	// store the current bandwidth for later use
 324	state->current_bandwidth = bw;
 325
 326	if (state->timf == 0) {
 327		dprintk("using default timf\n");
 328		timf = state->timf_default;
 329	} else {
 330		dprintk("using updated timf\n");
 331		timf = state->timf;
 332	}
 333
 334	timf = timf * (bw / 50) / 160;
 335
 336	dib7000m_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
 337	dib7000m_write_word(state, 24, (u16) ((timf      ) & 0xffff));
 338
 339	return 0;
 340}
 341
 342static int dib7000m_set_diversity_in(struct dvb_frontend *demod, int onoff)
 343{
 344	struct dib7000m_state *state = demod->demodulator_priv;
 345
 346	if (state->div_force_off) {
 347		dprintk("diversity combination deactivated - forced by COFDM parameters\n");
 348		onoff = 0;
 349	}
 350	state->div_state = (u8)onoff;
 351
 352	if (onoff) {
 353		dib7000m_write_word(state, 263 + state->reg_offs, 6);
 354		dib7000m_write_word(state, 264 + state->reg_offs, 6);
 355		dib7000m_write_word(state, 266 + state->reg_offs, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
 356	} else {
 357		dib7000m_write_word(state, 263 + state->reg_offs, 1);
 358		dib7000m_write_word(state, 264 + state->reg_offs, 0);
 359		dib7000m_write_word(state, 266 + state->reg_offs, 0);
 360	}
 361
 362	return 0;
 363}
 364
 365static int dib7000m_sad_calib(struct dib7000m_state *state)
 366{
 367
 368/* internal */
 369//	dib7000m_write_word(state, 928, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writing in set_bandwidth
 370	dib7000m_write_word(state, 929, (0 << 1) | (0 << 0));
 371	dib7000m_write_word(state, 930, 776); // 0.625*3.3 / 4096
 372
 373	/* do the calibration */
 374	dib7000m_write_word(state, 929, (1 << 0));
 375	dib7000m_write_word(state, 929, (0 << 0));
 376
 377	msleep(1);
 378
 379	return 0;
 380}
 381
 382static void dib7000m_reset_pll_common(struct dib7000m_state *state, const struct dibx000_bandwidth_config *bw)
 383{
 384	dib7000m_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff));
 385	dib7000m_write_word(state, 19, (u16) ( (bw->internal*1000)        & 0xffff));
 386	dib7000m_write_word(state, 21, (u16) ( (bw->ifreq          >> 16) & 0xffff));
 387	dib7000m_write_word(state, 22, (u16) (  bw->ifreq                 & 0xffff));
 388
 389	dib7000m_write_word(state, 928, bw->sad_cfg);
 390}
 391
 392static void dib7000m_reset_pll(struct dib7000m_state *state)
 393{
 394	const struct dibx000_bandwidth_config *bw = state->cfg.bw;
 395	u16 reg_907,reg_910;
 396
 397	/* default */
 398	reg_907 = (bw->pll_bypass << 15) | (bw->modulo << 7) |
 399		(bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) |
 400		(bw->enable_refdiv << 1) | (0 << 0);
 401	reg_910 = (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset;
 402
 403	// for this oscillator frequency should be 30 MHz for the Master (default values in the board_parameters give that value)
 404	// this is only working only for 30 MHz crystals
 405	if (!state->cfg.quartz_direct) {
 406		reg_910 |= (1 << 5);  // forcing the predivider to 1
 407
 408		// if the previous front-end is baseband, its output frequency is 15 MHz (prev freq divided by 2)
 409		if(state->cfg.input_clk_is_div_2)
 410			reg_907 |= (16 << 9);
 411		else // otherwise the previous front-end puts out its input (default 30MHz) - no extra division necessary
 412			reg_907 |= (8 << 9);
 413	} else {
 414		reg_907 |= (bw->pll_ratio & 0x3f) << 9;
 415		reg_910 |= (bw->pll_prediv << 5);
 416	}
 417
 418	dib7000m_write_word(state, 910, reg_910); // pll cfg
 419	dib7000m_write_word(state, 907, reg_907); // clk cfg0
 420	dib7000m_write_word(state, 908, 0x0006);  // clk_cfg1
 421
 422	dib7000m_reset_pll_common(state, bw);
 423}
 424
 425static void dib7000mc_reset_pll(struct dib7000m_state *state)
 426{
 427	const struct dibx000_bandwidth_config *bw = state->cfg.bw;
 428	u16 clk_cfg1;
 429
 430	// clk_cfg0
 431	dib7000m_write_word(state, 907, (bw->pll_prediv << 8) | (bw->pll_ratio << 0));
 432
 433	// clk_cfg1
 434	//dib7000m_write_word(state, 908, (1 << 14) | (3 << 12) |(0 << 11) |
 435	clk_cfg1 = (0 << 14) | (3 << 12) |(0 << 11) |
 436			(bw->IO_CLK_en_core << 10) | (bw->bypclk_div << 5) | (bw->enable_refdiv << 4) |
 437			(1 << 3) | (bw->pll_range << 1) | (bw->pll_reset << 0);
 438	dib7000m_write_word(state, 908, clk_cfg1);
 439	clk_cfg1 = (clk_cfg1 & 0xfff7) | (bw->pll_bypass << 3);
 440	dib7000m_write_word(state, 908, clk_cfg1);
 441
 442	// smpl_cfg
 443	dib7000m_write_word(state, 910, (1 << 12) | (2 << 10) | (bw->modulo << 8) | (bw->ADClkSrc << 7));
 444
 445	dib7000m_reset_pll_common(state, bw);
 446}
 447
 448static int dib7000m_reset_gpio(struct dib7000m_state *st)
 449{
 450	/* reset the GPIOs */
 451	dib7000m_write_word(st, 773, st->cfg.gpio_dir);
 452	dib7000m_write_word(st, 774, st->cfg.gpio_val);
 453
 454	/* TODO 782 is P_gpio_od */
 455
 456	dib7000m_write_word(st, 775, st->cfg.gpio_pwm_pos);
 457
 458	dib7000m_write_word(st, 780, st->cfg.pwm_freq_div);
 459	return 0;
 460}
 461
 462static u16 dib7000m_defaults_common[] =
 463
 464{
 465	// auto search configuration
 466	3, 2,
 467		0x0004,
 468		0x1000,
 469		0x0814,
 470
 471	12, 6,
 472		0x001b,
 473		0x7740,
 474		0x005b,
 475		0x8d80,
 476		0x01c9,
 477		0xc380,
 478		0x0000,
 479		0x0080,
 480		0x0000,
 481		0x0090,
 482		0x0001,
 483		0xd4c0,
 484
 485	1, 26,
 486		0x6680, // P_corm_thres Lock algorithms configuration
 487
 488	1, 170,
 489		0x0410, // P_palf_alpha_regul, P_palf_filter_freeze, P_palf_filter_on
 490
 491	8, 173,
 492		0,
 493		0,
 494		0,
 495		0,
 496		0,
 497		0,
 498		0,
 499		0,
 500
 501	1, 182,
 502		8192, // P_fft_nb_to_cut
 503
 504	2, 195,
 505		0x0ccd, // P_pha3_thres
 506		0,      // P_cti_use_cpe, P_cti_use_prog
 507
 508	1, 205,
 509		0x200f, // P_cspu_regul, P_cspu_win_cut
 510
 511	5, 214,
 512		0x023d, // P_adp_regul_cnt
 513		0x00a4, // P_adp_noise_cnt
 514		0x00a4, // P_adp_regul_ext
 515		0x7ff0, // P_adp_noise_ext
 516		0x3ccc, // P_adp_fil
 517
 518	1, 226,
 519		0, // P_2d_byp_ti_num
 520
 521	1, 255,
 522		0x800, // P_equal_thres_wgn
 523
 524	1, 263,
 525		0x0001,
 526
 527	1, 281,
 528		0x0010, // P_fec_*
 529
 530	1, 294,
 531		0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
 532
 533	0
 534};
 535
 536static u16 dib7000m_defaults[] =
 537
 538{
 539	/* set ADC level to -16 */
 540	11, 76,
 541		(1 << 13) - 825 - 117,
 542		(1 << 13) - 837 - 117,
 543		(1 << 13) - 811 - 117,
 544		(1 << 13) - 766 - 117,
 545		(1 << 13) - 737 - 117,
 546		(1 << 13) - 693 - 117,
 547		(1 << 13) - 648 - 117,
 548		(1 << 13) - 619 - 117,
 549		(1 << 13) - 575 - 117,
 550		(1 << 13) - 531 - 117,
 551		(1 << 13) - 501 - 117,
 552
 553	// Tuner IO bank: max drive (14mA)
 554	1, 912,
 555		0x2c8a,
 556
 557	1, 1817,
 558		1,
 559
 560	0,
 561};
 562
 563static int dib7000m_demod_reset(struct dib7000m_state *state)
 564{
 565	dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
 566
 567	/* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
 568	dib7000m_set_adc_state(state, DIBX000_VBG_ENABLE);
 569
 570	/* restart all parts */
 571	dib7000m_write_word(state,  898, 0xffff);
 572	dib7000m_write_word(state,  899, 0xffff);
 573	dib7000m_write_word(state,  900, 0xff0f);
 574	dib7000m_write_word(state,  901, 0xfffc);
 575
 576	dib7000m_write_word(state,  898, 0);
 577	dib7000m_write_word(state,  899, 0);
 578	dib7000m_write_word(state,  900, 0);
 579	dib7000m_write_word(state,  901, 0);
 580
 581	if (state->revision == 0x4000)
 582		dib7000m_reset_pll(state);
 583	else
 584		dib7000mc_reset_pll(state);
 585
 586	if (dib7000m_reset_gpio(state) != 0)
 587		dprintk("GPIO reset was not successful.\n");
 588
 589	if (dib7000m_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
 590		dprintk("OUTPUT_MODE could not be reset.\n");
 591
 592	/* unforce divstr regardless whether i2c enumeration was done or not */
 593	dib7000m_write_word(state, 1794, dib7000m_read_word(state, 1794) & ~(1 << 1) );
 594
 595	dib7000m_set_bandwidth(state, 8000);
 596
 597	dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON);
 598	dib7000m_sad_calib(state);
 599	dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
 600
 601	if (state->cfg.dvbt_mode)
 602		dib7000m_write_word(state, 1796, 0x0); // select DVB-T output
 603
 604	if (state->cfg.mobile_mode)
 605		dib7000m_write_word(state, 261 + state->reg_offs, 2);
 606	else
 607		dib7000m_write_word(state, 224 + state->reg_offs, 1);
 608
 609	// P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
 610	if(state->cfg.tuner_is_baseband)
 611		dib7000m_write_word(state, 36, 0x0755);
 612	else
 613		dib7000m_write_word(state, 36, 0x1f55);
 614
 615	// P_divclksel=3 P_divbitsel=1
 616	if (state->revision == 0x4000)
 617		dib7000m_write_word(state, 909, (3 << 10) | (1 << 6));
 618	else
 619		dib7000m_write_word(state, 909, (3 << 4) | 1);
 620
 621	dib7000m_write_tab(state, dib7000m_defaults_common);
 622	dib7000m_write_tab(state, dib7000m_defaults);
 623
 624	dib7000m_set_power_mode(state, DIB7000M_POWER_INTERFACE_ONLY);
 625
 626	state->internal_clk = state->cfg.bw->internal;
 627
 628	return 0;
 629}
 630
 631static void dib7000m_restart_agc(struct dib7000m_state *state)
 632{
 633	// P_restart_iqc & P_restart_agc
 634	dib7000m_write_word(state, 898, 0x0c00);
 635	dib7000m_write_word(state, 898, 0x0000);
 636}
 637
 638static int dib7000m_agc_soft_split(struct dib7000m_state *state)
 639{
 640	u16 agc,split_offset;
 641
 642	if(!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
 643		return 0;
 644
 645	// n_agc_global
 646	agc = dib7000m_read_word(state, 390);
 647
 648	if (agc > state->current_agc->split.min_thres)
 649		split_offset = state->current_agc->split.min;
 650	else if (agc < state->current_agc->split.max_thres)
 651		split_offset = state->current_agc->split.max;
 652	else
 653		split_offset = state->current_agc->split.max *
 654			(agc - state->current_agc->split.min_thres) /
 655			(state->current_agc->split.max_thres - state->current_agc->split.min_thres);
 656
 657	dprintk("AGC split_offset: %d\n", split_offset);
 658
 659	// P_agc_force_split and P_agc_split_offset
 660	return dib7000m_write_word(state, 103, (dib7000m_read_word(state, 103) & 0xff00) | split_offset);
 661}
 662
 663static int dib7000m_update_lna(struct dib7000m_state *state)
 664{
 665	u16 dyn_gain;
 666
 667	if (state->cfg.update_lna) {
 668		// read dyn_gain here (because it is demod-dependent and not fe)
 669		dyn_gain = dib7000m_read_word(state, 390);
 670
 671		if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed
 672			dib7000m_restart_agc(state);
 673			return 1;
 674		}
 675	}
 676	return 0;
 677}
 678
 679static int dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
 680{
 681	struct dibx000_agc_config *agc = NULL;
 682	int i;
 683	if (state->current_band == band && state->current_agc != NULL)
 684		return 0;
 685	state->current_band = band;
 686
 687	for (i = 0; i < state->cfg.agc_config_count; i++)
 688		if (state->cfg.agc[i].band_caps & band) {
 689			agc = &state->cfg.agc[i];
 690			break;
 691		}
 692
 693	if (agc == NULL) {
 694		dprintk("no valid AGC configuration found for band 0x%02x\n", band);
 695		return -EINVAL;
 696	}
 697
 698	state->current_agc = agc;
 699
 700	/* AGC */
 701	dib7000m_write_word(state, 72 ,  agc->setup);
 702	dib7000m_write_word(state, 73 ,  agc->inv_gain);
 703	dib7000m_write_word(state, 74 ,  agc->time_stabiliz);
 704	dib7000m_write_word(state, 97 , (agc->alpha_level << 12) | agc->thlock);
 705
 706	// Demod AGC loop configuration
 707	dib7000m_write_word(state, 98, (agc->alpha_mant << 5) | agc->alpha_exp);
 708	dib7000m_write_word(state, 99, (agc->beta_mant  << 6) | agc->beta_exp);
 709
 710	dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d\n",
 711		state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
 712
 713	/* AGC continued */
 714	if (state->wbd_ref != 0)
 715		dib7000m_write_word(state, 102, state->wbd_ref);
 716	else // use default
 717		dib7000m_write_word(state, 102, agc->wbd_ref);
 718
 719	dib7000m_write_word(state, 103, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8) );
 720	dib7000m_write_word(state, 104,  agc->agc1_max);
 721	dib7000m_write_word(state, 105,  agc->agc1_min);
 722	dib7000m_write_word(state, 106,  agc->agc2_max);
 723	dib7000m_write_word(state, 107,  agc->agc2_min);
 724	dib7000m_write_word(state, 108, (agc->agc1_pt1 << 8) | agc->agc1_pt2 );
 725	dib7000m_write_word(state, 109, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
 726	dib7000m_write_word(state, 110, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
 727	dib7000m_write_word(state, 111, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
 728
 729	if (state->revision > 0x4000) { // settings for the MC
 730		dib7000m_write_word(state, 71,   agc->agc1_pt3);
 731//		dprintk("929: %x %d %d\n",
 732//			(dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2), agc->wbd_inv, agc->wbd_sel);
 733		dib7000m_write_word(state, 929, (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2));
 734	} else {
 735		// wrong default values
 736		u16 b[9] = { 676, 696, 717, 737, 758, 778, 799, 819, 840 };
 737		for (i = 0; i < 9; i++)
 738			dib7000m_write_word(state, 88 + i, b[i]);
 739	}
 740	return 0;
 741}
 742
 743static void dib7000m_update_timf(struct dib7000m_state *state)
 744{
 745	u32 timf = (dib7000m_read_word(state, 436) << 16) | dib7000m_read_word(state, 437);
 746	state->timf = timf * 160 / (state->current_bandwidth / 50);
 747	dib7000m_write_word(state, 23, (u16) (timf >> 16));
 748	dib7000m_write_word(state, 24, (u16) (timf & 0xffff));
 749	dprintk("updated timf_frequency: %d (default: %d)\n", state->timf, state->timf_default);
 750}
 751
 752static int dib7000m_agc_startup(struct dvb_frontend *demod)
 753{
 754	struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
 755	struct dib7000m_state *state = demod->demodulator_priv;
 756	u16 cfg_72 = dib7000m_read_word(state, 72);
 757	int ret = -1;
 758	u8 *agc_state = &state->agc_state;
 759	u8 agc_split;
 760
 761	switch (state->agc_state) {
 762		case 0:
 763			// set power-up level: interf+analog+AGC
 764			dib7000m_set_power_mode(state, DIB7000M_POWER_INTERF_ANALOG_AGC);
 765			dib7000m_set_adc_state(state, DIBX000_ADC_ON);
 766
 767			if (dib7000m_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0)
 768				return -1;
 769
 770			ret = 7; /* ADC power up */
 771			(*agc_state)++;
 772			break;
 773
 774		case 1:
 775			/* AGC initialization */
 776			if (state->cfg.agc_control)
 777				state->cfg.agc_control(&state->demod, 1);
 778
 779			dib7000m_write_word(state, 75, 32768);
 780			if (!state->current_agc->perform_agc_softsplit) {
 781				/* we are using the wbd - so slow AGC startup */
 782				dib7000m_write_word(state, 103, 1 << 8); /* force 0 split on WBD and restart AGC */
 783				(*agc_state)++;
 784				ret = 5;
 785			} else {
 786				/* default AGC startup */
 787				(*agc_state) = 4;
 788				/* wait AGC rough lock time */
 789				ret = 7;
 790			}
 791
 792			dib7000m_restart_agc(state);
 793			break;
 794
 795		case 2: /* fast split search path after 5sec */
 796			dib7000m_write_word(state,  72, cfg_72 | (1 << 4)); /* freeze AGC loop */
 797			dib7000m_write_word(state, 103, 2 << 9);            /* fast split search 0.25kHz */
 798			(*agc_state)++;
 799			ret = 14;
 800			break;
 801
 802	case 3: /* split search ended */
 803			agc_split = (u8)dib7000m_read_word(state, 392); /* store the split value for the next time */
 804			dib7000m_write_word(state, 75, dib7000m_read_word(state, 390)); /* set AGC gain start value */
 805
 806			dib7000m_write_word(state, 72,  cfg_72 & ~(1 << 4));   /* std AGC loop */
 807			dib7000m_write_word(state, 103, (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
 808
 809			dib7000m_restart_agc(state);
 810
 811			dprintk("SPLIT %p: %u\n", demod, agc_split);
 812
 813			(*agc_state)++;
 814			ret = 5;
 815			break;
 816
 817		case 4: /* LNA startup */
 818			/* wait AGC accurate lock time */
 819			ret = 7;
 820
 821			if (dib7000m_update_lna(state))
 822				// wait only AGC rough lock time
 823				ret = 5;
 824			else
 825				(*agc_state)++;
 826			break;
 827
 828		case 5:
 829			dib7000m_agc_soft_split(state);
 830
 831			if (state->cfg.agc_control)
 832				state->cfg.agc_control(&state->demod, 0);
 833
 834			(*agc_state)++;
 835			break;
 836
 837		default:
 838			break;
 839	}
 840	return ret;
 841}
 842
 843static void dib7000m_set_channel(struct dib7000m_state *state, struct dtv_frontend_properties *ch,
 844				 u8 seq)
 845{
 846	u16 value, est[4];
 847
 848	dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
 849
 850	/* nfft, guard, qam, alpha */
 851	value = 0;
 852	switch (ch->transmission_mode) {
 853		case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
 854		case TRANSMISSION_MODE_4K: value |= (2 << 7); break;
 855		default:
 856		case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
 857	}
 858	switch (ch->guard_interval) {
 859		case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
 860		case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
 861		case GUARD_INTERVAL_1_4:  value |= (3 << 5); break;
 862		default:
 863		case GUARD_INTERVAL_1_8:  value |= (2 << 5); break;
 864	}
 865	switch (ch->modulation) {
 866		case QPSK:  value |= (0 << 3); break;
 867		case QAM_16: value |= (1 << 3); break;
 868		default:
 869		case QAM_64: value |= (2 << 3); break;
 870	}
 871	switch (HIERARCHY_1) {
 872		case HIERARCHY_2: value |= 2; break;
 873		case HIERARCHY_4: value |= 4; break;
 874		default:
 875		case HIERARCHY_1: value |= 1; break;
 876	}
 877	dib7000m_write_word(state, 0, value);
 878	dib7000m_write_word(state, 5, (seq << 4));
 879
 880	/* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
 881	value = 0;
 882	if (1 != 0)
 883		value |= (1 << 6);
 884	if (ch->hierarchy == 1)
 885		value |= (1 << 4);
 886	if (1 == 1)
 887		value |= 1;
 888	switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) {
 889		case FEC_2_3: value |= (2 << 1); break;
 890		case FEC_3_4: value |= (3 << 1); break;
 891		case FEC_5_6: value |= (5 << 1); break;
 892		case FEC_7_8: value |= (7 << 1); break;
 893		default:
 894		case FEC_1_2: value |= (1 << 1); break;
 895	}
 896	dib7000m_write_word(state, 267 + state->reg_offs, value);
 897
 898	/* offset loop parameters */
 899
 900	/* P_timf_alpha = 6, P_corm_alpha=6, P_corm_thres=0x80 */
 901	dib7000m_write_word(state, 26, (6 << 12) | (6 << 8) | 0x80);
 902
 903	/* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=1, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
 904	dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (1 << 9) | (3 << 5) | (1 << 4) | (0x3));
 905
 906	/* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max=3 */
 907	dib7000m_write_word(state, 32, (0 << 4) | 0x3);
 908
 909	/* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step=5 */
 910	dib7000m_write_word(state, 33, (0 << 4) | 0x5);
 911
 912	/* P_dvsy_sync_wait */
 913	switch (ch->transmission_mode) {
 914		case TRANSMISSION_MODE_8K: value = 256; break;
 915		case TRANSMISSION_MODE_4K: value = 128; break;
 916		case TRANSMISSION_MODE_2K:
 917		default: value = 64; break;
 918	}
 919	switch (ch->guard_interval) {
 920		case GUARD_INTERVAL_1_16: value *= 2; break;
 921		case GUARD_INTERVAL_1_8:  value *= 4; break;
 922		case GUARD_INTERVAL_1_4:  value *= 8; break;
 923		default:
 924		case GUARD_INTERVAL_1_32: value *= 1; break;
 925	}
 926	state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
 927
 928	/* deactivate the possibility of diversity reception if extended interleave - not for 7000MC */
 929	/* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
 930	if (1 == 1 || state->revision > 0x4000)
 931		state->div_force_off = 0;
 932	else
 933		state->div_force_off = 1;
 934	dib7000m_set_diversity_in(&state->demod, state->div_state);
 935
 936	/* channel estimation fine configuration */
 937	switch (ch->modulation) {
 938		case QAM_64:
 939			est[0] = 0x0148;       /* P_adp_regul_cnt 0.04 */
 940			est[1] = 0xfff0;       /* P_adp_noise_cnt -0.002 */
 941			est[2] = 0x00a4;       /* P_adp_regul_ext 0.02 */
 942			est[3] = 0xfff8;       /* P_adp_noise_ext -0.001 */
 943			break;
 944		case QAM_16:
 945			est[0] = 0x023d;       /* P_adp_regul_cnt 0.07 */
 946			est[1] = 0xffdf;       /* P_adp_noise_cnt -0.004 */
 947			est[2] = 0x00a4;       /* P_adp_regul_ext 0.02 */
 948			est[3] = 0xfff0;       /* P_adp_noise_ext -0.002 */
 949			break;
 950		default:
 951			est[0] = 0x099a;       /* P_adp_regul_cnt 0.3 */
 952			est[1] = 0xffae;       /* P_adp_noise_cnt -0.01 */
 953			est[2] = 0x0333;       /* P_adp_regul_ext 0.1 */
 954			est[3] = 0xfff8;       /* P_adp_noise_ext -0.002 */
 955			break;
 956	}
 957	for (value = 0; value < 4; value++)
 958		dib7000m_write_word(state, 214 + value + state->reg_offs, est[value]);
 959
 960	// set power-up level: autosearch
 961	dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD);
 962}
 963
 964static int dib7000m_autosearch_start(struct dvb_frontend *demod)
 965{
 966	struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
 967	struct dib7000m_state *state = demod->demodulator_priv;
 968	struct dtv_frontend_properties schan;
 969	int ret = 0;
 970	u32 value, factor;
 971
 972	schan = *ch;
 973
 974	schan.modulation = QAM_64;
 975	schan.guard_interval        = GUARD_INTERVAL_1_32;
 976	schan.transmission_mode         = TRANSMISSION_MODE_8K;
 977	schan.code_rate_HP = FEC_2_3;
 978	schan.code_rate_LP = FEC_3_4;
 979	schan.hierarchy    = 0;
 980
 981	dib7000m_set_channel(state, &schan, 7);
 982
 983	factor = BANDWIDTH_TO_KHZ(schan.bandwidth_hz);
 984	if (factor >= 5000)
 985		factor = 1;
 986	else
 987		factor = 6;
 988
 989	// always use the setting for 8MHz here lock_time for 7,6 MHz are longer
 990	value = 30 * state->internal_clk * factor;
 991	ret |= dib7000m_write_word(state, 6,  (u16) ((value >> 16) & 0xffff)); // lock0 wait time
 992	ret |= dib7000m_write_word(state, 7,  (u16)  (value        & 0xffff)); // lock0 wait time
 993	value = 100 * state->internal_clk * factor;
 994	ret |= dib7000m_write_word(state, 8,  (u16) ((value >> 16) & 0xffff)); // lock1 wait time
 995	ret |= dib7000m_write_word(state, 9,  (u16)  (value        & 0xffff)); // lock1 wait time
 996	value = 500 * state->internal_clk * factor;
 997	ret |= dib7000m_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
 998	ret |= dib7000m_write_word(state, 11, (u16)  (value        & 0xffff)); // lock2 wait time
 999
1000	// start search
1001	value = dib7000m_read_word(state, 0);
1002	ret |= dib7000m_write_word(state, 0, (u16) (value | (1 << 9)));
1003
1004	/* clear n_irq_pending */
1005	if (state->revision == 0x4000)
1006		dib7000m_write_word(state, 1793, 0);
1007	else
1008		dib7000m_read_word(state, 537);
1009
1010	ret |= dib7000m_write_word(state, 0, (u16) value);
1011
1012	return ret;
1013}
1014
1015static int dib7000m_autosearch_irq(struct dib7000m_state *state, u16 reg)
1016{
1017	u16 irq_pending = dib7000m_read_word(state, reg);
1018
1019	if (irq_pending & 0x1) { // failed
1020		dprintk("autosearch failed\n");
1021		return 1;
1022	}
1023
1024	if (irq_pending & 0x2) { // succeeded
1025		dprintk("autosearch succeeded\n");
1026		return 2;
1027	}
1028	return 0; // still pending
1029}
1030
1031static int dib7000m_autosearch_is_irq(struct dvb_frontend *demod)
1032{
1033	struct dib7000m_state *state = demod->demodulator_priv;
1034	if (state->revision == 0x4000)
1035		return dib7000m_autosearch_irq(state, 1793);
1036	else
1037		return dib7000m_autosearch_irq(state, 537);
1038}
1039
1040static int dib7000m_tune(struct dvb_frontend *demod)
1041{
1042	struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
1043	struct dib7000m_state *state = demod->demodulator_priv;
1044	int ret = 0;
1045	u16 value;
1046
1047	// we are already tuned - just resuming from suspend
1048	dib7000m_set_channel(state, ch, 0);
1049
1050	// restart demod
1051	ret |= dib7000m_write_word(state, 898, 0x4000);
1052	ret |= dib7000m_write_word(state, 898, 0x0000);
1053	msleep(45);
1054
1055	dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD);
1056	/* 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 */
1057	ret |= dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3));
1058
1059	// never achieved a lock before - wait for timfreq to update
1060	if (state->timf == 0)
1061		msleep(200);
1062
1063	//dump_reg(state);
1064	/* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1065	value = (6 << 8) | 0x80;
1066	switch (ch->transmission_mode) {
1067		case TRANSMISSION_MODE_2K: value |= (7 << 12); break;
1068		case TRANSMISSION_MODE_4K: value |= (8 << 12); break;
1069		default:
1070		case TRANSMISSION_MODE_8K: value |= (9 << 12); break;
1071	}
1072	ret |= dib7000m_write_word(state, 26, value);
1073
1074	/* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1075	value = (0 << 4);
1076	switch (ch->transmission_mode) {
1077		case TRANSMISSION_MODE_2K: value |= 0x6; break;
1078		case TRANSMISSION_MODE_4K: value |= 0x7; break;
1079		default:
1080		case TRANSMISSION_MODE_8K: value |= 0x8; break;
1081	}
1082	ret |= dib7000m_write_word(state, 32, value);
1083
1084	/* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1085	value = (0 << 4);
1086	switch (ch->transmission_mode) {
1087		case TRANSMISSION_MODE_2K: value |= 0x6; break;
1088		case TRANSMISSION_MODE_4K: value |= 0x7; break;
1089		default:
1090		case TRANSMISSION_MODE_8K: value |= 0x8; break;
1091	}
1092	ret |= dib7000m_write_word(state, 33,  value);
1093
1094	// we achieved a lock - it's time to update the timf freq
1095	if ((dib7000m_read_word(state, 535) >> 6)  & 0x1)
1096		dib7000m_update_timf(state);
1097
1098	dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
1099	return ret;
1100}
1101
1102static int dib7000m_wakeup(struct dvb_frontend *demod)
1103{
1104	struct dib7000m_state *state = demod->demodulator_priv;
1105
1106	dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
1107
1108	if (dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1109		dprintk("could not start Slow ADC\n");
1110
1111	return 0;
1112}
1113
1114static int dib7000m_sleep(struct dvb_frontend *demod)
1115{
1116	struct dib7000m_state *st = demod->demodulator_priv;
1117	dib7000m_set_output_mode(st, OUTMODE_HIGH_Z);
1118	dib7000m_set_power_mode(st, DIB7000M_POWER_INTERFACE_ONLY);
1119	return dib7000m_set_adc_state(st, DIBX000_SLOW_ADC_OFF) |
1120		dib7000m_set_adc_state(st, DIBX000_ADC_OFF);
1121}
1122
1123static int dib7000m_identify(struct dib7000m_state *state)
1124{
1125	u16 value;
1126
1127	if ((value = dib7000m_read_word(state, 896)) != 0x01b3) {
1128		dprintk("wrong Vendor ID (0x%x)\n", value);
1129		return -EREMOTEIO;
1130	}
1131
1132	state->revision = dib7000m_read_word(state, 897);
1133	if (state->revision != 0x4000 &&
1134		state->revision != 0x4001 &&
1135		state->revision != 0x4002 &&
1136		state->revision != 0x4003) {
1137		dprintk("wrong Device ID (0x%x)\n", value);
1138		return -EREMOTEIO;
1139	}
1140
1141	/* protect this driver to be used with 7000PC */
1142	if (state->revision == 0x4000 && dib7000m_read_word(state, 769) == 0x4000) {
1143		dprintk("this driver does not work with DiB7000PC\n");
1144		return -EREMOTEIO;
1145	}
1146
1147	switch (state->revision) {
1148	case 0x4000: dprintk("found DiB7000MA/PA/MB/PB\n"); break;
1149	case 0x4001: state->reg_offs = 1; dprintk("found DiB7000HC\n"); break;
1150	case 0x4002: state->reg_offs = 1; dprintk("found DiB7000MC\n"); break;
1151	case 0x4003: state->reg_offs = 1; dprintk("found DiB9000\n"); break;
1152	}
1153
1154	return 0;
1155}
1156
1157
1158static int dib7000m_get_frontend(struct dvb_frontend* fe,
1159				 struct dtv_frontend_properties *fep)
1160{
1161	struct dib7000m_state *state = fe->demodulator_priv;
1162	u16 tps = dib7000m_read_word(state,480);
1163
1164	fep->inversion = INVERSION_AUTO;
1165
1166	fep->bandwidth_hz = BANDWIDTH_TO_HZ(state->current_bandwidth);
1167
1168	switch ((tps >> 8) & 0x3) {
1169		case 0: fep->transmission_mode = TRANSMISSION_MODE_2K; break;
1170		case 1: fep->transmission_mode = TRANSMISSION_MODE_8K; break;
1171		/* case 2: fep->transmission_mode = TRANSMISSION_MODE_4K; break; */
1172	}
1173
1174	switch (tps & 0x3) {
1175		case 0: fep->guard_interval = GUARD_INTERVAL_1_32; break;
1176		case 1: fep->guard_interval = GUARD_INTERVAL_1_16; break;
1177		case 2: fep->guard_interval = GUARD_INTERVAL_1_8; break;
1178		case 3: fep->guard_interval = GUARD_INTERVAL_1_4; break;
1179	}
1180
1181	switch ((tps >> 14) & 0x3) {
1182		case 0: fep->modulation = QPSK; break;
1183		case 1: fep->modulation = QAM_16; break;
1184		case 2:
1185		default: fep->modulation = QAM_64; break;
1186	}
1187
1188	/* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1189	/* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1190
1191	fep->hierarchy = HIERARCHY_NONE;
1192	switch ((tps >> 5) & 0x7) {
1193		case 1: fep->code_rate_HP = FEC_1_2; break;
1194		case 2: fep->code_rate_HP = FEC_2_3; break;
1195		case 3: fep->code_rate_HP = FEC_3_4; break;
1196		case 5: fep->code_rate_HP = FEC_5_6; break;
1197		case 7:
1198		default: fep->code_rate_HP = FEC_7_8; break;
1199
1200	}
1201
1202	switch ((tps >> 2) & 0x7) {
1203		case 1: fep->code_rate_LP = FEC_1_2; break;
1204		case 2: fep->code_rate_LP = FEC_2_3; break;
1205		case 3: fep->code_rate_LP = FEC_3_4; break;
1206		case 5: fep->code_rate_LP = FEC_5_6; break;
1207		case 7:
1208		default: fep->code_rate_LP = FEC_7_8; break;
1209	}
1210
1211	/* native interleaver: (dib7000m_read_word(state, 481) >>  5) & 0x1 */
1212
1213	return 0;
1214}
1215
1216static int dib7000m_set_frontend(struct dvb_frontend *fe)
1217{
1218	struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
1219	struct dib7000m_state *state = fe->demodulator_priv;
1220	int time, ret;
1221
1222	dib7000m_set_output_mode(state, OUTMODE_HIGH_Z);
1223
1224	dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->bandwidth_hz));
1225
1226	if (fe->ops.tuner_ops.set_params)
1227		fe->ops.tuner_ops.set_params(fe);
1228
1229	/* start up the AGC */
1230	state->agc_state = 0;
1231	do {
1232		time = dib7000m_agc_startup(fe);
1233		if (time != -1)
1234			msleep(time);
1235	} while (time != -1);
1236
1237	if (fep->transmission_mode == TRANSMISSION_MODE_AUTO ||
1238		fep->guard_interval    == GUARD_INTERVAL_AUTO ||
1239		fep->modulation        == QAM_AUTO ||
1240		fep->code_rate_HP      == FEC_AUTO) {
1241		int i = 800, found;
1242
1243		dib7000m_autosearch_start(fe);
1244		do {
1245			msleep(1);
1246			found = dib7000m_autosearch_is_irq(fe);
1247		} while (found == 0 && i--);
1248
1249		dprintk("autosearch returns: %d\n", found);
1250		if (found == 0 || found == 1)
1251			return 0; // no channel found
1252
1253		dib7000m_get_frontend(fe, fep);
1254	}
1255
1256	ret = dib7000m_tune(fe);
1257
1258	/* make this a config parameter */
1259	dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO);
1260	return ret;
1261}
1262
1263static int dib7000m_read_status(struct dvb_frontend *fe, enum fe_status *stat)
1264{
1265	struct dib7000m_state *state = fe->demodulator_priv;
1266	u16 lock = dib7000m_read_word(state, 535);
1267
1268	*stat = 0;
1269
1270	if (lock & 0x8000)
1271		*stat |= FE_HAS_SIGNAL;
1272	if (lock & 0x3000)
1273		*stat |= FE_HAS_CARRIER;
1274	if (lock & 0x0100)
1275		*stat |= FE_HAS_VITERBI;
1276	if (lock & 0x0010)
1277		*stat |= FE_HAS_SYNC;
1278	if (lock & 0x0008)
1279		*stat |= FE_HAS_LOCK;
1280
1281	return 0;
1282}
1283
1284static int dib7000m_read_ber(struct dvb_frontend *fe, u32 *ber)
1285{
1286	struct dib7000m_state *state = fe->demodulator_priv;
1287	*ber = (dib7000m_read_word(state, 526) << 16) | dib7000m_read_word(state, 527);
1288	return 0;
1289}
1290
1291static int dib7000m_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
1292{
1293	struct dib7000m_state *state = fe->demodulator_priv;
1294	*unc = dib7000m_read_word(state, 534);
1295	return 0;
1296}
1297
1298static int dib7000m_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1299{
1300	struct dib7000m_state *state = fe->demodulator_priv;
1301	u16 val = dib7000m_read_word(state, 390);
1302	*strength = 65535 - val;
1303	return 0;
1304}
1305
1306static int dib7000m_read_snr(struct dvb_frontend* fe, u16 *snr)
1307{
1308	*snr = 0x0000;
1309	return 0;
1310}
1311
1312static int dib7000m_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
1313{
1314	tune->min_delay_ms = 1000;
1315	return 0;
1316}
1317
1318static void dib7000m_release(struct dvb_frontend *demod)
1319{
1320	struct dib7000m_state *st = demod->demodulator_priv;
1321	dibx000_exit_i2c_master(&st->i2c_master);
1322	kfree(st);
1323}
1324
1325struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1326{
1327	struct dib7000m_state *st = demod->demodulator_priv;
1328	return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1329}
1330EXPORT_SYMBOL(dib7000m_get_i2c_master);
1331
1332int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1333{
1334	struct dib7000m_state *state = fe->demodulator_priv;
1335	u16 val = dib7000m_read_word(state, 294 + state->reg_offs) & 0xffef;
1336	val |= (onoff & 0x1) << 4;
1337	dprintk("PID filter enabled %d\n", onoff);
1338	return dib7000m_write_word(state, 294 + state->reg_offs, val);
1339}
1340EXPORT_SYMBOL(dib7000m_pid_filter_ctrl);
1341
1342int dib7000m_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1343{
1344	struct dib7000m_state *state = fe->demodulator_priv;
1345	dprintk("PID filter: index %x, PID %d, OnOff %d\n", id, pid, onoff);
1346	return dib7000m_write_word(state, 300 + state->reg_offs + id,
1347			onoff ? (1 << 13) | pid : 0);
1348}
1349EXPORT_SYMBOL(dib7000m_pid_filter);
1350
1351#if 0
1352/* used with some prototype boards */
1353int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods,
1354		u8 default_addr, struct dib7000m_config cfg[])
1355{
1356	struct dib7000m_state st = { .i2c_adap = i2c };
1357	int k = 0;
1358	u8 new_addr = 0;
1359
1360	for (k = no_of_demods-1; k >= 0; k--) {
1361		st.cfg = cfg[k];
1362
1363		/* designated i2c address */
1364		new_addr          = (0x40 + k) << 1;
1365		st.i2c_addr = new_addr;
1366		if (dib7000m_identify(&st) != 0) {
1367			st.i2c_addr = default_addr;
1368			if (dib7000m_identify(&st) != 0) {
1369				dprintk("DiB7000M #%d: not identified\n", k);
1370				return -EIO;
1371			}
1372		}
1373
1374		/* start diversity to pull_down div_str - just for i2c-enumeration */
1375		dib7000m_set_output_mode(&st, OUTMODE_DIVERSITY);
1376
1377		dib7000m_write_word(&st, 1796, 0x0); // select DVB-T output
1378
1379		/* set new i2c address and force divstart */
1380		dib7000m_write_word(&st, 1794, (new_addr << 2) | 0x2);
1381
1382		dprintk("IC %d initialized (to i2c_address 0x%x)\n", k, new_addr);
1383	}
1384
1385	for (k = 0; k < no_of_demods; k++) {
1386		st.cfg = cfg[k];
1387		st.i2c_addr = (0x40 + k) << 1;
1388
1389		// unforce divstr
1390		dib7000m_write_word(&st,1794, st.i2c_addr << 2);
1391
1392		/* deactivate div - it was just for i2c-enumeration */
1393		dib7000m_set_output_mode(&st, OUTMODE_HIGH_Z);
1394	}
1395
1396	return 0;
1397}
1398EXPORT_SYMBOL(dib7000m_i2c_enumeration);
1399#endif
1400
1401static const struct dvb_frontend_ops dib7000m_ops;
1402struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg)
1403{
1404	struct dvb_frontend *demod;
1405	struct dib7000m_state *st;
1406	st = kzalloc(sizeof(struct dib7000m_state), GFP_KERNEL);
1407	if (st == NULL)
1408		return NULL;
1409
1410	memcpy(&st->cfg, cfg, sizeof(struct dib7000m_config));
1411	st->i2c_adap = i2c_adap;
1412	st->i2c_addr = i2c_addr;
1413
1414	demod                   = &st->demod;
1415	demod->demodulator_priv = st;
1416	memcpy(&st->demod.ops, &dib7000m_ops, sizeof(struct dvb_frontend_ops));
1417	mutex_init(&st->i2c_buffer_lock);
1418
1419	st->timf_default = cfg->bw->timf;
1420
1421	if (dib7000m_identify(st) != 0)
1422		goto error;
1423
1424	if (st->revision == 0x4000)
1425		dibx000_init_i2c_master(&st->i2c_master, DIB7000, st->i2c_adap, st->i2c_addr);
1426	else
1427		dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c_adap, st->i2c_addr);
1428
1429	dib7000m_demod_reset(st);
1430
1431	return demod;
1432
1433error:
1434	kfree(st);
1435	return NULL;
1436}
1437EXPORT_SYMBOL_GPL(dib7000m_attach);
1438
1439static const struct dvb_frontend_ops dib7000m_ops = {
1440	.delsys = { SYS_DVBT },
1441	.info = {
1442		.name = "DiBcom 7000MA/MB/PA/PB/MC",
1443		.frequency_min_hz      =  44250 * kHz,
1444		.frequency_max_hz      = 867250 * kHz,
1445		.frequency_stepsize_hz = 62500,
1446		.caps = FE_CAN_INVERSION_AUTO |
1447			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1448			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1449			FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1450			FE_CAN_TRANSMISSION_MODE_AUTO |
1451			FE_CAN_GUARD_INTERVAL_AUTO |
1452			FE_CAN_RECOVER |
1453			FE_CAN_HIERARCHY_AUTO,
1454	},
1455
1456	.release              = dib7000m_release,
1457
1458	.init                 = dib7000m_wakeup,
1459	.sleep                = dib7000m_sleep,
1460
1461	.set_frontend         = dib7000m_set_frontend,
1462	.get_tune_settings    = dib7000m_fe_get_tune_settings,
1463	.get_frontend         = dib7000m_get_frontend,
1464
1465	.read_status          = dib7000m_read_status,
1466	.read_ber             = dib7000m_read_ber,
1467	.read_signal_strength = dib7000m_read_signal_strength,
1468	.read_snr             = dib7000m_read_snr,
1469	.read_ucblocks        = dib7000m_read_unc_blocks,
1470};
1471
1472MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
1473MODULE_DESCRIPTION("Driver for the DiBcom 7000MA/MB/PA/PB/MC COFDM demodulator");
1474MODULE_LICENSE("GPL");